aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CREDITS10
-rw-r--r--Documentation/00-INDEX24
-rw-r--r--Documentation/CodingStyle7
-rw-r--r--Documentation/DMA-mapping.txt24
-rw-r--r--Documentation/DocBook/deviceiobook.tmpl10
-rw-r--r--Documentation/DocBook/filesystems.tmpl36
-rw-r--r--Documentation/DocBook/gadget.tmpl6
-rw-r--r--Documentation/DocBook/kernel-api.tmpl5
-rw-r--r--Documentation/HOWTO4
-rw-r--r--Documentation/IPMI.txt25
-rw-r--r--Documentation/RCU/00-INDEX22
-rw-r--r--Documentation/SM501.txt5
-rw-r--r--Documentation/accounting/getdelays.c1
-rw-r--r--Documentation/arm/00-INDEX22
-rw-r--r--Documentation/atomic_ops.txt73
-rw-r--r--Documentation/block/00-INDEX20
-rw-r--r--Documentation/block/as-iosched.txt21
-rw-r--r--Documentation/block/biodoc.txt4
-rw-r--r--Documentation/block/deadline-iosched.txt25
-rw-r--r--Documentation/block/ioprio.txt2
-rw-r--r--Documentation/block/request.txt2
-rw-r--r--Documentation/block/switching-sched.txt21
-rw-r--r--Documentation/cachetlb.txt6
-rw-r--r--Documentation/cpusets.txt24
-rw-r--r--Documentation/dontdiff8
-rw-r--r--Documentation/early-userspace/README6
-rw-r--r--Documentation/email-clients.txt217
-rw-r--r--Documentation/fb/00-INDEX46
-rw-r--r--Documentation/fb/uvesafb.txt188
-rw-r--r--Documentation/feature-removal-schedule.txt67
-rw-r--r--Documentation/filesystems/00-INDEX10
-rw-r--r--Documentation/filesystems/9p.txt22
-rw-r--r--Documentation/filesystems/Locking9
-rw-r--r--Documentation/filesystems/locks.txt (renamed from Documentation/locks.txt)10
-rw-r--r--Documentation/filesystems/mandatory-locking.txt (renamed from Documentation/mandatory.txt)21
-rw-r--r--Documentation/filesystems/proc.txt30
-rw-r--r--Documentation/filesystems/quota.txt59
-rw-r--r--Documentation/filesystems/ramfs-rootfs-initramfs.txt14
-rw-r--r--Documentation/filesystems/vfs.txt51
-rw-r--r--Documentation/firmware_class/firmware_sample_firmware_class.c10
-rw-r--r--Documentation/ide.txt6
-rw-r--r--Documentation/initrd.txt12
-rw-r--r--Documentation/kbuild/makefiles.txt62
-rw-r--r--Documentation/kdump/kdump.txt63
-rw-r--r--Documentation/kernel-parameters.txt53
-rw-r--r--Documentation/keys-request-key.txt25
-rw-r--r--Documentation/keys.txt93
-rw-r--r--Documentation/local_ops.txt25
-rw-r--r--Documentation/m68k/kernel-options.txt4
-rw-r--r--Documentation/make/headers_install.txt46
-rw-r--r--Documentation/memory-barriers.txt14
-rw-r--r--Documentation/mips/00-INDEX8
-rw-r--r--Documentation/mutex-design.txt3
-rw-r--r--Documentation/networking/bonding.txt33
-rw-r--r--Documentation/networking/proc_net_tcp.txt5
-rw-r--r--Documentation/networking/rxrpc.txt7
-rw-r--r--Documentation/parport-lowlevel.txt29
-rw-r--r--Documentation/power/00-INDEX34
-rw-r--r--Documentation/power/basic-pm-debugging.txt4
-rw-r--r--Documentation/power/drivers-testing.txt4
-rw-r--r--Documentation/power/freezing-of-tasks.txt44
-rw-r--r--Documentation/power/interface.txt2
-rw-r--r--Documentation/powerpc/00-INDEX4
-rw-r--r--Documentation/ramdisk.txt18
-rw-r--r--Documentation/scsi/ChangeLog.ncr53c8xx6
-rw-r--r--Documentation/scsi/ibmmca.txt2
-rw-r--r--Documentation/scsi/ncr53c8xx.txt14
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt115
-rw-r--r--Documentation/sound/alsa/CMIPCI.txt17
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl184
-rw-r--r--Documentation/sound/alsa/OSS-Emulation.txt7
-rw-r--r--Documentation/sound/alsa/hda_codec.txt49
-rw-r--r--Documentation/sound/alsa/powersave.txt41
-rw-r--r--Documentation/sound/oss/es137164
-rw-r--r--Documentation/spi/spi-summary25
-rw-r--r--Documentation/spi/spidev_test.c6
-rw-r--r--Documentation/sysctl/00-INDEX16
-rw-r--r--Documentation/sysctl/kernel.txt8
-rw-r--r--Documentation/sysctl/vm.txt28
-rw-r--r--Documentation/telephony/00-INDEX4
-rw-r--r--Documentation/vm/00-INDEX20
-rw-r--r--Documentation/vm/numa_memory_policy.txt33
-rw-r--r--Documentation/vm/slabinfo.c27
-rw-r--r--Documentation/w1/00-INDEX8
-rw-r--r--Documentation/w1/masters/00-INDEX6
-rw-r--r--Documentation/w1/masters/ds24822
-rw-r--r--Documentation/w1/masters/ds24902
-rw-r--r--Documentation/x86_64/mm.txt1
-rw-r--r--Documentation/xterm-linux.xpm61
-rw-r--r--MAINTAINERS36
-rw-r--r--Makefile65
-rw-r--r--arch/alpha/Makefile81
-rw-r--r--arch/alpha/kernel/Makefile2
-rw-r--r--arch/alpha/kernel/entry.S9
-rw-r--r--arch/alpha/kernel/ptrace.c46
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S260
-rw-r--r--arch/alpha/lib/Makefile2
-rw-r--r--arch/alpha/mm/fault.c2
-rw-r--r--arch/arm/Kconfig23
-rw-r--r--arch/arm/Kconfig-nommu2
-rw-r--r--arch/arm/Makefile16
-rw-r--r--arch/arm/boot/compressed/Makefile2
-rw-r--r--arch/arm/boot/compressed/head-xscale.S4
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/dmabounce.c4
-rw-r--r--arch/arm/common/it8152.c387
-rw-r--r--arch/arm/common/sharpsl_pm.c9
-rw-r--r--arch/arm/configs/cm_x270_defconfig1410
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig399
-rw-r--r--arch/arm/configs/omap_osk_5912_defconfig1073
-rw-r--r--arch/arm/kernel/bios32.c28
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/arm/kernel/ptrace.c4
-rw-r--r--arch/arm/kernel/relocate_kernel.S29
-rw-r--r--arch/arm/kernel/setup.c51
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c2
-rw-r--r--arch/arm/mach-at91/Kconfig25
-rw-r--r--arch/arm/mach-at91/Makefile5
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c195
-rw-r--r--arch/arm/mach-at91/at91x40.c67
-rw-r--r--arch/arm/mach-at91/at91x40_time.c80
-rw-r--r--arch/arm/mach-at91/board-eb01.c44
-rw-r--r--arch/arm/mach-at91/generic.h3
-rw-r--r--arch/arm/mach-at91/pm.c7
-rw-r--r--arch/arm/mach-clps7500/core.c6
-rw-r--r--arch/arm/mach-ep93xx/Kconfig6
-rw-r--r--arch/arm/mach-ep93xx/Makefile1
-rw-r--r--arch/arm/mach-ep93xx/edb9307.c91
-rw-r--r--arch/arm/mach-footbridge/cats-hw.c6
-rw-r--r--arch/arm/mach-footbridge/isa.c45
-rw-r--r--arch/arm/mach-ns9xxx/Makefile2
-rw-r--r--arch/arm/mach-ns9xxx/board-a9m9750dev.c70
-rw-r--r--arch/arm/mach-ns9xxx/gpio.c190
-rw-r--r--arch/arm/mach-ns9xxx/irq.c50
-rw-r--r--arch/arm/mach-ns9xxx/time.c172
-rw-r--r--arch/arm/mach-omap1/Kconfig38
-rw-r--r--arch/arm/mach-omap1/Makefile3
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c120
-rw-r--r--arch/arm/mach-omap1/board-h2.c79
-rw-r--r--arch/arm/mach-omap1/board-h3.c41
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c98
-rw-r--r--arch/arm/mach-omap1/board-osk.c55
-rw-r--r--arch/arm/mach-omap1/board-palmte.c377
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c357
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c383
-rw-r--r--arch/arm/mach-omap1/board-sx1.c494
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-omap1/clock.c34
-rw-r--r--arch/arm/mach-omap1/clock.h35
-rw-r--r--arch/arm/mach-omap1/leds-innovator.c3
-rw-r--r--arch/arm/mach-omap1/mux.c24
-rw-r--r--arch/arm/mach-omap1/pm.c34
-rw-r--r--arch/arm/mach-omap2/Kconfig11
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c218
-rw-r--r--arch/arm/mach-omap2/board-apollon.c99
-rw-r--r--arch/arm/mach-omap2/board-h4.c46
-rw-r--r--arch/arm/mach-omap2/devices.c6
-rw-r--r--arch/arm/mach-omap2/gpmc.c47
-rw-r--r--arch/arm/mach-omap2/id.c6
-rw-r--r--arch/arm/mach-omap2/io.c22
-rw-r--r--arch/arm/mach-omap2/irq.c19
-rw-r--r--arch/arm/mach-omap2/memory.c18
-rw-r--r--arch/arm/mach-omap2/mux.c38
-rw-r--r--arch/arm/mach-omap2/pm.c35
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c349
-rw-r--r--arch/arm/mach-pnx4008/pm.c6
-rw-r--r--arch/arm/mach-pxa/Kconfig34
-rw-r--r--arch/arm/mach-pxa/Makefile47
-rw-r--r--arch/arm/mach-pxa/clock.c79
-rw-r--r--arch/arm/mach-pxa/clock.h43
-rw-r--r--arch/arm/mach-pxa/cm-x270-pci.c218
-rw-r--r--arch/arm/mach-pxa/cm-x270-pci.h13
-rw-r--r--arch/arm/mach-pxa/cm-x270.c645
-rw-r--r--arch/arm/mach-pxa/devices.h3
-rw-r--r--arch/arm/mach-pxa/generic.c184
-rw-r--r--arch/arm/mach-pxa/generic.h26
-rw-r--r--arch/arm/mach-pxa/irq.c80
-rw-r--r--arch/arm/mach-pxa/lubbock.c19
-rw-r--r--arch/arm/mach-pxa/mainstone.c19
-rw-r--r--arch/arm/mach-pxa/mfp.c235
-rw-r--r--arch/arm/mach-pxa/pm.c4
-rw-r--r--arch/arm/mach-pxa/pxa25x.c94
-rw-r--r--arch/arm/mach-pxa/pxa27x.c129
-rw-r--r--arch/arm/mach-pxa/pxa300.c93
-rw-r--r--arch/arm/mach-pxa/pxa320.c88
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c216
-rw-r--r--arch/arm/mach-pxa/time.c53
-rw-r--r--arch/arm/mach-pxa/zylonite.c184
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c188
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c173
-rw-r--r--arch/arm/mach-s3c2410/dma.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c54
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c83
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c56
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c219
-rw-r--r--arch/arm/mach-s3c2412/dma.c2
-rw-r--r--arch/arm/mach-s3c2412/irq.c58
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c5
-rw-r--r--arch/arm/mach-s3c2440/dma.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c72
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c78
-rw-r--r--arch/arm/mach-s3c2443/dma.c2
-rw-r--r--arch/arm/mach-s3c2443/irq.c4
-rw-r--r--arch/arm/mach-sa1100/pm.c6
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/arm/mm/consistent.c4
-rw-r--r--arch/arm/mm/fault.c2
-rw-r--r--arch/arm/nwfpe/ARM-gcc.h2
-rw-r--r--arch/arm/nwfpe/entry.S25
-rw-r--r--arch/arm/nwfpe/fpa11.inl8
-rw-r--r--arch/arm/nwfpe/fpopcode.h6
-rw-r--r--arch/arm/plat-omap/Kconfig9
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/debug-devices.c86
-rw-r--r--arch/arm/plat-omap/dma.c6
-rw-r--r--arch/arm/plat-s3c24xx/dma.c4
-rw-r--r--arch/arm/plat-s3c24xx/pm.c6
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S8
-rw-r--r--arch/arm/vfp/Makefile2
-rw-r--r--arch/avr32/Makefile8
-rw-r--r--arch/avr32/kernel/kprobes.c2
-rw-r--r--arch/avr32/kernel/ptrace.c5
-rw-r--r--arch/avr32/mm/dma-coherent.c6
-rw-r--r--arch/avr32/mm/fault.c2
-rw-r--r--arch/blackfin/Kconfig2
-rw-r--r--arch/blackfin/Makefile4
-rw-r--r--arch/blackfin/kernel/ptrace.c6
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c6
-rw-r--r--arch/blackfin/mach-common/pm.c59
-rw-r--r--arch/cris/Makefile10
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c4
-rw-r--r--arch/cris/arch-v10/kernel/time.c8
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c4
-rw-r--r--arch/cris/arch-v32/kernel/smp.c8
-rw-r--r--arch/cris/kernel/sys_cris.c2
-rw-r--r--arch/cris/mm/fault.c2
-rw-r--r--arch/frv/Makefile32
-rw-r--r--arch/frv/kernel/sys_frv.c2
-rw-r--r--arch/frv/kernel/time.c5
-rw-r--r--arch/frv/mm/fault.c2
-rw-r--r--arch/h8300/Makefile14
-rw-r--r--arch/h8300/kernel/sys_h8300.c2
-rw-r--r--arch/h8300/lib/Makefile3
-rw-r--r--arch/i386/.gitignore1
-rw-r--r--arch/i386/Kconfig19
-rw-r--r--arch/i386/Kconfig.cpu36
-rw-r--r--arch/i386/Makefile16
-rw-r--r--arch/ia64/Kconfig10
-rw-r--r--arch/ia64/Makefile4
-rw-r--r--arch/ia64/hp/common/sba_iommu.c16
-rw-r--r--arch/ia64/hp/sim/simscsi.c1
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c2
-rw-r--r--arch/ia64/ia32/elfcore32.h1
-rw-r--r--arch/ia64/kernel/gate.lds.S135
-rw-r--r--arch/ia64/kernel/kprobes.c2
-rw-r--r--arch/ia64/kernel/machine_kexec.c30
-rw-r--r--arch/ia64/kernel/setup.c14
-rw-r--r--arch/ia64/kernel/smpboot.c18
-rw-r--r--arch/ia64/kernel/time.c5
-rw-r--r--arch/ia64/kernel/uncached.c4
-rw-r--r--arch/ia64/mm/discontig.c10
-rw-r--r--arch/ia64/mm/fault.c2
-rw-r--r--arch/ia64/mm/hugetlbpage.c4
-rw-r--r--arch/ia64/mm/init.c20
-rw-r--r--arch/ia64/sn/kernel/Makefile2
-rw-r--r--arch/ia64/sn/kernel/sn2/Makefile2
-rw-r--r--arch/ia64/sn/kernel/xpnet.c13
-rw-r--r--arch/ia64/sn/pci/Makefile2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c11
-rw-r--r--arch/ia64/sn/pci/pcibr/Makefile2
-rw-r--r--arch/m32r/Makefile8
-rw-r--r--arch/m32r/kernel/ptrace.c50
-rw-r--r--arch/m32r/kernel/sys_m32r.c2
-rw-r--r--arch/m32r/kernel/time.c8
-rw-r--r--arch/m32r/mm/fault.c2
-rw-r--r--arch/m68k/Makefile8
-rw-r--r--arch/m68k/atari/atakeyb.c2
-rw-r--r--arch/m68k/kernel/ptrace.c4
-rw-r--r--arch/m68k/kernel/sys_m68k.c2
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/m68knommu/Makefile8
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c2
-rw-r--r--arch/m68knommu/platform/5206/Makefile2
-rw-r--r--arch/m68knommu/platform/5206e/Makefile2
-rw-r--r--arch/m68knommu/platform/520x/Makefile2
-rw-r--r--arch/m68knommu/platform/523x/Makefile2
-rw-r--r--arch/m68knommu/platform/5249/Makefile2
-rw-r--r--arch/m68knommu/platform/5272/Makefile2
-rw-r--r--arch/m68knommu/platform/527x/Makefile2
-rw-r--r--arch/m68knommu/platform/528x/Makefile2
-rw-r--r--arch/m68knommu/platform/5307/Makefile2
-rw-r--r--arch/m68knommu/platform/532x/Makefile2
-rw-r--r--arch/m68knommu/platform/5407/Makefile2
-rw-r--r--arch/mips/Kconfig26
-rw-r--r--arch/mips/Makefile9
-rw-r--r--arch/mips/au1000/Kconfig2
-rw-r--r--arch/mips/au1000/common/au1xxx_irqmap.c2
-rw-r--r--arch/mips/au1000/common/dbdma.c2
-rw-r--r--arch/mips/au1000/common/irq.c729
-rw-r--r--arch/mips/au1000/common/power.c7
-rw-r--r--arch/mips/au1000/common/prom.c61
-rw-r--r--arch/mips/au1000/common/setup.c5
-rw-r--r--arch/mips/au1000/db1x00/init.c10
-rw-r--r--arch/mips/au1000/db1x00/irqmap.c2
-rw-r--r--arch/mips/au1000/mtx-1/init.c6
-rw-r--r--arch/mips/au1000/mtx-1/irqmap.c2
-rw-r--r--arch/mips/au1000/pb1000/init.c10
-rw-r--r--arch/mips/au1000/pb1000/irqmap.c2
-rw-r--r--arch/mips/au1000/pb1100/init.c10
-rw-r--r--arch/mips/au1000/pb1100/irqmap.c2
-rw-r--r--arch/mips/au1000/pb1200/board_setup.c6
-rw-r--r--arch/mips/au1000/pb1200/init.c10
-rw-r--r--arch/mips/au1000/pb1200/irqmap.c4
-rw-r--r--arch/mips/au1000/pb1500/init.c10
-rw-r--r--arch/mips/au1000/pb1500/irqmap.c2
-rw-r--r--arch/mips/au1000/pb1550/init.c10
-rw-r--r--arch/mips/au1000/pb1550/irqmap.c2
-rw-r--r--arch/mips/au1000/xxs1500/init.c10
-rw-r--r--arch/mips/au1000/xxs1500/irqmap.c2
-rw-r--r--arch/mips/configs/mtx1_defconfig2
-rw-r--r--arch/mips/jazz/irq.c6
-rw-r--r--arch/mips/jazz/setup.c8
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c68
-rw-r--r--arch/mips/kernel/Makefile4
-rw-r--r--arch/mips/kernel/cevt-r4k.c272
-rw-r--r--arch/mips/kernel/head.S20
-rw-r--r--arch/mips/kernel/irixelf.c12
-rw-r--r--arch/mips/kernel/linux32.c2
-rw-r--r--arch/mips/kernel/ptrace.c4
-rw-r--r--arch/mips/kernel/syscall.c2
-rw-r--r--arch/mips/kernel/time.c215
-rw-r--r--arch/mips/kernel/traps.c196
-rw-r--r--arch/mips/kernel/vmlinux.lds.S15
-rw-r--r--arch/mips/kernel/vpe.c27
-rw-r--r--arch/mips/lasat/interrupt.c8
-rw-r--r--arch/mips/mipssim/sim_cmdline.c5
-rw-r--r--arch/mips/mm/c-r4k.c10
-rw-r--r--arch/mips/mm/cache.c2
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips/mm/init.c19
-rw-r--r--arch/mips/pci/ops-pmcmsp.c2
-rw-r--r--arch/mips/pci/pci-lasat.c19
-rw-r--r--arch/mips/pmc-sierra/Kconfig2
-rw-r--r--arch/mips/sgi-ip22/Makefile2
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c9
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c9
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c155
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c162
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c6
-rw-r--r--arch/mips/sibyte/bcm1480/time.c2
-rw-r--r--arch/mips/sibyte/sb1250/time.c8
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c2
-rw-r--r--arch/mips/vr41xx/Kconfig6
-rw-r--r--arch/parisc/Makefile2
-rw-r--r--arch/parisc/kernel/ptrace.c4
-rw-r--r--arch/parisc/math-emu/Makefile2
-rw-r--r--arch/parisc/mm/fault.c2
-rw-r--r--arch/powerpc/Kconfig6
-rw-r--r--arch/powerpc/Kconfig.debug6
-rw-r--r--arch/powerpc/Makefile30
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts18
-rw-r--r--arch/powerpc/configs/bamboo_defconfig7
-rw-r--r--arch/powerpc/configs/celleb_defconfig7
-rw-r--r--arch/powerpc/configs/chrp32_defconfig7
-rw-r--r--arch/powerpc/configs/ebony_defconfig7
-rw-r--r--arch/powerpc/configs/g5_defconfig7
-rw-r--r--arch/powerpc/configs/holly_defconfig7
-rw-r--r--arch/powerpc/configs/iseries_defconfig7
-rw-r--r--arch/powerpc/configs/kilauea_defconfig7
-rw-r--r--arch/powerpc/configs/linkstation_defconfig7
-rw-r--r--arch/powerpc/configs/lite5200_defconfig7
-rw-r--r--arch/powerpc/configs/maple_defconfig8
-rw-r--r--arch/powerpc/configs/mpc7448_hpc2_defconfig5
-rw-r--r--arch/powerpc/configs/mpc8272_ads_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8313_rdb_defconfig7
-rw-r--r--arch/powerpc/configs/mpc832x_mds_defconfig5
-rw-r--r--arch/powerpc/configs/mpc832x_rdb_defconfig5
-rw-r--r--arch/powerpc/configs/mpc834x_itx_defconfig5
-rw-r--r--arch/powerpc/configs/mpc834x_itxgp_defconfig5
-rw-r--r--arch/powerpc/configs/mpc834x_mds_defconfig5
-rw-r--r--arch/powerpc/configs/mpc836x_mds_defconfig5
-rw-r--r--arch/powerpc/configs/mpc8540_ads_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8544_ds_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8560_ads_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8568mds_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8572_ds_defconfig7
-rw-r--r--arch/powerpc/configs/mpc85xx_cds_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8610_hpcd_defconfig7
-rw-r--r--arch/powerpc/configs/mpc8641_hpcn_defconfig7
-rw-r--r--arch/powerpc/configs/mpc866_ads_defconfig5
-rw-r--r--arch/powerpc/configs/pasemi_defconfig7
-rw-r--r--arch/powerpc/configs/pmac32_defconfig8
-rw-r--r--arch/powerpc/configs/ppc64_defconfig11
-rw-r--r--arch/powerpc/configs/pq2fads_defconfig7
-rw-r--r--arch/powerpc/configs/prpmc2800_defconfig5
-rw-r--r--arch/powerpc/configs/ps3_defconfig7
-rw-r--r--arch/powerpc/configs/pseries_defconfig11
-rw-r--r--arch/powerpc/configs/sequoia_defconfig7
-rw-r--r--arch/powerpc/configs/walnut_defconfig7
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kernel/binfmt_elf32.c67
-rw-r--r--arch/powerpc/kernel/dma_64.c5
-rw-r--r--arch/powerpc/kernel/entry_64.S6
-rw-r--r--arch/powerpc/kernel/ibmebus.c274
-rw-r--r--arch/powerpc/kernel/iommu.c23
-rw-r--r--arch/powerpc/kernel/kprobes.c2
-rw-r--r--arch/powerpc/kernel/of_device.c80
-rw-r--r--arch/powerpc/kernel/of_platform.c70
-rw-r--r--arch/powerpc/kernel/process.c28
-rw-r--r--arch/powerpc/kernel/ptrace.c4
-rw-r--r--arch/powerpc/kernel/rtas_flash.c2
-rw-r--r--arch/powerpc/kernel/setup-common.c20
-rw-r--r--arch/powerpc/kernel/setup_64.c16
-rw-r--r--arch/powerpc/kernel/smp.c4
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c2
-rw-r--r--arch/powerpc/kernel/syscalls.c1
-rw-r--r--arch/powerpc/kernel/time.c34
-rw-r--r--arch/powerpc/kernel/vdso32/vdso32.lds.S219
-rw-r--r--arch/powerpc/kernel/vdso64/sigtramp.S11
-rw-r--r--arch/powerpc/kernel/vdso64/vdso64.lds.S225
-rw-r--r--arch/powerpc/lib/Makefile5
-rw-r--r--arch/powerpc/lib/rheap.c15
-rw-r--r--arch/powerpc/math-emu/math.c13
-rw-r--r--arch/powerpc/mm/hash_utils_64.c3
-rw-r--r--arch/powerpc/mm/hugetlbpage.c2
-rw-r--r--arch/powerpc/mm/init_64.c70
-rw-r--r--arch/powerpc/mm/mem.c45
-rw-r--r--arch/powerpc/mm/slb.c3
-rw-r--r--arch/powerpc/mm/slice.c2
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c34
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pm.c15
-rw-r--r--arch/powerpc/platforms/Kconfig6
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype1
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c11
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c2
-rw-r--r--arch/powerpc/platforms/iseries/htab.c4
-rw-r--r--arch/powerpc/platforms/iseries/vio.c2
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c56
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c7
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/bestcomm/Kconfig39
-rw-r--r--arch/powerpc/sysdev/bestcomm/Makefile14
-rw-r--r--arch/powerpc/sysdev/bestcomm/ata.c154
-rw-r--r--arch/powerpc/sysdev/bestcomm/ata.h37
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_ata_task.c67
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c78
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c91
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c63
-rw-r--r--arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c69
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.c528
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.h190
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm_priv.h334
-rw-r--r--arch/powerpc/sysdev/bestcomm/fec.c270
-rw-r--r--arch/powerpc/sysdev/bestcomm/fec.h61
-rw-r--r--arch/powerpc/sysdev/bestcomm/gen_bd.c260
-rw-r--r--arch/powerpc/sysdev/bestcomm/gen_bd.h48
-rw-r--r--arch/powerpc/sysdev/bestcomm/sram.c177
-rw-r--r--arch/powerpc/sysdev/bestcomm/sram.h54
-rw-r--r--arch/powerpc/sysdev/dcr.c4
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c4
-rw-r--r--arch/ppc/Kconfig6
-rw-r--r--arch/ppc/Makefile16
-rw-r--r--arch/ppc/boot/Makefile1
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/s390/Makefile14
-rw-r--r--arch/s390/kernel/compat_linux.c2
-rw-r--r--arch/s390/kernel/entry.S12
-rw-r--r--arch/s390/kernel/entry64.S9
-rw-r--r--arch/s390/kernel/kprobes.c2
-rw-r--r--arch/s390/kernel/ptrace.c5
-rw-r--r--arch/s390/kernel/sys_s390.c2
-rw-r--r--arch/s390/mm/cmm.c1
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/Makefile6
-rw-r--r--arch/sh/boards/hp6xx/pm.c6
-rw-r--r--arch/sh/boot/compressed/Makefile2
-rw-r--r--arch/sh/drivers/pci/dma-dreamcast.c2
-rw-r--r--arch/sh/kernel/ptrace.c4
-rw-r--r--arch/sh/kernel/sys_sh.c2
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.lds.S77
-rw-r--r--arch/sh/mm/consistent.c8
-rw-r--r--arch/sh/mm/fault.c2
-rw-r--r--arch/sh/mm/init.c6
-rw-r--r--arch/sh/mm/pmb.c3
-rw-r--r--arch/sh64/Makefile4
-rw-r--r--arch/sh64/kernel/ptrace.c4
-rw-r--r--arch/sh64/kernel/sys_sh64.c2
-rw-r--r--arch/sh64/mm/consistent.c3
-rw-r--r--arch/sh64/mm/fault.c2
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/Makefile8
-rw-r--r--arch/sparc/kernel/ioport.c25
-rw-r--r--arch/sparc/kernel/of_device.c20
-rw-r--r--arch/sparc/kernel/sys_sparc.c2
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc/mm/io-unit.c12
-rw-r--r--arch/sparc/mm/iommu.c10
-rw-r--r--arch/sparc/mm/sun4c.c10
-rw-r--r--arch/sparc64/Kconfig3
-rw-r--r--arch/sparc64/Makefile8
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c17
-rw-r--r--arch/sparc64/kernel/iommu.c46
-rw-r--r--arch/sparc64/kernel/iommu_common.c51
-rw-r--r--arch/sparc64/kernel/iommu_common.h1
-rw-r--r--arch/sparc64/kernel/irq.c8
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/ktlb.S16
-rw-r--r--arch/sparc64/kernel/of_device.c20
-rw-r--r--arch/sparc64/kernel/pci_common.c7
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c36
-rw-r--r--arch/sparc64/kernel/smp.c17
-rw-r--r--arch/sparc64/kernel/sys_sparc.c1
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c1
-rw-r--r--arch/sparc64/lib/atomic.S38
-rw-r--r--arch/sparc64/lib/bitops.S30
-rw-r--r--arch/sparc64/mm/fault.c2
-rw-r--r--arch/sparc64/mm/init.c57
-rw-r--r--arch/sparc64/solaris/ipc.c2
-rw-r--r--arch/um/Kconfig244
-rw-r--r--arch/um/Kconfig.char141
-rw-r--r--arch/um/Kconfig.debug47
-rw-r--r--arch/um/Kconfig.i38614
-rw-r--r--arch/um/Kconfig.net22
-rw-r--r--arch/um/Kconfig.x86_6414
-rw-r--r--arch/um/Makefile47
-rw-r--r--arch/um/Makefile-i38612
-rw-r--r--arch/um/Makefile-os-Linux2
-rw-r--r--arch/um/Makefile-x86_646
-rw-r--r--arch/um/defconfig11
-rw-r--r--arch/um/drivers/Makefile13
-rw-r--r--arch/um/drivers/chan_kern.c211
-rw-r--r--arch/um/drivers/chan_user.c211
-rw-r--r--arch/um/drivers/cow_user.c133
-rw-r--r--arch/um/drivers/daemon.h20
-rw-r--r--arch/um/drivers/daemon_kern.c34
-rw-r--r--arch/um/drivers/daemon_user.c92
-rw-r--r--arch/um/drivers/fd.c69
-rw-r--r--arch/um/drivers/harddog_kern.c2
-rw-r--r--arch/um/drivers/harddog_user.c58
-rw-r--r--arch/um/drivers/hostaudio_kern.c118
-rw-r--r--arch/um/drivers/line.c237
-rw-r--r--arch/um/drivers/mcast.h16
-rw-r--r--arch/um/drivers/mcast_kern.c56
-rw-r--r--arch/um/drivers/mcast_user.c73
-rw-r--r--arch/um/drivers/mconsole_kern.c289
-rw-r--r--arch/um/drivers/mconsole_user.c119
-rw-r--r--arch/um/drivers/mmapper_kern.c64
-rw-r--r--arch/um/drivers/net_kern.c278
-rw-r--r--arch/um/drivers/net_user.c126
-rw-r--r--arch/um/drivers/null.c28
-rw-r--r--arch/um/drivers/pcap_kern.c38
-rw-r--r--arch/um/drivers/pcap_user.c58
-rw-r--r--arch/um/drivers/port_kern.c86
-rw-r--r--arch/um/drivers/port_user.c73
-rw-r--r--arch/um/drivers/pty.c30
-rw-r--r--arch/um/drivers/slip_kern.c42
-rw-r--r--arch/um/drivers/slip_user.c129
-rw-r--r--arch/um/drivers/slirp_kern.c63
-rw-r--r--arch/um/drivers/slirp_user.c74
-rw-r--r--arch/um/drivers/tty.c37
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/drivers/vde.h32
-rw-r--r--arch/um/drivers/vde_kern.c129
-rw-r--r--arch/um/drivers/vde_user.c127
-rw-r--r--arch/um/drivers/xterm.c28
-rw-r--r--arch/um/include/arch.h4
-rw-r--r--arch/um/include/as-layout.h27
-rw-r--r--arch/um/include/choose-mode.h38
-rw-r--r--arch/um/include/common-offsets.h10
-rw-r--r--arch/um/include/irq_user.h10
-rw-r--r--arch/um/include/kern_util.h30
-rw-r--r--arch/um/include/mconsole.h15
-rw-r--r--arch/um/include/mem.h21
-rw-r--r--arch/um/include/mode.h30
-rw-r--r--arch/um/include/mode_kern.h17
-rw-r--r--arch/um/include/net_kern.h13
-rw-r--r--arch/um/include/net_user.h4
-rw-r--r--arch/um/include/os.h69
-rw-r--r--arch/um/include/registers.h10
-rw-r--r--arch/um/include/skas/mmu-skas.h23
-rw-r--r--arch/um/include/skas/mode-skas.h9
-rw-r--r--arch/um/include/skas/mode_kern_skas.h41
-rw-r--r--arch/um/include/skas/skas.h5
-rw-r--r--arch/um/include/skas/uaccess-skas.h21
-rw-r--r--arch/um/include/sysdep-i386/kernel-offsets.h1
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h133
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h30
-rw-r--r--arch/um/include/sysdep-i386/stub.h14
-rw-r--r--arch/um/include/sysdep-i386/thread.h11
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h277
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h28
-rw-r--r--arch/um/include/sysdep-x86_64/stub.h13
-rw-r--r--arch/um/include/sysdep-x86_64/thread.h10
-rw-r--r--arch/um/include/task.h2
-rw-r--r--arch/um/include/tlb.h27
-rw-r--r--arch/um/include/tt/debug.h18
-rw-r--r--arch/um/include/tt/mmu-tt.h12
-rw-r--r--arch/um/include/tt/mode-tt.h23
-rw-r--r--arch/um/include/tt/mode_kern_tt.h40
-rw-r--r--arch/um/include/tt/tt.h37
-rw-r--r--arch/um/include/tt/uaccess-tt.h46
-rw-r--r--arch/um/include/um_mmu.h40
-rw-r--r--arch/um/include/um_uaccess.h64
-rw-r--r--arch/um/include/uml_uaccess.h24
-rw-r--r--arch/um/include/user.h8
-rw-r--r--arch/um/kernel/Makefile7
-rw-r--r--arch/um/kernel/dyn.lds.S2
-rw-r--r--arch/um/kernel/exec.c58
-rw-r--r--arch/um/kernel/init_task.c13
-rw-r--r--arch/um/kernel/irq.c113
-rw-r--r--arch/um/kernel/ksyms.c41
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/um/kernel/physmem.c69
-rw-r--r--arch/um/kernel/process.c226
-rw-r--r--arch/um/kernel/ptrace.c141
-rw-r--r--arch/um/kernel/reboot.c57
-rw-r--r--arch/um/kernel/signal.c59
-rw-r--r--arch/um/kernel/skas/Makefile4
-rw-r--r--arch/um/kernel/skas/clone.c6
-rw-r--r--arch/um/kernel/skas/exec.c40
-rw-r--r--arch/um/kernel/skas/mem.c22
-rw-r--r--arch/um/kernel/skas/mmu.c81
-rw-r--r--arch/um/kernel/skas/process.c187
-rw-r--r--arch/um/kernel/skas/syscall.c21
-rw-r--r--arch/um/kernel/skas/tlb.c164
-rw-r--r--arch/um/kernel/skas/uaccess.c146
-rw-r--r--arch/um/kernel/smp.c36
-rw-r--r--arch/um/kernel/syscall.c40
-rw-r--r--arch/um/kernel/time.c223
-rw-r--r--arch/um/kernel/tlb.c418
-rw-r--r--arch/um/kernel/trap.c129
-rw-r--r--arch/um/kernel/tt/Makefile14
-rw-r--r--arch/um/kernel/tt/exec_kern.c84
-rw-r--r--arch/um/kernel/tt/exec_user.c56
-rw-r--r--arch/um/kernel/tt/gdb.c280
-rw-r--r--arch/um/kernel/tt/gdb_kern.c40
-rw-r--r--arch/um/kernel/tt/include/mode-tt.h34
-rw-r--r--arch/um/kernel/tt/ksyms.c29
-rw-r--r--arch/um/kernel/tt/mem.c34
-rw-r--r--arch/um/kernel/tt/mem_user.c49
-rw-r--r--arch/um/kernel/tt/process_kern.c461
-rw-r--r--arch/um/kernel/tt/ptproxy/Makefile10
-rw-r--r--arch/um/kernel/tt/ptproxy/proxy.c377
-rw-r--r--arch/um/kernel/tt/ptproxy/ptproxy.h61
-rw-r--r--arch/um/kernel/tt/ptproxy/ptrace.c237
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c70
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.h25
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.c85
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.h15
-rw-r--r--arch/um/kernel/tt/syscall_kern.c46
-rw-r--r--arch/um/kernel/tt/syscall_user.c60
-rw-r--r--arch/um/kernel/tt/tlb.c120
-rw-r--r--arch/um/kernel/tt/tracer.c461
-rw-r--r--arch/um/kernel/tt/trap_user.c70
-rw-r--r--arch/um/kernel/tt/uaccess.c73
-rw-r--r--arch/um/kernel/tt/uaccess_user.c105
-rw-r--r--arch/um/kernel/uaccess.c2
-rw-r--r--arch/um/kernel/um_arch.c217
-rw-r--r--arch/um/kernel/uml.lds.S7
-rw-r--r--arch/um/os-Linux/Makefile15
-rw-r--r--arch/um/os-Linux/aio.c122
-rw-r--r--arch/um/os-Linux/drivers/etap.h16
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c52
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c132
-rw-r--r--arch/um/os-Linux/drivers/tuntap.h13
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c35
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c102
-rw-r--r--arch/um/os-Linux/file.c130
-rw-r--r--arch/um/os-Linux/helper.c8
-rw-r--r--arch/um/os-Linux/irq.c6
-rw-r--r--arch/um/os-Linux/main.c120
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/process.c175
-rw-r--r--arch/um/os-Linux/registers.c57
-rw-r--r--arch/um/os-Linux/signal.c131
-rw-r--r--arch/um/os-Linux/skas/mem.c109
-rw-r--r--arch/um/os-Linux/skas/process.c316
-rw-r--r--arch/um/os-Linux/skas/trap.c51
-rw-r--r--arch/um/os-Linux/start_up.c218
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile4
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c129
-rw-r--r--arch/um/os-Linux/sys-x86_64/Makefile4
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c75
-rw-r--r--arch/um/os-Linux/time.c111
-rw-r--r--arch/um/os-Linux/tls.c40
-rw-r--r--arch/um/os-Linux/trap.c23
-rw-r--r--arch/um/os-Linux/tt.c196
-rw-r--r--arch/um/os-Linux/uaccess.c2
-rw-r--r--arch/um/os-Linux/umid.c137
-rw-r--r--arch/um/os-Linux/util.c38
-rw-r--r--arch/um/scripts/Makefile.rules2
-rw-r--r--arch/um/sys-i386/Makefile14
-rw-r--r--arch/um/sys-i386/bugs.c108
-rw-r--r--arch/um/sys-i386/fault.c10
-rw-r--r--arch/um/sys-i386/ldt.c306
-rw-r--r--arch/um/sys-i386/ptrace.c368
-rw-r--r--arch/um/sys-i386/ptrace_user.c100
-rw-r--r--arch/um/sys-i386/sigcontext.c71
-rw-r--r--arch/um/sys-i386/signal.c409
-rw-r--r--arch/um/sys-i386/stub.S9
-rw-r--r--arch/um/sys-i386/stub_segv.c4
-rw-r--r--arch/um/sys-i386/syscalls.c2
-rw-r--r--arch/um/sys-i386/tls.c101
-rw-r--r--arch/um/sys-i386/unmap.c25
-rw-r--r--arch/um/sys-i386/user-offsets.c6
-rw-r--r--arch/um/sys-ppc/Makefile6
-rw-r--r--arch/um/sys-x86_64/Makefile11
-rw-r--r--arch/um/sys-x86_64/bugs.c2
-rw-r--r--arch/um/sys-x86_64/fault.c9
-rw-r--r--arch/um/sys-x86_64/ptrace.c154
-rw-r--r--arch/um/sys-x86_64/sigcontext.c39
-rw-r--r--arch/um/sys-x86_64/signal.c297
-rw-r--r--arch/um/sys-x86_64/stub.S9
-rw-r--r--arch/um/sys-x86_64/stub_segv.c3
-rw-r--r--arch/um/sys-x86_64/syscalls.c108
-rw-r--r--arch/um/sys-x86_64/tls.c4
-rw-r--r--arch/um/sys-x86_64/unmap.c25
-rw-r--r--arch/um/sys-x86_64/user-offsets.c9
-rw-r--r--arch/v850/Makefile8
-rw-r--r--arch/v850/kernel/fpga85e2c.c5
-rw-r--r--arch/v850/kernel/syscalls.c1
-rw-r--r--arch/v850/kernel/time.c11
-rw-r--r--arch/x86/boot/Makefile11
-rw-r--r--arch/x86/boot/compressed/Makefile_322
-rw-r--r--arch/x86/boot/compressed/Makefile_644
-rw-r--r--arch/x86/ia32/Makefile25
-rw-r--r--arch/x86/ia32/ia32_aout.c12
-rw-r--r--arch/x86/ia32/ia32_binfmt.c7
-rw-r--r--arch/x86/ia32/ipc32.c2
-rw-r--r--arch/x86/ia32/ptrace32.c10
-rw-r--r--arch/x86/kernel/.gitignore1
-rw-r--r--arch/x86/kernel/Makefile4
-rw-r--r--arch/x86/kernel/Makefile_322
-rw-r--r--arch/x86/kernel/acpi/wakeup_32.S12
-rw-r--r--arch/x86/kernel/acpi/wakeup_64.S32
-rw-r--r--arch/x86/kernel/alternative.c65
-rw-r--r--arch/x86/kernel/apic_32.c1
-rw-r--r--arch/x86/kernel/apic_64.c4
-rw-r--r--arch/x86/kernel/asm-offsets_32.c14
-rw-r--r--arch/x86/kernel/cpu/amd.c15
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k7.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c10
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c2
-rw-r--r--arch/x86/kernel/cpu/intel.c17
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c77
-rw-r--r--arch/x86/kernel/cpu/mcheck/p4.c1
-rw-r--r--arch/x86/kernel/cpu/mcheck/therm_throt.c12
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c8
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c14
-rw-r--r--arch/x86/kernel/cpu/proc.c3
-rw-r--r--arch/x86/kernel/cpuid.c28
-rw-r--r--arch/x86/kernel/e820_64.c19
-rw-r--r--arch/x86/kernel/early_printk.c15
-rw-r--r--arch/x86/kernel/efi_32.c15
-rw-r--r--arch/x86/kernel/entry_32.S6
-rw-r--r--arch/x86/kernel/entry_64.S25
-rw-r--r--arch/x86/kernel/genapic_64.c2
-rw-r--r--arch/x86/kernel/genapic_flat_64.c1
-rw-r--r--arch/x86/kernel/head64.c20
-rw-r--r--arch/x86/kernel/head_32.S21
-rw-r--r--arch/x86/kernel/i386_ksyms_32.c1
-rw-r--r--arch/x86/kernel/i8259_32.c6
-rw-r--r--arch/x86/kernel/i8259_64.c6
-rw-r--r--arch/x86/kernel/io_apic_32.c9
-rw-r--r--arch/x86/kernel/io_apic_64.c11
-rw-r--r--arch/x86/kernel/irq_32.c49
-rw-r--r--arch/x86/kernel/irq_64.c48
-rw-r--r--arch/x86/kernel/kprobes_32.c17
-rw-r--r--arch/x86/kernel/kprobes_64.c15
-rw-r--r--arch/x86/kernel/ldt_32.c14
-rw-r--r--arch/x86/kernel/ldt_64.c14
-rw-r--r--arch/x86/kernel/machine_kexec_32.c13
-rw-r--r--arch/x86/kernel/machine_kexec_64.c9
-rw-r--r--arch/x86/kernel/mce_64.c46
-rw-r--r--arch/x86/kernel/mce_amd_64.c7
-rw-r--r--arch/x86/kernel/mce_intel_64.c1
-rw-r--r--arch/x86/kernel/msr.c37
-rw-r--r--arch/x86/kernel/paravirt_32.c224
-rw-r--r--arch/x86/kernel/pci-calgary_64.c65
-rw-r--r--arch/x86/kernel/pci-dma_32.c1
-rw-r--r--arch/x86/kernel/pci-dma_64.c8
-rw-r--r--arch/x86/kernel/pci-gart_64.c69
-rw-r--r--arch/x86/kernel/pci-nommu_64.c5
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/ptrace_32.c9
-rw-r--r--arch/x86/kernel/ptrace_64.c9
-rw-r--r--arch/x86/kernel/setup64.c4
-rw-r--r--arch/x86/kernel/setup_32.c67
-rw-r--r--arch/x86/kernel/setup_64.c60
-rw-r--r--arch/x86/kernel/signal_32.c2
-rw-r--r--arch/x86/kernel/smp_32.c10
-rw-r--r--arch/x86/kernel/smp_64.c3
-rw-r--r--arch/x86/kernel/smpboot_32.c80
-rw-r--r--arch/x86/kernel/smpboot_64.c53
-rw-r--r--arch/x86/kernel/stacktrace.c2
-rw-r--r--arch/x86/kernel/suspend_64.c101
-rw-r--r--arch/x86/kernel/suspend_asm_64.S49
-rw-r--r--arch/x86/kernel/sys_i386_32.c2
-rw-r--r--arch/x86/kernel/tce_64.c4
-rw-r--r--arch/x86/kernel/topology.c6
-rw-r--r--arch/x86/kernel/trampoline_32.S4
-rw-r--r--arch/x86/kernel/trampoline_64.S7
-rw-r--r--arch/x86/kernel/traps_32.c37
-rw-r--r--arch/x86/kernel/traps_64.c4
-rw-r--r--arch/x86/kernel/tsc_32.c6
-rw-r--r--arch/x86/kernel/vmi_32.c201
-rw-r--r--arch/x86/kernel/vsyscall_64.c26
-rw-r--r--arch/x86/lib/bitstr_64.c2
-rw-r--r--arch/x86/lib/msr-on-cpu.c62
-rw-r--r--arch/x86/lib/rwlock_64.S2
-rw-r--r--arch/x86/lib/semaphore_32.S4
-rw-r--r--arch/x86/lib/string_32.c20
-rw-r--r--arch/x86/lib/thunk_64.S4
-rw-r--r--arch/x86/mach-default/setup.c18
-rw-r--r--arch/x86/mach-es7000/es7000plat.c32
-rw-r--r--arch/x86/mach-generic/probe.c2
-rw-r--r--arch/x86/mach-visws/setup.c2
-rw-r--r--arch/x86/mach-voyager/setup.c20
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c5
-rw-r--r--arch/x86/math-emu/Makefile3
-rw-r--r--arch/x86/mm/discontig_32.c15
-rw-r--r--arch/x86/mm/fault_32.c62
-rw-r--r--arch/x86/mm/fault_64.c44
-rw-r--r--arch/x86/mm/init_32.c38
-rw-r--r--arch/x86/mm/init_64.c51
-rw-r--r--arch/x86/mm/numa_64.c6
-rw-r--r--arch/x86/mm/pageattr_32.c4
-rw-r--r--arch/x86/mm/pageattr_64.c3
-rw-r--r--arch/x86/mm/pgtable_32.c8
-rw-r--r--arch/x86/mm/srat_64.c4
-rw-r--r--arch/x86/oprofile/nmi_int.c2
-rw-r--r--arch/x86/oprofile/op_model_p4.c2
-rw-r--r--arch/x86/pci/common.c16
-rw-r--r--arch/x86/vdso/Makefile21
-rw-r--r--arch/x86/vdso/vdso.lds.S16
-rw-r--r--arch/x86/vdso/vvar.c2
-rw-r--r--arch/x86/xen/enlighten.c240
-rw-r--r--arch/x86/xen/mmu.c145
-rw-r--r--arch/x86/xen/multicalls.c52
-rw-r--r--arch/x86/xen/multicalls.h5
-rw-r--r--arch/x86/xen/smp.c33
-rw-r--r--arch/x86/xen/time.c6
-rw-r--r--arch/x86/xen/xen-ops.h10
-rw-r--r--arch/x86_64/Kconfig42
-rw-r--r--arch/x86_64/Makefile16
-rw-r--r--arch/xtensa/Makefile8
-rw-r--r--arch/xtensa/boot/Makefile5
-rw-r--r--arch/xtensa/boot/boot-redboot/Makefile2
-rw-r--r--arch/xtensa/kernel/ptrace.c4
-rw-r--r--arch/xtensa/mm/fault.c2
-rw-r--r--block/blktrace.c2
-rw-r--r--block/bsg.c2
-rw-r--r--block/elevator.c17
-rw-r--r--block/ll_rw_blk.c338
-rw-r--r--crypto/digest.c2
-rw-r--r--crypto/scatterwalk.c2
-rw-r--r--crypto/scatterwalk.h2
-rw-r--r--drivers/Kconfig4
-rw-r--r--drivers/Makefile3
-rw-r--r--drivers/acorn/char/defkeymap-l7200.c2
-rw-r--r--drivers/acpi/sleep/main.c37
-rw-r--r--drivers/ata/Kconfig25
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/ata/ata_piix.c35
-rw-r--r--drivers/ata/libata-core.c44
-rw-r--r--drivers/ata/libata-scsi.c9
-rw-r--r--drivers/ata/libata-sff.c4
-rw-r--r--drivers/ata/pata_acpi.c2
-rw-r--r--drivers/ata/pata_bf54x.c77
-rw-r--r--drivers/ata/pata_cs5536.c344
-rw-r--r--drivers/ata/pata_pcmcia.c2
-rw-r--r--drivers/ata/pata_sil680.c61
-rw-r--r--drivers/ata/pdc_adma.c9
-rw-r--r--drivers/ata/sata_fsl.c1490
-rw-r--r--drivers/ata/sata_mv.c26
-rw-r--r--drivers/ata/sata_nv.c851
-rw-r--r--drivers/ata/sata_sil24.c11
-rw-r--r--drivers/atm/Makefile2
-rw-r--r--drivers/base/dmapool.c4
-rw-r--r--drivers/base/memory.c6
-rw-r--r--drivers/base/node.c91
-rw-r--r--drivers/base/power/trace.c2
-rw-r--r--drivers/base/topology.c11
-rw-r--r--drivers/block/aoe/aoe.h9
-rw-r--r--drivers/block/aoe/aoecmd.c14
-rw-r--r--drivers/block/aoe/aoenet.c2
-rw-r--r--drivers/block/cciss.c148
-rw-r--r--drivers/block/cpqarray.c3
-rw-r--r--drivers/block/floppy.c167
-rw-r--r--drivers/block/loop.c75
-rw-r--r--drivers/block/nbd.c114
-rw-r--r--drivers/block/pktcdvd.c7
-rw-r--r--drivers/block/ps3disk.c21
-rw-r--r--drivers/block/rd.c27
-rw-r--r--drivers/block/xsysace.c4
-rw-r--r--drivers/cdrom/cdrom.c46
-rw-r--r--drivers/char/Kconfig10
-rw-r--r--drivers/char/agp/Kconfig2
-rw-r--r--drivers/char/agp/efficeon-agp.c11
-rw-r--r--drivers/char/agp/hp-agp.c9
-rw-r--r--drivers/char/agp/i460-agp.c5
-rw-r--r--drivers/char/agp/parisc-agp.c7
-rw-r--r--drivers/char/apm-emulation.c2
-rw-r--r--drivers/char/consolemap.c25
-rw-r--r--drivers/char/cyclades.c767
-rw-r--r--drivers/char/defkeymap.c_shipped2
-rw-r--r--drivers/char/drm/Kconfig2
-rw-r--r--drivers/char/drm/radeon_irq.c4
-rw-r--r--drivers/char/ec3104_keyb.c457
-rw-r--r--drivers/char/epca.c2611
-rw-r--r--drivers/char/hvc_console.c56
-rw-r--r--drivers/char/hvc_lguest.c2
-rw-r--r--drivers/char/ip2/ip2main.c11
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c27
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c29
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c268
-rw-r--r--drivers/char/isicom.c10
-rw-r--r--drivers/char/keyboard.c37
-rw-r--r--drivers/char/lp.c17
-rw-r--r--drivers/char/mbcs.c1
-rw-r--r--drivers/char/mem.c130
-rw-r--r--drivers/char/moxa.c148
-rw-r--r--drivers/char/mspec.c2
-rw-r--r--drivers/char/mxser.c23
-rw-r--r--drivers/char/mxser.h3
-rw-r--r--drivers/char/mxser_new.c120
-rw-r--r--drivers/char/n_hdlc.c2
-rw-r--r--drivers/char/ppdev.c1
-rw-r--r--drivers/char/pty.c24
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/rocket.c91
-rw-r--r--drivers/char/rocket_int.h7
-rw-r--r--drivers/char/synclink.c4
-rw-r--r--drivers/char/sysrq.c5
-rw-r--r--drivers/char/tpm/tpm_tis.c22
-rw-r--r--drivers/char/tty_ioctl.c93
-rw-r--r--drivers/char/vt.c15
-rw-r--r--drivers/char/vt_ioctl.c63
-rw-r--r--drivers/dca/Kconfig7
-rw-r--r--drivers/dca/Makefile2
-rw-r--r--drivers/dca/dca-core.c200
-rw-r--r--drivers/dca/dca-sysfs.c88
-rw-r--r--drivers/dma/Kconfig60
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/ioat.c200
-rw-r--r--drivers/dma/ioat_dca.c263
-rw-r--r--drivers/dma/ioat_dma.c1009
-rw-r--r--drivers/dma/ioatdma.c817
-rw-r--r--drivers/dma/ioatdma.h43
-rw-r--r--drivers/dma/ioatdma_hw.h2
-rw-r--r--drivers/dma/ioatdma_registers.h6
-rw-r--r--drivers/dma/iop-adma.c9
-rw-r--r--drivers/firewire/fw-cdev.c52
-rw-r--r--drivers/firewire/fw-device.h5
-rw-r--r--drivers/firewire/fw-ohci.c41
-rw-r--r--drivers/firewire/fw-ohci.h2
-rw-r--r--drivers/firewire/fw-sbp2.c647
-rw-r--r--drivers/firewire/fw-topology.c10
-rw-r--r--drivers/firewire/fw-topology.h6
-rw-r--r--drivers/firewire/fw-transaction.c12
-rw-r--r--drivers/hwmon/Kconfig3
-rw-r--r--drivers/hwmon/adm1026.c2
-rw-r--r--drivers/hwmon/ams/ams-input.c76
-rw-r--r--drivers/hwmon/ams/ams.h5
-rw-r--r--drivers/hwmon/applesmc.c83
-rw-r--r--drivers/hwmon/hdaps.c55
-rw-r--r--drivers/hwmon/lm63.c2
-rw-r--r--drivers/hwmon/vt1211.c2
-rw-r--r--drivers/hwmon/w83791d.c2
-rw-r--r--drivers/hwmon/w83792d.c4
-rw-r--r--drivers/i2c/busses/i2c-pmcmsp.c8
-rw-r--r--drivers/i2c/busses/i2c-pnx.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c45
-rw-r--r--drivers/i2c/chips/menelaus.c12
-rw-r--r--drivers/ide/Kconfig18
-rw-r--r--drivers/ide/arm/icside.c18
-rw-r--r--drivers/ide/cris/ide-cris.c19
-rw-r--r--drivers/ide/ide-disk.c37
-rw-r--r--drivers/ide/ide-dma.c85
-rw-r--r--drivers/ide/ide-io.c45
-rw-r--r--drivers/ide/ide-iops.c4
-rw-r--r--drivers/ide/ide-lib.c15
-rw-r--r--drivers/ide/ide-probe.c21
-rw-r--r--drivers/ide/ide-taskfile.c18
-rw-r--r--drivers/ide/ide.c23
-rw-r--r--drivers/ide/legacy/ide-cs.c12
-rw-r--r--drivers/ide/mips/au1xxx-ide.c43
-rw-r--r--drivers/ide/pci/aec62xx.c127
-rw-r--r--drivers/ide/pci/alim15x3.c64
-rw-r--r--drivers/ide/pci/amd74xx.c228
-rw-r--r--drivers/ide/pci/atiixp.c112
-rw-r--r--drivers/ide/pci/cmd64x.c112
-rw-r--r--drivers/ide/pci/cs5520.c54
-rw-r--r--drivers/ide/pci/cs5530.c57
-rw-r--r--drivers/ide/pci/cs5535.c43
-rw-r--r--drivers/ide/pci/cy82c693.c28
-rw-r--r--drivers/ide/pci/generic.c175
-rw-r--r--drivers/ide/pci/hpt34x.c78
-rw-r--r--drivers/ide/pci/hpt366.c411
-rw-r--r--drivers/ide/pci/it8213.c100
-rw-r--r--drivers/ide/pci/it821x.c72
-rw-r--r--drivers/ide/pci/jmicron.c44
-rw-r--r--drivers/ide/pci/ns87415.c15
-rw-r--r--drivers/ide/pci/opti621.c36
-rw-r--r--drivers/ide/pci/pdc202xx_new.c238
-rw-r--r--drivers/ide/pci/pdc202xx_old.c167
-rw-r--r--drivers/ide/pci/piix.c284
-rw-r--r--drivers/ide/pci/rz1000.c9
-rw-r--r--drivers/ide/pci/sc1200.c43
-rw-r--r--drivers/ide/pci/scc_pata.c59
-rw-r--r--drivers/ide/pci/serverworks.c119
-rw-r--r--drivers/ide/pci/sgiioc4.c36
-rw-r--r--drivers/ide/pci/siimage.c77
-rw-r--r--drivers/ide/pci/sis5513.c470
-rw-r--r--drivers/ide/pci/sl82c105.c34
-rw-r--r--drivers/ide/pci/slc90e66.c78
-rw-r--r--drivers/ide/pci/tc86c001.c47
-rw-r--r--drivers/ide/pci/triflex.c33
-rw-r--r--drivers/ide/pci/trm290.c17
-rw-r--r--drivers/ide/pci/via82cxxx.c65
-rw-r--r--drivers/ide/ppc/pmac.c37
-rw-r--r--drivers/ide/setup-pci.c114
-rw-r--r--drivers/ieee1394/csr1212.c57
-rw-r--r--drivers/ieee1394/csr1212.h6
-rw-r--r--drivers/ieee1394/eth1394.c16
-rw-r--r--drivers/ieee1394/ieee1394_core.c2
-rw-r--r--drivers/ieee1394/nodemgr.c22
-rw-r--r--drivers/ieee1394/pcilynx.c29
-rw-r--r--drivers/ieee1394/sbp2.c15
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_eq.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c36
-rw-r--r--drivers/infiniband/hw/ipath/ipath_dma.c10
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c29
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c3
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c75
-rw-r--r--drivers/input/Kconfig22
-rw-r--r--drivers/input/Makefile1
-rw-r--r--drivers/input/evdev.c708
-rw-r--r--drivers/input/gameport/gameport.c3
-rw-r--r--drivers/input/input-polldev.c7
-rw-r--r--drivers/input/input.c660
-rw-r--r--drivers/input/joydev.c743
-rw-r--r--drivers/input/joystick/xpad.c55
-rw-r--r--drivers/input/keyboard/Kconfig40
-rw-r--r--drivers/input/keyboard/Makefile5
-rw-r--r--drivers/input/keyboard/atakbd.c7
-rw-r--r--drivers/input/keyboard/bf54x-keys.c382
-rw-r--r--drivers/input/keyboard/gpio_keys.c81
-rw-r--r--drivers/input/keyboard/jornada680_kbd.c277
-rw-r--r--drivers/input/keyboard/jornada720_kbd.c185
-rw-r--r--drivers/input/keyboard/maple_keyb.c252
-rw-r--r--drivers/input/keyboard/omap-keypad.c22
-rw-r--r--drivers/input/keyboard/pxa27x_keyboard.c25
-rw-r--r--drivers/input/misc/Kconfig2
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/input/mouse/appletouch.c15
-rw-r--r--drivers/input/mouse/lifebook.c10
-rw-r--r--drivers/input/mouse/psmouse-base.c5
-rw-r--r--drivers/input/mousedev.c740
-rw-r--r--drivers/input/serio/i8042.c4
-rw-r--r--drivers/input/serio/serio.c3
-rw-r--r--drivers/input/touchscreen/Kconfig21
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/jornada720_ts.c182
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c6
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c93
-rw-r--r--drivers/input/tsdev.c533
-rw-r--r--drivers/isdn/capi/capidrv.c5
-rw-r--r--drivers/isdn/capi/kcapi.c2
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c9
-rw-r--r--drivers/isdn/gigaset/common.c3
-rw-r--r--drivers/isdn/gigaset/i4l.c12
-rw-r--r--drivers/isdn/gigaset/proc.c8
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c7
-rw-r--r--drivers/isdn/hardware/avm/b1.c28
-rw-r--r--drivers/isdn/hardware/avm/c4.c14
-rw-r--r--drivers/isdn/i4l/isdn_common.c26
-rw-r--r--drivers/isdn/i4l/isdn_net.c146
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c9
-rw-r--r--drivers/leds/Kconfig8
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-cm-x270.c122
-rw-r--r--drivers/lguest/core.c6
-rw-r--r--drivers/lguest/lguest.c156
-rw-r--r--drivers/lguest/lguest_bus.c2
-rw-r--r--drivers/macintosh/Kconfig1
-rw-r--r--drivers/macintosh/adbhid.c58
-rw-r--r--drivers/md/dm-crypt.c31
-rw-r--r--drivers/md/dm-table.c28
-rw-r--r--drivers/md/dm.c16
-rw-r--r--drivers/md/dm.h1
-rw-r--r--drivers/md/linear.c20
-rw-r--r--drivers/md/md.c52
-rw-r--r--drivers/md/multipath.c30
-rw-r--r--drivers/md/raid0.c31
-rw-r--r--drivers/md/raid1.c34
-rw-r--r--drivers/md/raid10.c31
-rw-r--r--drivers/md/raid5.c31
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c3
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c2
-rw-r--r--drivers/media/video/v4l1-compat.c2
-rw-r--r--drivers/message/fusion/mptscsih.c16
-rw-r--r--drivers/message/i2o/exec-osm.c94
-rw-r--r--drivers/message/i2o/i2o_block.c24
-rw-r--r--drivers/misc/Kconfig12
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/atmel-ssc.c174
-rw-r--r--drivers/misc/thinkpad_acpi.c16
-rw-r--r--drivers/mmc/card/queue.c6
-rw-r--r--drivers/mmc/core/mmc.c3
-rw-r--r--drivers/mmc/host/at91_mci.c4
-rw-r--r--drivers/mmc/host/mmc_spi.c5
-rw-r--r--drivers/mmc/host/pxamci.c43
-rw-r--r--drivers/mmc/host/pxamci.h14
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c4
-rw-r--r--drivers/mtd/nand/s3c2410.c2
-rw-r--r--drivers/mtd/ubi/eba.c3
-rw-r--r--drivers/net/3c59x.c10
-rw-r--r--drivers/net/Kconfig60
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/au1000_eth.c28
-rw-r--r--drivers/net/ax88796.c2
-rw-r--r--drivers/net/bnx2.c34
-rw-r--r--drivers/net/bnx2_fw2.h7833
-rw-r--r--drivers/net/bonding/bond_main.c208
-rw-r--r--drivers/net/bonding/bond_sysfs.c74
-rw-r--r--drivers/net/bonding/bonding.h10
-rw-r--r--drivers/net/cassini.c2
-rw-r--r--drivers/net/cpmac.c1174
-rw-r--r--drivers/net/dm9000.c6
-rw-r--r--drivers/net/e1000e/ethtool.c35
-rw-r--r--drivers/net/e1000e/hw.h2
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c72
-rw-r--r--drivers/net/forcedeth.c195
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c28
-rw-r--r--drivers/net/fs_enet/fs_enet.h1
-rw-r--r--drivers/net/gianfar.c25
-rw-r--r--drivers/net/gianfar.h1
-rw-r--r--drivers/net/hp100.c4
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.c5
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.h5
-rw-r--r--drivers/net/ibm_newemac/mal.c34
-rw-r--r--drivers/net/ibm_newemac/mal.h5
-rw-r--r--drivers/net/irda/donauboe.c2
-rw-r--r--drivers/net/irda/pxaficp_ir.c51
-rw-r--r--drivers/net/jazzsonic.c1
-rw-r--r--drivers/net/loopback.c11
-rw-r--r--drivers/net/mipsnet.c63
-rw-r--r--drivers/net/mipsnet.h83
-rw-r--r--drivers/net/myri10ge/myri10ge.c103
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp.h90
-rw-r--r--drivers/net/natsemi.c20
-rw-r--r--drivers/net/ne-h8300.c4
-rw-r--r--drivers/net/netxen/netxen_nic_main.c3
-rw-r--r--drivers/net/niu.c19
-rw-r--r--drivers/net/pcnet32.c58
-rw-r--r--drivers/net/phy/mdio-bitbang.c2
-rw-r--r--drivers/net/saa9730.c9
-rw-r--r--drivers/net/skge.c485
-rw-r--r--drivers/net/skge.h17
-rw-r--r--drivers/net/sky2.c48
-rw-r--r--drivers/net/smc91x.c55
-rw-r--r--drivers/net/smc91x.h64
-rw-r--r--drivers/net/spider_net.h3
-rw-r--r--drivers/net/tc35815.c1
-rw-r--r--drivers/net/tehuti.c3
-rw-r--r--drivers/net/tg3.c12
-rw-r--r--drivers/net/tokenring/3c359.c2
-rw-r--r--drivers/net/tsi108_eth.c2
-rw-r--r--drivers/net/tulip/Kconfig14
-rw-r--r--drivers/net/tulip/de4x5.c4
-rw-r--r--drivers/net/ucc_geth.c5
-rw-r--r--drivers/net/usb/mcs7830.c16
-rw-r--r--drivers/net/wan/sdla.c8
-rw-r--r--drivers/net/wireless/Kconfig6
-rw-r--r--drivers/net/wireless/libertas/Makefile2
-rw-r--r--drivers/net/wireless/libertas/defs.h2
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c1079
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h45
-rw-r--r--drivers/net/xen-netfront.c37
-rw-r--r--drivers/of/platform.c21
-rw-r--r--drivers/parport/daisy.c29
-rw-r--r--drivers/parport/procfs.c38
-rw-r--r--drivers/pcmcia/Kconfig13
-rw-r--r--drivers/pcmcia/Makefile2
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c5
-rw-r--r--drivers/pcmcia/cistpl.c48
-rw-r--r--drivers/pcmcia/ds.c4
-rw-r--r--drivers/pcmcia/electra_cf.c377
-rw-r--r--drivers/pcmcia/pxa2xx_base.c2
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c175
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c31
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c18
-rw-r--r--drivers/pnp/Makefile4
-rw-r--r--drivers/pnp/card.c71
-rw-r--r--drivers/pnp/core.c28
-rw-r--r--drivers/pnp/driver.c5
-rw-r--r--drivers/pnp/interface.c5
-rw-r--r--drivers/pnp/isapnp/core.c4
-rw-r--r--drivers/pnp/isapnp/proc.c2
-rw-r--r--drivers/pnp/manager.c58
-rw-r--r--drivers/pnp/pnpacpi/core.c16
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c10
-rw-r--r--drivers/pnp/pnpbios/core.c28
-rw-r--r--drivers/pnp/pnpbios/proc.c5
-rw-r--r--drivers/pnp/quirks.c12
-rw-r--r--drivers/pnp/resource.c4
-rw-r--r--drivers/pnp/system.c29
-rw-r--r--drivers/power/ds2760_battery.c2
-rw-r--r--drivers/ps3/ps3av.c387
-rw-r--r--drivers/ps3/ps3av_cmd.c83
-rw-r--r--drivers/ps3/ps3stor_lib.c2
-rw-r--r--drivers/rtc/Kconfig11
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c1
-rw-r--r--drivers/rtc/interface.c122
-rw-r--r--drivers/rtc/rtc-cmos.c64
-rw-r--r--drivers/rtc/rtc-dev.c44
-rw-r--r--drivers/rtc/rtc-ds1374.c449
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-ds1742.c2
-rw-r--r--drivers/rtc/rtc-pcf8583.c3
-rw-r--r--drivers/rtc/rtc-sysfs.c29
-rw-r--r--drivers/s390/char/defkeymap.c2
-rw-r--r--drivers/s390/char/keyboard.c66
-rw-r--r--drivers/s390/char/keyboard.h4
-rw-r--r--drivers/s390/net/qeth_main.c3
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c6
-rw-r--r--drivers/sbus/char/vfc.h2
-rw-r--r--drivers/sbus/char/vfc_dev.c5
-rw-r--r--drivers/scsi/3w-9xxx.c1
-rw-r--r--drivers/scsi/3w-xxxx.c1
-rw-r--r--drivers/scsi/BusLogic.c1
-rw-r--r--drivers/scsi/NCR53c406a.c3
-rw-r--r--drivers/scsi/a100u2w.c1
-rw-r--r--drivers/scsi/aacraid/linit.c1
-rw-r--r--drivers/scsi/aha1542.c32
-rw-r--r--drivers/scsi/aha1740.c1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c1
-rw-r--r--drivers/scsi/aic7xxx_old.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c6
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c1
-rw-r--r--drivers/scsi/dc395x.c1
-rw-r--r--drivers/scsi/dpt_i2o.c1
-rw-r--r--drivers/scsi/eata.c3
-rw-r--r--drivers/scsi/gdth.c4
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/hptiop.c1
-rw-r--r--drivers/scsi/ibmmca.c1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c1
-rw-r--r--drivers/scsi/ide-scsi.c32
-rw-r--r--drivers/scsi/initio.c1
-rw-r--r--drivers/scsi/ipr.c11
-rw-r--r--drivers/scsi/ips.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c8
-rw-r--r--drivers/scsi/mac53c94.c1
-rw-r--r--drivers/scsi/mac_scsi.c9
-rw-r--r--drivers/scsi/megaraid.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mesh.c1
-rw-r--r--drivers/scsi/nsp32.c1
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c1
-rw-r--r--drivers/scsi/qla1280.c70
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c3
-rw-r--r--drivers/scsi/qlogicfas.c1
-rw-r--r--drivers/scsi/qlogicpti.c15
-rw-r--r--drivers/scsi/scsi_debug.c30
-rw-r--r--drivers/scsi/scsi_lib.c238
-rw-r--r--drivers/scsi/scsi_tgt_lib.c4
-rw-r--r--drivers/scsi/sd.c22
-rw-r--r--drivers/scsi/sg.c16
-rw-r--r--drivers/scsi/stex.c1
-rw-r--r--drivers/scsi/sym53c416.c1
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c1
-rw-r--r--drivers/scsi/u14-34f.c3
-rw-r--r--drivers/scsi/ultrastor.c1
-rw-r--r--drivers/scsi/wd7000.c1
-rw-r--r--drivers/serial/8250_pci.c120
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/crisv10.c67
-rw-r--r--drivers/serial/jsm/jsm_tty.c43
-rw-r--r--drivers/serial/m32r_sio.c2
-rw-r--r--drivers/serial/m32r_sio.h6
-rw-r--r--drivers/serial/pxa.c163
-rw-r--r--drivers/serial/serial_core.c68
-rw-r--r--drivers/serial/serial_cs.c1
-rw-r--r--drivers/serial/serial_txx9.c30
-rw-r--r--drivers/spi/Kconfig13
-rw-r--r--drivers/spi/atmel_spi.c14
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c4
-rw-r--r--drivers/spi/omap_uwire.c9
-rw-r--r--drivers/spi/pxa2xx_spi.c14
-rw-r--r--drivers/spi/spi.c36
-rw-r--r--drivers/spi/spi_bfin5xx.c5
-rw-r--r--drivers/spi/spi_bitbang.c2
-rw-r--r--drivers/spi/spi_imx.c17
-rw-r--r--drivers/spi/spi_lm70llp.c2
-rw-r--r--drivers/spi/spi_mpc83xx.c7
-rw-r--r--drivers/spi/spi_s3c24xx.c9
-rw-r--r--drivers/spi/spi_txx9.c2
-rw-r--r--drivers/ssb/Kconfig4
-rw-r--r--drivers/ssb/driver_mipscore.c3
-rw-r--r--drivers/tc/.gitignore1
-rw-r--r--drivers/tc/Makefile15
-rw-r--r--drivers/tc/lk201-map.c_shipped265
-rw-r--r--drivers/tc/lk201-map.map356
-rw-r--r--drivers/tc/lk201-remap.c172
-rw-r--r--drivers/tc/lk201.c439
-rw-r--r--drivers/tc/lk201.h125
-rw-r--r--drivers/telephony/Kconfig2
-rw-r--r--drivers/usb/class/cdc-acm.c34
-rw-r--r--drivers/usb/core/endpoint.c2
-rw-r--r--drivers/usb/core/hub.c9
-rw-r--r--drivers/usb/core/message.c4
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c68
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h1
-rw-r--r--drivers/usb/host/ohci-s3c2410.c2
-rw-r--r--drivers/usb/misc/adutux.c4
-rw-r--r--drivers/usb/misc/iowarrior.c8
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c2
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c3
-rw-r--r--drivers/usb/mon/mon_text.c4
-rw-r--r--drivers/usb/serial/ftdi_sio.c4
-rw-r--r--drivers/usb/serial/io_edgeport.c2
-rw-r--r--drivers/usb/serial/ipw.c18
-rw-r--r--drivers/usb/serial/mos7720.c4
-rw-r--r--drivers/usb/serial/oti6858.c2
-rw-r--r--drivers/usb/serial/sierra.c10
-rw-r--r--drivers/usb/storage/alauda.c16
-rw-r--r--drivers/usb/storage/datafab.c10
-rw-r--r--drivers/usb/storage/jumpshot.c10
-rw-r--r--drivers/usb/storage/libusual.c4
-rw-r--r--drivers/usb/storage/protocol.c20
-rw-r--r--drivers/usb/storage/protocol.h2
-rw-r--r--drivers/usb/storage/sddr09.c16
-rw-r--r--drivers/usb/storage/sddr55.c16
-rw-r--r--drivers/usb/storage/shuttle_usbat.c17
-rw-r--r--drivers/usb/storage/usb.c5
-rw-r--r--drivers/video/Kconfig60
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/arcfb.c2
-rw-r--r--drivers/video/atafb.c2
-rw-r--r--drivers/video/aty/ati_ids.h1
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb.h1
-rw-r--r--drivers/video/aty/atyfb_base.c6
-rw-r--r--drivers/video/aty/mach64_cursor.c1
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/aty/radeonfb.h4
-rw-r--r--drivers/video/au1100fb.c2
-rw-r--r--drivers/video/backlight/cr_bllcd.c1
-rw-r--r--drivers/video/backlight/progear_bl.c1
-rw-r--r--drivers/video/bf54x-lq043fb.c786
-rw-r--r--drivers/video/cfbcopyarea.c103
-rw-r--r--drivers/video/cfbfillrect.c20
-rw-r--r--drivers/video/cfbimgblt.c17
-rw-r--r--drivers/video/cirrusfb.c2053
-rw-r--r--drivers/video/clps711xfb.c2
-rw-r--r--drivers/video/console/dummycon.c4
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/console/font_10x18.c14
-rw-r--r--drivers/video/console/font_6x11.c13
-rw-r--r--drivers/video/console/font_7x14.c12
-rw-r--r--drivers/video/console/font_8x16.c14
-rw-r--r--drivers/video/console/font_8x8.c12
-rw-r--r--drivers/video/console/font_acorn_8x8.c14
-rw-r--r--drivers/video/console/font_mini_4x6.c12
-rw-r--r--drivers/video/console/font_pearl_8x8.c12
-rw-r--r--drivers/video/console/font_sun12x22.c14
-rw-r--r--drivers/video/console/font_sun8x16.c14
-rw-r--r--drivers/video/console/newport_con.c20
-rw-r--r--drivers/video/console/softcursor.c1
-rw-r--r--drivers/video/console/vgacon.c58
-rw-r--r--drivers/video/cyber2000fb.c1
-rw-r--r--drivers/video/epson1355fb.c2
-rw-r--r--drivers/video/fb_defio.c1
-rw-r--r--drivers/video/fb_draw.h94
-rw-r--r--drivers/video/fb_sys_fops.c2
-rw-r--r--drivers/video/fbcmap.c3
-rw-r--r--drivers/video/fbmem.c5
-rw-r--r--drivers/video/fbmon.c4
-rw-r--r--drivers/video/geode/lxfb_core.c7
-rw-r--r--drivers/video/gxt4500.c2
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/imxfb.c4
-rw-r--r--drivers/video/intelfb/intelfb.h17
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c60
-rw-r--r--drivers/video/intelfb/intelfbdrv.c183
-rw-r--r--drivers/video/intelfb/intelfbhw.c318
-rw-r--r--drivers/video/intelfb/intelfbhw.h52
-rw-r--r--drivers/video/kyro/fbdev.c2
-rw-r--r--drivers/video/logo/logo.c17
-rw-r--r--drivers/video/matrox/matroxfb_base.c2
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c2
-rw-r--r--drivers/video/matrox/matroxfb_g450.c1
-rw-r--r--drivers/video/matrox/matroxfb_maven.c1
-rw-r--r--drivers/video/mbx/mbxfb.c344
-rw-r--r--drivers/video/mbx/reg_bits.h87
-rw-r--r--drivers/video/mbx/regs.h2
-rw-r--r--drivers/video/modedb.c60
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_i2c.c10
-rw-r--r--drivers/video/nvidia/nv_type.h1
-rw-r--r--drivers/video/nvidia/nvidia.c6
-rw-r--r--drivers/video/omap/blizzard.c2
-rw-r--r--drivers/video/omap/dispc.c6
-rw-r--r--drivers/video/omap/hwa742.c2
-rw-r--r--drivers/video/omap/lcd_h3.c6
-rw-r--r--drivers/video/omap/lcd_inn1610.c6
-rw-r--r--drivers/video/omap/rfbi.c4
-rw-r--r--drivers/video/pm2fb.c883
-rw-r--r--drivers/video/pm3fb.c557
-rw-r--r--drivers/video/pmag-ba-fb.c34
-rw-r--r--drivers/video/pmagb-b-fb.c34
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c1
-rw-r--r--drivers/video/ps3fb.c511
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/pxafb.c101
-rw-r--r--drivers/video/pxafb.h3
-rw-r--r--drivers/video/s3c2410fb.c783
-rw-r--r--drivers/video/s3c2410fb.h13
-rw-r--r--drivers/video/s3fb.c24
-rw-r--r--drivers/video/sa1100fb.c1
-rw-r--r--drivers/video/savage/savagefb_driver.c1
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c2
-rw-r--r--drivers/video/sm501fb.c49
-rw-r--r--drivers/video/sstfb.c2
-rw-r--r--drivers/video/svgalib.c47
-rw-r--r--drivers/video/tdfxfb.c1255
-rw-r--r--drivers/video/tgafb.c20
-rw-r--r--drivers/video/tridentfb.c1075
-rw-r--r--drivers/video/uvesafb.c2066
-rw-r--r--drivers/video/vermilion/vermilion.c1
-rw-r--r--drivers/video/vfb.c79
-rw-r--r--drivers/video/vga16fb.c2
-rw-r--r--drivers/w1/masters/ds1wm.c2
-rw-r--r--drivers/w1/masters/matrox_w1.c1
-rw-r--r--drivers/watchdog/Kconfig (renamed from drivers/char/watchdog/Kconfig)0
-rw-r--r--drivers/watchdog/Makefile (renamed from drivers/char/watchdog/Makefile)0
-rw-r--r--drivers/watchdog/acquirewdt.c (renamed from drivers/char/watchdog/acquirewdt.c)0
-rw-r--r--drivers/watchdog/advantechwdt.c (renamed from drivers/char/watchdog/advantechwdt.c)0
-rw-r--r--drivers/watchdog/alim1535_wdt.c (renamed from drivers/char/watchdog/alim1535_wdt.c)0
-rw-r--r--drivers/watchdog/alim7101_wdt.c (renamed from drivers/char/watchdog/alim7101_wdt.c)0
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c (renamed from drivers/char/watchdog/at32ap700x_wdt.c)0
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c (renamed from drivers/char/watchdog/at91rm9200_wdt.c)0
-rw-r--r--drivers/watchdog/bfin_wdt.c (renamed from drivers/char/watchdog/bfin_wdt.c)0
-rw-r--r--drivers/watchdog/booke_wdt.c (renamed from drivers/char/watchdog/booke_wdt.c)0
-rw-r--r--drivers/watchdog/cpu5wdt.c (renamed from drivers/char/watchdog/cpu5wdt.c)0
-rw-r--r--drivers/watchdog/davinci_wdt.c (renamed from drivers/char/watchdog/davinci_wdt.c)0
-rw-r--r--drivers/watchdog/ep93xx_wdt.c (renamed from drivers/char/watchdog/ep93xx_wdt.c)0
-rw-r--r--drivers/watchdog/eurotechwdt.c (renamed from drivers/char/watchdog/eurotechwdt.c)0
-rw-r--r--drivers/watchdog/i6300esb.c (renamed from drivers/char/watchdog/i6300esb.c)0
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c (renamed from drivers/char/watchdog/iTCO_vendor_support.c)0
-rw-r--r--drivers/watchdog/iTCO_wdt.c (renamed from drivers/char/watchdog/iTCO_wdt.c)0
-rw-r--r--drivers/watchdog/ib700wdt.c (renamed from drivers/char/watchdog/ib700wdt.c)0
-rw-r--r--drivers/watchdog/ibmasr.c (renamed from drivers/char/watchdog/ibmasr.c)0
-rw-r--r--drivers/watchdog/indydog.c (renamed from drivers/char/watchdog/indydog.c)0
-rw-r--r--drivers/watchdog/iop_wdt.c (renamed from drivers/char/watchdog/iop_wdt.c)0
-rw-r--r--drivers/watchdog/ixp2000_wdt.c (renamed from drivers/char/watchdog/ixp2000_wdt.c)0
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c (renamed from drivers/char/watchdog/ixp4xx_wdt.c)0
-rw-r--r--drivers/watchdog/ks8695_wdt.c (renamed from drivers/char/watchdog/ks8695_wdt.c)0
-rw-r--r--drivers/watchdog/machzwd.c (renamed from drivers/char/watchdog/machzwd.c)0
-rw-r--r--drivers/watchdog/mixcomwd.c (renamed from drivers/char/watchdog/mixcomwd.c)0
-rw-r--r--drivers/watchdog/mpc5200_wdt.c (renamed from drivers/char/watchdog/mpc5200_wdt.c)0
-rw-r--r--drivers/watchdog/mpc83xx_wdt.c (renamed from drivers/char/watchdog/mpc83xx_wdt.c)0
-rw-r--r--drivers/watchdog/mpc8xx_wdt.c (renamed from drivers/char/watchdog/mpc8xx_wdt.c)0
-rw-r--r--drivers/watchdog/mpcore_wdt.c (renamed from drivers/char/watchdog/mpcore_wdt.c)0
-rw-r--r--drivers/watchdog/mtx-1_wdt.c (renamed from drivers/char/watchdog/mtx-1_wdt.c)0
-rw-r--r--drivers/watchdog/mv64x60_wdt.c (renamed from drivers/char/watchdog/mv64x60_wdt.c)0
-rw-r--r--drivers/watchdog/omap_wdt.c (renamed from drivers/char/watchdog/omap_wdt.c)0
-rw-r--r--drivers/watchdog/omap_wdt.h (renamed from drivers/char/watchdog/omap_wdt.h)0
-rw-r--r--drivers/watchdog/pc87413_wdt.c (renamed from drivers/char/watchdog/pc87413_wdt.c)0
-rw-r--r--drivers/watchdog/pcwd.c (renamed from drivers/char/watchdog/pcwd.c)0
-rw-r--r--drivers/watchdog/pcwd_pci.c (renamed from drivers/char/watchdog/pcwd_pci.c)0
-rw-r--r--drivers/watchdog/pcwd_usb.c (renamed from drivers/char/watchdog/pcwd_usb.c)0
-rw-r--r--drivers/watchdog/pnx4008_wdt.c (renamed from drivers/char/watchdog/pnx4008_wdt.c)0
-rw-r--r--drivers/watchdog/rm9k_wdt.c (renamed from drivers/char/watchdog/rm9k_wdt.c)0
-rw-r--r--drivers/watchdog/s3c2410_wdt.c (renamed from drivers/char/watchdog/s3c2410_wdt.c)0
-rw-r--r--drivers/watchdog/sa1100_wdt.c (renamed from drivers/char/watchdog/sa1100_wdt.c)0
-rw-r--r--drivers/watchdog/sbc60xxwdt.c (renamed from drivers/char/watchdog/sbc60xxwdt.c)0
-rw-r--r--drivers/watchdog/sbc8360.c (renamed from drivers/char/watchdog/sbc8360.c)0
-rw-r--r--drivers/watchdog/sbc_epx_c3.c (renamed from drivers/char/watchdog/sbc_epx_c3.c)0
-rw-r--r--drivers/watchdog/sc1200wdt.c (renamed from drivers/char/watchdog/sc1200wdt.c)0
-rw-r--r--drivers/watchdog/sc520_wdt.c (renamed from drivers/char/watchdog/sc520_wdt.c)0
-rw-r--r--drivers/watchdog/scx200_wdt.c (renamed from drivers/char/watchdog/scx200_wdt.c)0
-rw-r--r--drivers/watchdog/shwdt.c (renamed from drivers/char/watchdog/shwdt.c)0
-rw-r--r--drivers/watchdog/smsc37b787_wdt.c (renamed from drivers/char/watchdog/smsc37b787_wdt.c)0
-rw-r--r--drivers/watchdog/softdog.c (renamed from drivers/char/watchdog/softdog.c)0
-rw-r--r--drivers/watchdog/w83627hf_wdt.c (renamed from drivers/char/watchdog/w83627hf_wdt.c)0
-rw-r--r--drivers/watchdog/w83697hf_wdt.c (renamed from drivers/char/watchdog/w83697hf_wdt.c)0
-rw-r--r--drivers/watchdog/w83877f_wdt.c (renamed from drivers/char/watchdog/w83877f_wdt.c)0
-rw-r--r--drivers/watchdog/w83977f_wdt.c (renamed from drivers/char/watchdog/w83977f_wdt.c)0
-rw-r--r--drivers/watchdog/wafer5823wdt.c (renamed from drivers/char/watchdog/wafer5823wdt.c)0
-rw-r--r--drivers/watchdog/wd501p.h (renamed from drivers/char/watchdog/wd501p.h)0
-rw-r--r--drivers/watchdog/wdrtas.c (renamed from drivers/char/watchdog/wdrtas.c)0
-rw-r--r--drivers/watchdog/wdt.c (renamed from drivers/char/watchdog/wdt.c)0
-rw-r--r--drivers/watchdog/wdt285.c (renamed from drivers/char/watchdog/wdt285.c)0
-rw-r--r--drivers/watchdog/wdt977.c (renamed from drivers/char/watchdog/wdt977.c)0
-rw-r--r--drivers/watchdog/wdt_pci.c (renamed from drivers/char/watchdog/wdt_pci.c)0
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c5
-rw-r--r--fs/9p/fid.c157
-rw-r--r--fs/9p/v9fs.c189
-rw-r--r--fs/9p/v9fs.h38
-rw-r--r--fs/9p/vfs_file.c8
-rw-r--r--fs/9p/vfs_inode.c50
-rw-r--r--fs/9p/vfs_super.c19
-rw-r--r--fs/Kconfig61
-rw-r--r--fs/Makefile2
-rw-r--r--fs/adfs/inode.c14
-rw-r--r--fs/adfs/super.c2
-rw-r--r--fs/affs/bitmap.c2
-rw-r--r--fs/affs/file.c101
-rw-r--r--fs/affs/super.c2
-rw-r--r--fs/afs/callback.c2
-rw-r--r--fs/afs/cell.c19
-rw-r--r--fs/afs/cmservice.c2
-rw-r--r--fs/afs/flock.c3
-rw-r--r--fs/afs/internal.h1
-rw-r--r--fs/afs/mntpt.c2
-rw-r--r--fs/afs/proc.c2
-rw-r--r--fs/afs/rxrpc.c3
-rw-r--r--fs/afs/server.c2
-rw-r--r--fs/afs/super.c6
-rw-r--r--fs/afs/vlocation.c6
-rw-r--r--fs/afs/write.c8
-rw-r--r--fs/aio.c22
-rw-r--r--fs/anon_inodes.c25
-rw-r--r--fs/attr.c35
-rw-r--r--fs/autofs/waitq.c2
-rw-r--r--fs/autofs4/inode.c4
-rw-r--r--fs/autofs4/waitq.c2
-rw-r--r--fs/befs/linuxvfs.c2
-rw-r--r--fs/bfs/file.c12
-rw-r--r--fs/bfs/inode.c2
-rw-r--r--fs/binfmt_aout.c16
-rw-r--r--fs/binfmt_elf.c120
-rw-r--r--fs/binfmt_elf_fdpic.c15
-rw-r--r--fs/binfmt_flat.c18
-rw-r--r--fs/binfmt_som.c2
-rw-r--r--fs/bio.c23
-rw-r--r--fs/block_dev.c26
-rw-r--r--fs/buffer.c726
-rw-r--r--fs/char_dev.c1
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/inode.c5
-rw-r--r--fs/coda/inode.c2
-rw-r--r--fs/compat_ioctl.c3
-rw-r--r--fs/configfs/configfs_internal.h2
-rw-r--r--fs/configfs/dir.c5
-rw-r--r--fs/configfs/inode.c12
-rw-r--r--fs/configfs/mount.c9
-rw-r--r--fs/cramfs/inode.c20
-rw-r--r--fs/dcache.c46
-rw-r--r--fs/debugfs/file.c41
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/dlm/Kconfig8
-rw-r--r--fs/dquot.c144
-rw-r--r--fs/ecryptfs/Makefile2
-rw-r--r--fs/ecryptfs/crypto.c989
-rw-r--r--fs/ecryptfs/debug.c2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h183
-rw-r--r--fs/ecryptfs/file.c97
-rw-r--r--fs/ecryptfs/inode.c239
-rw-r--r--fs/ecryptfs/keystore.c1078
-rw-r--r--fs/ecryptfs/main.c265
-rw-r--r--fs/ecryptfs/messaging.c5
-rw-r--r--fs/ecryptfs/mmap.c704
-rw-r--r--fs/ecryptfs/read_write.c358
-rw-r--r--fs/ecryptfs/super.c39
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/eventpoll.c2
-rw-r--r--fs/exec.c165
-rw-r--r--fs/ext2/balloc.c1361
-rw-r--r--fs/ext2/dir.c55
-rw-r--r--fs/ext2/ext2.h39
-rw-r--r--fs/ext2/file.c7
-rw-r--r--fs/ext2/ialloc.c31
-rw-r--r--fs/ext2/inode.c566
-rw-r--r--fs/ext2/ioctl.c45
-rw-r--r--fs/ext2/super.c122
-rw-r--r--fs/ext2/xattr.c3
-rw-r--r--fs/ext3/balloc.c58
-rw-r--r--fs/ext3/bitmap.c2
-rw-r--r--fs/ext3/dir.c11
-rw-r--r--fs/ext3/fsync.c2
-rw-r--r--fs/ext3/ialloc.c17
-rw-r--r--fs/ext3/inode.c165
-rw-r--r--fs/ext3/namei.c19
-rw-r--r--fs/ext3/resize.c61
-rw-r--r--fs/ext3/super.c103
-rw-r--r--fs/ext4/balloc.c176
-rw-r--r--fs/ext4/bitmap.c2
-rw-r--r--fs/ext4/dir.c11
-rw-r--r--fs/ext4/extents.c14
-rw-r--r--fs/ext4/fsync.c2
-rw-r--r--fs/ext4/group.h27
-rw-r--r--fs/ext4/ialloc.c168
-rw-r--r--fs/ext4/inode.c192
-rw-r--r--fs/ext4/namei.c20
-rw-r--r--fs/ext4/resize.c63
-rw-r--r--fs/ext4/super.c204
-rw-r--r--fs/ext4/xattr.c7
-rw-r--r--fs/fat/cache.c2
-rw-r--r--fs/fat/inode.c29
-rw-r--r--fs/fcntl.c12
-rw-r--r--fs/file_table.c65
-rw-r--r--fs/fs-writeback.c164
-rw-r--r--fs/fuse/dev.c68
-rw-r--r--fs/fuse/dir.c347
-rw-r--r--fs/fuse/file.c243
-rw-r--r--fs/fuse/fuse_i.h62
-rw-r--r--fs/fuse/inode.c89
-rw-r--r--fs/gfs2/main.c4
-rw-r--r--fs/gfs2/ops_address.c211
-rw-r--r--fs/gfs2/ops_file.c6
-rw-r--r--fs/hfs/extent.c19
-rw-r--r--fs/hfs/inode.c18
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hfsplus/extents.c21
-rw-r--r--fs/hfsplus/inode.c18
-rw-r--r--fs/hfsplus/super.c2
-rw-r--r--fs/hostfs/hostfs.h9
-rw-r--r--fs/hostfs/hostfs_kern.c301
-rw-r--r--fs/hostfs/hostfs_user.c141
-rw-r--r--fs/hpfs/file.c18
-rw-r--r--fs/hpfs/super.c2
-rw-r--r--fs/hugetlbfs/inode.c184
-rw-r--r--fs/inode.c52
-rw-r--r--fs/inotify_user.c4
-rw-r--r--fs/isofs/compress.c25
-rw-r--r--fs/isofs/inode.c2
-rw-r--r--fs/isofs/namei.c3
-rw-r--r--fs/jbd/commit.c6
-rw-r--r--fs/jbd/journal.c112
-rw-r--r--fs/jbd/revoke.c6
-rw-r--r--fs/jbd/transaction.c33
-rw-r--r--fs/jbd2/commit.c16
-rw-r--r--fs/jbd2/journal.c128
-rw-r--r--fs/jbd2/recovery.c2
-rw-r--r--fs/jbd2/revoke.c4
-rw-r--r--fs/jbd2/transaction.c19
-rw-r--r--fs/jffs2/file.c105
-rw-r--r--fs/jffs2/super.c2
-rw-r--r--fs/jfs/inode.c16
-rw-r--r--fs/jfs/jfs_metapage.c2
-rw-r--r--fs/jfs/jfs_txnmgr.c9
-rw-r--r--fs/jfs/super.c2
-rw-r--r--fs/libfs.c49
-rw-r--r--fs/lockd/mon.c3
-rw-r--r--fs/lockd/xdr.c8
-rw-r--r--fs/lockd/xdr4.c8
-rw-r--r--fs/locks.c194
-rw-r--r--fs/minix/bitmap.c2
-rw-r--r--fs/minix/dir.c49
-rw-r--r--fs/minix/inode.c25
-rw-r--r--fs/minix/itree_v1.c9
-rw-r--r--fs/minix/itree_v2.c9
-rw-r--r--fs/minix/minix.h3
-rw-r--r--fs/mpage.c10
-rw-r--r--fs/namei.c159
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/ncpfs/inode.c2
-rw-r--r--fs/nfs/Makefile1
-rw-r--r--fs/nfs/client.c55
-rw-r--r--fs/nfs/delegation.c6
-rw-r--r--fs/nfs/dir.c263
-rw-r--r--fs/nfs/direct.c8
-rw-r--r--fs/nfs/file.c172
-rw-r--r--fs/nfs/inode.c279
-rw-r--r--fs/nfs/internal.h50
-rw-r--r--fs/nfs/nfs2xdr.c20
-rw-r--r--fs/nfs/nfs3acl.c2
-rw-r--r--fs/nfs/nfs3proc.c17
-rw-r--r--fs/nfs/nfs3xdr.c25
-rw-r--r--fs/nfs/nfs4proc.c85
-rw-r--r--fs/nfs/nfs4state.c2
-rw-r--r--fs/nfs/nfs4xdr.c72
-rw-r--r--fs/nfs/nfsroot.c3
-rw-r--r--fs/nfs/proc.c5
-rw-r--r--fs/nfs/read.c9
-rw-r--r--fs/nfs/super.c393
-rw-r--r--fs/nfs/unlink.c3
-rw-r--r--fs/nfs/write.c210
-rw-r--r--fs/nfsd/export.c17
-rw-r--r--fs/nfsd/nfs4state.c2
-rw-r--r--fs/nfsd/nfs4xdr.c16
-rw-r--r--fs/nfsd/vfs.c51
-rw-r--r--fs/nls/Kconfig50
-rw-r--r--fs/nls/nls_ascii.c12
-rw-r--r--fs/nls/nls_base.c20
-rw-r--r--fs/nls/nls_cp1250.c20
-rw-r--r--fs/nls/nls_cp1251.c18
-rw-r--r--fs/nls/nls_cp1255.c22
-rw-r--r--fs/nls/nls_cp437.c24
-rw-r--r--fs/nls/nls_cp737.c20
-rw-r--r--fs/nls/nls_cp775.c20
-rw-r--r--fs/nls/nls_cp850.c18
-rw-r--r--fs/nls/nls_cp852.c18
-rw-r--r--fs/nls/nls_cp855.c18
-rw-r--r--fs/nls/nls_cp857.c16
-rw-r--r--fs/nls/nls_cp860.c22
-rw-r--r--fs/nls/nls_cp861.c24
-rw-r--r--fs/nls/nls_cp862.c26
-rw-r--r--fs/nls/nls_cp863.c24
-rw-r--r--fs/nls/nls_cp864.c22
-rw-r--r--fs/nls/nls_cp865.c24
-rw-r--r--fs/nls/nls_cp866.c20
-rw-r--r--fs/nls/nls_cp869.c18
-rw-r--r--fs/nls/nls_cp874.c16
-rw-r--r--fs/nls/nls_cp932.c300
-rw-r--r--fs/nls/nls_cp936.c470
-rw-r--r--fs/nls/nls_cp949.c552
-rw-r--r--fs/nls/nls_cp950.c384
-rw-r--r--fs/nls/nls_euc-jp.c4
-rw-r--r--fs/nls/nls_iso8859-1.c12
-rw-r--r--fs/nls/nls_iso8859-13.c16
-rw-r--r--fs/nls/nls_iso8859-14.c16
-rw-r--r--fs/nls/nls_iso8859-15.c16
-rw-r--r--fs/nls/nls_iso8859-2.c16
-rw-r--r--fs/nls/nls_iso8859-3.c16
-rw-r--r--fs/nls/nls_iso8859-4.c16
-rw-r--r--fs/nls/nls_iso8859-5.c16
-rw-r--r--fs/nls/nls_iso8859-6.c14
-rw-r--r--fs/nls/nls_iso8859-7.c18
-rw-r--r--fs/nls/nls_iso8859-9.c14
-rw-r--r--fs/nls/nls_koi8-r.c20
-rw-r--r--fs/nls/nls_koi8-u.c20
-rw-r--r--fs/ntfs/file.c2
-rw-r--r--fs/ntfs/super.c7
-rw-r--r--fs/ocfs2/aops.c14
-rw-r--r--fs/ocfs2/aops.h8
-rw-r--r--fs/ocfs2/dir.c10
-rw-r--r--fs/ocfs2/dlm/dlmfs.c14
-rw-r--r--fs/ocfs2/file.c266
-rw-r--r--fs/ocfs2/super.c4
-rw-r--r--fs/open.c9
-rw-r--r--fs/openpromfs/inode.c2
-rw-r--r--fs/proc/base.c112
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/inode.c6
-rw-r--r--fs/proc/mmu.c21
-rw-r--r--fs/proc/proc_misc.c36
-rw-r--r--fs/qnx4/inode.c22
-rw-r--r--fs/ramfs/Makefile2
-rw-r--r--fs/ramfs/file-mmu.c4
-rw-r--r--fs/ramfs/file-nommu.c4
-rw-r--r--fs/ramfs/inode.c12
-rw-r--r--fs/read_write.c2
-rw-r--r--fs/reiserfs/bitmap.c57
-rw-r--r--fs/reiserfs/dir.c10
-rw-r--r--fs/reiserfs/file.c1240
-rw-r--r--fs/reiserfs/inode.c197
-rw-r--r--fs/reiserfs/ioctl.c10
-rw-r--r--fs/reiserfs/journal.c145
-rw-r--r--fs/reiserfs/super.c20
-rw-r--r--fs/reiserfs/xattr.c16
-rw-r--r--fs/romfs/inode.c6
-rw-r--r--fs/select.c133
-rw-r--r--fs/signalfd.c44
-rw-r--r--fs/smbfs/file.c32
-rw-r--r--fs/smbfs/inode.c2
-rw-r--r--fs/splice.c86
-rw-r--r--fs/super.c1
-rw-r--r--fs/sysfs/dir.c7
-rw-r--r--fs/sysfs/inode.c9
-rw-r--r--fs/sysfs/mount.c4
-rw-r--r--fs/sysfs/sysfs.h1
-rw-r--r--fs/sysv/dir.c50
-rw-r--r--fs/sysv/inode.c2
-rw-r--r--fs/sysv/itree.c23
-rw-r--r--fs/sysv/sysv.h3
-rw-r--r--fs/udf/balloc.c2
-rw-r--r--fs/udf/file.c35
-rw-r--r--fs/udf/inode.c13
-rw-r--r--fs/udf/super.c53
-rw-r--r--fs/udf/udftime.c8
-rw-r--r--fs/ufs/balloc.c1
-rw-r--r--fs/ufs/cylinder.c1
-rw-r--r--fs/ufs/dir.c56
-rw-r--r--fs/ufs/file.c3
-rw-r--r--fs/ufs/ialloc.c1
-rw-r--r--fs/ufs/inode.c24
-rw-r--r--fs/ufs/namei.c3
-rw-r--r--fs/ufs/super.c98
-rw-r--r--fs/ufs/symlink.c2
-rw-r--r--fs/ufs/truncate.c1
-rw-r--r--fs/ufs/ufs.h157
-rw-r--r--fs/ufs/util.c1
-rw-r--r--fs/ufs/util.h53
-rw-r--r--fs/utimes.c13
-rw-r--r--fs/xfs/Makefile-linux-2.63
-rw-r--r--fs/xfs/linux-2.6/kmem.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c81
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c26
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c20
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c174
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c54
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.h4
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c242
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c200
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c139
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h23
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c301
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h5
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c327
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h168
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c100
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h345
-rw-r--r--fs/xfs/quota/xfs_qm.c51
-rw-r--r--fs/xfs/quota/xfs_qm.h6
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c239
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c21
-rw-r--r--fs/xfs/support/move.c51
-rw-r--r--fs/xfs/support/move.h70
-rw-r--r--fs/xfs/xfs_acl.c33
-rw-r--r--fs/xfs/xfs_acl.h19
-rw-r--r--fs/xfs/xfs_ag.h4
-rw-r--r--fs/xfs/xfs_attr.c50
-rw-r--r--fs/xfs/xfs_attr.h17
-rw-r--r--fs/xfs/xfs_behavior.c183
-rw-r--r--fs/xfs/xfs_behavior.h185
-rw-r--r--fs/xfs/xfs_bmap.c150
-rw-r--r--fs/xfs/xfs_bmap.h4
-rw-r--r--fs/xfs/xfs_bmap_btree.c255
-rw-r--r--fs/xfs/xfs_bmap_btree.h68
-rw-r--r--fs/xfs/xfs_buf_item.c1
-rw-r--r--fs/xfs/xfs_clnt.h1
-rw-r--r--fs/xfs/xfs_dfrag.c6
-rw-r--r--fs/xfs/xfs_dinode.h65
-rw-r--r--fs/xfs/xfs_dir2.c117
-rw-r--r--fs/xfs/xfs_dir2.h17
-rw-r--r--fs/xfs/xfs_dir2_block.c64
-rw-r--r--fs/xfs/xfs_dir2_block.h5
-rw-r--r--fs/xfs/xfs_dir2_data.c1
-rw-r--r--fs/xfs/xfs_dir2_leaf.c76
-rw-r--r--fs/xfs/xfs_dir2_leaf.h6
-rw-r--r--fs/xfs/xfs_dir2_node.c1
-rw-r--r--fs/xfs/xfs_dir2_sf.c122
-rw-r--r--fs/xfs/xfs_dir2_sf.h5
-rw-r--r--fs/xfs/xfs_dmapi.h17
-rw-r--r--fs/xfs/xfs_dmops.c43
-rw-r--r--fs/xfs/xfs_error.c21
-rw-r--r--fs/xfs/xfs_error.h5
-rw-r--r--fs/xfs/xfs_extfree_item.c1
-rw-r--r--fs/xfs/xfs_fsops.c17
-rw-r--r--fs/xfs/xfs_ialloc.c6
-rw-r--r--fs/xfs/xfs_ialloc.h7
-rw-r--r--fs/xfs/xfs_iget.c605
-rw-r--r--fs/xfs/xfs_inode.c383
-rw-r--r--fs/xfs/xfs_inode.h158
-rw-r--r--fs/xfs/xfs_iocore.c4
-rw-r--r--fs/xfs/xfs_iomap.c8
-rw-r--r--fs/xfs/xfs_iomap.h1
-rw-r--r--fs/xfs/xfs_itable.c78
-rw-r--r--fs/xfs/xfs_log.c100
-rw-r--r--fs/xfs/xfs_log_priv.h21
-rw-r--r--fs/xfs/xfs_log_recover.c32
-rw-r--r--fs/xfs/xfs_mount.c242
-rw-r--r--fs/xfs/xfs_mount.h176
-rw-r--r--fs/xfs/xfs_qmops.c40
-rw-r--r--fs/xfs/xfs_quota.h10
-rw-r--r--fs/xfs/xfs_rename.c38
-rw-r--r--fs/xfs/xfs_rw.c5
-rw-r--r--fs/xfs/xfs_rw.h34
-rw-r--r--fs/xfs/xfs_sb.h68
-rw-r--r--fs/xfs/xfs_trans.c76
-rw-r--r--fs/xfs/xfs_trans_ail.c1
-rw-r--r--fs/xfs/xfs_trans_extfree.c1
-rw-r--r--fs/xfs/xfs_types.h12
-rw-r--r--fs/xfs/xfs_utils.c9
-rw-r--r--fs/xfs/xfs_utils.h6
-rw-r--r--fs/xfs/xfs_vfsops.c351
-rw-r--r--fs/xfs/xfs_vfsops.h28
-rw-r--r--fs/xfs/xfs_vnodeops.c745
-rw-r--r--fs/xfs/xfs_vnodeops.h86
-rw-r--r--include/Kbuild1
-rw-r--r--include/asm-alpha/bitops.h51
-rw-r--r--include/asm-alpha/elf.h1
-rw-r--r--include/asm-alpha/floppy.h2
-rw-r--r--include/asm-alpha/io.h6
-rw-r--r--include/asm-alpha/page.h3
-rw-r--r--include/asm-alpha/ptrace.h2
-rw-r--r--include/asm-alpha/semaphore.h1
-rw-r--r--include/asm-alpha/system.h1
-rw-r--r--include/asm-arm/arch-imx/imxfb.h1
-rw-r--r--include/asm-arm/arch-ixp23xx/platform.h6
-rw-r--r--include/asm-arm/arch-ns9xxx/clock.h6
-rw-r--r--include/asm-arm/arch-ns9xxx/gpio.h47
-rw-r--r--include/asm-arm/arch-ns9xxx/hardware.h47
-rw-r--r--include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h4
-rw-r--r--include/asm-arm/arch-ns9xxx/system.h4
-rw-r--r--include/asm-arm/arch-omap/blizzard.h12
-rw-r--r--include/asm-arm/arch-omap/board-2430sdp.h44
-rw-r--r--include/asm-arm/arch-omap/board-palmte.h34
-rw-r--r--include/asm-arm/arch-omap/board-palmtt.h23
-rw-r--r--include/asm-arm/arch-omap/board-palmz71.h26
-rw-r--r--include/asm-arm/arch-omap/board-sx1.h46
-rw-r--r--include/asm-arm/arch-omap/board.h4
-rw-r--r--include/asm-arm/arch-omap/dma.h1
-rw-r--r--include/asm-arm/arch-omap/eac.h101
-rw-r--r--include/asm-arm/arch-omap/gpmc.h5
-rw-r--r--include/asm-arm/arch-omap/hardware.h20
-rw-r--r--include/asm-arm/arch-omap/io.h10
-rw-r--r--include/asm-arm/arch-omap/menelaus.h20
-rw-r--r--include/asm-arm/arch-omap/mmc.h66
-rw-r--r--include/asm-arm/arch-omap/mux.h23
-rw-r--r--include/asm-arm/arch-omap/omap24xx.h12
-rw-r--r--include/asm-arm/arch-omap/onenand.h21
-rw-r--r--include/asm-arm/arch-pxa/cm-x270.h50
-rw-r--r--include/asm-arm/arch-pxa/dma.h4
-rw-r--r--include/asm-arm/arch-pxa/gpio.h12
-rw-r--r--include/asm-arm/arch-pxa/hardware.h99
-rw-r--r--include/asm-arm/arch-pxa/irqs.h27
-rw-r--r--include/asm-arm/arch-pxa/memory.h10
-rw-r--r--include/asm-arm/arch-pxa/mfp-pxa300.h574
-rw-r--r--include/asm-arm/arch-pxa/mfp-pxa320.h446
-rw-r--r--include/asm-arm/arch-pxa/mfp.h576
-rw-r--r--include/asm-arm/arch-pxa/pm.h2
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h13
-rw-r--r--include/asm-arm/arch-pxa/pxa3xx-regs.h75
-rw-r--r--include/asm-arm/arch-pxa/pxafb.h7
-rw-r--r--include/asm-arm/arch-pxa/timex.h2
-rw-r--r--include/asm-arm/arch-pxa/zylonite.h35
-rw-r--r--include/asm-arm/arch-rpc/uncompress.h72
-rw-r--r--include/asm-arm/arch-s3c2410/fb.h42
-rw-r--r--include/asm-arm/arch-s3c2410/irqs.h7
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpio.h10
-rw-r--r--include/asm-arm/arch-s3c2410/regs-power.h5
-rw-r--r--include/asm-arm/arch-s3c2410/regs-s3c2412.h2
-rw-r--r--include/asm-arm/arch-sa1100/SA-1101.h4
-rw-r--r--include/asm-arm/bitops.h1
-rw-r--r--include/asm-arm/dma-mapping.h14
-rw-r--r--include/asm-arm/floppy.h2
-rw-r--r--include/asm-arm/hardware/it8152.h99
-rw-r--r--include/asm-arm/ipc.h1
-rw-r--r--include/asm-arm/kexec.h2
-rw-r--r--include/asm-arm/pci.h7
-rw-r--r--include/asm-arm/semaphore.h1
-rw-r--r--include/asm-arm/types.h6
-rw-r--r--include/asm-arm/unistd.h1
-rw-r--r--include/asm-arm26/irq_regs.h1
-rw-r--r--include/asm-avr32/bitops.h1
-rw-r--r--include/asm-avr32/io.h7
-rw-r--r--include/asm-avr32/kdebug.h16
-rw-r--r--include/asm-avr32/kprobes.h2
-rw-r--r--include/asm-avr32/semaphore.h1
-rw-r--r--include/asm-avr32/types.h6
-rw-r--r--include/asm-blackfin/bitops.h1
-rw-r--r--include/asm-blackfin/io.h4
-rw-r--r--include/asm-blackfin/ipc.h1
-rw-r--r--include/asm-blackfin/mach-bf548/bf54x-lq043.h30
-rw-r--r--include/asm-blackfin/mach-bf548/bf54x_keys.h17
-rw-r--r--include/asm-blackfin/processor.h4
-rw-r--r--include/asm-blackfin/semaphore.h1
-rw-r--r--include/asm-blackfin/types.h6
-rw-r--r--include/asm-cris/bitops.h1
-rw-r--r--include/asm-cris/ipc.h1
-rw-r--r--include/asm-cris/irq_regs.h1
-rw-r--r--include/asm-cris/semaphore.h1
-rw-r--r--include/asm-cris/types.h6
-rw-r--r--include/asm-frv/bitops.h1
-rw-r--r--include/asm-frv/ipc.h1
-rw-r--r--include/asm-frv/semaphore.h1
-rw-r--r--include/asm-frv/thread_info.h5
-rw-r--r--include/asm-frv/tlbflush.h3
-rw-r--r--include/asm-frv/types.h6
-rw-r--r--include/asm-generic/Kbuild1
-rw-r--r--include/asm-generic/Kbuild.asm1
-rw-r--r--include/asm-generic/bitops.h1
-rw-r--r--include/asm-generic/bitops/lock.h45
-rw-r--r--include/asm-generic/ipc.h31
-rw-r--r--include/asm-generic/memory_model.h6
-rw-r--r--include/asm-generic/pgtable.h4
-rw-r--r--include/asm-h8300/bitops.h1
-rw-r--r--include/asm-h8300/io.h6
-rw-r--r--include/asm-h8300/ipc.h1
-rw-r--r--include/asm-h8300/semaphore.h1
-rw-r--r--include/asm-h8300/types.h6
-rw-r--r--include/asm-ia64/bitops.h41
-rw-r--r--include/asm-ia64/dma-mapping.h1
-rw-r--r--include/asm-ia64/elf.h1
-rw-r--r--include/asm-ia64/io.h4
-rw-r--r--include/asm-ia64/kdebug.h15
-rw-r--r--include/asm-ia64/kprobes.h2
-rw-r--r--include/asm-ia64/numa.h1
-rw-r--r--include/asm-ia64/pgtable.h50
-rw-r--r--include/asm-ia64/scatterlist.h2
-rw-r--r--include/asm-ia64/semaphore.h1
-rw-r--r--include/asm-ia64/smp.h2
-rw-r--r--include/asm-ia64/system.h2
-rw-r--r--include/asm-ia64/topology.h2
-rw-r--r--include/asm-m32r/bitops.h1
-rw-r--r--include/asm-m32r/ipc.h1
-rw-r--r--include/asm-m32r/ptrace.h5
-rw-r--r--include/asm-m32r/semaphore.h1
-rw-r--r--include/asm-m32r/thread_info.h5
-rw-r--r--include/asm-m32r/types.h6
-rw-r--r--include/asm-m68k/bitops.h1
-rw-r--r--include/asm-m68k/floppy.h3
-rw-r--r--include/asm-m68k/io.h6
-rw-r--r--include/asm-m68k/ipc.h1
-rw-r--r--include/asm-m68k/semaphore.h1
-rw-r--r--include/asm-m68k/types.h6
-rw-r--r--include/asm-m68knommu/bitops.h1
-rw-r--r--include/asm-m68knommu/io.h6
-rw-r--r--include/asm-m68knommu/ipc.h1
-rw-r--r--include/asm-m68knommu/semaphore.h1
-rw-r--r--include/asm-m68knommu/system.h3
-rw-r--r--include/asm-mips/bitops.h102
-rw-r--r--include/asm-mips/floppy.h2
-rw-r--r--include/asm-mips/io.h2
-rw-r--r--include/asm-mips/ip32/ip32_ints.h158
-rw-r--r--include/asm-mips/ipc.h1
-rw-r--r--include/asm-mips/lasat/lasatint.h9
-rw-r--r--include/asm-mips/mach-au1x00/au1000.h647
-rw-r--r--include/asm-mips/mach-au1x00/prom.h13
-rw-r--r--include/asm-mips/mach-db1x00/db1200.h49
-rw-r--r--include/asm-mips/mach-ip27/kernel-entry-init.h9
-rw-r--r--include/asm-mips/mach-pb1x00/pb1200.h52
-rw-r--r--include/asm-mips/pmc-sierra/msp71xx/war.h28
-rw-r--r--include/asm-mips/ptrace.h4
-rw-r--r--include/asm-mips/semaphore.h1
-rw-r--r--include/asm-mips/time.h7
-rw-r--r--include/asm-mips/types.h6
-rw-r--r--include/asm-mips/xxs1500.h35
-rw-r--r--include/asm-parisc/bitops.h1
-rw-r--r--include/asm-parisc/floppy.h4
-rw-r--r--include/asm-parisc/io.h5
-rw-r--r--include/asm-parisc/semaphore.h1
-rw-r--r--include/asm-parisc/types.h6
-rw-r--r--include/asm-powerpc/Kbuild2
-rw-r--r--include/asm-powerpc/bitops.h45
-rw-r--r--include/asm-powerpc/cputable.h3
-rw-r--r--include/asm-powerpc/dcr-mmio.h6
-rw-r--r--include/asm-powerpc/dcr-native.h6
-rw-r--r--include/asm-powerpc/dma-mapping.h17
-rw-r--r--include/asm-powerpc/elf.h47
-rw-r--r--include/asm-powerpc/floppy.h2
-rw-r--r--include/asm-powerpc/ibmebus.h38
-rw-r--r--include/asm-powerpc/io.h17
-rw-r--r--include/asm-powerpc/ipc.h1
-rw-r--r--include/asm-powerpc/kdebug.h19
-rw-r--r--include/asm-powerpc/kprobes.h2
-rw-r--r--include/asm-powerpc/mpc52xx.h6
-rw-r--r--include/asm-powerpc/of_device.h4
-rw-r--r--include/asm-powerpc/paca.h3
-rw-r--r--include/asm-powerpc/pgtable-ppc64.h8
-rw-r--r--include/asm-powerpc/ps3av.h33
-rw-r--r--include/asm-powerpc/scatterlist.h2
-rw-r--r--include/asm-powerpc/semaphore.h1
-rw-r--r--include/asm-powerpc/smp.h4
-rw-r--r--include/asm-powerpc/system.h1
-rw-r--r--include/asm-powerpc/topology.h2
-rw-r--r--include/asm-powerpc/types.h6
-rw-r--r--include/asm-ppc/floppy.h2
-rw-r--r--include/asm-ppc/io.h17
-rw-r--r--include/asm-ppc/irq_regs.h1
-rw-r--r--include/asm-ppc/mpc52xx_psc.h10
-rw-r--r--include/asm-ppc/time.h2
-rw-r--r--include/asm-s390/bitops.h1
-rw-r--r--include/asm-s390/ipc.h1
-rw-r--r--include/asm-s390/kdebug.h15
-rw-r--r--include/asm-s390/kprobes.h2
-rw-r--r--include/asm-s390/semaphore.h1
-rw-r--r--include/asm-s390/types.h6
-rw-r--r--include/asm-sh/bitops.h1
-rw-r--r--include/asm-sh/elf.h1
-rw-r--r--include/asm-sh/floppy.h6
-rw-r--r--include/asm-sh/io.h25
-rw-r--r--include/asm-sh/ipc.h1
-rw-r--r--include/asm-sh/kdebug.h2
-rw-r--r--include/asm-sh/semaphore.h1
-rw-r--r--include/asm-sh/system.h1
-rw-r--r--include/asm-sh/types.h6
-rw-r--r--include/asm-sh64/bitops.h1
-rw-r--r--include/asm-sh64/dma-mapping.h6
-rw-r--r--include/asm-sh64/io.h48
-rw-r--r--include/asm-sh64/ipc.h1
-rw-r--r--include/asm-sh64/semaphore.h1
-rw-r--r--include/asm-sh64/types.h6
-rw-r--r--include/asm-sparc/bitops.h1
-rw-r--r--include/asm-sparc/floppy.h2
-rw-r--r--include/asm-sparc/io.h7
-rw-r--r--include/asm-sparc/ioctls.h4
-rw-r--r--include/asm-sparc/ipc.h1
-rw-r--r--include/asm-sparc/of_platform.h5
-rw-r--r--include/asm-sparc/scatterlist.h2
-rw-r--r--include/asm-sparc/semaphore.h1
-rw-r--r--include/asm-sparc/termbits.h15
-rw-r--r--include/asm-sparc/termios.h48
-rw-r--r--include/asm-sparc64/Kbuild1
-rw-r--r--include/asm-sparc64/backoff.h28
-rw-r--r--include/asm-sparc64/bitops.h1
-rw-r--r--include/asm-sparc64/floppy.h4
-rw-r--r--include/asm-sparc64/io.h6
-rw-r--r--include/asm-sparc64/ioctls.h4
-rw-r--r--include/asm-sparc64/ipc.h1
-rw-r--r--include/asm-sparc64/kdebug.h18
-rw-r--r--include/asm-sparc64/kprobes.h3
-rw-r--r--include/asm-sparc64/of_platform.h5
-rw-r--r--include/asm-sparc64/pgtable.h3
-rw-r--r--include/asm-sparc64/scatterlist.h2
-rw-r--r--include/asm-sparc64/semaphore.h1
-rw-r--r--include/asm-sparc64/shmparam.h2
-rw-r--r--include/asm-sparc64/smp.h3
-rw-r--r--include/asm-sparc64/termbits.h17
-rw-r--r--include/asm-sparc64/termios.h42
-rw-r--r--include/asm-sparc64/topology.h2
-rw-r--r--include/asm-um/a.out.h12
-rw-r--r--include/asm-um/alternative-asm.h (renamed from include/asm-um/alternative-asm.i)2
-rw-r--r--include/asm-um/elf-i386.h12
-rw-r--r--include/asm-um/elf-x86_64.h56
-rw-r--r--include/asm-um/frame.h (renamed from include/asm-um/frame.i)2
-rw-r--r--include/asm-um/ipc.h1
-rw-r--r--include/asm-um/ldt.h4
-rw-r--r--include/asm-um/mmu_context.h43
-rw-r--r--include/asm-um/page.h1
-rw-r--r--include/asm-um/pgalloc.h2
-rw-r--r--include/asm-um/pgtable-3level.h2
-rw-r--r--include/asm-um/processor-generic.h48
-rw-r--r--include/asm-um/processor-x86_64.h2
-rw-r--r--include/asm-um/ptrace-generic.h17
-rw-r--r--include/asm-um/ptrace-i386.h42
-rw-r--r--include/asm-um/ptrace-x86_64.h13
-rw-r--r--include/asm-um/smp.h2
-rw-r--r--include/asm-um/tlbflush.h19
-rw-r--r--include/asm-um/uaccess.h2
-rw-r--r--include/asm-v850/bitops.h1
-rw-r--r--include/asm-v850/ipc.h1
-rw-r--r--include/asm-v850/irq_regs.h1
-rw-r--r--include/asm-v850/semaphore.h1
-rw-r--r--include/asm-v850/types.h6
-rw-r--r--include/asm-x86/Kbuild37
-rw-r--r--include/asm-x86/agp.h43
-rw-r--r--include/asm-x86/agp_32.h36
-rw-r--r--include/asm-x86/agp_64.h34
-rw-r--r--include/asm-x86/alternative-asm.h22
-rw-r--r--include/asm-x86/alternative-asm.i5
-rw-r--r--include/asm-x86/alternative-asm_32.i12
-rw-r--r--include/asm-x86/alternative-asm_64.i12
-rw-r--r--include/asm-x86/atomic_64.h2
-rw-r--r--include/asm-x86/auxvec.h23
-rw-r--r--include/asm-x86/auxvec_32.h11
-rw-r--r--include/asm-x86/auxvec_64.h6
-rw-r--r--include/asm-x86/bitops_32.h1
-rw-r--r--include/asm-x86/bitops_64.h3
-rw-r--r--include/asm-x86/bootparam.h3
-rw-r--r--include/asm-x86/bootsetup.h40
-rw-r--r--include/asm-x86/bug.h41
-rw-r--r--include/asm-x86/bug_32.h37
-rw-r--r--include/asm-x86/bug_64.h34
-rw-r--r--include/asm-x86/bugs.h11
-rw-r--r--include/asm-x86/bugs_32.h12
-rw-r--r--include/asm-x86/bugs_64.h6
-rw-r--r--include/asm-x86/cache.h23
-rw-r--r--include/asm-x86/cache_32.h14
-rw-r--r--include/asm-x86/cache_64.h26
-rw-r--r--include/asm-x86/cacheflush.h43
-rw-r--r--include/asm-x86/cacheflush_32.h39
-rw-r--r--include/asm-x86/cacheflush_64.h35
-rw-r--r--include/asm-x86/cpu.h3
-rw-r--r--include/asm-x86/cpufeature_32.h1
-rw-r--r--include/asm-x86/cputime.h6
-rw-r--r--include/asm-x86/cputime_32.h6
-rw-r--r--include/asm-x86/cputime_64.h6
-rw-r--r--include/asm-x86/debugreg.h79
-rw-r--r--include/asm-x86/debugreg_32.h64
-rw-r--r--include/asm-x86/debugreg_64.h65
-rw-r--r--include/asm-x86/delay.h36
-rw-r--r--include/asm-x86/delay_32.h31
-rw-r--r--include/asm-x86/delay_64.h30
-rw-r--r--include/asm-x86/device.h13
-rw-r--r--include/asm-x86/device_32.h15
-rw-r--r--include/asm-x86/device_64.h15
-rw-r--r--include/asm-x86/dma-mapping_32.h13
-rw-r--r--include/asm-x86/dma-mapping_64.h3
-rw-r--r--include/asm-x86/dmi.h36
-rw-r--r--include/asm-x86/dmi_32.h11
-rw-r--r--include/asm-x86/dmi_64.h24
-rw-r--r--include/asm-x86/edac.h21
-rw-r--r--include/asm-x86/edac_32.h18
-rw-r--r--include/asm-x86/edac_64.h18
-rw-r--r--include/asm-x86/elf_32.h2
-rw-r--r--include/asm-x86/errno.h14
-rw-r--r--include/asm-x86/errno_32.h6
-rw-r--r--include/asm-x86/errno_64.h6
-rw-r--r--include/asm-x86/fb.h20
-rw-r--r--include/asm-x86/fb_32.h17
-rw-r--r--include/asm-x86/fb_64.h19
-rw-r--r--include/asm-x86/floppy.h281
-rw-r--r--include/asm-x86/floppy_32.h284
-rw-r--r--include/asm-x86/floppy_64.h283
-rw-r--r--include/asm-x86/frame.h (renamed from include/asm-x86/frame.i)4
-rw-r--r--include/asm-x86/hardirq_32.h6
-rw-r--r--include/asm-x86/hw_irq_64.h35
-rw-r--r--include/asm-x86/intel_arch_perfmon.h36
-rw-r--r--include/asm-x86/intel_arch_perfmon_32.h31
-rw-r--r--include/asm-x86/intel_arch_perfmon_64.h31
-rw-r--r--include/asm-x86/io_32.h28
-rw-r--r--include/asm-x86/io_64.h6
-rw-r--r--include/asm-x86/ioctls.h98
-rw-r--r--include/asm-x86/ioctls_32.h87
-rw-r--r--include/asm-x86/ioctls_64.h86
-rw-r--r--include/asm-x86/ipc.h1
-rw-r--r--include/asm-x86/ipcbuf.h42
-rw-r--r--include/asm-x86/ipcbuf_32.h29
-rw-r--r--include/asm-x86/ipcbuf_64.h29
-rw-r--r--include/asm-x86/irqflags_32.h13
-rw-r--r--include/asm-x86/irqflags_64.h14
-rw-r--r--include/asm-x86/kdebug.h36
-rw-r--r--include/asm-x86/kdebug_32.h33
-rw-r--r--include/asm-x86/kdebug_64.h36
-rw-r--r--include/asm-x86/kmap_types.h30
-rw-r--r--include/asm-x86/kmap_types_32.h30
-rw-r--r--include/asm-x86/kmap_types_64.h19
-rw-r--r--include/asm-x86/kprobes_32.h4
-rw-r--r--include/asm-x86/kprobes_64.h2
-rw-r--r--include/asm-x86/ldt.h51
-rw-r--r--include/asm-x86/ldt_32.h32
-rw-r--r--include/asm-x86/ldt_64.h36
-rw-r--r--include/asm-x86/mach-default/mach_apicdef.h8
-rw-r--r--include/asm-x86/mach-visws/cobalt.h8
-rw-r--r--include/asm-x86/mach-visws/lithium.h8
-rw-r--r--include/asm-x86/mce.h128
-rw-r--r--include/asm-x86/mce_32.h11
-rw-r--r--include/asm-x86/mce_64.h115
-rw-r--r--include/asm-x86/mman.h32
-rw-r--r--include/asm-x86/mman_32.h17
-rw-r--r--include/asm-x86/mman_64.h19
-rw-r--r--include/asm-x86/mmu_32.h4
-rw-r--r--include/asm-x86/mmu_64.h4
-rw-r--r--include/asm-x86/namei.h16
-rw-r--r--include/asm-x86/namei_32.h17
-rw-r--r--include/asm-x86/namei_64.h11
-rw-r--r--include/asm-x86/numa_64.h3
-rw-r--r--include/asm-x86/page_64.h1
-rw-r--r--include/asm-x86/param.h31
-rw-r--r--include/asm-x86/param_32.h22
-rw-r--r--include/asm-x86/param_64.h22
-rw-r--r--include/asm-x86/paravirt.h487
-rw-r--r--include/asm-x86/parport.h15
-rw-r--r--include/asm-x86/parport_32.h18
-rw-r--r--include/asm-x86/parport_64.h18
-rw-r--r--include/asm-x86/pda.h6
-rw-r--r--include/asm-x86/pgtable-3level-defs.h2
-rw-r--r--include/asm-x86/pgtable_32.h2
-rw-r--r--include/asm-x86/pgtable_64.h1
-rw-r--r--include/asm-x86/processor_32.h31
-rw-r--r--include/asm-x86/processor_64.h27
-rw-r--r--include/asm-x86/ptrace-abi.h90
-rw-r--r--include/asm-x86/ptrace-abi_32.h39
-rw-r--r--include/asm-x86/ptrace-abi_64.h51
-rw-r--r--include/asm-x86/resource.h14
-rw-r--r--include/asm-x86/resource_32.h6
-rw-r--r--include/asm-x86/resource_64.h6
-rw-r--r--include/asm-x86/rtc.h6
-rw-r--r--include/asm-x86/rtc_32.h10
-rw-r--r--include/asm-x86/rtc_64.h10
-rw-r--r--include/asm-x86/rwlock.h14
-rw-r--r--include/asm-x86/rwlock_32.h25
-rw-r--r--include/asm-x86/rwlock_64.h26
-rw-r--r--include/asm-x86/scatterlist_32.h2
-rw-r--r--include/asm-x86/scatterlist_64.h2
-rw-r--r--include/asm-x86/sections.h6
-rw-r--r--include/asm-x86/sections_32.h7
-rw-r--r--include/asm-x86/sections_64.h7
-rw-r--r--include/asm-x86/semaphore_32.h1
-rw-r--r--include/asm-x86/semaphore_64.h1
-rw-r--r--include/asm-x86/sembuf.h37
-rw-r--r--include/asm-x86/sembuf_32.h25
-rw-r--r--include/asm-x86/sembuf_64.h25
-rw-r--r--include/asm-x86/serial.h30
-rw-r--r--include/asm-x86/serial_32.h29
-rw-r--r--include/asm-x86/serial_64.h29
-rw-r--r--include/asm-x86/setup_32.h29
-rw-r--r--include/asm-x86/setup_64.h13
-rw-r--r--include/asm-x86/shmparam.h19
-rw-r--r--include/asm-x86/shmparam_32.h6
-rw-r--r--include/asm-x86/shmparam_64.h6
-rw-r--r--include/asm-x86/siginfo.h21
-rw-r--r--include/asm-x86/siginfo_32.h6
-rw-r--r--include/asm-x86/siginfo_64.h8
-rw-r--r--include/asm-x86/smp_32.h13
-rw-r--r--include/asm-x86/smp_64.h12
-rw-r--r--include/asm-x86/sockios.h26
-rw-r--r--include/asm-x86/sockios_32.h13
-rw-r--r--include/asm-x86/sockios_64.h13
-rw-r--r--include/asm-x86/stacktrace.h2
-rw-r--r--include/asm-x86/string_32.h3
-rw-r--r--include/asm-x86/suspend_64.h2
-rw-r--r--include/asm-x86/system_32.h7
-rw-r--r--include/asm-x86/system_64.h16
-rw-r--r--include/asm-x86/termbits.h211
-rw-r--r--include/asm-x86/termbits_32.h198
-rw-r--r--include/asm-x86/termbits_64.h198
-rw-r--r--include/asm-x86/termios.h108
-rw-r--r--include/asm-x86/termios_32.h90
-rw-r--r--include/asm-x86/termios_64.h90
-rw-r--r--include/asm-x86/tlb.h14
-rw-r--r--include/asm-x86/tlb_32.h20
-rw-r--r--include/asm-x86/tlb_64.h13
-rw-r--r--include/asm-x86/topology_32.h4
-rw-r--r--include/asm-x86/topology_64.h4
-rw-r--r--include/asm-x86/types.h77
-rw-r--r--include/asm-x86/types_32.h64
-rw-r--r--include/asm-x86/types_64.h55
-rw-r--r--include/asm-x86/ucontext.h25
-rw-r--r--include/asm-x86/ucontext_32.h12
-rw-r--r--include/asm-x86/ucontext_64.h12
-rw-r--r--include/asm-x86/unaligned.h42
-rw-r--r--include/asm-x86/unaligned_32.h37
-rw-r--r--include/asm-x86/unaligned_64.h37
-rw-r--r--include/asm-x86/unistd_64.h619
-rw-r--r--include/asm-x86/unwind.h18
-rw-r--r--include/asm-x86/unwind_32.h13
-rw-r--r--include/asm-x86/unwind_64.h12
-rw-r--r--include/asm-xtensa/bitops.h1
-rw-r--r--include/asm-xtensa/semaphore.h1
-rw-r--r--include/asm-xtensa/types.h6
-rw-r--r--include/keys/rxrpc-type.h2
-rw-r--r--include/linux/Kbuild5
-rw-r--r--include/linux/aio.h12
-rw-r--r--include/linux/atmel-ssc.h312
-rw-r--r--include/linux/auxvec.h4
-rw-r--r--include/linux/backing-dev.h94
-rw-r--r--include/linux/binfmts.h9
-rw-r--r--include/linux/bio.h19
-rw-r--r--include/linux/bit_spinlock.h26
-rw-r--r--include/linux/bitops.h6
-rw-r--r--include/linux/blkdev.h8
-rw-r--r--include/linux/buffer_head.h26
-rw-r--r--include/linux/capability.h50
-rw-r--r--include/linux/clocksource.h5
-rw-r--r--include/linux/compiler-gcc.h16
-rw-r--r--include/linux/compiler-gcc3.h4
-rw-r--r--include/linux/compiler-gcc4.h4
-rw-r--r--include/linux/compiler-intel.h4
-rw-r--r--include/linux/compiler.h14
-rw-r--r--include/linux/connector.h7
-rw-r--r--include/linux/console.h10
-rw-r--r--include/linux/console_struct.h1
-rw-r--r--include/linux/consolemap.h1
-rw-r--r--include/linux/cpu.h5
-rw-r--r--include/linux/cpuset.h8
-rw-r--r--include/linux/cramfs_fs.h1
-rw-r--r--include/linux/cyclades.h27
-rw-r--r--include/linux/dca.h47
-rw-r--r--include/linux/dma-mapping.h37
-rw-r--r--include/linux/elf.h2
-rw-r--r--include/linux/elfcore-compat.h55
-rw-r--r--include/linux/ext2_fs.h23
-rw-r--r--include/linux/ext2_fs_sb.h51
-rw-r--r--include/linux/ext3_fs.h18
-rw-r--r--include/linux/ext3_fs_sb.h1
-rw-r--r--include/linux/ext4_fs.h103
-rw-r--r--include/linux/ext4_fs_extents.h4
-rw-r--r--include/linux/ext4_fs_i.h5
-rw-r--r--include/linux/ext4_fs_sb.h4
-rw-r--r--include/linux/ext4_jbd2.h6
-rw-r--r--include/linux/fb.h3
-rw-r--r--include/linux/fcntl.h15
-rw-r--r--include/linux/file.h9
-rw-r--r--include/linux/filter.h1
-rw-r--r--include/linux/firewire-cdev.h15
-rw-r--r--include/linux/freezer.h38
-rw-r--r--include/linux/fs.h192
-rw-r--r--include/linux/fuse.h65
-rw-r--r--include/linux/gfp.h62
-rw-r--r--include/linux/gpio_keys.h1
-rw-r--r--include/linux/hrtimer.h2
-rw-r--r--include/linux/hugetlb.h1
-rw-r--r--include/linux/i2c-id.h1
-rw-r--r--include/linux/i2o.h3
-rw-r--r--include/linux/ide.h76
-rw-r--r--include/linux/if_bridge.h2
-rw-r--r--include/linux/if_fddi.h2
-rw-r--r--include/linux/init.h4
-rw-r--r--include/linux/init_task.h2
-rw-r--r--include/linux/input.h116
-rw-r--r--include/linux/interrupt.h31
-rw-r--r--include/linux/ioport.h3
-rw-r--r--include/linux/ipc.h28
-rw-r--r--include/linux/ipmi.h10
-rw-r--r--include/linux/ipmi_smi.h36
-rw-r--r--include/linux/isdn.h4
-rw-r--r--include/linux/jbd.h21
-rw-r--r--include/linux/jbd2.h49
-rw-r--r--include/linux/jiffies.h6
-rw-r--r--include/linux/kbd_diacr.h2
-rw-r--r--include/linux/kd.h10
-rw-r--r--include/linux/kernel.h36
-rw-r--r--include/linux/kernel_stat.h2
-rw-r--r--include/linux/kexec.h33
-rw-r--r--include/linux/key-type.h112
-rw-r--r--include/linux/key.h99
-rw-r--r--include/linux/keyboard.h4
-rw-r--r--include/linux/kprobes.h6
-rw-r--r--include/linux/libata.h26
-rw-r--r--include/linux/list.h12
-rw-r--r--include/linux/lockdep.h9
-rw-r--r--include/linux/log2.h25
-rw-r--r--include/linux/magic.h3
-rw-r--r--include/linux/memory_hotplug.h18
-rw-r--r--include/linux/mempolicy.h7
-rw-r--r--include/linux/mm.h99
-rw-r--r--include/linux/mm_types.h163
-rw-r--r--include/linux/mmc/sdio_ids.h6
-rw-r--r--include/linux/mmzone.h110
-rw-r--r--include/linux/module.h18
-rw-r--r--include/linux/moduleparam.h18
-rw-r--r--include/linux/mutex.h12
-rw-r--r--include/linux/namei.h4
-rw-r--r--include/linux/nbd.h2
-rw-r--r--include/linux/netdevice.h20
-rw-r--r--include/linux/netfilter.h26
-rw-r--r--include/linux/netfilter/nf_conntrack_amanda.h2
-rw-r--r--include/linux/netfilter/nf_conntrack_ftp.h2
-rw-r--r--include/linux/netfilter/nf_conntrack_h323.h18
-rw-r--r--include/linux/netfilter/nf_conntrack_irc.h2
-rw-r--r--include/linux/netfilter/nf_conntrack_pptp.h4
-rw-r--r--include/linux/netfilter/nf_conntrack_sip.h4
-rw-r--r--include/linux/netfilter/nf_conntrack_tftp.h2
-rw-r--r--include/linux/netfilter/x_tables.h2
-rw-r--r--include/linux/netfilter/xt_sctp.h13
-rw-r--r--include/linux/netfilter_arp/arp_tables.h2
-rw-r--r--include/linux/netfilter_bridge/ebtables.h4
-rw-r--r--include/linux/netfilter_ipv4.h4
-rw-r--r--include/linux/netfilter_ipv4/ip_tables.h2
-rw-r--r--include/linux/netfilter_ipv6/ip6_tables.h2
-rw-r--r--include/linux/nfs_fs.h78
-rw-r--r--include/linux/nfs_page.h1
-rw-r--r--include/linux/nfs_xdr.h6
-rw-r--r--include/linux/nfsd/export.h11
-rw-r--r--include/linux/nls.h8
-rw-r--r--include/linux/nodemask.h94
-rw-r--r--include/linux/nsproxy.h1
-rw-r--r--include/linux/of_device.h5
-rw-r--r--include/linux/of_platform.h4
-rw-r--r--include/linux/oom.h26
-rw-r--r--include/linux/page-isolation.h37
-rw-r--r--include/linux/pageblock-flags.h75
-rw-r--r--include/linux/pagemap.h36
-rw-r--r--include/linux/parport.h1
-rw-r--r--include/linux/pci_ids.h5
-rw-r--r--include/linux/percpu_counter.h55
-rw-r--r--include/linux/pm.h98
-rw-r--r--include/linux/pnp.h6
-rw-r--r--include/linux/poison.h3
-rw-r--r--include/linux/profile.h3
-rw-r--r--include/linux/proportions.h119
-rw-r--r--include/linux/quota.h31
-rw-r--r--include/linux/radix-tree.h40
-rw-r--r--include/linux/raid/bitmap.h2
-rw-r--r--include/linux/rcupdate.h28
-rw-r--r--include/linux/reiserfs_fs.h7
-rw-r--r--include/linux/scatterlist.h84
-rw-r--r--include/linux/sched.h164
-rw-r--r--include/linux/screen_info.h9
-rw-r--r--include/linux/security.h1252
-rw-r--r--include/linux/selection.h1
-rw-r--r--include/linux/seq_file.h2
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/shm.h2
-rw-r--r--include/linux/signalfd.h32
-rw-r--r--include/linux/skbuff.h6
-rw-r--r--include/linux/slab.h6
-rw-r--r--include/linux/slub_def.h73
-rw-r--r--include/linux/sm501-regs.h18
-rw-r--r--include/linux/spi/at73c213.h25
-rw-r--r--include/linux/spi/spi.h12
-rw-r--r--include/linux/sunrpc/clnt.h2
-rw-r--r--include/linux/sunrpc/debug.h5
-rw-r--r--include/linux/sunrpc/msg_prot.h13
-rw-r--r--include/linux/sunrpc/rpc_rdma.h116
-rw-r--r--include/linux/sunrpc/xdr.h5
-rw-r--r--include/linux/sunrpc/xprt.h42
-rw-r--r--include/linux/sunrpc/xprtrdma.h85
-rw-r--r--include/linux/sunrpc/xprtsock.h51
-rw-r--r--include/linux/suspend.h169
-rw-r--r--include/linux/swap.h5
-rw-r--r--include/linux/sysctl.h58
-rw-r--r--include/linux/taskstats.h7
-rw-r--r--include/linux/tcp.h2
-rw-r--r--include/linux/time.h2
-rw-r--r--include/linux/tty.h8
-rw-r--r--include/linux/ufs_fs.h179
-rw-r--r--include/linux/ufs_fs_i.h33
-rw-r--r--include/linux/ufs_fs_sb.h37
-rw-r--r--include/linux/usb/gadget.h4
-rw-r--r--include/linux/vt_kern.h1
-rw-r--r--include/linux/writeback.h15
-rw-r--r--include/net/9p/9p.h21
-rw-r--r--include/net/9p/client.h9
-rw-r--r--include/net/9p/conn.h4
-rw-r--r--include/net/9p/transport.h27
-rw-r--r--include/net/inet_frag.h67
-rw-r--r--include/net/ip.h13
-rw-r--r--include/net/ip_vs.h13
-rw-r--r--include/net/ipv6.h32
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_ipv6.h5
-rw-r--r--include/net/netfilter/nf_conntrack_core.h10
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h2
-rw-r--r--include/net/netfilter/nf_nat_core.h4
-rw-r--r--include/net/netfilter/nf_nat_helper.h6
-rw-r--r--include/net/netfilter/nf_nat_protocol.h2
-rw-r--r--include/net/netfilter/nf_nat_rule.h2
-rw-r--r--include/net/protocol.h2
-rw-r--r--include/net/sock.h22
-rw-r--r--include/net/xfrm.h35
-rw-r--r--include/pcmcia/ds.h1
-rw-r--r--include/scsi/Kbuild4
-rw-r--r--include/scsi/scsi.h7
-rw-r--r--include/scsi/scsi_cmnd.h7
-rw-r--r--include/scsi/scsi_host.h13
-rw-r--r--include/sound/ac97_codec.h8
-rw-r--r--include/sound/ad1848.h5
-rw-r--r--include/sound/ainstr_gf1.h2
-rw-r--r--include/sound/ainstr_iw.h2
-rw-r--r--include/sound/ainstr_simple.h2
-rw-r--r--include/sound/ak4114.h2
-rw-r--r--include/sound/ak4117.h2
-rw-r--r--include/sound/ak4531_codec.h2
-rw-r--r--include/sound/ak4xxx-adda.h2
-rw-r--r--include/sound/asequencer.h2
-rw-r--r--include/sound/asound.h3
-rw-r--r--include/sound/asound_fm.h2
-rw-r--r--include/sound/asoundef.h2
-rw-r--r--include/sound/control.h10
-rw-r--r--include/sound/core.h2
-rw-r--r--include/sound/cs4231-regs.h180
-rw-r--r--include/sound/cs4231.h159
-rw-r--r--include/sound/cs46xx.h2
-rw-r--r--include/sound/cs46xx_dsp_scb_types.h2
-rw-r--r--include/sound/cs46xx_dsp_spos.h2
-rw-r--r--include/sound/cs46xx_dsp_task_types.h2
-rw-r--r--include/sound/cs8403.h2
-rw-r--r--include/sound/cs8427.h2
-rw-r--r--include/sound/driver.h2
-rw-r--r--include/sound/emu10k1.h15
-rw-r--r--include/sound/es1688.h2
-rw-r--r--include/sound/gus.h2
-rw-r--r--include/sound/hda_hwdep.h44
-rw-r--r--include/sound/hdspm.h16
-rw-r--r--include/sound/hwdep.h2
-rw-r--r--include/sound/info.h2
-rw-r--r--include/sound/initval.h2
-rw-r--r--include/sound/memalloc.h2
-rw-r--r--include/sound/mixer_oss.h2
-rw-r--r--include/sound/mpu401.h3
-rw-r--r--include/sound/opl3.h2
-rw-r--r--include/sound/pcm-indirect.h2
-rw-r--r--include/sound/pcm.h13
-rw-r--r--include/sound/pcm_oss.h2
-rw-r--r--include/sound/rawmidi.h2
-rw-r--r--include/sound/sb.h2
-rw-r--r--include/sound/seq_instr.h2
-rw-r--r--include/sound/seq_midi_event.h2
-rw-r--r--include/sound/seq_virmidi.h2
-rw-r--r--include/sound/soc.h3
-rw-r--r--include/sound/tea575x-tuner.h2
-rw-r--r--include/sound/timer.h2
-rw-r--r--include/sound/tlv.h2
-rw-r--r--include/sound/version.h4
-rw-r--r--include/sound/ymfpci.h2
-rw-r--r--include/video/Kbuild2
-rw-r--r--include/video/mbxfb.h53
-rw-r--r--include/video/permedia2.h17
-rw-r--r--include/video/pm3fb.h1272
-rw-r--r--include/video/tdfx.h270
-rw-r--r--include/video/uvesafb.h193
-rw-r--r--include/xen/interface/vcpu.h5
-rw-r--r--init/Kconfig3
-rw-r--r--init/Makefile2
-rw-r--r--init/calibrate.c2
-rw-r--r--init/do_mounts_rd.c6
-rw-r--r--ipc/ipc_sysctl.c4
-rw-r--r--ipc/mqueue.c12
-rw-r--r--ipc/shm.c18
-rw-r--r--kernel/Kconfig.preempt3
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/acct.c66
-rw-r--r--kernel/audit.c14
-rw-r--r--kernel/auditfilter.c4
-rw-r--r--kernel/auditsc.c12
-rw-r--r--kernel/capability.c199
-rw-r--r--kernel/compat.c117
-rw-r--r--kernel/cpu.c2
-rw-r--r--kernel/cpuset.c197
-rw-r--r--kernel/delayacct.c6
-rw-r--r--kernel/dma.c8
-rw-r--r--kernel/exec_domain.c2
-rw-r--r--kernel/exit.c116
-rw-r--r--kernel/fork.c42
-rw-r--r--kernel/futex.c7
-rw-r--r--kernel/hrtimer.c29
-rw-r--r--kernel/irq/chip.c3
-rw-r--r--kernel/irq/manage.c31
-rw-r--r--kernel/itimer.c4
-rw-r--r--kernel/kexec.c117
-rw-r--r--kernel/kprobes.c62
-rw-r--r--kernel/ksysfs.c10
-rw-r--r--kernel/lockdep.c26
-rw-r--r--kernel/lockdep_proc.c61
-rw-r--r--kernel/module.c168
-rw-r--r--kernel/mutex.c35
-rw-r--r--kernel/nsproxy.c3
-rw-r--r--kernel/panic.c10
-rw-r--r--kernel/params.c25
-rw-r--r--kernel/posix-timers.c20
-rw-r--r--kernel/power/Kconfig11
-rw-r--r--kernel/power/disk.c156
-rw-r--r--kernel/power/main.c48
-rw-r--r--kernel/power/power.h21
-rw-r--r--kernel/power/process.c141
-rw-r--r--kernel/power/snapshot.c53
-rw-r--r--kernel/power/swsusp.c33
-rw-r--r--kernel/power/user.c4
-rw-r--r--kernel/printk.c127
-rw-r--r--kernel/profile.c6
-rw-r--r--kernel/ptrace.c13
-rw-r--r--kernel/rcupdate.c9
-rw-r--r--kernel/rcutorture.c10
-rw-r--r--kernel/relay.c6
-rw-r--r--kernel/resource.c26
-rw-r--r--kernel/rtmutex-debug.c7
-rw-r--r--kernel/sched.c195
-rw-r--r--kernel/sched_debug.c2
-rw-r--r--kernel/sched_fair.c6
-rw-r--r--kernel/sched_stats.h8
-rw-r--r--kernel/signal.c25
-rw-r--r--kernel/softlockup.c54
-rw-r--r--kernel/sys.c1
-rw-r--r--kernel/sys_ni.c4
-rw-r--r--kernel/sysctl.c328
-rw-r--r--kernel/sysctl_check.c1588
-rw-r--r--kernel/taskstats.c1
-rw-r--r--kernel/time.c21
-rw-r--r--kernel/time/tick-broadcast.c35
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/time/timekeeping.c12
-rw-r--r--kernel/timer.c9
-rw-r--r--kernel/tsacct.c4
-rw-r--r--kernel/user.c35
-rw-r--r--lib/Kconfig.debug18
-rw-r--r--lib/Makefile3
-rw-r--r--lib/argv_split.c4
-rw-r--r--lib/bust_spinlocks.c6
-rw-r--r--lib/crc32.c12
-rw-r--r--lib/idr.c3
-rw-r--r--lib/iomap.c2
-rw-r--r--lib/ioremap.c1
-rw-r--r--lib/libcrc32c.c6
-rw-r--r--lib/percpu_counter.c48
-rw-r--r--lib/proportions.c384
-rw-r--r--lib/radix-tree.c148
-rw-r--r--lib/sort.c2
-rw-r--r--lib/swiotlb.c21
-rw-r--r--mm/Kconfig19
-rw-r--r--mm/Makefile3
-rw-r--r--mm/backing-dev.c47
-rw-r--r--mm/bounce.c6
-rw-r--r--mm/filemap.c782
-rw-r--r--mm/filemap.h103
-rw-r--r--mm/filemap_xip.c17
-rw-r--r--mm/fremap.c26
-rw-r--r--mm/hugetlb.c400
-rw-r--r--mm/internal.h10
-rw-r--r--mm/memory.c161
-rw-r--r--mm/memory_hotplug.c312
-rw-r--r--mm/mempolicy.c60
-rw-r--r--mm/migrate.c4
-rw-r--r--mm/mmap.c3
-rw-r--r--mm/mprotect.c1
-rw-r--r--mm/mremap.c4
-rw-r--r--mm/nommu.c1
-rw-r--r--mm/oom_kill.c116
-rw-r--r--mm/page-writeback.c310
-rw-r--r--mm/page_alloc.c754
-rw-r--r--mm/page_isolation.c138
-rw-r--r--mm/readahead.c94
-rw-r--r--mm/rmap.c5
-rw-r--r--mm/shmem.c82
-rw-r--r--mm/slab.c342
-rw-r--r--mm/slob.c13
-rw-r--r--mm/slub.c520
-rw-r--r--mm/sparse-vmemmap.c148
-rw-r--r--mm/sparse.c105
-rw-r--r--mm/swap.c111
-rw-r--r--mm/swap_state.c5
-rw-r--r--mm/tiny-shmem.c19
-rw-r--r--mm/truncate.c3
-rw-r--r--mm/util.c6
-rw-r--r--mm/vmalloc.c5
-rw-r--r--mm/vmscan.c101
-rw-r--r--mm/vmstat.c305
-rw-r--r--net/9p/Kconfig10
-rw-r--r--net/9p/Makefile5
-rw-r--r--net/9p/client.c13
-rw-r--r--net/9p/conv.c32
-rw-r--r--net/9p/mod.c71
-rw-r--r--net/9p/mux.c5
-rw-r--r--net/9p/sysctl.c81
-rw-r--r--net/9p/trans_fd.c419
-rw-r--r--net/atm/br2684.c121
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/bridge/br_input.c6
-rw-r--r--net/bridge/br_netfilter.c36
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c3
-rw-r--r--net/bridge/netfilter/ebt_dnat.c17
-rw-r--r--net/bridge/netfilter/ebt_mark.c10
-rw-r--r--net/bridge/netfilter/ebt_redirect.c21
-rw-r--r--net/bridge/netfilter/ebt_snat.c23
-rw-r--r--net/bridge/netfilter/ebtable_broute.c4
-rw-r--r--net/bridge/netfilter/ebtable_filter.c4
-rw-r--r--net/bridge/netfilter/ebtable_nat.c8
-rw-r--r--net/bridge/netfilter/ebtables.c12
-rw-r--r--net/core/dev.c89
-rw-r--r--net/core/filter.c58
-rw-r--r--net/core/neighbour.c77
-rw-r--r--net/core/pktgen.c2
-rw-r--r--net/core/skbuff.c195
-rw-r--r--net/core/sock.c14
-rw-r--r--net/dccp/input.c3
-rw-r--r--net/dccp/ipv6.c3
-rw-r--r--net/dccp/sysctl.c3
-rw-r--r--net/decnet/netfilter/dn_rtmsg.c4
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c2
-rw-r--r--net/ipv4/Makefile3
-rw-r--r--net/ipv4/inet_fragment.c261
-rw-r--r--net/ipv4/ip_forward.c2
-rw-r--r--net/ipv4/ip_fragment.c514
-rw-r--r--net/ipv4/ip_input.c10
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c33
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c104
-rw-r--r--net/ipv4/ipvs/ip_vs_ftp.c19
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c51
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c51
-rw-r--r--net/ipv4/ipvs/ip_vs_xmit.c6
-rw-r--r--net/ipv4/netfilter.c77
-rw-r--r--net/ipv4/netfilter/arp_tables.c20
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c28
-rw-r--r--net/ipv4/netfilter/arptable_filter.c4
-rw-r--r--net/ipv4/netfilter/ip_queue.c24
-rw-r--r--net/ipv4/netfilter/ip_tables.c20
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c14
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c27
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c4
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c6
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c8
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c6
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c22
-rw-r--r--net/ipv4/netfilter/ipt_SAME.c4
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c8
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c6
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c4
-rw-r--r--net/ipv4/netfilter/iptable_filter.c12
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c22
-rw-r--r--net/ipv4/netfilter/iptable_raw.c12
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c48
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_amanda.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c50
-rw-r--r--net/ipv4/netfilter/nf_nat_ftp.c18
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c58
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c118
-rw-r--r--net/ipv4/netfilter/nf_nat_irc.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c8
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c8
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_icmp.c10
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_tcp.c16
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_udp.c16
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_unknown.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c14
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c56
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c14
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c62
-rw-r--r--net/ipv4/netfilter/nf_nat_tftp.c2
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv4/sysctl_net_ipv4.c11
-rw-r--r--net/ipv4/tcp_input.c17
-rw-r--r--net/ipv4/xfrm4_input.c40
-rw-r--r--net/ipv4/xfrm4_mode_beet.c1
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c1
-rw-r--r--net/ipv4/xfrm4_output.c6
-rw-r--r--net/ipv4/xfrm4_policy.c27
-rw-r--r--net/ipv4/xfrm4_state.c1
-rw-r--r--net/ipv4/xfrm4_tunnel.c11
-rw-r--r--net/ipv6/addrconf.c10
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/ah6.c11
-rw-r--r--net/ipv6/esp6.c9
-rw-r--r--net/ipv6/exthdrs.c64
-rw-r--r--net/ipv6/icmp.c5
-rw-r--r--net/ipv6/inet6_connection_sock.c2
-rw-r--r--net/ipv6/ip6_flowlabel.c57
-rw-r--r--net/ipv6/ip6_input.c6
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ipcomp6.c9
-rw-r--r--net/ipv6/ndisc.c24
-rw-r--r--net/ipv6/netfilter.c6
-rw-r--r--net/ipv6/netfilter/ip6_queue.c20
-rw-r--r--net/ipv6/netfilter/ip6_tables.c16
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c6
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c5
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c14
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c12
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c32
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c4
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c52
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c368
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/ipv6/reassembly.c432
-rw-r--r--net/ipv6/route.c78
-rw-r--r--net/ipv6/sysctl_net_ipv6.c9
-rw-r--r--net/ipv6/tcp_ipv6.c3
-rw-r--r--net/ipv6/tunnel6.c6
-rw-r--r--net/ipv6/udp.c7
-rw-r--r--net/ipv6/udp_impl.h2
-rw-r--r--net/ipv6/udplite.c4
-rw-r--r--net/ipv6/xfrm6_input.c16
-rw-r--r--net/ipv6/xfrm6_mode_beet.c1
-rw-r--r--net/ipv6/xfrm6_mode_ro.c9
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c1
-rw-r--r--net/ipv6/xfrm6_output.c6
-rw-r--r--net/ipv6/xfrm6_policy.c17
-rw-r--r--net/ipv6/xfrm6_state.c7
-rw-r--r--net/ipv6/xfrm6_tunnel.c4
-rw-r--r--net/irda/ircomm/ircomm_tty_attach.c15
-rw-r--r--net/irda/irsysctl.c34
-rw-r--r--net/mac80211/ieee80211_ioctl.c16
-rw-r--r--net/mac80211/ieee80211_sta.c71
-rw-r--r--net/netfilter/core.c48
-rw-r--r--net/netfilter/nf_conntrack_amanda.c20
-rw-r--r--net/netfilter/nf_conntrack_core.c30
-rw-r--r--net/netfilter/nf_conntrack_ftp.c18
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c236
-rw-r--r--net/netfilter/nf_conntrack_irc.c16
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c10
-rw-r--r--net/netfilter/nf_conntrack_pptp.c28
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c14
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c29
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c4
-rw-r--r--net/netfilter/nf_conntrack_sane.c10
-rw-r--r--net/netfilter/nf_conntrack_sip.c24
-rw-r--r--net/netfilter/nf_conntrack_tftp.c8
-rw-r--r--net/netfilter/nf_internals.h2
-rw-r--r--net/netfilter/nf_queue.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c20
-rw-r--r--net/netfilter/xt_CLASSIFY.c4
-rw-r--r--net/netfilter/xt_CONNMARK.c14
-rw-r--r--net/netfilter/xt_CONNSECMARK.c3
-rw-r--r--net/netfilter/xt_DSCP.c16
-rw-r--r--net/netfilter/xt_MARK.c12
-rw-r--r--net/netfilter/xt_NFLOG.c4
-rw-r--r--net/netfilter/xt_NFQUEUE.c2
-rw-r--r--net/netfilter/xt_NOTRACK.c10
-rw-r--r--net/netfilter/xt_SECMARK.c4
-rw-r--r--net/netfilter/xt_TCPMSS.c58
-rw-r--r--net/netfilter/xt_TRACE.c4
-rw-r--r--net/netfilter/xt_sctp.c18
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/rxrpc/af_rxrpc.c1
-rw-r--r--net/rxrpc/ar-key.c32
-rw-r--r--net/sched/act_ipt.c6
-rw-r--r--net/sched/sch_generic.c7
-rw-r--r--net/sched/sch_ingress.c5
-rw-r--r--net/sctp/ipv6.c4
-rw-r--r--net/sctp/protocol.c1
-rw-r--r--net/socket.c20
-rw-r--r--net/sunrpc/Makefile1
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c6
-rw-r--r--net/sunrpc/clnt.c52
-rw-r--r--net/sunrpc/rpc_pipe.c10
-rw-r--r--net/sunrpc/rpcb_clnt.c151
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/socklib.c3
-rw-r--r--net/sunrpc/sunrpc_syms.c2
-rw-r--r--net/sunrpc/sysctl.c4
-rw-r--r--net/sunrpc/timer.c4
-rw-r--r--net/sunrpc/xprt.c116
-rw-r--r--net/sunrpc/xprtrdma/Makefile3
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c868
-rw-r--r--net/sunrpc/xprtrdma/transport.c800
-rw-r--r--net/sunrpc/xprtrdma/verbs.c1627
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h330
-rw-r--r--net/sunrpc/xprtsock.c567
-rw-r--r--net/xfrm/xfrm_input.c5
-rw-r--r--net/xfrm/xfrm_output.c4
-rw-r--r--net/xfrm/xfrm_policy.c179
-rw-r--r--net/xfrm/xfrm_state.c206
-rw-r--r--scripts/Kbuild.include8
-rw-r--r--scripts/Makefile.build45
-rw-r--r--scripts/Makefile.clean2
-rw-r--r--scripts/Makefile.lib30
-rw-r--r--scripts/basic/Makefile8
-rw-r--r--scripts/basic/docproc.c34
-rwxr-xr-xscripts/checkkconfigsymbols.sh59
-rwxr-xr-xscripts/checkpatch.pl580
-rwxr-xr-xscripts/checkstack.pl3
-rw-r--r--scripts/export_report.pl10
-rw-r--r--scripts/gcc-version.sh8
-rw-r--r--scripts/genksyms/Makefile8
-rw-r--r--scripts/genksyms/keywords.c_shipped180
-rw-r--r--scripts/genksyms/keywords.gperf1
-rw-r--r--scripts/genksyms/lex.c_shipped1802
-rw-r--r--scripts/genksyms/parse.c_shipped2088
-rw-r--r--scripts/genksyms/parse.h_shipped159
-rw-r--r--scripts/genksyms/parse.y5
-rw-r--r--scripts/kconfig/Makefile10
-rwxr-xr-xscripts/kconfig/check.sh14
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped25
-rw-r--r--scripts/kconfig/mconf.c36
-rw-r--r--scripts/kconfig/menu.c35
-rw-r--r--scripts/kconfig/util.c13
-rw-r--r--scripts/kconfig/zconf.gperf2
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped220
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped1406
-rw-r--r--scripts/kconfig/zconf.y11
-rwxr-xr-xscripts/kernel-doc41
-rwxr-xr-xscripts/makelst4
-rw-r--r--scripts/mkmakefile8
-rw-r--r--scripts/mod/file2alias.c40
-rw-r--r--scripts/mod/modpost.c6
-rw-r--r--scripts/mod/modpost.h4
-rwxr-xr-xscripts/ver_linux9
-rw-r--r--security/Kconfig16
-rw-r--r--security/capability.c30
-rw-r--r--security/commoncap.c319
-rw-r--r--security/dummy.c47
-rw-r--r--security/inode.c8
-rw-r--r--security/keys/internal.h35
-rw-r--r--security/keys/key.c34
-rw-r--r--security/keys/process_keys.c16
-rw-r--r--security/keys/request_key.c556
-rw-r--r--security/keys/request_key_auth.c11
-rw-r--r--security/root_plug.c31
-rw-r--r--security/security.c1012
-rw-r--r--security/selinux/avc.c5
-rw-r--r--security/selinux/hooks.c160
-rw-r--r--security/selinux/include/avc.h2
-rw-r--r--security/selinux/include/objsec.h2
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/selinuxfs.c26
-rw-r--r--security/selinux/ss/avtab.c91
-rw-r--r--security/selinux/ss/avtab.h16
-rw-r--r--security/selinux/ss/conditional.c4
-rw-r--r--security/selinux/ss/ebitmap.c282
-rw-r--r--security/selinux/ss/ebitmap.h89
-rw-r--r--security/selinux/ss/mls.c156
-rw-r--r--security/selinux/ss/policydb.c11
-rw-r--r--security/selinux/ss/policydb.h8
-rw-r--r--security/selinux/ss/services.c91
-rw-r--r--security/selinux/xfrm.c3
-rw-r--r--sound/Kconfig4
-rw-r--r--sound/Makefile3
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.c20
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c29
-rw-r--r--sound/aoa/fabrics/snd-aoa-fabric-layout.c10
-rw-r--r--sound/arm/aaci.c4
-rw-r--r--sound/arm/sa11xx-uda1341.c35
-rw-r--r--sound/core/Makefile15
-rw-r--r--sound/core/control.c33
-rw-r--r--sound/core/device.c2
-rw-r--r--sound/core/hwdep.c4
-rw-r--r--sound/core/info.c2
-rw-r--r--sound/core/info_oss.c2
-rw-r--r--sound/core/init.c2
-rw-r--r--sound/core/isadma.c2
-rw-r--r--sound/core/memalloc.c10
-rw-r--r--sound/core/memory.c2
-rw-r--r--sound/core/misc.c2
-rw-r--r--sound/core/oss/Makefile7
-rw-r--r--sound/core/oss/copy.c5
-rw-r--r--sound/core/oss/io.c7
-rw-r--r--sound/core/oss/linear.c91
-rw-r--r--sound/core/oss/mixer_oss.c4
-rw-r--r--sound/core/oss/mulaw.c90
-rw-r--r--sound/core/oss/pcm_oss.c39
-rw-r--r--sound/core/oss/pcm_plugin.c63
-rw-r--r--sound/core/oss/pcm_plugin.h2
-rw-r--r--sound/core/oss/plugin_ops.h370
-rw-r--r--sound/core/oss/rate.c7
-rw-r--r--sound/core/oss/route.c5
-rw-r--r--sound/core/pcm.c4
-rw-r--r--sound/core/pcm_lib.c2
-rw-r--r--sound/core/pcm_memory.c2
-rw-r--r--sound/core/pcm_misc.c65
-rw-r--r--sound/core/pcm_native.c10
-rw-r--r--sound/core/pcm_timer.c2
-rw-r--r--sound/core/rawmidi.c5
-rw-r--r--sound/core/seq/Makefile2
-rw-r--r--sound/core/seq/instr/Makefile2
-rw-r--r--sound/core/seq/instr/ainstr_gf1.c4
-rw-r--r--sound/core/seq/instr/ainstr_iw.c4
-rw-r--r--sound/core/seq/instr/ainstr_simple.c4
-rw-r--r--sound/core/seq/oss/Makefile2
-rw-r--r--sound/core/seq/oss/seq_oss_init.c40
-rw-r--r--sound/core/seq/oss/seq_oss_writeq.c6
-rw-r--r--sound/core/seq/seq.c2
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_instr.c14
-rw-r--r--sound/core/seq/seq_memory.c2
-rw-r--r--sound/core/seq/seq_midi.c4
-rw-r--r--sound/core/seq/seq_midi_event.c101
-rw-r--r--sound/core/seq/seq_ports.c2
-rw-r--r--sound/core/seq/seq_timer.c2
-rw-r--r--sound/core/sound.c12
-rw-r--r--sound/core/sound_oss.c2
-rw-r--r--sound/core/timer.c4
-rw-r--r--sound/drivers/Makefile2
-rw-r--r--sound/drivers/dummy.c14
-rw-r--r--sound/drivers/mpu401/Makefile2
-rw-r--r--sound/drivers/mpu401/mpu401.c10
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c7
-rw-r--r--sound/drivers/mts64.c10
-rw-r--r--sound/drivers/opl3/Makefile8
-rw-r--r--sound/drivers/opl3/opl3_lib.c4
-rw-r--r--sound/drivers/opl4/Makefile2
-rw-r--r--sound/drivers/serial-u16550.c2
-rw-r--r--sound/drivers/vx/Makefile2
-rw-r--r--sound/drivers/vx/vx_mixer.c18
-rw-r--r--sound/i2c/Makefile6
-rw-r--r--sound/i2c/cs8427.c10
-rw-r--r--sound/i2c/i2c.c4
-rw-r--r--sound/i2c/other/Makefile2
-rw-r--r--sound/i2c/other/ak4114.c14
-rw-r--r--sound/i2c/other/ak4117.c14
-rw-r--r--sound/i2c/other/ak4xxx-adda.c14
-rw-r--r--sound/i2c/other/pt2258.c10
-rw-r--r--sound/i2c/other/tea575x-tuner.c4
-rw-r--r--sound/i2c/tea6330t.c14
-rw-r--r--sound/isa/Kconfig22
-rw-r--r--sound/isa/Makefile4
-rw-r--r--sound/isa/ad1816a/Makefile2
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c2
-rw-r--r--sound/isa/ad1848/Makefile9
-rw-r--r--sound/isa/ad1848/ad1848.c6
-rw-r--r--sound/isa/ad1848/ad1848_lib.c140
-rw-r--r--sound/isa/cs423x/Makefile19
-rw-r--r--sound/isa/cs423x/cs4231.c4
-rw-r--r--sound/isa/cs423x/cs4231_lib.c115
-rw-r--r--sound/isa/cs423x/cs4236.c4
-rw-r--r--sound/isa/cs423x/cs4236_lib.c4
-rw-r--r--sound/isa/es1688/Makefile2
-rw-r--r--sound/isa/es1688/es1688.c4
-rw-r--r--sound/isa/es1688/es1688_lib.c4
-rw-r--r--sound/isa/es18xx.c19
-rw-r--r--sound/isa/gus/Makefile2
-rw-r--r--sound/isa/gus/gus_dma.c2
-rw-r--r--sound/isa/gus/gus_dram.c2
-rw-r--r--sound/isa/gus/gus_instr.c2
-rw-r--r--sound/isa/gus/gus_io.c2
-rw-r--r--sound/isa/gus/gus_irq.c20
-rw-r--r--sound/isa/gus/gus_main.c22
-rw-r--r--sound/isa/gus/gus_mem.c2
-rw-r--r--sound/isa/gus/gus_mem_proc.c2
-rw-r--r--sound/isa/gus/gus_mixer.c11
-rw-r--r--sound/isa/gus/gus_pcm.c2
-rw-r--r--sound/isa/gus/gus_reset.c2
-rw-r--r--sound/isa/gus/gus_sample.c2
-rw-r--r--sound/isa/gus/gus_simple.c2
-rw-r--r--sound/isa/gus/gus_synth.c4
-rw-r--r--sound/isa/gus/gus_tables.h2
-rw-r--r--sound/isa/gus/gus_timer.c2
-rw-r--r--sound/isa/gus/gus_uart.c2
-rw-r--r--sound/isa/gus/gus_volume.c2
-rw-r--r--sound/isa/gus/gusclassic.c4
-rw-r--r--sound/isa/gus/gusextreme.c4
-rw-r--r--sound/isa/gus/gusmax.c4
-rw-r--r--sound/isa/gus/interwave.c4
-rw-r--r--sound/isa/opl3sa2.c5
-rw-r--r--sound/isa/opti9xx/Makefile2
-rw-r--r--sound/isa/opti9xx/miro.c18
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c14
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/emu8000.c2
-rw-r--r--sound/isa/sb/emu8000_synth.c2
-rw-r--r--sound/isa/sb/sb16.c4
-rw-r--r--sound/isa/sb/sb16_csp.c9
-rw-r--r--sound/isa/sb/sb16_main.c4
-rw-r--r--sound/isa/sb/sb8.c4
-rw-r--r--sound/isa/sb/sb8_main.c4
-rw-r--r--sound/isa/sb/sb8_midi.c2
-rw-r--r--sound/isa/sb/sb_common.c8
-rw-r--r--sound/isa/sb/sb_mixer.c2
-rw-r--r--sound/isa/sc6000.c656
-rw-r--r--sound/isa/sscape.c354
-rw-r--r--sound/isa/wavefront/Makefile2
-rw-r--r--sound/isa/wavefront/wavefront_synth.c130
-rw-r--r--sound/last.c2
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/dmasound/Makefile6
-rw-r--r--sound/oss/dmasound/awacs_defs.h251
-rw-r--r--sound/oss/dmasound/dac3550a.c209
-rw-r--r--sound/oss/dmasound/dmasound.h13
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c3215
-rw-r--r--sound/oss/dmasound/dmasound_core.c287
-rw-r--r--sound/oss/dmasound/tas3001c.c849
-rw-r--r--sound/oss/dmasound/tas3001c.h64
-rw-r--r--sound/oss/dmasound/tas3001c_tables.c375
-rw-r--r--sound/oss/dmasound/tas3004.c1138
-rw-r--r--sound/oss/dmasound/tas3004.h77
-rw-r--r--sound/oss/dmasound/tas3004_tables.c301
-rw-r--r--sound/oss/dmasound/tas_common.c214
-rw-r--r--sound/oss/dmasound/tas_common.h284
-rw-r--r--sound/oss/dmasound/tas_eq_prefs.h24
-rw-r--r--sound/oss/dmasound/tas_ioctl.h23
-rw-r--r--sound/oss/dmasound/trans_16.c898
-rw-r--r--sound/oss/es1371.c3131
-rw-r--r--sound/pci/Kconfig111
-rw-r--r--sound/pci/Makefile2
-rw-r--r--sound/pci/ac97/Makefile2
-rw-r--r--sound/pci/ac97/ac97_codec.c40
-rw-r--r--sound/pci/ac97/ac97_id.h3
-rw-r--r--sound/pci/ac97/ac97_local.h2
-rw-r--r--sound/pci/ac97/ac97_patch.c162
-rw-r--r--sound/pci/ac97/ac97_patch.h2
-rw-r--r--sound/pci/ac97/ac97_pcm.c2
-rw-r--r--sound/pci/ac97/ac97_proc.c10
-rw-r--r--sound/pci/ac97/ak4531_codec.c4
-rw-r--r--sound/pci/ali5451/Makefile2
-rw-r--r--sound/pci/ali5451/ali5451.c10
-rw-r--r--sound/pci/als4000.c2
-rw-r--r--sound/pci/au88x0/au88x0.c1
-rw-r--r--sound/pci/au88x0/au88x0_eq.c10
-rw-r--r--sound/pci/au88x0/au88x0_mpu401.c2
-rw-r--r--sound/pci/au88x0/au88x0_synth.c4
-rw-r--r--sound/pci/bt87x.c217
-rw-r--r--sound/pci/ca0106/ca0106.h98
-rw-r--r--sound/pci/ca0106/ca0106_main.c103
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c98
-rw-r--r--sound/pci/ca0106/ca_midi.c2
-rw-r--r--sound/pci/ca0106/ca_midi.h6
-rw-r--r--sound/pci/cmipci.c537
-rw-r--r--sound/pci/cs4281.c28
-rw-r--r--sound/pci/cs46xx/Makefile8
-rw-r--r--sound/pci/cs46xx/cs46xx.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c12
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h2
-rw-r--r--sound/pci/cs46xx/dsp_spos.h2
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c2
-rw-r--r--sound/pci/cs5535audio/Makefile7
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c24
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h42
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c10
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c26
-rw-r--r--sound/pci/echoaudio/echoaudio.c33
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c4
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.h15
-rw-r--r--sound/pci/emu10k1/Makefile2
-rw-r--r--sound/pci/emu10k1/emu10k1.c4
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c130
-rw-r--r--sound/pci/emu10k1/emu10k1x.c9
-rw-r--r--sound/pci/emu10k1/emufx.c251
-rw-r--r--sound/pci/emu10k1/emumixer.c86
-rw-r--r--sound/pci/emu10k1/emumpu401.c2
-rw-r--r--sound/pci/emu10k1/emupcm.c2
-rw-r--r--sound/pci/emu10k1/emuproc.c58
-rw-r--r--sound/pci/emu10k1/io.c12
-rw-r--r--sound/pci/emu10k1/irq.c2
-rw-r--r--sound/pci/emu10k1/memory.c2
-rw-r--r--sound/pci/emu10k1/p16v.c19
-rw-r--r--sound/pci/emu10k1/voice.c2
-rw-r--r--sound/pci/ens1370.c44
-rw-r--r--sound/pci/es1938.c22
-rw-r--r--sound/pci/es1968.c28
-rw-r--r--sound/pci/fm801.c4
-rw-r--r--sound/pci/hda/Makefile27
-rw-r--r--sound/pci/hda/hda_codec.c735
-rw-r--r--sound/pci/hda/hda_codec.h113
-rw-r--r--sound/pci/hda/hda_generic.c100
-rw-r--r--sound/pci/hda/hda_hwdep.c122
-rw-r--r--sound/pci/hda/hda_intel.c382
-rw-r--r--sound/pci/hda/hda_local.h193
-rw-r--r--sound/pci/hda/hda_patch.h16
-rw-r--r--sound/pci/hda/hda_proc.c30
-rw-r--r--sound/pci/hda/patch_analog.c524
-rw-r--r--sound/pci/hda/patch_atihdmi.c16
-rw-r--r--sound/pci/hda/patch_cmedia.c24
-rw-r--r--sound/pci/hda/patch_conexant.c156
-rw-r--r--sound/pci/hda/patch_realtek.c1840
-rw-r--r--sound/pci/hda/patch_si3054.c20
-rw-r--r--sound/pci/hda/patch_sigmatel.c1000
-rw-r--r--sound/pci/hda/patch_via.c80
-rw-r--r--sound/pci/ice1712/Makefile2
-rw-r--r--sound/pci/ice1712/ak4xxx.c4
-rw-r--r--sound/pci/ice1712/amp.c2
-rw-r--r--sound/pci/ice1712/amp.h2
-rw-r--r--sound/pci/ice1712/aureon.c45
-rw-r--r--sound/pci/ice1712/delta.c13
-rw-r--r--sound/pci/ice1712/delta.h2
-rw-r--r--sound/pci/ice1712/envy24ht.h2
-rw-r--r--sound/pci/ice1712/ews.c20
-rw-r--r--sound/pci/ice1712/ews.h2
-rw-r--r--sound/pci/ice1712/hoontech.c2
-rw-r--r--sound/pci/ice1712/hoontech.h2
-rw-r--r--sound/pci/ice1712/ice1712.c52
-rw-r--r--sound/pci/ice1712/ice1712.h5
-rw-r--r--sound/pci/ice1712/ice1724.c54
-rw-r--r--sound/pci/ice1712/juli.c2
-rw-r--r--sound/pci/ice1712/phase.c23
-rw-r--r--sound/pci/ice1712/pontis.c27
-rw-r--r--sound/pci/ice1712/prodigy192.c27
-rw-r--r--sound/pci/ice1712/wtm.c29
-rw-r--r--sound/pci/intel8x0.c4
-rw-r--r--sound/pci/intel8x0m.c4
-rw-r--r--sound/pci/korg1212/Makefile2
-rw-r--r--sound/pci/korg1212/korg1212.c4
-rw-r--r--sound/pci/maestro3.c2
-rw-r--r--sound/pci/mixart/Makefile2
-rw-r--r--sound/pci/mixart/mixart.c10
-rw-r--r--sound/pci/mixart/mixart_mixer.c9
-rw-r--r--sound/pci/nm256/Makefile2
-rw-r--r--sound/pci/nm256/nm256.c1
-rw-r--r--sound/pci/pcxhr/pcxhr.c5
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c15
-rw-r--r--sound/pci/rme32.c33
-rw-r--r--sound/pci/rme96.c41
-rw-r--r--sound/pci/rme9652/Makefile2
-rw-r--r--sound/pci/rme9652/hdsp.c90
-rw-r--r--sound/pci/rme9652/hdspm.c723
-rw-r--r--sound/pci/rme9652/rme9652.c27
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/Makefile2
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/trident/trident_main.c22
-rw-r--r--sound/pci/trident/trident_memory.c2
-rw-r--r--sound/pci/via82xx.c19
-rw-r--r--sound/pci/via82xx_modem.c8
-rw-r--r--sound/pci/vx222/Makefile2
-rw-r--r--sound/pci/ymfpci/Makefile2
-rw-r--r--sound/pci/ymfpci/ymfpci.c4
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c108
-rw-r--r--sound/pcmcia/Makefile2
-rw-r--r--sound/pcmcia/pdaudiocf/Makefile2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_irq.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c2
-rw-r--r--sound/pcmcia/vx/Makefile2
-rw-r--r--sound/pcmcia/vx/vxp_mixer.c9
-rw-r--r--sound/ppc/Makefile2
-rw-r--r--sound/ppc/daca.c10
-rw-r--r--sound/ppc/pmac.c57
-rw-r--r--sound/ppc/pmac.h4
-rw-r--r--sound/ppc/snd_ps3.c1
-rw-r--r--sound/sh/aica.c10
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/cs4270.c805
-rw-r--r--sound/soc/codecs/cs4270.h28
-rw-r--r--sound/soc/pxa/spitz.c1
-rw-r--r--sound/soc/s3c24xx/Kconfig2
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c1
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c22
-rw-r--r--sound/soc/soc-core.c20
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/sparc/cs4231.c805
-rw-r--r--sound/sparc/dbri.c581
-rw-r--r--sound/spi/Kconfig31
-rw-r--r--sound/spi/Makefile5
-rw-r--r--sound/spi/at73c213.c1129
-rw-r--r--sound/spi/at73c213.h119
-rw-r--r--sound/synth/Makefile2
-rw-r--r--sound/synth/emux/Makefile2
-rw-r--r--sound/synth/util_mem.c2
-rw-r--r--sound/usb/Kconfig2
-rw-r--r--sound/usb/caiaq/caiaq-audio.c1
-rw-r--r--sound/usb/caiaq/caiaq-device.c18
-rw-r--r--sound/usb/caiaq/caiaq-device.h1
-rw-r--r--sound/usb/caiaq/caiaq-input.c28
-rw-r--r--sound/usb/usbaudio.c46
-rw-r--r--sound/usb/usbmidi.c46
-rw-r--r--sound/usb/usbmixer.c11
-rw-r--r--sound/usb/usbquirks.h100
3306 files changed, 114450 insertions, 86343 deletions
diff --git a/.gitignore b/.gitignore
index 27c3e839b54..22fb8fa9bc3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@ vmlinux*
!vmlinux.lds.S
System.map
Module.symvers
+!.gitignore
#
# Generated include files
diff --git a/CREDITS b/CREDITS
index 550bb2b9fe8..99566b1a6ee 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1165,6 +1165,12 @@ S: 600 North Bell Avenue, Suite 160
S: Carnegie, Pennsylvania 15106-4304
S: USA
+N: Kai Germaschewski
+E: kai@germaschewski.name
+D: Major kbuild rework during the 2.5 cycle
+D: ISDN Maintainer
+S: USA
+
N: Philip Gladstone
E: philip@gladstonefamily.net
D: Kernel / timekeeping stuff
@@ -1933,7 +1939,7 @@ M: seasons@makosteszta.sote.hu
D: Original author of software suspend
N: Jaroslav Kysela
-E: perex@suse.cz
+E: perex@perex.cz
W: http://www.perex.cz
D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters
D: ISA PnP
@@ -2702,7 +2708,7 @@ S: Canada K2P 0X8
N: Mikael Pettersson
E: mikpe@it.uu.se
-W: http://www.csd.uu.se/~mikpe/
+W: http://user.it.uu.se/~mikpe/linux/
D: Miscellaneous fixes
N: Reed H. Petty
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 43e89b1537d..299615d821a 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -22,6 +22,8 @@ CodingStyle
- how the boss likes the C code in the kernel to look.
DMA-API.txt
- DMA API, pci_ API & extensions for non-consistent memory machines.
+DMA-ISA-LPC.txt
+ - How to do DMA with ISA (and LPC) devices.
DMA-mapping.txt
- info for PCI drivers using DMA portably across all platforms.
DocBook/
@@ -50,6 +52,8 @@ README.cycladesZ
- info on Cyclades-Z firmware loading.
SAK.txt
- info on Secure Attention Keys.
+SM501.txt
+ - Silicon Motion SM501 multimedia companion chip
SecurityBugs
- procedure for reporting security bugs found in the kernel.
SubmitChecklist
@@ -145,7 +149,7 @@ fb/
feature-removal-schedule.txt
- list of files and features that are going to be removed.
filesystems/
- - directory with info on the various filesystems that Linux supports.
+ - info on the vfs and the various filesystems that Linux supports.
firmware_class/
- request_firmware() hotplug interface info.
floppy.txt
@@ -230,8 +234,6 @@ local_ops.txt
- semantics and behavior of local atomic operations.
lockdep-design.txt
- documentation on the runtime locking correctness validator.
-locks.txt
- - info on file locking implementations, flock() vs. fcntl(), etc.
logo.gif
- full colour GIF image of Linux logo (penguin - Tux).
logo.txt
@@ -240,14 +242,14 @@ m68k/
- directory with info about Linux on Motorola 68k architecture.
magic-number.txt
- list of magic numbers used to mark/protect kernel data structures.
-mandatory.txt
- - info on the Linux implementation of Sys V mandatory file locking.
mca.txt
- info on supporting Micro Channel Architecture (e.g. PS/2) systems.
md.txt
- info on boot arguments for the multiple devices driver.
memory-barriers.txt
- info on Linux kernel memory barriers.
+memory-hotplug.txt
+ - Hotpluggable memory support, how to use and current status.
memory.txt
- info on typical Linux memory problems.
mips/
@@ -298,6 +300,8 @@ pm.txt
- info on Linux power management support.
pnp.txt
- Linux Plug and Play documentation.
+power_supply_class.txt
+ - Tells userspace about battery, UPS, AC or DC power supply properties
power/
- directory with info on Linux PCI power management.
powerpc/
@@ -334,8 +338,12 @@ sched-coding.txt
- reference for various scheduler-related methods in the O(1) scheduler.
sched-design.txt
- goals, design and implementation of the Linux O(1) scheduler.
+sched-design-CFS.txt
+ - goals, design and implementation of the Complete Fair Scheduler.
sched-domains.txt
- information on scheduling domains.
+sched-nice-design.txt
+ - How and why the scheduler's nice levels are implemented.
sched-stats.txt
- information on schedstats (Linux Scheduler Statistics).
scsi/
@@ -380,6 +388,8 @@ stallion.txt
- info on using the Stallion multiport serial driver.
svga.txt
- short guide on selecting video modes at boot via VGA BIOS.
+sysfs-rules.txt
+ - How not to use sysfs.
sx.txt
- info on the Specialix SX/SI multiport serial driver.
sysctl/
@@ -410,6 +420,8 @@ video4linux/
- directory with info regarding video/TV/radio cards and linux.
vm/
- directory with info on the Linux vm code.
+volatile-considered-harmful.txt
+ - Why the "volatile" type class should not be used
voyager.txt
- guide to running Linux on the Voyager architecture.
w1/
@@ -418,7 +430,5 @@ watchdog/
- how to auto-reboot Linux if it has "fallen and can't get up". ;-)
x86_64/
- directory with info on Linux support for AMD x86-64 (Hammer) machines.
-xterm-linux.xpm
- - XPM image of penguin logo (see logo.txt) sitting on an xterm.
zorro.txt
- info on writing drivers for Zorro bus devices found on Amigas.
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index 7f1730f1a1a..6caa1461557 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -77,12 +77,15 @@ Get a decent editor and don't leave whitespace at the end of lines.
Coding style is all about readability and maintainability using commonly
available tools.
-The limit on the length of lines is 80 columns and this is a hard limit.
+The limit on the length of lines is 80 columns and this is a strongly
+preferred limit.
Statements longer than 80 columns will be broken into sensible chunks.
Descendants are always substantially shorter than the parent and are placed
substantially to the right. The same applies to function headers with a long
-argument list. Long strings are as well broken into shorter strings.
+argument list. Long strings are as well broken into shorter strings. The
+only exception to this is where exceeding 80 columns significantly increases
+readability and does not hide information.
void fun(int a, int b, int c)
{
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index e07f2530326..d84f89dbf92 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -189,12 +189,6 @@ smaller mask as pci_set_dma_mask(). However for the rare case that a
device driver only uses consistent allocations, one would have to
check the return value from pci_set_consistent_dma_mask().
-If your 64-bit device is going to be an enormous consumer of DMA
-mappings, this can be problematic since the DMA mappings are a
-finite resource on many platforms. Please see the "DAC Addressing
-for Address Space Hungry Devices" section near the end of this
-document for how to handle this case.
-
Finally, if your device can only drive the low 24-bits of
address during PCI bus mastering you might do something like:
@@ -203,8 +197,6 @@ address during PCI bus mastering you might do something like:
"mydev: 24-bit DMA addressing not available.\n");
goto ignore_this_device;
}
-[Better use DMA_24BIT_MASK instead of 0x00ffffff.
-See linux/include/dma-mapping.h for reference.]
When pci_set_dma_mask() is successful, and returns zero, the PCI layer
saves away this mask you have provided. The PCI layer will use this
@@ -514,7 +506,7 @@ With scatterlists, you map a region gathered from several regions by:
int i, count = pci_map_sg(dev, sglist, nents, direction);
struct scatterlist *sg;
- for (i = 0, sg = sglist; i < count; i++, sg++) {
+ for_each_sg(sglist, sg, count, i) {
hw_address[i] = sg_dma_address(sg);
hw_len[i] = sg_dma_len(sg);
}
@@ -652,18 +644,6 @@ It is planned to completely remove virt_to_bus() and bus_to_virt() as
they are entirely deprecated. Some ports already do not provide these
as it is impossible to correctly support them.
- 64-bit DMA and DAC cycle support
-
-Do you understand all of the text above? Great, then you already
-know how to use 64-bit DMA addressing under Linux. Simply make
-the appropriate pci_set_dma_mask() calls based upon your cards
-capabilities, then use the mapping APIs above.
-
-It is that simple.
-
-Well, not for some odd devices. See the next section for information
-about that.
-
Optimizing Unmap State Space Consumption
On many platforms, pci_unmap_{single,page}() is simply a nop.
@@ -782,5 +762,5 @@ following people:
Jay Estabrook <Jay.Estabrook@compaq.com>
Thomas Sailer <sailer@ife.ee.ethz.ch>
Andrea Arcangeli <andrea@suse.de>
- Jens Axboe <axboe@suse.de>
+ Jens Axboe <jens.axboe@oracle.com>
David Mosberger-Tang <davidm@hpl.hp.com>
diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl
index 361c884d860..9ee6f3cbb41 100644
--- a/Documentation/DocBook/deviceiobook.tmpl
+++ b/Documentation/DocBook/deviceiobook.tmpl
@@ -85,7 +85,7 @@
<chapter id="mmio">
<title>Memory Mapped IO</title>
- <sect1>
+ <sect1 id="getting_access_to_the_device">
<title>Getting Access to the Device</title>
<para>
The most widely supported form of IO is memory mapped IO.
@@ -114,7 +114,7 @@
</para>
</sect1>
- <sect1>
+ <sect1 id="accessing_the_device">
<title>Accessing the device</title>
<para>
The part of the interface most used by drivers is reading and
@@ -272,9 +272,9 @@ CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
</chapter>
- <chapter>
+ <chapter id="port_space_accesses">
<title>Port Space Accesses</title>
- <sect1>
+ <sect1 id="port_space_explained">
<title>Port Space Explained</title>
<para>
@@ -291,7 +291,7 @@ CPU B: spin_unlock_irqrestore(&amp;dev_lock, flags)
</para>
</sect1>
- <sect1>
+ <sect1 id="accessing_port_space">
<title>Accessing Port Space</title>
<para>
Accesses to this space are provided through a set of functions
diff --git a/Documentation/DocBook/filesystems.tmpl b/Documentation/DocBook/filesystems.tmpl
index 39fa2aba7f9..5eaef87e8f1 100644
--- a/Documentation/DocBook/filesystems.tmpl
+++ b/Documentation/DocBook/filesystems.tmpl
@@ -40,25 +40,25 @@
<chapter id="vfs">
<title>The Linux VFS</title>
- <sect1><title>The Filesystem types</title>
+ <sect1 id="the_filesystem_types"><title>The Filesystem types</title>
!Iinclude/linux/fs.h
</sect1>
- <sect1><title>The Directory Cache</title>
+ <sect1 id="the_directory_cache"><title>The Directory Cache</title>
!Efs/dcache.c
!Iinclude/linux/dcache.h
</sect1>
- <sect1><title>Inode Handling</title>
+ <sect1 id="inode_handling"><title>Inode Handling</title>
!Efs/inode.c
!Efs/bad_inode.c
</sect1>
- <sect1><title>Registration and Superblocks</title>
+ <sect1 id="registration_and_superblocks"><title>Registration and Superblocks</title>
!Efs/super.c
</sect1>
- <sect1><title>File Locks</title>
+ <sect1 id="file_locks"><title>File Locks</title>
!Efs/locks.c
!Ifs/locks.c
</sect1>
- <sect1><title>Other Functions</title>
+ <sect1 id="other_functions"><title>Other Functions</title>
!Efs/mpage.c
!Efs/namei.c
!Efs/buffer.c
@@ -73,11 +73,11 @@
<chapter id="proc">
<title>The proc filesystem</title>
- <sect1><title>sysctl interface</title>
+ <sect1 id="sysctl_interface"><title>sysctl interface</title>
!Ekernel/sysctl.c
</sect1>
- <sect1><title>proc filesystem interface</title>
+ <sect1 id="proc_filesystem_interface"><title>proc filesystem interface</title>
!Ifs/proc/base.c
</sect1>
</chapter>
@@ -92,7 +92,7 @@
<chapter id="debugfs">
<title>The debugfs filesystem</title>
- <sect1><title>debugfs interface</title>
+ <sect1 id="debugfs_interface"><title>debugfs interface</title>
!Efs/debugfs/inode.c
!Efs/debugfs/file.c
</sect1>
@@ -134,9 +134,9 @@
<title>The Linux Journalling API</title>
- <sect1>
+ <sect1 id="journaling_overview">
<title>Overview</title>
- <sect2>
+ <sect2 id="journaling_details">
<title>Details</title>
<para>
The journalling layer is easy to use. You need to
@@ -307,7 +307,7 @@ particular inode.
</sect2>
- <sect2>
+ <sect2 id="jbd_summary">
<title>Summary</title>
<para>
Using the journal is a matter of wrapping the different context changes,
@@ -349,7 +349,7 @@ an example.
</sect1>
- <sect1>
+ <sect1 id="data_types">
<title>Data Types</title>
<para>
The journalling layer uses typedefs to 'hide' the concrete definitions
@@ -358,27 +358,27 @@ an example.
Obviously the hiding is not enforced as this is 'C'.
</para>
- <sect2><title>Structures</title>
+ <sect2 id="structures"><title>Structures</title>
!Iinclude/linux/jbd.h
</sect2>
</sect1>
- <sect1>
+ <sect1 id="functions">
<title>Functions</title>
<para>
The functions here are split into two groups those that
affect a journal as a whole, and those which are used to
manage transactions
</para>
- <sect2><title>Journal Level</title>
+ <sect2 id="journal_level"><title>Journal Level</title>
!Efs/jbd/journal.c
!Ifs/jbd/recovery.c
</sect2>
- <sect2><title>Transasction Level</title>
+ <sect2 id="transaction_level"><title>Transasction Level</title>
!Efs/jbd/transaction.c
</sect2>
</sect1>
- <sect1>
+ <sect1 id="see_also">
<title>See also</title>
<para>
<citation>
diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl
index 6996d977bf8..5a8ffa761e0 100644
--- a/Documentation/DocBook/gadget.tmpl
+++ b/Documentation/DocBook/gadget.tmpl
@@ -144,7 +144,7 @@ with the lowest level (which directly handles hardware).
<para>This is the lowest software level.
It is the only layer that talks to hardware,
through registers, fifos, dma, irqs, and the like.
- The <filename>&lt;linux/usb_gadget.h&gt;</filename> API abstracts
+ The <filename>&lt;linux/usb/gadget.h&gt;</filename> API abstracts
the peripheral controller endpoint hardware.
That hardware is exposed through endpoint objects, which accept
streams of IN/OUT buffers, and through callbacks that interact
@@ -494,7 +494,7 @@ side drivers (and usbcore).
<sect1 id="core"><title>Core Objects and Methods</title>
<para>These are declared in
-<filename>&lt;linux/usb_gadget.h&gt;</filename>,
+<filename>&lt;linux/usb/gadget.h&gt;</filename>,
and are used by gadget drivers to interact with
USB peripheral controller drivers.
</para>
@@ -509,7 +509,7 @@ USB peripheral controller drivers.
unless the explanations are trivial.
-->
-!Iinclude/linux/usb_gadget.h
+!Iinclude/linux/usb/gadget.h
</sect1>
<sect1 id="utils"><title>Optional Utilities</title>
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 230cbf75378..d3290c46af5 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -340,7 +340,7 @@ X!Earch/x86/kernel/mca_32.c
<chapter id="security">
<title>Security Framework</title>
-!Esecurity/security.c
+!Isecurity/security.c
</chapter>
<chapter id="audit">
@@ -386,8 +386,7 @@ X!Edrivers/base/interface.c
!Edrivers/base/bus.c
</sect1>
<sect1><title>Device Drivers Power Management</title>
-!Edrivers/base/power/resume.c
-!Edrivers/base/power/suspend.c
+!Edrivers/base/power/main.c
</sect1>
<sect1><title>Device Drivers ACPI Support</title>
<!-- Internal functions only
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index c64e969dc33..54835610b3d 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -77,7 +77,7 @@ documentation files are also added which explain how to use the feature.
When a kernel change causes the interface that the kernel exposes to
userspace to change, it is recommended that you send the information or
a patch to the manual pages explaining the change to the manual pages
-maintainer at mtk-manpages@gmx.net.
+maintainer at mtk.manpages@gmail.com.
Here is a list of files that are in the kernel source tree that are
required reading:
@@ -330,7 +330,7 @@ Here is a list of some of the different kernel trees available:
- ACPI development tree, Len Brown <len.brown@intel.com>
git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
- - Block development tree, Jens Axboe <axboe@suse.de>
+ - Block development tree, Jens Axboe <jens.axboe@oracle.com>
git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
- DRM development tree, Dave Airlie <airlied@linux.ie>
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 24dc3fcf159..bc38283379f 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -441,17 +441,20 @@ ACPI, and if none of those then a KCS device at the spec-specified
0xca2. If you want to turn this off, set the "trydefaults" option to
false.
-If you have high-res timers compiled into the kernel, the driver will
-use them to provide much better performance. Note that if you do not
-have high-res timers enabled in the kernel and you don't have
-interrupts enabled, the driver will run VERY slowly. Don't blame me,
+If your IPMI interface does not support interrupts and is a KCS or
+SMIC interface, the IPMI driver will start a kernel thread for the
+interface to help speed things up. This is a low-priority kernel
+thread that constantly polls the IPMI driver while an IPMI operation
+is in progress. The force_kipmid module parameter will all the user to
+force this thread on or off. If you force it off and don't have
+interrupts, the driver will run VERY slowly. Don't blame me,
these interfaces suck.
The driver supports a hot add and remove of interfaces. This way,
interfaces can be added or removed after the kernel is up and running.
-This is done using /sys/modules/ipmi_si/hotmod, which is a write-only
-parameter. You write a string to this interface. The string has the
-format:
+This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a
+write-only parameter. You write a string to this interface. The string
+has the format:
<op1>[:op2[:op3...]]
The "op"s are:
add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]]
@@ -581,9 +584,11 @@ The watchdog will panic and start a 120 second reset timeout if it
gets a pre-action. During a panic or a reboot, the watchdog will
start a 120 timer if it is running to make sure the reboot occurs.
-Note that if you use the NMI preaction for the watchdog, you MUST
-NOT use nmi watchdog mode 1. If you use the NMI watchdog, you
-must use mode 2.
+Note that if you use the NMI preaction for the watchdog, you MUST NOT
+use the nmi watchdog. There is no reasonable way to tell if an NMI
+comes from the IPMI controller, so it must assume that if it gets an
+otherwise unhandled NMI, it must be from IPMI and it will panic
+immediately.
Once you open the watchdog timer, you must write a 'V' character to the
device to close it, or the timer will not stop. This is a new semantic
diff --git a/Documentation/RCU/00-INDEX b/Documentation/RCU/00-INDEX
new file mode 100644
index 00000000000..461481dfb7c
--- /dev/null
+++ b/Documentation/RCU/00-INDEX
@@ -0,0 +1,22 @@
+00-INDEX
+ - This file
+arrayRCU.txt
+ - Using RCU to Protect Read-Mostly Arrays
+checklist.txt
+ - Review Checklist for RCU Patches
+listRCU.txt
+ - Using RCU to Protect Read-Mostly Linked Lists
+NMI-RCU.txt
+ - Using RCU to Protect Dynamic NMI Handlers
+rcuref.txt
+ - Reference-count design for elements of lists/arrays protected by RCU
+rcu.txt
+ - RCU Concepts
+RTFP.txt
+ - List of RCU papers (bibliography) going back to 1980.
+torture.txt
+ - RCU Torture Test Operation (CONFIG_RCU_TORTURE_TEST)
+UP.txt
+ - RCU on Uniprocessor Systems
+whatisRCU.txt
+ - What is RCU?
diff --git a/Documentation/SM501.txt b/Documentation/SM501.txt
index 3a1bd95d376..6fc65603592 100644
--- a/Documentation/SM501.txt
+++ b/Documentation/SM501.txt
@@ -3,6 +3,11 @@
Copyright 2006, 2007 Simtec Electronics
+The Silicon Motion SM501 multimedia companion chip 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 interface.
+The device may be connected by PCI or local bus with varying functions enabled.
+
Core
----
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index cbee3a27f76..ab82b7f5331 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
-#include <sys/types.h>
#include <signal.h>
#include <linux/genetlink.h>
diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index 2c6a3b38967..82e418d648d 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -4,19 +4,29 @@ Booting
- requirements for booting
Interrupts
- ARM Interrupt subsystem documentation
+IXP2000
+ - Release Notes for Linux on Intel's IXP2000 Network Processor
Netwinder
- Netwinder specific documentation
+Porting
+ - Symbol definitions for porting Linux to a new ARM machine.
+Setup
+ - Kernel initialization parameters on ARM Linux
README
- General ARM documentation
-SA1100
+SA1100/
- SA1100 documentation
-XScale
- - XScale documentation
-empeg
- - Empeg documentation
+Samsung-S3C24XX
+ - S3C24XX ARM Linux Overview
+Sharp-LH
+ - Linux on Sharp LH79524 and LH7A40X System On a Chip (SOC)
+VFP/
+ - Release notes for Linux Kernel Vector Floating Point support code
+empeg/
+ - Ltd's Empeg MP3 Car Audio Player
mem_alignment
- alignment abort handler documentation
memory.txt
- description of the virtual memory layout
-nwfpe
+nwfpe/
- NWFPE floating point emulator documentation
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
index 05851e9982e..f20c10c2858 100644
--- a/Documentation/atomic_ops.txt
+++ b/Documentation/atomic_ops.txt
@@ -14,8 +14,15 @@ suffice:
typedef struct { volatile int counter; } atomic_t;
- The first operations to implement for atomic_t's are the
-initializers and plain reads.
+Historically, counter has been declared volatile. This is now discouraged.
+See Documentation/volatile-considered-harmful.txt for the complete rationale.
+
+local_t is very similar to atomic_t. If the counter is per CPU and only
+updated by one CPU, local_t is probably more appropriate. Please see
+Documentation/local_ops.txt for the semantics of local_t.
+
+The first operations to implement for atomic_t's are the initializers and
+plain reads.
#define ATOMIC_INIT(i) { (i) }
#define atomic_set(v, i) ((v)->counter = (i))
@@ -24,6 +31,12 @@ The first macro is used in definitions, such as:
static atomic_t my_counter = ATOMIC_INIT(1);
+The initializer is atomic in that the return values of the atomic operations
+are guaranteed to be correct reflecting the initialized value if the
+initializer is used before runtime. If the initializer is used at runtime, a
+proper implicit or explicit read memory barrier is needed before reading the
+value with atomic_read from another thread.
+
The second interface can be used at runtime, as in:
struct foo { atomic_t counter; };
@@ -36,13 +49,43 @@ The second interface can be used at runtime, as in:
return -ENOMEM;
atomic_set(&k->counter, 0);
+The setting is atomic in that the return values of the atomic operations by
+all threads are guaranteed to be correct reflecting either the value that has
+been set with this operation or set with another operation. A proper implicit
+or explicit memory barrier is needed before the value set with the operation
+is guaranteed to be readable with atomic_read from another thread.
+
Next, we have:
#define atomic_read(v) ((v)->counter)
-which simply reads the current value of the counter.
-
-Now, we move onto the actual atomic operation interfaces.
+which simply reads the counter value currently visible to the calling thread.
+The read is atomic in that the return value is guaranteed to be one of the
+values initialized or modified with the interface operations if a proper
+implicit or explicit memory barrier is used after possible runtime
+initialization by any other thread and the value is modified only with the
+interface operations. atomic_read does not guarantee that the runtime
+initialization by any other thread is visible yet, so the user of the
+interface must take care of that with a proper implicit or explicit memory
+barrier.
+
+*** WARNING: atomic_read() and atomic_set() DO NOT IMPLY BARRIERS! ***
+
+Some architectures may choose to use the volatile keyword, barriers, or inline
+assembly to guarantee some degree of immediacy for atomic_read() and
+atomic_set(). This is not uniformly guaranteed, and may change in the future,
+so all users of atomic_t should treat atomic_read() and atomic_set() as simple
+C statements that may be reordered or optimized away entirely by the compiler
+or processor, and explicitly invoke the appropriate compiler and/or memory
+barrier for each use case. Failure to do so will result in code that may
+suddenly break when used with different architectures or compiler
+optimizations, or even changes in unrelated code which changes how the
+compiler optimizes the section accessing atomic_t variables.
+
+*** YOU HAVE BEEN WARNED! ***
+
+Now, we move onto the atomic operation interfaces typically implemented with
+the help of assembly code.
void atomic_add(int i, atomic_t *v);
void atomic_sub(int i, atomic_t *v);
@@ -117,6 +160,12 @@ operation.
Then:
+ int atomic_xchg(atomic_t *v, int new);
+
+This performs an atomic exchange operation on the atomic variable v, setting
+the given new value. It returns the old value that the atomic variable v had
+just before the operation.
+
int atomic_cmpxchg(atomic_t *v, int old, int new);
This performs an atomic compare exchange operation on the atomic value v,
@@ -369,6 +418,20 @@ brothers:
*/
smp_mb__after_clear_bit();
+There are two special bitops with lock barrier semantics (acquire/release,
+same as spinlocks). These operate in the same way as their non-_lock/unlock
+postfixed variants, except that they are to provide acquire/release semantics,
+respectively. This means they can be used for bit_spin_trylock and
+bit_spin_unlock type operations without specifying any more barriers.
+
+ int test_and_set_bit_lock(unsigned long nr, unsigned long *addr);
+ void clear_bit_unlock(unsigned long nr, unsigned long *addr);
+ void __clear_bit_unlock(unsigned long nr, unsigned long *addr);
+
+The __clear_bit_unlock version is non-atomic, however it still implements
+unlock barrier semantics. This can be useful if the lock itself is protecting
+the other bits in the word.
+
Finally, there are non-atomic versions of the bitmask operations
provided. They are used in contexts where some other higher-level SMP
locking scheme is being used to protect the bitmask, and thus less
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX
new file mode 100644
index 00000000000..961a0513f8c
--- /dev/null
+++ b/Documentation/block/00-INDEX
@@ -0,0 +1,20 @@
+00-INDEX
+ - This file
+as-iosched.txt
+ - Anticipatory IO scheduler
+barrier.txt
+ - I/O Barriers
+biodoc.txt
+ - Notes on the Generic Block Layer Rewrite in Linux 2.5
+capability.txt
+ - Generic Block Device Capability (/sys/block/<disk>/capability)
+deadline-iosched.txt
+ - Deadline IO scheduler tunables
+ioprio.txt
+ - Block io priorities (in CFQ scheduler)
+request.txt
+ - The members of struct request (in include/linux/blkdev.h)
+stat.txt
+ - Block layer statistics in /sys/block/<dev>/stat
+switching-sched.txt
+ - Switching I/O schedulers at runtime
diff --git a/Documentation/block/as-iosched.txt b/Documentation/block/as-iosched.txt
index a598fe10a29..738b72be128 100644
--- a/Documentation/block/as-iosched.txt
+++ b/Documentation/block/as-iosched.txt
@@ -20,15 +20,10 @@ actually has a head for each physical device in the logical RAID device.
However, setting the antic_expire (see tunable parameters below) produces
very similar behavior to the deadline IO scheduler.
-
Selecting IO schedulers
-----------------------
-To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
-'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are
-assigned globally at boot time only presently. It's also possible to change
-the IO scheduler for a determined device on the fly, as described in
-Documentation/block/switching-sched.txt.
-
+Refer to Documentation/block/switching-sched.txt for information on
+selecting an io scheduler on a per-device basis.
Anticipatory IO scheduler Policies
----------------------------------
@@ -115,7 +110,7 @@ statistics (average think time, average seek distance) on the process
that submitted the just completed request are examined. If it seems
likely that that process will submit another request soon, and that
request is likely to be near the just completed request, then the IO
-scheduler will stop dispatching more read requests for up time (antic_expire)
+scheduler will stop dispatching more read requests for up to (antic_expire)
milliseconds, hoping that process will submit a new request near the one
that just completed. If such a request is made, then it is dispatched
immediately. If the antic_expire wait time expires, then the IO scheduler
@@ -165,3 +160,13 @@ The parameters are:
for big seek time devices though not a linear correspondence - most
processes have only a few ms thinktime.
+In addition to the tunables above there is a read-only file named est_time
+which, when read, will show:
+
+ - The probability of a task exiting without a cooperating task
+ submitting an anticipated IO.
+
+ - The current mean think time.
+
+ - The seek distance used to determine if an incoming IO is better.
+
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index dc3f49e3e53..93f223b9723 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -2,7 +2,7 @@
=====================================================
Notes Written on Jan 15, 2002:
- Jens Axboe <axboe@suse.de>
+ Jens Axboe <jens.axboe@oracle.com>
Suparna Bhattacharya <suparna@in.ibm.com>
Last Updated May 2, 2002
@@ -21,7 +21,7 @@ Credits:
---------
2.5 bio rewrite:
- Jens Axboe <axboe@suse.de>
+ Jens Axboe <jens.axboe@oracle.com>
Many aspects of the generic block layer redesign were driven by and evolved
over discussions, prior patches and the collective experience of several
diff --git a/Documentation/block/deadline-iosched.txt b/Documentation/block/deadline-iosched.txt
index be08ffd1e9b..c23cab13c3d 100644
--- a/Documentation/block/deadline-iosched.txt
+++ b/Documentation/block/deadline-iosched.txt
@@ -5,16 +5,10 @@ This little file attempts to document how the deadline io scheduler works.
In particular, it will clarify the meaning of the exposed tunables that may be
of interest to power users.
-Each io queue has a set of io scheduler tunables associated with it. These
-tunables control how the io scheduler works. You can find these entries
-in:
-
-/sys/block/<device>/queue/iosched
-
-assuming that you have sysfs mounted on /sys. If you don't have sysfs mounted,
-you can do so by typing:
-
-# mount none /sys -t sysfs
+Selecting IO schedulers
+-----------------------
+Refer to Documentation/block/switching-sched.txt for information on
+selecting an io scheduler on a per-device basis.
********************************************************************************
@@ -41,14 +35,11 @@ fifo_batch
When a read request expires its deadline, we must move some requests from
the sorted io scheduler list to the block device dispatch queue. fifo_batch
-controls how many requests we move, based on the cost of each request. A
-request is either qualified as a seek or a stream. The io scheduler knows
-the last request that was serviced by the drive (or will be serviced right
-before this one). See seek_cost and stream_unit.
+controls how many requests we move.
-write_starved (number of dispatches)
--------------
+writes_starved (number of dispatches)
+--------------
When we have to move requests from the io scheduler queue to the block
device dispatch queue, we always give a preference to reads. However, we
@@ -73,6 +64,6 @@ that comes at basically 0 cost we leave that on. We simply disable the
rbtree front sector lookup when the io scheduler merge function is called.
-Nov 11 2002, Jens Axboe <axboe@suse.de>
+Nov 11 2002, Jens Axboe <jens.axboe@oracle.com>
diff --git a/Documentation/block/ioprio.txt b/Documentation/block/ioprio.txt
index 35e516b0b8a..8ed8c59380b 100644
--- a/Documentation/block/ioprio.txt
+++ b/Documentation/block/ioprio.txt
@@ -180,4 +180,4 @@ int main(int argc, char *argv[])
---> snip ionice.c tool <---
-March 11 2005, Jens Axboe <axboe@suse.de>
+March 11 2005, Jens Axboe <jens.axboe@oracle.com>
diff --git a/Documentation/block/request.txt b/Documentation/block/request.txt
index fff58acb40a..754e104ed36 100644
--- a/Documentation/block/request.txt
+++ b/Documentation/block/request.txt
@@ -1,7 +1,7 @@
struct request documentation
-Jens Axboe <axboe@suse.de> 27/05/02
+Jens Axboe <jens.axboe@oracle.com> 27/05/02
1.0
Index
diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt
index 5fa130a6753..634c952e196 100644
--- a/Documentation/block/switching-sched.txt
+++ b/Documentation/block/switching-sched.txt
@@ -1,3 +1,18 @@
+To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
+'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are
+assigned globally at boot time only presently.
+
+Each io queue has a set of io scheduler tunables associated with it. These
+tunables control how the io scheduler works. You can find these entries
+in:
+
+/sys/block/<device>/queue/iosched
+
+assuming that you have sysfs mounted on /sys. If you don't have sysfs mounted,
+you can do so by typing:
+
+# mount none /sys -t sysfs
+
As of the Linux 2.6.10 kernel, it is now possible to change the
IO scheduler for a given block device on the fly (thus making it possible,
for instance, to set the CFQ scheduler for the system default, but
@@ -20,3 +35,9 @@ noop anticipatory deadline [cfq]
# echo anticipatory > /sys/block/hda/queue/scheduler
# cat /sys/block/hda/queue/scheduler
noop [anticipatory] deadline cfq
+
+Each io queue has a set of io scheduler tunables associated with it. These
+tunables control how the io scheduler works. You can find these entries
+in:
+
+/sys/block/<device>/queue/iosched
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index 866b7613942..552cabac060 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -133,12 +133,6 @@ changes occur:
The ia64 sn2 platform is one example of a platform
that uses this interface.
-8) void lazy_mmu_prot_update(pte_t pte)
- This interface is called whenever the protection on
- any user PTEs change. This interface provides a notification
- to architecture specific code to take appropriate action.
-
-
Next, we have the cache flushing interfaces. In general, when Linux
is changing an existing virtual-->physical mapping to a new value,
the sequence will be in one of the following forms:
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index f2c0a684293..ec9de6917f0 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -35,7 +35,8 @@ CONTENTS:
----------------------
Cpusets provide a mechanism for assigning a set of CPUs and Memory
-Nodes to a set of tasks.
+Nodes to a set of tasks. In this document "Memory Node" refers to
+an on-line node that contains memory.
Cpusets constrain the CPU and Memory placement of tasks to only
the resources within a tasks current cpuset. They form a nested
@@ -86,9 +87,6 @@ This can be especially valuable on:
and a database), or
* NUMA systems running large HPC applications with demanding
performance characteristics.
- * Also cpu_exclusive cpusets are useful for servers running orthogonal
- workloads such as RT applications requiring low latency and HPC
- applications that are throughput sensitive
These subsets, or "soft partitions" must be able to be dynamically
adjusted, as the job mix changes, without impacting other concurrently
@@ -131,8 +129,6 @@ Cpusets extends these two mechanisms as follows:
- A cpuset may be marked exclusive, which ensures that no other
cpuset (except direct ancestors and descendents) may contain
any overlapping CPUs or Memory Nodes.
- Also a cpu_exclusive cpuset would be associated with a sched
- domain.
- You can list all the tasks (by pid) attached to any cpuset.
The implementation of cpusets requires a few, simple hooks
@@ -144,9 +140,6 @@ into the rest of the kernel, none in performance critical paths:
allowed in that tasks cpuset.
- in sched.c migrate_all_tasks(), to keep migrating tasks within
the CPUs allowed by their cpuset, if possible.
- - in sched.c, a new API partition_sched_domains for handling
- sched domain changes associated with cpu_exclusive cpusets
- and related changes in both sched.c and arch/ia64/kernel/domain.c
- in the mbind and set_mempolicy system calls, to mask the requested
Memory Nodes by what's allowed in that tasks cpuset.
- in page_alloc.c, to restrict memory to allowed nodes.
@@ -220,8 +213,8 @@ and name space for cpusets, with a minimum of additional kernel code.
The cpus and mems files in the root (top_cpuset) cpuset are
read-only. The cpus file automatically tracks the value of
cpu_online_map using a CPU hotplug notifier, and the mems file
-automatically tracks the value of node_online_map using the
-cpuset_track_online_nodes() hook.
+automatically tracks the value of node_states[N_MEMORY]--i.e.,
+nodes with memory--using the cpuset_track_online_nodes() hook.
1.4 What are exclusive cpusets ?
@@ -231,15 +224,6 @@ If a cpuset is cpu or mem exclusive, no other cpuset, other than
a direct ancestor or descendent, may share any of the same CPUs or
Memory Nodes.
-A cpuset that is cpu_exclusive has a scheduler (sched) domain
-associated with it. The sched domain consists of all CPUs in the
-current cpuset that are not part of any exclusive child cpusets.
-This ensures that the scheduler load balancing code only balances
-against the CPUs that are in the sched domain as defined above and
-not all of the CPUs in the system. This removes any overhead due to
-load balancing code trying to pull tasks outside of the cpu_exclusive
-cpuset only to be prevented by the tasks' cpus_allowed mask.
-
A cpuset that is mem_exclusive restricts kernel allocations for
page, buffer and other data commonly shared by the kernel across
multiple users. All cpusets, whether mem_exclusive or not, restrict
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 7b9551fc6fe..f2d658a6a94 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -42,6 +42,9 @@
*.9.gz
.*
.cscope
+.gitignore
+.mailmap
+.mm
53c700_d.h
53c7xx_d.h
53c7xx_u.h
@@ -121,7 +124,6 @@ kxgettext
lkc_defs.h
lex.c*
lex.*.c
-lk201-map.c
logo_*.c
logo_*_clut224.c
logo_*_mono.c
@@ -176,11 +178,13 @@ times.h*
tkparse
trix_boot.h
utsrelease.h*
+vdso.lds
version.h*
vmlinux
vmlinux-*
vmlinux.aout
-vmlinux.lds
+vmlinux*.lds*
+vmlinux*.scr
vsyscall.lds
wanxlfw.inc
uImage
diff --git a/Documentation/early-userspace/README b/Documentation/early-userspace/README
index cddbac456c2..766d320c8eb 100644
--- a/Documentation/early-userspace/README
+++ b/Documentation/early-userspace/README
@@ -19,7 +19,7 @@ It consists of several major infrastructure components:
- klibc, a userspace C library, currently packaged separately, that is
optimized for correctness and small size.
-The cpio file format used by initramfs is the "newc" (aka "cpio -c")
+The cpio file format used by initramfs is the "newc" (aka "cpio -H newc")
format, and is documented in the file "buffer-format.txt". There are
two ways to add an early userspace image: specify an existing cpio
archive to be used as the image or have the kernel build process build
@@ -44,7 +44,7 @@ The image is specified as one or more sources in
CONFIG_INITRAMFS_SOURCE. Sources can be either directories or files -
cpio archives are *not* allowed when building from sources.
-A source directory will have it and all of it's contents packaged. The
+A source directory will have it and all of its contents packaged. The
specified directory name will be mapped to '/'. When packaging a
directory, limited user and group ID translation can be performed.
INITRAMFS_ROOT_UID can be set to a user ID that needs to be mapped to
@@ -144,7 +144,7 @@ c) using initramfs. The call to prepare_namespace() must be skipped.
initrd format, an cpio archive. It must be called "/init". This binary
is responsible to do all the things prepare_namespace() would do.
- To remain backwards compatibility, the /init binary will only run if it
+ To maintain backwards compatibility, the /init binary will only run if it
comes via an initramfs cpio archive. If this is not the case,
init/main.c:init() will run prepare_namespace() to mount the final root
and exec one of the predefined init binaries.
diff --git a/Documentation/email-clients.txt b/Documentation/email-clients.txt
new file mode 100644
index 00000000000..113165b4830
--- /dev/null
+++ b/Documentation/email-clients.txt
@@ -0,0 +1,217 @@
+Email clients info for Linux
+======================================================================
+
+General Preferences
+----------------------------------------------------------------------
+Patches for the Linux kernel are submitted via email, preferably as
+inline text in the body of the email. Some maintainers accept
+attachments, but then the attachments should have content-type
+"text/plain". However, attachments are generally frowned upon because
+it makes quoting portions of the patch more difficult in the patch
+review process.
+
+Email clients that are used for Linux kernel patches should send the
+patch text untouched. For example, they should not modify or delete tabs
+or spaces, even at the beginning or end of lines.
+
+Don't send patches with "format=flowed". This can cause unexpected
+and unwanted line breaks.
+
+Don't let your email client do automatic word wrapping for you.
+This can also corrupt your patch.
+
+Email clients should not modify the character set encoding of the text.
+Emailed patches should be in ASCII or UTF-8 encoding only.
+If you configure your email client to send emails with UTF-8 encoding,
+you avoid some possible charset problems.
+
+Email clients should generate and maintain References: or In-Reply-To:
+headers so that mail threading is not broken.
+
+Copy-and-paste (or cut-and-paste) usually does not work for patches
+because tabs are converted to spaces. Using xclipboard, xclip, and/or
+xcutsel may work, but it's best to test this for yourself or just avoid
+copy-and-paste.
+
+Don't use PGP/GPG signatures in mail that contains patches.
+This breaks many scripts that read and apply the patches.
+(This should be fixable.)
+
+It's a good idea to send a patch to yourself, save the received message,
+and successfully apply it with 'patch' before sending patches to Linux
+mailing lists.
+
+
+Some email client (MUA) hints
+----------------------------------------------------------------------
+Here are some specific MUA configuration hints for editing and sending
+patches for the Linux kernel. These are not meant to be complete
+software package configuration summaries.
+
+Legend:
+TUI = text-based user interface
+GUI = graphical user interface
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Alpine (TUI)
+
+Config options:
+In the "Sending Preferences" section:
+
+- "Do Not Send Flowed Text" must be enabled
+- "Strip Whitespace Before Sending" must be disabled
+
+When composing the message, the cursor should be placed where the patch
+should appear, and then pressing CTRL-R let you specify the patch file
+to insert into the message.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Evolution (GUI)
+
+Some people use this successfully for patches.
+
+When composing mail select: Preformat
+ from Format->Heading->Preformatted (Ctrl-7)
+ or the toolbar
+
+Then use:
+ Insert->Text File... (Alt-n x)
+to insert the patch.
+
+You can also "diff -Nru old.c new.c | xclip", select Preformat, then
+paste with the middle button.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Kmail (GUI)
+
+Some people use Kmail successfully for patches.
+
+The default setting of not composing in HTML is appropriate; do not
+enable it.
+
+When composing an email, under options, uncheck "word wrap". The only
+disadvantage is any text you type in the email will not be word-wrapped
+so you will have to manually word wrap text before the patch. The easiest
+way around this is to compose your email with word wrap enabled, then save
+it as a draft. Once you pull it up again from your drafts it is now hard
+word-wrapped and you can uncheck "word wrap" without losing the existing
+wrapping.
+
+At the bottom of your email, put the commonly-used patch delimiter before
+inserting your patch: three hyphens (---).
+
+Then from the "Message" menu item, select insert file and choose your patch.
+As an added bonus you can customise the message creation toolbar menu
+and put the "insert file" icon there.
+
+You can safely GPG sign attachments, but inlined text is preferred for
+patches so do not GPG sign them. Signing patches that have been inserted
+as inlined text will make them tricky to extract from their 7-bit encoding.
+
+If you absolutely must send patches as attachments instead of inlining
+them as text, right click on the attachment and select properties, and
+highlight "Suggest automatic display" to make the attachment inlined to
+make it more viewable.
+
+When saving patches that are sent as inlined text, select the email that
+contains the patch from the message list pane, right click and select
+"save as". You can use the whole email unmodified as a patch if it was
+properly composed. There is no option currently to save the email when you
+are actually viewing it in its own window -- there has been a request filed
+at kmail's bugzilla and hopefully this will be addressed. Emails are saved
+as read-write for user only so you will have to chmod them to make them
+group and world readable if you copy them elsewhere.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Lotus Notes (GUI)
+
+Run away from it.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Mutt (TUI)
+
+Plenty of Linux developers use mutt, so it must work pretty well.
+
+Mutt doesn't come with an editor, so whatever editor you use should be
+used in a way that there are no automatic linebreaks. Most editors have
+an "insert file" option that inserts the contents of a file unaltered.
+
+To use 'vim' with mutt:
+ set editor="vi"
+
+ If using xclip, type the command
+ :set paste
+ before middle button or shift-insert or use
+ :r filename
+
+if you want to include the patch inline.
+(a)ttach works fine without "set paste".
+
+Config options:
+It should work with default settings.
+However, it's a good idea to set the "send_charset" to:
+ set send_charset="us-ascii:utf-8"
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Pine (TUI)
+
+Pine has had some whitespace truncation issues in the past, but these
+should all be fixed now.
+
+Use alpine (pine's successor) if you can.
+
+Config options:
+- quell-flowed-text is needed for recent versions
+- the "no-strip-whitespace-before-send" option is needed
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Sylpheed (GUI)
+
+- Works well for inlining text (or using attachments).
+- Allows use of an external editor.
+- Not good for IMAP.
+- Is slow on large folders.
+- Won't do TLS SMTP auth over a non-SSL connection.
+- Has a helpful ruler bar in the compose window.
+- Adding addresses to address book doesn't understand the display name
+ properly.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Thunderbird (GUI)
+
+By default, thunderbird likes to mangle text, but there are ways to
+coerce it into being nice.
+
+- Under account settings, composition and addressing, uncheck "Compose
+ messages in HTML format".
+
+- Edit your Thunderbird config settings to tell it not to wrap lines:
+ user_pref("mailnews.wraplength", 0);
+
+- Edit your Thunderbird config settings so that it won't use format=flowed:
+ user_pref("mailnews.send_plaintext_flowed", false);
+
+- You need to get Thunderbird into preformat mode:
+. If you compose HTML messages by default, it's not too hard. Just select
+ "Preformat" from the drop-down box just under the subject line.
+. If you compose in text by default, you have to tell it to compose a new
+ message in HTML (just as a one-off), and then force it from there back to
+ text, else it will wrap lines. To do this, use shift-click on the Write
+ icon to compose to get HTML compose mode, then select "Preformat" from
+ the drop-down box just under the subject line.
+
+- Allows use of an external editor:
+ The easiest thing to do with Thunderbird and patches is to use an
+ "external editor" extension and then just use your favorite $EDITOR
+ for reading/merging patches into the body text. To do this, download
+ and install the extension, then add a button for it using
+ View->Toolbars->Customize... and finally just click on it when in the
+ Compose dialog.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+TkRat (GUI)
+
+Works. Use "Insert file..." or external editor.
+
+ ###
diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
index 92e89aeef52..caabbd395e6 100644
--- a/Documentation/fb/00-INDEX
+++ b/Documentation/fb/00-INDEX
@@ -5,21 +5,49 @@ please mail me.
00-INDEX
- this file
+arkfb.txt
+ - info on the fbdev driver for ARK Logic chips.
+aty128fb.txt
+ - info on the ATI Rage128 frame buffer driver.
+cirrusfb.txt
+ - info on the driver for Cirrus Logic chipsets.
+cyblafb/
+ - directory with documentation files related to the cyblafb driver.
+deferred_io.txt
+ - an introduction to deferred IO.
+fbcon.txt
+ - intro to and usage guide for the framebuffer console (fbcon).
framebuffer.txt
- - introduction to frame buffer devices
+ - introduction to frame buffer devices.
+imacfb.txt
+ - info on the generic EFI platform driver for Intel based Macs.
+intel810.txt
+ - documentation for the Intel 810/815 framebuffer driver.
+intelfb.txt
+ - docs for Intel 830M/845G/852GM/855GM/865G/915G/945G fb driver.
internals.txt
- - quick overview of frame buffer device internals
+ - quick overview of frame buffer device internals.
+matroxfb.txt
+ - info on the Matrox framebuffer driver for Alpha, Intel and PPC.
modedb.txt
- - info on the video mode database
-aty128fb.txt
- - info on the ATI Rage128 frame buffer driver
-clgenfb.txt
- - info on the Cirrus Logic frame buffer driver
+ - info on the video mode database.
matroxfb.txt
- - info on the Matrox frame buffer driver
+ - info on the Matrox frame buffer driver.
pvr2fb.txt
- - info on the PowerVR 2 frame buffer driver
+ - info on the PowerVR 2 frame buffer driver.
+pxafb.txt
+ - info on the driver for the PXA25x LCD controller.
+s3fb.txt
+ - info on the fbdev driver for S3 Trio/Virge chips.
+sa1100fb.txt
+ - information about the driver for the SA-1100 LCD controller.
+sisfb.txt
+ - info on the framebuffer device driver for various SiS chips.
+sstfb.txt
+ - info on the frame buffer driver for 3dfx' Voodoo Graphics boards.
tgafb.txt
- info on the TGA (DECChip 21030) frame buffer driver
vesafb.txt
- info on the VESA frame buffer device
+vt8623fb.txt
+ - info on the fb driver for the graphics core in VIA VT8623 chipsets.
diff --git a/Documentation/fb/uvesafb.txt b/Documentation/fb/uvesafb.txt
new file mode 100644
index 00000000000..bcfc233a008
--- /dev/null
+++ b/Documentation/fb/uvesafb.txt
@@ -0,0 +1,188 @@
+
+uvesafb - A Generic Driver for VBE2+ compliant video cards
+==========================================================
+
+1. Requirements
+---------------
+
+uvesafb should work with any video card that has a Video BIOS compliant
+with the VBE 2.0 standard.
+
+Unlike other drivers, uvesafb makes use of a userspace helper called
+v86d. v86d is used to run the x86 Video BIOS code in a simulated and
+controlled environment. This allows uvesafb to function on arches other
+than x86. Check the v86d documentation for a list of currently supported
+arches.
+
+v86d source code can be downloaded from the following website:
+ http://dev.gentoo.org/~spock/projects/uvesafb
+
+Please refer to the v86d documentation for detailed configuration and
+installation instructions.
+
+Note that the v86d userspace helper has to be available at all times in
+order for uvesafb to work properly. If you want to use uvesafb during
+early boot, you will have to include v86d into an initramfs image, and
+either compile it into the kernel or use it as an initrd.
+
+2. Caveats and limitations
+--------------------------
+
+uvesafb is a _generic_ driver which supports a wide variety of video
+cards, but which is ultimately limited by the Video BIOS interface.
+The most important limitations are:
+
+- Lack of any type of acceleration.
+- A strict and limited set of supported video modes. Often the native
+ or most optimal resolution/refresh rate for your setup will not work
+ with uvesafb, simply because the Video BIOS doesn't support the
+ video mode you want to use. This can be especially painful with
+ widescreen panels, where native video modes don't have the 4:3 aspect
+ ratio, which is what most BIOS-es are limited to.
+- Adjusting the refresh rate is only possible with a VBE 3.0 compliant
+ Video BIOS. Note that many nVidia Video BIOS-es claim to be VBE 3.0
+ compliant, while they simply ignore any refresh rate settings.
+
+3. Configuration
+----------------
+
+uvesafb can be compiled either as a module, or directly into the kernel.
+In both cases it supports the same set of configuration options, which
+are either given on the kernel command line or as module parameters, e.g.:
+
+ video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
+
+ # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap (module)
+
+Accepted options:
+
+ypan Enable display panning using the VESA protected mode
+ interface. The visible screen is just a window of the
+ video memory, console scrolling is done by changing the
+ start of the window. Available on x86 only.
+
+ywrap Same as ypan, but assumes your gfx board can wrap-around
+ the video memory (i.e. starts reading from top if it
+ reaches the end of video memory). Faster than ypan.
+ Available on x86 only.
+
+redraw Scroll by redrawing the affected part of the screen, this
+ is the safe (and slow) default.
+
+(If you're using uvesafb as a module, the above three options are
+ used a parameter of the scroll option, e.g. scroll=ypan.)
+
+vgapal Use the standard VGA registers for palette changes.
+
+pmipal Use the protected mode interface for palette changes.
+ This is the default if the protected mode interface is
+ available. Available on x86 only.
+
+mtrr:n Setup memory type range registers for the framebuffer
+ where n:
+ 0 - disabled (equivalent to nomtrr) (default)
+ 1 - uncachable
+ 2 - write-back
+ 3 - write-combining
+ 4 - write-through
+
+ If you see the following in dmesg, choose the type that matches
+ the old one. In this example, use "mtrr:2".
+...
+mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
+...
+
+nomtrr Do not use memory type range registers.
+
+vremap:n
+ Remap 'n' MiB of video RAM. If 0 or not specified, remap memory
+ according to video mode.
+
+vtotal:n
+ If the video BIOS of your card incorrectly determines the total
+ amount of video RAM, use this option to override the BIOS (in MiB).
+
+<mode> The mode you want to set, in the standard modedb format. Refer to
+ modedb.txt for a detailed description. When uvesafb is compiled as
+ a module, the mode string should be provided as a value of the
+ 'mode' option.
+
+vbemode:x
+ Force the use of VBE mode x. The mode will only be set if it's
+ found in the VBE-provided list of supported modes.
+ NOTE: The mode number 'x' should be specified in VESA mode number
+ notation, not the Linux kernel one (eg. 257 instead of 769).
+ HINT: If you use this option because normal <mode> parameter does
+ not work for you and you use a X server, you'll probably want to
+ set the 'nocrtc' option to ensure that the video mode is properly
+ restored after console <-> X switches.
+
+nocrtc Do not use CRTC timings while setting the video mode. This option
+ has any effect only if the Video BIOS is VBE 3.0 compliant. Use it
+ if you have problems with modes set the standard way. Note that
+ using this option implies that any refresh rate adjustments will
+ be ignored and the refresh rate will stay at your BIOS default (60 Hz).
+
+noedid Do not try to fetch and use EDID-provided modes.
+
+noblank Disable hardware blanking.
+
+v86d:path
+ Set path to the v86d executable. This option is only available as
+ a module parameter, and not as a part of the video= string. If you
+ need to use it and have uvesafb built into the kernel, use
+ uvesafb.v86d="path".
+
+Additionally, the following parameters may be provided. They all override the
+EDID-provided values and BIOS defaults. Refer to your monitor's specs to get
+the correct values for maxhf, maxvf and maxclk for your hardware.
+
+maxhf:n Maximum horizontal frequency (in kHz).
+maxvf:n Maximum vertical frequency (in Hz).
+maxclk:n Maximum pixel clock (in MHz).
+
+4. The sysfs interface
+----------------------
+
+uvesafb provides several sysfs nodes for configurable parameters and
+additional information.
+
+Driver attributes:
+
+/sys/bus/platform/drivers/uvesafb
+ - v86d (default: /sbin/v86d)
+ Path to the v86d executable. v86d is started by uvesafb
+ if an instance of the daemon isn't already running.
+
+Device attributes:
+
+/sys/bus/platform/drivers/uvesafb/uvesafb.0
+ - nocrtc
+ Use the default refresh rate (60 Hz) if set to 1.
+
+ - oem_product_name
+ - oem_product_rev
+ - oem_string
+ - oem_vendor
+ Information about the card and its maker.
+
+ - vbe_modes
+ A list of video modes supported by the Video BIOS along with their
+ VBE mode numbers in hex.
+
+ - vbe_version
+ A BCD value indicating the implemented VBE standard.
+
+5. Miscellaneous
+----------------
+
+Uvesafb will set a video mode with the default refresh rate and timings
+from the Video BIOS if you set pixclock to 0 in fb_var_screeninfo.
+
+
+--
+ Michal Januszewski <spock@gentoo.org>
+ Last updated: 2007-06-16
+
+ Documentation of the uvesafb options is loosely based on vesafb.txt.
+
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 63df2262d41..6b0f963f537 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -82,6 +82,52 @@ Who: Dominik Brodowski <linux@brodo.de>
---------------------------
+What: sys_sysctl
+When: September 2010
+Option: CONFIG_SYSCTL_SYSCALL
+Why: The same information is available in a more convenient from
+ /proc/sys, and none of the sysctl variables appear to be
+ important performance wise.
+
+ Binary sysctls are a long standing source of subtle kernel
+ bugs and security issues.
+
+ When I looked several months ago all I could find after
+ searching several distributions were 5 user space programs and
+ glibc (which falls back to /proc/sys) using this syscall.
+
+ The man page for sysctl(2) documents it as unusable for user
+ space programs.
+
+ sysctl(2) is not generally ABI compatible to a 32bit user
+ space application on a 64bit and a 32bit kernel.
+
+ For the last several months the policy has been no new binary
+ sysctls and no one has put forward an argument to use them.
+
+ Binary sysctls issues seem to keep happening appearing so
+ properly deprecating them (with a warning to user space) and a
+ 2 year grace warning period will mean eventually we can kill
+ them and end the pain.
+
+ In the mean time individual binary sysctls can be dealt with
+ in a piecewise fashion.
+
+Who: Eric Biederman <ebiederm@xmission.com>
+
+---------------------------
+
+What: a.out interpreter support for ELF executables
+When: 2.6.25
+Files: fs/binfmt_elf.c
+Why: Using a.out interpreters for ELF executables was a feature for
+ transition from a.out to ELF. But now it is unlikely to be still
+ needed anymore and removing it would simplify the hairy ELF
+ loader code.
+Who: Andi Kleen <ak@suse.de>
+
+---------------------------
+
What: remove EXPORT_SYMBOL(kernel_thread)
When: August 2006
Files: arch/*/kernel/*_ksyms.c
@@ -173,13 +219,6 @@ Who: Jean Delvare <khali@linux-fr.org>,
---------------------------
-What: drivers depending on OBSOLETE_OSS
-When: options in 2.6.22, code in 2.6.24
-Why: OSS drivers with ALSA replacements
-Who: Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
What: ACPI procfs interface
When: July 2008
Why: ACPI sysfs conversion should be finished by January 2008.
@@ -205,20 +244,6 @@ Who: Len Brown <len.brown@intel.com>
---------------------------
-What: Compaq touchscreen device emulation
-When: Oct 2007
-Files: drivers/input/tsdev.c
-Why: The code says it was obsolete when it was written in 2001.
- tslib is a userspace library which does anything tsdev can do and
- much more besides in userspace where this code belongs. There is no
- longer any need for tsdev and applications should have converted to
- use tslib by now.
- The name "tsdev" is also extremely confusing and lots of people have
- it loaded when they don't need/use it.
-Who: Richard Purdie <rpurdie@rpsys.net>
-
----------------------------
-
What: i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
When: September 2007
Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index 59db1bca702..1de155e2dc3 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -44,14 +44,24 @@ files.txt
- info on file management in the Linux kernel.
fuse.txt
- info on the Filesystem in User SpacE including mount options.
+gfs2.txt
+ - info on the Global File System 2.
hfs.txt
- info on the Macintosh HFS Filesystem for Linux.
+hfsplus.txt
+ - info on the Macintosh HFSPlus Filesystem for Linux.
hpfs.txt
- info and mount options for the OS/2 HPFS.
+inotify.txt
+ - info on the powerful yet simple file change notification system.
isofs.txt
- info and mount options for the ISO 9660 (CDROM) filesystem.
jfs.txt
- info and mount options for the JFS filesystem.
+locks.txt
+ - info on file locking implementations, flock() vs. fcntl(), etc.
+mandatory-locking.txt
+ - info on the Linux implementation of Sys V mandatory file locking.
ncpfs.txt
- info on Novell Netware(tm) filesystem using NCP protocol.
ntfs.txt
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index cda6905cbe4..d6fd6c6e424 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -35,12 +35,12 @@ For remote file server:
For Plan 9 From User Space applications (http://swtch.com/plan9)
- mount -t 9p `namespace`/acme /mnt/9 -o proto=unix,uname=$USER
+ mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER
OPTIONS
=======
- proto=name select an alternative transport. Valid options are
+ trans=name select an alternative transport. Valid options are
currently:
unix - specifying a named pipe mount point
tcp - specifying a normal TCP/IP connection
@@ -68,9 +68,9 @@ OPTIONS
0x40 = display transport debug
0x80 = display allocation debug
- rfdno=n the file descriptor for reading with proto=fd
+ rfdno=n the file descriptor for reading with trans=fd
- wfdno=n the file descriptor for writing with proto=fd
+ wfdno=n the file descriptor for writing with trans=fd
maxdata=n the number of bytes to use for 9p packet payload (msize)
@@ -78,9 +78,9 @@ OPTIONS
noextend force legacy mode (no 9p2000.u semantics)
- uid attempt to mount as a particular uid
+ dfltuid attempt to mount as a particular uid
- gid attempt to mount with a particular gid
+ dfltgid attempt to mount with a particular gid
afid security channel - used by Plan 9 authentication protocols
@@ -88,6 +88,16 @@ OPTIONS
This can be used to share devices/named pipes/sockets between
hosts. This functionality will be expanded in later versions.
+ access there are three access modes.
+ user = if a user tries to access a file on v9fs
+ filesystem for the first time, v9fs sends an
+ attach command (Tattach) for that user.
+ This is the default mode.
+ <uid> = allows only user with uid=<uid> to access
+ the files on the mounted filesystem
+ any = v9fs does single attach and performs all
+ operations as one user
+
RESOURCES
=========
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index f0f825808ca..fe26cc97852 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -178,15 +178,18 @@ prototypes:
locking rules:
All except set_page_dirty may block
- BKL PageLocked(page)
+ BKL PageLocked(page) i_sem
writepage: no yes, unlocks (see below)
readpage: no yes, unlocks
sync_page: no maybe
writepages: no
set_page_dirty no no
readpages: no
-prepare_write: no yes
-commit_write: no yes
+prepare_write: no yes yes
+commit_write: no yes yes
+write_begin: no locks the page yes
+write_end: no yes, unlocks yes
+perform_write: no n/a yes
bmap: yes
invalidatepage: no yes
releasepage: no yes
diff --git a/Documentation/locks.txt b/Documentation/filesystems/locks.txt
index e3b402ef33b..fab857accbd 100644
--- a/Documentation/locks.txt
+++ b/Documentation/filesystems/locks.txt
@@ -53,11 +53,11 @@ fcntl(), with all the problems that implies.
1.3 Mandatory Locking As A Mount Option
---------------------------------------
-Mandatory locking, as described in 'Documentation/mandatory.txt' was prior
-to this release a general configuration option that was valid for all
-mounted filesystems. This had a number of inherent dangers, not the least
-of which was the ability to freeze an NFS server by asking it to read a
-file for which a mandatory lock existed.
+Mandatory locking, as described in 'Documentation/filesystems/mandatory.txt'
+was prior to this release a general configuration option that was valid for
+all mounted filesystems. This had a number of inherent dangers, not the
+least of which was the ability to freeze an NFS server by asking it to read
+a file for which a mandatory lock existed.
From this release of the kernel, mandatory locking can be turned on and off
on a per-filesystem basis, using the mount options 'mand' and 'nomand'.
diff --git a/Documentation/mandatory.txt b/Documentation/filesystems/mandatory-locking.txt
index bc449d49eee..0979d1d2ca8 100644
--- a/Documentation/mandatory.txt
+++ b/Documentation/filesystems/mandatory-locking.txt
@@ -3,7 +3,26 @@
Andy Walker <andy@lysaker.kvaerner.no>
15 April 1996
-
+ (Updated September 2007)
+
+0. Why you should avoid mandatory locking
+-----------------------------------------
+
+The Linux implementation is prey to a number of difficult-to-fix race
+conditions which in practice make it not dependable:
+
+ - The write system call checks for a mandatory lock only once
+ at its start. It is therefore possible for a lock request to
+ be granted after this check but before the data is modified.
+ A process may then see file data change even while a mandatory
+ lock was held.
+ - Similarly, an exclusive lock may be granted on a file after
+ the kernel has decided to proceed with a read, but before the
+ read has actually completed, and the reading process may see
+ the file data in a state which should not have been visible
+ to it.
+ - Similar races make the claimed mutual exclusion between lock
+ and mmap similarly unreliable.
1. What is mandatory locking?
------------------------------
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 4a37e25e694..e5c1df52a87 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -347,7 +347,35 @@ connects the CPUs in a SMP system. This means that an error has been detected,
the IO-APIC automatically retry the transmission, so it should not be a big
problem, but you should read the SMP-FAQ.
-In this context it could be interesting to note the new irq directory in 2.4.
+In 2.6.2* /proc/interrupts was expanded again. This time the goal was for
+/proc/interrupts to display every IRQ vector in use by the system, not
+just those considered 'most important'. The new vectors are:
+
+ THR -- interrupt raised when a machine check threshold counter
+ (typically counting ECC corrected errors of memory or cache) exceeds
+ a configurable threshold. Only available on some systems.
+
+ TRM -- a thermal event interrupt occurs when a temperature threshold
+ has been exceeded for the CPU. This interrupt may also be generated
+ when the temperature drops back to normal.
+
+ SPU -- a spurious interrupt is some interrupt that was raised then lowered
+ by some IO device before it could be fully processed by the APIC. Hence
+ the APIC sees the interrupt but does not know what device it came from.
+ For this case the APIC will generate the interrupt with a IRQ vector
+ of 0xff. This might also be generated by chipset bugs.
+
+ RES, CAL, TLB -- rescheduling, call and TLB flush interrupts are
+ sent from one CPU to another per the needs of the OS. Typically,
+ their statistics are used by kernel developers and interested users to
+ determine the occurance of interrupt of the given type.
+
+The above IRQ vectors are displayed only when relevent. For example,
+the threshold vector does not exist on x86_64 platforms. Others are
+suppressed when the system is a uniprocessor. As of this writing, only
+i386 and x86_64 platforms support the new IRQ vector displays.
+
+Of some interest is the introduction of the /proc/irq directory to 2.4.
It could be used to set IRQ to CPU affinity, this means that you can "hook" an
IRQ to only one CPU, or to exclude a CPU of handling IRQs. The contents of the
irq subdir is one subdir for each IRQ, and one file; prof_cpu_mask
diff --git a/Documentation/filesystems/quota.txt b/Documentation/filesystems/quota.txt
new file mode 100644
index 00000000000..a590c4093ef
--- /dev/null
+++ b/Documentation/filesystems/quota.txt
@@ -0,0 +1,59 @@
+
+Quota subsystem
+===============
+
+Quota subsystem allows system administrator to set limits on used space and
+number of used inodes (inode is a filesystem structure which is associated
+with each file or directory) for users and/or groups. For both used space and
+number of used inodes there are actually two limits. The first one is called
+softlimit and the second one hardlimit. An user can never exceed a hardlimit
+for any resource. User is allowed to exceed softlimit but only for limited
+period of time. This period is called "grace period" or "grace time". When
+grace time is over, user is not able to allocate more space/inodes until he
+frees enough of them to get below softlimit.
+
+Quota limits (and amount of grace time) are set independently for each
+filesystem.
+
+For more details about quota design, see the documentation in quota-tools package
+(http://sourceforge.net/projects/linuxquota).
+
+Quota netlink interface
+=======================
+When user exceeds a softlimit, runs out of grace time or reaches hardlimit,
+quota subsystem traditionally printed a message to the controlling terminal of
+the process which caused the excess. This method has the disadvantage that
+when user is using a graphical desktop he usually cannot see the message.
+Thus quota netlink interface has been designed to pass information about
+the above events to userspace. There they can be captured by an application
+and processed accordingly.
+
+The interface uses generic netlink framework (see
+http://lwn.net/Articles/208755/ and http://people.suug.ch/~tgr/libnl/ for more
+details about this layer). The name of the quota generic netlink interface
+is "VFS_DQUOT". Definitions of constants below are in <linux/quota.h>.
+ Currently, the interface supports only one message type QUOTA_NL_C_WARNING.
+This command is used to send a notification about any of the above mentioned
+events. Each message has six attributes. These are (type of the argument is
+in parentheses):
+ QUOTA_NL_A_QTYPE (u32)
+ - type of quota being exceeded (one of USRQUOTA, GRPQUOTA)
+ QUOTA_NL_A_EXCESS_ID (u64)
+ - UID/GID (depends on quota type) of user / group whose limit
+ is being exceeded.
+ QUOTA_NL_A_CAUSED_ID (u64)
+ - UID of a user who caused the event
+ QUOTA_NL_A_WARNING (u32)
+ - what kind of limit is exceeded:
+ QUOTA_NL_IHARDWARN - inode hardlimit
+ QUOTA_NL_ISOFTLONGWARN - inode softlimit is exceeded longer
+ than given grace period
+ QUOTA_NL_ISOFTWARN - inode softlimit
+ QUOTA_NL_BHARDWARN - space (block) hardlimit
+ QUOTA_NL_BSOFTLONGWARN - space (block) softlimit is exceeded
+ longer than given grace period.
+ QUOTA_NL_BSOFTWARN - space (block) softlimit
+ QUOTA_NL_A_DEV_MAJOR (u32)
+ - major number of a device with the affected filesystem
+ QUOTA_NL_A_DEV_MINOR (u32)
+ - minor number of a device with the affected filesystem
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
index 25981e2e51b..339c6a4f220 100644
--- a/Documentation/filesystems/ramfs-rootfs-initramfs.txt
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -8,7 +8,7 @@ What is ramfs?
Ramfs is a very simple filesystem that exports Linux's disk caching
mechanisms (the page cache and dentry cache) as a dynamically resizable
-ram-based filesystem.
+RAM-based filesystem.
Normally all files are cached in memory by Linux. Pages of data read from
backing store (usually the block device the filesystem is mounted on) are kept
@@ -34,7 +34,7 @@ ramfs and ramdisk:
------------------
The older "ram disk" mechanism created a synthetic block device out of
-an area of ram and used it as backing store for a filesystem. This block
+an area of RAM and used it as backing store for a filesystem. This block
device was of fixed size, so the filesystem mounted on it was of fixed
size. Using a ram disk also required unnecessarily copying memory from the
fake block device into the page cache (and copying changes back out), as well
@@ -46,8 +46,8 @@ unnecessary work for the CPU, and pollutes the CPU caches. (There are tricks
to avoid this copying by playing with the page tables, but they're unpleasantly
complicated and turn out to be about as expensive as the copying anyway.)
More to the point, all the work ramfs is doing has to happen _anyway_,
-since all file access goes through the page and dentry caches. The ram
-disk is simply unnecessary, ramfs is internally much simpler.
+since all file access goes through the page and dentry caches. The RAM
+disk is simply unnecessary; ramfs is internally much simpler.
Another reason ramdisks are semi-obsolete is that the introduction of
loopback devices offered a more flexible and convenient way to create
@@ -103,7 +103,7 @@ All this differs from the old initrd in several ways:
initramfs archive is a gzipped cpio archive (like tar only simpler,
see cpio(1) and Documentation/early-userspace/buffer-format.txt). The
kernel's cpio extraction code is not only extremely small, it's also
- __init data that can be discarded during the boot process.
+ __init text and data that can be discarded during the boot process.
- The program run by the old initrd (which was called /initrd, not /init) did
some setup and then returned to the kernel, while the init program from
@@ -220,7 +220,7 @@ device) but the separate packaging of initrd (which is nice if you have
non-GPL code you'd like to run from initramfs, without conflating it with
the GPL licensed Linux kernel binary).
-It can also be used to supplement the kernel's built-in initamfs image. The
+It can also be used to supplement the kernel's built-in initramfs image. The
files in the external archive will overwrite any conflicting files in
the built-in initramfs archive. Some distributors also prefer to customize
a single kernel image with task-specific initramfs images, without recompiling.
@@ -339,7 +339,7 @@ smooth transition and allowing early boot functionality to gradually move to
The move to early userspace is necessary because finding and mounting the real
root device is complex. Root partitions can span multiple devices (raid or
separate journal). They can be out on the network (requiring dhcp, setting a
-specific mac address, logging into a server, etc). They can live on removable
+specific MAC address, logging into a server, etc). They can live on removable
media, with dynamically allocated major/minor numbers and persistent naming
issues requiring a full udev implementation to sort out. They can be
compressed, encrypted, copy-on-write, loopback mounted, strangely partitioned,
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 045f3e055a2..6f8e16e3d6c 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -537,6 +537,12 @@ struct address_space_operations {
struct list_head *pages, unsigned nr_pages);
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
+ int (*write_begin)(struct file *, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
+ int (*write_end)(struct file *, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata);
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
@@ -615,11 +621,7 @@ struct address_space_operations {
any basic-blocks on storage, then those blocks should be
pre-read (if they haven't been read already) so that the
updated blocks can be written out properly.
- The page will be locked. If prepare_write wants to unlock the
- page it, like readpage, may do so and return
- AOP_TRUNCATED_PAGE.
- In this case the prepare_write will be retried one the lock is
- regained.
+ The page will be locked.
Note: the page _must not_ be marked uptodate in this function
(or anywhere else) unless it actually is uptodate right now. As
@@ -633,6 +635,45 @@ struct address_space_operations {
operations. It should avoid returning an error if possible -
errors should have been handled by prepare_write.
+ write_begin: This is intended as a replacement for prepare_write. The
+ key differences being that:
+ - it returns a locked page (in *pagep) rather than being
+ given a pre locked page;
+ - it must be able to cope with short writes (where the
+ length passed to write_begin is greater than the number
+ of bytes copied into the page).
+
+ Called by the generic buffered write code to ask the filesystem to
+ prepare to write len bytes at the given offset in the file. The
+ address_space should check that the write will be able to complete,
+ by allocating space if necessary and doing any other internal
+ housekeeping. If the write will update parts of any basic-blocks on
+ storage, then those blocks should be pre-read (if they haven't been
+ read already) so that the updated blocks can be written out properly.
+
+ The filesystem must return the locked pagecache page for the specified
+ offset, in *pagep, for the caller to write into.
+
+ flags is a field for AOP_FLAG_xxx flags, described in
+ include/linux/fs.h.
+
+ A void * may be returned in fsdata, which then gets passed into
+ write_end.
+
+ Returns 0 on success; < 0 on failure (which is the error code), in
+ which case write_end is not called.
+
+ write_end: After a successful write_begin, and data copy, write_end must
+ be called. len is the original len passed to write_begin, and copied
+ is the amount that was able to be copied (copied == len is always true
+ if write_begin was called with the AOP_FLAG_UNINTERRUPTIBLE flag).
+
+ The filesystem must take care of unlocking the page and releasing it
+ refcount, and updating i_size.
+
+ Returns < 0 on failure, otherwise the number of bytes (<= 'copied')
+ that were able to be copied into pagecache.
+
bmap: called by the VFS to map a logical block offset within object to
physical block number. This method is used by the FIBMAP
ioctl and for working with swap-files. To be able to swap to
diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c
index fba943aacf9..2de62854f0e 100644
--- a/Documentation/firmware_class/firmware_sample_firmware_class.c
+++ b/Documentation/firmware_class/firmware_sample_firmware_class.c
@@ -109,15 +109,15 @@ static int fw_setup_class_device(struct class_device *class_dev,
const char *fw_name,
struct device *device)
{
- int retval = 0;
- struct firmware_priv *fw_priv = kmalloc(sizeof(struct firmware_priv),
- GFP_KERNEL);
+ int retval;
+ struct firmware_priv *fw_priv;
- if(!fw_priv){
+ fw_priv = kzalloc(sizeof(struct firmware_priv), GFP_KERNEL);
+ if (!fw_priv) {
retval = -ENOMEM;
goto out;
}
- memset(fw_priv, 0, sizeof(*fw_priv));
+
memset(class_dev, 0, sizeof(*class_dev));
strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX);
diff --git a/Documentation/ide.txt b/Documentation/ide.txt
index 3bb9f9c9861..1d50f23a5ca 100644
--- a/Documentation/ide.txt
+++ b/Documentation/ide.txt
@@ -242,6 +242,8 @@ Summary of ide driver parameters for kernel command line
and quite likely to cause trouble with
older/odd IDE drives.
+ "hdx=nodma" : disallow DMA
+
"hdx=swapdata" : when the drive is a disk, byte swap all data
"hdx=bswap" : same as above..........
@@ -278,8 +280,6 @@ Summary of ide driver parameters for kernel command line
"idex=four" : four drives on idex and ide(x^1) share same ports
"idex=reset" : reset interface after probe
-
- "idex=dma" : automatically configure/use DMA if possible.
"idex=ata66" : informs the interface that it has an 80c cable
for chipsets that are ATA-66 capable, but the
@@ -288,8 +288,6 @@ Summary of ide driver parameters for kernel command line
"ide=reverse" : formerly called to pci sub-system, but now local.
- "ide=nodma" : disable DMA globally for the IDE subsystem.
-
The following are valid ONLY on ide0, which usually corresponds
to the first ATA interface found on the particular host, and the defaults for
the base,ctl ports must not be altered.
diff --git a/Documentation/initrd.txt b/Documentation/initrd.txt
index d3dc505104d..74f68b35f7c 100644
--- a/Documentation/initrd.txt
+++ b/Documentation/initrd.txt
@@ -80,8 +80,8 @@ Compressed cpio images
----------------------
Recent kernels have support for populating a ramdisk from a compressed cpio
-archive, on such systems, the creation of a ramdisk image doesn't need to
-involve special block devices or loopbacks, you merely create a directory on
+archive. On such systems, the creation of a ramdisk image doesn't need to
+involve special block devices or loopbacks; you merely create a directory on
disk with the desired initrd content, cd to that directory, and run (as an
example):
@@ -293,7 +293,7 @@ information as small as possible. In this case, a common initrd could be
generated with all the necessary modules. Then, only /sbin/init or a file
read by it would have to be different.
-A third scenario are more convenient recovery disks, because information
+A third scenario is more convenient recovery disks, because information
like the location of the root FS partition doesn't have to be provided at
boot time, but the system loaded from initrd can invoke a user-friendly
dialog and it can also perform some sanity checks (or even some form of
@@ -339,8 +339,8 @@ the new, supported mechanism is called "pivot_root".
Mixed change_root and pivot_root mechanism
------------------------------------------
-In case you did not want to use root=/dev/ram0 to trig the pivot_root mechanism,
-you may create both /linuxrc and /sbin/init in your initrd image.
+In case you did not want to use root=/dev/ram0 to trigger the pivot_root
+mechanism, you may create both /linuxrc and /sbin/init in your initrd image.
/linuxrc would contain only the following:
@@ -350,7 +350,7 @@ echo 0x0100 >/proc/sys/kernel/real-root-dev
umount -n /proc
Once linuxrc exited, the kernel would mount again your initrd as root,
-this time executing /sbin/init. Again, it would be duty of this init
+this time executing /sbin/init. Again, it would be the duty of this init
to build the right environment (maybe using the root= device passed on
the cmdline) before the final execution of the real /sbin/init.
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index e08ef8759a0..f099b814d38 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -276,41 +276,39 @@ more details, with real examples.
--- 3.7 Compilation flags
- EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS
+ ccflags-y, asflags-y and ldflags-y
+ The three flags listed above applies only to the kbuild makefile
+ where they are assigned. They are used for all the normal
+ cc, as and ld invocation happenign during a recursive build.
+ Note: Flags with the same behaviour were previously named:
+ EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.
+ They are yet supported but their use are deprecated.
- All the EXTRA_ variables apply only to the kbuild makefile
- where they are assigned. The EXTRA_ variables apply to all
- commands executed in the kbuild makefile.
-
- $(EXTRA_CFLAGS) specifies options for compiling C files with
- $(CC).
+ ccflags-y specifies options for compiling C files with $(CC).
Example:
# drivers/sound/emu10k1/Makefile
- EXTRA_CFLAGS += -I$(obj)
- ifdef DEBUG
- EXTRA_CFLAGS += -DEMU10K1_DEBUG
- endif
+ ccflags-y += -I$(obj)
+ ccflags-$(DEBUG) += -DEMU10K1_DEBUG
This variable is necessary because the top Makefile owns the
- variable $(CFLAGS) and uses it for compilation flags for the
+ variable $(KBUILD_CFLAGS) and uses it for compilation flags for the
entire tree.
- $(EXTRA_AFLAGS) is a similar string for per-directory options
+ asflags-y is a similar string for per-directory options
when compiling assembly language source.
Example:
#arch/x86_64/kernel/Makefile
- EXTRA_AFLAGS := -traditional
+ asflags-y := -traditional
- $(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for
- per-directory options to $(LD) and $(AR).
+ ldflags-y is a string for per-directory options to $(LD).
Example:
#arch/m68k/fpsp040/Makefile
- EXTRA_LDFLAGS := -x
+ ldflags-y := -x
CFLAGS_$@, AFLAGS_$@
@@ -425,6 +423,7 @@ more details, with real examples.
as-instr checks if the assembler reports a specific instruction
and then outputs either option1 or option2
C escapes are supported in the test instruction
+ Note: as-instr-option uses KBUILD_AFLAGS for $(AS) options
cc-option
cc-option is used to check if $(CC) supports a given option, and not
@@ -438,6 +437,7 @@ more details, with real examples.
-march=pentium-mmx if supported by $(CC), otherwise -march=i586.
The second argument to cc-option is optional, and if omitted,
cflags-y will be assigned no value if first option is not supported.
+ Note: cc-option uses KBUILD_CFLAGS for $(CC) options
cc-option-yn
cc-option-yn is used to check if gcc supports a given option
@@ -453,6 +453,7 @@ more details, with real examples.
option. When $(biarch) equals 'y', the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32,
respectively.
+ Note: cc-option-yn uses KBUILD_CFLAGS for $(CC) options
cc-option-align
gcc versions >= 3.0 changed the type of options used to specify
@@ -464,10 +465,11 @@ more details, with real examples.
cc-option-align = -falign
Example:
- CFLAGS += $(cc-option-align)-functions=4
+ KBUILD_CFLAGS += $(cc-option-align)-functions=4
In the above example, the option -falign-functions=4 is used for
gcc >= 3.00. For gcc < 3.00, -malign-functions=4 is used.
+ Note: cc-option-align uses KBUILD_CFLAGS for $(CC) options
cc-version
cc-version returns a numerical version of the $(CC) compiler version.
@@ -492,9 +494,9 @@ more details, with real examples.
Example:
#fs/reiserfs/Makefile
- EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1)
+ ccflags-y := $(call cc-ifversion, -lt, 0402, -O1)
- In this example, EXTRA_CFLAGS will be assigned the value -O1 if the
+ In this example, ccflags-y will be assigned the value -O1 if the
$(CC) version is less than 4.2.
cc-ifversion takes all the shell operators:
-eq, -ne, -lt, -le, -gt, and -ge
@@ -780,8 +782,8 @@ When kbuild executes, the following steps are followed (roughly):
Example:
#arch/s390/Makefile
LDFLAGS := -m elf_s390
- Note: EXTRA_LDFLAGS and LDFLAGS_$@ can be used to further customise
- the flags used. See chapter 7.
+ Note: ldflags-y can be used to further customise
+ the flags used. See chapter 3.7.
LDFLAGS_MODULE Options for $(LD) when linking modules
@@ -817,26 +819,26 @@ When kbuild executes, the following steps are followed (roughly):
In this example, the binary $(obj)/image is a binary version of
vmlinux. The usage of $(call if_changed,xxx) will be described later.
- AFLAGS $(AS) assembler flags
+ KBUILD_AFLAGS $(AS) assembler flags
Default value - see top level Makefile
Append or modify as required per architecture.
Example:
#arch/sparc64/Makefile
- AFLAGS += -m64 -mcpu=ultrasparc
+ KBUILD_AFLAGS += -m64 -mcpu=ultrasparc
- CFLAGS $(CC) compiler flags
+ KBUILD_CFLAGS $(CC) compiler flags
Default value - see top level Makefile
Append or modify as required per architecture.
- Often, the CFLAGS variable depends on the configuration.
+ Often, the KBUILD_CFLAGS variable depends on the configuration.
Example:
#arch/i386/Makefile
cflags-$(CONFIG_M386) += -march=i386
- CFLAGS += $(cflags-y)
+ KBUILD_CFLAGS += $(cflags-y)
Many arch Makefiles dynamically run the target C compiler to
probe supported options:
@@ -848,7 +850,7 @@ When kbuild executes, the following steps are followed (roughly):
-march=pentium2,-march=i686)
...
# Disable unit-at-a-time mode ...
- CFLAGS += $(call cc-option,-fno-unit-at-a-time)
+ KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time)
...
@@ -1096,8 +1098,8 @@ When kbuild executes, the following steps are followed (roughly):
specified options when building the target vmlinux.lds.
When building the *.lds target, kbuild uses the variables:
- CPPFLAGS : Set in top-level Makefile
- EXTRA_CPPFLAGS : May be set in the kbuild makefile
+ KBUILD_CPPFLAGS : Set in top-level Makefile
+ cppflags-y : May be set in the kbuild makefile
CPPFLAGS_$(@F) : Target specific flags.
Note that the full filename is used in this
assignment.
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 2fedc081b4c..1b37b28cc23 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -13,7 +13,7 @@ dump of the system kernel's memory needs to be taken (for example, when
the system panics). The system kernel's memory image is preserved across
the reboot and is accessible to the dump-capture kernel.
-You can use common Linux commands, such as cp and scp, to copy the
+You can use common commands, such as cp and scp, to copy the
memory image to a dump file on the local disk, or across the network to
a remote system.
@@ -69,7 +69,7 @@ http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-test
This is a symlink to the latest version, which at the time of writing is
20061214, the only release of kexec-tools-testing so far. As other versions
-are made released, the older onese will remain available at
+are released, the older ones will remain available at
http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
Note: Latest kexec-tools-testing git tree is available at
@@ -159,16 +159,17 @@ Dump-capture kernel config options (Arch Independent)
CONFIG_PROC_VMCORE=y
(CONFIG_PROC_VMCORE is set by default when CONFIG_CRASH_DUMP is selected.)
-Dump-capture kernel config options (Arch Dependent, i386)
---------------------------------------------------------
-1) On x86, enable high memory support under "Processor type and
+Dump-capture kernel config options (Arch Dependent, i386 and x86_64)
+--------------------------------------------------------------------
+
+1) On i386, enable high memory support under "Processor type and
features":
CONFIG_HIGHMEM64G=y
or
CONFIG_HIGHMEM4G
-2) On x86 and x86_64, disable symmetric multi-processing support
+2) On i386 and x86_64, disable symmetric multi-processing support
under "Processor type and features":
CONFIG_SMP=n
@@ -203,28 +204,6 @@ Dump-capture kernel config options (Arch Dependent, i386)
5) Make and install the kernel and its modules. DO NOT add this kernel
to the boot loader configuration files.
-Dump-capture kernel config options (Arch Dependent, x86_64)
-----------------------------------------------------------
-1) On x86 and x86_64, disable symmetric multi-processing support
- under "Processor type and features":
-
- CONFIG_SMP=n
-
- (If CONFIG_SMP=y, then specify maxcpus=1 on the kernel command line
- when loading the dump-capture kernel, see section "Load the Dump-capture
- Kernel".)
-
-2) Use a suitable value for "Physical address where the kernel is
- loaded" (under "Processor type and features"). This only appears when
- "kernel crash dumps" is enabled. By default this value is 0x1000000
- (16MB). It should be the same as X in the "crashkernel=Y@X" boot
- parameter.
-
- For x86_64, normally "CONFIG_PHYSICAL_START=0x1000000".
-
-3) Make and install the kernel and its modules. DO NOT add this kernel
- to the boot loader configuration files.
-
Dump-capture kernel config options (Arch Dependent, ppc64)
----------------------------------------------------------
@@ -282,11 +261,9 @@ Based on the architecture and type of image (relocatable or not), one
can choose to load the uncompressed vmlinux or compressed bzImage/vmlinuz
of dump-capture kernel. Following is the summary.
-For i386:
+For i386 and x86_64:
- Use vmlinux if kernel is not relocatable.
- Use bzImage/vmlinuz if kernel is relocatable.
-For x86_64:
- - Use vmlinux
For ppc64:
- Use vmlinux
For ia64:
@@ -315,20 +292,22 @@ Following are the arch specific command line options to be used while
loading dump-capture kernel.
For i386, x86_64 and ia64:
- "1 irqpoll maxcpus=1"
+ "1 irqpoll maxcpus=1 reset_devices"
For ppc64:
- "1 maxcpus=1 noirqdistrib"
+ "1 maxcpus=1 noirqdistrib reset_devices"
Notes on loading the dump-capture kernel:
* By default, the ELF headers are stored in ELF64 format to support
- systems with more than 4GB memory. The --elf32-core-headers option can
- be used to force the generation of ELF32 headers. This is necessary
- because GDB currently cannot open vmcore files with ELF64 headers on
- 32-bit systems. ELF32 headers can be used on non-PAE systems (that is,
- less than 4GB of memory).
+ systems with more than 4GB memory. On i386, kexec automatically checks if
+ the physical RAM size exceeds the 4 GB limit and if not, uses ELF32.
+ So, on non-PAE systems, ELF32 is always used.
+
+ The --elf32-core-headers option can be used to force the generation of ELF32
+ headers. This is necessary because GDB currently cannot open vmcore files
+ with ELF64 headers on 32-bit systems.
* The "irqpoll" boot parameter reduces driver initialization failures
due to shared interrupts in the dump-capture kernel.
@@ -360,7 +339,7 @@ If die() is called, and it happens to be a thread with pid 0 or 1, or die()
is called inside interrupt context or die() is called and panic_on_oops is set,
the system will boot into the dump-capture kernel.
-On powererpc systems when a soft-reset is generated, die() is called by all cpus
+On powerpc systems when a soft-reset is generated, die() is called by all cpus
and the system will boot into the dump-capture kernel.
For testing purposes, you can trigger a crash by using "ALT-SysRq-c",
@@ -426,9 +405,3 @@ Contact
Vivek Goyal (vgoyal@in.ibm.com)
Maneesh Soni (maneesh@in.ibm.com)
-
-Trademark
-=========
-
-Linux is a trademark of Linus Torvalds in the United States, other
-countries, or both.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c323778270f..189df0bcab9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -75,10 +75,12 @@ parameter is applicable:
PPT Parallel port support is enabled.
PS2 Appropriate PS/2 support is enabled.
RAM RAM disk support is enabled.
+ ROOTPLUG The example Root Plug LSM is enabled.
S390 S390 architecture is enabled.
SCSI Appropriate SCSI support is enabled.
A lot of drivers has their options described inside of
Documentation/scsi/.
+ SECURITY Different security models are enabled.
SELINUX SELinux support is enabled.
SERIAL Serial support is enabled.
SH SuperH architecture is enabled.
@@ -349,6 +351,11 @@ and is between 256 and 4096 characters. It is defined in the file
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).
+ Format: integer
+
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
bttv.radio= Most important insmod options are available as
kernel args too.
@@ -368,6 +375,12 @@ and is between 256 and 4096 characters. It is defined in the file
possible to determine what the correct size should be.
This option provides an override for these situations.
+ capability.disable=
+ [SECURITY] Disable capabilities. This would normally
+ be used only if an alternative security model is to be
+ configured. Potentially dangerous and should only be
+ used if you are entirely sure of the consequences.
+
chandev= [HW,NET] Generic channel device initialisation
checkreqprot [SELINUX] Set initial checkreqprot flag value.
@@ -466,6 +479,16 @@ and is between 256 and 4096 characters. It is defined in the file
UART at the specified I/O port or MMIO address.
The options are the same as for ttyS, above.
+ no_console_suspend
+ [HW] Never suspend the console
+ Disable suspending of consoles during suspend and
+ hibernate operations. Once disabled, debugging
+ messages can reach various consoles while the rest
+ of the system is being put to sleep (ie, while
+ debugging driver suspend/resume hooks). This may
+ not work reliably with all consoles, but is known
+ to work with serial and VGA consoles.
+
cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
Format:
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
@@ -906,6 +929,11 @@ and is between 256 and 4096 characters. It is defined in the file
n must be a power of two. The default size
is set in the kernel config file.
+ logo.nologo [FB] Disables display of the built-in Linux logo.
+ This may be used to provide more screen space for
+ kernel log messages and is useful when debugging
+ kernel boot problems.
+
lp=0 [LP] Specify parallel ports to use, e.g,
lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses
lp=reset first parallel port). 'lp=0' disables the
@@ -976,6 +1004,8 @@ and is between 256 and 4096 characters. It is defined in the file
mce [X86-32] Machine Check Exception
+ mce=option [X86-64] See Documentation/x86_64/boot-options.txt
+
md= [HW] RAID subsystems devices and level
See Documentation/md.txt.
@@ -1083,6 +1113,13 @@ and is between 256 and 4096 characters. It is defined in the file
[NFS] set the maximum lifetime for idmapper cache
entries.
+ nfs.enable_ino64=
+ [NFS] enable 64-bit inode numbers.
+ If zero, the NFS client will fake up a 32-bit inode
+ number for the readdir() and stat() syscalls instead
+ of returning the full 64-bit number.
+ The default is to return 64-bit inode numbers.
+
nmi_watchdog= [KNL,BUGS=X86-32] Debugging features for SMP kernels
no387 [BUGS=X86-32] Tells the kernel to use the 387 maths
@@ -1456,14 +1493,10 @@ and is between 256 and 4096 characters. It is defined in the file
raid= [HW,RAID]
See Documentation/md.txt.
- ramdisk= [RAM] Sizes of RAM disks in kilobytes [deprecated]
- See Documentation/ramdisk.txt.
-
ramdisk_blocksize= [RAM]
See Documentation/ramdisk.txt.
ramdisk_size= [RAM] Sizes of RAM disks in kilobytes
- New name for the ramdisk parameter.
See Documentation/ramdisk.txt.
rcu.blimit= [KNL,BOOT] Set maximum number of finished
@@ -1526,6 +1559,15 @@ and is between 256 and 4096 characters. It is defined in the file
Useful for devices that are detected asynchronously
(e.g. USB and MMC devices).
+ root_plug.vendor_id=
+ [ROOTPLUG] Override the default vendor ID
+
+ root_plug.product_id=
+ [ROOTPLUG] Override the default product ID
+
+ root_plug.debug=
+ [ROOTPLUG] Enable debugging output
+
rw [KNL] Mount root device read-write on boot
S [KNL] Run init in single mode
@@ -1883,9 +1925,6 @@ and is between 256 and 4096 characters. It is defined in the file
Format:
<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
- tsdev.xres= [TS] Horizontal screen resolution.
- tsdev.yres= [TS] Vertical screen resolution.
-
turbografx.map[2|3]= [HW,JOY]
TurboGraFX parallel port interface
Format:
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt
index c1f64fdf84c..266955d23ee 100644
--- a/Documentation/keys-request-key.txt
+++ b/Documentation/keys-request-key.txt
@@ -20,6 +20,19 @@ or:
const char *callout_string,
void *aux);
+or:
+
+ struct key *request_key_async(const struct key_type *type,
+ const char *description,
+ const char *callout_string);
+
+or:
+
+ struct key *request_key_async_with_auxdata(const struct key_type *type,
+ const char *description,
+ const char *callout_string,
+ void *aux);
+
Or by userspace invoking the request_key system call:
key_serial_t request_key(const char *type,
@@ -32,10 +45,14 @@ does not need to link the key to a keyring to prevent it from being immediately
destroyed. The kernel interface returns a pointer directly to the key, and
it's up to the caller to destroy the key.
-The request_key_with_auxdata() call is like the in-kernel request_key() call,
-except that it permits auxiliary data to be passed to the upcaller (the default
-is NULL). This is only useful for those key types that define their own upcall
-mechanism rather than using /sbin/request-key.
+The request_key*_with_auxdata() calls are like the in-kernel request_key*()
+calls, except that they permit auxiliary data to be passed to the upcaller (the
+default is NULL). This is only useful for those key types that define their
+own upcall mechanism rather than using /sbin/request-key.
+
+The two async in-kernel calls may return keys that are still in the process of
+being constructed. The two non-async ones will wait for construction to
+complete first.
The userspace interface links the key to a keyring associated with the process
to prevent the key from going away, and returns the serial number of the key to
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 947d57d5345..51652d39e61 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -4,7 +4,7 @@
This service allows cryptographic keys, authentication tokens, cross-domain
user mappings, and similar to be cached in the kernel for the use of
-filesystems other kernel services.
+filesystems and other kernel services.
Keyrings are permitted; these are a special type of key that can hold links to
other keys. Processes each have three standard keyring subscriptions that a
@@ -726,6 +726,15 @@ call, and the key released upon close. How to deal with conflicting keys due to
two different users opening the same file is left to the filesystem author to
solve.
+To access the key manager, the following header must be #included:
+
+ <linux/key.h>
+
+Specific key types should have a header file under include/keys/ that should be
+used to access that type. For keys of type "user", for example, that would be:
+
+ <keys/user-type.h>
+
Note that there are two different types of pointers to keys that may be
encountered:
@@ -791,6 +800,36 @@ payload contents" for more information.
passed to the key_type->request_key() op if it exists.
+(*) A key can be requested asynchronously by calling one of:
+
+ struct key *request_key_async(const struct key_type *type,
+ const char *description,
+ const char *callout_string);
+
+ or:
+
+ struct key *request_key_async_with_auxdata(const struct key_type *type,
+ const char *description,
+ const char *callout_string,
+ void *aux);
+
+ which are asynchronous equivalents of request_key() and
+ request_key_with_auxdata() respectively.
+
+ These two functions return with the key potentially still under
+ construction. To wait for contruction completion, the following should be
+ called:
+
+ int wait_for_key_construction(struct key *key, bool intr);
+
+ The function will wait for the key to finish being constructed and then
+ invokes key_validate() to return an appropriate value to indicate the state
+ of the key (0 indicates the key is usable).
+
+ If intr is true, then the wait can be interrupted by a signal, in which
+ case error ERESTARTSYS will be returned.
+
+
(*) When it is no longer required, the key should be released using:
void key_put(struct key *key);
@@ -924,7 +963,11 @@ DEFINING A KEY TYPE
A kernel service may want to define its own key type. For instance, an AFS
filesystem might want to define a Kerberos 5 ticket key type. To do this, it
-author fills in a struct key_type and registers it with the system.
+author fills in a key_type struct and registers it with the system.
+
+Source files that implement key types should include the following header file:
+
+ <linux/key-type.h>
The structure has a number of fields, some of which are mandatory:
@@ -1053,22 +1096,44 @@ The structure has a number of fields, some of which are mandatory:
as might happen when the userspace buffer is accessed.
- (*) int (*request_key)(struct key *key, struct key *authkey, const char *op,
+ (*) int (*request_key)(struct key_construction *cons, const char *op,
void *aux);
- This method is optional. If provided, request_key() and
- request_key_with_auxdata() will invoke this function rather than
- upcalling to /sbin/request-key to operate upon a key of this type.
+ This method is optional. If provided, request_key() and friends will
+ invoke this function rather than upcalling to /sbin/request-key to operate
+ upon a key of this type.
+
+ The aux parameter is as passed to request_key_async_with_auxdata() and
+ similar or is NULL otherwise. Also passed are the construction record for
+ the key to be operated upon and the operation type (currently only
+ "create").
+
+ This method is permitted to return before the upcall is complete, but the
+ following function must be called under all circumstances to complete the
+ instantiation process, whether or not it succeeds, whether or not there's
+ an error:
+
+ void complete_request_key(struct key_construction *cons, int error);
+
+ The error parameter should be 0 on success, -ve on error. The
+ construction record is destroyed by this action and the authorisation key
+ will be revoked. If an error is indicated, the key under construction
+ will be negatively instantiated if it wasn't already instantiated.
+
+ If this method returns an error, that error will be returned to the
+ caller of request_key*(). complete_request_key() must be called prior to
+ returning.
+
+ The key under construction and the authorisation key can be found in the
+ key_construction struct pointed to by cons:
+
+ (*) struct key *key;
+
+ The key under construction.
- The aux parameter is as passed to request_key_with_auxdata() or is NULL
- otherwise. Also passed are the key to be operated upon, the
- authorisation key for this operation and the operation type (currently
- only "create").
+ (*) struct key *authkey;
- This function should return only when the upcall is complete. Upon return
- the authorisation key will be revoked, and the target key will be
- negatively instantiated if it is still uninstantiated. The error will be
- returned to the caller of request_key*().
+ The authorisation key.
============================
diff --git a/Documentation/local_ops.txt b/Documentation/local_ops.txt
index b0aca0705d1..4269a1105b3 100644
--- a/Documentation/local_ops.txt
+++ b/Documentation/local_ops.txt
@@ -27,7 +27,7 @@ CPU which owns the data. Therefore, care must taken to make sure that only one
CPU writes to the local_t data. This is done by using per cpu data and making
sure that we modify it from within a preemption safe context. It is however
permitted to read local_t data from any CPU : it will then appear to be written
-out of order wrt other memory writes on the owner CPU.
+out of order wrt other memory writes by the owner CPU.
* Implementation for a given architecture
@@ -45,6 +45,29 @@ long fails. The definition looks like :
typedef struct { atomic_long_t a; } local_t;
+* Rules to follow when using local atomic operations
+
+- Variables touched by local ops must be per cpu variables.
+- _Only_ the CPU owner of these variables must write to them.
+- This CPU can use local ops from any context (process, irq, softirq, nmi, ...)
+ to update its local_t variables.
+- Preemption (or interrupts) must be disabled when using local ops in
+ process context to make sure the process won't be migrated to a
+ different CPU between getting the per-cpu variable and doing the
+ actual local op.
+- When using local ops in interrupt context, no special care must be
+ taken on a mainline kernel, since they will run on the local CPU with
+ preemption already disabled. I suggest, however, to explicitly
+ disable preemption anyway to make sure it will still work correctly on
+ -rt kernels.
+- Reading the local cpu variable will provide the current copy of the
+ variable.
+- Reads of these variables can be done from any CPU, because updates to
+ "long", aligned, variables are always atomic. Since no memory
+ synchronization is done by the writer CPU, an outdated copy of the
+ variable can be read when reading some _other_ cpu's variables.
+
+
* How to use local atomic operations
#include <linux/percpu.h>
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index 59108cebe16..8a523f6af48 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -192,10 +192,10 @@ Devices possible for Atari:
seconds.
-2.6) ramdisk=
+2.6) ramdisk_size=
-------------
-Syntax: ramdisk=<size>
+Syntax: ramdisk_size=<size>
This option instructs the kernel to set up a ramdisk of the given
size in KBytes. Do not use this option if the ramdisk contents are
diff --git a/Documentation/make/headers_install.txt b/Documentation/make/headers_install.txt
new file mode 100644
index 00000000000..f2481cabffc
--- /dev/null
+++ b/Documentation/make/headers_install.txt
@@ -0,0 +1,46 @@
+Exporting kernel headers for use by userspace
+=============================================
+
+The "make headers_install" command exports the kernel's header files in a
+form suitable for use by userspace programs.
+
+The linux kernel's exported header files describe the API for user space
+programs attempting to use kernel services. These kernel header files are
+used by the system's C library (such as glibc or uClibc) to define available
+system calls, as well as constants and structures to be used with these
+system calls. The C library's header files include the kernel header files
+from the "linux" subdirectory. The system's libc headers are usually
+installed at the default location /usr/include and the kernel headers in
+subdirectories under that (most notably /usr/include/linux and
+/usr/include/asm).
+
+Kernel headers are backwards compatible, but not forwards compatible. This
+means that a program built against a C library using older kernel headers
+should run on a newer kernel (although it may not have access to new
+features), but a program built against newer kernel headers may not work on an
+older kernel.
+
+The "make headers_install" command can be run in the top level directory of the
+kernel source code (or using a standard out-of-tree build). It takes two
+optional arguments:
+
+ make headers_install ARCH=i386 INSTALL_HDR_PATH=/usr/include
+
+ARCH indicates which architecture to produce headers for, and defaults to the
+current architecture. The linux/asm directory of the exported kernel headers
+is platform-specific, to see a complete list of supported architectures use
+the command:
+
+ ls -d include/asm-* | sed 's/.*-//'
+
+INSTALL_HDR_PATH indicates where to install the headers. It defaults to
+"./usr/include".
+
+The command "make headers_install_all" exports headers for all architectures
+simultaneously. (This is mostly of interest to distribution maintainers,
+who create an architecture-independent tarball from the resulting include
+directory.) Remember to provide the appropriate linux/asm directory via "mv"
+or "ln -s" before building a C library with headers exported this way.
+
+The kernel header export infrastructure is maintained by David Woodhouse
+<dwmw2@infradead.org>.
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 650657c5473..4e17beba237 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -1479,7 +1479,8 @@ kernel.
Any atomic operation that modifies some state in memory and returns information
about the state (old or new) implies an SMP-conditional general memory barrier
-(smp_mb()) on each side of the actual operation. These include:
+(smp_mb()) on each side of the actual operation (with the exception of
+explicit lock operations, described later). These include:
xchg();
cmpxchg();
@@ -1536,10 +1537,19 @@ If they're used for constructing a lock of some description, then they probably
do need memory barriers as a lock primitive generally has to do things in a
specific order.
-
Basically, each usage case has to be carefully considered as to whether memory
barriers are needed or not.
+The following operations are special locking primitives:
+
+ test_and_set_bit_lock();
+ clear_bit_unlock();
+ __clear_bit_unlock();
+
+These implement LOCK-class and UNLOCK-class operations. These should be used in
+preference to other operations when implementing locking primitives, because
+their implementations can be optimised on many architectures.
+
[!] Note that special memory barrier primitives are available for these
situations because on some CPUs the atomic instructions used imply full memory
barriers, and so barrier instructions are superfluous in conjunction with them,
diff --git a/Documentation/mips/00-INDEX b/Documentation/mips/00-INDEX
new file mode 100644
index 00000000000..9df8a2eac7b
--- /dev/null
+++ b/Documentation/mips/00-INDEX
@@ -0,0 +1,8 @@
+00-INDEX
+ - this file.
+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/mutex-design.txt b/Documentation/mutex-design.txt
index cbf79881a41..51f935191ae 100644
--- a/Documentation/mutex-design.txt
+++ b/Documentation/mutex-design.txt
@@ -90,7 +90,8 @@ of advantages of mutexes:
* - task may not exit with mutex held
* - memory areas where held locks reside must not be freed
* - held mutexes must not be reinitialized
- * - mutexes may not be used in irq contexts
+ * - mutexes may not be used in hardware or software interrupt
+ * contexts such as tasklets and timers
furthermore, there are also convenience features in the debugging
code:
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 1da56663083..11340625e36 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -281,6 +281,39 @@ downdelay
will be rounded down to the nearest multiple. The default
value is 0.
+fail_over_mac
+
+ Specifies whether active-backup mode should set all slaves to
+ the same MAC address (the traditional behavior), or, when
+ enabled, change the bond's MAC address when changing the
+ active interface (i.e., fail over the MAC address itself).
+
+ Fail over MAC is useful for devices that cannot ever alter
+ their MAC address, or for devices that refuse incoming
+ broadcasts with their own source MAC (which interferes with
+ the ARP monitor).
+
+ The down side of fail over MAC is that every device on the
+ network must be updated via gratuitous ARP, vs. just updating
+ a switch or set of switches (which often takes place for any
+ traffic, not just ARP traffic, if the switch snoops incoming
+ traffic to update its tables) for the traditional method. If
+ the gratuitous ARP is lost, communication may be disrupted.
+
+ When fail over MAC is used in conjuction with the mii monitor,
+ devices which assert link up prior to being able to actually
+ transmit and receive are particularly susecptible to loss of
+ the gratuitous ARP, and an appropriate updelay setting may be
+ required.
+
+ A value of 0 disables fail over MAC, and is the default. A
+ value of 1 enables fail over MAC. This option is enabled
+ automatically if the first slave added cannot change its MAC
+ address. This option may be modified via sysfs only when no
+ slaves are present in the bond.
+
+ This option was added in bonding version 3.2.0.
+
lacp_rate
Option specifying the rate in which we'll ask our link partner
diff --git a/Documentation/networking/proc_net_tcp.txt b/Documentation/networking/proc_net_tcp.txt
index 5e21f7cb638..4a79209e77a 100644
--- a/Documentation/networking/proc_net_tcp.txt
+++ b/Documentation/networking/proc_net_tcp.txt
@@ -1,8 +1,9 @@
This document describes the interfaces /proc/net/tcp and /proc/net/tcp6.
+Note that these interfaces are deprecated in favor of tcp_diag.
These /proc interfaces provide information about currently active TCP
-connections, and are implemented by tcp_get_info() in net/ipv4/tcp_ipv4.c and
-tcp6_get_info() in net/ipv6/tcp_ipv6.c, respectively.
+connections, and are implemented by tcp4_seq_show() in net/ipv4/tcp_ipv4.c
+and tcp6_seq_show() in net/ipv6/tcp_ipv6.c, respectively.
It will first list all listening TCP sockets, and next list all established
TCP connections. A typical entry of /proc/net/tcp would look like this (split
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt
index cae231b1c13..c36b64b0020 100644
--- a/Documentation/networking/rxrpc.txt
+++ b/Documentation/networking/rxrpc.txt
@@ -857,3 +857,10 @@ The kernel interface functions are as follows:
This is used to extract the error number from a message indicating either
a local error occurred or a network error occurred.
+
+ (*) Allocate a null key for doing anonymous security.
+
+ struct key *rxrpc_get_null_key(const char *keyname);
+
+ This is used to allocate a null RxRPC key that can be used to indicate
+ anonymous security for a particular domain.
diff --git a/Documentation/parport-lowlevel.txt b/Documentation/parport-lowlevel.txt
index 8f2302415ef..265fcdcb8e5 100644
--- a/Documentation/parport-lowlevel.txt
+++ b/Documentation/parport-lowlevel.txt
@@ -25,7 +25,6 @@ Global functions:
parport_open
parport_close
parport_device_id
- parport_device_num
parport_device_coords
parport_find_class
parport_find_device
@@ -735,7 +734,7 @@ NULL is returned.
SEE ALSO
-parport_register_device, parport_device_num
+parport_register_device
parport_close - unregister device for particular device number
-------------
@@ -787,29 +786,7 @@ Many devices have ill-formed IEEE 1284 Device IDs.
SEE ALSO
-parport_find_class, parport_find_device, parport_device_num
-
-parport_device_num - convert device coordinates to device number
-------------------
-
-SYNOPSIS
-
-#include <linux/parport.h>
-
-int parport_device_num (int parport, int mux, int daisy);
-
-DESCRIPTION
-
-Convert between device coordinates (port, multiplexor, daisy chain
-address) and device number (zero-based).
-
-RETURN VALUE
-
-Device number, or -1 if no device at given coordinates.
-
-SEE ALSO
-
-parport_device_coords, parport_open, parport_device_id
+parport_find_class, parport_find_device
parport_device_coords - convert device number to device coordinates
------------------
@@ -833,7 +810,7 @@ Zero on success, in which case the coordinates are (*parport, *mux,
SEE ALSO
-parport_device_num, parport_open, parport_device_id
+parport_open, parport_device_id
parport_find_class - find a device by its class
------------------
diff --git a/Documentation/power/00-INDEX b/Documentation/power/00-INDEX
new file mode 100644
index 00000000000..8db4e41a052
--- /dev/null
+++ b/Documentation/power/00-INDEX
@@ -0,0 +1,34 @@
+00-INDEX
+ - This file
+basic-pm-debugging.txt
+ - Debugging suspend and resume
+devices.txt
+ - How drivers interact with system-wide power management
+drivers-testing.txt
+ - Testing suspend and resume support in device drivers
+freezing-of-tasks.txt
+ - How processes and controlled during suspend
+interface.txt
+ - Power management user interface in /sys/power
+notifiers.txt
+ - Registering suspend notifiers in device drivers
+pci.txt
+ - How the PCI Subsystem Does Power Management
+s2ram.txt
+ - How to get suspend to ram working (and debug it when it isn't)
+states.txt
+ - System power management states
+swsusp-and-swap-files.txt
+ - Using swap files with software suspend (to disk)
+swsusp-dmcrypt.txt
+ - How to use dm-crypt and software suspend (to disk) together
+swsusp.txt
+ - Goals, implementation, and usage of software suspend (ACPI S3)
+tricks.txt
+ - How to trick software suspend (to disk) into working when it isn't
+userland-swsusp.txt
+ - Experimental implementation of software suspend in userspace
+video_extension.txt
+ - ACPI video extensions
+video.txt
+ - Video issues during resume from suspend
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
index 1a85e2b964d..57aef2f6e0d 100644
--- a/Documentation/power/basic-pm-debugging.txt
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -78,8 +78,8 @@ c) Advanced debugging
In case the STD does not work on your system even in the minimal configuration
and compiling more drivers as modules is not practical or some modules cannot
be unloaded, you can use one of the more advanced debugging techniques to find
-the problem. First, if there is a serial port in your box, you can set the
-CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel
+the problem. First, if there is a serial port in your box, you can boot the
+kernel with the 'no_console_suspend' parameter and try to log kernel
messages using the serial console. This may provide you with some information
about the reasons of the suspend (resume) failure. Alternatively, it may be
possible to use a FireWire port for debugging with firescope
diff --git a/Documentation/power/drivers-testing.txt b/Documentation/power/drivers-testing.txt
index 33016c2f18d..e4bdcaee24e 100644
--- a/Documentation/power/drivers-testing.txt
+++ b/Documentation/power/drivers-testing.txt
@@ -14,8 +14,8 @@ the machine's BIOS.
Of course, for this purpose the test system has to be known to suspend and
resume without the driver being tested. Thus, if possible, you should first
resolve all suspend/resume-related problems in the test system before you start
-testing the new driver. Please see Documents/power/basic-pm-debugging.txt for
-more information about the debugging of suspend/resume functionality.
+testing the new driver. Please see Documentation/power/basic-pm-debugging.txt
+for more information about the debugging of suspend/resume functionality.
2. Testing the driver
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index 04dc1cf9d21..38b57248fd6 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -19,12 +19,13 @@ we only consider hibernation, but the description also applies to suspend).
Namely, as the first step of the hibernation procedure the function
freeze_processes() (defined in kernel/power/process.c) is called. It executes
try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
-sends a fake signal to each of them. A task that receives such a signal and has
-TIF_FREEZE set, should react to it by calling the refrigerator() function
-(defined in kernel/power/process.c), which sets the task's PF_FROZEN flag,
-changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is
-cleared for it. Then, we say that the task is 'frozen' and therefore the set of
-functions handling this mechanism is called 'the freezer' (these functions are
+either wakes them up, if they are kernel threads, or sends fake signals to them,
+if they are user space processes. A task that has TIF_FREEZE set, should react
+to it by calling the function called refrigerator() (defined in
+kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state
+to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
+Then, we say that the task is 'frozen' and therefore the set of functions
+handling this mechanism is referred to as 'the freezer' (these functions are
defined in kernel/power/process.c and include/linux/freezer.h). User space
processes are generally frozen before kernel threads.
@@ -35,21 +36,27 @@ task enter refrigerator() if the flag is set.
For user space processes try_to_freeze() is called automatically from the
signal-handling code, but the freezable kernel threads need to call it
-explicitly in suitable places. The code to do this may look like the following:
+explicitly in suitable places or use the wait_event_freezable() or
+wait_event_freezable_timeout() macros (defined in include/linux/freezer.h)
+that combine interruptible sleep with checking if TIF_FREEZE is set and calling
+try_to_freeze(). The main loop of a freezable kernel thread may look like the
+following one:
+ set_freezable();
do {
hub_events();
- wait_event_interruptible(khubd_wait,
- !list_empty(&hub_event_list));
- try_to_freeze();
- } while (!signal_pending(current));
+ wait_event_freezable(khubd_wait,
+ !list_empty(&hub_event_list) ||
+ kthread_should_stop());
+ } while (!kthread_should_stop() || !list_empty(&hub_event_list));
(from drivers/usb/core/hub.c::hub_thread()).
If a freezable kernel thread fails to call try_to_freeze() after the freezer has
set TIF_FREEZE for it, the freezing of tasks will fail and the entire
hibernation operation will be cancelled. For this reason, freezable kernel
-threads must call try_to_freeze() somewhere.
+threads must call try_to_freeze() somewhere or use one of the
+wait_event_freezable() and wait_event_freezable_timeout() macros.
After the system memory state has been restored from a hibernation image and
devices have been reinitialized, the function thaw_processes() is called in
@@ -81,7 +88,16 @@ hibernation image has been created and before the system is finally powered off.
The majority of these are user space processes, but if any of the kernel threads
may cause something like this to happen, they have to be freezable.
-2. The second reason is to prevent user space processes and some kernel threads
+2. Next, to create the hibernation image we need to free a sufficient amount of
+memory (approximately 50% of available RAM) and we need to do that before
+devices are deactivated, because we generally need them for swapping out. Then,
+after the memory for the image has been freed, we don't want tasks to allocate
+additional memory and we prevent them from doing that by freezing them earlier.
+[Of course, this also means that device drivers should not allocate substantial
+amounts of memory from their .suspend() callbacks before hibernation, but this
+is e separate issue.]
+
+3. The third reason is to prevent user space processes and some kernel threads
from interfering with the suspending and resuming of devices. A user space
process running on a second CPU while we are suspending devices may, for
example, be troublesome and without the freezing of tasks we would need some
@@ -111,7 +127,7 @@ frozen before the driver's .suspend() callback is executed and it will be
thawed after the driver's .resume() callback has run, so it won't be accessing
the device while it's suspended.
-3. Another reason for freezing tasks is to prevent user space processes from
+4. Another reason for freezing tasks is to prevent user space processes from
realizing that hibernation (or suspend) operation takes place. Ideally, user
space processes should not notice that such a system-wide operation has occurred
and should continue running without any problems after the restore (or resume
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index fd5192a8fa8..e67211fe0ee 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -20,7 +20,7 @@ states.
/sys/power/disk controls the operating mode of the suspend-to-disk
mechanism. Suspend-to-disk can be handled in several ways. We have a
few options for putting the system to sleep - using the platform driver
-(e.g. ACPI or other pm_ops), powering off the system or rebooting the
+(e.g. ACPI or other suspend_ops), powering off the system or rebooting the
system (for testing).
Additionally, /sys/power/disk can be used to turn on one of the two testing
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index d6d65b9bcfe..94a3c577b08 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -5,6 +5,8 @@ please mail me.
00-INDEX
- this file
+booting-without-of.txt
+ - Booting the Linux/ppc kernel without Open Firmware
cpu_features.txt
- info on how we support a variety of CPUs with minimal compile-time
options.
@@ -14,6 +16,8 @@ hvcs.txt
- IBM "Hypervisor Virtual Console Server" Installation Guide
mpc52xx.txt
- Linux 2.6.x on MPC52xx family
+mpc52xx-device-tree-bindings.txt
+ - MPC5200 Device Tree Bindings
ppc_htab.txt
- info about the Linux/PPC /proc/ppc_htab entry
SBC8260_memory_mapping.txt
diff --git a/Documentation/ramdisk.txt b/Documentation/ramdisk.txt
index 52f75b7d51c..6c820baa19a 100644
--- a/Documentation/ramdisk.txt
+++ b/Documentation/ramdisk.txt
@@ -22,16 +22,14 @@ The RAM disk dynamically grows as more space is required. It does this by using
RAM from the buffer cache. The driver marks the buffers it is using as dirty
so that the VM subsystem does not try to reclaim them later.
-Also, the RAM disk supports up to 16 RAM disks out of the box, and can
-be reconfigured to support up to 255 RAM disks - change "#define NUM_RAMDISKS"
-in drivers/block/rd.c. To use RAM disk support with your system, run
-'./MAKEDEV ram' from the /dev directory. RAM disks are all major number 1, and
-start with minor number 0 for /dev/ram0, etc. If used, modern kernels use
-/dev/ram0 for an initrd.
-
-The old "ramdisk=<ram_size>" has been changed to "ramdisk_size=<ram_size>" to
-make it clearer. The original "ramdisk=<ram_size>" has been kept around for
-compatibility reasons, but it may be removed in the future.
+The RAM disk supports up to 16 RAM disks by default, and can be reconfigured
+to support an unlimited number of RAM disks (at your own risk). Just change
+the configuration symbol BLK_DEV_RAM_COUNT in the Block drivers config menu
+and (re)build the kernel.
+
+To use RAM disk support with your system, run './MAKEDEV ram' from the /dev
+directory. RAM disks are all major number 1, and start with minor number 0
+for /dev/ram0, etc. If used, modern kernels use /dev/ram0 for an initrd.
The new RAM disk also has the ability to load compressed RAM disk images,
allowing one to squeeze more programs onto an average installation or
diff --git a/Documentation/scsi/ChangeLog.ncr53c8xx b/Documentation/scsi/ChangeLog.ncr53c8xx
index 7d03e9d5b5f..a9f721aeb11 100644
--- a/Documentation/scsi/ChangeLog.ncr53c8xx
+++ b/Documentation/scsi/ChangeLog.ncr53c8xx
@@ -195,9 +195,9 @@ Sun Feb 14:00 1999 Gerard Roudier (groudier@club-internet.fr)
Pointed out by Leonard Zubkoff.
- Allow to tune request_irq() flags from the boot command line using
ncr53c8xx=irqm:??, as follows:
- a) If bit 0x10 is set in irqm, SA_SHIRQ flag is not used.
- b) If bit 0x20 is set in irqm, SA_INTERRUPT flag is not used.
- By default the driver uses both SA_SHIRQ and SA_INTERRUPT.
+ a) If bit 0x10 is set in irqm, IRQF_SHARED flag is not used.
+ b) If bit 0x20 is set in irqm, IRQF_DISABLED flag is not used.
+ By default the driver uses both IRQF_SHARED and IRQF_DISABLED.
Option 'ncr53c8xx=irqm:0x20' may be used when an IRQ is shared by
a 53C8XX adapter and a network board.
- Tiny mispelling fixed (ABORT instead of ABRT). Was fortunately
diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
index 9707941704e..a08e225653d 100644
--- a/Documentation/scsi/ibmmca.txt
+++ b/Documentation/scsi/ibmmca.txt
@@ -1188,7 +1188,7 @@
and 15 get ignored by the driver & adapter!
Q: I have a 9595 and I get a NMI during heavy SCSI I/O e.g. during fsck.
A COMMAND ERROR is reported and characters on the screen are missing.
- Warm reboot is not possible. Things look like quite weired.
+ Warm reboot is not possible. Things look like quite weird.
A: Check the processor type of your 9595. If you have an 80486 or 486DX-2
processor complex on your mainboard and you compiled a kernel that
supports 80386 processors, it is possible, that the kernel cannot
diff --git a/Documentation/scsi/ncr53c8xx.txt b/Documentation/scsi/ncr53c8xx.txt
index 39d409a8efe..230e30846ef 100644
--- a/Documentation/scsi/ncr53c8xx.txt
+++ b/Documentation/scsi/ncr53c8xx.txt
@@ -785,8 +785,8 @@ port address 0x1400.
irqm:0 always open drain
irqm:1 same as initial settings (assumed BIOS settings)
irqm:2 always totem pole
- irqm:0x10 driver will not use SA_SHIRQ flag when requesting irq
- irqm:0x20 driver will not use SA_INTERRUPT flag when requesting irq
+ irqm:0x10 driver will not use IRQF_SHARED flag when requesting irq
+ irqm:0x20 driver will not use IRQF_DISABLED flag when requesting irq
(Bits 0x10 and 0x20 can be combined with hardware irq mode option)
@@ -1236,15 +1236,15 @@ when the SCSI DATA IN phase is reentered after a phase mismatch.
When an IRQ is shared by devices that are handled by different drivers, it
may happen that one driver complains about the request of the IRQ having
failed. Inder Linux-2.0, this may be due to one driver having requested the
-IRQ using the SA_INTERRUPT flag but some other having requested the same IRQ
+IRQ using the IRQF_DISABLED flag but some other having requested the same IRQ
without this flag. Under both Linux-2.0 and linux-2.2, this may be caused by
-one driver not having requested the IRQ with the SA_SHIRQ flag.
+one driver not having requested the IRQ with the IRQF_SHARED flag.
By default, the ncr53c8xx and sym53c8xx drivers request IRQs with both the
-SA_INTERRUPT and the SA_SHIRQ flag under Linux-2.0 and with only the SA_SHIRQ
+IRQF_DISABLED and the IRQF_SHARED flag under Linux-2.0 and with only the IRQF_SHARED
flag under Linux-2.2.
-Under Linux-2.0, you can disable use of SA_INTERRUPT flag from the boot
+Under Linux-2.0, you can disable use of IRQF_DISABLED flag from the boot
command line by using the following option:
ncr53c8xx=irqm:0x20 (for the generic ncr53c8xx driver)
@@ -1252,7 +1252,7 @@ command line by using the following option:
If this does not fix the problem, then you may want to check how all other
drivers are requesting the IRQ and report the problem. Note that if at least
-a single driver does not request the IRQ with the SA_SHIRQ flag (share IRQ),
+a single driver does not request the IRQ with the IRQF_SHARED flag (share IRQ),
then the request of the IRQ obviously will not succeed for all the drivers.
15. SCSI problem troubleshooting
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 241e26c4ff9..4b48c2e82c3 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -365,13 +365,14 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module snd-cmipci
-----------------
- Module for C-Media CMI8338 and 8738 PCI sound cards.
+ Module for C-Media CMI8338/8738/8768/8770 PCI sound cards.
- mpu_port - 0x300,0x310,0x320,0x330 = legacy port,
- 1 = integrated PCI port,
+ mpu_port - port address of MIDI interface (8338 only):
+ 0x300,0x310,0x320,0x330 = legacy port,
0 = disable (default)
- fm_port - 0x388 = legacy port,
- 1 = integrated PCI port (default),
+ fm_port - port address of OPL-3 FM synthesizer (8x38 only):
+ 0x388 = legacy port,
+ 1 = integrated PCI port (default on 8738),
0 = disable
soft_ac3 - Software-conversion of raw SPDIF packets (model 033 only)
(default = 1)
@@ -768,6 +769,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
single_cmd - Use single immediate commands to communicate with
codecs (for debugging only)
enable_msi - Enable Message Signaled Interrupt (MSI) (default = off)
+ power_save - Automatic power-saving timtout (in second, 0 =
+ disable)
+ power_save_controller - Reset HD-audio controller in power-saving mode
+ (default = on)
This module supports one card and autoprobe.
@@ -828,6 +833,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ALC268
3stack 3-stack model
+ toshiba Toshiba A205
+ acer Acer laptops
auto auto-config reading BIOS (default)
ALC662
@@ -842,7 +849,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack-dig 3-jack with SPDIF I/O
6stack-dig 6-jack digital with SPDIF I/O
arima Arima W820Di1
+ targa Targa T8, MSI-1049 T8
+ asus-a7j ASUS A7J
+ asus-a7m ASUS A7M
macpro MacPro support
+ mbp3 Macbook Pro rev3
imac24 iMac 24'' with jack detection
w2jc ASUS W2JC
auto auto-config reading BIOS (default)
@@ -854,6 +865,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
6stack-dig-demo 6-jack digital for Intel demo board
acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
+ acer-aspire Acer Aspire 9810
medion Medion Laptops
medion-md2 Medion MD2
targa-dig Targa/MSI
@@ -862,6 +874,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
lenovo-101e Lenovo 101E
lenovo-nb0763 Lenovo NB0763
lenovo-ms7195-dig Lenovo MS7195
+ haier-w66 Haier W66
6stack-hp HP machines with 6stack (Nettle boards)
3stack-hp HP machines with 3stack (Lucknow, Samba boards)
auto auto-config reading BIOS (default)
@@ -885,6 +898,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
lenovo Lenovo 3000 C200
dallas Dallas laptops
+ hp HP TX1000
auto auto-config reading BIOS (default)
CMI9880
@@ -920,6 +934,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
3stack 3-stack, shared surrounds
laptop 2-channel only (FSC V2060, Samsung M50)
laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J)
+ laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
ultra 2-channel with EAPD (Samsung Ultra tablet PC)
AD1988
@@ -945,14 +960,30 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
can be adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y
- STAC9200/9205/9254
+ STAC9200
ref Reference board
+ dell-d21 Dell (unknown)
+ dell-d22 Dell (unknown)
+ dell-d23 Dell (unknown)
+ dell-m21 Dell Inspiron 630m, Dell Inspiron 640m
+ dell-m22 Dell Latitude D620, Dell Latitude D820
+ dell-m23 Dell XPS M1710, Dell Precision M90
+ dell-m24 Dell Latitude 120L
+ dell-m25 Dell Inspiron E1505n
+ dell-m26 Dell Inspiron 1501
+ dell-m27 Dell Inspiron E1705/9400
+ gateway Gateway laptops with EAPD control
+
+ STAC9205/9254
+ ref Reference board
+ dell-m42 Dell (unknown)
+ dell-m43 Dell Precision
+ dell-m44 Dell Inspiron
STAC9220/9221
ref Reference board
3stack D945 3stack
5stack D945 5stack + SPDIF
- dell Dell XPS M1210
intel-mac-v1 Intel Mac Type 1
intel-mac-v2 Intel Mac Type 2
intel-mac-v3 Intel Mac Type 3
@@ -964,6 +995,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3)
imac-intel Intel iMac (eq. type 2)
imac-intel-20 Intel iMac (newer version) (eq. type 3)
+ dell-d81 Dell (unknown)
+ dell-d82 Dell (unknown)
+ dell-m81 Dell (unknown)
+ dell-m82 Dell XPS M1210
STAC9202/9250/9251
ref Reference board, base config
@@ -975,6 +1010,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ref Reference board
3stack D965 3stack
5stack D965 5stack + SPDIF
+ dell-3stack Dell Dimension E520
STAC9872
vaio Setup for VAIO FE550G/SZ110
@@ -989,6 +1025,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
ML (see the section "Links and Addresses").
+ power_save and power_save_controller options are for power-saving
+ mode. See powersave.txt for details.
+
Note 2: If you get click noises on output, try the module option
position_fix=1 or 2. position_fix=1 will use the SD_LPIB
register value without FIFO size correction as the current
@@ -1349,7 +1388,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
port - port number or -1 (disable)
irq - IRQ number or -1 (disable)
pnp - PnP detection - 0 = disable, 1 = enable (default)
- uart_enter - Issue UART_ENTER command at open - bool, default = on
This module supports multiple devices and PnP.
@@ -1630,6 +1668,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
+ Module snd-sc6000
+ -----------------
+
+ Module for Gallant SC-6000 soundcard.
+
+ port - Port # (0x220 or 0x240)
+ mss_port - MSS Port # (0x530 or 0xe80)
+ irq - IRQ # (5,7,9,10,11)
+ mpu_irq - MPU-401 IRQ # (5,7,9,10) ,0 - no MPU-401 irq
+ dma - DMA # (1,3,0)
+
+ This module supports multiple cards.
+
+ This card is also known as Audio Excel DSP 16 or Zoltrix AV302.
+
Module snd-sgalaxy
------------------
@@ -1650,9 +1703,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for ENSONIQ SoundScape PnP cards.
port - Port # (PnP setup)
+ wss_port - WSS Port # (PnP setup)
irq - IRQ # (PnP setup)
mpu_irq - MPU-401 IRQ # (PnP setup)
dma - DMA # (PnP setup)
+ dma2 - 2nd DMA # (PnP setup, -1 to disable)
This module supports multiple cards. ISA PnP must be enabled.
You need sscape_ctl tool in alsa-tools package for loading
@@ -1697,8 +1752,52 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
dma2 - DMA2 # for CS4232 PCM interface.
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
+ The below are options for wavefront_synth features:
+ wf_raw - Assume that we need to boot the OS (default:no)
+ If yes, then during driver loading, the state of the board is
+ ignored, and we reset the board and load the firmware anyway.
+ fx_raw - Assume that the FX process needs help (default:yes)
+ If false, we'll leave the FX processor in whatever state it is
+ when the driver is loaded. The default is to download the
+ microprogram and associated coefficients to set it up for
+ "default" operation, whatever that means.
+ debug_default - Debug parameters for card initialization
+ wait_usecs - How long to wait without sleeping, usecs
+ (default:150)
+ This magic number seems to give pretty optimal throughput
+ based on my limited experimentation.
+ If you want to play around with it and find a better value, be
+ my guest. Remember, the idea is to get a number that causes us
+ to just busy wait for as many WaveFront commands as possible,
+ without coming up with a number so large that we hog the whole
+ CPU.
+ Specifically, with this number, out of about 134,000 status
+ waits, only about 250 result in a sleep.
+ sleep_interval - How long to sleep when waiting for reply
+ (default: 100)
+ sleep_tries - How many times to try sleeping during a wait
+ (default: 50)
+ ospath - Pathname to processed ICS2115 OS firmware
+ (default:wavefront.os)
+ The path name of the ISC2115 OS firmware. In the recent
+ version, it's handled via firmware loader framework, so it
+ must be installed in the proper path, typically,
+ /lib/firmware.
+ reset_time - How long to wait for a reset to take effect
+ (default:2)
+ ramcheck_time - How many seconds to wait for the RAM test
+ (default:20)
+ osrun_time - How many seconds to wait for the ICS2115 OS
+ (default:10)
+
This module supports multiple cards and ISA PnP.
+ Note: the firmware file "wavefront.os" was located in the earlier
+ version in /etc. Now it's loaded via firmware loader, and
+ must be in the proper firmware path, such as /lib/firmware.
+ Copy (or symlink) the file appropriately if you get an error
+ regarding firmware downloading after upgrading the kernel.
+
Module snd-sonicvibes
---------------------
diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
index 4b2b1538705..16935c8561f 100644
--- a/Documentation/sound/alsa/CMIPCI.txt
+++ b/Documentation/sound/alsa/CMIPCI.txt
@@ -1,5 +1,5 @@
- Brief Notes on C-Media 8738/8338 Driver
- =======================================
+ Brief Notes on C-Media 8338/8738/8768/8770 Driver
+ =================================================
Takashi Iwai <tiwai@suse.de>
@@ -209,10 +209,13 @@ In addition to the standard SB mixer, CM8x38 provides more functions.
MIDI CONTROLLER
---------------
-The MPU401-UART interface is disabled as default. You need to set
-module option "mpu_port" with a valid I/O port address to enable the
-MIDI support. The valid I/O ports are 0x300, 0x310, 0x320 and 0x330.
-Choose the value which doesn't conflict with other cards.
+With CMI8338 chips, the MPU401-UART interface is disabled as default.
+You need to set the module option "mpu_port" to a valid I/O port address
+to enable MIDI support. Valid I/O ports are 0x300, 0x310, 0x320 and
+0x330. Choose a value that doesn't conflict with other cards.
+
+With CMI8738 and newer chips, the MIDI interface is enabled by default
+and the driver automatically chooses a port address.
There is _no_ hardware wavetable function on this chip (except for
OPL3 synth below).
@@ -230,6 +233,8 @@ Set "fm_port" module option for more cards.
The output quality of FM OPL/3 is, however, very weird.
I don't know why..
+CMI8768 and newer chips do not have the FM synth.
+
Joystick and Modem
------------------
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 74d3a35b59b..2c3fc3cb3b6 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
</affiliation>
</author>
- <date>November 17, 2005</date>
- <edition>0.3.6</edition>
+ <date>September 10, 2007</date>
+ <edition>0.3.7</edition>
<abstract>
<para>
@@ -405,8 +405,9 @@
/* definition of the chip-specific record */
struct mychip {
struct snd_card *card;
- // rest of implementation will be in the section
- // "PCI Resource Managements"
+ /* rest of implementation will be in the section
+ * "PCI Resource Managements"
+ */
};
/* chip-specific destructor
@@ -414,7 +415,7 @@
*/
static int snd_mychip_free(struct mychip *chip)
{
- .... // will be implemented later...
+ .... /* will be implemented later... */
}
/* component-destructor
@@ -440,8 +441,9 @@
*rchip = NULL;
- // check PCI availability here
- // (see "PCI Resource Managements")
+ /* check PCI availability here
+ * (see "PCI Resource Managements")
+ */
....
/* allocate a chip-specific data with zero filled */
@@ -451,12 +453,13 @@
chip->card = card;
- // rest of initialization here; will be implemented
- // later, see "PCI Resource Managements"
+ /* rest of initialization here; will be implemented
+ * later, see "PCI Resource Managements"
+ */
....
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_mychip_free(chip);
return err;
}
@@ -490,7 +493,8 @@
return -ENOMEM;
/* (3) */
- if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
+ err = snd_mychip_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -502,10 +506,11 @@
card->shortname, chip->ioport, chip->irq);
/* (5) */
- .... // implemented later
+ .... /* implemented later */
/* (6) */
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -605,7 +610,8 @@
<![CDATA[
struct mychip *chip;
....
- if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
+ err = snd_mychip_create(card, pci, &chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -666,7 +672,8 @@
<informalexample>
<programlisting>
<![CDATA[
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -1091,7 +1098,7 @@
static int snd_mychip_free(struct mychip *chip)
{
/* disable hardware here if any */
- .... // (not implemented in this document)
+ .... /* (not implemented in this document) */
/* release the irq */
if (chip->irq >= 0)
@@ -1119,7 +1126,8 @@
*rchip = NULL;
/* initialize the PCI entry */
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
/* check PCI availability (28bit DMA) */
if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
@@ -1141,7 +1149,8 @@
chip->irq = -1;
/* (1) PCI resource allocation */
- if ((err = pci_request_regions(pci, "My Chip")) < 0) {
+ err = pci_request_regions(pci, "My Chip");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1156,10 +1165,10 @@
chip->irq = pci->irq;
/* (2) initialization of the chip hardware */
- .... // (not implemented in this document)
+ .... /* (not implemented in this document) */
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
- chip, &ops)) < 0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
snd_mychip_free(chip);
return err;
}
@@ -1233,7 +1242,8 @@
<informalexample>
<programlisting>
<![CDATA[
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 ||
pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) {
@@ -1294,7 +1304,8 @@
<informalexample>
<programlisting>
<![CDATA[
- if ((err = pci_request_regions(pci, "My Chip")) < 0) {
+ err = pci_request_regions(pci, "My Chip");
+ if (err < 0) {
kfree(chip);
pci_disable_device(pci);
return err;
@@ -1322,7 +1333,7 @@
<programlisting>
<![CDATA[
if (request_irq(pci->irq, snd_mychip_interrupt,
- IRQF_DISABLED|IRQF_SHARED, "My Chip", chip)) {
+ IRQF_SHARED, "My Chip", chip)) {
printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
snd_mychip_free(chip);
return -EBUSY;
@@ -1773,7 +1784,8 @@
struct snd_pcm_runtime *runtime = substream->runtime;
runtime->hw = snd_mychip_playback_hw;
- // more hardware-initialization will be done here
+ /* more hardware-initialization will be done here */
+ ....
return 0;
}
@@ -1781,7 +1793,8 @@
static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
{
struct mychip *chip = snd_pcm_substream_chip(substream);
- // the hardware-specific codes will be here
+ /* the hardware-specific codes will be here */
+ ....
return 0;
}
@@ -1793,7 +1806,8 @@
struct snd_pcm_runtime *runtime = substream->runtime;
runtime->hw = snd_mychip_capture_hw;
- // more hardware-initialization will be done here
+ /* more hardware-initialization will be done here */
+ ....
return 0;
}
@@ -1801,7 +1815,8 @@
static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
{
struct mychip *chip = snd_pcm_substream_chip(substream);
- // the hardware-specific codes will be here
+ /* the hardware-specific codes will be here */
+ ....
return 0;
}
@@ -1844,10 +1859,12 @@
{
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- // do something to start the PCM engine
+ /* do something to start the PCM engine */
+ ....
break;
case SNDRV_PCM_TRIGGER_STOP:
- // do something to stop the PCM engine
+ /* do something to stop the PCM engine */
+ ....
break;
default:
return -EINVAL;
@@ -1900,8 +1917,8 @@
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
- &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
strcpy(pcm->name, "My Chip");
@@ -1939,8 +1956,8 @@
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
- &pcm)) < 0)
+ err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, &pcm);
+ if (err < 0)
return err;
pcm->private_data = chip;
strcpy(pcm->name, "My Chip");
@@ -2097,7 +2114,7 @@
struct mychip *chip = snd_pcm_chip(pcm);
/* free your own data */
kfree(chip->my_private_pcm_data);
- // do what you like else
+ /* do what you like else */
....
}
@@ -2884,10 +2901,10 @@ struct _snd_pcm_runtime {
<![CDATA[
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- // do something to start the PCM engine
+ /* do something to start the PCM engine */
break;
case SNDRV_PCM_TRIGGER_STOP:
- // do something to stop the PCM engine
+ /* do something to stop the PCM engine */
break;
default:
return -EINVAL;
@@ -3071,7 +3088,7 @@ struct _snd_pcm_runtime {
spin_unlock(&chip->lock);
snd_pcm_period_elapsed(chip->substream);
spin_lock(&chip->lock);
- // acknowledge the interrupt if necessary
+ /* acknowledge the interrupt if necessary */
}
....
spin_unlock(&chip->lock);
@@ -3134,7 +3151,7 @@ struct _snd_pcm_runtime {
snd_pcm_period_elapsed(substream);
spin_lock(&chip->lock);
}
- // acknowledge the interrupt if necessary
+ /* acknowledge the interrupt if necessary */
}
....
spin_unlock(&chip->lock);
@@ -3456,6 +3473,13 @@ struct _snd_pcm_runtime {
</para>
<para>
+ The <structfield>tlv</structfield> field can be used to provide
+ metadata about the control; see the
+ <link linkend="control-interface-tlv">
+ <citetitle>Metadata</citetitle></link> subsection.
+ </para>
+
+ <para>
The other three are
<link linkend="control-interface-callbacks"><citetitle>
callback functions</citetitle></link>.
@@ -3604,7 +3628,7 @@ struct _snd_pcm_runtime {
<title>Example of info callback</title>
<programlisting>
<![CDATA[
- static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+ static int snd_myctl_mono_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -3639,7 +3663,7 @@ struct _snd_pcm_runtime {
<informalexample>
<programlisting>
<![CDATA[
- static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+ static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
static char *texts[4] = {
@@ -3658,6 +3682,16 @@ struct _snd_pcm_runtime {
</programlisting>
</informalexample>
</para>
+
+ <para>
+ Some common info callbacks are prepared for easy use:
+ <function>snd_ctl_boolean_mono_info()</function> and
+ <function>snd_ctl_boolean_stereo_info()</function>.
+ Obviously, the former is an info callback for a mono channel
+ boolean item, just like <function>snd_myctl_mono_info</function>
+ above, and the latter is for a stereo channel boolean item.
+ </para>
+
</section>
<section id="control-interface-callbacks-get">
@@ -3794,7 +3828,8 @@ struct _snd_pcm_runtime {
<informalexample>
<programlisting>
<![CDATA[
- if ((err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
+ if (err < 0)
return err;
]]>
</programlisting>
@@ -3843,6 +3878,56 @@ struct _snd_pcm_runtime {
</para>
</section>
+ <section id="control-interface-tlv">
+ <title>Metadata</title>
+ <para>
+ To provide information about the dB values of a mixer control, use
+ on of the <constant>DECLARE_TLV_xxx</constant> macros from
+ <filename>&lt;sound/tlv.h&gt;</filename> to define a variable
+ containing this information, set the<structfield>tlv.p
+ </structfield> field to point to this variable, and include the
+ <constant>SNDRV_CTL_ELEM_ACCESS_TLV_READ</constant> flag in the
+ <structfield>access</structfield> field; like this:
+ <informalexample>
+ <programlisting>
+<![CDATA[
+ static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
+
+ static struct snd_kcontrol_new my_control __devinitdata = {
+ ...
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ ...
+ .tlv.p = db_scale_my_control,
+ };
+]]>
+ </programlisting>
+ </informalexample>
+ </para>
+
+ <para>
+ The <function>DECLARE_TLV_DB_SCALE</function> macro defines
+ information about a mixer control where each step in the control's
+ value changes the dB value by a constant dB amount.
+ The first parameter is the name of the variable to be defined.
+ The second parameter is the minimum value, in units of 0.01 dB.
+ The third parameter is the step size, in units of 0.01 dB.
+ Set the fourth parameter to 1 if the minimum value actually mutes
+ the control.
+ </para>
+
+ <para>
+ The <function>DECLARE_TLV_DB_LINEAR</function> macro defines
+ information about a mixer control where the control's value affects
+ the output linearly.
+ The first parameter is the name of the variable to be defined.
+ The second parameter is the minimum value, in units of 0.01 dB.
+ The third parameter is the maximum value, in units of 0.01 dB.
+ If the minimum value mutes the control, set the second parameter to
+ <constant>TLV_DB_GAIN_MUTE</constant>.
+ </para>
+ </section>
+
</chapter>
@@ -3880,7 +3965,7 @@ struct _snd_pcm_runtime {
{
struct mychip *chip = ac97->private_data;
....
- // read a register value here from the codec
+ /* read a register value here from the codec */
return the_register_value;
}
@@ -3889,7 +3974,7 @@ struct _snd_pcm_runtime {
{
struct mychip *chip = ac97->private_data;
....
- // write the given register value to the codec
+ /* write the given register value to the codec */
}
static int snd_mychip_ac97(struct mychip *chip)
@@ -3902,7 +3987,8 @@ struct _snd_pcm_runtime {
.read = snd_mychip_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &bus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
@@ -4447,10 +4533,10 @@ struct _snd_pcm_runtime {
<informalexample>
<programlisting>
<![CDATA[
- struct list_head *list;
struct snd_rawmidi_substream *substream;
- list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
- substream = list_entry(list, struct snd_rawmidi_substream, list);
+ list_for_each_entry(substream,
+ &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams,
+ list {
sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
}
/* same for SNDRV_RAWMIDI_STREAM_INPUT */
diff --git a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt
index bfa0c9aacb4..022aaeb0e9d 100644
--- a/Documentation/sound/alsa/OSS-Emulation.txt
+++ b/Documentation/sound/alsa/OSS-Emulation.txt
@@ -303,10 +303,3 @@ ICE1712 supports only the unconventional format, interleaved
the buffer as the conventional (mono or 2-channels, 8 or 16bit) format
on OSS.
-USB devices
------------
-Some USB devices support only 24bit format packed in 3bytes. This
-format is not supported by OSS and no conversion is provided by kernel
-OSS emulation. You can use the user-space OSS emulation via libaoss
-instead.
-
diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt
index 4eaae2a4553..8e1b0252669 100644
--- a/Documentation/sound/alsa/hda_codec.txt
+++ b/Documentation/sound/alsa/hda_codec.txt
@@ -49,6 +49,9 @@ struct hda_bus_ops {
unsigned int verb, unsigned int parm);
unsigned int (*get_response)(struct hda_codec *codec);
void (*private_free)(struct hda_bus *);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ void (*pm_notify)(struct hda_codec *codec);
+#endif
};
The command callback is called when the codec module needs to send a
@@ -56,9 +59,16 @@ VERB to the controller. It's always a single command.
The get_response callback is called when the codec requires the answer
for the last command. These two callbacks are mandatory and have to
be given.
-The last, private_free callback, is optional. It's called in the
+The third, private_free callback, is optional. It's called in the
destructor to release any necessary data in the lowlevel driver.
+The pm_notify callback is available only with
+CONFIG_SND_HDA_POWER_SAVE kconfig. It's called when the codec needs
+to power up or may power down. The controller should check the all
+belonging codecs on the bus whether they are actually powered off
+(check codec->power_on), and optionally the driver may power down the
+contoller side, too.
+
The bus instance is created via snd_hda_bus_new(). You need to pass
the card instance, the template, and the pointer to store the
resultant bus instance.
@@ -86,10 +96,8 @@ resultant codec instance (can be NULL if not needed).
The codec is stored in a linked list of bus instance. You can follow
the codec list like:
- struct list_head *p;
struct hda_codec *codec;
- list_for_each(p, &bus->codec_list) {
- codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &bus->codec_list, list) {
...
}
@@ -100,10 +108,15 @@ initialization sequence is called when the controls are built later.
Codec Access
============
-To access codec, use snd_codec_read() and snd_codec_write().
+To access codec, use snd_hda_codec_read() and snd_hda_codec_write().
snd_hda_param_read() is for reading parameters.
For writing a sequence of verbs, use snd_hda_sequence_write().
+There are variants of cached read/write, snd_hda_codec_write_cache(),
+snd_hda_sequence_write_cache(). These are used for recording the
+register states for the power-mangement resume. When no PM is needed,
+these are equivalent with non-cached version.
+
To retrieve the number of sub nodes connected to the given node, use
snd_hda_get_sub_nodes(). The connection list can be obtained via
snd_hda_get_connections() call.
@@ -239,6 +252,10 @@ set the codec->patch_ops field. This is defined as below:
int (*suspend)(struct hda_codec *codec, pm_message_t state);
int (*resume)(struct hda_codec *codec);
#endif
+ #ifdef CONFIG_SND_HDA_POWER_SAVE
+ int (*check_power_status)(struct hda_codec *codec,
+ hda_nid_t nid);
+ #endif
};
The build_controls callback is called from snd_hda_build_controls().
@@ -251,6 +268,18 @@ The unsol_event callback is called when an unsolicited event is
received.
The suspend and resume callbacks are for power management.
+They can be NULL if no special sequence is required. When the resume
+callback is NULL, the driver calls the init callback and resumes the
+registers from the cache. If other handling is needed, you'd need to
+write your own resume callback. There, the amp values can be resumed
+via
+ void snd_hda_codec_resume_amp(struct hda_codec *codec);
+and the other codec registers via
+ void snd_hda_codec_resume_cache(struct hda_codec *codec);
+
+The check_power_status callback is called when the amp value of the
+given widget NID is changed. The codec code can turn on/off the power
+appropriately from this information.
Each entry can be NULL if not necessary to be called.
@@ -267,8 +296,7 @@ Digital I/O
===========
Call snd_hda_create_spdif_out_ctls() from the patch to create controls
-related with SPDIF out. In the patch resume callback, call
-snd_hda_resume_spdif().
+related with SPDIF out.
Helper Functions
@@ -284,12 +312,7 @@ as a module parameter, and PCI subsystem IDs. If the matching entry
is found, it returns the config field value.
snd_hda_add_new_ctls() can be used to create and add control entries.
-Pass the zero-terminated array of struct snd_kcontrol_new. The same array
-can be passed to snd_hda_resume_ctls() for resume.
-Note that this will call control->put callback of these entries. So,
-put callback should check codec->in_resume and force to restore the
-given value if it's non-zero even if the value is identical with the
-cached value.
+Pass the zero-terminated array of struct snd_kcontrol_new
Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
used for the entry of struct snd_kcontrol_new.
diff --git a/Documentation/sound/alsa/powersave.txt b/Documentation/sound/alsa/powersave.txt
new file mode 100644
index 00000000000..9657e809922
--- /dev/null
+++ b/Documentation/sound/alsa/powersave.txt
@@ -0,0 +1,41 @@
+Notes on Power-Saving Mode
+==========================
+
+AC97 and HD-audio drivers have the automatic power-saving mode.
+This feature is enabled via Kconfig CONFIG_SND_AC97_POWER_SAVE
+and CONFIG_SND_HDA_POWER_SAVE options, respectively.
+
+With the automatic power-saving, the driver turns off the codec power
+appropriately when no operation is required. When no applications use
+the device and/or no analog loopback is set, the power disablement is
+done fully or partially. It'll save a certain power consumption, thus
+good for laptops (even for desktops).
+
+The time-out for automatic power-off can be specified via power_save
+module option of snd-ac97-codec and snd-hda-intel modules. Specify
+the time-out value in seconds. 0 means to disable the automatic
+power-saving. The default value of timeout is given via
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT and
+CONFIG_SND_HDA_POWER_SAVE_DEFAULT Kconfig options. Setting this to 1
+(the minimum value) isn't recommended because many applications try to
+reopen the device frequently. 10 would be a good choice for normal
+operations.
+
+The power_save option is exported as writable. This means you can
+adjust the value via sysfs on the fly. For example, to turn on the
+automatic power-save mode with 10 seconds, write to
+/sys/modules/snd_ac97_codec/parameters/power_save (usually as root):
+
+ # echo 10 > /sys/modules/snd_ac97_codec/parameters/power_save
+
+
+Note that you might hear click noise/pop when changing the power
+state. Also, it often takes certain time to wake up from the
+power-down to the active state. These are often hardly to fix, so
+don't report extra bug reports unless you have a fix patch ;-)
+
+For HD-audio interface, there is another module option,
+power_save_controller. This enables/disables the power-save mode of
+the controller side. Setting this on may reduce a bit more power
+consumption, but might result in longer wake-up time and click noise.
+Try to turn it off when you experience such a thing too often.
diff --git a/Documentation/sound/oss/es1371 b/Documentation/sound/oss/es1371
deleted file mode 100644
index c3151266771..00000000000
--- a/Documentation/sound/oss/es1371
+++ /dev/null
@@ -1,64 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-This soundcard does not have any hardware MIDI synthesizer;
-MIDI synthesis has to be done in software. To allow this
-the driver/soundcard supports two PCM (/dev/dsp) interfaces.
-
-There is a freely available software package that allows
-MIDI file playback on this soundcard called Timidity.
-See http://www.cgs.fi/~tt/timidity/.
-
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index 76ea6c837be..8861e47e5a2 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -156,21 +156,29 @@ using the driver model to connect controller and protocol drivers using
device tables provided by board specific initialization code. SPI
shows up in sysfs in several locations:
+ /sys/devices/.../CTLR ... physical node for a given SPI controller
+
/sys/devices/.../CTLR/spiB.C ... spi_device on bus "B",
chipselect C, accessed through CTLR.
+ /sys/bus/spi/devices/spiB.C ... symlink to that physical
+ .../CTLR/spiB.C device
+
/sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
that should be used with this device (for hotplug/coldplug)
- /sys/bus/spi/devices/spiB.C ... symlink to the physical
- spiB.C device
-
/sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
- /sys/class/spi_master/spiB ... class device for the controller
- managing bus "B". All the spiB.* devices share the same
+ /sys/class/spi_master/spiB ... symlink (or actual device node) to
+ a logical node which could hold class related state for the
+ controller managing bus "B". All spiB.* devices share one
physical SPI bus segment, with SCLK, MOSI, and MISO.
+Note that the actual location of the controller's class state depends
+on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time,
+the only class-specific state is the bus number ("B" in "spiB"), so
+those /sys/class entries are only useful to quickly identify busses.
+
How does board-specific init code declare SPI devices?
------------------------------------------------------
@@ -337,7 +345,8 @@ SPI protocol drivers somewhat resemble platform device drivers:
The driver core will autmatically attempt to bind this driver to any SPI
device whose board_info gave a modalias of "CHIP". Your probe() code
-might look like this unless you're creating a class_device:
+might look like this unless you're creating a device which is managing
+a bus (appearing under /sys/class/spi_master).
static int __devinit CHIP_probe(struct spi_device *spi)
{
@@ -442,7 +451,7 @@ An SPI controller will probably be registered on the platform_bus; write
a driver to bind to the device, whichever bus is involved.
The main task of this type of driver is to provide an "spi_master".
-Use spi_alloc_master() to allocate the master, and class_get_devdata()
+Use spi_alloc_master() to allocate the master, and spi_master_get_devdata()
to get the driver-private data allocated for that device.
struct spi_master *master;
@@ -452,7 +461,7 @@ to get the driver-private data allocated for that device.
if (!master)
return -ENODEV;
- c = class_get_devdata(&master->cdev);
+ c = spi_master_get_devdata(master);
The driver will initialize the fields of that spi_master, including the
bus number (maybe the same as the platform device ID) and three methods
diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c
index 218e8621529..cf0e3ce0d52 100644
--- a/Documentation/spi/spidev_test.c
+++ b/Documentation/spi/spidev_test.c
@@ -29,7 +29,7 @@ static void pabort(const char *s)
abort();
}
-static char *device = "/dev/spidev1.1";
+static const char *device = "/dev/spidev1.1";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
@@ -69,7 +69,7 @@ static void transfer(int fd)
puts("");
}
-void print_usage(char *prog)
+void print_usage(const char *prog)
{
printf("Usage: %s [-DsbdlHOLC3]\n", prog);
puts(" -D --device device to use (default /dev/spidev1.1)\n"
@@ -88,7 +88,7 @@ void print_usage(char *prog)
void parse_opts(int argc, char *argv[])
{
while (1) {
- static struct option lopts[] = {
+ static const struct option lopts[] = {
{ "device", 1, 0, 'D' },
{ "speed", 1, 0, 's' },
{ "delay", 1, 0, 'd' },
diff --git a/Documentation/sysctl/00-INDEX b/Documentation/sysctl/00-INDEX
new file mode 100644
index 00000000000..a20a9066dc4
--- /dev/null
+++ b/Documentation/sysctl/00-INDEX
@@ -0,0 +1,16 @@
+00-INDEX
+ - this file.
+README
+ - general information about /proc/sys/ sysctl files.
+abi.txt
+ - documentation for /proc/sys/abi/*.
+ctl_unnumbered.txt
+ - explanation of why one should not add new binary sysctl numbers.
+fs.txt
+ - documentation for /proc/sys/fs/*.
+kernel.txt
+ - documentation for /proc/sys/kernel/*.
+sunrpc.txt
+ - documentation for /proc/sys/sunrpc/*.
+vm.txt
+ - documentation for /proc/sys/vm/*.
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 111fd28727e..8984a539627 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -320,6 +320,14 @@ kernel. This value defaults to SHMMAX.
==============================================================
+softlockup_thresh:
+
+This value can be used to lower the softlockup tolerance
+threshold. The default threshold is 10s. If a cpu is locked up
+for 10s, the kernel complains. Valid values are 1-60s.
+
+==============================================================
+
tainted:
Non-zero if the kernel has been tainted. Numeric values, which
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index a0ccc5b6026..b89570c3043 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -31,6 +31,7 @@ Currently, these files are in /proc/sys/vm:
- min_unmapped_ratio
- min_slab_ratio
- panic_on_oom
+- oom_kill_allocating_task
- mmap_min_address
- numa_zonelist_order
@@ -111,6 +112,12 @@ of kilobytes free. The VM uses this number to compute a pages_min
value for each lowmem zone in the system. Each lowmem zone gets
a number of reserved free pages based proportionally on its size.
+Some minimal ammount of memory is needed to satisfy PF_MEMALLOC
+allocations; if you set this to lower than 1024KB, your system will
+become subtly broken, and prone to deadlock under high loads.
+
+Setting this too high will OOM your machine instantly.
+
==============================================================
percpu_pagelist_fraction
@@ -220,6 +227,27 @@ The default value is 0.
1 and 2 are for failover of clustering. Please select either
according to your policy of failover.
+=============================================================
+
+oom_kill_allocating_task
+
+This enables or disables killing the OOM-triggering task in
+out-of-memory situations.
+
+If this is set to zero, the OOM killer will scan through the entire
+tasklist and select a task based on heuristics to kill. This normally
+selects a rogue memory-hogging task that frees up a large amount of
+memory when killed.
+
+If this is set to non-zero, the OOM killer simply kills the task that
+triggered the out-of-memory condition. This avoids the expensive
+tasklist scan.
+
+If panic_on_oom is selected, it takes precedence over whatever value
+is used in oom_kill_allocating_task.
+
+The default value is 0.
+
==============================================================
mmap_min_addr
diff --git a/Documentation/telephony/00-INDEX b/Documentation/telephony/00-INDEX
new file mode 100644
index 00000000000..4ffe0ed5b6f
--- /dev/null
+++ b/Documentation/telephony/00-INDEX
@@ -0,0 +1,4 @@
+00-INDEX
+ - this file.
+ixj.txt
+ - document describing the Quicknet drivers.
diff --git a/Documentation/vm/00-INDEX b/Documentation/vm/00-INDEX
new file mode 100644
index 00000000000..2131b00b63f
--- /dev/null
+++ b/Documentation/vm/00-INDEX
@@ -0,0 +1,20 @@
+00-INDEX
+ - this file.
+balance
+ - various information on memory balancing.
+hugetlbpage.txt
+ - a brief summary of hugetlbpage support in the Linux kernel.
+locking
+ - info on how locking and synchronization is done in the Linux vm code.
+numa
+ - information about NUMA specific code in the Linux vm.
+numa_memory_policy.txt
+ - documentation of concepts and APIs of the 2.6 memory policy support.
+overcommit-accounting
+ - description of the Linux kernels overcommit handling modes.
+page_migration
+ - description of page migration in NUMA systems.
+slabinfo.c
+ - source code for a tool to get reports about slabs.
+slub.txt
+ - a short users guide for SLUB.
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 8242f52d0f2..dd498649799 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -302,31 +302,30 @@ MEMORY POLICIES AND CPUSETS
Memory policies work within cpusets as described above. For memory policies
that require a node or set of nodes, the nodes are restricted to the set of
-nodes whose memories are allowed by the cpuset constraints. If the
-intersection of the set of nodes specified for the policy and the set of nodes
-allowed by the cpuset is the empty set, the policy is considered invalid and
-cannot be installed.
+nodes whose memories are allowed by the cpuset constraints. If the nodemask
+specified for the policy contains nodes that are not allowed by the cpuset, or
+the intersection of the set of nodes specified for the policy and the set of
+nodes with memory is the empty set, the policy is considered invalid
+and cannot be installed.
The interaction of memory policies and cpusets can be problematic for a
couple of reasons:
-1) the memory policy APIs take physical node id's as arguments. However, the
- memory policy APIs do not provide a way to determine what nodes are valid
- in the context where the application is running. An application MAY consult
- the cpuset file system [directly or via an out of tree, and not generally
- available, libcpuset API] to obtain this information, but then the
- application must be aware that it is running in a cpuset and use what are
- intended primarily as administrative APIs.
-
- However, as long as the policy specifies at least one node that is valid
- in the controlling cpuset, the policy can be used.
+1) the memory policy APIs take physical node id's as arguments. As mentioned
+ above, it is illegal to specify nodes that are not allowed in the cpuset.
+ The application must query the allowed nodes using the get_mempolicy()
+ API with the MPOL_F_MEMS_ALLOWED flag to determine the allowed nodes and
+ restrict itself to those nodes. However, the resources available to a
+ cpuset can be changed by the system administrator, or a workload manager
+ application, at any time. So, a task may still get errors attempting to
+ specify policy nodes, and must query the allowed memories again.
2) when tasks in two cpusets share access to a memory region, such as shared
memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and
MAP_SHARED flags, and any of the tasks install shared policy on the region,
only nodes whose memories are allowed in both cpusets may be used in the
- policies. Again, obtaining this information requires "stepping outside"
- the memory policy APIs, as well as knowing in what cpusets other task might
- be attaching to the shared region, to use the cpuset information.
+ policies. Obtaining this information requires "stepping outside" the
+ memory policy APIs to use the cpuset information and requires that one
+ know in what cpusets other task might be attaching to the shared region.
Furthermore, if the cpusets' allowed memory sets are disjoint, "local"
allocation is the only valid policy.
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
index 1af7bd5a218..7047696c47a 100644
--- a/Documentation/vm/slabinfo.c
+++ b/Documentation/vm/slabinfo.c
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
+#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
@@ -84,7 +85,7 @@ void fatal(const char *x, ...)
va_start(ap, x);
vfprintf(stderr, x, ap);
va_end(ap);
- exit(1);
+ exit(EXIT_FAILURE);
}
void usage(void)
@@ -119,14 +120,14 @@ void usage(void)
);
}
-unsigned long read_obj(char *name)
+unsigned long read_obj(const char *name)
{
FILE *f = fopen(name, "r");
if (!f)
buffer[0] = 0;
else {
- if (!fgets(buffer,sizeof(buffer), f))
+ if (!fgets(buffer, sizeof(buffer), f))
buffer[0] = 0;
fclose(f);
if (buffer[strlen(buffer)] == '\n')
@@ -139,7 +140,7 @@ unsigned long read_obj(char *name)
/*
* Get the contents of an attribute
*/
-unsigned long get_obj(char *name)
+unsigned long get_obj(const char *name)
{
if (!read_obj(name))
return 0;
@@ -147,7 +148,7 @@ unsigned long get_obj(char *name)
return atol(buffer);
}
-unsigned long get_obj_and_str(char *name, char **x)
+unsigned long get_obj_and_str(const char *name, char **x)
{
unsigned long result = 0;
char *p;
@@ -166,12 +167,12 @@ unsigned long get_obj_and_str(char *name, char **x)
return result;
}
-void set_obj(struct slabinfo *s, char *name, int n)
+void set_obj(struct slabinfo *s, const char *name, int n)
{
char x[100];
FILE *f;
- sprintf(x, "%s/%s", s->name, name);
+ snprintf(x, 100, "%s/%s", s->name, name);
f = fopen(x, "w");
if (!f)
fatal("Cannot write to %s\n", x);
@@ -180,13 +181,13 @@ void set_obj(struct slabinfo *s, char *name, int n)
fclose(f);
}
-unsigned long read_slab_obj(struct slabinfo *s, char *name)
+unsigned long read_slab_obj(struct slabinfo *s, const char *name)
{
char x[100];
FILE *f;
- int l;
+ size_t l;
- sprintf(x, "%s/%s", s->name, name);
+ snprintf(x, 100, "%s/%s", s->name, name);
f = fopen(x, "r");
if (!f) {
buffer[0] = 0;
@@ -453,7 +454,7 @@ void slabcache(struct slabinfo *s)
return;
store_size(size_str, slab_size(s));
- sprintf(dist_str,"%lu/%lu/%d", s->slabs, s->partial, s->cpu_slabs);
+ snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs, s->partial, s->cpu_slabs);
if (!line++)
first_line();
@@ -1062,6 +1063,7 @@ void read_slab_dir(void)
slab->partial = get_obj("partial");
slab->partial = get_obj_and_str("partial", &t);
decode_numa_list(slab->numa_partial, t);
+ free(t);
slab->poison = get_obj("poison");
slab->reclaim_account = get_obj("reclaim_account");
slab->red_zone = get_obj("red_zone");
@@ -1069,6 +1071,7 @@ void read_slab_dir(void)
slab->slab_size = get_obj("slab_size");
slab->slabs = get_obj_and_str("slabs", &t);
decode_numa_list(slab->numa, t);
+ free(t);
slab->store_user = get_obj("store_user");
slab->trace = get_obj("trace");
chdir("..");
@@ -1148,7 +1151,7 @@ int main(int argc, char *argv[])
while ((c = getopt_long(argc, argv, "ad::efhil1noprstvzTS",
opts, NULL)) != -1)
- switch(c) {
+ switch (c) {
case '1':
show_single_ref = 1;
break;
diff --git a/Documentation/w1/00-INDEX b/Documentation/w1/00-INDEX
new file mode 100644
index 00000000000..5270cf4cb10
--- /dev/null
+++ b/Documentation/w1/00-INDEX
@@ -0,0 +1,8 @@
+00-INDEX
+ - This file
+masters/
+ - Individual chips providing 1-wire busses.
+w1.generic
+ - The 1-wire (w1) bus
+w1.netlink
+ - Userspace communication protocol over connector [1].
diff --git a/Documentation/w1/masters/00-INDEX b/Documentation/w1/masters/00-INDEX
new file mode 100644
index 00000000000..752613c4cea
--- /dev/null
+++ b/Documentation/w1/masters/00-INDEX
@@ -0,0 +1,6 @@
+00-INDEX
+ - This file
+ds2482
+ - The Maxim/Dallas Semiconductor DS2482 provides 1-wire busses.
+ds2490
+ - The Maxim/Dallas Semiconductor DS2490 builds USB <-> W1 bridges.
diff --git a/Documentation/w1/masters/ds2482 b/Documentation/w1/masters/ds2482
index c5d5478d90b..9210d6fa502 100644
--- a/Documentation/w1/masters/ds2482
+++ b/Documentation/w1/masters/ds2482
@@ -15,7 +15,7 @@ Author: Ben Gardner <bgardner@wabtec.com>
Description
-----------
-The Maixm/Dallas Semiconductor DS2482 is a I2C device that provides
+The Maxim/Dallas Semiconductor DS2482 is a I2C device that provides
one (DS2482-100) or eight (DS2482-800) 1-wire busses.
diff --git a/Documentation/w1/masters/ds2490 b/Documentation/w1/masters/ds2490
index 44a4918bd7f..239f9ae0184 100644
--- a/Documentation/w1/masters/ds2490
+++ b/Documentation/w1/masters/ds2490
@@ -10,7 +10,7 @@ Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Description
-----------
-The Maixm/Dallas Semiconductor DS2490 is a chip
+The Maxim/Dallas Semiconductor DS2490 is a chip
which allows to build USB <-> W1 bridges.
DS9490(R) is a USB <-> W1 bus master device
diff --git a/Documentation/x86_64/mm.txt b/Documentation/x86_64/mm.txt
index f42798ed1c5..b89b6d2bebf 100644
--- a/Documentation/x86_64/mm.txt
+++ b/Documentation/x86_64/mm.txt
@@ -9,6 +9,7 @@ ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
ffff810000000000 - ffffc0ffffffffff (=46 bits) direct mapping of all phys. memory
ffffc10000000000 - ffffc1ffffffffff (=40 bits) hole
ffffc20000000000 - ffffe1ffffffffff (=45 bits) vmalloc/ioremap space
+ffffe20000000000 - ffffe2ffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffffff80000000 - ffffffff82800000 (=40 MB) kernel text mapping, from phys 0
... unused hole ...
diff --git a/Documentation/xterm-linux.xpm b/Documentation/xterm-linux.xpm
deleted file mode 100644
index f469c1a18e6..00000000000
--- a/Documentation/xterm-linux.xpm
+++ /dev/null
@@ -1,61 +0,0 @@
-/* XPM */
-/*****************************************************************************/
-/** This pixmap was made by Torsten Poulin - 1996 - torsten@diku.dk **/
-/** It was made by combining xterm-blank.xpm with **/
-/** the wonderfully cute Linux penguin mascot by Larry Ewing. **/
-/** I had to change Larry's penguin a little to make it fit. **/
-/** xterm-blank.xpm contained the following comment: **/
-/** This pixmap is kindly offered by Ion Cionca - 1992 - **/
-/** Swiss Federal Institute of Technology **/
-/** Central Computing Service **/
-/*****************************************************************************/
-static char * image_name [] = {
-/**/
-"64 38 8 1",
-/**/
-" s mask c none",
-". c gray70",
-"X c gray85",
-"o c gray50",
-"O c yellow",
-"+ c darkolivegreen",
-"@ c white",
-"# c black",
-" ###### ",
-" ######## ",
-" ########## ........................... ",
-" ########### .XXXXXXXXXXXXXXXXXXXXXXXXXXX. ",
-" ########### .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXoo ",
-" #@@@#@@@### .XX+++++++++++++++++++++++XXXXoo ",
-" #@#@#@#@### .XX++++++++++++++++++++++++XXXooo ",
-" #@#####@### .XX++@@+@++@+@@@@++@+++++++XXXooo ",
-" ###OOO######.XX++++++++++++++++++++++++XXXoooo ",
-" ##OOOOOO####.XX++@@@@+@@+@@@+++++++++++XXXoooo ",
-" #O#OOO#O####.XX++++++++++++++++++++++++XXXooooo ",
-" ##O###OO####.XX++@@@@@@@@@@+@@@@@++++++XXXooooo ",
-" ###OOOO@#####XX++++++++++++++++++++++++XXXooooo ",
-" ##@###@@@@####XX++@@@+@@@@+@@++@@@++++++XXXooooo ",
-" #@@@@@@@@@@####X++++++++++++++++++++++++XXXooooo ",
-" ##@@@@@@@@@@#####++@+++++++++++++++++++++XXXooooo ",
-" ###@@@@@@@@@@######+++++++++++++++++++++++XXXooooo ",
-" ####@@@@@@@@@@@#####+@@@@+@+@@@+@++++++++++XXXooooo ",
-" ###@@@@@@@@@@@@######++++++++++++++++++++++XXXooooo ",
-" ##@@@@@@@@@@@@@@#####@+@@@@++++++++++++++++XXXooooo ",
-" ###@@@@@@@@@@@@@@######++++++++++++++++++++XXXXoooo ",
-" ###@@@@@@@@@@@@@@######XXXXXXXXXXXXXXXXXXXXXXXXooo ",
-" ###@@@@@@@@@@@@@@@######XXXXXXXXXXXXXXXXXXXXXXXooo ",
-" ###@@@@@@@@@@@@@@@@#####ooooooooooooooooooooooo...oo ",
-" ###@@@@@@@@@@@@@@@######.........................ooo ",
-" #OO##@@@@@@@@@@@@@#######oooooooooooooooooooooooooooo ",
-" #OOO##@@@@@@@@@@@#OO####O#XXXXXXXXXXXXXXXXXXXXXXXoooo.. .. ",
-" ###OOOOO##@@@@@@@@@@#OOO#OOO#XXXXXXXXXXXXXX#######XXoooo . .",
-" #OOOOOOOO###@@@@@@@@@#OOOOOOO#ooooooooooooooooooooXXXooo . ",
-" #OOOOOOOOO###@@@@@@@@@#OOOOOOO##XXXXXXXXXXXXXXXXXooooo . ",
-" #OOOOOOOOO#@@@@@@@@###OOOOOOOOO#XXXXXXXXXXXXXXXoo oooooo ",
-" #OOOOOOOOO#@@@@@@@####OOOOOOOO#@@@@@@@@@@@XXXXXoo ooooo...o ",
-" #OOOOOOOOOOO###########OOOOOO##XXXXXXXXXXXXXXXXoo ooXXXoo..o ",
-" ##OOOOOOOOO###########OOOO##@@@@@@@@@@@@@XXXXoo oXXXXX..o ",
-" ###OOOO### oXX##OOO#XXXXXXXXXXXXXXXXXXoo o.....oo ",
-" #### oooo####oooooooooooooooooooo ooooooo ",
-" ",
-" "};
diff --git a/MAINTAINERS b/MAINTAINERS
index 12cee3da262..2534dc4aa95 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1769,7 +1769,7 @@ S: Maintained
HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
P: Jaroslav Kysela
-M: perex@suse.cz
+M: perex@perex.cz
S: Maintained
HPET: High Precision Event Timers driver (hpet.c)
@@ -1877,10 +1877,8 @@ T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
S: Maintained
IDE/ATAPI CDROM DRIVER
-P: Alan Cox
-M: alan@lxorguk.ukuu.org.uk
L: linux-ide@vger.kernel.org
-S: Maintained
+S: Unmaintained
IDE/ATAPI FLOPPY DRIVERS
P: Paul Bristow
@@ -2132,14 +2130,12 @@ S: Maintained
ISAPNP
P: Jaroslav Kysela
-M: perex@suse.cz
+M: perex@perex.cz
S: Maintained
ISDN SUBSYSTEM
P: Karsten Keil
M: kkeil@suse.de
-P: Kai Germaschewski
-M: kai.germaschewski@gmx.de
L: isdn4linux@listserv.isdn4linux.de
W: http://www.isdn4linux.de
T: git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
@@ -2208,8 +2204,6 @@ L: autofs@linux.kernel.org
S: Maintained
KERNEL BUILD (kbuild: Makefile, scripts/Makefile.*)
-P: Kai Germaschewski
-M: kai@germaschewski.name
P: Sam Ravnborg
M: sam@ravnborg.org
T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
@@ -2240,7 +2234,7 @@ S: Supported
KEXEC
P: Eric Biederman
M: ebiederm@xmission.com
-W: http://www.xmission.com/~ebiederm/files/kexec/
+W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
L: linux-kernel@vger.kernel.org
L: kexec@lists.infradead.org
S: Maintained
@@ -2404,6 +2398,15 @@ M: khali@linux-fr.org
L: lm-sensors@lm-sensors.org
S: Maintained
+LOCKDEP AND LOCKSTAT
+P: Peter Zijlstra
+M: peterz@infradead.org
+P: Ingo Molnar
+M: mingo@redhat.com
+L: linux-kernel@vger.kernel.org
+T: git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git
+S: Maintained
+
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
P: Richard Russon (FlatCap)
M: ldm@flatcap.org
@@ -2483,7 +2486,7 @@ S: Supported
MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
P: Michael Kerrisk
-M: mtk-manpages@gmx.net
+M: mtk.manpages@gmail.com
W: ftp://ftp.kernel.org/pub/linux/docs/manpages
S: Maintained
@@ -2937,13 +2940,6 @@ L: linux-kernel@vger.kernel.org
L: linux-pci@atrey.karlin.mff.cuni.cz
S: Supported
-PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
-P: Thomas Sailer
-M: sailer@ife.ee.ethz.ch
-L: linux-sound@vger.kernel.org
-W: http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
-S: Maintained
-
PCI SUBSYSTEM
P: Greg Kroah-Hartman
M: gregkh@suse.de
@@ -3514,7 +3510,7 @@ S: Maintained
SOUND
P: Jaroslav Kysela
-M: perex@suse.cz
+M: perex@perex.cz
L: alsa-devel@alsa-project.org (subscribers-only)
S: Maintained
@@ -3704,7 +3700,7 @@ S: Maintained
TI OMAP MMC INTERFACE DRIVER
P: Carlos Aguiar, Anderson Briglia and Syed Khasim
-M: linux-omap-open-source@linux.omap.com
+M: linux-omap-open-source@linux.omap.com (subscribers only)
W: http://linux.omap.com
W: http://www.muru.com/linux/omap/
S: Maintained
diff --git a/Makefile b/Makefile
index 1274084c909..529b9048d97 100644
--- a/Makefile
+++ b/Makefile
@@ -115,13 +115,20 @@ saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
$(if $(KBUILD_OUTPUT),, \
$(error output directory "$(saved-output)" does not exist))
+# Check that OUTPUT directory is not the same as where we have kernel src
+$(if $(filter-out $(KBUILD_OUTPUT),$(shell /bin/pwd)),, \
+ $(error Output directory (O=...) specifies kernel src dir))
-PHONY += $(MAKECMDGOALS)
+PHONY += $(MAKECMDGOALS) sub-make
-$(filter-out _all,$(MAKECMDGOALS)) _all:
+$(filter-out _all sub-make,$(MAKECMDGOALS)) _all: sub-make
+ $(Q)@:
+
+sub-make: FORCE
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
KBUILD_SRC=$(CURDIR) \
- KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
+ KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile \
+ $(filter-out _all sub-make,$(MAKECMDGOALS))
# Leave processing to above invocation of make
skip-makefile := 1
@@ -311,12 +318,12 @@ LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-include include/linux/autoconf.h
-CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
+KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration
-AFLAGS := -D__ASSEMBLY__
+KBUILD_AFLAGS := -D__ASSEMBLY__
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
@@ -327,9 +334,9 @@ export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
-export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
-export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
-export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
@@ -485,35 +492,41 @@ endif # $(dot-config)
all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-CFLAGS += -Os
+KBUILD_CFLAGS += -Os
else
-CFLAGS += -O2
+KBUILD_CFLAGS += -O2
endif
include $(srctree)/arch/$(ARCH)/Makefile
ifdef CONFIG_FRAME_POINTER
-CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
+KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
else
-CFLAGS += -fomit-frame-pointer
+KBUILD_CFLAGS += -fomit-frame-pointer
endif
ifdef CONFIG_DEBUG_INFO
-CFLAGS += -g
+KBUILD_CFLAGS += -g
+KBUILD_AFLAGS += -gdwarf-2
endif
# Force gcc to behave correct even for buggy distributions
-CFLAGS += $(call cc-option, -fno-stack-protector)
+KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
# warn about C99 declaration after statement
-CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
+KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
-CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
+
+# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
+KBUILD_CPPFLAGS += $(CPPFLAGS)
+KBUILD_AFLAGS += $(AFLAGS)
+KBUILD_CFLAGS += $(CFLAGS)
# Use --build-id when available.
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
@@ -1149,6 +1162,7 @@ help:
@echo 'Static analysers'
@echo ' checkstack - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel'
+ @echo ' export_report - List the usages of all exported symbols'
@if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
echo ' headers_check - Sanity check on exported headers'; \
fi
@@ -1255,8 +1269,10 @@ $(clean-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
clean: rm-dirs := $(MODVERDIR)
+clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers
clean: $(clean-dirs)
$(call cmd,rmdirs)
+ $(call cmd,rmfiles)
@find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
@@ -1309,8 +1325,8 @@ ALLSOURCE_ARCHS := $(ARCH) $(SRCARCH)
endif
define find-sources
- ( for ARCH in $(ALLSOURCE_ARCHS) ; do \
- find $(__srctree)arch/$${SRCARCH} $(RCS_FIND_IGNORE) \
+ ( for arch in $(ALLSOURCE_ARCHS) ; do \
+ find $(__srctree)arch/$${arch} $(RCS_FIND_IGNORE) \
-name $1 -print; \
done ; \
find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
@@ -1318,8 +1334,8 @@ define find-sources
find $(__srctree)include $(RCS_FIND_IGNORE) \
\( -name config -o -name 'asm-*' \) -prune \
-o -name $1 -print; \
- for ARCH in $(ALLINCLUDE_ARCHS) ; do \
- find $(__srctree)include/asm-$${SRCARCH} $(RCS_FIND_IGNORE) \
+ for arch in $(ALLINCLUDE_ARCHS) ; do \
+ find $(__srctree)include/asm-$${arch} $(RCS_FIND_IGNORE) \
-name $1 -print; \
done ; \
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
@@ -1411,6 +1427,9 @@ versioncheck:
namespacecheck:
$(PERL) $(srctree)/scripts/namespace.pl
+export_report:
+ $(PERL) $(srctree)/scripts/export_report.pl
+
endif #ifeq ($(config-targets),1)
endif #ifeq ($(mixed-targets),1)
@@ -1488,8 +1507,8 @@ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))
cmd_rmfiles = rm -f $(rm-files)
-a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \
- $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
+ $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
quiet_cmd_as_o_S = AS $@
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 1b704ee54bf..63104ebd180 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -12,79 +12,28 @@ NM := $(NM) -B
LDFLAGS_vmlinux := -static -N #-relax
CHECKFLAGS += -D__alpha__ -m64
-cflags-y := -pipe -mno-fp-regs -ffixed-8
+cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
-# Determine if we can use the BWX instructions with GAS.
-old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi)
+cpuflags-$(CONFIG_ALPHA_EV67) := -mcpu=ev67
+cpuflags-$(CONFIG_ALPHA_EV6) := -mcpu=ev6
+cpuflags-$(CONFIG_ALPHA_POLARIS) := -mcpu=pca56
+cpuflags-$(CONFIG_ALPHA_SX164) := -mcpu=pca56
+cpuflags-$(CONFIG_ALPHA_EV56) := -mcpu=ev56
+cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
+cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
+# If GENERIC, make sure to turn off any instruction set extensions that
+# the host compiler might have on by default. Given that EV4 and EV5
+# have the same instruction set, prefer EV5 because an EV5 schedule is
+# more likely to keep an EV4 processor busy than vice-versa.
+cpuflags-$(CONFIG_ALPHA_GENERIC) := -mcpu=ev5
-ifeq ($(old_gas),y)
-$(error The assembler '$(AS)' does not support the BWX instruction)
-endif
-
-# Determine if GCC understands the -mcpu= option.
-have_mcpu := $(call cc-option-yn, -mcpu=ev5)
-have_mcpu_pca56 := $(call cc-option-yn, -mcpu=pca56)
-have_mcpu_ev6 := $(call cc-option-yn, -mcpu=ev6)
-have_mcpu_ev67 := $(call cc-option-yn, -mcpu=ev67)
-have_msmall_data := $(call cc-option-yn, -msmall-data)
-
-cflags-$(have_msmall_data) += -msmall-data
-
-# Turn on the proper cpu optimizations.
-ifeq ($(have_mcpu),y)
- mcpu_done := n
- # If GENERIC, make sure to turn off any instruction set extensions that
- # the host compiler might have on by default. Given that EV4 and EV5
- # have the same instruction set, prefer EV5 because an EV5 schedule is
- # more likely to keep an EV4 processor busy than vice-versa.
- ifeq ($(CONFIG_ALPHA_GENERIC),y)
- mcpu := ev5
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_SX164)$(have_mcpu_pca56),nyy)
- mcpu := pca56
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_POLARIS)$(have_mcpu_pca56),nyy)
- mcpu := pca56
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV4),ny)
- mcpu := ev4
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV56),ny)
- mcpu := ev56
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV5),ny)
- mcpu := ev5
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV67)$(have_mcpu_ev67),nyy)
- mcpu := ev67
- mcpu_done := y
- endif
- ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV6),ny)
- ifeq ($(have_mcpu_ev6),y)
- mcpu := ev6
- else
- ifeq ($(have_mcpu_pca56),y)
- mcpu := pca56
- else
- mcpu=ev56
- endif
- endif
- mcpu_done := y
- endif
- cflags-$(mcpu_done) += -mcpu=$(mcpu)
-endif
+cflags-y += $(cpuflags-y)
# For TSUNAMI, we must have the assembler not emulate our instructions.
# The same is true for IRONGATE, POLARIS, PYXIS.
# BWX is most important, but we don't really want any emulation ever.
-CFLAGS += $(cflags-y) -Wa,-mev6
+KBUILD_CFLAGS += $(cflags-y) -Wa,-mev6
head-y := arch/alpha/kernel/head.o
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index ab6fa54b386..dccf05245d4 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -3,7 +3,7 @@
#
extra-y := head.o vmlinux.lds
-EXTRA_AFLAGS := $(CFLAGS)
+EXTRA_AFLAGS := $(KBUILD_CFLAGS)
EXTRA_CFLAGS := -Werror -Wno-sign-compare
obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index debc8f03886..5fc61e281ac 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -917,15 +917,6 @@ sys_pipe:
.end sys_pipe
.align 4
- .globl sys_ptrace
- .ent sys_ptrace
-sys_ptrace:
- .prologue 0
- mov $sp, $20
- jmp $31, do_sys_ptrace
-.end sys_ptrace
-
- .align 4
.globl sys_execve
.ent sys_execve
sys_execve:
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 83a78184226..1e9ad52c460 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -260,38 +260,12 @@ void ptrace_disable(struct task_struct *child)
ptrace_cancel_bpt(child);
}
-asmlinkage long
-do_sys_ptrace(long request, long pid, long addr, long data,
- struct pt_regs *regs)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
- struct task_struct *child;
unsigned long tmp;
size_t copied;
long ret;
- lock_kernel();
- DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
- request, pid, addr, data));
- if (request == PTRACE_TRACEME) {
- ret = ptrace_traceme();
- goto out_notsk;
- }
-
- child = ptrace_get_task_struct(pid);
- if (IS_ERR(child)) {
- ret = PTR_ERR(child);
- goto out_notsk;
- }
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- goto out;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret < 0)
- goto out;
-
switch (request) {
/* When I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -301,13 +275,13 @@ do_sys_ptrace(long request, long pid, long addr, long data,
if (copied != sizeof(tmp))
break;
- regs->r0 = 0; /* special return: no errors */
+ force_successful_syscall_return();
ret = tmp;
break;
/* Read register number ADDR. */
case PTRACE_PEEKUSR:
- regs->r0 = 0; /* special return: no errors */
+ force_successful_syscall_return();
ret = get_reg(child, addr);
DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
break;
@@ -353,7 +327,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
/* make sure single-step breakpoint is gone. */
ptrace_cancel_bpt(child);
wake_up_process(child);
- goto out;
+ break;
case PTRACE_SINGLESTEP: /* execute single instruction. */
ret = -EIO;
@@ -366,20 +340,12 @@ do_sys_ptrace(long request, long pid, long addr, long data,
wake_up_process(child);
/* give it a chance to run. */
ret = 0;
- goto out;
-
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- goto out;
+ break;
default:
ret = ptrace_request(child, request, addr, data);
- goto out;
+ break;
}
- out:
- put_task_struct(child);
- out_notsk:
- unlock_kernel();
return ret;
}
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 7af07d3ad5f..55c05b511f4 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -1,4 +1,5 @@
#include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
OUTPUT_FORMAT("elf64-alpha")
OUTPUT_ARCH(alpha)
@@ -8,138 +9,145 @@ jiffies = jiffies_64;
SECTIONS
{
#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
- . = 0xfffffc0000310000;
+ . = 0xfffffc0000310000;
#else
- . = 0xfffffc0001010000;
+ . = 0xfffffc0001010000;
#endif
- _text = .; /* Text and read-only data */
- .text : {
+ _text = .; /* Text and read-only data */
+ .text : {
*(.text.head)
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- *(.fixup)
- *(.gnu.warning)
- } :kernel
- _etext = .; /* End of text section */
-
- . = ALIGN(16);
- __start___ex_table = .; /* Exception table */
- __ex_table : { *(__ex_table) }
- __stop___ex_table = .;
-
- NOTES :kernel :note
- .dummy : { *(.dummy) } :kernel
-
- RODATA
-
- /* Will be freed after init */
- . = ALIGN(8192); /* Init code and data */
- __init_begin = .;
- .init.text : {
- _sinittext = .;
- *(.init.text)
- _einittext = .;
- }
- .init.data : { *(.init.data) }
-
- . = ALIGN(16);
- __setup_start = .;
- .init.setup : { *(.init.setup) }
- __setup_end = .;
-
- . = ALIGN(8);
- __initcall_start = .;
- .initcall.init : {
- INITCALLS
- }
- __initcall_end = .;
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ *(.fixup)
+ *(.gnu.warning)
+ } :kernel
+ _etext = .; /* End of text section */
+
+ /* Exception table */
+ . = ALIGN(16);
+ __ex_table : {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ NOTES :kernel :note
+ .dummy : {
+ *(.dummy)
+ } :kernel
+
+ RODATA
+
+ /* Will be freed after init */
+ . = ALIGN(PAGE_SIZE);
+ /* Init code and data */
+ __init_begin = .;
+ .init.text : {
+ _sinittext = .;
+ *(.init.text)
+ _einittext = .;
+ }
+ .init.data : {
+ *(.init.data)
+ }
+
+ . = ALIGN(16);
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ . = ALIGN(8);
+ .initcall.init : {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
#ifdef CONFIG_BLK_DEV_INITRD
- . = ALIGN(8192);
- __initramfs_start = .;
- .init.ramfs : { *(.init.ramfs) }
- __initramfs_end = .;
+ . = ALIGN(PAGE_SIZE);
+ .init.ramfs : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
#endif
- . = ALIGN(8);
- .con_initcall.init : {
- __con_initcall_start = .;
- *(.con_initcall.init)
- __con_initcall_end = .;
- }
-
- . = ALIGN(8);
- SECURITY_INIT
-
- PERCPU(8192)
-
- . = ALIGN(2*8192);
- __init_end = .;
- /* Freed after init ends here */
-
- /* Note 2 page alignment above. */
- .data.init_thread : { *(.data.init_thread) }
-
- . = ALIGN(8192);
- .data.page_aligned : { *(.data.page_aligned) }
-
- . = ALIGN(64);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
- _data = .;
- .data : { /* Data */
- DATA_DATA
- CONSTRUCTORS
- }
-
- .got : { *(.got) }
- .sdata : { *(.sdata) }
-
- _edata = .; /* End of data section */
-
- __bss_start = .;
- .sbss : { *(.sbss) *(.scommon) }
- .bss : { *(.bss) *(COMMON) }
- __bss_stop = .;
-
- _end = .;
-
- /* Sections to be discarded */
- /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) }
-
- .mdebug 0 : { *(.mdebug) }
- .note 0 : { *(.note) }
- .comment 0 : { *(.comment) }
-
- /* Stabs debugging sections */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
+ . = ALIGN(8);
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ . = ALIGN(8);
+ SECURITY_INIT
+
+ PERCPU(PAGE_SIZE)
+
+ . = ALIGN(2 * PAGE_SIZE);
+ __init_end = .;
+ /* Freed after init ends here */
+
+ /* Note 2 page alignment above. */
+ .data.init_thread : {
+ *(.data.init_thread)
+ }
+
+ . = ALIGN(PAGE_SIZE);
+ .data.page_aligned : {
+ *(.data.page_aligned)
+ }
+
+ . = ALIGN(64);
+ .data.cacheline_aligned : {
+ *(.data.cacheline_aligned)
+ }
+
+ _data = .;
+ /* Data */
+ .data : {
+ DATA_DATA
+ CONSTRUCTORS
+ }
+
+ .got : {
+ *(.got)
+ }
+ .sdata : {
+ *(.sdata)
+ }
+ _edata = .; /* End of data section */
+
+ __bss_start = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ __bss_stop = .;
+ _end = .;
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.exit.text)
+ *(.exit.data)
+ *(.exitcall.exit)
+ }
+
+ .mdebug 0 : {
+ *(.mdebug)
+ }
+ .note 0 : {
+ *(.note)
+ }
+
+ STABS_DEBUG
+ DWARF_DEBUG
}
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index 266f78e1307..9b72c59c95b 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -2,7 +2,7 @@
# Makefile for alpha-specific library files..
#
-EXTRA_AFLAGS := $(CFLAGS)
+EXTRA_AFLAGS := $(KBUILD_CFLAGS)
EXTRA_CFLAGS := -Werror
# Many of these routines have implementations tuned for ev6.
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index a0e18da594d..25154df3055 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -197,7 +197,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
current->comm, current->pid);
if (!user_mode(regs))
goto no_context;
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
do_sigbus:
/* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 691aae309c8..0a0c88d0039 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -318,6 +318,9 @@ config ARCH_KS8695
config ARCH_NS9XXX
bool "NetSilicon NS9xxx"
+ select GENERIC_GPIO
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
help
Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
System.
@@ -336,14 +339,14 @@ config ARCH_PNX4008
This enables support for Philips PNX4008 mobile platform.
config ARCH_PXA
- bool "PXA2xx-based"
+ bool "PXA2xx/PXA3xx-based"
depends on MMU
select ARCH_MTD_XIP
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
- Support for Intel's PXA2XX processor line.
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
config ARCH_RPC
bool "RiscPC"
@@ -486,7 +489,7 @@ source arch/arm/mm/Kconfig
config IWMMXT
bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3
- default y if PXA27x
+ default y if PXA27x || PXA3xx
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
@@ -994,6 +997,10 @@ source "drivers/pnp/Kconfig"
source "drivers/block/Kconfig"
+# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
+
+source "drivers/misc/Kconfig"
+
if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \
|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
@@ -1029,16 +1036,16 @@ source "drivers/spi/Kconfig"
source "drivers/w1/Kconfig"
+source "drivers/power/Kconfig"
+
source "drivers/hwmon/Kconfig"
-#source "drivers/l3/Kconfig"
+source "drivers/ssb/Kconfig"
-source "drivers/misc/Kconfig"
+#source "drivers/l3/Kconfig"
source "drivers/mfd/Kconfig"
-source "drivers/leds/Kconfig"
-
source "drivers/media/Kconfig"
source "drivers/video/Kconfig"
@@ -1051,6 +1058,8 @@ source "drivers/usb/Kconfig"
source "drivers/mmc/Kconfig"
+source "drivers/leds/Kconfig"
+
source "drivers/rtc/Kconfig"
source "drivers/dma/Kconfig"
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
index f087376748d..901e6dff843 100644
--- a/arch/arm/Kconfig-nommu
+++ b/arch/arm/Kconfig-nommu
@@ -26,7 +26,7 @@ config FLASH_SIZE
default 0x00400000
config PROCESSOR_ID
- hex
+ hex 'Hard wire the processor ID'
default 0x00007700
depends on !CPU_CP15
help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index fa4ea9ff079..35e56c99ad1 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -12,11 +12,11 @@
LDFLAGS_vmlinux :=-p --no-undefined -X
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
-OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
+OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9
-#CFLAGS +=-pipe
+#KBUILD_CFLAGS +=-pipe
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
-CFLAGS +=$(call cc-option,-marm,)
+KBUILD_CFLAGS +=$(call cc-option,-marm,)
# Do not use arch/arm/defconfig - it's always outdated.
# Select a platform tht is kept up-to-date
@@ -28,15 +28,15 @@ MMUEXT := -nommu
endif
ifeq ($(CONFIG_FRAME_POINTER),y)
-CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
+KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
endif
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
-CPPFLAGS += -mbig-endian
+KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
LD += -EB
else
-CPPFLAGS += -mlittle-endian
+KBUILD_CPPFLAGS += -mlittle-endian
AS += -EL
LD += -EL
endif
@@ -85,8 +85,8 @@ CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-th
endif
# Need -Uarm for gcc < 3.x
-CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
-AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
+KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
CHECKFLAGS += -D__arm__
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 6b8cbd69f24..5fde99f9d9f 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -87,7 +87,7 @@ ifneq ($(PARAMS_PHYS),)
LDFLAGS_vmlinux += --defsym params_phys=$(PARAMS_PHYS)
endif
LDFLAGS_vmlinux += -p --no-undefined -X \
- $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -T
+ $(shell $(CC) $(KBUILD_CFLAGS) --print-libgcc-file-name) -T
# Don't allow any static data in misc.o, which
# would otherwise mess up our GOT table
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 236bbe57831..67ea99ef652 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -33,10 +33,6 @@ __XScale_start:
bic r0, r0, #0x1000 @ clear Icache
mcr p15, 0, r0, c1, c0, 0
-#ifdef CONFIG_ARCH_LUBBOCK
- mov r7, #MACH_TYPE_LUBBOCK
-#endif
-
#ifdef CONFIG_ARCH_COTULLA_IDP
mov r7, #MACH_TYPE_COTULLA_IDP
#endif
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e1289a256ce..3d0b9fa42f8 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
+obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index b36b1e8a105..44ab0dad403 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -263,7 +263,7 @@ map_single(struct device *dev, void *ptr, size_t size,
* We don't need to sync the DMA buffer since
* it was allocated via the coherent allocators.
*/
- consistent_sync(ptr, size, dir);
+ dma_cache_maint(ptr, size, dir);
}
return dma_addr;
@@ -383,7 +383,7 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
* via the coherent allocators.
*/
} else {
- consistent_sync(dma_to_virt(dev, dma_addr), size, dir);
+ dma_cache_maint(dma_to_virt(dev, dma_addr), size, dir);
}
}
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
new file mode 100644
index 00000000000..c03de9bfd76
--- /dev/null
+++ b/arch/arm/common/it8152.c
@@ -0,0 +1,387 @@
+/*
+ * linux/arch/arm/common/it8152.c
+ *
+ * Copyright Compulab Ltd, 2002-2007
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * The DMA bouncing part is taken from arch/arm/mach-ixp4xx/common-pci.c
+ * (see this file for respective copyrights)
+ *
+ * Thanks to Guennadi Liakhovetski <gl@dsa-ac.de> for IRQ enumberation
+ * and demux code.
+ *
+ * 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.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/mach/pci.h>
+#include <asm/hardware/it8152.h>
+
+#define MAX_SLOTS 21
+
+static void it8152_mask_irq(unsigned int irq)
+{
+ if (irq >= IT8152_LD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) |
+ (1 << (irq - IT8152_LD_IRQ(0)))),
+ IT8152_INTC_LDCNIMR);
+ } else if (irq >= IT8152_LP_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LPCNIMR) |
+ (1 << (irq - IT8152_LP_IRQ(0)))),
+ IT8152_INTC_LPCNIMR);
+ } else if (irq >= IT8152_PD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_PDCNIMR) |
+ (1 << (irq - IT8152_PD_IRQ(0)))),
+ IT8152_INTC_PDCNIMR);
+ }
+}
+
+static void it8152_unmask_irq(unsigned int irq)
+{
+ if (irq >= IT8152_LD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) &
+ ~(1 << (irq - IT8152_LD_IRQ(0)))),
+ IT8152_INTC_LDCNIMR);
+ } else if (irq >= IT8152_LP_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LPCNIMR) &
+ ~(1 << (irq - IT8152_LP_IRQ(0)))),
+ IT8152_INTC_LPCNIMR);
+ } else if (irq >= IT8152_PD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_PDCNIMR) &
+ ~(1 << (irq - IT8152_PD_IRQ(0)))),
+ IT8152_INTC_PDCNIMR);
+ }
+}
+
+static inline void it8152_irq(int irq)
+{
+ struct irq_desc *desc;
+
+ printk(KERN_DEBUG "===> %s: irq=%d\n", __FUNCTION__, irq);
+
+ desc = irq_desc + irq;
+ desc_handle_irq(irq, desc);
+}
+
+static struct irq_chip it8152_irq_chip = {
+ .name = "it8152",
+ .ack = it8152_mask_irq,
+ .mask = it8152_mask_irq,
+ .unmask = it8152_unmask_irq,
+};
+
+void it8152_init_irq(void)
+{
+ int irq;
+
+ __raw_writel((0xffff), IT8152_INTC_PDCNIMR);
+ __raw_writel((0), IT8152_INTC_PDCNIRR);
+ __raw_writel((0xffff), IT8152_INTC_LPCNIMR);
+ __raw_writel((0), IT8152_INTC_LPCNIRR);
+ __raw_writel((0xffff), IT8152_INTC_LDCNIMR);
+ __raw_writel((0), IT8152_INTC_LDCNIRR);
+
+ for (irq = IT8152_IRQ(0); irq <= IT8152_LAST_IRQ; irq++) {
+ set_irq_chip(irq, &it8152_irq_chip);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+}
+
+void it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+ int bits_pd, bits_lp, bits_ld;
+ int i;
+
+ printk(KERN_DEBUG "=> %s: irq = %d\n", __FUNCTION__, irq);
+
+ while (1) {
+ /* Read all */
+ bits_pd = __raw_readl(IT8152_INTC_PDCNIRR);
+ bits_lp = __raw_readl(IT8152_INTC_LPCNIRR);
+ bits_ld = __raw_readl(IT8152_INTC_LDCNIRR);
+
+ /* Ack */
+ __raw_writel((~bits_pd), IT8152_INTC_PDCNIRR);
+ __raw_writel((~bits_lp), IT8152_INTC_LPCNIRR);
+ __raw_writel((~bits_ld), IT8152_INTC_LDCNIRR);
+
+ if (!(bits_ld | bits_lp | bits_pd)) {
+ /* Re-read to guarantee, that there was a moment of
+ time, when they all three were 0. */
+ bits_pd = __raw_readl(IT8152_INTC_PDCNIRR);
+ bits_lp = __raw_readl(IT8152_INTC_LPCNIRR);
+ if (!(bits_ld | bits_lp | bits_pd))
+ return;
+ }
+
+ bits_pd &= ((1 << IT8152_PD_IRQ_COUNT) - 1);
+ while (bits_pd) {
+ i = __ffs(bits_pd);
+ it8152_irq(IT8152_PD_IRQ(i));
+ bits_pd &= ~(1 << i);
+ }
+
+ bits_lp &= ((1 << IT8152_LP_IRQ_COUNT) - 1);
+ while (bits_lp) {
+ i = __ffs(bits_pd);
+ it8152_irq(IT8152_LP_IRQ(i));
+ bits_lp &= ~(1 << i);
+ }
+
+ bits_ld &= ((1 << IT8152_LD_IRQ_COUNT) - 1);
+ while (bits_ld) {
+ i = __ffs(bits_pd);
+ it8152_irq(IT8152_LD_IRQ(i));
+ bits_ld &= ~(1 << i);
+ }
+ }
+}
+
+/* mapping for on-chip devices */
+int __init it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if ((dev->vendor == PCI_VENDOR_ID_ITE) &&
+ (dev->device == PCI_DEVICE_ID_ITE_8152)) {
+ if ((dev->class >> 8) == PCI_CLASS_MULTIMEDIA_AUDIO)
+ return IT8152_AUDIO_INT;
+ if ((dev->class >> 8) == PCI_CLASS_SERIAL_USB)
+ return IT8152_USB_INT;
+ if ((dev->class >> 8) == PCI_CLASS_SYSTEM_DMA)
+ return IT8152_CDMA_INT;
+ }
+
+ return 0;
+}
+
+static unsigned long it8152_pci_dev_base_address(struct pci_bus *bus,
+ unsigned int devfn)
+{
+ unsigned long addr = 0;
+
+ if (bus->number == 0) {
+ if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+ addr = (devfn << 8);
+ } else
+ addr = (bus->number << 16) | (devfn << 8);
+
+ return addr;
+}
+
+static int it8152_pci_read_config(struct pci_bus *bus,
+ unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+ u32 v;
+ int shift;
+
+ shift = (where & 3);
+
+ __raw_writel((addr + where), IT8152_PCI_CFG_ADDR);
+ v = (__raw_readl(IT8152_PCI_CFG_DATA) >> (8 * (shift)));
+
+ *value = v;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int it8152_pci_write_config(struct pci_bus *bus,
+ unsigned int devfn, int where,
+ int size, u32 value)
+{
+ unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+ u32 v, vtemp, mask = 0;
+ int shift;
+
+ if (size == 1)
+ mask = 0xff;
+ if (size == 2)
+ mask = 0xffff;
+
+ shift = (where & 3);
+
+ __raw_writel((addr + where), IT8152_PCI_CFG_ADDR);
+ vtemp = __raw_readl(IT8152_PCI_CFG_DATA);
+
+ if (mask)
+ vtemp &= ~(mask << (8 * shift));
+ else
+ vtemp = 0;
+
+ v = (value << (8 * shift));
+ __raw_writel((addr + where), IT8152_PCI_CFG_ADDR);
+ __raw_writel((v | vtemp), IT8152_PCI_CFG_DATA);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops it8152_ops = {
+ .read = it8152_pci_read_config,
+ .write = it8152_pci_write_config,
+};
+
+static struct resource it8152_io = {
+ .name = "IT8152 PCI I/O region",
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource it8152_mem = {
+ .name = "IT8152 PCI memory region",
+ .start = 0x10000000,
+ .end = 0x13e00000,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * The following functions are needed for DMA bouncing.
+ * ITE8152 chip can addrees up to 64MByte, so all the devices
+ * connected to ITE8152 (PCI and USB) should have limited DMA window
+ */
+
+/*
+ * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all
+ * other devices.
+ */
+static int it8152_pci_platform_notify(struct device *dev)
+{
+ if (dev->bus == &pci_bus_type) {
+ if (dev->dma_mask)
+ *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
+ dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
+ dmabounce_register_dev(dev, 2048, 4096);
+ }
+ return 0;
+}
+
+static int it8152_pci_platform_notify_remove(struct device *dev)
+{
+ if (dev->bus == &pci_bus_type)
+ dmabounce_unregister_dev(dev);
+
+ return 0;
+}
+
+int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
+ __FUNCTION__, dma_addr, size);
+ return (dev->bus == &pci_bus_type) &&
+ ((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
+}
+
+/*
+ * We override these so we properly do dmabounce otherwise drivers
+ * are able to set the dma_mask to 0xffffffff and we can no longer
+ * trap bounces. :(
+ *
+ * We just return true on everyhing except for < 64MB in which case
+ * we will fail miseralby and die since we can't handle that case.
+ */
+int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ printk(KERN_DEBUG "%s: %s %llx\n",
+ __FUNCTION__, dev->dev.bus_id, mask);
+ if (mask >= PHYS_OFFSET + SZ_64M - 1)
+ return 0;
+
+ return -EIO;
+}
+
+int
+pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
+{
+ printk(KERN_DEBUG "%s: %s %llx\n",
+ __FUNCTION__, dev->dev.bus_id, mask);
+ if (mask >= PHYS_OFFSET + SZ_64M - 1)
+ return 0;
+
+ return -EIO;
+}
+
+int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ it8152_io.start = IT8152_IO_BASE + 0x12000;
+ it8152_io.end = IT8152_IO_BASE + 0x12000 + 0x100000;
+
+ sys->mem_offset = 0x10000000;
+ sys->io_offset = IT8152_IO_BASE;
+
+ if (request_resource(&ioport_resource, &it8152_io)) {
+ printk(KERN_ERR "PCI: unable to allocate IO region\n");
+ goto err0;
+ }
+ if (request_resource(&iomem_resource, &it8152_mem)) {
+ printk(KERN_ERR "PCI: unable to allocate memory region\n");
+ goto err1;
+ }
+
+ sys->resource[0] = &it8152_io;
+ sys->resource[1] = &it8152_mem;
+
+ if (platform_notify || platform_notify_remove) {
+ printk(KERN_ERR "PCI: Can't use platform_notify\n");
+ goto err2;
+ }
+
+ platform_notify = it8152_pci_platform_notify;
+ platform_notify_remove = it8152_pci_platform_notify_remove;
+
+ return 1;
+
+err2:
+ release_resource(&it8152_io);
+err1:
+ release_resource(&it8152_mem);
+err0:
+ return -EBUSY;
+}
+
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as we don't have even crappy BIOSes to set it properly.
+ * The implementation is from arch/i386/pci/i386.c
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+ u8 lat;
+
+ /* no need to update on-chip OHCI controller */
+ if ((dev->vendor == PCI_VENDOR_ID_ITE) &&
+ (dev->device == PCI_DEVICE_ID_ITE_8152) &&
+ ((dev->class >> 8) == PCI_CLASS_SERIAL_USB))
+ return;
+
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ if (lat < 16)
+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+ else if (lat > pcibios_max_latency)
+ lat = pcibios_max_latency;
+ else
+ return;
+ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
+ pci_name(dev), lat);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+
+struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(nr, &it8152_ops, sys);
+}
+
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 111a7fa5deb..5bba5255b11 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/apm-emulation.h>
+#include <linux/suspend.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -765,9 +766,9 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
info->battery_life = sharpsl_pm.battstat.mainbat_percent;
}
-static struct pm_ops sharpsl_pm_ops = {
+static struct platform_suspend_ops sharpsl_pm_ops = {
.enter = corgi_pxa_pm_enter,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
static int __init sharpsl_pm_probe(struct platform_device *pdev)
@@ -799,7 +800,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
apm_get_power_status = sharpsl_apm_get_power_status;
- pm_set_ops(&sharpsl_pm_ops);
+ suspend_set_ops(&sharpsl_pm_ops);
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
@@ -808,7 +809,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
static int sharpsl_pm_remove(struct platform_device *pdev)
{
- pm_set_ops(NULL);
+ suspend_set_ops(NULL);
device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
diff --git a/arch/arm/configs/cm_x270_defconfig b/arch/arm/configs/cm_x270_defconfig
new file mode 100644
index 00000000000..5cab08397ae
--- /dev/null
+++ b/arch/arm/configs/cm_x270_defconfig
@@ -0,0 +1,1410 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22
+# Wed Jul 18 14:11:48 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+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 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_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=17
+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=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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 is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+CONFIG_SHMEM=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_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+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
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+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"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_DMABOUNCE=y
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+CONFIG_MACH_ARMCORE=y
+CONFIG_PXA27x=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCI_HOST_ITE8152=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+# CONFIG_APM_EMULATION 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=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_ARPD is not set
+# 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=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_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=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_IEEE80211_SOFTMAC is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=m
+# 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_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# 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 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 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_H1900 is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_CAFE is not set
+CONFIG_MTD_NAND_CM_X270=m
+# 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
+# CONFIG_PARPORT 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
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=12000
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_IDE=m
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# 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 is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# 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 Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# 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_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
+# CONFIG_SCSI_AACRAID is not set
+# 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_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 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 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# 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
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+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_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+# CONFIG_SMC911X is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 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 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# 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_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# 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
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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
+# CONFIG_ISDN 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=y
+# 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=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_UCB1400=m
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+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
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_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
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM 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
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
+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
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_CM_X270=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB 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=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
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX 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_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+CONFIG_FB_MBX=m
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=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
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 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
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# 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
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# 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
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# 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
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=m
+CONFIG_SND_PXA2XX_AC97=m
+
+#
+# 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
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# 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
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# 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_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# 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_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
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_BOUNCE=y
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_TIFM_SD is not set
+
+#
+# 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
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+CONFIG_RTC_DRV_V3020=y
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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=y
+# 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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=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_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_JFFS2_FS 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=y
+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_ROOT_NFS=y
+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=y
+# 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
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# 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=y
+# 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 is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING 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=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+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 is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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 is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW 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
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# 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 is not set
+# CONFIG_CRYPTO_TEST 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/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index b0efd4ca993..b8a78ab49cd 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -1,41 +1,58 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Thu Jun 29 15:25:18 2006
+# Linux kernel version: 2.6.23-rc6
+# Mon Sep 17 14:21:45 2007
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
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 is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
-CONFIG_UID16=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
@@ -44,27 +61,30 @@ 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_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=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 is not set
# 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
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -86,7 +106,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
@@ -96,11 +116,16 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
@@ -108,6 +133,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
CONFIG_ARCH_OMAP=y
#
@@ -124,6 +150,7 @@ CONFIG_ARCH_OMAP1=y
CONFIG_OMAP_MUX=y
# CONFIG_OMAP_MUX_DEBUG is not set
CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
# CONFIG_OMAP_MPU_TIMER is not set
CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_32K_TIMER_HZ=128
@@ -162,6 +189,14 @@ CONFIG_OMAP_ARM_192MHZ=y
# CONFIG_OMAP_ARM_30MHZ is not set
#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
# Processor Type
#
CONFIG_CPU_32=y
@@ -171,6 +206,8 @@ CONFIG_CPU_ABRT_EV5TJ=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
@@ -180,10 +217,13 @@ CONFIG_ARM_THUMB=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
#
# Bus support
#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -193,10 +233,13 @@ CONFIG_ARM_THUMB=y
#
# Kernel Features
#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
-CONFIG_NO_IDLE_HZ=y
CONFIG_HZ=128
-# CONFIG_AEABI is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -206,6 +249,10 @@ 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=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
# CONFIG_LEDS is not set
CONFIG_ALIGNMENT_TRAP=y
@@ -216,6 +263,7 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=0801 ro init=/bin/sh"
# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
#
# CPU Frequency scaling
@@ -251,7 +299,6 @@ CONFIG_FPE_NWFPE=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_AOUT=y
# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
#
# Power management options
@@ -259,7 +306,10 @@ CONFIG_BINFMT_AOUT=y
CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
-# CONFIG_APM is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
#
# Networking
@@ -269,12 +319,13 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
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
@@ -295,29 +346,20 @@ CONFIG_IP_PNP_BOOTP=y
# 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_BIC=y
+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_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
@@ -328,7 +370,6 @@ CONFIG_TCP_CONG_BIC=y
# 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
@@ -344,7 +385,17 @@ CONFIG_TCP_CONG_BIC=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_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -357,29 +408,10 @@ 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
-
-#
-# 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_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -387,7 +419,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
CONFIG_ATA_OVER_ETH=m
@@ -396,6 +428,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
#
@@ -414,82 +449,42 @@ CONFIG_SCSI_PROC_FS=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 is not set
# 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_SCSI_SATA is not set
# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_ATA is not set
# 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
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 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 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_PPP=y
# CONFIG_PPP_MULTILINK is not set
@@ -500,24 +495,24 @@ CONFIG_PPP=y
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=y
# CONFIG_SLIP_SMART is not set
# CONFIG_SLIP_MODE_SLIP6 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
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -537,8 +532,14 @@ CONFIG_INPUT_EVBUG=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=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=y
#
@@ -574,15 +575,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
@@ -590,25 +583,12 @@ CONFIG_WATCHDOG_NOWAYOUT=y
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_OMAP_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
# CONFIG_I2C is not set
#
@@ -616,61 +596,70 @@ CONFIG_WATCHDOG_NOWAYOUT=y
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_W1 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_F71805F is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
#
-# Misc devices
-#
-
-#
-# LED devices
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
# CONFIG_NEW_LEDS is not set
#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
# CONFIG_FB_CFB_FILLRECT is not set
# CONFIG_FB_CFB_COPYAREA is not set
# CONFIG_FB_CFB_IMAGEBLIT is not set
+# 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 is not set
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_OMAP is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -679,6 +668,7 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
@@ -691,15 +681,10 @@ 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=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -717,10 +702,10 @@ CONFIG_SOUND=y
CONFIG_SOUND_PRIME=y
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
-
-#
-# USB support
-#
+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 is not set
@@ -734,17 +719,22 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
#
-# MMC/SD Card support
+# DMA Engine support
#
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
#
-# Real Time Clock
+# DMA Clients
+#
+
+#
+# DMA Devices
#
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
#
# File systems
@@ -753,10 +743,12 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP 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=y
@@ -787,6 +779,7 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
@@ -825,6 +818,7 @@ CONFIG_LOCKD_V4=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 is not set
# CONFIG_SMB_FS is not set
@@ -832,7 +826,6 @@ CONFIG_RPCSEC_GSS_KRB5=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
@@ -885,6 +878,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -893,13 +891,14 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+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 is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
-# CONFIG_UNWIND_INFO is not set
# CONFIG_DEBUG_USER is not set
#
@@ -907,12 +906,12 @@ CONFIG_FRAME_POINTER=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY 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_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
@@ -921,7 +920,14 @@ CONFIG_CRYPTO_MD5=y
# 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=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -935,17 +941,22 @@ CONFIG_CRYPTO_DES=y
# 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_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_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/omap_osk_5912_defconfig b/arch/arm/configs/omap_osk_5912_defconfig
new file mode 100644
index 00000000000..8c1f15c7c45
--- /dev/null
+++ b/arch/arm/configs/omap_osk_5912_defconfig
@@ -0,0 +1,1073 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.23-rc6
+# Mon Sep 17 14:15:05 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS 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_SYSFS_DEPRECATED is not set
+# 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_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_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=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_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
+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
+#
+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"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+CONFIG_ARCH_OMAP1=y
+# CONFIG_ARCH_OMAP2 is not set
+
+#
+# OMAP Feature Selections
+#
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+# CONFIG_OMAP_DM_TIMER is not set
+CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_SERIAL_WAKE=y
+
+#
+# OMAP Core Type
+#
+# CONFIG_ARCH_OMAP730 is not set
+# CONFIG_ARCH_OMAP15XX is not set
+CONFIG_ARCH_OMAP16XX=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP_INNOVATOR is not set
+# CONFIG_MACH_OMAP_H2 is not set
+# CONFIG_MACH_OMAP_H3 is not set
+CONFIG_MACH_OMAP_OSK=y
+# CONFIG_OMAP_OSK_MISTRAL is not set
+# CONFIG_MACH_NOKIA770 is not set
+# CONFIG_MACH_OMAP_GENERIC is not set
+
+#
+# OMAP CPU Speed
+#
+# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set
+# CONFIG_OMAP_ARM_216MHZ is not set
+CONFIG_OMAP_ARM_192MHZ=y
+# CONFIG_OMAP_ARM_168MHZ is not set
+# CONFIG_OMAP_ARM_120MHZ is not set
+# CONFIG_OMAP_ARM_60MHZ is not set
+# CONFIG_OMAP_ARM_30MHZ is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+CONFIG_OMAP_CF=y
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x10400000,8M root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+# CONFIG_APM_EMULATION is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+# 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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+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 is not set
+# CONFIG_ARPD is not set
+# 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=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_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
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+# 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=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+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=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# 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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_OMAP_NOR=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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 is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+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 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+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_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# 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_NET_PCMCIA is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+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
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# 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_OMAP=y
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+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
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_OMAP=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 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 is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# 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_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM 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_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TPS65010=y
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 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 is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 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
+# 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_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_LM93 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_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_THMC50 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
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_NEW_LEDS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# 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=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# 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 is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_OMAP is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+# CONFIG_SOUND 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 is not set
+# 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_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP 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=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# 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_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# 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_JFFS2_FS=y
+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=y
+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_ROOT_NFS=y
+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
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_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=m
+# 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=m
+# 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 is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# 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_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+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/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index a2dd930d11e..e5747547b44 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -279,6 +279,25 @@ static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
+static void __init pci_fixup_it8152(struct pci_dev *dev)
+{
+ int i;
+ /* fixup for ITE 8152 devices */
+ /* FIXME: add defines for class 0x68000 and 0x80103 */
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST ||
+ dev->class == 0x68000 ||
+ dev->class == 0x80103) {
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152);
+
+
+
void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
{
if (debug_pci)
@@ -292,9 +311,12 @@ void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
*/
static inline int pdev_bad_for_parity(struct pci_dev *dev)
{
- return (dev->vendor == PCI_VENDOR_ID_INTERG &&
- (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
- dev->device == PCI_DEVICE_ID_INTERG_2010));
+ return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
+ (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+ dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
+ (dev->vendor == PCI_VENDOR_ID_ITE &&
+ dev->device == PCI_DEVICE_ID_ITE_8152));
+
}
/*
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index a98d0c933db..cecf658e362 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -361,6 +361,7 @@
CALL(sys_signalfd)
/* 350 */ CALL(sys_timerfd)
CALL(sys_eventfd)
+ CALL(sys_fallocate)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 78c9f1a3d41..5feee722ea9 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -731,10 +731,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *)data);
break;
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 7baadae7cb2..062c111c572 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -7,6 +7,23 @@
.globl relocate_new_kernel
relocate_new_kernel:
+ /* Move boot params back to where the kernel expects them */
+
+ ldr r0,kexec_boot_params_address
+ teq r0,#0
+ beq 8f
+
+ ldr r1,kexec_boot_params_copy
+ mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
+7:
+ ldr r5,[r1],#4
+ str r5,[r0],#4
+ subs r6,r6,#1
+ bne 7b
+
+8:
+ /* Boot params moved, now go on with the kernel */
+
ldr r0,kexec_indirection_page
ldr r1,kexec_start_address
@@ -50,7 +67,7 @@ relocate_new_kernel:
mov lr,r1
mov r0,#0
ldr r1,kexec_mach_type
- mov r2,#0
+ ldr r2,kexec_boot_params_address
mov pc,lr
.globl kexec_start_address
@@ -65,6 +82,16 @@ kexec_indirection_page:
kexec_mach_type:
.long 0x0
+ /* phy addr where new kernel will expect to find boot params */
+ .globl kexec_boot_params_address
+kexec_boot_params_address:
+ .long 0x0
+
+ /* phy addr where old kernel put a copy of orig boot params */
+ .globl kexec_boot_params_copy
+kexec_boot_params_copy:
+ .long 0x0
+
relocate_new_kernel_end:
.globl relocate_new_kernel_size
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 4de432ec903..bf56eb337df 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -24,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/fs.h>
+#include <linux/kexec.h>
#include <asm/cpu.h>
#include <asm/elf.h>
@@ -304,10 +305,23 @@ int cpu_architecture(void)
cpu_arch = (processor_id >> 16) & 7;
if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3;
- } else {
- /* the revised CPUID */
- cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6;
- }
+ } else if ((processor_id & 0x000f0000) == 0x000f0000) {
+ unsigned int mmfr0;
+
+ /* Revised CPUID format. Read the Memory Model Feature
+ * Register 0 and check for VMSAv7 or PMSAv7 */
+ asm("mrc p15, 0, %0, c0, c1, 4"
+ : "=r" (mmfr0));
+ if ((mmfr0 & 0x0000000f) == 0x00000003 ||
+ (mmfr0 & 0x000000f0) == 0x00000030)
+ cpu_arch = CPU_ARCH_ARMv7;
+ else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
+ (mmfr0 & 0x000000f0) == 0x00000020)
+ cpu_arch = CPU_ARCH_ARMv6;
+ else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+ } else
+ cpu_arch = CPU_ARCH_UNKNOWN;
return cpu_arch;
}
@@ -770,6 +784,23 @@ static int __init customize_machine(void)
}
arch_initcall(customize_machine);
+#ifdef CONFIG_KEXEC
+
+/* Physical addr of where the boot params should be for this machine */
+extern unsigned long kexec_boot_params_address;
+
+/* Physical addr of the buffer into which the boot params are copied */
+extern unsigned long kexec_boot_params_copy;
+
+/* Pointer to the boot params buffer, for manipulation and display */
+unsigned long kexec_boot_params;
+EXPORT_SYMBOL(kexec_boot_params);
+
+/* The buffer itself - make sure it is sized correctly */
+static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
+
+#endif
+
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = (struct tag *)&init_tags;
@@ -788,6 +819,18 @@ void __init setup_arch(char **cmdline_p)
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params);
+#ifdef CONFIG_KEXEC
+ kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
+ kexec_boot_params = (unsigned long)kexec_boot_params_buf;
+ if (__atags_pointer) {
+ kexec_boot_params_address = __atags_pointer;
+ memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
+ } else if (mdesc->boot_params) {
+ kexec_boot_params_address = mdesc->boot_params;
+ memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
+ }
+#endif
+
/*
* If we have the old style parameters, convert them to
* a tag list.
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 4d25e49a14f..9bd1870d980 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -26,9 +26,9 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
unsigned long new_len, unsigned long flags,
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index 8e2f9bc3368..e8b98046895 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -80,7 +80,7 @@
#include <linux/sem.h>
#include <linux/socket.h>
#include <linux/net.h>
-#include <asm/ipc.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
struct oldabi_stat64 {
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index a31157f1655..05a9f8a1b45 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -7,6 +7,8 @@ choice
config ARCH_AT91RM9200
bool "AT91RM9200"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
config ARCH_AT91SAM9260
bool "AT91SAM9260 or AT91SAM9XE"
@@ -20,8 +22,15 @@ config ARCH_AT91SAM9263
config ARCH_AT91SAM9RL
bool "AT91SAM9RL"
+config ARCH_AT91X40
+ bool "AT91x40"
+
endchoice
+config AT91_PMC_UNIT
+ bool
+ default !ARCH_AT91X40
+
# ----------------------------------------------------------
if ARCH_AT91RM9200
@@ -169,6 +178,22 @@ endif
# ----------------------------------------------------------
+if ARCH_AT91X40
+
+comment "AT91X40 Board Type"
+
+config MACH_AT91EB01
+ bool "Atmel AT91EB01 Evaluation Kit"
+ help
+ Select this if you are using Atmel's AT91EB01 Evaluation Kit.
+ It is also a popular target for simulators such as GDB's
+ ARM simulator (commonly known as the ARMulator) and the
+ Skyeye simulator.
+
+endif
+
+# ----------------------------------------------------------
+
comment "AT91 Board Options"
config MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index a4d80eb056e..a21f08c64ea 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,11 +2,12 @@
# Makefile for the linux kernel.
#
-obj-y := clock.o irq.o gpio.o
+obj-y := irq.o gpio.o
obj-m :=
obj-n :=
obj- :=
+obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
obj-$(CONFIG_PM) += pm.o
# CPU-specific support
@@ -15,6 +16,7 @@ obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_d
obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o
+obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
# AT91RM9200 board-specific support
obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
@@ -27,6 +29,7 @@ obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
obj-$(CONFIG_MACH_KAFA) += board-kafa.o
obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
+obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
# AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index a6340357585..50392ff7151 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -19,70 +19,64 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
+#include <linux/clockchips.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
#include <asm/mach/time.h>
#include <asm/arch/at91_st.h>
static unsigned long last_crtr;
+static u32 irqmask;
+static struct clock_event_device clkevt;
/*
- * The ST_CRTR is updated asynchronously to the master clock. It is therefore
- * necessary to read it twice (with the same value) to ensure accuracy.
+ * The ST_CRTR is updated asynchronously to the master clock ... but
+ * the updates as seen by the CPU don't seem to be strictly monotonic.
+ * Waiting until we read the same value twice avoids glitching.
*/
-static inline unsigned long read_CRTR(void) {
+static inline unsigned long read_CRTR(void)
+{
unsigned long x1, x2;
+ x1 = at91_sys_read(AT91_ST_CRTR);
do {
- x1 = at91_sys_read(AT91_ST_CRTR);
x2 = at91_sys_read(AT91_ST_CRTR);
- } while (x1 != x2);
-
+ if (x1 == x2)
+ break;
+ x1 = x2;
+ } while (1);
return x1;
}
/*
- * Returns number of microseconds since last timer interrupt. Note that interrupts
- * will have been disabled by do_gettimeofday()
- * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
- * 'tick' is usecs per jiffy (linux/timex.h).
- */
-static unsigned long at91rm9200_gettimeoffset(void)
-{
- unsigned long elapsed;
-
- elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV;
-
- return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
-}
-
-/*
* IRQ handler for the timer.
*/
static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
{
- if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */
- write_seqlock(&xtime_lock);
+ u32 sr = at91_sys_read(AT91_ST_SR) & irqmask;
- while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) {
- timer_tick();
- last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV;
- }
+ /* simulate "oneshot" timer with alarm */
+ if (sr & AT91_ST_ALMS) {
+ clkevt.event_handler(&clkevt);
+ return IRQ_HANDLED;
+ }
- write_sequnlock(&xtime_lock);
+ /* periodic mode should handle delayed ticks */
+ if (sr & AT91_ST_PITS) {
+ u32 crtr = read_CRTR();
+ while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) {
+ last_crtr += LATCH;
+ clkevt.event_handler(&clkevt);
+ }
return IRQ_HANDLED;
}
- else
- return IRQ_NONE; /* not handled */
+
+ /* this irq is shared ... */
+ return IRQ_NONE;
}
static struct irqaction at91rm9200_timer_irq = {
@@ -91,56 +85,127 @@ static struct irqaction at91rm9200_timer_irq = {
.handler = at91rm9200_timer_interrupt
};
-void at91rm9200_timer_reset(void)
+static cycle_t read_clk32k(void)
{
- last_crtr = 0;
+ return read_CRTR();
+}
- /* Real time counter incremented every 30.51758 microseconds */
- at91_sys_write(AT91_ST_RTMR, 1);
+static struct clocksource clk32k = {
+ .name = "32k_counter",
+ .rating = 150,
+ .read = read_clk32k,
+ .mask = CLOCKSOURCE_MASK(20),
+ .shift = 10,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void
+clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ /* Disable and flush pending timer interrupts */
+ at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
+ (void) at91_sys_read(AT91_ST_SR);
- /* Set Period Interval timer */
- at91_sys_write(AT91_ST_PIMR, LATCH);
+ last_crtr = read_CRTR();
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* PIT for periodic irqs; fixed rate of 1/HZ */
+ irqmask = AT91_ST_PITS;
+ at91_sys_write(AT91_ST_PIMR, LATCH);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* ALM for oneshot irqs, set by next_event()
+ * before 32 seconds have passed
+ */
+ irqmask = AT91_ST_ALMS;
+ at91_sys_write(AT91_ST_RTAR, last_crtr);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ irqmask = 0;
+ break;
+ }
+ at91_sys_write(AT91_ST_IER, irqmask);
+}
- /* Clear any pending interrupts */
+static int
+clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+ unsigned long flags;
+ u32 alm;
+ int status = 0;
+
+ BUG_ON(delta < 2);
+
+ /* Use "raw" primitives so we behave correctly on RT kernels. */
+ raw_local_irq_save(flags);
+
+ /* The alarm IRQ uses absolute time (now+delta), not the relative
+ * time (delta) in our calling convention. Like all clockevents
+ * using such "match" hardware, we have a race to defend against.
+ *
+ * Our defense here is to have set up the clockevent device so the
+ * delta is at least two. That way we never end up writing RTAR
+ * with the value then held in CRTR ... which would mean the match
+ * wouldn't trigger until 32 seconds later, after CRTR wraps.
+ */
+ alm = read_CRTR();
+
+ /* Cancel any pending alarm; flush any pending IRQ */
+ at91_sys_write(AT91_ST_RTAR, alm);
(void) at91_sys_read(AT91_ST_SR);
- /* Enable Period Interval Timer interrupt */
- at91_sys_write(AT91_ST_IER, AT91_ST_PITS);
+ /* Schedule alarm by writing RTAR. */
+ alm += delta;
+ at91_sys_write(AT91_ST_RTAR, alm);
+
+ raw_local_irq_restore(flags);
+ return status;
}
+static struct clock_event_device clkevt = {
+ .name = "at91_tick",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 150,
+ .cpumask = CPU_MASK_CPU0,
+ .set_next_event = clkevt32k_next_event,
+ .set_mode = clkevt32k_mode,
+};
+
/*
- * Set up timer interrupt.
+ * ST (system timer) module supports both clockevents and clocksource.
*/
void __init at91rm9200_timer_init(void)
{
- /* Disable all timer interrupts */
- at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
- (void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */
+ /* Disable all timer interrupts, and clear any pending ones */
+ at91_sys_write(AT91_ST_IDR,
+ AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
+ (void) at91_sys_read(AT91_ST_SR);
/* Make IRQs happen for the system timer */
setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
- /* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */
- tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE;
+ /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
+ * directly for the clocksource and all clockevents, after adjusting
+ * its prescaler from the 1 Hz default.
+ */
+ at91_sys_write(AT91_ST_RTMR, 1);
- /* Initialize and enable the timer interrupt */
- at91rm9200_timer_reset();
-}
+ /* Setup timer clockevent, with minimum of two ticks (important!!) */
+ clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
+ clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
+ clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
+ clkevt.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&clkevt);
-#ifdef CONFIG_PM
-static void at91rm9200_timer_suspend(void)
-{
- /* disable Period Interval Timer interrupt */
- at91_sys_write(AT91_ST_IDR, AT91_ST_PITS);
+ /* register clocksource */
+ clk32k.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, clk32k.shift);
+ clocksource_register(&clk32k);
}
-#else
-#define at91rm9200_timer_suspend NULL
-#endif
struct sys_timer at91rm9200_timer = {
.init = at91rm9200_timer_init,
- .offset = at91rm9200_gettimeoffset,
- .suspend = at91rm9200_timer_suspend,
- .resume = at91rm9200_timer_reset,
};
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c
new file mode 100644
index 00000000000..1de121fc55f
--- /dev/null
+++ b/arch/arm/mach-at91/at91x40.c
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-at91/at91x40.c
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/at91x40.h>
+#include <asm/arch/at91_st.h>
+#include "generic.h"
+
+/*
+ * This is used in the gpio code, stub locally.
+ */
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+
+void __init at91x40_initialize(unsigned long main_clock)
+{
+ at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
+ | (1 << AT91X40_ID_IRQ2);
+}
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller (FIQ) */
+ 0, /* System Peripherals */
+ 0, /* USART 0 */
+ 0, /* USART 1 */
+ 2, /* Timer Counter 0 */
+ 2, /* Timer Counter 1 */
+ 2, /* Timer Counter 2 */
+ 0, /* Watchdog timer */
+ 0, /* Parallel IO Controller A */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* External IRQ0 */
+ 0, /* External IRQ1 */
+ 0, /* External IRQ2 */
+};
+
+void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91x40_default_irq_priority;
+
+ at91_aic_init(priority);
+}
+
diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c
new file mode 100644
index 00000000000..eddc882f1b4
--- /dev/null
+++ b/arch/arm/mach-at91/at91x40_time.c
@@ -0,0 +1,80 @@
+/*
+ * arch/arm/mach-at91/at91x40_time.c
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/time.h>
+#include <asm/arch/at91_tc.h>
+
+/*
+ * 3 counter/timer units present.
+ */
+#define AT91_TC_CLK0BASE 0
+#define AT91_TC_CLK1BASE 0x40
+#define AT91_TC_CLK2BASE 0x80
+
+static unsigned long at91x40_gettimeoffset(void)
+{
+ return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128));
+}
+
+static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id)
+{
+ at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR);
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction at91x40_timer_irq = {
+ .name = "at91_tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = at91x40_timer_interrupt
+};
+
+void __init at91x40_timer_init(void)
+{
+ unsigned int v;
+
+ at91_sys_write(AT91_TC + AT91_TC_BCR, 0);
+ v = at91_sys_read(AT91_TC + AT91_TC_BMR);
+ v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE;
+ at91_sys_write(AT91_TC + AT91_TC_BMR, v);
+
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));
+
+ setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq);
+
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
+}
+
+struct sys_timer at91x40_timer = {
+ .init = at91x40_timer_init,
+ .offset = at91x40_gettimeoffset,
+};
+
diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c
new file mode 100644
index 00000000000..0c1e3858e7d
--- /dev/null
+++ b/arch/arm/mach-at91/board-eb01.c
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-at91/board-eb01.c
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/arch/board.h>
+#include "generic.h"
+
+static void __init at91eb01_map_io(void)
+{
+ at91x40_initialize(40000000);
+}
+
+MACHINE_START(AT91EB01, "Atmel AT91 EB01")
+ /* Maintainer: Greg Ungerer <gerg@snapgear.com> */
+ .timer = &at91x40_timer,
+ .init_irq = at91x40_init_interrupts,
+ .map_io = at91eb01_map_io,
+MACHINE_END
+
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 68ed71a3e6c..77d4c0a3784 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
extern void __init at91sam9261_initialize(unsigned long main_clock);
extern void __init at91sam9263_initialize(unsigned long main_clock);
extern void __init at91sam9rl_initialize(unsigned long main_clock);
+extern void __init at91x40_initialize(unsigned long main_clock);
/* Interrupts */
extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
@@ -21,12 +22,14 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
+extern void __init at91x40_init_interrupts(unsigned int priority[]);
extern void __init at91_aic_init(unsigned int priority[]);
/* Timer */
struct sys_timer;
extern struct sys_timer at91rm9200_timer;
extern struct sys_timer at91sam926x_timer;
+extern struct sys_timer at91x40_timer;
/* Clocks */
extern int __init at91_clock_init(unsigned long main_clock);
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index ddf9184d561..98cb6148291 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -10,10 +10,9 @@
* (at your option) any later version.
*/
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
-#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
@@ -199,7 +198,7 @@ error:
}
-static struct pm_ops at91_pm_ops ={
+static struct platform_suspend_ops at91_pm_ops ={
.valid = at91_pm_valid_state,
.set_target = at91_pm_set_target,
.enter = at91_pm_enter,
@@ -220,7 +219,7 @@ static int __init at91_pm_init(void)
/* Disable SDRAM low-power mode. Cannot be used with self-refresh. */
at91_sys_write(AT91_SDRAMC_LPR, 0);
- pm_set_ops(&at91_pm_ops);
+ suspend_set_ops(&at91_pm_ops);
return 0;
}
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 4dde34f25e6..986205ec926 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -193,7 +193,11 @@ static struct irq_chip clps7500_no_chip = {
.unmask = cl7500_no_action,
};
-static struct irqaction irq_isa = { no_action, 0, CPU_MASK_NONE, "isa", NULL, NULL };
+static struct irqaction irq_isa = {
+ .handler = no_action,
+ .mask = CPU_MASK_NONE,
+ .name = "isa",
+};
static void __init clps7500_init_irq(void)
{
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 575a21dabd2..ea8549bfbef 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -27,6 +27,12 @@ config MACH_EDB9302A
Say 'Y' here if you want your kernel to support the Cirrus
Logic EDB9302A Evaluation Board.
+config MACH_EDB9307
+ bool "Support Cirrus Logic EDB9307"
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9307 Evaluation Board.
+
config MACH_EDB9312
bool "Support Cirrus Logic EDB9312"
help
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index 0d3bf932654..0ecf99761fe 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -9,6 +9,7 @@ obj- :=
obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
obj-$(CONFIG_MACH_EDB9302) += edb9302.o
obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o
+obj-$(CONFIG_MACH_EDB9307) += edb9307.o
obj-$(CONFIG_MACH_EDB9312) += edb9312.o
obj-$(CONFIG_MACH_EDB9315) += edb9315.o
obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o
diff --git a/arch/arm/mach-ep93xx/edb9307.c b/arch/arm/mach-ep93xx/edb9307.c
new file mode 100644
index 00000000000..d6a5698da91
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb9307.c
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mach-ep93xx/edb9307.c
+ * Cirrus Logic EDB9307 support.
+ *
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data edb9307_flash_data = {
+ .width = 4,
+};
+
+static struct resource edb9307_flash_resource = {
+ .start = 0x60000000,
+ .end = 0x61ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device edb9307_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &edb9307_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &edb9307_flash_resource,
+};
+
+static struct ep93xx_eth_data edb9307_eth_data = {
+ .phy_id = 1,
+};
+
+static struct resource edb9307_eth_resource[] = {
+ {
+ .start = EP93XX_ETHERNET_PHYS_BASE,
+ .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_EP93XX_ETHERNET,
+ .end = IRQ_EP93XX_ETHERNET,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device edb9307_eth_device = {
+ .name = "ep93xx-eth",
+ .id = -1,
+ .dev = {
+ .platform_data = &edb9307_eth_data,
+ },
+ .num_resources = 2,
+ .resource = edb9307_eth_resource,
+};
+
+static void __init edb9307_init_machine(void)
+{
+ ep93xx_init_devices();
+ platform_device_register(&edb9307_flash);
+
+ memcpy(edb9307_eth_data.dev_addr,
+ (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
+ platform_device_register(&edb9307_eth_device);
+}
+
+MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
+ /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
+ .phys_io = EP93XX_APB_PHYS_BASE,
+ .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb9307_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
index ef6ccc8993e..c261472208c 100644
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -78,9 +78,9 @@ static void __init
fixup_cats(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
- ORIG_VIDEO_LINES = 25;
- ORIG_VIDEO_POINTS = 16;
- ORIG_Y = 24;
+ screen_info.orig_video_lines = 25;
+ screen_info.orig_video_points = 16;
+ screen_info.orig_y = 24;
}
MACHINE_START(CATS, "Chalice-CATS")
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
index 28846c7edaa..725a219d0ed 100644
--- a/arch/arm/mach-footbridge/isa.c
+++ b/arch/arm/mach-footbridge/isa.c
@@ -12,6 +12,39 @@
#include <asm/irq.h>
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = 0x70,
+ .end = 0x73,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = IRQ_ISA_RTC_ALARM,
+ .end = IRQ_ISA_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = rtc_resources,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+};
+
+static struct resource serial_resources[] = {
+ [0] = {
+ .start = 0x3f8,
+ .end = 0x3ff,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = 0x2f8,
+ .end = 0x2ff,
+ .flags = IORESOURCE_IO,
+ },
+};
+
static struct plat_serial8250_port serial_platform_data[] = {
{
.iobase = 0x3f8,
@@ -38,11 +71,21 @@ static struct platform_device serial_device = {
.dev = {
.platform_data = serial_platform_data,
},
+ .resource = serial_resources,
+ .num_resources = ARRAY_SIZE(serial_resources),
};
static int __init footbridge_isa_init(void)
{
- return platform_device_register(&serial_device);
+ int err;
+
+ err = platform_device_register(&rtc_device);
+ if (err)
+ printk(KERN_ERR "Unable to register RTC device: %d\n", err);
+ err = platform_device_register(&serial_device);
+ if (err)
+ printk(KERN_ERR "Unable to register serial device: %d\n", err);
+ return 0;
}
arch_initcall(footbridge_isa_init);
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
index 4476411b814..6fb82b855a5 100644
--- a/arch/arm/mach-ns9xxx/Makefile
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -1,4 +1,4 @@
-obj-y := irq.o time.o generic.o
+obj-y := irq.o time.o generic.o gpio.o
obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index 925048e7adf..0f65177f9e5 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -13,6 +13,7 @@
#include <linux/irq.h>
#include <asm/mach/map.h>
+#include <asm/gpio.h>
#include <asm/arch-ns9xxx/board.h>
#include <asm/arch-ns9xxx/regs-sys.h>
@@ -44,7 +45,13 @@ static void a9m9750dev_fpga_ack_irq(unsigned int irq)
static void a9m9750dev_fpga_mask_irq(unsigned int irq)
{
- FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0)));
+ u8 ier;
+
+ ier = __raw_readb(FPGA_IER);
+
+ ier &= ~(1 << (irq - FPGA_IRQ(0)));
+
+ __raw_writeb(ier, FPGA_IER);
}
static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
@@ -55,7 +62,13 @@ static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
{
- FPGA_IER |= 1 << (irq - FPGA_IRQ(0));
+ u8 ier;
+
+ ier = __raw_readb(FPGA_IER);
+
+ ier |= 1 << (irq - FPGA_IRQ(0));
+
+ __raw_writeb(ier, FPGA_IER);
}
static struct irq_chip a9m9750dev_fpga_chip = {
@@ -68,30 +81,34 @@ static struct irq_chip a9m9750dev_fpga_chip = {
static void a9m9750dev_fpga_demux_handler(unsigned int irq,
struct irq_desc *desc)
{
- int stat = FPGA_ISR;
+ u8 stat = __raw_readb(FPGA_ISR);
+
+ desc->chip->mask_ack(irq);
while (stat != 0) {
int irqno = fls(stat) - 1;
+ struct irq_desc *fpgadesc;
stat &= ~(1 << irqno);
- desc = irq_desc + FPGA_IRQ(irqno);
+ fpgadesc = irq_desc + FPGA_IRQ(irqno);
- desc_handle_irq(FPGA_IRQ(irqno), desc);
+ desc_handle_irq(FPGA_IRQ(irqno), fpgadesc);
}
+
+ desc->chip->unmask(irq);
}
void __init board_a9m9750dev_init_irq(void)
{
- u32 reg;
+ u32 eic;
int i;
- /*
- * configure gpio for IRQ_EXT2
- * use GPIO 11, because GPIO 32 is used for the LCD
- */
- /* XXX: proper GPIO handling */
- BBU_GCONFb1(1) &= ~0x2000;
+ if (gpio_request(11, "board a9m9750dev extirq2") == 0)
+ ns9xxx_gpio_configure(11, 0, 1);
+ else
+ printk(KERN_ERR "%s: cannot get gpio 11 for IRQ_EXT2\n",
+ __func__);
for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
set_irq_chip(i, &a9m9750dev_fpga_chip);
@@ -100,10 +117,10 @@ void __init board_a9m9750dev_init_irq(void)
}
/* IRQ_EXT2: level sensitive + active low */
- reg = SYS_EIC(2);
- REGSET(reg, SYS_EIC, PLTY, AL);
- REGSET(reg, SYS_EIC, LVEDG, LEVEL);
- SYS_EIC(2) = reg;
+ eic = __raw_readl(SYS_EIC(2));
+ REGSET(eic, SYS_EIC, PLTY, AL);
+ REGSET(eic, SYS_EIC, LVEDG, LEVEL);
+ __raw_writel(eic, SYS_EIC(2));
set_irq_chained_handler(IRQ_EXT2,
a9m9750dev_fpga_demux_handler);
@@ -167,17 +184,18 @@ void __init board_a9m9750dev_init_machine(void)
u32 reg;
/* setup static CS0: memory base ... */
- REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB,
- NS9XXX_CSxSTAT_PHYS(0) >> 12);
+ reg = __raw_readl(SYS_SMCSSMB(0));
+ REGSETIM(reg, SYS_SMCSSMB, CSxB, NS9XXX_CSxSTAT_PHYS(0) >> 12);
+ __raw_writel(reg, SYS_SMCSSMB(0));
/* ... and mask */
- reg = SYS_SMCSSMM(0);
+ reg = __raw_readl(SYS_SMCSSMM(0));
REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
REGSET(reg, SYS_SMCSSMM, CSEx, EN);
- SYS_SMCSSMM(0) = reg;
+ __raw_writel(reg, SYS_SMCSSMM(0));
/* setup static CS0: memory configuration */
- reg = MEM_SMC(0);
+ reg = __raw_readl(MEM_SMC(0));
REGSET(reg, MEM_SMC, PSMC, OFF);
REGSET(reg, MEM_SMC, BSMC, OFF);
REGSET(reg, MEM_SMC, EW, OFF);
@@ -185,13 +203,13 @@ void __init board_a9m9750dev_init_machine(void)
REGSET(reg, MEM_SMC, PC, AL);
REGSET(reg, MEM_SMC, PM, DIS);
REGSET(reg, MEM_SMC, MW, 8);
- MEM_SMC(0) = reg;
+ __raw_writel(reg, MEM_SMC(0));
/* setup static CS0: timing */
- MEM_SMWED(0) = 0x2;
- MEM_SMOED(0) = 0x2;
- MEM_SMRD(0) = 0x6;
- MEM_SMWD(0) = 0x6;
+ __raw_writel(0x2, MEM_SMWED(0));
+ __raw_writel(0x2, MEM_SMOED(0));
+ __raw_writel(0x6, MEM_SMRD(0));
+ __raw_writel(0x6, MEM_SMWD(0));
platform_add_devices(board_a9m9750dev_devices,
ARRAY_SIZE(board_a9m9750dev_devices));
diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c
new file mode 100644
index 00000000000..b2230213b98
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/gpio.c
@@ -0,0 +1,190 @@
+/*
+ * arch/arm/mach-ns9xxx/gpio.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+
+#include <asm/arch-ns9xxx/gpio.h>
+#include <asm/arch-ns9xxx/processor.h>
+#include <asm/arch-ns9xxx/regs-bbu.h>
+#include <asm/io.h>
+#include <asm/bug.h>
+#include <asm/types.h>
+#include <asm/bitops.h>
+
+#if defined(CONFIG_PROCESSOR_NS9360)
+#define GPIO_MAX 72
+#elif defined(CONFIG_PROCESSOR_NS9750)
+#define GPIO_MAX 49
+#endif
+
+/* protects BBU_GCONFx and BBU_GCTRLx */
+static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock);
+
+/* only access gpiores with atomic ops */
+static DECLARE_BITMAP(gpiores, GPIO_MAX);
+
+static inline int ns9xxx_valid_gpio(unsigned gpio)
+{
+#if defined(CONFIG_PROCESSOR_NS9360)
+ if (processor_is_ns9360())
+ return gpio <= 72;
+ else
+#endif
+#if defined(CONFIG_PROCESSOR_NS9750)
+ if (processor_is_ns9750())
+ return gpio <= 49;
+ else
+#endif
+ BUG();
+}
+
+static inline void __iomem *ns9xxx_gpio_get_gconfaddr(unsigned gpio)
+{
+ if (gpio < 56)
+ return BBU_GCONFb1(gpio / 8);
+ else
+ /*
+ * this could be optimised away on
+ * ns9750 only builds, but it isn't ...
+ */
+ return BBU_GCONFb2((gpio - 56) / 8);
+}
+
+static inline void __iomem *ns9xxx_gpio_get_gctrladdr(unsigned gpio)
+{
+ if (gpio < 32)
+ return BBU_GCTRL1;
+ else if (gpio < 64)
+ return BBU_GCTRL2;
+ else
+ /* this could be optimised away on ns9750 only builds */
+ return BBU_GCTRL3;
+}
+
+static inline void __iomem *ns9xxx_gpio_get_gstataddr(unsigned gpio)
+{
+ if (gpio < 32)
+ return BBU_GSTAT1;
+ else if (gpio < 64)
+ return BBU_GSTAT2;
+ else
+ /* this could be optimised away on ns9750 only builds */
+ return BBU_GSTAT3;
+}
+
+int gpio_request(unsigned gpio, const char *label)
+{
+ if (likely(ns9xxx_valid_gpio(gpio)))
+ return test_and_set_bit(gpio, gpiores) ? -EBUSY : 0;
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+ clear_bit(gpio, gpiores);
+ return;
+}
+EXPORT_SYMBOL(gpio_free);
+
+/*
+ * each gpio can serve for 4 different purposes [0..3]. These are called
+ * "functions" and passed in the parameter func. Functions 0-2 are always some
+ * special things, function 3 is GPIO. If func == 3 dir specifies input or
+ * output, and with inv you can enable an inverter (independent of func).
+ */
+static int __ns9xxx_gpio_configure(unsigned gpio, int dir, int inv, int func)
+{
+ void __iomem *conf = ns9xxx_gpio_get_gconfaddr(gpio);
+ u32 confval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ confval = __raw_readl(conf);
+ REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir);
+ REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv);
+ REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func);
+ __raw_writel(confval, conf);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+
+ return 0;
+}
+
+int ns9xxx_gpio_configure(unsigned gpio, int inv, int func)
+{
+ if (likely(ns9xxx_valid_gpio(gpio))) {
+ if (func == 3) {
+ printk(KERN_WARNING "use gpio_direction_input "
+ "or gpio_direction_output\n");
+ return -EINVAL;
+ } else
+ return __ns9xxx_gpio_configure(gpio, 0, inv, func);
+ } else
+ return -EINVAL;
+}
+EXPORT_SYMBOL(ns9xxx_gpio_configure);
+
+int gpio_direction_input(unsigned gpio)
+{
+ if (likely(ns9xxx_valid_gpio(gpio))) {
+ return __ns9xxx_gpio_configure(gpio, 0, 0, 3);
+ } else
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ if (likely(ns9xxx_valid_gpio(gpio))) {
+ gpio_set_value(gpio, value);
+
+ return __ns9xxx_gpio_configure(gpio, 1, 0, 3);
+ } else
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned gpio)
+{
+ void __iomem *stat = ns9xxx_gpio_get_gstataddr(gpio);
+ int ret;
+
+ ret = 1 & (__raw_readl(stat) >> (gpio & 31));
+
+ return ret;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ void __iomem *ctrl = ns9xxx_gpio_get_gctrladdr(gpio);
+ u32 ctrlval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ ctrlval = __raw_readl(ctrl);
+
+ if (value)
+ ctrlval |= 1 << (gpio & 31);
+ else
+ ctrlval &= ~(1 << (gpio & 31));
+
+ __raw_writel(ctrlval, ctrl);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index b8c7b00522e..00001b874e9 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*/
#include <linux/interrupt.h>
+#include <asm/io.h>
#include <asm/mach/irq.h>
#include <asm/mach-types.h>
#include <asm/arch-ns9xxx/regs-sys.h>
@@ -17,48 +18,17 @@
#include "generic.h"
-static void ns9xxx_ack_irq_timer(unsigned int irq)
-{
- u32 tc = SYS_TC(irq - IRQ_TIMER0);
-
- /*
- * If the timer is programmed to halt on terminal count, the
- * timer must be disabled before clearing the interrupt.
- */
- if (REGGET(tc, SYS_TCx, REN) == 0) {
- REGSET(tc, SYS_TCx, TEN, DIS);
- SYS_TC(irq - IRQ_TIMER0) = tc;
- }
-
- REGSET(tc, SYS_TCx, INTC, SET);
- SYS_TC(irq - IRQ_TIMER0) = tc;
-
- REGSET(tc, SYS_TCx, INTC, UNSET);
- SYS_TC(irq - IRQ_TIMER0) = tc;
-}
-
-static void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
- [IRQ_TIMER0] = ns9xxx_ack_irq_timer,
- [IRQ_TIMER1] = ns9xxx_ack_irq_timer,
- [IRQ_TIMER2] = ns9xxx_ack_irq_timer,
- [IRQ_TIMER3] = ns9xxx_ack_irq_timer,
-};
-
static void ns9xxx_mask_irq(unsigned int irq)
{
/* XXX: better use cpp symbols */
- SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3))));
+ u32 ic = __raw_readl(SYS_IC(irq / 4));
+ ic &= ~(1 << (7 + 8 * (3 - (irq & 3))));
+ __raw_writel(ic, SYS_IC(irq / 4));
}
static void ns9xxx_ack_irq(unsigned int irq)
{
- if (!ns9xxx_ack_irq_functions[irq]) {
- printk(KERN_ERR "no ack function for irq %u\n", irq);
- BUG();
- }
-
- ns9xxx_ack_irq_functions[irq](irq);
- SYS_ISRADDR = 0;
+ __raw_writel(0, SYS_ISRADDR);
}
static void ns9xxx_maskack_irq(unsigned int irq)
@@ -70,7 +40,9 @@ static void ns9xxx_maskack_irq(unsigned int irq)
static void ns9xxx_unmask_irq(unsigned int irq)
{
/* XXX: better use cpp symbols */
- SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3)));
+ u32 ic = __raw_readl(SYS_IC(irq / 4));
+ ic |= 1 << (7 + 8 * (3 - (irq & 3)));
+ __raw_writel(ic, SYS_IC(irq / 4));
}
static struct irq_chip ns9xxx_chip = {
@@ -86,14 +58,14 @@ void __init ns9xxx_init_irq(void)
/* disable all IRQs */
for (i = 0; i < 8; ++i)
- SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 |
- (4 * i + 2) << 8 | (4 * i + 3);
+ __raw_writel((4 * i) << 24 | (4 * i + 1) << 16 |
+ (4 * i + 2) << 8 | (4 * i + 3), SYS_IC(i));
/* simple interrupt prio table:
* prio(x) < prio(y) <=> x < y
*/
for (i = 0; i < 32; ++i)
- SYS_IVA(i) = i;
+ __raw_writel(i, SYS_IVA(i));
for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
set_irq_chip(i, &ns9xxx_chip);
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
index b97d0c54a38..c3dd1f4acb9 100644
--- a/arch/arm/mach-ns9xxx/time.c
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -11,78 +11,174 @@
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/stringify.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+
#include <asm/arch-ns9xxx/regs-sys.h>
#include <asm/arch-ns9xxx/clock.h>
#include <asm/arch-ns9xxx/irqs.h>
#include <asm/arch/system.h>
#include "generic.h"
-#define TIMERCLOCKSELECT 64
+#define TIMER_CLOCKSOURCE 0
+#define TIMER_CLOCKEVENT 1
+static u32 latch;
+
+static cycle_t ns9xxx_clocksource_read(void)
+{
+ return __raw_readl(SYS_TR(TIMER_CLOCKSOURCE));
+}
-static u32 usecs_per_tick;
+static struct clocksource ns9xxx_clocksource = {
+ .name = "ns9xxx-timer" __stringify(TIMER_CLOCKSOURCE),
+ .rating = 300,
+ .read = ns9xxx_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
-static irqreturn_t
-ns9xxx_timer_interrupt(int irq, void *dev_id)
+static void ns9xxx_clockevent_setmode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
{
- write_seqlock(&xtime_lock);
- timer_tick();
- write_sequnlock(&xtime_lock);
+ u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
+
+ switch(mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ __raw_writel(latch, SYS_TRC(TIMER_CLOCKEVENT));
+ REGSET(tc, SYS_TCx, REN, EN);
+ REGSET(tc, SYS_TCx, INTS, EN);
+ REGSET(tc, SYS_TCx, TEN, EN);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ REGSET(tc, SYS_TCx, REN, DIS);
+ REGSET(tc, SYS_TCx, INTS, EN);
+
+ /* fall through */
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ default:
+ REGSET(tc, SYS_TCx, TEN, DIS);
+ break;
+ }
+
+ __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
+}
- return IRQ_HANDLED;
+static int ns9xxx_clockevent_setnextevent(unsigned long evt,
+ struct clock_event_device *clk)
+{
+ u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
+
+ if (REGGET(tc, SYS_TCx, TEN)) {
+ REGSET(tc, SYS_TCx, TEN, DIS);
+ __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
+ }
+
+ REGSET(tc, SYS_TCx, TEN, EN);
+
+ __raw_writel(evt, SYS_TRC(TIMER_CLOCKEVENT));
+
+ __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
+
+ return 0;
}
-static unsigned long ns9xxx_timer_gettimeoffset(void)
+static struct clock_event_device ns9xxx_clockevent_device = {
+ .name = "ns9xxx-timer" __stringify(TIMER_CLOCKEVENT),
+ .shift = 20,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = ns9xxx_clockevent_setmode,
+ .set_next_event = ns9xxx_clockevent_setnextevent,
+};
+
+static irqreturn_t ns9xxx_clockevent_handler(int irq, void *dev_id)
{
- /* return the microseconds which have passed since the last interrupt
- * was _serviced_. That is, if an interrupt is pending or the counter
- * reloads, return one period more. */
+ int timerno = irq - IRQ_TIMER0;
+ u32 tc;
- u32 counter1 = SYS_TR(0);
- int pending = SYS_ISR & (1 << IRQ_TIMER0);
- u32 counter2 = SYS_TR(0);
- u32 elapsed;
+ struct clock_event_device *evt = &ns9xxx_clockevent_device;
- if (pending || counter2 > counter1)
- elapsed = 2 * SYS_TRC(0) - counter2;
- else
- elapsed = SYS_TRC(0) - counter1;
+ /* clear irq */
+ tc = __raw_readl(SYS_TC(timerno));
+ if (REGGET(tc, SYS_TCx, REN) == SYS_TCx_REN_DIS) {
+ REGSET(tc, SYS_TCx, TEN, DIS);
+ __raw_writel(tc, SYS_TC(timerno));
+ }
+ REGSET(tc, SYS_TCx, INTC, SET);
+ __raw_writel(tc, SYS_TC(timerno));
+ REGSET(tc, SYS_TCx, INTC, UNSET);
+ __raw_writel(tc, SYS_TC(timerno));
- return (elapsed * usecs_per_tick) >> 16;
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
}
-static struct irqaction ns9xxx_timer_irq = {
- .name = "NS9xxx Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = ns9xxx_timer_interrupt,
+static struct irqaction ns9xxx_clockevent_action = {
+ .name = "ns9xxx-timer" __stringify(TIMER_CLOCKEVENT),
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = ns9xxx_clockevent_handler,
};
static void __init ns9xxx_timer_init(void)
{
int tc;
- usecs_per_tick =
- SH_DIV(1000000 * TIMERCLOCKSELECT, ns9xxx_cpuclock(), 16);
+ tc = __raw_readl(SYS_TC(TIMER_CLOCKSOURCE));
+ if (REGGET(tc, SYS_TCx, TEN)) {
+ REGSET(tc, SYS_TCx, TEN, DIS);
+ __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
+ }
- /* disable timer */
- if ((tc = SYS_TC(0)) & SYS_TCx_TEN)
- SYS_TC(0) = tc & ~SYS_TCx_TEN;
-
- SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT * HZ), 0);
+ __raw_writel(0, SYS_TRC(TIMER_CLOCKSOURCE));
REGSET(tc, SYS_TCx, TEN, EN);
- REGSET(tc, SYS_TCx, TLCS, DIV64); /* This must match TIMERCLOCKSELECT */
- REGSET(tc, SYS_TCx, INTS, EN);
- REGSET(tc, SYS_TCx, UDS, DOWN);
REGSET(tc, SYS_TCx, TDBG, STOP);
+ REGSET(tc, SYS_TCx, TLCS, CPU);
+ REGSET(tc, SYS_TCx, TM, IEE);
+ REGSET(tc, SYS_TCx, INTS, DIS);
+ REGSET(tc, SYS_TCx, UDS, UP);
REGSET(tc, SYS_TCx, TSZ, 32);
REGSET(tc, SYS_TCx, REN, EN);
- SYS_TC(0) = tc;
- setup_irq(IRQ_TIMER0, &ns9xxx_timer_irq);
+ __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
+
+ ns9xxx_clocksource.mult = clocksource_hz2mult(ns9xxx_cpuclock(),
+ ns9xxx_clocksource.shift);
+
+ clocksource_register(&ns9xxx_clocksource);
+
+ latch = SH_DIV(ns9xxx_cpuclock(), HZ, 0);
+
+ tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
+ REGSET(tc, SYS_TCx, TEN, DIS);
+ REGSET(tc, SYS_TCx, TDBG, STOP);
+ REGSET(tc, SYS_TCx, TLCS, CPU);
+ REGSET(tc, SYS_TCx, TM, IEE);
+ REGSET(tc, SYS_TCx, INTS, DIS);
+ REGSET(tc, SYS_TCx, UDS, DOWN);
+ REGSET(tc, SYS_TCx, TSZ, 32);
+ REGSET(tc, SYS_TCx, REN, EN);
+ __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
+
+ ns9xxx_clockevent_device.mult = div_sc(ns9xxx_cpuclock(),
+ NSEC_PER_SEC, ns9xxx_clockevent_device.shift);
+ ns9xxx_clockevent_device.max_delta_ns =
+ clockevent_delta2ns(-1, &ns9xxx_clockevent_device);
+ ns9xxx_clockevent_device.min_delta_ns =
+ clockevent_delta2ns(1, &ns9xxx_clockevent_device);
+
+ ns9xxx_clockevent_device.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&ns9xxx_clockevent_device);
+
+ setup_irq(IRQ_TIMER0 + TIMER_CLOCKEVENT, &ns9xxx_clockevent_action);
}
struct sys_timer ns9xxx_timer = {
.init = ns9xxx_timer_init,
- .offset = ns9xxx_timer_gettimeoffset,
};
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index f6ecdd3a247..79f0b1f8497 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -84,11 +84,39 @@ config MACH_OMAP_PALMTE
bool "Palm Tungsten E"
depends on ARCH_OMAP1 && ARCH_OMAP15XX
help
- Support for the Palm Tungsten E PDA. Currently only the LCD panel
- is supported. To boot the kernel, you'll need a PalmOS compatible
- bootloader; check out http://palmtelinux.sourceforge.net for more
- information.
- Say Y here if you have such a PDA, say NO otherwise.
+ Support for the Palm Tungsten E PDA. To boot the kernel, you'll
+ need a PalmOS compatible bootloader; check out
+ http://palmtelinux.sourceforge.net/ for more information.
+ Say Y here if you have this PDA model, say N otherwise.
+
+config MACH_OMAP_PALMZ71
+ bool "Palm Zire71"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Palm Zire71 PDA. To boot the kernel,
+ you'll need a PalmOS compatible bootloader; check out
+ http://hackndev.com/palm/z71 for more informations.
+ Say Y here if you have such a PDA, say N otherwise.
+
+config MACH_OMAP_PALMTT
+ bool "Palm Tungsten|T"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Palm Tungsten|T PDA. To boot the kernel, you'll
+ need a PalmOS compatible bootloader (Garux); check out
+ http://www.hackndev.com/palm/tt/ for more information.
+ Say Y here if you have this PDA model, say N otherwise.
+
+config MACH_SX1
+ bool "Siemens SX1"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Siemens SX1 phone. To boot the kernel,
+ you'll need a SX1 compatible bootloader; check out
+ http://forum.oslik.ru and
+ http://www.handhelds.org/moin/moin.cgi/SiemensSX1
+ for more information.
+ Say Y here if you have such a phone, say NO otherwise.
config MACH_NOKIA770
bool "Nokia 770"
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index a8b9a00cea2..391b6f4827f 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -22,8 +22,11 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
+obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o
+obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o
obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
+obj-$(CONFIG_MACH_SX1) += board-sx1.o
ifeq ($(CONFIG_ARCH_OMAP15XX),y)
# Innovator-1510 FPGA
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 8437d065ada..c73ca61e585 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/input.h>
#include <linux/platform_device.h>
#include <asm/hardware.h>
@@ -23,6 +24,7 @@
#include <asm/arch/board-ams-delta.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
#include <asm/arch/board.h>
@@ -31,6 +33,86 @@
static u8 ams_delta_latch1_reg;
static u16 ams_delta_latch2_reg;
+static int ams_delta_keymap[] = {
+ KEY(0, 0, KEY_F1), /* Advert */
+
+ KEY(3, 0, KEY_COFFEE), /* Games */
+ KEY(2, 0, KEY_QUESTION), /* Directory */
+ KEY(3, 2, KEY_CONNECT), /* Internet */
+ KEY(2, 1, KEY_SHOP), /* Services */
+ KEY(1, 1, KEY_PHONE), /* VoiceMail */
+
+ KEY(1, 0, KEY_DELETE), /* Delete */
+ KEY(2, 2, KEY_PLAY), /* Play */
+ KEY(0, 1, KEY_PAGEUP), /* Up */
+ KEY(3, 1, KEY_PAGEDOWN), /* Down */
+ KEY(0, 2, KEY_EMAIL), /* ReadEmail */
+ KEY(1, 2, KEY_STOP), /* Stop */
+
+ /* Numeric keypad portion */
+ KEY(7, 0, KEY_KP1),
+ KEY(6, 0, KEY_KP2),
+ KEY(5, 0, KEY_KP3),
+ KEY(7, 1, KEY_KP4),
+ KEY(6, 1, KEY_KP5),
+ KEY(5, 1, KEY_KP6),
+ KEY(7, 2, KEY_KP7),
+ KEY(6, 2, KEY_KP8),
+ KEY(5, 2, KEY_KP9),
+ KEY(6, 3, KEY_KP0),
+ KEY(7, 3, KEY_KPASTERISK),
+ KEY(5, 3, KEY_KPDOT), /* # key */
+ KEY(2, 7, KEY_NUMLOCK), /* Mute */
+ KEY(1, 7, KEY_KPMINUS), /* Recall */
+ KEY(1, 6, KEY_KPPLUS), /* Redial */
+ KEY(6, 7, KEY_KPSLASH), /* Handsfree */
+ KEY(0, 6, KEY_ENTER), /* Video */
+
+ KEY(4, 7, KEY_CAMERA), /* Photo */
+
+ KEY(4, 0, KEY_F2), /* Home */
+ KEY(4, 1, KEY_F3), /* Office */
+ KEY(4, 2, KEY_F4), /* Mobile */
+ KEY(7, 7, KEY_F5), /* SMS */
+ KEY(5, 7, KEY_F6), /* Email */
+
+ /* QWERTY portion of keypad */
+ KEY(4, 3, KEY_Q),
+ KEY(3, 3, KEY_W),
+ KEY(2, 3, KEY_E),
+ KEY(1, 3, KEY_R),
+ KEY(0, 3, KEY_T),
+ KEY(7, 4, KEY_Y),
+ KEY(6, 4, KEY_U),
+ KEY(5, 4, KEY_I),
+ KEY(4, 4, KEY_O),
+ KEY(3, 4, KEY_P),
+
+ KEY(2, 4, KEY_A),
+ KEY(1, 4, KEY_S),
+ KEY(0, 4, KEY_D),
+ KEY(7, 5, KEY_F),
+ KEY(6, 5, KEY_G),
+ KEY(5, 5, KEY_H),
+ KEY(4, 5, KEY_J),
+ KEY(3, 5, KEY_K),
+ KEY(2, 5, KEY_L),
+
+ KEY(1, 5, KEY_Z),
+ KEY(0, 5, KEY_X),
+ KEY(7, 6, KEY_C),
+ KEY(6, 6, KEY_V),
+ KEY(5, 6, KEY_B),
+ KEY(4, 6, KEY_N),
+ KEY(3, 6, KEY_M),
+ KEY(2, 6, KEY_SPACE),
+
+ KEY(0, 7, KEY_LEFTSHIFT), /* Vol up */
+ KEY(3, 7, KEY_LEFTCTRL), /* Vol down */
+
+ 0
+};
+
void ams_delta_latch1_write(u8 mask, u8 value)
{
ams_delta_latch1_reg &= ~mask;
@@ -76,6 +158,10 @@ static struct map_desc ams_delta_io_desc[] __initdata = {
}
};
+static struct omap_lcd_config ams_delta_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
static struct omap_uart_config ams_delta_uart_config __initdata = {
.enabled_uarts = 1,
};
@@ -87,16 +173,50 @@ static struct omap_usb_config ams_delta_usb_config __initdata = {
};
static struct omap_board_config_kernel ams_delta_config[] = {
+ { OMAP_TAG_LCD, &ams_delta_lcd_config },
{ OMAP_TAG_UART, &ams_delta_uart_config },
{ OMAP_TAG_USB, &ams_delta_usb_config },
};
+static struct resource ams_delta_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data ams_delta_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = ams_delta_keymap,
+ .keymapsize = ARRAY_SIZE(ams_delta_keymap),
+ .delay = 9,
+};
+
+static struct platform_device ams_delta_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &ams_delta_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(ams_delta_kp_resources),
+ .resource = ams_delta_kp_resources,
+};
+
+static struct platform_device ams_delta_lcd_device = {
+ .name = "lcd_ams_delta",
+ .id = -1,
+};
+
static struct platform_device ams_delta_led_device = {
.name = "ams-delta-led",
.id = -1
};
static struct platform_device *ams_delta_devices[] __initdata = {
+ &ams_delta_kp_device,
+ &ams_delta_lcd_device,
&ams_delta_led_device,
};
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 2f8f6ecf111..b0921622566 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -140,6 +140,66 @@ static struct platform_device h2_nor_device = {
.resource = &h2_nor_resource,
};
+#if 0 /* REVISIT: Enable when nand_platform_data is applied */
+
+static struct mtd_partition h2_nand_partitions[] = {
+#if 0
+ /* REVISIT: enable these partitions if you make NAND BOOT
+ * work on your H2 (rev C or newer); published versions of
+ * x-load only support P2 and H3.
+ */
+ {
+ .name = "xloader",
+ .offset = 0,
+ .size = 64 * 1024,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * 1024,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 192 * 1024,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * SZ_1M,
+ },
+#endif
+ {
+ .name = "filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
+static struct nand_platform_data h2_nand_data = {
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ .parts = h2_nand_partitions,
+ .nr_parts = ARRAY_SIZE(h2_nand_partitions),
+};
+
+static struct resource h2_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device h2_nand_device = {
+ .name = "omapnand",
+ .id = 0,
+ .dev = {
+ .platform_data = &h2_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &h2_nand_resource,
+};
+#endif
+
static struct resource h2_smc91x_resources[] = {
[0] = {
.start = OMAP1610_ETHR_START, /* Physical */
@@ -219,11 +279,15 @@ static struct resource h2_irda_resources[] = {
.flags = IORESOURCE_IRQ,
},
};
+
+static u64 irda_dmamask = 0xffffffff;
+
static struct platform_device h2_irda_device = {
.name = "omapirda",
.id = 0,
.dev = {
.platform_data = &h2_irda_data,
+ .dma_mask = &irda_dmamask,
},
.num_resources = ARRAY_SIZE(h2_irda_resources),
.resource = h2_irda_resources,
@@ -271,6 +335,7 @@ static struct platform_device h2_mcbsp1_device = {
static struct platform_device *h2_devices[] __initdata = {
&h2_nor_device,
+ //&h2_nand_device,
&h2_smc91x_device,
&h2_irda_device,
&h2_kp_device,
@@ -348,6 +413,13 @@ static struct omap_board_config_kernel h2_config[] __initdata = {
{ OMAP_TAG_LCD, &h2_lcd_config },
};
+#define H2_NAND_RB_GPIO_PIN 62
+
+static int h2_nand_dev_ready(struct nand_platform_data *data)
+{
+ return omap_get_gpio_datain(H2_NAND_RB_GPIO_PIN);
+}
+
static void __init h2_init(void)
{
/* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
@@ -362,6 +434,13 @@ static void __init h2_init(void)
h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
h2_nor_resource.end += SZ_32M - 1;
+#if 0 /* REVISIT: Enable when nand_platform_data is applied */
+ h2_nand_resource.end = h2_nand_resource.start = OMAP_CS2B_PHYS;
+ h2_nand_resource.end += SZ_4K - 1;
+ if (!(omap_request_gpio(H2_NAND_RB_GPIO_PIN)))
+ h2_nand_data.dev_ready = h2_nand_dev_ready;
+#endif
+
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index add2f703204..4f84ae273a1 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -47,6 +47,8 @@
#include <asm/arch/keypad.h>
#include <asm/arch/dma.h>
#include <asm/arch/common.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/omap-alsa.h>
extern int omap_gpio_init(void);
@@ -354,11 +356,14 @@ static struct resource h3_irda_resources[] = {
},
};
+static u64 irda_dmamask = 0xffffffff;
+
static struct platform_device h3_irda_device = {
.name = "omapirda",
.id = 0,
.dev = {
.platform_data = &h3_irda_data,
+ .dma_mask = &irda_dmamask,
},
.num_resources = ARRAY_SIZE(h3_irda_resources),
.resource = h3_irda_resources,
@@ -369,6 +374,41 @@ static struct platform_device h3_lcd_device = {
.id = -1,
};
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
+ .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
+ .spcr1 = RINTM(3) | RRST,
+ .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
+ RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
+ .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
+ .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
+ XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
+ .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
+ .srgr1 = FWID(15),
+ .srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
+
+ .pcr0 = CLKRM | SCLKME | FSXP | FSRP | CLKXP | CLKRP,
+ //.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
+};
+
+static struct omap_alsa_codec_config alsa_config = {
+ .name = "H3 TSC2101",
+ .mcbsp_regs_alsa = &mcbsp_regs,
+ .codec_configure_dev = NULL, // tsc2101_configure,
+ .codec_set_samplerate = NULL, // tsc2101_set_samplerate,
+ .codec_clock_setup = NULL, // tsc2101_clock_setup,
+ .codec_clock_on = NULL, // tsc2101_clock_on,
+ .codec_clock_off = NULL, // tsc2101_clock_off,
+ .get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
+};
+
+static struct platform_device h3_mcbsp1_device = {
+ .name = "omap_alsa_mcbsp",
+ .id = 1,
+ .dev = {
+ .platform_data = &alsa_config,
+ },
+};
+
static struct platform_device *devices[] __initdata = {
&nor_device,
&nand_device,
@@ -377,6 +417,7 @@ static struct platform_device *devices[] __initdata = {
&h3_irda_device,
&h3_kp_device,
&h3_lcd_device,
+ &h3_mcbsp1_device,
};
static struct omap_usb_config h3_usb_config __initdata = {
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 70014f751bc..22db19a5364 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -33,6 +33,12 @@
#include <asm/arch/dsp_common.h>
#include <asm/arch/aic23.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/omapfb.h>
+#include <asm/arch/lcd_mipid.h>
+
+#include "../plat-omap/dsp/dsp_common.h"
+
+#define ADS7846_PENDOWN_GPIO 15
static void __init omap_nokia770_init_irq(void)
{
@@ -91,9 +97,44 @@ static struct platform_device nokia770_kp_device = {
};
static struct platform_device *nokia770_devices[] __initdata = {
- &nokia770_kp_device,
+ &nokia770_kp_device,
+};
+
+static void mipid_shutdown(struct mipid_platform_data *pdata)
+{
+ if (pdata->nreset_gpio != -1) {
+ printk(KERN_INFO "shutdown LCD\n");
+ omap_set_gpio_dataout(pdata->nreset_gpio, 0);
+ msleep(120);
+ }
+}
+
+static struct mipid_platform_data nokia770_mipid_platform_data = {
+ .shutdown = mipid_shutdown,
};
+static void mipid_dev_init(void)
+{
+ const struct omap_lcd_config *conf;
+
+ conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+ if (conf != NULL) {
+ nokia770_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
+ nokia770_mipid_platform_data.data_lines = conf->data_lines;
+ }
+}
+
+static void ads7846_dev_init(void)
+{
+ if (omap_request_gpio(ADS7846_PENDOWN_GPIO) < 0)
+ printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
+}
+
+static int ads7846_get_pendown_state(void)
+{
+ return !omap_get_gpio_datain(ADS7846_PENDOWN_GPIO);
+}
+
static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
.x_max = 0x0fff,
.y_max = 0x0fff,
@@ -101,14 +142,17 @@ static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata =
.pressure_max = 255,
.debounce_max = 10,
.debounce_tol = 3,
+ .debounce_rep = 1,
+ .get_pendown_state = ads7846_get_pendown_state,
};
static struct spi_board_info nokia770_spi_board_info[] __initdata = {
[0] = {
- .modalias = "lcd_mipid",
+ .modalias = "lcd_mipid",
.bus_num = 2,
.chip_select = 3,
.max_speed_hz = 12000000,
+ .platform_data = &nokia770_mipid_platform_data,
},
[1] = {
.modalias = "ads7846",
@@ -153,6 +197,7 @@ static struct omap_board_config_kernel nokia770_config[] = {
{ OMAP_TAG_MMC, &nokia770_mmc_config },
};
+#if defined(CONFIG_OMAP_DSP)
/*
* audio power control
*/
@@ -183,7 +228,7 @@ static void nokia770_audio_pwr_up(void)
clk_enable(dspxor_ck);
/* Turn on codec */
- tlv320aic23_power_up();
+ aic23_power_up();
if (omap_get_gpio_datain(HEADPHONE_GPIO))
/* HP not connected, turn on amplifier */
@@ -197,7 +242,7 @@ static void codec_delayed_power_down(struct work_struct *work)
{
down(&audio_pwr_sem);
if (audio_pwr_state == -1)
- tlv320aic23_power_down();
+ aic23_power_down();
clk_disable(dspxor_ck);
up(&audio_pwr_sem);
}
@@ -213,7 +258,8 @@ static void nokia770_audio_pwr_down(void)
schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
}
-void nokia770_audio_pwr_up_request(int stage)
+static int
+nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage)
{
down(&audio_pwr_sem);
if (audio_pwr_state == -1)
@@ -221,9 +267,11 @@ void nokia770_audio_pwr_up_request(int stage)
/* force audio_pwr_state = 0, even if it was 1. */
audio_pwr_state = 0;
up(&audio_pwr_sem);
+ return 0;
}
-void nokia770_audio_pwr_down_request(int stage)
+static int
+nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage)
{
down(&audio_pwr_sem);
switch (stage) {
@@ -239,8 +287,39 @@ void nokia770_audio_pwr_down_request(int stage)
break;
}
up(&audio_pwr_sem);
+ return 0;
}
+static struct dsp_kfunc_device nokia770_audio_device = {
+ .name = "audio",
+ .type = DSP_KFUNC_DEV_TYPE_AUDIO,
+ .enable = nokia770_audio_pwr_up_request,
+ .disable = nokia770_audio_pwr_down_request,
+};
+
+static __init int omap_dsp_init(void)
+{
+ int ret;
+
+ dspxor_ck = clk_get(0, "dspxor_ck");
+ if (IS_ERR(dspxor_ck)) {
+ printk(KERN_ERR "couldn't acquire dspxor_ck\n");
+ return PTR_ERR(dspxor_ck);
+ }
+
+ ret = dsp_kfunc_device_register(&nokia770_audio_device);
+ if (ret) {
+ printk(KERN_ERR
+ "KFUNC device registration faild: %s\n",
+ nokia770_audio_device.name);
+ goto out;
+ }
+ return 0;
+ out:
+ return ret;
+}
+#endif /* CONFIG_OMAP_DSP */
+
static void __init omap_nokia770_init(void)
{
nokia770_config[0].data = &nokia770_usb_config;
@@ -250,10 +329,11 @@ static void __init omap_nokia770_init(void)
ARRAY_SIZE(nokia770_spi_board_info));
omap_board_config = nokia770_config;
omap_board_config_size = ARRAY_SIZE(nokia770_config);
+ omap_gpio_init();
omap_serial_init();
- omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request;
- omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
- dspxor_ck = clk_get(0, "dspxor_ck");
+ omap_dsp_init();
+ ads7846_dev_init();
+ mipid_dev_init();
}
static void __init omap_nokia770_map_io(void)
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index a61bf455ee0..5db182da322 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
@@ -308,6 +309,18 @@ static struct platform_device osk5912_kp_device = {
.resource = osk5912_kp_resources,
};
+static struct omap_backlight_config mistral_bl_data = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device mistral_bl_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data = &mistral_bl_data,
+ },
+};
+
static struct platform_device osk5912_lcd_device = {
.name = "lcd_osk",
.id = -1,
@@ -315,6 +328,7 @@ static struct platform_device osk5912_lcd_device = {
static struct platform_device *mistral_devices[] __initdata = {
&osk5912_kp_device,
+ &mistral_bl_device,
&osk5912_lcd_device,
};
@@ -358,6 +372,38 @@ static void __init osk_mistral_init(void)
* can't talk to the ads or even the i2c eeprom.
*/
+ /* parallel camera interface */
+ omap_cfg_reg(J15_1610_CAM_LCLK);
+ omap_cfg_reg(J18_1610_CAM_D7);
+ omap_cfg_reg(J19_1610_CAM_D6);
+ omap_cfg_reg(J14_1610_CAM_D5);
+ omap_cfg_reg(K18_1610_CAM_D4);
+ omap_cfg_reg(K19_1610_CAM_D3);
+ omap_cfg_reg(K15_1610_CAM_D2);
+ omap_cfg_reg(K14_1610_CAM_D1);
+ omap_cfg_reg(L19_1610_CAM_D0);
+ omap_cfg_reg(L18_1610_CAM_VS);
+ omap_cfg_reg(L15_1610_CAM_HS);
+ omap_cfg_reg(M19_1610_CAM_RSTZ);
+ omap_cfg_reg(Y15_1610_CAM_OUTCLK);
+
+ /* serial camera interface */
+ omap_cfg_reg(H19_1610_CAM_EXCLK);
+ omap_cfg_reg(W13_1610_CCP_CLKM);
+ omap_cfg_reg(Y12_1610_CCP_CLKP);
+ /* CCP_DATAM CONFLICTS WITH UART1.TX (and serial console) */
+ // omap_cfg_reg(Y14_1610_CCP_DATAM);
+ omap_cfg_reg(W14_1610_CCP_DATAP);
+
+ /* CAM_PWDN */
+ if (omap_request_gpio(11) == 0) {
+ omap_cfg_reg(N20_1610_GPIO11);
+ omap_set_gpio_direction(11, 0 /* out */);
+ omap_set_gpio_dataout(11, 0 /* off */);
+ } else
+ pr_debug("OSK+Mistral: CAM_PWDN is awol\n");
+
+
// omap_cfg_reg(P19_1610_GPIO6); // BUSY
omap_cfg_reg(P20_1610_GPIO4); // PENIRQ
set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING);
@@ -388,6 +434,15 @@ static void __init osk_mistral_init(void)
} else
printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
+ /* LCD: backlight, and power; power controls other devices on the
+ * board, like the touchscreen, EEPROM, and wakeup (!) switch.
+ */
+ omap_cfg_reg(PWL);
+ if (omap_request_gpio(2) == 0) {
+ omap_set_gpio_direction(2, 0 /* out */);
+ omap_set_gpio_dataout(2, 1 /* on */);
+ }
+
platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices));
}
#else
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 01582418562..2f9d00a0013 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -17,49 +17,189 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/input.h>
#include <linux/platform_device.h>
-#include <linux/notifier.h>
-#include <linux/clk.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tsc2102.h>
+#include <linux/interrupt.h>
+#include <asm/apm.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/dma.h>
#include <asm/arch/board.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/keypad.h>
#include <asm/arch/common.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/omap-alsa.h>
-static void __init omap_generic_init_irq(void)
+static void __init omap_palmte_init_irq(void)
{
omap1_init_common_hw();
omap_init_irq();
+ omap_gpio_init();
}
+static int palmte_keymap[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(0, 1, KEY_F2),
+ KEY(0, 2, KEY_F3),
+ KEY(0, 3, KEY_F4),
+ KEY(0, 4, KEY_POWER),
+ KEY(1, 0, KEY_LEFT),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_UP),
+ KEY(1, 3, KEY_RIGHT),
+ KEY(1, 4, KEY_CENTER),
+ 0,
+};
+
+static struct omap_kp_platform_data palmte_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = palmte_keymap,
+ .rep = 1,
+ .delay = 12,
+};
+
+static struct resource palmte_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmte_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(palmte_kp_resources),
+ .resource = palmte_kp_resources,
+};
+
+static struct mtd_partition palmte_rom_partitions[] = {
+ /* PalmOS "Small ROM", contains the bootloader and the debugger */
+ {
+ .name = "smallrom",
+ .offset = 0,
+ .size = 0xa000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ /* PalmOS "Big ROM", a filesystem with all the OS code and data */
+ {
+ .name = "bigrom",
+ .offset = SZ_128K,
+ /*
+ * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
+ * 0x7b0000 bytes in the English-only ("enUS") version.
+ */
+ .size = 0x7b0000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct flash_platform_data palmte_rom_data = {
+ .map_name = "map_rom",
+ .width = 2,
+ .parts = palmte_rom_partitions,
+ .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
+};
+
+static struct resource palmte_rom_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmte_rom_device = {
+ .name = "omapflash",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_rom_data,
+ },
+ .num_resources = 1,
+ .resource = &palmte_rom_resource,
+};
+
static struct platform_device palmte_lcd_device = {
.name = "lcd_palmte",
.id = -1,
};
+static struct omap_backlight_config palmte_backlight_config = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device palmte_backlight_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_backlight_config,
+ },
+};
+
+static struct omap_irda_config palmte_irda_config = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource palmte_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmte_irda_device = {
+ .name = "omapirda",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_irda_config,
+ },
+ .num_resources = ARRAY_SIZE(palmte_irda_resources),
+ .resource = palmte_irda_resources,
+};
+
static struct platform_device *devices[] __initdata = {
+ &palmte_rom_device,
+ &palmte_kp_device,
&palmte_lcd_device,
+ &palmte_backlight_device,
+ &palmte_irda_device,
};
static struct omap_usb_config palmte_usb_config __initdata = {
- .register_dev = 1,
+ .register_dev = 1, /* Mini-B only receptacle */
.hmc_mode = 0,
- .pins[0] = 3,
+ .pins[0] = 2,
};
static struct omap_mmc_config palmte_mmc_config __initdata = {
- .mmc [0] = {
+ .mmc[0] = {
.enabled = 1,
- .wire4 = 1,
- .wp_pin = OMAP_MPUIO(3),
- .power_pin = -1,
- .switch_pin = -1,
+ .wp_pin = PALMTE_MMC_WP_GPIO,
+ .power_pin = PALMTE_MMC_POWER_GPIO,
+ .switch_pin = PALMTE_MMC_SWITCH_GPIO,
},
};
@@ -67,21 +207,222 @@ static struct omap_lcd_config palmte_lcd_config __initdata = {
.ctrl_name = "internal",
};
+static struct omap_uart_config palmte_uart_config __initdata = {
+ .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
+};
+
+static struct omap_mcbsp_reg_cfg palmte_mcbsp1_regs = {
+ .spcr2 = FRST | GRST | XRST | XINTM(3),
+ .xcr2 = XDATDLY(1) | XFIG,
+ .xcr1 = XWDLEN1(OMAP_MCBSP_WORD_32),
+ .pcr0 = SCLKME | FSXP | CLKXP,
+};
+
+static struct omap_alsa_codec_config palmte_alsa_config = {
+ .name = "TSC2102 audio",
+ .mcbsp_regs_alsa = &palmte_mcbsp1_regs,
+ .codec_configure_dev = NULL, /* tsc2102_configure, */
+ .codec_set_samplerate = NULL, /* tsc2102_set_samplerate, */
+ .codec_clock_setup = NULL, /* tsc2102_clock_setup, */
+ .codec_clock_on = NULL, /* tsc2102_clock_on, */
+ .codec_clock_off = NULL, /* tsc2102_clock_off, */
+ .get_default_samplerate = NULL, /* tsc2102_get_default_samplerate, */
+};
+
+#ifdef CONFIG_APM
+/*
+ * Values measured in 10 minute intervals averaged over 10 samples.
+ * May differ slightly from device to device but should be accurate
+ * enough to give basic idea of battery life left and trigger
+ * potential alerts.
+ */
+static const int palmte_battery_sample[] = {
+ 2194, 2157, 2138, 2120,
+ 2104, 2089, 2075, 2061,
+ 2048, 2038, 2026, 2016,
+ 2008, 1998, 1989, 1980,
+ 1970, 1958, 1945, 1928,
+ 1910, 1888, 1860, 1827,
+ 1791, 1751, 1709, 1656,
+};
+
+#define INTERVAL 10
+#define BATTERY_HIGH_TRESHOLD 66
+#define BATTERY_LOW_TRESHOLD 33
+
+static void palmte_get_power_status(struct apm_power_info *info, int *battery)
+{
+ int charging, batt, hi, lo, mid;
+
+ charging = !omap_get_gpio_datain(PALMTE_DC_GPIO);
+ batt = battery[0];
+ if (charging)
+ batt -= 60;
+
+ hi = ARRAY_SIZE(palmte_battery_sample);
+ lo = 0;
+
+ info->battery_flag = 0;
+ info->units = APM_UNITS_MINS;
+
+ if (batt > palmte_battery_sample[lo]) {
+ info->battery_life = 100;
+ info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
+ } else if (batt <= palmte_battery_sample[hi - 1]) {
+ info->battery_life = 0;
+ info->time = 0;
+ } else {
+ while (hi > lo + 1) {
+ mid = (hi + lo) >> 2;
+ if (batt <= palmte_battery_sample[mid])
+ lo = mid;
+ else
+ hi = mid;
+ }
+
+ mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
+ hi = palmte_battery_sample[lo] - batt;
+ info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
+ ARRAY_SIZE(palmte_battery_sample);
+ info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
+ lo) - INTERVAL * hi / mid;
+ }
+
+ if (charging) {
+ info->ac_line_status = APM_AC_ONLINE;
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
+ } else {
+ info->ac_line_status = APM_AC_OFFLINE;
+ if (info->battery_life > BATTERY_HIGH_TRESHOLD)
+ info->battery_status = APM_BATTERY_STATUS_HIGH;
+ else if (info->battery_life > BATTERY_LOW_TRESHOLD)
+ info->battery_status = APM_BATTERY_STATUS_LOW;
+ else
+ info->battery_status = APM_BATTERY_STATUS_CRITICAL;
+ }
+
+ if (info->battery_life > BATTERY_HIGH_TRESHOLD)
+ info->battery_flag |= APM_BATTERY_FLAG_HIGH;
+ else if (info->battery_life > BATTERY_LOW_TRESHOLD)
+ info->battery_flag |= APM_BATTERY_FLAG_LOW;
+ else
+ info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
+}
+#else
+#define palmte_get_power_status NULL
+#endif
+
+static struct tsc2102_config palmte_tsc2102_config = {
+ .use_internal = 0,
+ .monitor = TSC_BAT1 | TSC_AUX | TSC_TEMP,
+ .temp_at25c = { 2200, 2615 },
+ .apm_report = palmte_get_power_status,
+ .alsa_config = &palmte_alsa_config,
+};
+
static struct omap_board_config_kernel palmte_config[] = {
- { OMAP_TAG_USB, &palmte_usb_config },
- { OMAP_TAG_MMC, &palmte_mmc_config },
- { OMAP_TAG_LCD, &palmte_lcd_config },
+ { OMAP_TAG_USB, &palmte_usb_config },
+ { OMAP_TAG_MMC, &palmte_mmc_config },
+ { OMAP_TAG_LCD, &palmte_lcd_config },
+ { OMAP_TAG_UART, &palmte_uart_config },
};
-static void __init omap_generic_init(void)
+static struct spi_board_info palmte_spi_info[] __initdata = {
+ {
+ .modalias = "tsc2102",
+ .bus_num = 2, /* uWire (officially) */
+ .chip_select = 0, /* As opposed to 3 */
+ .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
+ .platform_data = &palmte_tsc2102_config,
+ .max_speed_hz = 8000000,
+ },
+};
+
+/* Periodically check for changes on important input pins */
+struct timer_list palmte_pin_timer;
+int prev_power, prev_headphones;
+
+static void palmte_pin_handler(unsigned long data) {
+ int power, headphones;
+
+ power = !omap_get_gpio_datain(PALMTE_DC_GPIO);
+ headphones = omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO);
+
+ if (power && !prev_power)
+ printk(KERN_INFO "PM: cable connected\n");
+ else if (!power && prev_power)
+ printk(KERN_INFO "PM: cable disconnected\n");
+
+ if (headphones && !prev_headphones) {
+ /* Headphones connected, disable speaker */
+ omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 0);
+ printk(KERN_INFO "PM: speaker off\n");
+ } else if (!headphones && prev_headphones) {
+ /* Headphones unplugged, re-enable speaker */
+ omap_set_gpio_dataout(PALMTE_SPEAKER_GPIO, 1);
+ printk(KERN_INFO "PM: speaker on\n");
+ }
+
+ prev_power = power;
+ prev_headphones = headphones;
+ mod_timer(&palmte_pin_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static void __init palmte_gpio_setup(void)
+{
+ /* Set TSC2102 PINTDAV pin as input */
+ if (omap_request_gpio(PALMTE_PINTDAV_GPIO)) {
+ printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
+ return;
+ }
+ omap_set_gpio_direction(PALMTE_PINTDAV_GPIO, 1);
+
+ /* Monitor cable-connected signals */
+ if (omap_request_gpio(PALMTE_DC_GPIO) ||
+ omap_request_gpio(PALMTE_USB_OR_DC_GPIO) ||
+ omap_request_gpio(PALMTE_USBDETECT_GPIO)) {
+ printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
+ return;
+ }
+ omap_set_gpio_direction(PALMTE_DC_GPIO, 1);
+ omap_set_gpio_direction(PALMTE_USB_OR_DC_GPIO, 1);
+ omap_set_gpio_direction(PALMTE_USBDETECT_GPIO, 1);
+
+ /* Set speaker-enable pin as output */
+ if (omap_request_gpio(PALMTE_SPEAKER_GPIO)) {
+ printk(KERN_ERR "Could not reserve speaker GPIO!\n");
+ return;
+ }
+ omap_set_gpio_direction(PALMTE_SPEAKER_GPIO, 0);
+
+ /* Monitor the headphones-connected signal */
+ if (omap_request_gpio(PALMTE_HEADPHONES_GPIO)) {
+ printk(KERN_ERR "Could not reserve headphones signal GPIO!\n");
+ return;
+ }
+ omap_set_gpio_direction(PALMTE_HEADPHONES_GPIO, 1);
+
+ prev_power = omap_get_gpio_datain(PALMTE_DC_GPIO);
+ prev_headphones = !omap_get_gpio_datain(PALMTE_HEADPHONES_GPIO);
+ setup_timer(&palmte_pin_timer, palmte_pin_handler, 0);
+ palmte_pin_handler(0);
+}
+
+static void __init omap_palmte_init(void)
{
omap_board_config = palmte_config;
omap_board_config_size = ARRAY_SIZE(palmte_config);
platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
+
+ omap_serial_init();
+ palmte_gpio_setup();
}
-static void __init omap_generic_map_io(void)
+static void __init omap_palmte_map_io(void)
{
omap1_map_common_io();
}
@@ -90,8 +431,8 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
.phys_io = 0xfff00000,
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
- .map_io = omap_generic_map_io,
- .init_irq = omap_generic_init_irq,
- .init_machine = omap_generic_init,
+ .map_io = omap_palmte_map_io,
+ .init_irq = omap_palmte_init_irq,
+ .init_machine = omap_palmte_init,
.timer = &omap_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
new file mode 100644
index 00000000000..e47010fec27
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -0,0 +1,357 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmtt.c
+ *
+ * Modified from board-palmtt2.c
+ *
+ * Modified and amended for Palm Tungsten|T
+ * by Marek Vasut <marek.vasut@gmail.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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/clk.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/leds.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/led.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/common.h>
+#include <asm/arch/omap-alsa.h>
+
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+static int palmtt_keymap[] = {
+ KEY(0, 0, KEY_ESC),
+ KEY(0, 1, KEY_SPACE),
+ KEY(0, 2, KEY_LEFTCTRL),
+ KEY(0, 3, KEY_TAB),
+ KEY(0, 4, KEY_ENTER),
+ KEY(1, 0, KEY_LEFT),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_UP),
+ KEY(1, 3, KEY_RIGHT),
+ KEY(2, 0, KEY_SLEEP),
+ KEY(2, 4, KEY_Y),
+ 0
+};
+
+static struct mtd_partition palmtt_partitions[] = {
+ {
+ .name = "write8k",
+ .offset = 0,
+ .size = SZ_8K,
+ .mask_flags = 0,
+ },
+ {
+ .name = "PalmOS-BootLoader(ro)",
+ .offset = SZ_8K,
+ .size = 7 * SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * SZ_8K,
+ .mask_flags = 0,
+ },
+ {
+ .name = "PalmOS-FS(ro)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 7 * SZ_1M + 4 * SZ_64K - 16 * SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "u-boot(rez)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0
+ },
+ {
+ .name = "empty",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct flash_platform_data palmtt_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = palmtt_partitions,
+ .nr_parts = ARRAY_SIZE(palmtt_partitions),
+};
+
+static struct resource palmtt_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmtt_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &palmtt_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &palmtt_flash_resource,
+};
+
+#define DEFAULT_BITPERSAMPLE 16
+
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
+ .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
+ .spcr1 = RINTM(3) | RRST,
+ .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
+ RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
+ .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) |
+ RWDLEN1(OMAP_MCBSP_WORD_16),
+ .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
+ XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
+ .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) |
+ XWDLEN1(OMAP_MCBSP_WORD_16),
+ .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
+ .srgr2 = GSYNC | CLKSP | FSGM |
+ FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
+ .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
+};
+
+static struct omap_alsa_codec_config alsa_config = {
+ .name = "PalmTT AIC23",
+ .mcbsp_regs_alsa = &mcbsp_regs,
+ .codec_configure_dev = NULL, // aic23_configure,
+ .codec_set_samplerate = NULL, // aic23_set_samplerate,
+ .codec_clock_setup = NULL, // aic23_clock_setup,
+ .codec_clock_on = NULL, // aic23_clock_on,
+ .codec_clock_off = NULL, // aic23_clock_off,
+ .get_default_samplerate = NULL, // aic23_get_default_samplerate,
+};
+
+static struct platform_device palmtt_mcbsp1_device = {
+ .name = "omap_alsa_mcbsp",
+ .id = 1,
+ .dev = {
+ .platform_data = &alsa_config,
+ },
+};
+
+static struct resource palmtt_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data palmtt_kp_data = {
+ .rows = 6,
+ .cols = 3,
+ .keymap = palmtt_keymap,
+};
+
+static struct platform_device palmtt_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtt_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(palmtt_kp_resources),
+ .resource = palmtt_kp_resources,
+};
+
+static struct platform_device palmtt_lcd_device = {
+ .name = "lcd_palmtt",
+ .id = -1,
+};
+static struct omap_irda_config palmtt_irda_config = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource palmtt_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmtt_irda_device = {
+ .name = "omapirda",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtt_irda_config,
+ },
+ .num_resources = ARRAY_SIZE(palmtt_irda_resources),
+ .resource = palmtt_irda_resources,
+};
+
+static struct platform_device palmtt_spi_device = {
+ .name = "spi_palmtt",
+ .id = -1,
+};
+
+static struct omap_backlight_config palmtt_backlight_config = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device palmtt_backlight_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data= &palmtt_backlight_config,
+ },
+};
+
+static struct omap_led_config palmtt_led_config[] = {
+ {
+ .cdev = {
+ .name = "palmtt:led0",
+ },
+ .gpio = PALMTT_LED_GPIO,
+ },
+};
+
+static struct omap_led_platform_data palmtt_led_data = {
+ .nr_leds = ARRAY_SIZE(palmtt_led_config),
+ .leds = palmtt_led_config,
+};
+
+static struct platform_device palmtt_led_device = {
+ .name = "omap-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtt_led_data,
+ },
+};
+
+static struct platform_device *palmtt_devices[] __initdata = {
+ &palmtt_flash_device,
+ &palmtt_mcbsp1_device,
+ &palmtt_kp_device,
+ &palmtt_lcd_device,
+ &palmtt_irda_device,
+ &palmtt_spi_device,
+ &palmtt_backlight_device,
+ &palmtt_led_device,
+};
+
+static int palmtt_get_pendown_state(void)
+{
+ return !omap_get_gpio_datain(6);
+}
+
+static const struct ads7846_platform_data palmtt_ts_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .get_pendown_state = palmtt_get_pendown_state,
+};
+
+static struct spi_board_info __initdata palmtt_boardinfo[] = {
+ {
+ /* MicroWire (bus 2) CS0 has an ads7846e */
+ .modalias = "ads7846",
+ .platform_data = &palmtt_ts_info,
+ .irq = OMAP_GPIO_IRQ(6),
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 2,
+ .chip_select = 0,
+ }
+};
+
+static void __init omap_palmtt_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static struct omap_usb_config palmtt_usb_config __initdata = {
+ .register_dev = 1,
+ .hmc_mode = 0,
+ .pins[0] = 2,
+};
+
+static struct omap_lcd_config palmtt_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_uart_config palmtt_uart_config __initdata = {
+ .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
+};
+
+static struct omap_board_config_kernel palmtt_config[] = {
+ { OMAP_TAG_USB, &palmtt_usb_config },
+ { OMAP_TAG_LCD, &palmtt_lcd_config },
+ { OMAP_TAG_UART, &palmtt_uart_config },
+};
+
+static void __init omap_mpu_wdt_mode(int mode) {
+ if (mode)
+ omap_writew(0x8000, OMAP_WDT_TIMER_MODE);
+ else {
+ omap_writew(0x00f5, OMAP_WDT_TIMER_MODE);
+ omap_writew(0x00a0, OMAP_WDT_TIMER_MODE);
+ }
+}
+
+static void __init omap_palmtt_init(void)
+{
+ omap_mpu_wdt_mode(0);
+
+ omap_board_config = palmtt_config;
+ omap_board_config_size = ARRAY_SIZE(palmtt_config);
+
+ platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices));
+
+ spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo));
+ omap_serial_init();
+}
+
+static void __init omap_palmtt_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
+ .phys_io = 0xfff00000,
+ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
+ .boot_params = 0x10000100,
+ .map_io = omap_palmtt_map_io,
+ .init_irq = omap_palmtt_init_irq,
+ .init_machine = omap_palmtt_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
new file mode 100644
index 00000000000..c275d517764
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -0,0 +1,383 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmz71.c
+ *
+ * Modified from board-generic.c
+ *
+ * Support for the Palm Zire71 PDA.
+ *
+ * Original version : Laurent Gonzalez
+ *
+ * Modified for zire71 : Marek Vasut
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/common.h>
+#include <asm/arch/omap-alsa.h>
+
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+static void __init
+omap_palmz71_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static int palmz71_keymap[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(0, 1, KEY_F2),
+ KEY(0, 2, KEY_F3),
+ KEY(0, 3, KEY_F4),
+ KEY(0, 4, KEY_POWER),
+ KEY(1, 0, KEY_LEFT),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_UP),
+ KEY(1, 3, KEY_RIGHT),
+ KEY(1, 4, KEY_CENTER),
+ KEY(2, 0, KEY_CAMERA),
+ 0,
+};
+
+static struct omap_kp_platform_data palmz71_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = palmz71_keymap,
+ .rep = 1,
+ .delay = 80,
+};
+
+static struct resource palmz71_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmz71_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(palmz71_kp_resources),
+ .resource = palmz71_kp_resources,
+};
+
+static struct mtd_partition palmz71_rom_partitions[] = {
+ /* PalmOS "Small ROM", contains the bootloader and the debugger */
+ {
+ .name = "smallrom",
+ .offset = 0,
+ .size = 0xa000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ /* PalmOS "Big ROM", a filesystem with all the OS code and data */
+ {
+ .name = "bigrom",
+ .offset = SZ_128K,
+ /*
+ * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
+ * 0x7b0000 bytes in the English-only ("enUS") version.
+ */
+ .size = 0x7b0000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct flash_platform_data palmz71_rom_data = {
+ .map_name = "map_rom",
+ .name = "onboardrom",
+ .width = 2,
+ .parts = palmz71_rom_partitions,
+ .nr_parts = ARRAY_SIZE(palmz71_rom_partitions),
+};
+
+static struct resource palmz71_rom_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmz71_rom_device = {
+ .name = "omapflash",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_rom_data,
+ },
+ .num_resources = 1,
+ .resource = &palmz71_rom_resource,
+};
+
+static struct platform_device palmz71_lcd_device = {
+ .name = "lcd_palmz71",
+ .id = -1,
+};
+
+static struct omap_irda_config palmz71_irda_config = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource palmz71_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmz71_irda_device = {
+ .name = "omapirda",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_irda_config,
+ },
+ .num_resources = ARRAY_SIZE(palmz71_irda_resources),
+ .resource = palmz71_irda_resources,
+};
+
+static struct platform_device palmz71_spi_device = {
+ .name = "spi_palmz71",
+ .id = -1,
+};
+
+#define DEFAULT_BITPERSAMPLE 16
+
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
+ .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
+ .spcr1 = RINTM(3) | RRST,
+ .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
+ RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
+ .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
+ .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
+ XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
+ .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
+ .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
+ .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
+ .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
+};
+
+static struct omap_alsa_codec_config alsa_config = {
+ .name = "PalmZ71 AIC23",
+ .mcbsp_regs_alsa = &mcbsp_regs,
+ .codec_configure_dev = NULL, /* aic23_configure */
+ .codec_set_samplerate = NULL, /* aic23_set_samplerate */
+ .codec_clock_setup = NULL, /* aic23_clock_setup */
+ .codec_clock_on = NULL, /* aic23_clock_on */
+ .codec_clock_off = NULL, /* aic23_clock_off */
+ .get_default_samplerate = NULL, /* aic23_get_default_samplerate */
+};
+
+static struct platform_device palmz71_mcbsp1_device = {
+ .name = "omap_alsa_mcbsp",
+ .id = 1,
+ .dev = {
+ .platform_data = &alsa_config,
+ },
+};
+
+static struct omap_backlight_config palmz71_backlight_config = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device palmz71_backlight_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_backlight_config,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &palmz71_rom_device,
+ &palmz71_kp_device,
+ &palmz71_mcbsp1_device,
+ &palmz71_lcd_device,
+ &palmz71_irda_device,
+ &palmz71_spi_device,
+ &palmz71_backlight_device,
+};
+
+static int
+palmz71_get_pendown_state(void)
+{
+ return !omap_get_gpio_datain(PALMZ71_PENIRQ_GPIO);
+}
+
+static const struct ads7846_platform_data palmz71_ts_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .get_pendown_state = palmz71_get_pendown_state,
+};
+
+static struct spi_board_info __initdata palmz71_boardinfo[] = { {
+ /* MicroWire (bus 2) CS0 has an ads7846e */
+ .modalias = "ads7846",
+ .platform_data = &palmz71_ts_info,
+ .irq = OMAP_GPIO_IRQ(PALMZ71_PENIRQ_GPIO),
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 2,
+ .chip_select = 0,
+} };
+
+static struct omap_usb_config palmz71_usb_config __initdata = {
+ .register_dev = 1, /* Mini-B only receptacle */
+ .hmc_mode = 0,
+ .pins[0] = 2,
+};
+
+static struct omap_mmc_config palmz71_mmc_config __initdata = {
+ .mmc[0] = {
+ .enabled = 1,
+ .wire4 = 0,
+ .wp_pin = PALMZ71_MMC_WP_GPIO,
+ .power_pin = -1,
+ .switch_pin = PALMZ71_MMC_IN_GPIO,
+ },
+};
+
+static struct omap_lcd_config palmz71_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_uart_config palmz71_uart_config __initdata = {
+ .enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
+};
+
+static struct omap_board_config_kernel palmz71_config[] = {
+ {OMAP_TAG_USB, &palmz71_usb_config},
+ {OMAP_TAG_MMC, &palmz71_mmc_config},
+ {OMAP_TAG_LCD, &palmz71_lcd_config},
+ {OMAP_TAG_UART, &palmz71_uart_config},
+};
+
+static irqreturn_t
+palmz71_powercable(int irq, void *dev_id)
+{
+ if (omap_get_gpio_datain(PALMZ71_USBDETECT_GPIO)) {
+ printk(KERN_INFO "PM: Power cable connected\n");
+ set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO),
+ IRQT_FALLING);
+ } else {
+ printk(KERN_INFO "PM: Power cable disconnected\n");
+ set_irq_type(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO),
+ IRQT_RISING);
+ }
+ return IRQ_HANDLED;
+}
+
+static void __init
+omap_mpu_wdt_mode(int mode)
+{
+ if (mode)
+ omap_writew(0x8000, OMAP_WDT_TIMER_MODE);
+ else {
+ omap_writew(0x00f5, OMAP_WDT_TIMER_MODE);
+ omap_writew(0x00a0, OMAP_WDT_TIMER_MODE);
+ }
+}
+
+static void __init
+palmz71_gpio_setup(int early)
+{
+ if (early) {
+ /* Only set GPIO1 so we have a working serial */
+ omap_set_gpio_dataout(1, 1);
+ omap_set_gpio_direction(1, 0);
+ } else {
+ /* Set MMC/SD host WP pin as input */
+ if (omap_request_gpio(PALMZ71_MMC_WP_GPIO)) {
+ printk(KERN_ERR "Could not reserve WP GPIO!\n");
+ return;
+ }
+ omap_set_gpio_direction(PALMZ71_MMC_WP_GPIO, 1);
+
+ /* Monitor the Power-cable-connected signal */
+ if (omap_request_gpio(PALMZ71_USBDETECT_GPIO)) {
+ printk(KERN_ERR
+ "Could not reserve cable signal GPIO!\n");
+ return;
+ }
+ omap_set_gpio_direction(PALMZ71_USBDETECT_GPIO, 1);
+ if (request_irq(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO),
+ palmz71_powercable, IRQF_SAMPLE_RANDOM,
+ "palmz71-cable", 0))
+ printk(KERN_ERR
+ "IRQ request for power cable failed!\n");
+ palmz71_powercable(OMAP_GPIO_IRQ(PALMZ71_USBDETECT_GPIO), 0);
+ }
+}
+
+static void __init
+omap_palmz71_init(void)
+{
+ palmz71_gpio_setup(1);
+ omap_mpu_wdt_mode(0);
+
+ omap_board_config = palmz71_config;
+ omap_board_config_size = ARRAY_SIZE(palmz71_config);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ spi_register_board_info(palmz71_boardinfo,
+ ARRAY_SIZE(palmz71_boardinfo));
+ omap_serial_init();
+ palmz71_gpio_setup(0);
+}
+
+static void __init
+omap_palmz71_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
+ .phys_io = 0xfff00000,
+ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
+ .boot_params = 0x10000100,.map_io = omap_palmz71_map_io,
+ .init_irq = omap_palmz71_init_irq,
+ .init_machine = omap_palmz71_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
new file mode 100644
index 00000000000..2743d639aa0
--- /dev/null
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -0,0 +1,494 @@
+/*
+* linux/arch/arm/mach-omap1/board-sx1.c
+*
+* Modified from board-generic.c
+*
+* Support for the Siemens SX1 mobile phone.
+*
+* Original version : Vladimir Ananiev (Vovan888-at-gmail com)
+*
+* Maintainters : Vladimir Ananiev (aka Vovan888), Sergge
+* oslik.ru
+*
+* 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/errno.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/omap-alsa.h>
+#include <asm/arch/keypad.h>
+
+/* Write to I2C device */
+int i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
+{
+ struct i2c_adapter *adap;
+ int err;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+
+ adap = i2c_get_adapter(0);
+ if (!adap)
+ return -ENODEV;
+ msg->addr = devaddr; /* I2C address of chip */
+ msg->flags = 0;
+ msg->len = 2;
+ msg->buf = data;
+ data[0] = regoffset; /* register num */
+ data[1] = value; /* register data */
+ err = i2c_transfer(adap, msg, 1);
+ if (err >= 0)
+ return 0;
+ return err;
+}
+
+/* Read from I2C device */
+int i2c_read_byte(u8 devaddr, u8 regoffset, u8 * value)
+{
+ struct i2c_adapter *adap;
+ int err;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+
+ adap = i2c_get_adapter(0);
+ if (!adap)
+ return -ENODEV;
+
+ msg->addr = devaddr; /* I2C address of chip */
+ msg->flags = 0;
+ msg->len = 1;
+ msg->buf = data;
+ data[0] = regoffset; /* register num */
+ err = i2c_transfer(adap, msg, 1);
+
+ msg->addr = devaddr; /* I2C address */
+ msg->flags = I2C_M_RD;
+ msg->len = 1;
+ msg->buf = data;
+ err = i2c_transfer(adap, msg, 1);
+ *value = data[0];
+
+ if (err >= 0)
+ return 0;
+ return err;
+}
+/* set keyboard backlight intensity */
+int sx1_setkeylight(u8 keylight)
+{
+ if (keylight > SOFIA_MAX_LIGHT_VAL)
+ keylight = SOFIA_MAX_LIGHT_VAL;
+ return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
+}
+/* get current keylight intensity */
+int sx1_getkeylight(u8 * keylight)
+{
+ return i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
+}
+/* set LCD backlight intensity */
+int sx1_setbacklight(u8 backlight)
+{
+ if (backlight > SOFIA_MAX_LIGHT_VAL)
+ backlight = SOFIA_MAX_LIGHT_VAL;
+ return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG, backlight);
+}
+/* get current LCD backlight intensity */
+int sx1_getbacklight (u8 * backlight)
+{
+ return i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG, backlight);
+}
+/* set LCD backlight power on/off */
+int sx1_setmmipower(u8 onoff)
+{
+ int err;
+ u8 dat = 0;
+ err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
+ if (err < 0)
+ return err;
+ if (onoff)
+ dat |= SOFIA_MMILIGHT_POWER;
+ else
+ dat &= ~SOFIA_MMILIGHT_POWER;
+ return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
+}
+/* set MMC power on/off */
+int sx1_setmmcpower(u8 onoff)
+{
+ int err;
+ u8 dat = 0;
+ err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
+ if (err < 0)
+ return err;
+ if (onoff)
+ dat |= SOFIA_MMC_POWER;
+ else
+ dat &= ~SOFIA_MMC_POWER;
+ return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
+}
+/* set USB power on/off */
+int sx1_setusbpower(u8 onoff)
+{
+ int err;
+ u8 dat = 0;
+ err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
+ if (err < 0)
+ return err;
+ if (onoff)
+ dat |= SOFIA_USB_POWER;
+ else
+ dat &= ~SOFIA_USB_POWER;
+ return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
+}
+
+EXPORT_SYMBOL(sx1_setkeylight);
+EXPORT_SYMBOL(sx1_getkeylight);
+EXPORT_SYMBOL(sx1_setbacklight);
+EXPORT_SYMBOL(sx1_getbacklight);
+EXPORT_SYMBOL(sx1_setmmipower);
+EXPORT_SYMBOL(sx1_setmmcpower);
+EXPORT_SYMBOL(sx1_setusbpower);
+
+/*----------- Keypad -------------------------*/
+
+static int sx1_keymap[] = {
+ KEY(5, 3, GROUP_0 | 117), /* camera Qt::Key_F17 */
+ KEY(0, 4, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
+ KEY(1, 4, GROUP_2 | 114), /* voice memo */
+ KEY(2, 4, GROUP_3 | 114), /* voice memo */
+ KEY(0, 0, GROUP_1 | KEY_F12), /* red button Qt::Key_Hangup */
+ KEY(4, 3, GROUP_1 | KEY_LEFT),
+ KEY(2, 3, GROUP_1 | KEY_DOWN),
+ KEY(1, 3, GROUP_1 | KEY_RIGHT),
+ KEY(0, 3, GROUP_1 | KEY_UP),
+ KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */
+ KEY(5, 0, GROUP_1 | KEY_1),
+ KEY(4, 0, GROUP_1 | KEY_2),
+ KEY(3, 0, GROUP_1 | KEY_3),
+ KEY(3, 4, GROUP_1 | KEY_4),
+ KEY(4, 4, GROUP_1 | KEY_5),
+ KEY(5, 4, GROUP_1 | KEY_KPASTERISK),/* "*" */
+ KEY(4, 1, GROUP_1 | KEY_6),
+ KEY(5, 1, GROUP_1 | KEY_7),
+ KEY(3, 1, GROUP_1 | KEY_8),
+ KEY(3, 2, GROUP_1 | KEY_9),
+ KEY(5, 2, GROUP_1 | KEY_0),
+ KEY(4, 2, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
+ KEY(0, 1, GROUP_1 | KEY_F11), /* green button Qt::Key_Call */
+ KEY(1, 2, GROUP_1 | KEY_YEN), /* left soft Qt::Key_Context1 */
+ KEY(2, 2, GROUP_1 | KEY_F8), /* right soft Qt::Key_Back */
+ KEY(2, 1, GROUP_1 | KEY_LEFTSHIFT), /* shift */
+ KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */
+ KEY(0, 2, GROUP_1 | KEY_F7), /* menu Qt::Key_Menu */
+ 0
+};
+
+static struct resource sx1_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_kp_platform_data sx1_kp_data = {
+ .rows = 6,
+ .cols = 6,
+ .keymap = sx1_keymap,
+ .keymapsize = ARRAY_SIZE(sx1_keymap),
+ .delay = 80,
+};
+
+static struct platform_device sx1_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &sx1_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(sx1_kp_resources),
+ .resource = sx1_kp_resources,
+};
+
+/*----------- IRDA -------------------------*/
+
+static struct omap_irda_config sx1_irda_data = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource sx1_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 irda_dmamask = 0xffffffff;
+
+static struct platform_device sx1_irda_device = {
+ .name = "omapirda",
+ .id = 0,
+ .dev = {
+ .platform_data = &sx1_irda_data,
+ .dma_mask = &irda_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(sx1_irda_resources),
+ .resource = sx1_irda_resources,
+};
+
+/*----------- McBSP & Sound -------------------------*/
+
+/* Playback interface - McBSP1 */
+static struct omap_mcbsp_reg_cfg mcbsp1_regs = {
+ .spcr2 = XINTM(3), /* SPCR2=30 */
+ .spcr1 = RINTM(3), /* SPCR1=30 */
+ .rcr2 = 0, /* RCR2 =00 */
+ .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1=140 */
+ .xcr2 = 0, /* XCR2 = 0 */
+ .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */
+ .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */
+ .srgr2 = FSGM | FPER(31), /* SRGR2=101f */
+ .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
+ /* PCR0 =0f0f */
+};
+
+/* TODO: PCM interface - McBSP2 */
+static struct omap_mcbsp_reg_cfg mcbsp2_regs = {
+ .spcr2 = FRST | GRST | XRST | XINTM(3), /* SPCR2=F1 */
+ .spcr1 = RINTM(3) | RRST, /* SPCR1=30 */
+ .rcr2 = 0, /* RCR2 =00 */
+ .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1 = 140 */
+ .xcr2 = 0, /* XCR2 = 0 */
+ .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */
+ .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */
+ .srgr2 = FSGM | FPER(31), /* SRGR2=101f */
+ .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
+ /* PCR0=0f0f */
+ /* mcbsp: slave */
+};
+
+static struct omap_alsa_codec_config sx1_alsa_config = {
+ .name = "SX1 EGold",
+ .mcbsp_regs_alsa = &mcbsp1_regs,
+};
+
+static struct platform_device sx1_mcbsp1_device = {
+ .name = "omap_alsa_mcbsp",
+ .id = 1,
+ .dev = {
+ .platform_data = &sx1_alsa_config,
+ },
+};
+
+/*----------- MTD -------------------------*/
+
+static struct mtd_partition sx1_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0x01800000,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M - 2 * SZ_128K,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct flash_platform_data sx1_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = sx1_partitions,
+ .nr_parts = ARRAY_SIZE(sx1_partitions),
+};
+
+#ifdef CONFIG_SX1_OLD_FLASH
+/* MTD Intel StrataFlash - old flashes */
+static struct resource sx1_old_flash_resource[] = {
+ [0] = {
+ .start = OMAP_CS0_PHYS, /* Physical */
+ .end = OMAP_CS0_PHYS + SZ_16M - 1,,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_CS1_PHYS,
+ .end = OMAP_CS1_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sx1_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sx1_flash_data,
+ },
+ .num_resources = 2,
+ .resource = &sx1_old_flash_resource,
+};
+#else
+/* MTD Intel 4000 flash - new flashes */
+static struct resource sx1_new_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device sx1_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sx1_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &sx1_new_flash_resource,
+};
+#endif
+
+/*----------- USB -------------------------*/
+
+static struct omap_usb_config sx1_usb_config __initdata = {
+ .otg = 0,
+ .register_dev = 1,
+ .register_host = 0,
+ .hmc_mode = 0,
+ .pins[0] = 2,
+ .pins[1] = 0,
+ .pins[2] = 0,
+};
+
+/*----------- MMC -------------------------*/
+
+static struct omap_mmc_config sx1_mmc_config __initdata = {
+ .mmc [0] = {
+ .enabled = 1,
+ .wire4 = 0,
+ .wp_pin = -1,
+ .power_pin = -1, /* power is in Sofia */
+ .switch_pin = OMAP_MPUIO(3),
+ },
+};
+
+/*----------- LCD -------------------------*/
+
+static struct platform_device sx1_lcd_device = {
+ .name = "lcd_sx1",
+ .id = -1,
+};
+
+static struct omap_lcd_config sx1_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+/*-----------------------------------------*/
+static struct platform_device *sx1_devices[] __initdata = {
+ &sx1_flash_device,
+ &sx1_kp_device,
+ &sx1_lcd_device,
+ &sx1_mcbsp1_device,
+ &sx1_irda_device,
+};
+/*-----------------------------------------*/
+
+static struct omap_uart_config sx1_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel sx1_config[] = {
+ { OMAP_TAG_USB, &sx1_usb_config },
+ { OMAP_TAG_MMC, &sx1_mmc_config },
+ { OMAP_TAG_LCD, &sx1_lcd_config },
+ { OMAP_TAG_UART, &sx1_uart_config },
+};
+/*-----------------------------------------*/
+static void __init omap_sx1_init(void)
+{
+ platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
+
+ omap_board_config = sx1_config;
+ omap_board_config_size = ARRAY_SIZE(sx1_config);
+ omap_serial_init();
+
+ /* turn on USB power */
+ /* sx1_setusbpower(1); cant do it here because i2c is not ready */
+ omap_request_gpio(1); /* A_IRDA_OFF */
+ omap_request_gpio(11); /* A_SWITCH */
+ omap_request_gpio(15); /* A_USB_ON */
+ omap_set_gpio_direction(1, 0);/* gpio1 -> output */
+ omap_set_gpio_direction(11, 0);/* gpio11 -> output */
+ omap_set_gpio_direction(15, 0);/* gpio15 -> output */
+ /* set GPIO data */
+ omap_set_gpio_dataout(1, 1);/*A_IRDA_OFF = 1 */
+ omap_set_gpio_dataout(11, 0);/*A_SWITCH = 0 */
+ omap_set_gpio_dataout(15, 0);/*A_USB_ON = 0 */
+
+}
+/*----------------------------------------*/
+static void __init omap_sx1_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+ omap_gpio_init();
+}
+/*----------------------------------------*/
+
+static void __init omap_sx1_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(SX1, "OMAP310 based Siemens SX1")
+ .phys_io = 0xfff00000,
+ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
+ .boot_params = 0x10000100,
+ .map_io = omap_sx1_map_io,
+ .init_irq = omap_sx1_init_irq,
+ .init_machine = omap_sx1_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 447a586eb33..214dd19889a 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
static int __init voiceblue_setup(void)
{
/* Setup panic notifier */
- notifier_chain_register(&panic_notifier_list, &panic_block);
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
return 0;
}
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index f625f6dd228..5d9faa68d2e 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -49,6 +49,15 @@ static void omap1_uart_recalc(struct clk * clk)
clk->rate = 12000000;
}
+static void omap1_sossi_recalc(struct clk *clk)
+{
+ u32 div = omap_readl(MOD_CONF_CTRL_1);
+
+ div = (div >> 17) & 0x7;
+ div++;
+ clk->rate = clk->parent->rate / div;
+}
+
static int omap1_clk_enable_dsp_domain(struct clk *clk)
{
int retval;
@@ -396,6 +405,31 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
return 0;
}
+static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
+{
+ u32 l;
+ int div;
+ unsigned long p_rate;
+
+ p_rate = clk->parent->rate;
+ /* Round towards slower frequency */
+ div = (p_rate + rate - 1) / rate;
+ div--;
+ if (div < 0 || div > 7)
+ return -EINVAL;
+
+ l = omap_readl(MOD_CONF_CTRL_1);
+ l &= ~(7 << 17);
+ l |= div << 17;
+ omap_writel(l, MOD_CONF_CTRL_1);
+
+ clk->rate = p_rate / (div + 1);
+ if (unlikely(clk->flags & RATE_PROPAGATES))
+ propagate_rate(clk);
+
+ return 0;
+}
+
static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate)
{
return 96000000 / calc_ext_dsor(rate);
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index f7df00205c4..6eadf72828d 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -17,6 +17,8 @@ static int omap1_clk_enable_generic(struct clk * clk);
static void omap1_clk_disable_generic(struct clk * clk);
static void omap1_ckctl_recalc(struct clk * clk);
static void omap1_watchdog_recalc(struct clk * clk);
+static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
+static void omap1_sossi_recalc(struct clk *clk);
static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
static int omap1_clk_enable_dsp_domain(struct clk * clk);
static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
@@ -168,9 +170,10 @@ static struct clk ck_dpll1 = {
static struct arm_idlect1_clk ck_dpll1out = {
.clk = {
- .name = "ck_dpll1out",
+ .name = "ck_dpll1out",
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL,
+ .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL |
+ ENABLE_REG_32BIT | RATE_PROPAGATES,
.enable_reg = (void __iomem *)ARM_IDLECT2,
.enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc,
@@ -180,6 +183,19 @@ static struct arm_idlect1_clk ck_dpll1out = {
.idlect_shift = 12,
};
+static struct clk sossi_ck = {
+ .name = "ck_sossi",
+ .parent = &ck_dpll1out.clk,
+ .flags = CLOCK_IN_OMAP16XX | CLOCK_NO_IDLE_PARENT |
+ ENABLE_REG_32BIT,
+ .enable_reg = (void __iomem *)MOD_CONF_CTRL_1,
+ .enable_bit = 16,
+ .recalc = &omap1_sossi_recalc,
+ .set_rate = &omap1_set_sossi_rate,
+ .enable = &omap1_clk_enable_generic,
+ .disable = &omap1_clk_disable_generic,
+};
+
static struct clk arm_ck = {
.name = "arm_ck",
.parent = &ck_dpll1,
@@ -282,7 +298,7 @@ static struct clk arminth_ck16xx = {
static struct clk dsp_ck = {
.name = "dsp_ck",
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL,
.enable_reg = (void __iomem *)ARM_CKCTL,
.enable_bit = EN_DSPCK,
@@ -295,7 +311,7 @@ static struct clk dsp_ck = {
static struct clk dspmmu_ck = {
.name = "dspmmu_ck",
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | ALWAYS_ENABLED,
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
@@ -306,7 +322,7 @@ static struct clk dspmmu_ck = {
static struct clk dspper_ck = {
.name = "dspper_ck",
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | VIRTUAL_IO_ADDRESS,
.enable_reg = (void __iomem *)DSP_IDLECT2,
.enable_bit = EN_PERCK,
@@ -320,7 +336,7 @@ static struct clk dspper_ck = {
static struct clk dspxor_ck = {
.name = "dspxor_ck",
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_IO_ADDRESS,
.enable_reg = (void __iomem *)DSP_IDLECT2,
.enable_bit = EN_XORPCK,
@@ -332,7 +348,7 @@ static struct clk dspxor_ck = {
static struct clk dsptim_ck = {
.name = "dsptim_ck",
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_IO_ADDRESS,
.enable_reg = (void __iomem *)DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
@@ -374,7 +390,7 @@ static struct clk arminth_ck1510 = {
static struct clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
- .name = "tibp_ck",
+ .name = "tipb_ck",
.parent = &tc_ck.clk,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
ALWAYS_ENABLED,
@@ -733,7 +749,7 @@ remains active during MPU idle whenever this is enabled */
static struct clk i2c_fck = {
.name = "i2c_fck",
.id = 1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+ .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
ALWAYS_ENABLED,
.parent = &armxor_ck.clk,
@@ -760,6 +776,7 @@ static struct clk * onchip_clks[] = {
&ck_dpll1,
/* CK_GEN1 clocks */
&ck_dpll1out.clk,
+ &sossi_ck,
&arm_ck,
&armper_ck.clk,
&arm_gpio_ck,
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
index a0cd001ac39..e7835d6f53a 100644
--- a/arch/arm/mach-omap1/leds-innovator.c
+++ b/arch/arm/mach-omap1/leds-innovator.c
@@ -95,8 +95,5 @@ void innovator_leds_event(led_event_t evt)
break;
}
- if (led_state & LED_STATE_ENABLED)
- ;
-
local_irq_restore(flags);
}
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 5432335bc49..52c70e5fcf6 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -283,6 +283,30 @@ MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
+
+/* parallel camera */
+MUX_CFG("J15_1610_CAM_LCLK", 4, 24, 0, 0, 18, 1, 0, 0, 0)
+MUX_CFG("J18_1610_CAM_D7", 4, 27, 0, 0, 19, 1, 0, 0, 0)
+MUX_CFG("J19_1610_CAM_D6", 5, 0, 0, 0, 20, 1, 0, 0, 0)
+MUX_CFG("J14_1610_CAM_D5", 5, 3, 0, 0, 21, 1, 0, 0, 0)
+MUX_CFG("K18_1610_CAM_D4", 5, 6, 0, 0, 22, 1, 0, 0, 0)
+MUX_CFG("K19_1610_CAM_D3", 5, 9, 0, 0, 23, 1, 0, 0, 0)
+MUX_CFG("K15_1610_CAM_D2", 5, 12, 0, 0, 24, 1, 0, 0, 0)
+MUX_CFG("K14_1610_CAM_D1", 5, 15, 0, 0, 25, 1, 0, 0, 0)
+MUX_CFG("L19_1610_CAM_D0", 5, 18, 0, 0, 26, 1, 0, 0, 0)
+MUX_CFG("L18_1610_CAM_VS", 5, 21, 0, 0, 27, 1, 0, 0, 0)
+MUX_CFG("L15_1610_CAM_HS", 5, 24, 0, 0, 28, 1, 0, 0, 0)
+MUX_CFG("M19_1610_CAM_RSTZ", 5, 27, 0, 0, 29, 0, 0, 0, 0)
+MUX_CFG("Y15_1610_CAM_OUTCLK", A, 0, 6, 2, 6, 0, 2, 0, 0)
+
+/* serial camera */
+MUX_CFG("H19_1610_CAM_EXCLK", 4, 21, 0, 0, 17, 0, 0, 0, 0)
+ /* REVISIT 5912 spec sez CCP_* can't pullup or pulldown ... ? */
+MUX_CFG("Y12_1610_CCP_CLKP", 8, 18, 6, 1, 24, 1, 1, 0, 0)
+MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0)
+MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0)
+MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0)
+
};
#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 2e68be60729..3bf01e28df3 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -35,10 +35,9 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
-#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
@@ -153,11 +152,8 @@ void omap_pm_idle(void)
use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
#endif
- if (omap_dma_running()) {
+ if (omap_dma_running())
use_idlect1 &= ~(1 << 6);
- if (omap_lcd_dma_ext_running())
- use_idlect1 &= ~(1 << 12);
- }
/* We should be able to remove the do_sleep variable and multiple
* tests above as soon as drivers, timer and DMA code have been fixed.
@@ -603,27 +599,15 @@ static void (*saved_idle)(void) = NULL;
/*
* omap_pm_prepare - Do preliminary suspend work.
- * @state: suspend state we're entering.
*
*/
-static int omap_pm_prepare(suspend_state_t state)
+static int omap_pm_prepare(void)
{
- int error = 0;
-
/* We cannot sleep in idle until we have resumed */
saved_idle = pm_idle;
pm_idle = NULL;
- switch (state)
- {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- break;
- default:
- return -EINVAL;
- }
-
- return error;
+ return 0;
}
@@ -651,16 +635,14 @@ static int omap_pm_enter(suspend_state_t state)
/**
* omap_pm_finish - Finish up suspend sequence.
- * @state: State we're coming out of.
*
* This is called after we wake back up (or if entering the sleep state
* failed).
*/
-static int omap_pm_finish(suspend_state_t state)
+static void omap_pm_finish(void)
{
pm_idle = saved_idle;
- return 0;
}
@@ -677,11 +659,11 @@ static struct irqaction omap_wakeup_irq = {
-static struct pm_ops omap_pm_ops ={
+static struct platform_suspend_ops omap_pm_ops ={
.prepare = omap_pm_prepare,
.enter = omap_pm_enter,
.finish = omap_pm_finish,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
static int __init omap_pm_init(void)
@@ -738,7 +720,7 @@ static int __init omap_pm_init(void)
else if (cpu_is_omap16xx())
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
- pm_set_ops(&omap_pm_ops);
+ suspend_set_ops(&omap_pm_ops);
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
omap_pm_init_proc();
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 7393109f5c3..7069c9d536f 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -11,6 +11,10 @@ config ARCH_OMAP2420
select OMAP_DM_TIMER
select ARCH_OMAP_OTG
+config ARCH_OMAP2430
+ bool "OMAP2430 support"
+ depends on ARCH_OMAP24XX
+
comment "OMAP Board Type"
depends on ARCH_OMAP2
@@ -21,8 +25,13 @@ config MACH_OMAP_GENERIC
config MACH_OMAP_H4
bool "OMAP 2420 H4 board"
depends on ARCH_OMAP2 && ARCH_OMAP24XX
- select OMAP_DEBUG_LEDS if LEDS || LEDS_OMAP_DEBUG
+ select OMAP_DEBUG_DEVICES
config MACH_OMAP_APOLLON
bool "OMAP 2420 Apollon board"
depends on ARCH_OMAP2 && ARCH_OMAP24XX
+
+config MACH_OMAP_2430SDP
+ bool "OMAP 2430 SDP board"
+ depends on ARCH_OMAP2 && ARCH_OMAP24XX
+
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 266d88e77bd..b05b738d31e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
+obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
new file mode 100644
index 00000000000..7e76fbf19b5
--- /dev/null
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -0,0 +1,218 @@
+/*
+ * linux/arch/arm/mach-omap2/board-2430sdp.c
+ *
+ * Copyright (C) 2006 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial Code : Based on a patch from Komal Shah and Richard Woodruff
+ * Updated the Code for 2430 SDP : Syed Mohammed Khasim
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include <asm/arch/gpmc.h>
+#include "prcm-regs.h"
+
+#include <asm/io.h>
+
+
+#define SDP2430_FLASH_CS 0
+#define SDP2430_SMC91X_CS 5
+
+static struct mtd_partition sdp2430_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct flash_platform_data sdp2430_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = sdp2430_partitions,
+ .nr_parts = ARRAY_SIZE(sdp2430_partitions),
+};
+
+static struct resource sdp2430_flash_resource = {
+ .start = SDP2430_CS0_BASE,
+ .end = SDP2430_CS0_BASE + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device sdp2430_flash_device = {
+ .name = "omapflash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sdp2430_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &sdp2430_flash_resource,
+};
+
+static struct resource sdp2430_smc91x_resources[] = {
+ [0] = {
+ .start = SDP2430_CS0_BASE,
+ .end = SDP2430_CS0_BASE + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+ .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdp2430_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sdp2430_smc91x_resources),
+ .resource = sdp2430_smc91x_resources,
+};
+
+static struct platform_device *sdp2430_devices[] __initdata = {
+ &sdp2430_smc91x_device,
+ &sdp2430_flash_device,
+};
+
+static inline void __init sdp2430_init_smc91x(void)
+{
+ int eth_cs;
+ unsigned long cs_mem_base;
+ unsigned int rate;
+ struct clk *l3ck;
+
+ eth_cs = SDP2430_SMC91X_CS;
+
+ l3ck = clk_get(NULL, "core_l3_ck");
+ if (IS_ERR(l3ck))
+ rate = 100000000;
+ else
+ rate = clk_get_rate(l3ck);
+
+ /* Make sure CS1 timings are correct, for 2430 always muxed */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
+
+ if (rate >= 160000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else if (rate >= 130000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else { /* rate = 100000000 */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
+ }
+
+ if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+ return;
+ }
+
+ sdp2430_smc91x_resources[0].start = cs_mem_base + 0x300;
+ sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f;
+ udelay(100);
+
+ if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+ OMAP24XX_ETHR_GPIO_IRQ);
+ gpmc_cs_free(eth_cs);
+ return;
+ }
+ omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
+
+}
+
+static void __init omap_2430sdp_init_irq(void)
+{
+ omap2_init_common_hw();
+ omap_init_irq();
+ omap_gpio_init();
+ sdp2430_init_smc91x();
+}
+
+static struct omap_uart_config sdp2430_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel sdp2430_config[] = {
+ {OMAP_TAG_UART, &sdp2430_uart_config},
+};
+
+static void __init omap_2430sdp_init(void)
+{
+ platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
+ omap_board_config = sdp2430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp2430_config);
+ omap_serial_init();
+}
+
+static void __init omap_2430sdp_map_io(void)
+{
+ omap2_map_common_io();
+}
+
+MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
+ /* Maintainer: Syed Khasim - Texas Instruments Inc */
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap_2430sdp_map_io,
+ .init_irq = omap_2430sdp_init_irq,
+ .init_machine = omap_2430sdp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 878ff9181d0..3bb49c17c85 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -25,6 +25,8 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/irq.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
@@ -32,10 +34,12 @@
#include <asm/mach/flash.h>
#include <asm/arch/gpio.h>
+#include <asm/arch/led.h>
#include <asm/arch/mux.h>
#include <asm/arch/usb.h>
#include <asm/arch/board.h>
#include <asm/arch/common.h>
+#include <asm/arch/gpmc.h>
#include "prcm-regs.h"
/* LED & Switch macros */
@@ -46,6 +50,9 @@
#define SW_UP_GPIO17 17
#define SW_DOWN_GPIO58 58
+#define APOLLON_FLASH_CS 0
+#define APOLLON_ETH_CS 1
+
static struct mtd_partition apollon_partitions[] = {
{
.name = "X-Loader + U-Boot",
@@ -85,10 +92,10 @@ static struct flash_platform_data apollon_flash_data = {
.nr_parts = ARRAY_SIZE(apollon_partitions),
};
-static struct resource apollon_flash_resource = {
- .start = APOLLON_CS0_BASE,
- .end = APOLLON_CS0_BASE + SZ_128K,
- .flags = IORESOURCE_MEM,
+static struct resource apollon_flash_resource[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
};
static struct platform_device apollon_onenand_device = {
@@ -97,14 +104,24 @@ static struct platform_device apollon_onenand_device = {
.dev = {
.platform_data = &apollon_flash_data,
},
- .num_resources = ARRAY_SIZE(&apollon_flash_resource),
- .resource = &apollon_flash_resource,
+ .num_resources = ARRAY_SIZE(apollon_flash_resource),
+ .resource = apollon_flash_resource,
};
+static void __init apollon_flash_init(void)
+{
+ unsigned long base;
+
+ if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
+ printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
+ return;
+ }
+ apollon_flash_resource[0].start = base;
+ apollon_flash_resource[0].end = base + SZ_128K - 1;
+}
+
static struct resource apollon_smc91x_resources[] = {
[0] = {
- .start = APOLLON_ETHR_START, /* Physical */
- .end = APOLLON_ETHR_START + 0xf,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -126,14 +143,51 @@ static struct platform_device apollon_lcd_device = {
.id = -1,
};
+static struct omap_led_config apollon_led_config[] = {
+ {
+ .cdev = {
+ .name = "apollon:led0",
+ },
+ .gpio = LED0_GPIO13,
+ },
+ {
+ .cdev = {
+ .name = "apollon:led1",
+ },
+ .gpio = LED1_GPIO14,
+ },
+ {
+ .cdev = {
+ .name = "apollon:led2",
+ },
+ .gpio = LED2_GPIO15,
+ },
+};
+
+static struct omap_led_platform_data apollon_led_data = {
+ .nr_leds = ARRAY_SIZE(apollon_led_config),
+ .leds = apollon_led_config,
+};
+
+static struct platform_device apollon_led_device = {
+ .name = "omap-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &apollon_led_data,
+ },
+};
+
static struct platform_device *apollon_devices[] __initdata = {
&apollon_onenand_device,
&apollon_smc91x_device,
&apollon_lcd_device,
+ &apollon_led_device,
};
static inline void __init apollon_init_smc91x(void)
{
+ unsigned long base;
+
/* Make sure CS1 timings are correct */
GPMC_CONFIG1_1 = 0x00011203;
GPMC_CONFIG2_1 = 0x001f1f01;
@@ -141,13 +195,20 @@ static inline void __init apollon_init_smc91x(void)
GPMC_CONFIG4_1 = 0x1c091c09;
GPMC_CONFIG5_1 = 0x041f1f1f;
GPMC_CONFIG6_1 = 0x000004c4;
- GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24);
+
+ if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
+ return;
+ }
+ apollon_smc91x_resources[0].start = base + 0x300;
+ apollon_smc91x_resources[0].end = base + 0x30f;
udelay(100);
omap_cfg_reg(W4__24XX_GPIO74);
if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
APOLLON_ETHR_GPIO_IRQ);
+ gpmc_cs_free(APOLLON_ETH_CS);
return;
}
omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
@@ -175,6 +236,13 @@ static struct omap_mmc_config apollon_mmc_config __initdata = {
},
};
+static struct omap_usb_config apollon_usb_config __initdata = {
+ .register_dev = 1,
+ .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
+
+ .pins[0] = 6,
+};
+
static struct omap_lcd_config apollon_lcd_config __initdata = {
.ctrl_name = "internal",
};
@@ -182,6 +250,7 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
static struct omap_board_config_kernel apollon_config[] = {
{ OMAP_TAG_UART, &apollon_uart_config },
{ OMAP_TAG_MMC, &apollon_mmc_config },
+ { OMAP_TAG_USB, &apollon_usb_config },
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
@@ -250,10 +319,22 @@ static void __init apollon_sw_init(void)
return;
}
+static void __init apollon_usb_init(void)
+{
+ /* USB device */
+ /* DEVICE_SUSPEND */
+ omap_cfg_reg(P21_242X_GPIO12);
+ omap_request_gpio(12);
+ omap_set_gpio_direction(12, 0); /* OUT */
+ omap_set_gpio_dataout(12, 0);
+}
+
static void __init omap_apollon_init(void)
{
apollon_led_init();
apollon_sw_init();
+ apollon_flash_init();
+ apollon_usb_init();
/* REVISIT: where's the correct place */
omap_cfg_reg(W19_24XX_SYS_NIRQ);
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 452193f0153..f125f432cc3 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -131,26 +131,6 @@ static struct platform_device h4_flash_device = {
.resource = &h4_flash_resource,
};
-static struct resource h4_smc91x_resources[] = {
- [0] = {
- .start = OMAP24XX_ETHR_START, /* Physical */
- .end = OMAP24XX_ETHR_START + 0xf,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
- .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device h4_smc91x_device = {
- .name = "smc91x",
- .id = -1,
- .num_resources = ARRAY_SIZE(h4_smc91x_resources),
- .resource = h4_smc91x_resources,
-};
-
/* Select between the IrDA and aGPS module
*/
static int h4_select_irda(struct device *dev, int state)
@@ -266,29 +246,14 @@ static struct platform_device h4_lcd_device = {
.id = -1,
};
-static struct resource h4_led_resources[] = {
- [0] = {
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device h4_led_device = {
- .name = "omap_dbg_led",
- .id = -1,
- .num_resources = ARRAY_SIZE(h4_led_resources),
- .resource = h4_led_resources,
-};
-
static struct platform_device *h4_devices[] __initdata = {
- &h4_smc91x_device,
&h4_flash_device,
&h4_irda_device,
&h4_kp_device,
&h4_lcd_device,
- &h4_led_device,
};
-static inline void __init h4_init_smc91x(void)
+static inline void __init h4_init_debug(void)
{
/* Make sure CS1 timings are correct */
GPMC_CONFIG1_1 = 0x00011200;
@@ -301,12 +266,8 @@ static inline void __init h4_init_smc91x(void)
udelay(100);
omap_cfg_reg(M15_24XX_GPIO92);
- if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
- printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
- OMAP24XX_ETHR_GPIO_IRQ);
- return;
- }
- omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
+ if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0)
+ gpmc_cs_free(eth_cs);
}
static void __init omap_h4_init_irq(void)
@@ -314,7 +275,6 @@ static void __init omap_h4_init_irq(void)
omap2_init_common_hw();
omap_init_irq();
omap_gpio_init();
- h4_init_smc91x();
}
static struct omap_uart_config h4_uart_config __initdata = {
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 52ec2f2d636..b603bc5f8e5 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -55,8 +55,10 @@ static void omap_init_i2c(void)
if (machine_is_omap_h4())
return;
- omap_cfg_reg(J15_24XX_I2C2_SCL);
- omap_cfg_reg(H19_24XX_I2C2_SDA);
+ if (!cpu_is_omap2430()) {
+ omap_cfg_reg(J15_24XX_I2C2_SCL);
+ omap_cfg_reg(H19_24XX_I2C2_SDA);
+ }
(void) platform_device_register(&omap_i2c_device2);
}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index e290b989aa9..5a4cc2076a7 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -22,7 +22,14 @@
#undef DEBUG
+#ifdef CONFIG_ARCH_OMAP2420
#define GPMC_BASE 0x6800a000
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+#define GPMC_BASE 0x6E000000
+#endif
+
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
#define GPMC_SYSSTATUS 0x14
@@ -88,7 +95,7 @@ u32 gpmc_cs_read_reg(int cs, int idx)
}
/* TODO: Add support for gpmc_fck to clock framework and use it */
-static unsigned long gpmc_get_fclk_period(void)
+unsigned long gpmc_get_fclk_period(void)
{
/* In picoseconds */
return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000);
@@ -104,6 +111,13 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
return (time_ns * 1000 + tick_ps - 1) / tick_ps;
}
+unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
+{
+ unsigned long ticks = gpmc_ns_to_ticks(time_ns);
+
+ return ticks * gpmc_get_fclk_period() / 1000;
+}
+
#ifdef DEBUG
static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
int time, const char *name)
@@ -120,15 +134,21 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
else
ticks = gpmc_ns_to_ticks(time);
nr_bits = end_bit - st_bit + 1;
- if (ticks >= 1 << nr_bits)
+ if (ticks >= 1 << nr_bits) {
+#ifdef DEBUG
+ printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+ cs, name, time, ticks, 1 << nr_bits);
+#endif
return -1;
+ }
mask = (1 << nr_bits) - 1;
l = gpmc_cs_read_reg(cs, reg);
#ifdef DEBUG
- printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n",
+ printk(KERN_INFO
+ "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
- (l >> st_bit) & mask);
+ (l >> st_bit) & mask, time);
#endif
l &= ~(mask << st_bit);
l |= ticks << st_bit;
@@ -157,7 +177,7 @@ int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
div = l / gpmc_get_fclk_period();
if (div > 4)
return -1;
- if (div < 0)
+ if (div <= 0)
div = 1;
return div;
@@ -191,14 +211,19 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
+ /* caller is expected to have initialized CONFIG1 to cover
+ * at least sync vs async
+ */
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+ if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
#ifdef DEBUG
- printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n",
- cs, gpmc_get_fclk_period(), div);
+ printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
+ cs, (div * gpmc_get_fclk_period()) / 1000, div);
#endif
-
- l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
- l &= ~0x03;
- l |= (div - 1);
+ l &= ~0x03;
+ l |= (div - 1);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
+ }
return 0;
}
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 871ace4fccb..4dfd878d796 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -17,7 +17,13 @@
#include <asm/io.h>
+#if defined(CONFIG_ARCH_OMAP2420)
#define OMAP24XX_TAP_BASE io_p2v(0x48014000)
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2430)
+#define OMAP24XX_TAP_BASE io_p2v(0x4900A000)
+#endif
#define OMAP_TAP_IDCODE 0x0204
#define OMAP_TAP_PROD_ID 0x0208
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 82dc70f6b77..5a4091f582e 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2005 Nokia Corporation
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * Updated map desc to add 2430 support : <x0khasim@ti.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
@@ -26,6 +27,7 @@
extern void omap_sram_init(void);
extern int omap2_clk_init(void);
extern void omap2_check_revision(void);
+extern void omap2_init_memory(void);
extern void gpmc_init(void);
extern void omapfb_reserve_sdram(void);
@@ -40,6 +42,20 @@ static struct map_desc omap2_io_desc[] __initdata = {
.length = L3_24XX_SIZE,
.type = MT_DEVICE
},
+#ifdef CONFIG_ARCH_OMAP2430
+ {
+ .virtual = L4_WK_243X_VIRT,
+ .pfn = __phys_to_pfn(L4_WK_243X_PHYS),
+ .length = L4_WK_243X_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP243X_GPMC_VIRT,
+ .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS),
+ .length = OMAP243X_GPMC_SIZE,
+ .type = MT_DEVICE
+ },
+#endif
{
.virtual = DSP_MEM_24XX_VIRT,
.pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS),
@@ -80,5 +96,11 @@ void __init omap2_init_common_hw(void)
{
omap2_mux_init();
omap2_clk_init();
+/*
+ * Need to Fix this for 2430
+ */
+#ifndef CONFIG_ARCH_OMAP2430
+ omap2_init_memory();
+#endif
gpmc_init();
}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index a39d3068030..f064f725e72 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -37,7 +37,7 @@ static struct omap_irq_bank {
} __attribute__ ((aligned(4))) irq_banks[] = {
{
/* MPU INTC */
- .base_reg = OMAP24XX_IC_BASE,
+ .base_reg = IO_ADDRESS(OMAP24XX_IC_BASE),
.nr_irqs = 96,
}, {
/* XXX: DSP INTC */
@@ -47,7 +47,7 @@ static struct omap_irq_bank {
/* XXX: FIQ and additional INTC support (only MPU at the moment) */
static void omap_ack_irq(unsigned int irq)
{
- omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
+ __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
}
static void omap_mask_irq(unsigned int irq)
@@ -60,7 +60,7 @@ static void omap_mask_irq(unsigned int irq)
irq %= 32;
}
- omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
+ __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
}
static void omap_unmask_irq(unsigned int irq)
@@ -73,7 +73,7 @@ static void omap_unmask_irq(unsigned int irq)
irq %= 32;
}
- omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
+ __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
}
static void omap_mask_ack_irq(unsigned int irq)
@@ -93,17 +93,20 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
{
unsigned long tmp;
- tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff;
+ tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff;
printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
"(revision %ld.%ld) with %d interrupts\n",
bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
- tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG);
+ tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG);
tmp |= 1 << 1; /* soft reset */
- omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
+ __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
- while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
+ while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
/* Wait for reset to complete */;
+
+ /* Enable autoidle */
+ __raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG);
}
void __init omap_init_irq(void)
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
index 85cbc2a2e66..3e5d8cd4ea4 100644
--- a/arch/arm/mach-omap2/memory.c
+++ b/arch/arm/mach-omap2/memory.c
@@ -30,6 +30,7 @@
#include "prcm-regs.h"
#include "memory.h"
+
static struct memory_timings mem_timings;
u32 omap2_memory_get_slow_dll_ctrl(void)
@@ -99,3 +100,20 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
/* 90 degree phase for anything below 133Mhz + disable DLL filter */
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
}
+
+/* turn on smart idle modes for SDRAM scheduler and controller */
+void __init omap2_init_memory(void)
+{
+ u32 l;
+
+ l = SMS_SYSCONFIG;
+ l &= ~(0x3 << 3);
+ l |= (0x2 << 3);
+ SMS_SYSCONFIG = l;
+
+ l = SDRC_SYSCONFIG;
+ l &= ~(0x3 << 3);
+ l |= (0x2 << 3);
+ SDRC_SYSCONFIG = l;
+
+}
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 0439906d5da..05750975d74 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -53,8 +53,8 @@ MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
/* 24xx GPMC chipselects, wait pin monitoring */
-MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1)
-MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1)
+MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1)
+MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1)
MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1)
MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1)
MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1)
@@ -67,18 +67,18 @@ MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
/* 24xx GPIO */
-MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
-MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1)
-MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
-MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
-MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
-MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
-MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
-MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
+MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
+MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1)
+MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
+MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
+MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
+MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
+MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
+MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
-MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
+MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
-MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1)
+MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1)
MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
MUX_CFG_24XX("P14_24XX_GPIO125", 0x140, 3, 1, 1, 1)
@@ -95,17 +95,17 @@ MUX_CFG_24XX("T3_242X_GPIO55", 0xd9, 3, 0, 0, 1)
MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1)
/* 24xx external DMA requests */
-MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1)
-MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1)
-MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1)
-MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1)
-MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1)
-MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1)
+MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1)
+MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1)
+MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1)
+MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1)
+MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1)
+MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1)
/* TSC IRQ */
MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
-/* UART3 */
+/* UART3 */
MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 6f4a5436d0c..baf7d82b458 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -16,10 +16,9 @@
* published by the Free Software Foundation.
*/
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
-#include <linux/pm.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
@@ -71,28 +70,12 @@ void omap2_pm_idle(void)
local_irq_enable();
}
-static int omap2_pm_prepare(suspend_state_t state)
+static int omap2_pm_prepare(void)
{
- int error = 0;
-
/* We cannot sleep in idle until we have resumed */
saved_idle = pm_idle;
pm_idle = NULL;
-
- switch (state)
- {
- case PM_SUSPEND_STANDBY:
- case PM_SUSPEND_MEM:
- break;
-
- case PM_SUSPEND_DISK:
- return -ENOTSUPP;
-
- default:
- return -EINVAL;
- }
-
- return error;
+ return 0;
}
#define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \
@@ -353,9 +336,6 @@ static int omap2_pm_enter(suspend_state_t state)
case PM_SUSPEND_MEM:
ret = omap2_pm_suspend();
break;
- case PM_SUSPEND_DISK:
- ret = -ENOTSUPP;
- break;
default:
ret = -EINVAL;
}
@@ -363,17 +343,16 @@ static int omap2_pm_enter(suspend_state_t state)
return ret;
}
-static int omap2_pm_finish(suspend_state_t state)
+static void omap2_pm_finish(void)
{
pm_idle = saved_idle;
- return 0;
}
-static struct pm_ops omap_pm_ops = {
+static struct platform_suspend_ops omap_pm_ops = {
.prepare = omap2_pm_prepare,
.enter = omap2_pm_enter,
.finish = omap2_pm_finish,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
int __init omap2_pm_init(void)
@@ -397,7 +376,7 @@ int __init omap2_pm_init(void)
omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
omap24xx_cpu_suspend_sz);
- pm_set_ops(&omap_pm_ops);
+ suspend_set_ops(&omap_pm_ops);
pm_idle = omap2_pm_idle;
pmdomain_init();
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
new file mode 100644
index 00000000000..80bb42eb508
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -0,0 +1,349 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-tusb6010.c
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <linux/usb/musb.h>
+
+#include <asm/arch/gpmc.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+
+
+static u8 async_cs, sync_cs;
+static unsigned refclk_psec;
+
+
+/* t2_ps, when quantized to fclk units, must happen no earlier than
+ * the clock after after t1_NS.
+ *
+ * Return a possibly updated value of t2_ps, converted to nsec.
+ */
+static unsigned
+next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
+{
+ unsigned t1_ps = t1_NS * 1000;
+ unsigned t1_f, t2_f;
+
+ if ((t1_ps + fclk_ps) < t2_ps)
+ return t2_ps / 1000;
+
+ t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
+ t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
+
+ if (t1_f >= t2_f)
+ t2_f = t1_f + 1;
+
+ return (t2_f * fclk_ps) / 1000;
+}
+
+/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
+
+static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+{
+ struct gpmc_timings t;
+ unsigned t_acsnh_advnh = sysclk_ps + 3000;
+ unsigned tmp;
+
+ memset(&t, 0, sizeof(t));
+
+ /* CS_ON = t_acsnh_acsnl */
+ t.cs_on = 8;
+ /* ADV_ON = t_acsnh_advnh - t_advn */
+ t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
+
+ /*
+ * READ ... from omap2420 TRM fig 12-13
+ */
+
+ /* ADV_RD_OFF = t_acsnh_advnh */
+ t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
+
+ /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
+ t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
+
+ /* ACCESS = counters continue only after nRDY */
+ tmp = t.oe_on * 1000 + 300;
+ t.access = next_clk(t.oe_on, tmp, fclk_ps);
+
+ /* OE_OFF = after data gets sampled */
+ tmp = t.access * 1000;
+ t.oe_off = next_clk(t.access, tmp, fclk_ps);
+
+ t.cs_rd_off = t.oe_off;
+
+ tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
+ t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
+
+ /*
+ * WRITE ... from omap2420 TRM fig 12-15
+ */
+
+ /* ADV_WR_OFF = t_acsnh_advnh */
+ t.adv_wr_off = t.adv_rd_off;
+
+ /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
+ t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
+
+ /* WE_OFF = after data gets sampled */
+ tmp = t.we_on * 1000 + 300;
+ t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+
+ t.cs_wr_off = t.we_off;
+
+ tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
+ t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+
+ return gpmc_cs_set_timings(async_cs, &t);
+}
+
+static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
+{
+ struct gpmc_timings t;
+ unsigned t_scsnh_advnh = sysclk_ps + 3000;
+ unsigned tmp;
+
+ memset(&t, 0, sizeof(t));
+ t.cs_on = 8;
+
+ /* ADV_ON = t_acsnh_advnh - t_advn */
+ t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
+
+ /* GPMC_CLK rate = fclk rate / div */
+ t.sync_clk = 12 /* 11.1 nsec */;
+ tmp = (t.sync_clk * 1000 + fclk_ps - 1) / fclk_ps;
+ if (tmp > 4)
+ return -ERANGE;
+ if (tmp <= 0)
+ tmp = 1;
+ t.page_burst_access = (fclk_ps * tmp) / 1000;
+
+ /*
+ * READ ... based on omap2420 TRM fig 12-19, 12-20
+ */
+
+ /* ADV_RD_OFF = t_scsnh_advnh */
+ t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
+
+ /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
+ tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
+ t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
+
+ /* ACCESS = number of clock cycles after t_adv_eon */
+ tmp = (t.oe_on * 1000) + (5 * fclk_ps);
+ t.access = next_clk(t.oe_on, tmp, fclk_ps);
+
+ /* OE_OFF = after data gets sampled */
+ tmp = (t.access * 1000) + (1 * fclk_ps);
+ t.oe_off = next_clk(t.access, tmp, fclk_ps);
+
+ t.cs_rd_off = t.oe_off;
+
+ tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
+ t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
+
+ /*
+ * WRITE ... based on omap2420 TRM fig 12-21
+ */
+
+ /* ADV_WR_OFF = t_scsnh_advnh */
+ t.adv_wr_off = t.adv_rd_off;
+
+ /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
+ tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
+ t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
+
+ /* WE_OFF = number of clock cycles after t_adv_wen */
+ tmp = (t.we_on * 1000) + (6 * fclk_ps);
+ t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+
+ t.cs_wr_off = t.we_off;
+
+ tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
+ t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+
+ return gpmc_cs_set_timings(sync_cs, &t);
+}
+
+extern unsigned long gpmc_get_fclk_period(void);
+
+/* tusb driver calls this when it changes the chip's clocking */
+int tusb6010_platform_retime(unsigned is_refclk)
+{
+ static const char error[] =
+ KERN_ERR "tusb6010 %s retime error %d\n";
+
+ unsigned fclk_ps = gpmc_get_fclk_period();
+ unsigned sysclk_ps;
+ int status;
+
+ if (!refclk_psec)
+ return -ENODEV;
+
+ sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
+
+ status = tusb_set_async_mode(sysclk_ps, fclk_ps);
+ if (status < 0) {
+ printk(error, "async", status);
+ goto done;
+ }
+ status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
+ if (status < 0)
+ printk(error, "sync", status);
+done:
+ return status;
+}
+EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
+
+static struct resource tusb_resources[] = {
+ /* Order is significant! The start/end fields
+ * are updated during setup..
+ */
+ { /* Asynchronous access */
+ .flags = IORESOURCE_MEM,
+ },
+ { /* Synchronous access */
+ .flags = IORESOURCE_MEM,
+ },
+ { /* IRQ */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 tusb_dmamask = ~(u32)0;
+
+static struct platform_device tusb_device = {
+ .name = "musb_hdrc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &tusb_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(tusb_resources),
+ .resource = tusb_resources,
+};
+
+
+/* this may be called only from board-*.c setup code */
+int __init
+tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
+ unsigned ps_refclk, unsigned waitpin,
+ unsigned async, unsigned sync,
+ unsigned irq, unsigned dmachan)
+{
+ int status;
+ static char error[] __initdata =
+ KERN_ERR "tusb6010 init error %d, %d\n";
+
+ /* ASYNC region, primarily for PIO */
+ status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
+ &tusb_resources[0].start);
+ if (status < 0) {
+ printk(error, 1, status);
+ return status;
+ }
+ tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
+ async_cs = async;
+ gpmc_cs_write_reg(async, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_PAGE_LEN(2)
+ | GPMC_CONFIG1_WAIT_READ_MON
+ | GPMC_CONFIG1_WAIT_WRITE_MON
+ | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
+ | GPMC_CONFIG1_READTYPE_ASYNC
+ | GPMC_CONFIG1_WRITETYPE_ASYNC
+ | GPMC_CONFIG1_DEVICESIZE_16
+ | GPMC_CONFIG1_DEVICETYPE_NOR
+ | GPMC_CONFIG1_MUXADDDATA);
+
+
+ /* SYNC region, primarily for DMA */
+ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
+ &tusb_resources[1].start);
+ if (status < 0) {
+ printk(error, 2, status);
+ return status;
+ }
+ tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
+ sync_cs = sync;
+ gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_READMULTIPLE_SUPP
+ | GPMC_CONFIG1_READTYPE_SYNC
+ | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
+ | GPMC_CONFIG1_WRITETYPE_SYNC
+ | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
+ | GPMC_CONFIG1_PAGE_LEN(2)
+ | GPMC_CONFIG1_WAIT_READ_MON
+ | GPMC_CONFIG1_WAIT_WRITE_MON
+ | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
+ | GPMC_CONFIG1_DEVICESIZE_16
+ | GPMC_CONFIG1_DEVICETYPE_NOR
+ | GPMC_CONFIG1_MUXADDDATA
+ /* fclk divider gets set later */
+ );
+
+ /* IRQ */
+ status = omap_request_gpio(irq);
+ if (status < 0) {
+ printk(error, 3, status);
+ return status;
+ }
+ omap_set_gpio_direction(irq, 1);
+ tusb_resources[2].start = irq + IH_GPIO_BASE;
+
+ /* set up memory timings ... can speed them up later */
+ if (!ps_refclk) {
+ printk(error, 4, status);
+ return -ENODEV;
+ }
+ refclk_psec = ps_refclk;
+ status = tusb6010_platform_retime(1);
+ if (status < 0) {
+ printk(error, 5, status);
+ return status;
+ }
+
+ /* finish device setup ... */
+ if (!data) {
+ printk(error, 6, status);
+ return -ENODEV;
+ }
+ data->multipoint = 1;
+ tusb_device.dev.platform_data = data;
+
+ /* REVISIT let the driver know what DMA channels work */
+ if (!dmachan)
+ tusb_device.dev.dma_mask = NULL;
+ else {
+ /* assume OMAP 2420 ES2.0 and later */
+ if (dmachan & (1 << 0))
+ omap_cfg_reg(AA10_242X_DMAREQ0);
+ if (dmachan & (1 << 1))
+ omap_cfg_reg(AA6_242X_DMAREQ1);
+ if (dmachan & (1 << 2))
+ omap_cfg_reg(E4_242X_DMAREQ2);
+ if (dmachan & (1 << 3))
+ omap_cfg_reg(G4_242X_DMAREQ3);
+ if (dmachan & (1 << 4))
+ omap_cfg_reg(D3_242X_DMAREQ4);
+ if (dmachan & (1 << 5))
+ omap_cfg_reg(E3_242X_DMAREQ5);
+ }
+
+ /* so far so good ... register the device */
+ status = platform_device_register(&tusb_device);
+ if (status < 0) {
+ printk(error, 7, status);
+ return status;
+ }
+ return 0;
+}
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
index 2a137f33f75..40116d25434 100644
--- a/arch/arm/mach-pnx4008/pm.c
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -15,7 +15,7 @@
#include <linux/rtc.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/delay.h>
#include <linux/clk.h>
@@ -117,7 +117,7 @@ static int pnx4008_pm_valid(suspend_state_t state)
(state == PM_SUSPEND_MEM);
}
-static struct pm_ops pnx4008_pm_ops = {
+static struct platform_suspend_ops pnx4008_pm_ops = {
.enter = pnx4008_pm_enter,
.valid = pnx4008_pm_valid,
};
@@ -146,7 +146,7 @@ static int __init pnx4008_pm_init(void)
return -ENOMEM;
}
- pm_set_ops(&pnx4008_pm_ops);
+ suspend_set_ops(&pnx4008_pm_ops);
return 0;
}
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 5ebec6d88b5..656d49661a2 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -1,6 +1,24 @@
if ARCH_PXA
-menu "Intel PXA2xx Implementations"
+menu "Intel PXA2xx/PXA3xx Implementations"
+
+if PXA3xx
+
+menu "Supported PXA3xx Processor Variants"
+
+config CPU_PXA300
+ bool "PXA300 (codename Monahans-L)"
+
+config CPU_PXA310
+ bool "PXA310 (codename Monahans-LV)"
+ select CPU_PXA300
+
+config CPU_PXA320
+ bool "PXA320 (codename Monahans-P)"
+
+endmenu
+
+endif
choice
prompt "Select target board"
@@ -41,6 +59,15 @@ config MACH_EM_X270
bool "CompuLab EM-x270 platform"
select PXA27x
+config MACH_ZYLONITE
+ bool "PXA3xx Development Platform"
+ select PXA3xx
+
+config MACH_ARMCORE
+ bool "CompuLab CM-X270 modules"
+ select PXA27x
+ select IWMMXT
+
endchoice
if PXA_SHARPSL
@@ -130,6 +157,11 @@ config PXA27x
help
Select code specific to PXA27x variants
+config PXA3xx
+ bool
+ help
+ Select code specific to PXA3xx variants
+
config PXA_SHARP_C7xx
bool
select PXA_SSP
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 7d6ab5c59ab..4263527e512 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,36 +3,51 @@
#
# Common support (must be linked before board specific support)
-obj-y += clock.o generic.o irq.o dma.o time.o
-obj-$(CONFIG_PXA25x) += pxa25x.o
-obj-$(CONFIG_PXA27x) += pxa27x.o
+obj-y += clock.o generic.o irq.o dma.o time.o
+obj-$(CONFIG_PXA25x) += pxa25x.o
+obj-$(CONFIG_PXA27x) += pxa27x.o
+obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
+obj-$(CONFIG_CPU_PXA300) += pxa300.o
+obj-$(CONFIG_CPU_PXA320) += pxa320.o
# Specific board support
-obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
-obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
-obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
+obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
+obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
-obj-$(CONFIG_MACH_TOSA) += tosa.o
-obj-$(CONFIG_MACH_EM_X270) += em-x270.o
+obj-$(CONFIG_MACH_TOSA) += tosa.o
+obj-$(CONFIG_MACH_EM_X270) += em-x270.o
+
+ifeq ($(CONFIG_MACH_ZYLONITE),y)
+ obj-y += zylonite.o
+ obj-$(CONFIG_CPU_PXA300) += zylonite_pxa300.o
+ obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
+endif
+
+obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o
# Support for blinky lights
led-y := leds.o
-led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
-led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o
-led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
-led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o
+led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
+led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o
+led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
+led-$(CONFIG_MACH_TRIZEPS4) += leds-trizeps4.o
-obj-$(CONFIG_LEDS) += $(led-y)
+obj-$(CONFIG_LEDS) += $(led-y)
# Misc features
-obj-$(CONFIG_PM) += pm.o sleep.o
-obj-$(CONFIG_PXA_SSP) += ssp.o
+obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PXA_SSP) += ssp.o
ifeq ($(CONFIG_PXA27x),y)
-obj-$(CONFIG_PM) += standby.o
+obj-$(CONFIG_PM) += standby.o
+endif
+
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
endif
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 34a31caa6f9..83ef5ecaf43 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -9,19 +9,15 @@
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
#include <asm/arch/pxa-regs.h>
#include <asm/hardware.h>
-struct clk {
- struct list_head node;
- unsigned long rate;
- struct module *owner;
- const char *name;
- unsigned int enabled;
- void (*enable)(void);
- void (*disable)(void);
-};
+#include "devices.h"
+#include "generic.h"
+#include "clock.h"
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
@@ -33,7 +29,8 @@ struct clk *clk_get(struct device *dev, const char *id)
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
- if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ if (strcmp(id, p->name) == 0 &&
+ (p->dev == NULL || p->dev == dev)) {
clk = p;
break;
}
@@ -46,7 +43,6 @@ EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
- module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
@@ -56,8 +52,12 @@ int clk_enable(struct clk *clk)
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
- clk->enable();
+ clk->ops->enable(clk);
spin_unlock_irqrestore(&clocks_lock, flags);
+
+ if (clk->delay)
+ udelay(clk->delay);
+
return 0;
}
EXPORT_SYMBOL(clk_enable);
@@ -70,54 +70,75 @@ void clk_disable(struct clk *clk)
spin_lock_irqsave(&clocks_lock, flags);
if (--clk->enabled == 0)
- clk->disable();
+ clk->ops->disable(clk);
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
- return clk->rate;
+ unsigned long rate;
+
+ rate = clk->rate;
+ if (clk->ops->getrate)
+ rate = clk->ops->getrate(clk);
+
+ return rate;
}
EXPORT_SYMBOL(clk_get_rate);
-static void clk_gpio27_enable(void)
+static void clk_gpio27_enable(struct clk *clk)
{
pxa_gpio_mode(GPIO11_3_6MHz_MD);
}
-static void clk_gpio27_disable(void)
+static void clk_gpio27_disable(struct clk *clk)
{
}
-static struct clk clk_gpio27 = {
- .name = "GPIO27_CLK",
- .rate = 3686400,
+static const struct clkops clk_gpio27_ops = {
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};
-int clk_register(struct clk *clk)
+
+void clk_cken_enable(struct clk *clk)
{
- mutex_lock(&clocks_mutex);
- list_add(&clk->node, &clocks);
- mutex_unlock(&clocks_mutex);
- return 0;
+ CKEN |= 1 << clk->cken;
}
-EXPORT_SYMBOL(clk_register);
-void clk_unregister(struct clk *clk)
+void clk_cken_disable(struct clk *clk)
{
+ CKEN &= ~(1 << clk->cken);
+}
+
+const struct clkops clk_cken_ops = {
+ .enable = clk_cken_enable,
+ .disable = clk_cken_disable,
+};
+
+static struct clk common_clks[] = {
+ {
+ .name = "GPIO27_CLK",
+ .ops = &clk_gpio27_ops,
+ .rate = 3686400,
+ },
+};
+
+void clks_register(struct clk *clks, size_t num)
+{
+ int i;
+
mutex_lock(&clocks_mutex);
- list_del(&clk->node);
+ for (i = 0; i < num; i++)
+ list_add(&clks[i].node, &clocks);
mutex_unlock(&clocks_mutex);
}
-EXPORT_SYMBOL(clk_unregister);
static int __init clk_init(void)
{
- clk_register(&clk_gpio27);
+ clks_register(common_clks, ARRAY_SIZE(common_clks));
return 0;
}
arch_initcall(clk_init);
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
new file mode 100644
index 00000000000..bc6b77e1592
--- /dev/null
+++ b/arch/arm/mach-pxa/clock.h
@@ -0,0 +1,43 @@
+struct clk;
+
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ unsigned long (*getrate)(struct clk *);
+};
+
+struct clk {
+ struct list_head node;
+ const char *name;
+ struct device *dev;
+ const struct clkops *ops;
+ unsigned long rate;
+ unsigned int cken;
+ unsigned int delay;
+ unsigned int enabled;
+};
+
+#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \
+ { \
+ .name = _name, \
+ .dev = _dev, \
+ .ops = &clk_cken_ops, \
+ .rate = _rate, \
+ .cken = CKEN_##_cken, \
+ .delay = _delay, \
+ }
+
+#define INIT_CK(_name, _cken, _ops, _dev) \
+ { \
+ .name = _name, \
+ .dev = _dev, \
+ .ops = _ops, \
+ .cken = CKEN_##_cken, \
+ }
+
+extern const struct clkops clk_cken_ops;
+
+void clk_cken_enable(struct clk *clk);
+void clk_cken_disable(struct clk *clk);
+
+void clks_register(struct clk *clks, size_t num);
diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c
new file mode 100644
index 00000000000..878d3b9b863
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x270-pci.c
@@ -0,0 +1,218 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x270-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ *
+ * Copyright (C) 2007 Compulab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+
+#include <asm/mach/pci.h>
+#include <asm/arch/cm-x270.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/mach-types.h>
+
+#include <asm/hardware/it8152.h>
+
+unsigned long it8152_base_address = CMX270_IT8152_VIRT;
+
+/*
+ * Only first 64MB of memory can be accessed via PCI.
+ * We use GFP_DMA to allocate safe buffers to do map/unmap.
+ * This is really ugly and we need a better way of specifying
+ * DMA-capable regions of memory.
+ */
+void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
+ unsigned long *zhole_size)
+{
+ unsigned int sz = SZ_64M >> PAGE_SHIFT;
+
+ printk(KERN_INFO "Adjusting zones for CM-x270\n");
+
+ /*
+ * Only adjust if > 64M on current system
+ */
+ if (node || (zone_size[0] <= sz))
+ return;
+
+ zone_size[1] = zone_size[0] - sz;
+ zone_size[0] = sz;
+ zhole_size[1] = zhole_size[0];
+ zhole_size[0] = 0;
+}
+
+static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+ /* clear our parent irq */
+ GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ);
+
+ it8152_irq_demux(irq, desc);
+}
+
+void __cmx270_pci_init_irq(void)
+{
+ it8152_init_irq();
+ pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ));
+ set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING);
+
+ set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ),
+ cmx270_it8152_irq_demux);
+}
+
+#ifdef CONFIG_PM
+static unsigned long sleep_save_ite[10];
+
+void __cmx270_pci_suspend(void)
+{
+ /* save ITE state */
+ sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR);
+ sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR);
+ sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR);
+
+ /* Clear ITE IRQ's */
+ __raw_writel((0), IT8152_INTC_PDCNIRR);
+ __raw_writel((0), IT8152_INTC_LPCNIRR);
+}
+
+void __cmx270_pci_resume(void)
+{
+ /* restore IT8152 state */
+ __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR);
+ __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR);
+ __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR);
+}
+#else
+void cmx270_pci_suspend(void) {}
+void cmx270_pci_resume(void) {}
+#endif
+
+/* PCI IRQ mapping*/
+static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ printk(KERN_DEBUG "===> %s: %s slot=%x, pin=%x\n", __FUNCTION__,
+ pci_name(dev), slot, pin);
+
+ irq = it8152_pci_map_irq(dev, slot, pin);
+ if (irq)
+ return irq;
+
+ /*
+ Here comes the ugly part. The routing is baseboard specific,
+ but defining a platform for each possible base of CM-x270 is
+ unrealistic. Here we keep mapping for ATXBase and SB-x270.
+ */
+ /* ATXBASE PCI slot */
+ if (slot == 7)
+ return IT8152_PCI_INTA;
+
+ /* ATXBase/SB-x270 CardBus */
+ if (slot == 8 || slot == 0)
+ return IT8152_PCI_INTB;
+
+ /* ATXBase Ethernet */
+ if (slot == 9)
+ return IT8152_PCI_INTA;
+
+ /* SB-x270 Ethernet */
+ if (slot == 16)
+ return IT8152_PCI_INTA;
+
+ /* PC104+ interrupt routing */
+ if ((slot == 17) || (slot == 19))
+ return IT8152_PCI_INTA;
+ if ((slot == 18) || (slot == 20))
+ return IT8152_PCI_INTB;
+
+ return(0);
+}
+
+static struct pci_bus * __init
+cmx270_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ printk(KERN_INFO "Initializing CM-X270 PCI subsystem\n");
+
+ __raw_writel(0x800, IT8152_PCI_CFG_ADDR);
+ if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) {
+ printk(KERN_INFO "PCI Bridge found.\n");
+
+ /* set PCI I/O base at 0 */
+ writel(0x848, IT8152_PCI_CFG_ADDR);
+ writel(0, IT8152_PCI_CFG_DATA);
+
+ /* set PCI memory base at 0 */
+ writel(0x840, IT8152_PCI_CFG_ADDR);
+ writel(0, IT8152_PCI_CFG_DATA);
+
+ writel(0x20, IT8152_GPIO_GPDR);
+
+ /* CardBus Controller on ATXbase baseboard */
+ writel(0x4000, IT8152_PCI_CFG_ADDR);
+ if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) {
+ printk(KERN_INFO "CardBus Bridge found.\n");
+
+ /* Configure socket 0 */
+ writel(0x408C, IT8152_PCI_CFG_ADDR);
+ writel(0x1022, IT8152_PCI_CFG_DATA);
+
+ writel(0x4080, IT8152_PCI_CFG_ADDR);
+ writel(0x3844d060, IT8152_PCI_CFG_DATA);
+
+ writel(0x4090, IT8152_PCI_CFG_ADDR);
+ writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
+ 0x60440000),
+ IT8152_PCI_CFG_DATA);
+
+ writel(0x4018, IT8152_PCI_CFG_ADDR);
+ writel(0xb0000000, IT8152_PCI_CFG_DATA);
+
+ /* Configure socket 1 */
+ writel(0x418C, IT8152_PCI_CFG_ADDR);
+ writel(0x1022, IT8152_PCI_CFG_DATA);
+
+ writel(0x4180, IT8152_PCI_CFG_ADDR);
+ writel(0x3844d060, IT8152_PCI_CFG_DATA);
+
+ writel(0x4190, IT8152_PCI_CFG_ADDR);
+ writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
+ 0x60440000),
+ IT8152_PCI_CFG_DATA);
+
+ writel(0x4118, IT8152_PCI_CFG_ADDR);
+ writel(0xb0000000, IT8152_PCI_CFG_DATA);
+ }
+ }
+ return it8152_pci_scan_bus(nr, sys);
+}
+
+static struct hw_pci cmx270_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .map_irq = cmx270_pci_map_irq,
+ .nr_controllers = 1,
+ .setup = it8152_pci_setup,
+ .scan = cmx270_pci_scan_bus,
+};
+
+static int __init cmx270_init_pci(void)
+{
+ if (machine_is_armcore())
+ pci_common_init(&cmx270_pci);
+
+ return 0;
+}
+
+subsys_initcall(cmx270_init_pci);
diff --git a/arch/arm/mach-pxa/cm-x270-pci.h b/arch/arm/mach-pxa/cm-x270-pci.h
new file mode 100644
index 00000000000..ffe37b66f9a
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x270-pci.h
@@ -0,0 +1,13 @@
+extern void __cmx270_pci_init_irq(void);
+extern void __cmx270_pci_suspend(void);
+extern void __cmx270_pci_resume(void);
+
+#ifdef CONFIG_PCI
+#define cmx270_pci_init_irq __cmx270_pci_init_irq
+#define cmx270_pci_suspend __cmx270_pci_suspend
+#define cmx270_pci_resume __cmx270_pci_resume
+#else
+#define cmx270_pci_init_irq() do {} while (0)
+#define cmx270_pci_suspend() do {} while (0)
+#define cmx270_pci_resume() do {} while (0)
+#endif
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
new file mode 100644
index 00000000000..177664ccb2e
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -0,0 +1,645 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x270.c
+ *
+ * Copyright (C) 2007 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/pm.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <linux/dm9000.h>
+#include <linux/rtc-v3020.h>
+#include <linux/serial_8250.h>
+
+#include <video/mbxfb.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/bitfield.h>
+#include <asm/arch/cm-x270.h>
+
+#include <asm/hardware/it8152.h>
+
+#include "generic.h"
+#include "cm-x270-pci.h"
+
+#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22))
+#define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22))
+
+static struct resource cmx270_dm9k_resource[] = {
+ [0] = {
+ .start = DM9000_PHYS_BASE,
+ .end = DM9000_PHYS_BASE + 4,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DM9000_PHYS_BASE + 8,
+ .end = DM9000_PHYS_BASE + 8 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = CMX270_ETHIRQ,
+ .end = CMX270_ETHIRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* for the moment we limit ourselves to 32bit IO until some
+ * better IO routines can be written and tested
+ */
+static struct dm9000_plat_data cmx270_dm9k_platdata = {
+ .flags = DM9000_PLATF_32BITONLY,
+};
+
+/* Ethernet device */
+static struct platform_device cmx270_device_dm9k = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cmx270_dm9k_resource),
+ .resource = cmx270_dm9k_resource,
+ .dev = {
+ .platform_data = &cmx270_dm9k_platdata,
+ }
+};
+
+/* audio device */
+static struct platform_device cmx270_audio_device = {
+ .name = "pxa2xx-ac97",
+ .id = -1,
+};
+
+/* touchscreen controller */
+static struct platform_device cmx270_ts_device = {
+ .name = "ucb1400_ts",
+ .id = -1,
+};
+
+/* RTC */
+static struct resource cmx270_v3020_resource[] = {
+ [0] = {
+ .start = RTC_PHYS_BASE,
+ .end = RTC_PHYS_BASE + 4,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct v3020_platform_data cmx270_v3020_pdata = {
+ .leftshift = 16,
+};
+
+static struct platform_device cmx270_rtc_device = {
+ .name = "v3020",
+ .num_resources = ARRAY_SIZE(cmx270_v3020_resource),
+ .resource = cmx270_v3020_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &cmx270_v3020_pdata,
+ }
+};
+
+/*
+ * CM-X270 LEDs
+ */
+static struct platform_device cmx270_led_device = {
+ .name = "cm-x270-led",
+ .id = -1,
+};
+
+/* 2700G graphics */
+static u64 fb_dma_mask = ~(u64)0;
+
+static struct resource cmx270_2700G_resource[] = {
+ /* frame buffer memory including ODFB and External SDRAM */
+ [0] = {
+ .start = MARATHON_PHYS,
+ .end = MARATHON_PHYS + 0x02000000,
+ .flags = IORESOURCE_MEM,
+ },
+ /* Marathon registers */
+ [1] = {
+ .start = MARATHON_PHYS + 0x03fe0000,
+ .end = MARATHON_PHYS + 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static unsigned long save_lcd_regs[10];
+
+static int cmx270_marathon_probe(struct fb_info *fb)
+{
+ /* save PXA-270 pin settings before enabling 2700G */
+ save_lcd_regs[0] = GPDR1;
+ save_lcd_regs[1] = GPDR2;
+ save_lcd_regs[2] = GAFR1_U;
+ save_lcd_regs[3] = GAFR2_L;
+ save_lcd_regs[4] = GAFR2_U;
+
+ /* Disable PXA-270 on-chip controller driving pins */
+ GPDR1 &= ~(0xfc000000);
+ GPDR2 &= ~(0x00c03fff);
+ GAFR1_U &= ~(0xfff00000);
+ GAFR2_L &= ~(0x0fffffff);
+ GAFR2_U &= ~(0x0000f000);
+ return 0;
+}
+
+static int cmx270_marathon_remove(struct fb_info *fb)
+{
+ GPDR1 = save_lcd_regs[0];
+ GPDR2 = save_lcd_regs[1];
+ GAFR1_U = save_lcd_regs[2];
+ GAFR2_L = save_lcd_regs[3];
+ GAFR2_U = save_lcd_regs[4];
+ return 0;
+}
+
+static struct mbxfb_platform_data cmx270_2700G_data = {
+ .xres = {
+ .min = 240,
+ .max = 1200,
+ .defval = 640,
+ },
+ .yres = {
+ .min = 240,
+ .max = 1200,
+ .defval = 480,
+ },
+ .bpp = {
+ .min = 16,
+ .max = 32,
+ .defval = 16,
+ },
+ .memsize = 8*1024*1024,
+ .probe = cmx270_marathon_probe,
+ .remove = cmx270_marathon_remove,
+};
+
+static struct platform_device cmx270_2700G = {
+ .name = "mbx-fb",
+ .dev = {
+ .platform_data = &cmx270_2700G_data,
+ .dma_mask = &fb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(cmx270_2700G_resource),
+ .resource = cmx270_2700G_resource,
+ .id = -1,
+};
+
+static u64 ata_dma_mask = ~(u64)0;
+
+static struct platform_device cmx270_ata = {
+ .name = "pata_cm_x270",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ata_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+/* platform devices */
+static struct platform_device *platform_devices[] __initdata = {
+ &cmx270_device_dm9k,
+ &cmx270_audio_device,
+ &cmx270_rtc_device,
+ &cmx270_2700G,
+ &cmx270_led_device,
+ &cmx270_ts_device,
+ &cmx270_ata,
+};
+
+/* Map PCI companion and IDE/General Purpose CS statically */
+static struct map_desc cmx270_io_desc[] __initdata = {
+ [0] = { /* IDE/general purpose space */
+ .virtual = CMX270_IDE104_VIRT,
+ .pfn = __phys_to_pfn(CMX270_IDE104_PHYS),
+ .length = SZ_64M - SZ_8M,
+ .type = MT_DEVICE
+ },
+ [1] = { /* PCI bridge */
+ .virtual = CMX270_IT8152_VIRT,
+ .pfn = __phys_to_pfn(CMX270_IT8152_PHYS),
+ .length = SZ_64M,
+ .type = MT_DEVICE
+ },
+};
+
+/*
+ Display definitions
+ keep these for backwards compatibility, although symbolic names (as
+ e.g. in lpd270.c) looks better
+*/
+#define MTYPE_STN320x240 0
+#define MTYPE_TFT640x480 1
+#define MTYPE_CRT640x480 2
+#define MTYPE_CRT800x600 3
+#define MTYPE_TFT320x240 6
+#define MTYPE_STN640x480 7
+
+static struct pxafb_mode_info generic_stn_320x240_mode = {
+ .pixclock = 76923,
+ .bpp = 8,
+ .xres = 320,
+ .yres = 240,
+ .hsync_len = 3,
+ .vsync_len = 2,
+ .left_margin = 3,
+ .upper_margin = 0,
+ .right_margin = 3,
+ .lower_margin = 0,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_stn_320x240 = {
+ .modes = &generic_stn_320x240_mode,
+ .num_modes = 1,
+ .lccr0 = 0,
+ .lccr3 = (LCCR3_PixClkDiv(0x03) |
+ LCCR3_Acb(0xff) |
+ LCCR3_PCP),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_tft_640x480_mode = {
+ .pixclock = 38461,
+ .bpp = 8,
+ .xres = 640,
+ .yres = 480,
+ .hsync_len = 60,
+ .vsync_len = 2,
+ .left_margin = 70,
+ .upper_margin = 10,
+ .right_margin = 70,
+ .lower_margin = 5,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_tft_640x480 = {
+ .modes = &generic_tft_640x480_mode,
+ .num_modes = 1,
+ .lccr0 = (LCCR0_PAS),
+ .lccr3 = (LCCR3_PixClkDiv(0x01) |
+ LCCR3_Acb(0xff) |
+ LCCR3_PCP),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_crt_640x480_mode = {
+ .pixclock = 38461,
+ .bpp = 8,
+ .xres = 640,
+ .yres = 480,
+ .hsync_len = 63,
+ .vsync_len = 2,
+ .left_margin = 81,
+ .upper_margin = 33,
+ .right_margin = 16,
+ .lower_margin = 10,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_crt_640x480 = {
+ .modes = &generic_crt_640x480_mode,
+ .num_modes = 1,
+ .lccr0 = (LCCR0_PAS),
+ .lccr3 = (LCCR3_PixClkDiv(0x01) |
+ LCCR3_Acb(0xff)),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_crt_800x600_mode = {
+ .pixclock = 28846,
+ .bpp = 8,
+ .xres = 800,
+ .yres = 600,
+ .hsync_len = 63,
+ .vsync_len = 2,
+ .left_margin = 26,
+ .upper_margin = 21,
+ .right_margin = 26,
+ .lower_margin = 11,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_crt_800x600 = {
+ .modes = &generic_crt_800x600_mode,
+ .num_modes = 1,
+ .lccr0 = (LCCR0_PAS),
+ .lccr3 = (LCCR3_PixClkDiv(0x02) |
+ LCCR3_Acb(0xff)),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_tft_320x240_mode = {
+ .pixclock = 134615,
+ .bpp = 16,
+ .xres = 320,
+ .yres = 240,
+ .hsync_len = 63,
+ .vsync_len = 7,
+ .left_margin = 75,
+ .upper_margin = 0,
+ .right_margin = 15,
+ .lower_margin = 15,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_tft_320x240 = {
+ .modes = &generic_tft_320x240_mode,
+ .num_modes = 1,
+ .lccr0 = (LCCR0_PAS),
+ .lccr3 = (LCCR3_PixClkDiv(0x06) |
+ LCCR3_Acb(0xff) |
+ LCCR3_PCP),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_stn_640x480_mode = {
+ .pixclock = 57692,
+ .bpp = 8,
+ .xres = 640,
+ .yres = 480,
+ .hsync_len = 4,
+ .vsync_len = 2,
+ .left_margin = 10,
+ .upper_margin = 5,
+ .right_margin = 10,
+ .lower_margin = 5,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_stn_640x480 = {
+ .modes = &generic_stn_640x480_mode,
+ .num_modes = 1,
+ .lccr0 = 0,
+ .lccr3 = (LCCR3_PixClkDiv(0x02) |
+ LCCR3_Acb(0xff)),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mach_info *cmx270_display = &generic_crt_640x480;
+
+static int __init cmx270_set_display(char *str)
+{
+ int disp_type = simple_strtol(str, NULL, 0);
+ switch (disp_type) {
+ case MTYPE_STN320x240:
+ cmx270_display = &generic_stn_320x240;
+ break;
+ case MTYPE_TFT640x480:
+ cmx270_display = &generic_tft_640x480;
+ break;
+ case MTYPE_CRT640x480:
+ cmx270_display = &generic_crt_640x480;
+ break;
+ case MTYPE_CRT800x600:
+ cmx270_display = &generic_crt_800x600;
+ break;
+ case MTYPE_TFT320x240:
+ cmx270_display = &generic_tft_320x240;
+ break;
+ case MTYPE_STN640x480:
+ cmx270_display = &generic_stn_640x480;
+ break;
+ default: /* fallback to CRT 640x480 */
+ cmx270_display = &generic_crt_640x480;
+ break;
+ }
+ return 1;
+}
+
+/*
+ This should be done really early to get proper configuration for
+ frame buffer.
+ Indeed, pxafb parameters can be used istead, but CM-X270 bootloader
+ has limitied line length for kernel command line, and also it will
+ break compatibitlty with proprietary releases already in field.
+*/
+__setup("monitor=", cmx270_set_display);
+
+/* PXA27x OHCI controller setup */
+static int cmx270_ohci_init(struct device *dev)
+{
+ /* Set the Power Control Polarity Low */
+ UHCHR = (UHCHR | UHCHR_PCPL) &
+ ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
+
+ return 0;
+}
+
+static struct pxaohci_platform_data cmx270_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .init = cmx270_ohci_init,
+};
+
+
+static int cmx270_mci_init(struct device *dev,
+ irq_handler_t cmx270_detect_int,
+ void *data)
+{
+ int err;
+
+ /*
+ * setup GPIO for PXA27x MMC controller
+ */
+ pxa_gpio_mode(GPIO32_MMCCLK_MD);
+ pxa_gpio_mode(GPIO112_MMCCMD_MD);
+ pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+ pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+ pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+ pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+ /* SB-X270 uses GPIO105 as SD power enable */
+ pxa_gpio_mode(105 | GPIO_OUT);
+
+ /* card detect IRQ on GPIO 83 */
+ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
+ set_irq_type(CMX270_MMC_IRQ, IRQT_FALLING);
+
+ err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't"
+ " request MMC card detect IRQ\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data *p_d = dev->platform_data;
+
+ if ((1 << vdd) & p_d->ocr_mask) {
+ printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+ GPCR(105) = GPIO_bit(105);
+ } else {
+ GPSR(105) = GPIO_bit(105);
+ printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+ }
+}
+
+static void cmx270_mci_exit(struct device *dev, void *data)
+{
+ free_irq(CMX270_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data cmx270_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = cmx270_mci_init,
+ .setpower = cmx270_mci_setpower,
+ .exit = cmx270_mci_exit,
+};
+
+#ifdef CONFIG_PM
+static unsigned long sleep_save_msc[10];
+
+static int cmx270_suspend(struct sys_device *dev, pm_message_t state)
+{
+ cmx270_pci_suspend();
+
+ /* save MSC registers */
+ sleep_save_msc[0] = MSC0;
+ sleep_save_msc[1] = MSC1;
+ sleep_save_msc[2] = MSC2;
+
+ /* setup power saving mode registers */
+ PCFR = 0x0;
+ PSLR = 0xff400000;
+ PMCR = 0x00000005;
+ PWER = 0x80000000;
+ PFER = 0x00000000;
+ PRER = 0x00000000;
+ PGSR0 = 0xC0018800;
+ PGSR1 = 0x004F0002;
+ PGSR2 = 0x6021C000;
+ PGSR3 = 0x00020000;
+
+ return 0;
+}
+
+static int cmx270_resume(struct sys_device *dev)
+{
+ cmx270_pci_resume();
+
+ /* restore MSC registers */
+ MSC0 = sleep_save_msc[0];
+ MSC1 = sleep_save_msc[1];
+ MSC2 = sleep_save_msc[2];
+
+ return 0;
+}
+
+static struct sysdev_class cmx270_pm_sysclass = {
+ set_kset_name("pm"),
+ .resume = cmx270_resume,
+ .suspend = cmx270_suspend,
+};
+
+static struct sys_device cmx270_pm_device = {
+ .cls = &cmx270_pm_sysclass,
+};
+
+static int __init cmx270_pm_init(void)
+{
+ int error;
+ error = sysdev_class_register(&cmx270_pm_sysclass);
+ if (error == 0)
+ error = sysdev_register(&cmx270_pm_device);
+ return error;
+}
+#else
+static int __init cmx270_pm_init(void) { return 0; }
+#endif
+
+static void __init cmx270_init(void)
+{
+ cmx270_pm_init();
+
+ set_pxa_fb_info(cmx270_display);
+
+ /* register CM-X270 platform devices */
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ /* set MCI and OHCI platform parameters */
+ pxa_set_mci_info(&cmx270_mci_platform_data);
+ pxa_set_ohci_info(&cmx270_ohci_platform_data);
+
+ /* This enables the STUART */
+ pxa_gpio_mode(GPIO46_STRXD_MD);
+ pxa_gpio_mode(GPIO47_STTXD_MD);
+
+ /* This enables the BTUART */
+ pxa_gpio_mode(GPIO42_BTRXD_MD);
+ pxa_gpio_mode(GPIO43_BTTXD_MD);
+ pxa_gpio_mode(GPIO44_BTCTS_MD);
+ pxa_gpio_mode(GPIO45_BTRTS_MD);
+}
+
+static void __init cmx270_init_irq(void)
+{
+ pxa27x_init_irq();
+
+
+ cmx270_pci_init_irq();
+
+ /* Setup interrupt for dm9000 */
+ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ));
+ set_irq_type(CMX270_ETHIRQ, IRQT_RISING);
+
+ /* Setup interrupt for 2700G */
+ pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ));
+ set_irq_type(CMX270_GFXIRQ, IRQT_FALLING);
+}
+
+static void __init cmx270_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
+}
+
+
+MACHINE_START(ARMCORE, "Compulab CM-x270")
+ .boot_params = 0xa0000100,
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = cmx270_map_io,
+ .init_irq = cmx270_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = cmx270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 636fdb1c049..94c8d5cdd60 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -9,3 +9,6 @@ extern struct platform_device pxa_device_i2c;
extern struct platform_device pxa_device_i2s;
extern struct platform_device pxa_device_ficp;
extern struct platform_device pxa_device_rtc;
+
+extern struct platform_device pxa27x_device_i2c_power;
+extern struct platform_device pxa27x_device_ohci;
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 5510f6fdce5..1c34946ee16 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -25,10 +25,6 @@
#include <linux/pm.h>
#include <linux/string.h>
-#include <linux/sched.h>
-#include <asm/cnt32_to_63.h>
-#include <asm/div64.h>
-
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -47,66 +43,39 @@
#include "generic.h"
/*
- * This is the PXA2xx sched_clock implementation. This has a resolution
- * of at least 308ns and a maximum value that depends on the value of
- * CLOCK_TICK_RATE.
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 582 seconds between successive
- * calls to this function.
+ * Get the clock frequency as reflected by CCCR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
*/
-unsigned long long sched_clock(void)
+unsigned int get_clk_frequency_khz(int info)
{
- unsigned long long v = cnt32_to_63(OSCR);
- /* Note: top bit ov v needs cleared unless multiplier is even. */
-
-#if CLOCK_TICK_RATE == 3686400
- /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */
- /* The <<1 is used to get rid of tick.hi top bit */
- v *= 78125<<1;
- do_div(v, 288<<1);
-#elif CLOCK_TICK_RATE == 3250000
- /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */
- v *= 4000;
- do_div(v, 13);
-#elif CLOCK_TICK_RATE == 3249600
- /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */
- v *= 625000;
- do_div(v, 2031);
-#else
-#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE"
- /*
- * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for
- * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand
- * years range and truncation to unsigned long long limits it to
- * sched_clock's max range of ~584 years. This is nice but with
- * higher computation cost.
- */
- {
- union {
- unsigned long long val;
- struct { unsigned long lo, hi; };
- } x;
- unsigned long long y;
-
- x.val = v;
- x.hi &= 0x7fffffff;
- y = (unsigned long long)x.lo * NSEC_PER_SEC;
- x.lo = y;
- y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC;
- x.hi = do_div(y, CLOCK_TICK_RATE);
- do_div(x.val, CLOCK_TICK_RATE);
- x.hi += y;
- v = x.val;
- }
-#endif
+ if (cpu_is_pxa21x() || cpu_is_pxa25x())
+ return pxa25x_get_clk_frequency_khz(info);
+ else if (cpu_is_pxa27x())
+ return pxa27x_get_clk_frequency_khz(info);
+ else
+ return pxa3xx_get_clk_frequency_khz(info);
+}
+EXPORT_SYMBOL(get_clk_frequency_khz);
- return v;
+/*
+ * Return the current memory clock frequency in units of 10kHz
+ */
+unsigned int get_memclk_frequency_10khz(void)
+{
+ if (cpu_is_pxa21x() || cpu_is_pxa25x())
+ return pxa25x_get_memclk_frequency_10khz();
+ else if (cpu_is_pxa27x())
+ return pxa27x_get_memclk_frequency_10khz();
+ else
+ return pxa3xx_get_memclk_frequency_10khz();
}
+EXPORT_SYMBOL(get_memclk_frequency_10khz);
/*
* Handy function to set GPIO alternate functions
*/
+int pxa_last_gpio;
int pxa_gpio_mode(int gpio_mode)
{
@@ -115,7 +84,7 @@ int pxa_gpio_mode(int gpio_mode)
int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
int gafr;
- if (gpio > PXA_LAST_GPIO)
+ if (gpio > pxa_last_gpio)
return -EINVAL;
local_irq_save(flags);
@@ -136,6 +105,44 @@ int pxa_gpio_mode(int gpio_mode)
EXPORT_SYMBOL(pxa_gpio_mode);
+int gpio_direction_input(unsigned gpio)
+{
+ unsigned long flags;
+ u32 mask;
+
+ if (gpio > pxa_last_gpio)
+ return -EINVAL;
+
+ mask = GPIO_bit(gpio);
+ local_irq_save(flags);
+ GPDR(gpio) &= ~mask;
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ unsigned long flags;
+ u32 mask;
+
+ if (gpio > pxa_last_gpio)
+ return -EINVAL;
+
+ mask = GPIO_bit(gpio);
+ local_irq_save(flags);
+ if (value)
+ GPSR(gpio) = mask;
+ else
+ GPCR(gpio) = mask;
+ GPDR(gpio) |= mask;
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
/*
* Return GPIO level
*/
@@ -159,7 +166,7 @@ EXPORT_SYMBOL(pxa_gpio_set_value);
/*
* Routine to safely enable or disable a clock in the CKEN
*/
-void pxa_set_cken(int clock, int enable)
+void __pxa_set_cken(int clock, int enable)
{
unsigned long flags;
local_irq_save(flags);
@@ -172,7 +179,7 @@ void pxa_set_cken(int clock, int enable)
local_irq_restore(flags);
}
-EXPORT_SYMBOL(pxa_set_cken);
+EXPORT_SYMBOL(__pxa_set_cken);
/*
* Intel PXA2xx internal register mapping.
@@ -329,21 +336,80 @@ void __init set_pxa_fb_parent(struct device *parent_dev)
pxa_device_fb.dev.parent = parent_dev;
}
+static struct resource pxa_resource_ffuart[] = {
+ {
+ .start = __PREG(FFUART),
+ .end = __PREG(FFUART) + 35,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_FFUART,
+ .end = IRQ_FFUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
struct platform_device pxa_device_ffuart= {
.name = "pxa2xx-uart",
.id = 0,
+ .resource = pxa_resource_ffuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
};
+
+static struct resource pxa_resource_btuart[] = {
+ {
+ .start = __PREG(BTUART),
+ .end = __PREG(BTUART) + 35,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_BTUART,
+ .end = IRQ_BTUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
struct platform_device pxa_device_btuart = {
.name = "pxa2xx-uart",
.id = 1,
+ .resource = pxa_resource_btuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_btuart),
};
+
+static struct resource pxa_resource_stuart[] = {
+ {
+ .start = __PREG(STUART),
+ .end = __PREG(STUART) + 35,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_STUART,
+ .end = IRQ_STUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
struct platform_device pxa_device_stuart = {
.name = "pxa2xx-uart",
.id = 2,
+ .resource = pxa_resource_stuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_stuart),
};
+
+static struct resource pxa_resource_hwuart[] = {
+ {
+ .start = __PREG(HWUART),
+ .end = __PREG(HWUART) + 47,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_HWUART,
+ .end = IRQ_HWUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
struct platform_device pxa_device_hwuart = {
.name = "pxa2xx-uart",
.id = 3,
+ .resource = pxa_resource_hwuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
};
static struct resource pxai2c_resources[] = {
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 91ab2ad8b34..b30f240a16c 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -15,14 +15,40 @@ extern struct sys_timer pxa_timer;
extern void __init pxa_init_irq_low(void);
extern void __init pxa_init_irq_high(void);
extern void __init pxa_init_irq_gpio(int gpio_nr);
+extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
extern void __init pxa25x_init_irq(void);
extern void __init pxa27x_init_irq(void);
+extern void __init pxa3xx_init_irq(void);
extern void __init pxa_map_io(void);
extern unsigned int get_clk_frequency_khz(int info);
+extern int pxa_last_gpio;
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
mi->bank[__nr].size = (__size), \
mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+#ifdef CONFIG_PXA25x
+extern unsigned pxa25x_get_clk_frequency_khz(int);
+extern unsigned pxa25x_get_memclk_frequency_10khz(void);
+#else
+#define pxa25x_get_clk_frequency_khz(x) (0)
+#define pxa25x_get_memclk_frequency_10khz() (0)
+#endif
+
+#ifdef CONFIG_PXA27x
+extern unsigned pxa27x_get_clk_frequency_khz(int);
+extern unsigned pxa27x_get_memclk_frequency_10khz(void);
+#else
+#define pxa27x_get_clk_frequency_khz(x) (0)
+#define pxa27x_get_memclk_frequency_10khz() (0)
+#endif
+
+#ifdef CONFIG_PXA3xx
+extern unsigned pxa3xx_get_clk_frequency_khz(int);
+extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
+#else
+#define pxa3xx_get_clk_frequency_khz(x) (0)
+#define pxa3xx_get_memclk_frequency_10khz() (0)
+#endif
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index ae2ae08032d..07acb45b16e 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -38,33 +38,11 @@ static void pxa_unmask_low_irq(unsigned int irq)
ICMR |= (1 << irq);
}
-static int pxa_set_wake(unsigned int irq, unsigned int on)
-{
- u32 mask;
-
- switch (irq) {
- case IRQ_RTCAlrm:
- mask = PWER_RTC;
- break;
-#ifdef CONFIG_PXA27x
- /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
-#endif
- default:
- return -EINVAL;
- }
- if (on)
- PWER |= mask;
- else
- PWER &= ~mask;
- return 0;
-}
-
static struct irq_chip pxa_internal_chip_low = {
.name = "SC",
.ack = pxa_mask_low_irq,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
- .set_wake = pxa_set_wake,
};
void __init pxa_init_irq_low(void)
@@ -87,7 +65,7 @@ void __init pxa_init_irq_low(void)
}
}
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
/*
* This is for the second set of internal IRQs as found on the PXA27x.
@@ -125,26 +103,6 @@ void __init pxa_init_irq_high(void)
}
#endif
-/* Note that if an input/irq line ever gets changed to an output during
- * suspend, the relevant PWER, PRER, and PFER bits should be cleared.
- */
-#ifdef CONFIG_PXA27x
-
-/* PXA27x: Various gpios can issue wakeup events. This logic only
- * handles the simple cases, not the WEMUX2 and WEMUX3 options
- */
-#define PXA27x_GPIO_NOWAKE_MASK \
- ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
-#define WAKEMASK(gpio) \
- (((gpio) <= 15) \
- ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
- : ((gpio == 35) ? (1 << 24) : 0))
-#else
-
-/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */
-#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
-#endif
-
/*
* PXA GPIO edge detection for IRQs:
* IRQs are generated on Falling-Edge, Rising-Edge, or both.
@@ -158,11 +116,9 @@ static long GPIO_IRQ_mask[4];
static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{
int gpio, idx;
- u32 mask;
gpio = IRQ_TO_GPIO(irq);
idx = gpio >> 5;
- mask = WAKEMASK(gpio);
if (type == IRQT_PROBE) {
/* Don't mess with enabled GPIOs using preconfigured edges or
@@ -182,19 +138,15 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
if (type & __IRQT_RISEDGE) {
/* printk("rising "); */
__set_bit (gpio, GPIO_IRQ_rising_edge);
- PRER |= mask;
} else {
__clear_bit (gpio, GPIO_IRQ_rising_edge);
- PRER &= ~mask;
}
if (type & __IRQT_FALEDGE) {
/* printk("falling "); */
__set_bit (gpio, GPIO_IRQ_falling_edge);
- PFER |= mask;
} else {
__clear_bit (gpio, GPIO_IRQ_falling_edge);
- PFER &= ~mask;
}
/* printk("edges\n"); */
@@ -213,29 +165,12 @@ static void pxa_ack_low_gpio(unsigned int irq)
GEDR0 = (1 << (irq - IRQ_GPIO0));
}
-static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
-{
- int gpio = IRQ_TO_GPIO(irq);
- u32 mask = WAKEMASK(gpio);
-
- if (!mask)
- return -EINVAL;
-
- if (on)
- PWER |= mask;
- else
- PWER &= ~mask;
- return 0;
-}
-
-
static struct irq_chip pxa_low_gpio_chip = {
.name = "GPIO-l",
.ack = pxa_ack_low_gpio,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
.set_type = pxa_gpio_irq_type,
- .set_wake = pxa_set_gpio_wake,
};
/*
@@ -342,13 +277,14 @@ static struct irq_chip pxa_muxed_gpio_chip = {
.mask = pxa_mask_muxed_gpio,
.unmask = pxa_unmask_muxed_gpio,
.set_type = pxa_gpio_irq_type,
- .set_wake = pxa_set_gpio_wake,
};
void __init pxa_init_irq_gpio(int gpio_nr)
{
int irq, i;
+ pxa_last_gpio = gpio_nr - 1;
+
/* clear all GPIO edge detects */
for (i = 0; i < gpio_nr; i += 32) {
GFER(i) = 0;
@@ -375,3 +311,13 @@ void __init pxa_init_irq_gpio(int gpio_nr)
set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
}
+
+void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
+{
+ pxa_internal_chip_low.set_wake = set_wake;
+#ifdef CONFIG_PXA27x
+ pxa_internal_chip_high.set_wake = set_wake;
+#endif
+ pxa_low_gpio_chip.set_wake = set_wake;
+ pxa_muxed_gpio_chip.set_wake = set_wake;
+}
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index e70048fd00a..011a1a72b61 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -512,6 +512,25 @@ static void __init lubbock_map_io(void)
pxa_gpio_mode(GPIO44_BTCTS_MD);
pxa_gpio_mode(GPIO45_BTRTS_MD);
+ GPSR(GPIO48_nPOE) =
+ GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) |
+ GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) |
+ GPIO_bit(GPIO52_nPCE_1) |
+ GPIO_bit(GPIO53_nPCE_2);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO52_nPCE_1_MD);
+ pxa_gpio_mode(GPIO53_nPCE_2_MD);
+ pxa_gpio_mode(GPIO54_pSKTSEL_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+
/* This is for the SMC chip select */
pxa_gpio_mode(GPIO79_nCS_3_MD);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index b02c79c7e6a..a4bc3483cbb 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -444,6 +444,25 @@ static void __init mainstone_init(void)
*/
pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
+ GPSR(GPIO48_nPOE) =
+ GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) |
+ GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) |
+ GPIO_bit(GPIO85_nPCE_1) |
+ GPIO_bit(GPIO54_nPCE_2);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO85_nPCE_1_MD);
+ pxa_gpio_mode(GPIO54_nPCE_2_MD);
+ pxa_gpio_mode(GPIO79_pSKTSEL_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
/* reading Mainstone's "Virtual Configuration Register"
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
new file mode 100644
index 00000000000..5cd3cadbbd1
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp.c
@@ -0,0 +1,235 @@
+/*
+ * linux/arch/arm/mach-pxa/mfp.c
+ *
+ * PXA3xx Multi-Function Pin Support
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/mfp.h>
+
+/* mfp_spin_lock is used to ensure that MFP register configuration
+ * (most likely a read-modify-write operation) is atomic, and that
+ * mfp_table[] is consistent
+ */
+static DEFINE_SPINLOCK(mfp_spin_lock);
+
+static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
+static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
+
+#define mfpr_readl(off) \
+ __raw_readl(mfpr_mmio_base + (off))
+
+#define mfpr_writel(off, val) \
+ __raw_writel(val, mfpr_mmio_base + (off))
+
+/*
+ * perform a read-back of any MFPR register to make sure the
+ * previous writings are finished
+ */
+#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
+
+static inline void __mfp_config(int pin, unsigned long val)
+{
+ unsigned long off = mfp_table[pin].mfpr_off;
+
+ mfp_table[pin].mfpr_val = val;
+ mfpr_writel(off, val);
+}
+
+void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num)
+{
+ int i, pin;
+ unsigned long val, flags;
+ mfp_cfg_t *mfp_cfg = mfp_cfgs;
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ for (i = 0; i < num; i++, mfp_cfg++) {
+ pin = MFP_CFG_PIN(*mfp_cfg);
+ val = MFP_CFG_VAL(*mfp_cfg);
+
+ BUG_ON(pin >= MFP_PIN_MAX);
+
+ __mfp_config(pin, val);
+ }
+
+ mfpr_sync();
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+unsigned long pxa3xx_mfp_read(int mfp)
+{
+ unsigned long val, flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ val = mfpr_readl(mfp_table[mfp].mfpr_off);
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+
+ return val;
+}
+
+void pxa3xx_mfp_write(int mfp, unsigned long val)
+{
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ mfpr_writel(mfp_table[mfp].mfpr_off, val);
+ mfpr_sync();
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void pxa3xx_mfp_set_afds(int mfp, int af, int ds)
+{
+ uint32_t mfpr_off, mfpr_val;
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ mfpr_off = mfp_table[mfp].mfpr_off;
+
+ mfpr_val = mfpr_readl(mfpr_off);
+ mfpr_val &= ~(MFPR_AF_MASK | MFPR_DRV_MASK);
+ mfpr_val |= (((af & 0x7) << MFPR_ALT_OFFSET) |
+ ((ds & 0x7) << MFPR_DRV_OFFSET));
+
+ mfpr_writel(mfpr_off, mfpr_val);
+ mfpr_sync();
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void pxa3xx_mfp_set_rdh(int mfp, int rdh)
+{
+ uint32_t mfpr_off, mfpr_val;
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ mfpr_off = mfp_table[mfp].mfpr_off;
+
+ mfpr_val = mfpr_readl(mfpr_off);
+ mfpr_val &= ~MFPR_RDH_MASK;
+
+ if (likely(rdh))
+ mfpr_val |= (1u << MFPR_SS_OFFSET);
+
+ mfpr_writel(mfpr_off, mfpr_val);
+ mfpr_sync();
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void pxa3xx_mfp_set_lpm(int mfp, int lpm)
+{
+ uint32_t mfpr_off, mfpr_val;
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ mfpr_off = mfp_table[mfp].mfpr_off;
+ mfpr_val = mfpr_readl(mfpr_off);
+ mfpr_val &= ~MFPR_LPM_MASK;
+
+ if (lpm & 0x1) mfpr_val |= 1u << MFPR_SON_OFFSET;
+ if (lpm & 0x2) mfpr_val |= 1u << MFPR_SD_OFFSET;
+ if (lpm & 0x4) mfpr_val |= 1u << MFPR_PU_OFFSET;
+ if (lpm & 0x8) mfpr_val |= 1u << MFPR_PD_OFFSET;
+ if (lpm &0x10) mfpr_val |= 1u << MFPR_PS_OFFSET;
+
+ mfpr_writel(mfpr_off, mfpr_val);
+ mfpr_sync();
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void pxa3xx_mfp_set_pull(int mfp, int pull)
+{
+ uint32_t mfpr_off, mfpr_val;
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ mfpr_off = mfp_table[mfp].mfpr_off;
+ mfpr_val = mfpr_readl(mfpr_off);
+ mfpr_val &= ~MFPR_PULL_MASK;
+ mfpr_val |= ((pull & 0x7u) << MFPR_PD_OFFSET);
+
+ mfpr_writel(mfpr_off, mfpr_val);
+ mfpr_sync();
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void pxa3xx_mfp_set_edge(int mfp, int edge)
+{
+ uint32_t mfpr_off, mfpr_val;
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ mfpr_off = mfp_table[mfp].mfpr_off;
+ mfpr_val = mfpr_readl(mfpr_off);
+
+ mfpr_val &= ~MFPR_EDGE_MASK;
+ mfpr_val |= (edge & 0x3u) << MFPR_ERE_OFFSET;
+ mfpr_val |= (!edge & 0x1) << MFPR_EC_OFFSET;
+
+ mfpr_writel(mfpr_off, mfpr_val);
+ mfpr_sync();
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
+{
+ struct pxa3xx_mfp_addr_map *p;
+ unsigned long offset, flags;
+ int i;
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ for (p = map; p->start != MFP_PIN_INVALID; p++) {
+ offset = p->offset;
+ i = p->start;
+
+ do {
+ mfp_table[i].mfpr_off = offset;
+ mfp_table[i].mfpr_val = 0;
+ offset += 4; i++;
+ } while ((i <= p->end) && (p->end != -1));
+ }
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void __init pxa3xx_init_mfp(void)
+{
+ memset(mfp_table, 0, sizeof(mfp_table));
+}
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index b59a81a8e7d..a941c71c7d0 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -86,7 +86,7 @@ static int pxa_pm_valid(suspend_state_t state)
return -EINVAL;
}
-static struct pm_ops pxa_pm_ops = {
+static struct platform_suspend_ops pxa_pm_ops = {
.valid = pxa_pm_valid,
.enter = pxa_pm_enter,
};
@@ -104,7 +104,7 @@ static int __init pxa_pm_init(void)
return -ENOMEM;
}
- pm_set_ops(&pxa_pm_ops);
+ suspend_set_ops(&pxa_pm_ops);
return 0;
}
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 6dfcca72e90..dcd81f8d083 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -20,7 +20,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <asm/hardware.h>
#include <asm/arch/irqs.h>
@@ -30,6 +30,7 @@
#include "generic.h"
#include "devices.h"
+#include "clock.h"
/*
* Various clock factors driven by the CCCR register.
@@ -53,7 +54,7 @@ static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
* We assume these values have been applied via a fcs.
* If info is not 0 we also display the current settings.
*/
-unsigned int get_clk_frequency_khz(int info)
+unsigned int pxa25x_get_clk_frequency_khz(int info)
{
unsigned long cccr, turbo;
unsigned int l, L, m, M, n2, N;
@@ -86,27 +87,48 @@ unsigned int get_clk_frequency_khz(int info)
return (turbo & 1) ? (N/1000) : (M/1000);
}
-EXPORT_SYMBOL(get_clk_frequency_khz);
-
/*
* Return the current memory clock frequency in units of 10kHz
*/
-unsigned int get_memclk_frequency_10khz(void)
+unsigned int pxa25x_get_memclk_frequency_10khz(void)
{
return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
}
-EXPORT_SYMBOL(get_memclk_frequency_10khz);
-
-/*
- * Return the current LCD clock frequency in units of 10kHz
- */
-unsigned int get_lcdclk_frequency_10khz(void)
+static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk)
{
- return get_memclk_frequency_10khz();
+ return pxa25x_get_memclk_frequency_10khz() * 10000;
}
-EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+static const struct clkops clk_pxa25x_lcd_ops = {
+ .enable = clk_cken_enable,
+ .disable = clk_cken_disable,
+ .getrate = clk_pxa25x_lcd_getrate,
+};
+
+/*
+ * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
+ * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
+ * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
+ */
+static struct clk pxa25x_clks[] = {
+ INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
+ INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev),
+ INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
+ INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
+ INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
+ INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
+ INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
+ INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
+ /*
+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
+ INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL),
+ INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL),
+ INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL),
+ */
+ INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
+};
#ifdef CONFIG_PM
@@ -193,7 +215,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
.save_size = SLEEP_SAVE_SIZE,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
.save = pxa25x_cpu_pm_save,
.restore = pxa25x_cpu_pm_restore,
.enter = pxa25x_cpu_pm_enter,
@@ -205,10 +227,52 @@ static void __init pxa25x_init_pm(void)
}
#endif
+/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
+ */
+
+static int pxa25x_set_wake(unsigned int irq, unsigned int on)
+{
+ int gpio = IRQ_TO_GPIO(irq);
+ uint32_t gpio_bit, mask = 0;
+
+ if (gpio >= 0 && gpio <= 15) {
+ gpio_bit = GPIO_bit(gpio);
+ mask = gpio_bit;
+ if (on) {
+ if (GRER(gpio) | gpio_bit)
+ PRER |= gpio_bit;
+ else
+ PRER &= ~gpio_bit;
+
+ if (GFER(gpio) | gpio_bit)
+ PFER |= gpio_bit;
+ else
+ PFER &= ~gpio_bit;
+ }
+ goto set_pwer;
+ }
+
+ if (irq == IRQ_RTCAlrm) {
+ mask = PWER_RTC;
+ goto set_pwer;
+ }
+
+ return -EINVAL;
+
+set_pwer:
+ if (on)
+ PWER |= mask;
+ else
+ PWER &=~mask;
+
+ return 0;
+}
+
void __init pxa25x_init_irq(void)
{
pxa_init_irq_low();
pxa_init_irq_gpio(85);
+ pxa_init_irq_set_wake(pxa25x_set_wake);
}
static struct platform_device *pxa25x_devices[] __initdata = {
@@ -229,6 +293,8 @@ static int __init pxa25x_init(void)
int ret = 0;
if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
+ clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks));
+
if ((ret = pxa_init_dma(16)))
return ret;
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 203371ab19d..d0f2b597db1 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -14,7 +14,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/platform_device.h>
#include <asm/hardware.h>
@@ -27,6 +27,7 @@
#include "generic.h"
#include "devices.h"
+#include "clock.h"
/* Crystal clock: 13MHz */
#define BASE_CLK 13000000
@@ -36,7 +37,7 @@
* We assume these values have been applied via a fcs.
* If info is not 0 we also display the current settings.
*/
-unsigned int get_clk_frequency_khz( int info)
+unsigned int pxa27x_get_clk_frequency_khz(int info)
{
unsigned long ccsr, clkcfg;
unsigned int l, L, m, M, n2, N, S;
@@ -79,7 +80,7 @@ unsigned int get_clk_frequency_khz( int info)
* Return the current mem clock frequency in units of 10kHz as
* reflected by CCCR[A], B, and L
*/
-unsigned int get_memclk_frequency_10khz(void)
+unsigned int pxa27x_get_memclk_frequency_10khz(void)
{
unsigned long ccsr, clkcfg;
unsigned int l, L, m, M;
@@ -104,7 +105,7 @@ unsigned int get_memclk_frequency_10khz(void)
/*
* Return the current LCD clock frequency in units of 10kHz as
*/
-unsigned int get_lcdclk_frequency_10khz(void)
+static unsigned int pxa27x_get_lcdclk_frequency_10khz(void)
{
unsigned long ccsr;
unsigned int l, L, k, K;
@@ -120,9 +121,47 @@ unsigned int get_lcdclk_frequency_10khz(void)
return (K / 10000);
}
-EXPORT_SYMBOL(get_clk_frequency_khz);
-EXPORT_SYMBOL(get_memclk_frequency_10khz);
-EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
+{
+ return pxa27x_get_lcdclk_frequency_10khz() * 10000;
+}
+
+static const struct clkops clk_pxa27x_lcd_ops = {
+ .enable = clk_cken_enable,
+ .disable = clk_cken_disable,
+ .getrate = clk_pxa27x_lcd_getrate,
+};
+
+static struct clk pxa27x_clks[] = {
+ INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev),
+ INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL),
+
+ INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
+ INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
+ INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
+
+ INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev),
+ INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
+ INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev),
+ INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev),
+ INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev),
+
+ INIT_CKEN("USBCLK", USB, 48000000, 0, &pxa27x_device_ohci.dev),
+ INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
+ INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
+
+ /*
+ INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
+ INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL),
+ INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL),
+ INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL),
+ INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
+ INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
+ INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
+ INIT_CKEN("IMCLK", IM, 0, 0, NULL),
+ INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL),
+ */
+};
#ifdef CONFIG_PM
@@ -267,6 +306,69 @@ static void __init pxa27x_init_pm(void)
}
#endif
+/* PXA27x: Various gpios can issue wakeup events. This logic only
+ * handles the simple cases, not the WEMUX2 and WEMUX3 options
+ */
+#define PXA27x_GPIO_NOWAKE_MASK \
+ ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
+#define WAKEMASK(gpio) \
+ (((gpio) <= 15) \
+ ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
+ : ((gpio == 35) ? (1 << 24) : 0))
+
+static int pxa27x_set_wake(unsigned int irq, unsigned int on)
+{
+ int gpio = IRQ_TO_GPIO(irq);
+ uint32_t mask;
+
+ if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) {
+ if (WAKEMASK(gpio) == 0)
+ return -EINVAL;
+
+ mask = WAKEMASK(gpio);
+
+ if (on) {
+ if (GRER(gpio) | GPIO_bit(gpio))
+ PRER |= mask;
+ else
+ PRER &= ~mask;
+
+ if (GFER(gpio) | GPIO_bit(gpio))
+ PFER |= mask;
+ else
+ PFER &= ~mask;
+ }
+ goto set_pwer;
+ }
+
+ switch (irq) {
+ case IRQ_RTCAlrm:
+ mask = PWER_RTC;
+ break;
+ case IRQ_USB:
+ mask = 1u << 26;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+set_pwer:
+ if (on)
+ PWER |= mask;
+ else
+ PWER &=~mask;
+
+ return 0;
+}
+
+void __init pxa27x_init_irq(void)
+{
+ pxa_init_irq_low();
+ pxa_init_irq_high();
+ pxa_init_irq_gpio(128);
+ pxa_init_irq_set_wake(pxa27x_set_wake);
+}
+
/*
* device registration specific to PXA27x.
*/
@@ -286,7 +388,7 @@ static struct resource pxa27x_ohci_resources[] = {
},
};
-static struct platform_device pxa27x_device_ohci = {
+struct platform_device pxa27x_device_ohci = {
.name = "pxa27x-ohci",
.id = -1,
.dev = {
@@ -314,7 +416,7 @@ static struct resource i2c_power_resources[] = {
},
};
-static struct platform_device pxa27x_device_i2c_power = {
+struct platform_device pxa27x_device_i2c_power = {
.name = "pxa2xx-i2c",
.id = 1,
.resource = i2c_power_resources,
@@ -336,17 +438,12 @@ static struct platform_device *devices[] __initdata = {
&pxa27x_device_ohci,
};
-void __init pxa27x_init_irq(void)
-{
- pxa_init_irq_low();
- pxa_init_irq_high();
- pxa_init_irq_gpio(128);
-}
-
static int __init pxa27x_init(void)
{
int ret = 0;
if (cpu_is_pxa27x()) {
+ clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks));
+
if ((ret = pxa_init_dma(32)))
return ret;
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
new file mode 100644
index 00000000000..5363b132265
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -0,0 +1,93 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa300.c
+ *
+ * Code specific to PXA300/PXA310
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/mfp-pxa300.h>
+
+static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR_X(GPIO0, GPIO2, 0x00b4),
+ MFP_ADDR_X(GPIO3, GPIO26, 0x027c),
+ MFP_ADDR_X(GPIO27, GPIO127, 0x0400),
+ MFP_ADDR_X(GPIO0_2, GPIO6_2, 0x02ec),
+
+ MFP_ADDR(nBE0, 0x0204),
+ MFP_ADDR(nBE1, 0x0208),
+
+ MFP_ADDR(nLUA, 0x0244),
+ MFP_ADDR(nLLA, 0x0254),
+
+ MFP_ADDR(DF_CLE_nOE, 0x0240),
+ MFP_ADDR(DF_nRE_nOE, 0x0200),
+ MFP_ADDR(DF_ALE_nWE, 0x020C),
+ MFP_ADDR(DF_INT_RnB, 0x00C8),
+ MFP_ADDR(DF_nCS0, 0x0248),
+ MFP_ADDR(DF_nCS1, 0x0278),
+ MFP_ADDR(DF_nWE, 0x00CC),
+
+ MFP_ADDR(DF_ADDR0, 0x0210),
+ MFP_ADDR(DF_ADDR1, 0x0214),
+ MFP_ADDR(DF_ADDR2, 0x0218),
+ MFP_ADDR(DF_ADDR3, 0x021C),
+
+ MFP_ADDR(DF_IO0, 0x0220),
+ MFP_ADDR(DF_IO1, 0x0228),
+ MFP_ADDR(DF_IO2, 0x0230),
+ MFP_ADDR(DF_IO3, 0x0238),
+ MFP_ADDR(DF_IO4, 0x0258),
+ MFP_ADDR(DF_IO5, 0x0260),
+ MFP_ADDR(DF_IO6, 0x0268),
+ MFP_ADDR(DF_IO7, 0x0270),
+ MFP_ADDR(DF_IO8, 0x0224),
+ MFP_ADDR(DF_IO9, 0x022C),
+ MFP_ADDR(DF_IO10, 0x0234),
+ MFP_ADDR(DF_IO11, 0x023C),
+ MFP_ADDR(DF_IO12, 0x025C),
+ MFP_ADDR(DF_IO13, 0x0264),
+ MFP_ADDR(DF_IO14, 0x026C),
+ MFP_ADDR(DF_IO15, 0x0274),
+
+ MFP_ADDR_END,
+};
+
+/* override pxa300 MFP register addresses */
+static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
+ MFP_ADDR_X(GPIO30, GPIO98, 0x0418),
+ MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C),
+
+ MFP_ADDR(ULPI_STP, 0x040C),
+ MFP_ADDR(ULPI_NXT, 0x0410),
+ MFP_ADDR(ULPI_DIR, 0x0414),
+
+ MFP_ADDR_END,
+};
+
+static int __init pxa300_init(void)
+{
+ if (cpu_is_pxa300() || cpu_is_pxa310()) {
+ pxa3xx_init_mfp();
+ pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
+ }
+
+ if (cpu_is_pxa310())
+ pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
+
+ return 0;
+}
+
+core_initcall(pxa300_init);
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
new file mode 100644
index 00000000000..cd9eba5b3df
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa320.c
+ *
+ * Code specific to PXA320
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/mfp.h>
+#include <asm/arch/mfp-pxa320.h>
+
+static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR_X(GPIO0, GPIO4, 0x0124),
+ MFP_ADDR_X(GPIO5, GPIO26, 0x028C),
+ MFP_ADDR_X(GPIO27, GPIO62, 0x0400),
+ MFP_ADDR_X(GPIO63, GPIO73, 0x04B4),
+ MFP_ADDR_X(GPIO74, GPIO98, 0x04F0),
+ MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
+ MFP_ADDR_X(GPIO0_2, GPIO5_2, 0x0674),
+ MFP_ADDR_X(GPIO6_2, GPIO13_2, 0x0494),
+ MFP_ADDR_X(GPIO14_2, GPIO17_2, 0x04E0),
+
+ MFP_ADDR(nXCVREN, 0x0138),
+ MFP_ADDR(DF_CLE_nOE, 0x0204),
+ MFP_ADDR(DF_nADV1_ALE, 0x0208),
+ MFP_ADDR(DF_SCLK_S, 0x020C),
+ MFP_ADDR(DF_SCLK_E, 0x0210),
+ MFP_ADDR(nBE0, 0x0214),
+ MFP_ADDR(nBE1, 0x0218),
+ MFP_ADDR(DF_nADV2_ALE, 0x021C),
+ MFP_ADDR(DF_INT_RnB, 0x0220),
+ MFP_ADDR(DF_nCS0, 0x0224),
+ MFP_ADDR(DF_nCS1, 0x0228),
+ MFP_ADDR(DF_nWE, 0x022C),
+ MFP_ADDR(DF_nRE_nOE, 0x0230),
+ MFP_ADDR(nLUA, 0x0234),
+ MFP_ADDR(nLLA, 0x0238),
+ MFP_ADDR(DF_ADDR0, 0x023C),
+ MFP_ADDR(DF_ADDR1, 0x0240),
+ MFP_ADDR(DF_ADDR2, 0x0244),
+ MFP_ADDR(DF_ADDR3, 0x0248),
+ MFP_ADDR(DF_IO0, 0x024C),
+ MFP_ADDR(DF_IO8, 0x0250),
+ MFP_ADDR(DF_IO1, 0x0254),
+ MFP_ADDR(DF_IO9, 0x0258),
+ MFP_ADDR(DF_IO2, 0x025C),
+ MFP_ADDR(DF_IO10, 0x0260),
+ MFP_ADDR(DF_IO3, 0x0264),
+ MFP_ADDR(DF_IO11, 0x0268),
+ MFP_ADDR(DF_IO4, 0x026C),
+ MFP_ADDR(DF_IO12, 0x0270),
+ MFP_ADDR(DF_IO5, 0x0274),
+ MFP_ADDR(DF_IO13, 0x0278),
+ MFP_ADDR(DF_IO6, 0x027C),
+ MFP_ADDR(DF_IO14, 0x0280),
+ MFP_ADDR(DF_IO7, 0x0284),
+ MFP_ADDR(DF_IO15, 0x0288),
+
+ MFP_ADDR_END,
+};
+
+static void __init pxa320_init_mfp(void)
+{
+ pxa3xx_init_mfp();
+ pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
+}
+
+static int __init pxa320_init(void)
+{
+ if (cpu_is_pxa320())
+ pxa320_init_mfp();
+
+ return 0;
+}
+
+core_initcall(pxa320_init);
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
new file mode 100644
index 00000000000..39f0de8c189
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -0,0 +1,216 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa3xx.c
+ *
+ * code specific to pxa3xx aka Monahans
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ *
+ * 2007-09-02: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/pxa3xx-regs.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/ssp.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK 13000000
+
+/* Ring Oscillator Clock: 60MHz */
+#define RO_CLK 60000000
+
+#define ACCR_D0CS (1 << 26)
+
+/* crystal frequency to static memory controller multiplier (SMCFS) */
+static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
+
+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
+static unsigned char hss_mult[4] = { 8, 12, 16, 0 };
+
+/*
+ * Get the clock frequency as reflected by CCSR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa3xx_get_clk_frequency_khz(int info)
+{
+ unsigned long acsr, xclkcfg;
+ unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
+
+ /* Read XCLKCFG register turbo bit */
+ __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
+ t = xclkcfg & 0x1;
+
+ acsr = ACSR;
+
+ xl = acsr & 0x1f;
+ xn = (acsr >> 8) & 0x7;
+ hss = (acsr >> 14) & 0x3;
+
+ XL = xl * BASE_CLK;
+ XN = xn * XL;
+
+ ro = acsr & ACCR_D0CS;
+
+ CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
+ HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+ if (info) {
+ pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
+ RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
+ (ro) ? "" : "in");
+ pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
+ XL / 1000000, (XL % 1000000) / 10000, xl);
+ pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
+ XN / 1000000, (XN % 1000000) / 10000, xn,
+ (t) ? "" : "in");
+ pr_info("HSIO bus clock: %d.%02dMHz\n",
+ HSS / 1000000, (HSS % 1000000) / 10000);
+ }
+
+ return CLK;
+}
+
+/*
+ * Return the current static memory controller clock frequency
+ * in units of 10kHz
+ */
+unsigned int pxa3xx_get_memclk_frequency_10khz(void)
+{
+ unsigned long acsr;
+ unsigned int smcfs, clk = 0;
+
+ acsr = ACSR;
+
+ smcfs = (acsr >> 23) & 0x7;
+ clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK;
+
+ return (clk / 10000);
+}
+
+/*
+ * Return the current HSIO bus clock frequency
+ */
+static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
+{
+ unsigned long acsr;
+ unsigned int hss, hsio_clk;
+
+ acsr = ACSR;
+
+ hss = (acsr >> 14) & 0x3;
+ hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+ return hsio_clk;
+}
+
+static void clk_pxa3xx_cken_enable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ local_irq_disable();
+
+ if (clk->cken < 32)
+ CKENA |= mask;
+ else
+ CKENB |= mask;
+
+ local_irq_enable();
+}
+
+static void clk_pxa3xx_cken_disable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ local_irq_disable();
+
+ if (clk->cken < 32)
+ CKENA &= ~mask;
+ else
+ CKENB &= ~mask;
+
+ local_irq_enable();
+}
+
+static const struct clkops clk_pxa3xx_hsio_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_hsio_getrate,
+};
+
+static struct clk pxa3xx_clks[] = {
+ INIT_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
+ INIT_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
+
+ INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
+ INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
+ INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
+
+ INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
+ INIT_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
+};
+
+void __init pxa3xx_init_irq(void)
+{
+ /* enable CP6 access */
+ u32 value;
+ __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
+ value |= (1 << 6);
+ __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
+
+ pxa_init_irq_low();
+ pxa_init_irq_high();
+ pxa_init_irq_gpio(128);
+}
+
+/*
+ * device registration specific to PXA3xx.
+ */
+
+static struct platform_device *devices[] __initdata = {
+ &pxa_device_mci,
+ &pxa_device_udc,
+ &pxa_device_fb,
+ &pxa_device_ffuart,
+ &pxa_device_btuart,
+ &pxa_device_stuart,
+ &pxa_device_i2c,
+ &pxa_device_i2s,
+ &pxa_device_ficp,
+ &pxa_device_rtc,
+};
+
+static int __init pxa3xx_init(void)
+{
+ int ret = 0;
+
+ if (cpu_is_pxa3xx()) {
+ clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks));
+
+ if ((ret = pxa_init_dma(32)))
+ return ret;
+
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+ return 0;
+}
+
+subsys_initcall(pxa3xx_init);
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 98d27e646b0..ec4286c7931 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -16,10 +16,48 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/clockchips.h>
+#include <linux/sched.h>
+#include <asm/div64.h>
+#include <asm/cnt32_to_63.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/arch/pxa-regs.h>
+#include <asm/mach-types.h>
+
+/*
+ * This is PXA's sched_clock implementation. This has a resolution
+ * of at least 308 ns and a maximum value of 208 days.
+ *
+ * The return value is guaranteed to be monotonic in that range as
+ * long as there is always less than 582 seconds between successive
+ * calls to sched_clock() which should always be the case in practice.
+ */
+
+#define OSCR2NS_SCALE_FACTOR 10
+
+static unsigned long oscr2ns_scale;
+
+static void __init set_oscr2ns_scale(unsigned long oscr_rate)
+{
+ unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR;
+ do_div(v, oscr_rate);
+ oscr2ns_scale = v;
+ /*
+ * We want an even value to automatically clear the top bit
+ * returned by cnt32_to_63() without an additional run time
+ * instruction. So if the LSB is 1 then round it up.
+ */
+ if (oscr2ns_scale & 1)
+ oscr2ns_scale++;
+}
+
+unsigned long long sched_clock(void)
+{
+ unsigned long long v = cnt32_to_63(OSCR);
+ return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR;
+}
+
static irqreturn_t
pxa_ost0_interrupt(int irq, void *dev_id)
@@ -149,18 +187,29 @@ static struct irqaction pxa_ost0_irq = {
static void __init pxa_timer_init(void)
{
+ unsigned long clock_tick_rate;
+
OIER = 0;
OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
+ if (cpu_is_pxa21x() || cpu_is_pxa25x())
+ clock_tick_rate = 3686400;
+ else if (machine_is_mainstone())
+ clock_tick_rate = 3249600;
+ else
+ clock_tick_rate = 3250000;
+
+ set_oscr2ns_scale(clock_tick_rate);
+
ckevt_pxa_osmr0.mult =
- div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
+ div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
ckevt_pxa_osmr0.max_delta_ns =
clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
ckevt_pxa_osmr0.min_delta_ns =
clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1;
cksrc_pxa_oscr0.mult =
- clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift);
+ clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
setup_irq(IRQ_OST0, &pxa_ost0_irq);
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
new file mode 100644
index 00000000000..3f18d760dd1
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -0,0 +1,184 @@
+/*
+ * linux/arch/arm/mach-pxa/zylonite.c
+ *
+ * Support for the PXA3xx Development Platform (aka Zylonite)
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ * rewrite to align with latest kernel
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/zylonite.h>
+
+#include "generic.h"
+
+int gpio_backlight;
+int gpio_eth_irq;
+
+int lcd_id;
+int lcd_orientation;
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = ZYLONITE_ETH_PHYS + 0x300,
+ .end = ZYLONITE_ETH_PHYS + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = -1, /* for run-time assignment */
+ .end = -1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES)
+static void zylonite_backlight_power(int on)
+{
+ gpio_set_value(gpio_backlight, on);
+}
+
+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
+ .pixclock = 110000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 6,
+ .right_margin = 4,
+ .vsync_len = 2,
+ .upper_margin = 2,
+ .lower_margin = 3,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
+ .pixclock = 50000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 1,
+ .left_margin = 0x9f,
+ .right_margin = 1,
+ .vsync_len = 44,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
+ .num_modes = 1,
+ .lccr0 = LCCR0_Act,
+ .lccr3 = LCCR3_PCP,
+ .pxafb_backlight_power = zylonite_backlight_power,
+};
+
+static struct pxafb_mode_info sharp_ls037_modes[] = {
+ [0] = {
+ .pixclock = 158000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 39,
+ .right_margin = 39,
+ .vsync_len = 1,
+ .upper_margin = 2,
+ .lower_margin = 3,
+ .sync = 0,
+ },
+ [1] = {
+ .pixclock = 39700,
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .hsync_len = 8,
+ .left_margin = 81,
+ .right_margin = 81,
+ .vsync_len = 1,
+ .upper_margin = 2,
+ .lower_margin = 7,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info zylonite_sharp_lcd_info = {
+ .modes = sharp_ls037_modes,
+ .num_modes = 2,
+ .lccr0 = LCCR0_Act,
+ .lccr3 = LCCR3_PCP | LCCR3_HSP | LCCR3_VSP,
+ .pxafb_backlight_power = zylonite_backlight_power,
+};
+
+static void __init zylonite_init_lcd(void)
+{
+ /* backlight GPIO: output, default on */
+ gpio_direction_output(gpio_backlight, 1);
+
+ if (lcd_id & 0x20) {
+ set_pxa_fb_info(&zylonite_sharp_lcd_info);
+ return;
+ }
+
+ /* legacy LCD panels, it would be handy here if LCD panel type can
+ * be decided at run-time
+ */
+ if (1)
+ zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
+ else
+ zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
+
+ set_pxa_fb_info(&zylonite_toshiba_lcd_info);
+}
+#else
+static inline void zylonite_init_lcd(void) {}
+#endif
+
+static void __init zylonite_init(void)
+{
+ /* board-processor specific initialization */
+ zylonite_pxa300_init();
+ zylonite_pxa320_init();
+
+ /*
+ * Note: We depend that the bootloader set
+ * the correct value to MSC register for SMC91x.
+ */
+ smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
+ smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
+ platform_device_register(&smc91x_device);
+
+ zylonite_init_lcd();
+}
+
+MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
+ .phys_io = 0x40000000,
+ .boot_params = 0xa0000100,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = zylonite_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
new file mode 100644
index 00000000000..b5fbd2f4c69
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-pxa/zylonite_pxa300.c
+ *
+ * PXA300/PXA310 specific support code for the
+ * PXA3xx Development Platform (aka Zylonite)
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/gpio.h>
+#include <asm/arch/mfp-pxa300.h>
+#include <asm/arch/zylonite.h>
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+/* PXA300/PXA310 common configurations */
+static mfp_cfg_t common_mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+ GPIO76_LCD_VSYNC,
+ GPIO127_LCD_CS_N,
+
+ /* BTUART */
+ GPIO111_UART2_RTS,
+ GPIO112_UART2_RXD,
+ GPIO113_UART2_TXD,
+ GPIO114_UART2_CTS,
+
+ /* STUART */
+ GPIO109_UART3_TXD,
+ GPIO110_UART3_RXD,
+
+ /* AC97 */
+ GPIO23_AC97_nACRESET,
+ GPIO24_AC97_SYSCLK,
+ GPIO29_AC97_BITCLK,
+ GPIO25_AC97_SDATA_IN_0,
+ GPIO27_AC97_SDATA_OUT,
+ GPIO28_AC97_SYNC,
+
+ /* Keypad */
+ GPIO107_KP_DKIN_0,
+ GPIO108_KP_DKIN_1,
+ GPIO115_KP_MKIN_0,
+ GPIO116_KP_MKIN_1,
+ GPIO117_KP_MKIN_2,
+ GPIO118_KP_MKIN_3,
+ GPIO119_KP_MKIN_4,
+ GPIO120_KP_MKIN_5,
+ GPIO2_2_KP_MKIN_6,
+ GPIO3_2_KP_MKIN_7,
+ GPIO121_KP_MKOUT_0,
+ GPIO122_KP_MKOUT_1,
+ GPIO123_KP_MKOUT_2,
+ GPIO124_KP_MKOUT_3,
+ GPIO125_KP_MKOUT_4,
+ GPIO4_2_KP_MKOUT_5,
+ GPIO5_2_KP_MKOUT_6,
+ GPIO6_2_KP_MKOUT_7,
+};
+
+static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
+ /* FFUART */
+ GPIO30_UART1_RXD,
+ GPIO31_UART1_TXD,
+ GPIO32_UART1_CTS,
+ GPIO37_UART1_RTS,
+ GPIO33_UART1_DCD,
+ GPIO34_UART1_DSR,
+ GPIO35_UART1_RI,
+ GPIO36_UART1_DTR,
+
+ /* Ethernet */
+ GPIO2_nCS3,
+ GPIO99_GPIO,
+};
+
+static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
+ /* FFUART */
+ GPIO99_UART1_RXD,
+ GPIO100_UART1_TXD,
+ GPIO101_UART1_CTS,
+ GPIO106_UART1_RTS,
+
+ /* Ethernet */
+ GPIO2_nCS3,
+ GPIO102_GPIO,
+};
+
+#define NUM_LCD_DETECT_PINS 7
+
+static int lcd_detect_pins[] __initdata = {
+ MFP_PIN_GPIO71, /* LCD_LDD_17 - ORIENT */
+ MFP_PIN_GPIO70, /* LCD_LDD_16 - LCDID[5] */
+ MFP_PIN_GPIO75, /* LCD_BIAS - LCDID[4] */
+ MFP_PIN_GPIO73, /* LCD_LCLK - LCDID[3] */
+ MFP_PIN_GPIO72, /* LCD_FCLK - LCDID[2] */
+ MFP_PIN_GPIO127,/* LCD_CS_N - LCDID[1] */
+ MFP_PIN_GPIO76, /* LCD_VSYNC - LCDID[0] */
+};
+
+static void __init zylonite_detect_lcd_panel(void)
+{
+ unsigned long mfpr_save[NUM_LCD_DETECT_PINS];
+ int i, gpio, id = 0;
+
+ /* save the original MFP settings of these pins and configure
+ * them as GPIO Input, DS01X, Pull Neither, Edge Clear
+ */
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
+ mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
+ pxa3xx_mfp_write(lcd_detect_pins[i], 0x8440);
+ }
+
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
+ id = id << 1;
+ gpio = mfp_to_gpio(lcd_detect_pins[i]);
+ gpio_direction_input(gpio);
+
+ if (gpio_get_value(gpio))
+ id = id | 0x1;
+ }
+
+ /* lcd id, flush out bit 1 */
+ lcd_id = id & 0x3d;
+
+ /* lcd orientation, portrait or landscape */
+ lcd_orientation = (id >> 6) & 0x1;
+
+ /* restore the original MFP settings */
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++)
+ pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
+}
+
+void __init zylonite_pxa300_init(void)
+{
+ if (cpu_is_pxa300() || cpu_is_pxa310()) {
+ /* initialize MFP */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(common_mfp_cfg));
+
+ /* detect LCD panel */
+ zylonite_detect_lcd_panel();
+
+ /* GPIO pin assignment */
+ gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
+ }
+
+ if (cpu_is_pxa300()) {
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_mfp_cfg));
+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO99);
+ }
+
+ if (cpu_is_pxa310()) {
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
+ }
+}
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
new file mode 100644
index 00000000000..63cb36be086
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -0,0 +1,173 @@
+/*
+ * linux/arch/arm/mach-pxa/zylonite_pxa320.c
+ *
+ * PXA320 specific support code for the
+ * PXA3xx Development Platform (aka Zylonite)
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mfp-pxa320.h>
+#include <asm/arch/zylonite.h>
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+static mfp_cfg_t mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO6_2_LCD_LDD_0,
+ GPIO7_2_LCD_LDD_1,
+ GPIO8_2_LCD_LDD_2,
+ GPIO9_2_LCD_LDD_3,
+ GPIO10_2_LCD_LDD_4,
+ GPIO11_2_LCD_LDD_5,
+ GPIO12_2_LCD_LDD_6,
+ GPIO13_2_LCD_LDD_7,
+ GPIO63_LCD_LDD_8,
+ GPIO64_LCD_LDD_9,
+ GPIO65_LCD_LDD_10,
+ GPIO66_LCD_LDD_11,
+ GPIO67_LCD_LDD_12,
+ GPIO68_LCD_LDD_13,
+ GPIO69_LCD_LDD_14,
+ GPIO70_LCD_LDD_15,
+ GPIO71_LCD_LDD_16,
+ GPIO72_LCD_LDD_17,
+ GPIO73_LCD_CS_N,
+ GPIO74_LCD_VSYNC,
+ GPIO14_2_LCD_FCLK,
+ GPIO15_2_LCD_LCLK,
+ GPIO16_2_LCD_PCLK,
+ GPIO17_2_LCD_BIAS,
+
+ /* FFUART */
+ GPIO41_UART1_RXD,
+ GPIO42_UART1_TXD,
+ GPIO43_UART1_CTS,
+ GPIO44_UART1_DCD,
+ GPIO45_UART1_DSR,
+ GPIO46_UART1_RI,
+ GPIO47_UART1_DTR,
+ GPIO48_UART1_RTS,
+
+ /* AC97 */
+ GPIO34_AC97_SYSCLK,
+ GPIO35_AC97_SDATA_IN_0,
+ GPIO37_AC97_SDATA_OUT,
+ GPIO38_AC97_SYNC,
+ GPIO39_AC97_BITCLK,
+ GPIO40_AC97_nACRESET,
+
+ /* I2C */
+ GPIO32_I2C_SCL,
+ GPIO33_I2C_SDA,
+
+ /* Keypad */
+ GPIO105_KP_DKIN_0,
+ GPIO106_KP_DKIN_1,
+ GPIO113_KP_MKIN_0,
+ GPIO114_KP_MKIN_1,
+ GPIO115_KP_MKIN_2,
+ GPIO116_KP_MKIN_3,
+ GPIO117_KP_MKIN_4,
+ GPIO118_KP_MKIN_5,
+ GPIO119_KP_MKIN_6,
+ GPIO120_KP_MKIN_7,
+ GPIO121_KP_MKOUT_0,
+ GPIO122_KP_MKOUT_1,
+ GPIO123_KP_MKOUT_2,
+ GPIO124_KP_MKOUT_3,
+ GPIO125_KP_MKOUT_4,
+ GPIO126_KP_MKOUT_5,
+ GPIO127_KP_MKOUT_6,
+ GPIO5_2_KP_MKOUT_7,
+
+ /* Ethernet */
+ GPIO4_nCS3,
+ GPIO90_GPIO,
+};
+
+#define NUM_LCD_DETECT_PINS 7
+
+static int lcd_detect_pins[] __initdata = {
+ MFP_PIN_GPIO72, /* LCD_LDD_17 - ORIENT */
+ MFP_PIN_GPIO71, /* LCD_LDD_16 - LCDID[5] */
+ MFP_PIN_GPIO17_2, /* LCD_BIAS - LCDID[4] */
+ MFP_PIN_GPIO15_2, /* LCD_LCLK - LCDID[3] */
+ MFP_PIN_GPIO14_2, /* LCD_FCLK - LCDID[2] */
+ MFP_PIN_GPIO73, /* LCD_CS_N - LCDID[1] */
+ MFP_PIN_GPIO74, /* LCD_VSYNC - LCDID[0] */
+ /*
+ * set the MFP_PIN_GPIO 14/15/17 to alternate function other than
+ * GPIO to avoid input level confliction with 14_2, 15_2, 17_2
+ */
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO17,
+};
+
+static int lcd_detect_mfpr[] __initdata = {
+ /* AF0, DS 1X, Pull Neither, Edge Clear */
+ 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440,
+ 0xc442, /* Backlight, Pull-Up, AF2 */
+ 0x8445, /* AF5 */
+ 0x8445, /* AF5 */
+};
+
+static void __init zylonite_detect_lcd_panel(void)
+{
+ unsigned long mfpr_save[ARRAY_SIZE(lcd_detect_pins)];
+ int i, gpio, id = 0;
+
+ /* save the original MFP settings of these pins and configure them
+ * as GPIO Input, DS01X, Pull Neither, Edge Clear
+ */
+ for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) {
+ mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
+ pxa3xx_mfp_write(lcd_detect_pins[i], lcd_detect_mfpr[i]);
+ }
+
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
+ id = id << 1;
+ gpio = mfp_to_gpio(lcd_detect_pins[i]);
+ gpio_direction_input(gpio);
+
+ if (gpio_get_value(gpio))
+ id = id | 0x1;
+ }
+
+ /* lcd id, flush out bit 1 */
+ lcd_id = id & 0x3d;
+
+ /* lcd orientation, portrait or landscape */
+ lcd_orientation = (id >> 6) & 0x1;
+
+ /* restore the original MFP settings */
+ for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++)
+ pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
+}
+
+void __init zylonite_pxa320_init(void)
+{
+ if (cpu_is_pxa320()) {
+ /* initialize MFP */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
+
+ /* detect LCD panel */
+ zylonite_detect_lcd_panel();
+
+ /* GPIO pin assignment */
+ gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14);
+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
+ }
+}
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 80d83739ab9..8f12e855ef5 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -145,7 +145,7 @@ static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
},
};
-static int s3c2410_dma_add(struct sys_device *sysdev)
+static int __init s3c2410_dma_add(struct sys_device *sysdev)
{
s3c2410_dma_init();
s3c24xx_dma_order_set(&s3c2410_dma_order);
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 43bb5e10630..a67a0685664 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -168,13 +168,31 @@ static void __init amlm5900_map_io(void)
}
#ifdef CONFIG_FB_S3C2410
-static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
+static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
.width = 160,
.height = 160,
-/* commented out until stn patch is submitted
-* .type = S3C2410_LCDCON1_STN4,
-*/
+ .type = S3C2410_LCDCON1_STN4,
+
+ .pixclock = 680000, /* HCLK = 100MHz */
+ .xres = 160,
+ .yres = 160,
+ .bpp = 4,
+ .left_margin = 1 << (4 + 3),
+ .right_margin = 8 << 3,
+ .hsync_len = 48,
+ .upper_margin = 0,
+ .lower_margin = 0,
+
+ .lcdcon5 = 0x00000001,
+};
+
+static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
+
+ .displays = &amlm5900_lcd_info,
+ .num_displays = 1,
+ .default_display = 0,
+
.gpccon = 0xaaaaaaaa,
.gpccon_mask = 0xffffffff,
.gpcup = 0x0000ffff,
@@ -184,32 +202,6 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
.gpdcon_mask = 0xffffffff,
.gpdup = 0x0000ffff,
.gpdup_mask = 0xffffffff,
-
- .xres = {
- .min = 160,
- .max = 160,
- .defval = 160,
- },
-
- .yres = {
- .min = 160,
- .max = 160,
- .defval = 160,
- },
-
- .bpp = {
- .min = 4,
- .max = 4,
- .defval = 4,
- },
-
- .regs = {
- .lcdcon1 = 0x00008225,
- .lcdcon2 = 0x0027c000,
- .lcdcon3 = 0x00182708,
- .lcdcon4 = 0x00000002,
- .lcdcon5 = 0x00000001,
- }
};
#endif
@@ -239,7 +231,7 @@ static void __init amlm5900_init(void)
{
amlm5900_init_pm();
#ifdef CONFIG_FB_S3C2410
- s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
+ s3c24xx_fb_set_platdata(&amlm5900_fb_info);
#endif
platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
}
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index bc926992b4e..587864fe25f 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -467,35 +467,70 @@ static struct platform_device bast_device_axpp = {
/* LCD/VGA controller */
-static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
- .width = 640,
- .height = 480,
-
- .xres = {
- .min = 320,
- .max = 1024,
- .defval = 640,
- },
+static struct s3c2410fb_display __initdata bast_lcd_info[] = {
+ {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 33333,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 4,
+ .left_margin = 40,
+ .right_margin = 20,
+ .hsync_len = 88,
+ .upper_margin = 30,
+ .lower_margin = 32,
+ .vsync_len = 3,
- .yres = {
- .min = 240,
- .max = 600,
- .defval = 480,
+ .lcdcon5 = 0x00014b02,
},
+ {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 33333,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 8,
+ .left_margin = 40,
+ .right_margin = 20,
+ .hsync_len = 88,
+ .upper_margin = 30,
+ .lower_margin = 32,
+ .vsync_len = 3,
- .bpp = {
- .min = 4,
- .max = 16,
- .defval = 8,
+ .lcdcon5 = 0x00014b02,
},
+ {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 33333,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .left_margin = 40,
+ .right_margin = 20,
+ .hsync_len = 88,
+ .upper_margin = 30,
+ .lower_margin = 32,
+ .vsync_len = 3,
- .regs = {
- .lcdcon1 = 0x00000176,
- .lcdcon2 = 0x1d77c7c2,
- .lcdcon3 = 0x013a7f13,
- .lcdcon4 = 0x00000057,
.lcdcon5 = 0x00014b02,
- }
+ },
+};
+
+/* LCD/VGA controller */
+
+static struct s3c2410fb_mach_info __initdata bast_fb_info = {
+
+ .displays = bast_lcd_info,
+ .num_displays = ARRAY_SIZE(bast_lcd_info),
+ .default_display = 4,
};
/* Standard BAST devices */
@@ -552,7 +587,7 @@ static void __init bast_map_io(void)
static void __init bast_init(void)
{
- s3c24xx_fb_set_platdata(&bast_lcd_info);
+ s3c24xx_fb_set_platdata(&bast_fb_info);
platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
}
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 9a172b4ad72..7c1145e87c1 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -133,29 +133,31 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
/**
* Set lcd on or off
**/
-static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
- .fixed_syncs= 1,
- .regs={
- .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \
- S3C2410_LCDCON1_TFT | \
- S3C2410_LCDCON1_CLKVAL(0x0C),
-
- .lcdcon2= S3C2410_LCDCON2_VBPD(7) | \
- S3C2410_LCDCON2_LINEVAL(319) | \
- S3C2410_LCDCON2_VFPD(6) | \
- S3C2410_LCDCON2_VSPW(0),
-
- .lcdcon3= S3C2410_LCDCON3_HBPD(19) | \
- S3C2410_LCDCON3_HOZVAL(239) | \
- S3C2410_LCDCON3_HFPD(7),
-
- .lcdcon4= S3C2410_LCDCON4_MVAL(0) | \
- S3C2410_LCDCON4_HSPW(3),
-
- .lcdcon5= S3C2410_LCDCON5_FRM565 | \
- S3C2410_LCDCON5_INVVLINE | \
- S3C2410_LCDCON5_HWSWP,
- },
+static struct s3c2410fb_display h1940_lcd __initdata = {
+ .lcdcon5= S3C2410_LCDCON5_FRM565 | \
+ S3C2410_LCDCON5_INVVLINE | \
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .pixclock = 260000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 20,
+ .right_margin = 8,
+ .hsync_len = 4,
+ .upper_margin = 8,
+ .lower_margin = 7,
+ .vsync_len = 1,
+};
+
+static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
+ .displays = &h1940_lcd,
+ .num_displays = 1,
+ .default_display = 0,
+
.lpcsel= 0x02,
.gpccon= 0xaa940659,
.gpccon_mask= 0xffffffff,
@@ -165,12 +167,6 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
.gpdcon_mask= 0xffffffff,
.gpdup= 0x0000faff,
.gpdup_mask= 0xffffffff,
-
- .width= 240,
- .height= 320,
- .xres= {240,240,240},
- .yres= {320,320,320},
- .bpp= {16,16,16},
};
static struct platform_device s3c_device_leds = {
@@ -217,7 +213,7 @@ static void __init h1940_init(void)
{
u32 tmp;
- s3c24xx_fb_set_platdata(&h1940_lcdcfg);
+ s3c24xx_fb_set_platdata(&h1940_fb_info);
s3c24xx_udc_set_platdata(&h1940_udc_cfg);
/* Turn off suspend on both USB ports, and switch the
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index e670b1e1631..a1caf4b0ada 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -95,157 +95,83 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
/* LCD driver info */
-/* Configuration for 640x480 SHARP LQ080V3DG01 */
-static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */
- S3C2410_LCDCON2_LINEVAL(479) |
- S3C2410_LCDCON2_VFPD(10) | /* 11 */
- S3C2410_LCDCON2_VSPW(14), /* 15 */
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */
- S3C2410_LCDCON3_HOZVAL(639) | /* 640 */
- S3C2410_LCDCON3_HFPD(115), /* 116 */
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(95), /* 96 */
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
+static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
+ {
+ /* Configuration for 640x480 SHARP LQ080V3DG01 */
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 40000, /* HCLK/4 */
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .left_margin = 44,
+ .right_margin = 116,
+ .hsync_len = 96,
+ .upper_margin = 19,
+ .lower_margin = 11,
+ .vsync_len = 15,
},
-
- .lpcsel = ((0xCE6) & ~7) | 1<<4,
-
- .width = 640,
- .height = 480,
-
- .xres = {
- .min = 640,
- .max = 640,
- .defval = 640,
- },
-
- .yres = {
- .min = 480,
- .max = 480,
- .defval = 480,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
-};
-
-/* Configuration for 480x640 toppoly TD028TTEC1 */
-static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */
- S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
- S3C2410_LCDCON2_VFPD(3) | /* 4 */
- S3C2410_LCDCON2_VSPW(1), /* 2 */
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */
- S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
- S3C2410_LCDCON3_HFPD(23), /* 24 */
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(7), /* 8 */
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- },
-
- .lpcsel = ((0xCE6) & ~7) | 1<<4,
-
- .width = 480,
- .height = 640,
-
- .xres = {
- .min = 480,
- .max = 480,
- .defval = 480,
+ {
+ /* Configuration for 480x640 toppoly TD028TTEC1 */
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 480,
+ .height = 640,
+ .pixclock = 40000, /* HCLK/4 */
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .left_margin = 8,
+ .right_margin = 24,
+ .hsync_len = 8,
+ .upper_margin = 2,
+ .lower_margin = 4,
+ .vsync_len = 2,
},
-
- .yres = {
- .min = 640,
- .max = 640,
- .defval = 640,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
+ {
+ /* Config for 240x320 LCD */
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .pixclock = 100000, /* HCLK/10 */
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 13,
+ .right_margin = 8,
+ .hsync_len = 4,
+ .upper_margin = 2,
+ .lower_margin = 7,
+ .vsync_len = 4,
},
};
-/* Config for 240x320 LCD */
-static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x04),
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
- S3C2410_LCDCON2_LINEVAL(319) |
- S3C2410_LCDCON2_VFPD(6) |
- S3C2410_LCDCON2_VSPW(3),
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(12) |
- S3C2410_LCDCON3_HOZVAL(239) |
- S3C2410_LCDCON3_HFPD(7),
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(3),
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- },
+static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
+ .displays = qt2410_lcd_cfg,
+ .num_displays = ARRAY_SIZE(qt2410_lcd_cfg),
+ .default_display = 0,
.lpcsel = ((0xCE6) & ~7) | 1<<4,
-
- .width = 240,
- .height = 320,
-
- .xres = {
- .min = 240,
- .max = 240,
- .defval = 240,
- },
-
- .yres = {
- .min = 320,
- .max = 320,
- .defval = 320,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
};
/* CS8900 */
@@ -408,16 +334,17 @@ static void __init qt2410_machine_init(void)
switch (tft_type) {
case 'p': /* production */
- s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg);
+ qt2410_fb_info.default_display = 1;
break;
case 'b': /* big */
- s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg);
+ qt2410_fb_info.default_display = 0;
break;
case 's': /* small */
default:
- s3c24xx_fb_set_platdata(&qt2410_lcd_cfg);
+ qt2410_fb_info.default_display = 2;
break;
}
+ s3c24xx_fb_set_platdata(&qt2410_fb_info);
s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB0, 1);
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 4b9425c1bf7..53c1d5bbce1 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -144,7 +144,7 @@ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
.map_size = ARRAY_SIZE(s3c2412_dma_mappings),
};
-static int s3c2412_dma_add(struct sys_device *sysdev)
+static int __init s3c2412_dma_add(struct sys_device *sysdev)
{
s3c2410_dma_init();
return s3c24xx_dma_init_map(&s3c2412_dma_sel);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index f0d66828f96..e9d0c769f5d 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -38,6 +38,9 @@
#include <asm/plat-s3c24xx/irq.h>
#include <asm/plat-s3c24xx/pm.h>
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
+
/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
* having them turn up in both the INT* and the EINT* registers. Whilst
* both show the status, they both now need to be acked when the IRQs
@@ -105,6 +108,51 @@ static struct irq_chip s3c2412_irq_eint0t4 = {
.set_type = s3c_irqext_type,
};
+#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
+
+/* CF and SDI sub interrupts */
+
+static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int subsrc, submsk;
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+
+ if (subsrc & INTBIT(IRQ_S3C2412_SDI))
+ desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI);
+
+ if (subsrc & INTBIT(IRQ_S3C2412_CF))
+ desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF);
+}
+
+#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
+#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
+
+static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
+{
+ s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+}
+
+static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
+{
+ s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
+}
+
+static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
+{
+ s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
+}
+
+static struct irq_chip s3c2412_irq_cfsdi = {
+ .name = "s3c2412-cfsdi",
+ .ack = s3c2412_irq_cfsdi_ack,
+ .mask = s3c2412_irq_cfsdi_mask,
+ .unmask = s3c2412_irq_cfsdi_unmask,
+};
+
static int s3c2412_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
@@ -115,6 +163,16 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
set_irq_flags(irqno, IRQF_VALID);
}
+ /* add demux support for CF/SDI */
+
+ set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
+
+ for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
+ set_irq_chip(irqno, &s3c2412_irq_cfsdi);
+ set_irq_handler(irqno, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
return 0;
}
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index e0ccb404623..4f92a1562d7 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -78,6 +78,11 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
s3c_device_lcd.name = "s3c2412-lcd";
s3c_device_nand.name = "s3c2412-nand";
+ /* alter IRQ of SDI controller */
+
+ s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
+ s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI;
+
/* spi channel related changes, s3c2412/13 specific */
s3c_device_spi0.name = "s3c2412-spi";
s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index f509f062e74..0b1260827ac 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -190,7 +190,7 @@ static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
},
};
-static int s3c2440_dma_add(struct sys_device *sysdev)
+static int __init s3c2440_dma_add(struct sys_device *sysdev)
{
s3c2410_dma_init();
s3c24xx_dma_order_set(&s3c2440_dma_order);
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index b59e6d39f2f..bac40c4878a 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -110,28 +110,32 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
/* framebuffer lcd controller information */
-static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
- .regs = {
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \
- S3C2410_LCDCON1_TFT | \
- S3C2410_LCDCON1_CLKVAL(0x0C),
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(5) | \
- S3C2410_LCDCON2_LINEVAL(319) | \
- S3C2410_LCDCON2_VFPD(6) | \
- S3C2410_LCDCON2_VSPW(2),
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(35) | \
- S3C2410_LCDCON3_HOZVAL(239) | \
- S3C2410_LCDCON3_HFPD(35),
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | \
- S3C2410_LCDCON4_HSPW(7),
-
- .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_HWSWP,
- },
+static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
+ .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+
+ .pixclock = 260000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 36,
+ .right_margin = 36,
+ .hsync_len = 8,
+ .upper_margin = 6,
+ .lower_margin = 7,
+ .vsync_len = 3,
+};
+
+static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
+
+ .displays = &rx3715_lcdcfg,
+ .num_displays = 1,
+ .default_display = 0,
.lpcsel = 0xf82,
@@ -144,28 +148,6 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
.gpdcon_mask = 0xffc0fff0,
.gpdup = 0x0000faff,
.gpdup_mask = 0xffffffff,
-
- .fixed_syncs = 1,
- .width = 240,
- .height = 320,
-
- .xres = {
- .min = 240,
- .max = 240,
- .defval = 240,
- },
-
- .yres = {
- .max = 320,
- .min = 320,
- .defval = 320,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
};
static struct mtd_partition rx3715_nand_part[] = {
@@ -224,7 +206,7 @@ static void __init rx3715_init_machine(void)
#endif
s3c2410_pm_init();
- s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
+ s3c24xx_fb_set_platdata(&rx3715_fb_info);
platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
}
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 670115b8a12..4552828bf80 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -103,31 +103,35 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
/* LCD driver info */
-static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
- .regs = {
-
- .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
- S3C2410_LCDCON1_TFT |
- S3C2410_LCDCON1_CLKVAL(0x04),
-
- .lcdcon2 = S3C2410_LCDCON2_VBPD(7) |
- S3C2410_LCDCON2_LINEVAL(319) |
- S3C2410_LCDCON2_VFPD(6) |
- S3C2410_LCDCON2_VSPW(3),
-
- .lcdcon3 = S3C2410_LCDCON3_HBPD(19) |
- S3C2410_LCDCON3_HOZVAL(239) |
- S3C2410_LCDCON3_HFPD(7),
-
- .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
- S3C2410_LCDCON4_HSPW(3),
-
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- },
+static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
+
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+
+ .width = 240,
+ .height = 320,
+
+ .pixclock = 166667, /* HCLK 60 MHz, divisor 10 */
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 20,
+ .right_margin = 8,
+ .hsync_len = 4,
+ .upper_margin = 8,
+ .lower_margin = 7,
+ .vsync_len = 4,
+};
+
+static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
+ .displays = &smdk2440_lcd_cfg,
+ .num_displays = 1,
+ .default_display = 0,
#if 0
/* currently setup by downloader */
@@ -142,28 +146,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
#endif
.lpcsel = ((0xCE6) & ~7) | 1<<4,
- .type = S3C2410_LCDCON1_TFT16BPP,
-
- .width = 240,
- .height = 320,
-
- .xres = {
- .min = 240,
- .max = 240,
- .defval = 240,
- },
-
- .yres = {
- .min = 320,
- .max = 320,
- .defval = 320,
- },
-
- .bpp = {
- .min = 16,
- .max = 16,
- .defval = 16,
- },
};
static struct platform_device *smdk2440_devices[] __initdata = {
@@ -183,7 +165,7 @@ static void __init smdk2440_map_io(void)
static void __init smdk2440_machine_init(void)
{
- s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
+ s3c24xx_fb_set_platdata(&smdk2440_fb_info);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index fc3ede82af8..f6c006d4297 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -162,7 +162,7 @@ static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
.map_size = ARRAY_SIZE(s3c2443_dma_mappings),
};
-static int s3c2443_dma_add(struct sys_device *sysdev)
+static int __init s3c2443_dma_add(struct sys_device *sysdev)
{
s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
return s3c24xx_dma_init_map(&s3c2443_dma_sel);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 6cd4818f3f0..f9ad498a6fc 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -252,7 +252,7 @@ static int __init s3c2443_add_sub(unsigned int base,
return 0;
}
-static int s3c2443_irq_add(struct sys_device *sysdev)
+static int __init s3c2443_irq_add(struct sys_device *sysdev)
{
printk("S3C2443: IRQ Support\n");
@@ -280,7 +280,7 @@ static struct sysdev_driver s3c2443_irq_driver = {
.add = s3c2443_irq_add,
};
-static int s3c2443_irq_init(void)
+static int __init s3c2443_irq_init(void)
{
return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
}
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 01a37d3c072..246c573e725 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -122,14 +122,14 @@ unsigned long sleep_phys_sp(void *sp)
return virt_to_phys(sp);
}
-static struct pm_ops sa11x0_pm_ops = {
+static struct platform_suspend_ops sa11x0_pm_ops = {
.enter = sa11x0_pm_enter,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
static int __init sa11x0_pm_init(void)
{
- pm_set_ops(&sa11x0_pm_ops);
+ suspend_set_ops(&sa11x0_pm_ops);
return 0;
}
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 12161ae445d..7868f4dc1d0 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -322,7 +322,7 @@ config CPU_SA1100
# XScale
config CPU_XSCALE
bool
- depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000
+ depends on ARCH_IOP32X || ARCH_IOP33X || PXA25x || PXA27x || ARCH_IXP4XX || ARCH_IXP2000
default y
select CPU_32v5
select CPU_ABRT_EV5T
@@ -333,7 +333,7 @@ config CPU_XSCALE
# XScale Core Version 3
config CPU_XSC3
bool
- depends on ARCH_IXP23XX || ARCH_IOP13XX
+ depends on ARCH_IXP23XX || ARCH_IOP13XX || PXA3xx
default y
select CPU_32v5
select CPU_ABRT_EV5T
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 1f9f94f9af4..cefdf2f9f26 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -481,7 +481,7 @@ core_initcall(consistent_init);
* platforms with CONFIG_DMABOUNCE.
* Use the driver DMA support - see dma-mapping.h (dma_sync_*)
*/
-void consistent_sync(const void *start, size_t size, int direction)
+void dma_cache_maint(const void *start, size_t size, int direction)
{
const void *end = start + size;
@@ -504,4 +504,4 @@ void consistent_sync(const void *start, size_t size, int direction)
BUG();
}
}
-EXPORT_SYMBOL(consistent_sync);
+EXPORT_SYMBOL(dma_cache_maint);
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 846cce48e2b..59ed1d05b71 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -266,7 +266,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
* the page fault gracefully.
*/
printk("VM: killing process %s\n", tsk->comm);
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
return 0;
}
if (fault & VM_FAULT_SIGBUS) {
diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h
index e6598470b07..436e54aa02e 100644
--- a/arch/arm/nwfpe/ARM-gcc.h
+++ b/arch/arm/nwfpe/ARM-gcc.h
@@ -68,7 +68,7 @@ a compiler does not support explicit inlining, this macro should be defined
to be `static'.
-------------------------------------------------------------------------------
*/
-#define INLINE extern __inline__
+#define INLINE static inline
/* For use as a GCC soft-float library we need some special function names. */
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
index 1dc13bc6d81..48bca0db460 100644
--- a/arch/arm/nwfpe/entry.S
+++ b/arch/arm/nwfpe/entry.S
@@ -70,13 +70,24 @@ floating point instructions. GCC attempts to group floating point
instructions to allow the emulator to spread the cost of the trap over
several floating point instructions. */
+#include <asm/asm-offsets.h>
+
.globl nwfpe_enter
nwfpe_enter:
mov r4, lr @ save the failure-return addresses
mov sl, sp @ we access the registers via 'sl'
- ldr r5, [sp, #60] @ get contents of PC;
+ ldr r5, [sp, #S_PC] @ get contents of PC;
+ mov r6, r0 @ save the opcode
emulate:
+ ldr r1, [sp, #S_PSR] @ fetch the PSR
+ bl checkCondition @ check the condition
+ cmp r0, #0 @ r0 = 0 ==> condition failed
+
+ @ if condition code failed to match, next insn
+ beq next @ get the next instruction;
+
+ mov r0, r6 @ prepare for EmulateAll()
bl EmulateAll @ emulate the instruction
cmp r0, #0 @ was emulation successful
moveq pc, r4 @ no, return failure
@@ -91,18 +102,10 @@ next:
teqne r2, #0x0E000000
movne pc, r9 @ return ok if not a fp insn
- str r5, [sp, #60] @ update PC copy in regs
+ str r5, [sp, #S_PC] @ update PC copy in regs
mov r0, r6 @ save a copy
- ldr r1, [sp, #64] @ fetch the condition codes
- bl checkCondition @ check the condition
- cmp r0, #0 @ r0 = 0 ==> condition failed
-
- @ if condition code failed to match, next insn
- beq next @ get the next instruction;
-
- mov r0, r6 @ prepare for EmulateAll()
- b emulate @ if r0 != 0, goto EmulateAll
+ b emulate @ check condition and emulate
@ We need to be prepared for the instructions at .Lx1 and .Lx2
@ to fault. Emit the appropriate exception gunk to fix things up.
diff --git a/arch/arm/nwfpe/fpa11.inl b/arch/arm/nwfpe/fpa11.inl
index 10c3caf2868..ab8d6826245 100644
--- a/arch/arm/nwfpe/fpa11.inl
+++ b/arch/arm/nwfpe/fpa11.inl
@@ -22,13 +22,13 @@
#include "fpa11.h"
/* Read and write floating point status register */
-extern __inline__ unsigned int readFPSR(void)
+static inline unsigned int readFPSR(void)
{
FPA11 *fpa11 = GET_FPA11();
return (fpa11->fpsr);
}
-extern __inline__ void writeFPSR(FPSR reg)
+static inline void writeFPSR(FPSR reg)
{
FPA11 *fpa11 = GET_FPA11();
/* the sysid byte in the status register is readonly */
@@ -36,14 +36,14 @@ extern __inline__ void writeFPSR(FPSR reg)
}
/* Read and write floating point control register */
-extern __inline__ FPCR readFPCR(void)
+static inline FPCR readFPCR(void)
{
FPA11 *fpa11 = GET_FPA11();
/* clear SB, AB and DA bits before returning FPCR */
return (fpa11->fpcr & ~MASK_RFC);
}
-extern __inline__ void writeFPCR(FPCR reg)
+static inline void writeFPCR(FPCR reg)
{
FPA11 *fpa11 = GET_FPA11();
fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
index ec78e3517fc..0090b19bbe6 100644
--- a/arch/arm/nwfpe/fpopcode.h
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -369,20 +369,20 @@ TABLE 5
#define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5)
#ifdef CONFIG_FPE_NWFPE_XP
-static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex)
+static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex)
{
extern const floatx80 floatx80Constant[];
return floatx80Constant[nIndex];
}
#endif
-static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex)
+static inline float64 __pure getDoubleConstant(const unsigned int nIndex)
{
extern const float64 float64Constant[];
return float64Constant[nIndex];
}
-static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex)
+static inline float32 __pure getSingleConstant(const unsigned int nIndex)
{
extern const float32 float32Constant[];
return float32Constant[nIndex];
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index cfc69f3842f..c1f7e5a819a 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -20,10 +20,15 @@ endchoice
comment "OMAP Feature Selections"
-config OMAP_DEBUG_LEDS
+config OMAP_DEBUG_DEVICES
bool
help
- For debug card leds on TI reference boards.
+ For debug cards on TI reference boards.
+
+config OMAP_DEBUG_LEDS
+ bool
+ depends on OMAP_DEBUG_DEVICES
+ default y if LEDS || LEDS_OMAP_DEBUG
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 41a3c1cf3bd..2549129aabc 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
+obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
new file mode 100644
index 00000000000..83a5f8b9185
--- /dev/null
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/arm/plat-omap/debug-devices.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Modified from mach-omap2/board-h4.c
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+
+/* Many OMAP development platforms reuse the same "debug board"; these
+ * platforms include H2, H3, H4, and Perseus2.
+ */
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct resource led_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device led_device = {
+ .name = "omap_dbg_led",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(led_resources),
+ .resource = led_resources,
+};
+
+static struct platform_device *debug_devices[] __initdata = {
+ &smc91x_device,
+ &led_device,
+ /* ps2 kbd + mouse ports */
+ /* 4 extra uarts */
+ /* 6 input dip switches */
+ /* 8 output pins */
+};
+
+int __init debug_card_init(u32 addr, unsigned gpio)
+{
+ int status;
+
+ smc91x_resources[0].start = addr + 0x300;
+ smc91x_resources[0].end = addr + 0x30f;
+
+ smc91x_resources[1].start = OMAP_GPIO_IRQ(gpio);
+ smc91x_resources[1].end = OMAP_GPIO_IRQ(gpio);
+
+ status = omap_request_gpio(gpio);
+ if (status < 0) {
+ printk(KERN_ERR "GPIO%d unavailable for smc91x IRQ\n", gpio);
+ return status;
+ }
+ omap_set_gpio_direction(gpio, 1);
+
+ led_resources[0].start = addr;
+ led_resources[0].end = addr + SZ_4K - 1;
+
+ return platform_add_devices(debug_devices, ARRAY_SIZE(debug_devices));
+}
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 88d5b6d9f95..05a38498cbe 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1347,11 +1347,6 @@ void omap_stop_lcd_dma(void)
omap_writew(w, OMAP1610_DMA_LCD_CTRL);
}
-int omap_lcd_dma_ext_running(void)
-{
- return lcd_dma.ext_ctrl && lcd_dma.active;
-}
-
/*----------------------------------------------------------------------------*/
static int __init omap_init_dma(void)
@@ -1493,7 +1488,6 @@ EXPORT_SYMBOL(omap_free_lcd_dma);
EXPORT_SYMBOL(omap_enable_lcd_dma);
EXPORT_SYMBOL(omap_setup_lcd_dma);
EXPORT_SYMBOL(omap_stop_lcd_dma);
-EXPORT_SYMBOL(omap_lcd_dma_ext_running);
EXPORT_SYMBOL(omap_set_lcd_dma_b1);
EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 6d048490c55..29696e46ed6 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1272,7 +1272,7 @@ struct sysdev_class dma_sysclass = {
/* kmem cache implementation */
-static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
+static void s3c2410_dma_cache_ctor(struct kmem_cache *c, void *p)
{
memset(p, 0, sizeof(struct s3c2410_dma_buf));
}
@@ -1372,7 +1372,7 @@ int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
return ret;
}
-int s3c2410_dma_init(void)
+int __init s3c2410_dma_init(void)
{
return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
}
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index eab1850616d..4fdb3117744 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -612,9 +612,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
return 0;
}
-static struct pm_ops s3c2410_pm_ops = {
+static struct platform_suspend_ops s3c2410_pm_ops = {
.enter = s3c2410_pm_enter,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
/* s3c2410_pm_init
@@ -628,6 +628,6 @@ int __init s3c2410_pm_init(void)
{
printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
- pm_set_ops(&s3c2410_pm_ops);
+ suspend_set_ops(&s3c2410_pm_ops);
return 0;
}
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index d47113bbc34..a646cbe8244 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -96,6 +96,14 @@ resume_with_mmu:
s3c2410_sleep_save_phys:
.word 0
+
+ /* sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c2410_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
/* s3c2410_cpu_resume
*
* resume code entry for bootloader to call
diff --git a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile
index 7e136e77971..39f6d8e1af7 100644
--- a/arch/arm/vfp/Makefile
+++ b/arch/arm/vfp/Makefile
@@ -7,7 +7,7 @@
# EXTRA_CFLAGS := -DDEBUG
# EXTRA_AFLAGS := -DDEBUG
-AFLAGS :=$(AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp)
+KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp)
LDFLAGS +=--no-warn-mismatch
obj-y += vfp.o
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
index dc6bc01f232..87918647be6 100644
--- a/arch/avr32/Makefile
+++ b/arch/avr32/Makefile
@@ -11,15 +11,15 @@ all: uImage vmlinux.elf
KBUILD_DEFCONFIG := atstk1002_defconfig
-CFLAGS += -pipe -fno-builtin -mno-pic
-AFLAGS += -mrelax -mno-pic
+KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic
+KBUILD_AFLAGS += -mrelax -mno-pic
CFLAGS_MODULE += -mno-relax
LDFLAGS_vmlinux += --relax
cpuflags-$(CONFIG_CPU_AT32AP7000) += -mcpu=ap7000
-CFLAGS += $(cpuflags-y)
-AFLAGS += $(cpuflags-y)
+KBUILD_CFLAGS += $(cpuflags-y)
+KBUILD_AFLAGS += $(cpuflags-y)
CHECKFLAGS += -D__avr32__ -D__BIG_ENDIAN
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 4942ee662e0..20b1c9d8f94 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -22,6 +22,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe);
static unsigned long kprobe_status;
static struct pt_regs jprobe_saved_regs;
+struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
int ret = 0;
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 39060cbeb2a..9e16b8a447f 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -227,11 +227,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- /* Detach a process that was attached */
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *)data);
break;
diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c
index 099212d4567..177fea8f7b7 100644
--- a/arch/avr32/mm/dma-coherent.c
+++ b/arch/avr32/mm/dma-coherent.c
@@ -21,13 +21,13 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction)
switch (direction) {
case DMA_FROM_DEVICE: /* invalidate only */
- dma_cache_inv(vaddr, size);
+ invalidate_dcache_region(vaddr, size);
break;
case DMA_TO_DEVICE: /* writeback only */
- dma_cache_wback(vaddr, size);
+ clean_dcache_region(vaddr, size);
break;
case DMA_BIDIRECTIONAL: /* writeback and invalidate */
- dma_cache_wback_inv(vaddr, size);
+ flush_dcache_region(vaddr, size);
break;
default:
BUG();
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index ae2d2c593b2..11472f8701b 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -216,7 +216,7 @@ out_of_memory:
}
printk("VM: Killing process %s\n", tsk->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index b24f4535ffe..aa9db307331 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -758,7 +758,7 @@ config BFIN_DMA_5XX
choice
prompt "Uncached SDRAM region"
default DMA_UNCACHED_1M
- depends BFIN_DMA_5XX
+ depends on BFIN_DMA_5XX
config DMA_UNCACHED_2M
bool "Enable 2M DMA region"
config DMA_UNCACHED_1M
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 20841663270..368933760d2 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -53,8 +53,8 @@ rev-$(CONFIG_BF_REV_0_5) := 0.5
rev-$(CONFIG_BF_REV_NONE) := none
rev-$(CONFIG_BF_REV_ANY) := any
-CFLAGS += -mcpu=$(cpu-y)-$(rev-y)
-AFLAGS += -mcpu=$(cpu-y)-$(rev-y)
+KBUILD_CFLAGS += -mcpu=$(cpu-y)-$(rev-y)
+KBUILD_AFLAGS += -mcpu=$(cpu-y)-$(rev-y)
head-y := arch/$(ARCH)/mach-$(MACHINE)/head.o arch/$(ARCH)/kernel/init_task.o
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 64ce5fea860..85caf9b711a 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -385,12 +385,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- case PTRACE_DETACH:
- { /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
- }
-
case PTRACE_GETREGS:
{
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 2c47db494f7..046e6d84bbf 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -88,7 +88,7 @@ static struct platform_device bf54x_lq043_device = {
#endif
#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
-static int bf548_keymap[] = {
+static const unsigned int bf548_keymap[] = {
KEYVAL(0, 0, KEY_ENTER),
KEYVAL(0, 1, KEY_HELP),
KEYVAL(0, 2, KEY_0),
@@ -110,8 +110,8 @@ static int bf548_keymap[] = {
static struct bfin_kpad_platform_data bf54x_kpad_data = {
.rows = 4,
.cols = 4,
- .keymap = bf548_keymap,
- .keymapsize = ARRAY_SIZE(bf548_keymap),
+ .keymap = bf548_keymap,
+ .keymapsize = ARRAY_SIZE(bf548_keymap),
.repeat = 0,
.debounce_time = 5000, /* ns (5ms) */
.coldrive_time = 1000, /* ns (1ms) */
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index b1030272220..dac51fb06f2 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -32,7 +32,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/io.h>
@@ -89,28 +89,15 @@ void bfin_pm_suspend_standby_enter(void)
#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
}
-
/*
- * bfin_pm_prepare - Do preliminary suspend work.
- * @state: suspend state we're entering.
+ * bfin_pm_valid - Tell the PM core that we only support the standby sleep
+ * state
+ * @state: suspend state we're checking.
*
*/
-static int bfin_pm_prepare(suspend_state_t state)
+static int bfin_pm_valid(suspend_state_t state)
{
- int error = 0;
-
- switch (state) {
- case PM_SUSPEND_STANDBY:
- break;
-
- case PM_SUSPEND_MEM:
- return -ENOTSUPP;
-
- default:
- return -EINVAL;
- }
-
- return error;
+ return (state == PM_SUSPEND_STANDBY);
}
/*
@@ -135,44 +122,14 @@ static int bfin_pm_enter(suspend_state_t state)
return 0;
}
-/*
- * bfin_pm_finish - Finish up suspend sequence.
- * @state: State we're coming out of.
- *
- * This is called after we wake back up (or if entering the sleep state
- * failed).
- */
-static int bfin_pm_finish(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_STANDBY:
- break;
-
- case PM_SUSPEND_MEM:
- return -ENOTSUPP;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int bfin_pm_valid(suspend_state_t state)
-{
- return (state == PM_SUSPEND_STANDBY);
-}
-
-struct pm_ops bfin_pm_ops = {
- .prepare = bfin_pm_prepare,
+struct platform_suspend_ops bfin_pm_ops = {
.enter = bfin_pm_enter,
- .finish = bfin_pm_finish,
.valid = bfin_pm_valid,
};
static int __init bfin_pm_init(void)
{
- pm_set_ops(&bfin_pm_ops);
+ suspend_set_ops(&bfin_pm_ops);
return 0;
}
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
index ee114699ef8..e6bf00c262e 100644
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -29,18 +29,18 @@ LD = $(CROSS_COMPILE)ld -mcrislinux
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
CPPFLAGS_vmlinux.lds = -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
-AFLAGS += -mlinux
+KBUILD_AFLAGS += -mlinux
-CFLAGS := $(CFLAGS) -mlinux -march=$(arch-y) -pipe
+KBUILD_CFLAGS += -mlinux -march=$(arch-y) -pipe
ifdef CONFIG_FRAME_POINTER
-CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
-CFLAGS += -fno-omit-frame-pointer
+KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
+KBUILD_CFLAGS += -fno-omit-frame-pointer
endif
head-y := arch/$(ARCH)/$(SARCH)/kernel/head.o
-LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
+LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libgcc.a)
core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/
core-y += arch/$(ARCH)/$(SARCH)/kernel/ arch/$(ARCH)/$(SARCH)/mm/
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index f4f9db698b4..b570ae9b6ca 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -177,10 +177,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
/* Get all GP registers from the child. */
case PTRACE_GETREGS: {
int i;
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index 077e973c33f..575a14bb110 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -254,8 +254,12 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* it needs to be IRQF_DISABLED to make the jiffies update work properly
*/
-static struct irqaction irq2 = { timer_interrupt, IRQF_SHARED | IRQF_DISABLED,
- CPU_MASK_NONE, "timer", NULL, NULL};
+static struct irqaction irq2 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_SHARED | IRQF_DISABLED,
+ .mask = CPU_MASK_NONE,
+ .name = "timer",
+};
void __init
time_init(void)
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 38ece0cd47c..2df60529a8a 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -245,10 +245,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
/* Get all GP registers from the child. */
case PTRACE_GETREGS: {
int i;
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 77e655f2656..697494bc2de 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -63,8 +63,12 @@ static unsigned long irq_regs[NR_CPUS] =
static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
-static struct irqaction irq_ipi = { crisv32_ipi_interrupt, IRQF_DISABLED,
- CPU_MASK_NONE, "ipi", NULL, NULL};
+static struct irqaction irq_ipi = {
+ .handler = crisv32_ipi_interrupt,
+ .flags = IRQF_DISABLED,
+ .mask = CPU_MASK_NONE,
+ .name = "ipi",
+};
extern void cris_mmu_init(void);
extern void cris_timer_init(void);
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
index 0aa0e0ebb3a..514359b8122 100644
--- a/arch/cris/kernel/sys_cris.c
+++ b/arch/cris/kernel/sys_cris.c
@@ -21,9 +21,9 @@
#include <linux/stat.h>
#include <linux/mman.h>
#include <linux/file.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/segment.h>
/*
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 8672ab7d797..8aab8143069 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -360,7 +360,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index 9bf7345c5cc..310c47a663f 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -39,13 +39,13 @@ endif
ARCHMODFLAGS += -G0 -mlong-calls
ifdef CONFIG_GPREL_DATA_8
-CFLAGS += -G8
+KBUILD_CFLAGS += -G8
else
ifdef CONFIG_GPREL_DATA_4
-CFLAGS += -G4
+KBUILD_CFLAGS += -G4
else
ifdef CONFIG_GPREL_DATA_NONE
-CFLAGS += -G0
+KBUILD_CFLAGS += -G0
endif
endif
endif
@@ -53,26 +53,26 @@ endif
#LDFLAGS_vmlinux := -Map linkmap.txt
ifdef CONFIG_GC_SECTIONS
-CFLAGS += -ffunction-sections -fdata-sections
+KBUILD_CFLAGS += -ffunction-sections -fdata-sections
LINKFLAGS += --gc-sections
endif
ifndef CONFIG_FRAME_POINTER
-CFLAGS += -mno-linked-fp
+KBUILD_CFLAGS += -mno-linked-fp
endif
ifdef CONFIG_CPU_FR451_COMPILE
-CFLAGS += -mcpu=fr450
-AFLAGS += -mcpu=fr450
+KBUILD_CFLAGS += -mcpu=fr450
+KBUILD_AFLAGS += -mcpu=fr450
ASFLAGS += -mcpu=fr450
else
ifdef CONFIG_CPU_FR551_COMPILE
-CFLAGS += -mcpu=fr550
-AFLAGS += -mcpu=fr550
+KBUILD_CFLAGS += -mcpu=fr550
+KBUILD_AFLAGS += -mcpu=fr550
ASFLAGS += -mcpu=fr550
else
-CFLAGS += -mcpu=fr400
-AFLAGS += -mcpu=fr400
+KBUILD_CFLAGS += -mcpu=fr400
+KBUILD_AFLAGS += -mcpu=fr400
ASFLAGS += -mcpu=fr400
endif
endif
@@ -80,16 +80,16 @@ endif
# pretend the kernel is going to run on an FR400 with no media-fp unit
# - reserve CC3 for use with atomic ops
# - all the extra registers are dealt with only at context switch time
-CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media
-CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2
-AFLAGS += -mno-fdpic
+KBUILD_CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media
+KBUILD_CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2
+KBUILD_AFLAGS += -mno-fdpic
ASFLAGS += -mno-fdpic
# make sure the .S files get compiled with debug info
# and disable optimisations that are unhelpful whilst debugging
ifdef CONFIG_DEBUG_INFO
-#CFLAGS += -O1
-AFLAGS += -Wa,--gdwarf2
+#KBUILD_CFLAGS += -O1
+KBUILD_AFLAGS += -Wa,--gdwarf2
ASFLAGS += -Wa,--gdwarf2
endif
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
index 6fbe2665c57..04c6b1677cc 100644
--- a/arch/frv/kernel/sys_frv.c
+++ b/arch/frv/kernel/sys_frv.c
@@ -23,10 +23,10 @@
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/syscalls.h>
+#include <linux/ipc.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
/*
* sys_pipe() is the normal C calling standard for creating
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index ed588d73d7d..e83e0bccfab 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -43,7 +43,10 @@ unsigned long __delay_loops_MHz;
static irqreturn_t timer_interrupt(int irq, void *dummy);
static struct irqaction timer_irq = {
- timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED,
+ .mask = CPU_MASK_NONE,
+ .name = "timer",
};
static inline int set_rtc_mmss(unsigned long nowtime)
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
index 6798fa0257b..05093d41d98 100644
--- a/arch/frv/mm/fault.c
+++ b/arch/frv/mm/fault.c
@@ -259,7 +259,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", current->comm);
if (user_mode(__frame))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
index 53b5c1edf59..a556447877b 100644
--- a/arch/h8300/Makefile
+++ b/arch/h8300/Makefile
@@ -30,16 +30,16 @@ ldflags-$(CONFIG_CPU_H8300H) := -mh8300helf
cflags-$(CONFIG_CPU_H8S) := -ms
ldflags-$(CONFIG_CPU_H8S) := -mh8300self
-CFLAGS += $(cflags-y)
-CFLAGS += -mint32 -fno-builtin
-CFLAGS += -g
-CFLAGS += -D__linux__
-CFLAGS += -DUTS_SYSNAME=\"uClinux\"
-AFLAGS += -DPLATFORM=$(PLATFORM) -DMODEL=$(MODEL) $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -mint32 -fno-builtin
+KBUILD_CFLAGS += -g
+KBUILD_CFLAGS += -D__linux__
+KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+KBUILD_AFLAGS += -DPLATFORM=$(PLATFORM) -DMODEL=$(MODEL) $(cflags-y)
LDFLAGS += $(ldflags-y)
CROSS_COMPILE = h8300-elf-
-LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
head-y := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index ddc62727dc9..00608be6d56 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -19,12 +19,12 @@
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/fs.h>
+#include <linux/ipc.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
#include <asm/cachectl.h>
#include <asm/traps.h>
-#include <asm/ipc.h>
#include <asm/unistd.h>
/*
diff --git a/arch/h8300/lib/Makefile b/arch/h8300/lib/Makefile
index 98272b66f4e..1577f5075b1 100644
--- a/arch/h8300/lib/Makefile
+++ b/arch/h8300/lib/Makefile
@@ -2,7 +2,4 @@
# Makefile for H8/300-specific library files..
#
-.S.o:
- $(CC) $(AFLAGS) -D__ASSEMBLY__ -c $< -o $@
-
lib-y = ashrdi3.o checksum.o memcpy.o memset.o abs.o romfs.o
diff --git a/arch/i386/.gitignore b/arch/i386/.gitignore
new file mode 100644
index 00000000000..36ef4c374d2
--- /dev/null
+++ b/arch/i386/.gitignore
@@ -0,0 +1 @@
+boot
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index bf9aafad497..b84d5050e92 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -146,6 +146,7 @@ config X86_ELAN
config X86_VOYAGER
bool "Voyager (NCR)"
+ select SMP if !BROKEN
help
Voyager is an MCA-based 32-way capable SMP architecture proprietary
to NCR Corp. Machine classes 345x/35xx/4100/51xx are Voyager-based.
@@ -831,12 +832,13 @@ config CRASH_DUMP
depends on HIGHMEM
help
Generate crash dump after being started by kexec.
- This should be normally only set in special crash dump kernels
+ This should be normally only set in special crash dump kernels
which are loaded in the main kernel with kexec-tools into
a specially reserved region and then later executed after
a crash by kdump/kexec. The crash dump kernel must be compiled
- to a memory address not used by the main kernel or BIOS using
- PHYSICAL_START.
+ to a memory address not used by the main kernel or BIOS using
+ PHYSICAL_START, or it must be built as a relocatable image
+ (CONFIG_RELOCATABLE=y).
For more details see Documentation/kdump/kdump.txt
config PHYSICAL_START
@@ -882,17 +884,17 @@ config PHYSICAL_START
Don't change this unless you know what you are doing.
config RELOCATABLE
- bool "Build a relocatable kernel(EXPERIMENTAL)"
+ bool "Build a relocatable kernel (EXPERIMENTAL)"
depends on EXPERIMENTAL
help
This builds a kernel image that retains relocation information
- so it can be loaded someplace besides the default 1MB.
+ so it can be loaded someplace besides the default 1MB.
The relocations tend to make the kernel binary about 10% larger,
- but are discarded at runtime.
+ but are discarded at runtime.
One use is for the kexec on panic case where the recovery kernel
- must live at a different physical address than the primary
- kernel.
+ must live at a different physical address than the primary
+ kernel.
config PHYSICAL_ALIGN
hex "Alignment value to which kernel should be aligned"
@@ -1256,7 +1258,6 @@ source "fs/Kconfig"
menuconfig INSTRUMENTATION
bool "Instrumentation Support"
- depends on EXPERIMENTAL
default y
---help---
Say Y here to get to see options related to performance measurement,
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 11a24d54f27..0e2adadf590 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -109,16 +109,42 @@ config MCORE2
help
Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx)
CPUs. You can distinguish newer from older Xeons by the CPU family
- in /proc/cpuinfo. Newer ones have 6.
+ in /proc/cpuinfo. Newer ones have 6 and older ones 15 (not a typo)
config MPENTIUM4
bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon"
help
Select this for Intel Pentium 4 chips. This includes the
- Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M
- (not Pentium M) chips. This option enables compile flags
- optimized for the chip, uses the correct cache shift, and
- applies any applicable Pentium III optimizations.
+ Pentium 4, Pentium D, P4-based Celeron and Xeon, and
+ Pentium-4 M (not Pentium M) chips. This option enables compile
+ flags optimized for the chip, uses the correct cache line size, and
+ applies any applicable optimizations.
+
+ CPUIDs: F[0-6][1-A] (in /proc/cpuinfo show = cpu family : 15 )
+
+ Select this for:
+ Pentiums (Pentium 4, Pentium D, Celeron, Celeron D) corename:
+ -Willamette
+ -Northwood
+ -Mobile Pentium 4
+ -Mobile Pentium 4 M
+ -Extreme Edition (Gallatin)
+ -Prescott
+ -Prescott 2M
+ -Cedar Mill
+ -Presler
+ -Smithfiled
+ Xeons (Intel Xeon, Xeon MP, Xeon LV, Xeon MV) corename:
+ -Foster
+ -Prestonia
+ -Gallatin
+ -Nocona
+ -Irwindale
+ -Cranford
+ -Potomac
+ -Paxville
+ -Dempsey
+
config MK6
bool "K6/K6-II/K6-III"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 5e50dbf00f3..f036d2dee3d 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -34,10 +34,10 @@ LDFLAGS_vmlinux := --emit-relocs
endif
CHECKFLAGS += -D__i386__
-CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return
+KBUILD_CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return
# prevent gcc from keeping the stack 16 byte aligned
-CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
+KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
# CPU-specific tuning. Anything which can be shared with UML should go here.
include $(srctree)/arch/i386/Makefile.cpu
@@ -51,17 +51,17 @@ cflags-y += -maccumulate-outgoing-args
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
# a lot more stack due to the lack of sharing of stacklots:
-CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
+KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
# do binutils support CFI?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
+KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
-CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
# Default subarch .c files
mcore-y := arch/x86/mach-default
@@ -116,8 +116,8 @@ drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
drivers-$(CONFIG_PM) += arch/x86/power/
drivers-$(CONFIG_FB) += arch/x86/video/
-CFLAGS += $(mflags-y)
-AFLAGS += $(mflags-y)
+KBUILD_CFLAGS += $(mflags-y)
+KBUILD_AFLAGS += $(mflags-y)
boot := arch/x86/boot
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 2e6310b8eab..c60532d93c5 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -54,6 +54,11 @@ config ARCH_HAS_ILOG2_U64
bool
default n
+config HUGETLB_PAGE_SIZE_VARIABLE
+ bool
+ depends on HUGETLB_PAGE
+ default y
+
config GENERIC_FIND_NEXT_BIT
bool
default y
@@ -300,6 +305,9 @@ config HOTPLUG_CPU
config ARCH_ENABLE_MEMORY_HOTPLUG
def_bool y
+config ARCH_ENABLE_MEMORY_HOTREMOVE
+ def_bool y
+
config SCHED_SMT
bool "SMT scheduler support"
depends on SMP
@@ -348,6 +356,7 @@ config ARCH_FLATMEM_ENABLE
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on ARCH_DISCONTIGMEM_ENABLE
+ select SPARSEMEM_VMEMMAP_ENABLE
config ARCH_DISCONTIGMEM_DEFAULT
def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB)
@@ -584,7 +593,6 @@ config IRQ_PER_CPU
source "arch/ia64/hp/sim/Kconfig"
menu "Instrumentation Support"
- depends on EXPERIMENTAL
source "arch/ia64/oprofile/Kconfig"
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 21033ed8330..34951aa2370 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -29,7 +29,7 @@ cflags-y := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
CFLAGS_KERNEL := -mconstant-gp
GAS_STATUS = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)")
-CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
+KBUILD_CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
ifeq ($(GAS_STATUS),buggy)
$(error Sorry, you need a newer version of the assember, one that is built from \
@@ -44,7 +44,7 @@ ifeq ($(call cc-version),0304)
cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley
endif
-CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
libs-y += arch/ia64/lib/
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index e980e7aa230..3c95f4184b9 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -396,7 +396,7 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents,
startsg->dma_address, startsg->dma_length,
sba_sg_address(startsg));
- startsg++;
+ startsg = sg_next(startsg);
}
}
@@ -409,7 +409,7 @@ sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
while (the_nents-- > 0) {
if (sba_sg_address(the_sg) == 0x0UL)
sba_dump_sg(NULL, startsg, nents);
- the_sg++;
+ the_sg = sg_next(the_sg);
}
}
@@ -1179,7 +1179,6 @@ sba_fill_pdir(
u64 *pdirp = NULL;
unsigned long dma_offset = 0;
- dma_sg--;
while (nents-- > 0) {
int cnt = startsg->dma_length;
startsg->dma_length = 0;
@@ -1201,7 +1200,8 @@ sba_fill_pdir(
u32 pide = startsg->dma_address & ~PIDE_FLAG;
dma_offset = (unsigned long) pide & ~iovp_mask;
startsg->dma_address = 0;
- dma_sg++;
+ if (n_mappings)
+ dma_sg = sg_next(dma_sg);
dma_sg->dma_address = pide | ioc->ibase;
pdirp = &(ioc->pdir_base[pide >> iovp_shift]);
n_mappings++;
@@ -1228,7 +1228,7 @@ sba_fill_pdir(
pdirp++;
} while (cnt > 0);
}
- startsg++;
+ startsg = sg_next(startsg);
}
/* force pdir update */
wmb();
@@ -1297,7 +1297,7 @@ sba_coalesce_chunks( struct ioc *ioc,
while (--nents > 0) {
unsigned long vaddr; /* tmp */
- startsg++;
+ startsg = sg_next(startsg);
/* PARANOID */
startsg->dma_address = startsg->dma_length = 0;
@@ -1407,7 +1407,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di
#ifdef ALLOW_IOV_BYPASS_SG
ASSERT(to_pci_dev(dev)->dma_mask);
if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) {
- for (sg = sglist ; filled < nents ; filled++, sg++){
+ for_each_sg(sglist, sg, nents, filled) {
sg->dma_length = sg->length;
sg->dma_address = virt_to_phys(sba_sg_address(sg));
}
@@ -1501,7 +1501,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in
while (nents && sglist->dma_length) {
sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir);
- sglist++;
+ sglist = sg_next(sglist);
nents--;
}
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index d62fa76e5a7..a3a558a0675 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -360,6 +360,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = 1024,
.cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int __init
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index 1cfab326fb7..f6ae3ec9381 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -240,7 +240,7 @@ static int __init check_elf32_binfmt(void)
{
if (cpu_uses_ia32el()) {
printk("Please use IA-32 EL for executing IA-32 binaries\n");
- return unregister_binfmt(&elf_format);
+ unregister_binfmt(&elf_format);
}
return 0;
}
diff --git a/arch/ia64/ia32/elfcore32.h b/arch/ia64/ia32/elfcore32.h
index a47f63b204f..446c9aac924 100644
--- a/arch/ia64/ia32/elfcore32.h
+++ b/arch/ia64/ia32/elfcore32.h
@@ -117,6 +117,7 @@ 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
static inline int
elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu)
{
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
index 6d198339bf8..44817d97ab4 100644
--- a/arch/ia64/kernel/gate.lds.S
+++ b/arch/ia64/kernel/gate.lds.S
@@ -1,7 +1,8 @@
/*
- * Linker script for gate DSO. The gate pages are an ELF shared object prelinked to its
- * virtual address, with only one read-only segment and one execute-only segment (both fit
- * in one page). This script controls its layout.
+ * Linker script for gate DSO. The gate pages are an ELF shared object
+ * prelinked to its virtual address, with only one read-only segment and
+ * one execute-only segment (both fit in one page). This script controls
+ * its layout.
*/
@@ -9,72 +10,80 @@
SECTIONS
{
- . = GATE_ADDR + SIZEOF_HEADERS;
-
- .hash : { *(.hash) } :readable
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .dynamic : { *(.dynamic) } :readable :dynamic
-
- /*
- * This linker script is used both with -r and with -shared. For the layouts to match,
- * we need to skip more than enough space for the dynamic symbol table et al. If this
- * amount is insufficient, ld -shared will barf. Just increase it here.
- */
- . = GATE_ADDR + 0x500;
-
- .data.patch : {
- __start_gate_mckinley_e9_patchlist = .;
- *(.data.patch.mckinley_e9)
- __end_gate_mckinley_e9_patchlist = .;
-
- __start_gate_vtop_patchlist = .;
- *(.data.patch.vtop)
- __end_gate_vtop_patchlist = .;
-
- __start_gate_fsyscall_patchlist = .;
- *(.data.patch.fsyscall_table)
- __end_gate_fsyscall_patchlist = .;
-
- __start_gate_brl_fsys_bubble_down_patchlist = .;
- *(.data.patch.brl_fsys_bubble_down)
- __end_gate_brl_fsys_bubble_down_patchlist = .;
- } :readable
- .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
- .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind
+ . = GATE_ADDR + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :readable
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .dynamic : { *(.dynamic) } :readable :dynamic
+
+ /*
+ * This linker script is used both with -r and with -shared. For
+ * the layouts to match, we need to skip more than enough space for
+ * the dynamic symbol table et al. If this amount is insufficient,
+ * ld -shared will barf. Just increase it here.
+ */
+ . = GATE_ADDR + 0x500;
+
+ .data.patch : {
+ __start_gate_mckinley_e9_patchlist = .;
+ *(.data.patch.mckinley_e9)
+ __end_gate_mckinley_e9_patchlist = .;
+
+ __start_gate_vtop_patchlist = .;
+ *(.data.patch.vtop)
+ __end_gate_vtop_patchlist = .;
+
+ __start_gate_fsyscall_patchlist = .;
+ *(.data.patch.fsyscall_table)
+ __end_gate_fsyscall_patchlist = .;
+
+ __start_gate_brl_fsys_bubble_down_patchlist = .;
+ *(.data.patch.brl_fsys_bubble_down)
+ __end_gate_brl_fsys_bubble_down_patchlist = .;
+ } :readable
+
+ .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
+ .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind
#ifdef HAVE_BUGGY_SEGREL
- .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable
+ .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable
#else
- . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
- .text : { *(.text) *(.text.*) } :epc
+ . = ALIGN(PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
+ .text : { *(.text) *(.text.*) } :epc
#endif
- /DISCARD/ : {
- *(.got.plt) *(.got)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(__ex_table)
- *(__mca_table)
- }
+ /DISCARD/ : {
+ *(.got.plt) *(.got)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(__ex_table)
+ *(__mca_table)
+ }
}
/*
+ * ld does not recognize this name token; use the constant.
+ */
+#define PT_IA_64_UNWIND 0x70000001
+
+/*
* We must supply the ELF program headers explicitly to get just one
* PT_LOAD segment, and set the flags explicitly to make segments read-only.
*/
PHDRS
{
- readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */
+ readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */
#ifndef HAVE_BUGGY_SEGREL
- epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */
+ epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */
#endif
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ unwind PT_IA_64_UNWIND;
}
/*
@@ -82,14 +91,14 @@ PHDRS
*/
VERSION
{
- LINUX_2.5 {
- global:
- __kernel_syscall_via_break;
- __kernel_syscall_via_epc;
- __kernel_sigtramp;
-
- local: *;
- };
+ LINUX_2.5 {
+ global:
+ __kernel_syscall_via_break;
+ __kernel_syscall_via_epc;
+ __kernel_sigtramp;
+
+ local: *;
+ };
}
/* The ELF entry point can be used to set the AT_SYSINFO value. */
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 5dc98b5abcf..5fd65d8302c 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -40,6 +40,8 @@ extern void jprobe_inst_return(void);
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+
enum instruction_type {A, I, M, F, B, L, X, u};
static enum instruction_type bundle_encoding[32][3] = {
{ M, I, I }, /* 00 */
diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
index 58e943a5d95..d6cd45f4c6c 100644
--- a/arch/ia64/kernel/machine_kexec.c
+++ b/arch/ia64/kernel/machine_kexec.c
@@ -15,10 +15,15 @@
#include <linux/cpu.h>
#include <linux/irq.h>
#include <linux/efi.h>
+#include <linux/numa.h>
+#include <linux/mmzone.h>
+
+#include <asm/numa.h>
#include <asm/mmu_context.h>
#include <asm/setup.h>
#include <asm/delay.h>
#include <asm/meminit.h>
+#include <asm/processor.h>
typedef NORET_TYPE void (*relocate_new_kernel_t)(
unsigned long indirection_page,
@@ -121,3 +126,28 @@ void machine_kexec(struct kimage *image)
unw_init_running(ia64_machine_kexec, image);
for(;;);
}
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#if defined(CONFIG_ARCH_DISCONTIGMEM_ENABLE) && defined(CONFIG_NUMA)
+ VMCOREINFO_SYMBOL(pgdat_list);
+ VMCOREINFO_LENGTH(pgdat_list, MAX_NUMNODES);
+
+ VMCOREINFO_SYMBOL(node_memblk);
+ VMCOREINFO_LENGTH(node_memblk, NR_NODE_MEMBLKS);
+ VMCOREINFO_SIZE(node_memblk_s);
+ VMCOREINFO_OFFSET(node_memblk_s, start_paddr);
+ VMCOREINFO_OFFSET(node_memblk_s, size);
+#endif
+#ifdef CONFIG_PGTABLE_3
+ VMCOREINFO_CONFIG(PGTABLE_3);
+#elif CONFIG_PGTABLE_4
+ VMCOREINFO_CONFIG(PGTABLE_4);
+#endif
+}
+
+unsigned long paddr_vmcoreinfo_note(void)
+{
+ return ia64_tpa((unsigned long)(char *)&vmcoreinfo_note);
+}
+
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 9e392a30d19..c5cfcfa4c87 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -528,10 +528,6 @@ setup_arch (char **cmdline_p)
#ifdef CONFIG_SMP
cpu_physical_id(0) = hard_smp_processor_id();
-
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
-
check_for_logical_procs();
if (smp_num_cpucores > 1)
printk(KERN_INFO
@@ -873,6 +869,16 @@ cpu_init (void)
void *cpu_data;
cpu_data = per_cpu_init();
+#ifdef CONFIG_SMP
+ /*
+ * insert boot cpu into sibling and core mapes
+ * (must be done after per_cpu area is setup)
+ */
+ if (smp_processor_id() == 0) {
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, cpu_core_map[0]);
+ }
+#endif
/*
* We set ar.k3 so that assembly code in MCA handler can compute
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 308772f7cdd..c57dbce25c1 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -138,7 +138,9 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_possible_map);
cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
-cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
+DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
+
int smp_num_siblings = 1;
int smp_num_cpucores = 1;
@@ -650,12 +652,12 @@ clear_cpu_sibling_map(int cpu)
{
int i;
- for_each_cpu_mask(i, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[i]);
+ for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
for_each_cpu_mask(i, cpu_core_map[cpu])
cpu_clear(cpu, cpu_core_map[i]);
- cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE;
+ per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE;
}
static void
@@ -666,7 +668,7 @@ remove_siblinginfo(int cpu)
if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
cpu_clear(cpu, cpu_core_map[cpu]);
- cpu_clear(cpu, cpu_sibling_map[cpu]);
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu));
return;
}
@@ -807,8 +809,8 @@ set_cpu_sibling_map(int cpu)
cpu_set(i, cpu_core_map[cpu]);
cpu_set(cpu, cpu_core_map[i]);
if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
+ cpu_set(i, per_cpu(cpu_sibling_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_sibling_map, i));
}
}
}
@@ -839,7 +841,7 @@ __cpu_up (unsigned int cpu)
if (cpu_data(cpu)->threads_per_core == 1 &&
cpu_data(cpu)->cores_per_socket == 1) {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, cpu_core_map[cpu]);
return 0;
}
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 98cfc90cab1..2bb84214e5f 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -371,6 +371,11 @@ ia64_setup_printk_clock(void)
ia64_printk_clock = ia64_itc_printk_clock;
}
+/* IA64 doesn't cache the timezone */
+void update_vsyscall_tz(void)
+{
+}
+
void update_vsyscall(struct timespec *wall, struct clocksource *c)
{
unsigned long flags;
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index c58e933694d..a7be4f20342 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -196,7 +196,7 @@ unsigned long uncached_alloc_page(int starting_nid)
nid = starting_nid;
do {
- if (!node_online(nid))
+ if (!node_state(nid, N_HIGH_MEMORY))
continue;
uc_pool = &uncached_pools[nid];
if (uc_pool->pool == NULL)
@@ -268,7 +268,7 @@ static int __init uncached_init(void)
{
int nid;
- for_each_online_node(nid) {
+ for_each_node_state(nid, N_ONLINE) {
uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid);
mutex_init(&uncached_pools[nid].add_chunk_mutex);
}
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 0d34585058c..0b567398f38 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -48,7 +48,7 @@ struct early_node_data {
static struct early_node_data mem_data[MAX_NUMNODES] __initdata;
static nodemask_t memory_less_mask __initdata;
-static pg_data_t *pgdat_list[MAX_NUMNODES];
+pg_data_t *pgdat_list[MAX_NUMNODES];
/*
* To prevent cache aliasing effects, align per-node structures so that they
@@ -715,3 +715,11 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
scatter_node_data();
}
#endif
+
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+int __meminit vmemmap_populate(struct page *start_page,
+ unsigned long size, int node)
+{
+ return vmemmap_populate_basepages(start_page, size, node);
+}
+#endif
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 9150ffaff9e..32f26253c4e 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -281,6 +281,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
}
printk(KERN_CRIT "VM: killing process %s\n", current->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
}
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index a9ff685aea2..d3ce8f3bcaa 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -194,6 +194,6 @@ static int __init hugetlb_setup_sz(char *str)
* override here with new page shift.
*/
ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2);
- return 1;
+ return 0;
}
-__setup("hugepagesz=", hugetlb_setup_sz);
+early_param("hugepagesz", hugetlb_setup_sz);
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index c14abefabaf..3e10152abbf 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -54,15 +54,12 @@ struct page *zero_page_memmap_ptr; /* map entry for zero page */
EXPORT_SYMBOL(zero_page_memmap_ptr);
void
-lazy_mmu_prot_update (pte_t pte)
+__ia64_sync_icache_dcache (pte_t pte)
{
unsigned long addr;
struct page *page;
unsigned long order;
- if (!pte_exec(pte))
- return; /* not an executable page... */
-
page = pte_page(pte);
addr = (unsigned long) page_address(page);
@@ -721,10 +718,21 @@ int arch_add_memory(int nid, u64 start, u64 size)
return ret;
}
-
+#ifdef CONFIG_MEMORY_HOTREMOVE
int remove_memory(u64 start, u64 size)
{
- return -EINVAL;
+ unsigned long start_pfn, end_pfn;
+ unsigned long timeout = 120 * HZ;
+ int ret;
+ start_pfn = start >> PAGE_SHIFT;
+ end_pfn = start_pfn + (size >> PAGE_SHIFT);
+ ret = offline_pages(start_pfn, end_pfn, timeout);
+ if (ret)
+ goto out;
+ /* we can free mem_map at this point */
+out:
+ return ret;
}
EXPORT_SYMBOL_GPL(remove_memory);
+#endif /* CONFIG_MEMORY_HOTREMOVE */
#endif
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index 0a59371d347..688a3c27e0f 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -7,7 +7,7 @@
# Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All Rights Reserved.
#
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+EXTRA_CFLAGS += -Iarch/ia64/sn/include
obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \
huberror.o io_acpi_init.o io_common.o \
diff --git a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile
index 99e17769323..08e6565dc90 100644
--- a/arch/ia64/sn/kernel/sn2/Makefile
+++ b/arch/ia64/sn/kernel/sn2/Makefile
@@ -9,7 +9,7 @@
# sn2 specific kernel files
#
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+EXTRA_CFLAGS += -Iarch/ia64/sn/include
obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c
index e58fcadff2e..a5df672d839 100644
--- a/arch/ia64/sn/kernel/xpnet.c
+++ b/arch/ia64/sn/kernel/xpnet.c
@@ -269,8 +269,9 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg)
skb->protocol = eth_type_trans(skb, xpnet_device);
skb->ip_summed = CHECKSUM_UNNECESSARY;
- dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p "
- "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n",
+ dev_dbg(xpnet, "passing skb to network layer\n"
+ KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
+ "skb->end=0x%p skb->len=%d\n",
(void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
skb_end_pointer(skb), skb->len);
@@ -576,10 +577,10 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
msg->buf_pa = __pa(start_addr);
- dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa="
- "0x%lx, msg->size=%u, msg->leadin_ignore=%u, "
- "msg->tailout_ignore=%u\n", dest_partid,
- XPC_NET_CHANNEL, msg->buf_pa, msg->size,
+ dev_dbg(xpnet, "sending XPC message to %d:%d\n"
+ KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, "
+ "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
+ dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
msg->leadin_ignore, msg->tailout_ignore);
diff --git a/arch/ia64/sn/pci/Makefile b/arch/ia64/sn/pci/Makefile
index c6946784a6a..ad4ef34dfe2 100644
--- a/arch/ia64/sn/pci/Makefile
+++ b/arch/ia64/sn/pci/Makefile
@@ -7,6 +7,6 @@
#
# Makefile for the sn pci general routines.
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+EXTRA_CFLAGS += -Iarch/ia64/sn/include
obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index d79ddacfba2..ecd8a52b9b9 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -218,16 +218,17 @@ EXPORT_SYMBOL(sn_dma_unmap_single);
*
* Unmap a set of streaming mode DMA translations.
*/
-void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
int nhwentries, int direction)
{
int i;
struct pci_dev *pdev = to_pci_dev(dev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
+ struct scatterlist *sg;
BUG_ON(dev->bus != &pci_bus_type);
- for (i = 0; i < nhwentries; i++, sg++) {
+ for_each_sg(sgl, sg, nhwentries, i) {
provider->dma_unmap(pdev, sg->dma_address, direction);
sg->dma_address = (dma_addr_t) NULL;
sg->dma_length = 0;
@@ -244,11 +245,11 @@ EXPORT_SYMBOL(sn_dma_unmap_sg);
*
* Maps each entry of @sg for DMA.
*/
-int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries,
int direction)
{
unsigned long phys_addr;
- struct scatterlist *saved_sg = sg;
+ struct scatterlist *saved_sg = sgl, *sg;
struct pci_dev *pdev = to_pci_dev(dev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
int i;
@@ -258,7 +259,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
/*
* Setup a DMA address for each entry in the scatterlist.
*/
- for (i = 0; i < nhwentries; i++, sg++) {
+ for_each_sg(sgl, sg, nhwentries, i) {
phys_addr = SG_ENT_PHYS_ADDRESS(sg);
sg->dma_address = provider->dma_map(pdev,
phys_addr, sg->length,
diff --git a/arch/ia64/sn/pci/pcibr/Makefile b/arch/ia64/sn/pci/pcibr/Makefile
index 3b403ea456f..01192d3247d 100644
--- a/arch/ia64/sn/pci/pcibr/Makefile
+++ b/arch/ia64/sn/pci/pcibr/Makefile
@@ -7,7 +7,7 @@
#
# Makefile for the sn2 io routines.
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+EXTRA_CFLAGS += -Iarch/ia64/sn/include
obj-y += pcibr_dma.o pcibr_reg.o \
pcibr_ate.o pcibr_provider.o
diff --git a/arch/m32r/Makefile b/arch/m32r/Makefile
index 60e12f31265..4072a07ebf8 100644
--- a/arch/m32r/Makefile
+++ b/arch/m32r/Makefile
@@ -9,7 +9,7 @@ LDFLAGS :=
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LDFLAGS_vmlinux :=
-CFLAGS += -pipe -fno-schedule-insns
+KBUILD_CFLAGS += -pipe -fno-schedule-insns
CFLAGS_KERNEL += -mmodel=medium
CFLAGS_MODULE += -mmodel=large
@@ -24,14 +24,14 @@ endif
cflags-$(CONFIG_ISA_M32R) += -DNO_FPU
aflags-$(CONFIG_ISA_M32R) += -DNO_FPU -O2 -Wa,-no-bitinst
-CFLAGS += $(cflags-y)
-AFLAGS += $(aflags-y)
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_AFLAGS += $(aflags-y)
CHECKFLAGS += -D__m32r__ -D__BIG_ENDIAN__=1
head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
libs-y += arch/m32r/lib/ $(LIBGCC)
core-y += arch/m32r/kernel/ \
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 62a51429306..ed4d0756c5d 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -570,7 +570,7 @@ withdraw_debug_trap(struct pt_regs *regs)
}
}
-static void
+void
init_debug_traps(struct task_struct *child)
{
struct debug_trap *p = &child->thread.debug_trap;
@@ -593,8 +593,8 @@ void ptrace_disable(struct task_struct *child)
/* nothing to do.. */
}
-static int
-do_ptrace(long request, struct task_struct *child, long addr, long data)
+long
+arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
int ret;
@@ -704,14 +704,6 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
break;
}
- /*
- * detach a process that was attached.
- */
- case PTRACE_DETACH:
- ret = 0;
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS:
ret = ptrace_getregs(child, (void __user *)data);
break;
@@ -728,42 +720,6 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
return ret;
}
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
- struct task_struct *child;
- int ret;
-
- lock_kernel();
- if (request == PTRACE_TRACEME) {
- ret = ptrace_traceme();
- goto out;
- }
-
- child = ptrace_get_task_struct(pid);
- if (IS_ERR(child)) {
- ret = PTR_ERR(child);
- goto out;
- }
-
- if (request == PTRACE_ATTACH) {
- ret = ptrace_attach(child);
- if (ret == 0)
- init_debug_traps(child);
- goto out_tsk;
- }
-
- ret = ptrace_check_attach(child, request == PTRACE_KILL);
- if (ret == 0)
- ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
- put_task_struct(child);
-out:
- unlock_kernel();
-
- return ret;
-}
-
/* notification of system call entry/exit
* - triggered by current->work.syscall_trace
*/
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index b13dbbeaeaf..0fc2efec18f 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -20,11 +20,11 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
#include <asm/cachectl.h>
#include <asm/cacheflush.h>
-#include <asm/ipc.h>
#include <asm/syscall.h>
#include <asm/unistd.h>
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 3858c9f39ba..994cc155635 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -228,8 +228,12 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE,
- "MFT2", NULL, NULL };
+struct irqaction irq0 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED,
+ .mask = CPU_MASK_NONE,
+ .name = "MFT2",
+};
void __init time_init(void)
{
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 676a1c443d2..70a766aad3e 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -278,7 +278,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", tsk->comm);
if (error_code & ACE_USERMODE)
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index aa383a5ea7a..4a1bd44ff16 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -32,18 +32,18 @@ endif
CHECKFLAGS += -D__mc68000__
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
-CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
+KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
# enable processor switch if compiled only for a single cpu
ifndef CONFIG_M68020
ifndef CONFIG_M68030
ifndef CONFIG_M68060
-CFLAGS := $(CFLAGS) -m68040
+KBUILD_CFLAGS += -m68040
endif
ifndef CONFIG_M68040
-CFLAGS := $(CFLAGS) -m68060
+KBUILD_CFLAGS += -m68060
endif
endif
@@ -52,7 +52,7 @@ endif
ifdef CONFIG_KGDB
# If configured for kgdb support, include debugging infos and keep the
# frame pointer
-CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
+KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
endif
ifndef CONFIG_SUN3
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index fbbccb5e751..880add120eb 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -1,6 +1,4 @@
/*
- * linux/arch/m68k/atari/atakeyb.c
- *
* Atari Keyboard driver for 680x0 Linux
*
* This file is subject to the terms and conditions of the GNU General Public
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index e792d3cba4c..2075543c2d9 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -226,10 +226,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
wake_up_process(child);
break;
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS: /* Get all gp regs from the child. */
for (i = 0; i < 19; i++) {
tmp = get_reg(child, i);
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 36d78cf1a7b..e892f17ba3f 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -21,12 +21,12 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ipc.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
#include <asm/cachectl.h>
#include <asm/traps.h>
-#include <asm/ipc.h>
#include <asm/page.h>
#include <asm/unistd.h>
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index 578b48f47b9..eaa61868115 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -188,7 +188,7 @@ out_of_memory:
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
no_context:
current->thread.signo = SIGBUS;
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index 1305cc98002..92227aaaa26 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -102,11 +102,11 @@ cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
cflags-$(CONFIG_M68360) := -m68332
-AFLAGS += $(cflags-y)
+KBUILD_AFLAGS += $(cflags-y)
-CFLAGS += $(cflags-y)
-CFLAGS += -D__linux__
-CFLAGS += -DUTS_SYSNAME=\"uClinux\"
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -D__linux__
+KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index 15d62c5279a..65f7a95f056 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -18,13 +18,13 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ipc.h>
#include <linux/fs.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
#include <asm/cachectl.h>
#include <asm/traps.h>
-#include <asm/ipc.h>
#include <asm/cacheflush.h>
#include <asm/unistd.h>
diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile
index 701b7abe019..c7bb0cef31a 100644
--- a/arch/m68knommu/platform/5206/Makefile
+++ b/arch/m68knommu/platform/5206/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/5206e/Makefile b/arch/m68knommu/platform/5206e/Makefile
index 701b7abe019..c7bb0cef31a 100644
--- a/arch/m68knommu/platform/5206e/Makefile
+++ b/arch/m68knommu/platform/5206e/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
index e861b05106b..31b4eb51739 100644
--- a/arch/m68knommu/platform/520x/Makefile
+++ b/arch/m68knommu/platform/520x/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile
index c1578b01616..ac9fbece8a4 100644
--- a/arch/m68knommu/platform/523x/Makefile
+++ b/arch/m68knommu/platform/523x/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile
index 701b7abe019..c7bb0cef31a 100644
--- a/arch/m68knommu/platform/5249/Makefile
+++ b/arch/m68knommu/platform/5249/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile
index 0871a29dd58..7475c38c3b4 100644
--- a/arch/m68knommu/platform/5272/Makefile
+++ b/arch/m68knommu/platform/5272/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68knommu/platform/527x/Makefile
index 0871a29dd58..7475c38c3b4 100644
--- a/arch/m68knommu/platform/527x/Makefile
+++ b/arch/m68knommu/platform/527x/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68knommu/platform/528x/Makefile
index 0871a29dd58..7475c38c3b4 100644
--- a/arch/m68knommu/platform/528x/Makefile
+++ b/arch/m68knommu/platform/528x/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index 719a313494b..5b600530c8d 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-$(CONFIG_COLDFIRE) += entry.o vectors.o
diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile
index 12301803b9e..475b92866a9 100644
--- a/arch/m68knommu/platform/532x/Makefile
+++ b/arch/m68knommu/platform/532x/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
#obj-y := config.o usb-mcf532x.o spi-mcf532x.o
diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile
index 91b2f495dd3..68633b27df5 100644
--- a/arch/m68knommu/platform/5407/Makefile
+++ b/arch/m68knommu/platform/5407/Makefile
@@ -13,7 +13,7 @@
#
ifdef CONFIG_FULLDEBUG
-AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+EXTRA_AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
endif
obj-y := config.o
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f943736541c..cb027580cd1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -21,6 +21,7 @@ config MACH_ALCHEMY
config BASLER_EXCITE
bool "Basler eXcite smart camera"
+ select CEVT_R4K
select DMA_COHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -47,6 +48,7 @@ config BASLER_EXCITE_PROTOTYPE
config BCM47XX
bool "BCM47XX based boards"
+ select CEVT_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -63,6 +65,7 @@ config BCM47XX
config MIPS_COBALT
bool "Cobalt Server"
+ select CEVT_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
select I8253
@@ -80,6 +83,7 @@ config MIPS_COBALT
config MACH_DECSTATION
bool "DECstations"
select BOOT_ELF32
+ select CEVT_R4K
select DMA_NONCOHERENT
select NO_IOPORT
select IRQ_CPU
@@ -111,6 +115,7 @@ config MACH_JAZZ
select ARC
select ARC32
select ARCH_MAY_HAVE_PC_FDC
+ select CEVT_R4K
select GENERIC_ISA_DMA
select IRQ_CPU
select I8253
@@ -130,9 +135,11 @@ config MACH_JAZZ
config LASAT
bool "LASAT Networks platforms"
+ select CEVT_R4K
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
select HW_HAS_PCI
+ select IRQ_CPU
select PCI_GT64XXX_PCI0
select MIPS_NILE4
select R5000_CPU_SCACHE
@@ -145,6 +152,7 @@ config LASAT
config LEMOTE_FULONG
bool "Lemote Fulong mini-PC"
select ARCH_SPARSEMEM_ENABLE
+ select CEVT_R4K
select SYS_HAS_CPU_LOONGSON2
select DMA_NONCOHERENT
select BOOT_ELF32
@@ -169,6 +177,7 @@ config LEMOTE_FULONG
config MIPS_ATLAS
bool "MIPS Atlas board"
select BOOT_ELF32
+ select CEVT_R4K
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
select IRQ_CPU
@@ -199,6 +208,7 @@ config MIPS_MALTA
bool "MIPS Malta board"
select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
+ select CEVT_R4K
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select IRQ_CPU
@@ -229,6 +239,7 @@ config MIPS_MALTA
config MIPS_SEAD
bool "MIPS SEAD board"
+ select CEVT_R4K
select IRQ_CPU
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
@@ -247,6 +258,7 @@ config MIPS_SEAD
config MIPS_SIM
bool 'MIPS simulator (MIPSsim)'
+ select CEVT_R4K
select DMA_NONCOHERENT
select SYS_HAS_EARLY_PRINTK
select IRQ_CPU
@@ -264,6 +276,7 @@ config MIPS_SIM
config MARKEINS
bool "NEC EMMA2RH Mark-eins"
+ select CEVT_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -278,6 +291,7 @@ config MARKEINS
config MACH_VR41XX
bool "NEC VR4100 series based machines"
+ select CEVT_R4K
select SYS_HAS_CPU_VR41XX
select GENERIC_HARDIRQS_NO__DO_IRQ
@@ -314,6 +328,7 @@ config PMC_MSP
config PMC_YOSEMITE
bool "PMC-Sierra Yosemite eval board"
+ select CEVT_R4K
select DMA_COHERENT
select HW_HAS_PCI
select IRQ_CPU
@@ -334,6 +349,7 @@ config PMC_YOSEMITE
config QEMU
bool "Qemu"
+ select CEVT_R4K
select DMA_COHERENT
select GENERIC_ISA_DMA
select HAVE_STD_PC_SERIAL_PORT
@@ -364,6 +380,7 @@ config SGI_IP22
select ARC
select ARC32
select BOOT_ELF32
+ select CEVT_R4K
select DMA_NONCOHERENT
select HW_HAS_EISA
select I8253
@@ -408,8 +425,10 @@ config SGI_IP32
select ARC
select ARC32
select BOOT_ELF32
+ select CEVT_R4K
select DMA_NONCOHERENT
select HW_HAS_PCI
+ select IRQ_CPU
select R5000_CPU_SCACHE
select RM7000_CPU_SCACHE
select SYS_HAS_CPU_R5000
@@ -534,6 +553,7 @@ config SNI_RM
select ARC32 if CPU_LITTLE_ENDIAN
select ARCH_MAY_HAVE_PC_FDC
select BOOT_ELF32
+ select CEVT_R4K
select DMA_NONCOHERENT
select GENERIC_ISA_DMA
select HW_HAS_EISA
@@ -575,6 +595,7 @@ config TOSHIBA_JMR3927
config TOSHIBA_RBTX4927
bool "Toshiba RBTX49[23]7 board"
+ select CEVT_R4K
select DMA_NONCOHERENT
select HAS_TXX9_SERIAL
select HW_HAS_PCI
@@ -595,6 +616,7 @@ config TOSHIBA_RBTX4927
config TOSHIBA_RBTX4938
bool "Toshiba RBTX4938 board"
+ select CEVT_R4K
select DMA_NONCOHERENT
select HAS_TXX9_SERIAL
select HW_HAS_PCI
@@ -614,6 +636,7 @@ config TOSHIBA_RBTX4938
config WR_PPMC
bool "Wind River PPMC board"
+ select CEVT_R4K
select IRQ_CPU
select BOOT_ELF32
select DMA_NONCOHERENT
@@ -706,6 +729,9 @@ config ARCH_MAY_HAVE_PC_FDC
config BOOT_RAW
bool
+config CEVT_R4K
+ bool
+
config CFE
bool
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index ebd5d02a7d7..14164c2b879 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -279,7 +279,6 @@ core-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/
cflags-$(CONFIG_MACH_DECSTATION)+= -Iinclude/asm-mips/mach-dec
libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/
load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000
-CLEAN_FILES += drivers/tc/lk201-map.c
#
# Wind River PPMC Board (4KC + GT64120)
@@ -608,14 +607,14 @@ ifdef CONFIG_64BIT
endif
endif
-AFLAGS += $(cflags-y)
-CFLAGS += $(cflags-y) \
+KBUILD_AFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y) \
-D"VMLINUX_LOAD_ADDRESS=$(load-y)"
LDFLAGS += -m $(ld-emul)
ifdef CONFIG_MIPS
-CHECKFLAGS += $(shell $(CC) $(CFLAGS) -dM -E -xc /dev/null | \
+CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \
egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
sed -e 's/^\#define /-D/' -e "s/ /='/" -e "s/$$/'/")
ifdef CONFIG_64BIT
@@ -632,7 +631,7 @@ OBJCOPYFLAGS += --remove-section=.reginfo
#
CPPFLAGS_vmlinux.lds := \
- $(CFLAGS) \
+ $(KBUILD_CFLAGS) \
-D"LOADADDR=$(load-y)" \
-D"JIFFIES=$(JIFFIES)" \
-D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)"
diff --git a/arch/mips/au1000/Kconfig b/arch/mips/au1000/Kconfig
index 29c95d97217..b36cec58a9a 100644
--- a/arch/mips/au1000/Kconfig
+++ b/arch/mips/au1000/Kconfig
@@ -137,6 +137,8 @@ config SOC_AU1200
config SOC_AU1X00
bool
select 64BIT_PHYS_ADDR
+ select CEVT_R4K
+ select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_APM_EMULATION
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c
index 7acfe9bf5fc..98a4e34b024 100644
--- a/arch/mips/au1000/common/au1xxx_irqmap.c
+++ b/arch/mips/au1000/common/au1xxx_irqmap.c
@@ -54,7 +54,7 @@
* Careful if you change match 2 request!
* The interrupt handler is called directly from the low level dispatch code.
*/
-au1xxx_irq_map_t __initdata au1xxx_ic0_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
#if defined(CONFIG_SOC_AU1000)
{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index 461cf013973..9d6ad43fded 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -859,7 +859,7 @@ dbdma_interrupt(int irq, void *dev_id)
intstat = dbdma_gptr->ddma_intstat;
au_sync();
- chan_index = au_ffs(intstat) - 1;
+ chan_index = ffs(intstat);
ctp = chan_tab_ptr[chan_index];
cp = ctp->chan_ptr;
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index a6640b998c6..59e932a928d 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -1,11 +1,10 @@
/*
- * BRIEF MODULE DESCRIPTION
- * Au1000 interrupt routines.
- *
* Copyright 2001 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
* ppopov@mvista.com or source@mvista.com
*
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.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
@@ -26,59 +25,123 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/errno.h>
+#include <linux/bitops.h>
#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/types.h>
+#include <linux/io.h>
#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
+#include <linux/irq.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
+#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
-#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_MIPS_PB1000
#include <asm/mach-pb1x00/pb1000.h>
#endif
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-/* note: prints function name for you */
-#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
#define EXT_INTC0_REQ0 2 /* IP 2 */
#define EXT_INTC0_REQ1 3 /* IP 3 */
#define EXT_INTC1_REQ0 4 /* IP 4 */
#define EXT_INTC1_REQ1 5 /* IP 5 */
#define MIPS_TIMER_IP 7 /* IP 7 */
-void (*board_init_irq)(void);
+void (*board_init_irq)(void) __initdata = NULL;
static DEFINE_SPINLOCK(irq_lock);
+#ifdef CONFIG_PM
+
+/*
+ * Save/restore the interrupt controller state.
+ * Called from the save/restore core registers as part of the
+ * au_sleep function in power.c.....maybe I should just pm_register()
+ * them instead?
+ */
+static unsigned int sleep_intctl_config0[2];
+static unsigned int sleep_intctl_config1[2];
+static unsigned int sleep_intctl_config2[2];
+static unsigned int sleep_intctl_src[2];
+static unsigned int sleep_intctl_assign[2];
+static unsigned int sleep_intctl_wake[2];
+static unsigned int sleep_intctl_mask[2];
+
+void save_au1xxx_intctl(void)
+{
+ sleep_intctl_config0[0] = au_readl(IC0_CFG0RD);
+ sleep_intctl_config1[0] = au_readl(IC0_CFG1RD);
+ sleep_intctl_config2[0] = au_readl(IC0_CFG2RD);
+ sleep_intctl_src[0] = au_readl(IC0_SRCRD);
+ sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD);
+ sleep_intctl_wake[0] = au_readl(IC0_WAKERD);
+ sleep_intctl_mask[0] = au_readl(IC0_MASKRD);
+
+ sleep_intctl_config0[1] = au_readl(IC1_CFG0RD);
+ sleep_intctl_config1[1] = au_readl(IC1_CFG1RD);
+ sleep_intctl_config2[1] = au_readl(IC1_CFG2RD);
+ sleep_intctl_src[1] = au_readl(IC1_SRCRD);
+ sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD);
+ sleep_intctl_wake[1] = au_readl(IC1_WAKERD);
+ sleep_intctl_mask[1] = au_readl(IC1_MASKRD);
+}
+
+/*
+ * For most restore operations, we clear the entire register and
+ * then set the bits we found during the save.
+ */
+void restore_au1xxx_intctl(void)
+{
+ au_writel(0xffffffff, IC0_MASKCLR); au_sync();
+
+ au_writel(0xffffffff, IC0_CFG0CLR); au_sync();
+ au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync();
+ au_writel(0xffffffff, IC0_CFG1CLR); au_sync();
+ au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync();
+ au_writel(0xffffffff, IC0_CFG2CLR); au_sync();
+ au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync();
+ au_writel(0xffffffff, IC0_SRCCLR); au_sync();
+ au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync();
+ au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync();
+ au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync();
+ au_writel(0xffffffff, IC0_WAKECLR); au_sync();
+ au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync();
+ au_writel(0xffffffff, IC0_RISINGCLR); au_sync();
+ au_writel(0xffffffff, IC0_FALLINGCLR); au_sync();
+ au_writel(0x00000000, IC0_TESTBIT); au_sync();
+
+ au_writel(0xffffffff, IC1_MASKCLR); au_sync();
+
+ au_writel(0xffffffff, IC1_CFG0CLR); au_sync();
+ au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync();
+ au_writel(0xffffffff, IC1_CFG1CLR); au_sync();
+ au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync();
+ au_writel(0xffffffff, IC1_CFG2CLR); au_sync();
+ au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync();
+ au_writel(0xffffffff, IC1_SRCCLR); au_sync();
+ au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync();
+ au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync();
+ au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync();
+ au_writel(0xffffffff, IC1_WAKECLR); au_sync();
+ au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync();
+ au_writel(0xffffffff, IC1_RISINGCLR); au_sync();
+ au_writel(0xffffffff, IC1_FALLINGCLR); au_sync();
+ au_writel(0x00000000, IC1_TESTBIT); au_sync();
+
+ au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync();
+
+ au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
+}
+#endif /* CONFIG_PM */
+
inline void local_enable_irq(unsigned int irq_nr)
{
- if (irq_nr > AU1000_LAST_INTC0_INT) {
- au_writel(1<<(irq_nr-32), IC1_MASKSET);
- au_writel(1<<(irq_nr-32), IC1_WAKESET);
- }
- else {
- au_writel(1<<irq_nr, IC0_MASKSET);
- au_writel(1<<irq_nr, IC0_WAKESET);
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ if (bit >= 32) {
+ au_writel(1 << (bit - 32), IC1_MASKSET);
+ au_writel(1 << (bit - 32), IC1_WAKESET);
+ } else {
+ au_writel(1 << bit, IC0_MASKSET);
+ au_writel(1 << bit, IC0_WAKESET);
}
au_sync();
}
@@ -86,13 +149,14 @@ inline void local_enable_irq(unsigned int irq_nr)
inline void local_disable_irq(unsigned int irq_nr)
{
- if (irq_nr > AU1000_LAST_INTC0_INT) {
- au_writel(1<<(irq_nr-32), IC1_MASKCLR);
- au_writel(1<<(irq_nr-32), IC1_WAKECLR);
- }
- else {
- au_writel(1<<irq_nr, IC0_MASKCLR);
- au_writel(1<<irq_nr, IC0_WAKECLR);
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ if (bit >= 32) {
+ au_writel(1 << (bit - 32), IC1_MASKCLR);
+ au_writel(1 << (bit - 32), IC1_WAKECLR);
+ } else {
+ au_writel(1 << bit, IC0_MASKCLR);
+ au_writel(1 << bit, IC0_WAKECLR);
}
au_sync();
}
@@ -100,13 +164,14 @@ inline void local_disable_irq(unsigned int irq_nr)
static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
{
- if (irq_nr > AU1000_LAST_INTC0_INT) {
- au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
- au_writel(1<<(irq_nr-32), IC1_MASKCLR);
- }
- else {
- au_writel(1<<irq_nr, IC0_RISINGCLR);
- au_writel(1<<irq_nr, IC0_MASKCLR);
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ if (bit >= 32) {
+ au_writel(1 << (bit - 32), IC1_RISINGCLR);
+ au_writel(1 << (bit - 32), IC1_MASKCLR);
+ } else {
+ au_writel(1 << bit, IC0_RISINGCLR);
+ au_writel(1 << bit, IC0_MASKCLR);
}
au_sync();
}
@@ -114,13 +179,14 @@ static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
{
- if (irq_nr > AU1000_LAST_INTC0_INT) {
- au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
- au_writel(1<<(irq_nr-32), IC1_MASKCLR);
- }
- else {
- au_writel(1<<irq_nr, IC0_FALLINGCLR);
- au_writel(1<<irq_nr, IC0_MASKCLR);
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ if (bit >= 32) {
+ au_writel(1 << (bit - 32), IC1_FALLINGCLR);
+ au_writel(1 << (bit - 32), IC1_MASKCLR);
+ } else {
+ au_writel(1 << bit, IC0_FALLINGCLR);
+ au_writel(1 << bit, IC0_MASKCLR);
}
au_sync();
}
@@ -128,18 +194,20 @@ static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
{
- /* This may assume that we don't get interrupts from
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ /*
+ * This may assume that we don't get interrupts from
* both edges at once, or if we do, that we don't care.
*/
- if (irq_nr > AU1000_LAST_INTC0_INT) {
- au_writel(1<<(irq_nr-32), IC1_FALLINGCLR);
- au_writel(1<<(irq_nr-32), IC1_RISINGCLR);
- au_writel(1<<(irq_nr-32), IC1_MASKCLR);
- }
- else {
- au_writel(1<<irq_nr, IC0_FALLINGCLR);
- au_writel(1<<irq_nr, IC0_RISINGCLR);
- au_writel(1<<irq_nr, IC0_MASKCLR);
+ if (bit >= 32) {
+ au_writel(1 << (bit - 32), IC1_FALLINGCLR);
+ au_writel(1 << (bit - 32), IC1_RISINGCLR);
+ au_writel(1 << (bit - 32), IC1_MASKCLR);
+ } else {
+ au_writel(1 << bit, IC0_FALLINGCLR);
+ au_writel(1 << bit, IC0_RISINGCLR);
+ au_writel(1 << bit, IC0_MASKCLR);
}
au_sync();
}
@@ -156,15 +224,13 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr)
au_sync();
}
#endif
- return;
}
-
static void end_irq(unsigned int irq_nr)
{
- if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
local_enable_irq(irq_nr);
- }
+
#if defined(CONFIG_MIPS_PB1000)
if (irq_nr == AU1000_GPIO_15) {
au_writel(0x4000, PB1000_MDR); /* enable int */
@@ -181,15 +247,12 @@ unsigned long save_local_and_disable(int controller)
spin_lock_irqsave(&irq_lock, flags);
if (controller) {
mask = au_readl(IC1_MASKSET);
- for (i=32; i<64; i++) {
+ for (i = 32; i < 64; i++)
local_disable_irq(i);
- }
- }
- else {
+ } else {
mask = au_readl(IC0_MASKSET);
- for (i=0; i<32; i++) {
+ for (i = 0; i < 32; i++)
local_disable_irq(i);
- }
}
spin_unlock_irqrestore(&irq_lock, flags);
@@ -202,10 +265,10 @@ void restore_local_and_enable(int controller, unsigned long mask)
unsigned long flags, new_mask;
spin_lock_irqsave(&irq_lock, flags);
- for (i=0; i<32; i++) {
- if (mask & (1<<i)) {
+ for (i = 0; i < 32; i++) {
+ if (mask & (1 << i)) {
if (controller)
- local_enable_irq(i+32);
+ local_enable_irq(i + 32);
else
local_enable_irq(i);
}
@@ -220,39 +283,39 @@ void restore_local_and_enable(int controller, unsigned long mask)
static struct irq_chip rise_edge_irq_type = {
- .name = "Au1000 Rise Edge",
- .ack = mask_and_ack_rise_edge_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_rise_edge_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
+ .name = "Au1000 Rise Edge",
+ .ack = mask_and_ack_rise_edge_irq,
+ .mask = local_disable_irq,
+ .mask_ack = mask_and_ack_rise_edge_irq,
+ .unmask = local_enable_irq,
+ .end = end_irq,
};
static struct irq_chip fall_edge_irq_type = {
- .name = "Au1000 Fall Edge",
- .ack = mask_and_ack_fall_edge_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_fall_edge_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
+ .name = "Au1000 Fall Edge",
+ .ack = mask_and_ack_fall_edge_irq,
+ .mask = local_disable_irq,
+ .mask_ack = mask_and_ack_fall_edge_irq,
+ .unmask = local_enable_irq,
+ .end = end_irq,
};
static struct irq_chip either_edge_irq_type = {
- .name = "Au1000 Rise or Fall Edge",
- .ack = mask_and_ack_either_edge_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_either_edge_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
+ .name = "Au1000 Rise or Fall Edge",
+ .ack = mask_and_ack_either_edge_irq,
+ .mask = local_disable_irq,
+ .mask_ack = mask_and_ack_either_edge_irq,
+ .unmask = local_enable_irq,
+ .end = end_irq,
};
static struct irq_chip level_irq_type = {
- .name = "Au1000 Level",
- .ack = mask_and_ack_level_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_level_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
+ .name = "Au1000 Level",
+ .ack = mask_and_ack_level_irq,
+ .mask = local_disable_irq,
+ .mask_ack = mask_and_ack_level_irq,
+ .unmask = local_enable_irq,
+ .end = end_irq,
};
#ifdef CONFIG_PM
@@ -263,7 +326,8 @@ void startup_match20_interrupt(irq_handler_t handler)
static struct irqaction action;
memset(&action, 0, sizeof(struct irqaction));
- /* This is a big problem.... since we didn't use request_irq
+ /*
+ * This is a big problem.... since we didn't use request_irq
* when kernel/irq.c calls probe_irq_xxx this interrupt will
* be probed for usage. This will end up disabling the device :(
* Give it a bogus "action" pointer -- this will keep it from
@@ -286,179 +350,122 @@ void startup_match20_interrupt(irq_handler_t handler)
}
#endif
-static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
+static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req)
{
- if (irq_nr > AU1000_MAX_INTR) return;
+ unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+
+ if (irq_nr > AU1000_MAX_INTR)
+ return;
+
/* Config2[n], Config1[n], Config0[n] */
- if (irq_nr > AU1000_LAST_INTC0_INT) {
+ if (bit >= 32) {
switch (type) {
- case INTC_INT_RISE_EDGE: /* 0:0:1 */
- au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG0SET);
- set_irq_chip(irq_nr, &rise_edge_irq_type);
- break;
- case INTC_INT_FALL_EDGE: /* 0:1:0 */
- au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG1SET);
- au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
- set_irq_chip(irq_nr, &fall_edge_irq_type);
- break;
- case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
- au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG1SET);
- au_writel(1<<(irq_nr-32), IC1_CFG0SET);
- set_irq_chip(irq_nr, &either_edge_irq_type);
- break;
- case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
- au_writel(1<<(irq_nr-32), IC1_CFG2SET);
- au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG0SET);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_LOW_LEVEL: /* 1:1:0 */
- au_writel(1<<(irq_nr-32), IC1_CFG2SET);
- au_writel(1<<(irq_nr-32), IC1_CFG1SET);
- au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_DISABLED: /* 0:0:0 */
- au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
- break;
- default: /* disable the interrupt */
- printk("unexpected int type %d (irq %d)\n", type, irq_nr);
- au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
- au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
- return;
+ case INTC_INT_RISE_EDGE: /* 0:0:1 */
+ au_writel(1 << (bit - 32), IC1_CFG2CLR);
+ au_writel(1 << (bit - 32), IC1_CFG1CLR);
+ au_writel(1 << (bit - 32), IC1_CFG0SET);
+ set_irq_chip(irq_nr, &rise_edge_irq_type);
+ break;
+ case INTC_INT_FALL_EDGE: /* 0:1:0 */
+ au_writel(1 << (bit - 32), IC1_CFG2CLR);
+ au_writel(1 << (bit - 32), IC1_CFG1SET);
+ au_writel(1 << (bit - 32), IC1_CFG0CLR);
+ set_irq_chip(irq_nr, &fall_edge_irq_type);
+ break;
+ case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
+ au_writel(1 << (bit - 32), IC1_CFG2CLR);
+ au_writel(1 << (bit - 32), IC1_CFG1SET);
+ au_writel(1 << (bit - 32), IC1_CFG0SET);
+ set_irq_chip(irq_nr, &either_edge_irq_type);
+ break;
+ case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+ au_writel(1 << (bit - 32), IC1_CFG2SET);
+ au_writel(1 << (bit - 32), IC1_CFG1CLR);
+ au_writel(1 << (bit - 32), IC1_CFG0SET);
+ set_irq_chip(irq_nr, &level_irq_type);
+ break;
+ case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+ au_writel(1 << (bit - 32), IC1_CFG2SET);
+ au_writel(1 << (bit - 32), IC1_CFG1SET);
+ au_writel(1 << (bit - 32), IC1_CFG0CLR);
+ set_irq_chip(irq_nr, &level_irq_type);
+ break;
+ case INTC_INT_DISABLED: /* 0:0:0 */
+ au_writel(1 << (bit - 32), IC1_CFG0CLR);
+ au_writel(1 << (bit - 32), IC1_CFG1CLR);
+ au_writel(1 << (bit - 32), IC1_CFG2CLR);
+ break;
+ default: /* disable the interrupt */
+ printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
+ type, irq_nr);
+ au_writel(1 << (bit - 32), IC1_CFG0CLR);
+ au_writel(1 << (bit - 32), IC1_CFG1CLR);
+ au_writel(1 << (bit - 32), IC1_CFG2CLR);
+ return;
}
if (int_req) /* assign to interrupt request 1 */
- au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
+ au_writel(1 << (bit - 32), IC1_ASSIGNCLR);
else /* assign to interrupt request 0 */
- au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
- au_writel(1<<(irq_nr-32), IC1_SRCSET);
- au_writel(1<<(irq_nr-32), IC1_MASKCLR);
- au_writel(1<<(irq_nr-32), IC1_WAKECLR);
- }
- else {
+ au_writel(1 << (bit - 32), IC1_ASSIGNSET);
+ au_writel(1 << (bit - 32), IC1_SRCSET);
+ au_writel(1 << (bit - 32), IC1_MASKCLR);
+ au_writel(1 << (bit - 32), IC1_WAKECLR);
+ } else {
switch (type) {
- case INTC_INT_RISE_EDGE: /* 0:0:1 */
- au_writel(1<<irq_nr, IC0_CFG2CLR);
- au_writel(1<<irq_nr, IC0_CFG1CLR);
- au_writel(1<<irq_nr, IC0_CFG0SET);
- set_irq_chip(irq_nr, &rise_edge_irq_type);
- break;
- case INTC_INT_FALL_EDGE: /* 0:1:0 */
- au_writel(1<<irq_nr, IC0_CFG2CLR);
- au_writel(1<<irq_nr, IC0_CFG1SET);
- au_writel(1<<irq_nr, IC0_CFG0CLR);
- set_irq_chip(irq_nr, &fall_edge_irq_type);
- break;
- case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
- au_writel(1<<irq_nr, IC0_CFG2CLR);
- au_writel(1<<irq_nr, IC0_CFG1SET);
- au_writel(1<<irq_nr, IC0_CFG0SET);
- set_irq_chip(irq_nr, &either_edge_irq_type);
- break;
- case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
- au_writel(1<<irq_nr, IC0_CFG2SET);
- au_writel(1<<irq_nr, IC0_CFG1CLR);
- au_writel(1<<irq_nr, IC0_CFG0SET);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_LOW_LEVEL: /* 1:1:0 */
- au_writel(1<<irq_nr, IC0_CFG2SET);
- au_writel(1<<irq_nr, IC0_CFG1SET);
- au_writel(1<<irq_nr, IC0_CFG0CLR);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_DISABLED: /* 0:0:0 */
- au_writel(1<<irq_nr, IC0_CFG0CLR);
- au_writel(1<<irq_nr, IC0_CFG1CLR);
- au_writel(1<<irq_nr, IC0_CFG2CLR);
- break;
- default: /* disable the interrupt */
- printk("unexpected int type %d (irq %d)\n", type, irq_nr);
- au_writel(1<<irq_nr, IC0_CFG0CLR);
- au_writel(1<<irq_nr, IC0_CFG1CLR);
- au_writel(1<<irq_nr, IC0_CFG2CLR);
- return;
+ case INTC_INT_RISE_EDGE: /* 0:0:1 */
+ au_writel(1 << bit, IC0_CFG2CLR);
+ au_writel(1 << bit, IC0_CFG1CLR);
+ au_writel(1 << bit, IC0_CFG0SET);
+ set_irq_chip(irq_nr, &rise_edge_irq_type);
+ break;
+ case INTC_INT_FALL_EDGE: /* 0:1:0 */
+ au_writel(1 << bit, IC0_CFG2CLR);
+ au_writel(1 << bit, IC0_CFG1SET);
+ au_writel(1 << bit, IC0_CFG0CLR);
+ set_irq_chip(irq_nr, &fall_edge_irq_type);
+ break;
+ case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
+ au_writel(1 << bit, IC0_CFG2CLR);
+ au_writel(1 << bit, IC0_CFG1SET);
+ au_writel(1 << bit, IC0_CFG0SET);
+ set_irq_chip(irq_nr, &either_edge_irq_type);
+ break;
+ case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+ au_writel(1 << bit, IC0_CFG2SET);
+ au_writel(1 << bit, IC0_CFG1CLR);
+ au_writel(1 << bit, IC0_CFG0SET);
+ set_irq_chip(irq_nr, &level_irq_type);
+ break;
+ case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+ au_writel(1 << bit, IC0_CFG2SET);
+ au_writel(1 << bit, IC0_CFG1SET);
+ au_writel(1 << bit, IC0_CFG0CLR);
+ set_irq_chip(irq_nr, &level_irq_type);
+ break;
+ case INTC_INT_DISABLED: /* 0:0:0 */
+ au_writel(1 << bit, IC0_CFG0CLR);
+ au_writel(1 << bit, IC0_CFG1CLR);
+ au_writel(1 << bit, IC0_CFG2CLR);
+ break;
+ default: /* disable the interrupt */
+ printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
+ type, irq_nr);
+ au_writel(1 << bit, IC0_CFG0CLR);
+ au_writel(1 << bit, IC0_CFG1CLR);
+ au_writel(1 << bit, IC0_CFG2CLR);
+ return;
}
if (int_req) /* assign to interrupt request 1 */
- au_writel(1<<irq_nr, IC0_ASSIGNCLR);
+ au_writel(1 << bit, IC0_ASSIGNCLR);
else /* assign to interrupt request 0 */
- au_writel(1<<irq_nr, IC0_ASSIGNSET);
- au_writel(1<<irq_nr, IC0_SRCSET);
- au_writel(1<<irq_nr, IC0_MASKCLR);
- au_writel(1<<irq_nr, IC0_WAKECLR);
+ au_writel(1 << bit, IC0_ASSIGNSET);
+ au_writel(1 << bit, IC0_SRCSET);
+ au_writel(1 << bit, IC0_MASKCLR);
+ au_writel(1 << bit, IC0_WAKECLR);
}
au_sync();
}
-
-void __init arch_init_irq(void)
-{
- int i;
- unsigned long cp0_status;
- au1xxx_irq_map_t *imp;
- extern au1xxx_irq_map_t au1xxx_irq_map[];
- extern au1xxx_irq_map_t au1xxx_ic0_map[];
- extern int au1xxx_nr_irqs;
- extern int au1xxx_ic0_nr_irqs;
-
- cp0_status = read_c0_status();
-
- /* Initialize interrupt controllers to a safe state.
- */
- au_writel(0xffffffff, IC0_CFG0CLR);
- au_writel(0xffffffff, IC0_CFG1CLR);
- au_writel(0xffffffff, IC0_CFG2CLR);
- au_writel(0xffffffff, IC0_MASKCLR);
- au_writel(0xffffffff, IC0_ASSIGNSET);
- au_writel(0xffffffff, IC0_WAKECLR);
- au_writel(0xffffffff, IC0_SRCSET);
- au_writel(0xffffffff, IC0_FALLINGCLR);
- au_writel(0xffffffff, IC0_RISINGCLR);
- au_writel(0x00000000, IC0_TESTBIT);
-
- au_writel(0xffffffff, IC1_CFG0CLR);
- au_writel(0xffffffff, IC1_CFG1CLR);
- au_writel(0xffffffff, IC1_CFG2CLR);
- au_writel(0xffffffff, IC1_MASKCLR);
- au_writel(0xffffffff, IC1_ASSIGNSET);
- au_writel(0xffffffff, IC1_WAKECLR);
- au_writel(0xffffffff, IC1_SRCSET);
- au_writel(0xffffffff, IC1_FALLINGCLR);
- au_writel(0xffffffff, IC1_RISINGCLR);
- au_writel(0x00000000, IC1_TESTBIT);
-
- /* Initialize IC0, which is fixed per processor.
- */
- imp = au1xxx_ic0_map;
- for (i=0; i<au1xxx_ic0_nr_irqs; i++) {
- setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
- imp++;
- }
-
- /* Now set up the irq mapping for the board.
- */
- imp = au1xxx_irq_map;
- for (i=0; i<au1xxx_nr_irqs; i++) {
- setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
- imp++;
- }
-
- set_c0_status(ALLINTS);
-
- /* Board specific IRQ initialization.
- */
- if (board_init_irq)
- (*board_init_irq)();
-}
-
-
/*
* Interrupts are nested. Even if an interrupt handler is registered
* as "fast", we might get another interrupt before we return from
@@ -467,44 +474,45 @@ void __init arch_init_irq(void)
static void intc0_req0_irqdispatch(void)
{
- int irq = 0;
- static unsigned long intc0_req0 = 0;
+ static unsigned long intc0_req0;
+ unsigned int bit;
intc0_req0 |= au_readl(IC0_REQ0INT);
if (!intc0_req0)
return;
+
#ifdef AU1000_USB_DEV_REQ_INT
/*
* Because of the tight timing of SETUP token to reply
* transactions, the USB devices-side packet complete
* interrupt needs the highest priority.
*/
- if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) {
- intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT);
+ if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) {
+ intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT);
do_IRQ(AU1000_USB_DEV_REQ_INT);
return;
}
#endif
- irq = au_ffs(intc0_req0) - 1;
- intc0_req0 &= ~(1<<irq);
- do_IRQ(irq);
+ bit = ffs(intc0_req0);
+ intc0_req0 &= ~(1 << bit);
+ do_IRQ(MIPS_CPU_IRQ_BASE + bit);
}
static void intc0_req1_irqdispatch(void)
{
- int irq = 0;
- static unsigned long intc0_req1 = 0;
+ static unsigned long intc0_req1;
+ unsigned int bit;
intc0_req1 |= au_readl(IC0_REQ1INT);
if (!intc0_req1)
return;
- irq = au_ffs(intc0_req1) - 1;
- intc0_req1 &= ~(1<<irq);
- do_IRQ(irq);
+ bit = ffs(intc0_req1);
+ intc0_req1 &= ~(1 << bit);
+ do_IRQ(bit);
}
@@ -514,126 +522,41 @@ static void intc0_req1_irqdispatch(void)
*/
static void intc1_req0_irqdispatch(void)
{
- int irq = 0;
- static unsigned long intc1_req0 = 0;
+ static unsigned long intc1_req0;
+ unsigned int bit;
intc1_req0 |= au_readl(IC1_REQ0INT);
if (!intc1_req0)
return;
- irq = au_ffs(intc1_req0) - 1;
- intc1_req0 &= ~(1<<irq);
- irq += 32;
- do_IRQ(irq);
+ bit = ffs(intc1_req0);
+ intc1_req0 &= ~(1 << bit);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 32 + bit);
}
static void intc1_req1_irqdispatch(void)
{
- int irq = 0;
- static unsigned long intc1_req1 = 0;
+ static unsigned long intc1_req1;
+ unsigned int bit;
intc1_req1 |= au_readl(IC1_REQ1INT);
if (!intc1_req1)
return;
- irq = au_ffs(intc1_req1) - 1;
- intc1_req1 &= ~(1<<irq);
- irq += 32;
- do_IRQ(irq);
-}
-
-#ifdef CONFIG_PM
-
-/* Save/restore the interrupt controller state.
- * Called from the save/restore core registers as part of the
- * au_sleep function in power.c.....maybe I should just pm_register()
- * them instead?
- */
-static unsigned int sleep_intctl_config0[2];
-static unsigned int sleep_intctl_config1[2];
-static unsigned int sleep_intctl_config2[2];
-static unsigned int sleep_intctl_src[2];
-static unsigned int sleep_intctl_assign[2];
-static unsigned int sleep_intctl_wake[2];
-static unsigned int sleep_intctl_mask[2];
-
-void
-save_au1xxx_intctl(void)
-{
- sleep_intctl_config0[0] = au_readl(IC0_CFG0RD);
- sleep_intctl_config1[0] = au_readl(IC0_CFG1RD);
- sleep_intctl_config2[0] = au_readl(IC0_CFG2RD);
- sleep_intctl_src[0] = au_readl(IC0_SRCRD);
- sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD);
- sleep_intctl_wake[0] = au_readl(IC0_WAKERD);
- sleep_intctl_mask[0] = au_readl(IC0_MASKRD);
-
- sleep_intctl_config0[1] = au_readl(IC1_CFG0RD);
- sleep_intctl_config1[1] = au_readl(IC1_CFG1RD);
- sleep_intctl_config2[1] = au_readl(IC1_CFG2RD);
- sleep_intctl_src[1] = au_readl(IC1_SRCRD);
- sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD);
- sleep_intctl_wake[1] = au_readl(IC1_WAKERD);
- sleep_intctl_mask[1] = au_readl(IC1_MASKRD);
+ bit = ffs(intc1_req1);
+ intc1_req1 &= ~(1 << bit);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 32 + bit);
}
-/* For most restore operations, we clear the entire register and
- * then set the bits we found during the save.
- */
-void
-restore_au1xxx_intctl(void)
-{
- au_writel(0xffffffff, IC0_MASKCLR); au_sync();
-
- au_writel(0xffffffff, IC0_CFG0CLR); au_sync();
- au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync();
- au_writel(0xffffffff, IC0_CFG1CLR); au_sync();
- au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync();
- au_writel(0xffffffff, IC0_CFG2CLR); au_sync();
- au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync();
- au_writel(0xffffffff, IC0_SRCCLR); au_sync();
- au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync();
- au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync();
- au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync();
- au_writel(0xffffffff, IC0_WAKECLR); au_sync();
- au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync();
- au_writel(0xffffffff, IC0_RISINGCLR); au_sync();
- au_writel(0xffffffff, IC0_FALLINGCLR); au_sync();
- au_writel(0x00000000, IC0_TESTBIT); au_sync();
-
- au_writel(0xffffffff, IC1_MASKCLR); au_sync();
-
- au_writel(0xffffffff, IC1_CFG0CLR); au_sync();
- au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync();
- au_writel(0xffffffff, IC1_CFG1CLR); au_sync();
- au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync();
- au_writel(0xffffffff, IC1_CFG2CLR); au_sync();
- au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync();
- au_writel(0xffffffff, IC1_SRCCLR); au_sync();
- au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync();
- au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync();
- au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync();
- au_writel(0xffffffff, IC1_WAKECLR); au_sync();
- au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync();
- au_writel(0xffffffff, IC1_RISINGCLR); au_sync();
- au_writel(0xffffffff, IC1_FALLINGCLR); au_sync();
- au_writel(0x00000000, IC1_TESTBIT); au_sync();
-
- au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync();
-
- au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
-}
-#endif /* CONFIG_PM */
-
asmlinkage void plat_irq_dispatch(void)
{
- unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+ unsigned int pending = read_c0_status() & read_c0_cause();
if (pending & CAUSEF_IP7)
- do_IRQ(63);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
else if (pending & CAUSEF_IP2)
intc0_req0_irqdispatch();
else if (pending & CAUSEF_IP3)
@@ -645,3 +568,65 @@ asmlinkage void plat_irq_dispatch(void)
else
spurious_interrupt();
}
+
+void __init arch_init_irq(void)
+{
+ int i;
+ struct au1xxx_irqmap *imp;
+ extern struct au1xxx_irqmap au1xxx_irq_map[];
+ extern struct au1xxx_irqmap au1xxx_ic0_map[];
+ extern int au1xxx_nr_irqs;
+ extern int au1xxx_ic0_nr_irqs;
+
+ /*
+ * Initialize interrupt controllers to a safe state.
+ */
+ au_writel(0xffffffff, IC0_CFG0CLR);
+ au_writel(0xffffffff, IC0_CFG1CLR);
+ au_writel(0xffffffff, IC0_CFG2CLR);
+ au_writel(0xffffffff, IC0_MASKCLR);
+ au_writel(0xffffffff, IC0_ASSIGNSET);
+ au_writel(0xffffffff, IC0_WAKECLR);
+ au_writel(0xffffffff, IC0_SRCSET);
+ au_writel(0xffffffff, IC0_FALLINGCLR);
+ au_writel(0xffffffff, IC0_RISINGCLR);
+ au_writel(0x00000000, IC0_TESTBIT);
+
+ au_writel(0xffffffff, IC1_CFG0CLR);
+ au_writel(0xffffffff, IC1_CFG1CLR);
+ au_writel(0xffffffff, IC1_CFG2CLR);
+ au_writel(0xffffffff, IC1_MASKCLR);
+ au_writel(0xffffffff, IC1_ASSIGNSET);
+ au_writel(0xffffffff, IC1_WAKECLR);
+ au_writel(0xffffffff, IC1_SRCSET);
+ au_writel(0xffffffff, IC1_FALLINGCLR);
+ au_writel(0xffffffff, IC1_RISINGCLR);
+ au_writel(0x00000000, IC1_TESTBIT);
+
+ mips_cpu_irq_init();
+
+ /*
+ * Initialize IC0, which is fixed per processor.
+ */
+ imp = au1xxx_ic0_map;
+ for (i = 0; i < au1xxx_ic0_nr_irqs; i++) {
+ setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
+ imp++;
+ }
+
+ /*
+ * Now set up the irq mapping for the board.
+ */
+ imp = au1xxx_irq_map;
+ for (i = 0; i < au1xxx_nr_irqs; i++) {
+ setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
+ imp++;
+ }
+
+ set_c0_status(ALLINTS);
+
+ /* Board specific IRQ initialization.
+ */
+ if (board_init_irq)
+ board_init_irq();
+}
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index 6f57f72a7d5..54047d69b82 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -403,9 +403,9 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
}
- /* We don't want _any_ interrupts other than
- * match20. Otherwise our au1000_calibrate_delay()
- * calculation will be off, potentially a lot.
+ /*
+ * We don't want _any_ interrupts other than match20. Otherwise our
+ * au1000_calibrate_delay() calculation will be off, potentially a lot.
*/
intc0_mask = save_local_and_disable(0);
intc1_mask = save_local_and_disable(1);
@@ -414,6 +414,7 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
au1000_calibrate_delay();
restore_local_and_enable(0, intc0_mask);
restore_local_and_enable(1, intc1_mask);
+
return retval;
}
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index a8637cdb5b4..90d70695aa6 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -33,7 +33,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -41,18 +40,16 @@
#include <asm/bootinfo.h>
-/* #define DEBUG_CMDLINE */
-
-extern int prom_argc;
-extern char **prom_argv, **prom_envp;
-
+int prom_argc;
+char **prom_argv;
+char **prom_envp;
char * __init_or_module prom_getcmdline(void)
{
return &(arcs_cmdline[0]);
}
-void prom_init_cmdline(void)
+void prom_init_cmdline(void)
{
char *cp;
int actr;
@@ -61,7 +58,7 @@ void prom_init_cmdline(void)
cp = &(arcs_cmdline[0]);
while(actr < prom_argc) {
- strcpy(cp, prom_argv[actr]);
+ strcpy(cp, prom_argv[actr]);
cp += strlen(prom_argv[actr]);
*cp++ = ' ';
actr++;
@@ -70,10 +67,8 @@ void prom_init_cmdline(void)
--cp;
if (prom_argc > 1)
*cp = '\0';
-
}
-
char *prom_getenv(char *envname)
{
/*
@@ -95,21 +90,23 @@ char *prom_getenv(char *envname)
}
env++;
}
+
return NULL;
}
-inline unsigned char str2hexnum(unsigned char c)
+static inline unsigned char str2hexnum(unsigned char c)
{
- if(c >= '0' && c <= '9')
+ if (c >= '0' && c <= '9')
return c - '0';
- if(c >= 'a' && c <= 'f')
+ if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
- if(c >= 'A' && c <= 'F')
+ if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
+
return 0; /* foo */
}
-inline void str2eaddr(unsigned char *ea, unsigned char *str)
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
{
int i;
@@ -124,35 +121,29 @@ inline void str2eaddr(unsigned char *ea, unsigned char *str)
}
}
-int get_ethernet_addr(char *ethernet_addr)
+int prom_get_ethernet_addr(char *ethernet_addr)
{
- char *ethaddr_str;
+ char *ethaddr_str;
+ char *argptr;
- ethaddr_str = prom_getenv("ethaddr");
+ /* Check the environment variables first */
+ ethaddr_str = prom_getenv("ethaddr");
if (!ethaddr_str) {
- printk("ethaddr not set in boot prom\n");
- return -1;
- }
- str2eaddr(ethernet_addr, ethaddr_str);
-
-#if 0
- {
- int i;
+ /* Check command line */
+ argptr = prom_getcmdline();
+ ethaddr_str = strstr(argptr, "ethaddr=");
+ if (!ethaddr_str)
+ return -1;
- printk("get_ethernet_addr: ");
- for (i=0; i<5; i++)
- printk("%02x:", (unsigned char)*(ethernet_addr+i));
- printk("%02x\n", *(ethernet_addr+i));
+ ethaddr_str += strlen("ethaddr=");
}
-#endif
+
+ str2eaddr(ethernet_addr, ethaddr_str);
return 0;
}
+EXPORT_SYMBOL(prom_get_ethernet_addr);
void __init prom_free_prom_memory(void)
{
}
-
-EXPORT_SYMBOL(prom_getcmdline);
-EXPORT_SYMBOL(get_ethernet_addr);
-EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index b212c072612..a90d425d465 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -40,10 +40,11 @@
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
-#include <asm/mach-au1x00/au1000.h>
#include <asm/time.h>
-extern char * prom_getcmdline(void);
+#include <au1000.h>
+#include <prom.h>
+
extern void __init board_setup(void);
extern void au1000_restart(char *);
extern void au1000_halt(void);
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index 4d7bcfc8cf7..43298fd9459 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/db1x00/irqmap.c b/arch/mips/au1000/db1x00/irqmap.c
index 3e5729145c2..09cea03411b 100644
--- a/arch/mips/au1000/db1x00/irqmap.c
+++ b/arch/mips/au1000/db1x00/irqmap.c
@@ -79,7 +79,7 @@ char irq_tab_alchemy[][5] __initdata = {
#endif
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
#ifndef CONFIG_MIPS_MIRAGE
#ifdef CONFIG_MIPS_DB1550
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index 2aa7b2ed6a8..cdeae3212a2 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -34,13 +34,11 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c
index a4fa0f227e4..49c612aeddc 100644
--- a/arch/mips/au1000/mtx-1/irqmap.c
+++ b/arch/mips/au1000/mtx-1/irqmap.c
@@ -58,7 +58,7 @@ char irq_tab_alchemy[][5] __initdata = {
[7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
};
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index 4535f7208e1..ddccaf6997d 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -30,15 +30,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/pb1000/irqmap.c b/arch/mips/au1000/pb1000/irqmap.c
index 156500ba467..88e35450820 100644
--- a/arch/mips/au1000/pb1000/irqmap.c
+++ b/arch/mips/au1000/pb1000/irqmap.c
@@ -47,7 +47,7 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 },
};
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
index 7ba6852de7c..c93fd39b4ab 100644
--- a/arch/mips/au1000/pb1100/init.c
+++ b/arch/mips/au1000/pb1100/init.c
@@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/pb1100/irqmap.c b/arch/mips/au1000/pb1100/irqmap.c
index d986916221b..880456bf8c1 100644
--- a/arch/mips/au1000/pb1100/irqmap.c
+++ b/arch/mips/au1000/pb1100/irqmap.c
@@ -47,7 +47,7 @@
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
index 2122515f79d..5dbc9868f59 100644
--- a/arch/mips/au1000/pb1200/board_setup.c
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -41,8 +41,10 @@
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#include <au1000.h>
+#include <au1xxx_dbdma.h>
+#include <prom.h>
#ifdef CONFIG_MIPS_PB1200
#include <asm/mach-pb1x00/pb1200.h>
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
index 5a70029d538..c251570749e 100644
--- a/arch/mips/au1000/pb1200/init.c
+++ b/arch/mips/au1000/pb1200/init.c
@@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
index 7c708db04a8..5f48b060379 100644
--- a/arch/mips/au1000/pb1200/irqmap.c
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -54,7 +54,7 @@
#define PB1200_INT_END DB1200_INT_END
#endif
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, // This is exteranl interrupt cascade
};
@@ -74,7 +74,7 @@ irqreturn_t pb1200_cascade_handler( int irq, void *dev_id)
bcsr->int_status = bisr;
for( ; bisr; bisr &= (bisr-1) )
{
- extirq_nr = (PB1200_INT_BEGIN-1) + au_ffs(bisr);
+ extirq_nr = PB1200_INT_BEGIN + ffs(bisr);
/* Ack and dispatch IRQ */
do_IRQ(extirq_nr);
}
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
index e58a9d6c502..507d4b20416 100644
--- a/arch/mips/au1000/pb1500/init.c
+++ b/arch/mips/au1000/pb1500/init.c
@@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/pb1500/irqmap.c b/arch/mips/au1000/pb1500/irqmap.c
index 409d1612bb6..810f695e24b 100644
--- a/arch/mips/au1000/pb1500/irqmap.c
+++ b/arch/mips/au1000/pb1500/irqmap.c
@@ -52,7 +52,7 @@ char irq_tab_alchemy[][5] __initdata = {
[13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
};
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
index fad53bf5aad..b03eee601e3 100644
--- a/arch/mips/au1000/pb1550/init.c
+++ b/arch/mips/au1000/pb1550/init.c
@@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/pb1550/irqmap.c b/arch/mips/au1000/pb1550/irqmap.c
index 24a9d186cf5..56becab28e5 100644
--- a/arch/mips/au1000/pb1550/irqmap.c
+++ b/arch/mips/au1000/pb1550/irqmap.c
@@ -52,7 +52,7 @@ char irq_tab_alchemy[][5] __initdata = {
[13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
};
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
};
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
index 9f839c36f69..6532939f377 100644
--- a/arch/mips/au1000/xxs1500/init.c
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -30,15 +30,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
const char *get_system_type(void)
{
diff --git a/arch/mips/au1000/xxs1500/irqmap.c b/arch/mips/au1000/xxs1500/irqmap.c
index 3844c6429e2..389349295d7 100644
--- a/arch/mips/au1000/xxs1500/irqmap.c
+++ b/arch/mips/au1000/xxs1500/irqmap.c
@@ -47,7 +47,7 @@
#include <asm/system.h>
#include <asm/au1000.h>
-au1xxx_irq_map_t __initdata au1xxx_irq_map[] = {
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 0280ef389d8..b536d7c6379 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -3021,7 +3021,7 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_CROSSCOMPILE is not set
+CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE=""
CONFIG_SYS_SUPPORTS_KGDB=y
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 835b056cea3..ae25b480723 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -4,7 +4,7 @@
* for more details.
*
* Copyright (C) 1992 Linus Torvalds
- * Copyright (C) 1994 - 2001, 2003 Ralf Baechle
+ * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle
*/
#include <linux/clockchips.h>
#include <linux/init.h>
@@ -13,6 +13,7 @@
#include <linux/spinlock.h>
#include <asm/irq_cpu.h>
+#include <asm/i8253.h>
#include <asm/i8259.h>
#include <asm/io.h>
#include <asm/jazz.h>
@@ -136,7 +137,7 @@ static struct irqaction r4030_timer_irqaction = {
.name = "timer",
};
-void __init plat_timer_setup(struct irqaction *ignored)
+void __init plat_time_init(void)
{
struct irqaction *irq = &r4030_timer_irqaction;
@@ -152,4 +153,5 @@ void __init plat_timer_setup(struct irqaction *ignored)
setup_irq(JAZZ_TIMER_IRQ, irq);
clockevents_register_device(&r4030_clockevent);
+ setup_pit_timer();
}
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index cfc7dce78da..a7857973ca0 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 2001, 07 by Ralf Baechle
* Copyright (C) 2001 MIPS Technologies, Inc.
* Copyright (C) 2007 by Thomas Bogendoerfer
*/
@@ -25,7 +25,6 @@
#include <linux/serial_8250.h>
#include <asm/bootinfo.h>
-#include <asm/i8253.h>
#include <asm/irq.h>
#include <asm/jazz.h>
#include <asm/jazzdma.h>
@@ -64,11 +63,6 @@ static struct resource jazz_io_resources[] = {
}
};
-void __init plat_time_init(void)
-{
- setup_pit_timer();
-}
-
void __init plat_mem_setup(void)
{
int i;
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 7f14f70a1b8..edb9e59248e 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -1,15 +1,4 @@
-/***********************************************************************
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ahennessy@mvista.com
- *
- * Based on arch/mips/ddb5xxx/ddb5477/setup.c
- *
- * Setup file for JMR3927.
- *
- * Copyright (C) 2000-2001 Toshiba Corporation
- *
+/*
* 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
@@ -30,9 +19,15 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
- ***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
*/
+#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
@@ -104,27 +99,60 @@ static cycle_t jmr3927_hpt_read(void)
return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
}
-static void jmr3927_timer_ack(void)
+static void jmr3927_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do here */
+}
+
+struct clock_event_device jmr3927_clock_event_device = {
+ .name = "MIPS",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 32,
+ .rating = 300,
+ .cpumask = CPU_MASK_CPU0,
+ .irq = JMR3927_IRQ_TICK,
+ .set_mode = jmr3927_set_mode,
+};
+
+static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id)
{
+ struct clock_event_device *cd = &jmr3927_clock_event_device;
+
jmr3927_tmrptr->tisr = 0; /* ack interrupt */
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
}
+static struct irqaction jmr3927_timer_irqaction = {
+ .handler = jmr3927_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "jmr3927-timer",
+};
+
void __init plat_time_init(void)
{
+ struct clock_event_device *cd;
+
clocksource_mips.read = jmr3927_hpt_read;
- mips_timer_ack = jmr3927_timer_ack;
mips_hpt_frequency = JMR3927_TIMER_CLK;
-}
-void __init plat_timer_setup(struct irqaction *irq)
-{
jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
jmr3927_tmrptr->tcr =
TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
- setup_irq(JMR3927_IRQ_TICK, irq);
+ cd = &jmr3927_clock_event_device;
+ /* Calculate the min / max delta */
+ cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ clockevents_register_device(cd);
+
+ setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction);
}
#define DO_WRITE_THROUGH
@@ -425,7 +453,7 @@ static int __init jmr3927_rtc_init(void)
.flags = IORESOURCE_MEM,
};
struct platform_device *dev;
- dev = platform_device_register_simple("ds1742", -1, &res, 1);
+ dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1);
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
device_initcall(jmr3927_rtc_init);
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index a2689f93c16..a3afa39faae 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -8,6 +8,8 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
time.o topology.o traps.o unaligned.o
+obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
+
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o
@@ -71,7 +73,7 @@ obj-$(CONFIG_PCSPEAKER) += pcspeaker.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
new file mode 100644
index 00000000000..08b84d476c8
--- /dev/null
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -0,0 +1,272 @@
+/*
+ * 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) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+
+#include <asm/time.h>
+
+static int mips_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned int cnt;
+ int res;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ {
+ unsigned long flags, vpflags;
+ local_irq_save(flags);
+ vpflags = dvpe();
+#endif
+ cnt = read_c0_count();
+ cnt += delta;
+ write_c0_compare(cnt);
+ res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
+#ifdef CONFIG_MIPS_MT_SMTC
+ evpe(vpflags);
+ local_irq_restore(flags);
+ }
+#endif
+ return res;
+}
+
+static void mips_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+static int cp0_timer_irq_installed;
+
+/*
+ * Timer ack for an R4k-compatible timer of a known frequency.
+ */
+static void c0_timer_ack(void)
+{
+ write_c0_compare(read_c0_compare());
+}
+
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+static inline int handle_perf_irq(int r2)
+{
+ /*
+ * The performance counter overflow interrupt may be shared with the
+ * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+ * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+ * and we can't reliably determine if a counter interrupt has also
+ * happened (!r2) then don't check for a timer interrupt.
+ */
+ return (cp0_perfcount_irq < 0) &&
+ perf_irq() == IRQ_HANDLED &&
+ !r2;
+}
+
+static irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+ const int r2 = cpu_has_mips_r2;
+ struct clock_event_device *cd;
+ int cpu = smp_processor_id();
+
+ /*
+ * Suckage alert:
+ * Before R2 of the architecture there was no way to see if a
+ * performance counter interrupt was pending, so we have to run
+ * the performance counter interrupt handler anyway.
+ */
+ if (handle_perf_irq(r2))
+ goto out;
+
+ /*
+ * The same applies to performance counter interrupts. But with the
+ * above we now know that the reason we got here must be a timer
+ * interrupt. Being the paranoiacs we are we check anyway.
+ */
+ if (!r2 || (read_c0_cause() & (1 << 30))) {
+ c0_timer_ack();
+#ifdef CONFIG_MIPS_MT_SMTC
+ if (cpu_data[cpu].vpe_id)
+ goto out;
+ cpu = 0;
+#endif
+ cd = &per_cpu(mips_clockevent_device, cpu);
+ cd->event_handler(cd);
+ }
+
+out:
+ return IRQ_HANDLED;
+}
+
+static struct irqaction c0_compare_irqaction = {
+ .handler = c0_compare_interrupt,
+#ifdef CONFIG_MIPS_MT_SMTC
+ .flags = IRQF_DISABLED,
+#else
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+#endif
+ .name = "timer",
+};
+
+#ifdef CONFIG_MIPS_MT_SMTC
+DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
+
+static void smtc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+
+static void mips_broadcast(cpumask_t mask)
+{
+ 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)
+{
+ //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
+
+static void mips_event_handler(struct clock_event_device *dev)
+{
+}
+
+/*
+ * FIXME: This doesn't hold for the relocated E9000 compare interrupt.
+ */
+static int c0_compare_int_pending(void)
+{
+ return (read_c0_cause() >> cp0_compare_irq) & 0x100;
+}
+
+static int c0_compare_int_usable(void)
+{
+ const unsigned int delta = 0x300000;
+ unsigned int cnt;
+
+ /*
+ * IP7 already pending? Try to clear it by acking the timer.
+ */
+ if (c0_compare_int_pending()) {
+ write_c0_compare(read_c0_compare());
+ irq_disable_hazard();
+ if (c0_compare_int_pending())
+ return 0;
+ }
+
+ cnt = read_c0_count();
+ cnt += delta;
+ write_c0_compare(cnt);
+
+ while ((long)(read_c0_count() - cnt) <= 0)
+ ; /* Wait for expiry */
+
+ if (!c0_compare_int_pending())
+ return 0;
+
+ write_c0_compare(read_c0_compare());
+ irq_disable_hazard();
+ if (c0_compare_int_pending())
+ return 0;
+
+ /*
+ * Feels like a real count / compare timer.
+ */
+ return 1;
+}
+
+void __cpuinit mips_clockevent_init(void)
+{
+ uint64_t mips_freq = mips_hpt_frequency;
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+ unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
+
+ if (!cpu_has_counter)
+ return;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ setup_smtc_dummy_clockevent_device();
+
+ /*
+ * On SMTC we only register VPE0's compare interrupt as clockevent
+ * device.
+ */
+ if (cpu)
+ return;
+#endif
+
+ if (!c0_compare_int_usable())
+ return;
+
+ cd = &per_cpu(mips_clockevent_device, cpu);
+
+ cd->name = "MIPS";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+
+ /* Calculate the min / max delta */
+ cd->mult = div_sc((unsigned long) mips_freq, 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->irq = irq;
+#ifdef CONFIG_MIPS_MT_SMTC
+ cd->cpumask = CPU_MASK_ALL;
+#else
+ cd->cpumask = cpumask_of_cpu(cpu);
+#endif
+ cd->set_next_event = mips_next_event;
+ cd->set_mode = mips_set_mode;
+ cd->event_handler = mips_event_handler;
+
+ clockevents_register_device(cd);
+
+ if (!cp0_timer_irq_installed) {
+#ifdef CONFIG_MIPS_MT_SMTC
+#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
+ setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
+#else
+ setup_irq(irq, &c0_compare_irqaction);
+#endif /* CONFIG_MIPS_MT_SMTC */
+ cp0_timer_irq_installed = 1;
+ }
+}
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index e46782b0ebc..23676873106 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -27,16 +27,6 @@
#include <kernel-entry-init.h>
- .macro ARC64_TWIDDLE_PC
-#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
- /* We get launched at a XKPHYS address but the kernel is linked to
- run at a KSEG0 address, so jump there. */
- PTR_LA t0, \@f
- jr t0
-\@:
-#endif
- .endm
-
/*
* inputs are the text nasid in t1, data nasid in t2.
*/
@@ -140,7 +130,7 @@
EXPORT(_stext)
-#ifndef CONFIG_BOOT_RAW
+#ifdef CONFIG_BOOT_RAW
/*
* Give us a fighting chance of running if execution beings at the
* kernel load address. This is needed because this platform does
@@ -149,13 +139,19 @@ EXPORT(_stext)
__INIT
#endif
+ __INIT_REFOK
+
NESTED(kernel_entry, 16, sp) # kernel entry point
kernel_entry_setup # cpu specific setup
setup_c0_status_pri
- ARC64_TWIDDLE_PC
+ /* We might not get launched at the address the kernel is linked to,
+ so we jump there. */
+ PTR_LA t0, 0f
+ jr t0
+0:
#ifdef CONFIG_MIPS_MT_SMTC
/*
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 8ef5cf4cc42..b997af713eb 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -44,11 +44,14 @@
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_irix_library(struct file *);
static int irix_core_dump(long signr, struct pt_regs * regs,
- struct file *file);
+ struct file *file, unsigned long limit);
static struct linux_binfmt irix_format = {
- NULL, THIS_MODULE, load_irix_binary, load_irix_library,
- irix_core_dump, PAGE_SIZE
+ .module = THIS_MODULE,
+ .load_binary = load_irix_binary,
+ .load_shlib = load_irix_library,
+ .core_dump = irix_core_dump,
+ .min_coredump = PAGE_SIZE,
};
/* Debugging routines. */
@@ -1088,7 +1091,7 @@ end_coredump:
* and then they are actually written out. If we run out of core limit
* we just truncate.
*/
-static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
+static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
int has_dumped = 0;
mm_segment_t fs;
@@ -1098,7 +1101,6 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
struct vm_area_struct *vma;
struct elfhdr elf;
off_t offset = 0, dataoff;
- int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
int numnote = 3;
struct memelfnote notes[3];
struct elf_prstatus prstatus; /* NT_PRSTATUS */
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index d6e01215fb2..2b8ec1102e8 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -35,12 +35,12 @@
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/vfs.h>
+#include <linux/ipc.h>
#include <net/sock.h>
#include <net/scm.h>
#include <asm/compat-signal.h>
-#include <asm/ipc.h>
#include <asm/sim.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 58aa6fec114..999f7853de2 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -435,10 +435,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
wake_up_process(child);
break;
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value,
(unsigned long __user *) data);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 17c4374d220..b95fe93dd64 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -28,11 +28,11 @@
#include <linux/shm.h>
#include <linux/compiler.h>
#include <linux/module.h>
+#include <linux/ipc.h>
#include <asm/branch.h>
#include <asm/cachectl.h>
#include <asm/cacheflush.h>
-#include <asm/ipc.h>
#include <asm/asm-offsets.h>
#include <asm/signal.h>
#include <asm/sim.h>
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 5892491b40e..ea7cfe766a8 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -72,14 +72,6 @@ int update_persistent_clock(struct timespec now)
return rtc_mips_set_mmss(now.tv_sec);
}
-/* how many counter cycles in a jiffy */
-static unsigned long cycles_per_jiffy __read_mostly;
-
-/*
- * Null timer ack for systems not needing one (e.g. i8254).
- */
-static void null_timer_ack(void) { /* nothing */ }
-
/*
* Null high precision timer functions for systems lacking one.
*/
@@ -89,14 +81,6 @@ static cycle_t null_hpt_read(void)
}
/*
- * Timer ack for an R4k-compatible timer of a known frequency.
- */
-static void c0_timer_ack(void)
-{
- write_c0_compare(read_c0_compare());
-}
-
-/*
* High precision timer functions for a R4k-compatible timer.
*/
static cycle_t c0_hpt_read(void)
@@ -105,7 +89,6 @@ static cycle_t c0_hpt_read(void)
}
int (*mips_timer_state)(void);
-void (*mips_timer_ack)(void);
/*
* local_timer_interrupt() does profiling and process accounting
@@ -135,35 +118,6 @@ int (*perf_irq)(void) = null_perf_irq;
EXPORT_SYMBOL(perf_irq);
/*
- * Timer interrupt
- */
-int cp0_compare_irq;
-
-/*
- * Performance counter IRQ or -1 if shared with timer
- */
-int cp0_perfcount_irq;
-EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
-
-/*
- * Possibly handle a performance counter interrupt.
- * Return true if the timer interrupt should not be checked
- */
-static inline int handle_perf_irq(int r2)
-{
- /*
- * The performance counter overflow interrupt may be shared with the
- * timer interrupt (cp0_perfcount_irq < 0). If it is and a
- * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
- * and we can't reliably determine if a counter interrupt has also
- * happened (!r2) then don't check for a timer interrupt.
- */
- return (cp0_perfcount_irq < 0) &&
- perf_irq() == IRQ_HANDLED &&
- !r2;
-}
-
-/*
* time_init() - it does the following things.
*
* 1) plat_time_init() -
@@ -228,84 +182,6 @@ struct clocksource clocksource_mips = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static int mips_next_event(unsigned long delta,
- struct clock_event_device *evt)
-{
- unsigned int cnt;
- int res;
-
-#ifdef CONFIG_MIPS_MT_SMTC
- {
- unsigned long flags, vpflags;
- local_irq_save(flags);
- vpflags = dvpe();
-#endif
- cnt = read_c0_count();
- cnt += delta;
- write_c0_compare(cnt);
- res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
-#ifdef CONFIG_MIPS_MT_SMTC
- evpe(vpflags);
- local_irq_restore(flags);
- }
-#endif
- return res;
-}
-
-static void mips_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- /* Nothing to do ... */
-}
-
-static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
-static int cp0_timer_irq_installed;
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
- const int r2 = cpu_has_mips_r2;
- struct clock_event_device *cd;
- int cpu = smp_processor_id();
-
- /*
- * Suckage alert:
- * Before R2 of the architecture there was no way to see if a
- * performance counter interrupt was pending, so we have to run
- * the performance counter interrupt handler anyway.
- */
- if (handle_perf_irq(r2))
- goto out;
-
- /*
- * The same applies to performance counter interrupts. But with the
- * above we now know that the reason we got here must be a timer
- * interrupt. Being the paranoiacs we are we check anyway.
- */
- if (!r2 || (read_c0_cause() & (1 << 30))) {
- c0_timer_ack();
-#ifdef CONFIG_MIPS_MT_SMTC
- if (cpu_data[cpu].vpe_id)
- goto out;
- cpu = 0;
-#endif
- cd = &per_cpu(mips_clockevent_device, cpu);
- cd->event_handler(cd);
- }
-
-out:
- return IRQ_HANDLED;
-}
-
-static struct irqaction timer_irqaction = {
- .handler = timer_interrupt,
-#ifdef CONFIG_MIPS_MT_SMTC
- .flags = IRQF_DISABLED,
-#else
- .flags = IRQF_DISABLED | IRQF_PERCPU,
-#endif
- .name = "timer",
-};
-
static void __init init_mips_clocksource(void)
{
u64 temp;
@@ -345,8 +221,6 @@ static void smtc_set_mode(enum clock_event_mode mode,
{
}
-int dummycnt[NR_CPUS];
-
static void mips_broadcast(cpumask_t mask)
{
unsigned int cpu;
@@ -387,66 +261,6 @@ static void setup_smtc_dummy_clockevent_device(void)
}
#endif
-static void mips_event_handler(struct clock_event_device *dev)
-{
-}
-
-void __cpuinit mips_clockevent_init(void)
-{
- uint64_t mips_freq = mips_hpt_frequency;
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *cd;
- unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
-
- if (!cpu_has_counter)
- return;
-
-#ifdef CONFIG_MIPS_MT_SMTC
- setup_smtc_dummy_clockevent_device();
-
- /*
- * On SMTC we only register VPE0's compare interrupt as clockevent
- * device.
- */
- if (cpu)
- return;
-#endif
-
- cd = &per_cpu(mips_clockevent_device, cpu);
-
- cd->name = "MIPS";
- cd->features = CLOCK_EVT_FEAT_ONESHOT;
-
- /* Calculate the min / max delta */
- cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
- cd->shift = 32;
- cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
- cd->min_delta_ns = clockevent_delta2ns(0x30, cd);
-
- cd->rating = 300;
- cd->irq = irq;
-#ifdef CONFIG_MIPS_MT_SMTC
- cd->cpumask = CPU_MASK_ALL;
-#else
- cd->cpumask = cpumask_of_cpu(cpu);
-#endif
- cd->set_next_event = mips_next_event;
- cd->set_mode = mips_set_mode;
- cd->event_handler = mips_event_handler;
-
- clockevents_register_device(cd);
-
- if (!cp0_timer_irq_installed) {
-#ifdef CONFIG_MIPS_MT_SMTC
-#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
- setup_irq_smtc(irq, &timer_irqaction, CPUCTR_IMASKBIT);
-#else
- setup_irq(irq, &timer_irqaction);
-#endif /* CONFIG_MIPS_MT_SMTC */
- cp0_timer_irq_installed = 1;
- }
-}
-
void __init time_init(void)
{
plat_time_init();
@@ -465,14 +279,6 @@ void __init time_init(void)
if (!clocksource_mips.read) {
/* No external high precision timer -- use R4k. */
clocksource_mips.read = c0_hpt_read;
-
- if (!mips_timer_state) {
- /* No external timer interrupt -- use R4k. */
- mips_timer_ack = c0_timer_ack;
- /* Calculate cache parameters. */
- cycles_per_jiffy =
- (mips_hpt_frequency + HZ / 2) / HZ;
- }
}
if (!mips_hpt_frequency)
mips_hpt_frequency = calibrate_hpt();
@@ -481,29 +287,8 @@ void __init time_init(void)
printk("Using %u.%03u MHz high precision timer.\n",
((mips_hpt_frequency + 500) / 1000) / 1000,
((mips_hpt_frequency + 500) / 1000) % 1000);
-
-#ifdef CONFIG_IRQ_CPU
- setup_irq(MIPS_CPU_IRQ_BASE + 7, &timer_irqaction);
-#endif
}
- if (!mips_timer_ack)
- /* No timer interrupt ack (e.g. i8254). */
- mips_timer_ack = null_timer_ack;
-
- /*
- * Call board specific timer interrupt setup.
- *
- * this pointer must be setup in machine setup routine.
- *
- * Even if a machine chooses to use a low-level timer interrupt,
- * it still needs to setup the timer_irqaction.
- * In that case, it might be better to set timer_irqaction.handler
- * to be NULL function so that we are sure the high-level code
- * is not invoked accidentally.
- */
- plat_timer_setup(&timer_irqaction);
-
init_mips_clocksource();
mips_clockevent_init();
}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 632bce1bf42..7b78d137259 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -9,9 +9,10 @@
* Copyright (C) 1999 Silicon Graphics, Inc.
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000, 01 MIPS Technologies, Inc.
- * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki
*/
#include <linux/bug.h>
+#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -104,7 +105,7 @@ static int __init set_raw_show_trace(char *str)
__setup("raw_show_trace", set_raw_show_trace);
#endif
-static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
+static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)
{
unsigned long sp = regs->regs[29];
unsigned long ra = regs->regs[31];
@@ -126,7 +127,8 @@ static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
* This routine abuses get_user()/put_user() to reference pointers
* with at least a bit of error checking ...
*/
-static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
+static void show_stacktrace(struct task_struct *task,
+ const struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
long stackdata;
@@ -203,7 +205,7 @@ static void show_code(unsigned int __user *pc)
}
}
-void show_regs(struct pt_regs *regs)
+static void __show_regs(const struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
unsigned int cause = regs->cp0_cause;
@@ -299,9 +301,17 @@ void show_regs(struct pt_regs *regs)
cpu_name_string());
}
-void show_registers(struct pt_regs *regs)
+/*
+ * FIXME: really the generic show_regs should take a const pointer argument.
+ */
+void show_regs(struct pt_regs *regs)
{
- show_regs(regs);
+ __show_regs((struct pt_regs *)regs);
+}
+
+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);
@@ -312,7 +322,7 @@ void show_registers(struct pt_regs *regs)
static DEFINE_SPINLOCK(die_lock);
-void __noreturn die(const char * str, struct pt_regs * regs)
+void __noreturn die(const char * str, const struct pt_regs * regs)
{
static int die_counter;
#ifdef CONFIG_MIPS_MT_SMTC
@@ -401,7 +411,7 @@ asmlinkage void do_be(struct pt_regs *regs)
}
/*
- * ll/sc emulation
+ * ll/sc, rdhwr, sync emulation
*/
#define OPCODE 0xfc000000
@@ -410,9 +420,11 @@ asmlinkage void do_be(struct pt_regs *regs)
#define OFFSET 0x0000ffff
#define LL 0xc0000000
#define SC 0xe0000000
+#define SPEC0 0x00000000
#define SPEC3 0x7c000000
#define RD 0x0000f800
#define FUNC 0x0000003f
+#define SYNC 0x0000000f
#define RDHWR 0x0000003b
/*
@@ -423,11 +435,10 @@ unsigned long ll_bit;
static struct task_struct *ll_task = NULL;
-static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
+static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode)
{
unsigned long value, __user *vaddr;
long offset;
- int signal = 0;
/*
* analyse the ll instruction that just caused a ri exception
@@ -442,14 +453,10 @@ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
vaddr = (unsigned long __user *)
((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
- if ((unsigned long)vaddr & 3) {
- signal = SIGBUS;
- goto sig;
- }
- if (get_user(value, vaddr)) {
- signal = SIGSEGV;
- goto sig;
- }
+ if ((unsigned long)vaddr & 3)
+ return SIGBUS;
+ if (get_user(value, vaddr))
+ return SIGSEGV;
preempt_disable();
@@ -462,22 +469,16 @@ static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode)
preempt_enable();
- compute_return_epc(regs);
-
regs->regs[(opcode & RT) >> 16] = value;
- return;
-
-sig:
- force_sig(signal, current);
+ return 0;
}
-static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
+static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode)
{
unsigned long __user *vaddr;
unsigned long reg;
long offset;
- int signal = 0;
/*
* analyse the sc instruction that just caused a ri exception
@@ -493,34 +494,25 @@ static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode)
((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
reg = (opcode & RT) >> 16;
- if ((unsigned long)vaddr & 3) {
- signal = SIGBUS;
- goto sig;
- }
+ if ((unsigned long)vaddr & 3)
+ return SIGBUS;
preempt_disable();
if (ll_bit == 0 || ll_task != current) {
- compute_return_epc(regs);
regs->regs[reg] = 0;
preempt_enable();
- return;
+ return 0;
}
preempt_enable();
- if (put_user(regs->regs[reg], vaddr)) {
- signal = SIGSEGV;
- goto sig;
- }
+ if (put_user(regs->regs[reg], vaddr))
+ return SIGSEGV;
- compute_return_epc(regs);
regs->regs[reg] = 1;
- return;
-
-sig:
- force_sig(signal, current);
+ return 0;
}
/*
@@ -530,27 +522,14 @@ sig:
* few processors such as NEC's VR4100 throw reserved instruction exceptions
* instead, so we're doing the emulation thing in both exception handlers.
*/
-static inline int simulate_llsc(struct pt_regs *regs)
+static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
{
- unsigned int opcode;
-
- if (get_user(opcode, (unsigned int __user *) exception_epc(regs)))
- goto out_sigsegv;
-
- if ((opcode & OPCODE) == LL) {
- simulate_ll(regs, opcode);
- return 0;
- }
- if ((opcode & OPCODE) == SC) {
- simulate_sc(regs, opcode);
- return 0;
- }
+ if ((opcode & OPCODE) == LL)
+ return simulate_ll(regs, opcode);
+ if ((opcode & OPCODE) == SC)
+ return simulate_sc(regs, opcode);
- return -EFAULT; /* Strange things going on ... */
-
-out_sigsegv:
- force_sig(SIGSEGV, current);
- return -EFAULT;
+ return -1; /* Must be something else ... */
}
/*
@@ -558,16 +537,9 @@ out_sigsegv:
* registers not implemented in hardware. The only current use of this
* is the thread area pointer.
*/
-static inline int simulate_rdhwr(struct pt_regs *regs)
+static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
{
struct thread_info *ti = task_thread_info(current);
- unsigned int opcode;
-
- if (get_user(opcode, (unsigned int __user *) exception_epc(regs)))
- goto out_sigsegv;
-
- if (unlikely(compute_return_epc(regs)))
- return -EFAULT;
if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
int rd = (opcode & RD) >> 11;
@@ -577,16 +549,20 @@ static inline int simulate_rdhwr(struct pt_regs *regs)
regs->regs[rt] = ti->tp_value;
return 0;
default:
- return -EFAULT;
+ return -1;
}
}
/* Not ours. */
- return -EFAULT;
+ return -1;
+}
-out_sigsegv:
- force_sig(SIGSEGV, current);
- return -EFAULT;
+static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
+{
+ if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC)
+ return 0;
+
+ return -1; /* Must be something else ... */
}
asmlinkage void do_ov(struct pt_regs *regs)
@@ -758,16 +734,35 @@ out_sigsegv:
asmlinkage void do_ri(struct pt_regs *regs)
{
- die_if_kernel("Reserved instruction in kernel code", regs);
+ unsigned int __user *epc = (unsigned int __user *)exception_epc(regs);
+ unsigned long old_epc = regs->cp0_epc;
+ unsigned int opcode = 0;
+ int status = -1;
- if (!cpu_has_llsc)
- if (!simulate_llsc(regs))
- return;
+ die_if_kernel("Reserved instruction in kernel code", regs);
- if (!simulate_rdhwr(regs))
+ if (unlikely(compute_return_epc(regs) < 0))
return;
- force_sig(SIGILL, current);
+ if (unlikely(get_user(opcode, epc) < 0))
+ status = SIGSEGV;
+
+ if (!cpu_has_llsc && status < 0)
+ status = simulate_llsc(regs, opcode);
+
+ if (status < 0)
+ status = simulate_rdhwr(regs, opcode);
+
+ if (status < 0)
+ status = simulate_sync(regs, opcode);
+
+ if (status < 0)
+ status = SIGILL;
+
+ if (unlikely(status > 0)) {
+ regs->cp0_epc = old_epc; /* Undo skip-over. */
+ force_sig(status, current);
+ }
}
/*
@@ -799,7 +794,11 @@ static void mt_ase_fp_affinity(void)
asmlinkage void do_cpu(struct pt_regs *regs)
{
+ unsigned int __user *epc;
+ unsigned long old_epc;
+ unsigned int opcode;
unsigned int cpid;
+ int status;
die_if_kernel("do_cpu invoked from kernel context!", regs);
@@ -807,14 +806,32 @@ asmlinkage void do_cpu(struct pt_regs *regs)
switch (cpid) {
case 0:
- if (!cpu_has_llsc)
- if (!simulate_llsc(regs))
- return;
+ epc = (unsigned int __user *)exception_epc(regs);
+ old_epc = regs->cp0_epc;
+ opcode = 0;
+ status = -1;
- if (!simulate_rdhwr(regs))
+ if (unlikely(compute_return_epc(regs) < 0))
return;
- break;
+ if (unlikely(get_user(opcode, epc) < 0))
+ status = SIGSEGV;
+
+ if (!cpu_has_llsc && status < 0)
+ status = simulate_llsc(regs, opcode);
+
+ if (status < 0)
+ status = simulate_rdhwr(regs, opcode);
+
+ if (status < 0)
+ status = SIGILL;
+
+ if (unlikely(status > 0)) {
+ regs->cp0_epc = old_epc; /* Undo skip-over. */
+ force_sig(status, current);
+ }
+
+ return;
case 1:
if (used_math()) /* Using the FPU again. */
@@ -1319,6 +1336,17 @@ extern void cpu_cache_init(void);
extern void tlb_init(void);
extern void flush_tlb_handlers(void);
+/*
+ * Timer interrupt
+ */
+int cp0_compare_irq;
+
+/*
+ * Performance counter IRQ or -1 if shared with timer
+ */
+int cp0_perfcount_irq;
+EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
+
void __init per_cpu_trap_init(void)
{
unsigned int cpu = smp_processor_id();
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 84f9a4cc6f2..2781cff1485 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -5,6 +5,10 @@
#define mips mips
OUTPUT_ARCH(mips)
ENTRY(kernel_entry)
+PHDRS {
+ text PT_LOAD FLAGS(7); /* RWX */
+ note PT_NOTE FLAGS(4); /* R__ */
+}
jiffies = JIFFIES;
SECTIONS
@@ -22,7 +26,6 @@ SECTIONS
*/
/* . = 0xa800000000300000; */
- /* . = 0xa800000000300000; */
. = 0xffffffff80300000;
#endif
. = LOADADDR;
@@ -32,9 +35,10 @@ SECTIONS
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
+ KPROBES_TEXT
*(.fixup)
*(.gnu.warning)
- } =0
+ } :text = 0
_etext = .; /* End of text section */
/* Exception table */
@@ -51,6 +55,10 @@ SECTIONS
*(__dbe_table)
__stop___dbe_table = .;
}
+
+ NOTES :text :note
+ .dummy : { *(.dummy) } :text
+
RODATA
/* writeable */
@@ -201,7 +209,4 @@ SECTIONS
*(.gptab.bss)
*(.gptab.sbss)
}
- .note : {
- *(.note)
- }
}
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 61b729fa054..df8cbe4c7c0 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1317,7 +1317,8 @@ static void kspd_sp_exit( int sp_id)
}
#endif
-static ssize_t store_kill(struct class_device *dev, const char *buf, size_t len)
+static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct vpe *vpe = get_vpe(tclimit);
struct vpe_notifications *not;
@@ -1334,14 +1335,16 @@ static ssize_t store_kill(struct class_device *dev, const char *buf, size_t len)
return len;
}
-static ssize_t show_ntcs(struct class_device *cd, char *buf)
+static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr,
+ char *buf)
{
struct vpe *vpe = get_vpe(tclimit);
return sprintf(buf, "%d\n", vpe->ntcs);
}
-static ssize_t store_ntcs(struct class_device *dev, const char *buf, size_t len)
+static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
{
struct vpe *vpe = get_vpe(tclimit);
unsigned long new;
@@ -1362,13 +1365,13 @@ out_einval:
return -EINVAL;;
}
-static struct class_device_attribute vpe_class_attributes[] = {
+static struct device_attribute vpe_class_attributes[] = {
__ATTR(kill, S_IWUSR, NULL, store_kill),
__ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs),
{}
};
-static void vpe_class_device_release(struct class_device *cd)
+static void vpe_device_release(struct device *cd)
{
kfree(cd);
}
@@ -1376,11 +1379,11 @@ static void vpe_class_device_release(struct class_device *cd)
struct class vpe_class = {
.name = "vpe",
.owner = THIS_MODULE,
- .release = vpe_class_device_release,
- .class_dev_attrs = vpe_class_attributes,
+ .dev_release = vpe_device_release,
+ .dev_attrs = vpe_class_attributes,
};
-struct class_device vpe_device;
+struct device vpe_device;
static int __init vpe_module_init(void)
{
@@ -1423,12 +1426,12 @@ static int __init vpe_module_init(void)
goto out_chrdev;
}
- class_device_initialize(&vpe_device);
+ device_initialize(&vpe_device);
vpe_device.class = &vpe_class,
vpe_device.parent = NULL,
- strlcpy(vpe_device.class_id, "vpe1", BUS_ID_SIZE);
+ strlcpy(vpe_device.bus_id, "vpe1", BUS_ID_SIZE);
vpe_device.devt = MKDEV(major, minor);
- err = class_device_add(&vpe_device);
+ err = device_add(&vpe_device);
if (err) {
printk(KERN_ERR "Adding vpe_device failed\n");
goto out_class;
@@ -1573,7 +1576,7 @@ static void __exit vpe_module_exit(void)
}
}
- class_device_del(&vpe_device);
+ device_del(&vpe_device);
unregister_chrdev(major, module_name);
}
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index 5f35289bfff..ba9692be356 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -26,6 +26,7 @@
#include <linux/kernel_stat.h>
#include <asm/bootinfo.h>
+#include <asm/irq_cpu.h>
#include <asm/lasat/lasatint.h>
#include <asm/time.h>
#include <asm/gdb-stub.h>
@@ -88,7 +89,7 @@ asmlinkage void plat_irq_dispatch(void)
int irq;
if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */
- ll_timer_interrupt(7);
+ do_IRQ(7);
return;
}
@@ -96,7 +97,7 @@ asmlinkage void plat_irq_dispatch(void)
/* if int_status == 0, then the interrupt has already been cleared */
if (int_status) {
- irq = ls1bit32(int_status);
+ irq = LASATINT_BASE + ls1bit32(int_status);
do_IRQ(irq);
}
@@ -125,6 +126,7 @@ void __init arch_init_irq(void)
panic("arch_init_irq: mips_machtype incorrect");
}
- for (i = 0; i <= LASATINT_END; i++)
+ mips_cpu_irq_init();
+ for (i = LASATINT_BASE; i <= LASATINT_END; i++)
set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
}
diff --git a/arch/mips/mipssim/sim_cmdline.c b/arch/mips/mipssim/sim_cmdline.c
index c63021a5dc6..74240e1ce5a 100644
--- a/arch/mips/mipssim/sim_cmdline.c
+++ b/arch/mips/mipssim/sim_cmdline.c
@@ -28,8 +28,5 @@ char * __init prom_getcmdline(void)
void __init prom_init_cmdline(void)
{
- char *cp;
- cp = arcs_cmdline;
- /* Get boot line from environment? */
- *cp = '\0';
+ /* XXX: Get boot line from environment? */
}
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 971f6c047b8..d7088331fb0 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -983,11 +983,15 @@ static void __init probe_pcache(void)
printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
icache_size >> 10,
- cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
+ cpu_has_vtag_icache ? "VIVT" : "VIPT",
way_string[c->icache.ways], c->icache.linesz);
- printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
- dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz);
+ printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n",
+ dcache_size >> 10, way_string[c->dcache.ways],
+ (c->dcache.flags & MIPS_CACHE_PINDEX) ? "PIPT" : "VIPT",
+ (c->dcache.flags & MIPS_CACHE_ALIASES) ?
+ "cache aliases" : "no aliases",
+ c->dcache.linesz);
}
/*
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 43dde874f41..81f30ac2bff 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -47,8 +47,6 @@ void (*_dma_cache_wback)(unsigned long start, unsigned long size);
void (*_dma_cache_inv)(unsigned long start, unsigned long size);
EXPORT_SYMBOL(_dma_cache_wback_inv);
-EXPORT_SYMBOL(_dma_cache_wback);
-EXPORT_SYMBOL(_dma_cache_inv);
#endif /* CONFIG_DMA_NONCOHERENT */
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 521771b373d..5699c7713e2 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -180,7 +180,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 5240432e6d1..110ee7656b4 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -211,7 +211,7 @@ void copy_user_highpage(struct page *to, struct page *from,
void *vfrom, *vto;
vto = kmap_atomic(to, KM_USER1);
- if (cpu_has_dc_aliases && !Page_dcache_dirty(from)) {
+ if (cpu_has_dc_aliases && page_mapped(from)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
kunmap_coherent();
@@ -234,12 +234,15 @@ void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (cpu_has_dc_aliases) {
+ if (cpu_has_dc_aliases && page_mapped(page)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
kunmap_coherent();
- } else
+ } else {
memcpy(dst, src, len);
+ if (cpu_has_dc_aliases)
+ SetPageDcacheDirty(page);
+ }
if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
flush_cache_page(vma, vaddr, page_to_pfn(page));
}
@@ -250,13 +253,15 @@ void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
{
- if (cpu_has_dc_aliases) {
- void *vfrom =
- kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ if (cpu_has_dc_aliases && page_mapped(page)) {
+ void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
kunmap_coherent();
- } else
+ } else {
memcpy(dst, src, len);
+ if (cpu_has_dc_aliases)
+ SetPageDcacheDirty(page);
+ }
}
EXPORT_SYMBOL(copy_from_user_page);
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 09fa007c1d1..059eade96f2 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -206,7 +206,7 @@ static void pci_proc_init(void)
}
#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
-spinlock_t bpci_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(bpci_lock);
/*****************************************************************************
*
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
index 5abd5c7119b..174f314933b 100644
--- a/arch/mips/pci/pci-lasat.c
+++ b/arch/mips/pci/pci-lasat.c
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/types.h>
#include <asm/bootinfo.h>
+#include <asm/lasat/lasatint.h>
extern struct pci_ops nile4_pci_ops;
extern struct pci_ops gt64xxx_pci0_ops;
@@ -54,15 +55,15 @@ static int __init lasat_pci_setup(void)
arch_initcall(lasat_pci_setup);
-#define LASATINT_ETH1 0
-#define LASATINT_ETH0 1
-#define LASATINT_HDC 2
-#define LASATINT_COMP 3
-#define LASATINT_HDLC 4
-#define LASATINT_PCIA 5
-#define LASATINT_PCIB 6
-#define LASATINT_PCIC 7
-#define LASATINT_PCID 8
+#define LASATINT_ETH1 (LASATINT_BASE + 0)
+#define LASATINT_ETH0 (LASATINT_BASE + 1)
+#define LASATINT_HDC (LASATINT_BASE + 2)
+#define LASATINT_COMP (LASATINT_BASE + 3)
+#define LASATINT_HDLC (LASATINT_BASE + 4)
+#define LASATINT_PCIA (LASATINT_BASE + 5)
+#define LASATINT_PCIB (LASATINT_BASE + 6)
+#define LASATINT_PCIC (LASATINT_BASE + 7)
+#define LASATINT_PCID (LASATINT_BASE + 8)
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
index abbd0bbfabd..6b293ce0935 100644
--- a/arch/mips/pmc-sierra/Kconfig
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -4,11 +4,13 @@ choice
config PMC_MSP4200_EVAL
bool "PMC-Sierra MSP4200 Eval Board"
+ select CEVT_R4K
select IRQ_MSP_SLP
select HW_HAS_PCI
config PMC_MSP4200_GW
bool "PMC-Sierra MSP4200 VoIP Gateway"
+ select CEVT_R4K
select IRQ_MSP_SLP
select HW_HAS_PCI
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index 1fb3e353e21..e3acb51b70b 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -7,3 +7,5 @@ obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o
obj-$(CONFIG_EISA) += ip22-eisa.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 63afd7e4442..a435b31cf03 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -232,11 +232,18 @@ static struct notifier_block panic_block = {
static int __init reboot_setup(void)
{
+ int res;
+
_machine_restart = sgi_machine_restart;
_machine_halt = sgi_machine_halt;
pm_power_off = sgi_machine_power_off;
- request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
+ res = request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
+ if (res) {
+ printk(KERN_ERR "Allocation of front panel IRQ failed\n");
+ return res;
+ }
+
init_timer(&blink_timer);
blink_timer.function = blink_timeout;
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index 9b9bffd2e8f..10e50549165 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -192,12 +192,3 @@ void indy_8254timer_irq(void)
ArcEnterInteractiveMode();
irq_exit();
}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
- /* over-write the handler, we use our own way */
- irq->handler = no_action;
-
- /* setup irqaction */
- setup_irq(SGI_TIMER_IRQ, irq);
-}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 856649cf9f1..1bb692a3b31 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -374,14 +374,13 @@ int __devinit request_bridge_irq(struct bridge_controller *bc)
return irq;
}
-extern void ip27_rt_timer_interrupt(void);
-
asmlinkage void plat_irq_dispatch(void)
{
unsigned long pending = read_c0_cause() & read_c0_status();
+ extern unsigned int rt_timer_irq;
if (pending & CAUSEF_IP4)
- ip27_rt_timer_interrupt();
+ do_IRQ(rt_timer_irq);
else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
ip27_do_irq_mask0();
else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index b7b3479b6bc..d467bf4f6c3 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -3,6 +3,7 @@
* Copytight (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/bcd.h>
+#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -25,22 +26,8 @@
#include <asm/sn/sn0/ip27.h>
#include <asm/sn/sn0/hub.h>
-/*
- * This is a hack; we really need to figure these values out dynamically
- *
- * Since 800 ns works very well with various HUB frequencies, such as
- * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
- *
- * Ralf: which clock rate is used to feed the counter?
- */
-#define NSEC_PER_CYCLE 800
-#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
-#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
-
#define TICK_SIZE (tick_nsec / 1000)
-static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */
-
#if 0
static int set_rtc_mmss(unsigned long nowtime)
{
@@ -86,36 +73,6 @@ static int set_rtc_mmss(unsigned long nowtime)
}
#endif
-static unsigned int rt_timer_irq;
-
-void ip27_rt_timer_interrupt(void)
-{
- int cpu = smp_processor_id();
- int cpuA = cputoslice(cpu) == 0;
- unsigned int irq = rt_timer_irq;
-
- irq_enter();
- write_seqlock(&xtime_lock);
-
-again:
- LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */
- ct_cur[cpu] += CYCLES_PER_JIFFY;
- LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
-
- if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
- goto again;
-
- kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */
-
- if (cpu == 0)
- do_timer(1);
-
- update_process_times(user_mode(get_irq_regs()));
-
- write_sequnlock(&xtime_lock);
- irq_exit();
-}
-
/* Includes for ioc3_init(). */
#include <asm/sn/types.h>
#include <asm/sn/sn0/addrs.h>
@@ -154,6 +111,46 @@ 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)
+{
+ unsigned int cpu = smp_processor_id();
+ int slice = cputoslice(cpu) == 0;
+ unsigned long cnt;
+
+ cnt = LOCAL_HUB_L(PI_RT_COUNT);
+ cnt += delta;
+ LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt);
+
+ return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
+}
+
+static void rt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* The only mode supported */
+ break;
+
+ 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)
{
}
@@ -171,6 +168,20 @@ static struct irq_chip rt_irq_type = {
.eoi = enable_rt_irq,
};
+unsigned int rt_timer_irq;
+
+static irqreturn_t ip27_rt_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = &rt_clock_event_device;
+ unsigned int cpu = smp_processor_id();
+ int slice = cputoslice(cpu) == 0;
+
+ LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
static struct irqaction rt_irqaction = {
.handler = (irq_handler_t) ip27_rt_timer_interrupt,
.flags = IRQF_DISABLED,
@@ -178,26 +189,43 @@ static struct irqaction rt_irqaction = {
.name = "timer"
};
-void __init plat_timer_setup(struct irqaction *irq)
+/*
+ * This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE 800
+#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE)
+
+static void __init ip27_rt_clock_event_init(void)
{
- int irqno = allocate_irqno();
+ struct clock_event_device *cd = &rt_clock_event_device;
+ unsigned int cpu = smp_processor_id();
+ int irq = allocate_irqno();
- if (irqno < 0)
+ if (irq < 0)
panic("Can't allocate interrupt number for timer interrupt");
- set_irq_chip_and_handler(irqno, &rt_irq_type, handle_percpu_irq);
+ rt_timer_irq = irq;
- /* over-write the handler, we use our own way */
- irq->handler = no_action;
+ cd->irq = irq,
+ cd->cpumask = cpumask_of_cpu(cpu),
- /* setup irqaction */
- irq_desc[irqno].status |= IRQ_PER_CPU;
-
- rt_timer_irq = irqno;
/*
- * Only needed to get /proc/interrupt to display timer irq stats
+ * Calculate the min / max delta
*/
- setup_irq(irqno, &rt_irqaction);
+ 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);
+ clockevents_register_device(cd);
+
+ set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
+ setup_irq(irq, &rt_irqaction);
}
static cycle_t hub_rt_read(void)
@@ -206,7 +234,7 @@ static cycle_t hub_rt_read(void)
}
struct clocksource ht_rt_clocksource = {
- .name = "HUB",
+ .name = "HUB-RT",
.rating = 200,
.read = hub_rt_read,
.mask = CLOCKSOURCE_MASK(52),
@@ -214,11 +242,17 @@ struct clocksource ht_rt_clocksource = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-void __init plat_time_init(void)
+static void __init ip27_rt_clocksource_init(void)
{
clocksource_register(&ht_rt_clocksource);
}
+void __init plat_time_init(void)
+{
+ ip27_rt_clock_event_init();
+ ip27_rt_clocksource_init();
+}
+
void __init cpu_time_init(void)
{
lboard_t *board;
@@ -248,17 +282,12 @@ void __init hub_rtc_init(cnodeid_t cnode)
* node and timeouts will not happen there.
*/
if (get_compact_nodeid() == cnode) {
- int cpu = smp_processor_id();
LOCAL_HUB_S(PI_RT_EN_A, 1);
LOCAL_HUB_S(PI_RT_EN_B, 1);
LOCAL_HUB_S(PI_PROF_EN_A, 0);
LOCAL_HUB_S(PI_PROF_EN_B, 0);
- ct_cur[cpu] = CYCLES_PER_JIFFY;
- LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
LOCAL_HUB_S(PI_RT_COUNT, 0);
LOCAL_HUB_S(PI_RT_PEND_A, 0);
- LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
- LOCAL_HUB_S(PI_RT_COUNT, 0);
LOCAL_HUB_S(PI_RT_PEND_B, 0);
}
}
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 7f4b793c3df..7e8094f617b 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -20,6 +20,7 @@
#include <linux/random.h>
#include <linux/sched.h>
+#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/signal.h>
#include <asm/system.h>
@@ -46,7 +47,8 @@ static void inline flush_mace_bus(void)
#define DBG(x...)
#endif
-/* O2 irq map
+/*
+ * O2 irq map
*
* IP0 -> software (ignored)
* IP1 -> software (ignored)
@@ -55,60 +57,60 @@ static void inline flush_mace_bus(void)
* IP4 -> (irq2) X unknown
* IP5 -> (irq3) X unknown
* IP6 -> (irq4) X unknown
- * IP7 -> (irq5) 0 CPU count/compare timer (system timer)
+ * IP7 -> (irq5) 7 CPU count/compare timer (system timer)
*
* crime: (C)
*
* CRIME_INT_STAT 31:0:
*
- * 0 -> 1 Video in 1
- * 1 -> 2 Video in 2
- * 2 -> 3 Video out
- * 3 -> 4 Mace ethernet
+ * 0 -> 8 Video in 1
+ * 1 -> 9 Video in 2
+ * 2 -> 10 Video out
+ * 3 -> 11 Mace ethernet
* 4 -> S SuperIO sub-interrupt
* 5 -> M Miscellaneous sub-interrupt
* 6 -> A Audio sub-interrupt
- * 7 -> 8 PCI bridge errors
- * 8 -> 9 PCI SCSI aic7xxx 0
- * 9 -> 10 PCI SCSI aic7xxx 1
- * 10 -> 11 PCI slot 0
- * 11 -> 12 unused (PCI slot 1)
- * 12 -> 13 unused (PCI slot 2)
- * 13 -> 14 unused (PCI shared 0)
- * 14 -> 15 unused (PCI shared 1)
- * 15 -> 16 unused (PCI shared 2)
- * 16 -> 17 GBE0 (E)
- * 17 -> 18 GBE1 (E)
- * 18 -> 19 GBE2 (E)
- * 19 -> 20 GBE3 (E)
- * 20 -> 21 CPU errors
- * 21 -> 22 Memory errors
- * 22 -> 23 RE empty edge (E)
- * 23 -> 24 RE full edge (E)
- * 24 -> 25 RE idle edge (E)
- * 25 -> 26 RE empty level
- * 26 -> 27 RE full level
- * 27 -> 28 RE idle level
- * 28 -> 29 unused (software 0) (E)
- * 29 -> 30 unused (software 1) (E)
- * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E)
- * 31 -> 32 VICE
+ * 7 -> 15 PCI bridge errors
+ * 8 -> 16 PCI SCSI aic7xxx 0
+ * 9 -> 17 PCI SCSI aic7xxx 1
+ * 10 -> 18 PCI slot 0
+ * 11 -> 19 unused (PCI slot 1)
+ * 12 -> 20 unused (PCI slot 2)
+ * 13 -> 21 unused (PCI shared 0)
+ * 14 -> 22 unused (PCI shared 1)
+ * 15 -> 23 unused (PCI shared 2)
+ * 16 -> 24 GBE0 (E)
+ * 17 -> 25 GBE1 (E)
+ * 18 -> 26 GBE2 (E)
+ * 19 -> 27 GBE3 (E)
+ * 20 -> 28 CPU errors
+ * 21 -> 29 Memory errors
+ * 22 -> 30 RE empty edge (E)
+ * 23 -> 31 RE full edge (E)
+ * 24 -> 32 RE idle edge (E)
+ * 25 -> 33 RE empty level
+ * 26 -> 34 RE full level
+ * 27 -> 35 RE idle level
+ * 28 -> 36 unused (software 0) (E)
+ * 29 -> 37 unused (software 1) (E)
+ * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 39 VICE
*
* S, M, A: Use the MACE ISA interrupt register
* MACE_ISA_INT_STAT 31:0
*
- * 0-7 -> 33-40 Audio
- * 8 -> 41 RTC
- * 9 -> 42 Keyboard
+ * 0-7 -> 40-47 Audio
+ * 8 -> 48 RTC
+ * 9 -> 49 Keyboard
* 10 -> X Keyboard polled
- * 11 -> 44 Mouse
+ * 11 -> 51 Mouse
* 12 -> X Mouse polled
- * 13-15 -> 46-48 Count/compare timers
- * 16-19 -> 49-52 Parallel (16 E)
- * 20-25 -> 53-58 Serial 1 (22 E)
- * 26-31 -> 59-64 Serial 2 (28 E)
+ * 13-15 -> 53-55 Count/compare timers
+ * 16-19 -> 56-59 Parallel (16 E)
+ * 20-25 -> 60-62 Serial 1 (22 E)
+ * 26-31 -> 66-71 Serial 2 (28 E)
*
- * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a
+ * Note that this means IRQs 12-14, 50, and 52 do not exist. This is a
* different IRQ map than IRIX uses, but that's OK as Linux irq handling
* is quite different anyway.
*/
@@ -131,36 +133,6 @@ struct irqaction cpuerr_irq = {
};
/*
- * For interrupts wired from a single device to the CPU. Only the clock
- * uses this it seems, which is IRQ 0 and IP7.
- */
-
-static void enable_cpu_irq(unsigned int irq)
-{
- set_c0_status(STATUSF_IP7);
-}
-
-static void disable_cpu_irq(unsigned int irq)
-{
- clear_c0_status(STATUSF_IP7);
-}
-
-static void end_cpu_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_cpu_irq(irq);
-}
-
-static struct irq_chip ip32_cpu_interrupt = {
- .name = "IP32 CPU",
- .ack = disable_cpu_irq,
- .mask = disable_cpu_irq,
- .mask_ack = disable_cpu_irq,
- .unmask = enable_cpu_irq,
- .end = end_cpu_irq,
-};
-
-/*
* This is for pure CRIME interrupts - ie not MACE. The advantage?
* We get to split the register in half and do faster lookups.
*/
@@ -422,15 +394,23 @@ static void ip32_irq0(void)
uint64_t crime_int;
int irq = 0;
+ /*
+ * Sanity check interrupt numbering enum.
+ * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy
+ * chained.
+ */
+ BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31);
+ BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31);
+
crime_int = crime->istat & crime_mask;
- irq = __ffs(crime_int);
+ irq = MACE_VID_IN1_IRQ + __ffs(crime_int);
crime_int = 1 << irq;
if (crime_int & CRIME_MACEISA_INT_MASK) {
unsigned long mace_int = mace->perif.ctrl.istat;
- irq = __ffs(mace_int & maceisa_mask) + 32;
+ irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
}
- irq++;
+
DBG("*irq %u*\n", irq);
do_IRQ(irq);
}
@@ -457,7 +437,7 @@ static void ip32_irq4(void)
static void ip32_irq5(void)
{
- do_IRQ(IP32_R4K_TIMER_IRQ);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
}
asmlinkage void plat_irq_dispatch(void)
@@ -490,21 +470,25 @@ void __init arch_init_irq(void)
mace->perif.ctrl.istat = 0;
mace->perif.ctrl.imask = 0;
- for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
- struct irq_chip *controller;
-
- if (irq == IP32_R4K_TIMER_IRQ)
- controller = &ip32_cpu_interrupt;
- else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
- controller = &ip32_mace_interrupt;
- else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
- controller = &ip32_macepci_interrupt;
- else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
- controller = &ip32_crime_interrupt;
- else
- controller = &ip32_maceisa_interrupt;
-
- set_irq_chip(irq, controller);
+ mips_cpu_irq_init();
+ for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) {
+ struct irq_chip *chip;
+
+ switch (irq) {
+ case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
+ chip = &ip32_mace_interrupt;
+ break;
+ case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
+ chip = &ip32_macepci_interrupt;
+ break;
+ case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ:
+ chip = &ip32_crime_interrupt;
+ break;
+ default:
+ chip = &ip32_maceisa_interrupt;
+ }
+
+ set_irq_chip(irq, chip);
}
setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index 4125a5ba119..1024bf40bd9 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -80,12 +80,6 @@ void __init plat_time_init(void)
printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- irq->handler = no_action;
- setup_irq(IP32_R4K_TIMER_IRQ, irq);
-}
-
void __init plat_mem_setup(void)
{
board_be_init = ip32_be_init;
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index 40d7126cd5b..5b4bfbbb5a2 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -84,7 +84,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
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_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 38199ad8fc5..fe11fed8e0d 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -83,7 +83,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
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_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
switch(mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -111,7 +111,7 @@ sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
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_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
__raw_writeq(0, timer_cfg);
__raw_writeq(delta, timer_init);
@@ -155,7 +155,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
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_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -183,7 +183,7 @@ sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
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_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
__raw_writeq(0, timer_cfg);
__raw_writeq(delta, timer_init);
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index acaf613358c..b97102a1c63 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -963,7 +963,7 @@ static int __init toshiba_rbtx4927_rtc_init(void)
.flags = IORESOURCE_MEM,
};
struct platform_device *dev =
- platform_device_register_simple("ds1742", -1, &res, 1);
+ platform_device_register_simple("rtc-ds1742", -1, &res, 1);
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
device_initcall(toshiba_rbtx4927_rtc_init);
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
index 8f4d3e74c23..eeb089f20c0 100644
--- a/arch/mips/vr41xx/Kconfig
+++ b/arch/mips/vr41xx/Kconfig
@@ -5,6 +5,7 @@ choice
config CASIO_E55
bool "CASIO CASSIOPEIA E-10/15/55/65"
+ select CEVT_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select ISA
@@ -13,6 +14,7 @@ config CASIO_E55
config IBM_WORKPAD
bool "IBM WorkPad z50"
+ select CEVT_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select ISA
@@ -21,6 +23,7 @@ config IBM_WORKPAD
config NEC_CMBVR4133
bool "NEC CMB-VR4133"
+ select CEVT_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
@@ -29,6 +32,7 @@ config NEC_CMBVR4133
config TANBAC_TB022X
bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+ select CEVT_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
@@ -43,6 +47,7 @@ config TANBAC_TB022X
config VICTOR_MPC30X
bool "Victor MP-C303/304"
+ select CEVT_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
@@ -52,6 +57,7 @@ config VICTOR_MPC30X
config ZAO_CAPCELLA
bool "ZAO Networks Capcella"
+ select CEVT_R4K
select DMA_NONCOHERENT
select IRQ_CPU
select HW_HAS_PCI
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 760567a9ba1..f3d0d7c7097 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -63,7 +63,7 @@ cflags-$(CONFIG_PA8X00) += -march=2.0 -mschedule=8000
head-y := arch/parisc/kernel/head.o
-CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
kernel-y := mm/ kernel/ math-emu/ kernel/init_task.o
kernel-$(CONFIG_HPUX) += hpux/
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 26ec774c502..49c63797078 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -329,10 +329,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* give it a chance to run. */
goto out_wake;
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- goto out_tsk;
-
case PTRACE_GETEVENTMSG:
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
goto out_tsk;
diff --git a/arch/parisc/math-emu/Makefile b/arch/parisc/math-emu/Makefile
index affd4c80e3b..1f3f225897f 100644
--- a/arch/parisc/math-emu/Makefile
+++ b/arch/parisc/math-emu/Makefile
@@ -3,7 +3,7 @@
#
# See arch/parisc/math-emu/README
-CFLAGS += -Wno-parentheses -Wno-implicit-function-declaration \
+EXTRA_CFLAGS += -Wno-parentheses -Wno-implicit-function-declaration \
-Wno-uninitialized -Wno-strict-prototypes -Wno-return-type \
-Wno-implicit-int
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 7899ab87785..1c091b415cd 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -263,6 +263,6 @@ no_context:
up_read(&mm->mmap_sem);
printk(KERN_CRIT "VM: killing process %s\n", current->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 037664d496d..3763f681ce4 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -295,6 +295,7 @@ config ARCH_FLATMEM_ENABLE
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on PPC64
+ select SPARSEMEM_VMEMMAP_ENABLE
config ARCH_SPARSEMEM_DEFAULT
def_bool y
@@ -669,7 +670,6 @@ source "arch/powerpc/sysdev/qe_lib/Kconfig"
source "lib/Kconfig"
menu "Instrumentation Support"
- depends on EXPERIMENTAL
source "arch/powerpc/oprofile/Kconfig"
@@ -698,3 +698,7 @@ source "crypto/Kconfig"
config PPC_CLOCK
bool
default n
+
+config PPC_LIB_RHEAP
+ bool
+
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 464f9b4b316..c939fe86a9e 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -144,7 +144,7 @@ config BDI_SWITCH
config BOOTX_TEXT
bool "Support for early boot text console (BootX or OpenFirmware only)"
- depends PPC_OF && PPC_MULTIPLATFORM
+ depends on PPC_OF && PPC_MULTIPLATFORM
help
Say Y here to see progress messages from the boot firmware in text
mode. Requires either BootX or Open Firmware.
@@ -234,12 +234,12 @@ endchoice
config PPC_EARLY_DEBUG_44x_PHYSLOW
hex "Low 32 bits of early debug UART physical address"
- depends PPC_EARLY_DEBUG_44x
+ depends on PPC_EARLY_DEBUG_44x
default "0x40000200"
config PPC_EARLY_DEBUG_44x_PHYSHIGH
hex "EPRN of early debug UART physical address"
- depends PPC_EARLY_DEBUG_44x
+ depends on PPC_EARLY_DEBUG_44x
default "0x1"
config PPC_EARLY_DEBUG_CPM_ADDR
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 643839a3f5d..4e165342210 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -75,10 +75,10 @@ CPPFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH)
AFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH)
CFLAGS-$(CONFIG_PPC64) := -mminimal-toc -mtraceback=none -mcall-aixdesc
CFLAGS-$(CONFIG_PPC32) := -Iarch/$(ARCH) -ffixed-r2 -mmultiple
-CPPFLAGS += $(CPPFLAGS-y)
-AFLAGS += $(AFLAGS-y)
-CFLAGS += -msoft-float -pipe $(CFLAGS-y)
-CPP = $(CC) -E $(CFLAGS)
+KBUILD_CPPFLAGS += $(CPPFLAGS-y)
+KBUILD_AFLAGS += $(AFLAGS-y)
+KBUILD_CFLAGS += -msoft-float -pipe $(CFLAGS-y)
+CPP = $(CC) -E $(KBUILD_CFLAGS)
CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__
@@ -88,35 +88,35 @@ GCC_BROKEN_VEC := $(shell if [ $(call cc-version) -lt 0400 ] ; then echo "y"; fi
ifeq ($(CONFIG_POWER4_ONLY),y)
ifeq ($(CONFIG_ALTIVEC),y)
ifeq ($(GCC_BROKEN_VEC),y)
- CFLAGS += $(call cc-option,-mcpu=970)
+ KBUILD_CFLAGS += $(call cc-option,-mcpu=970)
else
- CFLAGS += $(call cc-option,-mcpu=power4)
+ KBUILD_CFLAGS += $(call cc-option,-mcpu=power4)
endif
else
- CFLAGS += $(call cc-option,-mcpu=power4)
+ KBUILD_CFLAGS += $(call cc-option,-mcpu=power4)
endif
else
- CFLAGS += $(call cc-option,-mtune=power4)
+ KBUILD_CFLAGS += $(call cc-option,-mtune=power4)
endif
endif
ifeq ($(CONFIG_TUNE_CELL),y)
- CFLAGS += $(call cc-option,-mtune=cell)
+ KBUILD_CFLAGS += $(call cc-option,-mtune=cell)
endif
# No AltiVec instruction when building kernel
-CFLAGS += $(call cc-option,-mno-altivec)
+KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
# Enable unit-at-a-time mode when possible. It shrinks the
# kernel considerably.
-CFLAGS += $(call cc-option,-funit-at-a-time)
+KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
# Never use string load/store instructions as they are
# often slow when they are implemented at all
-CFLAGS += -mno-string
+KBUILD_CFLAGS += -mno-string
ifeq ($(CONFIG_6xx),y)
-CFLAGS += -mcpu=powerpc
+KBUILD_CFLAGS += -mcpu=powerpc
endif
cpu-as-$(CONFIG_4xx) += -Wa,-m405
@@ -125,8 +125,8 @@ cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec
cpu-as-$(CONFIG_E500) += -Wa,-me500
cpu-as-$(CONFIG_E200) += -Wa,-me200
-AFLAGS += $(cpu-as-y)
-CFLAGS += $(cpu-as-y)
+KBUILD_AFLAGS += $(cpu-as-y)
+KBUILD_CFLAGS += $(cpu-as-y)
head-y := arch/powerpc/kernel/head_$(CONFIG_WORD_SIZE).o
head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index a6bb1d0558e..6582c9a39b2 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -277,10 +277,26 @@
ethernet@3000 {
device_type = "network";
compatible = "mpc5200b-fec","mpc5200-fec";
- reg = <3000 800>;
+ reg = <3000 400>;
mac-address = [ 02 03 04 05 06 07 ]; // Bad!
interrupts = <2 5 0>;
interrupt-parent = <&mpc5200_pic>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "mpc5200b-fec-phy";
+ reg = <3000 400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+ interrupt-parent = <&mpc5200_pic>;
+
+ phy0:ethernet-phy@0 {
+ device_type = "ethernet-phy";
+ reg = <0>;
+ };
};
ata@3a00 {
diff --git a/arch/powerpc/configs/bamboo_defconfig b/arch/powerpc/configs/bamboo_defconfig
index b592dec4640..d22fed6d2cd 100644
--- a/arch/powerpc/configs/bamboo_defconfig
+++ b/arch/powerpc/configs/bamboo_defconfig
@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -695,7 +696,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/celleb_defconfig b/arch/powerpc/configs/celleb_defconfig
index b4ac498c3cc..2c5969801bd 100644
--- a/arch/powerpc/configs/celleb_defconfig
+++ b/arch/powerpc/configs/celleb_defconfig
@@ -92,8 +92,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1218,7 +1219,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig
index c3977e334b3..6f27e57331d 100644
--- a/arch/powerpc/configs/chrp32_defconfig
+++ b/arch/powerpc/configs/chrp32_defconfig
@@ -92,8 +92,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1373,7 +1374,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/ebony_defconfig b/arch/powerpc/configs/ebony_defconfig
index 3a50467b1f7..35a95dda681 100644
--- a/arch/powerpc/configs/ebony_defconfig
+++ b/arch/powerpc/configs/ebony_defconfig
@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -773,7 +774,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index a655d87b3f8..0a6fa1fc976 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -92,8 +92,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1580,7 +1581,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig
index 97d0202a9fe..11009185d23 100644
--- a/arch/powerpc/configs/holly_defconfig
+++ b/arch/powerpc/configs/holly_defconfig
@@ -88,8 +88,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -909,7 +910,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
+# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index 3fe1929460e..d78e3a6fc68 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -93,8 +93,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1056,7 +1057,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/kilauea_defconfig b/arch/powerpc/configs/kilauea_defconfig
index 31790d32926..fd1c530aa3e 100644
--- a/arch/powerpc/configs/kilauea_defconfig
+++ b/arch/powerpc/configs/kilauea_defconfig
@@ -91,8 +91,9 @@ CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -700,7 +701,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
index a4e3ee045a6..401033aefd4 100644
--- a/arch/powerpc/configs/linkstation_defconfig
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -89,8 +89,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1459,7 +1460,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/lite5200_defconfig b/arch/powerpc/configs/lite5200_defconfig
index d42e226d3a2..dd78ed955eb 100644
--- a/arch/powerpc/configs/lite5200_defconfig
+++ b/arch/powerpc/configs/lite5200_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -816,7 +817,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 96b538bc676..84b9ab4a5a9 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1095,8 +1096,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
-CONFIG_DEBUG_SLAB=y
-# CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig
index 05814a3b0e3..87ae894551b 100644
--- a/arch/powerpc/configs/mpc7448_hpc2_defconfig
+++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig
index 6b7951ec941..865a942ecc6 100644
--- a/arch/powerpc/configs/mpc8272_ads_defconfig
+++ b/arch/powerpc/configs/mpc8272_ads_defconfig
@@ -85,8 +85,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -867,7 +868,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8313_rdb_defconfig b/arch/powerpc/configs/mpc8313_rdb_defconfig
index f387dac69d0..259d40d1eb5 100644
--- a/arch/powerpc/configs/mpc8313_rdb_defconfig
+++ b/arch/powerpc/configs/mpc8313_rdb_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1272,7 +1273,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc832x_mds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig
index fc6695302cc..dd68d1818d6 100644
--- a/arch/powerpc/configs/mpc832x_mds_defconfig
+++ b/arch/powerpc/configs/mpc832x_mds_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc832x_rdb_defconfig b/arch/powerpc/configs/mpc832x_rdb_defconfig
index 6d1c3e84205..4f391028c79 100644
--- a/arch/powerpc/configs/mpc832x_rdb_defconfig
+++ b/arch/powerpc/configs/mpc832x_rdb_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig
index ddafa6b9af0..eb28dd85cb2 100644
--- a/arch/powerpc/configs/mpc834x_itx_defconfig
+++ b/arch/powerpc/configs/mpc834x_itx_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc834x_itxgp_defconfig b/arch/powerpc/configs/mpc834x_itxgp_defconfig
index 8241c698586..22b95462c91 100644
--- a/arch/powerpc/configs/mpc834x_itxgp_defconfig
+++ b/arch/powerpc/configs/mpc834x_itxgp_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc834x_mds_defconfig b/arch/powerpc/configs/mpc834x_mds_defconfig
index 06233b1a941..e59a88e9548 100644
--- a/arch/powerpc/configs/mpc834x_mds_defconfig
+++ b/arch/powerpc/configs/mpc834x_mds_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc836x_mds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig
index 3045749d62f..75657528518 100644
--- a/arch/powerpc/configs/mpc836x_mds_defconfig
+++ b/arch/powerpc/configs/mpc836x_mds_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/mpc8540_ads_defconfig b/arch/powerpc/configs/mpc8540_ads_defconfig
index b282c3521dd..b953b2c5145 100644
--- a/arch/powerpc/configs/mpc8540_ads_defconfig
+++ b/arch/powerpc/configs/mpc8540_ads_defconfig
@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -704,7 +705,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8544_ds_defconfig b/arch/powerpc/configs/mpc8544_ds_defconfig
index 150221f6f72..9a3e08bcd18 100644
--- a/arch/powerpc/configs/mpc8544_ds_defconfig
+++ b/arch/powerpc/configs/mpc8544_ds_defconfig
@@ -93,8 +93,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1427,7 +1428,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8560_ads_defconfig b/arch/powerpc/configs/mpc8560_ads_defconfig
index 3d68c65212c..0211e6b68e1 100644
--- a/arch/powerpc/configs/mpc8560_ads_defconfig
+++ b/arch/powerpc/configs/mpc8560_ads_defconfig
@@ -94,8 +94,9 @@ CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -791,7 +792,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8568mds_defconfig b/arch/powerpc/configs/mpc8568mds_defconfig
index 0307fe7b048..883d8af9deb 100644
--- a/arch/powerpc/configs/mpc8568mds_defconfig
+++ b/arch/powerpc/configs/mpc8568mds_defconfig
@@ -88,8 +88,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -949,7 +950,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8572_ds_defconfig b/arch/powerpc/configs/mpc8572_ds_defconfig
index 7f1a3e98713..4e85b2e8852 100644
--- a/arch/powerpc/configs/mpc8572_ds_defconfig
+++ b/arch/powerpc/configs/mpc8572_ds_defconfig
@@ -93,8 +93,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1427,7 +1428,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc85xx_cds_defconfig b/arch/powerpc/configs/mpc85xx_cds_defconfig
index e6850c619f8..a4f33d11054 100644
--- a/arch/powerpc/configs/mpc85xx_cds_defconfig
+++ b/arch/powerpc/configs/mpc85xx_cds_defconfig
@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -832,7 +833,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8610_hpcd_defconfig b/arch/powerpc/configs/mpc8610_hpcd_defconfig
index de19b781937..0483211f52b 100644
--- a/arch/powerpc/configs/mpc8610_hpcd_defconfig
+++ b/arch/powerpc/configs/mpc8610_hpcd_defconfig
@@ -88,8 +88,9 @@ CONFIG_SIGNALFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -993,7 +994,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc8641_hpcn_defconfig b/arch/powerpc/configs/mpc8641_hpcn_defconfig
index b2f389dcade..ed214fcd8ab 100644
--- a/arch/powerpc/configs/mpc8641_hpcn_defconfig
+++ b/arch/powerpc/configs/mpc8641_hpcn_defconfig
@@ -94,8 +94,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1432,7 +1433,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig
index 143a0cd8332..070b0a5b9c0 100644
--- a/arch/powerpc/configs/mpc866_ads_defconfig
+++ b/arch/powerpc/configs/mpc866_ads_defconfig
@@ -83,8 +83,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
# CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig
index 295207030c6..1ccf3ed7693 100644
--- a/arch/powerpc/configs/pasemi_defconfig
+++ b/arch/powerpc/configs/pasemi_defconfig
@@ -90,8 +90,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1588,7 +1589,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index cfc9c6573a3..8e5988c4a16 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -208,7 +209,6 @@ CONFIG_PM=y
# CONFIG_PM_LEGACY is not set
CONFIG_PM_DEBUG=y
# CONFIG_PM_VERBOSE is not set
-# CONFIG_DISABLE_CONSOLE_SUSPEND is not set
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_HIBERNATION=y
@@ -1829,7 +1829,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 5f6224a1feb..bb8d4e46f0c 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -96,8 +96,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -216,6 +217,10 @@ CONFIG_AXON_RAM=m
#
# Kernel options
#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
@@ -1750,7 +1755,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig
index a51fc39dea4..9191f557b04 100644
--- a/arch/powerpc/configs/pq2fads_defconfig
+++ b/arch/powerpc/configs/pq2fads_defconfig
@@ -86,8 +86,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -930,7 +931,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
+# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig
index cce3d3da086..3e87faf9b5c 100644
--- a/arch/powerpc/configs/prpmc2800_defconfig
+++ b/arch/powerpc/configs/prpmc2800_defconfig
@@ -89,8 +89,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index ca7a197998e..3566c448bdc 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -1059,7 +1060,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 0f274e5f692..c09eb8cfbe7 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -96,8 +96,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -176,6 +177,10 @@ CONFIG_IBMEBUS=y
#
# Kernel options
#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
@@ -1504,7 +1509,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/sequoia_defconfig b/arch/powerpc/configs/sequoia_defconfig
index bc7f5089a89..45a4ca0e0d7 100644
--- a/arch/powerpc/configs/sequoia_defconfig
+++ b/arch/powerpc/configs/sequoia_defconfig
@@ -91,8 +91,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -781,7 +782,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/configs/walnut_defconfig b/arch/powerpc/configs/walnut_defconfig
index 766bf840c18..7724292cc06 100644
--- a/arch/powerpc/configs/walnut_defconfig
+++ b/arch/powerpc/configs/walnut_defconfig
@@ -87,8 +87,9 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
@@ -706,7 +707,7 @@ 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_SLUB_DEBUG_ON is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0ae5d57b936..2c8e756d19a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -141,6 +141,7 @@ int main(void)
DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+ DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
index 5cb58757e1b..1d45d7782d4 100644
--- a/arch/powerpc/kernel/binfmt_elf32.c
+++ b/arch/powerpc/kernel/binfmt_elf32.c
@@ -13,49 +13,44 @@
* 2 of the License, or (at your option) any later version.
*/
-#define ELF_ARCH EM_PPC
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB;
-
#include <asm/processor.h>
#include <linux/module.h>
-#include <linux/elfcore.h>
#include <linux/compat.h>
+#include <linux/elfcore-compat.h>
+
+#undef ELF_ARCH
+#undef ELF_CLASS
+#define ELF_CLASS ELFCLASS32
+#define ELF_ARCH EM_PPC
+
+#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_prstatus elf_prstatus32
-struct elf_prstatus32
+#define elf_prstatus compat_elf_prstatus
+#define elf_prpsinfo compat_elf_prpsinfo
+
+#define elf_core_copy_regs compat_elf_core_copy_regs
+static inline void compat_elf_core_copy_regs(compat_elf_gregset_t *elf_regs,
+ struct pt_regs *regs)
{
- 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; /* General purpose registers. */
- int pr_fpvalid; /* True if math co-processor being used. */
-};
+ PPC_ELF_CORE_COPY_REGS((*elf_regs), regs);
+}
-#define elf_prpsinfo elf_prpsinfo32
-struct elf_prpsinfo32
+#define elf_core_copy_task_regs compat_elf_core_copy_task_regs
+static int compat_elf_core_copy_task_regs(struct task_struct *tsk,
+ compat_elf_gregset_t *elf_regs)
{
- 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 */
- u32 pr_uid;
- u32 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 */
-};
+ struct pt_regs *regs = tsk->thread.regs;
+ if (regs)
+ compat_elf_core_copy_regs(elf_regs, regs);
+ return 1;
+}
#include <linux/time.h>
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 7b0e754383c..9001104b56b 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -154,12 +154,13 @@ static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
{
}
-static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction direction)
{
+ struct scatterlist *sg;
int i;
- for (i = 0; i < nents; i++, sg++) {
+ for_each_sg(sgl, sg, nents, i) {
sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
dma_direct_offset;
sg->dma_length = sg->length;
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 0ec13403489..148a3547c9a 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -408,6 +408,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
+ /* No need to check for CPU_FTR_NO_SLBIE_B here, since when
+ * we have 1TB segments, the only CPUs known to have the errata
+ * only support less than 1TB of system memory and we'll never
+ * actually hit this code path.
+ */
+
slbie r6
slbie r6 /* Workaround POWER5 < DD2.1 issue */
slbmte r7,r0
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 53bf64623bd..289d7e93591 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -41,6 +41,7 @@
#include <linux/kobject.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/of_platform.h>
#include <asm/ibmebus.h>
#include <asm/abs_addr.h>
@@ -50,6 +51,13 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
struct bus_type ibmebus_bus_type;
+/* These devices will automatically be added to the bus during init */
+static struct of_device_id builtin_matches[] = {
+ { .compatible = "IBM,lhca" },
+ { .compatible = "IBM,lhea" },
+ {},
+};
+
static void *ibmebus_alloc_coherent(struct device *dev,
size_t size,
dma_addr_t *dma_handle,
@@ -87,15 +95,16 @@ static void ibmebus_unmap_single(struct device *dev,
}
static int ibmebus_map_sg(struct device *dev,
- struct scatterlist *sg,
+ struct scatterlist *sgl,
int nents, enum dma_data_direction direction)
{
+ struct scatterlist *sg;
int i;
- for (i = 0; i < nents; i++) {
- sg[i].dma_address = (dma_addr_t)page_address(sg[i].page)
- + sg[i].offset;
- sg[i].dma_length = sg[i].length;
+ for_each_sg(sgl, sg, nents, i) {
+ sg->dma_address = (dma_addr_t)page_address(sg->page)
+ + sg->offset;
+ sg->dma_length = sg->length;
}
return nents;
@@ -123,190 +132,87 @@ static struct dma_mapping_ops ibmebus_dma_ops = {
.dma_supported = ibmebus_dma_supported,
};
-static int ibmebus_bus_probe(struct device *dev)
+static int ibmebus_match_path(struct device *dev, void *data)
{
- struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
- struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
- const struct of_device_id *id;
- int error = -ENODEV;
-
- if (!ibmebusdrv->probe)
- return error;
-
- id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev);
- if (id) {
- error = ibmebusdrv->probe(ibmebusdev, id);
- }
-
- return error;
+ struct device_node *dn = to_of_device(dev)->node;
+ return (dn->full_name &&
+ (strcasecmp((char *)data, dn->full_name) == 0));
}
-static int ibmebus_bus_remove(struct device *dev)
+static int ibmebus_match_node(struct device *dev, void *data)
{
- struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev);
- struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver);
-
- if (ibmebusdrv->remove) {
- return ibmebusdrv->remove(ibmebusdev);
- }
-
- return 0;
+ return to_of_device(dev)->node == data;
}
-static void __devinit ibmebus_dev_release(struct device *dev)
+static int ibmebus_create_device(struct device_node *dn)
{
- of_node_put(to_ibmebus_dev(dev)->ofdev.node);
- kfree(to_ibmebus_dev(dev));
-}
-
-static int __devinit ibmebus_register_device_common(
- struct ibmebus_dev *dev, const char *name)
-{
- int err = 0;
-
- dev->ofdev.dev.parent = &ibmebus_bus_device;
- dev->ofdev.dev.bus = &ibmebus_bus_type;
- dev->ofdev.dev.release = ibmebus_dev_release;
+ struct of_device *dev;
+ int ret;
- dev->ofdev.dev.archdata.of_node = dev->ofdev.node;
- dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops;
- dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node);
-
- /* An ibmebusdev is based on a of_device. We have to change the
- * bus type to use our own DMA mapping operations.
- */
- if ((err = of_device_register(&dev->ofdev)) != 0) {
- printk(KERN_ERR "%s: failed to register device (%d).\n",
- __FUNCTION__, err);
- return -ENODEV;
- }
-
- return 0;
-}
-
-static struct ibmebus_dev* __devinit ibmebus_register_device_node(
- struct device_node *dn)
-{
- struct ibmebus_dev *dev;
- int i, len, bus_len;
-
- dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
+ dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
if (!dev)
- return ERR_PTR(-ENOMEM);
-
- dev->ofdev.node = of_node_get(dn);
-
- len = strlen(dn->full_name + 1);
- bus_len = min(len, BUS_ID_SIZE - 1);
- memcpy(dev->ofdev.dev.bus_id, dn->full_name + 1
- + (len - bus_len), bus_len);
- for (i = 0; i < bus_len; i++)
- if (dev->ofdev.dev.bus_id[i] == '/')
- dev->ofdev.dev.bus_id[i] = '_';
-
- /* Register with generic device framework. */
- if (ibmebus_register_device_common(dev, dn->name) != 0) {
- kfree(dev);
- return ERR_PTR(-ENODEV);
- }
-
- return dev;
-}
-
-static void ibmebus_probe_of_nodes(char* name)
-{
- struct device_node *dn = NULL;
-
- while ((dn = of_find_node_by_name(dn, name))) {
- if (IS_ERR(ibmebus_register_device_node(dn))) {
- of_node_put(dn);
- return;
- }
- }
-
- of_node_put(dn);
+ return -ENOMEM;
- return;
-}
+ dev->dev.bus = &ibmebus_bus_type;
+ dev->dev.archdata.dma_ops = &ibmebus_dma_ops;
-static void ibmebus_add_devices_by_id(struct of_device_id *idt)
-{
- while (strlen(idt->name) > 0) {
- ibmebus_probe_of_nodes(idt->name);
- idt++;
+ ret = of_device_register(dev);
+ if (ret) {
+ of_device_free(dev);
+ return ret;
}
- return;
-}
-
-static int ibmebus_match_name(struct device *dev, void *data)
-{
- const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
- const char *name;
-
- name = of_get_property(ebus_dev->ofdev.node, "name", NULL);
-
- if (name && (strcmp(data, name) == 0))
- return 1;
-
return 0;
}
-static int ibmebus_unregister_device(struct device *dev)
+static int ibmebus_create_devices(const struct of_device_id *matches)
{
- of_device_unregister(to_of_device(dev));
+ struct device_node *root, *child;
+ int ret = 0;
- return 0;
-}
+ root = of_find_node_by_path("/");
-static void ibmebus_remove_devices_by_id(struct of_device_id *idt)
-{
- struct device *dev;
+ for (child = NULL; (child = of_get_next_child(root, child)); ) {
+ if (!of_match_node(matches, child))
+ continue;
- while (strlen(idt->name) > 0) {
- while ((dev = bus_find_device(&ibmebus_bus_type, NULL,
- (void*)idt->name,
- ibmebus_match_name))) {
- ibmebus_unregister_device(dev);
+ if (bus_find_device(&ibmebus_bus_type, NULL, child,
+ ibmebus_match_node))
+ continue;
+
+ ret = ibmebus_create_device(child);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to create device (%i)",
+ __FUNCTION__, ret);
+ of_node_put(child);
+ break;
}
- idt++;
}
- return;
+ of_node_put(root);
+ return ret;
}
-int ibmebus_register_driver(struct ibmebus_driver *drv)
+int ibmebus_register_driver(struct of_platform_driver *drv)
{
- int err = 0;
+ /* If the driver uses devices that ibmebus doesn't know, add them */
+ ibmebus_create_devices(drv->match_table);
drv->driver.name = drv->name;
drv->driver.bus = &ibmebus_bus_type;
- drv->driver.probe = ibmebus_bus_probe;
- drv->driver.remove = ibmebus_bus_remove;
- if ((err = driver_register(&drv->driver) != 0))
- return err;
-
- /* remove all supported devices first, in case someone
- * probed them manually before registering the driver */
- ibmebus_remove_devices_by_id(drv->id_table);
- ibmebus_add_devices_by_id(drv->id_table);
-
- return 0;
+ return driver_register(&drv->driver);
}
EXPORT_SYMBOL(ibmebus_register_driver);
-void ibmebus_unregister_driver(struct ibmebus_driver *drv)
+void ibmebus_unregister_driver(struct of_platform_driver *drv)
{
driver_unregister(&drv->driver);
- ibmebus_remove_devices_by_id(drv->id_table);
}
EXPORT_SYMBOL(ibmebus_unregister_driver);
-int ibmebus_request_irq(struct ibmebus_dev *dev,
- u32 ist,
- irq_handler_t handler,
- unsigned long irq_flags, const char * devname,
+int ibmebus_request_irq(u32 ist, irq_handler_t handler,
+ unsigned long irq_flags, const char *devname,
void *dev_id)
{
unsigned int irq = irq_create_mapping(NULL, ist);
@@ -314,12 +220,11 @@ int ibmebus_request_irq(struct ibmebus_dev *dev,
if (irq == NO_IRQ)
return -EINVAL;
- return request_irq(irq, handler,
- irq_flags, devname, dev_id);
+ return request_irq(irq, handler, irq_flags, devname, dev_id);
}
EXPORT_SYMBOL(ibmebus_request_irq);
-void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
+void ibmebus_free_irq(u32 ist, void *dev_id)
{
unsigned int irq = irq_find_mapping(NULL, ist);
@@ -327,29 +232,10 @@ void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
}
EXPORT_SYMBOL(ibmebus_free_irq);
-static int ibmebus_bus_match(struct device *dev, struct device_driver *drv)
-{
- const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
- struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv);
- const struct of_device_id *ids = ebus_drv->id_table;
- const struct of_device_id *found_id;
-
- if (!ids)
- return 0;
-
- found_id = of_match_device(ids, &ebus_dev->ofdev);
- if (found_id)
- return 1;
-
- return 0;
-}
-
static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev);
- const char *name = of_get_property(ebus_dev->ofdev.node, "name", NULL);
- return sprintf(buf, "%s\n", name);
+ return sprintf(buf, "%s\n", to_of_device(dev)->node->name);
}
static struct device_attribute ibmebus_dev_attrs[] = {
@@ -357,18 +243,6 @@ static struct device_attribute ibmebus_dev_attrs[] = {
__ATTR_NULL
};
-static int ibmebus_match_path(struct device *dev, void *data)
-{
- int rc;
- struct device_node *dn =
- of_node_get(to_ibmebus_dev(dev)->ofdev.node);
-
- rc = (dn->full_name && (strcasecmp((char*)data, dn->full_name) == 0));
-
- of_node_put(dn);
- return rc;
-}
-
static char *ibmebus_chomp(const char *in, size_t count)
{
char *out = kmalloc(count + 1, GFP_KERNEL);
@@ -388,9 +262,8 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
const char *buf, size_t count)
{
struct device_node *dn = NULL;
- struct ibmebus_dev *dev;
char *path;
- ssize_t rc;
+ ssize_t rc = 0;
path = ibmebus_chomp(buf, count);
if (!path)
@@ -405,9 +278,8 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
}
if ((dn = of_find_node_by_path(path))) {
- dev = ibmebus_register_device_node(dn);
+ rc = ibmebus_create_device(dn);
of_node_put(dn);
- rc = IS_ERR(dev) ? PTR_ERR(dev) : count;
} else {
printk(KERN_WARNING "%s: no such device node: %s\n",
__FUNCTION__, path);
@@ -416,7 +288,9 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
out:
kfree(path);
- return rc;
+ if (rc)
+ return rc;
+ return count;
}
static ssize_t ibmebus_store_remove(struct bus_type *bus,
@@ -431,7 +305,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
ibmebus_match_path))) {
- ibmebus_unregister_device(dev);
+ of_device_unregister(to_of_device(dev));
kfree(path);
return count;
@@ -451,8 +325,7 @@ static struct bus_attribute ibmebus_bus_attrs[] = {
};
struct bus_type ibmebus_bus_type = {
- .name = "ibmebus",
- .match = ibmebus_bus_match,
+ .uevent = of_device_uevent,
.dev_attrs = ibmebus_dev_attrs,
.bus_attrs = ibmebus_bus_attrs
};
@@ -464,9 +337,9 @@ static int __init ibmebus_bus_init(void)
printk(KERN_INFO "IBM eBus Device Driver\n");
- err = bus_register(&ibmebus_bus_type);
+ err = of_bus_type_init(&ibmebus_bus_type, "ibmebus");
if (err) {
- printk(KERN_ERR ":%s: failed to register IBM eBus.\n",
+ printk(KERN_ERR "%s: failed to register IBM eBus.\n",
__FUNCTION__);
return err;
}
@@ -480,6 +353,13 @@ static int __init ibmebus_bus_init(void)
return err;
}
+ err = ibmebus_create_devices(builtin_matches);
+ if (err) {
+ device_unregister(&ibmebus_bus_device);
+ bus_unregister(&ibmebus_bus_type);
+ return err;
+ }
+
return 0;
}
-__initcall(ibmebus_bus_init);
+postcore_initcall(ibmebus_bus_init);
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index e4ec6eee81a..306a6f75b6c 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -277,7 +277,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
dma_addr_t dma_next = 0, dma_addr;
unsigned long flags;
struct scatterlist *s, *outs, *segstart;
- int outcount, incount;
+ int outcount, incount, i;
unsigned long handle;
BUG_ON(direction == DMA_NONE);
@@ -297,7 +297,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
spin_lock_irqsave(&(tbl->it_lock), flags);
- for (s = outs; nelems; nelems--, s++) {
+ for_each_sg(sglist, s, nelems, i) {
unsigned long vaddr, npages, entry, slen;
slen = s->length;
@@ -341,7 +341,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
if (novmerge || (dma_addr != dma_next)) {
/* Can't merge: create a new segment */
segstart = s;
- outcount++; outs++;
+ outcount++;
+ outs = sg_next(outs);
DBG(" can't merge, new segment.\n");
} else {
outs->dma_length += s->length;
@@ -374,7 +375,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
* next entry of the sglist if we didn't fill the list completely
*/
if (outcount < incount) {
- outs++;
+ outs = sg_next(outs);
outs->dma_address = DMA_ERROR_CODE;
outs->dma_length = 0;
}
@@ -385,7 +386,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
return outcount;
failure:
- for (s = &sglist[0]; s <= outs; s++) {
+ for_each_sg(sglist, s, nelems, i) {
if (s->dma_length != 0) {
unsigned long vaddr, npages;
@@ -395,6 +396,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
s->dma_address = DMA_ERROR_CODE;
s->dma_length = 0;
}
+ if (s == outs)
+ break;
}
spin_unlock_irqrestore(&(tbl->it_lock), flags);
return 0;
@@ -404,6 +407,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
int nelems, enum dma_data_direction direction)
{
+ struct scatterlist *sg;
unsigned long flags;
BUG_ON(direction == DMA_NONE);
@@ -413,15 +417,16 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
spin_lock_irqsave(&(tbl->it_lock), flags);
+ sg = sglist;
while (nelems--) {
unsigned int npages;
- dma_addr_t dma_handle = sglist->dma_address;
+ dma_addr_t dma_handle = sg->dma_address;
- if (sglist->dma_length == 0)
+ if (sg->dma_length == 0)
break;
- npages = iommu_num_pages(dma_handle,sglist->dma_length);
+ npages = iommu_num_pages(dma_handle, sg->dma_length);
__iommu_free(tbl, dma_handle, npages);
- sglist++;
+ sg = sg_next(sg);
}
/* Flush/invalidate TLBs if necessary. As for iommu_free(), we
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 440f5a87271..5338e485571 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -38,6 +38,8 @@
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
int ret = 0;
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 8f3db32fac8..3388ad61999 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -7,8 +7,88 @@
#include <linux/slab.h>
#include <asm/errno.h>
+#include <asm/dcr.h>
#include <asm/of_device.h>
+static void of_device_make_bus_id(struct of_device *dev)
+{
+ static atomic_t bus_no_reg_magic;
+ struct device_node *node = dev->node;
+ char *name = dev->dev.bus_id;
+ const u32 *reg;
+ u64 addr;
+ int magic;
+
+ /*
+ * If it's a DCR based device, use 'd' for native DCRs
+ * and 'D' for MMIO DCRs.
+ */
+#ifdef CONFIG_PPC_DCR
+ reg = of_get_property(node, "dcr-reg", NULL);
+ if (reg) {
+#ifdef CONFIG_PPC_DCR_NATIVE
+ snprintf(name, BUS_ID_SIZE, "d%x.%s",
+ *reg, node->name);
+#else /* CONFIG_PPC_DCR_NATIVE */
+ addr = of_translate_dcr_address(node, *reg, NULL);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(name, BUS_ID_SIZE,
+ "D%llx.%s", (unsigned long long)addr,
+ node->name);
+ return;
+ }
+#endif /* !CONFIG_PPC_DCR_NATIVE */
+ }
+#endif /* CONFIG_PPC_DCR */
+
+ /*
+ * For MMIO, get the physical address
+ */
+ reg = of_get_property(node, "reg", NULL);
+ if (reg) {
+ addr = of_translate_address(node, reg);
+ if (addr != OF_BAD_ADDR) {
+ snprintf(name, BUS_ID_SIZE,
+ "%llx.%s", (unsigned long long)addr,
+ node->name);
+ return;
+ }
+ }
+
+ /*
+ * No BusID, use the node name and add a globally incremented
+ * counter (and pray...)
+ */
+ magic = atomic_add_return(1, &bus_no_reg_magic);
+ snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
+}
+
+struct of_device *of_device_alloc(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
+{
+ struct of_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->node = of_node_get(np);
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dev.parent = parent;
+ dev->dev.release = of_release_dev;
+ dev->dev.archdata.of_node = np;
+ dev->dev.archdata.numa_node = of_node_to_nid(np);
+
+ if (bus_id)
+ strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
+ else
+ of_device_make_bus_id(dev);
+
+ return dev;
+}
+EXPORT_SYMBOL(of_device_alloc);
+
ssize_t of_device_get_modalias(struct of_device *ofdev,
char *str, ssize_t len)
{
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index eca8ccc3fa1..aeaa20268ce 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -23,7 +23,6 @@
#include <linux/of_platform.h>
#include <asm/errno.h>
-#include <asm/dcr.h>
#include <asm/topology.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
@@ -53,8 +52,6 @@ static struct of_device_id of_default_bus_ids[] = {
{},
};
-static atomic_t bus_no_reg_magic;
-
struct bus_type of_platform_bus_type = {
.uevent = of_device_uevent,
};
@@ -87,89 +84,26 @@ void of_unregister_platform_driver(struct of_platform_driver *drv)
}
EXPORT_SYMBOL(of_unregister_platform_driver);
-static void of_platform_make_bus_id(struct of_device *dev)
-{
- struct device_node *node = dev->node;
- char *name = dev->dev.bus_id;
- const u32 *reg;
- u64 addr;
- int magic;
-
- /*
- * If it's a DCR based device, use 'd' for native DCRs
- * and 'D' for MMIO DCRs.
- */
-#ifdef CONFIG_PPC_DCR
- reg = of_get_property(node, "dcr-reg", NULL);
- if (reg) {
-#ifdef CONFIG_PPC_DCR_NATIVE
- snprintf(name, BUS_ID_SIZE, "d%x.%s",
- *reg, node->name);
-#else /* CONFIG_PPC_DCR_NATIVE */
- addr = of_translate_dcr_address(node, *reg, NULL);
- if (addr != OF_BAD_ADDR) {
- snprintf(name, BUS_ID_SIZE,
- "D%llx.%s", (unsigned long long)addr,
- node->name);
- return;
- }
-#endif /* !CONFIG_PPC_DCR_NATIVE */
- }
-#endif /* CONFIG_PPC_DCR */
-
- /*
- * For MMIO, get the physical address
- */
- reg = of_get_property(node, "reg", NULL);
- if (reg) {
- addr = of_translate_address(node, reg);
- if (addr != OF_BAD_ADDR) {
- snprintf(name, BUS_ID_SIZE,
- "%llx.%s", (unsigned long long)addr,
- node->name);
- return;
- }
- }
-
- /*
- * No BusID, use the node name and add a globally incremented
- * counter (and pray...)
- */
- magic = atomic_add_return(1, &bus_no_reg_magic);
- snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
-}
-
struct of_device* of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent)
{
struct of_device *dev;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = of_device_alloc(np, bus_id, parent);
if (!dev)
return NULL;
- dev->node = of_node_get(np);
dev->dma_mask = 0xffffffffUL;
- dev->dev.dma_mask = &dev->dma_mask;
- dev->dev.parent = parent;
dev->dev.bus = &of_platform_bus_type;
- dev->dev.release = of_release_dev;
- dev->dev.archdata.of_node = np;
- dev->dev.archdata.numa_node = of_node_to_nid(np);
/* We do not fill the DMA ops for platform devices by default.
* This is currently the responsibility of the platform code
* to do such, possibly using a device notifier
*/
- if (bus_id)
- strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
- else
- of_platform_make_bus_id(dev);
-
if (of_device_register(dev) != 0) {
- kfree(dev);
+ of_device_free(dev);
return NULL;
}
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 7949c203cb8..ea6ad7a2a7e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -149,10 +149,32 @@ void flush_altivec_to_thread(struct task_struct *tsk)
}
}
-int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+int dump_task_altivec(struct task_struct *tsk, elf_vrregset_t *vrregs)
{
- flush_altivec_to_thread(current);
- memcpy(vrregs, &current->thread.vr[0], sizeof(*vrregs));
+ /* ELF_NVRREG includes the VSCR and VRSAVE which we need to save
+ * separately, see below */
+ const int nregs = ELF_NVRREG - 2;
+ elf_vrreg_t *reg;
+ u32 *dest;
+
+ if (tsk == current)
+ flush_altivec_to_thread(tsk);
+
+ reg = (elf_vrreg_t *)vrregs;
+
+ /* copy the 32 vr registers */
+ memcpy(reg, &tsk->thread.vr[0], nregs * sizeof(*reg));
+ reg += nregs;
+
+ /* copy the vscr */
+ memcpy(reg, &tsk->thread.vscr, sizeof(*reg));
+ reg++;
+
+ /* vrsave is stored in the high 32bit slot of the final 128bits */
+ memset(reg, 0, sizeof(*reg));
+ dest = (u32 *)reg;
+ *dest = tsk->thread.vrsave;
+
return 1;
}
#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cf7732cdd6c..3e17d154d0d 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -505,10 +505,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = ptrace_set_debugreg(child, addr, data);
break;
- case PTRACE_DETACH:
- ret = ptrace_detach(child, data);
- break;
-
#ifdef CONFIG_PPC64
case PTRACE_GETREGS64:
#endif
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 62b7bf2f3ea..f2276593f41 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -286,7 +286,7 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf,
}
/* constructor for flash_block_cache */
-void rtas_block_ctor(void *ptr, struct kmem_cache *cache, unsigned long flags)
+void rtas_block_ctor(struct kmem_cache *cache, void *ptr)
{
memset(ptr, 0, RTAS_BLK_SIZE);
}
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 36c90ba2d31..2de00f870ed 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -413,16 +413,28 @@ void __init smp_setup_cpu_maps(void)
of_node_put(dn);
}
+ vdso_data->processorCount = num_present_cpus();
+#endif /* CONFIG_PPC64 */
+}
+
+/*
+ * Being that cpu_sibling_map is now a per_cpu array, then it cannot
+ * be initialized until the per_cpu areas have been created. This
+ * function is now called from setup_per_cpu_areas().
+ */
+void __init smp_setup_cpu_sibling_map(void)
+{
+#if defined(CONFIG_PPC64)
+ int cpu;
+
/*
* Do the sibling map; assume only two threads per processor.
*/
for_each_possible_cpu(cpu) {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
if (cpu_has_feature(CPU_FTR_SMT))
- cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
+ cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu));
}
-
- vdso_data->processorCount = num_present_cpus();
#endif /* CONFIG_PPC64 */
}
#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 008ab6823b0..ede77dbbd4d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -426,11 +426,14 @@ void __init setup_system(void)
printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
- printk("ppc64_caches.dcache_line_size = 0x%x\n",
- ppc64_caches.dline_size);
- printk("ppc64_caches.icache_line_size = 0x%x\n",
- ppc64_caches.iline_size);
- printk("htab_address = 0x%p\n", htab_address);
+ if (ppc64_caches.dline_size != 0x80)
+ printk("ppc64_caches.dcache_line_size = 0x%x\n",
+ ppc64_caches.dline_size);
+ if (ppc64_caches.iline_size != 0x80)
+ printk("ppc64_caches.icache_line_size = 0x%x\n",
+ ppc64_caches.iline_size);
+ if (htab_address)
+ printk("htab_address = 0x%p\n", htab_address);
printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
#if PHYSICAL_START > 0
printk("physical_start = 0x%x\n", PHYSICAL_START);
@@ -597,6 +600,9 @@ void __init setup_per_cpu_areas(void)
paca[i].data_offset = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
}
+
+ /* Now that per_cpu is setup, initialize cpu_sibling_map */
+ smp_setup_cpu_sibling_map();
}
#endif
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d30f08fa029..338950aeb6f 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -61,11 +61,11 @@ struct thread_info *secondary_ti;
cpumask_t cpu_possible_map = CPU_MASK_NONE;
cpumask_t cpu_online_map = CPU_MASK_NONE;
-cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
-EXPORT_SYMBOL(cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* SMP operations for this machine */
struct smp_ops_t *smp_ops;
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index bd85b5fd08c..4a4f5c6b560 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -41,10 +41,10 @@
#include <linux/compat.h>
#include <linux/ptrace.h>
#include <linux/elf.h>
+#include <linux/ipc.h>
#include <asm/ptrace.h>
#include <asm/types.h>
-#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/semaphore.h>
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index f85f402ceae..3b1d5dd6564 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -38,7 +38,6 @@
#include <linux/personality.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/semaphore.h>
#include <asm/syscalls.h>
#include <asm/time.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 9368da371f3..9eb3284deac 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -212,23 +212,44 @@ static u64 read_purr(void)
}
/*
+ * Read the SPURR on systems that have it, otherwise the purr
+ */
+static u64 read_spurr(u64 purr)
+{
+ if (cpu_has_feature(CPU_FTR_SPURR))
+ return mfspr(SPRN_SPURR);
+ return purr;
+}
+
+/*
* Account time for a transition between system, hard irq
* or soft irq state.
*/
void account_system_vtime(struct task_struct *tsk)
{
- u64 now, delta;
+ u64 now, nowscaled, delta, deltascaled;
unsigned long flags;
local_irq_save(flags);
now = read_purr();
delta = now - get_paca()->startpurr;
get_paca()->startpurr = now;
+ nowscaled = read_spurr(now);
+ deltascaled = nowscaled - get_paca()->startspurr;
+ get_paca()->startspurr = nowscaled;
if (!in_interrupt()) {
+ /* deltascaled includes both user and system time.
+ * Hence scale it based on the purr ratio to estimate
+ * the system time */
+ deltascaled = deltascaled * get_paca()->system_time /
+ (get_paca()->system_time + get_paca()->user_time);
delta += get_paca()->system_time;
get_paca()->system_time = 0;
}
account_system_time(tsk, 0, delta);
+ get_paca()->purrdelta = delta;
+ account_system_time_scaled(tsk, deltascaled);
+ get_paca()->spurrdelta = deltascaled;
local_irq_restore(flags);
}
@@ -240,11 +261,17 @@ void account_system_vtime(struct task_struct *tsk)
*/
void account_process_vtime(struct task_struct *tsk)
{
- cputime_t utime;
+ cputime_t utime, utimescaled;
utime = get_paca()->user_time;
get_paca()->user_time = 0;
account_user_time(tsk, utime);
+
+ /* Estimate the scaled utime by scaling the real utime based
+ * on the last spurr to purr ratio */
+ utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta;
+ get_paca()->spurrdelta = get_paca()->purrdelta = 0;
+ account_user_time_scaled(tsk, utimescaled);
}
static void account_process_time(struct pt_regs *regs)
@@ -266,6 +293,7 @@ struct cpu_purr_data {
int initialized; /* thread is running */
u64 tb; /* last TB value read */
u64 purr; /* last PURR value read */
+ u64 spurr; /* last SPURR value read */
};
/*
@@ -829,7 +857,7 @@ static void register_decrementer_clockevent(int cpu)
*dec = decrementer_clockevent;
dec->cpumask = cpumask_of_cpu(cpu);
- printk(KERN_ERR "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
+ printk(KERN_INFO "clockevent: %s mult[%lx] shift[%d] cpu[%d]\n",
dec->name, dec->mult, dec->shift, cpu);
clockevents_register_device(dec);
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 26e138c4ce1..9352ab5200e 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -1,130 +1,147 @@
-
/*
* This is the infamous ld script for the 32 bits vdso
* library
*/
#include <asm/vdso.h>
-/* Default link addresses for the vDSOs */
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
SECTIONS
{
- . = VDSO32_LBASE + SIZEOF_HEADERS;
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
-
- .note : { *(.note.*) } :text :note
-
- . = ALIGN (16);
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- }
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
-
- . = ALIGN(8);
- __ftr_fixup : {
- *(__ftr_fixup)
- }
+ . = VDSO32_LBASE + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN(16);
+ .text : {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ }
+ PROVIDE(__etext = .);
+ PROVIDE(_etext = .);
+ PROVIDE(etext = .);
+
+ . = ALIGN(8);
+ __ftr_fixup : { *(__ftr_fixup) }
#ifdef CONFIG_PPC64
- . = ALIGN(8);
- __fw_ftr_fixup : {
- *(__fw_ftr_fixup)
- }
+ . = ALIGN(8);
+ __fw_ftr_fixup : { *(__fw_ftr_fixup) }
#endif
- /* Other stuff is appended to the text segment: */
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
-
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
- .gcc_except_table : { *(.gcc_except_table) }
- .fixup : { *(.fixup) }
-
- .dynamic : { *(.dynamic) } :text :dynamic
- .got : { *(.got) }
- .plt : { *(.plt) }
-
- _end = .;
- __end = .;
- PROVIDE (end = .);
-
-
- /* Stabs debugging sections are here too
- */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
-
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
-
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
-
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
-
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-
- /DISCARD/ : { *(.note.GNU-stack) }
- /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.* .sdata*) }
- /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) }
+ /*
+ * Other stuff is appended to the text segment:
+ */
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+ .gcc_except_table : { *(.gcc_except_table) }
+ .fixup : { *(.fixup) }
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+ .got : { *(.got) }
+ .plt : { *(.plt) }
+
+ _end = .;
+ __end = .;
+ PROVIDE(end = .);
+
+ /*
+ * Stabs debugging sections are here too.
+ */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+
+ /*
+ * DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to the beginning
+ * of the section so we begin them at 0.
+ */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
}
+/*
+ * Very old versions of ld do not recognize this name token; use the constant.
+ */
+#define PT_GNU_EH_FRAME 0x6474e550
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
PHDRS
{
- text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
- note PT_NOTE FLAGS(4); /* PF_R */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
+ text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
}
-
/*
* This controls what symbols we export from the DSO.
*/
VERSION
{
- VDSO_VERSION_STRING {
- global:
- __kernel_datapage_offset; /* Has to be there for the kernel to find */
- __kernel_get_syscall_map;
- __kernel_gettimeofday;
- __kernel_clock_gettime;
- __kernel_clock_getres;
- __kernel_get_tbfreq;
- __kernel_sync_dicache;
- __kernel_sync_dicache_p5;
- __kernel_sigtramp32;
- __kernel_sigtramp_rt32;
- local: *;
- };
+ VDSO_VERSION_STRING {
+ global:
+ /*
+ * Has to be there for the kernel to find
+ */
+ __kernel_datapage_offset;
+
+ __kernel_get_syscall_map;
+ __kernel_gettimeofday;
+ __kernel_clock_gettime;
+ __kernel_clock_getres;
+ __kernel_get_tbfreq;
+ __kernel_sync_dicache;
+ __kernel_sync_dicache_p5;
+ __kernel_sigtramp32;
+ __kernel_sigtramp_rt32;
+
+ local: *;
+ };
}
diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S
index 17a83fa6dc5..59eb59bb408 100644
--- a/arch/powerpc/kernel/vdso64/sigtramp.S
+++ b/arch/powerpc/kernel/vdso64/sigtramp.S
@@ -134,13 +134,16 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
9:
/* This is where the pt_regs pointer can be found on the stack. */
-#define PTREGS 128+168+56
+#define PTREGS 128+168+56
/* Size of regs. */
-#define RSIZE 8
+#define RSIZE 8
+
+/* Size of CR reg in DWARF unwind info. */
+#define CRSIZE 4
/* This is the offset of the VMX reg pointer. */
-#define VREGS 48*RSIZE+33*8
+#define VREGS 48*RSIZE+33*8
/* Describe where general purpose regs are saved. */
#define EH_FRAME_GEN \
@@ -178,7 +181,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
rsave (31, 31*RSIZE); \
rsave (67, 32*RSIZE); /* ap, used as temp for nip */ \
rsave (65, 36*RSIZE); /* lr */ \
- rsave (70, 38*RSIZE) /* cr */
+ rsave (70, 38*RSIZE + (RSIZE - CRSIZE)) /* cr */
/* Describe where the FP regs are saved. */
#define EH_FRAME_FP \
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index 2d70f35d50b..932b3fdb34b 100644
--- a/arch/powerpc/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -10,100 +10,114 @@ ENTRY(_start)
SECTIONS
{
- . = VDSO64_LBASE + SIZEOF_HEADERS;
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
-
- .note : { *(.note.*) } :text :note
-
- . = ALIGN (16);
- .text :
- {
- *(.text .stub .text.* .gnu.linkonce.t.*)
- *(.sfpr .glink)
- } :text
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
-
- . = ALIGN(8);
- __ftr_fixup : {
- *(__ftr_fixup)
- }
-
- . = ALIGN(8);
- __fw_ftr_fixup : {
- *(__fw_ftr_fixup)
- }
-
- /* Other stuff is appended to the text segment: */
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .rodata1 : { *(.rodata1) }
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
- .gcc_except_table : { *(.gcc_except_table) }
-
- .opd ALIGN(8) : { KEEP (*(.opd)) }
- .got ALIGN(8) : { *(.got .toc) }
- .rela.dyn ALIGN(8) : { *(.rela.dyn) }
-
- .dynamic : { *(.dynamic) } :text :dynamic
-
- _end = .;
- PROVIDE (end = .);
-
- /* Stabs debugging sections are here too
- */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sectio/ns.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-
- /DISCARD/ : { *(.note.GNU-stack) }
- /DISCARD/ : { *(.branch_lt) }
- /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.*) }
- /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) }
+ . = VDSO64_LBASE + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN(16);
+ .text : {
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ *(.sfpr .glink)
+ } :text
+ PROVIDE(__etext = .);
+ PROVIDE(_etext = .);
+ PROVIDE(etext = .);
+
+ . = ALIGN(8);
+ __ftr_fixup : { *(__ftr_fixup) }
+
+ . = ALIGN(8);
+ __fw_ftr_fixup : { *(__fw_ftr_fixup) }
+
+ /*
+ * Other stuff is appended to the text segment:
+ */
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+ .gcc_except_table : { *(.gcc_except_table) }
+
+ .opd ALIGN(8) : { KEEP (*(.opd)) }
+ .got ALIGN(8) : { *(.got .toc) }
+ .rela.dyn ALIGN(8) : { *(.rela.dyn) }
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ _end = .;
+ PROVIDE(end = .);
+
+ /*
+ * Stabs debugging sections are here too.
+ */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+
+ /*
+ * DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to the beginning
+ * of the section so we begin them at 0.
+ */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.branch_lt)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
}
+/*
+ * Very old versions of ld do not recognize this name token; use the constant.
+ */
+#define PT_GNU_EH_FRAME 0x6474e550
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
PHDRS
{
- text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
- note PT_NOTE FLAGS(4); /* PF_R */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
+ text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
}
/*
@@ -111,17 +125,22 @@ PHDRS
*/
VERSION
{
- VDSO_VERSION_STRING {
- global:
- __kernel_datapage_offset; /* Has to be there for the kernel to find */
- __kernel_get_syscall_map;
- __kernel_gettimeofday;
- __kernel_clock_gettime;
- __kernel_clock_getres;
- __kernel_get_tbfreq;
- __kernel_sync_dicache;
- __kernel_sync_dicache_p5;
- __kernel_sigtramp_rt64;
- local: *;
- };
+ VDSO_VERSION_STRING {
+ global:
+ /*
+ * Has to be there for the kernel to find
+ */
+ __kernel_datapage_offset;
+
+ __kernel_get_syscall_map;
+ __kernel_gettimeofday;
+ __kernel_clock_gettime;
+ __kernel_clock_getres;
+ __kernel_get_tbfreq;
+ __kernel_sync_dicache;
+ __kernel_sync_dicache_p5;
+ __kernel_sigtramp_rt64;
+
+ local: *;
+ };
}
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 65d492e316a..4bb023f4c86 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -14,7 +14,6 @@ endif
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o string.o
-obj-$(CONFIG_QUICC_ENGINE) += rheap.o
obj-$(CONFIG_XMON) += sstep.o
obj-$(CONFIG_KPROBES) += sstep.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
@@ -23,6 +22,4 @@ ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_SMP) += locks.o
endif
-# Temporary hack until we have migrated to asm-powerpc
-obj-$(CONFIG_8xx) += rheap.o
-obj-$(CONFIG_CPM2) += rheap.o
+obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
index ada5b42dd23..22c3b4f53de 100644
--- a/arch/powerpc/lib/rheap.c
+++ b/arch/powerpc/lib/rheap.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/slab.h>
@@ -275,6 +276,7 @@ rh_info_t *rh_create(unsigned int alignment)
return info;
}
+EXPORT_SYMBOL_GPL(rh_create);
/*
* Destroy a dynamically created remote heap. Deallocate only if the areas
@@ -288,6 +290,7 @@ void rh_destroy(rh_info_t * info)
if ((info->flags & RHIF_STATIC_INFO) == 0)
kfree(info);
}
+EXPORT_SYMBOL_GPL(rh_destroy);
/*
* Initialize in place a remote heap info block. This is needed to support
@@ -320,6 +323,7 @@ void rh_init(rh_info_t * info, unsigned int alignment, int max_blocks,
for (i = 0, blk = block; i < max_blocks; i++, blk++)
list_add(&blk->list, &info->empty_list);
}
+EXPORT_SYMBOL_GPL(rh_init);
/* Attach a free memory region, coalesces regions if adjuscent */
int rh_attach_region(rh_info_t * info, unsigned long start, int size)
@@ -360,6 +364,7 @@ int rh_attach_region(rh_info_t * info, unsigned long start, int size)
return 0;
}
+EXPORT_SYMBOL_GPL(rh_attach_region);
/* Detatch given address range, splits free block if needed. */
unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size)
@@ -428,6 +433,7 @@ unsigned long rh_detach_region(rh_info_t * info, unsigned long start, int size)
return s;
}
+EXPORT_SYMBOL_GPL(rh_detach_region);
/* Allocate a block of memory at the specified alignment. The value returned
* is an offset into the buffer initialized by rh_init(), or a negative number
@@ -502,6 +508,7 @@ unsigned long rh_alloc_align(rh_info_t * info, int size, int alignment, const ch
return start;
}
+EXPORT_SYMBOL_GPL(rh_alloc_align);
/* Allocate a block of memory at the default alignment. The value returned is
* an offset into the buffer initialized by rh_init(), or a negative number if
@@ -511,6 +518,7 @@ unsigned long rh_alloc(rh_info_t * info, int size, const char *owner)
{
return rh_alloc_align(info, size, info->alignment, owner);
}
+EXPORT_SYMBOL_GPL(rh_alloc);
/* Allocate a block of memory at the given offset, rounded up to the default
* alignment. The value returned is an offset into the buffer initialized by
@@ -594,6 +602,7 @@ unsigned long rh_alloc_fixed(rh_info_t * info, unsigned long start, int size, co
return start;
}
+EXPORT_SYMBOL_GPL(rh_alloc_fixed);
/* Deallocate the memory previously allocated by one of the rh_alloc functions.
* The return value is the size of the deallocated block, or a negative number
@@ -626,6 +635,7 @@ int rh_free(rh_info_t * info, unsigned long start)
return size;
}
+EXPORT_SYMBOL_GPL(rh_free);
int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
{
@@ -663,6 +673,7 @@ int rh_get_stats(rh_info_t * info, int what, int max_stats, rh_stats_t * stats)
return nr;
}
+EXPORT_SYMBOL_GPL(rh_get_stats);
int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner)
{
@@ -687,6 +698,7 @@ int rh_set_owner(rh_info_t * info, unsigned long start, const char *owner)
return size;
}
+EXPORT_SYMBOL_GPL(rh_set_owner);
void rh_dump(rh_info_t * info)
{
@@ -722,6 +734,7 @@ void rh_dump(rh_info_t * info)
st[i].size, st[i].owner != NULL ? st[i].owner : "");
printk(KERN_INFO "\n");
}
+EXPORT_SYMBOL_GPL(rh_dump);
void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
{
@@ -729,3 +742,5 @@ void rh_dump_blk(rh_info_t * info, rh_block_t * blk)
"blk @0x%p: 0x%lx-0x%lx (%u)\n",
blk, blk->start, blk->start + blk->size, blk->size);
}
+EXPORT_SYMBOL_GPL(rh_dump_blk);
+
diff --git a/arch/powerpc/math-emu/math.c b/arch/powerpc/math-emu/math.c
index 69058b2873d..381306bb159 100644
--- a/arch/powerpc/math-emu/math.c
+++ b/arch/powerpc/math-emu/math.c
@@ -407,11 +407,16 @@ do_mathemu(struct pt_regs *regs)
case XE:
idx = (insn >> 16) & 0x1f;
- if (!idx)
- goto illegal;
-
op0 = (void *)&current->thread.fpr[(insn >> 21) & 0x1f];
- op1 = (void *)(regs->gpr[idx] + regs->gpr[(insn >> 11) & 0x1f]);
+ if (!idx) {
+ if (((insn >> 1) & 0x3ff) == STFIWX)
+ op1 = (void *)(regs->gpr[(insn >> 11) & 0x1f]);
+ else
+ goto illegal;
+ } else {
+ op1 = (void *)(regs->gpr[idx] + regs->gpr[(insn >> 11) & 0x1f]);
+ }
+
break;
case XEU:
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 611ad084b7e..c78dc912411 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -209,9 +209,10 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node,
if (prop[0] == 40) {
DBG("1T segment support detected\n");
cur_cpu_spec->cpu_features |= CPU_FTR_1T_SEGMENT;
+ return 1;
}
- return 1;
}
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_NO_SLBIE_B;
return 0;
}
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 08f0d9ff771..71efb38d599 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -526,7 +526,7 @@ repeat:
return err;
}
-static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
+static void zero_ctor(struct kmem_cache *cache, void *addr)
{
memset(addr, 0, kmem_cache_size(cache));
}
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index fa90f6561b9..d9c82d3d648 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -142,7 +142,7 @@ static int __init setup_kcore(void)
module_init(setup_kcore);
#endif
-static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
+static void zero_ctor(struct kmem_cache *cache, void *addr)
{
memset(addr, 0, kmem_cache_size(cache));
}
@@ -183,3 +183,71 @@ void pgtable_cache_init(void)
zero_ctor);
}
}
+
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+/*
+ * Given an address within the vmemmap, determine the pfn of the page that
+ * represents the start of the section it is within. Note that we have to
+ * do this by hand as the proffered address may not be correctly aligned.
+ * Subtraction of non-aligned pointers produces undefined results.
+ */
+unsigned long __meminit vmemmap_section_start(unsigned long page)
+{
+ unsigned long offset = page - ((unsigned long)(vmemmap));
+
+ /* Return the pfn of the start of the section. */
+ return (offset / sizeof(struct page)) & PAGE_SECTION_MASK;
+}
+
+/*
+ * Check if this vmemmap page is already initialised. If any section
+ * which overlaps this vmemmap page is initialised then this page is
+ * initialised already.
+ */
+int __meminit vmemmap_populated(unsigned long start, int page_size)
+{
+ unsigned long end = start + page_size;
+
+ for (; start < end; start += (PAGES_PER_SECTION * sizeof(struct page)))
+ if (pfn_valid(vmemmap_section_start(start)))
+ return 1;
+
+ return 0;
+}
+
+int __meminit vmemmap_populate(struct page *start_page,
+ unsigned long nr_pages, int node)
+{
+ unsigned long mode_rw;
+ unsigned long start = (unsigned long)start_page;
+ unsigned long end = (unsigned long)(start_page + nr_pages);
+ unsigned long page_size = 1 << mmu_psize_defs[mmu_linear_psize].shift;
+
+ mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
+
+ /* Align to the page size of the linear mapping. */
+ start = _ALIGN_DOWN(start, page_size);
+
+ for (; start < end; start += page_size) {
+ int mapped;
+ void *p;
+
+ if (vmemmap_populated(start, page_size))
+ continue;
+
+ p = vmemmap_alloc_block(page_size, node);
+ if (!p)
+ return -ENOMEM;
+
+ printk(KERN_WARNING "vmemmap %08lx allocated at %p, "
+ "physical %08lx.\n", start, p, __pa(p));
+
+ mapped = htab_bolt_mapping(start, start + page_size,
+ __pa(p), mode_rw, mmu_linear_psize,
+ mmu_kernel_ssize);
+ BUG_ON(mapped < 0);
+ }
+
+ return 0;
+}
+#endif
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 32dcfc9b008..81eb96ec13b 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -129,51 +129,6 @@ int __devinit arch_add_memory(int nid, u64 start, u64 size)
return __add_pages(zone, start_pfn, nr_pages);
}
-/*
- * First pass at this code will check to determine if the remove
- * request is within the RMO. Do not allow removal within the RMO.
- */
-int __devinit remove_memory(u64 start, u64 size)
-{
- struct zone *zone;
- unsigned long start_pfn, end_pfn, nr_pages;
-
- start_pfn = start >> PAGE_SHIFT;
- nr_pages = size >> PAGE_SHIFT;
- end_pfn = start_pfn + nr_pages;
-
- printk("%s(): Attempting to remove memoy in range "
- "%lx to %lx\n", __func__, start, start+size);
- /*
- * check for range within RMO
- */
- zone = page_zone(pfn_to_page(start_pfn));
-
- printk("%s(): memory will be removed from "
- "the %s zone\n", __func__, zone->name);
-
- /*
- * not handling removing memory ranges that
- * overlap multiple zones yet
- */
- if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages))
- goto overlap;
-
- /* make sure it is NOT in RMO */
- if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) {
- printk("%s(): range to be removed must NOT be in RMO!\n",
- __func__);
- goto in_rmo;
- }
-
- return __remove_pages(zone, start_pfn, nr_pages);
-
-overlap:
- printk("%s(): memory range to be removed overlaps "
- "multiple zones!!!\n", __func__);
-in_rmo:
- return -1;
-}
#endif /* CONFIG_MEMORY_HOTPLUG */
void show_mem(void)
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 6c164cec9d2..bbd2c512ee0 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -157,7 +157,8 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
unsigned long stack = KSTK_ESP(tsk);
unsigned long unmapped_base;
- if (offset <= SLB_CACHE_ENTRIES) {
+ if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
+ offset <= SLB_CACHE_ENTRIES) {
int i;
asm volatile("isync" : : : "memory");
for (i = 0; i < offset; i++) {
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 319826ef164..ad928edafb0 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -34,7 +34,7 @@
#include <asm/mmu.h>
#include <asm/spu.h>
-static spinlock_t slice_convert_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(slice_convert_lock);
#ifdef DEBUG
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index f26afcd4175..ffa14aff524 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -1,5 +1,5 @@
#include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/mpc52xx.h>
@@ -18,6 +18,8 @@ static void __iomem *sram;
static const int sram_size = 0x4000; /* 16 kBytes */
static void __iomem *mbar;
+static suspend_state_t lite5200_pm_target_state;
+
static int lite5200_pm_valid(suspend_state_t state)
{
switch (state) {
@@ -29,13 +31,22 @@ static int lite5200_pm_valid(suspend_state_t state)
}
}
-static int lite5200_pm_prepare(suspend_state_t state)
+static int lite5200_pm_set_target(suspend_state_t state)
+{
+ if (lite5200_pm_valid(state)) {
+ lite5200_pm_target_state = state;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int lite5200_pm_prepare(void)
{
/* deep sleep? let mpc52xx code handle that */
- if (state == PM_SUSPEND_STANDBY)
- return mpc52xx_pm_prepare(state);
+ if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+ return mpc52xx_pm_prepare();
- if (state != PM_SUSPEND_MEM)
+ if (lite5200_pm_target_state != PM_SUSPEND_MEM)
return -EINVAL;
/* map registers */
@@ -190,17 +201,16 @@ static int lite5200_pm_enter(suspend_state_t state)
return 0;
}
-static int lite5200_pm_finish(suspend_state_t state)
+static void lite5200_pm_finish(void)
{
/* deep sleep? let mpc52xx code handle that */
- if (state == PM_SUSPEND_STANDBY) {
- return mpc52xx_pm_finish(state);
- }
- return 0;
+ if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
+ mpc52xx_pm_finish();
}
-static struct pm_ops lite5200_pm_ops = {
+static struct platform_suspend_ops lite5200_pm_ops = {
.valid = lite5200_pm_valid,
+ .set_target = lite5200_pm_set_target,
.prepare = lite5200_pm_prepare,
.enter = lite5200_pm_enter,
.finish = lite5200_pm_finish,
@@ -208,6 +218,6 @@ static struct pm_ops lite5200_pm_ops = {
int __init lite5200_pm_init(void)
{
- pm_set_ops(&lite5200_pm_ops);
+ suspend_set_ops(&lite5200_pm_ops);
return 0;
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index ee2e7639c63..7ffa7babf25 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -1,5 +1,5 @@
#include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/io.h>
#include <asm/time.h>
#include <asm/cacheflush.h>
@@ -57,11 +57,8 @@ int mpc52xx_set_wakeup_gpio(u8 pin, u8 level)
return 0;
}
-int mpc52xx_pm_prepare(suspend_state_t state)
+int mpc52xx_pm_prepare(void)
{
- if (state != PM_SUSPEND_STANDBY)
- return -EINVAL;
-
/* map the whole register space */
mbar = mpc52xx_find_and_map("mpc5200");
if (!mbar) {
@@ -166,18 +163,16 @@ int mpc52xx_pm_enter(suspend_state_t state)
return 0;
}
-int mpc52xx_pm_finish(suspend_state_t state)
+void mpc52xx_pm_finish(void)
{
/* call board resume code */
if (mpc52xx_suspend.board_resume_finish)
mpc52xx_suspend.board_resume_finish(mbar);
iounmap(mbar);
-
- return 0;
}
-static struct pm_ops mpc52xx_pm_ops = {
+static struct platform_suspend_ops mpc52xx_pm_ops = {
.valid = mpc52xx_pm_valid,
.prepare = mpc52xx_pm_prepare,
.enter = mpc52xx_pm_enter,
@@ -186,6 +181,6 @@ static struct pm_ops mpc52xx_pm_ops = {
int __init mpc52xx_pm_init(void)
{
- pm_set_ops(&mpc52xx_pm_ops);
+ suspend_set_ops(&mpc52xx_pm_ops);
return 0;
}
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index cc6013ffc29..229d355ed86 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -117,7 +117,7 @@ config RTAS_FLASH
config PPC_PMI
tristate "Support for PMI"
- depends PPC_IBM_CELL_BLADE
+ depends on PPC_IBM_CELL_BLADE
help
PMI (Platform Management Interrupt) is a way to
communicate with the BMC (Baseboard Mangement Controller).
@@ -264,6 +264,7 @@ config TAU_AVERAGE
config QUICC_ENGINE
bool
+ select PPC_LIB_RHEAP
help
The QUICC Engine (QE) is a new generation of communications
coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
@@ -274,6 +275,7 @@ config CPM2
bool
default n
select CPM
+ select PPC_LIB_RHEAP
help
The CPM2 (Communications Processor Module) is a coprocessor on
embedded CPUs made by Freescale. Selecting this option means that
@@ -313,4 +315,6 @@ config FSL_ULI1575
config CPM
bool
+source "arch/powerpc/sysdev/bestcomm/Kconfig"
+
endmenu
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 4c315be2501..3c7325ec36e 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -37,6 +37,7 @@ config PPC_8xx
select FSL_SOC
select 8xx
select WANT_DEVICE_TREE
+ select PPC_LIB_RHEAP
config 40x
bool "AMCC 40x"
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 1245b2f517b..095988f13bf 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -77,12 +77,7 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
{
pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
- dcr_write(msic->dcr_host, msic->dcr_host.base + dcr_n, val);
-}
-
-static u32 msic_dcr_read(struct axon_msic *msic, unsigned int dcr_n)
-{
- return dcr_read(msic->dcr_host, msic->dcr_host.base + dcr_n);
+ dcr_write(msic->dcr_host, dcr_n, val);
}
static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
@@ -91,7 +86,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
u32 write_offset, msi;
int idx;
- write_offset = msic_dcr_read(msic, MSIC_WRITE_OFFSET_REG);
+ write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
/* write_offset doesn't wrap properly, so we have to mask it */
@@ -306,7 +301,7 @@ static int axon_msi_notify_reboot(struct notifier_block *nb,
list_for_each_entry(msic, &axon_msic_list, list) {
pr_debug("axon_msi: disabling %s\n",
msic->irq_host->of_node->full_name);
- tmp = msic_dcr_read(msic, MSIC_CTRL_REG);
+ tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
}
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
index 5123e9d4164..13d5a87f13b 100644
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -117,7 +117,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->cur = cbe_freqs[cur_pmode].frequency;
#ifdef CONFIG_SMP
- policy->cpus = cpu_sibling_map[policy->cpu];
+ policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif
cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 11098747d09..0966d093db4 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -68,7 +68,7 @@ spufs_destroy_inode(struct inode *inode)
}
static void
-spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags)
+spufs_init_once(struct kmem_cache *cachep, void *p)
{
struct spufs_inode_info *ei = p;
diff --git a/arch/powerpc/platforms/iseries/htab.c b/arch/powerpc/platforms/iseries/htab.c
index 15a7097e5dd..f99c6c4b698 100644
--- a/arch/powerpc/platforms/iseries/htab.c
+++ b/arch/powerpc/platforms/iseries/htab.c
@@ -39,9 +39,9 @@ static inline void iSeries_hunlock(unsigned long slot)
spin_unlock(&iSeries_hlocks[(slot >> 4) & 0x3f]);
}
-long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
+static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long pa, unsigned long rflags,
- unsigned long vflags, int psize)
+ unsigned long vflags, int psize, int ssize)
{
long slot;
struct hash_pte lhpte;
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 910b00b4703..d6435b03971 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -2,7 +2,7 @@
* Legacy iSeries specific vio initialisation
* that needs to be built in (not a module).
*
- * © Copyright 2007 IBM Corporation
+ * © Copyright 2007 IBM Corporation
* Author: Stephen Rothwell
* Some parts collected from various other files
*
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 5ddf40a66ae..3a5d112af5e 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -37,6 +37,10 @@
#include <asm/time.h>
#include <asm/of_platform.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
#include "pasemi.h"
/* SDC reset register, must be pre-mapped at reset time */
@@ -308,7 +312,57 @@ static void __init pas_init_early(void)
iommu_init_early_pasemi();
}
+#ifdef CONFIG_PCMCIA
+static int pcmcia_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+ struct device *parent;
+ struct pcmcia_device *pdev = to_pcmcia_dev(dev);
+
+ /* We are only intereted in device addition */
+ if (action != BUS_NOTIFY_ADD_DEVICE)
+ return 0;
+
+ parent = pdev->socket->dev.parent;
+
+ /* We know electra_cf devices will always have of_node set, since
+ * electra_cf is an of_platform driver.
+ */
+ if (!parent->archdata.of_node)
+ return 0;
+
+ if (!of_device_is_compatible(parent->archdata.of_node, "electra-cf"))
+ return 0;
+
+ /* We use the direct ops for localbus */
+ dev->archdata.dma_ops = &dma_direct_ops;
+
+ return 0;
+}
+
+static struct notifier_block pcmcia_notifier = {
+ .notifier_call = pcmcia_notify,
+};
+
+static inline void pasemi_pcmcia_init(void)
+{
+ extern struct bus_type pcmcia_bus_type;
+
+ bus_register_notifier(&pcmcia_bus_type, &pcmcia_notifier);
+}
+
+#else
+
+static inline void pasemi_pcmcia_init(void)
+{
+}
+
+#endif
+
+
static struct of_device_id pasemi_bus_ids[] = {
+ { .type = "localbus", },
{ .type = "sdc", },
{},
};
@@ -318,6 +372,8 @@ static int __init pasemi_publish_devices(void)
if (!machine_is(pasemi))
return 0;
+ pasemi_pcmcia_init();
+
/* Publish OF platform devices for SDC and other non-PCI devices */
of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 190ff4b59a5..07e64b48e7f 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -616,17 +616,18 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
}
}
-static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction)
{
#if defined(CONFIG_PS3_DYNAMIC_DMA)
BUG_ON("do");
return -EPERM;
#else
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
+ struct scatterlist *sg;
int i;
- for (i = 0; i < nents; i++, sg++) {
+ 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);
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 1a6f5641ebc..99a77d743d4 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
obj-$(CONFIG_FSL_PCI) += fsl_pci.o
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
+obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
mv64x60_udbg.o
diff --git a/arch/powerpc/sysdev/bestcomm/Kconfig b/arch/powerpc/sysdev/bestcomm/Kconfig
new file mode 100644
index 00000000000..57cc5656256
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/Kconfig
@@ -0,0 +1,39 @@
+#
+# Kconfig options for Bestcomm
+#
+
+config PPC_BESTCOMM
+ tristate "Bestcomm DMA engine support"
+ depends on PPC_MPC52xx
+ default n
+ select PPC_LIB_RHEAP
+ help
+ BestComm is the name of the communication coprocessor found
+ on the Freescale MPC5200 family of processor. It's usage is
+ optionnal for some drivers (like ATA), but required for
+ others (like FEC).
+
+ If you want to use drivers that require DMA operations,
+ answer Y or M. Otherwise say N.
+
+config PPC_BESTCOMM_ATA
+ tristate "Bestcomm ATA task support"
+ depends on PPC_BESTCOMM
+ default n
+ help
+ This option enables the support for the ATA task.
+
+config PPC_BESTCOMM_FEC
+ tristate "Bestcomm FEC tasks support"
+ depends on PPC_BESTCOMM
+ default n
+ help
+ This option enables the support for the FEC tasks.
+
+config PPC_BESTCOMM_GEN_BD
+ tristate "Bestcomm GenBD tasks support"
+ depends on PPC_BESTCOMM
+ default n
+ help
+ This option enables the support for the GenBD tasks.
+
diff --git a/arch/powerpc/sysdev/bestcomm/Makefile b/arch/powerpc/sysdev/bestcomm/Makefile
new file mode 100644
index 00000000000..aed2df2a658
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for BestComm & co
+#
+
+bestcomm-core-objs := bestcomm.o sram.o
+bestcomm-ata-objs := ata.o bcom_ata_task.o
+bestcomm-fec-objs := fec.o bcom_fec_rx_task.o bcom_fec_tx_task.o
+bestcomm-gen-bd-objs := gen_bd.o bcom_gen_bd_rx_task.o bcom_gen_bd_tx_task.o
+
+obj-$(CONFIG_PPC_BESTCOMM) += bestcomm-core.o
+obj-$(CONFIG_PPC_BESTCOMM_ATA) += bestcomm-ata.o
+obj-$(CONFIG_PPC_BESTCOMM_FEC) += bestcomm-fec.o
+obj-$(CONFIG_PPC_BESTCOMM_GEN_BD) += bestcomm-gen-bd.o
+
diff --git a/arch/powerpc/sysdev/bestcomm/ata.c b/arch/powerpc/sysdev/bestcomm/ata.c
new file mode 100644
index 00000000000..1f5258fb38c
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/ata.c
@@ -0,0 +1,154 @@
+/*
+ * Bestcomm ATA task driver
+ *
+ *
+ * Patterned after bestcomm/fec.c by Dale Farnsworth <dfarnsworth@mvista.com>
+ * 2003-2004 (c) MontaVista, Software, Inc.
+ *
+ * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2006 Freescale - John Rigby
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/io.h>
+
+#include "bestcomm.h"
+#include "bestcomm_priv.h"
+#include "ata.h"
+
+
+/* ======================================================================== */
+/* Task image/var/inc */
+/* ======================================================================== */
+
+/* ata task image */
+extern u32 bcom_ata_task[];
+
+/* ata task vars that need to be set before enabling the task */
+struct bcom_ata_var {
+ u32 enable; /* (u16*) address of task's control register */
+ u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
+ u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
+ u32 bd_start; /* (struct bcom_bd*) current bd */
+ u32 buffer_size; /* size of receive buffer */
+};
+
+/* ata task incs that need to be set before enabling the task */
+struct bcom_ata_inc {
+ u16 pad0;
+ s16 incr_bytes;
+ u16 pad1;
+ s16 incr_dst;
+ u16 pad2;
+ s16 incr_src;
+};
+
+
+/* ======================================================================== */
+/* Task support code */
+/* ======================================================================== */
+
+struct bcom_task *
+bcom_ata_init(int queue_len, int maxbufsize)
+{
+ struct bcom_task *tsk;
+ struct bcom_ata_var *var;
+ struct bcom_ata_inc *inc;
+
+ tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0);
+ if (!tsk)
+ return NULL;
+
+ tsk->flags = BCOM_FLAGS_NONE;
+
+ bcom_ata_reset_bd(tsk);
+
+ var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum);
+ inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
+
+ if (bcom_load_image(tsk->tasknum, bcom_ata_task)) {
+ bcom_task_free(tsk);
+ return NULL;
+ }
+
+ var->enable = bcom_eng->regs_base +
+ offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
+ var->bd_base = tsk->bd_pa;
+ var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
+ var->bd_start = tsk->bd_pa;
+ var->buffer_size = maxbufsize;
+
+ /* Configure some stuff */
+ bcom_set_task_pragma(tsk->tasknum, BCOM_ATA_PRAGMA);
+ bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
+
+ out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX], BCOM_IPR_ATA_RX);
+ out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX], BCOM_IPR_ATA_TX);
+
+ out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
+
+ return tsk;
+}
+EXPORT_SYMBOL_GPL(bcom_ata_init);
+
+void bcom_ata_rx_prepare(struct bcom_task *tsk)
+{
+ struct bcom_ata_inc *inc;
+
+ inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
+
+ inc->incr_bytes = -(s16)sizeof(u32);
+ inc->incr_src = 0;
+ inc->incr_dst = sizeof(u32);
+
+ bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_RX);
+}
+EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare);
+
+void bcom_ata_tx_prepare(struct bcom_task *tsk)
+{
+ struct bcom_ata_inc *inc;
+
+ inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum);
+
+ inc->incr_bytes = -(s16)sizeof(u32);
+ inc->incr_src = sizeof(u32);
+ inc->incr_dst = 0;
+
+ bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_TX);
+}
+EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare);
+
+void bcom_ata_reset_bd(struct bcom_task *tsk)
+{
+ struct bcom_ata_var *var;
+
+ /* Reset all BD */
+ memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
+
+ tsk->index = 0;
+ tsk->outdex = 0;
+
+ var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum);
+ var->bd_start = var->bd_base;
+}
+EXPORT_SYMBOL_GPL(bcom_ata_reset_bd);
+
+void bcom_ata_release(struct bcom_task *tsk)
+{
+ /* Nothing special for the ATA tasks */
+ bcom_task_free(tsk);
+}
+EXPORT_SYMBOL_GPL(bcom_ata_release);
+
+
+MODULE_DESCRIPTION("BestComm ATA task driver");
+MODULE_AUTHOR("John Rigby");
+MODULE_LICENSE("GPL v2");
+
diff --git a/arch/powerpc/sysdev/bestcomm/ata.h b/arch/powerpc/sysdev/bestcomm/ata.h
new file mode 100644
index 00000000000..10982769c46
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/ata.h
@@ -0,0 +1,37 @@
+/*
+ * Header for Bestcomm ATA task driver
+ *
+ *
+ * Copyright (C) 2006 Freescale - John Rigby
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_ATA_H__
+#define __BESTCOMM_ATA_H__
+
+
+struct bcom_ata_bd {
+ u32 status;
+ u32 dst_pa;
+ u32 src_pa;
+};
+
+extern struct bcom_task *
+bcom_ata_init(int queue_len, int maxbufsize);
+
+extern void
+bcom_ata_rx_prepare(struct bcom_task *tsk);
+
+extern void
+bcom_ata_tx_prepare(struct bcom_task *tsk);
+
+extern void
+bcom_ata_reset_bd(struct bcom_task *tsk);
+
+
+#endif /* __BESTCOMM_ATA_H__ */
+
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_ata_task.c b/arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
new file mode 100644
index 00000000000..cc6049a4e46
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
@@ -0,0 +1,67 @@
+/*
+ * Bestcomm ATA task microcode
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ * Created based on bestcom/code_dma/image_rtos1/dma_image.hex
+ */
+
+#include <asm/types.h>
+
+/*
+ * The header consists of the following fields:
+ * u32 magic;
+ * u8 desc_size;
+ * u8 var_size;
+ * u8 inc_size;
+ * u8 first_var;
+ * u8 reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+ */
+
+u32 bcom_ata_task[] = {
+ /* header */
+ 0x4243544b,
+ 0x0e060709,
+ 0x00000000,
+ 0x00000000,
+
+ /* Task descriptors */
+ 0x8198009b, /* LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */
+ 0x13e00c08, /* DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */
+ 0xb8000264, /* LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */
+ 0x10000f00, /* DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+ 0x0c8cfc8a, /* DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */
+ 0xd8988240, /* LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */
+ 0xf845e011, /* LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */
+ 0xb845e00a, /* LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */
+ 0x0bfecf90, /* DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */
+ 0x9898802d, /* LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */
+ 0x64000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */
+ 0x0c0cf849, /* DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */
+ 0x000001f8, /* NOP */
+
+ /* VAR[9]-VAR[14] */
+ 0x40000000,
+ 0x7fff7fff,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+ 0x00000000,
+
+ /* INC[0]-INC[6] */
+ 0x40000000,
+ 0xe0000000,
+ 0xe0000000,
+ 0xa000000c,
+ 0x20000000,
+ 0x00000000,
+ 0x00000000,
+};
+
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
new file mode 100644
index 00000000000..a1ad6a02fce
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_fec_rx_task.c
@@ -0,0 +1,78 @@
+/*
+ * Bestcomm FEC RX task microcode
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
+ * on Tue Mar 22 11:19:38 2005 GMT
+ */
+
+#include <asm/types.h>
+
+/*
+ * The header consists of the following fields:
+ * u32 magic;
+ * u8 desc_size;
+ * u8 var_size;
+ * u8 inc_size;
+ * u8 first_var;
+ * u8 reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+ */
+
+u32 bcom_fec_rx_task[] = {
+ /* header */
+ 0x4243544b,
+ 0x18060709,
+ 0x00000000,
+ 0x00000000,
+
+ /* Task descriptors */
+ 0x808220e3, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
+ 0x10601010, /* DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */
+ 0xb8800264, /* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */
+ 0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+ 0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
+ 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
+ 0xb8c58029, /* LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */
+ 0x60000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
+ 0x088cf8cc, /* DRD2B1: idx2 = EU3(); EU3(idx3,var12) */
+ 0x991982f2, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */
+ 0x006acf80, /* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */
+ 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
+ 0x9999802d, /* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
+ 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x034cfc4e, /* DRD2B1: var13 = EU3(); EU3(*idx1,var14) */
+ 0x00008868, /* DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */
+ 0x99198341, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */
+ 0x007ecf80, /* DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */
+ 0x99198272, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */
+ 0x046acf80, /* DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */
+ 0x9819002d, /* LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */
+ 0x0060c790, /* DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */
+ 0x000001f8, /* NOP */
+
+ /* VAR[9]-VAR[14] */
+ 0x40000000,
+ 0x7fff7fff,
+ 0x00000000,
+ 0x00000003,
+ 0x40000008,
+ 0x43ffffff,
+
+ /* INC[0]-INC[6] */
+ 0x40000000,
+ 0xe0000000,
+ 0xe0000000,
+ 0xa0000008,
+ 0x20000000,
+ 0x00000000,
+ 0x4000ffff,
+};
+
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
new file mode 100644
index 00000000000..b1c495c3a65
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_fec_tx_task.c
@@ -0,0 +1,91 @@
+/*
+ * Bestcomm FEC TX task microcode
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
+ * on Tue Mar 22 11:19:29 2005 GMT
+ */
+
+#include <asm/types.h>
+
+/*
+ * The header consists of the following fields:
+ * u32 magic;
+ * u8 desc_size;
+ * u8 var_size;
+ * u8 inc_size;
+ * u8 first_var;
+ * u8 reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+ */
+
+u32 bcom_fec_tx_task[] = {
+ /* header */
+ 0x4243544b,
+ 0x2407070d,
+ 0x00000000,
+ 0x00000000,
+
+ /* Task descriptors */
+ 0x8018001b, /* LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */
+ 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+ 0x01ccfc0d, /* DRD2B1: var7 = EU3(); EU3(*idx0,var13) */
+ 0x8082a123, /* LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */
+ 0x10801418, /* DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */
+ 0xf88103a4, /* LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */
+ 0x801a6024, /* LCD: idx4 = var0; ; idx4 += inc4 */
+ 0x10001708, /* DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+ 0x0cccfccf, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var15) */
+ 0x991a002c, /* LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */
+ 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x024cfc4d, /* DRD2B1: var9 = EU3(); EU3(*idx1,var13) */
+ 0x60000003, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
+ 0x0cccf247, /* DRD2B1: *idx3 = EU3(); EU3(var9,var7) */
+ 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
+ 0xb8c80029, /* LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */
+ 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x088cf8d1, /* DRD2B1: idx2 = EU3(); EU3(idx3,var17) */
+ 0x00002f10, /* DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */
+ 0x99198432, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */
+ 0x008ac398, /* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */
+ 0x80004000, /* LCDEXT: idx2 = 0x00000000; ; */
+ 0x9999802d, /* LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
+ 0x70000002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+ 0x048cfc53, /* DRD2B1: var18 = EU3(); EU3(*idx1,var19) */
+ 0x60000008, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */
+ 0x088cf48b, /* DRD2B1: idx2 = EU3(); EU3(var18,var11) */
+ 0x99198481, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */
+ 0x009ec398, /* DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */
+ 0x991983b2, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */
+ 0x088ac398, /* DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */
+ 0x9919002d, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */
+ 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+ 0x0c4cf88e, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var14) */
+ 0x000001f8, /* NOP */
+
+ /* VAR[13]-VAR[19] */
+ 0x0c000000,
+ 0x40000000,
+ 0x7fff7fff,
+ 0x00000000,
+ 0x00000003,
+ 0x40000004,
+ 0x43ffffff,
+
+ /* INC[0]-INC[6] */
+ 0x40000000,
+ 0xe0000000,
+ 0xe0000000,
+ 0xa0000008,
+ 0x20000000,
+ 0x00000000,
+ 0x4000ffff,
+};
+
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
new file mode 100644
index 00000000000..efee022b025
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_rx_task.c
@@ -0,0 +1,63 @@
+/*
+ * Bestcomm GenBD RX task microcode
+ *
+ * Copyright (C) 2006 AppSpec Computer Technologies Corp.
+ * Jeff Gibbons <jeff.gibbons@appspec.com>
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ * Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
+ * on Tue Mar 4 10:14:12 2006 GMT
+ *
+ */
+
+#include <asm/types.h>
+
+/*
+ * The header consists of the following fields:
+ * u32 magic;
+ * u8 desc_size;
+ * u8 var_size;
+ * u8 inc_size;
+ * u8 first_var;
+ * u8 reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+ */
+
+u32 bcom_gen_bd_rx_task[] = {
+ /* header */
+ 0x4243544b,
+ 0x0d020409,
+ 0x00000000,
+ 0x00000000,
+
+ /* Task descriptors */
+ 0x808220da, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc3, idx1 += inc2 */
+ 0x13e01010, /* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
+ 0xb880025b, /* LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc3, idx3 += inc3 */
+ 0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+ 0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
+ 0xd9190240, /* LCDEXT: idx2 = idx2; idx2 > var9; idx2 += inc0 */
+ 0xb8c5e009, /* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
+ 0x07fecf80, /* DRD1A: *idx3 = *idx0; FN=0 INT init=31 WS=3 RS=3 */
+ 0x99190024, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc4 */
+ 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+ 0x0c4cf889, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
+ 0x000001f8, /* NOP */
+
+ /* VAR[9]-VAR[10] */
+ 0x40000000,
+ 0x7fff7fff,
+
+ /* INC[0]-INC[3] */
+ 0x40000000,
+ 0xe0000000,
+ 0xa0000008,
+ 0x20000000,
+};
+
diff --git a/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
new file mode 100644
index 00000000000..c605aa42ecb
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bcom_gen_bd_tx_task.c
@@ -0,0 +1,69 @@
+/*
+ * Bestcomm GenBD TX task microcode
+ *
+ * Copyright (C) 2006 AppSpec Computer Technologies Corp.
+ * Jeff Gibbons <jeff.gibbons@appspec.com>
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ * Based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
+ * on Tue Mar 4 10:14:12 2006 GMT
+ *
+ */
+
+#include <asm/types.h>
+
+/*
+ * The header consists of the following fields:
+ * u32 magic;
+ * u8 desc_size;
+ * u8 var_size;
+ * u8 inc_size;
+ * u8 first_var;
+ * u8 reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+ */
+
+u32 bcom_gen_bd_tx_task[] = {
+ /* header */
+ 0x4243544b,
+ 0x0f040609,
+ 0x00000000,
+ 0x00000000,
+
+ /* Task descriptors */
+ 0x800220e3, /* LCD: idx0 = var0, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
+ 0x13e01010, /* DRD1A: var4 = var2; FN=0 MORE init=31 WS=0 RS=0 */
+ 0xb8808264, /* LCD: idx2 = *idx1, idx3 = var1; idx2 < var9; idx2 += inc4, idx3 += inc4 */
+ 0x10001308, /* DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+ 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+ 0x0cccfcca, /* DRD2B1: *idx3 = EU3(); EU3(*idx3,var10) */
+ 0xd9190300, /* LCDEXT: idx2 = idx2; idx2 > var12; idx2 += inc0 */
+ 0xb8c5e009, /* LCD: idx3 = *(idx1 + var00000015); ; idx3 += inc1 */
+ 0x03fec398, /* DRD1A: *idx0 = *idx3; FN=0 init=31 WS=3 RS=3 */
+ 0x9919826a, /* LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc5, idx3 += inc2 */
+ 0x0feac398, /* DRD1A: *idx0 = *idx3; FN=0 TFD INT init=31 WS=1 RS=1 */
+ 0x99190036, /* LCD: idx2 = idx2; idx2 once var0; idx2 += inc6 */
+ 0x60000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+ 0x0c4cf889, /* DRD2B1: *idx1 = EU3(); EU3(idx2,var9) */
+ 0x000001f8, /* NOP */
+
+ /* VAR[9]-VAR[12] */
+ 0x40000000,
+ 0x7fff7fff,
+ 0x00000000,
+ 0x40000004,
+
+ /* INC[0]-INC[5] */
+ 0x40000000,
+ 0xe0000000,
+ 0xe0000000,
+ 0xa0000008,
+ 0x20000000,
+ 0x4000ffff,
+};
+
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c
new file mode 100644
index 00000000000..48492a83e5a
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c
@@ -0,0 +1,528 @@
+/*
+ * Driver for MPC52xx processor BestComm peripheral controller
+ *
+ *
+ * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2005 Varma Electronics Oy,
+ * ( by Andrey Volkov <avolkov@varma-el.com> )
+ * Copyright (C) 2003-2004 MontaVista, Software, Inc.
+ * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mpc52xx.h>
+
+#include "sram.h"
+#include "bestcomm_priv.h"
+#include "bestcomm.h"
+
+#define DRIVER_NAME "bestcomm-core"
+
+
+struct bcom_engine *bcom_eng = NULL;
+EXPORT_SYMBOL_GPL(bcom_eng); /* needed for inline functions */
+
+
+/* ======================================================================== */
+/* Public and private API */
+/* ======================================================================== */
+
+/* Private API */
+
+struct bcom_task *
+bcom_task_alloc(int bd_count, int bd_size, int priv_size)
+{
+ int i, tasknum = -1;
+ struct bcom_task *tsk;
+
+ /* Get and reserve a task num */
+ spin_lock(&bcom_eng->lock);
+
+ for (i=0; i<BCOM_MAX_TASKS; i++)
+ if (!bcom_eng->tdt[i].stop) { /* we use stop as a marker */
+ bcom_eng->tdt[i].stop = 0xfffffffful; /* dummy addr */
+ tasknum = i;
+ break;
+ }
+
+ spin_unlock(&bcom_eng->lock);
+
+ if (tasknum < 0)
+ return NULL;
+
+ /* Allocate our structure */
+ tsk = kzalloc(sizeof(struct bcom_task) + priv_size, GFP_KERNEL);
+ if (!tsk)
+ goto error;
+
+ tsk->tasknum = tasknum;
+ if (priv_size)
+ tsk->priv = (void*)tsk + sizeof(struct bcom_task);
+
+ /* Get IRQ of that task */
+ tsk->irq = irq_of_parse_and_map(bcom_eng->ofnode, tsk->tasknum);
+ if (tsk->irq == NO_IRQ)
+ goto error;
+
+ /* Init the BDs, if needed */
+ if (bd_count) {
+ tsk->cookie = kmalloc(sizeof(void*) * bd_count, GFP_KERNEL);
+ if (!tsk->cookie)
+ goto error;
+
+ tsk->bd = bcom_sram_alloc(bd_count * bd_size, 4, &tsk->bd_pa);
+ if (!tsk->bd)
+ goto error;
+ memset(tsk->bd, 0x00, bd_count * bd_size);
+
+ tsk->num_bd = bd_count;
+ tsk->bd_size = bd_size;
+ }
+
+ return tsk;
+
+error:
+ if (tsk) {
+ if (tsk->irq != NO_IRQ)
+ irq_dispose_mapping(tsk->irq);
+ bcom_sram_free(tsk->bd);
+ kfree(tsk->cookie);
+ kfree(tsk);
+ }
+
+ bcom_eng->tdt[tasknum].stop = 0;
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(bcom_task_alloc);
+
+void
+bcom_task_free(struct bcom_task *tsk)
+{
+ /* Stop the task */
+ bcom_disable_task(tsk->tasknum);
+
+ /* Clear TDT */
+ bcom_eng->tdt[tsk->tasknum].start = 0;
+ bcom_eng->tdt[tsk->tasknum].stop = 0;
+
+ /* Free everything */
+ irq_dispose_mapping(tsk->irq);
+ bcom_sram_free(tsk->bd);
+ kfree(tsk->cookie);
+ kfree(tsk);
+}
+EXPORT_SYMBOL_GPL(bcom_task_free);
+
+int
+bcom_load_image(int task, u32 *task_image)
+{
+ struct bcom_task_header *hdr = (struct bcom_task_header *)task_image;
+ struct bcom_tdt *tdt;
+ u32 *desc, *var, *inc;
+ u32 *desc_src, *var_src, *inc_src;
+
+ /* Safety checks */
+ if (hdr->magic != BCOM_TASK_MAGIC) {
+ printk(KERN_ERR DRIVER_NAME
+ ": Trying to load invalid microcode\n");
+ return -EINVAL;
+ }
+
+ if ((task < 0) || (task >= BCOM_MAX_TASKS)) {
+ printk(KERN_ERR DRIVER_NAME
+ ": Trying to load invalid task %d\n", task);
+ return -EINVAL;
+ }
+
+ /* Initial load or reload */
+ tdt = &bcom_eng->tdt[task];
+
+ if (tdt->start) {
+ desc = bcom_task_desc(task);
+ if (hdr->desc_size != bcom_task_num_descs(task)) {
+ printk(KERN_ERR DRIVER_NAME
+ ": Trying to reload wrong task image "
+ "(%d size %d/%d)!\n",
+ task,
+ hdr->desc_size,
+ bcom_task_num_descs(task));
+ return -EINVAL;
+ }
+ } else {
+ phys_addr_t start_pa;
+
+ desc = bcom_sram_alloc(hdr->desc_size * sizeof(u32), 4, &start_pa);
+ if (!desc)
+ return -ENOMEM;
+
+ tdt->start = start_pa;
+ tdt->stop = start_pa + ((hdr->desc_size-1) * sizeof(u32));
+ }
+
+ var = bcom_task_var(task);
+ inc = bcom_task_inc(task);
+
+ /* Clear & copy */
+ memset(var, 0x00, BCOM_VAR_SIZE);
+ memset(inc, 0x00, BCOM_INC_SIZE);
+
+ desc_src = (u32 *)(hdr + 1);
+ var_src = desc_src + hdr->desc_size;
+ inc_src = var_src + hdr->var_size;
+
+ memcpy(desc, desc_src, hdr->desc_size * sizeof(u32));
+ memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32));
+ memcpy(inc, inc_src, hdr->inc_size * sizeof(u32));
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcom_load_image);
+
+void
+bcom_set_initiator(int task, int initiator)
+{
+ int i;
+ int num_descs;
+ u32 *desc;
+ int next_drd_has_initiator;
+
+ bcom_set_tcr_initiator(task, initiator);
+
+ /* Just setting tcr is apparently not enough due to some problem */
+ /* with it. So we just go thru all the microcode and replace in */
+ /* the DRD directly */
+
+ desc = bcom_task_desc(task);
+ next_drd_has_initiator = 1;
+ num_descs = bcom_task_num_descs(task);
+
+ for (i=0; i<num_descs; i++, desc++) {
+ if (!bcom_desc_is_drd(*desc))
+ continue;
+ if (next_drd_has_initiator)
+ if (bcom_desc_initiator(*desc) != BCOM_INITIATOR_ALWAYS)
+ bcom_set_desc_initiator(desc, initiator);
+ next_drd_has_initiator = !bcom_drd_is_extended(*desc);
+ }
+}
+EXPORT_SYMBOL_GPL(bcom_set_initiator);
+
+
+/* Public API */
+
+void
+bcom_enable(struct bcom_task *tsk)
+{
+ bcom_enable_task(tsk->tasknum);
+}
+EXPORT_SYMBOL_GPL(bcom_enable);
+
+void
+bcom_disable(struct bcom_task *tsk)
+{
+ bcom_disable_task(tsk->tasknum);
+}
+EXPORT_SYMBOL_GPL(bcom_disable);
+
+
+/* ======================================================================== */
+/* Engine init/cleanup */
+/* ======================================================================== */
+
+/* Function Descriptor table */
+/* this will need to be updated if Freescale changes their task code FDT */
+static u32 fdt_ops[] = {
+ 0xa0045670, /* FDT[48] - load_acc() */
+ 0x80045670, /* FDT[49] - unload_acc() */
+ 0x21800000, /* FDT[50] - and() */
+ 0x21e00000, /* FDT[51] - or() */
+ 0x21500000, /* FDT[52] - xor() */
+ 0x21400000, /* FDT[53] - andn() */
+ 0x21500000, /* FDT[54] - not() */
+ 0x20400000, /* FDT[55] - add() */
+ 0x20500000, /* FDT[56] - sub() */
+ 0x20800000, /* FDT[57] - lsh() */
+ 0x20a00000, /* FDT[58] - rsh() */
+ 0xc0170000, /* FDT[59] - crc8() */
+ 0xc0145670, /* FDT[60] - crc16() */
+ 0xc0345670, /* FDT[61] - crc32() */
+ 0xa0076540, /* FDT[62] - endian32() */
+ 0xa0000760, /* FDT[63] - endian16() */
+};
+
+
+static int __devinit
+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;
+
+ /* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
+ tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
+ ctx_size = BCOM_MAX_TASKS * BCOM_CTX_SIZE;
+ var_size = BCOM_MAX_TASKS * (BCOM_VAR_SIZE + BCOM_INC_SIZE);
+ fdt_size = BCOM_FDT_SIZE;
+
+ bcom_eng->tdt = bcom_sram_alloc(tdt_size, sizeof(u32), &tdt_pa);
+ bcom_eng->ctx = bcom_sram_alloc(ctx_size, BCOM_CTX_ALIGN, &ctx_pa);
+ bcom_eng->var = bcom_sram_alloc(var_size, BCOM_VAR_ALIGN, &var_pa);
+ bcom_eng->fdt = bcom_sram_alloc(fdt_size, BCOM_FDT_ALIGN, &fdt_pa);
+
+ if (!bcom_eng->tdt || !bcom_eng->ctx || !bcom_eng->var || !bcom_eng->fdt) {
+ printk(KERN_ERR "DMA: SRAM alloc failed in engine init !\n");
+
+ bcom_sram_free(bcom_eng->tdt);
+ bcom_sram_free(bcom_eng->ctx);
+ bcom_sram_free(bcom_eng->var);
+ bcom_sram_free(bcom_eng->fdt);
+
+ return -ENOMEM;
+ }
+
+ memset(bcom_eng->tdt, 0x00, tdt_size);
+ memset(bcom_eng->ctx, 0x00, ctx_size);
+ memset(bcom_eng->var, 0x00, var_size);
+ memset(bcom_eng->fdt, 0x00, fdt_size);
+
+ /* Copy the FDT for the EU#3 */
+ memcpy(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops));
+
+ /* Initialize Task base structure */
+ for (task=0; task<BCOM_MAX_TASKS; task++)
+ {
+ out_be16(&bcom_eng->regs->tcr[task], 0);
+ out_8(&bcom_eng->regs->ipr[task], 0);
+
+ bcom_eng->tdt[task].context = ctx_pa;
+ bcom_eng->tdt[task].var = var_pa;
+ bcom_eng->tdt[task].fdt = fdt_pa;
+
+ var_pa += BCOM_VAR_SIZE + BCOM_INC_SIZE;
+ ctx_pa += BCOM_CTX_SIZE;
+ }
+
+ out_be32(&bcom_eng->regs->taskBar, tdt_pa);
+
+ /* 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);
+
+ /* Init lock */
+ spin_lock_init(&bcom_eng->lock);
+
+ return 0;
+}
+
+static void
+bcom_engine_cleanup(void)
+{
+ int task;
+
+ /* Stop all tasks */
+ for (task=0; task<BCOM_MAX_TASKS; task++)
+ {
+ out_be16(&bcom_eng->regs->tcr[task], 0);
+ out_8(&bcom_eng->regs->ipr[task], 0);
+ }
+
+ out_be32(&bcom_eng->regs->taskBar, 0ul);
+
+ /* Release the SRAM zones */
+ bcom_sram_free(bcom_eng->tdt);
+ bcom_sram_free(bcom_eng->ctx);
+ bcom_sram_free(bcom_eng->var);
+ bcom_sram_free(bcom_eng->fdt);
+}
+
+
+/* ======================================================================== */
+/* OF platform driver */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
+{
+ struct device_node *ofn_sram;
+ struct resource res_bcom;
+
+ int rv;
+
+ /* Inform user we're ok so far */
+ printk(KERN_INFO "DMA: MPC52xx BestComm driver\n");
+
+ /* Get the bestcomm node */
+ of_node_get(op->node);
+
+ /* Prepare SRAM */
+ ofn_sram = of_find_compatible_node(NULL, "sram", "mpc5200-sram");
+ if (!ofn_sram) {
+ printk(KERN_ERR DRIVER_NAME ": "
+ "No SRAM found in device tree\n");
+ rv = -ENODEV;
+ goto error_ofput;
+ }
+ rv = bcom_sram_init(ofn_sram, DRIVER_NAME);
+ of_node_put(ofn_sram);
+
+ if (rv) {
+ printk(KERN_ERR DRIVER_NAME ": "
+ "Error in SRAM init\n");
+ goto error_ofput;
+ }
+
+ /* Get a clean struct */
+ bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL);
+ if (!bcom_eng) {
+ printk(KERN_ERR DRIVER_NAME ": "
+ "Can't allocate state structure\n");
+ rv = -ENOMEM;
+ goto error_sramclean;
+ }
+
+ /* Save the node */
+ bcom_eng->ofnode = op->node;
+
+ /* Get, reserve & map io */
+ if (of_address_to_resource(op->node, 0, &res_bcom)) {
+ printk(KERN_ERR DRIVER_NAME ": "
+ "Can't get resource\n");
+ rv = -EINVAL;
+ goto error_sramclean;
+ }
+
+ if (!request_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma),
+ DRIVER_NAME)) {
+ printk(KERN_ERR DRIVER_NAME ": "
+ "Can't request registers region\n");
+ rv = -EBUSY;
+ goto error_sramclean;
+ }
+
+ bcom_eng->regs_base = res_bcom.start;
+ bcom_eng->regs = ioremap(res_bcom.start, sizeof(struct mpc52xx_sdma));
+ if (!bcom_eng->regs) {
+ printk(KERN_ERR DRIVER_NAME ": "
+ "Can't map registers\n");
+ rv = -ENOMEM;
+ goto error_release;
+ }
+
+ /* Now, do the real init */
+ rv = bcom_engine_init();
+ if (rv)
+ goto error_unmap;
+
+ /* Done ! */
+ printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n",
+ bcom_eng->regs_base);
+
+ return 0;
+
+ /* Error path */
+error_unmap:
+ iounmap(bcom_eng->regs);
+error_release:
+ release_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma));
+error_sramclean:
+ kfree(bcom_eng);
+ bcom_sram_cleanup();
+error_ofput:
+ of_node_put(op->node);
+
+ printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n");
+
+ return rv;
+}
+
+
+static int
+mpc52xx_bcom_remove(struct of_device *op)
+{
+ /* Clean up the engine */
+ bcom_engine_cleanup();
+
+ /* Cleanup SRAM */
+ bcom_sram_cleanup();
+
+ /* Release regs */
+ iounmap(bcom_eng->regs);
+ release_mem_region(bcom_eng->regs_base, sizeof(struct mpc52xx_sdma));
+
+ /* Release the node */
+ of_node_put(bcom_eng->ofnode);
+
+ /* Release memory */
+ kfree(bcom_eng);
+ bcom_eng = NULL;
+
+ return 0;
+}
+
+static struct of_device_id mpc52xx_bcom_of_match[] = {
+ {
+ .type = "dma-controller",
+ .compatible = "mpc5200-bestcomm",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match);
+
+
+static struct of_platform_driver mpc52xx_bcom_of_platform_driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .match_table = mpc52xx_bcom_of_match,
+ .probe = mpc52xx_bcom_probe,
+ .remove = mpc52xx_bcom_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+
+/* ======================================================================== */
+/* Module */
+/* ======================================================================== */
+
+static int __init
+mpc52xx_bcom_init(void)
+{
+ return of_register_platform_driver(&mpc52xx_bcom_of_platform_driver);
+}
+
+static void __exit
+mpc52xx_bcom_exit(void)
+{
+ of_unregister_platform_driver(&mpc52xx_bcom_of_platform_driver);
+}
+
+/* If we're not a module, we must make sure everything is setup before */
+/* anyone tries to use us ... that's why we use subsys_initcall instead */
+/* of module_init. */
+subsys_initcall(mpc52xx_bcom_init);
+module_exit(mpc52xx_bcom_exit);
+
+MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
+MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
+MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
+MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.h b/arch/powerpc/sysdev/bestcomm/bestcomm.h
new file mode 100644
index 00000000000..e802cb4eb69
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.h
@@ -0,0 +1,190 @@
+/*
+ * Public header for the MPC52xx processor BestComm driver
+ *
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2005 Varma Electronics Oy,
+ * ( by Andrey Volkov <avolkov@varma-el.com> )
+ * Copyright (C) 2003-2004 MontaVista, Software, Inc.
+ * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_H__
+#define __BESTCOMM_H__
+
+struct bcom_bd; /* defined later on ... */
+
+
+/* ======================================================================== */
+/* Generic task managment */
+/* ======================================================================== */
+
+/**
+ * struct bcom_task - Structure describing a loaded BestComm task
+ *
+ * This structure is never built by the driver it self. It's built and
+ * filled the intermediate layer of the BestComm API, the task dependent
+ * support code.
+ *
+ * Most likely you don't need to poke around inside this structure. The
+ * fields are exposed in the header just for the sake of inline functions
+ */
+struct bcom_task {
+ unsigned int tasknum;
+ unsigned int flags;
+ int irq;
+
+ struct bcom_bd *bd;
+ phys_addr_t bd_pa;
+ void **cookie;
+ unsigned short index;
+ unsigned short outdex;
+ unsigned int num_bd;
+ unsigned int bd_size;
+
+ void* priv;
+};
+
+#define BCOM_FLAGS_NONE 0x00000000ul
+#define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
+
+/**
+ * bcom_enable - Enable a BestComm task
+ * @tsk: The BestComm task structure
+ *
+ * This function makes sure the given task is enabled and can be run
+ * by the BestComm engine as needed
+ */
+extern void bcom_enable(struct bcom_task *tsk);
+
+/**
+ * bcom_disable - Disable a BestComm task
+ * @tsk: The BestComm task structure
+ *
+ * This function disable a given task, making sure it's not executed
+ * by the BestComm engine.
+ */
+extern void bcom_disable(struct bcom_task *tsk);
+
+
+/**
+ * bcom_get_task_irq - Returns the irq number of a BestComm task
+ * @tsk: The BestComm task structure
+ */
+static inline int
+bcom_get_task_irq(struct bcom_task *tsk) {
+ return tsk->irq;
+}
+
+/* ======================================================================== */
+/* BD based tasks helpers */
+/* ======================================================================== */
+
+/**
+ * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
+ * @status: The current status of this buffer. Exact meaning depends on the
+ * task type
+ * @data: An array of u32 whose meaning depends on the task type.
+ */
+struct bcom_bd {
+ u32 status;
+ u32 data[1]; /* variable, but at least 1 */
+};
+
+#define BCOM_BD_READY 0x40000000ul
+
+/** _bcom_next_index - Get next input index.
+ * @tsk: pointer to task structure
+ *
+ * Support function; Device drivers should not call this
+ */
+static inline int
+_bcom_next_index(struct bcom_task *tsk)
+{
+ return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
+}
+
+/** _bcom_next_outdex - Get next output index.
+ * @tsk: pointer to task structure
+ *
+ * Support function; Device drivers should not call this
+ */
+static inline int
+_bcom_next_outdex(struct bcom_task *tsk)
+{
+ return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
+}
+
+/**
+ * bcom_queue_empty - Checks if a BestComm task BD queue is empty
+ * @tsk: The BestComm task structure
+ */
+static inline int
+bcom_queue_empty(struct bcom_task *tsk)
+{
+ return tsk->index == tsk->outdex;
+}
+
+/**
+ * bcom_queue_full - Checks if a BestComm task BD queue is full
+ * @tsk: The BestComm task structure
+ */
+static inline int
+bcom_queue_full(struct bcom_task *tsk)
+{
+ return tsk->outdex == _bcom_next_index(tsk);
+}
+
+/**
+ * bcom_buffer_done - Checks if a BestComm
+ * @tsk: The BestComm task structure
+ */
+static inline int
+bcom_buffer_done(struct bcom_task *tsk)
+{
+ if (bcom_queue_empty(tsk))
+ return 0;
+ return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
+}
+
+/**
+ * bcom_prepare_next_buffer - clear status of next available buffer.
+ * @tsk: The BestComm task structure
+ *
+ * Returns pointer to next buffer descriptor
+ */
+static inline struct bcom_bd *
+bcom_prepare_next_buffer(struct bcom_task *tsk)
+{
+ tsk->bd[tsk->index].status = 0; /* cleanup last status */
+ return &tsk->bd[tsk->index];
+}
+
+static inline void
+bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
+{
+ tsk->cookie[tsk->index] = cookie;
+ mb(); /* ensure the bd is really up-to-date */
+ tsk->bd[tsk->index].status |= BCOM_BD_READY;
+ tsk->index = _bcom_next_index(tsk);
+ if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
+ bcom_enable(tsk);
+}
+
+static inline void *
+bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
+{
+ void *cookie = tsk->cookie[tsk->outdex];
+ if (p_status)
+ *p_status = tsk->bd[tsk->outdex].status;
+ if (p_bd)
+ *p_bd = &tsk->bd[tsk->outdex];
+ tsk->outdex = _bcom_next_outdex(tsk);
+ return cookie;
+}
+
+#endif /* __BESTCOMM_H__ */
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
new file mode 100644
index 00000000000..866a2915ef2
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm_priv.h
@@ -0,0 +1,334 @@
+/*
+ * Private header for the MPC52xx processor BestComm driver
+ *
+ * By private, we mean that driver should not use it directly. It's meant
+ * to be used by the BestComm engine driver itself and by the intermediate
+ * layer between the core and the drivers.
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2005 Varma Electronics Oy,
+ * ( by Andrey Volkov <avolkov@varma-el.com> )
+ * Copyright (C) 2003-2004 MontaVista, Software, Inc.
+ * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_PRIV_H__
+#define __BESTCOMM_PRIV_H__
+
+#include <linux/spinlock.h>
+#include <linux/of.h>
+#include <asm/io.h>
+#include <asm/mpc52xx.h>
+
+#include "sram.h"
+
+
+/* ======================================================================== */
+/* Engine related stuff */
+/* ======================================================================== */
+
+/* Zones sizes and needed alignments */
+#define BCOM_MAX_TASKS 16
+#define BCOM_MAX_VAR 24
+#define BCOM_MAX_INC 8
+#define BCOM_MAX_FDT 64
+#define BCOM_MAX_CTX 20
+#define BCOM_CTX_SIZE (BCOM_MAX_CTX * sizeof(u32))
+#define BCOM_CTX_ALIGN 0x100
+#define BCOM_VAR_SIZE (BCOM_MAX_VAR * sizeof(u32))
+#define BCOM_INC_SIZE (BCOM_MAX_INC * sizeof(u32))
+#define BCOM_VAR_ALIGN 0x80
+#define BCOM_FDT_SIZE (BCOM_MAX_FDT * sizeof(u32))
+#define BCOM_FDT_ALIGN 0x100
+
+/**
+ * struct bcom_tdt - Task Descriptor Table Entry
+ *
+ */
+struct bcom_tdt {
+ u32 start;
+ u32 stop;
+ u32 var;
+ u32 fdt;
+ u32 exec_status; /* used internally by BestComm engine */
+ u32 mvtp; /* used internally by BestComm engine */
+ u32 context;
+ u32 litbase;
+};
+
+/**
+ * struct bcom_engine
+ *
+ * This holds all info needed globaly to handle the engine
+ */
+struct bcom_engine {
+ struct device_node *ofnode;
+ struct mpc52xx_sdma __iomem *regs;
+ phys_addr_t regs_base;
+
+ struct bcom_tdt *tdt;
+ u32 *ctx;
+ u32 *var;
+ u32 *fdt;
+
+ spinlock_t lock;
+};
+
+extern struct bcom_engine *bcom_eng;
+
+
+/* ======================================================================== */
+/* Tasks related stuff */
+/* ======================================================================== */
+
+/* Tasks image header */
+#define BCOM_TASK_MAGIC 0x4243544B /* 'BCTK' */
+
+struct bcom_task_header {
+ u32 magic;
+ u8 desc_size; /* the size fields */
+ u8 var_size; /* are given in number */
+ u8 inc_size; /* of 32-bits words */
+ u8 first_var;
+ u8 reserved[8];
+};
+
+/* Descriptors stucture & co */
+#define BCOM_DESC_NOP 0x000001f8
+#define BCOM_LCD_MASK 0x80000000
+#define BCOM_DRD_EXTENDED 0x40000000
+#define BCOM_DRD_INITIATOR_SHIFT 21
+
+/* Tasks pragma */
+#define BCOM_PRAGMA_BIT_RSV 7 /* reserved pragma bit */
+#define BCOM_PRAGMA_BIT_PRECISE_INC 6 /* increment 0=when possible, */
+ /* 1=iter end */
+#define BCOM_PRAGMA_BIT_RST_ERROR_NO 5 /* don't reset errors on */
+ /* task enable */
+#define BCOM_PRAGMA_BIT_PACK 4 /* pack data enable */
+#define BCOM_PRAGMA_BIT_INTEGER 3 /* data alignment */
+ /* 0=frac(msb), 1=int(lsb) */
+#define BCOM_PRAGMA_BIT_SPECREAD 2 /* XLB speculative read */
+#define BCOM_PRAGMA_BIT_CW 1 /* write line buffer enable */
+#define BCOM_PRAGMA_BIT_RL 0 /* read line buffer enable */
+
+ /* Looks like XLB speculative read generates XLB errors when a buffer
+ * is at the end of the physical memory. i.e. when accessing the
+ * lasts words, the engine tries to prefetch the next but there is no
+ * next ...
+ */
+#define BCOM_STD_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
+ (0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
+ (0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
+ (0 << BCOM_PRAGMA_BIT_PACK) | \
+ (0 << BCOM_PRAGMA_BIT_INTEGER) | \
+ (0 << BCOM_PRAGMA_BIT_SPECREAD) | \
+ (1 << BCOM_PRAGMA_BIT_CW) | \
+ (1 << BCOM_PRAGMA_BIT_RL))
+
+#define BCOM_PCI_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \
+ (0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \
+ (0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \
+ (0 << BCOM_PRAGMA_BIT_PACK) | \
+ (1 << BCOM_PRAGMA_BIT_INTEGER) | \
+ (0 << BCOM_PRAGMA_BIT_SPECREAD) | \
+ (1 << BCOM_PRAGMA_BIT_CW) | \
+ (1 << BCOM_PRAGMA_BIT_RL))
+
+#define BCOM_ATA_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_CRC16_DP_0_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_CRC16_DP_1_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_FEC_RX_BD_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_FEC_TX_BD_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_DP_0_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_DP_1_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_DP_2_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_DP_3_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_DP_BD_0_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_DP_BD_1_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_RX_BD_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_TX_BD_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_GEN_LPC_PRAGMA BCOM_STD_PRAGMA
+#define BCOM_PCI_RX_PRAGMA BCOM_PCI_PRAGMA
+#define BCOM_PCI_TX_PRAGMA BCOM_PCI_PRAGMA
+
+/* Initiators number */
+#define BCOM_INITIATOR_ALWAYS 0
+#define BCOM_INITIATOR_SCTMR_0 1
+#define BCOM_INITIATOR_SCTMR_1 2
+#define BCOM_INITIATOR_FEC_RX 3
+#define BCOM_INITIATOR_FEC_TX 4
+#define BCOM_INITIATOR_ATA_RX 5
+#define BCOM_INITIATOR_ATA_TX 6
+#define BCOM_INITIATOR_SCPCI_RX 7
+#define BCOM_INITIATOR_SCPCI_TX 8
+#define BCOM_INITIATOR_PSC3_RX 9
+#define BCOM_INITIATOR_PSC3_TX 10
+#define BCOM_INITIATOR_PSC2_RX 11
+#define BCOM_INITIATOR_PSC2_TX 12
+#define BCOM_INITIATOR_PSC1_RX 13
+#define BCOM_INITIATOR_PSC1_TX 14
+#define BCOM_INITIATOR_SCTMR_2 15
+#define BCOM_INITIATOR_SCLPC 16
+#define BCOM_INITIATOR_PSC5_RX 17
+#define BCOM_INITIATOR_PSC5_TX 18
+#define BCOM_INITIATOR_PSC4_RX 19
+#define BCOM_INITIATOR_PSC4_TX 20
+#define BCOM_INITIATOR_I2C2_RX 21
+#define BCOM_INITIATOR_I2C2_TX 22
+#define BCOM_INITIATOR_I2C1_RX 23
+#define BCOM_INITIATOR_I2C1_TX 24
+#define BCOM_INITIATOR_PSC6_RX 25
+#define BCOM_INITIATOR_PSC6_TX 26
+#define BCOM_INITIATOR_IRDA_RX 25
+#define BCOM_INITIATOR_IRDA_TX 26
+#define BCOM_INITIATOR_SCTMR_3 27
+#define BCOM_INITIATOR_SCTMR_4 28
+#define BCOM_INITIATOR_SCTMR_5 29
+#define BCOM_INITIATOR_SCTMR_6 30
+#define BCOM_INITIATOR_SCTMR_7 31
+
+/* Initiators priorities */
+#define BCOM_IPR_ALWAYS 7
+#define BCOM_IPR_SCTMR_0 2
+#define BCOM_IPR_SCTMR_1 2
+#define BCOM_IPR_FEC_RX 6
+#define BCOM_IPR_FEC_TX 5
+#define BCOM_IPR_ATA_RX 4
+#define BCOM_IPR_ATA_TX 3
+#define BCOM_IPR_SCPCI_RX 2
+#define BCOM_IPR_SCPCI_TX 2
+#define BCOM_IPR_PSC3_RX 2
+#define BCOM_IPR_PSC3_TX 2
+#define BCOM_IPR_PSC2_RX 2
+#define BCOM_IPR_PSC2_TX 2
+#define BCOM_IPR_PSC1_RX 2
+#define BCOM_IPR_PSC1_TX 2
+#define BCOM_IPR_SCTMR_2 2
+#define BCOM_IPR_SCLPC 2
+#define BCOM_IPR_PSC5_RX 2
+#define BCOM_IPR_PSC5_TX 2
+#define BCOM_IPR_PSC4_RX 2
+#define BCOM_IPR_PSC4_TX 2
+#define BCOM_IPR_I2C2_RX 2
+#define BCOM_IPR_I2C2_TX 2
+#define BCOM_IPR_I2C1_RX 2
+#define BCOM_IPR_I2C1_TX 2
+#define BCOM_IPR_PSC6_RX 2
+#define BCOM_IPR_PSC6_TX 2
+#define BCOM_IPR_IRDA_RX 2
+#define BCOM_IPR_IRDA_TX 2
+#define BCOM_IPR_SCTMR_3 2
+#define BCOM_IPR_SCTMR_4 2
+#define BCOM_IPR_SCTMR_5 2
+#define BCOM_IPR_SCTMR_6 2
+#define BCOM_IPR_SCTMR_7 2
+
+
+/* ======================================================================== */
+/* API */
+/* ======================================================================== */
+
+extern struct bcom_task *bcom_task_alloc(int bd_count, int bd_size, int priv_size);
+extern void bcom_task_free(struct bcom_task *tsk);
+extern int bcom_load_image(int task, u32 *task_image);
+extern void bcom_set_initiator(int task, int initiator);
+
+
+#define TASK_ENABLE 0x8000
+
+static inline void
+bcom_enable_task(int task)
+{
+ u16 reg;
+ reg = in_be16(&bcom_eng->regs->tcr[task]);
+ out_be16(&bcom_eng->regs->tcr[task], reg | TASK_ENABLE);
+}
+
+static inline void
+bcom_disable_task(int task)
+{
+ u16 reg = in_be16(&bcom_eng->regs->tcr[task]);
+ out_be16(&bcom_eng->regs->tcr[task], reg & ~TASK_ENABLE);
+}
+
+
+static inline u32 *
+bcom_task_desc(int task)
+{
+ return bcom_sram_pa2va(bcom_eng->tdt[task].start);
+}
+
+static inline int
+bcom_task_num_descs(int task)
+{
+ return (bcom_eng->tdt[task].stop - bcom_eng->tdt[task].start)/sizeof(u32) + 1;
+}
+
+static inline u32 *
+bcom_task_var(int task)
+{
+ return bcom_sram_pa2va(bcom_eng->tdt[task].var);
+}
+
+static inline u32 *
+bcom_task_inc(int task)
+{
+ return &bcom_task_var(task)[BCOM_MAX_VAR];
+}
+
+
+static inline int
+bcom_drd_is_extended(u32 desc)
+{
+ return (desc) & BCOM_DRD_EXTENDED;
+}
+
+static inline int
+bcom_desc_is_drd(u32 desc)
+{
+ return !(desc & BCOM_LCD_MASK) && desc != BCOM_DESC_NOP;
+}
+
+static inline int
+bcom_desc_initiator(u32 desc)
+{
+ return (desc >> BCOM_DRD_INITIATOR_SHIFT) & 0x1f;
+}
+
+static inline void
+bcom_set_desc_initiator(u32 *desc, int initiator)
+{
+ *desc = (*desc & ~(0x1f << BCOM_DRD_INITIATOR_SHIFT)) |
+ ((initiator & 0x1f) << BCOM_DRD_INITIATOR_SHIFT);
+}
+
+
+static inline void
+bcom_set_task_pragma(int task, int pragma)
+{
+ u32 *fdt = &bcom_eng->tdt[task].fdt;
+ *fdt = (*fdt & ~0xff) | pragma;
+}
+
+static inline void
+bcom_set_task_auto_start(int task, int next_task)
+{
+ u16 __iomem *tcr = &bcom_eng->regs->tcr[task];
+ out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task);
+}
+
+static inline void
+bcom_set_tcr_initiator(int task, int initiator)
+{
+ u16 __iomem *tcr = &bcom_eng->regs->tcr[task];
+ out_be16(tcr, (in_be16(tcr) & ~0x1f00) | ((initiator & 0x1f) << 8));
+}
+
+
+#endif /* __BESTCOMM_PRIV_H__ */
+
diff --git a/arch/powerpc/sysdev/bestcomm/fec.c b/arch/powerpc/sysdev/bestcomm/fec.c
new file mode 100644
index 00000000000..957a988d23e
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/fec.c
@@ -0,0 +1,270 @@
+/*
+ * Bestcomm FEC tasks driver
+ *
+ *
+ * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003-2004 MontaVista, Software, Inc.
+ * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <asm/io.h>
+
+#include "bestcomm.h"
+#include "bestcomm_priv.h"
+#include "fec.h"
+
+
+/* ======================================================================== */
+/* Task image/var/inc */
+/* ======================================================================== */
+
+/* fec tasks images */
+extern u32 bcom_fec_rx_task[];
+extern u32 bcom_fec_tx_task[];
+
+/* rx task vars that need to be set before enabling the task */
+struct bcom_fec_rx_var {
+ u32 enable; /* (u16*) address of task's control register */
+ u32 fifo; /* (u32*) address of fec's fifo */
+ u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
+ u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
+ u32 bd_start; /* (struct bcom_bd*) current bd */
+ u32 buffer_size; /* size of receive buffer */
+};
+
+/* rx task incs that need to be set before enabling the task */
+struct bcom_fec_rx_inc {
+ u16 pad0;
+ s16 incr_bytes;
+ u16 pad1;
+ s16 incr_dst;
+ u16 pad2;
+ s16 incr_dst_ma;
+};
+
+/* tx task vars that need to be set before enabling the task */
+struct bcom_fec_tx_var {
+ u32 DRD; /* (u32*) address of self-modified DRD */
+ u32 fifo; /* (u32*) address of fec's fifo */
+ u32 enable; /* (u16*) address of task's control register */
+ u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
+ u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
+ u32 bd_start; /* (struct bcom_bd*) current bd */
+ u32 buffer_size; /* set by uCode for each packet */
+};
+
+/* tx task incs that need to be set before enabling the task */
+struct bcom_fec_tx_inc {
+ u16 pad0;
+ s16 incr_bytes;
+ u16 pad1;
+ s16 incr_src;
+ u16 pad2;
+ s16 incr_src_ma;
+};
+
+/* private structure in the task */
+struct bcom_fec_priv {
+ phys_addr_t fifo;
+ int maxbufsize;
+};
+
+
+/* ======================================================================== */
+/* Task support code */
+/* ======================================================================== */
+
+struct bcom_task *
+bcom_fec_rx_init(int queue_len, phys_addr_t fifo, int maxbufsize)
+{
+ struct bcom_task *tsk;
+ struct bcom_fec_priv *priv;
+
+ tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_fec_bd),
+ sizeof(struct bcom_fec_priv));
+ if (!tsk)
+ return NULL;
+
+ tsk->flags = BCOM_FLAGS_NONE;
+
+ priv = tsk->priv;
+ priv->fifo = fifo;
+ priv->maxbufsize = maxbufsize;
+
+ if (bcom_fec_rx_reset(tsk)) {
+ bcom_task_free(tsk);
+ return NULL;
+ }
+
+ return tsk;
+}
+EXPORT_SYMBOL_GPL(bcom_fec_rx_init);
+
+int
+bcom_fec_rx_reset(struct bcom_task *tsk)
+{
+ struct bcom_fec_priv *priv = tsk->priv;
+ struct bcom_fec_rx_var *var;
+ struct bcom_fec_rx_inc *inc;
+
+ /* Shutdown the task */
+ bcom_disable_task(tsk->tasknum);
+
+ /* Reset the microcode */
+ var = (struct bcom_fec_rx_var *) bcom_task_var(tsk->tasknum);
+ inc = (struct bcom_fec_rx_inc *) bcom_task_inc(tsk->tasknum);
+
+ if (bcom_load_image(tsk->tasknum, bcom_fec_rx_task))
+ return -1;
+
+ var->enable = bcom_eng->regs_base +
+ offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
+ var->fifo = (u32) priv->fifo;
+ var->bd_base = tsk->bd_pa;
+ var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
+ var->bd_start = tsk->bd_pa;
+ var->buffer_size = priv->maxbufsize;
+
+ inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */
+ inc->incr_dst = sizeof(u32); /* task image, but we stick */
+ inc->incr_dst_ma= sizeof(u8); /* to the official ones */
+
+ /* Reset the BDs */
+ tsk->index = 0;
+ tsk->outdex = 0;
+
+ memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
+
+ /* Configure some stuff */
+ bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_RX_BD_PRAGMA);
+ bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
+
+ out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_RX], BCOM_IPR_FEC_RX);
+
+ out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcom_fec_rx_reset);
+
+void
+bcom_fec_rx_release(struct bcom_task *tsk)
+{
+ /* Nothing special for the FEC tasks */
+ bcom_task_free(tsk);
+}
+EXPORT_SYMBOL_GPL(bcom_fec_rx_release);
+
+
+
+ /* Return 2nd to last DRD */
+ /* This is an ugly hack, but at least it's only done
+ once at initialization */
+static u32 *self_modified_drd(int tasknum)
+{
+ u32 *desc;
+ int num_descs;
+ int drd_count;
+ int i;
+
+ num_descs = bcom_task_num_descs(tasknum);
+ desc = bcom_task_desc(tasknum) + num_descs - 1;
+ drd_count = 0;
+ for (i=0; i<num_descs; i++, desc--)
+ if (bcom_desc_is_drd(*desc) && ++drd_count == 3)
+ break;
+ return desc;
+}
+
+struct bcom_task *
+bcom_fec_tx_init(int queue_len, phys_addr_t fifo)
+{
+ struct bcom_task *tsk;
+ struct bcom_fec_priv *priv;
+
+ tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_fec_bd),
+ sizeof(struct bcom_fec_priv));
+ if (!tsk)
+ return NULL;
+
+ tsk->flags = BCOM_FLAGS_ENABLE_TASK;
+
+ priv = tsk->priv;
+ priv->fifo = fifo;
+
+ if (bcom_fec_tx_reset(tsk)) {
+ bcom_task_free(tsk);
+ return NULL;
+ }
+
+ return tsk;
+}
+EXPORT_SYMBOL_GPL(bcom_fec_tx_init);
+
+int
+bcom_fec_tx_reset(struct bcom_task *tsk)
+{
+ struct bcom_fec_priv *priv = tsk->priv;
+ struct bcom_fec_tx_var *var;
+ struct bcom_fec_tx_inc *inc;
+
+ /* Shutdown the task */
+ bcom_disable_task(tsk->tasknum);
+
+ /* Reset the microcode */
+ var = (struct bcom_fec_tx_var *) bcom_task_var(tsk->tasknum);
+ inc = (struct bcom_fec_tx_inc *) bcom_task_inc(tsk->tasknum);
+
+ if (bcom_load_image(tsk->tasknum, bcom_fec_tx_task))
+ return -1;
+
+ var->enable = bcom_eng->regs_base +
+ offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
+ var->fifo = (u32) priv->fifo;
+ var->DRD = bcom_sram_va2pa(self_modified_drd(tsk->tasknum));
+ var->bd_base = tsk->bd_pa;
+ var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
+ var->bd_start = tsk->bd_pa;
+
+ inc->incr_bytes = -(s16)sizeof(u32); /* These should be in the */
+ inc->incr_src = sizeof(u32); /* task image, but we stick */
+ inc->incr_src_ma= sizeof(u8); /* to the official ones */
+
+ /* Reset the BDs */
+ tsk->index = 0;
+ tsk->outdex = 0;
+
+ memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
+
+ /* Configure some stuff */
+ bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA);
+ bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
+
+ out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_FEC_TX], BCOM_IPR_FEC_TX);
+
+ out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcom_fec_tx_reset);
+
+void
+bcom_fec_tx_release(struct bcom_task *tsk)
+{
+ /* Nothing special for the FEC tasks */
+ bcom_task_free(tsk);
+}
+EXPORT_SYMBOL_GPL(bcom_fec_tx_release);
+
+
+MODULE_DESCRIPTION("BestComm FEC tasks driver");
+MODULE_AUTHOR("Dale Farnsworth <dfarnsworth@mvista.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/arch/powerpc/sysdev/bestcomm/fec.h b/arch/powerpc/sysdev/bestcomm/fec.h
new file mode 100644
index 00000000000..ee565d94d50
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/fec.h
@@ -0,0 +1,61 @@
+/*
+ * Header for Bestcomm FEC tasks driver
+ *
+ *
+ * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003-2004 MontaVista, Software, Inc.
+ * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_FEC_H__
+#define __BESTCOMM_FEC_H__
+
+
+struct bcom_fec_bd {
+ u32 status;
+ u32 skb_pa;
+};
+
+#define BCOM_FEC_TX_BD_TFD 0x08000000ul /* transmit frame done */
+#define BCOM_FEC_TX_BD_TC 0x04000000ul /* transmit CRC */
+#define BCOM_FEC_TX_BD_ABC 0x02000000ul /* append bad CRC */
+
+#define BCOM_FEC_RX_BD_L 0x08000000ul /* buffer is last in frame */
+#define BCOM_FEC_RX_BD_BC 0x00800000ul /* DA is broadcast */
+#define BCOM_FEC_RX_BD_MC 0x00400000ul /* DA is multicast and not broadcast */
+#define BCOM_FEC_RX_BD_LG 0x00200000ul /* Rx frame length violation */
+#define BCOM_FEC_RX_BD_NO 0x00100000ul /* Rx non-octet aligned frame */
+#define BCOM_FEC_RX_BD_CR 0x00040000ul /* Rx CRC error */
+#define BCOM_FEC_RX_BD_OV 0x00020000ul /* overrun */
+#define BCOM_FEC_RX_BD_TR 0x00010000ul /* Rx frame truncated */
+#define BCOM_FEC_RX_BD_LEN_MASK 0x000007fful /* mask for length of received frame */
+#define BCOM_FEC_RX_BD_ERRORS (BCOM_FEC_RX_BD_LG | BCOM_FEC_RX_BD_NO | \
+ BCOM_FEC_RX_BD_CR | BCOM_FEC_RX_BD_OV | BCOM_FEC_RX_BD_TR)
+
+
+extern struct bcom_task *
+bcom_fec_rx_init(int queue_len, phys_addr_t fifo, int maxbufsize);
+
+extern int
+bcom_fec_rx_reset(struct bcom_task *tsk);
+
+extern void
+bcom_fec_rx_release(struct bcom_task *tsk);
+
+
+extern struct bcom_task *
+bcom_fec_tx_init(int queue_len, phys_addr_t fifo);
+
+extern int
+bcom_fec_tx_reset(struct bcom_task *tsk);
+
+extern void
+bcom_fec_tx_release(struct bcom_task *tsk);
+
+
+#endif /* __BESTCOMM_FEC_H__ */
+
diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.c b/arch/powerpc/sysdev/bestcomm/gen_bd.c
new file mode 100644
index 00000000000..8d33eafbb3f
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/gen_bd.c
@@ -0,0 +1,260 @@
+/*
+ * Driver for MPC52xx processor BestComm General Buffer Descriptor
+ *
+ * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2006 AppSpec Computer Technologies Corp.
+ * Jeff Gibbons <jeff.gibbons@appspec.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 published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include <asm/mpc52xx.h>
+
+#include "bestcomm.h"
+#include "bestcomm_priv.h"
+#include "gen_bd.h"
+
+
+/* ======================================================================== */
+/* Task image/var/inc */
+/* ======================================================================== */
+
+/* gen_bd tasks images */
+extern u32 bcom_gen_bd_rx_task[];
+extern u32 bcom_gen_bd_tx_task[];
+
+/* rx task vars that need to be set before enabling the task */
+struct bcom_gen_bd_rx_var {
+ u32 enable; /* (u16*) address of task's control register */
+ u32 fifo; /* (u32*) address of gen_bd's fifo */
+ u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
+ u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
+ u32 bd_start; /* (struct bcom_bd*) current bd */
+ u32 buffer_size; /* size of receive buffer */
+};
+
+/* rx task incs that need to be set before enabling the task */
+struct bcom_gen_bd_rx_inc {
+ u16 pad0;
+ s16 incr_bytes;
+ u16 pad1;
+ s16 incr_dst;
+};
+
+/* tx task vars that need to be set before enabling the task */
+struct bcom_gen_bd_tx_var {
+ u32 fifo; /* (u32*) address of gen_bd's fifo */
+ u32 enable; /* (u16*) address of task's control register */
+ u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */
+ u32 bd_last; /* (struct bcom_bd*) end of ring buffer */
+ u32 bd_start; /* (struct bcom_bd*) current bd */
+ u32 buffer_size; /* set by uCode for each packet */
+};
+
+/* tx task incs that need to be set before enabling the task */
+struct bcom_gen_bd_tx_inc {
+ u16 pad0;
+ s16 incr_bytes;
+ u16 pad1;
+ s16 incr_src;
+ u16 pad2;
+ s16 incr_src_ma;
+};
+
+/* private structure */
+struct bcom_gen_bd_priv {
+ phys_addr_t fifo;
+ int initiator;
+ int ipr;
+ int maxbufsize;
+};
+
+
+/* ======================================================================== */
+/* Task support code */
+/* ======================================================================== */
+
+struct bcom_task *
+bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
+ int initiator, int ipr, int maxbufsize)
+{
+ struct bcom_task *tsk;
+ struct bcom_gen_bd_priv *priv;
+
+ tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
+ sizeof(struct bcom_gen_bd_priv));
+ if (!tsk)
+ return NULL;
+
+ tsk->flags = BCOM_FLAGS_NONE;
+
+ priv = tsk->priv;
+ priv->fifo = fifo;
+ priv->initiator = initiator;
+ priv->ipr = ipr;
+ priv->maxbufsize = maxbufsize;
+
+ if (bcom_gen_bd_rx_reset(tsk)) {
+ bcom_task_free(tsk);
+ return NULL;
+ }
+
+ return tsk;
+}
+EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init);
+
+int
+bcom_gen_bd_rx_reset(struct bcom_task *tsk)
+{
+ struct bcom_gen_bd_priv *priv = tsk->priv;
+ struct bcom_gen_bd_rx_var *var;
+ struct bcom_gen_bd_rx_inc *inc;
+
+ /* Shutdown the task */
+ bcom_disable_task(tsk->tasknum);
+
+ /* Reset the microcode */
+ var = (struct bcom_gen_bd_rx_var *) bcom_task_var(tsk->tasknum);
+ inc = (struct bcom_gen_bd_rx_inc *) bcom_task_inc(tsk->tasknum);
+
+ if (bcom_load_image(tsk->tasknum, bcom_gen_bd_rx_task))
+ return -1;
+
+ var->enable = bcom_eng->regs_base +
+ offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
+ var->fifo = (u32) priv->fifo;
+ var->bd_base = tsk->bd_pa;
+ var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
+ var->bd_start = tsk->bd_pa;
+ var->buffer_size = priv->maxbufsize;
+
+ inc->incr_bytes = -(s16)sizeof(u32);
+ inc->incr_dst = sizeof(u32);
+
+ /* Reset the BDs */
+ tsk->index = 0;
+ tsk->outdex = 0;
+
+ memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
+
+ /* Configure some stuff */
+ bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_RX_BD_PRAGMA);
+ bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
+
+ out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
+ bcom_set_initiator(tsk->tasknum, priv->initiator);
+
+ out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_reset);
+
+void
+bcom_gen_bd_rx_release(struct bcom_task *tsk)
+{
+ /* Nothing special for the GenBD tasks */
+ bcom_task_free(tsk);
+}
+EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release);
+
+
+extern struct bcom_task *
+bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
+ int initiator, int ipr)
+{
+ struct bcom_task *tsk;
+ struct bcom_gen_bd_priv *priv;
+
+ tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_gen_bd),
+ sizeof(struct bcom_gen_bd_priv));
+ if (!tsk)
+ return NULL;
+
+ tsk->flags = BCOM_FLAGS_NONE;
+
+ priv = tsk->priv;
+ priv->fifo = fifo;
+ priv->initiator = initiator;
+ priv->ipr = ipr;
+
+ if (bcom_gen_bd_tx_reset(tsk)) {
+ bcom_task_free(tsk);
+ return NULL;
+ }
+
+ return tsk;
+}
+EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init);
+
+int
+bcom_gen_bd_tx_reset(struct bcom_task *tsk)
+{
+ struct bcom_gen_bd_priv *priv = tsk->priv;
+ struct bcom_gen_bd_tx_var *var;
+ struct bcom_gen_bd_tx_inc *inc;
+
+ /* Shutdown the task */
+ bcom_disable_task(tsk->tasknum);
+
+ /* Reset the microcode */
+ var = (struct bcom_gen_bd_tx_var *) bcom_task_var(tsk->tasknum);
+ inc = (struct bcom_gen_bd_tx_inc *) bcom_task_inc(tsk->tasknum);
+
+ if (bcom_load_image(tsk->tasknum, bcom_gen_bd_tx_task))
+ return -1;
+
+ var->enable = bcom_eng->regs_base +
+ offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]);
+ var->fifo = (u32) priv->fifo;
+ var->bd_base = tsk->bd_pa;
+ var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size);
+ var->bd_start = tsk->bd_pa;
+
+ inc->incr_bytes = -(s16)sizeof(u32);
+ inc->incr_src = sizeof(u32);
+ inc->incr_src_ma = sizeof(u8);
+
+ /* Reset the BDs */
+ tsk->index = 0;
+ tsk->outdex = 0;
+
+ memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
+
+ /* Configure some stuff */
+ bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA);
+ bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum);
+
+ out_8(&bcom_eng->regs->ipr[priv->initiator], priv->ipr);
+ bcom_set_initiator(tsk->tasknum, priv->initiator);
+
+ out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_reset);
+
+void
+bcom_gen_bd_tx_release(struct bcom_task *tsk)
+{
+ /* Nothing special for the GenBD tasks */
+ bcom_task_free(tsk);
+}
+EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release);
+
+
+MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver");
+MODULE_AUTHOR("Jeff Gibbons <jeff.gibbons@appspec.com>");
+MODULE_LICENSE("GPL v2");
+
diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.h b/arch/powerpc/sysdev/bestcomm/gen_bd.h
new file mode 100644
index 00000000000..5b6fa803c6a
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/gen_bd.h
@@ -0,0 +1,48 @@
+/*
+ * Header for Bestcomm General Buffer Descriptor tasks driver
+ *
+ *
+ * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2006 AppSpec Computer Technologies Corp.
+ * Jeff Gibbons <jeff.gibbons@appspec.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 published
+ * by the Free Software Foundation.
+ *
+ *
+ */
+
+#ifndef __BESTCOMM_GEN_BD_H__
+#define __BESTCOMM_GEN_BD_H__
+
+struct bcom_gen_bd {
+ u32 status;
+ u32 buf_pa;
+};
+
+
+extern struct bcom_task *
+bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo,
+ int initiator, int ipr, int maxbufsize);
+
+extern int
+bcom_gen_bd_rx_reset(struct bcom_task *tsk);
+
+extern void
+bcom_gen_bd_rx_release(struct bcom_task *tsk);
+
+
+extern struct bcom_task *
+bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo,
+ int initiator, int ipr);
+
+extern int
+bcom_gen_bd_tx_reset(struct bcom_task *tsk);
+
+extern void
+bcom_gen_bd_tx_release(struct bcom_task *tsk);
+
+
+#endif /* __BESTCOMM_GEN_BD_H__ */
+
diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c
new file mode 100644
index 00000000000..99784383a84
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/sram.c
@@ -0,0 +1,177 @@
+/*
+ * Simple memory allocator for on-board SRAM
+ *
+ *
+ * Maintainer : Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Copyright (C) 2005 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+
+#include <asm/io.h>
+#include <asm/mmu.h>
+
+#include "sram.h"
+
+
+/* Struct keeping our 'state' */
+struct bcom_sram *bcom_sram = NULL;
+EXPORT_SYMBOL_GPL(bcom_sram); /* needed for inline functions */
+
+
+/* ======================================================================== */
+/* Public API */
+/* ======================================================================== */
+/* DO NOT USE in interrupts, if needed in irq handler, we should use the
+ _irqsave version of the spin_locks */
+
+int bcom_sram_init(struct device_node *sram_node, char *owner)
+{
+ int rv;
+ const u32 *regaddr_p;
+ u64 regaddr64, size64;
+ unsigned int psize;
+
+ /* Create our state struct */
+ if (bcom_sram) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Already initialized !\n", owner);
+ return -EBUSY;
+ }
+
+ bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL);
+ if (!bcom_sram) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Couldn't allocate internal state !\n", owner);
+ return -ENOMEM;
+ }
+
+ /* Get address and size of the sram */
+ regaddr_p = of_get_address(sram_node, 0, &size64, NULL);
+ if (!regaddr_p) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Invalid device node !\n", owner);
+ rv = -EINVAL;
+ goto error_free;
+ }
+
+ regaddr64 = of_translate_address(sram_node, regaddr_p);
+
+ bcom_sram->base_phys = (phys_addr_t) regaddr64;
+ bcom_sram->size = (unsigned int) size64;
+
+ /* Request region */
+ if (!request_mem_region(bcom_sram->base_phys, bcom_sram->size, owner)) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Couldn't request region !\n", owner);
+ rv = -EBUSY;
+ goto error_free;
+ }
+
+ /* Map SRAM */
+ /* sram is not really __iomem */
+ bcom_sram->base_virt = (void*) ioremap(bcom_sram->base_phys, bcom_sram->size);
+
+ if (!bcom_sram->base_virt) {
+ printk(KERN_ERR "%s: bcom_sram_init: "
+ "Map error SRAM zone 0x%08lx (0x%0x)!\n",
+ owner, bcom_sram->base_phys, bcom_sram->size );
+ rv = -ENOMEM;
+ goto error_release;
+ }
+
+ /* Create an rheap (defaults to 32 bits word alignment) */
+ bcom_sram->rh = rh_create(4);
+
+ /* Attach the free zones */
+#if 0
+ /* Currently disabled ... for future use only */
+ reg_addr_p = of_get_property(sram_node, "available", &psize);
+#else
+ regaddr_p = NULL;
+ psize = 0;
+#endif
+
+ if (!regaddr_p || !psize) {
+ /* Attach the whole zone */
+ rh_attach_region(bcom_sram->rh, 0, bcom_sram->size);
+ } else {
+ /* Attach each zone independently */
+ while (psize >= 2 * sizeof(u32)) {
+ phys_addr_t zbase = of_translate_address(sram_node, regaddr_p);
+ rh_attach_region(bcom_sram->rh, zbase - bcom_sram->base_phys, regaddr_p[1]);
+ regaddr_p += 2;
+ psize -= 2 * sizeof(u32);
+ }
+ }
+
+ /* Init our spinlock */
+ spin_lock_init(&bcom_sram->lock);
+
+ return 0;
+
+error_release:
+ release_mem_region(bcom_sram->base_phys, bcom_sram->size);
+error_free:
+ kfree(bcom_sram);
+ bcom_sram = NULL;
+
+ return rv;
+}
+EXPORT_SYMBOL_GPL(bcom_sram_init);
+
+void bcom_sram_cleanup(void)
+{
+ /* Free resources */
+ if (bcom_sram) {
+ rh_destroy(bcom_sram->rh);
+ iounmap((void __iomem *)bcom_sram->base_virt);
+ release_mem_region(bcom_sram->base_phys, bcom_sram->size);
+ kfree(bcom_sram);
+ bcom_sram = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(bcom_sram_cleanup);
+
+void* bcom_sram_alloc(int size, int align, phys_addr_t *phys)
+{
+ unsigned long offset;
+
+ spin_lock(&bcom_sram->lock);
+ offset = rh_alloc_align(bcom_sram->rh, size, align, NULL);
+ spin_unlock(&bcom_sram->lock);
+
+ if (IS_ERR_VALUE(offset))
+ return NULL;
+
+ *phys = bcom_sram->base_phys + offset;
+ return bcom_sram->base_virt + offset;
+}
+EXPORT_SYMBOL_GPL(bcom_sram_alloc);
+
+void bcom_sram_free(void *ptr)
+{
+ unsigned long offset;
+
+ if (!ptr)
+ return;
+
+ offset = ptr - bcom_sram->base_virt;
+
+ spin_lock(&bcom_sram->lock);
+ rh_free(bcom_sram->rh, offset);
+ spin_unlock(&bcom_sram->lock);
+}
+EXPORT_SYMBOL_GPL(bcom_sram_free);
+
diff --git a/arch/powerpc/sysdev/bestcomm/sram.h b/arch/powerpc/sysdev/bestcomm/sram.h
new file mode 100644
index 00000000000..b6d668963cc
--- /dev/null
+++ b/arch/powerpc/sysdev/bestcomm/sram.h
@@ -0,0 +1,54 @@
+/*
+ * Handling of a sram zone for bestcomm
+ *
+ *
+ * Copyright (C) 2007 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __BESTCOMM_SRAM_H__
+#define __BESTCOMM_SRAM_H__
+
+#include <asm/rheap.h>
+#include <asm/mmu.h>
+#include <linux/spinlock.h>
+
+
+/* Structure used internally */
+ /* The internals are here for the inline functions
+ * sake, certainly not for the user to mess with !
+ */
+struct bcom_sram {
+ phys_addr_t base_phys;
+ void *base_virt;
+ unsigned int size;
+ rh_info_t *rh;
+ spinlock_t lock;
+};
+
+extern struct bcom_sram *bcom_sram;
+
+
+/* Public API */
+extern int bcom_sram_init(struct device_node *sram_node, char *owner);
+extern void bcom_sram_cleanup(void);
+
+extern void* bcom_sram_alloc(int size, int align, phys_addr_t *phys);
+extern void bcom_sram_free(void *ptr);
+
+static inline phys_addr_t bcom_sram_va2pa(void *va) {
+ return bcom_sram->base_phys +
+ (unsigned long)(va - bcom_sram->base_virt);
+}
+
+static inline void *bcom_sram_pa2va(phys_addr_t pa) {
+ return bcom_sram->base_virt +
+ (unsigned long)(pa - bcom_sram->base_phys);
+}
+
+
+#endif /* __BESTCOMM_SRAM_H__ */
+
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
index ab11c0b2902..427027c7ea0 100644
--- a/arch/powerpc/sysdev/dcr.c
+++ b/arch/powerpc/sysdev/dcr.c
@@ -126,13 +126,13 @@ dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
}
EXPORT_SYMBOL_GPL(dcr_map);
-void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c)
+void dcr_unmap(dcr_host_t host, unsigned int dcr_c)
{
dcr_host_t h = host;
if (h.token == NULL)
return;
- h.token += dcr_n * h.stride;
+ h.token += host.base * h.stride;
iounmap(h.token);
h.token = NULL;
}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index af090c93be1..33df4c347ca 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -255,7 +255,7 @@ DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transpare
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent);
-DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent)
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent);
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 893e65439e8..e47938899a9 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -156,7 +156,7 @@ static inline u32 _mpic_read(enum mpic_reg_type type,
switch(type) {
#ifdef CONFIG_PPC_DCR
case mpic_access_dcr:
- return dcr_read(rb->dhost, rb->dhost.base + reg);
+ return dcr_read(rb->dhost, reg);
#endif
case mpic_access_mmio_be:
return in_be32(rb->base + (reg >> 2));
@@ -173,7 +173,7 @@ static inline void _mpic_write(enum mpic_reg_type type,
switch(type) {
#ifdef CONFIG_PPC_DCR
case mpic_access_dcr:
- return dcr_write(rb->dhost, rb->dhost.base + reg, value);
+ return dcr_write(rb->dhost, reg, value);
#endif
case mpic_access_mmio_be:
return out_be32(rb->base + (reg >> 2), value);
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 20dce468125..607925c8a99 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -102,6 +102,7 @@ config 44x
config 8xx
bool "8xx"
+ select PPC_LIB_RHEAP
config E200
bool "e200"
@@ -798,6 +799,7 @@ config CPM1
config CPM2
bool
depends on 8260 || MPC8560 || MPC8555
+ select PPC_LIB_RHEAP
default y
help
The CPM2 (Communications Processor Module) is a coprocessor on
@@ -1277,6 +1279,10 @@ config BOOT_LOAD
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx
+
+config PPC_LIB_RHEAP
+ bool
+
endmenu
source "net/Kconfig"
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index eee6264e8a0..95894ef7bea 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -22,22 +22,22 @@ endif
LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic
# The -Iarch/$(ARCH)/include is temporary while we are merging
-CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
-AFLAGS += -Iarch/$(ARCH)
-CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
+KBUILD_CPPFLAGS += -Iarch/$(ARCH) -Iarch/$(ARCH)/include
+KBUILD_AFLAGS += -Iarch/$(ARCH)
+KBUILD_CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -mmultiple
# No AltiVec instruction when building kernel
-CFLAGS += $(call cc-option, -mno-altivec)
+KBUILD_CFLAGS += $(call cc-option, -mno-altivec)
-CPP = $(CC) -E $(CFLAGS)
+CPP = $(CC) -E $(KBUILD_CFLAGS)
# Temporary hack until we have migrated to asm-powerpc
LINUXINCLUDE += -Iarch/$(ARCH)/include
CHECKFLAGS += -D__powerpc__
ifndef CONFIG_FSL_BOOKE
-CFLAGS += -mstring
+KBUILD_CFLAGS += -mstring
endif
cpu-as-$(CONFIG_4xx) += -Wa,-m405
@@ -45,8 +45,8 @@ cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
cpu-as-$(CONFIG_E500) += -Wa,-me500
cpu-as-$(CONFIG_E200) += -Wa,-me200
-AFLAGS += $(cpu-as-y)
-CFLAGS += $(cpu-as-y)
+KBUILD_AFLAGS += $(cpu-as-y)
+KBUILD_CFLAGS += $(cpu-as-y)
# Default to the common case.
KBUILD_DEFCONFIG := common_defconfig
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index b739e25d472..487dc66dcc7 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -13,7 +13,6 @@
# modified by Cort (cort@cs.nmt.edu)
#
-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/mm/fault.c b/arch/ppc/mm/fault.c
index b98244e277f..94913ddcf76 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -297,7 +297,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
return SIGKILL;
do_sigbus:
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 143ed8e154a..f708be367b0 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -15,16 +15,16 @@
ifndef CONFIG_64BIT
LDFLAGS := -m elf_s390
-CFLAGS += -m31
-AFLAGS += -m31
+KBUILD_CFLAGS += -m31
+KBUILD_AFLAGS += -m31
UTS_MACHINE := s390
STACK_SIZE := 8192
CHECKFLAGS += -D__s390__ -msize-long
else
LDFLAGS := -m elf64_s390
MODFLAGS += -fpic -D__PIC__
-CFLAGS += -m64
-AFLAGS += -m64
+KBUILD_CFLAGS += -m64
+KBUILD_AFLAGS += -m64
UTS_MACHINE := s390x
STACK_SIZE := 16384
CHECKFLAGS += -D__s390__ -D__s390x__
@@ -77,9 +77,9 @@ cflags-$(CONFIG_WARN_STACK) += -mwarn-dynamicstack
cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE)
endif
-CFLAGS += -mbackchain -msoft-float $(cflags-y)
-CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
-AFLAGS += $(aflags-y)
+KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y)
+KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
+KBUILD_AFLAGS += $(aflags-y)
OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -e start
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 5236fdb17fc..50b85d07ddd 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -58,9 +58,9 @@
#include <linux/vfs.h>
#include <linux/ptrace.h>
#include <linux/fadvise.h>
+#include <linux/ipc.h>
#include <asm/types.h>
-#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index f3bceb16532..139ca153d5c 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -68,9 +68,15 @@ STACK_SIZE = 1 << STACK_SHIFT
l %r1,BASED(.Ltrace_irq_off)
basr %r14,%r1
.endm
+
+ .macro LOCKDEP_SYS_EXIT
+ l %r1,BASED(.Llockdep_sys_exit)
+ basr %r14,%r1
+ .endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
+#define LOCKDEP_SYS_EXIT
#endif
/*
@@ -260,6 +266,7 @@ sysc_return:
bno BASED(sysc_leave)
tm __TI_flags+3(%r9),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.)
+ LOCKDEP_SYS_EXIT
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
@@ -283,6 +290,7 @@ sysc_work:
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
+ LOCKDEP_SYS_EXIT
b BASED(sysc_leave)
#
@@ -572,6 +580,7 @@ io_return:
#endif
tm __TI_flags+3(%r9),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.)
+ LOCKDEP_SYS_EXIT
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
@@ -618,6 +627,7 @@ io_work_loop:
bo BASED(io_reschedule)
tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
bnz BASED(io_sigpending)
+ LOCKDEP_SYS_EXIT
b BASED(io_leave)
#
@@ -1040,6 +1050,8 @@ cleanup_io_leave_insn:
.Ltrace_irq_on: .long trace_hardirqs_on
.Ltrace_irq_off:
.long trace_hardirqs_off
+.Llockdep_sys_exit:
+ .long lockdep_sys_exit
#endif
.Lcritical_start:
.long __critical_start + 0x80000000
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 9c0d5cc8269..05e26d1fdf4 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -66,9 +66,14 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
.macro TRACE_IRQS_OFF
brasl %r14,trace_hardirqs_off
.endm
+
+ .macro LOCKDEP_SYS_EXIT
+ brasl %r14,lockdep_sys_exit
+ .endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
+#define LOCKDEP_SYS_EXIT
#endif
.macro STORE_TIMER lc_offset
@@ -255,6 +260,7 @@ sysc_return:
jno sysc_leave
tm __TI_flags+7(%r9),_TIF_WORK_SVC
jnz sysc_work # there is work to do (signals etc.)
+ LOCKDEP_SYS_EXIT
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
@@ -278,6 +284,7 @@ sysc_work:
jo sysc_restart
tm __TI_flags+7(%r9),_TIF_SINGLE_STEP
jo sysc_singlestep
+ LOCKDEP_SYS_EXIT
j sysc_leave
#
@@ -558,6 +565,7 @@ io_return:
#endif
tm __TI_flags+7(%r9),_TIF_WORK_INT
jnz io_work # there is work to do (signals etc.)
+ LOCKDEP_SYS_EXIT
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
@@ -605,6 +613,7 @@ io_work_loop:
jo io_reschedule
tm __TI_flags+7(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)
jnz io_sigpending
+ LOCKDEP_SYS_EXIT
j io_leave
#
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index e40373d9fbc..c5549a20628 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -33,6 +33,8 @@
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
/* Make sure the probe isn't going on a difficult instruction */
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index f4503ca2763..1d81bf9488a 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -683,11 +683,6 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
wake_up_process(child);
return 0;
- case PTRACE_DETACH:
- /* detach a process that was attached. */
- return ptrace_detach(child, data);
-
-
/* Do requests that differ for 31/64 bit */
default:
#ifdef CONFIG_COMPAT
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 1eaff84a1eb..fefee99f28a 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -28,9 +28,9 @@
#include <linux/utsname.h>
#include <linux/personality.h>
#include <linux/unistd.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
/*
* sys_pipe() is the normal C calling standard for creating
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index fabc50adc46..d4ed93dfb9c 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -17,6 +17,7 @@
#include <linux/ctype.h>
#include <linux/swap.h>
#include <linux/kthread.h>
+#include <linux/oom.h>
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 4c1ac341ec8..14c241ccdd4 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -218,7 +218,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
}
printk("VM: killing process %s\n", tsk->comm);
if (regs->psw.mask & PSW_MASK_PSTATE)
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
do_no_context(regs, error_code, address);
return 0;
}
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index a0a2083aad3..408342b175c 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -91,12 +91,12 @@ LDFLAGS_vmlinux += --defsym 'jiffies=jiffies_64+4'
LDFLAGS += -EB
endif
-CFLAGS += -pipe $(cflags-y)
-AFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -pipe $(cflags-y)
+KBUILD_AFLAGS += $(cflags-y)
head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
core-y += arch/sh/kernel/ arch/sh/mm/
core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
index 8143d1b948e..d22f6eac9cc 100644
--- a/arch/sh/boards/hp6xx/pm.c
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -67,14 +67,14 @@ static int hp6x0_pm_enter(suspend_state_t state)
return 0;
}
-static struct pm_ops hp6x0_pm_ops = {
+static struct platform_suspend_ops hp6x0_pm_ops = {
.enter = hp6x0_pm_enter,
- .valid = pm_valid_only_mem,
+ .valid = suspend_valid_only_mem,
};
static int __init hp6x0_pm_init(void)
{
- pm_set_ops(&hp6x0_pm_ops);
+ suspend_set_ops(&hp6x0_pm_ops);
return 0;
}
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 013504ae112..906a13f82fe 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -21,7 +21,7 @@ IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
$(CONFIG_MEMORY_START) + \
$(CONFIG_BOOT_LINK_OFFSET)]')
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c
index 230d6ec0d23..888a3405059 100644
--- a/arch/sh/drivers/pci/dma-dreamcast.c
+++ b/arch/sh/drivers/pci/dma-dreamcast.c
@@ -51,7 +51,7 @@ void *dreamcast_consistent_alloc(struct device *dev, size_t size,
buf = P2SEGADDR(buf);
/* Flush the dcache before we hand off the buffer */
- dma_cache_wback_inv((void *)buf, size);
+ __flush_purge_region((void *)buf, size);
return (void *)buf;
}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index f64a2d2416d..ac725f0aeb7 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -211,10 +211,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
#ifdef CONFIG_SH_DSP
case PTRACE_GETDSPREGS: {
unsigned long dp;
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 024ce5dedd8..d545a686a20 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -22,9 +22,9 @@
#include <linux/utsname.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/ipc.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/unistd.h>
/*
diff --git a/arch/sh/kernel/vsyscall/vsyscall.lds.S b/arch/sh/kernel/vsyscall/vsyscall.lds.S
index b13c3d439fe..c9bf2af35d3 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.lds.S
+++ b/arch/sh/kernel/vsyscall/vsyscall.lds.S
@@ -17,45 +17,52 @@ ENTRY(__kernel_vsyscall);
SECTIONS
{
- . = SIZEOF_HEADERS;
+ . = SIZEOF_HEADERS;
- .hash : { *(.hash) } :text
- .gnu.hash : { *(.gnu.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
- /* This linker script is used both with -r and with -shared.
- For the layouts to match, we need to skip more than enough
- space for the dynamic symbol table et al. If this amount
- is insufficient, ld -shared will barf. Just increase it here. */
- . = 0x400;
+ /*
+ * This linker script is used both with -r and with -shared.
+ * For the layouts to match, we need to skip more than enough
+ * space for the dynamic symbol table et al. If this amount
+ * is insufficient, ld -shared will barf. Just increase it here.
+ */
+ . = 0x400;
- .text : { *(.text) } :text =0x90909090
- .note : { *(.note.*) } :text :note
- .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
- .eh_frame : { KEEP (*(.eh_frame)) } :text
- .dynamic : { *(.dynamic) } :text :dynamic
- .useless : {
- *(.got.plt) *(.got)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- } :text
+ .text : { *(.text) } :text =0x90909090
+ .note : { *(.note.*) } :text :note
+ .eh_frame_hdr : { *(.eh_frame_hdr ) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+ .dynamic : { *(.dynamic) } :text :dynamic
+ .useless : {
+ *(.got.plt) *(.got)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ } :text
}
/*
+ * Very old versions of ld do not recognize this name token; use the constant.
+ */
+#define PT_GNU_EH_FRAME 0x6474e550
+
+/*
* We must supply the ELF program headers explicitly to get just one
* PT_LOAD segment, and set the flags explicitly to make segments read-only.
*/
PHDRS
{
- text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
- dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
- note PT_NOTE FLAGS(4); /* PF_R */
- eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
+ text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
}
/*
@@ -63,12 +70,12 @@ PHDRS
*/
VERSION
{
- LINUX_2.6 {
- global:
- __kernel_vsyscall;
- __kernel_sigreturn;
- __kernel_rt_sigreturn;
+ LINUX_2.6 {
+ global:
+ __kernel_vsyscall;
+ __kernel_sigreturn;
+ __kernel_rt_sigreturn;
- local: *;
- };
+ local: *;
+ };
}
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 38c82d890ff..e220c29a3c0 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -34,7 +34,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
/*
* We must flush the cache before we pass it on to the device
*/
- dma_cache_wback_inv(ret, size);
+ __flush_purge_region(ret, size);
page = virt_to_page(ret);
free = page + (size >> PAGE_SHIFT);
@@ -68,13 +68,13 @@ void consistent_sync(void *vaddr, size_t size, int direction)
switch (direction) {
case DMA_FROM_DEVICE: /* invalidate only */
- dma_cache_inv(p1addr, size);
+ __flush_invalidate_region(p1addr, size);
break;
case DMA_TO_DEVICE: /* writeback only */
- dma_cache_wback(p1addr, size);
+ __flush_wback_region(p1addr, size);
break;
case DMA_BIDIRECTIONAL: /* writeback and invalidate */
- dma_cache_wback_inv(p1addr, size);
+ __flush_purge_region(p1addr, size);
break;
default:
BUG();
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 04a39aa7f1f..4729668ce5b 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -214,7 +214,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 82b68c789a5..d5e160da64b 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -294,12 +294,6 @@ int arch_add_memory(int nid, u64 start, u64 size)
}
EXPORT_SYMBOL_GPL(arch_add_memory);
-int remove_memory(u64 start, u64 size)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(remove_memory);
-
#ifdef CONFIG_NUMA
int memory_add_physaddr_to_nid(u64 addr)
{
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 7d43758dc24..1d45b82f0a6 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -292,8 +292,7 @@ void pmb_unmap(unsigned long addr)
} while (pmbe);
}
-static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep,
- unsigned long flags)
+static void pmb_cache_ctor(struct kmem_cache *cachep, void *pmb)
{
struct pmb_entry *pmbe = pmb;
diff --git a/arch/sh64/Makefile b/arch/sh64/Makefile
index 8290c6380d7..8dac7e1a2be 100644
--- a/arch/sh64/Makefile
+++ b/arch/sh64/Makefile
@@ -26,7 +26,7 @@ LDFLAGS += -EB -mshelf32_linux
endif
# No requirements for endianess support from AFLAGS, 'as' always run through gcc
-CFLAGS += $(cpu-y)
+KBUILD_CFLAGS += $(cpu-y)
LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_CACHED_MEMORY_OFFSET) \
--defsym phys_stext_shmedia=phys_stext+1 \
@@ -58,7 +58,7 @@ ifneq ($(machine-y),)
core-y += arch/sh64/mach-$(machine-y)/
endif
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
libs-y += arch/$(ARCH)/lib/ $(LIBGCC)
drivers-$(CONFIG_OPROFILE) += arch/sh64/oprofile/
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index df06c647746..8a2d339cf76 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -244,10 +244,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index b7f18e298a2..de0a303ba26 100644
--- a/arch/sh64/kernel/sys_sh64.c
+++ b/arch/sh64/kernel/sys_sh64.c
@@ -29,8 +29,8 @@
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/syscalls.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/ptrace.h>
#include <asm/unistd.h>
diff --git a/arch/sh64/mm/consistent.c b/arch/sh64/mm/consistent.c
index 8875a2a40da..c439620402c 100644
--- a/arch/sh64/mm/consistent.c
+++ b/arch/sh64/mm/consistent.c
@@ -11,6 +11,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <asm/io.h>
@@ -32,7 +33,7 @@ void *consistent_alloc(struct pci_dev *hwdev, size_t size,
if (vp != NULL) {
memset(vp, 0, size);
*dma_handle = virt_to_phys(ret);
- dma_cache_wback_inv((unsigned long)ret, size);
+ dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL);
}
return vp;
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index 0d069d82141..dd81c669c79 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -334,7 +334,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", tsk->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 9d327ec5975..c0f4ba109da 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -321,7 +321,6 @@ endmenu
source "fs/Kconfig"
menu "Instrumentation Support"
- depends on EXPERIMENTAL
source "arch/sparc/oprofile/Kconfig"
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index f33c3817f01..fef28e267a5 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -8,16 +8,16 @@
#
#
-# Uncomment the first CFLAGS if you are doing kgdb source level
+# Uncomment the first KBUILD_CFLAGS if you are doing kgdb source level
# debugging of the kernel to get the proper debugging information.
AS := $(AS) -32
LDFLAGS := -m elf32_sparc
CHECKFLAGS += -D__sparc__
-#CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7
-CFLAGS := $(CFLAGS) -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
-AFLAGS := $(AFLAGS) -m32
+#KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
+KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+KBUILD_AFLAGS += -m32
#LDFLAGS_vmlinux = -N -Ttext 0xf0004000
# Since 2.5.40, the first stage is left not btfix-ed.
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 62182d2d7b0..9c3ed88853f 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/pci.h> /* struct pci_dev */
#include <linux/proc_fs.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/vaddrs.h>
@@ -717,19 +718,19 @@ void pci_unmap_page(struct pci_dev *hwdev,
* Device ownership issues as mentioned above for pci_map_single are
* the same here.
*/
-int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
+int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
int direction)
{
+ struct scatterlist *sg;
int n;
BUG_ON(direction == PCI_DMA_NONE);
/* IIep is write-through, not flushing. */
- for (n = 0; n < nents; n++) {
+ 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;
sg->dvma_length = sg->length;
- sg++;
}
return nents;
}
@@ -738,19 +739,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
* Again, cpu read rules concerning calls here are the same as for
* pci_unmap_single() above.
*/
-void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
+void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
int direction)
{
+ struct scatterlist *sg;
int n;
BUG_ON(direction == PCI_DMA_NONE);
if (direction != PCI_DMA_TODEVICE) {
- for (n = 0; n < nents; n++) {
+ for_each_sg(sgl, sg, nents, n) {
BUG_ON(page_address(sg->page) == NULL);
mmu_inval_dma_area(
(unsigned long) page_address(sg->page),
(sg->length + PAGE_SIZE-1) & PAGE_MASK);
- sg++;
}
}
}
@@ -789,34 +790,34 @@ void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t
* The same as pci_dma_sync_single_* but for a scatter-gather list,
* same rules and usage.
*/
-void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
{
+ struct scatterlist *sg;
int n;
BUG_ON(direction == PCI_DMA_NONE);
if (direction != PCI_DMA_TODEVICE) {
- for (n = 0; n < nents; n++) {
+ for_each_sg(sgl, sg, nents, n) {
BUG_ON(page_address(sg->page) == NULL);
mmu_inval_dma_area(
(unsigned long) page_address(sg->page),
(sg->length + PAGE_SIZE-1) & PAGE_MASK);
- sg++;
}
}
}
-void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
{
+ struct scatterlist *sg;
int n;
BUG_ON(direction == PCI_DMA_NONE);
if (direction != PCI_DMA_TODEVICE) {
- for (n = 0; n < nents; n++) {
+ for_each_sg(sgl, sg, nents, n) {
BUG_ON(page_address(sg->page) == NULL);
mmu_inval_dma_area(
(unsigned long) page_address(sg->page),
(sg->length + PAGE_SIZE-1) & PAGE_MASK);
- sg++;
}
}
}
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index fb2caef79ce..3ea000d15e3 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -585,24 +585,6 @@ static int __init of_debug(char *str)
__setup("of_debug=", of_debug);
-int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
-{
- /* initialize common driver fields */
- if (!drv->driver.name)
- drv->driver.name = drv->name;
- if (!drv->driver.owner)
- drv->driver.owner = drv->owner;
- drv->driver.bus = bus;
-
- /* register with core */
- return driver_register(&drv->driver);
-}
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-
struct of_device* of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent,
@@ -628,6 +610,4 @@ struct of_device* of_platform_device_create(struct device_node *np,
return dev;
}
-EXPORT_SYMBOL(of_register_driver);
-EXPORT_SYMBOL(of_unregister_driver);
EXPORT_SYMBOL(of_platform_device_create);
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index a954a0c0000..6c0221e9a9f 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -21,9 +21,9 @@
#include <linux/utsname.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/unistd.h>
/* #define DEBUG_UNIMP_SYSCALL */
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 50747fe4435..e4d9c8e19df 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -369,7 +369,7 @@ out_of_memory:
up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", tsk->comm);
if (from_user)
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 7c89893b1fe..375b4db6370 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -11,8 +11,8 @@
#include <linux/mm.h>
#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
#include <linux/bitops.h>
+#include <linux/scatterlist.h>
-#include <asm/scatterlist.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/sbus.h>
@@ -144,8 +144,9 @@ 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[sz].dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg[sz].page) + sg[sz].offset, sg[sz].length);
- sg[sz].dvma_length = sg[sz].length;
+ sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+ sg->dvma_length = sg->length;
+ sg = sg_next(sg);
}
spin_unlock_irqrestore(&iounit->lock, flags);
}
@@ -173,11 +174,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_
spin_lock_irqsave(&iounit->lock, flags);
while (sz != 0) {
--sz;
- len = ((sg[sz].dvma_address & ~PAGE_MASK) + sg[sz].length + (PAGE_SIZE-1)) >> PAGE_SHIFT;
- vaddr = (sg[sz].dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
+ len = ((sg->dvma_address & ~PAGE_MASK) + sg->length + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+ vaddr = (sg->dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr));
for (len += vaddr; vaddr < len; vaddr++)
clear_bit(vaddr, iounit->bmap);
+ sg = sg_next(sg);
}
spin_unlock_irqrestore(&iounit->lock, flags);
}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 52e907af9d2..283656d9f6e 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -12,8 +12,8 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
+#include <linux/scatterlist.h>
-#include <asm/scatterlist.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/sbus.h>
@@ -240,7 +240,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
sg->dvma_length = (__u32) sg->length;
- sg++;
+ sg = sg_next(sg);
}
}
@@ -254,7 +254,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
sg->dvma_length = (__u32) sg->length;
- sg++;
+ sg = sg_next(sg);
}
}
@@ -285,7 +285,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_length = (__u32) sg->length;
- sg++;
+ sg = sg_next(sg);
}
}
@@ -325,7 +325,7 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b
n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus);
sg->dvma_address = 0x21212121;
- sg++;
+ sg = sg_next(sg);
}
}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 005a3e72d4f..ee6708fc449 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -17,8 +17,8 @@
#include <linux/highmem.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
+#include <linux/scatterlist.h>
-#include <asm/scatterlist.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
@@ -1228,8 +1228,9 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
{
while (sz != 0) {
--sz;
- sg[sz].dvma_address = (__u32)sun4c_lockarea(page_address(sg[sz].page) + sg[sz].offset, sg[sz].length);
- sg[sz].dvma_length = sg[sz].length;
+ sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+ sg->dvma_length = sg->length;
+ sg = sg_next(sg);
}
}
@@ -1244,7 +1245,8 @@ static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b
{
while (sz != 0) {
--sz;
- sun4c_unlockarea((char *)sg[sz].dvma_address, sg[sz].length);
+ sun4c_unlockarea((char *)sg->dvma_address, sg->length);
+ sg = sg_next(sg);
}
}
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 33dabf588bd..59c4d752d28 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -240,10 +240,10 @@ config ARCH_SELECT_MEMORY_MODEL
config ARCH_SPARSEMEM_ENABLE
def_bool y
+ select SPARSEMEM_VMEMMAP_ENABLE
config ARCH_SPARSEMEM_DEFAULT
def_bool y
- select SPARSEMEM_STATIC
source "mm/Kconfig"
@@ -461,7 +461,6 @@ source "drivers/fc4/Kconfig"
source "fs/Kconfig"
menu "Instrumentation Support"
- depends on EXPERIMENTAL
source "arch/sparc64/oprofile/Kconfig"
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index cad10c5b83d..6c92a42efe7 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -39,17 +39,17 @@ AS := $(AS) --undeclared-regs
endif
ifneq ($(NEW_GCC),y)
- CFLAGS := $(CFLAGS) -pipe -mno-fpu -mtune=ultrasparc -mmedlow \
+ KBUILD_CFLAGS += -pipe -mno-fpu -mtune=ultrasparc -mmedlow \
-ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare
else
- CFLAGS := $(CFLAGS) -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
+ KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
-ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
$(CC_UNDECL)
- AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
+ KBUILD_AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
endif
ifeq ($(CONFIG_MCOUNT),y)
- CFLAGS := $(CFLAGS) -pg
+ KBUILD_CFLAGS += -pg
endif
head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index d208cc7804f..92c1b36a2e1 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -35,11 +35,14 @@
static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout32_library(struct file*);
-static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file);
+static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
static struct linux_binfmt aout32_format = {
- NULL, THIS_MODULE, load_aout32_binary, load_aout32_library, aout32_core_dump,
- PAGE_SIZE
+ .module = THIS_MODULE,
+ .load_binary = load_aout32_binary,
+ .load_shlib = load_aout32_library,
+ .core_dump = aout32_core_dump,
+ .min_coredump = PAGE_SIZE,
};
static void set_brk(unsigned long start, unsigned long end)
@@ -83,7 +86,7 @@ if (file->f_op->llseek) { \
* dumping of the process results in another error..
*/
-static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file)
+static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
mm_segment_t fs;
int has_dumped = 0;
@@ -102,13 +105,11 @@ static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file)
/* If the size of the dump file exceeds the rlimit, then see what would happen
if we wrote the stack, but not the data area. */
- if ((dump.u_dsize+dump.u_ssize) >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if (dump.u_dsize + dump.u_ssize > limit)
dump.u_dsize = 0;
/* Make sure we have enough room to write the stack and data areas. */
- if ((dump.u_ssize) >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if (dump.u_ssize > limit)
dump.u_ssize = 0;
/* make sure we actually have a data and stack area to dump */
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index b35a62167e9..29af777d7ac 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -475,12 +475,11 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
#define SG_ENT_PHYS_ADDRESS(SG) \
(__pa(page_address((SG)->page)) + (SG)->offset)
-static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
- int nused, int nelems,
- unsigned long iopte_protection)
+static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
+ int nused, int nelems,
+ unsigned long iopte_protection)
{
struct scatterlist *dma_sg = sg;
- struct scatterlist *sg_end = sg + nelems;
int i;
for (i = 0; i < nused; i++) {
@@ -515,7 +514,8 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
break;
}
- sg++;
+ sg = sg_next(sg);
+ nelems--;
}
pteval = iopte_protection | (pteval & IOPTE_PAGE);
@@ -528,24 +528,26 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
}
pteval = (pteval & IOPTE_PAGE) + len;
- sg++;
+ sg = sg_next(sg);
+ nelems--;
/* Skip over any tail mappings we've fully mapped,
* adjusting pteval along the way. Stop when we
* detect a page crossing event.
*/
- while (sg < sg_end &&
+ while (nelems &&
(pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
(pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
((pteval ^
(SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
pteval += sg->length;
- sg++;
+ sg = sg_next(sg);
+ nelems--;
}
if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
pteval = ~0UL;
} while (dma_npages != 0);
- dma_sg++;
+ dma_sg = sg_next(dma_sg);
}
}
@@ -606,7 +608,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
sgtmp = sglist;
while (used && sgtmp->dma_length) {
sgtmp->dma_address += dma_base;
- sgtmp++;
+ sgtmp = sg_next(sgtmp);
used--;
}
used = nelems - used;
@@ -642,6 +644,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
struct strbuf *strbuf;
iopte_t *base;
unsigned long flags, ctx, i, npages;
+ struct scatterlist *sg, *sgprv;
u32 bus_addr;
if (unlikely(direction == DMA_NONE)) {
@@ -654,11 +657,14 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
bus_addr = sglist->dma_address & IO_PAGE_MASK;
- for (i = 1; i < nelems; i++)
- if (sglist[i].dma_length == 0)
+ sgprv = NULL;
+ for_each_sg(sglist, sg, nelems, i) {
+ if (sg->dma_length == 0)
break;
- i--;
- npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) -
+ sgprv = sg;
+ }
+
+ npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) -
bus_addr) >> IO_PAGE_SHIFT;
base = iommu->page_table +
@@ -730,6 +736,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
struct iommu *iommu;
struct strbuf *strbuf;
unsigned long flags, ctx, npages, i;
+ struct scatterlist *sg, *sgprv;
u32 bus_addr;
iommu = dev->archdata.iommu;
@@ -753,11 +760,14 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
/* Step 2: Kick data out of streaming buffers. */
bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
- for(i = 1; i < nelems; i++)
- if (!sglist[i].dma_length)
+ sgprv = NULL;
+ for_each_sg(sglist, sg, nelems, i) {
+ if (sg->dma_length == 0)
break;
- i--;
- npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length)
+ sgprv = sg;
+ }
+
+ npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length)
- bus_addr) >> IO_PAGE_SHIFT;
strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index 12c93a3eee2..d7ca900ec51 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -12,18 +12,22 @@
*/
#ifdef VERIFY_SG
-static int verify_lengths(struct scatterlist *sg, int nents, int npages)
+static int verify_lengths(struct scatterlist *sglist, int nents, int npages)
{
int sg_len, dma_len;
int i, pgcount;
+ struct scatterlist *sg;
sg_len = 0;
- for (i = 0; i < nents; i++)
- sg_len += sg[i].length;
+ for_each_sg(sglist, sg, nents, i)
+ sg_len += sg->length;
dma_len = 0;
- for (i = 0; i < nents && sg[i].dma_length; i++)
- dma_len += sg[i].dma_length;
+ for_each_sg(sglist, sg, nents, i) {
+ if (!sg->dma_length)
+ break;
+ dma_len += sg->dma_length;
+ }
if (sg_len != dma_len) {
printk("verify_lengths: Error, different, sg[%d] dma[%d]\n",
@@ -32,13 +36,16 @@ static int verify_lengths(struct scatterlist *sg, int nents, int npages)
}
pgcount = 0;
- for (i = 0; i < nents && sg[i].dma_length; i++) {
+ for_each_sg(sglist, sg, nents, i) {
unsigned long start, end;
- start = sg[i].dma_address;
+ if (!sg->dma_length)
+ break;
+
+ start = sg->dma_address;
start = start & IO_PAGE_MASK;
- end = sg[i].dma_address + sg[i].dma_length;
+ end = sg->dma_address + sg->dma_length;
end = (end + (IO_PAGE_SIZE - 1)) & IO_PAGE_MASK;
pgcount += ((end - start) >> IO_PAGE_SHIFT);
@@ -113,7 +120,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
if (dlen > 0 && ((daddr & ~IO_PAGE_MASK) == 0))
iopte++;
- sg++;
+ sg = sg_next(sg);
if (--nents <= 0)
break;
sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
@@ -147,7 +154,7 @@ static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
nents = verify_one_map(dma_sg, &sg, nents, &iopte);
if (nents <= 0)
break;
- dma_sg++;
+ dma_sg = sg_next(dma_sg);
if (dma_sg->dma_length == 0)
break;
}
@@ -169,22 +176,24 @@ static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte)
return 0;
}
-void verify_sglist(struct scatterlist *sg, int nents, iopte_t *iopte, int npages)
+void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int npages)
{
- if (verify_lengths(sg, nents, npages) < 0 ||
- verify_maps(sg, nents, iopte) < 0) {
+ struct scatterlist *sg;
+
+ if (verify_lengths(sglist, nents, npages) < 0 ||
+ verify_maps(sglist, nents, iopte) < 0) {
int i;
printk("verify_sglist: Crap, messed up mappings, dumping, iodma at ");
- printk("%016lx.\n", sg->dma_address & IO_PAGE_MASK);
+ printk("%016lx.\n", sglist->dma_address & IO_PAGE_MASK);
- for (i = 0; i < nents; i++) {
+ for_each_sg(sglist, sg, nents, i) {
printk("sg(%d): page_addr(%p) off(%x) length(%x) "
- "dma_address[%016lx] dma_length[%016lx]\n",
+ "dma_address[%016x] dma_length[%016x]\n",
i,
- page_address(sg[i].page), sg[i].offset,
- sg[i].length,
- sg[i].dma_address, sg[i].dma_length);
+ page_address(sg->page), sg->offset,
+ sg->length,
+ sg->dma_address, sg->dma_length);
}
}
@@ -205,12 +214,12 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
while (--nents) {
unsigned long addr;
- sg++;
+ sg = sg_next(sg);
addr = (unsigned long) (page_address(sg->page) + sg->offset);
if (! VCONTIG(prev, addr)) {
dma_sg->dma_address = dent_addr;
dma_sg->dma_length = dent_len;
- dma_sg++;
+ dma_sg = sg_next(dma_sg);
dent_addr = ((dent_addr +
dent_len +
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
index ad791014419..75b5a581452 100644
--- a/arch/sparc64/kernel/iommu_common.h
+++ b/arch/sparc64/kernel/iommu_common.h
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/scatterlist.h>
#include <asm/iommu.h>
#include <asm/scatterlist.h>
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index f3922e5a89f..2c3bea22815 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -877,7 +877,7 @@ void __cpuinit sun4v_register_mondo_queues(int this_cpu)
static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
{
unsigned long size = PAGE_ALIGN(qmask + 1);
- void *p = __alloc_bootmem_low(size, size, 0);
+ void *p = __alloc_bootmem(size, size, 0);
if (!p) {
prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
prom_halt();
@@ -889,7 +889,7 @@ static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask)
{
unsigned long size = PAGE_ALIGN(qmask + 1);
- void *p = __alloc_bootmem_low(size, size, 0);
+ void *p = __alloc_bootmem(size, size, 0);
if (!p) {
prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
@@ -906,7 +906,7 @@ static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb)
BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
- page = alloc_bootmem_low_pages(PAGE_SIZE);
+ page = alloc_bootmem_pages(PAGE_SIZE);
if (!page) {
prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
prom_halt();
@@ -953,7 +953,7 @@ void __init init_IRQ(void)
kill_prom_timer();
size = sizeof(struct ino_bucket) * NUM_IVECS;
- ivector_table = alloc_bootmem_low(size);
+ ivector_table = alloc_bootmem(size);
if (!ivector_table) {
prom_printf("Fatal error, cannot allocate ivector_table\n");
prom_halt();
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index c93a15b785f..d94f901d321 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -42,6 +42,8 @@
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
p->ainsn.insn[0] = *p->addr;
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index d4024ac0d61..964527d2ffa 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -226,6 +226,15 @@ kvmap_dtlb_load:
ba,pt %xcc, sun4v_dtlb_load
mov %g5, %g3
+kvmap_vmemmap:
+ sub %g4, %g5, %g5
+ srlx %g5, 22, %g5
+ sethi %hi(vmemmap_table), %g1
+ sllx %g5, 3, %g5
+ or %g1, %lo(vmemmap_table), %g1
+ ba,pt %xcc, kvmap_dtlb_load
+ ldx [%g1 + %g5], %g5
+
kvmap_dtlb_nonlinear:
/* Catch kernel NULL pointer derefs. */
sethi %hi(PAGE_SIZE), %g5
@@ -233,6 +242,13 @@ kvmap_dtlb_nonlinear:
bleu,pn %xcc, kvmap_dtlb_longpath
nop
+ /* Do not use the TSB for vmemmap. */
+ mov (VMEMMAP_BASE >> 24), %g5
+ sllx %g5, 24, %g5
+ cmp %g4,%g5
+ bgeu,pn %xcc, kvmap_vmemmap
+ nop
+
KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
kvmap_dtlb_tsbmiss:
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 42d779866fb..fc5c0cc793b 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -869,26 +869,6 @@ static int __init of_debug(char *str)
__setup("of_debug=", of_debug);
-int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
-{
- /* initialize common driver fields */
- if (!drv->driver.name)
- drv->driver.name = drv->name;
- if (!drv->driver.owner)
- drv->driver.owner = drv->owner;
- drv->driver.bus = bus;
-
- /* register with core */
- return driver_register(&drv->driver);
-}
-EXPORT_SYMBOL(of_register_driver);
-
-void of_unregister_driver(struct of_platform_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-EXPORT_SYMBOL(of_unregister_driver);
-
struct of_device* of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent,
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index c76bfbb7da0..923e0bcc3bf 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -396,6 +396,13 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
saw_mem = saw_io = 0;
pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i);
+ if (!pbm_ranges) {
+ prom_printf("PCI: Fatal error, missing PBM ranges property "
+ " for %s\n",
+ pbm->name);
+ prom_halt();
+ }
+
num_pbm_ranges = i / sizeof(*pbm_ranges);
for (i = 0; i < num_pbm_ranges; i++) {
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 95de1444ee6..fe46ace3e59 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -368,12 +368,11 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
#define SG_ENT_PHYS_ADDRESS(SG) \
(__pa(page_address((SG)->page)) + (SG)->offset)
-static inline long fill_sg(long entry, struct device *dev,
- struct scatterlist *sg,
- int nused, int nelems, unsigned long prot)
+static long fill_sg(long entry, struct device *dev,
+ struct scatterlist *sg,
+ int nused, int nelems, unsigned long prot)
{
struct scatterlist *dma_sg = sg;
- struct scatterlist *sg_end = sg + nelems;
unsigned long flags;
int i;
@@ -413,7 +412,8 @@ static inline long fill_sg(long entry, struct device *dev,
len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
break;
}
- sg++;
+ sg = sg_next(sg);
+ nelems--;
}
pteval = (pteval & IOPTE_PAGE);
@@ -431,24 +431,26 @@ static inline long fill_sg(long entry, struct device *dev,
}
pteval = (pteval & IOPTE_PAGE) + len;
- sg++;
+ sg = sg_next(sg);
+ nelems--;
/* Skip over any tail mappings we've fully mapped,
* adjusting pteval along the way. Stop when we
* detect a page crossing event.
*/
- while (sg < sg_end &&
+ while (nelems &&
(pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
(pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
((pteval ^
(SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
pteval += sg->length;
- sg++;
+ sg = sg_next(sg);
+ nelems--;
}
if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
pteval = ~0UL;
} while (dma_npages != 0);
- dma_sg++;
+ dma_sg = sg_next(dma_sg);
}
if (unlikely(iommu_batch_end() < 0L))
@@ -510,7 +512,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
sgtmp = sglist;
while (used && sgtmp->dma_length) {
sgtmp->dma_address += dma_base;
- sgtmp++;
+ sgtmp = sg_next(sgtmp);
used--;
}
used = nelems - used;
@@ -545,6 +547,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
struct pci_pbm_info *pbm;
struct iommu *iommu;
unsigned long flags, i, npages;
+ struct scatterlist *sg, *sgprv;
long entry;
u32 devhandle, bus_addr;
@@ -558,12 +561,15 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
devhandle = pbm->devhandle;
bus_addr = sglist->dma_address & IO_PAGE_MASK;
-
- for (i = 1; i < nelems; i++)
- if (sglist[i].dma_length == 0)
+ sgprv = NULL;
+ for_each_sg(sglist, sg, nelems, i) {
+ if (sg->dma_length == 0)
break;
- i--;
- npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) -
+
+ sgprv = sg;
+ }
+
+ npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) -
bus_addr) >> IO_PAGE_SHIFT;
entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index c73b7a48b03..407d74a8a54 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -52,14 +52,13 @@ int sparc64_multi_core __read_mostly;
cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE;
cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly =
- { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE };
EXPORT_SYMBOL(cpu_possible_map);
EXPORT_SYMBOL(cpu_online_map);
-EXPORT_SYMBOL(cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(cpu_core_map);
static cpumask_t smp_commenced_mask;
@@ -1261,16 +1260,16 @@ void __devinit smp_fill_in_sib_core_maps(void)
for_each_present_cpu(i) {
unsigned int j;
- cpus_clear(cpu_sibling_map[i]);
+ cpus_clear(per_cpu(cpu_sibling_map, i));
if (cpu_data(i).proc_id == -1) {
- cpu_set(i, cpu_sibling_map[i]);
+ cpu_set(i, per_cpu(cpu_sibling_map, i));
continue;
}
for_each_present_cpu(j) {
if (cpu_data(i).proc_id ==
cpu_data(j).proc_id)
- cpu_set(j, cpu_sibling_map[i]);
+ cpu_set(j, per_cpu(cpu_sibling_map, i));
}
}
}
@@ -1342,9 +1341,9 @@ int __cpu_disable(void)
cpu_clear(cpu, cpu_core_map[i]);
cpus_clear(cpu_core_map[cpu]);
- for_each_cpu_mask(i, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[i]);
- cpus_clear(cpu_sibling_map[cpu]);
+ for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
+ cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
c = &cpu_data(cpu);
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 0d5c5026494..560cb1edb1d 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -26,7 +26,6 @@
#include <linux/random.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/utrap.h>
#include <asm/perfctr.h>
#include <asm/a.out.h>
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index e8dce90d05d..78caff92673 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -54,7 +54,6 @@
#include <linux/highuid.h>
#include <asm/types.h>
-#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/fpumacro.h>
#include <asm/semaphore.h>
diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S
index 9633750167d..70ac4186f62 100644
--- a/arch/sparc64/lib/atomic.S
+++ b/arch/sparc64/lib/atomic.S
@@ -1,10 +1,10 @@
-/* $Id: atomic.S,v 1.4 2001/11/18 00:12:56 davem Exp $
- * atomic.S: These things are too big to do inline.
+/* atomic.S: These things are too big to do inline.
*
- * Copyright (C) 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
*/
#include <asm/asi.h>
+#include <asm/backoff.h>
.text
@@ -16,27 +16,31 @@
.globl atomic_add
.type atomic_add,#function
atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
1: lduw [%o1], %g1
add %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, 1b
+ bne,pn %icc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_add, .-atomic_add
.globl atomic_sub
.type atomic_sub,#function
atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
1: lduw [%o1], %g1
sub %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, 1b
+ bne,pn %icc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_sub, .-atomic_sub
/* On SMP we need to use memory barriers to ensure
@@ -60,89 +64,101 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
.globl atomic_add_ret
.type atomic_add_ret,#function
atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
ATOMIC_PRE_BARRIER
1: lduw [%o1], %g1
add %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, 1b
+ bne,pn %icc, 2f
add %g7, %o0, %g7
sra %g7, 0, %o0
ATOMIC_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_add_ret, .-atomic_add_ret
.globl atomic_sub_ret
.type atomic_sub_ret,#function
atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
ATOMIC_PRE_BARRIER
1: lduw [%o1], %g1
sub %g1, %o0, %g7
cas [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %icc, 1b
+ bne,pn %icc, 2f
sub %g7, %o0, %g7
sra %g7, 0, %o0
ATOMIC_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic_sub_ret, .-atomic_sub_ret
.globl atomic64_add
.type atomic64_add,#function
atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
1: ldx [%o1], %g1
add %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_add, .-atomic64_add
.globl atomic64_sub
.type atomic64_sub,#function
atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
1: ldx [%o1], %g1
sub %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_sub, .-atomic64_sub
.globl atomic64_add_ret
.type atomic64_add_ret,#function
atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
ATOMIC_PRE_BARRIER
1: ldx [%o1], %g1
add %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
add %g7, %o0, %g7
mov %g7, %o0
ATOMIC_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_add_ret, .-atomic64_add_ret
.globl atomic64_sub_ret
.type atomic64_sub_ret,#function
atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
ATOMIC_PRE_BARRIER
1: ldx [%o1], %g1
sub %g1, %o0, %g7
casx [%o1], %g1, %g7
cmp %g1, %g7
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
sub %g7, %o0, %g7
mov %g7, %o0
ATOMIC_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o2, %o3, 1b)
.size atomic64_sub_ret, .-atomic64_sub_ret
diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S
index 892431a8213..6b015a6eefb 100644
--- a/arch/sparc64/lib/bitops.S
+++ b/arch/sparc64/lib/bitops.S
@@ -1,10 +1,10 @@
-/* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $
- * bitops.S: Sparc64 atomic bit operations.
+/* bitops.S: Sparc64 atomic bit operations.
*
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
*/
#include <asm/asi.h>
+#include <asm/backoff.h>
.text
@@ -29,6 +29,7 @@
.globl test_and_set_bit
.type test_and_set_bit,#function
test_and_set_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
BITOP_PRE_BARRIER
srlx %o0, 6, %g1
mov 1, %o2
@@ -40,18 +41,20 @@ test_and_set_bit: /* %o0=nr, %o1=addr */
or %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
BITOP_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
.size test_and_set_bit, .-test_and_set_bit
.globl test_and_clear_bit
.type test_and_clear_bit,#function
test_and_clear_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
BITOP_PRE_BARRIER
srlx %o0, 6, %g1
mov 1, %o2
@@ -63,18 +66,20 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */
andn %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
BITOP_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
.size test_and_clear_bit, .-test_and_clear_bit
.globl test_and_change_bit
.type test_and_change_bit,#function
test_and_change_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
BITOP_PRE_BARRIER
srlx %o0, 6, %g1
mov 1, %o2
@@ -86,18 +91,20 @@ test_and_change_bit: /* %o0=nr, %o1=addr */
xor %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
and %g7, %o2, %g2
clr %o0
movrne %g2, 1, %o0
BITOP_POST_BARRIER
retl
nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
.size test_and_change_bit, .-test_and_change_bit
.globl set_bit
.type set_bit,#function
set_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
sllx %g1, 3, %g3
@@ -108,15 +115,17 @@ set_bit: /* %o0=nr, %o1=addr */
or %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
.size set_bit, .-set_bit
.globl clear_bit
.type clear_bit,#function
clear_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
sllx %g1, 3, %g3
@@ -127,15 +136,17 @@ clear_bit: /* %o0=nr, %o1=addr */
andn %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
.size clear_bit, .-clear_bit
.globl change_bit
.type change_bit,#function
change_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
srlx %o0, 6, %g1
mov 1, %o2
sllx %g1, 3, %g3
@@ -146,8 +157,9 @@ change_bit: /* %o0=nr, %o1=addr */
xor %g7, %o2, %g1
casx [%o1], %g7, %g1
cmp %g7, %g1
- bne,pn %xcc, 1b
+ bne,pn %xcc, 2f
nop
retl
nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
.size change_bit, .-change_bit
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 9f7740eee8d..e2027f27c0f 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -463,7 +463,7 @@ out_of_memory:
up_read(&mm->mmap_sem);
printk("VM: killing process %s\n", current->comm);
if (!(regs->tstate & TSTATE_PRIV))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto handle_kernel_fault;
intr_or_no_mm:
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index f0ab9aab308..100c4456ed1 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1645,6 +1645,58 @@ EXPORT_SYMBOL(_PAGE_E);
unsigned long _PAGE_CACHE __read_mostly;
EXPORT_SYMBOL(_PAGE_CACHE);
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+
+#define VMEMMAP_CHUNK_SHIFT 22
+#define VMEMMAP_CHUNK (1UL << VMEMMAP_CHUNK_SHIFT)
+#define VMEMMAP_CHUNK_MASK ~(VMEMMAP_CHUNK - 1UL)
+#define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
+
+#define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
+ sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
+unsigned long vmemmap_table[VMEMMAP_SIZE];
+
+int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
+{
+ unsigned long vstart = (unsigned long) start;
+ unsigned long vend = (unsigned long) (start + nr);
+ unsigned long phys_start = (vstart - VMEMMAP_BASE);
+ unsigned long phys_end = (vend - VMEMMAP_BASE);
+ unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK;
+ unsigned long end = VMEMMAP_ALIGN(phys_end);
+ unsigned long pte_base;
+
+ pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4U |
+ _PAGE_CP_4U | _PAGE_CV_4U |
+ _PAGE_P_4U | _PAGE_W_4U);
+ if (tlb_type == hypervisor)
+ pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
+ _PAGE_CP_4V | _PAGE_CV_4V |
+ _PAGE_P_4V | _PAGE_W_4V);
+
+ for (; addr < end; addr += VMEMMAP_CHUNK) {
+ unsigned long *vmem_pp =
+ vmemmap_table + (addr >> VMEMMAP_CHUNK_SHIFT);
+ void *block;
+
+ if (!(*vmem_pp & _PAGE_VALID)) {
+ block = vmemmap_alloc_block(1UL << 22, node);
+ if (!block)
+ return -ENOMEM;
+
+ *vmem_pp = pte_base | __pa(block);
+
+ printk(KERN_INFO "[%p-%p] page_structs=%lu "
+ "node=%d entry=%lu/%lu\n", start, block, nr,
+ node,
+ addr >> VMEMMAP_CHUNK_SHIFT,
+ VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
+ }
+ }
+ return 0;
+}
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
+
static void prot_init_common(unsigned long page_none,
unsigned long page_shared,
unsigned long page_copy,
@@ -1909,9 +1961,4 @@ void online_page(struct page *page)
num_physpages++;
}
-int remove_memory(u64 start, u64 size)
-{
- return -EINVAL;
-}
-
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c
index a531a2cdb38..499135fa706 100644
--- a/arch/sparc64/solaris/ipc.c
+++ b/arch/sparc64/solaris/ipc.c
@@ -11,10 +11,10 @@
#include <linux/shm.h>
#include <linux/sem.h>
#include <linux/msg.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
#include <asm/string.h>
-#include <asm/ipc.h>
#include "conv.h"
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index e6ff3026654..740d8a922e4 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -55,6 +55,14 @@ config GENERIC_BUG
default y
depends on BUG
+config GENERIC_TIME
+ bool
+ default y
+
+config GENERIC_CLOCKEVENTS
+ bool
+ default y
+
# Used in kernel/irq/manage.c and include/linux/irq.h
config IRQ_RELEASE_METHOD
bool
@@ -62,63 +70,25 @@ config IRQ_RELEASE_METHOD
menu "UML-specific options"
-config MODE_TT
- bool "Tracing thread support (DEPRECATED)"
- default n
- depends on BROKEN
- help
- This option controls whether tracing thread support is compiled
- into UML. This option is largely obsolete, given that skas0 provides
- skas security and performance without needing to patch the host.
- It is safe to say 'N' here; saying 'Y' may cause additional problems
- with the resulting binary even if you run UML in SKAS mode, and running
- in TT mode is strongly *NOT RECOMMENDED*.
-
config STATIC_LINK
bool "Force a static link"
default n
- depends on !MODE_TT
help
- If CONFIG_MODE_TT is disabled, then this option gives you the ability
- to force a static link of UML. Normally, if only skas mode is built
- in to UML, it will be linked as a shared binary. This is inconvenient
- for use in a chroot jail. So, if you intend to run UML inside a
- chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
- here.
- Additionally, this option enables using higher memory spaces (up to
- 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads
- to best results for this.
-
-config KERNEL_HALF_GIGS
- int "Kernel address space size (in .5G units)"
- default "1"
- depends on MODE_TT
- help
- This determines the amount of address space that UML will allocate for
- its own, measured in half Gigabyte units. The default is 1.
- Change this only if you need to boot UML with an unusually large amount
- of physical memory.
-
-config MODE_SKAS
- bool "Separate Kernel Address Space support" if MODE_TT
- default y
- help
- This option controls whether skas (separate kernel address space)
- support is compiled in.
- Unless you have specific needs to use TT mode (which applies almost only
- to developers), you should say Y here.
- SKAS mode will make use of the SKAS3 patch if it is applied on the host
- (and your UML will run in SKAS3 mode), but if no SKAS patch is applied
- on the host it will run in SKAS0 mode, which is anyway faster than TT
- mode.
+ This option gives you the ability to force a static link of UML.
+ Normally, UML is linked as a shared binary. This is inconvenient for
+ use in a chroot jail. So, if you intend to run UML inside a chroot,
+ you probably want to say Y here.
+ Additionally, this option enables using higher memory spaces (up to
+ 2.75G) for UML.
source "arch/um/Kconfig.arch"
source "mm/Kconfig"
+source "kernel/time/Kconfig"
config LD_SCRIPT_STATIC
bool
default y
- depends on MODE_TT || STATIC_LINK
+ depends on STATIC_LINK
config LD_SCRIPT_DYN
bool
@@ -128,18 +98,18 @@ config LD_SCRIPT_DYN
config NET
bool "Networking support"
help
- Unless you really know what you are doing, you should say Y here.
- The reason is that some programs need kernel networking support even
- when running on a stand-alone machine that isn't connected to any
- other computer. If you are upgrading from an older kernel, you
- should consider updating your networking tools too because changes
- in the kernel and the tools often go hand in hand. The tools are
- contained in the package net-tools, the location and version number
- of which are given in <file:Documentation/Changes>.
+ Unless you really know what you are doing, you should say Y here.
+ The reason is that some programs need kernel networking support even
+ when running on a stand-alone machine that isn't connected to any
+ other computer. If you are upgrading from an older kernel, you
+ should consider updating your networking tools too because changes
+ in the kernel and the tools often go hand in hand. The tools are
+ contained in the package net-tools, the location and version number
+ of which are given in <file:Documentation/Changes>.
- For a general introduction to Linux networking, it is highly
- recommended to read the NET-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
+ For a general introduction to Linux networking, it is highly
+ recommended to read the NET-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
source "fs/Kconfig.binfmt"
@@ -147,99 +117,99 @@ source "fs/Kconfig.binfmt"
config HOSTFS
tristate "Host filesystem"
help
- While the User-Mode Linux port uses its own root file system for
- booting and normal file access, this module lets the UML user
- access files stored on the host. It does not require any
- network connection between the Host and UML. An example use of
- this might be:
+ While the User-Mode Linux port uses its own root file system for
+ booting and normal file access, this module lets the UML user
+ access files stored on the host. It does not require any
+ network connection between the Host and UML. An example use of
+ this might be:
- mount none /tmp/fromhost -t hostfs -o /tmp/umlshare
+ mount none /tmp/fromhost -t hostfs -o /tmp/umlshare
- where /tmp/fromhost is an empty directory inside UML and
- /tmp/umlshare is a directory on the host with files the UML user
- wishes to access.
+ where /tmp/fromhost is an empty directory inside UML and
+ /tmp/umlshare is a directory on the host with files the UML user
+ wishes to access.
- For more information, see
- <http://user-mode-linux.sourceforge.net/hostfs.html>.
+ For more information, see
+ <http://user-mode-linux.sourceforge.net/hostfs.html>.
- If you'd like to be able to work with files stored on the host,
- say Y or M here; otherwise say N.
+ If you'd like to be able to work with files stored on the host,
+ say Y or M here; otherwise say N.
config HPPFS
tristate "HoneyPot ProcFS (EXPERIMENTAL)"
depends on EXPERIMENTAL
help
- hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
- entries to be overridden, removed, or fabricated from the host.
- Its purpose is to allow a UML to appear to be a physical machine
- by removing or changing anything in /proc which gives away the
- identity of a UML.
+ hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
+ entries to be overridden, removed, or fabricated from the host.
+ Its purpose is to allow a UML to appear to be a physical machine
+ by removing or changing anything in /proc which gives away the
+ identity of a UML.
- See <http://user-mode-linux.sf.net/hppfs.html> for more information.
+ See <http://user-mode-linux.sf.net/hppfs.html> for more information.
- You only need this if you are setting up a UML honeypot. Otherwise,
- it is safe to say 'N' here.
+ You only need this if you are setting up a UML honeypot. Otherwise,
+ it is safe to say 'N' here.
config MCONSOLE
bool "Management console"
default y
help
- The user mode linux management console is a low-level interface to
- the kernel, somewhat like the i386 SysRq interface. Since there is
- a full-blown operating system running under every user mode linux
- instance, there is much greater flexibility possible than with the
- SysRq mechanism.
+ The user mode linux management console is a low-level interface to
+ the kernel, somewhat like the i386 SysRq interface. Since there is
+ a full-blown operating system running under every user mode linux
+ instance, there is much greater flexibility possible than with the
+ SysRq mechanism.
- If you answer 'Y' to this option, to use this feature, you need the
- mconsole client (called uml_mconsole) which is present in CVS in
- 2.4.5-9um and later (path /tools/mconsole), and is also in the
- distribution RPM package in 2.4.6 and later.
+ If you answer 'Y' to this option, to use this feature, you need the
+ mconsole client (called uml_mconsole) which is present in CVS in
+ 2.4.5-9um and later (path /tools/mconsole), and is also in the
+ distribution RPM package in 2.4.6 and later.
- It is safe to say 'Y' here.
+ It is safe to say 'Y' here.
config MAGIC_SYSRQ
bool "Magic SysRq key"
depends on MCONSOLE
- ---help---
- If you say Y here, you will have some control over the system even
- if the system crashes for example during kernel debugging (e.g., you
- will be able to flush the buffer cache to disk, reboot the system
- immediately or dump some status information). A key for each of the
- possible requests is provided.
+ help
+ If you say Y here, you will have some control over the system even
+ if the system crashes for example during kernel debugging (e.g., you
+ will be able to flush the buffer cache to disk, reboot the system
+ immediately or dump some status information). A key for each of the
+ possible requests is provided.
- This is the feature normally accomplished by pressing a key
- while holding SysRq (Alt+PrintScreen).
+ This is the feature normally accomplished by pressing a key
+ while holding SysRq (Alt+PrintScreen).
- On UML, this is accomplished by sending a "sysrq" command with
- mconsole, followed by the letter for the requested command.
+ On UML, this is accomplished by sending a "sysrq" command with
+ mconsole, followed by the letter for the requested command.
- The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
- unless you really know what this hack does.
+ The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
+ unless you really know what this hack does.
config SMP
bool "Symmetric multi-processing support (EXPERIMENTAL)"
default n
#SMP_BROKEN is for x86_64.
- depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
+ depends on EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
help
- This option enables UML SMP support.
- It is NOT related to having a real SMP box. Not directly, at least.
+ This option enables UML SMP support.
+ It is NOT related to having a real SMP box. Not directly, at least.
- UML implements virtual SMP by allowing as many processes to run
- simultaneously on the host as there are virtual processors configured.
+ UML implements virtual SMP by allowing as many processes to run
+ simultaneously on the host as there are virtual processors configured.
- Obviously, if the host is a uniprocessor, those processes will
- timeshare, but, inside UML, will appear to be running simultaneously.
- If the host is a multiprocessor, then UML processes may run
- simultaneously, depending on the host scheduler.
+ Obviously, if the host is a uniprocessor, those processes will
+ timeshare, but, inside UML, will appear to be running simultaneously.
+ If the host is a multiprocessor, then UML processes may run
+ simultaneously, depending on the host scheduler.
- This, however, is supported only in TT mode. So, if you use the SKAS
- patch on your host, switching to TT mode and enabling SMP usually gives
- you worse performances.
- Also, since the support for SMP has been under-developed, there could
- be some bugs being exposed by enabling SMP.
+ This, however, is supported only in TT mode. So, if you use the SKAS
+ patch on your host, switching to TT mode and enabling SMP usually
+ gives you worse performances.
+ Also, since the support for SMP has been under-developed, there could
+ be some bugs being exposed by enabling SMP.
- If you don't know what to do, say N.
+ If you don't know what to do, say N.
config NR_CPUS
int "Maximum number of CPUs (2-32)"
@@ -251,29 +221,24 @@ config NEST_LEVEL
int "Nesting level"
default "0"
help
- This is set to the number of layers of UMLs that this UML will be run
- in. Normally, this is zero, meaning that it will run directly on the
- host. Setting it to one will build a UML that can run inside a UML
- that is running on the host. Generally, if you intend this UML to run
- inside another UML, set CONFIG_NEST_LEVEL to one more than the host
- UML.
-
- Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to
- greater than one, then the guest UML should have its CONFIG_NEST_LEVEL
- set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
- Only change this if you are running nested UMLs.
+ This is set to the number of layers of UMLs that this UML will be run
+ in. Normally, this is zero, meaning that it will run directly on the
+ host. Setting it to one will build a UML that can run inside a UML
+ that is running on the host. Generally, if you intend this UML to run
+ inside another UML, set CONFIG_NEST_LEVEL to one more than the host
+ UML.
config HIGHMEM
bool "Highmem support (EXPERIMENTAL)"
depends on !64BIT && EXPERIMENTAL
default n
help
- This was used to allow UML to run with big amounts of memory.
- Currently it is unstable, so if unsure say N.
+ This was used to allow UML to run with big amounts of memory.
+ Currently it is unstable, so if unsure say N.
- To use big amounts of memory, it is recommended to disable TT mode (i.e.
- CONFIG_MODE_TT) and enable static linking (i.e. CONFIG_STATIC_LINK) -
- this should allow the guest to use up to 2.75G of memory.
+ To use big amounts of memory, it is recommended enable static
+ linking (i.e. CONFIG_STATIC_LINK) - this should allow the
+ guest to use up to 2.75G of memory.
config KERNEL_STACK_ORDER
int "Kernel stack size order"
@@ -281,20 +246,9 @@ config KERNEL_STACK_ORDER
range 1 10 if 64BIT
default 0 if !64BIT
help
- This option determines the size of UML kernel stacks. They will
- be 1 << order pages. The default is OK unless you're running Valgrind
- on UML, in which case, set this to 3.
-
-config UML_REAL_TIME_CLOCK
- bool "Real-time Clock"
- default y
- help
- This option makes UML time deltas match wall clock deltas. This should
- normally be enabled. The exception would be if you are debugging with
- UML and spend long times with UML stopped at a breakpoint. In this
- case, when UML is restarted, it will call the timer enough times to make
- up for the time spent at the breakpoint. This could result in a
- noticeable lag. If this is a problem, then disable this option.
+ This option determines the size of UML kernel stacks. They will
+ be 1 << order pages. The default is OK unless you're running Valgrind
+ on UML, in which case, set this to 3.
endmenu
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index a5b079d5e86..9a78d354f0b 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -5,7 +5,7 @@ config STDERR_CONSOLE
bool "stderr console"
default y
help
- console driver which dumps all printk messages to stderr.
+ console driver which dumps all printk messages to stderr.
config STDIO_CONSOLE
bool
@@ -14,60 +14,58 @@ config STDIO_CONSOLE
config SSL
bool "Virtual serial line"
help
- The User-Mode Linux environment allows you to create virtual serial
- lines on the UML that are usually made to show up on the host as
- ttys or ptys.
+ The User-Mode Linux environment allows you to create virtual serial
+ lines on the UML that are usually made to show up on the host as
+ ttys or ptys.
- See <http://user-mode-linux.sourceforge.net/input.html> for more
- information and command line examples of how to use this facility.
+ See <http://user-mode-linux.sourceforge.net/input.html> for more
+ information and command line examples of how to use this facility.
- Unless you have a specific reason for disabling this, say Y.
+ Unless you have a specific reason for disabling this, say Y.
config NULL_CHAN
bool "null channel support"
help
- This option enables support for attaching UML consoles and serial
- lines to a device similar to /dev/null. Data written to it disappears
- and there is never any data to be read.
+ This option enables support for attaching UML consoles and serial
+ lines to a device similar to /dev/null. Data written to it disappears
+ and there is never any data to be read.
config PORT_CHAN
bool "port channel support"
help
- This option enables support for attaching UML consoles and serial
- lines to host portals. They may be accessed with 'telnet <host>
- <port number>'. Any number of consoles and serial lines may be
- attached to a single portal, although what UML device you get when
- you telnet to that portal will be unpredictable.
- It is safe to say 'Y' here.
+ This option enables support for attaching UML consoles and serial
+ lines to host portals. They may be accessed with 'telnet <host>
+ <port number>'. Any number of consoles and serial lines may be
+ attached to a single portal, although what UML device you get when
+ you telnet to that portal will be unpredictable.
+ It is safe to say 'Y' here.
config PTY_CHAN
bool "pty channel support"
help
- This option enables support for attaching UML consoles and serial
- lines to host pseudo-terminals. Access to both traditional
- pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
- with this option. The assignment of UML devices to host devices
- will be announced in the kernel message log.
- It is safe to say 'Y' here.
+ This option enables support for attaching UML consoles and serial
+ lines to host pseudo-terminals. Access to both traditional
+ pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
+ with this option. The assignment of UML devices to host devices
+ will be announced in the kernel message log.
+ It is safe to say 'Y' here.
config TTY_CHAN
bool "tty channel support"
help
- This option enables support for attaching UML consoles and serial
- lines to host terminals. Access to both virtual consoles
- (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
- /dev/pts/*) are controlled by this option.
- It is safe to say 'Y' here.
+ This option enables support for attaching UML consoles and serial
+ lines to host terminals. Access to both virtual consoles
+ (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
+ /dev/pts/*) are controlled by this option.
+ It is safe to say 'Y' here.
config XTERM_CHAN
bool "xterm channel support"
help
- This option enables support for attaching UML consoles and serial
- lines to xterms. Each UML device so assigned will be brought up in
- its own xterm.
- If you disable this option, then CONFIG_PT_PROXY will be disabled as
- well, since UML's gdb currently requires an xterm.
- It is safe to say 'Y' here.
+ This option enables support for attaching UML consoles and serial
+ lines to xterms. Each UML device so assigned will be brought up in
+ its own xterm.
+ It is safe to say 'Y' here.
config NOCONFIG_CHAN
bool
@@ -77,39 +75,39 @@ config CON_ZERO_CHAN
string "Default main console channel initialization"
default "fd:0,fd:1"
help
- This is the string describing the channel to which the main console
- will be attached by default. This value can be overridden from the
- command line. The default value is "fd:0,fd:1", which attaches the
- main console to stdin and stdout.
- It is safe to leave this unchanged.
+ This is the string describing the channel to which the main console
+ will be attached by default. This value can be overridden from the
+ command line. The default value is "fd:0,fd:1", which attaches the
+ main console to stdin and stdout.
+ It is safe to leave this unchanged.
config CON_CHAN
string "Default console channel initialization"
default "xterm"
help
- This is the string describing the channel to which all consoles
- except the main console will be attached by default. This value can
- be overridden from the command line. The default value is "xterm",
- which brings them up in xterms.
- It is safe to leave this unchanged, although you may wish to change
- this if you expect the UML that you build to be run in environments
- which don't have X or xterm available.
+ This is the string describing the channel to which all consoles
+ except the main console will be attached by default. This value can
+ be overridden from the command line. The default value is "xterm",
+ which brings them up in xterms.
+ It is safe to leave this unchanged, although you may wish to change
+ this if you expect the UML that you build to be run in environments
+ which don't have X or xterm available.
config SSL_CHAN
string "Default serial line channel initialization"
default "pty"
help
- This is the string describing the channel to which the serial lines
- will be attached by default. This value can be overridden from the
- command line. The default value is "pty", which attaches them to
- traditional pseudo-terminals.
- It is safe to leave this unchanged, although you may wish to change
- this if you expect the UML that you build to be run in environments
- which don't have a set of /dev/pty* devices.
+ This is the string describing the channel to which the serial lines
+ will be attached by default. This value can be overridden from the
+ command line. The default value is "pty", which attaches them to
+ traditional pseudo-terminals.
+ It is safe to leave this unchanged, although you may wish to change
+ this if you expect the UML that you build to be run in environments
+ which don't have a set of /dev/pty* devices.
config UNIX98_PTYS
bool "Unix98 PTY support"
- ---help---
+ help
A pseudo terminal (PTY) is a software device consisting of two
halves: a master and a slave. The slave device behaves identical to
a physical terminal; the master device is used by a process to
@@ -132,7 +130,7 @@ config UNIX98_PTYS
config LEGACY_PTYS
bool "Legacy (BSD) PTY support"
default y
- ---help---
+ help
A pseudo terminal (PTY) is a software device consisting of two
halves: a master and a slave. The slave device behaves identical to
a physical terminal; the master device is used by a process to
@@ -170,7 +168,7 @@ config LEGACY_PTY_COUNT
int "Maximum number of legacy PTY in use"
depends on LEGACY_PTYS
default "256"
- ---help---
+ help
The maximum number of legacy PTYs that can be used at any one time.
The default is 256, and should be more than enough. Embedded
systems may want to reduce this to save memory.
@@ -196,10 +194,10 @@ config UML_WATCHDOG
config UML_SOUND
tristate "Sound support"
help
- This option enables UML sound support. If enabled, it will pull in
- soundcore and the UML hostaudio relay, which acts as a intermediary
- between the host's dsp and mixer devices and the UML sound system.
- It is safe to say 'Y' here.
+ This option enables UML sound support. If enabled, it will pull in
+ soundcore and the UML hostaudio relay, which acts as a intermediary
+ between the host's dsp and mixer devices and the UML sound system.
+ It is safe to say 'Y' here.
config SOUND
tristate
@@ -217,22 +215,21 @@ config HW_RANDOM
config UML_RANDOM
tristate "Hardware random number generator"
help
- This option enables UML's "hardware" random number generator. It
- attaches itself to the host's /dev/random, supplying as much entropy
- as the host has, rather than the small amount the UML gets from its
- own drivers. It registers itself as a standard hardware random number
- generator, major 10, minor 183, and the canonical device name is
- /dev/hwrng.
- The way to make use of this is to install the rng-tools package
- (check your distro, or download from
- http://sourceforge.net/projects/gkernel/). rngd periodically reads
- /dev/hwrng and injects the entropy into /dev/random.
+ This option enables UML's "hardware" random number generator. It
+ attaches itself to the host's /dev/random, supplying as much entropy
+ as the host has, rather than the small amount the UML gets from its
+ own drivers. It registers itself as a standard hardware random number
+ generator, major 10, minor 183, and the canonical device name is
+ /dev/hwrng.
+ The way to make use of this is to install the rng-tools package
+ (check your distro, or download from
+ http://sourceforge.net/projects/gkernel/). rngd periodically reads
+ /dev/hwrng and injects the entropy into /dev/random.
config MMAPPER
tristate "iomem emulation driver"
help
- This driver allows a host file to be used as emulated IO memory inside
- UML.
+ This driver allows a host file to be used as emulated IO memory inside
+ UML.
endmenu
-
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index c86f5eb29fd..1f6462ffd3e 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -2,50 +2,31 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
-config CMDLINE_ON_HOST
- bool "Show command line arguments on the host in TT mode"
- depends on MODE_TT
- default !DEBUG_INFO
- help
- This controls whether arguments in guest processes should be shown on
- the host's ps output.
- Enabling this option hinders debugging on some recent GDB versions
- (because GDB gets "confused" when we do an execvp()). So probably you
- should disable it.
-
-config PT_PROXY
- bool "Enable ptrace proxy"
- depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
- help
- This option enables a debugging interface which allows gdb to debug
- the kernel without needing to actually attach to kernel threads.
- If you want to do kernel debugging, say Y here; otherwise say N.
-
config GPROF
bool "Enable gprof support"
- depends on DEBUG_INFO && MODE_SKAS && !MODE_TT
+ depends on DEBUG_INFO
help
- This allows profiling of a User-Mode Linux kernel with the gprof
- utility.
+ This allows profiling of a User-Mode Linux kernel with the gprof
+ utility.
- See <http://user-mode-linux.sourceforge.net/gprof.html> for more
- details.
+ See <http://user-mode-linux.sourceforge.net/gprof.html> for more
+ details.
- If you're involved in UML kernel development and want to use gprof,
- say Y. If you're unsure, say N.
+ If you're involved in UML kernel development and want to use gprof,
+ say Y. If you're unsure, say N.
config GCOV
bool "Enable gcov support"
- depends on DEBUG_INFO && MODE_SKAS
+ depends on DEBUG_INFO
help
- This option allows developers to retrieve coverage data from a UML
- session.
+ This option allows developers to retrieve coverage data from a UML
+ session.
- See <http://user-mode-linux.sourceforge.net/gprof.html> for more
- details.
+ See <http://user-mode-linux.sourceforge.net/gprof.html> for more
+ details.
- If you're involved in UML kernel development and want to use gcov,
- say Y. If you're unsure, say N.
+ If you're involved in UML kernel development and want to use gcov,
+ say Y. If you're unsure, say N.
config DEBUG_STACK_USAGE
bool "Stack utilization instrumentation"
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index d6cffb27fff..9876d80d85d 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -65,20 +65,6 @@ config 3_LEVEL_PGTABLES
However, this it experimental on 32-bit architectures, so if unsure say
N (on x86-64 it's automatically enabled, instead, as it's safe there).
-config STUB_CODE
- hex
- default 0xbfffe000 if !HOST_VMSPLIT_2G
- default 0x7fffe000 if HOST_VMSPLIT_2G
-
-config STUB_DATA
- hex
- default 0xbffff000 if !HOST_VMSPLIT_2G
- default 0x7ffff000 if HOST_VMSPLIT_2G
-
-config STUB_START
- hex
- default STUB_CODE
-
config ARCH_HAS_SC_SIGNALS
bool
default y
diff --git a/arch/um/Kconfig.net b/arch/um/Kconfig.net
index 14a04ebdeae..66e50026ade 100644
--- a/arch/um/Kconfig.net
+++ b/arch/um/Kconfig.net
@@ -108,6 +108,28 @@ config UML_NET_DAEMON
more than one without conflict. If you don't need UML networking,
say N.
+config UML_NET_VDE
+ bool "VDE transport"
+ depends on UML_NET
+ help
+ This User-Mode Linux network transport allows one or more running
+ UMLs on a single host to communicate with each other and also
+ with the rest of the world using Virtual Distributed Ethernet,
+ an improved fork of uml_switch.
+
+ You must have libvdeplug installed in order to build the vde
+ transport into UML.
+
+ To use this form of networking, you will need to run vde_switch
+ on the host.
+
+ For more information, see <http://wiki.virtualsquare.org/>
+ That site has a good overview of what VDE is and also examples
+ of the UML command line to use to enable VDE networking.
+
+ If you need UML networking with VDE,
+ say Y.
+
config UML_NET_MCAST
bool "Multicast transport"
depends on UML_NET
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
index f60e9e50642..d632e9a89cc 100644
--- a/arch/um/Kconfig.x86_64
+++ b/arch/um/Kconfig.x86_64
@@ -17,24 +17,12 @@ config SEMAPHORE_SLEEPERS
config TOP_ADDR
hex
- default 0x80000000
+ default 0x7fc0000000
config 3_LEVEL_PGTABLES
bool
default y
-config STUB_CODE
- hex
- default 0x7fbfffe000
-
-config STUB_DATA
- hex
- default 0x7fbffff000
-
-config STUB_START
- hex
- default STUB_CODE
-
config ARCH_HAS_SC_SIGNALS
bool
default n
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 0666729eb97..82c2ac48040 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -2,7 +2,7 @@
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies.
#
-# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL
#
@@ -31,18 +31,9 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
-um-modes-$(CONFIG_MODE_TT) += tt
-um-modes-$(CONFIG_MODE_SKAS) += skas
+MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/skas
-MODE_INCLUDE += $(foreach mode,$(um-modes-y),\
- -I$(srctree)/$(ARCH_DIR)/include/$(mode))
-
-MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\
- $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
-
-ifneq ($(MAKEFILES-INCL),)
- include $(MAKEFILES-INCL)
-endif
+include $(srctree)/$(ARCH_DIR)/Makefile-skas
ARCH_INCLUDE := -I$(ARCH_DIR)/include
ifneq ($(KBUILD_SRC),)
@@ -58,14 +49,15 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
#
# These apply to USER_CFLAGS to.
-CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+KBUILD_CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
- -Din6addr_loopback=kernel_in6addr_loopback
+ -Din6addr_loopback=kernel_in6addr_loopback \
+ -Din6addr_any=kernel_in6addr_any
-AFLAGS += $(ARCH_INCLUDE)
+KBUILD_AFLAGS += $(ARCH_INCLUDE)
USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
- $(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
+ $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
-D_FILE_OFFSET_BITS=64
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
@@ -75,22 +67,21 @@ include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
# -Derrno=kernel_errno - This turns all kernel references to errno into
# kernel_errno to separate them from the libc errno. This allows -fno-common
-# in CFLAGS. Otherwise, it would cause ld to complain about the two different
+# in KBUILD_CFLAGS. Otherwise, it would cause ld to complain about the two different
# errnos.
# These apply to kernelspace only.
KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
-Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES)
-CFLAGS += $(KERNEL_DEFINES)
-CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
+KBUILD_CFLAGS += $(KERNEL_DEFINES)
+KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
# These are needed for clean and mrproper, since in that case .config is not
# included; the values here are meaningless
CONFIG_NEST_LEVEL ?= 0
-CONFIG_KERNEL_HALF_GIGS ?= 0
-SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
+SIZE = ($(CONFIG_NEST_LEVEL) * 0x20000000)
PHONY += linux
@@ -123,7 +114,6 @@ CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,)
$(call cc-option, -fno-stack-protector,) \
$(call cc-option, -fno-stack-protector-all,)
-CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
CONFIG_KERNEL_STACK_ORDER ?= 2
STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
@@ -131,13 +121,10 @@ ifndef START
START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
endif
-CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
- -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
- -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
- -DKERNEL_STACK_SIZE=$(STACK_SIZE) \
- -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o
+CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
+ -DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE)
-#The wrappers will select whether using "malloc" or the kernel allocator.
+# The wrappers will select whether using "malloc" or the kernel allocator.
LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
@@ -150,8 +137,8 @@ define cmd_vmlinux__
FORCE ,$^) ; rm -f linux
endef
-#When cleaning we don't include .config, so we don't include
-#TT or skas makefiles and don't clean skas_ptregs.h.
+# When cleaning we don't include .config, so we don't include
+# TT or skas makefiles and don't clean skas_ptregs.h.
CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
$(ARCH_DIR)/include/user_constants.h \
$(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 60107ed4905..0178df30693 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -2,11 +2,7 @@ core-y += arch/um/sys-i386/ arch/x86/crypto/
TOP_ADDR := $(CONFIG_TOP_ADDR)
-ifeq ($(CONFIG_MODE_SKAS),y)
- ifneq ($(CONFIG_MODE_TT),y)
- START := 0x8048000
- endif
-endif
+START := 0x8048000
LDFLAGS += -m elf_i386
ELF_ARCH := $(SUBARCH)
@@ -16,8 +12,8 @@ HEADER_ARCH := x86
ifeq ("$(origin SUBARCH)", "command line")
ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
-CFLAGS += $(call cc-option,-m32)
-AFLAGS += $(call cc-option,-m32)
+KBUILD_CFLAGS += $(call cc-option,-m32)
+KBUILD_AFLAGS += $(call cc-option,-m32)
LINK-y += $(call cc-option,-m32)
UML_OBJCOPYFLAGS += -F $(ELF_FORMAT)
@@ -42,4 +38,4 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
# an unresolved reference.
cflags-y += -ffreestanding
-CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
diff --git a/arch/um/Makefile-os-Linux b/arch/um/Makefile-os-Linux
index 0c0f9a1cbba..52859487c95 100644
--- a/arch/um/Makefile-os-Linux
+++ b/arch/um/Makefile-os-Linux
@@ -5,4 +5,4 @@
# To get a definition of F_SETSIG
USER_CFLAGS += -D_GNU_SOURCE -D_LARGEFILE64_SOURCE
-CFLAGS += -D_LARGEFILE64_SOURCE
+KBUILD_CFLAGS += -D_LARGEFILE64_SOURCE
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 8a00e5f6934..fe5316f0c6a 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -9,12 +9,12 @@ _extra_flags_ = -fno-builtin -m64
#We #undef __x86_64__ for kernelspace, not for userspace where
#it's needed for headers to work!
ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__
-CFLAGS += $(_extra_flags_)
+KBUILD_CFLAGS += $(_extra_flags_)
CHECKFLAGS += -m64
-AFLAGS += -m64
+KBUILD_AFLAGS += -m64
LDFLAGS += -m elf_x86_64
-CPPFLAGS += -m64
+KBUILD_CPPFLAGS += -m64
ELF_ARCH := i386:x86-64
ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 1e0f677c2f4..f609edede06 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -12,9 +12,7 @@ CONFIG_IRQ_RELEASE_METHOD=y
#
# UML-specific options
#
-# CONFIG_MODE_TT is not set
# CONFIG_STATIC_LINK is not set
-CONFIG_MODE_SKAS=y
#
# Host processor type and features
@@ -61,9 +59,6 @@ CONFIG_SEMAPHORE_SLEEPERS=y
# CONFIG_HOST_2G_2G is not set
CONFIG_TOP_ADDR=0xc0000000
# CONFIG_3_LEVEL_PGTABLES is not set
-CONFIG_STUB_CODE=0xbfffe000
-CONFIG_STUB_DATA=0xbffff000
-CONFIG_STUB_START=0xbfffe000
CONFIG_ARCH_HAS_SC_SIGNALS=y
CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
CONFIG_GENERIC_HWEIGHT=y
@@ -75,6 +70,9 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_LD_SCRIPT_DYN=y
CONFIG_NET=y
CONFIG_BINFMT_ELF=y
@@ -82,11 +80,10 @@ CONFIG_BINFMT_MISC=m
# CONFIG_HOSTFS is not set
# CONFIG_HPPFS is not set
CONFIG_MCONSOLE=y
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
CONFIG_NEST_LEVEL=0
# CONFIG_HIGHMEM is not set
CONFIG_KERNEL_STACK_ORDER=0
-CONFIG_UML_REAL_TIME_CLOCK=y
#
# Code maturity level options
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index de17d4c6e02..d283e7b022a 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -17,12 +17,18 @@ ubd-objs := ubd_kern.o ubd_user.o
port-objs := port_kern.o port_user.o
harddog-objs := harddog_kern.o harddog_user.o
-LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
+LDFLAGS_pcap.o := -r $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libpcap.a)
-targets := pcap_kern.o pcap_user.o
+LDFLAGS_vde.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libvdeplug.a)
+
+targets := pcap_kern.o pcap_user.o vde_kern.o vde_user.o
$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
$(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o)
+
+$(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o
+ $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_vde.o)
+
#XXX: The call below does not work because the flags are added before the
# object name, so nothing from the library gets linked.
#$(call if_changed,ld)
@@ -37,6 +43,7 @@ obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
+obj-$(CONFIG_UML_NET_VDE) += vde.o
obj-$(CONFIG_UML_NET_MCAST) += mcast.o
obj-$(CONFIG_UML_NET_PCAP) += pcap.o
obj-$(CONFIG_UML_NET) += net.o
@@ -54,6 +61,6 @@ obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
obj-$(CONFIG_UML_RANDOM) += random.o
# pcap_user.o must be added explicitly.
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 629b00e3b0b..db3082b4da4 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -1,28 +1,19 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
#include <linux/slab.h>
#include <linux/tty.h>
-#include <linux/string.h>
#include <linux/tty_flip.h>
-#include <asm/irq.h>
#include "chan_kern.h"
-#include "kern.h"
-#include "irq_user.h"
-#include "sigio.h"
-#include "line.h"
#include "os.h"
#ifdef CONFIG_NOCONFIG_CHAN
static void *not_configged_init(char *str, int device,
const struct chan_opts *opts)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return NULL;
}
@@ -30,34 +21,34 @@ static void *not_configged_init(char *str, int device,
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return -ENODEV;
}
static void not_configged_close(int fd, void *data)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return -EIO;
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return -EIO;
}
static int not_configged_console_write(int fd, const char *buf, int len)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return -EIO;
}
@@ -65,14 +56,14 @@ static int not_configged_console_write(int fd, const char *buf, int len)
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return -ENODEV;
}
static void not_configged_free(void *data)
{
- printk("Using a channel type which is configured out of "
+ printk(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
@@ -89,64 +80,17 @@ static const struct chan_ops not_configged_ops = {
};
#endif /* CONFIG_NOCONFIG_CHAN */
-void generic_close(int fd, void *unused)
-{
- os_close_file(fd);
-}
-
-int generic_read(int fd, char *c_out, void *unused)
-{
- int n;
-
- n = os_read_file(fd, c_out, sizeof(*c_out));
-
- if(n == -EAGAIN)
- return 0;
- else if(n == 0)
- return -EIO;
- return n;
-}
-
-/* XXX Trivial wrapper around os_write_file */
-
-int generic_write(int fd, const char *buf, int n, void *unused)
-{
- return os_write_file(fd, buf, n);
-}
-
-int generic_window_size(int fd, void *unused, unsigned short *rows_out,
- unsigned short *cols_out)
-{
- int rows, cols;
- int ret;
-
- ret = os_window_size(fd, &rows, &cols);
- if(ret < 0)
- return ret;
-
- ret = ((*rows_out != rows) || (*cols_out != cols));
-
- *rows_out = rows;
- *cols_out = cols;
-
- return ret;
-}
-
-void generic_free(void *data)
-{
- kfree(data);
-}
-
static void tty_receive_char(struct tty_struct *tty, char ch)
{
- if(tty == NULL) return;
+ if (tty == NULL)
+ return;
- if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
- if(ch == STOP_CHAR(tty)){
+ if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
+ if (ch == STOP_CHAR(tty)) {
stop_tty(tty);
return;
}
- else if(ch == START_CHAR(tty)){
+ else if (ch == START_CHAR(tty)) {
start_tty(tty);
return;
}
@@ -159,14 +103,14 @@ static int open_one_chan(struct chan *chan)
{
int fd, err;
- if(chan->opened)
+ if (chan->opened)
return 0;
- if(chan->ops->open == NULL)
+ if (chan->ops->open == NULL)
fd = 0;
else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
chan->data, &chan->dev);
- if(fd < 0)
+ if (fd < 0)
return fd;
err = os_set_fd_block(fd, 0);
@@ -187,10 +131,10 @@ int open_chan(struct list_head *chans)
struct chan *chan;
int ret, err = 0;
- list_for_each(ele, chans){
+ list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
ret = open_one_chan(chan);
- if(chan->primary)
+ if (chan->primary)
err = ret;
}
return err;
@@ -201,9 +145,9 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
struct list_head *ele;
struct chan *chan;
- list_for_each(ele, chans){
+ list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(chan->primary && chan->output && chan->ops->winch){
+ if (chan->primary && chan->output && chan->ops->winch) {
register_winch(chan->fd, tty);
return;
}
@@ -216,7 +160,7 @@ int enable_chan(struct line *line)
struct chan *chan;
int err;
- list_for_each(ele, &line->chan_list){
+ list_for_each(ele, &line->chan_list) {
chan = list_entry(ele, struct chan, list);
err = open_one_chan(chan);
if (err) {
@@ -226,7 +170,7 @@ int enable_chan(struct line *line)
continue;
}
- if(chan->enabled)
+ if (chan->enabled)
continue;
err = line_setup_irq(chan->fd, chan->input, chan->output, line,
chan);
@@ -263,12 +207,12 @@ void free_irqs(void)
list_splice_init(&irqs_to_free, &list);
spin_unlock_irqrestore(&irqs_to_free_lock, flags);
- list_for_each(ele, &list){
+ list_for_each(ele, &list) {
chan = list_entry(ele, struct chan, free_list);
- if(chan->input)
+ if (chan->input)
free_irq(chan->line->driver->read_irq, chan);
- if(chan->output)
+ if (chan->output)
free_irq(chan->line->driver->write_irq, chan);
chan->enabled = 0;
}
@@ -278,22 +222,22 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
{
unsigned long flags;
- if(!chan->opened)
+ if (!chan->opened)
return;
- if(delay_free_irq){
+ if (delay_free_irq) {
spin_lock_irqsave(&irqs_to_free_lock, flags);
list_add(&chan->free_list, &irqs_to_free);
spin_unlock_irqrestore(&irqs_to_free_lock, flags);
}
else {
- if(chan->input)
+ if (chan->input)
free_irq(chan->line->driver->read_irq, chan);
- if(chan->output)
+ if (chan->output)
free_irq(chan->line->driver->write_irq, chan);
chan->enabled = 0;
}
- if(chan->ops->close != NULL)
+ if (chan->ops->close != NULL)
(*chan->ops->close)(chan->fd, chan->data);
chan->opened = 0;
@@ -322,7 +266,7 @@ void deactivate_chan(struct list_head *chans, int irq)
list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(chan->enabled && chan->input)
+ if (chan->enabled && chan->input)
deactivate_fd(chan->fd, irq);
}
}
@@ -335,7 +279,7 @@ void reactivate_chan(struct list_head *chans, int irq)
list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(chan->enabled && chan->input)
+ if (chan->enabled && chan->input)
reactivate_fd(chan->fd, irq);
}
}
@@ -347,10 +291,14 @@ int write_chan(struct list_head *chans, const char *buf, int len,
struct chan *chan = NULL;
int n, ret = 0;
+ if (len == 0)
+ return 0;
+
list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
if (!chan->output || (chan->ops->write == NULL))
continue;
+
n = chan->ops->write(chan->fd, buf, len, chan->data);
if (chan->primary) {
ret = n;
@@ -367,12 +315,14 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
struct chan *chan;
int n, ret = 0;
- list_for_each(ele, chans){
+ list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(!chan->output || (chan->ops->console_write == NULL))
+ if (!chan->output || (chan->ops->console_write == NULL))
continue;
+
n = chan->ops->console_write(chan->fd, buf, len);
- if(chan->primary) ret = n;
+ if (chan->primary)
+ ret = n;
}
return ret;
}
@@ -382,10 +332,11 @@ int console_open_chan(struct line *line, struct console *co)
int err;
err = open_chan(&line->chan_list);
- if(err)
+ if (err)
return err;
- printk("Console initialized on /dev/%s%d\n", co->name, co->index);
+ printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name,
+ co->index);
return 0;
}
@@ -395,10 +346,10 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out,
struct list_head *ele;
struct chan *chan;
- list_for_each(ele, chans){
+ list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(chan->primary){
- if(chan->ops->window_size == NULL)
+ if (chan->primary) {
+ if (chan->ops->window_size == NULL)
return 0;
return chan->ops->window_size(chan->fd, chan->data,
rows_out, cols_out);
@@ -413,10 +364,11 @@ static void free_one_chan(struct chan *chan, int delay_free_irq)
close_one_chan(chan, delay_free_irq);
- if(chan->ops->free != NULL)
+ if (chan->ops->free != NULL)
(*chan->ops->free)(chan->data);
- if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
+ if (chan->primary && chan->output)
+ ignore_sigio_fd(chan->fd);
kfree(chan);
}
@@ -425,7 +377,7 @@ static void free_chan(struct list_head *chans, int delay_free_irq)
struct list_head *ele, *next;
struct chan *chan;
- list_for_each_safe(ele, next, chans){
+ list_for_each_safe(ele, next, chans) {
chan = list_entry(ele, struct chan, list);
free_one_chan(chan, delay_free_irq);
}
@@ -436,14 +388,14 @@ static int one_chan_config_string(struct chan *chan, char *str, int size,
{
int n = 0;
- if(chan == NULL){
+ if (chan == NULL) {
CONFIG_CHUNK(str, size, n, "none", 1);
return n;
}
CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
- if(chan->dev == NULL){
+ if (chan->dev == NULL) {
CONFIG_CHUNK(str, size, n, "", 1);
return n;
}
@@ -463,7 +415,7 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
str += n;
size -= n;
- if(in == out){
+ if (in == out) {
CONFIG_CHUNK(str, size, n, "", 1);
return n;
}
@@ -483,13 +435,13 @@ int chan_config_string(struct list_head *chans, char *str, int size,
struct list_head *ele;
struct chan *chan, *in = NULL, *out = NULL;
- list_for_each(ele, chans){
+ list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(!chan->primary)
+ if (!chan->primary)
continue;
- if(chan->input)
+ if (chan->input)
in = chan;
- if(chan->output)
+ if (chan->output)
out = chan;
}
@@ -548,27 +500,27 @@ static struct chan *parse_chan(struct line *line, char *str, int device,
ops = NULL;
data = NULL;
- for(i = 0; i < ARRAY_SIZE(chan_table); i++){
+ for(i = 0; i < ARRAY_SIZE(chan_table); i++) {
entry = &chan_table[i];
- if(!strncmp(str, entry->key, strlen(entry->key))){
+ if (!strncmp(str, entry->key, strlen(entry->key))) {
ops = entry->ops;
str += strlen(entry->key);
break;
}
}
- if(ops == NULL){
+ if (ops == NULL) {
*error_out = "No match for configured backends";
return NULL;
}
data = (*ops->init)(str, device, opts);
- if(data == NULL){
+ if (data == NULL) {
*error_out = "Configuration failed";
return NULL;
}
chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
- if(chan == NULL){
+ if (chan == NULL) {
*error_out = "Memory allocation failed";
return NULL;
}
@@ -594,26 +546,26 @@ int parse_chan_pair(char *str, struct line *line, int device,
struct chan *new, *chan;
char *in, *out;
- if(!list_empty(chans)){
+ if (!list_empty(chans)) {
chan = list_entry(chans->next, struct chan, list);
free_chan(chans, 0);
INIT_LIST_HEAD(chans);
}
out = strchr(str, ',');
- if(out != NULL){
+ if (out != NULL) {
in = str;
*out = '\0';
out++;
new = parse_chan(line, in, device, opts, error_out);
- if(new == NULL)
+ if (new == NULL)
return -1;
new->input = 1;
list_add(&new->list, chans);
new = parse_chan(line, out, device, opts, error_out);
- if(new == NULL)
+ if (new == NULL)
return -1;
list_add(&new->list, chans);
@@ -621,7 +573,7 @@ int parse_chan_pair(char *str, struct line *line, int device,
}
else {
new = parse_chan(line, str, device, opts, error_out);
- if(new == NULL)
+ if (new == NULL)
return -1;
list_add(&new->list, chans);
@@ -636,9 +588,9 @@ int chan_out_fd(struct list_head *chans)
struct list_head *ele;
struct chan *chan;
- list_for_each(ele, chans){
+ list_for_each(ele, chans) {
chan = list_entry(ele, struct chan, list);
- if(chan->primary && chan->output)
+ if (chan->primary && chan->output)
return chan->fd;
}
return -1;
@@ -652,23 +604,25 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task,
int err;
char c;
- list_for_each_safe(ele, next, chans){
+ list_for_each_safe(ele, next, chans) {
chan = list_entry(ele, struct chan, list);
- if(!chan->input || (chan->ops->read == NULL)) continue;
+ if (!chan->input || (chan->ops->read == NULL))
+ continue;
do {
if (tty && !tty_buffer_request_room(tty, 1)) {
schedule_delayed_work(task, 1);
goto out;
}
err = chan->ops->read(chan->fd, &c, chan->data);
- if(err > 0)
+ if (err > 0)
tty_receive_char(tty, c);
- } while(err > 0);
+ } while (err > 0);
- if(err == 0) reactivate_fd(chan->fd, irq);
- if(err == -EIO){
- if(chan->primary){
- if(tty != NULL)
+ if (err == 0)
+ reactivate_fd(chan->fd, irq);
+ if (err == -EIO) {
+ if (chan->primary) {
+ if (tty != NULL)
tty_hangup(tty);
close_chan(chans, 1);
return;
@@ -677,5 +631,6 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task,
}
}
out:
- if(tty) tty_flip_buffer_push(tty);
+ if (tty)
+ tty_flip_buffer_push(tty);
}
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 4d438f36ea2..b88e93b3a39 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -1,51 +1,107 @@
-/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
-#include <unistd.h>
#include <stdlib.h>
+#include <unistd.h>
#include <errno.h>
-#include <termios.h>
-#include <string.h>
-#include <signal.h>
#include <sched.h>
-#include <sys/stat.h>
+#include <signal.h>
+#include <termios.h>
#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include "kern_util.h"
#include "chan_user.h"
-#include "user.h"
#include "os.h"
-#include "choose-mode.h"
-#include "mode.h"
+#include "um_malloc.h"
+#include "user.h"
+
+void generic_close(int fd, void *unused)
+{
+ close(fd);
+}
+
+int generic_read(int fd, char *c_out, void *unused)
+{
+ int n;
+
+ n = read(fd, c_out, sizeof(*c_out));
+ if (n > 0)
+ return n;
+ else if (errno == EAGAIN)
+ return 0;
+ else if (n == 0)
+ return -EIO;
+ return -errno;
+}
+
+/* XXX Trivial wrapper around write */
+
+int generic_write(int fd, const char *buf, int n, void *unused)
+{
+ int err;
+
+ err = write(fd, buf, n);
+ if (err > 0)
+ return err;
+ else if (errno == EAGAIN)
+ return 0;
+ else if (err == 0)
+ return -EIO;
+ return -errno;
+}
+
+int generic_window_size(int fd, void *unused, unsigned short *rows_out,
+ unsigned short *cols_out)
+{
+ struct winsize size;
+ int ret;
+
+ if (ioctl(fd, TIOCGWINSZ, &size) < 0)
+ return -errno;
+
+ ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col));
+
+ *rows_out = size.ws_row;
+ *cols_out = size.ws_col;
+
+ return ret;
+}
+
+void generic_free(void *data)
+{
+ kfree(data);
+}
int generic_console_write(int fd, const char *buf, int n)
{
struct termios save, new;
int err;
- if(isatty(fd)){
+ if (isatty(fd)) {
CATCH_EINTR(err = tcgetattr(fd, &save));
if (err)
goto error;
new = save;
- /* The terminal becomes a bit less raw, to handle \n also as
+ /*
+ * The terminal becomes a bit less raw, to handle \n also as
* "Carriage Return", not only as "New Line". Otherwise, the new
- * line won't start at the first column.*/
+ * line won't start at the first column.
+ */
new.c_oflag |= OPOST;
CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new));
if (err)
goto error;
}
err = generic_write(fd, buf, n, NULL);
- /* Restore raw mode, in any case; we *must* ignore any error apart
- * EINTR, except for debug.*/
- if(isatty(fd))
+ /*
+ * Restore raw mode, in any case; we *must* ignore any error apart
+ * EINTR, except for debug.
+ */
+ if (isatty(fd))
CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save));
- return(err);
+ return err;
error:
- return(-errno);
+ return -errno;
}
/*
@@ -82,62 +138,73 @@ static int winch_thread(void *arg)
struct winch_data *data = arg;
sigset_t sigs;
int pty_fd, pipe_fd;
- int count, err;
+ int count;
char c = 1;
pty_fd = data->pty_fd;
pipe_fd = data->pipe_fd;
- count = os_write_file(pipe_fd, &c, sizeof(c));
- if(count != sizeof(c))
- printk("winch_thread : failed to write synchronization "
- "byte, err = %d\n", -count);
+ count = write(pipe_fd, &c, sizeof(c));
+ if (count != sizeof(c))
+ printk(UM_KERN_ERR "winch_thread : failed to write "
+ "synchronization byte, err = %d\n", -count);
- /* We are not using SIG_IGN on purpose, so don't fix it as I thought to
+ /*
+ * We are not using SIG_IGN on purpose, so don't fix it as I thought to
* do! If using SIG_IGN, the sigsuspend() call below would not stop on
- * SIGWINCH. */
+ * SIGWINCH.
+ */
signal(SIGWINCH, winch_handler);
sigfillset(&sigs);
/* Block all signals possible. */
- if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
- printk("winch_thread : sigprocmask failed, errno = %d\n",
- errno);
+ if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) {
+ printk(UM_KERN_ERR "winch_thread : sigprocmask failed, "
+ "errno = %d\n", errno);
exit(1);
}
/* In sigsuspend(), block anything else than SIGWINCH. */
sigdelset(&sigs, SIGWINCH);
- if(setsid() < 0){
- printk("winch_thread : setsid failed, errno = %d\n", errno);
+ if (setsid() < 0) {
+ printk(UM_KERN_ERR "winch_thread : setsid failed, errno = %d\n",
+ errno);
+ exit(1);
+ }
+
+ if (ioctl(pty_fd, TIOCSCTTY, 0) < 0) {
+ printk(UM_KERN_ERR "winch_thread : TIOCSCTTY failed on "
+ "fd %d err = %d\n", pty_fd, errno);
exit(1);
}
- err = os_new_tty_pgrp(pty_fd, os_getpid());
- if(err < 0){
- printk("winch_thread : new_tty_pgrp failed on fd %d, "
- "err = %d\n", pty_fd, -err);
+ if (tcsetpgrp(pty_fd, os_getpid()) < 0) {
+ printk(UM_KERN_ERR "winch_thread : tcsetpgrp failed on "
+ "fd %d err = %d\n", pty_fd, errno);
exit(1);
}
- /* These are synchronization calls between various UML threads on the
+ /*
+ * These are synchronization calls between various UML threads on the
* host - since they are not different kernel threads, we cannot use
* kernel semaphores. We don't use SysV semaphores because they are
- * persistent. */
- count = os_read_file(pipe_fd, &c, sizeof(c));
- if(count != sizeof(c))
- printk("winch_thread : failed to read synchronization byte, "
- "err = %d\n", -count);
-
- while(1){
- /* This will be interrupted by SIGWINCH only, since
+ * persistent.
+ */
+ count = read(pipe_fd, &c, sizeof(c));
+ if (count != sizeof(c))
+ printk(UM_KERN_ERR "winch_thread : failed to read "
+ "synchronization byte, err = %d\n", errno);
+
+ while(1) {
+ /*
+ * This will be interrupted by SIGWINCH only, since
* other signals are blocked.
*/
sigsuspend(&sigs);
- count = os_write_file(pipe_fd, &c, sizeof(c));
- if(count != sizeof(c))
- printk("winch_thread : write failed, err = %d\n",
- -count);
+ count = write(pipe_fd, &c, sizeof(c));
+ if (count != sizeof(c))
+ printk(UM_KERN_ERR "winch_thread : write failed, "
+ "err = %d\n", errno);
}
}
@@ -149,44 +216,49 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
char c;
err = os_pipe(fds, 1, 1);
- if(err < 0){
- printk("winch_tramp : os_pipe failed, err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "winch_tramp : os_pipe failed, err = %d\n",
+ -err);
goto out;
}
data = ((struct winch_data) { .pty_fd = fd,
.pipe_fd = fds[1] } );
- /* CLONE_FILES so this thread doesn't hold open files which are open
+ /*
+ * CLONE_FILES so this thread doesn't hold open files which are open
* now, but later closed in a different thread. This is a
* problem with /dev/net/tun, which if held open by this
* thread, prevents the TUN/TAP device from being reused.
*/
err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out);
- if(err < 0){
- printk("fork of winch_thread failed - errno = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n",
+ -err);
goto out_close;
}
*fd_out = fds[0];
- n = os_read_file(fds[0], &c, sizeof(c));
- if(n != sizeof(c)){
- printk("winch_tramp : failed to read synchronization byte\n");
- printk("read failed, err = %d\n", -n);
- printk("fd %d will not support SIGWINCH\n", fd);
- err = -EINVAL;
+ n = read(fds[0], &c, sizeof(c));
+ if (n != sizeof(c)) {
+ printk(UM_KERN_ERR "winch_tramp : failed to read "
+ "synchronization byte\n");
+ printk(UM_KERN_ERR "read failed, err = %d\n", errno);
+ printk(UM_KERN_ERR "fd %d will not support SIGWINCH\n", fd);
+ err = -EINVAL;
goto out_close;
}
if (os_set_fd_block(*fd_out, 0)) {
- printk("winch_tramp: failed to set thread_fd non-blocking.\n");
+ printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd "
+ "non-blocking.\n");
goto out_close;
}
return err;
out_close:
- os_close_file(fds[1]);
- os_close_file(fds[0]);
+ close(fds[1]);
+ close(fds[0]);
out:
return err;
}
@@ -197,21 +269,20 @@ void register_winch(int fd, struct tty_struct *tty)
int pid, thread, count, thread_fd = -1;
char c = 1;
- if(!isatty(fd))
+ if (!isatty(fd))
return;
pid = tcgetpgrp(fd);
- if (!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, tty) &&
- (pid == -1)) {
+ if (!is_skas_winch(pid, fd, tty) && (pid == -1)) {
thread = winch_tramp(fd, tty, &thread_fd, &stack);
if (thread < 0)
return;
register_winch_irq(thread_fd, fd, thread, tty, stack);
- count = os_write_file(thread_fd, &c, sizeof(c));
- if(count != sizeof(c))
- printk("register_winch : failed to write "
- "synchronization byte, err = %d\n", -count);
+ count = write(thread_fd, &c, sizeof(c));
+ if (count != sizeof(c))
+ printk(UM_KERN_ERR "register_winch : failed to write "
+ "synchronization byte, err = %d\n", errno);
}
}
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 0ec4052db9c..93f227a25ba 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -1,17 +1,18 @@
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-/* _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
+ * Licensed under the GPL
+ */
+
+/*
+ * _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines
* that.
*/
#include <unistd.h>
#include <byteswap.h>
-#include <sys/time.h>
-#include <sys/param.h>
-#include <sys/user.h>
-
-#include "os.h"
-
+#include <errno.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <asm/types.h>
#include "cow.h"
#include "cow_sys.h"
@@ -28,7 +29,8 @@ struct cow_header_v1 {
__s32 sectorsize;
} __attribute__((packed));
-/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
+/*
+ * Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
* case other systems have different values for MAXPATHLEN.
*
* The same must hold for V2 - we want file format compatibility, not anything
@@ -46,7 +48,8 @@ struct cow_header_v2 {
__s32 sectorsize;
} __attribute__((packed));
-/* Changes from V2 -
+/*
+ * Changes from V2 -
* PATH_LEN_V3 as described above
* Explicitly specify field bit lengths for systems with different
* lengths for the usual C types. Not sure whether char or
@@ -70,7 +73,8 @@ struct cow_header_v2 {
* Fixed (finally!) the rounding bug
*/
-/* Until Dec2005, __attribute__((packed)) was left out from the below
+/*
+ * Until Dec2005, __attribute__((packed)) was left out from the below
* definition, leading on 64-bit systems to 4 bytes of padding after mtime, to
* align size to 8-byte alignment. This shifted all fields above (no padding
* was present on 32-bit, no other padding was added).
@@ -122,7 +126,7 @@ void cow_sizes(int version, __u64 size, int sectorsize, int align,
int bitmap_offset, unsigned long *bitmap_len_out,
int *data_offset_out)
{
- if(version < 3){
+ if (version < 3) {
*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
*data_offset_out = bitmap_offset + *bitmap_len_out;
@@ -144,46 +148,46 @@ static int absolutize(char *to, int size, char *from)
char save_cwd[256], *slash;
int remaining;
- if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
+ if (getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
cow_printf("absolutize : unable to get cwd - errno = %d\n",
errno);
- return(-1);
+ return -1;
}
slash = strrchr(from, '/');
- if(slash != NULL){
+ if (slash != NULL) {
*slash = '\0';
- if(chdir(from)){
+ if (chdir(from)) {
*slash = '/';
cow_printf("absolutize : Can't cd to '%s' - "
"errno = %d\n", from, errno);
- return(-1);
+ return -1;
}
*slash = '/';
- if(getcwd(to, size) == NULL){
+ if (getcwd(to, size) == NULL) {
cow_printf("absolutize : unable to get cwd of '%s' - "
"errno = %d\n", from, errno);
- return(-1);
+ return -1;
}
remaining = size - strlen(to);
- if(strlen(slash) + 1 > remaining){
+ if (strlen(slash) + 1 > remaining) {
cow_printf("absolutize : unable to fit '%s' into %d "
"chars\n", from, size);
- return(-1);
+ return -1;
}
strcat(to, slash);
}
else {
- if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
+ if (strlen(save_cwd) + 1 + strlen(from) + 1 > size) {
cow_printf("absolutize : unable to fit '%s' into %d "
"chars\n", from, size);
- return(-1);
+ return -1;
}
strcpy(to, save_cwd);
strcat(to, "/");
strcat(to, from);
}
chdir(save_cwd);
- return(0);
+ return 0;
}
int write_cow_header(char *cow_file, int fd, char *backing_file,
@@ -194,22 +198,23 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
int err;
err = cow_seek_file(fd, 0);
- if(err < 0){
+ if (err < 0) {
cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
goto out;
}
err = -ENOMEM;
header = cow_malloc(sizeof(*header));
- if(header == NULL){
- cow_printf("write_cow_header - failed to allocate COW V3 header\n");
+ if (header == NULL) {
+ cow_printf("write_cow_header - failed to allocate COW V3 "
+ "header\n");
goto out;
}
header->magic = htonl(COW_MAGIC);
header->version = htonl(COW_VERSION);
err = -EINVAL;
- if(strlen(backing_file) > sizeof(header->backing_file) - 1){
+ if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
/* Below, %zd is for a size_t value */
cow_printf("Backing file name \"%s\" is too long - names are "
"limited to %zd characters\n", backing_file,
@@ -217,12 +222,12 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
goto out_free;
}
- if(absolutize(header->backing_file, sizeof(header->backing_file),
+ if (absolutize(header->backing_file, sizeof(header->backing_file),
backing_file))
goto out_free;
err = os_file_modtime(header->backing_file, &modtime);
- if(err < 0){
+ if (err < 0) {
cow_printf("write_cow_header - backing file '%s' mtime "
"request failed, err = %d\n", header->backing_file,
-err);
@@ -230,7 +235,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
}
err = cow_file_size(header->backing_file, size);
- if(err < 0){
+ if (err < 0) {
cow_printf("write_cow_header - couldn't get size of "
"backing file '%s', err = %d\n",
header->backing_file, -err);
@@ -244,7 +249,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
header->cow_format = COW_BITMAP;
err = cow_write_file(fd, header, sizeof(*header));
- if(err != sizeof(*header)){
+ if (err != sizeof(*header)) {
cow_printf("write_cow_header - write of header to "
"new COW file '%s' failed, err = %d\n", cow_file,
-err);
@@ -254,14 +259,14 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
out_free:
cow_free(header);
out:
- return(err);
+ return err;
}
int file_reader(__u64 offset, char *buf, int len, void *arg)
{
int fd = *((int *) arg);
- return(pread(fd, buf, len, offset));
+ return pread(fd, buf, len, offset);
}
/* XXX Need to sanity-check the values read from the header */
@@ -278,31 +283,29 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
unsigned long version, magic;
header = cow_malloc(sizeof(*header));
- if(header == NULL){
+ if (header == NULL) {
cow_printf("read_cow_header - Failed to allocate header\n");
- return(-ENOMEM);
+ return -ENOMEM;
}
err = -EINVAL;
n = (*reader)(0, (char *) header, sizeof(*header), arg);
- if(n < offsetof(typeof(header->v1), backing_file)){
+ if (n < offsetof(typeof(header->v1), backing_file)) {
cow_printf("read_cow_header - short header\n");
goto out;
}
magic = header->v1.magic;
- if(magic == COW_MAGIC) {
+ if (magic == COW_MAGIC)
version = header->v1.version;
- }
- else if(magic == ntohl(COW_MAGIC)){
+ else if (magic == ntohl(COW_MAGIC))
version = ntohl(header->v1.version);
- }
/* No error printed because the non-COW case comes through here */
else goto out;
*version_out = version;
- if(version == 1){
- if(n < sizeof(header->v1)){
+ if (version == 1) {
+ if (n < sizeof(header->v1)) {
cow_printf("read_cow_header - failed to read V1 "
"header\n");
goto out;
@@ -314,8 +317,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
*align_out = *sectorsize_out;
file = header->v1.backing_file;
}
- else if(version == 2){
- if(n < sizeof(header->v2)){
+ else if (version == 2) {
+ if (n < sizeof(header->v2)) {
cow_printf("read_cow_header - failed to read V2 "
"header\n");
goto out;
@@ -328,8 +331,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
file = header->v2.backing_file;
}
/* This is very subtle - see above at union cow_header definition */
- else if(version == 3 && (*((int*)header->v3.backing_file) != 0)){
- if(n < sizeof(header->v3)){
+ else if (version == 3 && (*((int*)header->v3.backing_file) != 0)) {
+ if (n < sizeof(header->v3)) {
cow_printf("read_cow_header - failed to read V3 "
"header\n");
goto out;
@@ -345,17 +348,18 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
*bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
file = header->v3.backing_file;
}
- else if(version == 3){
+ else if (version == 3) {
cow_printf("read_cow_header - broken V3 file with"
" 64-bit layout - recovering content.\n");
- if(n < sizeof(header->v3_b)){
+ if (n < sizeof(header->v3_b)) {
cow_printf("read_cow_header - failed to read V3 "
"header\n");
goto out;
}
- /* this was used until Dec2005 - 64bits are needed to represent
+ /*
+ * this was used until Dec2005 - 64bits are needed to represent
* 2038+. I.e. we can safely do this truncating cast.
*
* Additionally, we must use ntohl() instead of ntohll(), since
@@ -381,7 +385,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
}
err = -ENOMEM;
*backing_file_out = cow_strdup(file);
- if(*backing_file_out == NULL){
+ if (*backing_file_out == NULL) {
cow_printf("read_cow_header - failed to allocate backing "
"file\n");
goto out;
@@ -389,7 +393,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
err = 0;
out:
cow_free(header);
- return(err);
+ return err;
}
int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
@@ -402,7 +406,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
err = write_cow_header(cow_file, fd, backing_file, sectorsize,
alignment, &size);
- if(err)
+ if (err)
goto out;
*bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
@@ -411,17 +415,18 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
offset = *data_offset_out + size - sizeof(zero);
err = cow_seek_file(fd, offset);
- if(err < 0){
+ if (err < 0) {
cow_printf("cow bitmap lseek failed : err = %d\n", -err);
goto out;
}
- /* does not really matter how much we write it is just to set EOF
+ /*
+ * does not really matter how much we write it is just to set EOF
* this also sets the entire COW bitmap
* to zero without having to allocate it
*/
err = cow_write_file(fd, &zero, sizeof(zero));
- if(err != sizeof(zero)){
+ if (err != sizeof(zero)) {
cow_printf("Write of bitmap to new COW file '%s' failed, "
"err = %d\n", cow_file, -err);
if (err >= 0)
@@ -429,15 +434,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
goto out;
}
- return(0);
-
+ return 0;
out:
- return(err);
+ return err;
}
-
-/*
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
index 3bc3cf6b94a..6e0e891f8a0 100644
--- a/arch/um/drivers/daemon.h
+++ b/arch/um/drivers/daemon.h
@@ -1,8 +1,11 @@
-/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
+#ifndef __DAEMON_H__
+#define __DAEMON_H__
+
#include "net_user.h"
#define SWITCH_VERSION 3
@@ -20,16 +23,7 @@ struct daemon_data {
extern const struct net_user_info daemon_user_info;
-extern int daemon_user_write(int fd, void *buf, int len,
+extern int daemon_user_write(int fd, void *buf, int len,
struct daemon_data *pri);
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index adeece11e59..d53ff52bb40 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -1,16 +1,14 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
-#include "linux/kernel.h"
#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
+#include <linux/netdevice.h>
#include "net_kern.h"
-#include "net_user.h"
#include "daemon.h"
struct daemon_init {
@@ -36,25 +34,21 @@ static void daemon_init(struct net_device *dev, void *data)
dpri->data_addr = NULL;
dpri->local_addr = NULL;
- printk("daemon backend (uml_switch version %d) - %s:%s",
+ printk("daemon backend (uml_switch version %d) - %s:%s",
SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
printk("\n");
}
-static int daemon_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if(*skb == NULL) return(-ENOMEM);
- return(net_recvfrom(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER));
+ return net_recvfrom(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
}
-static int daemon_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return(daemon_user_write(fd, (*skb)->data, (*skb)->len,
- (struct daemon_data *) &lp->user));
+ return daemon_user_write(fd, skb->data, skb->len,
+ (struct daemon_data *) &lp->user);
}
static const struct net_kern_info daemon_kern_info = {
@@ -72,14 +66,14 @@ static int daemon_setup(char *str, char **mac_out, void *data)
*init = ((struct daemon_init)
{ .sock_type = "unix",
.ctl_sock = "/tmp/uml.ctl" });
-
+
remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
NULL);
- if(remain != NULL)
+ if (remain != NULL)
printk(KERN_WARNING "daemon_setup : Ignoring data socket "
"specification\n");
-
- return(1);
+
+ return 1;
}
static struct transport daemon_transport = {
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 8d2008f0668..f23c109a055 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -1,24 +1,23 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
-#include <errno.h>
-#include <unistd.h>
#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/un.h>
#include <sys/time.h>
-#include "net_user.h"
+#include <sys/un.h>
#include "daemon.h"
-#include "kern_util.h"
-#include "user.h"
+#include "net_user.h"
#include "os.h"
#include "um_malloc.h"
-
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
+#include "user.h"
enum request_type { REQ_NEW_CONTROL };
@@ -36,8 +35,9 @@ static struct sockaddr_un *new_addr(void *name, int len)
struct sockaddr_un *sun;
sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
- if(sun == NULL){
- printk("new_addr: allocation of sockaddr_un failed\n");
+ if (sun == NULL) {
+ printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
+ "failed\n");
return NULL;
}
sun->sun_family = AF_UNIX;
@@ -54,38 +54,39 @@ static int connect_to_switch(struct daemon_data *pri)
int fd, n, err;
pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
- if(pri->control < 0){
+ if (pri->control < 0) {
err = -errno;
- printk("daemon_open : control socket failed, errno = %d\n",
- -err);
+ printk(UM_KERN_ERR "daemon_open : control socket failed, "
+ "errno = %d\n", -err);
return err;
}
- if(connect(pri->control, (struct sockaddr *) ctl_addr,
- sizeof(*ctl_addr)) < 0){
+ if (connect(pri->control, (struct sockaddr *) ctl_addr,
+ sizeof(*ctl_addr)) < 0) {
err = -errno;
- printk("daemon_open : control connect failed, errno = %d\n",
- -err);
+ printk(UM_KERN_ERR "daemon_open : control connect failed, "
+ "errno = %d\n", -err);
goto out;
}
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
- if(fd < 0){
+ if (fd < 0) {
err = -errno;
- printk("daemon_open : data socket failed, errno = %d\n",
- -err);
+ printk(UM_KERN_ERR "daemon_open : data socket failed, "
+ "errno = %d\n", -err);
goto out;
}
- if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
+ if (bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0) {
err = -errno;
- printk("daemon_open : data bind failed, errno = %d\n",
- -err);
+ printk(UM_KERN_ERR "daemon_open : data bind failed, "
+ "errno = %d\n", -err);
goto out_close;
}
sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
- if(sun == NULL){
- printk("new_addr: allocation of sockaddr_un failed\n");
+ if (sun == NULL) {
+ printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
+ "failed\n");
err = -ENOMEM;
goto out_close;
}
@@ -94,18 +95,18 @@ static int connect_to_switch(struct daemon_data *pri)
req.version = SWITCH_VERSION;
req.type = REQ_NEW_CONTROL;
req.sock = *local_addr;
- n = os_write_file(pri->control, &req, sizeof(req));
- if(n != sizeof(req)){
- printk("daemon_open : control setup request failed, err = %d\n",
- -n);
+ n = write(pri->control, &req, sizeof(req));
+ if (n != sizeof(req)) {
+ printk(UM_KERN_ERR "daemon_open : control setup request "
+ "failed, err = %d\n", -errno);
err = -ENOTCONN;
goto out_free;
}
- n = os_read_file(pri->control, sun, sizeof(*sun));
- if(n != sizeof(*sun)){
- printk("daemon_open : read of data socket failed, err = %d\n",
- -n);
+ n = read(pri->control, sun, sizeof(*sun));
+ if (n != sizeof(*sun)) {
+ printk(UM_KERN_ERR "daemon_open : read of data socket failed, "
+ "err = %d\n", -errno);
err = -ENOTCONN;
goto out_free;
}
@@ -116,9 +117,9 @@ static int connect_to_switch(struct daemon_data *pri)
out_free:
kfree(sun);
out_close:
- os_close_file(fd);
+ close(fd);
out:
- os_close_file(pri->control);
+ close(pri->control);
return err;
}
@@ -132,8 +133,8 @@ static int daemon_user_init(void *data, void *dev)
int usecs;
} name;
- if(!strcmp(pri->sock_type, "unix"))
- pri->ctl_addr = new_addr(pri->ctl_sock,
+ if (!strcmp(pri->sock_type, "unix"))
+ pri->ctl_addr = new_addr(pri->ctl_sock,
strlen(pri->ctl_sock) + 1);
name.zero = 0;
name.pid = os_getpid();
@@ -142,7 +143,7 @@ static int daemon_user_init(void *data, void *dev)
pri->local_addr = new_addr(&name, sizeof(name));
pri->dev = dev;
pri->fd = connect_to_switch(pri);
- if(pri->fd < 0){
+ if (pri->fd < 0) {
kfree(pri->local_addr);
pri->local_addr = NULL;
return pri->fd;
@@ -161,9 +162,9 @@ static void daemon_remove(void *data)
{
struct daemon_data *pri = data;
- os_close_file(pri->fd);
+ close(pri->fd);
pri->fd = -1;
- os_close_file(pri->control);
+ close(pri->control);
pri->control = -1;
kfree(pri->data_addr);
@@ -181,18 +182,13 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
-static int daemon_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info daemon_user_info = {
.init = daemon_user_init,
.open = daemon_open,
.close = NULL,
.remove = daemon_remove,
- .set_mtu = daemon_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 39c01ffd45c..0a2bb5b64b8 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -1,17 +1,18 @@
-/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <termios.h>
#include <errno.h>
-#include "user.h"
+#include <termios.h>
#include "chan_user.h"
+#include "kern_constants.h"
#include "os.h"
#include "um_malloc.h"
+#include "user.h"
struct fd_chan {
int fd;
@@ -26,22 +27,26 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts)
char *end;
int n;
- if(*str != ':'){
- printk("fd_init : channel type 'fd' must specify a file "
- "descriptor\n");
- return(NULL);
+ if (*str != ':') {
+ printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a "
+ "file descriptor\n");
+ return NULL;
}
str++;
n = strtoul(str, &end, 0);
- if((*end != '\0') || (end == str)){
- printk("fd_init : couldn't parse file descriptor '%s'\n", str);
- return(NULL);
+ if ((*end != '\0') || (end == str)) {
+ printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor "
+ "'%s'\n", str);
+ return NULL;
}
+
data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
- if(data == NULL) return(NULL);
+ if (data == NULL)
+ return NULL;
+
*data = ((struct fd_chan) { .fd = n,
.raw = opts->raw });
- return(data);
+ return data;
}
static int fd_open(int input, int output, int primary, void *d, char **dev_out)
@@ -49,18 +54,18 @@ static int fd_open(int input, int output, int primary, void *d, char **dev_out)
struct fd_chan *data = d;
int err;
- if(data->raw && isatty(data->fd)){
+ if (data->raw && isatty(data->fd)) {
CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
- if(err)
- return(err);
+ if (err)
+ return err;
err = raw(data->fd);
- if(err)
- return(err);
+ if (err)
+ return err;
}
sprintf(data->str, "%d", data->fd);
*dev_out = data->str;
- return(data->fd);
+ return data->fd;
}
static void fd_close(int fd, void *d)
@@ -68,13 +73,14 @@ static void fd_close(int fd, void *d)
struct fd_chan *data = d;
int err;
- if(data->raw && isatty(fd)){
- CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
- if(err)
- printk("Failed to restore terminal state - "
- "errno = %d\n", -err);
- data->raw = 0;
- }
+ if (!data->raw || !isatty(fd))
+ return;
+
+ CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
+ if (err)
+ printk(UM_KERN_ERR "Failed to restore terminal state - "
+ "errno = %d\n", -err);
+ data->raw = 0;
}
const struct chan_ops fd_ops = {
@@ -89,14 +95,3 @@ const struct chan_ops fd_ops = {
.free = generic_free,
.winch = 1,
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 55601687b3b..a9ad4bd6d95 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -69,7 +69,7 @@ static int harddog_open(struct inode *inode, struct file *file)
spin_lock(&lock);
if(timer_alive)
goto err;
-#ifdef CONFIG_HARDDOG_NOWAYOUT
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
__module_get(THIS_MODULE);
#endif
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index 1171790f742..b56f8e0196a 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -1,16 +1,13 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
-#include "user.h"
-#include "mconsole.h"
#include "os.h"
-#include "choose-mode.h"
-#include "mode.h"
+#include "user.h"
struct dog_data {
int stdin;
@@ -25,10 +22,10 @@ static void pre_exec(void *d)
dup2(data->stdin, 0);
dup2(data->stdout, 1);
dup2(data->stdout, 2);
- os_close_file(data->stdin);
- os_close_file(data->stdout);
- os_close_file(data->close_me[0]);
- os_close_file(data->close_me[1]);
+ close(data->stdin);
+ close(data->stdout);
+ close(data->close_me[0]);
+ close(data->close_me[1]);
}
int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
@@ -42,13 +39,13 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
char **args = NULL;
err = os_pipe(in_fds, 1, 0);
- if(err < 0){
+ if (err < 0) {
printk("harddog_open - os_pipe failed, err = %d\n", -err);
goto out;
}
err = os_pipe(out_fds, 1, 0);
- if(err < 0){
+ if (err < 0) {
printk("harddog_open - os_pipe failed, err = %d\n", -err);
goto out_close_in;
}
@@ -58,37 +55,37 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
data.close_me[0] = out_fds[1];
data.close_me[1] = in_fds[0];
- if(sock != NULL){
+ if (sock != NULL) {
mconsole_args[2] = sock;
args = mconsole_args;
}
else {
/* XXX The os_getpid() is not SMP correct */
- sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid()));
+ sprintf(pid_buf, "%d", os_getpid());
args = pid_args;
}
pid = run_helper(pre_exec, &data, args);
- os_close_file(out_fds[0]);
- os_close_file(in_fds[1]);
+ close(out_fds[0]);
+ close(in_fds[1]);
- if(pid < 0){
+ if (pid < 0) {
err = -pid;
printk("harddog_open - run_helper failed, errno = %d\n", -err);
goto out_close_out;
}
- n = os_read_file(in_fds[0], &c, sizeof(c));
- if(n == 0){
+ n = read(in_fds[0], &c, sizeof(c));
+ if (n == 0) {
printk("harddog_open - EOF on watchdog pipe\n");
helper_wait(pid);
err = -EIO;
goto out_close_out;
}
- else if(n < 0){
+ else if (n < 0) {
printk("harddog_open - read of watchdog pipe failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
helper_wait(pid);
err = n;
goto out_close_out;
@@ -98,19 +95,19 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
return 0;
out_close_in:
- os_close_file(in_fds[0]);
- os_close_file(in_fds[1]);
+ close(in_fds[0]);
+ close(in_fds[1]);
out_close_out:
- os_close_file(out_fds[0]);
- os_close_file(out_fds[1]);
+ close(out_fds[0]);
+ close(out_fds[1]);
out:
return err;
}
void stop_watchdog(int in_fd, int out_fd)
{
- os_close_file(in_fd);
- os_close_file(out_fd);
+ close(in_fd);
+ close(out_fd);
}
int ping_watchdog(int fd)
@@ -118,10 +115,11 @@ int ping_watchdog(int fd)
int n;
char c = '\n';
- n = os_write_file(fd, &c, sizeof(c));
- if(n != sizeof(c)){
- printk("ping_watchdog - write failed, err = %d\n", -n);
- if(n < 0)
+ n = write(fd, &c, sizeof(c));
+ if (n != sizeof(c)) {
+ printk("ping_watchdog - write failed, ret = %d, err = %d\n",
+ n, errno);
+ if (n < 0)
return n;
return -EIO;
}
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 10e08a8c17c..ff1b22b69e9 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -1,16 +1,14 @@
-/*
- * Copyright (C) 2002 Steve Schmidtke
+/*
+ * Copyright (C) 2002 Steve Schmidtke
* Licensed under the GPL
*/
+#include "linux/fs.h"
#include "linux/module.h"
-#include "linux/init.h"
#include "linux/slab.h"
-#include "linux/fs.h"
#include "linux/sound.h"
#include "linux/soundcard.h"
#include "asm/uaccess.h"
-#include "kern_util.h"
#include "init.h"
#include "os.h"
@@ -25,7 +23,8 @@ struct hostmixer_state {
#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
-/* Changed either at boot time or module load time. At boot, this is
+/*
+ * Changed either at boot time or module load time. At boot, this is
* single-threaded; at module load, multiple modules would each have
* their own copy of these variables.
*/
@@ -44,7 +43,7 @@ static char *mixer = HOSTAUDIO_DEV_MIXER;
static int set_dsp(char *name, int *add)
{
dsp = name;
- return(0);
+ return 0;
}
__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
@@ -52,7 +51,7 @@ __uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
static int set_mixer(char *name, int *add)
{
mixer = name;
- return(0);
+ return 0;
}
__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
@@ -77,23 +76,23 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer,
int err;
#ifdef DEBUG
- printk("hostaudio: read called, count = %d\n", count);
+ printk(KERN_DEBUG "hostaudio: read called, count = %d\n", count);
#endif
kbuf = kmalloc(count, GFP_KERNEL);
- if(kbuf == NULL)
- return(-ENOMEM);
+ if (kbuf == NULL)
+ return -ENOMEM;
err = os_read_file(state->fd, kbuf, count);
- if(err < 0)
+ if (err < 0)
goto out;
- if(copy_to_user(buffer, kbuf, err))
+ if (copy_to_user(buffer, kbuf, err))
err = -EFAULT;
out:
kfree(kbuf);
- return(err);
+ return err;
}
static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
@@ -104,40 +103,40 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
int err;
#ifdef DEBUG
- printk("hostaudio: write called, count = %d\n", count);
+ printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count);
#endif
kbuf = kmalloc(count, GFP_KERNEL);
- if(kbuf == NULL)
- return(-ENOMEM);
+ if (kbuf == NULL)
+ return -ENOMEM;
err = -EFAULT;
- if(copy_from_user(kbuf, buffer, count))
+ if (copy_from_user(kbuf, buffer, count))
goto out;
err = os_write_file(state->fd, kbuf, count);
- if(err < 0)
+ if (err < 0)
goto out;
*ppos += err;
out:
kfree(kbuf);
- return(err);
+ return err;
}
-static unsigned int hostaudio_poll(struct file *file,
+static unsigned int hostaudio_poll(struct file *file,
struct poll_table_struct *wait)
{
unsigned int mask = 0;
#ifdef DEBUG
- printk("hostaudio: poll called (unimplemented)\n");
+ printk(KERN_DEBUG "hostaudio: poll called (unimplemented)\n");
#endif
- return(mask);
+ return mask;
}
-static int hostaudio_ioctl(struct inode *inode, struct file *file,
+static int hostaudio_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct hostaudio_state *state = file->private_data;
@@ -145,7 +144,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
int err;
#ifdef DEBUG
- printk("hostaudio: ioctl called, cmd = %u\n", cmd);
+ printk(KERN_DEBUG "hostaudio: ioctl called, cmd = %u\n", cmd);
#endif
switch(cmd){
case SNDCTL_DSP_SPEED:
@@ -154,8 +153,8 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
case SNDCTL_DSP_CHANNELS:
case SNDCTL_DSP_SUBDIVIDE:
case SNDCTL_DSP_SETFRAGMENT:
- if(get_user(data, (int __user *) arg))
- return(-EFAULT);
+ if (get_user(data, (int __user *) arg))
+ return EFAULT;
break;
default:
break;
@@ -170,14 +169,14 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
case SNDCTL_DSP_CHANNELS:
case SNDCTL_DSP_SUBDIVIDE:
case SNDCTL_DSP_SETFRAGMENT:
- if(put_user(data, (int __user *) arg))
- return(-EFAULT);
+ if (put_user(data, (int __user *) arg))
+ return -EFAULT;
break;
default:
break;
}
- return(err);
+ return err;
}
static int hostaudio_open(struct inode *inode, struct file *file)
@@ -187,24 +186,26 @@ static int hostaudio_open(struct inode *inode, struct file *file)
int ret;
#ifdef DEBUG
- printk("hostaudio: open called (host: %s)\n", dsp);
+ printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
#endif
state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
- if(state == NULL)
- return(-ENOMEM);
+ if (state == NULL)
+ return -ENOMEM;
- if(file->f_mode & FMODE_READ) r = 1;
- if(file->f_mode & FMODE_WRITE) w = 1;
+ if (file->f_mode & FMODE_READ)
+ r = 1;
+ if (file->f_mode & FMODE_WRITE)
+ w = 1;
ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
- if(ret < 0){
+ if (ret < 0) {
kfree(state);
- return(ret);
+ return ret;
}
state->fd = ret;
file->private_data = state;
- return(0);
+ return 0;
}
static int hostaudio_release(struct inode *inode, struct file *file)
@@ -212,26 +213,26 @@ static int hostaudio_release(struct inode *inode, struct file *file)
struct hostaudio_state *state = file->private_data;
#ifdef DEBUG
- printk("hostaudio: release called\n");
+ printk(KERN_DEBUG "hostaudio: release called\n");
#endif
os_close_file(state->fd);
kfree(state);
- return(0);
+ return 0;
}
/* /dev/mixer file operations */
-static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
+static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct hostmixer_state *state = file->private_data;
#ifdef DEBUG
- printk("hostmixer: ioctl called\n");
+ printk(KERN_DEBUG "hostmixer: ioctl called\n");
#endif
- return(os_ioctl_generic(state->fd, cmd, arg));
+ return os_ioctl_generic(state->fd, cmd, arg);
}
static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
@@ -241,26 +242,29 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
int ret;
#ifdef DEBUG
- printk("hostmixer: open called (host: %s)\n", mixer);
+ printk(KERN_DEBUG "hostmixer: open called (host: %s)\n", mixer);
#endif
state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
- if(state == NULL) return(-ENOMEM);
+ if (state == NULL)
+ return -ENOMEM;
- if(file->f_mode & FMODE_READ) r = 1;
- if(file->f_mode & FMODE_WRITE) w = 1;
+ if (file->f_mode & FMODE_READ)
+ r = 1;
+ if (file->f_mode & FMODE_WRITE)
+ w = 1;
ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
-
- if(ret < 0){
- printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
- dsp, -ret);
+
+ if (ret < 0) {
+ printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
+ "err = %d\n", dsp, -ret);
kfree(state);
- return(ret);
+ return ret;
}
file->private_data = state;
- return(0);
+ return 0;
}
static int hostmixer_release(struct inode *inode, struct file *file)
@@ -268,13 +272,13 @@ static int hostmixer_release(struct inode *inode, struct file *file)
struct hostmixer_state *state = file->private_data;
#ifdef DEBUG
- printk("hostmixer: release called\n");
+ printk(KERN_DEBUG "hostmixer: release called\n");
#endif
os_close_file(state->fd);
kfree(state);
- return(0);
+ return 0;
}
/* kernel module operations */
@@ -314,13 +318,13 @@ static int __init hostaudio_init_module(void)
dsp, mixer);
module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
- if(module_data.dev_audio < 0){
+ if (module_data.dev_audio < 0) {
printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
return -ENODEV;
}
module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
- if(module_data.dev_mixer < 0){
+ if (module_data.dev_mixer < 0) {
printk(KERN_ERR "hostmixer: couldn't register mixer "
"device!\n");
unregister_sound_dsp(module_data.dev_audio);
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 3e0b68e297f..76fe0b0da99 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -1,22 +1,14 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/sched.h"
-#include "linux/slab.h"
-#include "linux/list.h"
+#include "linux/irqreturn.h"
#include "linux/kd.h"
-#include "linux/interrupt.h"
-#include "asm/uaccess.h"
#include "chan_kern.h"
+#include "irq_kern.h"
#include "irq_user.h"
-#include "line.h"
-#include "kern.h"
-#include "kern_util.h"
#include "os.h"
-#include "irq_kern.h"
#define LINE_BUFSIZE 4096
@@ -35,12 +27,13 @@ static void line_timer_cb(struct work_struct *work)
{
struct line *line = container_of(work, struct line, task.work);
- if(!line->throttled)
+ if (!line->throttled)
chan_interrupt(&line->chan_list, &line->task, line->tty,
line->driver->read_irq);
}
-/* Returns the free space inside the ring buffer of this line.
+/*
+ * Returns the free space inside the ring buffer of this line.
*
* Should be called while holding line->lock (this does not modify datas).
*/
@@ -107,11 +100,12 @@ static int buffer_data(struct line *line, const char *buf, int len)
{
int end, room;
- if(line->buffer == NULL){
+ if (line->buffer == NULL) {
line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
if (line->buffer == NULL) {
- printk("buffer_data - atomic allocation failed\n");
- return(0);
+ printk(KERN_ERR "buffer_data - atomic allocation "
+ "failed\n");
+ return 0;
}
line->head = line->buffer;
line->tail = line->buffer;
@@ -122,7 +116,7 @@ static int buffer_data(struct line *line, const char *buf, int len)
end = line->buffer + LINE_BUFSIZE - line->tail;
- if (len < end){
+ if (len < end) {
memcpy(line->tail, buf, len);
line->tail += len;
}
@@ -162,8 +156,10 @@ static int flush_buffer(struct line *line)
if (n < 0)
return n;
if (n == count) {
- /* We have flushed from ->head to buffer end, now we
- * must flush only from the beginning to ->tail.*/
+ /*
+ * We have flushed from ->head to buffer end, now we
+ * must flush only from the beginning to ->tail.
+ */
line->head = line->buffer;
} else {
line->head += n;
@@ -175,7 +171,7 @@ static int flush_buffer(struct line *line)
n = write_chan(&line->chan_list, line->head, count,
line->driver->write_irq);
- if(n < 0)
+ if (n < 0)
return n;
line->head += n;
@@ -189,19 +185,18 @@ void line_flush_buffer(struct tty_struct *tty)
int err;
/*XXX: copied from line_write, verify if it is correct!*/
- if(tty->stopped)
+ if (tty->stopped)
return;
spin_lock_irqsave(&line->lock, flags);
err = flush_buffer(line);
- /*if (err == 1)
- err = 0;*/
spin_unlock_irqrestore(&line->lock, flags);
- //return err;
}
-/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer
- * and ->write. Hope it's not that bad.*/
+/*
+ * We map both ->flush_chars and ->put_char (which go in pair) onto
+ * ->flush_buffer and ->write. Hope it's not that bad.
+ */
void line_flush_chars(struct tty_struct *tty)
{
line_flush_buffer(tty);
@@ -216,18 +211,15 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
struct line *line = tty->driver_data;
unsigned long flags;
- int n, err, ret = 0;
+ int n, ret = 0;
- if(tty->stopped)
+ if (tty->stopped)
return 0;
spin_lock_irqsave(&line->lock, flags);
- if (line->head != line->tail) {
+ if (line->head != line->tail)
ret = buffer_data(line, buf, len);
- err = flush_buffer(line);
- if (err <= 0 && (err != -EAGAIN || !ret))
- ret = err;
- } else {
+ else {
n = write_chan(&line->chan_list, buf, len,
line->driver->write_irq);
if (n < 0) {
@@ -257,17 +249,17 @@ static const struct {
} tty_ioctls[] = {
/* don't print these, they flood the log ... */
{ TCGETS, NULL, "TCGETS" },
- { TCSETS, NULL, "TCSETS" },
- { TCSETSW, NULL, "TCSETSW" },
- { TCFLSH, NULL, "TCFLSH" },
- { TCSBRK, NULL, "TCSBRK" },
+ { TCSETS, NULL, "TCSETS" },
+ { TCSETSW, NULL, "TCSETSW" },
+ { TCFLSH, NULL, "TCFLSH" },
+ { TCSBRK, NULL, "TCSBRK" },
/* general tty stuff */
- { TCSETSF, KERN_DEBUG, "TCSETSF" },
- { TCGETA, KERN_DEBUG, "TCGETA" },
- { TIOCMGET, KERN_DEBUG, "TIOCMGET" },
- { TCSBRKP, KERN_DEBUG, "TCSBRKP" },
- { TIOCMSET, KERN_DEBUG, "TIOCMSET" },
+ { TCSETSF, KERN_DEBUG, "TCSETSF" },
+ { TCGETA, KERN_DEBUG, "TCGETA" },
+ { TIOCMGET, KERN_DEBUG, "TIOCMGET" },
+ { TCSBRKP, KERN_DEBUG, "TCSBRKP" },
+ { TIOCMSET, KERN_DEBUG, "TIOCMSET" },
/* linux-specific ones */
{ TIOCLINUX, KERN_INFO, "TIOCLINUX" },
@@ -324,12 +316,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
if (cmd == tty_ioctls[i].cmd)
break;
- if (i < ARRAY_SIZE(tty_ioctls)) {
- if (NULL != tty_ioctls[i].level)
- printk("%s%s: %s: ioctl %s called\n",
- tty_ioctls[i].level, __FUNCTION__,
- tty->name, tty_ioctls[i].name);
- } else {
+ if (i == ARRAY_SIZE(tty_ioctls)) {
printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
__FUNCTION__, tty->name, cmd);
}
@@ -355,11 +342,12 @@ void line_unthrottle(struct tty_struct *tty)
chan_interrupt(&line->chan_list, &line->task, tty,
line->driver->read_irq);
- /* Maybe there is enough stuff pending that calling the interrupt
+ /*
+ * Maybe there is enough stuff pending that calling the interrupt
* throttles us again. In this case, line->throttled will be 1
* again and we shouldn't turn the interrupt back on.
*/
- if(!line->throttled)
+ if (!line->throttled)
reactivate_chan(&line->chan_list, line->driver->read_irq);
}
@@ -370,27 +358,30 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
struct tty_struct *tty = line->tty;
int err;
- /* Interrupts are disabled here because we registered the interrupt with
- * IRQF_DISABLED (see line_setup_irq).*/
+ /*
+ * Interrupts are disabled here because we registered the interrupt with
+ * IRQF_DISABLED (see line_setup_irq).
+ */
spin_lock(&line->lock);
err = flush_buffer(line);
if (err == 0) {
return IRQ_NONE;
- } else if(err < 0) {
+ } else if (err < 0) {
line->head = line->buffer;
line->tail = line->buffer;
}
spin_unlock(&line->lock);
- if(tty == NULL)
+ if (tty == NULL)
return IRQ_NONE;
if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
(tty->ldisc.write_wakeup != NULL))
(tty->ldisc.write_wakeup)(tty);
- /* BLOCKING mode
+ /*
+ * BLOCKING mode
* In blocking mode, everything sleeps on tty->write_wait.
* Sleeping in the console driver would break non-blocking
* writes.
@@ -420,7 +411,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
return err;
}
-/* Normally, a driver like this can rely mostly on the tty layer
+/*
+ * Normally, a driver like this can rely mostly on the tty layer
* locking, particularly when it comes to the driver structure.
* However, in this case, mconsole requests can come in "from the
* side", and race with opens and closes.
@@ -442,11 +434,11 @@ int line_open(struct line *lines, struct tty_struct *tty)
int err = -ENODEV;
spin_lock(&line->count_lock);
- if(!line->valid)
+ if (!line->valid)
goto out_unlock;
err = 0;
- if(tty->count > 1)
+ if (tty->count > 1)
goto out_unlock;
spin_unlock(&line->count_lock);
@@ -460,7 +452,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
INIT_DELAYED_WORK(&line->task, line_timer_cb);
- if(!line->sigio){
+ if (!line->sigio) {
chan_enable_winch(&line->chan_list, tty);
line->sigio = 1;
}
@@ -481,20 +473,21 @@ void line_close(struct tty_struct *tty, struct file * filp)
{
struct line *line = tty->driver_data;
- /* If line_open fails (and tty->driver_data is never set),
+ /*
+ * If line_open fails (and tty->driver_data is never set),
* tty_open will call line_close. So just return in this case.
*/
- if(line == NULL)
+ if (line == NULL)
return;
/* We ignore the error anyway! */
flush_buffer(line);
spin_lock(&line->count_lock);
- if(!line->valid)
+ if (!line->valid)
goto out_unlock;
- if(tty->count > 1)
+ if (tty->count > 1)
goto out_unlock;
spin_unlock(&line->count_lock);
@@ -502,10 +495,10 @@ void line_close(struct tty_struct *tty, struct file * filp)
line->tty = NULL;
tty->driver_data = NULL;
- if(line->sigio){
+ if (line->sigio) {
unregister_winch(tty);
line->sigio = 0;
- }
+ }
return;
@@ -529,12 +522,12 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
spin_lock(&line->count_lock);
- if(line->tty != NULL){
+ if (line->tty != NULL) {
*error_out = "Device is already open";
goto out;
}
- if (line->init_pri <= init_prio){
+ if (line->init_pri <= init_prio) {
line->init_pri = init_prio;
if (!strcmp(init, "none"))
line->valid = 0;
@@ -549,7 +542,8 @@ out:
return err;
}
-/* Common setup code for both startup command line and mconsole initialization.
+/*
+ * Common setup code for both startup command line and mconsole initialization.
* @lines contains the array (of size @num) to modify;
* @init is the setup string;
* @error_out is an error string in the case of failure;
@@ -561,14 +555,16 @@ int line_setup(struct line *lines, unsigned int num, char *init,
int i, n, err;
char *end;
- if(*init == '=') {
- /* We said con=/ssl= instead of con#=, so we are configuring all
- * consoles at once.*/
+ if (*init == '=') {
+ /*
+ * We said con=/ssl= instead of con#=, so we are configuring all
+ * consoles at once.
+ */
n = -1;
}
else {
n = simple_strtoul(init, &end, 0);
- if(*end != '='){
+ if (*end != '=') {
*error_out = "Couldn't parse device number";
return -EINVAL;
}
@@ -580,16 +576,16 @@ int line_setup(struct line *lines, unsigned int num, char *init,
*error_out = "Device number out of range";
return -EINVAL;
}
- else if (n >= 0){
+ else if (n >= 0) {
err = setup_one_line(lines, n, init, INIT_ONE, error_out);
- if(err)
+ if (err)
return err;
}
else {
- for(i = 0; i < num; i++){
+ for(i = 0; i < num; i++) {
err = setup_one_line(lines, i, init, INIT_ALL,
error_out);
- if(err)
+ if (err)
return err;
}
}
@@ -603,18 +599,18 @@ int line_config(struct line *lines, unsigned int num, char *str,
char *new;
int n;
- if(*str == '='){
+ if (*str == '=') {
*error_out = "Can't configure all devices from mconsole";
return -EINVAL;
}
new = kstrdup(str, GFP_KERNEL);
- if(new == NULL){
+ if (new == NULL) {
*error_out = "Failed to allocate memory";
return -ENOMEM;
}
n = line_setup(lines, num, new, error_out);
- if(n < 0)
+ if (n < 0)
return n;
line = &lines[n];
@@ -629,12 +625,12 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
int dev, n = 0;
dev = simple_strtoul(name, &end, 0);
- if((*end != '\0') || (end == name)){
+ if ((*end != '\0') || (end == name)) {
*error_out = "line_get_config failed to parse device number";
return 0;
}
- if((dev < 0) || (dev >= num)){
+ if ((dev < 0) || (dev >= num)) {
*error_out = "device number out of range";
return 0;
}
@@ -642,9 +638,9 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
line = &lines[dev];
spin_lock(&line->count_lock);
- if(!line->valid)
+ if (!line->valid)
CONFIG_CHUNK(str, size, n, "none", 1);
- else if(line->tty == NULL)
+ else if (line->tty == NULL)
CONFIG_CHUNK(str, size, n, line->init_str, 1);
else n = chan_config_string(&line->chan_list, str, size, error_out);
spin_unlock(&line->count_lock);
@@ -655,16 +651,16 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
int line_id(char **str, int *start_out, int *end_out)
{
char *end;
- int n;
+ int n;
n = simple_strtoul(*str, &end, 0);
- if((*end != '\0') || (end == *str))
- return -1;
+ if ((*end != '\0') || (end == *str))
+ return -1;
- *str = end;
- *start_out = n;
- *end_out = n;
- return n;
+ *str = end;
+ *start_out = n;
+ *end_out = n;
+ return n;
}
int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
@@ -674,7 +670,7 @@ int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
sprintf(config, "%d=none", n);
err = line_setup(lines, num, config, error_out);
- if(err >= 0)
+ if (err >= 0)
err = 0;
return err;
}
@@ -700,14 +696,14 @@ struct tty_driver *register_lines(struct line_driver *line_driver,
tty_set_operations(driver, ops);
if (tty_register_driver(driver)) {
- printk("%s: can't register %s driver\n",
- __FUNCTION__,line_driver->name);
+ printk(KERN_ERR "register_lines : can't register %s driver\n",
+ line_driver->name);
put_tty_driver(driver);
return NULL;
}
- for(i = 0; i < nlines; i++){
- if(!lines[i].valid)
+ for(i = 0; i < nlines; i++) {
+ if (!lines[i].valid)
tty_unregister_device(driver, i);
}
@@ -724,20 +720,20 @@ void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
char *error;
int i;
- for(i = 0; i < nlines; i++){
+ for(i = 0; i < nlines; i++) {
line = &lines[i];
INIT_LIST_HEAD(&line->chan_list);
- if(line->init_str == NULL)
+ if (line->init_str == NULL)
continue;
line->init_str = kstrdup(line->init_str, GFP_KERNEL);
- if(line->init_str == NULL)
- printk("lines_init - kstrdup returned NULL\n");
+ if (line->init_str == NULL)
+ printk(KERN_ERR "lines_init - kstrdup returned NULL\n");
- if(parse_chan_pair(line->init_str, line, i, opts, &error)){
- printk("parse_chan_pair failed for device %d : %s\n",
- i, error);
+ if (parse_chan_pair(line->init_str, line, i, opts, &error)) {
+ printk(KERN_ERR "parse_chan_pair failed for "
+ "device %d : %s\n", i, error);
line->valid = 0;
}
}
@@ -775,14 +771,14 @@ static irqreturn_t winch_interrupt(int irq, void *data)
int err;
char c;
- if(winch->fd != -1){
+ if (winch->fd != -1) {
err = generic_read(winch->fd, &c, NULL);
- if(err < 0){
- if(err != -EAGAIN){
- printk("winch_interrupt : read failed, "
- "errno = %d\n", -err);
- printk("fd %d is losing SIGWINCH support\n",
- winch->tty_fd);
+ if (err < 0) {
+ if (err != -EAGAIN) {
+ printk(KERN_ERR "winch_interrupt : "
+ "read failed, errno = %d\n", -err);
+ printk(KERN_ERR "fd %d is losing SIGWINCH "
+ "support\n", winch->tty_fd);
free_winch(winch, 0);
return IRQ_HANDLED;
}
@@ -797,7 +793,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
kill_pgrp(tty->pgrp, SIGWINCH, 1);
}
out:
- if(winch->fd != -1)
+ if (winch->fd != -1)
reactivate_fd(winch->fd, WINCH_IRQ);
return IRQ_HANDLED;
}
@@ -809,7 +805,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
winch = kmalloc(sizeof(*winch), GFP_KERNEL);
if (winch == NULL) {
- printk("register_winch_irq - kmalloc failed\n");
+ printk(KERN_ERR "register_winch_irq - kmalloc failed\n");
goto cleanup;
}
@@ -823,7 +819,8 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
"winch", winch) < 0) {
- printk("register_winch_irq - failed to register IRQ\n");
+ printk(KERN_ERR "register_winch_irq - failed to register "
+ "IRQ\n");
goto out_free;
}
@@ -849,13 +846,13 @@ static void unregister_winch(struct tty_struct *tty)
spin_lock(&winch_handler_lock);
- list_for_each(ele, &winch_handlers){
+ list_for_each(ele, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
- if(winch->tty == tty){
+ if (winch->tty == tty) {
free_winch(winch, 1);
break;
- }
- }
+ }
+ }
spin_unlock(&winch_handler_lock);
}
@@ -866,7 +863,7 @@ static void winch_cleanup(void)
spin_lock(&winch_handler_lock);
- list_for_each_safe(ele, next, &winch_handlers){
+ list_for_each_safe(ele, next, &winch_handlers) {
winch = list_entry(ele, struct winch, list);
free_winch(winch, 1);
}
@@ -881,13 +878,13 @@ char *add_xterm_umid(char *base)
int len;
umid = get_umid();
- if(*umid == '\0')
+ if (*umid == '\0')
return base;
len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
title = kmalloc(len, GFP_KERNEL);
- if(title == NULL){
- printk("Failed to allocate buffer for xterm title\n");
+ if (title == NULL) {
+ printk(KERN_ERR "Failed to allocate buffer for xterm title\n");
return base;
}
diff --git a/arch/um/drivers/mcast.h b/arch/um/drivers/mcast.h
index bc56af9d3e5..6fa282e896b 100644
--- a/arch/um/drivers/mcast.h
+++ b/arch/um/drivers/mcast.h
@@ -1,8 +1,11 @@
/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
+#ifndef __DRIVERS_MCAST_H
+#define __DRIVERS_MCAST_H
+
#include "net_user.h"
struct mcast_data {
@@ -18,13 +21,4 @@ extern const struct net_user_info mcast_user_info;
extern int mcast_user_write(int fd, void *buf, int len,
struct mcast_data *pri);
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index e6b8e0dd72a..822092f149b 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -1,24 +1,20 @@
/*
* user-mode-linux networking multicast transport
* Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*
* based on the existing uml-networking code, which is
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
*
* Licensed under the GPL.
*/
-#include "linux/kernel.h"
#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
-#include "linux/in.h"
-#include "linux/inet.h"
-#include "net_kern.h"
-#include "net_user.h"
+#include <linux/netdevice.h>
#include "mcast.h"
+#include "net_kern.h"
struct mcast_init {
char *addr;
@@ -39,26 +35,20 @@ static void mcast_init(struct net_device *dev, void *data)
dpri->ttl = init->ttl;
dpri->dev = dev;
- printk("mcast backend ");
- printk("multicast address: %s:%u, TTL:%u ",
+ printk("mcast backend multicast address: %s:%u, TTL:%u\n",
dpri->addr, dpri->port, dpri->ttl);
-
- printk("\n");
}
-static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if(*skb == NULL) return(-ENOMEM);
- return(net_recvfrom(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER));
+ return net_recvfrom(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
}
-static int mcast_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return mcast_user_write(fd, (*skb)->data, (*skb)->len,
- (struct mcast_data *) &lp->user);
+ return mcast_user_write(fd, skb->data, skb->len,
+ (struct mcast_data *) &lp->user);
}
static const struct net_kern_info mcast_kern_info = {
@@ -81,34 +71,34 @@ int mcast_setup(char *str, char **mac_out, void *data)
remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
NULL);
- if(remain != NULL){
+ if (remain != NULL) {
printk(KERN_ERR "mcast_setup - Extra garbage on "
"specification : '%s'\n", remain);
- return(0);
+ return 0;
}
-
- if(port_str != NULL){
+
+ if (port_str != NULL) {
init->port = simple_strtoul(port_str, &last, 10);
- if((*last != '\0') || (last == port_str)){
- printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
+ if ((*last != '\0') || (last == port_str)) {
+ printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
port_str);
- return(0);
+ return 0;
}
}
- if(ttl_str != NULL){
+ if (ttl_str != NULL) {
init->ttl = simple_strtoul(ttl_str, &last, 10);
- if((*last != '\0') || (last == ttl_str)){
- printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
+ if ((*last != '\0') || (last == ttl_str)) {
+ printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
ttl_str);
- return(0);
+ return 0;
}
}
printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
init->port, init->ttl);
- return(1);
+ return 1;
}
static struct transport mcast_transport = {
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 236a3dfc297..5f647d7a729 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -1,9 +1,10 @@
/*
* user-mode-linux networking multicast transport
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
*
* based on the existing uml-networking code, which is
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
*
@@ -11,28 +12,22 @@
*
*/
-#include <errno.h>
#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/time.h>
+#include <errno.h>
#include <netinet/in.h>
-#include "net_user.h"
#include "mcast.h"
-#include "kern_util.h"
-#include "user.h"
-#include "os.h"
+#include "net_user.h"
#include "um_malloc.h"
-
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
+#include "user.h"
static struct sockaddr_in *new_addr(char *addr, unsigned short port)
{
struct sockaddr_in *sin;
sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
- if(sin == NULL){
- printk("new_addr: allocation of sockaddr_in failed\n");
+ if (sin == NULL) {
+ printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
+ "failed\n");
return NULL;
}
sin->sin_family = AF_INET;
@@ -71,17 +66,17 @@ static int mcast_open(void *data)
fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0){
+ if (fd < 0) {
err = -errno;
- printk("mcast_open : data socket failed, errno = %d\n",
- errno);
+ printk(UM_KERN_ERR "mcast_open : data socket failed, "
+ "errno = %d\n", errno);
goto out;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
err = -errno;
- printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
- errno);
+ printk(UM_KERN_ERR "mcast_open: SO_REUSEADDR failed, "
+ "errno = %d\n", errno);
goto out_close;
}
@@ -89,45 +84,46 @@ static int mcast_open(void *data)
if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
sizeof(pri->ttl)) < 0) {
err = -errno;
- printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
- errno);
+ printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_TTL failed, "
+ "error = %d\n", errno);
goto out_close;
}
/* set LOOP, so data does get fed back to local sockets */
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
err = -errno;
- printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
- errno);
+ printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_LOOP failed, "
+ "error = %d\n", errno);
goto out_close;
}
/* bind socket to mcast address */
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
err = -errno;
- printk("mcast_open : data bind failed, errno = %d\n", errno);
+ printk(UM_KERN_ERR "mcast_open : data bind failed, "
+ "errno = %d\n", errno);
goto out_close;
}
/* subscribe to the multicast group */
mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
mreq.imr_interface.s_addr = 0;
- if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
+ if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0) {
err = -errno;
- printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
- errno);
- printk("There appears not to be a multicast-capable network "
- "interface on the host.\n");
- printk("eth0 should be configured in order to use the "
- "multicast transport.\n");
+ printk(UM_KERN_ERR "mcast_open: IP_ADD_MEMBERSHIP failed, "
+ "error = %d\n", errno);
+ printk(UM_KERN_ERR "There appears not to be a multicast-"
+ "capable network interface on the host.\n");
+ printk(UM_KERN_ERR "eth0 should be configured in order to use "
+ "the multicast transport.\n");
goto out_close;
}
return fd;
out_close:
- os_close_file(fd);
+ close(fd);
out:
return err;
}
@@ -142,11 +138,11 @@ static void mcast_close(int fd, void *data)
mreq.imr_interface.s_addr = 0;
if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0) {
- printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n",
- errno);
+ printk(UM_KERN_ERR "mcast_open: IP_DROP_MEMBERSHIP failed, "
+ "error = %d\n", errno);
}
- os_close_file(fd);
+ close(fd);
}
int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
@@ -156,18 +152,13 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
-static int mcast_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info mcast_user_info = {
.init = mcast_user_init,
.open = mcast_open,
.close = mcast_close,
.remove = mcast_remove,
- .set_mtu = mcast_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index d8709050740..0f3c7d14a6e 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -1,44 +1,35 @@
/*
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
- * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/slab.h"
-#include "linux/init.h"
-#include "linux/notifier.h"
-#include "linux/reboot.h"
-#include "linux/utsname.h"
+#include "linux/console.h"
#include "linux/ctype.h"
#include "linux/interrupt.h"
-#include "linux/sysrq.h"
-#include "linux/workqueue.h"
+#include "linux/list.h"
+#include "linux/mm.h"
#include "linux/module.h"
-#include "linux/file.h"
-#include "linux/fs.h"
-#include "linux/namei.h"
+#include "linux/notifier.h"
+#include "linux/reboot.h"
#include "linux/proc_fs.h"
+#include "linux/slab.h"
#include "linux/syscalls.h"
-#include "linux/list.h"
-#include "linux/mm.h"
-#include "linux/console.h"
-#include "asm/irq.h"
+#include "linux/utsname.h"
+#include "linux/workqueue.h"
#include "asm/uaccess.h"
+#include "init.h"
+#include "irq_kern.h"
+#include "irq_user.h"
#include "kern_util.h"
-#include "kern.h"
#include "mconsole.h"
#include "mconsole_kern.h"
-#include "irq_user.h"
-#include "init.h"
#include "os.h"
-#include "irq_kern.h"
-#include "choose-mode.h"
static int do_unlink_socket(struct notifier_block *notifier,
unsigned long what, void *data)
{
- return(mconsole_unlink_socket());
+ return mconsole_unlink_socket();
}
@@ -59,10 +50,9 @@ static void mc_work_proc(struct work_struct *unused)
struct mconsole_entry *req;
unsigned long flags;
- while(!list_empty(&mc_requests)){
+ while (!list_empty(&mc_requests)) {
local_irq_save(flags);
- req = list_entry(mc_requests.next, struct mconsole_entry,
- list);
+ req = list_entry(mc_requests.next, struct mconsole_entry, list);
list_del(&req->list);
local_irq_restore(flags);
req->request.cmd->handler(&req->request);
@@ -80,12 +70,12 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
static struct mc_request req; /* that's OK */
fd = (long) dev_id;
- while (mconsole_get_request(fd, &req)){
- if(req.cmd->context == MCONSOLE_INTR)
+ while (mconsole_get_request(fd, &req)) {
+ if (req.cmd->context == MCONSOLE_INTR)
(*req.cmd->handler)(&req);
else {
new = kmalloc(sizeof(*new), GFP_NOWAIT);
- if(new == NULL)
+ if (new == NULL)
mconsole_reply(&req, "Out of memory", 1, 0);
else {
new->request = req;
@@ -94,10 +84,10 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
}
}
}
- if(!list_empty(&mc_requests))
+ if (!list_empty(&mc_requests))
schedule_work(&mconsole_work);
reactivate_fd(fd, MCONSOLE_IRQ);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
void mconsole_version(struct mc_request *req)
@@ -105,8 +95,8 @@ void mconsole_version(struct mc_request *req)
char version[256];
sprintf(version, "%s %s %s %s %s", utsname()->sysname,
- utsname()->nodename, utsname()->release,
- utsname()->version, utsname()->machine);
+ utsname()->nodename, utsname()->release, utsname()->version,
+ utsname()->machine);
mconsole_reply(req, version, 0, 0);
}
@@ -118,7 +108,7 @@ void mconsole_log(struct mc_request *req)
ptr += strlen("log ");
len = req->len - (ptr - req->request.data);
- printk("%.*s", len, ptr);
+ printk(KERN_WARNING "%.*s", len, ptr);
mconsole_reply(req, "", 0, 0);
}
@@ -137,17 +127,17 @@ void mconsole_proc(struct mc_request *req)
char *ptr = req->request.data, *buf;
ptr += strlen("proc");
- while(isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
proc = get_fs_type("proc");
- if(proc == NULL){
+ if (proc == NULL) {
mconsole_reply(req, "procfs not registered", 1, 0);
goto out;
}
super = (*proc->get_sb)(proc, 0, NULL, NULL);
put_filesystem(proc);
- if(super == NULL){
+ if (super == NULL) {
mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
goto out;
}
@@ -162,29 +152,29 @@ void mconsole_proc(struct mc_request *req)
* if commenting out these two calls + the below read cycle. To
* make UML crash again, it was enough to readd either one.*/
err = link_path_walk(ptr, &nd);
- if(err){
+ if (err) {
mconsole_reply(req, "Failed to look up file", 1, 0);
goto out_kill;
}
file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
- if(IS_ERR(file)){
+ if (IS_ERR(file)) {
mconsole_reply(req, "Failed to open file", 1, 0);
goto out_kill;
}
/*END*/
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if(buf == NULL){
+ if (buf == NULL) {
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
goto out_fput;
}
- if((file->f_op != NULL) && (file->f_op->read != NULL)){
+ if ((file->f_op != NULL) && (file->f_op->read != NULL)) {
do {
n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
&file->f_pos);
- if(n >= 0){
+ if (n >= 0) {
buf[n] = '\0';
mconsole_reply(req, buf, 0, (n > 0));
}
@@ -193,7 +183,7 @@ void mconsole_proc(struct mc_request *req)
1, 0);
goto out_free;
}
- } while(n > 0);
+ } while (n > 0);
}
else mconsole_reply(req, "", 0, 0);
@@ -217,18 +207,19 @@ void mconsole_proc(struct mc_request *req)
char *ptr = req->request.data;
ptr += strlen("proc");
- while(isspace(*ptr)) ptr++;
+ while (isspace(*ptr))
+ ptr++;
snprintf(path, sizeof(path), "/proc/%s", ptr);
fd = sys_open(path, 0, 0);
if (fd < 0) {
mconsole_reply(req, "Failed to open file", 1, 0);
- printk("open %s: %d\n",path,fd);
+ printk(KERN_ERR "open %s: %d\n",path,fd);
goto out;
}
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if(buf == NULL){
+ if (buf == NULL) {
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
goto out_close;
}
@@ -239,7 +230,7 @@ void mconsole_proc(struct mc_request *req)
mconsole_reply(req, "Read of file failed", 1, 0);
goto out_free;
}
- /*Begin the file content on his own line.*/
+ /* Begin the file content on his own line. */
if (first_chunk) {
mconsole_reply(req, "\n", 0, 1);
first_chunk = 0;
@@ -351,12 +342,12 @@ static struct mc_device *mconsole_find_dev(char *name)
struct list_head *ele;
struct mc_device *dev;
- list_for_each(ele, &mconsole_devices){
+ list_for_each(ele, &mconsole_devices) {
dev = list_entry(ele, struct mc_device, list);
- if(!strncmp(name, dev->name, strlen(dev->name)))
- return(dev);
+ if (!strncmp(name, dev->name, strlen(dev->name)))
+ return dev;
}
- return(NULL);
+ return NULL;
}
#define UNPLUGGED_PER_PAGE \
@@ -378,15 +369,15 @@ static int mem_config(char *str, char **error_out)
int err = -EINVAL, i, add;
char *ret;
- if(str[0] != '='){
+ if (str[0] != '=') {
*error_out = "Expected '=' after 'mem'";
goto out;
}
str++;
- if(str[0] == '-')
+ if (str[0] == '-')
add = 0;
- else if(str[0] == '+'){
+ else if (str[0] == '+') {
add = 1;
}
else {
@@ -396,7 +387,7 @@ static int mem_config(char *str, char **error_out)
str++;
diff = memparse(str, &ret);
- if(*ret != '\0'){
+ if (*ret != '\0') {
*error_out = "Failed to parse memory increment";
goto out;
}
@@ -404,17 +395,17 @@ static int mem_config(char *str, char **error_out)
diff /= PAGE_SIZE;
down(&plug_mem_mutex);
- for(i = 0; i < diff; i++){
+ for (i = 0; i < diff; i++) {
struct unplugged_pages *unplugged;
void *addr;
- if(add){
- if(list_empty(&unplugged_pages))
+ if (add) {
+ if (list_empty(&unplugged_pages))
break;
unplugged = list_entry(unplugged_pages.next,
struct unplugged_pages, list);
- if(unplug_index > 0)
+ if (unplug_index > 0)
addr = unplugged->pages[--unplug_index];
else {
list_del(&unplugged->list);
@@ -429,11 +420,11 @@ static int mem_config(char *str, char **error_out)
struct page *page;
page = alloc_page(GFP_ATOMIC);
- if(page == NULL)
+ if (page == NULL)
break;
unplugged = page_address(page);
- if(unplug_index == UNPLUGGED_PER_PAGE){
+ if (unplug_index == UNPLUGGED_PER_PAGE) {
list_add(&unplugged->list, &unplugged_pages);
unplug_index = 0;
}
@@ -445,9 +436,9 @@ static int mem_config(char *str, char **error_out)
struct unplugged_pages,
list);
err = os_drop_memory(addr, PAGE_SIZE);
- if(err){
- printk("Failed to release memory - "
- "errno = %d\n", err);
+ if (err) {
+ printk(KERN_ERR "Failed to release "
+ "memory - errno = %d\n", err);
*error_out = "Failed to release memory";
goto out_unlock;
}
@@ -501,10 +492,10 @@ static struct mc_device mem_mc = {
static int __init mem_mc_init(void)
{
- if(can_drop_memory())
+ if (can_drop_memory())
mconsole_register_dev(&mem_mc);
- else printk("Can't release memory to the host - memory hotplug won't "
- "be supported\n");
+ else printk(KERN_ERR "Can't release memory to the host - memory "
+ "hotplug won't be supported\n");
return 0;
}
@@ -519,7 +510,7 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
char default_buf[CONFIG_BUF_SIZE], *error, *buf;
int n, size;
- if(get_config == NULL){
+ if (get_config == NULL) {
mconsole_reply(req, "No get_config routine defined", 1, 0);
return;
}
@@ -528,30 +519,30 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
size = ARRAY_SIZE(default_buf);
buf = default_buf;
- while(1){
+ while (1) {
n = (*get_config)(name, buf, size, &error);
- if(error != NULL){
+ if (error != NULL) {
mconsole_reply(req, error, 1, 0);
goto out;
}
- if(n <= size){
+ if (n <= size) {
mconsole_reply(req, buf, 0, 0);
goto out;
}
- if(buf != default_buf)
+ if (buf != default_buf)
kfree(buf);
size = n;
buf = kmalloc(size, GFP_KERNEL);
- if(buf == NULL){
+ if (buf == NULL) {
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
return;
}
}
out:
- if(buf != default_buf)
+ if (buf != default_buf)
kfree(buf);
}
@@ -562,19 +553,20 @@ void mconsole_config(struct mc_request *req)
int err;
ptr += strlen("config");
- while(isspace(*ptr)) ptr++;
+ while (isspace(*ptr))
+ ptr++;
dev = mconsole_find_dev(ptr);
- if(dev == NULL){
+ if (dev == NULL) {
mconsole_reply(req, "Bad configuration option", 1, 0);
return;
}
name = &ptr[strlen(dev->name)];
ptr = name;
- while((*ptr != '=') && (*ptr != '\0'))
+ while ((*ptr != '=') && (*ptr != '\0'))
ptr++;
- if(*ptr == '='){
+ if (*ptr == '=') {
err = (*dev->config)(name, &error_string);
mconsole_reply(req, error_string, err, 0);
}
@@ -589,9 +581,9 @@ void mconsole_remove(struct mc_request *req)
int err, start, end, n;
ptr += strlen("remove");
- while(isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
dev = mconsole_find_dev(ptr);
- if(dev == NULL){
+ if (dev == NULL) {
mconsole_reply(req, "Bad remove option", 1, 0);
return;
}
@@ -600,11 +592,11 @@ void mconsole_remove(struct mc_request *req)
err = 1;
n = (*dev->id)(&ptr, &start, &end);
- if(n < 0){
+ if (n < 0) {
err_msg = "Couldn't parse device number";
goto out;
}
- else if((n < start) || (n > end)){
+ else if ((n < start) || (n > end)) {
sprintf(error, "Invalid device number - must be between "
"%d and %d", start, end);
err_msg = error;
@@ -613,16 +605,16 @@ void mconsole_remove(struct mc_request *req)
err_msg = NULL;
err = (*dev->remove)(n, &err_msg);
- switch(err){
+ switch(err) {
case 0:
err_msg = "";
break;
case -ENODEV:
- if(err_msg == NULL)
+ if (err_msg == NULL)
err_msg = "Device doesn't exist";
break;
case -EBUSY:
- if(err_msg == NULL)
+ if (err_msg == NULL)
err_msg = "Device is currently open";
break;
default:
@@ -640,35 +632,28 @@ struct mconsole_output {
static DEFINE_SPINLOCK(client_lock);
static LIST_HEAD(clients);
static char console_buf[MCONSOLE_MAX_DATA];
-static int console_index = 0;
static void console_write(struct console *console, const char *string,
- unsigned len)
+ unsigned int len)
{
struct list_head *ele;
int n;
- if(list_empty(&clients))
+ if (list_empty(&clients))
return;
- while(1){
- n = min((size_t) len, ARRAY_SIZE(console_buf) - console_index);
- strncpy(&console_buf[console_index], string, n);
- console_index += n;
+ while (len > 0) {
+ n = min((size_t) len, ARRAY_SIZE(console_buf));
+ strncpy(console_buf, string, n);
string += n;
len -= n;
- if(len == 0)
- return;
- list_for_each(ele, &clients){
+ list_for_each(ele, &clients) {
struct mconsole_output *entry;
entry = list_entry(ele, struct mconsole_output, list);
- mconsole_reply_len(entry->req, console_buf,
- console_index, 0, 1);
+ mconsole_reply_len(entry->req, console_buf, n, 0, 1);
}
-
- console_index = 0;
}
}
@@ -698,8 +683,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
(*proc)(arg);
- mconsole_reply_len(req, console_buf, console_index, 0, 0);
- console_index = 0;
+ mconsole_reply_len(req, "", 0, 0, 0);
spin_lock_irqsave(&client_lock, flags);
list_del(&entry.list);
@@ -707,6 +691,9 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
}
#ifdef CONFIG_MAGIC_SYSRQ
+
+#include <linux/sysrq.h>
+
static void sysrq_proc(void *arg)
{
char *op = arg;
@@ -718,12 +705,13 @@ void mconsole_sysrq(struct mc_request *req)
char *ptr = req->request.data;
ptr += strlen("sysrq");
- while(isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
- /* With 'b', the system will shut down without a chance to reply,
+ /*
+ * With 'b', the system will shut down without a chance to reply,
* so in this case, we reply first.
*/
- if(*ptr == 'b')
+ if (*ptr == 'b')
mconsole_reply(req, "", 0, 0);
with_console(req, sysrq_proc, ptr);
@@ -735,8 +723,6 @@ void mconsole_sysrq(struct mc_request *req)
}
#endif
-#ifdef CONFIG_MODE_SKAS
-
static void stack_proc(void *arg)
{
struct task_struct *from = current, *to = arg;
@@ -745,29 +731,34 @@ static void stack_proc(void *arg)
switch_to(from, to, from);
}
-/* Mconsole stack trace
+/*
+ * Mconsole stack trace
* Added by Allan Graves, Jeff Dike
* Dumps a stacks registers to the linux console.
* Usage stack <pid>.
*/
-static void do_stack_trace(struct mc_request *req)
+void mconsole_stack(struct mc_request *req)
{
char *ptr = req->request.data;
int pid_requested= -1;
struct task_struct *from = NULL;
struct task_struct *to = NULL;
- /* Would be nice:
+ /*
+ * Would be nice:
* 1) Send showregs output to mconsole.
* 2) Add a way to stack dump all pids.
*/
ptr += strlen("stack");
- while(isspace(*ptr)) ptr++;
+ while (isspace(*ptr))
+ ptr++;
- /* Should really check for multiple pids or reject bad args here */
+ /*
+ * Should really check for multiple pids or reject bad args here
+ */
/* What do the arguments in mconsole_reply mean? */
- if(sscanf(ptr, "%d", &pid_requested) == 0){
+ if (sscanf(ptr, "%d", &pid_requested) == 0) {
mconsole_reply(req, "Please specify a pid", 1, 0);
return;
}
@@ -775,25 +766,15 @@ static void do_stack_trace(struct mc_request *req)
from = current;
to = find_task_by_pid(pid_requested);
- if((to == NULL) || (pid_requested == 0)) {
+ if ((to == NULL) || (pid_requested == 0)) {
mconsole_reply(req, "Couldn't find that pid", 1, 0);
return;
}
with_console(req, stack_proc, to);
}
-#endif /* CONFIG_MODE_SKAS */
-void mconsole_stack(struct mc_request *req)
-{
- /* This command doesn't work in TT mode, so let's check and then
- * get out of here
- */
- CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
- 1, 0),
- do_stack_trace(req));
-}
-
-/* Changed by mconsole_setup, which is __setup, and called before SMP is
+/*
+ * Changed by mconsole_setup, which is __setup, and called before SMP is
* active.
*/
static char *notify_socket = NULL;
@@ -805,13 +786,14 @@ static int __init mconsole_init(void)
int err;
char file[256];
- if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
+ if (umid_file_name("mconsole", file, sizeof(file)))
+ return -1;
snprintf(mconsole_socket_name, sizeof(file), "%s", file);
sock = os_create_unix_socket(file, sizeof(file), 1);
- if (sock < 0){
- printk("Failed to initialize management console\n");
- return(1);
+ if (sock < 0) {
+ printk(KERN_ERR "Failed to initialize management console\n");
+ return 1;
}
register_reboot_notifier(&reboot_notifier);
@@ -819,14 +801,14 @@ static int __init mconsole_init(void)
err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
"mconsole", (void *)sock);
- if (err){
- printk("Failed to get IRQ for management console\n");
- return(1);
+ if (err) {
+ printk(KERN_ERR "Failed to get IRQ for management console\n");
+ return 1;
}
- if(notify_socket != NULL){
+ if (notify_socket != NULL) {
notify_socket = kstrdup(notify_socket, GFP_KERNEL);
- if(notify_socket != NULL)
+ if (notify_socket != NULL)
mconsole_notify(notify_socket, MCONSOLE_SOCKET,
mconsole_socket_name,
strlen(mconsole_socket_name) + 1);
@@ -834,9 +816,9 @@ static int __init mconsole_init(void)
"string\n");
}
- printk("mconsole (version %d) initialized on %s\n",
+ printk(KERN_INFO "mconsole (version %d) initialized on %s\n",
MCONSOLE_VERSION, mconsole_socket_name);
- return(0);
+ return 0;
}
__initcall(mconsole_init);
@@ -847,10 +829,10 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
char *buf;
buf = kmalloc(count + 1, GFP_KERNEL);
- if(buf == NULL)
- return(-ENOMEM);
+ if (buf == NULL)
+ return -ENOMEM;
- if(copy_from_user(buf, buffer, count)){
+ if (copy_from_user(buf, buffer, count)) {
count = -EFAULT;
goto out;
}
@@ -860,24 +842,26 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
out:
kfree(buf);
- return(count);
+ return count;
}
static int create_proc_mconsole(void)
{
struct proc_dir_entry *ent;
- if(notify_socket == NULL) return(0);
+ if (notify_socket == NULL)
+ return 0;
ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
- if(ent == NULL){
- printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n");
- return(0);
+ if (ent == NULL) {
+ printk(KERN_INFO "create_proc_mconsole : create_proc_entry "
+ "failed\n");
+ return 0;
}
ent->read_proc = NULL;
ent->write_proc = write_proc_mconsole;
- return(0);
+ return 0;
}
static DEFINE_SPINLOCK(notify_spinlock);
@@ -894,19 +878,19 @@ void unlock_notify(void)
__initcall(create_proc_mconsole);
-#define NOTIFY "=notify:"
+#define NOTIFY "notify:"
static int mconsole_setup(char *str)
{
- if(!strncmp(str, NOTIFY, strlen(NOTIFY))){
+ if (!strncmp(str, NOTIFY, strlen(NOTIFY))) {
str += strlen(NOTIFY);
notify_socket = str;
}
else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
- return(1);
+ return 1;
}
-__setup("mconsole", mconsole_setup);
+__setup("mconsole=", mconsole_setup);
__uml_help(mconsole_setup,
"mconsole=notify:<socket>\n"
@@ -921,11 +905,12 @@ static int notify_panic(struct notifier_block *self, unsigned long unused1,
{
char *message = ptr;
- if(notify_socket == NULL) return(0);
+ if (notify_socket == NULL)
+ return 0;
mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
strlen(message) + 1);
- return(0);
+ return 0;
}
static struct notifier_block panic_exit_notifier = {
@@ -938,14 +923,14 @@ static int add_notifier(void)
{
atomic_notifier_chain_register(&panic_notifier_list,
&panic_exit_notifier);
- return(0);
+ return 0;
}
__initcall(add_notifier);
char *mconsole_notify_socket(void)
{
- return(notify_socket);
+ return notify_socket;
}
EXPORT_SYMBOL(mconsole_notify_socket);
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index f31e71546e5..430c024a19b 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -1,25 +1,22 @@
/*
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
- * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stdio.h>
-#include <stdlib.h>
#include <errno.h>
-#include <signal.h>
+#include <string.h>
+#include <unistd.h>
#include <sys/socket.h>
-#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
-#include <unistd.h>
-#include "user.h"
-#include "sysdep/ptrace.h"
+#include "kern_constants.h"
#include "mconsole.h"
-#include "os.h"
+#include "user.h"
static struct mconsole_command commands[] = {
- /* With uts namespaces, uts information becomes process-specific, so
+ /*
+ * With uts namespaces, uts information becomes process-specific, so
* we need a process context. If we try handling this in interrupt
* context, we may hit an exiting process without a valid uts
* namespace.
@@ -36,7 +33,7 @@ static struct mconsole_command commands[] = {
{ "go", mconsole_go, MCONSOLE_INTR },
{ "log", mconsole_log, MCONSOLE_INTR },
{ "proc", mconsole_proc, MCONSOLE_PROC },
- { "stack", mconsole_stack, MCONSOLE_INTR },
+ { "stack", mconsole_stack, MCONSOLE_INTR },
};
/* Initialized in mconsole_init, which is an initcall */
@@ -44,21 +41,21 @@ char mconsole_socket_name[256];
int mconsole_reply_v0(struct mc_request *req, char *reply)
{
- struct iovec iov;
- struct msghdr msg;
+ struct iovec iov;
+ struct msghdr msg;
- iov.iov_base = reply;
- iov.iov_len = strlen(reply);
+ iov.iov_base = reply;
+ iov.iov_len = strlen(reply);
- msg.msg_name = &(req->origin);
- msg.msg_namelen = req->originlen;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
+ msg.msg_name = &(req->origin);
+ msg.msg_namelen = req->originlen;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
- return sendmsg(req->originating_fd, &msg, 0);
+ return sendmsg(req->originating_fd, &msg, 0);
}
static struct mconsole_command *mconsole_parse(struct mc_request *req)
@@ -66,10 +63,10 @@ static struct mconsole_command *mconsole_parse(struct mc_request *req)
struct mconsole_command *cmd;
int i;
- for(i = 0; i < ARRAY_SIZE(commands); i++){
+ for (i = 0; i < ARRAY_SIZE(commands); i++) {
cmd = &commands[i];
- if(!strncmp(req->request.data, cmd->command,
- strlen(cmd->command))){
+ if (!strncmp(req->request.data, cmd->command,
+ strlen(cmd->command))) {
return cmd;
}
}
@@ -94,9 +91,9 @@ int mconsole_get_request(int fd, struct mc_request *req)
req->originating_fd = fd;
- if(req->request.magic != MCONSOLE_MAGIC){
+ if (req->request.magic != MCONSOLE_MAGIC) {
/* Unversioned request */
- len = MIN(sizeof(req->request.data) - 1,
+ len = MIN(sizeof(req->request.data) - 1,
strlen((char *) &req->request));
memmove(req->request.data, &req->request, len);
req->request.data[len] = '\0';
@@ -107,32 +104,33 @@ int mconsole_get_request(int fd, struct mc_request *req)
mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
"not supported by this driver");
- return(0);
+ return 0;
}
- if(req->request.len >= MCONSOLE_MAX_DATA){
+ if (req->request.len >= MCONSOLE_MAX_DATA) {
mconsole_reply(req, "Request too large", 1, 0);
- return(0);
+ return 0;
}
- if(req->request.version != MCONSOLE_VERSION){
- mconsole_reply(req, "This driver only supports version "
- STRING(MCONSOLE_VERSION) " clients", 1, 0);
+ if (req->request.version != MCONSOLE_VERSION) {
+ mconsole_reply(req, "This driver only supports version "
+ STRING(MCONSOLE_VERSION) " clients", 1, 0);
}
-
+
req->request.data[req->request.len] = '\0';
req->cmd = mconsole_parse(req);
- if(req->cmd == NULL){
+ if (req->cmd == NULL) {
mconsole_reply(req, "Unknown command", 1, 0);
- return(0);
+ return 0;
}
- return(1);
+ return 1;
}
int mconsole_reply_len(struct mc_request *req, const char *str, int total,
int err, int more)
{
- /* XXX This is a stack consumption problem. It'd be nice to
+ /*
+ * XXX This is a stack consumption problem. It'd be nice to
* make it global and serialize access to it, but there are a
* ton of callers to this function.
*/
@@ -147,7 +145,7 @@ int mconsole_reply_len(struct mc_request *req, const char *str, int total,
len = MIN(total, MCONSOLE_MAX_DATA - 1);
- if(len == total) reply.more = more;
+ if (len == total) reply.more = more;
else reply.more = 1;
memcpy(reply.data, str, len);
@@ -161,9 +159,10 @@ int mconsole_reply_len(struct mc_request *req, const char *str, int total,
n = sendto(req->originating_fd, &reply, len, 0,
(struct sockaddr *) req->origin, req->originlen);
- if(n < 0) return(-errno);
- } while(total > 0);
- return(0);
+ if (n < 0)
+ return -errno;
+ } while (total > 0);
+ return 0;
}
int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
@@ -187,18 +186,18 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len)
int n, err = 0;
lock_notify();
- if(notify_sock < 0){
+ if (notify_sock < 0) {
notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
- if(notify_sock < 0){
+ if (notify_sock < 0) {
err = -errno;
- printk("mconsole_notify - socket failed, errno = %d\n",
- err);
+ printk(UM_KERN_ERR "mconsole_notify - socket failed, "
+ "errno = %d\n", errno);
}
}
unlock_notify();
-
- if(err)
- return(err);
+
+ if (err)
+ return err;
target.sun_family = AF_UNIX;
strcpy(target.sun_path, sock_name);
@@ -212,22 +211,12 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len)
err = 0;
len = sizeof(packet) + packet.len - sizeof(packet.data);
- n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
+ n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
sizeof(target));
- if(n < 0){
+ if (n < 0) {
err = -errno;
- printk("mconsole_notify - sendto failed, errno = %d\n", errno);
+ printk(UM_KERN_ERR "mconsole_notify - sendto failed, "
+ "errno = %d\n", errno);
}
- return(err);
+ return err;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 867666a0233..67b2f55a602 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -9,27 +9,29 @@
*
*/
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
#include <linux/fs.h>
+#include <linux/init.h>
#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mm.h>
#include <asm/uaccess.h>
#include "mem_user.h"
-
+
/* These are set in mmapper_init, which is called at boot time */
static unsigned long mmapper_size;
-static unsigned long p_buf = 0;
-static char *v_buf = NULL;
+static unsigned long p_buf;
+static char *v_buf;
-static ssize_t
-mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t mmapper_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
{
return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size);
}
-static ssize_t
-mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+static ssize_t mmapper_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
{
if (*ppos > mmapper_size)
return -EINVAL;
@@ -39,48 +41,46 @@ mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *p
if (copy_from_user(&v_buf[*ppos], buf, count))
return -EFAULT;
-
+
return count;
}
-static int
-mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
+static int mmapper_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
- return(-ENOIOCTLCMD);
+ return -ENOIOCTLCMD;
}
-static int
-mmapper_mmap(struct file *file, struct vm_area_struct * vma)
+static int mmapper_mmap(struct file *file, struct vm_area_struct *vma)
{
int ret = -EINVAL;
int size;
if (vma->vm_pgoff != 0)
goto out;
-
+
size = vma->vm_end - vma->vm_start;
- if(size > mmapper_size) return(-EFAULT);
+ if (size > mmapper_size)
+ return -EFAULT;
- /* XXX A comment above remap_pfn_range says it should only be
+ /*
+ * XXX A comment above remap_pfn_range says it should only be
* called when the mm semaphore is held
*/
if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size,
- vma->vm_page_prot))
+ vma->vm_page_prot))
goto out;
ret = 0;
out:
return ret;
}
-static int
-mmapper_open(struct inode *inode, struct file *file)
+static int mmapper_open(struct inode *inode, struct file *file)
{
return 0;
}
-static int
-mmapper_release(struct inode *inode, struct file *file)
+static int mmapper_release(struct inode *inode, struct file *file)
{
return 0;
}
@@ -95,7 +95,9 @@ static const struct file_operations mmapper_fops = {
.release = mmapper_release,
};
-/* No locking needed - only used (and modified) by below initcall and exitcall. */
+/*
+ * No locking needed - only used (and modified) by below initcall and exitcall.
+ */
static struct miscdevice mmapper_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mmapper",
@@ -109,13 +111,13 @@ static int __init mmapper_init(void)
printk(KERN_INFO "Mapper v0.1\n");
v_buf = (char *) find_iomem("mmapper", &mmapper_size);
- if(mmapper_size == 0){
+ if (mmapper_size == 0) {
printk(KERN_ERR "mmapper_init - find_iomem failed\n");
goto out;
}
err = misc_register(&mmapper_dev);
- if(err){
+ if (err) {
printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
err);
goto out;
@@ -136,9 +138,3 @@ module_exit(mmapper_exit);
MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
-/*
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index d35d0c1ee7f..8c01fa81a1a 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -1,33 +1,28 @@
/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
-#include "linux/kernel.h"
-#include "linux/netdevice.h"
-#include "linux/rtnetlink.h"
-#include "linux/skbuff.h"
-#include "linux/socket.h"
-#include "linux/spinlock.h"
-#include "linux/module.h"
-#include "linux/init.h"
-#include "linux/etherdevice.h"
-#include "linux/list.h"
-#include "linux/inetdevice.h"
-#include "linux/ctype.h"
-#include "linux/bootmem.h"
-#include "linux/ethtool.h"
-#include "linux/platform_device.h"
-#include "asm/uaccess.h"
-#include "kern_util.h"
-#include "net_kern.h"
-#include "net_user.h"
-#include "mconsole_kern.h"
+#include <linux/bootmem.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/inetdevice.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/rtnetlink.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
#include "init.h"
-#include "irq_user.h"
#include "irq_kern.h"
+#include "irq_user.h"
+#include "mconsole_kern.h"
+#include "net_kern.h"
+#include "net_user.h"
static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
{
@@ -39,6 +34,46 @@ static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
static DEFINE_SPINLOCK(opened_lock);
static LIST_HEAD(opened);
+/*
+ * The drop_skb is used when we can't allocate an skb. The
+ * packet is read into drop_skb in order to get the data off the
+ * connection to the host.
+ * It is reallocated whenever a maximum packet size is seen which is
+ * larger than any seen before. update_drop_skb is called from
+ * eth_configure when a new interface is added.
+ */
+static DEFINE_SPINLOCK(drop_lock);
+static struct sk_buff *drop_skb;
+static int drop_max;
+
+static int update_drop_skb(int max)
+{
+ struct sk_buff *new;
+ unsigned long flags;
+ int err = 0;
+
+ spin_lock_irqsave(&drop_lock, flags);
+
+ if (max <= drop_max)
+ goto out;
+
+ err = -ENOMEM;
+ new = dev_alloc_skb(max);
+ if (new == NULL)
+ goto out;
+
+ skb_put(new, max);
+
+ kfree_skb(drop_skb);
+ drop_skb = new;
+ drop_max = max;
+ err = 0;
+out:
+ spin_unlock_irqrestore(&drop_lock, flags);
+
+ return err;
+}
+
static int uml_net_rx(struct net_device *dev)
{
struct uml_net_private *lp = dev->priv;
@@ -46,16 +81,19 @@ static int uml_net_rx(struct net_device *dev)
struct sk_buff *skb;
/* If we can't allocate memory, try again next round. */
- skb = dev_alloc_skb(dev->mtu);
+ skb = dev_alloc_skb(lp->max_packet);
if (skb == NULL) {
+ drop_skb->dev = dev;
+ /* Read a packet into drop_skb and don't do anything with it. */
+ (*lp->read)(lp->fd, drop_skb, lp);
lp->stats.rx_dropped++;
return 0;
}
skb->dev = dev;
- skb_put(skb, dev->mtu);
+ skb_put(skb, lp->max_packet);
skb_reset_mac_header(skb);
- pkt_len = (*lp->read)(lp->fd, &skb, lp);
+ pkt_len = (*lp->read)(lp->fd, skb, lp);
if (pkt_len > 0) {
skb_trim(skb, pkt_len);
@@ -84,12 +122,12 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
struct uml_net_private *lp = dev->priv;
int err;
- if(!netif_running(dev))
- return(IRQ_NONE);
+ if (!netif_running(dev))
+ return IRQ_NONE;
spin_lock(&lp->lock);
- while((err = uml_net_rx(dev)) > 0) ;
- if(err < 0) {
+ while ((err = uml_net_rx(dev)) > 0) ;
+ if (err < 0) {
printk(KERN_ERR
"Device '%s' read returned %d, shutting it down\n",
dev->name, err);
@@ -115,20 +153,20 @@ static int uml_net_open(struct net_device *dev)
struct uml_net_private *lp = dev->priv;
int err;
- if(lp->fd >= 0){
+ if (lp->fd >= 0) {
err = -ENXIO;
goto out;
}
lp->fd = (*lp->open)(&lp->user);
- if(lp->fd < 0){
+ if (lp->fd < 0) {
err = lp->fd;
goto out;
}
err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
- if(err != 0){
+ if (err != 0) {
printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
err = -ENETUNREACH;
goto out_close;
@@ -141,7 +179,7 @@ static int uml_net_open(struct net_device *dev)
* is full when we get here. In this case, new data is never queued,
* SIGIOs never arrive, and the net never works.
*/
- while((err = uml_net_rx(dev)) > 0) ;
+ while ((err = uml_net_rx(dev)) > 0) ;
spin_lock(&opened_lock);
list_add(&lp->list, &opened);
@@ -149,7 +187,7 @@ static int uml_net_open(struct net_device *dev)
return 0;
out_close:
- if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
+ if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
lp->fd = -1;
out:
return err;
@@ -162,7 +200,7 @@ static int uml_net_close(struct net_device *dev)
netif_stop_queue(dev);
free_irq(dev->irq, dev);
- if(lp->close != NULL)
+ if (lp->close != NULL)
(*lp->close)(lp->fd, &lp->user);
lp->fd = -1;
@@ -183,9 +221,9 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- len = (*lp->write)(lp->fd, &skb, lp);
+ len = (*lp->write)(lp->fd, skb, lp);
- if(len == skb->len) {
+ if (len == skb->len) {
lp->stats.tx_packets++;
lp->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
@@ -194,7 +232,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* this is normally done in the interrupt when tx finishes */
netif_wake_queue(dev);
}
- else if(len == 0){
+ else if (len == 0) {
netif_start_queue(dev);
lp->stats.tx_dropped++;
}
@@ -218,8 +256,10 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
static void uml_net_set_multicast_list(struct net_device *dev)
{
- if (dev->flags & IFF_PROMISC) return;
- else if (dev->mc_count) dev->flags |= IFF_ALLMULTI;
+ if (dev->flags & IFF_PROMISC)
+ return;
+ else if (dev->mc_count)
+ dev->flags |= IFF_ALLMULTI;
else dev->flags &= ~IFF_ALLMULTI;
}
@@ -243,22 +283,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr)
static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
{
- struct uml_net_private *lp = dev->priv;
- int err = 0;
-
- spin_lock_irq(&lp->lock);
-
- new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
- if(new_mtu < 0){
- err = new_mtu;
- goto out;
- }
-
dev->mtu = new_mtu;
- out:
- spin_unlock_irq(&lp->lock);
- return err;
+ return 0;
}
static void uml_net_get_drvinfo(struct net_device *dev,
@@ -288,13 +315,13 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name)
char *end;
int i;
- if(str == NULL)
+ if (str == NULL)
goto random;
- for(i=0;i<6;i++){
+ for (i = 0;i < 6; i++) {
addr[i] = simple_strtoul(str, &end, 16);
- if((end == str) ||
- ((*end != ':') && (*end != ',') && (*end != '\0'))){
+ if ((end == str) ||
+ ((*end != ':') && (*end != ',') && (*end != '\0'))) {
printk(KERN_ERR
"setup_etheraddr: failed to parse '%s' "
"as an ethernet address\n", str);
@@ -349,7 +376,7 @@ static void net_device_release(struct device *dev)
struct net_device *netdev = device->dev;
struct uml_net_private *lp = netdev->priv;
- if(lp->remove != NULL)
+ if (lp->remove != NULL)
(*lp->remove)(&lp->user);
list_del(&device->list);
kfree(device);
@@ -413,7 +440,7 @@ static void eth_configure(int n, void *init, char *mac,
device->pdev.name = DRIVER_NAME;
device->pdev.dev.release = net_device_release;
device->pdev.dev.driver_data = device;
- if(platform_device_register(&device->pdev))
+ if (platform_device_register(&device->pdev))
goto out_free_netdev;
SET_NETDEV_DEV(dev,&device->pdev.dev);
@@ -430,6 +457,7 @@ static void eth_configure(int n, void *init, char *mac,
.dev = dev,
.fd = -1,
.mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
+ .max_packet = transport->user->max_packet,
.protocol = transport->kern->protocol,
.open = transport->user->open,
.close = transport->user->close,
@@ -437,8 +465,7 @@ static void eth_configure(int n, void *init, char *mac,
.read = transport->kern->read,
.write = transport->kern->write,
.add_address = transport->user->add_address,
- .delete_address = transport->user->delete_address,
- .set_mtu = transport->user->set_mtu });
+ .delete_address = transport->user->delete_address });
init_timer(&lp->tl);
spin_lock_init(&lp->lock);
@@ -450,7 +477,7 @@ static void eth_configure(int n, void *init, char *mac,
goto out_unregister;
set_ether_mac(dev, device->mac);
- dev->mtu = transport->user->max_packet;
+ dev->mtu = transport->user->mtu;
dev->open = uml_net_open;
dev->hard_start_xmit = uml_net_start_xmit;
dev->stop = uml_net_close;
@@ -463,6 +490,10 @@ static void eth_configure(int n, void *init, char *mac,
dev->watchdog_timeo = (HZ >> 1);
dev->irq = UM_ETH_IRQ;
+ err = update_drop_skb(lp->max_packet);
+ if (err)
+ goto out_undo_user_init;
+
rtnl_lock();
err = register_netdevice(dev);
rtnl_unlock();
@@ -493,9 +524,9 @@ static struct uml_net *find_device(int n)
struct list_head *ele;
spin_lock(&devices_lock);
- list_for_each(ele, &devices){
+ list_for_each(ele, &devices) {
device = list_entry(ele, struct uml_net, list);
- if(device->index == n)
+ if (device->index == n)
goto out;
}
device = NULL;
@@ -511,19 +542,19 @@ static int eth_parse(char *str, int *index_out, char **str_out,
int n, err = -EINVAL;;
n = simple_strtoul(str, &end, 0);
- if(end == str){
+ if (end == str) {
*error_out = "Bad device number";
return err;
}
str = end;
- if(*str != '='){
+ if (*str != '=') {
*error_out = "Expected '=' after device number";
return err;
}
str++;
- if(find_device(n)){
+ if (find_device(n)) {
*error_out = "Device already configured";
return err;
}
@@ -551,20 +582,20 @@ static int check_transport(struct transport *transport, char *eth, int n,
int len;
len = strlen(transport->name);
- if(strncmp(eth, transport->name, len))
+ if (strncmp(eth, transport->name, len))
return 0;
eth += len;
- if(*eth == ',')
+ if (*eth == ',')
eth++;
- else if(*eth != '\0')
+ else if (*eth != '\0')
return 0;
*init_out = kmalloc(transport->setup_size, GFP_KERNEL);
- if(*init_out == NULL)
+ if (*init_out == NULL)
return 1;
- if(!transport->setup(eth, mac_out, *init_out)){
+ if (!transport->setup(eth, mac_out, *init_out)) {
kfree(*init_out);
*init_out = NULL;
}
@@ -584,13 +615,13 @@ void register_transport(struct transport *new)
list_add(&new->list, &transports);
spin_unlock(&transports_lock);
- list_for_each_safe(ele, next, &eth_cmd_line){
+ list_for_each_safe(ele, next, &eth_cmd_line) {
eth = list_entry(ele, struct eth_init, list);
match = check_transport(new, eth->init, eth->index, &init,
&mac);
- if(!match)
+ if (!match)
continue;
- else if(init != NULL){
+ else if (init != NULL) {
eth_configure(eth->index, init, mac, new);
kfree(init);
}
@@ -607,11 +638,11 @@ static int eth_setup_common(char *str, int index)
int found = 0;
spin_lock(&transports_lock);
- list_for_each(ele, &transports){
+ list_for_each(ele, &transports) {
transport = list_entry(ele, struct transport, list);
- if(!check_transport(transport, str, index, &init, &mac))
+ if (!check_transport(transport, str, index, &init, &mac))
continue;
- if(init != NULL){
+ if (init != NULL) {
eth_configure(index, init, mac, transport);
kfree(init);
}
@@ -630,15 +661,15 @@ static int __init eth_setup(char *str)
int n, err;
err = eth_parse(str, &n, &str, &error);
- if(err){
+ if (err) {
printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n",
str, error);
return 1;
}
new = alloc_bootmem(sizeof(*new));
- if (new == NULL){
- printk("eth_init : alloc_bootmem failed\n");
+ if (new == NULL) {
+ printk(KERN_ERR "eth_init : alloc_bootmem failed\n");
return 1;
}
@@ -661,36 +692,36 @@ static int net_config(char *str, char **error_out)
int n, err;
err = eth_parse(str, &n, &str, error_out);
- if(err)
+ if (err)
return err;
/* This string is broken up and the pieces used by the underlying
* driver. So, it is freed only if eth_setup_common fails.
*/
str = kstrdup(str, GFP_KERNEL);
- if(str == NULL){
+ if (str == NULL) {
*error_out = "net_config failed to strdup string";
return -ENOMEM;
}
err = !eth_setup_common(str, n);
- if(err)
+ if (err)
kfree(str);
- return(err);
+ return err;
}
static int net_id(char **str, int *start_out, int *end_out)
{
- char *end;
- int n;
+ char *end;
+ int n;
n = simple_strtoul(*str, &end, 0);
- if((*end != '\0') || (end == *str))
+ if ((*end != '\0') || (end == *str))
return -1;
- *start_out = n;
- *end_out = n;
- *str = end;
- return n;
+ *start_out = n;
+ *end_out = n;
+ *str = end;
+ return n;
}
static int net_remove(int n, char **error_out)
@@ -700,12 +731,12 @@ static int net_remove(int n, char **error_out)
struct uml_net_private *lp;
device = find_device(n);
- if(device == NULL)
+ if (device == NULL)
return -ENODEV;
dev = device->dev;
lp = dev->priv;
- if(lp->fd > 0)
+ if (lp->fd > 0)
return -EBUSY;
unregister_netdev(dev);
platform_device_unregister(&device->pdev);
@@ -731,13 +762,13 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
void (*proc)(unsigned char *, unsigned char *, void *);
unsigned char addr_buf[4], netmask_buf[4];
- if(dev->open != uml_net_open)
+ if (dev->open != uml_net_open)
return NOTIFY_DONE;
lp = dev->priv;
proc = NULL;
- switch (event){
+ switch (event) {
case NETDEV_UP:
proc = lp->add_address;
break;
@@ -745,7 +776,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
proc = lp->delete_address;
break;
}
- if(proc != NULL){
+ if (proc != NULL) {
memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
(*proc)(addr_buf, netmask_buf, &lp->user);
@@ -773,13 +804,13 @@ static int uml_net_init(void)
* addresses which have already been set up get handled properly.
*/
spin_lock(&opened_lock);
- list_for_each(ele, &opened){
+ list_for_each(ele, &opened) {
lp = list_entry(ele, struct uml_net_private, list);
ip = lp->dev->ip_ptr;
- if(ip == NULL)
+ if (ip == NULL)
continue;
in = ip->ifa_list;
- while(in != NULL){
+ while (in != NULL) {
uml_inetaddr_event(NULL, NETDEV_UP, in);
in = in->ifa_next;
}
@@ -797,12 +828,12 @@ static void close_devices(void)
struct uml_net_private *lp;
spin_lock(&opened_lock);
- list_for_each(ele, &opened){
+ list_for_each(ele, &opened) {
lp = list_entry(ele, struct uml_net_private, list);
free_irq(lp->dev->irq, lp->dev);
- if((lp->close != NULL) && (lp->fd >= 0))
+ if ((lp->close != NULL) && (lp->fd >= 0))
(*lp->close)(lp->fd, &lp->user);
- if(lp->remove != NULL)
+ if (lp->remove != NULL)
(*lp->remove)(&lp->user);
}
spin_unlock(&opened_lock);
@@ -810,19 +841,6 @@ static void close_devices(void)
__uml_exitcall(close_devices);
-struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
-{
- if((skb != NULL) && (skb_tailroom(skb) < extra)){
- struct sk_buff *skb2;
-
- skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
- dev_kfree_skb(skb);
- skb = skb2;
- }
- if(skb != NULL) skb_put(skb, extra);
- return(skb);
-}
-
void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
void *),
void *arg)
@@ -832,9 +850,9 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
struct in_ifaddr *in;
unsigned char address[4], netmask[4];
- if(ip == NULL) return;
+ if (ip == NULL) return;
in = ip->ifa_list;
- while(in != NULL){
+ while (in != NULL) {
memcpy(address, &in->ifa_address, sizeof(address));
memcpy(netmask, &in->ifa_mask, sizeof(netmask));
(*cb)(address, netmask, arg);
@@ -849,15 +867,15 @@ int dev_netmask(void *d, void *m)
struct in_ifaddr *in;
__be32 *mask_out = m;
- if(ip == NULL)
- return(1);
+ if (ip == NULL)
+ return 1;
in = ip->ifa_list;
- if(in == NULL)
- return(1);
+ if (in == NULL)
+ return 1;
*mask_out = in->ifa_mask;
- return(0);
+ return 0;
}
void *get_output_buffer(int *len_out)
@@ -865,7 +883,7 @@ void *get_output_buffer(int *len_out)
void *ret;
ret = (void *) __get_free_pages(GFP_KERNEL, 0);
- if(ret) *len_out = PAGE_SIZE;
+ if (ret) *len_out = PAGE_SIZE;
else *len_out = 0;
return ret;
}
@@ -881,16 +899,16 @@ int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
char *remain;
remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
- if(remain != NULL){
- printk("tap_setup_common - Extra garbage on specification : "
- "'%s'\n", remain);
- return(1);
+ if (remain != NULL) {
+ printk(KERN_ERR "tap_setup_common - Extra garbage on "
+ "specification : '%s'\n", remain);
+ return 1;
}
- return(0);
+ return 0;
}
unsigned short eth_protocol(struct sk_buff *skb)
{
- return(eth_type_trans(skb, skb->dev));
+ return eth_type_trans(skb, skb->dev);
}
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index da946e3e1bf..90d7f2e8ead 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -1,34 +1,32 @@
-/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stddef.h>
-#include <stdarg.h>
-#include <unistd.h>
#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
#include <errno.h>
-#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
-#include <sys/time.h>
-#include "user.h"
-#include "kern_util.h"
#include "net_user.h"
+#include "kern_constants.h"
#include "os.h"
#include "um_malloc.h"
-#include "kern_constants.h"
+#include "user.h"
int tap_open_common(void *dev, char *gate_addr)
{
int tap_addr[4];
- if(gate_addr == NULL)
+ if (gate_addr == NULL)
return 0;
- if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
- &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
- printk("Invalid tap IP address - '%s'\n", gate_addr);
+ if (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
+ &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4) {
+ printk(UM_KERN_ERR "Invalid tap IP address - '%s'\n",
+ gate_addr);
return -EINVAL;
}
return 0;
@@ -38,15 +36,15 @@ void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
{
int tap_addr[4];
- if((gate_addr != NULL) &&
- (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
- &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
- (eth_addr[0] == tap_addr[0]) &&
- (eth_addr[1] == tap_addr[1]) &&
- (eth_addr[2] == tap_addr[2]) &&
- (eth_addr[3] == tap_addr[3])){
- printk("The tap IP address and the UML eth IP address"
- " must be different\n");
+ if ((gate_addr != NULL) &&
+ (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
+ &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
+ (eth_addr[0] == tap_addr[0]) &&
+ (eth_addr[1] == tap_addr[1]) &&
+ (eth_addr[2] == tap_addr[2]) &&
+ (eth_addr[3] == tap_addr[3])) {
+ printk(UM_KERN_ERR "The tap IP address and the UML eth IP "
+ "address must be different\n");
}
}
@@ -57,24 +55,28 @@ void read_output(int fd, char *output, int len)
char c;
char *str;
- if(output == NULL){
+ if (output == NULL) {
output = &c;
len = sizeof(c);
}
-
+
*output = '\0';
- ret = os_read_file(fd, &remain, sizeof(remain));
+ ret = read(fd, &remain, sizeof(remain));
if (ret != sizeof(remain)) {
+ if (ret < 0)
+ ret = -errno;
expected = sizeof(remain);
str = "length";
goto err;
}
- while(remain != 0){
+ while (remain != 0) {
expected = (remain < len) ? remain : len;
- ret = os_read_file(fd, output, expected);
+ ret = read(fd, output, expected);
if (ret != expected) {
+ if (ret < 0)
+ ret = -errno;
str = "data";
goto err;
}
@@ -85,20 +87,22 @@ void read_output(int fd, char *output, int len)
err:
if (ret < 0)
- printk("read_output - read of %s failed, errno = %d\n", str, -ret);
+ printk(UM_KERN_ERR "read_output - read of %s failed, "
+ "errno = %d\n", str, -ret);
else
- printk("read_output - read of %s failed, read only %d of %d bytes\n", str, ret, expected);
+ printk(UM_KERN_ERR "read_output - read of %s failed, read only "
+ "%d of %d bytes\n", str, ret, expected);
}
int net_read(int fd, void *buf, int len)
{
int n;
- n = os_read_file(fd, buf, len);
+ n = read(fd, buf, len);
- if(n == -EAGAIN)
+ if ((n < 0) && (errno == EAGAIN))
return 0;
- else if(n == 0)
+ else if (n == 0)
return -ENOTCONN;
return n;
}
@@ -108,12 +112,12 @@ int net_recvfrom(int fd, void *buf, int len)
int n;
CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL));
- if(n < 0){
- if(errno == EAGAIN)
+ if (n < 0) {
+ if (errno == EAGAIN)
return 0;
return -errno;
}
- else if(n == 0)
+ else if (n == 0)
return -ENOTCONN;
return n;
}
@@ -122,11 +126,11 @@ int net_write(int fd, void *buf, int len)
{
int n;
- n = os_write_file(fd, buf, len);
+ n = write(fd, buf, len);
- if(n == -EAGAIN)
+ if ((n < 0) && (errno == EAGAIN))
return 0;
- else if(n == 0)
+ else if (n == 0)
return -ENOTCONN;
return n;
}
@@ -136,12 +140,12 @@ int net_send(int fd, void *buf, int len)
int n;
CATCH_EINTR(n = send(fd, buf, len, 0));
- if(n < 0){
- if(errno == EAGAIN)
+ if (n < 0) {
+ if (errno == EAGAIN)
return 0;
return -errno;
}
- else if(n == 0)
+ else if (n == 0)
return -ENOTCONN;
return n;
}
@@ -152,12 +156,12 @@ int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
sock_len));
- if(n < 0){
- if(errno == EAGAIN)
+ if (n < 0) {
+ if (errno == EAGAIN)
return 0;
return -errno;
}
- else if(n == 0)
+ else if (n == 0)
return -ENOTCONN;
return n;
}
@@ -171,7 +175,7 @@ static void change_pre_exec(void *arg)
{
struct change_pre_exec_data *data = arg;
- os_close_file(data->close_me);
+ close(data->close_me);
dup2(data->stdout, 1);
}
@@ -181,8 +185,9 @@ static int change_tramp(char **argv, char *output, int output_len)
struct change_pre_exec_data pe_data;
err = os_pipe(fds, 1, 0);
- if(err < 0){
- printk("change_tramp - pipe failed, err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n",
+ -err);
return err;
}
pe_data.close_me = fds[0];
@@ -192,8 +197,8 @@ static int change_tramp(char **argv, char *output, int output_len)
if (pid > 0) /* Avoid hang as we won't get data in failure case. */
read_output(fds[0], output, output_len);
- os_close_file(fds[0]);
- os_close_file(fds[1]);
+ close(fds[0]);
+ close(fds[1]);
if (pid > 0)
CATCH_EINTR(err = waitpid(pid, NULL, 0));
@@ -206,25 +211,26 @@ static void change(char *dev, char *what, unsigned char *addr,
char addr_buf[sizeof("255.255.255.255\0")];
char netmask_buf[sizeof("255.255.255.255\0")];
char version[sizeof("nnnnn\0")];
- char *argv[] = { "uml_net", version, what, dev, addr_buf,
+ char *argv[] = { "uml_net", version, what, dev, addr_buf,
netmask_buf, NULL };
char *output;
int output_len, pid;
sprintf(version, "%d", UML_NET_VERSION);
sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
- sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
+ sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
netmask[2], netmask[3]);
output_len = UM_KERN_PAGE_SIZE;
output = kmalloc(output_len, UM_GFP_KERNEL);
- if(output == NULL)
- printk("change : failed to allocate output buffer\n");
+ if (output == NULL)
+ printk(UM_KERN_ERR "change : failed to allocate output "
+ "buffer\n");
pid = change_tramp(argv, output, output_len);
- if(pid < 0) return;
+ if (pid < 0) return;
- if(output != NULL){
+ if (output != NULL) {
printk("%s", output);
kfree(output);
}
@@ -246,13 +252,13 @@ char *split_if_spec(char *str, ...)
va_list ap;
va_start(ap, str);
- while((arg = va_arg(ap, char **)) != NULL){
- if(*str == '\0')
+ while ((arg = va_arg(ap, char **)) != NULL) {
+ if (*str == '\0')
return NULL;
end = strchr(str, ',');
- if(end != str)
+ if (end != str)
*arg = str;
- if(end == NULL)
+ if (end == NULL)
return NULL;
*end++ = '\0';
str = end;
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 9016c68beee..21ad3d7932b 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -1,10 +1,11 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
-#include <stdlib.h>
+#include <stddef.h>
#include <errno.h>
+#include <fcntl.h>
#include "chan_user.h"
#include "os.h"
@@ -13,19 +14,23 @@ static int null_chan;
static void *null_init(char *str, int device, const struct chan_opts *opts)
{
- return(&null_chan);
+ return &null_chan;
}
static int null_open(int input, int output, int primary, void *d,
char **dev_out)
{
+ int fd;
+
*dev_out = NULL;
- return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0));
+
+ fd = open(DEV_NULL, O_RDWR);
+ return (fd < 0) ? -errno : fd;
}
static int null_read(int fd, char *c_out, void *unused)
{
- return(-ENODEV);
+ return -ENODEV;
}
static void null_free(void *data)
@@ -44,14 +49,3 @@ const struct chan_ops null_ops = {
.free = null_free,
.winch = 0,
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index c329931673d..3a750dd39be 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -1,13 +1,11 @@
/*
- * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL.
*/
#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
+#include <linux/netdevice.h>
#include "net_kern.h"
-#include "net_user.h"
#include "pcap_user.h"
struct pcap_init {
@@ -33,19 +31,14 @@ void pcap_init(struct net_device *dev, void *data)
printk("pcap backend, host interface %s\n", ppri->host_if);
}
-static int pcap_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if(*skb == NULL)
- return -ENOMEM;
-
- return pcap_user_read(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER,
+ return pcap_user_read(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER,
(struct pcap_data *) &lp->user);
}
-static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
return -EPERM;
}
@@ -71,28 +64,29 @@ int pcap_setup(char *str, char **mac_out, void *data)
remain = split_if_spec(str, &host_if, &init->filter,
&options[0], &options[1], mac_out, NULL);
- if(remain != NULL){
+ if (remain != NULL) {
printk(KERN_ERR "pcap_setup - Extra garbage on "
"specification : '%s'\n", remain);
return 0;
}
- if(host_if != NULL)
+ if (host_if != NULL)
init->host_if = host_if;
- for(i = 0; i < ARRAY_SIZE(options); i++){
- if(options[i] == NULL)
+ for (i = 0; i < ARRAY_SIZE(options); i++) {
+ if (options[i] == NULL)
continue;
- if(!strcmp(options[i], "promisc"))
+ if (!strcmp(options[i], "promisc"))
init->promisc = 1;
- else if(!strcmp(options[i], "nopromisc"))
+ else if (!strcmp(options[i], "nopromisc"))
init->promisc = 0;
- else if(!strcmp(options[i], "optimize"))
+ else if (!strcmp(options[i], "optimize"))
init->optimize = 1;
- else if(!strcmp(options[i], "nooptimize"))
+ else if (!strcmp(options[i], "nooptimize"))
init->optimize = 0;
else {
- printk("pcap_setup : bad option - '%s'\n", options[i]);
+ printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
+ options[i]);
return 0;
}
}
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 1316456e2a2..e9809356c53 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -1,21 +1,17 @@
/*
- * Copyright (C) 2002 Jeff Dike <jdike@karaya.com>
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL.
*/
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
#include <errno.h>
#include <pcap.h>
+#include <string.h>
#include <asm/types.h>
#include "net_user.h"
#include "pcap_user.h"
-#include "user.h"
-#include "um_malloc.h"
#include "kern_constants.h"
-
-#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
+#include "um_malloc.h"
+#include "user.h"
#define PCAP_FD(p) (*(int *)(p))
@@ -25,8 +21,9 @@ static int pcap_user_init(void *data, void *dev)
pcap_t *p;
char errors[PCAP_ERRBUF_SIZE];
- p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
- if(p == NULL){
+ p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
+ pri->promisc, 0, errors);
+ if (p == NULL) {
printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
"'%s'\n", errors);
return -EINVAL;
@@ -43,50 +40,55 @@ static int pcap_open(void *data)
__u32 netmask;
int err;
- if(pri->pcap == NULL)
+ if (pri->pcap == NULL)
return -ENODEV;
- if(pri->filter != NULL){
+ if (pri->filter != NULL) {
err = dev_netmask(pri->dev, &netmask);
- if(err < 0){
+ if (err < 0) {
printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
return -EIO;
}
- pri->compiled = kmalloc(sizeof(struct bpf_program), UM_GFP_KERNEL);
- if(pri->compiled == NULL){
+ pri->compiled = kmalloc(sizeof(struct bpf_program),
+ UM_GFP_KERNEL);
+ if (pri->compiled == NULL) {
printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
return -ENOMEM;
}
- err = pcap_compile(pri->pcap,
- (struct bpf_program *) pri->compiled,
+ err = pcap_compile(pri->pcap,
+ (struct bpf_program *) pri->compiled,
pri->filter, pri->optimize, netmask);
- if(err < 0){
+ if (err < 0) {
printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
"'%s'\n", pcap_geterr(pri->pcap));
- return -EIO;
+ goto out;
}
err = pcap_setfilter(pri->pcap, pri->compiled);
- if(err < 0){
+ if (err < 0) {
printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
"failed - '%s'\n", pcap_geterr(pri->pcap));
- return -EIO;
+ goto out;
}
}
return PCAP_FD(pri->pcap);
+
+ out:
+ kfree(pri->compiled);
+ return -EIO;
}
static void pcap_remove(void *data)
{
struct pcap_data *pri = data;
- if(pri->compiled != NULL)
+ if (pri->compiled != NULL)
pcap_freecode(pri->compiled);
- if(pri->pcap != NULL)
+ if (pri->pcap != NULL)
pcap_close(pri->pcap);
}
@@ -95,7 +97,7 @@ struct pcap_handler_data {
int len;
};
-static void handler(u_char *data, const struct pcap_pkthdr *header,
+static void handler(u_char *data, const struct pcap_pkthdr *header,
const u_char *packet)
{
int len;
@@ -115,12 +117,12 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
int n;
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
- if(n < 0){
+ if (n < 0) {
printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
pcap_geterr(pri->pcap));
return -EIO;
}
- else if(n == 0)
+ else if (n == 0)
return 0;
return hdata.len;
}
@@ -130,8 +132,8 @@ const struct net_user_info pcap_user_info = {
.open = pcap_open,
.close = NULL,
.remove = pcap_remove,
- .set_mtu = NULL,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = MAX_PACKET - ETH_HEADER_OTHER
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 1c8efd95c42..330543b3129 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -1,24 +1,16 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
-#include "linux/list.h"
-#include "linux/sched.h"
-#include "linux/slab.h"
+#include "linux/completion.h"
#include "linux/interrupt.h"
-#include "linux/spinlock.h"
-#include "linux/errno.h"
+#include "linux/list.h"
#include "asm/atomic.h"
-#include "asm/semaphore.h"
-#include "asm/errno.h"
-#include "kern_util.h"
-#include "kern.h"
-#include "irq_user.h"
-#include "irq_kern.h"
-#include "port.h"
#include "init.h"
+#include "irq_kern.h"
#include "os.h"
+#include "port.h"
struct port_list {
struct list_head list;
@@ -53,8 +45,8 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
int fd;
fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
- if(fd < 0){
- if(fd == -EAGAIN)
+ if (fd < 0) {
+ if (fd == -EAGAIN)
return IRQ_NONE;
printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
@@ -81,18 +73,18 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
static int port_accept(struct port_list *port)
{
struct connection *conn;
- int fd, socket[2], pid, ret = 0;
+ int fd, socket[2], pid;
fd = port_connection(port->fd, socket, &pid);
- if(fd < 0){
- if(fd != -EAGAIN)
+ if (fd < 0) {
+ if (fd != -EAGAIN)
printk(KERN_ERR "port_accept : port_connection "
"returned %d\n", -fd);
goto out;
}
conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
- if(conn == NULL){
+ if (conn == NULL) {
printk(KERN_ERR "port_accept : failed to allocate "
"connection\n");
goto out_close;
@@ -104,17 +96,17 @@ static int port_accept(struct port_list *port)
.telnetd_pid = pid,
.port = port });
- if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
+ if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "telnetd", conn)){
+ "telnetd", conn)) {
printk(KERN_ERR "port_accept : failed to get IRQ for "
"telnetd\n");
goto out_free;
}
- if(atomic_read(&port->wait_count) == 0){
+ if (atomic_read(&port->wait_count) == 0) {
os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG));
- printk("No one waiting for port\n");
+ printk(KERN_ERR "No one waiting for port\n");
}
list_add(&conn->list, &port->pending);
return 1;
@@ -123,28 +115,29 @@ static int port_accept(struct port_list *port)
kfree(conn);
out_close:
os_close_file(fd);
- if(pid != -1)
- os_kill_process(pid, 1);
+ os_kill_process(pid, 1);
out:
- return ret;
+ return 0;
}
static DECLARE_MUTEX(ports_sem);
static LIST_HEAD(ports);
-void port_work_proc(struct work_struct *unused)
+static void port_work_proc(struct work_struct *unused)
{
struct port_list *port;
struct list_head *ele;
unsigned long flags;
local_irq_save(flags);
- list_for_each(ele, &ports){
+ list_for_each(ele, &ports) {
port = list_entry(ele, struct port_list, list);
- if(!port->has_connection)
+ if (!port->has_connection)
continue;
+
reactivate_fd(port->fd, ACCEPT_IRQ);
- while(port_accept(port)) ;
+ while (port_accept(port))
+ ;
port->has_connection = 0;
}
local_irq_restore(flags);
@@ -169,25 +162,27 @@ void *port_data(int port_num)
int fd;
down(&ports_sem);
- list_for_each(ele, &ports){
+ list_for_each(ele, &ports) {
port = list_entry(ele, struct port_list, list);
- if(port->port == port_num) goto found;
+ if (port->port == port_num)
+ goto found;
}
port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
- if(port == NULL){
+ if (port == NULL) {
printk(KERN_ERR "Allocation of port list failed\n");
goto out;
}
fd = port_listen_fd(port_num);
- if(fd < 0){
+ if (fd < 0) {
printk(KERN_ERR "binding to port %d failed, errno = %d\n",
port_num, -fd);
goto out_free;
}
- if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
+
+ if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "port", port)){
+ "port", port)) {
printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
goto out_close;
}
@@ -206,7 +201,7 @@ void *port_data(int port_num)
found:
dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
- if(dev == NULL){
+ if (dev == NULL) {
printk(KERN_ERR "Allocation of port device entry failed\n");
goto out;
}
@@ -216,10 +211,10 @@ void *port_data(int port_num)
.telnetd_pid = -1 });
goto out;
- out_free:
- kfree(port);
out_close:
os_close_file(fd);
+ out_free:
+ kfree(port);
out:
up(&ports_sem);
return dev;
@@ -233,9 +228,9 @@ int port_wait(void *data)
int fd;
atomic_inc(&port->wait_count);
- while(1){
+ while (1) {
fd = -ERESTARTSYS;
- if(wait_for_completion_interruptible(&port->done))
+ if (wait_for_completion_interruptible(&port->done))
goto out;
spin_lock(&port->lock);
@@ -258,7 +253,8 @@ int port_wait(void *data)
*/
free_irq(TELNETD_IRQ, conn);
- if(conn->fd >= 0) break;
+ if (conn->fd >= 0)
+ break;
os_close_file(conn->fd);
kfree(conn);
}
@@ -276,9 +272,9 @@ void port_remove_dev(void *d)
{
struct port_dev *dev = d;
- if(dev->helper_pid != -1)
+ if (dev->helper_pid != -1)
os_kill_process(dev->helper_pid, 0);
- if(dev->telnetd_pid != -1)
+ if (dev->telnetd_pid != -1)
os_kill_process(dev->telnetd_pid, 1);
dev->helper_pid = -1;
dev->telnetd_pid = -1;
@@ -297,7 +293,7 @@ static void free_port(void)
struct list_head *ele;
struct port_list *port;
- list_for_each(ele, &ports){
+ list_for_each(ele, &ports) {
port = list_entry(ele, struct port_list, list);
free_irq_by_fd(port->fd);
os_close_file(port->fd);
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index c799b00012c..addd7590265 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -1,24 +1,20 @@
/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
#include <stdio.h>
-#include <stddef.h>
#include <stdlib.h>
-#include <string.h>
#include <errno.h>
-#include <unistd.h>
#include <termios.h>
-#include <sys/socket.h>
-#include <sys/un.h>
+#include <unistd.h>
#include <netinet/in.h>
-#include "kern_util.h"
-#include "user.h"
#include "chan_user.h"
-#include "port.h"
+#include "kern_constants.h"
#include "os.h"
+#include "port.h"
#include "um_malloc.h"
+#include "user.h"
struct port_chan {
int raw;
@@ -34,24 +30,25 @@ static void *port_init(char *str, int device, const struct chan_opts *opts)
char *end;
int port;
- if(*str != ':'){
- printk("port_init : channel type 'port' must specify a "
- "port number\n");
+ if (*str != ':') {
+ printk(UM_KERN_ERR "port_init : channel type 'port' must "
+ "specify a port number\n");
return NULL;
}
str++;
port = strtoul(str, &end, 0);
- if((*end != '\0') || (end == str)){
- printk("port_init : couldn't parse port '%s'\n", str);
+ if ((*end != '\0') || (end == str)) {
+ printk(UM_KERN_ERR "port_init : couldn't parse port '%s'\n",
+ str);
return NULL;
}
kern_data = port_data(port);
- if(kern_data == NULL)
+ if (kern_data == NULL)
return NULL;
data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
- if(data == NULL)
+ if (data == NULL)
goto err;
*data = ((struct port_chan) { .raw = opts->raw,
@@ -79,13 +76,13 @@ static int port_open(int input, int output, int primary, void *d,
int fd, err;
fd = port_wait(data->kernel_data);
- if((fd >= 0) && data->raw){
+ if ((fd >= 0) && data->raw) {
CATCH_EINTR(err = tcgetattr(fd, &data->tt));
- if(err)
+ if (err)
return err;
err = raw(fd);
- if(err)
+ if (err)
return err;
}
*dev_out = data->dev;
@@ -119,11 +116,11 @@ int port_listen_fd(int port)
int fd, err, arg;
fd = socket(PF_INET, SOCK_STREAM, 0);
- if(fd == -1)
+ if (fd == -1)
return -errno;
arg = 1;
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) {
err = -errno;
goto out;
}
@@ -131,23 +128,23 @@ int port_listen_fd(int port)
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
- if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
err = -errno;
goto out;
}
- if(listen(fd, 1) < 0){
+ if (listen(fd, 1) < 0) {
err = -errno;
goto out;
}
err = os_set_fd_block(fd, 0);
- if(err < 0)
+ if (err < 0)
goto out;
return fd;
out:
- os_close_file(fd);
+ close(fd);
return err;
}
@@ -163,10 +160,10 @@ void port_pre_exec(void *arg)
dup2(data->sock_fd, 0);
dup2(data->sock_fd, 1);
dup2(data->sock_fd, 2);
- os_close_file(data->sock_fd);
+ close(data->sock_fd);
dup2(data->pipe_fd, 3);
- os_shutdown_socket(3, 1, 0);
- os_close_file(data->pipe_fd);
+ shutdown(3, SHUT_RD);
+ close(data->pipe_fd);
}
int port_connection(int fd, int *socket, int *pid_out)
@@ -176,12 +173,12 @@ int port_connection(int fd, int *socket, int *pid_out)
"/usr/lib/uml/port-helper", NULL };
struct port_pre_exec_data data;
- new = os_accept_connection(fd);
- if(new < 0)
- return new;
+ new = accept(fd, NULL, 0);
+ if (new < 0)
+ return -errno;
err = os_pipe(socket, 0, 0);
- if(err < 0)
+ if (err < 0)
goto out_close;
data = ((struct port_pre_exec_data)
@@ -189,18 +186,18 @@ int port_connection(int fd, int *socket, int *pid_out)
.pipe_fd = socket[1] });
err = run_helper(port_pre_exec, &data, argv);
- if(err < 0)
+ if (err < 0)
goto out_shutdown;
*pid_out = err;
return new;
out_shutdown:
- os_shutdown_socket(socket[0], 1, 1);
- os_close_file(socket[0]);
- os_shutdown_socket(socket[1], 1, 1);
- os_close_file(socket[1]);
+ shutdown(socket[0], SHUT_RDWR);
+ close(socket[0]);
+ shutdown(socket[1], SHUT_RDWR);
+ close(socket[1]);
out_close:
- os_close_file(new);
+ close(new);
return err;
}
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 1e3fd619a83..49c79dda604 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -6,16 +6,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
#include <termios.h>
#include <sys/stat.h>
#include "chan_user.h"
-#include "os.h"
-#include "user.h"
#include "kern_constants.h"
+#include "os.h"
#include "um_malloc.h"
+#include "user.h"
struct pty_chan {
void (*announce)(char *dev_name, int dev);
@@ -33,7 +33,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
if (data == NULL)
return NULL;
- *data = ((struct pty_chan) { .announce = opts->announce,
+ *data = ((struct pty_chan) { .announce = opts->announce,
.dev = device,
.raw = opts->raw });
return data;
@@ -56,11 +56,11 @@ static int pts_open(int input, int output, int primary, void *d,
if (data->raw) {
CATCH_EINTR(err = tcgetattr(fd, &data->tt));
if (err)
- return err;
+ goto out_close;
err = raw(fd);
if (err)
- return err;
+ goto out_close;
}
dev = ptsname(fd);
@@ -71,6 +71,10 @@ static int pts_open(int input, int output, int primary, void *d,
(*data->announce)(dev, data->dev);
return fd;
+
+out_close:
+ close(fd);
+ return err;
}
static int getmaster(char *line)
@@ -97,7 +101,7 @@ static int getmaster(char *line)
*tp = 't';
err = access(line, R_OK | W_OK);
*tp = 'p';
- if(!err)
+ if (!err)
return master;
close(master);
}
@@ -119,12 +123,14 @@ static int pty_open(int input, int output, int primary, void *d,
if (fd < 0)
return fd;
- if(data->raw){
+ if (data->raw) {
err = raw(fd);
- if (err)
+ if (err) {
+ close(fd);
return err;
+ }
}
-
+
if (data->announce)
(*data->announce)(dev, data->dev);
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 125c44f7763..6b4a0f9e38d 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -1,11 +1,12 @@
-#include "linux/kernel.h"
-#include "linux/stddef.h"
-#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/if_arp.h"
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL.
+ */
+
+#include <linux/if_arp.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
#include "net_kern.h"
-#include "net_user.h"
-#include "kern.h"
#include "slip.h"
struct slip_init {
@@ -30,10 +31,8 @@ void slip_init(struct net_device *dev, void *data)
slip_proto_init(&spri->slip);
dev->init = NULL;
- dev->header_cache_update = NULL;
- dev->hard_header_cache = NULL;
- dev->hard_header = NULL;
dev->hard_header_len = 0;
+ dev->header_ops = NULL;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 256;
@@ -43,21 +42,19 @@ void slip_init(struct net_device *dev, void *data)
static unsigned short slip_protocol(struct sk_buff *skbuff)
{
- return(htons(ETH_P_IP));
+ return htons(ETH_P_IP);
}
-static int slip_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return(slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
- (struct slip_data *) &lp->user));
+ return slip_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
+ (struct slip_data *) &lp->user);
}
-static int slip_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return(slip_user_write(fd, (*skb)->data, (*skb)->len,
- (struct slip_data *) &lp->user));
+ return slip_user_write(fd, skb->data, skb->len,
+ (struct slip_data *) &lp->user);
}
const struct net_kern_info slip_kern_info = {
@@ -71,12 +68,11 @@ static int slip_setup(char *str, char **mac_out, void *data)
{
struct slip_init *init = data;
- *init = ((struct slip_init)
- { .gate_addr = NULL });
+ *init = ((struct slip_init) { .gate_addr = NULL });
- if(str[0] != '\0')
+ if (str[0] != '\0')
init->gate_addr = str;
- return(1);
+ return 1;
}
static struct transport slip_transport = {
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index c0b73c28cff..5f06204d687 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -1,21 +1,22 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <stddef.h>
-#include <sched.h>
-#include <string.h>
#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
#include <sys/termios.h>
#include <sys/wait.h>
-#include <sys/signal.h>
-#include "kern_util.h"
-#include "user.h"
+#include "kern_constants.h"
#include "net_user.h"
-#include "slip.h"
-#include "slip_common.h"
#include "os.h"
+#include "slip.h"
#include "um_malloc.h"
-#include "kern_constants.h"
+#include "user.h"
static int slip_user_init(void *data, void *dev)
{
@@ -31,8 +32,9 @@ static int set_up_tty(int fd)
struct termios tios;
if (tcgetattr(fd, &tios) < 0) {
- printk("could not get initial terminal attributes\n");
- return(-1);
+ printk(UM_KERN_ERR "could not get initial terminal "
+ "attributes\n");
+ return -1;
}
tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
@@ -48,10 +50,10 @@ static int set_up_tty(int fd)
cfsetispeed(&tios, B38400);
if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
- printk("failed to set terminal attributes\n");
- return(-1);
+ printk(UM_KERN_ERR "failed to set terminal attributes\n");
+ return -1;
}
- return(0);
+ return 0;
}
struct slip_pre_exec_data {
@@ -64,9 +66,11 @@ static void slip_pre_exec(void *arg)
{
struct slip_pre_exec_data *data = arg;
- if(data->stdin >= 0) dup2(data->stdin, 0);
+ if (data->stdin >= 0)
+ dup2(data->stdin, 0);
dup2(data->stdout, 1);
- if(data->close_me >= 0) os_close_file(data->close_me);
+ if (data->close_me >= 0)
+ close(data->close_me);
}
static int slip_tramp(char **argv, int fd)
@@ -76,8 +80,9 @@ static int slip_tramp(char **argv, int fd)
int status, pid, fds[2], err, output_len;
err = os_pipe(fds, 1, 0);
- if(err < 0){
- printk("slip_tramp : pipe failed, err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
+ -err);
goto out;
}
@@ -86,41 +91,42 @@ static int slip_tramp(char **argv, int fd)
pe_data.stdout = fds[1];
pe_data.close_me = fds[0];
err = run_helper(slip_pre_exec, &pe_data, argv);
- if(err < 0)
+ if (err < 0)
goto out_close;
pid = err;
output_len = UM_KERN_PAGE_SIZE;
output = kmalloc(output_len, UM_GFP_KERNEL);
- if(output == NULL){
- printk("slip_tramp : failed to allocate output buffer\n");
+ if (output == NULL) {
+ printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
+ "buffer\n");
os_kill_process(pid, 1);
err = -ENOMEM;
goto out_free;
}
- os_close_file(fds[1]);
+ close(fds[1]);
read_output(fds[0], output, output_len);
printk("%s", output);
CATCH_EINTR(err = waitpid(pid, &status, 0));
- if(err < 0)
+ if (err < 0)
err = errno;
- else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
- printk("'%s' didn't exit with status 0\n", argv[0]);
+ else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
+ printk(UM_KERN_ERR "'%s' didn't exit with status 0\n", argv[0]);
err = -EINVAL;
}
else err = 0;
- os_close_file(fds[0]);
+ close(fds[0]);
out_free:
kfree(output);
return err;
out_close:
- os_close_file(fds[0]);
- os_close_file(fds[1]);
+ close(fds[0]);
+ close(fds[1]);
out:
return err;
}
@@ -130,60 +136,64 @@ static int slip_open(void *data)
struct slip_data *pri = data;
char version_buf[sizeof("nnnnn\0")];
char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
- char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
+ char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
NULL };
int sfd, mfd, err;
err = get_pty();
- if(err < 0){
- printk("slip-open : Failed to open pty, err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
+ -err);
goto out;
}
mfd = err;
- err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
- if(err < 0){
- printk("Couldn't open tty for slip line, err = %d\n", -err);
+ err = open(ptsname(mfd), O_RDWR, 0);
+ if (err < 0) {
+ printk(UM_KERN_ERR "Couldn't open tty for slip line, "
+ "err = %d\n", -err);
goto out_close;
}
sfd = err;
- if(set_up_tty(sfd))
+ if (set_up_tty(sfd))
goto out_close2;
pri->slave = sfd;
pri->slip.pos = 0;
pri->slip.esc = 0;
- if(pri->gate_addr != NULL){
+ if (pri->gate_addr != NULL) {
sprintf(version_buf, "%d", UML_NET_VERSION);
strcpy(gate_buf, pri->gate_addr);
err = slip_tramp(argv, sfd);
- if(err < 0){
- printk("slip_tramp failed - err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
+ -err);
goto out_close2;
}
err = os_get_ifname(pri->slave, pri->name);
- if(err < 0){
- printk("get_ifname failed, err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
+ -err);
goto out_close2;
}
iter_addresses(pri->dev, open_addr, pri->name);
}
else {
err = os_set_slip(sfd);
- if(err < 0){
- printk("Failed to set slip discipline encapsulation - "
- "err = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "Failed to set slip discipline "
+ "encapsulation - err = %d\n", -err);
goto out_close2;
}
}
- return(mfd);
+ return mfd;
out_close2:
- os_close_file(sfd);
+ close(sfd);
out_close:
- os_close_file(mfd);
+ close(mfd);
out:
return err;
}
@@ -192,21 +202,21 @@ static void slip_close(int fd, void *data)
{
struct slip_data *pri = data;
char version_buf[sizeof("nnnnn\0")];
- char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
+ char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
NULL };
int err;
- if(pri->gate_addr != NULL)
+ if (pri->gate_addr != NULL)
iter_addresses(pri->dev, close_addr, pri->name);
sprintf(version_buf, "%d", UML_NET_VERSION);
err = slip_tramp(argv, pri->slave);
- if(err != 0)
- printk("slip_tramp failed - errno = %d\n", -err);
- os_close_file(fd);
- os_close_file(pri->slave);
+ if (err != 0)
+ printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
+ close(fd);
+ close(pri->slave);
pri->slave = -1;
}
@@ -220,17 +230,13 @@ int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
return slip_proto_write(fd, buf, len, &pri->slip);
}
-static int slip_set_mtu(int mtu, void *data)
-{
- return(mtu);
-}
-
static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct slip_data *pri = data;
- if(pri->slave < 0) return;
+ if (pri->slave < 0)
+ return;
open_addr(addr, netmask, pri->name);
}
@@ -239,7 +245,8 @@ static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct slip_data *pri = data;
- if(pri->slave < 0) return;
+ if (pri->slave < 0)
+ return;
close_addr(addr, netmask, pri->name);
}
@@ -248,8 +255,8 @@ const struct net_user_info slip_user_info = {
.open = slip_open,
.close = slip_close,
.remove = NULL,
- .set_mtu = slip_set_mtu,
.add_address = slip_add_addr,
.delete_address = slip_del_addr,
- .max_packet = BUF_SIZE
+ .mtu = BUF_SIZE,
+ .max_packet = BUF_SIZE,
};
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 0a0324a6d29..d987af277db 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -1,11 +1,14 @@
-#include "linux/kernel.h"
-#include "linux/stddef.h"
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL.
+ */
+
+#include <linux/if_arp.h>
#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/if_arp.h"
+#include <linux/netdevice.h>
+#include <linux/string.h>
#include "net_kern.h"
#include "net_user.h"
-#include "kern.h"
#include "slirp.h"
struct slirp_init {
@@ -31,37 +34,32 @@ void slirp_init(struct net_device *dev, void *data)
dev->init = NULL;
dev->hard_header_len = 0;
- dev->header_cache_update = NULL;
- dev->hard_header_cache = NULL;
- dev->hard_header = NULL;
+ dev->header_ops = NULL;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 256;
dev->flags = IFF_NOARP;
printk("SLIRP backend - command line:");
- for(i=0;spri->argw.argv[i]!=NULL;i++) {
+ for (i = 0; spri->argw.argv[i] != NULL; i++)
printk(" '%s'",spri->argw.argv[i]);
- }
printk("\n");
}
static unsigned short slirp_protocol(struct sk_buff *skbuff)
{
- return(htons(ETH_P_IP));
+ return htons(ETH_P_IP);
}
-static int slirp_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return(slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu,
- (struct slirp_data *) &lp->user));
+ return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
+ (struct slirp_data *) &lp->user);
}
-static int slirp_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return(slirp_user_write(fd, (*skb)->data, (*skb)->len,
- (struct slirp_data *) &lp->user));
+ return slirp_user_write(fd, skb->data, skb->len,
+ (struct slirp_data *) &lp->user);
}
const struct net_kern_info slirp_kern_info = {
@@ -76,31 +74,32 @@ static int slirp_setup(char *str, char **mac_out, void *data)
struct slirp_init *init = data;
int i=0;
- *init = ((struct slirp_init)
- { .argw = { { "slirp", NULL } } });
+ *init = ((struct slirp_init) { .argw = { { "slirp", NULL } } });
str = split_if_spec(str, mac_out, NULL);
- if(str == NULL) { /* no command line given after MAC addr */
- return(1);
- }
+ if (str == NULL) /* no command line given after MAC addr */
+ return 1;
do {
- if(i>=SLIRP_MAX_ARGS-1) {
- printk("slirp_setup: truncating slirp arguments\n");
+ if (i >= SLIRP_MAX_ARGS - 1) {
+ printk(KERN_WARNING "slirp_setup: truncating slirp "
+ "arguments\n");
break;
}
init->argw.argv[i++] = str;
while(*str && *str!=',') {
- if(*str=='_') *str=' ';
+ if (*str == '_')
+ *str=' ';
str++;
}
- if(*str!=',')
+ if (*str != ',')
break;
- *str++='\0';
- } while(1);
- init->argw.argv[i]=NULL;
- return(1);
+ *str++ = '\0';
+ } while (1);
+
+ init->argw.argv[i] = NULL;
+ return 1;
}
static struct transport slirp_transport = {
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 0e462f64f22..1865089ff41 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -1,18 +1,17 @@
-#include <stdio.h>
-#include <stdlib.h>
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL.
+ */
+
#include <unistd.h>
-#include <stddef.h>
-#include <sched.h>
-#include <string.h>
#include <errno.h>
+#include <string.h>
#include <sys/wait.h>
-#include <sys/signal.h>
-#include "kern_util.h"
-#include "user.h"
+#include "kern_constants.h"
#include "net_user.h"
-#include "slirp.h"
-#include "slip_common.h"
#include "os.h"
+#include "slirp.h"
+#include "user.h"
static int slirp_user_init(void *data, void *dev)
{
@@ -31,8 +30,10 @@ static void slirp_pre_exec(void *arg)
{
struct slirp_pre_exec_data *data = arg;
- if(data->stdin != -1) dup2(data->stdin, 0);
- if(data->stdout != -1) dup2(data->stdout, 1);
+ if (data->stdin != -1)
+ dup2(data->stdin, 0);
+ if (data->stdout != -1)
+ dup2(data->stdout, 1);
}
static int slirp_tramp(char **argv, int fd)
@@ -44,7 +45,7 @@ static int slirp_tramp(char **argv, int fd)
pe_data.stdout = fd;
pid = run_helper(slirp_pre_exec, &pe_data, argv);
- return(pid);
+ return pid;
}
static int slirp_open(void *data)
@@ -53,12 +54,12 @@ static int slirp_open(void *data)
int fds[2], pid, err;
err = os_pipe(fds, 1, 1);
- if(err)
- return(err);
+ if (err)
+ return err;
err = slirp_tramp(pri->argw.argv, fds[1]);
- if(err < 0){
- printk("slirp_tramp failed - errno = %d\n", -err);
+ if (err < 0) {
+ printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err);
goto out;
}
pid = err;
@@ -68,10 +69,10 @@ static int slirp_open(void *data)
pri->slip.esc = 0;
pri->pid = err;
- return(fds[0]);
+ return fds[0];
out:
- os_close_file(fds[0]);
- os_close_file(fds[1]);
+ close(fds[0]);
+ close(fds[1]);
return err;
}
@@ -80,31 +81,33 @@ static void slirp_close(int fd, void *data)
struct slirp_data *pri = data;
int status,err;
- os_close_file(fd);
- os_close_file(pri->slave);
+ close(fd);
+ close(pri->slave);
pri->slave = -1;
- if(pri->pid<1) {
- printk("slirp_close: no child process to shut down\n");
+ if (pri->pid<1) {
+ printk(UM_KERN_ERR "slirp_close: no child process to shut "
+ "down\n");
return;
}
#if 0
- if(kill(pri->pid, SIGHUP)<0) {
- printk("slirp_close: sending hangup to %d failed (%d)\n",
- pri->pid, errno);
+ if (kill(pri->pid, SIGHUP)<0) {
+ printk(UM_KERN_ERR "slirp_close: sending hangup to %d failed "
+ "(%d)\n", pri->pid, errno);
}
#endif
CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
- if(err < 0) {
- printk("slirp_close: waitpid returned %d\n", errno);
+ if (err < 0) {
+ printk(UM_KERN_ERR "slirp_close: waitpid returned %d\n", errno);
return;
}
- if(err == 0) {
- printk("slirp_close: process %d has not exited\n", pri->pid);
+ if (err == 0) {
+ printk(UM_KERN_ERR "slirp_close: process %d has not exited\n",
+ pri->pid);
return;
}
@@ -121,18 +124,13 @@ int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
return slip_proto_write(fd, buf, len, &pri->slip);
}
-static int slirp_set_mtu(int mtu, void *data)
-{
- return(mtu);
-}
-
const struct net_user_info slirp_user_info = {
.init = slirp_user_init,
.open = slirp_open,
.close = slirp_close,
.remove = NULL,
- .set_mtu = slirp_set_mtu,
.add_address = NULL,
.delete_address = NULL,
- .max_packet = BUF_SIZE
+ .mtu = BUF_SIZE,
+ .max_packet = BUF_SIZE,
};
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index a9f87e19c5b..c930fedc517 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -1,16 +1,16 @@
/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
-#include <stdio.h>
-#include <termios.h>
#include <errno.h>
-#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
#include "chan_user.h"
-#include "user.h"
+#include "kern_constants.h"
#include "os.h"
#include "um_malloc.h"
+#include "user.h"
struct tty_chan {
char *dev;
@@ -22,15 +22,15 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
{
struct tty_chan *data;
- if(*str != ':'){
- printk("tty_init : channel type 'tty' must specify "
+ if (*str != ':') {
+ printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify "
"a device\n");
return NULL;
}
str++;
data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
- if(data == NULL)
+ if (data == NULL)
return NULL;
*data = ((struct tty_chan) { .dev = str,
.raw = opts->raw });
@@ -42,19 +42,26 @@ static int tty_open(int input, int output, int primary, void *d,
char **dev_out)
{
struct tty_chan *data = d;
- int fd, err;
+ int fd, err, mode = 0;
+
+ if (input && output)
+ mode = O_RDWR;
+ else if (input)
+ mode = O_RDONLY;
+ else if (output)
+ mode = O_WRONLY;
- fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
- if(fd < 0)
- return fd;
+ fd = open(data->dev, mode);
+ if (fd < 0)
+ return -errno;
- if(data->raw){
+ if (data->raw) {
CATCH_EINTR(err = tcgetattr(fd, &data->tt));
- if(err)
+ if (err)
return err;
err = raw(fd);
- if(err)
+ if (err)
return err;
}
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0eabe73c964..25b248a0250 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -615,7 +615,7 @@ static int ubd_open_dev(struct ubd *ubd_dev)
blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
err = -ENOMEM;
- ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len);
+ ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
if(ubd_dev->cow.bitmap == NULL){
printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
goto error;
diff --git a/arch/um/drivers/vde.h b/arch/um/drivers/vde.h
new file mode 100644
index 00000000000..fc3a05902ba
--- /dev/null
+++ b/arch/um/drivers/vde.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
+ * Licensed under the GPL.
+ */
+
+#ifndef __UM_VDE_H__
+#define __UM_VDE_H__
+
+struct vde_data {
+ char *vde_switch;
+ char *descr;
+ void *args;
+ void *conn;
+ void *dev;
+};
+
+struct vde_init {
+ char *vde_switch;
+ char *descr;
+ int port;
+ char *group;
+ int mode;
+};
+
+extern const struct net_user_info vde_user_info;
+
+extern void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init);
+
+extern int vde_user_read(void *conn, void *buf, int len);
+extern int vde_user_write(void *conn, void *buf, int len);
+
+#endif
diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c
new file mode 100644
index 00000000000..add7e722def
--- /dev/null
+++ b/arch/um/drivers/vde_kern.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
+ * Licensed under the GPL.
+ *
+ * Transport usage:
+ * ethN=vde,<vde_switch>,<mac addr>,<port>,<group>,<mode>,<description>
+ *
+ */
+
+#include "linux/init.h"
+#include <linux/netdevice.h>
+#include "net_kern.h"
+#include "net_user.h"
+#include "vde.h"
+
+static void vde_init(struct net_device *dev, void *data)
+{
+ struct vde_init *init = data;
+ struct uml_net_private *pri;
+ struct vde_data *vpri;
+
+ pri = dev->priv;
+ vpri = (struct vde_data *) pri->user;
+
+ vpri->vde_switch = init->vde_switch;
+ vpri->descr = init->descr ? init->descr : "UML vde_transport";
+ vpri->args = NULL;
+ vpri->conn = NULL;
+ vpri->dev = dev;
+
+ printk("vde backend - %s, ", vpri->vde_switch ?
+ vpri->vde_switch : "(default socket)");
+
+ vde_init_libstuff(vpri, init);
+
+ printk("\n");
+}
+
+static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
+{
+ struct vde_data *pri = (struct vde_data *) &lp->user;
+
+ if (pri->conn != NULL)
+ return vde_user_read(pri->conn, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
+
+ printk(KERN_ERR "vde_read - we have no VDECONN to read from");
+ return -EBADF;
+}
+
+static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
+{
+ struct vde_data *pri = (struct vde_data *) &lp->user;
+
+ if (pri->conn != NULL)
+ return vde_user_write((void *)pri->conn, skb->data,
+ skb->len);
+
+ printk(KERN_ERR "vde_write - we have no VDECONN to write to");
+ return -EBADF;
+}
+
+static const struct net_kern_info vde_kern_info = {
+ .init = vde_init,
+ .protocol = eth_protocol,
+ .read = vde_read,
+ .write = vde_write,
+};
+
+static int vde_setup(char *str, char **mac_out, void *data)
+{
+ struct vde_init *init = data;
+ char *remain, *port_str = NULL, *mode_str = NULL, *last;
+
+ *init = ((struct vde_init)
+ { .vde_switch = NULL,
+ .descr = NULL,
+ .port = 0,
+ .group = NULL,
+ .mode = 0 });
+
+ remain = split_if_spec(str, &init->vde_switch, mac_out, &port_str,
+ &init->group, &mode_str, &init->descr, NULL);
+
+ if (remain != NULL)
+ printk(KERN_WARNING "vde_setup - Ignoring extra data :"
+ "'%s'\n", remain);
+
+ if (port_str != NULL) {
+ init->port = simple_strtoul(port_str, &last, 10);
+ if ((*last != '\0') || (last == port_str)) {
+ printk(KERN_ERR "vde_setup - Bad port : '%s'\n",
+ port_str);
+ return 0;
+ }
+ }
+
+ if (mode_str != NULL) {
+ init->mode = simple_strtoul(mode_str, &last, 8);
+ if ((*last != '\0') || (last == mode_str)) {
+ printk(KERN_ERR "vde_setup - Bad mode : '%s'\n",
+ mode_str);
+ return 0;
+ }
+ }
+
+ printk(KERN_INFO "Configured vde device: %s\n", init->vde_switch ?
+ init->vde_switch : "(default socket)");
+
+ return 1;
+}
+
+static struct transport vde_transport = {
+ .list = LIST_HEAD_INIT(vde_transport.list),
+ .name = "vde",
+ .setup = vde_setup,
+ .user = &vde_user_info,
+ .kern = &vde_kern_info,
+ .private_size = sizeof(struct vde_data),
+ .setup_size = sizeof(struct vde_init),
+};
+
+static int register_vde(void)
+{
+ register_transport(&vde_transport);
+ return 0;
+}
+
+late_initcall(register_vde);
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
new file mode 100644
index 00000000000..d9941fe5f93
--- /dev/null
+++ b/arch/um/drivers/vde_user.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
+ * Licensed under the GPL.
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#include <libvdeplug.h>
+#include "kern_constants.h"
+#include "net_user.h"
+#include "um_malloc.h"
+#include "user.h"
+#include "vde.h"
+
+static int vde_user_init(void *data, void *dev)
+{
+ struct vde_data *pri = data;
+ VDECONN *conn = NULL;
+ int err = -EINVAL;
+
+ pri->dev = dev;
+
+ conn = vde_open(pri->vde_switch, pri->descr, pri->args);
+
+ if (conn == NULL) {
+ err = -errno;
+ printk(UM_KERN_ERR "vde_user_init: vde_open failed, "
+ "errno = %d\n", errno);
+ return err;
+ }
+
+ printk(UM_KERN_INFO "vde backend - connection opened\n");
+
+ pri->conn = conn;
+
+ return 0;
+}
+
+static int vde_user_open(void *data)
+{
+ struct vde_data *pri = data;
+
+ if (pri->conn != NULL)
+ return vde_datafd(pri->conn);
+
+ printk(UM_KERN_WARNING "vde_open - we have no VDECONN to open");
+ return -EINVAL;
+}
+
+static void vde_remove(void *data)
+{
+ struct vde_data *pri = data;
+
+ if (pri->conn != NULL) {
+ printk(UM_KERN_INFO "vde backend - closing connection\n");
+ vde_close(pri->conn);
+ pri->conn = NULL;
+ kfree(pri->args);
+ pri->args = NULL;
+ return;
+ }
+
+ printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove");
+}
+
+const struct net_user_info vde_user_info = {
+ .init = vde_user_init,
+ .open = vde_user_open,
+ .close = NULL,
+ .remove = vde_remove,
+ .add_address = NULL,
+ .delete_address = NULL,
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
+};
+
+void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
+{
+ struct vde_open_args *args;
+
+ vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL);
+ if (vpri->args == NULL) {
+ printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args"
+ "allocation failed");
+ return;
+ }
+
+ args = vpri->args;
+
+ args->port = init->port;
+ args->group = init->group;
+ args->mode = init->mode ? init->mode : 0700;
+
+ args->port ? printk(UM_KERN_INFO "port %d", args->port) :
+ printk(UM_KERN_INFO "undefined port");
+}
+
+int vde_user_read(void *conn, void *buf, int len)
+{
+ VDECONN *vconn = conn;
+ int rv;
+
+ if (vconn == NULL)
+ return 0;
+
+ rv = vde_recv(vconn, buf, len, 0);
+ if (rv < 0) {
+ if (errno == EAGAIN)
+ return 0;
+ return -errno;
+ }
+ else if (rv == 0)
+ return -ENOTCONN;
+
+ return rv;
+}
+
+int vde_user_write(void *conn, void *buf, int len)
+{
+ VDECONN *vconn = conn;
+
+ if (vconn == NULL)
+ return 0;
+
+ return vde_send(vconn, buf, len, 0);
+}
+
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index fd817e54154..8a1c18a9b24 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -1,20 +1,21 @@
-/*
+/*
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stdlib.h>
+#include <stddef.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
-#include <string.h>
#include <errno.h>
+#include <string.h>
#include <termios.h>
#include "chan_user.h"
+#include "kern_constants.h"
#include "os.h"
-#include "init.h"
+#include "um_malloc.h"
#include "user.h"
#include "xterm.h"
-#include "kern_constants.h"
struct xterm_chan {
int pid;
@@ -29,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
{
struct xterm_chan *data;
- data = malloc(sizeof(*data));
+ data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
return NULL;
*data = ((struct xterm_chan) { .pid = -1,
@@ -95,8 +96,10 @@ static int xterm_open(int input, int output, int primary, void *d,
if (access(argv[4], X_OK) < 0)
argv[4] = "port-helper";
- /* Check that DISPLAY is set, this doesn't guarantee the xterm
- * will work but w/o it we can be pretty sure it won't. */
+ /*
+ * Check that DISPLAY is set, this doesn't guarantee the xterm
+ * will work but w/o it we can be pretty sure it won't.
+ */
if (getenv("DISPLAY") == NULL) {
printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n");
return -ENODEV;
@@ -195,7 +198,7 @@ static int xterm_open(int input, int output, int primary, void *d,
static void xterm_close(int fd, void *d)
{
struct xterm_chan *data = d;
-
+
if (data->pid != -1)
os_kill_process(data->pid, 1);
data->pid = -1;
@@ -207,11 +210,6 @@ static void xterm_close(int fd, void *d)
os_close_file(fd);
}
-static void xterm_free(void *d)
-{
- free(d);
-}
-
const struct chan_ops xterm_ops = {
.type = "xterm",
.init = xterm_init,
@@ -221,6 +219,6 @@ const struct chan_ops xterm_ops = {
.write = generic_write,
.console_write = generic_console_write,
.window_size = generic_window_size,
- .free = xterm_free,
+ .free = generic_free,
.winch = 1,
};
diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h
index 10ad52daa8c..49c601ff2ba 100644
--- a/arch/um/include/arch.h
+++ b/arch/um/include/arch.h
@@ -9,7 +9,7 @@
#include "sysdep/ptrace.h"
extern void arch_check_bugs(void);
-extern int arch_fixup(unsigned long address, union uml_pt_regs *regs);
-extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
+extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
+extern int arch_handle_signal(int sig, struct uml_pt_regs *regs);
#endif
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
index fccf187bf4e..a5cdf953e04 100644
--- a/arch/um/include/as-layout.h
+++ b/arch/um/include/as-layout.h
@@ -6,6 +6,28 @@
#ifndef __START_H__
#define __START_H__
+#include "uml-config.h"
+#include "kern_constants.h"
+
+/*
+ * Assembly doesn't want any casting, but C does, so define these
+ * without casts here, and define new symbols with casts inside the C
+ * section.
+ */
+#define ASM_STUB_CODE (UML_CONFIG_TOP_ADDR - 2 * UM_KERN_PAGE_SIZE)
+#define ASM_STUB_DATA (UML_CONFIG_TOP_ADDR - UM_KERN_PAGE_SIZE)
+#define ASM_STUB_START ASM_STUB_CODE
+
+/*
+ * This file is included by the assembly stubs, which just want the
+ * definitions above.
+ */
+#ifndef __ASSEMBLY__
+
+#define STUB_CODE ((unsigned long) ASM_STUB_CODE)
+#define STUB_DATA ((unsigned long) ASM_STUB_DATA)
+#define STUB_START ((unsigned long) ASM_STUB_START)
+
#include "sysdep/ptrace.h"
struct cpu_task {
@@ -28,8 +50,9 @@ extern unsigned long _unprotected_end;
extern unsigned long brk_start;
extern int linux_main(int argc, char **argv);
-extern void set_cmdline(char *cmd);
-extern void (*sig_info[])(int, union uml_pt_regs *);
+extern void (*sig_info[])(int, struct uml_pt_regs *);
+
+#endif
#endif
diff --git a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h
deleted file mode 100644
index b87b36a87d9..00000000000
--- a/arch/um/include/choose-mode.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __CHOOSE_MODE_H__
-#define __CHOOSE_MODE_H__
-
-#include "uml-config.h"
-
-#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
-#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
-
-extern int mode_tt;
-static inline void *__choose_mode(void *tt, void *skas) {
- return mode_tt ? tt : skas;
-}
-
-#define __CHOOSE_MODE(tt, skas) (*( (typeof(tt) *) __choose_mode(&(tt), &(skas))))
-
-#elif defined(UML_CONFIG_MODE_SKAS)
-#define CHOOSE_MODE(tt, skas) (skas)
-
-#elif defined(UML_CONFIG_MODE_TT)
-#define CHOOSE_MODE(tt, skas) (tt)
-
-#else
-#error CONFIG_MODE_SKAS and CONFIG_MODE_TT are both disabled
-#endif
-
-#define CHOOSE_MODE_PROC(tt, skas, args...) \
- CHOOSE_MODE(tt(args), skas(args))
-
-#ifndef __CHOOSE_MODE
-#define __CHOOSE_MODE(tt, skas) CHOOSE_MODE(tt, skas)
-#endif
-
-#endif
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 6eee343e53e..0edab695ed4 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,15 +1,13 @@
/* for use by sys-$SUBARCH/kernel-offsets.c */
DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
-#ifdef CONFIG_MODE_TT
-OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
-#endif
OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
OFFSET(HOST_TASK_PID, task_struct, pid);
DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
+DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
@@ -34,3 +32,9 @@ DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC);
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
DEFINE(UM_THREAD_SIZE, THREAD_SIZE);
+
+DEFINE(UM_HZ, HZ);
+
+DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC);
+DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC);
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index 15d311b9be9..884a9c17eea 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -1,12 +1,12 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __IRQ_USER_H__
#define __IRQ_USER_H__
-#include "uml-config.h"
+#include "sysdep/ptrace.h"
struct irq_fd {
struct irq_fd *next;
@@ -21,7 +21,7 @@ struct irq_fd {
enum { IRQ_READ, IRQ_WRITE };
-extern void sigio_handler(int sig, union uml_pt_regs *regs);
+extern void sigio_handler(int sig, struct uml_pt_regs *regs);
extern int activate_fd(int irq, int fd, int type, void *dev_id);
extern void free_irq_by_irq_and_dev(unsigned int irq, void *dev_id);
extern void free_irq_by_fd(int fd);
@@ -30,8 +30,4 @@ extern void deactivate_fd(int fd, int irqnum);
extern int deactivate_all_fds(void);
extern int activate_ipi(int fd, int pid);
-#ifdef CONFIG_MODE_TT
-extern void forward_interrupts(int pid);
-#endif
-
#endif
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 6c2be26f1d7..74ce8e5370a 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -8,9 +8,8 @@
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
-#include "uml-config.h"
-typedef void (*kern_hndl)(int, union uml_pt_regs *);
+typedef void (*kern_hndl)(int, struct uml_pt_regs *);
struct kern_handlers {
kern_hndl relay_signal;
@@ -34,9 +33,6 @@ extern int nsyscalls;
UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
-#ifdef UML_CONFIG_MODE_TT
-extern unsigned long stack_sp(unsigned long page);
-#endif
extern int kernel_thread_proc(void *data);
extern void syscall_segv(int sig);
extern int current_pid(void);
@@ -44,7 +40,7 @@ extern unsigned long alloc_stack(int order, int atomic);
extern int do_signal(void);
extern int is_stack_fault(unsigned long sp);
extern unsigned long segv(struct faultinfo fi, unsigned long ip,
- int is_user, union uml_pt_regs *regs);
+ int is_user, struct uml_pt_regs *regs);
extern int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out);
extern void syscall_ready(void);
@@ -57,7 +53,7 @@ extern int need_finish_fork(void);
extern void free_stack(unsigned long stack, int order);
extern void add_input_request(int op, void (*proc)(int), void *arg);
extern char *current_cmd(void);
-extern void timer_handler(int sig, union uml_pt_regs *regs);
+extern void timer_handler(int sig, struct uml_pt_regs *regs);
extern int set_signals(int enable);
extern int pid_to_processor_id(int pid);
extern void deliver_signals(void *t);
@@ -67,9 +63,8 @@ extern void finish_fork(void);
extern void paging_init(void);
extern void init_flush_vm(void);
extern void *syscall_sp(void *t);
-extern void syscall_trace(union uml_pt_regs *regs, int entryexit);
-extern int hz(void);
-extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
+extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
+extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
extern void interrupt_end(void);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
extern int debugger_signal(int status, int pid);
@@ -79,10 +74,9 @@ extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
extern int init_parent_proxy(int pid);
extern int singlestepping(void *t);
extern void check_stack_overflow(void *ptr);
-extern void relay_signal(int sig, union uml_pt_regs *regs);
+extern void relay_signal(int sig, struct uml_pt_regs *regs);
extern int user_context(unsigned long sp);
-extern void timer_irq(union uml_pt_regs *regs);
-extern void unprotect_stack(unsigned long stack);
+extern void timer_irq(struct uml_pt_regs *regs);
extern void do_uml_exitcalls(void);
extern int attach_debugger(int idle_pid, int pid, int stop);
extern int config_gdb(char *str);
@@ -113,11 +107,9 @@ extern void time_init_kern(void);
/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */
extern int __cant_sleep(void);
-extern void sigio_handler(int sig, union uml_pt_regs *regs);
-
-extern void copy_sc(union uml_pt_regs *regs, void *from);
-
+extern void sigio_handler(int sig, struct uml_pt_regs *regs);
+extern void copy_sc(struct uml_pt_regs *regs, void *from);
extern unsigned long to_irq_stack(unsigned long *mask_out);
unsigned long from_irq_stack(int nested);
-
+extern int start_uml(void);
#endif
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index b282839c162..c139ae1d682 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -63,7 +63,7 @@ struct mc_request
struct mconsole_request request;
struct mconsole_command *cmd;
- union uml_pt_regs regs;
+ struct uml_pt_regs regs;
};
extern char mconsole_socket_name[];
@@ -96,14 +96,3 @@ extern void lock_notify(void);
extern void unlock_notify(void);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/mem.h b/arch/um/include/mem.h
index e8ff0d8fa61..5cd40e99e8d 100644
--- a/arch/um/include/mem.h
+++ b/arch/um/include/mem.h
@@ -1,18 +1,12 @@
/*
- * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __MEM_H__
#define __MEM_H__
-#include "linux/types.h"
-
-extern int phys_mapping(unsigned long phys, __u64 *offset_out);
-extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
-extern int is_remapped(void *virt);
-extern int physmem_remove_mapping(void *virt);
-extern void physmem_forget_descriptor(int fd);
+extern int phys_mapping(unsigned long phys, unsigned long long *offset_out);
extern unsigned long uml_physmem;
static inline unsigned long to_phys(void *virt)
@@ -26,14 +20,3 @@ static inline void *to_virt(unsigned long phys)
}
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/mode.h b/arch/um/include/mode.h
deleted file mode 100644
index 786cf563eb0..00000000000
--- a/arch/um/include/mode.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __MODE_H__
-#define __MODE_H__
-
-#include "uml-config.h"
-
-#ifdef UML_CONFIG_MODE_TT
-#include "mode-tt.h"
-#endif
-
-#ifdef UML_CONFIG_MODE_SKAS
-#include "mode-skas.h"
-#endif
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/mode_kern.h b/arch/um/include/mode_kern.h
deleted file mode 100644
index 88e5e77bf51..00000000000
--- a/arch/um/include/mode_kern.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __MODE_KERN_H__
-#define __MODE_KERN_H__
-
-#ifdef CONFIG_MODE_TT
-#include "mode_kern_tt.h"
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-#include "mode_kern_skas.h"
-#endif
-
-#endif
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 9237056b910..d843c7924a7 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -30,24 +30,24 @@ struct uml_net_private {
struct work_struct work;
int fd;
unsigned char mac[ETH_ALEN];
+ int max_packet;
unsigned short (*protocol)(struct sk_buff *);
int (*open)(void *);
void (*close)(int, void *);
void (*remove)(void *);
- int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
- int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
+ int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
+ int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
void (*add_address)(unsigned char *, unsigned char *, void *);
void (*delete_address)(unsigned char *, unsigned char *, void *);
- int (*set_mtu)(int mtu, void *);
char user[0];
};
struct net_kern_info {
void (*init)(struct net_device *, void *);
unsigned short (*protocol)(struct sk_buff *);
- int (*read)(int, struct sk_buff **skb, struct uml_net_private *);
- int (*write)(int, struct sk_buff **skb, struct uml_net_private *);
+ int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
+ int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
};
struct transport {
@@ -62,7 +62,6 @@ struct transport {
extern struct net_device *ether_init(int);
extern unsigned short ether_protocol(struct sk_buff *);
-extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
extern int tap_setup_common(char *str, char *type, char **dev_name,
char **mac_out, char **gate_addr);
extern void register_transport(struct transport *new);
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index cfe7c50634b..63bee158cd8 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -18,10 +18,10 @@ struct net_user_info {
int (*open)(void *);
void (*close)(int, void *);
void (*remove)(void *);
- int (*set_mtu)(int mtu, void *);
void (*add_address)(unsigned char *, unsigned char *, void *);
void (*delete_address)(unsigned char *, unsigned char *, void *);
int max_packet;
+ int mtu;
};
extern void ether_user_init(void *data, void *dev);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 930b261ea48..fbf0a87c6ea 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -1,20 +1,18 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __OS_H__
#define __OS_H__
-#include "uml-config.h"
-#include "asm/types.h"
-#include "../os/include/file.h"
-#include "sysdep/ptrace.h"
-#include "kern_util.h"
-#include "skas/mm_id.h"
+#include <stdarg.h>
#include "irq_user.h"
+#include "kern_util.h"
+#include "longjmp.h"
+#include "mm_id.h"
#include "sysdep/tls.h"
-#include "sysdep/archsetjmp.h"
+#include "../os/include/file.h"
#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
@@ -130,18 +128,15 @@ static inline struct openflags of_cloexec(struct openflags flags)
extern int os_stat_file(const char *file_name, struct uml_stat *buf);
extern int os_stat_fd(const int fd, struct uml_stat *buf);
extern int os_access(const char *file, int mode);
-extern void os_print_error(int error, const char* str);
extern int os_get_exec_close(int fd, int *close_on_exec);
-extern int os_set_exec_close(int fd, int close_on_exec);
+extern int os_set_exec_close(int fd);
extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
-extern int os_window_size(int fd, int *rows, int *cols);
-extern int os_new_tty_pgrp(int fd, int pid);
extern int os_get_ifname(int fd, char *namebuf);
extern int os_set_slip(int fd);
extern int os_set_owner(int fd, int pid);
extern int os_mode_fd(int fd, int mode);
-extern int os_seek_file(int fd, __u64 offset);
+extern int os_seek_file(int fd, unsigned long long offset);
extern int os_open_file(char *file, struct openflags flags, int mode);
extern int os_read_file(int fd, void *buf, int len);
extern int os_write_file(int fd, const void *buf, int count);
@@ -179,11 +174,7 @@ extern void check_host_supports_tls(int *supports_tls, int *tls_min);
/* Make sure they are clear when running in TT mode. Required by
* SEGV_MAYBE_FIXABLE */
-#ifdef UML_CONFIG_MODE_SKAS
#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
-#else
-#define clear_can_do_skas() do {} while (0)
-#endif
/* mem.c */
extern int create_mem_file(unsigned long long len);
@@ -194,20 +185,13 @@ extern int os_process_parent(int pid);
extern void os_stop_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_kill_ptraced_process(int pid, int reap_child);
-#ifdef UML_CONFIG_MODE_TT
-extern void os_usr1_process(int pid);
-#endif
extern long os_ptrace_ldt(long pid, long addr, long data);
extern int os_getpid(void);
extern int os_getpgrp(void);
-#ifdef UML_CONFIG_MODE_TT
-extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
-extern void stop(void);
-#endif
extern void init_new_thread_signals(void);
-extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
+extern int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr);
extern int os_map_memory(void *virt, int fd, unsigned long long off,
unsigned long len, int r, int w, int x);
@@ -218,21 +202,9 @@ extern int os_drop_memory(void *addr, int length);
extern int can_drop_memory(void);
extern void os_flush_stdout(void);
-/* tt.c
- * for tt mode only (will be deleted in future...)
- */
-extern void forward_ipi(int fd, int pid);
-extern void kill_child_dead(int pid);
-extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
-extern int protect_memory(unsigned long addr, unsigned long len,
- int r, int w, int x, int must_succeed);
-extern void forward_pending_sigio(int target);
-extern int start_fork_tramp(void *arg, unsigned long temp_stack,
- int clone_flags, int (*tramp)(void *));
-
/* uaccess.c */
extern unsigned long __do_user_copy(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher,
+ void **fault_addr, jmp_buf **fault_catcher,
void (*op)(void *to, const void *from,
int n), int *faulted_out);
@@ -255,6 +227,7 @@ extern int set_umid(char *name);
extern char *get_umid(void);
/* signal.c */
+extern void timer_init(void);
extern void set_sigstack(void *sig_stack, int size);
extern void remove_sigstack(void);
extern void set_handler(int sig, void (*handler)(int), int flags, ...);
@@ -266,7 +239,6 @@ extern int set_signals(int enable);
/* trap.c */
extern void os_fill_handlinfo(struct kern_handlers h);
-extern void do_longjmp(void *p, int val);
/* util.c */
extern void stack_protections(unsigned long address);
@@ -277,17 +249,12 @@ extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
extern void os_dump_core(void);
/* time.c */
-#define BILLION (1000 * 1000 * 1000)
-
-extern void switch_timers(int to_real);
-extern void idle_sleep(int secs);
-extern int set_interval(int is_virtual);
-#ifdef CONFIG_MODE_TT
-extern void enable_timer(void);
-#endif
-extern void disable_timer(void);
+extern void idle_sleep(unsigned long long nsecs);
+extern int set_interval(void);
+extern int timer_one_shot(int ticks);
+extern long long disable_timer(void);
extern void uml_idle_timer(void);
-extern unsigned long long os_nsecs(void);
+extern long long os_nsecs(void);
/* skas/mem.c */
extern long run_syscall_stub(struct mm_id * mm_idp,
@@ -308,7 +275,9 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr,
extern int is_skas_winch(int pid, int fd, void *data);
extern int start_userspace(unsigned long stub_stack);
extern int copy_context_skas0(unsigned long stack, int pid);
-extern void userspace(union uml_pt_regs *regs);
+extern void save_registers(int pid, struct uml_pt_regs *regs);
+extern void restore_registers(int pid, struct uml_pt_regs *regs);
+extern void userspace(struct uml_pt_regs *regs);
extern void map_stub_pages(int fd, unsigned long code,
unsigned long data, unsigned long stack);
extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index f845b3629a6..0e27406a43a 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -9,13 +9,15 @@
#include "sysdep/ptrace.h"
#include "sysdep/archsetjmp.h"
-extern void init_thread_registers(union uml_pt_regs *to);
+extern void init_thread_registers(struct uml_pt_regs *to);
extern int save_fp_registers(int pid, unsigned long *fp_regs);
extern int restore_fp_registers(int pid, unsigned long *fp_regs);
-extern void save_registers(int pid, union uml_pt_regs *regs);
-extern void restore_registers(int pid, union uml_pt_regs *regs);
+extern int save_fpx_registers(int pid, unsigned long *fp_regs);
+extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
+extern void save_registers(int pid, struct uml_pt_regs *regs);
+extern void restore_registers(int pid, struct uml_pt_regs *regs);
extern void init_registers(int pid);
-extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs);
+extern void get_safe_registers(unsigned long *regs);
extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
#endif
diff --git a/arch/um/include/skas/mmu-skas.h b/arch/um/include/skas/mmu-skas.h
deleted file mode 100644
index b26986c0c3d..00000000000
--- a/arch/um/include/skas/mmu-skas.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_MMU_H
-#define __SKAS_MMU_H
-
-#include "mm_id.h"
-#include "asm/ldt.h"
-
-struct mmu_context_skas {
- struct mm_id id;
- unsigned long last_page_table;
-#ifdef CONFIG_3_LEVEL_PGTABLES
- unsigned long last_pmd;
-#endif
- uml_ldt_t ldt;
-};
-
-extern void switch_mm_skas(struct mm_id * mm_idp);
-
-#endif
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
index 8bc6916bbbb..e065feb000d 100644
--- a/arch/um/include/skas/mode-skas.h
+++ b/arch/um/include/skas/mode-skas.h
@@ -1,18 +1,11 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
#ifndef __MODE_SKAS_H__
#define __MODE_SKAS_H__
-#include <sysdep/ptrace.h>
-
-extern unsigned long exec_regs[];
-extern unsigned long exec_fp_regs[];
-extern unsigned long exec_fpx_regs[];
-extern int have_fpx_regs;
-
extern void kill_off_processes_skas(void);
#endif
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
deleted file mode 100644
index 8ee6285dfac..00000000000
--- a/arch/um/include/skas/mode_kern_skas.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_MODE_KERN_H__
-#define __SKAS_MODE_KERN_H__
-
-#include "linux/sched.h"
-#include "asm/page.h"
-#include "asm/ptrace.h"
-
-extern void flush_thread_skas(void);
-extern void switch_to_skas(void *prev, void *next);
-extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
- unsigned long esp);
-extern int copy_thread_skas(int nr, unsigned long clone_flags,
- unsigned long sp, unsigned long stack_top,
- struct task_struct *p, struct pt_regs *regs);
-extern void release_thread_skas(struct task_struct *task);
-extern void init_idle_skas(void);
-extern void flush_tlb_kernel_range_skas(unsigned long start,
- unsigned long end);
-extern void flush_tlb_kernel_vm_skas(void);
-extern void __flush_tlb_one_skas(unsigned long addr);
-extern void flush_tlb_range_skas(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-extern void flush_tlb_mm_skas(struct mm_struct *mm);
-extern void force_flush_all_skas(void);
-extern long execute_syscall_skas(void *r);
-extern void before_mem_skas(unsigned long unused);
-extern unsigned long set_task_sizes_skas(unsigned long *task_size_out);
-extern int start_uml_skas(void);
-extern int external_pid_skas(struct task_struct *task);
-extern int thread_pid_skas(struct task_struct *task);
-extern void flush_tlb_page_skas(struct vm_area_struct *vma,
- unsigned long address);
-
-#define kmem_end_skas (host_task_size - 1024 * 1024)
-
-#endif
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
index e88926b1607..b073f8a86bd 100644
--- a/arch/um/include/skas/skas.h
+++ b/arch/um/include/skas/skas.h
@@ -1,12 +1,11 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __SKAS_H
#define __SKAS_H
-#include "mm_id.h"
#include "sysdep/ptrace.h"
extern int userspace_pid[];
@@ -15,7 +14,7 @@ extern int skas_needs_stub;
extern int user_thread(unsigned long stack, int flags);
extern void new_thread_handler(void);
-extern void handle_syscall(union uml_pt_regs *regs);
+extern void handle_syscall(struct uml_pt_regs *regs);
extern int new_mm(unsigned long stack);
extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
extern long execute_syscall_skas(void *r);
diff --git a/arch/um/include/skas/uaccess-skas.h b/arch/um/include/skas/uaccess-skas.h
deleted file mode 100644
index 224a75f4c02..00000000000
--- a/arch/um/include/skas/uaccess-skas.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SKAS_UACCESS_H
-#define __SKAS_UACCESS_H
-
-#include "asm/errno.h"
-
-/* No SKAS-specific checking. */
-#define access_ok_skas(type, addr, size) 0
-
-extern int copy_from_user_skas(void *to, const void __user *from, int n);
-extern int copy_to_user_skas(void __user *to, const void *from, int n);
-extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
-extern int __clear_user_skas(void __user *mem, int len);
-extern int clear_user_skas(void __user *mem, int len);
-extern int strnlen_user_skas(const void __user *str, int len);
-
-#endif
diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h
index 97ec9d894d7..5868526b5ee 100644
--- a/arch/um/include/sysdep-i386/kernel-offsets.h
+++ b/arch/um/include/sysdep-i386/kernel-offsets.h
@@ -17,6 +17,5 @@
void foo(void)
{
- OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
#include <common-offsets.h>
}
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 52b398bcafc..11c08969d13 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -9,17 +9,11 @@
#include "uml-config.h"
#include "user_constants.h"
#include "sysdep/faultinfo.h"
-#include "choose-mode.h"
#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
#define MAX_REG_OFFSET (UM_FRAME_SIZE)
-#ifdef UML_CONFIG_PT_PROXY
-extern void update_debugregs(int seq);
-#else
static inline void update_debugregs(int seq) {}
-#endif
-
/* syscall emulation path in ptrace */
@@ -31,12 +25,6 @@ void set_using_sysemu(int value);
int get_using_sysemu(void);
extern int sysemu_supported;
-#ifdef UML_CONFIG_MODE_TT
-#include "sysdep/sc.h"
-#endif
-
-#ifdef UML_CONFIG_MODE_SKAS
-
#include "skas_ptregs.h"
#define REGS_IP(r) ((r)[HOST_IP])
@@ -60,70 +48,36 @@ extern int sysemu_supported;
#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
-#endif
#ifndef PTRACE_SYSEMU_SINGLESTEP
#define PTRACE_SYSEMU_SINGLESTEP 32
#endif
-union uml_pt_regs {
-#ifdef UML_CONFIG_MODE_TT
- struct tt_regs {
- long syscall;
- void *sc;
- struct faultinfo faultinfo;
- } tt;
-#endif
-#ifdef UML_CONFIG_MODE_SKAS
- struct skas_regs {
- unsigned long regs[MAX_REG_NR];
- unsigned long fp[HOST_FP_SIZE];
- unsigned long xfp[HOST_XFP_SIZE];
- struct faultinfo faultinfo;
- long syscall;
- int is_user;
- } skas;
-#endif
+struct uml_pt_regs {
+ unsigned long gp[MAX_REG_NR];
+ struct faultinfo faultinfo;
+ long syscall;
+ int is_user;
};
#define EMPTY_UML_PT_REGS { }
-extern int mode_tt;
-
-#define UPT_SC(r) ((r)->tt.sc)
-#define UPT_IP(r) \
- __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
-#define UPT_SP(r) \
- __CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
-#define UPT_EFLAGS(r) \
- __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
-#define UPT_EAX(r) \
- __CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
-#define UPT_EBX(r) \
- __CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
-#define UPT_ECX(r) \
- __CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
-#define UPT_EDX(r) \
- __CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
-#define UPT_ESI(r) \
- __CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
-#define UPT_EDI(r) \
- __CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
-#define UPT_EBP(r) \
- __CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
-#define UPT_ORIG_EAX(r) \
- __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
-#define UPT_CS(r) \
- __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
-#define UPT_SS(r) \
- __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
-#define UPT_DS(r) \
- __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
-#define UPT_ES(r) \
- __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
-#define UPT_FS(r) \
- __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
-#define UPT_GS(r) \
- __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
+#define UPT_IP(r) REGS_IP((r)->gp)
+#define UPT_SP(r) REGS_SP((r)->gp)
+#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp)
+#define UPT_EAX(r) REGS_EAX((r)->gp)
+#define UPT_EBX(r) REGS_EBX((r)->gp)
+#define UPT_ECX(r) REGS_ECX((r)->gp)
+#define UPT_EDX(r) REGS_EDX((r)->gp)
+#define UPT_ESI(r) REGS_ESI((r)->gp)
+#define UPT_EDI(r) REGS_EDI((r)->gp)
+#define UPT_EBP(r) REGS_EBP((r)->gp)
+#define UPT_ORIG_EAX(r) ((r)->syscall)
+#define UPT_CS(r) REGS_CS((r)->gp)
+#define UPT_SS(r) REGS_SS((r)->gp)
+#define UPT_DS(r) REGS_DS((r)->gp)
+#define UPT_ES(r) REGS_ES((r)->gp)
+#define UPT_FS(r) REGS_FS((r)->gp)
+#define UPT_GS(r) REGS_GS((r)->gp)
#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
@@ -134,20 +88,19 @@ extern int mode_tt;
extern int user_context(unsigned long sp);
-#define UPT_IS_USER(r) \
- CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
+#define UPT_IS_USER(r) ((r)->is_user)
struct syscall_args {
unsigned long args[6];
};
#define SYSCALL_ARGS(r) ((struct syscall_args) \
- { .args = { UPT_SYSCALL_ARG1(r), \
- UPT_SYSCALL_ARG2(r), \
- UPT_SYSCALL_ARG3(r), \
- UPT_SYSCALL_ARG4(r), \
- UPT_SYSCALL_ARG5(r), \
- UPT_SYSCALL_ARG6(r) } } )
+ { .args = { UPT_SYSCALL_ARG1(r), \
+ UPT_SYSCALL_ARG2(r), \
+ UPT_SYSCALL_ARG3(r), \
+ UPT_SYSCALL_ARG4(r), \
+ UPT_SYSCALL_ARG5(r), \
+ UPT_SYSCALL_ARG6(r) } } )
#define UPT_REG(regs, reg) \
({ unsigned long val; \
@@ -175,7 +128,6 @@ struct syscall_args {
} \
val; \
})
-
#define UPT_SET(regs, reg, val) \
do { \
@@ -204,29 +156,16 @@ struct syscall_args {
} while (0)
#define UPT_SET_SYSCALL_RETURN(r, res) \
- CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
- REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
+ REGS_SET_SYSCALL_RETURN((r)->regs, (res))
-#define UPT_RESTART_SYSCALL(r) \
- CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
- REGS_RESTART_SYSCALL((r)->skas.regs))
+#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp)
#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
#define UPT_SYSCALL_RET(r) UPT_EAX(r)
-#define UPT_FAULTINFO(r) \
- CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
+#define UPT_FAULTINFO(r) (&(r)->faultinfo)
-#endif
+extern void arch_init_registers(int pid);
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 23fd2644d7e..67e77122aa4 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -1,19 +1,15 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __SYS_SIGCONTEXT_I386_H
#define __SYS_SIGCONTEXT_I386_H
-#include "uml-config.h"
-#include <sysdep/sc.h>
+#include "sysdep/sc.h"
#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
-#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
-#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
-
#define GET_FAULTINFO_FROM_SC(fi,sc) \
{ \
(fi).cr2 = SC_CR2(sc); \
@@ -21,32 +17,10 @@
(fi).trap_no = SC_TRAPNO(sc); \
}
-/* ptrace expects that, at the start of a system call, %eax contains
- * -ENOSYS, so this makes it so.
- */
-#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
-
/* This is Page Fault */
#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */
-#ifdef UML_CONFIG_MODE_SKAS
#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo)
-#else
-#define SEGV_MAYBE_FIXABLE(fi) 0
-#endif
-
-extern unsigned long *sc_sigmask(void *sc_ptr);
-extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
index 4fffae75ba5..8c097b87fca 100644
--- a/arch/um/include/sysdep-i386/stub.h
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -9,7 +9,7 @@
#include <sys/mman.h>
#include <asm/ptrace.h>
#include <asm/unistd.h>
-#include <asm/page.h>
+#include "as-layout.h"
#include "stub-data.h"
#include "kern_constants.h"
#include "uml-config.h"
@@ -19,7 +19,7 @@ extern void stub_clone_handler(void);
#define STUB_SYSCALL_RET EAX
#define STUB_MMAP_NR __NR_mmap2
-#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
+#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT)
static inline long stub_syscall0(long syscall)
{
@@ -90,12 +90,12 @@ static inline void remap_stack(int fd, unsigned long offset)
{
__asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;"
"movl %7, %%ebx ; movl %%eax, (%%ebx)"
- : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA),
- "c" (UM_KERN_PAGE_SIZE),
+ : : "g" (STUB_MMAP_NR), "b" (STUB_DATA),
+ "c" (UM_KERN_PAGE_SIZE),
"d" (PROT_READ | PROT_WRITE),
- "S" (MAP_FIXED | MAP_SHARED), "D" (fd),
- "a" (offset),
- "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err)
+ "S" (MAP_FIXED | MAP_SHARED), "D" (fd),
+ "a" (offset),
+ "i" (&((struct stub_data *) STUB_DATA)->err)
: "memory");
}
diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h
deleted file mode 100644
index 243fed44d78..00000000000
--- a/arch/um/include/sysdep-i386/thread.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __UM_THREAD_H
-#define __UM_THREAD_H
-
-#include <kern_constants.h>
-
-#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS]))
-#ifdef UML_CONFIG_MODE_TT
-#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
-#endif
-
-#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 62403bd9966..9ea44d111f3 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -1,5 +1,6 @@
/*
* Copyright 2003 PathScale, Inc.
+ * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*
* Licensed under the GPL
*/
@@ -14,11 +15,6 @@
#define MAX_REG_OFFSET (UM_FRAME_SIZE)
#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
-#ifdef UML_CONFIG_MODE_TT
-#include "sysdep/sc.h"
-#endif
-
-#ifdef UML_CONFIG_MODE_SKAS
#include "skas_ptregs.h"
#define REGS_IP(r) ((r)[HOST_IP])
@@ -88,78 +84,51 @@
#define REGS_ERR(r) ((r)->fault_type)
-#endif
-
-#include "choose-mode.h"
-
-/* XXX */
-union uml_pt_regs {
-#ifdef UML_CONFIG_MODE_TT
- struct tt_regs {
- long syscall;
- unsigned long orig_rax;
- void *sc;
- struct faultinfo faultinfo;
- } tt;
-#endif
-#ifdef UML_CONFIG_MODE_SKAS
- struct skas_regs {
- unsigned long regs[MAX_REG_NR];
- unsigned long fp[HOST_FP_SIZE];
- struct faultinfo faultinfo;
- long syscall;
- int is_user;
- } skas;
-#endif
+struct uml_pt_regs {
+ unsigned long gp[MAX_REG_NR];
+ struct faultinfo faultinfo;
+ long syscall;
+ int is_user;
};
#define EMPTY_UML_PT_REGS { }
-/* XXX */
-extern int mode_tt;
-
-#define UPT_RBX(r) __CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs))
-#define UPT_RCX(r) __CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs))
-#define UPT_RDX(r) __CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs))
-#define UPT_RSI(r) __CHOOSE_MODE(SC_RSI(UPT_SC(r)), REGS_RSI((r)->skas.regs))
-#define UPT_RDI(r) __CHOOSE_MODE(SC_RDI(UPT_SC(r)), REGS_RDI((r)->skas.regs))
-#define UPT_RBP(r) __CHOOSE_MODE(SC_RBP(UPT_SC(r)), REGS_RBP((r)->skas.regs))
-#define UPT_RAX(r) __CHOOSE_MODE(SC_RAX(UPT_SC(r)), REGS_RAX((r)->skas.regs))
-#define UPT_R8(r) __CHOOSE_MODE(SC_R8(UPT_SC(r)), REGS_R8((r)->skas.regs))
-#define UPT_R9(r) __CHOOSE_MODE(SC_R9(UPT_SC(r)), REGS_R9((r)->skas.regs))
-#define UPT_R10(r) __CHOOSE_MODE(SC_R10(UPT_SC(r)), REGS_R10((r)->skas.regs))
-#define UPT_R11(r) __CHOOSE_MODE(SC_R11(UPT_SC(r)), REGS_R11((r)->skas.regs))
-#define UPT_R12(r) __CHOOSE_MODE(SC_R12(UPT_SC(r)), REGS_R12((r)->skas.regs))
-#define UPT_R13(r) __CHOOSE_MODE(SC_R13(UPT_SC(r)), REGS_R13((r)->skas.regs))
-#define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs))
-#define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs))
-#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
-#define UPT_FS_BASE(r) \
- __CHOOSE_MODE(SC_FS_BASE(UPT_SC(r)), REGS_FS_BASE((r)->skas.regs))
-#define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
-#define UPT_GS_BASE(r) \
- __CHOOSE_MODE(SC_GS_BASE(UPT_SC(r)), REGS_GS_BASE((r)->skas.regs))
-#define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
-#define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
-#define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
-#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
-#define UPT_SS(r) __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
-#define UPT_ORIG_RAX(r) \
- __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs))
-
-#define UPT_IP(r) __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
-#define UPT_SP(r) __CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
-
-#define UPT_EFLAGS(r) \
- __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
-#define UPT_SC(r) ((r)->tt.sc)
-#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
+#define UPT_RBX(r) REGS_RBX((r)->gp)
+#define UPT_RCX(r) REGS_RCX((r)->gp)
+#define UPT_RDX(r) REGS_RDX((r)->gp)
+#define UPT_RSI(r) REGS_RSI((r)->gp)
+#define UPT_RDI(r) REGS_RDI((r)->gp)
+#define UPT_RBP(r) REGS_RBP((r)->gp)
+#define UPT_RAX(r) REGS_RAX((r)->gp)
+#define UPT_R8(r) REGS_R8((r)->gp)
+#define UPT_R9(r) REGS_R9((r)->gp)
+#define UPT_R10(r) REGS_R10((r)->gp)
+#define UPT_R11(r) REGS_R11((r)->gp)
+#define UPT_R12(r) REGS_R12((r)->gp)
+#define UPT_R13(r) REGS_R13((r)->gp)
+#define UPT_R14(r) REGS_R14((r)->gp)
+#define UPT_R15(r) REGS_R15((r)->gp)
+#define UPT_CS(r) REGS_CS((r)->gp)
+#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp)
+#define UPT_FS(r) REGS_FS((r)->gp)
+#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp)
+#define UPT_GS(r) REGS_GS((r)->gp)
+#define UPT_DS(r) REGS_DS((r)->gp)
+#define UPT_ES(r) REGS_ES((r)->gp)
+#define UPT_CS(r) REGS_CS((r)->gp)
+#define UPT_SS(r) REGS_SS((r)->gp)
+#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp)
+
+#define UPT_IP(r) REGS_IP((r)->gp)
+#define UPT_SP(r) REGS_SP((r)->gp)
+
+#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp)
+#define UPT_SYSCALL_NR(r) ((r)->syscall)
#define UPT_SYSCALL_RET(r) UPT_RAX(r)
extern int user_context(unsigned long sp);
-#define UPT_IS_USER(r) \
- CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
+#define UPT_IS_USER(r) ((r)->is_user)
#define UPT_SYSCALL_ARG1(r) UPT_RDI(r)
#define UPT_SYSCALL_ARG2(r) UPT_RSI(r)
@@ -173,101 +142,99 @@ struct syscall_args {
};
#define SYSCALL_ARGS(r) ((struct syscall_args) \
- { .args = { UPT_SYSCALL_ARG1(r), \
- UPT_SYSCALL_ARG2(r), \
- UPT_SYSCALL_ARG3(r), \
- UPT_SYSCALL_ARG4(r), \
- UPT_SYSCALL_ARG5(r), \
- UPT_SYSCALL_ARG6(r) } } )
+ { .args = { UPT_SYSCALL_ARG1(r), \
+ UPT_SYSCALL_ARG2(r), \
+ UPT_SYSCALL_ARG3(r), \
+ UPT_SYSCALL_ARG4(r), \
+ UPT_SYSCALL_ARG5(r), \
+ UPT_SYSCALL_ARG6(r) } } )
#define UPT_REG(regs, reg) \
- ({ unsigned long val; \
- switch(reg){ \
- case R8: val = UPT_R8(regs); break; \
- case R9: val = UPT_R9(regs); break; \
- case R10: val = UPT_R10(regs); break; \
- case R11: val = UPT_R11(regs); break; \
- case R12: val = UPT_R12(regs); break; \
- case R13: val = UPT_R13(regs); break; \
- case R14: val = UPT_R14(regs); break; \
- case R15: val = UPT_R15(regs); break; \
- case RIP: val = UPT_IP(regs); break; \
- case RSP: val = UPT_SP(regs); break; \
- case RAX: val = UPT_RAX(regs); break; \
- case RBX: val = UPT_RBX(regs); break; \
- case RCX: val = UPT_RCX(regs); break; \
- case RDX: val = UPT_RDX(regs); break; \
- case RSI: val = UPT_RSI(regs); break; \
- case RDI: val = UPT_RDI(regs); break; \
- case RBP: val = UPT_RBP(regs); break; \
- case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
- case CS: val = UPT_CS(regs); break; \
- case SS: val = UPT_SS(regs); break; \
- case FS_BASE: val = UPT_FS_BASE(regs); break; \
- case GS_BASE: val = UPT_GS_BASE(regs); break; \
- case DS: val = UPT_DS(regs); break; \
- case ES: val = UPT_ES(regs); break; \
- case FS : val = UPT_FS (regs); break; \
- case GS: val = UPT_GS(regs); break; \
- case EFLAGS: val = UPT_EFLAGS(regs); break; \
- default : \
- panic("Bad register in UPT_REG : %d\n", reg); \
- val = -1; \
- } \
- val; \
- })
+ ({ unsigned long val; \
+ switch(reg){ \
+ case R8: val = UPT_R8(regs); break; \
+ case R9: val = UPT_R9(regs); break; \
+ case R10: val = UPT_R10(regs); break; \
+ case R11: val = UPT_R11(regs); break; \
+ case R12: val = UPT_R12(regs); break; \
+ case R13: val = UPT_R13(regs); break; \
+ case R14: val = UPT_R14(regs); break; \
+ case R15: val = UPT_R15(regs); break; \
+ case RIP: val = UPT_IP(regs); break; \
+ case RSP: val = UPT_SP(regs); break; \
+ case RAX: val = UPT_RAX(regs); break; \
+ case RBX: val = UPT_RBX(regs); break; \
+ case RCX: val = UPT_RCX(regs); break; \
+ case RDX: val = UPT_RDX(regs); break; \
+ case RSI: val = UPT_RSI(regs); break; \
+ case RDI: val = UPT_RDI(regs); break; \
+ case RBP: val = UPT_RBP(regs); break; \
+ case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
+ case CS: val = UPT_CS(regs); break; \
+ case SS: val = UPT_SS(regs); break; \
+ case FS_BASE: val = UPT_FS_BASE(regs); break; \
+ case GS_BASE: val = UPT_GS_BASE(regs); break; \
+ case DS: val = UPT_DS(regs); break; \
+ case ES: val = UPT_ES(regs); break; \
+ case FS : val = UPT_FS (regs); break; \
+ case GS: val = UPT_GS(regs); break; \
+ case EFLAGS: val = UPT_EFLAGS(regs); break; \
+ default : \
+ panic("Bad register in UPT_REG : %d\n", reg); \
+ val = -1; \
+ } \
+ val; \
+ })
#define UPT_SET(regs, reg, val) \
- ({ unsigned long __upt_val = val; \
- switch(reg){ \
- case R8: UPT_R8(regs) = __upt_val; break; \
- case R9: UPT_R9(regs) = __upt_val; break; \
- case R10: UPT_R10(regs) = __upt_val; break; \
- case R11: UPT_R11(regs) = __upt_val; break; \
- case R12: UPT_R12(regs) = __upt_val; break; \
- case R13: UPT_R13(regs) = __upt_val; break; \
- case R14: UPT_R14(regs) = __upt_val; break; \
- case R15: UPT_R15(regs) = __upt_val; break; \
- case RIP: UPT_IP(regs) = __upt_val; break; \
- case RSP: UPT_SP(regs) = __upt_val; break; \
- case RAX: UPT_RAX(regs) = __upt_val; break; \
- case RBX: UPT_RBX(regs) = __upt_val; break; \
- case RCX: UPT_RCX(regs) = __upt_val; break; \
- case RDX: UPT_RDX(regs) = __upt_val; break; \
- case RSI: UPT_RSI(regs) = __upt_val; break; \
- case RDI: UPT_RDI(regs) = __upt_val; break; \
- case RBP: UPT_RBP(regs) = __upt_val; break; \
- case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
- case CS: UPT_CS(regs) = __upt_val; break; \
- case SS: UPT_SS(regs) = __upt_val; break; \
- case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \
- case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \
- case DS: UPT_DS(regs) = __upt_val; break; \
- case ES: UPT_ES(regs) = __upt_val; break; \
- case FS: UPT_FS(regs) = __upt_val; break; \
- case GS: UPT_GS(regs) = __upt_val; break; \
- case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
- default : \
- panic("Bad register in UPT_SET : %d\n", reg); \
- break; \
- } \
- __upt_val; \
- })
+ ({ unsigned long __upt_val = val; \
+ switch(reg){ \
+ case R8: UPT_R8(regs) = __upt_val; break; \
+ case R9: UPT_R9(regs) = __upt_val; break; \
+ case R10: UPT_R10(regs) = __upt_val; break; \
+ case R11: UPT_R11(regs) = __upt_val; break; \
+ case R12: UPT_R12(regs) = __upt_val; break; \
+ case R13: UPT_R13(regs) = __upt_val; break; \
+ case R14: UPT_R14(regs) = __upt_val; break; \
+ case R15: UPT_R15(regs) = __upt_val; break; \
+ case RIP: UPT_IP(regs) = __upt_val; break; \
+ case RSP: UPT_SP(regs) = __upt_val; break; \
+ case RAX: UPT_RAX(regs) = __upt_val; break; \
+ case RBX: UPT_RBX(regs) = __upt_val; break; \
+ case RCX: UPT_RCX(regs) = __upt_val; break; \
+ case RDX: UPT_RDX(regs) = __upt_val; break; \
+ case RSI: UPT_RSI(regs) = __upt_val; break; \
+ case RDI: UPT_RDI(regs) = __upt_val; break; \
+ case RBP: UPT_RBP(regs) = __upt_val; break; \
+ case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
+ case CS: UPT_CS(regs) = __upt_val; break; \
+ case SS: UPT_SS(regs) = __upt_val; break; \
+ case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \
+ case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \
+ case DS: UPT_DS(regs) = __upt_val; break; \
+ case ES: UPT_ES(regs) = __upt_val; break; \
+ case FS: UPT_FS(regs) = __upt_val; break; \
+ case GS: UPT_GS(regs) = __upt_val; break; \
+ case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
+ default : \
+ panic("Bad register in UPT_SET : %d\n", reg); \
+ break; \
+ } \
+ __upt_val; \
+ })
#define UPT_SET_SYSCALL_RETURN(r, res) \
- CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
- REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
+ REGS_SET_SYSCALL_RETURN((r)->regs, (res))
+
+#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp)
-#define UPT_RESTART_SYSCALL(r) \
- CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
- REGS_RESTART_SYSCALL((r)->skas.regs))
+#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas)
-#define UPT_SEGV_IS_FIXABLE(r) \
- CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
- REGS_SEGV_IS_FIXABLE(&r->skas))
+#define UPT_FAULTINFO(r) (&(r)->faultinfo)
-#define UPT_FAULTINFO(r) \
- CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
+static inline void arch_init_registers(int pid)
+{
+}
#endif
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 41073235e7a..0155133b145 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -11,43 +11,17 @@
#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
-#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
-#define SC_SET_SYSCALL_RETURN(sc, result) SC_RAX(sc) = (result)
-
-#define SC_FAULT_ADDR(sc) SC_CR2(sc)
-#define SC_FAULT_TYPE(sc) SC_ERR(sc)
-
-#define GET_FAULTINFO_FROM_SC(fi,sc) \
+#define GET_FAULTINFO_FROM_SC(fi, sc) \
{ \
(fi).cr2 = SC_CR2(sc); \
(fi).error_code = SC_ERR(sc); \
(fi).trap_no = SC_TRAPNO(sc); \
}
-/* ptrace expects that, at the start of a system call, %eax contains
- * -ENOSYS, so this makes it so.
- */
-
-#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
-
/* This is Page Fault */
#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
/* No broken SKAS API, which doesn't pass trap_no, here. */
#define SEGV_MAYBE_FIXABLE(fi) 0
-extern unsigned long *sc_sigmask(void *sc_ptr);
-
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
-
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
index 92e989f8176..655f9c2de3a 100644
--- a/arch/um/include/sysdep-x86_64/stub.h
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -9,6 +9,7 @@
#include <sys/mman.h>
#include <asm/unistd.h>
#include <sysdep/ptrace_user.h>
+#include "as-layout.h"
#include "stub-data.h"
#include "kern_constants.h"
#include "uml-config.h"
@@ -94,13 +95,13 @@ static inline void remap_stack(long fd, unsigned long offset)
{
__asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; "
"movq %6, %%r9; " __syscall "; movq %7, %%rbx ; "
- "movq %%rax, (%%rbx)":
- : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA),
- "S" (UM_KERN_PAGE_SIZE),
- "d" (PROT_READ | PROT_WRITE),
- "g" (MAP_FIXED | MAP_SHARED), "g" (fd),
+ "movq %%rax, (%%rbx)":
+ : "a" (STUB_MMAP_NR), "D" (STUB_DATA),
+ "S" (UM_KERN_PAGE_SIZE),
+ "d" (PROT_READ | PROT_WRITE),
+ "g" (MAP_FIXED | MAP_SHARED), "g" (fd),
"g" (offset),
- "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err)
+ "i" (&((struct stub_data *) STUB_DATA)->err)
: __syscall_clobber, "r10", "r8", "r9" );
}
diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h
deleted file mode 100644
index cbef3e1697f..00000000000
--- a/arch/um/include/sysdep-x86_64/thread.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __UM_THREAD_H
-#define __UM_THREAD_H
-
-#include <kern_constants.h>
-
-#ifdef UML_CONFIG_MODE_TT
-#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
-#endif
-
-#endif
diff --git a/arch/um/include/task.h b/arch/um/include/task.h
index 6375ba7203c..3fe726b3cf4 100644
--- a/arch/um/include/task.h
+++ b/arch/um/include/task.h
@@ -3,7 +3,7 @@
#include <kern_constants.h>
-#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
+#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
#endif
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index bcd1a4afb84..ecd2265b301 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -8,34 +8,7 @@
#include "um_mmu.h"
-struct host_vm_op {
- enum { NONE, MMAP, MUNMAP, MPROTECT } type;
- union {
- struct {
- unsigned long addr;
- unsigned long len;
- unsigned int prot;
- int fd;
- __u64 offset;
- } mmap;
- struct {
- unsigned long addr;
- unsigned long len;
- } munmap;
- struct {
- unsigned long addr;
- unsigned long len;
- unsigned int prot;
- } mprotect;
- } u;
-};
-
extern void force_flush_all(void);
-extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force,
- int (*do_ops)(union mm_context *,
- struct host_vm_op *, int, int,
- void **));
extern int flush_tlb_kernel_range_common(unsigned long start,
unsigned long end);
diff --git a/arch/um/include/tt/debug.h b/arch/um/include/tt/debug.h
deleted file mode 100644
index 9778fa83829..00000000000
--- a/arch/um/include/tt/debug.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
- * Lars Brinkhoff.
- * Licensed under the GPL
- */
-
-#ifndef __UML_TT_DEBUG_H
-#define __UML_TT_DEBUG_H
-
-extern int debugger_proxy(int status, pid_t pid);
-extern void child_proxy(pid_t pid, int status);
-extern void init_proxy (pid_t pid, int waiting, int status);
-extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
-extern void fake_child_exit(void);
-extern int gdb_config(char *str);
-extern int gdb_remove(int unused);
-
-#endif
diff --git a/arch/um/include/tt/mmu-tt.h b/arch/um/include/tt/mmu-tt.h
deleted file mode 100644
index 572a78b2258..00000000000
--- a/arch/um/include/tt/mmu-tt.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_MMU_H
-#define __TT_MMU_H
-
-struct mmu_context_tt {
-};
-
-#endif
diff --git a/arch/um/include/tt/mode-tt.h b/arch/um/include/tt/mode-tt.h
deleted file mode 100644
index 2823cd56eea..00000000000
--- a/arch/um/include/tt/mode-tt.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __MODE_TT_H__
-#define __MODE_TT_H__
-
-#include "sysdep/ptrace.h"
-
-enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
-
-extern int tracing_pid;
-
-extern int tracer(int (*init_proc)(void *), void *sp);
-extern void sig_handler_common_tt(int sig, void *sc);
-extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
-extern void reboot_tt(void);
-extern void halt_tt(void);
-extern int is_tracer_winch(int pid, int fd, void *data);
-extern void kill_off_processes_tt(void);
-
-#endif
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
deleted file mode 100644
index a4fc6305719..00000000000
--- a/arch/um/include/tt/mode_kern_tt.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_MODE_KERN_H__
-#define __TT_MODE_KERN_H__
-
-#include "linux/sched.h"
-#include "asm/page.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-
-extern void switch_to_tt(void *prev, void *next);
-extern void flush_thread_tt(void);
-extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
- unsigned long esp);
-extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct *p,
- struct pt_regs *regs);
-extern void release_thread_tt(struct task_struct *task);
-extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
-extern void init_idle_tt(void);
-extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
-extern void flush_tlb_kernel_vm_tt(void);
-extern void __flush_tlb_one_tt(unsigned long addr);
-extern void flush_tlb_range_tt(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-extern void flush_tlb_mm_tt(struct mm_struct *mm);
-extern void force_flush_all_tt(void);
-extern long execute_syscall_tt(void *r);
-extern void before_mem_tt(unsigned long brk_start);
-extern unsigned long set_task_sizes_tt(unsigned long *task_size_out);
-extern int start_uml_tt(void);
-extern int external_pid_tt(struct task_struct *task);
-extern int thread_pid_tt(struct task_struct *task);
-
-#define kmem_end_tt (host_task_size - ABOVE_KMEM)
-
-#endif
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h
deleted file mode 100644
index acb8356e1f9..00000000000
--- a/arch/um/include/tt/tt.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_H__
-#define __TT_H__
-
-#include "sysdep/ptrace.h"
-
-extern int gdb_pid;
-extern int debug;
-extern int debug_stop;
-extern int debug_trace;
-
-extern int honeypot;
-
-extern int fork_tramp(void *sig_stack);
-extern int do_proc_op(void *t, int proc_id);
-extern int tracer(int (*init_proc)(void *), void *sp);
-extern void attach_process(int pid);
-extern void tracer_panic(char *format, ...)
- __attribute__ ((format (printf, 1, 2)));
-extern void set_init_pid(int pid);
-extern int set_user_mode(void *task);
-extern void set_tracing(void *t, int tracing);
-extern int is_tracing(void *task);
-extern void syscall_handler(int sig, union uml_pt_regs *regs);
-extern void exit_kernel(int pid, void *task);
-extern void do_syscall(void *task, int pid, int local_using_sysemu);
-extern void do_sigtrap(void *task);
-extern int is_valid_pid(int pid);
-extern void remap_data(void *segment_start, void *segment_end, int w);
-extern long execute_syscall_tt(void *r);
-
-#endif
-
diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
deleted file mode 100644
index 13a64f61fcf..00000000000
--- a/arch/um/include/tt/uaccess-tt.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_UACCESS_H
-#define __TT_UACCESS_H
-
-#include "linux/string.h"
-#include "linux/sched.h"
-#include "asm/processor.h"
-#include "asm/errno.h"
-#include "asm/current.h"
-#include "asm/a.out.h"
-#include "uml_uaccess.h"
-
-#define ABOVE_KMEM (16 * 1024 * 1024)
-
-extern unsigned long end_vm;
-extern unsigned long uml_physmem;
-
-#define is_stack(addr, size) \
- (((unsigned long) (addr) < STACK_TOP) && \
- ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
- (((unsigned long) (addr) + (size)) <= STACK_TOP))
-
-#define access_ok_tt(type, addr, size) \
- (is_stack(addr, size))
-
-extern int __do_copy_from_user(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher);
-extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
- void **fault_addr, void **fault_catcher);
-extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
- void **fault_catcher);
-extern int __do_strnlen_user(const char *str, unsigned long n,
- void **fault_addr, void **fault_catcher);
-
-extern int copy_from_user_tt(void *to, const void __user *from, int n);
-extern int copy_to_user_tt(void __user *to, const void *from, int n);
-extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
-extern int __clear_user_tt(void __user *mem, int len);
-extern int clear_user_tt(void __user *mem, int len);
-extern int strnlen_user_tt(const void __user *str, int len);
-
-#endif
diff --git a/arch/um/include/um_mmu.h b/arch/um/include/um_mmu.h
index 0fa64323830..8855d8df512 100644
--- a/arch/um/include/um_mmu.h
+++ b/arch/um/include/um_mmu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -7,34 +7,22 @@
#define __ARCH_UM_MMU_H
#include "uml-config.h"
-#include "choose-mode.h"
+#include "mm_id.h"
+#include "asm/ldt.h"
-#ifdef UML_CONFIG_MODE_TT
-#include "mmu-tt.h"
+typedef struct mm_context {
+ struct mm_id id;
+ unsigned long last_page_table;
+#ifdef CONFIG_3_LEVEL_PGTABLES
+ unsigned long last_pmd;
#endif
+ struct uml_ldt ldt;
+} mm_context_t;
-#ifdef UML_CONFIG_MODE_SKAS
-#include "mmu-skas.h"
-#endif
+extern void __switch_mm(struct mm_id * mm_idp);
-typedef union mm_context {
-#ifdef UML_CONFIG_MODE_TT
- struct mmu_context_tt tt;
-#endif
-#ifdef UML_CONFIG_MODE_SKAS
- struct mmu_context_skas skas;
-#endif
-} mm_context_t;
+/* Avoid tangled inclusion with asm/ldt.h */
+extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm);
+extern void free_ldt(struct mm_context *mm);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index 5126a99b596..fdfc06b8560 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -1,26 +1,16 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#ifndef __ARCH_UM_UACCESS_H
#define __ARCH_UM_UACCESS_H
-#include "choose-mode.h"
-
-#ifdef CONFIG_MODE_TT
-#include "uaccess-tt.h"
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-#include "uaccess-skas.h"
-#endif
-
#include "asm/fixmap.h"
#define __under_task_size(addr, size) \
(((unsigned long) (addr) < TASK_SIZE) && \
- (((unsigned long) (addr) + (size)) < TASK_SIZE))
+ (((unsigned long) (addr) + (size)) < TASK_SIZE))
#define __access_ok_vsyscall(type, addr, size) \
((type == VERIFY_READ) && \
@@ -35,20 +25,14 @@
(__addr_range_nowrap(addr, size) && \
(__under_task_size(addr, size) || \
__access_ok_vsyscall(type, addr, size) || \
- segment_eq(get_fs(), KERNEL_DS) || \
- CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)))
+ segment_eq(get_fs(), KERNEL_DS)))
-static inline int copy_from_user(void *to, const void __user *from, int n)
-{
- return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
- from, n));
-}
+extern int copy_from_user(void *to, const void __user *from, int n);
+extern int copy_to_user(void __user *to, const void *from, int n);
-static inline int copy_to_user(void __user *to, const void *from, int n)
-{
- return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to,
- from, n));
-}
+extern int __do_copy_to_user(void *to, const void *from, int n,
+ void **fault_addr, jmp_buf **fault_catcher);
+extern void __do_copy(void *to, const void *from, int n);
/*
* strncpy_from_user: - Copy a NUL terminated string from userspace.
@@ -69,11 +53,7 @@ static inline int copy_to_user(void __user *to, const void *from, int n)
* and returns @count.
*/
-static inline int strncpy_from_user(char *dst, const char __user *src, int count)
-{
- return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
- dst, src, count));
-}
+extern int strncpy_from_user(char *dst, const char __user *src, int count);
/*
* __clear_user: - Zero a block of memory in user space, with less checking.
@@ -86,10 +66,7 @@ static inline int strncpy_from_user(char *dst, const char __user *src, int count
* Returns number of bytes that could not be cleared.
* On success, this will be zero.
*/
-static inline int __clear_user(void *mem, int len)
-{
- return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
-}
+extern int __clear_user(void __user *mem, int len);
/*
* clear_user: - Zero a block of memory in user space.
@@ -101,10 +78,7 @@ static inline int __clear_user(void *mem, int len)
* Returns number of bytes that could not be cleared.
* On success, this will be zero.
*/
-static inline int clear_user(void __user *mem, int len)
-{
- return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
-}
+extern int clear_user(void __user *mem, int len);
/*
* strlen_user: - Get the size of a string in user space.
@@ -117,20 +91,6 @@ static inline int clear_user(void __user *mem, int len)
* On exception, returns 0.
* If the string is too long, returns a value greater than @n.
*/
-static inline int strnlen_user(const void __user *str, long len)
-{
- return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
-}
+extern int strnlen_user(const void __user *str, int len);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
deleted file mode 100644
index c0df11d06f5..00000000000
--- a/arch/um/include/uml_uaccess.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UML_UACCESS_H__
-#define __UML_UACCESS_H__
-
-extern int __do_copy_to_user(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher);
-void __do_copy(void *to, const void *from, int n);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index d380e6d91a9..99033ff28a7 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -14,10 +14,12 @@
*/
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-/*
- * This will provide the size_t definition in both kernel and userspace builds
- */
+/* This is to get size_t */
+#ifdef __KERNEL__
#include <linux/types.h>
+#else
+#include <stddef.h>
+#endif
extern void panic(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index c5cf4a0827b..499e5e95e60 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux,intel}.com)
# Licensed under the GPL
#
@@ -9,15 +9,12 @@ clean-files :=
obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
physmem.o process.o ptrace.o reboot.o sigio.o \
signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
- um_arch.o umid.o
+ um_arch.o umid.o skas/
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
obj-$(CONFIG_GPROF) += gprof_syms.o
obj-$(CONFIG_GCOV) += gmon_syms.o
-obj-$(CONFIG_MODE_TT) += tt/
-obj-$(CONFIG_MODE_SKAS) += skas/
-
USER_OBJS := config.o
include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 41850906116..3866f4960f0 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -10,8 +10,6 @@ SECTIONS
PROVIDE (__executable_start = START);
. = START + SIZEOF_HEADERS;
.interp : { *(.interp) }
- /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
- * is remapped.*/
__binary_start = .;
. = ALIGN(4096); /* Init code and data */
_text = .;
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index ce6828fd396..8196450451c 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -1,35 +1,44 @@
/*
- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/slab.h"
+#include "linux/stddef.h"
+#include "linux/fs.h"
#include "linux/smp_lock.h"
#include "linux/ptrace.h"
-#include "linux/fs.h"
-#include "asm/ptrace.h"
-#include "asm/pgtable.h"
-#include "asm/tlbflush.h"
+#include "linux/sched.h"
+#include "asm/current.h"
+#include "asm/processor.h"
#include "asm/uaccess.h"
-#include "kern_util.h"
#include "as-layout.h"
#include "mem_user.h"
-#include "kern.h"
-#include "irq_user.h"
-#include "tlb.h"
+#include "skas.h"
#include "os.h"
-#include "choose-mode.h"
-#include "mode_kern.h"
void flush_thread(void)
{
+ void *data = NULL;
+ unsigned long end = proc_mm ? task_size : STUB_START;
+ int ret;
+
arch_flush_thread(&current->thread.arch);
- CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
+
+ ret = unmap(&current->mm->context.id, 0, end, 1, &data);
+ if (ret) {
+ printk(KERN_ERR "flush_thread - clearing address space failed, "
+ "err = %d\n", ret);
+ force_sig(SIGKILL, current);
+ }
+
+ __switch_mm(&current->mm->context.id);
}
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
{
- CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
+ set_fs(USER_DS);
+ PT_REGS_IP(regs) = eip;
+ PT_REGS_SP(regs) = esp;
}
#ifdef CONFIG_TTY_LOG
@@ -39,7 +48,7 @@ extern void log_exec(char **argv, void *tty);
static long execve1(char *file, char __user * __user *argv,
char __user *__user *env)
{
- long error;
+ long error;
#ifdef CONFIG_TTY_LOG
struct tty_struct *tty;
@@ -49,17 +58,16 @@ static long execve1(char *file, char __user * __user *argv,
log_exec(argv, tty);
mutex_unlock(&tty_mutex);
#endif
- error = do_execve(file, argv, env, &current->thread.regs);
- if (error == 0){
+ error = do_execve(file, argv, env, &current->thread.regs);
+ if (error == 0) {
task_lock(current);
- current->ptrace &= ~PT_DTRACE;
+ current->ptrace &= ~PT_DTRACE;
#ifdef SUBARCH_EXECVE1
SUBARCH_EXECVE1(&current->thread.regs.regs);
#endif
task_unlock(current);
- set_cmdline(current_cmd());
- }
- return(error);
+ }
+ return error;
}
long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
@@ -67,9 +75,9 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
long err;
err = execve1(file, argv, env);
- if(!err)
- do_longjmp(current->thread.exec_buf, 1);
- return(err);
+ if (!err)
+ UML_LONGJMP(current->thread.exec_buf, 1);
+ return err;
}
long sys_execve(char __user *file, char __user *__user *argv,
@@ -86,5 +94,5 @@ long sys_execve(char __user *file, char __user *__user *argv,
putname(filename);
out:
unlock_kernel();
- return(error);
+ return error;
}
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index cba516e6c99..dcfceca9505 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -3,16 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/mm.h"
-#include "linux/fs.h"
-#include "linux/module.h"
#include "linux/sched.h"
#include "linux/init_task.h"
+#include "linux/fs.h"
+#include "linux/module.h"
#include "linux/mqueue.h"
#include "asm/uaccess.h"
-#include "asm/pgtable.h"
-#include "mem_user.h"
-#include "os.h"
static struct fs_struct init_fs = INIT_FS;
struct mm_struct init_mm = INIT_MM(init_mm);
@@ -46,8 +42,3 @@ union thread_union init_thread_union
union thread_union cpu0_irqstack
__attribute__((__section__(".data.init_irqstack"))) =
{ INIT_THREAD_INFO(init_task) };
-
-void unprotect_stack(unsigned long stack)
-{
- os_protect_memory((void *) stack, THREAD_SIZE, 1, 1, 0);
-}
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index cf0dd9cf8c4..277fce17b08 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -1,37 +1,19 @@
/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
* Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
* Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
*/
-#include "linux/kernel.h"
-#include "linux/module.h"
-#include "linux/smp.h"
-#include "linux/kernel_stat.h"
+#include "linux/cpumask.h"
+#include "linux/hardirq.h"
#include "linux/interrupt.h"
-#include "linux/random.h"
-#include "linux/slab.h"
-#include "linux/file.h"
-#include "linux/proc_fs.h"
-#include "linux/init.h"
+#include "linux/kernel_stat.h"
+#include "linux/module.h"
#include "linux/seq_file.h"
-#include "linux/profile.h"
-#include "linux/hardirq.h"
-#include "asm/irq.h"
-#include "asm/hw_irq.h"
-#include "asm/atomic.h"
-#include "asm/signal.h"
-#include "asm/system.h"
-#include "asm/errno.h"
-#include "asm/uaccess.h"
+#include "as-layout.h"
#include "kern_util.h"
-#include "irq_user.h"
-#include "irq_kern.h"
#include "os.h"
-#include "sigio.h"
-#include "misc_constants.h"
-#include "as-layout.h"
/*
* Generic, controller-independent functions:
@@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
+ } else if (i == NR_IRQS)
seq_putc(p, '\n');
- }
return 0;
}
@@ -91,7 +72,7 @@ static struct irq_fd **last_irq_ptr = &active_fds;
extern void free_irqs(void);
-void sigio_handler(int sig, union uml_pt_regs *regs)
+void sigio_handler(int sig, struct uml_pt_regs *regs)
{
struct irq_fd *irq_fd;
int n;
@@ -102,11 +83,13 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
while (1) {
n = os_waiting_for_events(active_fds);
if (n <= 0) {
- if(n == -EINTR) continue;
+ if (n == -EINTR)
+ continue;
else break;
}
- for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
+ for (irq_fd = active_fds; irq_fd != NULL;
+ irq_fd = irq_fd->next) {
if (irq_fd->current_events != 0) {
irq_fd->current_events = 0;
do_IRQ(irq_fd->irq, regs);
@@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
if (type == IRQ_READ)
events = UM_POLLIN | UM_POLLPRI;
- else
- events = UM_POLLOUT;
+ else events = UM_POLLOUT;
*new_fd = ((struct irq_fd) { .next = NULL,
.id = dev_id,
.fd = fd,
@@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
spin_lock_irqsave(&irq_lock, flags);
for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
- printk("Registering fd %d twice\n", fd);
- printk("Irqs : %d, %d\n", irq_fd->irq, irq);
- printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
+ printk(KERN_ERR "Registering fd %d twice\n", fd);
+ printk(KERN_ERR "Irqs : %d, %d\n", irq_fd->irq, irq);
+ printk(KERN_ERR "Ids : 0x%p, 0x%p\n", irq_fd->id,
+ dev_id);
goto out_unlock;
}
}
@@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
if (n == 0)
break;
- /* n > 0
+ /*
+ * n > 0
* It means we couldn't put new pollfd to current pollfds
* and tmp_fds is NULL or too small for new pollfds array.
* Needed size is equal to n as minimum.
@@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
spin_unlock_irqrestore(&irq_lock, flags);
- /* This calls activate_fd, so it has to be outside the critical
+ /*
+ * This calls activate_fd, so it has to be outside the critical
* section.
*/
maybe_sigio_broken(fd, (type == IRQ_READ));
@@ -264,13 +249,14 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
i++;
}
if (irq == NULL) {
- printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
+ printk(KERN_ERR "find_irq_by_fd doesn't have descriptor %d\n",
+ fd);
goto out;
}
fdi = os_get_pollfd(i);
if ((fdi != -1) && (fdi != fd)) {
- printk("find_irq_by_fd - mismatch between active_fds and "
- "pollfds, fd %d vs %d, need %d\n", irq->fd,
+ printk(KERN_ERR "find_irq_by_fd - mismatch between active_fds "
+ "and pollfds, fd %d vs %d, need %d\n", irq->fd,
fdi, fd);
irq = NULL;
goto out;
@@ -306,7 +292,7 @@ void deactivate_fd(int fd, int irqnum)
spin_lock_irqsave(&irq_lock, flags);
irq = find_irq_by_fd(fd, irqnum, &i);
- if(irq == NULL){
+ if (irq == NULL) {
spin_unlock_irqrestore(&irq_lock, flags);
return;
}
@@ -339,36 +325,12 @@ int deactivate_all_fds(void)
return 0;
}
-#ifdef CONFIG_MODE_TT
-void forward_interrupts(int pid)
-{
- struct irq_fd *irq;
- unsigned long flags;
- int err;
-
- spin_lock_irqsave(&irq_lock, flags);
- for (irq = active_fds; irq != NULL; irq = irq->next) {
- err = os_set_owner(irq->fd, pid);
- if (err < 0) {
- /* XXX Just remove the irq rather than
- * print out an infinite stream of these
- */
- printk("Failed to forward %d to pid %d, err = %d\n",
- irq->fd, pid, -err);
- }
-
- irq->pid = pid;
- }
- spin_unlock_irqrestore(&irq_lock, flags);
-}
-#endif
-
/*
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
*/
-unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
+unsigned int do_IRQ(int irq, struct uml_pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs);
irq_enter();
@@ -396,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type,
EXPORT_SYMBOL(um_request_irq);
EXPORT_SYMBOL(reactivate_fd);
-/* hw_interrupt_type must define (startup || enable) &&
- * (shutdown || disable) && end */
+/*
+ * hw_interrupt_type must define (startup || enable) &&
+ * (shutdown || disable) && end
+ */
static void dummy(unsigned int irq)
{
}
@@ -446,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
err = os_pipe(fds, 1, 1);
if (err) {
- printk("init_aio_irq - os_pipe failed, err = %d\n", -err);
+ printk(KERN_ERR "init_aio_irq - os_pipe failed, err = %d\n",
+ -err);
goto out;
}
@@ -454,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name,
(void *) (long) fds[0]);
if (err) {
- printk("init_aio_irq - : um_request_irq failed, err = %d\n",
+ printk(KERN_ERR "init_aio_irq - : um_request_irq failed, "
+ "err = %d\n",
err);
goto out_close;
}
@@ -525,8 +491,9 @@ unsigned long to_irq_stack(unsigned long *mask_out)
int nested;
mask = xchg(&pending_mask, *mask_out);
- if(mask != 0){
- /* If any interrupts come in at this point, we want to
+ if (mask != 0) {
+ /*
+ * If any interrupts come in at this point, we want to
* make sure that their bits aren't lost by our
* putting our bit in. So, this loop accumulates bits
* until xchg returns the same value that we put in.
@@ -538,13 +505,13 @@ unsigned long to_irq_stack(unsigned long *mask_out)
do {
old |= mask;
mask = xchg(&pending_mask, old);
- } while(mask != old);
+ } while (mask != old);
return 1;
}
ti = current_thread_info();
nested = (ti->real_thread != NULL);
- if(!nested){
+ if (!nested) {
struct task_struct *task;
struct thread_info *tti;
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 7b3e53fb807..1b388b41d95 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -1,22 +1,15 @@
/*
- * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include "linux/module.h"
-#include "linux/string.h"
-#include "linux/smp_lock.h"
-#include "linux/spinlock.h"
-#include "linux/highmem.h"
-#include "asm/current.h"
-#include "asm/processor.h"
-#include "asm/unistd.h"
-#include "asm/pgalloc.h"
-#include "asm/pgtable.h"
-#include "asm/page.h"
+#include "linux/syscalls.h"
+#include "asm/a.out.h"
#include "asm/tlbflush.h"
-#include "kern_util.h"
+#include "asm/uaccess.h"
#include "as-layout.h"
+#include "kern_util.h"
#include "mem_user.h"
#include "os.h"
@@ -34,30 +27,19 @@ EXPORT_SYMBOL(get_kmem_end);
EXPORT_SYMBOL(high_physmem);
EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(um_virt_to_phys);
-EXPORT_SYMBOL(mode_tt);
EXPORT_SYMBOL(handle_page_fault);
EXPORT_SYMBOL(find_iomem);
-#ifdef CONFIG_MODE_TT
-EXPORT_SYMBOL(stop);
-EXPORT_SYMBOL(strncpy_from_user_tt);
-EXPORT_SYMBOL(copy_from_user_tt);
-EXPORT_SYMBOL(copy_to_user_tt);
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-EXPORT_SYMBOL(strnlen_user_skas);
-EXPORT_SYMBOL(strncpy_from_user_skas);
-EXPORT_SYMBOL(copy_to_user_skas);
-EXPORT_SYMBOL(copy_from_user_skas);
-EXPORT_SYMBOL(clear_user_skas);
-#endif
+EXPORT_SYMBOL(strnlen_user);
+EXPORT_SYMBOL(strncpy_from_user);
+EXPORT_SYMBOL(copy_to_user);
+EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(clear_user);
EXPORT_SYMBOL(uml_strdup);
EXPORT_SYMBOL(os_stat_fd);
EXPORT_SYMBOL(os_stat_file);
EXPORT_SYMBOL(os_access);
-EXPORT_SYMBOL(os_print_error);
EXPORT_SYMBOL(os_get_exec_close);
EXPORT_SYMBOL(os_set_exec_close);
EXPORT_SYMBOL(os_getpid);
@@ -85,9 +67,6 @@ EXPORT_SYMBOL(run_helper);
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(do_gettimeofday);
-EXPORT_SYMBOL(do_settimeofday);
-
#ifdef CONFIG_SMP
/* required for SMP */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index d2b11f24269..8456397f5f4 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -17,7 +17,7 @@
#include "as-layout.h"
#include "kern.h"
#include "mem_user.h"
-#include "uml_uaccess.h"
+#include "um_uaccess.h"
#include "os.h"
#include "linux/types.h"
#include "linux/string.h"
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 5ee7e851bbc..e66432f4248 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -1,25 +1,17 @@
/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/mm.h"
-#include "linux/rbtree.h"
-#include "linux/slab.h"
-#include "linux/vmalloc.h"
#include "linux/bootmem.h"
-#include "linux/module.h"
+#include "linux/mm.h"
#include "linux/pfn.h"
-#include "asm/types.h"
-#include "asm/pgtable.h"
-#include "kern_util.h"
+#include "asm/page.h"
#include "as-layout.h"
-#include "mode_kern.h"
-#include "mem.h"
+#include "init.h"
+#include "kern.h"
#include "mem_user.h"
#include "os.h"
-#include "kern.h"
-#include "init.h"
static int physmem_fd = -1;
@@ -49,10 +41,10 @@ int __init init_maps(unsigned long physmem, unsigned long iomem,
total_len = phys_len + iomem_len + highmem_len;
map = alloc_bootmem_low_pages(total_len);
- if(map == NULL)
+ if (map == NULL)
return -ENOMEM;
- for(i = 0; i < total_pages; i++){
+ for (i = 0; i < total_pages; i++) {
p = &map[i];
memset(p, 0, sizeof(struct page));
SetPageReserved(p);
@@ -68,8 +60,8 @@ static unsigned long kmem_top = 0;
unsigned long get_kmem_end(void)
{
- if(kmem_top == 0)
- kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
+ if (kmem_top == 0)
+ kmem_top = host_task_size - 1024 * 1024;
return kmem_top;
}
@@ -81,9 +73,9 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
fd = phys_mapping(phys, &offset);
err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
- if(err) {
- if(err == -ENOMEM)
- printk("try increasing the host's "
+ if (err) {
+ if (err == -ENOMEM)
+ printk(KERN_ERR "try increasing the host's "
"/proc/sys/vm/max_map_count to <physical "
"memory size>/4096\n");
panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
@@ -105,13 +97,16 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
offset = uml_reserved - uml_physmem;
err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
- len - offset, 1, 1, 0);
- if(err < 0){
- os_print_error(err, "Mapping memory");
+ len - offset, 1, 1, 1);
+ if (err < 0) {
+ printf("setup_physmem - mapping %ld bytes of memory at 0x%p "
+ "failed - errno = %d\n", len - offset,
+ (void *) uml_reserved, err);
exit(1);
}
- /* Special kludge - This page will be mapped in to userspace processes
+ /*
+ * Special kludge - This page will be mapped in to userspace processes
* from physmem_fd, so it needs to be written out there.
*/
os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
@@ -122,20 +117,20 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
len - bootmap_size - reserve);
}
-int phys_mapping(unsigned long phys, __u64 *offset_out)
+int phys_mapping(unsigned long phys, unsigned long long *offset_out)
{
int fd = -1;
- if(phys < physmem_size){
+ if (phys < physmem_size) {
fd = physmem_fd;
*offset_out = phys;
}
- else if(phys < __pa(end_iomem)){
+ else if (phys < __pa(end_iomem)) {
struct iomem_region *region = iomem_regions;
- while(region != NULL){
- if((phys >= region->phys) &&
- (phys < region->phys + region->size)){
+ while (region != NULL) {
+ if ((phys >= region->phys) &&
+ (phys < region->phys + region->size)) {
fd = region->fd;
*offset_out = phys - region->phys;
break;
@@ -143,7 +138,7 @@ int phys_mapping(unsigned long phys, __u64 *offset_out)
region = region->next;
}
}
- else if(phys < __pa(end_iomem) + highmem){
+ else if (phys < __pa(end_iomem) + highmem) {
fd = physmem_fd;
*offset_out = phys - iomem_size;
}
@@ -188,8 +183,8 @@ unsigned long find_iomem(char *driver, unsigned long *len_out)
{
struct iomem_region *region = iomem_regions;
- while(region != NULL){
- if(!strcmp(region->driver, driver)){
+ while (region != NULL) {
+ if (!strcmp(region->driver, driver)) {
*len_out = region->size;
return region->virt;
}
@@ -206,12 +201,12 @@ int setup_iomem(void)
unsigned long iomem_start = high_physmem + PAGE_SIZE;
int err;
- while(region != NULL){
+ while (region != NULL) {
err = os_map_memory((void *) iomem_start, region->fd, 0,
region->size, 1, 1, 0);
- if(err)
- printk("Mapping iomem region for driver '%s' failed, "
- "errno = %d\n", region->driver, -err);
+ if (err)
+ printk(KERN_ERR "Mapping iomem region for driver '%s' "
+ "failed, errno = %d\n", region->driver, -err);
else {
region->virt = iomem_start;
region->phys = __pa(region->virt);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index bfa52f206bb..0eae00b3e58 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -1,53 +1,30 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright 2003 PathScale, Inc.
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/sched.h"
-#include "linux/interrupt.h"
-#include "linux/string.h"
+#include "linux/stddef.h"
+#include "linux/err.h"
+#include "linux/hardirq.h"
#include "linux/mm.h"
-#include "linux/slab.h"
-#include "linux/utsname.h"
-#include "linux/fs.h"
-#include "linux/utime.h"
-#include "linux/smp_lock.h"
-#include "linux/module.h"
-#include "linux/init.h"
-#include "linux/capability.h"
-#include "linux/vmalloc.h"
-#include "linux/spinlock.h"
+#include "linux/personality.h"
#include "linux/proc_fs.h"
#include "linux/ptrace.h"
#include "linux/random.h"
-#include "linux/personality.h"
-#include "asm/unistd.h"
-#include "asm/mman.h"
-#include "asm/segment.h"
-#include "asm/stat.h"
+#include "linux/sched.h"
+#include "linux/tick.h"
+#include "linux/threads.h"
#include "asm/pgtable.h"
-#include "asm/processor.h"
-#include "asm/tlbflush.h"
#include "asm/uaccess.h"
-#include "asm/user.h"
-#include "kern_util.h"
#include "as-layout.h"
-#include "kern.h"
-#include "signal_kern.h"
-#include "init.h"
-#include "irq_user.h"
-#include "mem_user.h"
-#include "tlb.h"
-#include "frame_kern.h"
-#include "sigcontext.h"
+#include "kern_util.h"
#include "os.h"
-#include "mode.h"
-#include "mode_kern.h"
-#include "choose-mode.h"
+#include "skas.h"
+#include "tlb.h"
-/* This is a per-cpu array. A processor only modifies its entry and it only
+/*
+ * This is a per-cpu array. A processor only modifies its entry and it only
* cares about its entry, so it's OK if another processor is modifying its
* entry.
*/
@@ -55,15 +32,16 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
static inline int external_pid(struct task_struct *task)
{
- return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task);
+ /* FIXME: Need to look up userspace_pid by cpu */
+ return userspace_pid[0];
}
int pid_to_processor_id(int pid)
{
int i;
- for(i = 0; i < ncpus; i++){
- if(cpu_tasks[i].pid == pid)
+ for(i = 0; i < ncpus; i++) {
+ if (cpu_tasks[i].pid == pid)
return i;
}
return -1;
@@ -82,9 +60,9 @@ unsigned long alloc_stack(int order, int atomic)
if (atomic)
flags = GFP_ATOMIC;
page = __get_free_pages(flags, order);
- if(page == 0)
+ if (page == 0)
return 0;
- stack_protections(page);
+
return page;
}
@@ -105,6 +83,8 @@ static inline void set_current(struct task_struct *task)
{ external_pid(task), task });
}
+extern void arch_switch_to(struct task_struct *from, struct task_struct *to);
+
void *_switch_to(void *prev, void *next, void *last)
{
struct task_struct *from = prev;
@@ -114,9 +94,14 @@ void *_switch_to(void *prev, void *next, void *last)
set_current(to);
do {
- current->thread.saved_task = NULL ;
- CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
- if(current->thread.saved_task)
+ current->thread.saved_task = NULL;
+
+ switch_threads(&from->thread.switch_buf,
+ &to->thread.switch_buf);
+
+ arch_switch_to(current->thread.prev_sched, current);
+
+ if (current->thread.saved_task)
show_regs(&(current->thread.regs));
next= current->thread.saved_task;
prev= current;
@@ -128,20 +113,14 @@ void *_switch_to(void *prev, void *next, void *last)
void interrupt_end(void)
{
- if(need_resched())
+ if (need_resched())
schedule();
- if(test_tsk_thread_flag(current, TIF_SIGPENDING))
+ if (test_tsk_thread_flag(current, TIF_SIGPENDING))
do_signal();
}
-void release_thread(struct task_struct *task)
-{
- CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
-}
-
void exit_thread(void)
{
- unprotect_stack((unsigned long) current_thread);
}
void *get_current(void)
@@ -149,28 +128,99 @@ void *get_current(void)
return current;
}
+extern void schedule_tail(struct task_struct *prev);
+
+/*
+ * This is called magically, by its address being stuffed in a jmp_buf
+ * and being longjmp-d to.
+ */
+void new_thread_handler(void)
+{
+ int (*fn)(void *), n;
+ void *arg;
+
+ if (current->thread.prev_sched != NULL)
+ schedule_tail(current->thread.prev_sched);
+ current->thread.prev_sched = NULL;
+
+ fn = current->thread.request.u.thread.proc;
+ arg = current->thread.request.u.thread.arg;
+
+ /*
+ * The return value is 1 if the kernel thread execs a process,
+ * 0 if it just exits
+ */
+ n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
+ if (n == 1) {
+ /* Handle any immediate reschedules or signals */
+ interrupt_end();
+ userspace(&current->thread.regs.regs);
+ }
+ else do_exit(0);
+}
+
+/* Called magically, see new_thread_handler above */
+void fork_handler(void)
+{
+ force_flush_all();
+ if (current->thread.prev_sched == NULL)
+ panic("blech");
+
+ schedule_tail(current->thread.prev_sched);
+
+ /*
+ * XXX: if interrupt_end() calls schedule, this call to
+ * arch_switch_to isn't needed. We could want to apply this to
+ * improve performance. -bb
+ */
+ arch_switch_to(current->thread.prev_sched, current);
+
+ current->thread.prev_sched = NULL;
+
+ /* Handle any immediate reschedules or signals */
+ interrupt_end();
+
+ userspace(&current->thread.regs.regs);
+}
+
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long stack_top, struct task_struct * p,
struct pt_regs *regs)
{
- int ret;
+ void (*handler)(void);
+ int ret = 0;
p->thread = (struct thread_struct) INIT_THREAD;
- ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
- clone_flags, sp, stack_top, p, regs);
- if (ret || !current->thread.forking)
- goto out;
+ if (current->thread.forking) {
+ memcpy(&p->thread.regs.regs, &regs->regs,
+ sizeof(p->thread.regs.regs));
+ REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.gp, 0);
+ if (sp != 0)
+ REGS_SP(p->thread.regs.regs.gp) = sp;
- clear_flushed_tls(p);
+ handler = fork_handler;
- /*
- * Set a new TLS for the child thread?
- */
- if (clone_flags & CLONE_SETTLS)
- ret = arch_copy_tls(p);
+ arch_copy_thread(&current->thread.arch, &p->thread.arch);
+ }
+ else {
+ init_thread_registers(&p->thread.regs.regs);
+ p->thread.request.u.thread = current->thread.request.u.thread;
+ handler = new_thread_handler;
+ }
+
+ new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
+
+ if (current->thread.forking) {
+ clear_flushed_tls(p);
+
+ /*
+ * Set a new TLS for the child thread?
+ */
+ if (clone_flags & CLONE_SETTLS)
+ ret = arch_copy_tls(p);
+ }
-out:
return ret;
}
@@ -179,39 +229,35 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
int save_kmalloc_ok = kmalloc_ok;
kmalloc_ok = 0;
- CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
- arg);
+ initial_thread_cb_skas(proc, arg);
kmalloc_ok = save_kmalloc_ok;
}
-#ifdef CONFIG_MODE_TT
-unsigned long stack_sp(unsigned long page)
-{
- return page + PAGE_SIZE - sizeof(void *);
-}
-#endif
-
void default_idle(void)
{
- CHOOSE_MODE(uml_idle_timer(), (void) 0);
+ unsigned long long nsecs;
- while(1){
+ while(1) {
/* endless idle loop with no priority at all */
/*
* although we are an idle CPU, we do not want to
* get into the scheduler unnecessarily.
*/
- if(need_resched())
+ if (need_resched())
schedule();
- idle_sleep(10);
+ tick_nohz_stop_sched_tick();
+ nsecs = disable_timer();
+ idle_sleep(nsecs);
+ tick_nohz_restart_sched_tick();
}
}
void cpu_idle(void)
{
- CHOOSE_MODE(init_idle_tt(), init_idle_skas());
+ cpu_tasks[current_thread->cpu].pid = os_getpid();
+ default_idle();
}
void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
@@ -223,26 +269,26 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte;
pte_t ptent;
- if(task->mm == NULL)
+ if (task->mm == NULL)
return ERR_PTR(-EINVAL);
pgd = pgd_offset(task->mm, addr);
- if(!pgd_present(*pgd))
+ if (!pgd_present(*pgd))
return ERR_PTR(-EINVAL);
pud = pud_offset(pgd, addr);
- if(!pud_present(*pud))
+ if (!pud_present(*pud))
return ERR_PTR(-EINVAL);
pmd = pmd_offset(pud, addr);
- if(!pmd_present(*pmd))
+ if (!pmd_present(*pmd))
return ERR_PTR(-EINVAL);
pte = pte_offset_kernel(pmd, addr);
ptent = *pte;
- if(!pte_present(ptent))
+ if (!pte_present(ptent))
return ERR_PTR(-EINVAL);
- if(pte_out != NULL)
+ if (pte_out != NULL)
*pte_out = ptent;
return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
}
@@ -315,7 +361,7 @@ int smp_sigio_handler(void)
#ifdef CONFIG_SMP
int cpu = current_thread->cpu;
IPI_handler(cpu);
- if(cpu != 0)
+ if (cpu != 0)
return 1;
#endif
return 0;
@@ -343,7 +389,8 @@ int get_using_sysemu(void)
static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
{
- if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
+ if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size)
+ /* No overflow */
*eof = 1;
return strlen(buf);
@@ -358,7 +405,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned
if (tmp[0] >= '0' && tmp[0] <= '2')
set_using_sysemu(tmp[0] - '0');
- return count; /*We use the first char, but pretend to write everything*/
+ /* We use the first char, but pretend to write everything */
+ return count;
}
int __init make_proc_sysemu(void)
@@ -388,10 +436,10 @@ int singlestepping(void * t)
struct task_struct *task = t ? t : current;
if ( ! (task->ptrace & PT_DTRACE) )
- return(0);
+ return 0;
if (task->thread.singlestep_syscall)
- return(1);
+ return 1;
return 2;
}
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 6916c8888db..a0eba083306 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -1,35 +1,27 @@
-/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/mm.h"
-#include "linux/errno.h"
-#include "linux/smp_lock.h"
-#include "linux/security.h"
-#include "linux/ptrace.h"
#include "linux/audit.h"
+#include "linux/ptrace.h"
+#include "linux/sched.h"
+#include "asm/uaccess.h"
#ifdef CONFIG_PROC_MM
-#include "linux/proc_mm.h"
+#include "proc_mm.h"
#endif
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "kern_util.h"
#include "skas_ptrace.h"
-#include "sysdep/ptrace.h"
-#include "os.h"
static inline void set_singlestepping(struct task_struct *child, int on)
{
- if (on)
- child->ptrace |= PT_DTRACE;
- else
- child->ptrace &= ~PT_DTRACE;
- child->thread.singlestep_syscall = 0;
+ if (on)
+ child->ptrace |= PT_DTRACE;
+ else
+ child->ptrace &= ~PT_DTRACE;
+ child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING
- SUBARCH_SET_SINGLESTEPPING(child, on);
+ SUBARCH_SET_SINGLESTEPPING(child, on);
#endif
}
@@ -37,8 +29,8 @@ static inline void set_singlestepping(struct task_struct *child, int on)
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
-{
- set_singlestepping(child,0);
+{
+ set_singlestepping(child,0);
}
extern int peek_user(struct task_struct * child, long addr, long data);
@@ -50,40 +42,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
unsigned long __user *p = (void __user *)(unsigned long)data;
switch (request) {
- /* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
+ /* read word at location addr. */
+ case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
ret = generic_ptrace_peekdata(child, addr, data);
break;
/* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR:
- ret = peek_user(child, addr, data);
- break;
+ case PTRACE_PEEKUSR:
+ ret = peek_user(child, addr, data);
+ break;
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
+ /* write the word at location addr. */
+ case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = generic_ptrace_pokedata(child, addr, data);
break;
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- ret = poke_user(child, addr, data);
- break;
+ /* write the word at location addr in the USER area */
+ case PTRACE_POKEUSR:
+ ret = poke_user(child, addr, data);
+ break;
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
+ /* continue and stop at next (return from) syscall */
+ case PTRACE_SYSCALL:
+ /* restart after signal. */
+ case PTRACE_CONT: {
ret = -EIO;
if (!valid_signal(data))
break;
- set_singlestepping(child, 0);
- if (request == PTRACE_SYSCALL) {
+ set_singlestepping(child, 0);
+ if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
- else {
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
+ else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
wake_up_process(child);
ret = 0;
@@ -91,8 +83,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
/*
- * make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
* exit.
*/
case PTRACE_KILL: {
@@ -100,7 +92,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
- set_singlestepping(child, 0);
+ set_singlestepping(child, 0);
child->exit_code = SIGKILL;
wake_up_process(child);
break;
@@ -111,7 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- set_singlestepping(child, 1);
+ set_singlestepping(child, 1);
child->exit_code = data;
/* give it a chance to run. */
wake_up_process(child);
@@ -119,11 +111,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
}
- case PTRACE_DETACH:
- /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
#ifdef PTRACE_GETREGS
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
@@ -156,22 +143,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#endif
#ifdef PTRACE_GETFPREGS
case PTRACE_GETFPREGS: /* Get the child FPU state. */
- ret = get_fpregs(data, child);
+ ret = get_fpregs((struct user_i387_struct __user *) data,
+ child);
break;
#endif
#ifdef PTRACE_SETFPREGS
case PTRACE_SETFPREGS: /* Set the child FPU state. */
- ret = set_fpregs(data, child);
- break;
-#endif
-#ifdef PTRACE_GETFPXREGS
- case PTRACE_GETFPXREGS: /* Get the child FPU state. */
- ret = get_fpxregs(data, child);
- break;
-#endif
-#ifdef PTRACE_SETFPXREGS
- case PTRACE_SETFPXREGS: /* Set the child FPU state. */
- ret = set_fpxregs(data, child);
+ ret = set_fpregs((struct user_i387_struct __user *) data,
+ child);
break;
#endif
case PTRACE_GET_THREAD_AREA:
@@ -185,14 +164,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_FAULTINFO: {
- /* Take the info from thread->arch->faultinfo,
+ /*
+ * Take the info from thread->arch->faultinfo,
* but transfer max. sizeof(struct ptrace_faultinfo).
* On i386, ptrace_faultinfo is smaller!
*/
ret = copy_to_user(p, &child->thread.arch.faultinfo,
sizeof(struct ptrace_faultinfo));
- if(ret)
- break;
break;
}
@@ -200,12 +178,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_LDT: {
struct ptrace_ldt ldt;
- if(copy_from_user(&ldt, p, sizeof(ldt))){
+ if (copy_from_user(&ldt, p, sizeof(ldt))) {
ret = -EIO;
break;
}
- /* This one is confusing, so just punt and return -EIO for
+ /*
+ * This one is confusing, so just punt and return -EIO for
* now
*/
ret = -EIO;
@@ -217,7 +196,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
struct mm_struct *old = child->mm;
struct mm_struct *new = proc_mm_get_mm(data);
- if(IS_ERR(new)){
+ if (IS_ERR(new)) {
ret = PTR_ERR(new);
break;
}
@@ -231,20 +210,22 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
#endif
#ifdef PTRACE_ARCH_PRCTL
- case PTRACE_ARCH_PRCTL:
- /* XXX Calls ptrace on the host - needs some SMP thinking */
- ret = arch_prctl_skas(child, data, (void *) addr);
- break;
+ case PTRACE_ARCH_PRCTL:
+ /* XXX Calls ptrace on the host - needs some SMP thinking */
+ ret = arch_prctl(child, data, (void *) addr);
+ break;
#endif
default:
ret = ptrace_request(child, request, addr, data);
+ if (ret == -EIO)
+ ret = subarch_ptrace(child, request, addr, data);
break;
}
return ret;
}
-void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
+void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
int error_code)
{
struct siginfo info;
@@ -260,10 +241,11 @@ void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
force_sig_info(SIGTRAP, &info, tsk);
}
-/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
+/*
+ * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
* PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
*/
-void syscall_trace(union uml_pt_regs *regs, int entryexit)
+void syscall_trace(struct uml_pt_regs *regs, int entryexit)
{
int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
int tracesysgood;
@@ -277,7 +259,7 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
UPT_SYSCALL_ARG3(regs),
UPT_SYSCALL_ARG4(regs));
else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
- UPT_SYSCALL_RET(regs));
+ UPT_SYSCALL_RET(regs));
}
/* Fake a debug trap */
@@ -290,15 +272,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
if (!(current->ptrace & PT_PTRACED))
return;
- /* the 0x80 provides a way for the tracing parent to distinguish
- between a syscall stop and SIGTRAP delivery */
+ /*
+ * the 0x80 provides a way for the tracing parent to distinguish
+ * between a syscall stop and SIGTRAP delivery
+ */
tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
if (entryexit) /* force do_signal() --> is_syscall() */
set_thread_flag(TIF_SIGPENDING);
- /* this isn't the same as continuing with a signal, but it will do
+ /*
+ * this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 7e4305a1fd3..04cebcf0679 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -1,60 +1,53 @@
/*
- * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/module.h"
#include "linux/sched.h"
-#include "asm/smp.h"
-#include "kern_util.h"
-#include "kern.h"
#include "os.h"
-#include "mode.h"
-#include "choose-mode.h"
+#include "skas.h"
void (*pm_power_off)(void);
-#ifdef CONFIG_SMP
-static void kill_idlers(int me)
-{
-#ifdef CONFIG_MODE_TT
- struct task_struct *p;
- int i;
-
- for(i = 0; i < ARRAY_SIZE(idle_threads); i++){
- p = idle_threads[i];
- if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
- os_kill_process(p->thread.mode.tt.extern_pid, 0);
- }
-#endif
-}
-#endif
-
static void kill_off_processes(void)
{
- CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas());
-#ifdef CONFIG_SMP
- kill_idlers(os_getpid());
-#endif
+ if(proc_mm)
+ /*
+ * FIXME: need to loop over userspace_pids
+ */
+ os_kill_ptraced_process(userspace_pid[0], 1);
+ else {
+ struct task_struct *p;
+ int pid, me;
+
+ me = os_getpid();
+ for_each_process(p){
+ if(p->mm == NULL)
+ continue;
+
+ pid = p->mm->context.id.u.pid;
+ os_kill_ptraced_process(pid, 1);
+ }
+ }
}
void uml_cleanup(void)
{
- kmalloc_ok = 0;
+ kmalloc_ok = 0;
do_uml_exitcalls();
kill_off_processes();
}
void machine_restart(char * __unused)
{
- uml_cleanup();
- CHOOSE_MODE(reboot_tt(), reboot_skas());
+ uml_cleanup();
+ reboot_skas();
}
void machine_power_off(void)
{
- uml_cleanup();
- CHOOSE_MODE(halt_tt(), halt_skas());
+ uml_cleanup();
+ halt_skas();
}
void machine_halt(void)
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index c4020c3d785..19cb9773393 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -1,29 +1,17 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/stddef.h"
-#include "linux/sys.h"
-#include "linux/sched.h"
-#include "linux/wait.h"
-#include "linux/kernel.h"
-#include "linux/smp_lock.h"
#include "linux/module.h"
-#include "linux/slab.h"
-#include "linux/tty.h"
-#include "linux/binfmts.h"
#include "linux/ptrace.h"
+#include "linux/sched.h"
+#include "asm/siginfo.h"
#include "asm/signal.h"
-#include "asm/uaccess.h"
#include "asm/unistd.h"
-#include "asm/ucontext.h"
-#include "kern_util.h"
-#include "signal_kern.h"
-#include "kern.h"
#include "frame_kern.h"
+#include "kern_util.h"
#include "sigcontext.h"
-#include "mode.h"
EXPORT_SYMBOL(block_signals);
EXPORT_SYMBOL(unblock_signals);
@@ -46,9 +34,9 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
current_thread_info()->restart_block.fn = do_no_restart_syscall;
/* Did we come from a system call? */
- if(PT_REGS_SYSCALL_NR(regs) >= 0){
+ if (PT_REGS_SYSCALL_NR(regs) >= 0) {
/* If so, check system call restarting.. */
- switch(PT_REGS_SYSCALL_RET(regs)){
+ switch(PT_REGS_SYSCALL_RET(regs)) {
case -ERESTART_RESTARTBLOCK:
case -ERESTARTNOHAND:
PT_REGS_SYSCALL_RET(regs) = -EINTR;
@@ -68,17 +56,17 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
}
sp = PT_REGS_SP(regs);
- if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
+ if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
- if(!(ka->sa.sa_flags & SA_SIGINFO))
+ if (!(ka->sa.sa_flags & SA_SIGINFO))
err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
else
#endif
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
- if(err){
+ if (err) {
spin_lock_irq(&current->sighand->siglock);
current->blocked = *oldset;
recalc_sigpending();
@@ -88,7 +76,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked, &current->blocked,
&ka->sa.sa_mask);
- if(!(ka->sa.sa_flags & SA_NODEFER))
+ if (!(ka->sa.sa_flags & SA_NODEFER))
sigaddset(&current->blocked, signr);
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
@@ -109,14 +97,16 @@ static int kern_do_signal(struct pt_regs *regs)
else
oldset = &current->blocked;
- while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){
+ while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
handled_sig = 1;
/* Whee! Actually deliver the signal. */
- if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){
- /* a signal was successfully delivered; the saved
+ if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) {
+ /*
+ * a signal was successfully delivered; the saved
* sigmask will have been stored in the signal frame,
* and will be restored by sigreturn, so we can simply
- * clear the TIF_RESTORE_SIGMASK flag */
+ * clear the TIF_RESTORE_SIGMASK flag
+ */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
break;
@@ -124,9 +114,9 @@ static int kern_do_signal(struct pt_regs *regs)
}
/* Did we come from a system call? */
- if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){
+ if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) {
/* Restart the system call - no handlers present */
- switch(PT_REGS_SYSCALL_RET(regs)){
+ switch(PT_REGS_SYSCALL_RET(regs)) {
case -ERESTARTNOHAND:
case -ERESTARTSYS:
case -ERESTARTNOINTR:
@@ -137,22 +127,25 @@ static int kern_do_signal(struct pt_regs *regs)
PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
PT_REGS_RESTART_SYSCALL(regs);
break;
- }
+ }
}
- /* This closes a way to execute a system call on the host. If
+ /*
+ * This closes a way to execute a system call on the host. If
* you set a breakpoint on a system call instruction and singlestep
* from it, the tracing thread used to PTRACE_SINGLESTEP the process
* rather than PTRACE_SYSCALL it, allowing the system call to execute
* on the host. The tracing thread will check this flag and
* PTRACE_SYSCALL if necessary.
*/
- if(current->ptrace & PT_DTRACE)
+ if (current->ptrace & PT_DTRACE)
current->thread.singlestep_syscall =
is_syscall(PT_REGS_IP(&current->thread.regs));
- /* if there's no signal to deliver, we just put the saved sigmask
- * back */
+ /*
+ * if there's no signal to deliver, we just put the saved sigmask
+ * back
+ */
if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 3e3fa7e7e3c..0b76d8869c9 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -1,9 +1,9 @@
#
-# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
+# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL
#
-obj-y := clone.o exec.o mem.o mmu.o process.o syscall.o tlb.o uaccess.o
+obj-y := clone.o mmu.o process.o syscall.o uaccess.o
# clone.o is in the stub, so it can't be built with profiling
# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index 47b812b3bca..d119f4f7d89 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -4,6 +4,7 @@
#include <sys/time.h>
#include <asm/unistd.h>
#include <asm/page.h>
+#include "as-layout.h"
#include "ptrace_user.h"
#include "skas.h"
#include "stub-data.h"
@@ -21,12 +22,11 @@
void __attribute__ ((__section__ (".__syscall_stub")))
stub_clone_handler(void)
{
- struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA;
+ struct stub_data *data = (struct stub_data *) STUB_DATA;
long err;
err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
- UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE / 2 -
- sizeof(void *));
+ STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
if(err != 0)
goto out;
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c
deleted file mode 100644
index 580eb646894..00000000000
--- a/arch/um/kernel/skas/exec.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/kernel.h"
-#include "asm/current.h"
-#include "asm/page.h"
-#include "asm/signal.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "asm/mmu_context.h"
-#include "tlb.h"
-#include "skas.h"
-#include "um_mmu.h"
-#include "os.h"
-
-void flush_thread_skas(void)
-{
- void *data = NULL;
- unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
- int ret;
-
- ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data);
- if(ret){
- printk("flush_thread_skas - clearing address space failed, "
- "err = %d\n", ret);
- force_sig(SIGKILL, current);
- }
-
- switch_mm_skas(&current->mm->context.skas.id);
-}
-
-void start_thread_skas(struct pt_regs *regs, unsigned long eip,
- unsigned long esp)
-{
- set_fs(USER_DS);
- PT_REGS_IP(regs) = eip;
- PT_REGS_SP(regs) = esp;
-}
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
deleted file mode 100644
index 7c18dfcd7d8..00000000000
--- a/arch/um/kernel/skas/mem.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/mm.h"
-#include "asm/pgtable.h"
-#include "mem_user.h"
-#include "skas.h"
-
-unsigned long set_task_sizes_skas(unsigned long *task_size_out)
-{
- /* Round up to the nearest 4M */
- unsigned long host_task_size = ROUND_4M((unsigned long)
- &host_task_size);
-
- if (!skas_needs_stub)
- *task_size_out = host_task_size;
- else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
-
- return host_task_size;
-}
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 2c6d090a2e8..f859ec306cd 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -1,20 +1,13 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/list.h"
-#include "linux/spinlock.h"
-#include "linux/slab.h"
-#include "linux/errno.h"
#include "linux/mm.h"
-#include "asm/current.h"
-#include "asm/segment.h"
-#include "asm/mmu.h"
+#include "linux/sched.h"
#include "asm/pgalloc.h"
#include "asm/pgtable.h"
-#include "asm/ldt.h"
+#include "as-layout.h"
#include "os.h"
#include "skas.h"
@@ -41,10 +34,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
if (!pte)
goto out_pte;
- /* There's an interaction between the skas0 stub pages, stack
+ /*
+ * There's an interaction between the skas0 stub pages, stack
* randomization, and the BUG at the end of exit_mmap. exit_mmap
- * checks that the number of page tables freed is the same as had
- * been allocated. If the stack is on the last page table page,
+ * checks that the number of page tables freed is the same as had
+ * been allocated. If the stack is on the last page table page,
* then the stack pte page will be freed, and if not, it won't. To
* avoid having to know where the stack is, or if the process mapped
* something at the top of its address space for some other reason,
@@ -54,76 +48,77 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
* destroy_context_skas.
*/
- mm->context.skas.last_page_table = pmd_page_vaddr(*pmd);
+ mm->context.last_page_table = pmd_page_vaddr(*pmd);
#ifdef CONFIG_3_LEVEL_PGTABLES
- mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud));
+ mm->context.last_pmd = (unsigned long) __va(pud_val(*pud));
#endif
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
*pte = pte_mkread(*pte);
- return(0);
+ return 0;
out_pmd:
pud_free(pud);
out_pte:
pmd_free(pmd);
out:
- return(-ENOMEM);
+ return -ENOMEM;
}
-int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
+int init_new_context(struct task_struct *task, struct mm_struct *mm)
{
- struct mmu_context_skas *from_mm = NULL;
- struct mmu_context_skas *to_mm = &mm->context.skas;
+ struct mm_context *from_mm = NULL;
+ struct mm_context *to_mm = &mm->context;
unsigned long stack = 0;
int ret = -ENOMEM;
- if(skas_needs_stub){
+ if (skas_needs_stub) {
stack = get_zeroed_page(GFP_KERNEL);
- if(stack == 0)
+ if (stack == 0)
goto out;
- /* This zeros the entry that pgd_alloc didn't, needed since
+ /*
+ * This zeros the entry that pgd_alloc didn't, needed since
* we are about to reinitialize it, and want mm.nr_ptes to
* be accurate.
*/
mm->pgd[USER_PTRS_PER_PGD] = __pgd(0);
- ret = init_stub_pte(mm, CONFIG_STUB_CODE,
+ ret = init_stub_pte(mm, STUB_CODE,
(unsigned long) &__syscall_stub_start);
- if(ret)
+ if (ret)
goto out_free;
- ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack);
- if(ret)
+ ret = init_stub_pte(mm, STUB_DATA, stack);
+ if (ret)
goto out_free;
mm->nr_ptes--;
}
to_mm->id.stack = stack;
- if(current->mm != NULL && current->mm != &init_mm)
- from_mm = &current->mm->context.skas;
+ if (current->mm != NULL && current->mm != &init_mm)
+ from_mm = &current->mm->context;
- if(proc_mm){
+ if (proc_mm) {
ret = new_mm(stack);
- if(ret < 0){
- printk("init_new_context_skas - new_mm failed, "
- "errno = %d\n", ret);
+ if (ret < 0) {
+ printk(KERN_ERR "init_new_context_skas - "
+ "new_mm failed, errno = %d\n", ret);
goto out_free;
}
to_mm->id.u.mm_fd = ret;
}
else {
- if(from_mm)
+ if (from_mm)
to_mm->id.u.pid = copy_context_skas0(stack,
from_mm->id.u.pid);
else to_mm->id.u.pid = start_userspace(stack);
}
ret = init_new_ldt(to_mm, from_mm);
- if(ret < 0){
- printk("init_new_context_skas - init_ldt"
+ if (ret < 0) {
+ printk(KERN_ERR "init_new_context_skas - init_ldt"
" failed, errno = %d\n", ret);
goto out_free;
}
@@ -131,22 +126,22 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
return 0;
out_free:
- if(to_mm->id.stack != 0)
+ if (to_mm->id.stack != 0)
free_page(to_mm->id.stack);
out:
return ret;
}
-void destroy_context_skas(struct mm_struct *mm)
+void destroy_context(struct mm_struct *mm)
{
- struct mmu_context_skas *mmu = &mm->context.skas;
+ struct mm_context *mmu = &mm->context;
- if(proc_mm)
+ if (proc_mm)
os_close_file(mmu->id.u.mm_fd);
else
os_kill_ptraced_process(mmu->id.u.pid, 1);
- if(!proc_mm || !ptrace_faultinfo){
+ if (!proc_mm || !ptrace_faultinfo) {
free_page(mmu->id.stack);
pte_lock_deinit(virt_to_page(mmu->last_page_table));
pte_free_kernel((pte_t *) mmu->last_page_table);
@@ -155,4 +150,6 @@ void destroy_context_skas(struct mm_struct *mm)
pmd_free((pmd_t *) mmu->last_pmd);
#endif
}
+
+ free_ldt(mmu);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 48051a98525..fce389c2342 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -1,146 +1,26 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/slab.h"
-#include "linux/ptrace.h"
-#include "linux/proc_fs.h"
-#include "linux/file.h"
-#include "linux/errno.h"
#include "linux/init.h"
-#include "asm/uaccess.h"
-#include "asm/atomic.h"
-#include "kern_util.h"
+#include "linux/sched.h"
#include "as-layout.h"
-#include "skas.h"
#include "os.h"
-#include "tlb.h"
-#include "kern.h"
-#include "mode.h"
-#include "registers.h"
-
-void switch_to_skas(void *prev, void *next)
-{
- struct task_struct *from, *to;
-
- from = prev;
- to = next;
-
- /* XXX need to check runqueues[cpu].idle */
- if(current->pid == 0)
- switch_timers(0);
-
- switch_threads(&from->thread.mode.skas.switch_buf,
- &to->thread.mode.skas.switch_buf);
-
- arch_switch_to_skas(current->thread.prev_sched, current);
-
- if(current->pid == 0)
- switch_timers(1);
-}
-
-extern void schedule_tail(struct task_struct *prev);
-
-/* This is called magically, by its address being stuffed in a jmp_buf
- * and being longjmp-d to.
- */
-void new_thread_handler(void)
-{
- int (*fn)(void *), n;
- void *arg;
-
- if(current->thread.prev_sched != NULL)
- schedule_tail(current->thread.prev_sched);
- current->thread.prev_sched = NULL;
-
- fn = current->thread.request.u.thread.proc;
- arg = current->thread.request.u.thread.arg;
-
- /* The return value is 1 if the kernel thread execs a process,
- * 0 if it just exits
- */
- n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
- if(n == 1){
- /* Handle any immediate reschedules or signals */
- interrupt_end();
- userspace(&current->thread.regs.regs);
- }
- else do_exit(0);
-}
-
-void release_thread_skas(struct task_struct *task)
-{
-}
-
-/* Called magically, see new_thread_handler above */
-void fork_handler(void)
-{
- force_flush_all();
- if(current->thread.prev_sched == NULL)
- panic("blech");
-
- schedule_tail(current->thread.prev_sched);
-
- /* XXX: if interrupt_end() calls schedule, this call to
- * arch_switch_to_skas isn't needed. We could want to apply this to
- * improve performance. -bb */
- arch_switch_to_skas(current->thread.prev_sched, current);
-
- current->thread.prev_sched = NULL;
-
-/* Handle any immediate reschedules or signals */
- interrupt_end();
-
- userspace(&current->thread.regs.regs);
-}
-
-int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct * p,
- struct pt_regs *regs)
-{
- void (*handler)(void);
-
- if(current->thread.forking){
- memcpy(&p->thread.regs.regs.skas, &regs->regs.skas,
- sizeof(p->thread.regs.regs.skas));
- REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
- if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
-
- handler = fork_handler;
-
- arch_copy_thread(&current->thread.arch, &p->thread.arch);
- }
- else {
- init_thread_registers(&p->thread.regs.regs);
- p->thread.request.u.thread = current->thread.request.u.thread;
- handler = new_thread_handler;
- }
-
- new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf,
- handler);
- return(0);
-}
+#include "skas.h"
int new_mm(unsigned long stack)
{
int fd;
fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
- if(fd < 0)
- return(fd);
+ if (fd < 0)
+ return fd;
- if(skas_needs_stub)
- map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
+ if (skas_needs_stub)
+ map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
- return(fd);
-}
-
-void init_idle_skas(void)
-{
- cpu_tasks[current_thread->cpu].pid = os_getpid();
- default_idle();
+ return fd;
}
extern void start_kernel(void);
@@ -158,67 +38,32 @@ static int __init start_kernel_proc(void *unused)
cpu_online_map = cpumask_of_cpu(0);
#endif
start_kernel();
- return(0);
+ return 0;
}
extern int userspace_pid[];
extern char cpu0_irqstack[];
-int __init start_uml_skas(void)
+int __init start_uml(void)
{
stack_protections((unsigned long) &cpu0_irqstack);
set_sigstack(cpu0_irqstack, THREAD_SIZE);
- if(proc_mm)
+ if (proc_mm)
userspace_pid[0] = start_userspace(0);
init_new_thread_signals();
init_task.thread.request.u.thread.proc = start_kernel_proc;
init_task.thread.request.u.thread.arg = NULL;
- return(start_idle_thread(task_stack_page(&init_task),
- &init_task.thread.mode.skas.switch_buf));
-}
-
-int external_pid_skas(struct task_struct *task)
-{
- /* FIXME: Need to look up userspace_pid by cpu */
- return(userspace_pid[0]);
-}
-
-int thread_pid_skas(struct task_struct *task)
-{
- /* FIXME: Need to look up userspace_pid by cpu */
- return(userspace_pid[0]);
-}
-
-void kill_off_processes_skas(void)
-{
- if(proc_mm)
- /*
- * FIXME: need to loop over userspace_pids in
- * kill_off_processes_skas
- */
- os_kill_ptraced_process(userspace_pid[0], 1);
- else {
- struct task_struct *p;
- int pid, me;
-
- me = os_getpid();
- for_each_process(p){
- if(p->mm == NULL)
- continue;
-
- pid = p->mm->context.skas.id.u.pid;
- os_kill_ptraced_process(pid, 1);
- }
- }
+ return start_idle_thread(task_stack_page(&init_task),
+ &init_task.thread.switch_buf);
}
unsigned long current_stub_stack(void)
{
- if(current->mm == NULL)
- return(0);
+ if (current->mm == NULL)
+ return 0;
- return(current->mm->context.skas.id.stack);
+ return current->mm->context.id.stack;
}
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 0ae4eea21be..50b476f2b38 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -1,19 +1,15 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/sys.h"
+#include "linux/kernel.h"
#include "linux/ptrace.h"
-#include "asm/errno.h"
-#include "asm/unistd.h"
-#include "asm/ptrace.h"
-#include "asm/current.h"
-#include "sysdep/syscalls.h"
#include "kern_util.h"
-#include "syscall.h"
+#include "sysdep/ptrace.h"
+#include "sysdep/syscalls.h"
-void handle_syscall(union uml_pt_regs *r)
+void handle_syscall(struct uml_pt_regs *r)
{
struct pt_regs *regs = container_of(r, struct pt_regs, regs);
long result;
@@ -24,7 +20,8 @@ void handle_syscall(union uml_pt_regs *r)
current->thread.nsyscalls++;
nsyscalls++;
- /* This should go in the declaration of syscall, but when I do that,
+ /*
+ * This should go in the declaration of syscall, but when I do that,
* strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing
* children at all, sometimes hanging when bash doesn't see the first
* ls exit.
@@ -33,11 +30,11 @@ void handle_syscall(union uml_pt_regs *r)
* in case it's a compiler bug.
*/
syscall = UPT_SYSCALL_NR(r);
- if((syscall >= NR_syscalls) || (syscall < 0))
+ if ((syscall >= NR_syscalls) || (syscall < 0))
result = -ENOSYS;
else result = EXECUTE_SYSCALL(syscall, regs);
- REGS_SET_SYSCALL_RETURN(r->skas.regs, result);
+ REGS_SET_SYSCALL_RETURN(r->gp, result);
syscall_trace(r, 1);
}
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
deleted file mode 100644
index c0f0693743b..00000000000
--- a/arch/um/kernel/skas/tlb.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Copyright 2003 PathScale, Inc.
- * Licensed under the GPL
- */
-
-#include "linux/stddef.h"
-#include "linux/sched.h"
-#include "linux/mm.h"
-#include "asm/page.h"
-#include "asm/pgtable.h"
-#include "asm/mmu.h"
-#include "mem_user.h"
-#include "mem.h"
-#include "skas.h"
-#include "os.h"
-#include "tlb.h"
-
-static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
- int finished, void **flush)
-{
- struct host_vm_op *op;
- int i, ret = 0;
-
- for(i = 0; i <= last && !ret; i++){
- op = &ops[i];
- switch(op->type){
- case MMAP:
- ret = map(&mmu->skas.id, op->u.mmap.addr,
- op->u.mmap.len, op->u.mmap.prot,
- op->u.mmap.fd, op->u.mmap.offset, finished,
- flush);
- break;
- case MUNMAP:
- ret = unmap(&mmu->skas.id, op->u.munmap.addr,
- op->u.munmap.len, finished, flush);
- break;
- case MPROTECT:
- ret = protect(&mmu->skas.id, op->u.mprotect.addr,
- op->u.mprotect.len, op->u.mprotect.prot,
- finished, flush);
- break;
- default:
- printk("Unknown op type %d in do_ops\n", op->type);
- break;
- }
- }
-
- return ret;
-}
-
-extern int proc_mm;
-
-static void fix_range(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force)
-{
- if(!proc_mm && (end_addr > CONFIG_STUB_START))
- end_addr = CONFIG_STUB_START;
-
- fix_range_common(mm, start_addr, end_addr, force, do_ops);
-}
-
-void __flush_tlb_one_skas(unsigned long addr)
-{
- flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE);
-}
-
-void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- if(vma->vm_mm == NULL)
- flush_tlb_kernel_range_common(start, end);
- else fix_range(vma->vm_mm, start, end, 0);
-}
-
-void flush_tlb_mm_skas(struct mm_struct *mm)
-{
- unsigned long end;
-
- /* Don't bother flushing if this address space is about to be
- * destroyed.
- */
- if(atomic_read(&mm->mm_users) == 0)
- return;
-
- end = proc_mm ? task_size : CONFIG_STUB_START;
- fix_range(mm, 0, end, 0);
-}
-
-void force_flush_all_skas(void)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma = mm->mmap;
-
- while(vma != NULL) {
- fix_range(mm, vma->vm_start, vma->vm_end, 1);
- vma = vma->vm_next;
- }
-}
-
-void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- struct mm_struct *mm = vma->vm_mm;
- void *flush = NULL;
- int r, w, x, prot, err = 0;
- struct mm_id *mm_id;
-
- pgd = pgd_offset(mm, address);
- if(!pgd_present(*pgd))
- goto kill;
-
- pud = pud_offset(pgd, address);
- if(!pud_present(*pud))
- goto kill;
-
- pmd = pmd_offset(pud, address);
- if(!pmd_present(*pmd))
- goto kill;
-
- pte = pte_offset_kernel(pmd, address);
-
- r = pte_read(*pte);
- w = pte_write(*pte);
- x = pte_exec(*pte);
- if (!pte_young(*pte)) {
- r = 0;
- w = 0;
- } else if (!pte_dirty(*pte)) {
- w = 0;
- }
-
- mm_id = &mm->context.skas.id;
- prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
- (x ? UM_PROT_EXEC : 0));
- if(pte_newpage(*pte)){
- if(pte_present(*pte)){
- unsigned long long offset;
- int fd;
-
- fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
- err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
- 1, &flush);
- }
- else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
- }
- else if(pte_newprot(*pte))
- err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
-
- if(err)
- goto kill;
-
- *pte = pte_mkuptodate(*pte);
-
- return;
-
-kill:
- printk("Failed to flush page for address 0x%lx\n", address);
- force_sig(SIGKILL, current);
-}
-
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 8912cec0fe4..1d8b119f2d0 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -1,18 +1,14 @@
/*
- * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/compiler.h"
-#include "linux/stddef.h"
-#include "linux/kernel.h"
-#include "linux/string.h"
-#include "linux/fs.h"
-#include "linux/hardirq.h"
+#include "linux/err.h"
#include "linux/highmem.h"
+#include "linux/mm.h"
+#include "asm/current.h"
#include "asm/page.h"
#include "asm/pgtable.h"
-#include "asm/uaccess.h"
#include "kern_util.h"
#include "os.h"
@@ -27,16 +23,16 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
void *phys = um_virt_to_phys(current, virt, &pte);
int dummy_code;
- if(IS_ERR(phys) || (is_write && !pte_write(pte))){
+ if (IS_ERR(phys) || (is_write && !pte_write(pte))) {
err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
- if(err)
- return(-1UL);
+ if (err)
+ return -1UL;
phys = um_virt_to_phys(current, virt, NULL);
}
- if(IS_ERR(phys))
- phys = (void *) -1;
+ if (IS_ERR(phys))
+ phys = (void *) -1;
- return((unsigned long) phys);
+ return (unsigned long) phys;
}
static int do_op_one_page(unsigned long addr, int len, int is_write,
@@ -46,17 +42,18 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
int n;
addr = maybe_map(addr, is_write);
- if(addr == -1UL)
- return(-1);
+ if (addr == -1UL)
+ return -1;
page = phys_to_page(addr);
- addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK);
+ addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) +
+ (addr & ~PAGE_MASK);
n = (*op)(addr, len, arg);
kunmap_atomic(page, KM_UML_USERCOPY);
- return(n);
+ return n;
}
static void do_buffer_op(void *jmpbuf, void *arg_ptr)
@@ -81,21 +78,21 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
current->thread.fault_catcher = jmpbuf;
n = do_op_one_page(addr, size, is_write, op, arg);
- if(n != 0){
+ if (n != 0) {
*res = (n < 0 ? remain : 0);
goto out;
}
addr += size;
remain -= size;
- if(remain == 0){
+ if (remain == 0) {
*res = 0;
goto out;
}
- while(addr < ((addr + remain) & PAGE_MASK)){
+ while(addr < ((addr + remain) & PAGE_MASK)) {
n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg);
- if(n != 0){
+ if (n != 0) {
*res = (n < 0 ? remain : 0);
goto out;
}
@@ -103,13 +100,13 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
addr += PAGE_SIZE;
remain -= PAGE_SIZE;
}
- if(remain == 0){
+ if (remain == 0) {
*res = 0;
goto out;
}
n = do_op_one_page(addr, remain, is_write, op, arg);
- if(n != 0)
+ if (n != 0)
*res = (n < 0 ? remain : 0);
else *res = 0;
out:
@@ -124,10 +121,10 @@ static int buffer_op(unsigned long addr, int len, int is_write,
faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg,
&res);
- if(!faulted)
- return(res);
+ if (!faulted)
+ return res;
- return(addr + len - (unsigned long) current->thread.fault_addr);
+ return addr + len - (unsigned long) current->thread.fault_addr;
}
static int copy_chunk_from_user(unsigned long from, int len, void *arg)
@@ -136,19 +133,19 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
memcpy((void *) to, (void *) from, len);
*to_ptr += len;
- return(0);
+ return 0;
}
-int copy_from_user_skas(void *to, const void __user *from, int n)
+int copy_from_user(void *to, const void __user *from, int n)
{
- if(segment_eq(get_fs(), KERNEL_DS)){
+ if (segment_eq(get_fs(), KERNEL_DS)) {
memcpy(to, (__force void*)from, n);
- return(0);
+ return 0;
}
- return(access_ok(VERIFY_READ, from, n) ?
+ return access_ok(VERIFY_READ, from, n) ?
buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
- n);
+ n;
}
static int copy_chunk_to_user(unsigned long to, int len, void *arg)
@@ -157,19 +154,19 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
memcpy((void *) to, (void *) from, len);
*from_ptr += len;
- return(0);
+ return 0;
}
-int copy_to_user_skas(void __user *to, const void *from, int n)
+int copy_to_user(void __user *to, const void *from, int n)
{
- if(segment_eq(get_fs(), KERNEL_DS)){
- memcpy((__force void*)to, from, n);
- return(0);
+ if (segment_eq(get_fs(), KERNEL_DS)) {
+ memcpy((__force void *) to, from, n);
+ return 0;
}
- return(access_ok(VERIFY_WRITE, to, n) ?
+ return access_ok(VERIFY_WRITE, to, n) ?
buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
- n);
+ n;
}
static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
@@ -181,51 +178,51 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
n = strnlen(to, len);
*to_ptr += n;
- if(n < len)
- return(1);
- return(0);
+ if (n < len)
+ return 1;
+ return 0;
}
-int strncpy_from_user_skas(char *dst, const char __user *src, int count)
+int strncpy_from_user(char *dst, const char __user *src, int count)
{
int n;
char *ptr = dst;
- if(segment_eq(get_fs(), KERNEL_DS)){
- strncpy(dst, (__force void*)src, count);
- return(strnlen(dst, count));
+ if (segment_eq(get_fs(), KERNEL_DS)) {
+ strncpy(dst, (__force void *) src, count);
+ return strnlen(dst, count);
}
- if(!access_ok(VERIFY_READ, src, 1))
- return(-EFAULT);
+ if (!access_ok(VERIFY_READ, src, 1))
+ return -EFAULT;
n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
&ptr);
- if(n != 0)
- return(-EFAULT);
- return(strnlen(dst, count));
+ if (n != 0)
+ return -EFAULT;
+ return strnlen(dst, count);
}
static int clear_chunk(unsigned long addr, int len, void *unused)
{
memset((void *) addr, 0, len);
- return(0);
+ return 0;
}
-int __clear_user_skas(void __user *mem, int len)
+int __clear_user(void __user *mem, int len)
{
- return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
+ return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
}
-int clear_user_skas(void __user *mem, int len)
+int clear_user(void __user *mem, int len)
{
- if(segment_eq(get_fs(), KERNEL_DS)){
+ if (segment_eq(get_fs(), KERNEL_DS)) {
memset((__force void*)mem, 0, len);
- return(0);
+ return 0;
}
- return(access_ok(VERIFY_WRITE, mem, len) ?
- buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
+ return access_ok(VERIFY_WRITE, mem, len) ?
+ buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len;
}
static int strnlen_chunk(unsigned long str, int len, void *arg)
@@ -235,31 +232,20 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
n = strnlen((void *) str, len);
*len_ptr += n;
- if(n < len)
- return(1);
- return(0);
+ if (n < len)
+ return 1;
+ return 0;
}
-int strnlen_user_skas(const void __user *str, int len)
+int strnlen_user(const void __user *str, int len)
{
int count = 0, n;
- if(segment_eq(get_fs(), KERNEL_DS))
- return(strnlen((__force char*)str, len) + 1);
+ if (segment_eq(get_fs(), KERNEL_DS))
+ return strnlen((__force char*)str, len) + 1;
n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
- if(n == 0)
- return(count + 1);
- return(-EFAULT);
+ if (n == 0)
+ return count + 1;
+ return -EFAULT;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index e6a7778006a..36d89cf8d20 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -56,12 +56,12 @@ void smp_send_stop(void)
int i;
printk(KERN_INFO "Stopping all CPUs...");
- for(i = 0; i < num_online_cpus(); i++){
- if(i == current_thread->cpu)
+ for (i = 0; i < num_online_cpus(); i++) {
+ if (i == current_thread->cpu)
continue;
os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
}
- printk("done\n");
+ printk(KERN_INFO "done\n");
}
static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
@@ -72,7 +72,7 @@ static int idle_proc(void *cpup)
int cpu = (int) cpup, err;
err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
- if(err < 0)
+ if (err < 0)
panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
os_set_fd_async(cpu_data[cpu].ipi_pipe[0],
@@ -80,7 +80,7 @@ static int idle_proc(void *cpup)
wmb();
if (cpu_test_and_set(cpu, cpu_callin_map)) {
- printk("huh, CPU#%d already present??\n", cpu);
+ printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
BUG();
}
@@ -95,12 +95,11 @@ static int idle_proc(void *cpup)
static struct task_struct *idle_thread(int cpu)
{
struct task_struct *new_task;
- unsigned char c;
current->thread.request.u.thread.proc = idle_proc;
current->thread.request.u.thread.arg = (void *) cpu;
new_task = fork_idle(cpu);
- if(IS_ERR(new_task))
+ if (IS_ERR(new_task))
panic("copy_process failed in idle_thread, error = %ld",
PTR_ERR(new_task));
@@ -108,9 +107,7 @@ static struct task_struct *idle_thread(int cpu)
{ .pid = new_task->thread.mode.tt.extern_pid,
.task = new_task } );
idle_threads[cpu] = new_task;
- CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c,
- sizeof(c)),
- ({ panic("skas mode doesn't support SMP"); }));
+ panic("skas mode doesn't support SMP");
return new_task;
}
@@ -129,14 +126,14 @@ void smp_prepare_cpus(unsigned int maxcpus)
cpu_set(me, cpu_callin_map);
err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
- if(err < 0)
+ if (err < 0)
panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
os_set_fd_async(cpu_data[me].ipi_pipe[0],
current->thread.mode.tt.extern_pid);
- for(cpu = 1; cpu < ncpus; cpu++){
- printk("Booting processor %d...\n", cpu);
+ for (cpu = 1; cpu < ncpus; cpu++) {
+ printk(KERN_INFO "Booting processor %d...\n", cpu);
idle = idle_thread(cpu);
@@ -147,8 +144,8 @@ void smp_prepare_cpus(unsigned int maxcpus)
cpu_relax();
if (cpu_isset(cpu, cpu_callin_map))
- printk("done\n");
- else printk("failed\n");
+ printk(KERN_INFO "done\n");
+ else printk(KERN_INFO "failed\n");
}
}
@@ -190,13 +187,14 @@ void IPI_handler(int cpu)
break;
case 'S':
- printk("CPU#%d stopping\n", cpu);
- while(1)
+ printk(KERN_INFO "CPU#%d stopping\n", cpu);
+ while (1)
pause();
break;
default:
- printk("CPU#%d received unknown IPI [%c]!\n", cpu, c);
+ printk(KERN_ERR "CPU#%d received unknown IPI [%c]!\n",
+ cpu, c);
break;
}
}
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 7b3b67333ff..b9d92b2089a 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -1,27 +1,17 @@
/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/sched.h"
#include "linux/file.h"
-#include "linux/smp_lock.h"
-#include "linux/mm.h"
#include "linux/fs.h"
+#include "linux/mm.h"
+#include "linux/sched.h"
#include "linux/utsname.h"
-#include "linux/msg.h"
-#include "linux/shm.h"
-#include "linux/sys.h"
-#include "linux/syscalls.h"
-#include "linux/unistd.h"
-#include "linux/slab.h"
-#include "linux/utime.h"
+#include "asm/current.h"
#include "asm/mman.h"
#include "asm/uaccess.h"
-#include "kern_util.h"
-#include "sysdep/syscalls.h"
-#include "mode_kern.h"
-#include "choose-mode.h"
+#include "asm/unistd.h"
/* Unlocked, I don't care if this is a bit off */
int nsyscalls = 0;
@@ -34,7 +24,7 @@ long sys_fork(void)
ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
&current->thread.regs, 0, NULL, NULL);
current->thread.forking = 0;
- return(ret);
+ return ret;
}
long sys_vfork(void)
@@ -46,7 +36,7 @@ long sys_vfork(void)
UPT_SP(&current->thread.regs.regs),
&current->thread.regs, 0, NULL, NULL);
current->thread.forking = 0;
- return(ret);
+ return ret;
}
/* common code for old and new mmaps */
@@ -92,15 +82,15 @@ long old_mmap(unsigned long addr, unsigned long len,
*/
long sys_pipe(unsigned long __user * fildes)
{
- int fd[2];
- long error;
+ int fd[2];
+ long error;
- error = do_pipe(fd);
- if (!error) {
+ error = do_pipe(fd);
+ if (!error) {
if (copy_to_user(fildes, fd, sizeof(fd)))
- error = -EFAULT;
- }
- return error;
+ error = -EFAULT;
+ }
+ return error;
}
@@ -124,7 +114,7 @@ long sys_olduname(struct oldold_utsname __user * name)
if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
return -EFAULT;
- down_read(&uts_sem);
+ down_read(&uts_sem);
error = __copy_to_user(&name->sysname, &utsname()->sysname,
__OLD_UTS_LEN);
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 259c49da7ff..1ac746a9eae 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -1,189 +1,126 @@
/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/module.h"
-#include "linux/unistd.h"
-#include "linux/stddef.h"
-#include "linux/spinlock.h"
-#include "linux/time.h"
-#include "linux/sched.h"
+#include "linux/clockchips.h"
#include "linux/interrupt.h"
-#include "linux/init.h"
-#include "linux/delay.h"
-#include "linux/hrtimer.h"
+#include "linux/jiffies.h"
+#include "linux/threads.h"
#include "asm/irq.h"
#include "asm/param.h"
-#include "asm/current.h"
#include "kern_util.h"
-#include "mode.h"
#include "os.h"
-int hz(void)
-{
- return(HZ);
-}
-
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
- return (unsigned long long)jiffies_64 * (1000000000 / HZ);
+ return (unsigned long long)jiffies_64 * (NSEC_PER_SEC / HZ);
}
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
-static unsigned long long prev_nsecs[NR_CPUS];
-static long long delta[NR_CPUS]; /* Deviation per interval */
-#endif
+void timer_handler(int sig, struct uml_pt_regs *regs)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ do_IRQ(TIMER_IRQ, regs);
+ local_irq_restore(flags);
+}
-void timer_irq(union uml_pt_regs *regs)
+static void itimer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
{
- unsigned long long ticks = 0;
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
- int c = cpu();
- if(prev_nsecs[c]){
- /* We've had 1 tick */
- unsigned long long nsecs = os_nsecs();
-
- delta[c] += nsecs - prev_nsecs[c];
- prev_nsecs[c] = nsecs;
-
- /* Protect against the host clock being set backwards */
- if(delta[c] < 0)
- delta[c] = 0;
-
- ticks += (delta[c] * HZ) / BILLION;
- delta[c] -= (ticks * BILLION) / HZ;
- }
- else prev_nsecs[c] = os_nsecs();
-#else
- ticks = 1;
-#endif
- while(ticks > 0){
- do_IRQ(TIMER_IRQ, regs);
- ticks--;
+ switch(mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ set_interval();
+ break;
+
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_ONESHOT:
+ disable_timer();
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ break;
}
}
-/* Protects local_offset */
-static DEFINE_SPINLOCK(timer_spinlock);
-static unsigned long long local_offset = 0;
-
-static inline unsigned long long get_time(void)
+static int itimer_next_event(unsigned long delta,
+ struct clock_event_device *evt)
{
- unsigned long long nsecs;
- unsigned long flags;
-
- spin_lock_irqsave(&timer_spinlock, flags);
- nsecs = os_nsecs();
- nsecs += local_offset;
- spin_unlock_irqrestore(&timer_spinlock, flags);
-
- return nsecs;
+ return timer_one_shot(delta + 1);
}
-irqreturn_t um_timer(int irq, void *dev)
+static struct clock_event_device itimer_clockevent = {
+ .name = "itimer",
+ .rating = 250,
+ .cpumask = CPU_MASK_ALL,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = itimer_set_mode,
+ .set_next_event = itimer_next_event,
+ .shift = 32,
+ .irq = 0,
+};
+
+static irqreturn_t um_timer(int irq, void *dev)
{
- unsigned long long nsecs;
- unsigned long flags;
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- do_timer(1);
-
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
- nsecs = get_time();
-#else
- nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec +
- BILLION / HZ;
-#endif
- xtime.tv_sec = nsecs / NSEC_PER_SEC;
- xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
+ (*itimer_clockevent.event_handler)(&itimer_clockevent);
return IRQ_HANDLED;
}
-static void register_timer(void)
+static cycle_t itimer_read(void)
+{
+ return os_nsecs();
+}
+
+static struct clocksource itimer_clocksource = {
+ .name = "itimer",
+ .rating = 300,
+ .read = itimer_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .mult = 1,
+ .shift = 0,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init setup_itimer(void)
{
int err;
err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
- if(err != 0)
+ if (err != 0)
printk(KERN_ERR "register_timer : request_irq failed - "
"errno = %d\n", -err);
- err = set_interval(1);
- if(err != 0)
- printk(KERN_ERR "register_timer : set_interval failed - "
- "errno = %d\n", -err);
+ itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
+ itimer_clockevent.max_delta_ns =
+ clockevent_delta2ns(60 * HZ, &itimer_clockevent);
+ itimer_clockevent.min_delta_ns =
+ clockevent_delta2ns(1, &itimer_clockevent);
+ err = clocksource_register(&itimer_clocksource);
+ if (err) {
+ printk(KERN_ERR "clocksource_register returned %d\n", err);
+ return;
+ }
+ clockevents_register_device(&itimer_clockevent);
}
extern void (*late_time_init)(void);
-void time_init(void)
+void __init time_init(void)
{
long long nsecs;
- nsecs = os_nsecs();
- set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
- -nsecs % BILLION);
- set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION);
- late_time_init = register_timer;
-}
-
-void do_gettimeofday(struct timeval *tv)
-{
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
- unsigned long long nsecs = get_time();
-#else
- unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION +
- xtime.tv_nsec;
-#endif
- tv->tv_sec = nsecs / NSEC_PER_SEC;
- /* Careful about calculations here - this was originally done as
- * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
- * which gave bogus (> 1000000) values. Dunno why, suspect gcc
- * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
- * problem that I missed.
- */
- nsecs -= tv->tv_sec * NSEC_PER_SEC;
- tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC;
-}
-
-static inline void set_time(unsigned long long nsecs)
-{
- unsigned long long now;
- unsigned long flags;
-
- spin_lock_irqsave(&timer_spinlock, flags);
- now = os_nsecs();
- local_offset = nsecs - now;
- spin_unlock_irqrestore(&timer_spinlock, flags);
-
- clock_was_set();
-}
-
-int do_settimeofday(struct timespec *tv)
-{
- set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec);
-
- return 0;
-}
+ timer_init();
-void timer_handler(int sig, union uml_pt_regs *regs)
-{
- if(current_thread->cpu == 0)
- timer_irq(regs);
- local_irq_disable();
- irq_enter();
- update_process_times(CHOOSE_MODE(
- (UPT_SC(regs) && user_context(UPT_SP(regs))),
- (regs)->skas.is_user));
- irq_exit();
- local_irq_enable();
+ nsecs = os_nsecs();
+ set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC,
+ -nsecs % NSEC_PER_SEC);
+ set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC,
+ nsecs % NSEC_PER_SEC);
+ late_time_init = setup_itimer;
}
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 8a8d5285144..f4a0e407eee 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -1,130 +1,182 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include "linux/mm.h"
-#include "asm/page.h"
-#include "asm/pgalloc.h"
#include "asm/pgtable.h"
#include "asm/tlbflush.h"
-#include "choose-mode.h"
-#include "mode_kern.h"
#include "as-layout.h"
-#include "tlb.h"
-#include "mem.h"
#include "mem_user.h"
#include "os.h"
+#include "skas.h"
+#include "tlb.h"
+
+struct host_vm_change {
+ struct host_vm_op {
+ enum { NONE, MMAP, MUNMAP, MPROTECT } type;
+ union {
+ struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned int prot;
+ int fd;
+ __u64 offset;
+ } mmap;
+ struct {
+ unsigned long addr;
+ unsigned long len;
+ } munmap;
+ struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned int prot;
+ } mprotect;
+ } u;
+ } ops[1];
+ int index;
+ struct mm_id *id;
+ void *data;
+ int force;
+};
+
+#define INIT_HVC(mm, force) \
+ ((struct host_vm_change) \
+ { .ops = { { .type = NONE } }, \
+ .id = &mm->context.id, \
+ .data = NULL, \
+ .index = 0, \
+ .force = force })
+
+static int do_ops(struct host_vm_change *hvc, int end,
+ int finished)
+{
+ struct host_vm_op *op;
+ int i, ret = 0;
+
+ for (i = 0; i < end && !ret; i++) {
+ op = &hvc->ops[i];
+ switch(op->type) {
+ case MMAP:
+ ret = map(hvc->id, op->u.mmap.addr, op->u.mmap.len,
+ op->u.mmap.prot, op->u.mmap.fd,
+ op->u.mmap.offset, finished, &hvc->data);
+ break;
+ case MUNMAP:
+ ret = unmap(hvc->id, op->u.munmap.addr,
+ op->u.munmap.len, finished, &hvc->data);
+ break;
+ case MPROTECT:
+ ret = protect(hvc->id, op->u.mprotect.addr,
+ op->u.mprotect.len, op->u.mprotect.prot,
+ finished, &hvc->data);
+ break;
+ default:
+ printk(KERN_ERR "Unknown op type %d in do_ops\n",
+ op->type);
+ break;
+ }
+ }
+
+ return ret;
+}
static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
- unsigned int prot, struct host_vm_op *ops, int *index,
- int last_filled, union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *, struct host_vm_op *,
- int, int, void **))
+ unsigned int prot, struct host_vm_change *hvc)
{
__u64 offset;
struct host_vm_op *last;
int fd, ret = 0;
fd = phys_mapping(phys, &offset);
- if(*index != -1){
- last = &ops[*index];
- if((last->type == MMAP) &&
+ if (hvc->index != 0) {
+ last = &hvc->ops[hvc->index - 1];
+ if ((last->type == MMAP) &&
(last->u.mmap.addr + last->u.mmap.len == virt) &&
(last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) &&
- (last->u.mmap.offset + last->u.mmap.len == offset)){
+ (last->u.mmap.offset + last->u.mmap.len == offset)) {
last->u.mmap.len += len;
return 0;
}
}
- if(*index == last_filled){
- ret = (*do_ops)(mmu, ops, last_filled, 0, flush);
- *index = -1;
+ if (hvc->index == ARRAY_SIZE(hvc->ops)) {
+ ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
+ hvc->index = 0;
}
- ops[++*index] = ((struct host_vm_op) { .type = MMAP,
- .u = { .mmap = {
- .addr = virt,
- .len = len,
- .prot = prot,
- .fd = fd,
- .offset = offset }
+ hvc->ops[hvc->index++] = ((struct host_vm_op)
+ { .type = MMAP,
+ .u = { .mmap = { .addr = virt,
+ .len = len,
+ .prot = prot,
+ .fd = fd,
+ .offset = offset }
} });
return ret;
}
static int add_munmap(unsigned long addr, unsigned long len,
- struct host_vm_op *ops, int *index, int last_filled,
- union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *, struct host_vm_op *,
- int, int, void **))
+ struct host_vm_change *hvc)
{
struct host_vm_op *last;
int ret = 0;
- if(*index != -1){
- last = &ops[*index];
- if((last->type == MUNMAP) &&
- (last->u.munmap.addr + last->u.mmap.len == addr)){
+ if (hvc->index != 0) {
+ last = &hvc->ops[hvc->index - 1];
+ if ((last->type == MUNMAP) &&
+ (last->u.munmap.addr + last->u.mmap.len == addr)) {
last->u.munmap.len += len;
return 0;
}
}
- if(*index == last_filled){
- ret = (*do_ops)(mmu, ops, last_filled, 0, flush);
- *index = -1;
+ if (hvc->index == ARRAY_SIZE(hvc->ops)) {
+ ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
+ hvc->index = 0;
}
- ops[++*index] = ((struct host_vm_op) { .type = MUNMAP,
- .u = { .munmap = {
- .addr = addr,
- .len = len } } });
+ hvc->ops[hvc->index++] = ((struct host_vm_op)
+ { .type = MUNMAP,
+ .u = { .munmap = { .addr = addr,
+ .len = len } } });
return ret;
}
static int add_mprotect(unsigned long addr, unsigned long len,
- unsigned int prot, struct host_vm_op *ops, int *index,
- int last_filled, union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *, struct host_vm_op *,
- int, int, void **))
+ unsigned int prot, struct host_vm_change *hvc)
{
struct host_vm_op *last;
int ret = 0;
- if(*index != -1){
- last = &ops[*index];
- if((last->type == MPROTECT) &&
+ if (hvc->index != 0) {
+ last = &hvc->ops[hvc->index - 1];
+ if ((last->type == MPROTECT) &&
(last->u.mprotect.addr + last->u.mprotect.len == addr) &&
- (last->u.mprotect.prot == prot)){
+ (last->u.mprotect.prot == prot)) {
last->u.mprotect.len += len;
return 0;
}
}
- if(*index == last_filled){
- ret = (*do_ops)(mmu, ops, last_filled, 0, flush);
- *index = -1;
+ if (hvc->index == ARRAY_SIZE(hvc->ops)) {
+ ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
+ hvc->index = 0;
}
- ops[++*index] = ((struct host_vm_op) { .type = MPROTECT,
- .u = { .mprotect = {
- .addr = addr,
- .len = len,
- .prot = prot } } });
+ hvc->ops[hvc->index++] = ((struct host_vm_op)
+ { .type = MPROTECT,
+ .u = { .mprotect = { .addr = addr,
+ .len = len,
+ .prot = prot } } });
return ret;
}
#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
- unsigned long end, struct host_vm_op *ops,
- int last_op, int *op_index, int force,
- union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *,
- struct host_vm_op *, int, int,
- void **))
+ unsigned long end,
+ struct host_vm_change *hvc)
{
pte_t *pte;
int r, w, x, prot, ret = 0;
@@ -142,29 +194,22 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
}
prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
(x ? UM_PROT_EXEC : 0));
- if(force || pte_newpage(*pte)){
- if(pte_present(*pte))
+ if (hvc->force || pte_newpage(*pte)) {
+ if (pte_present(*pte))
ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
- PAGE_SIZE, prot, ops, op_index,
- last_op, mmu, flush, do_ops);
- else ret = add_munmap(addr, PAGE_SIZE, ops, op_index,
- last_op, mmu, flush, do_ops);
+ PAGE_SIZE, prot, hvc);
+ else ret = add_munmap(addr, PAGE_SIZE, hvc);
}
- else if(pte_newprot(*pte))
- ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index,
- last_op, mmu, flush, do_ops);
+ else if (pte_newprot(*pte))
+ ret = add_mprotect(addr, PAGE_SIZE, prot, hvc);
*pte = pte_mkuptodate(*pte);
} while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret));
return ret;
}
static inline int update_pmd_range(pud_t *pud, unsigned long addr,
- unsigned long end, struct host_vm_op *ops,
- int last_op, int *op_index, int force,
- union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *,
- struct host_vm_op *, int, int,
- void **))
+ unsigned long end,
+ struct host_vm_change *hvc)
{
pmd_t *pmd;
unsigned long next;
@@ -173,28 +218,20 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr,
pmd = pmd_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
- if(!pmd_present(*pmd)){
- if(force || pmd_newpage(*pmd)){
- ret = add_munmap(addr, next - addr, ops,
- op_index, last_op, mmu,
- flush, do_ops);
+ if (!pmd_present(*pmd)) {
+ if (hvc->force || pmd_newpage(*pmd)) {
+ ret = add_munmap(addr, next - addr, hvc);
pmd_mkuptodate(*pmd);
}
}
- else ret = update_pte_range(pmd, addr, next, ops, last_op,
- op_index, force, mmu, flush,
- do_ops);
+ else ret = update_pte_range(pmd, addr, next, hvc);
} while (pmd++, addr = next, ((addr != end) && !ret));
return ret;
}
static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
- unsigned long end, struct host_vm_op *ops,
- int last_op, int *op_index, int force,
- union mm_context *mmu, void **flush,
- int (*do_ops)(union mm_context *,
- struct host_vm_op *, int, int,
- void **))
+ unsigned long end,
+ struct host_vm_change *hvc)
{
pud_t *pud;
unsigned long next;
@@ -203,56 +240,45 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
pud = pud_offset(pgd, addr);
do {
next = pud_addr_end(addr, end);
- if(!pud_present(*pud)){
- if(force || pud_newpage(*pud)){
- ret = add_munmap(addr, next - addr, ops,
- op_index, last_op, mmu,
- flush, do_ops);
+ if (!pud_present(*pud)) {
+ if (hvc->force || pud_newpage(*pud)) {
+ ret = add_munmap(addr, next - addr, hvc);
pud_mkuptodate(*pud);
}
}
- else ret = update_pmd_range(pud, addr, next, ops, last_op,
- op_index, force, mmu, flush,
- do_ops);
+ else ret = update_pmd_range(pud, addr, next, hvc);
} while (pud++, addr = next, ((addr != end) && !ret));
return ret;
}
void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force,
- int (*do_ops)(union mm_context *, struct host_vm_op *,
- int, int, void **))
+ unsigned long end_addr, int force)
{
pgd_t *pgd;
- union mm_context *mmu = &mm->context;
- struct host_vm_op ops[1];
+ struct host_vm_change hvc;
unsigned long addr = start_addr, next;
- int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1;
- void *flush = NULL;
+ int ret = 0;
- ops[0].type = NONE;
+ hvc = INIT_HVC(mm, force);
pgd = pgd_offset(mm, addr);
do {
next = pgd_addr_end(addr, end_addr);
- if(!pgd_present(*pgd)){
- if (force || pgd_newpage(*pgd)){
- ret = add_munmap(addr, next - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
+ if (!pgd_present(*pgd)) {
+ if (force || pgd_newpage(*pgd)) {
+ ret = add_munmap(addr, next - addr, &hvc);
pgd_mkuptodate(*pgd);
}
}
- else ret = update_pud_range(pgd, addr, next, ops, last_op,
- &op_index, force, mmu, &flush,
- do_ops);
+ else ret = update_pud_range(pgd, addr, next, &hvc);
} while (pgd++, addr = next, ((addr != end_addr) && !ret));
- if(!ret)
- ret = (*do_ops)(mmu, ops, op_index, 1, &flush);
+ if (!ret)
+ ret = do_ops(&hvc, hvc.index, 1);
/* This is not an else because ret is modified above */
- if(ret) {
- printk("fix_range_common: failed, killing current process\n");
+ if (ret) {
+ printk(KERN_ERR "fix_range_common: failed, killing current "
+ "process\n");
force_sig(SIGKILL, current);
}
}
@@ -268,17 +294,17 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
int updated = 0, err;
mm = &init_mm;
- for(addr = start; addr < end;){
+ for (addr = start; addr < end;) {
pgd = pgd_offset(mm, addr);
- if(!pgd_present(*pgd)){
+ if (!pgd_present(*pgd)) {
last = ADD_ROUND(addr, PGDIR_SIZE);
- if(last > end)
+ if (last > end)
last = end;
- if(pgd_newpage(*pgd)){
+ if (pgd_newpage(*pgd)) {
updated = 1;
err = os_unmap_memory((void *) addr,
last - addr);
- if(err < 0)
+ if (err < 0)
panic("munmap failed, errno = %d\n",
-err);
}
@@ -287,15 +313,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
}
pud = pud_offset(pgd, addr);
- if(!pud_present(*pud)){
+ if (!pud_present(*pud)) {
last = ADD_ROUND(addr, PUD_SIZE);
- if(last > end)
+ if (last > end)
last = end;
- if(pud_newpage(*pud)){
+ if (pud_newpage(*pud)) {
updated = 1;
err = os_unmap_memory((void *) addr,
last - addr);
- if(err < 0)
+ if (err < 0)
panic("munmap failed, errno = %d\n",
-err);
}
@@ -304,15 +330,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
}
pmd = pmd_offset(pud, addr);
- if(!pmd_present(*pmd)){
+ if (!pmd_present(*pmd)) {
last = ADD_ROUND(addr, PMD_SIZE);
- if(last > end)
+ if (last > end)
last = end;
- if(pmd_newpage(*pmd)){
+ if (pmd_newpage(*pmd)) {
updated = 1;
err = os_unmap_memory((void *) addr,
last - addr);
- if(err < 0)
+ if (err < 0)
panic("munmap failed, errno = %d\n",
-err);
}
@@ -321,45 +347,110 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
}
pte = pte_offset_kernel(pmd, addr);
- if(!pte_present(*pte) || pte_newpage(*pte)){
+ if (!pte_present(*pte) || pte_newpage(*pte)) {
updated = 1;
err = os_unmap_memory((void *) addr,
PAGE_SIZE);
- if(err < 0)
+ if (err < 0)
panic("munmap failed, errno = %d\n",
-err);
- if(pte_present(*pte))
+ if (pte_present(*pte))
map_memory(addr,
pte_val(*pte) & PAGE_MASK,
PAGE_SIZE, 1, 1, 1);
}
- else if(pte_newprot(*pte)){
+ else if (pte_newprot(*pte)) {
updated = 1;
os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
}
addr += PAGE_SIZE;
}
- return(updated);
+ return updated;
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ struct mm_struct *mm = vma->vm_mm;
+ void *flush = NULL;
+ int r, w, x, prot, err = 0;
+ struct mm_id *mm_id;
+
+ address &= PAGE_MASK;
+ pgd = pgd_offset(mm, address);
+ if (!pgd_present(*pgd))
+ goto kill;
+
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ goto kill;
+
+ pmd = pmd_offset(pud, address);
+ if (!pmd_present(*pmd))
+ goto kill;
+
+ pte = pte_offset_kernel(pmd, address);
+
+ r = pte_read(*pte);
+ w = pte_write(*pte);
+ x = pte_exec(*pte);
+ if (!pte_young(*pte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*pte)) {
+ w = 0;
+ }
+
+ mm_id = &mm->context.id;
+ prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
+ (x ? UM_PROT_EXEC : 0));
+ if (pte_newpage(*pte)) {
+ if (pte_present(*pte)) {
+ unsigned long long offset;
+ int fd;
+
+ fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
+ err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
+ 1, &flush);
+ }
+ else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
+ }
+ else if (pte_newprot(*pte))
+ err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
+
+ if (err)
+ goto kill;
+
+ *pte = pte_mkuptodate(*pte);
+
+ return;
+
+kill:
+ printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address);
+ force_sig(SIGKILL, current);
}
pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
{
- return(pgd_offset(mm, address));
+ return pgd_offset(mm, address);
}
pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
{
- return(pud_offset(pgd, address));
+ return pud_offset(pgd, address);
}
pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
{
- return(pmd_offset(pud, address));
+ return pmd_offset(pud, address);
}
pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
{
- return(pte_offset_kernel(pmd, address));
+ return pte_offset_kernel(pmd, address);
}
pte_t *addr_pte(struct task_struct *task, unsigned long addr)
@@ -368,7 +459,7 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
pud_t *pud = pud_offset(pgd, addr);
pmd_t *pmd = pmd_offset(pud, addr);
- return(pte_offset_map(pmd, addr));
+ return pte_offset_map(pmd, addr);
}
void flush_tlb_all(void)
@@ -378,35 +469,58 @@ void flush_tlb_all(void)
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
- CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
- flush_tlb_kernel_range_common, start, end);
+ flush_tlb_kernel_range_common(start, end);
}
void flush_tlb_kernel_vm(void)
{
- CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
- flush_tlb_kernel_range_common(start_vm, end_vm));
+ flush_tlb_kernel_range_common(start_vm, end_vm);
}
void __flush_tlb_one(unsigned long addr)
{
- CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
+ flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE);
+}
+
+static void fix_range(struct mm_struct *mm, unsigned long start_addr,
+ unsigned long end_addr, int force)
+{
+ if (!proc_mm && (end_addr > STUB_START))
+ end_addr = STUB_START;
+
+ fix_range_common(mm, start_addr, end_addr, force);
}
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
- CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
- end);
+ if (vma->vm_mm == NULL)
+ flush_tlb_kernel_range_common(start, end);
+ else fix_range(vma->vm_mm, start, end, 0);
}
void flush_tlb_mm(struct mm_struct *mm)
{
- CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
+ unsigned long end;
+
+ /*
+ * Don't bother flushing if this address space is about to be
+ * destroyed.
+ */
+ if (atomic_read(&mm->mm_users) == 0)
+ return;
+
+ end = proc_mm ? task_size : STUB_START;
+ fix_range(mm, 0, end, 0);
}
void force_flush_all(void)
{
- CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
-}
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma = mm->mmap;
+ while (vma != NULL) {
+ fix_range(mm, vma->vm_start, vma->vm_end, 1);
+ vma = vma->vm_next;
+ }
+}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 3850d53f79f..bd060551e61 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -1,40 +1,24 @@
/*
- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "asm/errno.h"
-#include "linux/sched.h"
-#include "linux/mm.h"
-#include "linux/spinlock.h"
-#include "linux/init.h"
-#include "linux/ptrace.h"
-#include "asm/semaphore.h"
-#include "asm/pgtable.h"
-#include "asm/pgalloc.h"
-#include "asm/tlbflush.h"
-#include "asm/a.out.h"
-#include "asm/current.h"
-#include "asm/irq.h"
-#include "sysdep/sigcontext.h"
-#include "kern_util.h"
-#include "as-layout.h"
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <asm/current.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
#include "arch.h"
-#include "kern.h"
-#include "chan_kern.h"
-#include "mconsole_kern.h"
-#include "mem.h"
-#include "mem_kern.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/ptrace.h"
-#include "os.h"
-#ifdef CONFIG_MODE_SKAS
-#include "skas.h"
-#endif
+#include "as-layout.h"
+#include "kern_util.h"
#include "os.h"
+#include "sysdep/sigcontext.h"
-/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
+/*
+ * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by
+ * segv().
+ */
int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out)
{
@@ -48,31 +32,33 @@ int handle_page_fault(unsigned long address, unsigned long ip,
*code_out = SEGV_MAPERR;
- /* If the fault was during atomic operation, don't take the fault, just
- * fail. */
+ /*
+ * If the fault was during atomic operation, don't take the fault, just
+ * fail.
+ */
if (in_atomic())
goto out_nosemaphore;
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
- if(!vma)
+ if (!vma)
goto out;
- else if(vma->vm_start <= address)
+ else if (vma->vm_start <= address)
goto good_area;
- else if(!(vma->vm_flags & VM_GROWSDOWN))
+ else if (!(vma->vm_flags & VM_GROWSDOWN))
goto out;
- else if(is_user && !ARCH_IS_STACKGROW(address))
+ else if (is_user && !ARCH_IS_STACKGROW(address))
goto out;
- else if(expand_stack(vma, address))
+ else if (expand_stack(vma, address))
goto out;
good_area:
*code_out = SEGV_ACCERR;
- if(is_write && !(vma->vm_flags & VM_WRITE))
+ if (is_write && !(vma->vm_flags & VM_WRITE))
goto out;
/* Don't require VM_READ|VM_EXEC for write faults! */
- if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
+ if (!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
goto out;
do {
@@ -98,9 +84,10 @@ survive:
pud = pud_offset(pgd, address);
pmd = pmd_offset(pud, address);
pte = pte_offset_kernel(pmd, address);
- } while(!pte_present(*pte));
+ } while (!pte_present(*pte));
err = 0;
- /* The below warning was added in place of
+ /*
+ * The below warning was added in place of
* pte_mkyoung(); if (is_write) pte_mkdirty();
* If it's triggered, we'd see normally a hang here (a clean pte is
* marked read-only to emulate the dirty bit).
@@ -114,7 +101,7 @@ survive:
out:
up_read(&mm->mmap_sem);
out_nosemaphore:
- return(err);
+ return err;
/*
* We ran out of memory, or some other thing happened to us that made
@@ -141,11 +128,11 @@ static void bad_segv(struct faultinfo fi, unsigned long ip)
force_sig_info(SIGSEGV, &si, current);
}
-static void segv_handler(int sig, union uml_pt_regs *regs)
+static void segv_handler(int sig, struct uml_pt_regs *regs)
{
struct faultinfo * fi = UPT_FAULTINFO(regs);
- if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
+ if (UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)) {
bad_segv(*fi, UPT_IP(regs));
return;
}
@@ -159,45 +146,49 @@ static void segv_handler(int sig, union uml_pt_regs *regs)
* give us bad data!
*/
unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
- union uml_pt_regs *regs)
+ struct uml_pt_regs *regs)
{
struct siginfo si;
- void *catcher;
+ jmp_buf *catcher;
int err;
int is_write = FAULT_WRITE(fi);
unsigned long address = FAULT_ADDRESS(fi);
- if(!is_user && (address >= start_vm) && (address < end_vm)){
+ if (!is_user && (address >= start_vm) && (address < end_vm)) {
flush_tlb_kernel_vm();
return 0;
}
- else if(current->mm == NULL) {
+ else if (current->mm == NULL) {
show_regs(container_of(regs, struct pt_regs, regs));
- panic("Segfault with no mm");
+ panic("Segfault with no mm");
}
if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
- err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
+ err = handle_page_fault(address, ip, is_write, is_user,
+ &si.si_code);
else {
err = -EFAULT;
- /* A thread accessed NULL, we get a fault, but CR2 is invalid.
- * This code is used in __do_copy_from_user() of TT mode. */
+ /*
+ * A thread accessed NULL, we get a fault, but CR2 is invalid.
+ * This code is used in __do_copy_from_user() of TT mode.
+ * XXX tt mode is gone, so maybe this isn't needed any more
+ */
address = 0;
}
catcher = current->thread.fault_catcher;
- if(!err)
+ if (!err)
return 0;
- else if(catcher != NULL){
+ else if (catcher != NULL) {
current->thread.fault_addr = (void *) address;
- do_longjmp(catcher, 1);
+ UML_LONGJMP(catcher, 1);
}
- else if(current->thread.fault_addr != NULL)
+ else if (current->thread.fault_addr != NULL)
panic("fault_addr set but no fault catcher");
- else if(!is_user && arch_fixup(ip, regs))
+ else if (!is_user && arch_fixup(ip, regs))
return 0;
- if(!is_user) {
+ if (!is_user) {
show_regs(container_of(regs, struct pt_regs, regs));
panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
address, ip);
@@ -211,7 +202,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
current->thread.arch.faultinfo = fi;
force_sig_info(SIGBUS, &si, current);
} else if (err == -ENOMEM) {
- printk("VM: killing process %s\n", current->comm);
+ printk(KERN_INFO "VM: killing process %s\n", current->comm);
do_exit(SIGKILL);
} else {
BUG_ON(err != -EFAULT);
@@ -223,15 +214,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
return 0;
}
-void relay_signal(int sig, union uml_pt_regs *regs)
+void relay_signal(int sig, struct uml_pt_regs *regs)
{
- if(arch_handle_signal(sig, regs))
+ if (arch_handle_signal(sig, regs))
return;
- if(!UPT_IS_USER(regs)){
- if(sig == SIGBUS)
- printk("Bus error - the host /dev/shm or /tmp mount "
- "likely just ran out of space\n");
+ if (!UPT_IS_USER(regs)) {
+ if (sig == SIGBUS)
+ printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
+ "mount likely just ran out of space\n");
panic("Kernel mode signal %d", sig);
}
@@ -239,14 +230,14 @@ void relay_signal(int sig, union uml_pt_regs *regs)
force_sig(sig, current);
}
-static void bus_handler(int sig, union uml_pt_regs *regs)
+static void bus_handler(int sig, struct uml_pt_regs *regs)
{
- if(current->thread.fault_catcher != NULL)
- do_longjmp(current->thread.fault_catcher, 1);
+ if (current->thread.fault_catcher != NULL)
+ UML_LONGJMP(current->thread.fault_catcher, 1);
else relay_signal(sig, regs);
}
-static void winch(int sig, union uml_pt_regs *regs)
+static void winch(int sig, struct uml_pt_regs *regs)
{
do_IRQ(WINCH_IRQ, regs);
}
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
deleted file mode 100644
index 6939e5af847..00000000000
--- a/arch/um/kernel/tt/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
-# Licensed under the GPL
-#
-
-obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
- syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \
- uaccess.o uaccess_user.o
-
-obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
-
-USER_OBJS := gdb.o tracer.o
-
-include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
deleted file mode 100644
index 40126cb5180..00000000000
--- a/arch/um/kernel/tt/exec_kern.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/kernel.h"
-#include "linux/mm.h"
-#include "asm/signal.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "asm/pgalloc.h"
-#include "asm/tlbflush.h"
-#include "kern_util.h"
-#include "irq_user.h"
-#include "mem_user.h"
-#include "os.h"
-#include "tlb.h"
-#include "mode.h"
-
-static int exec_tramp(void *sig_stack)
-{
- init_new_thread_stack(sig_stack, NULL);
- init_new_thread_signals();
- os_stop_process(os_getpid());
- return(0);
-}
-
-void flush_thread_tt(void)
-{
- unsigned long stack;
- int new_pid;
-
- stack = alloc_stack(0, 0);
- if(stack == 0){
- printk(KERN_ERR
- "flush_thread : failed to allocate temporary stack\n");
- do_exit(SIGKILL);
- }
-
- new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp);
- if(new_pid < 0){
- printk(KERN_ERR
- "flush_thread : new thread failed, errno = %d\n",
- -new_pid);
- do_exit(SIGKILL);
- }
-
- if(current_thread->cpu == 0)
- forward_interrupts(new_pid);
- current->thread.request.op = OP_EXEC;
- current->thread.request.u.exec.pid = new_pid;
- unprotect_stack((unsigned long) current_thread);
- os_usr1_process(os_getpid());
- change_sig(SIGUSR1, 1);
-
- change_sig(SIGUSR1, 0);
- enable_timer();
- free_page(stack);
- protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
- stack_protections((unsigned long) current_thread);
- force_flush_all();
- unblock_signals();
-}
-
-void start_thread_tt(struct pt_regs *regs, unsigned long eip,
- unsigned long esp)
-{
- set_fs(USER_DS);
- flush_tlb_mm(current->mm);
- PT_REGS_IP(regs) = eip;
- PT_REGS_SP(regs) = esp;
- PT_FIX_EXEC_STACK(esp);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c
deleted file mode 100644
index 7b5f2181cf5..00000000000
--- a/arch/um/kernel/tt/exec_user.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sched.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include "kern_util.h"
-#include "user.h"
-#include "ptrace_user.h"
-#include "os.h"
-
-void do_exec(int old_pid, int new_pid)
-{
- unsigned long regs[FRAME_SIZE];
- int err;
-
- if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
- (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
- tracer_panic("do_exec failed to attach proc - errno = %d",
- errno);
-
- CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
- if (err < 0)
- tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
- errno);
-
- if(ptrace_getregs(old_pid, regs) < 0)
- tracer_panic("do_exec failed to get registers - errno = %d",
- errno);
-
- os_kill_ptraced_process(old_pid, 0);
-
- if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
- tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
-
- if(ptrace_setregs(new_pid, regs) < 0)
- tracer_panic("do_exec failed to start new proc - errno = %d",
- errno);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
deleted file mode 100644
index 030e4658f36..00000000000
--- a/arch/um/kernel/tt/gdb.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-#include "ptrace_user.h"
-#include "uml-config.h"
-#include "kern_constants.h"
-#include "chan_user.h"
-#include "init.h"
-#include "user.h"
-#include "debug.h"
-#include "kern_util.h"
-#include "tt.h"
-#include "sysdep/thread.h"
-#include "os.h"
-
-extern int debugger_pid;
-extern int debugger_fd;
-extern int debugger_parent;
-
-int detach(int pid, int sig)
-{
- return(ptrace(PTRACE_DETACH, pid, 0, sig));
-}
-
-int attach(int pid)
-{
- int err;
-
- err = ptrace(PTRACE_ATTACH, pid, 0, 0);
- if(err < 0) return(-errno);
- else return(err);
-}
-
-int cont(int pid)
-{
- return(ptrace(PTRACE_CONT, pid, 0, 0));
-}
-
-#ifdef UML_CONFIG_PT_PROXY
-
-int debugger_signal(int status, pid_t pid)
-{
- return(debugger_proxy(status, pid));
-}
-
-void child_signal(pid_t pid, int status)
-{
- child_proxy(pid, status);
-}
-
-static void gdb_announce(char *dev_name, int dev)
-{
- printf("gdb assigned device '%s'\n", dev_name);
-}
-
-static struct chan_opts opts = {
- .announce = gdb_announce,
- .xterm_title = "UML kernel debugger",
- .raw = 0,
- .tramp_stack = 0,
- .in_kernel = 0,
-};
-
-/* Accessed by the tracing thread, which automatically serializes access */
-static void *xterm_data;
-static int xterm_fd;
-
-extern void *xterm_init(char *, int, struct chan_opts *);
-extern int xterm_open(int, int, int, void *, char **);
-extern void xterm_close(int, void *);
-
-int open_gdb_chan(void)
-{
- char stack[UM_KERN_PAGE_SIZE], *dummy;
-
- opts.tramp_stack = (unsigned long) stack;
- xterm_data = xterm_init("", 0, &opts);
- xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
- return(xterm_fd);
-}
-
-static void exit_debugger_cb(void *unused)
-{
- if(debugger_pid != -1){
- if(gdb_pid != -1){
- fake_child_exit();
- gdb_pid = -1;
- }
- else kill_child_dead(debugger_pid);
- debugger_pid = -1;
- if(debugger_parent != -1)
- detach(debugger_parent, SIGINT);
- }
- if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
-}
-
-static void exit_debugger(void)
-{
- initial_thread_cb(exit_debugger_cb, NULL);
-}
-
-__uml_exitcall(exit_debugger);
-
-struct gdb_data {
- char *str;
- int err;
-};
-
-extern char *linux_prog;
-
-static void config_gdb_cb(void *arg)
-{
- struct gdb_data *data = arg;
- void *task;
- int pid;
-
- data->err = -1;
- if(debugger_pid != -1) exit_debugger_cb(NULL);
- if(!strncmp(data->str, "pid,", strlen("pid,"))){
- data->str += strlen("pid,");
- pid = strtoul(data->str, NULL, 0);
- task = cpu_tasks[0].task;
- debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
- if(debugger_pid != -1){
- data->err = 0;
- gdb_pid = pid;
- }
- return;
- }
- data->err = 0;
- debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
- init_proxy(debugger_pid, 0, 0);
-}
-
-int gdb_config(char *str, char **error_out)
-{
- struct gdb_data data;
-
- if(*str++ != '=') return(-1);
- data.str = str;
- initial_thread_cb(config_gdb_cb, &data);
- return(data.err);
-}
-
-void remove_gdb_cb(void *unused)
-{
- exit_debugger_cb(NULL);
-}
-
-int gdb_remove(int unused, char **error_out)
-{
- initial_thread_cb(remove_gdb_cb, NULL);
- return 0;
-}
-
-void signal_usr1(int sig)
-{
- if(debugger_pid != -1){
- printf("The debugger is already running\n");
- return;
- }
- debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
- init_proxy(debugger_pid, 0, 0);
-}
-
-int init_ptrace_proxy(int idle_pid, int startup, int stop)
-{
- int pid, status;
-
- pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
- status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
- if(pid < 0){
- cont(idle_pid);
- return(-1);
- }
- init_proxy(pid, 1, status);
- return(pid);
-}
-
-int attach_debugger(int idle_pid, int pid, int stop)
-{
- int status = 0, err;
-
- err = attach(pid);
- if(err < 0){
- printf("Failed to attach pid %d, errno = %d\n", pid, -err);
- return(-1);
- }
- if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
- init_proxy(pid, 1, status);
- return(pid);
-}
-
-#ifdef notdef /* Put this back in when it does something useful */
-static int __init uml_gdb_init_setup(char *line, int *add)
-{
- gdb_init = uml_strdup(line);
- return 0;
-}
-
-__uml_setup("gdb=", uml_gdb_init_setup,
-"gdb=<channel description>\n\n"
-);
-#endif
-
-static int __init uml_gdb_pid_setup(char *line, int *add)
-{
- gdb_pid = strtoul(line, NULL, 0);
- *add = 0;
- return 0;
-}
-
-__uml_setup("gdb-pid=", uml_gdb_pid_setup,
-"gdb-pid=<pid>\n"
-" gdb-pid is used to attach an external debugger to UML. This may be\n"
-" an already-running gdb or a debugger-like process like strace.\n\n"
-);
-
-#else
-
-int debugger_signal(int status, pid_t pid){ return(0); }
-void child_signal(pid_t pid, int status){ }
-int init_ptrace_proxy(int idle_pid, int startup, int stop)
-{
- printf("debug requested when CONFIG_PT_PROXY is off\n");
- kill_child_dead(idle_pid);
- exit(1);
-}
-
-void signal_usr1(int sig)
-{
- printf("debug requested when CONFIG_PT_PROXY is off\n");
-}
-
-int attach_debugger(int idle_pid, int pid, int stop)
-{
- printf("attach_debugger called when CONFIG_PT_PROXY "
- "is off\n");
- return(-1);
-}
-
-int config_gdb(char *str)
-{
- return(-1);
-}
-
-int remove_gdb(void)
-{
- return(-1);
-}
-
-int init_parent_proxy(int pid)
-{
- return(-1);
-}
-
-void debugger_parent_signal(int status, int pid)
-{
-}
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c
deleted file mode 100644
index 03b06bc0077..00000000000
--- a/arch/um/kernel/tt/gdb_kern.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/init.h"
-#include "mconsole_kern.h"
-
-#ifdef CONFIG_MCONSOLE
-
-extern int gdb_config(char *str, char **error_out);
-extern int gdb_remove(int n, char **error_out);
-
-static struct mc_device gdb_mc = {
- .list = INIT_LIST_HEAD(gdb_mc.list),
- .name = "gdb",
- .config = gdb_config,
- .remove = gdb_remove,
-};
-
-int gdb_mc_init(void)
-{
- mconsole_register_dev(&gdb_mc);
- return(0);
-}
-
-__initcall(gdb_mc_init);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h
deleted file mode 100644
index e171e15fead..00000000000
--- a/arch/um/kernel/tt/include/mode-tt.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __MODE_TT_H__
-#define __MODE_TT_H__
-
-#include "sysdep/ptrace.h"
-
-enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
-
-extern int tracing_pid;
-
-extern int tracer(int (*init_proc)(void *), void *sp);
-extern void sig_handler_common_tt(int sig, void *sc);
-extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
-extern void reboot_tt(void);
-extern void halt_tt(void);
-extern int is_tracer_winch(int pid, int fd, void *data);
-extern void kill_off_processes_tt(void);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c
deleted file mode 100644
index 84a9385a8fe..00000000000
--- a/arch/um/kernel/tt/ksyms.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/module.h"
-#include "asm/uaccess.h"
-#include "mode.h"
-
-EXPORT_SYMBOL(__do_copy_from_user);
-EXPORT_SYMBOL(__do_copy_to_user);
-EXPORT_SYMBOL(__do_strncpy_from_user);
-EXPORT_SYMBOL(__do_strnlen_user);
-EXPORT_SYMBOL(__do_clear_user);
-EXPORT_SYMBOL(clear_user_tt);
-
-EXPORT_SYMBOL(tracing_pid);
-EXPORT_SYMBOL(honeypot);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
deleted file mode 100644
index d0c3c4975f2..00000000000
--- a/arch/um/kernel/tt/mem.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/stddef.h"
-#include "linux/mm.h"
-#include "asm/uaccess.h"
-#include "mem_user.h"
-#include "kern_util.h"
-#include "kern.h"
-#include "tt.h"
-
-void before_mem_tt(unsigned long brk_start)
-{
- if(debug)
- remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
- remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
- remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
-}
-
-#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
-#define START (CONFIG_TOP_ADDR - SIZE)
-
-unsigned long set_task_sizes_tt(unsigned long *task_size_out)
-{
- unsigned long host_task_size;
-
- /* Round up to the nearest 4M */
- host_task_size = ROUND_4M((unsigned long) &host_task_size);
- *task_size_out = START;
-
- return host_task_size;
-}
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
deleted file mode 100644
index 9774f6360c3..00000000000
--- a/arch/um/kernel/tt/mem_user.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include "tt.h"
-#include "mem_user.h"
-#include "os.h"
-
-void remap_data(void *segment_start, void *segment_end, int w)
-{
- void *addr;
- unsigned long size;
- int data, prot;
-
- if(w) prot = PROT_WRITE;
- else prot = 0;
- prot |= PROT_READ | PROT_EXEC;
- size = (unsigned long) segment_end -
- (unsigned long) segment_start;
- data = create_mem_file(size);
- addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
- if(addr == MAP_FAILED){
- perror("mapping new data segment");
- exit(1);
- }
- memcpy(addr, segment_start, size);
- if(switcheroo(data, prot, addr, segment_start, size) < 0){
- printf("switcheroo failed\n");
- exit(1);
- }
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
deleted file mode 100644
index 74347adf81b..00000000000
--- a/arch/um/kernel/tt/process_kern.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include "linux/sched.h"
-#include "linux/signal.h"
-#include "linux/kernel.h"
-#include "linux/interrupt.h"
-#include "linux/ptrace.h"
-#include "asm/system.h"
-#include "asm/pgalloc.h"
-#include "asm/ptrace.h"
-#include "asm/tlbflush.h"
-#include "irq_user.h"
-#include "kern_util.h"
-#include "os.h"
-#include "kern.h"
-#include "sigcontext.h"
-#include "mem_user.h"
-#include "tlb.h"
-#include "mode.h"
-#include "mode_kern.h"
-#include "init.h"
-#include "tt.h"
-
-void switch_to_tt(void *prev, void *next)
-{
- struct task_struct *from, *to, *prev_sched;
- unsigned long flags;
- int err, vtalrm, alrm, prof, cpu;
- char c;
-
- from = prev;
- to = next;
-
- cpu = task_thread_info(from)->cpu;
- if(cpu == 0)
- forward_interrupts(to->thread.mode.tt.extern_pid);
-#ifdef CONFIG_SMP
- forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
-#endif
- local_irq_save(flags);
-
- vtalrm = change_sig(SIGVTALRM, 0);
- alrm = change_sig(SIGALRM, 0);
- prof = change_sig(SIGPROF, 0);
-
- forward_pending_sigio(to->thread.mode.tt.extern_pid);
-
- c = 0;
-
- /* Notice that here we "up" the semaphore on which "to" is waiting, and
- * below (the read) we wait on this semaphore (which is implemented by
- * switch_pipe) and go sleeping. Thus, after that, we have resumed in
- * "to", and can't use any more the value of "from" (which is outdated),
- * nor the value in "to" (since it was the task which stole us the CPU,
- * which we don't care about). */
-
- err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
- if(err != sizeof(c))
- panic("write of switch_pipe failed, err = %d", -err);
-
- if(from->thread.mode.tt.switch_pipe[0] == -1)
- os_kill_process(os_getpid(), 0);
-
- err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c,
- sizeof(c));
- if(err != sizeof(c))
- panic("read of switch_pipe failed, errno = %d", -err);
-
- /* If the process that we have just scheduled away from has exited,
- * then it needs to be killed here. The reason is that, even though
- * it will kill itself when it next runs, that may be too late. Its
- * stack will be freed, possibly before then, and if that happens,
- * we have a use-after-free situation. So, it gets killed here
- * in case it has not already killed itself.
- */
- prev_sched = current->thread.prev_sched;
- if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
- os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
-
- change_sig(SIGVTALRM, vtalrm);
- change_sig(SIGALRM, alrm);
- change_sig(SIGPROF, prof);
-
- arch_switch_to_tt(prev_sched, current);
-
- flush_tlb_all();
- local_irq_restore(flags);
-}
-
-void release_thread_tt(struct task_struct *task)
-{
- int pid = task->thread.mode.tt.extern_pid;
-
- /*
- * We first have to kill the other process, before
- * closing its switch_pipe. Else it might wake up
- * and receive "EOF" before we could kill it.
- */
- if(os_getpid() != pid)
- os_kill_process(pid, 0);
-
- os_close_file(task->thread.mode.tt.switch_pipe[0]);
- os_close_file(task->thread.mode.tt.switch_pipe[1]);
- /* use switch_pipe as flag: thread is released */
- task->thread.mode.tt.switch_pipe[0] = -1;
-}
-
-void suspend_new_thread(int fd)
-{
- int err;
- char c;
-
- os_stop_process(os_getpid());
- err = os_read_file(fd, &c, sizeof(c));
- if(err != sizeof(c))
- panic("read failed in suspend_new_thread, err = %d", -err);
-}
-
-void schedule_tail(struct task_struct *prev);
-
-static void new_thread_handler(int sig)
-{
- unsigned long disable;
- int (*fn)(void *);
- void *arg;
-
- fn = current->thread.request.u.thread.proc;
- arg = current->thread.request.u.thread.arg;
-
- UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
- disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
- (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
- SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
-
- suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
-
- force_flush_all();
- if(current->thread.prev_sched != NULL)
- schedule_tail(current->thread.prev_sched);
- current->thread.prev_sched = NULL;
-
- init_new_thread_signals();
- enable_timer();
- free_page(current->thread.temp_stack);
- set_cmdline("(kernel thread)");
-
- change_sig(SIGUSR1, 1);
- change_sig(SIGPROF, 1);
- local_irq_enable();
- if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
- do_exit(0);
-
- /* XXX No set_user_mode here because a newly execed process will
- * immediately segfault on its non-existent IP, coming straight back
- * to the signal handler, which will call set_user_mode on its way
- * out. This should probably change since it's confusing.
- */
-}
-
-static int new_thread_proc(void *stack)
-{
- /* local_irq_disable is needed to block out signals until this thread is
- * properly scheduled. Otherwise, the tracing thread will get mighty
- * upset about any signals that arrive before that.
- * This has the complication that it sets the saved signal mask in
- * the sigcontext to block signals. This gets restored when this
- * thread (or a descendant, since they get a copy of this sigcontext)
- * returns to userspace.
- * So, this is compensated for elsewhere.
- * XXX There is still a small window until local_irq_disable() actually
- * finishes where signals are possible - shouldn't be a problem in
- * practice since SIGIO hasn't been forwarded here yet, and the
- * local_irq_disable should finish before a SIGVTALRM has time to be
- * delivered.
- */
-
- local_irq_disable();
- init_new_thread_stack(stack, new_thread_handler);
- os_usr1_process(os_getpid());
- change_sig(SIGUSR1, 1);
- return(0);
-}
-
-/* Signal masking - signals are blocked at the start of fork_tramp. They
- * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
- * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
- * so it is blocked before it's called. They are re-enabled on sigreturn
- * despite the fact that they were blocked when the SIGUSR1 was issued because
- * copy_thread copies the parent's sigcontext, including the signal mask
- * onto the signal frame.
- */
-
-void finish_fork_handler(int sig)
-{
- UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
- suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
-
- force_flush_all();
- if(current->thread.prev_sched != NULL)
- schedule_tail(current->thread.prev_sched);
- current->thread.prev_sched = NULL;
-
- enable_timer();
- change_sig(SIGVTALRM, 1);
- local_irq_enable();
- if(current->mm != current->parent->mm)
- protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
- 1, 0, 1);
- stack_protections((unsigned long) current_thread);
-
- free_page(current->thread.temp_stack);
- local_irq_disable();
- change_sig(SIGUSR1, 0);
- set_user_mode(current);
-}
-
-int fork_tramp(void *stack)
-{
- local_irq_disable();
- arch_init_thread();
- init_new_thread_stack(stack, finish_fork_handler);
-
- os_usr1_process(os_getpid());
- change_sig(SIGUSR1, 1);
- return(0);
-}
-
-int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct * p,
- struct pt_regs *regs)
-{
- int (*tramp)(void *);
- int new_pid, err;
- unsigned long stack;
-
- if(current->thread.forking)
- tramp = fork_tramp;
- else {
- tramp = new_thread_proc;
- p->thread.request.u.thread = current->thread.request.u.thread;
- }
-
- err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
- if(err < 0){
- printk("copy_thread : pipe failed, err = %d\n", -err);
- return(err);
- }
-
- stack = alloc_stack(0, 0);
- if(stack == 0){
- printk(KERN_ERR "copy_thread : failed to allocate "
- "temporary stack\n");
- return(-ENOMEM);
- }
-
- clone_flags &= CLONE_VM;
- p->thread.temp_stack = stack;
- new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp);
- if(new_pid < 0){
- printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
- -new_pid);
- return(new_pid);
- }
-
- if(current->thread.forking){
- sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(&regs->regs));
- SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
- if(sp != 0)
- SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
- }
- p->thread.mode.tt.extern_pid = new_pid;
-
- current->thread.request.op = OP_FORK;
- current->thread.request.u.fork.pid = new_pid;
- os_usr1_process(os_getpid());
-
- /* Enable the signal and then disable it to ensure that it is handled
- * here, and nowhere else.
- */
- change_sig(SIGUSR1, 1);
-
- change_sig(SIGUSR1, 0);
- err = 0;
- return(err);
-}
-
-void reboot_tt(void)
-{
- current->thread.request.op = OP_REBOOT;
- os_usr1_process(os_getpid());
- change_sig(SIGUSR1, 1);
-}
-
-void halt_tt(void)
-{
- current->thread.request.op = OP_HALT;
- os_usr1_process(os_getpid());
- change_sig(SIGUSR1, 1);
-}
-
-void kill_off_processes_tt(void)
-{
- struct task_struct *p;
- int me;
-
- me = os_getpid();
- for_each_process(p){
- if(p->thread.mode.tt.extern_pid != me)
- os_kill_process(p->thread.mode.tt.extern_pid, 0);
- }
- if(init_task.thread.mode.tt.extern_pid != me)
- os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
-}
-
-void initial_thread_cb_tt(void (*proc)(void *), void *arg)
-{
- if(os_getpid() == tracing_pid){
- (*proc)(arg);
- }
- else {
- current->thread.request.op = OP_CB;
- current->thread.request.u.cb.proc = proc;
- current->thread.request.u.cb.arg = arg;
- os_usr1_process(os_getpid());
- change_sig(SIGUSR1, 1);
-
- change_sig(SIGUSR1, 0);
- }
-}
-
-int do_proc_op(void *t, int proc_id)
-{
- struct task_struct *task;
- struct thread_struct *thread;
- int op, pid;
-
- task = t;
- thread = &task->thread;
- op = thread->request.op;
- switch(op){
- case OP_NONE:
- case OP_TRACE_ON:
- break;
- case OP_EXEC:
- pid = thread->request.u.exec.pid;
- do_exec(thread->mode.tt.extern_pid, pid);
- thread->mode.tt.extern_pid = pid;
- cpu_tasks[task_thread_info(task)->cpu].pid = pid;
- break;
- case OP_FORK:
- attach_process(thread->request.u.fork.pid);
- break;
- case OP_CB:
- (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
- break;
- case OP_REBOOT:
- case OP_HALT:
- break;
- default:
- tracer_panic("Bad op in do_proc_op");
- break;
- }
- thread->request.op = OP_NONE;
- return(op);
-}
-
-void init_idle_tt(void)
-{
- default_idle();
-}
-
-extern void start_kernel(void);
-
-static int start_kernel_proc(void *unused)
-{
- int pid;
-
- block_signals();
- pid = os_getpid();
-
- cpu_tasks[0].pid = pid;
- cpu_tasks[0].task = current;
-#ifdef CONFIG_SMP
- cpu_online_map = cpumask_of_cpu(0);
-#endif
- if(debug) os_stop_process(pid);
- start_kernel();
- return(0);
-}
-
-void set_tracing(void *task, int tracing)
-{
- ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
-}
-
-int is_tracing(void *t)
-{
- return (((struct task_struct *) t)->thread.mode.tt.tracing);
-}
-
-int set_user_mode(void *t)
-{
- struct task_struct *task;
-
- task = t ? t : current;
- if(task->thread.mode.tt.tracing)
- return(1);
- task->thread.request.op = OP_TRACE_ON;
- os_usr1_process(os_getpid());
- return(0);
-}
-
-void set_init_pid(int pid)
-{
- int err;
-
- init_task.thread.mode.tt.extern_pid = pid;
- err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
- if(err)
- panic("Can't create switch pipe for init_task, errno = %d",
- -err);
-}
-
-int start_uml_tt(void)
-{
- void *sp;
- int pages;
-
- pages = (1 << CONFIG_KERNEL_STACK_ORDER);
- sp = task_stack_page(&init_task) +
- pages * PAGE_SIZE - sizeof(unsigned long);
- return(tracer(start_kernel_proc, sp));
-}
-
-int external_pid_tt(struct task_struct *task)
-{
- return(task->thread.mode.tt.extern_pid);
-}
-
-int thread_pid_tt(struct task_struct *task)
-{
- return(task->thread.mode.tt.extern_pid);
-}
-
-int is_valid_pid(int pid)
-{
- struct task_struct *task;
-
- read_lock(&tasklist_lock);
- for_each_process(task){
- if(task->thread.mode.tt.extern_pid == pid){
- read_unlock(&tasklist_lock);
- return(1);
- }
- }
- read_unlock(&tasklist_lock);
- return(0);
-}
diff --git a/arch/um/kernel/tt/ptproxy/Makefile b/arch/um/kernel/tt/ptproxy/Makefile
deleted file mode 100644
index 3ad5b774de5..00000000000
--- a/arch/um/kernel/tt/ptproxy/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
-# Licensed under the GPL
-#
-
-obj-y = proxy.o ptrace.o sysdep.o wait.o
-
-USER_OBJS := $(obj-y)
-
-include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
deleted file mode 100644
index 420c23f311f..00000000000
--- a/arch/um/kernel/tt/ptproxy/proxy.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/**********************************************************************
-proxy.c
-
-Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
-terms and conditions.
-
-Jeff Dike (jdike@karaya.com) : Modified for integration into uml
-**********************************************************************/
-
-/* XXX This file shouldn't refer to CONFIG_* */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <termios.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <asm/unistd.h>
-#include "ptrace_user.h"
-
-#include "ptproxy.h"
-#include "sysdep.h"
-#include "wait.h"
-
-#include "user.h"
-#include "os.h"
-#include "tempfile.h"
-
-static int debugger_wait(debugger_state *debugger, int *status, int options,
- int (*syscall)(debugger_state *debugger, pid_t child),
- int (*normal_return)(debugger_state *debugger,
- pid_t unused),
- int (*wait_return)(debugger_state *debugger,
- pid_t unused))
-{
- if(debugger->real_wait){
- debugger->handle_trace = normal_return;
- syscall_continue(debugger->pid);
- debugger->real_wait = 0;
- return(1);
- }
- debugger->wait_status_ptr = status;
- debugger->wait_options = options;
- if((debugger->debugee != NULL) && debugger->debugee->event){
- syscall_continue(debugger->pid);
- wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
- NULL);
- (*wait_return)(debugger, -1);
- return(0);
- }
- else if(debugger->wait_options & WNOHANG){
- syscall_cancel(debugger->pid, 0);
- debugger->handle_trace = syscall;
- return(0);
- }
- else {
- syscall_pause(debugger->pid);
- debugger->handle_trace = wait_return;
- debugger->waiting = 1;
- }
- return(1);
-}
-
-/*
- * Handle debugger trap, i.e. syscall.
- */
-
-int debugger_syscall(debugger_state *debugger, pid_t child)
-{
- long arg1, arg2, arg3, arg4, arg5, result;
- int syscall, ret = 0;
-
- syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
- &arg5);
-
- switch(syscall){
- case __NR_execve:
- /* execve never returns */
- debugger->handle_trace = debugger_syscall;
- break;
-
- case __NR_ptrace:
- if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
- if(!debugger->debugee->in_context)
- child = debugger->debugee->pid;
- result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
- &ret);
- syscall_cancel(debugger->pid, result);
- debugger->handle_trace = debugger_syscall;
- return(ret);
-
-#ifdef __NR_waitpid
- case __NR_waitpid:
-#endif
- case __NR_wait4:
- if(!debugger_wait(debugger, (int *) arg2, arg3,
- debugger_syscall, debugger_normal_return,
- proxy_wait_return))
- return(0);
- break;
-
- case __NR_kill:
- if(!debugger->debugee->in_context)
- child = debugger->debugee->pid;
- if(arg1 == debugger->debugee->pid){
- result = kill(child, arg2);
- syscall_cancel(debugger->pid, result);
- debugger->handle_trace = debugger_syscall;
- return(0);
- }
- else debugger->handle_trace = debugger_normal_return;
- break;
-
- default:
- debugger->handle_trace = debugger_normal_return;
- }
-
- syscall_continue(debugger->pid);
- return(0);
-}
-
-/* Used by the tracing thread */
-static debugger_state parent;
-static int parent_syscall(debugger_state *debugger, int pid);
-
-int init_parent_proxy(int pid)
-{
- parent = ((debugger_state) { .pid = pid,
- .wait_options = 0,
- .wait_status_ptr = NULL,
- .waiting = 0,
- .real_wait = 0,
- .expecting_child = 0,
- .handle_trace = parent_syscall,
- .debugee = NULL } );
- return(0);
-}
-
-int parent_normal_return(debugger_state *debugger, pid_t unused)
-{
- debugger->handle_trace = parent_syscall;
- syscall_continue(debugger->pid);
- return(0);
-}
-
-static int parent_syscall(debugger_state *debugger, int pid)
-{
- long arg1, arg2, arg3, arg4, arg5;
- int syscall;
-
- syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
-
- if((syscall == __NR_wait4)
-#ifdef __NR_waitpid
- || (syscall == __NR_waitpid)
-#endif
- ){
- debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
- parent_normal_return, parent_wait_return);
- }
- else ptrace(PTRACE_SYSCALL, pid, 0, 0);
- return(0);
-}
-
-int debugger_normal_return(debugger_state *debugger, pid_t unused)
-{
- debugger->handle_trace = debugger_syscall;
- syscall_continue(debugger->pid);
- return(0);
-}
-
-void debugger_cancelled_return(debugger_state *debugger, int result)
-{
- debugger->handle_trace = debugger_syscall;
- syscall_set_result(debugger->pid, result);
- syscall_continue(debugger->pid);
-}
-
-/* Used by the tracing thread */
-static debugger_state debugger;
-static debugee_state debugee;
-
-void init_proxy (pid_t debugger_pid, int stopped, int status)
-{
- debugger.pid = debugger_pid;
- debugger.handle_trace = debugger_syscall;
- debugger.debugee = &debugee;
- debugger.waiting = 0;
- debugger.real_wait = 0;
- debugger.expecting_child = 0;
-
- debugee.pid = 0;
- debugee.traced = 0;
- debugee.stopped = stopped;
- debugee.event = 0;
- debugee.zombie = 0;
- debugee.died = 0;
- debugee.wait_status = status;
- debugee.in_context = 1;
-}
-
-int debugger_proxy(int status, int pid)
-{
- int ret = 0, sig;
-
- if(WIFSTOPPED(status)){
- sig = WSTOPSIG(status);
- if (sig == SIGTRAP)
- ret = (*debugger.handle_trace)(&debugger, pid);
-
- else if(sig == SIGCHLD){
- if(debugger.expecting_child){
- ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
- debugger.expecting_child = 0;
- }
- else if(debugger.waiting)
- real_wait_return(&debugger);
- else {
- ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
- debugger.real_wait = 1;
- }
- }
- else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
- }
- else if(WIFEXITED(status)){
- tracer_panic("debugger (pid %d) exited with status %d",
- debugger.pid, WEXITSTATUS(status));
- }
- else if(WIFSIGNALED(status)){
- tracer_panic("debugger (pid %d) exited with signal %d",
- debugger.pid, WTERMSIG(status));
- }
- else {
- tracer_panic("proxy got unknown status (0x%x) on debugger "
- "(pid %d)", status, debugger.pid);
- }
- return(ret);
-}
-
-void child_proxy(pid_t pid, int status)
-{
- debugee.event = 1;
- debugee.wait_status = status;
-
- if(WIFSTOPPED(status)){
- debugee.stopped = 1;
- debugger.expecting_child = 1;
- kill(debugger.pid, SIGCHLD);
- }
- else if(WIFEXITED(status) || WIFSIGNALED(status)){
- debugee.zombie = 1;
- debugger.expecting_child = 1;
- kill(debugger.pid, SIGCHLD);
- }
- else panic("proxy got unknown status (0x%x) on child (pid %d)",
- status, pid);
-}
-
-void debugger_parent_signal(int status, int pid)
-{
- int sig;
-
- if(WIFSTOPPED(status)){
- sig = WSTOPSIG(status);
- if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
- else ptrace(PTRACE_SYSCALL, pid, 0, sig);
- }
-}
-
-void fake_child_exit(void)
-{
- int status, pid;
-
- child_proxy(1, W_EXITCODE(0, 0));
- while(debugger.waiting == 1){
- CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
- if(pid != debugger.pid){
- printk("fake_child_exit - waitpid failed, "
- "errno = %d\n", errno);
- return;
- }
- debugger_proxy(status, debugger.pid);
- }
- CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
- if(pid != debugger.pid){
- printk("fake_child_exit - waitpid failed, "
- "errno = %d\n", errno);
- return;
- }
- if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
- printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
- errno);
-}
-
-char gdb_init_string[] =
-"att 1 \n\
-b panic \n\
-b stop \n\
-handle SIGWINCH nostop noprint pass \n\
-";
-
-int start_debugger(char *prog, int startup, int stop, int *fd_out)
-{
- int slave, child;
-
- slave = open_gdb_chan();
- child = fork();
- if(child == 0){
- char *tempname = NULL;
- int fd;
-
- if(setsid() < 0) perror("setsid");
- if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) ||
- (dup2(slave, 2) < 0)){
- printk("start_debugger : dup2 failed, errno = %d\n",
- errno);
- exit(1);
- }
- if(ioctl(0, TIOCSCTTY, 0) < 0){
- printk("start_debugger : TIOCSCTTY failed, "
- "errno = %d\n", errno);
- exit(1);
- }
- if(tcsetpgrp (1, os_getpid()) < 0){
- printk("start_debugger : tcsetpgrp failed, "
- "errno = %d\n", errno);
-#ifdef notdef
- exit(1);
-#endif
- }
- fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
- if(fd < 0){
- printk("start_debugger : make_tempfile failed,"
- "err = %d\n", -fd);
- exit(1);
- }
- os_write_file(fd, gdb_init_string,
- sizeof(gdb_init_string) - 1);
- if(startup){
- if(stop){
- os_write_file(fd, "b start_kernel\n",
- strlen("b start_kernel\n"));
- }
- os_write_file(fd, "c\n", strlen("c\n"));
- }
- if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
- printk("start_debugger : PTRACE_TRACEME failed, "
- "errno = %d\n", errno);
- exit(1);
- }
- execlp("gdb", "gdb", "--command", tempname, prog, NULL);
- printk("start_debugger : exec of gdb failed, errno = %d\n",
- errno);
- }
- if(child < 0){
- printk("start_debugger : fork for gdb failed, errno = %d\n",
- errno);
- return(-1);
- }
- *fd_out = slave;
- return(child);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ptproxy/ptproxy.h b/arch/um/kernel/tt/ptproxy/ptproxy.h
deleted file mode 100644
index 5eb0285b196..00000000000
--- a/arch/um/kernel/tt/ptproxy/ptproxy.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**********************************************************************
-ptproxy.h
-
-Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
-terms and conditions.
-**********************************************************************/
-
-#ifndef __PTPROXY_H
-#define __PTPROXY_H
-
-#include <sys/types.h>
-
-typedef struct debugger debugger_state;
-typedef struct debugee debugee_state;
-
-struct debugger
-{
- pid_t pid;
- int wait_options;
- int *wait_status_ptr;
- unsigned int waiting : 1;
- unsigned int real_wait : 1;
- unsigned int expecting_child : 1;
- int (*handle_trace) (debugger_state *, pid_t);
-
- debugee_state *debugee;
-};
-
-struct debugee
-{
- pid_t pid;
- int wait_status;
- unsigned int died : 1;
- unsigned int event : 1;
- unsigned int stopped : 1;
- unsigned int trace_singlestep : 1;
- unsigned int trace_syscall : 1;
- unsigned int traced : 1;
- unsigned int zombie : 1;
- unsigned int in_context : 1;
-};
-
-extern int debugger_syscall(debugger_state *debugger, pid_t pid);
-extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
-
-extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
- int *strace_out);
-extern void debugger_cancelled_return(debugger_state *debugger, int result);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
deleted file mode 100644
index 4b4f6179b21..00000000000
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/**********************************************************************
-ptrace.c
-
-Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
-terms and conditions.
-
-Jeff Dike (jdike@karaya.com) : Modified for integration into uml
-**********************************************************************/
-
-#include <errno.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-
-#include "ptproxy.h"
-#include "debug.h"
-#include "kern_util.h"
-#include "ptrace_user.h"
-#include "tt.h"
-#include "os.h"
-
-long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
- long arg3, long arg4, pid_t child, int *ret)
-{
- sigset_t relay;
- long result;
- int status;
-
- *ret = 0;
- if(debugger->debugee->died) return(-ESRCH);
-
- switch(arg1){
- case PTRACE_ATTACH:
- if(debugger->debugee->traced) return(-EPERM);
-
- debugger->debugee->pid = arg2;
- debugger->debugee->traced = 1;
-
- if(is_valid_pid(arg2) && (arg2 != child)){
- debugger->debugee->in_context = 0;
- kill(arg2, SIGSTOP);
- debugger->debugee->event = 1;
- debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
- }
- else {
- debugger->debugee->in_context = 1;
- if(debugger->debugee->stopped)
- child_proxy(child, W_STOPCODE(SIGSTOP));
- else kill(child, SIGSTOP);
- }
-
- return(0);
-
- case PTRACE_DETACH:
- if(!debugger->debugee->traced) return(-EPERM);
-
- debugger->debugee->traced = 0;
- debugger->debugee->pid = 0;
- if(!debugger->debugee->in_context)
- kill(child, SIGCONT);
-
- return(0);
-
- case PTRACE_CONT:
- if(!debugger->debugee->in_context) return(-EPERM);
- *ret = PTRACE_CONT;
- return(ptrace(PTRACE_CONT, child, arg3, arg4));
-
-#ifdef UM_HAVE_GETFPREGS
- case PTRACE_GETFPREGS:
- {
- long regs[FP_FRAME_SIZE];
- int i, result;
-
- result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
- if(result == -1) return(-errno);
-
- for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
- ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
- regs[i]);
- return(result);
- }
-#endif
-
-#ifdef UM_HAVE_GETFPXREGS
- case PTRACE_GETFPXREGS:
- {
- long regs[FPX_FRAME_SIZE];
- int i, result;
-
- result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
- if(result == -1) return(-errno);
-
- for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
- ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
- regs[i]);
- return(result);
- }
-#endif
-
-#ifdef UM_HAVE_GETREGS
- case PTRACE_GETREGS:
- {
- long regs[FRAME_SIZE];
- int i, result;
-
- result = ptrace(PTRACE_GETREGS, child, 0, regs);
- if(result == -1) return(-errno);
-
- for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
- ptrace (PTRACE_POKEDATA, debugger->pid,
- arg4 + 4 * i, regs[i]);
- return(result);
- }
- break;
-#endif
-
- case PTRACE_KILL:
- result = ptrace(PTRACE_KILL, child, arg3, arg4);
- if(result == -1) return(-errno);
-
- return(result);
-
- case PTRACE_PEEKDATA:
- case PTRACE_PEEKTEXT:
- case PTRACE_PEEKUSR:
- /* The value being read out could be -1, so we have to
- * check errno to see if there's an error, and zero it
- * beforehand so we're not faked out by an old error
- */
-
- errno = 0;
- result = ptrace(arg1, child, arg3, 0);
- if((result == -1) && (errno != 0)) return(-errno);
-
- result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
- if(result == -1) return(-errno);
-
- return(result);
-
- case PTRACE_POKEDATA:
- case PTRACE_POKETEXT:
- case PTRACE_POKEUSR:
- result = ptrace(arg1, child, arg3, arg4);
- if(result == -1) return(-errno);
-
- if(arg1 == PTRACE_POKEUSR) ptrace_pokeuser(arg3, arg4);
- return(result);
-
-#ifdef UM_HAVE_SETFPREGS
- case PTRACE_SETFPREGS:
- {
- long regs[FP_FRAME_SIZE];
- int i;
-
- for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
- regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
- arg4 + 4 * i, 0);
- result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
- if(result == -1) return(-errno);
-
- return(result);
- }
-#endif
-
-#ifdef UM_HAVE_SETFPXREGS
- case PTRACE_SETFPXREGS:
- {
- long regs[FPX_FRAME_SIZE];
- int i;
-
- for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
- regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
- arg4 + 4 * i, 0);
- result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
- if(result == -1) return(-errno);
-
- return(result);
- }
-#endif
-
-#ifdef UM_HAVE_SETREGS
- case PTRACE_SETREGS:
- {
- long regs[FRAME_SIZE];
- int i;
-
- for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
- regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
- arg4 + 4 * i, 0);
- result = ptrace(PTRACE_SETREGS, child, 0, regs);
- if(result == -1) return(-errno);
-
- return(result);
- }
-#endif
-
- case PTRACE_SINGLESTEP:
- if(!debugger->debugee->in_context) return(-EPERM);
- sigemptyset(&relay);
- sigaddset(&relay, SIGSEGV);
- sigaddset(&relay, SIGILL);
- sigaddset(&relay, SIGBUS);
- result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
- if(result == -1) return(-errno);
-
- status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
- &relay);
- child_proxy(child, status);
- return(result);
-
- case PTRACE_SYSCALL:
- if(!debugger->debugee->in_context) return(-EPERM);
- result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
- if(result == -1) return(-errno);
-
- *ret = PTRACE_SYSCALL;
- return(result);
-
- case PTRACE_TRACEME:
- default:
- return(-EINVAL);
- }
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
deleted file mode 100644
index e0e1ab0588a..00000000000
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/**********************************************************************
-sysdep.c
-
-Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
-terms and conditions.
-**********************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <linux/unistd.h>
-#include "ptrace_user.h"
-#include "user.h"
-#include "os.h"
-
-int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
- long *arg5)
-{
- *arg1 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG1_OFFSET, 0);
- *arg2 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG2_OFFSET, 0);
- *arg3 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG3_OFFSET, 0);
- *arg4 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG4_OFFSET, 0);
- *arg5 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG5_OFFSET, 0);
- return(ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 0));
-}
-
-void syscall_cancel(pid_t pid, int result)
-{
- if((ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
- __NR_getpid) < 0) ||
- (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
- (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
- (ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
- (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
- printk("ptproxy: couldn't cancel syscall: errno = %d\n",
- errno);
-}
-
-void syscall_set_result(pid_t pid, long result)
-{
- ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result);
-}
-
-void syscall_continue(pid_t pid)
-{
- ptrace(PTRACE_SYSCALL, pid, 0, 0);
-}
-
-int syscall_pause(pid_t pid)
-{
- if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
- printk("syscall_change - ptrace failed, errno = %d\n", errno);
- return(-1);
- }
- return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.h b/arch/um/kernel/tt/ptproxy/sysdep.h
deleted file mode 100644
index 735f488049a..00000000000
--- a/arch/um/kernel/tt/ptproxy/sysdep.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/**********************************************************************
-sysdep.h
-
-Copyright (C) 1999 Lars Brinkhoff.
-Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
-See the file COPYING for licensing terms and conditions.
-**********************************************************************/
-
-extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3,
- long *arg4, long *arg5);
-extern void syscall_cancel (pid_t pid, long result);
-extern void syscall_set_result (pid_t pid, long result);
-extern void syscall_continue (pid_t pid);
-extern int syscall_pause(pid_t pid);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
deleted file mode 100644
index bdd4af4b65f..00000000000
--- a/arch/um/kernel/tt/ptproxy/wait.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**********************************************************************
-wait.c
-
-Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
-terms and conditions.
-
-**********************************************************************/
-
-#include <errno.h>
-#include <signal.h>
-#include <sys/wait.h>
-
-#include "ptproxy.h"
-#include "sysdep.h"
-#include "wait.h"
-#include "ptrace_user.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
-
-int proxy_wait_return(struct debugger *debugger, pid_t unused)
-{
- debugger->waiting = 0;
-
- if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
- debugger_cancelled_return(debugger, -ECHILD);
- return(0);
- }
-
- if(debugger->debugee->zombie && debugger->debugee->event)
- debugger->debugee->died = 1;
-
- if(debugger->debugee->event){
- debugger->debugee->event = 0;
- ptrace(PTRACE_POKEDATA, debugger->pid,
- debugger->wait_status_ptr,
- debugger->debugee->wait_status);
- /* if (wait4)
- ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
- debugger_cancelled_return(debugger, debugger->debugee->pid);
- return(0);
- }
-
- /* pause will return -EINTR, which happens to be right for wait */
- debugger_normal_return(debugger, -1);
- return(0);
-}
-
-int parent_wait_return(struct debugger *debugger, pid_t unused)
-{
- return(debugger_normal_return(debugger, -1));
-}
-
-int real_wait_return(struct debugger *debugger)
-{
- unsigned long ip;
- int pid;
-
- pid = debugger->pid;
-
- ip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0);
- IP_RESTART_SYSCALL(ip);
-
- if(ptrace(PTRACE_POKEUSR, pid, PT_IP_OFFSET, ip) < 0)
- tracer_panic("real_wait_return : Failed to restart system "
- "call, errno = %d\n", errno);
-
- if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
- (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
- (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
- debugger_normal_return(debugger, -1))
- tracer_panic("real_wait_return : gdb failed to wait, "
- "errno = %d\n", errno);
- return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/ptproxy/wait.h b/arch/um/kernel/tt/ptproxy/wait.h
deleted file mode 100644
index 542e73ee2ce..00000000000
--- a/arch/um/kernel/tt/ptproxy/wait.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**********************************************************************
-wait.h
-
-Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
-terms and conditions.
-**********************************************************************/
-
-#ifndef __PTPROXY_WAIT_H
-#define __PTPROXY_WAIT_H
-
-extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
-extern int real_wait_return(struct debugger *debugger);
-extern int parent_wait_return(struct debugger *debugger, pid_t unused);
-
-#endif
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
deleted file mode 100644
index 293caa6d0c2..00000000000
--- a/arch/um/kernel/tt/syscall_kern.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include "linux/types.h"
-#include "linux/utime.h"
-#include "linux/sys.h"
-#include "linux/ptrace.h"
-#include "asm/unistd.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "asm/stat.h"
-#include "sysdep/syscalls.h"
-#include "sysdep/sigcontext.h"
-#include "kern_util.h"
-#include "syscall.h"
-
-void syscall_handler_tt(int sig, struct pt_regs *regs)
-{
- void *sc;
- long result;
- int syscall;
-
- sc = UPT_SC(&regs->regs);
- SC_START_SYSCALL(sc);
-
- syscall = UPT_SYSCALL_NR(&regs->regs);
- syscall_trace(&regs->regs, 0);
-
- current->thread.nsyscalls++;
- nsyscalls++;
-
- if((syscall >= NR_syscalls) || (syscall < 0))
- result = -ENOSYS;
- else result = EXECUTE_SYSCALL(syscall, regs);
-
- /* regs->sc may have changed while the system call ran (there may
- * have been an interrupt or segfault), so it needs to be refreshed.
- */
- UPT_SC(&regs->regs) = sc;
-
- SC_SET_SYSCALL_RETURN(sc, result);
-
- syscall_trace(&regs->regs, 1);
-}
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
deleted file mode 100644
index f52b47aff1d..00000000000
--- a/arch/um/kernel/tt/syscall_user.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <asm/unistd.h>
-#include "sysdep/ptrace.h"
-#include "sigcontext.h"
-#include "ptrace_user.h"
-#include "task.h"
-#include "kern_util.h"
-#include "syscall.h"
-#include "tt.h"
-
-void do_sigtrap(void *task)
-{
- UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
-}
-
-void do_syscall(void *task, int pid, int local_using_sysemu)
-{
- unsigned long proc_regs[FRAME_SIZE];
-
- if(ptrace_getregs(pid, proc_regs) < 0)
- tracer_panic("Couldn't read registers");
-
- UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
-
-#ifdef UPT_ORIGGPR2
- UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
-#endif
-
- if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
- ((unsigned long *) PT_IP(proc_regs) <= &_etext))
- tracer_panic("I'm tracing myself and I can't get out");
-
- /* advanced sysemu mode set syscall number to -1 automatically */
- if (local_using_sysemu==2)
- return;
-
- /* syscall number -1 in sysemu skips syscall restarting in host */
- if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
- local_using_sysemu ? -1 : __NR_getpid) < 0)
- tracer_panic("do_syscall : Nullifying syscall failed, "
- "errno = %d", errno);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
deleted file mode 100644
index 7caa24fe05d..00000000000
--- a/arch/um/kernel/tt/tlb.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Copyright 2003 PathScale, Inc.
- * Licensed under the GPL
- */
-
-#include "linux/stddef.h"
-#include "linux/kernel.h"
-#include "linux/sched.h"
-#include "linux/mm.h"
-#include "asm/page.h"
-#include "asm/pgtable.h"
-#include "asm/uaccess.h"
-#include "asm/tlbflush.h"
-#include "mem_user.h"
-#include "os.h"
-#include "tlb.h"
-
-static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
- int finished, void **flush)
-{
- struct host_vm_op *op;
- int i, ret=0;
-
- for(i = 0; i <= last && !ret; i++){
- op = &ops[i];
- switch(op->type){
- case MMAP:
- ret = os_map_memory((void *) op->u.mmap.addr,
- op->u.mmap.fd, op->u.mmap.offset,
- op->u.mmap.len, op->u.mmap.r,
- op->u.mmap.w, op->u.mmap.x);
- break;
- case MUNMAP:
- ret = os_unmap_memory((void *) op->u.munmap.addr,
- op->u.munmap.len);
- break;
- case MPROTECT:
- ret = protect_memory(op->u.mprotect.addr,
- op->u.munmap.len,
- op->u.mprotect.r,
- op->u.mprotect.w,
- op->u.mprotect.x, 1);
- protect_memory(op->u.mprotect.addr, op->u.munmap.len,
- op->u.mprotect.r, op->u.mprotect.w,
- op->u.mprotect.x, 1);
- break;
- default:
- printk("Unknown op type %d in do_ops\n", op->type);
- break;
- }
- }
-
- return ret;
-}
-
-static void fix_range(struct mm_struct *mm, unsigned long start_addr,
- unsigned long end_addr, int force)
-{
- if((current->thread.mode.tt.extern_pid != -1) &&
- (current->thread.mode.tt.extern_pid != os_getpid()))
- panic("fix_range fixing wrong address space, current = 0x%p",
- current);
-
- fix_range_common(mm, start_addr, end_addr, force, do_ops);
-}
-
-atomic_t vmchange_seq = ATOMIC_INIT(1);
-
-void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end)
-{
- if(flush_tlb_kernel_range_common(start, end))
- atomic_inc(&vmchange_seq);
-}
-
-void flush_tlb_kernel_vm_tt(void)
-{
- flush_tlb_kernel_range(start_vm, end_vm);
-}
-
-void __flush_tlb_one_tt(unsigned long addr)
-{
- flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
-}
-
-void flush_tlb_range_tt(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
-{
- if(vma->vm_mm != current->mm) return;
-
- /* Assumes that the range start ... end is entirely within
- * either process memory or kernel vm
- */
- if((start >= start_vm) && (start < end_vm)){
- if(flush_tlb_kernel_range_common(start, end))
- atomic_inc(&vmchange_seq);
- }
- else fix_range(vma->vm_mm, start, end, 0);
-}
-
-void flush_tlb_mm_tt(struct mm_struct *mm)
-{
- unsigned long seq;
-
- if(mm != current->mm) return;
-
- fix_range(mm, 0, STACK_TOP, 0);
-
- seq = atomic_read(&vmchange_seq);
- if(current->thread.mode.tt.vm_seq == seq)
- return;
- current->thread.mode.tt.vm_seq = seq;
- flush_tlb_kernel_range_common(start_vm, end_vm);
-}
-
-void force_flush_all_tt(void)
-{
- fix_range(current->mm, 0, STACK_TOP, 1);
- flush_tlb_kernel_range_common(start_vm, end_vm);
-}
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
deleted file mode 100644
index c23588393f6..00000000000
--- a/arch/um/kernel/tt/tracer.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <sched.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include "user.h"
-#include "sysdep/ptrace.h"
-#include "sigcontext.h"
-#include "sysdep/sigcontext.h"
-#include "os.h"
-#include "mem_user.h"
-#include "process.h"
-#include "kern_util.h"
-#include "chan_user.h"
-#include "ptrace_user.h"
-#include "irq_user.h"
-#include "mode.h"
-#include "tt.h"
-
-static int tracer_winch[2];
-
-int is_tracer_winch(int pid, int fd, void *data)
-{
- if(pid != os_getpgrp())
- return(0);
-
- register_winch_irq(tracer_winch[0], fd, -1, data);
- return(1);
-}
-
-static void tracer_winch_handler(int sig)
-{
- int n;
- char c = 1;
-
- n = os_write_file(tracer_winch[1], &c, sizeof(c));
- if(n != sizeof(c))
- printk("tracer_winch_handler - write failed, err = %d\n", -n);
-}
-
-/* Called only by the tracing thread during initialization */
-
-static void setup_tracer_winch(void)
-{
- int err;
-
- err = os_pipe(tracer_winch, 1, 1);
- if(err < 0){
- printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
- return;
- }
- signal(SIGWINCH, tracer_winch_handler);
-}
-
-void attach_process(int pid)
-{
- if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
- (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
- tracer_panic("OP_FORK failed to attach pid");
- wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
- if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
- tracer_panic("OP_FORK: PTRACE_SETOPTIONS failed, errno = %d", errno);
- if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
- tracer_panic("OP_FORK failed to continue process");
-}
-
-void tracer_panic(char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- vprintf(format, ap);
- va_end(ap);
- printf("\n");
- while(1) pause();
-}
-
-static void tracer_segv(int sig, struct sigcontext sc)
-{
- struct faultinfo fi;
- GET_FAULTINFO_FROM_SC(fi, &sc);
- printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
- FAULT_ADDRESS(fi), SC_IP(&sc));
- while(1)
- pause();
-}
-
-/* Changed early in boot, and then only read */
-int debug = 0;
-int debug_stop = 1;
-int debug_parent = 0;
-int honeypot = 0;
-
-static int signal_tramp(void *arg)
-{
- int (*proc)(void *);
-
- if(honeypot && munmap((void *) (host_task_size - 0x10000000),
- 0x10000000))
- panic("Unmapping stack failed");
- if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
- panic("ptrace PTRACE_TRACEME failed");
- os_stop_process(os_getpid());
- change_sig(SIGWINCH, 0);
- signal(SIGUSR1, SIG_IGN);
- change_sig(SIGCHLD, 0);
- signal(SIGSEGV, (__sighandler_t) sig_handler);
- set_cmdline("(idle thread)");
- set_init_pid(os_getpid());
- init_irq_signals(0);
- proc = arg;
- return((*proc)(NULL));
-}
-
-static void sleeping_process_signal(int pid, int sig)
-{
- switch(sig){
- /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is
- * right because the process must be in the kernel already.
- */
- case SIGCONT:
- case SIGTSTP:
- if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
- tracer_panic("sleeping_process_signal : Failed to "
- "continue pid %d, signal = %d, "
- "errno = %d\n", pid, sig, errno);
- break;
-
- /* This happens when the debugger (e.g. strace) is doing system call
- * tracing on the kernel. During a context switch, the current task
- * will be set to the incoming process and the outgoing process will
- * hop into write and then read. Since it's not the current process
- * any more, the trace of those will land here. So, we need to just
- * PTRACE_SYSCALL it.
- */
- case (SIGTRAP + 0x80):
- if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
- tracer_panic("sleeping_process_signal : Failed to "
- "PTRACE_SYSCALL pid %d, errno = %d\n",
- pid, errno);
- break;
- case SIGSTOP:
- break;
- default:
- tracer_panic("sleeping process %d got unexpected "
- "signal : %d\n", pid, sig);
- break;
- }
-}
-
-/* Accessed only by the tracing thread */
-int debugger_pid = -1;
-int debugger_parent = -1;
-int debugger_fd = -1;
-int gdb_pid = -1;
-
-struct {
- int pid;
- int signal;
- unsigned long addr;
- struct timeval time;
-} signal_record[1024][32];
-
-int signal_index[32];
-int nsignals = 0;
-int debug_trace = 0;
-
-extern void signal_usr1(int sig);
-
-int tracing_pid = -1;
-
-int tracer(int (*init_proc)(void *), void *sp)
-{
- void *task = NULL;
- int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
- int proc_id = 0, n, err, old_tracing = 0, strace = 0;
- int local_using_sysemu = 0;
-
- signal(SIGPIPE, SIG_IGN);
- setup_tracer_winch();
- tracing_pid = os_getpid();
- printf("tracing thread pid = %d\n", tracing_pid);
-
- pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
- CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- if(n < 0){
- printf("waitpid on idle thread failed, errno = %d\n", errno);
- exit(1);
- }
- if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) {
- printf("Failed to PTRACE_SETOPTIONS for idle thread, errno = %d\n", errno);
- exit(1);
- }
- if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
- printf("Failed to continue idle thread, errno = %d\n", errno);
- exit(1);
- }
-
- signal(SIGSEGV, (sighandler_t) tracer_segv);
- signal(SIGUSR1, signal_usr1);
- if(debug_trace){
- printf("Tracing thread pausing to be attached\n");
- stop();
- }
- if(debug){
- if(gdb_pid != -1)
- debugger_pid = attach_debugger(pid, gdb_pid, 1);
- else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
- if(debug_parent){
- debugger_parent = os_process_parent(debugger_pid);
- init_parent_proxy(debugger_parent);
- err = attach(debugger_parent);
- if(err){
- printf("Failed to attach debugger parent %d, "
- "errno = %d\n", debugger_parent, -err);
- debugger_parent = -1;
- }
- else {
- if(ptrace(PTRACE_SYSCALL, debugger_parent,
- 0, 0) < 0){
- printf("Failed to continue debugger "
- "parent, errno = %d\n", errno);
- debugger_parent = -1;
- }
- }
- }
- }
- set_cmdline("(tracing thread)");
- while(1){
- CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
- if(pid <= 0){
- if(errno != ECHILD){
- printf("wait failed - errno = %d\n", errno);
- }
- continue;
- }
- if(pid == debugger_pid){
- int cont = 0;
-
- if(WIFEXITED(status) || WIFSIGNALED(status))
- debugger_pid = -1;
- /* XXX Figure out how to deal with gdb and SMP */
- else cont = debugger_signal(status, cpu_tasks[0].pid);
- if(cont == PTRACE_SYSCALL) strace = 1;
- continue;
- }
- else if(pid == debugger_parent){
- debugger_parent_signal(status, pid);
- continue;
- }
- nsignals++;
- if(WIFEXITED(status)) ;
-#ifdef notdef
- {
- printf("Child %d exited with status %d\n", pid,
- WEXITSTATUS(status));
- }
-#endif
- else if(WIFSIGNALED(status)){
- sig = WTERMSIG(status);
- if(sig != 9){
- printf("Child %d exited with signal %d\n", pid,
- sig);
- }
- }
- else if(WIFSTOPPED(status)){
- proc_id = pid_to_processor_id(pid);
- sig = WSTOPSIG(status);
- if(proc_id == -1){
- sleeping_process_signal(pid, sig);
- continue;
- }
-
- task = cpu_tasks[proc_id].task;
- tracing = is_tracing(task);
- old_tracing = tracing;
-
- /* Assume: no syscall, when coming from user */
- if ( tracing )
- do_sigtrap(task);
-
- switch(sig){
- case SIGUSR1:
- sig = 0;
- op = do_proc_op(task, proc_id);
- switch(op){
- /*
- * This is called when entering user mode; after
- * this, we start intercepting syscalls.
- *
- * In fact, a process is started in kernel mode,
- * so with is_tracing() == 0 (and that is reset
- * when executing syscalls, since UML kernel has
- * the right to do syscalls);
- */
- case OP_TRACE_ON:
- arch_leave_kernel(task, pid);
- tracing = 1;
- break;
- case OP_REBOOT:
- case OP_HALT:
- unmap_physmem();
- kmalloc_ok = 0;
- os_kill_ptraced_process(pid, 0);
- /* Now let's reap remaining zombies */
- errno = 0;
- do {
- waitpid(-1, &status,
- WUNTRACED);
- } while (errno != ECHILD);
- return(op == OP_REBOOT);
- case OP_NONE:
- printf("Detaching pid %d\n", pid);
- detach(pid, SIGSTOP);
- continue;
- default:
- break;
- }
- /* OP_EXEC switches host processes on us,
- * we want to continue the new one.
- */
- pid = cpu_tasks[proc_id].pid;
- break;
- case (SIGTRAP + 0x80):
- if(!tracing && (debugger_pid != -1)){
- child_signal(pid, status & 0x7fff);
- continue;
- }
- tracing = 0;
- /* local_using_sysemu has been already set
- * below, since if we are here, is_tracing() on
- * the traced task was 1, i.e. the process had
- * already run through one iteration of the
- * loop which executed a OP_TRACE_ON request.*/
- do_syscall(task, pid, local_using_sysemu);
- sig = SIGUSR2;
- break;
- case SIGTRAP:
- if(!tracing && (debugger_pid != -1)){
- child_signal(pid, status);
- continue;
- }
- tracing = 0;
- break;
- case SIGPROF:
- if(tracing) sig = 0;
- break;
- case SIGCHLD:
- case SIGHUP:
- sig = 0;
- break;
- case SIGSEGV:
- case SIGIO:
- case SIGALRM:
- case SIGVTALRM:
- case SIGFPE:
- case SIGBUS:
- case SIGILL:
- case SIGWINCH:
-
- default:
- tracing = 0;
- break;
- }
- set_tracing(task, tracing);
-
- if(!tracing && old_tracing)
- arch_enter_kernel(task, pid);
-
- if(!tracing && (debugger_pid != -1) && (sig != 0) &&
- (sig != SIGALRM) && (sig != SIGVTALRM) &&
- (sig != SIGSEGV) && (sig != SIGTRAP) &&
- (sig != SIGUSR2) && (sig != SIGIO) &&
- (sig != SIGFPE)){
- child_signal(pid, status);
- continue;
- }
-
- local_using_sysemu = get_using_sysemu();
-
- if(tracing)
- cont_type = SELECT_PTRACE_OPERATION(local_using_sysemu,
- singlestepping(task));
- else if((debugger_pid != -1) && strace)
- cont_type = PTRACE_SYSCALL;
- else
- cont_type = PTRACE_CONT;
-
- if(ptrace(cont_type, pid, 0, sig) != 0){
- tracer_panic("ptrace failed to continue "
- "process - errno = %d\n",
- errno);
- }
- }
- }
- return(0);
-}
-
-static int __init uml_debug_setup(char *line, int *add)
-{
- char *next;
-
- debug = 1;
- *add = 0;
- if(*line != '=') return(0);
- line++;
-
- while(line != NULL){
- next = strchr(line, ',');
- if(next) *next++ = '\0';
-
- if(!strcmp(line, "go")) debug_stop = 0;
- else if(!strcmp(line, "parent")) debug_parent = 1;
- else printf("Unknown debug option : '%s'\n", line);
-
- line = next;
- }
- return(0);
-}
-
-__uml_setup("debug", uml_debug_setup,
-"debug\n"
-" Starts up the kernel under the control of gdb. See the \n"
-" kernel debugging tutorial and the debugging session pages\n"
-" at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
-);
-
-static int __init uml_debugtrace_setup(char *line, int *add)
-{
- debug_trace = 1;
- return 0;
-}
-__uml_setup("debugtrace", uml_debugtrace_setup,
-"debugtrace\n"
-" Causes the tracing thread to pause until it is attached by a\n"
-" debugger and continued. This is mostly for debugging crashes\n"
-" early during boot, and should be pretty much obsoleted by\n"
-" the debug switch.\n\n"
-);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
deleted file mode 100644
index 3032eb5e246..00000000000
--- a/arch/um/kernel/tt/trap_user.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
-#include "kern_util.h"
-#include "task.h"
-#include "tt.h"
-#include "os.h"
-
-void sig_handler_common_tt(int sig, void *sc_ptr)
-{
- struct sigcontext *sc = sc_ptr;
- struct tt_regs save_regs, *r;
- int save_errno = errno, is_user = 0;
- void (*handler)(int, union uml_pt_regs *);
-
- /* This is done because to allow SIGSEGV to be delivered inside a SEGV
- * handler. This can happen in copy_user, and if SEGV is disabled,
- * the process will die.
- */
- if(sig == SIGSEGV)
- change_sig(SIGSEGV, 1);
-
- r = &TASK_REGS(get_current())->tt;
- if ( sig == SIGFPE || sig == SIGSEGV ||
- sig == SIGBUS || sig == SIGILL ||
- sig == SIGTRAP ) {
- GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
- }
- save_regs = *r;
- if (sc)
- is_user = user_context(SC_SP(sc));
- r->sc = sc;
- if(sig != SIGUSR2)
- r->syscall = -1;
-
- handler = sig_info[sig];
-
- /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
- if (sig != SIGIO && sig != SIGWINCH &&
- sig != SIGVTALRM && sig != SIGALRM)
- unblock_signals();
-
- handler(sig, (union uml_pt_regs *) r);
-
- if(is_user){
- interrupt_end();
- block_signals();
- set_user_mode(NULL);
- }
- *r = save_regs;
- errno = save_errno;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
deleted file mode 100644
index 1cb60726567..00000000000
--- a/arch/um/kernel/tt/uaccess.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include "linux/sched.h"
-#include "asm/uaccess.h"
-
-int copy_from_user_tt(void *to, const void __user *from, int n)
-{
- if(!access_ok(VERIFY_READ, from, n))
- return(n);
-
- return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
- &current->thread.fault_catcher));
-}
-
-int copy_to_user_tt(void __user *to, const void *from, int n)
-{
- if(!access_ok(VERIFY_WRITE, to, n))
- return(n);
-
- return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
- &current->thread.fault_catcher));
-}
-
-int strncpy_from_user_tt(char *dst, const char __user *src, int count)
-{
- int n;
-
- if(!access_ok(VERIFY_READ, src, 1))
- return(-EFAULT);
-
- n = __do_strncpy_from_user(dst, src, count,
- &current->thread.fault_addr,
- &current->thread.fault_catcher);
- if(n < 0) return(-EFAULT);
- return(n);
-}
-
-int __clear_user_tt(void __user *mem, int len)
-{
- return(__do_clear_user(mem, len,
- &current->thread.fault_addr,
- &current->thread.fault_catcher));
-}
-
-int clear_user_tt(void __user *mem, int len)
-{
- if(!access_ok(VERIFY_WRITE, mem, len))
- return(len);
-
- return(__do_clear_user(mem, len, &current->thread.fault_addr,
- &current->thread.fault_catcher));
-}
-
-int strnlen_user_tt(const void __user *str, int len)
-{
- return(__do_strnlen_user(str, len,
- &current->thread.fault_addr,
- &current->thread.fault_catcher));
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
deleted file mode 100644
index 0e5c82c5e5b..00000000000
--- a/arch/um/kernel/tt/uaccess_user.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <string.h>
-#include "uml_uaccess.h"
-#include "task.h"
-#include "kern_util.h"
-#include "os.h"
-#include "longjmp.h"
-
-int __do_copy_from_user(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher)
-{
- struct tt_regs save = TASK_REGS(get_current())->tt;
- unsigned long fault;
- int faulted;
-
- fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
- __do_copy, &faulted);
- TASK_REGS(get_current())->tt = save;
-
- if(!faulted)
- return 0;
- else if (fault)
- return n - (fault - (unsigned long) from);
- else
- /* In case of a general protection fault, we don't have the
- * fault address, so NULL is used instead. Pretend we didn't
- * copy anything. */
- return n;
-}
-
-static void __do_strncpy(void *dst, const void *src, int count)
-{
- strncpy(dst, src, count);
-}
-
-int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
- void **fault_addr, void **fault_catcher)
-{
- struct tt_regs save = TASK_REGS(get_current())->tt;
- unsigned long fault;
- int faulted;
-
- fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
- __do_strncpy, &faulted);
- TASK_REGS(get_current())->tt = save;
-
- if(!faulted) return(strlen(dst));
- else return(-1);
-}
-
-static void __do_clear(void *to, const void *from, int n)
-{
- memset(to, 0, n);
-}
-
-int __do_clear_user(void *mem, unsigned long len,
- void **fault_addr, void **fault_catcher)
-{
- struct tt_regs save = TASK_REGS(get_current())->tt;
- unsigned long fault;
- int faulted;
-
- fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
- __do_clear, &faulted);
- TASK_REGS(get_current())->tt = save;
-
- if(!faulted) return(0);
- else return(len - (fault - (unsigned long) mem));
-}
-
-int __do_strnlen_user(const char *str, unsigned long n,
- void **fault_addr, void **fault_catcher)
-{
- struct tt_regs save = TASK_REGS(get_current())->tt;
- int ret;
- unsigned long *faddrp = (unsigned long *)fault_addr;
- jmp_buf jbuf;
-
- *fault_catcher = &jbuf;
- if(UML_SETJMP(&jbuf) == 0)
- ret = strlen(str) + 1;
- else ret = *faddrp - (unsigned long) str;
-
- *fault_addr = NULL;
- *fault_catcher = NULL;
-
- TASK_REGS(get_current())->tt = save;
- return ret;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
index 054e3de0784..d7436aacd26 100644
--- a/arch/um/kernel/uaccess.c
+++ b/arch/um/kernel/uaccess.c
@@ -18,7 +18,7 @@ void __do_copy(void *to, const void *from, int n)
int __do_copy_to_user(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher)
+ void **fault_addr, jmp_buf **fault_catcher)
{
unsigned long fault;
int faulted;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index ecc458fe51b..f1c71393f57 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -1,46 +1,24 @@
/*
- * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/kernel.h"
-#include "linux/sched.h"
-#include "linux/notifier.h"
-#include "linux/mm.h"
-#include "linux/types.h"
-#include "linux/tty.h"
-#include "linux/init.h"
-#include "linux/bootmem.h"
-#include "linux/spinlock.h"
-#include "linux/utsname.h"
-#include "linux/sysrq.h"
-#include "linux/seq_file.h"
#include "linux/delay.h"
+#include "linux/mm.h"
#include "linux/module.h"
+#include "linux/seq_file.h"
+#include "linux/string.h"
#include "linux/utsname.h"
-#include "asm/page.h"
#include "asm/pgtable.h"
-#include "asm/ptrace.h"
-#include "asm/elf.h"
-#include "asm/user.h"
+#include "asm/processor.h"
#include "asm/setup.h"
-#include "ubd_user.h"
-#include "asm/current.h"
-#include "kern_util.h"
-#include "as-layout.h"
#include "arch.h"
+#include "as-layout.h"
+#include "init.h"
#include "kern.h"
#include "mem_user.h"
-#include "mem.h"
-#include "initrd.h"
-#include "init.h"
#include "os.h"
-#include "choose-mode.h"
-#include "mode_kern.h"
-#include "mode.h"
-#ifdef UML_CONFIG_MODE_SKAS
#include "skas.h"
-#endif
#define DEFAULT_COMMAND_LINE "root=98:0"
@@ -53,7 +31,7 @@ static void __init add_arg(char *arg)
printf("add_arg: Too many command line arguments!\n");
exit(1);
}
- if(strlen(command_line) > 0)
+ if (strlen(command_line) > 0)
strcat(command_line, " ");
strcat(command_line, arg);
}
@@ -70,8 +48,8 @@ struct cpuinfo_um boot_cpu_data = {
unsigned long thread_saved_pc(struct task_struct *task)
{
- return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
- task));
+ /* FIXME: Need to look up userspace_pid by cpu */
+ return os_process_pc(userspace_pid[0]);
}
/* Changed in setup_arch, which is called in early boot */
@@ -90,7 +68,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %d\n", index);
seq_printf(m, "vendor_id\t: User Mode Linux\n");
seq_printf(m, "model name\t: UML\n");
- seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
+ seq_printf(m, "mode\t\t: skas\n");
seq_printf(m, "host\t\t: %s\n", host_info);
seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
loops_per_jiffy/(500000/HZ),
@@ -132,44 +110,13 @@ unsigned long end_vm;
/* Set in uml_ncpus_setup */
int ncpus = 1;
-#ifdef CONFIG_CMDLINE_ON_HOST
-/* Pointer set in linux_main, the array itself is private to each thread,
- * and changed at address space creation time so this poses no concurrency
- * problems.
- */
-static char *argv1_begin = NULL;
-static char *argv1_end = NULL;
-#endif
-
/* Set in early boot */
static int have_root __initdata = 0;
/* Set in uml_mem_setup and modified in linux_main */
long long physmem_size = 32 * 1024 * 1024;
-void set_cmdline(char *cmd)
-{
-#ifdef CONFIG_CMDLINE_ON_HOST
- char *umid, *ptr;
-
- if(CHOOSE_MODE(honeypot, 0)) return;
-
- umid = get_umid();
- if(*umid != '\0'){
- snprintf(argv1_begin,
- (argv1_end - argv1_begin) * sizeof(*ptr),
- "(%s) ", umid);
- ptr = &argv1_begin[strlen(argv1_begin)];
- }
- else ptr = argv1_begin;
-
- snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
- memset(argv1_begin + strlen(argv1_begin), '\0',
- argv1_end - argv1_begin - strlen(argv1_begin));
-#endif
-}
-
-static char *usage_string =
+static char *usage_string =
"User Mode Linux v%s\n"
" available at http://user-mode-linux.sourceforge.net/\n\n";
@@ -201,13 +148,10 @@ __uml_setup("root=", uml_root_setup,
" root=/dev/ubd5\n\n"
);
-#ifndef CONFIG_MODE_TT
-
static int __init no_skas_debug_setup(char *line, int *add)
{
printf("'debug' is not necessary to gdb UML in skas mode - run \n");
- printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n");
- printf("doesn't work as expected\n");
+ printf("'gdb linux'");
return 0;
}
@@ -217,8 +161,6 @@ __uml_setup("debug", no_skas_debug_setup,
" this flag is not needed to run gdb on UML in skas mode\n\n"
);
-#endif
-
#ifdef CONFIG_SMP
static int __init uml_ncpus_setup(char *line, int *add)
{
@@ -232,56 +174,10 @@ static int __init uml_ncpus_setup(char *line, int *add)
__uml_setup("ncpus=", uml_ncpus_setup,
"ncpus=<# of desired CPUs>\n"
-" This tells an SMP kernel how many virtual processors to start.\n\n"
+" This tells an SMP kernel how many virtual processors to start.\n\n"
);
#endif
-static int force_tt = 0;
-
-#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
-#define DEFAULT_TT 0
-
-static int __init mode_tt_setup(char *line, int *add)
-{
- force_tt = 1;
- return 0;
-}
-
-#else
-#ifdef CONFIG_MODE_SKAS
-
-#define DEFAULT_TT 0
-
-static int __init mode_tt_setup(char *line, int *add)
-{
- printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
- return 0;
-}
-
-#else
-#ifdef CONFIG_MODE_TT
-
-#define DEFAULT_TT 1
-
-static int __init mode_tt_setup(char *line, int *add)
-{
- printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
- return 0;
-}
-
-#endif
-#endif
-#endif
-
-__uml_setup("mode=tt", mode_tt_setup,
-"mode=tt\n"
-" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
-" forces UML to run in tt (tracing thread) mode. It is not the default\n"
-" because it's slower and less secure than skas mode.\n\n"
-);
-
-int mode_tt = DEFAULT_TT;
-
static int __init Usage(char *line, int *add)
{
const char **p;
@@ -310,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add)
int n;
n = strlen(p->str);
- if(!strncmp(line, p->str, n)){
- if (p->setup_func(line + n, add)) return 1;
- }
+ if (!strncmp(line, p->str, n) && p->setup_func(line + n, add))
+ return 1;
p++;
}
return 0;
@@ -323,7 +218,7 @@ static void __init uml_postsetup(void)
initcall_t *p;
p = &__uml_postsetup_start;
- while(p < &__uml_postsetup_end){
+ while(p < &__uml_postsetup_end) {
(*p)();
p++;
}
@@ -339,6 +234,20 @@ EXPORT_SYMBOL(end_iomem);
extern char __binary_start;
+static unsigned long set_task_sizes_skas(unsigned long *task_size_out)
+{
+ /* Round up to the nearest 4M */
+ unsigned long host_task_size = ROUND_4M((unsigned long)
+ &host_task_size);
+
+ if (!skas_needs_stub)
+ *task_size_out = host_task_size;
+ else
+ *task_size_out = STUB_START & PGDIR_MASK;
+
+ return host_task_size;
+}
+
int __init linux_main(int argc, char **argv)
{
unsigned long avail, diff;
@@ -346,45 +255,30 @@ int __init linux_main(int argc, char **argv)
unsigned int i, add;
char * mode;
- for (i = 1; i < argc; i++){
- if((i == 1) && (argv[i][0] == ' ')) continue;
+ for (i = 1; i < argc; i++) {
+ if ((i == 1) && (argv[i][0] == ' '))
+ continue;
add = 1;
uml_checksetup(argv[i], &add);
if (add)
add_arg(argv[i]);
}
- if(have_root == 0)
+ if (have_root == 0)
add_arg(DEFAULT_COMMAND_LINE);
+ /* OS sanity checks that need to happen before the kernel runs */
os_early_checks();
- if (force_tt)
- clear_can_do_skas();
- mode_tt = force_tt ? 1 : !can_do_skas();
-#ifndef CONFIG_MODE_TT
- if (mode_tt) {
- /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So,
- * can_do_skas() returned 0, and the message is correct. */
- printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n");
- exit(1);
- }
-#endif
-#ifndef CONFIG_MODE_SKAS
- mode = "TT";
-#else
- /* Show to the user the result of selection */
- if (mode_tt)
- mode = "TT";
- else if (proc_mm && ptrace_faultinfo)
+ can_do_skas();
+
+ if (proc_mm && ptrace_faultinfo)
mode = "SKAS3";
else
mode = "SKAS0";
-#endif
printf("UML running in %s mode\n", mode);
- host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
- set_task_sizes_skas, &task_size);
+ host_task_size = set_task_sizes_skas(&task_size);
/*
* Setting up handlers to 'sig_info' struct
@@ -392,13 +286,15 @@ int __init linux_main(int argc, char **argv)
os_fill_handlinfo(handlinfo_kern);
brk_start = (unsigned long) sbrk(0);
- CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
- /* Increase physical memory size for exec-shield users
- so they actually get what they asked for. This should
- add zero for non-exec shield users */
+
+ /*
+ * Increase physical memory size for exec-shield users
+ * so they actually get what they asked for. This should
+ * add zero for non-exec shield users
+ */
diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
- if(diff > 1024 * 1024){
+ if (diff > 1024 * 1024) {
printf("Adding %ld bytes to physical memory to account for "
"exec-shield gap\n", diff);
physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
@@ -411,20 +307,16 @@ int __init linux_main(int argc, char **argv)
setup_machinename(init_utsname()->machine);
-#ifdef CONFIG_CMDLINE_ON_HOST
- argv1_begin = argv[1];
- argv1_end = &argv[1][strlen(argv[1])];
-#endif
-
highmem = 0;
iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
- /* Zones have to begin on a 1 << MAX_ORDER page boundary,
+ /*
+ * Zones have to begin on a 1 << MAX_ORDER page boundary,
* so this makes sure that's true for highmem
*/
max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
- if(physmem_size + iomem_size > max_physmem){
+ if (physmem_size + iomem_size > max_physmem) {
highmem = physmem_size + iomem_size - max_physmem;
physmem_size -= highmem;
#ifndef CONFIG_HIGHMEM
@@ -441,7 +333,7 @@ int __init linux_main(int argc, char **argv)
start_vm = VMALLOC_START;
setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
- if(init_maps(physmem_size, iomem_size, highmem)){
+ if (init_maps(physmem_size, iomem_size, highmem)) {
printf("Failed to allocate mem_map for %Lu bytes of physical "
"memory and %Lu bytes of highmem\n", physmem_size,
highmem);
@@ -450,10 +342,11 @@ int __init linux_main(int argc, char **argv)
virtmem_size = physmem_size;
avail = get_kmem_end() - start_vm;
- if(physmem_size > avail) virtmem_size = avail;
+ if (physmem_size > avail)
+ virtmem_size = avail;
end_vm = start_vm + virtmem_size;
- if(virtmem_size < physmem_size)
+ if (virtmem_size < physmem_size)
printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size);
@@ -462,7 +355,7 @@ int __init linux_main(int argc, char **argv)
stack_protections((unsigned long) &init_thread_info);
os_flush_stdout();
- return CHOOSE_MODE(start_uml_tt(), start_uml_skas());
+ return start_uml();
}
extern int uml_exitcode;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 81acdc24348..13df191e2b4 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -18,13 +18,6 @@ SECTIONS
. = START + SIZEOF_HEADERS;
-#ifdef MODE_TT
- .remap_data : { UNMAP_PATH (.data .bss) }
- .remap : { UNMAP_PATH (.text) }
-
- . = ALIGN(4096); /* Init code and data */
-#endif
-
_text = .;
_stext = .;
__init_begin = .;
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 2f8c7946401..8e129af8170 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -1,23 +1,18 @@
#
-# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL
#
obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
- sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \
- user_syms.o util.o drivers/ sys-$(SUBARCH)/
-
-obj-$(CONFIG_MODE_SKAS) += skas/
-
-obj-$(CONFIG_MODE_TT) += tt.o
-user-objs-$(CONFIG_MODE_TT) += tt.o
+ registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \
+ umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
obj-$(CONFIG_TTY_LOG) += tty_log.o
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
- main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \
- tls.o uaccess.o umid.o util.o
+ main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
+ trap.o tty.o tls.o uaccess.o umid.o util.o
CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 59348359f9a..4158118c4a5 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -1,20 +1,19 @@
/*
- * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stdlib.h>
#include <unistd.h>
+#include <sched.h>
#include <signal.h>
#include <errno.h>
-#include <sched.h>
-#include <sys/syscall.h>
-#include "os.h"
+#include <sys/time.h>
+#include <asm/unistd.h>
#include "aio.h"
#include "init.h"
-#include "user.h"
-#include "mode.h"
#include "kern_constants.h"
+#include "os.h"
+#include "user.h"
struct aio_thread_req {
enum aio_type type;
@@ -28,7 +27,8 @@ struct aio_thread_req {
#if defined(HAVE_AIO_ABI)
#include <linux/aio_abi.h>
-/* If we have the headers, we are going to build with AIO enabled.
+/*
+ * If we have the headers, we are going to build with AIO enabled.
* If we don't have aio in libc, we define the necessary stubs here.
*/
@@ -52,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
#endif
-/* The AIO_MMAP cases force the mmapped page into memory here
+/*
+ * The AIO_MMAP cases force the mmapped page into memory here
* rather than in whatever place first touches the data. I used
* to do this by touching the page, but that's delicate because
* gcc is prone to optimizing that away. So, what's done here
@@ -106,12 +107,12 @@ static int aio_thread(void *arg)
signal(SIGWINCH, SIG_IGN);
- while(1){
+ while (1) {
n = io_getevents(ctx, 1, 1, &event, NULL);
- if(n < 0){
- if(errno == EINTR)
+ if (n < 0) {
+ if (errno == EINTR)
continue;
- printk("aio_thread - io_getevents failed, "
+ printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
"errno = %d\n", errno);
}
else {
@@ -120,9 +121,9 @@ static int aio_thread(void *arg)
.err = event.res });
reply_fd = ((struct aio_context *) reply.data)->reply_fd;
err = write(reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
- printk("aio_thread - write failed, fd = %d, "
- "err = %d\n", reply_fd, errno);
+ if (err != sizeof(reply))
+ printk(UM_KERN_ERR "aio_thread - write failed, "
+ "fd = %d, err = %d\n", reply_fd, errno);
}
}
return 0;
@@ -137,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req)
int n;
actual = lseek64(req->io_fd, req->offset, SEEK_SET);
- if(actual != req->offset)
+ if (actual != req->offset)
return -errno;
- switch(req->type){
+ switch(req->type) {
case AIO_READ:
n = read(req->io_fd, req->buf, req->len);
break;
@@ -151,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req)
n = read(req->io_fd, &c, sizeof(c));
break;
default:
- printk("do_not_aio - bad request type : %d\n", req->type);
+ printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
+ req->type);
return -EINVAL;
}
- if(n < 0)
+ if (n < 0)
return -errno;
return 0;
}
@@ -173,16 +175,18 @@ static int not_aio_thread(void *arg)
int err;
signal(SIGWINCH, SIG_IGN);
- while(1){
+ while (1) {
err = read(aio_req_fd_r, &req, sizeof(req));
- if(err != sizeof(req)){
- if(err < 0)
- printk("not_aio_thread - read failed, "
- "fd = %d, err = %d\n", aio_req_fd_r,
+ if (err != sizeof(req)) {
+ if (err < 0)
+ printk(UM_KERN_ERR "not_aio_thread - "
+ "read failed, fd = %d, err = %d\n",
+ aio_req_fd_r,
errno);
else {
- printk("not_aio_thread - short read, fd = %d, "
- "length = %d\n", aio_req_fd_r, err);
+ printk(UM_KERN_ERR "not_aio_thread - short "
+ "read, fd = %d, length = %d\n",
+ aio_req_fd_r, err);
}
continue;
}
@@ -190,9 +194,9 @@ static int not_aio_thread(void *arg)
reply = ((struct aio_thread_reply) { .data = req.aio,
.err = err });
err = write(req.aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
- printk("not_aio_thread - write failed, fd = %d, "
- "err = %d\n", req.aio->reply_fd, errno);
+ if (err != sizeof(reply))
+ printk(UM_KERN_ERR "not_aio_thread - write failed, "
+ "fd = %d, err = %d\n", req.aio->reply_fd, errno);
}
return 0;
@@ -203,35 +207,36 @@ static int init_aio_24(void)
int fds[2], err;
err = os_pipe(fds, 1, 1);
- if(err)
+ if (err)
goto out;
aio_req_fd_w = fds[0];
aio_req_fd_r = fds[1];
err = os_set_fd_block(aio_req_fd_w, 0);
- if(err)
+ if (err)
goto out_close_pipe;
err = run_helper_thread(not_aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
- if(err < 0)
+ if (err < 0)
goto out_close_pipe;
aio_pid = err;
goto out;
out_close_pipe:
- os_close_file(fds[0]);
- os_close_file(fds[1]);
+ close(fds[0]);
+ close(fds[1]);
aio_req_fd_w = -1;
aio_req_fd_r = -1;
out:
#ifndef HAVE_AIO_ABI
- printk("/usr/include/linux/aio_abi.h not present during build\n");
+ printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
+ "build\n");
#endif
- printk("2.6 host AIO support not used - falling back to I/O "
- "thread\n");
+ printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
+ "I/O thread\n");
return 0;
}
@@ -241,21 +246,21 @@ static int init_aio_26(void)
{
int err;
- if(io_setup(256, &ctx)){
+ if (io_setup(256, &ctx)) {
err = -errno;
- printk("aio_thread failed to initialize context, err = %d\n",
- errno);
+ printk(UM_KERN_ERR "aio_thread failed to initialize context, "
+ "err = %d\n", errno);
return err;
}
err = run_helper_thread(aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
- if(err < 0)
+ if (err < 0)
return err;
aio_pid = err;
- printk("Using 2.6 host AIO\n");
+ printk(UM_KERN_INFO "Using 2.6 host AIO\n");
return 0;
}
@@ -266,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
int err;
err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
- if(err){
+ if (err) {
reply = ((struct aio_thread_reply) { .data = aio,
.err = err });
err = write(aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply)){
+ if (err != sizeof(reply)) {
err = -errno;
- printk("submit_aio_26 - write failed, "
+ printk(UM_KERN_ERR "submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err);
}
else err = 0;
@@ -320,28 +325,24 @@ static int init_aio(void)
{
int err;
- CHOOSE_MODE(({ if(!aio_24){
- printk("Disabling 2.6 AIO in tt mode\n");
- aio_24 = 1;
- } }), (void) 0);
-
- if(!aio_24){
+ if (!aio_24) {
err = init_aio_26();
- if(err && (errno == ENOSYS)){
- printk("2.6 AIO not supported on the host - "
- "reverting to 2.4 AIO\n");
+ if (err && (errno == ENOSYS)) {
+ printk(UM_KERN_INFO "2.6 AIO not supported on the "
+ "host - reverting to 2.4 AIO\n");
aio_24 = 1;
}
else return err;
}
- if(aio_24)
+ if (aio_24)
return init_aio_24();
return 0;
}
-/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
+/*
+ * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
* needs to be called when the kernel is running because it calls run_helper,
* which needs get_free_page. exit_aio is a __uml_exitcall because the generic
* kernel does not run __exitcalls on shutdown, and can't because many of them
@@ -372,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
int err;
err = write(aio_req_fd_w, &req, sizeof(req));
- if(err == sizeof(req))
+ if (err == sizeof(req))
err = 0;
else err = -errno;
@@ -384,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
struct aio_context *aio)
{
aio->reply_fd = reply_fd;
- if(aio_24)
+ if (aio_24)
return submit_aio_24(type, io_fd, buf, len, offset, aio);
- else {
+ else
return submit_aio_26(type, io_fd, buf, len, offset, aio);
- }
}
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
index 57ecdaf2f67..ddffd41c3f3 100644
--- a/arch/um/os-Linux/drivers/etap.h
+++ b/arch/um/os-Linux/drivers/etap.h
@@ -1,8 +1,11 @@
/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
+#ifndef __DRIVERS_ETAP_H
+#define __DRIVERS_ETAP_H
+
#include "net_user.h"
struct ethertap_data {
@@ -15,13 +18,4 @@ struct ethertap_data {
extern const struct net_user_info ethertap_user_info;
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 12689141414..04f11b9f1ac 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -1,16 +1,15 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
*/
#include "linux/init.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
-#include "net_kern.h"
-#include "net_user.h"
+#include <linux/netdevice.h>
#include "etap.h"
+#include "net_kern.h"
struct ethertap_init {
char *dev_name;
@@ -37,32 +36,24 @@ static void etap_init(struct net_device *dev, void *data)
printk("\n");
}
-static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
int len;
- *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP);
- if(*skb == NULL) return(-ENOMEM);
- len = net_recvfrom(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP);
- if(len <= 0) return(len);
- skb_pull(*skb, 2);
+ len = net_recvfrom(fd, skb_mac_header(skb),
+ skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
+ if (len <= 0)
+ return(len);
+
+ skb_pull(skb, 2);
len -= 2;
- return(len);
+ return len;
}
-static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
+static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- if(skb_headroom(*skb) < 2){
- struct sk_buff *skb2;
-
- skb2 = skb_realloc_headroom(*skb, 2);
- dev_kfree_skb(*skb);
- if (skb2 == NULL) return(-ENOMEM);
- *skb = skb2;
- }
- skb_push(*skb, 2);
- return(net_send(fd, (*skb)->data, (*skb)->len));
+ skb_push(skb, 2);
+ return net_send(fd, skb->data, skb->len);
}
const struct net_kern_info ethertap_kern_info = {
@@ -79,15 +70,15 @@ int ethertap_setup(char *str, char **mac_out, void *data)
*init = ((struct ethertap_init)
{ .dev_name = NULL,
.gate_addr = NULL });
- if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
+ if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
&init->gate_addr))
- return(0);
- if(init->dev_name == NULL){
- printk("ethertap_setup : Missing tap device name\n");
- return(0);
+ return 0;
+ if (init->dev_name == NULL) {
+ printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
+ return 0;
}
- return(1);
+ return 1;
}
static struct transport ethertap_transport = {
@@ -97,6 +88,7 @@ static struct transport ethertap_transport = {
.user = &ethertap_user_info,
.kern = &ethertap_kern_info,
.private_size = sizeof(struct ethertap_data),
+ .setup_size = sizeof(struct ethertap_init),
};
static int register_ethertap(void)
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 61d3953c7ac..4ff55360344 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
@@ -7,20 +8,16 @@
#include <stdio.h>
#include <unistd.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/errno.h>
+#include <errno.h>
+#include <string.h>
#include <sys/socket.h>
#include <sys/wait.h>
-#include <sys/un.h>
-#include <net/if.h>
-#include "user.h"
-#include "kern_util.h"
-#include "net_user.h"
#include "etap.h"
+#include "kern_constants.h"
#include "os.h"
+#include "net_user.h"
#include "um_malloc.h"
-#include "kern_constants.h"
+#include "user.h"
#define MAX_PACKET ETH_MAX_PACKET
@@ -49,16 +46,18 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
memcpy(change.addr, addr, sizeof(change.addr));
memcpy(change.netmask, netmask, sizeof(change.netmask));
CATCH_EINTR(n = write(fd, &change, sizeof(change)));
- if(n != sizeof(change)){
- printk("etap_change - request failed, err = %d\n", errno);
+ if (n != sizeof(change)) {
+ printk(UM_KERN_ERR "etap_change - request failed, err = %d\n",
+ errno);
return;
}
output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
- if(output == NULL)
- printk("etap_change : Failed to allocate output buffer\n");
+ if (output == NULL)
+ printk(UM_KERN_ERR "etap_change : Failed to allocate output "
+ "buffer\n");
read_output(fd, output, UM_KERN_PAGE_SIZE);
- if(output != NULL){
+ if (output != NULL) {
printk("%s", output);
kfree(output);
}
@@ -87,11 +86,11 @@ static void etap_pre_exec(void *arg)
struct etap_pre_exec_data *data = arg;
dup2(data->control_remote, 1);
- os_close_file(data->data_me);
- os_close_file(data->control_me);
+ close(data->data_me);
+ close(data->control_me);
}
-static int etap_tramp(char *dev, char *gate, int control_me,
+static int etap_tramp(char *dev, char *gate, int control_me,
int control_remote, int data_me, int data_remote)
{
struct etap_pre_exec_data pe_data;
@@ -101,13 +100,13 @@ static int etap_tramp(char *dev, char *gate, int control_me,
char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
data_fd_buf, gate_buf, NULL };
- char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
+ char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
dev, data_fd_buf, NULL };
char **args, c;
sprintf(data_fd_buf, "%d", data_remote);
sprintf(version_buf, "%d", UML_NET_VERSION);
- if(gate != NULL){
+ if (gate != NULL) {
strcpy(gate_buf, gate);
args = setup_args;
}
@@ -119,24 +118,26 @@ static int etap_tramp(char *dev, char *gate, int control_me,
pe_data.data_me = data_me;
pid = run_helper(etap_pre_exec, &pe_data, args);
- if(pid < 0)
+ if (pid < 0)
err = pid;
- os_close_file(data_remote);
- os_close_file(control_remote);
+ close(data_remote);
+ close(control_remote);
CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
- if(n != sizeof(c)){
+ if (n != sizeof(c)) {
err = -errno;
- printk("etap_tramp : read of status failed, err = %d\n", -err);
+ printk(UM_KERN_ERR "etap_tramp : read of status failed, "
+ "err = %d\n", -err);
return err;
}
- if(c != 1){
- printk("etap_tramp : uml_net failed\n");
+ if (c != 1) {
+ printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
err = -EINVAL;
CATCH_EINTR(n = waitpid(pid, &status, 0));
- if(n < 0)
+ if (n < 0)
err = -errno;
- else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
- printk("uml_net didn't exit with status 1\n");
+ else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
+ printk(UM_KERN_ERR "uml_net didn't exit with "
+ "status 1\n");
}
return err;
}
@@ -148,43 +149,56 @@ static int etap_open(void *data)
int data_fds[2], control_fds[2], err, output_len;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err)
+ if (err)
return err;
- err = os_pipe(data_fds, 0, 0);
- if(err < 0){
- printk("data os_pipe failed - err = %d\n", -err);
+ err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
+ if (err) {
+ err = -errno;
+ printk(UM_KERN_ERR "etap_open - data socketpair failed - "
+ "err = %d\n", errno);
return err;
}
- err = os_pipe(control_fds, 1, 0);
- if(err < 0){
- printk("control os_pipe failed - err = %d\n", -err);
- return err;
+ err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
+ if (err) {
+ err = -errno;
+ printk(UM_KERN_ERR "etap_open - control socketpair failed - "
+ "err = %d\n", errno);
+ goto out_close_data;
}
- err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
+ err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
output_len = UM_KERN_PAGE_SIZE;
output = kmalloc(output_len, UM_GFP_KERNEL);
read_output(control_fds[0], output, output_len);
- if(output == NULL)
- printk("etap_open : failed to allocate output buffer\n");
+ if (output == NULL)
+ printk(UM_KERN_ERR "etap_open : failed to allocate output "
+ "buffer\n");
else {
printk("%s", output);
kfree(output);
}
- if(err < 0){
- printk("etap_tramp failed - err = %d\n", -err);
- return err;
+ if (err < 0) {
+ printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err);
+ goto out_close_control;
}
pri->data_fd = data_fds[0];
pri->control_fd = control_fds[0];
iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
return data_fds[0];
+
+out_close_control:
+ close(control_fds[0]);
+ close(control_fds[1]);
+out_close_data:
+ close(data_fds[0]);
+ close(data_fds[1]);
+ return err;
}
static void etap_close(int fd, void *data)
@@ -192,37 +206,41 @@ static void etap_close(int fd, void *data)
struct ethertap_data *pri = data;
iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
- os_close_file(fd);
- os_shutdown_socket(pri->data_fd, 1, 1);
- os_close_file(pri->data_fd);
+ close(fd);
+
+ if (shutdown(pri->data_fd, SHUT_RDWR) < 0)
+ printk(UM_KERN_ERR "etap_close - shutdown data socket failed, "
+ "errno = %d\n", errno);
+
+ if (shutdown(pri->control_fd, SHUT_RDWR) < 0)
+ printk(UM_KERN_ERR "etap_close - shutdown control socket "
+ "failed, errno = %d\n", errno);
+
+ close(pri->data_fd);
pri->data_fd = -1;
- os_close_file(pri->control_fd);
+ close(pri->control_fd);
pri->control_fd = -1;
}
-static int etap_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct ethertap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if(pri->control_fd == -1)
+ if (pri->control_fd == -1)
return;
etap_open_addr(addr, netmask, &pri->control_fd);
}
-static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
+static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
void *data)
{
struct ethertap_data *pri = data;
- if(pri->control_fd == -1)
+ if (pri->control_fd == -1)
return;
+
etap_close_addr(addr, netmask, &pri->control_fd);
}
@@ -231,8 +249,8 @@ const struct net_user_info ethertap_user_info = {
.open = etap_open,
.close = etap_close,
.remove = NULL,
- .set_mtu = etap_set_mtu,
.add_address = etap_add_addr,
.delete_address = etap_del_addr,
- .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP,
};
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
index d3e8d3af624..f17c31586c8 100644
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ b/arch/um/os-Linux/drivers/tuntap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -19,14 +19,3 @@ struct tuntap_data {
extern const struct net_user_info tuntap_user_info;
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index f1714e7fb1d..9d384807b07 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -1,16 +1,13 @@
-/*
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/stddef.h"
-#include "linux/netdevice.h"
-#include "linux/etherdevice.h"
-#include "linux/skbuff.h"
-#include "linux/init.h"
-#include "asm/errno.h"
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <asm/errno.h>
#include "net_kern.h"
-#include "net_user.h"
#include "tuntap.h"
struct tuntap_init {
@@ -38,19 +35,15 @@ static void tuntap_init(struct net_device *dev, void *data)
printk("\n");
}
-static int tuntap_read(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if(*skb == NULL) return(-ENOMEM);
- return(net_read(fd, skb_mac_header(*skb),
- (*skb)->dev->mtu + ETH_HEADER_OTHER));
+ return net_read(fd, skb_mac_header(skb),
+ skb->dev->mtu + ETH_HEADER_OTHER);
}
-static int tuntap_write(int fd, struct sk_buff **skb,
- struct uml_net_private *lp)
+static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
{
- return(net_write(fd, (*skb)->data, (*skb)->len));
+ return net_write(fd, skb->data, skb->len);
}
const struct net_kern_info tuntap_kern_info = {
@@ -67,11 +60,11 @@ int tuntap_setup(char *str, char **mac_out, void *data)
*init = ((struct tuntap_init)
{ .dev_name = NULL,
.gate_addr = NULL });
- if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
+ if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
&init->gate_addr))
- return(0);
+ return 0;
- return(1);
+ return 1;
}
static struct transport tuntap_transport = {
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index f848b4ea934..6c55d3c8ead 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -1,27 +1,22 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
-#include <sys/wait.h>
+#include <string.h>
+#include <linux/if_tun.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <sys/un.h>
+#include <sys/wait.h>
#include <sys/uio.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <linux/if_tun.h>
-#include "net_user.h"
+#include "kern_constants.h"
+#include "os.h"
#include "tuntap.h"
-#include "kern_util.h"
#include "user.h"
-#include "os.h"
-
-#define MAX_PACKET ETH_MAX_PACKET
static int tuntap_user_init(void *data, void *dev)
{
@@ -37,7 +32,7 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
struct tuntap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if((pri->fd == -1) || pri->fixed_config)
+ if ((pri->fd == -1) || pri->fixed_config)
return;
open_addr(addr, netmask, pri->dev_name);
}
@@ -47,7 +42,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct tuntap_data *pri = data;
- if((pri->fd == -1) || pri->fixed_config)
+ if ((pri->fd == -1) || pri->fixed_config)
return;
close_addr(addr, netmask, pri->dev_name);
}
@@ -62,7 +57,7 @@ static void tuntap_pre_exec(void *arg)
struct tuntap_pre_exec_data *data = arg;
dup2(data->stdout, 1);
- os_close_file(data->close_me);
+ close(data->close_me);
}
static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
@@ -85,14 +80,14 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
pid = run_helper(tuntap_pre_exec, &data, argv);
- if(pid < 0)
+ if (pid < 0)
return -pid;
- os_close_file(remote);
+ close(remote);
msg.msg_name = NULL;
msg.msg_namelen = 0;
- if(buffer != NULL){
+ if (buffer != NULL) {
iov = ((struct iovec) { buffer, buffer_len });
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
@@ -106,26 +101,28 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
msg.msg_flags = 0;
n = recvmsg(me, &msg, 0);
*used_out = n;
- if(n < 0){
+ if (n < 0) {
err = -errno;
- printk("tuntap_open_tramp : recvmsg failed - errno = %d\n",
- errno);
+ printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - "
+ "errno = %d\n", errno);
return err;
}
CATCH_EINTR(waitpid(pid, NULL, 0));
cmsg = CMSG_FIRSTHDR(&msg);
- if(cmsg == NULL){
- printk("tuntap_open_tramp : didn't receive a message\n");
+ if (cmsg == NULL) {
+ printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
+ "message\n");
return -EINVAL;
}
- if((cmsg->cmsg_level != SOL_SOCKET) ||
- (cmsg->cmsg_type != SCM_RIGHTS)){
- printk("tuntap_open_tramp : didn't receive a descriptor\n");
+ if ((cmsg->cmsg_level != SOL_SOCKET) ||
+ (cmsg->cmsg_type != SCM_RIGHTS)) {
+ printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
+ "descriptor\n");
return -EINVAL;
}
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
- os_set_exec_close(*fd_out, 1);
+ os_set_exec_close(*fd_out);
return 0;
}
@@ -137,47 +134,51 @@ static int tuntap_open(void *data)
int err, fds[2], len, used;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err < 0)
+ if (err < 0)
return err;
- if(pri->fixed_config){
+ if (pri->fixed_config) {
pri->fd = os_open_file("/dev/net/tun",
of_cloexec(of_rdwr(OPENFLAGS())), 0);
- if(pri->fd < 0){
- printk("Failed to open /dev/net/tun, err = %d\n",
- -pri->fd);
+ if (pri->fd < 0) {
+ printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
+ "err = %d\n", -pri->fd);
return pri->fd;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
- if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
+ if (ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0) {
err = -errno;
- printk("TUNSETIFF failed, errno = %d\n", errno);
- os_close_file(pri->fd);
+ printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
+ errno);
+ close(pri->fd);
return err;
}
}
else {
- err = os_pipe(fds, 0, 0);
- if(err < 0){
- printk("tuntap_open : os_pipe failed - err = %d\n",
- -err);
+ err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
+ if (err) {
+ err = -errno;
+ printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
+ "errno = %d\n", errno);
return err;
}
buffer = get_output_buffer(&len);
- if(buffer != NULL) len--;
+ if (buffer != NULL)
+ len--;
used = 0;
err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
fds[1], buffer, len, &used);
output = buffer;
- if(err < 0) {
+ if (err < 0) {
printk("%s", output);
free_output_buffer(buffer);
- printk("tuntap_open_tramp failed - err = %d\n", -err);
+ printk(UM_KERN_ERR "tuntap_open_tramp failed - "
+ "err = %d\n", -err);
return err;
}
@@ -186,7 +187,7 @@ static int tuntap_open(void *data)
printk("%s", output);
free_output_buffer(buffer);
- os_close_file(fds[0]);
+ close(fds[0]);
iter_addresses(pri->dev, open_addr, pri->dev_name);
}
@@ -197,24 +198,19 @@ static void tuntap_close(int fd, void *data)
{
struct tuntap_data *pri = data;
- if(!pri->fixed_config)
+ if (!pri->fixed_config)
iter_addresses(pri->dev, close_addr, pri->dev_name);
- os_close_file(fd);
+ close(fd);
pri->fd = -1;
}
-static int tuntap_set_mtu(int mtu, void *data)
-{
- return mtu;
-}
-
const struct net_user_info tuntap_user_info = {
.init = tuntap_user_init,
.open = tuntap_open,
.close = tuntap_close,
.remove = NULL,
- .set_mtu = tuntap_set_mtu,
.add_address = tuntap_add_addr,
.delete_address = tuntap_del_addr,
- .max_packet = MAX_PACKET
+ .mtu = ETH_MAX_PACKET,
+ .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
};
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index c3ecc2a84e0..b542a3a021b 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -82,13 +82,6 @@ int os_access(const char* file, int mode)
return 0;
}
-void os_print_error(int error, const char* str)
-{
- errno = error < 0 ? -error : error;
-
- perror(str);
-}
-
/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
{
@@ -101,30 +94,6 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
return err;
}
-int os_window_size(int fd, int *rows, int *cols)
-{
- struct winsize size;
-
- if(ioctl(fd, TIOCGWINSZ, &size) < 0)
- return -errno;
-
- *rows = size.ws_row;
- *cols = size.ws_col;
-
- return 0;
-}
-
-int os_new_tty_pgrp(int fd, int pid)
-{
- if(ioctl(fd, TIOCSCTTY, 0) < 0)
- return -errno;
-
- if(tcsetpgrp(fd, pid) < 0)
- return -errno;
-
- return 0;
-}
-
/* FIXME: ensure namebuf in os_get_if_name is big enough */
int os_get_ifname(int fd, char* namebuf)
{
@@ -205,19 +174,19 @@ int os_file_mode(char *file, struct openflags *mode_out)
*mode_out = OPENFLAGS();
- err = os_access(file, OS_ACC_W_OK);
- if((err < 0) && (err != -EACCES))
- return(err);
-
- *mode_out = of_write(*mode_out);
-
- err = os_access(file, OS_ACC_R_OK);
- if((err < 0) && (err != -EACCES))
- return(err);
+ err = access(file, W_OK);
+ if(err && (errno != EACCES))
+ return -errno;
+ else if(!err)
+ *mode_out = of_write(*mode_out);
- *mode_out = of_read(*mode_out);
+ err = access(file, R_OK);
+ if(err && (errno != EACCES))
+ return -errno;
+ else if(!err)
+ *mode_out = of_read(*mode_out);
- return(0);
+ return err;
}
int os_open_file(char *file, struct openflags flags, int mode)
@@ -236,15 +205,15 @@ int os_open_file(char *file, struct openflags flags, int mode)
fd = open64(file, f, mode);
if(fd < 0)
- return(-errno);
+ return -errno;
if(flags.cl && fcntl(fd, F_SETFD, 1)){
err = -errno;
- os_close_file(fd);
+ close(fd);
return err;
}
- return(fd);
+ return fd;
}
int os_connect_socket(char *name)
@@ -280,9 +249,9 @@ void os_close_file(int fd)
close(fd);
}
-int os_seek_file(int fd, __u64 offset)
+int os_seek_file(int fd, unsigned long long offset)
{
- __u64 actual;
+ unsigned long long actual;
actual = lseek64(fd, offset, SEEK_SET);
if(actual != offset)
@@ -316,31 +285,33 @@ int os_file_size(char *file, unsigned long long *size_out)
err = os_stat_file(file, &buf);
if(err < 0){
printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
- return(err);
+ return err;
}
if(S_ISBLK(buf.ust_mode)){
int fd;
long blocks;
- fd = os_open_file(file, of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
- return(fd);
+ fd = open(file, O_RDONLY, 0);
+ if(fd < 0) {
+ err = -errno;
+ printk("Couldn't open \"%s\", errno = %d\n", file,
+ errno);
+ return err;
}
if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
err = -errno;
printk("Couldn't get the block size of \"%s\", "
"errno = %d\n", file, errno);
- os_close_file(fd);
- return(err);
+ close(fd);
+ return err;
}
*size_out = ((long long) blocks) * 512;
- os_close_file(fd);
- return(0);
+ close(fd);
}
- *size_out = buf.ust_size;
- return(0);
+ else *size_out = buf.ust_size;
+
+ return 0;
}
int os_file_modtime(char *file, unsigned long *modtime)
@@ -358,35 +329,28 @@ int os_file_modtime(char *file, unsigned long *modtime)
return 0;
}
-int os_get_exec_close(int fd, int* close_on_exec)
+int os_get_exec_close(int fd, int *close_on_exec)
{
int ret;
- do {
- ret = fcntl(fd, F_GETFD);
- } while((ret < 0) && (errno == EINTR)) ;
+ CATCH_EINTR(ret = fcntl(fd, F_GETFD));
if(ret < 0)
- return(-errno);
+ return -errno;
- *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
- return(ret);
+ *close_on_exec = (ret & FD_CLOEXEC) ? 1 : 0;
+ return ret;
}
-int os_set_exec_close(int fd, int close_on_exec)
+int os_set_exec_close(int fd)
{
- int flag, err;
-
- if(close_on_exec) flag = FD_CLOEXEC;
- else flag = 0;
+ int err;
- do {
- err = fcntl(fd, F_SETFD, flag);
- } while((err < 0) && (errno == EINTR)) ;
+ CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));
if(err < 0)
- return(-errno);
- return(err);
+ return -errno;
+ return err;
}
int os_pipe(int *fds, int stream, int close_on_exec)
@@ -395,16 +359,16 @@ int os_pipe(int *fds, int stream, int close_on_exec)
err = socketpair(AF_UNIX, type, 0, fds);
if(err < 0)
- return(-errno);
+ return -errno;
if(!close_on_exec)
- return(0);
+ return 0;
- err = os_set_exec_close(fds[0], 1);
+ err = os_set_exec_close(fds[0]);
if(err < 0)
goto error;
- err = os_set_exec_close(fds[1], 1);
+ err = os_set_exec_close(fds[1]);
if(err < 0)
goto error;
@@ -412,9 +376,9 @@ int os_pipe(int *fds, int stream, int close_on_exec)
error:
printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
- os_close_file(fds[1]);
- os_close_file(fds[0]);
- return(err);
+ close(fds[1]);
+ close(fds[0]);
+ return err;
}
int os_set_fd_async(int fd, int owner)
@@ -561,7 +525,7 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
return -errno;
if(close_on_exec) {
- err = os_set_exec_close(sock, 1);
+ err = os_set_exec_close(sock);
if(err < 0)
printk("create_unix_socket : close_on_exec failed, "
"err = %d", -err);
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index d81af7b8587..7a72dbb61b0 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -11,6 +11,7 @@
#include <limits.h>
#include <sys/signal.h>
#include <sys/wait.h>
+#include <sys/socket.h>
#include "user.h"
#include "kern_util.h"
#include "os.h"
@@ -54,13 +55,14 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
if (stack == 0)
return -ENOMEM;
- ret = os_pipe(fds, 1, 0);
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
if (ret < 0) {
- printk("run_helper : pipe failed, ret = %d\n", -ret);
+ ret = -errno;
+ printk("run_helper : pipe failed, errno = %d\n", errno);
goto out_free;
}
- ret = os_set_exec_close(fds[1], 1);
+ ret = os_set_exec_close(fds[1]);
if (ret < 0) {
printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
-ret);
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index a633fa8e0a9..6aa6f95d652 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -145,11 +145,7 @@ void init_irq_signals(int on_sigstack)
flags = on_sigstack ? SA_ONSTACK : 0;
- set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
- flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
- set_handler(SIGALRM, (__sighandler_t) alarm_handler,
- flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
signal(SIGWINCH, SIG_IGN);
}
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index e85f4995a01..82c3778627b 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -1,33 +1,21 @@
/*
- * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
+#include <unistd.h>
#include <errno.h>
+#include <signal.h>
+#include <string.h>
#include <sys/resource.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-#include <asm/page.h>
-#include "kern_util.h"
#include "as-layout.h"
-#include "mem_user.h"
-#include "irq_user.h"
-#include "user.h"
#include "init.h"
-#include "mode.h"
-#include "choose-mode.h"
-#include "uml-config.h"
+#include "kern_constants.h"
+#include "kern_util.h"
#include "os.h"
#include "um_malloc.h"
-#include "kern_constants.h"
-
-/* Set in main, unchanged thereafter */
-char *linux_prog;
#define PGD_BOUND (4 * 1024 * 1024)
#define STACKSIZE (8 * 1024 * 1024)
@@ -37,13 +25,13 @@ static void set_stklim(void)
{
struct rlimit lim;
- if(getrlimit(RLIMIT_STACK, &lim) < 0){
+ if (getrlimit(RLIMIT_STACK, &lim) < 0) {
perror("getrlimit");
exit(1);
}
- if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
+ if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) {
lim.rlim_cur = STACKSIZE;
- if(setrlimit(RLIMIT_STACK, &lim) < 0){
+ if (setrlimit(RLIMIT_STACK, &lim) < 0) {
perror("setrlimit");
exit(1);
}
@@ -55,7 +43,7 @@ static __init void do_uml_initcalls(void)
initcall_t *call;
call = &__uml_initcall_start;
- while (call < &__uml_initcall_end){
+ while (call < &__uml_initcall_end) {
(*call)();
call++;
}
@@ -74,7 +62,8 @@ static void install_fatal_handler(int sig)
/* All signals are enabled in this handler ... */
sigemptyset(&action.sa_mask);
- /* ... including the signal being handled, plus we want the
+ /*
+ * ... including the signal being handled, plus we want the
* handler reset to the default behavior, so that if an exit
* handler is hanging for some reason, the UML will just die
* after this signal is sent a second time.
@@ -82,7 +71,7 @@ static void install_fatal_handler(int sig)
action.sa_flags = SA_RESETHAND | SA_NODEFER;
action.sa_restorer = NULL;
action.sa_handler = last_ditch_exit;
- if(sigaction(sig, &action, NULL) < 0){
+ if (sigaction(sig, &action, NULL) < 0) {
printf("failed to install handler for signal %d - errno = %d\n",
errno);
exit(1);
@@ -98,7 +87,8 @@ static void setup_env_path(void)
int path_len = 0;
old_path = getenv("PATH");
- /* if no PATH variable is set or it has an empty value
+ /*
+ * if no PATH variable is set or it has an empty value
* just use the default + /usr/lib/uml
*/
if (!old_path || (path_len = strlen(old_path)) == 0) {
@@ -126,93 +116,68 @@ int __init main(int argc, char **argv, char **envp)
char **new_argv;
int ret, i, err;
-#ifdef UML_CONFIG_CMDLINE_ON_HOST
- /* Allocate memory for thread command lines */
- if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
-
- char padding[THREAD_NAME_LEN] = {
- [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
- };
-
- new_argv = malloc((argc + 2) * sizeof(char*));
- if(!new_argv) {
- perror("Allocating extended argv");
- exit(1);
- }
-
- new_argv[0] = argv[0];
- new_argv[1] = padding;
-
- for(i = 2; i <= argc; i++)
- new_argv[i] = argv[i - 1];
- new_argv[argc + 1] = NULL;
-
- execvp(new_argv[0], new_argv);
- perror("execing with extended args");
- exit(1);
- }
-#endif
-
- linux_prog = argv[0];
-
set_stklim();
setup_env_path();
new_argv = malloc((argc + 1) * sizeof(char *));
- if(new_argv == NULL){
+ if (new_argv == NULL) {
perror("Mallocing argv");
exit(1);
}
- for(i=0;i<argc;i++){
+ for (i = 0; i < argc; i++) {
new_argv[i] = strdup(argv[i]);
- if(new_argv[i] == NULL){
+ if (new_argv[i] == NULL) {
perror("Mallocing an arg");
exit(1);
}
}
new_argv[argc] = NULL;
- /* Allow these signals to bring down a UML if all other
+ /*
+ * Allow these signals to bring down a UML if all other
* methods of control fail.
*/
install_fatal_handler(SIGINT);
install_fatal_handler(SIGTERM);
install_fatal_handler(SIGHUP);
- scan_elf_aux( envp);
+ scan_elf_aux(envp);
do_uml_initcalls();
ret = linux_main(argc, argv);
- /* Disable SIGPROF - I have no idea why libc doesn't do this or turn
+ /*
+ * Disable SIGPROF - I have no idea why libc doesn't do this or turn
* off the profiling time, but UML dies with a SIGPROF just before
* exiting when profiling is active.
*/
change_sig(SIGPROF, 0);
- /* This signal stuff used to be in the reboot case. However,
+ /*
+ * This signal stuff used to be in the reboot case. However,
* sometimes a SIGVTALRM can come in when we're halting (reproducably
* when writing out gcov information, presumably because that takes
* some time) and cause a segfault.
*/
- /* stop timers and set SIG*ALRM to be ignored */
+ /* stop timers and set SIGVTALRM to be ignored */
disable_timer();
/* disable SIGIO for the fds and set SIGIO to be ignored */
err = deactivate_all_fds();
- if(err)
+ if (err)
printf("deactivate_all_fds failed, errno = %d\n", -err);
- /* Let any pending signals fire now. This ensures
+ /*
+ * Let any pending signals fire now. This ensures
* that they won't be delivered after the exec, when
* they are definitely not expected.
*/
unblock_signals();
/* Reboot */
- if(ret){
+ if (ret) {
printf("\n");
execvp(new_argv[0], new_argv);
perror("Failed to exec kernel");
@@ -222,26 +187,24 @@ int __init main(int argc, char **argv, char **envp)
return uml_exitcode;
}
-#define CAN_KMALLOC() \
- (kmalloc_ok && CHOOSE_MODE((os_getpid() != tracing_pid), 1))
-
extern void *__real_malloc(int);
void *__wrap_malloc(int size)
{
void *ret;
- if(!CAN_KMALLOC())
+ if (!kmalloc_ok)
return __real_malloc(size);
- else if(size <= UM_KERN_PAGE_SIZE)
+ else if (size <= UM_KERN_PAGE_SIZE)
/* finding contiguous pages can be hard*/
ret = kmalloc(size, UM_GFP_KERNEL);
else ret = vmalloc(size);
- /* glibc people insist that if malloc fails, errno should be
+ /*
+ * glibc people insist that if malloc fails, errno should be
* set by malloc as well. So we do.
*/
- if(ret == NULL)
+ if (ret == NULL)
errno = ENOMEM;
return ret;
@@ -251,7 +214,7 @@ void *__wrap_calloc(int n, int size)
{
void *ptr = __wrap_malloc(n * size);
- if(ptr == NULL)
+ if (ptr == NULL)
return NULL;
memset(ptr, 0, n * size);
return ptr;
@@ -265,7 +228,8 @@ void __wrap_free(void *ptr)
{
unsigned long addr = (unsigned long) ptr;
- /* We need to know how the allocation happened, so it can be correctly
+ /*
+ * We need to know how the allocation happened, so it can be correctly
* freed. This is done by seeing what region of memory the pointer is
* in -
* physical memory - kmalloc/kfree
@@ -283,12 +247,12 @@ void __wrap_free(void *ptr)
* there is a possibility for memory leaks.
*/
- if((addr >= uml_physmem) && (addr < high_physmem)){
- if(CAN_KMALLOC())
+ if ((addr >= uml_physmem) && (addr < high_physmem)) {
+ if (kmalloc_ok)
kfree(ptr);
}
- else if((addr >= start_vm) && (addr < end_vm)){
- if(CAN_KMALLOC())
+ else if ((addr >= start_vm) && (addr < end_vm)) {
+ if (kmalloc_ok)
vfree(ptr);
}
else __real_free(ptr);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index c6378c6d10d..436f8d20b20 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -218,7 +218,7 @@ int __init create_tmp_file(unsigned long long len)
err = fchmod(fd, 0777);
if(err < 0){
- perror("os_mode_fd");
+ perror("fchmod");
exit(1);
}
@@ -226,7 +226,7 @@ int __init create_tmp_file(unsigned long long len)
* increase the file size by one byte, to the desired length.
*/
if (lseek64(fd, len - 1, SEEK_SET) < 0) {
- perror("os_seek_file");
+ perror("lseek64");
exit(1);
}
@@ -247,7 +247,7 @@ int __init create_mem_file(unsigned long long len)
fd = create_tmp_file(len);
- err = os_set_exec_close(fd, 1);
+ err = os_set_exec_close(fd);
if(err < 0){
errno = -err;
perror("exec_close");
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index e9c14329751..37781db4cec 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -1,27 +1,24 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <unistd.h>
#include <stdio.h>
+#include <unistd.h>
#include <errno.h>
#include <signal.h>
+#include <fcntl.h>
#include <sys/mman.h>
+#include <sys/ptrace.h>
#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include "ptrace_user.h"
+#include <asm/unistd.h>
+#include "init.h"
+#include "kern_constants.h"
+#include "longjmp.h"
#include "os.h"
-#include "user.h"
#include "process.h"
-#include "irq_user.h"
-#include "kern_util.h"
-#include "longjmp.h"
#include "skas_ptrace.h"
-#include "kern_constants.h"
-#include "uml-config.h"
-#include "init.h"
+#include "user.h"
#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
@@ -32,30 +29,32 @@
unsigned long os_process_pc(int pid)
{
char proc_stat[STAT_PATH_LEN], buf[256];
- unsigned long pc;
+ unsigned long pc = ARBITRARY_ADDR;
int fd, err;
sprintf(proc_stat, "/proc/%d/stat", pid);
- fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("os_process_pc - couldn't open '%s', err = %d\n",
- proc_stat, -fd);
- return ARBITRARY_ADDR;
+ fd = open(proc_stat, O_RDONLY, 0);
+ if (fd < 0) {
+ printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
+ "errno = %d\n", proc_stat, errno);
+ goto out;
}
CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
- if(err < 0){
- printk("os_process_pc - couldn't read '%s', err = %d\n",
- proc_stat, errno);
- os_close_file(fd);
- return ARBITRARY_ADDR;
+ if (err < 0) {
+ printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
+ "err = %d\n", proc_stat, errno);
+ goto out_close;
}
os_close_file(fd);
pc = ARBITRARY_ADDR;
- if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
- "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
- "%*d %*d %*d %*d %*d %lu", &pc) != 1){
- printk("os_process_pc - couldn't find pc in '%s'\n", buf);
- }
+ if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
+ "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
+ "%*d %*d %*d %*d %*d %lu", &pc) != 1)
+ printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n",
+ buf);
+ out_close:
+ close(fd);
+ out:
return pc;
}
@@ -63,30 +62,32 @@ int os_process_parent(int pid)
{
char stat[STAT_PATH_LEN];
char data[256];
- int parent, n, fd;
+ int parent = FAILURE_PID, n, fd;
- if(pid == -1)
- return -1;
+ if (pid == -1)
+ return parent;
snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
- fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open '%s', err = %d\n", stat, -fd);
- return FAILURE_PID;
+ fd = open(stat, O_RDONLY, 0);
+ if (fd < 0) {
+ printk(UM_KERN_ERR "Couldn't open '%s', errno = %d\n", stat,
+ errno);
+ return parent;
}
CATCH_EINTR(n = read(fd, data, sizeof(data)));
- os_close_file(fd);
+ close(fd);
- if(n < 0){
- printk("Couldn't read '%s', err = %d\n", stat, errno);
- return FAILURE_PID;
+ if (n < 0) {
+ printk(UM_KERN_ERR "Couldn't read '%s', errno = %d\n", stat,
+ errno);
+ return parent;
}
parent = FAILURE_PID;
n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
- if(n != 1)
- printk("Failed to scan '%s'\n", data);
+ if (n != 1)
+ printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
return parent;
}
@@ -99,9 +100,8 @@ void os_stop_process(int pid)
void os_kill_process(int pid, int reap_child)
{
kill(pid, SIGKILL);
- if(reap_child)
+ if (reap_child)
CATCH_EINTR(waitpid(pid, NULL, 0));
-
}
/* This is here uniquely to have access to the userspace errno, i.e. the one
@@ -129,17 +129,10 @@ void os_kill_ptraced_process(int pid, int reap_child)
kill(pid, SIGKILL);
ptrace(PTRACE_KILL, pid);
ptrace(PTRACE_CONT, pid);
- if(reap_child)
+ if (reap_child)
CATCH_EINTR(waitpid(pid, NULL, 0));
}
-#ifdef UML_CONFIG_MODE_TT
-void os_usr1_process(int pid)
-{
- kill(pid, SIGUSR1);
-}
-#endif
-
/* Don't use the glibc version, which caches the result in TLS. It misses some
* syscalls, and also breaks with clone(), which does not unshare the TLS.
*/
@@ -160,34 +153,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
void *loc;
int prot;
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
+ prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
(x ? PROT_EXEC : 0);
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
fd, off);
- if(loc == MAP_FAILED)
+ if (loc == MAP_FAILED)
return -errno;
return 0;
}
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
{
- int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
+ int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
(x ? PROT_EXEC : 0));
- if(mprotect(addr, len, prot) < 0)
+ if (mprotect(addr, len, prot) < 0)
return -errno;
- return 0;
+
+ return 0;
}
int os_unmap_memory(void *addr, int len)
{
- int err;
+ int err;
- err = munmap(addr, len);
- if(err < 0)
+ err = munmap(addr, len);
+ if (err < 0)
return -errno;
- return 0;
+ return 0;
}
#ifndef MADV_REMOVE
@@ -199,7 +193,7 @@ int os_drop_memory(void *addr, int length)
int err;
err = madvise(addr, length, MADV_REMOVE);
- if(err < 0)
+ if (err < 0)
err = -errno;
return err;
}
@@ -209,22 +203,24 @@ int __init can_drop_memory(void)
void *addr;
int fd, ok = 0;
- printk("Checking host MADV_REMOVE support...");
+ printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
fd = create_mem_file(UM_KERN_PAGE_SIZE);
- if(fd < 0){
- printk("Creating test memory file failed, err = %d\n", -fd);
+ if (fd < 0) {
+ printk(UM_KERN_ERR "Creating test memory file failed, "
+ "err = %d\n", -fd);
goto out;
}
addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
- if(addr == MAP_FAILED){
- printk("Mapping test memory file failed, err = %d\n", -errno);
+ if (addr == MAP_FAILED) {
+ printk(UM_KERN_ERR "Mapping test memory file failed, "
+ "err = %d\n", -errno);
goto out_close;
}
- if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){
- printk("MADV_REMOVE failed, err = %d\n", -errno);
+ if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
+ printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
goto out_unmap;
}
@@ -239,58 +235,31 @@ out:
return ok;
}
-#ifdef UML_CONFIG_MODE_TT
-void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
-{
- int flags = 0, pages;
-
- if(sig_stack != NULL){
- pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
- set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
- flags = SA_ONSTACK;
- }
- if(usr1_handler){
- struct sigaction sa;
-
- sa.sa_handler = usr1_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = flags;
- sa.sa_restorer = NULL;
- if(sigaction(SIGUSR1, &sa, NULL) < 0)
- panic("init_new_thread_stack - sigaction failed - "
- "errno = %d\n", errno);
- }
-}
-#endif
-
void init_new_thread_signals(void)
{
set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+ SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK,
- SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
- set_handler(SIGUSR2, (__sighandler_t) sig_handler,
- SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
- -1);
+ SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
signal(SIGHUP, SIG_IGN);
init_irq_signals(1);
}
-int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
+int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
{
jmp_buf buf;
int n;
*jmp_ptr = &buf;
n = UML_SETJMP(&buf);
- if(n != 0)
+ if (n != 0)
return n;
(*fn)(arg);
return 0;
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
new file mode 100644
index 00000000000..a32ba6ab121
--- /dev/null
+++ b/arch/um/os-Linux/registers.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ptrace.h>
+#include "sysdep/ptrace.h"
+#include "user.h"
+
+/* This is set once at boot time and not changed thereafter */
+
+static unsigned long exec_regs[MAX_REG_NR];
+
+void init_thread_registers(struct uml_pt_regs *to)
+{
+ memcpy(to->gp, exec_regs, sizeof(to->gp));
+}
+
+void save_registers(int pid, struct uml_pt_regs *regs)
+{
+ int err;
+
+ err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
+ if (err < 0)
+ panic("save_registers - saving registers failed, errno = %d\n",
+ errno);
+}
+
+void restore_registers(int pid, struct uml_pt_regs *regs)
+{
+ int err;
+
+ err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
+ if (err < 0)
+ panic("restore_registers - saving registers failed, "
+ "errno = %d\n", errno);
+}
+
+void init_registers(int pid)
+{
+ int err;
+
+ err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
+ if (err)
+ panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
+ errno);
+
+ arch_init_registers(pid);
+}
+
+void get_safe_registers(unsigned long *regs)
+{
+ memcpy(regs, exec_regs, sizeof(exec_regs));
+}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b98f7ea2d2f..e9800b0b568 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -1,26 +1,21 @@
/*
* Copyright (C) 2004 PathScale, Inc
+ * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
#include <stdlib.h>
-#include <errno.h>
#include <stdarg.h>
-#include <string.h>
-#include <sys/mman.h>
-#include "user.h"
-#include "signal_kern.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/barrier.h"
-#include "sigcontext.h"
-#include "mode.h"
+#include <errno.h>
+#include <signal.h>
+#include <strings.h>
#include "os.h"
+#include "sysdep/barrier.h"
+#include "sysdep/sigcontext.h"
+#include "user.h"
-/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
- * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
+/*
+ * These are the asynchronous signals. SIGPROF is excluded because we want to
* be able to profile all of UML, not just the non-critical sections. If
* profiling is not thread-safe, then that is not my problem. We can disable
* profiling when SMP is enabled in that case.
@@ -31,10 +26,8 @@
#define SIGVTALRM_BIT 1
#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
-#define SIGALRM_BIT 2
-#define SIGALRM_MASK (1 << SIGALRM_BIT)
-
-/* These are used by both the signal handlers and
+/*
+ * These are used by both the signal handlers and
* block/unblock_signals. I don't want modifications cached in a
* register - they must go straight to memory.
*/
@@ -46,34 +39,27 @@ void sig_handler(int sig, struct sigcontext *sc)
int enabled;
enabled = signals_enabled;
- if(!enabled && (sig == SIGIO)){
+ if (!enabled && (sig == SIGIO)) {
pending |= SIGIO_MASK;
return;
}
block_signals();
- CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
- sig, sc);
+ sig_handler_common_skas(sig, sc);
set_signals(enabled);
}
-static void real_alarm_handler(int sig, struct sigcontext *sc)
+static void real_alarm_handler(struct sigcontext *sc)
{
- union uml_pt_regs regs;
+ struct uml_pt_regs regs;
- if(sig == SIGALRM)
- switch_timers(0);
-
- if(sc != NULL)
+ if (sc != NULL)
copy_sc(&regs, sc);
- regs.skas.is_user = 0;
+ regs.is_user = 0;
unblock_signals();
- timer_handler(sig, &regs);
-
- if(sig == SIGALRM)
- switch_timers(1);
+ timer_handler(SIGVTALRM, &regs);
}
void alarm_handler(int sig, struct sigcontext *sc)
@@ -81,27 +67,30 @@ void alarm_handler(int sig, struct sigcontext *sc)
int enabled;
enabled = signals_enabled;
- if(!signals_enabled){
- if(sig == SIGVTALRM)
- pending |= SIGVTALRM_MASK;
- else pending |= SIGALRM_MASK;
-
+ if (!signals_enabled) {
+ pending |= SIGVTALRM_MASK;
return;
}
block_signals();
- real_alarm_handler(sig, sc);
+ real_alarm_handler(sc);
set_signals(enabled);
}
+void timer_init(void)
+{
+ set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
+ SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1);
+}
+
void set_sigstack(void *sig_stack, int size)
{
stack_t stack = ((stack_t) { .ss_flags = 0,
.ss_sp = (__ptr_t) sig_stack,
.ss_size = size - sizeof(void *) });
- if(sigaltstack(&stack, NULL) != 0)
+ if (sigaltstack(&stack, NULL) != 0)
panic("enabling signal stack failed, errno = %d\n", errno);
}
@@ -111,7 +100,7 @@ void remove_sigstack(void)
.ss_sp = NULL,
.ss_size = 0 });
- if(sigaltstack(&stack, NULL) != 0)
+ if (sigaltstack(&stack, NULL) != 0)
panic("disabling signal stack failed, errno = %d\n", errno);
}
@@ -135,26 +124,27 @@ void handle_signal(int sig, struct sigcontext *sc)
* with this interrupt.
*/
bail = to_irq_stack(&pending);
- if(bail)
+ if (bail)
return;
nested = pending & 1;
pending &= ~1;
- while((sig = ffs(pending)) != 0){
+ while ((sig = ffs(pending)) != 0){
sig--;
pending &= ~(1 << sig);
(*handlers[sig])(sig, sc);
}
- /* Again, pending comes back with a mask of signals
+ /*
+ * Again, pending comes back with a mask of signals
* that arrived while tearing down the stack. If this
* is non-zero, we just go back, set up the stack
* again, and handle the new interrupts.
*/
- if(!nested)
+ if (!nested)
pending = from_irq_stack(nested);
- } while(pending);
+ } while (pending);
}
extern void hard_handler(int sig);
@@ -172,18 +162,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
sigemptyset(&action.sa_mask);
va_start(ap, flags);
- while((mask = va_arg(ap, int)) != -1)
+ while ((mask = va_arg(ap, int)) != -1)
sigaddset(&action.sa_mask, mask);
va_end(ap);
action.sa_flags = flags;
action.sa_restorer = NULL;
- if(sigaction(sig, &action, NULL) < 0)
+ if (sigaction(sig, &action, NULL) < 0)
panic("sigaction failed - errno = %d\n", errno);
sigemptyset(&sig_mask);
sigaddset(&sig_mask, sig);
- if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
+ if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
panic("sigprocmask failed - errno = %d\n", errno);
}
@@ -194,13 +184,14 @@ int change_sig(int signal, int on)
sigemptyset(&sigset);
sigaddset(&sigset, signal);
sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
- return(!sigismember(&old, signal));
+ return !sigismember(&old, signal);
}
void block_signals(void)
{
signals_enabled = 0;
- /* This must return with signals disabled, so this barrier
+ /*
+ * This must return with signals disabled, so this barrier
* ensures that writes are flushed out before the return.
* This might matter if gcc figures out how to inline this and
* decides to shuffle this code into the caller.
@@ -212,27 +203,31 @@ void unblock_signals(void)
{
int save_pending;
- if(signals_enabled == 1)
+ if (signals_enabled == 1)
return;
- /* We loop because the IRQ handler returns with interrupts off. So,
+ /*
+ * We loop because the IRQ handler returns with interrupts off. So,
* interrupts may have arrived and we need to re-enable them and
* recheck pending.
*/
- while(1){
- /* Save and reset save_pending after enabling signals. This
+ while(1) {
+ /*
+ * Save and reset save_pending after enabling signals. This
* way, pending won't be changed while we're reading it.
*/
signals_enabled = 1;
- /* Setting signals_enabled and reading pending must
+ /*
+ * Setting signals_enabled and reading pending must
* happen in this order.
*/
mb();
save_pending = pending;
- if(save_pending == 0){
- /* This must return with signals enabled, so
+ if (save_pending == 0) {
+ /*
+ * This must return with signals enabled, so
* this barrier ensures that writes are
* flushed out before the return. This might
* matter if gcc figures out how to inline
@@ -245,26 +240,24 @@ void unblock_signals(void)
pending = 0;
- /* We have pending interrupts, so disable signals, as the
+ /*
+ * We have pending interrupts, so disable signals, as the
* handlers expect them off when they are called. They will
* be enabled again above.
*/
signals_enabled = 0;
- /* Deal with SIGIO first because the alarm handler might
+ /*
+ * Deal with SIGIO first because the alarm handler might
* schedule, leaving the pending SIGIO stranded until we come
* back here.
*/
- if(save_pending & SIGIO_MASK)
- CHOOSE_MODE_PROC(sig_handler_common_tt,
- sig_handler_common_skas, SIGIO, NULL);
-
- if(save_pending & SIGALRM_MASK)
- real_alarm_handler(SIGALRM, NULL);
+ if (save_pending & SIGIO_MASK)
+ sig_handler_common_skas(SIGIO, NULL);
- if(save_pending & SIGVTALRM_MASK)
- real_alarm_handler(SIGVTALRM, NULL);
+ if (save_pending & SIGVTALRM_MASK)
+ real_alarm_handler(NULL);
}
}
@@ -276,11 +269,11 @@ int get_signals(void)
int set_signals(int enable)
{
int ret;
- if(signals_enabled == enable)
+ if (signals_enabled == enable)
return enable;
ret = signals_enabled;
- if(enable)
+ if (enable)
unblock_signals();
else block_signals();
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 0f7df4eb903..484e68f9f7a 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -1,31 +1,26 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <signal.h>
+#include <stddef.h>
+#include <unistd.h>
#include <errno.h>
#include <string.h>
-#include <unistd.h>
#include <sys/mman.h>
-#include <sys/wait.h>
-#include <asm/page.h>
-#include <asm/unistd.h>
-#include "mem_user.h"
-#include "mem.h"
-#include "skas.h"
-#include "user.h"
+#include "init.h"
+#include "kern_constants.h"
+#include "as-layout.h"
+#include "mm_id.h"
#include "os.h"
#include "proc_mm.h"
#include "ptrace_user.h"
-#include "kern_util.h"
-#include "task.h"
#include "registers.h"
-#include "uml-config.h"
+#include "skas.h"
+#include "user.h"
#include "sysdep/ptrace.h"
#include "sysdep/stub.h"
-#include "init.h"
-#include "kern_constants.h"
+#include "uml-config.h"
extern unsigned long batch_syscall_stub, __syscall_stub_start;
@@ -34,7 +29,7 @@ extern void wait_stub_done(int pid);
static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
unsigned long *stack)
{
- if(stack == NULL) {
+ if (stack == NULL) {
stack = (unsigned long *) mm_idp->stack + 2;
*stack = 0;
}
@@ -45,8 +40,8 @@ static unsigned long syscall_regs[MAX_REG_NR];
static int __init init_syscall_regs(void)
{
- get_safe_registers(syscall_regs, NULL);
- syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ get_safe_registers(syscall_regs);
+ syscall_regs[REGS_IP_INDEX] = STUB_CODE +
((unsigned long) &batch_syscall_stub -
(unsigned long) &__syscall_stub_start);
return 0;
@@ -68,29 +63,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
unsigned long * syscall;
int err, pid = mm_idp->u.pid;
- if(proc_mm)
+ if (proc_mm)
/* FIXME: Need to look up userspace_pid by cpu */
pid = userspace_pid[0];
multi_count++;
n = ptrace_setregs(pid, syscall_regs);
- if(n < 0){
- printk("Registers - \n");
- for(i = 0; i < MAX_REG_NR; i++)
- printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
+ if (n < 0) {
+ printk(UM_KERN_ERR "Registers - \n");
+ for (i = 0; i < MAX_REG_NR; i++)
+ printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-n);
}
err = ptrace(PTRACE_CONT, pid, 0, 0);
- if(err)
+ if (err)
panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
errno);
wait_stub_done(pid);
- /* When the stub stops, we find the following values on the
+ /*
+ * When the stub stops, we find the following values on the
* beginning of the stack:
* (long )return_value
* (long )offset to failed sycall-data (0, if no error)
@@ -98,26 +94,26 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
ret = *((unsigned long *) mm_idp->stack);
offset = *((unsigned long *) mm_idp->stack + 1);
if (offset) {
- data = (unsigned long *)(mm_idp->stack +
- offset - UML_CONFIG_STUB_DATA);
- printk("do_syscall_stub : ret = %ld, offset = %ld, "
+ data = (unsigned long *)(mm_idp->stack + offset - STUB_DATA);
+ printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, "
"data = %p\n", ret, offset, data);
syscall = (unsigned long *)((unsigned long)data + data[0]);
- printk("do_syscall_stub: syscall %ld failed, return value = "
- "0x%lx, expected return value = 0x%lx\n",
+ printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, "
+ "return value = 0x%lx, expected return value = 0x%lx\n",
syscall[0], ret, syscall[7]);
- printk(" syscall parameters: "
+ printk(UM_KERN_ERR " syscall parameters: "
"0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
syscall[1], syscall[2], syscall[3],
syscall[4], syscall[5], syscall[6]);
- for(n = 1; n < data[0]/sizeof(long); n++) {
- if(n == 1)
- printk(" additional syscall data:");
- if(n % 4 == 1)
- printk("\n ");
+ for (n = 1; n < data[0]/sizeof(long); n++) {
+ if (n == 1)
+ printk(UM_KERN_ERR " additional syscall "
+ "data:");
+ if (n % 4 == 1)
+ printk("\n" UM_KERN_ERR " ");
printk(" 0x%lx", data[n]);
}
- if(n > 1)
+ if (n > 1)
printk("\n");
}
else ret = 0;
@@ -133,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
{
unsigned long *stack = check_init_stack(mm_idp, *addr);
- if(done && *addr == NULL)
+ if (done && *addr == NULL)
single_count++;
*stack += sizeof(long);
@@ -150,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
*stack = 0;
multi_op_count++;
- if(!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
- UM_KERN_PAGE_SIZE - 10 * sizeof(long))){
+ if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
+ UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {
*addr = stack;
return 0;
}
@@ -166,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp,
unsigned long *stack;
int ret = 0;
- /* If *addr still is uninitialized, it *must* contain NULL.
+ /*
+ * If *addr still is uninitialized, it *must* contain NULL.
* Thus in this case do_syscall_stub correctly won't be called.
*/
- if((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
+ if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {
ret = do_syscall_stub(mm_idp, addr);
/* in case of error, don't overwrite data on stack */
- if(ret)
+ if (ret)
return ret;
}
@@ -185,7 +182,7 @@ long syscall_stub_data(struct mm_id * mm_idp,
memcpy(stack + 1, data, data_count * sizeof(long));
*stub_addr = (void *)(((unsigned long)(stack + 1) &
- ~UM_KERN_PAGE_MASK) + UML_CONFIG_STUB_DATA);
+ ~UM_KERN_PAGE_MASK) + STUB_DATA);
return 0;
}
@@ -195,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
{
int ret;
- if(proc_mm){
+ if (proc_mm) {
struct proc_mm_op map;
int fd = mm_idp->u.mm_fd;
@@ -211,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
.offset= offset
} } } );
CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
- if(ret != sizeof(map)){
+ if (ret != sizeof(map)) {
ret = -errno;
- printk("map : /proc/mm map failed, err = %d\n", -ret);
+ printk(UM_KERN_ERR "map : /proc/mm map failed, "
+ "err = %d\n", -ret);
}
else ret = 0;
}
@@ -234,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
{
int ret;
- if(proc_mm){
+ if (proc_mm) {
struct proc_mm_op unmap;
int fd = mm_idp->u.mm_fd;
@@ -245,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
(unsigned long) addr,
.len = len } } } );
CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
- if(ret != sizeof(unmap)){
+ if (ret != sizeof(unmap)) {
ret = -errno;
- printk("unmap - proc_mm write returned %d\n", ret);
+ printk(UM_KERN_ERR "unmap - proc_mm write returned "
+ "%d\n", ret);
}
else ret = 0;
}
@@ -268,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
struct proc_mm_op protect;
int ret;
- if(proc_mm){
+ if (proc_mm) {
int fd = mm_idp->u.mm_fd;
protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
@@ -280,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
.prot = prot } } } );
CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
- if(ret != sizeof(protect)){
+ if (ret != sizeof(protect)) {
ret = -errno;
- printk("protect failed, err = %d", -ret);
+ printk(UM_KERN_ERR "protect failed, err = %d", -ret);
}
else ret = 0;
}
@@ -295,7 +294,3 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
return ret;
}
-
-void before_mem_skas(unsigned long unused)
-{
-}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index ba9af8d6205..d77c81d7068 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -1,48 +1,38 @@
/*
- * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
#include <sched.h>
-#include "ptrace_user.h"
-#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
#include <sys/mman.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <sys/syscall.h>
-#include <asm/types.h>
-#include "user.h"
-#include "sysdep/ptrace.h"
-#include "kern_util.h"
-#include "skas.h"
-#include "stub-data.h"
-#include "mm_id.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/stub.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "skas_ptrace.h"
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <asm/unistd.h>
+#include "as-layout.h"
#include "chan_user.h"
-#include "registers.h"
+#include "kern_constants.h"
#include "mem.h"
-#include "uml-config.h"
+#include "os.h"
#include "process.h"
-#include "longjmp.h"
-#include "kern_constants.h"
-#include "as-layout.h"
+#include "proc_mm.h"
+#include "ptrace_user.h"
+#include "registers.h"
+#include "skas.h"
+#include "skas_ptrace.h"
+#include "user.h"
+#include "sysdep/stub.h"
int is_skas_winch(int pid, int fd, void *data)
{
- if(pid != os_getpgrp())
- return(0);
+ if (pid != getpgrp())
+ return 0;
register_winch_irq(-1, fd, -1, data, 0);
- return(1);
+ return 1;
}
static int ptrace_dump_regs(int pid)
@@ -50,13 +40,12 @@ static int ptrace_dump_regs(int pid)
unsigned long regs[MAX_REG_NR];
int i;
- if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
return -errno;
- else {
- printk("Stub registers -\n");
- for(i = 0; i < ARRAY_SIZE(regs); i++)
- printk("\t%d - %lx\n", i, regs[i]);
- }
+
+ printk(UM_KERN_ERR "Stub registers -\n");
+ for (i = 0; i < ARRAY_SIZE(regs); i++)
+ printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
return 0;
}
@@ -74,27 +63,28 @@ void wait_stub_done(int pid)
{
int n, status, err;
- while(1){
+ while (1) {
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- if((n < 0) || !WIFSTOPPED(status))
+ if ((n < 0) || !WIFSTOPPED(status))
goto bad_wait;
- if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
+ if (((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
break;
err = ptrace(PTRACE_CONT, pid, 0, 0);
- if(err)
+ if (err)
panic("wait_stub_done : continue failed, errno = %d\n",
errno);
}
- if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
+ if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
return;
bad_wait:
err = ptrace_dump_regs(pid);
- if(err)
- printk("Failed to get registers from stub, errno = %d\n", -err);
+ if (err)
+ printk(UM_KERN_ERR "Failed to get registers from stub, "
+ "errno = %d\n", -err);
panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
"n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
}
@@ -105,9 +95,9 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
{
int err;
- if(ptrace_faultinfo){
+ if (ptrace_faultinfo) {
err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
- if(err)
+ if (err)
panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
"errno = %d\n", errno);
@@ -119,52 +109,57 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
}
else {
err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
- if(err)
+ if (err)
panic("Failed to continue stub, pid = %d, errno = %d\n",
pid, errno);
wait_stub_done(pid);
- /* faultinfo is prepared by the stub-segv-handler at start of
+ /*
+ * faultinfo is prepared by the stub-segv-handler at start of
* the stub stack page. We just have to copy it.
*/
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
}
}
-static void handle_segv(int pid, union uml_pt_regs * regs)
+static void handle_segv(int pid, struct uml_pt_regs * regs)
{
- get_skas_faultinfo(pid, &regs->skas.faultinfo);
- segv(regs->skas.faultinfo, 0, 1, NULL);
+ get_skas_faultinfo(pid, &regs->faultinfo);
+ segv(regs->faultinfo, 0, 1, NULL);
}
-/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
-static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
+/*
+ * To use the same value of using_sysemu as the caller, ask it that value
+ * (in local_using_sysemu
+ */
+static void handle_trap(int pid, struct uml_pt_regs *regs,
+ int local_using_sysemu)
{
int err, status;
/* Mark this as a syscall */
- UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
+ UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
if (!local_using_sysemu)
{
err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
__NR_getpid);
- if(err < 0)
- panic("handle_trap - nullifying syscall failed errno = %d\n",
- errno);
+ if (err < 0)
+ panic("handle_trap - nullifying syscall failed, "
+ "errno = %d\n", errno);
err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
- if(err < 0)
- panic("handle_trap - continuing to end of syscall failed, "
- "errno = %d\n", errno);
+ if (err < 0)
+ panic("handle_trap - continuing to end of syscall "
+ "failed, errno = %d\n", errno);
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
- if((err < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGTRAP + 0x80)){
+ if ((err < 0) || !WIFSTOPPED(status) ||
+ (WSTOPSIG(status) != SIGTRAP + 0x80)) {
err = ptrace_dump_regs(pid);
- if(err)
- printk("Failed to get registers from process, "
- "errno = %d\n", -err);
+ if (err)
+ printk(UM_KERN_ERR "Failed to get registers "
+ "from process, errno = %d\n", -err);
panic("handle_trap - failed to wait at end of syscall, "
"errno = %d, status = %d\n", errno, status);
}
@@ -182,63 +177,64 @@ static int userspace_tramp(void *stack)
ptrace(PTRACE_TRACEME, 0, 0, 0);
- init_new_thread_signals();
- err = set_interval(1);
- if(err)
+ signal(SIGTERM, SIG_DFL);
+ err = set_interval();
+ if (err)
panic("userspace_tramp - setting timer failed, errno = %d\n",
err);
- if(!proc_mm){
- /* This has a pte, but it can't be mapped in with the usual
+ if (!proc_mm) {
+ /*
+ * This has a pte, but it can't be mapped in with the usual
* tlb_flush mechanism because this is part of that mechanism
*/
int fd;
- __u64 offset;
+ unsigned long long offset;
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
- addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
+ addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
- if(addr == MAP_FAILED){
- printk("mapping mmap stub failed, errno = %d\n",
- errno);
+ if (addr == MAP_FAILED) {
+ printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
+ "errno = %d\n", STUB_CODE, errno);
exit(1);
}
- if(stack != NULL){
+ if (stack != NULL) {
fd = phys_mapping(to_phys(stack), &offset);
- addr = mmap((void *) UML_CONFIG_STUB_DATA,
+ addr = mmap((void *) STUB_DATA,
UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, offset);
- if(addr == MAP_FAILED){
- printk("mapping segfault stack failed, "
- "errno = %d\n", errno);
+ if (addr == MAP_FAILED) {
+ printk(UM_KERN_ERR "mapping segfault stack "
+ "at 0x%lx failed, errno = %d\n",
+ STUB_DATA, errno);
exit(1);
}
}
}
- if(!ptrace_faultinfo && (stack != NULL)){
+ if (!ptrace_faultinfo && (stack != NULL)) {
struct sigaction sa;
- unsigned long v = UML_CONFIG_STUB_CODE +
+ unsigned long v = STUB_CODE +
(unsigned long) stub_segv_handler -
(unsigned long) &__syscall_stub_start;
- set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE);
+ set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
sigaddset(&sa.sa_mask, SIGWINCH);
- sigaddset(&sa.sa_mask, SIGALRM);
sigaddset(&sa.sa_mask, SIGVTALRM);
sigaddset(&sa.sa_mask, SIGUSR1);
sa.sa_flags = SA_ONSTACK;
sa.sa_handler = (void *) v;
sa.sa_restorer = NULL;
- if(sigaction(SIGSEGV, &sa, NULL) < 0)
+ if (sigaction(SIGSEGV, &sa, NULL) < 0)
panic("userspace_tramp - setting SIGSEGV handler "
"failed - errno = %d\n", errno);
}
- os_stop_process(os_getpid());
- return(0);
+ kill(os_getpid(), SIGSTOP);
+ return 0;
}
/* Each element set once, and only accessed by a single processor anyway */
@@ -255,44 +251,55 @@ int start_userspace(unsigned long stub_stack)
stack = mmap(NULL, UM_KERN_PAGE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if(stack == MAP_FAILED)
+ if (stack == MAP_FAILED)
panic("start_userspace : mmap failed, errno = %d", errno);
sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
flags = CLONE_FILES | SIGCHLD;
- if(proc_mm) flags |= CLONE_VM;
+ if (proc_mm)
+ flags |= CLONE_VM;
+
pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
- if(pid < 0)
+ if (pid < 0)
panic("start_userspace : clone failed, errno = %d", errno);
do {
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- if(n < 0)
+ if (n < 0)
panic("start_userspace : wait failed, errno = %d",
errno);
- } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
+ } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
- if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
+ if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
panic("start_userspace : expected SIGSTOP, got status = %d",
status);
- if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
- panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n",
- errno);
+ if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
+ (void *) PTRACE_O_TRACESYSGOOD) < 0)
+ panic("start_userspace : PTRACE_OLDSETOPTIONS failed, "
+ "errno = %d\n", errno);
- if(munmap(stack, UM_KERN_PAGE_SIZE) < 0)
+ if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
panic("start_userspace : munmap failed, errno = %d\n", errno);
- return(pid);
+ return pid;
}
-void userspace(union uml_pt_regs *regs)
+void userspace(struct uml_pt_regs *regs)
{
+ struct itimerval timer;
+ unsigned long long nsecs, now;
int err, status, op, pid = userspace_pid[0];
/* To prevent races if using_sysemu changes under us.*/
int local_using_sysemu;
- while(1){
+ if (getitimer(ITIMER_VIRTUAL, &timer))
+ printk("Failed to get itimer, errno = %d\n", errno);
+ nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC +
+ timer.it_value.tv_usec * UM_NSEC_PER_USEC;
+ nsecs += os_nsecs();
+
+ while (1) {
restore_registers(pid, regs);
/* Now we set local_using_sysemu to be used for one loop */
@@ -302,26 +309,28 @@ void userspace(union uml_pt_regs *regs)
singlestepping(NULL));
err = ptrace(op, pid, 0, 0);
- if(err)
+ if (err)
panic("userspace - could not resume userspace process, "
"pid=%d, ptrace operation = %d, errno = %d\n",
pid, op, errno);
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
- if(err < 0)
+ if (err < 0)
panic("userspace - waitpid failed, errno = %d\n",
errno);
- regs->skas.is_user = 1;
+ regs->is_user = 1;
save_registers(pid, regs);
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
- if(WIFSTOPPED(status)){
+ if (WIFSTOPPED(status)) {
int sig = WSTOPSIG(status);
- switch(sig){
+ switch(sig) {
case SIGSEGV:
- if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
- get_skas_faultinfo(pid, &regs->skas.faultinfo);
+ if (PTRACE_FULL_FAULTINFO ||
+ !ptrace_faultinfo) {
+ get_skas_faultinfo(pid,
+ &regs->faultinfo);
(*sig_info[SIGSEGV])(SIGSEGV, regs);
}
else handle_segv(pid, regs);
@@ -332,8 +341,20 @@ void userspace(union uml_pt_regs *regs)
case SIGTRAP:
relay_signal(SIGTRAP, regs);
break;
- case SIGIO:
case SIGVTALRM:
+ now = os_nsecs();
+ if(now < nsecs)
+ break;
+ block_signals();
+ (*sig_info[sig])(sig, regs);
+ unblock_signals();
+ nsecs = timer.it_value.tv_sec *
+ UM_NSEC_PER_SEC +
+ timer.it_value.tv_usec *
+ UM_NSEC_PER_USEC;
+ nsecs += os_nsecs();
+ break;
+ case SIGIO:
case SIGILL:
case SIGBUS:
case SIGFPE:
@@ -343,30 +364,29 @@ void userspace(union uml_pt_regs *regs)
unblock_signals();
break;
default:
- printk("userspace - child stopped with signal "
- "%d\n", sig);
+ printk(UM_KERN_ERR "userspace - child stopped "
+ "with signal %d\n", sig);
}
pid = userspace_pid[0];
interrupt_end();
/* Avoid -ERESTARTSYS handling in host */
- if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
- PT_SYSCALL_NR(regs->skas.regs) = -1;
+ if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
+ PT_SYSCALL_NR(regs->gp) = -1;
}
}
}
static unsigned long thread_regs[MAX_REG_NR];
-static unsigned long thread_fp_regs[HOST_FP_SIZE];
static int __init init_thread_regs(void)
{
- get_safe_registers(thread_regs, thread_fp_regs);
+ get_safe_registers(thread_regs);
/* Set parent's instruction pointer to start of clone-stub */
- thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ thread_regs[REGS_IP_INDEX] = STUB_CODE +
(unsigned long) stub_clone_handler -
(unsigned long) &__syscall_stub_start;
- thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE -
+ thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
sizeof(void *);
#ifdef __SIGNAL_FRAMESIZE
thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
@@ -378,53 +398,53 @@ __initcall(init_thread_regs);
int copy_context_skas0(unsigned long new_stack, int pid)
{
+ struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ };
int err;
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
- __u64 new_offset;
+ unsigned long long new_offset;
int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
- /* prepare offset and fd of child's stack as argument for parent's
+ /*
+ * prepare offset and fd of child's stack as argument for parent's
* and child's mmap2 calls
*/
*data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
.fd = new_fd,
.timer = ((struct itimerval)
- { { 0, 1000000 / hz() },
- { 0, 1000000 / hz() }})});
+ { .it_value = tv,
+ .it_interval = tv }) });
+
err = ptrace_setregs(pid, thread_regs);
- if(err < 0)
+ if (err < 0)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
- err = ptrace_setfpregs(pid, thread_fp_regs);
- if(err < 0)
- panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
- "pid = %d, errno = %d\n", pid, -err);
-
/* set a well known return code for detection of child write failure */
child_data->err = 12345678;
- /* Wait, until parent has finished its work: read child's pid from
+ /*
+ * Wait, until parent has finished its work: read child's pid from
* parent's stack, and check, if bad result.
*/
err = ptrace(PTRACE_CONT, pid, 0, 0);
- if(err)
+ if (err)
panic("Failed to continue new process, pid = %d, "
"errno = %d\n", pid, errno);
wait_stub_done(pid);
pid = data->err;
- if(pid < 0)
+ if (pid < 0)
panic("copy_context_skas0 - stub-parent reports error %d\n",
-pid);
- /* Wait, until child has finished too: read child's result from
+ /*
+ * Wait, until child has finished too: read child's result from
* child's stack and check it.
*/
wait_stub_done(pid);
- if (child_data->err != UML_CONFIG_STUB_DATA)
+ if (child_data->err != STUB_DATA)
panic("copy_context_skas0 - stub-child reports error %ld\n",
child_data->err);
@@ -446,7 +466,7 @@ void map_stub_pages(int fd, unsigned long code,
{
struct proc_mm_op mmop;
int n;
- __u64 code_offset;
+ unsigned long long code_offset;
int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),
&code_offset);
@@ -461,16 +481,17 @@ void map_stub_pages(int fd, unsigned long code,
.offset = code_offset
} } });
CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
- if(n != sizeof(mmop)){
+ if (n != sizeof(mmop)) {
n = errno;
- printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
- code, code_fd, (unsigned long long) code_offset);
+ printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
+ "offset = %llx\n", code, code_fd,
+ (unsigned long long) code_offset);
panic("map_stub_pages : /proc/mm map for code failed, "
"err = %d\n", n);
}
- if ( stack ) {
- __u64 map_offset;
+ if (stack) {
+ unsigned long long map_offset;
int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
mmop = ((struct proc_mm_op)
{ .op = MM_MMAP,
@@ -484,7 +505,7 @@ void map_stub_pages(int fd, unsigned long code,
.offset = map_offset
} } });
CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
- if(n != sizeof(mmop))
+ if (n != sizeof(mmop))
panic("map_stub_pages : /proc/mm map for data failed, "
"err = %d\n", errno);
}
@@ -504,7 +525,7 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
void switch_threads(jmp_buf *me, jmp_buf *you)
{
- if(UML_SETJMP(me) == 0)
+ if (UML_SETJMP(me) == 0)
UML_LONGJMP(you, 1);
}
@@ -520,8 +541,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
int n;
set_handler(SIGWINCH, (__sighandler_t) sig_handler,
- SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
- SIGVTALRM, -1);
+ SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1);
/*
* Can't use UML_SETJMP or UML_LONGJMP here because they save
@@ -532,7 +552,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
* after returning to the jumper.
*/
n = setjmp(initial_jmpbuf);
- switch(n){
+ switch(n) {
case INIT_JMP_NEW_THREAD:
(*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
(*switch_buf)[0].JB_SP = (unsigned long) stack +
@@ -544,10 +564,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
break;
case INIT_JMP_HALT:
kmalloc_ok = 0;
- return(0);
+ return 0;
case INIT_JMP_REBOOT:
kmalloc_ok = 0;
- return(1);
+ return 1;
default:
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
}
@@ -563,7 +583,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
cb_back = &here;
block_signals();
- if(UML_SETJMP(&here) == 0)
+ if (UML_SETJMP(&here) == 0)
UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
unblock_signals();
@@ -584,16 +604,16 @@ void reboot_skas(void)
UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
}
-void switch_mm_skas(struct mm_id *mm_idp)
+void __switch_mm(struct mm_id *mm_idp)
{
int err;
- /* FIXME: need cpu pid in switch_mm_skas */
- if(proc_mm){
+ /* FIXME: need cpu pid in __switch_mm */
+ if (proc_mm) {
err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
mm_idp->u.mm_fd);
- if(err)
- panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
+ if (err)
+ panic("__switch_mm - PTRACE_SWITCH_MM failed, "
"errno = %d\n", errno);
}
else userspace_pid[0] = mm_idp->u.pid;
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index 3b600c2e63b..3b1b9244f46 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -1,37 +1,43 @@
/*
- * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <signal.h>
-#include <errno.h>
+#if 0
#include "kern_util.h"
-#include "as-layout.h"
-#include "task.h"
-#include "sigcontext.h"
#include "skas.h"
#include "ptrace_user.h"
-#include "sysdep/ptrace.h"
#include "sysdep/ptrace_user.h"
+#endif
+
+#include <errno.h>
+#include <signal.h>
+#include "sysdep/ptrace.h"
+#include "kern_constants.h"
+#include "as-layout.h"
#include "os.h"
+#include "sigcontext.h"
+#include "task.h"
-static union uml_pt_regs ksig_regs[UM_NR_CPUS];
+static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
void sig_handler_common_skas(int sig, void *sc_ptr)
{
struct sigcontext *sc = sc_ptr;
- union uml_pt_regs *r;
- void (*handler)(int, union uml_pt_regs *);
+ struct uml_pt_regs *r;
+ void (*handler)(int, struct uml_pt_regs *);
int save_user, save_errno = errno;
- /* This is done because to allow SIGSEGV to be delivered inside a SEGV
+ /*
+ * This is done because to allow SIGSEGV to be delivered inside a SEGV
* handler. This can happen in copy_user, and if SEGV is disabled,
* the process will die.
* XXX Figure out why this is better than SA_NODEFER
*/
- if(sig == SIGSEGV) {
+ if (sig == SIGSEGV) {
change_sig(SIGSEGV, 1);
- /* For segfaults, we want the data from the
+ /*
+ * For segfaults, we want the data from the
* sigcontext. In this case, we don't want to mangle
* the process registers, so use a static set of
* registers. For other signals, the process
@@ -42,25 +48,22 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
}
else r = TASK_REGS(get_current());
- save_user = r->skas.is_user;
- r->skas.is_user = 0;
- if ( sig == SIGFPE || sig == SIGSEGV ||
- sig == SIGBUS || sig == SIGILL ||
- sig == SIGTRAP ) {
- GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc);
- }
+ save_user = r->is_user;
+ r->is_user = 0;
+ if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
+ (sig == SIGILL) || (sig == SIGTRAP))
+ GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
change_sig(SIGUSR1, 1);
handler = sig_info[sig];
- /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
- if (sig != SIGIO && sig != SIGWINCH &&
- sig != SIGVTALRM && sig != SIGALRM)
+ /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */
+ if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
unblock_signals();
handler(sig, r);
errno = save_errno;
- r->skas.is_user = save_user;
+ r->is_user = save_user;
}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 46f613975c1..7b81f6c08a5 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -1,75 +1,65 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <pty.h>
#include <stdio.h>
-#include <stddef.h>
-#include <stdarg.h>
#include <stdlib.h>
-#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
-#include <signal.h>
-#include <sched.h>
-#include <fcntl.h>
#include <errno.h>
-#include <sys/time.h>
-#include <sys/wait.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <signal.h>
+#include <string.h>
#include <sys/mman.h>
-#include <sys/resource.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
#include <asm/unistd.h>
-#include <asm/page.h>
-#include <sys/types.h>
-#include "kern_util.h"
-#include "user.h"
-#include "signal_kern.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
-#include "irq_user.h"
-#include "ptrace_user.h"
-#include "mem_user.h"
#include "init.h"
-#include "os.h"
-#include "uml-config.h"
-#include "choose-mode.h"
-#include "mode.h"
-#include "tempfile.h"
#include "kern_constants.h"
-
-#ifdef UML_CONFIG_MODE_SKAS
-#include "skas.h"
-#include "skas_ptrace.h"
+#include "os.h"
+#include "mem_user.h"
+#include "ptrace_user.h"
#include "registers.h"
-#endif
+#include "skas_ptrace.h"
-static int ptrace_child(void *arg)
+static int ptrace_child(void)
{
int ret;
+ /* Calling os_getpid because some libcs cached getpid incorrectly */
int pid = os_getpid(), ppid = getppid();
int sc_result;
change_sig(SIGWINCH, 0);
- if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
+ if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
perror("ptrace");
- os_kill_process(pid, 0);
+ kill(pid, SIGKILL);
}
kill(pid, SIGSTOP);
- /*This syscall will be intercepted by the parent. Don't call more than
- * once, please.*/
+ /*
+ * This syscall will be intercepted by the parent. Don't call more than
+ * once, please.
+ */
sc_result = os_getpid();
if (sc_result == pid)
- ret = 1; /*Nothing modified by the parent, we are running
- normally.*/
+ /* Nothing modified by the parent, we are running normally. */
+ ret = 1;
else if (sc_result == ppid)
- ret = 0; /*Expected in check_ptrace and check_sysemu when they
- succeed in modifying the stack frame*/
+ /*
+ * Expected in check_ptrace and check_sysemu when they succeed
+ * in modifying the stack frame
+ */
+ ret = 0;
else
- ret = 2; /*Serious trouble! This could be caused by a bug in
- host 2.6 SKAS3/2.6 patch before release -V6, together
- with a bug in the UML code itself.*/
+ /* Serious trouble! This could be caused by a bug in host 2.6
+ * SKAS3/2.6 patch before release -V6, together with a bug in
+ * the UML code itself.
+ */
+ ret = 2;
_exit(ret);
}
@@ -101,29 +91,23 @@ static void non_fatal(char *fmt, ...)
fflush(stdout);
}
-static int start_ptraced_child(void **stack_out)
+static int start_ptraced_child(void)
{
- void *stack;
- unsigned long sp;
int pid, n, status;
- stack = mmap(NULL, UM_KERN_PAGE_SIZE,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if(stack == MAP_FAILED)
- fatal_perror("check_ptrace : mmap failed");
- sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
- pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
- if(pid < 0)
- fatal_perror("start_ptraced_child : clone failed");
+ pid = fork();
+ if (pid == 0)
+ ptrace_child();
+ else if (pid < 0)
+ fatal_perror("start_ptraced_child : fork failed");
+
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- if(n < 0)
- fatal_perror("check_ptrace : clone failed");
- if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
+ if (n < 0)
+ fatal_perror("check_ptrace : waitpid failed");
+ if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
fatal("check_ptrace : expected SIGSTOP, got status = %d",
status);
- *stack_out = stack;
return pid;
}
@@ -133,15 +117,14 @@ static int start_ptraced_child(void **stack_out)
* So only for SYSEMU features we test mustpanic, while normal host features
* must work anyway!
*/
-static int stop_ptraced_child(int pid, void *stack, int exitcode,
- int mustexit)
+static int stop_ptraced_child(int pid, int exitcode, int mustexit)
{
int status, n, ret = 0;
- if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
+ if (ptrace(PTRACE_CONT, pid, 0, 0) < 0)
fatal_perror("stop_ptraced_child : ptrace failed");
CATCH_EINTR(n = waitpid(pid, &status, 0));
- if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
+ if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
int exit_with = WEXITSTATUS(status);
if (exit_with == 2)
non_fatal("check_ptrace : child exited with status 2. "
@@ -154,8 +137,6 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
ret = -1;
}
- if(munmap(stack, UM_KERN_PAGE_SIZE) < 0)
- fatal_perror("check_ptrace : munmap failed");
return ret;
}
@@ -207,40 +188,39 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
static void __init check_sysemu(void)
{
- void *stack;
unsigned long regs[MAX_REG_NR];
int pid, n, status, count=0;
non_fatal("Checking syscall emulation patch for ptrace...");
sysemu_supported = 0;
- pid = start_ptraced_child(&stack);
+ pid = start_ptraced_child();
- if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
+ if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
goto fail;
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if (n < 0)
fatal_perror("check_sysemu : wait failed");
- if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
+ if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
fatal("check_sysemu : expected SIGTRAP, got status = %d",
status);
- if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
fatal_perror("check_sysemu : PTRACE_GETREGS failed");
- if(PT_SYSCALL_NR(regs) != __NR_getpid){
+ if (PT_SYSCALL_NR(regs) != __NR_getpid) {
non_fatal("check_sysemu got system call number %d, "
"expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
goto fail;
}
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
- if(n < 0){
+ if (n < 0) {
non_fatal("check_sysemu : failed to modify system call "
"return");
goto fail;
}
- if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+ if (stop_ptraced_child(pid, 0, 0) < 0)
goto fail_stopped;
sysemu_supported = 1;
@@ -248,90 +228,90 @@ static void __init check_sysemu(void)
set_using_sysemu(!force_sysemu_disabled);
non_fatal("Checking advanced syscall emulation patch for ptrace...");
- pid = start_ptraced_child(&stack);
+ pid = start_ptraced_child();
- if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
+ if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
(void *) PTRACE_O_TRACESYSGOOD) < 0))
fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
- while(1){
+ while (1) {
count++;
- if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
+ if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
goto fail;
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- if(n < 0)
+ if (n < 0)
fatal_perror("check_ptrace : wait failed");
- if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){
+ if (WIFSTOPPED(status) &&
+ (WSTOPSIG(status) == (SIGTRAP|0x80))) {
if (!count)
fatal("check_ptrace : SYSEMU_SINGLESTEP "
"doesn't singlestep");
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
os_getpid());
- if(n < 0)
+ if (n < 0)
fatal_perror("check_sysemu : failed to modify "
"system call return");
break;
}
- else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
+ else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
count++;
else
fatal("check_ptrace : expected SIGTRAP or "
"(SIGTRAP | 0x80), got status = %d", status);
}
- if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+ if (stop_ptraced_child(pid, 0, 0) < 0)
goto fail_stopped;
sysemu_supported = 2;
non_fatal("OK\n");
- if ( !force_sysemu_disabled )
+ if (!force_sysemu_disabled)
set_using_sysemu(sysemu_supported);
return;
fail:
- stop_ptraced_child(pid, stack, 1, 0);
+ stop_ptraced_child(pid, 1, 0);
fail_stopped:
non_fatal("missing\n");
}
static void __init check_ptrace(void)
{
- void *stack;
int pid, syscall, n, status;
non_fatal("Checking that ptrace can change system call numbers...");
- pid = start_ptraced_child(&stack);
+ pid = start_ptraced_child();
- if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
+ if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
(void *) PTRACE_O_TRACESYSGOOD) < 0))
fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
- while(1){
- if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
+ while (1) {
+ if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
fatal_perror("check_ptrace : ptrace failed");
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- if(n < 0)
+ if (n < 0)
fatal_perror("check_ptrace : wait failed");
- if(!WIFSTOPPED(status) ||
+ if (!WIFSTOPPED(status) ||
(WSTOPSIG(status) != (SIGTRAP | 0x80)))
fatal("check_ptrace : expected (SIGTRAP|0x80), "
"got status = %d", status);
syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
0);
- if(syscall == __NR_getpid){
+ if (syscall == __NR_getpid) {
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
__NR_getppid);
- if(n < 0)
+ if (n < 0)
fatal_perror("check_ptrace : failed to modify "
"system call");
break;
}
}
- stop_ptraced_child(pid, stack, 0, 1);
+ stop_ptraced_child(pid, 0, 1);
non_fatal("OK\n");
check_sysemu();
}
@@ -343,18 +323,18 @@ static void __init check_coredump_limit(void)
struct rlimit lim;
int err = getrlimit(RLIMIT_CORE, &lim);
- if(err){
+ if (err) {
perror("Getting core dump limit");
return;
}
printf("Core dump limits :\n\tsoft - ");
- if(lim.rlim_cur == RLIM_INFINITY)
+ if (lim.rlim_cur == RLIM_INFINITY)
printf("NONE\n");
else printf("%lu\n", lim.rlim_cur);
printf("\thard - ");
- if(lim.rlim_max == RLIM_INFINITY)
+ if (lim.rlim_max == RLIM_INFINITY)
printf("NONE\n");
else printf("%lu\n", lim.rlim_max);
}
@@ -408,20 +388,18 @@ __uml_setup("noptraceldt", noptraceldt_cmd_param,
" To support PTRACE_LDT, the host needs to be patched using\n"
" the current skas3 patch.\n\n");
-#ifdef UML_CONFIG_MODE_SKAS
static inline void check_skas3_ptrace_faultinfo(void)
{
struct ptrace_faultinfo fi;
- void *stack;
int pid, n;
non_fatal(" - PTRACE_FAULTINFO...");
- pid = start_ptraced_child(&stack);
+ pid = start_ptraced_child();
n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
if (n < 0) {
ptrace_faultinfo = 0;
- if(errno == EIO)
+ if (errno == EIO)
non_fatal("not found\n");
else
perror("not found");
@@ -434,13 +412,12 @@ static inline void check_skas3_ptrace_faultinfo(void)
}
init_registers(pid);
- stop_ptraced_child(pid, stack, 1, 1);
+ stop_ptraced_child(pid, 1, 1);
}
static inline void check_skas3_ptrace_ldt(void)
{
#ifdef PTRACE_LDT
- void *stack;
int pid, n;
unsigned char ldtbuf[40];
struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
@@ -449,11 +426,11 @@ static inline void check_skas3_ptrace_ldt(void)
.bytecount = sizeof(ldtbuf)};
non_fatal(" - PTRACE_LDT...");
- pid = start_ptraced_child(&stack);
+ pid = start_ptraced_child();
n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
if (n < 0) {
- if(errno == EIO)
+ if (errno == EIO)
non_fatal("not found\n");
else {
perror("not found");
@@ -461,13 +438,13 @@ static inline void check_skas3_ptrace_ldt(void)
ptrace_ldt = 0;
}
else {
- if(ptrace_ldt)
+ if (ptrace_ldt)
non_fatal("found\n");
else
non_fatal("found, but use is disabled\n");
}
- stop_ptraced_child(pid, stack, 1, 1);
+ stop_ptraced_child(pid, 1, 1);
#else
/* PTRACE_LDT might be disabled via cmdline option.
* We want to override this, else we might use the stub
@@ -484,12 +461,9 @@ static inline void check_skas3_proc_mm(void)
proc_mm = 0;
perror("not found");
}
- else {
- if (!proc_mm)
- non_fatal("found but disabled on command line\n");
- else
- non_fatal("found\n");
- }
+ else if (!proc_mm)
+ non_fatal("found but disabled on command line\n");
+ else non_fatal("found\n");
}
int can_do_skas(void)
@@ -500,17 +474,11 @@ int can_do_skas(void)
check_skas3_ptrace_faultinfo();
check_skas3_ptrace_ldt();
- if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
+ if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
skas_needs_stub = 1;
return 1;
}
-#else
-int can_do_skas(void)
-{
- return 0;
-}
-#endif
int __init parse_iomem(char *str, int *add)
{
@@ -521,25 +489,25 @@ int __init parse_iomem(char *str, int *add)
driver = str;
file = strchr(str,',');
- if(file == NULL){
+ if (file == NULL) {
printf("parse_iomem : failed to parse iomem\n");
goto out;
}
*file = '\0';
file++;
fd = open(file, O_RDWR, 0);
- if(fd < 0){
- os_print_error(fd, "parse_iomem - Couldn't open io file");
+ if (fd < 0) {
+ perror("parse_iomem - Couldn't open io file");
goto out;
}
- if(fstat64(fd, &buf) < 0){
+ if (fstat64(fd, &buf) < 0) {
perror("parse_iomem - cannot stat_fd file");
goto out_close;
}
new = malloc(sizeof(*new));
- if(new == NULL){
+ if (new == NULL) {
perror("Couldn't allocate iomem_region struct");
goto out_close;
}
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
index 37806621b25..a841262c594 100644
--- a/arch/um/os-Linux/sys-i386/Makefile
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -1,9 +1,9 @@
#
-# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL
#
-obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o
+obj-y = registers.o signal.o tls.o
USER_OBJS := $(obj-y)
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 84b44f9cd42..d1997ca76e5 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -1,144 +1,73 @@
/*
* Copyright (C) 2004 PathScale, Inc
+ * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <errno.h>
-#include <string.h>
-#include "sysdep/ptrace_user.h"
-#include "sysdep/ptrace.h"
-#include "uml-config.h"
-#include "skas_ptregs.h"
-#include "registers.h"
+#include "kern_constants.h"
#include "longjmp.h"
#include "user.h"
+#include "sysdep/ptrace_user.h"
-/* These are set once at boot time and not changed thereafter */
-
-static unsigned long exec_regs[MAX_REG_NR];
-static unsigned long exec_fp_regs[HOST_FP_SIZE];
-static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
-static int have_fpx_regs = 1;
-
-void init_thread_registers(union uml_pt_regs *to)
-{
- memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
- memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
- if(have_fpx_regs)
- memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp));
-}
-
-/* XXX These need to use [GS]ETFPXREGS and copy_sc_{to,from}_user_skas needs
- * to pass in a sufficiently large buffer
- */
int save_fp_registers(int pid, unsigned long *fp_regs)
{
- if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
+ if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
return -errno;
return 0;
}
int restore_fp_registers(int pid, unsigned long *fp_regs)
{
- if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
+ if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
return -errno;
return 0;
}
-static int move_registers(int pid, int int_op, union uml_pt_regs *regs,
- int fp_op, unsigned long *fp_regs)
+int save_fpx_registers(int pid, unsigned long *fp_regs)
{
- if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
- return -errno;
-
- if(ptrace(fp_op, pid, 0, fp_regs) < 0)
+ if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0)
return -errno;
-
return 0;
}
-void save_registers(int pid, union uml_pt_regs *regs)
+int restore_fpx_registers(int pid, unsigned long *fp_regs)
{
- unsigned long *fp_regs;
- int err, fp_op;
-
- if(have_fpx_regs){
- fp_op = PTRACE_GETFPXREGS;
- fp_regs = regs->skas.xfp;
- }
- else {
- fp_op = PTRACE_GETFPREGS;
- fp_regs = regs->skas.fp;
- }
-
- err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs);
- if(err)
- panic("save_registers - saving registers failed, errno = %d\n",
- -err);
+ if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
+ return -errno;
+ return 0;
}
-void restore_registers(int pid, union uml_pt_regs *regs)
+unsigned long get_thread_reg(int reg, jmp_buf *buf)
{
- unsigned long *fp_regs;
- int err, fp_op;
-
- if(have_fpx_regs){
- fp_op = PTRACE_SETFPXREGS;
- fp_regs = regs->skas.xfp;
- }
- else {
- fp_op = PTRACE_SETFPREGS;
- fp_regs = regs->skas.fp;
+ switch (reg) {
+ case EIP:
+ return buf[0]->__eip;
+ case UESP:
+ return buf[0]->__esp;
+ case EBP:
+ return buf[0]->__ebp;
+ default:
+ printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
+ reg);
+ return 0;
}
-
- err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs);
- if(err)
- panic("restore_registers - saving registers failed, "
- "errno = %d\n", -err);
}
-void init_registers(int pid)
+int have_fpx_regs = 1;
+
+void arch_init_registers(int pid)
{
+ unsigned long fpx_regs[HOST_XFP_SIZE];
int err;
- memset(exec_regs, 0, sizeof(exec_regs));
- err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
- if(err)
- panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
- errno);
-
- errno = 0;
- err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
+ err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs);
if(!err)
return;
+
if(errno != EIO)
panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
errno);
have_fpx_regs = 0;
-
- err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
- if(err)
- panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
- errno);
-}
-
-void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
-{
- memcpy(regs, exec_regs, sizeof(exec_regs));
- if(fp_regs != NULL)
- memcpy(fp_regs, exec_fp_regs,
- HOST_FP_SIZE * sizeof(unsigned long));
-}
-
-unsigned long get_thread_reg(int reg, jmp_buf *buf)
-{
- switch(reg){
- case EIP: return buf[0]->__eip;
- case UESP: return buf[0]->__esp;
- case EBP: return buf[0]->__ebp;
- default:
- printk("get_thread_regs - unknown register %d\n", reg);
- return 0;
- }
}
diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
index 7955e061a67..a42a4ef02e1 100644
--- a/arch/um/os-Linux/sys-x86_64/Makefile
+++ b/arch/um/os-Linux/sys-x86_64/Makefile
@@ -1,9 +1,9 @@
#
-# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL
#
-obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o
+obj-y = registers.o prctl.o signal.o
USER_OBJS := $(obj-y)
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 9467315b805..9bfa789992d 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -1,23 +1,15 @@
/*
- * Copyright (C) 2004 PathScale, Inc
+ * Copyright (C) 2006-2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <errno.h>
#include <sys/ptrace.h>
-#include <string.h>
-#include "ptrace_user.h"
-#include "uml-config.h"
-#include "skas_ptregs.h"
-#include "registers.h"
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
#include "longjmp.h"
#include "user.h"
-/* These are set once at boot time and not changed thereafter */
-
-static unsigned long exec_regs[MAX_REG_NR];
-static unsigned long exec_fp_regs[HOST_FP_SIZE];
-
int save_fp_registers(int pid, unsigned long *fp_regs)
{
if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
@@ -32,67 +24,6 @@ int restore_fp_registers(int pid, unsigned long *fp_regs)
return 0;
}
-void init_thread_registers(union uml_pt_regs *to)
-{
- memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
- memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
-}
-
-static int move_registers(int pid, int int_op, int fp_op,
- union uml_pt_regs *regs)
-{
- if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
- return -errno;
-
- if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0)
- return -errno;
-
- return 0;
-}
-
-void save_registers(int pid, union uml_pt_regs *regs)
-{
- int err;
-
- err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs);
- if(err)
- panic("save_registers - saving registers failed, errno = %d\n",
- -err);
-}
-
-void restore_registers(int pid, union uml_pt_regs *regs)
-{
- int err;
-
- err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs);
- if(err)
- panic("restore_registers - saving registers failed, "
- "errno = %d\n", -err);
-}
-
-void init_registers(int pid)
-{
- int err;
-
- err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
- if(err)
- panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
- errno);
-
- err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
- if(err)
- panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
- errno);
-}
-
-void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
-{
- memcpy(regs, exec_regs, sizeof(exec_regs));
- if(fp_regs != NULL)
- memcpy(fp_regs, exec_fp_regs,
- HOST_FP_SIZE * sizeof(unsigned long));
-}
-
unsigned long get_thread_reg(int reg, jmp_buf *buf)
{
switch(reg){
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 5de169b168f..e34e1effe0f 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -1,101 +1,86 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include <stddef.h>
+#include <errno.h>
+#include <signal.h>
#include <time.h>
#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include "kern_util.h"
-#include "user.h"
-#include "process.h"
#include "kern_constants.h"
#include "os.h"
-#include "uml-config.h"
+#include "user.h"
-int set_interval(int is_virtual)
+int set_interval(void)
{
- int usec = 1000000/hz();
- int timer_type = is_virtual ? ITIMER_VIRTUAL : ITIMER_REAL;
+ int usec = UM_USEC_PER_SEC / UM_HZ;
struct itimerval interval = ((struct itimerval) { { 0, usec },
{ 0, usec } });
- if(setitimer(timer_type, &interval, NULL) == -1)
+ if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
return -errno;
return 0;
}
-#ifdef UML_CONFIG_MODE_TT
-void enable_timer(void)
+int timer_one_shot(int ticks)
{
- set_interval(1);
-}
-#endif
+ unsigned long usec = ticks * UM_USEC_PER_SEC / UM_HZ;
+ unsigned long sec = usec / UM_USEC_PER_SEC;
+ struct itimerval interval;
-void disable_timer(void)
-{
- struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
- if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
- (setitimer(ITIMER_REAL, &disable, NULL) < 0))
- printk("disnable_timer - setitimer failed, errno = %d\n",
- errno);
- /* If there are signals already queued, after unblocking ignore them */
- signal(SIGALRM, SIG_IGN);
- signal(SIGVTALRM, SIG_IGN);
+ usec %= UM_USEC_PER_SEC;
+ interval = ((struct itimerval) { { 0, 0 }, { sec, usec } });
+
+ if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
+ return -errno;
+
+ return 0;
}
-void switch_timers(int to_real)
+/**
+ * timeval_to_ns - Convert timeval to nanoseconds
+ * @ts: pointer to the timeval variable to be converted
+ *
+ * Returns the scalar nanosecond representation of the timeval
+ * parameter.
+ *
+ * Ripped from linux/time.h because it's a kernel header, and thus
+ * unusable from here.
+ */
+static inline long long timeval_to_ns(const struct timeval *tv)
{
- struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
- struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() },
- { 0, 1000000/hz() }});
- int old, new;
-
- if(to_real){
- old = ITIMER_VIRTUAL;
- new = ITIMER_REAL;
- }
- else {
- old = ITIMER_REAL;
- new = ITIMER_VIRTUAL;
- }
-
- if((setitimer(old, &disable, NULL) < 0) ||
- (setitimer(new, &enable, NULL)))
- printk("switch_timers - setitimer failed, errno = %d\n",
- errno);
+ return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
+ tv->tv_usec * UM_NSEC_PER_USEC;
}
-#ifdef UML_CONFIG_MODE_TT
-void uml_idle_timer(void)
+long long disable_timer(void)
{
- if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
- panic("Couldn't unset SIGVTALRM handler");
+ struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
+
+ if(setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
+ printk(UM_KERN_ERR "disable_timer - setitimer failed, "
+ "errno = %d\n", errno);
- set_handler(SIGALRM, (__sighandler_t) alarm_handler,
- SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
- set_interval(0);
+ return timeval_to_ns(&time.it_value);
}
-#endif
-unsigned long long os_nsecs(void)
+long long os_nsecs(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
- return((unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000);
+ return timeval_to_ns(&tv);
}
-void idle_sleep(int secs)
+extern void alarm_handler(int sig, struct sigcontext *sc);
+
+void idle_sleep(unsigned long long nsecs)
{
- struct timespec ts;
+ struct timespec ts = { .tv_sec = nsecs / UM_NSEC_PER_SEC,
+ .tv_nsec = nsecs % UM_NSEC_PER_SEC };
- ts.tv_sec = secs;
- ts.tv_nsec = 0;
- nanosleep(&ts, NULL);
+ if (nanosleep(&ts, &ts) == 0)
+ alarm_handler(SIGVTALRM, NULL);
}
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index 16215b99080..73277801ef1 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -1,18 +1,9 @@
#include <errno.h>
-#include <unistd.h>
#include <sys/ptrace.h>
-#include <sys/syscall.h>
-#include <asm/ldt.h>
#include "sysdep/tls.h"
-#include "uml-config.h"
/* TLS support - we basically rely on the host's one.*/
-/* In TT mode, this should be called only by the tracing thread, and makes sense
- * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally.
- *
- */
-
#ifndef PTRACE_GET_THREAD_AREA
#define PTRACE_GET_THREAD_AREA 25
#endif
@@ -32,8 +23,6 @@ int os_set_thread_area(user_desc_t *info, int pid)
return ret;
}
-#ifdef UML_CONFIG_MODE_SKAS
-
int os_get_thread_area(user_desc_t *info, int pid)
{
int ret;
@@ -44,32 +33,3 @@ int os_get_thread_area(user_desc_t *info, int pid)
ret = -errno;
return ret;
}
-
-#endif
-
-#ifdef UML_CONFIG_MODE_TT
-#include "linux/unistd.h"
-
-int do_set_thread_area_tt(user_desc_t *info)
-{
- int ret;
-
- ret = syscall(__NR_set_thread_area,info);
- if (ret < 0) {
- ret = -errno;
- }
- return ret;
-}
-
-int do_get_thread_area_tt(user_desc_t *info)
-{
- int ret;
-
- ret = syscall(__NR_get_thread_area,info);
- if (ret < 0) {
- ret = -errno;
- }
- return ret;
-}
-
-#endif /* UML_CONFIG_MODE_TT */
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index 295da657931..2a1c9843e32 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -1,22 +1,14 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stdlib.h>
#include <signal.h>
-#include "kern_util.h"
#include "os.h"
-#include "mode.h"
-#include "longjmp.h"
-
-void usr2_handler(int sig, union uml_pt_regs *regs)
-{
- CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
-}
+#include "sysdep/ptrace.h"
/* Initialized from linux_main() */
-void (*sig_info[NSIG])(int, union uml_pt_regs *);
+void (*sig_info[NSIG])(int, struct uml_pt_regs *);
void os_fill_handlinfo(struct kern_handlers h)
{
@@ -28,13 +20,4 @@ void os_fill_handlinfo(struct kern_handlers h)
sig_info[SIGSEGV] = h.page_fault;
sig_info[SIGIO] = h.sigio_handler;
sig_info[SIGVTALRM] = h.timer_handler;
- sig_info[SIGALRM] = h.timer_handler;
- sig_info[SIGUSR2] = usr2_handler;
-}
-
-void do_longjmp(void *b, int val)
-{
- jmp_buf *buf = b;
-
- UML_LONGJMP(buf, val);
}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
deleted file mode 100644
index bcf9359c4e9..00000000000
--- a/arch/um/os-Linux/tt.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sched.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/ptrace.h>
-#include <linux/ptrace.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <asm/ptrace.h>
-#include <asm/unistd.h>
-#include <asm/page.h>
-#include "kern_util.h"
-#include "user.h"
-#include "signal_kern.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
-#include "irq_user.h"
-#include "ptrace_user.h"
-#include "init.h"
-#include "os.h"
-#include "uml-config.h"
-#include "choose-mode.h"
-#include "mode.h"
-#include "tempfile.h"
-#include "kern_constants.h"
-
-int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
- int must_succeed)
-{
- int err;
-
- err = os_protect_memory((void *) addr, len, r, w, x);
- if(err < 0){
- if(must_succeed)
- panic("protect failed, err = %d", -err);
- else return(err);
- }
- return(0);
-}
-
-void kill_child_dead(int pid)
-{
- kill(pid, SIGKILL);
- kill(pid, SIGCONT);
- do {
- int n;
- CATCH_EINTR(n = waitpid(pid, NULL, 0));
- if (n > 0)
- kill(pid, SIGCONT);
- else
- break;
- } while(1);
-}
-
-void stop(void)
-{
- while(1) sleep(1000000);
-}
-
-int wait_for_stop(int pid, int sig, int cont_type, void *relay)
-{
- sigset_t *relay_signals = relay;
- int status, ret;
-
- while(1){
- CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
- if((ret < 0) ||
- !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
- if(ret < 0){
- printk("wait failed, errno = %d\n",
- errno);
- }
- else if(WIFEXITED(status))
- printk("process %d exited with status %d\n",
- pid, WEXITSTATUS(status));
- else if(WIFSIGNALED(status))
- printk("process %d exited with signal %d\n",
- pid, WTERMSIG(status));
- else if((WSTOPSIG(status) == SIGVTALRM) ||
- (WSTOPSIG(status) == SIGALRM) ||
- (WSTOPSIG(status) == SIGIO) ||
- (WSTOPSIG(status) == SIGPROF) ||
- (WSTOPSIG(status) == SIGCHLD) ||
- (WSTOPSIG(status) == SIGWINCH) ||
- (WSTOPSIG(status) == SIGINT)){
- ptrace(cont_type, pid, 0, WSTOPSIG(status));
- continue;
- }
- else if((relay_signals != NULL) &&
- sigismember(relay_signals, WSTOPSIG(status))){
- ptrace(cont_type, pid, 0, WSTOPSIG(status));
- continue;
- }
- else printk("process %d stopped with signal %d\n",
- pid, WSTOPSIG(status));
- panic("wait_for_stop failed to wait for %d to stop "
- "with %d\n", pid, sig);
- }
- return(status);
- }
-}
-
-void forward_ipi(int fd, int pid)
-{
- int err;
-
- err = os_set_owner(fd, pid);
- if(err < 0)
- printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
- "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
-}
-
-/*
- *-------------------------
- * only for tt mode (will be deleted in future...)
- *-------------------------
- */
-
-struct tramp {
- int (*tramp)(void *);
- void *tramp_data;
- unsigned long temp_stack;
- int flags;
- int pid;
-};
-
-/* See above for why sigkill is here */
-
-int sigkill = SIGKILL;
-
-int outer_tramp(void *arg)
-{
- struct tramp *t;
- int sig = sigkill;
-
- t = arg;
- t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2,
- t->flags, t->tramp_data);
- if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
- kill(os_getpid(), sig);
- _exit(0);
-}
-
-int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
- int clone_flags, int (*tramp)(void *))
-{
- struct tramp arg;
- unsigned long sp;
- int new_pid, status, err;
-
- /* The trampoline will run on the temporary stack */
- sp = stack_sp(temp_stack);
-
- clone_flags |= CLONE_FILES | SIGCHLD;
-
- arg.tramp = tramp;
- arg.tramp_data = thread_arg;
- arg.temp_stack = temp_stack;
- arg.flags = clone_flags;
-
- /* Start the process and wait for it to kill itself */
- new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
- if(new_pid < 0)
- return(new_pid);
-
- CATCH_EINTR(err = waitpid(new_pid, &status, 0));
- if(err < 0)
- panic("Waiting for outer trampoline failed - errno = %d",
- errno);
-
- if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
- panic("outer trampoline didn't exit with SIGKILL, "
- "status = %d", status);
-
- return(arg.pid);
-}
-
-void forward_pending_sigio(int target)
-{
- sigset_t sigs;
-
- if(sigpending(&sigs))
- panic("forward_pending_sigio : sigpending failed");
- if(sigismember(&sigs, SIGIO))
- kill(target, SIGIO);
-}
-
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index bbb73a65037..8d27b6d1df9 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -8,7 +8,7 @@
#include "longjmp.h"
unsigned long __do_user_copy(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher,
+ void **fault_addr, jmp_buf **fault_catcher,
void (*op)(void *to, const void *from,
int n), int *faulted_out)
{
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index b462863f717..106fa864155 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -1,17 +1,21 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
#include <stdio.h>
-#include <unistd.h>
#include <stdlib.h>
-#include <string.h>
+#include <dirent.h>
#include <errno.h>
+#include <fcntl.h>
#include <signal.h>
-#include <dirent.h>
-#include <sys/fcntl.h>
+#include <string.h>
+#include <unistd.h>
#include <sys/stat.h>
-#include <sys/param.h>
#include "init.h"
+#include "kern_constants.h"
#include "os.h"
#include "user.h"
-#include "mode.h"
#define UML_DIR "~/.uml/"
@@ -28,13 +32,13 @@ static int __init make_uml_dir(void)
char dir[512] = { '\0' };
int len, err;
- if(*uml_dir == '~'){
+ if (*uml_dir == '~') {
char *home = getenv("HOME");
err = -ENOENT;
- if(home == NULL){
- printk("make_uml_dir : no value in environment for "
- "$HOME\n");
+ if (home == NULL) {
+ printk(UM_KERN_ERR "make_uml_dir : no value in "
+ "environment for $HOME\n");
goto err;
}
strlcpy(dir, home, sizeof(dir));
@@ -53,7 +57,7 @@ static int __init make_uml_dir(void)
}
strcpy(uml_dir, dir);
- if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
+ if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) {
printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
err = -errno;
goto err_free;
@@ -70,8 +74,8 @@ err:
/*
* Unlinks the files contained in @dir and then removes @dir.
* Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
- * ignore ENOENT errors for anything (they happen, strangely enough - possibly due
- * to races between multiple dying UML threads).
+ * ignore ENOENT errors for anything (they happen, strangely enough - possibly
+ * due to races between multiple dying UML threads).
*/
static int remove_files_and_dir(char *dir)
{
@@ -116,7 +120,8 @@ out:
return ret;
}
-/* This says that there isn't already a user of the specified directory even if
+/*
+ * This says that there isn't already a user of the specified directory even if
* there are errors during the checking. This is because if these errors
* happen, the directory is unusable by the pre-existing UML, so we might as
* well take it over. This could happen either by
@@ -134,44 +139,45 @@ static inline int is_umdir_used(char *dir)
int dead, fd, p, n, err;
n = snprintf(file, sizeof(file), "%s/pid", dir);
- if(n >= sizeof(file)){
- printk("is_umdir_used - pid filename too long\n");
+ if (n >= sizeof(file)) {
+ printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
err = -E2BIG;
goto out;
}
dead = 0;
fd = open(file, O_RDONLY);
- if(fd < 0) {
+ if (fd < 0) {
fd = -errno;
- if(fd != -ENOENT){
- printk("is_umdir_used : couldn't open pid file '%s', "
- "err = %d\n", file, -fd);
+ if (fd != -ENOENT) {
+ printk(UM_KERN_ERR "is_umdir_used : couldn't open pid "
+ "file '%s', err = %d\n", file, -fd);
}
goto out;
}
err = 0;
n = read(fd, pid, sizeof(pid));
- if(n < 0){
- printk("is_umdir_used : couldn't read pid file '%s', "
- "err = %d\n", file, errno);
+ if (n < 0) {
+ printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
+ "'%s', err = %d\n", file, errno);
goto out_close;
- } else if(n == 0){
- printk("is_umdir_used : couldn't read pid file '%s', "
- "0-byte read\n", file);
+ } else if (n == 0) {
+ printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
+ "'%s', 0-byte read\n", file);
goto out_close;
}
p = strtoul(pid, &end, 0);
- if(end == pid){
- printk("is_umdir_used : couldn't parse pid file '%s', "
- "errno = %d\n", file, errno);
+ if (end == pid) {
+ printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file "
+ "'%s', errno = %d\n", file, errno);
goto out_close;
}
- if((kill(p, 0) == 0) || (errno != ESRCH)){
- printk("umid \"%s\" is already in use by pid %d\n", umid, p);
+ if ((kill(p, 0) == 0) || (errno != ESRCH)) {
+ printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n",
+ umid, p);
return 1;
}
@@ -195,8 +201,8 @@ static int umdir_take_if_dead(char *dir)
ret = remove_files_and_dir(dir);
if (ret) {
- printk("is_umdir_used - remove_files_and_dir failed with "
- "err = %d\n", ret);
+ printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir "
+ "failed with err = %d\n", ret);
}
return ret;
}
@@ -207,27 +213,28 @@ static void __init create_pid_file(void)
char pid[sizeof("nnnnn\0")];
int fd, n;
- if(umid_file_name("pid", file, sizeof(file)))
+ if (umid_file_name("pid", file, sizeof(file)))
return;
fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
- if(fd < 0){
- printk("Open of machine pid file \"%s\" failed: %s\n",
- file, strerror(errno));
+ if (fd < 0) {
+ printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: "
+ "%s\n", file, strerror(errno));
return;
}
snprintf(pid, sizeof(pid), "%d\n", getpid());
n = write(fd, pid, strlen(pid));
- if(n != strlen(pid))
- printk("Write of pid file failed - err = %d\n", errno);
+ if (n != strlen(pid))
+ printk(UM_KERN_ERR "Write of pid file failed - err = %d\n",
+ errno);
close(fd);
}
int __init set_umid(char *name)
{
- if(strlen(name) > UMID_LEN - 1)
+ if (strlen(name) > UMID_LEN - 1)
return -E2BIG;
strlcpy(umid, name, sizeof(umid));
@@ -243,18 +250,18 @@ int __init make_umid(void)
int fd, err;
char tmp[256];
- if(umid_setup)
+ if (umid_setup)
return 0;
make_uml_dir();
- if(*umid == '\0'){
+ if (*umid == '\0') {
strlcpy(tmp, uml_dir, sizeof(tmp));
strlcat(tmp, "XXXXXX", sizeof(tmp));
fd = mkstemp(tmp);
- if(fd < 0){
- printk("make_umid - mkstemp(%s) failed: %s\n",
- tmp, strerror(errno));
+ if (fd < 0) {
+ printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: "
+ "%s\n", tmp, strerror(errno));
err = -errno;
goto err;
}
@@ -263,11 +270,12 @@ int __init make_umid(void)
set_umid(&tmp[strlen(uml_dir)]);
- /* There's a nice tiny little race between this unlink and
+ /*
+ * There's a nice tiny little race between this unlink and
* the mkdir below. It'd be nice if there were a mkstemp
* for directories.
*/
- if(unlink(tmp)){
+ if (unlink(tmp)) {
err = -errno;
goto err;
}
@@ -275,9 +283,9 @@ int __init make_umid(void)
snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
err = mkdir(tmp, 0777);
- if(err < 0){
+ if (err < 0) {
err = -errno;
- if(err != -EEXIST)
+ if (err != -EEXIST)
goto err;
if (umdir_take_if_dead(tmp) < 0)
@@ -285,9 +293,10 @@ int __init make_umid(void)
err = mkdir(tmp, 0777);
}
- if(err){
+ if (err) {
err = -errno;
- printk("Failed to create '%s' - err = %d\n", umid, -errno);
+ printk(UM_KERN_ERR "Failed to create '%s' - err = %d\n", umid,
+ errno);
goto err;
}
@@ -302,14 +311,15 @@ int __init make_umid(void)
static int __init make_umid_init(void)
{
- if(!make_umid())
+ if (!make_umid())
return 0;
- /* If initializing with the given umid failed, then try again with
+ /*
+ * If initializing with the given umid failed, then try again with
* a random one.
*/
- printk("Failed to initialize umid \"%s\", trying with a random umid\n",
- umid);
+ printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a "
+ "random umid\n", umid);
*umid = '\0';
make_umid();
@@ -323,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len)
int n, err;
err = make_umid();
- if(err)
+ if (err)
return err;
n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
- if(n >= len){
- printk("umid_file_name : buffer too short\n");
+ if (n >= len) {
+ printk(UM_KERN_ERR "umid_file_name : buffer too short\n");
return -E2BIG;
}
@@ -342,21 +352,22 @@ char *get_umid(void)
static int __init set_uml_dir(char *name, int *add)
{
- if(*name == '\0'){
+ if (*name == '\0') {
printf("uml_dir can't be an empty string\n");
return 0;
}
- if(name[strlen(name) - 1] == '/'){
+ if (name[strlen(name) - 1] == '/') {
uml_dir = name;
return 0;
}
uml_dir = malloc(strlen(name) + 2);
- if(uml_dir == NULL){
+ if (uml_dir == NULL) {
printf("Failed to malloc uml_dir - error = %d\n", errno);
- /* Return 0 here because do_initcalls doesn't look at
+ /*
+ * Return 0 here because do_initcalls doesn't look at
* the return value.
*/
return 0;
@@ -377,7 +388,7 @@ static void remove_umid_dir(void)
sprintf(dir, "%s%s", uml_dir, umid);
err = remove_files_and_dir(dir);
- if(err)
+ if (err)
printf("remove_umid_dir - remove_files_and_dir failed with "
"err = %d\n", err);
}
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 7cbcf484e13..ef095436a78 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -105,6 +105,44 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
void os_dump_core(void)
{
+ int pid;
+
signal(SIGSEGV, SIG_DFL);
+
+ /*
+ * We are about to SIGTERM this entire process group to ensure that
+ * nothing is around to run after the kernel exits. The
+ * kernel wants to abort, not die through SIGTERM, so we
+ * ignore it here.
+ */
+
+ signal(SIGTERM, SIG_IGN);
+ kill(0, SIGTERM);
+ /*
+ * Most of the other processes associated with this UML are
+ * likely sTopped, so give them a SIGCONT so they see the
+ * SIGTERM.
+ */
+ kill(0, SIGCONT);
+
+ /*
+ * Now, having sent signals to everyone but us, make sure they
+ * die by ptrace. Processes can survive what's been done to
+ * them so far - the mechanism I understand is receiving a
+ * SIGSEGV and segfaulting immediately upon return. There is
+ * always a SIGSEGV pending, and (I'm guessing) signals are
+ * processed in numeric order so the SIGTERM (signal 15 vs
+ * SIGSEGV being signal 11) is never handled.
+ *
+ * Run a waitpid loop until we get some kind of error.
+ * Hopefully, it's ECHILD, but there's not a lot we can do if
+ * it's something else. Tell os_kill_ptraced_process not to
+ * wait for the child to report its death because there's
+ * nothing reasonable to do if that fails.
+ */
+
+ while ((pid = waitpid(-1, NULL, WNOHANG)) > 0)
+ os_kill_ptraced_process(pid, 0);
+
abort();
}
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index bf23dd3e24d..61107b68e05 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -21,7 +21,7 @@ $(UNPROFILE_OBJS:.o=.%): \
$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
-Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
-# The stubs and unmap.o can't try to call mcount or update basic block data
+# The stubs can't try to call mcount or update basic block data
define unprofile
$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
endef
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index a4618b6b85b..964dc1a04c3 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,23 +1,21 @@
+#
+# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+#
+
obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
- ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \
+ ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
sys_call_table.o tls.o
-obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
-
subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o
subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o
-USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
+USER_OBJS := bugs.o ptrace_user.o fault.o
USER_OBJS += user-offsets.s
extra-y += user-offsets.s
-extra-$(CONFIG_MODE_TT) += unmap.o
-
UNPROFILE_OBJS := stub_segv.o
CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
include arch/um/scripts/Makefile.rules
-
-$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index 0393e44813e..806895d73bc 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -1,18 +1,15 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <unistd.h>
#include <errno.h>
+#include <signal.h>
#include <string.h>
-#include <sys/signal.h>
-#include <asm/ldt.h>
-#include "kern_util.h"
-#include "user.h"
-#include "sysdep/ptrace.h"
-#include "task.h"
+#include "kern_constants.h"
#include "os.h"
+#include "task.h"
+#include "user.h"
#define MAXTOKEN 64
@@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop)
do {
n = os_read_file(fd, ptr, sizeof(*ptr));
c = *ptr++;
- if(n != sizeof(*ptr)){
- if(n == 0)
+ if (n != sizeof(*ptr)) {
+ if (n == 0)
return 0;
- printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
- if(n < 0)
+ printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
+ "err = %d\n", -n);
+ if (n < 0)
return n;
else return -EIO;
}
- } while((c != '\n') && (c != stop) && (ptr < end));
+ } while ((c != '\n') && (c != stop) && (ptr < end));
- if(ptr == end){
- printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
+ if (ptr == end) {
+ printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n",
+ stop);
return -1;
}
*(ptr - 1) = '\0';
@@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
char c;
scratch[len - 1] = '\0';
- while(1){
+ while (1) {
c = token(fd, scratch, len - 1, ':');
- if(c <= 0)
+ if (c <= 0)
return 0;
- else if(c != ':'){
- printk("Failed to find ':' in /proc/cpuinfo\n");
+ else if (c != ':') {
+ printk(UM_KERN_ERR "Failed to find ':' in "
+ "/proc/cpuinfo\n");
return 0;
}
- if(!strncmp(scratch, key, strlen(key)))
+ if (!strncmp(scratch, key, strlen(key)))
return 1;
do {
n = os_read_file(fd, &c, sizeof(c));
- if(n != sizeof(c)){
- printk("Failed to find newline in "
+ if (n != sizeof(c)) {
+ printk(UM_KERN_ERR "Failed to find newline in "
"/proc/cpuinfo, err = %d\n", -n);
return 0;
}
- } while(c != '\n');
+ } while (c != '\n');
}
return 0;
}
@@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it)
char buf[MAXTOKEN], c;
int fd, len = ARRAY_SIZE(buf);
- printk("Checking for host processor %s support...", feature);
+ printk(UM_KERN_INFO "Checking for host processor %s support...",
+ feature);
fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
+ if (fd < 0) {
+ printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n",
+ -fd);
return 0;
}
*have_it = 0;
- if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
+ if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
goto out;
c = token(fd, buf, len - 1, ' ');
- if(c < 0)
+ if (c < 0)
goto out;
- else if(c != ' '){
- printk("Failed to find ' ' in /proc/cpuinfo\n");
+ else if (c != ' ') {
+ printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
goto out;
}
- while(1){
+ while (1) {
c = token(fd, buf, len - 1, ' ');
- if(c < 0)
+ if (c < 0)
goto out;
- else if(c == '\n') break;
+ else if (c == '\n')
+ break;
- if(!strcmp(buf, feature)){
+ if (!strcmp(buf, feature)) {
*have_it = 1;
goto out;
}
}
out:
- if(*have_it == 0)
+ if (*have_it == 0)
printk("No\n");
- else if(*have_it == 1)
+ else if (*have_it == 1)
printk("Yes\n");
os_close_file(fd);
return 1;
}
-#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
+#if 0 /*
+ * This doesn't work in tt mode, plus it's causing compilation problems
* for some people.
*/
static void disable_lcall(void)
@@ -135,8 +139,9 @@ static void disable_lcall(void)
ldt.base_addr = 0;
ldt.limit = 0;
err = modify_ldt(1, &ldt, sizeof(ldt));
- if(err)
- printk("Failed to disable lcall7 - errno = %d\n", errno);
+ if (err)
+ printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
+ errno);
}
#endif
@@ -151,40 +156,41 @@ void arch_check_bugs(void)
{
int have_it;
- if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
- printk("/proc/cpuinfo not available - skipping CPU capability "
- "checks\n");
+ if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) {
+ printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
+ "capability checks\n");
return;
}
- if(check_cpu_flag("cmov", &have_it))
+ if (check_cpu_flag("cmov", &have_it))
host_has_cmov = have_it;
- if(check_cpu_flag("xmm", &have_it))
+ if (check_cpu_flag("xmm", &have_it))
host_has_xmm = have_it;
}
-int arch_handle_signal(int sig, union uml_pt_regs *regs)
+int arch_handle_signal(int sig, struct uml_pt_regs *regs)
{
unsigned char tmp[2];
- /* This is testing for a cmov (0x0f 0x4x) instruction causing a
+ /*
+ * This is testing for a cmov (0x0f 0x4x) instruction causing a
* SIGILL in init.
*/
- if((sig != SIGILL) || (TASK_PID(get_current()) != 1))
+ if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
return 0;
if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
panic("SIGILL in init, could not read instructions!\n");
- if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
+ if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
return 0;
- if(host_has_cmov == 0)
+ if (host_has_cmov == 0)
panic("SIGILL caused by cmov, which this processor doesn't "
"implement, boot a filesystem compiled for older "
"processors");
- else if(host_has_cmov == 1)
+ else if (host_has_cmov == 1)
panic("SIGILL caused by cmov, which this processor claims to "
"implement");
- else if(host_has_cmov == -1)
+ else if (host_has_cmov == -1)
panic("SIGILL caused by cmov, couldn't tell if this processor "
"implements it, boot a filesystem compiled for older "
"processors");
diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
index 745b4fd49e9..d670f68532f 100644
--- a/arch/um/sys-i386/fault.c
+++ b/arch/um/sys-i386/fault.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -15,14 +15,14 @@ struct exception_table_entry
const struct exception_table_entry *search_exception_tables(unsigned long add);
/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
-int arch_fixup(unsigned long address, union uml_pt_regs *regs)
+int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
{
const struct exception_table_entry *fixup;
fixup = search_exception_tables(address);
- if(fixup != 0){
+ if (fixup != 0) {
UPT_IP(regs) = fixup->fixup;
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index a939a7ef022..67c0958eb98 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -1,106 +1,30 @@
/*
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/slab.h"
-#include "linux/types.h"
-#include "linux/errno.h"
-#include "linux/spinlock.h"
-#include "asm/uaccess.h"
-#include "asm/smp.h"
-#include "asm/ldt.h"
+#include "linux/mm.h"
#include "asm/unistd.h"
-#include "choose-mode.h"
-#include "kern.h"
-#include "mode_kern.h"
#include "os.h"
-
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-#ifdef CONFIG_MODE_TT
-
-static long do_modify_ldt_tt(int func, void __user *ptr,
- unsigned long bytecount)
-{
- struct user_desc info;
- int res = 0;
- void *buf = NULL;
- void *p = NULL; /* What we pass to host. */
-
- switch(func){
- case 1:
- case 0x11: /* write_ldt */
- /* Do this check now to avoid overflows. */
- if (bytecount != sizeof(struct user_desc)) {
- res = -EINVAL;
- goto out;
- }
-
- if(copy_from_user(&info, ptr, sizeof(info))) {
- res = -EFAULT;
- goto out;
- }
-
- p = &info;
- break;
- case 0:
- case 2: /* read_ldt */
-
- /* The use of info avoids kmalloc on the write case, not on the
- * read one. */
- buf = kmalloc(bytecount, GFP_KERNEL);
- if (!buf) {
- res = -ENOMEM;
- goto out;
- }
- p = buf;
- break;
- default:
- res = -ENOSYS;
- goto out;
- }
-
- res = modify_ldt(func, p, bytecount);
- if(res < 0)
- goto out;
-
- switch(func){
- case 0:
- case 2:
- /* Modify_ldt was for reading and returned the number of read
- * bytes.*/
- if(copy_to_user(ptr, p, res))
- res = -EFAULT;
- break;
- }
-
-out:
- kfree(buf);
- return res;
-}
-
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-
+#include "proc_mm.h"
#include "skas.h"
#include "skas_ptrace.h"
-#include "asm/mmu_context.h"
-#include "proc_mm.h"
+#include "sysdep/tls.h"
+
+extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
void **addr, int done)
{
long res;
- if(proc_mm){
- /* This is a special handling for the case, that the mm to
+ if (proc_mm) {
+ /*
+ * This is a special handling for the case, that the mm to
* modify isn't current->active_mm.
* If this is called directly by modify_ldt,
* (current->active_mm->context.skas.u == mm_idp)
- * will be true. So no call to switch_mm_skas(mm_idp) is done.
+ * will be true. So no call to __switch_mm(mm_idp) is done.
* If this is called in case of init_new_ldt or PTRACE_LDT,
* mm_idp won't belong to current->active_mm, but child->mm.
* So we need to switch child's mm into our userspace, then
@@ -108,12 +32,12 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
*
* Note: I'm unsure: should interrupts be disabled here?
*/
- if(!current->active_mm || current->active_mm == &init_mm ||
- mm_idp != &current->active_mm->context.skas.id)
- switch_mm_skas(mm_idp);
+ if (!current->active_mm || current->active_mm == &init_mm ||
+ mm_idp != &current->active_mm->context.id)
+ __switch_mm(mm_idp);
}
- if(ptrace_ldt) {
+ if (ptrace_ldt) {
struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
.func = func,
.ptr = desc,
@@ -121,7 +45,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
u32 cpu;
int pid;
- if(!proc_mm)
+ if (!proc_mm)
pid = mm_idp->u.pid;
else {
cpu = get_cpu();
@@ -130,7 +54,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op);
- if(proc_mm)
+ if (proc_mm)
put_cpu();
}
else {
@@ -139,7 +63,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
(sizeof(*desc) + sizeof(long) - 1) &
~(sizeof(long) - 1),
addr, &stub_addr);
- if(!res){
+ if (!res) {
unsigned long args[] = { func,
(unsigned long)stub_addr,
sizeof(*desc),
@@ -149,13 +73,14 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
}
}
- if(proc_mm){
- /* This is the second part of special handling, that makes
+ if (proc_mm) {
+ /*
+ * This is the second part of special handling, that makes
* PTRACE_LDT possible to implement.
*/
- if(current->active_mm && current->active_mm != &init_mm &&
- mm_idp != &current->active_mm->context.skas.id)
- switch_mm_skas(&current->active_mm->context.skas.id);
+ if (current->active_mm && current->active_mm != &init_mm &&
+ mm_idp != &current->active_mm->context.id)
+ __switch_mm(&current->active_mm->context.id);
}
return res;
@@ -170,21 +95,22 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
.ptr = kmalloc(bytecount, GFP_KERNEL)};
u32 cpu;
- if(ptrace_ldt.ptr == NULL)
+ if (ptrace_ldt.ptr == NULL)
return -ENOMEM;
- /* This is called from sys_modify_ldt only, so userspace_pid gives
+ /*
+ * This is called from sys_modify_ldt only, so userspace_pid gives
* us the right number
*/
cpu = get_cpu();
res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt);
put_cpu();
- if(res < 0)
+ if (res < 0)
goto out;
n = copy_to_user(ptr, ptrace_ldt.ptr, res);
- if(n != 0)
+ if (n != 0)
res = -EFAULT;
out:
@@ -209,35 +135,34 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
{
int i, err = 0;
unsigned long size;
- uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+ uml_ldt_t * ldt = &current->mm->context.ldt;
- if(!ldt->entry_count)
+ if (!ldt->entry_count)
goto out;
- if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+ if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
err = bytecount;
- if(ptrace_ldt){
+ if (ptrace_ldt)
return read_ldt_from_host(ptr, bytecount);
- }
down(&ldt->semaphore);
- if(ldt->entry_count <= LDT_DIRECT_ENTRIES){
+ if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
- if(size > bytecount)
+ if (size > bytecount)
size = bytecount;
- if(copy_to_user(ptr, ldt->u.entries, size))
+ if (copy_to_user(ptr, ldt->u.entries, size))
err = -EFAULT;
bytecount -= size;
ptr += size;
}
else {
- for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
- i++){
+ for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
+ i++) {
size = PAGE_SIZE;
- if(size > bytecount)
+ if (size > bytecount)
size = bytecount;
- if(copy_to_user(ptr, ldt->u.pages[i], size)){
+ if (copy_to_user(ptr, ldt->u.pages[i], size)) {
err = -EFAULT;
break;
}
@@ -247,10 +172,10 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
}
up(&ldt->semaphore);
- if(bytecount == 0 || err == -EFAULT)
+ if (bytecount == 0 || err == -EFAULT)
goto out;
- if(clear_user(ptr, bytecount))
+ if (clear_user(ptr, bytecount))
err = -EFAULT;
out:
@@ -261,15 +186,16 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount)
{
int err;
- if(bytecount > 5*LDT_ENTRY_SIZE)
+ if (bytecount > 5*LDT_ENTRY_SIZE)
bytecount = 5*LDT_ENTRY_SIZE;
err = bytecount;
- /* UML doesn't support lcall7 and lcall27.
+ /*
+ * UML doesn't support lcall7 and lcall27.
* So, we don't really have a default ldt, but emulate
* an empty ldt of common host default ldt size.
*/
- if(clear_user(ptr, bytecount))
+ if (clear_user(ptr, bytecount))
err = -EFAULT;
return err;
@@ -277,60 +203,60 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount)
static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
{
- uml_ldt_t * ldt = &current->mm->context.skas.ldt;
- struct mm_id * mm_idp = &current->mm->context.skas.id;
+ uml_ldt_t * ldt = &current->mm->context.ldt;
+ struct mm_id * mm_idp = &current->mm->context.id;
int i, err;
struct user_desc ldt_info;
struct ldt_entry entry0, *ldt_p;
void *addr = NULL;
err = -EINVAL;
- if(bytecount != sizeof(ldt_info))
+ if (bytecount != sizeof(ldt_info))
goto out;
err = -EFAULT;
- if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
+ if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
goto out;
err = -EINVAL;
- if(ldt_info.entry_number >= LDT_ENTRIES)
+ if (ldt_info.entry_number >= LDT_ENTRIES)
goto out;
- if(ldt_info.contents == 3){
+ if (ldt_info.contents == 3) {
if (func == 1)
goto out;
if (ldt_info.seg_not_present == 0)
goto out;
}
- if(!ptrace_ldt)
- down(&ldt->semaphore);
+ if (!ptrace_ldt)
+ down(&ldt->semaphore);
err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
- if(err)
+ if (err)
goto out_unlock;
- else if(ptrace_ldt) {
- /* With PTRACE_LDT available, this is used as a flag only */
- ldt->entry_count = 1;
- goto out;
- }
-
- if(ldt_info.entry_number >= ldt->entry_count &&
- ldt_info.entry_number >= LDT_DIRECT_ENTRIES){
- for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
- i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
- i++){
- if(i == 0)
+ else if (ptrace_ldt) {
+ /* With PTRACE_LDT available, this is used as a flag only */
+ ldt->entry_count = 1;
+ goto out;
+ }
+
+ if (ldt_info.entry_number >= ldt->entry_count &&
+ ldt_info.entry_number >= LDT_DIRECT_ENTRIES) {
+ for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
+ i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
+ i++) {
+ if (i == 0)
memcpy(&entry0, ldt->u.entries,
sizeof(entry0));
ldt->u.pages[i] = (struct ldt_entry *)
__get_free_page(GFP_KERNEL|__GFP_ZERO);
- if(!ldt->u.pages[i]){
+ if (!ldt->u.pages[i]) {
err = -ENOMEM;
/* Undo the change in host */
memset(&ldt_info, 0, sizeof(ldt_info));
write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
goto out_unlock;
}
- if(i == 0) {
+ if (i == 0) {
memcpy(ldt->u.pages[0], &entry0,
sizeof(entry0));
memcpy(ldt->u.pages[0]+1, ldt->u.entries+1,
@@ -339,17 +265,17 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
}
}
- if(ldt->entry_count <= ldt_info.entry_number)
+ if (ldt->entry_count <= ldt_info.entry_number)
ldt->entry_count = ldt_info.entry_number + 1;
- if(ldt->entry_count <= LDT_DIRECT_ENTRIES)
+ if (ldt->entry_count <= LDT_DIRECT_ENTRIES)
ldt_p = ldt->u.entries + ldt_info.entry_number;
else
ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
- if(ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
- (func == 1 || LDT_empty(&ldt_info))){
+ if (ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
+ (func == 1 || LDT_empty(&ldt_info))) {
ldt_p->a = 0;
ldt_p->b = 0;
}
@@ -400,7 +326,7 @@ static void ldt_get_host_info(void)
spin_lock(&host_ldt_lock);
- if(host_ldt_entries != NULL){
+ if (host_ldt_entries != NULL) {
spin_unlock(&host_ldt_lock);
return;
}
@@ -408,49 +334,49 @@ static void ldt_get_host_info(void)
spin_unlock(&host_ldt_lock);
- for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
+ for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++)
+ ;
ldt = (struct ldt_entry *)
__get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
- if(ldt == NULL) {
- printk("ldt_get_host_info: couldn't allocate buffer for host "
- "ldt\n");
+ if (ldt == NULL) {
+ printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer "
+ "for host ldt\n");
return;
}
ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
- if(ret < 0) {
- printk("ldt_get_host_info: couldn't read host ldt\n");
+ if (ret < 0) {
+ printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n");
goto out_free;
}
- if(ret == 0) {
+ if (ret == 0) {
/* default_ldt is active, simply write an empty entry 0 */
host_ldt_entries = dummy_list;
goto out_free;
}
- for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){
- if(ldt[i].a != 0 || ldt[i].b != 0)
+ for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) {
+ if (ldt[i].a != 0 || ldt[i].b != 0)
size++;
}
- if(size < ARRAY_SIZE(dummy_list))
+ if (size < ARRAY_SIZE(dummy_list))
host_ldt_entries = dummy_list;
else {
size = (size + 1) * sizeof(dummy_list[0]);
tmp = kmalloc(size, GFP_KERNEL);
- if(tmp == NULL) {
- printk("ldt_get_host_info: couldn't allocate host ldt "
- "list\n");
+ if (tmp == NULL) {
+ printk(KERN_ERR "ldt_get_host_info: couldn't allocate "
+ "host ldt list\n");
goto out_free;
}
host_ldt_entries = tmp;
}
- for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
- if(ldt[i].a != 0 || ldt[i].b != 0) {
+ for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) {
+ if (ldt[i].a != 0 || ldt[i].b != 0)
host_ldt_entries[k++] = i;
- }
}
host_ldt_entries[k] = -1;
@@ -458,8 +384,7 @@ out_free:
free_pages((unsigned long)ldt, order);
}
-long init_new_ldt(struct mmu_context_skas * new_mm,
- struct mmu_context_skas * from_mm)
+long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
{
struct user_desc desc;
short * num_p;
@@ -469,15 +394,15 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
struct proc_mm_op copy;
- if(!ptrace_ldt)
+ if (!ptrace_ldt)
init_MUTEX(&new_mm->ldt.semaphore);
- if(!from_mm){
+ if (!from_mm) {
memset(&desc, 0, sizeof(desc));
/*
* We have to initialize a clean ldt.
*/
- if(proc_mm) {
+ if (proc_mm) {
/*
* If the new mm was created using proc_mm, host's
* default-ldt currently is assigned, which normally
@@ -485,8 +410,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
* To remove these gates, we simply write an empty
* entry as number 0 to the host.
*/
- err = write_ldt_entry(&new_mm->id, 1, &desc,
- &addr, 1);
+ err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1);
}
else{
/*
@@ -495,11 +419,11 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
* will be reset in the following loop
*/
ldt_get_host_info();
- for(num_p=host_ldt_entries; *num_p != -1; num_p++){
+ for (num_p=host_ldt_entries; *num_p != -1; num_p++) {
desc.entry_number = *num_p;
err = write_ldt_entry(&new_mm->id, 1, &desc,
&addr, *(num_p + 1) == -1);
- if(err)
+ if (err)
break;
}
}
@@ -508,8 +432,9 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
goto out;
}
- if(proc_mm){
- /* We have a valid from_mm, so we now have to copy the LDT of
+ if (proc_mm) {
+ /*
+ * We have a valid from_mm, so we now have to copy the LDT of
* from_mm to new_mm, because using proc_mm an new mm with
* an empty/default LDT was created in new_mm()
*/
@@ -518,27 +443,27 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
{ .copy_segments =
from_mm->id.u.mm_fd } } );
i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy));
- if(i != sizeof(copy))
- printk("new_mm : /proc/mm copy_segments failed, "
- "err = %d\n", -i);
+ if (i != sizeof(copy))
+ printk(KERN_ERR "new_mm : /proc/mm copy_segments "
+ "failed, err = %d\n", -i);
}
- if(!ptrace_ldt) {
- /* Our local LDT is used to supply the data for
+ if (!ptrace_ldt) {
+ /*
+ * Our local LDT is used to supply the data for
* modify_ldt(READLDT), if PTRACE_LDT isn't available,
* i.e., we have to use the stub for modify_ldt, which
* can't handle the big read buffer of up to 64kB.
*/
down(&from_mm->ldt.semaphore);
- if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){
+ if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES)
memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries,
sizeof(new_mm->ldt.u.entries));
- }
- else{
+ else {
i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
- while(i-->0){
+ while (i-->0) {
page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
- if (!page){
+ if (!page) {
err = -ENOMEM;
break;
}
@@ -557,22 +482,19 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
}
-void free_ldt(struct mmu_context_skas * mm)
+void free_ldt(struct mm_context *mm)
{
int i;
- if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){
+ if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) {
i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
- while(i-- > 0){
- free_page((long )mm->ldt.u.pages[i]);
- }
+ while (i-- > 0)
+ free_page((long) mm->ldt.u.pages[i]);
}
mm->ldt.entry_count = 0;
}
-#endif
int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
{
- return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
- ptr, bytecount);
+ return do_modify_ldt_skas(func, ptr, bytecount);
}
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 28bf0115032..9657c89fdf3 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -1,35 +1,26 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <linux/compiler.h>
-#include "linux/sched.h"
#include "linux/mm.h"
-#include "asm/elf.h"
-#include "asm/ptrace.h"
+#include "linux/sched.h"
#include "asm/uaccess.h"
-#include "asm/unistd.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/sc.h"
+#include "skas.h"
-void arch_switch_to_tt(struct task_struct *from, struct task_struct *to)
-{
- update_debugregs(to->thread.arch.debugregs_seq);
- arch_switch_tls_tt(from, to);
-}
+extern int arch_switch_tls(struct task_struct *from, struct task_struct *to);
-void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
+void arch_switch_to(struct task_struct *from, struct task_struct *to)
{
- int err = arch_switch_tls_skas(from, to);
+ int err = arch_switch_tls(from, to);
if (!err)
return;
if (err != -EINVAL)
- printk(KERN_WARNING "arch_switch_tls_skas failed, errno %d, not EINVAL\n", -err);
+ printk(KERN_WARNING "arch_switch_tls failed, errno %d, "
+ "not EINVAL\n", -err);
else
- printk(KERN_WARNING "arch_switch_tls_skas failed, errno = EINVAL\n");
+ printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n");
}
int is_syscall(unsigned long addr)
@@ -38,21 +29,21 @@ int is_syscall(unsigned long addr)
int n;
n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
- if(n){
+ if (n) {
/* access_process_vm() grants access to vsyscall and stub,
* while copy_from_user doesn't. Maybe access_process_vm is
* slow, but that doesn't matter, since it will be called only
* in case of singlestepping, if copy_from_user failed.
*/
n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
- if(n != sizeof(instr)) {
- printk("is_syscall : failed to read instruction from "
- "0x%lx\n", addr);
- return(1);
+ if (n != sizeof(instr)) {
+ printk(KERN_ERR "is_syscall : failed to read "
+ "instruction from 0x%lx\n", addr);
+ return 1;
}
}
/* int 0x80 or sysenter */
- return((instr == 0x80cd) || (instr == 0x340f));
+ return (instr == 0x80cd) || (instr == 0x340f);
}
/* determines which flags the user has access to. */
@@ -96,21 +87,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
int poke_user(struct task_struct *child, long addr, long data)
{
- if ((addr & 3) || addr < 0)
- return -EIO;
-
- if (addr < MAX_REG_OFFSET)
- return putreg(child, addr, data);
+ if ((addr & 3) || addr < 0)
+ return -EIO;
- else if((addr >= offsetof(struct user, u_debugreg[0])) &&
- (addr <= offsetof(struct user, u_debugreg[7]))){
- addr -= offsetof(struct user, u_debugreg[0]);
- addr = addr >> 2;
- if((addr == 4) || (addr == 5)) return -EIO;
- child->thread.arch.debugregs[addr] = data;
- return 0;
- }
- return -EIO;
+ if (addr < MAX_REG_OFFSET)
+ return putreg(child, addr, data);
+ else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))) {
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ if ((addr == 4) || (addr == 5))
+ return -EIO;
+ child->thread.arch.debugregs[addr] = data;
+ return 0;
+ }
+ return -EIO;
}
unsigned long getreg(struct task_struct *child, int regno)
@@ -133,20 +124,20 @@ unsigned long getreg(struct task_struct *child, int regno)
return retval;
}
+/* read the word at location addr in the USER area. */
int peek_user(struct task_struct *child, long addr, long data)
{
-/* read the word at location addr in the USER area. */
unsigned long tmp;
if ((addr & 3) || addr < 0)
return -EIO;
tmp = 0; /* Default return condition */
- if(addr < MAX_REG_OFFSET){
+ if (addr < MAX_REG_OFFSET) {
tmp = getreg(child, addr);
}
- else if((addr >= offsetof(struct user, u_debugreg[0])) &&
- (addr <= offsetof(struct user, u_debugreg[7]))){
+ else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))) {
addr -= offsetof(struct user, u_debugreg[0]);
addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr];
@@ -154,277 +145,68 @@ int peek_user(struct task_struct *child, long addr, long data)
return put_user(tmp, (unsigned long __user *) data);
}
-struct i387_fxsave_struct {
- unsigned short cwd;
- unsigned short swd;
- unsigned short twd;
- unsigned short fop;
- long fip;
- long fcs;
- long foo;
- long fos;
- long mxcsr;
- long reserved;
- long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
- long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
- long padding[56];
-};
-
-/*
- * FPU tag word conversions.
- */
-
-static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
+int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
- unsigned int tmp; /* to avoid 16 bit prefixes in the code */
-
- /* Transform each pair of bits into 01 (valid) or 00 (empty) */
- tmp = ~twd;
- tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
- /* and move the valid bits to the lower byte. */
- tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
- tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
- tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
- return tmp;
-}
+ int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
+ long fpregs[HOST_FP_SIZE];
-static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
-{
- struct _fpxreg *st = NULL;
- unsigned long twd = (unsigned long) fxsave->twd;
- unsigned long tag;
- unsigned long ret = 0xffff0000;
- int i;
+ BUG_ON(sizeof(*buf) != sizeof(fpregs));
+ err = save_fp_registers(userspace_pid[cpu], fpregs);
+ if (err)
+ return err;
-#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
+ n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
+ if(n > 0)
+ return -EFAULT;
- for ( i = 0 ; i < 8 ; i++ ) {
- if ( twd & 0x1 ) {
- st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
-
- switch ( st->exponent & 0x7fff ) {
- case 0x7fff:
- tag = 2; /* Special */
- break;
- case 0x0000:
- if ( !st->significand[0] &&
- !st->significand[1] &&
- !st->significand[2] &&
- !st->significand[3] ) {
- tag = 1; /* Zero */
- } else {
- tag = 2; /* Special */
- }
- break;
- default:
- if ( st->significand[3] & 0x8000 ) {
- tag = 0; /* Valid */
- } else {
- tag = 2; /* Special */
- }
- break;
- }
- } else {
- tag = 3; /* Empty */
- }
- ret |= (tag << (2 * i));
- twd = twd >> 1;
- }
- return ret;
+ return n;
}
-/*
- * FXSR floating point environment conversions.
- */
-
-#ifdef CONFIG_MODE_TT
-static inline int convert_fxsr_to_user_tt(struct _fpstate __user *buf,
- struct pt_regs *regs)
+int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
- struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
- unsigned long env[7];
- struct _fpreg __user *to;
- struct _fpxreg *from;
- int i;
+ int n, cpu = ((struct thread_info *) child->stack)->cpu;
+ long fpregs[HOST_FP_SIZE];
- env[0] = (unsigned long)fxsave->cwd | 0xffff0000;
- env[1] = (unsigned long)fxsave->swd | 0xffff0000;
- env[2] = twd_fxsr_to_i387(fxsave);
- env[3] = fxsave->fip;
- env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
- env[5] = fxsave->foo;
- env[6] = fxsave->fos;
+ BUG_ON(sizeof(*buf) != sizeof(fpregs));
+ n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
+ if (n > 0)
+ return -EFAULT;
- if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
- return 1;
-
- to = &buf->_st[0];
- from = (struct _fpxreg *) &fxsave->st_space[0];
- for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
- if ( __copy_to_user( to, from, sizeof(*to) ) )
- return 1;
- }
- return 0;
+ return restore_fp_registers(userspace_pid[cpu], fpregs);
}
-#endif
-static inline int convert_fxsr_to_user(struct _fpstate __user *buf,
- struct pt_regs *regs)
+int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
{
- return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
-}
+ int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
+ long fpregs[HOST_XFP_SIZE];
-#ifdef CONFIG_MODE_TT
-static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
- struct _fpstate __user *buf)
-{
- struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
- unsigned long env[7];
- struct _fpxreg *to;
- struct _fpreg __user *from;
- int i;
-
- if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
- return 1;
+ BUG_ON(sizeof(*buf) != sizeof(fpregs));
+ err = save_fpx_registers(userspace_pid[cpu], fpregs);
+ if (err)
+ return err;
- fxsave->cwd = (unsigned short)(env[0] & 0xffff);
- fxsave->swd = (unsigned short)(env[1] & 0xffff);
- fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
- fxsave->fip = env[3];
- fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
- fxsave->fcs = (env[4] & 0xffff);
- fxsave->foo = env[5];
- fxsave->fos = env[6];
+ n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
+ if(n > 0)
+ return -EFAULT;
- to = (struct _fpxreg *) &fxsave->st_space[0];
- from = &buf->_st[0];
- for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
- if ( __copy_from_user( to, from, sizeof(*from) ) )
- return 1;
- }
- return 0;
-}
-#endif
-
-static inline int convert_fxsr_from_user(struct pt_regs *regs,
- struct _fpstate __user *buf)
-{
- return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
-}
-
-int get_fpregs(unsigned long buf, struct task_struct *child)
-{
- int err;
-
- err = convert_fxsr_to_user((struct _fpstate __user *) buf,
- &child->thread.regs);
- if(err) return(-EFAULT);
- else return(0);
-}
-
-int set_fpregs(unsigned long buf, struct task_struct *child)
-{
- int err;
-
- err = convert_fxsr_from_user(&child->thread.regs,
- (struct _fpstate __user *) buf);
- if(err) return(-EFAULT);
- else return(0);
-}
-
-#ifdef CONFIG_MODE_TT
-int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
-{
- struct pt_regs *regs = &tsk->thread.regs;
- struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
- int err;
-
- err = __copy_to_user((void __user *) buf, fxsave,
- sizeof(struct user_fxsr_struct));
- if(err) return -EFAULT;
- else return 0;
-}
-#endif
-
-int get_fpxregs(unsigned long buf, struct task_struct *tsk)
-{
- return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
-}
-
-#ifdef CONFIG_MODE_TT
-int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
-{
- struct pt_regs *regs = &tsk->thread.regs;
- struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
- int err;
-
- err = __copy_from_user(fxsave, (void __user *) buf,
- sizeof(struct user_fxsr_struct) );
- if(err) return -EFAULT;
- else return 0;
-}
-#endif
-
-int set_fpxregs(unsigned long buf, struct task_struct *tsk)
-{
- return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
-}
-
-#ifdef notdef
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
-{
- fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
- (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
- fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
- fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
- fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
- fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
- fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
- fpu->fos = 0;
- memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
- sizeof(fpu->st_space));
- return(1);
+ return n;
}
-#endif
-#ifdef CONFIG_MODE_TT
-static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
- struct user_i387_struct *buf)
+int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
{
- struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
- unsigned short *to;
- unsigned short *from;
- int i;
+ int n, cpu = ((struct thread_info *) child->stack)->cpu;
+ long fpregs[HOST_XFP_SIZE];
- memcpy( buf, fpu, 7 * sizeof(long) );
+ BUG_ON(sizeof(*buf) != sizeof(fpregs));
+ n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
+ if (n > 0)
+ return -EFAULT;
- to = (unsigned short *) &buf->st_space[0];
- from = (unsigned short *) &fpu->st_space[0];
- for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
- memcpy( to, from, 5 * sizeof(unsigned short) );
- }
+ return restore_fpx_registers(userspace_pid[cpu], fpregs);
}
-#endif
-static inline void copy_fpu_fxsave(struct pt_regs *regs,
- struct user_i387_struct *buf)
+long subarch_ptrace(struct task_struct *child, long request, long addr,
+ long data)
{
- (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
+ return -EIO;
}
-
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
-{
- copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
- return(1);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 40ff0c831bd..5cf97bc229b 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -1,20 +1,10 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include <stdio.h>
-#include <stddef.h>
#include <errno.h>
-#include <unistd.h>
-#include "ptrace_user.h"
-/* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */
-#include <asm/user.h>
-#include "kern_util.h"
-#include "sysdep/thread.h"
-#include "user.h"
-#include "os.h"
-#include "uml-config.h"
+#include <sys/ptrace.h>
int ptrace_getregs(long pid, unsigned long *regs_out)
{
@@ -43,89 +33,3 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
return -errno;
return 0;
}
-
-#ifdef UML_CONFIG_MODE_TT
-
-static void write_debugregs(int pid, unsigned long *regs)
-{
- struct user *dummy;
- int nregs, i;
-
- dummy = NULL;
- nregs = ARRAY_SIZE(dummy->u_debugreg);
- for(i = 0; i < nregs; i++){
- if((i == 4) || (i == 5)) continue;
- if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
- regs[i]) < 0)
- printk("write_debugregs - ptrace failed on "
- "register %d, value = 0x%lx, errno = %d\n", i,
- regs[i], errno);
- }
-}
-
-static void read_debugregs(int pid, unsigned long *regs)
-{
- struct user *dummy;
- int nregs, i;
-
- dummy = NULL;
- nregs = ARRAY_SIZE(dummy->u_debugreg);
- for(i = 0; i < nregs; i++){
- regs[i] = ptrace(PTRACE_PEEKUSR, pid,
- &dummy->u_debugreg[i], 0);
- }
-}
-
-/* Accessed only by the tracing thread */
-static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
-
-void arch_enter_kernel(void *task, int pid)
-{
- read_debugregs(pid, TASK_DEBUGREGS(task));
- write_debugregs(pid, kernel_debugregs);
-}
-
-void arch_leave_kernel(void *task, int pid)
-{
- read_debugregs(pid, kernel_debugregs);
- write_debugregs(pid, TASK_DEBUGREGS(task));
-}
-
-#ifdef UML_CONFIG_PT_PROXY
-/* Accessed only by the tracing thread */
-static int debugregs_seq;
-
-/* Only called by the ptrace proxy */
-void ptrace_pokeuser(unsigned long addr, unsigned long data)
-{
- if((addr < offsetof(struct user, u_debugreg[0])) ||
- (addr > offsetof(struct user, u_debugreg[7])))
- return;
- addr -= offsetof(struct user, u_debugreg[0]);
- addr = addr >> 2;
- if(kernel_debugregs[addr] == data) return;
-
- kernel_debugregs[addr] = data;
- debugregs_seq++;
-}
-
-static void update_debugregs_cb(void *arg)
-{
- int pid = *((int *) arg);
-
- write_debugregs(pid, kernel_debugregs);
-}
-
-/* Optimized out in its header when not defined */
-void update_debugregs(int seq)
-{
- int me;
-
- if(seq == debugregs_seq) return;
-
- me = os_getpid();
- initial_thread_cb(update_debugregs_cb, &me);
-}
-#endif
-
-#endif
diff --git a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c
deleted file mode 100644
index 467d489c31c..00000000000
--- a/arch/um/sys-i386/sigcontext.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stddef.h>
-#include <string.h>
-#include <asm/ptrace.h>
-#include <asm/sigcontext.h>
-#include "sysdep/ptrace.h"
-#include "kern_util.h"
-
-void sc_to_sc(void *to_ptr, void *from_ptr)
-{
- struct sigcontext *to = to_ptr, *from = from_ptr;
-
- memcpy(to, from, sizeof(*to) + sizeof(struct _fpstate));
- if(from->fpstate != NULL)
- to->fpstate = (struct _fpstate *) (to + 1);
-}
-
-unsigned long *sc_sigmask(void *sc_ptr)
-{
- struct sigcontext *sc = sc_ptr;
- return &sc->oldmask;
-}
-
-int sc_get_fpregs(unsigned long buf, void *sc_ptr)
-{
- struct sigcontext *sc = sc_ptr;
- struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
- int err = 0;
-
- if(from == NULL){
- err |= clear_user_proc(&to->cw, sizeof(to->cw));
- err |= clear_user_proc(&to->sw, sizeof(to->sw));
- err |= clear_user_proc(&to->tag, sizeof(to->tag));
- err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
- err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
- err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
- err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
- err |= clear_user_proc(&to->_st, sizeof(to->_st));
- }
- else {
- err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
- err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
- err |= copy_to_user_proc(&to->tag, &from->tag,
- sizeof(to->tag));
- err |= copy_to_user_proc(&to->ipoff, &from->ipoff,
- sizeof(to->ipoff));
- err |= copy_to_user_proc(&to->cssel,& from->cssel,
- sizeof(to->cssel));
- err |= copy_to_user_proc(&to->dataoff, &from->dataoff,
- sizeof(to->dataoff));
- err |= copy_to_user_proc(&to->datasel, &from->datasel,
- sizeof(to->datasel));
- err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
- }
- return(err);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 1cbf95f6858..0147227ce18 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -1,189 +1,293 @@
/*
- * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/signal.h"
#include "linux/ptrace.h"
-#include "asm/current.h"
-#include "asm/ucontext.h"
-#include "asm/uaccess.h"
#include "asm/unistd.h"
+#include "asm/uaccess.h"
+#include "asm/ucontext.h"
#include "frame_kern.h"
-#include "sigcontext.h"
-#include "registers.h"
-#include "mode.h"
-
-#ifdef CONFIG_MODE_SKAS
-
#include "skas.h"
-void copy_sc(union uml_pt_regs *regs, void *from)
+void copy_sc(struct uml_pt_regs *regs, void *from)
{
struct sigcontext *sc = from;
- REGS_GS(regs->skas.regs) = sc->gs;
- REGS_FS(regs->skas.regs) = sc->fs;
- REGS_ES(regs->skas.regs) = sc->es;
- REGS_DS(regs->skas.regs) = sc->ds;
- REGS_EDI(regs->skas.regs) = sc->edi;
- REGS_ESI(regs->skas.regs) = sc->esi;
- REGS_EBP(regs->skas.regs) = sc->ebp;
- REGS_SP(regs->skas.regs) = sc->esp;
- REGS_EBX(regs->skas.regs) = sc->ebx;
- REGS_EDX(regs->skas.regs) = sc->edx;
- REGS_ECX(regs->skas.regs) = sc->ecx;
- REGS_EAX(regs->skas.regs) = sc->eax;
- REGS_IP(regs->skas.regs) = sc->eip;
- REGS_CS(regs->skas.regs) = sc->cs;
- REGS_EFLAGS(regs->skas.regs) = sc->eflags;
- REGS_SS(regs->skas.regs) = sc->ss;
+ REGS_GS(regs->gp) = sc->gs;
+ REGS_FS(regs->gp) = sc->fs;
+ REGS_ES(regs->gp) = sc->es;
+ REGS_DS(regs->gp) = sc->ds;
+ REGS_EDI(regs->gp) = sc->edi;
+ REGS_ESI(regs->gp) = sc->esi;
+ REGS_EBP(regs->gp) = sc->ebp;
+ REGS_SP(regs->gp) = sc->esp;
+ REGS_EBX(regs->gp) = sc->ebx;
+ REGS_EDX(regs->gp) = sc->edx;
+ REGS_ECX(regs->gp) = sc->ecx;
+ REGS_EAX(regs->gp) = sc->eax;
+ REGS_IP(regs->gp) = sc->eip;
+ REGS_CS(regs->gp) = sc->cs;
+ REGS_EFLAGS(regs->gp) = sc->eflags;
+ REGS_SS(regs->gp) = sc->ss;
}
-static int copy_sc_from_user_skas(struct pt_regs *regs,
- struct sigcontext __user *from)
+/*
+ * FPU tag word conversions.
+ */
+
+static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
{
- struct sigcontext sc;
- unsigned long fpregs[HOST_FP_SIZE];
- int err;
+ unsigned int tmp; /* to avoid 16 bit prefixes in the code */
+
+ /* Transform each pair of bits into 01 (valid) or 00 (empty) */
+ tmp = ~twd;
+ tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
+ /* and move the valid bits to the lower byte. */
+ tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
+ tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
+ tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
+ return tmp;
+}
- err = copy_from_user(&sc, from, sizeof(sc));
- err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
- if(err)
- return err;
+static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave)
+{
+ struct _fpxreg *st = NULL;
+ unsigned long twd = (unsigned long) fxsave->twd;
+ unsigned long tag;
+ unsigned long ret = 0xffff0000;
+ int i;
+
+#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
+
+ for (i = 0; i < 8; i++) {
+ if (twd & 0x1) {
+ st = (struct _fpxreg *) FPREG_ADDR(fxsave, i);
+
+ switch (st->exponent & 0x7fff) {
+ case 0x7fff:
+ tag = 2; /* Special */
+ break;
+ case 0x0000:
+ if ( !st->significand[0] &&
+ !st->significand[1] &&
+ !st->significand[2] &&
+ !st->significand[3] ) {
+ tag = 1; /* Zero */
+ } else {
+ tag = 2; /* Special */
+ }
+ break;
+ default:
+ if (st->significand[3] & 0x8000) {
+ tag = 0; /* Valid */
+ } else {
+ tag = 2; /* Special */
+ }
+ break;
+ }
+ } else {
+ tag = 3; /* Empty */
+ }
+ ret |= (tag << (2 * i));
+ twd = twd >> 1;
+ }
+ return ret;
+}
- copy_sc(&regs->regs, &sc);
+static int convert_fxsr_to_user(struct _fpstate __user *buf,
+ struct user_fxsr_struct *fxsave)
+{
+ unsigned long env[7];
+ struct _fpreg __user *to;
+ struct _fpxreg *from;
+ int i;
+
+ env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
+ env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
+ env[2] = twd_fxsr_to_i387(fxsave);
+ env[3] = fxsave->fip;
+ env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
+ env[5] = fxsave->foo;
+ env[6] = fxsave->fos;
+
+ if (__copy_to_user(buf, env, 7 * sizeof(unsigned long)))
+ return 1;
- err = restore_fp_registers(userspace_pid[0], fpregs);
- if(err < 0) {
- printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
- "errno = %d\n", -err);
- return err;
- }
+ to = &buf->_st[0];
+ from = (struct _fpxreg *) &fxsave->st_space[0];
+ for (i = 0; i < 8; i++, to++, from++) {
+ unsigned long __user *t = (unsigned long __user *)to;
+ unsigned long *f = (unsigned long *)from;
+ if (__put_user(*f, t) ||
+ __put_user(*(f + 1), t + 1) ||
+ __put_user(from->exponent, &to->exponent))
+ return 1;
+ }
return 0;
}
-int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp,
- struct pt_regs *regs, unsigned long sp)
+static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave,
+ struct _fpstate __user *buf)
{
- struct sigcontext sc;
- unsigned long fpregs[HOST_FP_SIZE];
- struct faultinfo * fi = &current->thread.arch.faultinfo;
- int err;
+ unsigned long env[7];
+ struct _fpxreg *to;
+ struct _fpreg __user *from;
+ int i;
- sc.gs = REGS_GS(regs->regs.skas.regs);
- sc.fs = REGS_FS(regs->regs.skas.regs);
- sc.es = REGS_ES(regs->regs.skas.regs);
- sc.ds = REGS_DS(regs->regs.skas.regs);
- sc.edi = REGS_EDI(regs->regs.skas.regs);
- sc.esi = REGS_ESI(regs->regs.skas.regs);
- sc.ebp = REGS_EBP(regs->regs.skas.regs);
- sc.esp = sp;
- sc.ebx = REGS_EBX(regs->regs.skas.regs);
- sc.edx = REGS_EDX(regs->regs.skas.regs);
- sc.ecx = REGS_ECX(regs->regs.skas.regs);
- sc.eax = REGS_EAX(regs->regs.skas.regs);
- sc.eip = REGS_IP(regs->regs.skas.regs);
- sc.cs = REGS_CS(regs->regs.skas.regs);
- sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
- sc.esp_at_signal = regs->regs.skas.regs[UESP];
- sc.ss = regs->regs.skas.regs[SS];
- sc.cr2 = fi->cr2;
- sc.err = fi->error_code;
- sc.trapno = fi->trap_no;
-
- err = save_fp_registers(userspace_pid[0], fpregs);
- if(err < 0){
- printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
- "errno = %d\n", err);
+ if (copy_from_user( env, buf, 7 * sizeof(long)))
return 1;
- }
- to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
- sc.fpstate = to_fp;
- if(err)
- return err;
-
- return copy_to_user(to, &sc, sizeof(sc)) ||
- copy_to_user(to_fp, fpregs, sizeof(fpregs));
+ fxsave->cwd = (unsigned short)(env[0] & 0xffff);
+ fxsave->swd = (unsigned short)(env[1] & 0xffff);
+ fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
+ fxsave->fip = env[3];
+ fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
+ fxsave->fcs = (env[4] & 0xffff);
+ fxsave->foo = env[5];
+ fxsave->fos = env[6];
+
+ to = (struct _fpxreg *) &fxsave->st_space[0];
+ from = &buf->_st[0];
+ for (i = 0; i < 8; i++, to++, from++) {
+ unsigned long *t = (unsigned long *)to;
+ unsigned long __user *f = (unsigned long __user *)from;
+
+ if (__get_user(*t, f) ||
+ __get_user(*(t + 1), f + 1) ||
+ __get_user(to->exponent, &from->exponent))
+ return 1;
+ }
+ return 0;
}
-#endif
-#ifdef CONFIG_MODE_TT
+extern int have_fpx_regs;
-/* These copy a sigcontext to/from userspace. They copy the fpstate pointer,
- * blowing away the old, good one. So, that value is saved, and then restored
- * after the sigcontext copy. In copy_from, the variable holding the saved
- * fpstate pointer, and the sigcontext that it should be restored to are both
- * in the kernel, so we can just restore using an assignment. In copy_to, the
- * saved pointer is in the kernel, but the sigcontext is in userspace, so we
- * copy_to_user it.
- */
-int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
- int fpsize)
+static int copy_sc_from_user(struct pt_regs *regs,
+ struct sigcontext __user *from)
{
- struct _fpstate *to_fp;
- struct _fpstate __user *from_fp;
- unsigned long sigs;
+ struct sigcontext sc;
int err;
- to_fp = to->fpstate;
- sigs = to->oldmask;
- err = copy_from_user(to, from, sizeof(*to));
- from_fp = to->fpstate;
- to->oldmask = sigs;
- to->fpstate = to_fp;
- if(to_fp != NULL)
- err |= copy_from_user(to_fp, from_fp, fpsize);
- return err;
+ err = copy_from_user(&sc, from, sizeof(sc));
+ if (err)
+ return err;
+
+ copy_sc(&regs->regs, &sc);
+ if (have_fpx_regs) {
+ struct user_fxsr_struct fpx;
+
+ err = copy_from_user(&fpx, &sc.fpstate->_fxsr_env[0],
+ sizeof(struct user_fxsr_struct));
+ if (err)
+ return 1;
+
+ err = convert_fxsr_from_user(&fpx, sc.fpstate);
+ if (err)
+ return 1;
+
+ err = restore_fpx_registers(userspace_pid[current_thread->cpu],
+ (unsigned long *) &fpx);
+ if (err < 0) {
+ printk(KERN_ERR "copy_sc_from_user - "
+ "restore_fpx_registers failed, errno = %d\n",
+ -err);
+ return 1;
+ }
+ }
+ else {
+ struct user_i387_struct fp;
+
+ err = copy_from_user(&fp, sc.fpstate,
+ sizeof(struct user_i387_struct));
+ if (err)
+ return 1;
+
+ err = restore_fp_registers(userspace_pid[current_thread->cpu],
+ (unsigned long *) &fp);
+ if (err < 0) {
+ printk(KERN_ERR "copy_sc_from_user - "
+ "restore_fp_registers failed, errno = %d\n",
+ -err);
+ return 1;
+ }
+ }
+
+ return 0;
}
-int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
- struct sigcontext *from, int fpsize, unsigned long sp)
+static int copy_sc_to_user(struct sigcontext __user *to,
+ struct _fpstate __user *to_fp, struct pt_regs *regs,
+ unsigned long sp)
{
- struct _fpstate __user *to_fp;
- struct _fpstate *from_fp;
+ struct sigcontext sc;
+ struct faultinfo * fi = &current->thread.arch.faultinfo;
int err;
- to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
- from_fp = from->fpstate;
- err = copy_to_user(to, from, sizeof(*to));
+ sc.gs = REGS_GS(regs->regs.gp);
+ sc.fs = REGS_FS(regs->regs.gp);
+ sc.es = REGS_ES(regs->regs.gp);
+ sc.ds = REGS_DS(regs->regs.gp);
+ sc.edi = REGS_EDI(regs->regs.gp);
+ sc.esi = REGS_ESI(regs->regs.gp);
+ sc.ebp = REGS_EBP(regs->regs.gp);
+ sc.esp = sp;
+ sc.ebx = REGS_EBX(regs->regs.gp);
+ sc.edx = REGS_EDX(regs->regs.gp);
+ sc.ecx = REGS_ECX(regs->regs.gp);
+ sc.eax = REGS_EAX(regs->regs.gp);
+ sc.eip = REGS_IP(regs->regs.gp);
+ sc.cs = REGS_CS(regs->regs.gp);
+ sc.eflags = REGS_EFLAGS(regs->regs.gp);
+ sc.esp_at_signal = regs->regs.gp[UESP];
+ sc.ss = regs->regs.gp[SS];
+ sc.cr2 = fi->cr2;
+ sc.err = fi->error_code;
+ sc.trapno = fi->trap_no;
- /* The SP in the sigcontext is the updated one for the signal
- * delivery. The sp passed in is the original, and this needs
- * to be restored, so we stick it in separately.
- */
- err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
+ to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
+ sc.fpstate = to_fp;
- if(from_fp != NULL){
- err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
- err |= copy_to_user(to_fp, from_fp, fpsize);
+ if (have_fpx_regs) {
+ struct user_fxsr_struct fpx;
+
+ err = save_fpx_registers(userspace_pid[current_thread->cpu],
+ (unsigned long *) &fpx);
+ if (err < 0){
+ printk(KERN_ERR "copy_sc_to_user - save_fpx_registers "
+ "failed, errno = %d\n", err);
+ return 1;
+ }
+
+ err = convert_fxsr_to_user(to_fp, &fpx);
+ if (err)
+ return 1;
+
+ err |= __put_user(fpx.swd, &to_fp->status);
+ err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic);
+ if (err)
+ return 1;
+
+ if (copy_to_user(&to_fp->_fxsr_env[0], &fpx,
+ sizeof(struct user_fxsr_struct)))
+ return 1;
}
- return err;
-}
-#endif
-
-static int copy_sc_from_user(struct pt_regs *to, void __user *from)
-{
- int ret;
+ else {
+ struct user_i387_struct fp;
- ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
- sizeof(struct _fpstate)),
- copy_sc_from_user_skas(to, from));
- return ret;
-}
+ err = save_fp_registers(userspace_pid[current_thread->cpu],
+ (unsigned long *) &fp);
+ if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct)))
+ return 1;
+ }
-static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp,
- struct pt_regs *from, unsigned long sp)
-{
- return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
- sizeof(*fp), sp),
- copy_sc_to_user_skas(to, fp, from, sp));
+ return copy_to_user(to, &sc, sizeof(sc));
}
-static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
- sigset_t *set, unsigned long sp)
+static int copy_ucontext_to_user(struct ucontext __user *uc,
+ struct _fpstate __user *fp, sigset_t *set,
+ unsigned long sp)
{
int err = 0;
@@ -233,7 +337,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
return 1;
restorer = frame->retcode;
- if(ka->sa.sa_flags & SA_RESTORER)
+ if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
/* Update SP now because the page fault handler refuses to extend
@@ -265,7 +369,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
- if(err)
+ if (err)
goto err;
PT_REGS_SP(regs) = (unsigned long) frame;
@@ -298,7 +402,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
return 1;
restorer = frame->retcode;
- if(ka->sa.sa_flags & SA_RESTORER)
+ if (ka->sa.sa_flags & SA_RESTORER)
restorer = ka->sa.sa_restorer;
/* See comment above about why this is here */
@@ -323,7 +427,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
- if(err)
+ if (err)
goto err;
PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -350,8 +454,8 @@ long sys_sigreturn(struct pt_regs regs)
unsigned long __user *extramask = frame->extramask;
int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
- if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
- copy_from_user(&set.sig[1], extramask, sig_size))
+ if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
+ copy_from_user(&set.sig[1], extramask, sig_size))
goto segfault;
sigdelsetmask(&set, ~_BLOCKABLE);
@@ -361,7 +465,7 @@ long sys_sigreturn(struct pt_regs regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if(copy_sc_from_user(&current->thread.regs, sc))
+ if (copy_sc_from_user(&current->thread.regs, sc))
goto segfault;
/* Avoid ERESTART handling */
@@ -376,12 +480,13 @@ long sys_sigreturn(struct pt_regs regs)
long sys_rt_sigreturn(struct pt_regs regs)
{
unsigned long sp = PT_REGS_SP(&current->thread.regs);
- struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4);
+ struct rt_sigframe __user *frame =
+ (struct rt_sigframe __user *) (sp - 4);
sigset_t set;
struct ucontext __user *uc = &frame->uc;
int sig_size = _NSIG_WORDS * sizeof(unsigned long);
- if(copy_from_user(&set, &uc->uc_sigmask, sig_size))
+ if (copy_from_user(&set, &uc->uc_sigmask, sig_size))
goto segfault;
sigdelsetmask(&set, ~_BLOCKABLE);
@@ -391,7 +496,7 @@ long sys_rt_sigreturn(struct pt_regs regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
+ if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
goto segfault;
/* Avoid ERESTART handling */
diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S
index 6a70d9ab5c2..e730772c401 100644
--- a/arch/um/sys-i386/stub.S
+++ b/arch/um/sys-i386/stub.S
@@ -1,4 +1,5 @@
#include "uml-config.h"
+#include "as-layout.h"
.globl syscall_stub
.section .__syscall_stub, "x"
@@ -6,7 +7,7 @@
.globl batch_syscall_stub
batch_syscall_stub:
/* load pointer to first operation */
- mov $(UML_CONFIG_STUB_DATA+8), %esp
+ mov $(ASM_STUB_DATA+8), %esp
again:
/* load length of additional data */
@@ -14,12 +15,12 @@ again:
/* if(length == 0) : end of list */
/* write possible 0 to header */
- mov %eax, UML_CONFIG_STUB_DATA+4
+ mov %eax, ASM_STUB_DATA+4
cmpl $0, %eax
jz done
/* save current pointer */
- mov %esp, UML_CONFIG_STUB_DATA+4
+ mov %esp, ASM_STUB_DATA+4
/* skip additional data */
add %eax, %esp
@@ -45,7 +46,7 @@ again:
done:
/* save return value */
- mov %eax, UML_CONFIG_STUB_DATA
+ mov %eax, ASM_STUB_DATA
/* stop */
int3
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
index 2355dc19c46..b3999cb76bf 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -6,6 +6,7 @@
#include <signal.h>
#include <sys/select.h> /* The only way I can see to get sigset_t */
#include <asm/unistd.h>
+#include "as-layout.h"
#include "uml-config.h"
#include "sysdep/stub.h"
#include "sysdep/sigcontext.h"
@@ -17,8 +18,7 @@ stub_segv_handler(int sig)
struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
int pid;
- GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
- sc);
+ GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc);
pid = stub_syscall0(__NR_getpid);
stub_syscall2(__NR_kill, pid, SIGUSR1);
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 710d5fb807e..e2d14268441 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -5,7 +5,7 @@
#include "linux/sched.h"
#include "linux/shm.h"
-#include "asm/ipc.h"
+#include "linux/ipc.h"
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "asm/unistd.h"
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index fea8e5e15cc..b02266ab5c5 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -3,25 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/kernel.h"
+#include "linux/percpu.h"
#include "linux/sched.h"
-#include "linux/slab.h"
-#include "linux/types.h"
#include "asm/uaccess.h"
-#include "asm/ptrace.h"
-#include "asm/segment.h"
-#include "asm/smp.h"
-#include "asm/desc.h"
-#include "choose-mode.h"
-#include "kern.h"
-#include "kern_util.h"
-#include "mode_kern.h"
#include "os.h"
-#include "mode.h"
-
-#ifdef CONFIG_MODE_SKAS
#include "skas.h"
-#endif
+#include "sysdep/tls.h"
/*
* If needed we can detect when it's uninitialized.
@@ -31,8 +18,7 @@
static int host_supports_tls = -1;
int host_gdt_entry_tls_min;
-#ifdef CONFIG_MODE_SKAS
-int do_set_thread_area_skas(struct user_desc *info)
+int do_set_thread_area(struct user_desc *info)
{
int ret;
u32 cpu;
@@ -43,7 +29,7 @@ int do_set_thread_area_skas(struct user_desc *info)
return ret;
}
-int do_get_thread_area_skas(struct user_desc *info)
+int do_get_thread_area(struct user_desc *info)
{
int ret;
u32 cpu;
@@ -53,7 +39,6 @@ int do_get_thread_area_skas(struct user_desc *info)
put_cpu();
return ret;
}
-#endif
/*
* sys_get_thread_area: get a yet unused TLS descriptor index.
@@ -82,7 +67,8 @@ static inline void clear_user_desc(struct user_desc* info)
/* Postcondition: LDT_empty(info) returns true. */
memset(info, 0, sizeof(*info));
- /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
+ /*
+ * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
* indeed an empty user_desc.
*/
info->read_exec_only = 1;
@@ -97,10 +83,13 @@ static int load_TLS(int flags, struct task_struct *to)
int idx;
for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) {
- struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
+ struct uml_tls_struct* curr =
+ &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
- /* Actually, now if it wasn't flushed it gets cleared and
- * flushed to the host, which will clear it.*/
+ /*
+ * Actually, now if it wasn't flushed it gets cleared and
+ * flushed to the host, which will clear it.
+ */
if (!curr->present) {
if (!curr->flushed) {
clear_user_desc(&curr->tls);
@@ -124,7 +113,8 @@ out:
return ret;
}
-/* Verify if we need to do a flush for the new process, i.e. if there are any
+/*
+ * Verify if we need to do a flush for the new process, i.e. if there are any
* present desc's, only if they haven't been flushed.
*/
static inline int needs_TLS_update(struct task_struct *task)
@@ -133,10 +123,13 @@ static inline int needs_TLS_update(struct task_struct *task)
int ret = 0;
for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
- struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
+ struct uml_tls_struct* curr =
+ &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
- /* Can't test curr->present, we may need to clear a descriptor
- * which had a value. */
+ /*
+ * Can't test curr->present, we may need to clear a descriptor
+ * which had a value.
+ */
if (curr->flushed)
continue;
ret = 1;
@@ -145,7 +138,8 @@ static inline int needs_TLS_update(struct task_struct *task)
return ret;
}
-/* On a newly forked process, the TLS descriptors haven't yet been flushed. So
+/*
+ * On a newly forked process, the TLS descriptors haven't yet been flushed. So
* we mark them as such and the first switch_to will do the job.
*/
void clear_flushed_tls(struct task_struct *task)
@@ -153,10 +147,13 @@ void clear_flushed_tls(struct task_struct *task)
int i;
for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
- struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
+ struct uml_tls_struct* curr =
+ &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
- /* Still correct to do this, if it wasn't present on the host it
- * will remain as flushed as it was. */
+ /*
+ * Still correct to do this, if it wasn't present on the host it
+ * will remain as flushed as it was.
+ */
if (!curr->present)
continue;
@@ -164,40 +161,33 @@ void clear_flushed_tls(struct task_struct *task)
}
}
-/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
+/*
+ * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
* common host process. So this is needed in SKAS0 too.
*
* However, if each thread had a different host process (and this was discussed
* for SMP support) this won't be needed.
*
* And this will not need be used when (and if) we'll add support to the host
- * SKAS patch. */
+ * SKAS patch.
+ */
-int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to)
+int arch_switch_tls(struct task_struct *from, struct task_struct *to)
{
if (!host_supports_tls)
return 0;
- /* We have no need whatsoever to switch TLS for kernel threads; beyond
+ /*
+ * We have no need whatsoever to switch TLS for kernel threads; beyond
* that, that would also result in us calling os_set_thread_area with
- * userspace_pid[cpu] == 0, which gives an error. */
+ * userspace_pid[cpu] == 0, which gives an error.
+ */
if (likely(to->mm))
return load_TLS(O_FORCE, to);
return 0;
}
-int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to)
-{
- if (!host_supports_tls)
- return 0;
-
- if (needs_TLS_update(to))
- return load_TLS(0, to);
-
- return 0;
-}
-
static int set_tls_entry(struct task_struct* task, struct user_desc *info,
int idx, int flushed)
{
@@ -251,17 +241,20 @@ static int get_tls_entry(struct task_struct* task, struct user_desc *info, int i
*info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls;
out:
- /* Temporary debugging check, to make sure that things have been
+ /*
+ * Temporary debugging check, to make sure that things have been
* flushed. This could be triggered if load_TLS() failed.
*/
- if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
+ if (unlikely(task == current &&
+ !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
printk(KERN_ERR "get_tls_entry: task with pid %d got here "
"without flushed TLS.", current->pid);
}
return 0;
clear:
- /* When the TLS entry has not been set, the values read to user in the
+ /*
+ * When the TLS entry has not been set, the values read to user in the
* tls_array are 0 (because it's cleared at boot, see
* arch/i386/kernel/head.S:cpu_gdt_table). Emulate that.
*/
@@ -293,7 +286,7 @@ asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc)
return -EFAULT;
}
- ret = CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, &info);
+ ret = do_set_thread_area(&info);
if (ret)
return ret;
return set_tls_entry(current, &info, idx, 1);
@@ -363,8 +356,10 @@ out:
}
-/* XXX: This part is probably common to i386 and x86-64. Don't create a common
- * file for now, do that when implementing x86-64 support.*/
+/*
+ * XXX: This part is probably common to i386 and x86-64. Don't create a common
+ * file for now, do that when implementing x86-64 support.
+ */
static int __init __setup_host_supports_tls(void)
{
check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
deleted file mode 100644
index 1b0ad0e4adc..00000000000
--- a/arch/um/sys-i386/unmap.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <linux/mman.h>
-#include <asm/unistd.h>
-
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
-int switcheroo(int fd, int prot, void *from, void *to, int size)
-{
- if(munmap(to, size) < 0){
- return(-1);
- }
- if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
- return(-1);
- }
- if(munmap(from, size) < 0){
- return(-1);
- }
- return(0);
-}
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 29118cf5ff2..514241526a1 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -2,9 +2,9 @@
#include <stddef.h>
#include <signal.h>
#include <sys/poll.h>
+#include <sys/user.h>
#include <sys/mman.h>
#include <asm/ptrace.h>
-#include <asm/user.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -48,8 +48,8 @@ void foo(void)
OFFSET(HOST_SC_FP_ST, _fpstate, _st);
OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
- DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
- DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));
+ DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
+ DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
DEFINE(HOST_IP, EIP);
DEFINE(HOST_SP, UESP);
diff --git a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
index af200268fdd..a9814a7ae60 100644
--- a/arch/um/sys-ppc/Makefile
+++ b/arch/um/sys-ppc/Makefile
@@ -1,7 +1,7 @@
OBJ = built-in.o
.S.o:
- $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
+ $(CC) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
ptrace_user.o sysrq.o
@@ -57,13 +57,13 @@ ppc_defs.h: mk_defs.c ppc_defs.head \
checksum.o: checksum.S
rm -f asm
ln -s $(TOPDIR)/include/asm-ppc asm
- $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
+ $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
rm -f asm
misc.o: misc.S ppc_defs.h
rm -f asm
ln -s $(TOPDIR)/include/asm-ppc asm
- $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
+ $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
rm -f asm
clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index ea8185d8540..3c22de53208 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,10 +5,9 @@
#
obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
- setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \
- ksyms.o tls.o
+ setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
+ sysrq.o ksyms.o tls.o
-obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
obj-$(CONFIG_MODULES) += um_module.o
subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
@@ -16,16 +15,12 @@ subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o
ldt-y = ../sys-i386/ldt.o
-USER_OBJS := ptrace_user.o sigcontext.o
+USER_OBJS := ptrace_user.o
USER_OBJS += user-offsets.s
extra-y += user-offsets.s
-extra-$(CONFIG_MODE_TT) += unmap.o
-
UNPROFILE_OBJS := stub_segv.o
CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
include arch/um/scripts/Makefile.rules
-
-$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
index 09547889037..506b6765bbc 100644
--- a/arch/um/sys-x86_64/bugs.c
+++ b/arch/um/sys-x86_64/bugs.c
@@ -14,7 +14,7 @@ void arch_check_bugs(void)
{
}
-int arch_handle_signal(int sig, union uml_pt_regs *regs)
+int arch_handle_signal(int sig, struct uml_pt_regs *regs)
{
return 0;
}
diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c
index 4636b1465b6..ce85117fc64 100644
--- a/arch/um/sys-x86_64/fault.c
+++ b/arch/um/sys-x86_64/fault.c
@@ -14,14 +14,15 @@ struct exception_table_entry
};
const struct exception_table_entry *search_exception_tables(unsigned long add);
-int arch_fixup(unsigned long address, union uml_pt_regs *regs)
+
+int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
{
const struct exception_table_entry *fixup;
fixup = search_exception_tables(address);
- if(fixup != 0){
+ if (fixup != 0) {
UPT_IP(regs) = fixup->fixup;
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 1970d78aa52..a3cfeed17af 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -1,5 +1,6 @@
/*
* Copyright 2003 PathScale, Inc.
+ * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*
* Licensed under the GPL
*/
@@ -12,17 +13,10 @@
#include <asm/uaccess.h>
#include <asm/elf.h>
-/* XXX x86_64 */
-unsigned long not_ss;
-unsigned long not_ds;
-unsigned long not_es;
-
-#define SC_SS(r) (not_ss)
-#define SC_DS(r) (not_ds)
-#define SC_ES(r) (not_es)
-
-/* determines which flags the user has access to. */
-/* 1 = access 0 = no access */
+/*
+ * determines which flags the user has access to.
+ * 1 = access 0 = no access
+ */
#define FLAG_MASK 0x44dd5UL
int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -66,20 +60,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
int poke_user(struct task_struct *child, long addr, long data)
{
- if ((addr & 3) || addr < 0)
- return -EIO;
-
- if (addr < MAX_REG_OFFSET)
- return putreg(child, addr, data);
- else if((addr >= offsetof(struct user, u_debugreg[0])) &&
- (addr <= offsetof(struct user, u_debugreg[7]))){
- addr -= offsetof(struct user, u_debugreg[0]);
- addr = addr >> 2;
- if((addr == 4) || (addr == 5)) return -EIO;
- child->thread.arch.debugregs[addr] = data;
- return 0;
- }
- return -EIO;
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ if (addr < MAX_REG_OFFSET)
+ return putreg(child, addr, data);
+ else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ if ((addr == 4) || (addr == 5))
+ return -EIO;
+ child->thread.arch.debugregs[addr] = data;
+ return 0;
+ }
+ return -EIO;
}
unsigned long getreg(struct task_struct *child, int regno)
@@ -107,29 +102,22 @@ unsigned long getreg(struct task_struct *child, int regno)
int peek_user(struct task_struct *child, long addr, long data)
{
/* read the word at location addr in the USER area. */
- unsigned long tmp;
-
- if ((addr & 3) || addr < 0)
- return -EIO;
-
- tmp = 0; /* Default return condition */
- if(addr < MAX_REG_OFFSET){
- tmp = getreg(child, addr);
- }
- else if((addr >= offsetof(struct user, u_debugreg[0])) &&
- (addr <= offsetof(struct user, u_debugreg[7]))){
- addr -= offsetof(struct user, u_debugreg[0]);
- addr = addr >> 2;
- tmp = child->thread.arch.debugregs[addr];
- }
- return put_user(tmp, (unsigned long *) data);
-}
+ unsigned long tmp;
-void arch_switch(void)
-{
-/* XXX
- printk("arch_switch\n");
-*/
+ if ((addr & 3) || addr < 0)
+ return -EIO;
+
+ tmp = 0; /* Default return condition */
+ if (addr < MAX_REG_OFFSET){
+ tmp = getreg(child, addr);
+ }
+ else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
+ (addr <= offsetof(struct user, u_debugreg[7]))){
+ addr -= offsetof(struct user, u_debugreg[0]);
+ addr = addr >> 2;
+ tmp = child->thread.arch.debugregs[addr];
+ }
+ return put_user(tmp, (unsigned long *) data);
}
/* XXX Mostly copied from sys-i386 */
@@ -139,54 +127,68 @@ int is_syscall(unsigned long addr)
int n;
n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
- if(n){
+ if (n){
/* access_process_vm() grants access to vsyscall and stub,
* while copy_from_user doesn't. Maybe access_process_vm is
* slow, but that doesn't matter, since it will be called only
* in case of singlestepping, if copy_from_user failed.
*/
n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
- if(n != sizeof(instr)) {
+ if (n != sizeof(instr)) {
printk("is_syscall : failed to read instruction from "
"0x%lx\n", addr);
- return(1);
+ return 1;
}
}
/* sysenter */
- return(instr == 0x050f);
+ return instr == 0x050f;
}
-int get_fpregs(unsigned long buf, struct task_struct *child)
+int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
- panic("get_fpregs");
- return(0);
-}
+ int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
+ long fpregs[HOST_FP_SIZE];
-int set_fpregs(unsigned long buf, struct task_struct *child)
-{
- panic("set_fpregs");
- return(0);
+ BUG_ON(sizeof(*buf) != sizeof(fpregs));
+ err = save_fp_registers(userspace_pid[cpu], fpregs);
+ if (err)
+ return err;
+
+ n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
+ if(n > 0)
+ return -EFAULT;
+
+ return n;
}
-int get_fpxregs(unsigned long buf, struct task_struct *tsk)
+int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
- panic("get_fpxregs");
- return(0);
+ int n, cpu = ((struct thread_info *) child->stack)->cpu;
+ long fpregs[HOST_FP_SIZE];
+
+ BUG_ON(sizeof(*buf) != sizeof(fpregs));
+ n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
+ if (n > 0)
+ return -EFAULT;
+
+ return restore_fp_registers(userspace_pid[cpu], fpregs);
}
-int set_fpxregs(unsigned long buf, struct task_struct *tsk)
+long subarch_ptrace(struct task_struct *child, long request, long addr,
+ long data)
{
- panic("set_fxpregs");
- return(0);
-}
+ int ret = -EIO;
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+ switch (request) {
+ case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+ ret = get_fpregs((struct user_i387_struct __user *) data,
+ child);
+ break;
+ case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+ ret = set_fpregs((struct user_i387_struct __user *) data,
+ child);
+ break;
+ }
+
+ return ret;
+}
diff --git a/arch/um/sys-x86_64/sigcontext.c b/arch/um/sys-x86_64/sigcontext.c
deleted file mode 100644
index c88e64def6f..00000000000
--- a/arch/um/sys-x86_64/sigcontext.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include "user.h"
-
-void sc_to_sc(void *to_ptr, void *from_ptr)
-{
- struct sigcontext *to = to_ptr, *from = from_ptr;
- int size = sizeof(*to); /* + sizeof(struct _fpstate); */
-
- memcpy(to, from, size);
- if(from->fpstate != NULL)
- to->fpstate = (struct _fpstate *) (to + 1);
-
- to->fpstate = NULL;
-}
-
-unsigned long *sc_sigmask(void *sc_ptr)
-{
- struct sigcontext *sc = sc_ptr;
-
- return(&sc->oldmask);
-}
-
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index fe8ec04d35b..1778d33808f 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -1,111 +1,121 @@
/*
* Copyright (C) 2003 PathScale, Inc.
+ * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
-#include "linux/stddef.h"
-#include "linux/errno.h"
#include "linux/personality.h"
#include "linux/ptrace.h"
-#include "asm/current.h"
+#include "asm/unistd.h"
#include "asm/uaccess.h"
-#include "asm/sigcontext.h"
-#include "asm/ptrace.h"
-#include "asm/arch/ucontext.h"
-#include "choose-mode.h"
-#include "sysdep/ptrace.h"
+#include "asm/ucontext.h"
#include "frame_kern.h"
-
-#ifdef CONFIG_MODE_SKAS
-
#include "skas.h"
-void copy_sc(union uml_pt_regs *regs, void *from)
+void copy_sc(struct uml_pt_regs *regs, void *from)
{
struct sigcontext *sc = from;
-#define GETREG(regs, regno, sc, regname) \
- (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname
-
- GETREG(regs, R8, sc, r8);
- GETREG(regs, R9, sc, r9);
- GETREG(regs, R10, sc, r10);
- GETREG(regs, R11, sc, r11);
- GETREG(regs, R12, sc, r12);
- GETREG(regs, R13, sc, r13);
- GETREG(regs, R14, sc, r14);
- GETREG(regs, R15, sc, r15);
- GETREG(regs, RDI, sc, rdi);
- GETREG(regs, RSI, sc, rsi);
- GETREG(regs, RBP, sc, rbp);
- GETREG(regs, RBX, sc, rbx);
- GETREG(regs, RDX, sc, rdx);
- GETREG(regs, RAX, sc, rax);
- GETREG(regs, RCX, sc, rcx);
- GETREG(regs, RSP, sc, rsp);
- GETREG(regs, RIP, sc, rip);
- GETREG(regs, EFLAGS, sc, eflags);
- GETREG(regs, CS, sc, cs);
+#define GETREG(regs, regno, sc, regname) \
+ (regs)->gp[(regno) / sizeof(unsigned long)] = (sc)->regname
+
+ GETREG(regs, R8, sc, r8);
+ GETREG(regs, R9, sc, r9);
+ GETREG(regs, R10, sc, r10);
+ GETREG(regs, R11, sc, r11);
+ GETREG(regs, R12, sc, r12);
+ GETREG(regs, R13, sc, r13);
+ GETREG(regs, R14, sc, r14);
+ GETREG(regs, R15, sc, r15);
+ GETREG(regs, RDI, sc, rdi);
+ GETREG(regs, RSI, sc, rsi);
+ GETREG(regs, RBP, sc, rbp);
+ GETREG(regs, RBX, sc, rbx);
+ GETREG(regs, RDX, sc, rdx);
+ GETREG(regs, RAX, sc, rax);
+ GETREG(regs, RCX, sc, rcx);
+ GETREG(regs, RSP, sc, rsp);
+ GETREG(regs, RIP, sc, rip);
+ GETREG(regs, EFLAGS, sc, eflags);
+ GETREG(regs, CS, sc, cs);
#undef GETREG
}
-static int copy_sc_from_user_skas(struct pt_regs *regs,
- struct sigcontext __user *from)
+static int copy_sc_from_user(struct pt_regs *regs,
+ struct sigcontext __user *from,
+ struct _fpstate __user *fpp)
{
- int err = 0;
-
-#define GETREG(regs, regno, sc, regname) \
- __get_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
- &(sc)->regname)
-
- err |= GETREG(regs, R8, from, r8);
- err |= GETREG(regs, R9, from, r9);
- err |= GETREG(regs, R10, from, r10);
- err |= GETREG(regs, R11, from, r11);
- err |= GETREG(regs, R12, from, r12);
- err |= GETREG(regs, R13, from, r13);
- err |= GETREG(regs, R14, from, r14);
- err |= GETREG(regs, R15, from, r15);
- err |= GETREG(regs, RDI, from, rdi);
- err |= GETREG(regs, RSI, from, rsi);
- err |= GETREG(regs, RBP, from, rbp);
- err |= GETREG(regs, RBX, from, rbx);
- err |= GETREG(regs, RDX, from, rdx);
- err |= GETREG(regs, RAX, from, rax);
- err |= GETREG(regs, RCX, from, rcx);
- err |= GETREG(regs, RSP, from, rsp);
- err |= GETREG(regs, RIP, from, rip);
- err |= GETREG(regs, EFLAGS, from, eflags);
- err |= GETREG(regs, CS, from, cs);
+ struct user_i387_struct fp;
+ int err = 0;
+
+#define GETREG(regs, regno, sc, regname) \
+ __get_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \
+ &(sc)->regname)
+
+ err |= GETREG(regs, R8, from, r8);
+ err |= GETREG(regs, R9, from, r9);
+ err |= GETREG(regs, R10, from, r10);
+ err |= GETREG(regs, R11, from, r11);
+ err |= GETREG(regs, R12, from, r12);
+ err |= GETREG(regs, R13, from, r13);
+ err |= GETREG(regs, R14, from, r14);
+ err |= GETREG(regs, R15, from, r15);
+ err |= GETREG(regs, RDI, from, rdi);
+ err |= GETREG(regs, RSI, from, rsi);
+ err |= GETREG(regs, RBP, from, rbp);
+ err |= GETREG(regs, RBX, from, rbx);
+ err |= GETREG(regs, RDX, from, rdx);
+ err |= GETREG(regs, RAX, from, rax);
+ err |= GETREG(regs, RCX, from, rcx);
+ err |= GETREG(regs, RSP, from, rsp);
+ err |= GETREG(regs, RIP, from, rip);
+ err |= GETREG(regs, EFLAGS, from, eflags);
+ err |= GETREG(regs, CS, from, cs);
+ if (err)
+ return 1;
#undef GETREG
- return err;
+ err = copy_from_user(&fp, fpp, sizeof(struct user_i387_struct));
+ if (err)
+ return 1;
+
+ err = restore_fp_registers(userspace_pid[current_thread->cpu],
+ (unsigned long *) &fp);
+ if (err < 0) {
+ printk(KERN_ERR "copy_sc_from_user - "
+ "restore_fp_registers failed, errno = %d\n",
+ -err);
+ return 1;
+ }
+
+ return 0;
}
-int copy_sc_to_user_skas(struct sigcontext __user *to,
- struct _fpstate __user *to_fp,
- struct pt_regs *regs, unsigned long mask,
- unsigned long sp)
+static int copy_sc_to_user(struct sigcontext __user *to,
+ struct _fpstate __user *to_fp, struct pt_regs *regs,
+ unsigned long mask, unsigned long sp)
{
- struct faultinfo * fi = &current->thread.arch.faultinfo;
+ struct faultinfo * fi = &current->thread.arch.faultinfo;
+ struct user_i387_struct fp;
int err = 0;
err |= __put_user(0, &to->gs);
err |= __put_user(0, &to->fs);
-#define PUTREG(regs, regno, sc, regname) \
- __put_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
- &(sc)->regname)
+#define PUTREG(regs, regno, sc, regname) \
+ __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \
+ &(sc)->regname)
err |= PUTREG(regs, RDI, to, rdi);
err |= PUTREG(regs, RSI, to, rsi);
err |= PUTREG(regs, RBP, to, rbp);
- /* Must use orignal RSP, which is passed in, rather than what's in
- * the pt_regs, because that's already been updated to point at the
- * signal frame.
- */
+ /*
+ * Must use orignal RSP, which is passed in, rather than what's in
+ * the pt_regs, because that's already been updated to point at the
+ * signal frame.
+ */
err |= __put_user(sp, &to->rsp);
err |= PUTREG(regs, RBX, to, rbx);
err |= PUTREG(regs, RDX, to, rdx);
@@ -121,91 +131,38 @@ int copy_sc_to_user_skas(struct sigcontext __user *to,
err |= PUTREG(regs, R15, to, r15);
err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
- err |= __put_user(fi->cr2, &to->cr2);
- err |= __put_user(fi->error_code, &to->err);
- err |= __put_user(fi->trap_no, &to->trapno);
+ err |= __put_user(fi->cr2, &to->cr2);
+ err |= __put_user(fi->error_code, &to->err);
+ err |= __put_user(fi->trap_no, &to->trapno);
err |= PUTREG(regs, RIP, to, rip);
err |= PUTREG(regs, EFLAGS, to, eflags);
#undef PUTREG
err |= __put_user(mask, &to->oldmask);
-
- return(err);
-}
-
-#endif
-
-#ifdef CONFIG_MODE_TT
-int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
- int fpsize)
-{
- struct _fpstate *to_fp;
- struct _fpstate __user *from_fp;
- unsigned long sigs;
- int err;
-
- to_fp = to->fpstate;
- sigs = to->oldmask;
- err = copy_from_user(to, from, sizeof(*to));
- from_fp = to->fpstate;
- to->fpstate = to_fp;
- to->oldmask = sigs;
- if(to_fp != NULL)
- err |= copy_from_user(to_fp, from_fp, fpsize);
- return(err);
-}
-
-int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
- struct sigcontext *from, int fpsize, unsigned long sp)
-{
- struct _fpstate __user *to_fp;
- struct _fpstate *from_fp;
- int err;
-
- to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
- from_fp = from->fpstate;
- err = copy_to_user(to, from, sizeof(*to));
- /* The SP in the sigcontext is the updated one for the signal
- * delivery. The sp passed in is the original, and this needs
- * to be restored, so we stick it in separately.
- */
- err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
-
- if(from_fp != NULL){
- err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
- err |= copy_to_user(to_fp, from_fp, fpsize);
+ if (err)
+ return 1;
+
+ err = save_fp_registers(userspace_pid[current_thread->cpu],
+ (unsigned long *) &fp);
+ if (err < 0) {
+ printk(KERN_ERR "copy_sc_from_user - restore_fp_registers "
+ "failed, errno = %d\n", -err);
+ return 1;
}
- return err;
-}
-#endif
-
-static int copy_sc_from_user(struct pt_regs *to, void __user *from)
-{
- int ret;
-
- ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
- sizeof(struct _fpstate)),
- copy_sc_from_user_skas(to, from));
- return(ret);
-}
+ if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct)))
+ return 1;
-static int copy_sc_to_user(struct sigcontext __user *to,
- struct _fpstate __user *fp,
- struct pt_regs *from, unsigned long mask,
- unsigned long sp)
-{
- return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
- sizeof(*fp), sp),
- copy_sc_to_user_skas(to, fp, from, mask, sp)));
+ return err;
}
struct rt_sigframe
{
- char __user *pretcode;
- struct ucontext uc;
- struct siginfo info;
+ char __user *pretcode;
+ struct ucontext uc;
+ struct siginfo info;
+ struct _fpstate fpstate;
};
#define round_down(m, n) (((m) / (n)) * (n))
@@ -215,7 +172,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
siginfo_t *info, sigset_t *set)
{
struct rt_sigframe __user *frame;
- struct _fpstate __user *fp = NULL;
unsigned long save_sp = PT_REGS_RSP(regs);
int err = 0;
struct task_struct *me = current;
@@ -223,15 +179,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
frame = (struct rt_sigframe __user *)
round_down(stack_top - sizeof(struct rt_sigframe), 16);
/* Subtract 128 for a red zone and 8 for proper alignment */
- frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
-
- if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
- goto out;
+ frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
-#if 0 /* XXX */
- if (save_i387(fp) < 0)
- err |= -1;
-#endif
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto out;
@@ -241,7 +190,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
goto out;
}
- /* Update SP now because the page fault handler refuses to extend
+ /*
+ * Update SP now because the page fault handler refuses to extend
* the stack if the faulting address is too far below the current
* SP, which frame now certainly is. If there's an error, the original
* value is restored on the way out.
@@ -258,9 +208,9 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
err |= __put_user(sas_ss_flags(save_sp),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0],
- save_sp);
- err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
+ err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
+ set->sig[0], save_sp);
+ err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
if (sizeof(*set) == 16) {
__put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
__put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
@@ -269,8 +219,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
err |= __copy_to_user(&frame->uc.uc_sigmask, set,
sizeof(*set));
- /* Set up to return from userspace. If provided, use a stub
- already in userspace. */
+ /*
+ * Set up to return from userspace. If provided, use a stub
+ * already in userspace.
+ */
/* x86-64 should always use SA_RESTORER. */
if (ka->sa.sa_flags & SA_RESTORER)
err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
@@ -292,8 +244,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
/* In case the signal handler was declared without prototypes */
PT_REGS_RAX(regs) = 0;
- /* This also works for non SA_SIGINFO handlers because they expect the
- next argument after the signal number on the stack. */
+ /*
+ * This also works for non SA_SIGINFO handlers because they expect the
+ * next argument after the signal number on the stack.
+ */
PT_REGS_RSI(regs) = (unsigned long) &frame->info;
PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -313,7 +267,7 @@ long sys_rt_sigreturn(struct pt_regs *regs)
struct ucontext __user *uc = &frame->uc;
sigset_t set;
- if(copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
+ if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto segfault;
sigdelsetmask(&set, ~_BLOCKABLE);
@@ -323,24 +277,15 @@ long sys_rt_sigreturn(struct pt_regs *regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
+ if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
+ &frame->fpstate))
goto segfault;
/* Avoid ERESTART handling */
PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+ return PT_REGS_SYSCALL_RET(&current->thread.regs);
segfault:
force_sig(SIGSEGV, current);
return 0;
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
index 03c27973578..4afe204a6af 100644
--- a/arch/um/sys-x86_64/stub.S
+++ b/arch/um/sys-x86_64/stub.S
@@ -1,4 +1,5 @@
#include "uml-config.h"
+#include "as-layout.h"
.globl syscall_stub
.section .__syscall_stub, "x"
@@ -7,18 +8,18 @@ syscall_stub:
/* We don't have 64-bit constants, so this constructs the address
* we need.
*/
- movq $(UML_CONFIG_STUB_DATA >> 32), %rbx
+ movq $(ASM_STUB_DATA >> 32), %rbx
salq $32, %rbx
- movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx
+ movq $(ASM_STUB_DATA & 0xffffffff), %rcx
or %rcx, %rbx
movq %rax, (%rbx)
int3
.globl batch_syscall_stub
batch_syscall_stub:
- mov $(UML_CONFIG_STUB_DATA >> 32), %rbx
+ mov $(ASM_STUB_DATA >> 32), %rbx
sal $32, %rbx
- mov $(UML_CONFIG_STUB_DATA & 0xffffffff), %rax
+ mov $(ASM_STUB_DATA & 0xffffffff), %rax
or %rax, %rbx
/* load pointer to first operation */
mov %rbx, %rsp
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 652fa34c2cd..3afb590f007 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -6,6 +6,7 @@
#include <stddef.h>
#include <signal.h>
#include <asm/unistd.h>
+#include "as-layout.h"
#include "uml-config.h"
#include "sysdep/sigcontext.h"
#include "sysdep/faultinfo.h"
@@ -33,7 +34,7 @@ stub_segv_handler(int sig)
int pid;
__asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
- GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
+ GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA),
&uc->uc_mcontext);
pid = stub_syscall0(__NR_getpid);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index b3f6350cac4..86f6b18410e 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -1,70 +1,36 @@
/*
+ * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Copyright 2003 PathScale, Inc.
*
* Licensed under the GPL
*/
#include "linux/linkage.h"
-#include "linux/slab.h"
-#include "linux/shm.h"
-#include "linux/utsname.h"
#include "linux/personality.h"
-#include "asm/uaccess.h"
-#define __FRAME_OFFSETS
-#include "asm/ptrace.h"
-#include "asm/unistd.h"
+#include "linux/utsname.h"
#include "asm/prctl.h" /* XXX This should get the constants from libc */
-#include "choose-mode.h"
-#include "kern.h"
+#include "asm/uaccess.h"
#include "os.h"
asmlinkage long sys_uname64(struct new_utsname __user * name)
{
int err;
+
down_read(&uts_sem);
err = copy_to_user(name, utsname(), sizeof (*name));
up_read(&uts_sem);
+
if (personality(current->personality) == PER_LINUX32)
err |= copy_to_user(&name->machine, "i686", 5);
- return err ? -EFAULT : 0;
-}
-
-#ifdef CONFIG_MODE_TT
-extern long arch_prctl(int code, unsigned long addr);
-
-static long arch_prctl_tt(int code, unsigned long addr)
-{
- unsigned long tmp;
- long ret;
-
- switch(code){
- case ARCH_SET_GS:
- case ARCH_SET_FS:
- ret = arch_prctl(code, addr);
- break;
- case ARCH_GET_FS:
- case ARCH_GET_GS:
- ret = arch_prctl(code, (unsigned long) &tmp);
- if(!ret)
- ret = put_user(tmp, (long __user *)addr);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return(ret);
+ return err ? -EFAULT : 0;
}
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-long arch_prctl_skas(struct task_struct *task, int code,
- unsigned long __user *addr)
+long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
{
- unsigned long *ptr = addr, tmp;
+ unsigned long *ptr = addr, tmp;
long ret;
- int pid = task->mm->context.skas.id.u.pid;
+ int pid = task->mm->context.id.u.pid;
/*
* With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
@@ -79,52 +45,50 @@ long arch_prctl_skas(struct task_struct *task, int code,
* arch_prctl is run on the host, then the registers are read
* back.
*/
- switch(code){
+ switch (code) {
case ARCH_SET_FS:
case ARCH_SET_GS:
- restore_registers(pid, &current->thread.regs.regs);
- break;
- case ARCH_GET_FS:
- case ARCH_GET_GS:
- /*
- * With these two, we read to a local pointer and
- * put_user it to the userspace pointer that we were
- * given. If addr isn't valid (because it hasn't been
- * faulted in or is just bogus), we want put_user to
- * fault it in (or return -EFAULT) instead of having
- * the host return -EFAULT.
- */
- ptr = &tmp;
- }
+ restore_registers(pid, &current->thread.regs.regs);
+ break;
+ case ARCH_GET_FS:
+ case ARCH_GET_GS:
+ /*
+ * With these two, we read to a local pointer and
+ * put_user it to the userspace pointer that we were
+ * given. If addr isn't valid (because it hasn't been
+ * faulted in or is just bogus), we want put_user to
+ * fault it in (or return -EFAULT) instead of having
+ * the host return -EFAULT.
+ */
+ ptr = &tmp;
+ }
- ret = os_arch_prctl(pid, code, ptr);
- if(ret)
- return ret;
+ ret = os_arch_prctl(pid, code, ptr);
+ if (ret)
+ return ret;
- switch(code){
+ switch (code) {
case ARCH_SET_FS:
current->thread.arch.fs = (unsigned long) ptr;
save_registers(pid, &current->thread.regs.regs);
break;
case ARCH_SET_GS:
- save_registers(pid, &current->thread.regs.regs);
+ save_registers(pid, &current->thread.regs.regs);
break;
case ARCH_GET_FS:
ret = put_user(tmp, addr);
- break;
+ break;
case ARCH_GET_GS:
ret = put_user(tmp, addr);
- break;
+ break;
}
return ret;
}
-#endif
long sys_arch_prctl(int code, unsigned long addr)
{
- return CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, current, code,
- (unsigned long __user *) addr);
+ return arch_prctl(current, code, (unsigned long __user *) addr);
}
long sys_clone(unsigned long clone_flags, unsigned long newsp,
@@ -141,10 +105,10 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
return ret;
}
-void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
+void arch_switch_to(struct task_struct *from, struct task_struct *to)
{
- if((to->thread.arch.fs == 0) || (to->mm == NULL))
- return;
+ if ((to->thread.arch.fs == 0) || (to->mm == NULL))
+ return;
- arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
+ arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
}
diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c
index febbc94be25..f7ba46200ec 100644
--- a/arch/um/sys-x86_64/tls.c
+++ b/arch/um/sys-x86_64/tls.c
@@ -11,7 +11,7 @@ int arch_copy_tls(struct task_struct *t)
* (which is argument 5, child_tid, of clone) so it can be set
* during context switches.
*/
- t->thread.arch.fs = t->thread.regs.regs.skas.regs[R8 / sizeof(long)];
+ t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)];
- return 0;
+ return 0;
}
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
deleted file mode 100644
index f4a4bffd8a1..00000000000
--- a/arch/um/sys-x86_64/unmap.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <linux/mman.h>
-#include <asm/unistd.h>
-
-static int errno;
-
-static inline _syscall2(int,munmap,void *,start,size_t,len)
-static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
-int switcheroo(int fd, int prot, void *from, void *to, int size)
-{
- if(munmap(to, size) < 0){
- return(-1);
- }
- if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
- return(-1);
- }
- if(munmap(from, size) < 0){
- return(-1);
- }
- return(0);
-}
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 0d5fd764c21..f1ef2a8dfbc 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -3,17 +3,10 @@
#include <signal.h>
#include <sys/poll.h>
#include <sys/mman.h>
+#include <sys/user.h>
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <asm/types.h>
-/* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I
- * refuse to include here, even though they're used throughout the headers.
- * These are used in asm/user.h, and that include can't be avoided because of
- * the sizeof(struct user_regs_struct) below.
- */
-typedef __u64 u64;
-typedef __u32 u32;
-#include <asm/user.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
diff --git a/arch/v850/Makefile b/arch/v850/Makefile
index 8be9aacb20a..8b629df0029 100644
--- a/arch/v850/Makefile
+++ b/arch/v850/Makefile
@@ -16,11 +16,11 @@
arch_dir = arch/v850
-CFLAGS += -mv850e
+KBUILD_CFLAGS += -mv850e
# r16 is a fixed pointer to the current task
-CFLAGS += -ffixed-r16 -mno-prolog-function
-CFLAGS += -fno-builtin
-CFLAGS += -D__linux__ -DUTS_SYSNAME=\"uClinux\"
+KBUILD_CFLAGS += -ffixed-r16 -mno-prolog-function
+KBUILD_CFLAGS += -fno-builtin
+KBUILD_CFLAGS += -D__linux__ -DUTS_SYSNAME=\"uClinux\"
# By default, build a kernel that runs on the gdb v850 simulator.
KBUILD_DEFCONFIG := sim_defconfig
diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c
index 5c4923558a7..ab9cf16a85c 100644
--- a/arch/v850/kernel/fpga85e2c.c
+++ b/arch/v850/kernel/fpga85e2c.c
@@ -160,5 +160,8 @@ static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
static int reg_snap_dev_id;
static struct irqaction reg_snap_action = {
- make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", &reg_snap_dev_id, 0
+ .handler = make_reg_snap,
+ .mask = CPU_MASK_NONE,
+ .name = "reg_snap",
+ .dev_id = &reg_snap_dev_id,
};
diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
index f9f00ccf532..0a4df4d6e05 100644
--- a/arch/v850/kernel/syscalls.c
+++ b/arch/v850/kernel/syscalls.c
@@ -30,7 +30,6 @@
#include <linux/file.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
#include <asm/semaphore.h>
#include <asm/unistd.h>
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index f0905b03523..d810c93fe66 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -92,12 +92,11 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
static int timer_dev_id;
static struct irqaction timer_irqaction = {
- timer_interrupt,
- IRQF_DISABLED,
- CPU_MASK_NONE,
- "timer",
- &timer_dev_id,
- NULL
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED,
+ .mask = CPU_MASK_NONE,
+ .name = "timer",
+ .dev_id = &timer_dev_id,
};
void time_init (void)
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index cb1035f2b7e..89dbf970e05 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -39,6 +39,7 @@ setup-y += printf.o string.o tty.o video.o version.o voyager.o
setup-y += video-vga.o
setup-y += video-vesa.o
setup-y += video-bios.o
+
targets += $(setup-y)
hostprogs-y := tools/build
@@ -50,7 +51,7 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE)
# that way we can complain to the user if the CPU is insufficient.
cflags-i386 :=
cflags-x86_64 := -m32
-CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(cflags-$(ARCH)) \
-Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \
@@ -61,13 +62,13 @@ CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -fno-stack-protector) \
$(call cc-option, -mpreferred-stack-boundary=2)
-AFLAGS := $(CFLAGS) -D__ASSEMBLY__
+KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
$(obj)/zImage: IMAGE_OFFSET := 0x1000
-$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
+$(obj)/zImage: asflags-y := $(SVGA_MODE) $(RAMDISK)
$(obj)/bzImage: IMAGE_OFFSET := 0x100000
-$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
-$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
+$(obj)/bzImage: ccflags-y := -D__BIG_KERNEL__
+$(obj)/bzImage: asflags-y := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
$(obj)/bzImage: BUILDFLAGS := -b
quiet_cmd_image = BUILD $@
diff --git a/arch/x86/boot/compressed/Makefile_32 b/arch/x86/boot/compressed/Makefile_32
index 22613c652d2..e43ff7c56e6 100644
--- a/arch/x86/boot/compressed/Makefile_32
+++ b/arch/x86/boot/compressed/Makefile_32
@@ -11,7 +11,7 @@ EXTRA_AFLAGS := -traditional
LDFLAGS_vmlinux := -T
hostprogs-y := relocs
-CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
+KBUILD_CFLAGS := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
-fno-strict-aliasing -fPIC \
$(call cc-option,-ffreestanding) \
$(call cc-option,-fno-stack-protector)
diff --git a/arch/x86/boot/compressed/Makefile_64 b/arch/x86/boot/compressed/Makefile_64
index dc6b3380cc4..7801e8dd90b 100644
--- a/arch/x86/boot/compressed/Makefile_64
+++ b/arch/x86/boot/compressed/Makefile_64
@@ -6,11 +6,11 @@
targets := vmlinux vmlinux.bin vmlinux.bin.gz head_64.o misc_64.o piggy.o
-CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \
+KBUILD_CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \
-fno-strict-aliasing -fPIC -mcmodel=small \
$(call cc-option, -ffreestanding) \
$(call cc-option, -fno-stack-protector)
-AFLAGS := $(CFLAGS) -D__ASSEMBLY__
+KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
LDFLAGS := -m elf_x86_64
LDFLAGS_vmlinux := -T
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index cdae36435e2..e2edda255a8 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -18,18 +18,35 @@ $(obj)/syscall32_syscall.o: \
$(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
# Teach kbuild about targets
-targets := $(foreach F,sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
+targets := $(foreach F,$(addprefix vsyscall-,sysenter syscall),\
+ $F.o $F.so $F.so.dbg)
# The DSO images are built using a special linker script
quiet_cmd_syscall = SYSCALL $@
- cmd_syscall = $(CC) -m32 -nostdlib -shared -s \
+ cmd_syscall = $(CC) -m32 -nostdlib -shared \
$(call ld-option, -Wl$(comma)--hash-style=sysv) \
-Wl,-soname=linux-gate.so.1 -o $@ \
-Wl,-T,$(filter-out FORCE,$^)
-$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vsyscall-sysenter.so.dbg $(obj)/vsyscall-syscall.so.dbg: \
+$(obj)/vsyscall-%.so.dbg: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
$(call if_changed,syscall)
AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
+
+vdsos := vdso32-sysenter.so vdso32-syscall.so
+
+quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(@:vdso32-%.so=$(obj)/vsyscall-%.so.dbg) \
+ $(MODLIB)/vdso/$@
+
+$(vdsos):
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso_install: $(vdsos)
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
index 08781370256..f82e1a94fcb 100644
--- a/arch/x86/ia32/ia32_aout.c
+++ b/arch/x86/ia32/ia32_aout.c
@@ -40,7 +40,7 @@ static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout_library(struct file*);
#ifdef CORE_DUMP
-static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
+static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
/*
* fill in the user structure for a core dump..
@@ -148,7 +148,7 @@ if (file->f_op->llseek) { \
* dumping of the process results in another error..
*/
-static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
+static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
mm_segment_t fs;
int has_dumped = 0;
@@ -168,13 +168,11 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
/* If the size of the dump file exceeds the rlimit, then see what would happen
if we wrote the stack, but not the data area. */
- if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if ((dump.u_dsize + dump.u_ssize + 1) * PAGE_SIZE > limit)
dump.u_dsize = 0;
/* Make sure we have enough room to write the stack and data areas. */
- if ((dump.u_ssize+1) * PAGE_SIZE >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
dump.u_ssize = 0;
/* make sure we actually have a data and stack area to dump */
@@ -422,6 +420,8 @@ beyond_if:
(regs)->eflags = 0x200;
(regs)->cs = __USER32_CS;
(regs)->ss = __USER32_DS;
+ regs->r8 = regs->r9 = regs->r10 = regs->r11 =
+ regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
set_fs(USER_DS);
if (unlikely(current->ptrace & PT_PTRACED)) {
if (current->ptrace & PT_TRACE_EXEC)
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
index dffd2ac7274..5027650eb27 100644
--- a/arch/x86/ia32/ia32_binfmt.c
+++ b/arch/x86/ia32/ia32_binfmt.c
@@ -112,11 +112,8 @@ struct elf_prpsinfo
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
#define _GET_SEG(x) \
- ({ __u32 seg; asm("movl %%" STR(x) ",%0" : "=r"(seg)); seg; })
+ ({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
/* Assumes current==process to be dumped */
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
@@ -188,6 +185,7 @@ 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
static inline int
elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
{
@@ -291,7 +289,6 @@ static void elf32_init(struct pt_regs *regs)
static ctl_table abi_table2[] = {
{
- .ctl_name = 99,
.procname = "vsyscall32",
.data = &sysctl_vsyscall32,
.maxlen = sizeof(int),
diff --git a/arch/x86/ia32/ipc32.c b/arch/x86/ia32/ipc32.c
index 2e1869ec4db..7b3342e5aab 100644
--- a/arch/x86/ia32/ipc32.c
+++ b/arch/x86/ia32/ipc32.c
@@ -9,8 +9,6 @@
#include <linux/ipc.h>
#include <linux/compat.h>
-#include <asm/ipc.h>
-
asmlinkage long
sys32_ipc(u32 call, int first, int second, int third,
compat_uptr_t ptr, u32 fifth)
diff --git a/arch/x86/ia32/ptrace32.c b/arch/x86/ia32/ptrace32.c
index 4a233ad6269..f52770ef0ee 100644
--- a/arch/x86/ia32/ptrace32.c
+++ b/arch/x86/ia32/ptrace32.c
@@ -228,6 +228,8 @@ static long ptrace32_siginfo(unsigned request, u32 pid, u32 addr, u32 data)
return ret;
}
+#define COMPAT_GDT_ENTRY_TLS_MIN 6
+
asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
{
struct task_struct *child;
@@ -246,8 +248,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SYSCALL:
case PTRACE_OLDSETOPTIONS:
case PTRACE_SETOPTIONS:
- case PTRACE_SET_THREAD_AREA:
- case PTRACE_GET_THREAD_AREA:
return sys_ptrace(request, pid, addr, data);
default:
@@ -271,6 +271,12 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SETSIGINFO:
case PTRACE_GETSIGINFO:
return ptrace32_siginfo(request, pid, addr, data);
+
+ case PTRACE_SET_THREAD_AREA:
+ case PTRACE_GET_THREAD_AREA:
+ return sys_ptrace(request, pid,
+ addr + GDT_ENTRY_TLS_MIN - COMPAT_GDT_ENTRY_TLS_MIN,
+ data);
}
child = ptrace_get_task_struct(pid);
diff --git a/arch/x86/kernel/.gitignore b/arch/x86/kernel/.gitignore
index 40836ad9079..4ea38a39aed 100644
--- a/arch/x86/kernel/.gitignore
+++ b/arch/x86/kernel/.gitignore
@@ -1 +1,2 @@
vsyscall.lds
+vsyscall_32.lds
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 45855c97923..38573340b14 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -3,3 +3,7 @@ include ${srctree}/arch/x86/kernel/Makefile_32
else
include ${srctree}/arch/x86/kernel/Makefile_64
endif
+
+# Workaround to delete .lds files with make clean
+# The problem is that we do not enter Makefile_32 with make clean.
+clean-files := vsyscall*.lds vsyscall*.so
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index 7ff02063b85..a3fa11f8f46 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -51,7 +51,7 @@ obj-$(CONFIG_SCx200) += scx200_32.o
# We must build both images before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/vsyscall_32.o: $(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so
-targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
+targets += $(foreach F,int80 sysenter,vsyscall-$F_32.o vsyscall-$F_32.so)
targets += vsyscall-note_32.o vsyscall_32.lds
# The DSO images are built using a special linker script.
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
index f22ba8534d2..a97313b1270 100644
--- a/arch/x86/kernel/acpi/wakeup_32.S
+++ b/arch/x86/kernel/acpi/wakeup_32.S
@@ -11,7 +11,7 @@
#
# If physical address of wakeup_code is 0x12345, BIOS should call us with
# cs = 0x1234, eip = 0x05
-#
+#
#define BEEP \
inb $97, %al; \
@@ -52,7 +52,6 @@ wakeup_code:
BEEP
1:
mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board
- movw $0x0e00 + 'S', %fs:(0x12)
pushl $0 # Kill any dangerous flags
popfl
@@ -90,9 +89,6 @@ wakeup_code:
# make sure %cr4 is set correctly (features, etc)
movl real_save_cr4 - wakeup_code, %eax
movl %eax, %cr4
- movw $0xb800, %ax
- movw %ax,%fs
- movw $0x0e00 + 'i', %fs:(0x12)
# need a gdt -- use lgdtl to force 32-bit operands, in case
# the GDT is located past 16 megabytes.
@@ -102,8 +98,6 @@ wakeup_code:
movl %eax, %cr0
jmp 1f
1:
- movw $0x0e00 + 'n', %fs:(0x14)
-
movl real_magic - wakeup_code, %eax
cmpl $0x12345678, %eax
jne bogus_real_magic
@@ -122,13 +116,11 @@ real_save_cr4: .long 0
real_magic: .long 0
video_mode: .long 0
realmode_flags: .long 0
-beep_flags: .long 0
real_efer_save_restore: .long 0
real_save_efer_edx: .long 0
real_save_efer_eax: .long 0
bogus_real_magic:
- movw $0x0e00 + 'B', %fs:(0x12)
jmp bogus_real_magic
/* This code uses an extended set of video mode numbers. These include:
@@ -194,7 +186,6 @@ wakeup_pmode_return:
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
- movw $0x0e00 + 'u', 0xb8016
# reload the gdt, as we need the full 32 bit address
lgdt saved_gdt
@@ -218,7 +209,6 @@ wakeup_pmode_return:
jmp *%eax
bogus_magic:
- movw $0x0e00 + 'B', 0xb8018
jmp bogus_magic
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S
index 8b4357e1efe..55608ec2ed7 100644
--- a/arch/x86/kernel/acpi/wakeup_64.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -41,7 +41,6 @@ wakeup_code:
# Running in *copy* of this code, somewhere in low 1MB.
- movb $0xa1, %al ; outb %al, $0x80
cli
cld
# setup data segment
@@ -65,11 +64,6 @@ wakeup_code:
cmpl $0x12345678, %eax
jne bogus_real_magic
- call verify_cpu # Verify the cpu supports long
- # mode
- testl %eax, %eax
- jnz no_longmode
-
testl $1, realmode_flags - wakeup_code
jz 1f
lcall $0xc000,$3
@@ -84,12 +78,6 @@ wakeup_code:
call mode_set
1:
- movw $0xb800, %ax
- movw %ax,%fs
- movw $0x0e00 + 'L', %fs:(0x10)
-
- movb $0xa2, %al ; outb %al, $0x80
-
mov %ds, %ax # Find 32bit wakeup_code addr
movzx %ax, %esi # (Convert %ds:gdt to a liner ptr)
shll $4, %esi
@@ -117,14 +105,10 @@ wakeup_32_vector:
.code32
wakeup_32:
# Running in this code, but at low address; paging is not yet turned on.
- movb $0xa5, %al ; outb %al, $0x80
movl $__KERNEL_DS, %eax
movl %eax, %ds
- movw $0x0e00 + 'i', %ds:(0xb8012)
- movb $0xa8, %al ; outb %al, $0x80;
-
/*
* Prepare for entering 64bits mode
*/
@@ -200,16 +184,11 @@ wakeup_long64:
*/
lgdt cpu_gdt_descr
- movw $0x0e00 + 'n', %ds:(0xb8014)
- movb $0xa9, %al ; outb %al, $0x80
-
movq saved_magic, %rax
movq $0x123456789abcdef0, %rdx
cmpq %rdx, %rax
jne bogus_64_magic
- movw $0x0e00 + 'u', %ds:(0xb8016)
-
nop
nop
movw $__KERNEL_DS, %ax
@@ -220,13 +199,11 @@ wakeup_long64:
movw %ax, %gs
movq saved_rsp, %rsp
- movw $0x0e00 + 'x', %ds:(0xb8018)
movq saved_rbx, %rbx
movq saved_rdi, %rdi
movq saved_rsi, %rsi
movq saved_rbp, %rbp
- movw $0x0e00 + '!', %ds:(0xb801a)
movq saved_rip, %rax
jmp *%rax
@@ -256,21 +233,12 @@ realmode_flags: .quad 0
.code16
bogus_real_magic:
- movb $0xba,%al ; outb %al,$0x80
jmp bogus_real_magic
.code64
bogus_64_magic:
- movb $0xb3,%al ; outb %al,$0x80
jmp bogus_64_magic
-.code16
-no_longmode:
- movb $0xbc,%al ; outb %al,$0x80
- jmp no_longmode
-
-#include "../verify_cpu_64.S"
-
/* This code uses an extended set of video mode numbers. These include:
* Aliases for standard modes
* NORMAL_VGA (-1)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 11b03d3c6fd..3bd2688bd44 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -63,11 +63,11 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
/* Use inline assembly to define this because the nops are defined
as inline assembly strings in the include files and we cannot
get them easily into strings. */
-asm("\t.data\nintelnops: "
+asm("\t.section .rodata, \"a\"\nintelnops: "
GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
GENERIC_NOP7 GENERIC_NOP8);
-extern unsigned char intelnops[];
-static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
+extern const unsigned char intelnops[];
+static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
NULL,
intelnops,
intelnops + 1,
@@ -81,11 +81,11 @@ static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
#endif
#ifdef K8_NOP1
-asm("\t.data\nk8nops: "
+asm("\t.section .rodata, \"a\"\nk8nops: "
K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
K8_NOP7 K8_NOP8);
-extern unsigned char k8nops[];
-static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
+extern const unsigned char k8nops[];
+static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
NULL,
k8nops,
k8nops + 1,
@@ -99,11 +99,11 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
#endif
#ifdef K7_NOP1
-asm("\t.data\nk7nops: "
+asm("\t.section .rodata, \"a\"\nk7nops: "
K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
K7_NOP7 K7_NOP8);
-extern unsigned char k7nops[];
-static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
+extern const unsigned char k7nops[];
+static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
NULL,
k7nops,
k7nops + 1,
@@ -116,28 +116,49 @@ static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
};
#endif
+#ifdef P6_NOP1
+asm("\t.section .rodata, \"a\"\np6nops: "
+ P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
+ P6_NOP7 P6_NOP8);
+extern const unsigned char p6nops[];
+static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
+ NULL,
+ p6nops,
+ p6nops + 1,
+ p6nops + 1 + 2,
+ p6nops + 1 + 2 + 3,
+ p6nops + 1 + 2 + 3 + 4,
+ p6nops + 1 + 2 + 3 + 4 + 5,
+ p6nops + 1 + 2 + 3 + 4 + 5 + 6,
+ p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+};
+#endif
+
#ifdef CONFIG_X86_64
extern char __vsyscall_0;
-static inline unsigned char** find_nop_table(void)
+static inline const unsigned char*const * find_nop_table(void)
{
- return k8_nops;
+ return boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+ boot_cpu_data.x86 < 6 ? k8_nops : p6_nops;
}
#else /* CONFIG_X86_64 */
-static struct nop {
+static const struct nop {
int cpuid;
- unsigned char **noptable;
+ const unsigned char *const *noptable;
} noptypes[] = {
{ X86_FEATURE_K8, k8_nops },
{ X86_FEATURE_K7, k7_nops },
+ { X86_FEATURE_P4, p6_nops },
+ { X86_FEATURE_P3, p6_nops },
{ -1, NULL }
};
-static unsigned char** find_nop_table(void)
+static const unsigned char*const * find_nop_table(void)
{
- unsigned char **noptable = intel_nops;
+ const unsigned char *const *noptable = intel_nops;
int i;
for (i = 0; noptypes[i].cpuid >= 0; i++) {
@@ -154,7 +175,7 @@ static unsigned char** find_nop_table(void)
/* Use this to add nops to a buffer, then text_poke the whole buffer. */
static void add_nops(void *insns, unsigned int len)
{
- unsigned char **noptable = find_nop_table();
+ const unsigned char *const *noptable = find_nop_table();
while (len > 0) {
unsigned int noplen = len;
@@ -369,8 +390,8 @@ void apply_paravirt(struct paravirt_patch_site *start,
BUG_ON(p->len > MAX_PATCH_LEN);
/* prep the buffer with the original instructions */
memcpy(insnbuf, p->instr, p->len);
- used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf,
- (unsigned long)p->instr, p->len);
+ used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
+ (unsigned long)p->instr, p->len);
BUG_ON(used > p->len);
@@ -415,9 +436,6 @@ void __init alternative_instructions(void)
alternatives_smp_unlock(__smp_locks, __smp_locks_end,
_text, _etext);
}
- free_init_pages("SMP alternatives",
- (unsigned long)__smp_locks,
- (unsigned long)__smp_locks_end);
} else {
alternatives_smp_module_add(NULL, "core kernel",
__smp_locks, __smp_locks_end,
@@ -428,6 +446,11 @@ void __init alternative_instructions(void)
apply_paravirt(__parainstructions, __parainstructions_end);
local_irq_restore(flags);
+ if (smp_alt_once)
+ free_init_pages("SMP alternatives",
+ (unsigned long)__smp_locks,
+ (unsigned long)__smp_locks_end);
+
restart_nmi();
#ifdef CONFIG_X86_MCE
restart_mce();
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 3d67ae18d76..793341fffc8 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -1277,6 +1277,7 @@ void smp_spurious_interrupt(struct pt_regs *regs)
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
printk(KERN_INFO "spurious APIC interrupt on CPU#%d, "
"should never happen.\n", smp_processor_id());
+ __get_cpu_var(irq_stat).irq_spurious_count++;
irq_exit();
}
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 09b82093bc7..f47bc493dba 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -974,15 +974,12 @@ void __init setup_boot_APIC_clock (void)
*/
void __cpuinit check_boot_apic_timer_broadcast(void)
{
- struct clock_event_device *levt = &per_cpu(lapic_events, boot_cpu_id);
-
if (!disable_apic_timer ||
(lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY))
return;
printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n");
lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY;
- levt->features |= CLOCK_EVT_FEAT_DUMMY;
local_irq_enable();
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &boot_cpu_id);
@@ -1143,6 +1140,7 @@ asmlinkage void smp_spurious_interrupt(void)
if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
ack_APIC_irq();
+ add_pda(irq_spurious_count, 1);
irq_exit();
}
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index 8029742c0fc..f1b7cdda82b 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -116,12 +116,14 @@ void foo(void)
#ifdef CONFIG_PARAVIRT
BLANK();
- OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled);
- OFFSET(PARAVIRT_irq_disable, paravirt_ops, irq_disable);
- OFFSET(PARAVIRT_irq_enable, paravirt_ops, irq_enable);
- OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
- OFFSET(PARAVIRT_iret, paravirt_ops, iret);
- OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
+ OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
+ OFFSET(PARAVIRT_PATCH_pv_cpu_ops, paravirt_patch_template, pv_cpu_ops);
+ OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
+ OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
+ OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
+ OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
+ OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
+ OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
#endif
#ifdef CONFIG_XEN
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index dcf6bbb1c7c..5f8af875f45 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -4,6 +4,7 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/apic.h>
+#include <asm/mach_apic.h>
#include "cpu.h"
@@ -45,13 +46,17 @@ static __cpuinit int amd_apic_timer_broken(void)
case CPUID_XFAM_10H:
case CPUID_XFAM_11H:
rdmsr(MSR_K8_ENABLE_C1E, lo, hi);
- if (lo & ENABLE_C1E_MASK)
+ if (lo & ENABLE_C1E_MASK) {
+ if (smp_processor_id() != boot_cpu_physical_apicid)
+ printk(KERN_INFO "AMD C1E detected late. "
+ " Force timer broadcast.\n");
return 1;
- break;
- default:
- /* err on the side of caution */
+ }
+ break;
+ default:
+ /* err on the side of caution */
return 1;
- }
+ }
return 0;
}
#endif
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index ffd01e5dcb5..2ca43ba32bc 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -595,7 +595,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
dmi_check_system(sw_any_bug_dmi_table);
if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
- policy->cpus = cpu_core_map[cpu];
+ policy->cpus = per_cpu(cpu_core_map, cpu);
}
#endif
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 8eb414b906d..793eae854f4 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -200,7 +200,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
unsigned int i;
#ifdef CONFIG_SMP
- policy->cpus = cpu_sibling_map[policy->cpu];
+ policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif
/* Errata workaround */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index 7decd6a50ff..f3686a5f230 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -565,7 +565,7 @@ static unsigned int powernow_get(unsigned int cpu)
}
-static int __init acer_cpufreq_pst(struct dmi_system_id *d)
+static int __init acer_cpufreq_pst(const struct dmi_system_id *d)
{
printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index b273b69cfdd..c06ac680c9c 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -57,7 +57,7 @@ static struct powernow_k8_data *powernow_data[NR_CPUS];
static int cpu_family = CPU_OPTERON;
#ifndef CONFIG_SMP
-static cpumask_t cpu_core_map[1];
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
#endif
/* Return a frequency in MHz, given an input fid */
@@ -667,7 +667,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
data->powernow_table = powernow_table;
- if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
+ if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
print_basics(data);
for (j = 0; j < data->numps; j++)
@@ -821,7 +821,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
/* fill in data */
data->numps = data->acpi_data.state_count;
- if (first_cpu(cpu_core_map[data->cpu]) == data->cpu)
+ if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
print_basics(data);
powernow_k8_acpi_pst_values(data, 0);
@@ -1214,7 +1214,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
if (cpu_family == CPU_HW_PSTATE)
pol->cpus = cpumask_of_cpu(pol->cpu);
else
- pol->cpus = cpu_core_map[pol->cpu];
+ pol->cpus = per_cpu(cpu_core_map, pol->cpu);
data->available_cores = &(pol->cpus);
/* Take a crude guess here.
@@ -1281,7 +1281,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
cpumask_t oldmask = current->cpus_allowed;
unsigned int khz = 0;
- data = powernow_data[first_cpu(cpu_core_map[cpu])];
+ data = powernow_data[first_cpu(per_cpu(cpu_core_map, cpu))];
if (!data)
return -EINVAL;
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 36685e8f7be..14d68aa301e 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -322,7 +322,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
- policy->cpus = cpu_sibling_map[policy->cpu];
+ policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
#endif
cpus_allowed = current->cpus_allowed;
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index dc4e08147b1..cc8c501b9f3 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <asm/processor.h>
+#include <asm/pgtable.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
@@ -19,8 +20,6 @@
#include <mach_apic.h>
#endif
-extern int trap_init_f00f_bug(void);
-
#ifdef CONFIG_X86_INTEL_USERCOPY
/*
* Alignment at which movsl is preferred for bulk memory copies.
@@ -95,6 +94,20 @@ static int __cpuinit num_cpu_cores(struct cpuinfo_x86 *c)
return 1;
}
+#ifdef CONFIG_X86_F00F_BUG
+static void __cpuinit trap_init_f00f_bug(void)
+{
+ __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
+
+ /*
+ * Update the IDT descriptor and reload the IDT so that
+ * it uses the read-only mapped virtual address.
+ */
+ idt_descr.address = fix_to_virt(FIX_F00F_IDT);
+ load_idt(&idt_descr);
+}
+#endif
+
static void __cpuinit init_intel(struct cpuinfo_x86 *c)
{
unsigned int l2 = 0;
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index db6c25aa577..297a2411694 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -170,15 +170,15 @@ union l3_cache {
unsigned val;
};
-static const unsigned short assocs[] = {
+static unsigned short assocs[] __cpuinitdata = {
[1] = 1, [2] = 2, [4] = 4, [6] = 8,
[8] = 16, [0xa] = 32, [0xb] = 48,
[0xc] = 64,
[0xf] = 0xffff // ??
};
-static const unsigned char levels[] = { 1, 1, 2, 3 };
-static const unsigned char types[] = { 1, 2, 3, 3 };
+static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
+static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
union _cpuid4_leaf_ebx *ebx,
@@ -493,12 +493,17 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
}
}
#else
-static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
-static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
+static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
#endif
static void free_cache_attributes(unsigned int cpu)
{
+ int i;
+
+ for (i = 0; i < num_cache_leaves; i++)
+ cache_remove_shared_cpu_map(cpu, i);
+
kfree(cpuid4_info[cpu]);
cpuid4_info[cpu] = NULL;
}
@@ -506,8 +511,8 @@ static void free_cache_attributes(unsigned int cpu)
static int __cpuinit detect_cache_attributes(unsigned int cpu)
{
struct _cpuid4_info *this_leaf;
- unsigned long j;
- int retval;
+ unsigned long j;
+ int retval;
cpumask_t oldmask;
if (num_cache_leaves == 0)
@@ -524,19 +529,26 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu)
goto out;
/* Do cpuid and store the results */
- retval = 0;
for (j = 0; j < num_cache_leaves; j++) {
this_leaf = CPUID4_INFO_IDX(cpu, j);
retval = cpuid4_cache_lookup(j, this_leaf);
- if (unlikely(retval < 0))
+ if (unlikely(retval < 0)) {
+ int i;
+
+ for (i = 0; i < j; i++)
+ cache_remove_shared_cpu_map(cpu, i);
break;
+ }
cache_shared_cpu_map_setup(cpu, j);
}
set_cpus_allowed(current, oldmask);
out:
- if (retval)
- free_cache_attributes(cpu);
+ if (retval) {
+ kfree(cpuid4_info[cpu]);
+ cpuid4_info[cpu] = NULL;
+ }
+
return retval;
}
@@ -669,7 +681,7 @@ static struct kobj_type ktype_percpu_entry = {
.sysfs_ops = &sysfs_ops,
};
-static void cpuid4_cache_sysfs_exit(unsigned int cpu)
+static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
{
kfree(cache_kobject[cpu]);
kfree(index_kobject[cpu]);
@@ -680,13 +692,14 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
{
+ int err;
if (num_cache_leaves == 0)
return -ENOENT;
- detect_cache_attributes(cpu);
- if (cpuid4_info[cpu] == NULL)
- return -ENOENT;
+ err = detect_cache_attributes(cpu);
+ if (err)
+ return err;
/* Allocate all required memory */
cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
@@ -705,13 +718,15 @@ err_out:
return -ENOMEM;
}
+static cpumask_t cache_dev_map = CPU_MASK_NONE;
+
/* Add/Remove cache interface for CPU device */
static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
{
unsigned int cpu = sys_dev->id;
unsigned long i, j;
struct _index_kobject *this_object;
- int retval = 0;
+ int retval;
retval = cpuid4_cache_sysfs_init(cpu);
if (unlikely(retval < 0))
@@ -721,6 +736,10 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
kobject_set_name(cache_kobject[cpu], "%s", "cache");
cache_kobject[cpu]->ktype = &ktype_percpu_entry;
retval = kobject_register(cache_kobject[cpu]);
+ if (retval < 0) {
+ cpuid4_cache_sysfs_exit(cpu);
+ return retval;
+ }
for (i = 0; i < num_cache_leaves; i++) {
this_object = INDEX_KOBJECT_PTR(cpu,i);
@@ -740,6 +759,9 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
break;
}
}
+ if (!retval)
+ cpu_set(cpu, cache_dev_map);
+
return retval;
}
@@ -750,13 +772,14 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
if (cpuid4_info[cpu] == NULL)
return;
- for (i = 0; i < num_cache_leaves; i++) {
- cache_remove_shared_cpu_map(cpu, i);
+ if (!cpu_isset(cpu, cache_dev_map))
+ return;
+ cpu_clear(cpu, cache_dev_map);
+
+ for (i = 0; i < num_cache_leaves; i++)
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
- }
kobject_unregister(cache_kobject[cpu]);
cpuid4_cache_sysfs_exit(cpu);
- return;
}
static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
@@ -781,7 +804,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
{
- .notifier_call = cacheinfo_cpu_callback,
+ .notifier_call = cacheinfo_cpu_callback,
};
static int __cpuinit cache_sysfs_init(void)
@@ -791,13 +814,15 @@ static int __cpuinit cache_sysfs_init(void)
if (num_cache_leaves == 0)
return 0;
- register_hotcpu_notifier(&cacheinfo_cpu_notifier);
-
for_each_online_cpu(i) {
- cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
- (void *)(long)i);
- }
+ int err;
+ struct sys_device *sys_dev = get_cpu_sysdev(i);
+ err = cache_add_dev(sys_dev);
+ if (err)
+ return err;
+ }
+ register_hotcpu_notifier(&cacheinfo_cpu_notifier);
return 0;
}
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
index 1509edfb231..be4dabfee1f 100644
--- a/arch/x86/kernel/cpu/mcheck/p4.c
+++ b/arch/x86/kernel/cpu/mcheck/p4.c
@@ -61,6 +61,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs)
{
irq_enter();
vendor_thermal_interrupt(regs);
+ __get_cpu_var(irq_stat).irq_thermal_count++;
irq_exit();
}
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index 1203dc5ab87..24885be5c48 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -131,17 +131,19 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb,
{
unsigned int cpu = (unsigned long)hcpu;
struct sys_device *sys_dev;
- int err;
+ int err = 0;
sys_dev = get_cpu_sysdev(cpu);
switch (action) {
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
mutex_lock(&therm_cpu_lock);
err = thermal_throttle_add_dev(sys_dev);
mutex_unlock(&therm_cpu_lock);
WARN_ON(err);
break;
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
mutex_lock(&therm_cpu_lock);
@@ -149,10 +151,10 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb,
mutex_unlock(&therm_cpu_lock);
break;
}
- return NOTIFY_OK;
+ return err ? NOTIFY_BAD : NOTIFY_OK;
}
-static struct notifier_block thermal_throttle_cpu_notifier =
+static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata =
{
.notifier_call = thermal_throttle_cpu_callback,
};
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index c48b6fea5ab..5e4be30ff90 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -738,13 +738,7 @@ void mtrr_ap_init(void)
*/
void mtrr_save_state(void)
{
- int cpu = get_cpu();
-
- if (cpu == 0)
- mtrr_save_fixed_ranges(NULL);
- else
- smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1);
- put_cpu();
+ smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1);
}
static int __init mtrr_init_finialize(void)
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 93fecd4b03d..54cdbf1a40f 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -34,7 +34,7 @@ struct wd_ops {
u64 checkbit;
};
-static struct wd_ops *wd_ops;
+static const struct wd_ops *wd_ops;
/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
* offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
@@ -317,7 +317,7 @@ static void single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz);
}
-static struct wd_ops k7_wd_ops = {
+static const struct wd_ops k7_wd_ops = {
.reserve = single_msr_reserve,
.unreserve = single_msr_unreserve,
.setup = setup_k7_watchdog,
@@ -380,7 +380,7 @@ static void p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
write_watchdog_counter32(wd->perfctr_msr, NULL,nmi_hz);
}
-static struct wd_ops p6_wd_ops = {
+static const struct wd_ops p6_wd_ops = {
.reserve = single_msr_reserve,
.unreserve = single_msr_unreserve,
.setup = setup_p6_watchdog,
@@ -532,7 +532,7 @@ static void p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz);
}
-static struct wd_ops p4_wd_ops = {
+static const struct wd_ops p4_wd_ops = {
.reserve = p4_reserve,
.unreserve = p4_unreserve,
.setup = setup_p4_watchdog,
@@ -550,6 +550,8 @@ static struct wd_ops p4_wd_ops = {
#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK
+static struct wd_ops intel_arch_wd_ops;
+
static int setup_intel_arch_watchdog(unsigned nmi_hz)
{
unsigned int ebx;
@@ -591,11 +593,11 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
wd->perfctr_msr = perfctr_msr;
wd->evntsel_msr = evntsel_msr;
wd->cccr_msr = 0; //unused
- wd_ops->checkbit = 1ULL << (eax.split.bit_width - 1);
+ intel_arch_wd_ops.checkbit = 1ULL << (eax.split.bit_width - 1);
return 1;
}
-static struct wd_ops intel_arch_wd_ops = {
+static struct wd_ops intel_arch_wd_ops __read_mostly = {
.reserve = single_msr_reserve,
.unreserve = single_msr_unreserve,
.setup = setup_intel_arch_watchdog,
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 1e31b6caffb..879a0f789b1 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -122,7 +122,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_X86_HT
if (c->x86_max_cores * smp_num_siblings > 1) {
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
- seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n]));
+ seq_printf(m, "siblings\t: %d\n",
+ cpus_weight(per_cpu(cpu_core_map, n)));
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
}
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index f4548c93ccf..70dcf912d9f 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -43,8 +43,6 @@
static struct class *cpuid_class;
-#ifdef CONFIG_SMP
-
struct cpuid_command {
u32 reg;
u32 *data;
@@ -62,25 +60,11 @@ static inline void do_cpuid(int cpu, u32 reg, u32 * data)
{
struct cpuid_command cmd;
- preempt_disable();
- if (cpu == smp_processor_id()) {
- cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
- } else {
- cmd.reg = reg;
- cmd.data = data;
+ cmd.reg = reg;
+ cmd.data = data;
- smp_call_function_single(cpu, cpuid_smp_cpuid, &cmd, 1, 1);
- }
- preempt_enable();
+ smp_call_function_single(cpu, cpuid_smp_cpuid, &cmd, 1, 1);
}
-#else /* ! CONFIG_SMP */
-
-static inline void do_cpuid(int cpu, u32 reg, u32 * data)
-{
- cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
-}
-
-#endif /* ! CONFIG_SMP */
static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
{
@@ -150,7 +134,7 @@ static const struct file_operations cpuid_fops = {
.open = cpuid_open,
};
-static int cpuid_device_create(int i)
+static int __cpuinit cpuid_device_create(int i)
{
int err = 0;
struct device *dev;
@@ -161,7 +145,9 @@ static int cpuid_device_create(int i)
return err;
}
-static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
+ unsigned long action,
+ void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index 0f4d5e209e9..e422b8159f6 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -24,7 +24,7 @@
#include <asm/page.h>
#include <asm/e820.h>
#include <asm/proto.h>
-#include <asm/bootsetup.h>
+#include <asm/setup.h>
#include <asm/sections.h>
struct e820map e820;
@@ -68,10 +68,15 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
/* initrd */
#ifdef CONFIG_BLK_DEV_INITRD
- if (LOADER_TYPE && INITRD_START && last >= INITRD_START &&
- addr < INITRD_START+INITRD_SIZE) {
- *addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
- return 1;
+ if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+ unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
+ unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
+ unsigned long ramdisk_end = ramdisk_image+ramdisk_size;
+
+ if (last >= ramdisk_image && addr < ramdisk_end) {
+ *addrp = PAGE_ALIGN(ramdisk_end);
+ return 1;
+ }
}
#endif
/* kernel code */
@@ -594,8 +599,8 @@ void __init setup_memory_region(void)
* Otherwise fake a memory map; one section from 0k->640k,
* the next section from 1mb->appropriate_mem_k
*/
- sanitize_e820_map(E820_MAP, &E820_MAP_NR);
- if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0)
+ sanitize_e820_map(boot_params.e820_map, &boot_params.e820_entries);
+ if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries) < 0)
early_panic("Cannot find a valid memory map");
printk(KERN_INFO "BIOS-provided physical RAM map:\n");
e820_print_map("BIOS-e820");
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index fd9aff3f389..b7d6c23f287 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -6,15 +6,10 @@
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/fcntl.h>
+#include <asm/setup.h>
#include <xen/hvc-console.h>
/* Simple VGA output */
-
-#ifdef __i386__
-#include <asm/setup.h>
-#else
-#include <asm/bootsetup.h>
-#endif
#define VGABASE (__ISA_IO_base + 0xb8000)
static int max_ypos = 25, max_xpos = 80;
@@ -234,10 +229,10 @@ static int __init setup_early_printk(char *buf)
early_serial_init(buf);
early_console = &early_serial_console;
} else if (!strncmp(buf, "vga", 3)
- && SCREEN_INFO.orig_video_isVGA == 1) {
- max_xpos = SCREEN_INFO.orig_video_cols;
- max_ypos = SCREEN_INFO.orig_video_lines;
- current_ypos = SCREEN_INFO.orig_y;
+ && boot_params.screen_info.orig_video_isVGA == 1) {
+ max_xpos = boot_params.screen_info.orig_video_cols;
+ max_ypos = boot_params.screen_info.orig_video_lines;
+ current_ypos = boot_params.screen_info.orig_y;
early_console = &early_vga_console;
} else if (!strncmp(buf, "simnow", 6)) {
simnow_init(buf + 6);
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
index 2452c6fbe99..b42558c48e9 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/kernel/efi_32.c
@@ -331,11 +331,13 @@ void __init efi_init(void)
memset(&efi, 0, sizeof(efi) );
memset(&efi_phys, 0, sizeof(efi_phys));
- efi_phys.systab = EFI_SYSTAB;
- memmap.phys_map = EFI_MEMMAP;
- memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE;
- memmap.desc_version = EFI_MEMDESC_VERSION;
- memmap.desc_size = EFI_MEMDESC_SIZE;
+ efi_phys.systab =
+ (efi_system_table_t *)boot_params.efi_info.efi_systab;
+ memmap.phys_map = (void *)boot_params.efi_info.efi_memmap;
+ memmap.nr_map = boot_params.efi_info.efi_memmap_size/
+ boot_params.efi_info.efi_memdesc_size;
+ memmap.desc_version = boot_params.efi_info.efi_memdesc_version;
+ memmap.desc_size = boot_params.efi_info.efi_memdesc_size;
efi.systab = (efi_system_table_t *)
boot_ioremap((unsigned long) efi_phys.systab,
@@ -446,7 +448,8 @@ void __init efi_init(void)
printk(KERN_ERR PFX "Could not map the runtime service table!\n");
/* Map the EFI memory map for use until paging_init() */
- memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE);
+ memmap.map = boot_ioremap(boot_params.efi_info.efi_memmap,
+ boot_params.efi_info.efi_memmap_size);
if (memmap.map == NULL)
printk(KERN_ERR PFX "Could not map the EFI memory map!\n");
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 290b7bc82da..dc7f938e501 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -251,6 +251,7 @@ check_userspace:
jb resume_kernel # not returning to v8086 or userspace
ENTRY(resume_userspace)
+ LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
@@ -338,6 +339,7 @@ sysenter_past_esp:
jae syscall_badsys
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp)
+ LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY)
TRACE_IRQS_OFF
movl TI_flags(%ebp), %ecx
@@ -377,6 +379,7 @@ syscall_call:
call *sys_call_table(,%eax,4)
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit:
+ LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
@@ -434,7 +437,7 @@ ldt_ss:
* is still available to implement the setting of the high
* 16-bits in the INTERRUPT_RETURN paravirt-op.
*/
- cmpl $0, paravirt_ops+PARAVIRT_enabled
+ cmpl $0, pv_info+PARAVIRT_enabled
jne restore_nocheck
#endif
@@ -467,6 +470,7 @@ work_pending:
jz work_notifysig
work_resched:
call schedule
+ LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1d232e5f565..3a058bb1640 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -244,6 +244,7 @@ ret_from_sys_call:
movl $_TIF_ALLWORK_MASK,%edi
/* edi: flagmask */
sysret_check:
+ LOCKDEP_SYS_EXIT
GET_THREAD_INFO(%rcx)
cli
TRACE_IRQS_OFF
@@ -333,6 +334,7 @@ int_ret_from_sys_call:
movl $_TIF_ALLWORK_MASK,%edi
/* edi: mask to check */
int_with_check:
+ LOCKDEP_SYS_EXIT_IRQ
GET_THREAD_INFO(%rcx)
movl threadinfo_flags(%rcx),%edx
andl %edi,%edx
@@ -544,11 +546,13 @@ exit_intr:
retint_with_reschedule:
movl $_TIF_WORK_MASK,%edi
retint_check:
+ LOCKDEP_SYS_EXIT_IRQ
movl threadinfo_flags(%rcx),%edx
andl %edi,%edx
CFI_REMEMBER_STATE
jnz retint_careful
-retint_swapgs:
+
+retint_swapgs: /* return to user-space */
/*
* The iretq could re-enable interrupts:
*/
@@ -557,7 +561,7 @@ retint_swapgs:
swapgs
jmp restore_args
-retint_restore_args:
+retint_restore_args: /* return to kernel space */
cli
/*
* The iretq could re-enable interrupts:
@@ -866,26 +870,21 @@ error_sti:
movq ORIG_RAX(%rsp),%rsi /* get error code */
movq $-1,ORIG_RAX(%rsp)
call *%rax
- /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
-error_exit:
- movl %ebx,%eax
+ /* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
+error_exit:
+ movl %ebx,%eax
RESTORE_REST
cli
TRACE_IRQS_OFF
GET_THREAD_INFO(%rcx)
testl %eax,%eax
jne retint_kernel
+ LOCKDEP_SYS_EXIT_IRQ
movl threadinfo_flags(%rcx),%edx
movl $_TIF_WORK_MASK,%edi
andl %edi,%edx
jnz retint_careful
- /*
- * The iret might restore flags:
- */
- TRACE_IRQS_IRETQ
- swapgs
- RESTORE_ARGS 0,8,0
- jmp iret_label
+ jmp retint_swapgs
CFI_ENDPROC
error_kernelspace:
@@ -989,7 +988,7 @@ child_rip:
movq %rsi, %rdi
call *%rax
# exit
- xorl %edi, %edi
+ mov %eax, %edi
call do_exit
CFI_ENDPROC
ENDPROC(child_rip)
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index 47496a40e84..4ae03e3e829 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -29,8 +29,6 @@ u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
= { [0 ... NR_CPUS-1] = BAD_APICID };
EXPORT_SYMBOL(x86_cpu_to_apicid);
-u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_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 ecb01eefdd2..91c7526768e 100644
--- a/arch/x86/kernel/genapic_flat_64.c
+++ b/arch/x86/kernel/genapic_flat_64.c
@@ -52,7 +52,6 @@ static void flat_init_apic_ldr(void)
num = smp_processor_id();
id = 1UL << num;
- x86_cpu_to_log_apicid[num] = id;
apic_write(APIC_DFR, APIC_DFR_FLAT);
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
val |= SET_APIC_LOGICAL_ID(id);
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 8561f626eda..a7eee0a4751 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -14,7 +14,6 @@
#include <asm/processor.h>
#include <asm/proto.h>
#include <asm/smp.h>
-#include <asm/bootsetup.h>
#include <asm/setup.h>
#include <asm/desc.h>
#include <asm/pgtable.h>
@@ -36,26 +35,15 @@ static void __init clear_bss(void)
(unsigned long) __bss_stop - (unsigned long) __bss_start);
}
-#define NEW_CL_POINTER 0x228 /* Relative to real mode data */
-#define OLD_CL_MAGIC_ADDR 0x20
-#define OLD_CL_MAGIC 0xA33F
-#define OLD_CL_OFFSET 0x22
-
static void __init copy_bootdata(char *real_mode_data)
{
- unsigned long new_data;
char * command_line;
- memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE);
- new_data = *(u32 *) (x86_boot_params + NEW_CL_POINTER);
- if (!new_data) {
- if (OLD_CL_MAGIC != *(u16 *)(real_mode_data + OLD_CL_MAGIC_ADDR)) {
- return;
- }
- new_data = __pa(real_mode_data) + *(u16 *)(real_mode_data + OLD_CL_OFFSET);
+ memcpy(&boot_params, real_mode_data, sizeof boot_params);
+ if (boot_params.hdr.cmd_line_ptr) {
+ command_line = __va(boot_params.hdr.cmd_line_ptr);
+ memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
}
- command_line = __va(new_data);
- memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
}
void __init x86_64_start_kernel(char * real_mode_data)
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 9150ca9b5f8..39677965e16 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -51,6 +51,15 @@
*/
LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
+/*
+ * To preserve the DMA pool in PAGEALLOC kernels, we'll allocate
+ * pagetables from above the 16MB DMA limit, so we'll have to set
+ * up pagetables 16MB more (worst-case):
+ */
+#ifdef CONFIG_DEBUG_PAGEALLOC
+LOW_PAGES = LOW_PAGES + 0x1000000
+#endif
+
#if PTRS_PER_PMD > 1
PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
#else
@@ -443,6 +452,7 @@ early_page_fault:
early_fault:
cld
#ifdef CONFIG_PRINTK
+ pusha
movl $(__KERNEL_DS),%eax
movl %eax,%ds
movl %eax,%es
@@ -534,8 +544,15 @@ int_msg:
.asciz "Unknown interrupt or fault at EIP %p %p %p\n"
fault_msg:
- .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n"
- .asciz "Stack: %p %p %p %p %p %p %p %p\n"
+ .ascii \
+/* fault info: */ "BUG: Int %d: CR2 %p\n" \
+/* pusha regs: */ " EDI %p ESI %p EBP %p ESP %p\n" \
+ " EBX %p EDX %p ECX %p EAX %p\n" \
+/* fault frame: */ " err %p EIP %p CS %p flg %p\n" \
+ \
+ "Stack: %p %p %p %p %p %p %p %p\n" \
+ " %p %p %p %p %p %p %p %p\n" \
+ " %p %p %p %p %p %p %p %p\n"
#include "../../x86/xen/xen-head.S"
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
index e3d4b73bfdb..edd39ccf139 100644
--- a/arch/x86/kernel/i386_ksyms_32.c
+++ b/arch/x86/kernel/i386_ksyms_32.c
@@ -1,4 +1,5 @@
#include <linux/module.h>
+#include <asm/semaphore.h>
#include <asm/checksum.h>
#include <asm/desc.h>
diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
index 679bb33acbf..d34a10cc13a 100644
--- a/arch/x86/kernel/i8259_32.c
+++ b/arch/x86/kernel/i8259_32.c
@@ -349,7 +349,11 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
* New motherboards sometimes make IRQ 13 be a PCI interrupt,
* so allow interrupt sharing.
*/
-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
+static struct irqaction fpu_irq = {
+ .handler = math_error_irq,
+ .mask = CPU_MASK_NONE,
+ .name = "fpu",
+};
void __init init_ISA_irqs (void)
{
diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c
index eb72976cc13..3f27ea0b981 100644
--- a/arch/x86/kernel/i8259_64.c
+++ b/arch/x86/kernel/i8259_64.c
@@ -395,7 +395,11 @@ device_initcall(i8259A_init_sysfs);
* IRQ2 is cascade interrupt to second interrupt controller
*/
-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
+static struct irqaction irq2 = {
+ .handler = no_action,
+ .mask = CPU_MASK_NONE,
+ .name = "cascade",
+};
DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
[0 ... IRQ0_VECTOR - 1] = -1,
[IRQ0_VECTOR] = 0,
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index e2f4a1c6854..5f10c718953 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -378,7 +378,7 @@ static struct irq_cpu_info {
#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask)
-#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i]))
+#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))
static cpumask_t balance_irq_affinity[NR_IRQS] = {
[0 ... NR_IRQS-1] = CPU_MASK_ALL
@@ -598,7 +598,7 @@ tryanotherirq:
* (A+B)/2 vs B
*/
load = CPU_IRQ(min_loaded) >> 1;
- for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) {
+ for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) {
if (load > CPU_IRQ(j)) {
/* This won't change cpu_sibling_map[min_loaded] */
load = CPU_IRQ(j);
@@ -1296,6 +1296,11 @@ static void __init setup_IO_APIC_irqs(void)
continue;
}
+ if (!first_notcon) {
+ apic_printk(APIC_VERBOSE, " not connected.\n");
+ first_notcon = 1;
+ }
+
entry.trigger = irq_trigger(idx);
entry.polarity = irq_polarity(idx);
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 966fa106249..1c2c7bf6a9d 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -875,6 +875,10 @@ static void __init setup_IO_APIC_irqs(void)
apic_printk(APIC_VERBOSE, ", %d-%d", mp_ioapics[apic].mpc_apicid, pin);
continue;
}
+ if (!first_notcon) {
+ apic_printk(APIC_VERBOSE, " not connected.\n");
+ first_notcon = 1;
+ }
irq = pin_2_irq(idx, apic, pin);
add_pin_to_irq(irq, apic, pin);
@@ -885,7 +889,7 @@ static void __init setup_IO_APIC_irqs(void)
}
if (!first_notcon)
- apic_printk(APIC_VERBOSE," not connected.\n");
+ apic_printk(APIC_VERBOSE, " not connected.\n");
}
/*
@@ -1845,7 +1849,7 @@ static struct sysdev_class ioapic_sysdev_class = {
static int __init ioapic_init_sysfs(void)
{
struct sys_device * dev;
- int i, size, error = 0;
+ int i, size, error;
error = sysdev_class_register(&ioapic_sysdev_class);
if (error)
@@ -1854,12 +1858,11 @@ static int __init ioapic_init_sysfs(void)
for (i = 0; i < nr_ioapics; i++ ) {
size = sizeof(struct sys_device) + nr_ioapic_registers[i]
* sizeof(struct IO_APIC_route_entry);
- mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL);
+ mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL);
if (!mp_ioapic_data[i]) {
printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
continue;
}
- memset(mp_ioapic_data[i], 0, size);
dev = &mp_ioapic_data[i]->dev;
dev->id = i;
dev->cls = &ioapic_sysdev_class;
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index e173b763f14..d3fde94f734 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -255,9 +255,17 @@ int show_interrupts(struct seq_file *p, void *v)
}
if (i < NR_IRQS) {
+ unsigned any_count = 0;
+
spin_lock_irqsave(&irq_desc[i].lock, flags);
+#ifndef CONFIG_SMP
+ any_count = kstat_irqs(i);
+#else
+ for_each_online_cpu(j)
+ any_count |= kstat_cpu(j).irqs[i];
+#endif
action = irq_desc[i].action;
- if (!action)
+ if (!action && !any_count)
goto skip;
seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
@@ -268,10 +276,12 @@ int show_interrupts(struct seq_file *p, void *v)
#endif
seq_printf(p, " %8s", irq_desc[i].chip->name);
seq_printf(p, "-%-8s", irq_desc[i].name);
- seq_printf(p, " %s", action->name);
- for (action=action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
+ if (action) {
+ seq_printf(p, " %s", action->name);
+ while ((action = action->next) != NULL)
+ seq_printf(p, ", %s", action->name);
+ }
seq_putc(p, '\n');
skip:
@@ -280,14 +290,41 @@ skip:
seq_printf(p, "NMI: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ", nmi_count(j));
- seq_putc(p, '\n');
+ seq_printf(p, " Non-maskable interrupts\n");
#ifdef CONFIG_X86_LOCAL_APIC
seq_printf(p, "LOC: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ",
per_cpu(irq_stat,j).apic_timer_irqs);
- seq_putc(p, '\n');
+ seq_printf(p, " Local timer interrupts\n");
#endif
+#ifdef CONFIG_SMP
+ seq_printf(p, "RES: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ per_cpu(irq_stat,j).irq_resched_count);
+ seq_printf(p, " Rescheduling interrupts\n");
+ seq_printf(p, "CAL: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ per_cpu(irq_stat,j).irq_call_count);
+ seq_printf(p, " function call interrupts\n");
+ seq_printf(p, "TLB: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ per_cpu(irq_stat,j).irq_tlb_count);
+ seq_printf(p, " TLB shootdowns\n");
+#endif
+ seq_printf(p, "TRM: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ per_cpu(irq_stat,j).irq_thermal_count);
+ seq_printf(p, " Thermal event interrupts\n");
+ seq_printf(p, "SPU: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ",
+ per_cpu(irq_stat,j).irq_spurious_count);
+ seq_printf(p, " Spurious interrupts\n");
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
#if defined(CONFIG_X86_IO_APIC)
seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 865669efc54..6b5c730d67b 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -62,9 +62,17 @@ int show_interrupts(struct seq_file *p, void *v)
}
if (i < NR_IRQS) {
+ unsigned any_count = 0;
+
spin_lock_irqsave(&irq_desc[i].lock, flags);
+#ifndef CONFIG_SMP
+ any_count = kstat_irqs(i);
+#else
+ for_each_online_cpu(j)
+ any_count |= kstat_cpu(j).irqs[i];
+#endif
action = irq_desc[i].action;
- if (!action)
+ if (!action && !any_count)
goto skip;
seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
@@ -76,9 +84,11 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, " %8s", irq_desc[i].chip->name);
seq_printf(p, "-%-8s", irq_desc[i].name);
- seq_printf(p, " %s", action->name);
- for (action=action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
+ if (action) {
+ seq_printf(p, " %s", action->name);
+ while ((action = action->next) != NULL)
+ seq_printf(p, ", %s", action->name);
+ }
seq_putc(p, '\n');
skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
@@ -86,11 +96,37 @@ skip:
seq_printf(p, "NMI: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
- seq_putc(p, '\n');
+ seq_printf(p, " Non-maskable interrupts\n");
seq_printf(p, "LOC: ");
for_each_online_cpu(j)
seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
- seq_putc(p, '\n');
+ seq_printf(p, " Local timer interrupts\n");
+#ifdef CONFIG_SMP
+ seq_printf(p, "RES: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->irq_resched_count);
+ seq_printf(p, " Rescheduling interrupts\n");
+ seq_printf(p, "CAL: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count);
+ seq_printf(p, " function call interrupts\n");
+ seq_printf(p, "TLB: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
+ seq_printf(p, " TLB shootdowns\n");
+#endif
+ seq_printf(p, "TRM: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->irq_thermal_count);
+ seq_printf(p, " Thermal event interrupts\n");
+ seq_printf(p, "THR: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->irq_threshold_count);
+ seq_printf(p, " Threshold APIC interrupts\n");
+ seq_printf(p, "SPU: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->irq_spurious_count);
+ seq_printf(p, " Spurious interrupts\n");
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
}
return 0;
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index c2d03e96ae9..90f778c04b3 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -41,6 +41,13 @@ void jprobe_return_end(void);
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+struct kretprobe_blackpoint kretprobe_blacklist[] = {
+ {"__switch_to", }, /* This function switches only current task, but
+ doesn't switch kernel stack.*/
+ {NULL, NULL} /* Terminator */
+};
+const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
+
/* insert a jmp code */
static __always_inline void set_jmp_op(void *from, void *to)
{
@@ -557,6 +564,12 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
resume_execution(cur, regs, kcb);
regs->eflags |= kcb->kprobe_saved_eflags;
+#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
+ if (raw_irqs_disabled_flags(regs->eflags))
+ trace_hardirqs_off();
+ else
+ trace_hardirqs_on();
+#endif
/*Restore back the original saved kprobes variables and continue. */
if (kcb->kprobe_status == KPROBE_REENTER) {
@@ -578,7 +591,7 @@ out:
return 1;
}
-static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -660,7 +673,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
ret = NOTIFY_STOP;
break;
case DIE_GPF:
- case DIE_PAGE_FAULT:
/* kprobe_running() needs smp_processor_id() */
preempt_disable();
if (kprobe_running() &&
@@ -694,6 +706,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
MIN_STACK_SIZE(addr));
regs->eflags &= ~IF_MASK;
+ trace_hardirqs_off();
regs->eip = (unsigned long)(jp->entry);
return 1;
}
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index 1df17a0ec0c..681b801c5e2 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -48,6 +48,13 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p);
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+struct kretprobe_blackpoint kretprobe_blacklist[] = {
+ {"__switch_to", }, /* This function switches only current task, but
+ doesn't switch kernel stack.*/
+ {NULL, NULL} /* Terminator */
+};
+const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
+
/*
* returns non-zero if opcode modifies the interrupt flag.
*/
@@ -544,6 +551,12 @@ int __kprobes post_kprobe_handler(struct pt_regs *regs)
resume_execution(cur, regs, kcb);
regs->eflags |= kcb->kprobe_saved_rflags;
+#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
+ if (raw_irqs_disabled_flags(regs->eflags))
+ trace_hardirqs_off();
+ else
+ trace_hardirqs_on();
+#endif
/* Restore the original saved kprobes variables and continue. */
if (kcb->kprobe_status == KPROBE_REENTER) {
@@ -651,7 +664,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
ret = NOTIFY_STOP;
break;
case DIE_GPF:
- case DIE_PAGE_FAULT:
/* kprobe_running() needs smp_processor_id() */
preempt_disable();
if (kprobe_running() &&
@@ -684,6 +696,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
MIN_STACK_SIZE(addr));
regs->eflags &= ~IF_MASK;
+ trace_hardirqs_off();
regs->rip = (unsigned long)(jp->entry);
return 1;
}
diff --git a/arch/x86/kernel/ldt_32.c b/arch/x86/kernel/ldt_32.c
index a8b18421863..9ff90a27c45 100644
--- a/arch/x86/kernel/ldt_32.c
+++ b/arch/x86/kernel/ldt_32.c
@@ -92,13 +92,13 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
struct mm_struct * old_mm;
int retval = 0;
- init_MUTEX(&mm->context.sem);
+ mutex_init(&mm->context.lock);
mm->context.size = 0;
old_mm = current->mm;
if (old_mm && old_mm->context.size > 0) {
- down(&old_mm->context.sem);
+ mutex_lock(&old_mm->context.lock);
retval = copy_ldt(&mm->context, &old_mm->context);
- up(&old_mm->context.sem);
+ mutex_unlock(&old_mm->context.lock);
}
return retval;
}
@@ -130,7 +130,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
- down(&mm->context.sem);
+ mutex_lock(&mm->context.lock);
size = mm->context.size*LDT_ENTRY_SIZE;
if (size > bytecount)
size = bytecount;
@@ -138,7 +138,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
err = 0;
if (copy_to_user(ptr, mm->context.ldt, size))
err = -EFAULT;
- up(&mm->context.sem);
+ mutex_unlock(&mm->context.lock);
if (err < 0)
goto error_return;
if (size != bytecount) {
@@ -194,7 +194,7 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
goto out;
}
- down(&mm->context.sem);
+ mutex_lock(&mm->context.lock);
if (ldt_info.entry_number >= mm->context.size) {
error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
if (error < 0)
@@ -221,7 +221,7 @@ install:
error = 0;
out_unlock:
- up(&mm->context.sem);
+ mutex_unlock(&mm->context.lock);
out:
return error;
}
diff --git a/arch/x86/kernel/ldt_64.c b/arch/x86/kernel/ldt_64.c
index 3796523d616..60e57abb8e9 100644
--- a/arch/x86/kernel/ldt_64.c
+++ b/arch/x86/kernel/ldt_64.c
@@ -96,13 +96,13 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
struct mm_struct * old_mm;
int retval = 0;
- init_MUTEX(&mm->context.sem);
+ mutex_init(&mm->context.lock);
mm->context.size = 0;
old_mm = current->mm;
if (old_mm && old_mm->context.size > 0) {
- down(&old_mm->context.sem);
+ mutex_lock(&old_mm->context.lock);
retval = copy_ldt(&mm->context, &old_mm->context);
- up(&old_mm->context.sem);
+ mutex_unlock(&old_mm->context.lock);
}
return retval;
}
@@ -133,7 +133,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
- down(&mm->context.sem);
+ mutex_lock(&mm->context.lock);
size = mm->context.size*LDT_ENTRY_SIZE;
if (size > bytecount)
size = bytecount;
@@ -141,7 +141,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
err = 0;
if (copy_to_user(ptr, mm->context.ldt, size))
err = -EFAULT;
- up(&mm->context.sem);
+ mutex_unlock(&mm->context.lock);
if (err < 0)
goto error_return;
if (size != bytecount) {
@@ -193,7 +193,7 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
goto out;
}
- down(&mm->context.sem);
+ mutex_lock(&mm->context.lock);
if (ldt_info.entry_number >= (unsigned)mm->context.size) {
error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
if (error < 0)
@@ -223,7 +223,7 @@ install:
error = 0;
out_unlock:
- up(&mm->context.sem);
+ mutex_unlock(&mm->context.lock);
out:
return error;
}
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index deda9a221cf..8459ca64bc2 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -10,6 +10,7 @@
#include <linux/kexec.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/numa.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
@@ -169,3 +170,15 @@ static int __init parse_crashkernel(char *arg)
return 0;
}
early_param("crashkernel", parse_crashkernel);
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ VMCOREINFO_SYMBOL(node_data);
+ VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
+#endif
+#ifdef CONFIG_X86_PAE
+ VMCOREINFO_CONFIG(X86_PAE);
+#endif
+}
+
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index cd1899a2f0c..7450b69710b 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -10,6 +10,7 @@
#include <linux/kexec.h>
#include <linux/string.h>
#include <linux/reboot.h>
+#include <linux/numa.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/mmu_context.h>
@@ -257,3 +258,11 @@ static int __init setup_crashkernel(char *arg)
}
early_param("crashkernel", setup_crashkernel);
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
+ VMCOREINFO_SYMBOL(node_data);
+ VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
+#endif
+}
+
diff --git a/arch/x86/kernel/mce_64.c b/arch/x86/kernel/mce_64.c
index a66d607f5b9..66e6b797b2c 100644
--- a/arch/x86/kernel/mce_64.c
+++ b/arch/x86/kernel/mce_64.c
@@ -76,9 +76,6 @@ void mce_log(struct mce *mce)
wmb();
for (;;) {
entry = rcu_dereference(mcelog.next);
- /* The rmb forces the compiler to reload next in each
- iteration */
- rmb();
for (;;) {
/* When the buffer fills up discard new entries. Assume
that the earlier errors are the more interesting. */
@@ -698,8 +695,6 @@ static int __init mcheck_disable(char *str)
mce=nobootlog Don't log MCEs from before booting. */
static int __init mcheck_enable(char *str)
{
- if (*str == '=')
- str++;
if (!strcmp(str, "off"))
mce_dont_init = 1;
else if (!strcmp(str, "bootlog") || !strcmp(str,"nobootlog"))
@@ -712,7 +707,7 @@ static int __init mcheck_enable(char *str)
}
__setup("nomce", mcheck_disable);
-__setup("mce", mcheck_enable);
+__setup("mce=", mcheck_enable);
/*
* Sysfs support
@@ -807,16 +802,29 @@ static __cpuinit int mce_create_device(unsigned int cpu)
if (!mce_available(&cpu_data[cpu]))
return -EIO;
+ memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
per_cpu(device_mce,cpu).id = cpu;
per_cpu(device_mce,cpu).cls = &mce_sysclass;
err = sysdev_register(&per_cpu(device_mce,cpu));
+ if (err)
+ return err;
+
+ for (i = 0; mce_attributes[i]; i++) {
+ err = sysdev_create_file(&per_cpu(device_mce,cpu),
+ mce_attributes[i]);
+ if (err)
+ goto error;
+ }
- if (!err) {
- for (i = 0; mce_attributes[i]; i++)
- sysdev_create_file(&per_cpu(device_mce,cpu),
- mce_attributes[i]);
+ return 0;
+error:
+ while (i--) {
+ sysdev_remove_file(&per_cpu(device_mce,cpu),
+ mce_attributes[i]);
}
+ sysdev_unregister(&per_cpu(device_mce,cpu));
+
return err;
}
@@ -828,7 +836,6 @@ static void mce_remove_device(unsigned int cpu)
sysdev_remove_file(&per_cpu(device_mce,cpu),
mce_attributes[i]);
sysdev_unregister(&per_cpu(device_mce,cpu));
- memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
}
/* Get notified when a cpu comes on/off. Be hotplug friendly. */
@@ -836,18 +843,21 @@ static int
mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
+ int err = 0;
switch (action) {
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- mce_create_device(cpu);
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ err = mce_create_device(cpu);
break;
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
mce_remove_device(cpu);
break;
}
- return NOTIFY_OK;
+ return err ? NOTIFY_BAD : NOTIFY_OK;
}
static struct notifier_block mce_cpu_notifier = {
@@ -862,9 +872,13 @@ static __init int mce_init_device(void)
if (!mce_available(&boot_cpu_data))
return -EIO;
err = sysdev_class_register(&mce_sysclass);
+ if (err)
+ return err;
for_each_online_cpu(i) {
- mce_create_device(i);
+ err = mce_create_device(i);
+ if (err)
+ return err;
}
register_hotcpu_notifier(&mce_cpu_notifier);
diff --git a/arch/x86/kernel/mce_amd_64.c b/arch/x86/kernel/mce_amd_64.c
index 2f8a7f18b0f..0d2afd96aca 100644
--- a/arch/x86/kernel/mce_amd_64.c
+++ b/arch/x86/kernel/mce_amd_64.c
@@ -237,6 +237,7 @@ asmlinkage void mce_threshold_interrupt(void)
}
}
out:
+ add_pda(irq_threshold_count, 1);
irq_exit();
}
@@ -472,7 +473,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifdef CONFIG_SMP
if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */
- i = first_cpu(cpu_core_map[cpu]);
+ i = first_cpu(per_cpu(cpu_core_map, cpu));
/* first core not up yet */
if (cpu_data[i].cpu_core_id)
@@ -492,7 +493,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
if (err)
goto out;
- b->cpus = cpu_core_map[cpu];
+ b->cpus = per_cpu(cpu_core_map, cpu);
per_cpu(threshold_banks, cpu)[bank] = b;
goto out;
}
@@ -509,7 +510,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifndef CONFIG_SMP
b->cpus = CPU_MASK_ALL;
#else
- b->cpus = cpu_core_map[cpu];
+ b->cpus = per_cpu(cpu_core_map, cpu);
#endif
err = kobject_register(&b->kobj);
if (err)
diff --git a/arch/x86/kernel/mce_intel_64.c b/arch/x86/kernel/mce_intel_64.c
index 6551505d8a2..c17eaf5dd6d 100644
--- a/arch/x86/kernel/mce_intel_64.c
+++ b/arch/x86/kernel/mce_intel_64.c
@@ -26,6 +26,7 @@ asmlinkage void smp_thermal_interrupt(void)
if (therm_throt_process(msr_val & 1))
mce_log_therm_throt_event(smp_processor_id(), msr_val);
+ add_pda(irq_thermal_count, 1);
irq_exit();
}
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index c044de310b6..e18e516cf54 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -133,37 +133,42 @@ static const struct file_operations msr_fops = {
.open = msr_open,
};
-static int msr_device_create(int i)
+static int __cpuinit msr_device_create(int cpu)
{
- int err = 0;
struct device *dev;
- dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i);
- if (IS_ERR(dev))
- err = PTR_ERR(dev);
- return err;
+ dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
+ "msr%d", cpu);
+ return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
-static int msr_class_cpu_callback(struct notifier_block *nfb,
+static void msr_device_destroy(int cpu)
+{
+ device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+}
+
+static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
+ int err = 0;
switch (action) {
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- msr_device_create(cpu);
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ err = msr_device_create(cpu);
break;
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+ msr_device_destroy(cpu);
break;
}
- return NOTIFY_OK;
+ return err ? NOTIFY_BAD : NOTIFY_OK;
}
-static struct notifier_block __cpuinitdata msr_class_cpu_notifier =
-{
+static struct notifier_block __cpuinitdata msr_class_cpu_notifier = {
.notifier_call = msr_class_cpu_callback,
};
@@ -196,7 +201,7 @@ static int __init msr_init(void)
out_class:
i = 0;
for_each_online_cpu(i)
- device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
+ msr_device_destroy(i);
class_destroy(msr_class);
out_chrdev:
unregister_chrdev(MSR_MAJOR, "cpu/msr");
@@ -208,7 +213,7 @@ static void __exit msr_exit(void)
{
int cpu = 0;
for_each_online_cpu(cpu)
- device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+ msr_device_destroy(cpu);
class_destroy(msr_class);
unregister_chrdev(MSR_MAJOR, "cpu/msr");
unregister_hotcpu_notifier(&msr_class_cpu_notifier);
diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt_32.c
index 739cfb207dd..6a80d67c212 100644
--- a/arch/x86/kernel/paravirt_32.c
+++ b/arch/x86/kernel/paravirt_32.c
@@ -42,32 +42,33 @@ void _paravirt_nop(void)
static void __init default_banner(void)
{
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
- paravirt_ops.name);
+ pv_info.name);
}
char *memory_setup(void)
{
- return paravirt_ops.memory_setup();
+ return pv_init_ops.memory_setup();
}
/* Simple instruction patching code. */
-#define DEF_NATIVE(name, code) \
- extern const char start_##name[], end_##name[]; \
- asm("start_" #name ": " code "; end_" #name ":")
-
-DEF_NATIVE(irq_disable, "cli");
-DEF_NATIVE(irq_enable, "sti");
-DEF_NATIVE(restore_fl, "push %eax; popf");
-DEF_NATIVE(save_fl, "pushf; pop %eax");
-DEF_NATIVE(iret, "iret");
-DEF_NATIVE(irq_enable_sysexit, "sti; sysexit");
-DEF_NATIVE(read_cr2, "mov %cr2, %eax");
-DEF_NATIVE(write_cr3, "mov %eax, %cr3");
-DEF_NATIVE(read_cr3, "mov %cr3, %eax");
-DEF_NATIVE(clts, "clts");
-DEF_NATIVE(read_tsc, "rdtsc");
-
-DEF_NATIVE(ud2a, "ud2a");
+#define DEF_NATIVE(ops, name, code) \
+ extern const char start_##ops##_##name[], end_##ops##_##name[]; \
+ asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
+
+DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
+DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
+DEF_NATIVE(pv_irq_ops, restore_fl, "push %eax; popf");
+DEF_NATIVE(pv_irq_ops, save_fl, "pushf; pop %eax");
+DEF_NATIVE(pv_cpu_ops, iret, "iret");
+DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "sti; sysexit");
+DEF_NATIVE(pv_mmu_ops, read_cr2, "mov %cr2, %eax");
+DEF_NATIVE(pv_mmu_ops, write_cr3, "mov %eax, %cr3");
+DEF_NATIVE(pv_mmu_ops, read_cr3, "mov %cr3, %eax");
+DEF_NATIVE(pv_cpu_ops, clts, "clts");
+DEF_NATIVE(pv_cpu_ops, read_tsc, "rdtsc");
+
+/* Undefined instruction for dealing with missing ops pointers. */
+static const unsigned char ud2a[] = { 0x0f, 0x0b };
static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
unsigned long addr, unsigned len)
@@ -76,37 +77,29 @@ static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
unsigned ret;
switch(type) {
-#define SITE(x) case PARAVIRT_PATCH(x): start = start_##x; end = end_##x; goto patch_site
- SITE(irq_disable);
- SITE(irq_enable);
- SITE(restore_fl);
- SITE(save_fl);
- SITE(iret);
- SITE(irq_enable_sysexit);
- SITE(read_cr2);
- SITE(read_cr3);
- SITE(write_cr3);
- SITE(clts);
- SITE(read_tsc);
+#define SITE(ops, x) \
+ case PARAVIRT_PATCH(ops.x): \
+ start = start_##ops##_##x; \
+ end = end_##ops##_##x; \
+ goto patch_site
+
+ SITE(pv_irq_ops, irq_disable);
+ SITE(pv_irq_ops, irq_enable);
+ SITE(pv_irq_ops, restore_fl);
+ SITE(pv_irq_ops, save_fl);
+ SITE(pv_cpu_ops, iret);
+ SITE(pv_cpu_ops, irq_enable_sysexit);
+ SITE(pv_mmu_ops, read_cr2);
+ SITE(pv_mmu_ops, read_cr3);
+ SITE(pv_mmu_ops, write_cr3);
+ SITE(pv_cpu_ops, clts);
+ SITE(pv_cpu_ops, read_tsc);
#undef SITE
patch_site:
ret = paravirt_patch_insns(ibuf, len, start, end);
break;
- case PARAVIRT_PATCH(make_pgd):
- case PARAVIRT_PATCH(make_pte):
- case PARAVIRT_PATCH(pgd_val):
- case PARAVIRT_PATCH(pte_val):
-#ifdef CONFIG_X86_PAE
- case PARAVIRT_PATCH(make_pmd):
- case PARAVIRT_PATCH(pmd_val):
-#endif
- /* These functions end up returning exactly what
- they're passed, in the same registers. */
- ret = paravirt_patch_nop();
- break;
-
default:
ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
break;
@@ -150,7 +143,7 @@ unsigned paravirt_patch_call(void *insnbuf,
return 5;
}
-unsigned paravirt_patch_jmp(const void *target, void *insnbuf,
+unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
unsigned long addr, unsigned len)
{
struct branch *b = insnbuf;
@@ -165,22 +158,37 @@ unsigned paravirt_patch_jmp(const void *target, void *insnbuf,
return 5;
}
+/* Neat trick to map patch type back to the call within the
+ * corresponding structure. */
+static void *get_call_destination(u8 type)
+{
+ struct paravirt_patch_template tmpl = {
+ .pv_init_ops = pv_init_ops,
+ .pv_time_ops = pv_time_ops,
+ .pv_cpu_ops = pv_cpu_ops,
+ .pv_irq_ops = pv_irq_ops,
+ .pv_apic_ops = pv_apic_ops,
+ .pv_mmu_ops = pv_mmu_ops,
+ };
+ return *((void **)&tmpl + type);
+}
+
unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
unsigned long addr, unsigned len)
{
- void *opfunc = *((void **)&paravirt_ops + type);
+ void *opfunc = get_call_destination(type);
unsigned ret;
if (opfunc == NULL)
/* If there's no function, patch it with a ud2a (BUG) */
- ret = paravirt_patch_insns(insnbuf, len, start_ud2a, end_ud2a);
+ ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
else if (opfunc == paravirt_nop)
/* If the operation is a nop, then nop the callsite */
ret = paravirt_patch_nop();
- else if (type == PARAVIRT_PATCH(iret) ||
- type == PARAVIRT_PATCH(irq_enable_sysexit))
+ else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
+ type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit))
/* If operation requires a jmp, then jmp */
- ret = paravirt_patch_jmp(opfunc, insnbuf, addr, len);
+ ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len);
else
/* Otherwise call the function; assume target could
clobber any caller-save reg */
@@ -205,7 +213,7 @@ unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
void init_IRQ(void)
{
- paravirt_ops.init_IRQ();
+ pv_irq_ops.init_IRQ();
}
static void native_flush_tlb(void)
@@ -233,7 +241,7 @@ extern void native_irq_enable_sysexit(void);
static int __init print_banner(void)
{
- paravirt_ops.banner();
+ pv_init_ops.banner();
return 0;
}
core_initcall(print_banner);
@@ -273,47 +281,96 @@ int paravirt_disable_iospace(void)
return ret;
}
-struct paravirt_ops paravirt_ops = {
+static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LAZY_NONE;
+
+static inline void enter_lazy(enum paravirt_lazy_mode mode)
+{
+ BUG_ON(x86_read_percpu(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
+ BUG_ON(preemptible());
+
+ x86_write_percpu(paravirt_lazy_mode, mode);
+}
+
+void paravirt_leave_lazy(enum paravirt_lazy_mode mode)
+{
+ BUG_ON(x86_read_percpu(paravirt_lazy_mode) != mode);
+ BUG_ON(preemptible());
+
+ x86_write_percpu(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
+}
+
+void paravirt_enter_lazy_mmu(void)
+{
+ enter_lazy(PARAVIRT_LAZY_MMU);
+}
+
+void paravirt_leave_lazy_mmu(void)
+{
+ paravirt_leave_lazy(PARAVIRT_LAZY_MMU);
+}
+
+void paravirt_enter_lazy_cpu(void)
+{
+ enter_lazy(PARAVIRT_LAZY_CPU);
+}
+
+void paravirt_leave_lazy_cpu(void)
+{
+ paravirt_leave_lazy(PARAVIRT_LAZY_CPU);
+}
+
+enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
+{
+ return x86_read_percpu(paravirt_lazy_mode);
+}
+
+struct pv_info pv_info = {
.name = "bare hardware",
.paravirt_enabled = 0,
.kernel_rpl = 0,
.shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
+};
- .patch = native_patch,
+struct pv_init_ops pv_init_ops = {
+ .patch = native_patch,
.banner = default_banner,
.arch_setup = paravirt_nop,
.memory_setup = machine_specific_memory_setup,
+};
+
+struct pv_time_ops pv_time_ops = {
+ .time_init = hpet_time_init,
.get_wallclock = native_get_wallclock,
.set_wallclock = native_set_wallclock,
- .time_init = hpet_time_init,
+ .sched_clock = native_sched_clock,
+ .get_cpu_khz = native_calculate_cpu_khz,
+};
+
+struct pv_irq_ops pv_irq_ops = {
.init_IRQ = native_init_IRQ,
+ .save_fl = native_save_fl,
+ .restore_fl = native_restore_fl,
+ .irq_disable = native_irq_disable,
+ .irq_enable = native_irq_enable,
+ .safe_halt = native_safe_halt,
+ .halt = native_halt,
+};
+struct pv_cpu_ops pv_cpu_ops = {
.cpuid = native_cpuid,
.get_debugreg = native_get_debugreg,
.set_debugreg = native_set_debugreg,
.clts = native_clts,
.read_cr0 = native_read_cr0,
.write_cr0 = native_write_cr0,
- .read_cr2 = native_read_cr2,
- .write_cr2 = native_write_cr2,
- .read_cr3 = native_read_cr3,
- .write_cr3 = native_write_cr3,
.read_cr4 = native_read_cr4,
.read_cr4_safe = native_read_cr4_safe,
.write_cr4 = native_write_cr4,
- .save_fl = native_save_fl,
- .restore_fl = native_restore_fl,
- .irq_disable = native_irq_disable,
- .irq_enable = native_irq_enable,
- .safe_halt = native_safe_halt,
- .halt = native_halt,
.wbinvd = native_wbinvd,
.read_msr = native_read_msr_safe,
.write_msr = native_write_msr_safe,
.read_tsc = native_read_tsc,
.read_pmc = native_read_pmc,
- .sched_clock = native_sched_clock,
- .get_cpu_khz = native_calculate_cpu_khz,
.load_tr_desc = native_load_tr_desc,
.set_ldt = native_set_ldt,
.load_gdt = native_load_gdt,
@@ -327,9 +384,19 @@ struct paravirt_ops paravirt_ops = {
.write_idt_entry = write_dt_entry,
.load_esp0 = native_load_esp0,
+ .irq_enable_sysexit = native_irq_enable_sysexit,
+ .iret = native_iret,
+
.set_iopl_mask = native_set_iopl_mask,
.io_delay = native_io_delay,
+ .lazy_mode = {
+ .enter = paravirt_nop,
+ .leave = paravirt_nop,
+ },
+};
+
+struct pv_apic_ops pv_apic_ops = {
#ifdef CONFIG_X86_LOCAL_APIC
.apic_write = native_apic_write,
.apic_write_atomic = native_apic_write_atomic,
@@ -338,11 +405,17 @@ struct paravirt_ops paravirt_ops = {
.setup_secondary_clock = setup_secondary_APIC_clock,
.startup_ipi_hook = paravirt_nop,
#endif
- .set_lazy_mode = paravirt_nop,
+};
+struct pv_mmu_ops pv_mmu_ops = {
.pagetable_setup_start = native_pagetable_setup_start,
.pagetable_setup_done = native_pagetable_setup_done,
+ .read_cr2 = native_read_cr2,
+ .write_cr2 = native_write_cr2,
+ .read_cr3 = native_read_cr3,
+ .write_cr3 = native_write_cr3,
+
.flush_tlb_user = native_flush_tlb,
.flush_tlb_kernel = native_flush_tlb_global,
.flush_tlb_single = native_flush_tlb_single,
@@ -381,12 +454,19 @@ struct paravirt_ops paravirt_ops = {
.make_pte = native_make_pte,
.make_pgd = native_make_pgd,
- .irq_enable_sysexit = native_irq_enable_sysexit,
- .iret = native_iret,
-
.dup_mmap = paravirt_nop,
.exit_mmap = paravirt_nop,
.activate_mm = paravirt_nop,
+
+ .lazy_mode = {
+ .enter = paravirt_nop,
+ .leave = paravirt_nop,
+ },
};
-EXPORT_SYMBOL(paravirt_ops);
+EXPORT_SYMBOL_GPL(pv_time_ops);
+EXPORT_SYMBOL_GPL(pv_cpu_ops);
+EXPORT_SYMBOL_GPL(pv_mmu_ops);
+EXPORT_SYMBOL_GPL(pv_apic_ops);
+EXPORT_SYMBOL_GPL(pv_info);
+EXPORT_SYMBOL (pv_irq_ops);
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 71da01e73f0..5098f58063a 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -35,6 +35,7 @@
#include <linux/pci_ids.h>
#include <linux/pci.h>
#include <linux/delay.h>
+#include <linux/scatterlist.h>
#include <asm/iommu.h>
#include <asm/calgary.h>
#include <asm/tce.h>
@@ -221,10 +222,10 @@ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
return npages;
}
-static inline int translate_phb(struct pci_dev* dev)
+static inline int translation_enabled(struct iommu_table *tbl)
{
- int disabled = bus_info[dev->bus->number].translation_disabled;
- return !disabled;
+ /* only PHBs with translation enabled have an IOMMU table */
+ return (tbl != NULL);
}
static void iommu_range_reserve(struct iommu_table *tbl,
@@ -384,31 +385,32 @@ static void calgary_unmap_sg(struct device *dev,
struct scatterlist *sglist, int nelems, int direction)
{
struct iommu_table *tbl = find_iommu_table(dev);
+ struct scatterlist *s;
+ int i;
- if (!translate_phb(to_pci_dev(dev)))
+ if (!translation_enabled(tbl))
return;
- while (nelems--) {
+ for_each_sg(sglist, s, nelems, i) {
unsigned int npages;
- dma_addr_t dma = sglist->dma_address;
- unsigned int dmalen = sglist->dma_length;
+ dma_addr_t dma = s->dma_address;
+ unsigned int dmalen = s->dma_length;
if (dmalen == 0)
break;
npages = num_dma_pages(dma, dmalen);
iommu_free(tbl, dma, npages);
- sglist++;
}
}
static int calgary_nontranslate_map_sg(struct device* dev,
struct scatterlist *sg, int nelems, int direction)
{
+ struct scatterlist *s;
int i;
- for (i = 0; i < nelems; i++ ) {
- struct scatterlist *s = &sg[i];
+ for_each_sg(sg, s, nelems, i) {
BUG_ON(!s->page);
s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
s->dma_length = s->length;
@@ -420,16 +422,16 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
int nelems, int direction)
{
struct iommu_table *tbl = find_iommu_table(dev);
+ struct scatterlist *s;
unsigned long vaddr;
unsigned int npages;
unsigned long entry;
int i;
- if (!translate_phb(to_pci_dev(dev)))
+ if (!translation_enabled(tbl))
return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
- for (i = 0; i < nelems; i++ ) {
- struct scatterlist *s = &sg[i];
+ for_each_sg(sg, s, nelems, i) {
BUG_ON(!s->page);
vaddr = (unsigned long)page_address(s->page) + s->offset;
@@ -454,9 +456,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
return nelems;
error:
calgary_unmap_sg(dev, sg, nelems, direction);
- for (i = 0; i < nelems; i++) {
- sg[i].dma_address = bad_dma_address;
- sg[i].dma_length = 0;
+ for_each_sg(sg, s, nelems, i) {
+ sg->dma_address = bad_dma_address;
+ sg->dma_length = 0;
}
return 0;
}
@@ -472,7 +474,7 @@ static dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
uaddr = (unsigned long)vaddr;
npages = num_dma_pages(uaddr, size);
- if (translate_phb(to_pci_dev(dev)))
+ if (translation_enabled(tbl))
dma_handle = iommu_alloc(tbl, vaddr, npages, direction);
else
dma_handle = virt_to_bus(vaddr);
@@ -486,7 +488,7 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
struct iommu_table *tbl = find_iommu_table(dev);
unsigned int npages;
- if (!translate_phb(to_pci_dev(dev)))
+ if (!translation_enabled(tbl))
return;
npages = num_dma_pages(dma_handle, size);
@@ -511,7 +513,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size,
goto error;
memset(ret, 0, size);
- if (translate_phb(to_pci_dev(dev))) {
+ if (translation_enabled(tbl)) {
/* set up tces to cover the allocated range */
mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL);
if (mapping == bad_dma_address)
@@ -1192,7 +1194,7 @@ static int __init calgary_init(void)
{
int ret;
struct pci_dev *dev = NULL;
- void *tce_space;
+ struct calgary_bus_info *info;
ret = calgary_locate_bbars();
if (ret)
@@ -1204,12 +1206,14 @@ static int __init calgary_init(void)
break;
if (!is_cal_pci_dev(dev->device))
continue;
- if (!translate_phb(dev)) {
+
+ info = &bus_info[dev->bus->number];
+ if (info->translation_disabled) {
calgary_init_one_nontraslated(dev);
continue;
}
- tce_space = bus_info[dev->bus->number].tce_space;
- if (!tce_space && !translate_empty_slots)
+
+ if (!info->tce_space && !translate_empty_slots)
continue;
ret = calgary_init_one(dev);
@@ -1227,11 +1231,13 @@ error:
break;
if (!is_cal_pci_dev(dev->device))
continue;
- if (!translate_phb(dev)) {
+
+ info = &bus_info[dev->bus->number];
+ if (info->translation_disabled) {
pci_dev_put(dev);
continue;
}
- if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots)
+ if (!info->tce_space && !translate_empty_slots)
continue;
calgary_disable_translation(dev);
@@ -1544,7 +1550,7 @@ static void __init calgary_fixup_one_tce_space(struct pci_dev *dev)
static int __init calgary_fixup_tce_spaces(void)
{
struct pci_dev *dev = NULL;
- void *tce_space;
+ struct calgary_bus_info *info;
if (no_iommu || swiotlb || !calgary_detected)
return -ENODEV;
@@ -1557,11 +1563,12 @@ static int __init calgary_fixup_tce_spaces(void)
break;
if (!is_cal_pci_dev(dev->device))
continue;
- if (!translate_phb(dev))
+
+ info = &bus_info[dev->bus->number];
+ if (info->translation_disabled)
continue;
- tce_space = bus_info[dev->bus->number].tce_space;
- if (!tce_space)
+ if (!info->tce_space)
continue;
calgary_fixup_one_tce_space(dev);
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 0aae2f3847a..51330321a5d 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -12,7 +12,6 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/module.h>
-#include <linux/pci.h>
#include <asm/io.h>
struct dma_coherent_mem {
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c
index 9576a2eb375..b2b42bdb0a1 100644
--- a/arch/x86/kernel/pci-dma_64.c
+++ b/arch/x86/kernel/pci-dma_64.c
@@ -51,11 +51,9 @@ dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order)
{
struct page *page;
int node;
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- node = pcibus_to_node(to_pci_dev(dev)->bus);
- else
-#endif
+
+ node = dev_to_node(dev);
+ if (node == -1)
node = numa_node_id();
if (node < first_node(node_online_map))
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 4918c575d58..5cdfab65e93 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -8,6 +8,7 @@
* See Documentation/DMA-mapping.txt for the interface specification.
*
* Copyright 2002 Andi Kleen, SuSE Labs.
+ * Subject to the GNU General Public License v2 only.
*/
#include <linux/types.h>
@@ -23,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/kdebug.h>
+#include <linux/scatterlist.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
@@ -278,10 +280,10 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
*/
static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
{
+ struct scatterlist *s;
int i;
- for (i = 0; i < nents; i++) {
- struct scatterlist *s = &sg[i];
+ for_each_sg(sg, s, nents, i) {
if (!s->dma_length || !s->length)
break;
gart_unmap_single(dev, s->dma_address, s->dma_length, dir);
@@ -292,14 +294,14 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
int nents, int dir)
{
+ struct scatterlist *s;
int i;
#ifdef CONFIG_IOMMU_DEBUG
printk(KERN_DEBUG "dma_map_sg overflow\n");
#endif
- for (i = 0; i < nents; i++ ) {
- struct scatterlist *s = &sg[i];
+ for_each_sg(sg, s, nents, i) {
unsigned long addr = page_to_phys(s->page) + s->offset;
if (nonforced_iommu(dev, addr, s->length)) {
addr = dma_map_area(dev, addr, s->length, dir);
@@ -319,23 +321,23 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
}
/* Map multiple scatterlist entries continuous into the first. */
-static int __dma_map_cont(struct scatterlist *sg, int start, int stopat,
+static int __dma_map_cont(struct scatterlist *start, int nelems,
struct scatterlist *sout, unsigned long pages)
{
unsigned long iommu_start = alloc_iommu(pages);
unsigned long iommu_page = iommu_start;
+ struct scatterlist *s;
int i;
if (iommu_start == -1)
return -1;
-
- for (i = start; i < stopat; i++) {
- struct scatterlist *s = &sg[i];
+
+ for_each_sg(start, s, nelems, i) {
unsigned long pages, addr;
unsigned long phys_addr = s->dma_address;
- BUG_ON(i > start && s->offset);
- if (i == start) {
+ BUG_ON(s != start && s->offset);
+ if (s == start) {
*sout = *s;
sout->dma_address = iommu_bus_base;
sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
@@ -357,30 +359,32 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat,
return 0;
}
-static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat,
+static inline int dma_map_cont(struct scatterlist *start, int nelems,
struct scatterlist *sout,
unsigned long pages, int need)
{
- if (!need) {
- BUG_ON(stopat - start != 1);
- *sout = sg[start];
- sout->dma_length = sg[start].length;
+ if (!need) {
+ BUG_ON(nelems != 1);
+ *sout = *start;
+ sout->dma_length = start->length;
return 0;
- }
- return __dma_map_cont(sg, start, stopat, sout, pages);
+ }
+ return __dma_map_cont(start, nelems, sout, pages);
}
/*
* DMA map all entries in a scatterlist.
* Merge chunks that have page aligned sizes into a continuous mapping.
*/
-int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
+static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ int dir)
{
int i;
int out;
int start;
unsigned long pages = 0;
int need = 0, nextneed;
+ struct scatterlist *s, *ps, *start_sg, *sgmap;
if (nents == 0)
return 0;
@@ -390,8 +394,9 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
out = 0;
start = 0;
- for (i = 0; i < nents; i++) {
- struct scatterlist *s = &sg[i];
+ 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;
s->dma_address = addr;
BUG_ON(s->length == 0);
@@ -400,29 +405,33 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
/* Handle the previous not yet processed entries */
if (i > start) {
- struct scatterlist *ps = &sg[i-1];
/* Can only merge when the last chunk ends on a page
boundary and the new one doesn't have an offset. */
if (!iommu_merge || !nextneed || !need || s->offset ||
- (ps->offset + ps->length) % PAGE_SIZE) {
- if (dma_map_cont(sg, start, i, sg+out, pages,
- need) < 0)
+ (ps->offset + ps->length) % PAGE_SIZE) {
+ if (dma_map_cont(start_sg, i - start, sgmap,
+ pages, need) < 0)
goto error;
out++;
+ sgmap = sg_next(sgmap);
pages = 0;
- start = i;
+ start = i;
+ start_sg = s;
}
}
need = nextneed;
pages += to_pages(s->offset, s->length);
+ ps = s;
}
- if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0)
+ if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0)
goto error;
out++;
flush_gart();
- if (out < nents)
- sg[out].dma_length = 0;
+ if (out < nents) {
+ sgmap = sg_next(sgmap);
+ sgmap->dma_length = 0;
+ }
return out;
error:
@@ -437,8 +446,8 @@ error:
if (panic_on_overflow)
panic("dma_map_sg: overflow on %lu pages\n", pages);
iommu_full(dev, pages << PAGE_SHIFT, dir);
- for (i = 0; i < nents; i++)
- sg[i].dma_address = bad_dma_address;
+ for_each_sg(sg, s, nents, i)
+ s->dma_address = bad_dma_address;
return 0;
}
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index 2a34c6c025a..e85d4360360 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -5,6 +5,7 @@
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
#include <asm/iommu.h>
#include <asm/processor.h>
@@ -57,10 +58,10 @@ static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
int nents, int direction)
{
+ struct scatterlist *s;
int i;
- for (i = 0; i < nents; i++ ) {
- struct scatterlist *s = &sg[i];
+ for_each_sg(sg, s, nents, i) {
BUG_ON(!s->page);
s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 7352d4b377e..6309b275cb9 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -581,7 +581,7 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
*
* Kprobes not supported here. Set the probe on schedule instead.
*/
-__kprobes struct task_struct *
+struct task_struct *
__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
struct thread_struct *prev = &prev_p->thread,
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 0cecd7513c9..99102ec5fad 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -165,7 +165,7 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_
seg &= ~7UL;
- down(&child->mm->context.sem);
+ mutex_lock(&child->mm->context.lock);
if (unlikely((seg >> 3) >= child->mm->context.size))
addr = -1L; /* bogus selector, access would fault */
else {
@@ -179,7 +179,7 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_
addr &= 0xffff;
addr += base;
}
- up(&child->mm->context.sem);
+ mutex_unlock(&child->mm->context.lock);
}
return addr;
}
@@ -524,11 +524,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- case PTRACE_DETACH:
- /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
if (!access_ok(VERIFY_WRITE, datap, FRAME_SIZE*sizeof(long))) {
ret = -EIO;
diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c
index c0cac42df3b..607085f3f08 100644
--- a/arch/x86/kernel/ptrace_64.c
+++ b/arch/x86/kernel/ptrace_64.c
@@ -103,7 +103,7 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r
seg &= ~7UL;
- down(&child->mm->context.sem);
+ mutex_lock(&child->mm->context.lock);
if (unlikely((seg >> 3) >= child->mm->context.size))
addr = -1L; /* bogus selector, access would fault */
else {
@@ -117,7 +117,7 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r
addr &= 0xffff;
addr += base;
}
- up(&child->mm->context.sem);
+ mutex_unlock(&child->mm->context.lock);
}
return addr;
@@ -500,11 +500,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = 0;
break;
- case PTRACE_DETACH:
- /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
sizeof(struct user_regs_struct))) {
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
index 1200aaac403..ba918823505 100644
--- a/arch/x86/kernel/setup64.c
+++ b/arch/x86/kernel/setup64.c
@@ -11,7 +11,6 @@
#include <linux/bootmem.h>
#include <linux/bitops.h>
#include <linux/module.h>
-#include <asm/bootsetup.h>
#include <asm/pda.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -23,8 +22,9 @@
#include <asm/percpu.h>
#include <asm/proto.h>
#include <asm/sections.h>
+#include <asm/setup.h>
-char x86_boot_params[BOOT_PARAM_SIZE] __initdata;
+struct boot_params __initdata boot_params;
cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index c8e1bc38d42..b87a6fd5ba4 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -137,10 +137,11 @@ EXPORT_SYMBOL(edd);
*/
static inline void copy_edd(void)
{
- memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
- memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
- edd.mbr_signature_nr = EDD_MBR_SIG_NR;
- edd.edd_info_nr = EDD_NR;
+ memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer,
+ sizeof(edd.mbr_signature));
+ memcpy(edd.edd_info, boot_params.eddbuf, sizeof(edd.edd_info));
+ edd.mbr_signature_nr = boot_params.edd_mbr_sig_buf_entries;
+ edd.edd_info_nr = boot_params.eddbuf_entries;
}
#else
static inline void copy_edd(void)
@@ -434,17 +435,20 @@ void __init setup_bootmem_allocator(void)
#endif
numa_kva_reserve();
#ifdef CONFIG_BLK_DEV_INITRD
- if (LOADER_TYPE && INITRD_START) {
- if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
- reserve_bootmem(INITRD_START, INITRD_SIZE);
- initrd_start = INITRD_START + PAGE_OFFSET;
- initrd_end = initrd_start+INITRD_SIZE;
- }
- else {
+ if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+ unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
+ unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
+ unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
+ unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT;
+
+ if (ramdisk_end <= end_of_lowmem) {
+ reserve_bootmem(ramdisk_image, ramdisk_size);
+ initrd_start = ramdisk_image + PAGE_OFFSET;
+ initrd_end = initrd_start+ramdisk_size;
+ } else {
printk(KERN_ERR "initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- INITRD_START + INITRD_SIZE,
- max_low_pfn << PAGE_SHIFT);
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ ramdisk_end, end_of_lowmem);
initrd_start = 0;
}
}
@@ -512,28 +516,29 @@ void __init setup_arch(char **cmdline_p)
* the system table is valid. If not, then initialize normally.
*/
#ifdef CONFIG_EFI
- if ((LOADER_TYPE == 0x50) && EFI_SYSTAB)
+ if ((boot_params.hdr.type_of_loader == 0x50) &&
+ boot_params.efi_info.efi_systab)
efi_enabled = 1;
#endif
- ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
- screen_info = SCREEN_INFO;
- edid_info = EDID_INFO;
- apm_info.bios = APM_BIOS_INFO;
- ist_info = IST_INFO;
- saved_videomode = VIDEO_MODE;
- if( SYS_DESC_TABLE.length != 0 ) {
- set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2);
- machine_id = SYS_DESC_TABLE.table[0];
- machine_submodel_id = SYS_DESC_TABLE.table[1];
- BIOS_revision = SYS_DESC_TABLE.table[2];
+ ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
+ screen_info = boot_params.screen_info;
+ edid_info = boot_params.edid_info;
+ apm_info.bios = boot_params.apm_bios_info;
+ ist_info = boot_params.ist_info;
+ saved_videomode = boot_params.hdr.vid_mode;
+ if( boot_params.sys_desc_table.length != 0 ) {
+ set_mca_bus(boot_params.sys_desc_table.table[3] & 0x2);
+ machine_id = boot_params.sys_desc_table.table[0];
+ machine_submodel_id = boot_params.sys_desc_table.table[1];
+ BIOS_revision = boot_params.sys_desc_table.table[2];
}
- bootloader_type = LOADER_TYPE;
+ bootloader_type = boot_params.hdr.type_of_loader;
#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+ rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0);
+ rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
#endif
ARCH_SETUP
if (efi_enabled)
@@ -545,7 +550,7 @@ void __init setup_arch(char **cmdline_p)
copy_edd();
- if (!MOUNT_ROOT_RDONLY)
+ if (!boot_params.hdr.root_flags)
root_mountflags &= ~MS_RDONLY;
init_mm.start_code = (unsigned long) _text;
init_mm.end_code = (unsigned long) _etext;
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index b7da90e79c7..5a19f0cc5b6 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -52,7 +52,6 @@
#include <asm/dma.h>
#include <asm/mpspec.h>
#include <asm/mmu_context.h>
-#include <asm/bootsetup.h>
#include <asm/proto.h>
#include <asm/setup.h>
#include <asm/mach_apic.h>
@@ -180,10 +179,11 @@ EXPORT_SYMBOL(edd);
*/
static inline void copy_edd(void)
{
- memcpy(edd.mbr_signature, EDD_MBR_SIGNATURE, sizeof(edd.mbr_signature));
- memcpy(edd.edd_info, EDD_BUF, sizeof(edd.edd_info));
- edd.mbr_signature_nr = EDD_MBR_SIG_NR;
- edd.edd_info_nr = EDD_NR;
+ memcpy(edd.mbr_signature, boot_params.edd_mbr_sig_buffer,
+ sizeof(edd.mbr_signature));
+ memcpy(edd.edd_info, boot_params.eddbuf, sizeof(edd.edd_info));
+ edd.mbr_signature_nr = boot_params.edd_mbr_sig_buf_entries;
+ edd.edd_info_nr = boot_params.eddbuf_entries;
}
#else
static inline void copy_edd(void)
@@ -220,21 +220,21 @@ void __init setup_arch(char **cmdline_p)
{
printk(KERN_INFO "Command line: %s\n", boot_command_line);
- ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
- screen_info = SCREEN_INFO;
- edid_info = EDID_INFO;
- saved_video_mode = SAVED_VIDEO_MODE;
- bootloader_type = LOADER_TYPE;
+ ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
+ screen_info = boot_params.screen_info;
+ edid_info = boot_params.edid_info;
+ saved_video_mode = boot_params.hdr.vid_mode;
+ bootloader_type = boot_params.hdr.type_of_loader;
#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+ rd_image_start = boot_params.hdr.ram_size & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0);
+ rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0);
#endif
setup_memory_region();
copy_edd();
- if (!MOUNT_ROOT_RDONLY)
+ if (!boot_params.hdr.root_flags)
root_mountflags &= ~MS_RDONLY;
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
@@ -339,17 +339,20 @@ void __init setup_arch(char **cmdline_p)
*/
find_smp_config();
#ifdef CONFIG_BLK_DEV_INITRD
- if (LOADER_TYPE && INITRD_START) {
- if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
- reserve_bootmem_generic(INITRD_START, INITRD_SIZE);
- initrd_start = INITRD_START + PAGE_OFFSET;
- initrd_end = initrd_start+INITRD_SIZE;
- }
- else {
+ if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
+ unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
+ unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
+ unsigned long ramdisk_end = ramdisk_image + ramdisk_size;
+ unsigned long end_of_mem = end_pfn << PAGE_SHIFT;
+
+ if (ramdisk_end <= end_of_mem) {
+ reserve_bootmem_generic(ramdisk_image, ramdisk_size);
+ initrd_start = ramdisk_image + PAGE_OFFSET;
+ initrd_end = initrd_start+ramdisk_size;
+ } else {
printk(KERN_ERR "initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- (unsigned long)(INITRD_START + INITRD_SIZE),
- (unsigned long)(end_pfn << PAGE_SHIFT));
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ ramdisk_end, end_of_mem);
initrd_start = 0;
}
}
@@ -601,7 +604,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
level = cpuid_eax(1);
if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
- if (c->x86 == 0x10)
+ if (c->x86 == 0x10 || c->x86 == 0x11)
set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
/* Enable workaround for FXSAVE leak */
@@ -965,7 +968,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
* applications want to get the raw CPUID data, they should access
* /dev/cpu/<cpu_nr>/cpuid instead.
*/
- static char *x86_cap_flags[] = {
+ static const char *const x86_cap_flags[] = {
/* Intel-defined */
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
@@ -1019,7 +1022,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
- static char *x86_power_flags[] = {
+ static const char *const x86_power_flags[] = {
"ts", /* temperature sensor */
"fid", /* frequency id control */
"vid", /* voltage id control */
@@ -1070,7 +1073,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
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(cpu_core_map[cpu]));
+ seq_printf(m, "siblings\t: %d\n",
+ cpus_weight(per_cpu(cpu_core_map, cpu)));
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
}
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index d01d51fcce2..0d79df3c563 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -385,7 +385,6 @@ static int setup_frame(int sig, struct k_sigaction *ka,
regs->edx = (unsigned long) 0;
regs->ecx = (unsigned long) 0;
- set_fs(USER_DS);
regs->xds = __USER_DS;
regs->xes = __USER_DS;
regs->xss = __USER_DS;
@@ -479,7 +478,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->edx = (unsigned long) &frame->info;
regs->ecx = (unsigned long) &frame->uc;
- set_fs(USER_DS);
regs->xds = __USER_DS;
regs->xes = __USER_DS;
regs->xss = __USER_DS;
diff --git a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
index 2d35d850202..791d9f8036a 100644
--- a/arch/x86/kernel/smp_32.c
+++ b/arch/x86/kernel/smp_32.c
@@ -342,6 +342,7 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs)
smp_mb__after_clear_bit();
out:
put_cpu_no_resched();
+ __get_cpu_var(irq_stat).irq_tlb_count++;
}
void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
@@ -640,6 +641,7 @@ static void native_smp_send_stop(void)
fastcall void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
+ __get_cpu_var(irq_stat).irq_resched_count++;
}
fastcall void smp_call_function_interrupt(struct pt_regs *regs)
@@ -660,6 +662,7 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs)
*/
irq_enter();
(*func)(info);
+ __get_cpu_var(irq_stat).irq_call_count++;
irq_exit();
if (wait) {
@@ -705,3 +708,10 @@ struct smp_ops smp_ops = {
.smp_send_reschedule = native_smp_send_reschedule,
.smp_call_function_mask = native_smp_call_function_mask,
};
+
+int smp_call_function_mask(cpumask_t mask, void (*func) (void *info),
+ void *info, int wait)
+{
+ return smp_ops.smp_call_function_mask(mask, func, info, wait);
+}
+EXPORT_SYMBOL(smp_call_function_mask);
diff --git a/arch/x86/kernel/smp_64.c b/arch/x86/kernel/smp_64.c
index df4a82812ad..5c2964727d1 100644
--- a/arch/x86/kernel/smp_64.c
+++ b/arch/x86/kernel/smp_64.c
@@ -163,6 +163,7 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
out:
ack_APIC_irq();
cpu_clear(cpu, f->flush_cpumask);
+ add_pda(irq_tlb_count, 1);
}
static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
@@ -493,6 +494,7 @@ void smp_send_stop(void)
asmlinkage void smp_reschedule_interrupt(void)
{
ack_APIC_irq();
+ add_pda(irq_resched_count, 1);
}
asmlinkage void smp_call_function_interrupt(void)
@@ -514,6 +516,7 @@ asmlinkage void smp_call_function_interrupt(void)
exit_idle();
irq_enter();
(*func)(info);
+ add_pda(irq_call_count, 1);
irq_exit();
if (wait) {
mb();
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
index e4f61d1c624..be3faac0471 100644
--- a/arch/x86/kernel/smpboot_32.c
+++ b/arch/x86/kernel/smpboot_32.c
@@ -70,12 +70,12 @@ EXPORT_SYMBOL(smp_num_siblings);
int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
/* representing HT siblings of each logical CPU */
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
-cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_core_map);
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+EXPORT_PER_CPU_SYMBOL(cpu_core_map);
/* bitmap of online cpus */
cpumask_t cpu_online_map __read_mostly;
@@ -102,8 +102,8 @@ u8 apicid_2_node[MAX_APICID];
* Trampoline 80x86 program as an array.
*/
-extern unsigned char trampoline_data [];
-extern unsigned char trampoline_end [];
+extern const unsigned char trampoline_data [];
+extern const unsigned char trampoline_end [];
static unsigned char *trampoline_base;
static int trampoline_exec;
@@ -118,7 +118,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
* has made sure it's suitably aligned.
*/
-static unsigned long __devinit setup_trampoline(void)
+static unsigned long __cpuinit setup_trampoline(void)
{
memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
return virt_to_phys(trampoline_base);
@@ -300,7 +300,7 @@ cpumask_t cpu_coregroup_map(int cpu)
* And for power savings, we return cpu_core_map
*/
if (sched_mc_power_savings || sched_smt_power_savings)
- return cpu_core_map[cpu];
+ return per_cpu(cpu_core_map, cpu);
else
return c->llc_shared_map;
}
@@ -319,22 +319,22 @@ void __cpuinit set_cpu_sibling_map(int cpu)
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) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ 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);
}
}
} else {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
- cpu_core_map[cpu] = cpu_sibling_map[cpu];
+ per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
c[cpu].booted_cores = 1;
return;
}
@@ -346,17 +346,17 @@ void __cpuinit set_cpu_sibling_map(int cpu)
cpu_set(cpu, c[i].llc_shared_map);
}
if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ cpu_set(i, per_cpu(cpu_core_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
* Does this new cpu bringup a new core?
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
/*
* for each core in package, increment
* the booted_cores for this new cpu
*/
- if (first_cpu(cpu_sibling_map[i]) == i)
+ if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
c[cpu].booted_cores++;
/*
* increment the core count for all
@@ -983,8 +983,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
map_cpu_to_logical_apicid();
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1008,8 +1008,8 @@ 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);
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1021,10 +1021,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
if (!max_cpus) {
smp_found_config = 0;
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
+
+ if (nmi_watchdog == NMI_LOCAL_APIC) {
+ printk(KERN_INFO "activating minimal APIC for NMI watchdog use.\n");
+ connect_bsp_APIC();
+ setup_local_APIC();
+ }
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, per_cpu(cpu_core_map, 0));
return;
}
@@ -1102,16 +1108,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
Dprintk("Boot done.\n");
/*
- * construct cpu_sibling_map[], so that we can tell sibling CPUs
+ * construct cpu_sibling_map, so that we can tell sibling CPUs
* efficiently.
*/
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
+ cpus_clear(per_cpu(cpu_core_map, cpu));
}
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, per_cpu(cpu_core_map, 0));
smpboot_setup_io_apic();
@@ -1148,19 +1154,19 @@ void remove_siblinginfo(int cpu)
int sibling;
struct cpuinfo_x86 *c = cpu_data;
- for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
- cpu_clear(cpu, cpu_core_map[sibling]);
- /*
+ for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
+ cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
+ /*/
* last thread sibling in this cpu core going down
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
c[sibling].booted_cores--;
}
- for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[sibling]);
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ 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;
cpu_clear(cpu, cpu_sibling_setup_map);
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index 720a7d1f886..e351ac4ab5b 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -91,19 +91,19 @@ EXPORT_SYMBOL(cpu_data);
int smp_threads_ready;
/* representing HT siblings of each logical CPU */
-cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
-cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
-EXPORT_SYMBOL(cpu_core_map);
+DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+EXPORT_PER_CPU_SYMBOL(cpu_core_map);
/*
* Trampoline 80x86 program as an array.
*/
-extern unsigned char trampoline_data[];
-extern unsigned char trampoline_end[];
+extern const unsigned char trampoline_data[];
+extern const unsigned char trampoline_end[];
/* State of each CPU */
DEFINE_PER_CPU(int, cpu_state) = { 0 };
@@ -243,7 +243,7 @@ cpumask_t cpu_coregroup_map(int cpu)
* And for power savings, we return cpu_core_map
*/
if (sched_mc_power_savings || sched_smt_power_savings)
- return cpu_core_map[cpu];
+ return per_cpu(cpu_core_map, cpu);
else
return c->llc_shared_map;
}
@@ -262,22 +262,22 @@ static inline void set_cpu_sibling_map(int cpu)
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) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ 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);
}
}
} else {
- cpu_set(cpu, cpu_sibling_map[cpu]);
+ cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
- cpu_core_map[cpu] = cpu_sibling_map[cpu];
+ per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
c[cpu].booted_cores = 1;
return;
}
@@ -289,17 +289,17 @@ static inline void set_cpu_sibling_map(int cpu)
cpu_set(cpu, c[i].llc_shared_map);
}
if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
+ cpu_set(i, per_cpu(cpu_core_map, cpu));
+ cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
* Does this new cpu bringup a new core?
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
/*
* for each core in package, increment
* the booted_cores for this new cpu
*/
- if (first_cpu(cpu_sibling_map[i]) == i)
+ if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
c[cpu].booted_cores++;
/*
* increment the core count for all
@@ -695,7 +695,6 @@ do_rest:
cpu_clear(cpu, cpu_present_map);
cpu_clear(cpu, cpu_possible_map);
x86_cpu_to_apicid[cpu] = BAD_APICID;
- x86_cpu_to_log_apicid[cpu] = BAD_APICID;
return -EIO;
}
@@ -735,8 +734,8 @@ static __init void disable_smp(void)
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
else
phys_cpu_present_map = physid_mask_of_physid(0);
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ cpu_set(0, per_cpu(cpu_sibling_map, 0));
+ cpu_set(0, per_cpu(cpu_core_map, 0));
}
#ifdef CONFIG_HOTPLUG_CPU
@@ -971,19 +970,19 @@ static void remove_siblinginfo(int cpu)
int sibling;
struct cpuinfo_x86 *c = cpu_data;
- for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
- cpu_clear(cpu, cpu_core_map[sibling]);
+ for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
+ cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
/*
* last thread sibling in this cpu core going down
*/
- if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+ if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
c[sibling].booted_cores--;
}
- for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[sibling]);
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ 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;
cpu_clear(cpu, cpu_sibling_setup_map);
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index 413e527cdeb..6fa6cf036c7 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -33,7 +33,7 @@ static void save_stack_address(void *data, unsigned long addr)
trace->entries[trace->nr_entries++] = addr;
}
-static struct stacktrace_ops save_stack_ops = {
+static const struct stacktrace_ops save_stack_ops = {
.warning = save_stack_warning,
.warning_symbol = save_stack_warning_symbol,
.stack = save_stack_stack,
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index 573c0a6e0ac..f8fafe527ff 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -150,8 +150,22 @@ void fix_processor_context(void)
/* Defined in arch/x86_64/kernel/suspend_asm.S */
extern int restore_image(void);
+/*
+ * Address to jump to in the last phase of restore in order to get to the image
+ * kernel's text (this value is passed in the image header).
+ */
+unsigned long restore_jump_address;
+
+/*
+ * Value of the cr3 register from before the hibernation (this value is passed
+ * in the image header).
+ */
+unsigned long restore_cr3;
+
pgd_t *temp_level4_pgt;
+void *relocated_restore_code;
+
static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
{
long i, j;
@@ -175,7 +189,7 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en
if (paddr >= end)
break;
- pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr;
+ pe = __PAGE_KERNEL_LARGE_EXEC | paddr;
pe &= __supported_pte_mask;
set_pmd(pmd, __pmd(pe));
}
@@ -183,25 +197,42 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en
return 0;
}
+static int res_kernel_text_pud_init(pud_t *pud, unsigned long start)
+{
+ pmd_t *pmd;
+ unsigned long paddr;
+
+ pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
+ if (!pmd)
+ return -ENOMEM;
+ set_pud(pud + pud_index(start), __pud(__pa(pmd) | _KERNPG_TABLE));
+ for (paddr = 0; paddr < KERNEL_TEXT_SIZE; pmd++, paddr += PMD_SIZE) {
+ unsigned long pe;
+
+ pe = __PAGE_KERNEL_LARGE_EXEC | _PAGE_GLOBAL | paddr;
+ pe &= __supported_pte_mask;
+ set_pmd(pmd, __pmd(pe));
+ }
+
+ return 0;
+}
+
static int set_up_temporary_mappings(void)
{
unsigned long start, end, next;
+ pud_t *pud;
int error;
temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
if (!temp_level4_pgt)
return -ENOMEM;
- /* It is safe to reuse the original kernel mapping */
- set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
- init_level4_pgt[pgd_index(__START_KERNEL_map)]);
-
/* Set up the direct mapping from scratch */
start = (unsigned long)pfn_to_kaddr(0);
end = (unsigned long)pfn_to_kaddr(end_pfn);
for (; start < end; start = next) {
- pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+ pud = (pud_t *)get_safe_page(GFP_ATOMIC);
if (!pud)
return -ENOMEM;
next = start + PGDIR_SIZE;
@@ -212,7 +243,17 @@ static int set_up_temporary_mappings(void)
set_pgd(temp_level4_pgt + pgd_index(start),
mk_kernel_pgd(__pa(pud)));
}
- return 0;
+
+ /* Set up the kernel text mapping from scratch */
+ pud = (pud_t *)get_safe_page(GFP_ATOMIC);
+ if (!pud)
+ return -ENOMEM;
+ error = res_kernel_text_pud_init(pud, __START_KERNEL_map);
+ if (!error)
+ set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
+ __pgd(__pa(pud) | _PAGE_TABLE));
+
+ return error;
}
int swsusp_arch_resume(void)
@@ -222,6 +263,13 @@ int swsusp_arch_resume(void)
/* We have got enough memory and from now on we cannot recover */
if ((error = set_up_temporary_mappings()))
return error;
+
+ relocated_restore_code = (void *)get_safe_page(GFP_ATOMIC);
+ if (!relocated_restore_code)
+ return -ENOMEM;
+ memcpy(relocated_restore_code, &core_restore_code,
+ &restore_registers - &core_restore_code);
+
restore_image();
return 0;
}
@@ -236,4 +284,43 @@ int pfn_is_nosave(unsigned long pfn)
unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT;
return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
}
+
+struct restore_data_record {
+ unsigned long jump_address;
+ unsigned long cr3;
+ unsigned long magic;
+};
+
+#define RESTORE_MAGIC 0x0123456789ABCDEFUL
+
+/**
+ * arch_hibernation_header_save - populate the architecture specific part
+ * of a hibernation image header
+ * @addr: address to save the data at
+ */
+int arch_hibernation_header_save(void *addr, unsigned int max_size)
+{
+ struct restore_data_record *rdr = addr;
+
+ if (max_size < sizeof(struct restore_data_record))
+ return -EOVERFLOW;
+ rdr->jump_address = restore_jump_address;
+ rdr->cr3 = restore_cr3;
+ rdr->magic = RESTORE_MAGIC;
+ return 0;
+}
+
+/**
+ * arch_hibernation_header_restore - read the architecture specific data
+ * from the hibernation image header
+ * @addr: address to read the data from
+ */
+int arch_hibernation_header_restore(void *addr)
+{
+ struct restore_data_record *rdr = addr;
+
+ restore_jump_address = rdr->jump_address;
+ restore_cr3 = rdr->cr3;
+ return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL;
+}
#endif /* CONFIG_HIBERNATION */
diff --git a/arch/x86/kernel/suspend_asm_64.S b/arch/x86/kernel/suspend_asm_64.S
index 16d183f67bc..48344b666d2 100644
--- a/arch/x86/kernel/suspend_asm_64.S
+++ b/arch/x86/kernel/suspend_asm_64.S
@@ -2,8 +2,8 @@
*
* Distribute under GPLv2.
*
- * swsusp_arch_resume may not use any stack, nor any variable that is
- * not "NoSave" during copying pages:
+ * swsusp_arch_resume must not use any stack or any nonlocal variables while
+ * copying pages:
*
* Its rewriting one kernel image with another. What is stack in "old"
* image could very well be data page in "new" image, and overwriting
@@ -36,6 +36,13 @@ ENTRY(swsusp_arch_suspend)
movq %r15, saved_context_r15(%rip)
pushfq ; popq saved_context_eflags(%rip)
+ /* save the address of restore_registers */
+ movq $restore_registers, %rax
+ movq %rax, restore_jump_address(%rip)
+ /* save cr3 */
+ movq %cr3, %rax
+ movq %rax, restore_cr3(%rip)
+
call swsusp_save
ret
@@ -54,7 +61,17 @@ ENTRY(restore_image)
movq %rcx, %cr3;
movq %rax, %cr4; # turn PGE back on
+ /* prepare to jump to the image kernel */
+ movq restore_jump_address(%rip), %rax
+ movq restore_cr3(%rip), %rbx
+
+ /* prepare to copy image data to their original locations */
movq restore_pblist(%rip), %rdx
+ movq relocated_restore_code(%rip), %rcx
+ jmpq *%rcx
+
+ /* code below has been relocated to a safe page */
+ENTRY(core_restore_code)
loop:
testq %rdx, %rdx
jz done
@@ -62,7 +79,7 @@ loop:
/* get addresses from the pbe and copy the page */
movq pbe_address(%rdx), %rsi
movq pbe_orig_address(%rdx), %rdi
- movq $512, %rcx
+ movq $(PAGE_SIZE >> 3), %rcx
rep
movsq
@@ -70,10 +87,22 @@ loop:
movq pbe_next(%rdx), %rdx
jmp loop
done:
+ /* jump to the restore_registers address from the image header */
+ jmpq *%rax
+ /*
+ * NOTE: This assumes that the boot kernel's text mapping covers the
+ * image kernel's page containing restore_registers and the address of
+ * this page is the same as in the image kernel's text mapping (it
+ * should always be true, because the text mapping is linear, starting
+ * from 0, and is supposed to cover the entire kernel text for every
+ * kernel).
+ *
+ * code below belongs to the image kernel
+ */
+
+ENTRY(restore_registers)
/* go back to the original page tables */
- movq $(init_level4_pgt - __START_KERNEL_map), %rax
- addq phys_base(%rip), %rax
- movq %rax, %cr3
+ movq %rbx, %cr3
/* Flush TLB, including "global" things (vmalloc) */
movq mmu_cr4_features(%rip), %rax
@@ -84,12 +113,9 @@ done:
movq %rcx, %cr3
movq %rax, %cr4; # turn PGE back on
- movl $24, %eax
- movl %eax, %ds
-
movq saved_context_esp(%rip), %rsp
movq saved_context_ebp(%rip), %rbp
- /* Don't restore %rax, it must be 0 anyway */
+ /* restore GPRs (we don't restore %rax, it must be 0 anyway) */
movq saved_context_ebx(%rip), %rbx
movq saved_context_ecx(%rip), %rcx
movq saved_context_edx(%rip), %rdx
@@ -107,4 +133,7 @@ done:
xorq %rax, %rax
+ /* tell the hibernation core that we've just restored the memory */
+ movq %rax, in_suspend(%rip)
+
ret
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
index f8bae9ba032..a86d26f036e 100644
--- a/arch/x86/kernel/sys_i386_32.c
+++ b/arch/x86/kernel/sys_i386_32.c
@@ -17,10 +17,10 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
-#include <asm/ipc.h>
/*
* sys_pipe() is the normal C calling standard for creating
diff --git a/arch/x86/kernel/tce_64.c b/arch/x86/kernel/tce_64.c
index e3f2569b2c4..9e540fee700 100644
--- a/arch/x86/kernel/tce_64.c
+++ b/arch/x86/kernel/tce_64.c
@@ -40,9 +40,9 @@ static inline void flush_tce(void* tceaddr)
{
/* a single tce can't cross a cache line */
if (cpu_has_clflush)
- asm volatile("clflush (%0)" :: "r" (tceaddr));
+ clflush(tceaddr);
else
- asm volatile("wbinvd":::"memory");
+ wbinvd();
}
void tce_build(struct iommu_table *tbl, unsigned long index,
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index c25f23eb397..8caa0b77746 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -44,15 +44,15 @@ int arch_register_cpu(int num)
* Also certain PCI quirks require not to enable hotplug control
* for all CPU's.
*/
- if (num && enable_cpu_hotplug)
+#ifdef CONFIG_HOTPLUG_CPU
+ if (num)
cpu_devices[num].cpu.hotpluggable = 1;
+#endif
return register_cpu(&cpu_devices[num].cpu, num);
}
#ifdef CONFIG_HOTPLUG_CPU
-int enable_cpu_hotplug = 1;
-
void arch_unregister_cpu(int num) {
return unregister_cpu(&cpu_devices[num].cpu);
}
diff --git a/arch/x86/kernel/trampoline_32.S b/arch/x86/kernel/trampoline_32.S
index f62815f8d06..9bcc1c6aca3 100644
--- a/arch/x86/kernel/trampoline_32.S
+++ b/arch/x86/kernel/trampoline_32.S
@@ -36,11 +36,11 @@
#include <asm/segment.h>
#include <asm/page.h>
-.data
-
/* We can free up trampoline after bootup if cpu hotplug is not supported. */
#ifndef CONFIG_HOTPLUG_CPU
.section ".init.data","aw",@progbits
+#else
+.section .rodata,"a",@progbits
#endif
.code16
diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/kernel/trampoline_64.S
index 607983b0d27..e30b67c6a9f 100644
--- a/arch/x86/kernel/trampoline_64.S
+++ b/arch/x86/kernel/trampoline_64.S
@@ -33,7 +33,12 @@
#include <asm/msr.h>
#include <asm/segment.h>
-.data
+/* We can free up trampoline after bootup if cpu hotplug is not supported. */
+#ifndef CONFIG_HOTPLUG_CPU
+.section .init.data, "aw", @progbits
+#else
+.section .rodata, "a", @progbits
+#endif
.code16
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 05c27ecaf2a..b132d3957df 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -112,7 +112,7 @@ struct stack_frame {
static inline unsigned long print_context_stack(struct thread_info *tinfo,
unsigned long *stack, unsigned long ebp,
- struct stacktrace_ops *ops, void *data)
+ const struct stacktrace_ops *ops, void *data)
{
#ifdef CONFIG_FRAME_POINTER
struct stack_frame *frame = (struct stack_frame *)ebp;
@@ -149,7 +149,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
void dump_trace(struct task_struct *task, struct pt_regs *regs,
unsigned long *stack,
- struct stacktrace_ops *ops, void *data)
+ const struct stacktrace_ops *ops, void *data)
{
unsigned long ebp = 0;
@@ -221,7 +221,7 @@ static void print_trace_address(void *data, unsigned long addr)
touch_nmi_watchdog();
}
-static struct stacktrace_ops print_trace_ops = {
+static const struct stacktrace_ops print_trace_ops = {
.warning = print_trace_warning,
.warning_symbol = print_trace_warning_symbol,
.stack = print_trace_stack,
@@ -398,31 +398,24 @@ void die(const char * str, struct pt_regs * regs, long err)
local_save_flags(flags);
if (++die.lock_owner_depth < 3) {
- int nl = 0;
unsigned long esp;
unsigned short ss;
report_bug(regs->eip, regs);
- printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+ printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
+ ++die_counter);
#ifdef CONFIG_PREEMPT
- printk(KERN_EMERG "PREEMPT ");
- nl = 1;
+ printk("PREEMPT ");
#endif
#ifdef CONFIG_SMP
- if (!nl)
- printk(KERN_EMERG);
printk("SMP ");
- nl = 1;
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
- if (!nl)
- printk(KERN_EMERG);
printk("DEBUG_PAGEALLOC");
- nl = 1;
#endif
- if (nl)
- printk("\n");
+ printk("\n");
+
if (notify_die(DIE_OOPS, str, regs, err,
current->thread.trap_no, SIGSEGV) !=
NOTIFY_STOP) {
@@ -1112,20 +1105,6 @@ asmlinkage void math_emulate(long arg)
#endif /* CONFIG_MATH_EMULATION */
-#ifdef CONFIG_X86_F00F_BUG
-void __init trap_init_f00f_bug(void)
-{
- __set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO);
-
- /*
- * Update the IDT descriptor and reload the IDT so that
- * it uses the read-only mapped virtual address.
- */
- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
- load_idt(&idt_descr);
-}
-#endif
-
/*
* This needs to use 'idt_table' rather than 'idt', and
* thus use the _nonmapped_ version of the IDT, as the
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index bc7116acf8f..b4a9b3db199 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -215,7 +215,7 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
unsigned long *stack,
- struct stacktrace_ops *ops, void *data)
+ const struct stacktrace_ops *ops, void *data)
{
const unsigned cpu = get_cpu();
unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr;
@@ -336,7 +336,7 @@ static void print_trace_address(void *data, unsigned long addr)
printk_address(addr);
}
-static struct stacktrace_ops print_trace_ops = {
+static const struct stacktrace_ops print_trace_ops = {
.warning = print_trace_warning,
.warning_symbol = print_trace_warning_symbol,
.stack = print_trace_stack,
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index b85ad754f70..e87a3939ed4 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -349,10 +349,10 @@ __cpuinit int unsynchronized_tsc(void)
static void __init check_geode_tsc_reliable(void)
{
- unsigned long val;
+ unsigned long res_low, res_high;
- rdmsrl(MSR_GEODE_BUSCONT_CONF0, val);
- if ((val & RTSC_SUSP))
+ rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high);
+ if (res_low & RTSC_SUSP)
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
}
#else
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 18673e0f193..f02bad68aba 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -134,21 +134,21 @@ static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
unsigned long eip, unsigned len)
{
switch (type) {
- case PARAVIRT_PATCH(irq_disable):
+ case PARAVIRT_PATCH(pv_irq_ops.irq_disable):
return patch_internal(VMI_CALL_DisableInterrupts, len,
insns, eip);
- case PARAVIRT_PATCH(irq_enable):
+ case PARAVIRT_PATCH(pv_irq_ops.irq_enable):
return patch_internal(VMI_CALL_EnableInterrupts, len,
insns, eip);
- case PARAVIRT_PATCH(restore_fl):
+ case PARAVIRT_PATCH(pv_irq_ops.restore_fl):
return patch_internal(VMI_CALL_SetInterruptMask, len,
insns, eip);
- case PARAVIRT_PATCH(save_fl):
+ case PARAVIRT_PATCH(pv_irq_ops.save_fl):
return patch_internal(VMI_CALL_GetInterruptMask, len,
insns, eip);
- case PARAVIRT_PATCH(iret):
+ case PARAVIRT_PATCH(pv_cpu_ops.iret):
return patch_internal(VMI_CALL_IRET, len, insns, eip);
- case PARAVIRT_PATCH(irq_enable_sysexit):
+ case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit):
return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip);
default:
break;
@@ -552,24 +552,22 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip,
}
#endif
-static void vmi_set_lazy_mode(enum paravirt_lazy_mode mode)
+static void vmi_enter_lazy_cpu(void)
{
- static DEFINE_PER_CPU(enum paravirt_lazy_mode, lazy_mode);
-
- if (!vmi_ops.set_lazy_mode)
- return;
+ paravirt_enter_lazy_cpu();
+ vmi_ops.set_lazy_mode(2);
+}
- /* Modes should never nest or overlap */
- BUG_ON(__get_cpu_var(lazy_mode) && !(mode == PARAVIRT_LAZY_NONE ||
- mode == PARAVIRT_LAZY_FLUSH));
+static void vmi_enter_lazy_mmu(void)
+{
+ paravirt_enter_lazy_mmu();
+ vmi_ops.set_lazy_mode(1);
+}
- if (mode == PARAVIRT_LAZY_FLUSH) {
- vmi_ops.set_lazy_mode(0);
- vmi_ops.set_lazy_mode(__get_cpu_var(lazy_mode));
- } else {
- vmi_ops.set_lazy_mode(mode);
- __get_cpu_var(lazy_mode) = mode;
- }
+static void vmi_leave_lazy(void)
+{
+ paravirt_leave_lazy(paravirt_get_lazy_mode());
+ vmi_ops.set_lazy_mode(0);
}
static inline int __init check_vmi_rom(struct vrom_header *rom)
@@ -690,9 +688,9 @@ do { \
reloc = call_vrom_long_func(vmi_rom, get_reloc, \
VMI_CALL_##vmicall); \
if (rel->type == VMI_RELOCATION_CALL_REL) \
- paravirt_ops.opname = (void *)rel->eip; \
+ opname = (void *)rel->eip; \
else if (rel->type == VMI_RELOCATION_NOP) \
- paravirt_ops.opname = (void *)vmi_nop; \
+ opname = (void *)vmi_nop; \
else if (rel->type != VMI_RELOCATION_NONE) \
printk(KERN_WARNING "VMI: Unknown relocation " \
"type %d for " #vmicall"\n",\
@@ -712,7 +710,7 @@ do { \
VMI_CALL_##vmicall); \
BUG_ON(rel->type == VMI_RELOCATION_JUMP_REL); \
if (rel->type == VMI_RELOCATION_CALL_REL) { \
- paravirt_ops.opname = wrapper; \
+ opname = wrapper; \
vmi_ops.cache = (void *)rel->eip; \
} \
} while (0)
@@ -732,11 +730,11 @@ static inline int __init activate_vmi(void)
}
savesegment(cs, kernel_cs);
- paravirt_ops.paravirt_enabled = 1;
- paravirt_ops.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
+ pv_info.paravirt_enabled = 1;
+ pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
+ pv_info.name = "vmi";
- paravirt_ops.patch = vmi_patch;
- paravirt_ops.name = "vmi";
+ pv_init_ops.patch = vmi_patch;
/*
* Many of these operations are ABI compatible with VMI.
@@ -754,26 +752,26 @@ static inline int __init activate_vmi(void)
*/
/* CPUID is special, so very special it gets wrapped like a present */
- para_wrap(cpuid, vmi_cpuid, cpuid, CPUID);
-
- para_fill(clts, CLTS);
- para_fill(get_debugreg, GetDR);
- para_fill(set_debugreg, SetDR);
- para_fill(read_cr0, GetCR0);
- para_fill(read_cr2, GetCR2);
- para_fill(read_cr3, GetCR3);
- para_fill(read_cr4, GetCR4);
- para_fill(write_cr0, SetCR0);
- para_fill(write_cr2, SetCR2);
- para_fill(write_cr3, SetCR3);
- para_fill(write_cr4, SetCR4);
- para_fill(save_fl, GetInterruptMask);
- para_fill(restore_fl, SetInterruptMask);
- para_fill(irq_disable, DisableInterrupts);
- para_fill(irq_enable, EnableInterrupts);
-
- para_fill(wbinvd, WBINVD);
- para_fill(read_tsc, RDTSC);
+ para_wrap(pv_cpu_ops.cpuid, vmi_cpuid, cpuid, CPUID);
+
+ para_fill(pv_cpu_ops.clts, CLTS);
+ para_fill(pv_cpu_ops.get_debugreg, GetDR);
+ para_fill(pv_cpu_ops.set_debugreg, SetDR);
+ para_fill(pv_cpu_ops.read_cr0, GetCR0);
+ para_fill(pv_mmu_ops.read_cr2, GetCR2);
+ para_fill(pv_mmu_ops.read_cr3, GetCR3);
+ para_fill(pv_cpu_ops.read_cr4, GetCR4);
+ para_fill(pv_cpu_ops.write_cr0, SetCR0);
+ para_fill(pv_mmu_ops.write_cr2, SetCR2);
+ para_fill(pv_mmu_ops.write_cr3, SetCR3);
+ para_fill(pv_cpu_ops.write_cr4, SetCR4);
+ para_fill(pv_irq_ops.save_fl, GetInterruptMask);
+ para_fill(pv_irq_ops.restore_fl, SetInterruptMask);
+ para_fill(pv_irq_ops.irq_disable, DisableInterrupts);
+ para_fill(pv_irq_ops.irq_enable, EnableInterrupts);
+
+ para_fill(pv_cpu_ops.wbinvd, WBINVD);
+ para_fill(pv_cpu_ops.read_tsc, RDTSC);
/* The following we emulate with trap and emulate for now */
/* paravirt_ops.read_msr = vmi_rdmsr */
@@ -781,29 +779,38 @@ static inline int __init activate_vmi(void)
/* paravirt_ops.rdpmc = vmi_rdpmc */
/* TR interface doesn't pass TR value, wrap */
- para_wrap(load_tr_desc, vmi_set_tr, set_tr, SetTR);
+ para_wrap(pv_cpu_ops.load_tr_desc, vmi_set_tr, set_tr, SetTR);
/* LDT is special, too */
- para_wrap(set_ldt, vmi_set_ldt, _set_ldt, SetLDT);
-
- para_fill(load_gdt, SetGDT);
- para_fill(load_idt, SetIDT);
- para_fill(store_gdt, GetGDT);
- para_fill(store_idt, GetIDT);
- para_fill(store_tr, GetTR);
- paravirt_ops.load_tls = vmi_load_tls;
- para_fill(write_ldt_entry, WriteLDTEntry);
- para_fill(write_gdt_entry, WriteGDTEntry);
- para_fill(write_idt_entry, WriteIDTEntry);
- para_wrap(load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack);
- para_fill(set_iopl_mask, SetIOPLMask);
- para_fill(io_delay, IODelay);
- para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode);
+ para_wrap(pv_cpu_ops.set_ldt, vmi_set_ldt, _set_ldt, SetLDT);
+
+ para_fill(pv_cpu_ops.load_gdt, SetGDT);
+ para_fill(pv_cpu_ops.load_idt, SetIDT);
+ para_fill(pv_cpu_ops.store_gdt, GetGDT);
+ para_fill(pv_cpu_ops.store_idt, GetIDT);
+ para_fill(pv_cpu_ops.store_tr, GetTR);
+ pv_cpu_ops.load_tls = vmi_load_tls;
+ para_fill(pv_cpu_ops.write_ldt_entry, WriteLDTEntry);
+ para_fill(pv_cpu_ops.write_gdt_entry, WriteGDTEntry);
+ para_fill(pv_cpu_ops.write_idt_entry, WriteIDTEntry);
+ para_wrap(pv_cpu_ops.load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack);
+ para_fill(pv_cpu_ops.set_iopl_mask, SetIOPLMask);
+ para_fill(pv_cpu_ops.io_delay, IODelay);
+
+ para_wrap(pv_cpu_ops.lazy_mode.enter, vmi_enter_lazy_cpu,
+ set_lazy_mode, SetLazyMode);
+ para_wrap(pv_cpu_ops.lazy_mode.leave, vmi_leave_lazy,
+ set_lazy_mode, SetLazyMode);
+
+ para_wrap(pv_mmu_ops.lazy_mode.enter, vmi_enter_lazy_mmu,
+ set_lazy_mode, SetLazyMode);
+ para_wrap(pv_mmu_ops.lazy_mode.leave, vmi_leave_lazy,
+ set_lazy_mode, SetLazyMode);
/* user and kernel flush are just handled with different flags to FlushTLB */
- para_wrap(flush_tlb_user, vmi_flush_tlb_user, _flush_tlb, FlushTLB);
- para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, _flush_tlb, FlushTLB);
- para_fill(flush_tlb_single, InvalPage);
+ para_wrap(pv_mmu_ops.flush_tlb_user, vmi_flush_tlb_user, _flush_tlb, FlushTLB);
+ para_wrap(pv_mmu_ops.flush_tlb_kernel, vmi_flush_tlb_kernel, _flush_tlb, FlushTLB);
+ para_fill(pv_mmu_ops.flush_tlb_single, InvalPage);
/*
* Until a standard flag format can be agreed on, we need to
@@ -819,41 +826,41 @@ static inline int __init activate_vmi(void)
#endif
if (vmi_ops.set_pte) {
- paravirt_ops.set_pte = vmi_set_pte;
- paravirt_ops.set_pte_at = vmi_set_pte_at;
- paravirt_ops.set_pmd = vmi_set_pmd;
+ pv_mmu_ops.set_pte = vmi_set_pte;
+ pv_mmu_ops.set_pte_at = vmi_set_pte_at;
+ pv_mmu_ops.set_pmd = vmi_set_pmd;
#ifdef CONFIG_X86_PAE
- paravirt_ops.set_pte_atomic = vmi_set_pte_atomic;
- paravirt_ops.set_pte_present = vmi_set_pte_present;
- paravirt_ops.set_pud = vmi_set_pud;
- paravirt_ops.pte_clear = vmi_pte_clear;
- paravirt_ops.pmd_clear = vmi_pmd_clear;
+ pv_mmu_ops.set_pte_atomic = vmi_set_pte_atomic;
+ pv_mmu_ops.set_pte_present = vmi_set_pte_present;
+ pv_mmu_ops.set_pud = vmi_set_pud;
+ pv_mmu_ops.pte_clear = vmi_pte_clear;
+ pv_mmu_ops.pmd_clear = vmi_pmd_clear;
#endif
}
if (vmi_ops.update_pte) {
- paravirt_ops.pte_update = vmi_update_pte;
- paravirt_ops.pte_update_defer = vmi_update_pte_defer;
+ pv_mmu_ops.pte_update = vmi_update_pte;
+ pv_mmu_ops.pte_update_defer = vmi_update_pte_defer;
}
vmi_ops.allocate_page = vmi_get_function(VMI_CALL_AllocatePage);
if (vmi_ops.allocate_page) {
- paravirt_ops.alloc_pt = vmi_allocate_pt;
- paravirt_ops.alloc_pd = vmi_allocate_pd;
- paravirt_ops.alloc_pd_clone = vmi_allocate_pd_clone;
+ pv_mmu_ops.alloc_pt = vmi_allocate_pt;
+ pv_mmu_ops.alloc_pd = vmi_allocate_pd;
+ pv_mmu_ops.alloc_pd_clone = vmi_allocate_pd_clone;
}
vmi_ops.release_page = vmi_get_function(VMI_CALL_ReleasePage);
if (vmi_ops.release_page) {
- paravirt_ops.release_pt = vmi_release_pt;
- paravirt_ops.release_pd = vmi_release_pd;
+ pv_mmu_ops.release_pt = vmi_release_pt;
+ pv_mmu_ops.release_pd = vmi_release_pd;
}
/* Set linear is needed in all cases */
vmi_ops.set_linear_mapping = vmi_get_function(VMI_CALL_SetLinearMapping);
#ifdef CONFIG_HIGHPTE
if (vmi_ops.set_linear_mapping)
- paravirt_ops.kmap_atomic_pte = vmi_kmap_atomic_pte;
+ pv_mmu_ops.kmap_atomic_pte = vmi_kmap_atomic_pte;
#endif
/*
@@ -863,17 +870,17 @@ static inline int __init activate_vmi(void)
* the backend. They are performance critical anyway, so requiring
* a patch is not a big problem.
*/
- paravirt_ops.irq_enable_sysexit = (void *)0xfeedbab0;
- paravirt_ops.iret = (void *)0xbadbab0;
+ pv_cpu_ops.irq_enable_sysexit = (void *)0xfeedbab0;
+ pv_cpu_ops.iret = (void *)0xbadbab0;
#ifdef CONFIG_SMP
- para_wrap(startup_ipi_hook, vmi_startup_ipi_hook, set_initial_ap_state, SetInitialAPState);
+ para_wrap(pv_apic_ops.startup_ipi_hook, vmi_startup_ipi_hook, set_initial_ap_state, SetInitialAPState);
#endif
#ifdef CONFIG_X86_LOCAL_APIC
- para_fill(apic_read, APICRead);
- para_fill(apic_write, APICWrite);
- para_fill(apic_write_atomic, APICWrite);
+ para_fill(pv_apic_ops.apic_read, APICRead);
+ para_fill(pv_apic_ops.apic_write, APICWrite);
+ para_fill(pv_apic_ops.apic_write_atomic, APICWrite);
#endif
/*
@@ -891,15 +898,15 @@ static inline int __init activate_vmi(void)
vmi_timer_ops.set_alarm = vmi_get_function(VMI_CALL_SetAlarm);
vmi_timer_ops.cancel_alarm =
vmi_get_function(VMI_CALL_CancelAlarm);
- paravirt_ops.time_init = vmi_time_init;
- paravirt_ops.get_wallclock = vmi_get_wallclock;
- paravirt_ops.set_wallclock = vmi_set_wallclock;
+ pv_time_ops.time_init = vmi_time_init;
+ pv_time_ops.get_wallclock = vmi_get_wallclock;
+ pv_time_ops.set_wallclock = vmi_set_wallclock;
#ifdef CONFIG_X86_LOCAL_APIC
- paravirt_ops.setup_boot_clock = vmi_time_bsp_init;
- paravirt_ops.setup_secondary_clock = vmi_time_ap_init;
+ pv_apic_ops.setup_boot_clock = vmi_time_bsp_init;
+ pv_apic_ops.setup_secondary_clock = vmi_time_ap_init;
#endif
- paravirt_ops.sched_clock = vmi_sched_clock;
- paravirt_ops.get_cpu_khz = vmi_cpu_khz;
+ pv_time_ops.sched_clock = vmi_sched_clock;
+ pv_time_ops.get_cpu_khz = vmi_cpu_khz;
/* We have true wallclock functions; disable CMOS clock sync */
no_sync_cmos_clock = 1;
@@ -908,7 +915,7 @@ static inline int __init activate_vmi(void)
disable_vmi_timer = 1;
}
- para_fill(safe_halt, Halt);
+ para_fill(pv_irq_ops.safe_halt, Halt);
/*
* Alternative instruction rewriting doesn't happen soon enough
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 93847d84815..585541ca1a7 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -64,6 +64,16 @@ struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data =
.sysctl_enabled = 1,
};
+void update_vsyscall_tz(void)
+{
+ unsigned long flags;
+
+ write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags);
+ /* sys_tz has changed */
+ vsyscall_gtod_data.sys_tz = sys_tz;
+ write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
+}
+
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
{
unsigned long flags;
@@ -77,8 +87,6 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
vsyscall_gtod_data.clock.shift = clock->shift;
vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
- vsyscall_gtod_data.sys_tz = sys_tz;
- vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
}
@@ -164,7 +172,7 @@ time_t __vsyscall(1) vtime(time_t *t)
if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
return time_syscall(t);
- vgettimeofday(&tv, 0);
+ vgettimeofday(&tv, NULL);
result = tv.tv_sec;
if (t)
*t = result;
@@ -258,18 +266,10 @@ out:
return ret;
}
-static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen,
- void __user *oldval, size_t __user *oldlenp,
- void __user *newval, size_t newlen)
-{
- return -ENOSYS;
-}
-
static ctl_table kernel_table2[] = {
- { .ctl_name = 99, .procname = "vsyscall64",
+ { .procname = "vsyscall64",
.data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
.mode = 0644,
- .strategy = vsyscall_sysctl_nostrat,
.proc_handler = vsyscall_sysctl_change },
{}
};
@@ -289,7 +289,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu)
unsigned long *d;
unsigned long node = 0;
#ifdef CONFIG_NUMA
- node = cpu_to_node[cpu];
+ node = cpu_to_node(cpu);
#endif
if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
write_rdtscp_aux((node << 12) | cpu);
diff --git a/arch/x86/lib/bitstr_64.c b/arch/x86/lib/bitstr_64.c
index 24676609a6a..7445caf1b5d 100644
--- a/arch/x86/lib/bitstr_64.c
+++ b/arch/x86/lib/bitstr_64.c
@@ -14,7 +14,7 @@ find_next_zero_string(unsigned long *bitmap, long start, long nbits, int len)
/* could test bitsliced, but it's hardly worth it */
end = n+len;
- if (end >= nbits)
+ if (end > nbits)
return -1;
for (i = n+1; i < end; i++) {
if (test_bit(i, bitmap)) {
diff --git a/arch/x86/lib/msr-on-cpu.c b/arch/x86/lib/msr-on-cpu.c
index 7767962f25d..57d043fa893 100644
--- a/arch/x86/lib/msr-on-cpu.c
+++ b/arch/x86/lib/msr-on-cpu.c
@@ -26,27 +26,18 @@ static void __rdmsr_safe_on_cpu(void *info)
static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe)
{
int err = 0;
- preempt_disable();
- if (smp_processor_id() == cpu)
- if (safe)
- err = rdmsr_safe(msr_no, l, h);
- else
- rdmsr(msr_no, *l, *h);
- else {
- struct msr_info rv;
-
- rv.msr_no = msr_no;
- if (safe) {
- smp_call_function_single(cpu, __rdmsr_safe_on_cpu,
- &rv, 0, 1);
- err = rv.err;
- } else {
- smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1);
- }
- *l = rv.l;
- *h = rv.h;
+ struct msr_info rv;
+
+ rv.msr_no = msr_no;
+ if (safe) {
+ smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 0, 1);
+ err = rv.err;
+ } else {
+ smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1);
}
- preempt_enable();
+ *l = rv.l;
+ *h = rv.h;
+
return err;
}
@@ -67,27 +58,18 @@ static void __wrmsr_safe_on_cpu(void *info)
static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe)
{
int err = 0;
- preempt_disable();
- if (smp_processor_id() == cpu)
- if (safe)
- err = wrmsr_safe(msr_no, l, h);
- else
- wrmsr(msr_no, l, h);
- else {
- struct msr_info rv;
-
- rv.msr_no = msr_no;
- rv.l = l;
- rv.h = h;
- if (safe) {
- smp_call_function_single(cpu, __wrmsr_safe_on_cpu,
- &rv, 0, 1);
- err = rv.err;
- } else {
- smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1);
- }
+ struct msr_info rv;
+
+ rv.msr_no = msr_no;
+ rv.l = l;
+ rv.h = h;
+ if (safe) {
+ smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 0, 1);
+ err = rv.err;
+ } else {
+ smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1);
}
- preempt_enable();
+
return err;
}
diff --git a/arch/x86/lib/rwlock_64.S b/arch/x86/lib/rwlock_64.S
index 0cde1f80731..05ea55f7140 100644
--- a/arch/x86/lib/rwlock_64.S
+++ b/arch/x86/lib/rwlock_64.S
@@ -2,7 +2,7 @@
#include <linux/linkage.h>
#include <asm/rwlock.h>
-#include <asm/alternative-asm.i>
+#include <asm/alternative-asm.h>
#include <asm/dwarf2.h>
/* rdi: pointer to rwlock_t */
diff --git a/arch/x86/lib/semaphore_32.S b/arch/x86/lib/semaphore_32.S
index c01eb39c0b4..444fba40098 100644
--- a/arch/x86/lib/semaphore_32.S
+++ b/arch/x86/lib/semaphore_32.S
@@ -15,8 +15,8 @@
#include <linux/linkage.h>
#include <asm/rwlock.h>
-#include <asm/alternative-asm.i>
-#include <asm/frame.i>
+#include <asm/alternative-asm.h>
+#include <asm/frame.h>
#include <asm/dwarf2.h>
/*
diff --git a/arch/x86/lib/string_32.c b/arch/x86/lib/string_32.c
index 2c773fefa3d..c2c0504a307 100644
--- a/arch/x86/lib/string_32.c
+++ b/arch/x86/lib/string_32.c
@@ -160,26 +160,6 @@ char *strchr(const char * s, int c)
EXPORT_SYMBOL(strchr);
#endif
-#ifdef __HAVE_ARCH_STRRCHR
-char *strrchr(const char * s, int c)
-{
- int d0, d1;
- char * res;
- asm volatile( "movb %%al,%%ah\n"
- "1:\tlodsb\n\t"
- "cmpb %%ah,%%al\n\t"
- "jne 2f\n\t"
- "leal -1(%%esi),%0\n"
- "2:\ttestb %%al,%%al\n\t"
- "jne 1b"
- :"=g" (res), "=&S" (d0), "=&a" (d1)
- :"0" (0),"1" (s),"2" (c)
- :"memory");
- return res;
-}
-EXPORT_SYMBOL(strrchr);
-#endif
-
#ifdef __HAVE_ARCH_STRLEN
size_t strlen(const char * s)
{
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S
index 55e586d352d..6ea73f3de56 100644
--- a/arch/x86/lib/thunk_64.S
+++ b/arch/x86/lib/thunk_64.S
@@ -50,6 +50,10 @@
thunk trace_hardirqs_on_thunk,trace_hardirqs_on
thunk trace_hardirqs_off_thunk,trace_hardirqs_off
#endif
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ thunk lockdep_sys_exit_thunk,lockdep_sys_exit
+#endif
/* SAVE_ARGS below is used only for the .cfi directives it contains. */
CFI_STARTPROC
diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c
index 7f635c7a238..3f08010f351 100644
--- a/arch/x86/mach-default/setup.c
+++ b/arch/x86/mach-default/setup.c
@@ -35,7 +35,11 @@ void __init pre_intr_init_hook(void)
/*
* IRQ2 is cascade interrupt to second interrupt controller
*/
-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
+static struct irqaction irq2 = {
+ .handler = no_action,
+ .mask = CPU_MASK_NONE,
+ .name = "cascade",
+};
/**
* intr_init_hook - post gate setup interrupt initialisation
@@ -159,16 +163,18 @@ char * __init machine_specific_memory_setup(void)
* Otherwise fake a memory map; one section from 0k->640k,
* the next section from 1mb->appropriate_mem_k
*/
- sanitize_e820_map(E820_MAP, &E820_MAP_NR);
- if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
+ sanitize_e820_map(boot_params.e820_map, &boot_params.e820_entries);
+ if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries)
+ < 0) {
unsigned long mem_size;
/* compare results from other methods and take the greater */
- if (ALT_MEM_K < EXT_MEM_K) {
- mem_size = EXT_MEM_K;
+ if (boot_params.alt_mem_k
+ < boot_params.screen_info.ext_mem_k) {
+ mem_size = boot_params.screen_info.ext_mem_k;
who = "BIOS-88";
} else {
- mem_size = ALT_MEM_K;
+ mem_size = boot_params.alt_mem_k;
who = "BIOS-e801";
}
diff --git a/arch/x86/mach-es7000/es7000plat.c b/arch/x86/mach-es7000/es7000plat.c
index ab99072d3f9..f5d6f7d8b86 100644
--- a/arch/x86/mach-es7000/es7000plat.c
+++ b/arch/x86/mach-es7000/es7000plat.c
@@ -46,11 +46,11 @@
* ES7000 Globals
*/
-volatile unsigned long *psai = NULL;
-struct mip_reg *mip_reg;
-struct mip_reg *host_reg;
-int mip_port;
-unsigned long mip_addr, host_addr;
+static volatile unsigned long *psai = NULL;
+static struct mip_reg *mip_reg;
+static struct mip_reg *host_reg;
+static int mip_port;
+static unsigned long mip_addr, host_addr;
/*
* GSI override for ES7000 platforms.
@@ -288,28 +288,8 @@ es7000_start_cpu(int cpu, unsigned long eip)
}
-int
-es7000_stop_cpu(int cpu)
-{
- int startup;
-
- if (psai == NULL)
- return -1;
-
- startup= (0x1000000 | cpu);
-
- while ((*psai & 0xff00ffff) != startup)
- ;
-
- startup = (*psai & 0xff0000) >> 16;
- *psai &= 0xffffff;
-
- return 0;
-
-}
-
void __init
-es7000_sw_apic()
+es7000_sw_apic(void)
{
if (es7000_plat) {
int mip_status;
diff --git a/arch/x86/mach-generic/probe.c b/arch/x86/mach-generic/probe.c
index 74f3da63442..4121d155180 100644
--- a/arch/x86/mach-generic/probe.c
+++ b/arch/x86/mach-generic/probe.c
@@ -22,7 +22,7 @@ extern struct genapic apic_default;
struct genapic *genapic = &apic_default;
-struct genapic *apic_probe[] __initdata = {
+static struct genapic *apic_probe[] __initdata = {
&apic_summit,
&apic_bigsmp,
&apic_es7000,
diff --git a/arch/x86/mach-visws/setup.c b/arch/x86/mach-visws/setup.c
index 1f81f10e03a..de4c9dbd086 100644
--- a/arch/x86/mach-visws/setup.c
+++ b/arch/x86/mach-visws/setup.c
@@ -152,7 +152,7 @@ char * __init machine_specific_memory_setup(void)
{
long long gfx_mem_size = 8 * MB;
- mem_size = ALT_MEM_K;
+ mem_size = boot_params.alt_mem_k;
if (!mem_size) {
printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n");
diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c
index 2b55694e640..3bef977cb29 100644
--- a/arch/x86/mach-voyager/setup.c
+++ b/arch/x86/mach-voyager/setup.c
@@ -18,7 +18,11 @@ void __init pre_intr_init_hook(void)
/*
* IRQ2 is cascade interrupt to second interrupt controller
*/
-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
+static struct irqaction irq2 = {
+ .handler = no_action,
+ .mask = CPU_MASK_NONE,
+ .name = "cascade",
+};
void __init intr_init_hook(void)
{
@@ -83,7 +87,7 @@ char * __init machine_specific_memory_setup(void)
if(inb(catbase) != VOYAGER_DINO) {
printk(KERN_ERR "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n");
- tom = (EXT_MEM_K)<<10;
+ tom = (boot_params.screen_info.ext_mem_k)<<10;
}
who = "Voyager-TOM";
add_memory_region(0, 0x9f000, E820_RAM);
@@ -104,16 +108,18 @@ char * __init machine_specific_memory_setup(void)
* Otherwise fake a memory map; one section from 0k->640k,
* the next section from 1mb->appropriate_mem_k
*/
- sanitize_e820_map(E820_MAP, &E820_MAP_NR);
- if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
+ sanitize_e820_map(boot_params.e820_map, &boot_params.e820_entries);
+ if (copy_e820_map(boot_params.e820_map, boot_params.e820_entries)
+ < 0) {
unsigned long mem_size;
/* compare results from other methods and take the greater */
- if (ALT_MEM_K < EXT_MEM_K) {
- mem_size = EXT_MEM_K;
+ if (boot_params.alt_mem_k
+ < boot_params.screen_info.ext_mem_k) {
+ mem_size = boot_params.screen_info.ext_mem_k;
who = "BIOS-88";
} else {
- mem_size = ALT_MEM_K;
+ mem_size = boot_params.alt_mem_k;
who = "BIOS-e801";
}
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index b87f8548e75..e4928aa6bdf 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -442,8 +442,8 @@ static __u32 __init
setup_trampoline(void)
{
/* these two are global symbols in trampoline.S */
- extern __u8 trampoline_end[];
- extern __u8 trampoline_data[];
+ extern const __u8 trampoline_end[];
+ extern const __u8 trampoline_data[];
memcpy((__u8 *)trampoline_base, trampoline_data,
trampoline_end - trampoline_data);
@@ -1037,6 +1037,7 @@ smp_call_function_interrupt(void)
*/
irq_enter();
(*func)(info);
+ __get_cpu_var(irq_stat).irq_call_count++;
irq_exit();
if (wait) {
mb();
diff --git a/arch/x86/math-emu/Makefile b/arch/x86/math-emu/Makefile
index 9c943fa6ce6..9b0c63b6030 100644
--- a/arch/x86/math-emu/Makefile
+++ b/arch/x86/math-emu/Makefile
@@ -5,8 +5,7 @@
#DEBUG = -DDEBUGGING
DEBUG =
PARANOID = -DPARANOID
-CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
-
+EXTRA_CFLAGS := $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
EXTRA_AFLAGS := $(PARANOID)
# From 'C' language sources:
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c
index 860e912a3fb..13893772cc4 100644
--- a/arch/x86/mm/discontig_32.c
+++ b/arch/x86/mm/discontig_32.c
@@ -103,14 +103,14 @@ extern unsigned long highend_pfn, highstart_pfn;
#define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
-unsigned long node_remap_start_pfn[MAX_NUMNODES];
+static unsigned long node_remap_start_pfn[MAX_NUMNODES];
unsigned long node_remap_size[MAX_NUMNODES];
-unsigned long node_remap_offset[MAX_NUMNODES];
-void *node_remap_start_vaddr[MAX_NUMNODES];
+static unsigned long node_remap_offset[MAX_NUMNODES];
+static void *node_remap_start_vaddr[MAX_NUMNODES];
void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
-void *node_remap_end_vaddr[MAX_NUMNODES];
-void *node_remap_alloc_vaddr[MAX_NUMNODES];
+static void *node_remap_end_vaddr[MAX_NUMNODES];
+static void *node_remap_alloc_vaddr[MAX_NUMNODES];
static unsigned long kva_start_pfn;
static unsigned long kva_pages;
/*
@@ -288,8 +288,9 @@ unsigned long __init setup_memory(void)
#ifdef CONFIG_BLK_DEV_INITRD
/* Numa kva area is below the initrd */
- if (LOADER_TYPE && INITRD_START)
- kva_start_pfn = PFN_DOWN(INITRD_START) - kva_pages;
+ if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image)
+ kva_start_pfn = PFN_DOWN(boot_params.hdr.ramdisk_image)
+ - kva_pages;
#endif
kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1);
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index fcb38e7f354..6555c3d1437 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -25,6 +25,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
+#include <linux/kprobes.h>
#include <asm/system.h>
#include <asm/desc.h>
@@ -32,33 +33,27 @@
extern void die(const char *,struct pt_regs *,long);
-static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-int register_page_fault_notifier(struct notifier_block *nb)
+#ifdef CONFIG_KPROBES
+static inline int notify_page_fault(struct pt_regs *regs)
{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_page_fault_notifier);
+ int ret = 0;
+
+ /* kprobe_running() needs smp_processor_id() */
+ if (!user_mode_vm(regs)) {
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, 14))
+ ret = 1;
+ preempt_enable();
+ }
-int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
+ return ret;
}
-EXPORT_SYMBOL_GPL(unregister_page_fault_notifier);
-
-static inline int notify_page_fault(struct pt_regs *regs, long err)
+#else
+static inline int notify_page_fault(struct pt_regs *regs)
{
- struct die_args args = {
- .regs = regs,
- .str = "page fault",
- .err = err,
- .trapnr = 14,
- .signr = SIGSEGV
- };
- return atomic_notifier_call_chain(&notify_page_fault_chain,
- DIE_PAGE_FAULT, &args);
+ return 0;
}
+#endif
/*
* Return EIP plus the CS segment base. The segment limit is also
@@ -110,7 +105,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
LDT and other horrors are only used in user space. */
if (seg & (1<<2)) {
/* Must lock the LDT while reading it. */
- down(&current->mm->context.sem);
+ mutex_lock(&current->mm->context.lock);
desc = current->mm->context.ldt;
desc = (void *)desc + (seg & ~7);
} else {
@@ -123,7 +118,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
base = get_desc_base((unsigned long *)desc);
if (seg & (1<<2)) {
- up(&current->mm->context.sem);
+ mutex_unlock(&current->mm->context.lock);
} else
put_cpu();
@@ -331,7 +326,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
if (unlikely(address >= TASK_SIZE)) {
if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0)
return;
- if (notify_page_fault(regs, error_code) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return;
/*
* Don't take the mm semaphore here. If we fixup a prefetch
@@ -340,7 +335,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
goto bad_area_nosemaphore;
}
- if (notify_page_fault(regs, error_code) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return;
/* It's safe to allow irq's after cr2 has been saved and the vmalloc
@@ -544,23 +539,22 @@ no_context:
printk(KERN_ALERT "BUG: unable to handle kernel paging"
" request");
printk(" at virtual address %08lx\n",address);
- printk(KERN_ALERT " printing eip:\n");
- printk("%08lx\n", regs->eip);
+ printk(KERN_ALERT "printing eip: %08lx ", regs->eip);
page = read_cr3();
page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
#ifdef CONFIG_X86_PAE
- printk(KERN_ALERT "*pdpt = %016Lx\n", page);
+ printk("*pdpt = %016Lx ", page);
if ((page >> PAGE_SHIFT) < max_low_pfn
&& page & _PAGE_PRESENT) {
page &= PAGE_MASK;
page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
& (PTRS_PER_PMD - 1)];
- printk(KERN_ALERT "*pde = %016Lx\n", page);
+ printk(KERN_ALERT "*pde = %016Lx ", page);
page &= ~_PAGE_NX;
}
#else
- printk(KERN_ALERT "*pde = %08lx\n", page);
+ printk("*pde = %08lx ", page);
#endif
/*
@@ -574,8 +568,10 @@ no_context:
page &= PAGE_MASK;
page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
& (PTRS_PER_PTE - 1)];
- printk(KERN_ALERT "*pte = %0*Lx\n", sizeof(page)*2, (u64)page);
+ printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
}
+
+ printk("\n");
}
tsk->thread.cr2 = address;
@@ -598,7 +594,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", tsk->comm);
if (error_code & 4)
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
goto no_context;
do_sigbus:
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 54816adb8e9..5e0e54906c4 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -25,6 +25,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
+#include <linux/kprobes.h>
#include <asm/system.h>
#include <asm/pgalloc.h>
@@ -40,34 +41,27 @@
#define PF_RSVD (1<<3)
#define PF_INSTR (1<<4)
-static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
+#ifdef CONFIG_KPROBES
+static inline int notify_page_fault(struct pt_regs *regs)
{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_page_fault_notifier);
+ int ret = 0;
+
+ /* kprobe_running() needs smp_processor_id() */
+ if (!user_mode(regs)) {
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, 14))
+ ret = 1;
+ preempt_enable();
+ }
-int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
+ return ret;
}
-EXPORT_SYMBOL_GPL(unregister_page_fault_notifier);
-
-static inline int notify_page_fault(struct pt_regs *regs, long err)
+#else
+static inline int notify_page_fault(struct pt_regs *regs)
{
- struct die_args args = {
- .regs = regs,
- .str = "page fault",
- .err = err,
- .trapnr = 14,
- .signr = SIGSEGV
- };
- return atomic_notifier_call_chain(&notify_page_fault_chain,
- DIE_PAGE_FAULT, &args);
+ return 0;
}
+#endif
/* Sometimes the CPU reports invalid exceptions on prefetch.
Check that here and ignore.
@@ -345,7 +339,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
if (vmalloc_fault(address) >= 0)
return;
}
- if (notify_page_fault(regs, error_code) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return;
/*
* Don't take the mm semaphore here. If we fixup a prefetch
@@ -354,7 +348,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
goto bad_area_nosemaphore;
}
- if (notify_page_fault(regs, error_code) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return;
if (likely(regs->eflags & X86_EFLAGS_IF))
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 730a5b177b1..c7d19471261 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -85,13 +85,20 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd)
static pte_t * __init one_page_table_init(pmd_t *pmd)
{
if (!(pmd_val(*pmd) & _PAGE_PRESENT)) {
- pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ pte_t *page_table = NULL;
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+ page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
+#endif
+ if (!page_table)
+ page_table =
+ (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
BUG_ON(page_table != pte_offset_kernel(pmd, 0));
}
-
+
return pte_offset_kernel(pmd, 0);
}
@@ -735,35 +742,18 @@ int arch_add_memory(int nid, u64 start, u64 size)
return __add_pages(zone, start_pfn, nr_pages);
}
-int remove_memory(u64 start, u64 size)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(remove_memory);
#endif
struct kmem_cache *pmd_cache;
void __init pgtable_cache_init(void)
{
- size_t pgd_size = PTRS_PER_PGD*sizeof(pgd_t);
-
- if (PTRS_PER_PMD > 1) {
+ if (PTRS_PER_PMD > 1)
pmd_cache = kmem_cache_create("pmd",
- PTRS_PER_PMD*sizeof(pmd_t),
- PTRS_PER_PMD*sizeof(pmd_t),
- SLAB_PANIC,
- pmd_ctor);
- if (!SHARED_KERNEL_PMD) {
- /* If we're in PAE mode and have a non-shared
- kernel pmd, then the pgd size must be a
- page size. This is because the pgd_list
- links through the page structure, so there
- can only be one pgd per page for this to
- work. */
- pgd_size = PAGE_SIZE;
- }
- }
+ PTRS_PER_PMD*sizeof(pmd_t),
+ PTRS_PER_PMD*sizeof(pmd_t),
+ SLAB_PANIC,
+ pmd_ctor);
}
/*
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 458893b376f..1e3862e4106 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -474,12 +474,6 @@ error:
}
EXPORT_SYMBOL_GPL(arch_add_memory);
-int remove_memory(u64 start, u64 size)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(remove_memory);
-
#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA)
int memory_add_physaddr_to_nid(u64 start)
{
@@ -748,3 +742,48 @@ const char *arch_vma_name(struct vm_area_struct *vma)
return "[vsyscall]";
return NULL;
}
+
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+/*
+ * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
+ */
+int __meminit vmemmap_populate(struct page *start_page,
+ unsigned long size, int node)
+{
+ unsigned long addr = (unsigned long)start_page;
+ unsigned long end = (unsigned long)(start_page + size);
+ unsigned long next;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ for (; addr < end; addr = next) {
+ next = pmd_addr_end(addr, end);
+
+ pgd = vmemmap_pgd_populate(addr, node);
+ if (!pgd)
+ return -ENOMEM;
+ pud = vmemmap_pud_populate(pgd, addr, node);
+ if (!pud)
+ return -ENOMEM;
+
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd)) {
+ pte_t entry;
+ void *p = vmemmap_alloc_block(PMD_SIZE, node);
+ if (!p)
+ return -ENOMEM;
+
+ entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
+ mk_pte_huge(entry);
+ set_pmd(pmd, __pmd(pte_val(entry)));
+
+ printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n",
+ addr, addr + PMD_SIZE - 1, p, node);
+ } else
+ vmemmap_verify((pte_t *)pmd, node, addr, next);
+ }
+
+ return 0;
+}
+#endif
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 6da23552226..5eec5e56d07 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -166,7 +166,7 @@ early_node_mem(int nodeid, unsigned long start, unsigned long end,
return __va(mem);
ptr = __alloc_bootmem_nopanic(size,
SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS));
- if (ptr == 0) {
+ if (ptr == NULL) {
printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
size, nodeid);
return NULL;
@@ -261,7 +261,7 @@ void __init numa_init_array(void)
We round robin the existing nodes. */
rr = first_node(node_online_map);
for (i = 0; i < NR_CPUS; i++) {
- if (cpu_to_node[i] != NUMA_NO_NODE)
+ if (cpu_to_node(i) != NUMA_NO_NODE)
continue;
numa_set_node(i, rr);
rr = next_node(rr, node_online_map);
@@ -543,7 +543,7 @@ __cpuinit void numa_add_cpu(int cpu)
void __cpuinit numa_set_node(int cpu, int node)
{
cpu_pda(cpu)->nodenumber = node;
- cpu_to_node[cpu] = node;
+ cpu_to_node(cpu) = node;
}
unsigned long __init numa_free_all_bootmem(void)
diff --git a/arch/x86/mm/pageattr_32.c b/arch/x86/mm/pageattr_32.c
index 4241a74d16c..260073c0760 100644
--- a/arch/x86/mm/pageattr_32.c
+++ b/arch/x86/mm/pageattr_32.c
@@ -70,10 +70,10 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
static void cache_flush_page(struct page *p)
{
- unsigned long adr = (unsigned long)page_address(p);
+ void *adr = page_address(p);
int i;
for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
- asm volatile("clflush (%0)" :: "r" (adr + i));
+ clflush(adr+i);
}
static void flush_kernel_map(void *arg)
diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c
index 10b9809ce82..8a4f65bf956 100644
--- a/arch/x86/mm/pageattr_64.c
+++ b/arch/x86/mm/pageattr_64.c
@@ -65,7 +65,7 @@ static void cache_flush_page(void *adr)
{
int i;
for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
- asm volatile("clflush (%0)" :: "r" (adr + i));
+ clflush(adr+i);
}
static void flush_kernel_map(void *arg)
@@ -148,6 +148,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
split = split_large_page(address, prot, ref_prot2);
if (!split)
return -ENOMEM;
+ pgprot_val(ref_prot2) &= ~_PAGE_NX;
set_pte(kpte, mk_pte(split, ref_prot2));
kpte_page = split;
}
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 01437c46baa..be61a1d845a 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mm.h>
+#include <linux/nmi.h>
#include <linux/swap.h>
#include <linux/smp.h>
#include <linux/highmem.h>
@@ -39,6 +40,8 @@ void show_mem(void)
for_each_online_pgdat(pgdat) {
pgdat_resize_lock(pgdat, &flags);
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
+ if (unlikely(i % MAX_ORDER_NR_PAGES == 0))
+ touch_nmi_watchdog();
page = pgdat_page_nr(pgdat, i);
total++;
if (PageHighMem(page))
@@ -97,8 +100,7 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
}
pte = pte_offset_kernel(pmd, vaddr);
if (pgprot_val(flags))
- /* <pfn,flags> stored as-is, to permit clearing entries */
- set_pte(pte, pfn_pte(pfn, flags));
+ set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
else
pte_clear(&init_mm, vaddr, pte);
@@ -193,7 +195,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
return pte;
}
-void pmd_ctor(void *pmd, struct kmem_cache *cache, unsigned long flags)
+void pmd_ctor(struct kmem_cache *cache, void *pmd)
{
memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
}
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index acdf03e1914..56089ccc394 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -431,9 +431,9 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
setup_node_bootmem(i, nodes[i].start, nodes[i].end);
for (i = 0; i < NR_CPUS; i++) {
- if (cpu_to_node[i] == NUMA_NO_NODE)
+ if (cpu_to_node(i) == NUMA_NO_NODE)
continue;
- if (!node_isset(cpu_to_node[i], node_possible_map))
+ if (!node_isset(cpu_to_node(i), node_possible_map))
numa_set_node(i, NUMA_NO_NODE);
}
numa_init_array();
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 11b7a51566a..2d0eeac7251 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -269,7 +269,6 @@ static void nmi_cpu_shutdown(void * dummy)
apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
apic_write(APIC_LVTERR, v);
nmi_restore_registers(msrs);
- model->shutdown(msrs);
}
@@ -278,6 +277,7 @@ static void nmi_shutdown(void)
nmi_enabled = 0;
on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
unregister_die_notifier(&profile_exceptions_nb);
+ model->shutdown(cpu_msrs);
free_msrs();
}
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 47925927b12..56b4757a1f4 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -379,7 +379,7 @@ static unsigned int get_stagger(void)
{
#ifdef CONFIG_SMP
int cpu = smp_processor_id();
- return (cpu != first_cpu(cpu_sibling_map[cpu]));
+ return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
#endif
return 0;
}
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 2d71bbc411d..f4386990b15 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -289,6 +289,22 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
},
},
+ {
+ .callback = set_bf_sort,
+ .ident = "HP ProLiant DL385 G2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385 G2"),
+ },
+ },
+ {
+ .callback = set_bf_sort,
+ .ident = "HP ProLiant DL585 G2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
+ },
+ },
#ifdef __i386__
{
.callback = assign_all_busses,
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index 8d03de029d9..7a2ba458393 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -13,7 +13,7 @@ vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
$(obj)/vdso.o: $(obj)/vdso.so
-targets += vdso.so vdso.lds $(vobjs-y) vdso-syms.o
+targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) vdso-syms.o
# The DSO images are built using a special linker script.
quiet_cmd_syscall = SYSCALL $@
@@ -26,16 +26,23 @@ vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \
$(call ld-option, -Wl$(comma)--hash-style=sysv) \
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
SYSCFLAGS_vdso.so = $(vdso-flags)
+SYSCFLAGS_vdso.so.dbg = $(vdso-flags)
$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
$(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE
+
+$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
$(call if_changed,syscall)
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
+
CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64
-$(obj)/vclock_gettime.o: CFLAGS = $(CFL)
-$(obj)/vgetcpu.o: CFLAGS = $(CFL)
+$(obj)/vclock_gettime.o: KBUILD_CFLAGS = $(CFL)
+$(obj)/vgetcpu.o: KBUILD_CFLAGS = $(CFL)
# We also create a special relocatable object that should mirror the symbol
# table and layout of the linked DSO. With ld -R we can then refer to
@@ -47,3 +54,11 @@ $(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o
SYSCFLAGS_vdso-syms.o = -r -d
$(obj)/vdso-syms.o: $(src)/vdso.lds $(vobjs) FORCE
$(call if_changed,syscall)
+
+quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+vdso.so:
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso_install: vdso.so
diff --git a/arch/x86/vdso/vdso.lds.S b/arch/x86/vdso/vdso.lds.S
index b9a60e665d0..667d3245d97 100644
--- a/arch/x86/vdso/vdso.lds.S
+++ b/arch/x86/vdso/vdso.lds.S
@@ -26,13 +26,16 @@ SECTIONS
is insufficient, ld -shared will barf. Just increase it here. */
. = VDSO_PRELINK + VDSO_TEXT_OFFSET;
- .text : { *(.text) } :text
- .text.ptr : { *(.text.ptr) } :text
- . = VDSO_PRELINK + 0x900;
- .data : { *(.data) } :text
- .bss : { *(.bss) } :text
+ .text : { *(.text*) } :text
+ .rodata : { *(.rodata*) } :text
+ .data : {
+ *(.data*)
+ *(.sdata*)
+ *(.bss*)
+ *(.dynbss*)
+ } :text
- .altinstructions : { *(.altinstructions) } :text
+ .altinstructions : { *(.altinstructions) } :text
.altinstr_replacement : { *(.altinstr_replacement) } :text
.note : { *(.note.*) } :text :note
@@ -42,7 +45,6 @@ SECTIONS
.useless : {
*(.got.plt) *(.got)
*(.gnu.linkonce.d.*)
- *(.dynbss)
*(.gnu.linkonce.b.*)
} :text
}
diff --git a/arch/x86/vdso/vvar.c b/arch/x86/vdso/vvar.c
index 6fc22219a47..1b7e703684f 100644
--- a/arch/x86/vdso/vvar.c
+++ b/arch/x86/vdso/vvar.c
@@ -8,5 +8,5 @@
#include <asm/timex.h>
#include <asm/vgtod.h>
-#define VEXTERN(x) typeof (__ ## x) *vdso_ ## x = (void *)VMAGIC;
+#define VEXTERN(x) typeof (__ ## x) *const vdso_ ## x = (void *)VMAGIC;
#include "vextern.h"
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index f01bfcd4bde..94c39aaf695 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/page-flags.h>
#include <linux/highmem.h>
-#include <linux/smp.h>
#include <xen/interface/xen.h>
#include <xen/interface/physdev.h>
@@ -52,11 +51,25 @@
EXPORT_SYMBOL_GPL(hypercall_page);
-DEFINE_PER_CPU(enum paravirt_lazy_mode, xen_lazy_mode);
-
DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
-DEFINE_PER_CPU(unsigned long, xen_cr3);
+
+/*
+ * Note about cr3 (pagetable base) values:
+ *
+ * xen_cr3 contains the current logical cr3 value; it contains the
+ * last set cr3. This may not be the current effective cr3, because
+ * its update may be being lazily deferred. However, a vcpu looking
+ * at its own cr3 can use this value knowing that it everything will
+ * be self-consistent.
+ *
+ * xen_current_cr3 contains the actual vcpu cr3; it is set once the
+ * hypercall to set the vcpu cr3 is complete (so it may be a little
+ * out of date, but it will never be set early). If one vcpu is
+ * looking at another vcpu's cr3 value, it should use this variable.
+ */
+DEFINE_PER_CPU(unsigned long, xen_cr3); /* cr3 stored as physaddr */
+DEFINE_PER_CPU(unsigned long, xen_current_cr3); /* actual vcpu cr3 */
struct start_info *xen_start_info;
EXPORT_SYMBOL_GPL(xen_start_info);
@@ -100,7 +113,7 @@ static void __init xen_vcpu_setup(int cpu)
info.mfn = virt_to_mfn(vcpup);
info.offset = offset_in_page(vcpup);
- printk(KERN_DEBUG "trying to map vcpu_info %d at %p, mfn %x, offset %d\n",
+ printk(KERN_DEBUG "trying to map vcpu_info %d at %p, mfn %llx, offset %d\n",
cpu, vcpup, info.mfn, info.offset);
/* Check to see if the hypervisor will put the vcpu_info
@@ -124,7 +137,7 @@ static void __init xen_vcpu_setup(int cpu)
static void __init xen_banner(void)
{
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
- paravirt_ops.name);
+ pv_info.name);
printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic);
}
@@ -249,29 +262,10 @@ static void xen_halt(void)
xen_safe_halt();
}
-static void xen_set_lazy_mode(enum paravirt_lazy_mode mode)
+static void xen_leave_lazy(void)
{
- BUG_ON(preemptible());
-
- switch (mode) {
- case PARAVIRT_LAZY_NONE:
- BUG_ON(x86_read_percpu(xen_lazy_mode) == PARAVIRT_LAZY_NONE);
- break;
-
- case PARAVIRT_LAZY_MMU:
- case PARAVIRT_LAZY_CPU:
- BUG_ON(x86_read_percpu(xen_lazy_mode) != PARAVIRT_LAZY_NONE);
- break;
-
- case PARAVIRT_LAZY_FLUSH:
- /* flush if necessary, but don't change state */
- if (x86_read_percpu(xen_lazy_mode) != PARAVIRT_LAZY_NONE)
- xen_mc_flush();
- return;
- }
-
+ paravirt_leave_lazy(paravirt_get_lazy_mode());
xen_mc_flush();
- x86_write_percpu(xen_lazy_mode, mode);
}
static unsigned long xen_store_tr(void)
@@ -358,7 +352,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
* loaded properly. This will go away as soon as Xen has been
* modified to not save/restore %gs for normal hypercalls.
*/
- if (xen_get_lazy_mode() == PARAVIRT_LAZY_CPU)
+ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)
loadsegment(gs, 0);
}
@@ -632,32 +626,36 @@ static unsigned long xen_read_cr3(void)
return x86_read_percpu(xen_cr3);
}
+static void set_current_cr3(void *v)
+{
+ x86_write_percpu(xen_current_cr3, (unsigned long)v);
+}
+
static void xen_write_cr3(unsigned long cr3)
{
+ struct mmuext_op *op;
+ struct multicall_space mcs;
+ unsigned long mfn = pfn_to_mfn(PFN_DOWN(cr3));
+
BUG_ON(preemptible());
- if (cr3 == x86_read_percpu(xen_cr3)) {
- /* just a simple tlb flush */
- xen_flush_tlb();
- return;
- }
+ mcs = xen_mc_entry(sizeof(*op)); /* disables interrupts */
+ /* Update while interrupts are disabled, so its atomic with
+ respect to ipis */
x86_write_percpu(xen_cr3, cr3);
+ op = mcs.args;
+ op->cmd = MMUEXT_NEW_BASEPTR;
+ op->arg1.mfn = mfn;
- {
- struct mmuext_op *op;
- struct multicall_space mcs = xen_mc_entry(sizeof(*op));
- unsigned long mfn = pfn_to_mfn(PFN_DOWN(cr3));
-
- op = mcs.args;
- op->cmd = MMUEXT_NEW_BASEPTR;
- op->arg1.mfn = mfn;
+ MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
- MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+ /* Update xen_update_cr3 once the batch has actually
+ been submitted. */
+ xen_mc_callback(set_current_cr3, (void *)cr3);
- xen_mc_issue(PARAVIRT_LAZY_CPU);
- }
+ xen_mc_issue(PARAVIRT_LAZY_CPU); /* interrupts restored */
}
/* Early in boot, while setting up the initial pagetable, assume
@@ -668,6 +666,15 @@ static __init void xen_alloc_pt_init(struct mm_struct *mm, u32 pfn)
make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
}
+static void pin_pagetable_pfn(unsigned level, unsigned long pfn)
+{
+ struct mmuext_op op;
+ op.cmd = level;
+ op.arg1.mfn = pfn_to_mfn(pfn);
+ if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
+ BUG();
+}
+
/* This needs to make sure the new pte page is pinned iff its being
attached to a pinned pagetable. */
static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
@@ -677,9 +684,10 @@ static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
if (PagePinned(virt_to_page(mm->pgd))) {
SetPagePinned(page);
- if (!PageHighMem(page))
+ if (!PageHighMem(page)) {
make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
- else
+ pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
+ } else
/* make sure there are no stray mappings of
this page */
kmap_flush_unused();
@@ -692,8 +700,10 @@ static void xen_release_pt(u32 pfn)
struct page *page = pfn_to_page(pfn);
if (PagePinned(page)) {
- if (!PageHighMem(page))
+ if (!PageHighMem(page)) {
+ pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
+ }
}
}
@@ -738,7 +748,7 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
/* special set_pte for pagetable initialization */
- paravirt_ops.set_pte = xen_set_pte_init;
+ pv_mmu_ops.set_pte = xen_set_pte_init;
init_mm.pgd = base;
/*
@@ -785,8 +795,8 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
{
/* This will work as long as patching hasn't happened yet
(which it hasn't) */
- paravirt_ops.alloc_pt = xen_alloc_pt;
- paravirt_ops.set_pte = xen_set_pte;
+ pv_mmu_ops.alloc_pt = xen_alloc_pt;
+ pv_mmu_ops.set_pte = xen_set_pte;
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/*
@@ -808,15 +818,15 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
/* Actually pin the pagetable down, but we can't set PG_pinned
yet because the page structures don't exist yet. */
{
- struct mmuext_op op;
+ unsigned level;
+
#ifdef CONFIG_X86_PAE
- op.cmd = MMUEXT_PIN_L3_TABLE;
+ level = MMUEXT_PIN_L3_TABLE;
#else
- op.cmd = MMUEXT_PIN_L3_TABLE;
+ level = MMUEXT_PIN_L2_TABLE;
#endif
- op.arg1.mfn = pfn_to_mfn(PFN_DOWN(__pa(base)));
- if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
- BUG();
+
+ pin_pagetable_pfn(level, PFN_DOWN(__pa(base)));
}
}
@@ -833,12 +843,12 @@ void __init xen_setup_vcpu_info_placement(void)
if (have_vcpu_info_placement) {
printk(KERN_INFO "Xen: using vcpu_info placement\n");
- paravirt_ops.save_fl = xen_save_fl_direct;
- paravirt_ops.restore_fl = xen_restore_fl_direct;
- paravirt_ops.irq_disable = xen_irq_disable_direct;
- paravirt_ops.irq_enable = xen_irq_enable_direct;
- paravirt_ops.read_cr2 = xen_read_cr2_direct;
- paravirt_ops.iret = xen_iret_direct;
+ pv_irq_ops.save_fl = xen_save_fl_direct;
+ pv_irq_ops.restore_fl = xen_restore_fl_direct;
+ pv_irq_ops.irq_disable = xen_irq_disable_direct;
+ pv_irq_ops.irq_enable = xen_irq_enable_direct;
+ pv_mmu_ops.read_cr2 = xen_read_cr2_direct;
+ pv_cpu_ops.iret = xen_iret_direct;
}
}
@@ -850,8 +860,8 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
start = end = reloc = NULL;
-#define SITE(x) \
- case PARAVIRT_PATCH(x): \
+#define SITE(op, x) \
+ case PARAVIRT_PATCH(op.x): \
if (have_vcpu_info_placement) { \
start = (char *)xen_##x##_direct; \
end = xen_##x##_direct_end; \
@@ -860,10 +870,10 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
goto patch_site
switch (type) {
- SITE(irq_enable);
- SITE(irq_disable);
- SITE(save_fl);
- SITE(restore_fl);
+ SITE(pv_irq_ops, irq_enable);
+ SITE(pv_irq_ops, irq_disable);
+ SITE(pv_irq_ops, save_fl);
+ SITE(pv_irq_ops, restore_fl);
#undef SITE
patch_site:
@@ -895,26 +905,32 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
return ret;
}
-static const struct paravirt_ops xen_paravirt_ops __initdata = {
+static const struct pv_info xen_info __initdata = {
.paravirt_enabled = 1,
.shared_kernel_pmd = 0,
.name = "Xen",
- .banner = xen_banner,
+};
+static const struct pv_init_ops xen_init_ops __initdata = {
.patch = xen_patch,
+ .banner = xen_banner,
.memory_setup = xen_memory_setup,
.arch_setup = xen_arch_setup,
- .init_IRQ = xen_init_IRQ,
.post_allocator_init = xen_mark_init_mm_pinned,
+};
+static const struct pv_time_ops xen_time_ops __initdata = {
.time_init = xen_time_init,
+
.set_wallclock = xen_set_wallclock,
.get_wallclock = xen_get_wallclock,
.get_cpu_khz = xen_cpu_khz,
.sched_clock = xen_sched_clock,
+};
+static const struct pv_cpu_ops xen_cpu_ops __initdata = {
.cpuid = xen_cpuid,
.set_debugreg = xen_set_debugreg,
@@ -925,22 +941,10 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
.read_cr0 = native_read_cr0,
.write_cr0 = native_write_cr0,
- .read_cr2 = xen_read_cr2,
- .write_cr2 = xen_write_cr2,
-
- .read_cr3 = xen_read_cr3,
- .write_cr3 = xen_write_cr3,
-
.read_cr4 = native_read_cr4,
.read_cr4_safe = native_read_cr4_safe,
.write_cr4 = xen_write_cr4,
- .save_fl = xen_save_fl,
- .restore_fl = xen_restore_fl,
- .irq_disable = xen_irq_disable,
- .irq_enable = xen_irq_enable,
- .safe_halt = xen_safe_halt,
- .halt = xen_halt,
.wbinvd = native_wbinvd,
.read_msr = native_read_msr_safe,
@@ -969,6 +973,23 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
.set_iopl_mask = xen_set_iopl_mask,
.io_delay = xen_io_delay,
+ .lazy_mode = {
+ .enter = paravirt_enter_lazy_cpu,
+ .leave = xen_leave_lazy,
+ },
+};
+
+static const struct pv_irq_ops xen_irq_ops __initdata = {
+ .init_IRQ = xen_init_IRQ,
+ .save_fl = xen_save_fl,
+ .restore_fl = xen_restore_fl,
+ .irq_disable = xen_irq_disable,
+ .irq_enable = xen_irq_enable,
+ .safe_halt = xen_safe_halt,
+ .halt = xen_halt,
+};
+
+static const struct pv_apic_ops xen_apic_ops __initdata = {
#ifdef CONFIG_X86_LOCAL_APIC
.apic_write = xen_apic_write,
.apic_write_atomic = xen_apic_write,
@@ -977,6 +998,17 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
.setup_secondary_clock = paravirt_nop,
.startup_ipi_hook = paravirt_nop,
#endif
+};
+
+static const struct pv_mmu_ops xen_mmu_ops __initdata = {
+ .pagetable_setup_start = xen_pagetable_setup_start,
+ .pagetable_setup_done = xen_pagetable_setup_done,
+
+ .read_cr2 = xen_read_cr2,
+ .write_cr2 = xen_write_cr2,
+
+ .read_cr3 = xen_read_cr3,
+ .write_cr3 = xen_write_cr3,
.flush_tlb_user = xen_flush_tlb,
.flush_tlb_kernel = xen_flush_tlb,
@@ -986,9 +1018,6 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
.pte_update = paravirt_nop,
.pte_update_defer = paravirt_nop,
- .pagetable_setup_start = xen_pagetable_setup_start,
- .pagetable_setup_done = xen_pagetable_setup_done,
-
.alloc_pt = xen_alloc_pt_init,
.release_pt = xen_release_pt,
.alloc_pd = paravirt_nop,
@@ -1024,7 +1053,10 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = {
.dup_mmap = xen_dup_mmap,
.exit_mmap = xen_exit_mmap,
- .set_lazy_mode = xen_set_lazy_mode,
+ .lazy_mode = {
+ .enter = paravirt_enter_lazy_mmu,
+ .leave = xen_leave_lazy,
+ },
};
#ifdef CONFIG_SMP
@@ -1080,6 +1112,17 @@ static const struct machine_ops __initdata xen_machine_ops = {
};
+static void __init xen_reserve_top(void)
+{
+ unsigned long top = HYPERVISOR_VIRT_START;
+ struct xen_platform_parameters pp;
+
+ if (HYPERVISOR_xen_version(XENVER_platform_parameters, &pp) == 0)
+ top = pp.virt_start;
+
+ reserve_top_address(-top + 2 * PAGE_SIZE);
+}
+
/* First C function to be called on Xen boot */
asmlinkage void __init xen_start_kernel(void)
{
@@ -1091,7 +1134,14 @@ asmlinkage void __init xen_start_kernel(void)
BUG_ON(memcmp(xen_start_info->magic, "xen-3.0", 7) != 0);
/* Install Xen paravirt ops */
- paravirt_ops = xen_paravirt_ops;
+ pv_info = xen_info;
+ pv_init_ops = xen_init_ops;
+ pv_time_ops = xen_time_ops;
+ pv_cpu_ops = xen_cpu_ops;
+ pv_irq_ops = xen_irq_ops;
+ pv_apic_ops = xen_apic_ops;
+ pv_mmu_ops = xen_mmu_ops;
+
machine_ops = xen_machine_ops;
#ifdef CONFIG_SMP
@@ -1113,6 +1163,7 @@ asmlinkage void __init xen_start_kernel(void)
/* keep using Xen gdt for now; no urgent need to change it */
x86_write_percpu(xen_cr3, __pa(pgd));
+ x86_write_percpu(xen_current_cr3, __pa(pgd));
#ifdef CONFIG_SMP
/* Don't do the full vcpu_info placement stuff until we have a
@@ -1124,12 +1175,12 @@ asmlinkage void __init xen_start_kernel(void)
xen_setup_vcpu_info_placement();
#endif
- paravirt_ops.kernel_rpl = 1;
+ pv_info.kernel_rpl = 1;
if (xen_feature(XENFEAT_supervisor_mode_kernel))
- paravirt_ops.kernel_rpl = 0;
+ pv_info.kernel_rpl = 0;
/* set the limit of our address space */
- reserve_top_address(-HYPERVISOR_VIRT_START + 2 * PAGE_SIZE);
+ xen_reserve_top();
/* set up basic CPUID stuff */
cpu_detect(&new_cpu_data);
@@ -1137,9 +1188,10 @@ asmlinkage void __init xen_start_kernel(void)
new_cpu_data.x86_capability[0] = cpuid_edx(1);
/* Poke various useful things into boot_params */
- LOADER_TYPE = (9 << 4) | 0;
- INITRD_START = xen_start_info->mod_start ? __pa(xen_start_info->mod_start) : 0;
- INITRD_SIZE = xen_start_info->mod_len;
+ boot_params.hdr.type_of_loader = (9 << 4) | 0;
+ boot_params.hdr.ramdisk_image = xen_start_info->mod_start
+ ? __pa(xen_start_info->mod_start) : 0;
+ boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
/* Start the world */
start_kernel();
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 874db0cd1d2..b2e32f9d007 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -41,7 +41,6 @@
#include <linux/sched.h>
#include <linux/highmem.h>
#include <linux/bug.h>
-#include <linux/sched.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
@@ -155,7 +154,7 @@ void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
if (mm == current->mm || mm == &init_mm) {
- if (xen_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
+ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
struct multicall_space mcs;
mcs = xen_mc_entry(0);
@@ -304,7 +303,12 @@ pgd_t xen_make_pgd(unsigned long pgd)
}
#endif /* CONFIG_X86_PAE */
-
+enum pt_level {
+ PT_PGD,
+ PT_PUD,
+ PT_PMD,
+ PT_PTE
+};
/*
(Yet another) pagetable walker. This one is intended for pinning a
@@ -316,7 +320,7 @@ pgd_t xen_make_pgd(unsigned long pgd)
FIXADDR_TOP. But the important bit is that we don't pin beyond
there, because then we start getting into Xen's ptes.
*/
-static int pgd_walk(pgd_t *pgd_base, int (*func)(struct page *, unsigned),
+static int pgd_walk(pgd_t *pgd_base, int (*func)(struct page *, enum pt_level),
unsigned long limit)
{
pgd_t *pgd = pgd_base;
@@ -341,7 +345,7 @@ static int pgd_walk(pgd_t *pgd_base, int (*func)(struct page *, unsigned),
pud = pud_offset(pgd, 0);
if (PTRS_PER_PUD > 1) /* not folded */
- flush |= (*func)(virt_to_page(pud), 0);
+ flush |= (*func)(virt_to_page(pud), PT_PUD);
for (; addr != pud_limit; pud++, addr = pud_next) {
pmd_t *pmd;
@@ -360,7 +364,7 @@ static int pgd_walk(pgd_t *pgd_base, int (*func)(struct page *, unsigned),
pmd = pmd_offset(pud, 0);
if (PTRS_PER_PMD > 1) /* not folded */
- flush |= (*func)(virt_to_page(pmd), 0);
+ flush |= (*func)(virt_to_page(pmd), PT_PMD);
for (; addr != pmd_limit; pmd++) {
addr += (PAGE_SIZE * PTRS_PER_PTE);
@@ -372,17 +376,47 @@ static int pgd_walk(pgd_t *pgd_base, int (*func)(struct page *, unsigned),
if (pmd_none(*pmd))
continue;
- flush |= (*func)(pmd_page(*pmd), 0);
+ flush |= (*func)(pmd_page(*pmd), PT_PTE);
}
}
}
- flush |= (*func)(virt_to_page(pgd_base), UVMF_TLB_FLUSH);
+ flush |= (*func)(virt_to_page(pgd_base), PT_PGD);
return flush;
}
-static int pin_page(struct page *page, unsigned flags)
+static spinlock_t *lock_pte(struct page *page)
+{
+ spinlock_t *ptl = NULL;
+
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+ ptl = __pte_lockptr(page);
+ spin_lock(ptl);
+#endif
+
+ return ptl;
+}
+
+static void do_unlock(void *v)
+{
+ spinlock_t *ptl = v;
+ spin_unlock(ptl);
+}
+
+static void xen_do_pin(unsigned level, unsigned long pfn)
+{
+ struct mmuext_op *op;
+ struct multicall_space mcs;
+
+ mcs = __xen_mc_entry(sizeof(*op));
+ op = mcs.args;
+ op->cmd = level;
+ op->arg1.mfn = pfn_to_mfn(pfn);
+ MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+}
+
+static int pin_page(struct page *page, enum pt_level level)
{
unsigned pgfl = test_and_set_bit(PG_pinned, &page->flags);
int flush;
@@ -397,12 +431,26 @@ static int pin_page(struct page *page, unsigned flags)
void *pt = lowmem_page_address(page);
unsigned long pfn = page_to_pfn(page);
struct multicall_space mcs = __xen_mc_entry(0);
+ spinlock_t *ptl;
flush = 0;
+ ptl = NULL;
+ if (level == PT_PTE)
+ ptl = lock_pte(page);
+
MULTI_update_va_mapping(mcs.mc, (unsigned long)pt,
pfn_pte(pfn, PAGE_KERNEL_RO),
- flags);
+ level == PT_PGD ? UVMF_TLB_FLUSH : 0);
+
+ if (level == PT_PTE)
+ xen_do_pin(MMUEXT_PIN_L1_TABLE, pfn);
+
+ if (ptl) {
+ /* Queue a deferred unlock for when this batch
+ is completed. */
+ xen_mc_callback(do_unlock, ptl);
+ }
}
return flush;
@@ -413,8 +461,7 @@ static int pin_page(struct page *page, unsigned flags)
read-only, and can be pinned. */
void xen_pgd_pin(pgd_t *pgd)
{
- struct multicall_space mcs;
- struct mmuext_op *op;
+ unsigned level;
xen_mc_batch();
@@ -425,16 +472,13 @@ void xen_pgd_pin(pgd_t *pgd)
xen_mc_batch();
}
- mcs = __xen_mc_entry(sizeof(*op));
- op = mcs.args;
-
#ifdef CONFIG_X86_PAE
- op->cmd = MMUEXT_PIN_L3_TABLE;
+ level = MMUEXT_PIN_L3_TABLE;
#else
- op->cmd = MMUEXT_PIN_L2_TABLE;
+ level = MMUEXT_PIN_L2_TABLE;
#endif
- op->arg1.mfn = pfn_to_mfn(PFN_DOWN(__pa(pgd)));
- MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+
+ xen_do_pin(level, PFN_DOWN(__pa(pgd)));
xen_mc_issue(0);
}
@@ -442,7 +486,7 @@ void xen_pgd_pin(pgd_t *pgd)
/* The init_mm pagetable is really pinned as soon as its created, but
that's before we have page structures to store the bits. So do all
the book-keeping now. */
-static __init int mark_pinned(struct page *page, unsigned flags)
+static __init int mark_pinned(struct page *page, enum pt_level level)
{
SetPagePinned(page);
return 0;
@@ -453,18 +497,32 @@ void __init xen_mark_init_mm_pinned(void)
pgd_walk(init_mm.pgd, mark_pinned, FIXADDR_TOP);
}
-static int unpin_page(struct page *page, unsigned flags)
+static int unpin_page(struct page *page, enum pt_level level)
{
unsigned pgfl = test_and_clear_bit(PG_pinned, &page->flags);
if (pgfl && !PageHighMem(page)) {
void *pt = lowmem_page_address(page);
unsigned long pfn = page_to_pfn(page);
- struct multicall_space mcs = __xen_mc_entry(0);
+ spinlock_t *ptl = NULL;
+ struct multicall_space mcs;
+
+ if (level == PT_PTE) {
+ ptl = lock_pte(page);
+
+ xen_do_pin(MMUEXT_UNPIN_TABLE, pfn);
+ }
+
+ mcs = __xen_mc_entry(0);
MULTI_update_va_mapping(mcs.mc, (unsigned long)pt,
pfn_pte(pfn, PAGE_KERNEL),
- flags);
+ level == PT_PGD ? UVMF_TLB_FLUSH : 0);
+
+ if (ptl) {
+ /* unlock when batch completed */
+ xen_mc_callback(do_unlock, ptl);
+ }
}
return 0; /* never need to flush on unpin */
@@ -473,18 +531,9 @@ static int unpin_page(struct page *page, unsigned flags)
/* Release a pagetables pages back as normal RW */
static void xen_pgd_unpin(pgd_t *pgd)
{
- struct mmuext_op *op;
- struct multicall_space mcs;
-
xen_mc_batch();
- mcs = __xen_mc_entry(sizeof(*op));
-
- op = mcs.args;
- op->cmd = MMUEXT_UNPIN_TABLE;
- op->arg1.mfn = pfn_to_mfn(PFN_DOWN(__pa(pgd)));
-
- MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
+ xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
pgd_walk(pgd, unpin_page, TASK_SIZE);
@@ -515,20 +564,43 @@ static void drop_other_mm_ref(void *info)
if (__get_cpu_var(cpu_tlbstate).active_mm == mm)
leave_mm(smp_processor_id());
+
+ /* If this cpu still has a stale cr3 reference, then make sure
+ it has been flushed. */
+ if (x86_read_percpu(xen_current_cr3) == __pa(mm->pgd)) {
+ load_cr3(swapper_pg_dir);
+ arch_flush_lazy_cpu_mode();
+ }
}
static void drop_mm_ref(struct mm_struct *mm)
{
+ cpumask_t mask;
+ unsigned cpu;
+
if (current->active_mm == mm) {
if (current->mm == mm)
load_cr3(swapper_pg_dir);
else
leave_mm(smp_processor_id());
+ arch_flush_lazy_cpu_mode();
}
- if (!cpus_empty(mm->cpu_vm_mask))
- xen_smp_call_function_mask(mm->cpu_vm_mask, drop_other_mm_ref,
- mm, 1);
+ /* Get the "official" set of cpus referring to our pagetable. */
+ mask = mm->cpu_vm_mask;
+
+ /* It's possible that a vcpu may have a stale reference to our
+ cr3, because its in lazy mode, and it hasn't yet flushed
+ its set of pending hypercalls yet. In this case, we can
+ look at its actual current cr3 value, and force it to flush
+ if needed. */
+ for_each_online_cpu(cpu) {
+ if (per_cpu(xen_current_cr3, cpu) == __pa(mm->pgd))
+ cpu_set(cpu, mask);
+ }
+
+ if (!cpus_empty(mask))
+ xen_smp_call_function_mask(mask, drop_other_mm_ref, mm, 1);
}
#else
static void drop_mm_ref(struct mm_struct *mm)
@@ -563,5 +635,6 @@ void xen_exit_mmap(struct mm_struct *mm)
/* pgd may not be pinned in the error exit path of execve */
if (PagePinned(virt_to_page(mm->pgd)))
xen_pgd_unpin(mm->pgd);
+
spin_unlock(&mm->page_table_lock);
}
diff --git a/arch/x86/xen/multicalls.c b/arch/x86/xen/multicalls.c
index c837e8e463d..5e6f36f6d87 100644
--- a/arch/x86/xen/multicalls.c
+++ b/arch/x86/xen/multicalls.c
@@ -26,13 +26,22 @@
#include "multicalls.h"
+#define MC_DEBUG 1
+
#define MC_BATCH 32
#define MC_ARGS (MC_BATCH * 16 / sizeof(u64))
struct mc_buffer {
struct multicall_entry entries[MC_BATCH];
+#if MC_DEBUG
+ struct multicall_entry debug[MC_BATCH];
+#endif
u64 args[MC_ARGS];
- unsigned mcidx, argidx;
+ struct callback {
+ void (*fn)(void *);
+ void *data;
+ } callbacks[MC_BATCH];
+ unsigned mcidx, argidx, cbidx;
};
static DEFINE_PER_CPU(struct mc_buffer, mc_buffer);
@@ -43,6 +52,7 @@ void xen_mc_flush(void)
struct mc_buffer *b = &__get_cpu_var(mc_buffer);
int ret = 0;
unsigned long flags;
+ int i;
BUG_ON(preemptible());
@@ -51,13 +61,31 @@ void xen_mc_flush(void)
local_irq_save(flags);
if (b->mcidx) {
- int i;
+#if MC_DEBUG
+ memcpy(b->debug, b->entries,
+ b->mcidx * sizeof(struct multicall_entry));
+#endif
if (HYPERVISOR_multicall(b->entries, b->mcidx) != 0)
BUG();
for (i = 0; i < b->mcidx; i++)
if (b->entries[i].result < 0)
ret++;
+
+#if MC_DEBUG
+ if (ret) {
+ printk(KERN_ERR "%d multicall(s) failed: cpu %d\n",
+ ret, smp_processor_id());
+ for(i = 0; i < b->mcidx; i++) {
+ printk(" call %2d/%d: op=%lu arg=[%lx] result=%ld\n",
+ i+1, b->mcidx,
+ b->debug[i].op,
+ b->debug[i].args[0],
+ b->entries[i].result);
+ }
+ }
+#endif
+
b->mcidx = 0;
b->argidx = 0;
} else
@@ -65,6 +93,13 @@ void xen_mc_flush(void)
local_irq_restore(flags);
+ for(i = 0; i < b->cbidx; i++) {
+ struct callback *cb = &b->callbacks[i];
+
+ (*cb->fn)(cb->data);
+ }
+ b->cbidx = 0;
+
BUG_ON(ret);
}
@@ -88,3 +123,16 @@ struct multicall_space __xen_mc_entry(size_t args)
return ret;
}
+
+void xen_mc_callback(void (*fn)(void *), void *data)
+{
+ struct mc_buffer *b = &__get_cpu_var(mc_buffer);
+ struct callback *cb;
+
+ if (b->cbidx == MC_BATCH)
+ xen_mc_flush();
+
+ cb = &b->callbacks[b->cbidx++];
+ cb->fn = fn;
+ cb->data = data;
+}
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h
index e6f7530b156..8bae996d99a 100644
--- a/arch/x86/xen/multicalls.h
+++ b/arch/x86/xen/multicalls.h
@@ -35,11 +35,14 @@ void xen_mc_flush(void);
/* Issue a multicall if we're not in a lazy mode */
static inline void xen_mc_issue(unsigned mode)
{
- if ((xen_get_lazy_mode() & mode) == 0)
+ if ((paravirt_get_lazy_mode() & mode) == 0)
xen_mc_flush();
/* restore flags saved in xen_mc_batch */
local_irq_restore(x86_read_percpu(xen_mc_irq_flags));
}
+/* Set up a callback to be called when the current batch is flushed */
+void xen_mc_callback(void (*fn)(void *), void *data);
+
#endif /* _XEN_MULTICALLS_H */
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 557b8e24706..c1b131bcdcb 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -147,8 +147,13 @@ void __init xen_smp_prepare_boot_cpu(void)
make_lowmem_page_readwrite(&per_cpu__gdt_page);
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
+ /*
+ * cpu_core_map lives in a per cpu area that is cleared
+ * when the per cpu array is allocated.
+ *
+ * cpus_clear(per_cpu(cpu_core_map, cpu));
+ */
}
xen_setup_vcpu_info_placement();
@@ -159,8 +164,13 @@ void __init xen_smp_prepare_cpus(unsigned int max_cpus)
unsigned cpu;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
+ cpus_clear(per_cpu(cpu_sibling_map, cpu));
+ /*
+ * cpu_core_ map will be zeroed when the per
+ * cpu area is allocated.
+ *
+ * cpus_clear(per_cpu(cpu_core_map, cpu));
+ */
}
smp_store_cpu_info(0);
@@ -346,6 +356,7 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
*/
irq_enter();
(*func)(info);
+ __get_cpu_var(irq_stat).irq_call_count++;
irq_exit();
if (wait) {
@@ -360,7 +371,8 @@ int xen_smp_call_function_mask(cpumask_t mask, void (*func)(void *),
void *info, int wait)
{
struct call_data_struct data;
- int cpus;
+ int cpus, cpu;
+ bool yield;
/* Holding any lock stops cpus from going down. */
spin_lock(&call_lock);
@@ -389,9 +401,14 @@ int xen_smp_call_function_mask(cpumask_t mask, void (*func)(void *),
/* Send a message to other CPUs and wait for them to respond */
xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
- /* Make sure other vcpus get a chance to run.
- XXX too severe? Maybe we should check the other CPU's states? */
- HYPERVISOR_sched_op(SCHEDOP_yield, 0);
+ /* Make sure other vcpus get a chance to run if they need to. */
+ yield = false;
+ for_each_cpu_mask(cpu, mask)
+ if (xen_vcpu_stolen(cpu))
+ yield = true;
+
+ if (yield)
+ HYPERVISOR_sched_op(SCHEDOP_yield, 0);
/* Wait for response */
while (atomic_read(&data.started) != cpus ||
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index dfd6db69ead..d083ff5ef08 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -105,6 +105,12 @@ static void get_runstate_snapshot(struct vcpu_runstate_info *res)
} while (get64(&state->state_entry_time) != state_time);
}
+/* return true when a vcpu could run but has no real cpu to run on */
+bool xen_vcpu_stolen(int vcpu)
+{
+ return per_cpu(runstate, vcpu).state == RUNSTATE_runnable;
+}
+
static void setup_runstate_info(int cpu)
{
struct vcpu_register_runstate_memory_area area;
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index b9aaea45f07..b02a909bfd4 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -11,6 +11,7 @@ void xen_copy_trap_info(struct trap_info *traps);
DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
DECLARE_PER_CPU(unsigned long, xen_cr3);
+DECLARE_PER_CPU(unsigned long, xen_current_cr3);
extern struct start_info *xen_start_info;
extern struct shared_info *HYPERVISOR_shared_info;
@@ -27,14 +28,9 @@ unsigned long xen_get_wallclock(void);
int xen_set_wallclock(unsigned long time);
unsigned long long xen_sched_clock(void);
-void xen_mark_init_mm_pinned(void);
-
-DECLARE_PER_CPU(enum paravirt_lazy_mode, xen_lazy_mode);
+bool xen_vcpu_stolen(int vcpu);
-static inline unsigned xen_get_lazy_mode(void)
-{
- return x86_read_percpu(xen_lazy_mode);
-}
+void xen_mark_init_mm_pinned(void);
void __init xen_fill_possible_map(void);
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index cf013cb85ea..78cb68f2ebb 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -175,14 +175,12 @@ config MK8
config MPSC
bool "Intel P4 / older Netburst based Xeon"
help
- Optimize for Intel Pentium 4 and older Nocona/Dempsey Xeon CPUs
- with Intel Extended Memory 64 Technology(EM64T). For details see
- <http://www.intel.com/technology/64bitextensions/>.
+ Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
+ Xeon CPUs with Intel 64bit which is compatible with x86-64.
Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
Netburst core and shouldn't use this option. You can distinguish them
using the cpu family field
- in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one
- (this rule only applies to systems that support EM64T)
+ in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
config MCORE2
bool "Intel Core2 / newer Xeon"
@@ -190,8 +188,7 @@ config MCORE2
Optimize for Intel Core2 and newer Xeons (51xx)
You can distinguish the newer Xeons from the older ones using
the cpu family field in /proc/cpuinfo. 15 is an older Xeon
- (use CONFIG_MPSC then), 6 is a newer one. This rule only
- applies to CPUs that support EM64T.
+ (use CONFIG_MPSC then), 6 is a newer one.
config GENERIC_CPU
bool "Generic-x86-64"
@@ -409,6 +406,7 @@ config ARCH_DISCONTIGMEM_DEFAULT
config ARCH_SPARSEMEM_ENABLE
def_bool y
depends on (NUMA || EXPERIMENTAL)
+ select SPARSEMEM_VMEMMAP_ENABLE
config ARCH_MEMORY_PROBE
def_bool y
@@ -475,8 +473,9 @@ config HPET_TIMER
<http://www.intel.com/hardwaredesign/hpetspec.htm>.
config HPET_EMULATE_RTC
- bool "Provide RTC interrupt"
+ bool
depends on HPET_TIMER && RTC=y
+ default y
# Mark as embedded because too many people got it wrong.
# The code disables itself when not needed.
@@ -581,17 +580,18 @@ config CRASH_DUMP
bool "kernel crash dumps (EXPERIMENTAL)"
depends on EXPERIMENTAL
help
- Generate crash dump after being started by kexec.
- This should be normally only set in special crash dump kernels
- which are loaded in the main kernel with kexec-tools into
- a specially reserved region and then later executed after
- a crash by kdump/kexec. The crash dump kernel must be compiled
+ Generate crash dump after being started by kexec.
+ This should be normally only set in special crash dump kernels
+ which are loaded in the main kernel with kexec-tools into
+ a specially reserved region and then later executed after
+ a crash by kdump/kexec. The crash dump kernel must be compiled
to a memory address not used by the main kernel or BIOS using
- PHYSICAL_START.
- For more details see Documentation/kdump/kdump.txt
+ PHYSICAL_START, or it must be built as a relocatable image
+ (CONFIG_RELOCATABLE=y).
+ For more details see Documentation/kdump/kdump.txt
config RELOCATABLE
- bool "Build a relocatable kernel(EXPERIMENTAL)"
+ bool "Build a relocatable kernel (EXPERIMENTAL)"
depends on EXPERIMENTAL
help
Builds a relocatable kernel. This enables loading and running
@@ -602,8 +602,8 @@ config RELOCATABLE
must live at a different physical address than the primary
kernel.
- Note: If CONFIG_RELOCATABLE=y, then kernel run from the address
- it has been loaded at and compile time physical address
+ Note: If CONFIG_RELOCATABLE=y, then the kernel runs from the address
+ it has been loaded at and the compile time physical address
(CONFIG_PHYSICAL_START) is ignored.
config PHYSICAL_START
@@ -716,6 +716,11 @@ menu "Power management options"
source kernel/power/Kconfig
+config ARCH_HIBERNATION_HEADER
+ bool
+ depends on HIBERNATION
+ default y
+
source "drivers/acpi/Kconfig"
source "arch/x86/kernel/cpufreq/Kconfig"
@@ -795,7 +800,6 @@ source "drivers/firmware/Kconfig"
source fs/Kconfig
menu "Instrumentation Support"
- depends on EXPERIMENTAL
source "arch/x86/oprofile/Kconfig"
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 8bffb94c71b..03e1ede27b8 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -61,18 +61,18 @@ cflags-y += -maccumulate-outgoing-args
# do binutils support CFI?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
+KBUILD_AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector )
cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector-all )
-CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
CFLAGS_KERNEL += $(cflags-kernel-y)
-AFLAGS += -m64
+KBUILD_AFLAGS += -m64
head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
@@ -110,9 +110,15 @@ bzdisk: vmlinux
fdimage fdimage144 fdimage288 isoimage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
-install:
+install: vdso_install
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
+vdso_install:
+ifeq ($(CONFIG_IA32_EMULATION),y)
+ $(Q)$(MAKE) $(build)=arch/x86/ia32 $@
+endif
+ $(Q)$(MAKE) $(build)=arch/x86/vdso $@
+
archclean:
$(Q)rm -rf $(objtree)/arch/x86_64/boot
$(Q)$(MAKE) $(clean)=$(boot)
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index acf05be2492..56685a88334 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -28,11 +28,9 @@ PLATFORM = $(platform-y)
export PLATFORM
# temporarily until string.h is fixed
-cflags-y += -ffreestanding
+KBUILD_CFLAGS += -ffreestanding
-cflags-y += -pipe -mlongcalls
-
-CFLAGS += $(cflags-y)
+KBUILD_CFLAGS += -pipe -mlongcalls
KBUILD_DEFCONFIG := iss_defconfig
@@ -56,7 +54,7 @@ endif
#
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
head-y := arch/xtensa/kernel/head.o
core-y += arch/xtensa/kernel/ arch/xtensa/mm/
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 820b31d10ae..9c5185f605b 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -8,13 +8,12 @@
#
-CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include
+EXTRA_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include
HOSTFLAGS += -Iarch/$(ARCH)/boot/include
BIG_ENDIAN := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
-export CFLAGS
-export AFLAGS
+export EXTRA_CFLAGS
export BIG_ENDIAN
subdir-y := lib
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
index f53262c2e1f..74d15d08077 100644
--- a/arch/xtensa/boot/boot-redboot/Makefile
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -19,7 +19,7 @@ boot-y := bootstrap.o
OBJS := $(addprefix $(obj)/,$(boot-y))
LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
-LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
zImage: vmlinux $(OBJS) $(LIBS)
$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 06a13d9b69d..5533c7850d5 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -304,10 +304,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
break;
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
default:
ret = ptrace_request(child, request, addr, data);
goto out;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 45d28f217c0..2f842859948 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -152,7 +152,7 @@ out_of_memory:
}
printk("VM: killing process %s\n", current->comm);
if (user_mode(regs))
- do_exit(SIGKILL);
+ do_group_exit(SIGKILL);
bad_page_fault(regs, address, SIGKILL);
return;
diff --git a/block/blktrace.c b/block/blktrace.c
index 775471ef84a..d00ac3993c1 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -550,7 +550,7 @@ static void blk_trace_set_ht_offsets(void)
for_each_online_cpu(cpu) {
unsigned long long *cpu_off, *sibling_off;
- for_each_cpu_mask(i, cpu_sibling_map[cpu]) {
+ for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) {
if (i == cpu)
continue;
diff --git a/block/bsg.c b/block/bsg.c
index b8ddfc66f21..8e181ab3afb 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -908,7 +908,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
}
-static struct file_operations bsg_fops = {
+static const struct file_operations bsg_fops = {
.read = bsg_read,
.write = bsg_write,
.poll = bsg_poll,
diff --git a/block/elevator.c b/block/elevator.c
index b9c518afe1f..952aee04a68 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -712,6 +712,14 @@ struct request *elv_next_request(struct request_queue *q)
int ret;
while ((rq = __elv_next_request(q)) != NULL) {
+ /*
+ * Kill the empty barrier place holder, the driver must
+ * not ever see it.
+ */
+ if (blk_empty_barrier(rq)) {
+ end_queued_request(rq, 1);
+ continue;
+ }
if (!(rq->cmd_flags & REQ_STARTED)) {
/*
* This is the first time the device driver
@@ -751,15 +759,8 @@ struct request *elv_next_request(struct request_queue *q)
rq = NULL;
break;
} else if (ret == BLKPREP_KILL) {
- int nr_bytes = rq->hard_nr_sectors << 9;
-
- if (!nr_bytes)
- nr_bytes = rq->data_len;
-
- blkdev_dequeue_request(rq);
rq->cmd_flags |= REQ_QUIET;
- end_that_request_chunk(rq, 0, nr_bytes);
- end_that_request_last(rq, 0);
+ end_queued_request(rq, 0);
} else {
printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
ret);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index d875673e76c..3935469e366 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -30,6 +30,7 @@
#include <linux/cpu.h>
#include <linux/blktrace_api.h>
#include <linux/fault-inject.h>
+#include <linux/scatterlist.h>
/*
* for max sense size
@@ -304,23 +305,6 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered,
EXPORT_SYMBOL(blk_queue_ordered);
-/**
- * blk_queue_issue_flush_fn - set function for issuing a flush
- * @q: the request queue
- * @iff: the function to be called issuing the flush
- *
- * Description:
- * If a driver supports issuing a flush command, the support is notified
- * to the block layer by defining it through this call.
- *
- **/
-void blk_queue_issue_flush_fn(struct request_queue *q, issue_flush_fn *iff)
-{
- q->issue_flush_fn = iff;
-}
-
-EXPORT_SYMBOL(blk_queue_issue_flush_fn);
-
/*
* Cache flushing for ordered writes handling
*/
@@ -377,10 +361,12 @@ void blk_ordered_complete_seq(struct request_queue *q, unsigned seq, int error)
/*
* Okay, sequence complete.
*/
- rq = q->orig_bar_rq;
- uptodate = q->orderr ? q->orderr : 1;
+ uptodate = 1;
+ if (q->orderr)
+ uptodate = q->orderr;
q->ordseq = 0;
+ rq = q->orig_bar_rq;
end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
end_that_request_last(rq, uptodate);
@@ -445,7 +431,8 @@ static inline struct request *start_ordered(struct request_queue *q,
rq_init(q, rq);
if (bio_data_dir(q->orig_bar_rq->bio) == WRITE)
rq->cmd_flags |= REQ_RW;
- rq->cmd_flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0;
+ if (q->ordered & QUEUE_ORDERED_FUA)
+ rq->cmd_flags |= REQ_FUA;
rq->elevator_private = NULL;
rq->elevator_private2 = NULL;
init_request_from_bio(rq, q->orig_bar_rq->bio);
@@ -455,9 +442,12 @@ static inline struct request *start_ordered(struct request_queue *q,
* Queue ordered sequence. As we stack them at the head, we
* need to queue in reverse order. Note that we rely on that
* no fs request uses ELEVATOR_INSERT_FRONT and thus no fs
- * request gets inbetween ordered sequence.
+ * request gets inbetween ordered sequence. If this request is
+ * an empty barrier, we don't need to do a postflush ever since
+ * there will be no data written between the pre and post flush.
+ * Hence a single flush will suffice.
*/
- if (q->ordered & QUEUE_ORDERED_POSTFLUSH)
+ if ((q->ordered & QUEUE_ORDERED_POSTFLUSH) && !blk_empty_barrier(rq))
queue_flush(q, QUEUE_ORDERED_POSTFLUSH);
else
q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH;
@@ -481,7 +471,7 @@ static inline struct request *start_ordered(struct request_queue *q,
int blk_do_ordered(struct request_queue *q, struct request **rqp)
{
struct request *rq = *rqp;
- int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
+ const int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
if (!q->ordseq) {
if (!is_barrier)
@@ -1329,10 +1319,11 @@ static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio,
* must make sure sg can hold rq->nr_phys_segments entries
*/
int blk_rq_map_sg(struct request_queue *q, struct request *rq,
- struct scatterlist *sg)
+ struct scatterlist *sglist)
{
struct bio_vec *bvec, *bvprv;
struct req_iterator iter;
+ struct scatterlist *sg;
int nsegs, cluster;
nsegs = 0;
@@ -1342,11 +1333,12 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
* for each bio in rq
*/
bvprv = NULL;
+ sg = NULL;
rq_for_each_segment(bvec, rq, iter) {
int nbytes = bvec->bv_len;
if (bvprv && cluster) {
- if (sg[nsegs - 1].length + nbytes > q->max_segment_size)
+ if (sg->length + nbytes > q->max_segment_size)
goto new_segment;
if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
@@ -1354,14 +1346,18 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
goto new_segment;
- sg[nsegs - 1].length += nbytes;
+ sg->length += nbytes;
} else {
new_segment:
- memset(&sg[nsegs],0,sizeof(struct scatterlist));
- sg[nsegs].page = bvec->bv_page;
- sg[nsegs].length = nbytes;
- sg[nsegs].offset = bvec->bv_offset;
-
+ if (!sg)
+ sg = sglist;
+ else
+ sg = sg_next(sg);
+
+ memset(sg, 0, sizeof(*sg));
+ sg->page = bvec->bv_page;
+ sg->length = nbytes;
+ sg->offset = bvec->bv_offset;
nsegs++;
}
bvprv = bvec;
@@ -1793,6 +1789,7 @@ static void blk_release_queue(struct kobject *kobj)
blk_trace_shutdown(q);
+ bdi_destroy(&q->backing_dev_info);
kmem_cache_free(requestq_cachep, q);
}
@@ -1846,21 +1843,27 @@ static struct kobj_type queue_ktype;
struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
{
struct request_queue *q;
+ int err;
q = kmem_cache_alloc_node(requestq_cachep,
gfp_mask | __GFP_ZERO, node_id);
if (!q)
return NULL;
+ q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug;
+ q->backing_dev_info.unplug_io_data = q;
+ err = bdi_init(&q->backing_dev_info);
+ if (err) {
+ kmem_cache_free(requestq_cachep, q);
+ return NULL;
+ }
+
init_timer(&q->unplug_timer);
kobject_set_name(&q->kobj, "%s", "queue");
q->kobj.ktype = &queue_ktype;
kobject_init(&q->kobj);
- q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug;
- q->backing_dev_info.unplug_io_data = q;
-
mutex_init(&q->sysfs_lock);
return q;
@@ -2660,6 +2663,14 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
EXPORT_SYMBOL(blk_execute_rq);
+static void bio_end_empty_barrier(struct bio *bio, int err)
+{
+ if (err)
+ clear_bit(BIO_UPTODATE, &bio->bi_flags);
+
+ complete(bio->bi_private);
+}
+
/**
* blkdev_issue_flush - queue a flush
* @bdev: blockdev to issue flush for
@@ -2672,7 +2683,10 @@ EXPORT_SYMBOL(blk_execute_rq);
*/
int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
{
+ DECLARE_COMPLETION_ONSTACK(wait);
struct request_queue *q;
+ struct bio *bio;
+ int ret;
if (bdev->bd_disk == NULL)
return -ENXIO;
@@ -2680,10 +2694,32 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
q = bdev_get_queue(bdev);
if (!q)
return -ENXIO;
- if (!q->issue_flush_fn)
- return -EOPNOTSUPP;
- return q->issue_flush_fn(q, bdev->bd_disk, error_sector);
+ bio = bio_alloc(GFP_KERNEL, 0);
+ if (!bio)
+ return -ENOMEM;
+
+ bio->bi_end_io = bio_end_empty_barrier;
+ bio->bi_private = &wait;
+ bio->bi_bdev = bdev;
+ submit_bio(1 << BIO_RW_BARRIER, bio);
+
+ wait_for_completion(&wait);
+
+ /*
+ * The driver must store the error location in ->bi_sector, if
+ * it supports it. For non-stacked drivers, this should be copied
+ * from rq->sector.
+ */
+ if (error_sector)
+ *error_sector = bio->bi_sector;
+
+ ret = 0;
+ if (!bio_flagged(bio, BIO_UPTODATE))
+ ret = -EIO;
+
+ bio_put(bio);
+ return ret;
}
EXPORT_SYMBOL(blkdev_issue_flush);
@@ -3051,7 +3087,7 @@ static inline void blk_partition_remap(struct bio *bio)
{
struct block_device *bdev = bio->bi_bdev;
- if (bdev != bdev->bd_contains) {
+ if (bio_sectors(bio) && bdev != bdev->bd_contains) {
struct hd_struct *p = bdev->bd_part;
const int rw = bio_data_dir(bio);
@@ -3117,6 +3153,35 @@ static inline int should_fail_request(struct bio *bio)
#endif /* CONFIG_FAIL_MAKE_REQUEST */
+/*
+ * Check whether this bio extends beyond the end of the device.
+ */
+static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
+{
+ sector_t maxsector;
+
+ if (!nr_sectors)
+ return 0;
+
+ /* Test device or partition size, when known. */
+ maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
+ if (maxsector) {
+ sector_t sector = bio->bi_sector;
+
+ if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
+ /*
+ * This may well happen - the kernel calls bread()
+ * without checking the size of the device, e.g., when
+ * mounting a device.
+ */
+ handle_bad_sector(bio);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/**
* generic_make_request: hand a buffer to its device driver for I/O
* @bio: The bio describing the location in memory and on the device.
@@ -3144,27 +3209,14 @@ static inline int should_fail_request(struct bio *bio)
static inline void __generic_make_request(struct bio *bio)
{
struct request_queue *q;
- sector_t maxsector;
sector_t old_sector;
int ret, nr_sectors = bio_sectors(bio);
dev_t old_dev;
might_sleep();
- /* Test device or partition size, when known. */
- maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
- if (maxsector) {
- sector_t sector = bio->bi_sector;
- if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
- /*
- * This may well happen - the kernel calls bread()
- * without checking the size of the device, e.g., when
- * mounting a device.
- */
- handle_bad_sector(bio);
- goto end_io;
- }
- }
+ if (bio_check_eod(bio, nr_sectors))
+ goto end_io;
/*
* Resolve the mapping until finished. (drivers are
@@ -3191,7 +3243,7 @@ end_io:
break;
}
- if (unlikely(bio_sectors(bio) > q->max_hw_sectors)) {
+ if (unlikely(nr_sectors > q->max_hw_sectors)) {
printk("bio too big device %s (%u > %u)\n",
bdevname(bio->bi_bdev, b),
bio_sectors(bio),
@@ -3212,7 +3264,7 @@ end_io:
blk_partition_remap(bio);
if (old_sector != -1)
- blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
+ blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
old_sector);
blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
@@ -3220,21 +3272,8 @@ end_io:
old_sector = bio->bi_sector;
old_dev = bio->bi_bdev->bd_dev;
- maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
- if (maxsector) {
- sector_t sector = bio->bi_sector;
-
- if (maxsector < nr_sectors ||
- maxsector - nr_sectors < sector) {
- /*
- * This may well happen - partitions are not
- * checked to make sure they are within the size
- * of the whole device.
- */
- handle_bad_sector(bio);
- goto end_io;
- }
- }
+ if (bio_check_eod(bio, nr_sectors))
+ goto end_io;
ret = q->make_request_fn(q, bio);
} while (ret);
@@ -3307,23 +3346,32 @@ void submit_bio(int rw, struct bio *bio)
{
int count = bio_sectors(bio);
- BIO_BUG_ON(!bio->bi_size);
- BIO_BUG_ON(!bio->bi_io_vec);
bio->bi_rw |= rw;
- if (rw & WRITE) {
- count_vm_events(PGPGOUT, count);
- } else {
- task_io_account_read(bio->bi_size);
- count_vm_events(PGPGIN, count);
- }
- if (unlikely(block_dump)) {
- char b[BDEVNAME_SIZE];
- printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
- current->comm, current->pid,
- (rw & WRITE) ? "WRITE" : "READ",
- (unsigned long long)bio->bi_sector,
- bdevname(bio->bi_bdev,b));
+ /*
+ * If it's a regular read/write or a barrier with data attached,
+ * go through the normal accounting stuff before submission.
+ */
+ if (!bio_empty_barrier(bio)) {
+
+ BIO_BUG_ON(!bio->bi_size);
+ BIO_BUG_ON(!bio->bi_io_vec);
+
+ if (rw & WRITE) {
+ count_vm_events(PGPGOUT, count);
+ } else {
+ task_io_account_read(bio->bi_size);
+ count_vm_events(PGPGIN, count);
+ }
+
+ if (unlikely(block_dump)) {
+ char b[BDEVNAME_SIZE];
+ printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
+ current->comm, current->pid,
+ (rw & WRITE) ? "WRITE" : "READ",
+ (unsigned long long)bio->bi_sector,
+ bdevname(bio->bi_bdev,b));
+ }
}
generic_make_request(bio);
@@ -3399,6 +3447,14 @@ static int __end_that_request_first(struct request *req, int uptodate,
while ((bio = req->bio) != NULL) {
int nbytes;
+ /*
+ * For an empty barrier request, the low level driver must
+ * store a potential error location in ->sector. We pass
+ * that back up in ->bi_sector.
+ */
+ if (blk_empty_barrier(req))
+ bio->bi_sector = req->sector;
+
if (nr_bytes >= bio->bi_size) {
req->bio = bio->bi_next;
nbytes = bio->bi_size;
@@ -3564,7 +3620,7 @@ static struct notifier_block blk_cpu_notifier __cpuinitdata = {
* Description:
* Ends all I/O on a request. It does not handle partial completions,
* unless the driver actually implements this in its completion callback
- * through requeueing. Theh actual completion happens out-of-order,
+ * through requeueing. The actual completion happens out-of-order,
* through a softirq handler. The user must have registered a completion
* callback through blk_queue_softirq_done().
**/
@@ -3627,15 +3683,83 @@ void end_that_request_last(struct request *req, int uptodate)
EXPORT_SYMBOL(end_that_request_last);
-void end_request(struct request *req, int uptodate)
+static inline void __end_request(struct request *rq, int uptodate,
+ unsigned int nr_bytes, int dequeue)
{
- if (!end_that_request_first(req, uptodate, req->hard_cur_sectors)) {
- add_disk_randomness(req->rq_disk);
- blkdev_dequeue_request(req);
- end_that_request_last(req, uptodate);
+ if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
+ if (dequeue)
+ blkdev_dequeue_request(rq);
+ add_disk_randomness(rq->rq_disk);
+ end_that_request_last(rq, uptodate);
}
}
+static unsigned int rq_byte_size(struct request *rq)
+{
+ if (blk_fs_request(rq))
+ return rq->hard_nr_sectors << 9;
+
+ return rq->data_len;
+}
+
+/**
+ * end_queued_request - end all I/O on a queued request
+ * @rq: the request being processed
+ * @uptodate: error value or 0/1 uptodate flag
+ *
+ * Description:
+ * Ends all I/O on a request, and removes it from the block layer queues.
+ * Not suitable for normal IO completion, unless the driver still has
+ * the request attached to the block layer.
+ *
+ **/
+void end_queued_request(struct request *rq, int uptodate)
+{
+ __end_request(rq, uptodate, rq_byte_size(rq), 1);
+}
+EXPORT_SYMBOL(end_queued_request);
+
+/**
+ * end_dequeued_request - end all I/O on a dequeued request
+ * @rq: the request being processed
+ * @uptodate: error value or 0/1 uptodate flag
+ *
+ * Description:
+ * Ends all I/O on a request. The request must already have been
+ * dequeued using blkdev_dequeue_request(), as is normally the case
+ * for most drivers.
+ *
+ **/
+void end_dequeued_request(struct request *rq, int uptodate)
+{
+ __end_request(rq, uptodate, rq_byte_size(rq), 0);
+}
+EXPORT_SYMBOL(end_dequeued_request);
+
+
+/**
+ * end_request - end I/O on the current segment of the request
+ * @rq: the request being processed
+ * @uptodate: error value or 0/1 uptodate flag
+ *
+ * Description:
+ * Ends I/O on the current segment of a request. If that is the only
+ * remaining segment, the request is also completed and freed.
+ *
+ * This is a remnant of how older block drivers handled IO completions.
+ * Modern drivers typically end IO on the full request in one go, unless
+ * they have a residual value to account for. For that case this function
+ * isn't really useful, unless the residual just happens to be the
+ * full current segment. In other words, don't use this function in new
+ * code. Either use end_request_completely(), or the
+ * end_that_request_chunk() (along with end_that_request_last()) for
+ * partial completions.
+ *
+ **/
+void end_request(struct request *req, int uptodate)
+{
+ __end_request(req, uptodate, req->hard_cur_sectors << 9, 1);
+}
EXPORT_SYMBOL(end_request);
static void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
@@ -3928,7 +4052,6 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
max_hw_sectors_kb = q->max_hw_sectors >> 1,
page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
- int ra_kb;
if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
return -EINVAL;
@@ -3937,14 +4060,6 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
* values synchronously:
*/
spin_lock_irq(q->queue_lock);
- /*
- * Trim readahead window as well, if necessary:
- */
- ra_kb = q->backing_dev_info.ra_pages << (PAGE_CACHE_SHIFT - 10);
- if (ra_kb > max_sectors_kb)
- q->backing_dev_info.ra_pages =
- max_sectors_kb >> (PAGE_CACHE_SHIFT - 10);
-
q->max_sectors = max_sectors_kb << 1;
spin_unlock_irq(q->queue_lock);
@@ -3958,7 +4073,23 @@ static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page)
return queue_var_show(max_hw_sectors_kb, (page));
}
+static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
+{
+ return queue_var_show(q->max_phys_segments, page);
+}
+
+static ssize_t queue_max_segments_store(struct request_queue *q,
+ const char *page, size_t count)
+{
+ unsigned long segments;
+ ssize_t ret = queue_var_store(&segments, page, count);
+
+ spin_lock_irq(q->queue_lock);
+ q->max_phys_segments = segments;
+ spin_unlock_irq(q->queue_lock);
+ return ret;
+}
static struct queue_sysfs_entry queue_requests_entry = {
.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
.show = queue_requests_show,
@@ -3982,6 +4113,12 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
.show = queue_max_hw_sectors_show,
};
+static struct queue_sysfs_entry queue_max_segments_entry = {
+ .attr = {.name = "max_segments", .mode = S_IRUGO | S_IWUSR },
+ .show = queue_max_segments_show,
+ .store = queue_max_segments_store,
+};
+
static struct queue_sysfs_entry queue_iosched_entry = {
.attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
.show = elv_iosched_show,
@@ -3993,6 +4130,7 @@ static struct attribute *default_attrs[] = {
&queue_ra_entry.attr,
&queue_max_hw_sectors_entry.attr,
&queue_max_sectors_entry.attr,
+ &queue_max_segments_entry.attr,
&queue_iosched_entry.attr,
NULL,
};
diff --git a/crypto/digest.c b/crypto/digest.c
index 1bf7414aeb9..e56de6748b1 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -77,7 +77,7 @@ static int update2(struct hash_desc *desc,
if (!nbytes)
break;
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}
return 0;
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 3052f6507f5..d6852c33cfb 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -62,7 +62,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
walk->offset += PAGE_SIZE - 1;
walk->offset &= PAGE_MASK;
if (walk->offset >= walk->sg->offset + walk->sg->length)
- scatterwalk_start(walk, sg_next(walk->sg));
+ scatterwalk_start(walk, scatterwalk_sg_next(walk->sg));
}
}
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 500a220ad90..9c73e37a42c 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -20,7 +20,7 @@
#include "internal.h"
-static inline struct scatterlist *sg_next(struct scatterlist *sg)
+static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
{
return (++sg)->length ? sg : (void *)sg->page;
}
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7bdae47d6b9..34f40ea0ba6 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -58,6 +58,8 @@ source "drivers/power/Kconfig"
source "drivers/hwmon/Kconfig"
+source "drivers/watchdog/Kconfig"
+
source "drivers/ssb/Kconfig"
source "drivers/mfd/Kconfig"
@@ -84,6 +86,8 @@ source "drivers/rtc/Kconfig"
source "drivers/dma/Kconfig"
+source "drivers/dca/Kconfig"
+
source "drivers/auxdisplay/Kconfig"
source "drivers/kvm/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index a168eacdcd9..d2dc01cc73e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -66,7 +66,7 @@ obj-y += i2c/
obj-$(CONFIG_W1) += w1/
obj-$(CONFIG_POWER_SUPPLY) += power/
obj-$(CONFIG_HWMON) += hwmon/
-obj-$(CONFIG_WATCHDOG) += char/watchdog/
+obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/
obj-$(CONFIG_BT) += bluetooth/
@@ -85,6 +85,7 @@ obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
obj-$(CONFIG_GENERIC_TIME) += clocksource/
obj-$(CONFIG_DMA_ENGINE) += dma/
+obj-$(CONFIG_DCA) += dca/
obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/
diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c
index 9e18ce742e3..28a5fbc6aa1 100644
--- a/drivers/acorn/char/defkeymap-l7200.c
+++ b/drivers/acorn/char/defkeymap-l7200.c
@@ -346,7 +346,7 @@ char *func_table[MAX_NR_FUNC] = {
0,
};
-struct kbdiacr accent_table[MAX_DIACR] = {
+struct kbdiacruc accent_table[MAX_DIACR] = {
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 5055acf2163..048295ec370 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -50,7 +50,7 @@ int acpi_sleep_prepare(u32 acpi_state)
}
#ifdef CONFIG_SUSPEND
-static struct pm_ops acpi_pm_ops;
+static struct platform_suspend_ops acpi_pm_ops;
extern void do_suspend_lowlevel(void);
@@ -85,13 +85,12 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
/**
* acpi_pm_prepare - Do preliminary suspend work.
- * @pm_state: ignored
*
* If necessary, set the firmware waking vector and do arch-specific
* nastiness to get the wakeup code to the waking vector.
*/
-static int acpi_pm_prepare(suspend_state_t pm_state)
+static int acpi_pm_prepare(void)
{
int error = acpi_sleep_prepare(acpi_target_sleep_state);
@@ -160,13 +159,12 @@ static int acpi_pm_enter(suspend_state_t pm_state)
/**
* acpi_pm_finish - Finish up suspend sequence.
- * @pm_state: ignored
*
* This is called after we wake back up (or if entering the sleep state
* failed).
*/
-static int acpi_pm_finish(suspend_state_t pm_state)
+static void acpi_pm_finish(void)
{
u32 acpi_state = acpi_target_sleep_state;
@@ -184,7 +182,6 @@ static int acpi_pm_finish(suspend_state_t pm_state)
init_8259A(0);
}
#endif
- return 0;
}
static int acpi_pm_state_valid(suspend_state_t pm_state)
@@ -203,7 +200,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
}
}
-static struct pm_ops acpi_pm_ops = {
+static struct platform_suspend_ops acpi_pm_ops = {
.valid = acpi_pm_state_valid,
.set_target = acpi_pm_set_target,
.prepare = acpi_pm_prepare,
@@ -233,6 +230,12 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
#endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION
+static int acpi_hibernation_start(void)
+{
+ acpi_target_sleep_state = ACPI_STATE_S4;
+ return 0;
+}
+
static int acpi_hibernation_prepare(void)
{
return acpi_sleep_prepare(ACPI_STATE_S4);
@@ -254,6 +257,15 @@ static int acpi_hibernation_enter(void)
return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
+static void acpi_hibernation_leave(void)
+{
+ /*
+ * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+ * enable it here.
+ */
+ acpi_enable();
+}
+
static void acpi_hibernation_finish(void)
{
acpi_leave_sleep_state(ACPI_STATE_S4);
@@ -261,6 +273,8 @@ static void acpi_hibernation_finish(void)
/* reset firmware waking vector */
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+
+ acpi_target_sleep_state = ACPI_STATE_S0;
}
static int acpi_hibernation_pre_restore(void)
@@ -277,10 +291,13 @@ static void acpi_hibernation_restore_cleanup(void)
acpi_hw_enable_all_runtime_gpes();
}
-static struct hibernation_ops acpi_hibernation_ops = {
+static struct platform_hibernation_ops acpi_hibernation_ops = {
+ .start = acpi_hibernation_start,
+ .pre_snapshot = acpi_hibernation_prepare,
+ .finish = acpi_hibernation_finish,
.prepare = acpi_hibernation_prepare,
.enter = acpi_hibernation_enter,
- .finish = acpi_hibernation_finish,
+ .leave = acpi_hibernation_leave,
.pre_restore = acpi_hibernation_pre_restore,
.restore_cleanup = acpi_hibernation_restore_cleanup,
};
@@ -417,7 +434,7 @@ int __init acpi_sleep_init(void)
}
}
- pm_set_ops(&acpi_pm_ops);
+ suspend_set_ops(&acpi_pm_ops);
#endif
#ifdef CONFIG_HIBERNATION
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4672066167e..ba63619ae5d 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -182,6 +182,15 @@ config PATA_ACPI
firmware in the BIOS. This driver can sometimes handle
otherwise unsupported hardware.
+config SATA_FSL
+ tristate "Freescale 3.0Gbps SATA support"
+ depends on PPC_MPC837x
+ help
+ This option enables support for Freescale 3.0Gbps SATA controller.
+ It can be found on MPC837x and MPC8315.
+
+ If unsure, say N.
+
config PATA_ALI
tristate "ALi PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
@@ -272,6 +281,15 @@ config PATA_CS5535
If unsure, say N.
+config PATA_CS5536
+ tristate "CS5536 PATA support (Experimental)"
+ depends on PCI && X86 && !X86_64 && EXPERIMENTAL
+ help
+ This option enables support for the AMD CS5536
+ companion chip used with the Geode LX processor family.
+
+ If unsure, say N.
+
config PATA_CYPRESS
tristate "Cypress CY82C693 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
@@ -632,11 +650,4 @@ config PATA_BF54X
If unsure, say N.
-config PATA_BF54X_DMA
- bool "DMA mode"
- depends on PATA_BF54X
- default y
- help
- Enable DMA mode for Blackfin ATAPI controller.
-
endif # ATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 2a63645003e..b13feb2c5da 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_MV) += sata_mv.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
+obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_PATA_ALI) += pata_ali.o
obj-$(CONFIG_PATA_AMD) += pata_amd.o
@@ -28,6 +29,7 @@ obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o
obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
obj-$(CONFIG_PATA_CS5535) += pata_cs5535.o
+obj-$(CONFIG_PATA_CS5536) += pata_cs5536.o
obj-$(CONFIG_PATA_CYPRESS) += pata_cypress.o
obj-$(CONFIG_PATA_EFAR) += pata_efar.o
obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 9ce4aa9c2f2..3c6f43e381f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -130,6 +130,7 @@ enum {
ich8_sata_ahci = 9,
piix_pata_mwdma = 10, /* PIIX3 MWDMA only */
tolapai_sata_ahci = 11,
+ ich9_2port_sata = 12,
/* constants for mapping table */
P0 = 0, /* port 0 */
@@ -238,19 +239,19 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* SATA Controller 1 IDE (ICH8) */
{ 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
/* SATA Controller 2 IDE (ICH8) */
- { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich9_2port_sata },
/* Mobile SATA Controller IDE (ICH8M) */
{ 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
/* SATA Controller IDE (ICH9) */
{ 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
/* SATA Controller IDE (ICH9) */
- { 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich9_2port_sata },
/* SATA Controller IDE (ICH9) */
- { 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich9_2port_sata },
/* SATA Controller IDE (ICH9M) */
- { 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2928, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich9_2port_sata },
/* SATA Controller IDE (ICH9M) */
- { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich9_2port_sata },
/* SATA Controller IDE (ICH9M) */
{ 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
/* SATA Controller IDE (Tolapai) */
@@ -448,6 +449,18 @@ static const struct piix_map_db tolapai_map_db = {
},
};
+static const struct piix_map_db ich9_2port_map_db = {
+ .mask = 0x3,
+ .port_enable = 0x3,
+ .map = {
+ /* PM PS SM SS MAP */
+ { P0, NA, P1, NA }, /* 00b */
+ { RV, RV, RV, RV }, /* 01b */
+ { RV, RV, RV, RV }, /* 10b */
+ { RV, RV, RV, RV },
+ },
+};
+
static const struct piix_map_db *piix_map_db_table[] = {
[ich5_sata] = &ich5_map_db,
[ich6_sata] = &ich6_map_db,
@@ -455,6 +468,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
[ich6m_sata_ahci] = &ich6m_map_db,
[ich8_sata_ahci] = &ich8_map_db,
[tolapai_sata_ahci] = &tolapai_map_db,
+ [ich9_2port_sata] = &ich9_2port_map_db,
};
static struct ata_port_info piix_port_info[] = {
@@ -570,6 +584,17 @@ static struct ata_port_info piix_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
+
+ [ich9_2port_sata] =
+ {
+ .sht = &piix_sht,
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
+ PIIX_FLAG_AHCI,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &piix_sata_ops,
+ },
};
static struct pci_bits piix_enable_bits[] = {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b05384a8c32..bbaa545ea99 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1410,7 +1410,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
*/
unsigned ata_exec_internal_sg(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
- int dma_dir, struct scatterlist *sg,
+ int dma_dir, struct scatterlist *sgl,
unsigned int n_elem, unsigned long timeout)
{
struct ata_link *link = dev->link;
@@ -1472,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
qc->dma_dir = dma_dir;
if (dma_dir != DMA_NONE) {
unsigned int i, buflen = 0;
+ struct scatterlist *sg;
- for (i = 0; i < n_elem; i++)
- buflen += sg[i].length;
+ for_each_sg(sgl, sg, n_elem, i)
+ buflen += sg->length;
- ata_sg_init(qc, sg, n_elem);
+ ata_sg_init(qc, sgl, n_elem);
qc->nbytes = buflen;
}
@@ -3984,6 +3985,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "ST9120822AS", "3.CLF", ATA_HORKAGE_NONCQ, },
{ "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, },
{ "ST9160821AS", "3.ALD", ATA_HORKAGE_NONCQ, },
+ { "ST9160821AS", "3.CCD", ATA_HORKAGE_NONCQ, },
{ "ST3160812AS", "3.ADJ", ATA_HORKAGE_NONCQ, },
{ "ST980813AS", "3.ADB", ATA_HORKAGE_NONCQ, },
{ "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, },
@@ -4013,8 +4015,14 @@ int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
p = strchr(patt, wildchar);
if (p && ((*(p + 1)) == 0))
len = p - patt;
- else
+ else {
len = strlen(name);
+ if (!len) {
+ if (!*patt)
+ return 0;
+ return -1;
+ }
+ }
return strncmp(patt, name, len);
}
@@ -4285,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
if (qc->n_elem)
dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
/* restore last sg */
- sg[qc->orig_n_elem - 1].length += qc->pad_len;
+ 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);
@@ -4540,6 +4548,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
qc->orig_n_elem = 1;
qc->buf_virt = buf;
qc->nbytes = buflen;
+ qc->cursg = qc->__sg;
sg_init_one(&qc->sgent, buf, buflen);
}
@@ -4565,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
qc->__sg = sg;
qc->n_elem = n_elem;
qc->orig_n_elem = n_elem;
+ qc->cursg = qc->__sg;
}
/**
@@ -4654,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct scatterlist *sg = qc->__sg;
- struct scatterlist *lsg = &sg[qc->n_elem - 1];
+ struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
int n_elem, pre_n_elem, dir, trim_sg = 0;
VPRINTK("ENTER, ata%u\n", ap->print_id);
@@ -4818,7 +4828,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
static void ata_pio_sector(struct ata_queued_cmd *qc)
{
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
- struct scatterlist *sg = qc->__sg;
struct ata_port *ap = qc->ap;
struct page *page;
unsigned int offset;
@@ -4827,8 +4836,8 @@ 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 = sg[qc->cursg].page;
- offset = sg[qc->cursg].offset + qc->cursg_ofs;
+ page = qc->cursg->page;
+ offset = qc->cursg->offset + qc->cursg_ofs;
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4856,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
qc->curbytes += qc->sect_size;
qc->cursg_ofs += qc->sect_size;
- if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
- qc->cursg++;
+ if (qc->cursg_ofs == qc->cursg->length) {
+ qc->cursg = sg_next(qc->cursg);
qc->cursg_ofs = 0;
}
}
@@ -4943,16 +4952,18 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
struct scatterlist *sg = qc->__sg;
+ struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
struct ata_port *ap = qc->ap;
struct page *page;
unsigned char *buf;
unsigned int offset, count;
+ int no_more_sg = 0;
if (qc->curbytes + bytes >= qc->nbytes)
ap->hsm_task_state = HSM_ST_LAST;
next_sg:
- if (unlikely(qc->cursg >= qc->n_elem)) {
+ if (unlikely(no_more_sg)) {
/*
* The end of qc->sg is reached and the device expects
* more data to transfer. In order not to overrun qc->sg
@@ -4975,7 +4986,7 @@ next_sg:
return;
}
- sg = &qc->__sg[qc->cursg];
+ sg = qc->cursg;
page = sg->page;
offset = sg->offset + qc->cursg_ofs;
@@ -5014,7 +5025,10 @@ next_sg:
qc->cursg_ofs += count;
if (qc->cursg_ofs == sg->length) {
- qc->cursg++;
+ if (qc->cursg == lsg)
+ no_more_sg = 1;
+
+ qc->cursg = sg_next(qc->cursg);
qc->cursg_ofs = 0;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index ea53e6a570b..9fbb39cd0f5 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -801,8 +801,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
ata_scsi_sdev_config(sdev);
- blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
-
sdev->manage_start_stop = 1;
if (dev)
@@ -1363,6 +1361,7 @@ nothing_to_do:
static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct ata_eh_info *ehi = &qc->dev->link->eh_info;
struct scsi_cmnd *cmd = qc->scsicmd;
u8 *cdb = cmd->cmnd;
int need_sense = (qc->err_mask != 0);
@@ -1376,14 +1375,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
case ATA_CMD_SET_FEATURES:
if ((qc->tf.feature == SETFEATURES_WC_ON) ||
(qc->tf.feature == SETFEATURES_WC_OFF)) {
- ap->link.eh_info.action |= ATA_EH_REVALIDATE;
+ ehi->action |= ATA_EH_REVALIDATE;
ata_port_schedule_eh(ap);
}
break;
case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
case ATA_CMD_SET_MULTI: /* multi_count changed */
- ap->link.eh_info.action |= ATA_EH_REVALIDATE;
+ ehi->action |= ATA_EH_REVALIDATE;
ata_port_schedule_eh(ap);
break;
}
@@ -3239,7 +3238,7 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
/**
* ata_scsi_media_change_notify - send media change event
- * @atadev: Pointer to the disk device with media change event
+ * @dev: Pointer to the disk device with media change event
*
* Tell the block layer to send a media change notification
* event.
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 026439e05af..f9e4cd52794 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -156,7 +156,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- tf->command = ata_check_status(ap);
+ tf->command = ata_chk_status(ap);
tf->feature = ioread8(ioaddr->error_addr);
tf->nsect = ioread8(ioaddr->nsect_addr);
tf->lbal = ioread8(ioaddr->lbal_addr);
@@ -882,7 +882,7 @@ unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer
/* Filter out DMA modes if the device has been configured by
the BIOS as PIO only */
- if (adev->link->ap->ioaddr.bmdma_addr == 0)
+ if (adev->link->ap->ioaddr.bmdma_addr == NULL)
xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
return xfer_mask;
}
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 5d3920f6fd6..0f6f7bcc3de 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -370,8 +370,10 @@ static struct pci_driver pacpi_pci_driver = {
.id_table = pacpi_pci_tbl,
.probe = pacpi_init_one,
.remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
+#endif
};
static int __init pacpi_init(void)
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 747549e4563..b5e38426b81 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1092,14 +1092,15 @@ static unsigned int bfin_bus_softreset(struct ata_port *ap,
* Note: Original code is ata_std_softreset().
*/
-static int bfin_std_softreset(struct ata_port *ap, unsigned int *classes,
+static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
unsigned long deadline)
{
+ struct ata_port *ap = link->ap;
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0, err_mask;
u8 err;
- if (ata_port_offline(ap)) {
+ if (ata_link_offline(link)) {
classes[0] = ATA_DEV_NONE;
goto out;
}
@@ -1122,9 +1123,11 @@ static int bfin_std_softreset(struct ata_port *ap, unsigned int *classes,
}
/* determine by signature whether we have ATA or ATAPI devices */
- classes[0] = ata_dev_try_classify(ap, 0, &err);
+ classes[0] = ata_dev_try_classify(&ap->link.device[0],
+ devmask & (1 << 0), &err);
if (slave_possible && err != 0x81)
- classes[1] = ata_dev_try_classify(ap, 1, &err);
+ classes[1] = ata_dev_try_classify(&ap->link.device[1],
+ devmask & (1 << 1), &err);
out:
return 0;
@@ -1167,7 +1170,7 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap)
static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf,
unsigned int buflen, int write_data)
{
- struct ata_port *ap = adev->ap;
+ struct ata_port *ap = adev->link->ap;
unsigned int words = buflen >> 1;
unsigned short *buf16 = (u16 *) buf;
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
@@ -1206,7 +1209,10 @@ static void bfin_irq_clear(struct ata_port *ap)
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
pr_debug("in atapi irq clear\n");
- ATAPI_SET_INT_STATUS(base, 0x1FF);
+
+ ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
+ | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
+ | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
}
/**
@@ -1234,33 +1240,6 @@ static unsigned char bfin_irq_on(struct ata_port *ap)
}
/**
- * bfin_irq_ack - Acknowledge a device interrupt.
- * @ap: Port on which interrupts are enabled.
- *
- * Note: Original code is ata_irq_ack().
- */
-
-static unsigned char bfin_irq_ack(struct ata_port *ap, unsigned int chk_drq)
-{
- void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
- unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
- unsigned char status;
-
- pr_debug("in atapi irq ack\n");
- status = ata_busy_wait(ap, bits, 1000);
- if (status & bits)
- if (ata_msg_err(ap))
- dev_err(ap->dev, "abnormal status 0x%X\n", status);
-
- /* get controller status; clear intr, err bits */
- ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
- | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
- | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
-
- return bfin_bmdma_status(ap);
-}
-
-/**
* bfin_bmdma_freeze - Freeze DMA controller port
* @ap: port to freeze
*
@@ -1308,8 +1287,9 @@ void bfin_bmdma_thaw(struct ata_port *ap)
* Note: Original code is ata_std_postreset().
*/
-static void bfin_std_postreset(struct ata_port *ap, unsigned int *classes)
+static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
{
+ struct ata_port *ap = link->ap;
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
/* re-enable interrupts */
@@ -1395,7 +1375,6 @@ static struct scsi_host_template bfin_sht = {
};
static const struct ata_port_operations bfin_pata_ops = {
- .port_disable = ata_port_disable,
.set_piomode = bfin_set_piomode,
.set_dmamode = bfin_set_dmamode,
@@ -1423,7 +1402,6 @@ static const struct ata_port_operations bfin_pata_ops = {
.irq_handler = ata_interrupt,
.irq_clear = bfin_irq_clear,
.irq_on = bfin_irq_on,
- .irq_ack = bfin_irq_ack,
.port_start = bfin_port_start,
.port_stop = bfin_port_stop,
@@ -1437,11 +1415,7 @@ static struct ata_port_info bfin_port_info[] = {
| ATA_FLAG_NO_LEGACY,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0,
-#ifdef CONFIG_PATA_BF54X_DMA
- .udma_mask = ATA_UDMA5,
-#else
.udma_mask = 0,
-#endif
.port_ops = &bfin_pata_ops,
},
};
@@ -1607,9 +1581,25 @@ static struct platform_driver bfin_atapi_driver = {
},
};
+#define ATAPI_MODE_SIZE 10
+static char bfin_atapi_mode[ATAPI_MODE_SIZE];
+
static int __init bfin_atapi_init(void)
{
pr_info("register bfin atapi driver\n");
+
+ switch(bfin_atapi_mode[0]) {
+ case 'p':
+ case 'P':
+ break;
+ case 'm':
+ case 'M':
+ bfin_port_info[0].mwdma_mask = ATA_MWDMA2;
+ break;
+ default:
+ bfin_port_info[0].udma_mask = ATA_UDMA5;
+ };
+
return platform_driver_register(&bfin_atapi_driver);
}
@@ -1620,6 +1610,13 @@ static void __exit bfin_atapi_exit(void)
module_init(bfin_atapi_init);
module_exit(bfin_atapi_exit);
+/*
+ * ATAPI mode:
+ * pio/PIO
+ * udma/UDMA (default)
+ * mwdma/MWDMA
+ */
+module_param_string(bfin_atapi_mode, bfin_atapi_mode, ATAPI_MODE_SIZE, 0);
MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
MODULE_DESCRIPTION("PATA driver for blackfin 54x ATAPI controller");
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
new file mode 100644
index 00000000000..53070f6b1fc
--- /dev/null
+++ b/drivers/ata/pata_cs5536.c
@@ -0,0 +1,344 @@
+/*
+ * pata_cs5536.c - CS5536 PATA for new ATA layer
+ * (C) 2007 Martin K. Petersen <mkp@mkp.net>
+ *
+ * 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
+ *
+ * Documentation:
+ * Available from AMD web site.
+ *
+ * The IDE timing registers for the CS5536 live in the Geode Machine
+ * Specific Register file and not PCI config space. Most BIOSes
+ * virtualize the PCI registers so the chip looks like a standard IDE
+ * controller. Unfortunately not all implementations get this right.
+ * In particular some have problems with unaligned accesses to the
+ * virtualized PCI registers. This driver always does full dword
+ * writes to work around the issue. Also, in case of a bad BIOS this
+ * driver can be loaded with the "msr=1" parameter which forces using
+ * the Machine Specific Registers to configure the device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/libata.h>
+#include <scsi/scsi_host.h>
+#include <asm/msr.h>
+
+#define DRV_NAME "pata_cs5536"
+#define DRV_VERSION "0.0.5"
+
+enum {
+ CFG = 0,
+ DTC = 1,
+ CAST = 2,
+ ETC = 3,
+
+ MSR_IDE_BASE = 0x51300000,
+ MSR_IDE_CFG = (MSR_IDE_BASE + 0x10),
+ MSR_IDE_DTC = (MSR_IDE_BASE + 0x12),
+ MSR_IDE_CAST = (MSR_IDE_BASE + 0x13),
+ MSR_IDE_ETC = (MSR_IDE_BASE + 0x14),
+
+ PCI_IDE_CFG = 0x40,
+ PCI_IDE_DTC = 0x48,
+ PCI_IDE_CAST = 0x4c,
+ PCI_IDE_ETC = 0x50,
+
+ IDE_CFG_CHANEN = 0x2,
+ IDE_CFG_CABLE = 0x10000,
+
+ IDE_D0_SHIFT = 24,
+ IDE_D1_SHIFT = 16,
+ IDE_DRV_MASK = 0xff,
+
+ IDE_CAST_D0_SHIFT = 6,
+ IDE_CAST_D1_SHIFT = 4,
+ IDE_CAST_DRV_MASK = 0x3,
+ IDE_CAST_CMD_MASK = 0xff,
+ IDE_CAST_CMD_SHIFT = 24,
+
+ IDE_ETC_NODMA = 0x03,
+};
+
+static int use_msr;
+
+static const u32 msr_reg[4] = {
+ MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC,
+};
+
+static const u8 pci_reg[4] = {
+ PCI_IDE_CFG, PCI_IDE_DTC, PCI_IDE_CAST, PCI_IDE_ETC,
+};
+
+static inline int cs5536_read(struct pci_dev *pdev, int reg, int *val)
+{
+ if (unlikely(use_msr)) {
+ u32 dummy;
+
+ rdmsr(msr_reg[reg], *val, dummy);
+ return 0;
+ }
+
+ return pci_read_config_dword(pdev, pci_reg[reg], val);
+}
+
+static inline int cs5536_write(struct pci_dev *pdev, int reg, int val)
+{
+ if (unlikely(use_msr)) {
+ wrmsr(msr_reg[reg], val, 0);
+ return 0;
+ }
+
+ return pci_write_config_dword(pdev, pci_reg[reg], val);
+}
+
+/**
+ * cs5536_cable_detect - detect cable type
+ * @ap: Port to detect on
+ * @deadline: deadline jiffies for the operation
+ *
+ * Perform cable detection for ATA66 capable cable. Return a libata
+ * cable type.
+ */
+
+static int cs5536_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 cfg;
+
+ cs5536_read(pdev, CFG, &cfg);
+
+ if (cfg & (IDE_CFG_CABLE << ap->port_no))
+ return ATA_CBL_PATA80;
+ else
+ return ATA_CBL_PATA40;
+}
+
+/**
+ * cs5536_set_piomode - PIO setup
+ * @ap: ATA interface
+ * @adev: device on the interface
+ */
+
+static void cs5536_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ static const u8 drv_timings[5] = {
+ 0x98, 0x55, 0x32, 0x21, 0x20,
+ };
+
+ static const u8 addr_timings[5] = {
+ 0x2, 0x1, 0x0, 0x0, 0x0,
+ };
+
+ static const u8 cmd_timings[5] = {
+ 0x99, 0x92, 0x90, 0x22, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ struct ata_device *pair = ata_dev_pair(adev);
+ int mode = adev->pio_mode - XFER_PIO_0;
+ int cmdmode = mode;
+ int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ int cshift = ap->port_no ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ u32 dtc, cast, etc;
+
+ if (pair)
+ cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);
+
+ cs5536_read(pdev, DTC, &dtc);
+ cs5536_read(pdev, CAST, &cast);
+ cs5536_read(pdev, ETC, &etc);
+
+ dtc &= ~(IDE_DRV_MASK << dshift);
+ dtc |= drv_timings[mode] << dshift;
+
+ cast &= ~(IDE_CAST_DRV_MASK << cshift);
+ cast |= addr_timings[mode] << cshift;
+
+ cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
+ cast |= cmd_timings[cmdmode] << IDE_CAST_CMD_SHIFT;
+
+ etc &= ~(IDE_DRV_MASK << dshift);
+ etc |= IDE_ETC_NODMA << dshift;
+
+ cs5536_write(pdev, DTC, dtc);
+ cs5536_write(pdev, CAST, cast);
+ cs5536_write(pdev, ETC, etc);
+}
+
+/**
+ * cs5536_set_dmamode - DMA timing setup
+ * @ap: ATA interface
+ * @adev: Device being configured
+ *
+ */
+
+static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ static const u8 udma_timings[6] = {
+ 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
+ };
+
+ static const u8 mwdma_timings[3] = {
+ 0x67, 0x21, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 dtc, etc;
+ int mode = adev->dma_mode;
+ int dshift = ap->port_no ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+
+ if (mode >= XFER_UDMA_0) {
+ cs5536_read(pdev, ETC, &etc);
+
+ etc &= ~(IDE_DRV_MASK << dshift);
+ etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
+
+ cs5536_write(pdev, ETC, etc);
+ } else { /* MWDMA */
+ cs5536_read(pdev, DTC, &dtc);
+
+ dtc &= ~(IDE_DRV_MASK << dshift);
+ dtc |= mwdma_timings[mode] << dshift;
+
+ cs5536_write(pdev, DTC, dtc);
+ }
+}
+
+static struct scsi_host_template cs5536_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations cs5536_port_ops = {
+ .set_piomode = cs5536_set_piomode,
+ .set_dmamode = cs5536_set_dmamode,
+ .mode_filter = ata_pci_default_filter,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .cable_detect = cs5536_cable_detect,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+
+ .data_xfer = ata_data_xfer,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+
+ .port_start = ata_port_start,
+};
+
+/**
+ * cs5536_init_one
+ * @dev: PCI device
+ * @id: Entry in match table
+ *
+ */
+
+static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ static const struct ata_port_info info = {
+ .sht = &cs5536_sht,
+ .flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA5,
+ .port_ops = &cs5536_port_ops,
+ };
+
+ const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+ u32 cfg;
+
+ if (use_msr)
+ printk(KERN_ERR DRV_NAME ": Using MSR regs instead of PCI\n");
+
+ cs5536_read(dev, CFG, &cfg);
+
+ if ((cfg & IDE_CFG_CHANEN) == 0) {
+ printk(KERN_ERR DRV_NAME ": disabled by BIOS\n");
+ return -ENODEV;
+ }
+
+ return ata_pci_init_one(dev, ppi);
+}
+
+static const struct pci_device_id cs5536[] = {
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), },
+ { },
+};
+
+static struct pci_driver cs5536_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = cs5536,
+ .probe = cs5536_init_one,
+ .remove = ata_pci_remove_one,
+#ifdef CONFIG_PM
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+#endif
+};
+
+static int __init cs5536_init(void)
+{
+ return pci_register_driver(&cs5536_pci_driver);
+}
+
+static void __exit cs5536_exit(void)
+{
+ pci_unregister_driver(&cs5536_pci_driver);
+}
+
+MODULE_AUTHOR("Martin K. Petersen");
+MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, cs5536);
+MODULE_VERSION(DRV_VERSION);
+module_param_named(msr, use_msr, int, 0644);
+MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
+
+module_init(cs5536_init);
+module_exit(cs5536_exit);
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 782ff4ada9d..5db2013230b 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -353,6 +353,7 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev)
static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_FUNC_ID(4),
+ PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */
PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
@@ -378,6 +379,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
+ PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 2eb75cd74a9..4dc2e73298f 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -279,7 +279,7 @@ static struct ata_port_operations sil680_port_ops = {
* Returns the final clock settings.
*/
-static u8 sil680_init_chip(struct pci_dev *pdev)
+static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
{
u32 class_rev = 0;
u8 tmpbyte = 0;
@@ -297,6 +297,8 @@ static u8 sil680_init_chip(struct pci_dev *pdev)
dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
tmpbyte & 1, tmpbyte & 0x30);
+ *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
+
switch(tmpbyte & 0x30) {
case 0x00:
/* 133 clock attempt to force it on */
@@ -361,25 +363,76 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
};
const struct ata_port_info *ppi[] = { &info, NULL };
static int printed_version;
+ struct ata_host *host;
+ void __iomem *mmio_base;
+ int rc, try_mmio;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- switch(sil680_init_chip(pdev))
- {
+ switch (sil680_init_chip(pdev, &try_mmio)) {
case 0:
ppi[0] = &info_slow;
break;
case 0x30:
return -ENODEV;
}
+
+ if (!try_mmio)
+ goto use_ioports;
+
+ /* Try to acquire MMIO resources and fallback to PIO if
+ * that fails
+ */
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+ rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME);
+ if (rc)
+ goto use_ioports;
+
+ /* Allocate host and set it up */
+ host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+ if (!host)
+ return -ENOMEM;
+ host->iomap = pcim_iomap_table(pdev);
+
+ /* Setup DMA masks */
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ pci_set_master(pdev);
+
+ /* Get MMIO base and initialize port addresses */
+ mmio_base = host->iomap[SIL680_MMIO_BAR];
+ host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x00;
+ host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80;
+ host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a;
+ host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a;
+ ata_std_ports(&host->ports[0]->ioaddr);
+ host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08;
+ host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0;
+ host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca;
+ host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca;
+ ata_std_ports(&host->ports[1]->ioaddr);
+
+ /* Register & activate */
+ return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+ &sil680_sht);
+
+use_ioports:
return ata_pci_init_one(pdev, ppi);
}
#ifdef CONFIG_PM
static int sil680_reinit_one(struct pci_dev *pdev)
{
- sil680_init_chip(pdev);
+ int try_mmio;
+
+ sil680_init_chip(pdev, &try_mmio);
return ata_pci_device_resume(pdev);
}
#endif
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 8d1b03d5bcb..199f7e150eb 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -318,7 +318,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
struct scatterlist *sg;
struct ata_port *ap = qc->ap;
struct adma_port_priv *pp = ap->private_data;
- u8 *buf = pp->pkt;
+ u8 *buf = pp->pkt, *last_buf = NULL;
int i = (2 + buf[3]) * 8;
u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0);
@@ -334,8 +334,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
*(__le32 *)(buf + i) = cpu_to_le32(len);
i += 4;
- if (ata_sg_is_last(sg, qc))
- pFLAGS |= pEND;
+ last_buf = &buf[i];
buf[i++] = pFLAGS;
buf[i++] = qc->dev->dma_mode & 0xf;
buf[i++] = 0; /* pPKLW */
@@ -348,6 +347,10 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
(unsigned long)addr, len);
}
+
+ if (likely(last_buf))
+ *last_buf |= pEND;
+
return i;
}
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
new file mode 100644
index 00000000000..b4c37b9e413
--- /dev/null
+++ b/drivers/ata/sata_fsl.c
@@ -0,0 +1,1490 @@
+/*
+ * drivers/ata/sata_fsl.c
+ *
+ * Freescale 3.0Gbps SATA device driver
+ *
+ * Author: Ashish Kalra <ashish.kalra@freescale.com>
+ * Li Yang <leoli@freescale.com>
+ *
+ * Copyright (c) 2006-2007 Freescale Semiconductor, 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_cmnd.h>
+#include <linux/libata.h>
+#include <asm/io.h>
+#include <linux/of_platform.h>
+
+/* Controller information */
+enum {
+ SATA_FSL_QUEUE_DEPTH = 16,
+ SATA_FSL_MAX_PRD = 63,
+ SATA_FSL_MAX_PRD_USABLE = SATA_FSL_MAX_PRD - 1,
+ SATA_FSL_MAX_PRD_DIRECT = 16, /* Direct PRDT entries */
+
+ SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY),
+
+ SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH,
+ SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */
+ SATA_FSL_CMD_SLOT_SIZE = (SATA_FSL_MAX_CMDS * SATA_FSL_CMD_HDR_SIZE),
+
+ /*
+ * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and
+ * chained indirect PRDEs upto a max count of 63.
+ * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will
+ * be setup as an indirect descriptor, pointing to it's next
+ * (contigious) PRDE. Though chained indirect PRDE arrays are
+ * supported,it will be more efficient to use a direct PRDT and
+ * a single chain/link to indirect PRDE array/PRDT.
+ */
+
+ SATA_FSL_CMD_DESC_CFIS_SZ = 32,
+ SATA_FSL_CMD_DESC_SFIS_SZ = 32,
+ SATA_FSL_CMD_DESC_ACMD_SZ = 16,
+ SATA_FSL_CMD_DESC_RSRVD = 16,
+
+ SATA_FSL_CMD_DESC_SIZE = (SATA_FSL_CMD_DESC_CFIS_SZ +
+ SATA_FSL_CMD_DESC_SFIS_SZ +
+ SATA_FSL_CMD_DESC_ACMD_SZ +
+ SATA_FSL_CMD_DESC_RSRVD +
+ SATA_FSL_MAX_PRD * 16),
+
+ SATA_FSL_CMD_DESC_OFFSET_TO_PRDT =
+ (SATA_FSL_CMD_DESC_CFIS_SZ +
+ SATA_FSL_CMD_DESC_SFIS_SZ +
+ SATA_FSL_CMD_DESC_ACMD_SZ +
+ SATA_FSL_CMD_DESC_RSRVD),
+
+ SATA_FSL_CMD_DESC_AR_SZ = (SATA_FSL_CMD_DESC_SIZE * SATA_FSL_MAX_CMDS),
+ SATA_FSL_PORT_PRIV_DMA_SZ = (SATA_FSL_CMD_SLOT_SIZE +
+ SATA_FSL_CMD_DESC_AR_SZ),
+
+ /*
+ * MPC8315 has two SATA controllers, SATA1 & SATA2
+ * (one port per controller)
+ * MPC837x has 2/4 controllers, one port per controller
+ */
+
+ SATA_FSL_MAX_PORTS = 1,
+
+ SATA_FSL_IRQ_FLAG = IRQF_SHARED,
+};
+
+/*
+* Host Controller command register set - per port
+*/
+enum {
+ CQ = 0,
+ CA = 8,
+ CC = 0x10,
+ CE = 0x18,
+ DE = 0x20,
+ CHBA = 0x24,
+ HSTATUS = 0x28,
+ HCONTROL = 0x2C,
+ CQPMP = 0x30,
+ SIGNATURE = 0x34,
+ ICC = 0x38,
+
+ /*
+ * Host Status Register (HStatus) bitdefs
+ */
+ ONLINE = (1 << 31),
+ GOING_OFFLINE = (1 << 30),
+ BIST_ERR = (1 << 29),
+
+ FATAL_ERR_HC_MASTER_ERR = (1 << 18),
+ FATAL_ERR_PARITY_ERR_TX = (1 << 17),
+ FATAL_ERR_PARITY_ERR_RX = (1 << 16),
+ FATAL_ERR_DATA_UNDERRUN = (1 << 13),
+ FATAL_ERR_DATA_OVERRUN = (1 << 12),
+ FATAL_ERR_CRC_ERR_TX = (1 << 11),
+ FATAL_ERR_CRC_ERR_RX = (1 << 10),
+ FATAL_ERR_FIFO_OVRFL_TX = (1 << 9),
+ FATAL_ERR_FIFO_OVRFL_RX = (1 << 8),
+
+ FATAL_ERROR_DECODE = FATAL_ERR_HC_MASTER_ERR |
+ FATAL_ERR_PARITY_ERR_TX |
+ FATAL_ERR_PARITY_ERR_RX |
+ FATAL_ERR_DATA_UNDERRUN |
+ FATAL_ERR_DATA_OVERRUN |
+ FATAL_ERR_CRC_ERR_TX |
+ FATAL_ERR_CRC_ERR_RX |
+ FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
+
+ INT_ON_FATAL_ERR = (1 << 5),
+ INT_ON_PHYRDY_CHG = (1 << 4),
+
+ INT_ON_SIGNATURE_UPDATE = (1 << 3),
+ INT_ON_SNOTIFY_UPDATE = (1 << 2),
+ INT_ON_SINGL_DEVICE_ERR = (1 << 1),
+ INT_ON_CMD_COMPLETE = 1,
+
+ INT_ON_ERROR = INT_ON_FATAL_ERR |
+ INT_ON_PHYRDY_CHG | INT_ON_SINGL_DEVICE_ERR,
+
+ /*
+ * Host Control Register (HControl) bitdefs
+ */
+ HCONTROL_ONLINE_PHY_RST = (1 << 31),
+ HCONTROL_FORCE_OFFLINE = (1 << 30),
+ HCONTROL_PARITY_PROT_MOD = (1 << 14),
+ HCONTROL_DPATH_PARITY = (1 << 12),
+ HCONTROL_SNOOP_ENABLE = (1 << 10),
+ HCONTROL_PMP_ATTACHED = (1 << 9),
+ HCONTROL_COPYOUT_STATFIS = (1 << 8),
+ IE_ON_FATAL_ERR = (1 << 5),
+ IE_ON_PHYRDY_CHG = (1 << 4),
+ IE_ON_SIGNATURE_UPDATE = (1 << 3),
+ IE_ON_SNOTIFY_UPDATE = (1 << 2),
+ IE_ON_SINGL_DEVICE_ERR = (1 << 1),
+ IE_ON_CMD_COMPLETE = 1,
+
+ DEFAULT_PORT_IRQ_ENABLE_MASK = IE_ON_FATAL_ERR | IE_ON_PHYRDY_CHG |
+ IE_ON_SIGNATURE_UPDATE |
+ IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
+
+ EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
+ DATA_SNOOP_ENABLE = (1 << 22),
+};
+
+/*
+ * SATA Superset Registers
+ */
+enum {
+ SSTATUS = 0,
+ SERROR = 4,
+ SCONTROL = 8,
+ SNOTIFY = 0xC,
+};
+
+/*
+ * Control Status Register Set
+ */
+enum {
+ TRANSCFG = 0,
+ TRANSSTATUS = 4,
+ LINKCFG = 8,
+ LINKCFG1 = 0xC,
+ LINKCFG2 = 0x10,
+ LINKSTATUS = 0x14,
+ LINKSTATUS1 = 0x18,
+ PHYCTRLCFG = 0x1C,
+ COMMANDSTAT = 0x20,
+};
+
+/* PHY (link-layer) configuration control */
+enum {
+ PHY_BIST_ENABLE = 0x01,
+};
+
+/*
+ * Command Header Table entry, i.e, command slot
+ * 4 Dwords per command slot, command header size == 64 Dwords.
+ */
+struct cmdhdr_tbl_entry {
+ u32 cda;
+ u32 prde_fis_len;
+ u32 ttl;
+ u32 desc_info;
+};
+
+/*
+ * Description information bitdefs
+ */
+enum {
+ VENDOR_SPECIFIC_BIST = (1 << 10),
+ CMD_DESC_SNOOP_ENABLE = (1 << 9),
+ FPDMA_QUEUED_CMD = (1 << 8),
+ SRST_CMD = (1 << 7),
+ BIST = (1 << 6),
+ ATAPI_CMD = (1 << 5),
+};
+
+/*
+ * Command Descriptor
+ */
+struct command_desc {
+ u8 cfis[8 * 4];
+ u8 sfis[8 * 4];
+ u8 acmd[4 * 4];
+ u8 fill[4 * 4];
+ u32 prdt[SATA_FSL_MAX_PRD_DIRECT * 4];
+ u32 prdt_indirect[(SATA_FSL_MAX_PRD - SATA_FSL_MAX_PRD_DIRECT) * 4];
+};
+
+/*
+ * Physical region table descriptor(PRD)
+ */
+
+struct prde {
+ u32 dba;
+ u8 fill[2 * 4];
+ u32 ddc_and_ext;
+};
+
+/*
+ * ata_port private data
+ * This is our per-port instance data.
+ */
+struct sata_fsl_port_priv {
+ struct cmdhdr_tbl_entry *cmdslot;
+ dma_addr_t cmdslot_paddr;
+ struct command_desc *cmdentry;
+ dma_addr_t cmdentry_paddr;
+
+ /*
+ * SATA FSL controller has a Status FIS which should contain the
+ * received D2H FIS & taskfile registers. This SFIS is present in
+ * the command descriptor, and to have a ready reference to it,
+ * we are caching it here, quite similar to what is done in H/W on
+ * AHCI compliant devices by copying taskfile fields to a 32-bit
+ * register.
+ */
+
+ struct ata_taskfile tf;
+};
+
+/*
+ * ata_port->host_set private data
+ */
+struct sata_fsl_host_priv {
+ void __iomem *hcr_base;
+ void __iomem *ssr_base;
+ void __iomem *csr_base;
+};
+
+static inline unsigned int sata_fsl_tag(unsigned int tag,
+ void __iomem * hcr_base)
+{
+ /* We let libATA core do actual (queue) tag allocation */
+
+ /* all non NCQ/queued commands should have tag#0 */
+ if (ata_tag_internal(tag)) {
+ DPRINTK("mapping internal cmds to tag#0\n");
+ return 0;
+ }
+
+ if (unlikely(tag >= SATA_FSL_QUEUE_DEPTH)) {
+ DPRINTK("tag %d invalid : out of range\n", tag);
+ return 0;
+ }
+
+ if (unlikely((ioread32(hcr_base + CQ)) & (1 << tag))) {
+ DPRINTK("tag %d invalid : in use!!\n", tag);
+ return 0;
+ }
+
+ return tag;
+}
+
+static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp,
+ unsigned int tag, u32 desc_info,
+ u32 data_xfer_len, u8 num_prde,
+ u8 fis_len)
+{
+ dma_addr_t cmd_descriptor_address;
+
+ cmd_descriptor_address = pp->cmdentry_paddr +
+ tag * SATA_FSL_CMD_DESC_SIZE;
+
+ /* NOTE: both data_xfer_len & fis_len are Dword counts */
+
+ pp->cmdslot[tag].cda = cpu_to_le32(cmd_descriptor_address);
+ pp->cmdslot[tag].prde_fis_len =
+ cpu_to_le32((num_prde << 16) | (fis_len << 2));
+ pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03);
+ pp->cmdslot[tag].desc_info = cpu_to_le32((desc_info | (tag & 0x1F)));
+
+ VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n",
+ pp->cmdslot[tag].cda,
+ pp->cmdslot[tag].prde_fis_len,
+ pp->cmdslot[tag].ttl, pp->cmdslot[tag].desc_info);
+
+}
+
+static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
+ u32 * ttl, dma_addr_t cmd_desc_paddr)
+{
+ struct scatterlist *sg;
+ unsigned int num_prde = 0;
+ u32 ttl_dwords = 0;
+
+ /*
+ * NOTE : direct & indirect prdt's are contigiously allocated
+ */
+ struct prde *prd = (struct prde *)&((struct command_desc *)
+ cmd_desc)->prdt;
+
+ struct prde *prd_ptr_to_indirect_ext = NULL;
+ unsigned indirect_ext_segment_sz = 0;
+ dma_addr_t indirect_ext_segment_paddr;
+
+ VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd);
+
+ indirect_ext_segment_paddr = cmd_desc_paddr +
+ SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16;
+
+ ata_for_each_sg(sg, qc) {
+ dma_addr_t sg_addr = sg_dma_address(sg);
+ u32 sg_len = sg_dma_len(sg);
+
+ VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n",
+ sg_addr, sg_len);
+
+ /* warn if each s/g element is not dword aligned */
+ if (sg_addr & 0x03)
+ ata_port_printk(qc->ap, KERN_ERR,
+ "s/g addr unaligned : 0x%x\n", sg_addr);
+ if (sg_len & 0x03)
+ ata_port_printk(qc->ap, KERN_ERR,
+ "s/g len unaligned : 0x%x\n", sg_len);
+
+ if ((num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1)) &&
+ !ata_sg_is_last(sg, qc)) {
+ VPRINTK("setting indirect prde\n");
+ prd_ptr_to_indirect_ext = prd;
+ prd->dba = cpu_to_le32(indirect_ext_segment_paddr);
+ indirect_ext_segment_sz = 0;
+ ++prd;
+ ++num_prde;
+ }
+
+ ttl_dwords += sg_len;
+ prd->dba = cpu_to_le32(sg_addr);
+ prd->ddc_and_ext =
+ cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03));
+
+ VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",
+ ttl_dwords, prd->dba, prd->ddc_and_ext);
+
+ ++num_prde;
+ ++prd;
+ if (prd_ptr_to_indirect_ext)
+ indirect_ext_segment_sz += sg_len;
+ }
+
+ if (prd_ptr_to_indirect_ext) {
+ /* set indirect extension flag along with indirect ext. size */
+ prd_ptr_to_indirect_ext->ddc_and_ext =
+ cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
+ DATA_SNOOP_ENABLE |
+ (indirect_ext_segment_sz & ~0x03)));
+ }
+
+ *ttl = ttl_dwords;
+ return num_prde;
+}
+
+static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct sata_fsl_port_priv *pp = ap->private_data;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+ struct command_desc *cd;
+ u32 desc_info = CMD_DESC_SNOOP_ENABLE;
+ u32 num_prde = 0;
+ u32 ttl_dwords = 0;
+ dma_addr_t cd_paddr;
+
+ cd = (struct command_desc *)pp->cmdentry + tag;
+ cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE;
+
+ ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) & cd->cfis);
+
+ VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n",
+ cd->cfis[0], cd->cfis[1], cd->cfis[2]);
+
+ if (qc->tf.protocol == ATA_PROT_NCQ) {
+ VPRINTK("FPDMA xfer,Sctor cnt[0:7],[8:15] = %d,%d\n",
+ cd->cfis[3], cd->cfis[11]);
+ }
+
+ /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */
+ if (is_atapi_taskfile(&qc->tf)) {
+ desc_info |= ATAPI_CMD;
+ memset((void *)&cd->acmd, 0, 32);
+ memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len);
+ }
+
+ if (qc->flags & ATA_QCFLAG_DMAMAP)
+ num_prde = sata_fsl_fill_sg(qc, (void *)cd,
+ &ttl_dwords, cd_paddr);
+
+ if (qc->tf.protocol == ATA_PROT_NCQ)
+ desc_info |= FPDMA_QUEUED_CMD;
+
+ sata_fsl_setup_cmd_hdr_entry(pp, tag, desc_info, ttl_dwords,
+ num_prde, 5);
+
+ VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d\n",
+ desc_info, ttl_dwords, num_prde);
+}
+
+static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+
+ VPRINTK("xx_qc_issue called,CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x\n",
+ ioread32(CQ + hcr_base),
+ ioread32(CA + hcr_base),
+ ioread32(CE + hcr_base), ioread32(CC + hcr_base));
+
+ /* Simply queue command to the controller/device */
+ iowrite32(1 << tag, CQ + hcr_base);
+
+ VPRINTK("xx_qc_issue called, tag=%d, CQ=0x%x, CA=0x%x\n",
+ tag, ioread32(CQ + hcr_base), ioread32(CA + hcr_base));
+
+ VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n",
+ ioread32(CE + hcr_base),
+ ioread32(DE + hcr_base),
+ ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base));
+
+ return 0;
+}
+
+static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
+ u32 val)
+{
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *ssr_base = host_priv->ssr_base;
+ unsigned int sc_reg;
+
+ switch (sc_reg_in) {
+ case SCR_STATUS:
+ sc_reg = 0;
+ break;
+ case SCR_ERROR:
+ sc_reg = 1;
+ break;
+ case SCR_CONTROL:
+ sc_reg = 2;
+ break;
+ case SCR_ACTIVE:
+ sc_reg = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ VPRINTK("xx_scr_write, reg_in = %d\n", sc_reg);
+
+ iowrite32(val, (void __iomem *)ssr_base + (sc_reg * 4));
+ return 0;
+}
+
+static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
+ u32 *val)
+{
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *ssr_base = host_priv->ssr_base;
+ unsigned int sc_reg;
+
+ switch (sc_reg_in) {
+ case SCR_STATUS:
+ sc_reg = 0;
+ break;
+ case SCR_ERROR:
+ sc_reg = 1;
+ break;
+ case SCR_CONTROL:
+ sc_reg = 2;
+ break;
+ case SCR_ACTIVE:
+ sc_reg = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ VPRINTK("xx_scr_read, reg_in = %d\n", sc_reg);
+
+ *val = ioread32((void __iomem *)ssr_base + (sc_reg * 4));
+ return 0;
+}
+
+static void sata_fsl_freeze(struct ata_port *ap)
+{
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 temp;
+
+ VPRINTK("xx_freeze, CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x\n",
+ ioread32(CQ + hcr_base),
+ ioread32(CA + hcr_base),
+ ioread32(CE + hcr_base), ioread32(DE + hcr_base));
+ VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT));
+
+ /* disable interrupts on the controller/port */
+ temp = ioread32(hcr_base + HCONTROL);
+ iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
+
+ VPRINTK("in xx_freeze : HControl = 0x%x, HStatus = 0x%x\n",
+ ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
+}
+
+static void sata_fsl_thaw(struct ata_port *ap)
+{
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 temp;
+
+ /* ack. any pending IRQs for this controller/port */
+ temp = ioread32(hcr_base + HSTATUS);
+
+ VPRINTK("xx_thaw, pending IRQs = 0x%x\n", (temp & 0x3F));
+
+ if (temp & 0x3F)
+ iowrite32((temp & 0x3F), hcr_base + HSTATUS);
+
+ /* enable interrupts on the controller/port */
+ temp = ioread32(hcr_base + HCONTROL);
+ iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL);
+
+ VPRINTK("xx_thaw : HControl = 0x%x, HStatus = 0x%x\n",
+ ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
+}
+
+/*
+ * NOTE : 1st D2H FIS from device does not update sfis in command descriptor.
+ */
+static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd
+ *qc,
+ struct ata_port *ap)
+{
+ struct sata_fsl_port_priv *pp = ap->private_data;
+ u8 fis[6 * 4];
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+ struct command_desc *cd;
+
+ cd = pp->cmdentry + tag;
+
+ memcpy(fis, &cd->sfis, 6 * 4); /* should we use memcpy_from_io() */
+ ata_tf_from_fis(fis, &pp->tf);
+}
+
+static u8 sata_fsl_check_status(struct ata_port *ap)
+{
+ struct sata_fsl_port_priv *pp = ap->private_data;
+
+ return pp->tf.command;
+}
+
+static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+ struct sata_fsl_port_priv *pp = ap->private_data;
+
+ *tf = pp->tf;
+}
+
+static int sata_fsl_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host->dev;
+ struct sata_fsl_port_priv *pp;
+ int retval;
+ void *mem;
+ dma_addr_t mem_dma;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 temp;
+
+ pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+
+ /*
+ * allocate per command dma alignment pad buffer, which is used
+ * internally by libATA to ensure that all transfers ending on
+ * unaligned boundaries are padded, to align on Dword boundaries
+ */
+ retval = ata_pad_alloc(ap, dev);
+ if (retval) {
+ kfree(pp);
+ return retval;
+ }
+
+ mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
+ if (!mem) {
+ ata_pad_free(ap, dev);
+ kfree(pp);
+ return -ENOMEM;
+ }
+ memset(mem, 0, SATA_FSL_PORT_PRIV_DMA_SZ);
+
+ pp->cmdslot = mem;
+ pp->cmdslot_paddr = mem_dma;
+
+ mem += SATA_FSL_CMD_SLOT_SIZE;
+ mem_dma += SATA_FSL_CMD_SLOT_SIZE;
+
+ pp->cmdentry = mem;
+ pp->cmdentry_paddr = mem_dma;
+
+ ap->private_data = pp;
+
+ VPRINTK("CHBA = 0x%x, cmdentry_phys = 0x%x\n",
+ pp->cmdslot_paddr, pp->cmdentry_paddr);
+
+ /* Now, update the CHBA register in host controller cmd register set */
+ iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA);
+
+ /*
+ * Now, we can bring the controller on-line & also initiate
+ * the COMINIT sequence, we simply return here and the boot-probing
+ * & device discovery process is re-initiated by libATA using a
+ * Softreset EH (dummy) session. Hence, boot probing and device
+ * discovey will be part of sata_fsl_softreset() callback.
+ */
+
+ temp = ioread32(hcr_base + HCONTROL);
+ iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL);
+
+ VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+ VPRINTK("CHBA = 0x%x\n", ioread32(hcr_base + CHBA));
+
+ /*
+ * Workaround for 8315DS board 3gbps link-up issue,
+ * currently limit SATA port to GEN1 speed
+ */
+ sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+ temp &= ~(0xF << 4);
+ temp |= (0x1 << 4);
+ sata_fsl_scr_write(ap, SCR_CONTROL, temp);
+
+ sata_fsl_scr_read(ap, SCR_CONTROL, &temp);
+ dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n",
+ temp);
+
+ return 0;
+}
+
+static void sata_fsl_port_stop(struct ata_port *ap)
+{
+ struct device *dev = ap->host->dev;
+ struct sata_fsl_port_priv *pp = ap->private_data;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 temp;
+
+ /*
+ * Force host controller to go off-line, aborting current operations
+ */
+ temp = ioread32(hcr_base + HCONTROL);
+ temp &= ~HCONTROL_ONLINE_PHY_RST;
+ temp |= HCONTROL_FORCE_OFFLINE;
+ iowrite32(temp, hcr_base + HCONTROL);
+
+ /* Poll for controller to go offline - should happen immediately */
+ ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1);
+
+ ap->private_data = NULL;
+ dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ,
+ pp->cmdslot, pp->cmdslot_paddr);
+
+ ata_pad_free(ap, dev);
+ kfree(pp);
+}
+
+static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
+{
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ struct ata_taskfile tf;
+ u32 temp;
+
+ temp = ioread32(hcr_base + SIGNATURE);
+
+ VPRINTK("raw sig = 0x%x\n", temp);
+ VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+ tf.lbah = (temp >> 24) & 0xff;
+ tf.lbam = (temp >> 16) & 0xff;
+ tf.lbal = (temp >> 8) & 0xff;
+ tf.nsect = temp & 0xff;
+
+ return ata_dev_classify(&tf);
+}
+
+static int sata_fsl_softreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
+{
+ struct sata_fsl_port_priv *pp = ap->private_data;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 temp;
+ struct ata_taskfile tf;
+ u8 *cfis;
+ u32 Serror;
+ int i = 0;
+ struct ata_queued_cmd qc;
+ u8 *buf;
+ dma_addr_t dma_address;
+ struct scatterlist *sg;
+ unsigned long start_jiffies;
+
+ DPRINTK("in xx_softreset\n");
+
+try_offline_again:
+ /*
+ * Force host controller to go off-line, aborting current operations
+ */
+ temp = ioread32(hcr_base + HCONTROL);
+ temp &= ~HCONTROL_ONLINE_PHY_RST;
+ iowrite32(temp, hcr_base + HCONTROL);
+
+ /* Poll for controller to go offline */
+ temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 500);
+
+ if (temp & ONLINE) {
+ ata_port_printk(ap, KERN_ERR,
+ "Softreset failed, not off-lined %d\n", i);
+
+ /*
+ * Try to offline controller atleast twice
+ */
+ i++;
+ if (i == 2)
+ goto err;
+ else
+ goto try_offline_again;
+ }
+
+ DPRINTK("softreset, controller off-lined\n");
+ VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+ /*
+ * PHY reset should remain asserted for atleast 1ms
+ */
+ msleep(1);
+
+ /*
+ * Now, bring the host controller online again, this can take time
+ * as PHY reset and communication establishment, 1st D2H FIS and
+ * device signature update is done, on safe side assume 500ms
+ * NOTE : Host online status may be indicated immediately!!
+ */
+
+ temp = ioread32(hcr_base + HCONTROL);
+ temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE);
+ iowrite32(temp, hcr_base + HCONTROL);
+
+ temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500);
+
+ if (!(temp & ONLINE)) {
+ ata_port_printk(ap, KERN_ERR,
+ "Softreset failed, not on-lined\n");
+ goto err;
+ }
+
+ DPRINTK("softreset, controller off-lined & on-lined\n");
+ VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+ /*
+ * First, wait for the PHYRDY change to occur before waiting for
+ * the signature, and also verify if SStatus indicates device
+ * presence
+ */
+
+ temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0, 1, 500);
+ if ((!(temp & 0x10)) || ata_port_offline(ap)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "No Device OR PHYRDY change,Hstatus = 0x%x\n",
+ ioread32(hcr_base + HSTATUS));
+ goto err;
+ }
+
+ /*
+ * Wait for the first D2H from device,i.e,signature update notification
+ */
+ start_jiffies = jiffies;
+ temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0x10,
+ 500, jiffies_to_msecs(deadline - start_jiffies));
+
+ if ((temp & 0xFF) != 0x18) {
+ ata_port_printk(ap, KERN_WARNING, "No Signature Update\n");
+ goto err;
+ } else {
+ ata_port_printk(ap, KERN_INFO,
+ "Signature Update detected @ %d msecs\n",
+ jiffies_to_msecs(jiffies - start_jiffies));
+ }
+
+ /*
+ * Send a device reset (SRST) explicitly on command slot #0
+ * Check : will the command queue (reg) be cleared during offlining ??
+ * Also we will be online only if Phy commn. has been established
+ * and device presence has been detected, therefore if we have
+ * reached here, we can send a command to the target device
+ */
+
+ if (ap->sactive)
+ goto skip_srst_do_ncq_error_handling;
+
+ DPRINTK("Sending SRST/device reset\n");
+
+ ata_tf_init(ap->device, &tf);
+ cfis = (u8 *) & pp->cmdentry->cfis;
+
+ /* device reset/SRST is a control register update FIS, uses tag0 */
+ sata_fsl_setup_cmd_hdr_entry(pp, 0,
+ SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+
+ tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */
+ ata_tf_to_fis(&tf, 0, 0, cfis);
+
+ DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ cfis[0], cfis[1], cfis[2], cfis[3]);
+
+ /*
+ * Queue SRST command to the controller/device, ensure that no
+ * other commands are active on the controller/device
+ */
+
+ DPRINTK("@Softreset, CQ = 0x%x, CA = 0x%x, CC = 0x%x\n",
+ ioread32(CQ + hcr_base),
+ ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+ iowrite32(0xFFFF, CC + hcr_base);
+ iowrite32(1, CQ + hcr_base);
+
+ temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
+ if (temp & 0x1) {
+ ata_port_printk(ap, KERN_WARNING, "ATA_SRST issue failed\n");
+
+ DPRINTK("Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n",
+ ioread32(CQ + hcr_base),
+ ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+ sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+
+ DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+ DPRINTK("Serror = 0x%x\n", Serror);
+ goto err;
+ }
+
+ msleep(1);
+
+ /*
+ * SATA device enters reset state after receving a Control register
+ * FIS with SRST bit asserted and it awaits another H2D Control reg.
+ * FIS with SRST bit cleared, then the device does internal diags &
+ * initialization, followed by indicating it's initialization status
+ * using ATA signature D2H register FIS to the host controller.
+ */
+
+ sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5);
+
+ tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */
+ ata_tf_to_fis(&tf, 0, 0, cfis);
+
+ iowrite32(1, CQ + hcr_base);
+ msleep(150); /* ?? */
+
+ /*
+ * The above command would have signalled an interrupt on command
+ * complete, which needs special handling, by clearing the Nth
+ * command bit of the CCreg
+ */
+ iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */
+ goto check_device_signature;
+
+skip_srst_do_ncq_error_handling:
+
+ VPRINTK("Sending read log ext(10h) command\n");
+
+ memset(&qc, 0, sizeof(struct ata_queued_cmd));
+ ata_tf_init(ap->device, &tf);
+
+ tf.command = ATA_CMD_READ_LOG_EXT;
+ tf.lbal = ATA_LOG_SATA_NCQ;
+ tf.nsect = 1;
+ tf.hob_nsect = 0;
+ tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE;
+ tf.protocol = ATA_PROT_PIO;
+
+ qc.tag = ATA_TAG_INTERNAL;
+ qc.scsicmd = NULL;
+ qc.ap = ap;
+ qc.dev = ap->device;
+
+ qc.tf = tf;
+ qc.flags |= ATA_QCFLAG_RESULT_TF;
+ qc.dma_dir = DMA_FROM_DEVICE;
+
+ buf = ap->sector_buf;
+ ata_sg_init_one(&qc, buf, 1 * ATA_SECT_SIZE);
+
+ /*
+ * Need to DMA-map the memory buffer associated with the command
+ */
+
+ sg = qc.__sg;
+ dma_address = dma_map_single(ap->dev, qc.buf_virt,
+ sg->length, DMA_FROM_DEVICE);
+
+ sg_dma_address(sg) = dma_address;
+ sg_dma_len(sg) = sg->length;
+
+ VPRINTK("EH, addr = 0x%x, len = 0x%x\n", dma_address, sg->length);
+
+ sata_fsl_qc_prep(&qc);
+ sata_fsl_qc_issue(&qc);
+
+ temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
+ if (temp & 0x1) {
+ VPRINTK("READ_LOG_EXT_10H issue failed\n");
+
+ VPRINTK("READ_LOG@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n",
+ ioread32(CQ + hcr_base),
+ ioread32(CA + hcr_base), ioread32(CC + hcr_base));
+
+ sata_fsl_scr_read(ap, SCR_ERROR, &Serror);
+
+ VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+ VPRINTK("Serror = 0x%x\n", Serror);
+ goto err;
+ }
+
+ iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */
+
+ check_device_signature:
+
+ DPRINTK("SATA FSL : Now checking device signature\n");
+
+ *class = ATA_DEV_NONE;
+
+ /* Verify if SStatus indicates device presence */
+ if (ata_port_online(ap)) {
+ /*
+ * if we are here, device presence has been detected,
+ * 1st D2H FIS would have been received, but sfis in
+ * command desc. is not updated, but signature register
+ * would have been updated
+ */
+
+ *class = sata_fsl_dev_classify(ap);
+
+ DPRINTK("class = %d\n", *class);
+ VPRINTK("ccreg = 0x%x\n", ioread32(hcr_base + CC));
+ VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE));
+ }
+
+ return 0;
+
+err:
+ return -EIO;
+}
+
+static int sata_fsl_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
+{
+ int retval;
+
+ retval = sata_std_hardreset(ap, class, deadline);
+
+ DPRINTK("SATA FSL : in xx_hardreset, retval = 0x%d\n", retval);
+
+ return retval;
+}
+
+static void sata_fsl_error_handler(struct ata_port *ap)
+{
+
+ DPRINTK("in xx_error_handler\n");
+
+ /* perform recovery */
+ ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_fsl_hardreset,
+ ata_std_postreset);
+}
+
+static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+ if (qc->flags & ATA_QCFLAG_FAILED)
+ qc->err_mask |= AC_ERR_OTHER;
+
+ if (qc->err_mask) {
+ /* make DMA engine forget about the failed command */
+
+ }
+}
+
+static void sata_fsl_irq_clear(struct ata_port *ap)
+{
+ /* unused */
+}
+
+static void sata_fsl_error_intr(struct ata_port *ap)
+{
+ struct ata_eh_info *ehi = &ap->eh_info;
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 hstatus, dereg, cereg = 0, SError = 0;
+ unsigned int err_mask = 0, action = 0;
+ struct ata_queued_cmd *qc;
+ int freeze = 0;
+
+ hstatus = ioread32(hcr_base + HSTATUS);
+ cereg = ioread32(hcr_base + CE);
+
+ ata_ehi_clear_desc(ehi);
+
+ /*
+ * Handle & Clear SError
+ */
+
+ sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+ if (unlikely(SError & 0xFFFF0000)) {
+ sata_fsl_scr_write(ap, SCR_ERROR, SError);
+ err_mask |= AC_ERR_ATA_BUS;
+ }
+
+ DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n",
+ hstatus, cereg, ioread32(hcr_base + DE), SError);
+
+ /* handle single device errors */
+ if (cereg) {
+ /*
+ * clear the command error, also clears queue to the device
+ * in error, and we can (re)issue commands to this device.
+ * When a device is in error all commands queued into the
+ * host controller and at the device are considered aborted
+ * and the queue for that device is stopped. Now, after
+ * clearing the device error, we can issue commands to the
+ * device to interrogate it to find the source of the error.
+ */
+ dereg = ioread32(hcr_base + DE);
+ iowrite32(dereg, hcr_base + DE);
+ iowrite32(cereg, hcr_base + CE);
+
+ DPRINTK("single device error, CE=0x%x, DE=0x%x\n",
+ ioread32(hcr_base + CE), ioread32(hcr_base + DE));
+ /*
+ * We should consider this as non fatal error, and TF must
+ * be updated as done below.
+ */
+
+ err_mask |= AC_ERR_DEV;
+ }
+
+ /* handle fatal errors */
+ if (hstatus & FATAL_ERROR_DECODE) {
+ err_mask |= AC_ERR_ATA_BUS;
+ action |= ATA_EH_SOFTRESET;
+ /* how will fatal error interrupts be completed ?? */
+ freeze = 1;
+ }
+
+ /* Handle PHYRDY change notification */
+ if (hstatus & INT_ON_PHYRDY_CHG) {
+ DPRINTK("SATA FSL: PHYRDY change indication\n");
+
+ /* Setup a soft-reset EH action */
+ ata_ehi_hotplugged(ehi);
+ freeze = 1;
+ }
+
+ /* record error info */
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+
+ if (qc) {
+ sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+ qc->err_mask |= err_mask;
+ } else
+ ehi->err_mask |= err_mask;
+
+ ehi->action |= action;
+ ehi->serror |= SError;
+
+ /* freeze or abort */
+ if (freeze)
+ ata_port_freeze(ap);
+ else
+ ata_port_abort(ap);
+}
+
+static void sata_fsl_qc_complete(struct ata_queued_cmd *qc)
+{
+ if (qc->flags & ATA_QCFLAG_RESULT_TF) {
+ DPRINTK("xx_qc_complete called\n");
+ sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+ }
+}
+
+static void sata_fsl_host_intr(struct ata_port *ap)
+{
+ struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 hstatus, qc_active = 0;
+ struct ata_queued_cmd *qc;
+ u32 SError;
+
+ hstatus = ioread32(hcr_base + HSTATUS);
+
+ sata_fsl_scr_read(ap, SCR_ERROR, &SError);
+
+ if (unlikely(SError & 0xFFFF0000)) {
+ DPRINTK("serror @host_intr : 0x%x\n", SError);
+ sata_fsl_error_intr(ap);
+
+ }
+
+ if (unlikely(hstatus & INT_ON_ERROR)) {
+ DPRINTK("error interrupt!!\n");
+ sata_fsl_error_intr(ap);
+ return;
+ }
+
+ if (ap->sactive) { /* only true for NCQ commands */
+ int i;
+ /* Read command completed register */
+ qc_active = ioread32(hcr_base + CC);
+ /* clear CC bit, this will also complete the interrupt */
+ iowrite32(qc_active, hcr_base + CC);
+
+ DPRINTK("Status of all queues :\n");
+ DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n",
+ qc_active, ioread32(hcr_base + CA),
+ ioread32(hcr_base + CE));
+
+ for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
+ if (qc_active & (1 << i)) {
+ qc = ata_qc_from_tag(ap, i);
+ if (qc) {
+ sata_fsl_qc_complete(qc);
+ ata_qc_complete(qc);
+ }
+ DPRINTK
+ ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
+ i, ioread32(hcr_base + CC),
+ ioread32(hcr_base + CA));
+ }
+ }
+ return;
+
+ } else if (ap->qc_active) {
+ iowrite32(1, hcr_base + CC);
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+
+ DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n",
+ ap->active_tag, ioread32(hcr_base + CC));
+
+ if (qc) {
+ sata_fsl_qc_complete(qc);
+ ata_qc_complete(qc);
+ }
+ } else {
+ /* Spurious Interrupt!! */
+ DPRINTK("spurious interrupt!!, CC = 0x%x\n",
+ ioread32(hcr_base + CC));
+ return;
+ }
+}
+
+static irqreturn_t sata_fsl_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ struct sata_fsl_host_priv *host_priv = host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 interrupt_enables;
+ unsigned handled = 0;
+ struct ata_port *ap;
+
+ /* ack. any pending IRQs for this controller/port */
+ interrupt_enables = ioread32(hcr_base + HSTATUS);
+ interrupt_enables &= 0x3F;
+
+ DPRINTK("interrupt status 0x%x\n", interrupt_enables);
+
+ if (!interrupt_enables)
+ return IRQ_NONE;
+
+ spin_lock(&host->lock);
+
+ /* Assuming one port per host controller */
+
+ ap = host->ports[0];
+ if (ap) {
+ sata_fsl_host_intr(ap);
+ } else {
+ dev_printk(KERN_WARNING, host->dev,
+ "interrupt on disabled port 0\n");
+ }
+
+ iowrite32(interrupt_enables, hcr_base + HSTATUS);
+ handled = 1;
+
+ spin_unlock(&host->lock);
+
+ return IRQ_RETVAL(handled);
+}
+
+/*
+ * Multiple ports are represented by multiple SATA controllers with
+ * one port per controller
+ */
+static int sata_fsl_init_controller(struct ata_host *host)
+{
+ struct sata_fsl_host_priv *host_priv = host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ u32 temp;
+
+ /*
+ * NOTE : We cannot bring the controller online before setting
+ * the CHBA, hence main controller initialization is done as
+ * part of the port_start() callback
+ */
+
+ /* ack. any pending IRQs for this controller/port */
+ temp = ioread32(hcr_base + HSTATUS);
+ if (temp & 0x3F)
+ iowrite32((temp & 0x3F), hcr_base + HSTATUS);
+
+ /* Keep interrupts disabled on the controller */
+ temp = ioread32(hcr_base + HCONTROL);
+ iowrite32((temp & ~0x3F), hcr_base + HCONTROL);
+
+ /* Disable interrupt coalescing control(icc), for the moment */
+ DPRINTK("icc = 0x%x\n", ioread32(hcr_base + ICC));
+ iowrite32(0x01000000, hcr_base + ICC);
+
+ /* clear error registers, SError is cleared by libATA */
+ iowrite32(0x00000FFFF, hcr_base + CE);
+ iowrite32(0x00000FFFF, hcr_base + DE);
+
+ /* initially assuming no Port multiplier, set CQPMP to 0 */
+ iowrite32(0x0, hcr_base + CQPMP);
+
+ /*
+ * host controller will be brought on-line, during xx_port_start()
+ * callback, that should also initiate the OOB, COMINIT sequence
+ */
+
+ DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
+ DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
+
+ return 0;
+}
+
+/*
+ * scsi mid-layer and libata interface structures
+ */
+static struct scsi_host_template sata_fsl_sht = {
+ .module = THIS_MODULE,
+ .name = "sata_fsl",
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .change_queue_depth = ata_scsi_change_queue_depth,
+ .can_queue = SATA_FSL_QUEUE_DEPTH,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = SATA_FSL_MAX_PRD_USABLE,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = "sata_fsl",
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
+#endif
+};
+
+static const struct ata_port_operations sata_fsl_ops = {
+ .port_disable = ata_port_disable,
+
+ .check_status = sata_fsl_check_status,
+ .check_altstatus = sata_fsl_check_status,
+ .dev_select = ata_noop_dev_select,
+
+ .tf_read = sata_fsl_tf_read,
+
+ .qc_prep = sata_fsl_qc_prep,
+ .qc_issue = sata_fsl_qc_issue,
+ .irq_clear = sata_fsl_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
+
+ .scr_read = sata_fsl_scr_read,
+ .scr_write = sata_fsl_scr_write,
+
+ .freeze = sata_fsl_freeze,
+ .thaw = sata_fsl_thaw,
+ .error_handler = sata_fsl_error_handler,
+ .post_internal_cmd = sata_fsl_post_internal_cmd,
+
+ .port_start = sata_fsl_port_start,
+ .port_stop = sata_fsl_port_stop,
+};
+
+static const struct ata_port_info sata_fsl_port_info[] = {
+ {
+ .flags = SATA_FSL_HOST_FLAGS,
+ .pio_mask = 0x1f, /* pio 0-4 */
+ .udma_mask = 0x7f, /* udma 0-6 */
+ .port_ops = &sata_fsl_ops,
+ },
+};
+
+static int sata_fsl_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ int retval = 0;
+ void __iomem *hcr_base = NULL;
+ void __iomem *ssr_base = NULL;
+ void __iomem *csr_base = NULL;
+ struct sata_fsl_host_priv *host_priv = NULL;
+ struct resource *r;
+ int irq;
+ struct ata_host *host;
+
+ struct ata_port_info pi = sata_fsl_port_info[0];
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+
+ dev_printk(KERN_INFO, &ofdev->dev,
+ "Sata FSL Platform/CSB Driver init\n");
+
+ r = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+ hcr_base = of_iomap(ofdev->node, 0);
+ if (!hcr_base)
+ goto error_exit_with_cleanup;
+
+ ssr_base = hcr_base + 0x100;
+ csr_base = hcr_base + 0x140;
+
+ DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG));
+ DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc));
+ DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE);
+
+ host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL);
+ if (!host_priv)
+ goto error_exit_with_cleanup;
+
+ host_priv->hcr_base = hcr_base;
+ host_priv->ssr_base = ssr_base;
+ host_priv->csr_base = csr_base;
+
+ irq = irq_of_parse_and_map(ofdev->node, 0);
+ if (irq < 0) {
+ dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n");
+ goto error_exit_with_cleanup;
+ }
+
+ /* allocate host structure */
+ host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
+
+ /* host->iomap is not used currently */
+ host->private_data = host_priv;
+
+ /* setup port(s) */
+
+ host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base;
+ host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base;
+
+ /* initialize host controller */
+ sata_fsl_init_controller(host);
+
+ /*
+ * Now, register with libATA core, this will also initiate the
+ * device discovery process, invoking our port_start() handler &
+ * error_handler() to execute a dummy Softreset EH session
+ */
+ ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG,
+ &sata_fsl_sht);
+
+ dev_set_drvdata(&ofdev->dev, host);
+
+ return 0;
+
+error_exit_with_cleanup:
+
+ if (hcr_base)
+ iounmap(hcr_base);
+ if (host_priv)
+ kfree(host_priv);
+
+ return retval;
+}
+
+static int sata_fsl_remove(struct of_device *ofdev)
+{
+ struct ata_host *host = dev_get_drvdata(&ofdev->dev);
+ struct sata_fsl_host_priv *host_priv = host->private_data;
+
+ ata_host_detach(host);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ irq_dispose_mapping(host->irq);
+ iounmap(host_priv->hcr_base);
+ kfree(host_priv);
+
+ return 0;
+}
+
+static struct of_device_id fsl_sata_match[] = {
+ {
+ .compatible = "fsl,mpc8315-sata",
+ },
+ {
+ .compatible = "fsl,mpc8379-sata",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, fsl_sata_match);
+
+static struct of_platform_driver fsl_sata_driver = {
+ .name = "fsl-sata",
+ .match_table = fsl_sata_match,
+ .probe = sata_fsl_probe,
+ .remove = sata_fsl_remove,
+};
+
+static int __init sata_fsl_init(void)
+{
+ of_register_platform_driver(&fsl_sata_driver);
+ return 0;
+}
+
+static void __exit sata_fsl_exit(void)
+{
+ of_unregister_platform_driver(&fsl_sata_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ashish Kalra, Freescale Semiconductor");
+MODULE_DESCRIPTION("Freescale 3.0Gbps SATA controller low level driver");
+MODULE_VERSION("1.10");
+
+module_init(sata_fsl_init);
+module_exit(sata_fsl_exit);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 4df8311968e..7f1b13e89cf 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -421,7 +421,6 @@ static void mv_error_handler(struct ata_port *ap);
static void mv_post_int_cmd(struct ata_queued_cmd *qc);
static void mv_eh_freeze(struct ata_port *ap);
static void mv_eh_thaw(struct ata_port *ap);
-static int mv_slave_config(struct scsi_device *sdev);
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
@@ -459,7 +458,7 @@ static struct scsi_host_template mv5_sht = {
.use_clustering = 1,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
- .slave_configure = mv_slave_config,
+ .slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
};
@@ -477,7 +476,7 @@ static struct scsi_host_template mv6_sht = {
.use_clustering = 1,
.proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
- .slave_configure = mv_slave_config,
+ .slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
};
@@ -756,17 +755,6 @@ static void mv_irq_clear(struct ata_port *ap)
{
}
-static int mv_slave_config(struct scsi_device *sdev)
-{
- int rc = ata_scsi_slave_config(sdev);
- if (rc)
- return rc;
-
- blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2);
-
- return 0; /* scsi layer doesn't check return value, sigh */
-}
-
static void mv_set_edma_ptrs(void __iomem *port_mmio,
struct mv_host_priv *hpriv,
struct mv_port_priv *pp)
@@ -1138,7 +1126,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
{
struct mv_port_priv *pp = qc->ap->private_data;
struct scatterlist *sg;
- struct mv_sg *mv_sg;
+ struct mv_sg *mv_sg, *last_sg = NULL;
mv_sg = pp->sg_tbl;
ata_for_each_sg(sg, qc) {
@@ -1159,13 +1147,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
sg_len -= len;
addr += len;
- if (!sg_len && ata_sg_is_last(sg, qc))
- mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
+ last_sg = mv_sg;
mv_sg++;
}
-
}
+
+ if (likely(last_sg))
+ last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
}
static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 40557fe2ffd..240a8920d0b 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -169,6 +169,35 @@ enum {
NV_ADMA_PORT_REGISTER_MODE = (1 << 0),
NV_ADMA_ATAPI_SETUP_COMPLETE = (1 << 1),
+ /* MCP55 reg offset */
+ NV_CTL_MCP55 = 0x400,
+ NV_INT_STATUS_MCP55 = 0x440,
+ NV_INT_ENABLE_MCP55 = 0x444,
+ NV_NCQ_REG_MCP55 = 0x448,
+
+ /* MCP55 */
+ NV_INT_ALL_MCP55 = 0xffff,
+ NV_INT_PORT_SHIFT_MCP55 = 16, /* each port occupies 16 bits */
+ NV_INT_MASK_MCP55 = NV_INT_ALL_MCP55 & 0xfffd,
+
+ /* SWNCQ ENABLE BITS*/
+ NV_CTL_PRI_SWNCQ = 0x02,
+ NV_CTL_SEC_SWNCQ = 0x04,
+
+ /* SW NCQ status bits*/
+ NV_SWNCQ_IRQ_DEV = (1 << 0),
+ NV_SWNCQ_IRQ_PM = (1 << 1),
+ NV_SWNCQ_IRQ_ADDED = (1 << 2),
+ NV_SWNCQ_IRQ_REMOVED = (1 << 3),
+
+ NV_SWNCQ_IRQ_BACKOUT = (1 << 4),
+ NV_SWNCQ_IRQ_SDBFIS = (1 << 5),
+ NV_SWNCQ_IRQ_DHREGFIS = (1 << 6),
+ NV_SWNCQ_IRQ_DMASETUP = (1 << 7),
+
+ NV_SWNCQ_IRQ_HOTPLUG = NV_SWNCQ_IRQ_ADDED |
+ NV_SWNCQ_IRQ_REMOVED,
+
};
/* ADMA Physical Region Descriptor - one SG segment */
@@ -226,6 +255,42 @@ struct nv_host_priv {
unsigned long type;
};
+struct defer_queue {
+ u32 defer_bits;
+ unsigned int head;
+ unsigned int tail;
+ unsigned int tag[ATA_MAX_QUEUE];
+};
+
+enum ncq_saw_flag_list {
+ ncq_saw_d2h = (1U << 0),
+ ncq_saw_dmas = (1U << 1),
+ ncq_saw_sdb = (1U << 2),
+ ncq_saw_backout = (1U << 3),
+};
+
+struct nv_swncq_port_priv {
+ struct ata_prd *prd; /* our SG list */
+ dma_addr_t prd_dma; /* and its DMA mapping */
+ void __iomem *sactive_block;
+ void __iomem *irq_block;
+ void __iomem *tag_block;
+ u32 qc_active;
+
+ unsigned int last_issue_tag;
+
+ /* fifo circular queue to store deferral command */
+ struct defer_queue defer_queue;
+
+ /* for NCQ interrupt analysis */
+ u32 dhfis_bits;
+ u32 dmafis_bits;
+ u32 sdbfis_bits;
+
+ unsigned int ncq_flags;
+};
+
+
#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT)))))
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -263,13 +328,29 @@ static void nv_adma_host_stop(struct ata_host *host);
static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+static void nv_mcp55_thaw(struct ata_port *ap);
+static void nv_mcp55_freeze(struct ata_port *ap);
+static void nv_swncq_error_handler(struct ata_port *ap);
+static int nv_swncq_slave_config(struct scsi_device *sdev);
+static int nv_swncq_port_start(struct ata_port *ap);
+static void nv_swncq_qc_prep(struct ata_queued_cmd *qc);
+static void nv_swncq_fill_sg(struct ata_queued_cmd *qc);
+static unsigned int nv_swncq_qc_issue(struct ata_queued_cmd *qc);
+static void nv_swncq_irq_clear(struct ata_port *ap, u16 fis);
+static irqreturn_t nv_swncq_interrupt(int irq, void *dev_instance);
+#ifdef CONFIG_PM
+static int nv_swncq_port_suspend(struct ata_port *ap, pm_message_t mesg);
+static int nv_swncq_port_resume(struct ata_port *ap);
+#endif
+
enum nv_host_type
{
GENERIC,
NFORCE2,
NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */
CK804,
- ADMA
+ ADMA,
+ SWNCQ,
};
static const struct pci_device_id nv_pci_tbl[] = {
@@ -280,13 +361,13 @@ static const struct pci_device_id nv_pci_tbl[] = {
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), GENERIC },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), GENERIC },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), GENERIC },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), GENERIC },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
- { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), SWNCQ },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), SWNCQ },
{ } /* terminate list */
};
@@ -339,6 +420,25 @@ static struct scsi_host_template nv_adma_sht = {
.bios_param = ata_std_bios_param,
};
+static struct scsi_host_template nv_swncq_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .change_queue_depth = ata_scsi_change_queue_depth,
+ .can_queue = ATA_MAX_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = nv_swncq_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
static const struct ata_port_operations nv_generic_ops = {
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
@@ -444,6 +544,35 @@ static const struct ata_port_operations nv_adma_ops = {
.host_stop = nv_adma_host_stop,
};
+static const struct ata_port_operations nv_swncq_ops = {
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .exec_command = ata_exec_command,
+ .check_status = ata_check_status,
+ .dev_select = ata_std_dev_select,
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+ .qc_defer = ata_std_qc_defer,
+ .qc_prep = nv_swncq_qc_prep,
+ .qc_issue = nv_swncq_qc_issue,
+ .freeze = nv_mcp55_freeze,
+ .thaw = nv_mcp55_thaw,
+ .error_handler = nv_swncq_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .data_xfer = ata_data_xfer,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .scr_read = nv_scr_read,
+ .scr_write = nv_scr_write,
+#ifdef CONFIG_PM
+ .port_suspend = nv_swncq_port_suspend,
+ .port_resume = nv_swncq_port_resume,
+#endif
+ .port_start = nv_swncq_port_start,
+};
+
static const struct ata_port_info nv_port_info[] = {
/* generic */
{
@@ -490,6 +619,18 @@ static const struct ata_port_info nv_port_info[] = {
.port_ops = &nv_adma_ops,
.irq_handler = nv_adma_interrupt,
},
+ /* SWNCQ */
+ {
+ .sht = &nv_swncq_sht,
+ .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_NCQ,
+ .link_flags = ATA_LFLAG_HRST_TO_RESUME,
+ .pio_mask = NV_PIO_MASK,
+ .mwdma_mask = NV_MWDMA_MASK,
+ .udma_mask = NV_UDMA_MASK,
+ .port_ops = &nv_swncq_ops,
+ .irq_handler = nv_swncq_interrupt,
+ },
};
MODULE_AUTHOR("NVIDIA");
@@ -499,6 +640,7 @@ MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
static int adma_enabled = 1;
+static int swncq_enabled;
static void nv_adma_register_mode(struct ata_port *ap)
{
@@ -1452,6 +1594,34 @@ static void nv_ck804_thaw(struct ata_port *ap)
writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
}
+static void nv_mcp55_freeze(struct ata_port *ap)
+{
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
+ int shift = ap->port_no * NV_INT_PORT_SHIFT_MCP55;
+ u32 mask;
+
+ writel(NV_INT_ALL_MCP55 << shift, mmio_base + NV_INT_STATUS_MCP55);
+
+ mask = readl(mmio_base + NV_INT_ENABLE_MCP55);
+ mask &= ~(NV_INT_ALL_MCP55 << shift);
+ writel(mask, mmio_base + NV_INT_ENABLE_MCP55);
+ ata_bmdma_freeze(ap);
+}
+
+static void nv_mcp55_thaw(struct ata_port *ap)
+{
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
+ int shift = ap->port_no * NV_INT_PORT_SHIFT_MCP55;
+ u32 mask;
+
+ writel(NV_INT_ALL_MCP55 << shift, mmio_base + NV_INT_STATUS_MCP55);
+
+ mask = readl(mmio_base + NV_INT_ENABLE_MCP55);
+ mask |= (NV_INT_MASK_MCP55 << shift);
+ writel(mask, mmio_base + NV_INT_ENABLE_MCP55);
+ ata_bmdma_thaw(ap);
+}
+
static int nv_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
@@ -1525,6 +1695,663 @@ static void nv_adma_error_handler(struct ata_port *ap)
nv_hardreset, ata_std_postreset);
}
+static void nv_swncq_qc_to_dq(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ struct defer_queue *dq = &pp->defer_queue;
+
+ /* queue is full */
+ WARN_ON(dq->tail - dq->head == ATA_MAX_QUEUE);
+ dq->defer_bits |= (1 << qc->tag);
+ dq->tag[dq->tail++ & (ATA_MAX_QUEUE - 1)] = qc->tag;
+}
+
+static struct ata_queued_cmd *nv_swncq_qc_from_dq(struct ata_port *ap)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ struct defer_queue *dq = &pp->defer_queue;
+ unsigned int tag;
+
+ if (dq->head == dq->tail) /* null queue */
+ return NULL;
+
+ tag = dq->tag[dq->head & (ATA_MAX_QUEUE - 1)];
+ dq->tag[dq->head++ & (ATA_MAX_QUEUE - 1)] = ATA_TAG_POISON;
+ WARN_ON(!(dq->defer_bits & (1 << tag)));
+ dq->defer_bits &= ~(1 << tag);
+
+ return ata_qc_from_tag(ap, tag);
+}
+
+static void nv_swncq_fis_reinit(struct ata_port *ap)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+
+ pp->dhfis_bits = 0;
+ pp->dmafis_bits = 0;
+ pp->sdbfis_bits = 0;
+ pp->ncq_flags = 0;
+}
+
+static void nv_swncq_pp_reinit(struct ata_port *ap)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ struct defer_queue *dq = &pp->defer_queue;
+
+ dq->head = 0;
+ dq->tail = 0;
+ dq->defer_bits = 0;
+ pp->qc_active = 0;
+ pp->last_issue_tag = ATA_TAG_POISON;
+ nv_swncq_fis_reinit(ap);
+}
+
+static void nv_swncq_irq_clear(struct ata_port *ap, u16 fis)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+
+ writew(fis, pp->irq_block);
+}
+
+static void __ata_bmdma_stop(struct ata_port *ap)
+{
+ struct ata_queued_cmd qc;
+
+ qc.ap = ap;
+ ata_bmdma_stop(&qc);
+}
+
+static void nv_swncq_ncq_stop(struct ata_port *ap)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ unsigned int i;
+ u32 sactive;
+ u32 done_mask;
+
+ ata_port_printk(ap, KERN_ERR,
+ "EH in SWNCQ mode,QC:qc_active 0x%X sactive 0x%X\n",
+ ap->qc_active, ap->link.sactive);
+ ata_port_printk(ap, KERN_ERR,
+ "SWNCQ:qc_active 0x%X defer_bits 0x%X last_issue_tag 0x%x\n "
+ "dhfis 0x%X dmafis 0x%X sdbfis 0x%X\n",
+ pp->qc_active, pp->defer_queue.defer_bits, pp->last_issue_tag,
+ pp->dhfis_bits, pp->dmafis_bits, pp->sdbfis_bits);
+
+ ata_port_printk(ap, KERN_ERR, "ATA_REG 0x%X ERR_REG 0x%X\n",
+ ap->ops->check_status(ap),
+ ioread8(ap->ioaddr.error_addr));
+
+ sactive = readl(pp->sactive_block);
+ done_mask = pp->qc_active ^ sactive;
+
+ ata_port_printk(ap, KERN_ERR, "tag : dhfis dmafis sdbfis sacitve\n");
+ for (i = 0; i < ATA_MAX_QUEUE; i++) {
+ u8 err = 0;
+ if (pp->qc_active & (1 << i))
+ err = 0;
+ else if (done_mask & (1 << i))
+ err = 1;
+ else
+ continue;
+
+ ata_port_printk(ap, KERN_ERR,
+ "tag 0x%x: %01x %01x %01x %01x %s\n", i,
+ (pp->dhfis_bits >> i) & 0x1,
+ (pp->dmafis_bits >> i) & 0x1,
+ (pp->sdbfis_bits >> i) & 0x1,
+ (sactive >> i) & 0x1,
+ (err ? "error! tag doesn't exit" : " "));
+ }
+
+ nv_swncq_pp_reinit(ap);
+ ap->ops->irq_clear(ap);
+ __ata_bmdma_stop(ap);
+ nv_swncq_irq_clear(ap, 0xffff);
+}
+
+static void nv_swncq_error_handler(struct ata_port *ap)
+{
+ struct ata_eh_context *ehc = &ap->link.eh_context;
+
+ if (ap->link.sactive) {
+ nv_swncq_ncq_stop(ap);
+ ehc->i.action |= ATA_EH_HARDRESET;
+ }
+
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
+ nv_hardreset, ata_std_postreset);
+}
+
+#ifdef CONFIG_PM
+static int nv_swncq_port_suspend(struct ata_port *ap, pm_message_t mesg)
+{
+ void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR];
+ u32 tmp;
+
+ /* clear irq */
+ writel(~0, mmio + NV_INT_STATUS_MCP55);
+
+ /* disable irq */
+ writel(0, mmio + NV_INT_ENABLE_MCP55);
+
+ /* disable swncq */
+ tmp = readl(mmio + NV_CTL_MCP55);
+ tmp &= ~(NV_CTL_PRI_SWNCQ | NV_CTL_SEC_SWNCQ);
+ writel(tmp, mmio + NV_CTL_MCP55);
+
+ return 0;
+}
+
+static int nv_swncq_port_resume(struct ata_port *ap)
+{
+ void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR];
+ u32 tmp;
+
+ /* clear irq */
+ writel(~0, mmio + NV_INT_STATUS_MCP55);
+
+ /* enable irq */
+ writel(0x00fd00fd, mmio + NV_INT_ENABLE_MCP55);
+
+ /* enable swncq */
+ tmp = readl(mmio + NV_CTL_MCP55);
+ writel(tmp | NV_CTL_PRI_SWNCQ | NV_CTL_SEC_SWNCQ, mmio + NV_CTL_MCP55);
+
+ return 0;
+}
+#endif
+
+static void nv_swncq_host_init(struct ata_host *host)
+{
+ u32 tmp;
+ void __iomem *mmio = host->iomap[NV_MMIO_BAR];
+ struct pci_dev *pdev = to_pci_dev(host->dev);
+ u8 regval;
+
+ /* disable ECO 398 */
+ pci_read_config_byte(pdev, 0x7f, &regval);
+ regval &= ~(1 << 7);
+ pci_write_config_byte(pdev, 0x7f, regval);
+
+ /* enable swncq */
+ tmp = readl(mmio + NV_CTL_MCP55);
+ VPRINTK("HOST_CTL:0x%X\n", tmp);
+ writel(tmp | NV_CTL_PRI_SWNCQ | NV_CTL_SEC_SWNCQ, mmio + NV_CTL_MCP55);
+
+ /* enable irq intr */
+ tmp = readl(mmio + NV_INT_ENABLE_MCP55);
+ VPRINTK("HOST_ENABLE:0x%X\n", tmp);
+ writel(tmp | 0x00fd00fd, mmio + NV_INT_ENABLE_MCP55);
+
+ /* clear port irq */
+ writel(~0x0, mmio + NV_INT_STATUS_MCP55);
+}
+
+static int nv_swncq_slave_config(struct scsi_device *sdev)
+{
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ struct ata_device *dev;
+ int rc;
+ u8 rev;
+ u8 check_maxtor = 0;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
+
+ rc = ata_scsi_slave_config(sdev);
+ if (sdev->id >= ATA_MAX_DEVICES || sdev->channel || sdev->lun)
+ /* Not a proper libata device, ignore */
+ return rc;
+
+ dev = &ap->link.device[sdev->id];
+ if (!(ap->flags & ATA_FLAG_NCQ) || dev->class == ATA_DEV_ATAPI)
+ return rc;
+
+ /* if MCP51 and Maxtor, then disable ncq */
+ if (pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA ||
+ pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2)
+ check_maxtor = 1;
+
+ /* if MCP55 and rev <= a2 and Maxtor, then disable ncq */
+ if (pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA ||
+ pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2) {
+ pci_read_config_byte(pdev, 0x8, &rev);
+ if (rev <= 0xa2)
+ check_maxtor = 1;
+ }
+
+ if (!check_maxtor)
+ return rc;
+
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
+
+ if (strncmp(model_num, "Maxtor", 6) == 0) {
+ ata_scsi_change_queue_depth(sdev, 1);
+ ata_dev_printk(dev, KERN_NOTICE,
+ "Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth);
+ }
+
+ return rc;
+}
+
+static int nv_swncq_port_start(struct ata_port *ap)
+{
+ struct device *dev = ap->host->dev;
+ void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR];
+ struct nv_swncq_port_priv *pp;
+ int rc;
+
+ rc = ata_port_start(ap);
+ if (rc)
+ return rc;
+
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+
+ pp->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ * ATA_MAX_QUEUE,
+ &pp->prd_dma, GFP_KERNEL);
+ if (!pp->prd)
+ return -ENOMEM;
+ memset(pp->prd, 0, ATA_PRD_TBL_SZ * ATA_MAX_QUEUE);
+
+ ap->private_data = pp;
+ pp->sactive_block = ap->ioaddr.scr_addr + 4 * SCR_ACTIVE;
+ pp->irq_block = mmio + NV_INT_STATUS_MCP55 + ap->port_no * 2;
+ pp->tag_block = mmio + NV_NCQ_REG_MCP55 + ap->port_no * 2;
+
+ return 0;
+}
+
+static void nv_swncq_qc_prep(struct ata_queued_cmd *qc)
+{
+ if (qc->tf.protocol != ATA_PROT_NCQ) {
+ ata_qc_prep(qc);
+ return;
+ }
+
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+ return;
+
+ nv_swncq_fill_sg(qc);
+}
+
+static void nv_swncq_fill_sg(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct scatterlist *sg;
+ unsigned int idx;
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ struct ata_prd *prd;
+
+ WARN_ON(qc->__sg == NULL);
+ WARN_ON(qc->n_elem == 0 && qc->pad_len == 0);
+
+ prd = pp->prd + ATA_MAX_PRD * qc->tag;
+
+ idx = 0;
+ ata_for_each_sg(sg, qc) {
+ u32 addr, offset;
+ u32 sg_len, len;
+
+ addr = (u32)sg_dma_address(sg);
+ sg_len = sg_dma_len(sg);
+
+ while (sg_len) {
+ offset = addr & 0xffff;
+ len = sg_len;
+ if ((offset + sg_len) > 0x10000)
+ len = 0x10000 - offset;
+
+ prd[idx].addr = cpu_to_le32(addr);
+ prd[idx].flags_len = cpu_to_le32(len & 0xffff);
+
+ idx++;
+ sg_len -= len;
+ addr += len;
+ }
+ }
+
+ if (idx)
+ prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
+static unsigned int nv_swncq_issue_atacmd(struct ata_port *ap,
+ struct ata_queued_cmd *qc)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+
+ if (qc == NULL)
+ return 0;
+
+ DPRINTK("Enter\n");
+
+ writel((1 << qc->tag), pp->sactive_block);
+ pp->last_issue_tag = qc->tag;
+ pp->dhfis_bits &= ~(1 << qc->tag);
+ pp->dmafis_bits &= ~(1 << qc->tag);
+ pp->qc_active |= (0x1 << qc->tag);
+
+ ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
+ ap->ops->exec_command(ap, &qc->tf);
+
+ DPRINTK("Issued tag %u\n", qc->tag);
+
+ return 0;
+}
+
+static unsigned int nv_swncq_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct nv_swncq_port_priv *pp = ap->private_data;
+
+ if (qc->tf.protocol != ATA_PROT_NCQ)
+ return ata_qc_issue_prot(qc);
+
+ DPRINTK("Enter\n");
+
+ if (!pp->qc_active)
+ nv_swncq_issue_atacmd(ap, qc);
+ else
+ nv_swncq_qc_to_dq(ap, qc); /* add qc to defer queue */
+
+ return 0;
+}
+
+static void nv_swncq_hotplug(struct ata_port *ap, u32 fis)
+{
+ u32 serror;
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+
+ ata_ehi_clear_desc(ehi);
+
+ /* AHCI needs SError cleared; otherwise, it might lock up */
+ sata_scr_read(&ap->link, SCR_ERROR, &serror);
+ sata_scr_write(&ap->link, SCR_ERROR, serror);
+
+ /* analyze @irq_stat */
+ if (fis & NV_SWNCQ_IRQ_ADDED)
+ ata_ehi_push_desc(ehi, "hot plug");
+ else if (fis & NV_SWNCQ_IRQ_REMOVED)
+ ata_ehi_push_desc(ehi, "hot unplug");
+
+ ata_ehi_hotplugged(ehi);
+
+ /* okay, let's hand over to EH */
+ ehi->serror |= serror;
+
+ ata_port_freeze(ap);
+}
+
+static int nv_swncq_sdbfis(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+ u32 sactive;
+ int nr_done = 0;
+ u32 done_mask;
+ int i;
+ u8 host_stat;
+ u8 lack_dhfis = 0;
+
+ host_stat = ap->ops->bmdma_status(ap);
+ if (unlikely(host_stat & ATA_DMA_ERR)) {
+ /* error when transfering data to/from memory */
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
+ ehi->err_mask |= AC_ERR_HOST_BUS;
+ ehi->action |= ATA_EH_SOFTRESET;
+ return -EINVAL;
+ }
+
+ ap->ops->irq_clear(ap);
+ __ata_bmdma_stop(ap);
+
+ sactive = readl(pp->sactive_block);
+ done_mask = pp->qc_active ^ sactive;
+
+ if (unlikely(done_mask & sactive)) {
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition"
+ "(%08x->%08x)", pp->qc_active, sactive);
+ ehi->err_mask |= AC_ERR_HSM;
+ ehi->action |= ATA_EH_HARDRESET;
+ return -EINVAL;
+ }
+ for (i = 0; i < ATA_MAX_QUEUE; i++) {
+ if (!(done_mask & (1 << i)))
+ continue;
+
+ qc = ata_qc_from_tag(ap, i);
+ if (qc) {
+ ata_qc_complete(qc);
+ pp->qc_active &= ~(1 << i);
+ pp->dhfis_bits &= ~(1 << i);
+ pp->dmafis_bits &= ~(1 << i);
+ pp->sdbfis_bits |= (1 << i);
+ nr_done++;
+ }
+ }
+
+ if (!ap->qc_active) {
+ DPRINTK("over\n");
+ nv_swncq_pp_reinit(ap);
+ return nr_done;
+ }
+
+ if (pp->qc_active & pp->dhfis_bits)
+ return nr_done;
+
+ if ((pp->ncq_flags & ncq_saw_backout) ||
+ (pp->qc_active ^ pp->dhfis_bits))
+ /* if the controller cann't get a device to host register FIS,
+ * The driver needs to reissue the new command.
+ */
+ lack_dhfis = 1;
+
+ DPRINTK("id 0x%x QC: qc_active 0x%x,"
+ "SWNCQ:qc_active 0x%X defer_bits %X "
+ "dhfis 0x%X dmafis 0x%X last_issue_tag %x\n",
+ ap->print_id, ap->qc_active, pp->qc_active,
+ pp->defer_queue.defer_bits, pp->dhfis_bits,
+ pp->dmafis_bits, pp->last_issue_tag);
+
+ nv_swncq_fis_reinit(ap);
+
+ if (lack_dhfis) {
+ qc = ata_qc_from_tag(ap, pp->last_issue_tag);
+ nv_swncq_issue_atacmd(ap, qc);
+ return nr_done;
+ }
+
+ if (pp->defer_queue.defer_bits) {
+ /* send deferral queue command */
+ qc = nv_swncq_qc_from_dq(ap);
+ WARN_ON(qc == NULL);
+ nv_swncq_issue_atacmd(ap, qc);
+ }
+
+ return nr_done;
+}
+
+static inline u32 nv_swncq_tag(struct ata_port *ap)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ u32 tag;
+
+ tag = readb(pp->tag_block) >> 2;
+ return (tag & 0x1f);
+}
+
+static int nv_swncq_dmafis(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+ unsigned int rw;
+ u8 dmactl;
+ u32 tag;
+ struct nv_swncq_port_priv *pp = ap->private_data;
+
+ __ata_bmdma_stop(ap);
+ tag = nv_swncq_tag(ap);
+
+ DPRINTK("dma setup tag 0x%x\n", tag);
+ qc = ata_qc_from_tag(ap, tag);
+
+ if (unlikely(!qc))
+ return 0;
+
+ rw = qc->tf.flags & ATA_TFLAG_WRITE;
+
+ /* load PRD table addr. */
+ iowrite32(pp->prd_dma + ATA_PRD_TBL_SZ * qc->tag,
+ ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+
+ /* specify data direction, triple-check start bit is clear */
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl &= ~ATA_DMA_WR;
+ if (!rw)
+ dmactl |= ATA_DMA_WR;
+
+ iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+
+ return 1;
+}
+
+static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
+{
+ struct nv_swncq_port_priv *pp = ap->private_data;
+ struct ata_queued_cmd *qc;
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+ u32 serror;
+ u8 ata_stat;
+ int rc = 0;
+
+ ata_stat = ap->ops->check_status(ap);
+ nv_swncq_irq_clear(ap, fis);
+ if (!fis)
+ return;
+
+ if (ap->pflags & ATA_PFLAG_FROZEN)
+ return;
+
+ if (fis & NV_SWNCQ_IRQ_HOTPLUG) {
+ nv_swncq_hotplug(ap, fis);
+ return;
+ }
+
+ if (!pp->qc_active)
+ return;
+
+ if (ap->ops->scr_read(ap, SCR_ERROR, &serror))
+ return;
+ ap->ops->scr_write(ap, SCR_ERROR, serror);
+
+ if (ata_stat & ATA_ERR) {
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "Ata error. fis:0x%X", fis);
+ ehi->err_mask |= AC_ERR_DEV;
+ ehi->serror |= serror;
+ ehi->action |= ATA_EH_SOFTRESET;
+ ata_port_freeze(ap);
+ return;
+ }
+
+ if (fis & NV_SWNCQ_IRQ_BACKOUT) {
+ /* If the IRQ is backout, driver must issue
+ * the new command again some time later.
+ */
+ pp->ncq_flags |= ncq_saw_backout;
+ }
+
+ if (fis & NV_SWNCQ_IRQ_SDBFIS) {
+ pp->ncq_flags |= ncq_saw_sdb;
+ DPRINTK("id 0x%x SWNCQ: qc_active 0x%X "
+ "dhfis 0x%X dmafis 0x%X sactive 0x%X\n",
+ ap->print_id, pp->qc_active, pp->dhfis_bits,
+ pp->dmafis_bits, readl(pp->sactive_block));
+ rc = nv_swncq_sdbfis(ap);
+ if (rc < 0)
+ goto irq_error;
+ }
+
+ if (fis & NV_SWNCQ_IRQ_DHREGFIS) {
+ /* The interrupt indicates the new command
+ * was transmitted correctly to the drive.
+ */
+ pp->dhfis_bits |= (0x1 << pp->last_issue_tag);
+ pp->ncq_flags |= ncq_saw_d2h;
+ if (pp->ncq_flags & (ncq_saw_sdb | ncq_saw_backout)) {
+ ata_ehi_push_desc(ehi, "illegal fis transaction");
+ ehi->err_mask |= AC_ERR_HSM;
+ ehi->action |= ATA_EH_HARDRESET;
+ goto irq_error;
+ }
+
+ if (!(fis & NV_SWNCQ_IRQ_DMASETUP) &&
+ !(pp->ncq_flags & ncq_saw_dmas)) {
+ ata_stat = ap->ops->check_status(ap);
+ if (ata_stat & ATA_BUSY)
+ goto irq_exit;
+
+ if (pp->defer_queue.defer_bits) {
+ DPRINTK("send next command\n");
+ qc = nv_swncq_qc_from_dq(ap);
+ nv_swncq_issue_atacmd(ap, qc);
+ }
+ }
+ }
+
+ if (fis & NV_SWNCQ_IRQ_DMASETUP) {
+ /* program the dma controller with appropriate PRD buffers
+ * and start the DMA transfer for requested command.
+ */
+ pp->dmafis_bits |= (0x1 << nv_swncq_tag(ap));
+ pp->ncq_flags |= ncq_saw_dmas;
+ rc = nv_swncq_dmafis(ap);
+ }
+
+irq_exit:
+ return;
+irq_error:
+ ata_ehi_push_desc(ehi, "fis:0x%x", fis);
+ ata_port_freeze(ap);
+ return;
+}
+
+static irqreturn_t nv_swncq_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ unsigned int i;
+ unsigned int handled = 0;
+ unsigned long flags;
+ u32 irq_stat;
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ irq_stat = readl(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_MCP55);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
+ if (ap->link.sactive) {
+ nv_swncq_host_interrupt(ap, (u16)irq_stat);
+ handled = 1;
+ } else {
+ if (irq_stat) /* reserve Hotplug */
+ nv_swncq_irq_clear(ap, 0xfff0);
+
+ handled += nv_host_intr(ap, (u8)irq_stat);
+ }
+ }
+ irq_stat >>= NV_INT_PORT_SHIFT_MCP55;
+ }
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
@@ -1551,7 +2378,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
/* determine type and allocate host */
- if (type >= CK804 && adma_enabled) {
+ if (type == CK804 && adma_enabled) {
dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
type = ADMA;
}
@@ -1597,6 +2424,9 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
rc = nv_adma_host_init(host);
if (rc)
return rc;
+ } else if (type == SWNCQ && swncq_enabled) {
+ dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n");
+ nv_swncq_host_init(host);
}
pci_set_master(pdev);
@@ -1696,3 +2526,6 @@ module_init(nv_init);
module_exit(nv_exit);
module_param_named(adma, adma_enabled, bool, 0444);
MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)");
+module_param_named(swncq, swncq_enabled, bool, 0444);
+MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: false)");
+
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index b0619278454..26ebffc10f3 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -796,16 +796,19 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
struct sil24_sge *sge)
{
struct scatterlist *sg;
+ struct sil24_sge *last_sge = NULL;
ata_for_each_sg(sg, qc) {
sge->addr = cpu_to_le64(sg_dma_address(sg));
sge->cnt = cpu_to_le32(sg_dma_len(sg));
- if (ata_sg_is_last(sg, qc))
- sge->flags = cpu_to_le32(SGE_TRM);
- else
- sge->flags = 0;
+ sge->flags = 0;
+
+ last_sge = sge;
sge++;
}
+
+ if (likely(last_sge))
+ last_sge->flags = cpu_to_le32(SGE_TRM);
}
static int sil24_qc_defer(struct ata_queued_cmd *qc)
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index 1b16f8166b0..e4fa9965869 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -41,7 +41,7 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
# guess the target endianess to choose the right PCA-200E firmware image
ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h
- CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) $(CPPFLAGS) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
+ CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) $(KBUILD_CPPFLAGS) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
endif
endif
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index 7647abfe189..5beddc322e6 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -302,7 +302,7 @@ restart:
if (mem_flags & __GFP_WAIT) {
DECLARE_WAITQUEUE (wait, current);
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue (&pool->waitq, &wait);
spin_unlock_irqrestore (&pool->lock, flags);
@@ -366,7 +366,7 @@ dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma)
unsigned long flags;
int map, block;
- if ((page = pool_find_page (pool, dma)) == 0) {
+ if ((page = pool_find_page(pool, dma)) == NULL) {
if (pool->dev)
dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n",
pool->name, vaddr, (unsigned long) dma);
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7a1390cd6aa..c41d0728efe 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -238,7 +238,7 @@ store_mem_state(struct sys_device *dev, const char *buf, size_t count)
mem = container_of(dev, struct memory_block, sysdev);
phys_section_nr = mem->phys_index;
- if (!valid_section_nr(phys_section_nr))
+ if (!present_section_nr(phys_section_nr))
goto out;
if (!strncmp(buf, "online", min((int)count, 6)))
@@ -418,7 +418,7 @@ int register_new_memory(struct mem_section *section)
int unregister_memory_section(struct mem_section *section)
{
- if (!valid_section(section))
+ if (!present_section(section))
return -EINVAL;
return remove_memory_block(0, section, 0);
@@ -443,7 +443,7 @@ int __init memory_dev_init(void)
* during boot and have been initialized
*/
for (i = 0; i < NR_MEM_SECTIONS; i++) {
- if (!valid_section_nr(i))
+ if (!present_section_nr(i))
continue;
err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
if (!ret)
diff --git a/drivers/base/node.c b/drivers/base/node.c
index cae346ef1b2..88eeed72b5d 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -12,6 +12,7 @@
#include <linux/topology.h>
#include <linux/nodemask.h>
#include <linux/cpu.h>
+#include <linux/device.h>
static struct sysdev_class node_class = {
set_kset_name("node"),
@@ -232,8 +233,96 @@ void unregister_one_node(int nid)
unregister_node(&node_devices[nid]);
}
+/*
+ * node states attributes
+ */
+
+static ssize_t print_nodes_state(enum node_states state, char *buf)
+{
+ int n;
+
+ n = nodelist_scnprintf(buf, PAGE_SIZE, node_states[state]);
+ if (n > 0 && PAGE_SIZE > n + 1) {
+ *(buf + n++) = '\n';
+ *(buf + n++) = '\0';
+ }
+ return n;
+}
+
+static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf)
+{
+ return print_nodes_state(N_POSSIBLE, buf);
+}
+
+static ssize_t print_nodes_online(struct sysdev_class *class, char *buf)
+{
+ return print_nodes_state(N_ONLINE, buf);
+}
+
+static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class,
+ char *buf)
+{
+ return print_nodes_state(N_NORMAL_MEMORY, buf);
+}
+
+static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf)
+{
+ return print_nodes_state(N_CPU, buf);
+}
+
+static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
+static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
+static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
+ NULL);
+static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
+
+#ifdef CONFIG_HIGHMEM
+static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
+ char *buf)
+{
+ return print_nodes_state(N_HIGH_MEMORY, buf);
+}
+
+static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
+ NULL);
+#endif
+
+struct sysdev_class_attribute *node_state_attr[] = {
+ &attr_possible,
+ &attr_online,
+ &attr_has_normal_memory,
+#ifdef CONFIG_HIGHMEM
+ &attr_has_high_memory,
+#endif
+ &attr_has_cpu,
+};
+
+static int node_states_init(void)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < NR_NODE_STATES; i++) {
+ int ret;
+ ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
+ if (!err)
+ err = ret;
+ }
+ return err;
+}
+
static int __init register_node_type(void)
{
- return sysdev_class_register(&node_class);
+ int ret;
+
+ ret = sysdev_class_register(&node_class);
+ if (!ret)
+ ret = node_states_init();
+
+ /*
+ * Note: we're not going to unregister the node class if we fail
+ * to register the node state class attribute files.
+ */
+ return ret;
}
postcore_initcall(register_node_type);
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
index 2b0c601e422..2b4b392dcbc 100644
--- a/drivers/base/power/trace.c
+++ b/drivers/base/power/trace.c
@@ -114,7 +114,7 @@ static unsigned int read_magic_time(void)
get_rtc_time(&time);
printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n",
time.tm_hour, time.tm_min, time.tm_sec,
- time.tm_mon, time.tm_mday, time.tm_year);
+ time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
val = time.tm_year; /* 100 years */
if (val > 100)
val -= 100;
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 8d8cdfec652..e1d3ad4db2f 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -94,27 +94,18 @@ static struct attribute_group topology_attr_group = {
.name = "topology"
};
-static cpumask_t topology_dev_map = CPU_MASK_NONE;
-
/* Add/Remove cpu_topology interface for CPU device */
static int __cpuinit topology_add_dev(unsigned int cpu)
{
- int rc;
struct sys_device *sys_dev = get_cpu_sysdev(cpu);
- rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
- if (!rc)
- cpu_set(cpu, topology_dev_map);
- return rc;
+ return sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
}
static void __cpuinit topology_remove_dev(unsigned int cpu)
{
struct sys_device *sys_dev = get_cpu_sysdev(cpu);
- if (!cpu_isset(cpu, topology_dev_map))
- return;
- cpu_clear(cpu, topology_dev_map);
sysfs_remove_group(&sys_dev->kobj, &topology_attr_group);
}
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index ba07f762c4c..07f02f855ab 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -48,15 +48,6 @@ struct aoe_hdr {
__be32 tag;
};
-#ifdef __KERNEL__
-#include <linux/skbuff.h>
-
-static inline struct aoe_hdr *aoe_hdr(const struct sk_buff *skb)
-{
- return (struct aoe_hdr *)skb_mac_header(skb);
-}
-#endif
-
struct aoe_atahdr {
unsigned char aflags;
unsigned char errfeat;
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 99672017ca5..4d59d505773 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -120,7 +120,7 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
/* initialize the headers & frame */
skb = f->skb;
- h = aoe_hdr(skb);
+ h = (struct aoe_hdr *) skb_mac_header(skb);
ah = (struct aoe_atahdr *) (h+1);
skb_put(skb, sizeof *h + sizeof *ah);
memset(h, 0, skb->len);
@@ -209,7 +209,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
skb->dev = ifp;
if (sl_tail == NULL)
sl_tail = skb;
- h = aoe_hdr(skb);
+ h = (struct aoe_hdr *) skb_mac_header(skb);
memset(h, 0, sizeof *h + sizeof *ch);
memset(h->dst, 0xff, sizeof h->dst);
@@ -304,7 +304,7 @@ rexmit(struct aoedev *d, struct frame *f)
aoechr_error(buf);
skb = f->skb;
- h = aoe_hdr(skb);
+ h = (struct aoe_hdr *) skb_mac_header(skb);
ah = (struct aoe_atahdr *) (h+1);
f->tag = n;
h->tag = cpu_to_be32(n);
@@ -533,7 +533,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
char ebuf[128];
u16 aoemajor;
- hin = aoe_hdr(skb);
+ hin = (struct aoe_hdr *) skb_mac_header(skb);
aoemajor = be16_to_cpu(get_unaligned(&hin->major));
d = aoedev_by_aoeaddr(aoemajor, hin->minor);
if (d == NULL) {
@@ -565,7 +565,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
calc_rttavg(d, tsince(f->tag));
ahin = (struct aoe_atahdr *) (hin+1);
- hout = aoe_hdr(f->skb);
+ hout = (struct aoe_hdr *) skb_mac_header(f->skb);
ahout = (struct aoe_atahdr *) (hout+1);
buf = f->buf;
@@ -699,7 +699,7 @@ aoecmd_ata_id(struct aoedev *d)
/* initialize the headers & frame */
skb = f->skb;
- h = aoe_hdr(skb);
+ h = (struct aoe_hdr *) skb_mac_header(skb);
ah = (struct aoe_atahdr *) (h+1);
skb_put(skb, sizeof *h + sizeof *ah);
memset(h, 0, skb->len);
@@ -730,7 +730,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
enum { MAXFRAMES = 16 };
u16 n;
- h = aoe_hdr(skb);
+ h = (struct aoe_hdr *) skb_mac_header(skb);
ch = (struct aoe_cfghdr *) (h+1);
/*
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index 4dc0fb7da94..4e6deb7f5c2 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -127,7 +127,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
goto exit;
skb_push(skb, ETH_HLEN); /* (1) */
- h = aoe_hdr(skb);
+ h = (struct aoe_hdr *) skb_mac_header(skb);
n = be32_to_cpu(get_unaligned(&h->tag));
if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
goto exit;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 55c3237fb1b..7c2cfde08f1 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1191,7 +1191,6 @@ static inline void complete_buffers(struct bio *bio, int status)
{
while (bio) {
struct bio *xbh = bio->bi_next;
- int nr_sectors = bio_sectors(bio);
bio->bi_next = NULL;
bio_endio(bio, status ? 0 : -EIO);
@@ -1583,38 +1582,36 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
* allows us to delete disk zero but keep the controller registered.
*/
if (h->gendisk[0] != disk) {
- if (disk) {
- struct request_queue *q = disk->queue;
- if (disk->flags & GENHD_FL_UP)
- del_gendisk(disk);
- if (q) {
- blk_cleanup_queue(q);
- /* Set drv->queue to NULL so that we do not try
- * to call blk_start_queue on this queue in the
- * interrupt handler
- */
- drv->queue = NULL;
- }
- /* If clear_all is set then we are deleting the logical
- * drive, not just refreshing its info. For drives
- * other than disk 0 we will call put_disk. We do not
- * do this for disk 0 as we need it to be able to
- * configure the controller.
+ struct request_queue *q = disk->queue;
+ if (disk->flags & GENHD_FL_UP)
+ del_gendisk(disk);
+ if (q) {
+ blk_cleanup_queue(q);
+ /* Set drv->queue to NULL so that we do not try
+ * to call blk_start_queue on this queue in the
+ * interrupt handler
+ */
+ drv->queue = NULL;
+ }
+ /* If clear_all is set then we are deleting the logical
+ * drive, not just refreshing its info. For drives
+ * other than disk 0 we will call put_disk. We do not
+ * do this for disk 0 as we need it to be able to
+ * configure the controller.
+ */
+ if (clear_all){
+ /* This isn't pretty, but we need to find the
+ * disk in our array and NULL our the pointer.
+ * This is so that we will call alloc_disk if
+ * this index is used again later.
*/
- if (clear_all){
- /* This isn't pretty, but we need to find the
- * disk in our array and NULL our the pointer.
- * This is so that we will call alloc_disk if
- * this index is used again later.
- */
- for (i=0; i < CISS_MAX_LUN; i++){
- if(h->gendisk[i] == disk){
- h->gendisk[i] = NULL;
- break;
- }
+ for (i=0; i < CISS_MAX_LUN; i++){
+ if(h->gendisk[i] == disk){
+ h->gendisk[i] = NULL;
+ break;
}
- put_disk(disk);
}
+ put_disk(disk);
}
} else {
set_capacity(disk, 0);
@@ -2366,30 +2363,55 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
start_io(h);
}
+static inline unsigned int make_status_bytes(unsigned int scsi_status_byte,
+ unsigned int msg_byte, unsigned int host_byte,
+ unsigned int driver_byte)
+{
+ /* inverse of macros in scsi.h */
+ return (scsi_status_byte & 0xff) |
+ ((msg_byte & 0xff) << 8) |
+ ((host_byte & 0xff) << 16) |
+ ((driver_byte & 0xff) << 24);
+}
+
static inline int evaluate_target_status(CommandList_struct *cmd)
{
unsigned char sense_key;
- int error_count = 1;
+ unsigned char status_byte, msg_byte, host_byte, driver_byte;
+ int error_value;
+
+ /* If we get in here, it means we got "target status", that is, scsi status */
+ status_byte = cmd->err_info->ScsiStatus;
+ driver_byte = DRIVER_OK;
+ msg_byte = cmd->err_info->CommandStatus; /* correct? seems too device specific */
+
+ if (blk_pc_request(cmd->rq))
+ host_byte = DID_PASSTHROUGH;
+ else
+ host_byte = DID_OK;
+
+ error_value = make_status_bytes(status_byte, msg_byte,
+ host_byte, driver_byte);
- if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */
+ if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) {
if (!blk_pc_request(cmd->rq))
printk(KERN_WARNING "cciss: cmd %p "
"has SCSI Status 0x%x\n",
cmd, cmd->err_info->ScsiStatus);
- return error_count;
+ return error_value;
}
/* check the sense key */
sense_key = 0xf & cmd->err_info->SenseInfo[2];
/* no status or recovered error */
- if ((sense_key == 0x0) || (sense_key == 0x1))
- error_count = 0;
+ if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq))
+ error_value = 0;
if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
- if (error_count != 0)
+ if (error_value != 0)
printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
" sense key = 0x%x\n", cmd, sense_key);
- return error_count;
+ return error_value;
}
/* SG_IO or similar, copy sense data back */
@@ -2401,7 +2423,7 @@ static inline int evaluate_target_status(CommandList_struct *cmd)
} else
cmd->rq->sense_len = 0;
- return error_count;
+ return error_value;
}
/* checks the status of the job and calls complete buffers to mark all
@@ -2417,7 +2439,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
rq->errors = 0;
if (timeout)
- rq->errors = 1;
+ rq->errors = make_status_bytes(0, 0, 0, DRIVER_TIMEOUT);
if (cmd->err_info->CommandStatus == 0) /* no error has occurred */
goto after_error_processing;
@@ -2443,32 +2465,44 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
case CMD_INVALID:
printk(KERN_WARNING "cciss: cmd %p is "
"reported invalid\n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
break;
case CMD_PROTOCOL_ERR:
printk(KERN_WARNING "cciss: cmd %p has "
"protocol error \n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
break;
case CMD_HARDWARE_ERR:
printk(KERN_WARNING "cciss: cmd %p had "
" hardware error\n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
break;
case CMD_CONNECTION_LOST:
printk(KERN_WARNING "cciss: cmd %p had "
"connection lost\n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
break;
case CMD_ABORTED:
printk(KERN_WARNING "cciss: cmd %p was "
"aborted\n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT);
break;
case CMD_ABORT_FAILED:
printk(KERN_WARNING "cciss: cmd %p reports "
"abort failed\n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
break;
case CMD_UNSOLICITED_ABORT:
printk(KERN_WARNING "cciss%d: unsolicited "
@@ -2482,17 +2516,23 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
printk(KERN_WARNING
"cciss%d: %p retried too "
"many times\n", h->ctlr, cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT);
break;
case CMD_TIMEOUT:
printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
break;
default:
printk(KERN_WARNING "cciss: cmd %p returned "
"unknown status %x\n", cmd,
cmd->err_info->CommandStatus);
- rq->errors = 1;
+ rq->errors = make_status_bytes(SAM_STAT_GOOD,
+ cmd->err_info->CommandStatus, DRIVER_OK,
+ blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR);
}
after_error_processing:
@@ -2570,6 +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));
seg = blk_rq_map_sg(q, creq, tmp_sg);
/* get the DMA records for the setup */
@@ -3035,15 +3076,20 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
}
#endif
- /* Disabling DMA prefetch for the P600
- * An ASIC bug may result in a prefetch beyond
- * physical memory.
+ /* Disabling DMA prefetch and refetch for the P600.
+ * An ASIC bug may result in accesses to invalid memory addresses.
+ * We've disabled prefetch for some time now. Testing with XEN
+ * kernels revealed a bug in the refetch if dom0 resides on a P600.
*/
if(board_id == 0x3225103C) {
__u32 dma_prefetch;
+ __u32 dma_refetch;
dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG);
dma_prefetch |= 0x8000;
writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG);
+ pci_read_config_dword(pdev, PCI_COMMAND_PARITY, &dma_refetch);
+ dma_refetch |= 0x1;
+ pci_write_config_dword(pdev, PCI_COMMAND_PARITY, dma_refetch);
}
#ifdef CCISS_DEBUG
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 3853c9a38d6..568603d3043 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -981,9 +981,8 @@ static void start_io(ctlr_info_t *h)
static inline void complete_buffers(struct bio *bio, int ok)
{
struct bio *xbh;
- while(bio) {
- int nr_sectors = bio_sectors(bio);
+ while (bio) {
xbh = bio->bi_next;
bio->bi_next = NULL;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 80483aac4cc..639ed14bb08 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -5,6 +5,7 @@
* Copyright (C) 1993, 1994 Alain Knaff
* Copyright (C) 1998 Alan Cox
*/
+
/*
* 02.12.91 - Changed to static variables to indicate need for reset
* and recalibrate. This makes some things easier (output_byte reset
@@ -149,7 +150,7 @@
#define REALLY_SLOW_IO
#define DEBUGT 2
-#define DCL_DEBUG /* debug disk change line */
+#define DCL_DEBUG /* debug disk change line */
/* do print messages for unexpected interrupts */
static int print_unex = 1;
@@ -161,10 +162,8 @@ static int print_unex = 1;
#include <linux/workqueue.h>
#define FDPATCHES
#include <linux/fdreg.h>
-
#include <linux/fd.h>
#include <linux/hdreg.h>
-
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/mm.h>
@@ -274,8 +273,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l)
return; /* we have the memory */
if (can_use_virtual_dma != 2)
return; /* no fallback allowed */
- printk
- ("DMA memory shortage. Temporarily falling back on virtual DMA\n");
+ printk("DMA memory shortage. Temporarily falling back on virtual DMA\n");
*addr = (char *)nodma_mem_alloc(l);
#else
return;
@@ -291,8 +289,8 @@ static int initialising = 1;
#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
#define UNIT(x) ((x) & 0x03) /* drive on fdc */
#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */
+ /* reverse mapping from unit and fdc to drive */
#define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2))
- /* reverse mapping from unit and fdc to drive */
#define DP (&drive_params[current_drive])
#define DRS (&drive_state[current_drive])
#define DRWE (&write_errors[current_drive])
@@ -356,7 +354,6 @@ static int inr; /* size of reply buffer, when called from interrupt */
#define R_HEAD (reply_buffer[4])
#define R_SECTOR (reply_buffer[5])
#define R_SIZECODE (reply_buffer[6])
-
#define SEL_DLY (2*HZ/100)
/*
@@ -472,8 +469,8 @@ static struct floppy_struct floppy_type[32] = {
{ 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5" */
{ 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5" */
{ 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5" */
-
{ 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5" */
+
{ 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */
{ 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */
};
@@ -539,12 +536,12 @@ static char *floppy_track_buffer;
static int max_buffer_sectors;
static int *errors;
-typedef void (*done_f) (int);
+typedef void (*done_f)(int);
static struct cont_t {
- void (*interrupt) (void); /* this is called after the interrupt of the
+ void (*interrupt)(void); /* this is called after the interrupt of the
* main command */
- void (*redo) (void); /* this is called to retry the operation */
- void (*error) (void); /* this is called to tally an error */
+ void (*redo)(void); /* this is called to retry the operation */
+ void (*error)(void); /* this is called to tally an error */
done_f done; /* this is called to say if the operation has
* succeeded/failed */
} *cont;
@@ -694,7 +691,6 @@ static void reschedule_timeout(int drive, const char *message, int marg)
}
#define INFBOUND(a,b) (a)=max_t(int, a, b)
-
#define SUPBOUND(a,b) (a)=min_t(int, a, b)
/*
@@ -733,6 +729,7 @@ static void reschedule_timeout(int drive, const char *message, int marg)
static int disk_change(int drive)
{
int fdc = FDC(drive);
+
#ifdef FLOPPY_SANITY_CHECK
if (time_before(jiffies, UDRS->select_date + UDP->select_delay))
DPRINT("WARNING disk change called early\n");
@@ -771,7 +768,6 @@ static int disk_change(int drive)
floppy_sizes[TOMINOR(drive)] = MAX_DISK_SIZE << 1;
}
- /*USETF(FD_DISK_NEWCHANGE); */
return 1;
} else {
UDRS->last_checked = jiffies;
@@ -787,7 +783,10 @@ static inline int is_selected(int dor, int unit)
static int set_dor(int fdc, char mask, char data)
{
- register unsigned char drive, unit, newdor, olddor;
+ unsigned char unit;
+ unsigned char drive;
+ unsigned char newdor;
+ unsigned char olddor;
if (FDCS->address == -1)
return -1;
@@ -892,7 +891,6 @@ static int _lock_fdc(int drive, int interruptible, int line)
set_current_state(TASK_RUNNING);
remove_wait_queue(&fdc_wait, &wait);
-
flush_scheduled_work();
}
command_status = FD_COMMAND_NONE;
@@ -942,7 +940,7 @@ static void motor_off_callback(unsigned long nr)
static void floppy_off(unsigned int drive)
{
unsigned long volatile delta;
- register int fdc = FDC(drive);
+ int fdc = FDC(drive);
if (!(FDCS->dor & (0x10 << UNIT(drive))))
return;
@@ -968,7 +966,9 @@ static void floppy_off(unsigned int drive)
*/
static void scandrives(void)
{
- int i, drive, saved_drive;
+ int i;
+ int drive;
+ int saved_drive;
if (DP->select_delay)
return;
@@ -1146,7 +1146,9 @@ static void show_floppy(void);
/* waits until the fdc becomes ready */
static int wait_til_ready(void)
{
- int counter, status;
+ int status;
+ int counter;
+
if (FDCS->reset)
return -1;
for (counter = 0; counter < 10000; counter++) {
@@ -1193,7 +1195,8 @@ static int output_byte(char byte)
/* gets the response from the fdc */
static int result(void)
{
- int i, status = 0;
+ int i;
+ int status = 0;
for (i = 0; i < MAX_REPLIES; i++) {
if ((status = wait_til_ready()) < 0)
@@ -1226,6 +1229,7 @@ static int result(void)
static int need_more_output(void)
{
int status;
+
if ((status = wait_til_ready()) < 0)
return -1;
if ((status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
@@ -1309,8 +1313,11 @@ static int fdc_configure(void)
*/
static void fdc_specify(void)
{
- unsigned char spec1, spec2;
- unsigned long srt, hlt, hut;
+ unsigned char spec1;
+ unsigned char spec2;
+ unsigned long srt;
+ unsigned long hlt;
+ unsigned long hut;
unsigned long dtr = NOMINAL_DTR;
unsigned long scale_dtr = NOMINAL_DTR;
int hlt_max_code = 0x7f;
@@ -1319,7 +1326,6 @@ static void fdc_specify(void)
if (FDCS->need_configure && FDCS->version >= FDC_82072A) {
fdc_configure();
FDCS->need_configure = 0;
- /*DPRINT("FIFO enabled\n"); */
}
switch (raw_cmd->rate & 0x03) {
@@ -1472,7 +1478,6 @@ static int interpret_errors(void)
tell_sector();
}
printk("\n");
-
}
if (ST2 & ST2_WC || ST2 & ST2_BC)
/* wrong cylinder => recal */
@@ -1498,7 +1503,10 @@ static int interpret_errors(void)
*/
static void setup_rw_floppy(void)
{
- int i, r, flags, dflags;
+ int i;
+ int r;
+ int flags;
+ int dflags;
unsigned long ready_date;
timeout_fn function;
@@ -1728,9 +1736,9 @@ static void print_result(char *message, int inr)
/* interrupt handler. Note that this can be called externally on the Sparc */
irqreturn_t floppy_interrupt(int irq, void *dev_id)
{
- void (*handler) (void) = do_floppy;
int do_print;
unsigned long f;
+ void (*handler)(void) = do_floppy;
lasthandler = handler;
interruptjiffies = jiffies;
@@ -1912,12 +1920,11 @@ static void floppy_shutdown(unsigned long data)
is_alive("floppy shutdown");
}
-/*typedef void (*timeout_fn)(unsigned long);*/
-
/* start motor, check media-changed condition and write protection */
-static int start_motor(void (*function) (void))
+static int start_motor(void (*function)(void))
{
- int mask, data;
+ int mask;
+ int data;
mask = 0xfc;
data = UNIT(current_drive);
@@ -2020,17 +2027,17 @@ static struct cont_t wakeup_cont = {
.interrupt = empty,
.redo = do_wakeup,
.error = empty,
- .done = (done_f) empty
+ .done = (done_f)empty
};
static struct cont_t intr_cont = {
.interrupt = empty,
.redo = process_fd_request,
.error = empty,
- .done = (done_f) empty
+ .done = (done_f)empty
};
-static int wait_til_done(void (*handler) (void), int interruptible)
+static int wait_til_done(void (*handler)(void), int interruptible)
{
int ret;
@@ -2049,7 +2056,6 @@ static int wait_til_done(void (*handler) (void), int interruptible)
break;
is_alive("wait_til_done");
-
schedule();
}
@@ -2141,6 +2147,7 @@ static void bad_flp_intr(void)
static void set_floppy(int drive)
{
int type = ITYPE(UDRS->fd_device);
+
if (type)
_floppy = floppy_type + type;
else
@@ -2169,11 +2176,14 @@ static void format_interrupt(void)
#define CT(x) ((x) | 0xc0)
static void setup_format_params(int track)
{
+ int n;
+ int il;
+ int count;
+ int head_shift;
+ int track_shift;
struct fparm {
unsigned char track, head, sect, size;
} *here = (struct fparm *)floppy_track_buffer;
- int il, n;
- int count, head_shift, track_shift;
raw_cmd = &default_raw_cmd;
raw_cmd->track = track;
@@ -2344,7 +2354,10 @@ static void request_done(int uptodate)
/* Interrupt handler evaluating the result of the r/w operation */
static void rw_interrupt(void)
{
- int nr_sectors, ssize, eoc, heads;
+ int eoc;
+ int ssize;
+ int heads;
+ int nr_sectors;
if (R_HEAD >= 2) {
/* some Toshiba floppy controllers occasionnally seem to
@@ -2476,7 +2489,8 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
{
int remaining; /* number of transferred 512-byte sectors */
struct bio_vec *bv;
- char *buffer, *dma_buffer;
+ char *buffer;
+ char *dma_buffer;
int size;
struct req_iterator iter;
@@ -2556,19 +2570,6 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
#endif
}
-#if 0
-static inline int check_dma_crossing(char *start,
- unsigned long length, char *message)
-{
- if (CROSS_64KB(start, length)) {
- printk("DMA xfer crosses 64KB boundary in %s %p-%p\n",
- message, start, start + length);
- return 1;
- } else
- return 0;
-}
-#endif
-
/* work around a bug in pseudo DMA
* (on some FDCs) pseudo DMA does not stop when the CPU stops
* sending data. Hence we need a different way to signal the
@@ -2578,7 +2579,8 @@ static inline int check_dma_crossing(char *start,
*/
static void virtualdmabug_workaround(void)
{
- int hard_sectors, end_sector;
+ int hard_sectors;
+ int end_sector;
if (CT(COMMAND) == FD_WRITE) {
COMMAND &= ~0x80; /* switch off multiple track mode */
@@ -2610,7 +2612,10 @@ static void virtualdmabug_workaround(void)
static int make_raw_rw_request(void)
{
int aligned_sector_t;
- int max_sector, max_size, tracksize, ssize;
+ int max_sector;
+ int max_size;
+ int tracksize;
+ int ssize;
if (max_buffer_sectors == 0) {
printk("VFS: Block I/O scheduled on unopened device\n");
@@ -2762,9 +2767,7 @@ static int make_raw_rw_request(void)
*/
if (!direct ||
(indirect * 2 > direct * 3 &&
- *errors < DP->max_errors.read_track &&
- /*!TESTF(FD_NEED_TWADDLE) && */
- ((!probing
+ *errors < DP->max_errors.read_track && ((!probing
|| (DP->read_track & (1 << DRS->probed_format)))))) {
max_size = current_req->nr_sectors;
} else {
@@ -2777,10 +2780,6 @@ static int make_raw_rw_request(void)
indirect, direct, fsector_t);
return 0;
}
-/* check_dma_crossing(raw_cmd->kernel_data,
- raw_cmd->length,
- "end of make_raw_request [1]");*/
-
virtualdmabug_workaround();
return 2;
}
@@ -2830,8 +2829,6 @@ static int make_raw_rw_request(void)
raw_cmd->length = ((raw_cmd->length - 1) | (ssize - 1)) + 1;
raw_cmd->length <<= 9;
#ifdef FLOPPY_SANITY_CHECK
- /*check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length,
- "end of make_raw_request"); */
if ((raw_cmd->length < current_count_sectors << 9) ||
(raw_cmd->kernel_data != current_req->buffer &&
CT(COMMAND) == FD_WRITE &&
@@ -3011,6 +3008,7 @@ static struct cont_t poll_cont = {
static int poll_drive(int interruptible, int flag)
{
int ret;
+
/* no auto-sense, just clear dcl */
raw_cmd = &default_raw_cmd;
raw_cmd->flags = flag;
@@ -3173,7 +3171,8 @@ static inline int raw_cmd_copyout(int cmd, char __user *param,
static void raw_cmd_free(struct floppy_raw_cmd **ptr)
{
- struct floppy_raw_cmd *next, *this;
+ struct floppy_raw_cmd *next;
+ struct floppy_raw_cmd *this;
this = *ptr;
*ptr = NULL;
@@ -3245,8 +3244,10 @@ static inline int raw_cmd_copyin(int cmd, char __user *param,
static int raw_cmd_ioctl(int cmd, void __user *param)
{
- int drive, ret, ret2;
struct floppy_raw_cmd *my_raw_cmd;
+ int drive;
+ int ret2;
+ int ret;
if (FDCS->rawcmd <= 1)
FDCS->rawcmd = 1;
@@ -3453,7 +3454,8 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
int drive = (long)inode->i_bdev->bd_disk->private_data;
- int i, type = ITYPE(UDRS->fd_device);
+ int type = ITYPE(UDRS->fd_device);
+ int i;
int ret;
int size;
union inparam {
@@ -3619,8 +3621,7 @@ static void __init config_types(void)
if (!UDP->cmos && FLOPPY1_TYPE)
UDP->cmos = FLOPPY1_TYPE;
- /* XXX */
- /* additional physical CMOS drive detection should go here */
+ /* FIXME: additional physical CMOS drive detection should go here */
for (drive = 0; drive < N_DRIVE; drive++) {
unsigned int type = UDP->cmos;
@@ -3903,13 +3904,13 @@ static int floppy_revalidate(struct gendisk *disk)
}
static struct block_device_operations floppy_fops = {
- .owner = THIS_MODULE,
- .open = floppy_open,
- .release = floppy_release,
- .ioctl = fd_ioctl,
- .getgeo = fd_getgeo,
- .media_changed = check_floppy_change,
- .revalidate_disk = floppy_revalidate,
+ .owner = THIS_MODULE,
+ .open = floppy_open,
+ .release = floppy_release,
+ .ioctl = fd_ioctl,
+ .getgeo = fd_getgeo,
+ .media_changed = check_floppy_change,
+ .revalidate_disk = floppy_revalidate,
};
/*
@@ -4388,11 +4389,15 @@ static int floppy_grab_irq_and_dma(void)
if (fd_request_dma()) {
DPRINT("Unable to grab DMA%d for the floppy driver\n",
FLOPPY_DMA);
- fd_free_irq();
- spin_lock_irqsave(&floppy_usage_lock, flags);
- usage_count--;
- spin_unlock_irqrestore(&floppy_usage_lock, flags);
- return -1;
+ if (can_use_virtual_dma & 2)
+ use_virtual_dma = can_use_virtual_dma = 1;
+ if (!(can_use_virtual_dma & 1)) {
+ fd_free_irq();
+ spin_lock_irqsave(&floppy_usage_lock, flags);
+ usage_count--;
+ spin_unlock_irqrestore(&floppy_usage_lock, flags);
+ return -1;
+ }
}
for (fdc = 0; fdc < N_FDC; fdc++) {
@@ -4424,8 +4429,8 @@ static int floppy_grab_irq_and_dma(void)
if (FDCS->address != -1)
fd_outb(FDCS->dor, FD_DOR);
/*
- * The driver will try and free resources and relies on us
- * to know if they were allocated or not.
+ * The driver will try and free resources and relies on us
+ * to know if they were allocated or not.
*/
fdc = 0;
irqdma_allocated = 1;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b9233a06934..589cbbd9cd4 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -204,14 +204,13 @@ lo_do_transfer(struct loop_device *lo, int cmd,
* do_lo_send_aops - helper for writing data to a loop device
*
* This is the fast version for backing filesystems which implement the address
- * space operations prepare_write and commit_write.
+ * space operations write_begin and write_end.
*/
static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
- int bsize, loff_t pos, struct page *page)
+ int bsize, loff_t pos, struct page *unused)
{
struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
struct address_space *mapping = file->f_mapping;
- const struct address_space_operations *aops = mapping->a_ops;
pgoff_t index;
unsigned offset, bv_offs;
int len, ret;
@@ -223,63 +222,45 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
len = bvec->bv_len;
while (len > 0) {
sector_t IV;
- unsigned size;
+ unsigned size, copied;
int transfer_result;
+ struct page *page;
+ void *fsdata;
IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
size = PAGE_CACHE_SIZE - offset;
if (size > len)
size = len;
- page = grab_cache_page(mapping, index);
- if (unlikely(!page))
+
+ ret = pagecache_write_begin(file, mapping, pos, size, 0,
+ &page, &fsdata);
+ if (ret)
goto fail;
- ret = aops->prepare_write(file, page, offset,
- offset + size);
- if (unlikely(ret)) {
- if (ret == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- continue;
- }
- goto unlock;
- }
+
transfer_result = lo_do_transfer(lo, WRITE, page, offset,
bvec->bv_page, bv_offs, size, IV);
- if (unlikely(transfer_result)) {
- /*
- * The transfer failed, but we still write the data to
- * keep prepare/commit calls balanced.
- */
- printk(KERN_ERR "loop: transfer error block %llu\n",
- (unsigned long long)index);
- zero_user_page(page, offset, size, KM_USER0);
- }
- flush_dcache_page(page);
- ret = aops->commit_write(file, page, offset,
- offset + size);
- if (unlikely(ret)) {
- if (ret == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- continue;
- }
- goto unlock;
- }
+ copied = size;
if (unlikely(transfer_result))
- goto unlock;
- bv_offs += size;
- len -= size;
+ copied = 0;
+
+ ret = pagecache_write_end(file, mapping, pos, size, copied,
+ page, fsdata);
+ if (ret < 0 || ret != copied)
+ goto fail;
+
+ if (unlikely(transfer_result))
+ goto fail;
+
+ bv_offs += copied;
+ len -= copied;
offset = 0;
index++;
- pos += size;
- unlock_page(page);
- page_cache_release(page);
+ pos += copied;
}
ret = 0;
out:
mutex_unlock(&mapping->host->i_mutex);
return ret;
-unlock:
- unlock_page(page);
- page_cache_release(page);
fail:
ret = -1;
goto out;
@@ -313,7 +294,7 @@ static int __do_lo_send_write(struct file *file,
* do_lo_send_direct_write - helper for writing data to a loop device
*
* This is the fast, non-transforming version for backing filesystems which do
- * not implement the address space operations prepare_write and commit_write.
+ * not implement the address space operations write_begin and write_end.
* It uses the write file operation which should be present on all writeable
* filesystems.
*/
@@ -332,7 +313,7 @@ static int do_lo_send_direct_write(struct loop_device *lo,
* do_lo_send_write - helper for writing data to a loop device
*
* This is the slow, transforming version for filesystems which do not
- * implement the address space operations prepare_write and commit_write. It
+ * implement the address space operations write_begin and write_end. It
* uses the write file operation which should be present on all writeable
* filesystems.
*
@@ -780,7 +761,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
*/
if (!file->f_op->splice_read)
goto out_putf;
- if (aops->prepare_write && aops->commit_write)
+ if (aops->prepare_write || aops->write_begin)
lo_flags |= LO_FLAGS_USE_AOPS;
if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write)
lo_flags |= LO_FLAGS_READ_ONLY;
@@ -1304,7 +1285,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
int err;
- lock_kernel();
switch(cmd) {
case LOOP_SET_STATUS:
mutex_lock(&lo->lo_ctl_mutex);
@@ -1330,7 +1310,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
err = -ENOIOCTLCMD;
break;
}
- unlock_kernel();
return err;
}
#endif
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index be5ec3a9b1f..cb136a919f2 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -113,12 +113,42 @@ static void nbd_end_request(struct request *req)
spin_unlock_irqrestore(q->queue_lock, flags);
}
+static void sock_shutdown(struct nbd_device *lo, int lock)
+{
+ /* Forcibly shutdown the socket causing all listeners
+ * to error
+ *
+ * FIXME: This code is duplicated from sys_shutdown, but
+ * there should be a more generic interface rather than
+ * calling socket ops directly here */
+ if (lock)
+ mutex_lock(&lo->tx_lock);
+ if (lo->sock) {
+ printk(KERN_WARNING "%s: shutting down socket\n",
+ lo->disk->disk_name);
+ lo->sock->ops->shutdown(lo->sock, SEND_SHUTDOWN|RCV_SHUTDOWN);
+ lo->sock = NULL;
+ }
+ if (lock)
+ mutex_unlock(&lo->tx_lock);
+}
+
+static void nbd_xmit_timeout(unsigned long arg)
+{
+ struct task_struct *task = (struct task_struct *)arg;
+
+ printk(KERN_WARNING "nbd: killing hung xmit (%s, pid: %d)\n",
+ task->comm, task->pid);
+ force_sig(SIGKILL, task);
+}
+
/*
* Send or receive packet.
*/
-static int sock_xmit(struct socket *sock, int send, void *buf, int size,
+static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
int msg_flags)
{
+ struct socket *sock = lo->sock;
int result;
struct msghdr msg;
struct kvec iov;
@@ -139,9 +169,20 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size,
msg.msg_controllen = 0;
msg.msg_flags = msg_flags | MSG_NOSIGNAL;
- if (send)
+ if (send) {
+ struct timer_list ti;
+
+ if (lo->xmit_timeout) {
+ init_timer(&ti);
+ ti.function = nbd_xmit_timeout;
+ ti.data = (unsigned long)current;
+ ti.expires = jiffies + lo->xmit_timeout;
+ add_timer(&ti);
+ }
result = kernel_sendmsg(sock, &msg, &iov, 1, size);
- else
+ if (lo->xmit_timeout)
+ del_timer_sync(&ti);
+ } else
result = kernel_recvmsg(sock, &msg, &iov, 1, size, 0);
if (signal_pending(current)) {
@@ -150,6 +191,7 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size,
current->pid, current->comm,
dequeue_signal_lock(current, &current->blocked, &info));
result = -EINTR;
+ sock_shutdown(lo, !send);
break;
}
@@ -167,23 +209,22 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size,
return result;
}
-static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec,
+static inline int sock_send_bvec(struct nbd_device *lo, struct bio_vec *bvec,
int flags)
{
int result;
void *kaddr = kmap(bvec->bv_page);
- result = sock_xmit(sock, 1, kaddr + bvec->bv_offset, bvec->bv_len,
- flags);
+ result = sock_xmit(lo, 1, kaddr + bvec->bv_offset, bvec->bv_len, flags);
kunmap(bvec->bv_page);
return result;
}
+/* always call with the tx_lock held */
static int nbd_send_req(struct nbd_device *lo, struct request *req)
{
int result, flags;
struct nbd_request request;
unsigned long size = req->nr_sectors << 9;
- struct socket *sock = lo->sock;
request.magic = htonl(NBD_REQUEST_MAGIC);
request.type = htonl(nbd_cmd(req));
@@ -196,8 +237,8 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
nbdcmd_to_ascii(nbd_cmd(req)),
(unsigned long long)req->sector << 9,
req->nr_sectors << 9);
- result = sock_xmit(sock, 1, &request, sizeof(request),
- (nbd_cmd(req) == NBD_CMD_WRITE)? MSG_MORE: 0);
+ result = sock_xmit(lo, 1, &request, sizeof(request),
+ (nbd_cmd(req) == NBD_CMD_WRITE) ? MSG_MORE : 0);
if (result <= 0) {
printk(KERN_ERR "%s: Send control failed (result %d)\n",
lo->disk->disk_name, result);
@@ -217,7 +258,7 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
flags = MSG_MORE;
dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n",
lo->disk->disk_name, req, bvec->bv_len);
- result = sock_send_bvec(sock, bvec, flags);
+ result = sock_send_bvec(lo, bvec, flags);
if (result <= 0) {
printk(KERN_ERR "%s: Send data failed (result %d)\n",
lo->disk->disk_name, result);
@@ -231,22 +272,18 @@ error_out:
return 1;
}
-static struct request *nbd_find_request(struct nbd_device *lo, char *handle)
+static struct request *nbd_find_request(struct nbd_device *lo,
+ struct request *xreq)
{
- struct request *req;
- struct list_head *tmp;
- struct request *xreq;
+ struct request *req, *tmp;
int err;
- memcpy(&xreq, handle, sizeof(xreq));
-
err = wait_event_interruptible(lo->active_wq, lo->active_req != xreq);
if (unlikely(err))
goto out;
spin_lock(&lo->queue_lock);
- list_for_each(tmp, &lo->queue_head) {
- req = list_entry(tmp, struct request, queuelist);
+ list_for_each_entry_safe(req, tmp, &lo->queue_head, queuelist) {
if (req != xreq)
continue;
list_del_init(&req->queuelist);
@@ -261,11 +298,11 @@ out:
return ERR_PTR(err);
}
-static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec)
+static inline int sock_recv_bvec(struct nbd_device *lo, struct bio_vec *bvec)
{
int result;
void *kaddr = kmap(bvec->bv_page);
- result = sock_xmit(sock, 0, kaddr + bvec->bv_offset, bvec->bv_len,
+ result = sock_xmit(lo, 0, kaddr + bvec->bv_offset, bvec->bv_len,
MSG_WAITALL);
kunmap(bvec->bv_page);
return result;
@@ -277,10 +314,9 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
int result;
struct nbd_reply reply;
struct request *req;
- struct socket *sock = lo->sock;
reply.magic = 0;
- result = sock_xmit(sock, 0, &reply, sizeof(reply), MSG_WAITALL);
+ result = sock_xmit(lo, 0, &reply, sizeof(reply), MSG_WAITALL);
if (result <= 0) {
printk(KERN_ERR "%s: Receive control failed (result %d)\n",
lo->disk->disk_name, result);
@@ -295,7 +331,7 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
goto harderror;
}
- req = nbd_find_request(lo, reply.handle);
+ req = nbd_find_request(lo, *(struct request **)reply.handle);
if (unlikely(IS_ERR(req))) {
result = PTR_ERR(req);
if (result != -ENOENT)
@@ -321,7 +357,7 @@ static struct request *nbd_read_stat(struct nbd_device *lo)
struct bio_vec *bvec;
rq_for_each_segment(bvec, req, iter) {
- result = sock_recv_bvec(sock, bvec);
+ result = sock_recv_bvec(lo, bvec);
if (result <= 0) {
printk(KERN_ERR "%s: Receive data failed (result %d)\n",
lo->disk->disk_name, result);
@@ -396,6 +432,7 @@ static void nbd_clear_que(struct nbd_device *lo)
}
}
+
/*
* We always wait for result of write, for now. It would be nice to make it optional
* in future
@@ -504,7 +541,9 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
sreq.nr_sectors = 0;
if (!lo->sock)
return -EINVAL;
+ mutex_lock(&lo->tx_lock);
nbd_send_req(lo, &sreq);
+ mutex_unlock(&lo->tx_lock);
return 0;
case NBD_CLEAR_SOCK:
@@ -548,6 +587,9 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
set_blocksize(inode->i_bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
+ case NBD_SET_TIMEOUT:
+ lo->xmit_timeout = arg * HZ;
+ return 0;
case NBD_SET_SIZE_BLOCKS:
lo->bytesize = ((u64) arg) * lo->blksize;
inode->i_bdev->bd_inode->i_size = lo->bytesize;
@@ -560,28 +602,16 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
error = nbd_do_it(lo);
if (error)
return error;
- /* on return tidy up in case we have a signal */
- /* Forcibly shutdown the socket causing all listeners
- * to error
- *
- * FIXME: This code is duplicated from sys_shutdown, but
- * there should be a more generic interface rather than
- * calling socket ops directly here */
- mutex_lock(&lo->tx_lock);
- if (lo->sock) {
- printk(KERN_WARNING "%s: shutting down socket\n",
- lo->disk->disk_name);
- lo->sock->ops->shutdown(lo->sock,
- SEND_SHUTDOWN|RCV_SHUTDOWN);
- lo->sock = NULL;
- }
- mutex_unlock(&lo->tx_lock);
+ sock_shutdown(lo, 1);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
printk(KERN_WARNING "%s: queue cleared\n", lo->disk->disk_name);
if (file)
fput(file);
+ lo->bytesize = 0;
+ inode->i_bdev->bd_inode->i_size = 0;
+ set_capacity(lo->disk, 0);
return lo->harderror;
case NBD_CLEAR_QUE:
/*
@@ -659,14 +689,14 @@ static int __init nbd_init(void)
mutex_init(&nbd_dev[i].tx_lock);
init_waitqueue_head(&nbd_dev[i].active_wq);
nbd_dev[i].blksize = 1024;
- nbd_dev[i].bytesize = 0x7ffffc00ULL << 10; /* 2TB */
+ nbd_dev[i].bytesize = 0;
disk->major = NBD_MAJOR;
disk->first_minor = i;
disk->fops = &nbd_fops;
disk->private_data = &nbd_dev[i];
disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
sprintf(disk->disk_name, "nbd%d", i);
- set_capacity(disk, 0x7ffffc00ULL << 1); /* 2 TB */
+ set_capacity(disk, 0);
add_disk(disk);
}
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 540bf367698..a8130a4ad6d 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1133,16 +1133,21 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
* Schedule reads for missing parts of the packet.
*/
for (f = 0; f < pkt->frames; f++) {
+ struct bio_vec *vec;
+
int p, offset;
if (written[f])
continue;
bio = pkt->r_bios[f];
+ vec = bio->bi_io_vec;
bio_init(bio);
bio->bi_max_vecs = 1;
bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
bio->bi_bdev = pd->bdev;
bio->bi_end_io = pkt_end_io_read;
bio->bi_private = pkt;
+ bio->bi_io_vec = vec;
+ bio->bi_destructor = pkt_bio_destructor;
p = (f * CD_FRAMESIZE) / PAGE_SIZE;
offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
@@ -1439,6 +1444,8 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
pkt->w_bio->bi_bdev = pd->bdev;
pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
pkt->w_bio->bi_private = pkt;
+ pkt->w_bio->bi_io_vec = bvec;
+ pkt->w_bio->bi_destructor = pkt_bio_destructor;
for (f = 0; f < pkt->frames; f++)
if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
BUG();
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 06d0552cf49..e354bfc070e 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -414,26 +414,6 @@ static void ps3disk_prepare_flush(struct request_queue *q, struct request *req)
req->cmd_type = REQ_TYPE_FLUSH;
}
-static int ps3disk_issue_flush(struct request_queue *q, struct gendisk *gendisk,
- sector_t *sector)
-{
- struct ps3_storage_device *dev = q->queuedata;
- struct request *req;
- int res;
-
- dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
-
- req = blk_get_request(q, WRITE, __GFP_WAIT);
- ps3disk_prepare_flush(q, req);
- res = blk_execute_rq(q, gendisk, req, 0);
- if (res)
- dev_err(&dev->sbd.core, "%s:%u: flush request failed %d\n",
- __func__, __LINE__, res);
- blk_put_request(req);
- return res;
-}
-
-
static unsigned long ps3disk_mask;
static DEFINE_MUTEX(ps3disk_mask_mutex);
@@ -506,7 +486,6 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
blk_queue_dma_alignment(queue, dev->blk_size-1);
blk_queue_hardsect_size(queue, dev->blk_size);
- blk_queue_issue_flush_fn(queue, ps3disk_issue_flush);
blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
ps3disk_prepare_flush);
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 701ea77f62e..08176d23a46 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -411,6 +411,9 @@ static void __exit rd_cleanup(void)
blk_cleanup_queue(rd_queue[i]);
}
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
+
+ bdi_destroy(&rd_file_backing_dev_info);
+ bdi_destroy(&rd_backing_dev_info);
}
/*
@@ -419,7 +422,19 @@ static void __exit rd_cleanup(void)
static int __init rd_init(void)
{
int i;
- int err = -ENOMEM;
+ int err;
+
+ err = bdi_init(&rd_backing_dev_info);
+ if (err)
+ goto out2;
+
+ err = bdi_init(&rd_file_backing_dev_info);
+ if (err) {
+ bdi_destroy(&rd_backing_dev_info);
+ goto out2;
+ }
+
+ err = -ENOMEM;
if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
(rd_blocksize & (rd_blocksize-1))) {
@@ -473,6 +488,9 @@ out:
put_disk(rd_disks[i]);
blk_cleanup_queue(rd_queue[i]);
}
+ bdi_destroy(&rd_backing_dev_info);
+ bdi_destroy(&rd_file_backing_dev_info);
+out2:
return err;
}
@@ -486,17 +504,12 @@ static int __init ramdisk_size(char *str)
rd_size = simple_strtol(str,NULL,0);
return 1;
}
-static int __init ramdisk_size2(char *str) /* kludge */
-{
- return ramdisk_size(str);
-}
static int __init ramdisk_blocksize(char *str)
{
rd_blocksize = simple_strtol(str,NULL,0);
return 1;
}
-__setup("ramdisk=", ramdisk_size);
-__setup("ramdisk_size=", ramdisk_size2);
+__setup("ramdisk_size=", ramdisk_size);
__setup("ramdisk_blocksize=", ramdisk_blocksize);
#endif
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 9e7652dcde6..82effce97c5 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -390,8 +390,8 @@ static inline void ace_dump_mem(void *base, int len)
static void ace_dump_regs(struct ace_device *ace)
{
dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n"
- " status:%.8x mpu_lba:%.8x busmode:%4x\n"
- " error: %.8x cfg_lba:%.8x fatstat:%.4x\n",
+ KERN_INFO " status:%.8x mpu_lba:%.8x busmode:%4x\n"
+ KERN_INFO " error: %.8x cfg_lba:%.8x fatstat:%.4x\n",
ace_in32(ace, ACE_CTRL),
ace_in(ace, ACE_SECCNTCMD),
ace_in(ace, ACE_VERSION),
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 79245714f0a..d70745c8425 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -3458,47 +3458,19 @@ static void cdrom_update_settings(void)
static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
- int *valp = ctl->data;
- int val = *valp;
int ret;
ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
- if (write && *valp != val) {
+ if (write) {
/* we only care for 1 or 0. */
- if (*valp)
- *valp = 1;
- else
- *valp = 0;
+ autoclose = !!cdrom_sysctl_settings.autoclose;
+ autoeject = !!cdrom_sysctl_settings.autoeject;
+ debug = !!cdrom_sysctl_settings.debug;
+ lockdoor = !!cdrom_sysctl_settings.lock;
+ check_media_type = !!cdrom_sysctl_settings.check;
- switch (ctl->ctl_name) {
- case DEV_CDROM_AUTOCLOSE: {
- if (valp == &cdrom_sysctl_settings.autoclose)
- autoclose = cdrom_sysctl_settings.autoclose;
- break;
- }
- case DEV_CDROM_AUTOEJECT: {
- if (valp == &cdrom_sysctl_settings.autoeject)
- autoeject = cdrom_sysctl_settings.autoeject;
- break;
- }
- case DEV_CDROM_DEBUG: {
- if (valp == &cdrom_sysctl_settings.debug)
- debug = cdrom_sysctl_settings.debug;
- break;
- }
- case DEV_CDROM_LOCK: {
- if (valp == &cdrom_sysctl_settings.lock)
- lockdoor = cdrom_sysctl_settings.lock;
- break;
- }
- case DEV_CDROM_CHECK_MEDIA: {
- if (valp == &cdrom_sysctl_settings.check)
- check_media_type = cdrom_sysctl_settings.check;
- break;
- }
- }
/* update the option flags according to the changes. we
don't have per device options through sysctl yet,
but we will have and then this will disappear. */
@@ -3511,7 +3483,6 @@ static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp,
/* Place files in /proc/sys/dev/cdrom */
static ctl_table cdrom_table[] = {
{
- .ctl_name = DEV_CDROM_INFO,
.procname = "info",
.data = &cdrom_sysctl_settings.info,
.maxlen = CDROM_STR_SIZE,
@@ -3519,7 +3490,6 @@ static ctl_table cdrom_table[] = {
.proc_handler = &cdrom_sysctl_info,
},
{
- .ctl_name = DEV_CDROM_AUTOCLOSE,
.procname = "autoclose",
.data = &cdrom_sysctl_settings.autoclose,
.maxlen = sizeof(int),
@@ -3527,7 +3497,6 @@ static ctl_table cdrom_table[] = {
.proc_handler = &cdrom_sysctl_handler,
},
{
- .ctl_name = DEV_CDROM_AUTOEJECT,
.procname = "autoeject",
.data = &cdrom_sysctl_settings.autoeject,
.maxlen = sizeof(int),
@@ -3535,7 +3504,6 @@ static ctl_table cdrom_table[] = {
.proc_handler = &cdrom_sysctl_handler,
},
{
- .ctl_name = DEV_CDROM_DEBUG,
.procname = "debug",
.data = &cdrom_sysctl_settings.debug,
.maxlen = sizeof(int),
@@ -3543,7 +3511,6 @@ static ctl_table cdrom_table[] = {
.proc_handler = &cdrom_sysctl_handler,
},
{
- .ctl_name = DEV_CDROM_LOCK,
.procname = "lock",
.data = &cdrom_sysctl_settings.lock,
.maxlen = sizeof(int),
@@ -3551,7 +3518,6 @@ static ctl_table cdrom_table[] = {
.proc_handler = &cdrom_sysctl_handler,
},
{
- .ctl_name = DEV_CDROM_CHECK_MEDIA,
.procname = "check_media",
.data = &cdrom_sysctl_settings.check,
.maxlen = sizeof(int),
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index b391776e5bf..65491103e0f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -568,8 +568,8 @@ config TIPAR
config HVC_DRIVER
bool
help
- Users of pSeries machines that want to utilize the hvc console front-end
- module for their backend console driver should select this option.
+ Generic "hypervisor virtual console" infrastructure for various
+ hypervisors (pSeries, iSeries, Xen, lguest).
It will automatically be selected if one of the back-end console drivers
is selected.
@@ -632,8 +632,6 @@ config HVCS
source "drivers/char/ipmi/Kconfig"
-source "drivers/char/watchdog/Kconfig"
-
config DS1620
tristate "NetWinder thermometer support"
depends on ARCH_NETWINDER
@@ -896,10 +894,6 @@ config GPIO_TB0219
depends on TANBAC_TB022X
select GPIO_VR41XX
-source "drivers/char/agp/Kconfig"
-
-source "drivers/char/drm/Kconfig"
-
source "drivers/char/pcmcia/Kconfig"
config MWAVE
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 713533d8a86..f22c253bc09 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,4 +1,4 @@
-config AGP
+menuconfig AGP
tristate "/dev/agpgart (AGP Support)"
depends on ALPHA || IA64 || PARISC || PPC || X86
depends on PCI
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index d78cd09186a..cac0009cebc 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -221,7 +221,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
SetPageReserved(virt_to_page((char *)page));
for (offset = 0; offset < PAGE_SIZE; offset += clflush_chunk)
- asm volatile("clflush %0" : : "m" (*(char *)(page+offset)));
+ clflush((char *)page+offset);
efficeon_private.l1_table[index] = page;
@@ -268,15 +268,16 @@ static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int t
*page = insert;
/* clflush is slow, so don't clflush until we have to */
- if ( last_page &&
- ((unsigned long)page^(unsigned long)last_page) & clflush_mask )
- asm volatile("clflush %0" : : "m" (*last_page));
+ if (last_page &&
+ (((unsigned long)page^(unsigned long)last_page) &
+ clflush_mask))
+ clflush(last_page);
last_page = page;
}
if ( last_page )
- asm volatile("clflush %0" : : "m" (*last_page));
+ clflush(last_page);
agp_bridge->driver->tlb_flush(mem);
return 0;
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 313a133a117..cbb0444467b 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -14,15 +14,12 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
+#include <linux/log2.h>
#include <asm/acpi-ext.h>
#include "agp.h"
-#ifndef log2
-#define log2(x) ffz(~(x))
-#endif
-
#define HP_ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */
/* HP ZX1 IOC registers */
@@ -257,7 +254,7 @@ hp_zx1_configure (void)
readl(hp->ioc_regs+HP_ZX1_IMASK);
writel(hp->iova_base|1, hp->ioc_regs+HP_ZX1_IBASE);
readl(hp->ioc_regs+HP_ZX1_IBASE);
- writel(hp->iova_base|log2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
+ writel(hp->iova_base|ilog2(HP_ZX1_IOVA_SIZE), hp->ioc_regs+HP_ZX1_PCOM);
readl(hp->ioc_regs+HP_ZX1_PCOM);
}
@@ -285,7 +282,7 @@ hp_zx1_tlbflush (struct agp_memory *mem)
{
struct _hp_private *hp = &hp_private;
- writeq(hp->gart_base | log2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM);
+ writeq(hp->gart_base | ilog2(hp->gart_size), hp->ioc_regs+HP_ZX1_PCOM);
readq(hp->ioc_regs+HP_ZX1_PCOM);
}
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 70117df4d06..e72a83e2bad 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -13,6 +13,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/agp_backend.h>
+#include <linux/log2.h>
#include "agp.h"
@@ -59,8 +60,6 @@
*/
#define WR_FLUSH_GATT(index) RD_GATT(index)
-#define log2(x) ffz(~(x))
-
static struct {
void *gatt; /* ioremap'd GATT area */
@@ -148,7 +147,7 @@ static int i460_fetch_size (void)
* values[i].size.
*/
values[i].num_entries = (values[i].size << 8) >> (I460_IO_PAGE_SHIFT - 12);
- values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT);
+ values[i].page_order = ilog2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT);
}
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index f4562cc2234..2939e3570f9 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/klist.h>
#include <linux/agp_backend.h>
+#include <linux/log2.h>
#include <asm-parisc/parisc-device.h>
#include <asm-parisc/ropes.h>
@@ -27,10 +28,6 @@
#define DRVNAME "quicksilver"
#define DRVPFX DRVNAME ": "
-#ifndef log2
-#define log2(x) ffz(~(x))
-#endif
-
#define AGP8X_MODE_BIT 3
#define AGP8X_MODE (1 << AGP8X_MODE_BIT)
@@ -92,7 +89,7 @@ parisc_agp_tlbflush(struct agp_memory *mem)
{
struct _parisc_agp_info *info = &parisc_agp_info;
- writeq(info->gart_base | log2(info->gart_size), info->ioc_regs+IOC_PCOM);
+ writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM);
readq(info->ioc_regs+IOC_PCOM); /* flush */
}
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index ec116df919d..c99e43b837f 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -18,7 +18,7 @@
#include <linux/apm_bios.h>
#include <linux/capability.h>
#include <linux/sched.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
#include <linux/apm-emulation.h>
#include <linux/freezer.h>
#include <linux/device.h>
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 4b3916f5490..6b104e45a32 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -494,12 +494,11 @@ int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
if (p && p->readonly) return -EIO;
if (!p || --p->refcount) {
- q = kmalloc(sizeof(*p), GFP_KERNEL);
+ q = kzalloc(sizeof(*p), GFP_KERNEL);
if (!q) {
if (p) p->refcount++;
return -ENOMEM;
}
- memset(q, 0, sizeof(*q));
q->refcount=1;
*vc->vc_uni_pagedir_loc = (unsigned long)q;
} else {
@@ -670,19 +669,29 @@ void con_protect_unimap(struct vc_data *vc, int rdonly)
p->readonly = rdonly;
}
+/*
+ * Always use USER_MAP. These functions are used by the keyboard,
+ * which shouldn't be affected by G0/G1 switching, etc.
+ * If the user map still contains default values, i.e. the
+ * direct-to-font mapping, then assume user is using Latin1.
+ */
/* may be called during an interrupt */
u32 conv_8bit_to_uni(unsigned char c)
{
- /*
- * Always use USER_MAP. This function is used by the keyboard,
- * which shouldn't be affected by G0/G1 switching, etc.
- * If the user map still contains default values, i.e. the
- * direct-to-font mapping, then assume user is using Latin1.
- */
unsigned short uni = translations[USER_MAP][c];
return uni == (0xf000 | c) ? c : uni;
}
+int conv_uni_to_8bit(u32 uni)
+{
+ int c;
+ for (c = 0; c < 0x100; c++)
+ if (translations[USER_MAP][c] == uni ||
+ (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
+ return c;
+ return -1;
+}
+
int
conv_uni_to_pc(struct vc_data *conp, long ucs)
{
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 9e0adfe27c1..d15234c5965 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -662,7 +662,7 @@
static void cy_throttle(struct tty_struct *tty);
static void cy_send_xchar(struct tty_struct *tty, char ch);
-#define IS_CYC_Z(card) ((card).num_chips == -1)
+#define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1)
#define Z_FPGA_CHECK(card) \
((readl(&((struct RUNTIME_9060 __iomem *) \
@@ -897,71 +897,6 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
return 0;
} /* serial_paranoia_check */
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver
- * (also known as the "bottom half"). This can be called any
- * number of times for any channel without harm.
- */
-static inline void cy_sched_event(struct cyclades_port *info, int event)
-{
- info->event |= 1 << event; /* remember what kind of event and who */
- schedule_work(&info->tqueue);
-} /* cy_sched_event */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using cy_sched_event(), and they get done here.
- *
- * This is done through one level of indirection--the task queue.
- * When a hardware interrupt service routine wants service by the
- * driver's bottom half, it enqueues the appropriate tq_struct (one
- * per port) to the keventd work queue and sets a request flag
- * that the work queue be processed.
- *
- * Although this may seem unwieldy, it gives the system a way to
- * pass an argument (in this case the pointer to the cyclades_port
- * structure) to the bottom half of the driver. Previous kernels
- * had to poll every port to see if that port needed servicing.
- */
-static void
-do_softint(struct work_struct *work)
-{
- struct cyclades_port *info =
- container_of(work, struct cyclades_port, tqueue);
- struct tty_struct *tty;
-
- tty = info->tty;
- if (!tty)
- return;
-
- if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
- tty_hangup(info->tty);
- wake_up_interruptible(&info->open_wait);
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- }
- if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
- wake_up_interruptible(&info->open_wait);
-#ifdef CONFIG_CYZ_INTR
- if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
- !timer_pending(&cyz_rx_full_timer[info->line]))
- mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
-#endif
- if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
- wake_up_interruptible(&info->delta_msr_wait);
- tty_wakeup(tty);
-#ifdef Z_WAKE
- if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
- complete(&info->shutdown_wait);
-#endif
-} /* do_softint */
-
-
/***********************************************************/
/********* Start of block of Cyclom-Y specific code ********/
@@ -1045,382 +980,332 @@ static unsigned detect_isa_irq(void __iomem * address)
}
#endif /* CONFIG_ISA */
-static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
- void __iomem * base_addr, int status, int index)
+static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
+ void __iomem *base_addr)
{
struct cyclades_port *info;
struct tty_struct *tty;
- int char_count;
- int j, len, mdm_change, mdm_status, outch;
- int save_xir, channel, save_car;
- char data;
+ int len, index = cinfo->bus_index;
+ u8 save_xir, channel, save_car, data, char_count;
- if (status & CySRReceive) { /* reception interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
+ printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
#endif
- /* determine the channel & change to that context */
- spin_lock(&cinfo->card_lock);
- save_xir = (u_char) readb(base_addr + (CyRIR << index));
- channel = (u_short) (save_xir & CyIRChannel);
- info = &cinfo->ports[channel + chip * 4];
- save_car = readb(base_addr + (CyCAR << index));
- cy_writeb(base_addr + (CyCAR << index), save_xir);
-
- /* if there is nowhere to put the data, discard it */
- if (info->tty == NULL) {
- j = (readb(base_addr + (CyRIVR << index)) &
- CyIVRMask);
- if (j == CyIVRRxEx) { /* exception */
+ /* determine the channel & change to that context */
+ save_xir = readb(base_addr + (CyRIR << index));
+ channel = save_xir & CyIRChannel;
+ info = &cinfo->ports[channel + chip * 4];
+ save_car = readb(base_addr + (CyCAR << index));
+ cy_writeb(base_addr + (CyCAR << index), save_xir);
+
+ /* if there is nowhere to put the data, discard it */
+ if (info->tty == NULL) {
+ if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
+ CyIVRRxEx) { /* exception */
+ data = readb(base_addr + (CyRDSR << index));
+ } else { /* normal character reception */
+ char_count = readb(base_addr + (CyRDCR << index));
+ while (char_count--)
data = readb(base_addr + (CyRDSR << index));
- } else { /* normal character reception */
- char_count = readb(base_addr +
- (CyRDCR << index));
- while (char_count--) {
- data = readb(base_addr +
- (CyRDSR << index));
- }
- }
- } else { /* there is an open port for this data */
- tty = info->tty;
- j = (readb(base_addr + (CyRIVR << index)) &
- CyIVRMask);
- if (j == CyIVRRxEx) { /* exception */
- data = readb(base_addr + (CyRDSR << index));
-
- /* For statistics only */
- if (data & CyBREAK)
- info->icount.brk++;
- else if (data & CyFRAME)
- info->icount.frame++;
- else if (data & CyPARITY)
- info->icount.parity++;
- else if (data & CyOVERRUN)
- info->icount.overrun++;
-
- if (data & info->ignore_status_mask) {
+ }
+ goto end;
+ }
+ /* there is an open port for this data */
+ tty = info->tty;
+ if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
+ CyIVRRxEx) { /* exception */
+ data = readb(base_addr + (CyRDSR << index));
+
+ /* For statistics only */
+ if (data & CyBREAK)
+ info->icount.brk++;
+ else if (data & CyFRAME)
+ info->icount.frame++;
+ else if (data & CyPARITY)
+ info->icount.parity++;
+ else if (data & CyOVERRUN)
+ info->icount.overrun++;
+
+ if (data & info->ignore_status_mask) {
+ info->icount.rx++;
+ return;
+ }
+ if (tty_buffer_request_room(tty, 1)) {
+ if (data & info->read_status_mask) {
+ if (data & CyBREAK) {
+ tty_insert_flip_char(tty,
+ readb(base_addr + (CyRDSR <<
+ index)), TTY_BREAK);
+ info->icount.rx++;
+ if (info->flags & ASYNC_SAK)
+ do_SAK(tty);
+ } else if (data & CyFRAME) {
+ tty_insert_flip_char( tty,
+ readb(base_addr + (CyRDSR <<
+ index)), TTY_FRAME);
+ info->icount.rx++;
+ info->idle_stats.frame_errs++;
+ } else if (data & CyPARITY) {
+ /* Pieces of seven... */
+ tty_insert_flip_char(tty,
+ readb(base_addr + (CyRDSR <<
+ index)), TTY_PARITY);
+ info->icount.rx++;
+ info->idle_stats.parity_errs++;
+ } else if (data & CyOVERRUN) {
+ tty_insert_flip_char(tty, 0,
+ TTY_OVERRUN);
+ info->icount.rx++;
+ /* If the flip buffer itself is
+ overflowing, we still lose
+ the next incoming character.
+ */
+ tty_insert_flip_char(tty,
+ readb(base_addr + (CyRDSR <<
+ index)), TTY_FRAME);
info->icount.rx++;
- spin_unlock(&cinfo->card_lock);
- return;
- }
- if (tty_buffer_request_room(tty, 1)) {
- if (data & info->read_status_mask) {
- if (data & CyBREAK) {
- tty_insert_flip_char(
- tty,
- readb(
- base_addr +
- (CyRDSR <<
- index)),
- TTY_BREAK);
- info->icount.rx++;
- if (info->flags &
- ASYNC_SAK) {
- do_SAK(tty);
- }
- } else if (data & CyFRAME) {
- tty_insert_flip_char(
- tty,
- readb(
- base_addr +
- (CyRDSR <<
- index)),
- TTY_FRAME);
- info->icount.rx++;
- info->idle_stats.
- frame_errs++;
- } else if (data & CyPARITY) {
- /* Pieces of seven... */
- tty_insert_flip_char(
- tty,
- readb(
- base_addr +
- (CyRDSR <<
- index)),
- TTY_PARITY);
- info->icount.rx++;
- info->idle_stats.
- parity_errs++;
- } else if (data & CyOVERRUN) {
- tty_insert_flip_char(
- tty, 0,
- TTY_OVERRUN);
- info->icount.rx++;
- /* If the flip buffer itself is
- overflowing, we still lose
- the next incoming character.
- */
- tty_insert_flip_char(
- tty,
- readb(
- base_addr +
- (CyRDSR <<
- index)),
- TTY_FRAME);
- info->icount.rx++;
- info->idle_stats.
- overruns++;
- /* These two conditions may imply */
- /* a normal read should be done. */
- /* }else if(data & CyTIMEOUT){ */
- /* }else if(data & CySPECHAR){ */
- } else {
- tty_insert_flip_char(
- tty, 0,
- TTY_NORMAL);
- info->icount.rx++;
- }
- } else {
- tty_insert_flip_char(tty, 0,
- TTY_NORMAL);
- info->icount.rx++;
- }
- } else {
- /* there was a software buffer
- overrun and nothing could be
- done about it!!! */
- info->icount.buf_overrun++;
info->idle_stats.overruns++;
+ /* These two conditions may imply */
+ /* a normal read should be done. */
+ /* } else if(data & CyTIMEOUT) { */
+ /* } else if(data & CySPECHAR) { */
+ } else {
+ tty_insert_flip_char(tty, 0,
+ TTY_NORMAL);
+ info->icount.rx++;
}
- } else { /* normal character reception */
- /* load # chars available from the chip */
- char_count = readb(base_addr +
- (CyRDCR << index));
+ } else {
+ tty_insert_flip_char(tty, 0, TTY_NORMAL);
+ info->icount.rx++;
+ }
+ } else {
+ /* there was a software buffer overrun and nothing
+ * could be done about it!!! */
+ info->icount.buf_overrun++;
+ info->idle_stats.overruns++;
+ }
+ } else { /* normal character reception */
+ /* load # chars available from the chip */
+ char_count = readb(base_addr + (CyRDCR << index));
#ifdef CY_ENABLE_MONITORING
- ++info->mon.int_count;
- info->mon.char_count += char_count;
- if (char_count > info->mon.char_max)
- info->mon.char_max = char_count;
- info->mon.char_last = char_count;
+ ++info->mon.int_count;
+ info->mon.char_count += char_count;
+ if (char_count > info->mon.char_max)
+ info->mon.char_max = char_count;
+ info->mon.char_last = char_count;
#endif
- len = tty_buffer_request_room(tty, char_count);
- while (len--) {
- data = readb(base_addr +
- (CyRDSR << index));
- tty_insert_flip_char(tty, data,
- TTY_NORMAL);
- info->idle_stats.recv_bytes++;
- info->icount.rx++;
+ len = tty_buffer_request_room(tty, char_count);
+ while (len--) {
+ data = readb(base_addr + (CyRDSR << index));
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
+ info->idle_stats.recv_bytes++;
+ info->icount.rx++;
#ifdef CY_16Y_HACK
- udelay(10L);
+ udelay(10L);
#endif
- }
- info->idle_stats.recv_idle = jiffies;
- }
- tty_schedule_flip(tty);
}
- /* end of service */
- cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f));
- cy_writeb(base_addr + (CyCAR << index), (save_car));
- spin_unlock(&cinfo->card_lock);
+ info->idle_stats.recv_idle = jiffies;
}
+ tty_schedule_flip(tty);
+end:
+ /* end of service */
+ cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
+ cy_writeb(base_addr + (CyCAR << index), save_car);
+}
+
+static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
+ void __iomem *base_addr)
+{
+ struct cyclades_port *info;
+ int char_count, index = cinfo->bus_index;
+ u8 save_xir, channel, save_car, outch;
- if (status & CySRTransmit) { /* transmission interrupt */
- /* Since we only get here when the transmit buffer
- is empty, we know we can always stuff a dozen
- characters. */
+ /* Since we only get here when the transmit buffer
+ is empty, we know we can always stuff a dozen
+ characters. */
#ifdef CY_DEBUG_INTERRUPTS
- printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
+ printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
#endif
- /* determine the channel & change to that context */
- spin_lock(&cinfo->card_lock);
- save_xir = (u_char) readb(base_addr + (CyTIR << index));
- channel = (u_short) (save_xir & CyIRChannel);
- save_car = readb(base_addr + (CyCAR << index));
- cy_writeb(base_addr + (CyCAR << index), save_xir);
+ /* determine the channel & change to that context */
+ save_xir = readb(base_addr + (CyTIR << index));
+ channel = save_xir & CyIRChannel;
+ save_car = readb(base_addr + (CyCAR << index));
+ cy_writeb(base_addr + (CyCAR << index), save_xir);
- /* validate the port# (as configured and open) */
- if (channel + chip * 4 >= cinfo->nports) {
- cy_writeb(base_addr + (CySRER << index),
- readb(base_addr + (CySRER << index)) &
- ~CyTxRdy);
- goto txend;
- }
- info = &cinfo->ports[channel + chip * 4];
- if (info->tty == NULL) {
- cy_writeb(base_addr + (CySRER << index),
- readb(base_addr + (CySRER << index)) &
- ~CyTxRdy);
- goto txdone;
- }
+ /* validate the port# (as configured and open) */
+ if (channel + chip * 4 >= cinfo->nports) {
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+ goto end;
+ }
+ info = &cinfo->ports[channel + chip * 4];
+ if (info->tty == NULL) {
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+ goto end;
+ }
- /* load the on-chip space for outbound data */
- char_count = info->xmit_fifo_size;
+ /* load the on-chip space for outbound data */
+ char_count = info->xmit_fifo_size;
- if (info->x_char) { /* send special char */
- outch = info->x_char;
- cy_writeb(base_addr + (CyTDR << index), outch);
- char_count--;
- info->icount.tx++;
- info->x_char = 0;
- }
+ if (info->x_char) { /* send special char */
+ outch = info->x_char;
+ cy_writeb(base_addr + (CyTDR << index), outch);
+ char_count--;
+ info->icount.tx++;
+ info->x_char = 0;
+ }
- if (info->breakon || info->breakoff) {
- if (info->breakon) {
- cy_writeb(base_addr + (CyTDR << index), 0);
- cy_writeb(base_addr + (CyTDR << index), 0x81);
- info->breakon = 0;
- char_count -= 2;
- }
- if (info->breakoff) {
- cy_writeb(base_addr + (CyTDR << index), 0);
- cy_writeb(base_addr + (CyTDR << index), 0x83);
- info->breakoff = 0;
- char_count -= 2;
- }
+ if (info->breakon || info->breakoff) {
+ if (info->breakon) {
+ cy_writeb(base_addr + (CyTDR << index), 0);
+ cy_writeb(base_addr + (CyTDR << index), 0x81);
+ info->breakon = 0;
+ char_count -= 2;
+ }
+ if (info->breakoff) {
+ cy_writeb(base_addr + (CyTDR << index), 0);
+ cy_writeb(base_addr + (CyTDR << index), 0x83);
+ info->breakoff = 0;
+ char_count -= 2;
}
+ }
- while (char_count-- > 0) {
- if (!info->xmit_cnt) {
- if (readb(base_addr + (CySRER << index)) &
- CyTxMpty) {
- cy_writeb(base_addr + (CySRER << index),
- readb(base_addr +
- (CySRER << index)) &
+ while (char_count-- > 0) {
+ if (!info->xmit_cnt) {
+ if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) &
~CyTxMpty);
- } else {
- cy_writeb(base_addr + (CySRER << index),
- (readb(base_addr +
- (CySRER << index)) &
+ } else {
+ cy_writeb(base_addr + (CySRER << index),
+ (readb(base_addr + (CySRER << index)) &
~CyTxRdy) | CyTxMpty);
- }
- goto txdone;
}
- if (info->xmit_buf == NULL) {
- cy_writeb(base_addr + (CySRER << index),
- readb(base_addr + (CySRER << index)) &
+ goto done;
+ }
+ if (info->xmit_buf == NULL) {
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
- goto txdone;
- }
- if (info->tty->stopped || info->tty->hw_stopped) {
- cy_writeb(base_addr + (CySRER << index),
- readb(base_addr + (CySRER << index)) &
+ goto done;
+ }
+ if (info->tty->stopped || info->tty->hw_stopped) {
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
- goto txdone;
- }
- /* Because the Embedded Transmit Commands have
- been enabled, we must check to see if the
- escape character, NULL, is being sent. If it
- is, we must ensure that there is room for it
- to be doubled in the output stream. Therefore
- we no longer advance the pointer when the
- character is fetched, but rather wait until
- after the check for a NULL output character.
- This is necessary because there may not be
- room for the two chars needed to send a NULL.)
- */
- outch = info->xmit_buf[info->xmit_tail];
- if (outch) {
+ goto done;
+ }
+ /* Because the Embedded Transmit Commands have been enabled,
+ * we must check to see if the escape character, NULL, is being
+ * sent. If it is, we must ensure that there is room for it to
+ * be doubled in the output stream. Therefore we no longer
+ * advance the pointer when the character is fetched, but
+ * rather wait until after the check for a NULL output
+ * character. This is necessary because there may not be room
+ * for the two chars needed to send a NULL.)
+ */
+ outch = info->xmit_buf[info->xmit_tail];
+ if (outch) {
+ info->xmit_cnt--;
+ info->xmit_tail = (info->xmit_tail + 1) &
+ (SERIAL_XMIT_SIZE - 1);
+ cy_writeb(base_addr + (CyTDR << index), outch);
+ info->icount.tx++;
+ } else {
+ if (char_count > 1) {
info->xmit_cnt--;
info->xmit_tail = (info->xmit_tail + 1) &
- (SERIAL_XMIT_SIZE - 1);
+ (SERIAL_XMIT_SIZE - 1);
cy_writeb(base_addr + (CyTDR << index), outch);
+ cy_writeb(base_addr + (CyTDR << index), 0);
info->icount.tx++;
- } else {
- if (char_count > 1) {
- info->xmit_cnt--;
- info->xmit_tail = (info->xmit_tail + 1)&
- (SERIAL_XMIT_SIZE - 1);
- cy_writeb(base_addr + (CyTDR << index),
- outch);
- cy_writeb(base_addr + (CyTDR << index),
- 0);
- info->icount.tx++;
- char_count--;
- }
+ char_count--;
}
}
-
-txdone:
- if (info->xmit_cnt < WAKEUP_CHARS) {
- cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
- }
-txend:
- /* end of service */
- cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f));
- cy_writeb(base_addr + (CyCAR << index), (save_car));
- spin_unlock(&cinfo->card_lock);
}
- if (status & CySRModem) { /* modem interrupt */
+done:
+ tty_wakeup(info->tty);
+end:
+ /* end of service */
+ cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
+ cy_writeb(base_addr + (CyCAR << index), save_car);
+}
- /* determine the channel & change to that context */
- spin_lock(&cinfo->card_lock);
- save_xir = (u_char) readb(base_addr + (CyMIR << index));
- channel = (u_short) (save_xir & CyIRChannel);
- info = &cinfo->ports[channel + chip * 4];
- save_car = readb(base_addr + (CyCAR << index));
- cy_writeb(base_addr + (CyCAR << index), save_xir);
+static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
+ void __iomem *base_addr)
+{
+ struct cyclades_port *info;
+ int index = cinfo->bus_index;
+ u8 save_xir, channel, save_car, mdm_change, mdm_status;
- mdm_change = readb(base_addr + (CyMISR << index));
- mdm_status = readb(base_addr + (CyMSVR1 << index));
+ /* determine the channel & change to that context */
+ save_xir = readb(base_addr + (CyMIR << index));
+ channel = save_xir & CyIRChannel;
+ info = &cinfo->ports[channel + chip * 4];
+ save_car = readb(base_addr + (CyCAR << index));
+ cy_writeb(base_addr + (CyCAR << index), save_xir);
- if (info->tty) {
- if (mdm_change & CyANY_DELTA) {
- /* For statistics only */
- if (mdm_change & CyDCD)
- info->icount.dcd++;
- if (mdm_change & CyCTS)
- info->icount.cts++;
- if (mdm_change & CyDSR)
- info->icount.dsr++;
- if (mdm_change & CyRI)
- info->icount.rng++;
-
- cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
- }
+ mdm_change = readb(base_addr + (CyMISR << index));
+ mdm_status = readb(base_addr + (CyMSVR1 << index));
- if ((mdm_change & CyDCD) &&
- (info->flags & ASYNC_CHECK_CD)) {
- if (mdm_status & CyDCD) {
- cy_sched_event(info,
- Cy_EVENT_OPEN_WAKEUP);
- } else {
- cy_sched_event(info, Cy_EVENT_HANGUP);
- }
- }
- if ((mdm_change & CyCTS) &&
- (info->flags & ASYNC_CTS_FLOW)) {
- if (info->tty->hw_stopped) {
- if (mdm_status & CyCTS) {
- /* cy_start isn't used
- because... !!! */
- info->tty->hw_stopped = 0;
- cy_writeb(base_addr +
- (CySRER << index),
- readb(base_addr +
- (CySRER <<
- index))|
- CyTxRdy);
- cy_sched_event(info,
- Cy_EVENT_WRITE_WAKEUP);
- }
- } else {
- if (!(mdm_status & CyCTS)) {
- /* cy_stop isn't used
- because ... !!! */
- info->tty->hw_stopped = 1;
- cy_writeb(base_addr +
- (CySRER << index),
- readb(base_addr +
- (CySRER <<
- index)) &
- ~CyTxRdy);
- }
- }
+ if (!info->tty)
+ goto end;
+
+ if (mdm_change & CyANY_DELTA) {
+ /* For statistics only */
+ if (mdm_change & CyDCD)
+ info->icount.dcd++;
+ if (mdm_change & CyCTS)
+ info->icount.cts++;
+ if (mdm_change & CyDSR)
+ info->icount.dsr++;
+ if (mdm_change & CyRI)
+ info->icount.rng++;
+
+ wake_up_interruptible(&info->delta_msr_wait);
+ }
+
+ if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) {
+ if (!(mdm_status & CyDCD)) {
+ tty_hangup(info->tty);
+ info->flags &= ~ASYNC_NORMAL_ACTIVE;
+ }
+ wake_up_interruptible(&info->open_wait);
+ }
+ if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) {
+ if (info->tty->hw_stopped) {
+ if (mdm_status & CyCTS) {
+ /* cy_start isn't used
+ because... !!! */
+ info->tty->hw_stopped = 0;
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) |
+ CyTxRdy);
+ tty_wakeup(info->tty);
}
-/* if (mdm_change & CyDSR) {
+ } else {
+ if (!(mdm_status & CyCTS)) {
+ /* cy_stop isn't used
+ because ... !!! */
+ info->tty->hw_stopped = 1;
+ cy_writeb(base_addr + (CySRER << index),
+ readb(base_addr + (CySRER << index)) &
+ ~CyTxRdy);
}
- if (mdm_change & CyRI) {
- }*/
}
- /* end of service */
- cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
- cy_writeb(base_addr + (CyCAR << index), save_car);
- spin_unlock(&cinfo->card_lock);
}
+/* if (mdm_change & CyDSR) {
+ }
+ if (mdm_change & CyRI) {
+ }*/
+end:
+ /* end of service */
+ cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
+ cy_writeb(base_addr + (CyCAR << index), save_car);
}
/* The real interrupt service routine is called
@@ -1432,10 +1317,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
int status;
struct cyclades_card *cinfo = dev_id;
void __iomem *base_addr, *card_base_addr;
- int chip;
+ unsigned int chip, too_many, had_work;
int index;
- int too_many;
- int had_work;
if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
@@ -1470,11 +1353,16 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
chips to be checked in a round-robin fashion (after
draining each of a bunch (1000) of characters).
*/
- if (1000 < too_many++) {
+ if (1000 < too_many++)
break;
- }
- cyy_intr_chip(cinfo, chip, base_addr, status,
- index);
+ spin_lock(&cinfo->card_lock);
+ if (status & CySRReceive) /* rx intr */
+ cyy_chip_rx(cinfo, chip, base_addr);
+ if (status & CySRTransmit) /* tx intr */
+ cyy_chip_tx(cinfo, chip, base_addr);
+ if (status & CySRModem) /* modem intr */
+ cyy_chip_modem(cinfo, chip, base_addr);
+ spin_unlock(&cinfo->card_lock);
}
}
} while (had_work);
@@ -1529,7 +1417,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
struct ZFW_CTRL __iomem *zfw_ctrl;
struct BOARD_CTRL __iomem *board_ctrl;
__u32 __iomem *pci_doorbell;
- int index;
+ unsigned int index;
firm_id = cinfo->base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
@@ -1554,13 +1442,12 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
return 0;
} /* cyz_issue_cmd */
-static void
-cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+static void cyz_handle_rx(struct cyclades_port *info,
struct BUF_CTRL __iomem *buf_ctrl)
{
struct cyclades_card *cinfo = info->card;
struct tty_struct *tty = info->tty;
- int char_count;
+ unsigned int char_count;
int len;
#ifdef BLOCKMOVE
unsigned char *buf;
@@ -1633,9 +1520,11 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
char_count = rx_put - rx_get;
else
char_count = rx_put - rx_get + rx_bufsize;
- if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
- cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
- }
+ if (char_count >= readl(&buf_ctrl->rx_threshold) &&
+ !timer_pending(&cyz_rx_full_timer[
+ info->line]))
+ mod_timer(&cyz_rx_full_timer[info->line],
+ jiffies + 1);
#endif
info->idle_stats.recv_idle = jiffies;
tty_schedule_flip(tty);
@@ -1645,14 +1534,13 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
}
}
-static void
-cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+static void cyz_handle_tx(struct cyclades_port *info,
struct BUF_CTRL __iomem *buf_ctrl)
{
struct cyclades_card *cinfo = info->card;
struct tty_struct *tty = info->tty;
- char data;
- int char_count;
+ u8 data;
+ unsigned int char_count;
#ifdef BLOCKMOVE
int small_count;
#endif
@@ -1717,9 +1605,7 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
}
#endif
ztxdone:
- if (info->xmit_cnt < WAKEUP_CHARS) {
- cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
- }
+ tty_wakeup(tty);
/* Update tx_put */
cy_writel(&buf_ctrl->tx_put, tx_put);
}
@@ -1781,10 +1667,11 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
if ((fw_ver > 241 ? ((u_long) param) :
readl(&ch_ctrl->rs_status)) &
C_RS_DCD) {
- cy_sched_event(info,
- Cy_EVENT_OPEN_WAKEUP);
+ wake_up_interruptible(&info->open_wait);
} else {
- cy_sched_event(info, Cy_EVENT_HANGUP);
+ tty_hangup(info->tty);
+ wake_up_interruptible(&info->open_wait);
+ info->flags &= ~ASYNC_NORMAL_ACTIVE;
}
}
break;
@@ -1802,7 +1689,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
break;
#ifdef Z_WAKE
case C_CM_IOCTLW:
- cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+ complete(&info->shutdown_wait);
break;
#endif
#ifdef CONFIG_CYZ_INTR
@@ -1814,7 +1701,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
"port %ld\n", info->card, channel);
#endif
- cyz_handle_rx(info, ch_ctrl, buf_ctrl);
+ cyz_handle_rx(info, buf_ctrl);
break;
case C_CM_TXBEMPTY:
case C_CM_TXLOWWM:
@@ -1824,7 +1711,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
"port %ld\n", info->card, channel);
#endif
- cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+ cyz_handle_tx(info, buf_ctrl);
break;
#endif /* CONFIG_CYZ_INTR */
case C_CM_FATAL:
@@ -1834,7 +1721,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
break;
}
if (delta_count)
- cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP);
+ wake_up_interruptible(&info->delta_msr_wait);
if (special_count)
tty_schedule_flip(tty);
}
@@ -1893,10 +1780,9 @@ static void cyz_poll(unsigned long arg)
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
struct BOARD_CTRL __iomem *board_ctrl;
- struct CH_CTRL __iomem *ch_ctrl;
struct BUF_CTRL __iomem *buf_ctrl;
unsigned long expires = jiffies + HZ;
- int card, port;
+ unsigned int port, card;
for (card = 0; card < NR_CARDS; card++) {
cinfo = &cy_card[card];
@@ -1923,12 +1809,11 @@ static void cyz_poll(unsigned long arg)
for (port = 0; port < cinfo->nports; port++) {
info = &cinfo->ports[port];
tty = info->tty;
- ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
if (!info->throttle)
- cyz_handle_rx(info, ch_ctrl, buf_ctrl);
- cyz_handle_tx(info, ch_ctrl, buf_ctrl);
+ cyz_handle_rx(info, buf_ctrl);
+ cyz_handle_tx(info, buf_ctrl);
}
/* poll every 'cyz_polling_cycle' period */
expires = jiffies + cyz_polling_cycle;
@@ -2491,11 +2376,11 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
static int cy_open(struct tty_struct *tty, struct file *filp)
{
struct cyclades_port *info;
- unsigned int i;
- int retval, line;
+ unsigned int i, line;
+ int retval;
line = tty->index;
- if ((line < 0) || (NR_PORTS <= line)) {
+ if ((tty->index < 0) || (NR_PORTS <= line)) {
return -ENODEV;
}
for (i = 0; i < NR_CARDS; i++)
@@ -2812,7 +2697,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&card->card_lock, flags);
tty->closing = 0;
- info->event = 0;
info->tty = NULL;
if (info->blocked_open) {
spin_unlock_irqrestore(&card->card_lock, flags);
@@ -4444,7 +4328,6 @@ static void cy_hangup(struct tty_struct *tty)
cy_flush_buffer(tty);
shutdown(info);
- info->event = 0;
info->count = 0;
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
@@ -4467,9 +4350,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
{
struct cyclades_port *info;
u32 uninitialized_var(mailbox);
- unsigned int nports;
+ unsigned int nports, port;
unsigned short chip_number;
- int uninitialized_var(index), port;
+ int uninitialized_var(index);
spin_lock_init(&cinfo->card_lock);
@@ -4502,7 +4385,6 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
info->closing_wait = CLOSING_WAIT_DELAY;
info->close_delay = 5 * HZ / 10;
- INIT_WORK(&info->tqueue, do_softint);
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
init_completion(&info->shutdown_wait);
@@ -5236,7 +5118,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
}
}
#endif /* CONFIG_CYZ_INTR */
- cy_card[card_no].num_chips = -1;
+ cy_card[card_no].num_chips = (unsigned int)-1;
}
/* set cy_card */
@@ -5480,13 +5362,13 @@ static int __init cy_init(void)
#ifdef CONFIG_PCI
/* look for pci boards */
retval = pci_register_driver(&cy_pci_driver);
- if (retval && !nboards)
- goto err_unr;
+ if (retval && !nboards) {
+ tty_unregister_driver(cy_serial_driver);
+ goto err_frtty;
+ }
#endif
return 0;
-err_unr:
- tty_unregister_driver(cy_serial_driver);
err_frtty:
put_tty_driver(cy_serial_driver);
err:
@@ -5496,7 +5378,7 @@ err:
static void __exit cy_cleanup_module(void)
{
struct cyclades_card *card;
- int i, e1;
+ unsigned int i, e1;
#ifndef CONFIG_CYZ_INTR
del_timer_sync(&cyz_timerlist);
@@ -5524,8 +5406,7 @@ static void __exit cy_cleanup_module(void)
#endif /* CONFIG_CYZ_INTR */
)
free_irq(card->irq, card);
- for (e1 = card->first_line;
- e1 < card->first_line +
+ for (e1 = card->first_line; e1 < card->first_line +
card->nports; e1++)
tty_unregister_device(cy_serial_driver, e1);
kfree(card->ports);
diff --git a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped
index 453a2f1ffa1..0aa419a6176 100644
--- a/drivers/char/defkeymap.c_shipped
+++ b/drivers/char/defkeymap.c_shipped
@@ -222,7 +222,7 @@ char *func_table[MAX_NR_FUNC] = {
NULL,
};
-struct kbdiacr accent_table[MAX_DIACR] = {
+struct kbdiacruc accent_table[MAX_DIACR] = {
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index 0b7ffa5191c..ba3058dd39a 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -4,7 +4,7 @@
# This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
#
-config DRM
+menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
help
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index f89e57665b6..2b2407ee490 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -144,8 +144,8 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
return ret;
}
-int radeon_driver_vblank_do_wait(struct drm_device * dev, unsigned int *sequence,
- int crtc)
+static int radeon_driver_vblank_do_wait(struct drm_device * dev,
+ unsigned int *sequence, int crtc)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
diff --git a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
deleted file mode 100644
index 020011495d9..00000000000
--- a/drivers/char/ec3104_keyb.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * linux/drivers/char/ec3104_keyb.c
- *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *
- * based on linux/drivers/char/pc_keyb.c, which had the following comments:
- *
- * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
- * See keyboard.c for the whole history.
- *
- * Major cleanup by Martin Mares, May 1997
- *
- * Combined the keyboard and PS/2 mouse handling into one file,
- * because they share the same hardware.
- * Johan Myreen <jem@iki.fi> 1998-10-08.
- *
- * Code fixes to handle mouse ACKs properly.
- * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
- */
-/* EC3104 note:
- * This code was written without any documentation about the EC3104 chip. While
- * I hope I got most of the basic functionality right, the register names I use
- * are most likely completely different from those in the chip documentation.
- *
- * If you have any further information about the EC3104, please tell me
- * (prumpf@tux.org).
- */
-
-
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/delay.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/kbd_kern.h>
-#include <linux/bitops.h>
-
-#include <asm/keyboard.h>
-#include <asm/uaccess.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/ec3104.h>
-
-#include <asm/io.h>
-
-/* Some configuration switches are present in the include file... */
-
-#include <linux/pc_keyb.h>
-
-#define MSR_CTS 0x10
-#define MCR_RTS 0x02
-#define LSR_DR 0x01
-#define LSR_BOTH_EMPTY 0x60
-
-static struct e5_struct {
- u8 packet[8];
- int pos;
- int length;
-
- u8 cached_mcr;
- u8 last_msr;
-} ec3104_keyb;
-
-/* Simple translation table for the SysRq keys */
-
-
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned char ec3104_kbd_sysrq_xlate[128] =
- "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
- "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
- "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
- "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
- "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
- "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
- "\r\000/"; /* 0x60 - 0x6f */
-#endif
-
-static void kbd_write_command_w(int data);
-static void kbd_write_output_w(int data);
-#ifdef CONFIG_PSMOUSE
-static void aux_write_ack(int val);
-static void __aux_write_ack(int val);
-#endif
-
-static DEFINE_SPINLOCK(kbd_controller_lock);
-static unsigned char handle_kbd_event(void);
-
-/* used only by send_data - set by keyboard_interrupt */
-static volatile unsigned char reply_expected;
-static volatile unsigned char acknowledge;
-static volatile unsigned char resend;
-
-
-int ec3104_kbd_setkeycode(unsigned int scancode, unsigned int keycode)
-{
- return 0;
-}
-
-int ec3104_kbd_getkeycode(unsigned int scancode)
-{
- return 0;
-}
-
-
-/* yes, it probably would be faster to use an array. I don't care. */
-
-static inline unsigned char ec3104_scan2key(unsigned char scancode)
-{
- switch (scancode) {
- case 1: /* '`' */
- return 41;
-
- case 2 ... 27:
- return scancode;
-
- case 28: /* '\\' */
- return 43;
-
- case 29 ... 39:
- return scancode + 1;
-
- case 40: /* '\r' */
- return 28;
-
- case 41 ... 50:
- return scancode + 3;
-
- case 51: /* ' ' */
- return 57;
-
- case 52: /* escape */
- return 1;
-
- case 54: /* insert/delete (labelled delete) */
- /* this should arguably be 110, but I'd like to have ctrl-alt-del
- * working with a standard keymap */
- return 111;
-
- case 55: /* left */
- return 105;
- case 56: /* home */
- return 102;
- case 57: /* end */
- return 107;
- case 58: /* up */
- return 103;
- case 59: /* down */
- return 108;
- case 60: /* pgup */
- return 104;
- case 61: /* pgdown */
- return 109;
- case 62: /* right */
- return 106;
-
- case 79 ... 88: /* f1 - f10 */
- return scancode - 20;
-
- case 89 ... 90: /* f11 - f12 */
- return scancode - 2;
-
- case 91: /* left shift */
- return 42;
-
- case 92: /* right shift */
- return 54;
-
- case 93: /* left alt */
- return 56;
- case 94: /* right alt */
- return 100;
- case 95: /* left ctrl */
- return 29;
- case 96: /* right ctrl */
- return 97;
-
- case 97: /* caps lock */
- return 58;
- case 102: /* left windows */
- return 125;
- case 103: /* right windows */
- return 126;
-
- case 106: /* Fn */
- /* this is wrong. */
- return 84;
-
- default:
- return 0;
- }
-}
-
-int ec3104_kbd_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode)
-{
- scancode &= 0x7f;
-
- *keycode = ec3104_scan2key(scancode);
-
- return 1;
-}
-
-char ec3104_kbd_unexpected_up(unsigned char keycode)
-{
- return 0200;
-}
-
-static inline void handle_keyboard_event(unsigned char scancode)
-{
-#ifdef CONFIG_VT
- handle_scancode(scancode, !(scancode & 0x80));
-#endif
- tasklet_schedule(&keyboard_tasklet);
-}
-
-void ec3104_kbd_leds(unsigned char leds)
-{
-}
-
-static u8 e5_checksum(u8 *packet, int count)
-{
- int i;
- u8 sum = 0;
-
- for (i=0; i<count; i++)
- sum ^= packet[i];
-
- if (sum & 0x80)
- sum ^= 0xc0;
-
- return sum;
-}
-
-static void e5_wait_for_cts(struct e5_struct *k)
-{
- u8 msr;
-
- do {
- msr = ctrl_inb(EC3104_SER4_MSR);
- } while (!(msr & MSR_CTS));
-}
-
-
-static void e5_send_byte(u8 byte, struct e5_struct *k)
-{
- u8 status;
-
- do {
- status = ctrl_inb(EC3104_SER4_LSR);
- } while ((status & LSR_BOTH_EMPTY) != LSR_BOTH_EMPTY);
-
- printk("<%02x>", byte);
-
- ctrl_outb(byte, EC3104_SER4_DATA);
-
- do {
- status = ctrl_inb(EC3104_SER4_LSR);
- } while ((status & LSR_BOTH_EMPTY) != LSR_BOTH_EMPTY);
-
-}
-
-static int e5_send_packet(u8 *packet, int count, struct e5_struct *k)
-{
- int i;
-
- disable_irq(EC3104_IRQ_SER4);
-
- if (k->cached_mcr & MCR_RTS) {
- printk("e5_send_packet: too slow\n");
- enable_irq(EC3104_IRQ_SER4);
- return -EAGAIN;
- }
-
- k->cached_mcr |= MCR_RTS;
- ctrl_outb(k->cached_mcr, EC3104_SER4_MCR);
-
- e5_wait_for_cts(k);
-
- printk("p: ");
-
- for(i=0; i<count; i++)
- e5_send_byte(packet[i], k);
-
- e5_send_byte(e5_checksum(packet, count), k);
-
- printk("\n");
-
- udelay(1500);
-
- k->cached_mcr &= ~MCR_RTS;
- ctrl_outb(k->cached_mcr, EC3104_SER4_MCR);
-
- set_current_state(TASK_UNINTERRUPTIBLE);
-
-
-
- enable_irq(EC3104_IRQ_SER4);
-
-
-
- return 0;
-}
-
-/*
- * E5 packets we know about:
- * E5->host 0x80 0x05 <checksum> - resend packet
- * host->E5 0x83 0x43 <contrast> - set LCD contrast
- * host->E5 0x85 0x41 0x02 <brightness> 0x02 - set LCD backlight
- * E5->host 0x87 <ps2 packet> 0x00 <checksum> - external PS2
- * E5->host 0x88 <scancode> <checksum> - key press
- */
-
-static void e5_receive(struct e5_struct *k)
-{
- k->packet[k->pos++] = ctrl_inb(EC3104_SER4_DATA);
-
- if (k->pos == 1) {
- switch(k->packet[0]) {
- case 0x80:
- k->length = 3;
- break;
-
- case 0x87: /* PS2 ext */
- k->length = 6;
- break;
-
- case 0x88: /* keyboard */
- k->length = 3;
- break;
-
- default:
- k->length = 1;
- printk(KERN_WARNING "unknown E5 packet %02x\n",
- k->packet[0]);
- }
- }
-
- if (k->pos == k->length) {
- int i;
-
- if (e5_checksum(k->packet, k->length) != 0)
- printk(KERN_WARNING "E5: wrong checksum\n");
-
-#if 0
- printk("E5 packet [");
- for(i=0; i<k->length; i++) {
- printk("%02x ", k->packet[i]);
- }
-
- printk("(%02x)]\n", e5_checksum(k->packet, k->length-1));
-#endif
-
- switch(k->packet[0]) {
- case 0x80:
- case 0x88:
- handle_keyboard_event(k->packet[1]);
- break;
- }
-
- k->pos = k->length = 0;
- }
-}
-
-static void ec3104_keyb_interrupt(int irq, void *data)
-{
- struct e5_struct *k = &ec3104_keyb;
- u8 msr, lsr;
-
- msr = ctrl_inb(EC3104_SER4_MSR);
-
- if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) {
- if (k->cached_mcr & MCR_RTS)
- printk("confused: RTS already high\n");
- /* CTS went high. Send RTS. */
- k->cached_mcr |= MCR_RTS;
-
- ctrl_outb(k->cached_mcr, EC3104_SER4_MCR);
- } else if ((!(msr & MSR_CTS)) && (k->last_msr & MSR_CTS)) {
- /* CTS went low. */
- if (!(k->cached_mcr & MCR_RTS))
- printk("confused: RTS already low\n");
-
- k->cached_mcr &= ~MCR_RTS;
-
- ctrl_outb(k->cached_mcr, EC3104_SER4_MCR);
- }
-
- k->last_msr = msr;
-
- lsr = ctrl_inb(EC3104_SER4_LSR);
-
- if (lsr & LSR_DR)
- e5_receive(k);
-}
-
-static void ec3104_keyb_clear_state(void)
-{
- struct e5_struct *k = &ec3104_keyb;
- u8 msr, lsr;
-
- /* we want CTS to be low */
- k->last_msr = 0;
-
- for (;;) {
- msleep(100);
-
- msr = ctrl_inb(EC3104_SER4_MSR);
-
- lsr = ctrl_inb(EC3104_SER4_LSR);
-
- if (lsr & LSR_DR) {
- e5_receive(k);
- continue;
- }
-
- if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) {
- if (k->cached_mcr & MCR_RTS)
- printk("confused: RTS already high\n");
- /* CTS went high. Send RTS. */
- k->cached_mcr |= MCR_RTS;
-
- ctrl_outb(k->cached_mcr, EC3104_SER4_MCR);
- } else if ((!(msr & MSR_CTS)) && (k->last_msr & MSR_CTS)) {
- /* CTS went low. */
- if (!(k->cached_mcr & MCR_RTS))
- printk("confused: RTS already low\n");
-
- k->cached_mcr &= ~MCR_RTS;
-
- ctrl_outb(k->cached_mcr, EC3104_SER4_MCR);
- } else
- break;
-
- k->last_msr = msr;
-
- continue;
- }
-}
-
-void __init ec3104_kbd_init_hw(void)
-{
- ec3104_keyb.last_msr = ctrl_inb(EC3104_SER4_MSR);
- ec3104_keyb.cached_mcr = ctrl_inb(EC3104_SER4_MCR);
-
- ec3104_keyb_clear_state();
-
- /* Ok, finally allocate the IRQ, and off we go.. */
- request_irq(EC3104_IRQ_SER4, ec3104_keyb_interrupt, 0, "keyboard", NULL);
-}
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index c6c56fb8ba5..ffcecde9e2a 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -1,34 +1,30 @@
/*
-
-
Copyright (C) 1996 Digi International.
-
+
For technical support please email digiLinux@dgii.com or
call Digi tech support at (612) 912-3456
** This driver is no longer supported by Digi **
- Much of this design and code came from epca.c which was
- copyright (C) 1994, 1995 Troy De Jongh, and subsquently
- modified by David Nugent, Christoph Lameter, Mike McLagan.
-
- 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
---------------------------------------------------------------------------- */
-/* See README.epca for change history --DAT*/
+ Much of this design and code came from epca.c which was
+ copyright (C) 1994, 1995 Troy De Jongh, and subsquently
+ modified by David Nugent, Christoph Lameter, Mike McLagan.
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/* See README.epca for change history --DAT*/
#include <linux/module.h>
#include <linux/kernel.h>
@@ -54,13 +50,10 @@
#include "epca.h"
#include "epcaconfig.h"
-/* ---------------------- Begin defines ------------------------ */
-
#define VERSION "1.3.0.1-LK2.6"
/* This major needs to be submitted to Linux to join the majors list */
-
-#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */
+#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */
#define MAXCARDS 7
@@ -68,60 +61,48 @@
#define PFX "epca: "
-/* ----------------- Begin global definitions ------------------- */
-
static int nbdevs, num_cards, liloconfig;
static int digi_poller_inhibited = 1 ;
static int setup_error_code;
static int invalid_lilo_config;
-/* The ISA boards do window flipping into the same spaces so its only sane
- with a single lock. It's still pretty efficient */
-
+/*
+ * The ISA boards do window flipping into the same spaces so its only sane with
+ * a single lock. It's still pretty efficient.
+ */
static DEFINE_SPINLOCK(epca_lock);
-/* -----------------------------------------------------------------------
- MAXBOARDS is typically 12, but ISA and EISA cards are restricted to
- 7 below.
---------------------------------------------------------------------------*/
+/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. */
static struct board_info boards[MAXBOARDS];
-
-/* ------------- Begin structures used for driver registeration ---------- */
-
static struct tty_driver *pc_driver;
static struct tty_driver *pc_info;
/* ------------------ Begin Digi specific structures -------------------- */
-/* ------------------------------------------------------------------------
- digi_channels represents an array of structures that keep track of
- each channel of the Digi product. Information such as transmit and
- receive pointers, termio data, and signal definitions (DTR, CTS, etc ...)
- are stored here. This structure is NOT used to overlay the cards
- physical channel structure.
--------------------------------------------------------------------------- */
-
+/*
+ * digi_channels represents an array of structures that keep track of each
+ * channel of the Digi product. Information such as transmit and receive
+ * pointers, termio data, and signal definitions (DTR, CTS, etc ...) are stored
+ * here. This structure is NOT used to overlay the cards physical channel
+ * structure.
+ */
static struct channel digi_channels[MAX_ALLOC];
-/* ------------------------------------------------------------------------
- card_ptr is an array used to hold the address of the
- first channel structure of each card. This array will hold
- the addresses of various channels located in digi_channels.
--------------------------------------------------------------------------- */
+/*
+ * card_ptr is an array used to hold the address of the first channel structure
+ * of each card. This array will hold the addresses of various channels located
+ * in digi_channels.
+ */
static struct channel *card_ptr[MAXCARDS];
static struct timer_list epca_timer;
-/* ---------------------- Begin function prototypes --------------------- */
-
-/* ----------------------------------------------------------------------
- Begin generic memory functions. These functions will be alias
- (point at) more specific functions dependent on the board being
- configured.
------------------------------------------------------------------------ */
-
+/*
+ * Begin generic memory functions. These functions will be alias (point at)
+ * more specific functions dependent on the board being configured.
+ */
static void memwinon(struct board_info *b, unsigned int win);
static void memwinoff(struct board_info *b, unsigned int win);
static void globalwinon(struct channel *ch);
@@ -170,8 +151,6 @@ static void dummy_memoff(struct channel *ch);
static void dummy_assertgwinon(struct channel *ch);
static void dummy_assertmemoff(struct channel *ch);
-/* ------------------- Begin declare functions ----------------------- */
-
static struct channel *verifyChannel(struct tty_struct *);
static void pc_sched_event(struct channel *, int);
static void epca_error(int, char *);
@@ -213,62 +192,55 @@ static int pc_write(struct tty_struct *, const unsigned char *, int);
static int pc_init(void);
static int init_PCI(void);
-
-/* ------------------------------------------------------------------
- Table of functions for each board to handle memory. Mantaining
- parallelism is a *very* good idea here. The idea is for the
- runtime code to blindly call these functions, not knowing/caring
- about the underlying hardware. This stuff should contain no
- conditionals; if more functionality is needed a different entry
- should be established. These calls are the interface calls and
- are the only functions that should be accessed. Anyone caught
- making direct calls deserves what they get.
--------------------------------------------------------------------- */
-
+/*
+ * Table of functions for each board to handle memory. Mantaining parallelism
+ * is a *very* good idea here. The idea is for the runtime code to blindly call
+ * these functions, not knowing/caring about the underlying hardware. This
+ * stuff should contain no conditionals; if more functionality is needed a
+ * different entry should be established. These calls are the interface calls
+ * and are the only functions that should be accessed. Anyone caught making
+ * direct calls deserves what they get.
+ */
static void memwinon(struct board_info *b, unsigned int win)
{
- (b->memwinon)(b, win);
+ b->memwinon(b, win);
}
static void memwinoff(struct board_info *b, unsigned int win)
{
- (b->memwinoff)(b, win);
+ b->memwinoff(b, win);
}
static void globalwinon(struct channel *ch)
{
- (ch->board->globalwinon)(ch);
+ ch->board->globalwinon(ch);
}
static void rxwinon(struct channel *ch)
{
- (ch->board->rxwinon)(ch);
+ ch->board->rxwinon(ch);
}
static void txwinon(struct channel *ch)
{
- (ch->board->txwinon)(ch);
+ ch->board->txwinon(ch);
}
static void memoff(struct channel *ch)
{
- (ch->board->memoff)(ch);
+ ch->board->memoff(ch);
}
static void assertgwinon(struct channel *ch)
{
- (ch->board->assertgwinon)(ch);
+ ch->board->assertgwinon(ch);
}
static void assertmemoff(struct channel *ch)
{
- (ch->board->assertmemoff)(ch);
+ ch->board->assertmemoff(ch);
}
-/* ---------------------------------------------------------
- PCXEM windowing is the same as that used in the PCXR
- and CX series cards.
------------------------------------------------------------- */
-
+/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */
static void pcxem_memwinon(struct board_info *b, unsigned int win)
{
outb_p(FEPWIN|win, b->port + 1);
@@ -300,32 +272,30 @@ static void pcxem_memoff(struct channel *ch)
}
/* ----------------- Begin pcxe memory window stuff ------------------ */
-
static void pcxe_memwinon(struct board_info *b, unsigned int win)
{
- outb_p(FEPWIN | win, b->port + 1);
+ outb_p(FEPWIN | win, b->port + 1);
}
static void pcxe_memwinoff(struct board_info *b, unsigned int win)
{
- outb_p(inb(b->port) & ~FEPMEM,
- b->port + 1);
+ outb_p(inb(b->port) & ~FEPMEM, b->port + 1);
outb_p(0, b->port + 1);
}
static void pcxe_globalwinon(struct channel *ch)
{
- outb_p( FEPWIN, (int)ch->board->port + 1);
+ outb_p(FEPWIN, (int)ch->board->port + 1);
}
static void pcxe_rxwinon(struct channel *ch)
{
- outb_p(ch->rxwin, (int)ch->board->port + 1);
+ outb_p(ch->rxwin, (int)ch->board->port + 1);
}
static void pcxe_txwinon(struct channel *ch)
{
- outb_p(ch->txwin, (int)ch->board->port + 1);
+ outb_p(ch->txwin, (int)ch->board->port + 1);
}
static void pcxe_memoff(struct channel *ch)
@@ -335,10 +305,9 @@ static void pcxe_memoff(struct channel *ch)
}
/* ------------- Begin pc64xe and pcxi memory window stuff -------------- */
-
static void pcxi_memwinon(struct board_info *b, unsigned int win)
{
- outb_p(inb(b->port) | FEPMEM, b->port);
+ outb_p(inb(b->port) | FEPMEM, b->port);
}
static void pcxi_memwinoff(struct board_info *b, unsigned int win)
@@ -353,12 +322,12 @@ static void pcxi_globalwinon(struct channel *ch)
static void pcxi_rxwinon(struct channel *ch)
{
- outb_p(FEPMEM, ch->board->port);
+ outb_p(FEPMEM, ch->board->port);
}
static void pcxi_txwinon(struct channel *ch)
{
- outb_p(FEPMEM, ch->board->port);
+ outb_p(FEPMEM, ch->board->port);
}
static void pcxi_memoff(struct channel *ch)
@@ -376,16 +345,13 @@ static void pcxi_assertmemoff(struct channel *ch)
epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on");
}
-
-/* ----------------------------------------------------------------------
- Not all of the cards need specific memory windowing routines. Some
- cards (Such as PCI) needs no windowing routines at all. We provide
- these do nothing routines so that the same code base can be used.
- The driver will ALWAYS call a windowing routine if it thinks it needs
- to; regardless of the card. However, dependent on the card the routine
- may or may not do anything.
----------------------------------------------------------------------------*/
-
+/*
+ * Not all of the cards need specific memory windowing routines. Some cards
+ * (Such as PCI) needs no windowing routines at all. We provide these do
+ * nothing routines so that the same code base can be used. The driver will
+ * ALWAYS call a windowing routine if it thinks it needs to; regardless of the
+ * card. However, dependent on the card the routine may or may not do anything.
+ */
static void dummy_memwinon(struct board_info *b, unsigned int win)
{
}
@@ -418,15 +384,14 @@ static void dummy_assertmemoff(struct channel *ch)
{
}
-/* ----------------- Begin verifyChannel function ----------------------- */
static struct channel *verifyChannel(struct tty_struct *tty)
-{ /* Begin verifyChannel */
- /* --------------------------------------------------------------------
- This routine basically provides a sanity check. It insures that
- the channel returned is within the proper range of addresses as
- well as properly initialized. If some bogus info gets passed in
- through tty->driver_data this should catch it.
- --------------------------------------------------------------------- */
+{
+ /*
+ * This routine basically provides a sanity check. It insures that the
+ * channel returned is within the proper range of addresses as well as
+ * properly initialized. If some bogus info gets passed in
+ * through tty->driver_data this should catch it.
+ */
if (tty) {
struct channel *ch = (struct channel *)tty->driver_data;
if ((ch >= &digi_channels[0]) && (ch < &digi_channels[nbdevs])) {
@@ -435,62 +400,55 @@ static struct channel *verifyChannel(struct tty_struct *tty)
}
}
return NULL;
-
-} /* End verifyChannel */
-
-/* ------------------ Begin pc_sched_event ------------------------- */
+}
static void pc_sched_event(struct channel *ch, int event)
{
- /* ----------------------------------------------------------------------
- We call this to schedule interrupt processing on some event. The
- kernel sees our request and calls the related routine in OUR driver.
- -------------------------------------------------------------------------*/
+ /*
+ * We call this to schedule interrupt processing on some event. The
+ * kernel sees our request and calls the related routine in OUR driver.
+ */
ch->event |= 1 << event;
schedule_work(&ch->tqueue);
-} /* End pc_sched_event */
-
-/* ------------------ Begin epca_error ------------------------- */
+}
static void epca_error(int line, char *msg)
{
printk(KERN_ERR "epca_error (Digi): line = %d %s\n",line,msg);
}
-/* ------------------ Begin pc_close ------------------------- */
-static void pc_close(struct tty_struct * tty, struct file * filp)
+static void pc_close(struct tty_struct *tty, struct file *filp)
{
struct channel *ch;
unsigned long flags;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if ch != NULL */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
+ if ((ch = verifyChannel(tty)) != NULL) {
spin_lock_irqsave(&epca_lock, flags);
if (tty_hung_up_p(filp)) {
spin_unlock_irqrestore(&epca_lock, flags);
return;
}
- /* Check to see if the channel is open more than once */
if (ch->count-- > 1) {
/* Begin channel is open more than once */
- /* -------------------------------------------------------------
- Return without doing anything. Someone might still be using
- the channel.
- ---------------------------------------------------------------- */
+ /*
+ * Return without doing anything. Someone might still
+ * be using the channel.
+ */
spin_unlock_irqrestore(&epca_lock, flags);
return;
- } /* End channel is open more than once */
+ }
/* Port open only once go ahead with shutdown & reset */
BUG_ON(ch->count < 0);
- /* ---------------------------------------------------------------
- Let the rest of the driver know the channel is being closed.
- This becomes important if an open is attempted before close
- is finished.
- ------------------------------------------------------------------ */
+ /*
+ * Let the rest of the driver know the channel is being closed.
+ * This becomes important if an open is attempted before close
+ * is finished.
+ */
ch->asyncflags |= ASYNC_CLOSING;
tty->closing = 1;
@@ -498,7 +456,7 @@ static void pc_close(struct tty_struct * tty, struct file * filp)
if (ch->asyncflags & ASYNC_INITIALIZED) {
/* Setup an event to indicate when the transmit buffer empties */
- setup_empty_event(tty, ch);
+ setup_empty_event(tty, ch);
tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
}
if (tty->driver->flush_buffer)
@@ -513,27 +471,24 @@ static void pc_close(struct tty_struct * tty, struct file * filp)
ch->tty = NULL;
spin_unlock_irqrestore(&epca_lock, flags);
- if (ch->blocked_open) { /* Begin if blocked_open */
- if (ch->close_delay)
+ if (ch->blocked_open) {
+ if (ch->close_delay)
msleep_interruptible(jiffies_to_msecs(ch->close_delay));
wake_up_interruptible(&ch->open_wait);
- } /* End if blocked_open */
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
+ }
+ ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
ASYNC_CLOSING);
wake_up_interruptible(&ch->close_wait);
- } /* End if ch != NULL */
-} /* End pc_close */
-
-/* ------------------ Begin shutdown ------------------------- */
+ }
+}
static void shutdown(struct channel *ch)
-{ /* Begin shutdown */
-
+{
unsigned long flags;
struct tty_struct *tty;
struct board_chan __iomem *bc;
- if (!(ch->asyncflags & ASYNC_INITIALIZED))
+ if (!(ch->asyncflags & ASYNC_INITIALIZED))
return;
spin_lock_irqsave(&epca_lock, flags);
@@ -541,50 +496,40 @@ static void shutdown(struct channel *ch)
globalwinon(ch);
bc = ch->brdchan;
- /* ------------------------------------------------------------------
- In order for an event to be generated on the receipt of data the
- idata flag must be set. Since we are shutting down, this is not
- necessary clear this flag.
- --------------------------------------------------------------------- */
-
+ /*
+ * In order for an event to be generated on the receipt of data the
+ * idata flag must be set. Since we are shutting down, this is not
+ * necessary clear this flag.
+ */
if (bc)
writeb(0, &bc->idata);
tty = ch->tty;
- /* ----------------------------------------------------------------
- If we're a modem control device and HUPCL is on, drop RTS & DTR.
- ------------------------------------------------------------------ */
-
+ /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */
if (tty->termios->c_cflag & HUPCL) {
ch->omodem &= ~(ch->m_rts | ch->m_dtr);
fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1);
}
memoff(ch);
- /* ------------------------------------------------------------------
- The channel has officialy been closed. The next time it is opened
- it will have to reinitialized. Set a flag to indicate this.
- ---------------------------------------------------------------------- */
-
+ /*
+ * The channel has officialy been closed. The next time it is opened it
+ * will have to reinitialized. Set a flag to indicate this.
+ */
/* Prevent future Digi programmed interrupts from coming active */
-
ch->asyncflags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&epca_lock, flags);
-
-} /* End shutdown */
-
-/* ------------------ Begin pc_hangup ------------------------- */
+}
static void pc_hangup(struct tty_struct *tty)
-{ /* Begin pc_hangup */
+{
struct channel *ch;
-
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if ch != NULL */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
+ if ((ch = verifyChannel(tty)) != NULL) {
unsigned long flags;
if (tty->driver->flush_buffer)
@@ -599,15 +544,12 @@ static void pc_hangup(struct tty_struct *tty)
ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
spin_unlock_irqrestore(&epca_lock, flags);
wake_up_interruptible(&ch->open_wait);
- } /* End if ch != NULL */
-
-} /* End pc_hangup */
-
-/* ------------------ Begin pc_write ------------------------- */
+ }
+}
-static int pc_write(struct tty_struct * tty,
+static int pc_write(struct tty_struct *tty,
const unsigned char *buf, int bytesAvailable)
-{ /* Begin pc_write */
+{
unsigned int head, tail;
int dataLen;
int size;
@@ -617,25 +559,23 @@ static int pc_write(struct tty_struct * tty,
int remain;
struct board_chan __iomem *bc;
- /* ----------------------------------------------------------------
- pc_write is primarily called directly by the kernel routine
- tty_write (Though it can also be called by put_char) found in
- tty_io.c. pc_write is passed a line discipline buffer where
- the data to be written out is stored. The line discipline
- implementation itself is done at the kernel level and is not
- brought into the driver.
- ------------------------------------------------------------------- */
-
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
+ /*
+ * pc_write is primarily called directly by the kernel routine
+ * tty_write (Though it can also be called by put_char) found in
+ * tty_io.c. pc_write is passed a line discipline buffer where the data
+ * to be written out is stored. The line discipline implementation
+ * itself is done at the kernel level and is not brought into the
+ * driver.
+ */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
if ((ch = verifyChannel(tty)) == NULL)
return 0;
/* Make a pointer to the channel data structure found on the board. */
-
bc = ch->brdchan;
size = ch->txbufsize;
amountCopied = 0;
@@ -650,37 +590,36 @@ static int pc_write(struct tty_struct * tty,
tail = readw(&bc->tout);
tail &= (size - 1);
- /* If head >= tail, head has not wrapped around. */
- if (head >= tail) { /* Begin head has not wrapped */
- /* ---------------------------------------------------------------
- remain (much like dataLen above) represents the total amount of
- space available on the card for data. Here dataLen represents
- the space existing between the head pointer and the end of
- buffer. This is important because a memcpy cannot be told to
- automatically wrap around when it hits the buffer end.
- ------------------------------------------------------------------ */
+ if (head >= tail) {
+ /* head has not wrapped */
+ /*
+ * remain (much like dataLen above) represents the total amount
+ * of space available on the card for data. Here dataLen
+ * represents the space existing between the head pointer and
+ * the end of buffer. This is important because a memcpy cannot
+ * be told to automatically wrap around when it hits the buffer
+ * end.
+ */
dataLen = size - head;
remain = size - (head - tail) - 1;
- } else { /* Begin head has wrapped around */
-
+ } else {
+ /* head has wrapped around */
remain = tail - head - 1;
dataLen = remain;
-
- } /* End head has wrapped around */
- /* -------------------------------------------------------------------
- Check the space on the card. If we have more data than
- space; reduce the amount of data to fit the space.
- ---------------------------------------------------------------------- */
+ }
+ /*
+ * Check the space on the card. If we have more data than space; reduce
+ * the amount of data to fit the space.
+ */
bytesAvailable = min(remain, bytesAvailable);
txwinon(ch);
- while (bytesAvailable > 0)
- { /* Begin while there is data to copy onto card */
-
- /* -----------------------------------------------------------------
- If head is not wrapped, the below will make sure the first
- data copy fills to the end of card buffer.
- ------------------------------------------------------------------- */
+ while (bytesAvailable > 0) {
+ /* there is data to copy onto card */
+ /*
+ * If head is not wrapped, the below will make sure the first
+ * data copy fills to the end of card buffer.
+ */
dataLen = min(bytesAvailable, dataLen);
memcpy_toio(ch->txptr + head, buf, dataLen);
buf += dataLen;
@@ -692,7 +631,7 @@ static int pc_write(struct tty_struct * tty,
head = 0;
dataLen = tail;
}
- } /* End while there is data to copy onto card */
+ }
ch->statusflags |= TXBUSY;
globalwinon(ch);
writew(head, &bc->tin);
@@ -703,22 +642,16 @@ static int pc_write(struct tty_struct * tty,
}
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
- return(amountCopied);
-
-} /* End pc_write */
-
-/* ------------------ Begin pc_put_char ------------------------- */
+ return amountCopied;
+}
static void pc_put_char(struct tty_struct *tty, unsigned char c)
-{ /* Begin pc_put_char */
+{
pc_write(tty, &c, 1);
-} /* End pc_put_char */
-
-/* ------------------ Begin pc_write_room ------------------------- */
+}
static int pc_write_room(struct tty_struct *tty)
-{ /* Begin pc_write_room */
-
+{
int remain;
struct channel *ch;
unsigned long flags;
@@ -727,11 +660,10 @@ static int pc_write_room(struct tty_struct *tty)
remain = 0;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
-
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
if ((ch = verifyChannel(tty)) != NULL) {
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
@@ -757,14 +689,10 @@ static int pc_write_room(struct tty_struct *tty)
}
/* Return how much room is left on card */
return remain;
-
-} /* End pc_write_room */
-
-/* ------------------ Begin pc_chars_in_buffer ---------------------- */
+}
static int pc_chars_in_buffer(struct tty_struct *tty)
-{ /* Begin pc_chars_in_buffer */
-
+{
int chars;
unsigned int ctail, head, tail;
int remain;
@@ -772,13 +700,12 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
struct channel *ch;
struct board_chan __iomem *bc;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
-
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
if ((ch = verifyChannel(tty)) == NULL)
- return(0);
+ return 0;
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
@@ -793,45 +720,40 @@ static int pc_chars_in_buffer(struct tty_struct *tty)
else { /* Begin if some space on the card has been used */
head = readw(&bc->tin) & (ch->txbufsize - 1);
tail &= (ch->txbufsize - 1);
- /* --------------------------------------------------------------
- The logic here is basically opposite of the above pc_write_room
- here we are finding the amount of bytes in the buffer filled.
- Not the amount of bytes empty.
- ------------------------------------------------------------------- */
+ /*
+ * The logic here is basically opposite of the above
+ * pc_write_room here we are finding the amount of bytes in the
+ * buffer filled. Not the amount of bytes empty.
+ */
if ((remain = tail - head - 1) < 0 )
remain += ch->txbufsize;
chars = (int)(ch->txbufsize - remain);
- /* -------------------------------------------------------------
- Make it possible to wakeup anything waiting for output
- in tty_ioctl.c, etc.
-
- If not already set. Setup an event to indicate when the
- transmit buffer empties
- ----------------------------------------------------------------- */
+ /*
+ * Make it possible to wakeup anything waiting for output in
+ * tty_ioctl.c, etc.
+ *
+ * If not already set. Setup an event to indicate when the
+ * transmit buffer empties.
+ */
if (!(ch->statusflags & EMPTYWAIT))
setup_empty_event(tty,ch);
-
} /* End if some space on the card has been used */
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
/* Return number of characters residing on card. */
- return(chars);
-
-} /* End pc_chars_in_buffer */
-
-/* ------------------ Begin pc_flush_buffer ---------------------- */
+ return chars;
+}
static void pc_flush_buffer(struct tty_struct *tty)
-{ /* Begin pc_flush_buffer */
-
+{
unsigned int tail;
unsigned long flags;
struct channel *ch;
struct board_chan __iomem *bc;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
if ((ch = verifyChannel(tty)) == NULL)
return;
@@ -844,51 +766,47 @@ static void pc_flush_buffer(struct tty_struct *tty)
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
tty_wakeup(tty);
-} /* End pc_flush_buffer */
-
-/* ------------------ Begin pc_flush_chars ---------------------- */
+}
static void pc_flush_chars(struct tty_struct *tty)
-{ /* Begin pc_flush_chars */
- struct channel * ch;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
+{
+ struct channel *ch;
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
if ((ch = verifyChannel(tty)) != NULL) {
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
- /* ----------------------------------------------------------------
- If not already set and the transmitter is busy setup an event
- to indicate when the transmit empties.
- ------------------------------------------------------------------- */
+ /*
+ * If not already set and the transmitter is busy setup an
+ * event to indicate when the transmit empties.
+ */
if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT))
setup_empty_event(tty,ch);
spin_unlock_irqrestore(&epca_lock, flags);
}
-} /* End pc_flush_chars */
-
-/* ------------------ Begin block_til_ready ---------------------- */
+}
-static int block_til_ready(struct tty_struct *tty,
+static int block_til_ready(struct tty_struct *tty,
struct file *filp, struct channel *ch)
-{ /* Begin block_til_ready */
+{
DECLARE_WAITQUEUE(wait,current);
- int retval, do_clocal = 0;
+ int retval, do_clocal = 0;
unsigned long flags;
if (tty_hung_up_p(filp)) {
if (ch->asyncflags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
- return(retval);
+ retval = -ERESTARTSYS;
+ return retval;
}
- /* -----------------------------------------------------------------
- If the device is in the middle of being closed, then block
- until it's done, and then try again.
- -------------------------------------------------------------------- */
+ /*
+ * If the device is in the middle of being closed, then block until
+ * it's done, and then try again.
+ */
if (ch->asyncflags & ASYNC_CLOSING) {
interruptible_sleep_on(&ch->close_wait);
@@ -899,17 +817,17 @@ static int block_til_ready(struct tty_struct *tty,
}
if (filp->f_flags & O_NONBLOCK) {
- /* -----------------------------------------------------------------
- If non-blocking mode is set, then make the check up front
- and then exit.
- -------------------------------------------------------------------- */
+ /*
+ * If non-blocking mode is set, then make the check up front
+ * and then exit.
+ */
ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
if (tty->termios->c_cflag & CLOCAL)
do_clocal = 1;
/* Block waiting for the carrier detect and the line to become free */
-
+
retval = 0;
add_wait_queue(&ch->open_wait, &wait);
@@ -918,19 +836,18 @@ static int block_til_ready(struct tty_struct *tty,
if (!tty_hung_up_p(filp))
ch->count--;
ch->blocked_open++;
- while(1)
- { /* Begin forever while */
+ while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(ch->asyncflags & ASYNC_INITIALIZED))
+ !(ch->asyncflags & ASYNC_INITIALIZED))
{
if (ch->asyncflags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
- retval = -ERESTARTSYS;
+ retval = -ERESTARTSYS;
break;
}
- if (!(ch->asyncflags & ASYNC_CLOSING) &&
+ if (!(ch->asyncflags & ASYNC_CLOSING) &&
(do_clocal || (ch->imodem & ch->dcd)))
break;
if (signal_pending(current)) {
@@ -938,16 +855,15 @@ static int block_til_ready(struct tty_struct *tty,
break;
}
spin_unlock_irqrestore(&epca_lock, flags);
- /* ---------------------------------------------------------------
- Allow someone else to be scheduled. We will occasionally go
- through this loop until one of the above conditions change.
- The below schedule call will allow other processes to enter and
- prevent this loop from hogging the cpu.
- ------------------------------------------------------------------ */
+ /*
+ * Allow someone else to be scheduled. We will occasionally go
+ * through this loop until one of the above conditions change.
+ * The below schedule call will allow other processes to enter
+ * and prevent this loop from hogging the cpu.
+ */
schedule();
spin_lock_irqsave(&epca_lock, flags);
-
- } /* End forever while */
+ }
__set_current_state(TASK_RUNNING);
remove_wait_queue(&ch->open_wait, &wait);
@@ -962,13 +878,10 @@ static int block_til_ready(struct tty_struct *tty,
ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
return 0;
-} /* End block_til_ready */
-
-/* ------------------ Begin pc_open ---------------------- */
+}
static int pc_open(struct tty_struct *tty, struct file * filp)
-{ /* Begin pc_open */
-
+{
struct channel *ch;
unsigned long flags;
int line, retval, boardnum;
@@ -984,12 +897,11 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
/* Check status of board configured in system. */
- /* -----------------------------------------------------------------
- I check to see if the epca_setup routine detected an user error.
- It might be better to put this in pc_init, but for the moment it
- goes here.
- ---------------------------------------------------------------------- */
-
+ /*
+ * I check to see if the epca_setup routine detected an user error. It
+ * might be better to put this in pc_init, but for the moment it goes
+ * here.
+ */
if (invalid_lilo_config) {
if (setup_error_code & INVALID_BOARD_TYPE)
printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n");
@@ -1010,49 +922,48 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
tty->driver_data = NULL; /* Mark this device as 'down' */
return(-ENODEV);
}
-
+
if ((bc = ch->brdchan) == 0) {
tty->driver_data = NULL;
return -ENODEV;
}
spin_lock_irqsave(&epca_lock, flags);
- /* ------------------------------------------------------------------
- Every time a channel is opened, increment a counter. This is
- necessary because we do not wish to flush and shutdown the channel
- until the last app holding the channel open, closes it.
- --------------------------------------------------------------------- */
+ /*
+ * Every time a channel is opened, increment a counter. This is
+ * necessary because we do not wish to flush and shutdown the channel
+ * until the last app holding the channel open, closes it.
+ */
ch->count++;
- /* ----------------------------------------------------------------
- Set a kernel structures pointer to our local channel
- structure. This way we can get to it when passed only
- a tty struct.
- ------------------------------------------------------------------ */
+ /*
+ * Set a kernel structures pointer to our local channel structure. This
+ * way we can get to it when passed only a tty struct.
+ */
tty->driver_data = ch;
- /* ----------------------------------------------------------------
- If this is the first time the channel has been opened, initialize
- the tty->termios struct otherwise let pc_close handle it.
- -------------------------------------------------------------------- */
+ /*
+ * If this is the first time the channel has been opened, initialize
+ * the tty->termios struct otherwise let pc_close handle it.
+ */
globalwinon(ch);
ch->statusflags = 0;
/* Save boards current modem status */
ch->imodem = readb(&bc->mstat);
- /* ----------------------------------------------------------------
- Set receive head and tail ptrs to each other. This indicates
- no data available to read.
- ----------------------------------------------------------------- */
+ /*
+ * Set receive head and tail ptrs to each other. This indicates no data
+ * available to read.
+ */
head = readw(&bc->rin);
writew(head, &bc->rout);
/* Set the channels associated tty structure */
ch->tty = tty;
- /* -----------------------------------------------------------------
- The below routine generally sets up parity, baud, flow control
- issues, etc.... It effect both control flags and input flags.
- -------------------------------------------------------------------- */
+ /*
+ * The below routine generally sets up parity, baud, flow control
+ * issues, etc.... It effect both control flags and input flags.
+ */
epcaparam(tty,ch);
ch->asyncflags |= ASYNC_INITIALIZED;
memoff(ch);
@@ -1061,10 +972,10 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
retval = block_til_ready(tty, filp, ch);
if (retval)
return retval;
- /* -------------------------------------------------------------
- Set this again in case a hangup set it to zero while this
- open() was waiting for the line...
- --------------------------------------------------------------- */
+ /*
+ * Set this again in case a hangup set it to zero while this open() was
+ * waiting for the line...
+ */
spin_lock_irqsave(&epca_lock, flags);
ch->tty = tty;
globalwinon(ch);
@@ -1073,13 +984,12 @@ static int pc_open(struct tty_struct *tty, struct file * filp)
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
return 0;
-} /* End pc_open */
+}
static int __init epca_module_init(void)
-{ /* Begin init_module */
+{
return pc_init();
}
-
module_init(epca_module_init);
static struct pci_driver epca_driver;
@@ -1092,8 +1002,7 @@ static void __exit epca_module_exit(void)
del_timer_sync(&epca_timer);
- if ((tty_unregister_driver(pc_driver)) ||
- (tty_unregister_driver(pc_info)))
+ if (tty_unregister_driver(pc_driver) || tty_unregister_driver(pc_info))
{
printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n");
return;
@@ -1101,23 +1010,20 @@ static void __exit epca_module_exit(void)
put_tty_driver(pc_driver);
put_tty_driver(pc_info);
- for (crd = 0; crd < num_cards; crd++) { /* Begin for each card */
+ for (crd = 0; crd < num_cards; crd++) {
bd = &boards[crd];
- if (!bd)
- { /* Begin sanity check */
+ if (!bd) { /* sanity check */
printk(KERN_ERR "<Error> - Digi : cleanup_module failed\n");
return;
- } /* End sanity check */
+ }
ch = card_ptr[crd];
- for (count = 0; count < bd->numports; count++, ch++)
- { /* Begin for each port */
+ for (count = 0; count < bd->numports; count++, ch++) {
if (ch && ch->tty)
tty_hangup(ch->tty);
- } /* End for each port */
- } /* End for each card */
- pci_unregister_driver (&epca_driver);
+ }
+ }
+ pci_unregister_driver(&epca_driver);
}
-
module_exit(epca_module_exit);
static const struct tty_operations pc_ops = {
@@ -1148,10 +1054,8 @@ static struct tty_operations info_ops = {
.ioctl = info_ioctl,
};
-/* ------------------ Begin pc_init ---------------------- */
-
static int __init pc_init(void)
-{ /* Begin pc_init */
+{
int crd;
struct board_info *bd;
unsigned char board_id = 0;
@@ -1169,63 +1073,57 @@ static int __init pc_init(void)
if (!pc_info)
goto out2;
- /* -----------------------------------------------------------------------
- If epca_setup has not been ran by LILO set num_cards to defaults; copy
- board structure defined by digiConfig into drivers board structure.
- Note : If LILO has ran epca_setup then epca_setup will handle defining
- num_cards as well as copying the data into the board structure.
- -------------------------------------------------------------------------- */
- if (!liloconfig) { /* Begin driver has been configured via. epcaconfig */
-
+ /*
+ * If epca_setup has not been ran by LILO set num_cards to defaults;
+ * copy board structure defined by digiConfig into drivers board
+ * structure. Note : If LILO has ran epca_setup then epca_setup will
+ * handle defining num_cards as well as copying the data into the board
+ * structure.
+ */
+ if (!liloconfig) {
+ /* driver has been configured via. epcaconfig */
nbdevs = NBDEVS;
num_cards = NUMCARDS;
- memcpy((void *)&boards, (void *)&static_boards,
- (sizeof(struct board_info) * NUMCARDS));
- } /* End driver has been configured via. epcaconfig */
-
- /* -----------------------------------------------------------------
- Note : If lilo was used to configure the driver and the
- ignore epcaconfig option was choosen (digiepca=2) then
- nbdevs and num_cards will equal 0 at this point. This is
- okay; PCI cards will still be picked up if detected.
- --------------------------------------------------------------------- */
-
- /* -----------------------------------------------------------
- Set up interrupt, we will worry about memory allocation in
- post_fep_init.
- --------------------------------------------------------------- */
+ memcpy(&boards, &static_boards,
+ sizeof(struct board_info) * NUMCARDS);
+ }
+ /*
+ * Note : If lilo was used to configure the driver and the ignore
+ * epcaconfig option was choosen (digiepca=2) then nbdevs and num_cards
+ * will equal 0 at this point. This is okay; PCI cards will still be
+ * picked up if detected.
+ */
+ /*
+ * Set up interrupt, we will worry about memory allocation in
+ * post_fep_init.
+ */
printk(KERN_INFO "DIGI epca driver version %s loaded.\n",VERSION);
- /* ------------------------------------------------------------------
- NOTE : This code assumes that the number of ports found in
- the boards array is correct. This could be wrong if
- the card in question is PCI (And therefore has no ports
- entry in the boards structure.) The rest of the
- information will be valid for PCI because the beginning
- of pc_init scans for PCI and determines i/o and base
- memory addresses. I am not sure if it is possible to
- read the number of ports supported by the card prior to
- it being booted (Since that is the state it is in when
- pc_init is run). Because it is not possible to query the
- number of supported ports until after the card has booted;
- we are required to calculate the card_ptrs as the card is
- is initialized (Inside post_fep_init). The negative thing
- about this approach is that digiDload's call to GET_INFO
- will have a bad port value. (Since this is called prior
- to post_fep_init.)
-
- --------------------------------------------------------------------- */
-
+ /*
+ * NOTE : This code assumes that the number of ports found in the
+ * boards array is correct. This could be wrong if the card in question
+ * is PCI (And therefore has no ports entry in the boards structure.)
+ * The rest of the information will be valid for PCI because the
+ * beginning of pc_init scans for PCI and determines i/o and base
+ * memory addresses. I am not sure if it is possible to read the number
+ * of ports supported by the card prior to it being booted (Since that
+ * is the state it is in when pc_init is run). Because it is not
+ * possible to query the number of supported ports until after the card
+ * has booted; we are required to calculate the card_ptrs as the card
+ * is initialized (Inside post_fep_init). The negative thing about this
+ * approach is that digiDload's call to GET_INFO will have a bad port
+ * value. (Since this is called prior to post_fep_init.)
+ */
pci_boards_found = 0;
- if(num_cards < MAXBOARDS)
+ if (num_cards < MAXBOARDS)
pci_boards_found += init_PCI();
num_cards += pci_boards_found;
pc_driver->owner = THIS_MODULE;
- pc_driver->name = "ttyD";
- pc_driver->major = DIGI_MAJOR;
+ pc_driver->name = "ttyD";
+ pc_driver->major = DIGI_MAJOR;
pc_driver->minor_start = 0;
pc_driver->type = TTY_DRIVER_TYPE_SERIAL;
pc_driver->subtype = SERIAL_TYPE_NORMAL;
@@ -1256,120 +1154,108 @@ static int __init pc_init(void)
tty_set_operations(pc_info, &info_ops);
- for (crd = 0; crd < num_cards; crd++)
- { /* Begin for each card */
-
- /* ------------------------------------------------------------------
- This is where the appropriate memory handlers for the hardware is
- set. Everything at runtime blindly jumps through these vectors.
- ---------------------------------------------------------------------- */
+ for (crd = 0; crd < num_cards; crd++) {
+ /*
+ * This is where the appropriate memory handlers for the
+ * hardware is set. Everything at runtime blindly jumps through
+ * these vectors.
+ */
/* defined in epcaconfig.h */
bd = &boards[crd];
- switch (bd->type)
- { /* Begin switch on bd->type {board type} */
- case PCXEM:
- case EISAXEM:
- bd->memwinon = pcxem_memwinon ;
- bd->memwinoff = pcxem_memwinoff ;
- bd->globalwinon = pcxem_globalwinon ;
- bd->txwinon = pcxem_txwinon ;
- bd->rxwinon = pcxem_rxwinon ;
- bd->memoff = pcxem_memoff ;
- bd->assertgwinon = dummy_assertgwinon;
- bd->assertmemoff = dummy_assertmemoff;
- break;
-
- case PCIXEM:
- case PCIXRJ:
- case PCIXR:
- bd->memwinon = dummy_memwinon;
- bd->memwinoff = dummy_memwinoff;
- bd->globalwinon = dummy_globalwinon;
- bd->txwinon = dummy_txwinon;
- bd->rxwinon = dummy_rxwinon;
- bd->memoff = dummy_memoff;
- bd->assertgwinon = dummy_assertgwinon;
- bd->assertmemoff = dummy_assertmemoff;
- break;
-
- case PCXE:
- case PCXEVE:
-
- bd->memwinon = pcxe_memwinon;
- bd->memwinoff = pcxe_memwinoff;
- bd->globalwinon = pcxe_globalwinon;
- bd->txwinon = pcxe_txwinon;
- bd->rxwinon = pcxe_rxwinon;
- bd->memoff = pcxe_memoff;
- bd->assertgwinon = dummy_assertgwinon;
- bd->assertmemoff = dummy_assertmemoff;
- break;
-
- case PCXI:
- case PC64XE:
-
- bd->memwinon = pcxi_memwinon;
- bd->memwinoff = pcxi_memwinoff;
- bd->globalwinon = pcxi_globalwinon;
- bd->txwinon = pcxi_txwinon;
- bd->rxwinon = pcxi_rxwinon;
- bd->memoff = pcxi_memoff;
- bd->assertgwinon = pcxi_assertgwinon;
- bd->assertmemoff = pcxi_assertmemoff;
- break;
-
- default:
- break;
-
- } /* End switch on bd->type */
-
- /* ---------------------------------------------------------------
- Some cards need a memory segment to be defined for use in
- transmit and receive windowing operations. These boards
- are listed in the below switch. In the case of the XI the
- amount of memory on the board is variable so the memory_seg
- is also variable. This code determines what they segment
- should be.
- ----------------------------------------------------------------- */
-
- switch (bd->type)
- { /* Begin switch on bd->type {board type} */
-
- case PCXE:
- case PCXEVE:
- case PC64XE:
- bd->memory_seg = 0xf000;
+ switch (bd->type) {
+ case PCXEM:
+ case EISAXEM:
+ bd->memwinon = pcxem_memwinon;
+ bd->memwinoff = pcxem_memwinoff;
+ bd->globalwinon = pcxem_globalwinon;
+ bd->txwinon = pcxem_txwinon;
+ bd->rxwinon = pcxem_rxwinon;
+ bd->memoff = pcxem_memoff;
+ bd->assertgwinon = dummy_assertgwinon;
+ bd->assertmemoff = dummy_assertmemoff;
break;
- case PCXI:
- board_id = inb((int)bd->port);
- if ((board_id & 0x1) == 0x1)
- { /* Begin it's an XI card */
-
- /* Is it a 64K board */
- if ((board_id & 0x30) == 0)
- bd->memory_seg = 0xf000;
-
- /* Is it a 128K board */
- if ((board_id & 0x30) == 0x10)
- bd->memory_seg = 0xe000;
+ case PCIXEM:
+ case PCIXRJ:
+ case PCIXR:
+ bd->memwinon = dummy_memwinon;
+ bd->memwinoff = dummy_memwinoff;
+ bd->globalwinon = dummy_globalwinon;
+ bd->txwinon = dummy_txwinon;
+ bd->rxwinon = dummy_rxwinon;
+ bd->memoff = dummy_memoff;
+ bd->assertgwinon = dummy_assertgwinon;
+ bd->assertmemoff = dummy_assertmemoff;
+ break;
- /* Is is a 256K board */
- if ((board_id & 0x30) == 0x20)
- bd->memory_seg = 0xc000;
+ case PCXE:
+ case PCXEVE:
+ bd->memwinon = pcxe_memwinon;
+ bd->memwinoff = pcxe_memwinoff;
+ bd->globalwinon = pcxe_globalwinon;
+ bd->txwinon = pcxe_txwinon;
+ bd->rxwinon = pcxe_rxwinon;
+ bd->memoff = pcxe_memoff;
+ bd->assertgwinon = dummy_assertgwinon;
+ bd->assertmemoff = dummy_assertmemoff;
+ break;
- /* Is it a 512K board */
- if ((board_id & 0x30) == 0x30)
- bd->memory_seg = 0x8000;
+ case PCXI:
+ case PC64XE:
+ bd->memwinon = pcxi_memwinon;
+ bd->memwinoff = pcxi_memwinoff;
+ bd->globalwinon = pcxi_globalwinon;
+ bd->txwinon = pcxi_txwinon;
+ bd->rxwinon = pcxi_rxwinon;
+ bd->memoff = pcxi_memoff;
+ bd->assertgwinon = pcxi_assertgwinon;
+ bd->assertmemoff = pcxi_assertmemoff;
+ break;
- } else printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port);
+ default:
break;
+ }
- } /* End switch on bd->type */
+ /*
+ * Some cards need a memory segment to be defined for use in
+ * transmit and receive windowing operations. These boards are
+ * listed in the below switch. In the case of the XI the amount
+ * of memory on the board is variable so the memory_seg is also
+ * variable. This code determines what they segment should be.
+ */
+ switch (bd->type) {
+ case PCXE:
+ case PCXEVE:
+ case PC64XE:
+ bd->memory_seg = 0xf000;
+ break;
- } /* End for each card */
+ case PCXI:
+ board_id = inb((int)bd->port);
+ if ((board_id & 0x1) == 0x1) {
+ /* it's an XI card */
+ /* Is it a 64K board */
+ if ((board_id & 0x30) == 0)
+ bd->memory_seg = 0xf000;
+
+ /* Is it a 128K board */
+ if ((board_id & 0x30) == 0x10)
+ bd->memory_seg = 0xe000;
+
+ /* Is is a 256K board */
+ if ((board_id & 0x30) == 0x20)
+ bd->memory_seg = 0xc000;
+
+ /* Is it a 512K board */
+ if ((board_id & 0x30) == 0x30)
+ bd->memory_seg = 0x8000;
+ } else
+ printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n",(int)bd->port);
+ break;
+ }
+ }
err = tty_register_driver(pc_driver);
if (err) {
@@ -1383,10 +1269,7 @@ static int __init pc_init(void)
goto out4;
}
- /* -------------------------------------------------------------------
- Start up the poller to check for events on all enabled boards
- ---------------------------------------------------------------------- */
-
+ /* Start up the poller to check for events on all enabled boards */
init_timer(&epca_timer);
epca_timer.function = epcapoll;
mod_timer(&epca_timer, jiffies + HZ/25);
@@ -1400,51 +1283,47 @@ out2:
put_tty_driver(pc_driver);
out1:
return err;
-
-} /* End pc_init */
-
-/* ------------------ Begin post_fep_init ---------------------- */
+}
static void post_fep_init(unsigned int crd)
-{ /* Begin post_fep_init */
-
+{
int i;
void __iomem *memaddr;
struct global_data __iomem *gd;
struct board_info *bd;
struct board_chan __iomem *bc;
- struct channel *ch;
- int shrinkmem = 0, lowwater ;
-
- /* -------------------------------------------------------------
- This call is made by the user via. the ioctl call DIGI_INIT.
- It is responsible for setting up all the card specific stuff.
- ---------------------------------------------------------------- */
- bd = &boards[crd];
+ struct channel *ch;
+ int shrinkmem = 0, lowwater;
- /* -----------------------------------------------------------------
- If this is a PCI board, get the port info. Remember PCI cards
- do not have entries into the epcaconfig.h file, so we can't get
- the number of ports from it. Unfortunetly, this means that anyone
- doing a DIGI_GETINFO before the board has booted will get an invalid
- number of ports returned (It should return 0). Calls to DIGI_GETINFO
- after DIGI_INIT has been called will return the proper values.
- ------------------------------------------------------------------- */
+ /*
+ * This call is made by the user via. the ioctl call DIGI_INIT. It is
+ * responsible for setting up all the card specific stuff.
+ */
+ bd = &boards[crd];
+ /*
+ * If this is a PCI board, get the port info. Remember PCI cards do not
+ * have entries into the epcaconfig.h file, so we can't get the number
+ * of ports from it. Unfortunetly, this means that anyone doing a
+ * DIGI_GETINFO before the board has booted will get an invalid number
+ * of ports returned (It should return 0). Calls to DIGI_GETINFO after
+ * DIGI_INIT has been called will return the proper values.
+ */
if (bd->type >= PCIXEM) { /* Begin get PCI number of ports */
- /* --------------------------------------------------------------------
- Below we use XEMPORTS as a memory offset regardless of which PCI
- card it is. This is because all of the supported PCI cards have
- the same memory offset for the channel data. This will have to be
- changed if we ever develop a PCI/XE card. NOTE : The FEP manual
- states that the port offset is 0xC22 as opposed to 0xC02. This is
- only true for PC/XE, and PC/XI cards; not for the XEM, or CX series.
- On the PCI cards the number of ports is determined by reading a
- ID PROM located in the box attached to the card. The card can then
- determine the index the id to determine the number of ports available.
- (FYI - The id should be located at 0x1ac (And may use up to 4 bytes
- if the box in question is a XEM or CX)).
- ------------------------------------------------------------------------ */
+ /*
+ * Below we use XEMPORTS as a memory offset regardless of which
+ * PCI card it is. This is because all of the supported PCI
+ * cards have the same memory offset for the channel data. This
+ * will have to be changed if we ever develop a PCI/XE card.
+ * NOTE : The FEP manual states that the port offset is 0xC22
+ * as opposed to 0xC02. This is only true for PC/XE, and PC/XI
+ * cards; not for the XEM, or CX series. On the PCI cards the
+ * number of ports is determined by reading a ID PROM located
+ * in the box attached to the card. The card can then determine
+ * the index the id to determine the number of ports available.
+ * (FYI - The id should be located at 0x1ac (And may use up to
+ * 4 bytes if the box in question is a XEM or CX)).
+ */
/* PCI cards are already remapped at this point ISA are not */
bd->numports = readw(bd->re_map_membase + XEMPORTS);
epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports");
@@ -1465,95 +1344,87 @@ static void post_fep_init(unsigned int crd)
memaddr = bd->re_map_membase;
- /* -----------------------------------------------------------------
- The below assignment will set bc to point at the BEGINING of
- the cards channel structures. For 1 card there will be between
- 8 and 64 of these structures.
- -------------------------------------------------------------------- */
-
+ /*
+ * The below assignment will set bc to point at the BEGINING of the
+ * cards channel structures. For 1 card there will be between 8 and 64
+ * of these structures.
+ */
bc = memaddr + CHANSTRUCT;
- /* -------------------------------------------------------------------
- The below assignment will set gd to point at the BEGINING of
- global memory address 0xc00. The first data in that global
- memory actually starts at address 0xc1a. The command in
- pointer begins at 0xd10.
- ---------------------------------------------------------------------- */
-
+ /*
+ * The below assignment will set gd to point at the BEGINING of global
+ * memory address 0xc00. The first data in that global memory actually
+ * starts at address 0xc1a. The command in pointer begins at 0xd10.
+ */
gd = memaddr + GLOBAL;
- /* --------------------------------------------------------------------
- XEPORTS (address 0xc22) points at the number of channels the
- card supports. (For 64XE, XI, XEM, and XR use 0xc02)
- ----------------------------------------------------------------------- */
-
+ /*
+ * XEPORTS (address 0xc22) points at the number of channels the card
+ * supports. (For 64XE, XI, XEM, and XR use 0xc02)
+ */
if ((bd->type == PCXEVE || bd->type == PCXE) && (readw(memaddr + XEPORTS) < 3))
shrinkmem = 1;
if (bd->type < PCIXEM)
if (!request_region((int)bd->port, 4, board_desc[bd->type]))
- return;
+ return;
memwinon(bd, 0);
- /* --------------------------------------------------------------------
- Remember ch is the main drivers channels structure, while bc is
- the cards channel structure.
- ------------------------------------------------------------------------ */
-
- /* For every port on the card do ..... */
-
- for (i = 0; i < bd->numports; i++, ch++, bc++) { /* Begin for each port */
+ /*
+ * Remember ch is the main drivers channels structure, while bc is the
+ * cards channel structure.
+ */
+ for (i = 0; i < bd->numports; i++, ch++, bc++) {
unsigned long flags;
u16 tseg, rseg;
- ch->brdchan = bc;
- ch->mailbox = gd;
+ ch->brdchan = bc;
+ ch->mailbox = gd;
INIT_WORK(&ch->tqueue, do_softint);
- ch->board = &boards[crd];
+ ch->board = &boards[crd];
spin_lock_irqsave(&epca_lock, flags);
switch (bd->type) {
- /* ----------------------------------------------------------------
- Since some of the boards use different bitmaps for their
- control signals we cannot hard code these values and retain
- portability. We virtualize this data here.
- ------------------------------------------------------------------- */
- case EISAXEM:
- case PCXEM:
- case PCIXEM:
- case PCIXRJ:
- case PCIXR:
- ch->m_rts = 0x02 ;
- ch->m_dcd = 0x80 ;
- ch->m_dsr = 0x20 ;
- ch->m_cts = 0x10 ;
- ch->m_ri = 0x40 ;
- ch->m_dtr = 0x01 ;
- break;
-
- case PCXE:
- case PCXEVE:
- case PCXI:
- case PC64XE:
- ch->m_rts = 0x02 ;
- ch->m_dcd = 0x08 ;
- ch->m_dsr = 0x10 ;
- ch->m_cts = 0x20 ;
- ch->m_ri = 0x40 ;
- ch->m_dtr = 0x80 ;
- break;
-
- } /* End switch bd->type */
+ /*
+ * Since some of the boards use different bitmaps for
+ * their control signals we cannot hard code these
+ * values and retain portability. We virtualize this
+ * data here.
+ */
+ case EISAXEM:
+ case PCXEM:
+ case PCIXEM:
+ case PCIXRJ:
+ case PCIXR:
+ ch->m_rts = 0x02;
+ ch->m_dcd = 0x80;
+ ch->m_dsr = 0x20;
+ ch->m_cts = 0x10;
+ ch->m_ri = 0x40;
+ ch->m_dtr = 0x01;
+ break;
+
+ case PCXE:
+ case PCXEVE:
+ case PCXI:
+ case PC64XE:
+ ch->m_rts = 0x02;
+ ch->m_dcd = 0x08;
+ ch->m_dsr = 0x10;
+ ch->m_cts = 0x20;
+ ch->m_ri = 0x40;
+ ch->m_dtr = 0x80;
+ break;
+ }
if (boards[crd].altpin) {
ch->dsr = ch->m_dcd;
ch->dcd = ch->m_dsr;
ch->digiext.digi_flags |= DIGI_ALTPIN;
- }
- else {
+ } else {
ch->dcd = ch->m_dcd;
ch->dsr = ch->m_dsr;
}
-
+
ch->boardnum = crd;
ch->channelnum = i;
ch->magic = EPCA_MAGIC;
@@ -1568,71 +1439,67 @@ static void post_fep_init(unsigned int crd)
rseg = readw(&bc->rseg);
switch (bd->type) {
+ case PCIXEM:
+ case PCIXRJ:
+ case PCIXR:
+ /* Cover all the 2MEG cards */
+ ch->txptr = memaddr + ((tseg << 4) & 0x1fffff);
+ ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff);
+ ch->txwin = FEPWIN | (tseg >> 11);
+ ch->rxwin = FEPWIN | (rseg >> 11);
+ break;
- case PCIXEM:
- case PCIXRJ:
- case PCIXR:
- /* Cover all the 2MEG cards */
- ch->txptr = memaddr + ((tseg << 4) & 0x1fffff);
- ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff);
- ch->txwin = FEPWIN | (tseg >> 11);
- ch->rxwin = FEPWIN | (rseg >> 11);
- break;
-
- case PCXEM:
- case EISAXEM:
- /* Cover all the 32K windowed cards */
- /* Mask equal to window size - 1 */
- ch->txptr = memaddr + ((tseg << 4) & 0x7fff);
- ch->rxptr = memaddr + ((rseg << 4) & 0x7fff);
- ch->txwin = FEPWIN | (tseg >> 11);
- ch->rxwin = FEPWIN | (rseg >> 11);
- break;
-
- case PCXEVE:
- case PCXE:
- ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff);
- ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
- ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff);
- ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 );
- break;
-
- case PCXI:
- case PC64XE:
- ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4);
- ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4);
- ch->txwin = ch->rxwin = 0;
- break;
-
- } /* End switch bd->type */
+ case PCXEM:
+ case EISAXEM:
+ /* Cover all the 32K windowed cards */
+ /* Mask equal to window size - 1 */
+ ch->txptr = memaddr + ((tseg << 4) & 0x7fff);
+ ch->rxptr = memaddr + ((rseg << 4) & 0x7fff);
+ ch->txwin = FEPWIN | (tseg >> 11);
+ ch->rxwin = FEPWIN | (rseg >> 11);
+ break;
+
+ case PCXEVE:
+ case PCXE:
+ ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) & 0x1fff);
+ ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9);
+ ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) & 0x1fff);
+ ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >>9 );
+ break;
+
+ case PCXI:
+ case PC64XE:
+ ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4);
+ ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4);
+ ch->txwin = ch->rxwin = 0;
+ break;
+ }
ch->txbufhead = 0;
ch->txbufsize = readw(&bc->tmax) + 1;
-
+
ch->rxbufhead = 0;
ch->rxbufsize = readw(&bc->rmax) + 1;
-
+
lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2);
/* Set transmitter low water mark */
fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);
/* Set receiver low water mark */
-
fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0);
/* Set receiver high water mark */
-
fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0);
writew(100, &bc->edelay);
writeb(1, &bc->idata);
-
+
ch->startc = readb(&bc->startc);
ch->stopc = readb(&bc->stopc);
ch->startca = readb(&bc->startca);
ch->stopca = readb(&bc->stopca);
-
+
ch->fepcflag = 0;
ch->fepiflag = 0;
ch->fepoflag = 0;
@@ -1640,7 +1507,7 @@ static void post_fep_init(unsigned int crd)
ch->fepstopc = 0;
ch->fepstartca = 0;
ch->fepstopca = 0;
-
+
ch->close_delay = 50;
ch->count = 0;
ch->blocked_open = 0;
@@ -1648,80 +1515,66 @@ static void post_fep_init(unsigned int crd)
init_waitqueue_head(&ch->close_wait);
spin_unlock_irqrestore(&epca_lock, flags);
- } /* End for each port */
+ }
- printk(KERN_INFO
- "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
+ printk(KERN_INFO
+ "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n",
VERSION, board_desc[bd->type], (long)bd->port, (long)bd->membase, bd->numports);
memwinoff(bd, 0);
-
-} /* End post_fep_init */
-
-/* --------------------- Begin epcapoll ------------------------ */
+}
static void epcapoll(unsigned long ignored)
-{ /* Begin epcapoll */
-
+{
unsigned long flags;
int crd;
volatile unsigned int head, tail;
struct channel *ch;
struct board_info *bd;
- /* -------------------------------------------------------------------
- This routine is called upon every timer interrupt. Even though
- the Digi series cards are capable of generating interrupts this
- method of non-looping polling is more efficient. This routine
- checks for card generated events (Such as receive data, are transmit
- buffer empty) and acts on those events.
- ----------------------------------------------------------------------- */
-
- for (crd = 0; crd < num_cards; crd++)
- { /* Begin for each card */
-
+ /*
+ * This routine is called upon every timer interrupt. Even though the
+ * Digi series cards are capable of generating interrupts this method
+ * of non-looping polling is more efficient. This routine checks for
+ * card generated events (Such as receive data, are transmit buffer
+ * empty) and acts on those events.
+ */
+ for (crd = 0; crd < num_cards; crd++) {
bd = &boards[crd];
ch = card_ptr[crd];
if ((bd->status == DISABLED) || digi_poller_inhibited)
- continue; /* Begin loop next interation */
-
- /* -----------------------------------------------------------
- assertmemoff is not needed here; indeed it is an empty subroutine.
- It is being kept because future boards may need this as well as
- some legacy boards.
- ---------------------------------------------------------------- */
+ continue;
+ /*
+ * assertmemoff is not needed here; indeed it is an empty
+ * subroutine. It is being kept because future boards may need
+ * this as well as some legacy boards.
+ */
spin_lock_irqsave(&epca_lock, flags);
assertmemoff(ch);
globalwinon(ch);
- /* ---------------------------------------------------------------
- In this case head and tail actually refer to the event queue not
- the transmit or receive queue.
- ------------------------------------------------------------------- */
-
+ /*
+ * In this case head and tail actually refer to the event queue
+ * not the transmit or receive queue.
+ */
head = readw(&ch->mailbox->ein);
tail = readw(&ch->mailbox->eout);
-
- /* If head isn't equal to tail we have an event */
+ /* If head isn't equal to tail we have an event */
if (head != tail)
doevent(crd);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
-
} /* End for each card */
mod_timer(&epca_timer, jiffies + (HZ / 25));
-} /* End epcapoll */
-
-/* --------------------- Begin doevent ------------------------ */
+}
static void doevent(int crd)
-{ /* Begin doevent */
-
+{
void __iomem *eventbuf;
struct channel *ch, *chan0;
static struct tty_struct *tty;
@@ -1731,28 +1584,28 @@ static void doevent(int crd)
int event, channel;
int mstat, lstat;
- /* -------------------------------------------------------------------
- This subroutine is called by epcapoll when an event is detected
- in the event queue. This routine responds to those events.
- --------------------------------------------------------------------- */
+ /*
+ * This subroutine is called by epcapoll when an event is detected
+ * in the event queue. This routine responds to those events.
+ */
bd = &boards[crd];
chan0 = card_ptr[crd];
epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range");
assertgwinon(chan0);
- while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein)))
- { /* Begin while something in event queue */
+ while ((tail = readw(&chan0->mailbox->eout)) != (head = readw(&chan0->mailbox->ein))) { /* Begin while something in event queue */
assertgwinon(chan0);
eventbuf = bd->re_map_membase + tail + ISTART;
/* Get the channel the event occurred on */
channel = readb(eventbuf);
/* Get the actual event code that occurred */
event = readb(eventbuf + 1);
- /* ----------------------------------------------------------------
- The two assignments below get the current modem status (mstat)
- and the previous modem status (lstat). These are useful becuase
- an event could signal a change in modem signals itself.
- ------------------------------------------------------------------- */
+ /*
+ * The two assignments below get the current modem status
+ * (mstat) and the previous modem status (lstat). These are
+ * useful becuase an event could signal a change in modem
+ * signals itself.
+ */
mstat = readb(eventbuf + 2);
lstat = readb(eventbuf + 3);
@@ -1772,37 +1625,36 @@ static void doevent(int crd)
assertgwinon(ch);
} /* End DATA_IND */
/* else *//* Fix for DCD transition missed bug */
- if (event & MODEMCHG_IND) { /* Begin MODEMCHG_IND */
+ if (event & MODEMCHG_IND) {
/* A modem signal change has been indicated */
ch->imodem = mstat;
- if (ch->asyncflags & ASYNC_CHECK_CD) {
+ if (ch->asyncflags & ASYNC_CHECK_CD) {
if (mstat & ch->dcd) /* We are now receiving dcd */
wake_up_interruptible(&ch->open_wait);
else
pc_sched_event(ch, EPCA_EVENT_HANGUP); /* No dcd; hangup */
}
- } /* End MODEMCHG_IND */
+ }
tty = ch->tty;
- if (tty) { /* Begin if valid tty */
- if (event & BREAK_IND) { /* Begin if BREAK_IND */
+ if (tty) {
+ if (event & BREAK_IND) {
/* A break has been indicated */
tty_insert_flip_char(tty, 0, TTY_BREAK);
- tty_schedule_flip(tty);
- } else if (event & LOWTX_IND) { /* Begin LOWTX_IND */
- if (ch->statusflags & LOWWAIT)
- { /* Begin if LOWWAIT */
+ tty_schedule_flip(tty);
+ } else if (event & LOWTX_IND) {
+ if (ch->statusflags & LOWWAIT) {
ch->statusflags &= ~LOWWAIT;
tty_wakeup(tty);
- } /* End if LOWWAIT */
- } else if (event & EMPTYTX_IND) { /* Begin EMPTYTX_IND */
+ }
+ } else if (event & EMPTYTX_IND) {
/* This event is generated by setup_empty_event */
ch->statusflags &= ~TXBUSY;
- if (ch->statusflags & EMPTYWAIT) { /* Begin if EMPTYWAIT */
+ if (ch->statusflags & EMPTYWAIT) {
ch->statusflags &= ~EMPTYWAIT;
tty_wakeup(tty);
- } /* End if EMPTYWAIT */
- } /* End EMPTYTX_IND */
- } /* End if valid tty */
+ }
+ }
+ }
next:
globalwinon(ch);
BUG_ON(!bc);
@@ -1810,13 +1662,11 @@ static void doevent(int crd)
writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout);
globalwinon(chan0);
} /* End while something in event queue */
-} /* End doevent */
-
-/* --------------------- Begin fepcmd ------------------------ */
+}
static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
int byte2, int ncmds, int bytecmd)
-{ /* Begin fepcmd */
+{
unchar __iomem *memaddr;
unsigned int head, cmdTail, cmdStart, cmdMax;
long count;
@@ -1831,11 +1681,11 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
head = readw(&ch->mailbox->cin);
/* cmdStart is a base address */
cmdStart = readw(&ch->mailbox->cstart);
- /* ------------------------------------------------------------------
- We do the addition below because we do not want a max pointer
- relative to cmdStart. We want a max pointer that points at the
- physical end of the command queue.
- -------------------------------------------------------------------- */
+ /*
+ * We do the addition below because we do not want a max pointer
+ * relative to cmdStart. We want a max pointer that points at the
+ * physical end of the command queue.
+ */
cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax));
memaddr = ch->board->re_map_membase;
@@ -1860,7 +1710,7 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
writew(head, &ch->mailbox->cin);
count = FEPTIMEOUT;
- for (;;) { /* Begin forever loop */
+ for (;;) {
count--;
if (count == 0) {
printk(KERN_ERR "<Error> - Fep not responding in fepcmd()\n");
@@ -1869,26 +1719,23 @@ static void fepcmd(struct channel *ch, int cmd, int word_or_byte,
head = readw(&ch->mailbox->cin);
cmdTail = readw(&ch->mailbox->cout);
n = (head - cmdTail) & (cmdMax - cmdStart - 4);
- /* ----------------------------------------------------------
- Basically this will break when the FEP acknowledges the
- command by incrementing cmdTail (Making it equal to head).
- ------------------------------------------------------------- */
+ /*
+ * Basically this will break when the FEP acknowledges the
+ * command by incrementing cmdTail (Making it equal to head).
+ */
if (n <= ncmds * (sizeof(short) * 4))
- break; /* Well nearly forever :-) */
- } /* End forever loop */
-} /* End fepcmd */
-
-/* ---------------------------------------------------------------------
- Digi products use fields in their channels structures that are very
- similar to the c_cflag and c_iflag fields typically found in UNIX
- termios structures. The below three routines allow mappings
- between these hardware "flags" and their respective Linux flags.
-------------------------------------------------------------------------- */
-
-/* --------------------- Begin termios2digi_h -------------------- */
+ break;
+ }
+}
+/*
+ * Digi products use fields in their channels structures that are very similar
+ * to the c_cflag and c_iflag fields typically found in UNIX termios
+ * structures. The below three routines allow mappings between these hardware
+ * "flags" and their respective Linux flags.
+ */
static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
-{ /* Begin termios2digi_h */
+{
unsigned res = 0;
if (cflag & CRTSCTS) {
@@ -1918,86 +1765,73 @@ static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
ch->digiext.digi_flags |= CTSPACE;
return res;
+}
-} /* End termios2digi_h */
-
-/* --------------------- Begin termios2digi_i -------------------- */
static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
-{ /* Begin termios2digi_i */
-
- unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
+{
+ unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK |
INPCK | ISTRIP|IXON|IXANY|IXOFF);
if (ch->digiext.digi_flags & DIGI_AIXON)
res |= IAIXON;
return res;
-
-} /* End termios2digi_i */
-
-/* --------------------- Begin termios2digi_c -------------------- */
+}
static unsigned termios2digi_c(struct channel *ch, unsigned cflag)
-{ /* Begin termios2digi_c */
-
+{
unsigned res = 0;
- if (cflag & CBAUDEX) { /* Begin detected CBAUDEX */
+ if (cflag & CBAUDEX) {
ch->digiext.digi_flags |= DIGI_FAST;
- /* -------------------------------------------------------------
- HUPCL bit is used by FEP to indicate fast baud
- table is to be used.
- ----------------------------------------------------------------- */
+ /*
+ * HUPCL bit is used by FEP to indicate fast baud table is to
+ * be used.
+ */
res |= FEP_HUPCL;
- } /* End detected CBAUDEX */
- else ch->digiext.digi_flags &= ~DIGI_FAST;
- /* -------------------------------------------------------------------
- CBAUD has bit position 0x1000 set these days to indicate Linux
- baud rate remap. Digi hardware can't handle the bit assignment.
- (We use a different bit assignment for high speed.). Clear this
- bit out.
- ---------------------------------------------------------------------- */
+ } else
+ ch->digiext.digi_flags &= ~DIGI_FAST;
+ /*
+ * CBAUD has bit position 0x1000 set these days to indicate Linux
+ * baud rate remap. Digi hardware can't handle the bit assignment.
+ * (We use a different bit assignment for high speed.). Clear this
+ * bit out.
+ */
res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE);
- /* -------------------------------------------------------------
- This gets a little confusing. The Digi cards have their own
- representation of c_cflags controling baud rate. For the most
- part this is identical to the Linux implementation. However;
- Digi supports one rate (76800) that Linux doesn't. This means
- that the c_cflag entry that would normally mean 76800 for Digi
- actually means 115200 under Linux. Without the below mapping,
- a stty 115200 would only drive the board at 76800. Since
- the rate 230400 is also found after 76800, the same problem afflicts
- us when we choose a rate of 230400. Without the below modificiation
- stty 230400 would actually give us 115200.
-
- There are two additional differences. The Linux value for CLOCAL
- (0x800; 0004000) has no meaning to the Digi hardware. Also in
- later releases of Linux; the CBAUD define has CBAUDEX (0x1000;
- 0010000) ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX
- should be checked for a screened out prior to termios2digi_c
- returning. Since CLOCAL isn't used by the board this can be
- ignored as long as the returned value is used only by Digi hardware.
- ----------------------------------------------------------------- */
+ /*
+ * This gets a little confusing. The Digi cards have their own
+ * representation of c_cflags controling baud rate. For the most part
+ * this is identical to the Linux implementation. However; Digi
+ * supports one rate (76800) that Linux doesn't. This means that the
+ * c_cflag entry that would normally mean 76800 for Digi actually means
+ * 115200 under Linux. Without the below mapping, a stty 115200 would
+ * only drive the board at 76800. Since the rate 230400 is also found
+ * after 76800, the same problem afflicts us when we choose a rate of
+ * 230400. Without the below modificiation stty 230400 would actually
+ * give us 115200.
+ *
+ * There are two additional differences. The Linux value for CLOCAL
+ * (0x800; 0004000) has no meaning to the Digi hardware. Also in later
+ * releases of Linux; the CBAUD define has CBAUDEX (0x1000; 0010000)
+ * ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX should be
+ * checked for a screened out prior to termios2digi_c returning. Since
+ * CLOCAL isn't used by the board this can be ignored as long as the
+ * returned value is used only by Digi hardware.
+ */
if (cflag & CBAUDEX) {
- /* -------------------------------------------------------------
- The below code is trying to guarantee that only baud rates
- 115200 and 230400 are remapped. We use exclusive or because
- the various baud rates share common bit positions and therefore
- can't be tested for easily.
- ----------------------------------------------------------------- */
-
-
- if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) ||
+ /*
+ * The below code is trying to guarantee that only baud rates
+ * 115200 and 230400 are remapped. We use exclusive or because
+ * the various baud rates share common bit positions and
+ * therefore can't be tested for easily.
+ */
+ if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) ||
(!((cflag & 0x7) ^ (B230400 & ~CBAUDEX))))
res += 1;
}
return res;
-
-} /* End termios2digi_c */
-
-/* --------------------- Begin epcaparam ----------------------- */
+}
/* Caller must hold the locks */
static void epcaparam(struct tty_struct *tty, struct channel *ch)
-{ /* Begin epcaparam */
-
+{
unsigned int cmdHead;
struct ktermios *ts;
struct board_chan __iomem *bc;
@@ -2013,28 +1847,29 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
writew(cmdHead, &bc->rout);
cmdHead = readw(&bc->tin);
/* Changing baud in mid-stream transmission can be wonderful */
- /* ---------------------------------------------------------------
- Flush current transmit buffer by setting cmdTail pointer (tout)
- to cmdHead pointer (tin). Hopefully the transmit buffer is empty.
- ----------------------------------------------------------------- */
+ /*
+ * Flush current transmit buffer by setting cmdTail pointer
+ * (tout) to cmdHead pointer (tin). Hopefully the transmit
+ * buffer is empty.
+ */
fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0);
mval = 0;
- } else { /* Begin CBAUD not detected */
- /* -------------------------------------------------------------------
- c_cflags have changed but that change had nothing to do with BAUD.
- Propagate the change to the card.
- ---------------------------------------------------------------------- */
+ } else { /* Begin CBAUD not detected */
+ /*
+ * c_cflags have changed but that change had nothing to do with
+ * BAUD. Propagate the change to the card.
+ */
cflag = termios2digi_c(ch, ts->c_cflag);
if (cflag != ch->fepcflag) {
ch->fepcflag = cflag;
/* Set baud rate, char size, stop bits, parity */
fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0);
}
- /* ----------------------------------------------------------------
- If the user has not forced CLOCAL and if the device is not a
- CALLOUT device (Which is always CLOCAL) we set flags such that
- the driver will wait on carrier detect.
- ------------------------------------------------------------------- */
+ /*
+ * If the user has not forced CLOCAL and if the device is not a
+ * CALLOUT device (Which is always CLOCAL) we set flags such
+ * that the driver will wait on carrier detect.
+ */
if (ts->c_cflag & CLOCAL)
ch->asyncflags &= ~ASYNC_CHECK_CD;
else
@@ -2045,19 +1880,19 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
/* Check input mode flags */
if (iflag != ch->fepiflag) {
ch->fepiflag = iflag;
- /* ---------------------------------------------------------------
- Command sets channels iflag structure on the board. Such things
- as input soft flow control, handling of parity errors, and
- break handling are all set here.
- ------------------------------------------------------------------- */
+ /*
+ * Command sets channels iflag structure on the board. Such
+ * things as input soft flow control, handling of parity
+ * errors, and break handling are all set here.
+ */
/* break handling, parity handling, input stripping, flow control chars */
fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
}
- /* ---------------------------------------------------------------
- Set the board mint value for this channel. This will cause hardware
- events to be generated each time the DCD signal (Described in mint)
- changes.
- ------------------------------------------------------------------- */
+ /*
+ * Set the board mint value for this channel. This will cause hardware
+ * events to be generated each time the DCD signal (Described in mint)
+ * changes.
+ */
writeb(ch->dcd, &bc->mint);
if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD))
if (ch->digiext.digi_flags & DIGI_FORCEDCD)
@@ -2066,23 +1901,23 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
hflow = termios2digi_h(ch, ts->c_cflag);
if (hflow != ch->hflow) {
ch->hflow = hflow;
- /* --------------------------------------------------------------
- Hard flow control has been selected but the board is not
- using it. Activate hard flow control now.
- ----------------------------------------------------------------- */
+ /*
+ * Hard flow control has been selected but the board is not
+ * using it. Activate hard flow control now.
+ */
fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1);
}
mval ^= ch->modemfake & (mval ^ ch->modem);
if (ch->omodem ^ mval) {
ch->omodem = mval;
- /* --------------------------------------------------------------
- The below command sets the DTR and RTS mstat structure. If
- hard flow control is NOT active these changes will drive the
- output of the actual DTR and RTS lines. If hard flow control
- is active, the changes will be saved in the mstat structure and
- only asserted when hard flow control is turned off.
- ----------------------------------------------------------------- */
+ /*
+ * The below command sets the DTR and RTS mstat structure. If
+ * hard flow control is NOT active these changes will drive the
+ * output of the actual DTR and RTS lines. If hard flow control
+ * is active, the changes will be saved in the mstat structure
+ * and only asserted when hard flow control is turned off.
+ */
/* First reset DTR & RTS; then set them */
fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1);
@@ -2091,28 +1926,26 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) {
ch->fepstartc = ch->startc;
ch->fepstopc = ch->stopc;
- /* ------------------------------------------------------------
- The XON / XOFF characters have changed; propagate these
- changes to the card.
- --------------------------------------------------------------- */
+ /*
+ * The XON / XOFF characters have changed; propagate these
+ * changes to the card.
+ */
fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
}
if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) {
ch->fepstartca = ch->startca;
ch->fepstopca = ch->stopca;
- /* ---------------------------------------------------------------
- Similar to the above, this time the auxilarly XON / XOFF
- characters have changed; propagate these changes to the card.
- ------------------------------------------------------------------ */
+ /*
+ * Similar to the above, this time the auxilarly XON / XOFF
+ * characters have changed; propagate these changes to the card.
+ */
fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
}
-} /* End epcaparam */
+}
-/* --------------------- Begin receive_data ----------------------- */
/* Caller holds lock */
static void receive_data(struct channel *ch)
-{ /* Begin receive_data */
-
+{
unchar *rptr;
struct ktermios *ts = NULL;
struct tty_struct *tty;
@@ -2121,11 +1954,10 @@ static void receive_data(struct channel *ch)
unsigned int tail, head;
unsigned int wrapmask;
- /* ---------------------------------------------------------------
- This routine is called by doint when a receive data event
- has taken place.
- ------------------------------------------------------------------- */
-
+ /*
+ * This routine is called by doint when a receive data event has taken
+ * place.
+ */
globalwinon(ch);
if (ch->statusflags & RXSTOPPED)
return;
@@ -2136,10 +1968,10 @@ static void receive_data(struct channel *ch)
BUG_ON(!bc);
wrapmask = ch->rxbufsize - 1;
- /* ---------------------------------------------------------------------
- Get the head and tail pointers to the receiver queue. Wrap the
- head pointer if it has reached the end of the buffer.
- ------------------------------------------------------------------------ */
+ /*
+ * Get the head and tail pointers to the receiver queue. Wrap the head
+ * pointer if it has reached the end of the buffer.
+ */
head = readw(&bc->rin);
head &= wrapmask;
tail = readw(&bc->rout) & wrapmask;
@@ -2148,10 +1980,7 @@ static void receive_data(struct channel *ch)
if (bytesAvailable == 0)
return;
- /* ------------------------------------------------------------------
- If CREAD bit is off or device not open, set TX tail to head
- --------------------------------------------------------------------- */
-
+ /* If CREAD bit is off or device not open, set TX tail to head */
if (!tty || !ts || !(ts->c_cflag & CREAD)) {
writew(head, &bc->rout);
return;
@@ -2168,22 +1997,20 @@ static void receive_data(struct channel *ch)
rxwinon(ch);
while (bytesAvailable > 0) { /* Begin while there is data on the card */
wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
- /* ---------------------------------------------------------------
- Even if head has wrapped around only report the amount of
- data to be equal to the size - tail. Remember memcpy can't
- automaticly wrap around the receive buffer.
- ----------------------------------------------------------------- */
+ /*
+ * Even if head has wrapped around only report the amount of
+ * data to be equal to the size - tail. Remember memcpy can't
+ * automaticly wrap around the receive buffer.
+ */
dataToRead = (wrapgap < bytesAvailable) ? wrapgap : bytesAvailable;
- /* --------------------------------------------------------------
- Make sure we don't overflow the buffer
- ----------------------------------------------------------------- */
+ /* Make sure we don't overflow the buffer */
dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead);
if (dataToRead == 0)
break;
- /* ---------------------------------------------------------------
- Move data read from our card into the line disciplines buffer
- for translation if necessary.
- ------------------------------------------------------------------ */
+ /*
+ * Move data read from our card into the line disciplines
+ * buffer for translation if necessary.
+ */
memcpy_fromio(rptr, ch->rxptr + tail, dataToRead);
tail = (tail + dataToRead) & wrapmask;
bytesAvailable -= dataToRead;
@@ -2191,28 +2018,26 @@ static void receive_data(struct channel *ch)
globalwinon(ch);
writew(tail, &bc->rout);
/* Must be called with global data */
- tty_schedule_flip(ch->tty);
- return;
-} /* End receive_data */
+ tty_schedule_flip(ch->tty);
+}
-static int info_ioctl(struct tty_struct *tty, struct file * file,
+static int info_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- switch (cmd)
- { /* Begin switch cmd */
- case DIGI_GETINFO:
- { /* Begin case DIGI_GETINFO */
- struct digi_info di ;
+ switch (cmd) {
+ case DIGI_GETINFO:
+ {
+ struct digi_info di;
int brd;
- if(get_user(brd, (unsigned int __user *)arg))
+ if (get_user(brd, (unsigned int __user *)arg))
return -EFAULT;
if (brd < 0 || brd >= num_cards || num_cards == 0)
return -ENODEV;
memset(&di, 0, sizeof(di));
- di.board = brd ;
+ di.board = brd;
di.status = boards[brd].status;
di.type = boards[brd].type ;
di.numports = boards[brd].numports ;
@@ -2220,45 +2045,44 @@ static int info_ioctl(struct tty_struct *tty, struct file * file,
di.port = (unsigned char *)boards[brd].port ;
di.membase = (unsigned char *)boards[brd].membase ;
- if (copy_to_user((void __user *)arg, &di, sizeof (di)))
+ if (copy_to_user((void __user *)arg, &di, sizeof(di)))
return -EFAULT;
break;
- } /* End case DIGI_GETINFO */
-
- case DIGI_POLLER:
- { /* Begin case DIGI_POLLER */
+ }
- int brd = arg & 0xff000000 >> 16 ;
- unsigned char state = arg & 0xff ;
+ case DIGI_POLLER:
+ {
+ int brd = arg & 0xff000000 >> 16;
+ unsigned char state = arg & 0xff;
if (brd < 0 || brd >= num_cards) {
printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n");
- return (-ENODEV);
+ return -ENODEV;
}
- digi_poller_inhibited = state ;
- break ;
- } /* End case DIGI_POLLER */
-
- case DIGI_INIT:
- { /* Begin case DIGI_INIT */
- /* ------------------------------------------------------------
- This call is made by the apps to complete the initilization
- of the board(s). This routine is responsible for setting
- the card to its initial state and setting the drivers control
- fields to the sutianle settings for the card in question.
- ---------------------------------------------------------------- */
- int crd ;
- for (crd = 0; crd < num_cards; crd++)
- post_fep_init (crd);
- break ;
- } /* End case DIGI_INIT */
- default:
- return -ENOTTY;
- } /* End switch cmd */
- return (0) ;
+ digi_poller_inhibited = state;
+ break;
+ }
+
+ case DIGI_INIT:
+ {
+ /*
+ * This call is made by the apps to complete the
+ * initilization of the board(s). This routine is
+ * responsible for setting the card to its initial
+ * state and setting the drivers control fields to the
+ * sutianle settings for the card in question.
+ */
+ int crd;
+ for (crd = 0; crd < num_cards; crd++)
+ post_fep_init(crd);
+ break;
+ }
+ default:
+ return -ENOTTY;
+ }
+ return 0;
}
-/* --------------------- Begin pc_ioctl ----------------------- */
static int pc_tiocmget(struct tty_struct *tty, struct file *file)
{
@@ -2304,9 +2128,9 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file,
spin_lock_irqsave(&epca_lock, flags);
/*
- * I think this modemfake stuff is broken. It doesn't
- * correctly reflect the behaviour desired by the TIOCM*
- * ioctls. Therefore this is probably broken.
+ * I think this modemfake stuff is broken. It doesn't correctly reflect
+ * the behaviour desired by the TIOCM* ioctls. Therefore this is
+ * probably broken.
*/
if (set & TIOCM_RTS) {
ch->modemfake |= ch->m_rts;
@@ -2325,10 +2149,10 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file,
ch->modem &= ~ch->m_dtr;
}
globalwinon(ch);
- /* --------------------------------------------------------------
- The below routine generally sets up parity, baud, flow control
- issues, etc.... It effect both control flags and input flags.
- ------------------------------------------------------------------ */
+ /*
+ * The below routine generally sets up parity, baud, flow control
+ * issues, etc.... It effect both control flags and input flags.
+ */
epcaparam(tty,ch);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
@@ -2337,8 +2161,7 @@ static int pc_tiocmset(struct tty_struct *tty, struct file *file,
static int pc_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg)
-{ /* Begin pc_ioctl */
-
+{
digiflow_t dflow;
int retval;
unsigned long flags;
@@ -2347,49 +2170,47 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
struct board_chan __iomem *bc;
struct channel *ch = (struct channel *) tty->driver_data;
void __user *argp = (void __user *)arg;
-
+
if (ch)
bc = ch->brdchan;
- else
+ else
return -EINVAL;
- /* -------------------------------------------------------------------
- For POSIX compliance we need to add more ioctls. See tty_ioctl.c
- in /usr/src/linux/drivers/char for a good example. In particular
- think about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS.
- ---------------------------------------------------------------------- */
-
- switch (cmd)
- { /* Begin switch cmd */
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- /* Setup an event to indicate when the transmit buffer empties */
- spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- tty_wait_until_sent(tty, 0);
- if (!arg)
- digi_send_break(ch, HZ/4); /* 1/4 second */
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- retval = tty_check_change(tty);
- if (retval)
- return retval;
+ /*
+ * For POSIX compliance we need to add more ioctls. See tty_ioctl.c in
+ * /usr/src/linux/drivers/char for a good example. In particular think
+ * about adding TCSETAF, TCSETAW, TCSETA, TCSETSF, TCSETSW, TCSETS.
+ */
+ switch (cmd) {
+ case TCSBRK: /* SVID version: non-zero arg --> no break */
+ retval = tty_check_change(tty);
+ if (retval)
+ return retval;
+ /* Setup an event to indicate when the transmit buffer empties */
+ spin_lock_irqsave(&epca_lock, flags);
+ setup_empty_event(tty,ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+ tty_wait_until_sent(tty, 0);
+ if (!arg)
+ digi_send_break(ch, HZ / 4); /* 1/4 second */
+ return 0;
+ case TCSBRKP: /* support for POSIX tcsendbreak() */
+ retval = tty_check_change(tty);
+ if (retval)
+ return retval;
- /* Setup an event to indicate when the transmit buffer empties */
- spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- tty_wait_until_sent(tty, 0);
- digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
- return 0;
- case TIOCGSOFTCAR:
- if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg))
- return -EFAULT;
- return 0;
- case TIOCSSOFTCAR:
+ /* Setup an event to indicate when the transmit buffer empties */
+ spin_lock_irqsave(&epca_lock, flags);
+ setup_empty_event(tty,ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+ tty_wait_until_sent(tty, 0);
+ digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
+ return 0;
+ case TIOCGSOFTCAR:
+ if (put_user(C_CLOCAL(tty)?1:0, (unsigned long __user *)arg))
+ return -EFAULT;
+ return 0;
+ case TIOCSSOFTCAR:
{
unsigned int value;
@@ -2400,144 +2221,141 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file,
(value ? CLOCAL : 0));
return 0;
}
- case TIOCMODG:
- mflag = pc_tiocmget(tty, file);
- if (put_user(mflag, (unsigned long __user *)argp))
- return -EFAULT;
- break;
- case TIOCMODS:
- if (get_user(mstat, (unsigned __user *)argp))
- return -EFAULT;
- return pc_tiocmset(tty, file, mstat, ~mstat);
- case TIOCSDTR:
- spin_lock_irqsave(&epca_lock, flags);
- ch->omodem |= ch->m_dtr;
- globalwinon(ch);
- fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1);
- memoff(ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- break;
+ case TIOCMODG:
+ mflag = pc_tiocmget(tty, file);
+ if (put_user(mflag, (unsigned long __user *)argp))
+ return -EFAULT;
+ break;
+ case TIOCMODS:
+ if (get_user(mstat, (unsigned __user *)argp))
+ return -EFAULT;
+ return pc_tiocmset(tty, file, mstat, ~mstat);
+ case TIOCSDTR:
+ spin_lock_irqsave(&epca_lock, flags);
+ ch->omodem |= ch->m_dtr;
+ globalwinon(ch);
+ fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1);
+ memoff(ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+ break;
- case TIOCCDTR:
+ case TIOCCDTR:
+ spin_lock_irqsave(&epca_lock, flags);
+ ch->omodem &= ~ch->m_dtr;
+ globalwinon(ch);
+ fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1);
+ memoff(ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+ break;
+ case DIGI_GETA:
+ if (copy_to_user(argp, &ch->digiext, sizeof(digi_t)))
+ return -EFAULT;
+ break;
+ case DIGI_SETAW:
+ case DIGI_SETAF:
+ if (cmd == DIGI_SETAW) {
+ /* Setup an event to indicate when the transmit buffer empties */
spin_lock_irqsave(&epca_lock, flags);
- ch->omodem &= ~ch->m_dtr;
- globalwinon(ch);
- fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1);
- memoff(ch);
+ setup_empty_event(tty,ch);
spin_unlock_irqrestore(&epca_lock, flags);
- break;
- case DIGI_GETA:
- if (copy_to_user(argp, &ch->digiext, sizeof(digi_t)))
- return -EFAULT;
- break;
- case DIGI_SETAW:
- case DIGI_SETAF:
- if (cmd == DIGI_SETAW) {
- /* Setup an event to indicate when the transmit buffer empties */
- spin_lock_irqsave(&epca_lock, flags);
- setup_empty_event(tty,ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- tty_wait_until_sent(tty, 0);
- } else {
- /* ldisc lock already held in ioctl */
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
- }
- /* Fall Thru */
- case DIGI_SETA:
- if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
- return -EFAULT;
-
- if (ch->digiext.digi_flags & DIGI_ALTPIN) {
- ch->dcd = ch->m_dsr;
- ch->dsr = ch->m_dcd;
- } else {
- ch->dcd = ch->m_dcd;
- ch->dsr = ch->m_dsr;
+ tty_wait_until_sent(tty, 0);
+ } else {
+ /* ldisc lock already held in ioctl */
+ if (tty->ldisc.flush_buffer)
+ tty->ldisc.flush_buffer(tty);
+ }
+ /* Fall Thru */
+ case DIGI_SETA:
+ if (copy_from_user(&ch->digiext, argp, sizeof(digi_t)))
+ return -EFAULT;
+
+ if (ch->digiext.digi_flags & DIGI_ALTPIN) {
+ ch->dcd = ch->m_dsr;
+ ch->dsr = ch->m_dcd;
+ } else {
+ ch->dcd = ch->m_dcd;
+ ch->dsr = ch->m_dsr;
}
-
- spin_lock_irqsave(&epca_lock, flags);
- globalwinon(ch);
- /* -----------------------------------------------------------------
- The below routine generally sets up parity, baud, flow control
- issues, etc.... It effect both control flags and input flags.
- ------------------------------------------------------------------- */
+ spin_lock_irqsave(&epca_lock, flags);
+ globalwinon(ch);
- epcaparam(tty,ch);
- memoff(ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- break;
+ /*
+ * The below routine generally sets up parity, baud, flow
+ * control issues, etc.... It effect both control flags and
+ * input flags.
+ */
+ epcaparam(tty,ch);
+ memoff(ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+ break;
+
+ case DIGI_GETFLOW:
+ case DIGI_GETAFLOW:
+ spin_lock_irqsave(&epca_lock, flags);
+ globalwinon(ch);
+ if (cmd == DIGI_GETFLOW) {
+ dflow.startc = readb(&bc->startc);
+ dflow.stopc = readb(&bc->stopc);
+ } else {
+ dflow.startc = readb(&bc->startca);
+ dflow.stopc = readb(&bc->stopca);
+ }
+ memoff(ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+
+ if (copy_to_user(argp, &dflow, sizeof(dflow)))
+ return -EFAULT;
+ break;
+
+ case DIGI_SETAFLOW:
+ case DIGI_SETFLOW:
+ if (cmd == DIGI_SETFLOW) {
+ startc = ch->startc;
+ stopc = ch->stopc;
+ } else {
+ startc = ch->startca;
+ stopc = ch->stopca;
+ }
+
+ if (copy_from_user(&dflow, argp, sizeof(dflow)))
+ return -EFAULT;
- case DIGI_GETFLOW:
- case DIGI_GETAFLOW:
+ if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
- if (cmd == DIGI_GETFLOW) {
- dflow.startc = readb(&bc->startc);
- dflow.stopc = readb(&bc->stopc);
- } else {
- dflow.startc = readb(&bc->startca);
- dflow.stopc = readb(&bc->stopca);
- }
- memoff(ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- if (copy_to_user(argp, &dflow, sizeof(dflow)))
- return -EFAULT;
- break;
-
- case DIGI_SETAFLOW:
- case DIGI_SETFLOW:
if (cmd == DIGI_SETFLOW) {
- startc = ch->startc;
- stopc = ch->stopc;
+ ch->fepstartc = ch->startc = dflow.startc;
+ ch->fepstopc = ch->stopc = dflow.stopc;
+ fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
} else {
- startc = ch->startca;
- stopc = ch->stopca;
+ ch->fepstartca = ch->startca = dflow.startc;
+ ch->fepstopca = ch->stopca = dflow.stopc;
+ fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
}
- if (copy_from_user(&dflow, argp, sizeof(dflow)))
- return -EFAULT;
+ if (ch->statusflags & TXSTOPPED)
+ pc_start(tty);
- if (dflow.startc != startc || dflow.stopc != stopc) { /* Begin if setflow toggled */
- spin_lock_irqsave(&epca_lock, flags);
- globalwinon(ch);
-
- if (cmd == DIGI_SETFLOW) {
- ch->fepstartc = ch->startc = dflow.startc;
- ch->fepstopc = ch->stopc = dflow.stopc;
- fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
- } else {
- ch->fepstartca = ch->startca = dflow.startc;
- ch->fepstopca = ch->stopca = dflow.stopc;
- fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
- }
-
- if (ch->statusflags & TXSTOPPED)
- pc_start(tty);
-
- memoff(ch);
- spin_unlock_irqrestore(&epca_lock, flags);
- } /* End if setflow toggled */
- break;
- default:
- return -ENOIOCTLCMD;
- } /* End switch cmd */
+ memoff(ch);
+ spin_unlock_irqrestore(&epca_lock, flags);
+ } /* End if setflow toggled */
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
return 0;
-} /* End pc_ioctl */
-
-/* --------------------- Begin pc_set_termios ----------------------- */
+}
static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
-{ /* Begin pc_set_termios */
-
+{
struct channel *ch;
unsigned long flags;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
@@ -2554,47 +2372,40 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
wake_up_interruptible(&ch->open_wait);
} /* End if channel valid */
-
-} /* End pc_set_termios */
-
-/* --------------------- Begin do_softint ----------------------- */
+}
static void do_softint(struct work_struct *work)
-{ /* Begin do_softint */
+{
struct channel *ch = container_of(work, struct channel, tqueue);
/* Called in response to a modem change event */
- if (ch && ch->magic == EPCA_MAGIC) { /* Begin EPCA_MAGIC */
+ if (ch && ch->magic == EPCA_MAGIC) {
struct tty_struct *tty = ch->tty;
if (tty && tty->driver_data) {
- if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { /* Begin if clear_bit */
+ if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
tty_hangup(tty); /* FIXME: module removal race here - AKPM */
wake_up_interruptible(&ch->open_wait);
ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- } /* End if clear_bit */
+ }
}
- } /* End EPCA_MAGIC */
-} /* End do_softint */
-
-/* ------------------------------------------------------------
- pc_stop and pc_start provide software flow control to the
- routine and the pc_ioctl routine.
----------------------------------------------------------------- */
-
-/* --------------------- Begin pc_stop ----------------------- */
+ }
+}
+/*
+ * pc_stop and pc_start provide software flow control to the routine and the
+ * pc_ioctl routine.
+ */
static void pc_stop(struct tty_struct *tty)
-{ /* Begin pc_stop */
-
+{
struct channel *ch;
unsigned long flags;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if valid channel */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
+ if ((ch = verifyChannel(tty)) != NULL) {
spin_lock_irqsave(&epca_lock, flags);
- if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */
+ if ((ch->statusflags & TXSTOPPED) == 0) { /* Begin if transmit stop requested */
globalwinon(ch);
/* STOP transmitting now !! */
fepcmd(ch, PAUSETX, 0, 0, 0, 0);
@@ -2602,19 +2413,17 @@ static void pc_stop(struct tty_struct *tty)
memoff(ch);
} /* End if transmit stop requested */
spin_unlock_irqrestore(&epca_lock, flags);
- } /* End if valid channel */
-} /* End pc_stop */
-
-/* --------------------- Begin pc_start ----------------------- */
+ }
+}
static void pc_start(struct tty_struct *tty)
-{ /* Begin pc_start */
+{
struct channel *ch;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
+ if ((ch = verifyChannel(tty)) != NULL) {
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
/* Just in case output was resumed because of a change in Digi-flow */
@@ -2630,28 +2439,25 @@ static void pc_start(struct tty_struct *tty)
memoff(ch);
} /* End transmit resume requested */
spin_unlock_irqrestore(&epca_lock, flags);
- } /* End if channel valid */
-} /* End pc_start */
-
-/* ------------------------------------------------------------------
- The below routines pc_throttle and pc_unthrottle are used
- to slow (And resume) the receipt of data into the kernels
- receive buffers. The exact occurrence of this depends on the
- size of the kernels receive buffer and what the 'watermarks'
- are set to for that buffer. See the n_ttys.c file for more
- details.
-______________________________________________________________________ */
-/* --------------------- Begin throttle ----------------------- */
-
-static void pc_throttle(struct tty_struct * tty)
-{ /* Begin pc_throttle */
+ }
+}
+
+/*
+ * The below routines pc_throttle and pc_unthrottle are used to slow (And
+ * resume) the receipt of data into the kernels receive buffers. The exact
+ * occurrence of this depends on the size of the kernels receive buffer and
+ * what the 'watermarks' are set to for that buffer. See the n_ttys.c file for
+ * more details.
+ */
+static void pc_throttle(struct tty_struct *tty)
+{
struct channel *ch;
unsigned long flags;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
+ if ((ch = verifyChannel(tty)) != NULL) {
spin_lock_irqsave(&epca_lock, flags);
if ((ch->statusflags & RXSTOPPED) == 0) {
globalwinon(ch);
@@ -2660,20 +2466,18 @@ static void pc_throttle(struct tty_struct * tty)
memoff(ch);
}
spin_unlock_irqrestore(&epca_lock, flags);
- } /* End if channel valid */
-} /* End pc_throttle */
-
-/* --------------------- Begin unthrottle ----------------------- */
+ }
+}
static void pc_unthrottle(struct tty_struct *tty)
-{ /* Begin pc_unthrottle */
+{
struct channel *ch;
unsigned long flags;
- /* ---------------------------------------------------------
- verifyChannel returns the channel from the tty struct
- if it is valid. This serves as a sanity check.
- ------------------------------------------------------------- */
- if ((ch = verifyChannel(tty)) != NULL) { /* Begin if channel valid */
+ /*
+ * verifyChannel returns the channel from the tty struct if it is
+ * valid. This serves as a sanity check.
+ */
+ if ((ch = verifyChannel(tty)) != NULL) {
/* Just in case output was resumed because of a change in Digi-flow */
spin_lock_irqsave(&epca_lock, flags);
if (ch->statusflags & RXSTOPPED) {
@@ -2683,151 +2487,143 @@ static void pc_unthrottle(struct tty_struct *tty)
memoff(ch);
}
spin_unlock_irqrestore(&epca_lock, flags);
- } /* End if channel valid */
-} /* End pc_unthrottle */
-
-/* --------------------- Begin digi_send_break ----------------------- */
+ }
+}
void digi_send_break(struct channel *ch, int msec)
-{ /* Begin digi_send_break */
+{
unsigned long flags;
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
- /* --------------------------------------------------------------------
- Maybe I should send an infinite break here, schedule() for
- msec amount of time, and then stop the break. This way,
- the user can't screw up the FEP by causing digi_send_break()
- to be called (i.e. via an ioctl()) more than once in msec amount
- of time. Try this for now...
- ------------------------------------------------------------------------ */
+ /*
+ * Maybe I should send an infinite break here, schedule() for msec
+ * amount of time, and then stop the break. This way, the user can't
+ * screw up the FEP by causing digi_send_break() to be called (i.e. via
+ * an ioctl()) more than once in msec amount of time.
+ * Try this for now...
+ */
fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
-} /* End digi_send_break */
-
-/* --------------------- Begin setup_empty_event ----------------------- */
+}
/* Caller MUST hold the lock */
-
static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
-{ /* Begin setup_empty_event */
-
+{
struct board_chan __iomem *bc = ch->brdchan;
globalwinon(ch);
ch->statusflags |= EMPTYWAIT;
- /* ------------------------------------------------------------------
- When set the iempty flag request a event to be generated when the
- transmit buffer is empty (If there is no BREAK in progress).
- --------------------------------------------------------------------- */
+ /*
+ * When set the iempty flag request a event to be generated when the
+ * transmit buffer is empty (If there is no BREAK in progress).
+ */
writeb(1, &bc->iempty);
memoff(ch);
-} /* End setup_empty_event */
+}
-/* ---------------------- Begin epca_setup -------------------------- */
void epca_setup(char *str, int *ints)
-{ /* Begin epca_setup */
+{
struct board_info board;
int index, loop, last;
char *temp, *t2;
unsigned len;
- /* ----------------------------------------------------------------------
- If this routine looks a little strange it is because it is only called
- if a LILO append command is given to boot the kernel with parameters.
- In this way, we can provide the user a method of changing his board
- configuration without rebuilding the kernel.
- ----------------------------------------------------------------------- */
- if (!liloconfig)
- liloconfig = 1;
+ /*
+ * If this routine looks a little strange it is because it is only
+ * called if a LILO append command is given to boot the kernel with
+ * parameters. In this way, we can provide the user a method of
+ * changing his board configuration without rebuilding the kernel.
+ */
+ if (!liloconfig)
+ liloconfig = 1;
memset(&board, 0, sizeof(board));
/* Assume the data is int first, later we can change it */
/* I think that array position 0 of ints holds the number of args */
for (last = 0, index = 1; index <= ints[0]; index++)
- switch(index)
- { /* Begin parse switch */
- case 1:
- board.status = ints[index];
- /* ---------------------------------------------------------
- We check for 2 (As opposed to 1; because 2 is a flag
- instructing the driver to ignore epcaconfig.) For this
- reason we check for 2.
- ------------------------------------------------------------ */
- if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */
- nbdevs = 0;
- num_cards = 0;
- return;
- } /* End ignore epcaconfig as well as lilo cmd line */
-
- if (board.status > 2) {
- printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_BOARD_STATUS;
- return;
- }
- last = index;
- break;
- case 2:
- board.type = ints[index];
- if (board.type >= PCIXEM) {
- printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_BOARD_TYPE;
- return;
- }
- last = index;
- break;
- case 3:
- board.altpin = ints[index];
- if (board.altpin > 1) {
- printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_ALTPIN;
- return;
- }
- last = index;
- break;
-
- case 4:
- board.numports = ints[index];
- if (board.numports < 2 || board.numports > 256) {
- printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_NUM_PORTS;
- return;
- }
- nbdevs += board.numports;
- last = index;
- break;
-
- case 5:
- board.port = ints[index];
- if (ints[index] <= 0) {
- printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_PORT_BASE;
- return;
- }
- last = index;
- break;
-
- case 6:
- board.membase = ints[index];
- if (ints[index] <= 0) {
- printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_MEM_BASE;
- return;
- }
- last = index;
- break;
+ switch (index) { /* Begin parse switch */
+ case 1:
+ board.status = ints[index];
+ /*
+ * We check for 2 (As opposed to 1; because 2 is a flag
+ * instructing the driver to ignore epcaconfig.) For
+ * this reason we check for 2.
+ */
+ if (board.status == 2) { /* Begin ignore epcaconfig as well as lilo cmd line */
+ nbdevs = 0;
+ num_cards = 0;
+ return;
+ } /* End ignore epcaconfig as well as lilo cmd line */
+
+ if (board.status > 2) {
+ printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", board.status);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_BOARD_STATUS;
+ return;
+ }
+ last = index;
+ break;
+ case 2:
+ board.type = ints[index];
+ if (board.type >= PCIXEM) {
+ printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_BOARD_TYPE;
+ return;
+ }
+ last = index;
+ break;
+ case 3:
+ board.altpin = ints[index];
+ if (board.altpin > 1) {
+ printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_ALTPIN;
+ return;
+ }
+ last = index;
+ break;
+
+ case 4:
+ board.numports = ints[index];
+ if (board.numports < 2 || board.numports > 256) {
+ printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_NUM_PORTS;
+ return;
+ }
+ nbdevs += board.numports;
+ last = index;
+ break;
- default:
- printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n");
+ case 5:
+ board.port = ints[index];
+ if (ints[index] <= 0) {
+ printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_PORT_BASE;
return;
+ }
+ last = index;
+ break;
+
+ case 6:
+ board.membase = ints[index];
+ if (ints[index] <= 0) {
+ printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_MEM_BASE;
+ return;
+ }
+ last = index;
+ break;
+
+ default:
+ printk(KERN_ERR "<Error> - epca_setup: Too many integer parms\n");
+ return;
} /* End parse switch */
@@ -2844,120 +2640,121 @@ void epca_setup(char *str, int *ints)
/* Set index to the number of args + 1 */
index = last + 1;
- switch(index)
- {
- case 1:
- len = strlen(str);
- if (strncmp("Disable", str, len) == 0)
- board.status = 0;
- else if (strncmp("Enable", str, len) == 0)
- board.status = 1;
- else {
- printk(KERN_ERR "epca_setup: Invalid status %s\n", str);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_BOARD_STATUS;
- return;
- }
- last = index;
- break;
-
- case 2:
- for(loop = 0; loop < EPCA_NUM_TYPES; loop++)
- if (strcmp(board_desc[loop], str) == 0)
- break;
- /* ---------------------------------------------------------------
- If the index incremented above refers to a legitamate board
- type set it here.
- ------------------------------------------------------------------*/
- if (index < EPCA_NUM_TYPES)
- board.type = loop;
- else {
- printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_BOARD_TYPE;
- return;
- }
- last = index;
- break;
-
- case 3:
- len = strlen(str);
- if (strncmp("Disable", str, len) == 0)
- board.altpin = 0;
- else if (strncmp("Enable", str, len) == 0)
- board.altpin = 1;
- else {
- printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_ALTPIN;
- return;
- }
- last = index;
- break;
-
- case 4:
- t2 = str;
- while (isdigit(*t2))
- t2++;
-
- if (*t2) {
- printk(KERN_ERR "epca_setup: Invalid port count %s\n", str);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_NUM_PORTS;
- return;
- }
+ switch (index) {
+ case 1:
+ len = strlen(str);
+ if (strncmp("Disable", str, len) == 0)
+ board.status = 0;
+ else if (strncmp("Enable", str, len) == 0)
+ board.status = 1;
+ else {
+ printk(KERN_ERR "epca_setup: Invalid status %s\n", str);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_BOARD_STATUS;
+ return;
+ }
+ last = index;
+ break;
- /* ------------------------------------------------------------
- There is not a man page for simple_strtoul but the code can be
- found in vsprintf.c. The first argument is the string to
- translate (To an unsigned long obviously), the second argument
- can be the address of any character variable or a NULL. If a
- variable is given, the end pointer of the string will be stored
- in that variable; if a NULL is given the end pointer will
- not be returned. The last argument is the base to use. If
- a 0 is indicated, the routine will attempt to determine the
- proper base by looking at the values prefix (A '0' for octal,
- a 'x' for hex, etc ... If a value is given it will use that
- value as the base.
- ---------------------------------------------------------------- */
- board.numports = simple_strtoul(str, NULL, 0);
- nbdevs += board.numports;
- last = index;
- break;
-
- case 5:
- t2 = str;
- while (isxdigit(*t2))
- t2++;
-
- if (*t2) {
- printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_PORT_BASE;
- return;
- }
+ case 2:
+ for (loop = 0; loop < EPCA_NUM_TYPES; loop++)
+ if (strcmp(board_desc[loop], str) == 0)
+ break;
+ /*
+ * If the index incremented above refers to a
+ * legitamate board type set it here.
+ */
+ if (index < EPCA_NUM_TYPES)
+ board.type = loop;
+ else {
+ printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_BOARD_TYPE;
+ return;
+ }
+ last = index;
+ break;
- board.port = simple_strtoul(str, NULL, 16);
- last = index;
- break;
+ case 3:
+ len = strlen(str);
+ if (strncmp("Disable", str, len) == 0)
+ board.altpin = 0;
+ else if (strncmp("Enable", str, len) == 0)
+ board.altpin = 1;
+ else {
+ printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_ALTPIN;
+ return;
+ }
+ last = index;
+ break;
- case 6:
- t2 = str;
- while (isxdigit(*t2))
- t2++;
+ case 4:
+ t2 = str;
+ while (isdigit(*t2))
+ t2++;
- if (*t2) {
- printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str);
- invalid_lilo_config = 1;
- setup_error_code |= INVALID_MEM_BASE;
- return;
- }
- board.membase = simple_strtoul(str, NULL, 16);
- last = index;
- break;
- default:
- printk(KERN_ERR "epca: Too many string parms\n");
+ if (*t2) {
+ printk(KERN_ERR "epca_setup: Invalid port count %s\n", str);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_NUM_PORTS;
+ return;
+ }
+
+ /*
+ * There is not a man page for simple_strtoul but the
+ * code can be found in vsprintf.c. The first argument
+ * is the string to translate (To an unsigned long
+ * obviously), the second argument can be the address
+ * of any character variable or a NULL. If a variable
+ * is given, the end pointer of the string will be
+ * stored in that variable; if a NULL is given the end
+ * pointer will not be returned. The last argument is
+ * the base to use. If a 0 is indicated, the routine
+ * will attempt to determine the proper base by looking
+ * at the values prefix (A '0' for octal, a 'x' for
+ * hex, etc ... If a value is given it will use that
+ * value as the base.
+ */
+ board.numports = simple_strtoul(str, NULL, 0);
+ nbdevs += board.numports;
+ last = index;
+ break;
+
+ case 5:
+ t2 = str;
+ while (isxdigit(*t2))
+ t2++;
+
+ if (*t2) {
+ printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_PORT_BASE;
+ return;
+ }
+
+ board.port = simple_strtoul(str, NULL, 16);
+ last = index;
+ break;
+
+ case 6:
+ t2 = str;
+ while (isxdigit(*t2))
+ t2++;
+
+ if (*t2) {
+ printk(KERN_ERR "epca_setup: Invalid memory base %s\n",str);
+ invalid_lilo_config = 1;
+ setup_error_code |= INVALID_MEM_BASE;
return;
+ }
+ board.membase = simple_strtoul(str, NULL, 16);
+ last = index;
+ break;
+ default:
+ printk(KERN_ERR "epca: Too many string parms\n");
+ return;
}
str = temp;
} /* End while there is a string arg */
@@ -2966,19 +2763,16 @@ void epca_setup(char *str, int *ints)
printk(KERN_ERR "epca: Insufficient parms specified\n");
return;
}
-
+
/* I should REALLY validate the stuff here */
/* Copies our local copy of board into boards */
memcpy((void *)&boards[num_cards],(void *)&board, sizeof(board));
/* Does this get called once per lilo arg are what ? */
- printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
- num_cards, board_desc[board.type],
+ printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n",
+ num_cards, board_desc[board.type],
board.numports, (int)board.port, (unsigned int) board.membase);
num_cards++;
-} /* End epca_setup */
-
-
-/* ------------------------ Begin init_PCI --------------------------- */
+}
enum epic_board_types {
brd_xr = 0,
@@ -2987,7 +2781,6 @@ enum epic_board_types {
brd_xrj,
};
-
/* indexed directly by epic_board_types enum */
static struct {
unsigned char board_type;
@@ -2999,7 +2792,7 @@ static struct {
{ PCIXRJ, 2, },
};
-static int __devinit epca_init_one (struct pci_dev *pdev,
+static int __devinit epca_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static int board_num = -1;
@@ -3013,7 +2806,7 @@ static int __devinit epca_init_one (struct pci_dev *pdev,
board_idx = board_num + num_cards;
if (board_idx >= MAXBOARDS)
goto err_out;
-
+
addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx);
if (!addr) {
printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n",
@@ -3053,15 +2846,15 @@ static int __devinit epca_init_one (struct pci_dev *pdev,
goto err_out_free_memregion;
}
- /* --------------------------------------------------------------
- I don't know what the below does, but the hardware guys say
- its required on everything except PLX (In this case XRJ).
- ---------------------------------------------------------------- */
+ /*
+ * I don't know what the below does, but the hardware guys say its
+ * required on everything except PLX (In this case XRJ).
+ */
if (info_idx != brd_xrj) {
- pci_write_config_byte(pdev, 0x40, 0);
+ pci_write_config_byte(pdev, 0x40, 0);
pci_write_config_byte(pdev, 0x46, 0);
}
-
+
return 0;
err_out_free_memregion:
@@ -3086,7 +2879,7 @@ static struct pci_device_id epca_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
int __init init_PCI (void)
-{ /* Begin init_PCI */
+{
memset (&epca_driver, 0, sizeof (epca_driver));
epca_driver.name = "epca";
epca_driver.id_table = epca_pci_tbl;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 83c1151ec7a..8252f866853 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -69,6 +69,8 @@ static struct task_struct *hvc_task;
/* Picks up late kicks after list walk but before schedule() */
static int hvc_kicked;
+static int hvc_init(void);
+
#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif
@@ -754,6 +756,13 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
struct hvc_struct *hp;
int i;
+ /* We wait until a driver actually comes along */
+ if (!hvc_driver) {
+ int err = hvc_init();
+ if (err)
+ return ERR_PTR(err);
+ }
+
hp = kmalloc(ALIGN(sizeof(*hp), sizeof(long)) + outbuf_size,
GFP_KERNEL);
if (!hp)
@@ -829,16 +838,18 @@ int __devexit hvc_remove(struct hvc_struct *hp)
return 0;
}
-/* Driver initialization. Follow console initialization. This is where the TTY
- * interfaces start to become available. */
-static int __init hvc_init(void)
+/* Driver initialization: called as soon as someone uses hvc_alloc(). */
+static int hvc_init(void)
{
struct tty_driver *drv;
+ int err;
/* We need more than hvc_count adapters due to hotplug additions. */
drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
- if (!drv)
- return -ENOMEM;
+ if (!drv) {
+ err = -ENOMEM;
+ goto out;
+ }
drv->owner = THIS_MODULE;
drv->driver_name = "hvc";
@@ -854,30 +865,43 @@ static int __init hvc_init(void)
* added later. */
hvc_task = kthread_run(khvcd, NULL, "khvcd");
if (IS_ERR(hvc_task)) {
- panic("Couldn't create kthread for console.\n");
- put_tty_driver(drv);
- return -EIO;
+ printk(KERN_ERR "Couldn't create kthread for console.\n");
+ err = PTR_ERR(hvc_task);
+ goto put_tty;
}
- if (tty_register_driver(drv))
- panic("Couldn't register hvc console driver\n");
+ err = tty_register_driver(drv);
+ if (err) {
+ printk(KERN_ERR "Couldn't register hvc console driver\n");
+ goto stop_thread;
+ }
+ /* FIXME: This mb() seems completely random. Remove it. */
mb();
hvc_driver = drv;
return 0;
+
+put_tty:
+ put_tty_driver(hvc_driver);
+stop_thread:
+ kthread_stop(hvc_task);
+ hvc_task = NULL;
+out:
+ return err;
}
-module_init(hvc_init);
/* This isn't particularly necessary due to this being a console driver
* but it is nice to be thorough.
*/
static void __exit hvc_exit(void)
{
- kthread_stop(hvc_task);
+ if (hvc_driver) {
+ kthread_stop(hvc_task);
- tty_unregister_driver(hvc_driver);
- /* return tty_struct instances allocated in hvc_init(). */
- put_tty_driver(hvc_driver);
- unregister_console(&hvc_con_driver);
+ tty_unregister_driver(hvc_driver);
+ /* return tty_struct instances allocated in hvc_init(). */
+ put_tty_driver(hvc_driver);
+ unregister_console(&hvc_con_driver);
+ }
}
module_exit(hvc_exit);
diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c
index 3d6bd0baa56..efccb215583 100644
--- a/drivers/char/hvc_lguest.c
+++ b/drivers/char/hvc_lguest.c
@@ -115,7 +115,7 @@ static struct hv_ops lguest_cons = {
* (0), and the struct hv_ops containing the put_chars() function. */
static int __init cons_init(void)
{
- if (strcmp(paravirt_ops.name, "lguest") != 0)
+ if (strcmp(pv_info.name, "lguest") != 0)
return 0;
return hvc_instantiate(0, 0, &lguest_cons);
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index bd94d5f9e62..2124dce38f2 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -619,11 +619,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
ip2config.irq[i] = pci_dev_i->irq;
} else { // ann error
ip2config.addr[i] = 0;
- if (status == PCIBIOS_DEVICE_NOT_FOUND) {
- printk( KERN_ERR "IP2: PCI board %d not found\n", i );
- } else {
- printk( KERN_ERR "IP2: PCI error 0x%x \n", status );
- }
+ printk(KERN_ERR "IP2: PCI board %d not found\n", i);
}
}
#else
@@ -646,10 +642,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
if ( ip2config.addr[i] ) {
- pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL);
- if ( pB != NULL ) {
+ pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
+ if (pB) {
i2BoardPtrTable[i] = pB;
- memset( pB, 0, sizeof(i2eBordStr) );
iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer );
iiReset( pB );
} else {
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 6a01dd9e43f..5dc1265ce1d 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -221,10 +221,8 @@ struct ipmi_smi
void *send_info;
#ifdef CONFIG_PROC_FS
- /* A list of proc entries for this interface. This does not
- need a lock, only one thread creates it and only one thread
- destroys it. */
- spinlock_t proc_entry_lock;
+ /* A list of proc entries for this interface. */
+ struct mutex proc_entry_lock;
struct ipmi_proc_entry *proc_entries;
#endif
@@ -1891,11 +1889,11 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
file->write_proc = write_proc;
file->owner = owner;
- spin_lock(&smi->proc_entry_lock);
+ mutex_lock(&smi->proc_entry_lock);
/* Stick it on the list. */
entry->next = smi->proc_entries;
smi->proc_entries = entry;
- spin_unlock(&smi->proc_entry_lock);
+ mutex_unlock(&smi->proc_entry_lock);
}
#endif /* CONFIG_PROC_FS */
@@ -1939,7 +1937,7 @@ static void remove_proc_entries(ipmi_smi_t smi)
#ifdef CONFIG_PROC_FS
struct ipmi_proc_entry *entry;
- spin_lock(&smi->proc_entry_lock);
+ mutex_lock(&smi->proc_entry_lock);
while (smi->proc_entries) {
entry = smi->proc_entries;
smi->proc_entries = entry->next;
@@ -1948,7 +1946,7 @@ static void remove_proc_entries(ipmi_smi_t smi)
kfree(entry->name);
kfree(entry);
}
- spin_unlock(&smi->proc_entry_lock);
+ mutex_unlock(&smi->proc_entry_lock);
remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
#endif /* CONFIG_PROC_FS */
}
@@ -2614,6 +2612,14 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
return;
}
+void ipmi_poll_interface(ipmi_user_t user)
+{
+ ipmi_smi_t intf = user->intf;
+
+ if (intf->handlers->poll)
+ intf->handlers->poll(intf->send_info);
+}
+
int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
void *send_info,
struct ipmi_device_id *device_id,
@@ -2671,7 +2677,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
}
intf->curr_seq = 0;
#ifdef CONFIG_PROC_FS
- spin_lock_init(&intf->proc_entry_lock);
+ mutex_init(&intf->proc_entry_lock);
#endif
spin_lock_init(&intf->waiting_msgs_lock);
INIT_LIST_HEAD(&intf->waiting_msgs);
@@ -4136,7 +4142,7 @@ static __exit void cleanup_ipmi(void)
del_timer_sync(&ipmi_timer);
#ifdef CONFIG_PROC_FS
- remove_proc_entry(proc_ipmi_root->name, &proc_root);
+ remove_proc_entry(proc_ipmi_root->name, NULL);
#endif /* CONFIG_PROC_FS */
driver_unregister(&ipmidriver);
@@ -4166,6 +4172,7 @@ EXPORT_SYMBOL(ipmi_destroy_user);
EXPORT_SYMBOL(ipmi_get_version);
EXPORT_SYMBOL(ipmi_request_settime);
EXPORT_SYMBOL(ipmi_request_supply_msgs);
+EXPORT_SYMBOL(ipmi_poll_interface);
EXPORT_SYMBOL(ipmi_register_smi);
EXPORT_SYMBOL(ipmi_unregister_smi);
EXPORT_SYMBOL(ipmi_register_for_cmd);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index c1222e98525..4f560d0bb80 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -675,7 +675,8 @@ static void handle_transaction_done(struct smi_info *smi_info)
}
/* Called on timeouts and events. Timeouts should pass the elapsed
- time, interrupts should pass in zero. */
+ time, interrupts should pass in zero. Must be called with
+ si_lock held and interrupts disabled. */
static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
int time)
{
@@ -892,13 +893,16 @@ static int ipmi_thread(void *data)
static void poll(void *send_info)
{
struct smi_info *smi_info = send_info;
+ unsigned long flags;
/*
* Make sure there is some delay in the poll loop so we can
* drive time forward and timeout things.
*/
udelay(10);
+ spin_lock_irqsave(&smi_info->si_lock, flags);
smi_event_handler(smi_info, 10);
+ spin_unlock_irqrestore(&smi_info->si_lock, flags);
}
static void request_events(void *send_info)
@@ -1006,6 +1010,10 @@ static int smi_start_processing(void *send_info,
new_smi->intf = intf;
+ /* Try to claim any interrupts. */
+ if (new_smi->irq_setup)
+ new_smi->irq_setup(new_smi);
+
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
new_smi->last_timeout_jiffies = jiffies;
@@ -2372,20 +2380,9 @@ static int try_get_dev_id(struct smi_info *smi_info)
/* Otherwise, we got some data. */
resp_len = smi_info->handlers->get_result(smi_info->si_sm,
resp, IPMI_MAX_MSG_LENGTH);
- if (resp_len < 14) {
- /* That's odd, it should be longer. */
- rv = -EINVAL;
- goto out;
- }
- if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) {
- /* That's odd, it shouldn't be able to fail. */
- rv = -EINVAL;
- goto out;
- }
-
- /* Record info from the get device id, in case we need it. */
- ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id);
+ /* Check and record info from the get device id, in case we need it. */
+ rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id);
out:
kfree(resp);
@@ -2765,10 +2762,6 @@ static int try_smi_init(struct smi_info *new_smi)
setup_oem_data_handler(new_smi);
setup_xaction_handlers(new_smi);
- /* Try to claim any interrupts. */
- if (new_smi->irq_setup)
- new_smi->irq_setup(new_smi);
-
INIT_LIST_HEAD(&(new_smi->xmit_msgs));
INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
new_smi->curr_msg = NULL;
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 41f78e2c158..e686fc92516 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -50,10 +50,19 @@
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/ctype.h>
+#include <linux/delay.h>
#include <asm/atomic.h>
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/apic.h>
+#ifdef CONFIG_X86
+/* This is ugly, but I've determined that x86 is the only architecture
+ that can reasonably support the IPMI NMI watchdog timeout at this
+ time. If another architecture adds this capability somehow, it
+ will have to be a somewhat different mechanism and I have no idea
+ how it will work. So in the unlikely event that another
+ architecture supports this, we can figure out a good generic
+ mechanism for it at that time. */
+#include <asm/kdebug.h>
+#define HAVE_DIE_NMI
#endif
#define PFX "IPMI Watchdog: "
@@ -166,8 +175,6 @@ static char expect_close;
static int ifnum_to_use = -1;
-static DECLARE_RWSEM(register_sem);
-
/* Parameters to ipmi_set_timeout */
#define IPMI_SET_TIMEOUT_NO_HB 0
#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1
@@ -193,11 +200,9 @@ static int set_param_int(const char *val, struct kernel_param *kp)
if (endp == val)
return -EINVAL;
- down_read(&register_sem);
*((int *)kp->arg) = l;
if (watchdog_user)
rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
- up_read(&register_sem);
return rv;
}
@@ -226,17 +231,15 @@ static int set_param_str(const char *val, struct kernel_param *kp)
s = strstrip(valcp);
- down_read(&register_sem);
rv = fn(s, NULL);
if (rv)
- goto out_unlock;
+ goto out;
check_parms();
if (watchdog_user)
rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
- out_unlock:
- up_read(&register_sem);
+ out:
return rv;
}
@@ -319,9 +322,12 @@ static unsigned char ipmi_version_minor;
/* If a pretimeout occurs, this is used to allow only one panic to happen. */
static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
-static int ipmi_heartbeat(void);
-static void panic_halt_ipmi_heartbeat(void);
+#ifdef HAVE_DIE_NMI
+static int testing_nmi;
+static int nmi_handler_registered;
+#endif
+static int ipmi_heartbeat(void);
/* We use a mutex to make sure that only one thing can send a set
timeout at one time, because we only have one copy of the data.
@@ -360,6 +366,9 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
int hbnow = 0;
+ /* These can be cleared as we are setting the timeout. */
+ pretimeout_since_last_heartbeat = 0;
+
data[0] = 0;
WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
@@ -434,31 +443,75 @@ static int ipmi_set_timeout(int do_heartbeat)
wait_for_completion(&set_timeout_wait);
+ mutex_unlock(&set_timeout_lock);
+
if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
|| ((send_heartbeat_now)
&& (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
- {
rv = ipmi_heartbeat();
- }
- mutex_unlock(&set_timeout_lock);
out:
return rv;
}
-static void dummy_smi_free(struct ipmi_smi_msg *msg)
+static atomic_t panic_done_count = ATOMIC_INIT(0);
+
+static void panic_smi_free(struct ipmi_smi_msg *msg)
{
+ atomic_dec(&panic_done_count);
}
-static void dummy_recv_free(struct ipmi_recv_msg *msg)
+static void panic_recv_free(struct ipmi_recv_msg *msg)
{
+ atomic_dec(&panic_done_count);
+}
+
+static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
+{
+ .done = panic_smi_free
+};
+static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
+{
+ .done = panic_recv_free
+};
+
+static void panic_halt_ipmi_heartbeat(void)
+{
+ struct kernel_ipmi_msg msg;
+ struct ipmi_system_interface_addr addr;
+ int rv;
+
+ /* Don't reset the timer if we have the timer turned off, that
+ re-enables the watchdog. */
+ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
+ return;
+
+ addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+ addr.channel = IPMI_BMC_CHANNEL;
+ addr.lun = 0;
+
+ msg.netfn = 0x06;
+ msg.cmd = IPMI_WDOG_RESET_TIMER;
+ msg.data = NULL;
+ msg.data_len = 0;
+ rv = ipmi_request_supply_msgs(watchdog_user,
+ (struct ipmi_addr *) &addr,
+ 0,
+ &msg,
+ NULL,
+ &panic_halt_heartbeat_smi_msg,
+ &panic_halt_heartbeat_recv_msg,
+ 1);
+ if (!rv)
+ atomic_add(2, &panic_done_count);
}
+
static struct ipmi_smi_msg panic_halt_smi_msg =
{
- .done = dummy_smi_free
+ .done = panic_smi_free
};
static struct ipmi_recv_msg panic_halt_recv_msg =
{
- .done = dummy_recv_free
+ .done = panic_recv_free
};
/* Special call, doesn't claim any locks. This is only to be called
@@ -470,13 +523,21 @@ static void panic_halt_ipmi_set_timeout(void)
int send_heartbeat_now;
int rv;
+ /* Wait for the messages to be free. */
+ while (atomic_read(&panic_done_count) != 0)
+ ipmi_poll_interface(watchdog_user);
rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
&panic_halt_recv_msg,
&send_heartbeat_now);
if (!rv) {
+ atomic_add(2, &panic_done_count);
if (send_heartbeat_now)
panic_halt_ipmi_heartbeat();
- }
+ } else
+ printk(KERN_WARNING PFX
+ "Unable to extend the watchdog timeout.");
+ while (atomic_read(&panic_done_count) != 0)
+ ipmi_poll_interface(watchdog_user);
}
/* We use a semaphore to make sure that only one thing can send a
@@ -505,24 +566,14 @@ static struct ipmi_recv_msg heartbeat_recv_msg =
.done = heartbeat_free_recv
};
-static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
-{
- .done = dummy_smi_free
-};
-static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
-{
- .done = dummy_recv_free
-};
-
static int ipmi_heartbeat(void)
{
struct kernel_ipmi_msg msg;
int rv;
struct ipmi_system_interface_addr addr;
- if (ipmi_ignore_heartbeat) {
+ if (ipmi_ignore_heartbeat)
return 0;
- }
if (ipmi_start_timer_on_heartbeat) {
ipmi_start_timer_on_heartbeat = 0;
@@ -533,7 +584,6 @@ static int ipmi_heartbeat(void)
We don't want to set the action, though, we want to
leave that alone (thus it can't be combined with the
above operation. */
- pretimeout_since_last_heartbeat = 0;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
}
@@ -586,35 +636,6 @@ static int ipmi_heartbeat(void)
return rv;
}
-static void panic_halt_ipmi_heartbeat(void)
-{
- struct kernel_ipmi_msg msg;
- struct ipmi_system_interface_addr addr;
-
-
- /* Don't reset the timer if we have the timer turned off, that
- re-enables the watchdog. */
- if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
- return;
-
- addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
- addr.channel = IPMI_BMC_CHANNEL;
- addr.lun = 0;
-
- msg.netfn = 0x06;
- msg.cmd = IPMI_WDOG_RESET_TIMER;
- msg.data = NULL;
- msg.data_len = 0;
- ipmi_request_supply_msgs(watchdog_user,
- (struct ipmi_addr *) &addr,
- 0,
- &msg,
- NULL,
- &panic_halt_heartbeat_smi_msg,
- &panic_halt_heartbeat_recv_msg,
- 1);
-}
-
static struct watchdog_info ident =
{
.options = 0, /* WDIOF_SETTIMEOUT, */
@@ -895,7 +916,6 @@ static void ipmi_register_watchdog(int ipmi_intf)
{
int rv = -EBUSY;
- down_write(&register_sem);
if (watchdog_user)
goto out;
@@ -921,15 +941,56 @@ static void ipmi_register_watchdog(int ipmi_intf)
printk(KERN_CRIT PFX "Unable to register misc device\n");
}
- out:
- up_write(&register_sem);
+#ifdef HAVE_DIE_NMI
+ if (nmi_handler_registered) {
+ int old_pretimeout = pretimeout;
+ int old_timeout = timeout;
+ int old_preop_val = preop_val;
+
+ /* Set the pretimeout to go off in a second and give
+ ourselves plenty of time to stop the timer. */
+ ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+ preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */
+ pretimeout = 99;
+ timeout = 100;
+
+ testing_nmi = 1;
+
+ rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
+ if (rv) {
+ printk(KERN_WARNING PFX "Error starting timer to"
+ " test NMI: 0x%x. The NMI pretimeout will"
+ " likely not work\n", rv);
+ rv = 0;
+ goto out_restore;
+ }
+
+ msleep(1500);
+ if (testing_nmi != 2) {
+ printk(KERN_WARNING PFX "IPMI NMI didn't seem to"
+ " occur. The NMI pretimeout will"
+ " likely not work\n");
+ }
+ out_restore:
+ testing_nmi = 0;
+ preop_val = old_preop_val;
+ pretimeout = old_pretimeout;
+ timeout = old_timeout;
+ }
+#endif
+
+ out:
if ((start_now) && (rv == 0)) {
/* Run from startup, so start the timer now. */
start_now = 0; /* Disable this function after first startup. */
ipmi_watchdog_state = action_val;
ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
printk(KERN_INFO PFX "Starting now!\n");
+ } else {
+ /* Stop the timer now. */
+ ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+ ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
}
}
@@ -937,8 +998,6 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
{
int rv;
- down_write(&register_sem);
-
if (!watchdog_user)
goto out;
@@ -963,20 +1022,44 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
watchdog_user = NULL;
out:
- up_write(&register_sem);
+ return;
}
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
static int
-ipmi_nmi(void *dev_id, int cpu, int handled)
+ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
{
+ struct die_args *args = data;
+
+ if (val != DIE_NMI)
+ return NOTIFY_OK;
+
+ /* Hack, if it's a memory or I/O error, ignore it. */
+ if (args->err & 0xc0)
+ return NOTIFY_OK;
+
+ /*
+ * If we get here, it's an NMI that's not a memory or I/O
+ * error. We can't truly tell if it's from IPMI or not
+ * without sending a message, and sending a message is almost
+ * impossible because of locking.
+ */
+
+ if (testing_nmi) {
+ testing_nmi = 2;
+ return NOTIFY_STOP;
+ }
+
/* If we are not expecting a timeout, ignore it. */
if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
- return NOTIFY_DONE;
+ return NOTIFY_OK;
+
+ if (preaction_val != WDOG_PRETIMEOUT_NMI)
+ return NOTIFY_OK;
/* If no one else handled the NMI, we assume it was the IPMI
watchdog. */
- if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) {
+ if (preop_val == WDOG_PREOP_PANIC) {
/* On some machines, the heartbeat will give
an error and not work unless we re-enable
the timer. So do so. */
@@ -985,18 +1068,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled)
panic(PFX "pre-timeout");
}
- return NOTIFY_DONE;
+ return NOTIFY_STOP;
}
-static struct nmi_handler ipmi_nmi_handler =
-{
- .link = LIST_HEAD_INIT(ipmi_nmi_handler.link),
- .dev_name = "ipmi_watchdog",
- .dev_id = NULL,
- .handler = ipmi_nmi,
- .priority = 0, /* Call us last. */
+static struct notifier_block ipmi_nmi_handler = {
+ .notifier_call = ipmi_nmi
};
-int nmi_handler_registered;
#endif
static int wdog_reboot_handler(struct notifier_block *this,
@@ -1009,7 +1086,7 @@ static int wdog_reboot_handler(struct notifier_block *this,
/* Make sure we only do this once. */
reboot_event_handled = 1;
- if (code == SYS_DOWN || code == SYS_HALT) {
+ if (code == SYS_POWER_OFF || code == SYS_HALT) {
/* Disable the WDT if we are shutting down. */
ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
panic_halt_ipmi_set_timeout();
@@ -1113,7 +1190,7 @@ static int preaction_op(const char *inval, char *outval)
preaction_val = WDOG_PRETIMEOUT_NONE;
else if (strcmp(inval, "pre_smi") == 0)
preaction_val = WDOG_PRETIMEOUT_SMI;
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
else if (strcmp(inval, "pre_nmi") == 0)
preaction_val = WDOG_PRETIMEOUT_NMI;
#endif
@@ -1147,7 +1224,7 @@ static int preop_op(const char *inval, char *outval)
static void check_parms(void)
{
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
int do_nmi = 0;
int rv;
@@ -1160,20 +1237,9 @@ static void check_parms(void)
preop_op("preop_none", NULL);
do_nmi = 0;
}
-#ifdef CONFIG_X86_LOCAL_APIC
- if (nmi_watchdog == NMI_IO_APIC) {
- printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC"
- " mode (value is %d), that is incompatible"
- " with using NMI in the IPMI watchdog."
- " Disabling IPMI nmi pretimeout.\n",
- nmi_watchdog);
- preaction_val = WDOG_PRETIMEOUT_NONE;
- do_nmi = 0;
- }
-#endif
}
if (do_nmi && !nmi_handler_registered) {
- rv = request_nmi(&ipmi_nmi_handler);
+ rv = register_die_notifier(&ipmi_nmi_handler);
if (rv) {
printk(KERN_WARNING PFX
"Can't register nmi handler\n");
@@ -1181,7 +1247,7 @@ static void check_parms(void)
} else
nmi_handler_registered = 1;
} else if (!do_nmi && nmi_handler_registered) {
- release_nmi(&ipmi_nmi_handler);
+ unregister_die_notifier(&ipmi_nmi_handler);
nmi_handler_registered = 0;
}
#endif
@@ -1217,9 +1283,9 @@ static int __init ipmi_wdog_init(void)
rv = ipmi_smi_watcher_register(&smi_watcher);
if (rv) {
-#ifdef HAVE_NMI_HANDLER
- if (preaction_val == WDOG_PRETIMEOUT_NMI)
- release_nmi(&ipmi_nmi_handler);
+#ifdef HAVE_DIE_NMI
+ if (nmi_handler_registered)
+ unregister_die_notifier(&ipmi_nmi_handler);
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
&wdog_panic_notifier);
@@ -1238,9 +1304,9 @@ static void __exit ipmi_wdog_exit(void)
ipmi_smi_watcher_unregister(&smi_watcher);
ipmi_unregister_watchdog(watchdog_ifnum);
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI
if (nmi_handler_registered)
- release_nmi(&ipmi_nmi_handler);
+ unregister_die_notifier(&ipmi_nmi_handler);
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 77a7a4a0662..85d596a3c18 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1529,7 +1529,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
portcount = inw(base + 0x2);
if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
portcount != 8 && portcount != 16)) {
- dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.",
+ dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n",
card + 1);
retval = -EIO;
goto end;
@@ -1622,7 +1622,9 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if ((status = inw(base + 0x4)) != 0) {
dev_warn(&pdev->dev, "Card%d rejected load header:\n"
- "Address:0x%x\nCount:0x%x\nStatus:0x%x\n",
+ KERN_WARNING "Address:0x%x\n"
+ KERN_WARNING "Count:0x%x\n"
+ KERN_WARNING "Status:0x%x\n",
index + 1, frame->addr, frame->count, status);
goto errrelfw;
}
@@ -1666,7 +1668,9 @@ static int __devinit load_firmware(struct pci_dev *pdev,
if ((status = inw(base + 0x4)) != 0) {
dev_warn(&pdev->dev, "Card%d rejected verify header:\n"
- "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n",
+ KERN_WARNING "Address:0x%x\n"
+ KERN_WARNING "Count:0x%x\n"
+ KERN_WARNING "Status: 0x%x\n",
index + 1, frame->addr, frame->count, status);
goto errrelfw;
}
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index d95f316afb5..212276affa1 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -38,6 +38,7 @@
#include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h>
#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
#include <linux/sysrq.h>
#include <linux/input.h>
#include <linux/reboot.h>
@@ -403,9 +404,12 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
return d;
if (kbd->kbdmode == VC_UNICODE)
- to_utf8(vc, conv_8bit_to_uni(d));
- else if (d < 0x100)
- put_queue(vc, d);
+ to_utf8(vc, d);
+ else {
+ int c = conv_uni_to_8bit(d);
+ if (c != -1)
+ put_queue(vc, c);
+ }
return ch;
}
@@ -417,9 +421,12 @@ static void fn_enter(struct vc_data *vc)
{
if (diacr) {
if (kbd->kbdmode == VC_UNICODE)
- to_utf8(vc, conv_8bit_to_uni(diacr));
- else if (diacr < 0x100)
- put_queue(vc, diacr);
+ to_utf8(vc, diacr);
+ else {
+ int c = conv_uni_to_8bit(diacr);
+ if (c != -1)
+ put_queue(vc, c);
+ }
diacr = 0;
}
put_queue(vc, 13);
@@ -627,9 +634,12 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
return;
}
if (kbd->kbdmode == VC_UNICODE)
- to_utf8(vc, conv_8bit_to_uni(value));
- else if (value < 0x100)
- put_queue(vc, value);
+ to_utf8(vc, value);
+ else {
+ int c = conv_uni_to_8bit(value);
+ if (c != -1)
+ put_queue(vc, c);
+ }
}
/*
@@ -646,7 +656,12 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
{
- k_unicode(vc, value, up_flag);
+ unsigned int uni;
+ if (kbd->kbdmode == VC_UNICODE)
+ uni = value;
+ else
+ uni = conv_8bit_to_uni(value);
+ k_unicode(vc, uni, up_flag);
}
static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
@@ -1366,7 +1381,7 @@ int __init kbd_init(void)
kbd_table[i].lockstate = KBD_DEFLOCK;
kbd_table[i].slockstate = 0;
kbd_table[i].modeflags = KBD_DEFMODE;
- kbd_table[i].kbdmode = VC_XLATE;
+ kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
}
error = input_register_handler(&kbd_handler);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index c59e2a0996c..81674d7c56c 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -144,7 +144,7 @@ static unsigned int lp_count = 0;
static struct class *lp_class;
#ifdef CONFIG_LP_CONSOLE
-static struct parport *console_registered; // initially NULL
+static struct parport *console_registered;
#endif /* CONFIG_LP_CONSOLE */
#undef LP_DEBUG
@@ -749,8 +749,8 @@ static struct console lpcons = {
/* --- initialisation code ------------------------------------- */
static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC };
-static char *parport[LP_NO] = { NULL, };
-static int reset = 0;
+static char *parport[LP_NO];
+static int reset;
module_param_array(parport, charp, NULL, 0);
module_param(reset, bool, 0);
@@ -758,10 +758,10 @@ module_param(reset, bool, 0);
#ifndef MODULE
static int __init lp_setup (char *str)
{
- static int parport_ptr; // initially zero
+ static int parport_ptr;
int x;
- if (get_option (&str, &x)) {
+ if (get_option(&str, &x)) {
if (x == 0) {
/* disable driver on "lp=" or "lp=0" */
parport_nr[0] = LP_PARPORT_OFF;
@@ -807,7 +807,7 @@ static int lp_register(int nr, struct parport *port)
#ifdef CONFIG_LP_CONSOLE
if (!nr) {
if (port->modes & PARPORT_MODE_SAFEININT) {
- register_console (&lpcons);
+ register_console(&lpcons);
console_registered = port;
printk (KERN_INFO "lp%d: console ready\n", CONSOLE_LP);
} else
@@ -823,8 +823,7 @@ static void lp_attach (struct parport *port)
{
unsigned int i;
- switch (parport_nr[0])
- {
+ switch (parport_nr[0]) {
case LP_PARPORT_UNSPEC:
case LP_PARPORT_AUTO:
if (parport_nr[0] == LP_PARPORT_AUTO &&
@@ -855,7 +854,7 @@ static void lp_detach (struct parport *port)
/* Write this some day. */
#ifdef CONFIG_LP_CONSOLE
if (console_registered == port) {
- unregister_console (&lpcons);
+ unregister_console(&lpcons);
console_registered = NULL;
}
#endif /* CONFIG_LP_CONSOLE */
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 7ee5d944492..3c5802ae171 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -22,7 +22,6 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mm.h>
-#include <linux/fs.h>
#include <linux/uio.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index bbee97ff355..0e937f64a78 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -625,65 +625,10 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
}
-#ifdef CONFIG_MMU
-/*
- * For fun, we are using the MMU for this.
- */
-static inline size_t read_zero_pagealigned(char __user * buf, size_t size)
-{
- struct mm_struct *mm;
- struct vm_area_struct * vma;
- unsigned long addr=(unsigned long)buf;
-
- mm = current->mm;
- /* Oops, this was forgotten before. -ben */
- down_read(&mm->mmap_sem);
-
- /* For private mappings, just map in zero pages. */
- for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
- unsigned long count;
-
- if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
- goto out_up;
- if (vma->vm_flags & (VM_SHARED | VM_HUGETLB))
- break;
- count = vma->vm_end - addr;
- if (count > size)
- count = size;
-
- zap_page_range(vma, addr, count, NULL);
- if (zeromap_page_range(vma, addr, count, PAGE_COPY))
- break;
-
- size -= count;
- buf += count;
- addr += count;
- if (size == 0)
- goto out_up;
- }
-
- up_read(&mm->mmap_sem);
-
- /* The shared case is hard. Let's do the conventional zeroing. */
- do {
- unsigned long unwritten = clear_user(buf, PAGE_SIZE);
- if (unwritten)
- return size + unwritten - PAGE_SIZE;
- cond_resched();
- buf += PAGE_SIZE;
- size -= PAGE_SIZE;
- } while (size);
-
- return size;
-out_up:
- up_read(&mm->mmap_sem);
- return size;
-}
-
static ssize_t read_zero(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
- unsigned long left, unwritten, written = 0;
+ size_t written;
if (!count)
return 0;
@@ -691,69 +636,33 @@ static ssize_t read_zero(struct file * file, char __user * buf,
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
- left = count;
-
- /* do we want to be clever? Arbitrary cut-off */
- if (count >= PAGE_SIZE*4) {
- unsigned long partial;
+ written = 0;
+ while (count) {
+ unsigned long unwritten;
+ size_t chunk = count;
- /* How much left of the page? */
- partial = (PAGE_SIZE-1) & -(unsigned long) buf;
- unwritten = clear_user(buf, partial);
- written = partial - unwritten;
- if (unwritten)
- goto out;
- left -= partial;
- buf += partial;
- unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
- written += (left & PAGE_MASK) - unwritten;
+ if (chunk > PAGE_SIZE)
+ chunk = PAGE_SIZE; /* Just for latency reasons */
+ unwritten = clear_user(buf, chunk);
+ written += chunk - unwritten;
if (unwritten)
- goto out;
- buf += left & PAGE_MASK;
- left &= ~PAGE_MASK;
- }
- unwritten = clear_user(buf, left);
- written += left - unwritten;
-out:
- return written ? written : -EFAULT;
-}
-
-static int mmap_zero(struct file * file, struct vm_area_struct * vma)
-{
- int err;
-
- if (vma->vm_flags & VM_SHARED)
- return shmem_zero_setup(vma);
- err = zeromap_page_range(vma, vma->vm_start,
- vma->vm_end - vma->vm_start, vma->vm_page_prot);
- BUG_ON(err == -EEXIST);
- return err;
-}
-#else /* CONFIG_MMU */
-static ssize_t read_zero(struct file * file, char * buf,
- size_t count, loff_t *ppos)
-{
- size_t todo = count;
-
- while (todo) {
- size_t chunk = todo;
-
- if (chunk > 4096)
- chunk = 4096; /* Just for latency reasons */
- if (clear_user(buf, chunk))
- return -EFAULT;
+ break;
buf += chunk;
- todo -= chunk;
+ count -= chunk;
cond_resched();
}
- return count;
+ return written ? written : -EFAULT;
}
static int mmap_zero(struct file * file, struct vm_area_struct * vma)
{
+#ifndef CONFIG_MMU
return -ENOSYS;
+#endif
+ if (vma->vm_flags & VM_SHARED)
+ return shmem_zero_setup(vma);
+ return 0;
}
-#endif /* CONFIG_MMU */
static ssize_t write_full(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
@@ -984,6 +893,11 @@ static struct class *mem_class;
static int __init chr_dev_init(void)
{
int i;
+ int err;
+
+ err = bdi_init(&zero_bdi);
+ if (err)
+ return err;
if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index ed76f0a127f..2fc255a2148 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -41,6 +41,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/completion.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -142,7 +143,7 @@ struct moxa_port {
struct tty_struct *tty;
int cflag;
wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
+ struct completion close_wait;
struct timer_list emptyTimer;
@@ -166,7 +167,6 @@ struct moxa_port {
#define WAKEUP_CHARS 256
-static int verbose = 0;
static int ttymajor = MOXAMAJOR;
/* Variables for insmod */
#ifdef MODULE
@@ -184,7 +184,6 @@ module_param_array(baseaddr, int, NULL, 0);
module_param_array(numports, int, NULL, 0);
#endif
module_param(ttymajor, int, 0);
-module_param(verbose, bool, 0644);
/*
* static functions:
@@ -208,13 +207,13 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file);
static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear);
static void moxa_poll(unsigned long);
-static void set_tty_param(struct tty_struct *);
-static int block_till_ready(struct tty_struct *, struct file *,
+static void moxa_set_tty_param(struct tty_struct *);
+static int moxa_block_till_ready(struct tty_struct *, struct file *,
struct moxa_port *);
-static void setup_empty_event(struct tty_struct *);
-static void check_xmit_empty(unsigned long);
-static void shut_down(struct moxa_port *);
-static void receive_data(struct moxa_port *);
+static void moxa_setup_empty_event(struct tty_struct *);
+static void moxa_check_xmit_empty(unsigned long);
+static void moxa_shut_down(struct moxa_port *);
+static void moxa_receive_data(struct moxa_port *);
/*
* moxa board interface functions:
*/
@@ -283,8 +282,10 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
int retval;
retval = pci_enable_device(pdev);
- if (retval)
+ if (retval) {
+ dev_err(&pdev->dev, "can't enable pci device\n");
goto err;
+ }
for (i = 0; i < MAX_BOARDS; i++)
if (moxa_boards[i].basemem == NULL)
@@ -292,16 +293,17 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
retval = -ENODEV;
if (i >= MAX_BOARDS) {
- if (verbose)
- printk("More than %d MOXA Intellio family boards "
+ dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards "
"found. Board is ignored.\n", MAX_BOARDS);
goto err;
}
board = &moxa_boards[i];
board->basemem = pci_iomap(pdev, 2, 0x4000);
- if (board->basemem == NULL)
+ if (board->basemem == NULL) {
+ dev_err(&pdev->dev, "can't remap io space 2\n");
goto err;
+ }
board->boardType = board_type;
switch (board_type) {
@@ -347,7 +349,8 @@ static int __init moxa_init(void)
int i, numBoards, retval = 0;
struct moxa_port *ch;
- printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
+ printk(KERN_INFO "MOXA Intellio family driver version %s\n",
+ MOXA_VERSION);
moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
if (!moxaDriver)
return -ENOMEM;
@@ -372,13 +375,13 @@ static int __init moxa_init(void)
ch->closing_wait = 30 * HZ;
ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
init_waitqueue_head(&ch->open_wait);
- init_waitqueue_head(&ch->close_wait);
+ init_completion(&ch->close_wait);
- setup_timer(&ch->emptyTimer, check_xmit_empty,
+ setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,
(unsigned long)ch);
}
- printk("Tty devices major number = %d\n", ttymajor);
+ pr_debug("Moxa tty devices major number = %d\n", ttymajor);
if (tty_register_driver(moxaDriver)) {
printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
@@ -400,11 +403,10 @@ static int __init moxa_init(void)
moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
- if (verbose)
- printk("Board %2d: %s board(baseAddr=%lx)\n",
- numBoards + 1,
- moxa_brdname[moxa_boards[numBoards].boardType - 1],
- moxa_boards[numBoards].baseAddr);
+ pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
+ numBoards + 1,
+ moxa_brdname[moxa_boards[numBoards].boardType-1],
+ moxa_boards[numBoards].baseAddr);
numBoards++;
}
}
@@ -413,14 +415,13 @@ static int __init moxa_init(void)
for (i = 0; i < MAX_BOARDS; i++) {
if ((type[i] == MOXA_BOARD_C218_ISA) ||
(type[i] == MOXA_BOARD_C320_ISA)) {
- if (verbose)
- printk("Board %2d: %s board(baseAddr=%lx)\n",
- numBoards + 1,
- moxa_brdname[type[i] - 1],
- (unsigned long) baseaddr[i]);
+ pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",
+ numBoards + 1, moxa_brdname[type[i] - 1],
+ (unsigned long)baseaddr[i]);
if (numBoards >= MAX_BOARDS) {
- if (verbose)
- printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
+ printk(KERN_WARNING "More than %d MOXA "
+ "Intellio family boards found. Board "
+ "is ignored.\n", MAX_BOARDS);
continue;
}
moxa_boards[numBoards].boardType = type[i];
@@ -456,16 +457,14 @@ static void __exit moxa_exit(void)
{
int i;
- if (verbose)
- printk("Unloading module moxa ...\n");
-
del_timer_sync(&moxaTimer);
for (i = 0; i < MAX_PORTS; i++)
del_timer_sync(&moxa_ports[i].emptyTimer);
if (tty_unregister_driver(moxaDriver))
- printk("Couldn't unregister MOXA Intellio family serial driver\n");
+ printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
+ "serial driver\n");
put_tty_driver(moxaDriver);
#ifdef CONFIG_PCI
@@ -475,9 +474,6 @@ static void __exit moxa_exit(void)
for (i = 0; i < MAX_BOARDS; i++)
if (moxa_boards[i].basemem)
iounmap(moxa_boards[i].basemem);
-
- if (verbose)
- printk("Done\n");
}
module_init(moxa_init);
@@ -504,12 +500,12 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
ch->tty = tty;
if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
ch->statusflags = 0;
- set_tty_param(tty);
+ moxa_set_tty_param(tty);
MoxaPortLineCtrl(ch->port, 1, 1);
MoxaPortEnable(ch->port);
ch->asyncflags |= ASYNC_INITIALIZED;
}
- retval = block_till_ready(tty, filp, ch);
+ retval = moxa_block_till_ready(tty, filp, ch);
moxa_unthrottle(tty);
@@ -532,9 +528,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
return;
}
if (!MoxaPortIsValid(port)) {
-#ifdef SERIAL_DEBUG_CLOSE
- printk("Invalid portno in moxa_close\n");
-#endif
+ pr_debug("Invalid portno in moxa_close\n");
tty->driver_data = NULL;
return;
}
@@ -547,13 +541,13 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
ch = (struct moxa_port *) tty->driver_data;
if ((tty->count == 1) && (ch->count != 1)) {
- printk("moxa_close: bad serial port count; tty->count is 1, "
- "ch->count is %d\n", ch->count);
+ printk(KERN_WARNING "moxa_close: bad serial port count; "
+ "tty->count is 1, ch->count is %d\n", ch->count);
ch->count = 1;
}
if (--ch->count < 0) {
- printk("moxa_close: bad serial port count, device=%s\n",
- tty->name);
+ printk(KERN_WARNING "moxa_close: bad serial port count, "
+ "device=%s\n", tty->name);
ch->count = 0;
}
if (ch->count) {
@@ -563,11 +557,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
ch->cflag = tty->termios->c_cflag;
if (ch->asyncflags & ASYNC_INITIALIZED) {
- setup_empty_event(tty);
+ moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
del_timer_sync(&moxa_ports[ch->port].emptyTimer);
}
- shut_down(ch);
+ moxa_shut_down(ch);
MoxaPortFlushData(port, 2);
if (tty->driver->flush_buffer)
@@ -584,7 +578,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
wake_up_interruptible(&ch->open_wait);
}
ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
- wake_up_interruptible(&ch->close_wait);
+ complete_all(&ch->close_wait);
}
static int moxa_write(struct tty_struct *tty,
@@ -653,7 +647,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty)
* in tty_ioctl.c, etc.
*/
if (!(ch->statusflags & EMPTYWAIT))
- setup_empty_event(tty);
+ moxa_setup_empty_event(tty);
}
return (chars);
}
@@ -751,7 +745,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
retval = tty_check_change(tty);
if (retval)
return (retval);
- setup_empty_event(tty);
+ moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 0);
if (!arg)
MoxaPortSendBreak(ch->port, 0);
@@ -760,7 +754,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
retval = tty_check_change(tty);
if (retval)
return (retval);
- setup_empty_event(tty);
+ moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 0);
MoxaPortSendBreak(ch->port, arg);
return (0);
@@ -809,7 +803,7 @@ static void moxa_set_termios(struct tty_struct *tty,
if (ch == NULL)
return;
- set_tty_param(tty);
+ moxa_set_tty_param(tty);
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
wake_up_interruptible(&ch->open_wait);
@@ -845,7 +839,7 @@ static void moxa_hangup(struct tty_struct *tty)
struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
moxa_flush_buffer(tty);
- shut_down(ch);
+ moxa_shut_down(ch);
ch->event = 0;
ch->count = 0;
ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
@@ -875,7 +869,7 @@ static void moxa_poll(unsigned long ignored)
continue;
if (!(ch->statusflags & THROTTLE) &&
(MoxaPortRxQueue(ch->port) > 0))
- receive_data(ch);
+ moxa_receive_data(ch);
if ((tp = ch->tty) == 0)
continue;
if (ch->statusflags & LOWWAIT) {
@@ -909,7 +903,7 @@ static void moxa_poll(unsigned long ignored)
/******************************************************************************/
-static void set_tty_param(struct tty_struct *tty)
+static void moxa_set_tty_param(struct tty_struct *tty)
{
register struct ktermios *ts;
struct moxa_port *ch;
@@ -934,7 +928,7 @@ static void set_tty_param(struct tty_struct *tty)
MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
}
-static int block_till_ready(struct tty_struct *tty, struct file *filp,
+static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
struct moxa_port *ch)
{
DECLARE_WAITQUEUE(wait,current);
@@ -948,7 +942,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
*/
if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
if (ch->asyncflags & ASYNC_CLOSING)
- interruptible_sleep_on(&ch->close_wait);
+ wait_for_completion_interruptible(&ch->close_wait);
#ifdef SERIAL_DO_RESTART
if (ch->asyncflags & ASYNC_HUP_NOTIFY)
return (-EAGAIN);
@@ -971,10 +965,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
*/
retval = 0;
add_wait_queue(&ch->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready before block: ttys%d, count = %d\n",
- ch->line, ch->count);
-#endif
+ pr_debug("block_til_ready before block: ttys%d, count = %d\n",
+ ch->port, ch->count);
spin_lock_irqsave(&moxa_lock, flags);
if (!tty_hung_up_p(filp))
ch->count--;
@@ -1013,10 +1005,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
ch->count++;
ch->blocked_open--;
spin_unlock_irqrestore(&moxa_lock, flags);
-#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready after blocking: ttys%d, count = %d\n",
- ch->line, ch->count);
-#endif
+ pr_debug("block_til_ready after blocking: ttys%d, count = %d\n",
+ ch->port, ch->count);
if (retval)
return (retval);
/* FIXME: review to see if we need to use set_bit on these */
@@ -1024,7 +1014,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
return 0;
}
-static void setup_empty_event(struct tty_struct *tty)
+static void moxa_setup_empty_event(struct tty_struct *tty)
{
struct moxa_port *ch = tty->driver_data;
unsigned long flags;
@@ -1035,24 +1025,24 @@ static void setup_empty_event(struct tty_struct *tty)
spin_unlock_irqrestore(&moxa_lock, flags);
}
-static void check_xmit_empty(unsigned long data)
+static void moxa_check_xmit_empty(unsigned long data)
{
struct moxa_port *ch;
ch = (struct moxa_port *) data;
- del_timer_sync(&moxa_ports[ch->port].emptyTimer);
if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
if (MoxaPortTxQueue(ch->port) == 0) {
ch->statusflags &= ~EMPTYWAIT;
tty_wakeup(ch->tty);
return;
}
- mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
+ mod_timer(&moxa_ports[ch->port].emptyTimer,
+ round_jiffies(jiffies + HZ));
} else
ch->statusflags &= ~EMPTYWAIT;
}
-static void shut_down(struct moxa_port *ch)
+static void moxa_shut_down(struct moxa_port *ch)
{
struct tty_struct *tp;
@@ -1072,7 +1062,7 @@ static void shut_down(struct moxa_port *ch)
ch->asyncflags &= ~ASYNC_INITIALIZED;
}
-static void receive_data(struct moxa_port *ch)
+static void moxa_receive_data(struct moxa_port *ch)
{
struct tty_struct *tp;
struct ktermios *ts;
@@ -1406,8 +1396,8 @@ static struct mon_str moxaLog;
static int moxaFuncTout = HZ / 2;
static void moxafunc(void __iomem *, int, ushort);
-static void wait_finish(void __iomem *);
-static void low_water_check(void __iomem *);
+static void moxa_wait_finish(void __iomem *);
+static void moxa_low_water_check(void __iomem *);
static int moxaloadbios(int, unsigned char __user *, int);
static int moxafindcard(int);
static int moxaload320b(int, unsigned char __user *, int);
@@ -1473,7 +1463,7 @@ void MoxaPortFlushData(int port, int mode)
moxafunc(ofsAddr, FC_FlushQueue, mode);
if (mode != 1) {
moxa_ports[port].lowChkFlag = 0;
- low_water_check(ofsAddr);
+ moxa_low_water_check(ofsAddr);
}
}
@@ -1654,7 +1644,7 @@ int MoxaDriverPoll(void)
if (moxa_ports[p].lowChkFlag) {
moxa_ports[p].lowChkFlag = 0;
ofsAddr = moxa_ports[p].tableAddr;
- low_water_check(ofsAddr);
+ moxa_low_water_check(ofsAddr);
}
}
}
@@ -2081,7 +2071,7 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
writeb(FC_SetXonXoff, ofsAddr + FuncCode);
- wait_finish(ofsAddr);
+ moxa_wait_finish(ofsAddr);
}
return (0);
@@ -2480,10 +2470,10 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
writew(arg, ofsAddr + FuncArg);
writew(cmd, ofsAddr + FuncCode);
- wait_finish(ofsAddr);
+ moxa_wait_finish(ofsAddr);
}
-static void wait_finish(void __iomem *ofsAddr)
+static void moxa_wait_finish(void __iomem *ofsAddr)
{
unsigned long i, j;
@@ -2496,7 +2486,7 @@ static void wait_finish(void __iomem *ofsAddr)
}
}
-static void low_water_check(void __iomem *ofsAddr)
+static void moxa_low_water_check(void __iomem *ofsAddr)
{
int len;
ushort rptr, wptr, mask;
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 04ac155d3a0..82f2e27dca7 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -362,7 +362,7 @@ mspec_init(void)
is_sn2 = 1;
if (is_shub2()) {
ret = -ENOMEM;
- for_each_online_node(nid) {
+ for_each_node_state(nid, N_ONLINE) {
int actual_nid;
int nasid;
unsigned long phys;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 2aee3fef041..661aca0e155 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -383,7 +383,6 @@ static int mxser_init(void);
/* static void mxser_poll(unsigned long); */
static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
-static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
static void mxser_do_softint(struct work_struct *);
static int mxser_open(struct tty_struct *, struct file *);
static void mxser_close(struct tty_struct *, struct file *);
@@ -422,7 +421,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout);
static void mxser_startrx(struct tty_struct *tty);
static void mxser_stoprx(struct tty_struct *tty);
-
+#ifdef CONFIG_PCI
static int CheckIsMoxaMust(int io)
{
u8 oldmcr, hwid;
@@ -445,6 +444,7 @@ static int CheckIsMoxaMust(int io)
}
return MOXA_OTHER_UART;
}
+#endif
/* above is modified by Victor Yu. 08-15-2002 */
@@ -1938,14 +1938,6 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
inb(info->base + UART_MSR);
continue;
}
- /* above add by Victor Yu. 09-13-2002 */
- /*
- if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) {
- info->IER |= MOXA_MUST_RECV_ISR;
- outb(info->IER, info->base + UART_IER);
- }
- */
-
/* mask by Victor Yu. 09-13-2002
if ( !info->tty ||
@@ -2599,19 +2591,8 @@ static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_te
info->IER |= UART_IER_MSI;
if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) {
info->MCR |= UART_MCR_AFE;
- /* status = mxser_get_msr(info->base, 0, info->port); */
-/*
- save_flags(flags);
- cli();
- status = inb(baseaddr + UART_MSR);
- restore_flags(flags);
-*/
- /* mxser_check_modem_status(info, status); */
} else {
- /* status = mxser_get_msr(info->base, 0, info->port); */
- /* MX_LOCK(&info->slock); */
status = inb(info->base + UART_MSR);
- /* MX_UNLOCK(&info->slock); */
if (info->tty->hw_stopped) {
if (status & UART_MSR_CTS) {
info->tty->hw_stopped = 0;
diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h
index 9fe28497eae..1f4aa45ec00 100644
--- a/drivers/char/mxser.h
+++ b/drivers/char/mxser.h
@@ -30,8 +30,7 @@
#define TTY_THRESHOLD_THROTTLE 128
-#define LO_WATER (TTY_FLIPBUF_SIZE)
-#define HI_WATER (TTY_FLIPBUF_SIZE*2*3/4)
+#define HI_WATER 768
// added by James. 03-11-2004.
#define MOXA_SDS_GETICOUNTER (MOXA + 68)
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index 6a563932ba1..854dbf59eb6 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -2,7 +2,7 @@
* mxser.c -- MOXA Smartio/Industio family multiport serial driver.
*
* Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw).
- * Copyright (C) 2006 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (C) 2006-2007 Jiri Slaby <jirislaby@gmail.com>
*
* This code is loosely based on the 1.8 moxa driver which is based on
* Linux serial driver, written by Linus Torvalds, Theodore T'so and
@@ -48,7 +48,7 @@
#include "mxser_new.h"
-#define MXSER_VERSION "2.0.1" /* 1.9.15 */
+#define MXSER_VERSION "2.0.2" /* 1.10 */
#define MXSERMAJOR 174
#define MXSERCUMAJOR 175
@@ -72,6 +72,12 @@
#define UART_MCR_AFE 0x20
#define UART_LSR_SPECIAL 0x1E
+#define PCI_DEVICE_ID_CB108 0x1080
+#define PCI_DEVICE_ID_CB114 0x1142
+#define PCI_DEVICE_ID_CB134I 0x1341
+#define PCI_DEVICE_ID_CP138U 0x1380
+#define PCI_DEVICE_ID_POS104UL 0x1044
+
#define C168_ASIC_ID 1
#define C104_ASIC_ID 2
@@ -107,71 +113,63 @@ struct mxser_cardinfo {
};
static const struct mxser_cardinfo mxser_cards[] = {
- { 8, "C168 series", }, /* C168-ISA */
- { 4, "C104 series", }, /* C104-ISA */
- { 4, "CI-104J series", }, /* CI104J */
- { 8, "C168H/PCI series", }, /* C168-PCI */
- { 4, "C104H/PCI series", }, /* C104-PCI */
- { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */
- { 4, "CI-132 series", MXSER_HAS2 }, /* CI132 */
- { 4, "CI-134 series", }, /* CI134 */
- { 2, "CP-132 series", }, /* CP132 */
- { 4, "CP-114 series", }, /* CP114 */
- { 4, "CT-114 series", }, /* CT114 */
- { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */
- { 4, "CP-104U series", }, /* CP104U */
- { 8, "CP-168U series", }, /* CP168U */
- { 2, "CP-132U series", }, /* CP132U */
- { 4, "CP-134U series", }, /* CP134U */
- { 4, "CP-104JU series", }, /* CP104JU */
+/* 0*/ { 8, "C168 series", },
+ { 4, "C104 series", },
+ { 4, "CI-104J series", },
+ { 8, "C168H/PCI series", },
+ { 4, "C104H/PCI series", },
+/* 5*/ { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */
+ { 4, "CI-132 series", MXSER_HAS2 },
+ { 4, "CI-134 series", },
+ { 2, "CP-132 series", },
+ { 4, "CP-114 series", },
+/*10*/ { 4, "CT-114 series", },
+ { 2, "CP-102 series", MXSER_HIGHBAUD },
+ { 4, "CP-104U series", },
+ { 8, "CP-168U series", },
+ { 2, "CP-132U series", },
+/*15*/ { 4, "CP-134U series", },
+ { 4, "CP-104JU series", },
{ 8, "Moxa UC7000 Serial", }, /* RC7000 */
- { 8, "CP-118U series", }, /* CP118U */
- { 2, "CP-102UL series", }, /* CP102UL */
- { 2, "CP-102U series", }, /* CP102U */
- { 8, "CP-118EL series", }, /* CP118EL */
- { 8, "CP-168EL series", }, /* CP168EL */
- { 4, "CP-104EL series", } /* CP104EL */
+ { 8, "CP-118U series", },
+ { 2, "CP-102UL series", },
+/*20*/ { 2, "CP-102U series", },
+ { 8, "CP-118EL series", },
+ { 8, "CP-168EL series", },
+ { 4, "CP-104EL series", },
+ { 8, "CB-108 series", },
+/*25*/ { 4, "CB-114 series", },
+ { 4, "CB-134I series", },
+ { 8, "CP-138U series", },
+ { 4, "POS-104UL series", }
};
/* driver_data correspond to the lines in the structure above
see also ISA probe function before you change something */
static struct pci_device_id mxser_pcibrds[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
- .driver_data = 3 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104),
- .driver_data = 4 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132),
- .driver_data = 8 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114),
- .driver_data = 9 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114),
- .driver_data = 10 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102),
- .driver_data = 11 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U),
- .driver_data = 12 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U),
- .driver_data = 13 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U),
- .driver_data = 14 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U),
- .driver_data = 15 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU),
- .driver_data = 16 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000),
- .driver_data = 17 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U),
- .driver_data = 18 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL),
- .driver_data = 19 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U),
- .driver_data = 20 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL),
- .driver_data = 21 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL),
- .driver_data = 22 },
- { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL),
- .driver_data = 23 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 },
+ { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 },
{ }
};
MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index e8332f305d7..82bcfb9c839 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -229,7 +229,7 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
wake_up_interruptible (&tty->read_wait);
wake_up_interruptible (&tty->write_wait);
- if (tty != NULL && tty->disc_data == n_hdlc)
+ if (tty->disc_data == n_hdlc)
tty->disc_data = NULL; /* Break the tty->n_hdlc link */
/* Release transmit and receive buffers */
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 84ac64fc48a..efe2f5c55b9 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,7 +66,6 @@
#include <linux/poll.h>
#include <linux/major.h>
#include <linux/ppdev.h>
-#include <linux/device.h>
#include <asm/uaccess.h>
#define PP_VERSION "ppdev: user-space parallel port driver"
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 73de77105fe..706ff34728f 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -318,7 +318,7 @@ int pty_limit = NR_UNIX98_PTY_DEFAULT;
static int pty_limit_min = 0;
static int pty_limit_max = NR_UNIX98_PTY_MAX;
-ctl_table pty_table[] = {
+static struct ctl_table pty_table[] = {
{
.ctl_name = PTY_MAX,
.procname = "max",
@@ -340,6 +340,27 @@ ctl_table pty_table[] = {
}
};
+static struct ctl_table pty_kern_table[] = {
+ {
+ .ctl_name = KERN_PTY,
+ .procname = "pty",
+ .mode = 0555,
+ .child = pty_table,
+ },
+ {}
+};
+
+static struct ctl_table pty_root_table[] = {
+ {
+ .ctl_name = CTL_KERN,
+ .procname = "kernel",
+ .mode = 0555,
+ .child = pty_kern_table,
+ },
+ {}
+};
+
+
static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -404,6 +425,7 @@ static void __init unix98_pty_init(void)
panic("Couldn't register Unix98 pts driver");
pty_table[1].data = &ptm_driver->refcount;
+ register_sysctl_table(pty_root_table);
}
#else
static inline void unix98_pty_init(void) { }
diff --git a/drivers/char/random.c b/drivers/char/random.c
index af274e5a25e..1756b1f7cb7 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -649,7 +649,7 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
void add_interrupt_randomness(int irq)
{
- if (irq >= NR_IRQS || irq_timer_state[irq] == 0)
+ if (irq >= NR_IRQS || irq_timer_state[irq] == NULL)
return;
DEBUG_ENT("irq event %d\n", irq);
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 56cbba7b6ec..7e6a3a413bb 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -84,6 +84,7 @@
#include <linux/mutex.h>
#include <linux/ioport.h>
#include <linux/delay.h>
+#include <linux/completion.h>
#include <linux/wait.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
@@ -548,8 +549,8 @@ static void rp_handle_port(struct r_port *info)
static void rp_do_poll(unsigned long dummy)
{
CONTROLLER_t *ctlp;
- int ctrl, aiop, ch, line, i;
- unsigned int xmitmask;
+ int ctrl, aiop, ch, line;
+ unsigned int xmitmask, i;
unsigned int CtlMask;
unsigned char AiopMask;
Word_t bit;
@@ -650,7 +651,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
info->closing_wait = 3000;
info->close_delay = 50;
init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
+ init_completion(&info->close_wait);
info->flags &= ~ROCKET_MODE_MASK;
switch (pc104[board][line]) {
case 422:
@@ -699,8 +700,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
spin_lock_init(&info->slock);
mutex_init(&info->write_mtx);
rp_table[line] = info;
- if (pci_dev)
- tty_register_device(rocket_driver, line, &pci_dev->dev);
+ tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev :
+ NULL);
}
/*
@@ -878,7 +879,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
if (tty_hung_up_p(filp))
return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
if (info->flags & ROCKET_CLOSING) {
- interruptible_sleep_on(&info->close_wait);
+ if (wait_for_completion_interruptible(&info->close_wait))
+ return -ERESTARTSYS;
return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
}
@@ -983,8 +985,10 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
return -ENOMEM;
if (info->flags & ROCKET_CLOSING) {
- interruptible_sleep_on(&info->close_wait);
+ retval = wait_for_completion_interruptible(&info->close_wait);
free_page(page);
+ if (retval)
+ return retval;
return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
}
@@ -1176,7 +1180,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
}
info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
tty->closing = 0;
- wake_up_interruptible(&info->close_wait);
+ complete_all(&info->close_wait);
atomic_dec(&rp_num_ports_open);
#ifdef ROCKET_DEBUG_OPEN
@@ -1869,8 +1873,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
int fast_clock = 0;
int altChanRingIndicator = 0;
int ports_per_aiop = 8;
- int ret;
- unsigned int class_rev;
WordIO_t ConfigIO = 0;
ByteIO_t UPCIRingInd = 0;
@@ -1878,12 +1880,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
return 0;
rcktpt_io_addr[i] = pci_resource_start(dev, 0);
- ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
-
- if (ret) {
- printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n");
- return 0;
- }
rcktpt_type[i] = ROCKET_TYPE_NORMAL;
rocketModel[i].loadrm2 = 0;
@@ -2037,8 +2033,9 @@ static __init int register_PCI(int i, struct pci_dev *dev)
ports_per_aiop = 6;
str = "6-port";
- /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */
- if ((class_rev & 0xFF) == 1) {
+ /* If revision is 1, the rocketmodem flash must be loaded.
+ * If it is 2 it is a "socketed" version. */
+ if (dev->revision == 1) {
rcktpt_type[i] = ROCKET_TYPE_MODEMII;
rocketModel[i].loadrm2 = 1;
} else {
@@ -2053,7 +2050,7 @@ static __init int register_PCI(int i, struct pci_dev *dev)
max_num_aiops = 1;
ports_per_aiop = 4;
str = "4-port";
- if ((class_rev & 0xFF) == 1) {
+ if (dev->revision == 1) {
rcktpt_type[i] = ROCKET_TYPE_MODEMII;
rocketModel[i].loadrm2 = 1;
} else {
@@ -2362,26 +2359,14 @@ static const struct tty_operations rocket_ops = {
*/
static int __init rp_init(void)
{
- int retval, pci_boards_found, isa_boards_found, i;
+ int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
ROCKET_VERSION, ROCKET_DATE);
rocket_driver = alloc_tty_driver(MAX_RP_PORTS);
if (!rocket_driver)
- return -ENOMEM;
-
- /*
- * Initialize the array of pointers to our own internal state
- * structures.
- */
- memset(rp_table, 0, sizeof (rp_table));
- memset(xmit_flags, 0, sizeof (xmit_flags));
-
- for (i = 0; i < MAX_RP_PORTS; i++)
- lineNumbers[i] = 0;
- nextLineNumber = 0;
- memset(rocketModel, 0, sizeof (rocketModel));
+ goto err;
/*
* If board 1 is non-zero, there is at least one ISA configured. If controller is
@@ -2396,8 +2381,11 @@ static int __init rp_init(void)
/* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */
if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) {
- printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller);
- return -EBUSY;
+ printk(KERN_ERR "Unable to reserve IO region for first "
+ "configured ISA RocketPort controller 0x%lx. "
+ "Driver exiting\n", controller);
+ ret = -EBUSY;
+ goto err_tty;
}
/* Store ISA variable retrieved from command line or .conf file. */
@@ -2434,15 +2422,14 @@ static int __init rp_init(void)
rocket_driver->init_termios.c_ispeed = 9600;
rocket_driver->init_termios.c_ospeed = 9600;
#ifdef ROCKET_SOFT_FLOW
- rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ rocket_driver->flags |= TTY_DRIVER_REAL_RAW;
#endif
tty_set_operations(rocket_driver, &rocket_ops);
- retval = tty_register_driver(rocket_driver);
- if (retval < 0) {
- printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval);
- put_tty_driver(rocket_driver);
- return -1;
+ ret = tty_register_driver(rocket_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "Couldn't install tty RocketPort driver\n");
+ goto err_tty;
}
#ifdef ROCKET_DEBUG_OPEN
@@ -2469,14 +2456,18 @@ static int __init rp_init(void)
max_board = pci_boards_found + isa_boards_found;
if (max_board == 0) {
- printk(KERN_INFO "No rocketport ports found; unloading driver.\n");
- del_timer_sync(&rocket_timer);
- tty_unregister_driver(rocket_driver);
- put_tty_driver(rocket_driver);
- return -ENXIO;
+ printk(KERN_ERR "No rocketport ports found; unloading driver\n");
+ ret = -ENXIO;
+ goto err_ttyu;
}
return 0;
+err_ttyu:
+ tty_unregister_driver(rocket_driver);
+err_tty:
+ put_tty_driver(rocket_driver);
+err:
+ return ret;
}
@@ -2491,10 +2482,14 @@ static void rp_cleanup_module(void)
if (retval)
printk(KERN_INFO "Error %d while trying to unregister "
"rocketport driver\n", -retval);
- put_tty_driver(rocket_driver);
for (i = 0; i < MAX_RP_PORTS; i++)
- kfree(rp_table[i]);
+ if (rp_table[i]) {
+ tty_unregister_device(rocket_driver, i);
+ kfree(rp_table[i]);
+ }
+
+ put_tty_driver(rocket_driver);
for (i = 0; i < NUM_BOARDS; i++) {
if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index b4c53dfa795..55b8f2d71a9 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1163,13 +1163,8 @@ struct r_port {
int read_status_mask;
int cps;
-#ifdef DECLARE_WAITQUEUE
wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
-#else
- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
-#endif
+ struct completion close_wait;
spinlock_t slock;
struct mutex write_mtx;
};
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index fdc256b380b..905d1f51a7b 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -81,13 +81,9 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
-
#include <linux/netdevice.h>
-
#include <linux/vmalloc.h>
#include <linux/init.h>
-
-#include <linux/delay.h>
#include <linux/ioctl.h>
#include <asm/system.h>
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 39cc318011e..78d14935f2b 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -36,6 +36,7 @@
#include <linux/kexec.h>
#include <linux/irq.h>
#include <linux/hrtimer.h>
+#include <linux/oom.h>
#include <asm/ptrace.h>
#include <asm/irq_regs.h>
@@ -107,12 +108,12 @@ static void sysrq_handle_unraw(int key, struct tty_struct *tty)
struct kbd_struct *kbd = &kbd_table[fg_console];
if (kbd)
- kbd->kbdmode = VC_XLATE;
+ kbd->kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
}
static struct sysrq_key_op sysrq_unraw_op = {
.handler = sysrq_handle_unraw,
.help_msg = "unRaw",
- .action_msg = "Keyboard mode set to XLATE",
+ .action_msg = "Keyboard mode set to system default",
.enable_mask = SYSRQ_ENABLE_KEYBOARD,
};
#else
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 23fa18a6654..a8e80846137 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -435,17 +435,12 @@ module_param(interrupts, bool, 0444);
MODULE_PARM_DESC(interrupts, "Enable interrupts");
static int tpm_tis_init(struct device *dev, resource_size_t start,
- resource_size_t len)
+ resource_size_t len, unsigned int irq)
{
u32 vendor, intfcaps, intmask;
int rc, i;
struct tpm_chip *chip;
- if (!start)
- start = TIS_MEM_BASE;
- if (!len)
- len = TIS_MEM_LEN;
-
if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
return -ENODEV;
@@ -512,7 +507,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
iowrite32(intmask,
chip->vendor.iobase +
TPM_INT_ENABLE(chip->vendor.locality));
- if (interrupts) {
+ if (interrupts)
+ chip->vendor.irq = irq;
+ if (interrupts && !chip->vendor.irq) {
chip->vendor.irq =
ioread8(chip->vendor.iobase +
TPM_INT_VECTOR(chip->vendor.locality));
@@ -597,10 +594,17 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
const struct pnp_device_id *pnp_id)
{
resource_size_t start, len;
+ unsigned int irq = 0;
+
start = pnp_mem_start(pnp_dev, 0);
len = pnp_mem_len(pnp_dev, 0);
- return tpm_tis_init(&pnp_dev->dev, start, len);
+ if (pnp_irq_valid(pnp_dev, 0))
+ irq = pnp_irq(pnp_dev, 0);
+ else
+ interrupts = 0;
+
+ return tpm_tis_init(&pnp_dev->dev, start, len, irq);
}
static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
@@ -660,7 +664,7 @@ static int __init init_tis(void)
return rc;
if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
return PTR_ERR(pdev);
- if((rc=tpm_tis_init(&pdev->dev, 0, 0)) != 0) {
+ if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
platform_device_unregister(pdev);
driver_unregister(&tis_drv);
}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 3ee73cf64bd..0def089cc1f 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -206,8 +206,6 @@ speed_t tty_termios_input_baud_rate(struct ktermios *termios)
EXPORT_SYMBOL(tty_termios_input_baud_rate);
-#ifdef BOTHER
-
/**
* tty_termios_encode_baud_rate
* @termios: ktermios structure holding user requested state
@@ -225,18 +223,26 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate);
*
* Locking: Caller should hold termios lock. This is already held
* when calling this function from the driver termios handler.
+ *
+ * The ifdefs deal with platforms whose owners have yet to update them
+ * and will all go away once this is done.
*/
-void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
+void tty_termios_encode_baud_rate(struct ktermios *termios,
+ speed_t ibaud, speed_t obaud)
{
int i = 0;
int ifound = -1, ofound = -1;
int iclose = ibaud/50, oclose = obaud/50;
int ibinput = 0;
+ if (obaud == 0) /* CD dropped */
+ ibaud = 0; /* Clear ibaud to be sure */
+
termios->c_ispeed = ibaud;
termios->c_ospeed = obaud;
+#ifdef BOTHER
/* If the user asked for a precise weird speed give a precise weird
answer. If they asked for a Bfoo speed they many have problems
digesting non-exact replies so fuzz a bit */
@@ -247,32 +253,64 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed
iclose = 0;
if ((termios->c_cflag >> IBSHIFT) & CBAUD)
ibinput = 1; /* An input speed was specified */
-
+#endif
termios->c_cflag &= ~CBAUD;
+ /*
+ * Our goal is to find a close match to the standard baud rate
+ * returned. Walk the baud rate table and if we get a very close
+ * match then report back the speed as a POSIX Bxxxx value by
+ * preference
+ */
+
do {
- if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) {
+ if (obaud - oclose <= baud_table[i] &&
+ obaud + oclose >= baud_table[i]) {
termios->c_cflag |= baud_bits[i];
ofound = i;
}
- if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) {
- /* For the case input == output don't set IBAUD bits if the user didn't do so */
- if (ofound != i || ibinput)
+ if (ibaud - iclose <= baud_table[i] &&
+ ibaud + iclose >= baud_table[i]) {
+ /* For the case input == output don't set IBAUD bits
+ if the user didn't do so */
+ if (ofound == i && !ibinput)
+ ifound = i;
+#ifdef IBSHIFT
+ else {
+ ifound = i;
termios->c_cflag |= (baud_bits[i] << IBSHIFT);
- ifound = i;
+ }
+#endif
}
} while (++i < n_baud_table);
+
+ /*
+ * If we found no match then use BOTHER if provided or warn
+ * the user their platform maintainer needs to wake up if not.
+ */
+#ifdef BOTHER
if (ofound == -1)
termios->c_cflag |= BOTHER;
/* Set exact input bits only if the input and output differ or the
user already did */
if (ifound == -1 && (ibaud != obaud || ibinput))
termios->c_cflag |= (BOTHER << IBSHIFT);
+#else
+ if (ifound == -1 || ofound == -1) {
+ static int warned;
+ if (!warned++)
+ printk(KERN_WARNING "tty: Unable to return correct "
+ "speed data as your architecture needs updating.\n");
+ }
+#endif
}
-
EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
-#endif
+void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
+{
+ tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
+}
+EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
/**
* tty_get_baud_rate - get tty bit rates
@@ -304,6 +342,29 @@ speed_t tty_get_baud_rate(struct tty_struct *tty)
EXPORT_SYMBOL(tty_get_baud_rate);
/**
+ * tty_termios_copy_hw - copy hardware settings
+ * @new: New termios
+ * @old: Old termios
+ *
+ * Propogate the hardware specific terminal setting bits from
+ * the old termios structure to the new one. This is used in cases
+ * where the hardware does not support reconfiguration or as a helper
+ * in some cases where only minimal reconfiguration is supported
+ */
+
+void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
+{
+ /* The bits a dumb device handles in software. Smart devices need
+ to always provide a set_termios method */
+ new->c_cflag &= HUPCL | CREAD | CLOCAL;
+ new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
+ new->c_ispeed = old->c_ispeed;
+ new->c_ospeed = old->c_ospeed;
+}
+
+EXPORT_SYMBOL(tty_termios_copy_hw);
+
+/**
* change_termios - update termios values
* @tty: tty to update
* @new_termios: desired new value
@@ -340,13 +401,12 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
tty->erasing = 0;
}
-
+ /* This bit should be in the ldisc code */
if (canon_change && !L_ICANON(tty) && tty->read_cnt)
/* Get characters left over from canonical mode. */
wake_up_interruptible(&tty->read_wait);
/* See if packet mode change of state. */
-
if (tty->link && tty->link->packet) {
int old_flow = ((old_termios.c_iflag & IXON) &&
(old_termios.c_cc[VSTOP] == '\023') &&
@@ -366,6 +426,8 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
if (tty->driver->set_termios)
(*tty->driver->set_termios)(tty, &old_termios);
+ else
+ tty_termios_copy_hw(tty->termios, &old_termios);
ld = tty_ldisc_ref(tty);
if (ld != NULL) {
@@ -440,6 +502,11 @@ static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
}
change_termios(tty, &tmp_termios);
+
+ /* FIXME: Arguably if tmp_termios == tty->termios AND the
+ actual requested termios was not tmp_termios then we may
+ want to return an error as no user requested change has
+ succeeded */
return 0;
}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index edb7002a321..1764c67b585 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -158,7 +158,7 @@ static void blank_screen_t(unsigned long dummy);
static void set_palette(struct vc_data *vc);
static int printable; /* Is console ready for printing? */
-static int default_utf8;
+int default_utf8 = true;
module_param(default_utf8, int, S_IRUGO | S_IWUSR);
/*
@@ -750,13 +750,15 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
return 0;
}
-static inline int resize_screen(struct vc_data *vc, int width, int height)
+static inline int resize_screen(struct vc_data *vc, int width, int height,
+ int user)
{
/* Resizes the resolution of the display adapater */
int err = 0;
if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
- err = vc->vc_sw->con_resize(vc, width, height);
+ err = vc->vc_sw->con_resize(vc, width, height, user);
+
return err;
}
@@ -772,7 +774,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
unsigned int old_cols, old_rows, old_row_size, old_screen_size;
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
- unsigned int end;
+ unsigned int end, user;
unsigned short *newscreen;
WARN_CONSOLE_UNLOCKED();
@@ -780,6 +782,9 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
if (!vc)
return -ENXIO;
+ user = vc->vc_resize_user;
+ vc->vc_resize_user = 0;
+
if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
return -EINVAL;
@@ -800,7 +805,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
old_row_size = vc->vc_size_row;
old_screen_size = vc->vc_screenbuf_size;
- err = resize_screen(vc, new_cols, new_rows);
+ err = resize_screen(vc, new_cols, new_rows, user);
if (err) {
kfree(newscreen);
return err;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 7a61a2a9aaf..e6f89e8b925 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -23,6 +23,7 @@
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/console.h>
+#include <linux/consolemap.h>
#include <linux/signal.h>
#include <linux/timex.h>
@@ -582,10 +583,27 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KDGKBDIACR:
{
struct kbdiacrs __user *a = up;
+ struct kbdiacr diacr;
+ int i;
if (put_user(accent_table_size, &a->kb_cnt))
return -EFAULT;
- if (copy_to_user(a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr)))
+ for (i = 0; i < accent_table_size; i++) {
+ diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
+ diacr.base = conv_uni_to_8bit(accent_table[i].base);
+ diacr.result = conv_uni_to_8bit(accent_table[i].result);
+ if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
+ return -EFAULT;
+ }
+ return 0;
+ }
+ case KDGKBDIACRUC:
+ {
+ struct kbdiacrsuc __user *a = up;
+
+ if (put_user(accent_table_size, &a->kb_cnt))
+ return -EFAULT;
+ if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc)))
return -EFAULT;
return 0;
}
@@ -593,6 +611,30 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KDSKBDIACR:
{
struct kbdiacrs __user *a = up;
+ struct kbdiacr diacr;
+ unsigned int ct;
+ int i;
+
+ if (!perm)
+ return -EPERM;
+ if (get_user(ct,&a->kb_cnt))
+ return -EFAULT;
+ if (ct >= MAX_DIACR)
+ return -EINVAL;
+ accent_table_size = ct;
+ for (i = 0; i < ct; i++) {
+ if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr)))
+ return -EFAULT;
+ accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
+ accent_table[i].base = conv_8bit_to_uni(diacr.base);
+ accent_table[i].result = conv_8bit_to_uni(diacr.result);
+ }
+ return 0;
+ }
+
+ case KDSKBDIACRUC:
+ {
+ struct kbdiacrsuc __user *a = up;
unsigned int ct;
if (!perm)
@@ -602,7 +644,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (ct >= MAX_DIACR)
return -EINVAL;
accent_table_size = ct;
- if (copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr)))
+ if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
return -EFAULT;
return 0;
}
@@ -847,14 +889,24 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case VT_RESIZE:
{
struct vt_sizes __user *vtsizes = up;
+ struct vc_data *vc;
+
ushort ll,cc;
if (!perm)
return -EPERM;
if (get_user(ll, &vtsizes->v_rows) ||
get_user(cc, &vtsizes->v_cols))
return -EFAULT;
- for (i = 0; i < MAX_NR_CONSOLES; i++)
- vc_lock_resize(vc_cons[i].d, cc, ll);
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ vc = vc_cons[i].d;
+
+ if (vc) {
+ vc->vc_resize_user = 1;
+ vc_lock_resize(vc_cons[i].d, cc, ll);
+ }
+ }
+
return 0;
}
@@ -900,6 +952,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
vc_cons[i].d->vc_scan_lines = vlin;
if (clin)
vc_cons[i].d->vc_font.height = clin;
+ vc_cons[i].d->vc_resize_user = 1;
vc_resize(vc_cons[i].d, cc, ll);
release_console_sem();
}
@@ -1072,7 +1125,7 @@ int vt_waitactive(int vt)
void reset_vc(struct vc_data *vc)
{
vc->vc_mode = KD_TEXT;
- kbd_table[vc->vc_num].kbdmode = VC_XLATE;
+ kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
vc->vt_mode.mode = VT_AUTO;
vc->vt_mode.waitv = 0;
vc->vt_mode.relsig = 0;
diff --git a/drivers/dca/Kconfig b/drivers/dca/Kconfig
new file mode 100644
index 00000000000..94f0364a0ef
--- /dev/null
+++ b/drivers/dca/Kconfig
@@ -0,0 +1,7 @@
+#
+# DCA server configuration
+#
+
+config DCA
+ tristate
+
diff --git a/drivers/dca/Makefile b/drivers/dca/Makefile
new file mode 100644
index 00000000000..b2db56bb9dd
--- /dev/null
+++ b/drivers/dca/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_DCA) += dca.o
+dca-objs := dca-core.o dca-sysfs.o
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
new file mode 100644
index 00000000000..bf5b92f86df
--- /dev/null
+++ b/drivers/dca/dca-core.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright(c) 2007 Intel Corporation. All rights reserved.
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
+/*
+ * This driver supports an interface for DCA clients and providers to meet.
+ */
+
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/device.h>
+#include <linux/dca.h>
+
+MODULE_LICENSE("GPL");
+
+/* For now we're assuming a single, global, DCA provider for the system. */
+
+static DEFINE_SPINLOCK(dca_lock);
+
+static struct dca_provider *global_dca = NULL;
+
+/**
+ * dca_add_requester - add a dca client to the list
+ * @dev - the device that wants dca service
+ */
+int dca_add_requester(struct device *dev)
+{
+ int err, slot;
+
+ if (!global_dca)
+ return -ENODEV;
+
+ spin_lock(&dca_lock);
+ slot = global_dca->ops->add_requester(global_dca, dev);
+ spin_unlock(&dca_lock);
+ if (slot < 0)
+ return slot;
+
+ err = dca_sysfs_add_req(global_dca, dev, slot);
+ if (err) {
+ spin_lock(&dca_lock);
+ global_dca->ops->remove_requester(global_dca, dev);
+ spin_unlock(&dca_lock);
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dca_add_requester);
+
+/**
+ * dca_remove_requester - remove a dca client from the list
+ * @dev - the device that wants dca service
+ */
+int dca_remove_requester(struct device *dev)
+{
+ int slot;
+ if (!global_dca)
+ return -ENODEV;
+
+ spin_lock(&dca_lock);
+ slot = global_dca->ops->remove_requester(global_dca, dev);
+ spin_unlock(&dca_lock);
+ if (slot < 0)
+ return slot;
+
+ dca_sysfs_remove_req(global_dca, slot);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dca_remove_requester);
+
+/**
+ * dca_get_tag - return the dca tag for the given cpu
+ * @cpu - the cpuid as returned by get_cpu()
+ */
+u8 dca_get_tag(int cpu)
+{
+ if (!global_dca)
+ return -ENODEV;
+ return global_dca->ops->get_tag(global_dca, cpu);
+}
+EXPORT_SYMBOL_GPL(dca_get_tag);
+
+/**
+ * alloc_dca_provider - get data struct for describing a dca provider
+ * @ops - pointer to struct of dca operation function pointers
+ * @priv_size - size of extra mem to be added for provider's needs
+ */
+struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size)
+{
+ struct dca_provider *dca;
+ int alloc_size;
+
+ alloc_size = (sizeof(*dca) + priv_size);
+ dca = kzalloc(alloc_size, GFP_KERNEL);
+ if (!dca)
+ return NULL;
+ dca->ops = ops;
+
+ return dca;
+}
+EXPORT_SYMBOL_GPL(alloc_dca_provider);
+
+/**
+ * free_dca_provider - release the dca provider data struct
+ * @ops - pointer to struct of dca operation function pointers
+ * @priv_size - size of extra mem to be added for provider's needs
+ */
+void free_dca_provider(struct dca_provider *dca)
+{
+ kfree(dca);
+}
+EXPORT_SYMBOL_GPL(free_dca_provider);
+
+static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
+
+/**
+ * register_dca_provider - register a dca provider
+ * @dca - struct created by alloc_dca_provider()
+ * @dev - device providing dca services
+ */
+int register_dca_provider(struct dca_provider *dca, struct device *dev)
+{
+ int err;
+
+ if (global_dca)
+ return -EEXIST;
+ err = dca_sysfs_add_provider(dca, dev);
+ if (err)
+ return err;
+ global_dca = dca;
+ blocking_notifier_call_chain(&dca_provider_chain,
+ DCA_PROVIDER_ADD, NULL);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(register_dca_provider);
+
+/**
+ * unregister_dca_provider - remove a dca provider
+ * @dca - struct created by alloc_dca_provider()
+ */
+void unregister_dca_provider(struct dca_provider *dca)
+{
+ if (!global_dca)
+ return;
+ blocking_notifier_call_chain(&dca_provider_chain,
+ DCA_PROVIDER_REMOVE, NULL);
+ global_dca = NULL;
+ dca_sysfs_remove_provider(dca);
+}
+EXPORT_SYMBOL_GPL(unregister_dca_provider);
+
+/**
+ * dca_register_notify - register a client's notifier callback
+ */
+void dca_register_notify(struct notifier_block *nb)
+{
+ blocking_notifier_chain_register(&dca_provider_chain, nb);
+}
+EXPORT_SYMBOL_GPL(dca_register_notify);
+
+/**
+ * dca_unregister_notify - remove a client's notifier callback
+ */
+void dca_unregister_notify(struct notifier_block *nb)
+{
+ blocking_notifier_chain_unregister(&dca_provider_chain, nb);
+}
+EXPORT_SYMBOL_GPL(dca_unregister_notify);
+
+static int __init dca_init(void)
+{
+ return dca_sysfs_init();
+}
+
+static void __exit dca_exit(void)
+{
+ dca_sysfs_exit();
+}
+
+module_init(dca_init);
+module_exit(dca_exit);
+
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
new file mode 100644
index 00000000000..24a263b6844
--- /dev/null
+++ b/drivers/dca/dca-sysfs.c
@@ -0,0 +1,88 @@
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/idr.h>
+#include <linux/kdev_t.h>
+#include <linux/err.h>
+#include <linux/dca.h>
+
+static struct class *dca_class;
+static struct idr dca_idr;
+static spinlock_t dca_idr_lock;
+
+int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
+{
+ struct class_device *cd;
+
+ cd = class_device_create(dca_class, dca->cd, MKDEV(0, slot + 1),
+ dev, "requester%d", slot);
+ if (IS_ERR(cd))
+ return PTR_ERR(cd);
+ return 0;
+}
+
+void dca_sysfs_remove_req(struct dca_provider *dca, int slot)
+{
+ class_device_destroy(dca_class, MKDEV(0, slot + 1));
+}
+
+int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev)
+{
+ struct class_device *cd;
+ int err = 0;
+
+idr_try_again:
+ if (!idr_pre_get(&dca_idr, GFP_KERNEL))
+ return -ENOMEM;
+ spin_lock(&dca_idr_lock);
+ err = idr_get_new(&dca_idr, dca, &dca->id);
+ spin_unlock(&dca_idr_lock);
+ switch (err) {
+ case 0:
+ break;
+ case -EAGAIN:
+ goto idr_try_again;
+ default:
+ return err;
+ }
+
+ cd = class_device_create(dca_class, NULL, MKDEV(0, 0),
+ dev, "dca%d", dca->id);
+ if (IS_ERR(cd)) {
+ spin_lock(&dca_idr_lock);
+ idr_remove(&dca_idr, dca->id);
+ spin_unlock(&dca_idr_lock);
+ return PTR_ERR(cd);
+ }
+ dca->cd = cd;
+ return 0;
+}
+
+void dca_sysfs_remove_provider(struct dca_provider *dca)
+{
+ class_device_unregister(dca->cd);
+ dca->cd = NULL;
+ spin_lock(&dca_idr_lock);
+ idr_remove(&dca_idr, dca->id);
+ spin_unlock(&dca_idr_lock);
+}
+
+int __init dca_sysfs_init(void)
+{
+ idr_init(&dca_idr);
+ spin_lock_init(&dca_idr_lock);
+
+ dca_class = class_create(THIS_MODULE, "dca");
+ if (IS_ERR(dca_class)) {
+ idr_destroy(&dca_idr);
+ return PTR_ERR(dca_class);
+ }
+ return 0;
+}
+
+void __exit dca_sysfs_exit(void)
+{
+ class_destroy(dca_class);
+ idr_destroy(&dca_idr);
+}
+
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8f670dae53b..9c91b0fd134 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -2,42 +2,52 @@
# DMA engine configuration
#
-menu "DMA Engine support"
- depends on HAS_DMA
+menuconfig DMADEVICES
+ bool "DMA Offload Engine support"
+ depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
+ help
+ Intel(R) offload engines enable offloading memory copies in the
+ network stack and RAID operations in the MD driver.
+
+if DMADEVICES
+
+comment "DMA Devices"
+
+config INTEL_IOATDMA
+ tristate "Intel I/OAT DMA support"
+ depends on PCI && X86
+ select DMA_ENGINE
+ select DCA
+ help
+ Enable support for the Intel(R) I/OAT DMA engine present
+ in recent Intel Xeon chipsets.
+
+ Say Y here if you have such a chipset.
+
+ If unsure, say N.
+
+config INTEL_IOP_ADMA
+ tristate "Intel IOP ADMA support"
+ depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
+ select ASYNC_CORE
+ select DMA_ENGINE
+ help
+ Enable support for the Intel(R) IOP Series RAID engines.
config DMA_ENGINE
- bool "Support for DMA engines"
- ---help---
- DMA engines offload bulk memory operations from the CPU to dedicated
- hardware, allowing the operations to happen asynchronously.
+ bool
comment "DMA Clients"
+ depends on DMA_ENGINE
config NET_DMA
bool "Network: TCP receive copy offload"
depends on DMA_ENGINE && NET
default y
- ---help---
+ help
This enables the use of DMA engines in the network stack to
offload receive copy-to-user operations, freeing CPU cycles.
Since this is the main user of the DMA engine, it should be enabled;
say Y here.
-comment "DMA Devices"
-
-config INTEL_IOATDMA
- tristate "Intel I/OAT DMA support"
- depends on DMA_ENGINE && PCI
- default m
- ---help---
- Enable support for the Intel(R) I/OAT DMA engine.
-
-config INTEL_IOP_ADMA
- tristate "Intel IOP ADMA support"
- depends on DMA_ENGINE && (ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX)
- select ASYNC_CORE
- default m
- ---help---
- Enable support for the Intel(R) IOP Series RAID engines.
-
-endmenu
+endif
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index b3839b687ae..b152cd84e12 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
obj-$(CONFIG_NET_DMA) += iovlock.o
obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
+ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c
new file mode 100644
index 00000000000..f204c39fb41
--- /dev/null
+++ b/drivers/dma/ioat.c
@@ -0,0 +1,200 @@
+/*
+ * Intel I/OAT DMA Linux driver
+ * Copyright(c) 2007 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 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ */
+
+/*
+ * This driver supports an Intel I/OAT DMA engine, which does asynchronous
+ * copy operations.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dca.h>
+#include "ioatdma.h"
+#include "ioatdma_registers.h"
+#include "ioatdma_hw.h"
+
+MODULE_VERSION(IOAT_DMA_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Intel Corporation");
+
+static struct pci_device_id ioat_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB) },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) },
+ { PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
+ { 0, }
+};
+
+struct ioat_device {
+ struct pci_dev *pdev;
+ void __iomem *iobase;
+ struct ioatdma_device *dma;
+ struct dca_provider *dca;
+};
+
+static int __devinit ioat_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id);
+static void __devexit ioat_remove(struct pci_dev *pdev);
+
+static int ioat_dca_enabled = 1;
+module_param(ioat_dca_enabled, int, 0644);
+MODULE_PARM_DESC(ioat_dca_enabled, "control support of dca service (default: 1)");
+
+static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
+{
+ struct ioat_device *device = pci_get_drvdata(pdev);
+ u8 version;
+ int err = 0;
+
+ version = readb(iobase + IOAT_VER_OFFSET);
+ switch (version) {
+ case IOAT_VER_1_2:
+ device->dma = ioat_dma_probe(pdev, iobase);
+ if (device->dma && ioat_dca_enabled)
+ device->dca = ioat_dca_init(pdev, iobase);
+ break;
+ default:
+ err = -ENODEV;
+ break;
+ }
+ return err;
+}
+
+static void ioat_shutdown_functionality(struct pci_dev *pdev)
+{
+ struct ioat_device *device = pci_get_drvdata(pdev);
+
+ dev_err(&pdev->dev, "Removing dma and dca services\n");
+ if (device->dca) {
+ unregister_dca_provider(device->dca);
+ free_dca_provider(device->dca);
+ device->dca = NULL;
+ }
+
+ if (device->dma) {
+ ioat_dma_remove(device->dma);
+ device->dma = NULL;
+ }
+}
+
+static struct pci_driver ioat_pci_driver = {
+ .name = "ioatdma",
+ .id_table = ioat_pci_tbl,
+ .probe = ioat_probe,
+ .shutdown = ioat_shutdown_functionality,
+ .remove = __devexit_p(ioat_remove),
+};
+
+static int __devinit ioat_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ void __iomem *iobase;
+ struct ioat_device *device;
+ unsigned long mmio_start, mmio_len;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ goto err_enable_device;
+
+ err = pci_request_regions(pdev, ioat_pci_driver.name);
+ if (err)
+ goto err_request_regions;
+
+ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+ if (err)
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err)
+ goto err_set_dma_mask;
+
+ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (err)
+ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (err)
+ goto err_set_dma_mask;
+
+ mmio_start = pci_resource_start(pdev, 0);
+ mmio_len = pci_resource_len(pdev, 0);
+ iobase = ioremap(mmio_start, mmio_len);
+ if (!iobase) {
+ err = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
+ if (!device) {
+ err = -ENOMEM;
+ goto err_kzalloc;
+ }
+ device->pdev = pdev;
+ pci_set_drvdata(pdev, device);
+ device->iobase = iobase;
+
+ pci_set_master(pdev);
+
+ err = ioat_setup_functionality(pdev, iobase);
+ if (err)
+ goto err_version;
+
+ return 0;
+
+err_version:
+ kfree(device);
+err_kzalloc:
+ iounmap(iobase);
+err_ioremap:
+err_set_dma_mask:
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+err_request_regions:
+err_enable_device:
+ return err;
+}
+
+/*
+ * It is unsafe to remove this module: if removed while a requested
+ * dma is outstanding, esp. from tcp, it is possible to hang while
+ * waiting for something that will never finish. However, if you're
+ * feeling lucky, this usually works just fine.
+ */
+static void __devexit ioat_remove(struct pci_dev *pdev)
+{
+ struct ioat_device *device = pci_get_drvdata(pdev);
+
+ ioat_shutdown_functionality(pdev);
+
+ kfree(device);
+}
+
+static int __init ioat_init_module(void)
+{
+ return pci_register_driver(&ioat_pci_driver);
+}
+module_init(ioat_init_module);
+
+static void __exit ioat_exit_module(void)
+{
+ pci_unregister_driver(&ioat_pci_driver);
+}
+module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioat_dca.c b/drivers/dma/ioat_dca.c
new file mode 100644
index 00000000000..ba985715b80
--- /dev/null
+++ b/drivers/dma/ioat_dca.c
@@ -0,0 +1,263 @@
+/*
+ * Intel I/OAT DMA Linux driver
+ * Copyright(c) 2007 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 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/dca.h>
+
+/* either a kernel change is needed, or we need something like this in kernel */
+#ifndef CONFIG_SMP
+#include <asm/smp.h>
+#undef cpu_physical_id
+#define cpu_physical_id(cpu) (cpuid_ebx(1) >> 24)
+#endif
+
+#include "ioatdma.h"
+#include "ioatdma_registers.h"
+
+/*
+ * Bit 16 of a tag map entry is the "valid" bit, if it is set then bits 0:15
+ * contain the bit number of the APIC ID to map into the DCA tag. If the valid
+ * bit is not set, then the value must be 0 or 1 and defines the bit in the tag.
+ */
+#define DCA_TAG_MAP_VALID 0x80
+
+/*
+ * "Legacy" DCA systems do not implement the DCA register set in the
+ * I/OAT device. Software needs direct support for their tag mappings.
+ */
+
+#define APICID_BIT(x) (DCA_TAG_MAP_VALID | (x))
+#define IOAT_TAG_MAP_LEN 8
+
+static u8 ioat_tag_map_BNB[IOAT_TAG_MAP_LEN] = {
+ 1, APICID_BIT(1), APICID_BIT(2), APICID_BIT(2), };
+static u8 ioat_tag_map_SCNB[IOAT_TAG_MAP_LEN] = {
+ 1, APICID_BIT(1), APICID_BIT(2), APICID_BIT(2), };
+static u8 ioat_tag_map_CNB[IOAT_TAG_MAP_LEN] = {
+ 1, APICID_BIT(1), APICID_BIT(3), APICID_BIT(4), APICID_BIT(2), };
+static u8 ioat_tag_map_UNISYS[IOAT_TAG_MAP_LEN] = { 0 };
+
+/* pack PCI B/D/F into a u16 */
+static inline u16 dcaid_from_pcidev(struct pci_dev *pci)
+{
+ return (pci->bus->number << 8) | pci->devfn;
+}
+
+static int dca_enabled_in_bios(struct pci_dev *pdev)
+{
+ /* CPUID level 9 returns DCA configuration */
+ /* Bit 0 indicates DCA enabled by the BIOS */
+ unsigned long cpuid_level_9;
+ int res;
+
+ cpuid_level_9 = cpuid_eax(9);
+ res = test_bit(0, &cpuid_level_9);
+ if (!res)
+ dev_err(&pdev->dev, "DCA is disabled in BIOS\n");
+
+ return res;
+}
+
+static int system_has_dca_enabled(struct pci_dev *pdev)
+{
+ if (boot_cpu_has(X86_FEATURE_DCA))
+ return dca_enabled_in_bios(pdev);
+
+ dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
+ return 0;
+}
+
+struct ioat_dca_slot {
+ struct pci_dev *pdev; /* requester device */
+ u16 rid; /* requester id, as used by IOAT */
+};
+
+#define IOAT_DCA_MAX_REQ 6
+
+struct ioat_dca_priv {
+ void __iomem *iobase;
+ void *dca_base;
+ int max_requesters;
+ int requester_count;
+ u8 tag_map[IOAT_TAG_MAP_LEN];
+ struct ioat_dca_slot req_slots[0];
+};
+
+/* 5000 series chipset DCA Port Requester ID Table Entry Format
+ * [15:8] PCI-Express Bus Number
+ * [7:3] PCI-Express Device Number
+ * [2:0] PCI-Express Function Number
+ *
+ * 5000 series chipset DCA control register format
+ * [7:1] Reserved (0)
+ * [0] Ignore Function Number
+ */
+
+static int ioat_dca_add_requester(struct dca_provider *dca, struct device *dev)
+{
+ struct ioat_dca_priv *ioatdca = dca_priv(dca);
+ struct pci_dev *pdev;
+ int i;
+ u16 id;
+
+ /* This implementation only supports PCI-Express */
+ if (dev->bus != &pci_bus_type)
+ return -ENODEV;
+ pdev = to_pci_dev(dev);
+ id = dcaid_from_pcidev(pdev);
+
+ if (ioatdca->requester_count == ioatdca->max_requesters)
+ return -ENODEV;
+
+ for (i = 0; i < ioatdca->max_requesters; i++) {
+ if (ioatdca->req_slots[i].pdev == NULL) {
+ /* found an empty slot */
+ ioatdca->requester_count++;
+ ioatdca->req_slots[i].pdev = pdev;
+ ioatdca->req_slots[i].rid = id;
+ writew(id, ioatdca->dca_base + (i * 4));
+ /* make sure the ignore function bit is off */
+ writeb(0, ioatdca->dca_base + (i * 4) + 2);
+ return i;
+ }
+ }
+ /* Error, ioatdma->requester_count is out of whack */
+ return -EFAULT;
+}
+
+static int ioat_dca_remove_requester(struct dca_provider *dca,
+ struct device *dev)
+{
+ struct ioat_dca_priv *ioatdca = dca_priv(dca);
+ struct pci_dev *pdev;
+ int i;
+
+ /* This implementation only supports PCI-Express */
+ if (dev->bus != &pci_bus_type)
+ return -ENODEV;
+ pdev = to_pci_dev(dev);
+
+ for (i = 0; i < ioatdca->max_requesters; i++) {
+ if (ioatdca->req_slots[i].pdev == pdev) {
+ writew(0, ioatdca->dca_base + (i * 4));
+ ioatdca->req_slots[i].pdev = NULL;
+ ioatdca->req_slots[i].rid = 0;
+ ioatdca->requester_count--;
+ return i;
+ }
+ }
+ return -ENODEV;
+}
+
+static u8 ioat_dca_get_tag(struct dca_provider *dca, int cpu)
+{
+ struct ioat_dca_priv *ioatdca = dca_priv(dca);
+ int i, apic_id, bit, value;
+ u8 entry, tag;
+
+ tag = 0;
+ apic_id = cpu_physical_id(cpu);
+
+ for (i = 0; i < IOAT_TAG_MAP_LEN; i++) {
+ entry = ioatdca->tag_map[i];
+ if (entry & DCA_TAG_MAP_VALID) {
+ bit = entry & ~DCA_TAG_MAP_VALID;
+ value = (apic_id & (1 << bit)) ? 1 : 0;
+ } else {
+ value = entry ? 1 : 0;
+ }
+ tag |= (value << i);
+ }
+ return tag;
+}
+
+static struct dca_ops ioat_dca_ops = {
+ .add_requester = ioat_dca_add_requester,
+ .remove_requester = ioat_dca_remove_requester,
+ .get_tag = ioat_dca_get_tag,
+};
+
+
+struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
+{
+ struct dca_provider *dca;
+ struct ioat_dca_priv *ioatdca;
+ u8 *tag_map = NULL;
+ int i;
+ int err;
+
+ if (!system_has_dca_enabled(pdev))
+ return NULL;
+
+ /* I/OAT v1 systems must have a known tag_map to support DCA */
+ switch (pdev->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_INTEL_IOAT:
+ tag_map = ioat_tag_map_BNB;
+ break;
+ case PCI_DEVICE_ID_INTEL_IOAT_CNB:
+ tag_map = ioat_tag_map_CNB;
+ break;
+ case PCI_DEVICE_ID_INTEL_IOAT_SCNB:
+ tag_map = ioat_tag_map_SCNB;
+ break;
+ }
+ break;
+ case PCI_VENDOR_ID_UNISYS:
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR:
+ tag_map = ioat_tag_map_UNISYS;
+ break;
+ }
+ break;
+ }
+ if (tag_map == NULL)
+ return NULL;
+
+ dca = alloc_dca_provider(&ioat_dca_ops,
+ sizeof(*ioatdca) +
+ (sizeof(struct ioat_dca_slot) * IOAT_DCA_MAX_REQ));
+ if (!dca)
+ return NULL;
+
+ ioatdca = dca_priv(dca);
+ ioatdca->max_requesters = IOAT_DCA_MAX_REQ;
+
+ ioatdca->dca_base = iobase + 0x54;
+
+ /* copy over the APIC ID to DCA tag mapping */
+ for (i = 0; i < IOAT_TAG_MAP_LEN; i++)
+ ioatdca->tag_map[i] = tag_map[i];
+
+ err = register_dca_provider(dca, &pdev->dev);
+ if (err) {
+ free_dca_provider(dca);
+ return NULL;
+ }
+
+ return dca;
+}
+
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
new file mode 100644
index 00000000000..7e4a785c2df
--- /dev/null
+++ b/drivers/dma/ioat_dma.c
@@ -0,0 +1,1009 @@
+/*
+ * Intel I/OAT DMA Linux driver
+ * Copyright(c) 2004 - 2007 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 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ */
+
+/*
+ * This driver supports an Intel I/OAT DMA engine, which does asynchronous
+ * copy operations.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include "ioatdma.h"
+#include "ioatdma_registers.h"
+#include "ioatdma_hw.h"
+
+#define INITIAL_IOAT_DESC_COUNT 128
+
+#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
+#define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, common)
+#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
+#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx)
+
+/* internal functions */
+static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
+static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
+static struct ioat_desc_sw *
+ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan);
+
+static inline struct ioat_dma_chan *ioat_lookup_chan_by_index(
+ struct ioatdma_device *device,
+ int index)
+{
+ return device->idx[index];
+}
+
+/**
+ * ioat_dma_do_interrupt - handler used for single vector interrupt mode
+ * @irq: interrupt id
+ * @data: interrupt data
+ */
+static irqreturn_t ioat_dma_do_interrupt(int irq, void *data)
+{
+ struct ioatdma_device *instance = data;
+ struct ioat_dma_chan *ioat_chan;
+ unsigned long attnstatus;
+ int bit;
+ u8 intrctrl;
+
+ intrctrl = readb(instance->reg_base + IOAT_INTRCTRL_OFFSET);
+
+ if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
+ return IRQ_NONE;
+
+ if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
+ writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
+ return IRQ_NONE;
+ }
+
+ attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
+ for_each_bit(bit, &attnstatus, BITS_PER_LONG) {
+ ioat_chan = ioat_lookup_chan_by_index(instance, bit);
+ tasklet_schedule(&ioat_chan->cleanup_task);
+ }
+
+ writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
+ return IRQ_HANDLED;
+}
+
+/**
+ * ioat_dma_do_interrupt_msix - handler used for vector-per-channel interrupt mode
+ * @irq: interrupt id
+ * @data: interrupt data
+ */
+static irqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data)
+{
+ struct ioat_dma_chan *ioat_chan = data;
+
+ tasklet_schedule(&ioat_chan->cleanup_task);
+
+ return IRQ_HANDLED;
+}
+
+static void ioat_dma_cleanup_tasklet(unsigned long data);
+
+/**
+ * ioat_dma_enumerate_channels - find and initialize the device's channels
+ * @device: the device to be enumerated
+ */
+static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
+{
+ u8 xfercap_scale;
+ u32 xfercap;
+ int i;
+ struct ioat_dma_chan *ioat_chan;
+
+ device->common.chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET);
+ xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
+ xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
+
+ for (i = 0; i < device->common.chancnt; i++) {
+ ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
+ if (!ioat_chan) {
+ device->common.chancnt = i;
+ break;
+ }
+
+ ioat_chan->device = device;
+ ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1));
+ ioat_chan->xfercap = xfercap;
+ spin_lock_init(&ioat_chan->cleanup_lock);
+ spin_lock_init(&ioat_chan->desc_lock);
+ INIT_LIST_HEAD(&ioat_chan->free_desc);
+ INIT_LIST_HEAD(&ioat_chan->used_desc);
+ /* This should be made common somewhere in dmaengine.c */
+ ioat_chan->common.device = &device->common;
+ list_add_tail(&ioat_chan->common.device_node,
+ &device->common.channels);
+ device->idx[i] = ioat_chan;
+ tasklet_init(&ioat_chan->cleanup_task,
+ ioat_dma_cleanup_tasklet,
+ (unsigned long) ioat_chan);
+ tasklet_disable(&ioat_chan->cleanup_task);
+ }
+ return device->common.chancnt;
+}
+
+static void ioat_set_src(dma_addr_t addr,
+ struct dma_async_tx_descriptor *tx,
+ int index)
+{
+ tx_to_ioat_desc(tx)->src = addr;
+}
+
+static void ioat_set_dest(dma_addr_t addr,
+ struct dma_async_tx_descriptor *tx,
+ int index)
+{
+ tx_to_ioat_desc(tx)->dst = addr;
+}
+
+static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
+ struct ioat_desc_sw *first = tx_to_ioat_desc(tx);
+ struct ioat_desc_sw *prev, *new;
+ struct ioat_dma_descriptor *hw;
+ int append = 0;
+ dma_cookie_t cookie;
+ LIST_HEAD(new_chain);
+ u32 copy;
+ size_t len;
+ dma_addr_t src, dst;
+ int orig_ack;
+ unsigned int desc_count = 0;
+
+ /* src and dest and len are stored in the initial descriptor */
+ len = first->len;
+ src = first->src;
+ dst = first->dst;
+ orig_ack = first->async_tx.ack;
+ new = first;
+
+ spin_lock_bh(&ioat_chan->desc_lock);
+ prev = to_ioat_desc(ioat_chan->used_desc.prev);
+ prefetch(prev->hw);
+ do {
+ copy = min((u32) len, ioat_chan->xfercap);
+
+ new->async_tx.ack = 1;
+
+ hw = new->hw;
+ hw->size = copy;
+ hw->ctl = 0;
+ hw->src_addr = src;
+ hw->dst_addr = dst;
+ hw->next = 0;
+
+ /* chain together the physical address list for the HW */
+ wmb();
+ prev->hw->next = (u64) new->async_tx.phys;
+
+ len -= copy;
+ dst += copy;
+ src += copy;
+
+ list_add_tail(&new->node, &new_chain);
+ desc_count++;
+ prev = new;
+ } while (len && (new = ioat_dma_get_next_descriptor(ioat_chan)));
+
+ hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+ if (new->async_tx.callback) {
+ hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
+ if (first != new) {
+ /* move callback into to last desc */
+ new->async_tx.callback = first->async_tx.callback;
+ new->async_tx.callback_param
+ = first->async_tx.callback_param;
+ first->async_tx.callback = NULL;
+ first->async_tx.callback_param = NULL;
+ }
+ }
+
+ new->tx_cnt = desc_count;
+ new->async_tx.ack = orig_ack; /* client is in control of this ack */
+
+ /* store the original values for use in later cleanup */
+ if (new != first) {
+ new->src = first->src;
+ new->dst = first->dst;
+ new->len = first->len;
+ }
+
+ /* cookie incr and addition to used_list must be atomic */
+ cookie = ioat_chan->common.cookie;
+ cookie++;
+ if (cookie < 0)
+ cookie = 1;
+ ioat_chan->common.cookie = new->async_tx.cookie = cookie;
+
+ /* write address into NextDescriptor field of last desc in chain */
+ to_ioat_desc(ioat_chan->used_desc.prev)->hw->next =
+ first->async_tx.phys;
+ __list_splice(&new_chain, ioat_chan->used_desc.prev);
+
+ ioat_chan->pending += desc_count;
+ if (ioat_chan->pending >= 4) {
+ append = 1;
+ ioat_chan->pending = 0;
+ }
+ spin_unlock_bh(&ioat_chan->desc_lock);
+
+ if (append)
+ writeb(IOAT_CHANCMD_APPEND,
+ ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+
+ return cookie;
+}
+
+static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
+ struct ioat_dma_chan *ioat_chan,
+ gfp_t flags)
+{
+ struct ioat_dma_descriptor *desc;
+ struct ioat_desc_sw *desc_sw;
+ struct ioatdma_device *ioatdma_device;
+ dma_addr_t phys;
+
+ ioatdma_device = to_ioatdma_device(ioat_chan->common.device);
+ desc = pci_pool_alloc(ioatdma_device->dma_pool, flags, &phys);
+ if (unlikely(!desc))
+ return NULL;
+
+ desc_sw = kzalloc(sizeof(*desc_sw), flags);
+ if (unlikely(!desc_sw)) {
+ pci_pool_free(ioatdma_device->dma_pool, desc, phys);
+ return NULL;
+ }
+
+ memset(desc, 0, sizeof(*desc));
+ dma_async_tx_descriptor_init(&desc_sw->async_tx, &ioat_chan->common);
+ desc_sw->async_tx.tx_set_src = ioat_set_src;
+ desc_sw->async_tx.tx_set_dest = ioat_set_dest;
+ desc_sw->async_tx.tx_submit = ioat_tx_submit;
+ INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
+ desc_sw->hw = desc;
+ desc_sw->async_tx.phys = phys;
+
+ return desc_sw;
+}
+
+/* returns the actual number of allocated descriptors */
+static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+ struct ioat_desc_sw *desc = NULL;
+ u16 chanctrl;
+ u32 chanerr;
+ int i;
+ LIST_HEAD(tmp_list);
+
+ /* have we already been set up? */
+ if (!list_empty(&ioat_chan->free_desc))
+ return INITIAL_IOAT_DESC_COUNT;
+
+ /* Setup register to interrupt and write completion status on error */
+ chanctrl = IOAT_CHANCTRL_ERR_INT_EN |
+ IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
+ IOAT_CHANCTRL_ERR_COMPLETION_EN;
+ writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET);
+
+ chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
+ if (chanerr) {
+ dev_err(&ioat_chan->device->pdev->dev,
+ "CHANERR = %x, clearing\n", chanerr);
+ writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
+ }
+
+ /* Allocate descriptors */
+ for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) {
+ desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
+ if (!desc) {
+ dev_err(&ioat_chan->device->pdev->dev,
+ "Only %d initial descriptors\n", i);
+ break;
+ }
+ list_add_tail(&desc->node, &tmp_list);
+ }
+ spin_lock_bh(&ioat_chan->desc_lock);
+ list_splice(&tmp_list, &ioat_chan->free_desc);
+ spin_unlock_bh(&ioat_chan->desc_lock);
+
+ /* allocate a completion writeback area */
+ /* doing 2 32bit writes to mmio since 1 64b write doesn't work */
+ ioat_chan->completion_virt =
+ pci_pool_alloc(ioat_chan->device->completion_pool,
+ GFP_KERNEL,
+ &ioat_chan->completion_addr);
+ memset(ioat_chan->completion_virt, 0,
+ sizeof(*ioat_chan->completion_virt));
+ writel(((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF,
+ ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_LOW);
+ writel(((u64) ioat_chan->completion_addr) >> 32,
+ ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
+
+ tasklet_enable(&ioat_chan->cleanup_task);
+ ioat_dma_start_null_desc(ioat_chan);
+ return i;
+}
+
+static void ioat_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+ struct ioatdma_device *ioatdma_device = to_ioatdma_device(chan->device);
+ struct ioat_desc_sw *desc, *_desc;
+ int in_use_descs = 0;
+
+ tasklet_disable(&ioat_chan->cleanup_task);
+ ioat_dma_memcpy_cleanup(ioat_chan);
+
+ /* Delay 100ms after reset to allow internal DMA logic to quiesce
+ * before removing DMA descriptor resources.
+ */
+ writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+ mdelay(100);
+
+ spin_lock_bh(&ioat_chan->desc_lock);
+ list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
+ in_use_descs++;
+ list_del(&desc->node);
+ pci_pool_free(ioatdma_device->dma_pool, desc->hw,
+ desc->async_tx.phys);
+ kfree(desc);
+ }
+ list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) {
+ list_del(&desc->node);
+ pci_pool_free(ioatdma_device->dma_pool, desc->hw,
+ desc->async_tx.phys);
+ kfree(desc);
+ }
+ spin_unlock_bh(&ioat_chan->desc_lock);
+
+ pci_pool_free(ioatdma_device->completion_pool,
+ ioat_chan->completion_virt,
+ ioat_chan->completion_addr);
+
+ /* one is ok since we left it on there on purpose */
+ if (in_use_descs > 1)
+ dev_err(&ioat_chan->device->pdev->dev,
+ "Freeing %d in use descriptors!\n",
+ in_use_descs - 1);
+
+ ioat_chan->last_completion = ioat_chan->completion_addr = 0;
+ ioat_chan->pending = 0;
+}
+
+/**
+ * ioat_dma_get_next_descriptor - return the next available descriptor
+ * @ioat_chan: IOAT DMA channel handle
+ *
+ * Gets the next descriptor from the chain, and must be called with the
+ * channel's desc_lock held. Allocates more descriptors if the channel
+ * has run out.
+ */
+static struct ioat_desc_sw *
+ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan)
+{
+ struct ioat_desc_sw *new = NULL;
+
+ if (!list_empty(&ioat_chan->free_desc)) {
+ new = to_ioat_desc(ioat_chan->free_desc.next);
+ list_del(&new->node);
+ } else {
+ /* try to get another desc */
+ new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
+ /* will this ever happen? */
+ /* TODO add upper limit on these */
+ BUG_ON(!new);
+ }
+
+ prefetch(new->hw);
+ return new;
+}
+
+static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy(
+ struct dma_chan *chan,
+ size_t len,
+ int int_en)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+ struct ioat_desc_sw *new;
+
+ spin_lock_bh(&ioat_chan->desc_lock);
+ new = ioat_dma_get_next_descriptor(ioat_chan);
+ new->len = len;
+ spin_unlock_bh(&ioat_chan->desc_lock);
+
+ return new ? &new->async_tx : NULL;
+}
+
+/**
+ * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended
+ * descriptors to hw
+ * @chan: DMA channel handle
+ */
+static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+
+ if (ioat_chan->pending != 0) {
+ ioat_chan->pending = 0;
+ writeb(IOAT_CHANCMD_APPEND,
+ ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+ }
+}
+
+static void ioat_dma_cleanup_tasklet(unsigned long data)
+{
+ struct ioat_dma_chan *chan = (void *)data;
+ ioat_dma_memcpy_cleanup(chan);
+ writew(IOAT_CHANCTRL_INT_DISABLE,
+ chan->reg_base + IOAT_CHANCTRL_OFFSET);
+}
+
+static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
+{
+ unsigned long phys_complete;
+ struct ioat_desc_sw *desc, *_desc;
+ dma_cookie_t cookie = 0;
+
+ prefetch(ioat_chan->completion_virt);
+
+ if (!spin_trylock_bh(&ioat_chan->cleanup_lock))
+ return;
+
+ /* The completion writeback can happen at any time,
+ so reads by the driver need to be atomic operations
+ The descriptor physical addresses are limited to 32-bits
+ when the CPU can only do a 32-bit mov */
+
+#if (BITS_PER_LONG == 64)
+ phys_complete =
+ ioat_chan->completion_virt->full
+ & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
+#else
+ phys_complete =
+ ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
+#endif
+
+ if ((ioat_chan->completion_virt->full
+ & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
+ IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
+ dev_err(&ioat_chan->device->pdev->dev,
+ "Channel halted, chanerr = %x\n",
+ readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET));
+
+ /* TODO do something to salvage the situation */
+ }
+
+ if (phys_complete == ioat_chan->last_completion) {
+ spin_unlock_bh(&ioat_chan->cleanup_lock);
+ return;
+ }
+
+ cookie = 0;
+ spin_lock_bh(&ioat_chan->desc_lock);
+ list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
+
+ /*
+ * Incoming DMA requests may use multiple descriptors, due to
+ * exceeding xfercap, perhaps. If so, only the last one will
+ * have a cookie, and require unmapping.
+ */
+ if (desc->async_tx.cookie) {
+ cookie = desc->async_tx.cookie;
+
+ /*
+ * yes we are unmapping both _page and _single alloc'd
+ * regions with unmap_page. Is this *really* that bad?
+ */
+ pci_unmap_page(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, dst),
+ pci_unmap_len(desc, len),
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_page(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, src),
+ pci_unmap_len(desc, len),
+ PCI_DMA_TODEVICE);
+ if (desc->async_tx.callback) {
+ desc->async_tx.callback(
+ desc->async_tx.callback_param);
+ desc->async_tx.callback = NULL;
+ }
+ }
+
+ if (desc->async_tx.phys != phys_complete) {
+ /*
+ * a completed entry, but not the last, so cleanup
+ * if the client is done with the descriptor
+ */
+ if (desc->async_tx.ack) {
+ list_del(&desc->node);
+ list_add_tail(&desc->node,
+ &ioat_chan->free_desc);
+ } else
+ desc->async_tx.cookie = 0;
+ } else {
+ /*
+ * last used desc. Do not remove, so we can append from
+ * it, but don't look at it next time, either
+ */
+ desc->async_tx.cookie = 0;
+
+ /* TODO check status bits? */
+ break;
+ }
+ }
+
+ spin_unlock_bh(&ioat_chan->desc_lock);
+
+ ioat_chan->last_completion = phys_complete;
+ if (cookie != 0)
+ ioat_chan->completed_cookie = cookie;
+
+ spin_unlock_bh(&ioat_chan->cleanup_lock);
+}
+
+static void ioat_dma_dependency_added(struct dma_chan *chan)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+ spin_lock_bh(&ioat_chan->desc_lock);
+ if (ioat_chan->pending == 0) {
+ spin_unlock_bh(&ioat_chan->desc_lock);
+ ioat_dma_memcpy_cleanup(ioat_chan);
+ } else
+ spin_unlock_bh(&ioat_chan->desc_lock);
+}
+
+/**
+ * ioat_dma_is_complete - poll the status of a IOAT DMA transaction
+ * @chan: IOAT DMA channel handle
+ * @cookie: DMA transaction identifier
+ * @done: if not %NULL, updated with last completed transaction
+ * @used: if not %NULL, updated with last used transaction
+ */
+static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ dma_cookie_t *done,
+ dma_cookie_t *used)
+{
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+ enum dma_status ret;
+
+ last_used = chan->cookie;
+ last_complete = ioat_chan->completed_cookie;
+
+ if (done)
+ *done = last_complete;
+ if (used)
+ *used = last_used;
+
+ ret = dma_async_is_complete(cookie, last_complete, last_used);
+ if (ret == DMA_SUCCESS)
+ return ret;
+
+ ioat_dma_memcpy_cleanup(ioat_chan);
+
+ last_used = chan->cookie;
+ last_complete = ioat_chan->completed_cookie;
+
+ if (done)
+ *done = last_complete;
+ if (used)
+ *used = last_used;
+
+ return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+/* PCI API */
+
+static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
+{
+ struct ioat_desc_sw *desc;
+
+ spin_lock_bh(&ioat_chan->desc_lock);
+
+ desc = ioat_dma_get_next_descriptor(ioat_chan);
+ desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL
+ | IOAT_DMA_DESCRIPTOR_CTL_INT_GN
+ | IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
+ desc->hw->next = 0;
+ desc->hw->size = 0;
+ desc->hw->src_addr = 0;
+ desc->hw->dst_addr = 0;
+ desc->async_tx.ack = 1;
+
+ list_add_tail(&desc->node, &ioat_chan->used_desc);
+ spin_unlock_bh(&ioat_chan->desc_lock);
+
+ writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
+ ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_LOW);
+ writel(((u64) desc->async_tx.phys) >> 32,
+ ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_HIGH);
+
+ writeb(IOAT_CHANCMD_START, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
+}
+
+/*
+ * Perform a IOAT transaction to verify the HW works.
+ */
+#define IOAT_TEST_SIZE 2000
+
+static void ioat_dma_test_callback(void *dma_async_param)
+{
+ printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n",
+ dma_async_param);
+}
+
+/**
+ * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works.
+ * @device: device to be tested
+ */
+static int ioat_dma_self_test(struct ioatdma_device *device)
+{
+ int i;
+ u8 *src;
+ u8 *dest;
+ struct dma_chan *dma_chan;
+ struct dma_async_tx_descriptor *tx = NULL;
+ dma_addr_t addr;
+ dma_cookie_t cookie;
+ int err = 0;
+
+ src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
+ if (!src)
+ return -ENOMEM;
+ dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
+ if (!dest) {
+ kfree(src);
+ return -ENOMEM;
+ }
+
+ /* Fill in src buffer */
+ for (i = 0; i < IOAT_TEST_SIZE; i++)
+ src[i] = (u8)i;
+
+ /* Start copy, using first DMA channel */
+ dma_chan = container_of(device->common.channels.next,
+ struct dma_chan,
+ device_node);
+ if (ioat_dma_alloc_chan_resources(dma_chan) < 1) {
+ dev_err(&device->pdev->dev,
+ "selftest cannot allocate chan resource\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0);
+ if (!tx) {
+ dev_err(&device->pdev->dev,
+ "Self-test prep failed, disabling\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+
+ async_tx_ack(tx);
+ addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE,
+ DMA_TO_DEVICE);
+ ioat_set_src(addr, tx, 0);
+ addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
+ DMA_FROM_DEVICE);
+ ioat_set_dest(addr, tx, 0);
+ tx->callback = ioat_dma_test_callback;
+ tx->callback_param = (void *)0x8086;
+ cookie = ioat_tx_submit(tx);
+ if (cookie < 0) {
+ dev_err(&device->pdev->dev,
+ "Self-test setup failed, disabling\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+ ioat_dma_memcpy_issue_pending(dma_chan);
+ msleep(1);
+
+ if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
+ dev_err(&device->pdev->dev,
+ "Self-test copy timed out, disabling\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+ if (memcmp(src, dest, IOAT_TEST_SIZE)) {
+ dev_err(&device->pdev->dev,
+ "Self-test copy failed compare, disabling\n");
+ err = -ENODEV;
+ goto free_resources;
+ }
+
+free_resources:
+ ioat_dma_free_chan_resources(dma_chan);
+out:
+ kfree(src);
+ kfree(dest);
+ return err;
+}
+
+static char ioat_interrupt_style[32] = "msix";
+module_param_string(ioat_interrupt_style, ioat_interrupt_style,
+ sizeof(ioat_interrupt_style), 0644);
+MODULE_PARM_DESC(ioat_interrupt_style,
+ "set ioat interrupt style: msix (default), "
+ "msix-single-vector, msi, intx)");
+
+/**
+ * ioat_dma_setup_interrupts - setup interrupt handler
+ * @device: ioat device
+ */
+static int ioat_dma_setup_interrupts(struct ioatdma_device *device)
+{
+ struct ioat_dma_chan *ioat_chan;
+ int err, i, j, msixcnt;
+ u8 intrctrl = 0;
+
+ if (!strcmp(ioat_interrupt_style, "msix"))
+ goto msix;
+ if (!strcmp(ioat_interrupt_style, "msix-single-vector"))
+ goto msix_single_vector;
+ if (!strcmp(ioat_interrupt_style, "msi"))
+ goto msi;
+ if (!strcmp(ioat_interrupt_style, "intx"))
+ goto intx;
+ dev_err(&device->pdev->dev, "invalid ioat_interrupt_style %s\n",
+ ioat_interrupt_style);
+ goto err_no_irq;
+
+msix:
+ /* The number of MSI-X vectors should equal the number of channels */
+ msixcnt = device->common.chancnt;
+ for (i = 0; i < msixcnt; i++)
+ device->msix_entries[i].entry = i;
+
+ err = pci_enable_msix(device->pdev, device->msix_entries, msixcnt);
+ if (err < 0)
+ goto msi;
+ if (err > 0)
+ goto msix_single_vector;
+
+ for (i = 0; i < msixcnt; i++) {
+ ioat_chan = ioat_lookup_chan_by_index(device, i);
+ err = request_irq(device->msix_entries[i].vector,
+ ioat_dma_do_interrupt_msix,
+ 0, "ioat-msix", ioat_chan);
+ if (err) {
+ for (j = 0; j < i; j++) {
+ ioat_chan =
+ ioat_lookup_chan_by_index(device, j);
+ free_irq(device->msix_entries[j].vector,
+ ioat_chan);
+ }
+ goto msix_single_vector;
+ }
+ }
+ intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL;
+ device->irq_mode = msix_multi_vector;
+ goto done;
+
+msix_single_vector:
+ device->msix_entries[0].entry = 0;
+ err = pci_enable_msix(device->pdev, device->msix_entries, 1);
+ if (err)
+ goto msi;
+
+ err = request_irq(device->msix_entries[0].vector, ioat_dma_do_interrupt,
+ 0, "ioat-msix", device);
+ if (err) {
+ pci_disable_msix(device->pdev);
+ goto msi;
+ }
+ device->irq_mode = msix_single_vector;
+ goto done;
+
+msi:
+ err = pci_enable_msi(device->pdev);
+ if (err)
+ goto intx;
+
+ err = request_irq(device->pdev->irq, ioat_dma_do_interrupt,
+ 0, "ioat-msi", device);
+ if (err) {
+ pci_disable_msi(device->pdev);
+ goto intx;
+ }
+ /*
+ * CB 1.2 devices need a bit set in configuration space to enable MSI
+ */
+ if (device->version == IOAT_VER_1_2) {
+ u32 dmactrl;
+ pci_read_config_dword(device->pdev,
+ IOAT_PCI_DMACTRL_OFFSET, &dmactrl);
+ dmactrl |= IOAT_PCI_DMACTRL_MSI_EN;
+ pci_write_config_dword(device->pdev,
+ IOAT_PCI_DMACTRL_OFFSET, dmactrl);
+ }
+ device->irq_mode = msi;
+ goto done;
+
+intx:
+ err = request_irq(device->pdev->irq, ioat_dma_do_interrupt,
+ IRQF_SHARED, "ioat-intx", device);
+ if (err)
+ goto err_no_irq;
+ device->irq_mode = intx;
+
+done:
+ intrctrl |= IOAT_INTRCTRL_MASTER_INT_EN;
+ writeb(intrctrl, device->reg_base + IOAT_INTRCTRL_OFFSET);
+ return 0;
+
+err_no_irq:
+ /* Disable all interrupt generation */
+ writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
+ dev_err(&device->pdev->dev, "no usable interrupts\n");
+ device->irq_mode = none;
+ return -1;
+}
+
+/**
+ * ioat_dma_remove_interrupts - remove whatever interrupts were set
+ * @device: ioat device
+ */
+static void ioat_dma_remove_interrupts(struct ioatdma_device *device)
+{
+ struct ioat_dma_chan *ioat_chan;
+ int i;
+
+ /* Disable all interrupt generation */
+ writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
+
+ switch (device->irq_mode) {
+ case msix_multi_vector:
+ for (i = 0; i < device->common.chancnt; i++) {
+ ioat_chan = ioat_lookup_chan_by_index(device, i);
+ free_irq(device->msix_entries[i].vector, ioat_chan);
+ }
+ pci_disable_msix(device->pdev);
+ break;
+ case msix_single_vector:
+ free_irq(device->msix_entries[0].vector, device);
+ pci_disable_msix(device->pdev);
+ break;
+ case msi:
+ free_irq(device->pdev->irq, device);
+ pci_disable_msi(device->pdev);
+ break;
+ case intx:
+ free_irq(device->pdev->irq, device);
+ break;
+ case none:
+ dev_warn(&device->pdev->dev,
+ "call to %s without interrupts setup\n", __func__);
+ }
+ device->irq_mode = none;
+}
+
+struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
+ void __iomem *iobase)
+{
+ int err;
+ struct ioatdma_device *device;
+
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
+ if (!device) {
+ err = -ENOMEM;
+ goto err_kzalloc;
+ }
+ device->pdev = pdev;
+ device->reg_base = iobase;
+ device->version = readb(device->reg_base + IOAT_VER_OFFSET);
+
+ /* DMA coherent memory pool for DMA descriptor allocations */
+ device->dma_pool = pci_pool_create("dma_desc_pool", pdev,
+ sizeof(struct ioat_dma_descriptor),
+ 64, 0);
+ if (!device->dma_pool) {
+ err = -ENOMEM;
+ goto err_dma_pool;
+ }
+
+ device->completion_pool = pci_pool_create("completion_pool", pdev,
+ sizeof(u64), SMP_CACHE_BYTES,
+ SMP_CACHE_BYTES);
+ if (!device->completion_pool) {
+ err = -ENOMEM;
+ goto err_completion_pool;
+ }
+
+ INIT_LIST_HEAD(&device->common.channels);
+ ioat_dma_enumerate_channels(device);
+
+ dma_cap_set(DMA_MEMCPY, device->common.cap_mask);
+ device->common.device_alloc_chan_resources =
+ ioat_dma_alloc_chan_resources;
+ device->common.device_free_chan_resources =
+ ioat_dma_free_chan_resources;
+ device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy;
+ device->common.device_is_tx_complete = ioat_dma_is_complete;
+ device->common.device_issue_pending = ioat_dma_memcpy_issue_pending;
+ device->common.device_dependency_added = ioat_dma_dependency_added;
+ device->common.dev = &pdev->dev;
+ dev_err(&device->pdev->dev,
+ "Intel(R) I/OAT DMA Engine found,"
+ " %d channels, device version 0x%02x, driver version %s\n",
+ device->common.chancnt, device->version, IOAT_DMA_VERSION);
+
+ err = ioat_dma_setup_interrupts(device);
+ if (err)
+ goto err_setup_interrupts;
+
+ err = ioat_dma_self_test(device);
+ if (err)
+ goto err_self_test;
+
+ dma_async_device_register(&device->common);
+
+ return device;
+
+err_self_test:
+ ioat_dma_remove_interrupts(device);
+err_setup_interrupts:
+ pci_pool_destroy(device->completion_pool);
+err_completion_pool:
+ pci_pool_destroy(device->dma_pool);
+err_dma_pool:
+ kfree(device);
+err_kzalloc:
+ dev_err(&device->pdev->dev,
+ "Intel(R) I/OAT DMA Engine initialization failed\n");
+ return NULL;
+}
+
+void ioat_dma_remove(struct ioatdma_device *device)
+{
+ struct dma_chan *chan, *_chan;
+ struct ioat_dma_chan *ioat_chan;
+
+ ioat_dma_remove_interrupts(device);
+
+ dma_async_device_unregister(&device->common);
+
+ pci_pool_destroy(device->dma_pool);
+ pci_pool_destroy(device->completion_pool);
+
+ iounmap(device->reg_base);
+ pci_release_regions(device->pdev);
+ pci_disable_device(device->pdev);
+
+ list_for_each_entry_safe(chan, _chan,
+ &device->common.channels, device_node) {
+ ioat_chan = to_ioat_chan(chan);
+ list_del(&chan->device_node);
+ kfree(ioat_chan);
+ }
+ kfree(device);
+}
+
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c
deleted file mode 100644
index 41b18c5a314..00000000000
--- a/drivers/dma/ioatdma.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
- *
- * 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.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-/*
- * This driver supports an Intel I/OAT DMA engine, which does asynchronous
- * copy operations.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/dmaengine.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-#include "ioatdma.h"
-#include "ioatdma_registers.h"
-#include "ioatdma_hw.h"
-
-#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
-#define to_ioat_device(dev) container_of(dev, struct ioat_device, common)
-#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
-#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx)
-
-/* internal functions */
-static int __devinit ioat_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-static void ioat_shutdown(struct pci_dev *pdev);
-static void __devexit ioat_remove(struct pci_dev *pdev);
-
-static int enumerate_dma_channels(struct ioat_device *device)
-{
- u8 xfercap_scale;
- u32 xfercap;
- int i;
- struct ioat_dma_chan *ioat_chan;
-
- device->common.chancnt = readb(device->reg_base + IOAT_CHANCNT_OFFSET);
- xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
- xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
-
- for (i = 0; i < device->common.chancnt; i++) {
- ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
- if (!ioat_chan) {
- device->common.chancnt = i;
- break;
- }
-
- ioat_chan->device = device;
- ioat_chan->reg_base = device->reg_base + (0x80 * (i + 1));
- ioat_chan->xfercap = xfercap;
- spin_lock_init(&ioat_chan->cleanup_lock);
- spin_lock_init(&ioat_chan->desc_lock);
- INIT_LIST_HEAD(&ioat_chan->free_desc);
- INIT_LIST_HEAD(&ioat_chan->used_desc);
- /* This should be made common somewhere in dmaengine.c */
- ioat_chan->common.device = &device->common;
- list_add_tail(&ioat_chan->common.device_node,
- &device->common.channels);
- }
- return device->common.chancnt;
-}
-
-static void
-ioat_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
-{
- struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-
- pci_unmap_addr_set(desc, src, addr);
-
- list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
- iter->hw->src_addr = addr;
- addr += ioat_chan->xfercap;
- }
-
-}
-
-static void
-ioat_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
-{
- struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
-
- pci_unmap_addr_set(desc, dst, addr);
-
- list_for_each_entry(iter, &desc->async_tx.tx_list, node) {
- iter->hw->dst_addr = addr;
- addr += ioat_chan->xfercap;
- }
-}
-
-static dma_cookie_t
-ioat_tx_submit(struct dma_async_tx_descriptor *tx)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
- struct ioat_desc_sw *desc = tx_to_ioat_desc(tx);
- int append = 0;
- dma_cookie_t cookie;
- struct ioat_desc_sw *group_start;
-
- group_start = list_entry(desc->async_tx.tx_list.next,
- struct ioat_desc_sw, node);
- spin_lock_bh(&ioat_chan->desc_lock);
- /* cookie incr and addition to used_list must be atomic */
- cookie = ioat_chan->common.cookie;
- cookie++;
- if (cookie < 0)
- cookie = 1;
- ioat_chan->common.cookie = desc->async_tx.cookie = cookie;
-
- /* write address into NextDescriptor field of last desc in chain */
- to_ioat_desc(ioat_chan->used_desc.prev)->hw->next =
- group_start->async_tx.phys;
- list_splice_init(&desc->async_tx.tx_list, ioat_chan->used_desc.prev);
-
- ioat_chan->pending += desc->tx_cnt;
- if (ioat_chan->pending >= 4) {
- append = 1;
- ioat_chan->pending = 0;
- }
- spin_unlock_bh(&ioat_chan->desc_lock);
-
- if (append)
- writeb(IOAT_CHANCMD_APPEND,
- ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
-
- return cookie;
-}
-
-static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
- struct ioat_dma_chan *ioat_chan,
- gfp_t flags)
-{
- struct ioat_dma_descriptor *desc;
- struct ioat_desc_sw *desc_sw;
- struct ioat_device *ioat_device;
- dma_addr_t phys;
-
- ioat_device = to_ioat_device(ioat_chan->common.device);
- desc = pci_pool_alloc(ioat_device->dma_pool, flags, &phys);
- if (unlikely(!desc))
- return NULL;
-
- desc_sw = kzalloc(sizeof(*desc_sw), flags);
- if (unlikely(!desc_sw)) {
- pci_pool_free(ioat_device->dma_pool, desc, phys);
- return NULL;
- }
-
- memset(desc, 0, sizeof(*desc));
- dma_async_tx_descriptor_init(&desc_sw->async_tx, &ioat_chan->common);
- desc_sw->async_tx.tx_set_src = ioat_set_src;
- desc_sw->async_tx.tx_set_dest = ioat_set_dest;
- desc_sw->async_tx.tx_submit = ioat_tx_submit;
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
- desc_sw->hw = desc;
- desc_sw->async_tx.phys = phys;
-
- return desc_sw;
-}
-
-#define INITIAL_IOAT_DESC_COUNT 128
-
-static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan);
-
-/* returns the actual number of allocated descriptors */
-static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
- struct ioat_desc_sw *desc = NULL;
- u16 chanctrl;
- u32 chanerr;
- int i;
- LIST_HEAD(tmp_list);
-
- /* have we already been set up? */
- if (!list_empty(&ioat_chan->free_desc))
- return INITIAL_IOAT_DESC_COUNT;
-
- /* Setup register to interrupt and write completion status on error */
- chanctrl = IOAT_CHANCTRL_ERR_INT_EN |
- IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
- IOAT_CHANCTRL_ERR_COMPLETION_EN;
- writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET);
-
- chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
- if (chanerr) {
- printk("IOAT: CHANERR = %x, clearing\n", chanerr);
- writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
- }
-
- /* Allocate descriptors */
- for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) {
- desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
- if (!desc) {
- printk(KERN_ERR "IOAT: Only %d initial descriptors\n", i);
- break;
- }
- list_add_tail(&desc->node, &tmp_list);
- }
- spin_lock_bh(&ioat_chan->desc_lock);
- list_splice(&tmp_list, &ioat_chan->free_desc);
- spin_unlock_bh(&ioat_chan->desc_lock);
-
- /* allocate a completion writeback area */
- /* doing 2 32bit writes to mmio since 1 64b write doesn't work */
- ioat_chan->completion_virt =
- pci_pool_alloc(ioat_chan->device->completion_pool,
- GFP_KERNEL,
- &ioat_chan->completion_addr);
- memset(ioat_chan->completion_virt, 0,
- sizeof(*ioat_chan->completion_virt));
- writel(((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF,
- ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_LOW);
- writel(((u64) ioat_chan->completion_addr) >> 32,
- ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
-
- ioat_start_null_desc(ioat_chan);
- return i;
-}
-
-static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
-
-static void ioat_dma_free_chan_resources(struct dma_chan *chan)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
- struct ioat_device *ioat_device = to_ioat_device(chan->device);
- struct ioat_desc_sw *desc, *_desc;
- u16 chanctrl;
- int in_use_descs = 0;
-
- ioat_dma_memcpy_cleanup(ioat_chan);
-
- writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
-
- spin_lock_bh(&ioat_chan->desc_lock);
- list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
- in_use_descs++;
- list_del(&desc->node);
- pci_pool_free(ioat_device->dma_pool, desc->hw,
- desc->async_tx.phys);
- kfree(desc);
- }
- list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) {
- list_del(&desc->node);
- pci_pool_free(ioat_device->dma_pool, desc->hw,
- desc->async_tx.phys);
- kfree(desc);
- }
- spin_unlock_bh(&ioat_chan->desc_lock);
-
- pci_pool_free(ioat_device->completion_pool,
- ioat_chan->completion_virt,
- ioat_chan->completion_addr);
-
- /* one is ok since we left it on there on purpose */
- if (in_use_descs > 1)
- printk(KERN_ERR "IOAT: Freeing %d in use descriptors!\n",
- in_use_descs - 1);
-
- ioat_chan->last_completion = ioat_chan->completion_addr = 0;
-}
-
-static struct dma_async_tx_descriptor *
-ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
- struct ioat_desc_sw *first, *prev, *new;
- LIST_HEAD(new_chain);
- u32 copy;
- size_t orig_len;
- int desc_count = 0;
-
- if (!len)
- return NULL;
-
- orig_len = len;
-
- first = NULL;
- prev = NULL;
-
- spin_lock_bh(&ioat_chan->desc_lock);
- while (len) {
- if (!list_empty(&ioat_chan->free_desc)) {
- new = to_ioat_desc(ioat_chan->free_desc.next);
- list_del(&new->node);
- } else {
- /* try to get another desc */
- new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
- /* will this ever happen? */
- /* TODO add upper limit on these */
- BUG_ON(!new);
- }
-
- copy = min((u32) len, ioat_chan->xfercap);
-
- new->hw->size = copy;
- new->hw->ctl = 0;
- new->async_tx.cookie = 0;
- new->async_tx.ack = 1;
-
- /* chain together the physical address list for the HW */
- if (!first)
- first = new;
- else
- prev->hw->next = (u64) new->async_tx.phys;
-
- prev = new;
- len -= copy;
- list_add_tail(&new->node, &new_chain);
- desc_count++;
- }
-
- list_splice(&new_chain, &new->async_tx.tx_list);
-
- new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
- new->hw->next = 0;
- new->tx_cnt = desc_count;
- new->async_tx.ack = 0; /* client is in control of this ack */
- new->async_tx.cookie = -EBUSY;
-
- pci_unmap_len_set(new, len, orig_len);
- spin_unlock_bh(&ioat_chan->desc_lock);
-
- return new ? &new->async_tx : NULL;
-}
-
-
-/**
- * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended descriptors to hw
- * @chan: DMA channel handle
- */
-
-static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
-
- if (ioat_chan->pending != 0) {
- ioat_chan->pending = 0;
- writeb(IOAT_CHANCMD_APPEND,
- ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
- }
-}
-
-static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
-{
- unsigned long phys_complete;
- struct ioat_desc_sw *desc, *_desc;
- dma_cookie_t cookie = 0;
-
- prefetch(chan->completion_virt);
-
- if (!spin_trylock(&chan->cleanup_lock))
- return;
-
- /* The completion writeback can happen at any time,
- so reads by the driver need to be atomic operations
- The descriptor physical addresses are limited to 32-bits
- when the CPU can only do a 32-bit mov */
-
-#if (BITS_PER_LONG == 64)
- phys_complete =
- chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
-#else
- phys_complete = chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
-#endif
-
- if ((chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
- IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
- printk("IOAT: Channel halted, chanerr = %x\n",
- readl(chan->reg_base + IOAT_CHANERR_OFFSET));
-
- /* TODO do something to salvage the situation */
- }
-
- if (phys_complete == chan->last_completion) {
- spin_unlock(&chan->cleanup_lock);
- return;
- }
-
- spin_lock_bh(&chan->desc_lock);
- list_for_each_entry_safe(desc, _desc, &chan->used_desc, node) {
-
- /*
- * Incoming DMA requests may use multiple descriptors, due to
- * exceeding xfercap, perhaps. If so, only the last one will
- * have a cookie, and require unmapping.
- */
- if (desc->async_tx.cookie) {
- cookie = desc->async_tx.cookie;
-
- /* yes we are unmapping both _page and _single alloc'd
- regions with unmap_page. Is this *really* that bad?
- */
- pci_unmap_page(chan->device->pdev,
- pci_unmap_addr(desc, dst),
- pci_unmap_len(desc, len),
- PCI_DMA_FROMDEVICE);
- pci_unmap_page(chan->device->pdev,
- pci_unmap_addr(desc, src),
- pci_unmap_len(desc, len),
- PCI_DMA_TODEVICE);
- }
-
- if (desc->async_tx.phys != phys_complete) {
- /* a completed entry, but not the last, so cleanup
- * if the client is done with the descriptor
- */
- if (desc->async_tx.ack) {
- list_del(&desc->node);
- list_add_tail(&desc->node, &chan->free_desc);
- } else
- desc->async_tx.cookie = 0;
- } else {
- /* last used desc. Do not remove, so we can append from
- it, but don't look at it next time, either */
- desc->async_tx.cookie = 0;
-
- /* TODO check status bits? */
- break;
- }
- }
-
- spin_unlock_bh(&chan->desc_lock);
-
- chan->last_completion = phys_complete;
- if (cookie != 0)
- chan->completed_cookie = cookie;
-
- spin_unlock(&chan->cleanup_lock);
-}
-
-static void ioat_dma_dependency_added(struct dma_chan *chan)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
- spin_lock_bh(&ioat_chan->desc_lock);
- if (ioat_chan->pending == 0) {
- spin_unlock_bh(&ioat_chan->desc_lock);
- ioat_dma_memcpy_cleanup(ioat_chan);
- } else
- spin_unlock_bh(&ioat_chan->desc_lock);
-}
-
-/**
- * ioat_dma_is_complete - poll the status of a IOAT DMA transaction
- * @chan: IOAT DMA channel handle
- * @cookie: DMA transaction identifier
- * @done: if not %NULL, updated with last completed transaction
- * @used: if not %NULL, updated with last used transaction
- */
-
-static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
- dma_cookie_t cookie,
- dma_cookie_t *done,
- dma_cookie_t *used)
-{
- struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
- dma_cookie_t last_used;
- dma_cookie_t last_complete;
- enum dma_status ret;
-
- last_used = chan->cookie;
- last_complete = ioat_chan->completed_cookie;
-
- if (done)
- *done= last_complete;
- if (used)
- *used = last_used;
-
- ret = dma_async_is_complete(cookie, last_complete, last_used);
- if (ret == DMA_SUCCESS)
- return ret;
-
- ioat_dma_memcpy_cleanup(ioat_chan);
-
- last_used = chan->cookie;
- last_complete = ioat_chan->completed_cookie;
-
- if (done)
- *done= last_complete;
- if (used)
- *used = last_used;
-
- return dma_async_is_complete(cookie, last_complete, last_used);
-}
-
-/* PCI API */
-
-static struct pci_device_id ioat_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
- { PCI_DEVICE(PCI_VENDOR_ID_UNISYS,
- PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
- { 0, }
-};
-
-static struct pci_driver ioat_pci_driver = {
- .name = "ioatdma",
- .id_table = ioat_pci_tbl,
- .probe = ioat_probe,
- .shutdown = ioat_shutdown,
- .remove = __devexit_p(ioat_remove),
-};
-
-static irqreturn_t ioat_do_interrupt(int irq, void *data)
-{
- struct ioat_device *instance = data;
- unsigned long attnstatus;
- u8 intrctrl;
-
- intrctrl = readb(instance->reg_base + IOAT_INTRCTRL_OFFSET);
-
- if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
- return IRQ_NONE;
-
- if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
- writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
- return IRQ_NONE;
- }
-
- attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
-
- printk(KERN_ERR "ioatdma error: interrupt! status %lx\n", attnstatus);
-
- writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
- return IRQ_HANDLED;
-}
-
-static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan)
-{
- struct ioat_desc_sw *desc;
-
- spin_lock_bh(&ioat_chan->desc_lock);
-
- if (!list_empty(&ioat_chan->free_desc)) {
- desc = to_ioat_desc(ioat_chan->free_desc.next);
- list_del(&desc->node);
- } else {
- /* try to get another desc */
- spin_unlock_bh(&ioat_chan->desc_lock);
- desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
- spin_lock_bh(&ioat_chan->desc_lock);
- /* will this ever happen? */
- BUG_ON(!desc);
- }
-
- desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
- desc->hw->next = 0;
- desc->async_tx.ack = 1;
-
- list_add_tail(&desc->node, &ioat_chan->used_desc);
- spin_unlock_bh(&ioat_chan->desc_lock);
-
- writel(((u64) desc->async_tx.phys) & 0x00000000FFFFFFFF,
- ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_LOW);
- writel(((u64) desc->async_tx.phys) >> 32,
- ioat_chan->reg_base + IOAT_CHAINADDR_OFFSET_HIGH);
-
- writeb(IOAT_CHANCMD_START, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
-}
-
-/*
- * Perform a IOAT transaction to verify the HW works.
- */
-#define IOAT_TEST_SIZE 2000
-
-static int ioat_self_test(struct ioat_device *device)
-{
- int i;
- u8 *src;
- u8 *dest;
- struct dma_chan *dma_chan;
- struct dma_async_tx_descriptor *tx;
- dma_addr_t addr;
- dma_cookie_t cookie;
- int err = 0;
-
- src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
- if (!src)
- return -ENOMEM;
- dest = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
- if (!dest) {
- kfree(src);
- return -ENOMEM;
- }
-
- /* Fill in src buffer */
- for (i = 0; i < IOAT_TEST_SIZE; i++)
- src[i] = (u8)i;
-
- /* Start copy, using first DMA channel */
- dma_chan = container_of(device->common.channels.next,
- struct dma_chan,
- device_node);
- if (ioat_dma_alloc_chan_resources(dma_chan) < 1) {
- err = -ENODEV;
- goto out;
- }
-
- tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0);
- async_tx_ack(tx);
- addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE,
- DMA_TO_DEVICE);
- ioat_set_src(addr, tx, 0);
- addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
- DMA_FROM_DEVICE);
- ioat_set_dest(addr, tx, 0);
- cookie = ioat_tx_submit(tx);
- ioat_dma_memcpy_issue_pending(dma_chan);
- msleep(1);
-
- if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
- printk(KERN_ERR "ioatdma: Self-test copy timed out, disabling\n");
- err = -ENODEV;
- goto free_resources;
- }
- if (memcmp(src, dest, IOAT_TEST_SIZE)) {
- printk(KERN_ERR "ioatdma: Self-test copy failed compare, disabling\n");
- err = -ENODEV;
- goto free_resources;
- }
-
-free_resources:
- ioat_dma_free_chan_resources(dma_chan);
-out:
- kfree(src);
- kfree(dest);
- return err;
-}
-
-static int __devinit ioat_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int err;
- unsigned long mmio_start, mmio_len;
- void __iomem *reg_base;
- struct ioat_device *device;
-
- err = pci_enable_device(pdev);
- if (err)
- goto err_enable_device;
-
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
- if (err)
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (err)
- goto err_set_dma_mask;
-
- err = pci_request_regions(pdev, ioat_pci_driver.name);
- if (err)
- goto err_request_regions;
-
- mmio_start = pci_resource_start(pdev, 0);
- mmio_len = pci_resource_len(pdev, 0);
-
- reg_base = ioremap(mmio_start, mmio_len);
- if (!reg_base) {
- err = -ENOMEM;
- goto err_ioremap;
- }
-
- device = kzalloc(sizeof(*device), GFP_KERNEL);
- if (!device) {
- err = -ENOMEM;
- goto err_kzalloc;
- }
-
- /* DMA coherent memory pool for DMA descriptor allocations */
- device->dma_pool = pci_pool_create("dma_desc_pool", pdev,
- sizeof(struct ioat_dma_descriptor), 64, 0);
- if (!device->dma_pool) {
- err = -ENOMEM;
- goto err_dma_pool;
- }
-
- device->completion_pool = pci_pool_create("completion_pool", pdev, sizeof(u64), SMP_CACHE_BYTES, SMP_CACHE_BYTES);
- if (!device->completion_pool) {
- err = -ENOMEM;
- goto err_completion_pool;
- }
-
- device->pdev = pdev;
- pci_set_drvdata(pdev, device);
-#ifdef CONFIG_PCI_MSI
- if (pci_enable_msi(pdev) == 0) {
- device->msi = 1;
- } else {
- device->msi = 0;
- }
-#endif
- err = request_irq(pdev->irq, &ioat_do_interrupt, IRQF_SHARED, "ioat",
- device);
- if (err)
- goto err_irq;
-
- device->reg_base = reg_base;
-
- writeb(IOAT_INTRCTRL_MASTER_INT_EN, device->reg_base + IOAT_INTRCTRL_OFFSET);
- pci_set_master(pdev);
-
- INIT_LIST_HEAD(&device->common.channels);
- enumerate_dma_channels(device);
-
- dma_cap_set(DMA_MEMCPY, device->common.cap_mask);
- device->common.device_alloc_chan_resources = ioat_dma_alloc_chan_resources;
- device->common.device_free_chan_resources = ioat_dma_free_chan_resources;
- device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy;
- device->common.device_is_tx_complete = ioat_dma_is_complete;
- device->common.device_issue_pending = ioat_dma_memcpy_issue_pending;
- device->common.device_dependency_added = ioat_dma_dependency_added;
- device->common.dev = &pdev->dev;
- printk(KERN_INFO "Intel(R) I/OAT DMA Engine found, %d channels\n",
- device->common.chancnt);
-
- err = ioat_self_test(device);
- if (err)
- goto err_self_test;
-
- dma_async_device_register(&device->common);
-
- return 0;
-
-err_self_test:
-err_irq:
- pci_pool_destroy(device->completion_pool);
-err_completion_pool:
- pci_pool_destroy(device->dma_pool);
-err_dma_pool:
- kfree(device);
-err_kzalloc:
- iounmap(reg_base);
-err_ioremap:
- pci_release_regions(pdev);
-err_request_regions:
-err_set_dma_mask:
- pci_disable_device(pdev);
-err_enable_device:
-
- printk(KERN_ERR "Intel(R) I/OAT DMA Engine initialization failed\n");
-
- return err;
-}
-
-static void ioat_shutdown(struct pci_dev *pdev)
-{
- struct ioat_device *device;
- device = pci_get_drvdata(pdev);
-
- dma_async_device_unregister(&device->common);
-}
-
-static void __devexit ioat_remove(struct pci_dev *pdev)
-{
- struct ioat_device *device;
- struct dma_chan *chan, *_chan;
- struct ioat_dma_chan *ioat_chan;
-
- device = pci_get_drvdata(pdev);
- dma_async_device_unregister(&device->common);
-
- free_irq(device->pdev->irq, device);
-#ifdef CONFIG_PCI_MSI
- if (device->msi)
- pci_disable_msi(device->pdev);
-#endif
- pci_pool_destroy(device->dma_pool);
- pci_pool_destroy(device->completion_pool);
- iounmap(device->reg_base);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- list_for_each_entry_safe(chan, _chan, &device->common.channels, device_node) {
- ioat_chan = to_ioat_chan(chan);
- list_del(&chan->device_node);
- kfree(ioat_chan);
- }
- kfree(device);
-}
-
-/* MODULE API */
-MODULE_VERSION("1.9");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Intel Corporation");
-
-static int __init ioat_init_module(void)
-{
- /* it's currently unsafe to unload this module */
- /* if forced, worst case is that rmmod hangs */
- __unsafe(THIS_MODULE);
-
- return pci_register_driver(&ioat_pci_driver);
-}
-
-module_init(ioat_init_module);
-
-static void __exit ioat_exit_module(void)
-{
- pci_unregister_driver(&ioat_pci_driver);
-}
-
-module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index bf4dad70e0f..5f9881e7b0e 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -28,25 +28,37 @@
#include <linux/cache.h>
#include <linux/pci_ids.h>
+#define IOAT_DMA_VERSION "1.26"
+
+enum ioat_interrupt {
+ none = 0,
+ msix_multi_vector = 1,
+ msix_single_vector = 2,
+ msi = 3,
+ intx = 4,
+};
+
#define IOAT_LOW_COMPLETION_MASK 0xffffffc0
/**
- * struct ioat_device - internal representation of a IOAT device
+ * struct ioatdma_device - internal representation of a IOAT device
* @pdev: PCI-Express device
* @reg_base: MMIO register space base address
* @dma_pool: for allocating DMA descriptors
* @common: embedded struct dma_device
- * @msi: Message Signaled Interrupt number
+ * @version: version of ioatdma device
*/
-struct ioat_device {
+struct ioatdma_device {
struct pci_dev *pdev;
void __iomem *reg_base;
struct pci_pool *dma_pool;
struct pci_pool *completion_pool;
-
struct dma_device common;
- u8 msi;
+ u8 version;
+ enum ioat_interrupt irq_mode;
+ struct msix_entry msix_entries[4];
+ struct ioat_dma_chan *idx[4];
};
/**
@@ -84,7 +96,7 @@ struct ioat_dma_chan {
int pending;
- struct ioat_device *device;
+ struct ioatdma_device *device;
struct dma_chan common;
dma_addr_t completion_addr;
@@ -95,6 +107,7 @@ struct ioat_dma_chan {
u32 high;
};
} *completion_virt;
+ struct tasklet_struct cleanup_task;
};
/* wrapper around hardware descriptor format + additional software fields */
@@ -111,10 +124,22 @@ struct ioat_desc_sw {
struct ioat_dma_descriptor *hw;
struct list_head node;
int tx_cnt;
- DECLARE_PCI_UNMAP_LEN(len)
- DECLARE_PCI_UNMAP_ADDR(src)
- DECLARE_PCI_UNMAP_ADDR(dst)
+ size_t len;
+ dma_addr_t src;
+ dma_addr_t dst;
struct dma_async_tx_descriptor async_tx;
};
+#if defined(CONFIG_INTEL_IOATDMA) || defined(CONFIG_INTEL_IOATDMA_MODULE)
+struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
+ void __iomem *iobase);
+void ioat_dma_remove(struct ioatdma_device *device);
+struct dca_provider *ioat_dca_init(struct pci_dev *pdev,
+ void __iomem *iobase);
+#else
+#define ioat_dma_probe(pdev, iobase) NULL
+#define ioat_dma_remove(device) do { } while (0)
+#define ioat_dca_init(pdev, iobase) NULL
+#endif
+
#endif /* IOATDMA_H */
diff --git a/drivers/dma/ioatdma_hw.h b/drivers/dma/ioatdma_hw.h
index 4d7a12880be..9e7434e1551 100644
--- a/drivers/dma/ioatdma_hw.h
+++ b/drivers/dma/ioatdma_hw.h
@@ -27,7 +27,7 @@
#define IOAT_PCI_RID 0x00
#define IOAT_PCI_SVID 0x8086
#define IOAT_PCI_SID 0x8086
-#define IOAT_VER 0x12 /* Version 1.2 */
+#define IOAT_VER_1_2 0x12 /* Version 1.2 */
struct ioat_dma_descriptor {
uint32_t size;
diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h
index a30c7349075..baaab5ea146 100644
--- a/drivers/dma/ioatdma_registers.h
+++ b/drivers/dma/ioatdma_registers.h
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved.
+ * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
*
* 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
@@ -21,6 +21,9 @@
#ifndef _IOAT_REGISTERS_H_
#define _IOAT_REGISTERS_H_
+#define IOAT_PCI_DMACTRL_OFFSET 0x48
+#define IOAT_PCI_DMACTRL_DMA_EN 0x00000001
+#define IOAT_PCI_DMACTRL_MSI_EN 0x00000002
/* MMIO Device Registers */
#define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */
@@ -39,6 +42,7 @@
#define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */
#define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */
#define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */
+#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL 0x08 /* Enable all MSI-X vectors */
#define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 5a1d426744d..e5c62b75f36 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -1446,21 +1446,20 @@ static struct platform_driver iop_adma_driver = {
static int __init iop_adma_init (void)
{
- /* it's currently unsafe to unload this module */
- /* if forced, worst case is that rmmod hangs */
- __unsafe(THIS_MODULE);
-
return platform_driver_register(&iop_adma_driver);
}
+/* it's currently unsafe to unload this module */
+#if 0
static void __exit iop_adma_exit (void)
{
platform_driver_unregister(&iop_adma_driver);
return;
}
+module_exit(iop_adma_exit);
+#endif
module_init(iop_adma_init);
-module_exit(iop_adma_exit);
MODULE_AUTHOR("Intel Corporation");
MODULE_DESCRIPTION("IOP ADMA Engine Driver");
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 06471302200..60f1a8924a9 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -25,11 +25,14 @@
#include <linux/device.h>
#include <linux/vmalloc.h>
#include <linux/poll.h>
+#include <linux/preempt.h>
+#include <linux/time.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/idr.h>
#include <linux/compat.h>
#include <linux/firewire-cdev.h>
+#include <asm/system.h>
#include <asm/uaccess.h>
#include "fw-transaction.h"
#include "fw-topology.h"
@@ -140,11 +143,10 @@ static void queue_event(struct client *client, struct event *event,
event->v[1].size = size1;
spin_lock_irqsave(&client->lock, flags);
-
list_add_tail(&event->link, &client->event_list);
- wake_up_interruptible(&client->wait);
-
spin_unlock_irqrestore(&client->lock, flags);
+
+ wake_up_interruptible(&client->wait);
}
static int
@@ -621,20 +623,19 @@ iso_callback(struct fw_iso_context *context, u32 cycle,
size_t header_length, void *header, void *data)
{
struct client *client = data;
- struct iso_interrupt *interrupt;
+ struct iso_interrupt *irq;
- interrupt = kzalloc(sizeof(*interrupt) + header_length, GFP_ATOMIC);
- if (interrupt == NULL)
+ irq = kzalloc(sizeof(*irq) + header_length, GFP_ATOMIC);
+ if (irq == NULL)
return;
- interrupt->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
- interrupt->interrupt.closure = client->iso_closure;
- interrupt->interrupt.cycle = cycle;
- interrupt->interrupt.header_length = header_length;
- memcpy(interrupt->interrupt.header, header, header_length);
- queue_event(client, &interrupt->event,
- &interrupt->interrupt,
- sizeof(interrupt->interrupt) + header_length, NULL, 0);
+ irq->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
+ irq->interrupt.closure = client->iso_closure;
+ irq->interrupt.cycle = cycle;
+ irq->interrupt.header_length = header_length;
+ memcpy(irq->interrupt.header, header, header_length);
+ queue_event(client, &irq->event, &irq->interrupt,
+ sizeof(irq->interrupt) + header_length, NULL, 0);
}
static int ioctl_create_iso_context(struct client *client, void *buffer)
@@ -812,6 +813,28 @@ static int ioctl_stop_iso(struct client *client, void *buffer)
return fw_iso_context_stop(client->iso_context);
}
+static int ioctl_get_cycle_timer(struct client *client, void *buffer)
+{
+ struct fw_cdev_get_cycle_timer *request = buffer;
+ struct fw_card *card = client->device->card;
+ unsigned long long bus_time;
+ struct timeval tv;
+ unsigned long flags;
+
+ preempt_disable();
+ local_irq_save(flags);
+
+ bus_time = card->driver->get_bus_time(card);
+ do_gettimeofday(&tv);
+
+ local_irq_restore(flags);
+ preempt_enable();
+
+ request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
+ request->cycle_timer = bus_time & 0xffffffff;
+ return 0;
+}
+
static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_get_info,
ioctl_send_request,
@@ -825,6 +848,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_queue_iso,
ioctl_start_iso,
ioctl_stop_iso,
+ ioctl_get_cycle_timer,
};
static int
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index d13e6a69707..894d4a92a18 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -102,11 +102,6 @@ fw_unit(struct device *dev)
#define CSR_INSTANCE 0x18
#define CSR_DIRECTORY_ID 0x20
-#define SBP2_COMMAND_SET_SPECIFIER 0x38
-#define SBP2_COMMAND_SET 0x39
-#define SBP2_COMMAND_SET_REVISION 0x3b
-#define SBP2_FIRMWARE_REVISION 0x3c
-
struct fw_csr_iterator {
u32 *p;
u32 *end;
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index e14c1ca7813..2f307c4df33 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -18,21 +18,23 @@
* 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/interrupt.h>
-#include <linux/pci.h>
+#include <linux/compiler.h>
#include <linux/delay.h>
-#include <linux/poll.h>
#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
-#include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <asm/page.h>
+#include <asm/system.h>
-#include "fw-transaction.h"
#include "fw-ohci.h"
+#include "fw-transaction.h"
#define DESCRIPTOR_OUTPUT_MORE 0
#define DESCRIPTOR_OUTPUT_LAST (1 << 12)
@@ -678,6 +680,9 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
/* FIXME: Document how the locking works. */
if (ohci->generation != packet->generation) {
+ if (packet->payload_length > 0)
+ dma_unmap_single(ohci->card.device, payload_bus,
+ packet->payload_length, DMA_TO_DEVICE);
packet->ack = RCODE_GENERATION;
return -1;
}
@@ -912,10 +917,15 @@ static void bus_reset_tasklet(unsigned long data)
reg = reg_read(ohci, OHCI1394_NodeID);
if (!(reg & OHCI1394_NodeID_idValid)) {
- fw_error("node ID not valid, new bus reset in progress\n");
+ fw_notify("node ID not valid, new bus reset in progress\n");
return;
}
- ohci->node_id = reg & 0xffff;
+ if ((reg & OHCI1394_NodeID_nodeNumber) == 63) {
+ fw_notify("malconfigured bus\n");
+ return;
+ }
+ ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
+ OHCI1394_NodeID_nodeNumber);
/*
* The count in the SelfIDCount register is the number of
@@ -926,12 +936,14 @@ static void bus_reset_tasklet(unsigned long data)
self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff;
generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff;
+ rmb();
for (i = 1, j = 0; j < self_id_count; i += 2, j++) {
if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1])
fw_error("inconsistent self IDs\n");
ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]);
}
+ rmb();
/*
* Check the consistency of the self IDs we just read. The
@@ -1046,6 +1058,9 @@ static irqreturn_t irq_handler(int irq, void *data)
iso_event &= ~(1 << i);
}
+ if (unlikely(event & OHCI1394_postedWriteErr))
+ fw_error("PCI posted write error\n");
+
if (event & OHCI1394_cycle64Seconds) {
cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
if ((cycle_time & 0x80000000) == 0)
@@ -1119,8 +1134,8 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
OHCI1394_RQPkt | OHCI1394_RSPkt |
OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
OHCI1394_isochRx | OHCI1394_isochTx |
- OHCI1394_masterIntEnable |
- OHCI1394_cycle64Seconds);
+ OHCI1394_postedWriteErr | OHCI1394_cycle64Seconds |
+ OHCI1394_masterIntEnable);
/* Activate link_on bit and contender bit in our self ID packets.*/
if (ohci_update_phy_reg(card, 4, 0,
diff --git a/drivers/firewire/fw-ohci.h b/drivers/firewire/fw-ohci.h
index fa15706397d..dec4f04e6b2 100644
--- a/drivers/firewire/fw-ohci.h
+++ b/drivers/firewire/fw-ohci.h
@@ -59,6 +59,8 @@
#define OHCI1394_LinkControl_cycleSource (1 << 22)
#define OHCI1394_NodeID 0x0E8
#define OHCI1394_NodeID_idValid 0x80000000
+#define OHCI1394_NodeID_nodeNumber 0x0000003f
+#define OHCI1394_NodeID_busNumber 0x0000ffc0
#define OHCI1394_PhyControl 0x0EC
#define OHCI1394_PhyControl_Read(addr) (((addr) << 8) | 0x00008000)
#define OHCI1394_PhyControl_ReadDone 0x80000000
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 238730f75db..5596df65c8e 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -37,11 +37,12 @@
#include <linux/dma-mapping.h>
#include <linux/blkdev.h>
#include <linux/string.h>
+#include <linux/stringify.h>
#include <linux/timer.h>
+#include <linux/workqueue.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
@@ -61,36 +62,94 @@ module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644);
MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
"(default = Y, use N for concurrent initiators)");
+/*
+ * Flags for firmware oddities
+ *
+ * - 128kB max transfer
+ * Limit transfer size. Necessary for some old bridges.
+ *
+ * - 36 byte inquiry
+ * When scsi_mod probes the device, let the inquiry command look like that
+ * from MS Windows.
+ *
+ * - skip mode page 8
+ * Suppress sending of mode_sense for mode page 8 if the device pretends to
+ * support the SCSI Primary Block commands instead of Reduced Block Commands.
+ *
+ * - fix capacity
+ * Tell sd_mod to correct the last sector number reported by read_capacity.
+ * Avoids access beyond actual disk limits on devices with an off-by-one bug.
+ * Don't use this with devices which don't have this bug.
+ *
+ * - override internal blacklist
+ * Instead of adding to the built-in blacklist, use only the workarounds
+ * specified in the module load parameter.
+ * Useful if a blacklist entry interfered with a non-broken device.
+ */
+#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
+#define SBP2_WORKAROUND_INQUIRY_36 0x2
+#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
+#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
+#define SBP2_WORKAROUND_OVERRIDE 0x100
+
+static int sbp2_param_workarounds;
+module_param_named(workarounds, sbp2_param_workarounds, int, 0644);
+MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0"
+ ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS)
+ ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36)
+ ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8)
+ ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY)
+ ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
+ ", or a combination)");
+
/* I don't know why the SCSI stack doesn't define something like this... */
typedef void (*scsi_done_fn_t)(struct scsi_cmnd *);
static const char sbp2_driver_name[] = "sbp2";
-struct sbp2_device {
- struct kref kref;
- struct fw_unit *unit;
+/*
+ * We create one struct sbp2_logical_unit per SBP-2 Logical Unit Number Entry
+ * and one struct scsi_device per sbp2_logical_unit.
+ */
+struct sbp2_logical_unit {
+ struct sbp2_target *tgt;
+ struct list_head link;
+ struct scsi_device *sdev;
struct fw_address_handler address_handler;
struct list_head orb_list;
- u64 management_agent_address;
+
u64 command_block_agent_address;
- u32 workarounds;
+ u16 lun;
int login_id;
/*
- * We cache these addresses and only update them once we've
- * logged in or reconnected to the sbp2 device. That way, any
- * IO to the device will automatically fail and get retried if
- * it happens in a window where the device is not ready to
- * handle it (e.g. after a bus reset but before we reconnect).
+ * The generation is updated once we've logged in or reconnected
+ * to the logical unit. Thus, I/O to the device will automatically
+ * fail and get retried if it happens in a window where the device
+ * is not ready, e.g. after a bus reset but before we reconnect.
*/
- int node_id;
- int address_high;
int generation;
-
int retries;
struct delayed_work work;
};
+/*
+ * We create one struct sbp2_target per IEEE 1212 Unit Directory
+ * and one struct Scsi_Host per sbp2_target.
+ */
+struct sbp2_target {
+ struct kref kref;
+ struct fw_unit *unit;
+
+ u64 management_agent_address;
+ int directory_id;
+ int node_id;
+ int address_high;
+
+ unsigned workarounds;
+ struct list_head lu_list;
+};
+
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
@@ -101,17 +160,9 @@ struct sbp2_device {
#define SBP2_DIRECTION_FROM_MEDIA 0x1
/* Unit directory keys */
-#define SBP2_COMMAND_SET_SPECIFIER 0x38
-#define SBP2_COMMAND_SET 0x39
-#define SBP2_COMMAND_SET_REVISION 0x3b
-#define SBP2_FIRMWARE_REVISION 0x3c
-
-/* Flags for detected oddities and brokeness */
-#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1
-#define SBP2_WORKAROUND_INQUIRY_36 0x2
-#define SBP2_WORKAROUND_MODE_SENSE_8 0x4
-#define SBP2_WORKAROUND_FIX_CAPACITY 0x8
-#define SBP2_WORKAROUND_OVERRIDE 0x100
+#define SBP2_CSR_FIRMWARE_REVISION 0x3c
+#define SBP2_CSR_LOGICAL_UNIT_NUMBER 0x14
+#define SBP2_CSR_LOGICAL_UNIT_DIRECTORY 0xd4
/* Management orb opcodes */
#define SBP2_LOGIN_REQUEST 0x0
@@ -219,7 +270,7 @@ struct sbp2_command_orb {
} request;
struct scsi_cmnd *cmd;
scsi_done_fn_t done;
- struct fw_unit *unit;
+ struct sbp2_logical_unit *lu;
struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8)));
dma_addr_t page_table_bus;
@@ -295,7 +346,7 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
unsigned long long offset,
void *payload, size_t length, void *callback_data)
{
- struct sbp2_device *sd = callback_data;
+ struct sbp2_logical_unit *lu = callback_data;
struct sbp2_orb *orb;
struct sbp2_status status;
size_t header_size;
@@ -319,7 +370,7 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
/* Lookup the orb corresponding to this status write. */
spin_lock_irqsave(&card->lock, flags);
- list_for_each_entry(orb, &sd->orb_list, link) {
+ list_for_each_entry(orb, &lu->orb_list, link) {
if (STATUS_GET_ORB_HIGH(status) == 0 &&
STATUS_GET_ORB_LOW(status) == orb->request_bus) {
orb->rcode = RCODE_COMPLETE;
@@ -329,7 +380,7 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
}
spin_unlock_irqrestore(&card->lock, flags);
- if (&orb->link != &sd->orb_list)
+ if (&orb->link != &lu->orb_list)
orb->callback(orb, &status);
else
fw_error("status write for unknown orb\n");
@@ -361,20 +412,20 @@ complete_transaction(struct fw_card *card, int rcode,
orb->rcode = rcode;
if (orb->rcode != RCODE_COMPLETE) {
list_del(&orb->link);
+ spin_unlock_irqrestore(&card->lock, flags);
orb->callback(orb, NULL);
+ } else {
+ spin_unlock_irqrestore(&card->lock, flags);
}
- spin_unlock_irqrestore(&card->lock, flags);
-
kref_put(&orb->kref, free_orb);
}
static void
-sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
+sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
int node_id, int generation, u64 offset)
{
- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_device *sd = unit->device.driver_data;
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
unsigned long flags;
orb->pointer.high = 0;
@@ -382,7 +433,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer));
spin_lock_irqsave(&device->card->lock, flags);
- list_add_tail(&orb->link, &sd->orb_list);
+ list_add_tail(&orb->link, &lu->orb_list);
spin_unlock_irqrestore(&device->card->lock, flags);
/* Take a ref for the orb list and for the transaction callback. */
@@ -395,10 +446,9 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
complete_transaction, orb);
}
-static int sbp2_cancel_orbs(struct fw_unit *unit)
+static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
{
- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_device *sd = unit->device.driver_data;
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_orb *orb, *next;
struct list_head list;
unsigned long flags;
@@ -406,7 +456,7 @@ static int sbp2_cancel_orbs(struct fw_unit *unit)
INIT_LIST_HEAD(&list);
spin_lock_irqsave(&device->card->lock, flags);
- list_splice_init(&sd->orb_list, &list);
+ list_splice_init(&lu->orb_list, &list);
spin_unlock_irqrestore(&device->card->lock, flags);
list_for_each_entry_safe(orb, next, &list, link) {
@@ -433,11 +483,11 @@ complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
}
static int
-sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
- int function, int lun, void *response)
+sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ int generation, int function, int lun_or_login_id,
+ void *response)
{
- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_device *sd = unit->device.driver_data;
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_management_orb *orb;
int retval = -ENOMEM;
@@ -458,12 +508,12 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
orb->request.misc =
MANAGEMENT_ORB_NOTIFY |
MANAGEMENT_ORB_FUNCTION(function) |
- MANAGEMENT_ORB_LUN(lun);
+ MANAGEMENT_ORB_LUN(lun_or_login_id);
orb->request.length =
MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response));
- orb->request.status_fifo.high = sd->address_handler.offset >> 32;
- orb->request.status_fifo.low = sd->address_handler.offset;
+ orb->request.status_fifo.high = lu->address_handler.offset >> 32;
+ orb->request.status_fifo.low = lu->address_handler.offset;
if (function == SBP2_LOGIN_REQUEST) {
orb->request.misc |=
@@ -482,14 +532,14 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
if (dma_mapping_error(orb->base.request_bus))
goto fail_mapping_request;
- sbp2_send_orb(&orb->base, unit,
- node_id, generation, sd->management_agent_address);
+ sbp2_send_orb(&orb->base, lu, node_id, generation,
+ lu->tgt->management_agent_address);
wait_for_completion_timeout(&orb->done,
msecs_to_jiffies(SBP2_ORB_TIMEOUT));
retval = -EIO;
- if (sbp2_cancel_orbs(unit) == 0) {
+ if (sbp2_cancel_orbs(lu) == 0) {
fw_error("orb reply timed out, rcode=0x%02x\n",
orb->base.rcode);
goto out;
@@ -534,10 +584,9 @@ complete_agent_reset_write(struct fw_card *card, int rcode,
kfree(t);
}
-static int sbp2_agent_reset(struct fw_unit *unit)
+static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
{
- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_device *sd = unit->device.driver_data;
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_transaction *t;
static u32 zero;
@@ -546,181 +595,272 @@ static int sbp2_agent_reset(struct fw_unit *unit)
return -ENOMEM;
fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
- sd->node_id, sd->generation, device->max_speed,
- sd->command_block_agent_address + SBP2_AGENT_RESET,
+ lu->tgt->node_id, lu->generation, device->max_speed,
+ lu->command_block_agent_address + SBP2_AGENT_RESET,
&zero, sizeof(zero), complete_agent_reset_write, t);
return 0;
}
-static void sbp2_reconnect(struct work_struct *work);
-static struct scsi_host_template scsi_driver_template;
-
-static void release_sbp2_device(struct kref *kref)
+static void sbp2_release_target(struct kref *kref)
{
- struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref);
- struct Scsi_Host *host =
- container_of((void *)sd, struct Scsi_Host, hostdata[0]);
-
- scsi_remove_host(host);
- sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation,
- SBP2_LOGOUT_REQUEST, sd->login_id, NULL);
- fw_core_remove_address_handler(&sd->address_handler);
- fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id);
- put_device(&sd->unit->device);
- scsi_host_put(host);
+ struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref);
+ struct sbp2_logical_unit *lu, *next;
+ struct Scsi_Host *shost =
+ container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+
+ list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
+ if (lu->sdev)
+ scsi_remove_device(lu->sdev);
+
+ sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+ fw_core_remove_address_handler(&lu->address_handler);
+ list_del(&lu->link);
+ kfree(lu);
+ }
+ scsi_remove_host(shost);
+ fw_notify("released %s\n", tgt->unit->device.bus_id);
+
+ put_device(&tgt->unit->device);
+ scsi_host_put(shost);
}
+static struct workqueue_struct *sbp2_wq;
+
+static void sbp2_reconnect(struct work_struct *work);
+
static void sbp2_login(struct work_struct *work)
{
- struct sbp2_device *sd =
- container_of(work, struct sbp2_device, work.work);
- struct Scsi_Host *host =
- container_of((void *)sd, struct Scsi_Host, hostdata[0]);
- struct fw_unit *unit = sd->unit;
+ struct sbp2_logical_unit *lu =
+ container_of(work, struct sbp2_logical_unit, work.work);
+ struct Scsi_Host *shost =
+ container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
+ struct scsi_device *sdev;
+ struct scsi_lun eight_bytes_lun;
+ struct fw_unit *unit = lu->tgt->unit;
struct fw_device *device = fw_device(unit->device.parent);
struct sbp2_login_response response;
- int generation, node_id, local_node_id, lun, retval;
-
- /* FIXME: Make this work for multi-lun devices. */
- lun = 0;
+ int generation, node_id, local_node_id;
generation = device->card->generation;
node_id = device->node->node_id;
local_node_id = device->card->local_node->node_id;
- if (sbp2_send_management_orb(unit, node_id, generation,
- SBP2_LOGIN_REQUEST, lun, &response) < 0) {
- if (sd->retries++ < 5) {
- schedule_delayed_work(&sd->work, DIV_ROUND_UP(HZ, 5));
+ if (sbp2_send_management_orb(lu, node_id, generation,
+ SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
+ if (lu->retries++ < 5) {
+ queue_delayed_work(sbp2_wq, &lu->work,
+ DIV_ROUND_UP(HZ, 5));
} else {
- fw_error("failed to login to %s\n",
- unit->device.bus_id);
- kref_put(&sd->kref, release_sbp2_device);
+ fw_error("failed to login to %s LUN %04x\n",
+ unit->device.bus_id, lu->lun);
+ kref_put(&lu->tgt->kref, sbp2_release_target);
}
return;
}
- sd->generation = generation;
- sd->node_id = node_id;
- sd->address_high = local_node_id << 16;
+ lu->generation = generation;
+ lu->tgt->node_id = node_id;
+ lu->tgt->address_high = local_node_id << 16;
/* Get command block agent offset and login id. */
- sd->command_block_agent_address =
+ lu->command_block_agent_address =
((u64) (response.command_block_agent.high & 0xffff) << 32) |
response.command_block_agent.low;
- sd->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
+ lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
- fw_notify("logged in to sbp2 unit %s (%d retries)\n",
- unit->device.bus_id, sd->retries);
- fw_notify(" - management_agent_address: 0x%012llx\n",
- (unsigned long long) sd->management_agent_address);
- fw_notify(" - command_block_agent_address: 0x%012llx\n",
- (unsigned long long) sd->command_block_agent_address);
- fw_notify(" - status write address: 0x%012llx\n",
- (unsigned long long) sd->address_handler.offset);
+ fw_notify("logged in to %s LUN %04x (%d retries)\n",
+ unit->device.bus_id, lu->lun, lu->retries);
#if 0
/* FIXME: The linux1394 sbp2 does this last step. */
sbp2_set_busy_timeout(scsi_id);
#endif
- PREPARE_DELAYED_WORK(&sd->work, sbp2_reconnect);
- sbp2_agent_reset(unit);
+ PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
+ sbp2_agent_reset(lu);
+
+ memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
+ eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
+ eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
- /* FIXME: Loop over luns here. */
- lun = 0;
- retval = scsi_add_device(host, 0, 0, lun);
- if (retval < 0) {
- sbp2_send_management_orb(unit, sd->node_id, sd->generation,
- SBP2_LOGOUT_REQUEST, sd->login_id,
- NULL);
+ sdev = __scsi_add_device(shost, 0, 0,
+ scsilun_to_int(&eight_bytes_lun), lu);
+ if (IS_ERR(sdev)) {
+ sbp2_send_management_orb(lu, node_id, generation,
+ SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
/*
* Set this back to sbp2_login so we fall back and
* retry login on bus reset.
*/
- PREPARE_DELAYED_WORK(&sd->work, sbp2_login);
+ PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
+ } else {
+ lu->sdev = sdev;
+ scsi_device_put(sdev);
}
- kref_put(&sd->kref, release_sbp2_device);
+ kref_put(&lu->tgt->kref, sbp2_release_target);
}
-static int sbp2_probe(struct device *dev)
+static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
{
- struct fw_unit *unit = fw_unit(dev);
- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_device *sd;
- struct fw_csr_iterator ci;
- struct Scsi_Host *host;
- int i, key, value, err;
- u32 model, firmware_revision;
+ struct sbp2_logical_unit *lu;
- err = -ENOMEM;
- host = scsi_host_alloc(&scsi_driver_template, sizeof(*sd));
- if (host == NULL)
- goto fail;
+ lu = kmalloc(sizeof(*lu), GFP_KERNEL);
+ if (!lu)
+ return -ENOMEM;
- sd = (struct sbp2_device *) host->hostdata;
- unit->device.driver_data = sd;
- sd->unit = unit;
- INIT_LIST_HEAD(&sd->orb_list);
- kref_init(&sd->kref);
+ lu->address_handler.length = 0x100;
+ lu->address_handler.address_callback = sbp2_status_write;
+ lu->address_handler.callback_data = lu;
- sd->address_handler.length = 0x100;
- sd->address_handler.address_callback = sbp2_status_write;
- sd->address_handler.callback_data = sd;
+ if (fw_core_add_address_handler(&lu->address_handler,
+ &fw_high_memory_region) < 0) {
+ kfree(lu);
+ return -ENOMEM;
+ }
- err = fw_core_add_address_handler(&sd->address_handler,
- &fw_high_memory_region);
- if (err < 0)
- goto fail_host;
+ lu->tgt = tgt;
+ lu->sdev = NULL;
+ lu->lun = lun_entry & 0xffff;
+ lu->retries = 0;
+ INIT_LIST_HEAD(&lu->orb_list);
+ INIT_DELAYED_WORK(&lu->work, sbp2_login);
- err = fw_device_enable_phys_dma(device);
- if (err < 0)
- goto fail_address_handler;
+ list_add_tail(&lu->link, &tgt->lu_list);
+ return 0;
+}
- err = scsi_add_host(host, &unit->device);
- if (err < 0)
- goto fail_address_handler;
+static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory)
+{
+ struct fw_csr_iterator ci;
+ int key, value;
- /*
- * Scan unit directory to get management agent address,
- * firmware revison and model. Initialize firmware_revision
- * and model to values that wont match anything in our table.
- */
- firmware_revision = 0xff000000;
- model = 0xff000000;
- fw_csr_iterator_init(&ci, unit->directory);
+ fw_csr_iterator_init(&ci, directory);
+ while (fw_csr_iterator_next(&ci, &key, &value))
+ if (key == SBP2_CSR_LOGICAL_UNIT_NUMBER &&
+ sbp2_add_logical_unit(tgt, value) < 0)
+ return -ENOMEM;
+ return 0;
+}
+
+static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
+ u32 *model, u32 *firmware_revision)
+{
+ struct fw_csr_iterator ci;
+ int key, value;
+
+ fw_csr_iterator_init(&ci, directory);
while (fw_csr_iterator_next(&ci, &key, &value)) {
switch (key) {
+
case CSR_DEPENDENT_INFO | CSR_OFFSET:
- sd->management_agent_address =
- 0xfffff0000000ULL + 4 * value;
+ tgt->management_agent_address =
+ CSR_REGISTER_BASE + 4 * value;
break;
- case SBP2_FIRMWARE_REVISION:
- firmware_revision = value;
+
+ case CSR_DIRECTORY_ID:
+ tgt->directory_id = value;
break;
+
case CSR_MODEL:
- model = value;
+ *model = value;
+ break;
+
+ case SBP2_CSR_FIRMWARE_REVISION:
+ *firmware_revision = value;
+ break;
+
+ case SBP2_CSR_LOGICAL_UNIT_NUMBER:
+ if (sbp2_add_logical_unit(tgt, value) < 0)
+ return -ENOMEM;
+ break;
+
+ case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
+ if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0)
+ return -ENOMEM;
break;
}
}
+ return 0;
+}
+
+static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
+ u32 firmware_revision)
+{
+ int i;
+ unsigned w = sbp2_param_workarounds;
+
+ if (w)
+ fw_notify("Please notify linux1394-devel@lists.sourceforge.net "
+ "if you need the workarounds parameter for %s\n",
+ tgt->unit->device.bus_id);
+
+ if (w & SBP2_WORKAROUND_OVERRIDE)
+ goto out;
for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) {
+
if (sbp2_workarounds_table[i].firmware_revision !=
(firmware_revision & 0xffffff00))
continue;
+
if (sbp2_workarounds_table[i].model != model &&
sbp2_workarounds_table[i].model != ~0)
continue;
- sd->workarounds |= sbp2_workarounds_table[i].workarounds;
+
+ w |= sbp2_workarounds_table[i].workarounds;
break;
}
-
- if (sd->workarounds)
- fw_notify("Workarounds for node %s: 0x%x "
+ out:
+ if (w)
+ fw_notify("Workarounds for %s: 0x%x "
"(firmware_revision 0x%06x, model_id 0x%06x)\n",
- unit->device.bus_id,
- sd->workarounds, firmware_revision, model);
+ tgt->unit->device.bus_id,
+ w, firmware_revision, model);
+ tgt->workarounds = w;
+}
+
+static struct scsi_host_template scsi_driver_template;
+
+static int sbp2_probe(struct device *dev)
+{
+ struct fw_unit *unit = fw_unit(dev);
+ struct fw_device *device = fw_device(unit->device.parent);
+ struct sbp2_target *tgt;
+ struct sbp2_logical_unit *lu;
+ struct Scsi_Host *shost;
+ u32 model, firmware_revision;
+
+ shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
+ if (shost == NULL)
+ return -ENOMEM;
+
+ tgt = (struct sbp2_target *)shost->hostdata;
+ unit->device.driver_data = tgt;
+ tgt->unit = unit;
+ kref_init(&tgt->kref);
+ INIT_LIST_HEAD(&tgt->lu_list);
+
+ if (fw_device_enable_phys_dma(device) < 0)
+ goto fail_shost_put;
+
+ if (scsi_add_host(shost, &unit->device) < 0)
+ goto fail_shost_put;
+
+ /* Initialize to values that won't match anything in our table. */
+ firmware_revision = 0xff000000;
+ model = 0xff000000;
+
+ /* implicit directory ID */
+ tgt->directory_id = ((unit->directory - device->config_rom) * 4
+ + CSR_CONFIG_ROM) & 0xffffff;
+
+ if (sbp2_scan_unit_dir(tgt, unit->directory, &model,
+ &firmware_revision) < 0)
+ goto fail_tgt_put;
+
+ sbp2_init_workarounds(tgt, model, firmware_revision);
get_device(&unit->device);
@@ -729,35 +869,34 @@ static int sbp2_probe(struct device *dev)
* reschedule retries. Always get the ref before scheduling
* work.
*/
- INIT_DELAYED_WORK(&sd->work, sbp2_login);
- if (schedule_delayed_work(&sd->work, 0))
- kref_get(&sd->kref);
-
+ list_for_each_entry(lu, &tgt->lu_list, link)
+ if (queue_delayed_work(sbp2_wq, &lu->work, 0))
+ kref_get(&tgt->kref);
return 0;
- fail_address_handler:
- fw_core_remove_address_handler(&sd->address_handler);
- fail_host:
- scsi_host_put(host);
- fail:
- return err;
+ fail_tgt_put:
+ kref_put(&tgt->kref, sbp2_release_target);
+ return -ENOMEM;
+
+ fail_shost_put:
+ scsi_host_put(shost);
+ return -ENOMEM;
}
static int sbp2_remove(struct device *dev)
{
struct fw_unit *unit = fw_unit(dev);
- struct sbp2_device *sd = unit->device.driver_data;
-
- kref_put(&sd->kref, release_sbp2_device);
+ struct sbp2_target *tgt = unit->device.driver_data;
+ kref_put(&tgt->kref, sbp2_release_target);
return 0;
}
static void sbp2_reconnect(struct work_struct *work)
{
- struct sbp2_device *sd =
- container_of(work, struct sbp2_device, work.work);
- struct fw_unit *unit = sd->unit;
+ struct sbp2_logical_unit *lu =
+ container_of(work, struct sbp2_logical_unit, work.work);
+ struct fw_unit *unit = lu->tgt->unit;
struct fw_device *device = fw_device(unit->device.parent);
int generation, node_id, local_node_id;
@@ -765,40 +904,49 @@ static void sbp2_reconnect(struct work_struct *work)
node_id = device->node->node_id;
local_node_id = device->card->local_node->node_id;
- if (sbp2_send_management_orb(unit, node_id, generation,
+ if (sbp2_send_management_orb(lu, node_id, generation,
SBP2_RECONNECT_REQUEST,
- sd->login_id, NULL) < 0) {
- if (sd->retries++ >= 5) {
+ lu->login_id, NULL) < 0) {
+ if (lu->retries++ >= 5) {
fw_error("failed to reconnect to %s\n",
unit->device.bus_id);
/* Fall back and try to log in again. */
- sd->retries = 0;
- PREPARE_DELAYED_WORK(&sd->work, sbp2_login);
+ lu->retries = 0;
+ PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
}
- schedule_delayed_work(&sd->work, DIV_ROUND_UP(HZ, 5));
+ queue_delayed_work(sbp2_wq, &lu->work, DIV_ROUND_UP(HZ, 5));
return;
}
- sd->generation = generation;
- sd->node_id = node_id;
- sd->address_high = local_node_id << 16;
+ lu->generation = generation;
+ lu->tgt->node_id = node_id;
+ lu->tgt->address_high = local_node_id << 16;
- fw_notify("reconnected to unit %s (%d retries)\n",
- unit->device.bus_id, sd->retries);
- sbp2_agent_reset(unit);
- sbp2_cancel_orbs(unit);
- kref_put(&sd->kref, release_sbp2_device);
+ fw_notify("reconnected to %s LUN %04x (%d retries)\n",
+ unit->device.bus_id, lu->lun, lu->retries);
+
+ sbp2_agent_reset(lu);
+ sbp2_cancel_orbs(lu);
+
+ kref_put(&lu->tgt->kref, sbp2_release_target);
}
static void sbp2_update(struct fw_unit *unit)
{
- struct fw_device *device = fw_device(unit->device.parent);
- struct sbp2_device *sd = unit->device.driver_data;
+ struct sbp2_target *tgt = unit->device.driver_data;
+ struct sbp2_logical_unit *lu;
- sd->retries = 0;
- fw_device_enable_phys_dma(device);
- if (schedule_delayed_work(&sd->work, 0))
- kref_get(&sd->kref);
+ fw_device_enable_phys_dma(fw_device(unit->device.parent));
+
+ /*
+ * Fw-core serializes sbp2_update() against sbp2_remove().
+ * Iteration over tgt->lu_list is therefore safe here.
+ */
+ list_for_each_entry(lu, &tgt->lu_list, link) {
+ lu->retries = 0;
+ if (queue_delayed_work(sbp2_wq, &lu->work, 0))
+ kref_get(&tgt->kref);
+ }
}
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
@@ -868,13 +1016,12 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
{
struct sbp2_command_orb *orb =
container_of(base_orb, struct sbp2_command_orb, base);
- struct fw_unit *unit = orb->unit;
- struct fw_device *device = fw_device(unit->device.parent);
+ struct fw_device *device = fw_device(orb->lu->tgt->unit->device.parent);
int result;
if (status != NULL) {
if (STATUS_GET_DEAD(*status))
- sbp2_agent_reset(unit);
+ sbp2_agent_reset(orb->lu);
switch (STATUS_GET_RESPONSE(*status)) {
case SBP2_STATUS_REQUEST_COMPLETE:
@@ -918,12 +1065,10 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
orb->done(orb->cmd);
}
-static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
+static int
+sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+ struct sbp2_logical_unit *lu)
{
- struct sbp2_device *sd =
- (struct sbp2_device *)orb->cmd->device->host->hostdata;
- struct fw_unit *unit = sd->unit;
- struct fw_device *device = fw_device(unit->device.parent);
struct scatterlist *sg;
int sg_len, l, i, j, count;
dma_addr_t sg_addr;
@@ -942,10 +1087,9 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
* tables.
*/
if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
- orb->request.data_descriptor.high = sd->address_high;
+ orb->request.data_descriptor.high = lu->tgt->address_high;
orb->request.data_descriptor.low = sg_dma_address(sg);
- orb->request.misc |=
- COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
+ orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
return 0;
}
@@ -989,7 +1133,7 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
* initiator (i.e. us), but data_descriptor can refer to data
* on other nodes so we need to put our ID in descriptor.high.
*/
- orb->request.data_descriptor.high = sd->address_high;
+ orb->request.data_descriptor.high = lu->tgt->address_high;
orb->request.data_descriptor.low = orb->page_table_bus;
orb->request.misc |=
COMMAND_ORB_PAGE_TABLE_PRESENT |
@@ -1008,12 +1152,11 @@ static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
{
- struct sbp2_device *sd =
- (struct sbp2_device *)cmd->device->host->hostdata;
- struct fw_unit *unit = sd->unit;
- struct fw_device *device = fw_device(unit->device.parent);
+ struct sbp2_logical_unit *lu = cmd->device->hostdata;
+ struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
unsigned max_payload;
+ int retval = SCSI_MLQUEUE_HOST_BUSY;
/*
* Bidirectional commands are not yet implemented, and unknown
@@ -1029,14 +1172,14 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
if (orb == NULL) {
fw_notify("failed to alloc orb\n");
- goto fail_alloc;
+ return SCSI_MLQUEUE_HOST_BUSY;
}
/* Initialize rcode to something not RCODE_COMPLETE. */
orb->base.rcode = -1;
kref_init(&orb->base.kref);
- orb->unit = unit;
+ orb->lu = lu;
orb->done = done;
orb->cmd = cmd;
@@ -1062,8 +1205,8 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
orb->request.misc |=
COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
- if (scsi_sg_count(cmd) && sbp2_command_orb_map_scatterlist(orb) < 0)
- goto fail_mapping;
+ if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
+ goto out;
fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
@@ -1076,49 +1219,47 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
dma_map_single(device->card->device, &orb->request,
sizeof(orb->request), DMA_TO_DEVICE);
if (dma_mapping_error(orb->base.request_bus))
- goto fail_mapping;
-
- sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation,
- sd->command_block_agent_address + SBP2_ORB_POINTER);
-
- kref_put(&orb->base.kref, free_orb);
- return 0;
+ goto out;
- fail_mapping:
+ sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation,
+ lu->command_block_agent_address + SBP2_ORB_POINTER);
+ retval = 0;
+ out:
kref_put(&orb->base.kref, free_orb);
- fail_alloc:
- return SCSI_MLQUEUE_HOST_BUSY;
+ return retval;
}
static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
{
- struct sbp2_device *sd = (struct sbp2_device *)sdev->host->hostdata;
+ struct sbp2_logical_unit *lu = sdev->hostdata;
sdev->allow_restart = 1;
- if (sd->workarounds & SBP2_WORKAROUND_INQUIRY_36)
+ if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
sdev->inquiry_len = 36;
+
return 0;
}
static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
{
- struct sbp2_device *sd = (struct sbp2_device *)sdev->host->hostdata;
- struct fw_unit *unit = sd->unit;
+ struct sbp2_logical_unit *lu = sdev->hostdata;
sdev->use_10_for_rw = 1;
if (sdev->type == TYPE_ROM)
sdev->use_10_for_ms = 1;
+
if (sdev->type == TYPE_DISK &&
- sd->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
+ lu->tgt->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
sdev->skip_ms_page_8 = 1;
- if (sd->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) {
- fw_notify("setting fix_capacity for %s\n", unit->device.bus_id);
+
+ if (lu->tgt->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
sdev->fix_capacity = 1;
- }
- if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
+
+ if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+
return 0;
}
@@ -1128,13 +1269,11 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
*/
static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
{
- struct sbp2_device *sd =
- (struct sbp2_device *)cmd->device->host->hostdata;
- struct fw_unit *unit = sd->unit;
+ struct sbp2_logical_unit *lu = cmd->device->hostdata;
fw_notify("sbp2_scsi_abort\n");
- sbp2_agent_reset(unit);
- sbp2_cancel_orbs(unit);
+ sbp2_agent_reset(lu);
+ sbp2_cancel_orbs(lu);
return SUCCESS;
}
@@ -1151,37 +1290,18 @@ sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
- struct sbp2_device *sd;
- struct fw_unit *unit;
+ struct sbp2_logical_unit *lu;
struct fw_device *device;
- u32 directory_id;
- struct fw_csr_iterator ci;
- int key, value, lun;
if (!sdev)
return 0;
- sd = (struct sbp2_device *)sdev->host->hostdata;
- unit = sd->unit;
- device = fw_device(unit->device.parent);
-
- /* implicit directory ID */
- directory_id = ((unit->directory - device->config_rom) * 4
- + CSR_CONFIG_ROM) & 0xffffff;
-
- /* explicit directory ID, overrides implicit ID if present */
- fw_csr_iterator_init(&ci, unit->directory);
- while (fw_csr_iterator_next(&ci, &key, &value))
- if (key == CSR_DIRECTORY_ID) {
- directory_id = value;
- break;
- }
- /* FIXME: Make this work for multi-lun devices. */
- lun = 0;
+ lu = sdev->hostdata;
+ device = fw_device(lu->tgt->unit->device.parent);
return sprintf(buf, "%08x%08x:%06x:%04x\n",
device->config_rom[3], device->config_rom[4],
- directory_id, lun);
+ lu->tgt->directory_id, lu->lun);
}
static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);
@@ -1219,12 +1339,17 @@ MODULE_ALIAS("sbp2");
static int __init sbp2_init(void)
{
+ sbp2_wq = create_singlethread_workqueue(KBUILD_MODNAME);
+ if (!sbp2_wq)
+ return -ENOMEM;
+
return driver_register(&sbp2_driver.driver);
}
static void __exit sbp2_cleanup(void)
{
driver_unregister(&sbp2_driver.driver);
+ destroy_workqueue(sbp2_wq);
}
module_init(sbp2_init);
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index 39e5cd12aa5..0fc9b000e99 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -152,6 +152,10 @@ static void update_hop_count(struct fw_node *node)
node->max_hops = max(max_child_hops, depths[0] + depths[1] + 2);
}
+static inline struct fw_node *fw_node(struct list_head *l)
+{
+ return list_entry(l, struct fw_node, link);
+}
/**
* build_tree - Build the tree representation of the topology
@@ -162,7 +166,7 @@ static void update_hop_count(struct fw_node *node)
* This function builds the tree representation of the topology given
* by the self IDs from the latest bus reset. During the construction
* of the tree, the function checks that the self IDs are valid and
- * internally consistent. On succcess this funtions returns the
+ * internally consistent. On succcess this function returns the
* fw_node corresponding to the local card otherwise NULL.
*/
static struct fw_node *build_tree(struct fw_card *card,
@@ -211,6 +215,10 @@ static struct fw_node *build_tree(struct fw_card *card,
*/
for (i = 0, h = &stack; i < child_port_count; i++)
h = h->prev;
+ /*
+ * When the stack is empty, this yields an invalid value,
+ * but that pointer will never be dereferenced.
+ */
child = fw_node(h);
node = fw_node_create(q, port_count, card->color);
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h
index 1b56b4ac7fb..cedc1ec906e 100644
--- a/drivers/firewire/fw-topology.h
+++ b/drivers/firewire/fw-topology.h
@@ -51,12 +51,6 @@ struct fw_node {
};
static inline struct fw_node *
-fw_node(struct list_head *l)
-{
- return list_entry(l, struct fw_node, link);
-}
-
-static inline struct fw_node *
fw_node_get(struct fw_node *node)
{
atomic_inc(&node->ref_count);
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 3e1cb12e43c..9959b799dbe 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -410,7 +410,12 @@ EXPORT_SYMBOL(fw_unit_space_region);
* controller. When a request is received that falls within the
* specified address range, the specified callback is invoked. The
* parameters passed to the callback give the details of the
- * particular request
+ * particular request.
+ *
+ * Return value: 0 on success, non-zero otherwise.
+ * The start offset of the handler's address region is determined by
+ * fw_core_add_address_handler() and is returned in handler->offset.
+ * The offset is quadlet-aligned.
*/
int
fw_core_add_address_handler(struct fw_address_handler *handler,
@@ -422,14 +427,15 @@ fw_core_add_address_handler(struct fw_address_handler *handler,
spin_lock_irqsave(&address_handler_lock, flags);
- handler->offset = region->start;
+ handler->offset = roundup(region->start, 4);
while (handler->offset + handler->length <= region->end) {
other =
lookup_overlapping_address_handler(&address_handler_list,
handler->offset,
handler->length);
if (other != NULL) {
- handler->offset += other->length;
+ handler->offset =
+ roundup(other->offset + other->length, 4);
} else {
list_add_tail(&handler->link, &address_handler_list);
ret = 0;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e47f8817080..700a1657554 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -158,6 +158,7 @@ config SENSORS_K8TEMP
config SENSORS_AMS
tristate "Apple Motion Sensor driver"
depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
+ select INPUT_POLLDEV
help
Support for the motion sensor included in PowerBooks. Includes
implementations for PMU and I2C.
@@ -701,6 +702,7 @@ config SENSORS_W83627EHF
config SENSORS_HDAPS
tristate "IBM Hard Drive Active Protection System (hdaps)"
depends on INPUT && X86
+ select INPUT_POLLDEV
default n
help
This driver provides support for the IBM Hard Drive Active Protection
@@ -722,6 +724,7 @@ config SENSORS_APPLESMC
depends on INPUT && X86
select NEW_LEDS
select LEDS_CLASS
+ select INPUT_POLLDEV
default n
help
This driver provides support for the Apple System Management
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index aa875ca50d9..3e63c148677 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -1651,7 +1651,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
break;
default :
dev_err(&adapter->dev, ": Internal error, invalid "
- "kind (%d)!", kind);
+ "kind (%d)!\n", kind);
err = -EFAULT;
goto exitfree;
}
diff --git a/drivers/hwmon/ams/ams-input.c b/drivers/hwmon/ams/ams-input.c
index ca7095d96ad..7b81e0c2c2d 100644
--- a/drivers/hwmon/ams/ams-input.c
+++ b/drivers/hwmon/ams/ams-input.c
@@ -27,47 +27,32 @@ static unsigned int invert;
module_param(invert, bool, 0644);
MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
-static int ams_input_kthread(void *data)
+static void ams_idev_poll(struct input_polled_dev *dev)
{
+ struct input_dev *idev = dev->input;
s8 x, y, z;
- while (!kthread_should_stop()) {
- mutex_lock(&ams_info.lock);
-
- ams_sensors(&x, &y, &z);
-
- x -= ams_info.xcalib;
- y -= ams_info.ycalib;
- z -= ams_info.zcalib;
-
- input_report_abs(ams_info.idev, ABS_X, invert ? -x : x);
- input_report_abs(ams_info.idev, ABS_Y, invert ? -y : y);
- input_report_abs(ams_info.idev, ABS_Z, z);
+ mutex_lock(&ams_info.lock);
- input_sync(ams_info.idev);
+ ams_sensors(&x, &y, &z);
- mutex_unlock(&ams_info.lock);
+ x -= ams_info.xcalib;
+ y -= ams_info.ycalib;
+ z -= ams_info.zcalib;
- msleep(25);
- }
+ input_report_abs(idev, ABS_X, invert ? -x : x);
+ input_report_abs(idev, ABS_Y, invert ? -y : y);
+ input_report_abs(idev, ABS_Z, z);
- return 0;
-}
+ input_sync(idev);
-static int ams_input_open(struct input_dev *dev)
-{
- ams_info.kthread = kthread_run(ams_input_kthread, NULL, "kams");
- return IS_ERR(ams_info.kthread) ? PTR_ERR(ams_info.kthread) : 0;
-}
-
-static void ams_input_close(struct input_dev *dev)
-{
- kthread_stop(ams_info.kthread);
+ mutex_unlock(&ams_info.lock);
}
/* Call with ams_info.lock held! */
static void ams_input_enable(void)
{
+ struct input_dev *input;
s8 x, y, z;
if (ams_info.idev)
@@ -78,27 +63,29 @@ static void ams_input_enable(void)
ams_info.ycalib = y;
ams_info.zcalib = z;
- ams_info.idev = input_allocate_device();
+ ams_info.idev = input_allocate_polled_device();
if (!ams_info.idev)
return;
- ams_info.idev->name = "Apple Motion Sensor";
- ams_info.idev->id.bustype = ams_info.bustype;
- ams_info.idev->id.vendor = 0;
- ams_info.idev->open = ams_input_open;
- ams_info.idev->close = ams_input_close;
- ams_info.idev->dev.parent = &ams_info.of_dev->dev;
+ ams_info.idev->poll = ams_idev_poll;
+ ams_info.idev->poll_interval = 25;
+
+ input = ams_info.idev->input;
+ input->name = "Apple Motion Sensor";
+ input->id.bustype = ams_info.bustype;
+ input->id.vendor = 0;
+ input->dev.parent = &ams_info.of_dev->dev;
- input_set_abs_params(ams_info.idev, ABS_X, -50, 50, 3, 0);
- input_set_abs_params(ams_info.idev, ABS_Y, -50, 50, 3, 0);
- input_set_abs_params(ams_info.idev, ABS_Z, -50, 50, 3, 0);
+ input_set_abs_params(input, ABS_X, -50, 50, 3, 0);
+ input_set_abs_params(input, ABS_Y, -50, 50, 3, 0);
+ input_set_abs_params(input, ABS_Z, -50, 50, 3, 0);
- set_bit(EV_ABS, ams_info.idev->evbit);
- set_bit(EV_KEY, ams_info.idev->evbit);
- set_bit(BTN_TOUCH, ams_info.idev->keybit);
+ set_bit(EV_ABS, input->evbit);
+ set_bit(EV_KEY, input->evbit);
+ set_bit(BTN_TOUCH, input->keybit);
- if (input_register_device(ams_info.idev)) {
- input_free_device(ams_info.idev);
+ if (input_register_polled_device(ams_info.idev)) {
+ input_free_polled_device(ams_info.idev);
ams_info.idev = NULL;
return;
}
@@ -108,7 +95,8 @@ static void ams_input_enable(void)
static void ams_input_disable(void)
{
if (ams_info.idev) {
- input_unregister_device(ams_info.idev);
+ input_unregister_polled_device(ams_info.idev);
+ input_free_polled_device(ams_info.idev);
ams_info.idev = NULL;
}
}
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
index 240730e6bcd..a6221e5dd98 100644
--- a/drivers/hwmon/ams/ams.h
+++ b/drivers/hwmon/ams/ams.h
@@ -1,5 +1,5 @@
#include <linux/i2c.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
@@ -52,8 +52,7 @@ struct ams {
#endif
/* Joystick emulation */
- struct task_struct *kthread;
- struct input_dev *idev;
+ struct input_polled_dev *idev;
__u16 bustype;
/* calibrated null values */
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index f37fd7ebf65..4879125b4cd 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -28,7 +28,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
@@ -59,9 +59,9 @@
#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */
#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */
-#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
+#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
-#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
+#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
#define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
@@ -103,7 +103,7 @@ static const char* fan_speed_keys[] = {
#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
-#define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
+#define APPLESMC_POLL_INTERVAL 50 /* msecs */
#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
#define APPLESMC_INPUT_FLAT 4
@@ -125,9 +125,8 @@ static const int debug;
static struct platform_device *pdev;
static s16 rest_x;
static s16 rest_y;
-static struct timer_list applesmc_timer;
-static struct input_dev *applesmc_idev;
static struct device *hwmon_dev;
+static struct input_polled_dev *applesmc_idev;
/* Indicates whether this computer has an accelerometer. */
static unsigned int applesmc_accelerometer;
@@ -138,7 +137,7 @@ static unsigned int applesmc_light;
/* Indicates which temperature sensors set to use. */
static unsigned int applesmc_temperature_set;
-static struct mutex applesmc_lock;
+static DEFINE_MUTEX(applesmc_lock);
/*
* Last index written to key_at_index sysfs file, and value to use for all other
@@ -455,27 +454,12 @@ static void applesmc_calibrate(void)
rest_x = -rest_x;
}
-static int applesmc_idev_open(struct input_dev *dev)
-{
- add_timer(&applesmc_timer);
-
- return 0;
-}
-
-static void applesmc_idev_close(struct input_dev *dev)
-{
- del_timer_sync(&applesmc_timer);
-}
-
-static void applesmc_idev_poll(unsigned long unused)
+static void applesmc_idev_poll(struct input_polled_dev *dev)
{
+ struct input_dev *idev = dev->input;
s16 x, y;
- /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
- if (!mutex_trylock(&applesmc_lock)) {
- mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
- return;
- }
+ mutex_lock(&applesmc_lock);
if (applesmc_read_motion_sensor(SENSOR_X, &x))
goto out;
@@ -483,13 +467,11 @@ static void applesmc_idev_poll(unsigned long unused)
goto out;
x = -x;
- input_report_abs(applesmc_idev, ABS_X, x - rest_x);
- input_report_abs(applesmc_idev, ABS_Y, y - rest_y);
- input_sync(applesmc_idev);
+ input_report_abs(idev, ABS_X, x - rest_x);
+ input_report_abs(idev, ABS_Y, y - rest_y);
+ input_sync(idev);
out:
- mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
-
mutex_unlock(&applesmc_lock);
}
@@ -821,8 +803,7 @@ static ssize_t applesmc_key_at_index_read_show(struct device *dev,
if (!ret) {
return info[0];
- }
- else {
+ } else {
return ret;
}
}
@@ -1093,6 +1074,7 @@ static int applesmc_dmi_match(const struct dmi_system_id *id)
/* Create accelerometer ressources */
static int applesmc_create_accelerometer(void)
{
+ struct input_dev *idev;
int ret;
ret = sysfs_create_group(&pdev->dev.kobj,
@@ -1100,40 +1082,37 @@ static int applesmc_create_accelerometer(void)
if (ret)
goto out;
- applesmc_idev = input_allocate_device();
+ applesmc_idev = input_allocate_polled_device();
if (!applesmc_idev) {
ret = -ENOMEM;
goto out_sysfs;
}
+ applesmc_idev->poll = applesmc_idev_poll;
+ applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL;
+
/* initial calibrate for the input device */
applesmc_calibrate();
- /* initialize the input class */
- applesmc_idev->name = "applesmc";
- applesmc_idev->id.bustype = BUS_HOST;
- applesmc_idev->dev.parent = &pdev->dev;
- applesmc_idev->evbit[0] = BIT(EV_ABS);
- applesmc_idev->open = applesmc_idev_open;
- applesmc_idev->close = applesmc_idev_close;
- input_set_abs_params(applesmc_idev, ABS_X,
+ /* initialize the input device */
+ idev = applesmc_idev->input;
+ idev->name = "applesmc";
+ idev->id.bustype = BUS_HOST;
+ idev->dev.parent = &pdev->dev;
+ idev->evbit[0] = BIT(EV_ABS);
+ input_set_abs_params(idev, ABS_X,
-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
- input_set_abs_params(applesmc_idev, ABS_Y,
+ input_set_abs_params(idev, ABS_Y,
-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
- ret = input_register_device(applesmc_idev);
+ ret = input_register_polled_device(applesmc_idev);
if (ret)
goto out_idev;
- /* start up our timer for the input device */
- init_timer(&applesmc_timer);
- applesmc_timer.function = applesmc_idev_poll;
- applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD;
-
return 0;
out_idev:
- input_free_device(applesmc_idev);
+ input_free_polled_device(applesmc_idev);
out_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
@@ -1146,8 +1125,8 @@ out:
/* Release all ressources used by the accelerometer */
static void applesmc_release_accelerometer(void)
{
- del_timer_sync(&applesmc_timer);
- input_unregister_device(applesmc_idev);
+ input_unregister_polled_device(applesmc_idev);
+ input_free_polled_device(applesmc_idev);
sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
}
@@ -1184,8 +1163,6 @@ static int __init applesmc_init(void)
int count;
int i;
- mutex_init(&applesmc_lock);
-
if (!dmi_check_system(applesmc_whitelist)) {
printk(KERN_WARNING "applesmc: supported laptop not found!\n");
ret = -ENODEV;
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index a7c6d407572..8a7ae03aeee 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -28,7 +28,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/module.h>
@@ -61,13 +61,12 @@
#define INIT_TIMEOUT_MSECS 4000 /* wait up to 4s for device init ... */
#define INIT_WAIT_MSECS 200 /* ... in 200ms increments */
-#define HDAPS_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
+#define HDAPS_POLL_INTERVAL 50 /* poll for input every 1/20s (50 ms)*/
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
#define HDAPS_INPUT_FLAT 4
-static struct timer_list hdaps_timer;
static struct platform_device *pdev;
-static struct input_dev *hdaps_idev;
+static struct input_polled_dev *hdaps_idev;
static unsigned int hdaps_invert;
static u8 km_activity;
static int rest_x;
@@ -323,24 +322,19 @@ static void hdaps_calibrate(void)
__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &rest_x, &rest_y);
}
-static void hdaps_mousedev_poll(unsigned long unused)
+static void hdaps_mousedev_poll(struct input_polled_dev *dev)
{
+ struct input_dev *input_dev = dev->input;
int x, y;
- /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
- if (mutex_trylock(&hdaps_mtx)) {
- mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
- return;
- }
+ mutex_lock(&hdaps_mtx);
if (__hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y))
goto out;
- input_report_abs(hdaps_idev, ABS_X, x - rest_x);
- input_report_abs(hdaps_idev, ABS_Y, y - rest_y);
- input_sync(hdaps_idev);
-
- mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
+ input_report_abs(input_dev, ABS_X, x - rest_x);
+ input_report_abs(input_dev, ABS_Y, y - rest_y);
+ input_sync(input_dev);
out:
mutex_unlock(&hdaps_mtx);
@@ -536,6 +530,7 @@ static struct dmi_system_id __initdata hdaps_whitelist[] = {
static int __init hdaps_init(void)
{
+ struct input_dev *idev;
int ret;
if (!dmi_check_system(hdaps_whitelist)) {
@@ -563,39 +558,37 @@ static int __init hdaps_init(void)
if (ret)
goto out_device;
- hdaps_idev = input_allocate_device();
+ hdaps_idev = input_allocate_polled_device();
if (!hdaps_idev) {
ret = -ENOMEM;
goto out_group;
}
+ hdaps_idev->poll = hdaps_mousedev_poll;
+ hdaps_idev->poll_interval = HDAPS_POLL_INTERVAL;
+
/* initial calibrate for the input device */
hdaps_calibrate();
/* initialize the input class */
- hdaps_idev->name = "hdaps";
- hdaps_idev->dev.parent = &pdev->dev;
- hdaps_idev->evbit[0] = BIT(EV_ABS);
- input_set_abs_params(hdaps_idev, ABS_X,
+ idev = hdaps_idev->input;
+ idev->name = "hdaps";
+ idev->dev.parent = &pdev->dev;
+ idev->evbit[0] = BIT(EV_ABS);
+ input_set_abs_params(idev, ABS_X,
-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
- input_set_abs_params(hdaps_idev, ABS_Y,
+ input_set_abs_params(idev, ABS_Y,
-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
- ret = input_register_device(hdaps_idev);
+ ret = input_register_polled_device(hdaps_idev);
if (ret)
goto out_idev;
- /* start up our timer for the input device */
- init_timer(&hdaps_timer);
- hdaps_timer.function = hdaps_mousedev_poll;
- hdaps_timer.expires = jiffies + HDAPS_POLL_PERIOD;
- add_timer(&hdaps_timer);
-
printk(KERN_INFO "hdaps: driver successfully loaded.\n");
return 0;
out_idev:
- input_free_device(hdaps_idev);
+ input_free_polled_device(hdaps_idev);
out_group:
sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
out_device:
@@ -611,8 +604,8 @@ out:
static void __exit hdaps_exit(void)
{
- del_timer_sync(&hdaps_timer);
- input_unregister_device(hdaps_idev);
+ input_unregister_polled_device(hdaps_idev);
+ input_free_polled_device(hdaps_idev);
sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
platform_device_unregister(pdev);
platform_driver_unregister(&hdaps_driver);
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index f207434730d..650b07d5b90 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -533,7 +533,7 @@ static void lm63_init_client(struct i2c_client *client)
/* Start converting if needed */
if (data->config & 0x40) { /* standby */
- dev_dbg(&client->dev, "Switching to operational mode");
+ dev_dbg(&client->dev, "Switching to operational mode\n");
data->config &= 0xA7;
i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
data->config);
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index e69416465e6..7dfcc8dd316 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -795,7 +795,7 @@ static ssize_t set_pwm_auto_point_pwm(struct device *dev,
if ((val < 0) || (val > 255)) {
dev_err(dev, "pwm value %ld is out of range. "
- "Choose a value between 0 and 255." , val);
+ "Choose a value between 0 and 255.\n" , val);
return -EINVAL;
}
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index b6f2ebf9f9c..a9c01a6f005 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -1096,7 +1096,7 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind == w83791d) {
client_name = "w83791d";
} else {
- dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?",
+ dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n",
kind);
goto error1;
}
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index f836198b705..007449d3e16 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -1385,8 +1385,8 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind == w83792d) {
client_name = "w83792d";
} else {
- dev_err(dev, "w83792d: Internal error: unknown"
- " kind (%d)?!?", kind);
+ dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n",
+ kind);
goto ERROR1;
}
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index 17cecf1ea79..be99c02ecac 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -591,18 +591,18 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
if (msg->flags & I2C_M_TEN)
pmcmsptwi_set_twi_config(&oldcfg, data);
- dev_dbg(&adap->dev, "I2C %s of %d bytes ",
- (msg->flags & I2C_M_RD) ? "read" : "write", msg->len);
+ dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n",
+ (msg->flags & I2C_M_RD) ? "read" : "write", msg->len,
+ (ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed");
+
if (ret != MSP_TWI_XFER_OK) {
/*
* TODO: We could potentially loop and retry in the case
* of MSP_TWI_XFER_TIMEOUT.
*/
- dev_dbg(&adap->dev, "failed\n");
return -1;
}
- dev_dbg(&adap->dev, "succeeded\n");
return 0;
}
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 17376feb1ac..f8d0dff0de7 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -575,7 +575,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
else {
freq_mhz = PNX_DEFAULT_FREQ;
dev_info(&pdev->dev, "Setting bus frequency to default value: "
- "%d MHz", freq_mhz);
+ "%d MHz\n", freq_mhz);
}
i2c_pnx->adapter->algo = &pnx_algorithm;
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index bb5466b27b5..00fad11733a 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -31,6 +31,8 @@
#include <linux/interrupt.h>
#include <linux/i2c-pxa.h>
#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -48,6 +50,7 @@ struct pxa_i2c {
unsigned int slave_addr;
struct i2c_adapter adap;
+ struct clk *clk;
#ifdef CONFIG_I2C_PXA_SLAVE
struct i2c_slave_client *slave;
#endif
@@ -869,6 +872,12 @@ static int i2c_pxa_probe(struct platform_device *dev)
sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id);
+ i2c->clk = clk_get(&dev->dev, "I2CCLK");
+ if (IS_ERR(i2c->clk)) {
+ ret = PTR_ERR(i2c->clk);
+ goto eclk;
+ }
+
i2c->reg_base = ioremap(res->start, res_len(res));
if (!i2c->reg_base) {
ret = -EIO;
@@ -889,22 +898,19 @@ static int i2c_pxa_probe(struct platform_device *dev)
}
#endif
+ clk_enable(i2c->clk);
+#ifdef CONFIG_PXA27x
switch (dev->id) {
case 0:
-#ifdef CONFIG_PXA27x
pxa_gpio_mode(GPIO117_I2CSCL_MD);
pxa_gpio_mode(GPIO118_I2CSDA_MD);
-#endif
- pxa_set_cken(CKEN_I2C, 1);
break;
-#ifdef CONFIG_PXA27x
case 1:
local_irq_disable();
PCFR |= PCFR_PI2CEN;
local_irq_enable();
- pxa_set_cken(CKEN_PWRI2C, 1);
-#endif
}
+#endif
ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
i2c->adap.name, i2c);
@@ -948,19 +954,18 @@ static int i2c_pxa_probe(struct platform_device *dev)
eadapt:
free_irq(irq, i2c);
ereqirq:
- switch (dev->id) {
- case 0:
- pxa_set_cken(CKEN_I2C, 0);
- break;
+ clk_disable(i2c->clk);
+
#ifdef CONFIG_PXA27x
- case 1:
- pxa_set_cken(CKEN_PWRI2C, 0);
+ if (dev->id == 1) {
local_irq_disable();
PCFR &= ~PCFR_PI2CEN;
local_irq_enable();
-#endif
}
+#endif
eremap:
+ clk_put(i2c->clk);
+eclk:
kfree(i2c);
emalloc:
release_mem_region(res->start, res_len(res));
@@ -975,18 +980,18 @@ static int i2c_pxa_remove(struct platform_device *dev)
i2c_del_adapter(&i2c->adap);
free_irq(i2c->irq, i2c);
- switch (dev->id) {
- case 0:
- pxa_set_cken(CKEN_I2C, 0);
- break;
+
+ clk_disable(i2c->clk);
+ clk_put(i2c->clk);
+
#ifdef CONFIG_PXA27x
- case 1:
- pxa_set_cken(CKEN_PWRI2C, 0);
+ if (dev->id == 1) {
local_irq_disable();
PCFR &= ~PCFR_PI2CEN;
local_irq_enable();
-#endif
}
+#endif
+
release_mem_region(i2c->iobase, i2c->iosize);
kfree(i2c);
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index d9c92c5e007..2dea0123a95 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -49,8 +49,6 @@
#define DRIVER_NAME "menelaus"
-#define pr_err(fmt, arg...) printk(KERN_ERR DRIVER_NAME ": ", ## arg);
-
#define MENELAUS_I2C_ADDRESS 0x72
#define MENELAUS_REV 0x01
@@ -155,7 +153,7 @@ static int menelaus_write_reg(int reg, u8 value)
int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
if (val < 0) {
- pr_err("write error");
+ pr_err(DRIVER_NAME ": write error");
return val;
}
@@ -167,7 +165,7 @@ static int menelaus_read_reg(int reg)
int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
if (val < 0)
- pr_err("read error");
+ pr_err(DRIVER_NAME ": read error");
return val;
}
@@ -1177,7 +1175,7 @@ static int menelaus_probe(struct i2c_client *client)
/* If a true probe check the device */
rev = menelaus_read_reg(MENELAUS_REV);
if (rev < 0) {
- pr_err("device not found");
+ pr_err(DRIVER_NAME ": device not found");
err = -ENODEV;
goto fail1;
}
@@ -1197,7 +1195,7 @@ static int menelaus_probe(struct i2c_client *client)
err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED,
DRIVER_NAME, menelaus);
if (err) {
- dev_dbg(&client->dev, "can't get IRQ %d, err %d",
+ dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
client->irq, err);
goto fail1;
}
@@ -1258,7 +1256,7 @@ static int __init menelaus_init(void)
res = i2c_add_driver(&menelaus_i2c_driver);
if (res < 0) {
- pr_err("driver registration failed\n");
+ pr_err(DRIVER_NAME ": driver registration failed\n");
return res;
}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 8982c093243..6d9fd92763f 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -435,24 +435,6 @@ config BLK_DEV_IDEDMA_PCI
bool
select BLK_DEV_IDEPCI
-config BLK_DEV_IDEDMA_FORCED
- bool "Force enable legacy 2.0.X HOSTS to use DMA"
- depends on BLK_DEV_IDEDMA_PCI
- help
- This is an old piece of lost code from Linux 2.0 Kernels.
-
- Generally say N here.
-
-# TODO: remove it
-config IDEDMA_ONLYDISK
- bool "Enable DMA only for disks "
- depends on BLK_DEV_IDEDMA_PCI
- help
- This is used if you know your ATAPI Devices are going to fail DMA
- Transfers.
-
- Generally say N here.
-
config BLK_DEV_AEC62XX
tristate "AEC62XX chipset support"
select BLK_DEV_IDEDMA_PCI
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index bd1f5b67037..3af33fbf1f8 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -309,14 +309,6 @@ static int icside_dma_on(ide_drive_t *drive)
return 0;
}
-static int icside_dma_check(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- return -1;
-}
-
static int icside_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -423,18 +415,13 @@ static void icside_dma_lost_irq(ide_drive_t *drive)
static void icside_dma_init(ide_hwif_t *hwif)
{
- printk(" %s: SG-DMA", hwif->name);
-
- hwif->atapi_dma = 1;
hwif->mwdma_mask = 7; /* MW0..2 */
hwif->swdma_mask = 7; /* SW0..2 */
hwif->dmatable_cpu = NULL;
hwif->dmatable_dma = 0;
hwif->set_dma_mode = icside_set_dma_mode;
- hwif->autodma = 1;
- hwif->ide_dma_check = icside_dma_check;
hwif->dma_host_off = icside_dma_host_off;
hwif->dma_off_quietly = icside_dma_off_quietly;
hwif->dma_host_on = icside_dma_host_on;
@@ -446,11 +433,6 @@ static void icside_dma_init(ide_hwif_t *hwif)
hwif->ide_dma_test_irq = icside_dma_test_irq;
hwif->dma_timeout = icside_dma_timeout;
hwif->dma_lost_irq = icside_dma_lost_irq;
-
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
-
- printk(" capable%s\n", hwif->autodma ? ", auto-enable" : "");
}
#else
#define icside_dma_init(hwif) (0)
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 2b4d2a0ae5c..9a96a10ba9d 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -664,7 +664,6 @@ cris_ide_inb(unsigned long reg)
return (unsigned char)cris_ide_inw(reg);
}
-static int cris_dma_check (ide_drive_t *drive);
static int cris_dma_end (ide_drive_t *drive);
static int cris_dma_setup (ide_drive_t *drive);
static void cris_dma_exec_cmd (ide_drive_t *drive, u8 command);
@@ -792,7 +791,6 @@ init_e100_ide (void)
hwif->ata_output_data = &cris_ide_output_data;
hwif->atapi_input_bytes = &cris_atapi_input_bytes;
hwif->atapi_output_bytes = &cris_atapi_output_bytes;
- hwif->ide_dma_check = &cris_dma_check;
hwif->ide_dma_end = &cris_dma_end;
hwif->dma_setup = &cris_dma_setup;
hwif->dma_exec_cmd = &cris_dma_exec_cmd;
@@ -807,12 +805,12 @@ init_e100_ide (void)
hwif->dma_host_on = &cris_dma_on;
hwif->dma_off_quietly = &cris_dma_off;
hwif->cbl = ATA_CBL_PATA40;
+ hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
hwif->pio_mask = ATA_PIO4,
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
hwif->ultra_mask = cris_ultra_mask;
hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
- hwif->autodma = 1;
- hwif->drives[0].autodma = 1;
- hwif->drives[1].autodma = 1;
}
/* Reset pulse */
@@ -939,7 +937,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
/* group sequential buffers into one large buffer */
addr = page_to_phys(sg->page) + sg->offset;
size = sg_dma_len(sg);
- while (sg++, --i) {
+ while (--i) {
+ sg = sg_next(sg);
if ((addr + size) != page_to_phys(sg->page) + sg->offset)
break;
size += sg_dma_len(sg);
@@ -1017,14 +1016,6 @@ static ide_startstop_t cris_dma_intr (ide_drive_t *drive)
* the caller should revert to PIO for the current request.
*/
-static int cris_dma_check(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- return -1;
-}
-
static int cris_dma_end(ide_drive_t *drive)
{
drive->waiting_for_dma = 0;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 4754769eda9..2722d9165b6 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -169,7 +169,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
nsectors.all = (u16) rq->nr_sectors;
- if (hwif->no_lba48_dma && lba48 && dma) {
+ if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
if (block + rq->nr_sectors > 1ULL << 28)
dma = 0;
else
@@ -716,32 +716,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
rq->buffer = rq->cmd;
}
-static int idedisk_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- ide_drive_t *drive = q->queuedata;
- struct request *rq;
- int ret;
-
- if (!drive->wcache)
- return 0;
-
- rq = blk_get_request(q, WRITE, __GFP_WAIT);
-
- idedisk_prepare_flush(q, rq);
-
- ret = blk_execute_rq(q, disk, rq, 0);
-
- /*
- * if we failed and caller wants error offset, get it
- */
- if (ret && error_sector)
- *error_sector = ide_get_error_location(drive, rq->cmd);
-
- blk_put_request(rq);
- return ret;
-}
-
/*
* This is tightly woven into the driver->do_special can not touch.
* DON'T do it again until a total personality rewrite is committed.
@@ -781,7 +755,6 @@ static void update_ordered(ide_drive_t *drive)
struct hd_driveid *id = drive->id;
unsigned ordered = QUEUE_ORDERED_NONE;
prepare_flush_fn *prep_fn = NULL;
- issue_flush_fn *issue_fn = NULL;
if (drive->wcache) {
unsigned long long capacity;
@@ -805,13 +778,11 @@ static void update_ordered(ide_drive_t *drive)
if (barrier) {
ordered = QUEUE_ORDERED_DRAIN_FLUSH;
prep_fn = idedisk_prepare_flush;
- issue_fn = idedisk_issue_flush;
}
} else
ordered = QUEUE_ORDERED_DRAIN;
blk_queue_ordered(drive->queue, ordered, prep_fn);
- blk_queue_issue_flush_fn(drive->queue, issue_fn);
}
static int write_cache(ide_drive_t *drive, int arg)
@@ -885,7 +856,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg)
drive->addressing = 0;
- if (HWIF(drive)->no_lba48)
+ if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48)
return 0;
if (!idedisk_supports_lba48(drive->id))
@@ -918,6 +889,7 @@ static inline void idedisk_add_settings(ide_drive_t *drive) { ; }
static void idedisk_setup (ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id = drive->id;
unsigned long long capacity;
@@ -938,7 +910,6 @@ static void idedisk_setup (ide_drive_t *drive)
(void)set_lba_addressing(drive, 1);
if (drive->addressing == 1) {
- ide_hwif_t *hwif = HWIF(drive);
int max_s = 2048;
if (max_s > hwif->rqsize)
@@ -961,7 +932,7 @@ static void idedisk_setup (ide_drive_t *drive)
drive->capacity64 = 1ULL << 28;
}
- if (drive->hwif->no_lba48_dma && drive->addressing) {
+ if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) {
if (drive->capacity64 > 1ULL << 28) {
printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will"
" be used for accessing sectors > %u\n",
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index b453211ee0f..80b4f17f394 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
}
}
- sg++;
+ sg = sg_next(sg);
i--;
}
@@ -338,35 +338,32 @@ static int config_drive_for_dma (ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id = drive->id;
- /* consult the list of known "bad" drives */
- if (__ide_dma_bad_drive(drive))
- return -1;
+ if (drive->media != ide_disk) {
+ if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+ return -1;
+ }
- if (drive->media != ide_disk && hwif->atapi_dma == 0)
- return -1;
+ /*
+ * Enable DMA on any drive that has
+ * UltraDMA (mode 0/1/2/3/4/5/6) enabled
+ */
+ if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
+ return 1;
- if ((id->capability & 1) && drive->autodma) {
- /*
- * Enable DMA on any drive that has
- * UltraDMA (mode 0/1/2/3/4/5/6) enabled
- */
- if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
- return 0;
- /*
- * Enable DMA on any drive that has mode2 DMA
- * (multi or single) enabled
- */
- if (id->field_valid & 2) /* regular DMA */
- if ((id->dma_mword & 0x404) == 0x404 ||
- (id->dma_1word & 0x404) == 0x404)
- return 0;
+ /*
+ * Enable DMA on any drive that has mode2 DMA
+ * (multi or single) enabled
+ */
+ if (id->field_valid & 2) /* regular DMA */
+ if ((id->dma_mword & 0x404) == 0x404 ||
+ (id->dma_1word & 0x404) == 0x404)
+ return 1;
- /* Consult the list of known "good" drives */
- if (ide_dma_good_drive(drive))
- return 0;
- }
+ /* Consult the list of known "good" drives */
+ if (ide_dma_good_drive(drive))
+ return 1;
- return -1;
+ return 0;
}
/**
@@ -627,6 +624,8 @@ static int __ide_dma_test_irq(ide_drive_t *drive)
drive->name, __FUNCTION__);
return 0;
}
+#else
+static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
int __ide_dma_bad_drive (ide_drive_t *drive)
@@ -729,8 +728,10 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
int x, i;
u8 mode = 0;
- if (drive->media != ide_disk && hwif->atapi_dma == 0)
- return 0;
+ if (drive->media != ide_disk) {
+ if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+ return 0;
+ }
for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
if (req_mode < xfer_mode_bases[i])
@@ -758,17 +759,20 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
EXPORT_SYMBOL_GPL(ide_find_dma_mode);
-int ide_tune_dma(ide_drive_t *drive)
+static int ide_tune_dma(ide_drive_t *drive)
{
u8 speed;
- if ((drive->id->capability & 1) == 0 || drive->autodma == 0)
+ if (noautodma || drive->nodma || (drive->id->capability & 1) == 0)
return 0;
/* consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
return 0;
+ if (drive->hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
+ return config_drive_for_dma(drive);
+
speed = ide_max_dma_mode(drive);
if (!speed)
@@ -783,7 +787,22 @@ int ide_tune_dma(ide_drive_t *drive)
return 1;
}
-EXPORT_SYMBOL_GPL(ide_tune_dma);
+static int ide_dma_check(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ int vdma = (hwif->host_flags & IDE_HFLAG_VDMA)? 1 : 0;
+
+ if (!vdma && ide_tune_dma(drive))
+ return 0;
+
+ /* TODO: always do PIO fallback */
+ if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
+ return -1;
+
+ ide_set_max_pio(drive);
+
+ return vdma ? 0 : -1;
+}
void ide_dma_verbose(ide_drive_t *drive)
{
@@ -842,7 +861,7 @@ int ide_set_dma(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
int rc;
- rc = hwif->ide_dma_check(drive);
+ rc = ide_dma_check(drive);
switch(rc) {
case -1: /* DMA needs to be disabled */
@@ -1019,8 +1038,6 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
hwif->ide_dma_on = &__ide_dma_on;
if (!hwif->dma_host_on)
hwif->dma_host_on = &ide_dma_host_on;
- if (!hwif->ide_dma_check)
- hwif->ide_dma_check = &config_drive_for_dma;
if (!hwif->dma_setup)
hwif->dma_setup = &ide_dma_setup;
if (!hwif->dma_exec_cmd)
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 4cece930114..5c8b008676f 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -219,11 +219,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */
/*
- * Right now, all we do is call hwif->ide_dma_check(drive),
+ * Right now, all we do is call ide_set_dma(drive),
* we could be smarter and check for current xfer_speed
* in struct drive etc...
*/
- if (drive->hwif->ide_dma_check == NULL)
+ if (drive->hwif->ide_dma_on == NULL)
break;
drive->hwif->dma_off_quietly(drive);
/*
@@ -322,41 +322,6 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
spin_unlock_irqrestore(&ide_lock, flags);
}
-/*
- * FIXME: probably move this somewhere else, name is bad too :)
- */
-u64 ide_get_error_location(ide_drive_t *drive, char *args)
-{
- u32 high, low;
- u8 hcyl, lcyl, sect;
- u64 sector;
-
- high = 0;
- hcyl = args[5];
- lcyl = args[4];
- sect = args[3];
-
- if (ide_id_has_flush_cache_ext(drive->id)) {
- low = (hcyl << 16) | (lcyl << 8) | sect;
- HWIF(drive)->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
- high = ide_read_24(drive);
- } else {
- u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
- if (cur & 0x40) {
- high = cur & 0xf;
- low = (hcyl << 16) | (lcyl << 8) | sect;
- } else {
- low = hcyl * drive->head * drive->sect;
- low += lcyl * drive->sect;
- low += sect - 1;
- }
- }
-
- sector = ((u64) high << 24) | low;
- return sector;
-}
-EXPORT_SYMBOL(ide_get_error_location);
-
/**
* ide_end_drive_cmd - end an explicit drive command
* @drive: command
@@ -519,7 +484,8 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
}
}
- if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
+ if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ &&
+ (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0)
try_to_flush_leftover_data(drive);
if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
@@ -881,7 +847,8 @@ void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
ide_hwif_t *hwif = drive->hwif;
hwif->nsect = hwif->nleft = rq->nr_sectors;
- hwif->cursg = hwif->cursg_ofs = 0;
+ hwif->cursg_ofs = 0;
+ hwif->cursg = NULL;
}
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index aa738833bed..d4d790f91f9 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -776,7 +776,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
// msleep(50);
#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->ide_dma_check) /* check if host supports DMA */
+ if (hwif->ide_dma_on) /* check if host supports DMA */
hwif->dma_host_off(drive);
#endif
@@ -830,7 +830,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed >= XFER_SW_DMA_0)
hwif->dma_host_on(drive);
- else if (hwif->ide_dma_check) /* check if host supports DMA */
+ else if (hwif->ide_dma_on) /* check if host supports DMA */
hwif->dma_off_quietly(drive);
#endif
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 0e2562f0f74..af86433baed 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -96,21 +96,6 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
return min(speed, mode);
}
-int ide_use_fast_pio(ide_drive_t *drive)
-{
- struct hd_driveid *id = drive->id;
-
- if ((id->capability & 1) && drive->autodma)
- return 1;
-
- if ((id->capability & 8) || (id->field_valid & 2))
- return 1;
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(ide_use_fast_pio);
-
/*
* Standard (generic) timings for PIO modes, from ATA2 specification.
* These timings are for access to the IDE data port register *only*.
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index d1011712601..e294c7415c2 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -835,16 +835,7 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
drive->nice1 = 1;
- /*
- * MAJOR HACK BARF :-/
- *
- * FIXME: chipsets own this cruft!
- */
- /*
- * Move here to prevent module loading clashing.
- */
- // drive->autodma = hwif->autodma;
- if (hwif->ide_dma_check) {
+ if (hwif->ide_dma_on) {
/*
* Force DMAing for the beginning of the check.
* Some chipsets appear to do interesting
@@ -852,10 +843,7 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
* PARANOIA!!!
*/
hwif->dma_off_quietly(drive);
-#ifdef CONFIG_IDEDMA_ONLYDISK
- if (drive->media == ide_disk)
-#endif
- ide_set_dma(drive);
+ ide_set_dma(drive);
}
}
}
@@ -963,7 +951,8 @@ static int ide_init_queue(ide_drive_t *drive)
blk_queue_segment_boundary(q, 0xffff);
if (!hwif->rqsize) {
- if (hwif->no_lba48 || hwif->no_lba48_dma)
+ if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+ (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
hwif->rqsize = 256;
else
hwif->rqsize = 65536;
@@ -1349,7 +1338,7 @@ static int hwif_init(ide_hwif_t *hwif)
if (!hwif->sg_max_nents)
hwif->sg_max_nents = PRD_ENTRIES;
- hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+ hwif->sg_table = kzalloc(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);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index aa06dafb74a..2a3c8d49834 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -45,6 +45,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/bitops.h>
+#include <linux/scatterlist.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -263,6 +264,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ struct scatterlist *cursg = hwif->cursg;
struct page *page;
#ifdef CONFIG_HIGHMEM
unsigned long flags;
@@ -270,8 +272,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
unsigned int offset;
u8 *buf;
- page = sg[hwif->cursg].page;
- offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE;
+ cursg = hwif->cursg;
+ if (!cursg) {
+ cursg = sg;
+ hwif->cursg = sg;
+ }
+
+ page = cursg->page;
+ offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -285,8 +293,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
hwif->nleft--;
hwif->cursg_ofs++;
- if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) {
- hwif->cursg++;
+ if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
+ hwif->cursg = sg_next(hwif->cursg);
hwif->cursg_ofs = 0;
}
@@ -367,6 +375,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
{
+ HWIF(drive)->cursg = NULL;
+
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = rq->special;
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 5c0e4078b5c..961e6c89728 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -100,8 +100,6 @@ static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
int noautodma = 0;
-EXPORT_SYMBOL(noautodma);
-
#ifdef CONFIG_BLK_DEV_IDEACPI
int ide_noacpi = 0;
int ide_noacpitfs = 1;
@@ -136,8 +134,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
hwif->bus_state = BUSSTATE_ON;
- hwif->atapi_dma = 0; /* disable all atapi dma */
-
init_completion(&hwif->gendev_rel_comp);
default_hwif_iops(hwif);
@@ -381,7 +377,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->pio_mask = tmp_hwif->pio_mask;
- hwif->atapi_dma = tmp_hwif->atapi_dma;
hwif->ultra_mask = tmp_hwif->ultra_mask;
hwif->mwdma_mask = tmp_hwif->mwdma_mask;
hwif->swdma_mask = tmp_hwif->swdma_mask;
@@ -418,7 +413,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd;
hwif->dma_start = tmp_hwif->dma_start;
hwif->ide_dma_end = tmp_hwif->ide_dma_end;
- hwif->ide_dma_check = tmp_hwif->ide_dma_check;
hwif->ide_dma_on = tmp_hwif->ide_dma_on;
hwif->dma_off_quietly = tmp_hwif->dma_off_quietly;
hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
@@ -443,7 +437,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->mmio = tmp_hwif->mmio;
hwif->rqsize = tmp_hwif->rqsize;
- hwif->no_lba48 = tmp_hwif->no_lba48;
#ifndef CONFIG_BLK_DEV_IDECS
hwif->irq = tmp_hwif->irq;
@@ -461,7 +454,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->select_data = tmp_hwif->select_data;
hwif->extra_base = tmp_hwif->extra_base;
hwif->extra_ports = tmp_hwif->extra_ports;
- hwif->autodma = tmp_hwif->autodma;
hwif->hwif_data = tmp_hwif->hwif_data;
}
@@ -823,7 +815,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
if (!drive->id || !(drive->id->capability & 1))
goto out;
- if (hwif->ide_dma_check == NULL)
+ if (hwif->ide_dma_on == NULL)
goto out;
err = -EBUSY;
@@ -1276,7 +1268,7 @@ static int __init ide_setup(char *s)
if (!strcmp(s, "ide=nodma")) {
printk(" : Prevented DMA\n");
noautodma = 1;
- return 1;
+ goto obsolete_option;
}
#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
@@ -1310,7 +1302,7 @@ static int __init ide_setup(char *s)
*/
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {
- "none", "noprobe", "nowerr", "cdrom", "minus5",
+ "none", "noprobe", "nowerr", "cdrom", "nodma",
"autotune", "noautotune", "minus8", "swapdata", "bswap",
"noflush", "remap", "remap63", "scsi", NULL };
unit = s[2] - 'a';
@@ -1338,6 +1330,9 @@ static int __init ide_setup(char *s)
drive->ready_stat = 0;
hwif->noprobe = 0;
goto done;
+ case -5: /* nodma */
+ drive->nodma = 1;
+ goto done;
case -6: /* "autotune" */
drive->autotune = IDE_TUNE_AUTO;
goto obsolete_option;
@@ -1399,7 +1394,7 @@ static int __init ide_setup(char *s)
*/
static const char *ide_words[] = {
"noprobe", "serialize", "minus3", "minus4",
- "reset", "dma", "ata66", "minus8", "minus9",
+ "reset", "minus6", "ata66", "minus8", "minus9",
"minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
"dtc2278", "umc8672", "ali14xx", NULL };
hw = s[3] - '0';
@@ -1478,6 +1473,7 @@ static int __init ide_setup(char *s)
case -10: /* minus10 */
case -9: /* minus9 */
case -8: /* minus8 */
+ case -6:
case -4:
case -3:
goto bad_option;
@@ -1492,9 +1488,6 @@ static int __init ide_setup(char *s)
#else
goto bad_hwif;
#endif
- case -6: /* dma */
- hwif->autodma = 1;
- goto obsolete_option;
case -5: /* "reset" */
hwif->reset = 1;
goto obsolete_option;
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 4cdb519f983..e8e360c2619 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -28,7 +28,7 @@
and other provisions required by the GPL. If you do not delete
the provisions above, a recipient may use your version of this
file under either the MPL or the GPL.
-
+
======================================================================*/
#include <linux/module.h>
@@ -327,13 +327,13 @@ failed:
After a card is removed, ide_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
-
+
======================================================================*/
void ide_release(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
-
+
DEBUG(0, "ide_release(0x%p)\n", link);
if (info->ndev) {
@@ -353,11 +353,12 @@ void ide_release(struct pcmcia_device *link)
stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the ide drivers from
talking to the ports.
-
+
======================================================================*/
static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_FUNC_ID(4),
+ PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */
PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000), /* I-O Data CFA */
PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001), /* Mitsubishi CFA */
@@ -366,7 +367,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000), /* Toshiba */
PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000), /* Samsung */
- PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
+ PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000), /* Hitachi */
PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100), /* Viking CFA */
PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200), /* Lexar, Viking CFA */
@@ -384,6 +385,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
+ PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index aebde49365d..2f322d7e881 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -296,7 +296,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
cur_addr += tc;
cur_len -= tc;
}
- sg++;
+ sg = sg_next(sg);
i--;
}
@@ -351,11 +351,18 @@ static int auide_dma_setup(ide_drive_t *drive)
return 0;
}
-static int auide_dma_check(ide_drive_t *drive)
+static u8 auide_mdma_filter(ide_drive_t *drive)
{
- u8 speed = ide_max_dma_mode(drive);
+ /*
+ * FIXME: ->white_list and ->black_list are based on completely bogus
+ * ->ide_dma_check implementation which didn't set neither the host
+ * controller timings nor the device for the desired transfer mode.
+ *
+ * They should be either removed or 0x00 MWDMA mask should be
+ * returned for devices on the ->black_list.
+ */
- if( dbdma_init_done == 0 ){
+ if (dbdma_init_done == 0) {
auide_hwif.white_list = ide_in_drive_list(drive->id,
dma_white_list);
auide_hwif.black_list = ide_in_drive_list(drive->id,
@@ -366,22 +373,11 @@ static int auide_dma_check(ide_drive_t *drive)
}
/* Is the drive in our DMA black list? */
-
- if ( auide_hwif.black_list ) {
- drive->using_dma = 0;
-
- /* Borrowed the warning message from ide-dma.c */
-
+ if (auide_hwif.black_list)
printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",
- drive->name, drive->id->model);
- }
- else
- drive->using_dma = 1;
+ drive->name, drive->id->model);
- if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
- return 0;
-
- return -1;
+ return drive->hwif->mwdma_mask;
}
static int auide_dma_test_irq(ide_drive_t *drive)
@@ -692,7 +688,8 @@ static int au_ide_probe(struct device *dev)
hwif->dma_off_quietly = &auide_dma_off_quietly;
hwif->dma_timeout = &auide_dma_timeout;
- hwif->ide_dma_check = &auide_dma_check;
+ hwif->mdma_filter = &auide_mdma_filter;
+
hwif->dma_exec_cmd = &auide_dma_exec_cmd;
hwif->dma_start = &auide_dma_start;
hwif->ide_dma_end = &auide_dma_end;
@@ -702,20 +699,12 @@ static int au_ide_probe(struct device *dev)
hwif->dma_host_on = &auide_dma_host_on;
hwif->dma_lost_irq = &auide_dma_lost_irq;
hwif->ide_dma_on = &auide_dma_on;
-
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
- hwif->atapi_dma = 1;
-
#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
- hwif->autodma = 0;
hwif->channel = 0;
hwif->hold = 1;
hwif->select_data = 0; /* no chipset-specific code */
hwif->config_data = 0; /* no chipset-specific code */
- hwif->drives[0].autodma = 0;
hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
#endif
hwif->drives[0].no_io_32bit = 1;
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index d6cb2d5143c..b3dc12a70d5 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.24 May 24, 2007
+ * linux/drivers/ide/pci/aec62xx.c Version 0.26 Sep 1, 2007
*
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
@@ -141,17 +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 int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static void aec62xx_dma_lost_irq (ide_drive_t *drive)
{
switch (HWIF(drive)->pci_dev->device) {
@@ -195,114 +184,78 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
- u8 reg54 = 0, mask = hwif->channel ? 0xf0 : 0x0f;
- unsigned long flags;
hwif->set_pio_mode = &aec_set_pio_mode;
- if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
- if(hwif->mate)
- hwif->mate->serialized = hwif->serialized = 1;
+ if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
hwif->set_dma_mode = &aec6210_set_mode;
- } else
+ else
hwif->set_dma_mode = &aec6260_set_mode;
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
-
- hwif->ultra_mask = hwif->cds->udma_mask;
- hwif->mwdma_mask = 0x07;
- hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate;
hwif->dma_lost_irq = &aec62xx_dma_lost_irq;
- if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
- spin_lock_irqsave(&ide_lock, flags);
- pci_read_config_byte (dev, 0x54, &reg54);
- pci_write_config_byte(dev, 0x54, (reg54 & ~mask));
- spin_unlock_irqrestore(&ide_lock, flags);
- } else if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
+ if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
+ return;
+
+ if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
hwif->cbl = (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
-}
-
-static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
-{
- return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d)
-{
- unsigned long dma_base = pci_resource_start(dev, 4);
-
- if (inb(dma_base + 2) & 0x10) {
- d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ?
- "AEC6880R" : "AEC6880";
- d->udma_mask = 0x7f; /* udma0-6 */
- }
-
- return ide_setup_pci_device(dev, d);
}
static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
{ /* 0 */
.name = "AEC6210",
- .init_setup = init_setup_aec62xx,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .autodma = AUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = OFF_BOARD,
+ .host_flags = IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
- .udma_mask = 0x07, /* udma0-2 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
},{ /* 1 */
.name = "AEC6260",
- .init_setup = init_setup_aec62xx,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .autodma = NOAUTODMA,
- .bootable = OFF_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
+ IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
- .udma_mask = 0x1f, /* udma0-4 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
},{ /* 2 */
.name = "AEC6260R",
- .init_setup = init_setup_aec62xx,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .autodma = AUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = NEVER_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA,
.pio_mask = ATA_PIO4,
- .udma_mask = 0x1f, /* udma0-4 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
},{ /* 3 */
.name = "AEC6280",
- .init_setup = init_setup_aec6x80,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
- .udma_mask = 0x3f, /* udma0-5 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
},{ /* 4 */
.name = "AEC6280R",
- .init_setup = init_setup_aec6x80,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .autodma = AUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = OFF_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
- .udma_mask = 0x3f, /* udma0-5 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
}
};
@@ -320,17 +273,29 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t d = aec62xx_chipsets[id->driver_data];
+ ide_pci_device_t d;
+ u8 idx = id->driver_data;
+
+ d = aec62xx_chipsets[idx];
+
+ if (idx == 3 || idx == 4) {
+ unsigned long dma_base = pci_resource_start(dev, 4);
+
+ if (inb(dma_base + 2) & 0x10) {
+ d.name = (idx == 4) ? "AEC6880R" : "AEC6880";
+ d.udma_mask = ATA_UDMA6;
+ }
+ }
- return d.init_setup(dev, &d);
+ return ide_setup_pci_device(dev, &d);
}
-static struct pci_device_id aec62xx_pci_tbl[] = {
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
- { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+static const struct pci_device_id aec62xx_pci_tbl[] = {
+ { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 },
+ { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 },
+ { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 },
+ { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 },
+ { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl);
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 0b83443bf25..8ee2b48d105 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.26 Jul 14 2007
+ * linux/drivers/ide/pci/alim15x3.c Version 0.27 Aug 27 2007
*
* Copyright (C) 1998-2000 Michel Aubry, Maintainer
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -437,26 +437,6 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * ali15x3_config_drive_for_dma - configure for DMA
- * @drive: drive to configure
- *
- * Configure a drive for DMA operation. If DMA is not possible we
- * drop the drive into PIO mode instead.
- */
-
-static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
-
- return -1;
-}
-
-/**
* ali15x3_dma_setup - begin a DMA phase
* @drive: target device
*
@@ -680,52 +660,39 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
{
- hwif->autodma = 0;
hwif->set_pio_mode = &ali_set_pio_mode;
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 */
- hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0;
+ if (m5229_revision <= 0xC4)
+ hwif->host_flags |= IDE_HFLAG_NO_LBA48_DMA;
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
/*
* check in ->init_dma guarantees m5229_revision >= 0x20 here
*/
- if (m5229_revision > 0x20)
- hwif->atapi_dma = 1;
+ 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 = 0x07; /* udma0-2 */
+ hwif->ultra_mask = ATA_UDMA2;
else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
- hwif->ultra_mask = 0x1f; /* udma0-4 */
+ hwif->ultra_mask = ATA_UDMA4;
else if (m5229_revision == 0xC4)
- hwif->ultra_mask = 0x3f; /* udma0-5 */
+ hwif->ultra_mask = ATA_UDMA5;
else
- hwif->ultra_mask = 0x7f; /* udma0-6 */
+ hwif->ultra_mask = ATA_UDMA6;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
-
- hwif->ide_dma_check = &ali15x3_config_drive_for_dma;
hwif->dma_setup = &ali15x3_dma_setup;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_ali15x3(hwif);
-
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
/**
@@ -804,9 +771,10 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
.init_chipset = init_chipset_ali15x3,
.init_hwif = init_hwif_ali15x3,
.init_dma = init_dma_ali15x3,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
};
/**
@@ -836,9 +804,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
}
-static struct pci_device_id alim15x3_pci_tbl[] = {
- { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+static const struct pci_device_id alim15x3_pci_tbl[] = {
+ { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 },
+ { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl);
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 6ff4089a237..7cafefbf6c1 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -1,5 +1,5 @@
/*
- * Version 2.23
+ * Version 2.24
*
* AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
* IDE driver for Linux.
@@ -28,9 +28,6 @@
#include "ide-timing.h"
-#define DISPLAY_AMD_TIMINGS
-
-#define AMD_IDE_ENABLE (0x00 + amd_config->base)
#define AMD_IDE_CONFIG (0x01 + amd_config->base)
#define AMD_CABLE_DETECT (0x02 + amd_config->base)
#define AMD_DRIVE_TIMING (0x08 + amd_config->base)
@@ -88,118 +85,6 @@ static char *amd_dma[] = { "16", "25", "33", "44", "66", "100", "133" };
static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 };
/*
- * AMD /proc entry.
- */
-
-#ifdef CONFIG_IDE_PROC_FS
-
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 amd74xx_proc;
-
-static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 15 };
-static unsigned long amd_base;
-static struct pci_dev *bmide_dev;
-extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
-
-#define amd_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
-#define amd_print_drive(name, format, arg...)\
- p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
-
-static int amd74xx_get_info(char *buffer, char **addr, off_t offset, int count)
-{
- int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
- uen[4], udma[4], active8b[4], recover8b[4];
- struct pci_dev *dev = bmide_dev;
- unsigned int v, u, i;
- unsigned short c, w;
- unsigned char t;
- int len;
- char *p = buffer;
-
- amd_print("----------AMD BusMastering IDE Configuration----------------");
-
- amd_print("Driver Version: 2.13");
- amd_print("South Bridge: %s", pci_name(bmide_dev));
-
- amd_print("Revision: IDE %#x", dev->revision);
- amd_print("Highest DMA rate: UDMA%s", amd_dma[fls(amd_config->udma_mask) - 1]);
-
- amd_print("BM-DMA base: %#lx", amd_base);
- amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10);
-
- amd_print("-----------------------Primary IDE-------Secondary IDE------");
-
- pci_read_config_byte(dev, AMD_IDE_CONFIG, &t);
- amd_print("Prefetch Buffer: %10s%20s", (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
- amd_print("Post Write Buffer: %10s%20s", (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
- pci_read_config_byte(dev, AMD_IDE_ENABLE, &t);
- amd_print("Enabled: %10s%20s", (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
-
- c = inb(amd_base + 0x02) | (inb(amd_base + 0x0a) << 8);
- amd_print("Simplex only: %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
-
- amd_print("Cable Type: %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w");
-
- if (!amd_clock)
- return p - buffer;
-
- amd_print("-------------------drive0----drive1----drive2----drive3-----");
-
- pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t);
- pci_read_config_dword(dev, AMD_DRIVE_TIMING, &v);
- pci_read_config_word(dev, AMD_8BIT_TIMING, &w);
- pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
-
- for (i = 0; i < 4; i++) {
- setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1;
- recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
- active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
- active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
- recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1;
-
- udma[i] = amd_udma2cyc[((u >> ((3 - i) << 3)) & 0x7)];
- uen[i] = ((u >> ((3 - i) << 3)) & 0x40) ? 1 : 0;
- den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
-
- if (den[i] && uen[i] && udma[i] == 1) {
- speed[i] = amd_clock * 3;
- cycle[i] = 666666 / amd_clock;
- continue;
- }
-
- if (den[i] && uen[i] && udma[i] == 15) {
- speed[i] = amd_clock * 4;
- cycle[i] = 500000 / amd_clock;
- continue;
- }
-
- speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2);
- cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2;
- }
-
- amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
-
- amd_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / amd_clock);
- amd_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / amd_clock);
- amd_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / amd_clock);
- amd_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / amd_clock);
- amd_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / amd_clock);
- amd_print_drive("Cycle Time: ", "%8dns", cycle[i]);
- amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
-
- /* hoping p - buffer is less than 4K... */
- len = (p - buffer) - offset;
- *addr = buffer + offset;
-
- return len > count ? count : len;
-}
-
-#endif
-
-/*
* amd_set_speed() writes timing values to the chipset registers
*/
@@ -264,16 +149,6 @@ static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
amd_set_drive(drive, XFER_PIO_0 + pio);
}
-static int amd74xx_ide_dma_check(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
-
- return -1;
-}
-
/*
* The initialization callback. Here we determine the IDE chip type
* and initialize its drive independent registers.
@@ -358,24 +233,10 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
* Print the boot message.
*/
- pci_read_config_byte(dev, PCI_REVISION_ID, &t);
printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n",
amd_chipset->name, pci_name(dev), dev->revision,
amd_dma[fls(amd_config->udma_mask) - 1]);
-/*
- * Register /proc/ide/amd74xx entry
- */
-
-#if defined(DISPLAY_AMD_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
- if (!amd74xx_proc) {
- amd_base = pci_resource_start(dev, 4);
- bmide_dev = dev;
- ide_pci_create_host_proc("amd74xx", amd74xx_get_info);
- amd74xx_proc = 1;
- }
-#endif /* DISPLAY_AMD_TIMINGS && CONFIG_IDE_PROC_FS */
-
return dev->irq;
}
@@ -386,27 +247,20 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
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->autodma = 0;
-
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;
- hwif->drives[i].autotune = 1;
- hwif->drives[i].dn = hwif->channel * 2 + i;
}
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
-
hwif->ultra_mask = amd_config->udma_mask;
- hwif->mwdma_mask = 0x07;
- if ((amd_config->flags & AMD_BAD_SWDMA) == 0)
- hwif->swdma_mask = 0x07;
+ if (amd_config->flags & AMD_BAD_SWDMA)
+ hwif->swdma_mask = 0x00;
if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
if ((amd_80w >> hwif->channel) & 1)
@@ -414,12 +268,6 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
else
hwif->cbl = ATA_CBL_PATA40;
}
-
- hwif->ide_dma_check = &amd74xx_ide_dma_check;
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
#define DECLARE_AMD_DEV(name_str) \
@@ -427,13 +275,14 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.name = name_str, \
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
- .autodma = AUTODMA, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
- .bootable = ON_BOARD, \
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \
- | IDE_HFLAG_PIO_NO_DOWNGRADE \
- | IDE_HFLAG_POST_SET_MODE, \
+ .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, \
}
#define DECLARE_NV_DEV(name_str) \
@@ -441,13 +290,14 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.name = name_str, \
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
- .autodma = AUTODMA, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
- .bootable = ON_BOARD, \
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \
- | IDE_HFLAG_PIO_NO_DOWNGRADE \
- | IDE_HFLAG_POST_SET_MODE, \
+ .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 ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
@@ -489,34 +339,34 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_
return ide_setup_pci_device(dev, amd_chipset);
}
-static struct pci_device_id amd74xx_pci_tbl[] = {
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
+static const struct pci_device_id amd74xx_pci_tbl[] = {
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7409), 1 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7411), 2 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_OPUS_7441), 3 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_8111_IDE), 4 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE), 5 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE), 6 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE), 7 },
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA), 8 },
#endif
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE), 9 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE), 10 },
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA), 11 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2), 12 },
#endif
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21 },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE), 13 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE), 14 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE), 15 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE), 16 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE), 17 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE), 18 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE), 19 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE), 20 },
+ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE), 21 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 22 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 0eb97f021d3..30784305307 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/atiixp.c Version 0.02 Jun 16 2007
+ * linux/drivers/ide/pci/atiixp.c Version 0.03 Aug 3 2007
*
* Copyright (C) 2003 ATI Inc. <hyu@ati.com>
* Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
@@ -47,43 +47,6 @@ static int save_mdma_mode[4];
static DEFINE_SPINLOCK(atiixp_lock);
-/**
- * atiixp_dma_2_pio - return the PIO mode matching DMA
- * @xfer_rate: transfer speed
- *
- * Returns the nearest equivalent PIO timing for the PIO or DMA
- * mode requested by the controller.
- */
-
-static u8 atiixp_dma_2_pio(u8 xfer_rate) {
- switch(xfer_rate) {
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- case XFER_MW_DMA_2:
- case XFER_PIO_4:
- return 4;
- case XFER_MW_DMA_1:
- case XFER_PIO_3:
- return 3;
- case XFER_SW_DMA_2:
- case XFER_PIO_2:
- return 2;
- case XFER_MW_DMA_0:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
- case XFER_PIO_1:
- case XFER_PIO_0:
- case XFER_PIO_SLOW:
- default:
- return 0;
- }
-}
-
static void atiixp_dma_host_on(ide_drive_t *drive)
{
struct pci_dev *dev = drive->hwif->pci_dev;
@@ -169,7 +132,9 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
u32 tmp32;
u16 tmp16;
- u8 pio;
+
+ if (speed < XFER_MW_DMA_0)
+ return;
spin_lock_irqsave(&atiixp_lock, flags);
@@ -191,34 +156,6 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
spin_unlock_irqrestore(&atiixp_lock, flags);
-
- if (speed >= XFER_SW_DMA_0)
- pio = atiixp_dma_2_pio(speed);
- else
- pio = speed - XFER_PIO_0;
-
- atiixp_set_pio_mode(drive, pio);
-}
-
-/**
- * atiixp_dma_check - set up an IDE device
- * @drive: IDE drive to configure
- *
- * Set up the ATIIXP interface for the best available speed on this
- * interface, preferring DMA to PIO.
- */
-
-static int atiixp_dma_check(ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
}
/**
@@ -235,23 +172,12 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
u8 ch = hwif->channel;
struct pci_dev *pdev = hwif->pci_dev;
- if (!hwif->irq)
- hwif->irq = ch ? 15 : 14;
-
- hwif->autodma = 0;
hwif->set_pio_mode = &atiixp_set_pio_mode;
hwif->set_dma_mode = &atiixp_set_dma_mode;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x3f;
- hwif->mwdma_mask = 0x06;
- hwif->swdma_mask = 0x04;
-
pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
@@ -261,12 +187,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->dma_host_on = &atiixp_dma_host_on;
hwif->dma_host_off = &atiixp_dma_host_off;
- hwif->ide_dma_check = &atiixp_dma_check;
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->drives[1].autodma = hwif->autodma;
- hwif->drives[0].autodma = hwif->autodma;
}
@@ -274,18 +194,20 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
{ /* 0 */
.name = "ATIIXP",
.init_hwif = init_hwif_atiixp,
- .autodma = AUTODMA,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
},{ /* 1 */
.name = "SB600_PATA",
.init_hwif = init_hwif_atiixp,
- .autodma = AUTODMA,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
},
};
@@ -303,12 +225,12 @@ static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_devic
return ide_setup_pci_device(dev, &atiixp_pci_info[id->driver_data]);
}
-static struct pci_device_id atiixp_pci_tbl[] = {
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id atiixp_pci_tbl[] = {
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), 0 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), 0 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), 0 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), 1 },
+ { PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index d50f15e34b8..adee2ef6fd7 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -330,17 +330,6 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
(void) pci_write_config_byte(dev, pciU, regU);
}
-static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static int cmd648_ide_dma_end (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -450,11 +439,8 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
u8 mrdmode = 0;
if (dev->device == PCI_DEVICE_ID_CMD_646) {
- u8 rev = 0;
- pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
-
- switch (rev) {
+ switch (dev->revision) {
case 0x07:
case 0x05:
printk("%s: UltraDMA capable\n", name);
@@ -516,22 +502,13 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif)
static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
- u8 rev = 0;
-
- pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
hwif->set_pio_mode = &cmd64x_set_pio_mode;
hwif->set_dma_mode = &cmd64x_set_dma_mode;
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x07;
- hwif->ultra_mask = hwif->cds->udma_mask;
-
/*
* UltraDMA only supported on PCI646U and PCI646U2, which
* correspond to revisions 0x03, 0x05 and 0x07 respectively.
@@ -544,11 +521,9 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
*
* So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
*/
- if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5)
+ if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5)
hwif->ultra_mask = 0x00;
- hwif->ide_dma_check = &cmd64x_config_drive_for_dma;
-
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_cmd64x(hwif);
@@ -561,10 +536,10 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
break;
case PCI_DEVICE_ID_CMD_646:
hwif->chipset = ide_cmd646;
- if (rev == 0x01) {
+ if (dev->revision == 0x01) {
hwif->ide_dma_end = &cmd646_1_ide_dma_end;
break;
- } else if (rev >= 0x03)
+ } else if (dev->revision >= 0x03)
goto alt_irq_bits;
/* fall thru */
default:
@@ -572,93 +547,70 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq;
break;
}
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
-}
-
-static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d)
-{
- return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d)
-{
- /*
- * The original PCI0646 didn't have the primary channel enable bit,
- * it appeared starting with PCI0646U (i.e. revision ID 3).
- */
- if (dev->revision < 3)
- d->enablebits[0].reg = 0;
-
- return ide_setup_pci_device(dev, d);
}
static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
{ /* 0 */
.name = "CMD643",
- .init_setup = init_setup_cmd64x,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .autodma = AUTODMA,
.enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* no udma */
},{ /* 1 */
.name = "CMD646",
- .init_setup = init_setup_cmd646,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .autodma = AUTODMA,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
- .udma_mask = 0x07, /* udma0-2 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
},{ /* 2 */
.name = "CMD648",
- .init_setup = init_setup_cmd64x,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .autodma = AUTODMA,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
- .udma_mask = 0x1f, /* udma0-4 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
},{ /* 3 */
.name = "CMD649",
- .init_setup = init_setup_cmd64x,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .autodma = AUTODMA,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
- .udma_mask = 0x3f, /* udma0-5 */
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
}
};
-/*
- * We may have to modify enablebits for PCI0646, so we'd better pass
- * a local copy of the ide_pci_device_t structure down the call chain...
- */
static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t d = cmd64x_chipsets[id->driver_data];
+ ide_pci_device_t d;
+ u8 idx = id->driver_data;
+
+ d = cmd64x_chipsets[idx];
+
+ /*
+ * The original PCI0646 didn't have the primary channel enable bit,
+ * it appeared starting with PCI0646U (i.e. revision ID 3).
+ */
+ if (idx == 1 && dev->revision < 3)
+ d.enablebits[0].reg = 0;
- return d.init_setup(dev, &d);
+ return ide_setup_pci_device(dev, &d);
}
-static struct pci_device_id cmd64x_pci_tbl[] = {
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+static const struct pci_device_id cmd64x_pci_tbl[] = {
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 2 },
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 3 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, cmd64x_pci_tbl);
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index fbce90048ae..aa98e817d38 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -105,27 +105,6 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
cs5520_set_pio_mode(drive, 0);
}
-static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
-{
- /* Tune the drive for PIO modes up to PIO 4 */
- ide_set_max_pio(drive);
-
- /* Then tell the core to use DMA operations */
- return 0;
-}
-
-/*
- * We provide a callback for our nonstandard DMA location
- */
-
-static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
-{
- unsigned long bmide = pci_resource_start(dev, 2); /* Not the usual 4 */
- if(hwif->mate && hwif->mate->dma_base) /* Second channel at primary + 8 */
- bmide += 8;
- ide_setup_dma(hwif, bmide, 8);
-}
-
/*
* We wrap the DMA activate to set the vdma flag. This is needed
* so that the IDE DMA layer issues PIO not DMA commands over the
@@ -134,6 +113,7 @@ static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_
static int cs5520_dma_on(ide_drive_t *drive)
{
+ /* ATAPI is harder so leave it for now */
drive->vdma = 1;
return 0;
}
@@ -143,35 +123,21 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
hwif->set_pio_mode = &cs5520_set_pio_mode;
hwif->set_dma_mode = &cs5520_set_dma_mode;
- if (hwif->dma_base == 0) {
- hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
- hwif->ide_dma_check = &cs5520_config_drive_xfer_rate;
hwif->ide_dma_on = &cs5520_dma_on;
-
- /* ATAPI is harder so leave it for now */
- hwif->atapi_dma = 0;
- hwif->ultra_mask = 0;
- hwif->swdma_mask = 0;
- hwif->mwdma_mask = 0;
-
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
#define DECLARE_CS_DEV(name_str) \
{ \
.name = name_str, \
- .init_setup_dma = cs5520_init_setup_dma, \
.init_hwif = init_hwif_cs5520, \
- .autodma = AUTODMA, \
- .bootable = ON_BOARD, \
- .host_flags = IDE_HFLAG_ISA_PORTS, \
+ .host_flags = IDE_HFLAG_ISA_PORTS | \
+ IDE_HFLAG_CS5520 | \
+ IDE_HFLAG_VDMA | \
+ IDE_HFLAG_NO_ATAPI_DMA | \
+ IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
}
@@ -233,9 +199,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
return 0;
}
-static struct pci_device_id cs5520_pci_tbl[] = {
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+static const struct pci_device_id cs5520_pci_tbl[] = {
+ { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), 0 },
+ { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), 1 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, cs5520_pci_tbl);
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index e4121577cef..ba0c6eba024 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.74 Jul 28 2007
+ * linux/drivers/ide/pci/cs5530.c Version 0.76 Aug 3 2007
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2000 Mark Lord <mlord@pobox.com>
@@ -104,22 +104,6 @@ out:
return mask;
}
-/**
- * cs5530_config_dma - set DMA/UDMA mode
- * @drive: drive to tune
- *
- * cs5530_config_dma() handles setting of DMA/UDMA mode
- * for both the chipset and drive.
- */
-
-static int cs5530_config_dma(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- return 1;
-}
-
static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
unsigned long basereg;
@@ -260,54 +244,33 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
{
unsigned long basereg;
u32 d0_timings;
- hwif->autodma = 0;
-
- if (hwif->mate)
- hwif->serialized = hwif->mate->serialized = 1;
hwif->set_pio_mode = &cs5530_set_pio_mode;
hwif->set_dma_mode = &cs5530_set_dma_mode;
basereg = CS5530_BASEREG(hwif);
d0_timings = inl(basereg + 0);
- if (CS5530_BAD_PIO(d0_timings)) {
- /* PIO timings not initialized? */
+ if (CS5530_BAD_PIO(d0_timings))
outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 0);
- if (!hwif->drives[0].autotune)
- hwif->drives[0].autotune = 1;
- /* needs autotuning later */
- }
- if (CS5530_BAD_PIO(inl(basereg + 8))) {
- /* PIO timings not initialized? */
+ if (CS5530_BAD_PIO(inl(basereg + 8)))
outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
- if (!hwif->drives[1].autotune)
- hwif->drives[1].autotune = 1;
- /* needs autotuning later */
- }
if (hwif->dma_base == 0)
return;
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x07;
- hwif->mwdma_mask = 0x07;
-
hwif->udma_filter = cs5530_udma_filter;
- hwif->ide_dma_check = &cs5530_config_dma;
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t cs5530_chipset __devinitdata = {
.name = "CS5530",
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_POST_SET_MODE |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
- .host_flags = IDE_HFLAG_POST_SET_MODE,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
};
static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -315,8 +278,8 @@ static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_devic
return ide_setup_pci_device(dev, &cs5530_chipset);
}
-static struct pci_device_id cs5530_pci_tbl[] = {
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id cs5530_pci_tbl[] = {
+ { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, cs5530_pci_tbl);
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 257865778f9..5ac82ffa5c0 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -84,7 +84,7 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
/* Set the PIO timings */
if ((speed & XFER_MODE) == XFER_PIO) {
- ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1];
+ ide_drive_t *pair = ide_get_paired_drive(drive);
u8 cmd, pioa;
cmd = pioa = speed - XFER_PIO_0;
@@ -157,19 +157,6 @@ static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
cs5535_set_speed(drive, XFER_PIO_0 + pio);
}
-static int cs5535_dma_check(ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
{
u8 bit;
@@ -190,37 +177,23 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
*/
static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
{
- hwif->autodma = 0;
-
hwif->set_pio_mode = &cs5535_set_pio_mode;
hwif->set_dma_mode = &cs5535_set_dma_mode;
- hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
-
if (hwif->dma_base == 0)
return;
- hwif->ide_dma_check = &cs5535_dma_check;
-
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x1F;
- hwif->mwdma_mask = 0x07;
-
hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
-
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->drives[1].autodma = hwif->drives[0].autodma = hwif->autodma;
}
static ide_pci_device_t cs5535_chipset __devinitdata = {
.name = "CS5535",
.init_hwif = init_hwif_cs5535,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
};
static int __devinit cs5535_init_one(struct pci_dev *dev,
@@ -229,10 +202,8 @@ static int __devinit cs5535_init_one(struct pci_dev *dev,
return ide_setup_pci_device(dev, &cs5535_chipset);
}
-static struct pci_device_id cs5535_pci_tbl[] =
-{
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
- PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id cs5535_pci_tbl[] = {
+ { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_CS5535_IDE), 0 },
{ 0, },
};
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index dc278025d31..efc20bd97fd 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/cy82c693.c Version 0.40 Sep. 10, 2002
+ * linux/drivers/ide/pci/cy82c693.c Version 0.41 Aug 27, 2007
*
* Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
@@ -428,26 +428,13 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
*/
static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
{
- hwif->autodma = 0;
-
hwif->chipset = ide_cy82c693;
hwif->set_pio_mode = &cy82c693_set_pio_mode;
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
-
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x04;
- hwif->swdma_mask = 0x04;
hwif->ide_dma_on = &cy82c693_ide_dma_on;
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static __devinitdata ide_hwif_t *primary;
@@ -467,10 +454,11 @@ static ide_pci_device_t cy82c693_chipset __devinitdata = {
.init_chipset = init_chipset_cy82c693,
.init_iops = init_iops_cy82c693,
.init_hwif = init_hwif_cy82c693,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .swdma_mask = ATA_SWDMA2_ONLY,
+ .mwdma_mask = ATA_MWDMA2_ONLY,
};
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -489,8 +477,8 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
return ret;
}
-static struct pci_device_id cy82c693_pci_tbl[] = {
- { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id cy82c693_pci_tbl[] = {
+ { PCI_VDEVICE(CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, cy82c693_pci_tbl);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 48caa468b76..51165832e7f 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -65,109 +65,65 @@ static void __devinit init_hwif_generic (ide_hwif_t *hwif)
default:
break;
}
-
- if (!(hwif->dma_base))
- return;
-
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x7f;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
-#if 0
- /* Logic to add back later on */
-
- if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
- ide_pci_device_t *unknown = unknown_chipset;
- init_setup_unknown(dev, unknown);
- return 1;
+#define DECLARE_GENERIC_PCI_DEV(name_str, dma_setting) \
+ { \
+ .name = name_str, \
+ .init_hwif = init_hwif_generic, \
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
+ dma_setting | \
+ IDE_HFLAG_BOOTABLE, \
+ .swdma_mask = ATA_SWDMA2, \
+ .mwdma_mask = ATA_MWDMA2, \
+ .udma_mask = ATA_UDMA6, \
}
- return 0;
-#endif
static ide_pci_device_t generic_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "Unknown",
- .init_hwif = init_hwif_generic,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 1 */
+ /* 0 */ DECLARE_GENERIC_PCI_DEV("Unknown", 0),
+
+ { /* 1 */
.name = "NS87410",
.init_hwif = init_hwif_generic,
- .autodma = AUTODMA,
.enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
- .bootable = ON_BOARD,
- },{ /* 2 */
- .name = "SAMURAI",
- .init_hwif = init_hwif_generic,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 3 */
- .name = "HT6565",
- .init_hwif = init_hwif_generic,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 4 */
- .name = "UM8673F",
- .init_hwif = init_hwif_generic,
- .autodma = NODMA,
- .bootable = ON_BOARD,
- },{ /* 5 */
- .name = "UM8886A",
- .init_hwif = init_hwif_generic,
- .autodma = NODMA,
- .bootable = ON_BOARD,
- },{ /* 6 */
- .name = "UM8886BF",
- .init_hwif = init_hwif_generic,
- .autodma = NODMA,
- .bootable = ON_BOARD,
- },{ /* 7 */
- .name = "HINT_IDE",
- .init_hwif = init_hwif_generic,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- },{ /* 8 */
- .name = "VIA_IDE",
- .init_hwif = init_hwif_generic,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 9 */
- .name = "OPTI621V",
- .init_hwif = init_hwif_generic,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 10 */
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_BOOTABLE,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
+ },
+
+ /* 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),
+ /* 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,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- },{ /* 11 */
- .name = "Piccolo0102",
- .init_hwif = init_hwif_generic,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 12 */
- .name = "Piccolo0103",
- .init_hwif = init_hwif_generic,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 13 */
- .name = "Piccolo0105",
- .init_hwif = init_hwif_generic,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
- },{ /* 14 */
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_OFF_BOARD,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
+ },
+
+ /* 11 */ DECLARE_GENERIC_PCI_DEV("Piccolo0102", IDE_HFLAG_NO_AUTODMA),
+ /* 12 */ DECLARE_GENERIC_PCI_DEV("Piccolo0103", IDE_HFLAG_NO_AUTODMA),
+ /* 13 */ DECLARE_GENERIC_PCI_DEV("Piccolo0105", IDE_HFLAG_NO_AUTODMA),
+
+ { /* 14 */
.name = "Revolution",
.init_hwif = init_hwif_generic,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_OFF_BOARD,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
}
};
@@ -226,25 +182,28 @@ out:
return ret;
}
-static struct pci_device_id generic_pci_tbl[] = {
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
- { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
- { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
- { PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
- { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+static const struct pci_device_id generic_pci_tbl[] = {
+ { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87410), 1 },
+ { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE), 2 },
+ { PCI_VDEVICE(HOLTEK, PCI_DEVICE_ID_HOLTEK_6565), 3 },
+ { PCI_VDEVICE(UMC, PCI_DEVICE_ID_UMC_UM8673F), 4 },
+ { PCI_VDEVICE(UMC, PCI_DEVICE_ID_UMC_UM8886A), 5 },
+ { PCI_VDEVICE(UMC, PCI_DEVICE_ID_UMC_UM8886BF), 6 },
+ { PCI_VDEVICE(HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE), 7 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C561), 8 },
+ { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C558), 9 },
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10},
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237_SATA), 10 },
#endif
- { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11},
- { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12},
- { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13},
- { PCI_VENDOR_ID_NETCELL,PCI_DEVICE_ID_REVOLUTION, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14},
- /* Must come last. If you add entries adjust this table appropriately and the init_one code */
- { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0},
+ { PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO), 11 },
+ { PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), 12 },
+ { PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), 13 },
+ { PCI_VDEVICE(NETCELL, PCI_DEVICE_ID_REVOLUTION), 14 },
+ /*
+ * Must come last. If you add entries adjust
+ * this table and generic_chipsets[] appropriately.
+ */
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, generic_pci_tbl);
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 218852aaf22..67af1a7dde3 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -80,19 +80,6 @@ static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio)
hpt34x_set_mode(drive, XFER_PIO_0 + pio);
}
-static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return -1;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
/*
* If the BIOS does not set the IO base addaress to XX00, 343 will fail.
*/
@@ -138,60 +125,51 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha
static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
{
- u16 pcicmd = 0;
-
- hwif->autodma = 0;
-
hwif->set_pio_mode = &hpt34x_set_pio_mode;
hwif->set_dma_mode = &hpt34x_set_mode;
+}
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
- pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
-
- if (!hwif->dma_base)
- return;
-
+static ide_pci_device_t hpt34x_chipsets[] __devinitdata = {
+ { /* 0 */
+ .name = "HPT343",
+ .init_chipset = init_chipset_hpt34x,
+ .init_hwif = init_hwif_hpt34x,
+ .extra = 16,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_NO_AUTODMA,
+ .pio_mask = ATA_PIO5,
+ },
+ { /* 1 */
+ .name = "HPT345",
+ .init_chipset = init_chipset_hpt34x,
+ .init_hwif = init_hwif_hpt34x,
+ .extra = 16,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_NO_AUTODMA |
+ IDE_HFLAG_OFF_BOARD,
+ .pio_mask = ATA_PIO5,
#ifdef CONFIG_HPT34X_AUTODMA
- hwif->ultra_mask = 0x07;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
#endif
-
- hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate;
- if (!noautodma)
- hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
-}
-
-static ide_pci_device_t hpt34x_chipset __devinitdata = {
- .name = "HPT34X",
- .init_chipset = init_chipset_hpt34x,
- .init_hwif = init_hwif_hpt34x,
- .autodma = NOAUTODMA,
- .bootable = NEVER_BOARD,
- .extra = 16,
- .pio_mask = ATA_PIO5,
+ }
};
static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &hpt34x_chipset;
- static char *chipset_names[] = {"HPT343", "HPT345"};
+ ide_pci_device_t *d;
u16 pcicmd = 0;
pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
- d->name = chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
- d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
+ d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
return ide_setup_pci_device(dev, d);
}
-static struct pci_device_id hpt34x_pci_tbl[] = {
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id hpt34x_pci_tbl[] = {
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 8812a9bb032..18f5b7ddaee 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,9 +1,10 @@
/*
- * linux/drivers/ide/pci/hpt366.c Version 1.13 Sep 29, 2007
+ * linux/drivers/ide/pci/hpt366.c Version 1.20 Oct 1, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
+ * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz
* Portions Copyright (C) 2005-2007 MontaVista Software, Inc.
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
@@ -393,8 +394,9 @@ enum ata_clock {
*/
struct hpt_info {
+ char *chip_name; /* Chip name */
u8 chip_type; /* Chip type */
- u8 max_ultra; /* Max. UltraDMA mode allowed */
+ u8 udma_mask; /* Allowed UltraDMA modes mask. */
u8 dpll_clk; /* DPLL clock in MHz */
u8 pci_clk; /* PCI clock in MHz */
u32 **settings; /* Chipset settings table */
@@ -432,78 +434,89 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
};
static struct hpt_info hpt36x __devinitdata = {
+ .chip_name = "HPT36x",
.chip_type = HPT36x,
- .max_ultra = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2,
+ .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
.dpll_clk = 0, /* no DPLL */
.settings = hpt36x_settings
};
static struct hpt_info hpt370 __devinitdata = {
+ .chip_name = "HPT370",
.chip_type = HPT370,
- .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4,
+ .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
.dpll_clk = 48,
.settings = hpt37x_settings
};
static struct hpt_info hpt370a __devinitdata = {
+ .chip_name = "HPT370A",
.chip_type = HPT370A,
- .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4,
+ .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
.dpll_clk = 48,
.settings = hpt37x_settings
};
static struct hpt_info hpt374 __devinitdata = {
+ .chip_name = "HPT374",
.chip_type = HPT374,
- .max_ultra = 5,
+ .udma_mask = ATA_UDMA5,
.dpll_clk = 48,
.settings = hpt37x_settings
};
static struct hpt_info hpt372 __devinitdata = {
+ .chip_name = "HPT372",
.chip_type = HPT372,
- .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 55,
.settings = hpt37x_settings
};
static struct hpt_info hpt372a __devinitdata = {
+ .chip_name = "HPT372A",
.chip_type = HPT372A,
- .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 66,
.settings = hpt37x_settings
};
static struct hpt_info hpt302 __devinitdata = {
+ .chip_name = "HPT302",
.chip_type = HPT302,
- .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 66,
.settings = hpt37x_settings
};
static struct hpt_info hpt371 __devinitdata = {
+ .chip_name = "HPT371",
.chip_type = HPT371,
- .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 66,
.settings = hpt37x_settings
};
static struct hpt_info hpt372n __devinitdata = {
+ .chip_name = "HPT372N",
.chip_type = HPT372N,
- .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 77,
.settings = hpt37x_settings
};
static struct hpt_info hpt302n __devinitdata = {
+ .chip_name = "HPT302N",
.chip_type = HPT302N,
- .max_ultra = HPT302_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 77,
.settings = hpt37x_settings
};
static struct hpt_info hpt371n __devinitdata = {
+ .chip_name = "HPT371N",
.chip_type = HPT371N,
- .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5,
+ .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 77,
.settings = hpt37x_settings
};
@@ -676,12 +689,11 @@ static int hpt3xx_quirkproc(ide_drive_t *drive)
static void hpt3xx_intrproc(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (drive->quirk_list)
return;
+
/* drives in the quirk_list may not like intr setups/cleanups */
- hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
+ outb(drive->ctl | 2, IDE_CONTROL_REG);
}
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
@@ -709,21 +721,8 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
enable_irq (hwif->irq);
}
} else
- hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
- IDE_CONTROL_REG);
-}
-
-static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
+ outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
+ IDE_CONTROL_REG);
}
/*
@@ -763,9 +762,9 @@ static void hpt370_irq_timeout(ide_drive_t *drive)
printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff);
/* get DMA command mode */
- dma_cmd = hwif->INB(hwif->dma_command);
+ dma_cmd = inb(hwif->dma_command);
/* stop DMA */
- hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command);
+ outb(dma_cmd & ~0x1, hwif->dma_command);
hpt370_clear_engine(drive);
}
@@ -780,12 +779,12 @@ static void hpt370_ide_dma_start(ide_drive_t *drive)
static int hpt370_ide_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
- u8 dma_stat = hwif->INB(hwif->dma_status);
+ u8 dma_stat = inb(hwif->dma_status);
if (dma_stat & 0x01) {
/* wait a little */
udelay(20);
- dma_stat = hwif->INB(hwif->dma_status);
+ dma_stat = inb(hwif->dma_status);
if (dma_stat & 0x01)
hpt370_irq_timeout(drive);
}
@@ -846,34 +845,32 @@ static int hpt374_ide_dma_end(ide_drive_t *drive)
static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
{
- u8 scr2 = hwif->INB(hwif->dma_master + 0x7b);
+ u8 scr2 = inb(hwif->dma_master + 0x7b);
if ((scr2 & 0x7f) == mode)
return;
/* Tristate the bus */
- hwif->OUTB(0x80, hwif->dma_master + 0x73);
- hwif->OUTB(0x80, hwif->dma_master + 0x77);
+ outb(0x80, hwif->dma_master + 0x73);
+ outb(0x80, hwif->dma_master + 0x77);
/* Switch clock and reset channels */
- hwif->OUTB(mode, hwif->dma_master + 0x7b);
- hwif->OUTB(0xc0, hwif->dma_master + 0x79);
+ outb(mode, hwif->dma_master + 0x7b);
+ outb(0xc0, hwif->dma_master + 0x79);
/*
* Reset the state machines.
* NOTE: avoid accidentally enabling the disabled channels.
*/
- hwif->OUTB(hwif->INB(hwif->dma_master + 0x70) | 0x32,
- hwif->dma_master + 0x70);
- hwif->OUTB(hwif->INB(hwif->dma_master + 0x74) | 0x32,
- hwif->dma_master + 0x74);
+ outb(inb(hwif->dma_master + 0x70) | 0x32, hwif->dma_master + 0x70);
+ outb(inb(hwif->dma_master + 0x74) | 0x32, hwif->dma_master + 0x74);
/* Complete reset */
- hwif->OUTB(0x00, hwif->dma_master + 0x79);
+ outb(0x00, hwif->dma_master + 0x79);
/* Reconnect channels to bus */
- hwif->OUTB(0x00, hwif->dma_master + 0x73);
- hwif->OUTB(0x00, hwif->dma_master + 0x77);
+ outb(0x00, hwif->dma_master + 0x73);
+ outb(0x00, hwif->dma_master + 0x77);
}
/**
@@ -1152,7 +1149,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
* Select 66 MHz DPLL clock only if UltraATA/133 mode is
* supported/enabled, use 50 MHz DPLL clock otherwise...
*/
- if (info->max_ultra == 6) {
+ if (info->udma_mask == ATA_UDMA6) {
dpll_clk = 66;
clock = ATA_CLOCK_66MHZ;
} else if (dpll_clk) { /* HPT36x chips don't have DPLL */
@@ -1304,13 +1301,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
if (new_mcr != old_mcr)
pci_write_config_byte(dev, hwif->select_data + 1, new_mcr);
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
-
- hwif->ultra_mask = hwif->cds->udma_mask;
- hwif->mwdma_mask = 0x07;
/*
* The HPT37x uses the CBLID pins as outputs for MA15/MA16
@@ -1349,8 +1341,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
- hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;
-
if (chip_type >= HPT374) {
hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
hwif->ide_dma_end = &hpt374_ide_dma_end;
@@ -1360,10 +1350,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->dma_timeout = &hpt370_dma_timeout;
} else
hwif->dma_lost_irq = &hpt366_dma_lost_irq;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
}
static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
@@ -1373,7 +1359,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
u8 dma_new = 0, dma_old = 0;
unsigned long flags;
- dma_old = hwif->INB(dmabase + 2);
+ dma_old = inb(dmabase + 2);
local_irq_save(flags);
@@ -1384,60 +1370,26 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
if (masterdma & 0x30) dma_new |= 0x20;
if ( slavedma & 0x30) dma_new |= 0x40;
if (dma_new != dma_old)
- hwif->OUTB(dma_new, dmabase + 2);
+ outb(dma_new, dmabase + 2);
local_irq_restore(flags);
ide_setup_dma(hwif, dmabase, 8);
}
-static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
{
- struct pci_dev *dev2;
-
- if (PCI_FUNC(dev->devfn) & 1)
- return -ENODEV;
-
- pci_set_drvdata(dev, &hpt374);
-
- if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
- int ret;
-
- pci_set_drvdata(dev2, &hpt374);
-
- if (dev2->irq != dev->irq) {
- /* FIXME: we need a core pci_set_interrupt() */
- dev2->irq = dev->irq;
- printk(KERN_WARNING "%s: PCI config space interrupt "
- "fixed.\n", d->name);
- }
- ret = ide_setup_pci_devices(dev, dev2, d);
- if (ret < 0)
- pci_dev_put(dev2);
- return ret;
+ if (dev2->irq != dev->irq) {
+ /* FIXME: we need a core pci_set_interrupt() */
+ dev2->irq = dev->irq;
+ printk(KERN_INFO "HPT374: PCI config space interrupt fixed\n");
}
- return ide_setup_pci_device(dev, d);
}
-static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d)
+static void __devinit hpt371_init(struct pci_dev *dev)
{
- pci_set_drvdata(dev, &hpt372n);
-
- return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
-{
- struct hpt_info *info;
u8 mcr1 = 0;
- if (dev->revision > 1) {
- d->name = "HPT371N";
-
- info = &hpt371n;
- } else
- info = &hpt371;
-
/*
* HPT371 chips physically have only one channel, the secondary one,
* but the primary channel registers do exist! Go figure...
@@ -1447,194 +1399,102 @@ static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
pci_read_config_byte(dev, 0x50, &mcr1);
if (mcr1 & 0x04)
pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);
-
- pci_set_drvdata(dev, info);
-
- return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d)
-{
- struct hpt_info *info;
-
- if (dev->revision > 1) {
- d->name = "HPT372N";
-
- info = &hpt372n;
- } else
- info = &hpt372a;
- pci_set_drvdata(dev, info);
-
- return ide_setup_pci_device(dev, d);
}
-static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
{
- struct hpt_info *info;
-
- if (dev->revision > 1) {
- d->name = "HPT302N";
-
- info = &hpt302n;
- } else
- info = &hpt302;
- pci_set_drvdata(dev, info);
-
- return ide_setup_pci_device(dev, d);
-}
+ u8 mcr1 = 0, pin1 = 0, pin2 = 0;
-static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
-{
- struct pci_dev *dev2;
- u8 rev = dev->revision;
- static char *chipset_names[] = { "HPT366", "HPT366", "HPT368",
- "HPT370", "HPT370A", "HPT372",
- "HPT372N" };
- static struct hpt_info *info[] = { &hpt36x, &hpt36x, &hpt36x,
- &hpt370, &hpt370a, &hpt372,
- &hpt372n };
-
- if (PCI_FUNC(dev->devfn) & 1)
- return -ENODEV;
+ /*
+ * Now we'll have to force both channels enabled if
+ * at least one of them has been enabled by BIOS...
+ */
+ pci_read_config_byte(dev, 0x50, &mcr1);
+ if (mcr1 & 0x30)
+ pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
- switch (rev) {
- case 0:
- case 1:
- case 2:
- /*
- * HPT36x chips have one channel per function and have
- * both channel enable bits located differently and visible
- * to both functions -- really stupid design decision... :-(
- * Bit 4 is for the primary channel, bit 5 for the secondary.
- */
- d->host_flags |= IDE_HFLAG_SINGLE;
- d->enablebits[0].mask = d->enablebits[0].val = 0x10;
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
+ pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
- d->udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ?
- ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2;
- break;
- case 3:
- case 4:
- d->udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4;
- break;
- default:
- rev = 6;
- /* fall thru */
- case 5:
- case 6:
- d->udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5;
- break;
+ if (pin1 != pin2 && dev->irq == dev2->irq) {
+ printk(KERN_INFO "HPT36x: onboard version of chipset, "
+ "pin1=%d pin2=%d\n", pin1, pin2);
+ return 1;
}
- d->name = chipset_names[rev];
-
- pci_set_drvdata(dev, info[rev]);
-
- if (rev > 2)
- goto init_single;
-
- if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
- u8 mcr1 = 0, pin1 = 0, pin2 = 0;
- int ret;
-
- pci_set_drvdata(dev2, info[rev]);
-
- /*
- * Now we'll have to force both channels enabled if
- * at least one of them has been enabled by BIOS...
- */
- pci_read_config_byte(dev, 0x50, &mcr1);
- if (mcr1 & 0x30)
- pci_write_config_byte(dev, 0x50, mcr1 | 0x30);
-
- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
- pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
- if (pin1 != pin2 && dev->irq == dev2->irq) {
- d->bootable = ON_BOARD;
- printk("%s: onboard version of chipset, pin1=%d pin2=%d\n",
- d->name, pin1, pin2);
- }
- ret = ide_setup_pci_devices(dev, dev2, d);
- if (ret < 0)
- pci_dev_put(dev2);
- return ret;
- }
-init_single:
- return ide_setup_pci_device(dev, d);
+ return 0;
}
static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
{ /* 0 */
- .name = "HPT366",
- .init_setup = init_setup_hpt366,
+ .name = "HPT36x",
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .autodma = AUTODMA,
- .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .bootable = OFF_BOARD,
+ /*
+ * HPT36x chips have one channel per function and have
+ * both channel enable bits located differently and visible
+ * to both functions -- really stupid design decision... :-(
+ * Bit 4 is for the primary channel, bit 5 for the secondary.
+ */
+ .enablebits = {{0x50,0x10,0x10}, {0x54,0x04,0x04}},
.extra = 240,
+ .host_flags = IDE_HFLAG_SINGLE |
+ IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
},{ /* 1 */
.name = "HPT372A",
- .init_setup = init_setup_hpt372a,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
- .bootable = OFF_BOARD,
.extra = 240,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
},{ /* 2 */
.name = "HPT302",
- .init_setup = init_setup_hpt302,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
- .bootable = OFF_BOARD,
.extra = 240,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
},{ /* 3 */
.name = "HPT371",
- .init_setup = init_setup_hpt371,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
- .bootable = OFF_BOARD,
.extra = 240,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
},{ /* 4 */
.name = "HPT374",
- .init_setup = init_setup_hpt374,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.udma_mask = ATA_UDMA5,
- .bootable = OFF_BOARD,
.extra = 240,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
},{ /* 5 */
.name = "HPT372N",
- .init_setup = init_setup_hpt372n,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
- .bootable = OFF_BOARD,
.extra = 240,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
}
};
@@ -1645,25 +1505,86 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
*
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
- *
- * NOTE: since we'll have to modify some fields of the ide_pci_device_t
- * structure depending on the chip's revision, we'd better pass a local
- * copy down the call chain...
*/
static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t d = hpt366_chipsets[id->driver_data];
+ struct hpt_info *info = NULL;
+ struct pci_dev *dev2 = NULL;
+ ide_pci_device_t d;
+ u8 idx = id->driver_data;
+ u8 rev = dev->revision;
+
+ if ((idx == 0 || idx == 4) && (PCI_FUNC(dev->devfn) & 1))
+ return -ENODEV;
+
+ switch (idx) {
+ case 0:
+ if (rev < 3)
+ info = &hpt36x;
+ else {
+ static struct hpt_info *hpt37x_info[] =
+ { &hpt370, &hpt370a, &hpt372, &hpt372n };
+
+ info = hpt37x_info[min_t(u8, rev, 6) - 3];
+ idx++;
+ }
+ break;
+ case 1:
+ info = (rev > 1) ? &hpt372n : &hpt372a;
+ break;
+ case 2:
+ info = (rev > 1) ? &hpt302n : &hpt302;
+ break;
+ case 3:
+ hpt371_init(dev);
+ info = (rev > 1) ? &hpt371n : &hpt371;
+ break;
+ case 4:
+ info = &hpt374;
+ break;
+ case 5:
+ info = &hpt372n;
+ break;
+ }
+
+ d = hpt366_chipsets[idx];
+
+ d.name = info->chip_name;
+ d.udma_mask = info->udma_mask;
+
+ pci_set_drvdata(dev, info);
+
+ if (info == &hpt36x || info == &hpt374)
+ dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
+
+ if (dev2) {
+ int ret;
+
+ pci_set_drvdata(dev2, info);
+
+ if (info == &hpt374)
+ hpt374_init(dev, dev2);
+ else {
+ if (hpt36x_init(dev, dev2))
+ d.host_flags |= IDE_HFLAG_BOOTABLE;
+ }
+
+ ret = ide_setup_pci_devices(dev, dev2, &d);
+ if (ret < 0)
+ pci_dev_put(dev2);
+ return ret;
+ }
- return d.init_setup(dev, &d);
+ return ide_setup_pci_device(dev, &d);
}
-static struct pci_device_id hpt366_pci_tbl[] = {
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
- { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+static const struct pci_device_id hpt366_pci_tbl[] = {
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 },
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 },
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 },
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), 3 },
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), 4 },
+ { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), 5 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, hpt366_pci_tbl);
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index ecf4ce078dc..dfbe605120c 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -18,37 +18,6 @@
#include <asm/io.h>
/**
- * it8213_dma_2_pio - return the PIO mode matching DMA
- * @xfer_rate: transfer speed
- *
- * Returns the nearest equivalent PIO timing for the DMA
- * mode requested by the controller.
- */
-
-static u8 it8213_dma_2_pio (u8 xfer_rate) {
- switch(xfer_rate) {
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- case XFER_MW_DMA_2:
- return 4;
- case XFER_MW_DMA_1:
- return 3;
- case XFER_SW_DMA_2:
- return 2;
- case XFER_MW_DMA_0:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
- default:
- return 0;
- }
-}
-
-/**
* it8213_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
@@ -166,6 +135,9 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
} else
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
+ const u8 mwdma_to_pio[] = { 0, 3, 4 };
+ u8 pio;
+
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
@@ -174,38 +146,21 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
if (reg55 & w_flag)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
- }
- it8213_set_pio_mode(drive, it8213_dma_2_pio(speed));
-}
-
-/**
- * it8213_configure_drive_for_dma - set up for DMA transfers
- * @drive: drive we are going to set up
- *
- * Set up the drive for DMA, tune the controller and drive as
- * required. If the drive isn't suitable for DMA or we hit
- * other problems then we will drop down to PIO and set up
- * PIO appropriately
- */
-
-static int it8213_config_drive_for_dma (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
+ if (speed >= XFER_MW_DMA_0)
+ pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ else
+ pio = 2; /* only SWDMA2 is allowed */
- return -1;
+ it8213_set_pio_mode(drive, pio);
+ }
}
/**
* init_hwif_it8213 - set up hwif structs
* @hwif: interface to set up
*
- * We do the basic set up of the interface structure. The IT8212
- * requires several custom handlers so we override the default
- * ide DMA handlers appropriately
+ * We do the basic set up of the interface structure.
*/
static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
@@ -215,35 +170,13 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
hwif->set_dma_mode = &it8213_set_dma_mode;
hwif->set_pio_mode = &it8213_set_pio_mode;
- hwif->autodma = 0;
-
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x7f;
- hwif->mwdma_mask = 0x06;
- hwif->swdma_mask = 0x04;
-
pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
- hwif->ide_dma_check = &it8213_config_drive_for_dma;
-
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = (reg42h & 0x02) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
-
- /*
- * The BIOS often doesn't set up DMA on this controller
- * so we always do it.
- */
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
@@ -251,11 +184,13 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
{ \
.name = name_str, \
.init_hwif = init_hwif_it8213, \
- .autodma = AUTODMA, \
.enablebits = {{0x41,0x80,0x80}}, \
- .bootable = ON_BOARD, \
- .host_flags = IDE_HFLAG_SINGLE, \
+ .host_flags = IDE_HFLAG_SINGLE | \
+ IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
+ .swdma_mask = ATA_SWDMA2_ONLY, \
+ .mwdma_mask = ATA_MWDMA12_ONLY, \
+ .udma_mask = ATA_UDMA6, \
}
static ide_pci_device_t it8213_chipsets[] __devinitdata = {
@@ -279,9 +214,8 @@ static int __devinit it8213_init_one(struct pci_dev *dev, const struct pci_devic
return 0;
}
-
-static struct pci_device_id it8213_pci_tbl[] = {
- { PCI_VENDOR_ID_ITE, 0x8213, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+static const struct pci_device_id it8213_pci_tbl[] = {
+ { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8213), 0 },
{ 0, },
};
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 1b69d82478c..ec45b724720 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -416,26 +416,6 @@ static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * it821x_configure_drive_for_dma - set up for DMA transfers
- * @drive: drive we are going to set up
- *
- * Set up the drive for DMA, tune the controller and drive as
- * required. If the drive isn't suitable for DMA or we hit
- * other problems then we will drop down to PIO and set up
- * PIO appropriately
- */
-
-static int it821x_config_drive_for_dma (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
-
- return -1;
-}
-
-/**
* ata66_it821x - check for 80 pin cable
* @hwif: interface to check
*
@@ -557,18 +537,17 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
u8 conf;
- if(idev == NULL) {
+ if (idev == NULL) {
printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
- goto fallback;
+ return;
}
- ide_set_hwifdata(hwif, idev);
- hwif->atapi_dma = 1;
+ ide_set_hwifdata(hwif, idev);
pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
- if(conf & 1) {
+ if (conf & 1) {
idev->smart = 1;
- hwif->atapi_dma = 0;
+ hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
/* Long I/O's although allowed in LBA48 space cause the
onboard firmware to enter the twighlight zone */
hwif->rqsize = 256;
@@ -589,10 +568,10 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
*/
pci_read_config_byte(hwif->pci_dev, 0x08, &conf);
- if(conf == 0x10) {
+ if (conf == 0x10) {
idev->timing10 = 1;
- hwif->atapi_dma = 0;
- if(!idev->smart)
+ hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+ if (idev->smart == 0)
printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
}
@@ -606,32 +585,14 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
} else
hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
- if (!hwif->dma_base)
- goto fallback;
-
- hwif->ultra_mask = 0x7f;
- hwif->mwdma_mask = 0x07;
+ if (hwif->dma_base == 0)
+ return;
- hwif->ide_dma_check = &it821x_config_drive_for_dma;
+ hwif->ultra_mask = ATA_UDMA6;
+ hwif->mwdma_mask = ATA_MWDMA2;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_it821x(hwif);
-
- /*
- * The BIOS often doesn't set up DMA on this controller
- * so we always do it.
- */
-
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
- return;
-fallback:
- hwif->autodma = 0;
- return;
}
static void __devinit it8212_disable_raid(struct pci_dev *dev)
@@ -672,9 +633,8 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
.name = name_str, \
.init_chipset = init_chipset_it821x, \
.init_hwif = init_hwif_it821x, \
- .autodma = AUTODMA, \
- .bootable = ON_BOARD, \
.fixup = it821x_fixups, \
+ .host_flags = IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
}
@@ -697,9 +657,9 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic
return 0;
}
-static struct pci_device_id it821x_pci_tbl[] = {
- { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id it821x_pci_tbl[] = {
+ { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 },
+ { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 },
{ 0, },
};
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index 582b4cae2b5..2eeff670d9a 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -100,24 +100,6 @@ static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
}
/**
- * jmicron_configure_drive_for_dma - set up for DMA transfers
- * @drive: drive we are going to set up
- *
- * As the JMicron snoops for timings all we actually need to do is
- * make sure we don't set an invalid mode.
- */
-
-static int jmicron_config_drive_for_dma (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
-
- return -1;
-}
-
-/**
* init_hwif_jmicron - set up hwif structs
* @hwif: interface to set up
*
@@ -129,37 +111,21 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
hwif->set_pio_mode = &jmicron_set_pio_mode;
hwif->set_dma_mode = &jmicron_set_dma_mode;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
- if (!hwif->dma_base)
- goto fallback;
-
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x7f;
- hwif->mwdma_mask = 0x07;
-
- hwif->ide_dma_check = &jmicron_config_drive_for_dma;
+ if (hwif->dma_base == 0)
+ return;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_jmicron(hwif);
-
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
- return;
-fallback:
- hwif->autodma = 0;
- return;
}
static ide_pci_device_t jmicron_chipset __devinitdata = {
.name = "JMB",
.init_hwif = init_hwif_jmicron,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_BOOTABLE,
.enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
.pio_mask = ATA_PIO5,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
};
/**
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 465c935fdf2..d21b5892382 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -197,7 +197,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
u8 stat;
#endif
- hwif->autodma = 0;
hwif->selectproc = &ns87415_selectproc;
/*
@@ -259,11 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
outb(0x60, hwif->dma_status);
hwif->dma_setup = &ns87415_ide_dma_setup;
hwif->ide_dma_end = &ns87415_ide_dma_end;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t ns87415_chipset __devinitdata = {
@@ -272,8 +266,9 @@ static ide_pci_device_t ns87415_chipset __devinitdata = {
.init_iops = init_iops_ns87415,
#endif
.init_hwif = init_hwif_ns87415,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_BOOTABLE,
};
static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -281,8 +276,8 @@ static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_devi
return ide_setup_pci_device(dev, &ns87415_chipset);
}
-static struct pci_device_id ns87415_pci_tbl[] = {
- { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id ns87415_pci_tbl[] = {
+ { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87415), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl);
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 9fa06393469..3573ffeaaa3 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.7 Sept 10, 2002
+ * linux/drivers/ide/pci/opti621.c Version 0.8 Aug 27, 2007
*
* Copyright (C) 1996-1998 Linus Torvalds & authors (see below)
*/
@@ -57,9 +57,6 @@
* There is a 25/33MHz switch in configuration
* register, but driver is written for use at any frequency which get
* (use idebus=xx to select PCI bus speed).
- * Use hda=autotune and hdb=autotune for automatical tune of the PIO modes.
- * If you get strange results, do not use this and set PIO manually
- * by hdparm.
*
* Version 0.1, Nov 8, 1996
* by Jaromir Koutek, for 2.1.8.
@@ -328,40 +325,31 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
*/
static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
{
- hwif->autodma = 0;
hwif->drives[0].drive_data = PIO_DONT_KNOW;
hwif->drives[1].drive_data = PIO_DONT_KNOW;
hwif->set_pio_mode = &opti621_set_pio_mode;
-
- if (!(hwif->dma_base))
- return;
-
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t opti621_chipsets[] __devinitdata = {
{ /* 0 */
.name = "OPTI621",
.init_hwif = init_hwif_opti621,
- .autodma = AUTODMA,
.enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO3,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
},{ /* 1 */
.name = "OPTI621X",
.init_hwif = init_hwif_opti621,
- .autodma = AUTODMA,
.enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO3,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
}
};
@@ -370,9 +358,9 @@ static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_devi
return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]);
}
-static struct pci_device_id opti621_pci_tbl[] = {
- { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+static const struct pci_device_id opti621_pci_tbl[] = {
+ { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C621), 0 },
+ { PCI_VDEVICE(OPTI, PCI_DEVICE_ID_OPTI_82C825), 1 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, opti621_pci_tbl);
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index ad0bdcb0c02..d1e7823454f 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -223,19 +223,6 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static int pdcnew_quirkproc(ide_drive_t *drive)
{
const char **list, *model = drive->id->model;
@@ -345,16 +332,12 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base)
static void __devinit apple_kiwi_init(struct pci_dev *pdev)
{
struct device_node *np = pci_device_to_OF_node(pdev);
- unsigned int class_rev = 0;
u8 conf;
if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
return;
- pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
- class_rev &= 0xff;
-
- if (class_rev >= 0x03) {
+ if (pdev->revision >= 0x03) {
/* Setup chip magic config stuff (from darwin) */
pci_read_config_byte (pdev, 0x40, &conf);
pci_write_config_byte(pdev, 0x40, (conf | 0x01));
@@ -482,46 +465,82 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
{
- hwif->autodma = 0;
-
hwif->set_pio_mode = &pdcnew_set_pio_mode;
hwif->set_dma_mode = &pdcnew_set_mode;
hwif->quirkproc = &pdcnew_quirkproc;
hwif->resetproc = &pdcnew_reset;
- hwif->err_stops_fifo = 1;
-
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
if (hwif->dma_base == 0)
return;
- hwif->atapi_dma = 1;
-
- hwif->ultra_mask = hwif->cds->udma_mask;
- hwif->mwdma_mask = 0x07;
-
- hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
-
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = pdcnew_cable_detect(hwif);
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
}
-static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
+static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
{
- return ide_setup_pci_device(dev, d);
+ struct pci_dev *dev2;
+
+ dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
+ PCI_FUNC(dev->devfn)));
+ if (dev2 &&
+ dev2->vendor == dev->vendor &&
+ dev2->device == dev->device) {
+
+ if (dev2->irq != dev->irq) {
+ dev2->irq = dev->irq;
+ printk(KERN_INFO "PDC20270: PCI config space "
+ "interrupt fixed\n");
+ }
+
+ return dev2;
+ }
+
+ return NULL;
}
-static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
+#define DECLARE_PDCNEW_DEV(name_str, udma) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_pdcnew, \
+ .init_hwif = init_hwif_pdc202new, \
+ .host_flags = IDE_HFLAG_POST_SET_MODE | \
+ IDE_HFLAG_ERROR_STOPS_FIFO | \
+ IDE_HFLAG_OFF_BOARD, \
+ .pio_mask = ATA_PIO4, \
+ .mwdma_mask = ATA_MWDMA2, \
+ .udma_mask = udma, \
+ }
+
+static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
+ /* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5),
+ /* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6),
+ /* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5),
+ /* 3 */ DECLARE_PDCNEW_DEV("PDC20271", ATA_UDMA6),
+ /* 4 */ DECLARE_PDCNEW_DEV("PDC20275", ATA_UDMA6),
+ /* 5 */ DECLARE_PDCNEW_DEV("PDC20276", ATA_UDMA6),
+ /* 6 */ DECLARE_PDCNEW_DEV("PDC20277", ATA_UDMA6),
+};
+
+/**
+ * pdc202new_init_one - called when a pdc202xx is found
+ * @dev: the pdc202new device
+ * @id: the matching pci id
+ *
+ * Called when the PCI registration layer (or the IDE initialization)
+ * finds a device matching our IDE device tables.
+ */
+
+static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
+ ide_pci_device_t *d;
struct pci_dev *bridge = dev->bus->self;
+ u8 idx = id->driver_data;
+
+ d = &pdcnew_chipsets[idx];
- if (bridge != NULL &&
+ if (idx == 2 && bridge &&
bridge->vendor == PCI_VENDOR_ID_DEC &&
bridge->device == PCI_DEVICE_ID_DEC_21150) {
struct pci_dev *dev2;
@@ -529,143 +548,36 @@ static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *
if (PCI_SLOT(dev->devfn) & 2)
return -ENODEV;
- dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
- PCI_FUNC(dev->devfn)));
- if (dev2 != NULL &&
- dev2->vendor == dev->vendor &&
- dev2->device == dev->device) {
- int ret;
+ dev2 = pdc20270_get_dev2(dev);
- if (dev2->irq != dev->irq) {
- dev2->irq = dev->irq;
-
- printk(KERN_WARNING "%s: PCI config space "
- "interrupt fixed.\n", d->name);
- }
-
- ret = ide_setup_pci_devices(dev, dev2, d);
+ if (dev2) {
+ int ret = ide_setup_pci_devices(dev, dev2, d);
if (ret < 0)
pci_dev_put(dev2);
return ret;
}
}
- return ide_setup_pci_device(dev, d);
-}
-static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
-{
- struct pci_dev *bridge = dev->bus->self;
-
- if (bridge != NULL &&
+ if (idx == 5 && bridge &&
bridge->vendor == PCI_VENDOR_ID_INTEL &&
- (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
- bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
-
- printk(KERN_INFO "%s: attached to I2O RAID controller, "
- "skipping.\n", d->name);
+ (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+ bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+ printk(KERN_INFO "PDC20276: attached to I2O RAID controller, "
+ "skipping\n");
return -ENODEV;
}
- return ide_setup_pci_device(dev, d);
-}
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "PDC20268",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x3f, /* udma0-5 */
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- },{ /* 1 */
- .name = "PDC20269",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x7f, /* udma0-6*/
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- },{ /* 2 */
- .name = "PDC20270",
- .init_setup = init_setup_pdc20270,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x3f, /* udma0-5 */
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- },{ /* 3 */
- .name = "PDC20271",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x7f, /* udma0-6*/
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- },{ /* 4 */
- .name = "PDC20275",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x7f, /* udma0-6*/
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- },{ /* 5 */
- .name = "PDC20276",
- .init_setup = init_setup_pdc20276,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x7f, /* udma0-6*/
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- },{ /* 6 */
- .name = "PDC20277",
- .init_setup = init_setup_pdcnew,
- .init_chipset = init_chipset_pdcnew,
- .init_hwif = init_hwif_pdc202new,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x7f, /* udma0-6*/
- .host_flags = IDE_HFLAG_POST_SET_MODE,
- }
-};
-
-/**
- * pdc202new_init_one - called when a pdc202xx is found
- * @dev: the pdc202new device
- * @id: the matching pci id
- *
- * Called when the PCI registration layer (or the IDE initialization)
- * finds a device matching our IDE device tables.
- */
-
-static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
- ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
-
- return d->init_setup(dev, d);
+ return ide_setup_pci_device(dev, d);
}
-static struct pci_device_id pdc202new_pci_tbl[] = {
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
+static const struct pci_device_id pdc202new_pci_tbl[] = {
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), 0 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), 1 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20270), 2 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20271), 3 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20275), 4 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20276), 5 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20277), 6 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl);
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 8c3e8cf36ec..29306121dc4 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007
+ * linux/drivers/ide/pci/pdc202xx_old.c Version 0.52 Aug 27, 2007
*
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc.
@@ -97,9 +97,6 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break;
case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break;
case XFER_MW_DMA_0: TB = 0xE0; TC = 0x0F; break;
- case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break;
- case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break;
- case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break;
case XFER_PIO_4: TA = 0x01; TB = 0x04; break;
case XFER_PIO_3: TA = 0x02; TB = 0x06; break;
case XFER_PIO_2: TA = 0x03; TB = 0x08; break;
@@ -179,19 +176,6 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
}
-static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static int pdc202xx_quirkproc (ide_drive_t *drive)
{
const char **list, *model = drive->id->model;
@@ -325,8 +309,6 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
(dev->device == PCI_DEVICE_ID_PROMISE_20265))
hwif->rqsize = 256;
- hwif->autodma = 0;
-
hwif->set_pio_mode = &pdc202xx_set_pio_mode;
hwif->set_dma_mode = &pdc202xx_set_mode;
@@ -335,19 +317,9 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
hwif->resetproc = &pdc202xx_reset;
- hwif->err_stops_fifo = 1;
-
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
if (hwif->dma_base == 0)
return;
- hwif->ultra_mask = hwif->cds->udma_mask;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
- hwif->atapi_dma = 1;
-
- hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
hwif->dma_timeout = &pdc202xx_dma_timeout;
@@ -359,10 +331,6 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
hwif->ide_dma_end = &pdc202xx_old_ide_dma_end;
}
hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
}
static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
@@ -397,8 +365,8 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
ide_setup_dma(hwif, dmabase, 8);
}
-static int __devinit init_setup_pdc202ata4(struct pci_dev *dev,
- ide_pci_device_t *d)
+static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
+ const char *name)
{
if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
u8 irq = 0, irq2 = 0;
@@ -408,90 +376,44 @@ static int __devinit init_setup_pdc202ata4(struct pci_dev *dev,
if (irq != irq2) {
pci_write_config_byte(dev,
(PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */
- printk(KERN_INFO "%s: pci-config space interrupt "
- "mirror fixed.\n", d->name);
+ printk(KERN_INFO "%s: PCI config space interrupt "
+ "mirror fixed\n", name);
}
}
- return ide_setup_pci_device(dev, d);
}
-static int __devinit init_setup_pdc20265(struct pci_dev *dev,
- ide_pci_device_t *d)
-{
- if ((dev->bus->self) &&
- (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
- ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) ||
- (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
- printk(KERN_INFO "ide: Skipping Promise PDC20265 "
- "attached to I2O RAID controller.\n");
- return -ENODEV;
+#define DECLARE_PDC2026X_DEV(name_str, udma) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_pdc202xx, \
+ .init_hwif = init_hwif_pdc202xx, \
+ .init_dma = init_dma_pdc202xx, \
+ .extra = 48, \
+ .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | \
+ IDE_HFLAG_OFF_BOARD, \
+ .pio_mask = ATA_PIO4, \
+ .mwdma_mask = ATA_MWDMA2, \
+ .udma_mask = udma, \
}
- return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_pdc202xx(struct pci_dev *dev,
- ide_pci_device_t *d)
-{
- return ide_setup_pci_device(dev, d);
-}
static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
{ /* 0 */
.name = "PDC20246",
- .init_setup = init_setup_pdc202ata4,
.init_chipset = init_chipset_pdc202xx,
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
.extra = 16,
+ .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO |
+ IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
- .udma_mask = 0x07, /* udma0-2 */
- },{ /* 1 */
- .name = "PDC20262",
- .init_setup = init_setup_pdc202ata4,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .extra = 48,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x1f, /* udma0-4 */
- },{ /* 2 */
- .name = "PDC20263",
- .init_setup = init_setup_pdc202ata4,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .extra = 48,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x1f, /* udma0-4 */
- },{ /* 3 */
- .name = "PDC20265",
- .init_setup = init_setup_pdc20265,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .extra = 48,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x3f, /* udma0-5 */
- },{ /* 4 */
- .name = "PDC20267",
- .init_setup = init_setup_pdc202xx,
- .init_chipset = init_chipset_pdc202xx,
- .init_hwif = init_hwif_pdc202xx,
- .init_dma = init_dma_pdc202xx,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .extra = 48,
- .pio_mask = ATA_PIO4,
- .udma_mask = 0x3f, /* udma0-5 */
- }
+ .mwdma_mask = ATA_MWDMA2,
+ .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),
};
/**
@@ -505,17 +427,36 @@ 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 = &pdc202xx_chipsets[id->driver_data];
+ ide_pci_device_t *d;
+ u8 idx = id->driver_data;
+
+ d = &pdc202xx_chipsets[idx];
+
+ if (idx < 3)
+ pdc202ata4_fixup_irq(dev, d->name);
- return d->init_setup(dev, d);
+ if (idx == 3) {
+ struct pci_dev *bridge = dev->bus->self;
+
+ if (bridge &&
+ bridge->vendor == PCI_VENDOR_ID_INTEL &&
+ (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+ bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+ printk(KERN_INFO "ide: Skipping Promise PDC20265 "
+ "attached to I2O RAID controller\n");
+ return -ENODEV;
+ }
+ }
+
+ return ide_setup_pci_device(dev, d);
}
-static struct pci_device_id pdc202xx_pci_tbl[] = {
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+static const struct pci_device_id pdc202xx_pci_tbl[] = {
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 2 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 3 },
+ { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 4 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl);
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 38c91ba6497..ec0c6e96a21 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/piix.c Version 0.52 Jul 14, 2007
+ * linux/drivers/ide/pci/piix.c Version 0.54 Sep 5, 2007
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -106,37 +106,6 @@
static int no_piix_dma;
/**
- * piix_dma_2_pio - return the PIO mode matching DMA
- * @xfer_rate: transfer speed
- *
- * Returns the nearest equivalent PIO timing for the DMA
- * mode requested by the controller.
- */
-
-static u8 piix_dma_2_pio (u8 xfer_rate) {
- switch(xfer_rate) {
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- case XFER_MW_DMA_2:
- return 4;
- case XFER_MW_DMA_1:
- return 3;
- case XFER_SW_DMA_2:
- return 2;
- case XFER_MW_DMA_0:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
- default:
- return 0;
- }
-}
-
-/**
* piix_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
@@ -263,6 +232,9 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
} else
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
+ const u8 mwdma_to_pio[] = { 0, 3, 4 };
+ u8 pio;
+
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
@@ -271,80 +243,31 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
if (reg55 & w_flag)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
- }
- piix_set_pio_mode(drive, piix_dma_2_pio(speed));
-}
-
-/**
- * piix_config_drive_xfer_rate - set up an IDE device
- * @drive: IDE drive to configure
- *
- * Set up the PIIX interface for the best available speed on this
- * interface, preferring DMA to PIO.
- */
-
-static int piix_config_drive_xfer_rate (ide_drive_t *drive)
-{
- drive->init_speed = 0;
+ if (speed >= XFER_MW_DMA_0)
+ pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ else
+ pio = 2; /* only SWDMA2 is allowed */
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
-/**
- * piix_is_ichx - check if ICHx
- * @dev: PCI device to check
- *
- * returns 1 if ICHx, 0 otherwise.
- */
-static int piix_is_ichx(struct pci_dev *dev)
-{
- switch (dev->device) {
- case PCI_DEVICE_ID_INTEL_82801EB_1:
- case PCI_DEVICE_ID_INTEL_82801AA_1:
- case PCI_DEVICE_ID_INTEL_82801AB_1:
- case PCI_DEVICE_ID_INTEL_82801BA_8:
- case PCI_DEVICE_ID_INTEL_82801BA_9:
- case PCI_DEVICE_ID_INTEL_82801CA_10:
- case PCI_DEVICE_ID_INTEL_82801CA_11:
- case PCI_DEVICE_ID_INTEL_82801DB_1:
- case PCI_DEVICE_ID_INTEL_82801DB_10:
- case PCI_DEVICE_ID_INTEL_82801DB_11:
- case PCI_DEVICE_ID_INTEL_82801EB_11:
- case PCI_DEVICE_ID_INTEL_82801E_11:
- case PCI_DEVICE_ID_INTEL_ESB_2:
- case PCI_DEVICE_ID_INTEL_ICH6_19:
- case PCI_DEVICE_ID_INTEL_ICH7_21:
- case PCI_DEVICE_ID_INTEL_ESB2_18:
- case PCI_DEVICE_ID_INTEL_ICH8_6:
- return 1;
+ piix_set_pio_mode(drive, pio);
}
-
- return 0;
}
/**
- * init_chipset_piix - set up the PIIX chipset
+ * init_chipset_ich - set up the ICH chipset
* @dev: PCI device to set up
* @name: Name of the device
*
- * Initialize the PCI device as required. For the PIIX this turns
- * out to be nice and simple
+ * Initialize the PCI device as required. For the ICH this turns
+ * out to be nice and simple.
*/
-static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_ich(struct pci_dev *dev, const char *name)
{
- if (piix_is_ichx(dev)) {
- unsigned int extra = 0;
- pci_read_config_dword(dev, 0x54, &extra);
- pci_write_config_dword(dev, 0x54, extra|0x400);
- }
+ u32 extra = 0;
+
+ pci_read_config_dword(dev, 0x54, &extra);
+ pci_write_config_dword(dev, 0x54, extra | 0x400);
return 0;
}
@@ -362,9 +285,9 @@ static void piix_dma_clear_irq(ide_drive_t *drive)
u8 dma_stat;
/* clear the INTR & ERROR bits */
- dma_stat = hwif->INB(hwif->dma_status);
+ dma_stat = inb(hwif->dma_status);
/* Should we force the bit as well ? */
- hwif->OUTB(dma_stat, hwif->dma_status);
+ outb(dma_stat, hwif->dma_status);
}
struct ich_laptop {
@@ -418,37 +341,12 @@ static u8 __devinit piix_cable_detect(ide_hwif_t *hwif)
static void __devinit init_hwif_piix(ide_hwif_t *hwif)
{
-#ifndef CONFIG_IA64
- if (!hwif->irq)
- hwif->irq = hwif->channel ? 15 : 14;
-#endif /* CONFIG_IA64 */
-
- if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
- /* This is a painful system best to let it self tune for now */
- return;
- }
-
- hwif->autodma = 0;
-
hwif->set_pio_mode = &piix_set_pio_mode;
hwif->set_dma_mode = &piix_set_dma_mode;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
if (!hwif->dma_base)
return;
- /* ICHx need to clear the bmdma status for all interrupts */
- if (piix_is_ichx(hwif->pci_dev))
- hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
-
- hwif->atapi_dma = 1;
-
- hwif->ultra_mask = hwif->cds->udma_mask;
- hwif->mwdma_mask = 0x06;
- hwif->swdma_mask = 0x04;
-
if (hwif->ultra_mask & 0x78) {
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = piix_cable_detect(hwif);
@@ -456,30 +354,51 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
if (no_piix_dma)
hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
+}
- hwif->ide_dma_check = &piix_config_drive_xfer_rate;
- if (!noautodma)
- hwif->autodma = 1;
+static void __devinit init_hwif_ich(ide_hwif_t *hwif)
+{
+ init_hwif_piix(hwif);
- hwif->drives[1].autodma = hwif->autodma;
- hwif->drives[0].autodma = hwif->autodma;
+ /* ICHx need to clear the BMDMA status for all interrupts */
+ if (hwif->dma_base)
+ hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
}
+#ifndef CONFIG_IA64
+ #define IDE_HFLAGS_PIIX (IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE)
+#else
+ #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE
+#endif
+
#define DECLARE_PIIX_DEV(name_str, udma) \
{ \
.name = name_str, \
- .init_chipset = init_chipset_piix, \
.init_hwif = init_hwif_piix, \
- .autodma = AUTODMA, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
- .bootable = ON_BOARD, \
+ .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
+ .swdma_mask = ATA_SWDMA2_ONLY, \
+ .mwdma_mask = ATA_MWDMA12_ONLY, \
.udma_mask = udma, \
}
+#define DECLARE_ICH_DEV(name_str, udma) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_ich, \
+ .init_hwif = init_hwif_ich, \
+ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
+ .host_flags = IDE_HFLAGS_PIIX, \
+ .pio_mask = ATA_PIO4, \
+ .swdma_mask = ATA_SWDMA2_ONLY, \
+ .mwdma_mask = ATA_MWDMA12_ONLY, \
+ .udma_mask = udma, \
+ }
+
static ide_pci_device_t piix_pci_info[] __devinitdata = {
- /* 0 */ DECLARE_PIIX_DEV("PIIXa", 0x00), /* no udma */
- /* 1 */ DECLARE_PIIX_DEV("PIIXb", 0x00), /* no udma */
+ /* 0 */ DECLARE_PIIX_DEV("PIIXa", 0x00), /* no udma */
+ /* 1 */ DECLARE_PIIX_DEV("PIIXb", 0x00), /* no udma */
/* 2 */
{ /*
@@ -488,36 +407,35 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
* of the bit 14 of the IDETIM register at offset 0x6c
*/
.name = "MPIIX",
- .init_hwif = init_hwif_piix,
- .autodma = NODMA,
.enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ISA_PORTS,
+ .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
+ IDE_HFLAGS_PIIX,
.pio_mask = ATA_PIO4,
+ /* This is a painful system best to let it self tune for now */
},
- /* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */
- /* 4 */ DECLARE_PIIX_DEV("PIIX4", 0x07), /* udma0-2 */
- /* 5 */ DECLARE_PIIX_DEV("ICH0", 0x07), /* udma0-2 */
- /* 6 */ DECLARE_PIIX_DEV("PIIX4", 0x07), /* udma0-2 */
- /* 7 */ DECLARE_PIIX_DEV("ICH", 0x1f), /* udma0-4 */
- /* 8 */ DECLARE_PIIX_DEV("PIIX4", 0x1f), /* udma0-4 */
- /* 9 */ DECLARE_PIIX_DEV("PIIX4", 0x07), /* udma0-2 */
- /* 10 */ DECLARE_PIIX_DEV("ICH2", 0x3f), /* udma0-5 */
- /* 11 */ DECLARE_PIIX_DEV("ICH2M", 0x3f), /* udma0-5 */
- /* 12 */ DECLARE_PIIX_DEV("ICH3M", 0x3f), /* udma0-5 */
- /* 13 */ DECLARE_PIIX_DEV("ICH3", 0x3f), /* udma0-5 */
- /* 14 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */
- /* 15 */ DECLARE_PIIX_DEV("ICH5", 0x3f), /* udma0-5 */
- /* 16 */ DECLARE_PIIX_DEV("C-ICH", 0x3f), /* udma0-5 */
- /* 17 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */
- /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA", 0x3f), /* udma0-5 */
- /* 19 */ DECLARE_PIIX_DEV("ICH5", 0x3f), /* udma0-5 */
- /* 20 */ DECLARE_PIIX_DEV("ICH6", 0x3f), /* udma0-5 */
- /* 21 */ DECLARE_PIIX_DEV("ICH7", 0x3f), /* udma0-5 */
- /* 22 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */
- /* 23 */ DECLARE_PIIX_DEV("ESB2", 0x3f), /* udma0-5 */
- /* 24 */ DECLARE_PIIX_DEV("ICH8M", 0x3f), /* udma0-5 */
+ /* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */
+ /* 4 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2),
+ /* 5 */ DECLARE_ICH_DEV("ICH0", ATA_UDMA2),
+ /* 6 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2),
+ /* 7 */ DECLARE_ICH_DEV("ICH", ATA_UDMA4),
+ /* 8 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA4),
+ /* 9 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2),
+ /* 10 */ DECLARE_ICH_DEV("ICH2", ATA_UDMA5),
+ /* 11 */ DECLARE_ICH_DEV("ICH2M", ATA_UDMA5),
+ /* 12 */ DECLARE_ICH_DEV("ICH3M", ATA_UDMA5),
+ /* 13 */ DECLARE_ICH_DEV("ICH3", ATA_UDMA5),
+ /* 14 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5),
+ /* 15 */ DECLARE_ICH_DEV("ICH5", ATA_UDMA5),
+ /* 16 */ DECLARE_ICH_DEV("C-ICH", ATA_UDMA5),
+ /* 17 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5),
+ /* 18 */ DECLARE_ICH_DEV("ICH5-SATA", ATA_UDMA5),
+ /* 19 */ DECLARE_ICH_DEV("ICH5", ATA_UDMA5),
+ /* 20 */ DECLARE_ICH_DEV("ICH6", ATA_UDMA5),
+ /* 21 */ DECLARE_ICH_DEV("ICH7", ATA_UDMA5),
+ /* 22 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5),
+ /* 23 */ DECLARE_ICH_DEV("ESB2", ATA_UDMA5),
+ /* 24 */ DECLARE_ICH_DEV("ICH8M", ATA_UDMA5),
};
/**
@@ -565,34 +483,34 @@ static void __devinit piix_check_450nx(void)
printk(KERN_WARNING "piix: A BIOS update may resolve this.\n");
}
-static struct pci_device_id piix_pci_tbl[] = {
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17},
+static const struct pci_device_id piix_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371FB_0), 0 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371FB_1), 1 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), 2 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371SB_1), 3 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371AB), 4 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801AB_1), 5 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82443MX_1), 6 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801AA_1), 7 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82372FB_1), 8 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82451NX), 9 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801BA_9), 10 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801BA_8), 11 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801CA_10), 12 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801CA_11), 13 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_11), 14 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801EB_11), 15 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801E_11), 16 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_10), 17 },
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18},
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801EB_1), 18 },
#endif
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 23},
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 24},
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2), 19 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19), 20 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 21 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1), 22 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 23 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6), 24 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
index 10e1ae7a4a0..dd2583ef1ad 100644
--- a/drivers/ide/pci/rz1000.c
+++ b/drivers/ide/pci/rz1000.c
@@ -52,8 +52,7 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
static ide_pci_device_t rz1000_chipset __devinitdata = {
.name = "RZ100x",
.init_hwif = init_hwif_rz1000,
- .autodma = NODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE,
};
static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -61,9 +60,9 @@ static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_devic
return ide_setup_pci_device(dev, &rz1000_chipset);
}
-static struct pci_device_id rz1000_pci_tbl[] = {
- { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id rz1000_pci_tbl[] = {
+ { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), 0 },
+ { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl);
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index ee0e3f554d9..b2423e03bf3 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/sc1200.c Version 0.95 Jun 16 2007
+ * linux/drivers/ide/pci/sc1200.c Version 0.97 Aug 3 2007
*
* Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
@@ -199,19 +199,6 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
}
}
-/*
- * sc1200_config_dma() handles selection/setting of DMA/UDMA modes
- * for both the chipset and drive.
- */
-static int sc1200_config_dma (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- return 1;
-}
-
-
/* Replacement for the standard ide_dma_end action in
* dma_proc.
*
@@ -375,10 +362,6 @@ static int sc1200_resume (struct pci_dev *dev)
*/
static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
{
- if (hwif->mate)
- hwif->serialized = hwif->mate->serialized = 1;
- hwif->autodma = 0;
-
hwif->set_pio_mode = &sc1200_set_pio_mode;
hwif->set_dma_mode = &sc1200_set_dma_mode;
@@ -386,27 +369,19 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
return;
hwif->udma_filter = sc1200_udma_filter;
- hwif->ide_dma_check = &sc1200_config_dma;
hwif->ide_dma_end = &sc1200_ide_dma_end;
-
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x07;
- hwif->mwdma_mask = 0x07;
-
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t sc1200_chipset __devinitdata = {
.name = "SC1200",
.init_hwif = init_hwif_sc1200,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE,
+ .host_flags = IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_POST_SET_MODE |
+ IDE_HFLAG_ABUSE_DMA_MODES |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
};
static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -414,8 +389,8 @@ static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_devic
return ide_setup_pci_device(dev, &sc1200_chipset);
}
-static struct pci_device_id sc1200_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0},
+static const struct pci_device_id sc1200_pci_tbl[] = {
+ { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl);
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 67f06dd11b3..ae9b50331d2 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -284,28 +284,6 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * scc_configure_drive_for_dma - set up for DMA transfers
- * @drive: drive we are going to set up
- *
- * Set up the drive for DMA, tune the controller and drive as
- * required.
- * If the drive isn't suitable for DMA or we hit other problems
- * then we will drop down to PIO and set up PIO appropriately.
- * (return -1)
- */
-
-static int scc_config_drive_for_dma(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
-/**
* scc_ide_dma_setup - begin a DMA phase
* @drive: target device
*
@@ -494,7 +472,7 @@ static u8 scc_udma_filter(ide_drive_t *drive)
if ((drive->media != ide_disk) && (mask & 0xE0)) {
printk(KERN_INFO "%s: limit %s to UDMA4\n",
SCC_PATA_NAME, drive->name);
- mask = 0x1F;
+ mask = ATA_UDMA4;
}
return mask;
@@ -702,41 +680,25 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
hwif->ide_dma_end = scc_ide_dma_end;
hwif->set_pio_mode = scc_set_pio_mode;
hwif->set_dma_mode = scc_set_dma_mode;
- hwif->ide_dma_check = scc_config_drive_for_dma;
hwif->ide_dma_test_irq = scc_dma_test_irq;
hwif->udma_filter = scc_udma_filter;
- hwif->drives[0].autotune = IDE_TUNE_AUTO;
- hwif->drives[1].autotune = IDE_TUNE_AUTO;
-
- if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) {
- hwif->ultra_mask = 0x7f; /* 133MHz */
- } else {
- hwif->ultra_mask = 0x3f; /* 100MHz */
- }
- hwif->mwdma_mask = 0x00;
- hwif->swdma_mask = 0x00;
- hwif->atapi_dma = 1;
+ if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN)
+ hwif->ultra_mask = ATA_UDMA6; /* 133MHz */
+ else
+ hwif->ultra_mask = ATA_UDMA5; /* 100MHz */
/* we support 80c cable only. */
hwif->cbl = ATA_CBL_PATA80;
-
- hwif->autodma = 0;
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
#define DECLARE_SCC_DEV(name_str) \
{ \
.name = name_str, \
- .init_setup = init_setup_scc, \
.init_iops = init_iops_scc, \
.init_hwif = init_hwif_scc, \
- .autodma = AUTODMA, \
- .bootable = ON_BOARD, \
- .host_flags = IDE_HFLAG_SINGLE, \
+ .host_flags = IDE_HFLAG_SINGLE | \
+ IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
}
@@ -756,7 +718,8 @@ 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 d->init_setup(dev, d);
+
+ return init_setup_scc(dev, d);
}
/**
@@ -793,8 +756,8 @@ static void __devexit scc_remove(struct pci_dev *dev)
memset(ports, 0, sizeof(*ports));
}
-static struct pci_device_id scc_pci_tbl[] = {
- { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id scc_pci_tbl[] = {
+ { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 49ec0ac64a4..a3d880e21d0 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -97,6 +97,7 @@ static u8 svwks_udma_filter(ide_drive_t *drive)
mode = 2;
switch(mode) {
+ case 3: mask = 0x3f; break;
case 2: mask = 0x1f; break;
case 1: mask = 0x07; break;
default: mask = 0x00; break;
@@ -195,19 +196,6 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, ultra_enable);
}
-static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
-{
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
{
unsigned int reg;
@@ -372,105 +360,62 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
{
- if (!hwif->irq)
- hwif->irq = hwif->channel ? 15 : 14;
-
hwif->set_pio_mode = &svwks_set_pio_mode;
hwif->set_dma_mode = &svwks_set_dma_mode;
hwif->udma_filter = &svwks_udma_filter;
- hwif->atapi_dma = 1;
-
- if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
- hwif->ultra_mask = 0x3f;
-
- hwif->mwdma_mask = 0x07;
-
- hwif->autodma = 0;
-
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
if (!hwif->dma_base)
return;
- hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_svwks(hwif);
}
- if (!noautodma)
- hwif->autodma = 1;
-
- hwif->drives[0].autodma = hwif->drives[1].autodma = 1;
-}
-
-static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
-{
- return ide_setup_pci_device(dev, d);
-}
-
-static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
-{
- if (!(PCI_FUNC(dev->devfn) & 1)) {
- d->bootable = NEVER_BOARD;
- if (dev->resource[0].start == 0x01f1)
- d->bootable = ON_BOARD;
- }
-
- if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE ||
- dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- d->host_flags |= IDE_HFLAG_SINGLE;
- else
- d->host_flags &= ~IDE_HFLAG_SINGLE;
-
- return ide_setup_pci_device(dev, d);
}
static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
{ /* 0 */
.name = "SvrWks OSB4",
- .init_setup = init_setup_svwks,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = 0x00, /* UDMA is problematic on OSB4 */
},{ /* 1 */
.name = "SvrWks CSB5",
- .init_setup = init_setup_svwks,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
},{ /* 2 */
.name = "SvrWks CSB6",
- .init_setup = init_setup_csb6,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
},{ /* 3 */
.name = "SvrWks CSB6",
- .init_setup = init_setup_csb6,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
},{ /* 4 */
.name = "SvrWks HT1000",
- .init_setup = init_setup_svwks,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .autodma = AUTODMA,
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
}
};
@@ -485,17 +430,29 @@ 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 = &serverworks_chipsets[id->driver_data];
+ ide_pci_device_t d;
+ u8 idx = id->driver_data;
+
+ d = serverworks_chipsets[idx];
+
+ if (idx == 2 || idx == 3) {
+ if ((PCI_FUNC(dev->devfn) & 1) == 0) {
+ if (pci_resource_start(dev, 0) != 0x01f1)
+ d.host_flags &= ~IDE_HFLAG_BOOTABLE;
+ d.host_flags |= IDE_HFLAG_SINGLE;
+ } else
+ d.host_flags &= ~IDE_HFLAG_SINGLE;
+ }
- return d->init_setup(dev, d);
+ return ide_setup_pci_device(dev, &d);
}
-static struct pci_device_id svwks_pci_tbl[] = {
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
- { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+static const struct pci_device_id svwks_pci_tbl[] = {
+ { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0 },
+ { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 1 },
+ { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2 },
+ { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 3 },
+ { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 4 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, svwks_pci_tbl);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 85ffaaa39b1..5af74ea1d46 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -29,6 +29,7 @@
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
+#include <linux/scatterlist.h>
#include <linux/ioc4.h>
#include <asm/io.h>
@@ -295,20 +296,6 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
}
-static int sgiioc4_ide_dma_check(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- /*
- * ->set_pio_mode is not implemented currently
- * so this is just for the completness
- */
- ide_set_max_pio(drive);
-
- return -1;
-}
-
/* returns 1 if dma irq issued, 0 otherwise */
static int
sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
@@ -537,7 +524,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
}
}
- sg++;
+ sg = sg_next(sg);
i--;
}
@@ -605,13 +592,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
if (hwif->dma_base == 0)
return;
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x04;
+ hwif->mwdma_mask = ATA_MWDMA2_ONLY;
hwif->dma_setup = &sgiioc4_ide_dma_setup;
hwif->dma_start = &sgiioc4_ide_dma_start;
hwif->ide_dma_end = &sgiioc4_ide_dma_end;
- hwif->ide_dma_check = &sgiioc4_ide_dma_check;
hwif->ide_dma_on = &sgiioc4_ide_dma_on;
hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
@@ -688,12 +673,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
/* Initializing chipset IRQ Registers */
writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
- hwif->autodma = 0;
-
- if (dma_base && ide_dma_sgiioc4(hwif, dma_base) == 0) {
- hwif->autodma = 1;
- hwif->drives[1].autodma = hwif->drives[0].autodma = 1;
- } else
+ if (dma_base == 0 || ide_dma_sgiioc4(hwif, dma_base))
printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
hwif->name, DRV_NAME);
@@ -711,14 +691,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
static unsigned int __devinit
pci_init_sgiioc4(struct pci_dev *dev)
{
- unsigned int class_rev;
int ret;
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
- class_rev &= 0xff;
printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
- DRV_NAME, pci_name(dev), class_rev);
- if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
+ DRV_NAME, pci_name(dev), dev->revision);
+
+ if (dev->revision < IOC4_SUPPORTED_FIRMWARE_REV) {
printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
"firmware is obsolete - please upgrade to "
"revision46 or higher\n",
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index ce7784996d1..689786df1ed 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.16 Jul 13 2007
+ * linux/drivers/ide/pci/siimage.c Version 1.17 Oct 18 2007
*
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
@@ -180,7 +180,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
ide_hwif_t *hwif = HWIF(drive);
- ide_drive_t *pair = &hwif->drives[drive->dn ^ 1];
+ ide_drive_t *pair = ide_get_paired_drive(drive);
u32 speedt = 0;
u16 speedp = 0;
unsigned long addr = siimage_seldev(drive, 0x04);
@@ -311,27 +311,6 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
}
-/**
- * siimage_configure_drive_for_dma - set up for DMA transfers
- * @drive: drive we are going to set up
- *
- * Set up the drive for DMA, tune the controller and drive as
- * required. If the drive isn't suitable for DMA or we hit
- * other problems then we will drop down to PIO and set up
- * PIO appropriately
- */
-
-static int siimage_config_drive_for_dma (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
/* returns 1 if dma irq issued, 0 otherwise */
static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
{
@@ -661,13 +640,9 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
{
- u32 class_rev = 0;
- u8 tmpbyte = 0;
- u8 BA5_EN = 0;
+ u8 rev = dev->revision, tmpbyte = 0, BA5_EN = 0;
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
- class_rev &= 0xff;
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
pci_read_config_byte(dev, 0x8A, &BA5_EN);
if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) {
@@ -846,19 +821,14 @@ static void __devinit siimage_fixup(ide_hwif_t *hwif)
static void __devinit init_iops_siimage(ide_hwif_t *hwif)
{
- struct pci_dev *dev = hwif->pci_dev;
- u32 class_rev = 0;
-
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
- class_rev &= 0xff;
-
hwif->hwif_data = NULL;
/* Pessimal until we finish probing */
hwif->rqsize = 15;
- if (pci_get_drvdata(dev) == NULL)
+ if (pci_get_drvdata(hwif->pci_dev) == NULL)
return;
+
init_mmio_iops_siimage(hwif);
}
@@ -894,8 +864,6 @@ static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
{
- hwif->autodma = 0;
-
hwif->resetproc = &siimage_reset;
hwif->set_pio_mode = &sil_set_pio_mode;
hwif->set_dma_mode = &sil_set_dma_mode;
@@ -914,18 +882,11 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
}
}
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
if (hwif->dma_base == 0)
return;
- hwif->ultra_mask = 0x7f;
- hwif->mwdma_mask = 0x07;
-
- if (!is_sata(hwif))
- hwif->atapi_dma = 1;
-
- hwif->ide_dma_check = &siimage_config_drive_for_dma;
+ if (is_sata(hwif))
+ hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_siimage(hwif);
@@ -935,15 +896,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
} else {
hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
}
-
- /*
- * The BIOS often doesn't set up DMA on this controller
- * so we always do it.
- */
-
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
#define DECLARE_SII_DEV(name_str) \
@@ -953,9 +905,10 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
.init_iops = init_iops_siimage, \
.init_hwif = init_hwif_siimage, \
.fixup = siimage_fixup, \
- .autodma = AUTODMA, \
- .bootable = ON_BOARD, \
+ .host_flags = IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
+ .mwdma_mask = ATA_MWDMA2, \
+ .udma_mask = ATA_UDMA6, \
}
static ide_pci_device_t siimage_chipsets[] __devinitdata = {
@@ -978,11 +931,11 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi
return ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]);
}
-static struct pci_device_id siimage_pci_tbl[] = {
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id siimage_pci_tbl[] = {
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), 0 },
#ifdef CONFIG_BLK_DEV_IDE_SATA
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_3112), 1 },
+ { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_1210SA), 2 },
#endif
{ 0, },
};
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index b375ee53d66..c1d280b0639 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/sis5513.c Version 0.27 Jul 14, 2007
+ * linux/drivers/ide/pci/sis5513.c Version 0.31 Aug 9, 2007
*
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
@@ -65,8 +65,6 @@
#include "ide-timing.h"
-#define DISPLAY_SIS_TIMINGS
-
/* registers layout and init values are chipset family dependant */
#define ATA_16 0x01
@@ -193,362 +191,124 @@ static char* chipset_capability[] = {
"ATA 133 (1st gen)", "ATA 133 (2nd gen)"
};
-#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 sis_proc = 0;
-
-static struct pci_dev *bmide_dev;
-
-static char* cable_type[] = {
- "80 pins",
- "40 pins"
-};
+/*
+ * Configuration functions
+ */
-static char* recovery_time[] ={
- "12 PCICLK", "1 PCICLK",
- "2 PCICLK", "3 PCICLK",
- "4 PCICLK", "5 PCICLCK",
- "6 PCICLK", "7 PCICLCK",
- "8 PCICLK", "9 PCICLCK",
- "10 PCICLK", "11 PCICLK",
- "13 PCICLK", "14 PCICLK",
- "15 PCICLK", "15 PCICLK"
-};
+static u8 sis_ata133_get_base(ide_drive_t *drive)
+{
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ u32 reg54 = 0;
-static char* active_time[] = {
- "8 PCICLK", "1 PCICLCK",
- "2 PCICLK", "3 PCICLK",
- "4 PCICLK", "5 PCICLK",
- "6 PCICLK", "12 PCICLK"
-};
+ pci_read_config_dword(dev, 0x54, &reg54);
-static char* cycle_time[] = {
- "Reserved", "2 CLK",
- "3 CLK", "4 CLK",
- "5 CLK", "6 CLK",
- "7 CLK", "8 CLK",
- "9 CLK", "10 CLK",
- "11 CLK", "12 CLK",
- "13 CLK", "14 CLK",
- "15 CLK", "16 CLK"
-};
+ return ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4;
+}
-/* Generic add master or slave info function */
-static char* get_drives_info (char *buffer, u8 pos)
+static void sis_ata16_program_timings(ide_drive_t *drive, const u8 mode)
{
- u8 reg00, reg01, reg10, reg11; /* timing registers */
- u32 regdw0, regdw1;
- char* p = buffer;
-
-/* Postwrite/Prefetch */
- if (chipset_family < ATA_133) {
- pci_read_config_byte(bmide_dev, 0x4b, &reg00);
- p += sprintf(p, "Drive %d: Postwrite %s \t \t Postwrite %s\n",
- pos, (reg00 & (0x10 << pos)) ? "Enabled" : "Disabled",
- (reg00 & (0x40 << pos)) ? "Enabled" : "Disabled");
- p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n",
- (reg00 & (0x01 << pos)) ? "Enabled" : "Disabled",
- (reg00 & (0x04 << pos)) ? "Enabled" : "Disabled");
- pci_read_config_byte(bmide_dev, 0x40+2*pos, &reg00);
- pci_read_config_byte(bmide_dev, 0x41+2*pos, &reg01);
- pci_read_config_byte(bmide_dev, 0x44+2*pos, &reg10);
- pci_read_config_byte(bmide_dev, 0x45+2*pos, &reg11);
- } else {
- u32 reg54h;
- u8 drive_pci = 0x40;
- pci_read_config_dword(bmide_dev, 0x54, &reg54h);
- if (reg54h & 0x40000000) {
- // Configuration space remapped to 0x70
- drive_pci = 0x70;
- }
- pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, &regdw0);
- pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, &regdw1);
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ u16 t1 = 0;
+ u8 drive_pci = 0x40 + drive->dn * 2;
- p += sprintf(p, "Drive %d:\n", pos);
- }
+ const u16 pio_timings[] = { 0x000, 0x607, 0x404, 0x303, 0x301 };
+ const u16 mwdma_timings[] = { 0x008, 0x302, 0x301 };
+ pci_read_config_word(dev, drive_pci, &t1);
-/* UDMA */
- if (chipset_family >= ATA_133) {
- p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n",
- (regdw0 & 0x04) ? "Enabled" : "Disabled",
- (regdw1 & 0x04) ? "Enabled" : "Disabled");
- p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
- cycle_time[(regdw0 & 0xF0) >> 4],
- cycle_time[(regdw1 & 0xF0) >> 4]);
- } else if (chipset_family >= ATA_33) {
- p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n",
- (reg01 & 0x80) ? "Enabled" : "Disabled",
- (reg11 & 0x80) ? "Enabled" : "Disabled");
-
- p += sprintf(p, " UDMA Cycle Time ");
- switch(chipset_family) {
- case ATA_33: p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break;
- case ATA_66:
- case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
- case ATA_100:
- case ATA_133a: p += sprintf(p, cycle_time[reg01 & 0x0F]); break;
- default: p += sprintf(p, "?"); break;
- }
- p += sprintf(p, " \t UDMA Cycle Time ");
- switch(chipset_family) {
- case ATA_33: p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break;
- case ATA_66:
- case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
- case ATA_100:
- case ATA_133a: p += sprintf(p, cycle_time[reg11 & 0x0F]); break;
- default: p += sprintf(p, "?"); break;
- }
- p += sprintf(p, "\n");
- }
+ /* clear active/recovery timings */
+ t1 &= ~0x070f;
+ if (mode >= XFER_MW_DMA_0) {
+ if (chipset_family > ATA_16)
+ t1 &= ~0x8000; /* disable UDMA */
+ t1 |= mwdma_timings[mode - XFER_MW_DMA_0];
+ } else
+ t1 |= pio_timings[mode - XFER_PIO_0];
+ pci_write_config_word(dev, drive_pci, t1);
+}
- if (chipset_family < ATA_133) { /* else case TODO */
+static void sis_ata100_program_timings(ide_drive_t *drive, const u8 mode)
+{
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ u8 t1, drive_pci = 0x40 + drive->dn * 2;
-/* Data Active */
- p += sprintf(p, " Data Active Time ");
- switch(chipset_family) {
- case ATA_16: /* confirmed */
- case ATA_33:
- case ATA_66:
- case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
- case ATA_100:
- case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
- default: p += sprintf(p, "?"); break;
- }
- p += sprintf(p, " \t Data Active Time ");
- switch(chipset_family) {
- case ATA_16:
- case ATA_33:
- case ATA_66:
- case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
- case ATA_100:
- case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
- default: p += sprintf(p, "?"); break;
- }
- p += sprintf(p, "\n");
+ /* timing bits: 7:4 active 3:0 recovery */
+ const u8 pio_timings[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
+ const u8 mwdma_timings[] = { 0x08, 0x32, 0x31 };
-/* Data Recovery */
- /* warning: may need (reg&0x07) for pre ATA66 chips */
- p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n",
- recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]);
- }
+ if (mode >= XFER_MW_DMA_0) {
+ u8 t2 = 0;
- return p;
-}
+ pci_read_config_byte(dev, drive_pci, &t2);
+ t2 &= ~0x80; /* disable UDMA */
+ pci_write_config_byte(dev, drive_pci, t2);
-static char* get_masters_info(char* buffer)
-{
- return get_drives_info(buffer, 0);
-}
+ t1 = mwdma_timings[mode - XFER_MW_DMA_0];
+ } else
+ t1 = pio_timings[mode - XFER_PIO_0];
-static char* get_slaves_info(char* buffer)
-{
- return get_drives_info(buffer, 1);
+ pci_write_config_byte(dev, drive_pci + 1, t1);
}
-/* Main get_info, called on /proc/ide/sis reads */
-static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
+static void sis_ata133_program_timings(ide_drive_t *drive, const u8 mode)
{
- char *p = buffer;
- int len;
- u8 reg;
- u16 reg2, reg3;
-
- p += sprintf(p, "\nSiS 5513 ");
- switch(chipset_family) {
- case ATA_16: p += sprintf(p, "DMA 16"); break;
- case ATA_33: p += sprintf(p, "Ultra 33"); break;
- case ATA_66: p += sprintf(p, "Ultra 66"); break;
- case ATA_100a:
- case ATA_100: p += sprintf(p, "Ultra 100"); break;
- case ATA_133a:
- case ATA_133: p += sprintf(p, "Ultra 133"); break;
- default: p+= sprintf(p, "Unknown???"); break;
- }
- p += sprintf(p, " chipset\n");
- p += sprintf(p, "--------------- Primary Channel "
- "---------------- Secondary Channel "
- "-------------\n");
-
-/* Status */
- pci_read_config_byte(bmide_dev, 0x4a, &reg);
- if (chipset_family == ATA_133) {
- pci_read_config_word(bmide_dev, 0x50, &reg2);
- pci_read_config_word(bmide_dev, 0x52, &reg3);
- }
- p += sprintf(p, "Channel Status: ");
- if (chipset_family < ATA_66) {
- p += sprintf(p, "%s \t \t \t \t %s\n",
- (reg & 0x04) ? "On" : "Off",
- (reg & 0x02) ? "On" : "Off");
- } else if (chipset_family < ATA_133) {
- p += sprintf(p, "%s \t \t \t \t %s \n",
- (reg & 0x02) ? "On" : "Off",
- (reg & 0x04) ? "On" : "Off");
- } else { /* ATA_133 */
- p += sprintf(p, "%s \t \t \t \t %s \n",
- (reg2 & 0x02) ? "On" : "Off",
- (reg3 & 0x02) ? "On" : "Off");
- }
-
-/* Operation Mode */
- pci_read_config_byte(bmide_dev, 0x09, &reg);
- p += sprintf(p, "Operation Mode: %s \t \t \t %s \n",
- (reg & 0x01) ? "Native" : "Compatible",
- (reg & 0x04) ? "Native" : "Compatible");
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ u32 t1 = 0;
+ u8 drive_pci = sis_ata133_get_base(drive), clk, idx;
-/* 80-pin cable ? */
- if (chipset_family >= ATA_133) {
- p += sprintf(p, "Cable Type: %s \t \t \t %s\n",
- (reg2 & 0x01) ? cable_type[1] : cable_type[0],
- (reg3 & 0x01) ? cable_type[1] : cable_type[0]);
- } else if (chipset_family > ATA_33) {
- pci_read_config_byte(bmide_dev, 0x48, &reg);
- p += sprintf(p, "Cable Type: %s \t \t \t %s\n",
- (reg & 0x10) ? cable_type[1] : cable_type[0],
- (reg & 0x20) ? cable_type[1] : cable_type[0]);
- }
+ pci_read_config_dword(dev, drive_pci, &t1);
-/* Prefetch Count */
- if (chipset_family < ATA_133) {
- pci_read_config_word(bmide_dev, 0x4c, &reg2);
- pci_read_config_word(bmide_dev, 0x4e, &reg3);
- p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n",
- reg2, reg3);
+ t1 &= 0xc0c00fff;
+ clk = (t1 & 0x08) ? ATA_133 : ATA_100;
+ if (mode >= XFER_MW_DMA_0) {
+ t1 &= ~0x04; /* disable UDMA */
+ idx = mode - XFER_MW_DMA_0 + 5;
}
+ idx = mode - XFER_PIO_0;
+ t1 |= ini_time_value[clk][idx] << 12;
+ t1 |= act_time_value[clk][idx] << 16;
+ t1 |= rco_time_value[clk][idx] << 24;
- p = get_masters_info(p);
- p = get_slaves_info(p);
-
- len = (p - buffer) - offset;
- *addr = buffer + offset;
+ pci_write_config_dword(dev, drive_pci, t1);
+}
- return len > count ? count : len;
+static void sis_program_timings(ide_drive_t *drive, const u8 mode)
+{
+ if (chipset_family < ATA_100) /* ATA_16/33/66/100a */
+ sis_ata16_program_timings(drive, mode);
+ else if (chipset_family < ATA_133) /* ATA_100/133a */
+ sis_ata100_program_timings(drive, mode);
+ else /* ATA_133 */
+ sis_ata133_program_timings(drive, mode);
}
-#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
-/*
- * Configuration functions
- */
-/* Enables per-drive prefetch and postwrite */
static void config_drive_art_rwp (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
-
u8 reg4bh = 0;
- u8 rw_prefetch = (0x11 << drive->dn);
+ u8 rw_prefetch = 0;
- if (drive->media != ide_disk)
- return;
pci_read_config_byte(dev, 0x4b, &reg4bh);
- if ((reg4bh & rw_prefetch) != rw_prefetch)
+ if (drive->media == ide_disk)
+ rw_prefetch = 0x11 << drive->dn;
+
+ if ((reg4bh & (0x11 << drive->dn)) != rw_prefetch)
pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
}
-/* Set per-drive active and recovery time */
static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
-
- u8 drive_pci, test1, test2;
-
config_drive_art_rwp(drive);
-
- /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
- drive_pci = 0x40;
- /* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */
- if (chipset_family >= ATA_133) {
- u32 reg54h;
- pci_read_config_dword(dev, 0x54, &reg54h);
- if (reg54h & 0x40000000) drive_pci = 0x70;
- drive_pci += ((drive->dn)*0x4);
- } else {
- drive_pci += ((drive->dn)*0x2);
- }
-
- /* register layout changed with newer ATA100 chips */
- if (chipset_family < ATA_100) {
- pci_read_config_byte(dev, drive_pci, &test1);
- pci_read_config_byte(dev, drive_pci+1, &test2);
-
- /* Clear active and recovery timings */
- test1 &= ~0x0F;
- test2 &= ~0x07;
-
- switch(pio) {
- case 4: test1 |= 0x01; test2 |= 0x03; break;
- case 3: test1 |= 0x03; test2 |= 0x03; break;
- case 2: test1 |= 0x04; test2 |= 0x04; break;
- case 1: test1 |= 0x07; test2 |= 0x06; break;
- case 0: /* PIO0: register setting == X000 */
- default: break;
- }
- pci_write_config_byte(dev, drive_pci, test1);
- pci_write_config_byte(dev, drive_pci+1, test2);
- } else if (chipset_family < ATA_133) {
- switch(pio) { /* active recovery
- v v */
- case 4: test1 = 0x30|0x01; break;
- case 3: test1 = 0x30|0x03; break;
- case 2: test1 = 0x40|0x04; break;
- case 1: test1 = 0x60|0x07; break;
- case 0: test1 = 0x00; break;
- default: break;
- }
- pci_write_config_byte(dev, drive_pci, test1);
- } else { /* ATA_133 */
- u32 test3;
- pci_read_config_dword(dev, drive_pci, &test3);
- test3 &= 0xc0c00fff;
- if (test3 & 0x08) {
- test3 |= ini_time_value[ATA_133][pio] << 12;
- test3 |= act_time_value[ATA_133][pio] << 16;
- test3 |= rco_time_value[ATA_133][pio] << 24;
- } else {
- test3 |= ini_time_value[ATA_100][pio] << 12;
- test3 |= act_time_value[ATA_100][pio] << 16;
- test3 |= rco_time_value[ATA_100][pio] << 24;
- }
- pci_write_config_dword(dev, drive_pci, test3);
- }
+ sis_program_timings(drive, XFER_PIO_0 + pio);
}
static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- u32 regdw;
- u8 drive_pci, reg;
-
- /* See sis_set_pio_mode() for drive PCI config registers */
- drive_pci = 0x40;
- if (chipset_family >= ATA_133) {
- u32 reg54h;
- pci_read_config_dword(dev, 0x54, &reg54h);
- if (reg54h & 0x40000000) drive_pci = 0x70;
- drive_pci += ((drive->dn)*0x4);
- pci_read_config_dword(dev, (unsigned long)drive_pci, &regdw);
- /* Disable UDMA bit for non UDMA modes on UDMA chips */
- if (speed < XFER_UDMA_0) {
- regdw &= 0xfffffffb;
- pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
- }
-
- } else {
- drive_pci += ((drive->dn)*0x2);
- pci_read_config_byte(dev, drive_pci+1, &reg);
- /* Disable UDMA bit for non UDMA modes on UDMA chips */
- if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) {
- reg &= 0x7F;
- pci_write_config_byte(dev, drive_pci+1, reg);
- }
- }
/* Config chip for mode */
switch(speed) {
@@ -560,6 +320,10 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
case XFER_UDMA_1:
case XFER_UDMA_0:
if (chipset_family >= ATA_133) {
+ u32 regdw = 0;
+ u8 drive_pci = sis_ata133_get_base(drive);
+
+ pci_read_config_dword(dev, drive_pci, &regdw);
regdw |= 0x04;
regdw &= 0xfffff00f;
/* check if ATA133 enable */
@@ -572,6 +336,9 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
} else {
+ u8 drive_pci = 0x40 + drive->dn * 2, reg = 0;
+
+ pci_read_config_byte(dev, drive_pci+1, &reg);
/* Force the UDMA bit on if we want to use UDMA */
reg |= 0x80;
/* clean reg cycle time bits */
@@ -586,9 +353,7 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
- case XFER_SW_DMA_2:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
+ sis_program_timings(drive, speed);
break;
default:
BUG();
@@ -596,32 +361,12 @@ static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
}
-static int sis5513_config_xfer_rate(ide_drive_t *drive)
-{
- /*
- * TODO: always set PIO mode and remove this
- */
- ide_set_max_pio(drive);
-
- drive->init_speed = 0;
-
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
{
struct pci_dev *dev = drive->hwif->pci_dev;
- int drive_pci;
- u32 reg54 = 0, regdw = 0;
+ u32 regdw = 0;
+ u8 drive_pci = sis_ata133_get_base(drive);
- pci_read_config_dword(dev, 0x54, &reg54);
- drive_pci = ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4;
pci_read_config_dword(dev, drive_pci, &regdw);
/* if ATA133 disable, we should not set speed above UDMA5 */
@@ -767,14 +512,6 @@ static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const c
}
break;
}
-
-#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
- if (!sis_proc) {
- sis_proc = 1;
- bmide_dev = dev;
- ide_pci_create_host_proc("sis", sis_get_info);
- }
-#endif
}
return 0;
@@ -827,53 +564,30 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
{
u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
- hwif->autodma = 0;
-
- if (!hwif->irq)
- hwif->irq = hwif->channel ? 15 : 14;
-
hwif->set_pio_mode = &sis_set_pio_mode;
hwif->set_dma_mode = &sis_set_dma_mode;
if (chipset_family >= ATA_133)
hwif->udma_filter = sis5513_ata133_udma_filter;
- if (!(hwif->dma_base)) {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
-
- hwif->atapi_dma = 1;
hwif->ultra_mask = udma_rates[chipset_family];
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
-
- if (!chipset_family)
- return;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = ata66_sis5513(hwif);
-
- if (chipset_family > ATA_16) {
- hwif->ide_dma_check = &sis5513_config_xfer_rate;
- if (!noautodma)
- hwif->autodma = 1;
- }
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
- return;
}
static ide_pci_device_t sis5513_chipset __devinitdata = {
.name = "SIS5513",
.init_chipset = init_chipset_sis5513,
.init_hwif = init_hwif_sis5513,
- .autodma = NOAUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
};
static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -881,10 +595,10 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi
return ide_setup_pci_device(dev, &sis5513_chipset);
}
-static struct pci_device_id sis5513_pci_tbl[] = {
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5518, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id sis5513_pci_tbl[] = {
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_5513), 0 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_5518), 0 },
+ { PCI_VDEVICE(SI, PCI_DEVICE_ID_SI_1180), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, sis5513_pci_tbl);
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 2ef26e3f7be..0dce459b126 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -145,19 +145,6 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/*
- * Check to see if the drive and chipset are capable of DMA mode.
- */
-static int sl82c105_ide_dma_check(ide_drive_t *drive)
-{
- DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name));
-
- if (ide_tune_dma(drive))
- return 0;
-
- return -1;
-}
-
-/*
* The SL82C105 holds off all IDE interrupts while in DMA mode until
* all DMA activity is completed. Sometimes this causes problems (eg,
* when the drive wants to report an error condition).
@@ -381,12 +368,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1;
hwif->drives[0].unmask = hwif->drives[1].unmask = 1;
- /*
- * We always autotune PIO, this is done before DMA is checked,
- * so there's no risk of accidentally disabling DMA
- */
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
if (!hwif->dma_base)
return;
@@ -401,20 +382,14 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
return;
}
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x07;
+ hwif->mwdma_mask = ATA_MWDMA2;
- hwif->ide_dma_check = &sl82c105_ide_dma_check;
hwif->ide_dma_on = &sl82c105_ide_dma_on;
hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
hwif->dma_lost_irq = &sl82c105_dma_lost_irq;
hwif->dma_start = &sl82c105_dma_start;
hwif->dma_timeout = &sl82c105_dma_timeout;
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
-
if (hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
}
@@ -423,9 +398,8 @@ static ide_pci_device_t sl82c105_chipset __devinitdata = {
.name = "W82C105",
.init_chipset = init_chipset_sl82c105,
.init_hwif = init_hwif_sl82c105,
- .autodma = NOAUTODMA,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_NO_AUTODMA | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
};
@@ -434,8 +408,8 @@ static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_dev
return ide_setup_pci_device(dev, &sl82c105_chipset);
}
-static struct pci_device_id sl82c105_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), 0},
+static const struct pci_device_id sl82c105_pci_tbl[] = {
+ { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl);
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index ebac87f7200..4f22dffdf8e 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.16 Jul 14, 2007
+ * linux/drivers/ide/pci/slc90e66.c Version 0.18 Aug 9, 2007
*
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
@@ -21,27 +21,6 @@
#include <asm/io.h>
-static u8 slc90e66_dma_2_pio (u8 xfer_rate) {
- switch(xfer_rate) {
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- case XFER_MW_DMA_2:
- return 4;
- case XFER_MW_DMA_1:
- return 3;
- case XFER_SW_DMA_2:
- return 2;
- case XFER_MW_DMA_0:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
- default:
- return 0;
- }
-}
-
static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -132,26 +111,21 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_word(dev, 0x4a, reg4a|u_speed);
}
} else {
+ const u8 mwdma_to_pio[] = { 0, 3, 4 };
+ u8 pio;
+
if (reg48 & u_flag)
pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- }
- slc90e66_set_pio_mode(drive, slc90e66_dma_2_pio(speed));
-}
-
-static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
-{
- drive->init_speed = 0;
+ if (speed >= XFER_MW_DMA_0)
+ pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ else
+ pio = 2; /* only SWDMA2 is allowed */
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
+ slc90e66_set_pio_mode(drive, pio);
+ }
}
static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
@@ -159,46 +133,28 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
u8 reg47 = 0;
u8 mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */
- hwif->autodma = 0;
-
- if (!hwif->irq)
- hwif->irq = hwif->channel ? 15 : 14;
-
hwif->set_pio_mode = &slc90e66_set_pio_mode;
hwif->set_dma_mode = &slc90e66_set_dma_mode;
pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
return;
- }
-
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x1f;
- hwif->mwdma_mask = 0x06;
- hwif->swdma_mask = 0x04;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
/* bit[0(1)]: 0:80, 1:40 */
hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
-
- hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t slc90e66_chipset __devinitdata = {
.name = "SLC90E66",
.init_hwif = init_hwif_slc90e66,
- .autodma = AUTODMA,
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .swdma_mask = ATA_SWDMA2_ONLY,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA4,
};
static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -206,8 +162,8 @@ static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_dev
return ide_setup_pci_device(dev, &slc90e66_chipset);
}
-static struct pci_device_id slc90e66_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1), 0},
+static const struct pci_device_id slc90e66_pci_tbl[] = {
+ { PCI_VDEVICE(EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl);
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 840415d68d3..631506e9b5d 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -1,5 +1,5 @@
/*
- * drivers/ide/pci/tc86c001.c Version 1.00 Dec 12, 2006
+ * drivers/ide/pci/tc86c001.c Version 1.01 Sep 5, 2007
*
* Copyright (C) 2002 Toshiba Corporation
* Copyright (C) 2005-2006 MontaVista Software, Inc. <source@mvista.com>
@@ -17,7 +17,7 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
- u16 mode, scr = hwif->INW(scr_port);
+ u16 mode, scr = inw(scr_port);
switch (speed) {
case XFER_UDMA_4: mode = 0x00c0; break;
@@ -65,7 +65,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive);
ide_expiry_t *expiry = ide_get_hwifdata(hwif);
ide_hwgroup_t *hwgroup = HWGROUP(drive);
- u8 dma_stat = hwif->INB(hwif->dma_status);
+ u8 dma_stat = inb(hwif->dma_status);
/* Restore a higher level driver's expiry handler first. */
hwgroup->expiry = expiry;
@@ -73,7 +73,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */
unsigned long sc_base = hwif->config_data;
unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
- u8 dma_cmd = hwif->INB(hwif->dma_command);
+ u8 dma_cmd = inb(hwif->dma_command);
printk(KERN_WARNING "%s: DMA interrupt possibly stuck, "
"attempting recovery...\n", drive->name);
@@ -135,7 +135,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
u16 scr1;
/* System Control 1 Register bit 11 (ATA Hard Reset) read */
- scr1 = hwif->INW(sc_base + 0x00);
+ scr1 = inw(sc_base + 0x00);
switch (state) {
case BUSSTATE_ON:
@@ -162,21 +162,10 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
return 0;
}
-static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- if (ide_use_fast_pio(drive))
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
{
unsigned long sc_base = pci_resource_start(hwif->pci_dev, 5);
- u16 scr1 = hwif->INW(sc_base + 0x00);;
+ u16 scr1 = inw(sc_base + 0x00);
/* System Control 1 Register bit 15 (Soft Reset) set */
outw(scr1 | 0x8000, sc_base + 0x00);
@@ -195,8 +184,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
hwif->busproc = &tc86c001_busproc;
- hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-
if (!hwif->dma_base)
return;
@@ -209,11 +196,6 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
/* Sector Count Register limit */
hwif->rqsize = 0xffff;
- hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x1f;
- hwif->mwdma_mask = 0x07;
-
- hwif->ide_dma_check = &tc86c001_config_drive_xfer_rate;
hwif->dma_start = &tc86c001_dma_start;
if (hwif->cbl != ATA_CBL_PATA40_SHORT) {
@@ -221,13 +203,9 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
* System Control 1 Register bit 13 (PDIAGN):
* 0=80-pin cable, 1=40-pin cable
*/
- scr1 = hwif->INW(sc_base + 0x00);
+ scr1 = inw(sc_base + 0x00);
hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
}
static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
@@ -244,10 +222,10 @@ static ide_pci_device_t tc86c001_chipset __devinitdata = {
.name = "TC86C001",
.init_chipset = init_chipset_tc86c001,
.init_hwif = init_hwif_tc86c001,
- .autodma = AUTODMA,
- .bootable = OFF_BOARD,
- .host_flags = IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
};
static int __devinit tc86c001_init_one(struct pci_dev *dev,
@@ -256,9 +234,8 @@ static int __devinit tc86c001_init_one(struct pci_dev *dev,
return ide_setup_pci_device(dev, &tc86c001_chipset);
}
-static struct pci_device_id tc86c001_pci_tbl[] = {
- { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id tc86c001_pci_tbl[] = {
+ { PCI_VDEVICE(TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE), 0 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, tc86c001_pci_tbl);
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index 54e411d4e56..30b52f62699 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -96,42 +96,20 @@ static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
triflex_set_mode(drive, XFER_PIO_0 + pio);
}
-static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
{
hwif->set_pio_mode = &triflex_set_pio_mode;
hwif->set_dma_mode = &triflex_set_mode;
-
- if (hwif->dma_base == 0)
- return;
-
- hwif->atapi_dma = 1;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
- hwif->ide_dma_check = &triflex_config_drive_xfer_rate;
-
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t triflex_device __devinitdata = {
.name = "TRIFLEX",
.init_hwif = init_hwif_triflex,
- .autodma = AUTODMA,
.enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
};
static int __devinit triflex_init_one(struct pci_dev *dev,
@@ -140,9 +118,8 @@ static int __devinit triflex_init_one(struct pci_dev *dev,
return ide_setup_pci_device(dev, &triflex_device);
}
-static struct pci_device_id triflex_pci_tbl[] = {
- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+static const struct pci_device_id triflex_pci_tbl[] = {
+ { PCI_VDEVICE(COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, triflex_pci_tbl);
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index dc4f4e298e0..140d486f623 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->no_lba48 = 1;
hwif->chipset = ide_trm290;
cfgbase = pci_resource_start(dev, 4);
if ((dev->class & 5) && cfgbase) {
@@ -292,9 +291,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
hwif->selectproc = &trm290_selectproc;
- hwif->autodma = 0; /* play it safe for now */
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
#if 1
{
/*
@@ -327,8 +323,13 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
static ide_pci_device_t trm290_chipset __devinitdata = {
.name = "TRM290",
.init_hwif = init_hwif_trm290,
- .autodma = NOAUTODMA,
- .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
+#if 0 /* play it safe for now */
+ IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+#endif
+ IDE_HFLAG_NO_AUTODMA |
+ IDE_HFLAG_BOOTABLE |
+ IDE_HFLAG_NO_LBA48,
};
static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -336,8 +337,8 @@ static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_devic
return ide_setup_pci_device(dev, &trm290_chipset);
}
-static struct pci_device_id trm290_pci_tbl[] = {
- { PCI_VENDOR_ID_TEKRAM, PCI_DEVICE_ID_TEKRAM_DC290, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id trm290_pci_tbl[] = {
+ { PCI_VDEVICE(TEKRAM, PCI_DEVICE_ID_TEKRAM_DC290), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, trm290_pci_tbl);
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 479e4966103..c8022a92a0e 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -197,24 +197,6 @@ static void via_set_pio_mode(ide_drive_t *drive, const u8 pio)
via_set_drive(drive, XFER_PIO_0 + pio);
}
-/**
- * via82cxxx_ide_dma_check - set up for DMA if possible
- * @drive: IDE drive to set up
- *
- * Set up the drive for the highest supported speed considering the
- * driver, controller and cable
- */
-
-static int via82cxxx_ide_dma_check (ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- ide_set_max_pio(drive);
-
- return -1;
-}
-
static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
{
struct via_isa_bridge *via_config;
@@ -443,8 +425,6 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
int i;
- hwif->autodma = 0;
-
hwif->set_pio_mode = &via_set_pio_mode;
hwif->set_dma_mode = &via_set_drive;
@@ -457,27 +437,15 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
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;
- hwif->drives[i].autotune = 1;
- hwif->drives[i].dn = hwif->channel * 2 + i;
}
if (!hwif->dma_base)
return;
- hwif->atapi_dma = 1;
-
hwif->ultra_mask = vdev->via_config->udma_mask;
- hwif->mwdma_mask = 0x07;
- hwif->swdma_mask = 0x07;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = via82cxxx_cable_detect(hwif);
-
- hwif->ide_dma_check = &via82cxxx_ide_dma_check;
- if (!noautodma)
- hwif->autodma = 1;
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
}
static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
@@ -485,24 +453,27 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
.name = "VP_IDE",
.init_chipset = init_chipset_via82cxxx,
.init_hwif = init_hwif_via82cxxx,
- .autodma = NOAUTODMA,
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST
- | IDE_HFLAG_PIO_NO_DOWNGRADE
- | IDE_HFLAG_POST_SET_MODE,
+ .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,
- .autodma = AUTODMA,
.enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
- .bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST
- | IDE_HFLAG_PIO_NO_DOWNGRADE
- | IDE_HFLAG_POST_SET_MODE,
+ .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,
}
};
@@ -522,11 +493,11 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
}
-static struct pci_device_id via_pci_tbl[] = {
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_SATA_EIDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+static const struct pci_device_id via_pci_tbl[] = {
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, via_pci_tbl);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 7d8873839e2..c5547935676 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1421,17 +1421,12 @@ static struct macio_driver pmac_ide_macio_driver =
.resume = pmac_ide_macio_resume,
};
-static struct pci_device_id pmac_ide_pci_match[] = {
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id pmac_ide_pci_match[] = {
+ { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA), 0 },
+ { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100), 0 },
+ { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100), 0 },
+ { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_SH_ATA), 0 },
+ { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA), 0 },
{},
};
@@ -1539,7 +1534,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
cur_len -= tc;
++table;
}
- sg++;
+ sg = sg_next(sg);
i--;
}
@@ -1579,19 +1574,6 @@ pmac_ide_destroy_dmatable (ide_drive_t *drive)
}
/*
- * Check what is the best DMA timing setting for the drive and
- * call appropriate functions to apply it.
- */
-static int
-pmac_ide_dma_check(ide_drive_t *drive)
-{
- if (ide_tune_dma(drive))
- return 0;
-
- return -1;
-}
-
-/*
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
@@ -1788,7 +1770,6 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->dma_off_quietly = &ide_dma_off_quietly;
hwif->ide_dma_on = &__ide_dma_on;
- hwif->ide_dma_check = &pmac_ide_dma_check;
hwif->dma_setup = &pmac_ide_dma_setup;
hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd;
hwif->dma_start = &pmac_ide_dma_start;
@@ -1799,7 +1780,6 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->dma_timeout = &ide_dma_timeout;
hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
- hwif->atapi_dma = 1;
switch(pmif->kind) {
case controller_sh_ata6:
hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07;
@@ -1823,9 +1803,6 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->swdma_mask = 0x00;
break;
}
-
- hwif->autodma = 1;
- hwif->drives[1].autodma = hwif->drives[0].autodma = hwif->autodma;
}
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 1129f8c3084..fff567bcedb 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -145,74 +145,36 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
}
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
-
-#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
-/*
- * Long lost data from 2.0.34 that is now in 2.0.39
- *
- * This was used in ./drivers/block/triton.c to do DMA Base address setup
- * when PnP failed. Oh the things we forget. I believe this was part
- * of SFF-8038i that has been withdrawn from public access... :-((
- */
-#define DEFAULT_BMIBA 0xe800 /* in case BIOS did not init it */
-#define DEFAULT_BMCRBA 0xcc00 /* VIA's default value */
-#define DEFAULT_BMALIBA 0xd400 /* ALI's default value */
-#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
-
/**
* ide_get_or_set_dma_base - setup BMIBA
+ * @d: IDE pci device data
* @hwif: Interface
*
- * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
- * If need be we set up the DMA base. Where a device has a partner that
- * is already in DMA mode we check and enforce IDE simplex rules.
+ * 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_hwif_t *hwif)
+static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hwif)
{
unsigned long dma_base = 0;
struct pci_dev *dev = hwif->pci_dev;
-#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
- int second_chance = 0;
-
-second_chance_to_dma:
-#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
-
if (hwif->mmio)
return hwif->dma_base;
if (hwif->mate && hwif->mate->dma_base) {
dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
} else {
- dma_base = pci_resource_start(dev, 4);
- if (!dma_base) {
- printk(KERN_ERR "%s: dma_base is invalid\n",
- hwif->cds->name);
- }
- }
+ u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4;
-#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
- /* FIXME - should use pci_assign_resource surely */
- if ((!dma_base) && (!second_chance)) {
- unsigned long set_bmiba = 0;
- second_chance++;
- switch(dev->vendor) {
- case PCI_VENDOR_ID_AL:
- set_bmiba = DEFAULT_BMALIBA; break;
- case PCI_VENDOR_ID_VIA:
- set_bmiba = DEFAULT_BMCRBA; break;
- case PCI_VENDOR_ID_INTEL:
- set_bmiba = DEFAULT_BMIBA; break;
- default:
- return dma_base;
- }
- pci_write_config_dword(dev, 0x20, set_bmiba|1);
- goto second_chance_to_dma;
+ dma_base = pci_resource_start(dev, baridx);
+
+ if (dma_base == 0)
+ printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
- if (dma_base) {
+ if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) {
u8 simplex_stat = 0;
dma_base += hwif->channel ? 8 : 0;
@@ -223,13 +185,13 @@ second_chance_to_dma:
case PCI_DEVICE_ID_CMD_643:
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
case PCI_DEVICE_ID_REVOLUTION:
- simplex_stat = hwif->INB(dma_base + 2);
- hwif->OUTB((simplex_stat&0x60),(dma_base + 2));
- simplex_stat = hwif->INB(dma_base + 2);
+ simplex_stat = inb(dma_base + 2);
+ outb(simplex_stat & 0x60, dma_base + 2);
+ simplex_stat = inb(dma_base + 2);
if (simplex_stat & 0x80) {
printk(KERN_INFO "%s: simplex device: "
- "DMA forced\n",
- hwif->cds->name);
+ "DMA forced\n",
+ d->name);
}
break;
default:
@@ -252,8 +214,8 @@ second_chance_to_dma:
*/
if (hwif->mate && hwif->mate->dma_base) {
printk(KERN_INFO "%s: simplex device: "
- "DMA disabled\n",
- hwif->cds->name);
+ "DMA disabled\n",
+ d->name);
dma_base = 0;
}
}
@@ -400,6 +362,7 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
{
unsigned long ctl = 0, base = 0;
ide_hwif_t *hwif;
+ u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0;
if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
/* Possibly we should fail if these checks report true */
@@ -420,7 +383,7 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
ctl = port ? 0x374 : 0x3f4;
base = port ? 0x170 : 0x1f0;
}
- if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL)
+ if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL)
return NULL; /* no room in ide_hwifs[] */
if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
@@ -467,19 +430,18 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
{
u16 pcicmd;
+
pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
- if ((d->autodma == AUTODMA) ||
+ if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
(dev->class & 0x80))) {
- unsigned long dma_base = ide_get_or_set_dma_base(hwif);
+ unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
/*
* Set up BM-DMA capability
* (PnP BIOS should have done this)
*/
- /* default DMA off if we had to configure it here */
- hwif->autodma = 0;
pci_set_master(dev);
if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {
printk(KERN_ERR "%s: %s error updating PCICMD\n",
@@ -516,7 +478,6 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config)
{
int ret;
- u32 class_rev;
u16 pcicmd;
if (noisy)
@@ -539,10 +500,9 @@ 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);
}
- pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
- class_rev &= 0xff;
if (noisy)
- printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev);
+ printk(KERN_INFO "%s: chipset revision %d\n",
+ d->name, dev->revision);
out:
return ret;
}
@@ -599,17 +559,27 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
if (d->init_iops)
d->init_iops(hwif);
- if (d->autodma == NODMA)
- goto bypass_legacy_dma;
-
- if(d->init_setup_dma)
- d->init_setup_dma(dev, d, hwif);
- else
+ if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
ide_hwif_setup_dma(dev, d, hwif);
-bypass_legacy_dma:
+
+ if ((d->host_flags & IDE_HFLAG_LEGACY_IRQS) && hwif->irq == 0)
+ hwif->irq = port ? 15 : 14;
+
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 (hwif->dma_base) {
+ hwif->swdma_mask = d->swdma_mask;
+ hwif->mwdma_mask = d->mwdma_mask;
+ hwif->ultra_mask = d->udma_mask;
+ }
+
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+
if (d->init_hwif)
/* Call chipset-specific routine
* for each enabled hwif
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index d08166bda1c..e8122def164 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -218,12 +218,10 @@ static struct csr1212_keyval *csr1212_new_keyval(u8 type, u8 key)
if (!kv)
return NULL;
+ atomic_set(&kv->refcnt, 1);
kv->key.type = type;
kv->key.id = key;
-
kv->associate = NULL;
- kv->refcnt = 1;
-
kv->next = NULL;
kv->prev = NULL;
kv->offset = 0;
@@ -326,12 +324,13 @@ void csr1212_associate_keyval(struct csr1212_keyval *kv,
if (kv->associate)
csr1212_release_keyval(kv->associate);
- associate->refcnt++;
+ csr1212_keep_keyval(associate);
kv->associate = associate;
}
-int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
- struct csr1212_keyval *kv)
+static int __csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
+ struct csr1212_keyval *kv,
+ bool keep_keyval)
{
struct csr1212_dentry *dentry;
@@ -341,10 +340,10 @@ int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
if (!dentry)
return -ENOMEM;
+ if (keep_keyval)
+ csr1212_keep_keyval(kv);
dentry->kv = kv;
- kv->refcnt++;
-
dentry->next = NULL;
dentry->prev = dir->value.directory.dentries_tail;
@@ -358,6 +357,12 @@ int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
return CSR1212_SUCCESS;
}
+int csr1212_attach_keyval_to_directory(struct csr1212_keyval *dir,
+ struct csr1212_keyval *kv)
+{
+ return __csr1212_attach_keyval_to_directory(dir, kv, true);
+}
+
#define CSR1212_DESCRIPTOR_LEAF_DATA(kv) \
(&((kv)->value.leaf.data[1]))
@@ -483,15 +488,18 @@ void csr1212_detach_keyval_from_directory(struct csr1212_keyval *dir,
/* This function is used to free the memory taken by a keyval. If the given
* keyval is a directory type, then any keyvals contained in that directory
- * will be destroyed as well if their respective refcnts are 0. By means of
+ * will be destroyed as well if noone holds a reference on them. By means of
* list manipulation, this routine will descend a directory structure in a
* non-recursive manner. */
-static void csr1212_destroy_keyval(struct csr1212_keyval *kv)
+void csr1212_release_keyval(struct csr1212_keyval *kv)
{
struct csr1212_keyval *k, *a;
struct csr1212_dentry dentry;
struct csr1212_dentry *head, *tail;
+ if (!atomic_dec_and_test(&kv->refcnt))
+ return;
+
dentry.kv = kv;
dentry.next = NULL;
dentry.prev = NULL;
@@ -503,9 +511,8 @@ static void csr1212_destroy_keyval(struct csr1212_keyval *kv)
k = head->kv;
while (k) {
- k->refcnt--;
-
- if (k->refcnt > 0)
+ /* must not dec_and_test kv->refcnt again */
+ if (k != kv && !atomic_dec_and_test(&k->refcnt))
break;
a = k->associate;
@@ -536,14 +543,6 @@ static void csr1212_destroy_keyval(struct csr1212_keyval *kv)
}
}
-void csr1212_release_keyval(struct csr1212_keyval *kv)
-{
- if (kv->refcnt > 1)
- kv->refcnt--;
- else
- csr1212_destroy_keyval(kv);
-}
-
void csr1212_destroy_csr(struct csr1212_csr *csr)
{
struct csr1212_csr_rom_cache *c, *oc;
@@ -1126,6 +1125,7 @@ csr1212_parse_dir_entry(struct csr1212_keyval *dir, u32 ki, u32 kv_pos)
int ret = CSR1212_SUCCESS;
struct csr1212_keyval *k = NULL;
u32 offset;
+ bool keep_keyval = true;
switch (CSR1212_KV_KEY_TYPE(ki)) {
case CSR1212_KV_TYPE_IMMEDIATE:
@@ -1135,8 +1135,8 @@ csr1212_parse_dir_entry(struct csr1212_keyval *dir, u32 ki, u32 kv_pos)
ret = -ENOMEM;
goto out;
}
-
- k->refcnt = 0; /* Don't keep local reference when parsing. */
+ /* Don't keep local reference when parsing. */
+ keep_keyval = false;
break;
case CSR1212_KV_TYPE_CSR_OFFSET:
@@ -1146,7 +1146,8 @@ csr1212_parse_dir_entry(struct csr1212_keyval *dir, u32 ki, u32 kv_pos)
ret = -ENOMEM;
goto out;
}
- k->refcnt = 0; /* Don't keep local reference when parsing. */
+ /* Don't keep local reference when parsing. */
+ keep_keyval = false;
break;
default:
@@ -1174,8 +1175,10 @@ csr1212_parse_dir_entry(struct csr1212_keyval *dir, u32 ki, u32 kv_pos)
ret = -ENOMEM;
goto out;
}
- k->refcnt = 0; /* Don't keep local reference when parsing. */
- k->valid = 0; /* Contents not read yet so it's not valid. */
+ /* Don't keep local reference when parsing. */
+ keep_keyval = false;
+ /* Contents not read yet so it's not valid. */
+ k->valid = 0;
k->offset = offset;
k->prev = dir;
@@ -1183,7 +1186,7 @@ csr1212_parse_dir_entry(struct csr1212_keyval *dir, u32 ki, u32 kv_pos)
dir->next->prev = k;
dir->next = k;
}
- ret = csr1212_attach_keyval_to_directory(dir, k);
+ ret = __csr1212_attach_keyval_to_directory(dir, k, keep_keyval);
out:
if (ret != CSR1212_SUCCESS && k != NULL)
free_keyval(k);
diff --git a/drivers/ieee1394/csr1212.h b/drivers/ieee1394/csr1212.h
index df909ce6630..043039fc63e 100644
--- a/drivers/ieee1394/csr1212.h
+++ b/drivers/ieee1394/csr1212.h
@@ -32,6 +32,7 @@
#include <linux/types.h>
#include <linux/slab.h>
+#include <asm/atomic.h>
#define CSR1212_MALLOC(size) kmalloc((size), GFP_KERNEL)
#define CSR1212_FREE(ptr) kfree(ptr)
@@ -149,7 +150,7 @@ struct csr1212_keyval {
struct csr1212_directory directory;
} value;
struct csr1212_keyval *associate;
- int refcnt;
+ atomic_t refcnt;
/* used in generating and/or parsing CSR image */
struct csr1212_keyval *next, *prev; /* flat list of CSR elements */
@@ -350,7 +351,8 @@ csr1212_get_keyval(struct csr1212_csr *csr, struct csr1212_keyval *kv);
* need for code to retain a keyval that has been parsed. */
static inline void csr1212_keep_keyval(struct csr1212_keyval *kv)
{
- kv->refcnt++;
+ atomic_inc(&kv->refcnt);
+ smp_mb__after_atomic_inc();
}
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index dc9dce22f6a..b166b3575fa 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -1153,8 +1153,6 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
pdg->sz++;
lh = find_partial_datagram(pdgl, dgl);
} else {
- struct partial_datagram *pd;
-
pd = list_entry(lh, struct partial_datagram, list);
if (fragment_overlap(&pd->frag_info, fg_off, fg_len)) {
@@ -1222,23 +1220,19 @@ static int ether1394_data_handler(struct net_device *dev, int srcid, int destid,
priv->stats.rx_errors++;
priv->stats.rx_dropped++;
dev_kfree_skb_any(skb);
- goto bad_proto;
- }
-
- if (netif_rx(skb) == NET_RX_DROP) {
+ } else if (netif_rx(skb) == NET_RX_DROP) {
priv->stats.rx_errors++;
priv->stats.rx_dropped++;
- goto bad_proto;
+ } else {
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += skb->len;
}
- /* Statistics */
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += skb->len;
+ spin_unlock_irqrestore(&priv->lock, flags);
bad_proto:
if (netif_queue_stopped(dev))
netif_wake_queue(dev);
- spin_unlock_irqrestore(&priv->lock, flags);
dev->last_rx = jiffies;
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 98fd985a32f..36c747b277d 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -488,7 +488,7 @@ void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
highlevel_host_reset(host);
}
-static spinlock_t pending_packets_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pending_packets_lock);
/**
* hpsb_packet_sent - notify core of sending a packet
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 1939fee616e..90dc75be341 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1014,13 +1014,13 @@ static struct unit_directory *nodemgr_process_unit_directory
CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE(kv) == 0) {
switch (last_key_id) {
case CSR1212_KV_ID_VENDOR:
- ud->vendor_name_kv = kv;
csr1212_keep_keyval(kv);
+ ud->vendor_name_kv = kv;
break;
case CSR1212_KV_ID_MODEL:
- ud->model_name_kv = kv;
csr1212_keep_keyval(kv);
+ ud->model_name_kv = kv;
break;
}
@@ -1112,7 +1112,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
{
unsigned int ud_id = 0;
struct csr1212_dentry *dentry;
- struct csr1212_keyval *kv;
+ struct csr1212_keyval *kv, *vendor_name_kv = NULL;
u8 last_key_id = 0;
ne->needs_probe = 0;
@@ -1139,8 +1139,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
CSR1212_TEXTUAL_DESCRIPTOR_LEAF_WIDTH(kv) == 0 &&
CSR1212_TEXTUAL_DESCRIPTOR_LEAF_CHAR_SET(kv) == 0 &&
CSR1212_TEXTUAL_DESCRIPTOR_LEAF_LANGUAGE(kv) == 0) {
- ne->vendor_name_kv = kv;
csr1212_keep_keyval(kv);
+ vendor_name_kv = kv;
}
}
break;
@@ -1149,10 +1149,13 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
}
if (ne->vendor_name_kv) {
- int error = device_create_file(&ne->device,
- &dev_attr_ne_vendor_name_kv);
-
- if (error && error != -EEXIST)
+ kv = ne->vendor_name_kv;
+ ne->vendor_name_kv = vendor_name_kv;
+ csr1212_release_keyval(kv);
+ } else if (vendor_name_kv) {
+ ne->vendor_name_kv = vendor_name_kv;
+ if (device_create_file(&ne->device,
+ &dev_attr_ne_vendor_name_kv) != 0)
HPSB_ERR("Failed to add sysfs attribute");
}
}
@@ -1712,7 +1715,8 @@ static int nodemgr_host_thread(void *__hi)
* to make sure things settle down. */
g = get_hpsb_generation(host);
for (i = 0; i < 4 ; i++) {
- if (msleep_interruptible(63) || kthread_should_stop())
+ msleep_interruptible(63);
+ if (kthread_should_stop())
goto exit;
/* Now get the generation in which the node ID's we collect
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index d1a5bcdb5e0..8af01ab30cc 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -121,16 +121,6 @@ static int bit_getsda(void *data)
return reg_read((struct ti_lynx *) data, SERIAL_EEPROM_CONTROL) & 0x00000010;
}
-static int bit_reg(struct i2c_client *client)
-{
- return 0;
-}
-
-static int bit_unreg(struct i2c_client *client)
-{
- return 0;
-}
-
static struct i2c_algo_bit_data bit_data = {
.setsda = bit_setsda,
.setscl = bit_setscl,
@@ -140,14 +130,6 @@ static struct i2c_algo_bit_data bit_data = {
.timeout = 100,
};
-static struct i2c_adapter bit_ops = {
- .id = 0xAA, //FIXME: probably we should get an id in i2c-id.h
- .client_register = bit_reg,
- .client_unregister = bit_unreg,
- .name = "PCILynx I2C",
-};
-
-
/*
* PCL handling functions.
@@ -765,7 +747,6 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg)
} else {
struct ti_pcl pcl;
u32 ack;
- struct hpsb_packet *packet;
PRINT(KERN_INFO, lynx->id, "cancelling async packet, that was already in PCL");
@@ -1436,9 +1417,11 @@ static int __devinit add_card(struct pci_dev *dev,
struct i2c_algo_bit_data i2c_adapter_data;
error = -ENOMEM;
- i2c_ad = kmemdup(&bit_ops, sizeof(*i2c_ad), GFP_KERNEL);
+ i2c_ad = kzalloc(sizeof(*i2c_ad), GFP_KERNEL);
if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
+ i2c_ad->id = I2C_HW_B_PCILYNX;
+ strlcpy(i2c_ad->name, "PCILynx I2C", sizeof(i2c_ad->name));
i2c_adapter_data = bit_data;
i2c_ad->algo_data = &i2c_adapter_data;
i2c_adapter_data.data = lynx;
@@ -1465,13 +1448,11 @@ static int __devinit add_card(struct pci_dev *dev,
{ 0x50, I2C_M_RD, 20, (unsigned char*) lynx->bus_info_block }
};
- /* we use i2c_transfer, because i2c_smbus_read_block_data does not work properly and we
- do it more efficiently in one transaction rather then using several reads */
+ /* we use i2c_transfer because we have no i2c_client
+ at hand */
if (i2c_transfer(i2c_ad, msg, 2) < 0) {
PRINT(KERN_ERR, lynx->id, "unable to read bus info block from i2c");
} else {
- int i;
-
PRINT(KERN_INFO, lynx->id, "got bus info block from serial eeprom");
/* FIXME: probably we shoud rewrite the max_rec, max_ROM(1394a),
* generation(1394a) and link_spd(1394a) field and recalculate
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index a81ba8fca0d..1b353b964b3 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -242,6 +242,8 @@ static int sbp2_max_speed_and_size(struct sbp2_lu *);
static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
+static DEFINE_RWLOCK(sbp2_hi_logical_units_lock);
+
static struct hpsb_highlevel sbp2_highlevel = {
.name = SBP2_DEVICE_NAME,
.host_reset = sbp2_host_reset,
@@ -732,6 +734,7 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
struct sbp2_fwhost_info *hi;
struct Scsi_Host *shost = NULL;
struct sbp2_lu *lu = NULL;
+ unsigned long flags;
lu = kzalloc(sizeof(*lu), GFP_KERNEL);
if (!lu) {
@@ -784,7 +787,9 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
lu->hi = hi;
+ write_lock_irqsave(&sbp2_hi_logical_units_lock, flags);
list_add_tail(&lu->lu_list, &hi->logical_units);
+ write_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags);
/* Register the status FIFO address range. We could use the same FIFO
* for targets at different nodes. However we need different FIFOs per
@@ -828,16 +833,20 @@ static void sbp2_host_reset(struct hpsb_host *host)
{
struct sbp2_fwhost_info *hi;
struct sbp2_lu *lu;
+ unsigned long flags;
hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
if (!hi)
return;
+
+ read_lock_irqsave(&sbp2_hi_logical_units_lock, flags);
list_for_each_entry(lu, &hi->logical_units, lu_list)
if (likely(atomic_read(&lu->state) !=
SBP2LU_STATE_IN_SHUTDOWN)) {
atomic_set(&lu->state, SBP2LU_STATE_IN_RESET);
scsi_block_requests(lu->shost);
}
+ read_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags);
}
static int sbp2_start_device(struct sbp2_lu *lu)
@@ -919,6 +928,7 @@ alloc_fail:
static void sbp2_remove_device(struct sbp2_lu *lu)
{
struct sbp2_fwhost_info *hi;
+ unsigned long flags;
if (!lu)
return;
@@ -933,7 +943,9 @@ static void sbp2_remove_device(struct sbp2_lu *lu)
flush_scheduled_work();
sbp2util_remove_command_orb_pool(lu, hi->host);
+ write_lock_irqsave(&sbp2_hi_logical_units_lock, flags);
list_del(&lu->lu_list);
+ write_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags);
if (lu->login_response)
dma_free_coherent(hi->host->device.parent,
@@ -1707,6 +1719,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
}
/* Find the unit which wrote the status. */
+ read_lock_irqsave(&sbp2_hi_logical_units_lock, flags);
list_for_each_entry(lu_tmp, &hi->logical_units, lu_list) {
if (lu_tmp->ne->nodeid == nodeid &&
lu_tmp->status_fifo_addr == addr) {
@@ -1714,6 +1727,8 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
break;
}
}
+ read_unlock_irqrestore(&sbp2_hi_logical_units_lock, flags);
+
if (unlikely(!lu)) {
SBP2_ERR("lu is NULL - device is gone?");
return RCODE_ADDRESS_ERROR;
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 0f7a55d35ea..3f2d68cff76 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -107,7 +107,7 @@ struct ehca_sport {
struct ehca_shca {
struct ib_device ib_device;
- struct ibmebus_dev *ibmebus_dev;
+ struct of_device *ofdev;
u8 num_ports;
int hw_level;
struct list_head shca_list;
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index 1d41faa7a33..b4ac617a70e 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -123,7 +123,7 @@ int ehca_create_eq(struct ehca_shca *shca,
/* register interrupt handlers and initialize work queues */
if (type == EHCA_EQ) {
- ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_eq,
+ ret = ibmebus_request_irq(eq->ist, ehca_interrupt_eq,
IRQF_DISABLED, "ehca_eq",
(void *)shca);
if (ret < 0)
@@ -131,7 +131,7 @@ int ehca_create_eq(struct ehca_shca *shca,
tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
} else if (type == EHCA_NEQ) {
- ret = ibmebus_request_irq(NULL, eq->ist, ehca_interrupt_neq,
+ ret = ibmebus_request_irq(eq->ist, ehca_interrupt_neq,
IRQF_DISABLED, "ehca_neq",
(void *)shca);
if (ret < 0)
@@ -171,7 +171,7 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq)
u64 h_ret;
spin_lock_irqsave(&eq->spinlock, flags);
- ibmebus_free_irq(NULL, eq->ist, (void *)shca);
+ ibmebus_free_irq(eq->ist, (void *)shca);
h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 403467f66fe..7a7dab890f6 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -404,7 +404,7 @@ int ehca_init_device(struct ehca_shca *shca)
shca->ib_device.node_type = RDMA_NODE_IB_CA;
shca->ib_device.phys_port_cnt = shca->num_ports;
shca->ib_device.num_comp_vectors = 1;
- shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev;
+ shca->ib_device.dma_device = &shca->ofdev->dev;
shca->ib_device.query_device = ehca_query_device;
shca->ib_device.query_port = ehca_query_port;
shca->ib_device.query_gid = ehca_query_gid;
@@ -579,12 +579,12 @@ static ssize_t ehca_show_##name(struct device *dev, \
\
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); \
if (!rblock) { \
- dev_err(dev, "Can't allocate rblock memory."); \
+ dev_err(dev, "Can't allocate rblock memory.\n"); \
return 0; \
} \
\
if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
- dev_err(dev, "Can't query device properties"); \
+ dev_err(dev, "Can't query device properties\n"); \
ehca_free_fw_ctrlblock(rblock); \
return 0; \
} \
@@ -658,7 +658,7 @@ static struct attribute_group ehca_dev_attr_grp = {
.attrs = ehca_dev_attrs
};
-static int __devinit ehca_probe(struct ibmebus_dev *dev,
+static int __devinit ehca_probe(struct of_device *dev,
const struct of_device_id *id)
{
struct ehca_shca *shca;
@@ -666,16 +666,16 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
struct ib_pd *ibpd;
int ret;
- handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
+ handle = of_get_property(dev->node, "ibm,hca-handle", NULL);
if (!handle) {
ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
- dev->ofdev.node->full_name);
+ dev->node->full_name);
return -ENODEV;
}
if (!(*handle)) {
ehca_gen_err("Wrong eHCA handle for adapter: %s.",
- dev->ofdev.node->full_name);
+ dev->node->full_name);
return -ENODEV;
}
@@ -686,9 +686,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
}
mutex_init(&shca->modify_mutex);
- shca->ibmebus_dev = dev;
+ shca->ofdev = dev;
shca->ipz_hca_handle.handle = *handle;
- dev->ofdev.dev.driver_data = shca;
+ dev->dev.driver_data = shca;
ret = ehca_sense_attributes(shca);
if (ret < 0) {
@@ -764,7 +764,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
}
}
- ret = sysfs_create_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
+ ret = sysfs_create_group(&dev->dev.kobj, &ehca_dev_attr_grp);
if (ret) /* only complain; we can live without attributes */
ehca_err(&shca->ib_device,
"Cannot create device attributes ret=%d", ret);
@@ -814,12 +814,12 @@ probe1:
return -EINVAL;
}
-static int __devexit ehca_remove(struct ibmebus_dev *dev)
+static int __devexit ehca_remove(struct of_device *dev)
{
- struct ehca_shca *shca = dev->ofdev.dev.driver_data;
+ struct ehca_shca *shca = dev->dev.driver_data;
int ret;
- sysfs_remove_group(&dev->ofdev.dev.kobj, &ehca_dev_attr_grp);
+ sysfs_remove_group(&dev->dev.kobj, &ehca_dev_attr_grp);
if (ehca_open_aqp1 == 1) {
int i;
@@ -870,11 +870,11 @@ static struct of_device_id ehca_device_table[] =
{},
};
-static struct ibmebus_driver ehca_driver = {
- .name = "ehca",
- .id_table = ehca_device_table,
- .probe = ehca_probe,
- .remove = ehca_remove,
+static struct of_platform_driver ehca_driver = {
+ .name = "ehca",
+ .match_table = ehca_device_table,
+ .probe = ehca_probe,
+ .remove = ehca_remove,
};
void ehca_poll_eqs(unsigned long data)
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index f87f003e3ef..22709a4f8fc 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -30,6 +30,7 @@
* SOFTWARE.
*/
+#include <linux/scatterlist.h>
#include <rdma/ib_verbs.h>
#include "ipath_verbs.h"
@@ -96,17 +97,18 @@ static void ipath_dma_unmap_page(struct ib_device *dev,
BUG_ON(!valid_dma_direction(direction));
}
-static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction)
{
+ struct scatterlist *sg;
u64 addr;
int i;
int ret = nents;
BUG_ON(!valid_dma_direction(direction));
- for (i = 0; i < nents; i++) {
- addr = (u64) page_address(sg[i].page);
+ for_each_sg(sgl, sg, nents, i) {
+ addr = (u64) page_address(sg->page);
/* TODO: handle highmem pages */
if (!addr) {
ret = 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 6545fa798b1..1b3327ad6bc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -349,6 +349,7 @@ struct ipoib_neigh {
struct sk_buff_head queue;
struct neighbour *neighbour;
+ struct net_device *dev;
struct list_head list;
};
@@ -365,7 +366,8 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh)
INFINIBAND_ALEN, sizeof(void *));
}
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh);
+struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
+ struct net_device *dev);
void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
extern struct workqueue_struct *ipoib_workqueue;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index e072f3c32ce..362610d870e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -517,7 +517,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
struct ipoib_path *path;
struct ipoib_neigh *neigh;
- neigh = ipoib_neigh_alloc(skb->dst->neighbour);
+ neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
if (!neigh) {
++dev->stats.tx_dropped;
dev_kfree_skb_any(skb);
@@ -692,9 +692,10 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
} else if (neigh->ah) {
- if (unlikely(memcmp(&neigh->dgid.raw,
+ if (unlikely((memcmp(&neigh->dgid.raw,
skb->dst->neighbour->ha + 4,
- sizeof(union ib_gid)))) {
+ sizeof(union ib_gid))) ||
+ (neigh->dev != dev))) {
spin_lock(&priv->lock);
/*
* It's safe to call ipoib_put_ah() inside
@@ -817,6 +818,13 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
unsigned long flags;
struct ipoib_ah *ah = NULL;
+ neigh = *to_ipoib_neigh(n);
+ if (neigh) {
+ priv = netdev_priv(neigh->dev);
+ ipoib_dbg(priv, "neigh_destructor for bonding device: %s\n",
+ n->dev->name);
+ } else
+ return;
ipoib_dbg(priv,
"neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
IPOIB_QPN(n->ha),
@@ -824,13 +832,10 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
spin_lock_irqsave(&priv->lock, flags);
- neigh = *to_ipoib_neigh(n);
- if (neigh) {
- if (neigh->ah)
- ah = neigh->ah;
- list_del(&neigh->list);
- ipoib_neigh_free(n->dev, neigh);
- }
+ if (neigh->ah)
+ ah = neigh->ah;
+ list_del(&neigh->list);
+ ipoib_neigh_free(n->dev, neigh);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -838,7 +843,8 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
ipoib_put_ah(ah);
}
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
+struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour,
+ struct net_device *dev)
{
struct ipoib_neigh *neigh;
@@ -847,6 +853,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
return NULL;
neigh->neighbour = neighbour;
+ neigh->dev = dev;
*to_ipoib_neigh(neighbour) = neigh;
skb_queue_head_init(&neigh->queue);
ipoib_cm_set(neigh, NULL);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 827820ec66d..9bcfc7ad6aa 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -705,7 +705,8 @@ out:
if (skb->dst &&
skb->dst->neighbour &&
!*to_ipoib_neigh(skb->dst->neighbour)) {
- struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour);
+ struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
+ skb->dev);
if (neigh) {
kref_get(&mcast->ah->ref);
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index e05690e3592..f3529b6f0a3 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -124,17 +124,19 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
if (cmd_dir == ISER_DIR_OUT) {
/* copy the unaligned sg the buffer which is used for RDMA */
- struct scatterlist *sg = (struct scatterlist *)data->buf;
+ struct scatterlist *sgl = (struct scatterlist *)data->buf;
+ struct scatterlist *sg;
int i;
char *p, *from;
- for (p = mem, i = 0; i < data->size; i++) {
- from = kmap_atomic(sg[i].page, KM_USER0);
+ p = mem;
+ for_each_sg(sgl, sg, data->size, i) {
+ from = kmap_atomic(sg->page, KM_USER0);
memcpy(p,
- from + sg[i].offset,
- sg[i].length);
+ from + sg->offset,
+ sg->length);
kunmap_atomic(from, KM_USER0);
- p += sg[i].length;
+ p += sg->length;
}
}
@@ -176,7 +178,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
if (cmd_dir == ISER_DIR_IN) {
char *mem;
- struct scatterlist *sg;
+ struct scatterlist *sgl, *sg;
unsigned char *p, *to;
unsigned int sg_size;
int i;
@@ -184,16 +186,17 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
/* copy back read RDMA to unaligned sg */
mem = mem_copy->copy_buf;
- sg = (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf;
+ sgl = (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf;
sg_size = iser_ctask->data[ISER_DIR_IN].size;
- for (p = mem, i = 0; i < sg_size; i++){
- to = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
- memcpy(to + sg[i].offset,
+ p = mem;
+ for_each_sg(sgl, sg, sg_size, i) {
+ to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+ memcpy(to + sg->offset,
p,
- sg[i].length);
+ sg->length);
kunmap_atomic(to, KM_SOFTIRQ0);
- p += sg[i].length;
+ p += sg->length;
}
}
@@ -224,7 +227,8 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
struct iser_page_vec *page_vec,
struct ib_device *ibdev)
{
- struct scatterlist *sg = (struct scatterlist *)data->buf;
+ struct scatterlist *sgl = (struct scatterlist *)data->buf;
+ struct scatterlist *sg;
u64 first_addr, last_addr, page;
int end_aligned;
unsigned int cur_page = 0;
@@ -232,24 +236,25 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
int i;
/* compute the offset of first element */
- page_vec->offset = (u64) sg[0].offset & ~MASK_4K;
+ page_vec->offset = (u64) sgl[0].offset & ~MASK_4K;
- for (i = 0; i < data->dma_nents; i++) {
- unsigned int dma_len = ib_sg_dma_len(ibdev, &sg[i]);
+ for_each_sg(sgl, sg, data->dma_nents, i) {
+ unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
total_sz += dma_len;
- first_addr = ib_sg_dma_address(ibdev, &sg[i]);
+ first_addr = ib_sg_dma_address(ibdev, sg);
last_addr = first_addr + dma_len;
end_aligned = !(last_addr & ~MASK_4K);
/* continue to collect page fragments till aligned or SG ends */
while (!end_aligned && (i + 1 < data->dma_nents)) {
+ sg = sg_next(sg);
i++;
- dma_len = ib_sg_dma_len(ibdev, &sg[i]);
+ dma_len = ib_sg_dma_len(ibdev, sg);
total_sz += dma_len;
- last_addr = ib_sg_dma_address(ibdev, &sg[i]) + dma_len;
+ last_addr = ib_sg_dma_address(ibdev, sg) + dma_len;
end_aligned = !(last_addr & ~MASK_4K);
}
@@ -284,25 +289,26 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
struct ib_device *ibdev)
{
- struct scatterlist *sg;
+ struct scatterlist *sgl, *sg;
u64 end_addr, next_addr;
int i, cnt;
unsigned int ret_len = 0;
- sg = (struct scatterlist *)data->buf;
+ sgl = (struct scatterlist *)data->buf;
- for (cnt = 0, i = 0; i < data->dma_nents; i++, cnt++) {
+ cnt = 0;
+ 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[i].page),
- (unsigned long)sg[i].offset,
- (unsigned long)sg[i].length); */
- end_addr = ib_sg_dma_address(ibdev, &sg[i]) +
- ib_sg_dma_len(ibdev, &sg[i]);
+ (unsigned long)page_to_phys(sg->page),
+ (unsigned long)sg->offset,
+ (unsigned long)sg->length); */
+ end_addr = ib_sg_dma_address(ibdev, sg) +
+ ib_sg_dma_len(ibdev, sg);
/* iser_dbg("Checking sg iobuf end address "
"0x%08lX\n", end_addr); */
if (i + 1 < data->dma_nents) {
- next_addr = ib_sg_dma_address(ibdev, &sg[i+1]);
+ next_addr = ib_sg_dma_address(ibdev, sg_next(sg));
/* are i, i+1 fragments of the same page? */
if (end_addr == next_addr)
continue;
@@ -322,15 +328,16 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
static void iser_data_buf_dump(struct iser_data_buf *data,
struct ib_device *ibdev)
{
- struct scatterlist *sg = (struct scatterlist *)data->buf;
+ struct scatterlist *sgl = (struct scatterlist *)data->buf;
+ struct scatterlist *sg;
int i;
- for (i = 0; i < data->dma_nents; i++)
+ for_each_sg(sgl, sg, data->dma_nents, i)
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[i]),
- sg[i].page, sg[i].offset,
- sg[i].length, ib_sg_dma_len(ibdev, &sg[i]));
+ i, (unsigned long)ib_sg_dma_address(ibdev, sg),
+ sg->page, sg->offset,
+ sg->length, ib_sg_dma_len(ibdev, sg));
}
static void iser_dump_page_vec(struct iser_page_vec *page_vec)
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 2d87357e2b2..63512d906f0 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -114,28 +114,6 @@ config INPUT_JOYDEV
To compile this driver as a module, choose M here: the
module will be called joydev.
-config INPUT_TSDEV
- tristate "Touchscreen interface"
- ---help---
- Say Y here if you have an application that only can understand the
- Compaq touchscreen protocol for absolute pointer data. This is
- useful namely for embedded configurations.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called tsdev.
-
-config INPUT_TSDEV_SCREEN_X
- int "Horizontal screen resolution"
- depends on INPUT_TSDEV
- default "240"
-
-config INPUT_TSDEV_SCREEN_Y
- int "Vertical screen resolution"
- depends on INPUT_TSDEV
- default "320"
-
config INPUT_EVDEV
tristate "Event interface"
help
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 15eb752697b..99af903bd3c 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -13,7 +13,6 @@ obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
obj-$(CONFIG_INPUT_EVDEV) += evdev.o
-obj-$(CONFIG_INPUT_TSDEV) += tsdev.o
obj-$(CONFIG_INPUT_EVBUG) += evbug.o
obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index f1c3d6cebd5..1d62c8b88e1 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -30,6 +30,8 @@ struct evdev {
wait_queue_head_t wait;
struct evdev_client *grab;
struct list_head client_list;
+ spinlock_t client_lock; /* protects client_list */
+ struct mutex mutex;
struct device dev;
};
@@ -37,39 +39,54 @@ struct evdev_client {
struct input_event buffer[EVDEV_BUFFER_SIZE];
int head;
int tail;
+ spinlock_t buffer_lock; /* protects access to buffer, head and tail */
struct fasync_struct *fasync;
struct evdev *evdev;
struct list_head node;
};
static struct evdev *evdev_table[EVDEV_MINORS];
+static DEFINE_MUTEX(evdev_table_mutex);
-static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void evdev_pass_event(struct evdev_client *client,
+ struct input_event *event)
+{
+ /*
+ * Interrupts are disabled, just acquire the lock
+ */
+ spin_lock(&client->buffer_lock);
+ client->buffer[client->head++] = *event;
+ client->head &= EVDEV_BUFFER_SIZE - 1;
+ spin_unlock(&client->buffer_lock);
+
+ kill_fasync(&client->fasync, SIGIO, POLL_IN);
+}
+
+/*
+ * Pass incoming event to all connected clients.
+ */
+static void evdev_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
{
struct evdev *evdev = handle->private;
struct evdev_client *client;
+ struct input_event event;
- if (evdev->grab) {
- client = evdev->grab;
+ do_gettimeofday(&event.time);
+ event.type = type;
+ event.code = code;
+ event.value = value;
- do_gettimeofday(&client->buffer[client->head].time);
- client->buffer[client->head].type = type;
- client->buffer[client->head].code = code;
- client->buffer[client->head].value = value;
- client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1);
+ rcu_read_lock();
- kill_fasync(&client->fasync, SIGIO, POLL_IN);
- } else
- list_for_each_entry(client, &evdev->client_list, node) {
+ client = rcu_dereference(evdev->grab);
+ if (client)
+ evdev_pass_event(client, &event);
+ else
+ list_for_each_entry_rcu(client, &evdev->client_list, node)
+ evdev_pass_event(client, &event);
- do_gettimeofday(&client->buffer[client->head].time);
- client->buffer[client->head].type = type;
- client->buffer[client->head].code = code;
- client->buffer[client->head].value = value;
- client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1);
-
- kill_fasync(&client->fasync, SIGIO, POLL_IN);
- }
+ rcu_read_unlock();
wake_up_interruptible(&evdev->wait);
}
@@ -88,38 +105,140 @@ static int evdev_flush(struct file *file, fl_owner_t id)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
+ int retval;
+
+ retval = mutex_lock_interruptible(&evdev->mutex);
+ if (retval)
+ return retval;
if (!evdev->exist)
- return -ENODEV;
+ retval = -ENODEV;
+ else
+ retval = input_flush_device(&evdev->handle, file);
- return input_flush_device(&evdev->handle, file);
+ mutex_unlock(&evdev->mutex);
+ return retval;
}
static void evdev_free(struct device *dev)
{
struct evdev *evdev = container_of(dev, struct evdev, dev);
- evdev_table[evdev->minor] = NULL;
kfree(evdev);
}
+/*
+ * Grabs an event device (along with underlying input device).
+ * This function is called with evdev->mutex taken.
+ */
+static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
+{
+ int error;
+
+ if (evdev->grab)
+ return -EBUSY;
+
+ error = input_grab_device(&evdev->handle);
+ if (error)
+ return error;
+
+ rcu_assign_pointer(evdev->grab, client);
+ synchronize_rcu();
+
+ return 0;
+}
+
+static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client)
+{
+ if (evdev->grab != client)
+ return -EINVAL;
+
+ rcu_assign_pointer(evdev->grab, NULL);
+ synchronize_rcu();
+ input_release_device(&evdev->handle);
+
+ return 0;
+}
+
+static void evdev_attach_client(struct evdev *evdev,
+ struct evdev_client *client)
+{
+ spin_lock(&evdev->client_lock);
+ list_add_tail_rcu(&client->node, &evdev->client_list);
+ spin_unlock(&evdev->client_lock);
+ synchronize_rcu();
+}
+
+static void evdev_detach_client(struct evdev *evdev,
+ struct evdev_client *client)
+{
+ spin_lock(&evdev->client_lock);
+ list_del_rcu(&client->node);
+ spin_unlock(&evdev->client_lock);
+ synchronize_rcu();
+}
+
+static int evdev_open_device(struct evdev *evdev)
+{
+ int retval;
+
+ retval = mutex_lock_interruptible(&evdev->mutex);
+ if (retval)
+ return retval;
+
+ if (!evdev->exist)
+ retval = -ENODEV;
+ else if (!evdev->open++) {
+ retval = input_open_device(&evdev->handle);
+ if (retval)
+ evdev->open--;
+ }
+
+ mutex_unlock(&evdev->mutex);
+ return retval;
+}
+
+static void evdev_close_device(struct evdev *evdev)
+{
+ mutex_lock(&evdev->mutex);
+
+ if (evdev->exist && !--evdev->open)
+ input_close_device(&evdev->handle);
+
+ mutex_unlock(&evdev->mutex);
+}
+
+/*
+ * Wake up users waiting for IO so they can disconnect from
+ * dead device.
+ */
+static void evdev_hangup(struct evdev *evdev)
+{
+ struct evdev_client *client;
+
+ spin_lock(&evdev->client_lock);
+ list_for_each_entry(client, &evdev->client_list, node)
+ kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ spin_unlock(&evdev->client_lock);
+
+ wake_up_interruptible(&evdev->wait);
+}
+
static int evdev_release(struct inode *inode, struct file *file)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
- if (evdev->grab == client) {
- input_release_device(&evdev->handle);
- evdev->grab = NULL;
- }
+ mutex_lock(&evdev->mutex);
+ if (evdev->grab == client)
+ evdev_ungrab(evdev, client);
+ mutex_unlock(&evdev->mutex);
evdev_fasync(-1, file, 0);
- list_del(&client->node);
+ evdev_detach_client(evdev, client);
kfree(client);
- if (!--evdev->open && evdev->exist)
- input_close_device(&evdev->handle);
-
+ evdev_close_device(evdev);
put_device(&evdev->dev);
return 0;
@@ -127,41 +246,44 @@ static int evdev_release(struct inode *inode, struct file *file)
static int evdev_open(struct inode *inode, struct file *file)
{
- struct evdev_client *client;
struct evdev *evdev;
+ struct evdev_client *client;
int i = iminor(inode) - EVDEV_MINOR_BASE;
int error;
if (i >= EVDEV_MINORS)
return -ENODEV;
+ error = mutex_lock_interruptible(&evdev_table_mutex);
+ if (error)
+ return error;
evdev = evdev_table[i];
+ if (evdev)
+ get_device(&evdev->dev);
+ mutex_unlock(&evdev_table_mutex);
- if (!evdev || !evdev->exist)
+ if (!evdev)
return -ENODEV;
- get_device(&evdev->dev);
-
client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
if (!client) {
error = -ENOMEM;
goto err_put_evdev;
}
+ spin_lock_init(&client->buffer_lock);
client->evdev = evdev;
- list_add_tail(&client->node, &evdev->client_list);
+ evdev_attach_client(evdev, client);
- if (!evdev->open++ && evdev->exist) {
- error = input_open_device(&evdev->handle);
- if (error)
- goto err_free_client;
- }
+ error = evdev_open_device(evdev);
+ if (error)
+ goto err_free_client;
file->private_data = client;
return 0;
err_free_client:
- list_del(&client->node);
+ evdev_detach_client(evdev, client);
kfree(client);
err_put_evdev:
put_device(&evdev->dev);
@@ -197,12 +319,14 @@ static inline size_t evdev_event_size(void)
sizeof(struct input_event_compat) : sizeof(struct input_event);
}
-static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
+static int evdev_event_from_user(const char __user *buffer,
+ struct input_event *event)
{
if (COMPAT_TEST) {
struct input_event_compat compat_event;
- if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat)))
+ if (copy_from_user(&compat_event, buffer,
+ sizeof(struct input_event_compat)))
return -EFAULT;
event->time.tv_sec = compat_event.time.tv_sec;
@@ -219,7 +343,8 @@ static int evdev_event_from_user(const char __user *buffer, struct input_event *
return 0;
}
-static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
+static int evdev_event_to_user(char __user *buffer,
+ const struct input_event *event)
{
if (COMPAT_TEST) {
struct input_event_compat compat_event;
@@ -230,7 +355,8 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev
compat_event.code = event->code;
compat_event.value = event->value;
- if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat)))
+ if (copy_to_user(buffer, &compat_event,
+ sizeof(struct input_event_compat)))
return -EFAULT;
} else {
@@ -248,7 +374,8 @@ static inline size_t evdev_event_size(void)
return sizeof(struct input_event);
}
-static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
+static int evdev_event_from_user(const char __user *buffer,
+ struct input_event *event)
{
if (copy_from_user(event, buffer, sizeof(struct input_event)))
return -EFAULT;
@@ -256,7 +383,8 @@ static int evdev_event_from_user(const char __user *buffer, struct input_event *
return 0;
}
-static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
+static int evdev_event_to_user(char __user *buffer,
+ const struct input_event *event)
{
if (copy_to_user(buffer, event, sizeof(struct input_event)))
return -EFAULT;
@@ -266,37 +394,71 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev
#endif /* CONFIG_COMPAT */
-static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+static ssize_t evdev_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
struct input_event event;
- int retval = 0;
+ int retval;
- if (!evdev->exist)
- return -ENODEV;
+ retval = mutex_lock_interruptible(&evdev->mutex);
+ if (retval)
+ return retval;
+
+ if (!evdev->exist) {
+ retval = -ENODEV;
+ goto out;
+ }
while (retval < count) {
- if (evdev_event_from_user(buffer + retval, &event))
- return -EFAULT;
- input_inject_event(&evdev->handle, event.type, event.code, event.value);
+ if (evdev_event_from_user(buffer + retval, &event)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ input_inject_event(&evdev->handle,
+ event.type, event.code, event.value);
retval += evdev_event_size();
}
+ out:
+ mutex_unlock(&evdev->mutex);
return retval;
}
-static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+static int evdev_fetch_next_event(struct evdev_client *client,
+ struct input_event *event)
+{
+ int have_event;
+
+ spin_lock_irq(&client->buffer_lock);
+
+ have_event = client->head != client->tail;
+ if (have_event) {
+ *event = client->buffer[client->tail++];
+ client->tail &= EVDEV_BUFFER_SIZE - 1;
+ }
+
+ spin_unlock_irq(&client->buffer_lock);
+
+ return have_event;
+}
+
+static ssize_t evdev_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
+ struct input_event event;
int retval;
if (count < evdev_event_size())
return -EINVAL;
- if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK))
+ if (client->head == client->tail && evdev->exist &&
+ (file->f_flags & O_NONBLOCK))
return -EAGAIN;
retval = wait_event_interruptible(evdev->wait,
@@ -307,14 +469,12 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count,
if (!evdev->exist)
return -ENODEV;
- while (client->head != client->tail && retval + evdev_event_size() <= count) {
-
- struct input_event *event = (struct input_event *) client->buffer + client->tail;
+ while (retval + evdev_event_size() <= count &&
+ evdev_fetch_next_event(client, &event)) {
- if (evdev_event_to_user(buffer + retval, event))
+ if (evdev_event_to_user(buffer + retval, &event))
return -EFAULT;
- client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
retval += evdev_event_size();
}
@@ -409,8 +569,8 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
return copy_to_user(p, str, len) ? -EFAULT : len;
}
-static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
- void __user *p, int compat_mode)
+static long evdev_do_ioctl(struct file *file, unsigned int cmd,
+ void __user *p, int compat_mode)
{
struct evdev_client *client = file->private_data;
struct evdev *evdev = client->evdev;
@@ -421,215 +581,289 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
int i, t, u, v;
int error;
- if (!evdev->exist)
- return -ENODEV;
-
switch (cmd) {
- case EVIOCGVERSION:
- return put_user(EV_VERSION, ip);
+ case EVIOCGVERSION:
+ return put_user(EV_VERSION, ip);
- case EVIOCGID:
- if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
- return -EFAULT;
- return 0;
+ case EVIOCGID:
+ if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
+ return -EFAULT;
+ return 0;
- case EVIOCGREP:
- if (!test_bit(EV_REP, dev->evbit))
- return -ENOSYS;
- if (put_user(dev->rep[REP_DELAY], ip))
- return -EFAULT;
- if (put_user(dev->rep[REP_PERIOD], ip + 1))
- return -EFAULT;
- return 0;
+ case EVIOCGREP:
+ if (!test_bit(EV_REP, dev->evbit))
+ return -ENOSYS;
+ if (put_user(dev->rep[REP_DELAY], ip))
+ return -EFAULT;
+ if (put_user(dev->rep[REP_PERIOD], ip + 1))
+ return -EFAULT;
+ return 0;
- case EVIOCSREP:
- if (!test_bit(EV_REP, dev->evbit))
- return -ENOSYS;
- if (get_user(u, ip))
- return -EFAULT;
- if (get_user(v, ip + 1))
- return -EFAULT;
+ case EVIOCSREP:
+ if (!test_bit(EV_REP, dev->evbit))
+ return -ENOSYS;
+ if (get_user(u, ip))
+ return -EFAULT;
+ if (get_user(v, ip + 1))
+ return -EFAULT;
- input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
- input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);
+ input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
+ input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);
- return 0;
+ return 0;
- case EVIOCGKEYCODE:
- if (get_user(t, ip))
- return -EFAULT;
+ case EVIOCGKEYCODE:
+ if (get_user(t, ip))
+ return -EFAULT;
- error = dev->getkeycode(dev, t, &v);
- if (error)
- return error;
+ error = dev->getkeycode(dev, t, &v);
+ if (error)
+ return error;
- if (put_user(v, ip + 1))
- return -EFAULT;
+ if (put_user(v, ip + 1))
+ return -EFAULT;
- return 0;
+ return 0;
- case EVIOCSKEYCODE:
- if (get_user(t, ip) || get_user(v, ip + 1))
- return -EFAULT;
+ case EVIOCSKEYCODE:
+ if (get_user(t, ip) || get_user(v, ip + 1))
+ return -EFAULT;
- return dev->setkeycode(dev, t, v);
+ return dev->setkeycode(dev, t, v);
- case EVIOCSFF:
- if (copy_from_user(&effect, p, sizeof(effect)))
- return -EFAULT;
+ case EVIOCSFF:
+ if (copy_from_user(&effect, p, sizeof(effect)))
+ return -EFAULT;
- error = input_ff_upload(dev, &effect, file);
+ error = input_ff_upload(dev, &effect, file);
- if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
- return -EFAULT;
+ if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
+ return -EFAULT;
- return error;
+ return error;
- case EVIOCRMFF:
- return input_ff_erase(dev, (int)(unsigned long) p, file);
+ case EVIOCRMFF:
+ return input_ff_erase(dev, (int)(unsigned long) p, file);
- case EVIOCGEFFECTS:
- i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
- if (put_user(i, ip))
- return -EFAULT;
- return 0;
-
- case EVIOCGRAB:
- if (p) {
- if (evdev->grab)
- return -EBUSY;
- if (input_grab_device(&evdev->handle))
- return -EBUSY;
- evdev->grab = client;
- return 0;
- } else {
- if (evdev->grab != client)
- return -EINVAL;
- input_release_device(&evdev->handle);
- evdev->grab = NULL;
- return 0;
- }
+ case EVIOCGEFFECTS:
+ i = test_bit(EV_FF, dev->evbit) ?
+ dev->ff->max_effects : 0;
+ if (put_user(i, ip))
+ return -EFAULT;
+ return 0;
+
+ case EVIOCGRAB:
+ if (p)
+ return evdev_grab(evdev, client);
+ else
+ return evdev_ungrab(evdev, client);
- default:
+ default:
- if (_IOC_TYPE(cmd) != 'E')
- return -EINVAL;
+ if (_IOC_TYPE(cmd) != 'E')
+ return -EINVAL;
- if (_IOC_DIR(cmd) == _IOC_READ) {
+ if (_IOC_DIR(cmd) == _IOC_READ) {
- if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
+ if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) {
- unsigned long *bits;
- int len;
+ unsigned long *bits;
+ int len;
- switch (_IOC_NR(cmd) & EV_MAX) {
- case 0: bits = dev->evbit; len = EV_MAX; break;
- case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
- case EV_REL: bits = dev->relbit; len = REL_MAX; break;
- case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
- case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
- case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
- case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
- case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
- case EV_SW: bits = dev->swbit; len = SW_MAX; break;
- default: return -EINVAL;
- }
- return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
- }
+ switch (_IOC_NR(cmd) & EV_MAX) {
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
- return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
- p, compat_mode);
+ case 0: bits = dev->evbit; len = EV_MAX; break;
+ case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
+ case EV_REL: bits = dev->relbit; len = REL_MAX; break;
+ case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
+ case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
+ case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
+ case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
+ case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
+ case EV_SW: bits = dev->swbit; len = SW_MAX; break;
+ default: return -EINVAL;
+ }
+ return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
+ }
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
- return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
- p, compat_mode);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
+ return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
+ p, compat_mode);
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
- return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
- p, compat_mode);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
+ return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
+ p, compat_mode);
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
- return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
- p, compat_mode);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
+ return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
+ p, compat_mode);
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
- return str_to_user(dev->name, _IOC_SIZE(cmd), p);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
+ return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
+ p, compat_mode);
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
- return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
+ return str_to_user(dev->name, _IOC_SIZE(cmd), p);
- if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
- return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
+ return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
- if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
+ if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
+ return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
- t = _IOC_NR(cmd) & ABS_MAX;
+ if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
- abs.value = dev->abs[t];
- abs.minimum = dev->absmin[t];
- abs.maximum = dev->absmax[t];
- abs.fuzz = dev->absfuzz[t];
- abs.flat = dev->absflat[t];
+ t = _IOC_NR(cmd) & ABS_MAX;
- if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
- return -EFAULT;
+ abs.value = dev->abs[t];
+ abs.minimum = dev->absmin[t];
+ abs.maximum = dev->absmax[t];
+ abs.fuzz = dev->absfuzz[t];
+ abs.flat = dev->absflat[t];
- return 0;
- }
+ if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
+ return -EFAULT;
+ return 0;
}
- if (_IOC_DIR(cmd) == _IOC_WRITE) {
+ }
+
+ if (_IOC_DIR(cmd) == _IOC_WRITE) {
- if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
+ if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
- t = _IOC_NR(cmd) & ABS_MAX;
+ t = _IOC_NR(cmd) & ABS_MAX;
- if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
- return -EFAULT;
+ if (copy_from_user(&abs, p,
+ sizeof(struct input_absinfo)))
+ return -EFAULT;
- dev->abs[t] = abs.value;
- dev->absmin[t] = abs.minimum;
- dev->absmax[t] = abs.maximum;
- dev->absfuzz[t] = abs.fuzz;
- dev->absflat[t] = abs.flat;
+ /*
+ * Take event lock to ensure that we are not
+ * changing device parameters in the middle
+ * of event.
+ */
+ spin_lock_irq(&dev->event_lock);
- return 0;
- }
+ dev->abs[t] = abs.value;
+ dev->absmin[t] = abs.minimum;
+ dev->absmax[t] = abs.maximum;
+ dev->absfuzz[t] = abs.fuzz;
+ dev->absflat[t] = abs.flat;
+
+ spin_unlock_irq(&dev->event_lock);
+
+ return 0;
}
+ }
}
return -EINVAL;
}
+static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
+ void __user *p, int compat_mode)
+{
+ struct evdev_client *client = file->private_data;
+ struct evdev *evdev = client->evdev;
+ int retval;
+
+ retval = mutex_lock_interruptible(&evdev->mutex);
+ if (retval)
+ return retval;
+
+ if (!evdev->exist) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ retval = evdev_do_ioctl(file, cmd, p, compat_mode);
+
+ out:
+ mutex_unlock(&evdev->mutex);
+ return retval;
+}
+
static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0);
}
#ifdef CONFIG_COMPAT
-static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+static long evdev_ioctl_compat(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1);
}
#endif
static const struct file_operations evdev_fops = {
- .owner = THIS_MODULE,
- .read = evdev_read,
- .write = evdev_write,
- .poll = evdev_poll,
- .open = evdev_open,
- .release = evdev_release,
- .unlocked_ioctl = evdev_ioctl,
+ .owner = THIS_MODULE,
+ .read = evdev_read,
+ .write = evdev_write,
+ .poll = evdev_poll,
+ .open = evdev_open,
+ .release = evdev_release,
+ .unlocked_ioctl = evdev_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = evdev_ioctl_compat,
+ .compat_ioctl = evdev_ioctl_compat,
#endif
- .fasync = evdev_fasync,
- .flush = evdev_flush
+ .fasync = evdev_fasync,
+ .flush = evdev_flush
};
+static int evdev_install_chrdev(struct evdev *evdev)
+{
+ /*
+ * No need to do any locking here as calls to connect and
+ * disconnect are serialized by the input core
+ */
+ evdev_table[evdev->minor] = evdev;
+ return 0;
+}
+
+static void evdev_remove_chrdev(struct evdev *evdev)
+{
+ /*
+ * Lock evdev table to prevent race with evdev_open()
+ */
+ mutex_lock(&evdev_table_mutex);
+ evdev_table[evdev->minor] = NULL;
+ mutex_unlock(&evdev_table_mutex);
+}
+
+/*
+ * Mark device non-existent. This disables writes, ioctls and
+ * prevents new users from opening the device. Already posted
+ * blocking reads will stay, however new ones will fail.
+ */
+static void evdev_mark_dead(struct evdev *evdev)
+{
+ mutex_lock(&evdev->mutex);
+ evdev->exist = 0;
+ mutex_unlock(&evdev->mutex);
+}
+
+static void evdev_cleanup(struct evdev *evdev)
+{
+ struct input_handle *handle = &evdev->handle;
+
+ evdev_mark_dead(evdev);
+ evdev_hangup(evdev);
+ evdev_remove_chrdev(evdev);
+
+ /* evdev is marked dead so no one else accesses evdev->open */
+ if (evdev->open) {
+ input_flush_device(handle, NULL);
+ input_close_device(handle);
+ }
+}
+
+/*
+ * Create new evdev device. Note that input core serializes calls
+ * to connect and disconnect so we don't need to lock evdev_table here.
+ */
static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
@@ -637,7 +871,10 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
int minor;
int error;
- for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
+ for (minor = 0; minor < EVDEV_MINORS; minor++)
+ if (!evdev_table[minor])
+ break;
+
if (minor == EVDEV_MINORS) {
printk(KERN_ERR "evdev: no more free evdev devices\n");
return -ENFILE;
@@ -648,38 +885,44 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
return -ENOMEM;
INIT_LIST_HEAD(&evdev->client_list);
+ spin_lock_init(&evdev->client_lock);
+ mutex_init(&evdev->mutex);
init_waitqueue_head(&evdev->wait);
+ snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
evdev->exist = 1;
evdev->minor = minor;
+
evdev->handle.dev = dev;
evdev->handle.name = evdev->name;
evdev->handle.handler = handler;
evdev->handle.private = evdev;
- snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
- snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
- "event%d", minor);
+ strlcpy(evdev->dev.bus_id, evdev->name, sizeof(evdev->dev.bus_id));
+ evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
evdev->dev.class = &input_class;
evdev->dev.parent = &dev->dev;
- evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
evdev->dev.release = evdev_free;
device_initialize(&evdev->dev);
- evdev_table[minor] = evdev;
-
- error = device_add(&evdev->dev);
+ error = input_register_handle(&evdev->handle);
if (error)
goto err_free_evdev;
- error = input_register_handle(&evdev->handle);
+ error = evdev_install_chrdev(evdev);
+ if (error)
+ goto err_unregister_handle;
+
+ error = device_add(&evdev->dev);
if (error)
- goto err_delete_evdev;
+ goto err_cleanup_evdev;
return 0;
- err_delete_evdev:
- device_del(&evdev->dev);
+ err_cleanup_evdev:
+ evdev_cleanup(evdev);
+ err_unregister_handle:
+ input_unregister_handle(&evdev->handle);
err_free_evdev:
put_device(&evdev->dev);
return error;
@@ -688,21 +931,10 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
static void evdev_disconnect(struct input_handle *handle)
{
struct evdev *evdev = handle->private;
- struct evdev_client *client;
- input_unregister_handle(handle);
device_del(&evdev->dev);
-
- evdev->exist = 0;
-
- if (evdev->open) {
- input_flush_device(handle, NULL);
- input_close_device(handle);
- list_for_each_entry(client, &evdev->client_list, node)
- kill_fasync(&client->fasync, SIGIO, POLL_HUP);
- wake_up_interruptible(&evdev->wait);
- }
-
+ evdev_cleanup(evdev);
+ input_unregister_handle(handle);
put_device(&evdev->dev);
}
@@ -714,13 +946,13 @@ static const struct input_device_id evdev_ids[] = {
MODULE_DEVICE_TABLE(input, evdev_ids);
static struct input_handler evdev_handler = {
- .event = evdev_event,
- .connect = evdev_connect,
- .disconnect = evdev_disconnect,
- .fops = &evdev_fops,
- .minor = EVDEV_MINOR_BASE,
- .name = "evdev",
- .id_table = evdev_ids,
+ .event = evdev_event,
+ .connect = evdev_connect,
+ .disconnect = evdev_disconnect,
+ .fops = &evdev_fops,
+ .minor = EVDEV_MINOR_BASE,
+ .name = "evdev",
+ .id_table = evdev_ids,
};
static int __init evdev_init(void)
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 20896d5e5f0..ec1b6cfefcd 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -448,9 +448,8 @@ static int gameport_thread(void *nothing)
set_freezable();
do {
gameport_handle_event();
- wait_event_interruptible(gameport_wait,
+ wait_event_freezable(gameport_wait,
kthread_should_stop() || !list_empty(&gameport_event_list));
- try_to_freeze();
} while (!kthread_should_stop());
printk(KERN_DEBUG "gameport: kgameportd exiting\n");
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
index b773d4c756a..92b359894e8 100644
--- a/drivers/input/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -70,6 +70,7 @@ static int input_open_polled_device(struct input_dev *input)
{
struct input_polled_dev *dev = input->private;
int error;
+ unsigned long ticks;
error = input_polldev_start_workqueue();
if (error)
@@ -78,8 +79,10 @@ static int input_open_polled_device(struct input_dev *input)
if (dev->flush)
dev->flush(dev);
- queue_delayed_work(polldev_wq, &dev->work,
- msecs_to_jiffies(dev->poll_interval));
+ ticks = msecs_to_jiffies(dev->poll_interval);
+ if (ticks >= HZ)
+ ticks = round_jiffies(ticks);
+ queue_delayed_work(polldev_wq, &dev->work, ticks);
return 0;
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 5dc361c954e..2f2b020cd62 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -17,10 +17,10 @@
#include <linux/major.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/rcupdate.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("Input core");
@@ -31,167 +31,245 @@ MODULE_LICENSE("GPL");
static LIST_HEAD(input_dev_list);
static LIST_HEAD(input_handler_list);
+/*
+ * input_mutex protects access to both input_dev_list and input_handler_list.
+ * This also causes input_[un]register_device and input_[un]register_handler
+ * be mutually exclusive which simplifies locking in drivers implementing
+ * input handlers.
+ */
+static DEFINE_MUTEX(input_mutex);
+
static struct input_handler *input_table[8];
-/**
- * input_event() - report new input event
- * @dev: device that generated the event
- * @type: type of the event
- * @code: event code
- * @value: value of the event
- *
- * This function should be used by drivers implementing various input devices
- * See also input_inject_event()
- */
-void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static inline int is_event_supported(unsigned int code,
+ unsigned long *bm, unsigned int max)
{
- struct input_handle *handle;
+ return code <= max && test_bit(code, bm);
+}
- if (type > EV_MAX || !test_bit(type, dev->evbit))
- return;
+static int input_defuzz_abs_event(int value, int old_val, int fuzz)
+{
+ if (fuzz) {
+ if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2)
+ return old_val;
- add_input_randomness(type, code, value);
+ if (value > old_val - fuzz && value < old_val + fuzz)
+ return (old_val * 3 + value) / 4;
- switch (type) {
-
- case EV_SYN:
- switch (code) {
- case SYN_CONFIG:
- if (dev->event)
- dev->event(dev, type, code, value);
- break;
-
- case SYN_REPORT:
- if (dev->sync)
- return;
- dev->sync = 1;
- break;
- }
- break;
+ if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2)
+ return (old_val + value) / 2;
+ }
- case EV_KEY:
+ return value;
+}
- if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value)
- return;
+/*
+ * Pass event through all open handles. This function is called with
+ * dev->event_lock held and interrupts disabled.
+ */
+static void input_pass_event(struct input_dev *dev,
+ unsigned int type, unsigned int code, int value)
+{
+ struct input_handle *handle;
- if (value == 2)
- break;
+ rcu_read_lock();
- change_bit(code, dev->key);
+ handle = rcu_dereference(dev->grab);
+ if (handle)
+ handle->handler->event(handle, type, code, value);
+ else
+ list_for_each_entry_rcu(handle, &dev->h_list, d_node)
+ if (handle->open)
+ handle->handler->event(handle,
+ type, code, value);
+ rcu_read_unlock();
+}
- if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && dev->timer.data && value) {
- dev->repeat_key = code;
- mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
- }
+/*
+ * Generate software autorepeat event. Note that we take
+ * dev->event_lock here to avoid racing with input_event
+ * which may cause keys get "stuck".
+ */
+static void input_repeat_key(unsigned long data)
+{
+ struct input_dev *dev = (void *) data;
+ unsigned long flags;
- break;
+ spin_lock_irqsave(&dev->event_lock, flags);
- case EV_SW:
+ if (test_bit(dev->repeat_key, dev->key) &&
+ is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
- if (code > SW_MAX || !test_bit(code, dev->swbit) || !!test_bit(code, dev->sw) == value)
- return;
+ input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
- change_bit(code, dev->sw);
+ if (dev->sync) {
+ /*
+ * Only send SYN_REPORT if we are not in a middle
+ * of driver parsing a new hardware packet.
+ * Otherwise assume that the driver will send
+ * SYN_REPORT once it's done.
+ */
+ input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+ }
- break;
+ if (dev->rep[REP_PERIOD])
+ mod_timer(&dev->timer, jiffies +
+ msecs_to_jiffies(dev->rep[REP_PERIOD]));
+ }
- case EV_ABS:
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
- if (code > ABS_MAX || !test_bit(code, dev->absbit))
- return;
+static void input_start_autorepeat(struct input_dev *dev, int code)
+{
+ if (test_bit(EV_REP, dev->evbit) &&
+ dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
+ dev->timer.data) {
+ dev->repeat_key = code;
+ mod_timer(&dev->timer,
+ jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
+ }
+}
- if (dev->absfuzz[code]) {
- if ((value > dev->abs[code] - (dev->absfuzz[code] >> 1)) &&
- (value < dev->abs[code] + (dev->absfuzz[code] >> 1)))
- return;
+#define INPUT_IGNORE_EVENT 0
+#define INPUT_PASS_TO_HANDLERS 1
+#define INPUT_PASS_TO_DEVICE 2
+#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
- if ((value > dev->abs[code] - dev->absfuzz[code]) &&
- (value < dev->abs[code] + dev->absfuzz[code]))
- value = (dev->abs[code] * 3 + value) >> 2;
+static void input_handle_event(struct input_dev *dev,
+ unsigned int type, unsigned int code, int value)
+{
+ int disposition = INPUT_IGNORE_EVENT;
- if ((value > dev->abs[code] - (dev->absfuzz[code] << 1)) &&
- (value < dev->abs[code] + (dev->absfuzz[code] << 1)))
- value = (dev->abs[code] + value) >> 1;
- }
+ switch (type) {
- if (dev->abs[code] == value)
- return;
+ case EV_SYN:
+ switch (code) {
+ case SYN_CONFIG:
+ disposition = INPUT_PASS_TO_ALL;
+ break;
- dev->abs[code] = value;
+ case SYN_REPORT:
+ if (!dev->sync) {
+ dev->sync = 1;
+ disposition = INPUT_PASS_TO_HANDLERS;
+ }
break;
+ }
+ break;
- case EV_REL:
+ case EV_KEY:
+ if (is_event_supported(code, dev->keybit, KEY_MAX) &&
+ !!test_bit(code, dev->key) != value) {
- if (code > REL_MAX || !test_bit(code, dev->relbit) || (value == 0))
- return;
+ if (value != 2) {
+ __change_bit(code, dev->key);
+ if (value)
+ input_start_autorepeat(dev, code);
+ }
- break;
+ disposition = INPUT_PASS_TO_HANDLERS;
+ }
+ break;
- case EV_MSC:
+ case EV_SW:
+ if (is_event_supported(code, dev->swbit, SW_MAX) &&
+ !!test_bit(code, dev->sw) != value) {
- if (code > MSC_MAX || !test_bit(code, dev->mscbit))
- return;
+ __change_bit(code, dev->sw);
+ disposition = INPUT_PASS_TO_HANDLERS;
+ }
+ break;
- if (dev->event)
- dev->event(dev, type, code, value);
+ case EV_ABS:
+ if (is_event_supported(code, dev->absbit, ABS_MAX)) {
- break;
+ value = input_defuzz_abs_event(value,
+ dev->abs[code], dev->absfuzz[code]);
+
+ if (dev->abs[code] != value) {
+ dev->abs[code] = value;
+ disposition = INPUT_PASS_TO_HANDLERS;
+ }
+ }
+ break;
- case EV_LED:
+ case EV_REL:
+ if (is_event_supported(code, dev->relbit, REL_MAX) && value)
+ disposition = INPUT_PASS_TO_HANDLERS;
- if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
- return;
+ break;
- change_bit(code, dev->led);
+ case EV_MSC:
+ if (is_event_supported(code, dev->mscbit, MSC_MAX))
+ disposition = INPUT_PASS_TO_ALL;
- if (dev->event)
- dev->event(dev, type, code, value);
+ break;
- break;
+ case EV_LED:
+ if (is_event_supported(code, dev->ledbit, LED_MAX) &&
+ !!test_bit(code, dev->led) != value) {
- case EV_SND:
+ __change_bit(code, dev->led);
+ disposition = INPUT_PASS_TO_ALL;
+ }
+ break;
- if (code > SND_MAX || !test_bit(code, dev->sndbit))
- return;
+ case EV_SND:
+ if (is_event_supported(code, dev->sndbit, SND_MAX)) {
if (!!test_bit(code, dev->snd) != !!value)
- change_bit(code, dev->snd);
+ __change_bit(code, dev->snd);
+ disposition = INPUT_PASS_TO_ALL;
+ }
+ break;
- if (dev->event)
- dev->event(dev, type, code, value);
+ case EV_REP:
+ if (code <= REP_MAX && value >= 0 && dev->rep[code] != value) {
+ dev->rep[code] = value;
+ disposition = INPUT_PASS_TO_ALL;
+ }
+ break;
- break;
+ case EV_FF:
+ if (value >= 0)
+ disposition = INPUT_PASS_TO_ALL;
+ break;
+ }
- case EV_REP:
+ if (type != EV_SYN)
+ dev->sync = 0;
- if (code > REP_MAX || value < 0 || dev->rep[code] == value)
- return;
+ if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
+ dev->event(dev, type, code, value);
- dev->rep[code] = value;
- if (dev->event)
- dev->event(dev, type, code, value);
+ if (disposition & INPUT_PASS_TO_HANDLERS)
+ input_pass_event(dev, type, code, value);
+}
- break;
+/**
+ * input_event() - report new input event
+ * @dev: device that generated the event
+ * @type: type of the event
+ * @code: event code
+ * @value: value of the event
+ *
+ * This function should be used by drivers implementing various input
+ * devices. See also input_inject_event().
+ */
- case EV_FF:
+void input_event(struct input_dev *dev,
+ unsigned int type, unsigned int code, int value)
+{
+ unsigned long flags;
- if (value < 0)
- return;
+ if (is_event_supported(type, dev->evbit, EV_MAX)) {
- if (dev->event)
- dev->event(dev, type, code, value);
- break;
+ spin_lock_irqsave(&dev->event_lock, flags);
+ add_input_randomness(type, code, value);
+ input_handle_event(dev, type, code, value);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
}
-
- if (type != EV_SYN)
- dev->sync = 0;
-
- if (dev->grab)
- dev->grab->handler->event(dev->grab, type, code, value);
- else
- list_for_each_entry(handle, &dev->h_list, d_node)
- if (handle->open)
- handle->handler->event(handle, type, code, value);
}
EXPORT_SYMBOL(input_event);
@@ -202,102 +280,228 @@ EXPORT_SYMBOL(input_event);
* @code: event code
* @value: value of the event
*
- * Similar to input_event() but will ignore event if device is "grabbed" and handle
- * injecting event is not the one that owns the device.
+ * Similar to input_event() but will ignore event if device is
+ * "grabbed" and handle injecting event is not the one that owns
+ * the device.
*/
-void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
-{
- if (!handle->dev->grab || handle->dev->grab == handle)
- input_event(handle->dev, type, code, value);
-}
-EXPORT_SYMBOL(input_inject_event);
-
-static void input_repeat_key(unsigned long data)
+void input_inject_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
{
- struct input_dev *dev = (void *) data;
+ struct input_dev *dev = handle->dev;
+ struct input_handle *grab;
+ unsigned long flags;
- if (!test_bit(dev->repeat_key, dev->key))
- return;
+ if (is_event_supported(type, dev->evbit, EV_MAX)) {
+ spin_lock_irqsave(&dev->event_lock, flags);
- input_event(dev, EV_KEY, dev->repeat_key, 2);
- input_sync(dev);
+ rcu_read_lock();
+ grab = rcu_dereference(dev->grab);
+ if (!grab || grab == handle)
+ input_handle_event(dev, type, code, value);
+ rcu_read_unlock();
- if (dev->rep[REP_PERIOD])
- mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD]));
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
}
+EXPORT_SYMBOL(input_inject_event);
+/**
+ * input_grab_device - grabs device for exclusive use
+ * @handle: input handle that wants to own the device
+ *
+ * When a device is grabbed by an input handle all events generated by
+ * the device are delivered only to this handle. Also events injected
+ * by other input handles are ignored while device is grabbed.
+ */
int input_grab_device(struct input_handle *handle)
{
- if (handle->dev->grab)
- return -EBUSY;
+ struct input_dev *dev = handle->dev;
+ int retval;
- handle->dev->grab = handle;
- return 0;
+ retval = mutex_lock_interruptible(&dev->mutex);
+ if (retval)
+ return retval;
+
+ if (dev->grab) {
+ retval = -EBUSY;
+ goto out;
+ }
+
+ rcu_assign_pointer(dev->grab, handle);
+ synchronize_rcu();
+
+ out:
+ mutex_unlock(&dev->mutex);
+ return retval;
}
EXPORT_SYMBOL(input_grab_device);
-void input_release_device(struct input_handle *handle)
+static void __input_release_device(struct input_handle *handle)
{
struct input_dev *dev = handle->dev;
if (dev->grab == handle) {
- dev->grab = NULL;
+ rcu_assign_pointer(dev->grab, NULL);
+ /* Make sure input_pass_event() notices that grab is gone */
+ synchronize_rcu();
list_for_each_entry(handle, &dev->h_list, d_node)
- if (handle->handler->start)
+ if (handle->open && handle->handler->start)
handle->handler->start(handle);
}
}
+
+/**
+ * input_release_device - release previously grabbed device
+ * @handle: input handle that owns the device
+ *
+ * Releases previously grabbed device so that other input handles can
+ * start receiving input events. Upon release all handlers attached
+ * to the device have their start() method called so they have a change
+ * to synchronize device state with the rest of the system.
+ */
+void input_release_device(struct input_handle *handle)
+{
+ struct input_dev *dev = handle->dev;
+
+ mutex_lock(&dev->mutex);
+ __input_release_device(handle);
+ mutex_unlock(&dev->mutex);
+}
EXPORT_SYMBOL(input_release_device);
+/**
+ * input_open_device - open input device
+ * @handle: handle through which device is being accessed
+ *
+ * This function should be called by input handlers when they
+ * want to start receive events from given input device.
+ */
int input_open_device(struct input_handle *handle)
{
struct input_dev *dev = handle->dev;
- int err;
+ int retval;
- err = mutex_lock_interruptible(&dev->mutex);
- if (err)
- return err;
+ retval = mutex_lock_interruptible(&dev->mutex);
+ if (retval)
+ return retval;
+
+ if (dev->going_away) {
+ retval = -ENODEV;
+ goto out;
+ }
handle->open++;
if (!dev->users++ && dev->open)
- err = dev->open(dev);
-
- if (err)
- handle->open--;
+ retval = dev->open(dev);
+
+ if (retval) {
+ dev->users--;
+ if (!--handle->open) {
+ /*
+ * Make sure we are not delivering any more events
+ * through this handle
+ */
+ synchronize_rcu();
+ }
+ }
+ out:
mutex_unlock(&dev->mutex);
-
- return err;
+ return retval;
}
EXPORT_SYMBOL(input_open_device);
-int input_flush_device(struct input_handle* handle, struct file* file)
+int input_flush_device(struct input_handle *handle, struct file *file)
{
- if (handle->dev->flush)
- return handle->dev->flush(handle->dev, file);
+ struct input_dev *dev = handle->dev;
+ int retval;
- return 0;
+ retval = mutex_lock_interruptible(&dev->mutex);
+ if (retval)
+ return retval;
+
+ if (dev->flush)
+ retval = dev->flush(dev, file);
+
+ mutex_unlock(&dev->mutex);
+ return retval;
}
EXPORT_SYMBOL(input_flush_device);
+/**
+ * input_close_device - close input device
+ * @handle: handle through which device is being accessed
+ *
+ * This function should be called by input handlers when they
+ * want to stop receive events from given input device.
+ */
void input_close_device(struct input_handle *handle)
{
struct input_dev *dev = handle->dev;
- input_release_device(handle);
-
mutex_lock(&dev->mutex);
+ __input_release_device(handle);
+
if (!--dev->users && dev->close)
dev->close(dev);
- handle->open--;
+
+ if (!--handle->open) {
+ /*
+ * synchronize_rcu() makes sure that input_pass_event()
+ * completed and that no more input events are delivered
+ * through this handle
+ */
+ synchronize_rcu();
+ }
mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL(input_close_device);
+/*
+ * Prepare device for unregistering
+ */
+static void input_disconnect_device(struct input_dev *dev)
+{
+ struct input_handle *handle;
+ int code;
+
+ /*
+ * Mark device as going away. Note that we take dev->mutex here
+ * not to protect access to dev->going_away but rather to ensure
+ * that there are no threads in the middle of input_open_device()
+ */
+ mutex_lock(&dev->mutex);
+ dev->going_away = 1;
+ mutex_unlock(&dev->mutex);
+
+ spin_lock_irq(&dev->event_lock);
+
+ /*
+ * Simulate keyup events for all pressed keys so that handlers
+ * are not left with "stuck" keys. The driver may continue
+ * generate events even after we done here but they will not
+ * reach any handlers.
+ */
+ if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
+ for (code = 0; code <= KEY_MAX; code++) {
+ if (is_event_supported(code, dev->keybit, KEY_MAX) &&
+ test_bit(code, dev->key)) {
+ input_pass_event(dev, EV_KEY, code, 0);
+ }
+ }
+ input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+ }
+
+ list_for_each_entry(handle, &dev->h_list, d_node)
+ handle->open = 0;
+
+ spin_unlock_irq(&dev->event_lock);
+}
+
static int input_fetch_keycode(struct input_dev *dev, int scancode)
{
switch (dev->keycodesize) {
@@ -473,7 +677,8 @@ static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
{
- /* acquire lock here ... Yes, we do need locking, I knowi, I know... */
+ if (mutex_lock_interruptible(&input_mutex))
+ return NULL;
return seq_list_start(&input_dev_list, *pos);
}
@@ -485,7 +690,7 @@ static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void input_devices_seq_stop(struct seq_file *seq, void *v)
{
- /* release lock here */
+ mutex_unlock(&input_mutex);
}
static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
@@ -569,7 +774,9 @@ static const struct file_operations input_devices_fileops = {
static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
{
- /* acquire lock here ... Yes, we do need locking, I knowi, I know... */
+ if (mutex_lock_interruptible(&input_mutex))
+ return NULL;
+
seq->private = (void *)(unsigned long)*pos;
return seq_list_start(&input_handler_list, *pos);
}
@@ -582,7 +789,7 @@ static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void input_handlers_seq_stop(struct seq_file *seq, void *v)
{
- /* release lock here */
+ mutex_unlock(&input_mutex);
}
static int input_handlers_seq_show(struct seq_file *seq, void *v)
@@ -983,6 +1190,7 @@ struct input_dev *input_allocate_device(void)
dev->dev.class = &input_class;
device_initialize(&dev->dev);
mutex_init(&dev->mutex);
+ spin_lock_init(&dev->event_lock);
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
@@ -1000,7 +1208,7 @@ EXPORT_SYMBOL(input_allocate_device);
* This function should only be used if input_register_device()
* was not called yet or if it failed. Once device was registered
* use input_unregister_device() and memory will be freed once last
- * refrence to the device is dropped.
+ * reference to the device is dropped.
*
* Device should be allocated by input_allocate_device().
*
@@ -1070,6 +1278,18 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
}
EXPORT_SYMBOL(input_set_capability);
+/**
+ * input_register_device - register device with input core
+ * @dev: device to be registered
+ *
+ * This function registers device with input core. The device must be
+ * allocated with input_allocate_device() and all it's capabilities
+ * set up before registering.
+ * If function fails the device must be freed with input_free_device().
+ * Once device has been successfully registered it can be unregistered
+ * with input_unregister_device(); input_free_device() should not be
+ * called in this case.
+ */
int input_register_device(struct input_dev *dev)
{
static atomic_t input_no = ATOMIC_INIT(0);
@@ -1077,7 +1297,7 @@ int input_register_device(struct input_dev *dev)
const char *path;
int error;
- set_bit(EV_SYN, dev->evbit);
+ __set_bit(EV_SYN, dev->evbit);
/*
* If delay and period are pre-set by the driver, then autorepeating
@@ -1098,8 +1318,6 @@ int input_register_device(struct input_dev *dev)
if (!dev->setkeycode)
dev->setkeycode = input_default_setkeycode;
- list_add_tail(&dev->node, &input_dev_list);
-
snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
"input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
@@ -1115,49 +1333,79 @@ int input_register_device(struct input_dev *dev)
dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
kfree(path);
+ error = mutex_lock_interruptible(&input_mutex);
+ if (error) {
+ device_del(&dev->dev);
+ return error;
+ }
+
+ list_add_tail(&dev->node, &input_dev_list);
+
list_for_each_entry(handler, &input_handler_list, node)
input_attach_handler(dev, handler);
input_wakeup_procfs_readers();
+ mutex_unlock(&input_mutex);
+
return 0;
}
EXPORT_SYMBOL(input_register_device);
+/**
+ * input_unregister_device - unregister previously registered device
+ * @dev: device to be unregistered
+ *
+ * This function unregisters an input device. Once device is unregistered
+ * the caller should not try to access it as it may get freed at any moment.
+ */
void input_unregister_device(struct input_dev *dev)
{
struct input_handle *handle, *next;
- int code;
- for (code = 0; code <= KEY_MAX; code++)
- if (test_bit(code, dev->key))
- input_report_key(dev, code, 0);
- input_sync(dev);
+ input_disconnect_device(dev);
- del_timer_sync(&dev->timer);
+ mutex_lock(&input_mutex);
list_for_each_entry_safe(handle, next, &dev->h_list, d_node)
handle->handler->disconnect(handle);
WARN_ON(!list_empty(&dev->h_list));
+ del_timer_sync(&dev->timer);
list_del_init(&dev->node);
- device_unregister(&dev->dev);
-
input_wakeup_procfs_readers();
+
+ mutex_unlock(&input_mutex);
+
+ device_unregister(&dev->dev);
}
EXPORT_SYMBOL(input_unregister_device);
+/**
+ * input_register_handler - register a new input handler
+ * @handler: handler to be registered
+ *
+ * This function registers a new input handler (interface) for input
+ * devices in the system and attaches it to all input devices that
+ * are compatible with the handler.
+ */
int input_register_handler(struct input_handler *handler)
{
struct input_dev *dev;
+ int retval;
+
+ retval = mutex_lock_interruptible(&input_mutex);
+ if (retval)
+ return retval;
INIT_LIST_HEAD(&handler->h_list);
if (handler->fops != NULL) {
- if (input_table[handler->minor >> 5])
- return -EBUSY;
-
+ if (input_table[handler->minor >> 5]) {
+ retval = -EBUSY;
+ goto out;
+ }
input_table[handler->minor >> 5] = handler;
}
@@ -1167,14 +1415,26 @@ int input_register_handler(struct input_handler *handler)
input_attach_handler(dev, handler);
input_wakeup_procfs_readers();
- return 0;
+
+ out:
+ mutex_unlock(&input_mutex);
+ return retval;
}
EXPORT_SYMBOL(input_register_handler);
+/**
+ * input_unregister_handler - unregisters an input handler
+ * @handler: handler to be unregistered
+ *
+ * This function disconnects a handler from its input devices and
+ * removes it from lists of known handlers.
+ */
void input_unregister_handler(struct input_handler *handler)
{
struct input_handle *handle, *next;
+ mutex_lock(&input_mutex);
+
list_for_each_entry_safe(handle, next, &handler->h_list, h_node)
handler->disconnect(handle);
WARN_ON(!list_empty(&handler->h_list));
@@ -1185,14 +1445,45 @@ void input_unregister_handler(struct input_handler *handler)
input_table[handler->minor >> 5] = NULL;
input_wakeup_procfs_readers();
+
+ mutex_unlock(&input_mutex);
}
EXPORT_SYMBOL(input_unregister_handler);
+/**
+ * input_register_handle - register a new input handle
+ * @handle: handle to register
+ *
+ * This function puts a new input handle onto device's
+ * and handler's lists so that events can flow through
+ * it once it is opened using input_open_device().
+ *
+ * This function is supposed to be called from handler's
+ * connect() method.
+ */
int input_register_handle(struct input_handle *handle)
{
struct input_handler *handler = handle->handler;
+ struct input_dev *dev = handle->dev;
+ int error;
+
+ /*
+ * We take dev->mutex here to prevent race with
+ * input_release_device().
+ */
+ error = mutex_lock_interruptible(&dev->mutex);
+ if (error)
+ return error;
+ list_add_tail_rcu(&handle->d_node, &dev->h_list);
+ mutex_unlock(&dev->mutex);
+ synchronize_rcu();
- list_add_tail(&handle->d_node, &handle->dev->h_list);
+ /*
+ * Since we are supposed to be called from ->connect()
+ * which is mutually exclusive with ->disconnect()
+ * we can't be racing with input_unregister_handle()
+ * and so separate lock is not needed here.
+ */
list_add_tail(&handle->h_node, &handler->h_list);
if (handler->start)
@@ -1202,10 +1493,29 @@ int input_register_handle(struct input_handle *handle)
}
EXPORT_SYMBOL(input_register_handle);
+/**
+ * input_unregister_handle - unregister an input handle
+ * @handle: handle to unregister
+ *
+ * This function removes input handle from device's
+ * and handler's lists.
+ *
+ * This function is supposed to be called from handler's
+ * disconnect() method.
+ */
void input_unregister_handle(struct input_handle *handle)
{
+ struct input_dev *dev = handle->dev;
+
list_del_init(&handle->h_node);
- list_del_init(&handle->d_node);
+
+ /*
+ * Take dev->mutex to prevent race with input_release_device().
+ */
+ mutex_lock(&dev->mutex);
+ list_del_rcu(&handle->d_node);
+ mutex_unlock(&dev->mutex);
+ synchronize_rcu();
}
EXPORT_SYMBOL(input_unregister_handle);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index a9a0180bfd4..2b201f9aa02 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -43,6 +43,8 @@ struct joydev {
struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
+ spinlock_t client_lock; /* protects client_list */
+ struct mutex mutex;
struct device dev;
struct js_corr corr[ABS_MAX + 1];
@@ -61,31 +63,61 @@ struct joydev_client {
int head;
int tail;
int startup;
+ spinlock_t buffer_lock; /* protects access to buffer, head and tail */
struct fasync_struct *fasync;
struct joydev *joydev;
struct list_head node;
};
static struct joydev *joydev_table[JOYDEV_MINORS];
+static DEFINE_MUTEX(joydev_table_mutex);
static int joydev_correct(int value, struct js_corr *corr)
{
switch (corr->type) {
- case JS_CORR_NONE:
- break;
- case JS_CORR_BROKEN:
- value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
- ((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
- ((corr->coef[2] * (value - corr->coef[0])) >> 14);
- break;
- default:
- return 0;
+
+ case JS_CORR_NONE:
+ break;
+
+ case JS_CORR_BROKEN:
+ value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
+ ((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
+ ((corr->coef[2] * (value - corr->coef[0])) >> 14);
+ break;
+
+ default:
+ return 0;
}
return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
}
-static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void joydev_pass_event(struct joydev_client *client,
+ struct js_event *event)
+{
+ struct joydev *joydev = client->joydev;
+
+ /*
+ * IRQs already disabled, just acquire the lock
+ */
+ spin_lock(&client->buffer_lock);
+
+ client->buffer[client->head] = *event;
+
+ if (client->startup == joydev->nabs + joydev->nkey) {
+ client->head++;
+ client->head &= JOYDEV_BUFFER_SIZE - 1;
+ if (client->tail == client->head)
+ client->startup = 0;
+ }
+
+ spin_unlock(&client->buffer_lock);
+
+ kill_fasync(&client->fasync, SIGIO, POLL_IN);
+}
+
+static void joydev_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
{
struct joydev *joydev = handle->private;
struct joydev_client *client;
@@ -93,39 +125,34 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
switch (type) {
- case EV_KEY:
- if (code < BTN_MISC || value == 2)
- return;
- event.type = JS_EVENT_BUTTON;
- event.number = joydev->keymap[code - BTN_MISC];
- event.value = value;
- break;
-
- case EV_ABS:
- event.type = JS_EVENT_AXIS;
- event.number = joydev->absmap[code];
- event.value = joydev_correct(value, joydev->corr + event.number);
- if (event.value == joydev->abs[event.number])
- return;
- joydev->abs[event.number] = event.value;
- break;
+ case EV_KEY:
+ if (code < BTN_MISC || value == 2)
+ return;
+ event.type = JS_EVENT_BUTTON;
+ event.number = joydev->keymap[code - BTN_MISC];
+ event.value = value;
+ break;
- default:
+ case EV_ABS:
+ event.type = JS_EVENT_AXIS;
+ event.number = joydev->absmap[code];
+ event.value = joydev_correct(value,
+ &joydev->corr[event.number]);
+ if (event.value == joydev->abs[event.number])
return;
+ joydev->abs[event.number] = event.value;
+ break;
+
+ default:
+ return;
}
event.time = jiffies_to_msecs(jiffies);
- list_for_each_entry(client, &joydev->client_list, node) {
-
- memcpy(client->buffer + client->head, &event, sizeof(struct js_event));
-
- if (client->startup == joydev->nabs + joydev->nkey)
- if (client->tail == (client->head = (client->head + 1) & (JOYDEV_BUFFER_SIZE - 1)))
- client->startup = 0;
-
- kill_fasync(&client->fasync, SIGIO, POLL_IN);
- }
+ rcu_read_lock();
+ list_for_each_entry_rcu(client, &joydev->client_list, node)
+ joydev_pass_event(client, &event);
+ rcu_read_unlock();
wake_up_interruptible(&joydev->wait);
}
@@ -144,23 +171,83 @@ static void joydev_free(struct device *dev)
{
struct joydev *joydev = container_of(dev, struct joydev, dev);
- joydev_table[joydev->minor] = NULL;
kfree(joydev);
}
+static void joydev_attach_client(struct joydev *joydev,
+ struct joydev_client *client)
+{
+ spin_lock(&joydev->client_lock);
+ list_add_tail_rcu(&client->node, &joydev->client_list);
+ spin_unlock(&joydev->client_lock);
+ synchronize_rcu();
+}
+
+static void joydev_detach_client(struct joydev *joydev,
+ struct joydev_client *client)
+{
+ spin_lock(&joydev->client_lock);
+ list_del_rcu(&client->node);
+ spin_unlock(&joydev->client_lock);
+ synchronize_rcu();
+}
+
+static int joydev_open_device(struct joydev *joydev)
+{
+ int retval;
+
+ retval = mutex_lock_interruptible(&joydev->mutex);
+ if (retval)
+ return retval;
+
+ if (!joydev->exist)
+ retval = -ENODEV;
+ else if (!joydev->open++) {
+ retval = input_open_device(&joydev->handle);
+ if (retval)
+ joydev->open--;
+ }
+
+ mutex_unlock(&joydev->mutex);
+ return retval;
+}
+
+static void joydev_close_device(struct joydev *joydev)
+{
+ mutex_lock(&joydev->mutex);
+
+ if (joydev->exist && !--joydev->open)
+ input_close_device(&joydev->handle);
+
+ mutex_unlock(&joydev->mutex);
+}
+
+/*
+ * Wake up users waiting for IO so they can disconnect from
+ * dead device.
+ */
+static void joydev_hangup(struct joydev *joydev)
+{
+ struct joydev_client *client;
+
+ spin_lock(&joydev->client_lock);
+ list_for_each_entry(client, &joydev->client_list, node)
+ kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ spin_unlock(&joydev->client_lock);
+
+ wake_up_interruptible(&joydev->wait);
+}
+
static int joydev_release(struct inode *inode, struct file *file)
{
struct joydev_client *client = file->private_data;
struct joydev *joydev = client->joydev;
joydev_fasync(-1, file, 0);
-
- list_del(&client->node);
+ joydev_detach_client(joydev, client);
kfree(client);
- if (!--joydev->open && joydev->exist)
- input_close_device(&joydev->handle);
-
+ joydev_close_device(joydev);
put_device(&joydev->dev);
return 0;
@@ -176,11 +263,16 @@ static int joydev_open(struct inode *inode, struct file *file)
if (i >= JOYDEV_MINORS)
return -ENODEV;
+ error = mutex_lock_interruptible(&joydev_table_mutex);
+ if (error)
+ return error;
joydev = joydev_table[i];
- if (!joydev || !joydev->exist)
- return -ENODEV;
+ if (joydev)
+ get_device(&joydev->dev);
+ mutex_unlock(&joydev_table_mutex);
- get_device(&joydev->dev);
+ if (!joydev)
+ return -ENODEV;
client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
if (!client) {
@@ -188,37 +280,129 @@ static int joydev_open(struct inode *inode, struct file *file)
goto err_put_joydev;
}
+ spin_lock_init(&client->buffer_lock);
client->joydev = joydev;
- list_add_tail(&client->node, &joydev->client_list);
+ joydev_attach_client(joydev, client);
- if (!joydev->open++ && joydev->exist) {
- error = input_open_device(&joydev->handle);
- if (error)
- goto err_free_client;
- }
+ error = joydev_open_device(joydev);
+ if (error)
+ goto err_free_client;
file->private_data = client;
return 0;
err_free_client:
- list_del(&client->node);
+ joydev_detach_client(joydev, client);
kfree(client);
err_put_joydev:
put_device(&joydev->dev);
return error;
}
-static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+static int joydev_generate_startup_event(struct joydev_client *client,
+ struct input_dev *input,
+ struct js_event *event)
{
- return -EINVAL;
+ struct joydev *joydev = client->joydev;
+ int have_event;
+
+ spin_lock_irq(&client->buffer_lock);
+
+ have_event = client->startup < joydev->nabs + joydev->nkey;
+
+ if (have_event) {
+
+ event->time = jiffies_to_msecs(jiffies);
+ if (client->startup < joydev->nkey) {
+ event->type = JS_EVENT_BUTTON | JS_EVENT_INIT;
+ event->number = client->startup;
+ event->value = !!test_bit(joydev->keypam[event->number],
+ input->key);
+ } else {
+ event->type = JS_EVENT_AXIS | JS_EVENT_INIT;
+ event->number = client->startup - joydev->nkey;
+ event->value = joydev->abs[event->number];
+ }
+ client->startup++;
+ }
+
+ spin_unlock_irq(&client->buffer_lock);
+
+ return have_event;
+}
+
+static int joydev_fetch_next_event(struct joydev_client *client,
+ struct js_event *event)
+{
+ int have_event;
+
+ spin_lock_irq(&client->buffer_lock);
+
+ have_event = client->head != client->tail;
+ if (have_event) {
+ *event = client->buffer[client->tail++];
+ client->tail &= JOYDEV_BUFFER_SIZE - 1;
+ }
+
+ spin_unlock_irq(&client->buffer_lock);
+
+ return have_event;
+}
+
+/*
+ * Old joystick interface
+ */
+static ssize_t joydev_0x_read(struct joydev_client *client,
+ struct input_dev *input,
+ char __user *buf)
+{
+ struct joydev *joydev = client->joydev;
+ struct JS_DATA_TYPE data;
+ int i;
+
+ spin_lock_irq(&input->event_lock);
+
+ /*
+ * Get device state
+ */
+ for (data.buttons = i = 0; i < 32 && i < joydev->nkey; i++)
+ data.buttons |=
+ test_bit(joydev->keypam[i], input->key) ? (1 << i) : 0;
+ data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x;
+ data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y;
+
+ /*
+ * Reset reader's event queue
+ */
+ spin_lock(&client->buffer_lock);
+ client->startup = 0;
+ client->tail = client->head;
+ spin_unlock(&client->buffer_lock);
+
+ spin_unlock_irq(&input->event_lock);
+
+ if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
+ return -EFAULT;
+
+ return sizeof(struct JS_DATA_TYPE);
+}
+
+static inline int joydev_data_pending(struct joydev_client *client)
+{
+ struct joydev *joydev = client->joydev;
+
+ return client->startup < joydev->nabs + joydev->nkey ||
+ client->head != client->tail;
}
-static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static ssize_t joydev_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
{
struct joydev_client *client = file->private_data;
struct joydev *joydev = client->joydev;
struct input_dev *input = joydev->handle.dev;
- int retval = 0;
+ struct js_event event;
+ int retval;
if (!joydev->exist)
return -ENODEV;
@@ -226,68 +410,35 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo
if (count < sizeof(struct js_event))
return -EINVAL;
- if (count == sizeof(struct JS_DATA_TYPE)) {
-
- struct JS_DATA_TYPE data;
- int i;
-
- for (data.buttons = i = 0; i < 32 && i < joydev->nkey; i++)
- data.buttons |= test_bit(joydev->keypam[i], input->key) ? (1 << i) : 0;
- data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x;
- data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y;
-
- if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
- return -EFAULT;
-
- client->startup = 0;
- client->tail = client->head;
+ if (count == sizeof(struct JS_DATA_TYPE))
+ return joydev_0x_read(client, input, buf);
- return sizeof(struct JS_DATA_TYPE);
- }
-
- if (client->startup == joydev->nabs + joydev->nkey &&
- client->head == client->tail && (file->f_flags & O_NONBLOCK))
+ if (!joydev_data_pending(client) && (file->f_flags & O_NONBLOCK))
return -EAGAIN;
retval = wait_event_interruptible(joydev->wait,
- !joydev->exist ||
- client->startup < joydev->nabs + joydev->nkey ||
- client->head != client->tail);
+ !joydev->exist || joydev_data_pending(client));
if (retval)
return retval;
if (!joydev->exist)
return -ENODEV;
- while (client->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) {
-
- struct js_event event;
-
- event.time = jiffies_to_msecs(jiffies);
-
- if (client->startup < joydev->nkey) {
- event.type = JS_EVENT_BUTTON | JS_EVENT_INIT;
- event.number = client->startup;
- event.value = !!test_bit(joydev->keypam[event.number], input->key);
- } else {
- event.type = JS_EVENT_AXIS | JS_EVENT_INIT;
- event.number = client->startup - joydev->nkey;
- event.value = joydev->abs[event.number];
- }
+ while (retval + sizeof(struct js_event) <= count &&
+ joydev_generate_startup_event(client, input, &event)) {
if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
return -EFAULT;
- client->startup++;
retval += sizeof(struct js_event);
}
- while (client->head != client->tail && retval + sizeof(struct js_event) <= count) {
+ while (retval + sizeof(struct js_event) <= count &&
+ joydev_fetch_next_event(client, &event)) {
- if (copy_to_user(buf + retval, client->buffer + client->tail, sizeof(struct js_event)))
+ if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
return -EFAULT;
- client->tail = (client->tail + 1) & (JOYDEV_BUFFER_SIZE - 1);
retval += sizeof(struct js_event);
}
@@ -301,126 +452,144 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
struct joydev *joydev = client->joydev;
poll_wait(file, &joydev->wait, wait);
- return ((client->head != client->tail || client->startup < joydev->nabs + joydev->nkey) ?
- (POLLIN | POLLRDNORM) : 0) | (joydev->exist ? 0 : (POLLHUP | POLLERR));
+ return (joydev_data_pending(client) ? (POLLIN | POLLRDNORM) : 0) |
+ (joydev->exist ? 0 : (POLLHUP | POLLERR));
}
-static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp)
+static int joydev_ioctl_common(struct joydev *joydev,
+ unsigned int cmd, void __user *argp)
{
struct input_dev *dev = joydev->handle.dev;
int i, j;
switch (cmd) {
- case JS_SET_CAL:
- return copy_from_user(&joydev->glue.JS_CORR, argp,
+ case JS_SET_CAL:
+ return copy_from_user(&joydev->glue.JS_CORR, argp,
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
- case JS_GET_CAL:
- return copy_to_user(argp, &joydev->glue.JS_CORR,
+ case JS_GET_CAL:
+ return copy_to_user(argp, &joydev->glue.JS_CORR,
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
- case JS_SET_TIMEOUT:
- return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
+ case JS_SET_TIMEOUT:
+ return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
- case JS_GET_TIMEOUT:
- return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
+ case JS_GET_TIMEOUT:
+ return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
- case JSIOCGVERSION:
- return put_user(JS_VERSION, (__u32 __user *) argp);
+ case JSIOCGVERSION:
+ return put_user(JS_VERSION, (__u32 __user *) argp);
- case JSIOCGAXES:
- return put_user(joydev->nabs, (__u8 __user *) argp);
+ case JSIOCGAXES:
+ return put_user(joydev->nabs, (__u8 __user *) argp);
- case JSIOCGBUTTONS:
- return put_user(joydev->nkey, (__u8 __user *) argp);
+ case JSIOCGBUTTONS:
+ return put_user(joydev->nkey, (__u8 __user *) argp);
- case JSIOCSCORR:
- if (copy_from_user(joydev->corr, argp,
- sizeof(joydev->corr[0]) * joydev->nabs))
- return -EFAULT;
- for (i = 0; i < joydev->nabs; i++) {
- j = joydev->abspam[i];
- joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
- }
- return 0;
+ case JSIOCSCORR:
+ if (copy_from_user(joydev->corr, argp,
+ sizeof(joydev->corr[0]) * joydev->nabs))
+ return -EFAULT;
- case JSIOCGCORR:
- return copy_to_user(argp, joydev->corr,
- sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
+ for (i = 0; i < joydev->nabs; i++) {
+ j = joydev->abspam[i];
+ joydev->abs[i] = joydev_correct(dev->abs[j],
+ &joydev->corr[i]);
+ }
+ return 0;
- case JSIOCSAXMAP:
- if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
- return -EFAULT;
- for (i = 0; i < joydev->nabs; i++) {
- if (joydev->abspam[i] > ABS_MAX)
- return -EINVAL;
- joydev->absmap[joydev->abspam[i]] = i;
- }
- return 0;
-
- case JSIOCGAXMAP:
- return copy_to_user(argp, joydev->abspam,
- sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
-
- case JSIOCSBTNMAP:
- if (copy_from_user(joydev->keypam, argp, sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
+ case JSIOCGCORR:
+ return copy_to_user(argp, joydev->corr,
+ sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
+
+ case JSIOCSAXMAP:
+ if (copy_from_user(joydev->abspam, argp,
+ sizeof(__u8) * (ABS_MAX + 1)))
+ return -EFAULT;
+
+ for (i = 0; i < joydev->nabs; i++) {
+ if (joydev->abspam[i] > ABS_MAX)
+ return -EINVAL;
+ joydev->absmap[joydev->abspam[i]] = i;
+ }
+ return 0;
+
+ case JSIOCGAXMAP:
+ return copy_to_user(argp, joydev->abspam,
+ sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
+
+ case JSIOCSBTNMAP:
+ if (copy_from_user(joydev->keypam, argp,
+ sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
+ return -EFAULT;
+
+ for (i = 0; i < joydev->nkey; i++) {
+ if (joydev->keypam[i] > KEY_MAX ||
+ joydev->keypam[i] < BTN_MISC)
+ return -EINVAL;
+ joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
+ }
+
+ return 0;
+
+ case JSIOCGBTNMAP:
+ return copy_to_user(argp, joydev->keypam,
+ sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
+
+ default:
+ if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
+ int len;
+ if (!dev->name)
+ return 0;
+ len = strlen(dev->name) + 1;
+ if (len > _IOC_SIZE(cmd))
+ len = _IOC_SIZE(cmd);
+ if (copy_to_user(argp, dev->name, len))
return -EFAULT;
- for (i = 0; i < joydev->nkey; i++) {
- if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC)
- return -EINVAL;
- joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
- }
- return 0;
-
- case JSIOCGBTNMAP:
- return copy_to_user(argp, joydev->keypam,
- sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
-
- default:
- if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
- int len;
- if (!dev->name)
- return 0;
- len = strlen(dev->name) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- if (copy_to_user(argp, dev->name, len))
- return -EFAULT;
- return len;
- }
+ return len;
+ }
}
return -EINVAL;
}
#ifdef CONFIG_COMPAT
-static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long joydev_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct joydev_client *client = file->private_data;
struct joydev *joydev = client->joydev;
void __user *argp = (void __user *)arg;
s32 tmp32;
struct JS_DATA_SAVE_TYPE_32 ds32;
- int err;
+ int retval;
- if (!joydev->exist)
- return -ENODEV;
+ retval = mutex_lock_interruptible(&joydev->mutex);
+ if (retval)
+ return retval;
+
+ if (!joydev->exist) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ switch (cmd) {
- switch(cmd) {
case JS_SET_TIMELIMIT:
- err = get_user(tmp32, (s32 __user *) arg);
- if (err == 0)
+ retval = get_user(tmp32, (s32 __user *) arg);
+ if (retval == 0)
joydev->glue.JS_TIMELIMIT = tmp32;
break;
+
case JS_GET_TIMELIMIT:
tmp32 = joydev->glue.JS_TIMELIMIT;
- err = put_user(tmp32, (s32 __user *) arg);
+ retval = put_user(tmp32, (s32 __user *) arg);
break;
case JS_SET_ALL:
- err = copy_from_user(&ds32, argp,
- sizeof(ds32)) ? -EFAULT : 0;
- if (err == 0) {
+ retval = copy_from_user(&ds32, argp,
+ sizeof(ds32)) ? -EFAULT : 0;
+ if (retval == 0) {
joydev->glue.JS_TIMEOUT = ds32.JS_TIMEOUT;
joydev->glue.BUSY = ds32.BUSY;
joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
@@ -438,55 +607,119 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo
ds32.JS_SAVE = joydev->glue.JS_SAVE;
ds32.JS_CORR = joydev->glue.JS_CORR;
- err = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0;
+ retval = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0;
break;
default:
- err = joydev_ioctl_common(joydev, cmd, argp);
+ retval = joydev_ioctl_common(joydev, cmd, argp);
+ break;
}
- return err;
+
+ out:
+ mutex_unlock(&joydev->mutex);
+ return retval;
}
#endif /* CONFIG_COMPAT */
-static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long joydev_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct joydev_client *client = file->private_data;
struct joydev *joydev = client->joydev;
void __user *argp = (void __user *)arg;
+ int retval;
- if (!joydev->exist)
- return -ENODEV;
+ retval = mutex_lock_interruptible(&joydev->mutex);
+ if (retval)
+ return retval;
+
+ if (!joydev->exist) {
+ retval = -ENODEV;
+ goto out;
+ }
+
+ switch (cmd) {
+
+ case JS_SET_TIMELIMIT:
+ retval = get_user(joydev->glue.JS_TIMELIMIT,
+ (long __user *) arg);
+ break;
+
+ case JS_GET_TIMELIMIT:
+ retval = put_user(joydev->glue.JS_TIMELIMIT,
+ (long __user *) arg);
+ break;
+
+ case JS_SET_ALL:
+ retval = copy_from_user(&joydev->glue, argp,
+ sizeof(joydev->glue)) ? -EFAULT: 0;
+ break;
+
+ case JS_GET_ALL:
+ retval = copy_to_user(argp, &joydev->glue,
+ sizeof(joydev->glue)) ? -EFAULT : 0;
+ break;
- switch(cmd) {
- case JS_SET_TIMELIMIT:
- return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
- case JS_GET_TIMELIMIT:
- return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
- case JS_SET_ALL:
- return copy_from_user(&joydev->glue, argp,
- sizeof(joydev->glue)) ? -EFAULT : 0;
- case JS_GET_ALL:
- return copy_to_user(argp, &joydev->glue,
- sizeof(joydev->glue)) ? -EFAULT : 0;
- default:
- return joydev_ioctl_common(joydev, cmd, argp);
+ default:
+ retval = joydev_ioctl_common(joydev, cmd, argp);
+ break;
}
+ out:
+ mutex_unlock(&joydev->mutex);
+ return retval;
}
static const struct file_operations joydev_fops = {
- .owner = THIS_MODULE,
- .read = joydev_read,
- .write = joydev_write,
- .poll = joydev_poll,
- .open = joydev_open,
- .release = joydev_release,
- .ioctl = joydev_ioctl,
+ .owner = THIS_MODULE,
+ .read = joydev_read,
+ .poll = joydev_poll,
+ .open = joydev_open,
+ .release = joydev_release,
+ .unlocked_ioctl = joydev_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = joydev_compat_ioctl,
+ .compat_ioctl = joydev_compat_ioctl,
#endif
- .fasync = joydev_fasync,
+ .fasync = joydev_fasync,
};
+static int joydev_install_chrdev(struct joydev *joydev)
+{
+ joydev_table[joydev->minor] = joydev;
+ return 0;
+}
+
+static void joydev_remove_chrdev(struct joydev *joydev)
+{
+ mutex_lock(&joydev_table_mutex);
+ joydev_table[joydev->minor] = NULL;
+ mutex_unlock(&joydev_table_mutex);
+}
+
+/*
+ * Mark device non-existant. This disables writes, ioctls and
+ * prevents new users from opening the device. Already posted
+ * blocking reads will stay, however new ones will fail.
+ */
+static void joydev_mark_dead(struct joydev *joydev)
+{
+ mutex_lock(&joydev->mutex);
+ joydev->exist = 0;
+ mutex_unlock(&joydev->mutex);
+}
+
+static void joydev_cleanup(struct joydev *joydev)
+{
+ struct input_handle *handle = &joydev->handle;
+
+ joydev_mark_dead(joydev);
+ joydev_hangup(joydev);
+ joydev_remove_chrdev(joydev);
+
+ /* joydev is marked dead so noone else accesses joydev->open */
+ if (joydev->open)
+ input_close_device(handle);
+}
+
static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{
@@ -494,7 +727,10 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
int i, j, t, minor;
int error;
- for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
+ for (minor = 0; minor < JOYDEV_MINORS; minor++)
+ if (!joydev_table[minor])
+ break;
+
if (minor == JOYDEV_MINORS) {
printk(KERN_ERR "joydev: no more free joydev devices\n");
return -ENFILE;
@@ -505,15 +741,19 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
return -ENOMEM;
INIT_LIST_HEAD(&joydev->client_list);
+ spin_lock_init(&joydev->client_lock);
+ mutex_init(&joydev->mutex);
init_waitqueue_head(&joydev->wait);
+ snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
+ joydev->exist = 1;
joydev->minor = minor;
+
joydev->exist = 1;
joydev->handle.dev = dev;
joydev->handle.name = joydev->name;
joydev->handle.handler = handler;
joydev->handle.private = joydev;
- snprintf(joydev->name, sizeof(joydev->name), "js%d", minor);
for (i = 0; i < ABS_MAX + 1; i++)
if (test_bit(i, dev->absbit)) {
@@ -545,67 +785,65 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
}
joydev->corr[i].type = JS_CORR_BROKEN;
joydev->corr[i].prec = dev->absfuzz[j];
- joydev->corr[i].coef[0] = (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
- joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
- if (!(t = ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j])))
- continue;
- joydev->corr[i].coef[2] = (1 << 29) / t;
- joydev->corr[i].coef[3] = (1 << 29) / t;
-
- joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
+ joydev->corr[i].coef[0] =
+ (dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
+ joydev->corr[i].coef[1] =
+ (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
+
+ t = (dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j];
+ if (t) {
+ joydev->corr[i].coef[2] = (1 << 29) / t;
+ joydev->corr[i].coef[3] = (1 << 29) / t;
+
+ joydev->abs[i] = joydev_correct(dev->abs[j],
+ joydev->corr + i);
+ }
}
- snprintf(joydev->dev.bus_id, sizeof(joydev->dev.bus_id),
- "js%d", minor);
+ strlcpy(joydev->dev.bus_id, joydev->name, sizeof(joydev->dev.bus_id));
+ joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
joydev->dev.class = &input_class;
joydev->dev.parent = &dev->dev;
- joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
joydev->dev.release = joydev_free;
device_initialize(&joydev->dev);
- joydev_table[minor] = joydev;
-
- error = device_add(&joydev->dev);
+ error = input_register_handle(&joydev->handle);
if (error)
goto err_free_joydev;
- error = input_register_handle(&joydev->handle);
+ error = joydev_install_chrdev(joydev);
if (error)
- goto err_delete_joydev;
+ goto err_unregister_handle;
+
+ error = device_add(&joydev->dev);
+ if (error)
+ goto err_cleanup_joydev;
return 0;
- err_delete_joydev:
- device_del(&joydev->dev);
+ err_cleanup_joydev:
+ joydev_cleanup(joydev);
+ err_unregister_handle:
+ input_unregister_handle(&joydev->handle);
err_free_joydev:
put_device(&joydev->dev);
return error;
}
-
static void joydev_disconnect(struct input_handle *handle)
{
struct joydev *joydev = handle->private;
- struct joydev_client *client;
- input_unregister_handle(handle);
device_del(&joydev->dev);
-
- joydev->exist = 0;
-
- if (joydev->open) {
- input_close_device(handle);
- list_for_each_entry(client, &joydev->client_list, node)
- kill_fasync(&client->fasync, SIGIO, POLL_HUP);
- wake_up_interruptible(&joydev->wait);
- }
-
+ joydev_cleanup(joydev);
+ input_unregister_handle(handle);
put_device(&joydev->dev);
}
static const struct input_device_id joydev_blacklist[] = {
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) },
.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
}, /* Avoid itouchpads, touchscreens and tablets */
@@ -614,17 +852,20 @@ static const struct input_device_id joydev_blacklist[] = {
static const struct input_device_id joydev_ids[] = {
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT(EV_ABS) },
.absbit = { BIT(ABS_X) },
},
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT(EV_ABS) },
.absbit = { BIT(ABS_WHEEL) },
},
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT(EV_ABS) },
.absbit = { BIT(ABS_THROTTLE) },
},
@@ -634,14 +875,14 @@ static const struct input_device_id joydev_ids[] = {
MODULE_DEVICE_TABLE(input, joydev_ids);
static struct input_handler joydev_handler = {
- .event = joydev_event,
- .connect = joydev_connect,
- .disconnect = joydev_disconnect,
- .fops = &joydev_fops,
- .minor = JOYDEV_MINOR_BASE,
- .name = "joydev",
- .id_table = joydev_ids,
- .blacklist = joydev_blacklist,
+ .event = joydev_event,
+ .connect = joydev_connect,
+ .disconnect = joydev_disconnect,
+ .fops = &joydev_fops,
+ .minor = JOYDEV_MINOR_BASE,
+ .name = "joydev",
+ .id_table = joydev_ids,
+ .blacklist = joydev_blacklist,
};
static int __init joydev_init(void)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 28080395899..623629a69b0 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -223,12 +223,16 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
struct input_dev *dev = xpad->dev;
/* left stick */
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14]));
+ input_report_abs(dev, ABS_X,
+ (__s16) le16_to_cpup((__le16 *)(data + 12)));
+ input_report_abs(dev, ABS_Y,
+ (__s16) le16_to_cpup((__le16 *)(data + 14)));
/* right stick */
- input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16]));
- input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18]));
+ input_report_abs(dev, ABS_RX,
+ (__s16) le16_to_cpup((__le16 *)(data + 16)));
+ input_report_abs(dev, ABS_RY,
+ (__s16) le16_to_cpup((__le16 *)(data + 18)));
/* triggers left/right */
input_report_abs(dev, ABS_Z, data[10]);
@@ -236,8 +240,10 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
/* digital pad */
if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
- input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
- input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
+ input_report_abs(dev, ABS_HAT0X,
+ !!(data[2] & 0x08) - !!(data[2] & 0x04));
+ input_report_abs(dev, ABS_HAT0Y,
+ !!(data[2] & 0x02) - !!(data[2] & 0x01));
} else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
input_report_key(dev, BTN_LEFT, data[2] & 0x04);
input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
@@ -274,14 +280,17 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
* http://www.free60.org/wiki/Gamepad
*/
-static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
+static void xpad360_process_packet(struct usb_xpad *xpad,
+ u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
/* digital pad */
if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
- input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
- input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
+ input_report_abs(dev, ABS_HAT0X,
+ !!(data[2] & 0x08) - !!(data[2] & 0x04));
+ input_report_abs(dev, ABS_HAT0Y,
+ !!(data[2] & 0x02) - !!(data[2] & 0x01));
} else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) {
/* dpad as buttons (right, left, down, up) */
input_report_key(dev, BTN_LEFT, data[2] & 0x04);
@@ -308,12 +317,16 @@ static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char
input_report_key(dev, BTN_MODE, data[3] & 0x04);
/* left stick */
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[7] << 8) | (__s16)data[6]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[9] << 8) | (__s16)data[8]));
+ input_report_abs(dev, ABS_X,
+ (__s16) le16_to_cpup((__le16 *)(data + 6)));
+ input_report_abs(dev, ABS_Y,
+ (__s16) le16_to_cpup((__le16 *)(data + 8)));
/* right stick */
- input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[11] << 8) | (__s16)data[10]));
- input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[13] << 8) | (__s16)data[12]));
+ input_report_abs(dev, ABS_RX,
+ (__s16) le16_to_cpup((__le16 *)(data + 10)));
+ input_report_abs(dev, ABS_RY,
+ (__s16) le16_to_cpup((__le16 *)(data + 12)));
/* triggers left/right */
input_report_abs(dev, ABS_Z, data[4]);
@@ -335,10 +348,12 @@ static void xpad_irq_in(struct urb *urb)
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+ dbg("%s - urb shutting down with status: %d",
+ __FUNCTION__, urb->status);
return;
default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
goto exit;
}
@@ -367,10 +382,12 @@ static void xpad_irq_out(struct urb *urb)
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+ dbg("%s - urb shutting down with status: %d",
+ __FUNCTION__, urb->status);
return;
default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
goto exit;
}
@@ -378,7 +395,7 @@ exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
err("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
+ __FUNCTION__, retval);
}
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
@@ -595,7 +612,7 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- struct usb_device *udev = interface_to_usbdev (intf);
+ struct usb_device *udev = interface_to_usbdev(intf);
struct usb_xpad *xpad;
struct input_dev *input_dev;
struct usb_endpoint_descriptor *ep_irq_in;
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index c97d5eb0075..2316a018fae 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -208,6 +208,27 @@ config KEYBOARD_HIL
This driver implements support for HIL-keyboards attached
to your machine, so normally you should say Y here.
+config KEYBOARD_HP6XX
+ tristate "HP Jornada 6XX Keyboard support"
+ depends on SH_HP6XX
+ select INPUT_POLLDEV
+ help
+ This adds support for the onboard keyboard found on
+ HP Jornada 620/660/680/690.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jornada680_kbd.
+
+config KEYBOARD_HP7XX
+ tristate "HP Jornada 7XX Keyboard Driver"
+ depends on SA1100_JORNADA720_SSP && SA1100_SSP
+ help
+ Say Y here to add support for the HP Jornada 7xx (710/720/728)
+ onboard keyboard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jornada720_kbd.
+
config KEYBOARD_OMAP
tristate "TI OMAP keypad support"
depends on (ARCH_OMAP1 || ARCH_OMAP2)
@@ -253,4 +274,23 @@ config KEYBOARD_GPIO
To compile this driver as a module, choose M here: the
module will be called gpio-keys.
+config KEYBOARD_MAPLE
+ tristate "Maple bus keyboard"
+ depends on SH_DREAMCAST && MAPLE
+ help
+ Say Y here if you have a Dreamcast console running Linux and have
+ a keyboard attached to its Maple bus.
+
+ To compile this driver as a module, choose M here: the
+ module will be called maple_keyb.
+
+config KEYBOARD_BFIN
+ tristate "Blackfin BF54x keypad support"
+ depends on BF54x
+ help
+ Say Y here if you want to use the BF54x keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bf54x-keys.
+
endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 28d211b87b1..e97455fdcc8 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -21,4 +21,7 @@ obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o
obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
-
+obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
+obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
+obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
+obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c
index f948d3a14a9..a1800151b6c 100644
--- a/drivers/input/keyboard/atakbd.c
+++ b/drivers/input/keyboard/atakbd.c
@@ -217,7 +217,7 @@ static void atakbd_interrupt(unsigned char scancode, char down)
static int __init atakbd_init(void)
{
- int i;
+ int i, error;
if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
return -EIO;
@@ -247,9 +247,10 @@ static int __init atakbd_init(void)
}
/* error check */
- if (input_register_device(atakbd_dev)) {
+ error = input_register_device(atakbd_dev);
+ if (error) {
input_free_device(atakbd_dev);
- return -ENOMEM;
+ return error;
}
atari_input_keyboard_interrupt_hook = atakbd_interrupt;
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
new file mode 100644
index 00000000000..a67b29b089e
--- /dev/null
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -0,0 +1,382 @@
+/*
+ * File: drivers/input/keyboard/bf54x-keys.c
+ * Based on:
+ * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
+ *
+ * Created:
+ * Description: keypad driver for Analog Devices Blackfin BF54x Processors
+ *
+ *
+ * Modified:
+ * Copyright 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/version.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+
+#include <asm/portmux.h>
+#include <asm/mach/bf54x_keys.h>
+
+#define DRV_NAME "bf54x-keys"
+#define TIME_SCALE 100 /* 100 ns */
+#define MAX_MULT (0xFF * TIME_SCALE)
+#define MAX_RC 8 /* Max Row/Col */
+
+static const u16 per_rows[] = {
+ P_KEY_ROW7,
+ P_KEY_ROW6,
+ P_KEY_ROW5,
+ P_KEY_ROW4,
+ P_KEY_ROW3,
+ P_KEY_ROW2,
+ P_KEY_ROW1,
+ P_KEY_ROW0,
+ 0
+};
+
+static const u16 per_cols[] = {
+ P_KEY_COL7,
+ P_KEY_COL6,
+ P_KEY_COL5,
+ P_KEY_COL4,
+ P_KEY_COL3,
+ P_KEY_COL2,
+ P_KEY_COL1,
+ P_KEY_COL0,
+ 0
+};
+
+struct bf54x_kpad {
+ struct input_dev *input;
+ int irq;
+ unsigned short lastkey;
+ unsigned short *keycode;
+ struct timer_list timer;
+ unsigned int keyup_test_jiffies;
+};
+
+static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,
+ struct input_dev *input, u16 keyident)
+{
+ u16 i;
+
+ for (i = 0; i < input->keycodemax; i++)
+ if (bf54x_kpad->keycode[i + input->keycodemax] == keyident)
+ return bf54x_kpad->keycode[i];
+ return -1;
+}
+
+static inline void bfin_keycodecpy(unsigned short *keycode,
+ const unsigned int *pdata_kc,
+ unsigned short keymapsize)
+{
+ unsigned int i;
+
+ for (i = 0; i < keymapsize; i++) {
+ keycode[i] = pdata_kc[i] & 0xffff;
+ keycode[i + keymapsize] = pdata_kc[i] >> 16;
+ }
+}
+
+static inline u16 bfin_kpad_get_prescale(u32 timescale)
+{
+ u32 sclk = get_sclk();
+
+ return ((((sclk / 1000) * timescale) / 1024) - 1);
+}
+
+static inline u16 bfin_kpad_get_keypressed(struct bf54x_kpad *bf54x_kpad)
+{
+ return (bfin_read_KPAD_STAT() & KPAD_PRESSED);
+}
+
+static inline void bfin_kpad_clear_irq(void)
+{
+ bfin_write_KPAD_STAT(0xFFFF);
+ bfin_write_KPAD_ROWCOL(0xFFFF);
+}
+
+static void bfin_kpad_timer(unsigned long data)
+{
+ struct platform_device *pdev = (struct platform_device *) data;
+ struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
+
+ if (bfin_kpad_get_keypressed(bf54x_kpad)) {
+ /* Try again later */
+ mod_timer(&bf54x_kpad->timer,
+ jiffies + bf54x_kpad->keyup_test_jiffies);
+ return;
+ }
+
+ input_report_key(bf54x_kpad->input, bf54x_kpad->lastkey, 0);
+ input_sync(bf54x_kpad->input);
+
+ /* Clear IRQ Status */
+
+ bfin_kpad_clear_irq();
+ enable_irq(bf54x_kpad->irq);
+}
+
+static irqreturn_t bfin_kpad_isr(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
+ struct input_dev *input = bf54x_kpad->input;
+ int key;
+ u16 rowcol = bfin_read_KPAD_ROWCOL();
+
+ key = bfin_kpad_find_key(bf54x_kpad, input, rowcol);
+
+ input_report_key(input, key, 1);
+ input_sync(input);
+
+ if (bfin_kpad_get_keypressed(bf54x_kpad)) {
+ disable_irq(bf54x_kpad->irq);
+ bf54x_kpad->lastkey = key;
+ mod_timer(&bf54x_kpad->timer,
+ jiffies + bf54x_kpad->keyup_test_jiffies);
+ } else {
+ input_report_key(input, key, 0);
+ input_sync(input);
+
+ bfin_kpad_clear_irq();
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit bfin_kpad_probe(struct platform_device *pdev)
+{
+ struct bf54x_kpad *bf54x_kpad;
+ struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input;
+ int i, error;
+
+ if (!pdata->rows || !pdata->cols || !pdata->keymap) {
+ printk(KERN_ERR DRV_NAME
+ ": No rows, cols or keymap from pdata\n");
+ return -EINVAL;
+ }
+
+ if (!pdata->keymapsize ||
+ pdata->keymapsize > (pdata->rows * pdata->cols)) {
+ printk(KERN_ERR DRV_NAME ": Invalid keymapsize\n");
+ return -EINVAL;
+ }
+
+ bf54x_kpad = kzalloc(sizeof(struct bf54x_kpad), GFP_KERNEL);
+ if (!bf54x_kpad)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, bf54x_kpad);
+
+ /* Allocate memory for keymap followed by private LUT */
+ bf54x_kpad->keycode = kmalloc(pdata->keymapsize *
+ sizeof(unsigned short) * 2, GFP_KERNEL);
+ if (!bf54x_kpad->keycode) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ if (!pdata->debounce_time || !pdata->debounce_time > MAX_MULT ||
+ !pdata->coldrive_time || !pdata->coldrive_time > MAX_MULT) {
+ printk(KERN_ERR DRV_NAME
+ ": Invalid Debounce/Columdrive Time from pdata\n");
+ bfin_write_KPAD_MSEL(0xFF0); /* Default MSEL */
+ } else {
+ bfin_write_KPAD_MSEL(
+ ((pdata->debounce_time / TIME_SCALE)
+ & DBON_SCALE) |
+ (((pdata->coldrive_time / TIME_SCALE) << 8)
+ & COLDRV_SCALE));
+
+ }
+
+ if (!pdata->keyup_test_interval)
+ bf54x_kpad->keyup_test_jiffies = msecs_to_jiffies(50);
+ else
+ bf54x_kpad->keyup_test_jiffies =
+ msecs_to_jiffies(pdata->keyup_test_interval);
+
+ if (peripheral_request_list((u16 *)&per_rows[MAX_RC - pdata->rows],
+ DRV_NAME)) {
+ printk(KERN_ERR DRV_NAME
+ ": Requesting Peripherals failed\n");
+ error = -EFAULT;
+ goto out0;
+ }
+
+ if (peripheral_request_list((u16 *)&per_cols[MAX_RC - pdata->cols],
+ DRV_NAME)) {
+ printk(KERN_ERR DRV_NAME
+ ": Requesting Peripherals failed\n");
+ error = -EFAULT;
+ goto out1;
+ }
+
+ bf54x_kpad->irq = platform_get_irq(pdev, 0);
+ if (bf54x_kpad->irq < 0) {
+ error = -ENODEV;
+ goto out2;
+ }
+
+ error = request_irq(bf54x_kpad->irq, bfin_kpad_isr,
+ IRQF_SAMPLE_RANDOM, DRV_NAME, pdev);
+ if (error) {
+ printk(KERN_ERR DRV_NAME
+ ": unable to claim irq %d; error %d\n",
+ bf54x_kpad->irq, error);
+ error = -EBUSY;
+ goto out2;
+ }
+
+ input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+ goto out3;
+ }
+
+ bf54x_kpad->input = input;
+
+ input->name = pdev->name;
+ input->phys = "bf54x-keys/input0";
+ input->dev.parent = &pdev->dev;
+
+ input_set_drvdata(input, bf54x_kpad);
+
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0001;
+ input->id.version = 0x0100;
+
+ input->keycodesize = sizeof(unsigned short);
+ input->keycodemax = pdata->keymapsize;
+ input->keycode = bf54x_kpad->keycode;
+
+ bfin_keycodecpy(bf54x_kpad->keycode, pdata->keymap, pdata->keymapsize);
+
+ /* setup input device */
+ __set_bit(EV_KEY, input->evbit);
+
+ if (pdata->repeat)
+ __set_bit(EV_REP, input->evbit);
+
+ for (i = 0; i < input->keycodemax; i++)
+ __set_bit(bf54x_kpad->keycode[i] & KEY_MAX, input->keybit);
+ __clear_bit(KEY_RESERVED, input->keybit);
+
+ error = input_register_device(input);
+ if (error) {
+ printk(KERN_ERR DRV_NAME
+ ": Unable to register input device (%d)\n", error);
+ goto out4;
+ }
+
+ /* Init Keypad Key Up/Release test timer */
+
+ setup_timer(&bf54x_kpad->timer, bfin_kpad_timer, (unsigned long) pdev);
+
+ bfin_write_KPAD_PRESCALE(bfin_kpad_get_prescale(TIME_SCALE));
+
+ bfin_write_KPAD_CTL((((pdata->cols - 1) << 13) & KPAD_COLEN) |
+ (((pdata->rows - 1) << 10) & KPAD_ROWEN) |
+ (2 & KPAD_IRQMODE));
+
+ bfin_write_KPAD_CTL(bfin_read_KPAD_CTL() | KPAD_EN);
+
+ printk(KERN_ERR DRV_NAME
+ ": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq);
+
+ return 0;
+
+out4:
+ input_free_device(input);
+out3:
+ free_irq(bf54x_kpad->irq, pdev);
+out2:
+ peripheral_free_list((u16 *)&per_cols[MAX_RC - pdata->cols]);
+out1:
+ peripheral_free_list((u16 *)&per_rows[MAX_RC - pdata->rows]);
+out0:
+ kfree(bf54x_kpad->keycode);
+out:
+ kfree(bf54x_kpad);
+ platform_set_drvdata(pdev, NULL);
+
+ return error;
+}
+
+static int __devexit bfin_kpad_remove(struct platform_device *pdev)
+{
+ struct bfin_kpad_platform_data *pdata = pdev->dev.platform_data;
+ struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
+
+ del_timer_sync(&bf54x_kpad->timer);
+ free_irq(bf54x_kpad->irq, pdev);
+
+ input_unregister_device(bf54x_kpad->input);
+
+ peripheral_free_list((u16 *)&per_rows[MAX_RC - pdata->rows]);
+ peripheral_free_list((u16 *)&per_cols[MAX_RC - pdata->cols]);
+
+ kfree(bf54x_kpad->keycode);
+ kfree(bf54x_kpad);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+struct platform_driver bfin_kpad_device_driver = {
+ .probe = bfin_kpad_probe,
+ .remove = __devexit_p(bfin_kpad_remove),
+ .driver = {
+ .name = DRV_NAME,
+ }
+};
+
+static int __init bfin_kpad_init(void)
+{
+ return platform_driver_register(&bfin_kpad_device_driver);
+}
+
+static void __exit bfin_kpad_exit(void)
+{
+ platform_driver_unregister(&bfin_kpad_device_driver);
+}
+
+module_init(bfin_kpad_init);
+module_exit(bfin_kpad_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Keypad driver for BF54x Processors");
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index f0b22b8b276..e2a3293bc67 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -54,6 +54,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input;
int i, error;
+ int wakeup = 0;
input = input_allocate_device();
if (!input)
@@ -77,31 +78,51 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
int irq = gpio_to_irq(button->gpio);
unsigned int type = button->type ?: EV_KEY;
- set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
- error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM,
- button->desc ? button->desc : "gpio_keys",
- pdev);
+ if (irq < 0) {
+ error = irq;
+ printk(KERN_ERR
+ "gpio-keys: "
+ "Unable to get irq number for GPIO %d,"
+ "error %d\n",
+ button->gpio, error);
+ goto fail;
+ }
+
+ error = request_irq(irq, gpio_keys_isr,
+ IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ button->desc ? button->desc : "gpio_keys",
+ pdev);
if (error) {
- printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",
+ printk(KERN_ERR
+ "gpio-keys: Unable to claim irq %d; error %d\n",
irq, error);
goto fail;
}
+ if (button->wakeup)
+ wakeup = 1;
+
input_set_capability(input, type, button->code);
}
error = input_register_device(input);
if (error) {
- printk(KERN_ERR "Unable to register gpio-keys input device\n");
+ printk(KERN_ERR
+ "gpio-keys: Unable to register input device, "
+ "error: %d\n", error);
goto fail;
}
+ device_init_wakeup(&pdev->dev, wakeup);
+
return 0;
fail:
- for (i = i - 1; i >= 0; i--)
+ while (--i >= 0)
free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
+ platform_set_drvdata(pdev, NULL);
input_free_device(input);
return error;
@@ -113,6 +134,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
struct input_dev *input = platform_get_drvdata(pdev);
int i;
+ device_init_wakeup(&pdev->dev, 0);
+
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, pdev);
@@ -123,9 +146,53 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
return 0;
}
+
+#ifdef CONFIG_PM
+static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ int i;
+
+ if (device_may_wakeup(&pdev->dev)) {
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ if (button->wakeup) {
+ int irq = gpio_to_irq(button->gpio);
+ enable_irq_wake(irq);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int gpio_keys_resume(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ int i;
+
+ if (device_may_wakeup(&pdev->dev)) {
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ if (button->wakeup) {
+ int irq = gpio_to_irq(button->gpio);
+ disable_irq_wake(irq);
+ }
+ }
+ }
+
+ return 0;
+}
+#else
+#define gpio_keys_suspend NULL
+#define gpio_keys_resume NULL
+#endif
+
struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = __devexit_p(gpio_keys_remove),
+ .suspend = gpio_keys_suspend,
+ .resume = gpio_keys_resume,
.driver = {
.name = "gpio-keys",
}
diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c
new file mode 100644
index 00000000000..bec1cf48372
--- /dev/null
+++ b/drivers/input/keyboard/jornada680_kbd.c
@@ -0,0 +1,277 @@
+/*
+ * drivers/input/keyboard/jornada680_kbd.c
+ *
+ * HP Jornada 620/660/680/690 scan keyboard platform driver
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ *
+ * Based on hp680_keyb.c
+ * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2005 Andriy Skulysh
+ * Split from drivers/input/keyboard/hp600_keyb.c
+ * Copyright (C) 2000 Yaegashi Takeshi (hp6xx kbd scan routine and translation table)
+ * Copyright (C) 2000 Niibe Yutaka (HP620 Keyb translation table)
+ *
+ * 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.
+ */
+
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input-polldev.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+
+#define PCCR 0xa4000104
+#define PDCR 0xa4000106
+#define PECR 0xa4000108
+#define PFCR 0xa400010a
+#define PCDR 0xa4000124
+#define PDDR 0xa4000126
+#define PEDR 0xa4000128
+#define PFDR 0xa400012a
+#define PGDR 0xa400012c
+#define PHDR 0xa400012e
+#define PJDR 0xa4000130
+#define PKDR 0xa4000132
+#define PLDR 0xa4000134
+
+static const unsigned short jornada_scancodes[] = {
+/* PTD1 */ KEY_CAPSLOCK, KEY_MACRO, KEY_LEFTCTRL, 0, KEY_ESC, 0, 0, 0, /* 1 -> 8 */
+ KEY_F1, KEY_F2, KEY_F3, KEY_F8, KEY_F7, KEY_F2, KEY_F4, KEY_F5, /* 9 -> 16 */
+/* PTD5 */ KEY_SLASH, KEY_APOSTROPHE, KEY_ENTER, 0, KEY_Z, 0, 0, 0, /* 17 -> 24 */
+ KEY_X, KEY_C, KEY_V, KEY_DOT, KEY_COMMA, KEY_M, KEY_B, KEY_N, /* 25 -> 32 */
+/* PTD7 */ KEY_KP2, KEY_KP6, 0, 0, 0, 0, 0, 0, /* 33 -> 40 */
+ 0, 0, 0, KEY_KP4, 0, 0, KEY_LEFTALT, KEY_HANJA, /* 41 -> 48 */
+/* PTE0 */ 0, 0, 0, 0, KEY_FINANCE, 0, 0, 0, /* 49 -> 56 */
+ KEY_LEFTCTRL, 0, KEY_SPACE, KEY_KPDOT, KEY_VOLUMEUP, 249, 0, 0, /* 57 -> 64 */
+/* PTE1 */ KEY_SEMICOLON, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, KEY_A, 0, 0, 0,/* 65 -> 72 */
+ KEY_S, KEY_D, KEY_F, KEY_L, KEY_K, KEY_J, KEY_G, KEY_H, /* 73 -> 80 */
+/* PTE3 */ KEY_KP8, KEY_LEFTMETA, KEY_RIGHTSHIFT, 0, KEY_TAB, 0, 0,0, /* 81 -> 88 */
+ 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, /* 89 -> 96 */
+/* PTE6 */ KEY_P, KEY_LEFTBRACE, KEY_BACKSPACE, 0, KEY_Q, 0, 0, 0, /* 97 -> 104 */
+ KEY_W, KEY_E, KEY_R, KEY_O, KEY_I, KEY_U, KEY_T, KEY_R, /* 105 -> 112 */
+/* PTE7 */ KEY_0, KEY_MINUS, KEY_EQUAL, 0, KEY_1, 0, 0, 0, /* 113 -> 120 */
+ KEY_2, KEY_3, KEY_4, KEY_9, KEY_8, KEY_7, KEY_5, KEY_6, /* 121 -> 128 */
+/* **** */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+};
+
+#define JORNADA_SCAN_SIZE 18
+
+struct jornadakbd {
+ struct input_polled_dev *poll_dev;
+ unsigned short keymap[ARRAY_SIZE(jornada_scancodes)];
+ unsigned char length;
+ unsigned char old_scan[JORNADA_SCAN_SIZE];
+ unsigned char new_scan[JORNADA_SCAN_SIZE];
+};
+
+static void jornada_parse_kbd(struct jornadakbd *jornadakbd)
+{
+ struct input_dev *input_dev = jornadakbd->poll_dev->input;
+ unsigned short *keymap = jornadakbd->keymap;
+ unsigned int sync_me = 0;
+ unsigned int i, j;
+
+ for (i = 0; i < JORNADA_SCAN_SIZE; i++) {
+ unsigned char new = jornadakbd->new_scan[i];
+ unsigned char old = jornadakbd->old_scan[i];
+ unsigned int xor = new ^ old;
+
+ if (xor == 0)
+ continue;
+
+ for (j = 0; j < 8; j++) {
+ unsigned int bit = 1 << j;
+ if (xor & bit) {
+ unsigned int scancode = (i << 3) + j;
+ input_event(input_dev,
+ EV_MSC, MSC_SCAN, scancode);
+ input_report_key(input_dev,
+ keymap[scancode],
+ !(new & bit));
+ sync_me = 1;
+ }
+ }
+ }
+
+ if (sync_me)
+ input_sync(input_dev);
+}
+
+static void jornada_scan_keyb(unsigned char *s)
+{
+ int i;
+ unsigned short ec_static, dc_static; /* = UINT16_t */
+ unsigned char matrix_switch[] = {
+ 0xfd, 0xff, /* PTD1 PD(1) */
+ 0xdf, 0xff, /* PTD5 PD(5) */
+ 0x7f, 0xff, /* PTD7 PD(7) */
+ 0xff, 0xfe, /* PTE0 PE(0) */
+ 0xff, 0xfd, /* PTE1 PE(1) */
+ 0xff, 0xf7, /* PTE3 PE(3) */
+ 0xff, 0xbf, /* PTE6 PE(6) */
+ 0xff, 0x7f, /* PTE7 PE(7) */
+ }, *t = matrix_switch;
+ /* PD(x) :
+ 1. 0xcc0c & (1~(1 << (2*(x)+1)))))
+ 2. (0xf0cf & 0xfffff) */
+ /* PE(x) :
+ 1. 0xcc0c & 0xffff
+ 2. 0xf0cf & (1~(1 << (2*(x)+1))))) */
+ unsigned short matrix_PDE[] = {
+ 0xcc04, 0xf0cf, /* PD(1) */
+ 0xc40c, 0xf0cf, /* PD(5) */
+ 0x4c0c, 0xf0cf, /* PD(7) */
+ 0xcc0c, 0xf0cd, /* PE(0) */
+ 0xcc0c, 0xf0c7, /* PE(1) */
+ 0xcc0c, 0xf04f, /* PE(3) */
+ 0xcc0c, 0xd0cf, /* PE(6) */
+ 0xcc0c, 0x70cf, /* PE(7) */
+ }, *y = matrix_PDE;
+
+ /* Save these control reg bits */
+ dc_static = (ctrl_inw(PDCR) & (~0xcc0c));
+ ec_static = (ctrl_inw(PECR) & (~0xf0cf));
+
+ for (i = 0; i < 8; i++) {
+ /* disable output for all but the one we want to scan */
+ ctrl_outw((dc_static | *y++), PDCR);
+ ctrl_outw((ec_static | *y++), PECR);
+ udelay(5);
+
+ /* Get scanline row */
+ ctrl_outb(*t++, PDDR);
+ ctrl_outb(*t++, PEDR);
+ udelay(50);
+
+ /* Read data */
+ *s++ = ctrl_inb(PCDR);
+ *s++ = ctrl_inb(PFDR);
+ }
+ /* Scan no lines */
+ ctrl_outb(0xff, PDDR);
+ ctrl_outb(0xff, PEDR);
+
+ /* Enable all scanlines */
+ ctrl_outw((dc_static | (0x5555 & 0xcc0c)),PDCR);
+ ctrl_outw((ec_static | (0x5555 & 0xf0cf)),PECR);
+
+ /* Ignore extra keys and events */
+ *s++ = ctrl_inb(PGDR);
+ *s++ = ctrl_inb(PHDR);
+}
+
+static void jornadakbd680_poll(struct input_polled_dev *dev)
+{
+ struct jornadakbd *jornadakbd = dev->private;
+
+ jornada_scan_keyb(jornadakbd->new_scan);
+ jornada_parse_kbd(jornadakbd);
+ memcpy(jornadakbd->old_scan, jornadakbd->new_scan, JORNADA_SCAN_SIZE);
+}
+
+static int __devinit jornada680kbd_probe(struct platform_device *pdev)
+{
+ struct jornadakbd *jornadakbd;
+ struct input_polled_dev *poll_dev;
+ struct input_dev *input_dev;
+ int i, error;
+
+ jornadakbd = kzalloc(sizeof(struct jornadakbd), GFP_KERNEL);
+ if (!jornadakbd)
+ return -ENOMEM;
+
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev) {
+ error = -ENOMEM;
+ goto failed;
+ }
+
+ platform_set_drvdata(pdev, jornadakbd);
+
+ jornadakbd->poll_dev = poll_dev;
+
+ memcpy(jornadakbd->keymap, jornada_scancodes,
+ sizeof(jornadakbd->keymap));
+
+ poll_dev->private = jornadakbd;
+ poll_dev->poll = jornadakbd680_poll;
+ poll_dev->poll_interval = 50; /* msec */
+
+ input_dev = poll_dev->input;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->name = "HP Jornada 680 keyboard";
+ input_dev->phys = "jornadakbd/input0";
+ input_dev->keycode = jornadakbd->keymap;
+ input_dev->keycodesize = sizeof(unsigned short);
+ input_dev->keycodemax = ARRAY_SIZE(jornada_scancodes);
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->id.bustype = BUS_HOST;
+
+ for (i = 0; i < 128; i++)
+ if (jornadakbd->keymap[i])
+ __set_bit(jornadakbd->keymap[i], input_dev->keybit);
+ __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ error = input_register_polled_device(jornadakbd->poll_dev);
+ if (error)
+ goto failed;
+
+ return 0;
+
+ failed:
+ printk(KERN_ERR "Jornadakbd: failed to register driver, error: %d\n",
+ error);
+ platform_set_drvdata(pdev, NULL);
+ input_free_polled_device(poll_dev);
+ kfree(jornadakbd);
+ return error;
+
+}
+
+static int __devexit jornada680kbd_remove(struct platform_device *pdev)
+{
+ struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ input_unregister_polled_device(jornadakbd->poll_dev);
+ input_free_polled_device(jornadakbd->poll_dev);
+ kfree(jornadakbd);
+
+ return 0;
+}
+
+static struct platform_driver jornada680kbd_driver = {
+ .driver = {
+ .name = "jornada680_kbd",
+ },
+ .probe = jornada680kbd_probe,
+ .remove = __devexit_p(jornada680kbd_remove),
+};
+
+static int __init jornada680kbd_init(void)
+{
+ return platform_driver_register(&jornada680kbd_driver);
+}
+
+static void __exit jornada680kbd_exit(void)
+{
+ platform_driver_unregister(&jornada680kbd_driver);
+}
+
+module_init(jornada680kbd_init);
+module_exit(jornada680kbd_exit);
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 620/660/680/690 Keyboard Driver");
+MODULE_LICENSE("GPLv2");
diff --git a/drivers/input/keyboard/jornada720_kbd.c b/drivers/input/keyboard/jornada720_kbd.c
new file mode 100644
index 00000000000..e6696b3c941
--- /dev/null
+++ b/drivers/input/keyboard/jornada720_kbd.c
@@ -0,0 +1,185 @@
+/*
+ * drivers/input/keyboard/jornada720_kbd.c
+ *
+ * HP Jornada 720 keyboard platform driver
+ *
+ * Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@Gmail.com>
+ *
+ * Copyright (C) 2006 jornada 720 kbd driver by
+ Filip Zyzniewsk <Filip.Zyzniewski@tefnet.plX
+ * based on (C) 2004 jornada 720 kbd driver by
+ Alex Lange <chicken@handhelds.org>
+ *
+ * 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.
+ *
+ */
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/arch/jornada720.h>
+#include <asm/hardware.h>
+
+MODULE_AUTHOR("Kristoffer Ericson <Kristoffer.Ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 keyboard driver");
+MODULE_LICENSE("GPLv2");
+
+static unsigned short jornada_std_keymap[128] = { /* ROW */
+ 0, KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, /* #1 */
+ KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE, /* -> */
+ 0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, /* #2 */
+ KEY_0, KEY_MINUS, KEY_EQUAL,0, 0, 0, /* -> */
+ 0, KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, /* #3 */
+ KEY_P, KEY_BACKSLASH, KEY_BACKSPACE, 0, 0, 0, /* -> */
+ 0, KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, /* #4 */
+ KEY_SEMICOLON, KEY_LEFTBRACE, KEY_RIGHTBRACE, 0, 0, 0, /* -> */
+ 0, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, KEY_COMMA, /* #5 */
+ KEY_DOT, KEY_KPMINUS, KEY_APOSTROPHE, KEY_ENTER, 0, 0,0, /* -> */
+ 0, KEY_TAB, 0, KEY_LEFTSHIFT, 0, KEY_APOSTROPHE, 0, 0, 0, 0, /* #6 */
+ KEY_UP, 0, KEY_RIGHTSHIFT, 0, 0, 0,0, 0, 0, 0, 0, KEY_LEFTALT, KEY_GRAVE, /* -> */
+ 0, 0, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0,0, KEY_KPASTERISK, /* -> */
+ KEY_LEFTCTRL, 0, KEY_SPACE, 0, 0, 0, KEY_SLASH, KEY_DELETE, 0, 0, /* -> */
+ 0, 0, 0, KEY_POWER, /* -> */
+};
+
+struct jornadakbd {
+ unsigned short keymap[ARRAY_SIZE(jornada_std_keymap)];
+ struct input_dev *input;
+};
+
+static irqreturn_t jornada720_kbd_interrupt(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
+ struct input_dev *input = jornadakbd->input;
+ u8 count, kbd_data, scan_code;
+
+ /* startup ssp with spinlock */
+ jornada_ssp_start();
+
+ if (jornada_ssp_inout(GETSCANKEYCODE) != TXDUMMY) {
+ printk(KERN_DEBUG
+ "jornada720_kbd: "
+ "GetKeycode command failed with ETIMEDOUT, "
+ "flushed bus\n");
+ } else {
+ /* How many keycodes are waiting for us? */
+ count = jornada_ssp_byte(TXDUMMY);
+
+ /* Lets drag them out one at a time */
+ while (count--) {
+ /* Exchange TxDummy for location (keymap[kbddata]) */
+ kbd_data = jornada_ssp_byte(TXDUMMY);
+ scan_code = kbd_data & 0x7f;
+
+ input_event(input, EV_MSC, MSC_SCAN, scan_code);
+ input_report_key(input, jornadakbd->keymap[scan_code],
+ !(kbd_data & 0x80));
+ input_sync(input);
+ }
+ }
+
+ /* release spinlock and turn off ssp */
+ jornada_ssp_end();
+
+ return IRQ_HANDLED;
+};
+
+static int __devinit jornada720_kbd_probe(struct platform_device *pdev)
+{
+ struct jornadakbd *jornadakbd;
+ struct input_dev *input_dev;
+ int i, err;
+
+ jornadakbd = kzalloc(sizeof(struct jornadakbd), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!jornadakbd || !input_dev) {
+ err = -ENOMEM;
+ goto fail1;
+ }
+
+ platform_set_drvdata(pdev, jornadakbd);
+
+ memcpy(jornadakbd->keymap, jornada_std_keymap,
+ sizeof(jornada_std_keymap));
+ jornadakbd->input = input_dev;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->name = "HP Jornada 720 keyboard";
+ input_dev->phys = "jornadakbd/input0";
+ input_dev->keycode = jornadakbd->keymap;
+ input_dev->keycodesize = sizeof(unsigned short);
+ input_dev->keycodemax = ARRAY_SIZE(jornada_std_keymap);
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->dev.parent = &pdev->dev;
+
+ for (i = 0; i < ARRAY_SIZE(jornadakbd->keymap); i++)
+ __set_bit(jornadakbd->keymap[i], input_dev->keybit);
+ __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ err = request_irq(IRQ_GPIO0,
+ jornada720_kbd_interrupt,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "jornadakbd", pdev);
+ if (err) {
+ printk(KERN_INFO "jornadakbd720_kbd: Unable to grab IRQ\n");
+ goto fail1;
+ }
+
+ err = input_register_device(jornadakbd->input);
+ if (err)
+ goto fail2;
+
+ return 0;
+
+ fail2: /* IRQ, DEVICE, MEMORY */
+ free_irq(IRQ_GPIO0, pdev);
+ fail1: /* DEVICE, MEMORY */
+ platform_set_drvdata(pdev, NULL);
+ input_free_device(input_dev);
+ kfree(jornadakbd);
+ return err;
+};
+
+static int __devexit jornada720_kbd_remove(struct platform_device *pdev)
+{
+ struct jornadakbd *jornadakbd = platform_get_drvdata(pdev);
+
+ free_irq(IRQ_GPIO0, pdev);
+ platform_set_drvdata(pdev, NULL);
+ input_unregister_device(jornadakbd->input);
+ kfree(jornadakbd);
+
+ return 0;
+}
+
+static struct platform_driver jornada720_kbd_driver = {
+ .driver = {
+ .name = "jornada720_kbd",
+ },
+ .probe = jornada720_kbd_probe,
+ .remove = __devexit_p(jornada720_kbd_remove),
+};
+
+static int __init jornada720_kbd_init(void)
+{
+ return platform_driver_register(&jornada720_kbd_driver);
+}
+
+static void __exit jornada720_kbd_exit(void)
+{
+ platform_driver_unregister(&jornada720_kbd_driver);
+}
+
+module_init(jornada720_kbd_init);
+module_exit(jornada720_kbd_exit);
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
new file mode 100644
index 00000000000..2b404284c28
--- /dev/null
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -0,0 +1,252 @@
+/*
+ * SEGA Dreamcast keyboard driver
+ * Based on drivers/usb/usbkbd.c
+ * Copyright YAEGASHI Takeshi, 2001
+ * Porting to 2.6 Copyright Adrian McMenamin, 2007
+ *
+ * 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/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/maple.h>
+#include <asm/mach/maple.h>
+
+/* Very simple mutex to ensure proper cleanup */
+static DEFINE_MUTEX(maple_keyb_mutex);
+
+#define NR_SCANCODES 256
+
+MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin");
+MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
+MODULE_LICENSE("GPL");
+
+struct dc_kbd {
+ struct input_dev *dev;
+ unsigned short keycode[NR_SCANCODES];
+ unsigned char new[8];
+ unsigned char old[8];
+};
+
+static const unsigned short dc_kbd_keycode[NR_SCANCODES] = {
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_A, KEY_B, KEY_C, KEY_D,
+ KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
+ KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
+ KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_1, KEY_2,
+ KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
+ KEY_ENTER, KEY_ESC, KEY_BACKSPACE, KEY_TAB, KEY_SPACE, KEY_MINUS, KEY_EQUAL, KEY_LEFTBRACE,
+ KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_BACKSLASH, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_GRAVE, KEY_COMMA,
+ KEY_DOT, KEY_SLASH, KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6,
+ KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_SYSRQ,
+ KEY_SCROLLLOCK, KEY_PAUSE, KEY_INSERT, KEY_HOME, KEY_PAGEUP, KEY_DELETE,
+ KEY_END, KEY_PAGEDOWN, KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP,
+ KEY_NUMLOCK, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS, KEY_KPPLUS, KEY_KPENTER, KEY_KP1, KEY_KP2,
+ KEY_KP3, KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, KEY_KP9, KEY_KP0, KEY_KPDOT,
+ KEY_102ND, KEY_COMPOSE, KEY_POWER, KEY_KPEQUAL, KEY_F13, KEY_F14, KEY_F15,
+ KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20,
+ KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_OPEN, KEY_HELP, KEY_PROPS, KEY_FRONT,
+ KEY_STOP, KEY_AGAIN, KEY_UNDO, KEY_CUT, KEY_COPY, KEY_PASTE, KEY_FIND, KEY_MUTE,
+ KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_KPCOMMA, KEY_RESERVED, KEY_RO, KEY_KATAKANAHIRAGANA , KEY_YEN,
+ KEY_HENKAN, KEY_MUHENKAN, KEY_KPJPCOMMA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_HANGEUL, KEY_HANJA, KEY_KATAKANA, KEY_HIRAGANA, KEY_ZENKAKUHANKAKU, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ KEY_LEFTCTRL, KEY_LEFTSHIFT, KEY_LEFTALT, KEY_LEFTMETA, KEY_RIGHTCTRL, KEY_RIGHTSHIFT, KEY_RIGHTALT, KEY_RIGHTMETA,
+ KEY_PLAYPAUSE, KEY_STOPCD, KEY_PREVIOUSSONG, KEY_NEXTSONG, KEY_EJECTCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_MUTE,
+ KEY_WWW, KEY_BACK, KEY_FORWARD, KEY_STOP, KEY_FIND, KEY_SCROLLUP, KEY_SCROLLDOWN, KEY_EDIT, KEY_SLEEP,
+ KEY_SCREENLOCK, KEY_REFRESH, KEY_CALC, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
+};
+
+static void dc_scan_kbd(struct dc_kbd *kbd)
+{
+ struct input_dev *dev = kbd->dev;
+ void *ptr;
+ int code, keycode;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ code = i + 224;
+ keycode = kbd->keycode[code];
+ input_event(dev, EV_MSC, MSC_SCAN, code);
+ input_report_key(dev, keycode, (kbd->new[0] >> i) & 1);
+ }
+
+ for (i = 2; i < 8; i++) {
+ ptr = memchr(kbd->new + 2, kbd->old[i], 6);
+ code = kbd->old[i];
+ if (code > 3 && ptr == NULL) {
+ keycode = kbd->keycode[code];
+ if (keycode) {
+ input_event(dev, EV_MSC, MSC_SCAN, code);
+ input_report_key(dev, keycode, 0);
+ } else
+ printk(KERN_DEBUG "maple_keyb: "
+ "Unknown key (scancode %#x) released.",
+ code);
+ }
+ ptr = memchr(kbd->old + 2, kbd->new[i], 6);
+ code = kbd->new[i];
+ if (code > 3 && ptr) {
+ keycode = kbd->keycode[code];
+ if (keycode) {
+ input_event(dev, EV_MSC, MSC_SCAN, code);
+ input_report_key(dev, keycode, 1);
+ } else
+ printk(KERN_DEBUG "maple_keyb: "
+ "Unknown key (scancode %#x) pressed.",
+ code);
+ }
+ }
+ input_sync(dev);
+ memcpy(kbd->old, kbd->new, 8);
+}
+
+static void dc_kbd_callback(struct mapleq *mq)
+{
+ struct maple_device *mapledev = mq->dev;
+ struct dc_kbd *kbd = mapledev->private_data;
+ unsigned long *buf = mq->recvbuf;
+
+ /*
+ * We should always be getting the lock because the only
+ * time it may be locked if driver is in cleanup phase.
+ */
+ if (likely(mutex_trylock(&maple_keyb_mutex))) {
+
+ if (buf[1] == mapledev->function) {
+ memcpy(kbd->new, buf + 2, 8);
+ dc_scan_kbd(kbd);
+ }
+
+ mutex_unlock(&maple_keyb_mutex);
+ }
+}
+
+static int dc_kbd_connect(struct maple_device *mdev)
+{
+ int i, error;
+ struct dc_kbd *kbd;
+ struct input_dev *dev;
+
+ if (!(mdev->function & MAPLE_FUNC_KEYBOARD))
+ return -EINVAL;
+
+ kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
+ dev = input_allocate_device();
+ if (!kbd || !dev) {
+ error = -ENOMEM;
+ goto fail;
+ }
+
+ mdev->private_data = kbd;
+
+ kbd->dev = dev;
+ memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
+
+ dev->name = mdev->product_name;
+ dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ dev->keycode = kbd->keycode;
+ dev->keycodesize = sizeof (unsigned short);
+ dev->keycodemax = ARRAY_SIZE(kbd->keycode);
+ dev->id.bustype = BUS_HOST;
+ dev->dev.parent = &mdev->dev;
+
+ for (i = 0; i < NR_SCANCODES; i++)
+ __set_bit(dc_kbd_keycode[i], dev->keybit);
+ __clear_bit(KEY_RESERVED, dev->keybit);
+
+ input_set_capability(dev, EV_MSC, MSC_SCAN);
+ input_set_drvdata(dev, kbd);
+
+ error = input_register_device(dev);
+ if (error)
+ goto fail;
+
+ /* Maple polling is locked to VBLANK - which may be just 50/s */
+ maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, MAPLE_FUNC_KEYBOARD);
+ return 0;
+
+ fail:
+ input_free_device(dev);
+ kfree(kbd);
+ mdev->private_data = NULL;
+ return error;
+}
+
+static void dc_kbd_disconnect(struct maple_device *mdev)
+{
+ struct dc_kbd *kbd;
+
+ mutex_lock(&maple_keyb_mutex);
+
+ kbd = mdev->private_data;
+ mdev->private_data = NULL;
+ input_unregister_device(kbd->dev);
+ kfree(kbd);
+
+ mutex_unlock(&maple_keyb_mutex);
+}
+
+/* allow the keyboard to be used */
+static int probe_maple_kbd(struct device *dev)
+{
+ struct maple_device *mdev = to_maple_dev(dev);
+ struct maple_driver *mdrv = to_maple_driver(dev->driver);
+ int error;
+
+ error = dc_kbd_connect(mdev);
+ if (error)
+ return error;
+
+ mdev->driver = mdrv;
+ mdev->registered = 1;
+
+ return 0;
+}
+
+static struct maple_driver dc_kbd_driver = {
+ .function = MAPLE_FUNC_KEYBOARD,
+ .connect = dc_kbd_connect,
+ .disconnect = dc_kbd_disconnect,
+ .drv = {
+ .name = "Dreamcast_keyboard",
+ .probe = probe_maple_kbd,
+ },
+};
+
+static int __init dc_kbd_init(void)
+{
+ return maple_driver_register(&dc_kbd_driver.drv);
+}
+
+static void __exit dc_kbd_exit(void)
+{
+ driver_unregister(&dc_kbd_driver.drv);
+}
+
+module_init(dc_kbd_init);
+module_exit(dc_kbd_exit);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 3a228634f10..76f1969552c 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -233,7 +233,7 @@ static void omap_kp_tasklet(unsigned long data)
omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
kp_cur_group = -1;
}
- }
+ }
}
static ssize_t omap_kp_enable_show(struct device *dev,
@@ -318,7 +318,7 @@ static int __init omap_kp_probe(struct platform_device *pdev)
keymap = pdata->keymap;
if (pdata->rep)
- set_bit(EV_REP, input_dev->evbit);
+ __set_bit(EV_REP, input_dev->evbit);
if (pdata->delay)
omap_kp->delay = pdata->delay;
@@ -365,9 +365,9 @@ static int __init omap_kp_probe(struct platform_device *pdev)
goto err2;
/* setup input device */
- set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
for (i = 0; keymap[i] != 0; i++)
- set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
+ __set_bit(keymap[i] & KEY_MAX, input_dev->keybit);
input_dev->name = "omap-keypad";
input_dev->phys = "omap-keypad/input0";
input_dev->dev.parent = &pdev->dev;
@@ -377,10 +377,6 @@ static int __init omap_kp_probe(struct platform_device *pdev)
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
- input_dev->keycode = keymap;
- input_dev->keycodesize = sizeof(unsigned int);
- input_dev->keycodemax = pdata->keymapsize;
-
ret = input_register_device(omap_kp->input);
if (ret < 0) {
printk(KERN_ERR "Unable to register omap-keypad input device\n");
@@ -403,15 +399,15 @@ static int __init omap_kp_probe(struct platform_device *pdev)
} else {
for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
if (request_irq(OMAP_GPIO_IRQ(row_gpios[irq_idx]),
- omap_kp_interrupt,
+ omap_kp_interrupt,
IRQF_TRIGGER_FALLING,
- "omap-keypad", omap_kp) < 0)
+ "omap-keypad", omap_kp) < 0)
goto err5;
}
}
return 0;
err5:
- for (i = irq_idx-1; i >=0; i--)
+ for (i = irq_idx - 1; i >=0; i--)
free_irq(row_gpios[i], 0);
err4:
input_unregister_device(omap_kp->input);
@@ -440,9 +436,9 @@ static int omap_kp_remove(struct platform_device *pdev)
if (cpu_is_omap24xx()) {
int i;
for (i = 0; i < omap_kp->cols; i++)
- omap_free_gpio(col_gpios[i]);
+ omap_free_gpio(col_gpios[i]);
for (i = 0; i < omap_kp->rows; i++) {
- omap_free_gpio(row_gpios[i]);
+ omap_free_gpio(row_gpios[i]);
free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
}
} else {
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c
index ebe5eacf299..b7061aa3881 100644
--- a/drivers/input/keyboard/pxa27x_keyboard.c
+++ b/drivers/input/keyboard/pxa27x_keyboard.c
@@ -23,6 +23,8 @@
#include <linux/input.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -40,6 +42,8 @@
col/2 == 2 ? KPASMKP2 : KPASMKP3)
#define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2)))
+static struct clk *pxakbd_clk;
+
static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id)
{
struct platform_device *pdev = dev_id;
@@ -104,7 +108,7 @@ static int pxakbd_open(struct input_dev *dev)
KPREC = 0x7F;
/* Enable unit clock */
- pxa_set_cken(CKEN_KEYPAD, 1);
+ clk_enable(pxakbd_clk);
return 0;
}
@@ -112,7 +116,7 @@ static int pxakbd_open(struct input_dev *dev)
static void pxakbd_close(struct input_dev *dev)
{
/* Disable clock unit */
- pxa_set_cken(CKEN_KEYPAD, 0);
+ clk_disable(pxakbd_clk);
}
#ifdef CONFIG_PM
@@ -140,7 +144,8 @@ static int pxakbd_resume(struct platform_device *pdev)
KPREC = pdata->reg_kprec;
/* Enable unit clock */
- pxa_set_cken(CKEN_KEYPAD, 1);
+ clk_disable(pxakbd_clk);
+ clk_enable(pxakbd_clk);
}
mutex_unlock(&input_dev->mutex);
@@ -158,11 +163,18 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
struct input_dev *input_dev;
int i, row, col, error;
+ pxakbd_clk = clk_get(&pdev->dev, "KBDCLK");
+ if (IS_ERR(pxakbd_clk)) {
+ error = PTR_ERR(pxakbd_clk);
+ goto err_clk;
+ }
+
/* Create and register the input driver. */
input_dev = input_allocate_device();
if (!input_dev) {
printk(KERN_ERR "Cannot request keypad device\n");
- return -ENOMEM;
+ error = -ENOMEM;
+ goto err_alloc;
}
input_dev->name = DRIVER_NAME;
@@ -185,7 +197,6 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
DRIVER_NAME, pdev);
if (error) {
printk(KERN_ERR "Cannot request keypad IRQ\n");
- pxa_set_cken(CKEN_KEYPAD, 0);
goto err_free_dev;
}
@@ -217,6 +228,9 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
free_irq(IRQ_KEYPAD, pdev);
err_free_dev:
input_free_device(input_dev);
+ err_alloc:
+ clk_put(pxakbd_clk);
+ err_clk:
return error;
}
@@ -226,6 +240,7 @@ static int __devexit pxakbd_remove(struct platform_device *pdev)
input_unregister_device(input_dev);
free_irq(IRQ_KEYPAD, pdev);
+ clk_put(pxakbd_clk);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index d602b8fa7d4..7acc6351bb4 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -152,7 +152,7 @@ config INPUT_POWERMATE
config INPUT_YEALINK
tristate "Yealink usb-p1k voip phone"
- depends EXPERIMENTAL
+ depends on EXPERIMENTAL
depends on USB_ARCH_HAS_HCD
select USB
help
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 2c5f11a4f6b..64d70a9b714 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -48,11 +48,13 @@ static const struct alps_model_info alps_model_data[] = {
{ { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
{ { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 },
{ { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS }, /* Dell Latitude D800 */
+ { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
{ { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
{ { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
{ { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
{ { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
+ { { 0x73, 0x02, 0x50 }, 0xcf, 0xff, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
};
/*
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index a1804bfdbb8..0117817bf53 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -502,18 +502,23 @@ static void atp_complete(struct urb* urb)
/* reset the accumulator on release */
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
+ }
+
+ /* Geyser 3 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 */
- /* Geyser 3 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 (!key && atp_is_geyser_3(dev)) {
+ if (atp_is_geyser_3(dev)) {
+ 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);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 608674d0be8..d7de4c53b3d 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -97,6 +97,14 @@ static const struct dmi_system_id lifebook_dmi_table[] = {
.callback = lifebook_set_6byte_proto,
},
{
+ .ident = "CF-72",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"),
+ },
+ .callback = lifebook_set_serio_phys,
+ .driver_data = "isa0060/serio3",
+ },
+ {
.ident = "Lifebook B142",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
@@ -282,7 +290,7 @@ static int lifebook_create_relative_device(struct psmouse *psmouse)
int lifebook_init(struct psmouse *psmouse)
{
struct input_dev *dev1 = psmouse->dev;
- int max_coord = lifebook_use_6byte_proto ? 1024 : 4096;
+ int max_coord = lifebook_use_6byte_proto ? 4096 : 1024;
if (lifebook_absolute_mode(psmouse))
return -1;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index b9f0fb2530e..07352575653 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -648,9 +648,10 @@ static int psmouse_extensions(struct psmouse *psmouse,
/*
* Reset to defaults in case the device got confused by extended
- * protocol probes. Note that we do full reset becuase some mice
- * put themselves to sleep when see PSMOUSE_RESET_DIS.
+ * protocol probes. Note that we follow up with full reset because
+ * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS.
*/
+ ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
psmouse_reset(psmouse);
if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 9173916b8be..79146d6ed2a 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -61,9 +61,11 @@ struct mousedev {
int open;
int minor;
char name[16];
+ struct input_handle handle;
wait_queue_head_t wait;
struct list_head client_list;
- struct input_handle handle;
+ spinlock_t client_lock; /* protects client_list */
+ struct mutex mutex;
struct device dev;
struct list_head mixdev_node;
@@ -113,108 +115,137 @@ static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
static struct input_handler mousedev_handler;
static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
+static DEFINE_MUTEX(mousedev_table_mutex);
static struct mousedev *mousedev_mix;
static LIST_HEAD(mousedev_mix_list);
+static void mixdev_open_devices(void);
+static void mixdev_close_devices(void);
+
#define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
#define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
-static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
+static void mousedev_touchpad_event(struct input_dev *dev,
+ struct mousedev *mousedev,
+ unsigned int code, int value)
{
int size, tmp;
enum { FRACTION_DENOM = 128 };
switch (code) {
- case ABS_X:
- fx(0) = value;
- if (mousedev->touch && mousedev->pkt_count >= 2) {
- size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
- if (size == 0)
- size = 256 * 2;
- tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size;
- tmp += mousedev->frac_dx;
- mousedev->packet.dx = tmp / FRACTION_DENOM;
- mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM;
- }
- break;
- case ABS_Y:
- fy(0) = value;
- if (mousedev->touch && mousedev->pkt_count >= 2) {
- /* use X size to keep the same scale */
- size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
- if (size == 0)
- size = 256 * 2;
- tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size;
- tmp += mousedev->frac_dy;
- mousedev->packet.dy = tmp / FRACTION_DENOM;
- mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM;
- }
- break;
+ case ABS_X:
+ fx(0) = value;
+ if (mousedev->touch && mousedev->pkt_count >= 2) {
+ size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+ if (size == 0)
+ size = 256 * 2;
+ tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
+ tmp += mousedev->frac_dx;
+ mousedev->packet.dx = tmp / FRACTION_DENOM;
+ mousedev->frac_dx =
+ tmp - mousedev->packet.dx * FRACTION_DENOM;
+ }
+ break;
+
+ case ABS_Y:
+ fy(0) = value;
+ if (mousedev->touch && mousedev->pkt_count >= 2) {
+ /* use X size to keep the same scale */
+ size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+ if (size == 0)
+ size = 256 * 2;
+ tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
+ tmp += mousedev->frac_dy;
+ mousedev->packet.dy = tmp / FRACTION_DENOM;
+ mousedev->frac_dy = tmp -
+ mousedev->packet.dy * FRACTION_DENOM;
+ }
+ break;
}
}
-static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
+static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
+ unsigned int code, int value)
{
int size;
switch (code) {
- case ABS_X:
- size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
- if (size == 0)
- size = xres ? : 1;
- if (value > dev->absmax[ABS_X])
- value = dev->absmax[ABS_X];
- if (value < dev->absmin[ABS_X])
- value = dev->absmin[ABS_X];
- mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size;
- mousedev->packet.abs_event = 1;
- break;
- case ABS_Y:
- size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
- if (size == 0)
- size = yres ? : 1;
- if (value > dev->absmax[ABS_Y])
- value = dev->absmax[ABS_Y];
- if (value < dev->absmin[ABS_Y])
- value = dev->absmin[ABS_Y];
- mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size;
- mousedev->packet.abs_event = 1;
- break;
+ case ABS_X:
+ size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+ if (size == 0)
+ size = xres ? : 1;
+ if (value > dev->absmax[ABS_X])
+ value = dev->absmax[ABS_X];
+ if (value < dev->absmin[ABS_X])
+ value = dev->absmin[ABS_X];
+ mousedev->packet.x =
+ ((value - dev->absmin[ABS_X]) * xres) / size;
+ mousedev->packet.abs_event = 1;
+ break;
+
+ case ABS_Y:
+ size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
+ if (size == 0)
+ size = yres ? : 1;
+ if (value > dev->absmax[ABS_Y])
+ value = dev->absmax[ABS_Y];
+ if (value < dev->absmin[ABS_Y])
+ value = dev->absmin[ABS_Y];
+ mousedev->packet.y = yres -
+ ((value - dev->absmin[ABS_Y]) * yres) / size;
+ mousedev->packet.abs_event = 1;
+ break;
}
}
-static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
+static void mousedev_rel_event(struct mousedev *mousedev,
+ unsigned int code, int value)
{
switch (code) {
- case REL_X: mousedev->packet.dx += value; break;
- case REL_Y: mousedev->packet.dy -= value; break;
- case REL_WHEEL: mousedev->packet.dz -= value; break;
+ case REL_X:
+ mousedev->packet.dx += value;
+ break;
+
+ case REL_Y:
+ mousedev->packet.dy -= value;
+ break;
+
+ case REL_WHEEL:
+ mousedev->packet.dz -= value;
+ break;
}
}
-static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
+static void mousedev_key_event(struct mousedev *mousedev,
+ unsigned int code, int value)
{
int index;
switch (code) {
- case BTN_TOUCH:
- case BTN_0:
- case BTN_LEFT: index = 0; break;
- case BTN_STYLUS:
- case BTN_1:
- case BTN_RIGHT: index = 1; break;
- case BTN_2:
- case BTN_FORWARD:
- case BTN_STYLUS2:
- case BTN_MIDDLE: index = 2; break;
- case BTN_3:
- case BTN_BACK:
- case BTN_SIDE: index = 3; break;
- case BTN_4:
- case BTN_EXTRA: index = 4; break;
- default: return;
+
+ case BTN_TOUCH:
+ case BTN_0:
+ case BTN_LEFT: index = 0; break;
+
+ case BTN_STYLUS:
+ case BTN_1:
+ case BTN_RIGHT: index = 1; break;
+
+ case BTN_2:
+ case BTN_FORWARD:
+ case BTN_STYLUS2:
+ case BTN_MIDDLE: index = 2; break;
+
+ case BTN_3:
+ case BTN_BACK:
+ case BTN_SIDE: index = 3; break;
+
+ case BTN_4:
+ case BTN_EXTRA: index = 4; break;
+
+ default: return;
}
if (value) {
@@ -226,19 +257,23 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int
}
}
-static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet)
+static void mousedev_notify_readers(struct mousedev *mousedev,
+ struct mousedev_hw_data *packet)
{
struct mousedev_client *client;
struct mousedev_motion *p;
- unsigned long flags;
+ unsigned int new_head;
int wake_readers = 0;
- list_for_each_entry(client, &mousedev->client_list, node) {
- spin_lock_irqsave(&client->packet_lock, flags);
+ rcu_read_lock();
+ list_for_each_entry_rcu(client, &mousedev->client_list, node) {
+
+ /* Just acquire the lock, interrupts already disabled */
+ spin_lock(&client->packet_lock);
p = &client->packets[client->head];
if (client->ready && p->buttons != mousedev->packet.buttons) {
- unsigned int new_head = (client->head + 1) % PACKET_QUEUE_LEN;
+ new_head = (client->head + 1) % PACKET_QUEUE_LEN;
if (new_head != client->tail) {
p = &client->packets[client->head = new_head];
memset(p, 0, sizeof(struct mousedev_motion));
@@ -253,25 +288,29 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h
}
client->pos_x += packet->dx;
- client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x);
+ client->pos_x = client->pos_x < 0 ?
+ 0 : (client->pos_x >= xres ? xres : client->pos_x);
client->pos_y += packet->dy;
- client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y);
+ client->pos_y = client->pos_y < 0 ?
+ 0 : (client->pos_y >= yres ? yres : client->pos_y);
p->dx += packet->dx;
p->dy += packet->dy;
p->dz += packet->dz;
p->buttons = mousedev->packet.buttons;
- if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons)
+ if (p->dx || p->dy || p->dz ||
+ p->buttons != client->last_buttons)
client->ready = 1;
- spin_unlock_irqrestore(&client->packet_lock, flags);
+ spin_unlock(&client->packet_lock);
if (client->ready) {
kill_fasync(&client->fasync, SIGIO, POLL_IN);
wake_readers = 1;
}
}
+ rcu_read_unlock();
if (wake_readers)
wake_up_interruptible(&mousedev->wait);
@@ -281,7 +320,8 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
{
if (!value) {
if (mousedev->touch &&
- time_before(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) {
+ time_before(jiffies,
+ mousedev->touch + msecs_to_jiffies(tap_time))) {
/*
* Toggle left button to emulate tap.
* We rely on the fact that mousedev_mix always has 0
@@ -290,7 +330,8 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
set_bit(0, &mousedev->packet.buttons);
set_bit(0, &mousedev_mix->packet.buttons);
mousedev_notify_readers(mousedev, &mousedev_mix->packet);
- mousedev_notify_readers(mousedev_mix, &mousedev_mix->packet);
+ mousedev_notify_readers(mousedev_mix,
+ &mousedev_mix->packet);
clear_bit(0, &mousedev->packet.buttons);
clear_bit(0, &mousedev_mix->packet.buttons);
}
@@ -302,54 +343,61 @@ static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
mousedev->touch = jiffies;
}
-static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void mousedev_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
{
struct mousedev *mousedev = handle->private;
switch (type) {
- case EV_ABS:
- /* Ignore joysticks */
- if (test_bit(BTN_TRIGGER, handle->dev->keybit))
- return;
- if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
- mousedev_touchpad_event(handle->dev, mousedev, code, value);
- else
- mousedev_abs_event(handle->dev, mousedev, code, value);
+ case EV_ABS:
+ /* Ignore joysticks */
+ if (test_bit(BTN_TRIGGER, handle->dev->keybit))
+ return;
- break;
+ if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+ mousedev_touchpad_event(handle->dev,
+ mousedev, code, value);
+ else
+ mousedev_abs_event(handle->dev, mousedev, code, value);
- case EV_REL:
- mousedev_rel_event(mousedev, code, value);
- break;
+ break;
- case EV_KEY:
- if (value != 2) {
- if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
- mousedev_touchpad_touch(mousedev, value);
- else
- mousedev_key_event(mousedev, code, value);
- }
- break;
+ case EV_REL:
+ mousedev_rel_event(mousedev, code, value);
+ break;
- case EV_SYN:
- if (code == SYN_REPORT) {
- if (mousedev->touch) {
- mousedev->pkt_count++;
- /* Input system eats duplicate events, but we need all of them
- * to do correct averaging so apply present one forward
- */
- fx(0) = fx(1);
- fy(0) = fy(1);
- }
-
- mousedev_notify_readers(mousedev, &mousedev->packet);
- mousedev_notify_readers(mousedev_mix, &mousedev->packet);
-
- mousedev->packet.dx = mousedev->packet.dy = mousedev->packet.dz = 0;
- mousedev->packet.abs_event = 0;
+ case EV_KEY:
+ if (value != 2) {
+ if (code == BTN_TOUCH &&
+ test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+ mousedev_touchpad_touch(mousedev, value);
+ else
+ mousedev_key_event(mousedev, code, value);
+ }
+ break;
+
+ case EV_SYN:
+ if (code == SYN_REPORT) {
+ if (mousedev->touch) {
+ mousedev->pkt_count++;
+ /*
+ * Input system eats duplicate events,
+ * but we need all of them to do correct
+ * averaging so apply present one forward
+ */
+ fx(0) = fx(1);
+ fy(0) = fy(1);
}
- break;
+
+ mousedev_notify_readers(mousedev, &mousedev->packet);
+ mousedev_notify_readers(mousedev_mix, &mousedev->packet);
+
+ mousedev->packet.dx = mousedev->packet.dy =
+ mousedev->packet.dz = 0;
+ mousedev->packet.abs_event = 0;
+ }
+ break;
}
}
@@ -367,41 +415,48 @@ static void mousedev_free(struct device *dev)
{
struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
- mousedev_table[mousedev->minor] = NULL;
kfree(mousedev);
}
-static int mixdev_add_device(struct mousedev *mousedev)
+static int mousedev_open_device(struct mousedev *mousedev)
{
- int error;
+ int retval;
- if (mousedev_mix->open) {
- error = input_open_device(&mousedev->handle);
- if (error)
- return error;
+ retval = mutex_lock_interruptible(&mousedev->mutex);
+ if (retval)
+ return retval;
- mousedev->open++;
- mousedev->mixdev_open = 1;
+ if (mousedev->minor == MOUSEDEV_MIX)
+ mixdev_open_devices();
+ else if (!mousedev->exist)
+ retval = -ENODEV;
+ else if (!mousedev->open++) {
+ retval = input_open_device(&mousedev->handle);
+ if (retval)
+ mousedev->open--;
}
- get_device(&mousedev->dev);
- list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
-
- return 0;
+ mutex_unlock(&mousedev->mutex);
+ return retval;
}
-static void mixdev_remove_device(struct mousedev *mousedev)
+static void mousedev_close_device(struct mousedev *mousedev)
{
- if (mousedev->mixdev_open) {
- mousedev->mixdev_open = 0;
- if (!--mousedev->open && mousedev->exist)
- input_close_device(&mousedev->handle);
- }
+ mutex_lock(&mousedev->mutex);
- list_del_init(&mousedev->mixdev_node);
- put_device(&mousedev->dev);
+ if (mousedev->minor == MOUSEDEV_MIX)
+ mixdev_close_devices();
+ else if (mousedev->exist && !--mousedev->open)
+ input_close_device(&mousedev->handle);
+
+ mutex_unlock(&mousedev->mutex);
}
+/*
+ * Open all available devices so they can all be multiplexed in one.
+ * stream. Note that this function is called with mousedev_mix->mutex
+ * held.
+ */
static void mixdev_open_devices(void)
{
struct mousedev *mousedev;
@@ -411,16 +466,19 @@ static void mixdev_open_devices(void)
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
if (!mousedev->mixdev_open) {
- if (!mousedev->open && mousedev->exist)
- if (input_open_device(&mousedev->handle))
- continue;
+ if (mousedev_open_device(mousedev))
+ continue;
- mousedev->open++;
mousedev->mixdev_open = 1;
}
}
}
+/*
+ * Close all devices that were opened as part of multiplexed
+ * device. Note that this function is called with mousedev_mix->mutex
+ * held.
+ */
static void mixdev_close_devices(void)
{
struct mousedev *mousedev;
@@ -431,33 +489,45 @@ static void mixdev_close_devices(void)
list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) {
if (mousedev->mixdev_open) {
mousedev->mixdev_open = 0;
- if (!--mousedev->open && mousedev->exist)
- input_close_device(&mousedev->handle);
+ mousedev_close_device(mousedev);
}
}
}
+
+static void mousedev_attach_client(struct mousedev *mousedev,
+ struct mousedev_client *client)
+{
+ spin_lock(&mousedev->client_lock);
+ list_add_tail_rcu(&client->node, &mousedev->client_list);
+ spin_unlock(&mousedev->client_lock);
+ synchronize_rcu();
+}
+
+static void mousedev_detach_client(struct mousedev *mousedev,
+ struct mousedev_client *client)
+{
+ spin_lock(&mousedev->client_lock);
+ list_del_rcu(&client->node);
+ spin_unlock(&mousedev->client_lock);
+ synchronize_rcu();
+}
+
static int mousedev_release(struct inode *inode, struct file *file)
{
struct mousedev_client *client = file->private_data;
struct mousedev *mousedev = client->mousedev;
mousedev_fasync(-1, file, 0);
-
- list_del(&client->node);
+ mousedev_detach_client(mousedev, client);
kfree(client);
- if (mousedev->minor == MOUSEDEV_MIX)
- mixdev_close_devices();
- else if (!--mousedev->open && mousedev->exist)
- input_close_device(&mousedev->handle);
-
+ mousedev_close_device(mousedev);
put_device(&mousedev->dev);
return 0;
}
-
static int mousedev_open(struct inode *inode, struct file *file)
{
struct mousedev_client *client;
@@ -475,12 +545,17 @@ static int mousedev_open(struct inode *inode, struct file *file)
if (i >= MOUSEDEV_MINORS)
return -ENODEV;
+ error = mutex_lock_interruptible(&mousedev_table_mutex);
+ if (error)
+ return error;
mousedev = mousedev_table[i];
+ if (mousedev)
+ get_device(&mousedev->dev);
+ mutex_unlock(&mousedev_table_mutex);
+
if (!mousedev)
return -ENODEV;
- get_device(&mousedev->dev);
-
client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
if (!client) {
error = -ENOMEM;
@@ -491,21 +566,17 @@ static int mousedev_open(struct inode *inode, struct file *file)
client->pos_x = xres / 2;
client->pos_y = yres / 2;
client->mousedev = mousedev;
- list_add_tail(&client->node, &mousedev->client_list);
+ mousedev_attach_client(mousedev, client);
- if (mousedev->minor == MOUSEDEV_MIX)
- mixdev_open_devices();
- else if (!mousedev->open++ && mousedev->exist) {
- error = input_open_device(&mousedev->handle);
- if (error)
- goto err_free_client;
- }
+ error = mousedev_open_device(mousedev);
+ if (error)
+ goto err_free_client;
file->private_data = client;
return 0;
err_free_client:
- list_del(&client->node);
+ mousedev_detach_client(mousedev, client);
kfree(client);
err_put_mousedev:
put_device(&mousedev->dev);
@@ -517,41 +588,41 @@ static inline int mousedev_limit_delta(int delta, int limit)
return delta > limit ? limit : (delta < -limit ? -limit : delta);
}
-static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data)
+static void mousedev_packet(struct mousedev_client *client,
+ signed char *ps2_data)
{
- struct mousedev_motion *p;
- unsigned long flags;
-
- spin_lock_irqsave(&client->packet_lock, flags);
- p = &client->packets[client->tail];
+ struct mousedev_motion *p = &client->packets[client->tail];
- ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
+ ps2_data[0] = 0x08 |
+ ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07);
ps2_data[1] = mousedev_limit_delta(p->dx, 127);
ps2_data[2] = mousedev_limit_delta(p->dy, 127);
p->dx -= ps2_data[1];
p->dy -= ps2_data[2];
switch (client->mode) {
- case MOUSEDEV_EMUL_EXPS:
- ps2_data[3] = mousedev_limit_delta(p->dz, 7);
- p->dz -= ps2_data[3];
- ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
- client->bufsiz = 4;
- break;
-
- case MOUSEDEV_EMUL_IMPS:
- ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
- ps2_data[3] = mousedev_limit_delta(p->dz, 127);
- p->dz -= ps2_data[3];
- client->bufsiz = 4;
- break;
-
- case MOUSEDEV_EMUL_PS2:
- default:
- ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
- p->dz = 0;
- client->bufsiz = 3;
- break;
+ case MOUSEDEV_EMUL_EXPS:
+ ps2_data[3] = mousedev_limit_delta(p->dz, 7);
+ p->dz -= ps2_data[3];
+ ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1);
+ client->bufsiz = 4;
+ break;
+
+ case MOUSEDEV_EMUL_IMPS:
+ ps2_data[0] |=
+ ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
+ ps2_data[3] = mousedev_limit_delta(p->dz, 127);
+ p->dz -= ps2_data[3];
+ client->bufsiz = 4;
+ break;
+
+ case MOUSEDEV_EMUL_PS2:
+ default:
+ ps2_data[0] |=
+ ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1);
+ p->dz = 0;
+ client->bufsiz = 3;
+ break;
}
if (!p->dx && !p->dy && !p->dz) {
@@ -561,12 +632,56 @@ static void mousedev_packet(struct mousedev_client *client, signed char *ps2_dat
} else
client->tail = (client->tail + 1) % PACKET_QUEUE_LEN;
}
-
- spin_unlock_irqrestore(&client->packet_lock, flags);
}
+static void mousedev_generate_response(struct mousedev_client *client,
+ int command)
+{
+ client->ps2[0] = 0xfa; /* ACK */
+
+ switch (command) {
-static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+ case 0xeb: /* Poll */
+ mousedev_packet(client, &client->ps2[1]);
+ client->bufsiz++; /* account for leading ACK */
+ break;
+
+ case 0xf2: /* Get ID */
+ switch (client->mode) {
+ case MOUSEDEV_EMUL_PS2:
+ client->ps2[1] = 0;
+ break;
+ case MOUSEDEV_EMUL_IMPS:
+ client->ps2[1] = 3;
+ break;
+ case MOUSEDEV_EMUL_EXPS:
+ client->ps2[1] = 4;
+ break;
+ }
+ client->bufsiz = 2;
+ break;
+
+ case 0xe9: /* Get info */
+ client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
+ client->bufsiz = 4;
+ break;
+
+ case 0xff: /* Reset */
+ client->impsseq = client->imexseq = 0;
+ client->mode = MOUSEDEV_EMUL_PS2;
+ client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
+ client->bufsiz = 3;
+ break;
+
+ default:
+ client->bufsiz = 1;
+ break;
+ }
+ client->buffer = client->bufsiz;
+}
+
+static ssize_t mousedev_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct mousedev_client *client = file->private_data;
unsigned char c;
@@ -577,6 +692,8 @@ static ssize_t mousedev_write(struct file *file, const char __user *buffer, size
if (get_user(c, buffer + i))
return -EFAULT;
+ spin_lock_irq(&client->packet_lock);
+
if (c == mousedev_imex_seq[client->imexseq]) {
if (++client->imexseq == MOUSEDEV_SEQ_LEN) {
client->imexseq = 0;
@@ -593,68 +710,39 @@ static ssize_t mousedev_write(struct file *file, const char __user *buffer, size
} else
client->impsseq = 0;
- client->ps2[0] = 0xfa;
-
- switch (c) {
-
- case 0xeb: /* Poll */
- mousedev_packet(client, &client->ps2[1]);
- client->bufsiz++; /* account for leading ACK */
- break;
-
- case 0xf2: /* Get ID */
- switch (client->mode) {
- case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break;
- case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break;
- case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break;
- }
- client->bufsiz = 2;
- break;
-
- case 0xe9: /* Get info */
- client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200;
- client->bufsiz = 4;
- break;
-
- case 0xff: /* Reset */
- client->impsseq = client->imexseq = 0;
- client->mode = MOUSEDEV_EMUL_PS2;
- client->ps2[1] = 0xaa; client->ps2[2] = 0x00;
- client->bufsiz = 3;
- break;
-
- default:
- client->bufsiz = 1;
- break;
- }
+ mousedev_generate_response(client, c);
- client->buffer = client->bufsiz;
+ spin_unlock_irq(&client->packet_lock);
}
kill_fasync(&client->fasync, SIGIO, POLL_IN);
-
wake_up_interruptible(&client->mousedev->wait);
return count;
}
-static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+static ssize_t mousedev_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct mousedev_client *client = file->private_data;
+ struct mousedev *mousedev = client->mousedev;
+ signed char data[sizeof(client->ps2)];
int retval = 0;
- if (!client->ready && !client->buffer && (file->f_flags & O_NONBLOCK))
+ if (!client->ready && !client->buffer && mousedev->exist &&
+ (file->f_flags & O_NONBLOCK))
return -EAGAIN;
- retval = wait_event_interruptible(client->mousedev->wait,
- !client->mousedev->exist || client->ready || client->buffer);
-
+ retval = wait_event_interruptible(mousedev->wait,
+ !mousedev->exist || client->ready || client->buffer);
if (retval)
return retval;
- if (!client->mousedev->exist)
+ if (!mousedev->exist)
return -ENODEV;
+ spin_lock_irq(&client->packet_lock);
+
if (!client->buffer && client->ready) {
mousedev_packet(client, client->ps2);
client->buffer = client->bufsiz;
@@ -663,9 +751,12 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t coun
if (count > client->buffer)
count = client->buffer;
+ memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
client->buffer -= count;
- if (copy_to_user(buffer, client->ps2 + client->bufsiz - client->buffer - count, count))
+ spin_unlock_irq(&client->packet_lock);
+
+ if (copy_to_user(buffer, data, count))
return -EFAULT;
return count;
@@ -692,6 +783,60 @@ static const struct file_operations mousedev_fops = {
.fasync = mousedev_fasync,
};
+static int mousedev_install_chrdev(struct mousedev *mousedev)
+{
+ mousedev_table[mousedev->minor] = mousedev;
+ return 0;
+}
+
+static void mousedev_remove_chrdev(struct mousedev *mousedev)
+{
+ mutex_lock(&mousedev_table_mutex);
+ mousedev_table[mousedev->minor] = NULL;
+ mutex_unlock(&mousedev_table_mutex);
+}
+
+/*
+ * Mark device non-existent. This disables writes, ioctls and
+ * prevents new users from opening the device. Already posted
+ * blocking reads will stay, however new ones will fail.
+ */
+static void mousedev_mark_dead(struct mousedev *mousedev)
+{
+ mutex_lock(&mousedev->mutex);
+ mousedev->exist = 0;
+ mutex_unlock(&mousedev->mutex);
+}
+
+/*
+ * Wake up users waiting for IO so they can disconnect from
+ * dead device.
+ */
+static void mousedev_hangup(struct mousedev *mousedev)
+{
+ struct mousedev_client *client;
+
+ spin_lock(&mousedev->client_lock);
+ list_for_each_entry(client, &mousedev->client_list, node)
+ kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ spin_unlock(&mousedev->client_lock);
+
+ wake_up_interruptible(&mousedev->wait);
+}
+
+static void mousedev_cleanup(struct mousedev *mousedev)
+{
+ struct input_handle *handle = &mousedev->handle;
+
+ mousedev_mark_dead(mousedev);
+ mousedev_hangup(mousedev);
+ mousedev_remove_chrdev(mousedev);
+
+ /* mousedev is marked dead so no one else accesses mousedev->open */
+ if (mousedev->open)
+ input_close_device(handle);
+}
+
static struct mousedev *mousedev_create(struct input_dev *dev,
struct input_handler *handler,
int minor)
@@ -707,6 +852,10 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
INIT_LIST_HEAD(&mousedev->client_list);
INIT_LIST_HEAD(&mousedev->mixdev_node);
+ spin_lock_init(&mousedev->client_lock);
+ mutex_init(&mousedev->mutex);
+ lockdep_set_subclass(&mousedev->mutex,
+ minor == MOUSEDEV_MIX ? MOUSEDEV_MIX : 0);
init_waitqueue_head(&mousedev->wait);
if (minor == MOUSEDEV_MIX)
@@ -731,14 +880,27 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
mousedev->dev.release = mousedev_free;
device_initialize(&mousedev->dev);
- mousedev_table[minor] = mousedev;
+ if (minor != MOUSEDEV_MIX) {
+ error = input_register_handle(&mousedev->handle);
+ if (error)
+ goto err_free_mousedev;
+ }
+
+ error = mousedev_install_chrdev(mousedev);
+ if (error)
+ goto err_unregister_handle;
error = device_add(&mousedev->dev);
if (error)
- goto err_free_mousedev;
+ goto err_cleanup_mousedev;
return mousedev;
+ err_cleanup_mousedev:
+ mousedev_cleanup(mousedev);
+ err_unregister_handle:
+ if (minor != MOUSEDEV_MIX)
+ input_unregister_handle(&mousedev->handle);
err_free_mousedev:
put_device(&mousedev->dev);
err_out:
@@ -747,29 +909,64 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
static void mousedev_destroy(struct mousedev *mousedev)
{
- struct mousedev_client *client;
-
device_del(&mousedev->dev);
- mousedev->exist = 0;
+ mousedev_cleanup(mousedev);
+ if (mousedev->minor != MOUSEDEV_MIX)
+ input_unregister_handle(&mousedev->handle);
+ put_device(&mousedev->dev);
+}
- if (mousedev->open) {
- input_close_device(&mousedev->handle);
- list_for_each_entry(client, &mousedev->client_list, node)
- kill_fasync(&client->fasync, SIGIO, POLL_HUP);
- wake_up_interruptible(&mousedev->wait);
+static int mixdev_add_device(struct mousedev *mousedev)
+{
+ int retval;
+
+ retval = mutex_lock_interruptible(&mousedev_mix->mutex);
+ if (retval)
+ return retval;
+
+ if (mousedev_mix->open) {
+ retval = mousedev_open_device(mousedev);
+ if (retval)
+ goto out;
+
+ mousedev->mixdev_open = 1;
}
+ get_device(&mousedev->dev);
+ list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list);
+
+ out:
+ mutex_unlock(&mousedev_mix->mutex);
+ return retval;
+}
+
+static void mixdev_remove_device(struct mousedev *mousedev)
+{
+ mutex_lock(&mousedev_mix->mutex);
+
+ if (mousedev->mixdev_open) {
+ mousedev->mixdev_open = 0;
+ mousedev_close_device(mousedev);
+ }
+
+ list_del_init(&mousedev->mixdev_node);
+ mutex_unlock(&mousedev_mix->mutex);
+
put_device(&mousedev->dev);
}
-static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
+static int mousedev_connect(struct input_handler *handler,
+ struct input_dev *dev,
const struct input_device_id *id)
{
struct mousedev *mousedev;
int minor;
int error;
- for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
+ for (minor = 0; minor < MOUSEDEV_MINORS; minor++)
+ if (!mousedev_table[minor])
+ break;
+
if (minor == MOUSEDEV_MINORS) {
printk(KERN_ERR "mousedev: no more free mousedev devices\n");
return -ENFILE;
@@ -779,21 +976,13 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev
if (IS_ERR(mousedev))
return PTR_ERR(mousedev);
- error = input_register_handle(&mousedev->handle);
- if (error)
- goto err_delete_mousedev;
-
error = mixdev_add_device(mousedev);
- if (error)
- goto err_unregister_handle;
+ if (error) {
+ mousedev_destroy(mousedev);
+ return error;
+ }
return 0;
-
- err_unregister_handle:
- input_unregister_handle(&mousedev->handle);
- err_delete_mousedev:
- device_unregister(&mousedev->dev);
- return error;
}
static void mousedev_disconnect(struct input_handle *handle)
@@ -801,33 +990,42 @@ static void mousedev_disconnect(struct input_handle *handle)
struct mousedev *mousedev = handle->private;
mixdev_remove_device(mousedev);
- input_unregister_handle(handle);
mousedev_destroy(mousedev);
}
static const struct input_device_id mousedev_ids[] = {
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
+ .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) },
- }, /* A mouse like device, at least one button, two relative axes */
+ }, /* A mouse like device, at least one button,
+ two relative axes */
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_RELBIT,
.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
.relbit = { BIT(REL_WHEEL) },
}, /* A separate scrollwheel */
{
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .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) },
- }, /* A tablet like device, at least touch detection, two absolute axes */
+ }, /* 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,
+ .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) },
+ .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
+ BIT(ABS_TOOL_WIDTH) },
}, /* A touchpad */
{ }, /* Terminating entry */
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c2eea2767e1..11dafc0ee99 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -385,6 +385,8 @@ static int i8042_enable_kbd_port(void)
i8042_ctr |= I8042_CTR_KBDINT;
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ i8042_ctr &= ~I8042_CTR_KBDINT;
+ i8042_ctr |= I8042_CTR_KBDDIS;
printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n");
return -EIO;
}
@@ -402,6 +404,8 @@ static int i8042_enable_aux_port(void)
i8042_ctr |= I8042_CTR_AUXINT;
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ i8042_ctr &= ~I8042_CTR_AUXINT;
+ i8042_ctr |= I8042_CTR_AUXDIS;
printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n");
return -EIO;
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index b3bc15acd3f..7f5293828fb 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -387,9 +387,8 @@ static int serio_thread(void *nothing)
set_freezable();
do {
serio_handle_event();
- wait_event_interruptible(serio_wait,
+ wait_event_freezable(serio_wait,
kthread_should_stop() || !list_empty(&serio_event_list));
- try_to_freeze();
} while (!kthread_should_stop());
printk(KERN_DEBUG "serio: kseriod exiting\n");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index f929fcdbae2..e3e0baa1a15 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -126,6 +126,16 @@ config TOUCHSCREEN_HP600
To compile this driver as a module, choose M here: the
module will be called hp680_ts_input.
+config TOUCHSCREEN_HP7XX
+ tristate "HP Jornada 710/720/728 touchscreen"
+ depends on SA1100_JORNADA720_SSP
+ help
+ Say Y here if you have a HP Jornada 710/720/728 and want
+ to support the built-in touchscreen.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jornada720_ts.
+
config TOUCHSCREEN_PENMOUNT
tristate "Penmount serial touchscreen"
select SERIO
@@ -191,6 +201,7 @@ config TOUCHSCREEN_USB_COMPOSITE
- Gunze AHL61
- DMC TSC-10/25
- IRTOUCHSYSTEMS/UNITOP
+ - IdealTEK URTC1000
Have a look at <http://linux.chapter7.ch/touchkit/> for
a usage description and the required user-space stuff.
@@ -238,4 +249,14 @@ config TOUCHSCREEN_USB_IRTOUCH
bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED
depends on TOUCHSCREEN_USB_COMPOSITE
+config TOUCHSCREEN_USB_IDEALTEK
+ default y
+ bool "IdealTEK URTC1000 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_GENERAL_TOUCH
+ default y
+ bool "GeneralTouch Touchscreen device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 5de8933c499..35d4097df35 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c
new file mode 100644
index 00000000000..42a1c9a1940
--- /dev/null
+++ b/drivers/input/touchscreen/jornada720_ts.c
@@ -0,0 +1,182 @@
+/*
+ * drivers/input/touchscreen/jornada720_ts.c
+ *
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ *
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ * based on HP Jornada 56x touchscreen driver by Alex Lange <chicken@handhelds.org>
+ *
+ * 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.
+ *
+ * HP Jornada 710/720/729 Touchscreen Driver
+ */
+
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/jornada720.h>
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 touchscreen driver");
+MODULE_LICENSE("GPLv2");
+
+struct jornada_ts {
+ struct input_dev *dev;
+ int x_data[4]; /* X sample values */
+ int y_data[4]; /* Y sample values */
+};
+
+static void jornada720_ts_collect_data(struct jornada_ts *jornada_ts)
+{
+
+ /* 3 low word X samples */
+ jornada_ts->x_data[0] = jornada_ssp_byte(TXDUMMY);
+ jornada_ts->x_data[1] = jornada_ssp_byte(TXDUMMY);
+ jornada_ts->x_data[2] = jornada_ssp_byte(TXDUMMY);
+
+ /* 3 low word Y samples */
+ jornada_ts->y_data[0] = jornada_ssp_byte(TXDUMMY);
+ jornada_ts->y_data[1] = jornada_ssp_byte(TXDUMMY);
+ jornada_ts->y_data[2] = jornada_ssp_byte(TXDUMMY);
+
+ /* combined x samples bits */
+ jornada_ts->x_data[3] = jornada_ssp_byte(TXDUMMY);
+
+ /* combined y samples bits */
+ jornada_ts->y_data[3] = jornada_ssp_byte(TXDUMMY);
+}
+
+static int jornada720_ts_average(int coords[4])
+{
+ int coord, high_bits = coords[3];
+
+ coord = coords[0] | ((high_bits & 0x03) << 8);
+ coord += coords[1] | ((high_bits & 0x0c) << 6);
+ coord += coords[2] | ((high_bits & 0x30) << 4);
+
+ return coord / 3;
+}
+
+static irqreturn_t jornada720_ts_interrupt(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
+ struct input_dev *input = jornada_ts->dev;
+ int x, y;
+
+ /* If GPIO_GPIO9 is set to high then report pen up */
+ if (GPLR & GPIO_GPIO(9)) {
+ input_report_key(input, BTN_TOUCH, 0);
+ input_sync(input);
+ } else {
+ jornada_ssp_start();
+
+ /* proper reply to request is always TXDUMMY */
+ if (jornada_ssp_inout(GETTOUCHSAMPLES) == TXDUMMY) {
+ jornada720_ts_collect_data(jornada_ts);
+
+ x = jornada720_ts_average(jornada_ts->x_data);
+ y = jornada720_ts_average(jornada_ts->y_data);
+
+ input_report_key(input, BTN_TOUCH, 1);
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+ input_sync(input);
+ }
+
+ jornada_ssp_end();
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit jornada720_ts_probe(struct platform_device *pdev)
+{
+ struct jornada_ts *jornada_ts;
+ struct input_dev *input_dev;
+ int error;
+
+ jornada_ts = kzalloc(sizeof(struct jornada_ts), GFP_KERNEL);
+ input_dev = input_allocate_device();
+
+ if (!jornada_ts || !input_dev) {
+ error = -ENOMEM;
+ goto fail1;
+ }
+
+ platform_set_drvdata(pdev, jornada_ts);
+
+ jornada_ts->dev = input_dev;
+
+ input_dev->name = "HP Jornada 7xx Touchscreen";
+ input_dev->phys = "jornadats/input0";
+ input_dev->id.bustype = BUS_HOST;
+ 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_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0);
+
+ error = request_irq(IRQ_GPIO9,
+ jornada720_ts_interrupt,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
+ "HP7XX Touchscreen driver", pdev);
+ if (error) {
+ printk(KERN_INFO "HP7XX TS : Unable to acquire irq!\n");
+ goto fail1;
+ }
+
+ error = input_register_device(jornada_ts->dev);
+ if (error)
+ goto fail2;
+
+ return 0;
+
+ fail2:
+ free_irq(IRQ_GPIO9, pdev);
+ fail1:
+ platform_set_drvdata(pdev, NULL);
+ input_free_device(input_dev);
+ kfree(jornada_ts);
+ return error;
+}
+
+static int __devexit jornada720_ts_remove(struct platform_device *pdev)
+{
+ struct jornada_ts *jornada_ts = platform_get_drvdata(pdev);
+
+ free_irq(IRQ_GPIO9, pdev);
+ platform_set_drvdata(pdev, NULL);
+ input_unregister_device(jornada_ts->dev);
+ kfree(jornada_ts);
+
+ return 0;
+}
+
+static struct platform_driver jornada720_ts_driver = {
+ .probe = jornada720_ts_probe,
+ .remove = __devexit_p(jornada720_ts_remove),
+ .driver = {
+ .name = "jornada_ts",
+ },
+};
+
+static int __init jornada720_ts_init(void)
+{
+ return platform_driver_register(&jornada720_ts_driver);
+}
+
+static void __exit jornada720_ts_exit(void)
+{
+ platform_driver_unregister(&jornada720_ts_driver);
+}
+
+module_init(jornada720_ts_init);
+module_exit(jornada720_ts_exit);
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 36f94401915..89373b01d8f 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -130,8 +130,7 @@ static unsigned int ucb1400_adc_read(struct ucb1400 *ucb, u16 adc_channel)
if (val & UCB_ADC_DAT_VALID)
break;
/* yield to other processes */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
}
return UCB_ADC_DAT_VALUE(val);
@@ -334,10 +333,9 @@ static int ucb1400_ts_thread(void *_ucb)
timeout = msecs_to_jiffies(10);
}
- wait_event_interruptible_timeout(ucb->ts_wait,
+ wait_event_freezable_timeout(ucb->ts_wait,
ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
timeout);
- try_to_freeze();
}
/* Send the "pen off" if we are stopping with the pen still active */
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 741f6c6f1e5..9fb3d5c3099 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -10,6 +10,7 @@
* - Gunze AHL61
* - DMC TSC-10/25
* - IRTOUCHSYSTEMS/UNITOP
+ * - IdealTEK URTC1000
*
* Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
* Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -92,7 +93,7 @@ struct usbtouch_usb {
};
-#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO)
+#if defined(CONFIG_TOUCHSCREEN_USB_EGALAX) || defined(CONFIG_TOUCHSCREEN_USB_ETURBO) || defined(CONFIG_TOUCHSCREEN_USB_IDEALTEK)
#define MULTI_PACKET
#endif
@@ -112,6 +113,8 @@ enum {
DEVTYPE_GUNZE,
DEVTYPE_DMC_TSC10,
DEVTYPE_IRTOUCH,
+ DEVTYPE_IDEALTEK,
+ DEVTYPE_GENERAL_TOUCH,
};
static struct usb_device_id usbtouch_devices[] = {
@@ -157,6 +160,14 @@ static struct usb_device_id usbtouch_devices[] = {
{USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
#endif
+#ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+ {USB_DEVICE(0x1391, 0x1000), .driver_info = DEVTYPE_IDEALTEK},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
+ {USB_DEVICE(0x0dfc, 0x0001), .driver_info = DEVTYPE_GENERAL_TOUCH},
+#endif
+
{}
};
@@ -396,7 +407,8 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
if (ret < 0)
return ret;
- if (buf[0] != 0x06 || buf[1] != 0x00)
+ if ((buf[0] != 0x06 || buf[1] != 0x00) &&
+ (buf[0] != 0x15 || buf[1] != 0x01))
return -ENODEV;
/* start sending data */
@@ -438,6 +450,57 @@ static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
/*****************************************************************************
+ * IdealTEK URTC1000 Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+static int idealtek_get_pkt_len(unsigned char *buf, int len)
+{
+ if (buf[0] & 0x80)
+ return 5;
+ if (buf[0] == 0x01)
+ return len;
+ return 0;
+}
+
+static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+ switch (pkt[0] & 0x98) {
+ case 0x88:
+ /* touch data in IdealTEK mode */
+ dev->x = (pkt[1] << 5) | (pkt[2] >> 2);
+ dev->y = (pkt[3] << 5) | (pkt[4] >> 2);
+ dev->touch = (pkt[0] & 0x40) ? 1 : 0;
+ return 1;
+
+ case 0x98:
+ /* touch data in MT emulation mode */
+ dev->x = (pkt[2] << 5) | (pkt[1] >> 2);
+ dev->y = (pkt[4] << 5) | (pkt[3] >> 2);
+ dev->touch = (pkt[0] & 0x40) ? 1 : 0;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * General Touch Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
+static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+ dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ;
+ dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ;
+ dev->press = pkt[5] & 0xff;
+ dev->touch = pkt[0] & 0x01;
+
+ return 1;
+}
+#endif
+
+/*****************************************************************************
* the different device descriptors
*/
static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -537,6 +600,32 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.read_data = irtouch_read_data,
},
#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK
+ [DEVTYPE_IDEALTEK] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .rept_size = 8,
+ .flags = USBTOUCH_FLG_BUFFER,
+ .process_pkt = usbtouch_process_multi,
+ .get_pkt_len = idealtek_get_pkt_len,
+ .read_data = idealtek_read_data,
+ },
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
+ [DEVTYPE_GENERAL_TOUCH] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0500,
+ .min_yc = 0x0,
+ .max_yc = 0x0500,
+ .rept_size = 7,
+ .read_data = general_touch_read_data,
+ }
+#endif
+
};
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
deleted file mode 100644
index d2f882e98e5..00000000000
--- a/drivers/input/tsdev.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * $Id: tsdev.c,v 1.15 2002/04/10 16:50:19 jsimmons Exp $
- *
- * Copyright (c) 2001 "Crazy" james Simmons
- *
- * Compaq touchscreen protocol driver. The protocol emulated by this driver
- * is obsolete; for new programs use the tslib library which can read directly
- * from evdev and perform dejittering, variance filtering and calibration -
- * all in user space, not at kernel level. The meaning of this driver is
- * to allow usage of newer input drivers with old applications that use the
- * old /dev/h3600_ts and /dev/h3600_tsraw devices.
- *
- * 09-Apr-2004: Andrew Zabolotny <zap@homelink.ru>
- * Fixed to actually work, not just output random numbers.
- * Added support for both h3600_ts and h3600_tsraw protocol
- * emulation.
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <jsimmons@infradead.org>.
- */
-
-#define TSDEV_MINOR_BASE 128
-#define TSDEV_MINORS 32
-/* First 16 devices are h3600_ts compatible; second 16 are h3600_tsraw */
-#define TSDEV_MINOR_MASK 15
-#define TSDEV_BUFFER_SIZE 64
-
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/major.h>
-#include <linux/random.h>
-#include <linux/time.h>
-#include <linux/device.h>
-
-#ifndef CONFIG_INPUT_TSDEV_SCREEN_X
-#define CONFIG_INPUT_TSDEV_SCREEN_X 240
-#endif
-#ifndef CONFIG_INPUT_TSDEV_SCREEN_Y
-#define CONFIG_INPUT_TSDEV_SCREEN_Y 320
-#endif
-
-/* This driver emulates both protocols of the old h3600_ts and h3600_tsraw
- * devices. The first one must output X/Y data in 'cooked' format, e.g.
- * filtered, dejittered and calibrated. Second device just outputs raw
- * data received from the hardware.
- *
- * This driver doesn't support filtering and dejittering; it supports only
- * calibration. Filtering and dejittering must be done in the low-level
- * driver, if needed, because it may gain additional benefits from knowing
- * the low-level details, the nature of noise and so on.
- *
- * The driver precomputes a calibration matrix given the initial xres and
- * yres values (quite innacurate for most touchscreens) that will result
- * in a more or less expected range of output values. The driver supports
- * the TS_SET_CAL ioctl, which will replace the calibration matrix with a
- * new one, supposedly generated from the values taken from the raw device.
- */
-
-MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
-MODULE_DESCRIPTION("Input driver to touchscreen converter");
-MODULE_LICENSE("GPL");
-
-static int xres = CONFIG_INPUT_TSDEV_SCREEN_X;
-module_param(xres, uint, 0);
-MODULE_PARM_DESC(xres, "Horizontal screen resolution (can be negative for X-mirror)");
-
-static int yres = CONFIG_INPUT_TSDEV_SCREEN_Y;
-module_param(yres, uint, 0);
-MODULE_PARM_DESC(yres, "Vertical screen resolution (can be negative for Y-mirror)");
-
-/* From Compaq's Touch Screen Specification version 0.2 (draft) */
-struct ts_event {
- short pressure;
- short x;
- short y;
- short millisecs;
-};
-
-struct ts_calibration {
- int xscale;
- int xtrans;
- int yscale;
- int ytrans;
- int xyswap;
-};
-
-struct tsdev {
- int exist;
- int open;
- int minor;
- char name[8];
- struct input_handle handle;
- wait_queue_head_t wait;
- struct list_head client_list;
- struct device dev;
-
- int x, y, pressure;
- struct ts_calibration cal;
-};
-
-struct tsdev_client {
- struct fasync_struct *fasync;
- struct list_head node;
- struct tsdev *tsdev;
- int head, tail;
- struct ts_event event[TSDEV_BUFFER_SIZE];
- int raw;
-};
-
-/* The following ioctl codes are defined ONLY for backward compatibility.
- * Don't use tsdev for new developement; use the tslib library instead.
- * Touchscreen calibration is a fully userspace task.
- */
-/* Use 'f' as magic number */
-#define IOC_H3600_TS_MAGIC 'f'
-#define TS_GET_CAL _IOR(IOC_H3600_TS_MAGIC, 10, struct ts_calibration)
-#define TS_SET_CAL _IOW(IOC_H3600_TS_MAGIC, 11, struct ts_calibration)
-
-static struct tsdev *tsdev_table[TSDEV_MINORS/2];
-
-static int tsdev_fasync(int fd, struct file *file, int on)
-{
- struct tsdev_client *client = file->private_data;
- int retval;
-
- retval = fasync_helper(fd, file, on, &client->fasync);
- return retval < 0 ? retval : 0;
-}
-
-static int tsdev_open(struct inode *inode, struct file *file)
-{
- int i = iminor(inode) - TSDEV_MINOR_BASE;
- struct tsdev_client *client;
- struct tsdev *tsdev;
- int error;
-
- printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled "
- "for removal.\nSee Documentation/feature-removal-schedule.txt "
- "for details.\n");
-
- if (i >= TSDEV_MINORS)
- return -ENODEV;
-
- tsdev = tsdev_table[i & TSDEV_MINOR_MASK];
- if (!tsdev || !tsdev->exist)
- return -ENODEV;
-
- get_device(&tsdev->dev);
-
- client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL);
- if (!client) {
- error = -ENOMEM;
- goto err_put_tsdev;
- }
-
- client->tsdev = tsdev;
- client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0;
- list_add_tail(&client->node, &tsdev->client_list);
-
- if (!tsdev->open++ && tsdev->exist) {
- error = input_open_device(&tsdev->handle);
- if (error)
- goto err_free_client;
- }
-
- file->private_data = client;
- return 0;
-
- err_free_client:
- list_del(&client->node);
- kfree(client);
- err_put_tsdev:
- put_device(&tsdev->dev);
- return error;
-}
-
-static void tsdev_free(struct device *dev)
-{
- struct tsdev *tsdev = container_of(dev, struct tsdev, dev);
-
- tsdev_table[tsdev->minor] = NULL;
- kfree(tsdev);
-}
-
-static int tsdev_release(struct inode *inode, struct file *file)
-{
- struct tsdev_client *client = file->private_data;
- struct tsdev *tsdev = client->tsdev;
-
- tsdev_fasync(-1, file, 0);
-
- list_del(&client->node);
- kfree(client);
-
- if (!--tsdev->open && tsdev->exist)
- input_close_device(&tsdev->handle);
-
- put_device(&tsdev->dev);
-
- return 0;
-}
-
-static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count,
- loff_t *ppos)
-{
- struct tsdev_client *client = file->private_data;
- struct tsdev *tsdev = client->tsdev;
- int retval = 0;
-
- if (client->head == client->tail && tsdev->exist && (file->f_flags & O_NONBLOCK))
- return -EAGAIN;
-
- retval = wait_event_interruptible(tsdev->wait,
- client->head != client->tail || !tsdev->exist);
- if (retval)
- return retval;
-
- if (!tsdev->exist)
- return -ENODEV;
-
- while (client->head != client->tail &&
- retval + sizeof (struct ts_event) <= count) {
- if (copy_to_user (buffer + retval, client->event + client->tail,
- sizeof (struct ts_event)))
- return -EFAULT;
- client->tail = (client->tail + 1) & (TSDEV_BUFFER_SIZE - 1);
- retval += sizeof (struct ts_event);
- }
-
- return retval;
-}
-
-/* No kernel lock - fine */
-static unsigned int tsdev_poll(struct file *file, poll_table *wait)
-{
- struct tsdev_client *client = file->private_data;
- struct tsdev *tsdev = client->tsdev;
-
- poll_wait(file, &tsdev->wait, wait);
- return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) |
- (tsdev->exist ? 0 : (POLLHUP | POLLERR));
-}
-
-static int tsdev_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct tsdev_client *client = file->private_data;
- struct tsdev *tsdev = client->tsdev;
- int retval = 0;
-
- switch (cmd) {
- case TS_GET_CAL:
- if (copy_to_user((void __user *)arg, &tsdev->cal,
- sizeof (struct ts_calibration)))
- retval = -EFAULT;
- break;
-
- case TS_SET_CAL:
- if (copy_from_user(&tsdev->cal, (void __user *)arg,
- sizeof (struct ts_calibration)))
- retval = -EFAULT;
- break;
-
- default:
- retval = -EINVAL;
- break;
- }
-
- return retval;
-}
-
-static const struct file_operations tsdev_fops = {
- .owner = THIS_MODULE,
- .open = tsdev_open,
- .release = tsdev_release,
- .read = tsdev_read,
- .poll = tsdev_poll,
- .fasync = tsdev_fasync,
- .ioctl = tsdev_ioctl,
-};
-
-static void tsdev_event(struct input_handle *handle, unsigned int type,
- unsigned int code, int value)
-{
- struct tsdev *tsdev = handle->private;
- struct tsdev_client *client;
- struct timeval time;
-
- switch (type) {
- case EV_ABS:
- switch (code) {
- case ABS_X:
- tsdev->x = value;
- break;
-
- case ABS_Y:
- tsdev->y = value;
- break;
-
- case ABS_PRESSURE:
- if (value > handle->dev->absmax[ABS_PRESSURE])
- value = handle->dev->absmax[ABS_PRESSURE];
- value -= handle->dev->absmin[ABS_PRESSURE];
- if (value < 0)
- value = 0;
- tsdev->pressure = value;
- break;
- }
- break;
-
- case EV_REL:
- switch (code) {
- case REL_X:
- tsdev->x += value;
- if (tsdev->x < 0)
- tsdev->x = 0;
- else if (tsdev->x > xres)
- tsdev->x = xres;
- break;
-
- case REL_Y:
- tsdev->y += value;
- if (tsdev->y < 0)
- tsdev->y = 0;
- else if (tsdev->y > yres)
- tsdev->y = yres;
- break;
- }
- break;
-
- case EV_KEY:
- if (code == BTN_TOUCH || code == BTN_MOUSE) {
- switch (value) {
- case 0:
- tsdev->pressure = 0;
- break;
-
- case 1:
- if (!tsdev->pressure)
- tsdev->pressure = 1;
- break;
- }
- }
- break;
- }
-
- if (type != EV_SYN || code != SYN_REPORT)
- return;
-
- list_for_each_entry(client, &tsdev->client_list, node) {
- int x, y, tmp;
-
- do_gettimeofday(&time);
- client->event[client->head].millisecs = time.tv_usec / 1000;
- client->event[client->head].pressure = tsdev->pressure;
-
- x = tsdev->x;
- y = tsdev->y;
-
- /* Calibration */
- if (!client->raw) {
- x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans;
- y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans;
- if (tsdev->cal.xyswap) {
- tmp = x; x = y; y = tmp;
- }
- }
-
- client->event[client->head].x = x;
- client->event[client->head].y = y;
- client->head = (client->head + 1) & (TSDEV_BUFFER_SIZE - 1);
- kill_fasync(&client->fasync, SIGIO, POLL_IN);
- }
- wake_up_interruptible(&tsdev->wait);
-}
-
-static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
- const struct input_device_id *id)
-{
- struct tsdev *tsdev;
- int minor, delta;
- int error;
-
- for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++);
- if (minor >= TSDEV_MINORS / 2) {
- printk(KERN_ERR
- "tsdev: You have way too many touchscreens\n");
- return -ENFILE;
- }
-
- tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL);
- if (!tsdev)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&tsdev->client_list);
- init_waitqueue_head(&tsdev->wait);
-
- tsdev->exist = 1;
- tsdev->minor = minor;
- tsdev->handle.dev = dev;
- tsdev->handle.name = tsdev->name;
- tsdev->handle.handler = handler;
- tsdev->handle.private = tsdev;
- snprintf(tsdev->name, sizeof(tsdev->name), "ts%d", minor);
-
- /* Precompute the rough calibration matrix */
- delta = dev->absmax [ABS_X] - dev->absmin [ABS_X] + 1;
- if (delta == 0)
- delta = 1;
- tsdev->cal.xscale = (xres << 8) / delta;
- tsdev->cal.xtrans = - ((dev->absmin [ABS_X] * tsdev->cal.xscale) >> 8);
-
- delta = dev->absmax [ABS_Y] - dev->absmin [ABS_Y] + 1;
- if (delta == 0)
- delta = 1;
- tsdev->cal.yscale = (yres << 8) / delta;
- tsdev->cal.ytrans = - ((dev->absmin [ABS_Y] * tsdev->cal.yscale) >> 8);
-
- snprintf(tsdev->dev.bus_id, sizeof(tsdev->dev.bus_id),
- "ts%d", minor);
- tsdev->dev.class = &input_class;
- tsdev->dev.parent = &dev->dev;
- tsdev->dev.devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor);
- tsdev->dev.release = tsdev_free;
- device_initialize(&tsdev->dev);
-
- tsdev_table[minor] = tsdev;
-
- error = device_add(&tsdev->dev);
- if (error)
- goto err_free_tsdev;
-
- error = input_register_handle(&tsdev->handle);
- if (error)
- goto err_delete_tsdev;
-
- return 0;
-
- err_delete_tsdev:
- device_del(&tsdev->dev);
- err_free_tsdev:
- put_device(&tsdev->dev);
- return error;
-}
-
-static void tsdev_disconnect(struct input_handle *handle)
-{
- struct tsdev *tsdev = handle->private;
- struct tsdev_client *client;
-
- input_unregister_handle(handle);
- device_del(&tsdev->dev);
-
- tsdev->exist = 0;
-
- if (tsdev->open) {
- input_close_device(handle);
- list_for_each_entry(client, &tsdev->client_list, node)
- kill_fasync(&client->fasync, SIGIO, POLL_HUP);
- wake_up_interruptible(&tsdev->wait);
- }
-
- put_device(&tsdev->dev);
-}
-
-static const struct input_device_id tsdev_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) },
- }, /* A mouse like device, at least one button, two relative 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_TOUCH)] = BIT(BTN_TOUCH) },
- .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
- }, /* A tablet like device, at least touch detection, two absolute axes */
-
- {
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT(EV_ABS) },
- .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
- }, /* A tablet like device with several gradations of pressure */
-
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(input, tsdev_ids);
-
-static struct input_handler tsdev_handler = {
- .event = tsdev_event,
- .connect = tsdev_connect,
- .disconnect = tsdev_disconnect,
- .fops = &tsdev_fops,
- .minor = TSDEV_MINOR_BASE,
- .name = "tsdev",
- .id_table = tsdev_ids,
-};
-
-static int __init tsdev_init(void)
-{
- return input_register_handler(&tsdev_handler);
-}
-
-static void __exit tsdev_exit(void)
-{
- input_unregister_handler(&tsdev_handler);
-}
-
-module_init(tsdev_init);
-module_exit(tsdev_exit);
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 23b6f7bc16b..476012b6dfa 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -506,9 +506,14 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg)
{
struct sk_buff *skb;
size_t len;
+
capi_cmsg2message(cmsg, cmsg->buf);
len = CAPIMSG_LEN(cmsg->buf);
skb = alloc_skb(len, GFP_ATOMIC);
+ if (!skb) {
+ printk(KERN_ERR "capidrv::send_message: can't allocate mem\n");
+ return;
+ }
memcpy(skb_put(skb, len), cmsg->buf, len);
if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
kfree_skb(skb);
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 9f73bc2727c..f5553186931 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -821,6 +821,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
return -EFAULT;
}
card = get_capi_ctr_by_nr(ldef.contr);
+ if (!card)
+ return -EINVAL;
card = capi_ctr_get(card);
if (!card)
return -ESRCH;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 00e31609a23..af7648274b3 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1936,14 +1936,7 @@ static int gigaset_write_room(struct cardstate *cs)
*/
static int gigaset_chars_in_buffer(struct cardstate *cs)
{
- unsigned long flags;
- unsigned bytes;
-
- spin_lock_irqsave(&cs->cmdlock, flags);
- bytes = cs->cmdbytes;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
- return bytes;
+ return cs->cmdbytes;
}
/* gigaset_brkchars
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 6df336bdd57..acd417197d0 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -534,7 +534,8 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
n = RBUFSIZE - tail;
if (!n) {
dev_err(inbuf->cs->dev,
- "buffer overflow (%u bytes lost)", bytesleft);
+ "buffer overflow (%u bytes lost)\n",
+ bytesleft);
break;
}
if (n > bytesleft)
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 1654fa41357..9e089f06a94 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -109,13 +109,9 @@ EXPORT_SYMBOL_GPL(gigaset_skb_sent);
static int command_from_LL(isdn_ctrl *cntrl)
{
struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver);
- //isdn_ctrl response;
- //unsigned long flags;
struct bc_state *bcs;
int retval = 0;
struct setup_parm *sp;
- unsigned param;
- unsigned long flags;
gigaset_debugdrivers();
@@ -162,12 +158,8 @@ static int command_from_LL(isdn_ctrl *cntrl)
}
*sp = cntrl->parm.setup;
- spin_lock_irqsave(&cs->lock, flags);
- param = bcs->at_state.seq_index;
- spin_unlock_irqrestore(&cs->lock, flags);
-
- if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param,
- NULL)) {
+ if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp,
+ bcs->at_state.seq_index, NULL)) {
//FIXME what should we do?
kfree(sp);
gigaset_free_channel(bcs);
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index e767afa55ab..da6f3acf9fd 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -19,15 +19,9 @@
static ssize_t show_cidmode(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int ret;
- unsigned long flags;
struct cardstate *cs = dev_get_drvdata(dev);
- spin_lock_irqsave(&cs->lock, flags);
- ret = sprintf(buf, "%u\n", cs->cidmode);
- spin_unlock_irqrestore(&cs->lock, flags);
-
- return ret;
+ return sprintf(buf, "%u\n", cs->cidmode);
}
static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index a1263019df5..ca4bee173cf 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -310,7 +310,6 @@ static void gigaset_modem_fill(unsigned long data)
struct cardstate *cs = (struct cardstate *) data;
struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
struct cmdbuf_t *cb;
- unsigned long flags;
int again;
gig_dbg(DEBUG_OUTPUT, "modem_fill");
@@ -323,9 +322,7 @@ static void gigaset_modem_fill(unsigned long data)
do {
again = 0;
if (!bcs->tx_skb) { /* no skb is being sent */
- spin_lock_irqsave(&cs->cmdlock, flags);
cb = cs->cmdbuf;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
if (cb) { /* commands to send? */
gig_dbg(DEBUG_OUTPUT, "modem_fill: cb");
if (send_cb(cs, cb) < 0) {
@@ -546,13 +543,9 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
static int gigaset_write_room(struct cardstate *cs)
{
- unsigned long flags;
unsigned bytes;
- spin_lock_irqsave(&cs->cmdlock, flags);
bytes = cs->cmdbytes;
- spin_unlock_irqrestore(&cs->cmdlock, flags);
-
return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;
}
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index 7a69a18d07e..4484a641723 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -321,12 +321,15 @@ void b1_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;
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);
}
@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
unsigned int port = card->port;
unsigned long flags;
- capilib_release_appl(&cinfo->ncci_head, appl);
-
spin_lock_irqsave(&card->lock, flags);
+ capilib_release_appl(&cinfo->ncci_head, appl);
b1_put_byte(port, SEND_RELEASE);
b1_put_word(port, appl);
spin_unlock_irqrestore(&card->lock, flags);
@@ -380,27 +382,27 @@ u16 b1_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);
b1_put_slice(port, skb->data, len);
b1_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);
b1_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;
@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
ApplId = (unsigned) b1_get_word(card->port);
MsgLen = b1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
printk(KERN_ERR "%s: incoming packet dropped\n",
card->name);
+ spin_unlock_irqrestore(&card->lock, flags);
} else {
memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
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;
@@ -554,21 +556,17 @@ irqreturn_t b1_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:
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index d58f927e766..8710cf6214d 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card)
{
struct sk_buff *skb;
void *p;
+ unsigned long flags;
skb = alloc_skb(15, GFP_ATOMIC);
if (!skb) {
@@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card)
skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb);
+ spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
+ spin_unlock_irqrestore(&card->lock, flags);
}
static int queue_sendconfigword(avmcard *card, u32 val)
{
struct sk_buff *skb;
+ unsigned long flags;
void *p;
skb = alloc_skb(3+4, GFP_ATOMIC);
@@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard *card, u32 val)
skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb);
+ spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
+ spin_unlock_irqrestore(&card->lock, flags);
return 0;
}
@@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
struct sk_buff *skb;
void *p;
+ spin_lock_irqsave(&card->lock, flags);
capilib_release_appl(&cinfo->ncci_head, appl);
+ spin_unlock_irqrestore(&card->lock, flags);
if (ctrl->cnr == card->cardnr) {
skb = alloc_skb(7, GFP_ATOMIC);
@@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
u16 retval = CAPI_NOERROR;
unsigned long flags;
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+ spin_lock_irqsave(&card->lock, flags);
+ if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
@@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
}
if (retval == CAPI_NOERROR) {
skb_queue_tail(&card->dma->send_queue, skb);
- spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
}
+ spin_unlock_irqrestore(&card->lock, flags);
return retval;
}
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 4910bca5264..c6df2925ebd 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1365,7 +1365,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
} else {
s = NULL;
}
- ret = down_interruptible(&dev->sem);
+ ret = mutex_lock_interruptible(&dev->mtx);
if( ret ) return ret;
if ((s = isdn_net_new(s, NULL))) {
if (copy_to_user(argp, s, strlen(s) + 1)){
@@ -1375,7 +1375,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
}
} else
ret = -ENODEV;
- up(&dev->sem);
+ mutex_unlock(&dev->mtx);
return ret;
case IIOCNETASL:
/* Add a slave to a network-interface */
@@ -1384,7 +1384,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
return -EFAULT;
} else
return -EINVAL;
- ret = down_interruptible(&dev->sem);
+ ret = mutex_lock_interruptible(&dev->mtx);
if( ret ) return ret;
if ((s = isdn_net_newslave(bname))) {
if (copy_to_user(argp, s, strlen(s) + 1)){
@@ -1394,17 +1394,17 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
}
} else
ret = -ENODEV;
- up(&dev->sem);
+ mutex_unlock(&dev->mtx);
return ret;
case IIOCNETDIF:
/* Delete a network-interface */
if (arg) {
if (copy_from_user(name, argp, sizeof(name)))
return -EFAULT;
- ret = down_interruptible(&dev->sem);
+ ret = mutex_lock_interruptible(&dev->mtx);
if( ret ) return ret;
ret = isdn_net_rm(name);
- up(&dev->sem);
+ mutex_unlock(&dev->mtx);
return ret;
} else
return -EINVAL;
@@ -1433,10 +1433,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
if (arg) {
if (copy_from_user(&phone, argp, sizeof(phone)))
return -EFAULT;
- ret = down_interruptible(&dev->sem);
+ ret = mutex_lock_interruptible(&dev->mtx);
if( ret ) return ret;
ret = isdn_net_addphone(&phone);
- up(&dev->sem);
+ mutex_unlock(&dev->mtx);
return ret;
} else
return -EINVAL;
@@ -1445,10 +1445,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
if (arg) {
if (copy_from_user(&phone, argp, sizeof(phone)))
return -EFAULT;
- ret = down_interruptible(&dev->sem);
+ ret = mutex_lock_interruptible(&dev->mtx);
if( ret ) return ret;
ret = isdn_net_getphones(&phone, argp);
- up(&dev->sem);
+ mutex_unlock(&dev->mtx);
return ret;
} else
return -EINVAL;
@@ -1457,10 +1457,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
if (arg) {
if (copy_from_user(&phone, argp, sizeof(phone)))
return -EFAULT;
- ret = down_interruptible(&dev->sem);
+ ret = mutex_lock_interruptible(&dev->mtx);
if( ret ) return ret;
ret = isdn_net_delphone(&phone);
- up(&dev->sem);
+ mutex_unlock(&dev->mtx);
return ret;
} else
return -EINVAL;
@@ -2304,7 +2304,7 @@ static int __init isdn_init(void)
#ifdef MODULE
dev->owner = THIS_MODULE;
#endif
- init_MUTEX(&dev->sem);
+ mutex_init(&dev->mtx);
init_waitqueue_head(&dev->info_waitq);
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
dev->drvmap[i] = -1;
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 7c9cb7e19f2..b39d1f5b378 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -328,7 +328,7 @@ isdn_net_autohup(void)
l->cps = (l->transcount * HZ) / (jiffies - last_jiffies);
l->transcount = 0;
if (dev->net_verbose > 3)
- printk(KERN_DEBUG "%s: %d bogocps\n", l->name, l->cps);
+ printk(KERN_DEBUG "%s: %d bogocps\n", p->dev->name, l->cps);
if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
anymore = 1;
l->huptimer++;
@@ -350,12 +350,12 @@ isdn_net_autohup(void)
if (l->hupflags & ISDN_CHARGEHUP) {
if (l->hupflags & ISDN_WAITCHARGE) {
printk(KERN_DEBUG "isdn_net: Hupflags of %s are %X\n",
- l->name, l->hupflags);
+ p->dev->name, l->hupflags);
isdn_net_hangup(p->dev);
} else if (time_after(jiffies, l->chargetime + l->chargeint)) {
printk(KERN_DEBUG
"isdn_net: %s: chtime = %lu, chint = %d\n",
- l->name, l->chargetime, l->chargeint);
+ p->dev->name, l->chargetime, l->chargeint);
isdn_net_hangup(p->dev);
}
} else
@@ -442,8 +442,8 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
#endif
isdn_net_lp_disconnected(lp);
isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
- printk(KERN_INFO "%s: remote hangup\n", lp->name);
- printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
+ printk(KERN_INFO "%s: remote hangup\n", p->dev->name);
+ printk(KERN_INFO "%s: Chargesum is %d\n", p->dev->name,
lp->charge);
isdn_net_unbind_channel(lp);
return 1;
@@ -487,7 +487,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
isdn_net_add_to_bundle(nd, lp);
}
}
- printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
+ printk(KERN_INFO "isdn_net: %s connected\n", p->dev->name);
/* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here.
*/
@@ -534,7 +534,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
lp->hupflags |= ISDN_HAVECHARGE;
lp->chargetime = jiffies;
printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
- lp->name, lp->chargetime);
+ p->dev->name, lp->chargetime);
return 1;
}
}
@@ -565,7 +565,7 @@ isdn_net_dial(void)
#ifdef ISDN_DEBUG_NET_DIAL
if (lp->dialstate)
- printk(KERN_DEBUG "%s: dialstate=%d\n", lp->name, lp->dialstate);
+ printk(KERN_DEBUG "%s: dialstate=%d\n", p->dev->name, lp->dialstate);
#endif
switch (lp->dialstate) {
case 0:
@@ -578,7 +578,7 @@ isdn_net_dial(void)
lp->dial = lp->phone[1];
if (!lp->dial) {
printk(KERN_WARNING "%s: phone number deleted?\n",
- lp->name);
+ p->dev->name);
isdn_net_hangup(p->dev);
break;
}
@@ -632,13 +632,13 @@ isdn_net_dial(void)
cmd.arg = lp->isdn_channel;
if (!lp->dial) {
printk(KERN_WARNING "%s: phone number deleted?\n",
- lp->name);
+ p->dev->name);
isdn_net_hangup(p->dev);
break;
}
if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
lp->dialstate = 4;
- printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
+ printk(KERN_INFO "%s: Open leased line ...\n", p->dev->name);
} else {
if(lp->dialtimeout > 0)
if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
@@ -688,7 +688,7 @@ isdn_net_dial(void)
dev->usage[i] |= ISDN_USAGE_OUTGOING;
isdn_info_update();
}
- printk(KERN_INFO "%s: dialing %d %s... %s\n", lp->name,
+ printk(KERN_INFO "%s: dialing %d %s... %s\n", p->dev->name,
lp->dialretry, cmd.parm.setup.phone,
(cmd.parm.setup.si1 == 1) ? "DOV" : "");
lp->dtimer = 0;
@@ -797,7 +797,7 @@ isdn_net_dial(void)
*/
if (lp->dtimer++ > lp->cbdelay)
{
- printk(KERN_INFO "%s: hangup waiting for callback ...\n", lp->name);
+ printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->dev->name);
lp->dtimer = 0;
lp->dialstate = 4;
cmd.driver = lp->isdn_device;
@@ -810,7 +810,7 @@ isdn_net_dial(void)
break;
default:
printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
- lp->dialstate, lp->name);
+ lp->dialstate, p->dev->name);
}
p = (isdn_net_dev *) p->next;
}
@@ -836,11 +836,11 @@ isdn_net_hangup(struct net_device *d)
if (slp->flags & ISDN_NET_CONNECTED) {
printk(KERN_INFO
"isdn_net: hang up slave %s before %s\n",
- slp->name, lp->name);
+ lp->slave->name, d->name);
isdn_net_hangup(lp->slave);
}
}
- printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
+ printk(KERN_INFO "isdn_net: local hangup %s\n", d->name);
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
isdn_ppp_free(lp);
@@ -858,7 +858,7 @@ isdn_net_hangup(struct net_device *d)
cmd.command = ISDN_CMD_HANGUP;
cmd.arg = lp->isdn_channel;
isdn_command(&cmd);
- printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
+ printk(KERN_INFO "%s: Chargesum is %d\n", d->name, lp->charge);
isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
}
isdn_net_unbind_channel(lp);
@@ -885,7 +885,7 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
/* fall back to old isdn_net_log_packet method() */
char * buf = skb->data;
- printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->name);
+ printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->netdev->dev->name);
p = buf;
proto = ETH_P_IP;
switch (lp->p_encap) {
@@ -1023,7 +1023,7 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
if (ret != len) {
/* we should never get here */
- printk(KERN_WARNING "%s: HL driver queue full\n", lp->name);
+ printk(KERN_WARNING "%s: HL driver queue full\n", lp->netdev->dev->name);
goto error;
}
@@ -1461,7 +1461,7 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
mod_timer(&lp->cisco_timer, expires);
printk(KERN_INFO "%s: Keepalive period set "
"to %d seconds.\n",
- lp->name, lp->cisco_keepalive_period);
+ dev->name, lp->cisco_keepalive_period);
}
break;
@@ -1512,7 +1512,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
lp->cisco_line_state = 0;
printk (KERN_WARNING
"UPDOWN: Line protocol on Interface %s,"
- " changed state to down\n", lp->name);
+ " changed state to down\n", lp->netdev->dev->name);
/* should stop routing higher-level data accross */
} else if ((!lp->cisco_line_state) &&
(myseq_diff >= 0) && (myseq_diff <= 2)) {
@@ -1520,14 +1520,14 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
lp->cisco_line_state = 1;
printk (KERN_WARNING
"UPDOWN: Line protocol on Interface %s,"
- " changed state to up\n", lp->name);
+ " changed state to up\n", lp->netdev->dev->name);
/* restart routing higher-level data accross */
}
if (lp->cisco_debserint)
printk (KERN_DEBUG "%s: HDLC "
"myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
- lp->name, last_cisco_myseq, lp->cisco_mineseen,
+ lp->netdev->dev->name, last_cisco_myseq, lp->cisco_mineseen,
((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
lp->cisco_yourseq,
((lp->cisco_line_state) ? "line up" : "line down"));
@@ -1682,7 +1682,7 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
"remote ip: %d.%d.%d.%d, "
"local ip: %d.%d.%d.%d "
"mask: %d.%d.%d.%d\n",
- lp->name,
+ lp->netdev->dev->name,
HIPQUAD(addr),
HIPQUAD(local),
HIPQUAD(mask));
@@ -1690,7 +1690,7 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
slarp_reply_out:
printk(KERN_INFO "%s: got invalid slarp "
"reply (%d.%d.%d.%d/%d.%d.%d.%d) "
- "- ignored\n", lp->name,
+ "- ignored\n", lp->netdev->dev->name,
HIPQUAD(addr), HIPQUAD(mask));
break;
case CISCO_SLARP_KEEPALIVE:
@@ -1701,7 +1701,8 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
lp->cisco_last_slarp_in) {
printk(KERN_DEBUG "%s: Keepalive period mismatch - "
"is %d but should be %d.\n",
- lp->name, period, lp->cisco_keepalive_period);
+ lp->netdev->dev->name, period,
+ lp->cisco_keepalive_period);
}
lp->cisco_last_slarp_in = jiffies;
p += get_u32(p, &my_seq);
@@ -1732,12 +1733,12 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
if (addr != CISCO_ADDR_UNICAST && addr != CISCO_ADDR_BROADCAST) {
printk(KERN_WARNING "%s: Unknown Cisco addr 0x%02x\n",
- lp->name, addr);
+ lp->netdev->dev->name, addr);
goto out_free;
}
if (ctrl != CISCO_CTRL) {
printk(KERN_WARNING "%s: Unknown Cisco ctrl 0x%02x\n",
- lp->name, ctrl);
+ lp->netdev->dev->name, ctrl);
goto out_free;
}
@@ -1748,7 +1749,8 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
case CISCO_TYPE_CDP:
if (lp->cisco_debserint)
printk(KERN_DEBUG "%s: Received CDP packet. use "
- "\"no cdp enable\" on cisco.\n", lp->name);
+ "\"no cdp enable\" on cisco.\n",
+ lp->netdev->dev->name);
goto out_free;
default:
/* no special cisco protocol */
@@ -1843,7 +1845,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
};
#endif /* CONFIG_ISDN_X25 */
printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
- lp->name);
+ lp->netdev->dev->name);
kfree_skb(skb);
return;
}
@@ -2174,7 +2176,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
wret = matchret;
#ifdef ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
- lp->name, lp->msn, lp->flags, lp->dialstate);
+ p->dev->name, lp->msn, lp->flags, lp->dialstate);
#endif
if ((!matchret) && /* EAZ is matching */
(((!(lp->flags & ISDN_NET_CONNECTED)) && /* but not connected */
@@ -2277,7 +2279,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
* */
if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
- lp->name);
+ p->dev->name);
return 3;
}
/*
@@ -2286,7 +2288,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
*/
if (!isdn_net_device_started(p)) {
printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
- lp->name);
+ p->dev->name);
return 3;
}
/* Interface is up, now see if it's a slave. If so, see if
@@ -2294,8 +2296,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
*/
if (lp->master) {
isdn_net_local *mlp = (isdn_net_local *) lp->master->priv;
- printk(KERN_DEBUG "ICALLslv: %s\n", lp->name);
- printk(KERN_DEBUG "master=%s\n", mlp->name);
+ printk(KERN_DEBUG "ICALLslv: %s\n", p->dev->name);
+ printk(KERN_DEBUG "master=%s\n", lp->master->name);
if (mlp->flags & ISDN_NET_CONNECTED) {
printk(KERN_DEBUG "master online\n");
/* Master is online, find parent-slave (master if first slave) */
@@ -2322,11 +2324,11 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
* */
if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
printk(KERN_INFO "incoming call for callback, interface %s `off' -> rejected\n",
- lp->name);
+ p->dev->name);
return 3;
}
printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
- lp->name, nr, eaz);
+ p->dev->name, nr, eaz);
if (lp->phone[1]) {
/* Grab a free ISDN-Channel */
spin_lock_irqsave(&dev->lock, flags);
@@ -2340,7 +2342,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
lp->msn)
) < 0) {
- printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
+ printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n",
+ p->dev->name);
spin_unlock_irqrestore(&dev->lock, flags);
return 0;
}
@@ -2361,11 +2364,12 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
/* Initiate dialing by returning 2 or 4 */
return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
} else
- printk(KERN_WARNING "isdn_net: %s: No phone number\n", lp->name);
+ printk(KERN_WARNING "isdn_net: %s: No phone number\n",
+ p->dev->name);
return 0;
} else {
- printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
- eaz);
+ printk(KERN_DEBUG "%s: call from %s -> %s accepted\n",
+ p->dev->name, nr, eaz);
/* if this interface is dialing, it does it probably on a different
device, so free this device */
if ((lp->dialstate == 4) || (lp->dialstate == 12)) {
@@ -2424,7 +2428,7 @@ isdn_net_findif(char *name)
isdn_net_dev *p = dev->netdev;
while (p) {
- if (!strcmp(p->local->name, name))
+ if (!strcmp(p->dev->name, name))
return p;
p = (isdn_net_dev *) p->next;
}
@@ -2453,7 +2457,8 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
lp->pre_device,
lp->pre_channel,
lp->msn)) < 0) {
- printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
+ printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n",
+ lp->netdev->dev->name);
spin_unlock_irqrestore(&dev->lock, flags);
return -EAGAIN;
}
@@ -2556,7 +2561,7 @@ isdn_net_new(char *name, struct net_device *master)
return NULL;
}
if (name == NULL)
- name = " ";
+ return NULL;
if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
return NULL;
@@ -2568,7 +2573,6 @@ isdn_net_new(char *name, struct net_device *master)
return NULL;
}
netdev->local = netdev->dev->priv;
- strcpy(netdev->local->name, netdev->dev->name);
netdev->dev->init = isdn_net_init;
if (master) {
/* Device shall be a slave */
@@ -2673,7 +2677,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
#endif
if (isdn_net_device_started(p)) {
printk(KERN_WARNING "%s: cannot change encap when if is up\n",
- lp->name);
+ p->dev->name);
return -EBUSY;
}
#ifdef CONFIG_ISDN_X25
@@ -2698,7 +2702,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
case ISDN_NET_ENCAP_SYNCPPP:
#ifndef CONFIG_ISDN_PPP
printk(KERN_WARNING "%s: SyncPPP support not configured\n",
- lp->name);
+ p->dev->name);
return -EINVAL;
#else
p->dev->type = ARPHRD_PPP; /* change ARP type */
@@ -2709,7 +2713,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
case ISDN_NET_ENCAP_X25IFACE:
#ifndef CONFIG_ISDN_X25
printk(KERN_WARNING "%s: isdn-x25 support not configured\n",
- p->local->name);
+ p->dev->name);
return -EINVAL;
#else
p->dev->type = ARPHRD_X25; /* change ARP type */
@@ -2725,7 +2729,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
break;
printk(KERN_WARNING
"%s: encapsulation protocol %d not supported\n",
- p->local->name, cfg->p_encap);
+ p->dev->name, cfg->p_encap);
return -EINVAL;
}
if (strlen(cfg->drvid)) {
@@ -2902,13 +2906,18 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
cfg->pppbind = lp->pppbind;
cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
cfg->dialwait = lp->dialwait / HZ;
- if (lp->slave)
- strcpy(cfg->slave, ((isdn_net_local *) lp->slave->priv)->name);
- else
+ if (lp->slave) {
+ if (strlen(lp->slave->name) > 8)
+ strcpy(cfg->slave, "too-long");
+ else
+ strcpy(cfg->slave, lp->slave->name);
+ } else
cfg->slave[0] = '\0';
- if (lp->master)
- strcpy(cfg->master, ((isdn_net_local *) lp->master->priv)->name);
- else
+ if (lp->master) {
+ if (strlen(lp->master->name) > 8)
+ strcpy(cfg->master, "too-long");
+ strcpy(cfg->master, lp->master->name);
+ } else
cfg->master[0] = '\0';
return 0;
}
@@ -2978,7 +2987,8 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
isdn_net_dev *p = isdn_net_findif(phone->name);
int ch, dv, idx;
- if (!p) return -ENODEV;
+ if (!p)
+ return -ENODEV;
/*
* Theoretical race: while this executes, the remote number might
* become invalid (hang up) or change (new connection), resulting
@@ -2987,14 +2997,18 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
*/
ch = p->local->isdn_channel;
dv = p->local->isdn_device;
- if(ch<0 && dv<0) return -ENOTCONN;
+ if(ch < 0 && dv < 0)
+ return -ENOTCONN;
idx = isdn_dc2minor(dv, ch);
- if (idx<0) return -ENODEV;
+ if (idx <0 )
+ return -ENODEV;
/* for pre-bound channels, we need this extra check */
- if ( strncmp(dev->num[idx],"???",3) == 0 ) return -ENOTCONN;
- strncpy(phone->phone,dev->num[idx],ISDN_MSNLEN);
- phone->outgoing=USG_OUTGOING(dev->usage[idx]);
- if ( copy_to_user(peer,phone,sizeof(*peer)) ) return -EFAULT;
+ if (strncmp(dev->num[idx], "???", 3) == 0)
+ return -ENOTCONN;
+ strncpy(phone->phone, dev->num[idx], ISDN_MSNLEN);
+ phone->outgoing = USG_OUTGOING(dev->usage[idx]);
+ if (copy_to_user(peer, phone, sizeof(*peer)))
+ return -EFAULT;
return 0;
}
/*
@@ -3113,18 +3127,18 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
dev->netdev = p->next;
if (p->local->slave) {
/* If this interface has a slave, remove it also */
- char *slavename = ((isdn_net_local *) (p->local->slave->priv))->name;
+ char *slavename = p->local->slave->name;
isdn_net_dev *n = dev->netdev;
q = NULL;
while (n) {
- if (!strcmp(n->local->name, slavename)) {
+ if (!strcmp(n->dev->name, slavename)) {
spin_unlock_irqrestore(&dev->lock, flags);
isdn_net_realrm(n, q);
spin_lock_irqsave(&dev->lock, flags);
break;
}
q = n;
- n = (isdn_net_dev *) n->next;
+ n = (isdn_net_dev *)n->next;
}
}
spin_unlock_irqrestore(&dev->lock, flags);
@@ -3152,7 +3166,7 @@ isdn_net_rm(char *name)
p = dev->netdev;
q = NULL;
while (p) {
- if (!strcmp(p->local->name, name)) {
+ if (!strcmp(p->dev->name, name)) {
spin_unlock_irqrestore(&dev->lock, flags);
return (isdn_net_realrm(p, q));
}
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 0e5e59f8434..9f5fe372f83 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -190,9 +190,11 @@ isdn_ppp_bind(isdn_net_local * lp)
retval = -1;
goto out;
}
- unit = isdn_ppp_if_get_unit(lp->name); /* get unit number from interface name .. ugly! */
+ /* get unit number from interface name .. ugly! */
+ unit = isdn_ppp_if_get_unit(lp->netdev->dev->name);
if (unit < 0) {
- printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n", lp->name);
+ printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n",
+ lp->netdev->dev->name);
retval = -1;
goto out;
}
@@ -507,7 +509,8 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
case PPPIOCGIFNAME:
if(!lp)
return -EINVAL;
- if ((r = set_arg(argp, lp->name, strlen(lp->name))))
+ if ((r = set_arg(argp, lp->netdev->dev->name,
+ strlen(lp->netdev->dev->name))))
return r;
break;
case PPPIOCGMPFLAGS: /* get configuration flags */
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 3cb23210b91..ec568fa1c6c 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -83,7 +83,7 @@ config LEDS_WRAP
config LEDS_H1940
tristate "LED Support for iPAQ H1940 device"
- depends LEDS_CLASS && ARCH_H1940
+ depends on LEDS_CLASS && ARCH_H1940
help
This option enables support for the LEDs on the h1940.
@@ -108,6 +108,12 @@ config LEDS_GPIO
outputs. To be useful the particular board must have LEDs
and they must be connected to the GPIO lines.
+config LEDS_CM_X270
+ tristate "LED Support for the CM-X270 LEDs"
+ depends on LEDS_CLASS && MACH_ARMCORE
+ help
+ This option enables support for the CM-X270 LEDs.
+
comment "LED Triggers"
config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index d2ca1abbc3d..a60de1b46c2 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
+obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
diff --git a/drivers/leds/leds-cm-x270.c b/drivers/leds/leds-cm-x270.c
new file mode 100644
index 00000000000..9aebef02a97
--- /dev/null
+++ b/drivers/leds/leds-cm-x270.c
@@ -0,0 +1,122 @@
+/*
+ * drivers/leds/leds-cm-x270.c
+ *
+ * Copyright 2007 CompuLab Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on leds-corgi.c
+ * Author: Richard Purdie <rpurdie@openedhand.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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#define GPIO_RED_LED (93)
+#define GPIO_GREEN_LED (94)
+
+static void cmx270_red_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ GPCR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED);
+ else
+ GPSR(GPIO_RED_LED) = GPIO_bit(GPIO_RED_LED);
+}
+
+static void cmx270_green_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ if (value)
+ GPCR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED);
+ else
+ GPSR(GPIO_GREEN_LED) = GPIO_bit(GPIO_GREEN_LED);
+}
+
+static struct led_classdev cmx270_red_led = {
+ .name = "cm-x270:red",
+ .default_trigger = "nand-disk",
+ .brightness_set = cmx270_red_set,
+};
+
+static struct led_classdev cmx270_green_led = {
+ .name = "cm-x270:green",
+ .default_trigger = "heartbeat",
+ .brightness_set = cmx270_green_set,
+};
+
+#ifdef CONFIG_PM
+static int cmx270led_suspend(struct platform_device *dev, pm_message_t state)
+{
+ led_classdev_suspend(&cmx270_red_led);
+ led_classdev_suspend(&cmx270_green_led);
+ return 0;
+}
+
+static int cmx270led_resume(struct platform_device *dev)
+{
+ led_classdev_resume(&cmx270_red_led);
+ led_classdev_resume(&cmx270_green_led);
+ return 0;
+}
+#endif
+
+static int cmx270led_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = led_classdev_register(&pdev->dev, &cmx270_red_led);
+ if (ret < 0)
+ return ret;
+
+ ret = led_classdev_register(&pdev->dev, &cmx270_green_led);
+ if (ret < 0)
+ led_classdev_unregister(&cmx270_red_led);
+
+ return ret;
+}
+
+static int cmx270led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&cmx270_red_led);
+ led_classdev_unregister(&cmx270_green_led);
+ return 0;
+}
+
+static struct platform_driver cmx270led_driver = {
+ .probe = cmx270led_probe,
+ .remove = cmx270led_remove,
+#ifdef CONFIG_PM
+ .suspend = cmx270led_suspend,
+ .resume = cmx270led_resume,
+#endif
+ .driver = {
+ .name = "cm-x270-led",
+ },
+};
+
+static int __init cmx270led_init(void)
+{
+ return platform_driver_register(&cmx270led_driver);
+}
+
+static void __exit cmx270led_exit(void)
+{
+ platform_driver_unregister(&cmx270led_driver);
+}
+
+module_init(cmx270led_init);
+module_exit(cmx270led_exit);
+
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("CM-x270 LED driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 4a315f08a56..a0788c12b39 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -248,8 +248,8 @@ static void unmap_switcher(void)
}
/*H:130 Our Guest is usually so well behaved; it never tries to do things it
- * isn't allowed to. Unfortunately, "struct paravirt_ops" isn't quite
- * complete, because it doesn't contain replacements for the Intel I/O
+ * isn't allowed to. Unfortunately, Linux's paravirtual infrastructure isn't
+ * quite complete, because it doesn't contain replacements for the Intel I/O
* instructions. As a result, the Guest sometimes fumbles across one during
* the boot process as it probes for various things which are usually attached
* to a PC.
@@ -694,7 +694,7 @@ static int __init init(void)
/* Lguest can't run under Xen, VMI or itself. It does Tricky Stuff. */
if (paravirt_enabled()) {
- printk("lguest is afraid of %s\n", paravirt_ops.name);
+ printk("lguest is afraid of %s\n", pv_info.name);
return -EPERM;
}
diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c
index ee1c6d05c3d..3ba337dde85 100644
--- a/drivers/lguest/lguest.c
+++ b/drivers/lguest/lguest.c
@@ -23,7 +23,7 @@
*
* So how does the kernel know it's a Guest? The Guest starts at a special
* entry point marked with a magic string, which sets up a few things then
- * calls here. We replace the native functions in "struct paravirt_ops"
+ * calls here. We replace the native functions various "paravirt" structures
* with our Guest versions, then boot like normal. :*/
/*
@@ -97,29 +97,17 @@ static cycle_t clock_base;
* them as a batch when lazy_mode is eventually turned off. Because hypercalls
* are reasonably expensive, batching them up makes sense. For example, a
* large mmap might update dozens of page table entries: that code calls
- * lguest_lazy_mode(PARAVIRT_LAZY_MMU), does the dozen updates, then calls
- * lguest_lazy_mode(PARAVIRT_LAZY_NONE).
+ * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
+ * lguest_leave_lazy_mode().
*
* So, when we're in lazy mode, we call async_hypercall() to store the call for
* future processing. When lazy mode is turned off we issue a hypercall to
* flush the stored calls.
- *
- * There's also a hack where "mode" is set to "PARAVIRT_LAZY_FLUSH" which
- * indicates we're to flush any outstanding calls immediately. This is used
- * when an interrupt handler does a kmap_atomic(): the page table changes must
- * happen immediately even if we're in the middle of a batch. Usually we're
- * not, though, so there's nothing to do. */
-static enum paravirt_lazy_mode lazy_mode; /* Note: not SMP-safe! */
-static void lguest_lazy_mode(enum paravirt_lazy_mode mode)
+ */
+static void lguest_leave_lazy_mode(void)
{
- if (mode == PARAVIRT_LAZY_FLUSH) {
- if (unlikely(lazy_mode != PARAVIRT_LAZY_NONE))
- hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
- } else {
- lazy_mode = mode;
- if (mode == PARAVIRT_LAZY_NONE)
- hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
- }
+ paravirt_leave_lazy(paravirt_get_lazy_mode());
+ hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
}
static void lazy_hcall(unsigned long call,
@@ -127,7 +115,7 @@ static void lazy_hcall(unsigned long call,
unsigned long arg2,
unsigned long arg3)
{
- if (lazy_mode == PARAVIRT_LAZY_NONE)
+ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
hcall(call, arg1, arg2, arg3);
else
async_hcall(call, arg1, arg2, arg3);
@@ -331,7 +319,7 @@ static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
}
/*G:038 That's enough excitement for now, back to ploughing through each of
- * the paravirt_ops (we're about 1/3 of the way through).
+ * the different pv_ops structures (we're about 1/3 of the way through).
*
* This is the Local Descriptor Table, another weird Intel thingy. Linux only
* uses this for some strange applications like Wine. We don't do anything
@@ -558,7 +546,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval)
lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
}
-/* Unfortunately for Lguest, the paravirt_ops for page tables were based on
+/* Unfortunately for Lguest, the pv_mmu_ops for page tables were based on
* native page table operations. On native hardware you can set a new page
* table entry whenever you want, but if you want to remove one you have to do
* a TLB flush (a TLB is a little cache of page table entries kept by the CPU).
@@ -782,7 +770,7 @@ static void lguest_time_init(void)
clocksource_register(&lguest_clock);
/* Now we've set up our clock, we can use it as the scheduler clock */
- paravirt_ops.sched_clock = lguest_sched_clock;
+ pv_time_ops.sched_clock = lguest_sched_clock;
/* We can't set cpumask in the initializer: damn C limitations! Set it
* here and register our timer device. */
@@ -893,7 +881,9 @@ static __init char *lguest_memory_setup(void)
/* The Linux bootloader header contains an "e820" memory map: the
* Launcher populated the first entry with our memory limit. */
- add_memory_region(E820_MAP->addr, E820_MAP->size, E820_MAP->type);
+ add_memory_region(boot_params.e820_map[0].addr,
+ boot_params.e820_map[0].size,
+ boot_params.e820_map[0].type);
/* This string is for the boot messages. */
return "LGUEST";
@@ -902,7 +892,7 @@ static __init char *lguest_memory_setup(void)
/*G:050
* Patching (Powerfully Placating Performance Pedants)
*
- * We have already seen that "struct paravirt_ops" lets us replace simple
+ * We have already seen that pv_ops structures let us replace simple
* native instructions with calls to the appropriate back end all throughout
* the kernel. This allows the same kernel to run as a Guest and as a native
* kernel, but it's slow because of all the indirect branches.
@@ -927,10 +917,10 @@ static const struct lguest_insns
{
const char *start, *end;
} lguest_insns[] = {
- [PARAVIRT_PATCH(irq_disable)] = { lgstart_cli, lgend_cli },
- [PARAVIRT_PATCH(irq_enable)] = { lgstart_sti, lgend_sti },
- [PARAVIRT_PATCH(restore_fl)] = { lgstart_popf, lgend_popf },
- [PARAVIRT_PATCH(save_fl)] = { lgstart_pushf, lgend_pushf },
+ [PARAVIRT_PATCH(pv_irq_ops.irq_disable)] = { lgstart_cli, lgend_cli },
+ [PARAVIRT_PATCH(pv_irq_ops.irq_enable)] = { lgstart_sti, lgend_sti },
+ [PARAVIRT_PATCH(pv_irq_ops.restore_fl)] = { lgstart_popf, lgend_popf },
+ [PARAVIRT_PATCH(pv_irq_ops.save_fl)] = { lgstart_pushf, lgend_pushf },
};
/* Now our patch routine is fairly simple (based on the native one in
@@ -957,9 +947,9 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
return insn_len;
}
-/*G:030 Once we get to lguest_init(), we know we're a Guest. The paravirt_ops
- * structure in the kernel provides a single point for (almost) every routine
- * we have to override to avoid privileged instructions. */
+/*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops
+ * structures in the kernel provide points for (almost) every routine we have
+ * to override to avoid privileged instructions. */
__init void lguest_init(void *boot)
{
/* Copy boot parameters first: the Launcher put the physical location
@@ -974,54 +964,70 @@ __init void lguest_init(void *boot)
/* We're under lguest, paravirt is enabled, and we're running at
* privilege level 1, not 0 as normal. */
- paravirt_ops.name = "lguest";
- paravirt_ops.paravirt_enabled = 1;
- paravirt_ops.kernel_rpl = 1;
+ pv_info.name = "lguest";
+ pv_info.paravirt_enabled = 1;
+ pv_info.kernel_rpl = 1;
/* We set up all the lguest overrides for sensitive operations. These
* are detailed with the operations themselves. */
- paravirt_ops.save_fl = save_fl;
- paravirt_ops.restore_fl = restore_fl;
- paravirt_ops.irq_disable = irq_disable;
- paravirt_ops.irq_enable = irq_enable;
- paravirt_ops.load_gdt = lguest_load_gdt;
- paravirt_ops.memory_setup = lguest_memory_setup;
- paravirt_ops.cpuid = lguest_cpuid;
- paravirt_ops.write_cr3 = lguest_write_cr3;
- paravirt_ops.flush_tlb_user = lguest_flush_tlb_user;
- paravirt_ops.flush_tlb_single = lguest_flush_tlb_single;
- paravirt_ops.flush_tlb_kernel = lguest_flush_tlb_kernel;
- paravirt_ops.set_pte = lguest_set_pte;
- paravirt_ops.set_pte_at = lguest_set_pte_at;
- paravirt_ops.set_pmd = lguest_set_pmd;
+
+ /* interrupt-related operations */
+ pv_irq_ops.init_IRQ = lguest_init_IRQ;
+ pv_irq_ops.save_fl = save_fl;
+ pv_irq_ops.restore_fl = restore_fl;
+ pv_irq_ops.irq_disable = irq_disable;
+ pv_irq_ops.irq_enable = irq_enable;
+ pv_irq_ops.safe_halt = lguest_safe_halt;
+
+ /* init-time operations */
+ pv_init_ops.memory_setup = lguest_memory_setup;
+ pv_init_ops.patch = lguest_patch;
+
+ /* Intercepts of various cpu instructions */
+ pv_cpu_ops.load_gdt = lguest_load_gdt;
+ pv_cpu_ops.cpuid = lguest_cpuid;
+ pv_cpu_ops.load_idt = lguest_load_idt;
+ pv_cpu_ops.iret = lguest_iret;
+ pv_cpu_ops.load_esp0 = lguest_load_esp0;
+ pv_cpu_ops.load_tr_desc = lguest_load_tr_desc;
+ pv_cpu_ops.set_ldt = lguest_set_ldt;
+ pv_cpu_ops.load_tls = lguest_load_tls;
+ pv_cpu_ops.set_debugreg = lguest_set_debugreg;
+ pv_cpu_ops.clts = lguest_clts;
+ pv_cpu_ops.read_cr0 = lguest_read_cr0;
+ pv_cpu_ops.write_cr0 = lguest_write_cr0;
+ pv_cpu_ops.read_cr4 = lguest_read_cr4;
+ pv_cpu_ops.write_cr4 = lguest_write_cr4;
+ pv_cpu_ops.write_gdt_entry = lguest_write_gdt_entry;
+ pv_cpu_ops.write_idt_entry = lguest_write_idt_entry;
+ pv_cpu_ops.wbinvd = lguest_wbinvd;
+ pv_cpu_ops.lazy_mode.enter = paravirt_enter_lazy_cpu;
+ pv_cpu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
+
+ /* pagetable management */
+ pv_mmu_ops.write_cr3 = lguest_write_cr3;
+ pv_mmu_ops.flush_tlb_user = lguest_flush_tlb_user;
+ pv_mmu_ops.flush_tlb_single = lguest_flush_tlb_single;
+ pv_mmu_ops.flush_tlb_kernel = lguest_flush_tlb_kernel;
+ pv_mmu_ops.set_pte = lguest_set_pte;
+ pv_mmu_ops.set_pte_at = lguest_set_pte_at;
+ pv_mmu_ops.set_pmd = lguest_set_pmd;
+ pv_mmu_ops.read_cr2 = lguest_read_cr2;
+ pv_mmu_ops.read_cr3 = lguest_read_cr3;
+ pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
+ pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
+
#ifdef CONFIG_X86_LOCAL_APIC
- paravirt_ops.apic_write = lguest_apic_write;
- paravirt_ops.apic_write_atomic = lguest_apic_write;
- paravirt_ops.apic_read = lguest_apic_read;
+ /* apic read/write intercepts */
+ pv_apic_ops.apic_write = lguest_apic_write;
+ pv_apic_ops.apic_write_atomic = lguest_apic_write;
+ pv_apic_ops.apic_read = lguest_apic_read;
#endif
- paravirt_ops.load_idt = lguest_load_idt;
- paravirt_ops.iret = lguest_iret;
- paravirt_ops.load_esp0 = lguest_load_esp0;
- paravirt_ops.load_tr_desc = lguest_load_tr_desc;
- paravirt_ops.set_ldt = lguest_set_ldt;
- paravirt_ops.load_tls = lguest_load_tls;
- paravirt_ops.set_debugreg = lguest_set_debugreg;
- paravirt_ops.clts = lguest_clts;
- paravirt_ops.read_cr0 = lguest_read_cr0;
- paravirt_ops.write_cr0 = lguest_write_cr0;
- paravirt_ops.init_IRQ = lguest_init_IRQ;
- paravirt_ops.read_cr2 = lguest_read_cr2;
- paravirt_ops.read_cr3 = lguest_read_cr3;
- paravirt_ops.read_cr4 = lguest_read_cr4;
- paravirt_ops.write_cr4 = lguest_write_cr4;
- paravirt_ops.write_gdt_entry = lguest_write_gdt_entry;
- paravirt_ops.write_idt_entry = lguest_write_idt_entry;
- paravirt_ops.patch = lguest_patch;
- paravirt_ops.safe_halt = lguest_safe_halt;
- paravirt_ops.get_wallclock = lguest_get_wallclock;
- paravirt_ops.time_init = lguest_time_init;
- paravirt_ops.set_lazy_mode = lguest_lazy_mode;
- paravirt_ops.wbinvd = lguest_wbinvd;
+
+ /* time operations */
+ pv_time_ops.get_wallclock = lguest_get_wallclock;
+ pv_time_ops.time_init = lguest_time_init;
+
/* Now is a good time to look at the implementations of these functions
* before returning to the rest of lguest_init(). */
diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c
index 9e7752cc800..57329788f8a 100644
--- a/drivers/lguest/lguest_bus.c
+++ b/drivers/lguest/lguest_bus.c
@@ -201,7 +201,7 @@ static void scan_devices(void)
* "struct lguest_device_desc" array. */
static int __init lguest_bus_init(void)
{
- if (strcmp(paravirt_ops.name, "lguest") != 0)
+ if (strcmp(pv_info.name, "lguest") != 0)
return 0;
/* Devices are in a single page above top of "normal" mem */
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 56cd8998fe4..77f50b63a97 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -172,6 +172,7 @@ config INPUT_ADBHID
config MAC_EMUMOUSEBTN
bool "Support for mouse button 2+3 emulation"
+ select INPUT
help
This provides generic support for emulating the 2nd and 3rd mouse
button with keypresses. If you say Y here, the emulation is still
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 48d17bf6c92..2766e4fc4ea 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -52,6 +52,11 @@
MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>");
+static int restore_capslock_events;
+module_param(restore_capslock_events, int, 0644);
+MODULE_PARM_DESC(restore_capslock_events,
+ "Produce keypress events for capslock on both keyup and keydown.");
+
#define KEYB_KEYREG 0 /* register # for key up/down data */
#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
@@ -217,6 +222,8 @@ struct adbhid {
#define FLAG_FN_KEY_PRESSED 0x00000001
#define FLAG_POWER_FROM_FN 0x00000002
#define FLAG_EMU_FWDEL_DOWN 0x00000004
+#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
+#define FLAG_CAPSLOCK_DOWN 0x00000010
static struct adbhid *adbhid[16];
@@ -272,19 +279,50 @@ adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
}
static void
-adbhid_input_keycode(int id, int keycode, int repeat)
+adbhid_input_keycode(int id, int scancode, int repeat)
{
struct adbhid *ahid = adbhid[id];
- int up_flag, key;
-
- up_flag = (keycode & 0x80);
- keycode &= 0x7f;
+ int keycode, up_flag, key;
+
+ keycode = scancode & 0x7f;
+ up_flag = scancode & 0x80;
+
+ if (restore_capslock_events) {
+ if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
+ /* Key pressed, turning on the CapsLock LED.
+ * The next 0xff will be interpreted as a release. */
+ ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
+ | FLAG_CAPSLOCK_DOWN;
+ } else if (scancode == 0xff) {
+ /* Scancode 0xff usually signifies that the capslock
+ * key was either pressed or released. */
+ if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
+ keycode = ADB_KEY_CAPSLOCK;
+ if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
+ /* Key released */
+ up_flag = 1;
+ ahid->flags &= ~FLAG_CAPSLOCK_DOWN;
+ } else {
+ /* Key pressed */
+ up_flag = 0;
+ ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE;
+ }
+ } else {
+ printk(KERN_INFO "Spurious caps lock event "
+ "(scancode 0xff).");
+ }
+ }
+ }
switch (keycode) {
- case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */
- input_report_key(ahid->input, KEY_CAPSLOCK, 1);
- input_report_key(ahid->input, KEY_CAPSLOCK, 0);
- input_sync(ahid->input);
+ case ADB_KEY_CAPSLOCK:
+ if (!restore_capslock_events) {
+ /* Generate down/up events for CapsLock everytime. */
+ input_report_key(ahid->input, KEY_CAPSLOCK, 1);
+ input_sync(ahid->input);
+ input_report_key(ahid->input, KEY_CAPSLOCK, 0);
+ input_sync(ahid->input);
+ }
return;
#ifdef CONFIG_PPC_PMAC
case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */
@@ -296,7 +334,7 @@ adbhid_input_keycode(int id, int keycode, int repeat)
keycode = ADB_KEY_POWER;
}
break;
- case ADB_KEY_POWER:
+ case ADB_KEY_POWER:
/* Fn + Command will produce a bogus "power" keycode */
if (ahid->flags & FLAG_FN_KEY_PRESSED) {
keycode = ADB_KEY_CMD;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 8216a6f75be..64fee90bb68 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -441,33 +441,12 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
return clone;
}
-static void crypt_free_buffer_pages(struct crypt_config *cc,
- struct bio *clone, unsigned int bytes)
+static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
{
- unsigned int i, start, end;
+ unsigned int i;
struct bio_vec *bv;
- /*
- * This is ugly, but Jens Axboe thinks that using bi_idx in the
- * endio function is too dangerous at the moment, so I calculate the
- * correct position using bi_vcnt and bi_size.
- * The bv_offset and bv_len fields might already be modified but we
- * know that we always allocated whole pages.
- * A fix to the bi_idx issue in the kernel is in the works, so
- * we will hopefully be able to revert to the cleaner solution soon.
- */
- i = clone->bi_vcnt - 1;
- bv = bio_iovec_idx(clone, i);
- end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size;
- start = end - bytes;
-
- start >>= PAGE_SHIFT;
- if (!clone->bi_size)
- end = clone->bi_vcnt;
- else
- end >>= PAGE_SHIFT;
-
- for (i = start; i < end; i++) {
+ for (i = 0; i < clone->bi_vcnt; i++) {
bv = bio_iovec_idx(clone, i);
BUG_ON(!bv->bv_page);
mempool_free(bv->bv_page, cc->page_pool);
@@ -519,7 +498,7 @@ static void crypt_endio(struct bio *clone, int error)
* free the processed pages
*/
if (!read_io) {
- crypt_free_buffer_pages(cc, clone, clone->bi_size);
+ crypt_free_buffer_pages(cc, clone);
goto out;
}
@@ -608,7 +587,7 @@ static void process_write(struct dm_crypt_io *io)
ctx.idx_out = 0;
if (unlikely(crypt_convert(cc, &ctx) < 0)) {
- crypt_free_buffer_pages(cc, clone, clone->bi_size);
+ crypt_free_buffer_pages(cc, clone);
bio_put(clone);
dec_pending(io, -EIO);
return;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2bcde5798b5..fbe477bb2c6 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -999,33 +999,6 @@ void dm_table_unplug_all(struct dm_table *t)
}
}
-int dm_table_flush_all(struct dm_table *t)
-{
- struct list_head *d, *devices = dm_table_get_devices(t);
- int ret = 0;
- unsigned i;
-
- for (i = 0; i < t->num_targets; i++)
- if (t->targets[i].type->flush)
- t->targets[i].type->flush(&t->targets[i]);
-
- for (d = devices->next; d != devices; d = d->next) {
- struct dm_dev *dd = list_entry(d, struct dm_dev, list);
- struct request_queue *q = bdev_get_queue(dd->bdev);
- int err;
-
- if (!q->issue_flush_fn)
- err = -EOPNOTSUPP;
- else
- err = q->issue_flush_fn(q, dd->bdev->bd_disk, NULL);
-
- if (!ret)
- ret = err;
- }
-
- return ret;
-}
-
struct mapped_device *dm_table_get_md(struct dm_table *t)
{
dm_get(t->md);
@@ -1043,4 +1016,3 @@ EXPORT_SYMBOL(dm_table_get_md);
EXPORT_SYMBOL(dm_table_put);
EXPORT_SYMBOL(dm_table_get);
EXPORT_SYMBOL(dm_table_unplug_all);
-EXPORT_SYMBOL(dm_table_flush_all);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 167765c4774..d837d37f620 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -840,21 +840,6 @@ static int dm_request(struct request_queue *q, struct bio *bio)
return 0;
}
-static int dm_flush_all(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- struct mapped_device *md = q->queuedata;
- struct dm_table *map = dm_get_table(md);
- int ret = -ENXIO;
-
- if (map) {
- ret = dm_table_flush_all(map);
- dm_table_put(map);
- }
-
- return ret;
-}
-
static void dm_unplug_all(struct request_queue *q)
{
struct mapped_device *md = q->queuedata;
@@ -1003,7 +988,6 @@ static struct mapped_device *alloc_dev(int minor)
blk_queue_make_request(md->queue, dm_request);
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
md->queue->unplug_fn = dm_unplug_all;
- md->queue->issue_flush_fn = dm_flush_all;
md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache);
if (!md->io_pool)
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 462ee652a89..4b3faa45277 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -111,7 +111,6 @@ void dm_table_postsuspend_targets(struct dm_table *t);
int dm_table_resume_targets(struct dm_table *t);
int dm_table_any_congested(struct dm_table *t, int bdi_bits);
void dm_table_unplug_all(struct dm_table *t);
-int dm_table_flush_all(struct dm_table *t);
/*-----------------------------------------------------------------
* A registry of target types.
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 550148770bb..56a11f6c127 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -92,25 +92,6 @@ static void linear_unplug(struct request_queue *q)
}
}
-static int linear_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- mddev_t *mddev = q->queuedata;
- linear_conf_t *conf = mddev_to_conf(mddev);
- int i, ret = 0;
-
- for (i=0; i < mddev->raid_disks && ret == 0; i++) {
- struct block_device *bdev = conf->disks[i].rdev->bdev;
- struct request_queue *r_queue = bdev_get_queue(bdev);
-
- if (!r_queue->issue_flush_fn)
- ret = -EOPNOTSUPP;
- else
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
- }
- return ret;
-}
-
static int linear_congested(void *data, int bits)
{
mddev_t *mddev = data;
@@ -279,7 +260,6 @@ static int linear_run (mddev_t *mddev)
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
- mddev->queue->issue_flush_fn = linear_issue_flush;
mddev->queue->backing_dev_info.congested_fn = linear_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
return 0;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index acf1b81b47c..c059ae6f37e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2714,7 +2714,7 @@ action_show(mddev_t *mddev, char *page)
{
char *type = "idle";
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
- test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
+ (!mddev->ro && test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))) {
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
type = "reshape";
else if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
@@ -2833,6 +2833,12 @@ sync_max_store(mddev_t *mddev, const char *buf, size_t len)
static struct md_sysfs_entry md_sync_max =
__ATTR(sync_speed_max, S_IRUGO|S_IWUSR, sync_max_show, sync_max_store);
+static ssize_t
+degraded_show(mddev_t *mddev, char *page)
+{
+ return sprintf(page, "%d\n", mddev->degraded);
+}
+static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded);
static ssize_t
sync_speed_show(mddev_t *mddev, char *page)
@@ -2976,6 +2982,7 @@ static struct attribute *md_redundancy_attrs[] = {
&md_suspend_lo.attr,
&md_suspend_hi.attr,
&md_bitmap.attr,
+ &md_degraded.attr,
NULL,
};
static struct attribute_group md_redundancy_group = {
@@ -3463,7 +3470,6 @@ static int do_md_stop(mddev_t * mddev, int mode)
mddev->pers->stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
- mddev->queue->issue_flush_fn = NULL;
mddev->queue->backing_dev_info.congested_fn = NULL;
if (mddev->pers->sync_request)
sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
@@ -5771,26 +5777,47 @@ static int __init md_init(void)
* Searches all registered partitions for autorun RAID arrays
* at boot time.
*/
-static dev_t detected_devices[128];
-static int dev_cnt;
+
+static LIST_HEAD(all_detected_devices);
+struct detected_devices_node {
+ struct list_head list;
+ dev_t dev;
+};
void md_autodetect_dev(dev_t dev)
{
- if (dev_cnt >= 0 && dev_cnt < 127)
- detected_devices[dev_cnt++] = dev;
+ struct detected_devices_node *node_detected_dev;
+
+ node_detected_dev = kzalloc(sizeof(*node_detected_dev), GFP_KERNEL);
+ if (node_detected_dev) {
+ node_detected_dev->dev = dev;
+ list_add_tail(&node_detected_dev->list, &all_detected_devices);
+ } else {
+ printk(KERN_CRIT "md: md_autodetect_dev: kzalloc failed"
+ ", skipping dev(%d,%d)\n", MAJOR(dev), MINOR(dev));
+ }
}
static void autostart_arrays(int part)
{
mdk_rdev_t *rdev;
- int i;
+ struct detected_devices_node *node_detected_dev;
+ dev_t dev;
+ int i_scanned, i_passed;
- printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
+ i_scanned = 0;
+ i_passed = 0;
- for (i = 0; i < dev_cnt; i++) {
- dev_t dev = detected_devices[i];
+ printk(KERN_INFO "md: Autodetecting RAID arrays.\n");
+ while (!list_empty(&all_detected_devices) && i_scanned < INT_MAX) {
+ i_scanned++;
+ node_detected_dev = list_entry(all_detected_devices.next,
+ struct detected_devices_node, list);
+ list_del(&node_detected_dev->list);
+ dev = node_detected_dev->dev;
+ kfree(node_detected_dev);
rdev = md_import_device(dev,0, 90);
if (IS_ERR(rdev))
continue;
@@ -5800,8 +5827,11 @@ static void autostart_arrays(int part)
continue;
}
list_add(&rdev->same_set, &pending_raid_disks);
+ i_passed++;
}
- dev_cnt = 0;
+
+ printk(KERN_INFO "md: Scanned %d and added %d devices.\n",
+ i_scanned, i_passed);
autorun_devices(part);
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index f2a63f394ad..b35731cceac 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -194,35 +194,6 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
seq_printf (seq, "]");
}
-static int multipath_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- mddev_t *mddev = q->queuedata;
- multipath_conf_t *conf = mddev_to_conf(mddev);
- int i, ret = 0;
-
- rcu_read_lock();
- for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
- if (rdev && !test_bit(Faulty, &rdev->flags)) {
- struct block_device *bdev = rdev->bdev;
- struct request_queue *r_queue = bdev_get_queue(bdev);
-
- if (!r_queue->issue_flush_fn)
- ret = -EOPNOTSUPP;
- else {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
- error_sector);
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- }
- }
- }
- rcu_read_unlock();
- return ret;
-}
static int multipath_congested(void *data, int bits)
{
mddev_t *mddev = data;
@@ -527,7 +498,6 @@ static int multipath_run (mddev_t *mddev)
mddev->array_size = mddev->size;
mddev->queue->unplug_fn = multipath_unplug;
- mddev->queue->issue_flush_fn = multipath_issue_flush;
mddev->queue->backing_dev_info.congested_fn = multipath_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index ef0da2d8495..c111105fc2d 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -40,26 +40,6 @@ static void raid0_unplug(struct request_queue *q)
}
}
-static int raid0_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- mddev_t *mddev = q->queuedata;
- raid0_conf_t *conf = mddev_to_conf(mddev);
- mdk_rdev_t **devlist = conf->strip_zone[0].dev;
- int i, ret = 0;
-
- for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- struct block_device *bdev = devlist[i]->bdev;
- struct request_queue *r_queue = bdev_get_queue(bdev);
-
- if (!r_queue->issue_flush_fn)
- ret = -EOPNOTSUPP;
- else
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
- }
- return ret;
-}
-
static int raid0_congested(void *data, int bits)
{
mddev_t *mddev = data;
@@ -250,7 +230,6 @@ static int create_strip_zones (mddev_t *mddev)
mddev->queue->unplug_fn = raid0_unplug;
- mddev->queue->issue_flush_fn = raid0_issue_flush;
mddev->queue->backing_dev_info.congested_fn = raid0_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
@@ -493,7 +472,7 @@ bad_map:
bio_io_error(bio);
return 0;
}
-
+
static void raid0_status (struct seq_file *seq, mddev_t *mddev)
{
#undef MD_DEBUG
@@ -501,18 +480,18 @@ static void raid0_status (struct seq_file *seq, mddev_t *mddev)
int j, k, h;
char b[BDEVNAME_SIZE];
raid0_conf_t *conf = mddev_to_conf(mddev);
-
+
h = 0;
for (j = 0; j < conf->nr_strip_zones; j++) {
seq_printf(seq, " z%d", j);
if (conf->hash_table[h] == conf->strip_zone+j)
- seq_printf("(h%d)", h++);
+ seq_printf(seq, "(h%d)", h++);
seq_printf(seq, "=[");
for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
- seq_printf (seq, "%s/", bdevname(
+ seq_printf(seq, "%s/", bdevname(
conf->strip_zone[j].dev[k]->bdev,b));
- seq_printf (seq, "] zo=%d do=%d s=%d\n",
+ seq_printf(seq, "] zo=%d do=%d s=%d\n",
conf->strip_zone[j].zone_offset,
conf->strip_zone[j].dev_offset,
conf->strip_zone[j].size);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6d03bea6fa5..16775a0df7f 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -567,36 +567,6 @@ static void raid1_unplug(struct request_queue *q)
md_wakeup_thread(mddev->thread);
}
-static int raid1_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- mddev_t *mddev = q->queuedata;
- conf_t *conf = mddev_to_conf(mddev);
- int i, ret = 0;
-
- rcu_read_lock();
- for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
- if (rdev && !test_bit(Faulty, &rdev->flags)) {
- struct block_device *bdev = rdev->bdev;
- struct request_queue *r_queue = bdev_get_queue(bdev);
-
- if (!r_queue->issue_flush_fn)
- ret = -EOPNOTSUPP;
- else {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
- error_sector);
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- }
- }
- }
- rcu_read_unlock();
- return ret;
-}
-
static int raid1_congested(void *data, int bits)
{
mddev_t *mddev = data;
@@ -1244,7 +1214,8 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
j = 0;
if (j >= 0)
mddev->resync_mismatches += r1_bio->sectors;
- if (j < 0 || test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
+ if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
+ && test_bit(BIO_UPTODATE, &sbio->bi_flags))) {
sbio->bi_end_io = NULL;
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
} else {
@@ -1997,7 +1968,6 @@ static int run(mddev_t *mddev)
mddev->array_size = mddev->size;
mddev->queue->unplug_fn = raid1_unplug;
- mddev->queue->issue_flush_fn = raid1_issue_flush;
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 25a96c42bdb..fc6607acb6e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -611,36 +611,6 @@ static void raid10_unplug(struct request_queue *q)
md_wakeup_thread(mddev->thread);
}
-static int raid10_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- mddev_t *mddev = q->queuedata;
- conf_t *conf = mddev_to_conf(mddev);
- int i, ret = 0;
-
- rcu_read_lock();
- for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
- if (rdev && !test_bit(Faulty, &rdev->flags)) {
- struct block_device *bdev = rdev->bdev;
- struct request_queue *r_queue = bdev_get_queue(bdev);
-
- if (!r_queue->issue_flush_fn)
- ret = -EOPNOTSUPP;
- else {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
- error_sector);
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- }
- }
- }
- rcu_read_unlock();
- return ret;
-}
-
static int raid10_congested(void *data, int bits)
{
mddev_t *mddev = data;
@@ -2118,7 +2088,6 @@ static int run(mddev_t *mddev)
mddev->resync_max_sectors = size << conf->chunk_shift;
mddev->queue->unplug_fn = raid10_unplug;
- mddev->queue->issue_flush_fn = raid10_issue_flush;
mddev->queue->backing_dev_info.congested_fn = raid10_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index caaca9e178b..8ee181a01f5 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3204,36 +3204,6 @@ static void raid5_unplug_device(struct request_queue *q)
unplug_slaves(mddev);
}
-static int raid5_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- mddev_t *mddev = q->queuedata;
- raid5_conf_t *conf = mddev_to_conf(mddev);
- int i, ret = 0;
-
- rcu_read_lock();
- for (i=0; i<mddev->raid_disks && ret == 0; i++) {
- mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
- if (rdev && !test_bit(Faulty, &rdev->flags)) {
- struct block_device *bdev = rdev->bdev;
- struct request_queue *r_queue = bdev_get_queue(bdev);
-
- if (!r_queue->issue_flush_fn)
- ret = -EOPNOTSUPP;
- else {
- atomic_inc(&rdev->nr_pending);
- rcu_read_unlock();
- ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
- error_sector);
- rdev_dec_pending(rdev, mddev);
- rcu_read_lock();
- }
- }
- }
- rcu_read_unlock();
- return ret;
-}
-
static int raid5_congested(void *data, int bits)
{
mddev_t *mddev = data;
@@ -4263,7 +4233,6 @@ static int run(mddev_t *mddev)
mdname(mddev));
mddev->queue->unplug_fn = raid5_unplug_device;
- mddev->queue->issue_flush_fn = raid5_issue_flush;
mddev->queue->backing_dev_info.congested_data = mddev;
mddev->queue->backing_dev_info.congested_fn = raid5_congested;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index b203640ef1c..445f0266557 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -527,7 +527,8 @@ static int dvb_frontend_thread(void *data)
up(&fepriv->sem); /* is locked when we enter the thread... */
restart:
timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
- dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
+ dvb_frontend_should_wakeup(fe) || kthread_should_stop()
+ || freezing(current),
fepriv->delay);
if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 90c36c5705c..141dadf7cf1 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -7,7 +7,7 @@
* (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
* (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
* Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
- * Based on dummy.c by Jaroslav Kysela <perex@suse.cz>
+ * Based on dummy.c by Jaroslav Kysela <perex@perex.cz>
*
* 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/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 9eac65f34bf..dcf22a3b672 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -144,7 +144,7 @@ const static unsigned int palette2pixelformat[] = {
[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
};
-static unsigned int __attribute_pure__
+static unsigned int __pure
palette_to_pixelformat(unsigned int palette)
{
if (palette < ARRAY_SIZE(palette2pixelformat))
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index bdff950a54a..626bb3c9af2 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -293,7 +293,7 @@ nextSGEset:
for (ii=0; ii < (numSgeThisFrame-1); ii++) {
thisxfer = sg_dma_len(sg);
if (thisxfer == 0) {
- sg ++; /* Get next SG element from the OS */
+ sg = sg_next(sg); /* Get next SG element from the OS */
sg_done++;
continue;
}
@@ -301,7 +301,7 @@ nextSGEset:
v2 = sg_dma_address(sg);
mptscsih_add_sge(psge, sgflags | thisxfer, v2);
- sg++; /* Get next SG element from the OS */
+ sg = sg_next(sg); /* Get next SG element from the OS */
psge += (sizeof(u32) + sizeof(dma_addr_t));
sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
sg_done++;
@@ -322,7 +322,7 @@ nextSGEset:
v2 = sg_dma_address(sg);
mptscsih_add_sge(psge, sgflags | thisxfer, v2);
/*
- sg++;
+ sg = sg_next(sg);
psge += (sizeof(u32) + sizeof(dma_addr_t));
*/
sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
@@ -2605,14 +2605,10 @@ mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
}
/**
- * SCPNT_TO_LOOKUP_IDX
- *
- * search's for a given scmd in the ScsiLookup[] array list
- *
+ * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
* @ioc: Pointer to MPT_ADAPTER structure
- * @scmd: scsi_cmnd pointer
- *
- **/
+ * @sc: scsi_cmnd pointer
+ */
static int
SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
{
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 8c83ee3b092..ce8f1a34ed2 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -41,8 +41,6 @@
struct i2o_driver i2o_exec_driver;
-static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
-
/* global wait list for POST WAIT */
static LIST_HEAD(i2o_exec_wait_list);
@@ -369,6 +367,53 @@ static int i2o_exec_remove(struct device *dev)
return 0;
};
+#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES
+/**
+ * i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request
+ * @c: I2O controller to which the request should be send
+ * @change_ind: change indicator
+ *
+ * This function sends a LCT NOTIFY request to the I2O controller with
+ * the change indicator change_ind. If the change_ind == 0 the controller
+ * replies immediately after the request. If change_ind > 0 the reply is
+ * send after change indicator of the LCT is > change_ind.
+ */
+static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
+{
+ i2o_status_block *sb = c->status_block.virt;
+ struct device *dev;
+ struct i2o_message *msg;
+
+ mutex_lock(&c->lct_lock);
+
+ dev = &c->pdev->dev;
+
+ if (i2o_dma_realloc
+ (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL))
+ return -ENOMEM;
+
+ msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+ if (IS_ERR(msg))
+ return PTR_ERR(msg);
+
+ msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
+ msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 |
+ ADAPTER_TID);
+ msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
+ msg->u.s.tcntxt = cpu_to_le32(0x00000000);
+ msg->body[0] = cpu_to_le32(0xffffffff);
+ msg->body[1] = cpu_to_le32(change_ind);
+ msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len);
+ msg->body[3] = cpu_to_le32(c->dlct.phys);
+
+ i2o_msg_post(c, msg);
+
+ mutex_unlock(&c->lct_lock);
+
+ return 0;
+}
+#endif
+
/**
* i2o_exec_lct_modified - Called on LCT NOTIFY reply
* @_work: work struct for a specific controller
@@ -525,51 +570,6 @@ int i2o_exec_lct_get(struct i2o_controller *c)
return rc;
}
-/**
- * i2o_exec_lct_notify - Send a asynchronus LCT NOTIFY request
- * @c: I2O controller to which the request should be send
- * @change_ind: change indicator
- *
- * This function sends a LCT NOTIFY request to the I2O controller with
- * the change indicator change_ind. If the change_ind == 0 the controller
- * replies immediately after the request. If change_ind > 0 the reply is
- * send after change indicator of the LCT is > change_ind.
- */
-static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
-{
- i2o_status_block *sb = c->status_block.virt;
- struct device *dev;
- struct i2o_message *msg;
-
- mutex_lock(&c->lct_lock);
-
- dev = &c->pdev->dev;
-
- if (i2o_dma_realloc
- (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL))
- return -ENOMEM;
-
- msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
- msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 |
- ADAPTER_TID);
- msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
- msg->u.s.tcntxt = cpu_to_le32(0x00000000);
- msg->body[0] = cpu_to_le32(0xffffffff);
- msg->body[1] = cpu_to_le32(change_ind);
- msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len);
- msg->body[3] = cpu_to_le32(c->dlct.phys);
-
- i2o_msg_post(c, msg);
-
- mutex_unlock(&c->lct_lock);
-
- return 0;
-};
-
/* Exec OSM driver struct */
struct i2o_driver i2o_exec_driver = {
.name = OSM_NAME,
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 50b2c733441..d602ba6d541 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -149,29 +149,6 @@ static int i2o_block_device_flush(struct i2o_device *dev)
};
/**
- * i2o_block_issue_flush - device-flush interface for block-layer
- * @queue: the request queue of the device which should be flushed
- * @disk: gendisk
- * @error_sector: error offset
- *
- * Helper function to provide flush functionality to block-layer.
- *
- * Returns 0 on success or negative error code on failure.
- */
-
-static int i2o_block_issue_flush(struct request_queue * queue, struct gendisk *disk,
- sector_t * error_sector)
-{
- struct i2o_block_device *i2o_blk_dev = queue->queuedata;
- int rc = -ENODEV;
-
- if (likely(i2o_blk_dev))
- rc = i2o_block_device_flush(i2o_blk_dev->i2o_dev);
-
- return rc;
-}
-
-/**
* i2o_block_device_mount - Mount (load) the media of device dev
* @dev: I2O device which should receive the mount request
* @media_id: Media Identifier
@@ -1009,7 +986,6 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
}
blk_queue_prep_rq(queue, i2o_block_prep_req_fn);
- blk_queue_issue_flush_fn(queue, i2o_block_issue_flush);
gd->major = I2O_MAJOR;
gd->queue = queue;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 73e248fb2ff..346c44eff95 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -203,4 +203,16 @@ config THINKPAD_ACPI_BAY
If you are not sure, say Y here.
+config ATMEL_SSC
+ tristate "Device driver for Atmel SSC peripheral"
+ depends on AVR32 || ARCH_AT91
+ ---help---
+ This option enables device driver support for Atmel Syncronized
+ Serial Communication peripheral (SSC).
+
+ The SSC peripheral supports a wide variety of serial frame based
+ communications, i.e. I2S, SPI, etc.
+
+ If unsure, say N.
+
endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b5ce0e3dba8..a24c61475c2 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
+obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_LKDTM) += lkdtm.o
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
new file mode 100644
index 00000000000..058ccac700d
--- /dev/null
+++ b/drivers/misc/atmel-ssc.c
@@ -0,0 +1,174 @@
+/*
+ * Atmel SSC driver
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/atmel-ssc.h>
+
+/* Serialize access to ssc_list and user count */
+static DEFINE_SPINLOCK(user_lock);
+static LIST_HEAD(ssc_list);
+
+struct ssc_device *ssc_request(unsigned int ssc_num)
+{
+ int ssc_valid = 0;
+ struct ssc_device *ssc;
+
+ spin_lock(&user_lock);
+ list_for_each_entry(ssc, &ssc_list, list) {
+ if (ssc->pdev->id == ssc_num) {
+ ssc_valid = 1;
+ break;
+ }
+ }
+
+ if (!ssc_valid) {
+ spin_unlock(&user_lock);
+ dev_dbg(&ssc->pdev->dev, "could not find requested device\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ if (ssc->user) {
+ spin_unlock(&user_lock);
+ dev_dbg(&ssc->pdev->dev, "module busy\n");
+ return ERR_PTR(-EBUSY);
+ }
+ ssc->user++;
+ spin_unlock(&user_lock);
+
+ clk_enable(ssc->clk);
+
+ return ssc;
+}
+EXPORT_SYMBOL(ssc_request);
+
+void ssc_free(struct ssc_device *ssc)
+{
+ spin_lock(&user_lock);
+ if (ssc->user) {
+ ssc->user--;
+ clk_disable(ssc->clk);
+ } else {
+ dev_dbg(&ssc->pdev->dev, "device already free\n");
+ }
+ spin_unlock(&user_lock);
+}
+EXPORT_SYMBOL(ssc_free);
+
+static int __init ssc_probe(struct platform_device *pdev)
+{
+ int retval = 0;
+ struct resource *regs;
+ struct ssc_device *ssc;
+
+ ssc = kzalloc(sizeof(struct ssc_device), GFP_KERNEL);
+ if (!ssc) {
+ dev_dbg(&pdev->dev, "out of memory\n");
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!regs) {
+ dev_dbg(&pdev->dev, "no mmio resource defined\n");
+ retval = -ENXIO;
+ goto out_free;
+ }
+
+ ssc->clk = clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(ssc->clk)) {
+ dev_dbg(&pdev->dev, "no pclk clock defined\n");
+ retval = -ENXIO;
+ goto out_free;
+ }
+
+ ssc->pdev = pdev;
+ ssc->regs = ioremap(regs->start, regs->end - regs->start + 1);
+ if (!ssc->regs) {
+ dev_dbg(&pdev->dev, "ioremap failed\n");
+ retval = -EINVAL;
+ goto out_clk;
+ }
+
+ /* disable all interrupts */
+ clk_enable(ssc->clk);
+ ssc_writel(ssc->regs, IDR, ~0UL);
+ ssc_readl(ssc->regs, SR);
+ clk_disable(ssc->clk);
+
+ ssc->irq = platform_get_irq(pdev, 0);
+ if (!ssc->irq) {
+ dev_dbg(&pdev->dev, "could not get irq\n");
+ retval = -ENXIO;
+ goto out_unmap;
+ }
+
+ spin_lock(&user_lock);
+ list_add_tail(&ssc->list, &ssc_list);
+ spin_unlock(&user_lock);
+
+ platform_set_drvdata(pdev, ssc);
+
+ dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
+ ssc->regs, ssc->irq);
+
+ goto out;
+
+out_unmap:
+ iounmap(ssc->regs);
+out_clk:
+ clk_put(ssc->clk);
+out_free:
+ kfree(ssc);
+out:
+ return retval;
+}
+
+static int __devexit ssc_remove(struct platform_device *pdev)
+{
+ struct ssc_device *ssc = platform_get_drvdata(pdev);
+
+ spin_lock(&user_lock);
+ iounmap(ssc->regs);
+ clk_put(ssc->clk);
+ list_del(&ssc->list);
+ kfree(ssc);
+ spin_unlock(&user_lock);
+
+ return 0;
+}
+
+static struct platform_driver ssc_driver = {
+ .remove = __devexit_p(ssc_remove),
+ .driver = {
+ .name = "ssc",
+ },
+};
+
+static int __init ssc_init(void)
+{
+ return platform_driver_probe(&ssc_driver, ssc_probe);
+}
+module_init(ssc_init);
+
+static void __exit ssc_exit(void)
+{
+ platform_driver_unregister(&ssc_driver);
+}
+module_exit(ssc_exit);
+
+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
+MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 216948dd71a..81e068fa7ac 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -945,15 +945,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
- KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
+ KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
- KEY_RESERVED, /* 0x10: FN+END (brightness down) */
+ KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
- KEY_RESERVED, /* 0x14: VOLUME UP */
- KEY_RESERVED, /* 0x15: VOLUME DOWN */
- KEY_RESERVED, /* 0x16: MUTE */
+ KEY_VOLUMEUP, /* 0x14: VOLUME UP */
+ KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */
+ KEY_MUTE, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
@@ -974,9 +974,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
- KEY_RESERVED, /* 0x14: VOLUME UP */
- KEY_RESERVED, /* 0x15: VOLUME DOWN */
- KEY_RESERVED, /* 0x16: MUTE */
+ KEY_VOLUMEUP, /* 0x14: VOLUME UP */
+ KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */
+ KEY_MUTE, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index b0abc7d9280..a5d0354bbbd 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -153,14 +153,14 @@ 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 = kmalloc(sizeof(struct scatterlist),
+ mq->sg = kzalloc(sizeof(struct scatterlist),
GFP_KERNEL);
if (!mq->sg) {
ret = -ENOMEM;
goto cleanup_queue;
}
- mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
+ mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
bouncesz / 512, GFP_KERNEL);
if (!mq->bounce_sg) {
ret = -ENOMEM;
@@ -177,7 +177,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
blk_queue_max_segment_size(mq->queue, host->max_seg_size);
- mq->sg = kmalloc(sizeof(struct scatterlist) *
+ mq->sg = kzalloc(sizeof(struct scatterlist) *
host->max_phys_segs, GFP_KERNEL);
if (!mq->sg) {
ret = -ENOMEM;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 65fe28860f5..68c0e3b2f0e 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -213,7 +213,8 @@ static int mmc_read_ext_csd(struct mmc_card *card)
printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
"version %d\n", mmc_hostname(card->host),
ext_csd_struct);
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
if (ext_csd_struct >= 2) {
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 6ba98a49612..7a452c2ad1f 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -581,9 +581,7 @@ static void at91_mci_completed_command(struct at91mci_host *host)
pr_debug("Status = %08X [%08X %08X %08X %08X]\n",
status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
- if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
- AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
- AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
+ if (status & AT91_MCI_ERRORS) {
if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
cmd->error = 0;
}
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 254b194e762..7ae18eaed6c 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -30,6 +30,7 @@
#include <linux/dma-mapping.h>
#include <linux/crc7.h>
#include <linux/crc-itu-t.h>
+#include <linux/scatterlist.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h> /* for R1_SPI_* bit values */
@@ -1280,8 +1281,8 @@ static int mmc_spi_probe(struct spi_device *spi)
if (!host->data)
goto fail_nobuf1;
- if (spi->master->cdev.dev->dma_mask) {
- struct device *dev = spi->master->cdev.dev;
+ if (spi->master->dev.parent->dma_mask) {
+ struct device *dev = spi->master->dev.parent;
host->dma_dev = dev;
host->ones_dma = dma_map_single(dev, ones,
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 657901eecfc..0601e01aa2c 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -23,6 +23,8 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/mmc/host.h>
#include <asm/dma.h>
@@ -44,6 +46,8 @@ struct pxamci_host {
spinlock_t lock;
struct resource *res;
void __iomem *base;
+ struct clk *clk;
+ unsigned long clkrate;
int irq;
int dma;
unsigned int clkrt;
@@ -119,7 +123,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
writel(nob, host->base + MMC_NOB);
writel(data->blksz, host->base + MMC_BLKLEN);
- clks = (unsigned long long)data->timeout_ns * CLOCKRATE;
+ clks = (unsigned long long)data->timeout_ns * host->clkrate;
do_div(clks, 1000000000UL);
timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt);
writel((timeout + 255) / 256, host->base + MMC_RDTO);
@@ -365,18 +369,25 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
struct pxamci_host *host = mmc_priv(mmc);
if (ios->clock) {
- unsigned int clk = CLOCKRATE / ios->clock;
- if (CLOCKRATE / clk > ios->clock)
+ unsigned long rate = host->clkrate;
+ unsigned int clk = rate / ios->clock;
+
+ /*
+ * clk might result in a lower divisor than we
+ * desire. check for that condition and adjust
+ * as appropriate.
+ */
+ if (rate / clk > ios->clock)
clk <<= 1;
host->clkrt = fls(clk) - 1;
- pxa_set_cken(CKEN_MMC, 1);
+ clk_enable(host->clk);
/*
* we write clkrt on the next command
*/
} else {
pxamci_stop_clock(host);
- pxa_set_cken(CKEN_MMC, 0);
+ clk_disable(host->clk);
}
if (host->power_mode != ios->power_mode) {
@@ -462,8 +473,6 @@ static int pxamci_probe(struct platform_device *pdev)
}
mmc->ops = &pxamci_ops;
- mmc->f_min = CLOCKRATE_MIN;
- mmc->f_max = CLOCKRATE_MAX;
/*
* We can do SG-DMA, but we don't because we never know how much
@@ -490,6 +499,22 @@ static int pxamci_probe(struct platform_device *pdev)
host->mmc = mmc;
host->dma = -1;
host->pdata = pdev->dev.platform_data;
+
+ host->clk = clk_get(&pdev->dev, "MMCCLK");
+ if (IS_ERR(host->clk)) {
+ ret = PTR_ERR(host->clk);
+ host->clk = NULL;
+ goto out;
+ }
+
+ host->clkrate = clk_get_rate(host->clk);
+
+ /*
+ * Calculate minimum clock rate, rounding up.
+ */
+ mmc->f_min = (host->clkrate + 63) / 64;
+ mmc->f_max = host->clkrate;
+
mmc->ocr_avail = host->pdata ?
host->pdata->ocr_mask :
MMC_VDD_32_33|MMC_VDD_33_34;
@@ -554,6 +579,8 @@ static int pxamci_probe(struct platform_device *pdev)
iounmap(host->base);
if (host->sg_cpu)
dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+ if (host->clk)
+ clk_put(host->clk);
}
if (mmc)
mmc_free_host(mmc);
@@ -588,6 +615,8 @@ static int pxamci_remove(struct platform_device *pdev)
iounmap(host->base);
dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+ clk_put(host->clk);
+
release_resource(host->res);
mmc_free_host(mmc);
diff --git a/drivers/mmc/host/pxamci.h b/drivers/mmc/host/pxamci.h
index 3153e779d46..748c7706f23 100644
--- a/drivers/mmc/host/pxamci.h
+++ b/drivers/mmc/host/pxamci.h
@@ -88,17 +88,3 @@
#define MMC_RXFIFO 0x0040 /* 8 bit */
#define MMC_TXFIFO 0x0044 /* 8 bit */
-
-/*
- * The base MMC clock rate
- */
-#ifdef CONFIG_PXA27x
-#define CLOCKRATE_MIN 304688
-#define CLOCKRATE_MAX 19500000
-#else
-#define CLOCKRATE_MIN 312500
-#define CLOCKRATE_MAX 20000000
-#endif
-
-#define CLOCKRATE CLOCKRATE_MAX
-
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index cb933ac475d..82113295c26 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -14,20 +14,20 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <asm/io.h>
#include <asm/hardware.h>
+#include <asm/cacheflush.h>
#include <asm/mach/flash.h>
static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from,
ssize_t len)
{
- consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
+ flush_ioremap_region(map->phys, map->cached, from, len);
}
struct pxa2xx_flash_info {
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index b79a9cf2d16..21b921dd6aa 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -696,7 +696,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev,
info->clk = clk_get(&pdev->dev, "nand");
if (IS_ERR(info->clk)) {
- dev_err(&pdev->dev, "failed to get clock");
+ dev_err(&pdev->dev, "failed to get clock\n");
err = -ENOENT;
goto exit_error;
}
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 1297732f4db..880fa369035 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -933,8 +933,7 @@ write_error:
* @cache: the lock tree entry slab cache
* @flags: constructor flags
*/
-static void ltree_entry_ctor(void *obj, struct kmem_cache *cache,
- unsigned long flags)
+static void ltree_entry_ctor(struct kmem_cache *cache, void *obj)
{
struct ltree_entry *le = obj;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8d3893da06f..6f8e7d4cf74 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1491,7 +1491,7 @@ vortex_up(struct net_device *dev)
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
unsigned int config;
- int i, mii_reg1, mii_reg5, err;
+ int i, mii_reg1, mii_reg5, err = 0;
if (VORTEX_PCI(vp)) {
pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */
@@ -3118,7 +3118,13 @@ static void acpi_set_WOL(struct net_device *dev)
iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
iowrite16(RxEnable, ioaddr + EL3_CMD);
- pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+ if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
+ printk(KERN_INFO "%s: WOL not supported.\n",
+ pci_name(VORTEX_PCI(vp)));
+
+ vp->enable_wol = 0;
+ return;
+ }
/* Change the power state to D3; RxEnable doesn't take effect. */
pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9c635a237a9..2cafa5c1783 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -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
@@ -1780,6 +1765,15 @@ config SC92031
To compile this driver as a module, choose M here: the module
will be called sc92031. This is recommended.
+config CPMAC
+ tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
+ depends on NET_ETHERNET && EXPERIMENTAL && AR7
+ select PHYLIB
+ select FIXED_PHY
+ select FIXED_MII_100_FDX
+ help
+ TI AR7 CPMAC Ethernet support
+
config NET_POCKET
bool "Pocket and portable adapters"
depends on PARPORT
@@ -1994,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
@@ -2090,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
@@ -2101,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
@@ -2164,6 +2152,16 @@ config SKGE
To compile this driver as a module, choose M here: the module
will be called skge. This is recommended.
+config SKGE_DEBUG
+ bool "Debugging interface"
+ depends on SKGE && DEBUG_FS
+ help
+ This option adds the ability to dump driver state for debugging.
+ The file debugfs/skge/ethX displays the state of the internal
+ transmit and receive rings.
+
+ If unsure, say N.
+
config SKY2
tristate "SysKonnect Yukon2 support"
depends on PCI
@@ -2345,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
@@ -2357,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
@@ -2475,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.
@@ -2540,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
@@ -2565,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/Makefile b/drivers/net/Makefile
index d2e0f35da42..22f78cbd126 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
obj-$(CONFIG_8139TOO) += 8139too.o
obj-$(CONFIG_ZNET) += znet.o
obj-$(CONFIG_LAN_SAA9730) += saa9730.o
+obj-$(CONFIG_CPMAC) += cpmac.o
obj-$(CONFIG_DEPCA) += depca.o
obj-$(CONFIG_EWRK3) += ewrk3.o
obj-$(CONFIG_ATP) += atp.o
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index b46c5d8a77b..185f98e3964 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -54,13 +54,16 @@
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/phy.h>
+
+#include <asm/cpu.h>
#include <asm/mipsregs.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/processor.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/cpu.h>
+#include <au1000.h>
+#include <prom.h>
+
#include "au1000_eth.h"
#ifdef AU1000_ETH_DEBUG
@@ -96,11 +99,6 @@ static void mdio_write(struct net_device *, int, int, u16);
static void au1000_adjust_link(struct net_device *);
static void enable_mac(struct net_device *, int);
-// externs
-extern int get_ethernet_addr(char *ethernet_addr);
-extern void str2eaddr(unsigned char *ea, unsigned char *str);
-extern char * prom_getcmdline(void);
-
/*
* Theory of operation
*
@@ -619,7 +617,6 @@ static struct net_device * au1000_probe(int port_num)
struct au1000_private *aup = NULL;
struct net_device *dev = NULL;
db_dest_t *pDB, *pDBfree;
- char *pmac, *argptr;
char ethaddr[6];
int irq, i, err;
u32 base, macen;
@@ -677,21 +674,12 @@ static struct net_device * au1000_probe(int port_num)
au_macs[port_num] = aup;
if (port_num == 0) {
- /* Check the environment variables first */
- if (get_ethernet_addr(ethaddr) == 0)
+ if (prom_get_ethernet_addr(ethaddr) == 0)
memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
else {
- /* Check command line */
- argptr = prom_getcmdline();
- if ((pmac = strstr(argptr, "ethaddr=")) == NULL)
- printk(KERN_INFO "%s: No MAC address found\n",
- dev->name);
+ printk(KERN_INFO "%s: No MAC address found\n",
+ dev->name);
/* Use the hard coded MAC addresses */
- else {
- str2eaddr(ethaddr, pmac + strlen("ethaddr="));
- memcpy(au1000_mac_addr, ethaddr,
- sizeof(au1000_mac_addr));
- }
}
setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 9fe0517cf89..7495a9ee8f4 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -900,7 +900,7 @@ static int ax_probe(struct platform_device *pdev)
ax->map2 = ioremap(res->start, size);
if (ax->map2 == NULL) {
- dev_err(&pdev->dev, "cannot map reset register");
+ dev_err(&pdev->dev, "cannot map reset register\n");
ret = -ENXIO;
goto exit_mem2;
}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 78ed633ceb8..96cee4badd2 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -56,8 +56,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.6.7"
-#define DRV_MODULE_RELDATE "October 10, 2007"
+#define DRV_MODULE_VERSION "1.6.8"
+#define DRV_MODULE_RELDATE "October 17, 2007"
#define RUN_AT(x) (jiffies + (x))
@@ -3079,14 +3079,18 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
autoneg = bp->autoneg;
advertising = bp->advertising;
- bp->autoneg = AUTONEG_SPEED;
- bp->advertising = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_Autoneg;
+ if (bp->phy_port == PORT_TP) {
+ bp->autoneg = AUTONEG_SPEED;
+ bp->advertising = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_Autoneg;
+ }
- bnx2_setup_copper_phy(bp);
+ spin_lock_bh(&bp->phy_lock);
+ bnx2_setup_phy(bp, bp->phy_port);
+ spin_unlock_bh(&bp->phy_lock);
bp->autoneg = autoneg;
bp->advertising = advertising;
@@ -3097,10 +3101,16 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
/* Enable port mode. */
val &= ~BNX2_EMAC_MODE_PORT;
- val |= BNX2_EMAC_MODE_PORT_MII |
- BNX2_EMAC_MODE_MPKT_RCVD |
+ val |= BNX2_EMAC_MODE_MPKT_RCVD |
BNX2_EMAC_MODE_ACPI_RCVD |
BNX2_EMAC_MODE_MPKT;
+ if (bp->phy_port == PORT_TP)
+ val |= BNX2_EMAC_MODE_PORT_MII;
+ else {
+ val |= BNX2_EMAC_MODE_PORT_GMII;
+ if (bp->line_speed == SPEED_2500)
+ val |= BNX2_EMAC_MODE_25G_MODE;
+ }
REG_WR(bp, BNX2_EMAC_MODE, val);
@@ -6428,7 +6438,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
/* enable device (incl. PCI PM wakeup), and bus-mastering */
rc = pci_enable_device(pdev);
if (rc) {
- dev_err(&pdev->dev, "Cannot enable PCI device, aborting.");
+ dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
goto err_out;
}
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
index 5bd52bead9b..4b129b7cbfa 100644
--- a/drivers/net/bnx2_fw2.h
+++ b/drivers/net/bnx2_fw2.h
@@ -15,3248 +15,3270 @@
*/
static u8 bnx2_COM_b09FwText[] = {
-/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
- 0xdc, 0x5b,
- 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xef, 0xd9, 0xbb, 0xf2, 0x5a, 0x92,
- 0xe5, 0x6b, 0x79, 0x23, 0x16, 0x4b, 0xc0, 0xae, 0x75, 0x6d, 0x69, 0xb0,
- 0x43, 0x16, 0xa1, 0x80, 0x9a, 0xd9, 0xc0, 0xb2, 0x2b, 0x33, 0x9e, 0x0c,
- 0x69, 0x64, 0x50, 0x80, 0xb6, 0x4c, 0x46, 0xec, 0x1a, 0x9a, 0x4e, 0x87,
- 0xd6, 0xa6, 0x6e, 0x9b, 0xc9, 0x34, 0x78, 0x47, 0x1f, 0x8d, 0xa7, 0x15,
- 0xba, 0x06, 0x1b, 0xd9, 0xd3, 0xd0, 0xa0, 0x6a, 0x71, 0xf1, 0x8f, 0x8d,
- 0xaf, 0xf9, 0x48, 0xaa, 0x4c, 0x4d, 0xa5, 0x18, 0x48, 0x69, 0xa7, 0x4d,
- 0xfb, 0xa3, 0x9e, 0xa1, 0x5f, 0x84, 0x32, 0xfd, 0xc1, 0x74, 0xda, 0x4e,
- 0x3a, 0x24, 0x53, 0x08, 0x84, 0xed, 0xf3, 0x9c, 0x7b, 0xee, 0xea, 0x6a,
- 0x25, 0x7f, 0xf1, 0x91, 0x1f, 0xd5, 0xcc, 0xfa, 0xde, 0xf3, 0xfd, 0x9e,
- 0xf7, 0xbc, 0xef, 0xf3, 0x7e, 0xdc, 0xe3, 0x4f, 0x8a, 0xb4, 0x8a, 0xf9,
- 0xdb, 0x80, 0x5f, 0xfa, 0xc1, 0xdf, 0x2c, 0x5f, 0x37, 0x78, 0xdd, 0x0d,
- 0x78, 0xbd, 0x41, 0xc5, 0xec, 0x18, 0xeb, 0xf9, 0x4f, 0x12, 0xbf, 0x01,
- 0xf3, 0xbe, 0xd6, 0x9f, 0x83, 0xdf, 0x9b, 0x68, 0x1c, 0xfb, 0x0f, 0x11,
- 0xeb, 0x3c, 0x7d, 0xa2, 0x7f, 0xf5, 0xfa, 0x85, 0xdb, 0x15, 0x69, 0xb9,
- 0x40, 0x7b, 0x2c, 0x58, 0x52, 0xd3, 0xcc, 0x9f, 0x24, 0x54, 0x6e, 0xec,
- 0xe1, 0x82, 0x2b, 0x89, 0x58, 0x6e, 0xf7, 0xc1, 0xb2, 0x2b, 0x92, 0xaf,
- 0xed, 0x48, 0x17, 0xe5, 0x67, 0xf5, 0x4a, 0xd2, 0x16, 0xd6, 0x5f, 0x95,
- 0x7b, 0xef, 0xc9, 0x17, 0x6e, 0xca, 0xfc, 0x68, 0x2e, 0x26, 0x09, 0x27,
- 0xf7, 0xbc, 0x38, 0xdb, 0x25, 0xd1, 0x83, 0x31, 0x4f, 0xf4, 0xe5, 0x2d,
- 0xe9, 0x08, 0xe7, 0x7a, 0xb3, 0xfe, 0x42, 0x9f, 0x54, 0xb6, 0xe4, 0x12,
- 0xa2, 0x72, 0xdb, 0x5e, 0x2d, 0xc4, 0x9c, 0xb1, 0x58, 0xce, 0x91, 0x45,
- 0x5f, 0x46, 0xee, 0x9f, 0x96, 0x44, 0x22, 0xf7, 0xe5, 0xc4, 0xba, 0x6d,
- 0x92, 0xb0, 0x73, 0x4b, 0x0f, 0xff, 0xbe, 0x7b, 0xb0, 0xae, 0x5c, 0xb7,
- 0x7f, 0x5e, 0xda, 0x87, 0x4e, 0x0c, 0xa2, 0xbd, 0x96, 0xe9, 0x17, 0xb9,
- 0x49, 0x94, 0x5b, 0x69, 0x8f, 0xb9, 0x09, 0x29, 0xf8, 0xae, 0x14, 0x7d,
- 0x91, 0xbf, 0xac, 0x59, 0x72, 0xc2, 0xed, 0x92, 0xf9, 0x9d, 0xef, 0xd5,
- 0xf3, 0xa0, 0xe5, 0xfb, 0xee, 0xd2, 0xc3, 0x93, 0x2e, 0xe9, 0x3d, 0x90,
- 0x08, 0xe8, 0xdd, 0xbb, 0xae, 0xec, 0xda, 0x32, 0x5e, 0x63, 0xdd, 0xa8,
- 0x62, 0x5d, 0x3c, 0x97, 0x68, 0x3d, 0xe1, 0xb6, 0x9b, 0xba, 0x57, 0x6f,
- 0x29, 0x60, 0xbe, 0x89, 0x1a, 0xfb, 0xe6, 0xaf, 0x2f, 0xbb, 0x49, 0x53,
- 0xbf, 0x70, 0x63, 0xc1, 0x4d, 0xa1, 0xbe, 0xc7, 0xb4, 0x8d, 0x3d, 0x58,
- 0x76, 0x5d, 0xd3, 0xf6, 0x76, 0xac, 0xe0, 0xf6, 0x9b, 0xfa, 0xf7, 0x6e,
- 0x2e, 0xbb, 0x3b, 0x4d, 0x7d, 0x0f, 0xe6, 0xca, 0x9a, 0xfa, 0x85, 0x7b,
- 0xca, 0xee, 0xa0, 0xa9, 0xdf, 0x7d, 0x73, 0xc1, 0x1d, 0x32, 0xf5, 0x89,
- 0xa1, 0xb2, 0x9b, 0x43, 0xfd, 0x97, 0x13, 0x6a, 0x9b, 0x23, 0x53, 0xb5,
- 0x34, 0x7e, 0x79, 0xb4, 0x0d, 0xa3, 0x6e, 0x37, 0x7e, 0xb7, 0xe3, 0xf7,
- 0xc8, 0x46, 0xe9, 0x18, 0xc1, 0xf3, 0xbf, 0xba, 0x03, 0xde, 0x81, 0x47,
- 0x5e, 0x42, 0x5e, 0x8f, 0xa5, 0xe4, 0x85, 0xbe, 0xd7, 0xc1, 0x43, 0x47,
- 0x4e, 0xfb, 0x62, 0x8d, 0xf4, 0xa5, 0xc0, 0xbb, 0xa4, 0x3c, 0xe3, 0xb7,
- 0x49, 0xec, 0xb1, 0x18, 0x78, 0xf3, 0xcb, 0x52, 0x4a, 0x26, 0x64, 0xd3,
- 0xac, 0x25, 0x5b, 0x07, 0x12, 0x92, 0x77, 0xb8, 0x36, 0x4e, 0x7b, 0x26,
- 0x29, 0xb1, 0xd9, 0xfc, 0x66, 0x25, 0xdb, 0x9c, 0xa2, 0x54, 0xc0, 0xbb,
- 0x57, 0x29, 0x97, 0x68, 0x4b, 0x4b, 0x71, 0xfa, 0x5a, 0x19, 0x73, 0x48,
- 0xd7, 0x1f, 0x5c, 0x15, 0xac, 0x95, 0xb0, 0x0a, 0xc7, 0x46, 0x65, 0xca,
- 0x6b, 0xb7, 0x8a, 0xc7, 0x6e, 0x96, 0x42, 0x56, 0x92, 0x18, 0x97, 0x2a,
- 0xa1, 0xa5, 0x5a, 0x1b, 0x95, 0x49, 0x4f, 0xac, 0x82, 0x47, 0x7e, 0x76,
- 0xa1, 0xbd, 0x43, 0xf7, 0x45, 0x5d, 0x4f, 0x4c, 0xcf, 0x9d, 0x40, 0xbd,
- 0x83, 0xfa, 0x4e, 0x6b, 0x58, 0xcf, 0xa1, 0xeb, 0xd3, 0x13, 0xd2, 0x2e,
- 0x4f, 0xd5, 0x92, 0xa6, 0x6f, 0xbd, 0x5e, 0xc8, 0x3a, 0xe8, 0x37, 0x2a,
- 0x13, 0x5e, 0x52, 0xc6, 0xf0, 0x1c, 0xf7, 0xb8, 0x7e, 0x0a, 0x32, 0x75,
- 0xdd, 0xc1, 0xd2, 0x51, 0x3d, 0x5f, 0x3a, 0x96, 0xe3, 0x7c, 0x3d, 0xe8,
- 0xf7, 0x12, 0xe8, 0xb2, 0xc4, 0xd6, 0x67, 0x99, 0x97, 0xd2, 0xb4, 0x05,
- 0x79, 0xc3, 0x53, 0xf3, 0x75, 0x18, 0xf4, 0xdb, 0xe2, 0x0e, 0x58, 0x52,
- 0xc6, 0x59, 0x55, 0x1c, 0x94, 0x6b, 0x0b, 0xaa, 0xe0, 0xad, 0x93, 0xa2,
- 0x9d, 0x96, 0xd8, 0x0c, 0x65, 0x69, 0x4c, 0x26, 0x30, 0x46, 0xb9, 0xec,
- 0xf3, 0x0e, 0xf6, 0x3d, 0xa6, 0xcf, 0xa1, 0x25, 0x57, 0x51, 0x45, 0xbf,
- 0x4b, 0xd4, 0xec, 0xbd, 0xf2, 0xd2, 0xb4, 0x38, 0x38, 0xc7, 0x7a, 0xc1,
- 0x9d, 0x54, 0x85, 0xa7, 0x6d, 0x89, 0xcf, 0x58, 0x32, 0xe9, 0x66, 0xa0,
- 0x01, 0x87, 0xd4, 0x2e, 0x7f, 0x01, 0xfd, 0x38, 0x0e, 0xfd, 0x6a, 0x0a,
- 0x7c, 0xe5, 0xfb, 0x0e, 0x47, 0x69, 0x79, 0x66, 0x1f, 0x9c, 0x01, 0xf6,
- 0xf1, 0x8c, 0x87, 0x33, 0xd1, 0x67, 0x94, 0xc6, 0x19, 0x89, 0x35, 0xdc,
- 0x07, 0x99, 0x3a, 0x6a, 0x4b, 0x29, 0x8b, 0x7d, 0xa1, 0x77, 0x29, 0xbb,
- 0x4c, 0xd7, 0xc4, 0x74, 0x33, 0x5d, 0x1c, 0x47, 0xba, 0x02, 0x9a, 0xc6,
- 0x8f, 0x92, 0xbe, 0x65, 0x7a, 0xa6, 0xa6, 0x43, 0x1a, 0xb9, 0x1e, 0x69,
- 0x0b, 0xe9, 0xe2, 0x38, 0xd2, 0xb5, 0x99, 0x67, 0xcd, 0x3f, 0x6b, 0x18,
- 0x74, 0x4c, 0x78, 0x36, 0xce, 0xa8, 0x5d, 0x4a, 0x4e, 0xc5, 0x9a, 0x18,
- 0xda, 0x91, 0x82, 0x36, 0x5b, 0xe3, 0x43, 0xa4, 0xd9, 0xc5, 0x39, 0xb6,
- 0xe8, 0xf3, 0x56, 0xb9, 0x49, 0xf2, 0x0e, 0xfd, 0xb9, 0x3e, 0xde, 0x6b,
- 0x8e, 0x4c, 0xea, 0xf9, 0x48, 0xd3, 0x47, 0x31, 0x0f, 0x69, 0x7d, 0x05,
- 0xb2, 0x3a, 0x08, 0x19, 0xcd, 0xca, 0x5f, 0xf8, 0x3b, 0xe5, 0xcf, 0xfc,
- 0x7e, 0xf9, 0x0e, 0xf4, 0xf6, 0xdb, 0x7e, 0x5a, 0x9e, 0xf7, 0x7b, 0xe4,
- 0x39, 0x3f, 0x25, 0xcf, 0x6a, 0xf9, 0x1d, 0x16, 0xe9, 0xa0, 0x4c, 0xa7,
- 0xa5, 0x13, 0xfa, 0xb3, 0x09, 0xba, 0xf9, 0x38, 0xf8, 0x77, 0xb4, 0x4f,
- 0xf2, 0x9b, 0x73, 0x92, 0xb8, 0x1a, 0xbf, 0x2b, 0xf0, 0xeb, 0xca, 0xd9,
- 0x5a, 0x56, 0xec, 0x1c, 0x79, 0x68, 0x4b, 0x51, 0xef, 0xd9, 0x96, 0x09,
- 0xff, 0x91, 0xab, 0x03, 0xd9, 0x15, 0x19, 0x01, 0x8f, 0xd5, 0xc0, 0x4f,
- 0xea, 0x79, 0x07, 0xfb, 0x18, 0xd8, 0xa1, 0x79, 0xaf, 0x06, 0x28, 0xb3,
- 0x69, 0xc8, 0xbd, 0x6d, 0x15, 0xbd, 0x93, 0xc0, 0x8d, 0x36, 0xab, 0x70,
- 0xa4, 0x22, 0xe5, 0x23, 0x75, 0x29, 0x67, 0xe3, 0xf2, 0x90, 0x53, 0x97,
- 0xe1, 0x6c, 0x8b, 0xec, 0x77, 0xc0, 0xfb, 0x9d, 0xbf, 0x6d, 0x85, 0x98,
- 0xfd, 0xb8, 0xff, 0x3b, 0x78, 0x67, 0x9d, 0xc8, 0x51, 0xfd, 0x1e, 0xd4,
- 0x57, 0xfc, 0xb8, 0xe4, 0x93, 0x95, 0x94, 0x2d, 0x5b, 0x54, 0xb0, 0xee,
- 0x78, 0xd8, 0x06, 0x7e, 0x2c, 0x01, 0x27, 0x33, 0x5a, 0x5f, 0x4a, 0xd3,
- 0xeb, 0xdf, 0xce, 0xeb, 0x6a, 0xf4, 0x77, 0x06, 0xe5, 0xac, 0xe6, 0x67,
- 0x7a, 0xcc, 0xca, 0x25, 0x65, 0x6b, 0x8d, 0xe5, 0x21, 0xeb, 0x4e, 0x9f,
- 0xf2, 0x8c, 0x77, 0x9f, 0x74, 0x5e, 0x89, 0x7e, 0x36, 0x9e, 0x79, 0x43,
- 0x6f, 0x94, 0x46, 0xce, 0x43, 0x1a, 0xf9, 0xfc, 0x66, 0x84, 0xc6, 0x27,
- 0x1b, 0xef, 0x47, 0x23, 0xef, 0x15, 0xff, 0x8f, 0x5a, 0x03, 0xda, 0x86,
- 0xe4, 0x8d, 0x99, 0xaf, 0x98, 0x75, 0xf0, 0x7e, 0x8a, 0xf3, 0x7f, 0xab,
- 0x1e, 0xc8, 0x4b, 0xe5, 0x22, 0xeb, 0x2c, 0x44, 0xd6, 0xf9, 0x6e, 0x64,
- 0x9d, 0xef, 0x46, 0xd6, 0xa9, 0x80, 0xa7, 0xb2, 0x51, 0x41, 0x86, 0x4b,
- 0x34, 0x63, 0x72, 0x08, 0x73, 0xbe, 0x2e, 0xb1, 0x1c, 0xf5, 0x3c, 0xc4,
- 0x9b, 0x73, 0xe8, 0x9f, 0x93, 0xb3, 0x33, 0x15, 0x29, 0x1d, 0x89, 0xcb,
- 0x1d, 0xba, 0xdf, 0x26, 0x43, 0x5f, 0xb4, 0x2d, 0x21, 0x7b, 0x92, 0x7c,
- 0x0f, 0xdb, 0x6c, 0xf0, 0x99, 0xe5, 0x6f, 0x5d, 0x19, 0x94, 0xf9, 0xbe,
- 0x60, 0xf6, 0x32, 0x1a, 0x8c, 0x3b, 0xf5, 0xa6, 0xc6, 0xc3, 0x45, 0x9f,
- 0xb8, 0x25, 0xd9, 0x98, 0x2b, 0xfb, 0x86, 0xb3, 0x5d, 0x32, 0xe1, 0x58,
- 0xd9, 0xf1, 0xfe, 0x75, 0xd4, 0x8b, 0xbc, 0x72, 0xdb, 0x80, 0x0d, 0x92,
- 0x56, 0xc4, 0x7c, 0xbd, 0x2f, 0x4b, 0x05, 0xf4, 0x3b, 0x2c, 0x8f, 0x28,
- 0xb7, 0xb3, 0xa9, 0x9e, 0xba, 0x1d, 0xc3, 0x3b, 0x65, 0x78, 0x97, 0x39,
- 0x63, 0x1b, 0x65, 0xe2, 0xf0, 0x35, 0xa6, 0x1c, 0xb6, 0x6f, 0xb6, 0x57,
- 0x96, 0xcf, 0x76, 0xaf, 0x2c, 0x87, 0x38, 0x11, 0xc5, 0x70, 0xee, 0x15,
- 0xf8, 0xe4, 0x52, 0xee, 0xe2, 0xa0, 0x35, 0x0b, 0x9d, 0x5b, 0x67, 0x68,
- 0xb8, 0xc2, 0xd0, 0x00, 0x5a, 0xfb, 0x20, 0x59, 0x5a, 0x97, 0xb4, 0x68,
- 0x35, 0x95, 0xc9, 0xfb, 0xf0, 0x7d, 0x83, 0x6e, 0x0f, 0x74, 0x2e, 0x7c,
- 0x86, 0xf8, 0xfe, 0x66, 0xc4, 0x5e, 0xf4, 0x40, 0x67, 0x93, 0xe0, 0x55,
- 0x88, 0xf5, 0xc4, 0xe0, 0x14, 0xec, 0x03, 0x64, 0x55, 0x63, 0x7b, 0x3b,
- 0xf0, 0xd0, 0x36, 0xd8, 0x9c, 0x30, 0xd8, 0xdc, 0x0e, 0x5c, 0x66, 0xd9,
- 0x31, 0xe5, 0xa4, 0x29, 0xa7, 0x50, 0x86, 0x1d, 0x9f, 0x25, 0x2e, 0x5f,
- 0x77, 0x70, 0xef, 0x51, 0x8d, 0xf7, 0xb4, 0x15, 0x40, 0x61, 0xe2, 0x35,
- 0x71, 0xbb, 0x47, 0xe6, 0x6b, 0x58, 0xaf, 0x81, 0x8d, 0xdc, 0x7b, 0x94,
- 0x1e, 0xd2, 0xb2, 0x5e, 0x14, 0x6c, 0x57, 0x3e, 0x49, 0x7a, 0x1f, 0xc4,
- 0xde, 0x89, 0x3f, 0xa4, 0xfb, 0x2a, 0xd0, 0xca, 0x7d, 0xfc, 0x3c, 0x69,
- 0xe5, 0x7a, 0xcd, 0xf4, 0x7e, 0x58, 0x1c, 0x24, 0xed, 0x27, 0xb1, 0xe7,
- 0x3c, 0x30, 0x4f, 0xac, 0xd1, 0xbe, 0x51, 0xec, 0x79, 0x04, 0x78, 0x78,
- 0x3b, 0xf0, 0x70, 0x37, 0xf0, 0x70, 0x18, 0x78, 0x98, 0x03, 0x16, 0x0e,
- 0x01, 0x0b, 0x07, 0x81, 0x85, 0x59, 0xf0, 0x26, 0x29, 0x73, 0xc0, 0xc6,
- 0x39, 0x60, 0xe4, 0x1c, 0xe6, 0x18, 0x9f, 0x15, 0xeb, 0x4b, 0xd8, 0xc3,
- 0x63, 0x33, 0x99, 0x93, 0x90, 0xa5, 0x54, 0x45, 0x41, 0xfe, 0xb3, 0x43,
- 0x90, 0xed, 0x7e, 0xa9, 0xfa, 0xb6, 0x94, 0x69, 0x53, 0xb7, 0xf7, 0x42,
- 0xd7, 0x20, 0xef, 0x29, 0x31, 0x7f, 0x1b, 0xcc, 0xf3, 0x1f, 0x45, 0xdc,
- 0xbf, 0xa3, 0x2c, 0xa6, 0x45, 0xce, 0x48, 0xc9, 0xeb, 0x75, 0x0a, 0xaa,
- 0x1f, 0xfd, 0x58, 0xce, 0xaa, 0xfb, 0x8f, 0x5c, 0xaf, 0xf6, 0x1e, 0x21,
- 0x5f, 0xa6, 0x81, 0x57, 0x75, 0x99, 0xcc, 0x52, 0xb7, 0xea, 0x72, 0x22,
- 0x9b, 0x19, 0xaa, 0x48, 0x9b, 0x4c, 0x25, 0xa7, 0xb5, 0xad, 0xb5, 0x73,
- 0x87, 0xb5, 0xbd, 0x2a, 0xbb, 0x78, 0xd6, 0x06, 0x54, 0xe9, 0x08, 0xf7,
- 0xdf, 0x8b, 0x5f, 0x1c, 0xb4, 0x70, 0x7e, 0x5b, 0x86, 0x07, 0x1d, 0xf5,
- 0x40, 0x5f, 0x05, 0x08, 0x96, 0x71, 0xce, 0x62, 0xe5, 0xe2, 0x74, 0x6f,
- 0xaa, 0xa8, 0x6c, 0x19, 0xb3, 0x2d, 0x19, 0x87, 0x7c, 0x0f, 0x67, 0xdf,
- 0xa9, 0x4f, 0x25, 0xd9, 0xbe, 0x4e, 0xbe, 0xae, 0x7d, 0x0e, 0xac, 0x5d,
- 0x3d, 0x8a, 0x75, 0xe3, 0x38, 0x03, 0xae, 0xcb, 0x79, 0x50, 0xae, 0xd9,
- 0x28, 0x67, 0x4e, 0x56, 0xc4, 0x87, 0x9e, 0x6c, 0x94, 0xc2, 0xce, 0x16,
- 0xc9, 0x8f, 0xa4, 0x65, 0x7c, 0xc6, 0x07, 0x4e, 0xe1, 0x1c, 0xdd, 0x56,
- 0x29, 0x8d, 0xa6, 0xe5, 0xd1, 0x19, 0xd6, 0x9d, 0xc6, 0xfe, 0x33, 0x87,
- 0xf2, 0xc2, 0xfd, 0xc7, 0xf5, 0xbe, 0xd2, 0xea, 0xb4, 0xec, 0xf7, 0xde,
- 0x30, 0x7a, 0x14, 0x94, 0xef, 0xc7, 0x99, 0x9e, 0xf0, 0x17, 0xb0, 0x7f,
- 0x57, 0xe6, 0x81, 0xff, 0xc5, 0x23, 0xc0, 0x41, 0xb7, 0x03, 0x98, 0x95,
- 0x59, 0xa0, 0x4d, 0x8d, 0xc1, 0xef, 0xab, 0x6a, 0x5e, 0xf7, 0xc8, 0x91,
- 0x19, 0x25, 0xdf, 0xbe, 0x31, 0x8d, 0x32, 0xb0, 0x31, 0x9b, 0x39, 0x3d,
- 0xa6, 0x7a, 0xe4, 0x86, 0xce, 0x14, 0xc6, 0xe5, 0x54, 0xc9, 0xdb, 0x18,
- 0x03, 0x2f, 0x8f, 0xa7, 0x15, 0xfb, 0x2a, 0x29, 0x66, 0x63, 0x38, 0xff,
- 0x0a, 0xfa, 0xbf, 0x8f, 0xf5, 0x7a, 0x64, 0x16, 0xbe, 0xd6, 0xec, 0x4c,
- 0x1e, 0xe3, 0x88, 0x5d, 0x99, 0xe3, 0x4b, 0x0a, 0x18, 0x33, 0x0b, 0xf9,
- 0x1e, 0x85, 0x2f, 0x33, 0x03, 0xd1, 0x69, 0x4d, 0xe3, 0x4c, 0x7b, 0x9d,
- 0x71, 0xe0, 0x41, 0xbe, 0x87, 0xef, 0x9c, 0xd3, 0x95, 0x13, 0x1e, 0xe5,
- 0x30, 0x2d, 0x4f, 0xf9, 0x1c, 0xd7, 0xbb, 0xf0, 0x1c, 0x7c, 0x9f, 0xdf,
- 0xf5, 0xae, 0x44, 0xff, 0x77, 0xe1, 0x07, 0x3b, 0x52, 0xc5, 0xb9, 0x95,
- 0xc1, 0xcb, 0x7c, 0x2a, 0x28, 0x8f, 0xcf, 0x66, 0x16, 0xde, 0x50, 0x7c,
- 0x77, 0x2b, 0xf3, 0xea, 0x5a, 0x91, 0x4e, 0xf2, 0x33, 0x0b, 0x5e, 0xba,
- 0x8e, 0x52, 0xdb, 0x8d, 0xef, 0x47, 0x3d, 0x72, 0x41, 0x9f, 0x2d, 0xf3,
- 0x03, 0x51, 0x3d, 0xa2, 0x3d, 0x0c, 0xf5, 0x28, 0x93, 0x5a, 0x52, 0x0a,
- 0xed, 0xb6, 0x1c, 0xd6, 0x65, 0x0b, 0xb4, 0x66, 0x52, 0xdc, 0xdf, 0x44,
- 0xad, 0x5f, 0x9e, 0xf2, 0xd8, 0x1f, 0x7c, 0x9e, 0x6e, 0x37, 0xfd, 0x4f,
- 0x83, 0x87, 0xf4, 0xdf, 0xfa, 0x41, 0x73, 0xa0, 0x5b, 0xf3, 0xd3, 0x49,
- 0xdd, 0x36, 0xe5, 0x05, 0x7e, 0x9a, 0x82, 0x2f, 0x37, 0x07, 0x5f, 0xae,
- 0xa8, 0xf5, 0xcc, 0xc9, 0xc3, 0xd7, 0x87, 0x9e, 0x04, 0x3a, 0x56, 0xad,
- 0x91, 0x96, 0xbb, 0x40, 0x5f, 0xa6, 0x02, 0x62, 0x0e, 0xab, 0x1c, 0xce,
- 0x7d, 0x50, 0x2a, 0xf4, 0xf7, 0xce, 0xc6, 0x9e, 0x92, 0xb1, 0x2a, 0xed,
- 0x11, 0x7e, 0x9e, 0xeb, 0x30, 0xbe, 0xc8, 0x6b, 0x5b, 0xd1, 0x0d, 0x39,
- 0x80, 0x1d, 0xc9, 0x6e, 0x32, 0x7e, 0xce, 0x13, 0x38, 0xcf, 0x33, 0x38,
- 0xf7, 0x9a, 0xec, 0x3d, 0xf6, 0x0a, 0x65, 0xba, 0xbf, 0x2a, 0x99, 0xfe,
- 0x29, 0xd9, 0xe1, 0xcc, 0x43, 0x1f, 0xf3, 0xa3, 0xf5, 0x5b, 0x54, 0x8e,
- 0x63, 0x0e, 0x62, 0x0c, 0x9e, 0xd5, 0x57, 0xe4, 0x21, 0x9f, 0x75, 0x0f,
- 0x81, 0x9f, 0xd0, 0x95, 0xc1, 0x27, 0x8c, 0x1e, 0x60, 0x3e, 0x3b, 0x9c,
- 0xef, 0x15, 0x33, 0x1f, 0xfb, 0xb1, 0x0f, 0xc7, 0x2c, 0xcf, 0xbb, 0x8b,
- 0xb6, 0x08, 0x78, 0xb4, 0x4b, 0xd5, 0x6f, 0x89, 0xa3, 0xfd, 0xc4, 0x20,
- 0xdf, 0x31, 0x0f, 0x6c, 0x91, 0xe3, 0x9e, 0x41, 0x5f, 0xf8, 0x7a, 0xde,
- 0x7a, 0x29, 0x74, 0x85, 0xf4, 0x52, 0x06, 0xe8, 0x27, 0x68, 0x1b, 0xbc,
- 0x39, 0xe0, 0xfd, 0x1f, 0xc6, 0x02, 0x99, 0x3c, 0x80, 0x32, 0xf5, 0xef,
- 0x80, 0x14, 0xbd, 0x0c, 0xf6, 0x09, 0x1d, 0xf3, 0x3b, 0xac, 0x60, 0x8f,
- 0xe0, 0xff, 0xc8, 0x39, 0xf0, 0x41, 0x2a, 0x01, 0x6f, 0xc8, 0x17, 0xf2,
- 0xa4, 0x03, 0xb2, 0x0f, 0xb9, 0x87, 0xdc, 0x96, 0x34, 0x0f, 0xfe, 0xbd,
- 0x33, 0xf0, 0x8b, 0x33, 0x95, 0x3c, 0xe3, 0xb9, 0x4e, 0xe2, 0x26, 0x30,
- 0xcc, 0x87, 0x70, 0x60, 0xee, 0x25, 0xb5, 0x9e, 0xf4, 0xa6, 0x97, 0x62,
- 0x7d, 0x2c, 0xf7, 0x2f, 0x41, 0x86, 0xab, 0x38, 0x9f, 0xc2, 0xce, 0x5e,
- 0x83, 0x5b, 0xcf, 0xc6, 0x28, 0xaf, 0x55, 0x60, 0x4c, 0xc9, 0xdb, 0xe1,
- 0xdc, 0x4d, 0xbe, 0x39, 0x8e, 0x3c, 0xe7, 0x45, 0xb1, 0x03, 0xb6, 0xcf,
- 0xa5, 0x1c, 0x26, 0x21, 0x07, 0x36, 0x6c, 0x68, 0x0a, 0x67, 0xfe, 0x6f,
- 0x9d, 0xc1, 0x5e, 0xf8, 0x6e, 0xcb, 0x9c, 0x83, 0x35, 0xbd, 0xc5, 0x8d,
- 0x41, 0x1d, 0xdf, 0xb7, 0xf0, 0x8c, 0x0e, 0xaf, 0xa4, 0x9d, 0xe7, 0xdb,
- 0x7c, 0xa6, 0x27, 0xb0, 0x17, 0xd6, 0xe3, 0x59, 0x3d, 0x2e, 0x7b, 0x89,
- 0x9b, 0x83, 0xdb, 0x52, 0x2f, 0xa2, 0x7f, 0x11, 0x36, 0xa1, 0x62, 0xb3,
- 0xed, 0x6d, 0x6b, 0x79, 0x8c, 0xa2, 0x5f, 0x0a, 0x1f, 0x78, 0xc9, 0xfa,
- 0x92, 0xff, 0x92, 0x55, 0xa8, 0xbe, 0x6d, 0x15, 0x21, 0x27, 0x55, 0x8f,
- 0xf1, 0x0b, 0xf5, 0xc7, 0xc1, 0xda, 0x99, 0xd4, 0x5b, 0xaa, 0x37, 0x3d,
- 0x0f, 0x2c, 0xb8, 0x1f, 0x3a, 0x5d, 0xb4, 0x17, 0xa4, 0xec, 0xd7, 0xa4,
- 0x74, 0x6c, 0x07, 0xf4, 0x2d, 0x1d, 0xa1, 0x8b, 0x78, 0x56, 0xa1, 0x1f,
- 0x6e, 0xed, 0xf2, 0xa4, 0xd2, 0x92, 0x23, 0xae, 0x6d, 0x83, 0xec, 0xa0,
- 0xae, 0xb6, 0x2c, 0x7f, 0xb7, 0xad, 0xa2, 0x15, 0xb1, 0xee, 0xe0, 0x4a,
- 0x7a, 0xab, 0x72, 0x71, 0x7a, 0x77, 0x35, 0xe8, 0x25, 0x66, 0x00, 0xff,
- 0x3d, 0xe0, 0xbf, 0x07, 0xfc, 0xf7, 0x80, 0xff, 0x1e, 0xf0, 0xdf, 0x83,
- 0x6d, 0xf0, 0x60, 0x03, 0x3c, 0xd8, 0x00, 0x0f, 0x36, 0xc0, 0x83, 0x0d,
- 0xf0, 0x0a, 0x38, 0x27, 0xe2, 0x3c, 0x6d, 0xc8, 0x3d, 0x0d, 0xbb, 0x19,
- 0xf8, 0x39, 0x57, 0x1a, 0xdf, 0x01, 0xfa, 0xe7, 0x6c, 0x91, 0xf1, 0xfe,
- 0x2b, 0xb0, 0xb7, 0x56, 0x3c, 0xdb, 0xf0, 0xc4, 0x1a, 0xfd, 0x9f, 0x35,
- 0x7a, 0xf2, 0x55, 0xd0, 0xa5, 0x50, 0xfe, 0x05, 0xc8, 0x61, 0x0b, 0xe8,
- 0xf9, 0x94, 0xf1, 0x31, 0xbe, 0x61, 0x07, 0x72, 0xd8, 0x86, 0xba, 0xcf,
- 0xa0, 0xae, 0x0d, 0x7d, 0xf6, 0xa3, 0x0f, 0x7d, 0x94, 0x0e, 0x53, 0x17,
- 0xed, 0x47, 0x5f, 0xe5, 0x0b, 0x58, 0x2b, 0x83, 0x7e, 0x1d, 0x98, 0xbb,
- 0x07, 0x7d, 0x6e, 0x46, 0x9f, 0xab, 0x50, 0xa6, 0x6f, 0xdb, 0x8d, 0xf2,
- 0xa7, 0x9b, 0xc6, 0x5c, 0x83, 0xba, 0xcf, 0x36, 0xd5, 0x9d, 0x45, 0x1d,
- 0x62, 0x62, 0xe7, 0x45, 0x33, 0xae, 0x82, 0x72, 0x57, 0x53, 0x9f, 0x57,
- 0x50, 0x37, 0x84, 0xba, 0xbf, 0xc2, 0x13, 0xb1, 0xb0, 0x43, 0x9a, 0xc2,
- 0x36, 0xfa, 0xa9, 0x69, 0xd4, 0xc7, 0x8d, 0xaf, 0xf9, 0x24, 0x7d, 0x2f,
- 0xd8, 0xdc, 0x3f, 0xb6, 0x03, 0xdf, 0x0c, 0xde, 0xab, 0x96, 0xc3, 0xb0,
- 0xfc, 0xcd, 0xa6, 0x32, 0xfb, 0x7e, 0xbf, 0xa9, 0xae, 0x6d, 0xd3, 0xca,
- 0xf2, 0x4f, 0xe3, 0xab, 0xc7, 0xdc, 0xdb, 0xd4, 0xe7, 0xeb, 0x9d, 0x2b,
- 0xcb, 0xbb, 0x5b, 0x56, 0x8f, 0xd9, 0xbe, 0x71, 0x65, 0xdd, 0xad, 0x9b,
- 0x57, 0x96, 0xe9, 0x03, 0x26, 0x11, 0xc3, 0x84, 0xfd, 0x77, 0x7e, 0x22,
- 0x68, 0x27, 0x7f, 0x9b, 0x65, 0x49, 0x2b, 0x23, 0xca, 0x0a, 0xe7, 0xb0,
- 0x64, 0x41, 0x9f, 0x1c, 0x95, 0x7b, 0xc9, 0x2a, 0x42, 0xa6, 0x0a, 0x7e,
- 0x38, 0x1f, 0x75, 0xb6, 0x39, 0x4f, 0x10, 0xe6, 0x07, 0xe8, 0x6f, 0xb5,
- 0x43, 0x6e, 0xee, 0xa2, 0x4d, 0x3a, 0x54, 0x91, 0x65, 0xfd, 0xdc, 0xaa,
- 0xce, 0xa7, 0x9f, 0xf7, 0x19, 0x8c, 0x3a, 0x07, 0x3a, 0xeb, 0x32, 0x92,
- 0x5d, 0x47, 0x1b, 0x63, 0xb0, 0x8b, 0xb8, 0x53, 0xaf, 0xc7, 0xb6, 0xd7,
- 0x65, 0x5f, 0xf6, 0xdd, 0xba, 0x68, 0xcc, 0xbb, 0x57, 0xe3, 0x4e, 0x5a,
- 0x75, 0xe3, 0x8c, 0x1c, 0xc4, 0x12, 0x88, 0xed, 0x93, 0xb4, 0x49, 0xc7,
- 0xe9, 0x9f, 0x1c, 0x0c, 0x30, 0x95, 0xb8, 0x83, 0xb2, 0x3f, 0x85, 0x39,
- 0xb9, 0x3e, 0x9e, 0x55, 0xe2, 0xb8, 0xad, 0x6d, 0x4a, 0xc9, 0xe1, 0xbc,
- 0x6b, 0x61, 0xe3, 0xbf, 0xd8, 0xf4, 0x0b, 0x6d, 0xf7, 0x24, 0xec, 0x1b,
- 0xdb, 0xe8, 0x2b, 0x9c, 0xa4, 0x5f, 0x12, 0xc1, 0xaa, 0x9b, 0x62, 0xe2,
- 0x2e, 0x63, 0x66, 0xb0, 0xaf, 0x2d, 0xf4, 0xfb, 0x2f, 0x61, 0xaf, 0x6b,
- 0x63, 0x51, 0xaf, 0xba, 0xb8, 0x6e, 0xef, 0x69, 0xe8, 0x76, 0x28, 0x7b,
- 0x6b, 0xe5, 0x03, 0x5e, 0xd5, 0x67, 0xf1, 0xac, 0x9f, 0x39, 0x5c, 0x81,
- 0x2e, 0x2d, 0xea, 0xd8, 0x37, 0x3c, 0x17, 0xfa, 0x38, 0x99, 0xe3, 0x73,
- 0x90, 0xed, 0xbd, 0x3a, 0x26, 0x60, 0x3c, 0x50, 0x97, 0x5d, 0xd9, 0x4f,
- 0x25, 0xc9, 0x87, 0xbc, 0xfa, 0x71, 0x9c, 0x3e, 0xc3, 0xa2, 0x47, 0x9e,
- 0x65, 0xd1, 0x9e, 0x05, 0x26, 0xfc, 0xab, 0x14, 0x93, 0xac, 0x7b, 0xab,
- 0x3e, 0x0f, 0xbf, 0x4a, 0xfb, 0x47, 0xda, 0xde, 0xd3, 0xbf, 0x83, 0x5d,
- 0xf7, 0xc9, 0xd3, 0x25, 0xf0, 0x39, 0xf4, 0x01, 0x7e, 0x40, 0x1f, 0x55,
- 0x56, 0xfa, 0xd2, 0x22, 0x0f, 0xd5, 0xfe, 0x01, 0x36, 0x47, 0x05, 0xbe,
- 0x0a, 0xe3, 0x65, 0x97, 0xf5, 0x37, 0xc6, 0xe9, 0xcb, 0x05, 0xb6, 0x3e,
- 0x86, 0xf5, 0x10, 0x5f, 0xd7, 0xfe, 0xd3, 0x2a, 0x79, 0x3d, 0xf4, 0xb3,
- 0xb0, 0x7f, 0xf8, 0x50, 0x3e, 0xdb, 0x58, 0x97, 0x30, 0xfe, 0x77, 0xbb,
- 0xf1, 0xb7, 0x1d, 0xe3, 0x6f, 0x6b, 0x3a, 0x12, 0x4e, 0x2e, 0xf4, 0x0b,
- 0x78, 0x66, 0xe9, 0x83, 0x6a, 0x3b, 0xfd, 0x82, 0x0e, 0x59, 0xdb, 0x2f,
- 0x08, 0x69, 0x3a, 0x85, 0x7d, 0xd2, 0xcf, 0xd3, 0x79, 0xa0, 0xce, 0x20,
- 0xf7, 0x44, 0x1a, 0x42, 0xfb, 0xa8, 0xed, 0xf0, 0x21, 0x98, 0x3c, 0xe6,
- 0x24, 0x41, 0xeb, 0x6e, 0x29, 0x4c, 0x9f, 0x32, 0xf6, 0x96, 0x71, 0x04,
- 0x7d, 0xf8, 0x40, 0x66, 0x0b, 0xd9, 0x0e, 0xcb, 0xcc, 0xd3, 0x05, 0x0b,
- 0x19, 0xc9, 0x51, 0x71, 0x2d, 0xfa, 0x31, 0xa1, 0x4f, 0xb3, 0x60, 0x7c,
- 0x9a, 0x33, 0xb2, 0xcf, 0x0b, 0xe2, 0x86, 0x91, 0xda, 0x12, 0xea, 0x34,
- 0xed, 0x29, 0xfa, 0x96, 0x0a, 0x3e, 0x77, 0xfe, 0xde, 0x0c, 0x02, 0x90,
- 0x60, 0x2f, 0x5b, 0xb1, 0x97, 0x6a, 0x63, 0x2f, 0x6d, 0x4b, 0xcd, 0x3e,
- 0x0e, 0xc7, 0x4e, 0xae, 0x1a, 0x2b, 0xd8, 0xc7, 0xdc, 0x79, 0xda, 0xb8,
- 0x47, 0xfa, 0x0d, 0x8e, 0xd9, 0x63, 0x78, 0x4e, 0x8f, 0x63, 0x8f, 0x49,
- 0xab, 0xa4, 0x7d, 0x2d, 0xfa, 0x2d, 0x88, 0xb3, 0x6b, 0x2f, 0xe1, 0x49,
- 0xfd, 0xd0, 0xf3, 0x60, 0x4f, 0xed, 0x7a, 0x4f, 0x53, 0xde, 0x2b, 0x7a,
- 0x1f, 0xf3, 0xb5, 0xbf, 0x91, 0xf2, 0xb1, 0x1f, 0xc0, 0xee, 0x45, 0x73,
- 0x73, 0xcc, 0x6b, 0x92, 0x1f, 0x95, 0x08, 0x7e, 0x72, 0xaf, 0xcc, 0xbb,
- 0xbd, 0x1c, 0x0f, 0xe2, 0x83, 0x69, 0x9c, 0xb1, 0x15, 0xb4, 0xeb, 0xf5,
- 0x43, 0xbe, 0xb6, 0x44, 0xe8, 0xa9, 0xc3, 0xe7, 0x4c, 0x81, 0x86, 0xe8,
- 0x98, 0x03, 0x32, 0xec, 0xf1, 0x3c, 0x7a, 0x53, 0x7b, 0xc5, 0x75, 0x4a,
- 0x12, 0xfa, 0x19, 0x5c, 0x9f, 0x3a, 0x5f, 0x84, 0xe3, 0xcb, 0x5c, 0x6a,
- 0xc8, 0xbb, 0x90, 0x6f, 0xed, 0x4b, 0xcd, 0x32, 0x30, 0x89, 0x58, 0xab,
- 0xec, 0x91, 0x4f, 0xa1, 0x6c, 0x86, 0x6b, 0xbf, 0x6a, 0x71, 0x3f, 0x13,
- 0x3a, 0x7f, 0xf8, 0x4f, 0x0d, 0x19, 0x1d, 0x07, 0x76, 0x04, 0x32, 0xf7,
- 0xf7, 0x86, 0x37, 0xa1, 0x6c, 0xb6, 0x9b, 0x73, 0x66, 0x2c, 0x48, 0xdd,
- 0x09, 0xe5, 0x60, 0x9b, 0x73, 0xa7, 0xe6, 0x05, 0xdb, 0xb4, 0xcf, 0xad,
- 0xcf, 0x72, 0xac, 0x71, 0x96, 0x1b, 0x9a, 0xe4, 0xf2, 0xdd, 0x8d, 0x81,
- 0x1e, 0x52, 0xdf, 0xa0, 0xb7, 0xe0, 0xd7, 0xb3, 0x2b, 0xf4, 0xbb, 0xff,
- 0x3c, 0x39, 0xd9, 0x76, 0x89, 0xcd, 0x7e, 0x0f, 0xbc, 0xbc, 0x06, 0xb1,
- 0x8a, 0x88, 0x3d, 0x43, 0x1c, 0xa2, 0xbf, 0xb1, 0xec, 0xef, 0xce, 0xcb,
- 0x5a, 0xbe, 0xee, 0xc5, 0x7c, 0x8d, 0x4f, 0x5e, 0xa2, 0xaf, 0x31, 0xdc,
- 0x22, 0xad, 0xc4, 0xa2, 0x33, 0xf0, 0x6d, 0x2d, 0x69, 0x71, 0xbf, 0x01,
- 0x1b, 0x76, 0xda, 0x5e, 0xe7, 0x86, 0x98, 0xd0, 0x2e, 0x9b, 0x66, 0xb7,
- 0x68, 0x5c, 0x70, 0x66, 0x96, 0x71, 0x61, 0x1c, 0xbc, 0x1f, 0x09, 0xf2,
- 0xbc, 0xc9, 0x4d, 0x72, 0xa9, 0xf1, 0xf5, 0xb2, 0xdf, 0x3f, 0xd6, 0xf0,
- 0xfb, 0xaf, 0x6c, 0xe2, 0xe3, 0x5a, 0xb8, 0x78, 0x1a, 0x7c, 0xcb, 0x21,
- 0xfe, 0x65, 0x5c, 0x3b, 0x8c, 0x78, 0x98, 0xb1, 0x58, 0x1e, 0x31, 0x71,
- 0xe6, 0xb4, 0xc8, 0x6e, 0xc4, 0xc8, 0x99, 0x1f, 0x31, 0x7f, 0xf5, 0xbc,
- 0x9f, 0x99, 0x13, 0xb9, 0x1d, 0x7c, 0x1d, 0x04, 0x6e, 0x66, 0x81, 0xa3,
- 0x3b, 0xc1, 0xdf, 0x7e, 0x8d, 0x9d, 0xf7, 0x1f, 0x11, 0xeb, 0x0e, 0x9d,
- 0xab, 0xa6, 0x3e, 0x27, 0x61, 0x47, 0xeb, 0xf5, 0xfd, 0xd9, 0x5e, 0xc4,
- 0xf5, 0x69, 0xb9, 0xd5, 0x66, 0x1c, 0x6b, 0xd9, 0x5b, 0x07, 0xe6, 0x63,
- 0x51, 0x9f, 0xb4, 0x70, 0x51, 0x3b, 0xb0, 0x9a, 0xf7, 0x45, 0x6d, 0x0b,
- 0x0e, 0xc7, 0x2e, 0xc4, 0xfb, 0x3b, 0x1a, 0xbc, 0x6f, 0x69, 0x95, 0xd6,
- 0xdb, 0x75, 0x1e, 0x61, 0xeb, 0xc0, 0x7e, 0xe2, 0x55, 0x16, 0x76, 0x1d,
- 0xf6, 0xb7, 0x2e, 0xb7, 0x65, 0xdf, 0xae, 0xbf, 0xe8, 0x6e, 0x94, 0xd2,
- 0xce, 0xfb, 0x0c, 0x66, 0x2f, 0x7d, 0xad, 0xe0, 0x56, 0xa0, 0x1f, 0x41,
- 0xce, 0x70, 0xef, 0x74, 0x02, 0x96, 0x80, 0x7f, 0x9d, 0x32, 0x3f, 0xf4,
- 0x16, 0xce, 0x70, 0xc7, 0x49, 0x26, 0x9c, 0x14, 0x70, 0x78, 0x3e, 0xd9,
- 0xae, 0xf3, 0xc5, 0x9f, 0x70, 0x59, 0xef, 0xe0, 0x4c, 0x47, 0x65, 0x1e,
- 0xfe, 0x43, 0x75, 0x08, 0x34, 0xee, 0xec, 0x42, 0x7f, 0xea, 0x1d, 0x79,
- 0x3e, 0x0a, 0xdb, 0x4b, 0x9e, 0x26, 0xd1, 0x7f, 0x0f, 0xfa, 0x74, 0xe2,
- 0x79, 0x5f, 0x6c, 0xde, 0x61, 0xec, 0xfc, 0x79, 0x94, 0x39, 0x47, 0xd4,
- 0x76, 0x7e, 0x2e, 0x2e, 0x7a, 0x4e, 0x8e, 0xe9, 0xd2, 0xfa, 0xbf, 0xbc,
- 0x16, 0xd7, 0x61, 0xdb, 0xcf, 0xea, 0xd7, 0x0f, 0x0c, 0x45, 0xd6, 0xeb,
- 0x88, 0xac, 0x37, 0x14, 0x59, 0x8f, 0x74, 0x76, 0x46, 0xe8, 0xec, 0xc4,
- 0xf8, 0x22, 0xd6, 0x26, 0x3f, 0xa2, 0x6b, 0x3e, 0x18, 0x59, 0x33, 0xdc,
- 0x5f, 0x57, 0x64, 0xdc, 0xbb, 0x58, 0x8f, 0x75, 0xc9, 0x48, 0x1d, 0x69,
- 0xd8, 0x8c, 0x3a, 0x96, 0x3b, 0x23, 0x74, 0x91, 0xd6, 0x0d, 0xa8, 0xd7,
- 0xfe, 0x13, 0xf8, 0xdc, 0x0a, 0xbb, 0xa5, 0x60, 0x3b, 0x5a, 0xe0, 0x5f,
- 0x35, 0xef, 0xf5, 0x51, 0xac, 0x1b, 0xce, 0x97, 0xc4, 0x1c, 0xec, 0xcf,
- 0xbe, 0x31, 0x33, 0x9e, 0xf5, 0x6c, 0xff, 0xf3, 0xfa, 0x9f, 0x6a, 0xbe,
- 0x6d, 0x06, 0xed, 0x3a, 0xef, 0x22, 0x73, 0x9d, 0x36, 0xce, 0x93, 0xf1,
- 0xb1, 0x25, 0x57, 0xbb, 0xca, 0xea, 0x1d, 0xe0, 0xd9, 0x6f, 0x34, 0x58,
- 0xda, 0x6a, 0x15, 0x8e, 0x30, 0x5f, 0xd0, 0x66, 0x62, 0x3e, 0xc4, 0x1e,
- 0xda, 0xc6, 0xd8, 0xa6, 0x9d, 0x36, 0x86, 0x7e, 0x0b, 0xed, 0xe7, 0x69,
- 0xf3, 0x8e, 0x27, 0x64, 0xf8, 0x81, 0x6a, 0xa7, 0xbc, 0xa8, 0x79, 0xea,
- 0xc8, 0xd9, 0x06, 0x4f, 0xe3, 0xe6, 0xbb, 0xcc, 0x01, 0xf3, 0xcd, 0xa3,
- 0x0f, 0x7e, 0x11, 0xde, 0x6b, 0x79, 0xd0, 0x90, 0x96, 0xde, 0x01, 0xc6,
- 0x6e, 0x15, 0x3c, 0x99, 0xa7, 0xb0, 0xf0, 0x0c, 0xf2, 0x17, 0xbd, 0x03,
- 0xb0, 0x4b, 0xc0, 0xa1, 0xde, 0x81, 0x73, 0x3a, 0x9e, 0xab, 0xfa, 0x8e,
- 0x75, 0x9b, 0x17, 0xe4, 0x88, 0xce, 0xba, 0x17, 0xca, 0x11, 0xdd, 0xb3,
- 0x8e, 0x79, 0x8d, 0x30, 0x47, 0x74, 0x56, 0x74, 0x8e, 0xe8, 0xf8, 0x45,
- 0x72, 0x44, 0xf9, 0x4b, 0xcf, 0x11, 0x71, 0x7e, 0x5b, 0xee, 0x1c, 0x74,
- 0xd4, 0xaf, 0x9a, 0x1c, 0xd1, 0x1b, 0x12, 0xe4, 0x88, 0x5e, 0x94, 0xb5,
- 0x73, 0x44, 0x87, 0x9a, 0x72, 0x44, 0x9b, 0x75, 0x8e, 0x88, 0xf3, 0x04,
- 0x39, 0x22, 0x96, 0x4b, 0x03, 0x43, 0x91, 0x5c, 0x07, 0xf0, 0xd7, 0xbb,
- 0x01, 0x7c, 0x73, 0xac, 0x51, 0x2f, 0xc4, 0x34, 0x62, 0xff, 0x15, 0x0d,
- 0xfb, 0xb5, 0x8c, 0x6f, 0x96, 0x96, 0xb9, 0x8b, 0xe1, 0xdb, 0x68, 0xe0,
- 0x97, 0xac, 0xc0, 0xb6, 0xc9, 0x86, 0xef, 0xe2, 0xad, 0x63, 0x0c, 0x3d,
- 0x51, 0x5b, 0x9e, 0x77, 0x02, 0xbc, 0x1e, 0x6b, 0xe4, 0x49, 0xce, 0xe7,
- 0x1f, 0x25, 0xe5, 0xc0, 0x9a, 0xdf, 0xbd, 0x52, 0xf9, 0xd5, 0xdf, 0xbd,
- 0x2c, 0x49, 0x82, 0xce, 0xd2, 0x40, 0x49, 0xc7, 0x5d, 0xf3, 0xde, 0xaf,
- 0xc8, 0xd2, 0xdd, 0x0e, 0xf0, 0x27, 0xcc, 0x9f, 0xf0, 0x7c, 0x97, 0x6d,
- 0x4a, 0x41, 0x7d, 0x7c, 0x39, 0x94, 0x07, 0x74, 0x0e, 0xe5, 0xc5, 0x75,
- 0xd1, 0x1c, 0xca, 0x59, 0xb9, 0x70, 0x0e, 0xe5, 0x81, 0x35, 0x72, 0x28,
- 0x2f, 0xcb, 0x72, 0x0e, 0xe5, 0x65, 0x09, 0x73, 0x28, 0x31, 0x59, 0xda,
- 0x1c, 0x48, 0xe3, 0x03, 0xfe, 0x12, 0x7e, 0x67, 0xf0, 0x0b, 0x72, 0x2a,
- 0x67, 0x1b, 0xf4, 0xaf, 0x95, 0x53, 0x79, 0x7d, 0xdd, 0x07, 0xc9, 0xa9,
- 0x04, 0x36, 0x20, 0xcc, 0xa9, 0xe0, 0xe7, 0xc0, 0xe6, 0xa8, 0x68, 0x4e,
- 0xe5, 0x27, 0xd4, 0x07, 0xd4, 0xb1, 0xcc, 0x7a, 0xe8, 0x05, 0xec, 0x52,
- 0x5e, 0xe7, 0x38, 0x3e, 0x67, 0x78, 0x38, 0x87, 0x3d, 0xa7, 0x71, 0x16,
- 0xe4, 0x63, 0xaf, 0xf6, 0x2d, 0xf3, 0x76, 0xca, 0x2a, 0xf4, 0xc1, 0x9a,
- 0x4d, 0xf3, 0xbb, 0xb8, 0x6d, 0xed, 0xf5, 0x29, 0xe3, 0x09, 0xab, 0x8c,
- 0xbd, 0x0c, 0x4f, 0xcf, 0xc9, 0x5e, 0x3f, 0xf4, 0xa9, 0x06, 0x1a, 0x73,
- 0x50, 0x37, 0xe7, 0x81, 0xb3, 0xc0, 0x89, 0x4b, 0xb0, 0x51, 0xa7, 0x40,
- 0x73, 0x74, 0x1f, 0x88, 0x89, 0x07, 0x51, 0xa7, 0xcf, 0x9c, 0xbe, 0x65,
- 0x48, 0x4b, 0x9a, 0x7a, 0x7e, 0x09, 0xf3, 0xb1, 0xee, 0x94, 0x8e, 0xc7,
- 0xca, 0x83, 0xdc, 0x2b, 0x6d, 0xdd, 0x22, 0xe8, 0x43, 0x5d, 0x95, 0x31,
- 0x20, 0xed, 0x5e, 0x18, 0xa3, 0xb5, 0xeb, 0x18, 0xad, 0x4b, 0xf3, 0x83,
- 0xbc, 0xbe, 0x35, 0x41, 0xac, 0xec, 0x72, 0xb9, 0x87, 0x33, 0x06, 0xeb,
- 0x58, 0x0e, 0x62, 0xc1, 0xbc, 0xe2, 0xfb, 0xef, 0xe1, 0x5c, 0x99, 0xa7,
- 0x09, 0xcf, 0xef, 0x2b, 0x66, 0xdf, 0x43, 0x52, 0xe9, 0x92, 0xc4, 0x66,
- 0xd0, 0x53, 0x9a, 0xa1, 0xdf, 0xfd, 0x69, 0x1d, 0x83, 0x24, 0xdd, 0xf3,
- 0xeb, 0xed, 0x1d, 0x97, 0xa1, 0xb7, 0x23, 0x17, 0xd4, 0xdb, 0xaf, 0x25,
- 0xa2, 0x7a, 0x7b, 0xc7, 0x65, 0xe8, 0xed, 0xbe, 0xcb, 0xd2, 0x5b, 0xee,
- 0x8d, 0x98, 0x14, 0xe6, 0xc4, 0x56, 0xfb, 0x59, 0xe1, 0xba, 0xe3, 0x58,
- 0x33, 0x7f, 0x9e, 0x35, 0xc7, 0xce, 0x9b, 0x5b, 0x6d, 0xf6, 0xb1, 0x2e,
- 0xe5, 0xbc, 0x19, 0x5b, 0xd1, 0xde, 0xb6, 0x1b, 0xbb, 0x74, 0x9f, 0x89,
- 0xe7, 0xc3, 0xb8, 0x3e, 0xaa, 0x3f, 0x94, 0x0b, 0xca, 0xc2, 0x77, 0xc0,
- 0x2f, 0xca, 0x43, 0xa8, 0x73, 0xdd, 0x4d, 0x32, 0xb8, 0x88, 0x78, 0xbf,
- 0xdb, 0xc8, 0x20, 0xcf, 0xba, 0x4f, 0x7f, 0x67, 0xaa, 0x7a, 0x4f, 0x05,
- 0x71, 0xbe, 0x8b, 0x67, 0x35, 0xd4, 0x35, 0xf0, 0x24, 0x19, 0xb6, 0x91,
- 0x8f, 0x2e, 0x7c, 0x9e, 0x1d, 0xf0, 0xd7, 0xc0, 0x23, 0x5d, 0xbf, 0x32,
- 0x27, 0x7c, 0x61, 0x3c, 0x93, 0x4a, 0x1c, 0x7d, 0x4f, 0x0c, 0x42, 0xc7,
- 0x07, 0x89, 0x51, 0x35, 0xc4, 0x3d, 0x94, 0x43, 0xca, 0xe6, 0xb6, 0xfe,
- 0x5d, 0x8a, 0x3e, 0xd5, 0x13, 0x88, 0x83, 0x29, 0xaf, 0x69, 0xd9, 0xe5,
- 0x6f, 0x3b, 0x7d, 0x56, 0x71, 0x8d, 0x7a, 0xbd, 0xc4, 0x58, 0xd1, 0x11,
- 0xb5, 0x75, 0xe0, 0xbf, 0x13, 0xb4, 0x4b, 0x57, 0xb8, 0x31, 0x23, 0x6b,
- 0x79, 0xbc, 0x53, 0x6e, 0x7f, 0x08, 0x7b, 0xcf, 0xef, 0xfd, 0xaf, 0xa1,
- 0x3e, 0x05, 0x9d, 0xa7, 0x7d, 0x67, 0x3c, 0x72, 0x93, 0xe9, 0xd7, 0xad,
- 0xbf, 0x57, 0x16, 0xb2, 0x37, 0x98, 0x6f, 0x57, 0xb4, 0x3f, 0x19, 0xda,
- 0xec, 0x15, 0xe7, 0xcc, 0xfb, 0x12, 0x45, 0x1d, 0xcf, 0x70, 0xbc, 0x96,
- 0x49, 0xc4, 0x20, 0x76, 0x24, 0x97, 0x9e, 0x30, 0xb1, 0x1b, 0x75, 0xac,
- 0x1d, 0x67, 0xe8, 0x9b, 0x58, 0x85, 0xf1, 0xeb, 0xca, 0x7b, 0x12, 0x6b,
- 0xcb, 0xc0, 0x96, 0x0f, 0x20, 0x03, 0xcd, 0xe7, 0x97, 0x80, 0xee, 0x87,
- 0xe7, 0x17, 0xfa, 0x31, 0x73, 0x66, 0xdf, 0xdd, 0xc1, 0x19, 0xfe, 0xbf,
- 0xd8, 0xa7, 0x15, 0xd9, 0x67, 0x88, 0x47, 0x0f, 0x98, 0x7d, 0xde, 0xd4,
- 0x84, 0x47, 0x23, 0x4d, 0x3a, 0xfb, 0x71, 0xe2, 0xd1, 0x9f, 0xac, 0xff,
- 0xf8, 0xf1, 0x88, 0xfb, 0xea, 0x5e, 0x13, 0x87, 0x82, 0x7d, 0x3c, 0x22,
- 0x2a, 0xf7, 0x51, 0xc6, 0x7b, 0x1f, 0xe4, 0x7c, 0xa2, 0x38, 0xc2, 0x33,
- 0xe9, 0xd0, 0x3e, 0x6c, 0xa0, 0x7b, 0xb0, 0xe5, 0xd5, 0xb8, 0xbc, 0x7e,
- 0x57, 0x42, 0xfe, 0xf7, 0x46, 0x7e, 0x0f, 0xb3, 0x4d, 0x4e, 0x8b, 0xe5,
- 0xd7, 0xd6, 0x07, 0x76, 0xe8, 0xb5, 0x4d, 0x81, 0xdd, 0xe1, 0x98, 0x50,
- 0x9f, 0x1d, 0xb4, 0xb3, 0xad, 0x5b, 0x96, 0x3a, 0x2f, 0x27, 0x06, 0xdc,
- 0xe6, 0xbc, 0xa1, 0xd6, 0x8a, 0x01, 0x2f, 0x9c, 0x0f, 0x5c, 0x8e, 0x01,
- 0x89, 0xb3, 0x9d, 0x5a, 0x36, 0x4a, 0x49, 0xc6, 0x3e, 0x7d, 0x06, 0x3b,
- 0xf9, 0x8e, 0xd8, 0xd6, 0x43, 0xbc, 0xeb, 0x21, 0xd6, 0xf5, 0x10, 0xff,
- 0x7a, 0x88, 0x71, 0x3d, 0xc4, 0xb6, 0x1e, 0x62, 0x5b, 0x0f, 0xb1, 0xad,
- 0xd7, 0x6f, 0x62, 0xe4, 0x11, 0x93, 0xf7, 0xe7, 0x77, 0x72, 0xe6, 0x17,
- 0x2a, 0xb0, 0x25, 0x93, 0xbc, 0xe7, 0xa0, 0x0a, 0xd9, 0xf5, 0x66, 0x7f,
- 0x61, 0x4e, 0xbc, 0xc7, 0xe4, 0x6c, 0x5e, 0xd7, 0x79, 0x43, 0x51, 0xb3,
- 0xad, 0xc1, 0xb7, 0x74, 0xde, 0xc7, 0xf8, 0x2d, 0xf8, 0x25, 0xfa, 0x3e,
- 0x13, 0x75, 0xb4, 0xae, 0x72, 0xcc, 0xc9, 0x88, 0x52, 0xb9, 0xeb, 0x31,
- 0x66, 0x47, 0x10, 0x13, 0x24, 0x25, 0xa6, 0x72, 0x6d, 0xe4, 0xa9, 0xa5,
- 0x72, 0x1b, 0xcc, 0x5c, 0x47, 0x5b, 0x03, 0xdf, 0xaa, 0x8f, 0x65, 0x5b,
- 0xe5, 0x6e, 0xe6, 0x13, 0xe7, 0x1e, 0xd6, 0xf7, 0x74, 0xae, 0x5c, 0x6b,
- 0x4a, 0xe3, 0x7b, 0x21, 0x7b, 0x37, 0xe6, 0xd3, 0xf7, 0x88, 0x1a, 0xfc,
- 0x56, 0xe7, 0xe5, 0xf7, 0x94, 0xe1, 0x77, 0xc0, 0xe3, 0x18, 0xfb, 0xe9,
- 0xbc, 0x30, 0x79, 0x1d, 0xce, 0xa7, 0xf3, 0x7a, 0x58, 0x47, 0xdf, 0xa5,
- 0xc0, 0x53, 0xc5, 0xa5, 0x63, 0xf4, 0x9e, 0xb8, 0x1b, 0x5d, 0x37, 0xfc,
- 0x26, 0x7e, 0x29, 0x6b, 0x76, 0xeb, 0xef, 0x68, 0x81, 0xcd, 0x98, 0xd2,
- 0x32, 0x68, 0xe7, 0xb8, 0xaf, 0xf7, 0x21, 0x7f, 0x53, 0x5a, 0xfe, 0x8a,
- 0x88, 0x63, 0x26, 0x07, 0xb7, 0xa5, 0x6d, 0x75, 0xa0, 0x95, 0xf9, 0xd7,
- 0x61, 0x3f, 0xc4, 0x3d, 0xae, 0xd7, 0x6c, 0xc7, 0x99, 0x57, 0x0b, 0xf1,
- 0x4c, 0xb6, 0x04, 0xf9, 0xb6, 0x0f, 0xa3, 0x4b, 0xad, 0x4d, 0xba, 0x14,
- 0xee, 0x93, 0xfb, 0xe7, 0x73, 0xed, 0x3b, 0x15, 0x8b, 0x7e, 0xe4, 0xfb,
- 0x48, 0x43, 0x36, 0x78, 0xb7, 0xe4, 0x8b, 0x90, 0x41, 0xfd, 0x9d, 0x02,
- 0x7a, 0x54, 0xaf, 0x0f, 0x33, 0xc7, 0xbc, 0xf3, 0x0b, 0xe6, 0xde, 0x82,
- 0x3c, 0xcc, 0xfc, 0x83, 0xbd, 0x2a, 0xff, 0x30, 0x0c, 0x59, 0x81, 0x0f,
- 0xe0, 0x75, 0x68, 0x9f, 0x4e, 0xb9, 0xf4, 0x07, 0x9a, 0xbf, 0xbf, 0x3c,
- 0xda, 0x16, 0xf0, 0xe1, 0xed, 0xd6, 0xe0, 0x1b, 0xc4, 0xdf, 0x26, 0x57,
- 0x96, 0x39, 0xfe, 0x7f, 0x8c, 0xac, 0x1c, 0x86, 0x6d, 0x1e, 0x86, 0x2c,
- 0x22, 0x26, 0xd7, 0xf3, 0x1d, 0x96, 0xd2, 0xd3, 0x0b, 0x9d, 0x2b, 0xfb,
- 0xa3, 0xee, 0x58, 0xd8, 0xff, 0xb1, 0xa6, 0xfe, 0x8f, 0xa1, 0xff, 0x0b,
- 0x4d, 0xfd, 0x1f, 0x8b, 0xf4, 0x3f, 0xda, 0xd4, 0x1f, 0x31, 0xe2, 0xd3,
- 0xff, 0xdc, 0xd4, 0xff, 0x68, 0xa4, 0xff, 0x6c, 0x53, 0xff, 0x59, 0xf4,
- 0x7f, 0xad, 0xa9, 0x3f, 0xea, 0x8e, 0xb5, 0x98, 0xef, 0x62, 0xc4, 0xd8,
- 0x7d, 0x26, 0x16, 0xc7, 0xb3, 0xd6, 0xfc, 0xad, 0x85, 0x72, 0xd7, 0x83,
- 0x33, 0x08, 0xef, 0xb4, 0x51, 0x5f, 0xf3, 0xd0, 0xd7, 0x65, 0x5f, 0x26,
- 0x90, 0xc7, 0xa8, 0x2c, 0x12, 0x1f, 0x2a, 0x12, 0x73, 0x7d, 0xfa, 0x47,
- 0x56, 0xb9, 0x1a, 0xda, 0x24, 0xde, 0x5b, 0xe2, 0x7d, 0xd7, 0xc0, 0xf6,
- 0xc6, 0xdd, 0x45, 0x13, 0x83, 0x5d, 0xd1, 0x06, 0xda, 0x81, 0x97, 0x21,
- 0x66, 0xca, 0xe1, 0x40, 0x6f, 0x28, 0xbf, 0x9c, 0xdf, 0xe8, 0x0f, 0x65,
- 0xd5, 0xac, 0x33, 0xbc, 0x0a, 0xd7, 0xd2, 0xab, 0x72, 0x5b, 0xb1, 0x4b,
- 0xc0, 0xb5, 0x91, 0x06, 0xae, 0x7d, 0x51, 0xe6, 0x1a, 0xf1, 0xf6, 0x19,
- 0xd9, 0xef, 0xed, 0xe1, 0x3d, 0x9d, 0xc3, 0x79, 0xf9, 0x68, 0xe2, 0xed,
- 0x3d, 0x0d, 0x3b, 0xc9, 0x3b, 0x1d, 0xe9, 0x83, 0xbc, 0x83, 0x1b, 0xe6,
- 0x66, 0x27, 0xbd, 0x5f, 0xc7, 0xfe, 0x69, 0x33, 0x2f, 0x37, 0xde, 0xe6,
- 0x7c, 0x49, 0xd9, 0x1f, 0xdc, 0x77, 0x68, 0xcc, 0x5b, 0x69, 0xcc, 0x9b,
- 0x32, 0xfa, 0x46, 0x1b, 0xbc, 0x6c, 0x2f, 0x8b, 0xb0, 0x97, 0x63, 0x88,
- 0xb9, 0x17, 0xbd, 0xb5, 0xf2, 0xa3, 0x97, 0x6b, 0x2f, 0x9b, 0xf3, 0xcc,
- 0xcd, 0xf6, 0x92, 0xeb, 0x34, 0xe7, 0x96, 0xd3, 0x4d, 0xf8, 0x4f, 0x79,
- 0x3a, 0x67, 0x7c, 0x6a, 0x3c, 0xab, 0xe7, 0xa0, 0x8f, 0x4a, 0xc6, 0xb4,
- 0xfc, 0xb2, 0x1c, 0xc6, 0x96, 0xf7, 0x34, 0x62, 0xcb, 0xe5, 0x78, 0x10,
- 0xbe, 0x6b, 0xff, 0x67, 0x0c, 0x3e, 0xd2, 0x47, 0x76, 0xac, 0xb2, 0xb7,
- 0x5b, 0xed, 0xd5, 0x6d, 0xcc, 0x97, 0x5e, 0x2b, 0xb7, 0xea, 0x38, 0xfe,
- 0x8c, 0xc9, 0x4d, 0xcd, 0x69, 0xff, 0x9f, 0xdf, 0x0b, 0xca, 0xd9, 0x4d,
- 0xc6, 0xdf, 0xbb, 0x18, 0xae, 0xae, 0x8c, 0x4d, 0x95, 0x3a, 0x88, 0xb1,
- 0x8c, 0x4d, 0xfb, 0xdb, 0x89, 0xa1, 0x05, 0xff, 0x82, 0xe3, 0x31, 0x8e,
- 0xe3, 0xd9, 0x47, 0xc7, 0xa1, 0xe8, 0xb7, 0x68, 0xc6, 0x07, 0x71, 0x68,
- 0xc1, 0xff, 0x71, 0x5b, 0x80, 0x83, 0x17, 0x8a, 0x59, 0x3e, 0xdf, 0xce,
- 0xbc, 0xde, 0xa2, 0x77, 0x31, 0x5a, 0x57, 0xc7, 0xbd, 0xb1, 0x55, 0x71,
- 0xaf, 0x6d, 0xe2, 0xda, 0x5f, 0xd2, 0x71, 0x6f, 0xc0, 0x63, 0xee, 0x25,
- 0x1a, 0x47, 0xb9, 0xc0, 0x42, 0x7e, 0x53, 0x21, 0x3e, 0xd0, 0x47, 0x81,
- 0x9f, 0x35, 0xfd, 0x8b, 0xe0, 0x73, 0x72, 0x0d, 0xb9, 0xf9, 0xb8, 0xed,
- 0x44, 0xb8, 0xf7, 0x73, 0x12, 0xe4, 0xeb, 0x76, 0x83, 0x16, 0xc6, 0x56,
- 0x71, 0x23, 0x0f, 0x3f, 0x35, 0xf7, 0x2a, 0xc3, 0x7e, 0x61, 0x1c, 0xdf,
- 0xf8, 0xee, 0x5a, 0xc9, 0xaf, 0xc8, 0x9f, 0x74, 0x33, 0x0d, 0x8d, 0x73,
- 0xcf, 0x5f, 0xc6, 0x77, 0x8b, 0x0f, 0x73, 0x3f, 0xa2, 0xd9, 0xae, 0xf1,
- 0xbb, 0x29, 0xbf, 0x95, 0x8a, 0x75, 0x67, 0x9f, 0x0b, 0x1d, 0xe0, 0xbd,
- 0xe1, 0x28, 0xbe, 0x26, 0xa4, 0x34, 0x2b, 0x89, 0x64, 0x8e, 0xdf, 0x00,
- 0x68, 0xff, 0x7f, 0x68, 0xf6, 0x99, 0x92, 0x7d, 0x33, 0x41, 0xce, 0x53,
- 0x5d, 0xf0, 0x5e, 0xdc, 0xe3, 0xe0, 0x43, 0xe6, 0x50, 0x98, 0xf3, 0x54,
- 0xc1, 0xbd, 0xb8, 0x43, 0x1f, 0xdd, 0xbd, 0x38, 0xce, 0x6f, 0xcb, 0x9e,
- 0x35, 0xee, 0xc5, 0xc5, 0x2e, 0xf1, 0x5e, 0xdc, 0x26, 0x9d, 0xf3, 0xe4,
- 0x3c, 0x41, 0xce, 0x93, 0xe5, 0xad, 0x03, 0xcc, 0x95, 0xf0, 0xee, 0xdb,
- 0xa0, 0xbe, 0x2f, 0xbc, 0x75, 0xe0, 0xe7, 0x11, 0xa3, 0xfc, 0x75, 0xfb,
- 0xc7, 0x1f, 0xa3, 0x70, 0x2f, 0xbf, 0x11, 0x7c, 0xdf, 0x95, 0xcb, 0xc9,
- 0x03, 0x7c, 0xb8, 0xbc, 0xe6, 0x3e, 0x9d, 0xd7, 0x7c, 0xa7, 0x3d, 0x9a,
- 0xd7, 0x54, 0x17, 0xb9, 0x1b, 0xb6, 0x6f, 0x8d, 0xbc, 0x66, 0x3c, 0x72,
- 0x37, 0x2c, 0x6e, 0xee, 0x86, 0x6d, 0x72, 0x11, 0x4b, 0x9a, 0x3c, 0xa6,
- 0xba, 0xe0, 0xdd, 0xb0, 0xce, 0x0d, 0x1f, 0x3e, 0x8f, 0xb9, 0xea, 0x6e,
- 0x18, 0x6c, 0xdd, 0x16, 0x49, 0x5f, 0x56, 0xdc, 0xf3, 0x61, 0x62, 0x1e,
- 0xde, 0xab, 0x6f, 0xc1, 0x9e, 0xe3, 0xb2, 0x27, 0x49, 0xf9, 0xe4, 0xdd,
- 0xc6, 0x3e, 0xe8, 0x02, 0x9e, 0x3e, 0xcb, 0xfd, 0x3c, 0x23, 0x6b, 0xa4,
- 0x6f, 0xe5, 0x3d, 0x84, 0xe5, 0x3b, 0xbd, 0x89, 0xc6, 0x9d, 0xde, 0x29,
- 0xc8, 0x8d, 0x9a, 0x49, 0xc8, 0x7c, 0x44, 0xa6, 0x26, 0x3d, 0xf8, 0x4b,
- 0xb3, 0x8e, 0x69, 0xe7, 0xff, 0xef, 0x48, 0x02, 0xf3, 0x78, 0x0f, 0xb8,
- 0x43, 0x62, 0xb3, 0xc1, 0x37, 0xcb, 0xe0, 0xff, 0xb8, 0xa4, 0xd0, 0x87,
- 0x77, 0x3c, 0xe3, 0xb2, 0x5f, 0xe7, 0x2c, 0x42, 0x59, 0xfe, 0x35, 0xf0,
- 0x78, 0x73, 0x7e, 0xb9, 0x9c, 0x5c, 0xc3, 0xee, 0x27, 0xa5, 0x3c, 0x43,
- 0x79, 0xbe, 0xc1, 0xfc, 0xff, 0x82, 0xd3, 0x52, 0xf6, 0x4f, 0x99, 0xf8,
- 0x42, 0x7f, 0xdb, 0x01, 0x2f, 0xb7, 0x18, 0x1b, 0x8c, 0x67, 0x75, 0x0b,
- 0x6d, 0x1e, 0xd6, 0x38, 0x2e, 0xc3, 0xd3, 0x3b, 0x52, 0x7b, 0x81, 0x77,
- 0x63, 0x7a, 0xcd, 0xcb, 0xe1, 0xb9, 0x75, 0x9e, 0xef, 0x8d, 0x97, 0xca,
- 0xf7, 0xd0, 0x3f, 0xae, 0x62, 0x7f, 0x5b, 0x20, 0x1f, 0x5f, 0x95, 0xe2,
- 0xb1, 0x6b, 0x65, 0xf8, 0x68, 0x06, 0xf4, 0xbc, 0x5f, 0x2f, 0x67, 0xe1,
- 0x4b, 0x3f, 0xcd, 0x7b, 0x63, 0xc0, 0x50, 0xf0, 0xed, 0xf9, 0x55, 0xdf,
- 0xb1, 0xa3, 0x77, 0xcd, 0xfa, 0x1b, 0x77, 0x87, 0x9e, 0xf5, 0x25, 0xd1,
- 0x49, 0x9a, 0x67, 0x96, 0xef, 0x8f, 0x2f, 0xfa, 0xbb, 0xb4, 0x6d, 0x7b,
- 0xc6, 0x5f, 0x91, 0xfb, 0xd1, 0x67, 0x38, 0x5e, 0xfb, 0x1e, 0xec, 0xdb,
- 0x39, 0x8b, 0xf6, 0x6d, 0xca, 0x93, 0xab, 0x63, 0xc2, 0xf3, 0x10, 0x0b,
- 0x3c, 0xd0, 0x77, 0x38, 0x82, 0xef, 0xfb, 0x3d, 0xfa, 0x5c, 0x03, 0xac,
- 0x58, 0x88, 0xdc, 0xc1, 0x58, 0x3e, 0xdb, 0xe0, 0x6e, 0x46, 0x70, 0x16,
- 0xc1, 0xfd, 0x11, 0xed, 0x6f, 0x1e, 0xdc, 0xe3, 0x06, 0xf7, 0x47, 0x7a,
- 0x67, 0x59, 0xd7, 0xd5, 0x64, 0xfb, 0x12, 0x90, 0x01, 0xde, 0x3b, 0xe2,
- 0xbd, 0x71, 0xd2, 0xac, 0x73, 0x1d, 0xff, 0x47, 0xdd, 0xd5, 0xc7, 0xb6,
- 0x75, 0x5d, 0xf7, 0xc3, 0x47, 0xea, 0xc3, 0xb4, 0x2c, 0x53, 0x32, 0x25,
- 0xd3, 0x96, 0x2c, 0xbf, 0x27, 0x3d, 0x59, 0x72, 0xac, 0x14, 0xac, 0xab,
- 0xad, 0x02, 0x46, 0xa4, 0x0c, 0x49, 0x7f, 0xb4, 0x08, 0x06, 0xfa, 0xa3,
- 0x99, 0x8b, 0x66, 0xab, 0x4b, 0xd9, 0x4e, 0x0a, 0xf4, 0x0f, 0xb7, 0xc5,
- 0x80, 0x6c, 0x58, 0x60, 0x86, 0xb4, 0x12, 0x63, 0x56, 0x4c, 0xd6, 0x66,
- 0x85, 0x0c, 0xd8, 0x30, 0x4e, 0x54, 0x9c, 0x14, 0x50, 0xc6, 0x04, 0x69,
- 0x83, 0xa2, 0x58, 0x61, 0x45, 0x76, 0x36, 0x6c, 0x7f, 0x65, 0x43, 0xd0,
- 0x05, 0x9b, 0xb3, 0x38, 0x76, 0xb0, 0x06, 0x45, 0xd6, 0x7d, 0x62, 0x18,
- 0xd0, 0x0d, 0xdc, 0xf9, 0xdd, 0x0f, 0xf2, 0xf1, 0xf1, 0x51, 0x1f, 0x89,
- 0x33, 0x60, 0x02, 0x04, 0xbe, 0xf7, 0x78, 0xdf, 0x7b, 0xf7, 0x9e, 0x7b,
- 0xce, 0xb9, 0xbf, 0x73, 0xee, 0x39, 0x87, 0x9e, 0x7b, 0xdb, 0x9b, 0xf3,
- 0xb9, 0xca, 0x77, 0x8e, 0x8a, 0x77, 0x0e, 0x28, 0x9d, 0xa5, 0xe3, 0xc5,
- 0x63, 0xc6, 0x6c, 0x61, 0x22, 0xe2, 0x67, 0xfe, 0x9e, 0xad, 0xc2, 0xbe,
- 0x6e, 0x87, 0xe1, 0xd6, 0xa2, 0x67, 0xbc, 0x85, 0x9e, 0xcd, 0x32, 0xc1,
- 0xf6, 0x78, 0x5d, 0x77, 0x4b, 0xda, 0xc9, 0xeb, 0x88, 0x85, 0xd7, 0x31,
- 0x0e, 0x92, 0x76, 0x75, 0x19, 0xba, 0xe2, 0x8c, 0x6f, 0x68, 0xd0, 0xee,
- 0x74, 0x9d, 0x76, 0x3b, 0xff, 0x1f, 0xd1, 0xee, 0x1d, 0x81, 0x7f, 0x5f,
- 0xad, 0x22, 0x6e, 0x4d, 0x63, 0x00, 0x9d, 0x3b, 0x04, 0x3a, 0x42, 0x9f,
- 0x5a, 0xe5, 0x15, 0x82, 0x4e, 0x45, 0x5c, 0x71, 0xad, 0xf6, 0x5a, 0xb4,
- 0xee, 0xa7, 0x64, 0xbb, 0x04, 0xf6, 0x09, 0xfc, 0x79, 0xed, 0xd7, 0xc8,
- 0x63, 0x1f, 0x6b, 0x8d, 0x04, 0x56, 0x72, 0xdb, 0x27, 0x0c, 0x08, 0x1d,
- 0xf6, 0xc9, 0xb1, 0x4d, 0xda, 0x27, 0xe7, 0xa5, 0x7d, 0x92, 0xdd, 0xb8,
- 0x7d, 0xb2, 0xbb, 0x25, 0xae, 0xab, 0x31, 0x9e, 0xcd, 0xdb, 0x27, 0xc6,
- 0x9a, 0xf6, 0xc9, 0x90, 0xc3, 0x17, 0x83, 0xfe, 0xfe, 0x06, 0x65, 0x8f,
- 0x43, 0xc7, 0x69, 0x3a, 0x83, 0xc6, 0xc7, 0x5d, 0x7e, 0xe1, 0x4f, 0x93,
- 0xd6, 0xbf, 0xf8, 0x3f, 0xa6, 0xf5, 0x50, 0x8b, 0xcf, 0xbb, 0x31, 0x1e,
- 0x0a, 0xef, 0xd8, 0x14, 0x8e, 0x77, 0xd3, 0x7a, 0xa8, 0xad, 0xef, 0xb4,
- 0x7d, 0xcc, 0x62, 0xb3, 0xef, 0x74, 0xd4, 0x68, 0xa7, 0xdb, 0xff, 0xd8,
- 0xe1, 0x53, 0x75, 0xea, 0x77, 0xc8, 0x14, 0xf9, 0x8e, 0x4d, 0xe8, 0x77,
- 0x41, 0x96, 0xac, 0x6c, 0x96, 0x60, 0x33, 0xe1, 0x7d, 0x11, 0x21, 0x6b,
- 0x2e, 0xbc, 0xc5, 0xef, 0x63, 0x7a, 0xbe, 0xf8, 0x87, 0x62, 0x9d, 0x92,
- 0xfe, 0x07, 0xb4, 0x0f, 0xfb, 0xce, 0x88, 0xb6, 0x32, 0xbe, 0x49, 0xf9,
- 0x23, 0x14, 0xf6, 0x6f, 0xe7, 0x87, 0x68, 0x5d, 0xf3, 0x36, 0x67, 0x2b,
- 0x68, 0x19, 0xdf, 0xcb, 0xf3, 0x12, 0x69, 0xb2, 0xb5, 0xa0, 0x3f, 0xcf,
- 0x33, 0x2e, 0x18, 0xad, 0x63, 0x82, 0xe6, 0xb9, 0xb9, 0x28, 0x6c, 0x3a,
- 0xad, 0x3b, 0x57, 0x64, 0xec, 0xa9, 0xb8, 0x0e, 0x9c, 0xa6, 0x75, 0xa7,
- 0x1b, 0x07, 0xef, 0xf5, 0xe0, 0x0b, 0xcf, 0xdc, 0x4f, 0x3d, 0x77, 0x26,
- 0x62, 0xce, 0x53, 0x9e, 0x73, 0x57, 0xcf, 0xe1, 0xca, 0x36, 0xda, 0xca,
- 0xfb, 0x53, 0x62, 0x5c, 0xdf, 0xfc, 0x62, 0x02, 0xb9, 0x6a, 0xf5, 0xfc,
- 0x21, 0x77, 0xce, 0x14, 0xd6, 0x01, 0x2d, 0x87, 0x3a, 0x3f, 0x1b, 0xb4,
- 0x18, 0xf1, 0xc8, 0x99, 0x72, 0xae, 0x25, 0xb8, 0xcf, 0x4d, 0x8b, 0xc6,
- 0x3a, 0x32, 0xa7, 0xd6, 0x91, 0x45, 0x87, 0x1e, 0x6f, 0xc5, 0xed, 0xfd,
- 0x1e, 0xb8, 0xdd, 0x2b, 0x6f, 0x0a, 0x7d, 0x7a, 0x92, 0x71, 0xc8, 0x67,
- 0x80, 0x43, 0x42, 0xc8, 0x5b, 0x92, 0x58, 0x04, 0xdf, 0x17, 0x19, 0x8f,
- 0x44, 0x98, 0x57, 0x7e, 0x44, 0xe7, 0x18, 0x6b, 0x5f, 0xa7, 0xfd, 0xca,
- 0x3e, 0x83, 0xdc, 0xea, 0x38, 0x53, 0xc4, 0xf1, 0xfb, 0x28, 0xfb, 0x98,
- 0x35, 0x19, 0xa7, 0x1f, 0xd1, 0x59, 0x11, 0x33, 0x83, 0xfd, 0x3d, 0xc4,
- 0x1c, 0x3c, 0x20, 0xde, 0x2f, 0x7d, 0x19, 0xf7, 0x23, 0xa6, 0x6e, 0xe3,
- 0xf1, 0xfb, 0x2a, 0xb7, 0x8e, 0xdb, 0xe1, 0x9d, 0x4b, 0x4a, 0xa6, 0xc4,
- 0x35, 0xbe, 0xff, 0x49, 0xa3, 0xf5, 0xfe, 0xb8, 0x91, 0xaa, 0xa6, 0x8c,
- 0x44, 0x05, 0xed, 0x9e, 0x34, 0x92, 0x55, 0xd8, 0x90, 0x9a, 0x47, 0xac,
- 0x28, 0xe4, 0x6d, 0x95, 0xd6, 0xdf, 0x8b, 0x58, 0x24, 0x57, 0x9e, 0xc4,
- 0x06, 0xfa, 0x7d, 0xb8, 0xa9, 0xdf, 0x9a, 0xbe, 0x38, 0x86, 0xbf, 0xe7,
- 0x15, 0xa6, 0xa9, 0xc6, 0xb5, 0x41, 0xf8, 0xd7, 0x27, 0xb3, 0xb4, 0x16,
- 0xae, 0xb5, 0x5a, 0x70, 0xed, 0xe2, 0xba, 0xfd, 0xfe, 0xa4, 0x32, 0x2e,
- 0xf3, 0xa3, 0xfd, 0xb6, 0xc0, 0xaf, 0xdc, 0xef, 0x26, 0x6c, 0xeb, 0xe2,
- 0x29, 0xb4, 0xd1, 0x7e, 0x70, 0xed, 0x07, 0xeb, 0x55, 0xf1, 0xc0, 0x3a,
- 0x3e, 0x21, 0x88, 0x7c, 0xaf, 0x90, 0x8c, 0x6b, 0x85, 0x8d, 0xb5, 0xc2,
- 0xfd, 0x83, 0xbd, 0x05, 0x9f, 0x8f, 0xb0, 0xb7, 0xcc, 0x24, 0x49, 0x5f,
- 0xf7, 0x99, 0xaa, 0xd3, 0xbf, 0xeb, 0x95, 0x4b, 0x39, 0xea, 0x91, 0x4b,
- 0xe9, 0x94, 0xb5, 0x80, 0x43, 0xd6, 0x22, 0x0e, 0xdc, 0x36, 0xcc, 0x76,
- 0x4b, 0x0f, 0xeb, 0x90, 0x1e, 0xb1, 0x6d, 0xe2, 0xbf, 0xea, 0xb4, 0x5b,
- 0xdc, 0x79, 0xf1, 0x90, 0x3b, 0x60, 0x33, 0x69, 0xc3, 0xa4, 0x4a, 0xf5,
- 0x9c, 0x7a, 0x1e, 0x77, 0x23, 0x6f, 0xb1, 0xd2, 0x92, 0x63, 0xe9, 0xd5,
- 0xdf, 0x91, 0x96, 0xfe, 0x62, 0xfd, 0x8a, 0xb7, 0xc5, 0x74, 0x5e, 0x76,
- 0xd5, 0xfd, 0xea, 0x9f, 0x5b, 0x9f, 0xe1, 0x5d, 0xa3, 0xc2, 0xe7, 0x9d,
- 0xad, 0xeb, 0xb2, 0x19, 0xd9, 0xdf, 0x42, 0xb3, 0x9d, 0xe1, 0xbf, 0x42,
- 0x8a, 0x76, 0xde, 0xba, 0x7d, 0x73, 0xfe, 0xb3, 0xad, 0x6e, 0x1c, 0xdc,
- 0x27, 0xfd, 0x62, 0x73, 0x2a, 0x0e, 0x7b, 0x40, 0xd9, 0x7b, 0xeb, 0xf1,
- 0x3b, 0xae, 0xcd, 0x29, 0x5f, 0xa2, 0x65, 0x96, 0x09, 0x7c, 0x7e, 0xfc,
- 0x54, 0x87, 0x1d, 0x52, 0x7b, 0x59, 0xd8, 0xaf, 0x02, 0xdf, 0xeb, 0xe7,
- 0x43, 0x67, 0x6f, 0x64, 0xce, 0xcc, 0x96, 0x39, 0x93, 0x7c, 0x05, 0x5b,
- 0x0b, 0xf1, 0xc5, 0x53, 0xae, 0x18, 0xef, 0x4f, 0x42, 0x8b, 0x5e, 0x8f,
- 0xb8, 0x67, 0xc4, 0x2d, 0xb7, 0xeb, 0xe7, 0x1d, 0x07, 0x2e, 0x47, 0x7f,
- 0x6b, 0xb5, 0x57, 0xa2, 0xbb, 0xe5, 0x5a, 0x5c, 0xf5, 0xc6, 0x48, 0xa1,
- 0x0d, 0xf7, 0xcf, 0xbd, 0xf6, 0xee, 0xda, 0xe0, 0xda, 0x2b, 0xea, 0x8b,
- 0xf8, 0x0e, 0x09, 0x1d, 0xd0, 0x43, 0x95, 0x12, 0xe2, 0xaf, 0x3f, 0x0b,
- 0x99, 0x67, 0x3d, 0xeb, 0xc8, 0x49, 0xf3, 0x9e, 0xc7, 0xfa, 0x9e, 0x4a,
- 0x20, 0x86, 0xbd, 0x3f, 0xc4, 0x96, 0xf4, 0xb3, 0xee, 0x41, 0xfb, 0x71,
- 0xf3, 0x16, 0xfc, 0xbd, 0xca, 0xff, 0x94, 0x52, 0xeb, 0xcb, 0xa1, 0x0d,
- 0xec, 0xad, 0x6c, 0x4e, 0x4f, 0x5b, 0xe6, 0x0a, 0x61, 0xdf, 0x07, 0xf1,
- 0xc2, 0xc7, 0x7a, 0xa9, 0xf7, 0x2b, 0x5d, 0x5d, 0xf6, 0x1f, 0xf4, 0xc9,
- 0xbd, 0x28, 0x7c, 0xd7, 0x43, 0x2f, 0x94, 0x10, 0xcb, 0x8d, 0xef, 0x7e,
- 0x8b, 0xbf, 0xf3, 0xd2, 0x51, 0x3a, 0x16, 0x1d, 0x58, 0x4e, 0xce, 0x4f,
- 0x99, 0x60, 0x2b, 0xd5, 0xe8, 0x6f, 0xa2, 0x9f, 0x93, 0xfb, 0x19, 0xd5,
- 0xfb, 0xbd, 0x57, 0xe3, 0xe5, 0x2f, 0xfc, 0x69, 0xdf, 0xc7, 0x8d, 0x8d,
- 0xfc, 0xd6, 0x86, 0xfc, 0x85, 0xd8, 0xe7, 0xdf, 0xc8, 0x9e, 0x89, 0xde,
- 0x1b, 0x9e, 0x16, 0x39, 0xa7, 0x4e, 0x3e, 0xb8, 0x3f, 0xfb, 0xc3, 0xe0,
- 0x87, 0x91, 0x16, 0x5d, 0xf5, 0xc9, 0xfd, 0xfd, 0x6e, 0xba, 0x06, 0x3d,
- 0x7d, 0x55, 0xde, 0xfb, 0xc0, 0xd8, 0xf3, 0x87, 0x9f, 0xba, 0x4a, 0x67,
- 0xae, 0x81, 0x87, 0x0d, 0xe6, 0xb6, 0x31, 0xca, 0x87, 0x91, 0x57, 0x24,
- 0x72, 0x73, 0xf4, 0xbe, 0xa1, 0xc8, 0x15, 0x3a, 0x23, 0x72, 0x20, 0xc7,
- 0x23, 0xf7, 0x78, 0x3d, 0x3c, 0x53, 0x7d, 0x9b, 0xce, 0x56, 0x82, 0xfc,
- 0xdf, 0xc0, 0xee, 0xad, 0x79, 0x90, 0xcd, 0x3c, 0x7e, 0x4f, 0xf0, 0xf8,
- 0xf0, 0x9a, 0x3c, 0x7e, 0xa4, 0xce, 0xe3, 0x5f, 0xe9, 0x97, 0xfc, 0xdc,
- 0xcb, 0xcf, 0xea, 0xa5, 0x43, 0xe2, 0xb9, 0x6f, 0xf3, 0xf1, 0x56, 0x3a,
- 0x14, 0x92, 0xc7, 0x67, 0x2b, 0xac, 0xe3, 0x0b, 0x6f, 0xd3, 0xb9, 0x6b,
- 0x59, 0x5f, 0x4a, 0xe4, 0x2f, 0x38, 0x6b, 0x69, 0xe8, 0xfb, 0xd1, 0xae,
- 0x1d, 0xff, 0x6b, 0xbd, 0x24, 0x73, 0xae, 0xca, 0x52, 0x3f, 0xd1, 0x5b,
- 0xd1, 0x21, 0x17, 0xff, 0x37, 0xdb, 0x8e, 0xe7, 0xd5, 0x1a, 0x78, 0x7c,
- 0x0d, 0xbf, 0x46, 0x2b, 0x5f, 0xf6, 0x79, 0xe0, 0xe1, 0xa7, 0xfb, 0xe5,
- 0x3e, 0xd5, 0x5a, 0x7e, 0x8d, 0xa6, 0xb8, 0x0e, 0xe7, 0xbe, 0x3d, 0xeb,
- 0xfd, 0x3d, 0x2a, 0x17, 0xf0, 0x87, 0xfd, 0x72, 0xbd, 0x40, 0x7e, 0xe0,
- 0x0a, 0xd3, 0xe1, 0x22, 0x63, 0x95, 0x21, 0xea, 0xbc, 0xaa, 0xc7, 0x3a,
- 0x24, 0xf4, 0xad, 0xd3, 0x4f, 0x73, 0x51, 0xe5, 0x76, 0xe7, 0x1c, 0x63,
- 0xba, 0x28, 0x6c, 0x9c, 0xf6, 0xf2, 0xd6, 0x3e, 0xe6, 0x6a, 0xd8, 0xb5,
- 0x26, 0xb8, 0xf9, 0x0d, 0x75, 0x4a, 0x30, 0xbf, 0x64, 0x48, 0x1c, 0x3c,
- 0xc3, 0xf8, 0x76, 0xb3, 0xfb, 0x45, 0x9f, 0x14, 0x23, 0xba, 0x6b, 0x60,
- 0xb8, 0x8f, 0x31, 0x0f, 0xd2, 0xe6, 0xc8, 0xbc, 0x58, 0x15, 0xba, 0xe0,
- 0xe2, 0x54, 0x8d, 0x92, 0xd1, 0x6d, 0x94, 0x99, 0xe2, 0x77, 0xcf, 0xd8,
- 0x6c, 0x7b, 0xf9, 0x29, 0xcb, 0xf2, 0x9b, 0x99, 0xda, 0xa2, 0xf0, 0xa2,
- 0xf6, 0xa7, 0x77, 0xa9, 0x38, 0x87, 0x5e, 0xb1, 0x2f, 0x29, 0x6b, 0xf5,
- 0xf0, 0x71, 0x45, 0x3f, 0x1b, 0xd7, 0xc1, 0xbb, 0x9d, 0xaa, 0xdd, 0x65,
- 0x47, 0x3b, 0xb4, 0xb9, 0xac, 0xda, 0xe2, 0x99, 0x1a, 0x53, 0x74, 0x2b,
- 0x7d, 0x0b, 0x39, 0x5c, 0x51, 0xb9, 0x7a, 0xc2, 0x7e, 0xa0, 0xd9, 0xfa,
- 0x58, 0x2e, 0x73, 0xdb, 0xff, 0xae, 0xc5, 0x85, 0x2d, 0x77, 0x99, 0x31,
- 0x6f, 0x55, 0xc8, 0x8a, 0xbb, 0x4f, 0x18, 0x8b, 0x5f, 0xec, 0x0f, 0xf1,
- 0xb1, 0x7a, 0xcf, 0xe9, 0x7a, 0x9f, 0x10, 0xa3, 0x61, 0x45, 0xe4, 0xb3,
- 0x74, 0xbb, 0xcb, 0x8e, 0x76, 0x5a, 0x57, 0xe8, 0xfd, 0x87, 0x8f, 0x7c,
- 0xb3, 0x85, 0xdb, 0x3e, 0x19, 0xc3, 0x1b, 0x12, 0xfb, 0xa7, 0x32, 0x46,
- 0x43, 0x1f, 0xc3, 0xbf, 0x8c, 0x98, 0x0a, 0xc4, 0x49, 0x38, 0xf5, 0x8d,
- 0x1c, 0x6f, 0x00, 0x6b, 0x51, 0x15, 0xfb, 0xa6, 0xd8, 0xaf, 0x68, 0x87,
- 0x9d, 0x77, 0x21, 0x36, 0x7f, 0x13, 0x18, 0x74, 0x23, 0xf2, 0x67, 0x7a,
- 0xc8, 0x9f, 0xf3, 0xfd, 0xc8, 0x83, 0x43, 0x3e, 0x5c, 0x76, 0xd2, 0xa0,
- 0x1a, 0xdb, 0x0a, 0x06, 0x95, 0x43, 0x3e, 0x3a, 0x67, 0x5b, 0xd1, 0x8a,
- 0xc0, 0x9a, 0x8f, 0xc0, 0x7f, 0x35, 0xb9, 0x42, 0x07, 0x44, 0xce, 0x38,
- 0x6a, 0x1f, 0x94, 0x79, 0x0d, 0x3e, 0xcd, 0x3c, 0x78, 0x96, 0xed, 0x8f,
- 0xec, 0x49, 0xec, 0xb7, 0xe8, 0x79, 0x41, 0x0e, 0x3c, 0x3e, 0x4d, 0x9e,
- 0xbb, 0xdf, 0xdd, 0x41, 0xc1, 0x38, 0x3f, 0xd3, 0x84, 0x7e, 0xe2, 0xe7,
- 0xa4, 0x29, 0xc1, 0x76, 0x12, 0x6c, 0xd6, 0xd3, 0x27, 0xad, 0x50, 0x99,
- 0x0c, 0x6e, 0x0b, 0xdb, 0x15, 0xcf, 0xc1, 0xfd, 0xf1, 0x50, 0x07, 0xb9,
- 0x73, 0x72, 0x7b, 0x45, 0x9e, 0xe2, 0x5b, 0xd1, 0x07, 0xc9, 0x18, 0x84,
- 0xbe, 0xc2, 0xbc, 0x3d, 0xa0, 0xf6, 0x89, 0xb6, 0xf3, 0xf1, 0x84, 0x3a,
- 0x0e, 0x8a, 0xf9, 0x94, 0xc7, 0x9a, 0xbf, 0xf1, 0xf7, 0xf3, 0x2e, 0xb2,
- 0xfd, 0x6a, 0xfe, 0x9a, 0x62, 0x41, 0x22, 0x63, 0x46, 0x90, 0xce, 0x57,
- 0xd6, 0xf2, 0xbf, 0x78, 0xe5, 0xba, 0x6e, 0xdf, 0x60, 0xae, 0xeb, 0x4f,
- 0x76, 0xc8, 0xdc, 0x32, 0x67, 0x5f, 0xfe, 0x93, 0xfb, 0xe2, 0x85, 0xc9,
- 0x5a, 0x70, 0x22, 0x8f, 0xb7, 0x46, 0x3f, 0x8b, 0x7e, 0x9e, 0xee, 0x84,
- 0x23, 0x2a, 0x66, 0x09, 0x31, 0x4a, 0x0f, 0x2a, 0xbe, 0xd6, 0xba, 0x9f,
- 0x3c, 0x74, 0xff, 0xa3, 0x22, 0x56, 0x53, 0xae, 0x1d, 0x43, 0x8a, 0x1e,
- 0xa0, 0x59, 0xc4, 0x41, 0xb3, 0x01, 0x07, 0xcd, 0x0c, 0x75, 0xbc, 0x4d,
- 0x9c, 0x9f, 0xaf, 0x3c, 0xb5, 0x5d, 0xe6, 0x8b, 0x63, 0x2f, 0xf1, 0x92,
- 0x3a, 0x5e, 0x6f, 0xbc, 0x56, 0x98, 0x82, 0xc2, 0xdf, 0xe4, 0x18, 0xeb,
- 0xcb, 0x44, 0xf6, 0x81, 0x70, 0x2b, 0x0d, 0x5e, 0x73, 0x5c, 0x47, 0x1f,
- 0xc7, 0x1d, 0x7d, 0x1c, 0x75, 0xf4, 0x71, 0x6f, 0x9b, 0x3e, 0xb2, 0x8e,
- 0xe7, 0xf7, 0x9c, 0xad, 0x7e, 0xdc, 0xbe, 0xa2, 0x9f, 0xc8, 0x23, 0x06,
- 0x3d, 0xb7, 0x52, 0x2e, 0x1c, 0x51, 0x6b, 0xc7, 0x2f, 0x55, 0x2e, 0xba,
- 0x57, 0x9f, 0xff, 0x8e, 0xda, 0xcf, 0x9b, 0x93, 0x57, 0x9d, 0xf9, 0xc7,
- 0xdf, 0xa5, 0xa4, 0xcc, 0x23, 0x57, 0xb2, 0x7d, 0xb9, 0x8d, 0x1f, 0x1a,
- 0xf1, 0x1c, 0xc0, 0x20, 0xc2, 0x2e, 0xdc, 0x2d, 0x6b, 0xc1, 0x05, 0x68,
- 0xa9, 0x9e, 0xcb, 0xeb, 0x57, 0xb9, 0x3b, 0xc7, 0xc3, 0xf7, 0x37, 0x8f,
- 0x17, 0xd7, 0xff, 0x4c, 0xf8, 0xf2, 0xe4, 0xfe, 0xd1, 0x8a, 0xca, 0x47,
- 0xb6, 0x4c, 0xc4, 0x06, 0x2c, 0x2e, 0xc3, 0xff, 0xda, 0x2e, 0x77, 0x57,
- 0xea, 0xa2, 0x4c, 0xbd, 0x3e, 0x4a, 0x59, 0xe4, 0x35, 0x48, 0xff, 0x98,
- 0xcc, 0xbf, 0x5d, 0x5c, 0xbe, 0x25, 0x72, 0x5e, 0x13, 0x2a, 0x8f, 0x37,
- 0x43, 0x3d, 0x02, 0xe7, 0x7e, 0xfc, 0xfc, 0xdb, 0x17, 0xc2, 0x9b, 0xcf,
- 0xbf, 0x75, 0xde, 0xb3, 0xb9, 0xfc, 0xdb, 0x10, 0x8f, 0xdd, 0x58, 0x90,
- 0xf9, 0xb7, 0xcd, 0x7b, 0x32, 0x32, 0xff, 0x36, 0xe3, 0xc0, 0x0f, 0x12,
- 0xaf, 0xbf, 0xe5, 0x88, 0xdf, 0x96, 0xb9, 0xb5, 0x8b, 0x75, 0xcc, 0x2a,
- 0x73, 0x6b, 0x65, 0xbc, 0xb7, 0xb3, 0x0e, 0x8c, 0xdc, 0xfb, 0x91, 0xef,
- 0xd9, 0xe6, 0xda, 0xfb, 0x91, 0x39, 0xb5, 0xa6, 0xd1, 0xce, 0x86, 0xc3,
- 0x1a, 0x81, 0x7a, 0x08, 0x71, 0xe6, 0xdd, 0xad, 0x6d, 0xea, 0x21, 0xc4,
- 0xdb, 0xd4, 0x43, 0x70, 0xea, 0x7e, 0x27, 0xc6, 0x02, 0x26, 0xc6, 0xda,
- 0x08, 0x2c, 0x8c, 0x7a, 0x06, 0x51, 0x3a, 0x5f, 0xc7, 0x9e, 0x0f, 0x52,
- 0x5a, 0x61, 0xcf, 0xf3, 0x15, 0xad, 0x8f, 0x46, 0x5d, 0xfa, 0xc8, 0x0b,
- 0x8b, 0x5a, 0x2a, 0xce, 0x47, 0xcb, 0x6b, 0xd6, 0x21, 0xaf, 0x59, 0x0f,
- 0x79, 0xc5, 0x3d, 0xd9, 0x36, 0xfd, 0xfe, 0xa5, 0xba, 0x07, 0xff, 0x4f,
- 0x46, 0x50, 0xb3, 0x85, 0x68, 0xf7, 0x80, 0xc2, 0x7f, 0x0e, 0x79, 0x3d,
- 0xcb, 0xf2, 0xaa, 0xaf, 0xa3, 0xbf, 0xed, 0x6c, 0x00, 0x8d, 0x19, 0x87,
- 0x7c, 0x87, 0xaf, 0xbd, 0x21, 0xe2, 0xa4, 0x9a, 0xed, 0x45, 0x8d, 0x27,
- 0xf6, 0x09, 0x59, 0xba, 0xe3, 0x47, 0xdc, 0x8a, 0xbe, 0x16, 0x52, 0x7e,
- 0x32, 0x4d, 0x8b, 0xce, 0x26, 0xcc, 0xd1, 0xc0, 0x1b, 0x22, 0xc6, 0xd7,
- 0xd1, 0xb7, 0x7f, 0xe5, 0xbe, 0xe9, 0xeb, 0x7a, 0xcd, 0x7c, 0xa7, 0xc9,
- 0x9f, 0x71, 0xa3, 0xa9, 0xee, 0x1f, 0x7c, 0x47, 0xdb, 0xd2, 0x86, 0x9d,
- 0x12, 0x31, 0xa6, 0x7d, 0x36, 0xfc, 0x64, 0x09, 0x96, 0xfd, 0xbe, 0x34,
- 0xe2, 0x99, 0xfb, 0xae, 0x98, 0x74, 0xa2, 0x70, 0x7e, 0x8f, 0xe4, 0x95,
- 0x0b, 0xa2, 0xa6, 0x25, 0x6a, 0x20, 0x26, 0x79, 0x7d, 0x4e, 0x30, 0xe8,
- 0x9c, 0xab, 0x76, 0xd1, 0x22, 0xa3, 0x7b, 0xbf, 0x5d, 0x16, 0xbe, 0x3e,
- 0xd6, 0x49, 0x45, 0xd4, 0x36, 0x35, 0x16, 0x3a, 0xf9, 0xb9, 0x83, 0xb4,
- 0x54, 0x1a, 0x17, 0x35, 0xa1, 0x64, 0x7d, 0x11, 0xb4, 0xf5, 0x51, 0xbf,
- 0xfd, 0x0d, 0xa6, 0xdd, 0xd7, 0x44, 0x8c, 0xe5, 0x62, 0xf1, 0x82, 0xfc,
- 0x2c, 0x3f, 0xa5, 0xde, 0xc1, 0xef, 0xab, 0xfe, 0x98, 0xe2, 0xfd, 0xa6,
- 0xc3, 0x96, 0x73, 0xfe, 0x79, 0xe3, 0x95, 0x63, 0x9b, 0xc2, 0x2b, 0xd9,
- 0x74, 0x03, 0xaf, 0x38, 0x9f, 0xad, 0xb1, 0xcb, 0xe4, 0xa0, 0xac, 0xf7,
- 0x00, 0x1a, 0x6c, 0x05, 0x16, 0x4b, 0x83, 0x96, 0x46, 0xcc, 0x8a, 0x24,
- 0xfc, 0x33, 0x94, 0xaf, 0x5e, 0xa7, 0x4c, 0x11, 0x98, 0x99, 0x3f, 0xcb,
- 0xe7, 0x76, 0x4a, 0x1f, 0x8d, 0xbe, 0x07, 0x7a, 0x65, 0x07, 0xb7, 0xff,
- 0xeb, 0x41, 0x19, 0x97, 0xed, 0xbc, 0xde, 0xcb, 0xd7, 0xbf, 0x10, 0x69,
- 0xbe, 0xbe, 0x85, 0xaf, 0xf7, 0xa7, 0x31, 0x87, 0xc6, 0x15, 0xf8, 0x25,
- 0x27, 0x29, 0xc7, 0xf3, 0x93, 0xaf, 0xf2, 0xda, 0x7a, 0x95, 0xf5, 0x55,
- 0x45, 0xb7, 0x1b, 0x40, 0xce, 0x8e, 0x98, 0x13, 0x83, 0xdb, 0x5c, 0x2c,
- 0x4c, 0x71, 0xbb, 0x21, 0xf2, 0x5f, 0x35, 0x29, 0x5f, 0xd1, 0xbc, 0xaa,
- 0xe3, 0xed, 0xdf, 0x18, 0x90, 0x31, 0x55, 0xef, 0xec, 0x94, 0xf4, 0x9b,
- 0x14, 0x3e, 0x4f, 0xc4, 0x73, 0x3c, 0x23, 0xf8, 0xd0, 0x9a, 0x31, 0xeb,
- 0xef, 0xdf, 0x06, 0xbe, 0x42, 0xdd, 0x54, 0x1e, 0x03, 0xeb, 0xc5, 0x98,
- 0x1d, 0xca, 0xd5, 0x63, 0xd5, 0x9e, 0xdb, 0x2d, 0xef, 0xff, 0xe9, 0x80,
- 0xac, 0x55, 0x7a, 0x5b, 0x9d, 0xeb, 0x35, 0x07, 0xf1, 0xcb, 0x3e, 0x41,
- 0x1b, 0xff, 0x02, 0xf4, 0xa5, 0xc1, 0xc7, 0x3c, 0x9e, 0x34, 0xfa, 0xf8,
- 0xb3, 0x01, 0x5d, 0x9f, 0x50, 0x8e, 0xeb, 0x28, 0xf7, 0x37, 0xc5, 0xe3,
- 0xd2, 0xd7, 0xe3, 0x7c, 0xee, 0x35, 0xbf, 0x78, 0x56, 0x30, 0x2d, 0xeb,
- 0x8b, 0x05, 0xd3, 0x99, 0x49, 0x39, 0xcf, 0x0d, 0x9f, 0x6e, 0xa4, 0xee,
- 0xd3, 0x9d, 0x2b, 0xf4, 0x0f, 0xc2, 0xbf, 0x61, 0x5c, 0xe1, 0xf9, 0x0e,
- 0x3f, 0xc3, 0x6d, 0x91, 0xab, 0x90, 0xe3, 0xcf, 0x1e, 0x15, 0xd7, 0xd3,
- 0xca, 0x2b, 0x32, 0x4e, 0x42, 0xaf, 0x5b, 0xb8, 0x77, 0x80, 0x9f, 0x21,
- 0xd7, 0xae, 0xf6, 0xef, 0xa1, 0x96, 0x38, 0x98, 0x56, 0x1e, 0x5b, 0xcb,
- 0x0f, 0x2b, 0xf6, 0x13, 0x3d, 0xf8, 0x6c, 0xad, 0x7a, 0x06, 0xef, 0x08,
- 0x3f, 0x5a, 0xb2, 0x45, 0x5e, 0x21, 0xc7, 0x01, 0xfa, 0xce, 0x7c, 0x96,
- 0xb6, 0xf0, 0x5c, 0x7d, 0xc3, 0xf8, 0x35, 0xec, 0xb7, 0x93, 0x8c, 0x79,
- 0x62, 0x1a, 0x17, 0xec, 0xc9, 0xb3, 0x06, 0xd3, 0xb9, 0x90, 0xad, 0x05,
- 0xec, 0x1e, 0xea, 0x64, 0x59, 0xfd, 0x22, 0x8d, 0xb1, 0xfd, 0x07, 0x99,
- 0xb5, 0x23, 0x29, 0x82, 0xbc, 0x59, 0xa1, 0xc3, 0xcc, 0x13, 0xc9, 0x2a,
- 0xf8, 0xd9, 0xa0, 0x27, 0x4a, 0x44, 0x8f, 0x97, 0xc6, 0x42, 0xdf, 0x27,
- 0xdb, 0x6c, 0x7c, 0x6f, 0x85, 0x12, 0xdc, 0x8f, 0x54, 0xf5, 0x77, 0xe8,
- 0x43, 0x51, 0xe7, 0x04, 0x74, 0xd4, 0xf3, 0xfe, 0xdb, 0x74, 0x3a, 0x8d,
- 0x7e, 0x6f, 0x5c, 0x3e, 0x4f, 0x6c, 0x4a, 0x3e, 0x83, 0x1e, 0xf2, 0xf9,
- 0xea, 0xa0, 0xe4, 0x9b, 0x1a, 0xf3, 0x68, 0x90, 0x66, 0x8b, 0x88, 0x01,
- 0x7b, 0x18, 0x75, 0xa7, 0x8a, 0x19, 0xd6, 0x4b, 0x99, 0x86, 0x5e, 0xba,
- 0x94, 0xf0, 0xc7, 0x21, 0xe3, 0xa8, 0xcb, 0xa6, 0xe2, 0x7e, 0x30, 0x8e,
- 0xdd, 0x34, 0xb6, 0xb0, 0x95, 0xef, 0xa5, 0x95, 0xc4, 0x74, 0x5c, 0xe5,
- 0xfa, 0x5b, 0x66, 0x92, 0xf5, 0xe3, 0x1c, 0xcb, 0x72, 0xae, 0xf8, 0x00,
- 0x2d, 0x86, 0x87, 0x69, 0x74, 0x41, 0xd7, 0x37, 0xc1, 0x58, 0xff, 0x6d,
- 0x48, 0xea, 0x24, 0x3d, 0xee, 0x5f, 0x11, 0xbe, 0x0b, 0xf3, 0xfa, 0xa7,
- 0x35, 0xee, 0xad, 0xeb, 0xe8, 0xa5, 0xbf, 0x52, 0x32, 0x5b, 0xbb, 0x91,
- 0x88, 0x52, 0x36, 0x31, 0xfd, 0x97, 0x82, 0xff, 0x47, 0xaf, 0xc3, 0x0f,
- 0x07, 0x1d, 0x6d, 0x52, 0xba, 0xe0, 0xa6, 0xc5, 0x30, 0x8f, 0x1b, 0xdf,
- 0xd7, 0xfe, 0x79, 0x36, 0xfa, 0x94, 0x58, 0xfb, 0xc7, 0xae, 0x73, 0x3b,
- 0xb1, 0x36, 0x69, 0xbd, 0xe1, 0xc5, 0x87, 0xba, 0x8e, 0xa5, 0xe6, 0x45,
- 0x19, 0xeb, 0xc9, 0xf8, 0x2d, 0x94, 0xf6, 0xbb, 0x79, 0xf2, 0x23, 0x3a,
- 0x36, 0x6f, 0xd2, 0xf1, 0x82, 0xf5, 0x7c, 0x96, 0x66, 0x58, 0xae, 0x9d,
- 0xeb, 0x05, 0xb7, 0x27, 0xf0, 0x59, 0x8c, 0x65, 0x9f, 0xed, 0xe6, 0xa2,
- 0x29, 0xe3, 0xee, 0x44, 0xed, 0xb9, 0x2e, 0xa1, 0x47, 0x43, 0xf6, 0x3f,
- 0x0d, 0xea, 0xf5, 0x20, 0x53, 0x44, 0x1e, 0x21, 0x7f, 0x96, 0xb9, 0x7d,
- 0x61, 0x90, 0x32, 0x25, 0x3c, 0x07, 0xeb, 0x1d, 0xfa, 0xce, 0xe7, 0x4b,
- 0x72, 0x5e, 0x47, 0xf9, 0xd9, 0xc8, 0xbb, 0x3f, 0x5e, 0x9d, 0x12, 0xb1,
- 0x77, 0xd0, 0xcd, 0x72, 0x3e, 0x63, 0x74, 0xd1, 0x53, 0xaf, 0x28, 0x4c,
- 0xe9, 0x90, 0xef, 0x8c, 0x90, 0xef, 0x98, 0x98, 0x8f, 0x4c, 0xc9, 0x60,
- 0xbc, 0xa6, 0x7d, 0x0f, 0xfd, 0x7c, 0x1e, 0x50, 0x3a, 0x04, 0xdf, 0x0d,
- 0xec, 0x14, 0x71, 0x89, 0x36, 0xae, 0xe3, 0x33, 0x46, 0xcf, 0x30, 0xee,
- 0x7c, 0xb6, 0xd0, 0x45, 0xb7, 0x8a, 0x5d, 0xf4, 0x66, 0x71, 0x98, 0x6e,
- 0xce, 0x6f, 0xa7, 0x8b, 0x8c, 0x99, 0x2f, 0xda, 0x01, 0x33, 0xc7, 0xf6,
- 0xc5, 0x0b, 0x51, 0x11, 0x33, 0xc4, 0x72, 0x87, 0xf6, 0xc0, 0x7f, 0x89,
- 0x5d, 0xcc, 0x73, 0x8c, 0xbd, 0xbb, 0xe9, 0x03, 0x7e, 0x67, 0xae, 0xa0,
- 0x63, 0x1d, 0xe0, 0x93, 0x1f, 0xaf, 0xe3, 0xd7, 0xf5, 0x79, 0x24, 0xb4,
- 0x0e, 0x8f, 0xc4, 0x84, 0xae, 0xcf, 0xcf, 0xf3, 0xf7, 0xf3, 0xf0, 0x9f,
- 0x33, 0xbd, 0x59, 0x3f, 0x7f, 0x3d, 0x80, 0xf6, 0xb8, 0x66, 0xcb, 0x58,
- 0x49, 0x31, 0xb6, 0x08, 0x9f, 0x83, 0xb6, 0x11, 0x45, 0x87, 0x6e, 0x1e,
- 0x9f, 0x4f, 0xb4, 0xcf, 0x2c, 0x75, 0xd3, 0x99, 0x12, 0x63, 0x90, 0x92,
- 0x9f, 0x6d, 0x18, 0xb4, 0x0d, 0xec, 0xd5, 0xf5, 0x5f, 0x2f, 0x72, 0xdf,
- 0x73, 0x25, 0x89, 0x41, 0x72, 0x4b, 0xbd, 0x94, 0x2f, 0xf5, 0xa8, 0xf3,
- 0x07, 0x44, 0x8c, 0xbb, 0xac, 0x63, 0x84, 0xef, 0xd6, 0xd2, 0x6f, 0x6f,
- 0x31, 0x4f, 0x61, 0x4d, 0x95, 0x76, 0x29, 0x74, 0xcd, 0x8d, 0x96, 0xba,
- 0xc4, 0xe0, 0xb9, 0x19, 0xfa, 0x2e, 0xaf, 0xb7, 0xa3, 0x57, 0xe1, 0x3f,
- 0xfe, 0x2a, 0xf8, 0xa6, 0x0c, 0x1e, 0x1b, 0xbd, 0x8a, 0xba, 0x48, 0x7e,
- 0x91, 0xe7, 0x94, 0x0c, 0x4f, 0x8a, 0xdc, 0x10, 0x29, 0xa3, 0x27, 0x45,
- 0x2d, 0xba, 0x1f, 0x0a, 0xdd, 0x64, 0x65, 0x4d, 0x03, 0x78, 0x04, 0x3e,
- 0x18, 0x19, 0x83, 0x75, 0xc2, 0xee, 0x7b, 0x6b, 0x20, 0x36, 0x41, 0xf1,
- 0x41, 0xf0, 0xbd, 0x94, 0x59, 0x55, 0x5f, 0x40, 0xe8, 0xfb, 0xd0, 0x3e,
- 0x9d, 0x2f, 0xa9, 0xcf, 0xf5, 0x5a, 0xa1, 0xcf, 0x7b, 0x5c, 0xdf, 0x87,
- 0x5c, 0xdf, 0xd7, 0xe3, 0xe5, 0x78, 0xcd, 0xe3, 0x75, 0x9e, 0x64, 0x8d,
- 0xa2, 0xcc, 0x82, 0xe4, 0xbf, 0xd0, 0xbe, 0xf1, 0xd0, 0x97, 0x15, 0x06,
- 0xcf, 0x2c, 0x8f, 0x45, 0xfa, 0x8c, 0x1e, 0x7f, 0x66, 0xea, 0xef, 0x6b,
- 0xf1, 0x34, 0x70, 0xd1, 0xdc, 0x4e, 0xa9, 0xe3, 0xd0, 0xaf, 0x6c, 0x14,
- 0xd0, 0xed, 0xe4, 0x72, 0x0f, 0xad, 0x88, 0x9a, 0x5c, 0xc0, 0x18, 0xb8,
- 0x1f, 0xcf, 0xc9, 0x86, 0x3a, 0x08, 0x35, 0xd7, 0x21, 0xe3, 0x07, 0x22,
- 0xd7, 0x79, 0x3e, 0x53, 0xcb, 0xff, 0x55, 0x3b, 0x2d, 0x6a, 0xdc, 0xa0,
- 0x2d, 0x63, 0x48, 0x81, 0xf9, 0x19, 0xbf, 0x34, 0xd9, 0x55, 0x33, 0xe8,
- 0x67, 0x16, 0x7b, 0x2b, 0x86, 0xfd, 0x22, 0xcb, 0x98, 0xdc, 0x2b, 0x4f,
- 0xb9, 0xf6, 0xca, 0x4f, 0x8a, 0xbd, 0x72, 0xec, 0x93, 0x83, 0xae, 0xa0,
- 0xa5, 0x57, 0x4c, 0x0b, 0xe6, 0x31, 0xca, 0xf3, 0x68, 0xd2, 0xc5, 0x6b,
- 0x42, 0xdf, 0x44, 0x93, 0x7e, 0x19, 0x5f, 0x9d, 0xa2, 0xac, 0x88, 0xbf,
- 0x96, 0x9f, 0x71, 0x23, 0x61, 0x5b, 0x93, 0xab, 0x8c, 0x29, 0x2a, 0xc5,
- 0x2d, 0x74, 0xb3, 0xdc, 0xc1, 0x98, 0xef, 0x6f, 0x69, 0xb5, 0x4c, 0x8c,
- 0x0d, 0xb7, 0x53, 0x3e, 0xca, 0xbc, 0x36, 0x19, 0xe4, 0x79, 0x65, 0x7c,
- 0x3b, 0xc9, 0xf2, 0xc7, 0x63, 0xa8, 0x94, 0x6a, 0xef, 0xe7, 0xa2, 0x71,
- 0x33, 0x31, 0xdd, 0xc3, 0xf6, 0x4b, 0x88, 0xff, 0x6d, 0xfe, 0xff, 0x6c,
- 0x04, 0xb4, 0x59, 0x5c, 0xc2, 0xf7, 0x8c, 0x7d, 0x0a, 0xb5, 0xf7, 0x67,
- 0xb9, 0xcd, 0xec, 0x34, 0xec, 0x20, 0xd8, 0x7b, 0x36, 0xff, 0xcb, 0x36,
- 0x15, 0xe6, 0xbb, 0xdc, 0xb5, 0x6c, 0xc4, 0x10, 0x3a, 0x1e, 0x75, 0x5d,
- 0xc6, 0xd4, 0x67, 0xdc, 0x98, 0xe5, 0xbe, 0xdc, 0x24, 0x3c, 0xc3, 0xa4,
- 0x4c, 0x74, 0x1f, 0xcb, 0xc1, 0x76, 0xfe, 0x44, 0x3e, 0xd6, 0x56, 0xca,
- 0x4f, 0x8d, 0xab, 0x7c, 0xac, 0x48, 0x9b, 0x7c, 0x2c, 0xdc, 0xc7, 0x38,
- 0x60, 0xbe, 0x76, 0x6f, 0x36, 0xea, 0x7c, 0x2f, 0x19, 0x99, 0xe8, 0x36,
- 0x81, 0x99, 0x2a, 0x4b, 0xfb, 0xb9, 0x0f, 0x71, 0x33, 0x33, 0xcd, 0x7d,
- 0x2d, 0x39, 0xfb, 0x5f, 0xbb, 0x97, 0x8c, 0xa2, 0x9d, 0xdf, 0xd5, 0x2e,
- 0x4e, 0xa2, 0xed, 0x12, 0xda, 0xd7, 0xfe, 0x27, 0x11, 0xd5, 0xe3, 0x74,
- 0xde, 0x8b, 0xf1, 0x40, 0xbe, 0xf8, 0xb3, 0x72, 0x9b, 0x6e, 0x16, 0x61,
- 0x8f, 0x1b, 0xcc, 0xf7, 0xe8, 0x91, 0x49, 0xd9, 0x0a, 0x63, 0xc0, 0x6b,
- 0x7b, 0x7d, 0xab, 0xc5, 0x37, 0x6a, 0x99, 0xa6, 0xd8, 0x96, 0x66, 0x3f,
- 0xbc, 0xb4, 0xc1, 0x86, 0xc9, 0xbe, 0x82, 0x35, 0x14, 0xeb, 0x67, 0xb6,
- 0xe6, 0xb7, 0x81, 0xf7, 0x60, 0x1b, 0x5d, 0x60, 0xfd, 0x25, 0xe3, 0x93,
- 0x58, 0x97, 0xb2, 0x0e, 0x93, 0xf2, 0x93, 0x6a, 0xfa, 0x39, 0x04, 0xc9,
- 0xc3, 0xa3, 0x8d, 0xb8, 0x48, 0xc7, 0xfe, 0x7a, 0xc0, 0xb1, 0xbf, 0x1e,
- 0x72, 0xc4, 0x45, 0x86, 0x05, 0x3e, 0x6b, 0x60, 0xaa, 0xb0, 0xc2, 0x54,
- 0xc0, 0x5e, 0x52, 0xb7, 0x2d, 0xd6, 0x75, 0xdb, 0x8e, 0x75, 0x74, 0x9b,
- 0x97, 0xad, 0xba, 0xa2, 0xf4, 0x88, 0x15, 0xc5, 0x1a, 0x73, 0x83, 0xf5,
- 0xc5, 0xeb, 0xd5, 0x69, 0xd6, 0x23, 0x51, 0xd6, 0x23, 0x53, 0xac, 0x47,
- 0x26, 0x59, 0x8f, 0xd8, 0x4c, 0x03, 0x93, 0xc7, 0xfe, 0x11, 0xeb, 0x69,
- 0xac, 0x1f, 0x33, 0xf4, 0x4c, 0x15, 0x3a, 0x79, 0x8a, 0x31, 0xd0, 0x47,
- 0xb4, 0x3a, 0xdf, 0xcb, 0xfc, 0x2b, 0x71, 0x4f, 0xb3, 0x5d, 0x83, 0xda,
- 0x2b, 0xf0, 0x17, 0xff, 0x39, 0xf4, 0xce, 0x2b, 0x59, 0x1a, 0xf1, 0xdd,
- 0x2c, 0x82, 0xce, 0xab, 0xa8, 0x55, 0xf1, 0x12, 0x64, 0x1b, 0x35, 0x82,
- 0x7f, 0x30, 0x31, 0xc3, 0x7d, 0x1f, 0xf1, 0xe5, 0x79, 0x5e, 0xbe, 0x1d,
- 0xcd, 0x86, 0xfa, 0x59, 0x06, 0x8e, 0x2b, 0x19, 0x38, 0xde, 0x90, 0x81,
- 0x6c, 0x8e, 0x47, 0xd2, 0xb7, 0xb0, 0x9d, 0xc6, 0x0f, 0x26, 0x76, 0xf5,
- 0xb1, 0xfc, 0x22, 0x66, 0xa2, 0x51, 0xbf, 0xc7, 0x4f, 0xa7, 0xc3, 0x41,
- 0x55, 0xf7, 0xc7, 0x14, 0x39, 0xef, 0xf9, 0xe2, 0xbb, 0x8c, 0x4b, 0x58,
- 0x4e, 0x43, 0x38, 0xbf, 0x0c, 0xbf, 0x28, 0xdb, 0x0d, 0xdd, 0xc2, 0xaf,
- 0xb4, 0x28, 0xda, 0xe2, 0xdc, 0x9a, 0x64, 0x1d, 0x17, 0x5d, 0x31, 0xac,
- 0x99, 0xb8, 0xf1, 0x9b, 0xc3, 0xa8, 0xe1, 0xfe, 0x83, 0xea, 0xe7, 0x86,
- 0xe5, 0xde, 0x5c, 0x72, 0x97, 0xd4, 0x27, 0xcc, 0xa3, 0xe1, 0xb8, 0xb0,
- 0xdd, 0x3a, 0xae, 0xc8, 0xf5, 0x73, 0x91, 0xe7, 0xbb, 0x12, 0x9d, 0xe4,
- 0xf9, 0xee, 0x51, 0x6b, 0x67, 0x96, 0xbf, 0x17, 0xeb, 0x32, 0xaf, 0xa1,
- 0xc3, 0xa8, 0x7f, 0x1f, 0x12, 0x75, 0x22, 0x4e, 0xa2, 0x0e, 0x4f, 0x02,
- 0xcf, 0x63, 0xee, 0x85, 0xfe, 0xf8, 0x07, 0x5e, 0xa3, 0xf1, 0x5e, 0xf0,
- 0x23, 0x1f, 0x97, 0x67, 0xe8, 0x52, 0x41, 0xf7, 0xe1, 0x3d, 0x32, 0xbe,
- 0x8b, 0x7e, 0xf8, 0x68, 0x87, 0xfd, 0x9e, 0xc8, 0x05, 0x31, 0xfe, 0xc4,
- 0xdd, 0xa7, 0xa3, 0xaa, 0x4f, 0xa8, 0x75, 0xd9, 0x85, 0xda, 0x3e, 0x84,
- 0x9a, 0x48, 0x8b, 0xa2, 0x16, 0x65, 0xa7, 0xb0, 0x59, 0x17, 0x85, 0xed,
- 0xb1, 0x7f, 0x57, 0xa3, 0x3e, 0xe6, 0x7e, 0xd7, 0xb5, 0x3b, 0xbc, 0x6e,
- 0x1d, 0x12, 0x18, 0x6d, 0x14, 0xf5, 0xda, 0x45, 0x5e, 0xea, 0x8c, 0xf8,
- 0xce, 0x58, 0xc0, 0x77, 0x0f, 0xa9, 0xef, 0x3e, 0x2f, 0xb0, 0xb1, 0x11,
- 0xeb, 0x66, 0xbd, 0x28, 0xf8, 0x9d, 0xe7, 0xd9, 0x9e, 0x64, 0x7e, 0x8f,
- 0x54, 0xf8, 0xb9, 0xa7, 0x05, 0x3d, 0x35, 0x3d, 0x40, 0x0b, 0xc8, 0x40,
- 0x8f, 0xe2, 0x7f, 0xcb, 0x4c, 0xf9, 0xf5, 0xb8, 0xdb, 0xd1, 0x99, 0xb1,
- 0x4e, 0x01, 0x63, 0xc5, 0x98, 0x4c, 0x5f, 0xbc, 0x1c, 0xf1, 0xe5, 0xe6,
- 0x61, 0xeb, 0x20, 0xdf, 0x65, 0x0f, 0xe2, 0xa9, 0xb8, 0x0f, 0x3b, 0x29,
- 0x9e, 0x46, 0xbf, 0xd0, 0x4e, 0xd3, 0xc0, 0x76, 0xd1, 0xc2, 0x79, 0xdf,
- 0x76, 0x75, 0x5f, 0xb7, 0x98, 0x0b, 0x32, 0xf0, 0x1e, 0xfd, 0x6e, 0xbc,
- 0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x00, 0xeb, 0xed, 0xc4,
- 0xb4, 0x7c, 0x96, 0x71, 0x5d, 0x7e, 0x37, 0x60, 0x7b, 0xf7, 0x57, 0xce,
- 0x9f, 0x4f, 0xd5, 0xf1, 0xc1, 0xfc, 0x6d, 0xa7, 0xb2, 0xf0, 0x7d, 0xe2,
- 0xbb, 0x11, 0x9f, 0xb0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xf3,
- 0x33, 0xc5, 0xdb, 0xc2, 0x66, 0xcf, 0xa5, 0x47, 0x7c, 0xe5, 0x32, 0xc6,
- 0x3b, 0xe2, 0x4b, 0xb1, 0x0c, 0x24, 0x8b, 0x89, 0x5a, 0x5e, 0xe2, 0x02,
- 0x3a, 0xdd, 0x6f, 0x85, 0x4e, 0x1b, 0xef, 0x0f, 0xcb, 0x9a, 0xb7, 0x38,
- 0x66, 0x39, 0x2c, 0xb0, 0x1c, 0x16, 0x58, 0x0e, 0x0b, 0x2c, 0x87, 0x6c,
- 0xab, 0xbe, 0x56, 0x60, 0x39, 0xe4, 0xb5, 0xe4, 0x55, 0x5e, 0x4b, 0xa4,
- 0xec, 0xc6, 0x95, 0x7f, 0x53, 0xcb, 0xae, 0x3b, 0x6f, 0x53, 0xcb, 0x2a,
- 0xd6, 0x6f, 0xf2, 0x1d, 0x99, 0x68, 0x96, 0xd9, 0x5b, 0x2c, 0xb3, 0x1d,
- 0xb1, 0x41, 0xba, 0x5b, 0xc2, 0x9c, 0x59, 0xe6, 0x1c, 0xeb, 0xea, 0x94,
- 0x1f, 0x58, 0x2b, 0xc0, 0xf2, 0x04, 0xac, 0x69, 0x31, 0xdd, 0x07, 0xe9,
- 0x1e, 0xeb, 0xeb, 0xbb, 0x25, 0xc8, 0xf0, 0x1e, 0x75, 0x6e, 0xb1, 0x0c,
- 0x63, 0xfd, 0xb3, 0x7d, 0xb7, 0x8a, 0x06, 0x63, 0xb2, 0x40, 0x28, 0x43,
- 0xd0, 0xa7, 0x02, 0xa7, 0xf1, 0xbc, 0xaf, 0xb0, 0xde, 0x87, 0x0f, 0x0f,
- 0xeb, 0xc5, 0x19, 0x1f, 0xaf, 0x17, 0x91, 0x9b, 0xac, 0x4f, 0xcf, 0x97,
- 0x6c, 0x96, 0xfb, 0x7e, 0xfa, 0x56, 0x09, 0xeb, 0x34, 0x68, 0xc4, 0xe7,
- 0x65, 0x12, 0xbe, 0x31, 0x23, 0x86, 0xb1, 0x8f, 0x67, 0x0d, 0xc1, 0x27,
- 0x7f, 0x0a, 0x3a, 0x30, 0xed, 0x5f, 0xdc, 0x85, 0xda, 0xf3, 0x71, 0xa3,
- 0x53, 0xf9, 0x1a, 0x71, 0x8c, 0xf6, 0x68, 0x0b, 0xba, 0xe1, 0xbc, 0xdd,
- 0xbe, 0x24, 0x7e, 0xb3, 0x21, 0x0a, 0xff, 0x9b, 0x4b, 0x7f, 0x5d, 0xe2,
- 0xfb, 0x05, 0xbd, 0x66, 0x12, 0x7e, 0xe4, 0x90, 0xd3, 0xd3, 0xfe, 0xd8,
- 0x0c, 0x3d, 0x5b, 0x45, 0xbf, 0xaf, 0x52, 0x3e, 0x0c, 0x7d, 0x64, 0x45,
- 0xef, 0x90, 0xa4, 0x5d, 0x37, 0xe3, 0xce, 0x27, 0xbc, 0x75, 0x9c, 0x99,
- 0x10, 0x38, 0xb9, 0x8b, 0xf5, 0x0b, 0x68, 0xf3, 0x13, 0xe6, 0x35, 0x7e,
- 0x5f, 0x41, 0xeb, 0xb7, 0x1f, 0xb3, 0xce, 0xc1, 0x9c, 0xe1, 0x7c, 0x6d,
- 0x9d, 0xb6, 0xaa, 0x74, 0x9a, 0xed, 0xd0, 0x69, 0xb9, 0xba, 0x4e, 0x63,
- 0xde, 0x10, 0xba, 0x0c, 0xba, 0xea, 0x51, 0xc6, 0x91, 0xf2, 0x18, 0xf8,
- 0x70, 0x87, 0xd0, 0x5d, 0xac, 0xfb, 0xd9, 0xae, 0x58, 0xac, 0x66, 0x7d,
- 0x87, 0x85, 0x0e, 0xd1, 0xfc, 0xbd, 0x7f, 0xb7, 0x94, 0x8b, 0x6e, 0xa1,
- 0x0f, 0x72, 0x27, 0xa1, 0xb7, 0xbc, 0xda, 0x8f, 0x73, 0x3b, 0xb4, 0xb7,
- 0x23, 0x2f, 0xb1, 0x3e, 0x5b, 0x8c, 0xc2, 0xa6, 0xed, 0x51, 0xb6, 0x0f,
- 0xea, 0x72, 0x61, 0xaf, 0x0b, 0x63, 0xd5, 0xfa, 0x6c, 0x40, 0xf9, 0x35,
- 0xe0, 0x87, 0xc4, 0x9c, 0xb7, 0xc5, 0x08, 0x26, 0x30, 0x02, 0xdf, 0x13,
- 0x60, 0x7a, 0x89, 0x1a, 0xe2, 0x44, 0xef, 0xd2, 0xaa, 0x90, 0x8d, 0x77,
- 0x05, 0x76, 0xc9, 0xf3, 0x77, 0xb3, 0xd3, 0x07, 0x45, 0x3f, 0xf3, 0x4b,
- 0x0d, 0xfd, 0x38, 0x57, 0x78, 0x0f, 0xeb, 0x86, 0xe8, 0x6b, 0x65, 0x42,
- 0xea, 0xc0, 0xc5, 0x32, 0x6a, 0x80, 0x89, 0x3e, 0x73, 0x5f, 0xf5, 0x38,
- 0xd1, 0x0f, 0xad, 0x0f, 0x36, 0x22, 0x7b, 0x8c, 0x6b, 0xfb, 0x31, 0x47,
- 0x59, 0x07, 0x0f, 0x3d, 0xcb, 0xef, 0xc7, 0xb5, 0xf5, 0xc7, 0x73, 0xaf,
- 0x3e, 0x1e, 0xf8, 0xf6, 0x70, 0xcf, 0xbb, 0x74, 0x57, 0x8d, 0xe7, 0x6e,
- 0x7d, 0x3c, 0xcf, 0xa8, 0xf1, 0x50, 0xce, 0x88, 0x0d, 0x28, 0xdc, 0xbf,
- 0xe1, 0x67, 0x77, 0x27, 0x18, 0xc7, 0xe4, 0x96, 0x40, 0xe7, 0xfd, 0x8a,
- 0x9f, 0x9c, 0x7e, 0x54, 0x67, 0x5f, 0xad, 0xc9, 0x3b, 0xac, 0x7f, 0xef,
- 0x09, 0x1c, 0x33, 0xc2, 0x38, 0x06, 0xd7, 0x29, 0x0f, 0x3d, 0x9d, 0x0b,
- 0xa3, 0x4e, 0xed, 0x0c, 0x8f, 0x9b, 0xed, 0xb1, 0x69, 0xfe, 0x14, 0xfe,
- 0x35, 0x3c, 0x47, 0xdf, 0xff, 0x3c, 0xdd, 0x9b, 0x87, 0x2e, 0x07, 0x8e,
- 0x95, 0xb5, 0x6c, 0xef, 0x2d, 0x4b, 0xff, 0x6e, 0xca, 0xd3, 0xbf, 0x0b,
- 0xdf, 0xee, 0x34, 0x70, 0x7e, 0x08, 0x7e, 0xe0, 0xa4, 0xfa, 0xad, 0x8f,
- 0x5c, 0x15, 0xcf, 0xf2, 0xd2, 0x4b, 0x33, 0x8e, 0xd8, 0x38, 0xc4, 0xaa,
- 0x64, 0x59, 0xcf, 0xd8, 0xa1, 0x0e, 0x43, 0xe6, 0xdc, 0xdc, 0xa8, 0x6a,
- 0xec, 0x74, 0x94, 0xe7, 0xcc, 0x8e, 0x1a, 0x46, 0x4a, 0xf8, 0x1a, 0xba,
- 0xed, 0x1e, 0xea, 0xe2, 0x75, 0xf4, 0x2c, 0xa1, 0x96, 0x9a, 0x65, 0x62,
- 0x0f, 0xe0, 0x12, 0xf3, 0x64, 0x3e, 0x6a, 0x45, 0x1e, 0x17, 0x76, 0x29,
- 0xd6, 0x17, 0x03, 0x74, 0x62, 0x5a, 0xa3, 0x0f, 0x7c, 0xbc, 0x84, 0x3a,
- 0x9a, 0x51, 0x1e, 0x3f, 0xfc, 0xc7, 0x63, 0xe6, 0x9b, 0xbc, 0x2e, 0x5d,
- 0x12, 0x7e, 0x99, 0x0b, 0x94, 0x63, 0x39, 0x3d, 0x22, 0xe4, 0xd4, 0x18,
- 0x61, 0x29, 0x62, 0xb9, 0x42, 0x6c, 0xc2, 0xb8, 0xa8, 0xdb, 0x23, 0x6d,
- 0x1d, 0x1e, 0xe5, 0xb2, 0xaa, 0x87, 0x90, 0x86, 0xee, 0xd8, 0xb8, 0x4f,
- 0x22, 0xfd, 0x89, 0x7d, 0x31, 0x4e, 0x4c, 0xe6, 0xf6, 0x7d, 0xc3, 0xae,
- 0x33, 0x45, 0xbd, 0x48, 0xd0, 0x4e, 0xf8, 0x13, 0x8d, 0x29, 0xa6, 0x9b,
- 0xfe, 0xdd, 0x19, 0xa7, 0xdf, 0xe0, 0x9c, 0xc8, 0xeb, 0x7f, 0xa5, 0x2a,
- 0xd7, 0xe0, 0x1c, 0xdb, 0xf4, 0xf9, 0x83, 0x4e, 0x4c, 0x62, 0x15, 0x93,
- 0xc2, 0x97, 0xb3, 0x9b, 0x12, 0x0b, 0x53, 0xf4, 0x68, 0x01, 0x3a, 0x8c,
- 0xee, 0x24, 0x6c, 0xfc, 0xa2, 0x0c, 0x64, 0x7c, 0x8a, 0x52, 0x55, 0xd0,
- 0xc8, 0xc7, 0x58, 0x89, 0x79, 0xaf, 0x88, 0x3d, 0x7f, 0x3e, 0x2e, 0xe3,
- 0x77, 0x54, 0x7e, 0x5d, 0xf9, 0xcb, 0x87, 0x29, 0xb9, 0x40, 0xd9, 0x4c,
- 0xf4, 0x4b, 0xa2, 0xd6, 0x75, 0x26, 0x3a, 0xa1, 0x7c, 0x3b, 0x11, 0xbe,
- 0x0e, 0x7f, 0x99, 0x49, 0x5f, 0x2e, 0x58, 0xd9, 0x0c, 0x49, 0x9f, 0x05,
- 0x71, 0x1f, 0x0c, 0x5e, 0x7b, 0x77, 0xb0, 0x0e, 0x39, 0x21, 0xfc, 0x16,
- 0x8c, 0x54, 0xe6, 0xd1, 0x1e, 0x3e, 0x87, 0x7e, 0x82, 0x9d, 0x96, 0x29,
- 0x3e, 0xa5, 0xda, 0xd6, 0x28, 0xc4, 0xbc, 0x10, 0xfa, 0x55, 0x3b, 0x1b,
- 0x35, 0x1a, 0xf7, 0xc3, 0xe7, 0x71, 0x42, 0xe0, 0xc8, 0x11, 0xb6, 0x79,
- 0x44, 0xbb, 0xda, 0xac, 0xf0, 0x5f, 0xf0, 0x79, 0xf9, 0x81, 0x21, 0xfd,
- 0x9b, 0x08, 0xb8, 0x2e, 0xfd, 0x1a, 0xfc, 0xcc, 0x32, 0xf7, 0xa3, 0x29,
- 0x9e, 0x7e, 0x98, 0xe2, 0x9b, 0xf0, 0x33, 0x9d, 0xbc, 0xaf, 0x7e, 0x26,
- 0xa6, 0x35, 0xaf, 0x3d, 0x37, 0x58, 0x36, 0x5e, 0x5f, 0xd7, 0xfe, 0xfb,
- 0x50, 0xaf, 0xe1, 0x4c, 0xab, 0x90, 0xf8, 0xdd, 0x0c, 0x60, 0xf0, 0x7c,
- 0xf5, 0x71, 0xfc, 0x5e, 0x8c, 0x2f, 0x2d, 0xb0, 0x71, 0x84, 0xb1, 0x0d,
- 0x30, 0xce, 0x98, 0xd8, 0x17, 0x8b, 0x3f, 0x16, 0xf1, 0xe5, 0x97, 0x07,
- 0xc9, 0x0f, 0x7f, 0x9c, 0xad, 0x63, 0x29, 0xba, 0x45, 0xdc, 0xbb, 0xdc,
- 0x8f, 0xc4, 0xfa, 0x0c, 0x9d, 0x78, 0x87, 0xed, 0x86, 0x09, 0x15, 0x87,
- 0xd3, 0x21, 0x6a, 0x53, 0xc9, 0xbd, 0x54, 0xad, 0x53, 0x34, 0xef, 0xe9,
- 0xbd, 0x0e, 0xe7, 0x6f, 0x73, 0x41, 0x76, 0x9d, 0x98, 0x02, 0xfe, 0x29,
- 0x31, 0x47, 0x97, 0x88, 0xe4, 0x1c, 0x37, 0xf6, 0x31, 0xba, 0x78, 0x9e,
- 0x60, 0x0f, 0xc2, 0xef, 0xf7, 0x35, 0xfe, 0xc4, 0x7e, 0xc4, 0xd5, 0x21,
- 0xe0, 0xa8, 0x3e, 0x9b, 0x79, 0x66, 0x1a, 0xe7, 0x83, 0x6c, 0x9f, 0x69,
- 0xdc, 0x2b, 0x7d, 0x51, 0x6c, 0xb3, 0xa9, 0xf9, 0x82, 0x1f, 0x6a, 0x54,
- 0xd5, 0x29, 0xb0, 0xc8, 0xec, 0x07, 0x9d, 0x3e, 0x2d, 0x79, 0x5c, 0x6f,
- 0xef, 0x62, 0x23, 0xb1, 0x4e, 0xf8, 0xdd, 0x30, 0xd4, 0xeb, 0xdc, 0x0b,
- 0xda, 0xf3, 0x1c, 0x39, 0xf7, 0x36, 0x1e, 0xdf, 0xa5, 0x7f, 0xb3, 0xe8,
- 0xfe, 0xcc, 0xdb, 0x16, 0x8f, 0x79, 0xfb, 0xf9, 0x90, 0xdc, 0x3b, 0x7b,
- 0x58, 0xb5, 0xf1, 0x8a, 0x6f, 0x5d, 0xfe, 0x0e, 0xfc, 0x50, 0x8d, 0xfc,
- 0x8b, 0x77, 0x84, 0x5e, 0x69, 0xf5, 0x85, 0x47, 0x58, 0x9f, 0x4a, 0x39,
- 0x3e, 0xe1, 0x21, 0xc7, 0xfd, 0x31, 0xe0, 0x96, 0x8f, 0x2f, 0xc7, 0xc7,
- 0xdb, 0xca, 0xf1, 0x9e, 0x61, 0xe9, 0x8b, 0x6d, 0x95, 0x63, 0xe4, 0x00,
- 0x9d, 0xa8, 0xb6, 0xf3, 0x7b, 0x61, 0x1e, 0x90, 0xcb, 0xee, 0xf4, 0x95,
- 0x80, 0x66, 0xda, 0x5f, 0x82, 0x7d, 0x43, 0xf0, 0x25, 0xf6, 0x5e, 0x4e,
- 0x1a, 0xa9, 0x79, 0xf7, 0x5e, 0xea, 0x46, 0xee, 0xbd, 0xed, 0x71, 0x2f,
- 0xb0, 0x3b, 0x64, 0xc3, 0x8a, 0x48, 0x5f, 0x80, 0xa6, 0xdf, 0xb0, 0xef,
- 0x70, 0xc9, 0xca, 0x96, 0x09, 0xbe, 0xee, 0x30, 0x9d, 0xc3, 0xfe, 0xb4,
- 0xf2, 0x25, 0x1f, 0x2b, 0x48, 0x3a, 0x84, 0x0e, 0x0a, 0xfe, 0x00, 0xbe,
- 0x8d, 0xa4, 0xfd, 0x69, 0x9e, 0x63, 0xe9, 0x47, 0xce, 0x2c, 0x45, 0xd4,
- 0xbc, 0x71, 0x5b, 0x3c, 0xcf, 0x33, 0x5f, 0x10, 0xf3, 0x65, 0x3d, 0xbf,
- 0x52, 0x8f, 0x4f, 0xc6, 0xda, 0x50, 0xa3, 0xff, 0xe0, 0x75, 0xcf, 0x7f,
- 0x30, 0x24, 0x6a, 0x37, 0xdc, 0xa8, 0x1e, 0x64, 0xbc, 0x89, 0x39, 0x85,
- 0x0f, 0x52, 0xfb, 0x88, 0x1f, 0xda, 0x4b, 0xbd, 0x07, 0x18, 0x05, 0x18,
- 0x64, 0x33, 0xbe, 0x34, 0x0e, 0x22, 0xce, 0xdc, 0xe4, 0x7b, 0x50, 0x73,
- 0x6a, 0xdc, 0x4c, 0x51, 0x0f, 0xfc, 0x10, 0xa8, 0x25, 0x6d, 0xe6, 0x9a,
- 0x64, 0xec, 0x94, 0x90, 0xb1, 0xd4, 0xf2, 0x29, 0x25, 0x63, 0xa7, 0x94,
- 0x1f, 0xfe, 0x94, 0x92, 0xb1, 0x53, 0x4a, 0xc6, 0x4e, 0x29, 0x19, 0x3b,
- 0xc5, 0x7c, 0x3e, 0xc6, 0xf8, 0x16, 0x58, 0x44, 0xfb, 0x41, 0x7b, 0x29,
- 0x53, 0xc2, 0x75, 0xac, 0xcf, 0x6e, 0x39, 0x7b, 0x69, 0x44, 0xca, 0x19,
- 0x63, 0x13, 0x19, 0xaf, 0xc7, 0xef, 0xc2, 0x1c, 0xfc, 0x1e, 0xd3, 0xef,
- 0x23, 0x3a, 0x33, 0x8f, 0xbe, 0xfa, 0x28, 0x29, 0x6a, 0xc9, 0x76, 0x50,
- 0xc2, 0x89, 0x85, 0x43, 0xc8, 0x0f, 0x93, 0xb6, 0x5f, 0xb6, 0x6d, 0xae,
- 0x98, 0xe6, 0x93, 0x98, 0x9a, 0x2f, 0xb7, 0x5d, 0xd4, 0x45, 0xe9, 0x22,
- 0xe8, 0x8a, 0x98, 0x4a, 0x93, 0xe7, 0x46, 0xd0, 0x49, 0x86, 0x44, 0xb9,
- 0x68, 0x70, 0x4c, 0xd1, 0xe0, 0xdb, 0x62, 0x8c, 0x88, 0x49, 0x84, 0x2f,
- 0xb3, 0x3d, 0x1d, 0x72, 0x85, 0x31, 0x7e, 0x0e, 0xcb, 0xc2, 0xc1, 0x08,
- 0xeb, 0xa4, 0x8d, 0xd3, 0xa1, 0x31, 0xf6, 0x76, 0xba, 0x67, 0xa3, 0x79,
- 0x39, 0x77, 0x1c, 0x6b, 0x49, 0x44, 0xad, 0x23, 0x12, 0x17, 0x6f, 0xb1,
- 0x6b, 0x74, 0x34, 0xba, 0x97, 0x8f, 0xad, 0x74, 0x96, 0x0e, 0x90, 0xd1,
- 0x57, 0xa3, 0xbf, 0x60, 0x39, 0xe8, 0x66, 0x39, 0x38, 0xaa, 0xec, 0x92,
- 0xa3, 0x75, 0xbb, 0x64, 0xcf, 0x1e, 0xc4, 0x65, 0x64, 0xc4, 0xbe, 0xd7,
- 0x56, 0x55, 0x43, 0x00, 0xbe, 0x6f, 0x9c, 0x77, 0x51, 0x7c, 0x18, 0xe7,
- 0xf8, 0x2d, 0x22, 0x6b, 0x32, 0xee, 0x1b, 0xdf, 0x23, 0xb0, 0xbb, 0xcf,
- 0xc2, 0x3d, 0x47, 0xa5, 0xde, 0xf3, 0x91, 0x7f, 0xfc, 0x36, 0xe3, 0x89,
- 0x1a, 0x3d, 0xc1, 0xef, 0xcc, 0x17, 0xf7, 0xf1, 0xb3, 0x75, 0x4d, 0x09,
- 0x3b, 0x6e, 0xf8, 0xb6, 0x92, 0xbf, 0xaf, 0xdd, 0xbb, 0x2d, 0xc1, 0x8f,
- 0x8c, 0xa7, 0x8d, 0xd9, 0xe8, 0x7b, 0xb5, 0xd3, 0x27, 0xe1, 0x63, 0x87,
- 0x9c, 0x58, 0x21, 0xd3, 0xe7, 0x25, 0x1f, 0x12, 0x2b, 0x35, 0xe2, 0x63,
- 0x21, 0x2f, 0x35, 0xfa, 0x77, 0x1e, 0x5b, 0x88, 0xb0, 0x77, 0x22, 0x9f,
- 0x9f, 0xa6, 0x19, 0x91, 0x83, 0x8d, 0x38, 0xe9, 0x33, 0xf3, 0xfa, 0x5d,
- 0xb6, 0xe2, 0x8d, 0xcf, 0x20, 0xce, 0xad, 0xb8, 0x48, 0x6b, 0xaf, 0x39,
- 0xf0, 0xd7, 0x8d, 0x2d, 0xac, 0xf6, 0x85, 0x45, 0x4e, 0xf8, 0x76, 0xc6,
- 0x48, 0x3a, 0x1e, 0x7a, 0x9c, 0x9f, 0x0f, 0x3f, 0x5e, 0x80, 0x92, 0x57,
- 0xd0, 0xae, 0x93, 0x46, 0x17, 0x6a, 0x5f, 0xe0, 0xef, 0xc5, 0xfe, 0x65,
- 0x86, 0xba, 0xd5, 0xde, 0x44, 0x8f, 0xda, 0xcf, 0x8a, 0xb0, 0xec, 0x35,
- 0x72, 0x9d, 0x47, 0xeb, 0x3e, 0x3d, 0xc8, 0x84, 0xdb, 0xa7, 0xf7, 0xf4,
- 0x3a, 0xeb, 0xd5, 0x7a, 0x72, 0x80, 0x58, 0xd6, 0x2e, 0x52, 0xbe, 0x4a,
- 0x33, 0x4f, 0x1b, 0xcd, 0xe9, 0xdb, 0xf4, 0x3d, 0xdd, 0x9d, 0x31, 0xf3,
- 0xc2, 0x9b, 0x76, 0x50, 0xf1, 0x5f, 0x27, 0x9d, 0x29, 0x05, 0x79, 0xcd,
- 0x87, 0x6e, 0x05, 0xbd, 0xfc, 0xc3, 0xc8, 0x73, 0xf9, 0x7a, 0xa0, 0x93,
- 0x96, 0x96, 0x10, 0x6b, 0xf1, 0x47, 0x7b, 0x64, 0x7c, 0x71, 0x9a, 0xe9,
- 0x72, 0x80, 0xd7, 0x47, 0x43, 0xed, 0x1d, 0xe1, 0x1a, 0x74, 0x89, 0xa8,
- 0x37, 0x1a, 0xf8, 0xd2, 0x44, 0x90, 0xed, 0x02, 0xb9, 0xf7, 0x70, 0x88,
- 0x9f, 0xfd, 0xfd, 0x52, 0x1a, 0xfe, 0xb2, 0xd0, 0x11, 0x7e, 0x7e, 0x92,
- 0xf1, 0x44, 0x9c, 0x3a, 0xa9, 0xb2, 0xd4, 0xc9, 0x76, 0x41, 0x27, 0xe3,
- 0x89, 0xb1, 0xd0, 0xa8, 0x4f, 0xbc, 0x4b, 0xe4, 0xd4, 0x3c, 0x1c, 0x38,
- 0xc0, 0x7c, 0x85, 0x77, 0xbd, 0xae, 0xde, 0xe5, 0x7e, 0xc7, 0x2f, 0x6a,
- 0x38, 0x3f, 0xe2, 0x37, 0x2f, 0xdc, 0xc2, 0xef, 0x51, 0xcd, 0xcf, 0x30,
- 0x76, 0x0e, 0x53, 0x7e, 0xbe, 0x83, 0xc7, 0x10, 0x63, 0x3b, 0x22, 0xca,
- 0xe7, 0x8f, 0x50, 0xb6, 0x7a, 0x92, 0x7e, 0xbf, 0xea, 0xf4, 0x09, 0x3f,
- 0xc2, 0x7d, 0x96, 0x39, 0xfd, 0x5d, 0xdc, 0xaf, 0x0f, 0x6d, 0xb7, 0x8e,
- 0x09, 0x92, 0xff, 0x7b, 0x61, 0xea, 0x7c, 0x0e, 0xbe, 0x97, 0x1a, 0x15,
- 0xa3, 0xd6, 0xa5, 0x3b, 0x24, 0xfd, 0xcf, 0x2f, 0x88, 0xb8, 0x5a, 0xbe,
- 0x9f, 0x9f, 0x39, 0x87, 0x76, 0x2f, 0x98, 0x74, 0xd3, 0x96, 0xf4, 0x7e,
- 0x23, 0x10, 0x26, 0xff, 0xcb, 0x88, 0x7d, 0x02, 0x56, 0x33, 0x2f, 0xd8,
- 0xfb, 0x58, 0xbf, 0x3f, 0x87, 0xfb, 0xf8, 0xf3, 0x65, 0x9c, 0x07, 0x79,
- 0x9c, 0x58, 0xaf, 0x11, 0xef, 0x02, 0xbd, 0x78, 0x20, 0x12, 0x12, 0xfc,
- 0xf7, 0x08, 0xf3, 0x54, 0x87, 0xf0, 0x35, 0xf6, 0xa3, 0xad, 0x3d, 0xc4,
- 0xd8, 0xc2, 0xbc, 0x30, 0xb1, 0x0f, 0xe7, 0xf1, 0x3e, 0x3f, 0xd3, 0x48,
- 0xf2, 0x10, 0xc6, 0xd3, 0xc4, 0xdc, 0x81, 0x43, 0x13, 0xc4, 0xf3, 0x09,
- 0xfc, 0xc1, 0xf3, 0x19, 0x42, 0x7d, 0xa7, 0x20, 0xa5, 0xf8, 0x1d, 0xc9,
- 0x92, 0x1c, 0xf7, 0x5c, 0xd5, 0x4f, 0xd2, 0x4f, 0x75, 0x74, 0x44, 0xff,
- 0x9e, 0x21, 0x0d, 0xe2, 0xd9, 0x5a, 0x56, 0x70, 0xdc, 0x4b, 0x77, 0x4b,
- 0x3d, 0x74, 0x4f, 0xed, 0x69, 0xdd, 0x15, 0x76, 0x19, 0xeb, 0xf0, 0x74,
- 0x2f, 0xdd, 0x59, 0xea, 0x20, 0xea, 0x0f, 0x8a, 0x3d, 0xe7, 0xbb, 0xa5,
- 0x32, 0xbf, 0x3f, 0x31, 0x22, 0xfd, 0x3a, 0x0d, 0x1e, 0xb9, 0xeb, 0xc1,
- 0x23, 0x1f, 0x08, 0x1e, 0xd9, 0x37, 0xb2, 0x36, 0x8f, 0xec, 0x52, 0xb6,
- 0x48, 0x90, 0x3a, 0x15, 0x7f, 0xbc, 0xc4, 0xfc, 0xf1, 0x2c, 0xf3, 0xc7,
- 0xe1, 0x36, 0xfc, 0x61, 0xb8, 0xf8, 0xe3, 0x88, 0xe0, 0x8f, 0x87, 0x46,
- 0xd6, 0xe2, 0x8f, 0xc3, 0xfe, 0xb5, 0x7c, 0x4d, 0xe2, 0xb7, 0x3c, 0x2f,
- 0xcc, 0xd9, 0xbb, 0x99, 0xd7, 0x6d, 0xaa, 0xcc, 0x23, 0x67, 0x61, 0x25,
- 0x6a, 0xd0, 0xbf, 0x08, 0x9b, 0x6c, 0x55, 0xd8, 0xfc, 0x31, 0x11, 0xc3,
- 0xba, 0x28, 0xf8, 0x8b, 0xd7, 0xff, 0x18, 0x72, 0xaa, 0xdc, 0x73, 0xd1,
- 0x4d, 0x37, 0xa3, 0x98, 0x0b, 0x53, 0xcd, 0x05, 0xae, 0x75, 0xe9, 0xfa,
- 0x90, 0x01, 0xbe, 0x7e, 0xe1, 0x03, 0xf0, 0xe8, 0x72, 0x4f, 0x20, 0x59,
- 0xf8, 0xe6, 0x08, 0xf0, 0x5f, 0x7e, 0x99, 0x1c, 0xd7, 0x03, 0x7c, 0x3d,
- 0x2c, 0x7e, 0xfb, 0x09, 0xb2, 0xf2, 0x8f, 0x88, 0x71, 0x64, 0x9e, 0xbc,
- 0x59, 0x1a, 0xa6, 0x5b, 0xa5, 0xdd, 0xb4, 0x5a, 0x1a, 0xa1, 0x37, 0x45,
- 0x2d, 0x0d, 0x99, 0x1b, 0xb9, 0x2a, 0xe6, 0xc8, 0xa0, 0x43, 0x61, 0x6e,
- 0xb3, 0xb4, 0x9b, 0x56, 0x96, 0x34, 0x7f, 0x83, 0xb7, 0xc1, 0x2f, 0xf1,
- 0x3e, 0x99, 0x2f, 0xd7, 0xca, 0x33, 0xc9, 0x26, 0x9e, 0x91, 0xf7, 0x80,
- 0x57, 0xf2, 0xad, 0xb9, 0xbe, 0xdd, 0xa1, 0x18, 0x62, 0xf5, 0x82, 0xd4,
- 0x81, 0xb8, 0x45, 0xc3, 0x9a, 0x3c, 0xe4, 0x07, 0x86, 0xfe, 0x2a, 0xaf,
- 0xb9, 0x3c, 0x67, 0x36, 0xe2, 0x9c, 0x46, 0x18, 0x0f, 0x6f, 0x17, 0xf8,
- 0x37, 0x61, 0x07, 0x22, 0x49, 0xaa, 0x5d, 0x30, 0x6c, 0xd4, 0x73, 0x4c,
- 0xf3, 0xf3, 0x0c, 0xe5, 0x6f, 0xda, 0xe6, 0xe0, 0x3f, 0x37, 0xd6, 0xc5,
- 0x5e, 0xf2, 0x63, 0xdc, 0x67, 0xac, 0xc3, 0x8d, 0xfd, 0x1a, 0xaa, 0xef,
- 0xd7, 0x74, 0xf3, 0xb8, 0xa5, 0xec, 0xcd, 0xda, 0xdc, 0xae, 0xca, 0xed,
- 0xaa, 0xd8, 0xfb, 0xe3, 0xeb, 0x4b, 0xd8, 0x77, 0x1e, 0xa6, 0xd5, 0x79,
- 0xc8, 0x28, 0xfc, 0x21, 0x8d, 0xbd, 0xde, 0xd5, 0x65, 0x5c, 0x87, 0x4f,
- 0xa4, 0xb1, 0xd7, 0xbb, 0xaa, 0xf6, 0x7a, 0x57, 0x97, 0x63, 0x42, 0x6f,
- 0xe7, 0x4b, 0x4c, 0xf7, 0x92, 0x5f, 0xc5, 0x39, 0xee, 0x53, 0xbf, 0x2d,
- 0xf4, 0x98, 0xf0, 0x69, 0xf7, 0xd9, 0x6b, 0xd3, 0xf0, 0x50, 0x0b, 0x0d,
- 0x63, 0x02, 0x67, 0xa5, 0xf8, 0x99, 0xc9, 0xd2, 0x63, 0xff, 0x3b, 0x60,
- 0x78, 0x46, 0x00, 0xf3, 0x9e, 0x30, 0x34, 0xef, 0xc1, 0xe6, 0x8e, 0xf9,
- 0x19, 0x20, 0xf7, 0x14, 0xd9, 0x80, 0xfb, 0x16, 0x90, 0xf2, 0x4a, 0x06,
- 0xad, 0xbc, 0x02, 0xa6, 0x09, 0x75, 0x88, 0xfe, 0xa6, 0xf5, 0x9f, 0xe5,
- 0x60, 0xe3, 0x80, 0x4d, 0x40, 0x73, 0x9b, 0xa7, 0x90, 0x32, 0xf7, 0x0c,
- 0xac, 0x6f, 0xb1, 0xae, 0x6d, 0xb4, 0x01, 0xef, 0xb1, 0x5e, 0x34, 0x85,
- 0x85, 0x61, 0x49, 0x0f, 0x03, 0xb0, 0x7e, 0x00, 0xa5, 0x75, 0x50, 0x1d,
- 0x01, 0x4f, 0xef, 0x02, 0x4d, 0x40, 0xf7, 0x39, 0x01, 0xdb, 0xa2, 0xce,
- 0xfd, 0xca, 0xe0, 0xb5, 0xb2, 0x0d, 0xd0, 0x73, 0xab, 0x16, 0xf5, 0x88,
- 0xc9, 0x83, 0xf2, 0x99, 0x93, 0x0a, 0x03, 0x19, 0x79, 0x81, 0x0d, 0x9a,
- 0x17, 0xc0, 0xe1, 0x04, 0x4c, 0xeb, 0xc0, 0x32, 0x6a, 0x8d, 0x2e, 0xd0,
- 0x3c, 0x1e, 0x16, 0x97, 0x7e, 0x90, 0x18, 0x03, 0x54, 0x8c, 0x05, 0xc8,
- 0x97, 0x01, 0xb6, 0x29, 0x41, 0x7e, 0x05, 0xe5, 0x05, 0x90, 0xd9, 0x20,
- 0xbf, 0x83, 0xca, 0x4e, 0x50, 0x5e, 0x04, 0xb2, 0x97, 0x08, 0x41, 0xfd,
- 0x0c, 0xa4, 0x81, 0xec, 0xe6, 0x29, 0x22, 0x60, 0x7e, 0x52, 0x80, 0x10,
- 0x43, 0x03, 0x3c, 0x1f, 0x10, 0x1b, 0xc6, 0x30, 0xf5, 0x31, 0x64, 0xe4,
- 0x1b, 0x88, 0x19, 0x88, 0x7c, 0xc3, 0xce, 0x70, 0x40, 0x00, 0x16, 0x56,
- 0xff, 0xff, 0x1f, 0x53, 0x61, 0x01, 0xa6, 0x53, 0xd0, 0x3a, 0xd6, 0xdf,
- 0xff, 0x0f, 0x88, 0xb0, 0x30, 0xb4, 0xc0, 0xd7, 0x23, 0xe6, 0xc8, 0x83,
- 0xca, 0xd0, 0x05, 0x40, 0x56, 0x1b, 0xbc, 0x4d, 0xc0, 0x02, 0xbe, 0xef,
- 0x79, 0x01, 0xc3, 0x2f, 0x60, 0x99, 0xf5, 0xff, 0xff, 0x52, 0xb8, 0x5a,
- 0x10, 0x00, 0x00, 0x19, 0x3f, 0x16, 0x21, 0xc4, 0x7d, 0x00, 0x00, 0x00 };
+ 0xdc, 0x5b, 0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae,
+ 0xc8, 0x15, 0x35, 0x22, 0x57, 0xd4, 0x9a, 0xa2, 0xed, 0x5d, 0x72, 0x28,
+ 0xb2, 0x96, 0xea, 0xae, 0x29, 0xa6, 0x62, 0xd3, 0x4d, 0xb4, 0xd9, 0xa5,
+ 0x5c, 0xb5, 0x75, 0x5a, 0x4a, 0x26, 0xfc, 0x48, 0x55, 0x83, 0xde, 0xa5,
+ 0x9c, 0xa0, 0xa8, 0x53, 0xc9, 0x76, 0x85, 0x20, 0x05, 0xaa, 0x05, 0x1f,
+ 0x89, 0x52, 0xb0, 0x1c, 0xc5, 0x92, 0x29, 0xb5, 0x71, 0x6b, 0x96, 0xb4,
+ 0x6c, 0x15, 0xd8, 0x6a, 0x65, 0xc7, 0x6d, 0x68, 0x54, 0x2e, 0x65, 0xca,
+ 0x69, 0x95, 0x26, 0x48, 0x8d, 0xa0, 0x42, 0x95, 0x3f, 0x8e, 0xe1, 0xf4,
+ 0x87, 0x5b, 0xf4, 0x87, 0xd1, 0x07, 0x22, 0xd7, 0x8f, 0xed, 0xf7, 0xdd,
+ 0xb9, 0x43, 0x0e, 0x97, 0x14, 0x45, 0xf9, 0xf5, 0xa3, 0x04, 0x56, 0x33,
+ 0xf7, 0x7d, 0xee, 0xb9, 0xe7, 0x7c, 0xe7, 0x31, 0x57, 0x3f, 0x2f, 0x52,
+ 0x27, 0xfa, 0x6f, 0x3d, 0x7e, 0x89, 0x87, 0x7f, 0xaf, 0x70, 0xfb, 0xce,
+ 0xdb, 0x77, 0xe0, 0xf5, 0x0e, 0xd3, 0xa8, 0x0d, 0xb1, 0x9e, 0xff, 0xc4,
+ 0xf0, 0xeb, 0xd6, 0xef, 0x2b, 0xfd, 0xd9, 0xf8, 0xbd, 0x89, 0xc6, 0xc1,
+ 0x7f, 0x17, 0x31, 0xae, 0xd1, 0x27, 0xf8, 0x57, 0xa9, 0xac, 0xde, 0x6e,
+ 0x92, 0x96, 0x55, 0xda, 0x43, 0xde, 0x92, 0x8a, 0x66, 0xfe, 0x24, 0x62,
+ 0xa6, 0x33, 0x47, 0xb2, 0x8e, 0x11, 0x09, 0xa5, 0xbb, 0x8a, 0x05, 0x47,
+ 0x24, 0x53, 0xda, 0x96, 0xc8, 0xc9, 0x7b, 0x95, 0x62, 0xcc, 0x92, 0xac,
+ 0x23, 0x91, 0x9b, 0xd3, 0xef, 0x3e, 0xf5, 0xd2, 0xce, 0xe4, 0x5b, 0x53,
+ 0x21, 0x89, 0xd8, 0xe9, 0x17, 0xc4, 0xde, 0x2a, 0x91, 0x56, 0x8c, 0x79,
+ 0xb2, 0x33, 0x63, 0x48, 0x83, 0x3f, 0xd7, 0x9b, 0x95, 0x97, 0x3a, 0xa5,
+ 0xd8, 0x92, 0x8e, 0x88, 0x99, 0xee, 0xb8, 0x92, 0x0d, 0xd9, 0x83, 0xa1,
+ 0xb4, 0x2d, 0x73, 0x65, 0xe9, 0x3f, 0x30, 0x2e, 0x91, 0x48, 0xfa, 0x4b,
+ 0x91, 0xda, 0x0e, 0x89, 0x58, 0xe9, 0xa9, 0x23, 0x5f, 0x73, 0x8e, 0x54,
+ 0x4c, 0xc7, 0xe9, 0x9a, 0x96, 0x68, 0xef, 0xe9, 0x1e, 0xb4, 0x97, 0x92,
+ 0x5d, 0x22, 0x3b, 0xc5, 0x74, 0x8a, 0xd1, 0x90, 0x13, 0x91, 0x6c, 0xd9,
+ 0x91, 0x5c, 0x59, 0xe4, 0x1f, 0x4a, 0x86, 0x9c, 0x76, 0x9a, 0x65, 0x7a,
+ 0xfb, 0xbb, 0x95, 0x0c, 0x68, 0xf9, 0x7b, 0x67, 0xea, 0xc8, 0xa8, 0x43,
+ 0x7a, 0x1f, 0x8b, 0x90, 0xae, 0x50, 0x7a, 0xa8, 0xb6, 0xe0, 0x58, 0x32,
+ 0x5c, 0x62, 0xdd, 0x80, 0xc9, 0xba, 0x70, 0x3a, 0x52, 0x77, 0xda, 0x89,
+ 0xea, 0xba, 0x52, 0x26, 0x8b, 0xf9, 0x46, 0x4a, 0xec, 0x1b, 0xe9, 0x2e,
+ 0x38, 0x31, 0x5d, 0x3f, 0xba, 0x33, 0xeb, 0xc4, 0x51, 0xdf, 0xaa, 0xdb,
+ 0x7a, 0xbe, 0x5c, 0x70, 0x1c, 0xdd, 0x76, 0x35, 0x94, 0x75, 0xba, 0x74,
+ 0xfd, 0xab, 0xbb, 0x0a, 0xce, 0x76, 0x5d, 0xff, 0xd6, 0xae, 0xac, 0x93,
+ 0xd2, 0xf5, 0xe3, 0xf7, 0x17, 0x9c, 0x1e, 0x5d, 0xdf, 0x8a, 0xfa, 0x5e,
+ 0x5d, 0xff, 0x83, 0xde, 0x82, 0x93, 0x46, 0xfd, 0x97, 0x22, 0x66, 0x87,
+ 0x2d, 0x63, 0xa5, 0x04, 0x7e, 0x19, 0xb4, 0xf5, 0xa1, 0x6e, 0x0f, 0x7e,
+ 0x77, 0xe1, 0x37, 0xbf, 0x41, 0x1a, 0xfa, 0xf1, 0x6c, 0x6b, 0xf5, 0x78,
+ 0x07, 0x1e, 0xb9, 0x11, 0x79, 0x3d, 0x14, 0x97, 0x97, 0x3a, 0x5f, 0x07,
+ 0x0f, 0x6d, 0x39, 0x57, 0x16, 0xa3, 0xbf, 0x33, 0x0e, 0xde, 0xc5, 0xe4,
+ 0xb9, 0x72, 0xbd, 0x84, 0x1e, 0x0f, 0x81, 0x37, 0x5f, 0x90, 0x7c, 0x2c,
+ 0x22, 0x1b, 0x27, 0x0d, 0x69, 0xeb, 0x8e, 0x48, 0xc6, 0xe6, 0xda, 0x38,
+ 0xed, 0x89, 0x98, 0x84, 0x26, 0x33, 0x4d, 0xa6, 0x74, 0xd8, 0x39, 0x29,
+ 0x82, 0x77, 0x57, 0x28, 0x97, 0x68, 0x4b, 0x48, 0x6e, 0xfc, 0x36, 0x19,
+ 0xb4, 0x49, 0xd7, 0xdc, 0xcd, 0xde, 0x5a, 0x11, 0x23, 0x7b, 0x72, 0x40,
+ 0xc6, 0xdc, 0xa8, 0x91, 0x3b, 0xf9, 0x59, 0xc9, 0xa6, 0x24, 0x86, 0x71,
+ 0xf1, 0x3c, 0x5a, 0x66, 0x4a, 0x03, 0x32, 0xea, 0x8a, 0x91, 0x75, 0xc9,
+ 0xcf, 0x66, 0xb4, 0x37, 0xa8, 0xbe, 0xa8, 0x6b, 0x0d, 0xa9, 0xb9, 0x23,
+ 0xa8, 0xb7, 0x51, 0xdf, 0x68, 0xf4, 0xa9, 0x39, 0x54, 0x7d, 0x62, 0x44,
+ 0xa2, 0xf2, 0x74, 0x29, 0xa6, 0xfb, 0x56, 0x2a, 0xd9, 0x94, 0x8d, 0x7e,
+ 0x03, 0x32, 0xe2, 0xc6, 0x64, 0x10, 0xcf, 0x61, 0x97, 0x72, 0x15, 0x87,
+ 0x4c, 0x35, 0x14, 0xf3, 0x27, 0xd4, 0x7c, 0x89, 0x50, 0x9a, 0xf3, 0xb5,
+ 0xa2, 0xdf, 0xdb, 0xa0, 0xcb, 0x10, 0x4b, 0x9d, 0x65, 0x46, 0xf2, 0xe3,
+ 0x06, 0xe4, 0x0d, 0x4f, 0xc5, 0xd7, 0x3e, 0xd0, 0x6f, 0x89, 0xd3, 0x6d,
+ 0x48, 0x01, 0x67, 0x55, 0xb4, 0x51, 0x2e, 0xcd, 0x9a, 0x59, 0xb7, 0x56,
+ 0x72, 0x56, 0x42, 0x42, 0x13, 0x94, 0xa5, 0x41, 0x19, 0xc1, 0x18, 0xd3,
+ 0x61, 0x9f, 0xb7, 0xb1, 0xef, 0x41, 0x75, 0x0e, 0x35, 0xe9, 0xa2, 0x99,
+ 0x2b, 0x37, 0x8b, 0x39, 0xb9, 0x5f, 0x5e, 0x19, 0x17, 0x3b, 0x94, 0x7e,
+ 0xb7, 0x92, 0x75, 0x46, 0xcd, 0xec, 0xb3, 0x96, 0x84, 0x27, 0x0c, 0x19,
+ 0x75, 0x92, 0xd0, 0x80, 0xa3, 0xe6, 0xee, 0xf2, 0x2c, 0xfa, 0x71, 0x1c,
+ 0xfa, 0x95, 0x4c, 0xf0, 0x95, 0xef, 0xdb, 0x6c, 0x53, 0xc9, 0x33, 0xfb,
+ 0xe0, 0x0c, 0xb0, 0x8f, 0xe7, 0x5c, 0x9c, 0x89, 0x3a, 0xa3, 0x04, 0xce,
+ 0x48, 0x8c, 0xbe, 0x4e, 0xc8, 0xd4, 0x09, 0x4b, 0xf2, 0x29, 0xec, 0x0b,
+ 0xbd, 0xf3, 0xa9, 0x45, 0xba, 0x46, 0xc6, 0xab, 0xe9, 0xe2, 0x38, 0xd2,
+ 0xe5, 0xd1, 0x34, 0x7c, 0x82, 0xf4, 0x2d, 0xd2, 0x33, 0x36, 0xee, 0xd3,
+ 0xc8, 0xf5, 0x48, 0x9b, 0x4f, 0x17, 0xc7, 0x91, 0xae, 0x26, 0x9e, 0x35,
+ 0xff, 0x8c, 0x3e, 0xd0, 0x31, 0xe2, 0x5a, 0x38, 0xa3, 0xa8, 0xe4, 0xed,
+ 0xa2, 0x31, 0xd2, 0xbb, 0x2d, 0x0e, 0x6d, 0x36, 0x86, 0x7b, 0x49, 0xb3,
+ 0x83, 0x73, 0xac, 0x51, 0xe7, 0x0d, 0xf9, 0x26, 0xef, 0xd0, 0x9f, 0xeb,
+ 0xe3, 0xbd, 0x64, 0xcb, 0xa8, 0x9a, 0x8f, 0x34, 0x7d, 0x14, 0xf3, 0x90,
+ 0xd6, 0x4b, 0x90, 0xd5, 0x1e, 0xc8, 0x68, 0x4a, 0xfe, 0xae, 0xbc, 0x5d,
+ 0xbe, 0x53, 0xee, 0x92, 0xbf, 0x81, 0xde, 0xfe, 0x75, 0x39, 0x21, 0x2f,
+ 0x94, 0x5b, 0xe5, 0xdb, 0xe5, 0xb8, 0x3c, 0xaf, 0xe4, 0xb7, 0x4f, 0xa4,
+ 0x81, 0x32, 0x9d, 0x90, 0x46, 0xe8, 0xcf, 0x46, 0xe8, 0xe6, 0x13, 0xe0,
+ 0xdf, 0x89, 0x4e, 0xc9, 0x34, 0xa5, 0x25, 0x72, 0x0b, 0x7e, 0x9b, 0xf1,
+ 0x6b, 0x4e, 0x43, 0xee, 0x5c, 0xf2, 0x8e, 0x3c, 0xb4, 0x24, 0xa7, 0xf6,
+ 0x6c, 0xc9, 0x48, 0x79, 0xfe, 0x16, 0x4f, 0x76, 0x45, 0xfa, 0xc1, 0x63,
+ 0xb3, 0xfb, 0x7f, 0x2a, 0x19, 0x1b, 0xfb, 0xe8, 0xde, 0xa6, 0x78, 0x6f,
+ 0x76, 0x53, 0x66, 0x13, 0x90, 0x7b, 0xcb, 0xc8, 0xb9, 0x67, 0x80, 0x1b,
+ 0xf5, 0x46, 0xf6, 0x78, 0x51, 0x0a, 0xc7, 0x2b, 0x52, 0x48, 0x85, 0xe5,
+ 0x11, 0xbb, 0x22, 0x7d, 0xa9, 0x1a, 0x39, 0x64, 0x83, 0xf7, 0xdb, 0x7f,
+ 0xdf, 0xf0, 0x31, 0xfb, 0x89, 0xf2, 0x61, 0xbc, 0xb3, 0x4e, 0xe4, 0x84,
+ 0x7a, 0xf7, 0xea, 0x8b, 0xe5, 0xb0, 0x64, 0x62, 0xc5, 0xb8, 0x25, 0x2d,
+ 0xa6, 0xb7, 0xee, 0xb0, 0xdf, 0x06, 0x7e, 0x4c, 0x01, 0x27, 0x93, 0x4a,
+ 0x5f, 0xf2, 0xe3, 0xeb, 0xae, 0x66, 0x54, 0x35, 0xfa, 0xdb, 0x3d, 0x32,
+ 0xaf, 0xf8, 0x99, 0x18, 0x34, 0xd2, 0x31, 0x69, 0x2b, 0xb1, 0xdc, 0x6b,
+ 0xdc, 0x5d, 0xa6, 0x3c, 0xe3, 0xbd, 0x4c, 0x3a, 0x6f, 0x42, 0x3f, 0x0b,
+ 0xcf, 0x8c, 0xa6, 0x37, 0x48, 0x23, 0xe7, 0x21, 0x8d, 0x7c, 0xfe, 0x79,
+ 0x80, 0xc6, 0xa7, 0x16, 0xde, 0x4f, 0x04, 0xde, 0x8b, 0xe5, 0x4b, 0x75,
+ 0x1e, 0x6d, 0xbd, 0xf2, 0xc6, 0xc4, 0x57, 0xf4, 0x3a, 0x78, 0x3f, 0xcb,
+ 0xf9, 0xff, 0xaa, 0xe2, 0xc9, 0x4b, 0xf1, 0x3a, 0xeb, 0xcc, 0x06, 0xd6,
+ 0x79, 0x31, 0xb0, 0xce, 0x8b, 0x81, 0x75, 0x8a, 0xe0, 0xa9, 0x6c, 0x30,
+ 0x21, 0xc3, 0x79, 0x9a, 0x31, 0x39, 0x8a, 0x39, 0x5f, 0x97, 0x50, 0x9a,
+ 0x7a, 0xee, 0xe3, 0xcd, 0x65, 0xf4, 0x4f, 0xcb, 0xfc, 0x44, 0x51, 0xf2,
+ 0xc7, 0xc3, 0xb2, 0x4f, 0xf5, 0xdb, 0xa5, 0xe9, 0x0b, 0xb6, 0x45, 0x64,
+ 0x6f, 0x8c, 0xef, 0x7e, 0x9b, 0x05, 0x3e, 0xb3, 0xfc, 0xc6, 0x4d, 0x5e,
+ 0x99, 0xef, 0xb3, 0x7a, 0x2f, 0x03, 0xde, 0xb8, 0xb3, 0x6f, 0x2a, 0x3c,
+ 0x9c, 0x2b, 0x13, 0xb7, 0x24, 0x15, 0x72, 0xe4, 0x60, 0x5f, 0xaa, 0x59,
+ 0x46, 0x6c, 0x23, 0x35, 0xdc, 0x55, 0x4b, 0xbd, 0xc8, 0x98, 0x4e, 0x3d,
+ 0xb0, 0x41, 0x12, 0x26, 0x31, 0x5f, 0xed, 0xcb, 0x30, 0x3d, 0xfa, 0x6d,
+ 0x96, 0xfb, 0x4d, 0xa7, 0xb1, 0xaa, 0x9e, 0xba, 0x1d, 0xc2, 0x3b, 0x65,
+ 0x78, 0xb7, 0x3e, 0x63, 0x0b, 0x65, 0xe2, 0xf0, 0xad, 0xba, 0xec, 0xb7,
+ 0xe3, 0xc0, 0x96, 0x94, 0x7f, 0xb6, 0x65, 0x69, 0xd9, 0xc7, 0x89, 0x20,
+ 0x86, 0x73, 0xaf, 0xc0, 0x27, 0x87, 0x72, 0x17, 0x06, 0xad, 0x29, 0xe8,
+ 0x5c, 0xad, 0xa6, 0x61, 0xb3, 0xa6, 0x01, 0xb4, 0x76, 0x42, 0xb2, 0x94,
+ 0x2e, 0x29, 0xd1, 0xaa, 0x2a, 0x93, 0xf7, 0xfe, 0xfb, 0x7a, 0xd5, 0xee,
+ 0xe9, 0x9c, 0xff, 0xf4, 0xf1, 0xfd, 0xcd, 0x80, 0xbd, 0x68, 0x85, 0xce,
+ 0xc6, 0xc0, 0x2b, 0x1f, 0xeb, 0x89, 0xc1, 0x71, 0xd8, 0x07, 0xc8, 0xaa,
+ 0xc2, 0xf6, 0x28, 0xf0, 0xd0, 0xd2, 0xd8, 0x1c, 0xd1, 0xd8, 0x1c, 0x05,
+ 0x2e, 0xb3, 0x6c, 0xeb, 0x72, 0x4c, 0x97, 0xe3, 0x28, 0xc3, 0x8e, 0x4f,
+ 0x12, 0xbb, 0x1b, 0x8a, 0x43, 0x27, 0x14, 0xde, 0xd3, 0x56, 0x00, 0x85,
+ 0x89, 0xd7, 0xc4, 0xed, 0x56, 0x99, 0x2e, 0x61, 0xbd, 0x05, 0x6c, 0xe4,
+ 0xde, 0x83, 0xf4, 0x90, 0x96, 0x75, 0x62, 0xc2, 0x76, 0x65, 0x62, 0xa4,
+ 0xf7, 0x61, 0xec, 0x9d, 0xf8, 0x43, 0xba, 0x6f, 0x06, 0xad, 0xdc, 0xc7,
+ 0x27, 0x49, 0x2b, 0xd7, 0xab, 0xa6, 0xf7, 0xc3, 0xe2, 0x20, 0x69, 0x3f,
+ 0x83, 0x3d, 0x67, 0x80, 0x79, 0x62, 0x0c, 0x74, 0x0e, 0x60, 0xcf, 0xfd,
+ 0xc0, 0xc3, 0xbb, 0x80, 0x87, 0x7b, 0x80, 0x87, 0x7d, 0xc0, 0xc3, 0x34,
+ 0xb0, 0xb0, 0x17, 0x58, 0xd8, 0x03, 0x2c, 0x4c, 0x81, 0x37, 0x31, 0x99,
+ 0x02, 0x36, 0x4e, 0x01, 0x23, 0xa7, 0x30, 0xc7, 0xf0, 0xa4, 0x18, 0x0f,
+ 0x60, 0x0f, 0xdf, 0x9c, 0x48, 0x9e, 0x82, 0x2c, 0xc5, 0x8b, 0x26, 0xe4,
+ 0x3f, 0xd5, 0x0b, 0xd9, 0xee, 0x92, 0x99, 0xb2, 0x25, 0x05, 0xd8, 0xd4,
+ 0xb6, 0xad, 0xed, 0xd0, 0x35, 0xc8, 0x7b, 0x5c, 0xf4, 0xdf, 0x7a, 0xfd,
+ 0xfc, 0xb1, 0x88, 0xf3, 0x4f, 0x94, 0xc5, 0x84, 0xc8, 0x79, 0xc9, 0xbb,
+ 0xed, 0x76, 0x9b, 0xd9, 0x85, 0x7e, 0x2c, 0xa7, 0xcc, 0x03, 0xc7, 0xef,
+ 0x30, 0x87, 0x8e, 0x2b, 0x7f, 0x05, 0x78, 0x55, 0x91, 0xd1, 0x14, 0x75,
+ 0xab, 0x22, 0xa7, 0x53, 0xc9, 0xde, 0xa2, 0xd4, 0xcb, 0x58, 0x6c, 0x5c,
+ 0xd9, 0x5a, 0x2b, 0x7d, 0x4c, 0xd9, 0xab, 0x82, 0x83, 0x67, 0xa9, 0xdb,
+ 0xcc, 0x1f, 0xe7, 0xfe, 0xdb, 0xf1, 0x0b, 0x83, 0x16, 0xce, 0x6f, 0x49,
+ 0x5f, 0x8f, 0x6d, 0x3e, 0xd4, 0x59, 0x84, 0x42, 0x24, 0xed, 0x79, 0xac,
+ 0x9c, 0x1b, 0x6f, 0x8f, 0xb7, 0x9b, 0x96, 0x0c, 0x5a, 0x86, 0x0c, 0x43,
+ 0xbe, 0xfb, 0x52, 0x6f, 0x57, 0xc6, 0x62, 0x6c, 0xaf, 0x95, 0xaf, 0x2b,
+ 0x9f, 0x03, 0x6b, 0xcf, 0x9c, 0xc0, 0xba, 0x61, 0x9c, 0x01, 0xd7, 0xe5,
+ 0x3c, 0x28, 0x97, 0x2c, 0x94, 0x93, 0xa7, 0x8a, 0x52, 0x86, 0x9e, 0x6c,
+ 0x90, 0xec, 0xf6, 0x1a, 0xc9, 0xf4, 0x27, 0x64, 0x78, 0xa2, 0x0c, 0x9c,
+ 0x8a, 0x28, 0x5d, 0xc9, 0x0f, 0x24, 0xe4, 0xf1, 0x09, 0xd6, 0x9d, 0xc3,
+ 0xfe, 0x93, 0xc7, 0x32, 0xc2, 0xfd, 0x1b, 0x92, 0xd9, 0x7f, 0x4e, 0x1e,
+ 0x71, 0xcf, 0xc9, 0x10, 0xce, 0xf0, 0xe9, 0xf2, 0xac, 0x1c, 0x70, 0x1d,
+ 0x39, 0x0d, 0xbc, 0xcf, 0x1d, 0x07, 0xee, 0x39, 0xeb, 0x81, 0x51, 0xc9,
+ 0x73, 0xb4, 0xa1, 0x26, 0xfc, 0xbc, 0x69, 0xf0, 0xf7, 0x89, 0x09, 0xf2,
+ 0xd7, 0x94, 0x47, 0x7f, 0xd1, 0x80, 0x3e, 0x26, 0xc0, 0xcf, 0x56, 0x39,
+ 0xec, 0x26, 0x67, 0x33, 0x26, 0x70, 0x31, 0x65, 0x87, 0xa4, 0x2e, 0x8e,
+ 0x7e, 0x5e, 0x9f, 0x5c, 0x2a, 0x84, 0xb3, 0x2e, 0xa2, 0xef, 0xdb, 0xa0,
+ 0x93, 0x63, 0x63, 0xf8, 0x65, 0xd0, 0x0f, 0xf2, 0x6b, 0x27, 0x67, 0xa7,
+ 0x4c, 0xf6, 0x4f, 0xe0, 0xcc, 0x80, 0x2b, 0x93, 0x00, 0x1e, 0x9b, 0xef,
+ 0x69, 0x33, 0x4f, 0x1a, 0x5c, 0xca, 0x59, 0x02, 0x34, 0x11, 0xd3, 0xda,
+ 0xcf, 0x7d, 0x47, 0xb8, 0xce, 0x46, 0xf4, 0x7f, 0x07, 0x7e, 0xae, 0x2d,
+ 0x33, 0x38, 0x97, 0x9f, 0x82, 0x57, 0x99, 0xb8, 0x57, 0x1e, 0x9e, 0x4c,
+ 0x9e, 0x9b, 0x37, 0xf9, 0xee, 0x14, 0xf3, 0xe6, 0x6d, 0x22, 0x8d, 0xe4,
+ 0x57, 0x0a, 0xbc, 0x72, 0x6c, 0xd3, 0xdc, 0xaa, 0x7d, 0x3b, 0xea, 0x89,
+ 0x03, 0x9a, 0xe0, 0x67, 0x74, 0x07, 0xf5, 0x84, 0xf6, 0xce, 0xd7, 0x93,
+ 0x64, 0x7c, 0xca, 0x84, 0xff, 0xd1, 0x6d, 0xc9, 0x31, 0x55, 0x06, 0x8f,
+ 0x06, 0x92, 0xf1, 0x8c, 0x49, 0x9f, 0xb7, 0x4b, 0x9e, 0x76, 0xd9, 0x1f,
+ 0x7c, 0x1c, 0x8f, 0xea, 0xfe, 0xe7, 0x20, 0x23, 0xf4, 0xcf, 0xba, 0x40,
+ 0xb3, 0xa7, 0x3b, 0xd3, 0xe3, 0x31, 0xd5, 0x36, 0xa6, 0xf6, 0x60, 0x60,
+ 0x5d, 0xc8, 0x26, 0x7c, 0xb5, 0x9c, 0xd2, 0x23, 0x3b, 0x03, 0x5f, 0x1e,
+ 0x7a, 0xe0, 0xe9, 0xd0, 0x4c, 0x89, 0xb4, 0xdc, 0x43, 0x7e, 0x14, 0x41,
+ 0xcc, 0x31, 0x33, 0x8d, 0x73, 0xed, 0x91, 0x22, 0xfd, 0xb9, 0xf9, 0xd0,
+ 0xd3, 0x32, 0x38, 0x43, 0x7b, 0x83, 0x9f, 0xeb, 0xd8, 0x8c, 0x1f, 0x32,
+ 0xca, 0x16, 0x6c, 0xc1, 0x39, 0xc3, 0x4e, 0xa4, 0x36, 0x6a, 0x3f, 0xe6,
+ 0x49, 0x9c, 0xdb, 0x79, 0x9c, 0x6b, 0x49, 0x86, 0x4e, 0x5e, 0xa2, 0xcc,
+ 0x76, 0xcd, 0x48, 0xb2, 0x6b, 0x4c, 0xb6, 0xd9, 0xd3, 0xd0, 0xb7, 0xcc,
+ 0x40, 0x65, 0x97, 0x99, 0xe6, 0x98, 0x23, 0x18, 0x83, 0xe7, 0xcc, 0x25,
+ 0x39, 0x54, 0x66, 0xdd, 0xef, 0x80, 0x9f, 0xb0, 0x3b, 0x3d, 0x4f, 0x6a,
+ 0x39, 0xc7, 0x7c, 0x96, 0x3f, 0xdf, 0x25, 0x3d, 0x1f, 0xfb, 0xb1, 0x0f,
+ 0xc7, 0x2c, 0xce, 0xbb, 0x9b, 0xb6, 0x06, 0x78, 0xd3, 0x61, 0x56, 0x76,
+ 0x85, 0xd1, 0x7e, 0xba, 0x87, 0xef, 0x98, 0x07, 0xb6, 0xc6, 0x76, 0xce,
+ 0xa3, 0x2f, 0xf6, 0xe5, 0xae, 0x93, 0xb6, 0x66, 0x9f, 0x5e, 0x9e, 0x3b,
+ 0xfd, 0x00, 0x96, 0x1f, 0x6e, 0xf2, 0x78, 0x3f, 0x12, 0xf2, 0xb0, 0xfb,
+ 0x2f, 0x51, 0xa6, 0x7e, 0x3d, 0x26, 0x39, 0x37, 0x89, 0x7d, 0x42, 0x87,
+ 0xca, 0x0d, 0x86, 0xb7, 0x47, 0xf0, 0xbf, 0xff, 0x32, 0xf8, 0x20, 0x45,
+ 0x8f, 0x37, 0xe4, 0x0b, 0x79, 0xd2, 0x00, 0xd9, 0xae, 0xc3, 0xbc, 0x58,
+ 0x47, 0xf1, 0xe0, 0x96, 0x26, 0xcf, 0xef, 0x4d, 0x16, 0x33, 0x8c, 0xd7,
+ 0x1a, 0x29, 0xb3, 0xc0, 0xa8, 0xf2, 0xfd, 0x36, 0xe7, 0x9e, 0x32, 0xd7,
+ 0x91, 0xde, 0xc4, 0x85, 0xd0, 0x7e, 0x96, 0xbb, 0xa6, 0x4c, 0xf0, 0x1e,
+ 0xe7, 0x93, 0xdd, 0xde, 0xae, 0x71, 0xe9, 0x99, 0x10, 0x65, 0x94, 0xf2,
+ 0x9c, 0x77, 0xb7, 0xd9, 0xf7, 0x08, 0x65, 0x34, 0x86, 0xf3, 0x26, 0x2e,
+ 0xf0, 0x69, 0xc1, 0x26, 0xc6, 0x71, 0xc6, 0x5b, 0x34, 0xed, 0x7c, 0xb7,
+ 0x64, 0xca, 0xc6, 0x1a, 0xee, 0x7f, 0x6f, 0xf0, 0xea, 0xf8, 0xde, 0xc2,
+ 0x33, 0x39, 0xb6, 0x94, 0x56, 0x9e, 0x67, 0xf5, 0x19, 0x9e, 0x06, 0xed,
+ 0xac, 0xc7, 0x73, 0xe6, 0x14, 0xf4, 0x0f, 0x58, 0xd1, 0xd3, 0x11, 0xbf,
+ 0x88, 0xfe, 0x39, 0x60, 0x7c, 0xd1, 0x62, 0xdb, 0x55, 0x63, 0x71, 0x8c,
+ 0x49, 0x3f, 0x13, 0x3e, 0xed, 0x05, 0xe3, 0x81, 0xf2, 0x2b, 0x46, 0x76,
+ 0xe6, 0xaa, 0x91, 0x83, 0x5c, 0xcc, 0xb8, 0x3b, 0x20, 0xcf, 0xd4, 0x17,
+ 0x1b, 0x6b, 0x27, 0xe3, 0xff, 0x62, 0xb6, 0x27, 0xa6, 0xa1, 0xdb, 0x07,
+ 0xc0, 0x58, 0xef, 0x2c, 0x5b, 0xd5, 0xd9, 0xce, 0x9b, 0x61, 0x8d, 0x75,
+ 0x2c, 0x27, 0xed, 0x7b, 0xe5, 0x35, 0xec, 0x77, 0x16, 0x7c, 0x9e, 0x95,
+ 0x42, 0xb9, 0x24, 0xf9, 0x93, 0xdb, 0xec, 0x61, 0xc4, 0xb8, 0x8b, 0xb4,
+ 0x13, 0xc3, 0x8a, 0xf4, 0xbd, 0x8d, 0xdd, 0xae, 0x14, 0x6b, 0xd2, 0xc4,
+ 0xb2, 0x0e, 0xc8, 0x13, 0xea, 0x4a, 0x8b, 0x32, 0x79, 0xe7, 0xb2, 0xfd,
+ 0x20, 0xbe, 0xed, 0x59, 0xba, 0xa7, 0x19, 0xb9, 0xfe, 0x9e, 0x76, 0x2f,
+ 0xec, 0x89, 0xd8, 0x01, 0xcc, 0x77, 0x81, 0xf9, 0x2e, 0x30, 0xdf, 0x05,
+ 0xe6, 0xbb, 0xc0, 0x7c, 0x17, 0xf6, 0xc0, 0x05, 0xee, 0xbb, 0xc0, 0x7d,
+ 0x17, 0xb8, 0xef, 0x02, 0xf7, 0xdd, 0x2c, 0xce, 0x8e, 0xd8, 0x4e, 0xbb,
+ 0x71, 0xdf, 0x82, 0xad, 0xf4, 0x7c, 0x9b, 0x9b, 0xb4, 0xbf, 0x00, 0x9d,
+ 0xb4, 0x5b, 0x64, 0xb8, 0x6b, 0x33, 0xf6, 0x56, 0x87, 0x67, 0x3d, 0x9e,
+ 0x58, 0xa3, 0xeb, 0x33, 0x5a, 0x77, 0xbe, 0x0a, 0xba, 0x4c, 0x94, 0x7f,
+ 0x09, 0xb2, 0x59, 0x03, 0x7a, 0x7e, 0x41, 0xfb, 0x15, 0xa7, 0x2c, 0x4f,
+ 0x36, 0xeb, 0x51, 0xf7, 0x69, 0xd4, 0xd5, 0xa3, 0xcf, 0x21, 0xf4, 0xa1,
+ 0x5f, 0xd2, 0xa0, 0xeb, 0x82, 0xfd, 0xe8, 0x9f, 0xfc, 0x26, 0xd6, 0x4a,
+ 0xa2, 0x5f, 0x03, 0xe6, 0x6e, 0x45, 0x9f, 0xcf, 0xa2, 0xcf, 0xcd, 0x28,
+ 0xd3, 0x9f, 0xdd, 0x82, 0xf2, 0xa7, 0xaa, 0xc6, 0xdc, 0x8a, 0xba, 0xcf,
+ 0x54, 0xd5, 0xcd, 0xa3, 0x0e, 0x71, 0xb0, 0x7d, 0x51, 0x8f, 0x2b, 0xa2,
+ 0xdc, 0x5c, 0xd5, 0xe7, 0x12, 0xea, 0x7a, 0x51, 0xf7, 0x3d, 0x3c, 0x11,
+ 0xff, 0xda, 0xa4, 0xc9, 0x6f, 0xa3, 0x6f, 0x9a, 0x40, 0x7d, 0x58, 0xfb,
+ 0x97, 0x4f, 0xd2, 0xdf, 0x82, 0x9d, 0xfd, 0x53, 0xcb, 0xf3, 0xc7, 0x9e,
+ 0xb1, 0x3d, 0x59, 0xf5, 0xcb, 0x3f, 0xaa, 0x2a, 0xb3, 0xef, 0xff, 0x56,
+ 0xd5, 0xed, 0xda, 0xb8, 0xb4, 0xfc, 0x7e, 0x78, 0xf9, 0x98, 0xe3, 0x55,
+ 0x7d, 0x5e, 0x6e, 0x5c, 0x5a, 0xfe, 0x7c, 0xcd, 0xf2, 0x31, 0xbf, 0xb5,
+ 0x61, 0x69, 0xdd, 0xe1, 0xa6, 0xa5, 0x65, 0xfa, 0x7d, 0x31, 0xc4, 0x2d,
+ 0x7e, 0xff, 0x07, 0x37, 0x79, 0xed, 0xe4, 0x6f, 0xb5, 0x2c, 0x29, 0xe3,
+ 0x8d, 0xb2, 0x89, 0x73, 0xb8, 0x60, 0x40, 0xe7, 0x6c, 0x33, 0xfd, 0x8a,
+ 0x91, 0x83, 0x4c, 0x65, 0xcb, 0xfe, 0x7c, 0xd4, 0xe5, 0xea, 0xdc, 0x80,
+ 0x9f, 0x13, 0xa0, 0x8f, 0x15, 0x85, 0xdc, 0x00, 0x8b, 0x63, 0xc9, 0xa3,
+ 0x45, 0x59, 0xd4, 0xe1, 0x36, 0xf3, 0x5a, 0x3a, 0x3c, 0xa9, 0x71, 0xeb,
+ 0x32, 0xe8, 0xac, 0x48, 0x7f, 0xaa, 0x96, 0x76, 0x47, 0xe3, 0x19, 0xb1,
+ 0xa8, 0x52, 0x09, 0x6d, 0xad, 0xc8, 0xc1, 0xd4, 0x3b, 0x15, 0x51, 0x38,
+ 0xf8, 0x4d, 0xcd, 0x57, 0xe2, 0xa1, 0x0d, 0xb9, 0x8d, 0x29, 0x3f, 0x2e,
+ 0x94, 0x3e, 0x45, 0x9f, 0xe4, 0x88, 0x87, 0xb3, 0xc4, 0x22, 0x94, 0xcb,
+ 0x63, 0xe8, 0xc3, 0xf5, 0xf1, 0x9c, 0x21, 0xb6, 0x5b, 0xca, 0xce, 0xe4,
+ 0x6d, 0xce, 0xbb, 0x12, 0x5e, 0xfe, 0xd8, 0xa2, 0x2f, 0x68, 0x39, 0x67,
+ 0x60, 0xf3, 0xd8, 0x46, 0xff, 0xe0, 0x0c, 0x7d, 0x91, 0x80, 0x6f, 0xd3,
+ 0x11, 0x12, 0x67, 0x11, 0x47, 0xbd, 0x7d, 0xb5, 0xd0, 0xd7, 0x5f, 0xc3,
+ 0x5e, 0x57, 0xc6, 0xab, 0x76, 0xf3, 0xfa, 0xba, 0xbd, 0x77, 0x41, 0xb7,
+ 0x7d, 0xd9, 0x5b, 0x29, 0x07, 0x70, 0x45, 0x9d, 0xc5, 0xf3, 0xe5, 0xe4,
+ 0xb1, 0x22, 0x74, 0x69, 0x4e, 0xc5, 0xbb, 0xfe, 0xb9, 0xd0, 0xaf, 0x49,
+ 0x9e, 0x9a, 0x82, 0x6c, 0x0f, 0xa9, 0x38, 0x80, 0x31, 0x40, 0x45, 0x76,
+ 0xa7, 0x86, 0x62, 0xe4, 0x43, 0xc6, 0xbc, 0x1a, 0xa6, 0x1f, 0x31, 0xe7,
+ 0x92, 0x67, 0x29, 0xb4, 0xa7, 0xc0, 0xdb, 0x7f, 0x95, 0x5c, 0x8c, 0x75,
+ 0xff, 0x55, 0x99, 0x86, 0xff, 0xa3, 0x7c, 0x22, 0xe5, 0x03, 0xd0, 0xa7,
+ 0x83, 0xad, 0x2f, 0x93, 0xa7, 0x17, 0xc0, 0x67, 0xdf, 0x2f, 0xb8, 0x4c,
+ 0xbf, 0x54, 0x96, 0xfa, 0xcf, 0x22, 0x8f, 0x94, 0xfe, 0x19, 0x76, 0xc8,
+ 0xc4, 0x7c, 0xb4, 0x77, 0xb4, 0x29, 0xac, 0xdf, 0x11, 0xa6, 0xff, 0xe6,
+ 0xd9, 0xff, 0x10, 0xd6, 0x43, 0x4c, 0x5d, 0xfa, 0x0f, 0x23, 0xef, 0xb6,
+ 0xd2, 0xb7, 0xc2, 0xfe, 0x89, 0xab, 0x6c, 0x63, 0x5d, 0x44, 0xfb, 0xdc,
+ 0x51, 0xed, 0x63, 0xdb, 0xda, 0xc7, 0x26, 0x1d, 0x46, 0xc4, 0x4e, 0xfb,
+ 0xbe, 0x02, 0xcf, 0x0c, 0x67, 0xb3, 0x55, 0xf9, 0x0a, 0xb2, 0xb2, 0xaf,
+ 0xe0, 0xd3, 0x74, 0x16, 0xfb, 0xa4, 0x6f, 0xa7, 0x72, 0x3f, 0x8d, 0x5e,
+ 0xbe, 0x89, 0x34, 0xf8, 0x36, 0x53, 0xd9, 0xe6, 0xa3, 0x30, 0x83, 0xd8,
+ 0xdb, 0x6f, 0x83, 0xd6, 0x3d, 0x92, 0x1d, 0x3f, 0xab, 0x6d, 0x30, 0x63,
+ 0x07, 0xfa, 0xed, 0x9e, 0xcc, 0x66, 0x53, 0x0d, 0x86, 0x9e, 0xa7, 0x19,
+ 0x56, 0x33, 0x90, 0x97, 0xe2, 0x5a, 0xf4, 0x6d, 0x7c, 0x3f, 0x67, 0x56,
+ 0xfb, 0x39, 0xe7, 0xe5, 0xa0, 0xeb, 0xc5, 0x0a, 0xfd, 0xa5, 0x0b, 0xa8,
+ 0x53, 0xb4, 0xc7, 0xe9, 0x4f, 0x9a, 0x26, 0xfd, 0xc9, 0x24, 0x82, 0x0e,
+ 0x6f, 0x2f, 0x6d, 0xd8, 0xcb, 0xcc, 0xc2, 0x5e, 0xea, 0x2f, 0x2c, 0xdd,
+ 0x0b, 0xe9, 0xb7, 0xc1, 0x4f, 0x4b, 0xe3, 0x14, 0xe7, 0xfc, 0x46, 0x98,
+ 0x18, 0xd6, 0x4f, 0x9f, 0xc8, 0xf5, 0x7c, 0xb1, 0xa5, 0xf3, 0xc2, 0x63,
+ 0x28, 0x4d, 0x5d, 0xa3, 0x8d, 0xfb, 0xf7, 0xf5, 0xca, 0xd2, 0xd8, 0xce,
+ 0x3d, 0xfc, 0x09, 0xe6, 0x8c, 0x19, 0x79, 0xe5, 0x9b, 0xd1, 0xcf, 0x41,
+ 0xdc, 0x5d, 0x7a, 0x05, 0x4f, 0xea, 0x8e, 0x9a, 0x07, 0xfb, 0x8d, 0xaa,
+ 0xfd, 0x8e, 0xb9, 0x97, 0xd4, 0x1e, 0xa7, 0x4b, 0x3f, 0x90, 0xc2, 0xc9,
+ 0x1f, 0xc2, 0x26, 0x06, 0x73, 0x75, 0xcc, 0x73, 0x92, 0x57, 0xc5, 0x00,
+ 0xb6, 0x92, 0x66, 0xe6, 0xe1, 0xbe, 0x17, 0xf6, 0xe2, 0x85, 0x71, 0x9c,
+ 0xbf, 0xe1, 0xb5, 0xab, 0xf5, 0x7d, 0x9e, 0xd7, 0x04, 0xe8, 0xa9, 0xc0,
+ 0x47, 0x8d, 0x83, 0x86, 0xe0, 0x98, 0xc7, 0xa4, 0xcf, 0xe5, 0x59, 0xb5,
+ 0xc7, 0x87, 0xc4, 0xb1, 0xf3, 0xe2, 0xfb, 0x25, 0x5c, 0x9f, 0x78, 0x90,
+ 0x43, 0x0c, 0xc5, 0xdc, 0xaa, 0xcf, 0x57, 0x9f, 0xa7, 0xd1, 0x0b, 0xd5,
+ 0xf2, 0x31, 0x8a, 0xd8, 0xab, 0xe0, 0x92, 0x4f, 0xbe, 0xdc, 0xfa, 0x6b,
+ 0x5f, 0x31, 0xb8, 0x9f, 0x11, 0x95, 0x4f, 0x7c, 0x6d, 0x41, 0x7e, 0x87,
+ 0x81, 0x2b, 0x9e, 0x3c, 0xbe, 0xaa, 0x79, 0xe3, 0xcb, 0x6d, 0x54, 0xcb,
+ 0x00, 0x63, 0x43, 0xea, 0x95, 0x2f, 0x23, 0x1d, 0xf6, 0xdd, 0x8a, 0x17,
+ 0x6c, 0x53, 0x79, 0x46, 0x75, 0xce, 0x83, 0x0b, 0xe7, 0xbc, 0xbe, 0x4a,
+ 0x66, 0x53, 0xb6, 0xa7, 0xa3, 0xd4, 0x45, 0xe8, 0x34, 0xf8, 0xf5, 0xfc,
+ 0x12, 0xdd, 0xef, 0xba, 0x46, 0x8e, 0x36, 0x2a, 0xa1, 0xc9, 0x97, 0xc1,
+ 0xcb, 0x5b, 0x11, 0xbb, 0x88, 0x58, 0x13, 0xc4, 0x28, 0xfa, 0x22, 0x8b,
+ 0xfe, 0xf1, 0xb4, 0xac, 0xe4, 0x1b, 0x5f, 0xcf, 0x0f, 0xb9, 0x7d, 0x8d,
+ 0x7e, 0xc8, 0xaf, 0xd6, 0x30, 0x96, 0x99, 0x83, 0x9e, 0x1e, 0xc0, 0xf8,
+ 0x1a, 0xe7, 0x47, 0xb0, 0x6f, 0xa7, 0xad, 0x5a, 0xc7, 0xc7, 0x8b, 0xa8,
+ 0x6c, 0x9c, 0xdc, 0xa2, 0x30, 0xc3, 0x9e, 0x58, 0xc4, 0x8c, 0x61, 0x97,
+ 0xf2, 0xab, 0xf4, 0x34, 0xb6, 0x51, 0x7c, 0x8c, 0x78, 0xd6, 0x62, 0xbe,
+ 0x67, 0x65, 0x1c, 0xf0, 0x72, 0xba, 0x2b, 0xc7, 0x0a, 0x37, 0x55, 0xf1,
+ 0x72, 0x25, 0xdc, 0x3c, 0x07, 0xde, 0xa5, 0x11, 0x13, 0x27, 0xcf, 0x88,
+ 0xec, 0x41, 0x9c, 0x9c, 0x7c, 0x4b, 0xa4, 0x0f, 0xb1, 0x72, 0x72, 0x56,
+ 0x24, 0x83, 0x78, 0x99, 0xf1, 0xdb, 0x5d, 0xe0, 0x69, 0x2f, 0xe2, 0xe9,
+ 0x1e, 0x60, 0x6a, 0x0a, 0x18, 0xbb, 0x1d, 0xfc, 0xed, 0x02, 0xbf, 0x6d,
+ 0xc4, 0x5b, 0x65, 0x39, 0x70, 0x5c, 0x8c, 0x7d, 0x2a, 0x7f, 0x4d, 0x7d,
+ 0x8f, 0xc1, 0xce, 0x56, 0x2a, 0x87, 0x52, 0xed, 0x88, 0xf5, 0x13, 0xf2,
+ 0x39, 0x8b, 0xb1, 0xad, 0x61, 0xb5, 0x75, 0x7f, 0x3f, 0x14, 0xf4, 0x6b,
+ 0xb3, 0xd7, 0xb5, 0x13, 0xcb, 0xf9, 0x9f, 0x53, 0xb6, 0xe2, 0xc5, 0xd0,
+ 0x6a, 0xfc, 0xdf, 0xb7, 0xc0, 0xff, 0x9e, 0x3a, 0xa9, 0xbb, 0x4b, 0xe5,
+ 0x16, 0xda, 0xba, 0x0f, 0x11, 0xcf, 0x52, 0xb0, 0xfb, 0xb0, 0xcf, 0x15,
+ 0xb9, 0x33, 0x75, 0xb5, 0x72, 0xd1, 0xd9, 0x20, 0xf9, 0xed, 0x0f, 0x6a,
+ 0x4c, 0x3f, 0xf5, 0x87, 0x59, 0xa7, 0x08, 0x1d, 0xf1, 0xf2, 0x88, 0x43,
+ 0xe3, 0x11, 0x58, 0x0a, 0xfe, 0x35, 0xca, 0x74, 0xef, 0x55, 0x9c, 0xe3,
+ 0xb6, 0x33, 0x4c, 0x42, 0x11, 0x6b, 0xa6, 0x63, 0x51, 0x95, 0x43, 0xde,
+ 0xe4, 0xb0, 0xde, 0xc6, 0xb9, 0x0e, 0xc8, 0x34, 0xfc, 0x8b, 0x99, 0x5e,
+ 0xd0, 0xb8, 0xbd, 0x19, 0xfd, 0xa9, 0x7b, 0xe4, 0xf9, 0x80, 0x0c, 0xc6,
+ 0xc8, 0xd3, 0x18, 0xfa, 0xef, 0x45, 0x9f, 0x46, 0x3c, 0xff, 0x28, 0x34,
+ 0x6d, 0x33, 0x9e, 0xfe, 0x3c, 0xca, 0x9c, 0x23, 0x68, 0x5b, 0x77, 0x85,
+ 0x45, 0xcd, 0xc9, 0x31, 0xcd, 0x0a, 0x03, 0x16, 0xd7, 0xe2, 0x3a, 0x6c,
+ 0x7b, 0xaf, 0x72, 0x47, 0x77, 0x6f, 0x60, 0xbd, 0x86, 0xc0, 0x7a, 0xbd,
+ 0x81, 0xf5, 0x48, 0x67, 0x63, 0x80, 0xce, 0x46, 0x8c, 0xff, 0x5d, 0xac,
+ 0x4d, 0x7e, 0x04, 0xd7, 0xcc, 0x07, 0xd6, 0xf4, 0xf7, 0xd7, 0x1c, 0x18,
+ 0xf7, 0x0e, 0xd6, 0x63, 0x5d, 0x2c, 0x50, 0x47, 0x1a, 0x9a, 0x50, 0xc7,
+ 0x72, 0x63, 0x80, 0xae, 0xa8, 0x8a, 0xf7, 0xa7, 0xd5, 0x19, 0x92, 0xcf,
+ 0x75, 0xb0, 0x6b, 0x26, 0x6c, 0x4b, 0x0d, 0xfc, 0xaf, 0xea, 0xbd, 0x7e,
+ 0x0d, 0xeb, 0xfa, 0xf3, 0xc5, 0x30, 0x07, 0xfb, 0xb3, 0x6f, 0x48, 0x8f,
+ 0x67, 0x3d, 0xdb, 0xff, 0xb6, 0xf2, 0x8c, 0xe2, 0x5b, 0x1a, 0xb4, 0x93,
+ 0xc6, 0x36, 0x99, 0x6a, 0xb4, 0x70, 0x9e, 0xa6, 0xb6, 0xa5, 0xc0, 0xda,
+ 0xb2, 0x69, 0xb4, 0x77, 0xf3, 0xfc, 0x37, 0x68, 0x4c, 0xad, 0x33, 0xb2,
+ 0xc7, 0x99, 0x4b, 0xa8, 0xd7, 0xb1, 0x22, 0xe2, 0x13, 0x65, 0x87, 0x7c,
+ 0x3b, 0x41, 0x3b, 0x44, 0xdf, 0x86, 0x36, 0xf6, 0x9c, 0x7e, 0xc7, 0x13,
+ 0x72, 0xfc, 0xd0, 0x4c, 0xa3, 0x5c, 0x54, 0x7c, 0xb5, 0x65, 0x7e, 0x81,
+ 0xaf, 0x61, 0xfd, 0xbd, 0xe6, 0x31, 0xfd, 0x2d, 0x64, 0x3f, 0x7c, 0x27,
+ 0xbc, 0x97, 0x32, 0xa0, 0x23, 0x21, 0xed, 0xdd, 0xcc, 0x61, 0x14, 0xf1,
+ 0x74, 0xf0, 0x34, 0xf0, 0x84, 0xcd, 0x42, 0x0c, 0xd2, 0xde, 0xcd, 0x58,
+ 0x50, 0x40, 0xdb, 0x15, 0x15, 0x07, 0xce, 0x94, 0x6d, 0xe3, 0x4e, 0xd7,
+ 0xcb, 0x1d, 0xcd, 0x3b, 0xab, 0xe5, 0x8e, 0x1e, 0xa8, 0xc5, 0x79, 0x9c,
+ 0xf2, 0x73, 0x47, 0xf3, 0xa2, 0x72, 0x47, 0xa7, 0xae, 0x93, 0x3b, 0xca,
+ 0xac, 0x3d, 0x77, 0xc4, 0xf9, 0x2d, 0xb9, 0xbb, 0xc7, 0x36, 0xbf, 0xa8,
+ 0x73, 0x47, 0x6f, 0x88, 0x97, 0x3b, 0xba, 0x28, 0x2b, 0xe7, 0x8e, 0x8e,
+ 0x56, 0xe5, 0x8e, 0x9a, 0x54, 0xee, 0x88, 0xf3, 0x78, 0xb9, 0x23, 0x96,
+ 0xf3, 0xdd, 0xbf, 0xac, 0x72, 0xe9, 0xf9, 0x6e, 0x60, 0xb0, 0xeb, 0x63,
+ 0x9c, 0x6d, 0x0c, 0xa8, 0xf8, 0xf2, 0x4a, 0xb8, 0xd9, 0xf1, 0x31, 0x8e,
+ 0xb6, 0x60, 0xf3, 0x82, 0x3d, 0xf3, 0xf1, 0x6e, 0x54, 0xd9, 0xbd, 0xe5,
+ 0xf9, 0xc5, 0x7b, 0xaa, 0xf2, 0x8b, 0x03, 0x9e, 0xdd, 0x50, 0x38, 0x37,
+ 0xa8, 0x71, 0x6e, 0x74, 0xc1, 0xcf, 0x39, 0x59, 0xcb, 0x18, 0x7c, 0xa4,
+ 0x14, 0xc4, 0x51, 0x4b, 0x8d, 0xf5, 0xf2, 0x2c, 0x8b, 0x18, 0x7a, 0xb8,
+ 0x0a, 0x43, 0x1f, 0x5b, 0xf1, 0xbb, 0x58, 0x3c, 0xb3, 0xfc, 0xbb, 0x98,
+ 0x21, 0xcd, 0xf4, 0x39, 0xba, 0xf3, 0xd8, 0x03, 0x63, 0xe6, 0xfd, 0x92,
+ 0x19, 0xb0, 0x81, 0x45, 0x7e, 0xfe, 0x85, 0xe7, 0xbc, 0x68, 0x63, 0xb2,
+ 0xe6, 0xc7, 0x97, 0x83, 0x79, 0x48, 0xe5, 0x60, 0xbe, 0x5f, 0x1b, 0xcc,
+ 0xc1, 0xcc, 0x03, 0xb3, 0x32, 0x16, 0xf3, 0x5b, 0x2b, 0xe7, 0x60, 0x1e,
+ 0x5a, 0x21, 0x07, 0xf3, 0x5d, 0x59, 0xcc, 0xc1, 0x7c, 0x57, 0xfc, 0x1c,
+ 0x0c, 0xe7, 0x08, 0x69, 0x9f, 0x56, 0x30, 0xee, 0x02, 0x7e, 0xe7, 0xf1,
+ 0xf3, 0xf2, 0x32, 0xf3, 0x0b, 0x7b, 0x58, 0x29, 0x2f, 0xf3, 0x6f, 0xb5,
+ 0x1f, 0x24, 0x2f, 0xe3, 0xd9, 0x04, 0x3f, 0x2f, 0x83, 0x9f, 0x0d, 0x1b,
+ 0x64, 0x06, 0xf3, 0x32, 0xef, 0x53, 0x37, 0x50, 0xc7, 0x32, 0xeb, 0xa1,
+ 0x23, 0xb0, 0x53, 0x19, 0xd8, 0x99, 0x69, 0xf7, 0xd7, 0xd5, 0x79, 0xcc,
+ 0xb8, 0x53, 0xd8, 0x77, 0x02, 0xe7, 0x41, 0x5e, 0xb6, 0x2b, 0x5f, 0x34,
+ 0x63, 0xc5, 0x8d, 0x6c, 0x27, 0xac, 0xda, 0x38, 0xbf, 0x9d, 0x5b, 0xc6,
+ 0x50, 0x99, 0xf2, 0x1e, 0x31, 0x0a, 0xd8, 0x4b, 0xdf, 0xf8, 0x94, 0x0c,
+ 0x95, 0x7d, 0x3f, 0xab, 0x5b, 0x9f, 0xc5, 0x94, 0xd2, 0xd3, 0x69, 0xf0,
+ 0x00, 0x98, 0xb1, 0x06, 0x9b, 0x75, 0x16, 0x34, 0x07, 0xf7, 0x81, 0x18,
+ 0xba, 0x07, 0x75, 0xea, 0xdc, 0xe9, 0x6f, 0xfa, 0xb4, 0x24, 0xa8, 0xf3,
+ 0x6b, 0x98, 0x8f, 0x75, 0x67, 0x55, 0xfc, 0x56, 0xe8, 0xe1, 0x5e, 0x69,
+ 0xfb, 0xe6, 0x40, 0x1f, 0xea, 0x66, 0x18, 0x33, 0xd2, 0x0e, 0xfa, 0x31,
+ 0x5d, 0x54, 0xc5, 0x74, 0x9b, 0x15, 0x3f, 0xc8, 0xeb, 0x5f, 0x8b, 0x10,
+ 0x3b, 0x37, 0x3b, 0xdc, 0xc3, 0x79, 0x8d, 0x7b, 0x2c, 0xfb, 0xb1, 0x23,
+ 0xdf, 0xc9, 0xa7, 0xa7, 0x54, 0xde, 0x67, 0xda, 0xf5, 0xcf, 0xf0, 0x5b,
+ 0xd8, 0x3b, 0xcb, 0xbd, 0x72, 0xa1, 0x59, 0x22, 0xb1, 0x34, 0x73, 0xbd,
+ 0xf4, 0xd5, 0x77, 0x30, 0xf7, 0x50, 0xd3, 0xb4, 0x8a, 0xfe, 0xee, 0x5b,
+ 0x45, 0x7f, 0xef, 0xae, 0xd2, 0xdf, 0xfe, 0x55, 0xf5, 0xf7, 0xeb, 0x91,
+ 0xa0, 0xfe, 0xee, 0x5b, 0x45, 0x7f, 0x1f, 0xad, 0xd2, 0xdf, 0x83, 0x37,
+ 0xa4, 0xbf, 0x3a, 0x36, 0x4e, 0xdd, 0xaa, 0x72, 0xc6, 0xc3, 0x13, 0xc4,
+ 0xac, 0x4f, 0xeb, 0xdc, 0xd5, 0x4a, 0xbe, 0x98, 0x4f, 0x43, 0x5b, 0xcd,
+ 0x47, 0xe3, 0x87, 0xfd, 0x23, 0xf6, 0xe9, 0xf9, 0xa3, 0xfd, 0xf0, 0x69,
+ 0xaf, 0xbd, 0xee, 0x1f, 0x8b, 0x99, 0xf6, 0x7d, 0xc0, 0xad, 0x1f, 0xd1,
+ 0xda, 0x6b, 0x91, 0x3f, 0xc6, 0x56, 0xf4, 0x07, 0xa2, 0xda, 0x66, 0x4e,
+ 0x6a, 0x1d, 0xf4, 0xf3, 0x12, 0x41, 0x7d, 0xa6, 0x9c, 0x52, 0x36, 0x7f,
+ 0x8a, 0x3d, 0x51, 0x3e, 0x7d, 0x0c, 0xd8, 0x52, 0xa5, 0x13, 0x73, 0x52,
+ 0x00, 0x6e, 0x79, 0x3a, 0x41, 0x39, 0xeb, 0xc4, 0xbe, 0x61, 0x2b, 0xdd,
+ 0xa7, 0xbd, 0xb3, 0x70, 0xf0, 0x9c, 0xf1, 0x75, 0x3f, 0x81, 0x75, 0xfd,
+ 0x36, 0xda, 0x1e, 0x07, 0x3e, 0xd9, 0x36, 0xf8, 0x93, 0x2d, 0xc0, 0x19,
+ 0xd6, 0x2f, 0xcd, 0x73, 0xaf, 0x8e, 0xb1, 0x52, 0x0c, 0xa3, 0xef, 0xe9,
+ 0x1e, 0x60, 0x4e, 0x0f, 0x71, 0xb3, 0x84, 0xd8, 0x8c, 0x7a, 0x41, 0x5d,
+ 0xe9, 0xe8, 0xda, 0x6d, 0xd2, 0xe7, 0x7b, 0x12, 0x71, 0xfc, 0x2d, 0x4a,
+ 0xaf, 0x76, 0x97, 0x3b, 0x66, 0xdf, 0x30, 0xb9, 0x46, 0xa5, 0x92, 0x57,
+ 0xdf, 0x19, 0xc4, 0x6c, 0xeb, 0xde, 0xb2, 0x8e, 0x36, 0xf3, 0x16, 0x27,
+ 0xa4, 0xe5, 0x3e, 0x83, 0x77, 0xea, 0xd1, 0xeb, 0xf0, 0x47, 0x78, 0x47,
+ 0xe1, 0x27, 0x2a, 0x5f, 0x37, 0xed, 0xd2, 0xf7, 0x60, 0xcc, 0xb4, 0x53,
+ 0xf7, 0xdb, 0xa2, 0xbe, 0xb1, 0x66, 0x53, 0x3b, 0xf4, 0xf7, 0x36, 0xda,
+ 0xc4, 0x24, 0x31, 0x75, 0xc9, 0x79, 0xf3, 0x8e, 0x47, 0x4e, 0xc5, 0x5c,
+ 0x1c, 0xaf, 0x7c, 0x7f, 0xc4, 0x49, 0x56, 0xe0, 0xfb, 0x40, 0x44, 0xc7,
+ 0x97, 0xd4, 0xf9, 0xa8, 0x8a, 0x7d, 0xbd, 0x78, 0x8a, 0xf1, 0xf7, 0xd2,
+ 0xbb, 0x1d, 0x2b, 0xcb, 0x40, 0xcb, 0x07, 0x90, 0x81, 0xea, 0xf3, 0x8b,
+ 0x00, 0x8b, 0xfc, 0xf3, 0xf3, 0x7d, 0xac, 0xbf, 0xd0, 0xfb, 0xde, 0xa2,
+ 0xf5, 0xe9, 0xff, 0xc3, 0x3e, 0x8d, 0xc0, 0x3e, 0x7d, 0x6c, 0xfc, 0xa2,
+ 0xde, 0xe7, 0xce, 0x2a, 0x6c, 0xec, 0x41, 0xfd, 0xe1, 0x9a, 0x8d, 0x1f,
+ 0x10, 0x1b, 0xf7, 0xde, 0x10, 0x36, 0xfe, 0x70, 0xdd, 0x5a, 0xb1, 0xf1,
+ 0xd0, 0x07, 0xc6, 0x46, 0xee, 0x6b, 0x65, 0x3c, 0xda, 0xb7, 0x0c, 0x8f,
+ 0xfe, 0xe0, 0x13, 0xc4, 0xa3, 0xd5, 0xb0, 0x84, 0xe7, 0xd2, 0xa0, 0x7c,
+ 0x6c, 0x4f, 0xff, 0xe0, 0x5f, 0xcc, 0x84, 0xe5, 0xc2, 0xbd, 0x11, 0x79,
+ 0x6d, 0x27, 0xfc, 0x6e, 0xf2, 0x48, 0x9d, 0x07, 0xcb, 0xd1, 0x3a, 0xcf,
+ 0x36, 0xc6, 0x1b, 0xbd, 0x9c, 0x02, 0xc7, 0xf8, 0x3a, 0x6d, 0xa3, 0x9d,
+ 0x6d, 0x5b, 0xe4, 0xf5, 0xc6, 0x1b, 0x89, 0x53, 0xf9, 0x8d, 0x66, 0xa5,
+ 0x38, 0x75, 0xf5, 0x9c, 0xe6, 0x62, 0x9c, 0x4a, 0xac, 0x6d, 0xd4, 0x79,
+ 0x2c, 0xc6, 0x67, 0xfb, 0x35, 0x7e, 0xf2, 0x1d, 0xf1, 0xb8, 0x8b, 0x58,
+ 0xdc, 0x45, 0x1c, 0xee, 0x22, 0x46, 0x87, 0x6d, 0x7e, 0x01, 0x32, 0xf7,
+ 0x6d, 0x17, 0x31, 0xb8, 0x8b, 0x18, 0xdc, 0xed, 0xd2, 0x71, 0x7c, 0xbf,
+ 0xfe, 0x76, 0xc1, 0xef, 0xfb, 0xcc, 0x83, 0x14, 0x61, 0x57, 0x46, 0x79,
+ 0x3f, 0xc3, 0xcc, 0xa6, 0xd6, 0xe9, 0xfd, 0xf9, 0x79, 0xfd, 0x56, 0x9d,
+ 0x5b, 0xda, 0xb4, 0x49, 0xf9, 0x0b, 0xe6, 0x2b, 0x75, 0xde, 0x1d, 0x00,
+ 0xde, 0x23, 0x79, 0x14, 0xbe, 0x92, 0xba, 0x87, 0x45, 0x3d, 0xad, 0x98,
+ 0x69, 0xe6, 0x8e, 0xc4, 0x34, 0xd3, 0x77, 0x60, 0xcc, 0x36, 0x2f, 0x66,
+ 0x89, 0x49, 0xc8, 0x4c, 0xd7, 0x93, 0xa7, 0x86, 0x99, 0x5e, 0xaf, 0xe7,
+ 0x9a, 0xaf, 0xf3, 0xfc, 0xbd, 0x4e, 0x96, 0x2d, 0x33, 0xfd, 0x59, 0x3e,
+ 0x71, 0xee, 0x7e, 0xfd, 0x3d, 0x8d, 0x4b, 0xd7, 0x1a, 0x53, 0x18, 0x9f,
+ 0x4d, 0xdd, 0x8b, 0xf9, 0xd4, 0xfd, 0xa7, 0x05, 0x7e, 0x9b, 0xd7, 0xe4,
+ 0xf7, 0x98, 0xe6, 0xb7, 0xc7, 0xe3, 0x10, 0xfb, 0xa9, 0xdc, 0x36, 0x79,
+ 0xed, 0xcf, 0xa7, 0x72, 0x93, 0x58, 0x47, 0xdd, 0x01, 0xc1, 0xb3, 0x62,
+ 0x49, 0xc3, 0xc0, 0x7d, 0x61, 0x27, 0xb8, 0xae, 0xff, 0x2d, 0x7f, 0x2d,
+ 0x6b, 0x6e, 0x51, 0xdf, 0x07, 0x3d, 0xbb, 0x31, 0xa6, 0x64, 0xd0, 0x4a,
+ 0x73, 0x5f, 0xef, 0x43, 0xfe, 0xc6, 0x94, 0xfc, 0xe5, 0x10, 0x67, 0x8d,
+ 0xf6, 0x74, 0x24, 0x2c, 0x73, 0xba, 0x8e, 0x39, 0xe4, 0xbe, 0xb2, 0x8f,
+ 0x7d, 0x5c, 0xaf, 0xda, 0xa6, 0x33, 0xff, 0xe7, 0x63, 0x9a, 0xb4, 0x78,
+ 0x79, 0xc1, 0xb5, 0xde, 0xa9, 0x58, 0xd4, 0xa5, 0xc1, 0x05, 0x5d, 0xaa,
+ 0xab, 0xd2, 0x25, 0x7f, 0x9f, 0xeb, 0xc5, 0xff, 0xe6, 0xbe, 0xd2, 0x5d,
+ 0x90, 0xb9, 0x72, 0xe0, 0x1b, 0xcf, 0x82, 0x6c, 0xf0, 0x4e, 0xcc, 0x3d,
+ 0x90, 0x41, 0x7e, 0xdf, 0xd8, 0x03, 0x3d, 0xaa, 0x54, 0xfa, 0x98, 0x27,
+ 0xdf, 0xde, 0xaf, 0xef, 0x5b, 0x5c, 0x51, 0x39, 0x12, 0x6b, 0x59, 0x8e,
+ 0xa4, 0x0f, 0xb2, 0x02, 0x3f, 0x00, 0x3a, 0x98, 0x57, 0x67, 0x49, 0x9f,
+ 0xa0, 0xfa, 0x1b, 0xd2, 0xc5, 0x7a, 0x8f, 0x0f, 0x9d, 0xf5, 0xde, 0x77,
+ 0x14, 0x73, 0xd3, 0xd2, 0x32, 0xc7, 0x27, 0xea, 0x3d, 0x59, 0x39, 0x06,
+ 0xfb, 0xdc, 0x07, 0x59, 0xac, 0x91, 0x9c, 0x9a, 0xef, 0x98, 0xe4, 0x9f,
+ 0xfd, 0xcf, 0xc6, 0xa5, 0xfd, 0x51, 0x77, 0xd2, 0xef, 0xff, 0x78, 0x55,
+ 0xff, 0xc7, 0xd1, 0xff, 0x67, 0x55, 0xfd, 0x1f, 0x0f, 0xf4, 0x3f, 0xa1,
+ 0xfb, 0xd7, 0xa2, 0xbf, 0xd2, 0x83, 0x26, 0xdf, 0x2f, 0x36, 0x1d, 0xc4,
+ 0xb3, 0xcf, 0xfa, 0x63, 0x4e, 0x04, 0xc6, 0x4c, 0x56, 0xad, 0x31, 0x89,
+ 0x7e, 0xf1, 0xa6, 0xa5, 0x6b, 0xa0, 0xee, 0x64, 0x8d, 0xfe, 0xbe, 0x47,
+ 0x9f, 0xe5, 0xa0, 0xce, 0x17, 0xe0, 0x59, 0x0a, 0x7e, 0x33, 0xe2, 0x77,
+ 0x0a, 0xca, 0x9e, 0xff, 0x8d, 0xc2, 0xbf, 0x93, 0x47, 0xbd, 0xcd, 0x40,
+ 0x6f, 0x17, 0xfd, 0x1a, 0x4f, 0x2e, 0x83, 0x32, 0x49, 0x9c, 0x28, 0x4a,
+ 0xc8, 0x29, 0xd3, 0x57, 0x32, 0x0a, 0x33, 0xbe, 0x7d, 0xe2, 0xbd, 0x2b,
+ 0xde, 0xd7, 0xf5, 0xec, 0x70, 0xd8, 0x99, 0xd3, 0x31, 0xe2, 0xaf, 0x90,
+ 0x7e, 0xe0, 0xa6, 0x8f, 0x9d, 0x72, 0xcc, 0xd3, 0x1f, 0xca, 0x31, 0xe7,
+ 0xd7, 0x7a, 0x44, 0x99, 0xd5, 0xeb, 0xf4, 0x2d, 0xc3, 0xb7, 0xc4, 0xb2,
+ 0x3c, 0x5c, 0x68, 0x0d, 0xf8, 0xd6, 0xbf, 0x80, 0x6f, 0xf7, 0xca, 0x94,
+ 0x9d, 0x50, 0x79, 0xd0, 0x43, 0x0b, 0x79, 0x81, 0xc3, 0x91, 0x46, 0x87,
+ 0x79, 0x81, 0xe4, 0xa9, 0x8c, 0x7c, 0xb0, 0xbc, 0xc0, 0xbe, 0x2a, 0x1d,
+ 0xd9, 0xbb, 0xaa, 0xed, 0xfc, 0xb3, 0xfa, 0xb5, 0xe6, 0x05, 0x1e, 0xa9,
+ 0xb2, 0x63, 0x87, 0x6e, 0xc0, 0x76, 0xe6, 0x95, 0xed, 0xe4, 0x5e, 0xaf,
+ 0xe7, 0xcb, 0x7f, 0x25, 0xf2, 0xd1, 0xd8, 0xce, 0xd5, 0x72, 0xe2, 0x41,
+ 0x7b, 0x40, 0xb9, 0xba, 0xac, 0xfd, 0x6c, 0x3c, 0x67, 0x2e, 0x43, 0x3f,
+ 0x4d, 0x19, 0x54, 0xb2, 0xcc, 0xb2, 0x1f, 0xff, 0xde, 0xb7, 0x10, 0xff,
+ 0x2e, 0xc6, 0xac, 0xf0, 0x67, 0xbb, 0xfc, 0xd8, 0x88, 0x7e, 0xb3, 0x6d,
+ 0x14, 0xdc, 0x3d, 0xe6, 0x90, 0x6a, 0x63, 0x8e, 0xf7, 0x36, 0xf9, 0x9c,
+ 0xba, 0x27, 0x70, 0x5e, 0xe7, 0xd2, 0xa6, 0x54, 0x4c, 0xc0, 0xef, 0x1c,
+ 0x85, 0xd4, 0x46, 0xed, 0x03, 0x5e, 0x0f, 0x67, 0x97, 0xc6, 0xcf, 0xa6,
+ 0x79, 0x04, 0x63, 0x19, 0x3f, 0x7f, 0x21, 0x4a, 0x4c, 0xcd, 0x96, 0x57,
+ 0x1d, 0x8f, 0x71, 0x1c, 0xcf, 0x3e, 0x2a, 0x56, 0x46, 0xbf, 0x39, 0x3d,
+ 0xde, 0x8b, 0x95, 0xb3, 0xe5, 0xad, 0x51, 0x0f, 0x17, 0x57, 0x8b, 0x63,
+ 0x8e, 0x44, 0x99, 0x8b, 0x9c, 0x73, 0xaf, 0x47, 0xeb, 0xf2, 0xd8, 0x3c,
+ 0xb4, 0x2c, 0x36, 0xb7, 0x74, 0xec, 0x7d, 0xbf, 0x8a, 0xcd, 0x3d, 0x1e,
+ 0x73, 0x2f, 0xc1, 0xd8, 0xca, 0x01, 0x36, 0xf2, 0x5b, 0x10, 0xb1, 0x82,
+ 0x3e, 0x0b, 0xe4, 0x67, 0xfc, 0x37, 0x94, 0x1f, 0xb3, 0x5c, 0x7e, 0x3e,
+ 0x6e, 0xbb, 0xe1, 0xef, 0xfd, 0xb2, 0x78, 0xf9, 0xc5, 0x3d, 0xa0, 0x85,
+ 0xf1, 0x56, 0x58, 0xcb, 0xc3, 0xcf, 0x69, 0xfc, 0xf6, 0xfb, 0xf9, 0xb9,
+ 0x86, 0x85, 0x6f, 0xc9, 0xc5, 0xcc, 0x92, 0x1c, 0xcf, 0x16, 0xa6, 0xce,
+ 0x71, 0xee, 0x99, 0x1b, 0xf8, 0xde, 0xf2, 0x61, 0xee, 0x7c, 0x54, 0xdb,
+ 0xb9, 0x57, 0x21, 0xfb, 0x09, 0x7d, 0xff, 0xaf, 0x0b, 0x3a, 0xc0, 0x3b,
+ 0xd0, 0xd5, 0x58, 0xab, 0xee, 0xf9, 0x45, 0x36, 0xa5, 0xf9, 0xed, 0x82,
+ 0x3e, 0xc1, 0x4f, 0xf4, 0x5e, 0xe3, 0x72, 0x6c, 0xc2, 0xcb, 0xd3, 0x9a,
+ 0xab, 0xde, 0xf1, 0xbb, 0x04, 0x5e, 0x24, 0x8f, 0xfa, 0x79, 0x5a, 0xd3,
+ 0xbb, 0xe3, 0x77, 0xf4, 0xa3, 0xbb, 0xe3, 0xc7, 0xf9, 0x2d, 0xd9, 0xbb,
+ 0xc2, 0x1d, 0xbf, 0xd0, 0x1a, 0xef, 0xf8, 0x6d, 0x54, 0x79, 0x5a, 0xce,
+ 0xe3, 0xe5, 0x69, 0x59, 0x6e, 0xeb, 0xfe, 0x94, 0xc2, 0xa8, 0xe9, 0x09,
+ 0xe6, 0x75, 0x1e, 0x5c, 0xf7, 0xc9, 0xe4, 0x75, 0xde, 0x8b, 0x7e, 0xfc,
+ 0x79, 0x1d, 0x7e, 0x17, 0xf8, 0xb2, 0xf7, 0xdd, 0x5a, 0x6e, 0x24, 0x3f,
+ 0xf0, 0xe1, 0x72, 0xb0, 0x07, 0x55, 0x0e, 0x76, 0xfb, 0xfa, 0x60, 0x0e,
+ 0xd6, 0xbc, 0xce, 0x3d, 0xb8, 0x83, 0x2b, 0xe4, 0x60, 0xc3, 0x81, 0x7b,
+ 0x70, 0x61, 0x7d, 0x0f, 0x6e, 0xa3, 0x83, 0x18, 0x53, 0xe7, 0x5b, 0xcd,
+ 0x55, 0xef, 0xc1, 0xed, 0x5e, 0xff, 0xe1, 0xf3, 0xad, 0xcb, 0xee, 0xc1,
+ 0x1d, 0xcd, 0x48, 0x8b, 0x24, 0x6e, 0x28, 0x16, 0xfa, 0x30, 0x71, 0x10,
+ 0xff, 0x8f, 0x40, 0x0d, 0xf6, 0x0c, 0x99, 0x8f, 0x51, 0x3e, 0x29, 0x77,
+ 0x69, 0x33, 0x5f, 0xe6, 0x7b, 0x17, 0xcf, 0xc7, 0xe8, 0xef, 0x5c, 0x7a,
+ 0xb7, 0x62, 0xf1, 0x6e, 0x72, 0x64, 0xe1, 0x6e, 0xf2, 0x18, 0x64, 0xc6,
+ 0x9c, 0x88, 0xc8, 0x74, 0xc0, 0xb6, 0x8e, 0xba, 0xf0, 0x9b, 0x26, 0x6d,
+ 0xdd, 0xce, 0xff, 0xa7, 0x82, 0xb8, 0xb0, 0xc4, 0xfb, 0xcc, 0x0d, 0x12,
+ 0x9a, 0x54, 0x98, 0x1a, 0xf3, 0xfe, 0xaf, 0x4e, 0x1c, 0x7d, 0x78, 0x77,
+ 0x35, 0x2c, 0x87, 0x62, 0x94, 0x65, 0x5f, 0x8e, 0xbf, 0x05, 0xfe, 0x36,
+ 0x65, 0x16, 0xcb, 0x31, 0x2d, 0xd7, 0x94, 0x69, 0x5f, 0xfe, 0x62, 0x32,
+ 0x32, 0x41, 0x59, 0xde, 0xa1, 0xff, 0x9f, 0xc4, 0x39, 0x29, 0x94, 0xcf,
+ 0xea, 0x78, 0x43, 0x7d, 0x8b, 0x02, 0x1f, 0x5b, 0xb4, 0x0d, 0xc6, 0x73,
+ 0xa6, 0x85, 0x36, 0x8f, 0xdf, 0x1e, 0xa5, 0x6f, 0x7c, 0x5b, 0x7c, 0x08,
+ 0x78, 0x37, 0xa8, 0x72, 0x27, 0x37, 0xc2, 0x6f, 0xe3, 0x1a, 0xdf, 0x48,
+ 0xd7, 0xca, 0x73, 0xdf, 0x5f, 0xbe, 0x8c, 0xfd, 0xb5, 0x40, 0x36, 0xbe,
+ 0x2a, 0xb9, 0x93, 0xb7, 0x49, 0xdf, 0x89, 0x24, 0xe8, 0x79, 0xbf, 0x52,
+ 0x48, 0xc1, 0xb7, 0x7e, 0x96, 0x77, 0xe1, 0x80, 0xa1, 0x2e, 0x30, 0x14,
+ 0xbc, 0x7b, 0x61, 0x99, 0xbf, 0x11, 0xbc, 0x43, 0x97, 0x5a, 0xb8, 0x13,
+ 0xf5, 0x7c, 0x59, 0x22, 0x8d, 0xa4, 0x7b, 0x62, 0xf1, 0x2e, 0xfc, 0x5c,
+ 0x39, 0xa7, 0xec, 0xdb, 0x73, 0xe5, 0x25, 0x39, 0x21, 0x75, 0x8e, 0xc3,
+ 0xa5, 0x97, 0x61, 0xe3, 0x2e, 0x1b, 0xb4, 0x71, 0x63, 0xae, 0xdc, 0x12,
+ 0x12, 0x9e, 0x89, 0x18, 0xe0, 0x83, 0xba, 0x9b, 0xe2, 0xdd, 0x4d, 0x68,
+ 0x55, 0x67, 0xfb, 0x7f, 0xd4, 0x5d, 0x7d, 0x6c, 0x5b, 0xd7, 0x75, 0x3f,
+ 0x7c, 0xa4, 0x3e, 0x4c, 0xcb, 0xd2, 0x93, 0x4c, 0xc9, 0xb4, 0x2d, 0xcb,
+ 0x8f, 0xd2, 0x93, 0xa5, 0xc4, 0x4a, 0xc1, 0x79, 0xda, 0xaa, 0x01, 0x5a,
+ 0xc7, 0x52, 0xf4, 0xc7, 0x82, 0x60, 0xa5, 0x65, 0x25, 0xf3, 0xd2, 0x2c,
+ 0x51, 0x29, 0xdb, 0xc9, 0xfe, 0x18, 0xe0, 0x25, 0xd9, 0x9a, 0xfd, 0x51,
+ 0xe4, 0x95, 0x94, 0x12, 0x63, 0x56, 0x4d, 0xc6, 0xe6, 0x84, 0x02, 0x0b,
+ 0x36, 0x56, 0x92, 0x9d, 0x14, 0x50, 0xc0, 0x24, 0x6d, 0x87, 0x2c, 0x6d,
+ 0x11, 0x55, 0x76, 0xda, 0x7f, 0x8d, 0x2d, 0xc0, 0xb2, 0x2e, 0x69, 0x14,
+ 0x3b, 0xc8, 0x02, 0x2c, 0x58, 0xbb, 0x6e, 0x28, 0xf6, 0x4f, 0xc7, 0x9d,
+ 0xdf, 0xfd, 0x20, 0x1f, 0xc9, 0x47, 0x7d, 0x24, 0x6e, 0x81, 0x09, 0x10,
+ 0xc8, 0xf7, 0xde, 0x7d, 0xef, 0xdd, 0x7b, 0xee, 0xf9, 0xf8, 0x9d, 0x73,
+ 0xcf, 0xb9, 0x94, 0xba, 0xe2, 0x35, 0x57, 0x6e, 0x49, 0x65, 0x7e, 0x65,
+ 0xce, 0x89, 0x9c, 0x0f, 0x95, 0x43, 0x0b, 0x9a, 0x3a, 0x27, 0x6d, 0x99,
+ 0x17, 0x33, 0xb0, 0x80, 0x73, 0x3d, 0x35, 0xf6, 0xaf, 0x95, 0xf9, 0xc0,
+ 0x14, 0x31, 0x85, 0x69, 0x13, 0x7d, 0xde, 0x2b, 0xf4, 0x81, 0xf7, 0xba,
+ 0x7c, 0x40, 0xe9, 0xbc, 0x56, 0xa5, 0xa3, 0x36, 0xc2, 0x6f, 0xf2, 0x9d,
+ 0xfd, 0xe2, 0x9d, 0xdd, 0x4a, 0x67, 0xe9, 0xdc, 0xf7, 0x71, 0x63, 0xba,
+ 0x08, 0x5f, 0x9b, 0xe9, 0x52, 0x87, 0xdf, 0xac, 0x4d, 0xe8, 0xf8, 0xb9,
+ 0x3a, 0x3a, 0x56, 0xcb, 0x03, 0xfb, 0xe6, 0x65, 0x9d, 0x2d, 0x69, 0x26,
+ 0xcf, 0x23, 0x9f, 0x5f, 0xe7, 0x65, 0x48, 0x9a, 0x95, 0xe5, 0xe7, 0x92,
+ 0x3b, 0x27, 0xa3, 0x42, 0xb3, 0xe9, 0x32, 0xcd, 0xf6, 0xfc, 0x3f, 0xa0,
+ 0xd9, 0x4d, 0x81, 0x79, 0x5f, 0x29, 0x22, 0xff, 0x6e, 0x58, 0xe4, 0x2e,
+ 0xac, 0xd2, 0x88, 0xb2, 0xff, 0xee, 0x1a, 0x28, 0xd0, 0x12, 0xba, 0x34,
+ 0x52, 0x58, 0xa7, 0x98, 0x8c, 0x43, 0x98, 0xa5, 0xd2, 0x77, 0xa2, 0x90,
+ 0x3f, 0xf8, 0x24, 0xf0, 0x51, 0x10, 0xdf, 0x3b, 0xc9, 0x63, 0xfb, 0x97,
+ 0x60, 0xd7, 0x06, 0x36, 0xf2, 0xe4, 0x36, 0x7c, 0x94, 0x8a, 0x8d, 0x04,
+ 0x5e, 0x22, 0x27, 0x6e, 0x57, 0xf2, 0x5e, 0x66, 0xb3, 0x3f, 0x6c, 0x67,
+ 0x3f, 0x92, 0x69, 0x5c, 0x79, 0xee, 0xd6, 0x7c, 0x14, 0x3c, 0x4f, 0xda,
+ 0xc9, 0xd9, 0x6c, 0xe5, 0xb9, 0x4e, 0xf9, 0xb9, 0x61, 0x0f, 0x5d, 0x65,
+ 0xd1, 0xcc, 0xa5, 0x7d, 0x75, 0xf9, 0x6a, 0x95, 0xf1, 0x48, 0x5f, 0x45,
+ 0x8f, 0xe7, 0xc9, 0x4d, 0xf1, 0xa5, 0xcc, 0x3b, 0xab, 0xe4, 0xf0, 0xd4,
+ 0xfa, 0x29, 0xfb, 0x5d, 0xf1, 0x19, 0xd0, 0xf8, 0x0f, 0x69, 0x75, 0x12,
+ 0x7a, 0xae, 0x96, 0xd6, 0xef, 0xff, 0x9a, 0x68, 0x1d, 0xe9, 0xf8, 0xf5,
+ 0xd2, 0x7a, 0x7f, 0x5d, 0x2c, 0xbc, 0x32, 0x1e, 0x0a, 0x75, 0x6f, 0x0b,
+ 0xcb, 0xd7, 0xd2, 0x7a, 0x7f, 0xc3, 0x78, 0x6a, 0xe3, 0x5c, 0xcc, 0xea,
+ 0x78, 0x6a, 0xbf, 0xc1, 0x32, 0x92, 0x65, 0x79, 0x69, 0xa8, 0xe3, 0xff,
+ 0xce, 0x15, 0x6f, 0x75, 0xeb, 0x79, 0xc8, 0x1a, 0xf9, 0x4e, 0x0e, 0xe9,
+ 0x77, 0x42, 0xae, 0x22, 0x8e, 0x43, 0xf0, 0x9f, 0xf0, 0x5e, 0xe4, 0x62,
+ 0xd5, 0xe1, 0x2e, 0x7e, 0x2f, 0xcb, 0xff, 0x0b, 0xcf, 0x0b, 0x9b, 0x25,
+ 0x63, 0x12, 0x68, 0x1f, 0xf2, 0x9d, 0x11, 0x6d, 0x65, 0x8e, 0x96, 0x8a,
+ 0x51, 0x28, 0x3f, 0xa0, 0x51, 0x6c, 0xa2, 0xde, 0xfe, 0x6d, 0xcf, 0x6f,
+ 0xd0, 0xf1, 0x88, 0x83, 0x3c, 0x3f, 0xe1, 0x2a, 0xbf, 0x0b, 0xfa, 0xf4,
+ 0x3c, 0x63, 0x84, 0xfe, 0x32, 0x3e, 0xa8, 0x9e, 0xa3, 0x59, 0xe1, 0xdf,
+ 0x69, 0x5d, 0xba, 0x2a, 0x73, 0x6b, 0xc5, 0x79, 0xe0, 0xb5, 0xb2, 0x2e,
+ 0xad, 0xc1, 0xc3, 0x07, 0x3d, 0xf8, 0xc3, 0xb3, 0x9e, 0x55, 0xcf, 0xa1,
+ 0x85, 0x9c, 0xfa, 0x84, 0xe7, 0x1c, 0x96, 0xeb, 0xd2, 0x9c, 0x4a, 0x5b,
+ 0x79, 0x7f, 0x42, 0x8c, 0x6b, 0xea, 0xde, 0x38, 0xea, 0xef, 0xca, 0x35,
+ 0x51, 0xb5, 0x75, 0x60, 0xb0, 0x0b, 0x5a, 0x1e, 0x75, 0xcd, 0x39, 0x68,
+ 0xd1, 0xe7, 0x51, 0x07, 0xe6, 0xb6, 0x2d, 0xb8, 0xaf, 0x96, 0x16, 0x15,
+ 0xbb, 0x32, 0xa7, 0xec, 0xca, 0xa2, 0x4b, 0xaf, 0xd7, 0xe3, 0xf7, 0x2e,
+ 0x0f, 0xfc, 0xee, 0x55, 0x0b, 0x86, 0x3e, 0x3d, 0xc5, 0x98, 0xe4, 0x33,
+ 0xc0, 0x24, 0x26, 0x6a, 0xb1, 0x24, 0x2e, 0xc1, 0xf5, 0x1c, 0x63, 0x93,
+ 0x30, 0xf3, 0xca, 0x6b, 0x74, 0x8e, 0x31, 0xf7, 0x35, 0xba, 0x4b, 0xf9,
+ 0x69, 0x90, 0x5f, 0x9d, 0x47, 0x8b, 0x5a, 0x06, 0x1f, 0x39, 0x0f, 0x45,
+ 0x86, 0x63, 0xf4, 0x1a, 0x9d, 0x15, 0xf9, 0x3e, 0x58, 0xff, 0x43, 0x9e,
+ 0xc4, 0xdd, 0xe2, 0xfd, 0x32, 0xae, 0x71, 0x27, 0xf2, 0x02, 0xb7, 0x5e,
+ 0x9f, 0xa0, 0xea, 0x05, 0xb9, 0x1d, 0xde, 0xb9, 0xac, 0x64, 0x4a, 0x9c,
+ 0xe3, 0xfb, 0x9f, 0x32, 0xea, 0xef, 0x8f, 0x19, 0x89, 0x62, 0xc2, 0x88,
+ 0x2f, 0xa1, 0xdd, 0x53, 0xc6, 0x44, 0x11, 0xbe, 0xa4, 0xe6, 0x91, 0x48,
+ 0x14, 0xf2, 0xb6, 0x46, 0x9b, 0xaf, 0x53, 0x2c, 0x52, 0x4d, 0xad, 0xc8,
+ 0x16, 0xfa, 0x7d, 0xac, 0xaa, 0xdf, 0x9a, 0xbe, 0xf8, 0x8e, 0xd8, 0xcf,
+ 0xcb, 0x4c, 0x53, 0x8d, 0x71, 0x83, 0x88, 0xbd, 0x0f, 0x3b, 0xb4, 0x11,
+ 0xc6, 0x8d, 0xd4, 0x61, 0xdc, 0xc5, 0x4d, 0xfb, 0xfd, 0x69, 0x65, 0x5c,
+ 0xd6, 0x7c, 0xfb, 0x6d, 0x81, 0x65, 0xb9, 0xdf, 0x55, 0x38, 0xb7, 0x86,
+ 0xa7, 0xd0, 0x46, 0xc7, 0xc8, 0x75, 0x4c, 0xac, 0x5d, 0xc5, 0x74, 0x75,
+ 0x3e, 0x45, 0x50, 0xc5, 0xb4, 0x71, 0x1d, 0xbe, 0xd6, 0x2a, 0xf7, 0x0f,
+ 0x7e, 0x17, 0xe2, 0x3f, 0x6e, 0xbf, 0xcb, 0x1d, 0xf3, 0xf5, 0xaa, 0x0d,
+ 0xed, 0xf7, 0xa8, 0x0d, 0x75, 0xcb, 0x59, 0xc0, 0x25, 0x67, 0x61, 0x17,
+ 0x86, 0xeb, 0x65, 0xff, 0xa5, 0x8d, 0xf5, 0x07, 0xfc, 0x97, 0x20, 0xf9,
+ 0x2f, 0xbb, 0xfd, 0x97, 0xda, 0x3a, 0x7f, 0xc8, 0x1c, 0x70, 0x9a, 0xf4,
+ 0x65, 0x12, 0xf9, 0xf2, 0x1e, 0x01, 0x3c, 0xe6, 0x4a, 0x1d, 0xe6, 0x52,
+ 0x5d, 0xcd, 0xa8, 0x57, 0x7f, 0xfb, 0xea, 0xfa, 0x0b, 0x1b, 0x16, 0x6b,
+ 0x88, 0xef, 0xbc, 0xfc, 0xab, 0x3b, 0xd5, 0xbf, 0x5a, 0x5d, 0x86, 0x77,
+ 0xf5, 0x8b, 0x18, 0xb8, 0x53, 0xd6, 0x63, 0x63, 0xb2, 0xbf, 0xd9, 0x6a,
+ 0x5f, 0xc3, 0x7f, 0x89, 0x14, 0xed, 0xbc, 0xf5, 0xfa, 0xf6, 0xe2, 0x68,
+ 0x3b, 0x6b, 0x6c, 0xef, 0x78, 0xa7, 0x8c, 0x8f, 0xcd, 0xa9, 0x3c, 0xf2,
+ 0x6e, 0xe5, 0xf7, 0x6d, 0xc6, 0xeb, 0x38, 0x37, 0xa7, 0x62, 0x8a, 0x11,
+ 0xab, 0x40, 0xe0, 0xf1, 0xc9, 0xd3, 0x4d, 0xb6, 0xa9, 0xd6, 0xb8, 0xb0,
+ 0x8e, 0x05, 0x9e, 0xd7, 0xcf, 0x97, 0x35, 0x65, 0x9b, 0xcf, 0x99, 0x55,
+ 0x37, 0x67, 0x92, 0xaf, 0xe0, 0x6f, 0x21, 0x3f, 0x7a, 0xa4, 0x26, 0x47,
+ 0xfd, 0xd3, 0xd0, 0xa2, 0xdd, 0x23, 0x6f, 0x1b, 0x79, 0xd7, 0x8d, 0xfa,
+ 0xb9, 0xee, 0xc2, 0xea, 0xb2, 0x6e, 0x63, 0x95, 0xd0, 0xef, 0x52, 0xe9,
+ 0xe5, 0x28, 0xb0, 0x69, 0x6f, 0x1d, 0xaf, 0x69, 0xbc, 0x64, 0xba, 0xfa,
+ 0xf9, 0xf8, 0xc6, 0xfd, 0xac, 0xb1, 0xbf, 0x7b, 0x3d, 0xec, 0x6f, 0x23,
+ 0x5f, 0x42, 0xec, 0x9d, 0xe2, 0x3b, 0x2a, 0x74, 0x41, 0x1b, 0x2d, 0xe5,
+ 0x91, 0x4b, 0xfe, 0x1b, 0xa8, 0x67, 0x65, 0x7d, 0xeb, 0xaa, 0xcf, 0xf3,
+ 0x9e, 0xd3, 0xf2, 0x7a, 0x4b, 0x60, 0x1c, 0xeb, 0x83, 0xc8, 0x41, 0xe9,
+ 0x62, 0x1d, 0x84, 0xf6, 0x83, 0xd6, 0x0d, 0xc4, 0x80, 0x55, 0x3c, 0x2a,
+ 0xa1, 0xec, 0xcc, 0xd1, 0x2d, 0xac, 0xbb, 0x6c, 0x4f, 0x5f, 0x47, 0xac,
+ 0x55, 0xc2, 0x9a, 0x10, 0xf2, 0x9e, 0x9d, 0x76, 0x6a, 0xbf, 0xbf, 0xa5,
+ 0xc5, 0xbe, 0xd9, 0x29, 0xd7, 0xaa, 0x70, 0xad, 0x8d, 0xae, 0xe6, 0x91,
+ 0x97, 0x8e, 0x6b, 0x0f, 0xf2, 0x35, 0x2f, 0x7d, 0xf5, 0xb6, 0xe2, 0x25,
+ 0x60, 0x3a, 0x39, 0x47, 0x05, 0x92, 0x73, 0xb6, 0x4e, 0xf0, 0xa5, 0x4a,
+ 0xf4, 0x4f, 0xd1, 0xdf, 0x14, 0xfe, 0x5f, 0x65, 0xae, 0xb6, 0xb7, 0x8e,
+ 0x53, 0x9b, 0x03, 0x31, 0xb9, 0x61, 0x1c, 0xb1, 0xa3, 0x6b, 0xab, 0xeb,
+ 0x38, 0xb5, 0x39, 0x10, 0x8f, 0x6f, 0x29, 0x8e, 0x18, 0xb1, 0xa6, 0x37,
+ 0xac, 0x33, 0x70, 0xaf, 0xa9, 0xe8, 0xb5, 0xe4, 0x51, 0x51, 0x7b, 0xeb,
+ 0xe6, 0x89, 0x3b, 0xb3, 0x9e, 0x0c, 0xde, 0xe8, 0xab, 0xd3, 0x61, 0x77,
+ 0x60, 0x3d, 0xa0, 0x86, 0xb6, 0x41, 0xcf, 0x58, 0x96, 0xf7, 0xba, 0x31,
+ 0x72, 0x04, 0x10, 0xc3, 0x2e, 0xd2, 0x99, 0x2b, 0xe0, 0x67, 0x83, 0x39,
+ 0x6f, 0x80, 0x32, 0x21, 0xd4, 0x52, 0x89, 0xba, 0x28, 0xbd, 0xbe, 0x28,
+ 0xea, 0xa3, 0xce, 0x88, 0xba, 0xcf, 0xc1, 0xf0, 0x6d, 0xb6, 0x91, 0x67,
+ 0x8a, 0x6f, 0xd1, 0xd9, 0xa5, 0x20, 0xff, 0x57, 0xf0, 0x7c, 0x7d, 0xed,
+ 0x67, 0x35, 0xbf, 0xdf, 0x16, 0xfc, 0xde, 0xbb, 0x21, 0xbf, 0x1f, 0x2f,
+ 0xf3, 0x3b, 0x77, 0x28, 0x28, 0x6b, 0x2b, 0x53, 0x57, 0xda, 0xe9, 0xa8,
+ 0x78, 0xee, 0x5b, 0xfc, 0x7d, 0x27, 0x1d, 0x35, 0xe5, 0xf7, 0xb3, 0x4b,
+ 0xac, 0xfb, 0xb3, 0x6f, 0xd1, 0xb9, 0x2b, 0x8e, 0x2f, 0x21, 0xea, 0x32,
+ 0xdc, 0x7b, 0x86, 0xe8, 0xfb, 0xd1, 0xce, 0x4b, 0x16, 0xea, 0xf5, 0x55,
+ 0x41, 0xea, 0x2b, 0xba, 0x29, 0x62, 0x20, 0xde, 0xfa, 0x0a, 0xfc, 0x79,
+ 0x5e, 0xd9, 0xc6, 0xc9, 0x0d, 0x62, 0x1f, 0xf5, 0xbc, 0xd9, 0xe9, 0x81,
+ 0x91, 0xbf, 0xdb, 0x25, 0xd7, 0xb1, 0x36, 0x8a, 0x81, 0x54, 0xe5, 0x81,
+ 0xb8, 0xd7, 0xf9, 0xd9, 0x1e, 0x4c, 0xaa, 0x75, 0xf7, 0x9f, 0x76, 0x49,
+ 0x3b, 0x82, 0x9a, 0xc8, 0x55, 0xa6, 0xc3, 0x3f, 0x30, 0x7e, 0xd9, 0x4f,
+ 0xcd, 0x97, 0xf5, 0x58, 0xf7, 0x0b, 0x7f, 0xc8, 0x1d, 0xcb, 0x99, 0x55,
+ 0x35, 0xee, 0x69, 0xd7, 0x98, 0x66, 0x85, 0xdf, 0xf3, 0x49, 0xd6, 0x31,
+ 0x7b, 0x6b, 0x6c, 0x45, 0x2d, 0xbf, 0x61, 0x3f, 0x16, 0xcc, 0x2f, 0x19,
+ 0x12, 0x1b, 0x8f, 0x31, 0xe6, 0xdd, 0xee, 0x7a, 0xd2, 0xa7, 0xc5, 0x8d,
+ 0xb5, 0x7b, 0x7d, 0xd4, 0x7e, 0xc7, 0x3c, 0x48, 0x3f, 0x24, 0xf5, 0x42,
+ 0x51, 0xe8, 0x82, 0xd9, 0x91, 0x12, 0x4d, 0x44, 0x77, 0x51, 0x6a, 0x84,
+ 0xdf, 0x3d, 0x66, 0xb3, 0x3f, 0xe6, 0x27, 0x87, 0xe5, 0x37, 0x35, 0xb2,
+ 0x43, 0xd5, 0xcc, 0xe9, 0x58, 0x7b, 0x8b, 0xc2, 0x90, 0xed, 0x62, 0xdd,
+ 0x52, 0xee, 0x49, 0xc4, 0xdf, 0x97, 0xf4, 0xb3, 0x71, 0x1e, 0xbc, 0xdb,
+ 0xac, 0xda, 0x5d, 0x74, 0xb5, 0x43, 0x9b, 0x8b, 0xaa, 0x2d, 0x9e, 0xa9,
+ 0xb1, 0x86, 0xae, 0xd3, 0x82, 0x1c, 0xae, 0xaa, 0xfa, 0x44, 0xf9, 0xbc,
+ 0x99, 0xe2, 0x45, 0x6e, 0xd3, 0xa5, 0xae, 0x5f, 0x64, 0xfc, 0x5b, 0x14,
+ 0x32, 0x22, 0xfb, 0xd2, 0x54, 0xee, 0x8b, 0xc4, 0xed, 0xb8, 0xa7, 0x5d,
+ 0xe5, 0x62, 0xbe, 0x25, 0xd7, 0x05, 0x54, 0x1f, 0xe4, 0x75, 0xfe, 0x5c,
+ 0xaa, 0xf6, 0x29, 0xdf, 0x28, 0xea, 0x75, 0x88, 0x8f, 0x7d, 0x33, 0xd9,
+ 0x77, 0x7c, 0x32, 0xe7, 0xd8, 0x14, 0x6b, 0xa9, 0x32, 0x7f, 0x43, 0x7f,
+ 0x47, 0xac, 0x19, 0x39, 0x16, 0xc8, 0x9f, 0x70, 0xeb, 0x16, 0x39, 0xb6,
+ 0x00, 0x6c, 0x50, 0x11, 0x6b, 0xa8, 0x1b, 0xe1, 0xe7, 0xbd, 0xcc, 0x9b,
+ 0xe6, 0x36, 0x70, 0xe8, 0x56, 0x64, 0xcd, 0xf2, 0x90, 0x35, 0xf7, 0xfb,
+ 0x51, 0xcb, 0x87, 0x9a, 0x3e, 0x67, 0xd8, 0xa0, 0x12, 0xfb, 0x0a, 0x06,
+ 0x15, 0x4c, 0x1f, 0x9d, 0xb3, 0x23, 0xd1, 0x25, 0x81, 0x37, 0xef, 0x43,
+ 0xce, 0xcf, 0xf0, 0x2a, 0x1d, 0x36, 0xcf, 0x92, 0xdc, 0xef, 0xa1, 0xc0,
+ 0xb6, 0x77, 0x9a, 0xf9, 0xed, 0x2c, 0xfb, 0x1f, 0xce, 0x14, 0xd6, 0x5d,
+ 0x34, 0xcd, 0xb0, 0x0f, 0x00, 0x3e, 0x2d, 0x9e, 0xa7, 0xe2, 0x6e, 0x0a,
+ 0xc6, 0xf8, 0x99, 0x16, 0x74, 0x11, 0x3f, 0x27, 0x49, 0x71, 0xf6, 0x93,
+ 0xe0, 0xb3, 0x4e, 0x4f, 0x45, 0xcc, 0x02, 0x19, 0xdc, 0x16, 0xbe, 0x2b,
+ 0x9e, 0x83, 0xfb, 0x63, 0x66, 0x13, 0xd5, 0xd6, 0x1c, 0xb7, 0x8b, 0x3a,
+ 0xcc, 0x9b, 0xd1, 0x7b, 0xc8, 0xe8, 0x81, 0x6e, 0xc2, 0x9c, 0xdd, 0xad,
+ 0xd6, 0x8b, 0x3a, 0xf8, 0xfb, 0x90, 0xfa, 0x2e, 0xe7, 0x5a, 0x7e, 0xd7,
+ 0xbc, 0x8c, 0xbf, 0x0f, 0x5b, 0xc8, 0xfe, 0x5d, 0x35, 0x7f, 0xd5, 0xeb,
+ 0x66, 0xfd, 0x46, 0x90, 0xce, 0x7b, 0xae, 0x9b, 0x6d, 0x54, 0xcb, 0xdb,
+ 0xb1, 0xc5, 0x5a, 0xde, 0x9f, 0xef, 0x96, 0xf5, 0x71, 0xee, 0xbe, 0xfc,
+ 0x9c, 0xfb, 0xe2, 0x15, 0x0f, 0x71, 0xeb, 0x5e, 0xad, 0x73, 0x4b, 0xf4,
+ 0x6f, 0xd1, 0xcf, 0xd2, 0x7a, 0x28, 0xac, 0xf2, 0x99, 0x90, 0xbf, 0x74,
+ 0x8f, 0xe2, 0x55, 0xad, 0xe7, 0xc9, 0x43, 0xcf, 0x3f, 0x20, 0xf2, 0x8e,
+ 0xa5, 0x9d, 0xd8, 0xaf, 0xe8, 0x01, 0x9a, 0x85, 0x5d, 0x34, 0xeb, 0x76,
+ 0xd1, 0xcc, 0x50, 0xdf, 0x77, 0x89, 0xe3, 0xf3, 0x4b, 0xaf, 0x76, 0xc8,
+ 0x7a, 0x78, 0xac, 0x29, 0x7e, 0x5f, 0x7d, 0xdf, 0x6c, 0xbc, 0x0f, 0x84,
+ 0x28, 0x28, 0xe2, 0x4d, 0xae, 0xb1, 0xbe, 0x44, 0x64, 0xb3, 0x37, 0x5c,
+ 0x47, 0x83, 0x6f, 0xb9, 0xce, 0xa3, 0x8f, 0x83, 0xae, 0x3e, 0xf6, 0xbb,
+ 0xfa, 0x78, 0xb0, 0x41, 0x1f, 0x59, 0x9f, 0xf3, 0x7b, 0xce, 0x16, 0x3f,
+ 0x69, 0x5f, 0xd1, 0x4f, 0xd4, 0x49, 0x83, 0x9e, 0x3b, 0x29, 0x1d, 0x0a,
+ 0x2b, 0x3b, 0x11, 0x55, 0xf5, 0x03, 0x5e, 0x7d, 0xfe, 0x31, 0x35, 0x9e,
+ 0x37, 0x37, 0xaf, 0xba, 0xeb, 0xab, 0x9f, 0xa3, 0x09, 0x59, 0x27, 0xaf,
+ 0x64, 0xfb, 0x62, 0x83, 0x78, 0x34, 0x72, 0x3b, 0x80, 0x37, 0x84, 0x6f,
+ 0xb8, 0x4f, 0xee, 0x6f, 0x17, 0xa0, 0xe5, 0x72, 0xad, 0xb2, 0x5f, 0xd5,
+ 0xf0, 0x3d, 0x1b, 0xba, 0xb3, 0x75, 0xca, 0x38, 0xff, 0x3d, 0x11, 0xcb,
+ 0x93, 0xeb, 0x48, 0xab, 0xaa, 0xde, 0x3a, 0x62, 0x21, 0x47, 0x60, 0x71,
+ 0x05, 0x71, 0xd8, 0x46, 0xb5, 0xc9, 0x52, 0x17, 0xa5, 0xca, 0x7b, 0xc2,
+ 0x14, 0x44, 0x1d, 0x86, 0x8c, 0x8f, 0xc9, 0x1a, 0xe2, 0xc5, 0x95, 0x1b,
+ 0xa2, 0x6e, 0x37, 0xae, 0x6a, 0x91, 0x53, 0xd4, 0x26, 0x70, 0xed, 0x27,
+ 0xaf, 0x21, 0xfe, 0x71, 0x68, 0xfb, 0x35, 0xc4, 0xee, 0x7b, 0xb6, 0x57,
+ 0x43, 0x6c, 0xf2, 0xd8, 0x8d, 0x05, 0x59, 0x43, 0x5c, 0xbd, 0x46, 0x23,
+ 0x6b, 0x88, 0x53, 0x2e, 0xac, 0x20, 0xf1, 0xf9, 0x4d, 0x57, 0x7e, 0xb7,
+ 0xac, 0x0f, 0x5e, 0x2c, 0xe3, 0x53, 0x59, 0x1f, 0x2c, 0xf3, 0xc1, 0xdd,
+ 0x7b, 0xdf, 0xc8, 0xb5, 0x20, 0xf9, 0x9e, 0x5d, 0x35, 0x6b, 0x41, 0xb2,
+ 0x2e, 0xd8, 0x32, 0xbc, 0xf8, 0x4e, 0xdb, 0x25, 0xec, 0xf7, 0x10, 0x63,
+ 0xde, 0xdd, 0xd9, 0x60, 0xbf, 0x87, 0x58, 0x83, 0xfd, 0x1e, 0xdc, 0xba,
+ 0xdf, 0x8d, 0xa7, 0x80, 0x7f, 0x61, 0x17, 0x81, 0x7b, 0xb1, 0x5f, 0x43,
+ 0x94, 0xce, 0x97, 0x71, 0xe6, 0x3d, 0x94, 0x54, 0x38, 0xf3, 0xfc, 0x92,
+ 0xd6, 0x47, 0xfd, 0x35, 0xfa, 0xc8, 0x0b, 0x77, 0x46, 0x54, 0xce, 0x8f,
+ 0x96, 0x57, 0xc7, 0x25, 0xaf, 0x8e, 0x87, 0xbc, 0xe2, 0x1e, 0xa7, 0x41,
+ 0xbf, 0x41, 0x13, 0xdc, 0x83, 0xff, 0x97, 0xc2, 0xd8, 0xa7, 0x86, 0xe8,
+ 0x0b, 0xdd, 0x0a, 0xeb, 0xb9, 0xe4, 0xf5, 0x2c, 0xcb, 0xab, 0x3e, 0x8f,
+ 0xfe, 0x36, 0xc2, 0xfb, 0x1a, 0x1f, 0xee, 0xf7, 0x1d, 0xbb, 0xf2, 0x0b,
+ 0x91, 0x17, 0x50, 0xed, 0x27, 0x6a, 0x0c, 0x71, 0x48, 0xc8, 0xd2, 0xba,
+ 0x1f, 0xf9, 0x2b, 0xfa, 0x1c, 0x6a, 0xa7, 0x20, 0x7f, 0x9a, 0x16, 0xcd,
+ 0x35, 0x38, 0xa3, 0x5d, 0xe1, 0x08, 0x91, 0xff, 0xeb, 0xea, 0xdb, 0x7f,
+ 0x72, 0xdf, 0xf4, 0x79, 0x6d, 0x33, 0xdf, 0xae, 0x8a, 0x69, 0x54, 0xe7,
+ 0x4d, 0x22, 0x7e, 0xb4, 0x2b, 0x69, 0xd8, 0x09, 0x91, 0x7f, 0xda, 0x69,
+ 0x23, 0x56, 0x16, 0x67, 0xd9, 0xef, 0x4c, 0x22, 0xd7, 0xb9, 0xf3, 0x92,
+ 0x45, 0xa7, 0xb2, 0x57, 0x0f, 0x48, 0x5e, 0x79, 0x5a, 0xec, 0xd3, 0x89,
+ 0x7d, 0x1d, 0x27, 0xd8, 0x3e, 0xc7, 0x19, 0x60, 0xce, 0x15, 0x5b, 0x68,
+ 0x91, 0x91, 0xbc, 0xdf, 0x2e, 0x88, 0x58, 0x1f, 0xeb, 0xa4, 0x1c, 0xf6,
+ 0x6b, 0x35, 0x16, 0x9a, 0xf9, 0xb9, 0x3d, 0xb4, 0x9c, 0x07, 0xcf, 0x35,
+ 0xa9, 0xfd, 0x53, 0xd0, 0xd6, 0x47, 0x5d, 0xf6, 0xdf, 0x32, 0xed, 0x1e,
+ 0x11, 0x79, 0x97, 0x8b, 0xb9, 0xa7, 0xe5, 0x67, 0xe1, 0x55, 0xf5, 0x0e,
+ 0x7e, 0x5f, 0xf1, 0x75, 0x8a, 0x75, 0xb9, 0xf3, 0x00, 0xdd, 0x7f, 0xde,
+ 0x78, 0xe5, 0xe4, 0xb6, 0xf0, 0x8a, 0x93, 0xac, 0xe0, 0x15, 0xf7, 0xb3,
+ 0x35, 0x76, 0xf9, 0xe3, 0x1e, 0xb9, 0x9f, 0x05, 0x68, 0xb0, 0x13, 0x58,
+ 0x2c, 0x09, 0x5a, 0x1a, 0xe3, 0x91, 0x70, 0xdc, 0x3f, 0x46, 0x99, 0xe2,
+ 0x35, 0x4a, 0xe5, 0x60, 0xe7, 0xf9, 0xb3, 0xf0, 0x37, 0x7b, 0x64, 0x9c,
+ 0x46, 0xdf, 0x03, 0xbd, 0xb2, 0x9b, 0xdb, 0x37, 0xef, 0x91, 0x39, 0xdb,
+ 0xee, 0xf3, 0xed, 0x7c, 0xfe, 0xc9, 0x70, 0xf5, 0xf9, 0x1d, 0x7c, 0xbe,
+ 0x2b, 0x89, 0x39, 0x34, 0x2e, 0x21, 0x36, 0x39, 0x4c, 0x69, 0x9e, 0x9f,
+ 0x4c, 0x91, 0x6d, 0xeb, 0x65, 0xd6, 0x57, 0x4b, 0xba, 0x5d, 0x37, 0xb7,
+ 0x0b, 0x89, 0x39, 0x31, 0xb8, 0xcd, 0x6c, 0x76, 0x84, 0xdb, 0xed, 0x27,
+ 0xff, 0x65, 0x8b, 0x32, 0x4b, 0x9a, 0x57, 0x75, 0x2e, 0xfe, 0x2f, 0xba,
+ 0x65, 0x6e, 0xd5, 0xae, 0xb0, 0xa4, 0xdf, 0xb0, 0x88, 0x7b, 0x22, 0xb7,
+ 0xe3, 0x19, 0xc1, 0x87, 0x91, 0x31, 0xab, 0xfc, 0x7e, 0xec, 0x31, 0x26,
+ 0xf6, 0x7c, 0xe5, 0x31, 0xb0, 0x5e, 0x1c, 0xb7, 0xcd, 0x74, 0x39, 0x6f,
+ 0x6d, 0x6d, 0x9f, 0xbc, 0x7f, 0x67, 0x8f, 0xdc, 0x7f, 0xb5, 0x53, 0xed,
+ 0x15, 0xa8, 0x6d, 0xce, 0x17, 0x90, 0xa7, 0x2d, 0x68, 0xe3, 0x5f, 0x80,
+ 0xbe, 0x34, 0xf8, 0x3b, 0x8f, 0x27, 0x89, 0x3e, 0xf6, 0xf6, 0xe8, 0x3d,
+ 0x17, 0xe5, 0xb8, 0x4e, 0x70, 0x7f, 0x13, 0x3c, 0x2e, 0x7d, 0x3e, 0xc6,
+ 0xc7, 0x5e, 0xf3, 0x8b, 0x67, 0x05, 0xf9, 0x39, 0x2c, 0x03, 0x53, 0xc1,
+ 0x64, 0x6a, 0x58, 0xce, 0x73, 0x25, 0xae, 0x1b, 0x2e, 0xc7, 0x75, 0xe7,
+ 0xb2, 0xc7, 0x7b, 0x10, 0xcf, 0x30, 0x2e, 0xf1, 0x7c, 0x87, 0x9e, 0xe1,
+ 0xb6, 0xa8, 0x63, 0x48, 0xf3, 0x67, 0x9b, 0xca, 0xef, 0xa9, 0xe7, 0x15,
+ 0x99, 0x2f, 0xa1, 0xed, 0x16, 0xee, 0xbd, 0x97, 0x9f, 0x21, 0x6d, 0x57,
+ 0xe3, 0xf7, 0x50, 0x5d, 0x4e, 0x4c, 0x3d, 0x8f, 0x6d, 0x14, 0x8b, 0x15,
+ 0xeb, 0x8a, 0x1e, 0x7c, 0xb6, 0x51, 0xac, 0x44, 0xe4, 0x39, 0xfb, 0x26,
+ 0xea, 0xe4, 0x15, 0x72, 0x1c, 0xa0, 0x27, 0xe6, 0x1d, 0xda, 0xc1, 0x73,
+ 0xf5, 0x27, 0x06, 0xea, 0x86, 0x4b, 0x24, 0x73, 0x9f, 0x98, 0xc6, 0x59,
+ 0x7b, 0xf8, 0xac, 0xc1, 0x74, 0xce, 0x3a, 0xa5, 0x80, 0xdd, 0x46, 0xcd,
+ 0x2c, 0xab, 0xbf, 0x4f, 0x03, 0xec, 0xeb, 0x41, 0x66, 0xed, 0x70, 0x82,
+ 0x20, 0x6f, 0x11, 0xf3, 0x18, 0xf3, 0xc4, 0x44, 0x11, 0xfc, 0x6c, 0xd0,
+ 0x63, 0x79, 0xa2, 0x47, 0xf3, 0x03, 0xe6, 0x37, 0xc9, 0xb6, 0x2a, 0xd7,
+ 0x23, 0x66, 0x9c, 0xfb, 0x91, 0x28, 0xfe, 0x25, 0x7d, 0x24, 0xf6, 0x71,
+ 0x01, 0x1d, 0xf5, 0xbc, 0xff, 0x39, 0x4d, 0x27, 0xd1, 0xef, 0xad, 0xcb,
+ 0xe7, 0xa9, 0x6d, 0xc9, 0x67, 0xd0, 0x43, 0x3e, 0x3f, 0x54, 0x7c, 0x53,
+ 0x62, 0x1e, 0x0d, 0xd2, 0x4c, 0x0e, 0xb9, 0x60, 0x9f, 0x47, 0x0d, 0x66,
+ 0x2e, 0xc5, 0x7a, 0x29, 0x55, 0xd1, 0x4b, 0x17, 0xe2, 0xfe, 0x18, 0x64,
+ 0x1c, 0x7b, 0xd1, 0xa9, 0x1c, 0x20, 0x8c, 0x63, 0x1f, 0x0d, 0x2c, 0xec,
+ 0xe4, 0x7b, 0x69, 0x35, 0x3e, 0x1a, 0x53, 0x7b, 0x15, 0x44, 0xac, 0x09,
+ 0xd6, 0x8f, 0x73, 0x2c, 0xcb, 0xe9, 0xdc, 0xdd, 0xb4, 0x18, 0xea, 0xa5,
+ 0xfe, 0x05, 0xbd, 0x7f, 0x0b, 0xc6, 0x3a, 0xd4, 0x2b, 0x75, 0x92, 0x1e,
+ 0xf7, 0x6f, 0x89, 0x38, 0x85, 0x75, 0xed, 0x57, 0x35, 0xee, 0x9d, 0x9b,
+ 0xe8, 0xa5, 0x92, 0x92, 0xd9, 0xd2, 0x1b, 0xf1, 0x28, 0x39, 0xf1, 0xd1,
+ 0xff, 0x15, 0xfc, 0xdf, 0x7f, 0x0d, 0xb5, 0x38, 0xd0, 0xd1, 0x16, 0x25,
+ 0xb3, 0xb5, 0xb4, 0xe8, 0xe5, 0x71, 0xe3, 0x7a, 0xe9, 0xa7, 0x33, 0xd1,
+ 0x57, 0x85, 0xed, 0x1f, 0xb8, 0xc6, 0xed, 0x84, 0x6d, 0xd2, 0x7a, 0xc3,
+ 0x8b, 0x0f, 0xf5, 0xde, 0x9c, 0x9a, 0x17, 0x65, 0xce, 0x27, 0xe3, 0x37,
+ 0x33, 0xe9, 0xaf, 0xe5, 0xc9, 0x8f, 0xe9, 0xe4, 0xbc, 0x45, 0x93, 0x59,
+ 0xec, 0x81, 0x38, 0xc6, 0x72, 0xed, 0xb6, 0x17, 0xdc, 0x9e, 0xc0, 0x67,
+ 0xe3, 0x2c, 0xfb, 0xec, 0xb7, 0xe7, 0x2c, 0x99, 0x7f, 0x27, 0xf6, 0xdb,
+ 0x6b, 0x11, 0x7a, 0xd4, 0xb4, 0xfb, 0xf7, 0x68, 0x7b, 0x90, 0xca, 0xa1,
+ 0xce, 0x90, 0x3f, 0x0b, 0xdc, 0x3e, 0xdb, 0x43, 0xa9, 0x3c, 0x9e, 0x03,
+ 0x7b, 0x87, 0xbe, 0xf3, 0xf1, 0xb2, 0x9c, 0xd7, 0x7e, 0x7e, 0x36, 0xf6,
+ 0x0e, 0x98, 0x2c, 0x8e, 0x88, 0x1c, 0x3c, 0xe8, 0x66, 0x39, 0x9f, 0xe3,
+ 0x34, 0xeb, 0xa9, 0x57, 0x14, 0xa6, 0x74, 0xc9, 0x77, 0x4a, 0xc8, 0xf7,
+ 0xb8, 0x98, 0x8f, 0x54, 0xde, 0x60, 0xbc, 0xa6, 0xe3, 0x0c, 0x5d, 0x7c,
+ 0x1c, 0x50, 0x3a, 0x04, 0xd7, 0xee, 0xdd, 0x23, 0xf2, 0x13, 0x6d, 0x9c,
+ 0xc7, 0xe7, 0x38, 0x3d, 0xc3, 0xb8, 0xf3, 0xd9, 0x6c, 0x0b, 0xdd, 0xc8,
+ 0xb5, 0xd0, 0x9b, 0xb9, 0x5e, 0xba, 0x3e, 0xdf, 0x41, 0xb3, 0x8c, 0x99,
+ 0x67, 0xed, 0x80, 0x95, 0x66, 0xff, 0xe2, 0x6a, 0x54, 0xe4, 0x10, 0xb1,
+ 0xdc, 0xa1, 0x3d, 0xf0, 0x5f, 0x7c, 0x2f, 0xf3, 0x1c, 0x63, 0xef, 0x56,
+ 0xfa, 0x80, 0xdf, 0x99, 0xce, 0xea, 0x9c, 0x07, 0xc4, 0xe3, 0x07, 0xcb,
+ 0xf8, 0x75, 0x73, 0x1e, 0x31, 0x37, 0xe1, 0x91, 0x71, 0xa1, 0xeb, 0x33,
+ 0xf3, 0x7c, 0x7d, 0x1e, 0x71, 0x73, 0x4b, 0xc4, 0x24, 0xbe, 0x14, 0x40,
+ 0x7b, 0x9c, 0xb3, 0x65, 0xce, 0xa4, 0x18, 0x5b, 0x98, 0x8f, 0x41, 0xdb,
+ 0xb0, 0xa2, 0x43, 0x2b, 0x8f, 0x4f, 0xc6, 0x30, 0x52, 0xcb, 0xad, 0x74,
+ 0x26, 0xcf, 0x18, 0x24, 0xef, 0x67, 0x1f, 0x06, 0x6d, 0x7f, 0xe7, 0xa0,
+ 0xde, 0xd3, 0x76, 0x96, 0xfb, 0x9e, 0xce, 0x4b, 0x0c, 0x92, 0x5e, 0x6e,
+ 0xa7, 0x4c, 0xbe, 0x4d, 0x1d, 0xdf, 0x2d, 0xf2, 0xdd, 0xe5, 0xde, 0x12,
+ 0xb8, 0xb6, 0x91, 0x7e, 0x43, 0xae, 0x11, 0x6c, 0xaa, 0xf4, 0x4b, 0xa1,
+ 0x6b, 0xbc, 0xf3, 0x8c, 0xc6, 0xe8, 0x39, 0xb6, 0xb7, 0xfd, 0x97, 0x11,
+ 0x2b, 0xfe, 0x22, 0xf8, 0xa6, 0x00, 0x1e, 0xeb, 0xbf, 0x8c, 0x7d, 0x9f,
+ 0xfc, 0x22, 0xf7, 0x68, 0x22, 0x34, 0x2c, 0x6a, 0x46, 0xa4, 0x8c, 0x4e,
+ 0x89, 0xba, 0xec, 0xef, 0x08, 0xdd, 0x14, 0x71, 0x2c, 0x03, 0x78, 0x24,
+ 0x12, 0x26, 0x92, 0x39, 0x59, 0xa7, 0xec, 0xce, 0x9b, 0xdd, 0xe3, 0x43,
+ 0x14, 0xeb, 0x01, 0xdf, 0x4b, 0x99, 0x95, 0x7b, 0x22, 0x90, 0xd0, 0xf7,
+ 0xe6, 0x21, 0x5d, 0x63, 0xa0, 0x8f, 0xb5, 0xad, 0xd0, 0xc7, 0x6d, 0x35,
+ 0xd7, 0xcd, 0x9a, 0xeb, 0x1a, 0x7f, 0x63, 0xad, 0x8c, 0xed, 0x3c, 0xc9,
+ 0x3d, 0x98, 0x52, 0x0b, 0x92, 0xff, 0xcc, 0x43, 0x83, 0xe6, 0xfd, 0x0a,
+ 0x83, 0xa7, 0x56, 0x06, 0xc2, 0x9d, 0x46, 0x9b, 0x3f, 0x35, 0xf2, 0xaf,
+ 0xa5, 0x58, 0x12, 0xb8, 0xe8, 0xf5, 0x3d, 0x52, 0xc7, 0xa1, 0x5f, 0x4e,
+ 0x14, 0xd0, 0x6d, 0x6a, 0xa5, 0x8d, 0x56, 0xc5, 0x9e, 0x63, 0xc0, 0x18,
+ 0xb8, 0x1f, 0xcf, 0x71, 0xcc, 0x26, 0xc2, 0x3e, 0xf2, 0x90, 0xf1, 0xc3,
+ 0xe1, 0x6b, 0x3c, 0x9f, 0x89, 0x95, 0xff, 0x29, 0x4d, 0x8b, 0x7d, 0x7a,
+ 0xd0, 0x96, 0x31, 0xa4, 0xc0, 0xfc, 0x8c, 0x5f, 0xaa, 0xfc, 0xaa, 0x31,
+ 0xf4, 0xd3, 0xc1, 0x9a, 0x8a, 0x61, 0xbf, 0xc0, 0x32, 0x26, 0xd7, 0xca,
+ 0x13, 0x35, 0x6b, 0xe5, 0x53, 0x62, 0xad, 0x1c, 0xeb, 0xe4, 0x1b, 0xe5,
+ 0x2d, 0xea, 0x3c, 0x16, 0x8b, 0x66, 0xaf, 0x08, 0x7d, 0x13, 0x9d, 0xf0,
+ 0xcb, 0x3c, 0xeb, 0x04, 0xbb, 0x37, 0x86, 0xa8, 0x6d, 0xc0, 0x67, 0xcc,
+ 0x88, 0xdb, 0x91, 0xe1, 0x35, 0xc6, 0x14, 0x4b, 0xb9, 0x1d, 0x74, 0xbd,
+ 0xd0, 0xc4, 0x98, 0xef, 0x9f, 0x69, 0xad, 0x40, 0x8c, 0x0d, 0x3b, 0x28,
+ 0x13, 0x65, 0x5e, 0x1b, 0x0e, 0xf2, 0xbc, 0x32, 0xbe, 0x1d, 0x66, 0xf9,
+ 0xe3, 0x31, 0x2c, 0xe5, 0x4b, 0xef, 0xa7, 0xa3, 0x31, 0x2b, 0x3e, 0xda,
+ 0xc6, 0xfe, 0x8b, 0xc9, 0xff, 0x36, 0xff, 0x9f, 0x0b, 0x83, 0x36, 0x8b,
+ 0xcb, 0xb8, 0xce, 0xd8, 0x27, 0x5b, 0x7a, 0x7f, 0x86, 0xdb, 0xcc, 0x8c,
+ 0xc2, 0x0f, 0x82, 0xbf, 0x67, 0xf3, 0xbf, 0x6c, 0xb3, 0xc4, 0x7c, 0x97,
+ 0xbe, 0xe2, 0x84, 0x0d, 0xa1, 0xe3, 0xb1, 0x2f, 0xcd, 0x80, 0xfa, 0x8c,
+ 0x19, 0x33, 0xdc, 0x97, 0xeb, 0x84, 0x67, 0x58, 0x94, 0x8a, 0x1e, 0x62,
+ 0x39, 0xe8, 0xe0, 0x4f, 0xd4, 0x6a, 0xed, 0xa4, 0xcc, 0xc8, 0xa0, 0xaa,
+ 0xd5, 0xfa, 0x59, 0x83, 0x5a, 0x2d, 0xdc, 0xc7, 0x38, 0x60, 0xbe, 0x74,
+ 0x7b, 0x26, 0xea, 0x7e, 0x2f, 0x19, 0xa9, 0xe8, 0x2e, 0x81, 0x99, 0x96,
+ 0x96, 0x1f, 0xe6, 0x3e, 0xc4, 0xac, 0xd4, 0x28, 0xf7, 0x35, 0xef, 0xee,
+ 0x7f, 0xe9, 0xf6, 0x44, 0x14, 0xed, 0xfc, 0x35, 0xed, 0x62, 0x24, 0xda,
+ 0x2e, 0xa3, 0x7d, 0xe9, 0x97, 0xf1, 0xa8, 0x1e, 0xa7, 0xfb, 0x5e, 0x8c,
+ 0x07, 0xf2, 0xc5, 0x9f, 0x4b, 0xef, 0xd0, 0xf5, 0x1c, 0xfc, 0x71, 0x43,
+ 0xd5, 0x5f, 0x59, 0xe4, 0x2c, 0x31, 0x06, 0xbc, 0x72, 0xd0, 0xb7, 0x96,
+ 0xfb, 0x41, 0x29, 0x55, 0x95, 0xdb, 0x52, 0x1d, 0x73, 0x97, 0x3e, 0x58,
+ 0x2f, 0xd9, 0x97, 0x60, 0x43, 0x61, 0x3f, 0x9d, 0x92, 0xdf, 0x06, 0xde,
+ 0x83, 0x6f, 0xf4, 0x34, 0xeb, 0x2f, 0x99, 0x9f, 0xc4, 0xba, 0x94, 0x75,
+ 0x98, 0x94, 0x9f, 0x44, 0xd5, 0x4f, 0x3c, 0x48, 0x1e, 0xee, 0xaf, 0xe4,
+ 0x49, 0xba, 0xd6, 0xd8, 0x03, 0xae, 0x35, 0x76, 0xd3, 0x95, 0x27, 0x19,
+ 0x12, 0xf8, 0xac, 0x82, 0xa9, 0x42, 0x0a, 0x53, 0x01, 0x7b, 0x49, 0xdd,
+ 0xb6, 0x58, 0xd6, 0x6d, 0xbb, 0x37, 0xd1, 0x6d, 0x5e, 0xbe, 0xea, 0xaa,
+ 0xd2, 0x23, 0x91, 0x28, 0x6c, 0x0c, 0xf6, 0x59, 0xfa, 0xfb, 0xe2, 0x28,
+ 0xeb, 0x91, 0x28, 0xeb, 0x91, 0x11, 0xd6, 0x23, 0xc3, 0xac, 0x47, 0x6c,
+ 0xa6, 0x81, 0xc5, 0x63, 0xff, 0x98, 0xf5, 0x34, 0xec, 0xc7, 0x18, 0x3d,
+ 0x53, 0x84, 0x4e, 0x1e, 0x61, 0x0c, 0xf4, 0x31, 0xad, 0xcd, 0xb7, 0x33,
+ 0xff, 0x4a, 0xdc, 0x53, 0xed, 0xd7, 0x60, 0xdf, 0x18, 0xc4, 0x86, 0x7f,
+ 0x08, 0xbd, 0xf3, 0xb2, 0x43, 0x7d, 0xbe, 0xeb, 0x39, 0xd0, 0x79, 0x0d,
+ 0x7b, 0x6b, 0xbc, 0x08, 0xd9, 0xc6, 0xbe, 0xc7, 0xdf, 0x1e, 0x1a, 0xe3,
+ 0xbe, 0xf7, 0xf9, 0x32, 0x3c, 0x2f, 0x8f, 0x47, 0x1d, 0xb3, 0x8b, 0x65,
+ 0x60, 0x52, 0xc9, 0xc0, 0x64, 0x45, 0x06, 0x9c, 0x34, 0x8f, 0xa4, 0x73,
+ 0xa1, 0x83, 0x06, 0x8f, 0xc4, 0xf7, 0x76, 0xb2, 0xfc, 0x22, 0x67, 0xa2,
+ 0xb2, 0xff, 0x90, 0x9f, 0xa6, 0x43, 0x41, 0xb5, 0x6f, 0x91, 0xc5, 0x76,
+ 0xf3, 0x27, 0x94, 0xc9, 0xbd, 0xcb, 0xb8, 0x84, 0xe5, 0xd4, 0xc4, 0xf1,
+ 0x45, 0xc4, 0x45, 0xd9, 0x6f, 0x68, 0x15, 0x71, 0xa5, 0x45, 0xd1, 0x16,
+ 0xc7, 0x91, 0x61, 0xd6, 0x71, 0xd1, 0x55, 0x23, 0x32, 0x16, 0x33, 0x2e,
+ 0xf7, 0x62, 0x5f, 0xfa, 0x6f, 0x17, 0x1f, 0xeb, 0x95, 0xf5, 0xb9, 0x4f,
+ 0xed, 0x95, 0xfa, 0x84, 0x79, 0x34, 0x14, 0x13, 0xbe, 0x5b, 0xd3, 0x25,
+ 0x69, 0x3f, 0x17, 0x79, 0xbe, 0x97, 0xa2, 0xc3, 0x3c, 0xdf, 0x6d, 0xca,
+ 0x76, 0x3a, 0x7c, 0x5d, 0xd8, 0x65, 0xb6, 0xa1, 0xbd, 0xd8, 0xd3, 0xdf,
+ 0x8c, 0x47, 0x9f, 0xe2, 0x77, 0x62, 0x1f, 0xa1, 0x2f, 0xe3, 0x79, 0xcc,
+ 0xbd, 0xd0, 0x1f, 0x3f, 0x61, 0x1b, 0x8d, 0xf7, 0x82, 0x1f, 0xf9, 0x7b,
+ 0x61, 0x8c, 0x2e, 0x64, 0x75, 0x1f, 0xde, 0x23, 0xe3, 0x39, 0xf4, 0xc3,
+ 0x47, 0xbb, 0xed, 0xf7, 0x44, 0x4d, 0x88, 0xf1, 0x8d, 0xda, 0x3e, 0x7d,
+ 0x45, 0xf5, 0x09, 0x7b, 0x79, 0xb6, 0xf0, 0x18, 0x76, 0x13, 0xf6, 0x74,
+ 0x5a, 0x14, 0x7b, 0x6d, 0x36, 0x0b, 0x9f, 0x75, 0x51, 0xf8, 0x1e, 0x0f,
+ 0xef, 0xad, 0xec, 0xff, 0x79, 0x57, 0xcd, 0xb9, 0x75, 0xb6, 0x5b, 0x47,
+ 0x05, 0x46, 0xeb, 0xc7, 0x1e, 0xf4, 0xa2, 0x66, 0xf5, 0x4f, 0xc5, 0x35,
+ 0x63, 0x01, 0xd7, 0x3e, 0xa7, 0xae, 0x7d, 0x56, 0x60, 0x63, 0x63, 0xbc,
+ 0x95, 0xf5, 0xa2, 0xe0, 0x77, 0x9e, 0x67, 0x7b, 0x98, 0xf9, 0x3d, 0xbc,
+ 0xc4, 0xcf, 0x9d, 0x16, 0xf4, 0xd4, 0xf4, 0x00, 0x2d, 0x20, 0x03, 0x6d,
+ 0x8a, 0xff, 0x23, 0x56, 0xc2, 0xaf, 0xc7, 0xdd, 0x88, 0xce, 0x63, 0xb0,
+ 0xcf, 0x3c, 0x56, 0x8c, 0xc9, 0xf2, 0xc5, 0x0a, 0x61, 0x5f, 0x7a, 0x1e,
+ 0xbe, 0x0e, 0xea, 0x5e, 0x0e, 0x20, 0x9f, 0x8a, 0xfb, 0xb0, 0x87, 0x62,
+ 0x49, 0xf4, 0x0b, 0xed, 0x34, 0x0d, 0xfe, 0xa8, 0x86, 0x16, 0xee, 0xfb,
+ 0x3a, 0xd4, 0x7d, 0xad, 0x62, 0x2e, 0xc8, 0xc0, 0x7b, 0xf4, 0xbb, 0xf1,
+ 0x5e, 0xbc, 0x1f, 0xf7, 0xe1, 0x79, 0xf2, 0xb9, 0xdd, 0xac, 0xb7, 0xe3,
+ 0xa3, 0xf2, 0x59, 0xc6, 0x35, 0x79, 0xad, 0xdb, 0xf6, 0xee, 0xaf, 0x9c,
+ 0x3f, 0x9f, 0xda, 0x83, 0x08, 0xf3, 0xd7, 0x41, 0x05, 0x11, 0xfb, 0xc4,
+ 0xb5, 0x3e, 0x9f, 0xf0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xe3,
+ 0x33, 0xb9, 0x77, 0x84, 0xcf, 0x9e, 0x4e, 0xf6, 0xf9, 0x0a, 0x05, 0x8c,
+ 0xb7, 0xcf, 0x97, 0x60, 0x19, 0x98, 0xc8, 0xc5, 0x4b, 0x19, 0xa1, 0x6b,
+ 0x18, 0xeb, 0x76, 0x45, 0xcc, 0x69, 0xa3, 0x47, 0x60, 0x3e, 0x7e, 0x1f,
+ 0x7f, 0x67, 0x39, 0xcc, 0xb2, 0x1c, 0x66, 0x59, 0x0e, 0xb3, 0x2c, 0x87,
+ 0xec, 0xab, 0x7e, 0x2b, 0xcb, 0x72, 0xc8, 0xb6, 0xe4, 0x15, 0xb6, 0x25,
+ 0x52, 0x76, 0x63, 0x2a, 0xbe, 0xa9, 0x65, 0x17, 0xeb, 0x7f, 0x6e, 0x1f,
+ 0x47, 0xcb, 0x2a, 0xec, 0x37, 0xf9, 0x8e, 0x0f, 0x55, 0xcb, 0xec, 0x0d,
+ 0x96, 0xd9, 0xa6, 0xf1, 0x1e, 0xba, 0x95, 0xc7, 0x9c, 0x45, 0xac, 0x39,
+ 0xd6, 0xd5, 0x09, 0x3f, 0xb0, 0x56, 0x80, 0xe5, 0x09, 0x58, 0x33, 0xc2,
+ 0x74, 0xef, 0xa1, 0xdb, 0xac, 0xaf, 0x6f, 0xe5, 0x21, 0xc3, 0x07, 0xd4,
+ 0x71, 0x84, 0x65, 0x18, 0xf6, 0xcf, 0xf6, 0xdd, 0xc8, 0x19, 0x8c, 0xc9,
+ 0x02, 0x66, 0x8a, 0xa0, 0x4f, 0x05, 0x4e, 0xe3, 0x79, 0x5f, 0x65, 0xbd,
+ 0x8f, 0x18, 0x1e, 0xec, 0xc5, 0x19, 0x1f, 0xdb, 0x8b, 0xf0, 0x75, 0xd6,
+ 0xa7, 0xe7, 0xf3, 0x36, 0xcb, 0x7d, 0x17, 0xfd, 0x59, 0x1e, 0x76, 0x1a,
+ 0x34, 0xe2, 0xe3, 0x02, 0x89, 0xd8, 0x98, 0x31, 0x8e, 0xb1, 0x0f, 0x3a,
+ 0x86, 0xe0, 0x93, 0xdb, 0x98, 0x23, 0xa6, 0xfd, 0x3b, 0x7b, 0xb1, 0x9f,
+ 0x7e, 0xcc, 0x68, 0x56, 0xb1, 0x46, 0x7c, 0x47, 0xfb, 0x1e, 0x85, 0x4d,
+ 0x71, 0xdc, 0x68, 0x0d, 0x12, 0xbf, 0x43, 0x11, 0x65, 0x7a, 0xd4, 0xea,
+ 0xaf, 0x0b, 0x7c, 0xbf, 0xa0, 0xd7, 0x58, 0xdc, 0x8f, 0xfa, 0x72, 0xfa,
+ 0xaa, 0x7f, 0x7c, 0x8c, 0x9e, 0x2d, 0xa2, 0xdf, 0x97, 0x29, 0x13, 0x82,
+ 0x3e, 0x8a, 0x44, 0xd7, 0x49, 0xd2, 0xae, 0x95, 0x71, 0xe7, 0x63, 0xde,
+ 0x3a, 0xce, 0x8a, 0x0b, 0x9c, 0xdc, 0xc2, 0xfa, 0x05, 0xb4, 0xf9, 0x3e,
+ 0xf3, 0x5a, 0x14, 0x75, 0x69, 0x4a, 0xbf, 0xbd, 0xce, 0x3a, 0x07, 0x73,
+ 0x86, 0xe3, 0x8d, 0x75, 0xda, 0x9a, 0xd2, 0x69, 0xb6, 0x4b, 0xa7, 0xa5,
+ 0xcb, 0x3a, 0x8d, 0x79, 0x43, 0xe8, 0xb2, 0xa0, 0xa8, 0x8d, 0x4e, 0xab,
+ 0xef, 0xc0, 0x87, 0xbb, 0x85, 0xee, 0x62, 0xdd, 0x3f, 0x84, 0x3d, 0xc8,
+ 0x1c, 0xdf, 0x31, 0xa1, 0x43, 0x34, 0x7f, 0x3f, 0xbc, 0x4f, 0xca, 0x45,
+ 0xab, 0xd0, 0x07, 0xe9, 0x29, 0xe8, 0x2d, 0xaf, 0xf6, 0x0f, 0x72, 0x3b,
+ 0xb4, 0xb7, 0xc3, 0x2f, 0xb2, 0x3e, 0x5b, 0x8c, 0xc2, 0xa7, 0x6d, 0x53,
+ 0xbe, 0x0f, 0xf6, 0x14, 0xc3, 0x5a, 0x17, 0xc6, 0xaa, 0xf5, 0x59, 0xb7,
+ 0x8a, 0x6b, 0x20, 0x0e, 0x89, 0x39, 0x6f, 0x88, 0x11, 0x2c, 0x60, 0x04,
+ 0xbe, 0x27, 0xc0, 0xf4, 0x82, 0x7e, 0x61, 0x3b, 0xf0, 0x2e, 0xad, 0x09,
+ 0xd9, 0x78, 0x57, 0x60, 0x97, 0x0c, 0x5f, 0x9b, 0x19, 0x7d, 0x54, 0xf4,
+ 0x33, 0xb3, 0x5c, 0xd1, 0x8f, 0x73, 0xd9, 0xf7, 0x60, 0x37, 0x44, 0x5f,
+ 0x97, 0x86, 0xa4, 0x0e, 0x5c, 0x2c, 0x98, 0xd8, 0xe3, 0x0c, 0x7d, 0xe6,
+ 0xbe, 0xea, 0x71, 0xa2, 0x1f, 0x5a, 0x1f, 0x6c, 0x45, 0xf6, 0x18, 0xd7,
+ 0x76, 0x61, 0x8e, 0x1c, 0x17, 0x0f, 0x7d, 0x8f, 0xdf, 0x8f, 0x73, 0x9b,
+ 0x8f, 0xe7, 0x76, 0x79, 0x3c, 0x88, 0xed, 0xe1, 0x9e, 0x77, 0xe9, 0x96,
+ 0x1a, 0xcf, 0xad, 0xf2, 0x78, 0xbe, 0xab, 0xc6, 0x43, 0x69, 0x63, 0xbc,
+ 0x5b, 0xe1, 0xfe, 0x2d, 0x3f, 0xbb, 0x35, 0xce, 0x38, 0x26, 0xbd, 0x0c,
+ 0x3a, 0xdf, 0xa5, 0xf8, 0xc9, 0x1d, 0x47, 0x75, 0xf7, 0x35, 0x32, 0xbc,
+ 0xce, 0xfa, 0xf7, 0xb6, 0xc0, 0x31, 0x7d, 0x8c, 0x63, 0x70, 0x9e, 0x32,
+ 0xd0, 0xd3, 0xe9, 0x10, 0xf6, 0xe1, 0x1d, 0xe3, 0x71, 0xb3, 0x3f, 0x36,
+ 0xca, 0x9f, 0x22, 0xbe, 0x26, 0xe2, 0xbe, 0xea, 0xfe, 0xaf, 0xd3, 0xed,
+ 0x79, 0xe8, 0x72, 0xe0, 0x58, 0xb9, 0x57, 0xef, 0xed, 0x15, 0x19, 0xdf,
+ 0x4d, 0x78, 0xc6, 0x77, 0x11, 0xdb, 0x1d, 0x05, 0xce, 0x37, 0x11, 0x07,
+ 0x9e, 0x50, 0xbf, 0x5f, 0x92, 0x2e, 0xe2, 0x59, 0x5e, 0x7a, 0x69, 0xcc,
+ 0x95, 0x1f, 0x87, 0xbc, 0x14, 0x87, 0xf5, 0x8c, 0x6d, 0x36, 0x19, 0x47,
+ 0x65, 0x9c, 0xb9, 0xa8, 0xb1, 0xd3, 0x09, 0x9e, 0x33, 0x3b, 0x6a, 0x18,
+ 0x09, 0x11, 0x6b, 0x68, 0xb5, 0xdb, 0xa8, 0x85, 0xed, 0xe8, 0x59, 0xc2,
+ 0x3e, 0x70, 0x11, 0x0b, 0x6b, 0x00, 0x17, 0x98, 0x27, 0x33, 0xd1, 0x48,
+ 0xf8, 0x51, 0xe1, 0x97, 0xc2, 0xbe, 0x18, 0xa0, 0x13, 0xd3, 0x1a, 0x7d,
+ 0xe0, 0xef, 0xcb, 0xd8, 0x0b, 0x34, 0xca, 0xe3, 0x47, 0xfc, 0x78, 0xc0,
+ 0x7a, 0x93, 0xed, 0xd2, 0x05, 0x11, 0x97, 0x79, 0x9a, 0xd2, 0x2c, 0xa7,
+ 0xc7, 0x85, 0x9c, 0x1a, 0x7d, 0x2c, 0x45, 0x2c, 0x57, 0xc8, 0x43, 0x18,
+ 0x44, 0x0c, 0x50, 0xf9, 0x3a, 0x3c, 0xca, 0x15, 0xb5, 0x57, 0x42, 0x12,
+ 0xba, 0x63, 0xeb, 0x31, 0x89, 0xe4, 0xa7, 0x8e, 0xc5, 0xb8, 0x31, 0x59,
+ 0xa3, 0xda, 0x51, 0xf8, 0x69, 0x2a, 0x9e, 0x88, 0xfc, 0xf8, 0xf2, 0x6f,
+ 0xe9, 0xb8, 0xe3, 0x06, 0xe7, 0x44, 0x6e, 0xe8, 0xcb, 0x45, 0x69, 0x83,
+ 0xd3, 0xec, 0xd3, 0x67, 0x8e, 0xb8, 0x31, 0x49, 0x24, 0x37, 0x21, 0x62,
+ 0x39, 0xfb, 0x28, 0xbe, 0x30, 0x42, 0x0f, 0x64, 0xa1, 0xc3, 0x68, 0x3d,
+ 0x6e, 0xe3, 0x57, 0x72, 0x20, 0xe3, 0x23, 0x94, 0x28, 0x82, 0x46, 0x3e,
+ 0xc6, 0x4a, 0xcc, 0x7b, 0x39, 0xac, 0xef, 0xf3, 0xf7, 0x02, 0x7e, 0x1b,
+ 0xe6, 0x0f, 0x54, 0xbc, 0xbc, 0x97, 0x26, 0x16, 0xc8, 0x49, 0x45, 0xef,
+ 0x15, 0x7b, 0x79, 0xa7, 0xa2, 0x43, 0x2a, 0xb6, 0x13, 0xe6, 0xf3, 0x88,
+ 0x97, 0x59, 0x74, 0x7f, 0x36, 0xe2, 0xa4, 0x48, 0xc6, 0x2c, 0x88, 0xfb,
+ 0x60, 0xb0, 0xed, 0xdd, 0xcd, 0x3a, 0xe4, 0x94, 0x88, 0x5b, 0x30, 0x52,
+ 0x99, 0x47, 0x7b, 0xc4, 0x1c, 0xba, 0x08, 0x7e, 0x5a, 0x2a, 0xf7, 0xaa,
+ 0x6a, 0x5b, 0x22, 0x93, 0x79, 0xc1, 0xfc, 0x6d, 0xdb, 0x89, 0x1a, 0x95,
+ 0xfb, 0x11, 0xf3, 0x38, 0x25, 0x70, 0x64, 0x1f, 0xfb, 0x3c, 0xa2, 0x5d,
+ 0x69, 0x46, 0xc4, 0x2f, 0xf8, 0xb8, 0xf0, 0xc8, 0x7e, 0xa9, 0xdb, 0xe4,
+ 0x79, 0x19, 0xd7, 0xe0, 0x67, 0x16, 0xb8, 0x1f, 0x55, 0xf9, 0xf4, 0xbd,
+ 0x14, 0xdb, 0x46, 0x9c, 0x69, 0xea, 0x8e, 0xc6, 0x99, 0x98, 0xd6, 0xc5,
+ 0xcd, 0x6a, 0x1a, 0xb4, 0xff, 0xf7, 0x91, 0xb6, 0xe1, 0x4c, 0x2b, 0x53,
+ 0xfc, 0x16, 0x08, 0x30, 0x78, 0xa6, 0xf8, 0x3c, 0x7e, 0x03, 0xc7, 0x97,
+ 0x14, 0xd8, 0x38, 0xcc, 0xd8, 0x06, 0x18, 0x67, 0x40, 0xac, 0x8b, 0xc5,
+ 0x1e, 0x0a, 0xfb, 0x32, 0x2b, 0x3d, 0xe4, 0x47, 0x3c, 0xce, 0xd6, 0xb9,
+ 0x1c, 0xad, 0x22, 0xef, 0x5d, 0xae, 0x47, 0xc2, 0x3e, 0x43, 0x27, 0xae,
+ 0xb3, 0xdf, 0xf0, 0x90, 0xca, 0xb9, 0x41, 0xcd, 0xa6, 0xce, 0xb9, 0xd1,
+ 0x3a, 0x45, 0xf3, 0x9e, 0x5e, 0xeb, 0x70, 0xff, 0xde, 0x18, 0x64, 0xd7,
+ 0x8d, 0x29, 0x10, 0x9f, 0x12, 0x73, 0x74, 0x81, 0x48, 0xce, 0x71, 0x65,
+ 0x1d, 0xa3, 0x85, 0xe7, 0x09, 0xfe, 0x20, 0xe2, 0x7e, 0x8f, 0xf0, 0x27,
+ 0xd6, 0x23, 0x7e, 0xb4, 0x1f, 0x38, 0xaa, 0xd3, 0x66, 0x9e, 0x19, 0xc5,
+ 0x71, 0x0f, 0xfb, 0x67, 0x1a, 0xf7, 0xca, 0x58, 0x14, 0xfb, 0x6c, 0x6a,
+ 0xbe, 0x10, 0x87, 0xea, 0x97, 0x39, 0x4c, 0xd9, 0x08, 0x59, 0x5d, 0xa0,
+ 0xd3, 0xaf, 0x4a, 0x1e, 0x37, 0x5b, 0xbb, 0xd8, 0x4a, 0x5e, 0x13, 0x7e,
+ 0x0b, 0x0d, 0xfb, 0x8d, 0x1e, 0x04, 0xed, 0x79, 0x8e, 0xdc, 0x6b, 0x1b,
+ 0xcf, 0xef, 0xd5, 0xbf, 0xc3, 0x74, 0x67, 0xe6, 0x6d, 0x87, 0xc7, 0xbc,
+ 0x1d, 0xec, 0x95, 0x6b, 0x67, 0x7f, 0xa1, 0xda, 0x78, 0xe5, 0xb8, 0x3a,
+ 0x4f, 0x22, 0x0e, 0x55, 0xa9, 0xbf, 0x78, 0x5b, 0xe8, 0x95, 0xfa, 0x58,
+ 0x78, 0x98, 0xf5, 0xa9, 0x94, 0xe3, 0x53, 0x1e, 0x72, 0xdc, 0x35, 0x0e,
+ 0xdc, 0xf2, 0xc9, 0xe5, 0x78, 0xb2, 0xa1, 0x1c, 0x4f, 0xf6, 0xca, 0x58,
+ 0x6c, 0xbd, 0x1c, 0xbf, 0x81, 0xbe, 0x14, 0x37, 0xca, 0x81, 0x44, 0x4d,
+ 0xbb, 0x3b, 0x56, 0x02, 0x9a, 0xe9, 0x78, 0x09, 0xd6, 0x0d, 0xc1, 0x97,
+ 0x58, 0x7b, 0x99, 0x32, 0x12, 0xf3, 0xb5, 0x6b, 0xa9, 0x5b, 0xb9, 0x17,
+ 0xeb, 0x34, 0xb5, 0xf7, 0x02, 0xbb, 0x43, 0x36, 0x22, 0x61, 0x19, 0x0b,
+ 0xd0, 0xf4, 0xeb, 0xf5, 0x1d, 0xcb, 0x47, 0x9c, 0x02, 0x21, 0xd6, 0x1d,
+ 0xa2, 0x73, 0x58, 0x9f, 0x56, 0xb1, 0xe4, 0x93, 0x59, 0x49, 0x07, 0xf3,
+ 0x88, 0xe0, 0x0f, 0xe0, 0xdb, 0x70, 0xd2, 0x9f, 0xe4, 0x39, 0x96, 0x71,
+ 0xe4, 0xd4, 0x72, 0x58, 0xcd, 0x1b, 0xb7, 0xc5, 0xf3, 0xaa, 0xf6, 0x92,
+ 0xd7, 0x71, 0x07, 0xcc, 0x57, 0xe4, 0xeb, 0x95, 0xdc, 0x64, 0xd8, 0x86,
+ 0x12, 0xfd, 0x37, 0xdb, 0x3d, 0xff, 0x11, 0x53, 0xec, 0xe3, 0xf0, 0x46,
+ 0xf1, 0x08, 0xe3, 0x4d, 0xcc, 0x29, 0x62, 0x90, 0x3a, 0x46, 0xfc, 0xc4,
+ 0x41, 0x6a, 0x3f, 0xcc, 0x28, 0xc0, 0x20, 0x9b, 0xf1, 0xa5, 0x71, 0x04,
+ 0xb9, 0xe6, 0x16, 0xdf, 0x83, 0xfd, 0xa8, 0x06, 0xad, 0x04, 0xb5, 0x21,
+ 0x0e, 0x81, 0xfd, 0xb0, 0xad, 0x74, 0x95, 0x8c, 0x9d, 0x16, 0x32, 0x96,
+ 0x58, 0x39, 0xad, 0x64, 0xec, 0xb4, 0x8a, 0xc3, 0x9f, 0x56, 0x32, 0x76,
+ 0x5a, 0xc9, 0xd8, 0x69, 0x25, 0x63, 0xa7, 0x99, 0xcf, 0x07, 0x18, 0xdf,
+ 0x02, 0x8b, 0xe8, 0x38, 0x68, 0x3b, 0xa5, 0xf2, 0x38, 0x0f, 0xfb, 0x5c,
+ 0x2b, 0x67, 0xef, 0xf6, 0x49, 0x39, 0x63, 0x6c, 0x22, 0xeb, 0xc9, 0xf8,
+ 0x5d, 0x98, 0x83, 0x57, 0x98, 0xe6, 0x1f, 0xd3, 0x99, 0x79, 0xf4, 0xd5,
+ 0x47, 0x13, 0x62, 0x1f, 0xdc, 0x26, 0x8a, 0xbb, 0xb1, 0xb0, 0xc9, 0x63,
+ 0xcd, 0x4a, 0xdf, 0xcf, 0x31, 0x6c, 0xc1, 0x27, 0xde, 0x7a, 0x15, 0x7c,
+ 0x32, 0xae, 0xe6, 0xab, 0xd6, 0x2f, 0x6a, 0xa1, 0x64, 0x0e, 0x74, 0x45,
+ 0xfe, 0xa4, 0xc5, 0x73, 0x23, 0xe8, 0xe4, 0x98, 0x1e, 0x34, 0x38, 0xa9,
+ 0x68, 0xf0, 0xb8, 0x18, 0x23, 0xf2, 0x0f, 0x11, 0xcb, 0x6c, 0x4c, 0x87,
+ 0x74, 0x76, 0x80, 0x9f, 0xc3, 0xb2, 0x70, 0x24, 0xcc, 0x3a, 0x69, 0xeb,
+ 0x74, 0xa8, 0x8c, 0xbd, 0x91, 0xee, 0xd9, 0x6a, 0x5d, 0xce, 0xba, 0xcb,
+ 0x96, 0x84, 0x95, 0x1d, 0x91, 0xb8, 0x78, 0x87, 0x5d, 0xa2, 0x13, 0xd1,
+ 0x83, 0xfc, 0x3d, 0x92, 0x74, 0xe8, 0x30, 0x19, 0x9d, 0x25, 0xfa, 0x11,
+ 0xcb, 0x41, 0x2b, 0xcb, 0xc1, 0x09, 0xe5, 0x97, 0x9c, 0x28, 0xfb, 0x25,
+ 0x93, 0x07, 0x90, 0x97, 0x91, 0x12, 0xeb, 0x5e, 0x3b, 0xcb, 0xbf, 0xc3,
+ 0x02, 0x3d, 0xb6, 0x88, 0xfd, 0x28, 0x7a, 0x71, 0x6c, 0xd2, 0x55, 0xf6,
+ 0xab, 0x63, 0xbe, 0x07, 0x0f, 0x08, 0xec, 0xee, 0x7b, 0x00, 0xf7, 0x9c,
+ 0x90, 0x7a, 0xcf, 0x47, 0xfe, 0xc1, 0x77, 0x18, 0x4f, 0x94, 0xe8, 0x31,
+ 0x7e, 0x67, 0x26, 0x77, 0x88, 0x9f, 0xad, 0xf7, 0x96, 0xb0, 0x63, 0x86,
+ 0x6f, 0x27, 0xf9, 0x3b, 0x1b, 0xbd, 0x3b, 0x22, 0xf8, 0x91, 0xf1, 0xb4,
+ 0x31, 0x13, 0x7d, 0xaf, 0x34, 0x3d, 0x85, 0x18, 0x3b, 0xe4, 0x24, 0x62,
+ 0x5a, 0x3e, 0x2f, 0xf9, 0x90, 0x58, 0xa9, 0x92, 0x0b, 0x2b, 0xf3, 0xc2,
+ 0xff, 0x8b, 0xc7, 0x66, 0x12, 0xd6, 0x4e, 0xe4, 0xf3, 0x93, 0x04, 0x9f,
+ 0x00, 0xfb, 0x53, 0x58, 0x4c, 0x67, 0xfd, 0x2e, 0x5b, 0xf1, 0xc6, 0x67,
+ 0x90, 0xe7, 0x96, 0x5b, 0xa4, 0x8d, 0x6d, 0x0e, 0xe2, 0x75, 0x03, 0x0b,
+ 0x6b, 0x9d, 0x21, 0x51, 0x1b, 0xde, 0xc1, 0x18, 0x49, 0xe7, 0x3e, 0x0f,
+ 0xf2, 0xf3, 0x11, 0xc7, 0x0b, 0xd0, 0xc4, 0x25, 0xb4, 0x6b, 0xa6, 0xfe,
+ 0x85, 0xd2, 0xef, 0xf1, 0x75, 0xb1, 0x7e, 0x99, 0xa2, 0x56, 0xb5, 0x36,
+ 0xa1, 0xf7, 0xad, 0x08, 0xb3, 0xec, 0x55, 0x6a, 0x9f, 0xfb, 0xcb, 0x31,
+ 0x3d, 0x21, 0x13, 0x35, 0x31, 0xbd, 0xaf, 0x6e, 0x62, 0xaf, 0x36, 0x93,
+ 0x03, 0xe4, 0xd4, 0xb5, 0x90, 0x8a, 0x55, 0x5a, 0x19, 0xda, 0x6a, 0x4d,
+ 0xdf, 0x76, 0xef, 0xf1, 0xb5, 0x36, 0x8f, 0x93, 0xf3, 0xa6, 0x1d, 0x54,
+ 0xfc, 0xd7, 0x4c, 0x67, 0xf2, 0x41, 0xb6, 0xf9, 0xd0, 0xad, 0xa0, 0x97,
+ 0xbf, 0x17, 0xb5, 0x2e, 0x5f, 0x0a, 0x34, 0xd3, 0xf2, 0x32, 0x72, 0x2d,
+ 0xfe, 0xf1, 0x80, 0xcc, 0x25, 0x4e, 0x32, 0x5d, 0x0e, 0xb3, 0x7d, 0x34,
+ 0xd4, 0xda, 0x11, 0xce, 0x41, 0x97, 0x88, 0xdf, 0x21, 0x0a, 0xdc, 0x3b,
+ 0x14, 0x64, 0xbf, 0x40, 0xae, 0x3d, 0x1c, 0xe5, 0x67, 0x7f, 0x33, 0x9f,
+ 0x44, 0xbc, 0xcc, 0x3c, 0xce, 0xcf, 0x9f, 0x60, 0x3c, 0x11, 0xa3, 0x66,
+ 0x5a, 0x5a, 0x6e, 0x66, 0xbf, 0xa0, 0x99, 0xf1, 0xc4, 0x80, 0xd9, 0xef,
+ 0x13, 0xef, 0x12, 0x75, 0x35, 0x9f, 0x0f, 0x1c, 0x66, 0xbe, 0xc2, 0xbb,
+ 0xfe, 0x5d, 0xbd, 0xab, 0xf6, 0x1d, 0xff, 0x51, 0xc2, 0xf1, 0x71, 0x3f,
+ 0x39, 0x37, 0xf0, 0x1b, 0x5c, 0xf3, 0x63, 0x8c, 0x9d, 0x43, 0x94, 0x99,
+ 0x6f, 0xe2, 0x31, 0x8c, 0xb3, 0x1f, 0x11, 0xe5, 0xe3, 0xfb, 0xc8, 0x29,
+ 0x4e, 0xd1, 0x5f, 0x15, 0xdd, 0x31, 0xe1, 0xfb, 0xb8, 0xcf, 0xb2, 0xb6,
+ 0xbf, 0x85, 0xfb, 0xf5, 0x91, 0x5d, 0xab, 0x63, 0x82, 0xe4, 0xff, 0xeb,
+ 0x10, 0x35, 0x7f, 0x0d, 0xb1, 0x97, 0x12, 0xe5, 0xa2, 0xa8, 0x57, 0x90,
+ 0xf1, 0xe7, 0xab, 0x22, 0x87, 0x96, 0xef, 0xe7, 0x67, 0xce, 0xa1, 0xdd,
+ 0x55, 0x8b, 0xae, 0xdb, 0x92, 0xde, 0x3f, 0x08, 0x84, 0xc8, 0xff, 0x12,
+ 0x72, 0x9f, 0xc4, 0xfe, 0x1a, 0x8e, 0x7d, 0x88, 0xf5, 0xfb, 0xd7, 0x70,
+ 0x1f, 0x7f, 0xbe, 0x84, 0xe3, 0x20, 0x8f, 0x13, 0xf6, 0x1a, 0xf9, 0x2e,
+ 0xd0, 0x8b, 0x87, 0xc3, 0xa6, 0xe0, 0xbf, 0xfb, 0x98, 0xa7, 0x9a, 0x44,
+ 0xac, 0xb1, 0x0b, 0x6d, 0xed, 0xfd, 0xc0, 0x16, 0xce, 0xd0, 0x21, 0x1c,
+ 0xc7, 0x3a, 0xfd, 0x4c, 0x23, 0xc9, 0x43, 0x18, 0x4f, 0x15, 0x73, 0x07,
+ 0x8e, 0x0e, 0x11, 0xcf, 0x27, 0xf0, 0xc7, 0x2f, 0xf1, 0x1b, 0x91, 0x4e,
+ 0x3f, 0xbf, 0x23, 0xc1, 0xef, 0x98, 0xc8, 0xcb, 0x71, 0xcf, 0x15, 0xfd,
+ 0x24, 0xe3, 0x54, 0x5f, 0xe9, 0xd3, 0xbf, 0xd1, 0x48, 0x3d, 0x78, 0x76,
+ 0x59, 0x56, 0xf8, 0x7b, 0x3b, 0xdd, 0xca, 0xb7, 0xd1, 0x6d, 0xb5, 0xa6,
+ 0x75, 0x4b, 0xf8, 0x65, 0xac, 0xc3, 0x93, 0xed, 0xb4, 0xbe, 0xdc, 0x44,
+ 0xd4, 0x15, 0x14, 0x6b, 0xce, 0xb7, 0xf2, 0x05, 0x7e, 0xff, 0x97, 0xfb,
+ 0x64, 0x5c, 0xa7, 0xc2, 0x23, 0xb7, 0x3c, 0x78, 0xe4, 0x03, 0xc1, 0x23,
+ 0x5f, 0xec, 0xdb, 0x98, 0x47, 0x50, 0xf3, 0x0f, 0xde, 0x08, 0x52, 0xb3,
+ 0xe2, 0x8f, 0x17, 0x99, 0x3f, 0x9e, 0x65, 0xfe, 0x38, 0xd6, 0x80, 0x3f,
+ 0x8c, 0x1a, 0xfe, 0x38, 0x2e, 0xf8, 0xe3, 0x89, 0xbe, 0x8d, 0xf8, 0xe3,
+ 0x98, 0x7f, 0xa3, 0x58, 0x93, 0xaf, 0x35, 0xc0, 0xef, 0x9e, 0xb3, 0xf7,
+ 0x31, 0xaf, 0xdb, 0xb4, 0x34, 0x8f, 0xfa, 0x84, 0xd5, 0xa8, 0x41, 0x3f,
+ 0x13, 0x3e, 0xd9, 0x9a, 0xf0, 0xf9, 0xc7, 0x45, 0xcd, 0xc1, 0xa2, 0xe0,
+ 0x2f, 0xb6, 0xff, 0xe3, 0xa8, 0xab, 0xaa, 0x9d, 0x8b, 0x56, 0xba, 0x1e,
+ 0xc5, 0x5c, 0x58, 0x7a, 0x2e, 0x08, 0xeb, 0xbb, 0x6a, 0xef, 0xc8, 0x40,
+ 0x3c, 0x4b, 0xce, 0x07, 0xe0, 0xd1, 0x95, 0xb6, 0xc0, 0x44, 0xf6, 0x1b,
+ 0x7d, 0xc0, 0x7f, 0x99, 0x15, 0x72, 0x9d, 0x0f, 0xf0, 0xf9, 0x90, 0xf8,
+ 0x6d, 0x2b, 0xc8, 0xca, 0x87, 0xc8, 0x71, 0x64, 0x9e, 0xbc, 0x9e, 0xef,
+ 0xa5, 0x1b, 0xf9, 0x7d, 0xb4, 0x96, 0xef, 0xa3, 0x37, 0xc5, 0xbe, 0x1a,
+ 0xb2, 0x36, 0x72, 0x4d, 0xcc, 0x91, 0x41, 0x47, 0x43, 0xdc, 0x66, 0x79,
+ 0x1f, 0xad, 0x2e, 0x6b, 0xfe, 0x06, 0x6f, 0x83, 0x5f, 0x62, 0x9d, 0xb2,
+ 0x66, 0xae, 0x9e, 0x67, 0x26, 0xaa, 0x79, 0x46, 0xdc, 0x03, 0x5e, 0xc9,
+ 0xd4, 0xd5, 0xfa, 0x22, 0x5f, 0x11, 0xb9, 0x7a, 0x41, 0x6a, 0x42, 0xde,
+ 0xa2, 0x11, 0x19, 0x3e, 0xea, 0x07, 0x86, 0xce, 0xb1, 0xcd, 0xe5, 0x39,
+ 0xb3, 0x91, 0xe7, 0xd4, 0xc7, 0x78, 0xb8, 0x43, 0xe0, 0xdf, 0xb8, 0x1d,
+ 0x08, 0x4f, 0x50, 0xe9, 0x69, 0xc3, 0xc6, 0x5e, 0x8f, 0x49, 0x7e, 0x9e,
+ 0xa1, 0xe2, 0x4d, 0xbb, 0x5c, 0xfc, 0x57, 0x8b, 0x75, 0xb1, 0x96, 0xfc,
+ 0x10, 0xf7, 0x19, 0x76, 0xb8, 0xb2, 0x5e, 0x43, 0xe5, 0xf5, 0x9a, 0x56,
+ 0x1e, 0xb7, 0x94, 0xbd, 0x19, 0x9b, 0xdb, 0x15, 0xff, 0x6f, 0x40, 0x75,
+ 0xeb, 0x41, 0x73, 0x7f, 0x40, 0xf1, 0x25, 0xa0, 0x79, 0x67, 0x19, 0x86,
+ 0x43, 0x3d, 0xa0, 0x3c, 0x0a, 0x1a, 0x0f, 0x41, 0xcc, 0xf5, 0x1e, 0x5a,
+ 0x03, 0x12, 0x07, 0x8d, 0x89, 0x20, 0xe6, 0x7a, 0x0f, 0x41, 0xe7, 0x7a,
+ 0x0f, 0xad, 0xb1, 0x01, 0x97, 0xdb, 0xcd, 0x53, 0x80, 0xe1, 0x3e, 0x85,
+ 0x19, 0xba, 0xce, 0x51, 0x0d, 0x7a, 0x77, 0x52, 0x0c, 0x78, 0x4c, 0x5b,
+ 0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d, 0xb8, 0x9d, 0xe5,
+ 0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23, 0x80, 0x79, 0x4f,
+ 0x18, 0x9a, 0xf7, 0x60, 0x73, 0xc7, 0xfc, 0x0c, 0x90, 0x7b, 0x98, 0x6c,
+ 0xc0, 0x7d, 0x0b, 0x48, 0x79, 0x25, 0x83, 0x56, 0x5e, 0x01, 0xd3, 0x84,
+ 0x3a, 0x44, 0x7f, 0xd3, 0x7a, 0x0d, 0x79, 0xd8, 0x38, 0x60, 0x13, 0xd0,
+ 0xdc, 0xe6, 0x29, 0xa4, 0xcc, 0x3d, 0x03, 0xeb, 0x5b, 0xac, 0x6b, 0x1b,
+ 0x6d, 0xc0, 0x7b, 0xac, 0x17, 0x4d, 0x61, 0x61, 0x58, 0xd2, 0xc3, 0x00,
+ 0xac, 0x1f, 0x40, 0x69, 0x1d, 0x54, 0x47, 0xc0, 0xd3, 0xbb, 0x40, 0x13,
+ 0xd0, 0x7d, 0x4e, 0xc0, 0xb6, 0xa8, 0x73, 0xbf, 0x32, 0x78, 0xad, 0x6c,
+ 0x03, 0xf4, 0xfc, 0xaa, 0x45, 0x3d, 0xde, 0xf2, 0xa0, 0x7c, 0xe6, 0xa4,
+ 0xc2, 0x40, 0x46, 0x5e, 0x60, 0x83, 0xe6, 0x05, 0x70, 0x38, 0x01, 0xd3,
+ 0x3a, 0xb0, 0x8c, 0x5a, 0x93, 0x04, 0x34, 0x8f, 0x87, 0xc5, 0xa5, 0x1f,
+ 0x24, 0xc6, 0x00, 0x15, 0x63, 0x01, 0xf2, 0x65, 0x80, 0x6d, 0x4a, 0x90,
+ 0x5f, 0x41, 0x79, 0x01, 0x64, 0x36, 0xc8, 0xef, 0xa0, 0xb2, 0x13, 0x94,
+ 0x17, 0x81, 0xec, 0x25, 0x42, 0x50, 0x3f, 0x03, 0x69, 0x20, 0xbb, 0x79,
+ 0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x07, 0xc4,
+ 0x86, 0x31, 0x4c, 0x7d, 0x0c, 0x19, 0xf9, 0x06, 0x62, 0x06, 0x22, 0xdf,
+ 0xb0, 0x33, 0x1c, 0x10, 0x80, 0x85, 0xd5, 0xff, 0xff, 0xc7, 0x54, 0x58,
+ 0x80, 0xe9, 0x14, 0xb4, 0x8e, 0xf5, 0xf7, 0xff, 0x03, 0x22, 0x2c, 0x0c,
+ 0x2d, 0xf0, 0xf5, 0x88, 0x0b, 0xe5, 0x41, 0x65, 0xe8, 0x02, 0x20, 0xab,
+ 0x0d, 0xde, 0x26, 0x60, 0x01, 0xdf, 0x61, 0xbd, 0x80, 0xe1, 0x17, 0xb0,
+ 0xcc, 0xfa, 0xff, 0x7f, 0x29, 0x5c, 0x2d, 0x08, 0x00, 0x00, 0xff, 0x88,
+ 0x78, 0xb5, 0x98, 0x7e, 0x00, 0x00, 0x00 };
static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = {
- 0x08001b68, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4,
- 0x08001ab4, 0x08001ba4, 0x08001b28, 0x08001ba4, 0x08001a3c, 0x08001ba4,
- 0x08001ba4, 0x08001ba4, 0x08001a48, 0x00000000, 0x08002abc, 0x08002b0c,
- 0x08002b3c, 0x08002b6c, 0x08002b9c, 0x00000000, 0x0800604c, 0x0800604c,
- 0x0800604c, 0x0800604c, 0x0800604c, 0x08006078, 0x08006078, 0x080060b8,
- 0x080060c4, 0x080060c4, 0x0800604c, 0x00000000, 0x00000000 };
+ 0x08001b7c, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8,
+ 0x08001ac8, 0x08001bb8, 0x08001b3c, 0x08001bb8, 0x08001a50, 0x08001bb8,
+ 0x08001bb8, 0x08001bb8, 0x08001a5c, 0x00000000, 0x08002b74, 0x08002bc4,
+ 0x08002bf4, 0x08002c24, 0x08002c58, 0x00000000, 0x08006120, 0x08006120,
+ 0x08006120, 0x08006120, 0x08006120, 0x0800614c, 0x0800614c, 0x0800618c,
+ 0x08006198, 0x08006198, 0x08006120, 0x00000000, 0x00000000 };
static struct fw_info bnx2_com_fw_09 = {
+ /* Firmware version: 3.7.1 */
.ver_major = 0x3,
- .ver_minor = 0x4,
- .ver_fix = 0x3,
+ .ver_minor = 0x7,
+ .ver_fix = 0x1,
.start_addr = 0x080000b4,
.text_addr = 0x08000000,
- .text_len = 0x7dc0,
+ .text_len = 0x7e94,
.text_index = 0x0,
.gz_text = bnx2_COM_b09FwText,
.gz_text_len = sizeof(bnx2_COM_b09FwText),
- .data_addr = 0x08007e60,
+ .data_addr = 0x08007f40,
.data_len = 0x0,
.data_index = 0x0,
.data = bnx2_COM_b09FwData,
- .sbss_addr = 0x08007e60,
+ .sbss_addr = 0x08007f40,
.sbss_len = 0x60,
.sbss_index = 0x0,
- .bss_addr = 0x08007ec0,
+ .bss_addr = 0x08007fa0,
.bss_len = 0x88,
.bss_index = 0x0,
- .rodata_addr = 0x08007dc0,
+ .rodata_addr = 0x08007e98,
.rodata_len = 0x88,
.rodata_index = 0x0,
.rodata = bnx2_COM_b09FwRodata,
};
static u8 bnx2_CP_b09FwText[] = {
-/* 0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, */
- 0xbd, 0x7d,
- 0x0d, 0x74, 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x19, 0x49, 0x63, 0x59,
- 0x96, 0x9f, 0xe5, 0x89, 0x32, 0x51, 0x84, 0x3d, 0x23, 0x3d, 0xd9, 0x22,
- 0x12, 0xe1, 0xc5, 0x11, 0xac, 0xda, 0x2a, 0xe9, 0x30, 0x92, 0x3f, 0x12,
- 0x02, 0xab, 0x10, 0x43, 0xb3, 0x1c, 0x4a, 0xc5, 0x48, 0x4e, 0x02, 0x04,
- 0xea, 0x40, 0xe8, 0x86, 0xdd, 0xec, 0x66, 0x32, 0x92, 0x3f, 0x9a, 0x8e,
- 0x3d, 0x93, 0x44, 0x89, 0xbd, 0xdd, 0x9c, 0xad, 0x90, 0x14, 0x3b, 0x74,
- 0x07, 0x4f, 0xe2, 0x98, 0x96, 0x73, 0x0a, 0x8d, 0x50, 0x8c, 0x9b, 0xe6,
- 0xb0, 0xdd, 0xd0, 0xa6, 0x34, 0xdb, 0x86, 0x22, 0x8c, 0x81, 0xf4, 0x2c,
- 0xdd, 0x86, 0x42, 0x77, 0xd3, 0x36, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d,
- 0x9a, 0x91, 0x34, 0xce, 0x07, 0xdd, 0xad, 0xcf, 0x79, 0x7e, 0xf3, 0xee,
- 0xbb, 0x1f, 0xff, 0xfb, 0xbf, 0xff, 0xef, 0xfb, 0xbf, 0x4f, 0x97, 0x8b,
- 0x34, 0x8b, 0xfd, 0xb7, 0x01, 0xd7, 0xd5, 0xc9, 0xfd, 0xe3, 0x57, 0x5f,
- 0x39, 0x70, 0x25, 0x9f, 0xa3, 0x91, 0x68, 0x44, 0xde, 0xc4, 0xbf, 0xe4,
- 0x1b, 0xa8, 0x83, 0x0e, 0xdd, 0x70, 0x2c, 0x5e, 0x12, 0x53, 0x43, 0xde,
- 0xfe, 0x8c, 0x27, 0xb1, 0xc8, 0x50, 0xee, 0xce, 0x71, 0x4f, 0x24, 0x5d,
- 0xee, 0x4b, 0x0e, 0xcb, 0x3f, 0x05, 0xb9, 0x78, 0x54, 0x58, 0xfe, 0x96,
- 0xa1, 0x57, 0x7f, 0xeb, 0x2b, 0xff, 0x2a, 0xf5, 0xf2, 0x4c, 0x44, 0x62,
- 0xee, 0xd0, 0xed, 0xe2, 0x6e, 0x93, 0x58, 0xe7, 0x50, 0x72, 0xff, 0x23,
- 0xdb, 0x97, 0x44, 0x5a, 0xc3, 0xbe, 0x5e, 0x0a, 0xbe, 0xb2, 0x5d, 0x72,
- 0x1d, 0x43, 0x89, 0xb1, 0x86, 0x21, 0x57, 0x9e, 0xaa, 0xc8, 0xe8, 0x89,
- 0xc2, 0xcb, 0x41, 0x74, 0x28, 0x88, 0x4c, 0x0d, 0x38, 0x12, 0x19, 0x92,
- 0xb3, 0xe3, 0x03, 0xf7, 0x04, 0xca, 0xf3, 0xfc, 0x45, 0x69, 0x19, 0x3c,
- 0x37, 0x80, 0xf7, 0x65, 0x41, 0xdd, 0xbd, 0xd7, 0x9c, 0x28, 0xc4, 0x44,
- 0x0d, 0xf5, 0xbc, 0x90, 0x89, 0x5c, 0x25, 0x7c, 0x7f, 0x56, 0x7a, 0xfc,
- 0xa7, 0x05, 0xe5, 0xe5, 0x98, 0x64, 0x2a, 0xd2, 0x82, 0x32, 0xdc, 0x9b,
- 0x51, 0x27, 0xe5, 0x66, 0x22, 0xae, 0xe4, 0x2b, 0x3f, 0x5e, 0x67, 0xc6,
- 0x9d, 0xb3, 0xf7, 0xbf, 0x8e, 0x99, 0x3b, 0xc6, 0x2d, 0xc6, 0x64, 0x29,
- 0x92, 0x10, 0xc0, 0x82, 0x79, 0x25, 0x64, 0xb2, 0x98, 0x94, 0x4c, 0x81,
- 0xb0, 0x45, 0x25, 0xeb, 0x12, 0xae, 0x04, 0xda, 0xb7, 0x39, 0xf5, 0xeb,
- 0xb3, 0xee, 0x0b, 0xa8, 0x9b, 0x44, 0xbd, 0x4e, 0x79, 0x12, 0x75, 0x4f,
- 0x57, 0xe2, 0xf2, 0x44, 0xe5, 0x57, 0x25, 0x8d, 0xb6, 0x8f, 0x57, 0x30,
- 0x76, 0xb1, 0x51, 0x86, 0xa7, 0x9b, 0x25, 0x33, 0xdd, 0x9d, 0xc8, 0x4a,
- 0x10, 0x7c, 0xda, 0xff, 0xa8, 0x8c, 0xb5, 0xa1, 0x7e, 0x91, 0xef, 0x12,
- 0x2b, 0xde, 0x65, 0xfd, 0x3e, 0x37, 0xab, 0x1c, 0x49, 0xef, 0x4d, 0x25,
- 0xc6, 0x14, 0x9f, 0x1b, 0x24, 0xd3, 0x8f, 0xe7, 0xd1, 0xa8, 0x44, 0xbc,
- 0x20, 0xb8, 0xc3, 0xbf, 0x0c, 0x70, 0xa4, 0x92, 0x49, 0xc5, 0xb6, 0x6c,
- 0x97, 0xca, 0x25, 0x55, 0x5c, 0x72, 0x95, 0x2b, 0x25, 0xd9, 0x16, 0x04,
- 0xef, 0xf3, 0x3b, 0x51, 0x2e, 0x32, 0x5c, 0x90, 0xfd, 0x58, 0x23, 0xf4,
- 0x29, 0xbe, 0x1a, 0xda, 0x8c, 0x79, 0xf4, 0xb9, 0xc3, 0xd2, 0x28, 0xe9,
- 0xb8, 0xa4, 0xd5, 0x90, 0x24, 0xd5, 0xd0, 0x3a, 0x94, 0x39, 0xd2, 0xe0,
- 0x7d, 0xc1, 0xd2, 0xd2, 0x46, 0x3c, 0xcb, 0xa8, 0x1a, 0x6a, 0x5b, 0x55,
- 0x9e, 0x4a, 0x8a, 0x5a, 0x07, 0x5c, 0xa5, 0x7a, 0xd3, 0x8a, 0x65, 0xb8,
- 0xeb, 0xb2, 0x0f, 0x36, 0xad, 0x2d, 0xdb, 0xef, 0xac, 0x2c, 0xbb, 0xbd,
- 0x85, 0xb0, 0x8a, 0xe2, 0xef, 0xb8, 0x9e, 0x6b, 0x3a, 0xde, 0xed, 0x36,
- 0x60, 0x5e, 0xa3, 0x7e, 0xca, 0xdd, 0xa9, 0x9e, 0x0f, 0xa4, 0x9d, 0x30,
- 0xf3, 0x9d, 0xc2, 0x3b, 0x54, 0x1d, 0xf2, 0xb1, 0x6e, 0xae, 0x1c, 0xc2,
- 0xdc, 0xce, 0x4f, 0xa7, 0xdc, 0x2e, 0x85, 0xfb, 0x3c, 0x7f, 0x07, 0x41,
- 0xc6, 0xcf, 0xe9, 0x35, 0xfd, 0xee, 0x74, 0x02, 0xcf, 0x80, 0x3f, 0x9e,
- 0x4e, 0x6d, 0x92, 0xab, 0xed, 0xba, 0x7c, 0x13, 0x63, 0x76, 0xbb, 0x77,
- 0xa8, 0x6e, 0xd7, 0x57, 0x29, 0x77, 0x56, 0xce, 0xe0, 0x39, 0x08, 0x6e,
- 0xf4, 0x53, 0x89, 0x1c, 0xd6, 0xec, 0x42, 0x21, 0x2e, 0xdf, 0x2b, 0xa4,
- 0x40, 0xc5, 0xa9, 0xde, 0x39, 0xe9, 0xf3, 0xe7, 0x00, 0x6f, 0x1e, 0xd7,
- 0x41, 0xbe, 0x2b, 0xe3, 0x5d, 0x99, 0x6d, 0x83, 0xe0, 0x26, 0xff, 0x37,
- 0x83, 0xb1, 0x76, 0xc3, 0x17, 0x4f, 0x15, 0xb1, 0x9e, 0x80, 0xf9, 0x74,
- 0x11, 0xeb, 0x89, 0xb5, 0x7a, 0x5c, 0xaf, 0x7b, 0x2f, 0xd6, 0x9d, 0xb4,
- 0x41, 0xba, 0xd8, 0x61, 0x69, 0xf9, 0x03, 0xf6, 0x2e, 0x92, 0x29, 0x3a,
- 0x92, 0xf1, 0xff, 0x31, 0x48, 0x6b, 0x7e, 0x11, 0x67, 0xb8, 0x48, 0x5a,
- 0x6c, 0x00, 0xac, 0x7c, 0xcc, 0xda, 0x7a, 0x1b, 0x1d, 0xe0, 0x96, 0xeb,
- 0xc0, 0xf7, 0x31, 0xe5, 0x35, 0xd9, 0xf7, 0x21, 0x5f, 0xf0, 0xdf, 0x26,
- 0x47, 0xbc, 0x6a, 0xbd, 0x0c, 0x69, 0xb2, 0x92, 0x93, 0xec, 0x83, 0x81,
- 0x0c, 0xfb, 0xc0, 0x13, 0xfb, 0x74, 0x7d, 0xd1, 0x6d, 0x5d, 0xd6, 0xd1,
- 0x75, 0xf1, 0x6f, 0x7d, 0x23, 0xc6, 0x70, 0x46, 0x8a, 0xd5, 0xb6, 0x23,
- 0xc5, 0xfc, 0x66, 0x0b, 0x1f, 0x9e, 0x07, 0x9d, 0x4c, 0xe5, 0x82, 0x5d,
- 0xdb, 0x70, 0x1e, 0x57, 0xd7, 0xa1, 0x6d, 0x17, 0x7c, 0xe0, 0x4a, 0xb6,
- 0x30, 0x88, 0x71, 0xe3, 0xb8, 0x07, 0xc1, 0x94, 0x9f, 0x4e, 0x45, 0x65,
- 0x08, 0xcf, 0xa3, 0xe4, 0x3d, 0xe0, 0x4f, 0xa2, 0x99, 0xed, 0xbe, 0x8c,
- 0x80, 0xee, 0xf3, 0x95, 0xd7, 0x97, 0x22, 0x7a, 0x0e, 0xfe, 0x3f, 0x59,
- 0xdc, 0x70, 0x1c, 0x33, 0xe6, 0x54, 0xb1, 0x43, 0xf2, 0xd3, 0x9e, 0x4c,
- 0x16, 0x16, 0x7a, 0x95, 0xbc, 0x4c, 0x7e, 0xc7, 0xfa, 0xa5, 0x40, 0xbb,
- 0x43, 0x32, 0x5c, 0xf1, 0x24, 0x5f, 0xc0, 0xbd, 0xd8, 0x0d, 0xfa, 0x8d,
- 0x4a, 0x3a, 0x61, 0xd6, 0x26, 0x5f, 0x18, 0xc1, 0xfc, 0x80, 0x6b, 0x8f,
- 0xbf, 0x07, 0x2d, 0x4c, 0xae, 0x64, 0x06, 0x48, 0x3f, 0x6f, 0x06, 0x96,
- 0x98, 0xcc, 0xfa, 0xe0, 0x0b, 0xd7, 0xc0, 0x92, 0x2f, 0xc6, 0xa2, 0xc3,
- 0x98, 0xf7, 0x70, 0xf9, 0x57, 0xd0, 0x7f, 0x8b, 0xfe, 0x0d, 0x7e, 0xb2,
- 0x65, 0x51, 0xdc, 0xe3, 0xb8, 0x13, 0xe6, 0x90, 0x56, 0x21, 0x1b, 0xa6,
- 0x3b, 0x65, 0x12, 0xb4, 0x3a, 0x2c, 0xf8, 0x3d, 0xcf, 0xb9, 0x10, 0xae,
- 0x0e, 0xfd, 0x7b, 0x72, 0x7a, 0x8b, 0x7e, 0xce, 0x8e, 0x76, 0x48, 0x6e,
- 0x3e, 0x9c, 0x33, 0xe5, 0x05, 0x65, 0x44, 0xea, 0xb0, 0x08, 0x65, 0x46,
- 0x10, 0x3c, 0xe8, 0x53, 0x6e, 0x04, 0xc1, 0x69, 0x9f, 0x72, 0xe4, 0x0c,
- 0xe4, 0x03, 0x65, 0x07, 0x79, 0xd9, 0x53, 0x5c, 0xab, 0x4c, 0xa1, 0x17,
- 0xeb, 0xd1, 0x28, 0xd9, 0xfe, 0xe3, 0x84, 0x15, 0x72, 0xe7, 0xa5, 0x4f,
- 0x66, 0xbc, 0x5c, 0x22, 0xa2, 0xf1, 0x04, 0xca, 0x82, 0x3c, 0x4c, 0xeb,
- 0x99, 0x75, 0x49, 0xbe, 0xbf, 0x64, 0xeb, 0xc8, 0xaf, 0xb2, 0x4e, 0x74,
- 0x4d, 0x9d, 0x7f, 0xa7, 0x0c, 0x5f, 0xf6, 0x62, 0xdd, 0x3a, 0x14, 0xf1,
- 0xd8, 0xb5, 0x8d, 0xcf, 0x12, 0x6b, 0x18, 0xfa, 0x3d, 0xbc, 0x7b, 0xee,
- 0x53, 0x8f, 0x7a, 0xf5, 0xde, 0xfd, 0x28, 0xba, 0xf6, 0xdd, 0x94, 0x44,
- 0xbd, 0x54, 0xef, 0x8d, 0xea, 0x4f, 0x1a, 0xa4, 0x35, 0x08, 0x1e, 0xf5,
- 0xc3, 0xf2, 0xc6, 0x86, 0xb5, 0x63, 0x5c, 0x55, 0xa7, 0xec, 0x68, 0x9d,
- 0xb2, 0xcf, 0xd7, 0x29, 0x7b, 0x7b, 0xe3, 0xda, 0xb2, 0xdb, 0xeb, 0x94,
- 0xcd, 0xd6, 0x29, 0xfb, 0x69, 0x9d, 0x32, 0x69, 0x5a, 0x5b, 0x16, 0xa9,
- 0x53, 0xd6, 0x57, 0xa7, 0x2c, 0x0a, 0xbe, 0xdb, 0x26, 0xf9, 0xf8, 0xbd,
- 0x9c, 0xbb, 0xc5, 0x4d, 0x29, 0xb2, 0x16, 0x37, 0x0d, 0xa8, 0xd7, 0xb9,
- 0xaa, 0xde, 0x17, 0xeb, 0xd4, 0x6b, 0x44, 0xbd, 0xb6, 0x55, 0xf5, 0x76,
- 0xd4, 0xc1, 0x75, 0x13, 0xea, 0xc5, 0x56, 0xd5, 0x7b, 0xb0, 0x4e, 0x3d,
- 0x96, 0x7f, 0xc6, 0x8e, 0xd3, 0x07, 0x2d, 0xf4, 0x5a, 0xeb, 0xd5, 0x28,
- 0xd2, 0xce, 0xf2, 0x5e, 0xe8, 0x90, 0x0e, 0x65, 0xe4, 0x02, 0x65, 0x10,
- 0xcb, 0x3a, 0x41, 0xe7, 0x71, 0xd0, 0x1d, 0xe5, 0x28, 0xf8, 0x8c, 0x73,
- 0xa9, 0x6c, 0x90, 0xb1, 0x78, 0x9f, 0x7b, 0xb5, 0x6a, 0x01, 0x8d, 0xa5,
- 0xdc, 0xa4, 0x22, 0xff, 0x49, 0x2e, 0x32, 0xe4, 0xe5, 0x86, 0x45, 0xc5,
- 0x95, 0x04, 0x32, 0xe2, 0xab, 0x36, 0x25, 0xf7, 0x80, 0xbf, 0xd2, 0xd0,
- 0x59, 0x37, 0x06, 0xc3, 0x9a, 0xb7, 0x4c, 0xdd, 0x8b, 0xcb, 0x54, 0x5f,
- 0x0e, 0x52, 0x16, 0x0e, 0x8d, 0x7e, 0x2a, 0xe3, 0x2d, 0x0c, 0x36, 0x82,
- 0x66, 0xcf, 0xa3, 0xcd, 0x6e, 0xb4, 0xdc, 0x57, 0x8e, 0xca, 0x48, 0x79,
- 0x00, 0xbc, 0xe0, 0xc8, 0x39, 0x6f, 0xa3, 0x9c, 0xf3, 0x51, 0xb7, 0x12,
- 0x91, 0xc5, 0xb8, 0x23, 0x8b, 0x78, 0xce, 0xf8, 0x78, 0x57, 0x09, 0x79,
- 0x6b, 0x40, 0x0e, 0x14, 0x7d, 0x39, 0x5c, 0xbc, 0x41, 0x85, 0x7a, 0x6d,
- 0xa7, 0xbf, 0x5e, 0x1e, 0x73, 0x4d, 0xdf, 0xbb, 0xbd, 0x05, 0x68, 0xd4,
- 0xa8, 0x9c, 0xf7, 0x52, 0x89, 0x45, 0xcd, 0x13, 0xff, 0x27, 0x18, 0x41,
- 0x3f, 0xb3, 0x5e, 0xca, 0xfd, 0x03, 0x3c, 0x8f, 0x95, 0x69, 0xcb, 0x54,
- 0xfb, 0x9a, 0x44, 0x5f, 0x87, 0x8a, 0x1b, 0xe4, 0x56, 0xdb, 0x7e, 0x97,
- 0xb7, 0xd0, 0x0b, 0x9e, 0x73, 0x4f, 0x50, 0x86, 0x14, 0x00, 0xd7, 0x5e,
- 0xf0, 0x36, 0xda, 0x7e, 0x4d, 0xcb, 0x33, 0xd8, 0x3e, 0x85, 0x8d, 0x90,
- 0xcf, 0x7f, 0x17, 0xdc, 0x1a, 0x67, 0x7d, 0x96, 0x51, 0xe7, 0x48, 0x49,
- 0x0d, 0x41, 0x26, 0x0c, 0x50, 0x66, 0x26, 0x21, 0x2f, 0x21, 0x7b, 0x8a,
- 0x3f, 0x0d, 0xd2, 0xd1, 0x5a, 0x39, 0x28, 0xb9, 0x6a, 0x1d, 0x96, 0x25,
- 0x8d, 0x5c, 0x2d, 0x2e, 0x2d, 0xcb, 0x8a, 0x1c, 0xe4, 0xcb, 0x53, 0x15,
- 0xca, 0x85, 0x0f, 0x82, 0x47, 0x3b, 0x65, 0xa4, 0x90, 0xca, 0xa5, 0x65,
- 0x1b, 0xd6, 0xef, 0xd7, 0xb1, 0xa6, 0x51, 0x5c, 0x0f, 0xad, 0x97, 0x56,
- 0x1f, 0xba, 0x9b, 0xe5, 0xe8, 0xb4, 0x9d, 0x36, 0xd2, 0x6f, 0x03, 0x0f,
- 0x93, 0x5c, 0xf3, 0x44, 0x26, 0xe2, 0x8c, 0xd2, 0x5e, 0x19, 0x85, 0x7c,
- 0xcc, 0x96, 0xd9, 0x37, 0xe1, 0x4d, 0xd8, 0xdf, 0xb0, 0x9b, 0x0a, 0x9d,
- 0xf6, 0x77, 0x0b, 0x7e, 0x27, 0xed, 0x6f, 0xc8, 0xd4, 0x82, 0x67, 0x7f,
- 0xc7, 0xb5, 0x1c, 0x32, 0xbf, 0x13, 0xf8, 0xdd, 0xaf, 0x7f, 0x4f, 0x15,
- 0x77, 0xed, 0x52, 0xde, 0x95, 0x92, 0x9d, 0xef, 0x94, 0x03, 0x85, 0x77,
- 0x58, 0xd9, 0x82, 0x4b, 0xbe, 0xe4, 0x98, 0x79, 0x26, 0xf4, 0xba, 0xe7,
- 0x8b, 0x39, 0x67, 0x94, 0xf0, 0xe3, 0xf7, 0x70, 0xa1, 0xcf, 0xdd, 0x24,
- 0xa4, 0x81, 0x29, 0x67, 0xb8, 0xe2, 0xa4, 0x23, 0x43, 0x3d, 0x89, 0x49,
- 0x39, 0x8c, 0xdf, 0xe2, 0x46, 0x86, 0xbe, 0x84, 0xbb, 0xc1, 0xc1, 0x57,
- 0xb6, 0x43, 0xb6, 0x16, 0x29, 0x2f, 0x3d, 0xcc, 0x3d, 0x29, 0x67, 0x56,
- 0xd8, 0x58, 0xc4, 0x85, 0x92, 0xec, 0x74, 0xea, 0x78, 0x4e, 0x52, 0xb9,
- 0x19, 0x30, 0xc4, 0x8d, 0x7e, 0x54, 0xde, 0xe7, 0x83, 0x76, 0xaf, 0x74,
- 0x64, 0xd7, 0x95, 0x51, 0xd8, 0x44, 0xde, 0xcc, 0x2e, 0xc8, 0x58, 0xc8,
- 0xbe, 0x08, 0xe9, 0x41, 0x9d, 0x92, 0xb1, 0xe8, 0x10, 0xb0, 0x7d, 0xaa,
- 0x7f, 0x64, 0xb2, 0x90, 0xbd, 0x5d, 0x0d, 0xed, 0xff, 0x6c, 0x66, 0xe0,
- 0xad, 0x92, 0xdd, 0xab, 0x80, 0xa3, 0xf6, 0x31, 0xc8, 0x4c, 0xcc, 0x2b,
- 0x08, 0x40, 0xcf, 0x90, 0xe7, 0x37, 0xdd, 0x14, 0x19, 0x6a, 0x90, 0xe1,
- 0xbd, 0xed, 0x68, 0xc3, 0x77, 0xc4, 0xd7, 0x79, 0xe0, 0x33, 0x95, 0x1c,
- 0x11, 0xb9, 0x7b, 0x6a, 0x60, 0xc9, 0x99, 0x2c, 0x7d, 0x10, 0x3c, 0x79,
- 0x15, 0xda, 0x3f, 0x80, 0xf6, 0x2f, 0x3b, 0xf9, 0xe9, 0x57, 0x9c, 0xc9,
- 0xe9, 0xbf, 0x75, 0xa6, 0xa6, 0xb7, 0x6c, 0xd9, 0x39, 0xb8, 0x65, 0xcb,
- 0xf8, 0x60, 0xd4, 0xea, 0x97, 0x2d, 0x5b, 0xa6, 0x06, 0x07, 0x81, 0x83,
- 0x3e, 0x77, 0x44, 0x3c, 0x77, 0x97, 0x80, 0x7f, 0xe2, 0x1c, 0x93, 0xfa,
- 0x27, 0x85, 0xf7, 0x6c, 0xef, 0xe9, 0xf7, 0xc3, 0xd2, 0x97, 0x68, 0x13,
- 0x8e, 0x1f, 0xb1, 0x75, 0xda, 0x01, 0xfb, 0x03, 0x76, 0x7d, 0x0b, 0xaa,
- 0xc1, 0x63, 0x39, 0xe7, 0xc2, 0x72, 0xae, 0xed, 0x8f, 0xac, 0x2d, 0xbb,
- 0x11, 0xe5, 0x7c, 0x26, 0xce, 0x88, 0x17, 0xda, 0x22, 0x0d, 0xda, 0x76,
- 0xcc, 0x16, 0x48, 0x33, 0x51, 0x99, 0x28, 0xb4, 0xa1, 0x0d, 0xe8, 0xe2,
- 0x94, 0xbd, 0x8e, 0x02, 0xb6, 0xbd, 0xe8, 0xeb, 0xe8, 0x21, 0xb4, 0xa3,
- 0xcc, 0x48, 0xf5, 0x8a, 0xfa, 0x04, 0xea, 0xf4, 0xb9, 0x9b, 0x85, 0x36,
- 0xc7, 0x71, 0xc9, 0x16, 0xc9, 0xdf, 0x3d, 0x80, 0x27, 0x26, 0xc9, 0x76,
- 0x3c, 0x57, 0x0e, 0xc0, 0x0e, 0x69, 0xb0, 0x3a, 0x33, 0x94, 0x17, 0xfc,
- 0x77, 0x87, 0x12, 0xef, 0x80, 0x8c, 0xcd, 0x5d, 0x8e, 0x7a, 0x0e, 0xf0,
- 0x42, 0x3b, 0x05, 0x36, 0xcb, 0x5c, 0x5a, 0x32, 0xdb, 0xee, 0xc5, 0xdd,
- 0xc5, 0x73, 0x1e, 0xf7, 0xb7, 0xe0, 0x3e, 0x89, 0x7b, 0x08, 0x27, 0xf0,
- 0xea, 0x47, 0xac, 0xce, 0xba, 0x06, 0x63, 0xff, 0x6b, 0xc9, 0x94, 0x12,
- 0xb4, 0x39, 0x36, 0x66, 0xbc, 0xb4, 0xab, 0x44, 0x6d, 0x56, 0x32, 0x85,
- 0xfa, 0xf0, 0x09, 0xbc, 0x83, 0x32, 0x7e, 0x12, 0xbf, 0x1f, 0xa4, 0x4d,
- 0x3c, 0x25, 0xe3, 0x73, 0x1c, 0xa7, 0x00, 0x98, 0x4a, 0x92, 0x3d, 0xf9,
- 0x00, 0xae, 0x69, 0x5c, 0x0f, 0xe3, 0xe2, 0xdc, 0xd8, 0xff, 0xe2, 0x26,
- 0x05, 0x5c, 0xf3, 0x39, 0x4b, 0x3a, 0xae, 0xe0, 0x37, 0x69, 0xb8, 0x42,
- 0xdb, 0x06, 0xf4, 0x5b, 0x09, 0xe9, 0xda, 0xb7, 0xbf, 0x13, 0x9a, 0xaf,
- 0x73, 0x6d, 0xa0, 0x99, 0xca, 0xa0, 0x96, 0x39, 0x19, 0x0f, 0xf7, 0x0a,
- 0x6c, 0x8f, 0x36, 0xce, 0xd1, 0xb3, 0x65, 0x9e, 0x2e, 0x4b, 0xea, 0xb2,
- 0x7e, 0x5b, 0x86, 0x7b, 0xa5, 0x41, 0xc6, 0xda, 0x01, 0x31, 0xe5, 0xb3,
- 0x84, 0xf8, 0xa4, 0x0c, 0x00, 0xfd, 0xc2, 0x66, 0x38, 0x73, 0x51, 0xf9,
- 0xb7, 0xa4, 0x6d, 0xb1, 0xc7, 0x2b, 0xa4, 0x63, 0xd2, 0x76, 0x10, 0xdc,
- 0xef, 0x37, 0xa1, 0x7f, 0xf2, 0xbc, 0x48, 0xc3, 0xd1, 0xa8, 0xcc, 0xb8,
- 0xa4, 0x85, 0x77, 0xb4, 0x90, 0x06, 0x1a, 0x3d, 0xd2, 0x70, 0x2d, 0x7f,
- 0x71, 0x0d, 0xd9, 0x5f, 0x0e, 0xf6, 0x1d, 0xed, 0xbc, 0x1e, 0xd8, 0xce,
- 0x1c, 0xe3, 0x30, 0x9f, 0x5d, 0x05, 0x9e, 0xca, 0x2c, 0xf3, 0x94, 0xc8,
- 0x6c, 0x81, 0xb8, 0x09, 0xed, 0x3f, 0xae, 0x33, 0xf1, 0xf3, 0x38, 0xe6,
- 0xcc, 0xfb, 0x19, 0x8b, 0xa7, 0x2f, 0x59, 0x3c, 0x7d, 0xd9, 0xde, 0x5d,
- 0x27, 0xab, 0x6d, 0xc1, 0x05, 0x3c, 0x73, 0x7d, 0xa2, 0x1a, 0x67, 0xd9,
- 0xc2, 0x0c, 0xee, 0xa8, 0x5b, 0x7c, 0x5c, 0xc6, 0xb5, 0x9d, 0x16, 0x91,
- 0x77, 0x69, 0xd9, 0x06, 0x21, 0xdd, 0x5c, 0x00, 0xcc, 0x0d, 0x92, 0x8b,
- 0x47, 0xf4, 0xda, 0x47, 0xbd, 0x03, 0x51, 0x43, 0xab, 0xc4, 0xc9, 0x0a,
- 0x5f, 0xaa, 0x06, 0xa6, 0xb8, 0x95, 0x73, 0x84, 0x8b, 0xb4, 0xfb, 0x88,
- 0x86, 0xeb, 0x16, 0xc8, 0xbb, 0x9c, 0xa8, 0xf6, 0x46, 0xb9, 0x0c, 0xb4,
- 0xa0, 0xe2, 0xd0, 0x5c, 0xc1, 0xd3, 0xb0, 0x9b, 0xb2, 0x73, 0xb4, 0xa1,
- 0xbb, 0xe8, 0xb7, 0xc4, 0xb2, 0xfd, 0xad, 0xa4, 0x23, 0xa5, 0x60, 0x7f,
- 0xe1, 0x59, 0x65, 0xfb, 0x35, 0x9d, 0x3a, 0xca, 0x8b, 0x6b, 0x3b, 0x19,
- 0xbc, 0x12, 0xb1, 0xbe, 0x73, 0x54, 0x79, 0x9b, 0x57, 0x97, 0x25, 0xa9,
- 0x87, 0xd1, 0x2e, 0x99, 0xed, 0x6f, 0x27, 0x8f, 0xb9, 0xca, 0x03, 0x2e,
- 0x3d, 0xed, 0x1b, 0xe5, 0xd4, 0xc0, 0xc6, 0x55, 0xf5, 0xf5, 0xdd, 0xb1,
- 0xcf, 0x51, 0x7b, 0x77, 0xed, 0x3d, 0x69, 0xef, 0xb9, 0xe8, 0x00, 0xef,
- 0x8e, 0x44, 0x87, 0x78, 0xc7, 0x1a, 0x0e, 0xb1, 0x0f, 0xcd, 0x57, 0x56,
- 0xce, 0xf4, 0xb8, 0x79, 0x21, 0x5f, 0xfd, 0xa9, 0xdc, 0x32, 0x67, 0xe4,
- 0xef, 0x2e, 0xc8, 0x20, 0xf8, 0x6f, 0xee, 0xa2, 0x00, 0xfe, 0xbd, 0x65,
- 0xb9, 0xa5, 0x42, 0xbc, 0xfd, 0x06, 0xf0, 0xb7, 0x35, 0x4a, 0xde, 0x74,
- 0x85, 0x72, 0xf7, 0x4e, 0xd1, 0xf6, 0x69, 0x81, 0x38, 0x3f, 0x2b, 0x5c,
- 0x9b, 0x7c, 0xe1, 0x19, 0xbd, 0x36, 0x07, 0x0b, 0x8b, 0xc0, 0xcf, 0xd7,
- 0x41, 0xf7, 0x41, 0xb0, 0xe8, 0xe7, 0x41, 0x39, 0x7f, 0x84, 0xdf, 0xe8,
- 0xbb, 0xf0, 0x1c, 0xde, 0xb7, 0x4a, 0xbe, 0x44, 0x9e, 0x8b, 0x5a, 0x1e,
- 0x3e, 0x05, 0x7e, 0xba, 0x0c, 0xfd, 0xa2, 0x6c, 0x80, 0xbf, 0xff, 0x11,
- 0xef, 0x70, 0x9f, 0xc3, 0x22, 0xb6, 0xd3, 0xd6, 0xe1, 0xd8, 0x5c, 0x3b,
- 0xae, 0x59, 0x5c, 0xfb, 0xad, 0x8f, 0x2f, 0xaf, 0x1b, 0xd7, 0x2b, 0xd5,
- 0x9b, 0x93, 0x70, 0xcd, 0x44, 0x1e, 0x2f, 0xb0, 0x3e, 0xe9, 0xff, 0x1f,
- 0x62, 0x46, 0x17, 0xfc, 0xc9, 0x3a, 0x73, 0x5f, 0xdd, 0x96, 0x6b, 0x5e,
- 0x4b, 0x83, 0xf4, 0x6f, 0x52, 0x83, 0x39, 0xc8, 0x9d, 0xa8, 0xd7, 0x2a,
- 0x23, 0xda, 0x27, 0x22, 0x4d, 0x90, 0x06, 0x6e, 0x56, 0x86, 0x36, 0x3f,
- 0xa4, 0x0c, 0x6d, 0x3e, 0x03, 0x5a, 0xc4, 0x55, 0x5c, 0x72, 0x0c, 0x6d,
- 0x7e, 0x1d, 0x77, 0x5c, 0xc5, 0x0b, 0x4e, 0xc8, 0xc7, 0xc3, 0xf0, 0xf9,
- 0x76, 0x15, 0xa2, 0xce, 0x78, 0x05, 0xf4, 0x5b, 0x8c, 0xa1, 0x7c, 0x81,
- 0x38, 0xc7, 0xfc, 0x39, 0xce, 0x56, 0xdb, 0xff, 0xe3, 0x32, 0x51, 0x0c,
- 0xb4, 0x5d, 0x95, 0x9d, 0xbb, 0x17, 0xf7, 0xf5, 0x5a, 0xce, 0x28, 0x2f,
- 0xad, 0x8c, 0xbc, 0x7a, 0x17, 0xee, 0xdd, 0x89, 0x83, 0xd2, 0xed, 0x46,
- 0xe4, 0x39, 0xf4, 0xf5, 0x43, 0x67, 0xa2, 0xf2, 0x32, 0xae, 0x9f, 0xe0,
- 0x7a, 0x15, 0xd7, 0x2b, 0xe8, 0xf7, 0x45, 0x94, 0xaf, 0x97, 0x05, 0xb7,
- 0x19, 0xf5, 0x45, 0x8d, 0x57, 0x5e, 0x70, 0xc6, 0x4e, 0xbe, 0x84, 0x2b,
- 0xaa, 0x26, 0x2a, 0xcf, 0x3b, 0xd9, 0xb9, 0x60, 0xe3, 0xa2, 0x47, 0x19,
- 0xf6, 0xa7, 0x8e, 0xe9, 0x7b, 0x08, 0x73, 0x00, 0x4d, 0x17, 0x17, 0x30,
- 0xf6, 0x33, 0x9a, 0x67, 0x46, 0x20, 0xf3, 0xb3, 0xb0, 0x4b, 0xc6, 0x34,
- 0x4c, 0x97, 0x03, 0x3e, 0xf8, 0xba, 0x03, 0xb8, 0xcf, 0x35, 0xca, 0x52,
- 0x9c, 0x76, 0xe4, 0x97, 0x75, 0xfd, 0x6c, 0xb1, 0x5b, 0xe3, 0x76, 0x66,
- 0x0d, 0xff, 0xd0, 0x3f, 0x0b, 0xe5, 0x81, 0x91, 0xc6, 0xb3, 0x05, 0xca,
- 0x02, 0xe8, 0x9f, 0xc2, 0x14, 0xee, 0x8d, 0x5a, 0x26, 0xe4, 0x25, 0x94,
- 0x07, 0x6c, 0x47, 0x99, 0x50, 0x2b, 0x77, 0x28, 0x6b, 0x28, 0x7b, 0x28,
- 0x4b, 0xcc, 0x7a, 0x8c, 0x3f, 0x48, 0x19, 0x7e, 0x2d, 0xfc, 0x53, 0xda,
- 0x1f, 0x9d, 0xc6, 0x07, 0x99, 0xce, 0x28, 0x23, 0x4f, 0xf7, 0xe8, 0xb5,
- 0x98, 0x28, 0xa8, 0x38, 0x20, 0x47, 0x19, 0xae, 0x63, 0x7b, 0x71, 0xcf,
- 0xaa, 0x09, 0x5c, 0xd9, 0x63, 0x1f, 0xc0, 0x6f, 0xae, 0xcd, 0x04, 0xea,
- 0xe1, 0x2a, 0x8e, 0xe2, 0x8e, 0x0b, 0xb6, 0x99, 0x91, 0x23, 0x5c, 0xd3,
- 0x84, 0x5d, 0xd3, 0x2f, 0x03, 0x0f, 0x9c, 0x9f, 0xd2, 0xf1, 0x07, 0xe5,
- 0xed, 0x00, 0xde, 0x2b, 0xd6, 0xdf, 0x6d, 0x15, 0xc3, 0x83, 0xb8, 0x7a,
- 0xc9, 0xcf, 0x2d, 0x66, 0xbd, 0x34, 0xed, 0x7e, 0x37, 0x6a, 0x78, 0x31,
- 0x8e, 0xb2, 0x08, 0xca, 0xda, 0x45, 0xf3, 0xfe, 0x32, 0x1e, 0xd3, 0x16,
- 0x8f, 0xfc, 0xad, 0xec, 0x6f, 0xd0, 0x13, 0x6c, 0xda, 0x8c, 0x37, 0x80,
- 0x71, 0x31, 0x97, 0x63, 0x7b, 0xd4, 0x38, 0xe4, 0xf7, 0xb8, 0x47, 0x19,
- 0xce, 0x38, 0x03, 0xe7, 0xc7, 0x7e, 0x51, 0xae, 0x71, 0xe0, 0x4b, 0xd5,
- 0x87, 0xff, 0x32, 0xd6, 0xec, 0x71, 0xd9, 0x57, 0xbc, 0x5a, 0xfb, 0xd4,
- 0x8d, 0x47, 0xcd, 0x7a, 0x88, 0x0a, 0xeb, 0xa1, 0xef, 0x38, 0x6d, 0x9b,
- 0x31, 0xfd, 0x3e, 0x7a, 0x94, 0xbf, 0x29, 0x9f, 0x6b, 0xe5, 0xbd, 0xb1,
- 0x6b, 0xf2, 0x2b, 0x64, 0x1d, 0x6d, 0x0b, 0xac, 0x59, 0xb9, 0x16, 0xef,
- 0xf4, 0xf1, 0x29, 0xf3, 0xc8, 0x4f, 0x07, 0xc1, 0x13, 0xaa, 0xc1, 0xf0,
- 0x3e, 0x7d, 0x8d, 0x7a, 0xfc, 0x04, 0xfb, 0x0b, 0xbc, 0x72, 0x02, 0xb6,
- 0xdb, 0xae, 0xe5, 0x3e, 0x20, 0x2b, 0xe3, 0x31, 0x39, 0x59, 0x68, 0x91,
- 0xb9, 0x82, 0x82, 0xc1, 0x60, 0x64, 0x67, 0x44, 0x12, 0x5a, 0xff, 0xd2,
- 0xbe, 0x1b, 0x9e, 0x8e, 0x58, 0xba, 0x83, 0xc3, 0xd2, 0xfc, 0x1b, 0xd0,
- 0xb1, 0x65, 0xe8, 0xd8, 0x56, 0xe8, 0xe0, 0xd5, 0x32, 0xa2, 0xab, 0x61,
- 0xad, 0x8c, 0x60, 0x9b, 0x14, 0xbc, 0xf2, 0x83, 0x68, 0x17, 0xd2, 0x5f,
- 0x4c, 0xd3, 0x5a, 0x56, 0x72, 0xce, 0xae, 0xca, 0x94, 0xb3, 0xbb, 0xb2,
- 0x5a, 0x07, 0xf5, 0xb9, 0x51, 0x31, 0xb0, 0x9e, 0xd4, 0x71, 0xbc, 0x94,
- 0x9f, 0x01, 0x4e, 0x76, 0x83, 0xee, 0x9e, 0x2e, 0xc1, 0x8f, 0xa7, 0x5c,
- 0x06, 0xcc, 0x8f, 0x01, 0xe6, 0xd9, 0x92, 0x13, 0xda, 0x06, 0xc2, 0xe0,
- 0xc9, 0xec, 0x74, 0xbf, 0x2c, 0xce, 0x93, 0x0e, 0x21, 0x03, 0x4a, 0x58,
- 0x4f, 0x7f, 0x1d, 0xec, 0x00, 0x8e, 0x0f, 0xb9, 0x3d, 0xdd, 0xa1, 0xdf,
- 0x19, 0x7d, 0xde, 0x29, 0x8b, 0xe5, 0xf7, 0x58, 0xd8, 0x0e, 0xd7, 0xc0,
- 0xb6, 0x6e, 0x19, 0xb6, 0xdd, 0x80, 0x6d, 0x4f, 0x5d, 0xd8, 0xea, 0xe9,
- 0xe2, 0x2e, 0xd8, 0x34, 0xe4, 0x8f, 0x10, 0xaf, 0xed, 0x96, 0x1e, 0x6e,
- 0xb7, 0xf6, 0x2e, 0x6d, 0xa2, 0x9f, 0x02, 0x1e, 0xd2, 0x18, 0x7e, 0xcf,
- 0x3d, 0x4a, 0x59, 0x86, 0x72, 0x3e, 0x7f, 0x06, 0x75, 0xf0, 0x3c, 0xf7,
- 0xe7, 0x56, 0x0e, 0xde, 0x65, 0x61, 0xa1, 0x9d, 0x90, 0x86, 0x4d, 0x3c,
- 0xe2, 0x64, 0xe6, 0x08, 0x43, 0x0e, 0xf0, 0xe2, 0x5d, 0xa5, 0xb6, 0x4f,
- 0xde, 0xd9, 0xef, 0x15, 0xb6, 0x1f, 0xf6, 0x1d, 0xce, 0x65, 0xbd, 0xd5,
- 0xf3, 0x21, 0x7d, 0x85, 0xf6, 0xf5, 0x94, 0x93, 0x5e, 0x33, 0xaf, 0x5a,
- 0x9a, 0xa3, 0xbc, 0x8d, 0xca, 0x4e, 0xd0, 0xc9, 0xce, 0x15, 0xb4, 0xa6,
- 0xdd, 0x10, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x18, 0xbe, 0xf1, 0x63,
- 0xd0, 0x87, 0x94, 0x37, 0x37, 0x1b, 0xdf, 0x5c, 0x4e, 0x00, 0xd6, 0xf0,
- 0x99, 0xb4, 0xc9, 0xdf, 0x94, 0x49, 0x55, 0x5a, 0x34, 0xbe, 0x4b, 0xa7,
- 0x8e, 0x9f, 0x56, 0xed, 0xf5, 0xa8, 0x8c, 0x9a, 0x35, 0x3f, 0xcc, 0x35,
- 0xa7, 0x2f, 0xd2, 0xfd, 0xc0, 0xa8, 0xe5, 0xaf, 0x54, 0x29, 0x27, 0xbb,
- 0xed, 0xdc, 0xbf, 0x5c, 0x67, 0xed, 0x5a, 0x97, 0xd7, 0x6e, 0xb4, 0xb2,
- 0x7a, 0x8e, 0x22, 0x5d, 0x0f, 0x44, 0xb5, 0x6f, 0x2b, 0xca, 0x97, 0x46,
- 0x8f, 0xf2, 0x93, 0xb6, 0x12, 0xca, 0x67, 0xfb, 0xdc, 0x36, 0xd0, 0xdb,
- 0x53, 0x6b, 0xec, 0xae, 0xa4, 0x95, 0x9b, 0xf4, 0x83, 0xc3, 0x31, 0x72,
- 0x56, 0x4e, 0xe6, 0xd0, 0xff, 0x94, 0xb3, 0xb3, 0x52, 0x4f, 0x5e, 0x86,
- 0x72, 0x92, 0xf3, 0xb9, 0x57, 0xee, 0x78, 0x90, 0x3c, 0x7a, 0xbb, 0xb6,
- 0xaf, 0xaf, 0xda, 0x71, 0x00, 0xf8, 0x23, 0xfc, 0x8b, 0x9b, 0x60, 0x32,
- 0x40, 0xe7, 0xa6, 0x65, 0xdc, 0xae, 0xdb, 0xf8, 0xf2, 0xfa, 0xf3, 0x6a,
- 0xc7, 0x6f, 0xc6, 0x59, 0x95, 0x85, 0x59, 0xdb, 0xb1, 0xb0, 0xeb, 0x56,
- 0xdb, 0xb2, 0x9c, 0x03, 0xed, 0xd9, 0x46, 0x63, 0x0b, 0x16, 0x69, 0x7f,
- 0x52, 0x76, 0xd1, 0xfe, 0x8c, 0x35, 0x4a, 0x33, 0xe7, 0x33, 0x68, 0xcb,
- 0x68, 0xa7, 0xae, 0x9e, 0xdf, 0x6a, 0xff, 0x91, 0x70, 0x12, 0x6e, 0x43,
- 0x5b, 0x49, 0x45, 0xd8, 0x02, 0x19, 0xf5, 0xaf, 0xd5, 0x6b, 0xa0, 0x68,
- 0xbb, 0xee, 0xf8, 0x76, 0x83, 0x89, 0x31, 0x27, 0xd1, 0x3f, 0xc7, 0x24,
- 0xff, 0xf1, 0x4e, 0x3b, 0xbf, 0x9e, 0x2c, 0xab, 0xd5, 0x3d, 0x97, 0x2d,
- 0xe3, 0x6f, 0xe7, 0x8a, 0x35, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x2d, 0x0e,
- 0x49, 0x13, 0xa4, 0x85, 0x90, 0x16, 0xb7, 0x5a, 0x7d, 0x13, 0xd2, 0xde,
- 0xa5, 0xa0, 0xbd, 0xfb, 0x80, 0x27, 0xca, 0x70, 0xc6, 0xed, 0x36, 0xe3,
- 0xf9, 0x08, 0x9e, 0x43, 0x3e, 0xb9, 0x98, 0x0c, 0xa7, 0xfc, 0x66, 0x9b,
- 0x8c, 0x95, 0xfb, 0xa1, 0x9f, 0xcb, 0x36, 0x9c, 0x37, 0xe5, 0xff, 0x57,
- 0xe9, 0x77, 0x35, 0x1a, 0x3b, 0xfd, 0x43, 0x8d, 0x94, 0xaf, 0x9b, 0xe4,
- 0x60, 0x4d, 0xd9, 0xc5, 0xe4, 0x77, 0xed, 0x9c, 0x2f, 0xff, 0x7f, 0x30,
- 0xe7, 0xc4, 0xaa, 0x39, 0xbb, 0x76, 0xce, 0x15, 0xbc, 0x6f, 0xc3, 0xfb,
- 0x16, 0xea, 0x82, 0x64, 0x55, 0xde, 0x58, 0x5c, 0xe8, 0x79, 0xd5, 0xca,
- 0x89, 0x50, 0x46, 0x70, 0x5e, 0x1f, 0xb1, 0x73, 0x78, 0xa0, 0x66, 0x5e,
- 0x1f, 0x79, 0x13, 0xf3, 0xea, 0x5c, 0x31, 0xaf, 0x5d, 0x17, 0x9d, 0x57,
- 0x3d, 0x1e, 0x27, 0x2f, 0x87, 0xf3, 0x8b, 0xc9, 0x8d, 0x05, 0xce, 0x71,
- 0x27, 0xe6, 0x48, 0x18, 0xc2, 0x39, 0x0e, 0xd9, 0x39, 0x8a, 0xea, 0xda,
- 0xf1, 0x73, 0xf8, 0x5d, 0x3b, 0x3f, 0xea, 0xfe, 0x1f, 0x83, 0xa6, 0x9b,
- 0x24, 0xd3, 0xdf, 0x64, 0xe5, 0xff, 0x97, 0xe5, 0xd6, 0x22, 0xd7, 0x3a,
- 0x95, 0x16, 0xd9, 0xa3, 0xf6, 0x15, 0x9f, 0x6d, 0x64, 0x8c, 0x7f, 0x97,
- 0x6f, 0xf5, 0x18, 0xf4, 0xc5, 0x6e, 0xd8, 0x7c, 0x3b, 0x0b, 0x6a, 0x20,
- 0x22, 0x41, 0x70, 0x9b, 0xdf, 0x8c, 0xb1, 0x37, 0x6a, 0x5f, 0x75, 0x6d,
- 0x7c, 0xfd, 0x99, 0x46, 0xf1, 0x68, 0x6f, 0x50, 0x9f, 0x43, 0xdf, 0x1d,
- 0xa3, 0x0d, 0x96, 0x81, 0x9d, 0x9c, 0x4e, 0x44, 0xb4, 0x2d, 0x46, 0x9d,
- 0x98, 0x4a, 0xa4, 0xa5, 0x2c, 0xd9, 0x63, 0xe9, 0x84, 0x12, 0x8e, 0x01,
- 0x5b, 0x0d, 0x36, 0xe4, 0xad, 0x90, 0x35, 0xb7, 0x56, 0xf6, 0xaa, 0x5b,
- 0x60, 0xef, 0xdc, 0x72, 0xf2, 0x03, 0xea, 0x36, 0xd8, 0x3a, 0xb7, 0x9d,
- 0xbc, 0x41, 0xed, 0x83, 0x6d, 0xb3, 0x0f, 0x76, 0xce, 0xbe, 0x0a, 0x6d,
- 0xcf, 0x9b, 0x41, 0x7b, 0x9d, 0x35, 0xb4, 0x46, 0x1b, 0x87, 0xf3, 0x23,
- 0xee, 0x8f, 0x71, 0x0d, 0xfc, 0xa4, 0x7a, 0x45, 0xaf, 0x4b, 0xdb, 0x8a,
- 0xb2, 0xd7, 0x92, 0x55, 0xa1, 0x7e, 0xda, 0x60, 0xe3, 0x46, 0x94, 0xb7,
- 0xaf, 0x45, 0x5b, 0xa4, 0x11, 0x17, 0x78, 0x26, 0xfe, 0x48, 0x5b, 0xb5,
- 0xf3, 0xdf, 0xd4, 0x24, 0x5e, 0x67, 0x93, 0x34, 0xdf, 0x0b, 0xf9, 0x5a,
- 0x4b, 0x53, 0xbc, 0xbb, 0x56, 0xd7, 0x90, 0xb6, 0x28, 0x83, 0x43, 0x7a,
- 0xd8, 0xfa, 0x1a, 0xf2, 0xf7, 0xa2, 0xf4, 0x74, 0x4f, 0x64, 0x28, 0x08,
- 0xc6, 0x07, 0x64, 0x23, 0xe3, 0x01, 0x99, 0x4a, 0x35, 0x26, 0xa0, 0xbc,
- 0xda, 0x98, 0x00, 0xfd, 0xac, 0x47, 0x80, 0xdf, 0x19, 0x5c, 0x22, 0x63,
- 0x8c, 0x3b, 0x54, 0x42, 0xbb, 0xfc, 0x1b, 0xd6, 0x2e, 0x0f, 0xe1, 0x48,
- 0x02, 0x0e, 0x23, 0x9f, 0xd7, 0xea, 0xb9, 0x95, 0xfa, 0x3b, 0xb7, 0x6c,
- 0xd3, 0x26, 0xe5, 0xc6, 0x22, 0xe7, 0x4d, 0x19, 0x4c, 0xdc, 0xd4, 0xca,
- 0xe0, 0x84, 0xb5, 0xa3, 0x50, 0x47, 0xcb, 0xcf, 0xb5, 0xb2, 0x93, 0x72,
- 0x8f, 0xf1, 0xf9, 0x07, 0x7c, 0xd2, 0xfa, 0x7b, 0x24, 0xbd, 0x1c, 0x9f,
- 0x17, 0xd0, 0x9b, 0xf8, 0x91, 0x21, 0xbd, 0xdf, 0xe6, 0xce, 0xca, 0x6e,
- 0x19, 0x8e, 0x33, 0xd6, 0xc9, 0x78, 0x9e, 0x97, 0x9b, 0x05, 0x0f, 0x4c,
- 0x16, 0x15, 0x2c, 0xf8, 0x46, 0x19, 0x73, 0x03, 0xd9, 0xe5, 0x3b, 0x3a,
- 0x76, 0x6c, 0x74, 0xed, 0x4c, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0xff, 0x5d,
- 0x04, 0xf5, 0x2d, 0x6a, 0xfb, 0x56, 0x69, 0xfd, 0xbb, 0xa0, 0xeb, 0x7c,
- 0xae, 0x29, 0x8c, 0x63, 0x2e, 0xba, 0x11, 0x5b, 0xaf, 0xb6, 0xfc, 0x8b,
- 0x36, 0x3e, 0x9d, 0x84, 0xec, 0x0f, 0xcb, 0xfe, 0xb0, 0x4e, 0xd9, 0xb7,
- 0xea, 0x94, 0xfd, 0xcf, 0x3a, 0x65, 0x26, 0x2e, 0xb8, 0xb3, 0xf0, 0xf7,
- 0x78, 0x37, 0xa5, 0x7d, 0x77, 0xb1, 0xfb, 0x61, 0xb9, 0xe5, 0x3a, 0x1b,
- 0xac, 0x5f, 0xc6, 0x18, 0xb1, 0x89, 0x0d, 0x67, 0x75, 0x6c, 0xb8, 0xcf,
- 0xdd, 0xa1, 0xf4, 0x5e, 0xca, 0x7e, 0xc6, 0x19, 0xf7, 0x69, 0xbc, 0x10,
- 0x27, 0x5f, 0x61, 0x0c, 0x38, 0xc7, 0xbd, 0xd8, 0xa4, 0xba, 0x18, 0x6d,
- 0x57, 0x6d, 0x13, 0xb3, 0x6e, 0xb4, 0x8b, 0x5b, 0x64, 0x04, 0xb6, 0xc2,
- 0xce, 0x42, 0x9b, 0xec, 0x9a, 0x1e, 0x58, 0x47, 0xbd, 0xb5, 0x7b, 0xda,
- 0xf8, 0x83, 0xfb, 0xc0, 0x57, 0x69, 0x21, 0x8c, 0x29, 0x5f, 0x84, 0x36,
- 0xf1, 0x5a, 0x5b, 0xf8, 0xb5, 0xfb, 0xfb, 0xa5, 0x8b, 0xf4, 0xe7, 0xc0,
- 0x76, 0x78, 0xa3, 0xfd, 0x35, 0xcb, 0xc8, 0x74, 0x88, 0x2b, 0xf5, 0x33,
- 0xb6, 0x8b, 0x5c, 0xa4, 0x9d, 0xb6, 0x4b, 0xe4, 0xe9, 0x65, 0x59, 0xbc,
- 0x15, 0x36, 0x93, 0x04, 0x99, 0x01, 0xe9, 0x8c, 0x88, 0x8e, 0xf1, 0xf8,
- 0x46, 0x36, 0xf7, 0x70, 0x6f, 0x07, 0xf4, 0x6f, 0x6c, 0x15, 0x13, 0x37,
- 0x0d, 0xed, 0x94, 0x7a, 0xb4, 0x7b, 0x9d, 0xa5, 0x5d, 0xee, 0xb9, 0xee,
- 0xa6, 0xcc, 0xd5, 0x6b, 0x42, 0x3a, 0xde, 0x55, 0x90, 0x64, 0x48, 0xc7,
- 0x8b, 0x92, 0x5e, 0x41, 0xc7, 0x8b, 0x32, 0xa4, 0xe9, 0xb8, 0x71, 0x05,
- 0x1d, 0x77, 0x5a, 0x3a, 0xde, 0x13, 0x33, 0x74, 0xa1, 0xb4, 0x9e, 0x22,
- 0x9d, 0x1a, 0x3a, 0x76, 0x34, 0x1d, 0x2f, 0xe2, 0x1e, 0xf5, 0xae, 0xb3,
- 0x75, 0x22, 0xb6, 0x8c, 0xbf, 0xc3, 0x32, 0xca, 0xc5, 0x4f, 0xc6, 0x8c,
- 0x5e, 0x1a, 0x02, 0x1d, 0x85, 0xe5, 0xfb, 0x6d, 0xfc, 0xa0, 0xb6, 0xcc,
- 0xc4, 0x47, 0x76, 0x16, 0xc6, 0x62, 0x2b, 0xe9, 0x73, 0x08, 0xf4, 0x19,
- 0xd6, 0x79, 0x2d, 0xfa, 0x6c, 0xb6, 0xfb, 0x16, 0x71, 0xbd, 0x2f, 0x9f,
- 0x8e, 0x1b, 0x5a, 0xbd, 0x45, 0xcf, 0x9d, 0xf3, 0x3e, 0xfb, 0x06, 0x68,
- 0xd5, 0xac, 0xcd, 0xb9, 0xaa, 0xbf, 0xcd, 0x58, 0x54, 0xd2, 0xc4, 0xb0,
- 0x19, 0x27, 0xbd, 0x98, 0xed, 0x68, 0xe4, 0x53, 0x83, 0x96, 0x4f, 0xad,
- 0x63, 0xcc, 0x35, 0xa8, 0xca, 0xec, 0x01, 0xe8, 0x0a, 0xda, 0xd8, 0x5a,
- 0x4e, 0xe3, 0x5d, 0x67, 0x32, 0x53, 0x78, 0x35, 0x88, 0x78, 0x8c, 0x0f,
- 0x71, 0x5f, 0x40, 0xc6, 0x1c, 0x94, 0x75, 0x95, 0xcd, 0xbc, 0x94, 0xd7,
- 0x8a, 0xe7, 0x01, 0xe9, 0x2a, 0x2b, 0xf9, 0xe8, 0x74, 0x8b, 0xec, 0x2f,
- 0x44, 0xe5, 0xe3, 0x68, 0xff, 0xb1, 0x82, 0x0b, 0x7f, 0xfc, 0x4c, 0x8c,
- 0x76, 0xe1, 0xbe, 0x02, 0xf7, 0x27, 0x59, 0x37, 0xbe, 0x6a, 0x7f, 0x36,
- 0x22, 0x5d, 0x3d, 0x79, 0x78, 0x2a, 0x12, 0xdd, 0x03, 0x38, 0x9a, 0x86,
- 0x86, 0xe4, 0x07, 0x03, 0x1b, 0x51, 0xf6, 0xb2, 0x1d, 0x6f, 0xd4, 0x31,
- 0xf1, 0xde, 0x41, 0x79, 0x77, 0x65, 0x48, 0xae, 0xaf, 0x98, 0x3d, 0xd5,
- 0xea, 0x9e, 0x69, 0xca, 0x5d, 0x80, 0xfe, 0x49, 0xbb, 0x41, 0x70, 0xce,
- 0xc3, 0xaa, 0x1f, 0x89, 0x4a, 0xac, 0x27, 0x95, 0x58, 0x10, 0xf3, 0x7c,
- 0xbe, 0xfc, 0x0f, 0xc1, 0x58, 0x3c, 0x2a, 0x3f, 0xf0, 0x38, 0xc7, 0x41,
- 0xb9, 0xae, 0x5c, 0x3b, 0x36, 0x97, 0xf3, 0x0f, 0x63, 0xdc, 0xa7, 0xc8,
- 0x54, 0x16, 0x62, 0x8c, 0xa5, 0xd3, 0xe7, 0xe8, 0x7a, 0x1b, 0xfc, 0x38,
- 0x48, 0xee, 0xae, 0xb7, 0x81, 0x6e, 0xe2, 0xd0, 0xf9, 0x57, 0x01, 0xc6,
- 0xab, 0x18, 0xfb, 0x62, 0xcc, 0x8b, 0xcf, 0x5f, 0xc7, 0xb8, 0x6c, 0xfb,
- 0x1b, 0xd6, 0x5e, 0xe6, 0xfa, 0x1b, 0xde, 0xa9, 0xaf, 0x77, 0x5a, 0xc7,
- 0x62, 0x43, 0xe2, 0xc4, 0xde, 0x91, 0x90, 0x75, 0x5e, 0xed, 0xf8, 0xdc,
- 0x27, 0x86, 0xc5, 0x38, 0x20, 0xd1, 0xdd, 0xdb, 0x07, 0x65, 0x04, 0xf3,
- 0xdb, 0xb9, 0x66, 0x7e, 0xf7, 0x08, 0xe3, 0xab, 0xe7, 0x0b, 0x9c, 0x43,
- 0x75, 0x5e, 0xea, 0x0b, 0x66, 0x5e, 0xb1, 0x9e, 0xd5, 0xf3, 0xd1, 0xed,
- 0xd5, 0x09, 0xc0, 0xf2, 0x35, 0x9d, 0x57, 0x10, 0x04, 0x6f, 0xed, 0x39,
- 0x1f, 0x24, 0x2f, 0x49, 0xf5, 0x2e, 0x54, 0xf7, 0x77, 0xc6, 0x22, 0x43,
- 0x69, 0xad, 0xcf, 0xf0, 0x9c, 0xcc, 0x96, 0xd3, 0x58, 0x47, 0x89, 0x66,
- 0xfb, 0xa3, 0x9a, 0x4f, 0xb2, 0x5e, 0xda, 0xee, 0x61, 0x85, 0x3e, 0x54,
- 0x10, 0x28, 0x6f, 0xb5, 0xdc, 0xa0, 0xbe, 0xc2, 0xdc, 0xe5, 0xdf, 0xda,
- 0x1c, 0x96, 0x5e, 0xc6, 0xb3, 0xc6, 0xa2, 0x43, 0xb1, 0x64, 0xbe, 0xec,
- 0xe1, 0x77, 0x0b, 0xee, 0x3b, 0x60, 0xaf, 0xf8, 0xb0, 0x67, 0x24, 0xae,
- 0x8c, 0x6c, 0x00, 0x2d, 0xf7, 0xe4, 0x94, 0x22, 0x6f, 0xba, 0xc9, 0xc9,
- 0x72, 0x3c, 0x59, 0x2a, 0x7f, 0x96, 0xed, 0x51, 0xb7, 0x5e, 0x2c, 0xcf,
- 0xc8, 0x86, 0xa7, 0x2a, 0x1c, 0x83, 0xfe, 0xef, 0x1b, 0x19, 0x23, 0x6a,
- 0xfb, 0x66, 0x9f, 0x21, 0x5e, 0xa2, 0x74, 0xc9, 0xf1, 0x2f, 0x6d, 0x7d,
- 0x13, 0xce, 0xef, 0xb3, 0x16, 0xee, 0xd5, 0xe3, 0xbe, 0xa0, 0xed, 0x97,
- 0xd3, 0x15, 0xda, 0x8c, 0xdc, 0xdf, 0x49, 0x1d, 0x9f, 0x11, 0xc2, 0x11,
- 0x04, 0xcf, 0xf9, 0x46, 0x77, 0x3f, 0x55, 0xe1, 0x1e, 0x47, 0x10, 0xfc,
- 0x88, 0x76, 0xf1, 0xde, 0x22, 0xc6, 0x0b, 0x71, 0xb0, 0x35, 0x17, 0x85,
- 0x5c, 0x9c, 0x1a, 0x20, 0x7e, 0x05, 0x1e, 0x6a, 0x8f, 0x7b, 0xa3, 0xc4,
- 0x92, 0x9f, 0x2a, 0xb7, 0x24, 0x3f, 0x5d, 0x76, 0x81, 0x67, 0xce, 0x3b,
- 0x9e, 0x9c, 0xb0, 0x73, 0xce, 0x96, 0x89, 0xdf, 0xd7, 0xda, 0x87, 0x7c,
- 0x61, 0x85, 0xbf, 0x44, 0x98, 0xaa, 0xb0, 0x10, 0xb6, 0xa4, 0xc5, 0x4d,
- 0x10, 0xfc, 0xd8, 0x37, 0x6b, 0x3a, 0x55, 0x94, 0x29, 0x8c, 0x9b, 0xdb,
- 0xac, 0x88, 0x87, 0x58, 0xf2, 0x0e, 0x8c, 0xfd, 0x29, 0x8c, 0xbd, 0xbf,
- 0xcc, 0xf1, 0x20, 0x2b, 0x30, 0xf7, 0xa9, 0x4a, 0x08, 0x6f, 0xbd, 0xb1,
- 0xc3, 0x35, 0xef, 0xb5, 0x36, 0x5e, 0xf8, 0xac, 0x11, 0xd9, 0xae, 0xbc,
- 0x7e, 0xd0, 0xd7, 0xe2, 0xa6, 0xa8, 0xfc, 0x22, 0xe4, 0x6e, 0x20, 0x8f,
- 0x42, 0x9e, 0x2d, 0x6a, 0xba, 0xc9, 0x5c, 0xce, 0xff, 0x23, 0xf2, 0xeb,
- 0xeb, 0x18, 0x5f, 0x1e, 0xf6, 0x68, 0xbb, 0x2e, 0x05, 0x8b, 0x1e, 0xe5,
- 0xf3, 0x06, 0x99, 0x71, 0x73, 0xbd, 0xd0, 0x15, 0x28, 0x6b, 0xa5, 0xbf,
- 0x9d, 0xcc, 0x44, 0x52, 0xc9, 0x49, 0x61, 0x3e, 0x14, 0x73, 0x15, 0x98,
- 0x23, 0x44, 0xd9, 0x10, 0x85, 0xcc, 0xe3, 0x1a, 0x9a, 0xf1, 0x26, 0xcb,
- 0xd5, 0xba, 0x07, 0x84, 0x7b, 0x86, 0xa9, 0xc4, 0x3e, 0x6d, 0x9f, 0x88,
- 0x8c, 0x17, 0x58, 0x77, 0x3b, 0xac, 0x13, 0xaf, 0xa6, 0xbe, 0xce, 0xe1,
- 0x02, 0x9f, 0x87, 0x71, 0xac, 0x58, 0x2c, 0x53, 0x90, 0x97, 0x23, 0x03,
- 0xf2, 0x32, 0xed, 0xce, 0x61, 0xd0, 0xb6, 0xeb, 0xf1, 0xbd, 0x29, 0xcf,
- 0xf8, 0xb2, 0x94, 0x19, 0xec, 0xa3, 0x9d, 0x9d, 0x53, 0x9a, 0x27, 0x44,
- 0xa1, 0x6d, 0x2c, 0x5b, 0x96, 0x91, 0x6c, 0xc1, 0xc6, 0x7a, 0x46, 0x39,
- 0xe7, 0x0d, 0x35, 0x73, 0x6f, 0x95, 0x28, 0x60, 0x1a, 0x89, 0x24, 0x9d,
- 0x06, 0xef, 0x23, 0x2d, 0x46, 0xe7, 0x43, 0xee, 0xb7, 0xdd, 0xdf, 0xce,
- 0x3d, 0x53, 0x05, 0x1f, 0x5a, 0xb5, 0xdf, 0x7e, 0x8d, 0x1a, 0xfa, 0xf3,
- 0x04, 0xf4, 0xa0, 0x95, 0x95, 0xb1, 0x91, 0xae, 0x65, 0xfa, 0xe6, 0xf8,
- 0xd2, 0x1e, 0xf1, 0x92, 0x23, 0xc3, 0x65, 0x51, 0x91, 0x21, 0x37, 0x36,
- 0x5c, 0x5e, 0x49, 0xf3, 0x4f, 0x55, 0xfe, 0xbd, 0xb5, 0x05, 0x6b, 0x63,
- 0xaa, 0xb5, 0xef, 0xc8, 0x77, 0x2b, 0xf6, 0x2b, 0x92, 0x26, 0x07, 0x86,
- 0xfb, 0xb4, 0x5c, 0x93, 0xf4, 0x5b, 0x1b, 0xa0, 0x7c, 0x66, 0xb4, 0x8f,
- 0xc6, 0x9c, 0x8b, 0x98, 0xcd, 0x3d, 0x33, 0xb8, 0x4e, 0x97, 0x1d, 0x99,
- 0x82, 0x7c, 0x38, 0x20, 0x7f, 0x1f, 0xa4, 0xe3, 0xe6, 0xbd, 0x59, 0x5f,
- 0xd6, 0xe7, 0x5e, 0x44, 0xb3, 0xe4, 0x4f, 0x46, 0x25, 0x77, 0x92, 0x7b,
- 0x60, 0xcf, 0xed, 0xaf, 0xe6, 0x6d, 0x50, 0x0e, 0x70, 0xbf, 0xd6, 0x91,
- 0x3c, 0xfc, 0xda, 0x11, 0xee, 0xc3, 0xf7, 0xff, 0x1f, 0xf4, 0xc1, 0x7a,
- 0x61, 0xdb, 0x16, 0xb4, 0x6d, 0xb4, 0x6d, 0x47, 0xef, 0x78, 0x73, 0x6d,
- 0x5b, 0xd1, 0x36, 0x16, 0x8e, 0xfb, 0x06, 0xdb, 0x6a, 0x7c, 0x5e, 0x33,
- 0x5c, 0x28, 0x2e, 0xc1, 0x4f, 0x4e, 0x4c, 0x48, 0xda, 0x19, 0x1f, 0xd0,
- 0xf3, 0xb9, 0x66, 0xb8, 0x0c, 0x38, 0xe2, 0x41, 0x90, 0xf7, 0x43, 0x3d,
- 0xcc, 0x7f, 0xc7, 0x44, 0x3c, 0x96, 0x71, 0xdf, 0x92, 0xfe, 0x04, 0xa3,
- 0xa4, 0x2e, 0xf3, 0xd9, 0x24, 0xcf, 0xfd, 0xc9, 0xf8, 0x46, 0xdc, 0x55,
- 0x17, 0x71, 0x92, 0xf5, 0x18, 0xef, 0xdd, 0x68, 0xcb, 0x23, 0x2c, 0x4f,
- 0x45, 0x21, 0x4b, 0x4c, 0x79, 0xc4, 0x96, 0x03, 0x26, 0x3f, 0x9f, 0x04,
- 0xb7, 0xd9, 0x72, 0x3e, 0x2b, 0x5d, 0x6e, 0x9e, 0x0d, 0x0f, 0x8d, 0x09,
- 0xe3, 0x3a, 0x99, 0xeb, 0x1a, 0x64, 0x2b, 0xd6, 0x87, 0x3e, 0xa3, 0x23,
- 0xcd, 0x80, 0xe3, 0x9c, 0xff, 0x76, 0xd8, 0xd6, 0x81, 0xfc, 0xc0, 0x37,
- 0xf4, 0x3f, 0x2b, 0x3d, 0x69, 0xe5, 0x30, 0x07, 0x20, 0x90, 0x9d, 0xfe,
- 0xb6, 0xc4, 0x2e, 0xfc, 0x1e, 0xef, 0x4f, 0xca, 0xec, 0x20, 0xe8, 0xb1,
- 0x9f, 0xbc, 0xb1, 0x15, 0x36, 0x0f, 0x7e, 0xf7, 0xb4, 0xc8, 0x92, 0x9b,
- 0x73, 0xd7, 0xc1, 0x5f, 0x1b, 0xc1, 0xac, 0xe6, 0x0a, 0x9e, 0x7b, 0x1b,
- 0x84, 0x5c, 0xda, 0xed, 0xc1, 0xbd, 0x76, 0xbe, 0xdf, 0xc2, 0x7c, 0x7f,
- 0xad, 0x59, 0x9a, 0x59, 0x5e, 0x5b, 0xb7, 0x51, 0xf6, 0xb8, 0xdb, 0xdd,
- 0xd8, 0x8a, 0xba, 0xe7, 0x51, 0x97, 0x65, 0x9e, 0xcb, 0x1c, 0x9d, 0xd9,
- 0x32, 0xe9, 0xcc, 0xc0, 0xda, 0xd5, 0x13, 0x04, 0xd7, 0xf9, 0x1c, 0x37,
- 0x08, 0xae, 0xf7, 0xfb, 0xdc, 0x67, 0xe5, 0xf9, 0xc0, 0xd8, 0x54, 0x21,
- 0xed, 0x3c, 0x67, 0xe5, 0x75, 0x10, 0xbc, 0xec, 0xf7, 0xca, 0xef, 0x54,
- 0x52, 0x8f, 0xd3, 0xe7, 0x3e, 0x83, 0xe7, 0x33, 0xbe, 0xc9, 0x2b, 0xfa,
- 0x13, 0xb4, 0x8b, 0xab, 0x7e, 0xd0, 0xb0, 0x27, 0x5f, 0xd4, 0x3e, 0x3a,
- 0xf1, 0x67, 0x62, 0xfc, 0x55, 0x18, 0x30, 0x61, 0x2f, 0xb3, 0xc9, 0x65,
- 0x7e, 0xa0, 0xa6, 0xdf, 0xda, 0x77, 0x0a, 0xef, 0x58, 0x16, 0x04, 0x97,
- 0x0c, 0xfc, 0x31, 0xe6, 0x94, 0x2a, 0x71, 0xef, 0xee, 0x03, 0x9a, 0xff,
- 0x04, 0x7e, 0x3d, 0xe9, 0x24, 0xea, 0x2a, 0xe5, 0x1d, 0xee, 0x52, 0xa9,
- 0x9c, 0xc8, 0x5b, 0xb0, 0xfe, 0x5c, 0x63, 0x30, 0x48, 0x1b, 0x60, 0xdf,
- 0xb6, 0xbd, 0xd9, 0xc4, 0x92, 0xe8, 0x4b, 0xa7, 0x37, 0xc1, 0xd7, 0xd5,
- 0xf6, 0x4c, 0x14, 0x7c, 0x3d, 0xd1, 0x16, 0x04, 0xef, 0xf7, 0xc3, 0x35,
- 0xb3, 0xb1, 0x6a, 0xe8, 0xf8, 0x6c, 0xff, 0xb9, 0x66, 0x63, 0xc7, 0x31,
- 0x4f, 0x30, 0xa9, 0xe3, 0xfa, 0xaa, 0x1d, 0x3a, 0x64, 0xdb, 0x57, 0x39,
- 0x7e, 0x8e, 0xe5, 0xef, 0xf3, 0x43, 0x98, 0xaa, 0xed, 0xb3, 0xfd, 0xeb,
- 0xac, 0xcd, 0x19, 0x05, 0x2e, 0x3d, 0xb7, 0x4b, 0xfd, 0x4d, 0x60, 0x74,
- 0x6b, 0x48, 0xc3, 0x7f, 0x17, 0x3c, 0x18, 0x37, 0xcf, 0x99, 0x6d, 0xec,
- 0x63, 0xab, 0x4c, 0x6e, 0xc3, 0x73, 0xf4, 0x5a, 0xdc, 0x87, 0x2f, 0x8b,
- 0xc8, 0x15, 0x89, 0x61, 0xb5, 0xcd, 0x7d, 0x50, 0xfa, 0xac, 0x8c, 0xfb,
- 0x1a, 0xf4, 0x7d, 0x0e, 0xfe, 0x78, 0x93, 0x3c, 0x08, 0x9a, 0x56, 0x03,
- 0xa9, 0xe4, 0x82, 0x4a, 0xf5, 0xce, 0xa8, 0x94, 0x3f, 0xa6, 0xae, 0xe7,
- 0xbc, 0x06, 0x89, 0x8b, 0x19, 0xe2, 0xb7, 0x08, 0xfc, 0x17, 0x81, 0xe3,
- 0x8b, 0xee, 0xf1, 0xfa, 0x56, 0xb7, 0x18, 0xfd, 0x96, 0xd3, 0xb4, 0x69,
- 0xec, 0xf2, 0x3f, 0xf6, 0xc3, 0x35, 0x84, 0x6d, 0xc8, 0x1c, 0x99, 0xba,
- 0x6b, 0x94, 0xe5, 0x1a, 0x41, 0x31, 0xe4, 0x40, 0xf7, 0xa9, 0xe4, 0x84,
- 0x5a, 0x0a, 0x36, 0xed, 0xe8, 0xee, 0x7d, 0x42, 0xf7, 0x93, 0xf2, 0xd3,
- 0x2a, 0x0f, 0x78, 0xb6, 0x4a, 0xd3, 0x0e, 0xe2, 0x99, 0xb0, 0xc6, 0x18,
- 0x4f, 0x72, 0xef, 0x40, 0xdd, 0x31, 0xa5, 0xf7, 0xa0, 0x6d, 0x1d, 0xc2,
- 0x1c, 0x5f, 0x2f, 0xcd, 0xd4, 0x43, 0x8c, 0x93, 0xbd, 0x96, 0x2e, 0x84,
- 0x4c, 0x3a, 0x46, 0x19, 0x18, 0x31, 0xb1, 0xdf, 0xca, 0xcf, 0xa1, 0x9d,
- 0xce, 0x67, 0x89, 0x45, 0x21, 0xa3, 0xa6, 0xc0, 0xc5, 0x87, 0x8e, 0x49,
- 0xb4, 0xc1, 0xfb, 0x5f, 0xcd, 0xc6, 0x6f, 0xa2, 0x0f, 0xc5, 0xb1, 0x1b,
- 0x24, 0xbf, 0x26, 0xde, 0x52, 0x02, 0xfc, 0xcd, 0x32, 0x79, 0x8c, 0x6b,
- 0x11, 0x85, 0xcc, 0xe1, 0xd8, 0x12, 0xcd, 0xf4, 0x07, 0xc1, 0x38, 0xcb,
- 0x4f, 0x92, 0x7f, 0x25, 0xc5, 0x77, 0xb9, 0x93, 0x0b, 0x9b, 0xd4, 0x0a,
- 0x59, 0xdb, 0x62, 0xe1, 0xd0, 0x78, 0x92, 0x92, 0x96, 0x23, 0xd4, 0x37,
- 0xb7, 0xd5, 0xc0, 0x33, 0x7a, 0xc7, 0x94, 0xd7, 0xf8, 0x26, 0xe0, 0xf9,
- 0x3d, 0xc0, 0xd3, 0x62, 0xe1, 0x69, 0x5c, 0x05, 0x4f, 0x4b, 0x08, 0x0f,
- 0xe4, 0x1c, 0xe5, 0x6a, 0xec, 0x9a, 0x74, 0x59, 0x9c, 0xbc, 0x27, 0x9d,
- 0x4a, 0xfb, 0x2f, 0xd4, 0x37, 0x8d, 0xee, 0xf8, 0x80, 0x2b, 0xe3, 0x5a,
- 0xd7, 0x44, 0xaf, 0xe9, 0x2e, 0x2f, 0xc0, 0x7a, 0x15, 0x27, 0xe3, 0x11,
- 0xf6, 0x7a, 0x76, 0xd5, 0x3d, 0x90, 0xff, 0x8b, 0xa9, 0xa8, 0xb5, 0x25,
- 0x4a, 0x3e, 0xfd, 0x96, 0xb8, 0xde, 0xdb, 0xaf, 0xc2, 0xf4, 0x12, 0x60,
- 0x82, 0x3c, 0x3e, 0xd6, 0xe7, 0x8e, 0xca, 0xa5, 0xda, 0x37, 0xb3, 0xb8,
- 0xc6, 0xdc, 0x62, 0x35, 0x73, 0x83, 0xfe, 0x53, 0xe1, 0xdc, 0x20, 0x13,
- 0x51, 0xaf, 0x24, 0xf7, 0x5b, 0x5c, 0xb4, 0x62, 0x4e, 0xb1, 0x9a, 0xf9,
- 0x74, 0x27, 0xf6, 0xb3, 0xcc, 0xcc, 0xa7, 0x27, 0xef, 0xc5, 0x2c, 0x7e,
- 0x57, 0xc3, 0x58, 0xf5, 0x17, 0x67, 0x24, 0x90, 0x29, 0x1f, 0x6b, 0xd4,
- 0x4b, 0xff, 0x24, 0x66, 0xf3, 0x98, 0x15, 0x9e, 0x37, 0x58, 0xfe, 0x72,
- 0x25, 0xaf, 0xfd, 0xb7, 0x2f, 0xad, 0x37, 0x7c, 0x1a, 0xb5, 0xf9, 0x6b,
- 0xfc, 0xdd, 0xb1, 0xde, 0xee, 0xef, 0xe7, 0xd2, 0xf2, 0xfb, 0xeb, 0x69,
- 0x97, 0x34, 0x78, 0x43, 0xab, 0xca, 0x62, 0x28, 0xbb, 0x7d, 0xbd, 0x95,
- 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1a, 0xf3, 0x34, 0xf8, 0x8e, 0x32, 0xb8,
- 0x16, 0x27, 0x7d, 0x60, 0x45, 0xf2, 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc,
- 0x51, 0x7d, 0x27, 0x8c, 0xa3, 0xe3, 0x77, 0x3d, 0xdb, 0x9f, 0xf8, 0x26,
- 0xae, 0xe5, 0xdb, 0x53, 0xe0, 0xfb, 0x03, 0xbe, 0x13, 0x9d, 0x65, 0x1e,
- 0x80, 0xa6, 0xe1, 0xda, 0xbe, 0xaf, 0x47, 0xdf, 0x21, 0x2d, 0x93, 0x5e,
- 0xae, 0xd7, 0x74, 0xd3, 0x44, 0x5d, 0x7c, 0x8c, 0xf4, 0xc7, 0x58, 0x72,
- 0xb3, 0xd6, 0x8f, 0xd5, 0x75, 0x6c, 0x82, 0xae, 0x89, 0x1b, 0x1e, 0x75,
- 0xcd, 0x7e, 0x77, 0xb5, 0xbf, 0x31, 0xf4, 0x47, 0x3b, 0x0d, 0x7e, 0xba,
- 0xc7, 0x68, 0x0e, 0xe5, 0x97, 0x13, 0x55, 0x57, 0x6a, 0x3f, 0x33, 0xa6,
- 0xf3, 0x8e, 0x96, 0xeb, 0x4e, 0xd8, 0xb1, 0x49, 0xb7, 0x26, 0xfe, 0x5f,
- 0x1d, 0x5f, 0x1c, 0xb5, 0x4d, 0x40, 0x65, 0x8d, 0x32, 0x35, 0x40, 0x1a,
- 0xe5, 0xdc, 0xb5, 0x0d, 0x75, 0x0d, 0xed, 0x08, 0x43, 0x9f, 0xb4, 0x9d,
- 0xa2, 0xd7, 0x64, 0x0b, 0x8d, 0xc6, 0x67, 0x89, 0xcb, 0xe6, 0x06, 0x9d,
- 0x47, 0x80, 0xb2, 0x72, 0xa8, 0xcb, 0xa2, 0x32, 0xdb, 0xff, 0xbf, 0x83,
- 0xf4, 0x5e, 0xd6, 0xad, 0xbb, 0x6f, 0x9f, 0x98, 0x11, 0x8d, 0xa7, 0xbf,
- 0xa8, 0xe2, 0xc9, 0xce, 0x2d, 0xbe, 0x7a, 0x6e, 0x05, 0xc0, 0x7b, 0x0f,
- 0x64, 0x27, 0xd7, 0xc9, 0xe4, 0x6f, 0x3f, 0x2e, 0x4e, 0x34, 0xd3, 0x5b,
- 0x6f, 0x6e, 0xa5, 0x10, 0xaf, 0x9c, 0x1b, 0x68, 0x35, 0x9c, 0x17, 0x69,
- 0x3b, 0xae, 0xf7, 0x89, 0x94, 0x22, 0x2c, 0xad, 0xab, 0x70, 0x1b, 0xd2,
- 0x9d, 0xa1, 0xb9, 0xa7, 0x34, 0xcd, 0xb5, 0x58, 0x9a, 0x43, 0x5d, 0x97,
- 0xfb, 0xde, 0xa3, 0x2d, 0x55, 0x9a, 0xdb, 0x60, 0x69, 0xee, 0x99, 0xf5,
- 0x66, 0x4f, 0xfc, 0xfd, 0x2d, 0x66, 0x4f, 0xea, 0x2f, 0x57, 0x3d, 0x6f,
- 0xa2, 0xcd, 0x08, 0x5f, 0x2c, 0x7c, 0xae, 0x85, 0xf5, 0x0c, 0x60, 0xad,
- 0x95, 0x35, 0x4d, 0x36, 0xee, 0xc6, 0xfd, 0x73, 0xfa, 0x7d, 0x51, 0x79,
- 0x14, 0x76, 0x50, 0xbe, 0xfc, 0x8f, 0xc1, 0x02, 0x7c, 0xbf, 0xa9, 0x65,
- 0xdd, 0x7b, 0x5b, 0x0b, 0xf9, 0x6d, 0x06, 0xbf, 0x0e, 0xd6, 0xf8, 0x3c,
- 0x98, 0x2f, 0xca, 0xfe, 0x01, 0xeb, 0x01, 0xb9, 0xbc, 0x5c, 0x97, 0x31,
- 0x0b, 0xe3, 0xe3, 0x30, 0x66, 0x68, 0xf6, 0x13, 0x29, 0xe7, 0xef, 0x84,
- 0x4f, 0x74, 0x0f, 0xf4, 0x24, 0xe9, 0xfb, 0xa5, 0x16, 0x93, 0xe7, 0x1b,
- 0x87, 0x1e, 0xfb, 0x65, 0x9b, 0x0b, 0x75, 0xf8, 0x57, 0xeb, 0xe7, 0xf8,
- 0x82, 0xf6, 0x1d, 0xd2, 0xcc, 0xdf, 0xb7, 0x98, 0x98, 0xf1, 0xb7, 0x5a,
- 0xc8, 0x67, 0x6a, 0xdb, 0x0f, 0x37, 0x68, 0xbe, 0x70, 0xc2, 0xe7, 0xcf,
- 0xb4, 0xae, 0x7c, 0x0e, 0xdb, 0x3d, 0xd9, 0xba, 0xb2, 0x5d, 0x58, 0xfe,
- 0x73, 0x1b, 0x57, 0x96, 0x5f, 0xe3, 0xae, 0x6c, 0xff, 0xf5, 0x55, 0xcf,
- 0x2d, 0x9b, 0x56, 0x3e, 0x5f, 0xbd, 0xea, 0x79, 0x6a, 0xd5, 0xf3, 0x85,
- 0x55, 0xcf, 0x57, 0xb5, 0xad, 0x7c, 0xbe, 0xbd, 0xad, 0x3e, 0xbc, 0x87,
- 0xdb, 0x56, 0xc2, 0x75, 0xa7, 0x8e, 0xf7, 0xcf, 0x54, 0xa2, 0xb2, 0xab,
- 0x80, 0xf7, 0x4e, 0xe7, 0x66, 0xa3, 0xd7, 0x6a, 0xdf, 0x33, 0xbe, 0xf6,
- 0xd7, 0xab, 0xfa, 0xab, 0xb6, 0xdb, 0x5d, 0x6d, 0xe7, 0x57, 0xdb, 0x19,
- 0xd9, 0x36, 0x5b, 0xe1, 0x3b, 0x96, 0x87, 0xfd, 0x9a, 0xb6, 0x53, 0xc5,
- 0x4e, 0x9d, 0x0b, 0x3b, 0xaa, 0x73, 0x61, 0x93, 0xe0, 0xc3, 0x3b, 0x75,
- 0x4c, 0x69, 0x93, 0x42, 0x79, 0xa5, 0x55, 0xc7, 0x95, 0x74, 0x2c, 0xb5,
- 0x30, 0x0a, 0xdb, 0x96, 0x39, 0xb0, 0x81, 0xec, 0xf1, 0xcd, 0xdd, 0xe4,
- 0xc4, 0x1e, 0x0e, 0x86, 0xdd, 0x20, 0x98, 0xf4, 0x6e, 0xb3, 0xf9, 0x62,
- 0xb8, 0x57, 0x4c, 0x1b, 0xea, 0xe0, 0x27, 0xa0, 0x83, 0xab, 0xba, 0xf7,
- 0x4e, 0x8c, 0xb5, 0x00, 0x9a, 0x19, 0x90, 0xdf, 0xad, 0xa4, 0xbe, 0x24,
- 0xfa, 0xcc, 0x4d, 0x3f, 0x6c, 0xb8, 0xa5, 0x4f, 0xbd, 0xdf, 0xf3, 0x61,
- 0xeb, 0x05, 0xf2, 0xb0, 0x3f, 0x08, 0x1a, 0xea, 0x85, 0xbd, 0xe7, 0x69,
- 0xbf, 0xf4, 0xb4, 0xa6, 0x2d, 0xd2, 0x58, 0x8b, 0xce, 0xd7, 0x7f, 0xd4,
- 0x77, 0x62, 0x99, 0xfe, 0x3f, 0x32, 0x71, 0x1a, 0xbf, 0xdb, 0xfd, 0x1a,
- 0xf8, 0x76, 0xa7, 0xb7, 0x05, 0x3e, 0x0a, 0x69, 0x88, 0xf1, 0xaf, 0xcb,
- 0x75, 0x1e, 0x21, 0x03, 0x68, 0x33, 0x51, 0xc6, 0x09, 0x53, 0x83, 0x63,
- 0xc2, 0x79, 0xa7, 0x12, 0x49, 0xa5, 0xed, 0xaa, 0xe0, 0x46, 0x9f, 0x39,
- 0xb6, 0xdc, 0x63, 0x21, 0x3f, 0xef, 0xff, 0xf4, 0x94, 0x97, 0x73, 0x23,
- 0x36, 0x2f, 0x37, 0x53, 0x30, 0xb4, 0x39, 0x41, 0xda, 0x84, 0x3f, 0xb5,
- 0xd8, 0xff, 0xb7, 0x01, 0xed, 0xfb, 0xa4, 0x22, 0xed, 0xff, 0x4d, 0x30,
- 0x17, 0x65, 0x5f, 0x84, 0x7b, 0xff, 0xa7, 0x33, 0x1a, 0x57, 0x77, 0xca,
- 0x81, 0x22, 0x6d, 0xe1, 0x98, 0xce, 0xe7, 0x18, 0xf7, 0x69, 0xa7, 0xc5,
- 0x80, 0xc7, 0x0f, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x47, 0x50, 0x27, 0x22,
- 0x63, 0x60, 0xf1, 0xd9, 0x02, 0xf9, 0x93, 0xf7, 0x28, 0xea, 0xbb, 0x32,
- 0x5f, 0xb8, 0x59, 0xe7, 0xdb, 0x9d, 0x46, 0xdb, 0x27, 0x71, 0xcd, 0x16,
- 0x26, 0xd0, 0x66, 0xaf, 0xae, 0x3f, 0x5b, 0x62, 0x8e, 0xb2, 0x40, 0x2e,
- 0xed, 0x97, 0xfc, 0x5c, 0x97, 0x8c, 0xc5, 0x17, 0x66, 0xa2, 0xcb, 0x71,
- 0x99, 0x8f, 0x6f, 0xe0, 0x1e, 0x47, 0xfe, 0x4a, 0xee, 0x07, 0x4b, 0x74,
- 0x74, 0xbb, 0xea, 0x6d, 0xd3, 0x3e, 0xd7, 0xa0, 0xec, 0xac, 0x0c, 0xc9,
- 0x4d, 0x95, 0xcf, 0x6e, 0x36, 0xb1, 0xa8, 0x15, 0xf1, 0xad, 0xc3, 0xc4,
- 0x8a, 0x3a, 0x1a, 0xe5, 0xb9, 0x25, 0x99, 0x3d, 0x25, 0x12, 0x39, 0x1a,
- 0xc6, 0x12, 0x59, 0xe6, 0x4a, 0xd7, 0x95, 0x80, 0xeb, 0x14, 0x64, 0x6b,
- 0x3c, 0x26, 0x5f, 0xdc, 0x16, 0x8e, 0x95, 0x0b, 0xa6, 0xb7, 0xe5, 0xe4,
- 0xd3, 0xb8, 0xb2, 0x57, 0xa6, 0x4a, 0x19, 0xc5, 0x71, 0xbf, 0x13, 0x50,
- 0x96, 0xa9, 0x21, 0x4f, 0x72, 0x6d, 0xe1, 0xd8, 0xf0, 0x6f, 0x76, 0x84,
- 0xe3, 0xd3, 0xe6, 0x36, 0x67, 0x1e, 0xf2, 0xdc, 0x77, 0x01, 0xfd, 0x45,
- 0x86, 0xee, 0xde, 0x40, 0xdf, 0x61, 0x58, 0xd8, 0x0e, 0x32, 0x5d, 0xb1,
- 0x6f, 0xc2, 0x49, 0xf8, 0x6b, 0xe1, 0x5c, 0x4c, 0xc6, 0x81, 0xa3, 0xdc,
- 0xeb, 0xc2, 0xdb, 0xe7, 0x7a, 0xaa, 0x1e, 0xbc, 0xa3, 0x36, 0x96, 0xc8,
- 0xf8, 0xe0, 0x3a, 0xe0, 0xad, 0x05, 0xe5, 0x1f, 0x94, 0xa9, 0x63, 0x6f,
- 0xdb, 0xcc, 0xbd, 0xec, 0x06, 0xcf, 0xb1, 0x39, 0xa7, 0x3c, 0xbf, 0x73,
- 0x37, 0xea, 0xf0, 0xfd, 0xcd, 0x68, 0x93, 0xca, 0x65, 0x22, 0x9b, 0xe1,
- 0x13, 0x71, 0xdc, 0x20, 0xd2, 0xb5, 0xa3, 0x59, 0xe7, 0x90, 0xca, 0x29,
- 0xea, 0xf3, 0xb0, 0xed, 0xdd, 0x3a, 0x47, 0x03, 0x7e, 0x7b, 0x6e, 0x24,
- 0x42, 0xf9, 0xd5, 0x2b, 0xc3, 0xd4, 0x27, 0xa7, 0x6e, 0xd6, 0xb4, 0xdf,
- 0xbd, 0x8d, 0x67, 0x99, 0xfa, 0x8c, 0x8d, 0x1e, 0x27, 0x8c, 0xa3, 0x28,
- 0x87, 0xfd, 0xfe, 0x9a, 0x30, 0xdc, 0xf5, 0x26, 0x61, 0xb8, 0xeb, 0x4d,
- 0xc2, 0x40, 0x5c, 0x00, 0x8e, 0xca, 0x5f, 0x6c, 0x08, 0x63, 0xd5, 0x97,
- 0x62, 0x1e, 0x07, 0x8b, 0x77, 0xc9, 0xa1, 0xa2, 0xa3, 0xe3, 0x8e, 0x0b,
- 0x8a, 0x32, 0xc1, 0x05, 0x4f, 0x82, 0xf7, 0x8a, 0xe0, 0xcd, 0x22, 0x78,
- 0xb1, 0x08, 0xbe, 0x84, 0xfd, 0x7f, 0x06, 0xf6, 0xff, 0x93, 0x58, 0x9b,
- 0xd3, 0x2b, 0x78, 0x39, 0xad, 0x79, 0x39, 0x5f, 0xa4, 0xaf, 0xd6, 0x7f,
- 0x11, 0x7e, 0x8d, 0xca, 0x70, 0x21, 0x05, 0x55, 0xe2, 0x44, 0xb3, 0xfd,
- 0x9f, 0x24, 0xbf, 0xca, 0x83, 0xfe, 0x0d, 0x68, 0x73, 0x18, 0x34, 0x9e,
- 0xa2, 0x1d, 0x48, 0xfb, 0x27, 0x07, 0xde, 0x3c, 0x4c, 0x5f, 0x4d, 0x5d,
- 0xb9, 0x49, 0xa8, 0x5f, 0xa2, 0x3b, 0x98, 0x7b, 0xc8, 0xb9, 0x26, 0x57,
- 0xe1, 0xc9, 0xf0, 0xef, 0x84, 0x47, 0x3d, 0x43, 0xbe, 0x7d, 0x99, 0x7c,
- 0x5b, 0xc3, 0xab, 0x01, 0xe7, 0x17, 0xb8, 0xdb, 0xea, 0xb5, 0xad, 0xd6,
- 0xdf, 0xb4, 0x5c, 0x5f, 0x8f, 0x5f, 0x22, 0x3f, 0x42, 0x27, 0x11, 0xf7,
- 0xc9, 0x4c, 0x64, 0x8b, 0xc5, 0x3d, 0x6c, 0xb7, 0x1d, 0x97, 0x00, 0xf7,
- 0x9d, 0x92, 0x9b, 0x0f, 0xc4, 0xdb, 0x11, 0xf6, 0x59, 0xed, 0xc7, 0xb5,
- 0xfd, 0x8c, 0x17, 0x1c, 0x19, 0xd9, 0xc6, 0x7d, 0x08, 0x07, 0x7a, 0x3e,
- 0x5c, 0x0f, 0xd8, 0xfb, 0x7a, 0xcd, 0x29, 0x63, 0x29, 0x5b, 0x5b, 0x6c,
- 0xfc, 0x89, 0xfd, 0x1d, 0x5e, 0xb5, 0x4e, 0x17, 0x02, 0x9e, 0x11, 0x9b,
- 0xf2, 0x6e, 0xa8, 0xa1, 0x95, 0xfb, 0x2c, 0xad, 0xa8, 0x55, 0xf3, 0xb8,
- 0xdd, 0xd2, 0x4a, 0x08, 0x6f, 0x3c, 0xa4, 0x95, 0xa6, 0x90, 0x56, 0x72,
- 0x33, 0x21, 0xad, 0xb0, 0xed, 0xed, 0x21, 0xad, 0x24, 0x6b, 0x69, 0x25,
- 0x37, 0xe3, 0xe0, 0x5a, 0x0d, 0x07, 0xe9, 0x85, 0xfd, 0x90, 0x5e, 0x00,
- 0x4b, 0xe5, 0xd6, 0xd6, 0x90, 0x5e, 0xe2, 0xe8, 0xe7, 0x50, 0xd1, 0xe4,
- 0x74, 0xc0, 0xef, 0xb2, 0x3a, 0xc4, 0xc5, 0x9a, 0x1b, 0x1f, 0xb1, 0x3e,
- 0x8d, 0xf8, 0x96, 0x46, 0xaa, 0x79, 0xee, 0xab, 0x68, 0x03, 0xb8, 0x67,
- 0x2e, 0xeb, 0x76, 0x4d, 0x1b, 0xf7, 0xfb, 0x53, 0xa8, 0xbb, 0x07, 0xb4,
- 0x11, 0xe2, 0xe0, 0x7a, 0x8b, 0x83, 0xd5, 0x6b, 0x39, 0x66, 0x71, 0xb0,
- 0xc7, 0xe2, 0x40, 0xf3, 0x4b, 0x8e, 0x6b, 0xa6, 0x34, 0x0e, 0x9a, 0x34,
- 0x0e, 0x44, 0x85, 0x6d, 0xc7, 0xea, 0xe0, 0x80, 0x75, 0xf6, 0xe8, 0xf9,
- 0x47, 0x30, 0xff, 0xfd, 0x98, 0xbf, 0xd2, 0xf3, 0xe7, 0x3a, 0x70, 0xfe,
- 0x80, 0xa5, 0x72, 0x72, 0x79, 0xfe, 0x6d, 0xe8, 0xe3, 0x60, 0x31, 0xa2,
- 0xe7, 0x0f, 0xdb, 0x7e, 0x30, 0x9c, 0xff, 0xe9, 0x8a, 0xc9, 0x7f, 0x3e,
- 0xbd, 0x46, 0xcf, 0x4d, 0x59, 0xde, 0xf0, 0xb4, 0x5f, 0xcc, 0x98, 0xf6,
- 0x19, 0xe8, 0xb6, 0x69, 0x3f, 0x69, 0xcf, 0x43, 0x19, 0x7b, 0xe9, 0x1b,
- 0x3e, 0x79, 0xe7, 0xe3, 0x3a, 0x0f, 0xe5, 0x71, 0xda, 0x4d, 0xc5, 0x36,
- 0x19, 0x99, 0xae, 0x85, 0x9b, 0xf0, 0xe6, 0xb4, 0x1c, 0xcd, 0x62, 0x7e,
- 0xe3, 0x7e, 0x2f, 0xe4, 0x9b, 0xa6, 0x25, 0x94, 0xa7, 0x72, 0xc3, 0x91,
- 0x26, 0x51, 0x0f, 0x7c, 0x08, 0x73, 0x8e, 0xca, 0x66, 0xaf, 0xdb, 0xdd,
- 0xa1, 0xa8, 0x0b, 0x2f, 0xab, 0xd1, 0x85, 0xed, 0x56, 0x17, 0x6e, 0xa2,
- 0x2e, 0x04, 0xdc, 0x77, 0xca, 0xe1, 0x22, 0xd7, 0x2f, 0x97, 0x6c, 0x82,
- 0xfe, 0xff, 0x81, 0xc7, 0xb3, 0x27, 0x3a, 0x6e, 0x96, 0x38, 0xac, 0x69,
- 0x99, 0x3a, 0x2d, 0xa5, 0xcf, 0x6a, 0x2c, 0xd2, 0xc6, 0x8e, 0x33, 0x16,
- 0x4a, 0xbd, 0xf7, 0xe3, 0xe0, 0x73, 0x75, 0xf4, 0xde, 0x64, 0xd1, 0xd8,
- 0x6f, 0x0d, 0xb0, 0x09, 0xe5, 0x44, 0x3b, 0xae, 0x8d, 0x3c, 0xab, 0xd0,
- 0xdb, 0xa3, 0x9a, 0xa5, 0xe1, 0x44, 0xab, 0x4c, 0x4c, 0x1b, 0x1b, 0x57,
- 0x9d, 0x00, 0xfe, 0x4f, 0x30, 0xdf, 0x55, 0x74, 0x7e, 0x7e, 0xb6, 0x04,
- 0x3b, 0x77, 0xf6, 0x4e, 0x93, 0xb7, 0x32, 0xdd, 0xa0, 0x7f, 0xd3, 0x06,
- 0xc9, 0xfb, 0x69, 0xe8, 0xbb, 0x98, 0x4c, 0xa0, 0xcf, 0xee, 0x6d, 0x8d,
- 0x98, 0x73, 0x1c, 0x6d, 0xe9, 0xf3, 0x31, 0x8e, 0xd6, 0x28, 0xd1, 0xd9,
- 0xb8, 0xce, 0xad, 0xe7, 0xd9, 0xd1, 0xcc, 0x60, 0x1b, 0xde, 0x31, 0x9f,
- 0xc1, 0xc5, 0x58, 0xa1, 0xec, 0x47, 0xbf, 0x47, 0xc5, 0xee, 0xf7, 0x0c,
- 0x69, 0xfd, 0x17, 0x39, 0xea, 0xda, 0x33, 0x74, 0x83, 0x58, 0xf7, 0x7a,
- 0x7a, 0xd1, 0x18, 0xb9, 0x19, 0xac, 0x9f, 0x3a, 0x15, 0xc5, 0xbd, 0x13,
- 0xf7, 0xb0, 0xbf, 0x50, 0x8f, 0x40, 0x37, 0xbe, 0xb3, 0x6f, 0xa3, 0x34,
- 0x03, 0xdf, 0xb3, 0x0a, 0xb8, 0x36, 0x39, 0x59, 0x39, 0xcd, 0x0b, 0x55,
- 0x7a, 0x78, 0xf2, 0x75, 0xf9, 0x81, 0x34, 0x41, 0x5a, 0xa0, 0x5c, 0x24,
- 0x6d, 0x50, 0x26, 0x3a, 0xfa, 0x6c, 0x03, 0xe9, 0xe1, 0x09, 0xdf, 0x8b,
- 0x70, 0xdf, 0xde, 0xc4, 0xe5, 0x49, 0x1b, 0xa4, 0xf9, 0xa4, 0x8e, 0xd7,
- 0xa7, 0xe5, 0x7b, 0x92, 0x6e, 0xeb, 0x86, 0x5d, 0xf6, 0x2f, 0xbb, 0xc6,
- 0xe6, 0xdc, 0xad, 0xa6, 0x39, 0xe8, 0x26, 0xe6, 0xd0, 0xf5, 0xca, 0xfb,
- 0x2a, 0x39, 0xe0, 0xe1, 0x5e, 0x28, 0xe5, 0x3b, 0x75, 0x5e, 0xe2, 0xee,
- 0xc2, 0x46, 0xb9, 0xc5, 0x8f, 0xd9, 0xb8, 0xfb, 0x41, 0xd0, 0xc1, 0xa2,
- 0x23, 0x27, 0xce, 0xe2, 0x3a, 0xe7, 0x70, 0xfd, 0xce, 0xfb, 0xe9, 0x94,
- 0x22, 0xb3, 0x7b, 0xd1, 0xc4, 0xa2, 0xf4, 0xb9, 0x13, 0xfa, 0x0c, 0xc8,
- 0x82, 0xd3, 0x74, 0xe2, 0xd0, 0x46, 0xe3, 0x4b, 0x03, 0x16, 0xaf, 0xd1,
- 0x1d, 0xa1, 0x2d, 0xe7, 0x07, 0x41, 0x96, 0x76, 0x83, 0x28, 0xed, 0x23,
- 0xc1, 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x5b, 0x9d, 0xc6, 0x53, 0x2f, 0x5a,
- 0x5a, 0x91, 0x88, 0x1a, 0x7a, 0xc6, 0x69, 0x38, 0x71, 0x9c, 0x6b, 0xa6,
- 0xf3, 0xa4, 0x0d, 0x5d, 0x3d, 0xe7, 0x54, 0xe9, 0xea, 0x1b, 0xf6, 0xb7,
- 0x1a, 0x6a, 0x92, 0x74, 0xaa, 0x09, 0xf3, 0x1d, 0x2e, 0x84, 0x30, 0x7e,
- 0x1f, 0x70, 0x11, 0x1e, 0xd0, 0xed, 0xec, 0x9f, 0xe1, 0x5a, 0x02, 0x2c,
- 0xf7, 0x01, 0xee, 0xf3, 0x80, 0xf9, 0x02, 0x2e, 0xd5, 0x11, 0x91, 0x3f,
- 0x76, 0x22, 0xb3, 0xb5, 0xf0, 0x12, 0xc6, 0xd3, 0x16, 0xde, 0xd7, 0x82,
- 0xd5, 0x95, 0xc5, 0x81, 0x2e, 0xc0, 0x43, 0x38, 0x5f, 0x02, 0x8c, 0xb4,
- 0x5b, 0x9f, 0xc7, 0xb3, 0x0b, 0xf8, 0x5e, 0xb0, 0x30, 0x81, 0x1e, 0xa7,
- 0xff, 0x47, 0xf5, 0x77, 0x81, 0x76, 0xf4, 0x9f, 0xdb, 0xe7, 0xce, 0x55,
- 0x32, 0xa0, 0xc7, 0x21, 0x9e, 0xa7, 0x8a, 0x4b, 0xb4, 0x03, 0xc0, 0xf7,
- 0x3f, 0x94, 0xc8, 0xa9, 0x84, 0x1c, 0x2a, 0x70, 0x0f, 0xe8, 0x24, 0xf0,
- 0xa1, 0xcf, 0xa4, 0xa0, 0xce, 0x15, 0xb8, 0xa0, 0xec, 0x67, 0xb7, 0xe3,
- 0xea, 0xc5, 0xf5, 0x56, 0x5c, 0x20, 0x87, 0xd9, 0x13, 0xb8, 0xfa, 0xd0,
- 0xb7, 0x8a, 0x37, 0x09, 0x73, 0xa9, 0xbe, 0x8d, 0x36, 0xda, 0xb6, 0xcc,
- 0xa9, 0xa1, 0x01, 0xe0, 0x6f, 0x00, 0xb0, 0x25, 0x70, 0x31, 0xff, 0xf8,
- 0x87, 0x8e, 0x9c, 0x7a, 0x19, 0x17, 0x18, 0xec, 0x14, 0x08, 0xf3, 0xd4,
- 0x20, 0x2e, 0x28, 0xb1, 0x53, 0x69, 0x5c, 0x23, 0xb8, 0xfe, 0xd2, 0x31,
- 0x3c, 0xd7, 0x09, 0x7c, 0x85, 0x3c, 0x02, 0x9c, 0xaf, 0xe0, 0xb9, 0xaf,
- 0x3b, 0x6f, 0x9c, 0xe7, 0x7e, 0xe2, 0x18, 0x9e, 0x7b, 0xc5, 0xa9, 0xf2,
- 0xdc, 0x59, 0x47, 0x3d, 0xfc, 0x8c, 0x13, 0x79, 0x98, 0xbe, 0xc4, 0x59,
- 0xc7, 0xf0, 0x7f, 0x44, 0x86, 0xf7, 0x82, 0x96, 0x1e, 0x5e, 0xc0, 0x45,
- 0xba, 0x7a, 0x16, 0xe5, 0x2f, 0xac, 0x1a, 0xf7, 0xf9, 0x37, 0x31, 0xee,
- 0xab, 0x76, 0x5c, 0x51, 0xd5, 0x71, 0x2f, 0xa0, 0xef, 0x97, 0xec, 0xb8,
- 0x17, 0x6a, 0xc6, 0x05, 0xad, 0x3c, 0xbc, 0x84, 0x8b, 0x74, 0xf1, 0x22,
- 0xca, 0x43, 0x99, 0x80, 0x85, 0x6e, 0x6e, 0xd0, 0x67, 0x9d, 0xe2, 0x5e,
- 0xc3, 0xb2, 0x6e, 0x4c, 0xd7, 0xe8, 0x87, 0x37, 0xa2, 0x1f, 0x27, 0x8b,
- 0xb4, 0x11, 0x17, 0x6a, 0xe4, 0x02, 0x7d, 0xa3, 0x40, 0x8e, 0x69, 0x3f,
- 0x88, 0x3e, 0x11, 0xfd, 0xa3, 0xd5, 0xb6, 0xd5, 0x27, 0x75, 0xee, 0xd8,
- 0xaf, 0x15, 0x3a, 0xe5, 0xd3, 0x05, 0xda, 0x84, 0xa4, 0x97, 0x20, 0x98,
- 0xd8, 0x41, 0xfb, 0x34, 0x17, 0x5c, 0xe2, 0x91, 0x4e, 0x3c, 0xf7, 0x33,
- 0x6b, 0x75, 0x46, 0x69, 0x18, 0xbe, 0x7b, 0xe6, 0xe8, 0xaf, 0x40, 0x67,
- 0x34, 0x00, 0x6e, 0xd2, 0x5b, 0x87, 0xdc, 0x58, 0x52, 0x53, 0x9b, 0x25,
- 0x21, 0x37, 0x15, 0x1a, 0x61, 0xf7, 0x30, 0xaf, 0xaa, 0x59, 0xba, 0x77,
- 0xc4, 0x4c, 0xde, 0xb7, 0x1b, 0xc7, 0x6f, 0xd7, 0xe4, 0xa1, 0xc7, 0x13,
- 0x78, 0xff, 0x7b, 0x2e, 0xe5, 0x60, 0xdc, 0xbb, 0x56, 0xe7, 0xf4, 0x74,
- 0xed, 0xa0, 0xdd, 0x72, 0xbd, 0xd6, 0xe1, 0xd1, 0x35, 0x76, 0x92, 0xea,
- 0x70, 0xa5, 0x6a, 0xa3, 0x8d, 0x17, 0x52, 0x49, 0xc2, 0xf5, 0x90, 0x70,
- 0xff, 0xeb, 0x1e, 0xc9, 0xfb, 0xad, 0xf0, 0x0b, 0x18, 0x3b, 0x4f, 0xf5,
- 0xd2, 0x36, 0x9a, 0x9d, 0x76, 0x6d, 0x5e, 0xf4, 0x46, 0x79, 0x4e, 0x8f,
- 0xd3, 0xa8, 0x61, 0x34, 0x67, 0x25, 0xb8, 0x8f, 0x10, 0xd3, 0xe7, 0x73,
- 0x66, 0xcb, 0x2d, 0x5a, 0xef, 0xcc, 0x96, 0x99, 0x87, 0x0f, 0x7f, 0xaa,
- 0xcc, 0xbc, 0x7b, 0x5f, 0xdc, 0x77, 0xc2, 0xcf, 0x2d, 0x6f, 0x91, 0xf1,
- 0xe9, 0x75, 0xd2, 0xe8, 0xa9, 0xf8, 0x66, 0xc8, 0x47, 0xb6, 0xe9, 0xda,
- 0x01, 0xff, 0x70, 0x66, 0xab, 0x3c, 0x39, 0xc3, 0xbe, 0x3b, 0x64, 0x6e,
- 0x5e, 0x1c, 0xf7, 0x9d, 0xeb, 0x51, 0x07, 0x72, 0x7d, 0x07, 0xcb, 0x92,
- 0xb8, 0x8b, 0x72, 0xdf, 0x19, 0x95, 0x73, 0x03, 0x7c, 0x66, 0xee, 0xbf,
- 0x44, 0xd9, 0xdf, 0xb9, 0x81, 0x4e, 0x79, 0x7c, 0x1e, 0x34, 0x01, 0xb9,
- 0x3f, 0x72, 0x82, 0x30, 0x89, 0xec, 0x9a, 0x65, 0x2c, 0xbd, 0xdb, 0x65,
- 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0x0c, 0x70, 0x2c, 0xe8, 0x25, 0xe8, 0xb8,
- 0xae, 0x1d, 0x46, 0x16, 0xa4, 0x67, 0x1b, 0x50, 0xce, 0x7e, 0xe1, 0x3f,
- 0xee, 0x65, 0x3f, 0x61, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59, 0x5a,
- 0xa5, 0x3f, 0xce, 0xfc, 0x4c, 0xf6, 0x37, 0xfb, 0xe8, 0xd5, 0x7b, 0x21,
- 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae, 0xba,
- 0x42, 0xdb, 0x17, 0x73, 0x15, 0xae, 0x20, 0x63, 0x51, 0xe1, 0x1a, 0x25,
- 0xe4, 0xd1, 0xe2, 0xf2, 0x3a, 0x6d, 0x69, 0x58, 0xb9, 0x4e, 0xa4, 0x15,
- 0x7f, 0xcc, 0xda, 0x1e, 0x8b, 0x92, 0x83, 0x5d, 0xd6, 0xab, 0xd7, 0x6c,
- 0x11, 0xb6, 0xac, 0x5d, 0x33, 0x6d, 0xcf, 0xe6, 0xc3, 0x35, 0x1b, 0x85,
- 0xc6, 0x29, 0xab, 0x4d, 0x5c, 0x33, 0x97, 0xf1, 0x6e, 0xe0, 0x3d, 0x87,
- 0x75, 0xca, 0x61, 0x8d, 0x72, 0xe5, 0x0e, 0x99, 0x3d, 0xa6, 0x3a, 0x1b,
- 0x44, 0x92, 0xe3, 0x5e, 0x87, 0x4c, 0xce, 0x33, 0x96, 0xb0, 0x05, 0x36,
- 0xd8, 0x56, 0x5c, 0x9d, 0x78, 0x66, 0x3b, 0xf0, 0x54, 0x59, 0xa1, 0x6d,
- 0xd3, 0x1a, 0x3b, 0xeb, 0x71, 0x8c, 0xcd, 0x1c, 0xe1, 0x27, 0x80, 0x87,
- 0x2a, 0xef, 0x4c, 0xd5, 0xc4, 0x9f, 0x38, 0x57, 0xad, 0x43, 0x31, 0xdf,
- 0xb8, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x36, 0xbe, 0x19, 0x7b, 0x2a, 0x41,
- 0x7b, 0x2a, 0x5b, 0x72, 0xcd, 0xf9, 0x80, 0x51, 0xf8, 0x4e, 0x5e, 0xef,
- 0x26, 0xd2, 0xfa, 0xd8, 0x0c, 0xe1, 0x8a, 0x85, 0x70, 0xad, 0x58, 0x33,
- 0x9e, 0xe7, 0x5a, 0x1b, 0xe7, 0x98, 0x5a, 0xce, 0x5f, 0x34, 0xb1, 0x7d,
- 0xc6, 0x51, 0x3a, 0xeb, 0xc0, 0x74, 0xa7, 0xb6, 0x61, 0x45, 0x8d, 0xc9,
- 0x81, 0x22, 0xcf, 0x82, 0x31, 0x9e, 0x78, 0x23, 0xe3, 0x49, 0xbd, 0xb3,
- 0xf2, 0x5e, 0x8c, 0xcd, 0x5c, 0x1d, 0x65, 0xe3, 0x37, 0x1b, 0x6c, 0x8e,
- 0x48, 0x6d, 0x0c, 0xc7, 0xe4, 0xf2, 0xac, 0xcc, 0x8b, 0x4e, 0x8d, 0x2e,
- 0x61, 0x9d, 0x7f, 0x5d, 0xef, 0x0d, 0x4a, 0x29, 0x02, 0xed, 0x37, 0x3e,
- 0x90, 0x1a, 0x34, 0xe7, 0x60, 0x92, 0xb2, 0xb3, 0x68, 0xe6, 0x7f, 0x5e,
- 0xe7, 0xf4, 0x98, 0xdc, 0x45, 0x93, 0xef, 0x73, 0x8f, 0x9c, 0x87, 0x0e,
- 0xaf, 0xae, 0x6d, 0x93, 0x4c, 0x02, 0x17, 0x59, 0xbd, 0x2f, 0x91, 0x94,
- 0xec, 0xc0, 0xc7, 0x37, 0xf1, 0x9c, 0x44, 0x0c, 0xeb, 0x93, 0x9f, 0xe1,
- 0xd9, 0x49, 0xf6, 0x7b, 0xb1, 0xbe, 0x28, 0x66, 0x99, 0x87, 0x0f, 0x59,
- 0xf9, 0xb6, 0xbe, 0x44, 0xb3, 0x7e, 0xbf, 0xce, 0xe6, 0x5b, 0x3b, 0x22,
- 0x37, 0x06, 0xf2, 0x87, 0x10, 0x9f, 0x8f, 0xd9, 0x39, 0x25, 0x75, 0xcc,
- 0x4a, 0x82, 0x73, 0x7e, 0xc2, 0xc6, 0x2c, 0x39, 0x97, 0x1b, 0x2c, 0x7d,
- 0x1b, 0xfb, 0xa7, 0x6a, 0x43, 0x9b, 0x7d, 0xbf, 0x27, 0xb5, 0x2c, 0xec,
- 0xb7, 0xb6, 0xb3, 0x8e, 0xf3, 0x1c, 0x17, 0x9d, 0x13, 0x10, 0xfa, 0x46,
- 0x3d, 0x35, 0x7e, 0x81, 0xf1, 0xe5, 0xf2, 0xd3, 0xf5, 0x64, 0x54, 0xd5,
- 0x27, 0xa4, 0x2f, 0x37, 0xb1, 0x8d, 0xdf, 0x2d, 0x08, 0x7d, 0xb9, 0x7e,
- 0xeb, 0xcb, 0xb5, 0x6a, 0x5f, 0xce, 0xc4, 0x1e, 0x5a, 0x97, 0x7d, 0xb9,
- 0xfc, 0x74, 0x0e, 0xb4, 0x12, 0x7e, 0x67, 0xc1, 0xd8, 0x42, 0x93, 0x05,
- 0x9e, 0x79, 0x69, 0x94, 0xec, 0xa8, 0x82, 0xdf, 0x60, 0x7c, 0x2c, 0xc6,
- 0x2a, 0x94, 0xfa, 0x96, 0xf5, 0x2f, 0x3a, 0x25, 0xdd, 0xbe, 0x0e, 0xf3,
- 0xbe, 0x53, 0xaf, 0xf9, 0x5c, 0xc1, 0xec, 0x7d, 0x66, 0xf7, 0x32, 0x26,
- 0xc4, 0x73, 0x4d, 0x9a, 0xbf, 0x92, 0xc3, 0x91, 0x5e, 0x63, 0xcf, 0x7a,
- 0xdf, 0x04, 0xde, 0x4f, 0x02, 0xe7, 0x31, 0x3b, 0x6e, 0x12, 0x30, 0x1d,
- 0xc0, 0xda, 0x5c, 0x6b, 0x65, 0x32, 0xc7, 0xde, 0xd3, 0xc4, 0xd8, 0xc0,
- 0x7c, 0x21, 0x8c, 0x11, 0x46, 0xec, 0x99, 0x4a, 0x2f, 0xd2, 0xe8, 0xad,
- 0xab, 0x6b, 0xab, 0x9e, 0x7e, 0x5d, 0xdd, 0x44, 0x5a, 0xba, 0x53, 0xe7,
- 0xb9, 0xac, 0x1f, 0x48, 0xed, 0xd1, 0x39, 0xf2, 0x3a, 0xc6, 0x98, 0x13,
- 0xe6, 0x94, 0x7d, 0x57, 0xde, 0xa1, 0x65, 0xfe, 0x01, 0x9f, 0xfa, 0x6b,
- 0x87, 0xfe, 0xdd, 0x38, 0x14, 0x04, 0xe7, 0x06, 0xee, 0x86, 0xad, 0xe2,
- 0xb9, 0xdf, 0x97, 0xee, 0xc4, 0xb0, 0xb6, 0x9d, 0xb0, 0x46, 0x7b, 0x9b,
- 0x65, 0x9d, 0x77, 0xb3, 0xcd, 0x99, 0xc9, 0x41, 0x6e, 0xa6, 0x60, 0x33,
- 0xf1, 0x4c, 0x70, 0x8f, 0x7d, 0x97, 0x0b, 0x9a, 0x41, 0x47, 0x1f, 0x13,
- 0x23, 0x63, 0xb2, 0x55, 0x19, 0xc3, 0x5c, 0x83, 0x34, 0x09, 0x39, 0x7a,
- 0x44, 0x52, 0xfc, 0xee, 0x07, 0xc7, 0xce, 0xcb, 0xa5, 0xd0, 0xcb, 0x6c,
- 0xa7, 0xbf, 0xd9, 0x83, 0x67, 0xee, 0xe1, 0x78, 0xee, 0x41, 0xe8, 0x96,
- 0xeb, 0xd7, 0xea, 0x96, 0x04, 0xfd, 0xfa, 0x6c, 0x89, 0xbe, 0xe1, 0x7a,
- 0xb4, 0xe9, 0x90, 0x8f, 0x4f, 0x77, 0xb7, 0x91, 0xb7, 0xc6, 0x20, 0xd7,
- 0xd5, 0xfd, 0xe1, 0x59, 0x20, 0x96, 0xf1, 0x3d, 0xfb, 0x6d, 0x92, 0xe4,
- 0xfb, 0x5d, 0xf9, 0x7c, 0x25, 0x95, 0x5c, 0x82, 0x6e, 0x1a, 0x73, 0x7e,
- 0xf1, 0x72, 0x13, 0x53, 0x7d, 0x7b, 0x9b, 0x39, 0x3b, 0xd0, 0x4c, 0x9b,
- 0xdd, 0xc6, 0x59, 0x6b, 0x69, 0x76, 0xc9, 0xca, 0xe3, 0x20, 0x68, 0x1e,
- 0xd0, 0x32, 0x78, 0x0f, 0x65, 0xf0, 0x01, 0xbf, 0xc7, 0xd0, 0xbe, 0xf6,
- 0x99, 0x02, 0xac, 0x23, 0xf0, 0x30, 0x10, 0x65, 0x7e, 0x9e, 0xe5, 0x4f,
- 0x2f, 0xbd, 0x68, 0xe5, 0x92, 0x72, 0xd6, 0xf2, 0xa5, 0xba, 0x2a, 0xb6,
- 0x42, 0xe6, 0x1e, 0x9a, 0xa6, 0x3e, 0xf6, 0x17, 0xbe, 0x0b, 0x39, 0x95,
- 0xd5, 0x78, 0xe8, 0x90, 0xfb, 0xa6, 0x25, 0x7d, 0x1e, 0xba, 0x2a, 0x3f,
- 0xbf, 0x92, 0x37, 0xd7, 0xf6, 0xc7, 0xb9, 0x7e, 0xb8, 0xcd, 0xf8, 0xb6,
- 0x2b, 0xe7, 0xba, 0x80, 0xb9, 0xa6, 0xf5, 0x5c, 0xb9, 0x6f, 0xf3, 0x31,
- 0x3b, 0xd7, 0xf5, 0xe1, 0x5c, 0x07, 0x57, 0xce, 0x35, 0xf4, 0xed, 0x43,
- 0xb9, 0x9b, 0xd4, 0xf9, 0xf2, 0x3a, 0x4f, 0x7b, 0x7a, 0xbd, 0x0c, 0x97,
- 0x5a, 0xad, 0xbc, 0x74, 0xa1, 0x7b, 0x98, 0xc3, 0xbe, 0x70, 0xaf, 0x2b,
- 0x16, 0x67, 0x8a, 0x78, 0xa0, 0xac, 0x6d, 0xd3, 0x67, 0x6c, 0x66, 0xe1,
- 0x5f, 0xdd, 0x5a, 0x60, 0xdd, 0xf0, 0xfd, 0xc5, 0x62, 0xc7, 0xa1, 0x4f,
- 0x4d, 0xbf, 0xa9, 0x77, 0x4d, 0x4c, 0xc1, 0xc4, 0x87, 0x19, 0x17, 0x36,
- 0x67, 0x7f, 0x99, 0x8b, 0x78, 0x07, 0x78, 0xea, 0x53, 0x85, 0xd4, 0x60,
- 0x26, 0x42, 0x39, 0x7a, 0x5c, 0x0e, 0x55, 0x46, 0xa4, 0x4b, 0x9f, 0xff,
- 0x7c, 0xdd, 0xd8, 0x71, 0xba, 0x36, 0x76, 0xcc, 0x74, 0x02, 0xc6, 0x8e,
- 0xf7, 0xfc, 0x0c, 0xb1, 0x63, 0x71, 0x4c, 0xec, 0xb8, 0x9e, 0x7f, 0x35,
- 0x55, 0x3c, 0x8e, 0x79, 0x35, 0x43, 0x96, 0x2c, 0x3a, 0xd9, 0xf9, 0x16,
- 0xdc, 0xcf, 0xe2, 0x1e, 0xc3, 0xfd, 0x3c, 0xee, 0x2e, 0xee, 0x17, 0x70,
- 0x8f, 0xcb, 0xd4, 0xb2, 0xce, 0x38, 0x0e, 0xb9, 0x41, 0x5d, 0xc6, 0xb6,
- 0xc6, 0x1f, 0x98, 0x2b, 0xb7, 0xf3, 0x7b, 0x2d, 0xce, 0xec, 0x3c, 0xe7,
- 0xd0, 0x2a, 0x93, 0xd3, 0x94, 0xd9, 0x6d, 0x52, 0x9a, 0x0e, 0x6d, 0xdb,
- 0x9f, 0xef, 0xe0, 0x9e, 0xc1, 0x98, 0x84, 0xb6, 0xeb, 0x3d, 0x1d, 0x66,
- 0xaf, 0xf1, 0x3b, 0x58, 0xe3, 0x8d, 0x58, 0x83, 0x93, 0x72, 0x7e, 0x66,
- 0xe3, 0x0a, 0x1b, 0x36, 0x69, 0x63, 0x82, 0x33, 0x56, 0xf7, 0xd6, 0x97,
- 0x11, 0xb5, 0xeb, 0x9f, 0xb0, 0x67, 0xcb, 0xc2, 0x1c, 0xa1, 0xa4, 0x5e,
- 0x9f, 0xd1, 0xca, 0x71, 0x8c, 0x37, 0x28, 0xe9, 0x19, 0xce, 0x73, 0xf9,
- 0x9b, 0x11, 0x90, 0x87, 0x27, 0xa0, 0x57, 0x57, 0xd0, 0x25, 0xe8, 0x96,
- 0x73, 0x73, 0x40, 0xbb, 0x8f, 0xca, 0x6c, 0x89, 0xf0, 0xf5, 0x24, 0x22,
- 0xfa, 0xac, 0x19, 0x9e, 0x67, 0x4c, 0x8e, 0xfb, 0x70, 0x25, 0x3c, 0x67,
- 0xb6, 0x89, 0x67, 0x07, 0x57, 0x9d, 0x35, 0xb3, 0xfa, 0x59, 0xdb, 0x0e,
- 0x3c, 0x73, 0x16, 0xce, 0xa1, 0x1e, 0x3d, 0x05, 0x32, 0xa9, 0xf3, 0xce,
- 0x36, 0xcb, 0x63, 0x0f, 0x2e, 0xe7, 0xbc, 0xb6, 0xc1, 0x46, 0xe9, 0x84,
- 0x89, 0x3c, 0x1a, 0x1d, 0xea, 0x81, 0x8f, 0xc7, 0x3c, 0x99, 0x9e, 0xc4,
- 0x6d, 0x3a, 0x17, 0xb9, 0x7a, 0xee, 0xaf, 0x9a, 0x8f, 0x1c, 0x9e, 0xb3,
- 0x4a, 0xe8, 0xef, 0x5a, 0xec, 0xd4, 0xe5, 0x71, 0xcc, 0x87, 0xfb, 0x7e,
- 0x1a, 0x0f, 0x09, 0x7e, 0xa7, 0xeb, 0x29, 0xe0, 0x60, 0xb2, 0xf2, 0x6d,
- 0xd0, 0xbb, 0x63, 0xcf, 0x9c, 0x91, 0xc6, 0x06, 0x64, 0xa2, 0x9c, 0x70,
- 0x26, 0xca, 0x03, 0xce, 0xbe, 0xb2, 0x7d, 0x37, 0xb0, 0x67, 0xb3, 0x34,
- 0xe3, 0xf7, 0x4c, 0x97, 0x33, 0x06, 0x7c, 0xe5, 0x8b, 0xdd, 0x4e, 0x5a,
- 0xdf, 0x3d, 0x7b, 0x87, 0x1c, 0xc0, 0x5a, 0x0d, 0xcf, 0xc4, 0xb5, 0x9c,
- 0xaf, 0x7e, 0x5b, 0x2a, 0x5c, 0x57, 0x7e, 0x13, 0x89, 0x7c, 0x7c, 0x5c,
- 0x7f, 0xe7, 0xc8, 0xd8, 0x0e, 0x27, 0xd1, 0xdf, 0x71, 0x1b, 0x13, 0xef,
- 0x73, 0xb2, 0xba, 0x1f, 0xb3, 0x1e, 0xf9, 0xe2, 0x09, 0xdc, 0x57, 0x9f,
- 0x79, 0x0e, 0xf5, 0x8c, 0x85, 0xbb, 0x10, 0xdc, 0x63, 0xe4, 0xd5, 0x71,
- 0x99, 0xaa, 0x30, 0x7f, 0xc4, 0xd1, 0x7c, 0x34, 0x59, 0x3e, 0x00, 0x9d,
- 0xb4, 0xf2, 0xcc, 0xdf, 0xce, 0xea, 0x3a, 0x24, 0x67, 0x84, 0xb0, 0x70,
- 0x0d, 0x56, 0x9e, 0x87, 0xbf, 0xf8, 0xbf, 0x70, 0x5f, 0xd1, 0xc8, 0x50,
- 0x0b, 0x47, 0x9a, 0xf2, 0xce, 0xc8, 0x95, 0x69, 0x39, 0x08, 0x78, 0x0e,
- 0xe3, 0x52, 0xf7, 0xf3, 0x3b, 0x2c, 0xf3, 0x92, 0x9f, 0xbb, 0x4f, 0xd4,
- 0x43, 0xe7, 0x9d, 0xe8, 0x43, 0x07, 0x25, 0xf2, 0xd0, 0xa2, 0xd3, 0xf0,
- 0x50, 0xb7, 0xf6, 0xcb, 0x77, 0xfb, 0xdd, 0x89, 0x7d, 0x72, 0x52, 0xa2,
- 0xf7, 0x2b, 0x7d, 0xfe, 0x2b, 0xef, 0x32, 0xc6, 0x77, 0x52, 0x22, 0xf7,
- 0xc7, 0xec, 0xd9, 0x51, 0x13, 0xd7, 0x5b, 0xd2, 0x7c, 0xff, 0x9b, 0x71,
- 0xe2, 0x6c, 0x49, 0x8e, 0x6b, 0xde, 0x19, 0x86, 0x9e, 0xc8, 0x94, 0x92,
- 0xcb, 0x75, 0x4c, 0xbe, 0xe7, 0xf3, 0x9b, 0x0d, 0xbf, 0xb0, 0x4e, 0x8f,
- 0xc3, 0xef, 0x38, 0x18, 0x9d, 0x91, 0xb9, 0x2c, 0xcc, 0xfd, 0x34, 0x6b,
- 0xca, 0xf7, 0x67, 0xb1, 0x86, 0x3d, 0x58, 0x2f, 0x8e, 0xe7, 0xe8, 0xfd,
- 0x5c, 0x9e, 0x9d, 0x75, 0xa5, 0x2f, 0xd1, 0xb4, 0x6c, 0x07, 0xb1, 0xee,
- 0x7d, 0xd2, 0x04, 0xb8, 0xd5, 0x43, 0x79, 0x63, 0xd7, 0x09, 0xe9, 0x54,
- 0x20, 0xb9, 0x49, 0xb3, 0x3d, 0x83, 0xbb, 0xf5, 0x1a, 0xde, 0x6b, 0x69,
- 0x66, 0x9d, 0xb1, 0x1f, 0xf1, 0x6c, 0xe8, 0x22, 0x2f, 0xbb, 0xa6, 0x7f,
- 0x08, 0x3d, 0xcf, 0x7d, 0x17, 0x6d, 0x2f, 0xd6, 0xb1, 0x05, 0xc9, 0x4b,
- 0xcf, 0x58, 0xbf, 0x32, 0x08, 0xa6, 0x7d, 0x1f, 0x78, 0xac, 0xe7, 0x4b,
- 0x6e, 0x71, 0xe6, 0x4a, 0x5b, 0x9d, 0xd9, 0x52, 0x20, 0x13, 0x3e, 0xbf,
- 0xe3, 0xc1, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x86, 0x6e, 0xfd, 0xeb,
- 0xcd, 0x3c, 0x8f, 0x74, 0x93, 0xf7, 0xa2, 0x98, 0x7a, 0xc4, 0x31, 0x7d,
- 0xe4, 0xee, 0xe3, 0x59, 0xe1, 0xf7, 0x34, 0xfa, 0x12, 0x71, 0xfd, 0x5d,
- 0x8f, 0xcf, 0xa1, 0x1d, 0xc6, 0x28, 0x72, 0xdc, 0x67, 0x9d, 0x59, 0xc8,
- 0xb3, 0xb9, 0x69, 0x9e, 0xe1, 0x67, 0x3e, 0x6d, 0xa4, 0x53, 0xc9, 0x15,
- 0xee, 0xa4, 0xfd, 0x06, 0x5c, 0x0e, 0x2e, 0x50, 0x44, 0x97, 0xf5, 0xb9,
- 0xe3, 0xcb, 0xdf, 0x85, 0x0b, 0xcb, 0xc2, 0xef, 0xc3, 0x29, 0x9d, 0x3b,
- 0x0d, 0x5f, 0xf6, 0xb1, 0x31, 0xf9, 0x89, 0x33, 0x5f, 0x78, 0xc5, 0x79,
- 0xb4, 0x90, 0xbe, 0xea, 0x12, 0xd0, 0xc7, 0x39, 0xbf, 0x97, 0xf2, 0x0b,
- 0x36, 0x5f, 0x41, 0x72, 0x95, 0x09, 0x99, 0xe9, 0xe8, 0x76, 0xef, 0xd7,
- 0x6b, 0x33, 0x03, 0x9c, 0x7d, 0x1b, 0xeb, 0xf7, 0xc9, 0x38, 0xf5, 0xdb,
- 0x78, 0x41, 0x81, 0x97, 0xd5, 0xcf, 0xe3, 0x82, 0x6d, 0xdb, 0xa8, 0x6d,
- 0x94, 0x7d, 0x3e, 0xeb, 0x6d, 0x75, 0x86, 0x4b, 0x5b, 0xb0, 0x8e, 0x7b,
- 0xa1, 0x3f, 0x1d, 0xd8, 0x69, 0xa0, 0x6d, 0x94, 0x4d, 0x02, 0x07, 0xe3,
- 0xbe, 0x91, 0xe7, 0xc3, 0x92, 0xd3, 0x3e, 0x9e, 0xb9, 0xa7, 0x95, 0x89,
- 0x99, 0x05, 0xc1, 0x1c, 0xec, 0x83, 0x6c, 0x7f, 0x09, 0xbc, 0xf0, 0x08,
- 0xae, 0xb7, 0xdb, 0x3d, 0xed, 0x17, 0x2e, 0xb2, 0xa7, 0xed, 0xca, 0xc9,
- 0x8a, 0x3e, 0xd7, 0xae, 0xf3, 0xab, 0x92, 0xea, 0xbf, 0x5f, 0xa2, 0xd7,
- 0x4a, 0xf5, 0xe8, 0x9c, 0xb4, 0xb4, 0x7c, 0x38, 0x6e, 0xf4, 0x30, 0x61,
- 0x4a, 0x02, 0x9e, 0xad, 0xc0, 0x05, 0xe1, 0x31, 0x6d, 0x44, 0x6d, 0xba,
- 0x94, 0xfa, 0x70, 0x49, 0x3e, 0x12, 0x0f, 0xcf, 0x14, 0xa0, 0x1f, 0xc8,
- 0xb8, 0x8f, 0x5d, 0x6a, 0xf4, 0xe4, 0xe6, 0x3a, 0xfd, 0x84, 0x73, 0x73,
- 0xec, 0xdc, 0x48, 0xb7, 0x7f, 0x96, 0xa0, 0x4f, 0xb1, 0x24, 0x4d, 0xab,
- 0xea, 0x33, 0xa6, 0xbf, 0xe1, 0x72, 0x73, 0x46, 0x81, 0x75, 0x5d, 0xd8,
- 0xa6, 0xb4, 0x73, 0x89, 0x47, 0xbd, 0x6e, 0x05, 0x25, 0x3c, 0x67, 0x00,
- 0x6e, 0xae, 0x5c, 0xe1, 0xbe, 0x43, 0x91, 0x0e, 0x43, 0x5c, 0x7f, 0x5b,
- 0xf3, 0xc9, 0x78, 0x81, 0xb1, 0x95, 0x47, 0x83, 0xf4, 0x28, 0x79, 0x8c,
- 0x7d, 0xf0, 0x7d, 0x41, 0xc7, 0x73, 0xf7, 0xfa, 0x8c, 0x15, 0x75, 0x1f,
- 0xbf, 0x43, 0x85, 0x72, 0x0a, 0xfa, 0xb7, 0xb8, 0xe8, 0xf0, 0x1b, 0x78,
- 0x37, 0x0a, 0xee, 0xf3, 0x8b, 0xce, 0x77, 0xa7, 0x9f, 0xc5, 0x73, 0x83,
- 0xfd, 0xee, 0x9d, 0xd1, 0x53, 0x22, 0xc5, 0x70, 0xbe, 0x89, 0x1c, 0xd6,
- 0xfe, 0x02, 0xd6, 0xbe, 0xfe, 0x77, 0xee, 0xf0, 0xae, 0x8c, 0x77, 0xe5,
- 0x0f, 0x07, 0xe9, 0x36, 0xd2, 0x22, 0xe9, 0xef, 0xb5, 0xfc, 0xe6, 0x41,
- 0xcd, 0x17, 0x93, 0xc5, 0xc7, 0xc1, 0x17, 0x69, 0xee, 0x37, 0x07, 0x0f,
- 0xfb, 0x37, 0x80, 0x2f, 0xf6, 0xc8, 0xef, 0xc3, 0x2e, 0xf8, 0xdd, 0xca,
- 0x10, 0xf8, 0x63, 0x10, 0xfc, 0x32, 0x00, 0x1e, 0xf1, 0xb5, 0x8d, 0xfc,
- 0x04, 0xf4, 0x1f, 0xf4, 0x9a, 0xb3, 0xaf, 0xd4, 0xe5, 0x64, 0x4b, 0x9e,
- 0x33, 0x51, 0xe2, 0xf7, 0x5a, 0xd4, 0x5b, 0x1b, 0x24, 0x9a, 0x98, 0x13,
- 0xf2, 0x42, 0x37, 0x73, 0x1c, 0xdb, 0x81, 0xab, 0x53, 0xc4, 0xd5, 0x5c,
- 0xa5, 0xcf, 0xbd, 0x04, 0x3c, 0xd1, 0xae, 0x79, 0xa2, 0xd5, 0x49, 0xbb,
- 0x37, 0x58, 0x9e, 0x78, 0x11, 0x3c, 0x71, 0x7e, 0x0d, 0x4f, 0x3c, 0x6d,
- 0xe9, 0x7f, 0xa1, 0x86, 0x27, 0xe6, 0x6c, 0xd9, 0xcc, 0x45, 0x78, 0xe2,
- 0x52, 0x2f, 0xf5, 0xa5, 0x31, 0x79, 0x15, 0x3c, 0x21, 0x8a, 0x3c, 0x71,
- 0xa9, 0xe6, 0x09, 0xc6, 0x8e, 0xc8, 0x17, 0x9d, 0x90, 0x23, 0xe4, 0x8b,
- 0xb3, 0xb2, 0x04, 0xbe, 0x78, 0x5e, 0x71, 0xec, 0x19, 0xda, 0x0a, 0x25,
- 0xfa, 0x64, 0x27, 0x8a, 0x5d, 0xe0, 0x77, 0x25, 0xff, 0x65, 0x3a, 0x08,
- 0x16, 0xe1, 0xa7, 0x3f, 0x08, 0x7b, 0x3e, 0xaa, 0xbf, 0xa9, 0xb8, 0x00,
- 0xba, 0x0f, 0xe9, 0x7d, 0xc2, 0x01, 0xbd, 0x1f, 0x9e, 0xc5, 0x1c, 0x26,
- 0xd4, 0x7f, 0x86, 0x2f, 0xec, 0x62, 0x5d, 0x69, 0xe7, 0x1f, 0xd3, 0x3c,
- 0xd4, 0x00, 0x7d, 0xf0, 0xe8, 0x00, 0x63, 0x4d, 0x9e, 0xbb, 0x4f, 0x75,
- 0xe7, 0x46, 0x00, 0x73, 0x44, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xad, 0xb2,
- 0xf3, 0x29, 0x23, 0x46, 0x21, 0xeb, 0xcc, 0xbb, 0x5c, 0xd0, 0x04, 0x9b,
- 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x48, 0xb9, 0x1f, 0x84, 0x00, 0x6d,
- 0x84, 0xbd, 0xb0, 0x0b, 0xab, 0x3d, 0x52, 0xa8, 0xb5, 0xf1, 0xff, 0x03,
- 0x6c, 0x7c, 0xb6, 0x91, 0xa8, 0xb1, 0xf1, 0x7f, 0xcd, 0xf2, 0x1a, 0x7f,
- 0xbb, 0xda, 0xde, 0x3f, 0x00, 0xf8, 0x76, 0x2f, 0xdb, 0xfb, 0xec, 0x83,
- 0x76, 0x87, 0xc8, 0xf5, 0xb0, 0xf9, 0xde, 0x0d, 0x1e, 0xbc, 0x01, 0xbe,
- 0xd4, 0x7b, 0x0a, 0xae, 0xec, 0x29, 0xb4, 0xc3, 0xe7, 0xee, 0x94, 0xf7,
- 0x4e, 0x6f, 0x95, 0x9d, 0x25, 0xff, 0x12, 0x69, 0xee, 0x80, 0x8d, 0x5a,
- 0x00, 0x9c, 0x11, 0x2b, 0xb7, 0xcf, 0x02, 0x6f, 0xdd, 0xc9, 0x9f, 0xa8,
- 0x17, 0xad, 0x5d, 0xc4, 0xb3, 0x8e, 0xf5, 0xfa, 0x89, 0xa3, 0x3d, 0x63,
- 0x29, 0x1d, 0x72, 0xea, 0x18, 0xbd, 0xaf, 0x24, 0xec, 0x72, 0x1f, 0x36,
- 0xc9, 0x16, 0xf4, 0xc7, 0x78, 0xf2, 0x46, 0x79, 0xfa, 0xaa, 0xe8, 0x5d,
- 0x59, 0xcd, 0x87, 0x9d, 0x4e, 0x66, 0x1a, 0x3e, 0xc0, 0xde, 0x18, 0xe6,
- 0xa0, 0xda, 0x37, 0xcb, 0x75, 0xb2, 0x53, 0xcf, 0x67, 0x46, 0x0e, 0x42,
- 0x37, 0xff, 0x41, 0x61, 0xa7, 0x2c, 0x8d, 0xb6, 0xe1, 0x39, 0x26, 0x4f,
- 0x17, 0xfa, 0xe0, 0xfb, 0xbc, 0x0b, 0x38, 0x6a, 0xc4, 0x73, 0xa3, 0x0c,
- 0x5f, 0x42, 0x5e, 0x6d, 0x91, 0x45, 0x94, 0xbf, 0x5b, 0x7e, 0xc1, 0x96,
- 0xb3, 0x8c, 0xbc, 0xd1, 0x82, 0xb6, 0x31, 0x39, 0x57, 0xa0, 0x5d, 0xa9,
- 0x79, 0x62, 0xf0, 0x7b, 0xd2, 0x97, 0xfe, 0x1e, 0xec, 0xd4, 0xb3, 0xb8,
- 0x9e, 0x91, 0xd4, 0x9e, 0x71, 0xa7, 0x2f, 0xd9, 0xed, 0x40, 0x77, 0xe2,
- 0x8a, 0x3a, 0x7d, 0x6e, 0xa3, 0x73, 0x85, 0xed, 0xa3, 0x41, 0x9e, 0xd9,
- 0xab, 0x12, 0x2d, 0x58, 0x93, 0xed, 0x4e, 0x8f, 0x2d, 0xe3, 0x73, 0xca,
- 0x78, 0x40, 0xa7, 0xd4, 0x96, 0x0d, 0x22, 0x5d, 0x2d, 0xb0, 0x79, 0x26,
- 0x44, 0xb5, 0xb7, 0x48, 0x54, 0xba, 0x67, 0x55, 0x27, 0xca, 0x3c, 0x5b,
- 0x16, 0x6f, 0x81, 0x7e, 0x40, 0x59, 0x07, 0xca, 0xb6, 0xd9, 0xb2, 0xb6,
- 0x16, 0x69, 0x44, 0xd9, 0x8c, 0xe6, 0xf9, 0xf3, 0x3d, 0x9e, 0x9b, 0x75,
- 0x9a, 0xa5, 0xeb, 0x44, 0x0b, 0x64, 0xc3, 0x46, 0x59, 0xbc, 0xaa, 0x49,
- 0xba, 0xf0, 0x8e, 0x71, 0x6e, 0xff, 0x44, 0x4c, 0xae, 0x3d, 0xd1, 0x9d,
- 0xf8, 0x38, 0xe6, 0xd0, 0x7d, 0x8a, 0x71, 0xef, 0xfc, 0x25, 0x8c, 0xfb,
- 0x74, 0x9d, 0xe2, 0xbd, 0x49, 0xcb, 0x1f, 0xe2, 0xc3, 0x7c, 0x93, 0x88,
- 0x32, 0xf9, 0x24, 0xfc, 0x5c, 0xea, 0xf0, 0x6e, 0xfb, 0xfd, 0x8c, 0xe3,
- 0x97, 0xd0, 0x6f, 0x9b, 0xa5, 0x5d, 0x52, 0x24, 0x3f, 0x52, 0x0f, 0xe1,
- 0x3e, 0xe3, 0x48, 0xbe, 0x2a, 0xb3, 0xe6, 0xc9, 0x57, 0xc7, 0x14, 0x73,
- 0x59, 0x50, 0x56, 0xf9, 0xc5, 0xc0, 0xac, 0x31, 0x79, 0xc1, 0xc8, 0xa5,
- 0x0f, 0x18, 0xb9, 0xf4, 0xd8, 0x99, 0x15, 0x72, 0xe9, 0xbc, 0x96, 0x4b,
- 0x7b, 0x05, 0xf7, 0xf9, 0xf3, 0x90, 0x4b, 0x2f, 0xe2, 0xd9, 0xd5, 0x72,
- 0x29, 0x2e, 0xd6, 0x5e, 0x96, 0xaf, 0xea, 0xf1, 0xe7, 0x8a, 0x51, 0x6d,
- 0x57, 0xe5, 0x67, 0x60, 0x93, 0x14, 0xa7, 0xac, 0xfe, 0x96, 0xa1, 0x36,
- 0xe9, 0x19, 0xfc, 0xa9, 0x84, 0x36, 0xe7, 0x7f, 0xba, 0x84, 0xdf, 0xee,
- 0x7c, 0x5e, 0x51, 0x86, 0xbd, 0x0a, 0x19, 0x26, 0xaa, 0xbe, 0x0c, 0xc3,
- 0xbb, 0x32, 0xde, 0x95, 0xd9, 0xef, 0x8f, 0x7e, 0x3a, 0xe6, 0x52, 0x7e,
- 0x50, 0x66, 0x40, 0x26, 0x15, 0x21, 0x93, 0x8a, 0x90, 0x53, 0x45, 0xc8,
- 0x25, 0xd8, 0x6c, 0x67, 0x8a, 0x90, 0x4b, 0x45, 0xc8, 0x25, 0xc8, 0xb8,
- 0x27, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x85, 0x4c, 0x9b, 0x91, 0xfb, 0xac,
- 0xae, 0x37, 0xb1, 0x92, 0x7e, 0xeb, 0x23, 0x0d, 0xe8, 0x18, 0xf2, 0x99,
- 0x9a, 0xd8, 0xe0, 0x8d, 0x47, 0x34, 0xbf, 0xbb, 0x9e, 0xba, 0xc2, 0x61,
- 0x0e, 0xcd, 0x4f, 0xb4, 0xff, 0xbe, 0x9d, 0xbf, 0xa5, 0x09, 0x7c, 0xfd,
- 0x03, 0xcb, 0xd7, 0xdb, 0x97, 0xf9, 0x3a, 0xe5, 0x30, 0x56, 0x5c, 0x9f,
- 0xaf, 0x3b, 0xec, 0xbb, 0x5c, 0xb0, 0x0e, 0x7c, 0xbd, 0x6e, 0x15, 0x5f,
- 0xc7, 0xc0, 0xd7, 0x7b, 0xd6, 0xf0, 0xf5, 0x06, 0x67, 0x58, 0xb7, 0xe1,
- 0x19, 0x09, 0x3e, 0x37, 0x3a, 0x55, 0xbe, 0xbe, 0x47, 0xf3, 0xf5, 0x21,
- 0xf0, 0xf5, 0x75, 0x35, 0x7c, 0xbd, 0x47, 0x52, 0x37, 0x67, 0x22, 0x5b,
- 0x65, 0xfc, 0x7e, 0xd5, 0xbe, 0x49, 0xfe, 0x49, 0x4c, 0x7b, 0xc3, 0x63,
- 0xc3, 0xd3, 0xed, 0x92, 0x7d, 0xe8, 0x15, 0x94, 0x91, 0xcf, 0x52, 0x63,
- 0x69, 0xc7, 0x95, 0x83, 0x47, 0x7e, 0x22, 0x0b, 0x9a, 0xb7, 0x44, 0x26,
- 0x8e, 0xc4, 0x64, 0xf2, 0x08, 0xe3, 0x10, 0x7f, 0x63, 0xe9, 0xbd, 0x49,
- 0x26, 0xf7, 0x32, 0x6f, 0x2e, 0x2a, 0xe3, 0x47, 0xe0, 0x6f, 0x1d, 0x61,
- 0x1c, 0xe2, 0xa5, 0x65, 0x1e, 0x5b, 0x80, 0x6c, 0x19, 0x3f, 0xc2, 0xb5,
- 0x8e, 0xa1, 0x9f, 0x16, 0x39, 0x74, 0x44, 0xe4, 0xb6, 0x23, 0x51, 0xf9,
- 0xe8, 0x91, 0x65, 0x5e, 0x1b, 0x0d, 0x79, 0xed, 0x59, 0xf0, 0x5a, 0xb7,
- 0xe5, 0x35, 0xb5, 0xcc, 0x6b, 0x7f, 0x5a, 0xc3, 0x6b, 0x6c, 0x4f, 0x5e,
- 0x7b, 0xce, 0x96, 0xf1, 0x39, 0x2a, 0xfb, 0x8e, 0x74, 0xca, 0xf8, 0x43,
- 0x6f, 0x91, 0x89, 0xfb, 0x09, 0xab, 0xf9, 0x8e, 0x13, 0x6d, 0xb1, 0x99,
- 0x4a, 0x37, 0xfa, 0x0f, 0x73, 0x88, 0xf4, 0xf7, 0x10, 0x7a, 0x67, 0x25,
- 0x95, 0xe3, 0x78, 0x8d, 0xf0, 0xa3, 0x4f, 0xc0, 0xbf, 0xd8, 0x07, 0x98,
- 0x6e, 0x39, 0x22, 0xa9, 0xa8, 0xbc, 0x2c, 0x53, 0xfe, 0x27, 0x2e, 0x37,
- 0xf6, 0x04, 0x6c, 0x11, 0x6d, 0xfb, 0xa4, 0x25, 0xfb, 0xce, 0x40, 0xfb,
- 0x18, 0xa5, 0xb2, 0x30, 0x16, 0xc0, 0xb8, 0xb9, 0x63, 0xbe, 0xc7, 0xc4,
- 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0x07, 0xf8, 0x9e, 0xcf,
- 0xb0, 0x67, 0xf4, 0x59, 0x43, 0xb6, 0x7f, 0x44, 0x7f, 0x1b, 0x91, 0x31,
- 0xf5, 0x7c, 0x99, 0xdf, 0xb0, 0x81, 0xff, 0x59, 0xe6, 0xb7, 0xb0, 0xf6,
- 0xb7, 0x9b, 0xf8, 0x2c, 0xf9, 0xee, 0x87, 0x0e, 0xbf, 0x5d, 0x35, 0xa5,
- 0x73, 0xbd, 0xf0, 0xbb, 0xcc, 0x67, 0xd6, 0x7f, 0x84, 0xf1, 0x8e, 0x64,
- 0x52, 0xbd, 0xf7, 0x72, 0xe6, 0x1e, 0xec, 0x9d, 0x67, 0xdd, 0xad, 0x96,
- 0x47, 0xb7, 0x6a, 0xbf, 0x83, 0x36, 0xd6, 0x78, 0xe9, 0x45, 0xc9, 0xd3,
- 0x36, 0x19, 0xdd, 0xea, 0xe4, 0x66, 0x92, 0x97, 0x1b, 0xfb, 0x79, 0xdd,
- 0xa5, 0xcc, 0x3b, 0x4c, 0xab, 0xb5, 0x32, 0xf9, 0x84, 0x84, 0x32, 0x39,
- 0x75, 0x33, 0xbf, 0xb7, 0x9b, 0x3d, 0xa2, 0xbf, 0x2f, 0x95, 0xec, 0x56,
- 0x9c, 0xd3, 0xa7, 0x21, 0x5f, 0x43, 0x5a, 0x48, 0xc8, 0x27, 0x8f, 0x90,
- 0x1e, 0x54, 0xbc, 0x55, 0x3e, 0x61, 0xe9, 0x61, 0x46, 0x0a, 0x90, 0x3b,
- 0x47, 0x8e, 0x7c, 0x54, 0x66, 0x6e, 0x5c, 0x4d, 0x0f, 0x13, 0x55, 0x7a,
- 0x88, 0xc3, 0x3e, 0x73, 0x6a, 0xe9, 0xe1, 0x97, 0x97, 0xe9, 0x61, 0xc6,
- 0xf9, 0xe7, 0xd2, 0xc3, 0xf5, 0x2b, 0xe8, 0x61, 0x4a, 0xd3, 0xc3, 0xce,
- 0x65, 0x7a, 0x98, 0x3a, 0xc2, 0x71, 0xf5, 0xde, 0xa8, 0xbb, 0xe8, 0x70,
- 0xcd, 0x97, 0x69, 0x21, 0x39, 0xa9, 0xf3, 0xf5, 0x53, 0x39, 0x9e, 0x6f,
- 0xda, 0xa0, 0x18, 0x27, 0xa9, 0xae, 0x7f, 0xeb, 0xbf, 0xe8, 0xfa, 0xbf,
- 0xfc, 0xff, 0x79, 0xfd, 0xd5, 0xa5, 0xcc, 0xdd, 0xe7, 0x99, 0x55, 0x23,
- 0x8f, 0x43, 0x7a, 0x88, 0x5d, 0x6a, 0xf4, 0x02, 0xd7, 0x98, 0xcf, 0x90,
- 0x67, 0x90, 0x7f, 0x67, 0x20, 0xff, 0x9e, 0x84, 0xfc, 0x3b, 0xbd, 0x62,
- 0x4f, 0x60, 0xd0, 0xc6, 0x23, 0x02, 0x39, 0xe8, 0x57, 0xf1, 0xb1, 0x38,
- 0x40, 0x7c, 0x98, 0xfc, 0x13, 0xe6, 0xfe, 0xae, 0xc4, 0x49, 0x54, 0xe7,
- 0x1c, 0x3d, 0xea, 0xd7, 0xe2, 0x84, 0x70, 0xbf, 0x5c, 0x33, 0x47, 0xfc,
- 0x2e, 0xf3, 0x79, 0x46, 0xe7, 0x91, 0xe4, 0xf5, 0x1e, 0x14, 0xf1, 0xc2,
- 0x3d, 0x28, 0xe2, 0x24, 0xaa, 0xed, 0xfd, 0x7c, 0xb9, 0x49, 0xe7, 0xd0,
- 0x1f, 0x98, 0x8f, 0xcb, 0x62, 0x9c, 0x31, 0x3e, 0x7e, 0x97, 0x90, 0x7e,
- 0xb3, 0x97, 0xc8, 0x4b, 0x8e, 0xb9, 0x72, 0xe0, 0xe9, 0x0d, 0x96, 0xb6,
- 0x19, 0x1b, 0xe4, 0x99, 0xdd, 0x70, 0x2f, 0xa2, 0xd7, 0xca, 0xba, 0x96,
- 0x9a, 0x98, 0x25, 0xf0, 0x3e, 0x2d, 0xc9, 0xcc, 0x00, 0xee, 0xf3, 0x1c,
- 0x7b, 0xbf, 0x4c, 0x3d, 0x38, 0x01, 0x5b, 0x6e, 0x2f, 0x74, 0x0e, 0xcf,
- 0x9f, 0x99, 0xef, 0x70, 0x13, 0x86, 0x59, 0xfd, 0xdd, 0x29, 0xfa, 0x80,
- 0xa4, 0x87, 0x04, 0x9e, 0x67, 0x6c, 0x5c, 0x29, 0x21, 0xf9, 0xc2, 0x05,
- 0xf3, 0x6d, 0xcb, 0xc2, 0x4b, 0xb8, 0xbf, 0xde, 0x7a, 0x18, 0x3f, 0x64,
- 0xd4, 0xdc, 0xd1, 0xd7, 0x92, 0xa4, 0xcb, 0x26, 0xc7, 0xa5, 0x1a, 0x37,
- 0x99, 0x91, 0xc3, 0xda, 0x7e, 0x1e, 0xb2, 0xb9, 0x2d, 0xa9, 0xd1, 0x9c,
- 0x18, 0x1b, 0xfa, 0x77, 0x60, 0x43, 0x7f, 0xb1, 0x92, 0xd6, 0xfb, 0x58,
- 0xa7, 0x61, 0x43, 0x3f, 0x01, 0xdd, 0x43, 0x9d, 0x13, 0xb7, 0x3a, 0x67,
- 0x4a, 0xdd, 0xa8, 0x75, 0xce, 0x37, 0xb5, 0xce, 0x79, 0xef, 0x1a, 0x9d,
- 0x73, 0x48, 0x75, 0x97, 0xa8, 0x73, 0x86, 0xd5, 0x1e, 0x87, 0xf6, 0xe2,
- 0xe6, 0x3a, 0x3a, 0xe7, 0x7d, 0xf2, 0x2e, 0xfb, 0xee, 0x1e, 0x79, 0xff,
- 0x0e, 0xbd, 0x77, 0xe3, 0xce, 0x2a, 0x7e, 0x6b, 0xc9, 0xe8, 0xa0, 0xeb,
- 0x54, 0xaf, 0xde, 0xf3, 0xfd, 0x46, 0x8d, 0xce, 0xe9, 0x52, 0x03, 0xce,
- 0xb0, 0x6e, 0xc3, 0xd8, 0x04, 0x9f, 0x7d, 0x27, 0x3d, 0xda, 0x84, 0xe7,
- 0x84, 0x44, 0x8e, 0x60, 0xee, 0xe6, 0x7b, 0x50, 0xca, 0xbc, 0x7b, 0xab,
- 0x7d, 0xa7, 0xc2, 0xf2, 0xa8, 0x29, 0xef, 0xb6, 0xe5, 0x46, 0x57, 0x75,
- 0xa9, 0x4e, 0xad, 0xab, 0xb6, 0x83, 0xa1, 0x66, 0xa1, 0x5f, 0x67, 0x8b,
- 0xa1, 0xce, 0xe2, 0x6f, 0xc6, 0x9e, 0x19, 0xa3, 0x08, 0x63, 0xd8, 0x49,
- 0xd4, 0xc1, 0x55, 0x0c, 0x6d, 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x1e,
- 0x78, 0xbd, 0x19, 0xfc, 0xf3, 0x6f, 0x0a, 0x8c, 0x81, 0xb6, 0xcb, 0xd1,
- 0xe9, 0xda, 0x77, 0x9d, 0xf2, 0x9e, 0xe9, 0x2d, 0xb2, 0xbf, 0xf4, 0x2d,
- 0xf0, 0xc1, 0x56, 0x99, 0x2a, 0x15, 0xf4, 0x79, 0xf5, 0x4d, 0xfa, 0x3b,
- 0x1e, 0xfc, 0xbe, 0x8d, 0x91, 0x91, 0x3b, 0x1d, 0x23, 0x23, 0xd3, 0xaa,
- 0x6a, 0xb3, 0x86, 0x7d, 0xf2, 0xdb, 0x21, 0x23, 0xa5, 0x84, 0xfe, 0xc6,
- 0xe9, 0x6c, 0xe5, 0x0a, 0xf9, 0xc2, 0x31, 0x75, 0xa7, 0xaa, 0x9e, 0xef,
- 0xd5, 0x36, 0xeb, 0xdc, 0x0a, 0x9b, 0xf5, 0xaf, 0x64, 0xf1, 0xfd, 0x31,
- 0xcc, 0x13, 0x34, 0x7c, 0xe5, 0xf7, 0xb8, 0x17, 0xda, 0x1e, 0x97, 0x0b,
- 0x32, 0xa2, 0xf1, 0x47, 0x79, 0xda, 0x02, 0x39, 0xb8, 0xa4, 0xf5, 0xeb,
- 0x66, 0xd0, 0x20, 0x65, 0xe9, 0xc7, 0xe4, 0x45, 0x2d, 0xcf, 0x36, 0x5b,
- 0xdb, 0x75, 0x81, 0xb1, 0xd4, 0x23, 0xb4, 0x5d, 0xbf, 0x69, 0xcb, 0x59,
- 0x96, 0x4a, 0x2c, 0x09, 0xf5, 0x5d, 0x1c, 0x32, 0x94, 0xf2, 0xf4, 0x8d,
- 0xda, 0xae, 0x5f, 0xb3, 0x7d, 0x50, 0x7e, 0x1a, 0xd9, 0xbd, 0xdd, 0x59,
- 0xb0, 0x65, 0x7c, 0x0e, 0xe3, 0xe9, 0x5e, 0x3a, 0x6b, 0xf9, 0x4c, 0x39,
- 0x5f, 0xc2, 0xfb, 0x4d, 0x78, 0x4f, 0x3e, 0x3b, 0xad, 0xf9, 0x4c, 0xdb,
- 0x27, 0x4e, 0xbf, 0xdd, 0x5f, 0x58, 0xde, 0x1b, 0xc8, 0x91, 0xcf, 0xd4,
- 0x51, 0x77, 0xc1, 0xc8, 0x03, 0xe6, 0xa9, 0x7e, 0x1e, 0xba, 0x83, 0x6d,
- 0x51, 0xfe, 0x70, 0x9a, 0xbe, 0x2d, 0xfc, 0x9f, 0x56, 0x3c, 0xb7, 0xe3,
- 0x79, 0x56, 0xde, 0xbb, 0x37, 0xa6, 0xe7, 0x3d, 0x85, 0x79, 0x1c, 0x38,
- 0x82, 0x39, 0x39, 0xc6, 0x76, 0x8e, 0x9e, 0x8a, 0x4a, 0xc3, 0x29, 0xf2,
- 0x1d, 0xcf, 0xda, 0x04, 0xc1, 0xbe, 0x7e, 0xd2, 0x6d, 0xca, 0xdd, 0xa9,
- 0xcf, 0x96, 0x6e, 0x4f, 0x44, 0x80, 0x93, 0x03, 0x58, 0x8f, 0xa9, 0x82,
- 0xe7, 0x66, 0x1c, 0x2f, 0x81, 0x79, 0xc2, 0x06, 0xec, 0x86, 0x2d, 0xd8,
- 0x0d, 0x3b, 0xb0, 0x1b, 0x76, 0xe0, 0x46, 0x39, 0x71, 0x15, 0x73, 0x4c,
- 0x72, 0xd7, 0xc2, 0x2b, 0x97, 0xef, 0xe8, 0x38, 0x7d, 0xe3, 0xcd, 0x23,
- 0xf0, 0xd9, 0xc5, 0x4d, 0x8d, 0x32, 0x0f, 0x7f, 0xc9, 0x6d, 0xbc, 0x79,
- 0xa7, 0x74, 0x0f, 0xe2, 0xfd, 0xe0, 0x05, 0xe9, 0xb9, 0xf9, 0x56, 0xa7,
- 0x71, 0x74, 0x04, 0x78, 0x4c, 0x3b, 0xa9, 0xc4, 0x98, 0xb3, 0x80, 0x71,
- 0x32, 0xdb, 0x23, 0xc2, 0xb8, 0xe5, 0x02, 0x63, 0x11, 0x37, 0x77, 0x47,
- 0xfa, 0x92, 0xe3, 0x4e, 0x6a, 0x54, 0x45, 0x52, 0xa3, 0x23, 0x4e, 0x58,
- 0x8f, 0xdf, 0x48, 0x85, 0x9c, 0x01, 0xac, 0x07, 0x8a, 0xd3, 0xa0, 0xa7,
- 0xff, 0x28, 0xf9, 0x63, 0x2d, 0x32, 0x5f, 0xe8, 0x76, 0x33, 0x2a, 0xae,
- 0x73, 0x4b, 0xd4, 0x09, 0x10, 0xfd, 0xa9, 0x98, 0xcc, 0x96, 0xb6, 0x8a,
- 0xd2, 0xb6, 0x7b, 0x87, 0x64, 0xa6, 0x4b, 0x72, 0x6e, 0x40, 0xda, 0x14,
- 0xfa, 0xe7, 0xb7, 0x67, 0xd5, 0x09, 0xee, 0x25, 0x86, 0xbc, 0x70, 0x39,
- 0xf9, 0xa4, 0x04, 0x1c, 0x82, 0x6e, 0x19, 0xe3, 0x6d, 0x12, 0xca, 0xbd,
- 0x8f, 0xea, 0xf8, 0x29, 0x63, 0xb6, 0xb5, 0x7b, 0x0f, 0xe4, 0x8f, 0x58,
- 0x5d, 0xfe, 0x98, 0x2b, 0x72, 0x9f, 0x46, 0x72, 0x51, 0xc6, 0x88, 0x3d,
- 0xfc, 0x9e, 0x61, 0xdd, 0x26, 0x99, 0x1a, 0xc8, 0xd9, 0x3c, 0x8f, 0x47,
- 0x12, 0xcc, 0x21, 0x26, 0x4e, 0xc6, 0x07, 0xc8, 0xeb, 0xab, 0xf7, 0x36,
- 0x62, 0x35, 0xf2, 0xc0, 0x91, 0xc5, 0x52, 0xb8, 0x17, 0xc2, 0xfe, 0xf0,
- 0x3c, 0x63, 0xe4, 0x6d, 0x66, 0x4d, 0x3b, 0xc2, 0xc5, 0xfd, 0xca, 0x95,
- 0x32, 0x56, 0x79, 0x94, 0xa9, 0xae, 0x96, 0xaf, 0x8f, 0x55, 0x8c, 0x6c,
- 0x9d, 0xa9, 0x84, 0xba, 0x25, 0x66, 0x74, 0xe9, 0x1a, 0x7d, 0x62, 0xa2,
- 0x99, 0x55, 0x7d, 0x42, 0xbd, 0xa8, 0xe4, 0x03, 0xf3, 0x1d, 0x12, 0x7d,
- 0x58, 0x96, 0xa6, 0xbc, 0xec, 0xe5, 0xcc, 0xd5, 0x98, 0xf2, 0xdf, 0x8c,
- 0x7e, 0xfc, 0x6f, 0x09, 0xea, 0xc3, 0x31, 0xf5, 0x75, 0xdc, 0x37, 0x69,
- 0xfa, 0x03, 0x4f, 0xe1, 0xd9, 0xf8, 0x09, 0xbf, 0x03, 0x3f, 0xe1, 0x8b,
- 0xd0, 0x75, 0x67, 0xe0, 0x27, 0x3c, 0x09, 0x3f, 0xe1, 0x34, 0xfc, 0x84,
- 0x27, 0xa0, 0x27, 0x6b, 0xfd, 0x83, 0xc9, 0x15, 0xfe, 0x41, 0xa0, 0xf9,
- 0x9f, 0xf1, 0xc0, 0x27, 0x6b, 0x7c, 0x83, 0x7d, 0x46, 0x5f, 0xc1, 0xef,
- 0x37, 0x7c, 0xd4, 0xa5, 0x6e, 0xd2, 0xfa, 0xd1, 0xe4, 0xed, 0x8e, 0x2e,
- 0xeb, 0xab, 0x2e, 0x65, 0xf4, 0xd5, 0x6c, 0x55, 0x5f, 0x19, 0x3e, 0x7a,
- 0xb8, 0x24, 0x11, 0xaf, 0xb4, 0x90, 0xf1, 0x77, 0x69, 0x1e, 0x6a, 0xf3,
- 0xb6, 0x4a, 0xe4, 0x01, 0xd5, 0xde, 0x20, 0x19, 0xfb, 0x0c, 0xfa, 0x3a,
- 0x3a, 0x8d, 0xbe, 0xae, 0x95, 0xac, 0xb6, 0xcf, 0x2e, 0x8e, 0xef, 0x27,
- 0x56, 0xe1, 0x3b, 0x5f, 0xbc, 0x5b, 0xe3, 0xfc, 0xfe, 0x32, 0xf7, 0x59,
- 0x5a, 0x64, 0xb2, 0x1c, 0xe2, 0x9c, 0xe7, 0x59, 0x99, 0x8b, 0xd1, 0x29,
- 0x91, 0x87, 0x3b, 0x78, 0xce, 0x4a, 0x65, 0xfd, 0xf5, 0x3a, 0x87, 0xe5,
- 0xc4, 0x80, 0x24, 0xb2, 0x03, 0xa4, 0xd5, 0xfb, 0x64, 0x56, 0xaf, 0x45,
- 0x87, 0x34, 0x3c, 0x4c, 0x1b, 0x25, 0xdc, 0xcf, 0xeb, 0xba, 0xcc, 0x7e,
- 0x23, 0x35, 0x66, 0xea, 0x89, 0x1c, 0xd4, 0xeb, 0x75, 0x5c, 0xe7, 0x19,
- 0xde, 0x34, 0xcf, 0xb8, 0x3c, 0xbf, 0x47, 0xc5, 0x98, 0xfc, 0x3f, 0x67,
- 0xfd, 0x7e, 0xe1, 0x32, 0x63, 0xcf, 0x6c, 0xb2, 0x76, 0x8c, 0x89, 0x53,
- 0xd5, 0xb7, 0x61, 0xd8, 0x4f, 0xed, 0x37, 0x14, 0xb7, 0x38, 0x93, 0xa5,
- 0xad, 0x4e, 0xbe, 0xc4, 0xbd, 0x6c, 0xfb, 0xf7, 0x2e, 0xdc, 0x3d, 0xce,
- 0x01, 0x6f, 0x0b, 0xca, 0x18, 0xb3, 0x64, 0xcc, 0xe6, 0x97, 0x2e, 0x63,
- 0x8c, 0x36, 0xe3, 0x71, 0x6c, 0x96, 0x6d, 0x71, 0xa6, 0x4a, 0xdd, 0xf0,
- 0xcd, 0x79, 0xae, 0x8a, 0xef, 0x77, 0x72, 0xed, 0xa0, 0x83, 0x5d, 0x7d,
- 0x66, 0x77, 0x42, 0xae, 0xb0, 0x31, 0x68, 0xea, 0xe1, 0x9f, 0x5f, 0xb1,
- 0x77, 0x7b, 0x08, 0x7a, 0xec, 0x16, 0xc8, 0x23, 0xea, 0xe1, 0x43, 0x72,
- 0xb5, 0xa5, 0xe7, 0x95, 0x7a, 0xf8, 0xbc, 0x30, 0x4e, 0xdc, 0x8f, 0x77,
- 0xb9, 0x20, 0x06, 0x7a, 0x38, 0x5c, 0xe3, 0xab, 0xd1, 0xef, 0x6b, 0x1a,
- 0x32, 0xfb, 0x61, 0x2b, 0xfd, 0x3e, 0xc8, 0x81, 0x78, 0xe8, 0xe7, 0x35,
- 0x2e, 0xef, 0xd7, 0xee, 0xb1, 0x6d, 0xa7, 0xfc, 0xfb, 0x89, 0xa3, 0xe4,
- 0x21, 0xe9, 0x81, 0x2e, 0x63, 0x0e, 0xc8, 0x6f, 0x69, 0x9c, 0x89, 0x22,
- 0xed, 0x6d, 0xd2, 0x30, 0x5a, 0x39, 0x9f, 0x0c, 0x73, 0x38, 0xf2, 0xb6,
- 0xed, 0x84, 0xdd, 0x93, 0xcf, 0xcb, 0xdc, 0x65, 0xd4, 0x83, 0x23, 0x91,
- 0xf5, 0xfc, 0x7e, 0x22, 0xda, 0xf6, 0x18, 0xbd, 0x28, 0x61, 0x5f, 0x7c,
- 0x6e, 0xa8, 0xe9, 0x9b, 0x76, 0x14, 0xef, 0xab, 0xcf, 0x91, 0x3d, 0xa3,
- 0xf7, 0x19, 0xcd, 0xf7, 0x12, 0x42, 0x3e, 0x21, 0xef, 0x24, 0xf5, 0x59,
- 0x27, 0xef, 0x61, 0xda, 0x3d, 0xdc, 0x83, 0x75, 0x17, 0x26, 0xfd, 0x4f,
- 0xe8, 0x6f, 0xfc, 0xcd, 0x88, 0x38, 0x79, 0xff, 0x36, 0x9d, 0x7b, 0x92,
- 0xd7, 0xb1, 0xe6, 0x1c, 0xee, 0x55, 0x1f, 0xb5, 0xeb, 0x61, 0xfe, 0x4d,
- 0x0b, 0x96, 0x65, 0x01, 0x1b, 0x75, 0x08, 0x65, 0x6f, 0x5c, 0xba, 0x8e,
- 0x7e, 0x58, 0xf3, 0xc2, 0x66, 0xf8, 0x02, 0xc3, 0x47, 0xa1, 0xab, 0x8f,
- 0x26, 0x64, 0xe7, 0x51, 0xad, 0x1b, 0xd3, 0x6b, 0x63, 0x05, 0x7d, 0x6e,
- 0xd4, 0x79, 0x8f, 0x3e, 0xc7, 0xf6, 0xd6, 0xa3, 0x11, 0x39, 0x1c, 0xef,
- 0x73, 0x7b, 0x9c, 0xf7, 0x5a, 0x5d, 0x18, 0xc6, 0xb0, 0x5b, 0xd0, 0xfe,
- 0xf5, 0xe2, 0xd8, 0x61, 0xfc, 0x3a, 0x22, 0x33, 0x7b, 0x3b, 0x01, 0xdb,
- 0x5f, 0x5d, 0x66, 0xce, 0x20, 0x63, 0xad, 0xf4, 0xb7, 0xe7, 0xa3, 0x09,
- 0xca, 0xb2, 0x2e, 0xc0, 0x32, 0x72, 0x94, 0xfa, 0xcc, 0xd3, 0x3c, 0x0e,
- 0x18, 0xdc, 0x06, 0xed, 0x87, 0x90, 0x2f, 0xdf, 0x22, 0xde, 0x03, 0x90,
- 0x71, 0x47, 0x63, 0xd2, 0x73, 0xb4, 0x45, 0xb6, 0x1d, 0xa5, 0x1f, 0x52,
- 0xeb, 0x97, 0xd2, 0x2e, 0x7d, 0x04, 0x73, 0x7c, 0xb7, 0x96, 0x93, 0xdc,
- 0xd3, 0xdc, 0x4f, 0xde, 0x45, 0xdd, 0x2c, 0x6c, 0xe6, 0xcc, 0x51, 0x57,
- 0xef, 0x91, 0x66, 0x30, 0xe7, 0x6c, 0xd9, 0xc5, 0x38, 0x46, 0xe6, 0xe4,
- 0xe9, 0xa7, 0x8c, 0x76, 0x00, 0xc7, 0xef, 0xb5, 0xbc, 0xb3, 0xbe, 0xc3,
- 0xf2, 0xe8, 0xcf, 0xc8, 0x7b, 0x5b, 0x3a, 0x8c, 0xec, 0x7c, 0x4b, 0x07,
- 0x73, 0x93, 0x36, 0x7b, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
- 0xe2, 0x45, 0x01, 0x8e, 0xc2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0x38, 0xe7,
- 0xeb, 0xf3, 0x2b, 0xfe, 0xa2, 0xfe, 0x3b, 0x21, 0xdc, 0x23, 0xab, 0x7e,
- 0x6f, 0x65, 0x57, 0x85, 0x71, 0xf2, 0xcf, 0x86, 0x7f, 0x97, 0xa4, 0x26,
- 0xef, 0xb0, 0x76, 0x0f, 0x8c, 0xb1, 0xa6, 0xe5, 0xdc, 0xa0, 0xa0, 0xa4,
- 0xbf, 0x5f, 0xf4, 0x9c, 0x73, 0xbe, 0x70, 0xd6, 0xf9, 0xee, 0xb4, 0x04,
- 0x51, 0xef, 0x27, 0xce, 0xf7, 0x3d, 0xee, 0x99, 0x7f, 0xdd, 0xf9, 0x5e,
- 0xc1, 0x03, 0x1f, 0xde, 0x87, 0x79, 0xbc, 0xe2, 0xfc, 0x00, 0xeb, 0x7b,
- 0xb0, 0x98, 0x4e, 0xb9, 0x36, 0x26, 0x7e, 0xb6, 0xf0, 0x8a, 0xf3, 0xb5,
- 0x6a, 0x3c, 0x69, 0x30, 0xa4, 0x91, 0x43, 0x7c, 0x57, 0xc6, 0xbb, 0xb2,
- 0xde, 0xff, 0x71, 0xe6, 0xa6, 0x6d, 0x7e, 0x89, 0xe6, 0xe3, 0x85, 0xe5,
- 0x7d, 0x99, 0x51, 0xbd, 0x57, 0xf1, 0xac, 0x33, 0x37, 0x7f, 0x77, 0x87,
- 0xc9, 0x33, 0x3a, 0x8b, 0x77, 0x26, 0xe7, 0x72, 0x76, 0xfe, 0x2c, 0xea,
- 0x3c, 0xe3, 0xcc, 0xea, 0xf8, 0x97, 0xf6, 0xc5, 0x9d, 0x99, 0xf9, 0x67,
- 0x9c, 0x79, 0xbd, 0x07, 0x7d, 0xce, 0x79, 0x74, 0x9a, 0x7d, 0x9f, 0x43,
- 0x9d, 0x05, 0xe7, 0x04, 0xfa, 0x9b, 0x9f, 0xe6, 0x79, 0xdc, 0x6e, 0xd8,
- 0x05, 0xfc, 0x7b, 0x3f, 0xfc, 0x1e, 0xc7, 0xb3, 0xce, 0xfc, 0x72, 0xbf,
- 0x8b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x59, 0xf4, 0xbf, 0x76,
- 0xaf, 0x6a, 0x2d, 0x4e, 0x5e, 0x00, 0x4e, 0x2e, 0x58, 0x9c, 0xbc, 0x6a,
- 0x71, 0xf2, 0x7c, 0x0d, 0x4e, 0x44, 0xad, 0xc4, 0xc9, 0xab, 0xc0, 0x89,
- 0xa8, 0xfa, 0x38, 0xc1, 0xbb, 0x32, 0xde, 0x69, 0x9c, 0xbc, 0xb4, 0x0a,
- 0x27, 0x4b, 0xcb, 0x71, 0x79, 0x83, 0x93, 0x17, 0x81, 0x93, 0xaf, 0x5a,
- 0xd8, 0x2f, 0x58, 0x9c, 0xe0, 0x3e, 0x7f, 0x01, 0x75, 0x5e, 0xaa, 0xc1,
- 0xc9, 0x05, 0xe0, 0xe4, 0x25, 0x8b, 0x93, 0xef, 0x5b, 0x9c, 0x7c, 0x1f,
- 0x75, 0x96, 0x80, 0x93, 0xf3, 0x75, 0x70, 0xf2, 0x22, 0x70, 0x12, 0xf6,
- 0x7b, 0x1e, 0xfd, 0x7c, 0xbf, 0x06, 0x27, 0x2f, 0xd6, 0xc1, 0x09, 0xf7,
- 0x62, 0xc3, 0x9c, 0xee, 0x99, 0xd7, 0xc9, 0xe9, 0x96, 0x3b, 0x5f, 0x3f,
- 0xa7, 0x9b, 0x75, 0x66, 0xa4, 0xfa, 0x37, 0x25, 0xee, 0xb6, 0x39, 0x6a,
- 0x26, 0x17, 0xb0, 0xfa, 0xcd, 0xa6, 0x6e, 0xf0, 0x79, 0x3e, 0xe7, 0x8a,
- 0xc9, 0x29, 0x8d, 0xee, 0xf8, 0x10, 0x78, 0x6d, 0x97, 0x1c, 0x38, 0xd6,
- 0x78, 0x38, 0x6b, 0xcb, 0xbc, 0x1d, 0xdd, 0x39, 0xa5, 0xf8, 0x2e, 0xcc,
- 0x49, 0xa0, 0x5f, 0xd2, 0xc0, 0x6f, 0x0b, 0xf6, 0xa6, 0xa5, 0x76, 0x4f,
- 0xba, 0xc0, 0x6f, 0x34, 0x61, 0xec, 0x25, 0xfe, 0xfd, 0x8b, 0x24, 0xf3,
- 0xac, 0xf2, 0x1a, 0xde, 0x14, 0xf4, 0xc7, 0xa0, 0xce, 0xad, 0xca, 0x14,
- 0x68, 0x73, 0x27, 0x99, 0xa3, 0x06, 0x5b, 0x79, 0xc8, 0x9e, 0x09, 0xf3,
- 0xf5, 0x39, 0x95, 0x2a, 0xff, 0xd4, 0x9e, 0x87, 0x26, 0xdf, 0x55, 0xe9,
- 0xe6, 0xe0, 0xf2, 0x77, 0x02, 0x4f, 0xca, 0xd3, 0x3a, 0x56, 0xdc, 0x8c,
- 0xf5, 0x09, 0x82, 0xc7, 0x7c, 0x13, 0xa3, 0x5d, 0xd4, 0x31, 0x5a, 0x81,
- 0x37, 0x3e, 0x69, 0xe3, 0xb4, 0x3d, 0x83, 0x2f, 0x2d, 0xc7, 0x68, 0x6b,
- 0xf3, 0x59, 0xcc, 0xfe, 0x7a, 0xa6, 0xf4, 0x88, 0xce, 0xd1, 0x19, 0xe1,
- 0xf7, 0x37, 0x20, 0x23, 0x26, 0x66, 0xe6, 0x65, 0xf2, 0x41, 0x3e, 0x53,
- 0xbf, 0x45, 0xa0, 0xc3, 0x28, 0xc3, 0x73, 0x92, 0x19, 0x64, 0x99, 0x69,
- 0x33, 0xa2, 0xfd, 0xe5, 0x93, 0x32, 0xbc, 0x3c, 0x3e, 0xf1, 0x7b, 0x57,
- 0xcd, 0x77, 0xab, 0x69, 0xf3, 0xa4, 0x9d, 0x4c, 0x85, 0xef, 0xc3, 0x3d,
- 0xf2, 0xbb, 0xec, 0xb7, 0xb3, 0xf8, 0xbe, 0xf6, 0x5b, 0xad, 0x5a, 0x74,
- 0xe0, 0x37, 0xbf, 0x87, 0x36, 0xe5, 0x8c, 0xa0, 0xcd, 0x82, 0xdb, 0x32,
- 0xaa, 0x86, 0x6e, 0x18, 0xe5, 0xb9, 0xb9, 0xd9, 0x35, 0xdf, 0xba, 0xae,
- 0xea, 0xc5, 0xbc, 0x5e, 0x53, 0xe6, 0x67, 0xdd, 0x05, 0x5a, 0xd4, 0xb4,
- 0xa5, 0xe9, 0xff, 0xc0, 0xb2, 0xbe, 0xa4, 0x9e, 0x35, 0xdf, 0x9e, 0x31,
- 0xfa, 0x32, 0x95, 0x18, 0xc1, 0xf8, 0xfa, 0x6f, 0x2a, 0xd8, 0x73, 0xbd,
- 0xd9, 0xf9, 0xdb, 0xb5, 0xae, 0x9f, 0xf2, 0xd3, 0xc9, 0xa8, 0xd4, 0xa9,
- 0x5b, 0xaa, 0xa9, 0xab, 0xe7, 0xed, 0xca, 0x7f, 0xc5, 0xda, 0x7c, 0xbe,
- 0x58, 0x96, 0xe1, 0xe9, 0xbf, 0x84, 0xff, 0x98, 0x90, 0xdf, 0x2e, 0x96,
- 0x40, 0xaf, 0xb9, 0xcd, 0xf6, 0x5b, 0x4d, 0x19, 0xc0, 0xcd, 0x6f, 0xaf,
- 0xe8, 0x7c, 0xe2, 0xc8, 0x17, 0x40, 0x17, 0x9f, 0x2b, 0x71, 0x0c, 0xc0,
- 0x12, 0x81, 0x6d, 0x0f, 0x3b, 0x61, 0xa6, 0xa4, 0x73, 0xe7, 0xae, 0x2b,
- 0x97, 0x74, 0xcc, 0x62, 0x67, 0xb9, 0x53, 0x76, 0x95, 0x5b, 0x64, 0x37,
- 0xf4, 0xc2, 0xee, 0xb2, 0x87, 0x2b, 0x26, 0xef, 0x2e, 0x9b, 0x75, 0xfa,
- 0x58, 0x99, 0xeb, 0xbd, 0x43, 0x66, 0x8f, 0xad, 0xfe, 0x3e, 0xe7, 0x42,
- 0x2e, 0xfc, 0x3b, 0x4b, 0x4a, 0x31, 0xbf, 0x8c, 0xb4, 0x84, 0xab, 0x98,
- 0x3a, 0xbc, 0xa0, 0xf1, 0xc0, 0x0c, 0xd7, 0x54, 0x69, 0x49, 0x98, 0xa7,
- 0xcf, 0xbf, 0xad, 0x34, 0x73, 0x39, 0xcf, 0x4d, 0xf3, 0x5b, 0x5e, 0x3b,
- 0x2b, 0x61, 0xde, 0x78, 0xbd, 0x9c, 0x71, 0xd8, 0xf9, 0x3b, 0xc2, 0x1c,
- 0xbf, 0x18, 0x73, 0xc6, 0xa5, 0xeb, 0x54, 0x0b, 0xee, 0xa7, 0x2f, 0xd7,
- 0x67, 0x9b, 0x4f, 0x89, 0x2d, 0xd3, 0xf9, 0xe4, 0x78, 0x5e, 0xfd, 0x7d,
- 0xb5, 0x90, 0x1f, 0xaa, 0x7f, 0xa7, 0x40, 0xe4, 0xff, 0x02, 0xfb, 0x2e,
- 0x88, 0x71, 0xec, 0x6e, 0x00, 0x00, 0x00 };
+ 0xbd, 0x7d, 0x0d, 0x74, 0x5c, 0xd7, 0x5d, 0xe7, 0xff, 0xdd, 0x79, 0x92,
+ 0xc6, 0xb2, 0x6c, 0x3f, 0xcb, 0x13, 0x79, 0x62, 0xab, 0xf6, 0x8c, 0xf4,
+ 0x64, 0xab, 0x91, 0x08, 0x2f, 0xae, 0x28, 0x82, 0x9d, 0x84, 0xe9, 0x48,
+ 0xb2, 0x9d, 0x34, 0xed, 0xca, 0x8d, 0x5b, 0xb2, 0x9c, 0x02, 0x62, 0x24,
+ 0x27, 0xe9, 0x77, 0xd2, 0x04, 0xb6, 0xec, 0xc9, 0x6e, 0x26, 0x23, 0xf9,
+ 0x83, 0x74, 0xec, 0x51, 0x12, 0x25, 0xce, 0xa1, 0x3d, 0xbb, 0xaa, 0xa4,
+ 0xd8, 0x06, 0x06, 0x8f, 0x93, 0xb8, 0xa5, 0xec, 0xa6, 0x54, 0x28, 0xae,
+ 0x09, 0xa1, 0x07, 0x52, 0x48, 0xd9, 0x40, 0x53, 0x2a, 0xdc, 0xb4, 0xcd,
+ 0x9e, 0x53, 0xb6, 0x01, 0xca, 0x12, 0x68, 0xe8, 0xdb, 0xdf, 0xef, 0xde,
+ 0xfb, 0x34, 0xa3, 0x0f, 0xe7, 0xa3, 0xec, 0xe2, 0x73, 0x9e, 0xdf, 0xbc,
+ 0xfb, 0xee, 0xc7, 0xff, 0xfe, 0xef, 0xff, 0xfb, 0xfe, 0xef, 0xd3, 0x76,
+ 0x91, 0x66, 0xb1, 0xff, 0x36, 0xe0, 0x7a, 0x5b, 0xea, 0xf6, 0xd1, 0x6b,
+ 0xae, 0xfe, 0xc9, 0xab, 0xf9, 0xec, 0x3a, 0x4d, 0x31, 0x79, 0x13, 0xff,
+ 0x52, 0x6f, 0xa0, 0x0e, 0x3a, 0xf4, 0xa2, 0xb1, 0x78, 0x49, 0x5c, 0x65,
+ 0xdc, 0x3b, 0x72, 0xbe, 0xc4, 0x63, 0x99, 0x91, 0x5f, 0x1e, 0xf5, 0x45,
+ 0xb2, 0x95, 0x9e, 0xd4, 0x80, 0xfc, 0x4b, 0x58, 0x48, 0xb8, 0xc2, 0xf2,
+ 0xb7, 0x64, 0x5e, 0xfd, 0x6f, 0x5f, 0xf8, 0xc9, 0xf4, 0xcb, 0xd3, 0x31,
+ 0x89, 0x7b, 0x99, 0x0f, 0x8b, 0xb7, 0x4b, 0xe2, 0xed, 0x19, 0xb9, 0xe3,
+ 0xd3, 0xbb, 0xff, 0x46, 0x64, 0x63, 0xd4, 0xd7, 0x4b, 0xe1, 0x17, 0x76,
+ 0x4b, 0x61, 0x5b, 0x26, 0x39, 0xd2, 0x90, 0x49, 0xc8, 0x17, 0xab, 0x9e,
+ 0x9c, 0xab, 0xca, 0xf0, 0xa9, 0xd2, 0xcb, 0xa1, 0x9b, 0x09, 0x63, 0x13,
+ 0x7d, 0x8e, 0xc4, 0x32, 0x72, 0x61, 0xb4, 0xef, 0x9e, 0x50, 0xf9, 0x32,
+ 0xe2, 0x65, 0xfc, 0x60, 0x41, 0x5a, 0xfa, 0x2f, 0xf6, 0xa1, 0x4e, 0xe5,
+ 0xe0, 0xb5, 0x8d, 0x27, 0xe2, 0xa2, 0x32, 0x5d, 0xcf, 0xe7, 0x62, 0xd7,
+ 0x88, 0xf2, 0xfd, 0xe0, 0x82, 0x74, 0x05, 0x4f, 0x09, 0xca, 0xcf, 0xc6,
+ 0x25, 0x57, 0x95, 0x16, 0x94, 0xe1, 0xde, 0x8c, 0x3a, 0x69, 0x2f, 0x17,
+ 0x4b, 0x48, 0xb1, 0xfa, 0x63, 0xcd, 0x66, 0xec, 0xaf, 0xaf, 0x33, 0xf7,
+ 0xdd, 0xf6, 0xbe, 0xee, 0x67, 0xdd, 0x4c, 0x3c, 0xae, 0x4e, 0xc8, 0xcb,
+ 0x13, 0x7d, 0x2f, 0x87, 0x31, 0xdf, 0xf7, 0x06, 0xa4, 0x41, 0x06, 0x13,
+ 0x80, 0xa9, 0xec, 0xa0, 0xef, 0x14, 0xda, 0xfe, 0x12, 0x70, 0x0e, 0xf8,
+ 0xca, 0x29, 0x29, 0x10, 0xce, 0x72, 0x5c, 0x16, 0x63, 0x49, 0x01, 0xfc,
+ 0xc0, 0x45, 0xbb, 0x8c, 0xa3, 0x3c, 0x57, 0xe2, 0x7c, 0x5c, 0xc9, 0x7b,
+ 0x1e, 0xe6, 0xd2, 0x8e, 0x36, 0x3b, 0x1d, 0xd3, 0x3f, 0x9e, 0x97, 0xd5,
+ 0x67, 0xdd, 0xe7, 0x51, 0x37, 0xa5, 0xeb, 0x3d, 0x51, 0x4d, 0xca, 0xe3,
+ 0xd5, 0x84, 0x3c, 0x56, 0xfd, 0x98, 0x64, 0x3d, 0xe2, 0x00, 0xb0, 0x96,
+ 0x1b, 0x65, 0x60, 0xaa, 0x59, 0x72, 0x53, 0x9d, 0xc9, 0xbc, 0x84, 0xe1,
+ 0x9d, 0xc1, 0x07, 0x64, 0xa4, 0x15, 0xf5, 0xcb, 0x7c, 0x97, 0x5c, 0xf6,
+ 0x2e, 0x1f, 0xf4, 0x78, 0x79, 0xe5, 0x48, 0xf6, 0x60, 0x3a, 0x39, 0xa2,
+ 0xf8, 0xdc, 0x20, 0xb9, 0x5e, 0x3c, 0x0f, 0xbb, 0x12, 0xf3, 0xc3, 0xf0,
+ 0x8e, 0x60, 0x17, 0xe0, 0x48, 0xa7, 0x52, 0x8a, 0x6d, 0xd9, 0x2e, 0x5d,
+ 0x48, 0xa9, 0x24, 0xe6, 0x71, 0xb5, 0xa4, 0x5a, 0xc3, 0xf0, 0x3d, 0x81,
+ 0x8f, 0x72, 0x91, 0x81, 0x92, 0xdc, 0xae, 0x32, 0x3e, 0xfa, 0x94, 0x40,
+ 0x65, 0xb6, 0x60, 0x1e, 0x3d, 0xc0, 0x43, 0xa3, 0x64, 0x13, 0x92, 0x55,
+ 0x19, 0x49, 0xa9, 0xcc, 0x3a, 0x94, 0x39, 0xd2, 0xe0, 0xff, 0x77, 0x4b,
+ 0x7f, 0x9b, 0xf0, 0x2c, 0xc3, 0x2a, 0xd3, 0xba, 0xa2, 0x3c, 0x9d, 0x12,
+ 0xf5, 0xe3, 0x71, 0x8c, 0xd9, 0x9d, 0x55, 0x2c, 0xc3, 0x5d, 0x97, 0x15,
+ 0x9a, 0x56, 0x97, 0x4d, 0x3a, 0xcb, 0xcb, 0x4e, 0xb5, 0x10, 0x56, 0x51,
+ 0xfc, 0x9d, 0xd4, 0x73, 0xcd, 0x26, 0x3a, 0xbd, 0x06, 0xcc, 0x6b, 0x38,
+ 0x48, 0x7b, 0x43, 0xea, 0xb9, 0x50, 0xda, 0x08, 0x33, 0xdf, 0x29, 0xbc,
+ 0x43, 0xd5, 0x4c, 0x80, 0x75, 0x4e, 0xc8, 0x51, 0xcc, 0xed, 0xd2, 0x54,
+ 0xda, 0xeb, 0x50, 0xb8, 0xcf, 0xf1, 0x77, 0x18, 0xe6, 0x82, 0x82, 0xa6,
+ 0x81, 0x6f, 0x4e, 0x25, 0xf1, 0x0c, 0xf8, 0x13, 0xd9, 0xf4, 0x66, 0xb9,
+ 0xc9, 0xae, 0xcb, 0x37, 0x31, 0x66, 0xa7, 0x77, 0x87, 0xea, 0xf4, 0x02,
+ 0x95, 0xf6, 0x66, 0xe4, 0xf7, 0xf1, 0x1c, 0x86, 0x07, 0x82, 0x74, 0xb2,
+ 0x80, 0x35, 0x7b, 0xb1, 0x94, 0x90, 0x6f, 0x95, 0xd2, 0xa0, 0xfc, 0x74,
+ 0xf7, 0xac, 0xf4, 0x04, 0xb3, 0x80, 0xb7, 0x88, 0xeb, 0x08, 0xdf, 0x55,
+ 0xf0, 0xae, 0xc2, 0xb6, 0x61, 0x78, 0x53, 0xf0, 0xeb, 0xe1, 0x48, 0x9b,
+ 0xe1, 0xa5, 0x2f, 0x96, 0xb1, 0x9e, 0x80, 0xf9, 0x71, 0xac, 0xd3, 0x63,
+ 0xe5, 0x88, 0x4e, 0xba, 0xb1, 0xee, 0xa4, 0x0d, 0xd2, 0xc5, 0x1e, 0x4b,
+ 0xff, 0xa3, 0xf6, 0x2e, 0x92, 0x03, 0x8d, 0xe5, 0x82, 0x1f, 0x84, 0x59,
+ 0xcd, 0x63, 0xe2, 0x0c, 0x94, 0x49, 0xbb, 0x0d, 0x80, 0x95, 0x8f, 0x1f,
+ 0xb3, 0xf5, 0xda, 0x1d, 0xe0, 0x96, 0xeb, 0xc0, 0xf7, 0x71, 0xe5, 0x37,
+ 0xd9, 0xf7, 0x11, 0x2f, 0xf1, 0x1f, 0xe8, 0xcd, 0xaf, 0xd5, 0xcb, 0x91,
+ 0x26, 0xab, 0x05, 0xc9, 0x3f, 0x18, 0xca, 0x40, 0x00, 0x3c, 0xb1, 0x4f,
+ 0x2f, 0x10, 0xdd, 0xd6, 0x63, 0x1d, 0x5d, 0x17, 0xff, 0xae, 0x69, 0xc4,
+ 0x18, 0xce, 0x60, 0xb9, 0xd6, 0x76, 0xb0, 0xfc, 0xe4, 0x16, 0x0b, 0x1f,
+ 0x9e, 0xfb, 0x9d, 0x5c, 0xf5, 0x6f, 0xed, 0xda, 0x46, 0xf3, 0xb8, 0x69,
+ 0x0d, 0xda, 0x0e, 0xc3, 0x89, 0x40, 0x46, 0x54, 0x66, 0x31, 0x9e, 0x2b,
+ 0x89, 0xd3, 0x90, 0xf1, 0xbd, 0x21, 0x59, 0x27, 0x76, 0x5e, 0xb6, 0xdc,
+ 0x03, 0xaf, 0x74, 0xa1, 0xdc, 0x11, 0xc8, 0x8d, 0x11, 0x07, 0x65, 0x1d,
+ 0x15, 0x94, 0x61, 0xfd, 0xc6, 0x81, 0xaf, 0x7c, 0xa9, 0x5f, 0xaf, 0x65,
+ 0xbe, 0x34, 0x0c, 0xde, 0xcf, 0xe0, 0x77, 0x76, 0xb3, 0x2b, 0x5d, 0xa0,
+ 0x43, 0xae, 0xb1, 0xb8, 0xb9, 0xdd, 0xa0, 0xd5, 0xea, 0xeb, 0x4b, 0x2c,
+ 0x3d, 0xf7, 0xe0, 0x5f, 0x88, 0xd3, 0x25, 0x78, 0x62, 0x19, 0xf2, 0xf5,
+ 0xf3, 0x21, 0xe8, 0x19, 0x65, 0x84, 0x99, 0x35, 0x13, 0x32, 0x51, 0xde,
+ 0x26, 0xc5, 0x29, 0x5f, 0xc6, 0x4b, 0xf3, 0xdd, 0x4a, 0x5e, 0x86, 0xac,
+ 0xf1, 0x41, 0x0b, 0x69, 0xf0, 0x41, 0x46, 0x06, 0xaa, 0x18, 0xaf, 0x84,
+ 0x7b, 0xb9, 0x13, 0x6d, 0x5d, 0xc9, 0x26, 0xcd, 0x3a, 0x17, 0x4b, 0x63,
+ 0xc0, 0x15, 0xd6, 0x8d, 0xb2, 0x41, 0xc3, 0x3c, 0x0c, 0x3a, 0xf4, 0x24,
+ 0xd7, 0xa7, 0xe1, 0x7c, 0x13, 0xf0, 0xc5, 0x65, 0x26, 0x68, 0xb4, 0x38,
+ 0x22, 0x7f, 0xc6, 0xdd, 0x01, 0xe0, 0x61, 0xa0, 0x72, 0x0f, 0xfa, 0x6f,
+ 0xc1, 0x6f, 0x96, 0x89, 0x2d, 0x73, 0xf5, 0xf3, 0x40, 0x85, 0x30, 0x47,
+ 0x74, 0x0f, 0x3e, 0x98, 0x82, 0xfc, 0x01, 0xdd, 0x0f, 0x90, 0x5f, 0xe6,
+ 0x38, 0x17, 0xc2, 0xb5, 0x4d, 0xff, 0x1e, 0x9f, 0xda, 0xa1, 0x9f, 0xf3,
+ 0xc3, 0xdb, 0xa4, 0x30, 0x17, 0xcd, 0x99, 0xb2, 0x87, 0xf2, 0x26, 0x7d,
+ 0x0c, 0x74, 0x05, 0xf9, 0x13, 0x86, 0x0f, 0x06, 0x94, 0x41, 0x61, 0xf8,
+ 0x78, 0x40, 0x99, 0x74, 0x1e, 0xb2, 0x86, 0x72, 0x88, 0x72, 0x61, 0x50,
+ 0x71, 0xdd, 0x73, 0xa5, 0x00, 0xeb, 0xd3, 0x28, 0xf9, 0xde, 0x47, 0x08,
+ 0x2b, 0x64, 0xd8, 0xb3, 0x1f, 0xcb, 0xf9, 0x85, 0x64, 0x4c, 0xe3, 0x49,
+ 0xb0, 0x5e, 0x71, 0xc9, 0xea, 0x99, 0x75, 0x48, 0xb1, 0x77, 0xd2, 0xd6,
+ 0x79, 0x49, 0xd7, 0x71, 0x57, 0xd5, 0xf9, 0x75, 0x65, 0x78, 0x3c, 0xc0,
+ 0x5a, 0xfe, 0xb4, 0x22, 0x1e, 0x3b, 0x76, 0xf1, 0x59, 0xe2, 0x0d, 0x99,
+ 0xaf, 0xe1, 0xdd, 0xb9, 0x3b, 0x1f, 0xf5, 0xd7, 0x7a, 0xb7, 0xb5, 0x61,
+ 0xf5, 0xbb, 0x09, 0x71, 0xfd, 0x74, 0xf7, 0x01, 0xf5, 0x4f, 0x78, 0x17,
+ 0x86, 0x8f, 0x06, 0x51, 0x79, 0x6f, 0xc3, 0xea, 0x31, 0x7e, 0x76, 0x8d,
+ 0xb2, 0xf3, 0x6b, 0x94, 0xfd, 0xc9, 0x1a, 0x65, 0xef, 0x6d, 0x5c, 0x5d,
+ 0xf6, 0xc0, 0x1a, 0x65, 0x4f, 0xaf, 0x51, 0xe6, 0x37, 0xad, 0x2e, 0xdb,
+ 0xb5, 0x46, 0xd9, 0x5b, 0xd7, 0x28, 0x3b, 0xb0, 0x46, 0x99, 0x0b, 0x1e,
+ 0xde, 0x25, 0xc5, 0xc4, 0xbd, 0x9c, 0xbb, 0xc5, 0xcd, 0xe7, 0x62, 0xab,
+ 0x71, 0xd3, 0x80, 0x7a, 0xed, 0x2b, 0xea, 0x7d, 0x6d, 0x8d, 0x7a, 0x8d,
+ 0xa8, 0xd7, 0xba, 0xa2, 0xde, 0xcd, 0xee, 0xea, 0x7a, 0x4d, 0xa8, 0x17,
+ 0x5f, 0x51, 0xef, 0x77, 0xd7, 0xa8, 0xc7, 0xf2, 0x4f, 0xd9, 0x71, 0x7a,
+ 0xa0, 0xd1, 0x5e, 0x6b, 0xbd, 0x1a, 0x45, 0xda, 0x58, 0x1e, 0x40, 0x1f,
+ 0xfd, 0xb4, 0x32, 0x32, 0x86, 0xf2, 0x4c, 0xe3, 0x0d, 0x74, 0x9e, 0x04,
+ 0xdd, 0x51, 0x26, 0x83, 0xcf, 0x7c, 0xf2, 0xfe, 0x06, 0x19, 0x49, 0xf4,
+ 0x78, 0x6f, 0x53, 0x2d, 0xa0, 0xb1, 0xb4, 0x97, 0x52, 0xe4, 0x3f, 0x29,
+ 0x80, 0xb7, 0x0b, 0x03, 0xa2, 0x12, 0x4a, 0x42, 0x19, 0x0c, 0x54, 0xab,
+ 0x92, 0x7b, 0xc0, 0x5f, 0x59, 0xe8, 0xbf, 0x03, 0xe1, 0x80, 0xe6, 0x2d,
+ 0x53, 0xf7, 0xf2, 0xf2, 0xb9, 0x5f, 0x8e, 0x50, 0xae, 0x66, 0x82, 0x3b,
+ 0x73, 0xfe, 0x7c, 0x7f, 0x23, 0x68, 0xf6, 0x12, 0xda, 0xec, 0x43, 0xcb,
+ 0x43, 0x15, 0x57, 0x06, 0x2b, 0x19, 0xf0, 0x82, 0x23, 0x17, 0xfd, 0x4d,
+ 0x72, 0x31, 0x40, 0xdd, 0x6a, 0x4c, 0x16, 0x12, 0x8e, 0x2c, 0xe0, 0x39,
+ 0x17, 0xe0, 0x5d, 0x35, 0xe2, 0xad, 0x8c, 0x1c, 0x2e, 0xf7, 0xcb, 0xb1,
+ 0xf2, 0x87, 0x55, 0xa4, 0x23, 0x87, 0x82, 0xf5, 0x72, 0xc6, 0x33, 0x7d,
+ 0xef, 0xf3, 0xe7, 0xa1, 0x9d, 0x5d, 0xb9, 0xe4, 0xa7, 0x93, 0x0b, 0x9a,
+ 0x27, 0xfe, 0x31, 0x1c, 0x44, 0x3f, 0x33, 0x7e, 0xda, 0xfb, 0x03, 0x0a,
+ 0xc9, 0x0a, 0x6d, 0xa9, 0x5a, 0x5f, 0xe3, 0xe8, 0xeb, 0x68, 0x79, 0x83,
+ 0xdc, 0x6a, 0xdb, 0xef, 0xf5, 0xe7, 0xbb, 0xc1, 0x73, 0xde, 0x29, 0xca,
+ 0x90, 0x12, 0xe0, 0x3a, 0x08, 0xde, 0x46, 0xdb, 0x2f, 0x09, 0xdb, 0xc0,
+ 0xf6, 0x2a, 0x6d, 0x82, 0xac, 0xff, 0x87, 0xf0, 0xd6, 0x04, 0xeb, 0xb3,
+ 0x8c, 0xfa, 0x4b, 0x26, 0x55, 0x06, 0x32, 0xa1, 0xaf, 0x0b, 0xfa, 0x2b,
+ 0x25, 0x83, 0x55, 0xc8, 0x9e, 0xf2, 0x0f, 0xc3, 0xac, 0xcb, 0x31, 0xa2,
+ 0xb1, 0xa4, 0x50, 0xab, 0xc3, 0x32, 0xd6, 0x23, 0xff, 0x2f, 0x2e, 0xc9,
+ 0x8a, 0x02, 0xe4, 0x8b, 0xb1, 0xd1, 0xfe, 0x13, 0x78, 0xb4, 0x5d, 0x06,
+ 0x4b, 0xe9, 0x42, 0x56, 0x76, 0x61, 0xfd, 0x7e, 0x0d, 0x6b, 0xea, 0xe2,
+ 0xfa, 0x93, 0xf5, 0xb2, 0x31, 0x80, 0x1d, 0xc0, 0x72, 0x74, 0xda, 0x46,
+ 0xfb, 0xec, 0x19, 0xe0, 0x61, 0x9c, 0x6b, 0x9e, 0xcc, 0xc5, 0x9c, 0x61,
+ 0xda, 0x3e, 0xc3, 0x90, 0x8f, 0xf9, 0x0a, 0xfb, 0x26, 0xbc, 0x49, 0xfb,
+ 0x1b, 0x36, 0x5b, 0xa9, 0xdd, 0xfe, 0x6e, 0xc1, 0xef, 0x94, 0xfd, 0x0d,
+ 0x99, 0x5a, 0xf2, 0xed, 0xef, 0x04, 0x7e, 0x77, 0xdb, 0xdf, 0x49, 0xfc,
+ 0xee, 0xd5, 0xbf, 0x27, 0xca, 0x7b, 0xf7, 0x2a, 0xff, 0x6a, 0xc9, 0xcf,
+ 0xb5, 0xcb, 0xe1, 0xd2, 0x7b, 0xad, 0x6c, 0xc1, 0x25, 0x9f, 0x77, 0xcc,
+ 0x3c, 0x01, 0x77, 0x99, 0x6d, 0x0a, 0xce, 0xb0, 0xb6, 0xdd, 0xda, 0x61,
+ 0xeb, 0xf4, 0x78, 0x9b, 0x85, 0x34, 0x30, 0xe1, 0x0c, 0x54, 0x9d, 0x6c,
+ 0x2c, 0xd3, 0x95, 0x1c, 0x97, 0x63, 0xf8, 0x2d, 0x5e, 0x2c, 0xf3, 0x79,
+ 0xdc, 0x0d, 0x0e, 0xbe, 0x00, 0x7d, 0x33, 0x5e, 0xa6, 0xbc, 0xf4, 0x31,
+ 0xf7, 0x94, 0x9c, 0x5f, 0x66, 0xaf, 0x11, 0x17, 0x4a, 0xf2, 0x53, 0xe9,
+ 0x47, 0x0a, 0x92, 0x2e, 0x4c, 0x83, 0x21, 0x0e, 0x04, 0xae, 0xbc, 0x27,
+ 0x00, 0xed, 0x5e, 0xed, 0xc8, 0xde, 0xab, 0x5d, 0xd8, 0x57, 0xfe, 0xf4,
+ 0x5e, 0xc8, 0xd8, 0x7c, 0xe9, 0xea, 0x18, 0xe9, 0x41, 0x9d, 0x95, 0x11,
+ 0x37, 0x03, 0x6c, 0x9f, 0xed, 0x1d, 0x1c, 0x2f, 0xe5, 0x3f, 0xac, 0x32,
+ 0xb7, 0xff, 0x6a, 0xae, 0x6f, 0x17, 0x74, 0x79, 0x18, 0xc6, 0x32, 0x6d,
+ 0xd0, 0x4b, 0x5c, 0x57, 0xea, 0xa9, 0x9b, 0x6e, 0x8a, 0x65, 0x1a, 0x64,
+ 0xe0, 0x60, 0x1b, 0xea, 0xb3, 0x9c, 0xb8, 0x72, 0xd0, 0x47, 0x3a, 0x35,
+ 0x28, 0x72, 0xf7, 0x44, 0xdf, 0xa2, 0x33, 0x3e, 0xf9, 0x73, 0xe0, 0xc7,
+ 0x7e, 0xc9, 0x1f, 0x7c, 0x00, 0xf8, 0x7d, 0xd9, 0x29, 0x4e, 0xbd, 0xe2,
+ 0x8c, 0x4f, 0xfd, 0x9d, 0x33, 0x31, 0xb5, 0x63, 0xc7, 0x50, 0xff, 0x8e,
+ 0x1d, 0xa3, 0xfd, 0xae, 0xd5, 0x2d, 0x3b, 0x76, 0x4c, 0xf4, 0x67, 0x31,
+ 0xff, 0x1e, 0x6f, 0x50, 0x7c, 0x6f, 0x2f, 0x95, 0x7c, 0xc2, 0xac, 0xfd,
+ 0x4c, 0xd0, 0x8d, 0xf7, 0x6c, 0xdf, 0xab, 0xdf, 0x0f, 0x48, 0x4f, 0xb2,
+ 0x55, 0x38, 0x7e, 0x87, 0xd5, 0x49, 0x6c, 0x07, 0x7a, 0xe9, 0xa5, 0x1d,
+ 0xa8, 0x50, 0x2f, 0x05, 0x7c, 0xd0, 0x26, 0xde, 0x06, 0x1b, 0x82, 0xed,
+ 0x94, 0x5d, 0xf7, 0x92, 0x6a, 0xf0, 0x63, 0xba, 0x5f, 0x75, 0x36, 0x13,
+ 0x33, 0x6b, 0xde, 0x63, 0xed, 0xeb, 0x4d, 0x28, 0xe7, 0x33, 0x71, 0x49,
+ 0x7c, 0xd1, 0xde, 0x69, 0xd0, 0xf6, 0x69, 0xbe, 0x44, 0x5a, 0x72, 0x65,
+ 0xac, 0xd4, 0x8f, 0x36, 0xa0, 0x97, 0xb3, 0xf6, 0x3a, 0x81, 0xf1, 0x0e,
+ 0xa2, 0xaf, 0x13, 0x47, 0xd1, 0x8e, 0xb2, 0x24, 0xdd, 0x2d, 0xea, 0x41,
+ 0xd4, 0xe9, 0xf1, 0xb6, 0x08, 0xed, 0x9a, 0x47, 0x24, 0x5f, 0x26, 0xdf,
+ 0xd3, 0x36, 0x88, 0x4b, 0xaa, 0x0d, 0xcf, 0xd5, 0xc3, 0xb0, 0x75, 0x1a,
+ 0x22, 0x7b, 0x43, 0x6a, 0x76, 0xd1, 0xaf, 0x2a, 0xf1, 0x0f, 0xcb, 0xc8,
+ 0xec, 0x76, 0xd4, 0x33, 0xf6, 0xbc, 0xf2, 0x61, 0x17, 0xcd, 0x66, 0x25,
+ 0xb7, 0xeb, 0x5e, 0xdc, 0x3d, 0x3c, 0x17, 0x71, 0x7f, 0x0b, 0xee, 0xe3,
+ 0xb8, 0x47, 0x70, 0x02, 0xe7, 0x41, 0xcc, 0xea, 0xb2, 0x51, 0x8c, 0xfd,
+ 0xef, 0x25, 0x37, 0x09, 0x7a, 0x2d, 0x85, 0x9b, 0x72, 0x7e, 0xd6, 0x53,
+ 0xa2, 0xb6, 0x28, 0x99, 0x40, 0x7d, 0xf8, 0x29, 0xfe, 0x11, 0x19, 0x3d,
+ 0x8d, 0xdf, 0x0f, 0xd2, 0xee, 0x9e, 0x90, 0xd1, 0x59, 0x8e, 0x53, 0x02,
+ 0x4c, 0x93, 0x92, 0x3f, 0xfd, 0x00, 0xae, 0x29, 0x5c, 0x0f, 0xe3, 0xe2,
+ 0xdc, 0xd8, 0xff, 0xc2, 0x66, 0x25, 0x2d, 0xfa, 0x39, 0x4f, 0xfa, 0xae,
+ 0xe2, 0x37, 0x69, 0xbb, 0x4a, 0x1b, 0x08, 0x74, 0x5d, 0x8d, 0xe8, 0x3d,
+ 0xb0, 0xbf, 0x93, 0x9a, 0xdf, 0x0b, 0xad, 0xa0, 0xa5, 0x6a, 0x56, 0xcb,
+ 0x22, 0xc0, 0x00, 0xb9, 0x03, 0x9b, 0xa4, 0x95, 0x73, 0xec, 0xb5, 0x65,
+ 0xbd, 0xba, 0x2c, 0xa5, 0xcb, 0xfa, 0x6c, 0x19, 0xee, 0xd5, 0x06, 0x19,
+ 0x69, 0x03, 0xc4, 0x94, 0xdb, 0x12, 0xe1, 0x93, 0xb2, 0x01, 0x74, 0x8d,
+ 0xf5, 0x3d, 0x7f, 0x59, 0xb9, 0xb8, 0xa8, 0xed, 0xbd, 0x73, 0x55, 0xd2,
+ 0x37, 0x69, 0x3e, 0x0c, 0xef, 0x0f, 0x9a, 0xd0, 0x3f, 0x65, 0x81, 0x48,
+ 0xc3, 0x09, 0x57, 0xa6, 0x3d, 0xd2, 0xc0, 0xc7, 0x5a, 0x48, 0x03, 0x8d,
+ 0x3e, 0x69, 0xbb, 0x9e, 0xef, 0xb8, 0x86, 0xec, 0xaf, 0x00, 0x1b, 0x92,
+ 0xb6, 0x64, 0x17, 0xec, 0x73, 0x8e, 0x71, 0x8c, 0xcf, 0x9e, 0x02, 0xaf,
+ 0xe5, 0x96, 0x78, 0x4d, 0x64, 0xa6, 0x44, 0xdc, 0x44, 0x36, 0x26, 0xd7,
+ 0x99, 0xf8, 0x39, 0x87, 0x39, 0xf3, 0x7e, 0xde, 0xe2, 0xe9, 0xf3, 0x16,
+ 0x4f, 0x4f, 0xda, 0xbb, 0xe7, 0xe4, 0xb5, 0xcd, 0x38, 0x8f, 0x67, 0xae,
+ 0x0f, 0xe8, 0xaa, 0x4a, 0x9e, 0x9b, 0xc6, 0x1d, 0x75, 0xcb, 0xe7, 0x64,
+ 0x54, 0xdb, 0x6f, 0x31, 0x79, 0x87, 0x96, 0x79, 0x5f, 0xc5, 0x5a, 0x96,
+ 0x00, 0x73, 0x83, 0x14, 0x12, 0x31, 0xbd, 0xf6, 0xae, 0xff, 0x5b, 0xae,
+ 0xa1, 0x55, 0xe2, 0x64, 0x99, 0xbf, 0x56, 0x07, 0x53, 0xe4, 0xa3, 0x12,
+ 0x2e, 0xd2, 0xee, 0xa7, 0x35, 0x5c, 0xb7, 0x40, 0x0e, 0x16, 0x44, 0xb5,
+ 0x35, 0xca, 0x95, 0xa0, 0x05, 0x95, 0x80, 0x46, 0x0b, 0x9f, 0x82, 0x3d,
+ 0x95, 0x9f, 0xa5, 0x9d, 0xde, 0x41, 0xdf, 0x28, 0x9e, 0xef, 0xdd, 0x48,
+ 0x3a, 0x52, 0x86, 0x6f, 0x1c, 0x95, 0xef, 0xd5, 0x74, 0xea, 0x28, 0x3f,
+ 0xa1, 0x6d, 0x71, 0xd7, 0xdf, 0xea, 0x5a, 0x9f, 0xde, 0x55, 0xfe, 0x96,
+ 0x95, 0x65, 0x29, 0xea, 0x67, 0xb4, 0x4b, 0xe5, 0x7b, 0xdb, 0xc8, 0x63,
+ 0x1e, 0xfc, 0xe1, 0xac, 0xf2, 0xb5, 0xff, 0x55, 0x50, 0x7d, 0x9b, 0x56,
+ 0xd4, 0xd7, 0x77, 0xc7, 0x3e, 0xbb, 0xf6, 0xee, 0xd9, 0x7b, 0xca, 0xde,
+ 0x0b, 0x6e, 0x1f, 0xef, 0x8e, 0xb8, 0x19, 0xde, 0xb1, 0x86, 0x19, 0xf6,
+ 0xa1, 0xf9, 0x2a, 0x34, 0xb6, 0x72, 0x97, 0x57, 0x14, 0xf2, 0xd5, 0x57,
+ 0xe5, 0x96, 0x59, 0x23, 0x97, 0xf7, 0x96, 0xc2, 0x10, 0x3e, 0xa2, 0xb7,
+ 0x00, 0xff, 0x38, 0x7b, 0xb0, 0x22, 0xb7, 0x54, 0x89, 0xb7, 0x4f, 0x02,
+ 0x7f, 0x43, 0x2e, 0x79, 0xd3, 0x13, 0xca, 0xe3, 0xbb, 0x84, 0xf6, 0x6a,
+ 0xb1, 0x44, 0x9c, 0x5f, 0x10, 0xae, 0x4d, 0xb1, 0xf4, 0xb4, 0x5e, 0x9b,
+ 0x23, 0xa5, 0x05, 0xe0, 0xe7, 0xcb, 0xa0, 0xfb, 0x30, 0x5c, 0x08, 0x8a,
+ 0xa0, 0x9c, 0x3f, 0xc6, 0x6f, 0xd8, 0x28, 0xa5, 0x67, 0xf1, 0x7e, 0xa3,
+ 0x14, 0x27, 0xc9, 0x73, 0xae, 0xe5, 0xe1, 0xb3, 0xe0, 0xa7, 0x9f, 0x41,
+ 0xbf, 0x28, 0xeb, 0xe3, 0xef, 0x1f, 0xe0, 0x1d, 0xee, 0xb3, 0x58, 0xc4,
+ 0x36, 0xda, 0x40, 0x1c, 0x9b, 0x6b, 0xc7, 0x35, 0xa3, 0xaf, 0x5e, 0xef,
+ 0x97, 0x73, 0xbd, 0xd2, 0xdd, 0x05, 0x59, 0x8a, 0x2b, 0xc8, 0xb9, 0x12,
+ 0xeb, 0x93, 0xfe, 0xfb, 0xd6, 0x19, 0x1d, 0xb1, 0xa1, 0xd9, 0xdc, 0x57,
+ 0xb6, 0xe5, 0x9a, 0xd7, 0xd3, 0x20, 0x7d, 0xa8, 0x74, 0x7f, 0x01, 0x72,
+ 0xc7, 0xf5, 0x37, 0xca, 0xa0, 0x96, 0x9d, 0xa4, 0x09, 0xd2, 0xc0, 0xcd,
+ 0xca, 0xd0, 0xe6, 0xfb, 0x95, 0xa1, 0xcd, 0xa7, 0x41, 0x8b, 0xb8, 0xca,
+ 0x8b, 0x8e, 0xa1, 0xcd, 0x2f, 0xe3, 0x8e, 0xab, 0xfc, 0xa2, 0x13, 0xf1,
+ 0xf1, 0x00, 0xfc, 0xca, 0xbd, 0x25, 0xd7, 0x19, 0xad, 0x82, 0x7e, 0xcb,
+ 0x71, 0x94, 0xcf, 0x13, 0xe7, 0x98, 0x3f, 0xc7, 0xd9, 0x69, 0xfb, 0x3f,
+ 0x27, 0x63, 0xe5, 0x50, 0xdb, 0x5b, 0xf9, 0xd9, 0x7b, 0x71, 0x5f, 0xaf,
+ 0xe5, 0x8c, 0xf2, 0xb3, 0xca, 0xc8, 0xab, 0x77, 0xe0, 0xde, 0x99, 0x3c,
+ 0x22, 0x9d, 0x5e, 0x4c, 0x9e, 0x45, 0x5f, 0xdf, 0x75, 0xc6, 0xaa, 0x2f,
+ 0xe3, 0xfa, 0x3e, 0xae, 0x57, 0x71, 0xbd, 0x82, 0x7e, 0x5f, 0x40, 0xf9,
+ 0x7a, 0x99, 0xf7, 0x9a, 0x51, 0x5f, 0xd4, 0x68, 0xf5, 0x79, 0x67, 0xe4,
+ 0xf4, 0x4b, 0xb8, 0x5c, 0x35, 0x56, 0x7d, 0xce, 0xc9, 0xcf, 0x86, 0x9b,
+ 0x16, 0x7c, 0xca, 0xb0, 0xaf, 0x3a, 0xa6, 0xef, 0x0c, 0xe6, 0x00, 0x9a,
+ 0x2e, 0xcf, 0x63, 0xec, 0xa7, 0x35, 0xcf, 0x0c, 0x42, 0x1f, 0xe4, 0x61,
+ 0xaf, 0x8c, 0x68, 0x98, 0xb6, 0x03, 0x3e, 0xf8, 0xd3, 0x7d, 0xb8, 0xcf,
+ 0x36, 0xca, 0x62, 0x82, 0xf6, 0xe5, 0x93, 0xba, 0x7e, 0xbe, 0x7c, 0xbd,
+ 0xc6, 0xed, 0xf4, 0x2a, 0xfe, 0xa1, 0x4f, 0x18, 0xc9, 0x03, 0x23, 0x8d,
+ 0x67, 0x4a, 0x94, 0x05, 0xd0, 0x4d, 0xa5, 0x09, 0xdc, 0x1b, 0xb5, 0x4c,
+ 0x28, 0x4a, 0x24, 0x0f, 0xd8, 0x8e, 0x32, 0xa1, 0x5e, 0xee, 0x50, 0xd6,
+ 0x50, 0xf6, 0x50, 0x96, 0x98, 0xf5, 0x18, 0x7d, 0x90, 0x32, 0xfc, 0x3a,
+ 0xe8, 0x4d, 0xda, 0x25, 0xbe, 0xf1, 0x4d, 0xa6, 0x72, 0xca, 0xc8, 0xd3,
+ 0xfd, 0x7a, 0x2d, 0xc6, 0x4a, 0x2a, 0x01, 0xc8, 0x51, 0x86, 0xeb, 0xe4,
+ 0x41, 0xdc, 0xf3, 0x6a, 0x0c, 0x57, 0xfe, 0xe4, 0xfb, 0xf0, 0x9b, 0x6b,
+ 0x33, 0x86, 0x7a, 0xb8, 0xca, 0xc3, 0xb8, 0xe3, 0x2a, 0xdf, 0xa8, 0x8c,
+ 0x1c, 0xe1, 0x9a, 0x26, 0xed, 0x9a, 0x3e, 0x09, 0x3c, 0x70, 0x7e, 0x4a,
+ 0xc7, 0x38, 0x94, 0xbf, 0x07, 0x78, 0xaf, 0x5a, 0x9f, 0x7a, 0xa3, 0x18,
+ 0x1e, 0xc4, 0xd5, 0x4d, 0x7e, 0x6e, 0x31, 0xeb, 0xa5, 0x69, 0x77, 0x5d,
+ 0x83, 0xe1, 0xc5, 0x04, 0xca, 0x62, 0x28, 0x6b, 0x33, 0x3a, 0x73, 0x09,
+ 0x8f, 0x59, 0x8b, 0x47, 0xfe, 0x56, 0xf6, 0x37, 0xe8, 0x09, 0xb6, 0x2e,
+ 0xe4, 0x35, 0xc6, 0xc5, 0x5c, 0x4e, 0xee, 0x57, 0xa3, 0x65, 0xfa, 0xc9,
+ 0x94, 0xe1, 0x8c, 0x65, 0x70, 0x7e, 0xec, 0x17, 0xe5, 0x1a, 0x07, 0x81,
+ 0xd4, 0xe2, 0x04, 0x4f, 0x62, 0xcd, 0xce, 0xc9, 0xa1, 0xf2, 0x47, 0xb4,
+ 0xdf, 0xde, 0x78, 0xc2, 0xac, 0x87, 0xa8, 0xa8, 0x1e, 0xfa, 0x4e, 0xd0,
+ 0xe6, 0xf9, 0x75, 0xfd, 0xde, 0x3d, 0xc1, 0xdf, 0x49, 0x1d, 0x4f, 0xaa,
+ 0xc9, 0x7b, 0x63, 0xef, 0x14, 0x97, 0xc9, 0x3a, 0xda, 0x1d, 0x58, 0xb3,
+ 0x4a, 0x3d, 0xde, 0x19, 0x47, 0xa0, 0xcc, 0x23, 0x3f, 0x1d, 0x01, 0x4f,
+ 0x60, 0xf2, 0x9a, 0xf7, 0xe9, 0x83, 0xac, 0xc5, 0x4f, 0x3e, 0x6c, 0x62,
+ 0x57, 0x4e, 0xc1, 0xa6, 0xdb, 0xbb, 0xd4, 0x07, 0x64, 0x65, 0x22, 0x2e,
+ 0xa7, 0x4b, 0x2d, 0x32, 0x5b, 0x52, 0x6d, 0x31, 0x2b, 0x3b, 0x63, 0x92,
+ 0xd4, 0xfa, 0x97, 0x76, 0xdf, 0xc0, 0x54, 0xcc, 0xd2, 0xdd, 0x8d, 0xe8,
+ 0xff, 0x93, 0xd0, 0xb1, 0x15, 0xe8, 0xd8, 0x8d, 0xd0, 0xc1, 0x2b, 0x65,
+ 0xc4, 0xfe, 0x86, 0xd5, 0x32, 0x82, 0x6d, 0xd2, 0xf0, 0xd6, 0x8f, 0xa0,
+ 0x5d, 0x44, 0x7f, 0x71, 0x4d, 0x6b, 0x79, 0x29, 0x38, 0x7b, 0xab, 0x13,
+ 0xce, 0xbe, 0xea, 0x4a, 0x1d, 0xd4, 0xe3, 0xb9, 0x62, 0x60, 0x3d, 0x5d,
+ 0xa2, 0xed, 0x9a, 0x0e, 0x72, 0xc0, 0xc9, 0x3e, 0xd0, 0xdd, 0x53, 0x93,
+ 0xf0, 0xef, 0x29, 0x97, 0x01, 0xf3, 0x19, 0xc0, 0x3c, 0x33, 0xe9, 0x44,
+ 0xb6, 0x81, 0x30, 0x40, 0x33, 0x33, 0xd5, 0x2b, 0x0b, 0x73, 0xa4, 0x43,
+ 0xc8, 0x80, 0x49, 0xac, 0x67, 0xb0, 0x0e, 0x76, 0x00, 0xc7, 0x87, 0xdc,
+ 0x9e, 0xda, 0xa6, 0xdf, 0x19, 0x7d, 0xde, 0x2e, 0x0b, 0x95, 0x3b, 0x2d,
+ 0x6c, 0xc7, 0xea, 0x60, 0x5b, 0xb7, 0x04, 0xdb, 0x3e, 0xc0, 0xb6, 0x7f,
+ 0x4d, 0xd8, 0xd6, 0xd2, 0xc5, 0x1d, 0xb0, 0x69, 0xc8, 0x1f, 0x11, 0x5e,
+ 0xdb, 0x2c, 0x3d, 0x94, 0xac, 0x1d, 0x4c, 0x9b, 0xe8, 0x87, 0x80, 0x87,
+ 0x34, 0x86, 0xdf, 0xb3, 0x8f, 0x52, 0x96, 0xa1, 0x9c, 0xcf, 0x0f, 0xa1,
+ 0x0e, 0x9e, 0x67, 0x13, 0x56, 0x0e, 0x7e, 0xc2, 0xc2, 0x42, 0x3b, 0x21,
+ 0x0b, 0x5b, 0x79, 0xd0, 0xc9, 0xcd, 0x12, 0x86, 0x53, 0x80, 0x17, 0xef,
+ 0xaa, 0xf5, 0x7d, 0xf2, 0xce, 0x7e, 0xaf, 0xb2, 0xfd, 0xb0, 0xef, 0x68,
+ 0x2e, 0xeb, 0xad, 0x9e, 0x8f, 0xe8, 0x2b, 0xb2, 0xbb, 0x27, 0x9c, 0xec,
+ 0xaa, 0x79, 0xd5, 0xd3, 0x1c, 0xe5, 0xad, 0x2b, 0x43, 0xa0, 0x93, 0xa1,
+ 0x65, 0xb4, 0xa6, 0xdd, 0x13, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x1b,
+ 0xbe, 0x09, 0xe2, 0xd0, 0x87, 0x94, 0x37, 0xff, 0xc5, 0xf8, 0xec, 0xf2,
+ 0xe5, 0x06, 0xc6, 0x69, 0xcd, 0x33, 0x69, 0x93, 0xbf, 0x29, 0x93, 0x6a,
+ 0xb4, 0x68, 0x7c, 0x9a, 0x76, 0x8c, 0x55, 0x6f, 0xc7, 0xbb, 0x32, 0x6c,
+ 0xd6, 0xfc, 0x18, 0xd7, 0x9c, 0x3e, 0x4a, 0xe7, 0x03, 0xc3, 0x96, 0xbf,
+ 0xd2, 0x93, 0x05, 0xb9, 0xd5, 0xce, 0xfd, 0xd2, 0x1a, 0x6b, 0xb7, 0x71,
+ 0x69, 0xed, 0x86, 0xab, 0x2b, 0xe7, 0x28, 0xd2, 0xf1, 0x80, 0xab, 0x7d,
+ 0x5e, 0xfa, 0xf0, 0x8d, 0x3e, 0xe5, 0x27, 0x6d, 0x25, 0x94, 0xcf, 0xf4,
+ 0x78, 0xad, 0xf0, 0x0d, 0xbe, 0xb8, 0xca, 0xee, 0x4a, 0x59, 0xb9, 0x49,
+ 0xff, 0x38, 0x1a, 0xa3, 0x60, 0xe5, 0x64, 0x01, 0xfd, 0x4f, 0x38, 0x43,
+ 0xd5, 0xb5, 0xe4, 0x65, 0x24, 0x27, 0x39, 0x9f, 0x7b, 0xe5, 0x8e, 0x07,
+ 0xc9, 0xa3, 0x25, 0x6d, 0x5f, 0x5f, 0xb3, 0xe7, 0x30, 0xf0, 0x47, 0xf8,
+ 0x17, 0x36, 0xc3, 0x64, 0x80, 0xce, 0xcd, 0xca, 0xa8, 0x5d, 0xb7, 0xd1,
+ 0xa5, 0xf5, 0xe7, 0x35, 0x0c, 0xdd, 0xc8, 0x58, 0xae, 0xb2, 0x30, 0x6b,
+ 0x3b, 0x16, 0x76, 0xdd, 0x4a, 0x5b, 0x96, 0x73, 0xa0, 0x3d, 0xdb, 0x68,
+ 0x6c, 0xc1, 0x32, 0xed, 0x4f, 0xca, 0x2e, 0xda, 0x9f, 0x57, 0x37, 0x4a,
+ 0x33, 0xe7, 0x93, 0xb5, 0x65, 0xb4, 0x53, 0x57, 0xce, 0x6f, 0xa5, 0x5f,
+ 0x49, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x94, 0x22, 0x6c, 0xa1, 0x0c, 0x07,
+ 0xd7, 0xe9, 0x35, 0x50, 0xb4, 0x5d, 0xf7, 0x34, 0x34, 0x9a, 0x38, 0xf6,
+ 0x5e, 0xf4, 0xcf, 0x31, 0xc9, 0x7f, 0xbc, 0xd3, 0xce, 0x5f, 0x4b, 0x96,
+ 0xd5, 0xeb, 0x9e, 0x2b, 0x97, 0xf0, 0x37, 0xb4, 0x6c, 0x8d, 0x22, 0xfc,
+ 0x45, 0x74, 0x51, 0x8f, 0x43, 0xd2, 0x04, 0x69, 0x21, 0xa2, 0xc5, 0x9d,
+ 0x56, 0xdf, 0x44, 0xb4, 0xb7, 0x15, 0xb4, 0x77, 0x1f, 0xf0, 0x44, 0x19,
+ 0xce, 0x78, 0xde, 0x16, 0x3c, 0x1f, 0xc7, 0x73, 0xc4, 0x27, 0x91, 0x0c,
+ 0xa7, 0x4d, 0xb4, 0x52, 0x8e, 0x53, 0x86, 0xc7, 0x61, 0xf7, 0x50, 0xd6,
+ 0x6f, 0xb7, 0xfc, 0x94, 0xb3, 0xbc, 0x44, 0x5d, 0xf0, 0xfb, 0xe8, 0xe7,
+ 0x86, 0x46, 0x63, 0xa7, 0x17, 0x1b, 0x29, 0x5f, 0x37, 0xcb, 0x91, 0xba,
+ 0xb2, 0xcb, 0xc9, 0xef, 0xfa, 0x39, 0x6f, 0xff, 0x7f, 0x30, 0xe7, 0xe4,
+ 0x8a, 0x39, 0x7b, 0x76, 0xce, 0x55, 0xbc, 0x6f, 0xc5, 0xfb, 0x16, 0xea,
+ 0x82, 0x54, 0x4d, 0xde, 0x58, 0x5c, 0x68, 0x7d, 0x56, 0x2f, 0x27, 0x22,
+ 0x19, 0xc1, 0x79, 0x1d, 0xb5, 0x73, 0xf8, 0x7c, 0xdd, 0xbc, 0x8e, 0xbe,
+ 0x89, 0x79, 0xb5, 0x2f, 0x9b, 0xd7, 0xde, 0xcb, 0xce, 0x6b, 0x2d, 0x1e,
+ 0x27, 0x2f, 0x47, 0xf3, 0x8b, 0xcb, 0x81, 0x12, 0xe7, 0x38, 0x84, 0x39,
+ 0x12, 0x86, 0x68, 0x8e, 0x19, 0x3b, 0x47, 0x51, 0x1d, 0x7b, 0x7e, 0x0a,
+ 0xbf, 0xeb, 0xe7, 0x47, 0xdd, 0xff, 0xf7, 0xa0, 0xe9, 0x26, 0xf8, 0xc4,
+ 0x4d, 0x56, 0xfe, 0x3f, 0x29, 0xb7, 0x96, 0xb9, 0xd6, 0xe9, 0xac, 0xc8,
+ 0x7e, 0x75, 0xa8, 0xfc, 0x72, 0x23, 0xf7, 0x11, 0xf6, 0x06, 0x56, 0x8f,
+ 0x41, 0x5f, 0xec, 0x83, 0xcd, 0x37, 0x54, 0x52, 0x7d, 0x31, 0x09, 0xc3,
+ 0xdb, 0x82, 0x66, 0x8c, 0xbd, 0x49, 0xfb, 0xaa, 0xab, 0x63, 0xf8, 0xcf,
+ 0x36, 0x8a, 0x4f, 0x7b, 0x83, 0xfa, 0x1c, 0xfa, 0xee, 0x24, 0x6d, 0xb0,
+ 0x1c, 0xec, 0xe4, 0x6c, 0x32, 0xa6, 0x6d, 0x31, 0xea, 0xc4, 0x74, 0x32,
+ 0x2b, 0x15, 0xc9, 0x9f, 0xcc, 0x26, 0xe1, 0xd8, 0x62, 0x0c, 0xd8, 0x6a,
+ 0xb0, 0x21, 0x6f, 0x85, 0xac, 0xb9, 0xb5, 0x7a, 0x50, 0xdd, 0x02, 0x7b,
+ 0xe7, 0x96, 0xd3, 0xef, 0x53, 0xb7, 0xc1, 0xd6, 0xb9, 0xed, 0xf4, 0x8d,
+ 0xea, 0x10, 0x6c, 0x9b, 0x43, 0xb0, 0x73, 0x0e, 0x55, 0x69, 0x7b, 0xde,
+ 0x0c, 0xba, 0x6b, 0x87, 0x1e, 0xe2, 0x5c, 0xb8, 0x26, 0xb4, 0x71, 0x38,
+ 0x3f, 0xe2, 0xfe, 0x0b, 0x5c, 0x83, 0x20, 0xa5, 0x76, 0x34, 0x71, 0x5d,
+ 0x5a, 0x97, 0x95, 0xbd, 0x96, 0xac, 0x8a, 0xf4, 0xd3, 0x06, 0x1b, 0x4f,
+ 0x32, 0x7e, 0xe5, 0xe5, 0x69, 0x8b, 0x34, 0xe2, 0x01, 0xcf, 0xc4, 0x1f,
+ 0x69, 0xab, 0x7e, 0xfe, 0x57, 0x36, 0x89, 0x9f, 0xc3, 0xf8, 0xf7, 0x42,
+ 0xbe, 0xd6, 0xd3, 0x14, 0xef, 0x5e, 0x1d, 0x7f, 0x50, 0x06, 0x47, 0xf4,
+ 0xb0, 0xf3, 0x35, 0xe4, 0xef, 0x65, 0xe9, 0xe9, 0x9e, 0x58, 0x26, 0x0c,
+ 0x47, 0xfb, 0x64, 0x13, 0xe3, 0x01, 0xb9, 0x6a, 0x2d, 0x26, 0xa0, 0xfc,
+ 0xfa, 0x98, 0x00, 0xfd, 0xac, 0x4f, 0x03, 0xbf, 0xd3, 0xb8, 0x44, 0x46,
+ 0x18, 0x77, 0xa8, 0x46, 0x76, 0xf9, 0x57, 0xac, 0x5d, 0x1e, 0xc1, 0x91,
+ 0x02, 0x1c, 0x46, 0x3e, 0xaf, 0xd6, 0x73, 0xcb, 0xf5, 0x77, 0x61, 0xc9,
+ 0xa6, 0x4d, 0xc9, 0x81, 0xb2, 0xb6, 0x13, 0x21, 0x83, 0x89, 0x9b, 0x7a,
+ 0x19, 0x9c, 0xb4, 0x76, 0x14, 0xea, 0x68, 0xf9, 0xb9, 0x5a, 0x76, 0x52,
+ 0xee, 0x31, 0x6e, 0xff, 0x40, 0x40, 0x5a, 0x7f, 0x97, 0x64, 0x97, 0xe2,
+ 0xf6, 0x02, 0x7a, 0x93, 0x20, 0x96, 0xd1, 0x7b, 0x7a, 0xde, 0x8c, 0xec,
+ 0x93, 0x81, 0x04, 0x63, 0xa0, 0x8c, 0xf3, 0xf9, 0x85, 0x19, 0xe9, 0x66,
+ 0x8c, 0x03, 0x16, 0x7c, 0xa3, 0x8c, 0x78, 0xa1, 0xec, 0x0d, 0x1c, 0x1d,
+ 0x53, 0x36, 0xba, 0xf6, 0x62, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0x17, 0x5e,
+ 0x00, 0xf5, 0x2d, 0x68, 0xfb, 0x56, 0x69, 0xfd, 0x3b, 0xaf, 0xeb, 0xfc,
+ 0x41, 0x53, 0x14, 0xdf, 0x5c, 0xf0, 0x62, 0xb6, 0x5e, 0x7d, 0xf9, 0xd7,
+ 0x6c, 0xdc, 0xba, 0x1b, 0xb2, 0x3f, 0x2a, 0xfb, 0xde, 0x1a, 0x65, 0xb1,
+ 0xf8, 0xea, 0xb2, 0xcd, 0x6b, 0x94, 0x99, 0x78, 0xe1, 0x50, 0x69, 0x27,
+ 0xde, 0x4d, 0x68, 0xdf, 0x5d, 0xf4, 0x9e, 0x5b, 0xb7, 0x14, 0x96, 0xea,
+ 0x6c, 0xb0, 0x7e, 0x19, 0x63, 0xc7, 0x26, 0x66, 0x9c, 0xd7, 0x31, 0xe3,
+ 0x1e, 0x6f, 0x8f, 0xd2, 0x7b, 0x2c, 0xb7, 0x33, 0xfe, 0x78, 0x48, 0xe3,
+ 0x85, 0x38, 0xf9, 0x02, 0x63, 0xc3, 0x05, 0xee, 0x0f, 0xa7, 0xd4, 0xe5,
+ 0x68, 0xbb, 0x66, 0x9b, 0x98, 0x75, 0xa3, 0x5d, 0xdc, 0x22, 0x83, 0xb0,
+ 0x15, 0x86, 0x4a, 0xad, 0xb2, 0x77, 0xea, 0xa3, 0xeb, 0xa8, 0xb7, 0xf6,
+ 0x4d, 0x19, 0x7f, 0xf0, 0x10, 0xf8, 0x2a, 0x2b, 0x84, 0x31, 0x1d, 0x88,
+ 0xd0, 0x26, 0x5e, 0x6d, 0x0b, 0xbf, 0x76, 0x7f, 0xf7, 0x5f, 0xa6, 0x3f,
+ 0x07, 0xb6, 0xc3, 0x1b, 0xed, 0xaf, 0x59, 0x06, 0xa7, 0x22, 0x5c, 0xa9,
+ 0x1f, 0xb1, 0x5d, 0xec, 0x32, 0xed, 0xb4, 0x5d, 0x22, 0x4f, 0x2d, 0xc9,
+ 0xe2, 0x9d, 0xb0, 0x99, 0x24, 0xcc, 0xf5, 0x49, 0x7b, 0x4c, 0x74, 0x8c,
+ 0x27, 0x30, 0xb2, 0xb9, 0x8b, 0x7b, 0x3e, 0xa0, 0x7f, 0x63, 0xab, 0x98,
+ 0x78, 0x6a, 0x64, 0xa7, 0xac, 0x45, 0xbb, 0xd7, 0x5b, 0xda, 0xe5, 0xbe,
+ 0xee, 0x3e, 0xca, 0x5c, 0xac, 0x89, 0xa1, 0xe3, 0xbd, 0x25, 0x49, 0x45,
+ 0x74, 0xbc, 0x20, 0xd9, 0x65, 0x74, 0xbc, 0x20, 0x83, 0x9a, 0x8e, 0x1b,
+ 0x97, 0xd1, 0x71, 0xbb, 0xa5, 0xe3, 0x8f, 0xc6, 0x0d, 0x5d, 0x28, 0xad,
+ 0xa7, 0x48, 0xa7, 0x86, 0x8e, 0x1d, 0x4d, 0xc7, 0x0b, 0xb8, 0xbb, 0xfe,
+ 0xc7, 0x6c, 0x9d, 0x98, 0x2d, 0xe3, 0xef, 0xa8, 0x8c, 0x72, 0x71, 0x2a,
+ 0x6e, 0xf4, 0xd2, 0x20, 0xe8, 0x28, 0x2a, 0xff, 0x4d, 0x4b, 0x9f, 0xf5,
+ 0x65, 0x26, 0x3e, 0x32, 0x54, 0x3a, 0xb2, 0x82, 0x3e, 0x07, 0x41, 0x9f,
+ 0x51, 0x9d, 0xd7, 0xa2, 0xcf, 0x66, 0xbb, 0x9f, 0x91, 0xd4, 0x7b, 0xff,
+ 0xd9, 0x84, 0xa1, 0xd5, 0x5b, 0xf4, 0xdc, 0x39, 0xef, 0x0b, 0x6f, 0x80,
+ 0x56, 0xcd, 0xda, 0x5c, 0xac, 0xf9, 0xdb, 0x8c, 0x45, 0xa5, 0x4c, 0x6c,
+ 0x9b, 0x71, 0xd2, 0xcb, 0xd9, 0x8e, 0x2f, 0xd5, 0xf9, 0x15, 0x1b, 0xa4,
+ 0xc0, 0xbc, 0x87, 0xea, 0x46, 0xc6, 0xa2, 0x47, 0xdc, 0x4c, 0x9f, 0x64,
+ 0x2b, 0xed, 0xa9, 0x62, 0x89, 0x7e, 0xd1, 0xab, 0x36, 0x37, 0x02, 0xcf,
+ 0x95, 0x16, 0x79, 0xb4, 0x44, 0xda, 0x3a, 0x62, 0x70, 0xb1, 0x26, 0xad,
+ 0x73, 0xad, 0xd9, 0x4f, 0xbd, 0x0e, 0xe8, 0x83, 0xee, 0xa1, 0xcd, 0xae,
+ 0xe5, 0x3e, 0xde, 0xb5, 0xa7, 0x72, 0xa5, 0xa8, 0x5f, 0xee, 0x3f, 0x70,
+ 0x4f, 0xb8, 0x3d, 0xd5, 0x51, 0xf1, 0x6d, 0x9c, 0x79, 0x23, 0x9e, 0xfb,
+ 0xa4, 0xa3, 0xa2, 0xe4, 0x03, 0x53, 0x2d, 0x72, 0x7b, 0xc9, 0x95, 0x0f,
+ 0xa1, 0xfd, 0x07, 0x4b, 0x1e, 0xfc, 0xfb, 0xff, 0x1d, 0xa7, 0x9d, 0x79,
+ 0xa8, 0xc4, 0x7d, 0x50, 0x47, 0xdb, 0x2a, 0xcb, 0xf7, 0x86, 0x63, 0xd2,
+ 0xd1, 0x55, 0x84, 0xe7, 0x23, 0xee, 0x7e, 0xc0, 0xd1, 0x94, 0xc9, 0xc8,
+ 0x77, 0xfa, 0x36, 0xa1, 0x2c, 0xca, 0xf1, 0x18, 0x76, 0x4c, 0xfc, 0xb8,
+ 0x5f, 0xde, 0x59, 0xcd, 0xc8, 0x0d, 0x55, 0xb3, 0x77, 0x5b, 0xdb, 0x9b,
+ 0x4d, 0x7b, 0xf3, 0xd0, 0x67, 0x59, 0x2f, 0x0c, 0x2f, 0xfa, 0xa0, 0xa2,
+ 0xe3, 0xae, 0xc4, 0xbb, 0xd2, 0xc9, 0x79, 0x31, 0xcf, 0x97, 0x2a, 0xff,
+ 0x1c, 0x8e, 0x24, 0x5c, 0xf9, 0x8e, 0xcf, 0x39, 0xf6, 0xcb, 0xf5, 0x95,
+ 0xfa, 0xb1, 0xb9, 0x3f, 0x1b, 0x5b, 0xc7, 0xfd, 0x90, 0x5c, 0xf5, 0x9f,
+ 0xe3, 0x8c, 0xdb, 0xd3, 0x87, 0xe9, 0xf8, 0x31, 0xee, 0x87, 0xbb, 0xb8,
+ 0x83, 0x0e, 0x13, 0xb0, 0x21, 0xae, 0x01, 0x8c, 0xd7, 0x30, 0x96, 0xc6,
+ 0x18, 0x1a, 0x9f, 0xbf, 0x8c, 0x71, 0xd9, 0xf6, 0x93, 0xd6, 0xfe, 0x3e,
+ 0xb2, 0xc4, 0x8b, 0x6b, 0xeb, 0xb1, 0x8d, 0x23, 0xf1, 0x8c, 0x38, 0xf1,
+ 0x9f, 0x48, 0xca, 0x3a, 0xbf, 0x7e, 0x7c, 0xee, 0x47, 0xc3, 0xa2, 0xec,
+ 0x13, 0x77, 0xdf, 0xee, 0x7e, 0x19, 0xc4, 0xfc, 0x86, 0x56, 0xcd, 0xef,
+ 0x1e, 0x61, 0xbc, 0xf6, 0x52, 0x89, 0x73, 0xa8, 0xcd, 0x4b, 0xfd, 0xb6,
+ 0x99, 0x57, 0xbc, 0x6b, 0xe5, 0x7c, 0x74, 0x7b, 0x75, 0x0a, 0xb0, 0x7c,
+ 0x49, 0xe7, 0x42, 0x84, 0xe1, 0x5b, 0xbb, 0x2e, 0x85, 0xa9, 0x2b, 0xd2,
+ 0xdd, 0xf3, 0xb5, 0x7d, 0xa4, 0x91, 0x58, 0x26, 0xab, 0xf5, 0x23, 0x9e,
+ 0x53, 0xf9, 0xca, 0x7e, 0xac, 0xa3, 0xb8, 0xf9, 0x5e, 0x57, 0xf3, 0x5d,
+ 0xde, 0xdf, 0x6f, 0xf7, 0xca, 0x22, 0x9f, 0x2c, 0x0c, 0x95, 0xbf, 0x52,
+ 0x0e, 0x51, 0xff, 0x61, 0xee, 0xf2, 0x98, 0xdd, 0x3f, 0xe8, 0x66, 0x7c,
+ 0x0c, 0xb4, 0x18, 0x07, 0xdd, 0xf9, 0xf8, 0xdd, 0x82, 0xfb, 0x1e, 0xd8,
+ 0x3f, 0x01, 0xec, 0x23, 0x49, 0x28, 0x23, 0x6b, 0xc0, 0x1b, 0x5d, 0x05,
+ 0xa5, 0xc8, 0xeb, 0x5e, 0x6a, 0xbc, 0x92, 0x48, 0x4d, 0x56, 0x9e, 0x60,
+ 0x7b, 0xd4, 0x5d, 0x2b, 0x36, 0x68, 0xf2, 0x6c, 0xbe, 0x58, 0xe5, 0x18,
+ 0xa4, 0xfb, 0x37, 0x32, 0x86, 0x6b, 0xfb, 0x66, 0x9f, 0x11, 0x5e, 0x5c,
+ 0xba, 0xf8, 0xf8, 0xb7, 0xdf, 0xfa, 0x3a, 0x9c, 0xdf, 0x13, 0x16, 0xee,
+ 0x95, 0xe3, 0x3e, 0xaf, 0xed, 0xa1, 0xc7, 0xab, 0xb4, 0x41, 0xb9, 0x8f,
+ 0x94, 0x7e, 0x64, 0x5a, 0x08, 0x47, 0x18, 0x3e, 0x1b, 0x18, 0x5b, 0xe0,
+ 0x8b, 0x55, 0xee, 0x99, 0x84, 0xe1, 0xdf, 0xd2, 0xce, 0x3e, 0x58, 0xc6,
+ 0x78, 0x11, 0x0e, 0x76, 0x16, 0x5c, 0xc8, 0xd9, 0x89, 0x3e, 0xe2, 0x57,
+ 0xe0, 0xf1, 0x76, 0x79, 0x07, 0x24, 0x9e, 0xfa, 0x78, 0xa5, 0x25, 0x75,
+ 0x67, 0xc5, 0x03, 0x9e, 0x39, 0xef, 0x44, 0x6a, 0xcc, 0xce, 0x39, 0x5f,
+ 0x21, 0x7e, 0x5f, 0x6b, 0xbf, 0xf3, 0xf9, 0x65, 0xfe, 0x17, 0x61, 0xaa,
+ 0xc1, 0x42, 0xd8, 0x52, 0x16, 0x37, 0x61, 0xf8, 0xf7, 0x01, 0xc7, 0xdc,
+ 0x0f, 0x1f, 0x46, 0x26, 0x30, 0x6e, 0x61, 0x8b, 0x22, 0x1e, 0xe2, 0xa9,
+ 0x3b, 0x30, 0xf6, 0xc7, 0x31, 0xf6, 0xed, 0x15, 0x8e, 0x07, 0xd9, 0x83,
+ 0xb9, 0x4f, 0x54, 0x23, 0x78, 0xd7, 0x1a, 0x3b, 0x5a, 0xf3, 0x6e, 0x6b,
+ 0x33, 0x46, 0xcf, 0x1a, 0x91, 0x6d, 0x0a, 0xbe, 0x63, 0xae, 0xba, 0xb0,
+ 0xd9, 0x95, 0x9f, 0x81, 0x1c, 0x0f, 0xe5, 0x51, 0xc8, 0xc7, 0x05, 0x4d,
+ 0x37, 0xb9, 0xed, 0xfc, 0x3f, 0x26, 0x4f, 0xad, 0x63, 0xbc, 0x7a, 0xc0,
+ 0xa7, 0x2d, 0xbc, 0x18, 0x2e, 0xf8, 0x94, 0xf7, 0x1b, 0x64, 0xda, 0x2b,
+ 0x74, 0x43, 0xf7, 0xa0, 0x6c, 0x23, 0xfd, 0xf7, 0x54, 0x2e, 0x96, 0x4e,
+ 0x8d, 0x0b, 0x73, 0xbe, 0x98, 0x13, 0xc1, 0xbc, 0x26, 0xca, 0x06, 0x17,
+ 0x32, 0x94, 0x6b, 0x68, 0xc6, 0x1b, 0xaf, 0xd4, 0xea, 0x1e, 0x16, 0xee,
+ 0x4d, 0xa6, 0x93, 0x87, 0xb4, 0xbd, 0x23, 0x32, 0x5a, 0x62, 0xdd, 0xdd,
+ 0xb0, 0x76, 0xfc, 0xba, 0xfa, 0x3a, 0x57, 0x0d, 0x7c, 0x1e, 0xc5, 0xc5,
+ 0xe2, 0xcc, 0x29, 0x79, 0x39, 0xd6, 0x27, 0x2f, 0xd3, 0x8e, 0x1d, 0x00,
+ 0x6d, 0x7b, 0xbe, 0xce, 0x2b, 0xd1, 0xe5, 0xb9, 0x40, 0x16, 0x73, 0xfd,
+ 0x3d, 0xb4, 0xdb, 0x0b, 0x4a, 0xf3, 0x84, 0x28, 0xb4, 0x8d, 0xe7, 0x2b,
+ 0x32, 0x98, 0x2f, 0xd9, 0xd8, 0xd1, 0x30, 0xe7, 0xbc, 0xa1, 0x6e, 0xee,
+ 0x1b, 0xc5, 0x05, 0x4c, 0x83, 0xb1, 0x94, 0xd3, 0xe0, 0x7f, 0xaa, 0xc5,
+ 0xd8, 0x10, 0xd0, 0x23, 0xad, 0xf7, 0xb7, 0x71, 0x6f, 0x56, 0xc1, 0x27,
+ 0x57, 0x6d, 0x1f, 0xbe, 0x56, 0x65, 0xfe, 0x32, 0x09, 0xbd, 0x6a, 0x65,
+ 0x65, 0x7c, 0xb0, 0x63, 0x89, 0xbe, 0x39, 0xbe, 0xb4, 0xc5, 0xfc, 0xd4,
+ 0xe0, 0x40, 0x45, 0x54, 0x2c, 0xe3, 0xc5, 0x07, 0x2a, 0xcb, 0x69, 0xfe,
+ 0x8b, 0xd5, 0xcf, 0x5a, 0xdb, 0xb2, 0x3e, 0x46, 0x5b, 0xff, 0x8e, 0x7c,
+ 0xb7, 0x6c, 0xff, 0x23, 0x05, 0xbe, 0xb2, 0xfb, 0xc6, 0x5c, 0x93, 0xec,
+ 0x5b, 0x19, 0xd8, 0x9c, 0xd6, 0x3e, 0x1f, 0x73, 0x3b, 0xe2, 0x36, 0xbf,
+ 0xce, 0xe0, 0x3a, 0x5b, 0x71, 0x64, 0x02, 0xf2, 0xe1, 0xb0, 0xfc, 0x53,
+ 0x98, 0x4d, 0x98, 0xf7, 0x66, 0x7d, 0x59, 0x9f, 0x7b, 0x1b, 0xcd, 0x52,
+ 0x3c, 0xed, 0x4a, 0xe1, 0x34, 0xf7, 0xd4, 0xce, 0xdd, 0x51, 0xcb, 0x0f,
+ 0xa1, 0x1c, 0xe0, 0xbe, 0xb0, 0x23, 0x45, 0xf8, 0xc8, 0x83, 0xdc, 0xef,
+ 0xef, 0xfd, 0x47, 0xe6, 0xea, 0xc4, 0xb9, 0x4e, 0xa6, 0x6d, 0x0b, 0xda,
+ 0x36, 0xda, 0xb6, 0xc1, 0xc7, 0xdf, 0x5c, 0xdb, 0x8d, 0x68, 0x1b, 0x8f,
+ 0xc6, 0x7d, 0x83, 0x6d, 0x35, 0x3e, 0xaf, 0x1d, 0x28, 0x95, 0x17, 0x5d,
+ 0xdf, 0x4f, 0x8e, 0x49, 0xd6, 0x19, 0xed, 0xd3, 0xf3, 0xb9, 0x76, 0xa0,
+ 0x02, 0x38, 0x12, 0x61, 0x58, 0x0c, 0x22, 0xbd, 0xce, 0x7f, 0x27, 0xa1,
+ 0xde, 0x59, 0xc6, 0x7d, 0x50, 0xfa, 0x27, 0x8c, 0xba, 0x7a, 0xcc, 0xc1,
+ 0x93, 0x22, 0xf7, 0x3b, 0x13, 0x9b, 0x70, 0x57, 0x1d, 0xc4, 0x49, 0xde,
+ 0x67, 0xfc, 0x78, 0x93, 0x2d, 0x8f, 0xb1, 0x3c, 0xed, 0x42, 0x96, 0x98,
+ 0xf2, 0x98, 0x2d, 0x07, 0x4c, 0x41, 0x31, 0x05, 0x6e, 0xb3, 0xe5, 0x7c,
+ 0x56, 0xba, 0xdc, 0x3c, 0x1b, 0x1e, 0x1a, 0x11, 0xc6, 0x89, 0x72, 0xd7,
+ 0x37, 0xc8, 0x4e, 0xac, 0x0f, 0x7d, 0x50, 0x47, 0x9a, 0x01, 0xc7, 0xc5,
+ 0xe0, 0xc7, 0x61, 0xab, 0x87, 0xf2, 0x9d, 0xc0, 0xd0, 0xff, 0x8c, 0x74,
+ 0x65, 0x95, 0xc3, 0x5c, 0x83, 0x50, 0x86, 0x82, 0x5d, 0xc9, 0xbd, 0xf8,
+ 0x3d, 0xda, 0x9b, 0x92, 0x99, 0x7e, 0xd0, 0x63, 0x2f, 0x79, 0x63, 0x27,
+ 0x6c, 0x28, 0xfc, 0xee, 0x6a, 0x91, 0x45, 0xaf, 0xe0, 0xad, 0x83, 0xff,
+ 0x37, 0x88, 0x59, 0xcd, 0x96, 0x7c, 0xef, 0x36, 0x08, 0xb9, 0xac, 0xd7,
+ 0x85, 0x7b, 0xfd, 0x7c, 0xbf, 0x8e, 0xf9, 0x9e, 0x6b, 0x96, 0x66, 0x96,
+ 0xd7, 0xd7, 0x6d, 0x94, 0xfd, 0xde, 0x6e, 0x2f, 0xbe, 0xac, 0xee, 0x25,
+ 0xd4, 0x65, 0x99, 0xef, 0x31, 0x17, 0x68, 0xa6, 0x42, 0x3a, 0x33, 0xb0,
+ 0x76, 0x74, 0x85, 0xe1, 0xf5, 0x01, 0xc7, 0x0d, 0xc3, 0x1b, 0x82, 0x1e,
+ 0xef, 0x19, 0x79, 0x2e, 0x34, 0x36, 0x5a, 0x44, 0x3b, 0xcf, 0x5a, 0x79,
+ 0x1d, 0x86, 0x2f, 0x07, 0xdd, 0xf2, 0xb9, 0x6a, 0xfa, 0x1c, 0x7d, 0xf8,
+ 0xf3, 0x78, 0x3e, 0x1f, 0x98, 0xfc, 0xa5, 0x3f, 0x43, 0xbb, 0x84, 0xea,
+ 0x05, 0x0d, 0xfb, 0xf2, 0x59, 0xed, 0xf3, 0x13, 0x7f, 0x66, 0xcf, 0xa0,
+ 0x06, 0x03, 0x26, 0xec, 0xe7, 0x36, 0x7b, 0xcc, 0x69, 0xd4, 0xf4, 0x5b,
+ 0xff, 0x4e, 0xe1, 0x1d, 0xcb, 0xc2, 0xf0, 0x8a, 0xbe, 0x96, 0xf5, 0xd0,
+ 0xd7, 0x93, 0xdc, 0x0b, 0x7c, 0x9f, 0xe6, 0x3f, 0x91, 0x03, 0xdc, 0xf7,
+ 0x02, 0x0e, 0x95, 0xf2, 0x8f, 0x75, 0xa8, 0x74, 0x41, 0xe4, 0x2d, 0x58,
+ 0x7f, 0xae, 0x31, 0x18, 0xa4, 0x15, 0xb0, 0xef, 0xfa, 0xa5, 0x66, 0x13,
+ 0x9b, 0xa2, 0x6f, 0x9e, 0xdd, 0x0c, 0xdf, 0x59, 0xdb, 0x33, 0xdc, 0x57,
+ 0x1f, 0x6b, 0x0d, 0xc3, 0xf7, 0x06, 0xd1, 0x9a, 0xd9, 0xd8, 0x37, 0x74,
+ 0x7c, 0xbe, 0x57, 0xd6, 0x1b, 0xbb, 0x90, 0xb9, 0x8d, 0x29, 0xbd, 0x4f,
+ 0xa0, 0xda, 0xa0, 0x43, 0x76, 0xfd, 0x00, 0x38, 0xe5, 0x18, 0xcc, 0x73,
+ 0x8c, 0x60, 0xaa, 0xb5, 0xcf, 0xf7, 0xae, 0xb3, 0x36, 0xac, 0x0b, 0x5c,
+ 0xfa, 0x5e, 0x87, 0xfa, 0x5e, 0x68, 0x74, 0x6b, 0x44, 0xc3, 0xff, 0x10,
+ 0x3e, 0x98, 0x30, 0xcf, 0xb9, 0x5d, 0xec, 0x63, 0xa7, 0x8c, 0xef, 0xc2,
+ 0xb3, 0x7b, 0x1d, 0xee, 0x03, 0x57, 0xc6, 0xe4, 0xaa, 0xe4, 0x80, 0xda,
+ 0xe5, 0x3d, 0x28, 0x3d, 0x56, 0xc6, 0x7d, 0x09, 0xfa, 0xbe, 0x00, 0xff,
+ 0xbe, 0x49, 0x1e, 0x04, 0x4d, 0xab, 0xbe, 0x74, 0x6a, 0x5e, 0xa5, 0xbb,
+ 0xa7, 0x55, 0x3a, 0x18, 0x51, 0x13, 0x9c, 0x57, 0x3f, 0x71, 0x31, 0x4d,
+ 0xfc, 0x96, 0x81, 0xff, 0x32, 0x70, 0x7c, 0xd9, 0x3d, 0xe3, 0xc0, 0xea,
+ 0x16, 0xa3, 0xdf, 0x0a, 0x9a, 0x36, 0x8d, 0x9d, 0xff, 0xa7, 0x41, 0xb4,
+ 0x86, 0x3d, 0x5e, 0x03, 0x73, 0x71, 0xd6, 0x5c, 0xa3, 0x3c, 0xd7, 0x08,
+ 0x8a, 0xa1, 0x00, 0xba, 0x4f, 0xa7, 0xc6, 0xd4, 0x62, 0xb8, 0x79, 0x4f,
+ 0x67, 0xf7, 0x63, 0xba, 0x9f, 0x74, 0x90, 0x55, 0x4f, 0x02, 0x9e, 0x9d,
+ 0xd2, 0xb4, 0x87, 0x78, 0x26, 0xac, 0x71, 0xc6, 0xa7, 0xbc, 0x3b, 0x50,
+ 0x77, 0x44, 0xe9, 0x3d, 0x6d, 0x5b, 0x87, 0x30, 0xbf, 0x1b, 0xf8, 0xa5,
+ 0x1e, 0x62, 0xcc, 0xed, 0xb5, 0x74, 0x21, 0x64, 0xd2, 0x49, 0xca, 0xc0,
+ 0x98, 0x89, 0x25, 0x57, 0xef, 0xe4, 0xfa, 0xd3, 0x13, 0x88, 0xbb, 0x90,
+ 0x51, 0x13, 0xe0, 0xe2, 0xa3, 0x27, 0xc5, 0x6d, 0xf0, 0xbb, 0xd7, 0x1b,
+ 0x3f, 0x8c, 0x3e, 0x19, 0xc7, 0x6e, 0x90, 0xe2, 0xaa, 0xf8, 0xcd, 0x24,
+ 0xe0, 0x6f, 0x96, 0xf1, 0x93, 0x5c, 0x0b, 0x17, 0x32, 0x87, 0x63, 0x8b,
+ 0x9b, 0xeb, 0x0d, 0xc3, 0x51, 0x96, 0x9f, 0x26, 0xff, 0x4a, 0x9a, 0xef,
+ 0x0a, 0xa7, 0xe7, 0x37, 0xab, 0x65, 0xb2, 0xb6, 0xc5, 0xc2, 0xa1, 0xf1,
+ 0x24, 0x93, 0x5a, 0x8e, 0x50, 0xdf, 0xcc, 0xd4, 0xc1, 0x13, 0x7c, 0x7c,
+ 0xc2, 0x6f, 0x7c, 0x13, 0xf0, 0xfc, 0x0f, 0xc0, 0xd3, 0x62, 0xe1, 0x69,
+ 0x5c, 0x01, 0x4f, 0x4b, 0x04, 0x0f, 0xe4, 0x1c, 0xe5, 0x6a, 0xfc, 0xda,
+ 0x6c, 0x45, 0x9c, 0xa2, 0x2f, 0xed, 0x4a, 0xfb, 0x43, 0xd4, 0x37, 0x8d,
+ 0xde, 0x68, 0x9f, 0x27, 0xa3, 0x5a, 0xd7, 0xb8, 0xd7, 0x76, 0x56, 0xe6,
+ 0x61, 0xbd, 0x8a, 0x93, 0xf3, 0x09, 0xfb, 0x5a, 0x76, 0xd5, 0x3d, 0x90,
+ 0xff, 0x0b, 0x69, 0xd7, 0xda, 0x12, 0x93, 0x01, 0xfd, 0xa0, 0x84, 0xce,
+ 0x15, 0xa8, 0xc1, 0xf4, 0x12, 0x60, 0x82, 0x3c, 0x3e, 0xd9, 0xe3, 0x0d,
+ 0xcb, 0x56, 0xed, 0xeb, 0x59, 0x5c, 0x63, 0x6e, 0xf1, 0xba, 0xb9, 0x41,
+ 0xff, 0xa9, 0x68, 0x6e, 0x90, 0x89, 0xa8, 0x37, 0x29, 0x7f, 0x64, 0x71,
+ 0xb1, 0x11, 0x73, 0x8a, 0xd7, 0xcd, 0xa7, 0x33, 0x79, 0x3b, 0xcb, 0xcc,
+ 0x7c, 0xba, 0x8a, 0x7e, 0xdc, 0xe2, 0x77, 0x2d, 0x9f, 0xc4, 0xd8, 0x3d,
+ 0xd3, 0x12, 0xca, 0x44, 0x80, 0x35, 0xea, 0xa6, 0x7f, 0x12, 0xb7, 0xb9,
+ 0xd7, 0x0a, 0xcf, 0x1b, 0x2c, 0x7f, 0x79, 0x52, 0xd4, 0xfe, 0xe0, 0xdf,
+ 0x59, 0x3e, 0x75, 0x6d, 0x9e, 0x1c, 0x7f, 0x1f, 0x5c, 0x6f, 0xf3, 0x05,
+ 0x0a, 0x59, 0x79, 0x65, 0x3d, 0xed, 0x92, 0x06, 0xff, 0x57, 0x56, 0x94,
+ 0xc5, 0x51, 0x76, 0x6a, 0xbd, 0x95, 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1f,
+ 0xf3, 0x3e, 0xf8, 0x8e, 0x32, 0xb8, 0x1e, 0x27, 0x3d, 0x60, 0x45, 0xf2,
+ 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, 0x51, 0x6d, 0x8f, 0xe2, 0xf2, 0xf8,
+ 0xbd, 0x96, 0xed, 0x4f, 0x7c, 0x13, 0xd7, 0xf2, 0x8d, 0x09, 0xf0, 0xfd,
+ 0xe1, 0xc0, 0x71, 0x67, 0x98, 0x57, 0xa0, 0x69, 0xb8, 0xbe, 0xef, 0x1b,
+ 0x18, 0x26, 0xb4, 0xb4, 0x4c, 0x7a, 0x21, 0x4f, 0x3b, 0xd2, 0x44, 0x5d,
+ 0x7c, 0xd2, 0xd3, 0x39, 0xee, 0x39, 0xad, 0x97, 0xeb, 0xd7, 0xb1, 0x09,
+ 0xba, 0x26, 0x61, 0x78, 0xd4, 0x33, 0xfb, 0xe7, 0xb5, 0xfe, 0x46, 0xd0,
+ 0x1f, 0xed, 0x34, 0xf8, 0xfd, 0x3e, 0xa3, 0x43, 0x94, 0x5f, 0x8e, 0xab,
+ 0xae, 0xd6, 0x7e, 0x6b, 0x5c, 0xe7, 0x37, 0x2d, 0xd5, 0x1d, 0xb3, 0x63,
+ 0x93, 0x6e, 0xcd, 0x7e, 0x42, 0x6d, 0x7c, 0x71, 0xd4, 0x2e, 0x01, 0x95,
+ 0x35, 0xca, 0x44, 0x1f, 0x69, 0x94, 0x73, 0xd7, 0x36, 0xd4, 0xb5, 0xb4,
+ 0x23, 0x0c, 0x7d, 0xd2, 0x76, 0x72, 0xaf, 0xcd, 0x97, 0x1a, 0x8d, 0xcf,
+ 0x92, 0x90, 0x2d, 0x0d, 0x3a, 0x2f, 0x01, 0x65, 0x95, 0x48, 0x97, 0xb9,
+ 0x32, 0xd3, 0xfb, 0x7f, 0xc2, 0xec, 0x41, 0xd6, 0x5d, 0x33, 0x0f, 0x20,
+ 0x39, 0x2d, 0x1a, 0x4f, 0x5f, 0xab, 0xe1, 0xc9, 0xce, 0x2d, 0xb1, 0x72,
+ 0x6e, 0x70, 0x6a, 0xfd, 0x7b, 0x20, 0x3b, 0xb9, 0x4e, 0x26, 0xe7, 0xfc,
+ 0x9c, 0x38, 0x6e, 0xae, 0x7b, 0xad, 0xb9, 0x4d, 0x46, 0x78, 0xe5, 0xdc,
+ 0x40, 0xab, 0xd1, 0xbc, 0x48, 0xdb, 0x09, 0xbd, 0xef, 0xa4, 0x14, 0x61,
+ 0xd9, 0xb8, 0x02, 0xb7, 0x11, 0xdd, 0x19, 0x9a, 0xfb, 0xa2, 0xa6, 0xb9,
+ 0x16, 0x4b, 0x73, 0xa8, 0xeb, 0x71, 0x1f, 0xfd, 0xbe, 0x96, 0x1a, 0xcd,
+ 0x6d, 0xb0, 0x34, 0xa7, 0x5a, 0xcc, 0x1e, 0x7b, 0xb9, 0xc5, 0xec, 0x71,
+ 0x25, 0x57, 0x3c, 0xbf, 0x93, 0xcf, 0xf0, 0xc5, 0xa2, 0xe7, 0x7a, 0x58,
+ 0xcf, 0x03, 0xd6, 0x7a, 0x59, 0xd3, 0x64, 0xe3, 0x78, 0xdc, 0x8f, 0xa7,
+ 0xdf, 0xe7, 0xca, 0xa3, 0xb0, 0x83, 0x8a, 0x95, 0x1f, 0x84, 0xf3, 0xf0,
+ 0xfd, 0x26, 0x96, 0x74, 0xef, 0x4c, 0x0b, 0xf9, 0x6d, 0x1a, 0xbf, 0x8e,
+ 0xd4, 0xf9, 0x3c, 0x98, 0x2f, 0xca, 0xfe, 0x19, 0xeb, 0x01, 0xb9, 0xbc,
+ 0x54, 0x97, 0x31, 0x10, 0xe3, 0xe3, 0x9c, 0xab, 0xb6, 0xdb, 0xfd, 0x49,
+ 0xca, 0xf9, 0xbb, 0xe1, 0x13, 0xdd, 0x03, 0x3d, 0x49, 0xfa, 0xee, 0xd8,
+ 0x60, 0xf2, 0x89, 0x13, 0xd0, 0x63, 0x3f, 0x6f, 0x73, 0xab, 0x6e, 0xbf,
+ 0x7d, 0xed, 0x5c, 0x62, 0xd0, 0xbe, 0x43, 0x9a, 0x79, 0xdb, 0x06, 0x13,
+ 0x83, 0xde, 0xba, 0x81, 0x7c, 0xa6, 0x76, 0xed, 0xda, 0xa8, 0xf9, 0xc2,
+ 0x89, 0x9e, 0xab, 0x2b, 0x9e, 0xa3, 0x76, 0x7f, 0xb3, 0x71, 0x79, 0xbb,
+ 0xa8, 0xfc, 0xce, 0x4d, 0xcb, 0xcb, 0xff, 0xa3, 0xb7, 0xbc, 0x7d, 0xe3,
+ 0xe6, 0xe5, 0xcf, 0x7b, 0x57, 0x3c, 0x7f, 0x64, 0xc5, 0xf3, 0xef, 0xad,
+ 0x78, 0xde, 0xd1, 0xba, 0xfc, 0xf9, 0x43, 0x2b, 0x9e, 0x4f, 0xb5, 0xae,
+ 0x0d, 0xef, 0x42, 0xeb, 0x72, 0xb8, 0xee, 0xd6, 0xfb, 0x07, 0xd3, 0x55,
+ 0x57, 0xf6, 0x96, 0xf0, 0xde, 0x79, 0xdf, 0x16, 0xa3, 0xd7, 0xea, 0xdf,
+ 0x33, 0x5e, 0xb7, 0x7b, 0xcb, 0xf2, 0xfe, 0x6a, 0xed, 0xf6, 0xd5, 0xda,
+ 0x05, 0xb5, 0x76, 0x46, 0xb6, 0xcd, 0x54, 0xf9, 0x8e, 0xe5, 0x51, 0xbf,
+ 0xa6, 0xed, 0x44, 0xd9, 0xd7, 0x39, 0xb7, 0xc3, 0x3a, 0xe7, 0x36, 0x05,
+ 0x3e, 0xbc, 0x5b, 0xc7, 0xa8, 0x36, 0xc3, 0x50, 0x1e, 0xaf, 0x6e, 0xd4,
+ 0x71, 0x2a, 0xd1, 0x79, 0xb7, 0xc3, 0xb0, 0x6d, 0x99, 0x6b, 0x1b, 0xca,
+ 0xfe, 0xc0, 0xdc, 0x4d, 0xee, 0xed, 0xb1, 0x70, 0xc0, 0x0b, 0xc3, 0x71,
+ 0xff, 0x76, 0x9b, 0x7f, 0x86, 0x7b, 0xd5, 0xb4, 0xa1, 0x0e, 0x7e, 0x0c,
+ 0x3a, 0xb8, 0xa6, 0x7b, 0xef, 0xc6, 0x58, 0xf3, 0xa0, 0x99, 0x3e, 0xf9,
+ 0x9d, 0x6a, 0xfa, 0xf3, 0xa2, 0xcf, 0x16, 0xf5, 0xc2, 0x86, 0x9b, 0xbf,
+ 0xf3, 0xbd, 0x7e, 0x00, 0x5b, 0x2f, 0x94, 0x87, 0x83, 0x7e, 0xd0, 0x50,
+ 0x37, 0xec, 0x3d, 0x5f, 0xfb, 0xa5, 0x8f, 0x6b, 0xda, 0x22, 0x8d, 0x31,
+ 0xdf, 0x86, 0x76, 0x81, 0x13, 0xcf, 0xf5, 0xfe, 0xb1, 0x89, 0xd3, 0x04,
+ 0x9d, 0xde, 0x97, 0xc0, 0xb7, 0x43, 0xfe, 0x0e, 0xf8, 0x28, 0xa4, 0x21,
+ 0xc6, 0xd3, 0xb6, 0xdb, 0x7c, 0xc7, 0x36, 0x99, 0x76, 0x19, 0x77, 0x4c,
+ 0xf7, 0x8f, 0x08, 0xe7, 0x9d, 0x4e, 0xa6, 0x94, 0xb6, 0xab, 0xc2, 0x03,
+ 0x01, 0x73, 0x79, 0xb9, 0x67, 0x43, 0x7e, 0x1e, 0xbe, 0x6b, 0xc2, 0x2f,
+ 0x78, 0x31, 0x9b, 0xff, 0x9b, 0x2b, 0x19, 0xda, 0x1c, 0x23, 0x6d, 0xc2,
+ 0x9f, 0x5a, 0xe8, 0xfd, 0xbb, 0x90, 0xf6, 0x7d, 0x4a, 0x91, 0xf6, 0xbf,
+ 0x17, 0xce, 0xba, 0xec, 0x8b, 0x70, 0x0f, 0xdf, 0x95, 0xd3, 0xb8, 0xba,
+ 0x5b, 0x0e, 0x97, 0x69, 0x0b, 0xc7, 0x75, 0x7e, 0xc8, 0x68, 0x40, 0x3b,
+ 0x2d, 0x0e, 0x3c, 0x8e, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x6f, 0x44, 0x9d,
+ 0x98, 0x8c, 0x0c, 0xb7, 0x80, 0xf7, 0xc8, 0x9f, 0xbc, 0xbb, 0xa8, 0xef,
+ 0xc9, 0x5c, 0x69, 0x44, 0xe7, 0xef, 0x3d, 0x8e, 0xb6, 0x4f, 0xe0, 0x9a,
+ 0x29, 0x7d, 0x18, 0x6d, 0xde, 0xaf, 0xeb, 0xcf, 0x4c, 0x32, 0x17, 0x5a,
+ 0x20, 0x97, 0x3e, 0x21, 0xc5, 0xd9, 0x0e, 0x19, 0x49, 0xcc, 0x4f, 0xbb,
+ 0x4b, 0x71, 0x99, 0x47, 0x37, 0x70, 0xcf, 0xa4, 0x78, 0x35, 0xf7, 0x97,
+ 0xc5, 0x1d, 0xde, 0xad, 0xba, 0x5b, 0xb5, 0xcf, 0xd5, 0x2f, 0x43, 0xd5,
+ 0x8c, 0xdc, 0x54, 0x7d, 0x62, 0x8b, 0x89, 0x45, 0x2d, 0x8b, 0x6f, 0x1d,
+ 0xd3, 0x52, 0xe5, 0x84, 0xcb, 0xf3, 0x59, 0x32, 0x73, 0x56, 0x24, 0x76,
+ 0x22, 0x8a, 0x4d, 0xb2, 0xcc, 0x93, 0x8e, 0xab, 0x01, 0xd7, 0x59, 0xc8,
+ 0xd6, 0x44, 0x5c, 0x3e, 0xbb, 0x2b, 0x1a, 0xab, 0x10, 0x4e, 0xed, 0x2a,
+ 0xc8, 0x9d, 0xb8, 0xf2, 0x57, 0xa7, 0x27, 0x73, 0x8a, 0xe3, 0xfe, 0x75,
+ 0x48, 0x59, 0xa6, 0x32, 0xbe, 0x14, 0x5a, 0xa3, 0xb1, 0xe1, 0xdf, 0xec,
+ 0x89, 0xc6, 0xa7, 0xcd, 0x6d, 0xce, 0x56, 0x14, 0xb9, 0x8f, 0x03, 0xfa,
+ 0x8b, 0x65, 0x3e, 0xb7, 0x81, 0xbe, 0xc3, 0x80, 0xb0, 0x1d, 0x64, 0xba,
+ 0x62, 0xdf, 0x84, 0x93, 0xf0, 0xd7, 0xc3, 0xb9, 0x90, 0x4a, 0x00, 0x47,
+ 0x85, 0xd7, 0x85, 0xb7, 0xc7, 0xf3, 0xd5, 0x5a, 0xf0, 0xde, 0x6c, 0x63,
+ 0x89, 0x8c, 0x0f, 0xae, 0x03, 0xde, 0x5a, 0x50, 0x9e, 0x97, 0x89, 0x93,
+ 0xb7, 0x6e, 0xe1, 0xde, 0x78, 0x83, 0xef, 0xd8, 0x1c, 0x56, 0x9e, 0x39,
+ 0x9a, 0x40, 0x1d, 0xbe, 0x1f, 0x41, 0x9b, 0x74, 0x21, 0x17, 0xdb, 0x02,
+ 0x9f, 0x88, 0xe3, 0x86, 0xb1, 0x8e, 0x3d, 0xcd, 0x3a, 0x27, 0x55, 0xce,
+ 0x52, 0x9f, 0x47, 0x6d, 0x27, 0x74, 0xce, 0x07, 0xfc, 0xf6, 0xc2, 0x60,
+ 0x8c, 0xf2, 0xab, 0x5b, 0x06, 0xa8, 0x4f, 0xce, 0x8e, 0x68, 0xda, 0xef,
+ 0xdc, 0xc5, 0xf3, 0x57, 0x3d, 0xc6, 0x46, 0x4f, 0x10, 0xc6, 0x9b, 0x51,
+ 0x0e, 0xfb, 0xfd, 0x35, 0x61, 0x28, 0xbc, 0x49, 0x18, 0x0a, 0x6f, 0x12,
+ 0x06, 0xe2, 0x02, 0x70, 0x54, 0xaf, 0xd8, 0x18, 0xc5, 0xbe, 0xb7, 0x62,
+ 0x1e, 0x47, 0xca, 0x05, 0x39, 0x5a, 0x76, 0x74, 0xdc, 0x71, 0x5e, 0x51,
+ 0x26, 0x78, 0xe0, 0x49, 0xf0, 0x5e, 0x19, 0xbc, 0x59, 0x06, 0x2f, 0x96,
+ 0xc1, 0x97, 0xb0, 0xff, 0xcf, 0x43, 0x3e, 0x3c, 0x81, 0xb5, 0x79, 0x7c,
+ 0x19, 0x2f, 0x67, 0x35, 0x2f, 0x17, 0xcb, 0xf4, 0xd5, 0x7a, 0x2f, 0xc3,
+ 0xaf, 0xae, 0x0c, 0x94, 0xd2, 0x50, 0x25, 0x8e, 0x9b, 0xef, 0xfd, 0x28,
+ 0xf9, 0x55, 0x1e, 0x0c, 0x0e, 0xa2, 0xcd, 0x24, 0x68, 0x3c, 0x4d, 0x3b,
+ 0x90, 0xf6, 0x4f, 0x01, 0xbc, 0x79, 0x8c, 0xbe, 0x9a, 0xba, 0x7a, 0xb3,
+ 0x50, 0xbf, 0xb8, 0x7b, 0x98, 0xcb, 0xc8, 0xb9, 0xa6, 0x56, 0xe0, 0xc9,
+ 0xf0, 0xef, 0x98, 0x4f, 0x3d, 0x43, 0xbe, 0x7d, 0x96, 0x7c, 0x5b, 0xc7,
+ 0xab, 0x3f, 0xc5, 0xf9, 0x85, 0xde, 0xae, 0xb5, 0xda, 0xd6, 0xea, 0x6f,
+ 0x5e, 0xaa, 0xaf, 0xc7, 0x9f, 0x24, 0x3f, 0xaa, 0xcc, 0x24, 0x71, 0x9f,
+ 0xca, 0xc5, 0x76, 0x58, 0xdc, 0xc3, 0x76, 0xdb, 0x73, 0x05, 0x70, 0xdf,
+ 0x2e, 0x85, 0xb9, 0x50, 0xfc, 0x3d, 0x51, 0x9f, 0xb5, 0x7e, 0x3c, 0xdb,
+ 0xcf, 0x68, 0xc9, 0x91, 0xc1, 0x5d, 0xdc, 0xd7, 0x70, 0xa0, 0xe7, 0xa3,
+ 0xf5, 0x80, 0xbd, 0xaf, 0xd7, 0x9c, 0x32, 0x96, 0xb2, 0xb5, 0xc5, 0xc6,
+ 0x9f, 0xd8, 0xdf, 0xe4, 0x8a, 0x75, 0x7a, 0x31, 0xe4, 0xb9, 0xb6, 0x09,
+ 0xff, 0x60, 0x1d, 0xad, 0x3c, 0x60, 0x69, 0x45, 0xad, 0x98, 0xc7, 0x5d,
+ 0x96, 0x56, 0x22, 0x78, 0x13, 0x11, 0xad, 0x34, 0x45, 0xb4, 0x52, 0x98,
+ 0x8e, 0x68, 0x85, 0x6d, 0xef, 0x8a, 0x68, 0x25, 0x55, 0x4f, 0x2b, 0x85,
+ 0x69, 0x07, 0xd7, 0x4a, 0x38, 0x48, 0x2f, 0xec, 0x87, 0xf4, 0x02, 0x58,
+ 0xaa, 0x9f, 0x59, 0xa2, 0x97, 0x04, 0xfa, 0x39, 0x5a, 0x36, 0x39, 0x22,
+ 0xf0, 0xbb, 0xac, 0x0e, 0xf1, 0xb0, 0xe6, 0xc6, 0x47, 0x5c, 0x9b, 0x46,
+ 0x02, 0x4b, 0x23, 0xb5, 0x7c, 0xfa, 0x15, 0xb4, 0x01, 0xdc, 0x33, 0x37,
+ 0x76, 0xb7, 0xa6, 0x8d, 0xfb, 0x83, 0x12, 0xea, 0x0e, 0x83, 0x36, 0x22,
+ 0x1c, 0xbc, 0xc7, 0xe2, 0x60, 0xe5, 0x5a, 0xde, 0x66, 0x71, 0x30, 0x6c,
+ 0x71, 0xa0, 0xf9, 0xa5, 0xc0, 0x35, 0x53, 0x1a, 0x07, 0x4d, 0x1a, 0x07,
+ 0xa2, 0xa2, 0xb6, 0xb7, 0xad, 0x81, 0x03, 0xd6, 0x19, 0xd6, 0xf3, 0x8f,
+ 0x61, 0xfe, 0xb7, 0x63, 0xfe, 0x4a, 0xcf, 0x9f, 0xeb, 0x60, 0x72, 0xb9,
+ 0x8b, 0xd5, 0xbf, 0x5e, 0x9a, 0x7f, 0x2b, 0xfa, 0x38, 0x52, 0x8e, 0xe9,
+ 0xf9, 0xc3, 0xb6, 0xef, 0x8f, 0xe6, 0xff, 0x78, 0xd5, 0xe4, 0x53, 0x3f,
+ 0xbe, 0x4a, 0xcf, 0x95, 0x2c, 0x6f, 0xf8, 0xda, 0x2f, 0x66, 0x4c, 0xfb,
+ 0x3c, 0x74, 0xdb, 0x54, 0x90, 0xb2, 0xe7, 0xae, 0x8c, 0xbd, 0xf4, 0x95,
+ 0x80, 0xbc, 0xf3, 0x21, 0x9d, 0xd7, 0x72, 0x8e, 0x76, 0x53, 0xb9, 0x55,
+ 0x06, 0xa7, 0xea, 0xe1, 0x26, 0xbc, 0x05, 0x2d, 0x47, 0xf3, 0x98, 0xdf,
+ 0x68, 0xd0, 0x0d, 0xf9, 0xa6, 0x69, 0x09, 0xe5, 0xe9, 0xc2, 0x40, 0xac,
+ 0x49, 0xd4, 0x03, 0xef, 0xc7, 0x9c, 0x5d, 0xd9, 0xe2, 0x77, 0x7a, 0x7b,
+ 0x14, 0x75, 0xe1, 0x95, 0x75, 0xba, 0xb0, 0xcd, 0xea, 0xc2, 0xcd, 0xd4,
+ 0x85, 0x80, 0xfb, 0x6e, 0x39, 0x56, 0xe6, 0xfa, 0x15, 0x52, 0x4d, 0xd0,
+ 0xff, 0xdf, 0xf1, 0x79, 0xc6, 0x45, 0xc7, 0xcd, 0x92, 0xc7, 0x34, 0x2d,
+ 0x53, 0xa7, 0xa5, 0xf5, 0x99, 0x90, 0x05, 0xda, 0xd8, 0x09, 0xc6, 0x42,
+ 0xa9, 0xf7, 0xfe, 0x3e, 0xfc, 0xcc, 0x1a, 0x7a, 0x6f, 0xbc, 0x6c, 0xec,
+ 0xb7, 0x06, 0xd8, 0x84, 0x72, 0xaa, 0x0d, 0xd7, 0x26, 0x9e, 0x89, 0xe8,
+ 0xee, 0x52, 0xcd, 0xd2, 0x70, 0x6a, 0xa3, 0x8c, 0x4d, 0x19, 0x1b, 0x57,
+ 0x9d, 0x02, 0xfe, 0x4f, 0x31, 0x7f, 0x56, 0x74, 0xbe, 0x7f, 0x7e, 0x12,
+ 0x76, 0xee, 0xcc, 0xdd, 0xe6, 0x1c, 0xc8, 0x54, 0x83, 0xfe, 0x4d, 0x1b,
+ 0xa4, 0x18, 0x64, 0xa1, 0xef, 0xe2, 0x32, 0x86, 0x3e, 0x3b, 0x77, 0x35,
+ 0x62, 0xce, 0x09, 0xb4, 0xa5, 0xcf, 0xc7, 0x38, 0x5a, 0xa3, 0xb8, 0x33,
+ 0x49, 0x9d, 0xab, 0xcf, 0xf3, 0xae, 0xb9, 0xfe, 0x56, 0xbc, 0x63, 0x7e,
+ 0x84, 0x87, 0xb1, 0x22, 0xd9, 0x8f, 0x7e, 0x4f, 0x88, 0xdd, 0xef, 0xc9,
+ 0x68, 0xfd, 0x17, 0x3b, 0xe1, 0xd9, 0xb3, 0x7a, 0xfd, 0x58, 0xf7, 0xb5,
+ 0xf4, 0xa2, 0x31, 0x72, 0x73, 0x58, 0x3f, 0x75, 0xd6, 0xc5, 0xbd, 0x1d,
+ 0xf7, 0xa8, 0xbf, 0x48, 0x8f, 0x40, 0x37, 0xbe, 0xfd, 0xd0, 0x26, 0x69,
+ 0x06, 0xbe, 0x67, 0x14, 0x70, 0x6d, 0x72, 0xbc, 0x0a, 0x9a, 0x17, 0x6a,
+ 0xf4, 0xf0, 0xc4, 0xeb, 0xf2, 0x03, 0x69, 0x82, 0xb4, 0x40, 0xb9, 0x48,
+ 0xda, 0xa0, 0x4c, 0x24, 0x6d, 0x1b, 0x7a, 0x78, 0x2c, 0xf0, 0x63, 0xcc,
+ 0x03, 0x30, 0x71, 0x79, 0xd2, 0x06, 0x69, 0x3e, 0xa5, 0xe3, 0xf5, 0x59,
+ 0xf9, 0x96, 0x64, 0x5b, 0x3b, 0x61, 0x97, 0xfd, 0xdb, 0xae, 0xb1, 0x39,
+ 0x2b, 0xac, 0x69, 0x0e, 0xba, 0x89, 0x39, 0x79, 0xdd, 0xf2, 0x9e, 0x6a,
+ 0x01, 0x78, 0xb8, 0x17, 0x4a, 0xf9, 0x6e, 0x9d, 0xe7, 0xb8, 0xaf, 0xb4,
+ 0x49, 0x6e, 0x09, 0xe2, 0x36, 0xee, 0x7e, 0x04, 0x74, 0xb0, 0xe0, 0xc8,
+ 0xa9, 0x0b, 0xb8, 0x2e, 0x3a, 0x5c, 0xbf, 0x4b, 0x41, 0x36, 0xad, 0xc8,
+ 0xec, 0xbe, 0x9b, 0x5c, 0x90, 0x1e, 0x6f, 0x4c, 0x18, 0xeb, 0x98, 0x77,
+ 0x9a, 0x4e, 0xfd, 0xfe, 0x26, 0xe3, 0x4b, 0x03, 0x16, 0xbf, 0xd1, 0x1b,
+ 0xa4, 0x2d, 0x17, 0x84, 0x61, 0x9e, 0x76, 0x83, 0x28, 0xed, 0x23, 0xc1,
+ 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x3b, 0x9d, 0xc6, 0xb3, 0x2f, 0x58, 0x5a,
+ 0x91, 0x98, 0xca, 0x3c, 0xed, 0x34, 0x9c, 0x7a, 0x84, 0x6b, 0xa6, 0xf3,
+ 0xae, 0x0d, 0x5d, 0x3d, 0xeb, 0xd4, 0xe8, 0xea, 0x2b, 0xf6, 0xb7, 0xca,
+ 0x34, 0x49, 0x36, 0xdd, 0x84, 0xf9, 0x0e, 0x94, 0x22, 0x18, 0xbf, 0x0d,
+ 0xb8, 0x08, 0x0f, 0xe8, 0x76, 0xe6, 0x7f, 0xe2, 0x5a, 0x04, 0x2c, 0xf7,
+ 0x01, 0xee, 0x4b, 0x80, 0xf9, 0x45, 0x5c, 0x6a, 0x5b, 0x4c, 0xfe, 0xd4,
+ 0x89, 0xcd, 0xd4, 0xc3, 0x4b, 0x18, 0xbf, 0x6b, 0xe1, 0x7d, 0x2d, 0x58,
+ 0x3d, 0x59, 0xe8, 0xeb, 0x00, 0x3c, 0x84, 0xf3, 0x25, 0xc0, 0x48, 0xbb,
+ 0xf5, 0x39, 0x3c, 0x7b, 0x80, 0xef, 0x79, 0x0b, 0x13, 0xe8, 0x71, 0xea,
+ 0x2f, 0x6a, 0xbf, 0x4b, 0xb4, 0xa3, 0xff, 0xd2, 0x3e, 0xb7, 0xaf, 0x90,
+ 0x01, 0x5d, 0x0e, 0xf1, 0x3c, 0x51, 0x5e, 0xa4, 0x1d, 0x00, 0xbe, 0xff,
+ 0xae, 0xc4, 0xce, 0x26, 0xe5, 0x68, 0x89, 0x7b, 0x40, 0xa7, 0x81, 0x0f,
+ 0x7d, 0xc6, 0x05, 0x75, 0xae, 0xc2, 0x05, 0x65, 0x3f, 0xb3, 0x1b, 0x57,
+ 0x37, 0xae, 0xb7, 0xe2, 0x02, 0x39, 0xcc, 0x9c, 0xc2, 0xd5, 0x83, 0xbe,
+ 0x55, 0xa2, 0x49, 0x98, 0x9b, 0xf5, 0x0d, 0xb4, 0xd1, 0xb6, 0x65, 0x41,
+ 0x65, 0xfa, 0x80, 0xbf, 0x3e, 0xc0, 0x96, 0xc4, 0xc5, 0x7c, 0xe6, 0xef,
+ 0x3a, 0x72, 0xf6, 0x65, 0x5c, 0x60, 0xb0, 0xb3, 0x20, 0xcc, 0xb3, 0xfd,
+ 0xb8, 0xa0, 0xc4, 0xce, 0x66, 0x71, 0x0d, 0xe2, 0xfa, 0x2b, 0xc7, 0xf0,
+ 0x5c, 0x3b, 0xf0, 0x15, 0xf1, 0x08, 0x70, 0xbe, 0x8c, 0xe7, 0xbe, 0xec,
+ 0xbc, 0x71, 0x9e, 0xfb, 0xbe, 0x63, 0x78, 0xee, 0x15, 0xa7, 0xc6, 0x73,
+ 0x17, 0x1c, 0xf5, 0xf0, 0xd3, 0x4e, 0xec, 0x61, 0xfa, 0x12, 0x17, 0x1c,
+ 0xc3, 0xff, 0x31, 0x19, 0x38, 0x08, 0x5a, 0x7a, 0x78, 0x1e, 0x17, 0xe9,
+ 0xea, 0x19, 0x94, 0x3f, 0xbf, 0x62, 0xdc, 0xe7, 0xde, 0xc4, 0xb8, 0xaf,
+ 0xda, 0x71, 0x45, 0xd5, 0xc6, 0x7d, 0x11, 0x7d, 0xbf, 0x64, 0xc7, 0x7d,
+ 0xb1, 0x6e, 0x5c, 0xd0, 0xca, 0xc3, 0x8b, 0xb8, 0x48, 0x17, 0x2f, 0xa0,
+ 0x3c, 0x92, 0x09, 0x1f, 0xf4, 0xa4, 0xb9, 0x01, 0xbc, 0x1b, 0x87, 0x7e,
+ 0x6c, 0x58, 0xd2, 0x8d, 0xd9, 0x3a, 0xfd, 0xf0, 0x46, 0xf4, 0xe3, 0x78,
+ 0x99, 0x36, 0xe2, 0x7c, 0x9d, 0x5c, 0xa0, 0x6f, 0x14, 0xca, 0x49, 0xed,
+ 0x07, 0xd1, 0x27, 0xa2, 0x7f, 0xb4, 0xd2, 0xb6, 0xfa, 0xa8, 0xce, 0x45,
+ 0xfb, 0x95, 0x52, 0xbb, 0xdc, 0x59, 0xa2, 0x4d, 0x48, 0x7a, 0x09, 0xc3,
+ 0xb1, 0x3d, 0xb4, 0x4f, 0x0b, 0xe1, 0x15, 0x3e, 0xe9, 0xc4, 0xf7, 0x7e,
+ 0x79, 0xb5, 0xce, 0x98, 0x1c, 0x80, 0xef, 0x9e, 0x3b, 0xf1, 0x8b, 0xd0,
+ 0x19, 0x0d, 0x80, 0x9b, 0xf4, 0xb6, 0x4d, 0x0e, 0x4c, 0xaa, 0x89, 0x2d,
+ 0x90, 0x25, 0x37, 0x95, 0x1a, 0x61, 0xf7, 0x30, 0x4f, 0xab, 0x59, 0x3a,
+ 0xf7, 0xc4, 0x4d, 0x1e, 0xb9, 0x97, 0xc0, 0x6f, 0xcf, 0xe4, 0xb5, 0x27,
+ 0x92, 0x78, 0xff, 0x0f, 0x1e, 0xe5, 0x60, 0xc2, 0xbf, 0x4e, 0xe7, 0x08,
+ 0x75, 0xec, 0xa1, 0xdd, 0x72, 0x83, 0xd6, 0xe1, 0xee, 0x2a, 0x3b, 0x49,
+ 0x6d, 0xf3, 0xa4, 0x66, 0xa3, 0x8d, 0x96, 0xd2, 0x29, 0xc2, 0xf5, 0x90,
+ 0x70, 0xff, 0xeb, 0x1e, 0x29, 0x06, 0x1b, 0xe1, 0x17, 0x30, 0x76, 0x9e,
+ 0xee, 0xa6, 0x6d, 0x34, 0x33, 0xe5, 0xd9, 0x3c, 0xeb, 0x4d, 0xf2, 0xac,
+ 0x1e, 0xa7, 0x51, 0xc3, 0x68, 0xce, 0x5e, 0x70, 0x1f, 0x21, 0xae, 0xcf,
+ 0xfb, 0xcc, 0x54, 0x5a, 0xb4, 0xde, 0x99, 0xa9, 0x30, 0xaf, 0x1f, 0xfe,
+ 0x54, 0x85, 0x79, 0xfc, 0x81, 0x78, 0x6f, 0x87, 0x9f, 0x5b, 0xd9, 0x21,
+ 0xa3, 0x53, 0xeb, 0xa4, 0xd1, 0x57, 0x89, 0x2d, 0xd0, 0x1f, 0x6c, 0xd3,
+ 0xb1, 0x07, 0xfe, 0xe1, 0xf4, 0x4e, 0x79, 0x62, 0x9a, 0x7d, 0x6f, 0x93,
+ 0xd9, 0x39, 0x71, 0xbc, 0xb7, 0xaf, 0x47, 0x1d, 0xc8, 0xf5, 0x3d, 0x2c,
+ 0x4b, 0xe1, 0x2e, 0xca, 0x7b, 0xbb, 0x2b, 0x17, 0xfb, 0xf8, 0xcc, 0xb3,
+ 0x04, 0xe2, 0xb2, 0xbf, 0x8b, 0x7d, 0xed, 0x72, 0x6e, 0x0e, 0x34, 0x01,
+ 0xb9, 0x3f, 0x78, 0x8a, 0x30, 0x89, 0xec, 0x9d, 0x61, 0x2c, 0xbd, 0xd3,
+ 0x63, 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0xf4, 0x71, 0x2c, 0xe8, 0x25, 0xe8,
+ 0xb8, 0x8e, 0x3d, 0x46, 0x16, 0x64, 0x67, 0x1a, 0x50, 0xce, 0x7e, 0xe1,
+ 0x3f, 0x1e, 0x64, 0x3f, 0x51, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59,
+ 0x5c, 0xa1, 0x3f, 0xce, 0xff, 0x48, 0xf6, 0x37, 0xfb, 0xe8, 0xd6, 0x7b,
+ 0x21, 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae,
+ 0xba, 0x4a, 0xdb, 0x17, 0xb3, 0x55, 0xae, 0x20, 0x63, 0x51, 0xd1, 0x1a,
+ 0x25, 0xe5, 0xd1, 0xf2, 0xd2, 0x3a, 0xed, 0x68, 0x58, 0xbe, 0x4e, 0xa4,
+ 0x95, 0x60, 0xc4, 0xda, 0x1e, 0x0b, 0x72, 0x0c, 0x76, 0x59, 0xb7, 0x5e,
+ 0xb3, 0x05, 0xd8, 0xb2, 0x76, 0xcd, 0xb4, 0x3d, 0x5b, 0x8c, 0xd6, 0x6c,
+ 0x18, 0x1a, 0xa7, 0x92, 0xd9, 0xcc, 0x35, 0xf3, 0x18, 0xef, 0x06, 0xde,
+ 0x0b, 0x58, 0xa7, 0x02, 0xd6, 0xa8, 0x50, 0xd9, 0x26, 0x33, 0x27, 0x55,
+ 0x7b, 0x83, 0x48, 0x6a, 0xd4, 0xdf, 0x26, 0xe3, 0x73, 0x8c, 0x25, 0xec,
+ 0x80, 0x0d, 0xb6, 0x13, 0x57, 0x3b, 0x9e, 0xd9, 0x2e, 0x21, 0xc5, 0x8a,
+ 0x42, 0xdb, 0xa6, 0x55, 0x76, 0xd6, 0x39, 0x8c, 0xcd, 0x33, 0x9d, 0x8f,
+ 0x01, 0x0f, 0x35, 0xde, 0x29, 0xd5, 0xc5, 0x9f, 0x38, 0x57, 0xad, 0x43,
+ 0x31, 0xdf, 0x84, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x37, 0xbe, 0x19, 0x7b,
+ 0x2a, 0x49, 0x7b, 0x2a, 0x3f, 0xe9, 0x99, 0xf3, 0x06, 0xc3, 0xf0, 0x9d,
+ 0xfc, 0xfc, 0x66, 0xd2, 0xfa, 0xc8, 0x34, 0xe1, 0x8a, 0x47, 0x70, 0x2d,
+ 0x5b, 0x33, 0x9e, 0x0f, 0x5b, 0x1d, 0xe7, 0x28, 0x2d, 0xe5, 0x43, 0x9a,
+ 0xd8, 0x3e, 0xe3, 0x28, 0xed, 0x6b, 0xc0, 0x74, 0xb7, 0xb6, 0x61, 0x45,
+ 0xdd, 0x26, 0x87, 0xcb, 0x3c, 0x5b, 0xc6, 0x78, 0xe2, 0x27, 0x19, 0x5f,
+ 0xea, 0x9e, 0x91, 0x63, 0x18, 0x9b, 0xb9, 0x3f, 0xca, 0xc6, 0x6f, 0x36,
+ 0xd8, 0x1c, 0x91, 0xfa, 0x18, 0x8e, 0xc9, 0x0d, 0x5a, 0x9e, 0x67, 0x9d,
+ 0x1e, 0x5e, 0xc4, 0x3a, 0xff, 0x9a, 0xde, 0x1b, 0x94, 0xc9, 0x18, 0xb4,
+ 0xdf, 0x68, 0x5f, 0xba, 0xdf, 0x9c, 0xab, 0x49, 0xc9, 0x50, 0xd9, 0xcc,
+ 0xff, 0x92, 0xce, 0x11, 0x32, 0xb9, 0x90, 0x26, 0x7f, 0xe8, 0x1e, 0xb9,
+ 0x04, 0x1d, 0x5e, 0x5b, 0xdb, 0x26, 0x19, 0x07, 0x2e, 0xf2, 0x7a, 0x5f,
+ 0x22, 0x25, 0xf9, 0xbe, 0x47, 0x37, 0xf3, 0xdc, 0x45, 0x1c, 0xeb, 0x53,
+ 0x9c, 0xe6, 0x59, 0x4c, 0xf6, 0x7b, 0xb9, 0xbe, 0x28, 0x66, 0x99, 0xd7,
+ 0x0f, 0x59, 0xf9, 0x63, 0x3d, 0xc9, 0x66, 0xfd, 0x7e, 0x9d, 0xcd, 0xdf,
+ 0x76, 0x44, 0x0e, 0x84, 0xf2, 0x87, 0xd0, 0x93, 0x67, 0xec, 0x9c, 0x52,
+ 0x3a, 0x66, 0x25, 0xe1, 0xc5, 0x20, 0x69, 0x63, 0x96, 0x9c, 0xcb, 0x41,
+ 0x4b, 0xdf, 0xc6, 0xfe, 0xa9, 0xd9, 0xd0, 0x66, 0xdf, 0xef, 0x09, 0x2d,
+ 0x0b, 0x7b, 0xad, 0xed, 0xac, 0xe3, 0x3c, 0x8f, 0x88, 0xce, 0x09, 0x88,
+ 0x7c, 0xa3, 0xae, 0x3a, 0xbf, 0xc0, 0xf8, 0x72, 0xc5, 0xa9, 0xb5, 0x64,
+ 0x54, 0xcd, 0x27, 0xa4, 0x2f, 0x37, 0xb6, 0x8b, 0xdf, 0x47, 0x88, 0x7c,
+ 0xb9, 0x5e, 0xeb, 0xcb, 0x6d, 0xd4, 0xbe, 0x9c, 0x89, 0x3d, 0x6c, 0x5c,
+ 0xf2, 0xe5, 0x8a, 0x53, 0x05, 0xd0, 0x4a, 0xf4, 0x3d, 0x07, 0x63, 0x0b,
+ 0x8d, 0x97, 0x78, 0x86, 0xa6, 0x51, 0xf2, 0xc3, 0x0a, 0x7e, 0x83, 0xf1,
+ 0xb1, 0x18, 0xab, 0x50, 0xea, 0xeb, 0xd6, 0xbf, 0x68, 0x97, 0x6c, 0xdb,
+ 0x3a, 0xcc, 0xfb, 0x6e, 0xbd, 0xe6, 0xb3, 0x25, 0xb3, 0xf7, 0x99, 0x3f,
+ 0xc8, 0x98, 0x10, 0xcf, 0x49, 0x69, 0xfe, 0x4a, 0x0d, 0xc4, 0xba, 0x8d,
+ 0x3d, 0xeb, 0x7b, 0xad, 0xd2, 0x7c, 0x1a, 0x38, 0x8f, 0xdb, 0x71, 0x53,
+ 0x80, 0xe9, 0x30, 0xd6, 0xe6, 0x3a, 0x2b, 0x93, 0x39, 0xf6, 0x47, 0x9b,
+ 0x18, 0x1b, 0x98, 0x2b, 0x45, 0x31, 0xc2, 0x98, 0x3d, 0xa3, 0xe9, 0xc7,
+ 0x1a, 0xfd, 0x75, 0x6b, 0xda, 0xaa, 0x8f, 0xbf, 0xae, 0x6e, 0x22, 0x2d,
+ 0xdd, 0xad, 0xf3, 0x5c, 0xd6, 0xf7, 0xa5, 0xf7, 0xeb, 0x9c, 0x7b, 0x1d,
+ 0x63, 0x2c, 0x08, 0x73, 0xd4, 0xbe, 0x29, 0x3f, 0xa1, 0x65, 0xfe, 0xe1,
+ 0x80, 0xfa, 0x6b, 0x8f, 0xfe, 0xdd, 0x98, 0x09, 0xc3, 0x8b, 0x7d, 0x13,
+ 0x8c, 0x29, 0x7a, 0xdf, 0x96, 0xce, 0xe4, 0x80, 0xb6, 0x9d, 0xb0, 0x46,
+ 0x07, 0x9b, 0x65, 0x9d, 0x3f, 0x62, 0x73, 0x66, 0x0a, 0x90, 0x9b, 0x69,
+ 0xd8, 0x4c, 0x3c, 0x7f, 0xdc, 0x65, 0xdf, 0x15, 0xc2, 0x66, 0xd0, 0xd1,
+ 0x07, 0xc5, 0xc8, 0x98, 0x7c, 0x4d, 0xc6, 0x30, 0xd7, 0x20, 0x4b, 0x42,
+ 0x76, 0x8f, 0x4b, 0x9a, 0xdf, 0x2a, 0xe1, 0xd8, 0x45, 0xd9, 0x0a, 0xbd,
+ 0xcc, 0x76, 0xb4, 0x55, 0xf9, 0xcc, 0x3d, 0x1c, 0xdf, 0x3b, 0x02, 0xdd,
+ 0x72, 0xc3, 0x6a, 0xdd, 0x92, 0xa4, 0x5f, 0x9f, 0x9f, 0xa4, 0x6f, 0xb8,
+ 0x1e, 0x6d, 0xb6, 0xc9, 0x87, 0xa6, 0x7e, 0xbe, 0x95, 0xbc, 0x35, 0x02,
+ 0xb9, 0xae, 0xee, 0x8f, 0xce, 0x16, 0xb1, 0x8c, 0xef, 0xd9, 0x6f, 0x93,
+ 0xa4, 0xde, 0xeb, 0xc9, 0x6f, 0x54, 0xd3, 0xa9, 0x45, 0xe8, 0xa6, 0x11,
+ 0xe7, 0x57, 0xb7, 0x9b, 0x98, 0xea, 0x07, 0x5a, 0xcd, 0x59, 0x84, 0x66,
+ 0xe0, 0x34, 0x8a, 0xb3, 0xd6, 0xd3, 0xec, 0xa2, 0x95, 0xc7, 0x61, 0xd8,
+ 0xdc, 0xa7, 0x65, 0xf0, 0x7e, 0xca, 0xe0, 0xc3, 0x41, 0x97, 0xa1, 0x7d,
+ 0xed, 0x33, 0x85, 0x58, 0x47, 0xe0, 0xa1, 0xcf, 0x65, 0xbe, 0x9f, 0xe5,
+ 0x4f, 0x3f, 0xbb, 0x60, 0xe5, 0x92, 0x72, 0x56, 0xf3, 0xa5, 0xba, 0x26,
+ 0xbe, 0x4c, 0xe6, 0x1e, 0x9d, 0xa2, 0x3e, 0x0e, 0xe6, 0xbf, 0x09, 0x39,
+ 0x95, 0xd7, 0x78, 0xd8, 0x26, 0xf7, 0x4d, 0x49, 0xf6, 0x12, 0x74, 0x55,
+ 0x71, 0x6e, 0x39, 0x6f, 0xae, 0xee, 0x8f, 0x73, 0x7d, 0xa4, 0xd5, 0xf8,
+ 0xb6, 0xcb, 0xe7, 0x3a, 0x8f, 0xb9, 0x66, 0xf5, 0x5c, 0xb9, 0x6f, 0x33,
+ 0x67, 0xe7, 0xba, 0x3e, 0x9a, 0x6b, 0xff, 0xf2, 0xb9, 0x46, 0xbe, 0x7d,
+ 0x24, 0x77, 0x53, 0x3a, 0xff, 0x5e, 0xe7, 0x7d, 0x4f, 0xad, 0x97, 0x81,
+ 0xc9, 0x8d, 0x56, 0x5e, 0x7a, 0xd0, 0x3d, 0xcc, 0x89, 0x9f, 0xbf, 0xd7,
+ 0x13, 0x8b, 0x33, 0x45, 0x3c, 0x50, 0xd6, 0xb6, 0xea, 0x33, 0x3b, 0x33,
+ 0xf0, 0xaf, 0x6e, 0x2d, 0xb1, 0x6e, 0xf4, 0xfe, 0x72, 0xb1, 0xe3, 0xc8,
+ 0xa7, 0xa6, 0xdf, 0xd4, 0xbd, 0x2a, 0xa6, 0x60, 0xe2, 0xc3, 0x8c, 0x0b,
+ 0x9b, 0xb3, 0xc4, 0xcc, 0x45, 0xbc, 0x03, 0x3c, 0xf5, 0xf1, 0x52, 0xba,
+ 0x3f, 0x17, 0xa3, 0x1c, 0x9d, 0x96, 0xa3, 0xd5, 0x41, 0xe9, 0xd0, 0xe7,
+ 0x49, 0x5f, 0x37, 0x76, 0x9c, 0xad, 0x8f, 0x1d, 0x33, 0x9d, 0x80, 0xb1,
+ 0xe3, 0xfd, 0x3f, 0x42, 0xec, 0x58, 0x1c, 0x13, 0x3b, 0x5e, 0xcb, 0xbf,
+ 0x9a, 0x28, 0x4f, 0x63, 0x5e, 0xcd, 0x90, 0x25, 0x0b, 0x4e, 0x7e, 0xae,
+ 0x05, 0xf7, 0x0b, 0xb8, 0xc7, 0x71, 0xbf, 0x84, 0xbb, 0x87, 0xfb, 0x8b,
+ 0xb8, 0x27, 0x64, 0x62, 0x49, 0x67, 0x4c, 0x43, 0x6e, 0x50, 0x97, 0xb1,
+ 0xad, 0xf1, 0x07, 0x66, 0x2b, 0x6d, 0xfc, 0x2e, 0x8c, 0x33, 0x33, 0xc7,
+ 0x39, 0x6c, 0x94, 0xf1, 0x29, 0xca, 0xec, 0x56, 0x99, 0x9c, 0x8a, 0x6c,
+ 0xdb, 0xbb, 0xb6, 0x71, 0xcf, 0x60, 0x44, 0x22, 0xdb, 0xf5, 0x77, 0xb7,
+ 0xd9, 0x5c, 0xfb, 0x2d, 0xd2, 0xbc, 0x09, 0x6b, 0x70, 0x5a, 0x2e, 0x4d,
+ 0x6f, 0x5a, 0x66, 0xc3, 0xa6, 0x6c, 0x4c, 0x70, 0xda, 0xea, 0xde, 0xb5,
+ 0x65, 0x44, 0xfd, 0xfa, 0x27, 0x6d, 0x4e, 0x69, 0x94, 0x23, 0x94, 0xd2,
+ 0xeb, 0x33, 0x5c, 0x9d, 0xc6, 0x78, 0xfd, 0x92, 0x9d, 0xe6, 0x3c, 0x97,
+ 0xbe, 0x4d, 0x01, 0x79, 0x78, 0x0a, 0x7a, 0x75, 0x19, 0x5d, 0x82, 0x6e,
+ 0x39, 0x37, 0x07, 0xb4, 0xfb, 0xa8, 0xcc, 0x4c, 0x12, 0xbe, 0xae, 0x64,
+ 0x4c, 0x9f, 0x5d, 0xc3, 0xf3, 0xb4, 0xc9, 0x99, 0x1f, 0xa8, 0x46, 0xe7,
+ 0xd6, 0x36, 0xeb, 0xef, 0x11, 0x2c, 0x3f, 0xbb, 0x66, 0xf5, 0xb3, 0xb6,
+ 0x1d, 0x78, 0x86, 0x2d, 0x9a, 0xc3, 0x5a, 0xf4, 0x14, 0xca, 0xb8, 0xce,
+ 0x3b, 0xdb, 0x22, 0x67, 0x1e, 0x5c, 0xca, 0xa1, 0x6d, 0x85, 0x8d, 0xd2,
+ 0x0e, 0x13, 0x79, 0xd8, 0xcd, 0x74, 0xc1, 0xc7, 0x63, 0x9e, 0x4c, 0x57,
+ 0xf2, 0x36, 0x9d, 0xdb, 0x5c, 0x3b, 0x47, 0x58, 0xcb, 0x6f, 0x8e, 0xce,
+ 0x6d, 0x25, 0x65, 0x10, 0x74, 0x38, 0xa4, 0xcb, 0x13, 0x98, 0x0f, 0xf7,
+ 0xfd, 0x34, 0x1e, 0x20, 0x7b, 0xb8, 0xe7, 0x87, 0xb9, 0x57, 0xbf, 0x01,
+ 0x7a, 0x77, 0xec, 0x19, 0x36, 0xd2, 0x58, 0x9f, 0x8c, 0x55, 0x92, 0xce,
+ 0x58, 0xa5, 0xcf, 0x39, 0x54, 0xb1, 0xef, 0xfa, 0x8a, 0x58, 0x0f, 0xfc,
+ 0x9e, 0xee, 0x70, 0x46, 0x80, 0xaf, 0x62, 0xb9, 0xd3, 0xc9, 0xea, 0xbb,
+ 0x6f, 0xef, 0x90, 0x03, 0x58, 0xab, 0x81, 0xe9, 0xa4, 0x96, 0xf3, 0xb5,
+ 0xef, 0x61, 0x45, 0xeb, 0xfa, 0xa4, 0xde, 0x1b, 0x9a, 0x97, 0x69, 0xfd,
+ 0x7d, 0x25, 0x63, 0x3b, 0x9c, 0x46, 0x7f, 0xd3, 0x36, 0x26, 0xde, 0xe3,
+ 0xe4, 0x75, 0x3f, 0x66, 0x3d, 0x8a, 0xe5, 0x53, 0xb8, 0xaf, 0x3c, 0x43,
+ 0x1d, 0xe9, 0x19, 0xc2, 0xfd, 0x08, 0xf4, 0x59, 0x78, 0x8f, 0x91, 0x57,
+ 0xd3, 0x32, 0x51, 0x65, 0xfe, 0x08, 0xfb, 0x41, 0x79, 0xe5, 0x30, 0x74,
+ 0xd2, 0xf2, 0x33, 0x84, 0x43, 0xb5, 0x75, 0x48, 0x4d, 0x0b, 0x61, 0xe1,
+ 0x1a, 0x2c, 0x3f, 0x5f, 0x7f, 0xf9, 0x7f, 0xd1, 0xbe, 0xa2, 0x91, 0xa1,
+ 0x16, 0x8e, 0x2c, 0xe5, 0x9d, 0x91, 0x2b, 0x9f, 0x96, 0x23, 0xc0, 0xe3,
+ 0x31, 0xc0, 0xa4, 0xee, 0xe7, 0xf7, 0x5e, 0x2a, 0x52, 0x9c, 0xbd, 0x4f,
+ 0xd4, 0x43, 0x97, 0x1c, 0xf7, 0xa1, 0x23, 0x12, 0x7b, 0x68, 0xc1, 0x69,
+ 0x78, 0xa8, 0x53, 0xfb, 0xe5, 0xfb, 0x82, 0xce, 0xe4, 0x21, 0x39, 0x2d,
+ 0xee, 0xfd, 0x4a, 0x9f, 0x27, 0x2b, 0x7a, 0x8c, 0xf1, 0x9d, 0x96, 0xd8,
+ 0xfd, 0x71, 0x7b, 0x16, 0xd5, 0xc4, 0xf5, 0x16, 0x35, 0xdf, 0x3f, 0x97,
+ 0x20, 0xce, 0x16, 0x65, 0x5a, 0xf3, 0xce, 0x00, 0xf4, 0x44, 0x6e, 0x32,
+ 0xb5, 0x54, 0xc7, 0xe4, 0x7b, 0x6e, 0x4c, 0x18, 0x7e, 0x61, 0x9d, 0x2e,
+ 0x87, 0xdf, 0x85, 0xb0, 0x3a, 0xff, 0xca, 0x28, 0xf7, 0xd3, 0xac, 0x29,
+ 0xdf, 0xff, 0x10, 0x6b, 0xd8, 0x85, 0xf5, 0xe2, 0x78, 0x8e, 0xde, 0xcf,
+ 0xe5, 0x59, 0x5c, 0x4f, 0x7a, 0x92, 0x4d, 0x4b, 0x76, 0x10, 0xeb, 0xde,
+ 0x27, 0x4d, 0x80, 0x5b, 0x3d, 0x54, 0x34, 0x76, 0x9d, 0x90, 0x4e, 0x05,
+ 0x92, 0x9b, 0x34, 0xdb, 0xd5, 0xbf, 0x4f, 0xaf, 0xe1, 0xbd, 0x96, 0x66,
+ 0xd6, 0x19, 0xfb, 0x11, 0xcf, 0x86, 0x2e, 0x8a, 0xb2, 0x77, 0xea, 0xbb,
+ 0xd0, 0xf3, 0xdc, 0x77, 0xd1, 0xf6, 0xe2, 0x1a, 0xb6, 0x20, 0x79, 0xe9,
+ 0x69, 0xeb, 0x57, 0x86, 0xe1, 0x54, 0x10, 0x00, 0x8f, 0x6b, 0xf9, 0x92,
+ 0x3b, 0x9c, 0xd9, 0xc9, 0x9d, 0xce, 0xcc, 0x64, 0x28, 0x63, 0x01, 0xbf,
+ 0x19, 0xc2, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x84, 0x6e, 0xdd, 0x9d,
+ 0xe0, 0xf9, 0xa6, 0x9b, 0xfc, 0x17, 0xc4, 0xd4, 0x23, 0x8e, 0xe9, 0x23,
+ 0x77, 0x3e, 0x92, 0x17, 0x7e, 0x9f, 0xa3, 0x27, 0x99, 0xd0, 0xdf, 0x10,
+ 0xf9, 0x0c, 0xda, 0x61, 0x8c, 0x32, 0xc7, 0x7d, 0xc6, 0x99, 0x81, 0x3c,
+ 0x9b, 0x9d, 0xe2, 0x37, 0x01, 0x98, 0x4f, 0x1b, 0x6b, 0x57, 0x72, 0x95,
+ 0x37, 0x6e, 0xbf, 0x5b, 0x57, 0x80, 0x0b, 0x14, 0xd3, 0x65, 0x3d, 0xde,
+ 0xe8, 0xd2, 0xb7, 0xec, 0xa2, 0xb2, 0xe8, 0x9b, 0x76, 0x4a, 0xe7, 0x4e,
+ 0xc3, 0x97, 0x3d, 0x33, 0x22, 0xdf, 0x77, 0xe6, 0x4a, 0xaf, 0x38, 0x8f,
+ 0x96, 0xb2, 0xd7, 0x5c, 0x01, 0xfa, 0xb8, 0x18, 0xe4, 0x29, 0xbf, 0x60,
+ 0xf3, 0x4d, 0x49, 0xa1, 0x3a, 0x26, 0xd3, 0xdb, 0x3a, 0xbd, 0xfb, 0xf5,
+ 0xda, 0x9c, 0x01, 0xce, 0xbe, 0x81, 0xf5, 0x3b, 0x93, 0xa0, 0x7e, 0x1b,
+ 0x2d, 0x29, 0xf0, 0xb2, 0xfa, 0x69, 0x5c, 0xb0, 0x6d, 0x1b, 0xb5, 0x8d,
+ 0x72, 0x28, 0x60, 0xbd, 0x9d, 0xce, 0xc0, 0xe4, 0x0e, 0xac, 0xe3, 0x41,
+ 0xe8, 0x4f, 0x07, 0x76, 0x1a, 0x68, 0x1b, 0x65, 0xe3, 0xc0, 0xc1, 0x68,
+ 0x60, 0xe4, 0xf9, 0x80, 0x14, 0xb4, 0x8f, 0x67, 0xee, 0x59, 0x65, 0x62,
+ 0x66, 0x61, 0x38, 0x0b, 0xfb, 0x80, 0xdf, 0xc5, 0x9a, 0xa8, 0xce, 0xe1,
+ 0xfa, 0x71, 0xbb, 0xa7, 0x3d, 0x7f, 0x99, 0x3d, 0x6d, 0x4f, 0x4e, 0x57,
+ 0xf5, 0x39, 0x79, 0x9d, 0x5f, 0x95, 0x52, 0xeb, 0xda, 0xf4, 0x5a, 0xa9,
+ 0x2e, 0x9d, 0x93, 0x96, 0x95, 0x47, 0x12, 0x46, 0x0f, 0x13, 0xa6, 0x14,
+ 0xe0, 0xd9, 0x09, 0x5c, 0x10, 0x1e, 0xd3, 0x46, 0xd4, 0x3b, 0xb7, 0x52,
+ 0x1f, 0x2e, 0xca, 0xa7, 0x12, 0xd1, 0x19, 0x05, 0xf4, 0x03, 0x19, 0x37,
+ 0xb7, 0xd5, 0xe8, 0xc9, 0x2d, 0x6b, 0xf4, 0x13, 0xcd, 0xcd, 0xb1, 0x73,
+ 0x23, 0xdd, 0x6e, 0xbe, 0x92, 0x3e, 0xc5, 0xa2, 0x34, 0xad, 0xa8, 0xcf,
+ 0x98, 0xfe, 0xbe, 0xed, 0xe6, 0xcc, 0x03, 0xeb, 0x7a, 0xb0, 0x4d, 0x69,
+ 0xe7, 0x12, 0x8f, 0x7a, 0xdd, 0x4a, 0x4a, 0x78, 0x6e, 0xe1, 0x0c, 0x64,
+ 0xcb, 0x55, 0xde, 0x4f, 0x28, 0xd2, 0x61, 0x84, 0xeb, 0x6f, 0x68, 0x3e,
+ 0x19, 0x2d, 0x31, 0xb6, 0xf2, 0x68, 0x98, 0x1d, 0x26, 0x8f, 0xb1, 0x0f,
+ 0xbe, 0x9f, 0xd2, 0xf1, 0xdc, 0x83, 0x01, 0x63, 0x45, 0x9d, 0x8f, 0xdc,
+ 0xa1, 0x22, 0x39, 0x05, 0xfd, 0x5b, 0x5e, 0x70, 0xf8, 0xdd, 0xbe, 0x03,
+ 0x82, 0xfb, 0xdc, 0x82, 0xf3, 0xcd, 0xa9, 0x67, 0xf0, 0xdc, 0x60, 0xbf,
+ 0xd5, 0x67, 0xf4, 0x94, 0xc8, 0x1f, 0x46, 0xf3, 0x4d, 0x16, 0xb0, 0xf6,
+ 0x2f, 0x62, 0xed, 0xd7, 0xfe, 0x36, 0x1f, 0xde, 0x55, 0xf0, 0xae, 0xf2,
+ 0x0b, 0x61, 0xb6, 0x95, 0xb4, 0x18, 0xe8, 0xb3, 0xa9, 0x97, 0xf7, 0x9b,
+ 0xfb, 0x35, 0x5f, 0x8c, 0x97, 0xcf, 0x81, 0x2f, 0xb2, 0xdc, 0x6f, 0x0e,
+ 0x1f, 0x0e, 0x6e, 0x04, 0x5f, 0xec, 0x97, 0xdf, 0x83, 0x5d, 0xf0, 0x3b,
+ 0xd5, 0x0c, 0xf8, 0xa3, 0x1f, 0xfc, 0xd2, 0x07, 0x1e, 0x09, 0xb4, 0x8d,
+ 0xfc, 0x18, 0xf4, 0x1f, 0xf4, 0x9a, 0x73, 0x68, 0xb2, 0xc3, 0xc9, 0x4f,
+ 0xfa, 0xce, 0xd8, 0x24, 0xbf, 0xff, 0xa2, 0xde, 0xda, 0x20, 0x6e, 0x72,
+ 0x56, 0xc8, 0x0b, 0x9d, 0xcc, 0x71, 0x6c, 0x03, 0xae, 0xce, 0x12, 0x57,
+ 0xb3, 0xd5, 0x1e, 0xef, 0x0a, 0xf0, 0x44, 0x9b, 0xe6, 0x89, 0x8d, 0x4e,
+ 0xd6, 0xbb, 0xd1, 0xf2, 0xc4, 0x0b, 0xe0, 0x89, 0x4b, 0xab, 0x78, 0xe2,
+ 0x29, 0x4b, 0xff, 0xf3, 0x75, 0x3c, 0x31, 0x6b, 0xcb, 0xa6, 0x2f, 0xc3,
+ 0x13, 0x5b, 0xfd, 0xf4, 0xe7, 0x47, 0xe4, 0x55, 0xf0, 0x84, 0x28, 0xf2,
+ 0xc4, 0x56, 0xcd, 0x13, 0x8c, 0x1d, 0x91, 0x2f, 0xda, 0x21, 0x47, 0xc8,
+ 0x17, 0x17, 0x64, 0x11, 0x7c, 0xf1, 0x9c, 0xe2, 0xd8, 0x67, 0x68, 0x2b,
+ 0x4c, 0xd2, 0x27, 0x3b, 0x55, 0xee, 0x00, 0xbf, 0x2b, 0xf9, 0xaf, 0x53,
+ 0x61, 0xb8, 0x00, 0x3f, 0xfd, 0x41, 0xd8, 0xf3, 0xae, 0xfe, 0x0e, 0xe4,
+ 0x3c, 0xe8, 0x3e, 0xa2, 0xf7, 0x31, 0x07, 0xf4, 0x7e, 0x6c, 0x06, 0x73,
+ 0x18, 0x53, 0x9f, 0x82, 0x2f, 0xec, 0x61, 0x5d, 0x69, 0xe7, 0x9f, 0xd4,
+ 0x3c, 0xd4, 0x00, 0x7d, 0xf0, 0x68, 0x1f, 0x63, 0x4d, 0xbe, 0x77, 0x48,
+ 0x75, 0x16, 0x06, 0x01, 0x73, 0x4c, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xae,
+ 0xb0, 0xf3, 0x29, 0x23, 0x86, 0x21, 0xeb, 0xcc, 0xbb, 0x42, 0xd8, 0x04,
+ 0x9b, 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x49, 0x7b, 0x3f, 0x07, 0x01,
+ 0xda, 0x08, 0x7b, 0x61, 0x2f, 0x56, 0x7b, 0xb0, 0x54, 0x6f, 0xe3, 0xff,
+ 0x67, 0xd8, 0xf8, 0x6c, 0x23, 0xae, 0xb1, 0xf1, 0x7f, 0xc5, 0xf2, 0x1a,
+ 0x7f, 0x7b, 0xda, 0xde, 0x3f, 0x0c, 0xf8, 0xf6, 0x2d, 0xd9, 0xfb, 0xec,
+ 0x83, 0x76, 0x87, 0xc8, 0x0d, 0xb0, 0xf9, 0xde, 0x09, 0x1e, 0xbc, 0x11,
+ 0xbe, 0xd4, 0xbb, 0x4a, 0x9e, 0xec, 0x2f, 0xb5, 0xc1, 0xe7, 0x6e, 0x97,
+ 0x77, 0x4f, 0xed, 0x94, 0xa1, 0xc9, 0x0f, 0x5e, 0x21, 0xcd, 0xdb, 0x60,
+ 0xa3, 0x4e, 0x01, 0xce, 0x98, 0x95, 0xdb, 0x3f, 0x04, 0xde, 0x3a, 0x53,
+ 0xdf, 0x57, 0x6d, 0xdb, 0x8d, 0x9c, 0xe7, 0xd9, 0xc9, 0xb5, 0xfa, 0x49,
+ 0xa0, 0x3d, 0x63, 0x29, 0xdb, 0xe4, 0xec, 0x49, 0x7a, 0x5f, 0x29, 0xd8,
+ 0xe5, 0x01, 0x6c, 0x92, 0x1d, 0xe8, 0x8f, 0xf1, 0xe4, 0x4d, 0xf2, 0xd4,
+ 0x35, 0xee, 0x27, 0xf2, 0x9a, 0x0f, 0xdb, 0x9d, 0xdc, 0xd4, 0x8d, 0x52,
+ 0x3c, 0x18, 0xc7, 0x1c, 0x54, 0xdb, 0x16, 0xb9, 0x5e, 0x86, 0xf4, 0x7c,
+ 0xce, 0xc8, 0x11, 0xe8, 0xe6, 0x3f, 0x28, 0x0d, 0xc9, 0xe2, 0x70, 0x2b,
+ 0x9e, 0xe3, 0xf2, 0x54, 0xa9, 0x07, 0xbe, 0xcf, 0x3b, 0x80, 0xa3, 0x46,
+ 0x3c, 0x37, 0xca, 0xc0, 0x15, 0xe4, 0xd5, 0x16, 0x59, 0x40, 0xf9, 0x3b,
+ 0xe5, 0xdf, 0xd9, 0x72, 0x96, 0x91, 0x37, 0x5a, 0xd0, 0x36, 0x2e, 0x17,
+ 0x4b, 0xb4, 0x2b, 0x35, 0x4f, 0xf4, 0x7f, 0x4b, 0x7a, 0xb2, 0xdf, 0x82,
+ 0x9d, 0x7a, 0x01, 0xd7, 0xd3, 0x92, 0xde, 0x3f, 0xea, 0xf4, 0xa4, 0x3a,
+ 0x1d, 0xe8, 0x4e, 0x5c, 0xae, 0xd3, 0xe3, 0x35, 0x3a, 0x57, 0xd9, 0x3e,
+ 0x1a, 0xe4, 0xe9, 0x83, 0x2a, 0xd9, 0x82, 0x35, 0xd9, 0xed, 0x74, 0xd9,
+ 0x32, 0x3e, 0xeb, 0x9c, 0x3c, 0xe9, 0x3c, 0xab, 0x76, 0x6c, 0x10, 0xe9,
+ 0x68, 0x81, 0xcd, 0x33, 0x26, 0xaa, 0xad, 0x45, 0x5c, 0xe9, 0x9c, 0x51,
+ 0xed, 0x28, 0xf3, 0x6d, 0x59, 0xa2, 0x05, 0xfa, 0x01, 0x65, 0xdb, 0x50,
+ 0xb6, 0xcb, 0x96, 0xb5, 0xb6, 0x48, 0x23, 0xca, 0xce, 0x68, 0x9e, 0xbf,
+ 0xd4, 0xe5, 0x7b, 0x79, 0xa7, 0x59, 0x3a, 0x4e, 0xb5, 0x40, 0x36, 0x6c,
+ 0x92, 0x85, 0x6b, 0x9a, 0xa4, 0x03, 0xef, 0x18, 0xe7, 0x0e, 0x4e, 0xc5,
+ 0xe5, 0xba, 0x53, 0x9d, 0xc9, 0x0f, 0x61, 0x0e, 0x9d, 0x67, 0x19, 0xf7,
+ 0x7e, 0xf2, 0x0a, 0xc6, 0x7d, 0x3a, 0xce, 0xf2, 0xde, 0xa4, 0xe5, 0x0f,
+ 0xf1, 0x61, 0xbe, 0x71, 0x44, 0x99, 0x7c, 0x1a, 0x7e, 0x2e, 0x75, 0x78,
+ 0xa7, 0xfd, 0x1e, 0xc7, 0x9f, 0x5e, 0x41, 0xbf, 0x6d, 0x86, 0xf6, 0x54,
+ 0x99, 0xfc, 0x48, 0x3d, 0x84, 0xfb, 0xb4, 0x23, 0xc5, 0x9a, 0xcc, 0x9a,
+ 0x23, 0x5f, 0x9d, 0x54, 0xcc, 0x65, 0x41, 0x59, 0xf5, 0x67, 0x42, 0xb3,
+ 0xc6, 0xe4, 0x05, 0x23, 0x97, 0xde, 0x67, 0xe4, 0xd2, 0x99, 0xf3, 0xcb,
+ 0xe4, 0xd2, 0x25, 0x2d, 0x97, 0x0e, 0x0a, 0xee, 0x73, 0x97, 0x20, 0x97,
+ 0x5e, 0xc0, 0xb3, 0xa7, 0xe5, 0x52, 0x42, 0xac, 0xbd, 0x2c, 0x3f, 0xd0,
+ 0xe3, 0xcf, 0x96, 0x5d, 0x6d, 0x57, 0x15, 0xa7, 0x61, 0x93, 0x94, 0x27,
+ 0xac, 0xfe, 0x96, 0x4c, 0xab, 0x74, 0xf5, 0xff, 0x50, 0x22, 0x9b, 0xf3,
+ 0xcf, 0xae, 0xe0, 0xf7, 0x46, 0x9f, 0x53, 0x94, 0x61, 0xaf, 0x42, 0x86,
+ 0x89, 0x5a, 0x5b, 0x86, 0xe1, 0x5d, 0x05, 0xef, 0x2a, 0xec, 0xf7, 0x6f,
+ 0x7f, 0x38, 0xe2, 0x51, 0x7e, 0x50, 0x66, 0x40, 0x26, 0x95, 0x21, 0x93,
+ 0xca, 0x90, 0x53, 0x65, 0xc8, 0x25, 0xd8, 0x6c, 0xe7, 0xcb, 0x90, 0x4b,
+ 0x65, 0xc8, 0x25, 0xc8, 0xb8, 0xc7, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x86,
+ 0x4c, 0x3b, 0x23, 0xf7, 0x59, 0x5d, 0x6f, 0x62, 0x25, 0xbd, 0xd6, 0x47,
+ 0xea, 0xd3, 0x31, 0xe4, 0xf3, 0x75, 0xb1, 0xc1, 0x03, 0xc7, 0x35, 0xbf,
+ 0x7b, 0xbe, 0xba, 0xca, 0x61, 0x0e, 0xcd, 0xf7, 0xb5, 0xff, 0xbe, 0x9b,
+ 0xbf, 0xa5, 0x09, 0x7c, 0xfd, 0x1d, 0xcb, 0xd7, 0xbb, 0x97, 0xf8, 0x3a,
+ 0xed, 0x30, 0x56, 0xbc, 0x36, 0x5f, 0x6f, 0xb3, 0xef, 0x0a, 0xe1, 0x3a,
+ 0xf0, 0xf5, 0xba, 0x15, 0x7c, 0x1d, 0x07, 0x5f, 0xef, 0x5f, 0xc5, 0xd7,
+ 0x1b, 0x9c, 0x01, 0xdd, 0x86, 0x67, 0x24, 0xf8, 0xdc, 0xe8, 0xd4, 0xf8,
+ 0xfa, 0x1e, 0xcd, 0xd7, 0x47, 0xc1, 0xd7, 0xd7, 0xd7, 0xf1, 0xf5, 0x7e,
+ 0x49, 0xdf, 0x9c, 0x8b, 0xed, 0x94, 0xd1, 0xfb, 0x55, 0xdb, 0x66, 0xf9,
+ 0x17, 0x31, 0xed, 0x0d, 0x8f, 0x0d, 0x4c, 0xb5, 0x49, 0xfe, 0xa1, 0x57,
+ 0x50, 0x46, 0x3e, 0x4b, 0x8f, 0x64, 0x1d, 0x4f, 0x8e, 0x1c, 0xff, 0xbe,
+ 0xcc, 0x6b, 0xde, 0x12, 0x19, 0x3b, 0x1e, 0x97, 0xf1, 0xe3, 0x8c, 0x43,
+ 0x7c, 0xcf, 0xd2, 0x7b, 0x93, 0x8c, 0x1f, 0x64, 0xde, 0x9c, 0x2b, 0xa3,
+ 0xc7, 0xe1, 0x6f, 0x1d, 0x67, 0x1c, 0xe2, 0xa5, 0x25, 0x1e, 0x9b, 0x87,
+ 0x6c, 0x19, 0x3d, 0xce, 0xb5, 0x8e, 0xa3, 0x9f, 0x16, 0x39, 0x7a, 0x5c,
+ 0xe4, 0xb6, 0xe3, 0xae, 0x7c, 0xe0, 0xf8, 0x12, 0xaf, 0x0d, 0x47, 0xbc,
+ 0xf6, 0x0c, 0x78, 0xad, 0xd3, 0xf2, 0x9a, 0x5a, 0xe2, 0xb5, 0xaf, 0xd6,
+ 0xf1, 0x1a, 0xdb, 0x93, 0xd7, 0x9e, 0xb5, 0x65, 0x7c, 0x76, 0xe5, 0xd0,
+ 0xf1, 0x76, 0x19, 0x7d, 0xe8, 0x2d, 0x32, 0x76, 0x3f, 0x61, 0x35, 0xdf,
+ 0x85, 0xa2, 0x2d, 0x36, 0x5d, 0xed, 0x44, 0xff, 0x51, 0x0e, 0x11, 0x71,
+ 0xed, 0x77, 0xcf, 0x48, 0xba, 0xc0, 0xf1, 0x1a, 0xe1, 0x47, 0x9f, 0x82,
+ 0x7f, 0x71, 0x08, 0x30, 0xdd, 0x72, 0x5c, 0xd2, 0xae, 0xbc, 0x2c, 0x13,
+ 0xc1, 0xe9, 0xed, 0xc6, 0x9e, 0x80, 0x2d, 0xa2, 0x6d, 0x9f, 0xac, 0xe4,
+ 0xdf, 0x1e, 0x6a, 0x1f, 0x63, 0xb2, 0x22, 0x8c, 0x05, 0x30, 0x6e, 0x6e,
+ 0xbf, 0x85, 0xca, 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0xfb,
+ 0xf8, 0x9e, 0xcf, 0xb0, 0x67, 0xf4, 0xd9, 0x45, 0xb6, 0x67, 0x3f, 0x09,
+ 0x1d, 0x53, 0x2f, 0x56, 0xf8, 0x4d, 0x1c, 0xf8, 0x9f, 0x15, 0x7e, 0x5b,
+ 0xeb, 0x37, 0xdb, 0x4c, 0x7c, 0x96, 0x7c, 0xf7, 0x5d, 0x27, 0x5f, 0x9a,
+ 0xd3, 0xdf, 0x38, 0xc8, 0xf9, 0xf8, 0x5d, 0xe1, 0x33, 0xeb, 0xcf, 0x31,
+ 0xde, 0x91, 0x4a, 0xa9, 0x63, 0xdb, 0x99, 0x7b, 0x70, 0x70, 0x8e, 0x75,
+ 0x77, 0x5a, 0x1e, 0xdd, 0xa9, 0xfd, 0x0e, 0xda, 0x58, 0xa3, 0x93, 0x2f,
+ 0x48, 0x91, 0xb6, 0xc9, 0xf0, 0x4e, 0xa7, 0x30, 0xfd, 0x73, 0xdb, 0x8d,
+ 0xfd, 0x3c, 0xb0, 0x95, 0x79, 0x87, 0x59, 0xb5, 0x5a, 0x26, 0x9f, 0x92,
+ 0x48, 0x26, 0xa7, 0x6f, 0xce, 0xc2, 0xce, 0xce, 0x1f, 0xd7, 0xdf, 0xab,
+ 0x4a, 0x75, 0x2a, 0xce, 0xe9, 0x4e, 0xc8, 0xd7, 0x88, 0x16, 0x92, 0xf2,
+ 0xd1, 0xe3, 0xa4, 0x07, 0x95, 0xd8, 0x28, 0x1f, 0xb1, 0xf4, 0x70, 0x46,
+ 0x4a, 0x90, 0x3b, 0xc7, 0x8f, 0x7f, 0x40, 0xa6, 0x0f, 0xac, 0xa4, 0x87,
+ 0xb1, 0x1a, 0x3d, 0x24, 0x60, 0x9f, 0x39, 0xf5, 0xf4, 0xf0, 0xf3, 0x4b,
+ 0xf4, 0x30, 0xed, 0xfc, 0x6b, 0xe9, 0xe1, 0x86, 0x65, 0xf4, 0x30, 0xa1,
+ 0xe9, 0x61, 0x68, 0x89, 0x1e, 0x26, 0x8e, 0x73, 0x5c, 0xbd, 0x37, 0xea,
+ 0x2d, 0x38, 0x5c, 0xf3, 0x25, 0x5a, 0x48, 0x8d, 0xeb, 0x7c, 0xfd, 0x74,
+ 0x81, 0xe7, 0x9b, 0x36, 0x28, 0xc6, 0x49, 0x6a, 0xeb, 0xbf, 0xf1, 0xdf,
+ 0x74, 0xfd, 0xaf, 0xda, 0xfa, 0xff, 0x77, 0xfd, 0x33, 0x5b, 0x99, 0xbb,
+ 0xcf, 0x33, 0xb0, 0x46, 0x1e, 0x47, 0xf4, 0x90, 0xdb, 0x6a, 0xf4, 0x02,
+ 0xd7, 0x98, 0xcf, 0x90, 0x67, 0x90, 0x7f, 0xe7, 0x21, 0xff, 0x9e, 0x80,
+ 0xfc, 0x7b, 0x7c, 0xd9, 0x9e, 0x40, 0xbf, 0x8d, 0x47, 0x84, 0x72, 0x24,
+ 0xa8, 0xe1, 0x63, 0xa1, 0x8f, 0xf8, 0x30, 0xf9, 0x27, 0xcc, 0xfd, 0x5d,
+ 0x8e, 0x13, 0x57, 0xe7, 0x1c, 0x3d, 0x1a, 0xd4, 0xe3, 0x84, 0x70, 0xbf,
+ 0x5c, 0x37, 0x47, 0xfc, 0xae, 0xf0, 0xf9, 0x8c, 0xce, 0x23, 0x29, 0xea,
+ 0x3d, 0x28, 0xe2, 0x85, 0x7b, 0x50, 0xc4, 0x89, 0xab, 0xed, 0xfd, 0x62,
+ 0xa5, 0x49, 0xe7, 0xd0, 0x1f, 0x9e, 0x4b, 0xc8, 0x42, 0x82, 0x31, 0x3e,
+ 0x7e, 0xe7, 0x90, 0x7e, 0xb3, 0x9f, 0x2c, 0x4a, 0x81, 0xb9, 0x72, 0xe0,
+ 0xe9, 0x0d, 0x96, 0xb6, 0x19, 0x1b, 0xe4, 0x19, 0xe0, 0x68, 0x2f, 0xa2,
+ 0xdb, 0xca, 0xba, 0x96, 0xba, 0x98, 0x25, 0xf0, 0x3e, 0x25, 0xa9, 0x5c,
+ 0x1f, 0xee, 0x73, 0x1c, 0xfb, 0x13, 0x32, 0xf1, 0xe0, 0x87, 0x61, 0xcb,
+ 0xbd, 0x1f, 0x3a, 0x87, 0xe7, 0xcf, 0xb8, 0xf7, 0xe0, 0x69, 0x18, 0x66,
+ 0xf4, 0x77, 0xac, 0xe8, 0x03, 0x92, 0x1e, 0x92, 0x78, 0x3e, 0x63, 0xe3,
+ 0x4a, 0x49, 0x29, 0x96, 0x5e, 0x94, 0x7c, 0x85, 0xdf, 0x5c, 0x7b, 0x09,
+ 0xf7, 0xd7, 0x5b, 0x0f, 0xe3, 0x87, 0x0c, 0xeb, 0x3b, 0xd7, 0x66, 0x51,
+ 0xb2, 0x15, 0x93, 0xe3, 0x52, 0x8b, 0x9b, 0x9c, 0x91, 0x63, 0xda, 0x7e,
+ 0xce, 0xd8, 0xdc, 0x96, 0xf4, 0x70, 0x41, 0x8c, 0x0d, 0xfd, 0x39, 0xd8,
+ 0xd0, 0x9f, 0xad, 0x66, 0xf5, 0x3e, 0xd6, 0xe3, 0xb0, 0xa1, 0x1f, 0x83,
+ 0xee, 0xa1, 0xce, 0x49, 0x58, 0x9d, 0x33, 0xa1, 0x0e, 0x68, 0x9d, 0xf3,
+ 0xe7, 0x5a, 0xe7, 0xbc, 0x7b, 0x95, 0xce, 0x39, 0xaa, 0x3a, 0x27, 0xa9,
+ 0x73, 0x06, 0xd4, 0x7e, 0x87, 0xf6, 0xe2, 0x96, 0x35, 0x74, 0xce, 0x7b,
+ 0xe4, 0x1d, 0xf6, 0xdd, 0x3d, 0xf2, 0xde, 0x3d, 0x7a, 0xef, 0xc6, 0x9b,
+ 0x51, 0xfc, 0x76, 0x93, 0xd1, 0x41, 0xd7, 0xab, 0x6e, 0xbd, 0xe7, 0xfb,
+ 0x95, 0x3a, 0x9d, 0xd3, 0xa1, 0xfa, 0x9c, 0x01, 0xdd, 0x86, 0xb1, 0x09,
+ 0x3e, 0x07, 0x4e, 0x76, 0xb8, 0x09, 0xcf, 0x49, 0x89, 0x1d, 0xc7, 0xdc,
+ 0xcd, 0xf7, 0xa5, 0x94, 0x79, 0xf7, 0x56, 0xfb, 0x4e, 0x45, 0xe5, 0xae,
+ 0x29, 0xef, 0xb4, 0xe5, 0x46, 0x57, 0x75, 0xa8, 0x76, 0xad, 0xab, 0x76,
+ 0x83, 0xa1, 0x66, 0xa0, 0x5f, 0x67, 0xca, 0x91, 0xce, 0xe2, 0x6f, 0xc6,
+ 0x9e, 0x19, 0xa3, 0x88, 0x62, 0xd8, 0x29, 0xd4, 0xc1, 0x55, 0x8e, 0x6c,
+ 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x0e, 0x78, 0xbd, 0x19, 0xfc, 0xf3,
+ 0x1f, 0x4a, 0x8c, 0x81, 0xb6, 0xc9, 0x89, 0xa9, 0xfa, 0x77, 0xed, 0xf2,
+ 0xae, 0xa9, 0x1d, 0x72, 0xfb, 0xe4, 0xd6, 0xa4, 0x34, 0xef, 0x94, 0x89,
+ 0xc9, 0x29, 0x7d, 0xfe, 0x7d, 0xb3, 0xfe, 0x2e, 0x08, 0xbf, 0x97, 0x63,
+ 0x64, 0xe4, 0x90, 0x63, 0x64, 0x64, 0x56, 0xd5, 0x6c, 0xd6, 0xa8, 0x4f,
+ 0x7e, 0x8b, 0x64, 0x70, 0x32, 0xa9, 0xbf, 0xa5, 0x3a, 0x53, 0xbd, 0x4a,
+ 0x7e, 0xfb, 0xa4, 0xba, 0x4b, 0xd5, 0xce, 0xf7, 0x6a, 0x9b, 0x75, 0x76,
+ 0x99, 0xcd, 0xfa, 0xbf, 0x64, 0xe1, 0xbd, 0x71, 0xcc, 0x13, 0x34, 0x7c,
+ 0xf5, 0xb7, 0xb8, 0x17, 0xda, 0x96, 0x90, 0x17, 0x65, 0x50, 0xe3, 0x8f,
+ 0xf2, 0xb4, 0x05, 0x72, 0x70, 0x51, 0xeb, 0xd7, 0x2d, 0xa0, 0x41, 0xca,
+ 0xd2, 0x0f, 0xca, 0x0b, 0x5a, 0x9e, 0x6d, 0xb1, 0xb6, 0xeb, 0x3c, 0xbf,
+ 0x6d, 0x7d, 0x9c, 0xb6, 0xeb, 0x9f, 0xdb, 0x72, 0x96, 0xa5, 0x93, 0x8b,
+ 0x42, 0x7d, 0x97, 0x80, 0x0c, 0xa5, 0x3c, 0x7d, 0xa3, 0xb6, 0xeb, 0x97,
+ 0x6c, 0x1f, 0x94, 0x9f, 0x46, 0x76, 0xef, 0x76, 0xe6, 0x6d, 0x19, 0x9f,
+ 0xa3, 0x78, 0xba, 0x9f, 0xcd, 0x5b, 0x3e, 0x53, 0xce, 0xe7, 0xf1, 0x7e,
+ 0x33, 0xde, 0x93, 0xcf, 0x1e, 0xd7, 0x7c, 0xa6, 0xed, 0x13, 0xa7, 0xd7,
+ 0xee, 0x2f, 0x2c, 0xed, 0x0d, 0x14, 0xc8, 0x67, 0xea, 0x84, 0x37, 0x6f,
+ 0xe4, 0x01, 0xf3, 0x54, 0x7f, 0x03, 0xba, 0x83, 0x6d, 0x51, 0xfe, 0x70,
+ 0x96, 0xbe, 0x2d, 0xfc, 0x9f, 0x8d, 0x78, 0x6e, 0xc3, 0xf3, 0x8c, 0xbc,
+ 0xfb, 0x60, 0x5c, 0xcf, 0x7b, 0x02, 0xf3, 0x38, 0x7c, 0x1c, 0x73, 0x72,
+ 0x8c, 0xed, 0xec, 0x9e, 0x75, 0xa5, 0xe1, 0x2c, 0xf9, 0x8e, 0x67, 0x6d,
+ 0xc2, 0xf0, 0x50, 0x2f, 0xe9, 0x36, 0xed, 0x0d, 0xe9, 0xb3, 0xa5, 0xbb,
+ 0x93, 0x31, 0xe0, 0xe4, 0x30, 0xd6, 0x63, 0xa2, 0xe4, 0x7b, 0x39, 0xc7,
+ 0x4f, 0x62, 0x9e, 0xb0, 0x01, 0x3b, 0x61, 0x0b, 0x76, 0xc2, 0x0e, 0xec,
+ 0x84, 0x1d, 0xb8, 0x49, 0x4e, 0x5d, 0xc3, 0x1c, 0x93, 0xc2, 0x75, 0xf0,
+ 0xca, 0xe5, 0xaf, 0x75, 0x9c, 0xbe, 0xf1, 0xe6, 0x41, 0xf8, 0xec, 0xe2,
+ 0xa5, 0x87, 0x99, 0x87, 0xbf, 0xe8, 0x35, 0xde, 0x3c, 0x24, 0x9d, 0xfd,
+ 0x78, 0xdf, 0xff, 0xa2, 0x74, 0xdd, 0x7c, 0xab, 0xd3, 0x38, 0x3c, 0x08,
+ 0x3c, 0x66, 0x9d, 0x74, 0x72, 0xc4, 0x99, 0xc7, 0x38, 0xb9, 0xdd, 0x31,
+ 0x61, 0xdc, 0x72, 0x9e, 0xb1, 0x88, 0x9b, 0x3b, 0x63, 0x3d, 0xa9, 0x51,
+ 0x27, 0x3d, 0xac, 0x62, 0xe9, 0xe1, 0x41, 0x27, 0xaa, 0xc7, 0x6f, 0xae,
+ 0x42, 0xce, 0x00, 0xd6, 0xc3, 0xe5, 0x4f, 0x83, 0x9e, 0x8e, 0x48, 0xf1,
+ 0x64, 0x8b, 0xcc, 0x95, 0x3a, 0xbd, 0x9c, 0x4a, 0xe8, 0xdc, 0x12, 0x75,
+ 0x0a, 0x44, 0x7f, 0x36, 0x2e, 0x33, 0x93, 0x3b, 0x45, 0x69, 0xdb, 0x7d,
+ 0x9b, 0xe4, 0xa6, 0x26, 0xe5, 0x62, 0x9f, 0xb4, 0x2a, 0xf4, 0xcf, 0x6f,
+ 0xdc, 0xaa, 0x53, 0xdc, 0x4b, 0x8c, 0x78, 0x61, 0x3b, 0xf9, 0x64, 0x12,
+ 0x38, 0x04, 0xdd, 0x32, 0xc6, 0xdb, 0x24, 0x94, 0x7b, 0x1f, 0xd0, 0xf1,
+ 0x53, 0xc6, 0x6c, 0xeb, 0xf7, 0x1e, 0xc8, 0x1f, 0xf1, 0x35, 0xf9, 0x63,
+ 0xb6, 0xcc, 0x7d, 0x1a, 0x29, 0xb8, 0x8c, 0x11, 0xfb, 0xf8, 0x3d, 0xcd,
+ 0xba, 0x4d, 0x32, 0xd1, 0x57, 0xb0, 0x79, 0x1e, 0x7f, 0x9e, 0x64, 0x0e,
+ 0x31, 0x71, 0x32, 0xda, 0x47, 0x5e, 0x5f, 0xb9, 0xb7, 0x11, 0xaf, 0x93,
+ 0x07, 0x8e, 0x2c, 0x4c, 0x46, 0x7b, 0x21, 0xec, 0x0f, 0xcf, 0xd3, 0x46,
+ 0xde, 0xe6, 0x56, 0xb5, 0x23, 0x5c, 0xdc, 0xaf, 0x5c, 0x2e, 0x63, 0x95,
+ 0x4f, 0x99, 0xea, 0x69, 0xf9, 0x7a, 0xa6, 0x6a, 0x64, 0xeb, 0x74, 0x35,
+ 0xd2, 0x2d, 0x71, 0xa3, 0x4b, 0x57, 0xe9, 0x13, 0x13, 0xcd, 0xac, 0xe9,
+ 0x13, 0xea, 0x45, 0x25, 0xef, 0x9b, 0xdb, 0x26, 0xee, 0xc3, 0xb2, 0x38,
+ 0xe1, 0x7f, 0x7a, 0x3b, 0x73, 0x35, 0x26, 0x82, 0x37, 0xa3, 0x1f, 0x9b,
+ 0xae, 0xa4, 0x3e, 0x1c, 0x51, 0x8d, 0xb8, 0x6f, 0xd6, 0xf4, 0x07, 0x9e,
+ 0xc2, 0xb3, 0xf1, 0x13, 0x3e, 0x07, 0x3f, 0xe1, 0xb3, 0xd0, 0x75, 0xe7,
+ 0xe1, 0x27, 0x3c, 0x01, 0x3f, 0xe1, 0x71, 0xf8, 0x09, 0x8f, 0x41, 0x4f,
+ 0xd6, 0xfb, 0x07, 0xe3, 0xcb, 0xfc, 0x83, 0x50, 0xf3, 0x3f, 0xe3, 0x81,
+ 0x4f, 0xd4, 0xf9, 0x06, 0x87, 0x8c, 0xbe, 0x82, 0xdf, 0x6f, 0xf8, 0xa8,
+ 0x43, 0xdd, 0xa4, 0xf5, 0xa3, 0xc9, 0xdb, 0x1d, 0x5e, 0xd2, 0x57, 0x1d,
+ 0xca, 0xe8, 0xab, 0x99, 0x9a, 0xbe, 0x32, 0x7c, 0xf4, 0xf0, 0xa4, 0xc4,
+ 0xfc, 0xc9, 0xf9, 0x5c, 0xb0, 0x57, 0xf3, 0x50, 0xab, 0xbf, 0x53, 0x62,
+ 0x0f, 0xa8, 0xb6, 0x06, 0xc9, 0xd9, 0x67, 0xd0, 0xd7, 0x89, 0x4f, 0xa3,
+ 0xaf, 0xeb, 0x24, 0xaf, 0xed, 0xb3, 0xcb, 0xe3, 0xfb, 0xb1, 0x15, 0xf8,
+ 0x2e, 0x96, 0x27, 0x34, 0xce, 0xef, 0xaf, 0x70, 0x9f, 0xa5, 0x45, 0xc6,
+ 0x2b, 0x11, 0xce, 0x79, 0x9e, 0x95, 0xb9, 0x18, 0xed, 0x12, 0x7b, 0x78,
+ 0x1b, 0xcf, 0x59, 0xa9, 0x7c, 0xb0, 0x5e, 0xe7, 0xb0, 0x9c, 0xea, 0x93,
+ 0x64, 0xbe, 0x8f, 0xb4, 0x7a, 0x9f, 0xcc, 0xe8, 0xb5, 0xd8, 0x26, 0x0d,
+ 0x0f, 0xd3, 0x46, 0x89, 0xf6, 0xf3, 0xde, 0x7f, 0xa5, 0xfd, 0xe6, 0x6a,
+ 0xdc, 0xd4, 0x13, 0x39, 0xa2, 0xd7, 0x6b, 0x5a, 0xe7, 0x19, 0xde, 0x34,
+ 0xc7, 0xb8, 0x3c, 0xbf, 0x6f, 0xc5, 0x98, 0xfc, 0xbf, 0x66, 0xfd, 0x7e,
+ 0xf9, 0x4a, 0x63, 0xcf, 0x6c, 0xb6, 0x76, 0x8c, 0x89, 0x53, 0xad, 0x6d,
+ 0xc3, 0xb0, 0x9f, 0xfa, 0x6f, 0x32, 0xee, 0x70, 0xc6, 0x27, 0x77, 0x3a,
+ 0xc5, 0x49, 0xee, 0x65, 0xdb, 0xbf, 0xd1, 0xe1, 0xed, 0x77, 0x0e, 0xfb,
+ 0x3b, 0x50, 0xc6, 0x98, 0x25, 0x63, 0x36, 0xf7, 0x5f, 0xc9, 0x18, 0x6d,
+ 0xce, 0xe7, 0xd8, 0x2c, 0xdb, 0xe1, 0x4c, 0x4c, 0x76, 0xc2, 0x37, 0xe7,
+ 0xb9, 0x2a, 0xbe, 0x1f, 0xe2, 0xda, 0x41, 0x07, 0x7b, 0xfa, 0xcc, 0xee,
+ 0x98, 0x5c, 0x65, 0x63, 0xd0, 0xd4, 0xc3, 0x3f, 0xbd, 0x6c, 0xef, 0xf6,
+ 0x28, 0xf4, 0xd8, 0x2d, 0x90, 0x47, 0xd4, 0xc3, 0x47, 0xe5, 0x6d, 0x96,
+ 0x9e, 0x97, 0xeb, 0xe1, 0x4b, 0xc2, 0x38, 0x71, 0x2f, 0xde, 0x15, 0xc2,
+ 0x38, 0xe8, 0xe1, 0x58, 0x9d, 0xaf, 0x46, 0xbf, 0xaf, 0x29, 0x63, 0xf6,
+ 0xc3, 0x96, 0xfb, 0x7d, 0x90, 0x03, 0x89, 0xc8, 0xcf, 0x6b, 0x5c, 0xda,
+ 0xaf, 0xdd, 0x6f, 0xdb, 0x4e, 0x04, 0x7f, 0x44, 0x1c, 0xa5, 0x8e, 0xca,
+ 0x2f, 0x42, 0xa7, 0x31, 0x07, 0xe4, 0x2f, 0x34, 0xce, 0x44, 0x91, 0xf6,
+ 0x36, 0x6b, 0x18, 0xad, 0x9c, 0x4f, 0x45, 0x39, 0x1c, 0x45, 0xdb, 0x76,
+ 0xcc, 0xee, 0xc9, 0x17, 0xe5, 0xeb, 0x8c, 0x73, 0xa6, 0x06, 0x63, 0xeb,
+ 0xf9, 0x3d, 0x46, 0xb4, 0xfd, 0x45, 0xed, 0xb7, 0x67, 0x25, 0xea, 0x8b,
+ 0xcf, 0x0d, 0x75, 0x7d, 0xd3, 0x8e, 0xe2, 0x7d, 0xe5, 0x39, 0xb2, 0xa7,
+ 0xf5, 0x3e, 0xa3, 0xf9, 0x5e, 0x42, 0xc4, 0x27, 0xe4, 0x9d, 0x94, 0x3e,
+ 0xeb, 0xe4, 0x3f, 0x4c, 0xbb, 0x87, 0x7b, 0xb0, 0xde, 0xfc, 0x78, 0xf0,
+ 0x11, 0xfd, 0xcd, 0xc0, 0x69, 0x11, 0xa7, 0x18, 0xdc, 0xa6, 0x73, 0x4f,
+ 0x8a, 0x3a, 0xd6, 0x5c, 0xc0, 0xbd, 0xe6, 0xa3, 0x76, 0x3c, 0xcc, 0xbf,
+ 0xc3, 0xc1, 0xb2, 0x3c, 0x60, 0xa3, 0x0e, 0xa1, 0xec, 0x4d, 0x48, 0xc7,
+ 0x89, 0x5f, 0xd0, 0xbc, 0xb0, 0x05, 0xbe, 0xc0, 0xc0, 0x09, 0xe8, 0xea,
+ 0x13, 0x49, 0x19, 0x3a, 0xa1, 0x75, 0x63, 0x76, 0x75, 0xac, 0xa0, 0xc7,
+ 0x73, 0x9d, 0x77, 0xe9, 0x73, 0x6c, 0x6f, 0x3d, 0x11, 0x93, 0x63, 0x89,
+ 0x1e, 0xaf, 0xcb, 0x79, 0xb7, 0xd5, 0x85, 0x51, 0x0c, 0xbb, 0x05, 0xed,
+ 0x5f, 0x2f, 0x8e, 0x1d, 0xc5, 0xaf, 0x63, 0x32, 0x7d, 0xb0, 0x1d, 0xb0,
+ 0x75, 0x6e, 0x33, 0x67, 0x90, 0xb1, 0x56, 0xfa, 0x1b, 0xf7, 0x6e, 0x92,
+ 0xb2, 0xac, 0x03, 0xb0, 0x0c, 0x9e, 0xa0, 0x3e, 0xf3, 0x35, 0x8f, 0x03,
+ 0x06, 0xaf, 0x41, 0xfb, 0x21, 0xe4, 0xcb, 0xb7, 0x88, 0xff, 0x00, 0x64,
+ 0xdc, 0x89, 0xb8, 0x74, 0x9d, 0x68, 0x91, 0x5d, 0x27, 0xe8, 0x87, 0xd4,
+ 0xfb, 0xa5, 0xb4, 0x4b, 0xe7, 0x30, 0xc7, 0x77, 0x6a, 0x39, 0xc9, 0x3d,
+ 0xcd, 0xdb, 0xc9, 0xbb, 0xa8, 0x9b, 0x87, 0xcd, 0x9c, 0x3b, 0xe1, 0xe9,
+ 0x3d, 0xd2, 0x1c, 0xe6, 0x9c, 0xaf, 0x78, 0x18, 0xc7, 0xc8, 0x9c, 0x22,
+ 0xfd, 0x94, 0xe1, 0x6d, 0xc0, 0xf1, 0x31, 0xcb, 0x3b, 0x43, 0xdb, 0x2c,
+ 0x8f, 0xfe, 0x88, 0xbc, 0x77, 0xf3, 0x36, 0x23, 0x3b, 0x7f, 0x76, 0x1b,
+ 0x73, 0x93, 0xb6, 0xf8, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
+ 0xe2, 0x45, 0x01, 0x8e, 0xa2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0xbc, 0x18,
+ 0xe8, 0xf3, 0x2b, 0xc1, 0x02, 0xf3, 0x08, 0xf5, 0x77, 0x14, 0x6a, 0xdf,
+ 0x5b, 0xd9, 0x5b, 0x65, 0x9c, 0xfc, 0x89, 0xe8, 0x6f, 0xa9, 0xd4, 0xe5,
+ 0x1d, 0xd6, 0xef, 0x81, 0x31, 0xd6, 0xb4, 0x94, 0x1b, 0x14, 0x4e, 0xea,
+ 0xef, 0x21, 0x3d, 0xeb, 0x5c, 0x2a, 0x5d, 0x70, 0xbe, 0x39, 0x25, 0xa1,
+ 0xeb, 0x7f, 0xdf, 0xf9, 0xb6, 0xcf, 0x3d, 0xf3, 0x2f, 0x3b, 0xdf, 0x2a,
+ 0xf9, 0xe0, 0xc3, 0x0b, 0x98, 0xc7, 0x2b, 0xce, 0x77, 0xb0, 0xbe, 0x47,
+ 0xca, 0xd9, 0xb4, 0x67, 0x63, 0xe2, 0x17, 0x4a, 0xaf, 0x38, 0x5f, 0xaa,
+ 0xc5, 0x93, 0xfa, 0x23, 0x1a, 0x39, 0xca, 0x77, 0x15, 0xbc, 0xab, 0xe8,
+ 0xfd, 0x1f, 0x67, 0x76, 0xca, 0xe6, 0x97, 0x68, 0x3e, 0x9e, 0x5f, 0xda,
+ 0x97, 0x19, 0xd6, 0x7b, 0x15, 0xcf, 0x38, 0xb3, 0x73, 0x9f, 0xdb, 0x66,
+ 0xf2, 0x8c, 0x2e, 0xe0, 0x9d, 0xc9, 0xb9, 0x9c, 0x99, 0xbb, 0x80, 0x3a,
+ 0x4f, 0x3b, 0x33, 0x3a, 0xfe, 0xc5, 0x76, 0x17, 0x9c, 0xe9, 0xb9, 0xa7,
+ 0x9d, 0x39, 0xbd, 0x07, 0x7d, 0xd1, 0x79, 0x74, 0x8a, 0x7d, 0x5f, 0x44,
+ 0x9d, 0x79, 0xe7, 0x14, 0xfa, 0x9b, 0x9b, 0xe2, 0x79, 0xdc, 0x4e, 0xd8,
+ 0x05, 0xfc, 0x1b, 0x45, 0xfc, 0x1e, 0xc7, 0x33, 0xce, 0xdc, 0x52, 0xbf,
+ 0x0b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x19, 0xf4, 0xbf, 0x7a,
+ 0xaf, 0x6a, 0x35, 0x4e, 0x9e, 0x07, 0x4e, 0x5e, 0xb4, 0x38, 0x79, 0xd5,
+ 0xe2, 0xe4, 0xb9, 0x3a, 0x9c, 0x88, 0x5a, 0x8e, 0x93, 0x57, 0x81, 0x13,
+ 0x51, 0x6b, 0xe3, 0x04, 0xef, 0x2a, 0x78, 0xa7, 0x71, 0xf2, 0xd2, 0x0a,
+ 0x9c, 0x2c, 0x2e, 0xc5, 0xe5, 0x0d, 0x4e, 0x5e, 0x00, 0x4e, 0x7e, 0x60,
+ 0x61, 0x7f, 0xd1, 0xe2, 0x04, 0xf7, 0xb9, 0x17, 0x51, 0xe7, 0xa5, 0x3a,
+ 0x9c, 0xbc, 0x08, 0x9c, 0xbc, 0x64, 0x71, 0xf2, 0x6d, 0x8b, 0x93, 0x6f,
+ 0xa3, 0xce, 0x22, 0x70, 0x72, 0x69, 0x0d, 0x9c, 0xbc, 0x00, 0x9c, 0x44,
+ 0xfd, 0x5e, 0x42, 0x3f, 0xdf, 0xae, 0xc3, 0xc9, 0x0b, 0x6b, 0xe0, 0x84,
+ 0x7b, 0xb1, 0x51, 0x4e, 0xf7, 0x99, 0xd7, 0xc9, 0xe9, 0x5e, 0x7c, 0x03,
+ 0x39, 0xdd, 0xac, 0x73, 0x46, 0x6a, 0x7f, 0xbb, 0x62, 0xc2, 0xe6, 0xa8,
+ 0x99, 0x5c, 0xc0, 0xda, 0x37, 0x9b, 0x3a, 0xc1, 0xe7, 0xc5, 0x02, 0xbc,
+ 0x11, 0x9d, 0x53, 0xea, 0xee, 0x19, 0x03, 0xaf, 0xbd, 0x5b, 0x0e, 0x9f,
+ 0x6c, 0x3c, 0x96, 0xb7, 0x65, 0xfe, 0x9e, 0xce, 0x82, 0x52, 0x7c, 0x17,
+ 0xe5, 0x24, 0xd0, 0x2f, 0x69, 0xe0, 0xb7, 0x0a, 0xbb, 0xb3, 0x52, 0xbf,
+ 0x27, 0x3d, 0xc5, 0x6f, 0x34, 0x71, 0x7f, 0x8c, 0x7f, 0x67, 0x23, 0xc5,
+ 0x3c, 0xab, 0xa2, 0x86, 0x37, 0x0d, 0xfd, 0xd1, 0xaf, 0x73, 0xab, 0xf8,
+ 0x37, 0x82, 0x62, 0xf0, 0xfb, 0x47, 0xfb, 0x68, 0x2b, 0x67, 0xec, 0x99,
+ 0xb0, 0x40, 0x9f, 0x53, 0xa9, 0xf1, 0x4f, 0xfd, 0x79, 0x68, 0xf2, 0x5d,
+ 0x8d, 0x6e, 0x8e, 0x2c, 0x7d, 0x77, 0xf0, 0xb4, 0x3c, 0xa5, 0x63, 0xc5,
+ 0xcd, 0xfa, 0xef, 0x2b, 0x9c, 0x09, 0x4c, 0x8c, 0x76, 0x41, 0xc7, 0x68,
+ 0x05, 0xde, 0xf8, 0xb8, 0x8d, 0xd3, 0x76, 0xf5, 0xbf, 0xb4, 0x14, 0xa3,
+ 0xad, 0xcf, 0x67, 0x31, 0xfb, 0xeb, 0xb9, 0xc9, 0x39, 0x9d, 0xa3, 0x33,
+ 0xc8, 0xef, 0x6f, 0x40, 0x46, 0x8c, 0x4d, 0x57, 0x64, 0xfc, 0x41, 0x3e,
+ 0x53, 0xbf, 0xc5, 0xa0, 0xc3, 0x28, 0xc3, 0x0b, 0x92, 0xeb, 0x67, 0x99,
+ 0x69, 0x33, 0xa8, 0xfd, 0xe5, 0xd3, 0x32, 0xb0, 0x34, 0x3e, 0xf1, 0xfb,
+ 0x89, 0xba, 0xef, 0x60, 0xd3, 0xe6, 0xc9, 0x3a, 0xb9, 0x2a, 0xdf, 0x47,
+ 0x7b, 0xe4, 0x9f, 0xb0, 0xdf, 0x0a, 0xe4, 0xfb, 0xfa, 0x6f, 0xbf, 0x6a,
+ 0xd1, 0x81, 0xdf, 0xfc, 0xbe, 0xda, 0x84, 0x33, 0x88, 0x36, 0xf3, 0x5e,
+ 0xcb, 0xb0, 0xca, 0xdc, 0x38, 0xcc, 0x73, 0x73, 0x33, 0xab, 0xbe, 0x9d,
+ 0x5d, 0xd3, 0x8b, 0x45, 0xbd, 0xa6, 0xcc, 0xcf, 0x2a, 0x80, 0x16, 0x35,
+ 0x6d, 0x69, 0xfa, 0x3f, 0xbc, 0xa4, 0x2f, 0xa9, 0x67, 0xcd, 0xb7, 0x67,
+ 0x8c, 0xbe, 0x4c, 0x27, 0x07, 0x31, 0xbe, 0xfe, 0x1b, 0x0d, 0xf6, 0x5c,
+ 0x6f, 0x7e, 0xee, 0x2e, 0xad, 0xeb, 0x27, 0x82, 0x6c, 0xca, 0x95, 0x35,
+ 0xea, 0x4e, 0xd6, 0xd5, 0xd5, 0xf3, 0xf6, 0xe4, 0xb7, 0xb0, 0x36, 0xbf,
+ 0x51, 0xae, 0xc8, 0xc0, 0xd4, 0x5f, 0xc1, 0x7f, 0x4c, 0xca, 0x6f, 0x96,
+ 0x1f, 0x01, 0xbd, 0x16, 0xb6, 0xd8, 0x6f, 0x35, 0xe5, 0x00, 0x37, 0xbf,
+ 0xbd, 0xa2, 0xf3, 0x89, 0x63, 0xbf, 0x0d, 0xba, 0xf8, 0xcc, 0x23, 0x1c,
+ 0x03, 0xb0, 0xc4, 0x60, 0xdb, 0xc3, 0x4e, 0x98, 0x7e, 0x44, 0xe7, 0xce,
+ 0x5d, 0x5f, 0x79, 0x44, 0xc7, 0x2c, 0x86, 0x2a, 0xed, 0xb2, 0xb7, 0xd2,
+ 0x22, 0xfb, 0xa0, 0x17, 0xf6, 0x55, 0x7c, 0x5c, 0x71, 0x79, 0x67, 0xc5,
+ 0xac, 0xd3, 0x07, 0x2b, 0x5c, 0xef, 0x3d, 0x32, 0x73, 0x72, 0xe5, 0xf7,
+ 0x3e, 0xe7, 0x0b, 0xd1, 0xdf, 0x73, 0x52, 0x8a, 0xf9, 0x65, 0xa4, 0x25,
+ 0x5c, 0xe5, 0xf4, 0xb1, 0x79, 0x8d, 0x07, 0x66, 0xb8, 0xa6, 0x27, 0x17,
+ 0x85, 0x79, 0xfa, 0xfc, 0x1b, 0x4e, 0x7f, 0xb9, 0x9d, 0xe7, 0xa6, 0xf9,
+ 0x2d, 0xaf, 0xa1, 0x6a, 0x94, 0x37, 0xbe, 0x56, 0xce, 0x38, 0xec, 0xfc,
+ 0x3d, 0x51, 0x8e, 0x5f, 0x9c, 0x39, 0xe3, 0xd2, 0x71, 0xb6, 0x05, 0xf7,
+ 0xef, 0x6e, 0xd7, 0x67, 0x9b, 0xcf, 0x8a, 0x2d, 0xd3, 0xf9, 0xe4, 0x78,
+ 0x5e, 0xf9, 0xbd, 0xb6, 0x88, 0x1f, 0x6a, 0x7f, 0xf7, 0x40, 0xe4, 0xff,
+ 0x02, 0x06, 0x86, 0xe5, 0x0a, 0xd4, 0x6f, 0x00, 0x00, 0x00 };
static const u32 bnx2_CP_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = {
- 0x0800061c, 0x0800083c, 0x08000780, 0x080007a8, 0x080007d0, 0x080007f8,
- 0x08000654, 0x08000640, 0x08000864, 0x08000864, 0x08000670, 0x0800068c,
- 0x0800068c, 0x08000864, 0x080006a4, 0x080006b8, 0x08000864, 0x080006cc,
- 0x08000864, 0x08000864, 0x080006e0, 0x08000864, 0x08000864, 0x08000864,
- 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864,
- 0x08000864, 0x080006f4, 0x08000864, 0x08000708, 0x0800071c, 0x08000730,
- 0x08000864, 0x08000744, 0x08000758, 0x0800076c, 0x08003200, 0x08003218,
- 0x08003228, 0x08003238, 0x08003250, 0x08003268, 0x08003278, 0x08003288,
- 0x080032a8, 0x080032b8, 0x080032c8, 0x08003358, 0x08003298, 0x080032d8,
- 0x080032e8, 0x08003300, 0x08003320, 0x08003358, 0x08003338, 0x08003338,
- 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050fc,
- 0x080050fc, 0x08005124, 0x08005174, 0x08005144, 0x00000000 };
+ 0x0800069c, 0x080008bc, 0x08000800, 0x08000828, 0x08000850, 0x08000878,
+ 0x080006d4, 0x080006c0, 0x080008e4, 0x080008e4, 0x080006f0, 0x0800070c,
+ 0x0800070c, 0x080008e4, 0x08000724, 0x08000738, 0x080008e4, 0x0800074c,
+ 0x080008e4, 0x080008e4, 0x08000760, 0x080008e4, 0x080008e4, 0x080008e4,
+ 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4,
+ 0x080008e4, 0x08000774, 0x080008e4, 0x08000788, 0x0800079c, 0x080007b0,
+ 0x080008e4, 0x080007c4, 0x080007d8, 0x080007ec, 0x080032e8, 0x08003300,
+ 0x08003310, 0x08003320, 0x08003338, 0x08003350, 0x08003360, 0x08003370,
+ 0x08003390, 0x080033a0, 0x080033b0, 0x08003440, 0x08003380, 0x080033c0,
+ 0x080033d0, 0x080033e8, 0x08003408, 0x08003440, 0x08003420, 0x08003420,
+ 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051e4,
+ 0x080051e4, 0x0800520c, 0x0800525c, 0x0800522c, 0x00000000 };
static struct fw_info bnx2_cp_fw_09 = {
+ /* Firmware version: 3.7.1 */
.ver_major = 0x3,
- .ver_minor = 0x4,
- .ver_fix = 0x3,
+ .ver_minor = 0x7,
+ .ver_fix = 0x1,
.start_addr = 0x0800006c,
.text_addr = 0x08000000,
- .text_len = 0x6ee8,
+ .text_len = 0x6fd0,
.text_index = 0x0,
.gz_text = bnx2_CP_b09FwText,
.gz_text_len = sizeof(bnx2_CP_b09FwText),
- .data_addr = 0x08007020,
+ .data_addr = 0x08007100,
.data_len = 0x0,
.data_index = 0x0,
.data = bnx2_CP_b09FwData,
- .sbss_addr = 0x08007024,
- .sbss_len = 0xa1,
+ .sbss_addr = 0x08007104,
+ .sbss_len = 0xa9,
.sbss_index = 0x0,
- .bss_addr = 0x080070d0,
+ .bss_addr = 0x080071b0,
.bss_len = 0x3b0,
.bss_index = 0x0,
- .rodata_addr = 0x08006ee8,
+ .rodata_addr = 0x08006fd0,
.rodata_len = 0x118,
.rodata_index = 0x0,
.rodata = bnx2_CP_b09FwRodata,
};
static u8 bnx2_RXP_b09FwText[] = {
-/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
- 0xec, 0x5c,
- 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x6a, 0x49, 0xf1, 0x67,
- 0xb8, 0x5c, 0xb1, 0x2b, 0x99, 0x96, 0x77, 0xc9, 0x91, 0xc8, 0x58, 0x8a,
- 0x31, 0xa2, 0x09, 0x5b, 0x48, 0x17, 0xf6, 0x76, 0x76, 0x25, 0xb1, 0xb1,
- 0x03, 0x53, 0xb6, 0x62, 0x07, 0x45, 0x6a, 0xb0, 0x4b, 0xb9, 0x0e, 0x8c,
- 0x06, 0x90, 0xff, 0x52, 0xbf, 0xb0, 0xde, 0x2c, 0xa9, 0x58, 0x4d, 0x17,
- 0x9c, 0xb5, 0x4d, 0x9b, 0x0e, 0x60, 0xb7, 0x0b, 0x92, 0x12, 0xf5, 0xb0,
- 0xd0, 0xb2, 0xa9, 0xdb, 0xea, 0xc1, 0x8e, 0x09, 0x56, 0xb1, 0x53, 0xa0,
- 0x2d, 0x5c, 0x27, 0x69, 0xfc, 0x10, 0x14, 0xaa, 0xec, 0xc4, 0x42, 0xd1,
- 0xa2, 0x02, 0x12, 0xd8, 0x29, 0x22, 0x7b, 0xfa, 0x7d, 0x77, 0x66, 0xc8,
- 0x25, 0x2d, 0xdb, 0x41, 0x1f, 0xfa, 0xd2, 0xbd, 0xc0, 0x62, 0xee, 0xbd,
- 0x73, 0xee, 0xb9, 0xe7, 0x9e, 0xff, 0x73, 0x87, 0xd2, 0x1f, 0x74, 0x48,
- 0xbb, 0x84, 0xad, 0x13, 0xbf, 0xd4, 0x89, 0x27, 0x1e, 0xb9, 0x69, 0xf4,
- 0xa6, 0x9b, 0xd1, 0xbd, 0xd9, 0x30, 0x4c, 0x23, 0x9a, 0x6f, 0xb6, 0x66,
- 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
- 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
- 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
- 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
- 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66,
- 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0xfb, 0xff, 0xde,
- 0x0c, 0x11, 0x8b, 0xcf, 0xce, 0xf0, 0x27, 0x31, 0x3d, 0x23, 0x0f, 0xb9,
- 0xb6, 0xc4, 0x8c, 0xcc, 0xd5, 0xa9, 0x49, 0x5b, 0x24, 0x5b, 0xdb, 0x97,
- 0xca, 0xc9, 0x87, 0x7e, 0x31, 0x61, 0x0a, 0xe7, 0xaf, 0xcf, 0x5c, 0xfd,
- 0x8b, 0x57, 0x6f, 0x4d, 0x5f, 0xa9, 0x1a, 0x12, 0xb3, 0x32, 0x33, 0x07,
- 0xac, 0xbd, 0x12, 0xeb, 0xc7, 0x9a, 0x17, 0x87, 0xfe, 0xa9, 0x4b, 0xba,
- 0x22, 0x5c, 0x22, 0x0b, 0xe5, 0xb4, 0x73, 0x18, 0xcf, 0x33, 0xb5, 0x7d,
- 0xce, 0x9a, 0x98, 0xb2, 0x6a, 0x05, 0x3b, 0x96, 0xca, 0x1a, 0xf1, 0x48,
- 0xa9, 0x16, 0x93, 0x8b, 0xea, 0xdf, 0x79, 0x60, 0x4f, 0x9b, 0xfd, 0xf3,
- 0x9a, 0x5b, 0xf7, 0xfd, 0xd3, 0x8e, 0xef, 0xbf, 0x8e, 0xdf, 0x7b, 0x0e,
- 0xc6, 0xde, 0x47, 0x7e, 0xd6, 0x34, 0x44, 0xb7, 0xff, 0x4c, 0x73, 0x17,
- 0x5b, 0xa5, 0x34, 0x2f, 0x32, 0xed, 0xc5, 0xe4, 0x94, 0x57, 0xd4, 0xf2,
- 0xf5, 0xb2, 0x76, 0x68, 0x79, 0x56, 0x3b, 0xbc, 0x7c, 0x4a, 0x3b, 0xb2,
- 0x5c, 0xd1, 0xdc, 0x65, 0x29, 0xea, 0x07, 0x3a, 0x24, 0x6b, 0x9d, 0xd5,
- 0x72, 0xf5, 0x3e, 0xcd, 0x9d, 0xbf, 0xea, 0xbb, 0x4e, 0xda, 0xfa, 0x3d,
- 0x31, 0xb3, 0xdc, 0xcf, 0x2d, 0xfb, 0x18, 0x9b, 0x92, 0x4d, 0xf8, 0xbe,
- 0x9e, 0xf1, 0x9f, 0x74, 0x47, 0x6d, 0x4b, 0xd7, 0x62, 0x52, 0xaa, 0xb7,
- 0x03, 0x6f, 0x87, 0x96, 0x9b, 0x37, 0xb5, 0xbc, 0xe7, 0xbf, 0xe6, 0x3a,
- 0xd2, 0x6f, 0x88, 0xef, 0xcf, 0x38, 0x7b, 0x92, 0xc7, 0xe5, 0x0c, 0xf0,
- 0xd6, 0x80, 0x4f, 0x2c, 0x3d, 0x43, 0xfa, 0x22, 0x9a, 0x8b, 0x5a, 0x6e,
- 0x28, 0xa2, 0x4f, 0x52, 0xa4, 0xbf, 0xb0, 0xa4, 0x83, 0xce, 0xed, 0x52,
- 0xa8, 0x5a, 0x32, 0xb1, 0xb4, 0x15, 0xfe, 0xa2, 0xff, 0xea, 0x50, 0x42,
- 0xfe, 0xb2, 0x9e, 0x3e, 0x55, 0x04, 0x2f, 0x66, 0xbc, 0x94, 0x80, 0xcf,
- 0x59, 0x77, 0xb4, 0x5f, 0x5e, 0xab, 0x27, 0xe5, 0xbb, 0x75, 0x3b, 0x59,
- 0x92, 0x6d, 0x52, 0x48, 0x58, 0xb2, 0x82, 0x35, 0xd3, 0xa0, 0x43, 0xb7,
- 0x6d, 0xab, 0x04, 0xd8, 0x52, 0xfd, 0x27, 0xfc, 0xb7, 0x32, 0xd6, 0xe4,
- 0xa8, 0x5a, 0x53, 0x04, 0xdd, 0x21, 0x2c, 0xcf, 0xa1, 0x60, 0xd5, 0x59,
- 0x02, 0x58, 0x29, 0x4e, 0x8e, 0x62, 0xae, 0xfe, 0x85, 0x50, 0x16, 0xad,
- 0x38, 0x2f, 0x9f, 0xbb, 0x71, 0xbe, 0xdd, 0xe0, 0x89, 0x24, 0x74, 0xd9,
- 0x93, 0x2c, 0x60, 0x66, 0xba, 0xde, 0x81, 0x31, 0x69, 0xf1, 0xfd, 0x23,
- 0x8e, 0x58, 0x25, 0xa7, 0x1b, 0xbc, 0x4b, 0x49, 0xc9, 0xe9, 0xc2, 0x9a,
- 0x16, 0xb1, 0x6c, 0x9e, 0x81, 0x78, 0xdb, 0x30, 0xef, 0x77, 0x1a, 0x19,
- 0xdf, 0x9f, 0x1c, 0x95, 0xae, 0x60, 0x6e, 0x1f, 0x70, 0x98, 0x32, 0x31,
- 0xae, 0x01, 0xee, 0x03, 0xd2, 0x17, 0x8b, 0x67, 0xd8, 0xe7, 0x73, 0x54,
- 0xdc, 0xd9, 0x54, 0xb8, 0x6f, 0x87, 0x94, 0xbc, 0xeb, 0xc3, 0x3e, 0x78,
- 0xed, 0xe1, 0xcc, 0xce, 0x4e, 0x8c, 0xb5, 0x1b, 0x80, 0xc7, 0x29, 0x09,
- 0xf7, 0xd8, 0x21, 0x6b, 0x09, 0xd1, 0x2f, 0x39, 0xbd, 0x21, 0x5c, 0x17,
- 0x68, 0x8d, 0x64, 0xde, 0x2e, 0x33, 0xf3, 0xad, 0x72, 0x72, 0x9e, 0xbc,
- 0x2d, 0x43, 0x16, 0x78, 0xde, 0x52, 0xd4, 0xb2, 0xf5, 0x53, 0xe8, 0x9b,
- 0x32, 0x69, 0xfb, 0xaf, 0xcd, 0x38, 0xb3, 0x5a, 0x6e, 0xf9, 0x8c, 0x96,
- 0x87, 0x0e, 0x1c, 0x5a, 0x3e, 0xaf, 0x1d, 0xae, 0xaf, 0x76, 0x4a, 0x7b,
- 0x1a, 0xda, 0x66, 0xca, 0x49, 0x4f, 0x13, 0xd2, 0xbb, 0x00, 0x7e, 0x65,
- 0x2d, 0x70, 0xde, 0xee, 0xd2, 0x0e, 0x03, 0x57, 0x8b, 0xfd, 0xad, 0x0e,
- 0xe9, 0x32, 0x64, 0x9b, 0x1d, 0xc1, 0xc6, 0xe4, 0x5b, 0xa0, 0x6d, 0xcd,
- 0x49, 0x00, 0x4e, 0xba, 0x83, 0x35, 0x3d, 0x21, 0x3d, 0xd4, 0x25, 0xea,
- 0x91, 0x9e, 0xcd, 0xcf, 0xfd, 0x69, 0x6f, 0x69, 0xff, 0x76, 0xc2, 0xc0,
- 0x3e, 0x52, 0x0f, 0x4d, 0xda, 0x6e, 0x8f, 0x29, 0x45, 0x4b, 0x97, 0xb4,
- 0x95, 0x93, 0x1b, 0x64, 0xc6, 0x11, 0xc9, 0x41, 0xbf, 0x75, 0xdb, 0x04,
- 0x8f, 0x6c, 0xf0, 0x68, 0xcf, 0xa9, 0x41, 0xfd, 0x0e, 0x49, 0xf5, 0x15,
- 0x35, 0x33, 0xe4, 0xe7, 0x82, 0xdc, 0xa6, 0xd6, 0xeb, 0x19, 0x07, 0x3a,
- 0xd9, 0xce, 0x3e, 0xf6, 0x8d, 0xa9, 0x7d, 0x8d, 0x8c, 0x9d, 0x5c, 0x14,
- 0xd1, 0xf4, 0xcc, 0x3e, 0xe0, 0xa3, 0xae, 0x12, 0xee, 0x29, 0xd0, 0x48,
- 0xda, 0xd9, 0xb7, 0xb1, 0x26, 0x26, 0xae, 0xd3, 0xd9, 0x40, 0x27, 0xe8,
- 0x49, 0x90, 0xe7, 0xe4, 0xa1, 0x3a, 0xa7, 0xb6, 0x71, 0xce, 0x5f, 0xfb,
- 0xdb, 0x46, 0x4c, 0x79, 0x5d, 0x9d, 0x97, 0x76, 0x45, 0x38, 0x75, 0x46,
- 0x21, 0x7f, 0xa6, 0x3d, 0xd1, 0x0a, 0x8e, 0xb5, 0x8e, 0x0b, 0x7a, 0xa1,
- 0x1b, 0x99, 0x0e, 0xc9, 0x29, 0xfa, 0x0e, 0x62, 0x2f, 0xda, 0x1b, 0xec,
- 0xc6, 0xe6, 0x59, 0x38, 0x97, 0x81, 0xed, 0xa6, 0x95, 0xfe, 0x14, 0x2a,
- 0xf4, 0x07, 0xa4, 0x6d, 0x35, 0xad, 0x4b, 0x80, 0xaf, 0xf4, 0x6c, 0x37,
- 0x68, 0xe3, 0x18, 0xb6, 0x67, 0xe3, 0xfd, 0x7e, 0xd8, 0xfa, 0xc1, 0x41,
- 0xf0, 0x87, 0x70, 0x76, 0x0a, 0xf2, 0xce, 0xba, 0xd8, 0xd3, 0x75, 0x6e,
- 0x56, 0x3c, 0xe8, 0xc1, 0x79, 0x06, 0x67, 0xc9, 0xaf, 0x76, 0xe8, 0xb3,
- 0x26, 0x05, 0x27, 0x9d, 0xa2, 0xfc, 0x03, 0xda, 0x75, 0xd9, 0x76, 0x4b,
- 0x23, 0xed, 0x91, 0xac, 0xa8, 0x8f, 0xa6, 0xc4, 0x47, 0x08, 0x4b, 0x38,
- 0xc2, 0xa7, 0x0f, 0x8a, 0xfe, 0x6b, 0xdf, 0xda, 0x74, 0x56, 0x5b, 0x06,
- 0x66, 0x41, 0x43, 0xc0, 0x5b, 0xf0, 0xe4, 0xb3, 0x60, 0xc9, 0xd7, 0xad,
- 0xfc, 0x23, 0x6c, 0x23, 0x1c, 0x74, 0xa2, 0x8f, 0x34, 0xac, 0x74, 0x04,
- 0xf6, 0x15, 0xd1, 0x14, 0xc9, 0x46, 0x0b, 0x71, 0x7c, 0xda, 0x39, 0x08,
- 0x0f, 0xbb, 0xf7, 0x60, 0xf7, 0x1e, 0x7c, 0x82, 0x07, 0x9b, 0xf7, 0xe8,
- 0x27, 0x52, 0xf2, 0xea, 0x10, 0xfc, 0xda, 0x86, 0x5f, 0x41, 0x1b, 0x43,
- 0x5f, 0x17, 0x03, 0x7e, 0x65, 0xba, 0xaa, 0xc3, 0x76, 0x61, 0x43, 0x4b,
- 0x9c, 0xb3, 0xf0, 0xcc, 0xe3, 0x69, 0xc3, 0x8f, 0x52, 0xaf, 0x22, 0xff,
- 0x49, 0x3f, 0x93, 0x84, 0x4f, 0xa1, 0xaf, 0xa1, 0x2f, 0x21, 0xac, 0xef,
- 0xe7, 0x1d, 0xae, 0xf5, 0x65, 0xdc, 0xa1, 0x1d, 0x75, 0x88, 0x1e, 0x2f,
- 0x6a, 0x47, 0x87, 0x60, 0x63, 0x37, 0xb6, 0x80, 0x56, 0xda, 0xda, 0x75,
- 0x74, 0x15, 0x68, 0xbf, 0xe8, 0x0c, 0xfe, 0x5d, 0xde, 0x36, 0xc0, 0x28,
- 0xa1, 0x76, 0x05, 0xe3, 0xb6, 0xd0, 0x9f, 0xf0, 0x7d, 0x3a, 0x95, 0x95,
- 0xdd, 0xe1, 0x98, 0xfd, 0x75, 0x7a, 0x1d, 0xfd, 0x96, 0x98, 0x0c, 0x9c,
- 0x09, 0xfc, 0xe0, 0xc0, 0x82, 0x25, 0xf6, 0x99, 0x80, 0xc6, 0x81, 0x73,
- 0x91, 0x3f, 0x6c, 0x01, 0x3e, 0xd0, 0xe7, 0x6d, 0xc4, 0x09, 0x91, 0xf7,
- 0x34, 0x98, 0x0a, 0xe6, 0xb6, 0xf2, 0x82, 0x3e, 0x98, 0xf6, 0x66, 0x35,
- 0xda, 0xdb, 0x01, 0xd8, 0x9b, 0xd3, 0x2a, 0x69, 0xe7, 0xef, 0x60, 0x6f,
- 0x4f, 0x39, 0x1a, 0x78, 0x23, 0x72, 0xa1, 0xdc, 0x01, 0x5b, 0x37, 0x93,
- 0xef, 0xc8, 0x9e, 0xd4, 0xb4, 0x68, 0x72, 0x9a, 0x73, 0x35, 0xcc, 0x29,
- 0xff, 0x1b, 0xd8, 0xf7, 0x45, 0xe3, 0x69, 0xd0, 0xe5, 0xfb, 0xd3, 0xc0,
- 0x59, 0xd8, 0x6f, 0x84, 0xb6, 0x15, 0xcd, 0xa7, 0x10, 0xf3, 0xdc, 0xcf,
- 0x19, 0x52, 0x1c, 0x6e, 0x91, 0xf4, 0xf0, 0x02, 0x70, 0x4f, 0x3a, 0x81,
- 0x1d, 0x53, 0xd7, 0x17, 0x81, 0x7f, 0xc6, 0x1b, 0x82, 0x1e, 0xd3, 0x0e,
- 0x40, 0x17, 0xf0, 0x2f, 0x02, 0xff, 0x4c, 0xbd, 0x45, 0xbe, 0x69, 0x46,
- 0xb1, 0x34, 0x3a, 0x4f, 0x1b, 0xc0, 0xa2, 0x7d, 0x4f, 0xc8, 0x17, 0xbd,
- 0xb8, 0xe6, 0x3e, 0x4b, 0x3f, 0x5b, 0x1a, 0x86, 0x9d, 0x68, 0x25, 0x87,
- 0x7b, 0x1b, 0xb2, 0xb8, 0x0e, 0x23, 0xd9, 0x52, 0x60, 0x83, 0x59, 0x77,
- 0xa8, 0x98, 0x34, 0x94, 0x2f, 0x11, 0x39, 0x5c, 0x36, 0x01, 0xc3, 0x31,
- 0xe7, 0x83, 0xb9, 0xb1, 0x72, 0x1f, 0x7c, 0x23, 0xc7, 0x57, 0xfd, 0x49,
- 0x27, 0x98, 0xfb, 0xdd, 0x72, 0x81, 0x32, 0x62, 0xdc, 0x4e, 0x95, 0x9c,
- 0x7f, 0xf7, 0xa1, 0xbf, 0x9b, 0xd6, 0x5c, 0x1b, 0x4f, 0x7a, 0x2c, 0x8c,
- 0xf5, 0xda, 0x11, 0x5b, 0xef, 0x6b, 0x0d, 0x7d, 0xd8, 0x11, 0x4c, 0x1e,
- 0x2a, 0x97, 0x7a, 0x5b, 0xe5, 0xaa, 0xc1, 0xd8, 0x79, 0x09, 0x46, 0xed,
- 0x96, 0xf7, 0x82, 0x1f, 0xa5, 0x9e, 0x86, 0xb9, 0x58, 0xbe, 0xec, 0xcb,
- 0x9a, 0x13, 0xac, 0xc1, 0xb8, 0x23, 0x57, 0xd6, 0xfb, 0x62, 0xb2, 0x3e,
- 0xb6, 0xb8, 0x66, 0x49, 0xf6, 0x0e, 0x2f, 0x8a, 0x5a, 0xdb, 0x1b, 0xdb,
- 0x58, 0x9b, 0xc8, 0x97, 0x4b, 0x3d, 0x0d, 0xe3, 0x64, 0x0e, 0xb8, 0xf4,
- 0x03, 0xeb, 0x6b, 0xfb, 0x37, 0xd6, 0xee, 0x90, 0x54, 0x0f, 0xd7, 0xeb,
- 0x7d, 0x6d, 0x1b, 0xb8, 0x53, 0x21, 0x3d, 0xbd, 0x6d, 0x1b, 0x38, 0x6c,
- 0xe2, 0x6c, 0x18, 0x0f, 0x13, 0xe7, 0xc0, 0x06, 0xce, 0xfd, 0x9b, 0xe9,
- 0x39, 0x21, 0xf0, 0x41, 0xb1, 0xd6, 0x8c, 0x1c, 0xb8, 0x50, 0x1e, 0x1c,
- 0xff, 0xa2, 0x20, 0xe6, 0xed, 0xdf, 0x16, 0xfa, 0x64, 0xf3, 0x80, 0x0b,
- 0x5e, 0x99, 0x42, 0x1f, 0xa7, 0x49, 0x09, 0x72, 0x7e, 0xa8, 0x26, 0x07,
- 0xd6, 0x6a, 0x12, 0xea, 0x12, 0x75, 0xe2, 0x32, 0x6c, 0x4c, 0x8a, 0xbb,
- 0x32, 0x1d, 0x13, 0x66, 0xc6, 0x82, 0xad, 0xc9, 0x78, 0x09, 0x3e, 0xd9,
- 0xc8, 0xec, 0x79, 0x3b, 0x67, 0x3c, 0xe9, 0x1b, 0x88, 0xdb, 0x39, 0xe9,
- 0x38, 0xe8, 0x8e, 0x62, 0xbe, 0x46, 0xdb, 0x82, 0x5f, 0xa9, 0x13, 0xf7,
- 0x7c, 0xb7, 0x74, 0x21, 0x2e, 0xd6, 0x5e, 0xda, 0x11, 0xd8, 0x8e, 0x98,
- 0x26, 0x7c, 0xed, 0xcc, 0x28, 0xe3, 0x78, 0x6b, 0x0c, 0xf0, 0x13, 0x46,
- 0x66, 0x6c, 0xe7, 0xf1, 0xda, 0x9d, 0x3b, 0x0b, 0xb5, 0xe2, 0xce, 0x42,
- 0xd9, 0xa2, 0x9d, 0xe8, 0xee, 0x28, 0xfa, 0x2a, 0x57, 0x4a, 0xc2, 0x26,
- 0x2e, 0xab, 0x3c, 0xe2, 0xb5, 0x7a, 0x1d, 0xf6, 0x47, 0xfb, 0x16, 0x19,
- 0xf7, 0xb0, 0xc7, 0xc8, 0x87, 0x90, 0x3b, 0x68, 0x83, 0x4f, 0xcb, 0xe2,
- 0xd4, 0xfa, 0xc8, 0xbf, 0x85, 0xf6, 0xc9, 0xfe, 0xfb, 0x7e, 0xe0, 0xef,
- 0xef, 0xe8, 0x0e, 0xe6, 0xde, 0x0a, 0x6d, 0x3a, 0xc2, 0x45, 0x3c, 0xc3,
- 0xda, 0x38, 0x72, 0x92, 0xf1, 0xba, 0xa9, 0xd1, 0x3f, 0xe7, 0x3c, 0xe6,
- 0x12, 0xcc, 0x23, 0xa6, 0x43, 0x3f, 0x27, 0xd9, 0x1c, 0xfc, 0x88, 0x8e,
- 0xdc, 0xa2, 0x00, 0xbb, 0x31, 0x33, 0x57, 0x64, 0x46, 0xf9, 0x48, 0x89,
- 0xb5, 0x64, 0x9e, 0x00, 0xcc, 0x7f, 0xc0, 0xe6, 0xda, 0xba, 0x43, 0x3d,
- 0x0c, 0x7d, 0xbc, 0xf2, 0xbb, 0x80, 0xbd, 0xbc, 0x05, 0xf6, 0xdd, 0x46,
- 0x58, 0xbc, 0xbf, 0xb8, 0xe5, 0xfd, 0x4f, 0x69, 0xbf, 0x78, 0xb7, 0x0a,
- 0x7f, 0xda, 0x1a, 0xda, 0xfe, 0x05, 0x29, 0xc0, 0xb7, 0x9a, 0x36, 0x73,
- 0xc7, 0xdb, 0xb0, 0x16, 0xe3, 0x1a, 0x68, 0x84, 0xbf, 0x40, 0xcc, 0x04,
- 0xbf, 0x11, 0x13, 0x12, 0x37, 0x30, 0x3f, 0xa2, 0x9f, 0x00, 0x2c, 0xfd,
- 0x2f, 0x61, 0x5f, 0xe9, 0x20, 0xcf, 0x0b, 0x35, 0xae, 0xa1, 0xaf, 0x12,
- 0xdf, 0x1d, 0x6d, 0x83, 0x46, 0xf9, 0xaf, 0x19, 0x76, 0x04, 0x1b, 0xe1,
- 0xdd, 0x0a, 0xcb, 0x7c, 0x85, 0xb8, 0xbb, 0xc3, 0x3c, 0x60, 0x4c, 0xb2,
- 0xf5, 0x2c, 0x7e, 0x45, 0x99, 0x7c, 0x16, 0xb9, 0x98, 0xdd, 0x42, 0x5e,
- 0x90, 0x35, 0x56, 0xc0, 0xa3, 0x68, 0xdd, 0x13, 0xbd, 0x9b, 0xc7, 0xf7,
- 0xc5, 0x37, 0x7c, 0x25, 0x2d, 0x4d, 0xb2, 0x88, 0x15, 0xe0, 0x71, 0x6a,
- 0x42, 0xcf, 0x24, 0x24, 0x57, 0x0b, 0xf8, 0x8b, 0x78, 0x0b, 0xff, 0xc8,
- 0x2e, 0x64, 0xb2, 0xee, 0x07, 0x23, 0x99, 0x53, 0xcf, 0xb2, 0x90, 0x4d,
- 0x0a, 0xba, 0x34, 0x86, 0xb5, 0x72, 0x02, 0x38, 0x18, 0x87, 0x1d, 0x3d,
- 0x13, 0x97, 0x82, 0xc5, 0x7c, 0x41, 0xe5, 0x7a, 0x59, 0xfa, 0x01, 0x3d,
- 0xd3, 0x86, 0x39, 0xf6, 0x1f, 0xee, 0x0e, 0x64, 0xdd, 0xc9, 0xf1, 0xb8,
- 0x9e, 0xe9, 0xde, 0x32, 0xff, 0x7a, 0x67, 0x40, 0x9b, 0x1a, 0x63, 0xfe,
- 0x5f, 0xb6, 0x8c, 0xbf, 0x1e, 0xdf, 0x3c, 0x7e, 0x60, 0x67, 0xa4, 0x0f,
- 0x7a, 0xe6, 0x89, 0x90, 0x5e, 0xea, 0xe9, 0x56, 0x5a, 0x7f, 0x13, 0x7d,
- 0x79, 0x0e, 0x38, 0x95, 0x8e, 0xff, 0x06, 0xfa, 0xb2, 0x0e, 0xfb, 0x09,
- 0xfa, 0xd2, 0x48, 0xc3, 0x7a, 0x5d, 0x51, 0xd1, 0x91, 0x93, 0xba, 0xa3,
- 0x7b, 0x90, 0x77, 0xa4, 0x24, 0x5f, 0x07, 0xef, 0xd6, 0xe3, 0xea, 0x3a,
- 0x4c, 0x71, 0x03, 0x26, 0x88, 0x3b, 0xf9, 0xba, 0x8f, 0x3c, 0xae, 0x31,
- 0x06, 0x0f, 0xa3, 0x5f, 0xc4, 0x59, 0x57, 0x64, 0xd2, 0x5b, 0xcb, 0xea,
- 0xf6, 0xa9, 0x20, 0x0f, 0xb5, 0xbf, 0xad, 0xe5, 0x17, 0x99, 0xa3, 0xc6,
- 0xd0, 0x57, 0xf5, 0x07, 0x62, 0xdc, 0x33, 0x5a, 0x76, 0x79, 0x0e, 0xf9,
- 0xe9, 0x12, 0x7e, 0x67, 0xf1, 0xab, 0xe1, 0x17, 0xd5, 0x01, 0x2f, 0xa0,
- 0x8e, 0x50, 0xfe, 0x1e, 0xb1, 0x29, 0xd8, 0xff, 0x67, 0x4b, 0xc8, 0x8f,
- 0xe7, 0x12, 0xf2, 0x94, 0xad, 0xf7, 0xea, 0x81, 0x8f, 0xcb, 0x22, 0xb7,
- 0xb6, 0x2e, 0xcb, 0x97, 0xc2, 0x1c, 0x4d, 0xe4, 0x9d, 0x0a, 0x64, 0xb9,
- 0xff, 0x48, 0xe8, 0x9f, 0xbe, 0xf6, 0xa0, 0xab, 0x7c, 0x79, 0x98, 0x83,
- 0xc1, 0xef, 0x64, 0x15, 0xd4, 0x1b, 0xe0, 0x8f, 0x26, 0xef, 0x41, 0x8f,
- 0xdf, 0xa9, 0xb4, 0x83, 0x1e, 0x5b, 0x0a, 0xc7, 0x90, 0xbb, 0x68, 0x83,
- 0xd6, 0x36, 0xad, 0x1d, 0x79, 0x18, 0xfc, 0x8e, 0x1a, 0x93, 0x67, 0x17,
- 0xa7, 0x16, 0xca, 0x3a, 0x60, 0xc1, 0xf3, 0x51, 0xf4, 0xa1, 0x7f, 0x97,
- 0x2a, 0x5c, 0xa7, 0xcb, 0xbb, 0x15, 0x43, 0x7e, 0x8e, 0xbc, 0xee, 0x3d,
- 0xfb, 0xe2, 0x14, 0x6c, 0xb0, 0x0f, 0xf1, 0x0a, 0xb5, 0xd0, 0x1e, 0xc6,
- 0x8c, 0x01, 0x13, 0xcf, 0x3c, 0x7e, 0x87, 0x91, 0xe7, 0x5d, 0x7b, 0xcd,
- 0x27, 0xc1, 0x93, 0xb6, 0x18, 0xd6, 0x10, 0xde, 0x04, 0x6d, 0x5d, 0xd0,
- 0xc1, 0xb4, 0x35, 0x21, 0xdd, 0x96, 0xca, 0x9d, 0x34, 0xce, 0x07, 0x7e,
- 0xf2, 0xe3, 0xf3, 0xe4, 0xb3, 0x01, 0x1d, 0xe2, 0x98, 0xef, 0xe8, 0xcf,
- 0x89, 0x2f, 0x7d, 0x30, 0x8b, 0xc3, 0x5c, 0xaa, 0x04, 0xfd, 0x68, 0x4e,
- 0xb4, 0x28, 0xa6, 0xd2, 0x4f, 0xe7, 0x61, 0xab, 0x1c, 0x8f, 0x8b, 0x92,
- 0xc1, 0x26, 0x79, 0x52, 0x8f, 0x56, 0xa7, 0x66, 0x6c, 0xca, 0xd5, 0x92,
- 0xe9, 0x72, 0x24, 0x57, 0xca, 0x08, 0x75, 0x66, 0xe5, 0xdb, 0x90, 0xab,
- 0x1e, 0xd6, 0x20, 0xf0, 0x03, 0x73, 0x94, 0x2f, 0xea, 0xc4, 0x0a, 0xf2,
- 0xb0, 0x8a, 0xc4, 0x83, 0x1a, 0xea, 0x19, 0xd4, 0x1d, 0x90, 0x5f, 0x79,
- 0x0e, 0x38, 0x12, 0x78, 0x2e, 0xe1, 0x99, 0xc4, 0xf3, 0x2c, 0x9e, 0xfd,
- 0x78, 0xd6, 0x68, 0x1f, 0x61, 0xde, 0xf3, 0x31, 0x7a, 0x60, 0x27, 0x79,
- 0xda, 0xb4, 0x7c, 0xaf, 0x9e, 0x91, 0xbf, 0xad, 0x1f, 0x94, 0xbf, 0xa9,
- 0x8f, 0xca, 0x5f, 0xd7, 0x1d, 0x79, 0xb9, 0xbe, 0x5f, 0xfe, 0xaa, 0x3e,
- 0xcc, 0x9a, 0x10, 0x39, 0x5c, 0x0a, 0xbe, 0xf9, 0xbc, 0x3c, 0xe8, 0xd5,
- 0xe1, 0x73, 0x28, 0xff, 0x8b, 0x53, 0xd9, 0xda, 0x75, 0x52, 0x78, 0xd6,
- 0x42, 0x9e, 0x69, 0xb0, 0x2e, 0x93, 0xc7, 0x9c, 0x3b, 0xe2, 0x94, 0xbd,
- 0x6e, 0xb3, 0x4e, 0x39, 0x49, 0x38, 0xd4, 0xbb, 0x1a, 0xf2, 0x97, 0x16,
- 0x99, 0x48, 0xa4, 0x57, 0x5c, 0x23, 0x19, 0xfa, 0xa3, 0x3b, 0x01, 0x87,
- 0x3d, 0xbd, 0x0e, 0x59, 0x7b, 0x1e, 0xb6, 0xe0, 0xa0, 0x56, 0x4e, 0xc4,
- 0xe0, 0xfb, 0x54, 0x7e, 0xa2, 0x7c, 0x4b, 0xe0, 0x4b, 0xa3, 0x9a, 0x91,
- 0x73, 0xd9, 0x70, 0x8e, 0xf1, 0xd1, 0x02, 0xec, 0x72, 0x18, 0x43, 0xb6,
- 0xe2, 0xa4, 0x6f, 0x3c, 0x16, 0xfa, 0xc7, 0x15, 0x39, 0xe1, 0x0d, 0x66,
- 0xaf, 0x20, 0xf6, 0x68, 0x2d, 0x51, 0x5e, 0xb4, 0x0b, 0xb4, 0xf9, 0xfe,
- 0xdd, 0xac, 0xbf, 0xe3, 0xa6, 0xfc, 0x70, 0x36, 0x6d, 0x3d, 0xa2, 0xcf,
- 0x40, 0xce, 0xbe, 0x7f, 0xd4, 0x4e, 0x9f, 0x9a, 0xd0, 0x3b, 0xe5, 0x27,
- 0xcf, 0x30, 0x26, 0xaf, 0x4e, 0x7d, 0x1f, 0x7a, 0x50, 0x5d, 0x6a, 0x95,
- 0x6a, 0xd5, 0x94, 0x4b, 0x23, 0x83, 0x6a, 0xdf, 0x6a, 0x2d, 0x8e, 0x3c,
- 0xaf, 0x4d, 0xa6, 0xfb, 0x94, 0xb2, 0xc3, 0x6f, 0x0f, 0x2b, 0xbf, 0xed,
- 0xda, 0x78, 0xd6, 0x92, 0xd6, 0x66, 0x5a, 0x5e, 0x96, 0x82, 0x07, 0x1d,
- 0x8b, 0xef, 0x02, 0x4f, 0xd8, 0x1f, 0xb4, 0x0a, 0x3a, 0x62, 0xa0, 0x39,
- 0x68, 0x3d, 0xa8, 0xff, 0xd2, 0xff, 0x1d, 0x93, 0x7c, 0x7c, 0x1b, 0xb1,
- 0x85, 0xb1, 0x52, 0x53, 0x7a, 0xb7, 0xb0, 0xf4, 0x53, 0x8b, 0xfe, 0x65,
- 0xa5, 0xb6, 0x2b, 0x1c, 0xd3, 0xbf, 0x73, 0xdc, 0x2e, 0x2f, 0x57, 0xb7,
- 0xcb, 0x62, 0x95, 0xef, 0x5b, 0x65, 0xa1, 0x3a, 0x78, 0xa5, 0x57, 0xef,
- 0x93, 0xd5, 0xeb, 0x6e, 0xb4, 0xee, 0xd7, 0xc1, 0x93, 0x63, 0x1f, 0xc9,
- 0x07, 0x23, 0xdd, 0xf2, 0xd6, 0x7d, 0xe9, 0x17, 0xfe, 0x44, 0x87, 0x3e,
- 0x8e, 0x74, 0xd0, 0xce, 0xd0, 0xe7, 0x7c, 0xfa, 0x4a, 0x56, 0xa7, 0x9e,
- 0xfd, 0x00, 0xfa, 0x95, 0xae, 0x04, 0x3a, 0x49, 0xdc, 0xc4, 0x0b, 0xf9,
- 0xd8, 0x6f, 0x00, 0x27, 0xde, 0xd5, 0x06, 0x81, 0xeb, 0x0d, 0xc5, 0x8b,
- 0xbb, 0x9d, 0xf4, 0x15, 0x84, 0x28, 0xff, 0x92, 0x3d, 0x38, 0x3c, 0xa0,
- 0xef, 0x92, 0x6a, 0xf2, 0x46, 0xeb, 0xbb, 0x88, 0x07, 0xd9, 0x44, 0xfa,
- 0xd4, 0x45, 0x59, 0x9d, 0xba, 0x60, 0x53, 0x17, 0x69, 0xc3, 0xff, 0x80,
- 0x9c, 0xd4, 0x92, 0x4a, 0x8d, 0xbe, 0x8b, 0xb8, 0x58, 0x17, 0xec, 0xb5,
- 0x4e, 0x80, 0x06, 0x77, 0x3f, 0xde, 0x61, 0xde, 0xf8, 0x3c, 0xe5, 0xd6,
- 0xc2, 0xb5, 0xc3, 0x59, 0xbd, 0x7f, 0x0b, 0x8f, 0x06, 0xad, 0x43, 0x3a,
- 0xf7, 0xfb, 0x2f, 0xec, 0xfb, 0x3e, 0x68, 0x1d, 0xc4, 0x5a, 0xc4, 0xd0,
- 0x64, 0xe3, 0x1e, 0x3f, 0x52, 0x7b, 0x3c, 0x5b, 0x43, 0x0e, 0xb8, 0xbe,
- 0x07, 0xe6, 0x6a, 0x3a, 0xce, 0x69, 0x2a, 0xb9, 0x5c, 0x1a, 0x21, 0x7f,
- 0x6f, 0xef, 0x61, 0x2c, 0x37, 0x32, 0x2f, 0x85, 0x79, 0x46, 0x4c, 0x7e,
- 0x8c, 0xba, 0x6b, 0x12, 0xfe, 0x7f, 0x61, 0xef, 0x20, 0x68, 0x40, 0x7d,
- 0x9a, 0x54, 0xf1, 0x7c, 0xca, 0x05, 0x8e, 0x9c, 0xc2, 0xfd, 0xa6, 0x2c,
- 0x01, 0xf7, 0x38, 0xf9, 0x00, 0xdc, 0x33, 0x9c, 0x57, 0x32, 0xc0, 0x7c,
- 0x2d, 0x05, 0xbc, 0xbd, 0xa1, 0xff, 0x8b, 0x43, 0x57, 0xf7, 0x59, 0x77,
- 0x4b, 0x2c, 0xf4, 0x7f, 0x71, 0x79, 0xeb, 0x79, 0xe8, 0x7d, 0x9c, 0xfa,
- 0x93, 0xe8, 0xd9, 0xd0, 0x9f, 0x46, 0xfc, 0xad, 0x92, 0xaf, 0xc4, 0x80,
- 0x17, 0x39, 0xf7, 0x28, 0xf1, 0x62, 0x5c, 0xa5, 0x2e, 0x17, 0x43, 0x5d,
- 0xee, 0x08, 0x71, 0xaf, 0x41, 0x97, 0xd3, 0xa9, 0x55, 0x9d, 0xf5, 0xd5,
- 0x4e, 0x55, 0xf3, 0x1a, 0xb0, 0xaf, 0x42, 0x99, 0xb1, 0x88, 0xb6, 0x75,
- 0x71, 0x6a, 0x12, 0x35, 0x6c, 0xa1, 0x7c, 0x50, 0x2f, 0xd4, 0x47, 0xf5,
- 0x82, 0x47, 0x7d, 0xdb, 0x6b, 0x2d, 0x28, 0x1e, 0x27, 0x65, 0xa1, 0xfe,
- 0x81, 0x5f, 0xda, 0xbb, 0x0d, 0x7d, 0xe8, 0xfe, 0x38, 0xe5, 0x7b, 0x3d,
- 0xe9, 0x42, 0x50, 0x27, 0xbf, 0x13, 0x72, 0x66, 0xe8, 0x7b, 0xdd, 0xcc,
- 0xd1, 0x96, 0x87, 0x88, 0x1f, 0x74, 0x24, 0x12, 0xb2, 0xe8, 0x71, 0x8f,
- 0xd5, 0x29, 0xf2, 0xb2, 0x30, 0x67, 0xc9, 0x09, 0x25, 0x3f, 0x9e, 0x9b,
- 0xf7, 0x47, 0x86, 0x4c, 0xc6, 0x07, 0xad, 0x47, 0x25, 0x7d, 0x65, 0xcd,
- 0x48, 0xbf, 0x30, 0x81, 0xb8, 0xba, 0x30, 0x6f, 0x88, 0xab, 0xea, 0x30,
- 0xca, 0x28, 0x5d, 0x81, 0x35, 0x86, 0x67, 0xbf, 0xa7, 0xe1, 0xec, 0x5d,
- 0x72, 0xe1, 0xf9, 0xcf, 0xc3, 0xee, 0x5f, 0x81, 0x2c, 0xcc, 0xd4, 0x71,
- 0xe4, 0x19, 0xcf, 0xc9, 0xa0, 0x55, 0x42, 0xfe, 0x0c, 0xbe, 0xa3, 0xbd,
- 0xa2, 0x6c, 0x60, 0x41, 0xc7, 0xb8, 0x9f, 0x7c, 0xe2, 0x78, 0xb7, 0x2c,
- 0xf4, 0x05, 0x36, 0xce, 0x77, 0x03, 0xc0, 0x11, 0xbc, 0xe3, 0xf8, 0xb7,
- 0x64, 0x40, 0xbd, 0xab, 0xaa, 0x75, 0x25, 0xe9, 0x0d, 0xe5, 0xf7, 0x18,
- 0xf6, 0x24, 0x8f, 0xa3, 0xf9, 0x4e, 0x09, 0x6c, 0x29, 0xe2, 0xbb, 0x25,
- 0x47, 0x6b, 0x09, 0xb9, 0xa7, 0x96, 0x94, 0x2f, 0xd7, 0xfa, 0x25, 0x0f,
- 0x39, 0x4e, 0x8e, 0x3e, 0xd9, 0xc3, 0xb3, 0xe5, 0x96, 0xd2, 0x2f, 0x88,
- 0x4e, 0x5a, 0xab, 0x72, 0xdc, 0x8b, 0xe8, 0xe9, 0x08, 0xe9, 0x33, 0xc3,
- 0x71, 0x2c, 0xa4, 0xa1, 0x11, 0x5f, 0x07, 0x70, 0x65, 0x81, 0xe7, 0xa5,
- 0x10, 0x0f, 0xfd, 0x08, 0x68, 0x3d, 0x96, 0x94, 0x25, 0x8f, 0x74, 0x6c,
- 0x97, 0x52, 0x82, 0xfd, 0x57, 0xa0, 0x6f, 0xc4, 0xb3, 0x8d, 0xf9, 0xcd,
- 0x26, 0x1e, 0x3f, 0x5c, 0x2b, 0x82, 0xc7, 0xe4, 0x2f, 0xe1, 0xe0, 0xaf,
- 0xbf, 0x40, 0xf9, 0xed, 0x43, 0x8e, 0x6f, 0x07, 0xba, 0x69, 0x6d, 0xec,
- 0x99, 0x9f, 0xeb, 0x82, 0xac, 0xb8, 0x6f, 0xbb, 0x1c, 0x83, 0xdd, 0xe7,
- 0xaa, 0xdc, 0xff, 0x18, 0xf4, 0xe8, 0x2d, 0xb5, 0x7f, 0x7e, 0xa9, 0x2f,
- 0x5c, 0xcf, 0xb5, 0x5d, 0x5b, 0xd6, 0xb6, 0xca, 0xa1, 0x8a, 0x75, 0x8d,
- 0xf5, 0xbf, 0x8f, 0xf5, 0xba, 0x9c, 0x1e, 0xe5, 0x7a, 0xe2, 0x01, 0x5c,
- 0x35, 0xf1, 0x29, 0x78, 0xe2, 0xaa, 0xde, 0xcf, 0x55, 0x5b, 0x25, 0x57,
- 0x89, 0x70, 0x11, 0xcf, 0x47, 0xa8, 0x87, 0xbf, 0xaa, 0x70, 0x4d, 0x2a,
- 0x5c, 0x78, 0x5f, 0xa5, 0xcf, 0xb9, 0x15, 0xeb, 0x3b, 0xe8, 0xff, 0xa5,
- 0x14, 0xef, 0x94, 0x92, 0xaa, 0xe9, 0xdb, 0x95, 0xaf, 0x29, 0xc5, 0xdb,
- 0xf0, 0xbe, 0x13, 0x36, 0xbf, 0x0f, 0xb9, 0x45, 0x17, 0xeb, 0xdc, 0x2d,
- 0x73, 0x5b, 0xe9, 0x8f, 0x6d, 0xa1, 0x3f, 0x06, 0xb8, 0x5e, 0xec, 0x19,
- 0xc0, 0xe5, 0x01, 0x37, 0x3d, 0x07, 0x3e, 0x3b, 0xf4, 0x2b, 0x8c, 0x93,
- 0xd7, 0x29, 0x5a, 0xa6, 0x97, 0xfe, 0x1b, 0xe7, 0xea, 0xc3, 0xda, 0x68,
- 0x1c, 0xf0, 0xe1, 0x69, 0xe0, 0x99, 0xab, 0xaa, 0xbb, 0x0b, 0xc8, 0x60,
- 0x7b, 0x9c, 0x67, 0x2f, 0x55, 0x3f, 0x8b, 0x67, 0xd7, 0x35, 0xf0, 0x8b,
- 0xbc, 0x22, 0xbd, 0xa4, 0x95, 0xf7, 0x48, 0xb0, 0x37, 0x07, 0x7a, 0x1c,
- 0x37, 0x24, 0x3f, 0x6a, 0x21, 0x3f, 0xe7, 0x3d, 0x2c, 0xed, 0xd2, 0xe2,
- 0xdd, 0x67, 0x4c, 0xb7, 0x19, 0x6b, 0x4d, 0x75, 0xf6, 0xe3, 0x4b, 0xbc,
- 0x8b, 0x4d, 0xf1, 0xee, 0x6e, 0x98, 0xd7, 0x18, 0x8f, 0x2c, 0xd9, 0xf2,
- 0x78, 0x6d, 0x58, 0x1e, 0xad, 0xa5, 0xad, 0xfb, 0xe1, 0x03, 0x0a, 0xeb,
- 0x77, 0xb4, 0x43, 0x71, 0xfa, 0x2f, 0x13, 0x79, 0x60, 0x8b, 0x1d, 0xe4,
- 0x05, 0x25, 0xd6, 0x6c, 0x73, 0x69, 0xde, 0xe3, 0x58, 0x55, 0xd9, 0x9a,
- 0x3b, 0xfc, 0x5f, 0xe6, 0x0d, 0xdc, 0x9f, 0xfe, 0x1a, 0x79, 0x82, 0x87,
- 0x3c, 0xc1, 0x43, 0x9e, 0xe0, 0x21, 0x4f, 0xf0, 0x90, 0x27, 0x78, 0xc8,
- 0x13, 0x3c, 0xe4, 0x09, 0x1e, 0xf2, 0x04, 0xc4, 0xee, 0xa0, 0x5e, 0x18,
- 0x43, 0xfe, 0x0b, 0xff, 0xe5, 0xdd, 0x06, 0x3e, 0xf1, 0xfe, 0x92, 0x31,
- 0x87, 0xb1, 0x99, 0x73, 0xab, 0xdb, 0x5c, 0xca, 0x4d, 0xf9, 0xbe, 0x3b,
- 0x31, 0x37, 0x1e, 0xe6, 0x23, 0x84, 0x89, 0x62, 0x37, 0xe1, 0xe4, 0xa0,
- 0xeb, 0x68, 0xb0, 0x31, 0xe6, 0x2b, 0x41, 0xcc, 0x0a, 0x72, 0xe5, 0xb7,
- 0x91, 0xb3, 0xa4, 0x90, 0xb3, 0xf4, 0x23, 0x3f, 0xe1, 0x9d, 0x75, 0x74,
- 0xc7, 0x94, 0xd5, 0x8e, 0x7a, 0x63, 0xda, 0x3d, 0x1e, 0x73, 0x69, 0x3b,
- 0x55, 0xd0, 0xf5, 0xb9, 0x5e, 0xf1, 0x25, 0x37, 0xf2, 0x4d, 0xe4, 0xad,
- 0xcf, 0xa9, 0xfb, 0xb4, 0xf1, 0x21, 0xca, 0xbc, 0xf2, 0x09, 0xb9, 0x6b,
- 0xc4, 0xdf, 0xe0, 0x1e, 0x50, 0x5f, 0x20, 0xff, 0x44, 0x7a, 0xce, 0x81,
- 0xe1, 0xe7, 0x62, 0x12, 0x3f, 0xb3, 0x1d, 0x73, 0x96, 0xf4, 0xaa, 0xbb,
- 0x24, 0x88, 0xf2, 0xdc, 0x55, 0xc8, 0xcb, 0x16, 0xfd, 0x1c, 0x6f, 0x1c,
- 0x88, 0x97, 0xfe, 0x75, 0x65, 0x2a, 0x57, 0x5d, 0x51, 0x3a, 0x75, 0xb4,
- 0x96, 0x47, 0x7d, 0xd4, 0xd3, 0x2b, 0xed, 0x26, 0x6a, 0xab, 0x08, 0x37,
- 0x71, 0xfe, 0x32, 0xae, 0x6a, 0x9e, 0x73, 0xeb, 0xf2, 0x84, 0xac, 0xb9,
- 0xcf, 0xca, 0x54, 0xa9, 0x92, 0x4e, 0xb2, 0x56, 0xce, 0x5a, 0x2b, 0x53,
- 0x27, 0x81, 0x63, 0x11, 0xb9, 0x81, 0xa1, 0xf6, 0x5e, 0x99, 0x9a, 0xae,
- 0x04, 0xf7, 0x59, 0x01, 0x0d, 0x8c, 0x57, 0xed, 0x62, 0x2c, 0x04, 0xf7,
- 0x5a, 0xba, 0x5a, 0xcb, 0x75, 0x5c, 0x6f, 0x62, 0x1d, 0xe5, 0x36, 0x8c,
- 0xb5, 0x94, 0x1d, 0x69, 0x58, 0x99, 0x2a, 0x56, 0x1b, 0x69, 0x20, 0x1e,
- 0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0xc4, 0x45, 0x3f, 0xe3, 0xfb, 0x85, 0x91,
- 0xfe, 0x30, 0xef, 0x3a, 0x89, 0xfc, 0xce, 0x0c, 0xf4, 0x5c, 0x8d, 0xbf,
- 0xa3, 0xe2, 0x54, 0x4a, 0xe7, 0x3c, 0x9f, 0x78, 0x37, 0xba, 0x80, 0x39,
- 0x8c, 0x17, 0x23, 0x58, 0x3d, 0x84, 0xed, 0x6c, 0xe0, 0x67, 0x4b, 0xb8,
- 0x1f, 0x69, 0xe2, 0x39, 0x2f, 0x61, 0x2f, 0xd2, 0x45, 0x98, 0x38, 0x68,
- 0x83, 0x2c, 0xbd, 0xff, 0x2d, 0xef, 0x1b, 0xcf, 0x44, 0x9e, 0x9a, 0x58,
- 0x43, 0x78, 0xe2, 0x88, 0xd6, 0xe0, 0xc5, 0xb9, 0x60, 0x9d, 0xbe, 0x7e,
- 0xff, 0xf7, 0x69, 0xfb, 0x36, 0xd2, 0x1a, 0xed, 0x1f, 0xe1, 0x19, 0x0e,
- 0xe4, 0xb6, 0xbe, 0x5e, 0xfd, 0x9f, 0x61, 0x78, 0x42, 0x17, 0x3f, 0x76,
- 0x8f, 0x3a, 0xdc, 0x50, 0x87, 0x46, 0xf7, 0x17, 0xbc, 0x0f, 0x60, 0x7d,
- 0xcf, 0x6f, 0x07, 0x8d, 0xb5, 0xe2, 0xcb, 0x61, 0x2c, 0xdb, 0x29, 0x59,
- 0x93, 0x75, 0xc3, 0xf9, 0x70, 0xbc, 0x03, 0xb1, 0x8d, 0xe3, 0x3a, 0xf8,
- 0x0b, 0x5d, 0x76, 0xda, 0xc3, 0xba, 0x25, 0x1e, 0x7c, 0xe3, 0x19, 0xa6,
- 0x1d, 0xb1, 0xee, 0x6b, 0x0b, 0xe7, 0x22, 0x3b, 0xa2, 0x1f, 0x36, 0xc3,
- 0x39, 0xfa, 0x5b, 0x1d, 0xb5, 0x0b, 0xfb, 0xc0, 0xb3, 0xd8, 0x68, 0x4b,
- 0xd1, 0x33, 0x2e, 0x67, 0xe7, 0x23, 0xbf, 0x05, 0x9f, 0x32, 0x64, 0x86,
- 0xbe, 0xbf, 0x03, 0xbe, 0xaf, 0x4b, 0x0e, 0xc1, 0x67, 0x1d, 0x86, 0xcf,
- 0x3a, 0x82, 0x7a, 0x71, 0x6c, 0xa9, 0xf1, 0x9e, 0x97, 0x35, 0x6a, 0x97,
- 0x76, 0x5c, 0xc9, 0xbf, 0xe8, 0x1b, 0xf6, 0x47, 0xd0, 0x01, 0xd6, 0x5d,
- 0x91, 0x4e, 0xc0, 0xdf, 0x3a, 0x71, 0xe8, 0xc4, 0xd6, 0xfb, 0xe4, 0x61,
- 0xd8, 0x46, 0x7b, 0x56, 0xc5, 0x86, 0xa5, 0x80, 0xf7, 0xa5, 0x6a, 0xc0,
- 0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5, 0x58, 0xb3, 0xa4, 0x88, 0x7d, 0x8b,
- 0xd8, 0xb7, 0x88, 0x3a, 0x6f, 0xba, 0xd6, 0xf8, 0x1d, 0xab, 0x33, 0xa4,
- 0x9d, 0x6b, 0xa3, 0xbe, 0xd5, 0x70, 0xfe, 0xe8, 0x79, 0x0a, 0xfc, 0x7f,
- 0x0c, 0xfc, 0x3f, 0x81, 0xfa, 0xe6, 0x8f, 0x50, 0xdf, 0x7c, 0x0d, 0xf5,
- 0xcd, 0x71, 0xd4, 0x37, 0x13, 0xa8, 0x6f, 0xbe, 0x0a, 0xff, 0xf1, 0x15,
- 0xf8, 0x8f, 0x63, 0xf0, 0x1f, 0xe3, 0xea, 0xee, 0xe9, 0xa8, 0xb7, 0xf5,
- 0x4e, 0x25, 0xda, 0x8b, 0xed, 0x67, 0x22, 0x76, 0x11, 0x67, 0x1a, 0x93,
- 0x6a, 0x9d, 0xf5, 0x8d, 0x23, 0xee, 0x41, 0xd6, 0x37, 0xc7, 0xb4, 0x09,
- 0xe4, 0xef, 0xf7, 0xef, 0x67, 0xdd, 0x13, 0xd7, 0x72, 0xaa, 0xee, 0x49,
- 0x9f, 0x77, 0x91, 0x22, 0x21, 0xf7, 0xc3, 0x99, 0xd3, 0x67, 0x73, 0xa0,
- 0x25, 0xc8, 0xf9, 0x7a, 0x42, 0xbf, 0xd7, 0x21, 0x8b, 0xb3, 0xa8, 0x19,
- 0xbc, 0x1f, 0x6b, 0x05, 0xe5, 0x1b, 0x2d, 0x8c, 0x51, 0x2b, 0x7b, 0xff,
- 0x1c, 0x8e, 0x47, 0x64, 0x72, 0x1e, 0xb5, 0xed, 0xf3, 0xff, 0xa8, 0xe5,
- 0xd4, 0xd8, 0xc1, 0x18, 0xf9, 0xee, 0xf3, 0x7f, 0x1f, 0x8e, 0x8b, 0xa1,
- 0x3e, 0x84, 0xb4, 0x5a, 0x0e, 0x9e, 0xdd, 0x61, 0xce, 0xf1, 0x6a, 0xef,
- 0xe6, 0xff, 0xd3, 0x8e, 0xad, 0x45, 0x13, 0xfb, 0x1b, 0x3b, 0x82, 0xfa,
- 0xac, 0x71, 0xbe, 0xab, 0x61, 0xfe, 0x8a, 0xfa, 0xce, 0x5a, 0x28, 0xb7,
- 0xfd, 0x0a, 0x1e, 0x58, 0x96, 0x86, 0x98, 0xe7, 0x7d, 0xe4, 0xf3, 0xfb,
- 0x9f, 0xab, 0xb7, 0xab, 0x6f, 0x72, 0xae, 0xca, 0xb7, 0x61, 0xe7, 0x23,
- 0xa5, 0x1d, 0x81, 0x2f, 0x60, 0x3f, 0xa1, 0x05, 0xfe, 0xfd, 0x8f, 0x81,
- 0x07, 0xbc, 0xf6, 0x1a, 0x6b, 0x38, 0x2b, 0xbc, 0x4b, 0xb9, 0x32, 0xc5,
- 0xdc, 0xba, 0xa4, 0x70, 0xb3, 0xd6, 0x63, 0xdd, 0x17, 0xc5, 0x80, 0x08,
- 0xd7, 0xcf, 0x13, 0x01, 0xdd, 0xe3, 0xa8, 0xe9, 0x08, 0x13, 0x8d, 0x1b,
- 0xeb, 0xbf, 0x8e, 0xf0, 0x1e, 0xee, 0x4a, 0x90, 0x57, 0x29, 0x7c, 0x66,
- 0x88, 0xef, 0x3f, 0xfd, 0xc0, 0xf7, 0x70, 0xbd, 0xd5, 0xb0, 0xfe, 0x3c,
- 0x72, 0x3d, 0xde, 0x99, 0xec, 0x52, 0xdf, 0x19, 0xdf, 0x9f, 0xed, 0x94,
- 0x5f, 0x3c, 0xe3, 0xfb, 0xe3, 0x4e, 0x7a, 0xf8, 0x4d, 0xd4, 0x1e, 0x67,
- 0x68, 0x27, 0x23, 0xa4, 0x73, 0x30, 0x35, 0x2d, 0x03, 0xbd, 0x41, 0x2e,
- 0xfe, 0x75, 0xed, 0xe3, 0x74, 0xeb, 0xe1, 0x3e, 0x3f, 0x6c, 0xd8, 0x27,
- 0xd5, 0xb0, 0xcf, 0x0a, 0x6d, 0xb6, 0x7a, 0x2f, 0xce, 0x5c, 0xdc, 0x75,
- 0xa3, 0x95, 0x08, 0xeb, 0xb2, 0x47, 0x47, 0xda, 0xa4, 0xd2, 0x97, 0x5e,
- 0xf9, 0x11, 0xf2, 0xf5, 0xc2, 0x08, 0xe6, 0x12, 0x83, 0x78, 0xc7, 0xf9,
- 0x74, 0x15, 0xb9, 0xe8, 0x4a, 0x55, 0x86, 0xb0, 0x3e, 0x5d, 0x14, 0xe1,
- 0x3c, 0xfb, 0x8a, 0xb6, 0x6a, 0xe8, 0x03, 0x92, 0x6b, 0x38, 0xf3, 0x04,
- 0xea, 0xaf, 0x13, 0xeb, 0xf5, 0x30, 0xf7, 0xb9, 0x59, 0x5b, 0x53, 0xb9,
- 0xf1, 0x01, 0xad, 0x98, 0x08, 0xce, 0xf8, 0x87, 0xf0, 0x17, 0x86, 0xce,
- 0xb5, 0xef, 0x03, 0xb7, 0x26, 0x0b, 0xcf, 0x18, 0xea, 0x0e, 0xb6, 0x30,
- 0x42, 0x59, 0xf3, 0x79, 0x2d, 0xde, 0x45, 0x67, 0xfa, 0xf3, 0xf0, 0x4c,
- 0xd9, 0xb0, 0x9e, 0x8e, 0xce, 0x14, 0x93, 0x77, 0x67, 0x2d, 0xac, 0xfd,
- 0x1c, 0xf8, 0x91, 0x97, 0xa5, 0x7a, 0xea, 0x33, 0xf0, 0x94, 0x1b, 0x78,
- 0x63, 0x6e, 0x91, 0x61, 0x71, 0xa3, 0x86, 0x1f, 0x4f, 0xc2, 0x0e, 0xbf,
- 0xd1, 0x1b, 0xdd, 0x0d, 0x1b, 0xb6, 0xcf, 0xba, 0x07, 0x8d, 0xf3, 0xfd,
- 0xb0, 0xc5, 0x14, 0xec, 0x93, 0x39, 0x53, 0x9e, 0xb5, 0x0a, 0xed, 0xc9,
- 0x72, 0x8d, 0xb4, 0x75, 0x4c, 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x19, 0x59,
- 0xac, 0x47, 0x34, 0x8c, 0xc2, 0x1e, 0x0f, 0xe2, 0xb7, 0x1f, 0xef, 0x1c,
- 0xfc, 0x58, 0x2b, 0xad, 0xc8, 0xe3, 0x2a, 0x17, 0x47, 0xae, 0x3d, 0x44,
- 0xfa, 0xee, 0x04, 0x3c, 0xf5, 0x99, 0x7a, 0x7a, 0xa7, 0xb8, 0x7d, 0xf4,
- 0x15, 0x49, 0xe0, 0xc6, 0x1a, 0xef, 0x22, 0x6c, 0xbd, 0x1f, 0xcf, 0xb4,
- 0x55, 0x20, 0x6f, 0x15, 0x7e, 0xdf, 0x37, 0x46, 0xf9, 0x8d, 0xe2, 0x7c,
- 0x38, 0x1e, 0xb4, 0xbe, 0x4c, 0xdd, 0x4b, 0xee, 0x96, 0x95, 0xf9, 0x28,
- 0x0e, 0x9e, 0x86, 0x0d, 0xf2, 0xce, 0x76, 0x0c, 0x7c, 0xe1, 0x58, 0x0b,
- 0xe3, 0x21, 0xe6, 0x17, 0x97, 0x71, 0xee, 0x8c, 0x9c, 0x41, 0xfd, 0x2f,
- 0x7d, 0x7c, 0xa6, 0x80, 0x7f, 0x7b, 0xa8, 0xef, 0x9b, 0xd7, 0x1b, 0x36,
- 0xfb, 0x63, 0xa0, 0xcf, 0x6c, 0x58, 0xcf, 0x35, 0x41, 0x7d, 0xb2, 0x26,
- 0x88, 0xc7, 0x49, 0xff, 0x76, 0x3d, 0xf3, 0xa2, 0x3c, 0xa0, 0xce, 0x54,
- 0x93, 0xe3, 0xf3, 0xbe, 0xef, 0x8e, 0x0e, 0x0e, 0x2f, 0x4a, 0x7a, 0xf8,
- 0xa4, 0xec, 0xb3, 0x0e, 0xb1, 0x1e, 0xb3, 0x88, 0xc7, 0xbf, 0xbd, 0x25,
- 0xe3, 0xfb, 0xa7, 0x41, 0xfb, 0xf7, 0xd5, 0x3e, 0x2f, 0x82, 0x7e, 0xf0,
- 0x4a, 0xd5, 0x24, 0xa4, 0x15, 0xcf, 0x04, 0xe9, 0x2d, 0xcb, 0xf1, 0xfa,
- 0x85, 0x50, 0x36, 0x8f, 0x89, 0xeb, 0x5d, 0x36, 0x5c, 0xbb, 0x0c, 0xd8,
- 0x85, 0x90, 0xb6, 0x0c, 0xe8, 0xc5, 0xfe, 0xf5, 0xb7, 0x13, 0xf4, 0x0d,
- 0x94, 0xb9, 0x8b, 0xac, 0xd1, 0x1d, 0x41, 0x1e, 0x95, 0xf8, 0x24, 0x3f,
- 0x10, 0x97, 0xcd, 0x7e, 0x80, 0xeb, 0xe2, 0xd7, 0xd0, 0x15, 0xd2, 0x51,
- 0x54, 0xfe, 0x53, 0xc5, 0x2d, 0x85, 0xcf, 0xd8, 0xe2, 0x0b, 0x2a, 0xea,
- 0xb9, 0x6a, 0xd0, 0x37, 0x31, 0xfe, 0x51, 0x87, 0xbb, 0xe0, 0xff, 0xa0,
- 0x83, 0xb0, 0xe3, 0xdc, 0x3c, 0xef, 0x27, 0x86, 0x78, 0xaf, 0x74, 0x36,
- 0x0f, 0xd9, 0x2e, 0xf0, 0xfb, 0x63, 0x22, 0xa8, 0x31, 0x83, 0xfa, 0x2b,
- 0x45, 0x5f, 0x88, 0xb6, 0xa4, 0xfc, 0x64, 0x5e, 0x7d, 0x6f, 0x8c, 0x03,
- 0xc6, 0xa7, 0xef, 0x6c, 0xf8, 0x9b, 0x89, 0x1f, 0x64, 0x83, 0xbf, 0x99,
- 0x08, 0xbf, 0xfd, 0x56, 0x83, 0x3c, 0xe2, 0xe1, 0x9a, 0x29, 0x13, 0xb5,
- 0xe8, 0x6f, 0x28, 0x28, 0x07, 0xf8, 0xe6, 0x5a, 0x94, 0x3b, 0xf8, 0x41,
- 0x4d, 0xb3, 0x49, 0x96, 0x4b, 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4,
- 0x78, 0x31, 0xaa, 0x2f, 0x07, 0x20, 0x3f, 0xf0, 0x1c, 0x74, 0xbd, 0x3b,
- 0x1b, 0xd4, 0xb9, 0x25, 0xfa, 0xc5, 0xfe, 0xa8, 0xee, 0xdd, 0x25, 0xa5,
- 0x63, 0x7c, 0x1f, 0x93, 0x77, 0x66, 0x63, 0xea, 0x7d, 0x41, 0x62, 0xe1,
- 0x7b, 0x8e, 0xe3, 0x52, 0x50, 0xef, 0xab, 0x21, 0x3e, 0xd4, 0x69, 0x5f,
- 0x89, 0xc6, 0xa6, 0x76, 0xbc, 0x1e, 0xac, 0x9b, 0xac, 0x57, 0xe5, 0xf1,
- 0xfa, 0x2a, 0xce, 0xaf, 0x49, 0x6e, 0xbc, 0x28, 0xbb, 0x6d, 0x4b, 0xc5,
- 0x7d, 0x37, 0x4e, 0x1d, 0xa3, 0x7e, 0x8d, 0xa9, 0xba, 0xb3, 0x88, 0x7c,
- 0xa1, 0x30, 0xc2, 0x6f, 0x3c, 0xbf, 0xba, 0xab, 0x50, 0x4e, 0x5b, 0x59,
- 0xf9, 0xd0, 0x77, 0x4d, 0x8e, 0x45, 0x47, 0x3d, 0x74, 0xd7, 0xc3, 0xb5,
- 0x0b, 0x77, 0x05, 0x67, 0xc5, 0xfb, 0x1a, 0x61, 0x0d, 0xf5, 0x6d, 0xf6,
- 0x5f, 0x6f, 0x35, 0x65, 0xed, 0x56, 0xdf, 0xbf, 0xdf, 0xb1, 0xc4, 0x0d,
- 0x6b, 0x57, 0x4b, 0xd5, 0xae, 0xed, 0x2a, 0x07, 0x71, 0x47, 0x52, 0x5a,
- 0x1e, 0xf6, 0x7a, 0xc6, 0x43, 0x9d, 0xa3, 0xa7, 0x0f, 0xae, 0xea, 0x16,
- 0x62, 0x6e, 0x3a, 0x35, 0x27, 0x6e, 0x2f, 0xbf, 0x37, 0xcf, 0x38, 0x84,
- 0xd9, 0x19, 0xdc, 0x75, 0xdd, 0x34, 0xae, 0xfc, 0xac, 0x48, 0x18, 0x7b,
- 0x6e, 0x6a, 0xb4, 0x89, 0xc6, 0xdc, 0x92, 0xb6, 0x20, 0x13, 0x26, 0x68,
- 0x29, 0x95, 0xa3, 0x3c, 0x8d, 0x7f, 0x1b, 0xb0, 0x7a, 0xd7, 0xd3, 0xa0,
- 0x73, 0x1a, 0x74, 0xf2, 0x1c, 0xd3, 0xb5, 0x48, 0xe7, 0xa2, 0x5a, 0x81,
- 0x7d, 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0x3d,
- 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0xbd, 0xf1,
- 0x30, 0x4f, 0x7b, 0x62, 0x3d, 0x4f, 0x5b, 0xa9, 0xf3, 0x3b, 0x94, 0xa2,
- 0xa5, 0x58, 0x94, 0x20, 0xcf, 0x15, 0x9d, 0x39, 0x4d, 0x94, 0xe7, 0x5e,
- 0xfb, 0x9b, 0x48, 0xb0, 0x8e, 0x39, 0x1e, 0xd7, 0x15, 0x35, 0xdd, 0xe6,
- 0xba, 0x20, 0xcf, 0x63, 0x6d, 0xb5, 0x79, 0x0d, 0xf2, 0xb5, 0x0c, 0xfd,
- 0x19, 0xed, 0x22, 0x11, 0xd4, 0x8b, 0x99, 0xf3, 0xf7, 0xba, 0x88, 0xbf,
- 0x85, 0x9a, 0x8a, 0xc1, 0xbc, 0x17, 0xbc, 0x97, 0x7f, 0xb7, 0x00, 0x39,
- 0xf0, 0xdd, 0x7d, 0xac, 0x27, 0x0a, 0xb5, 0xa4, 0x14, 0x17, 0xa3, 0xfc,
- 0x07, 0xeb, 0xbc, 0x7d, 0x5a, 0xbe, 0x42, 0xd9, 0xea, 0x32, 0x9d, 0x00,
- 0x53, 0xec, 0xc6, 0xbc, 0xee, 0x4d, 0x55, 0x23, 0xad, 0xd4, 0x49, 0xcf,
- 0x7e, 0xd0, 0x16, 0xdd, 0xe3, 0x8a, 0x18, 0xb3, 0x09, 0xd1, 0x67, 0x91,
- 0xd3, 0xda, 0x43, 0xea, 0x6f, 0x1d, 0x7a, 0xb0, 0x8f, 0x3e, 0x3b, 0x10,
- 0xfd, 0x2d, 0x06, 0xeb, 0xae, 0xec, 0xc6, 0xfd, 0x2b, 0xcf, 0x91, 0x80,
- 0xbd, 0x7e, 0x69, 0x27, 0xce, 0x06, 0xb9, 0x5e, 0xde, 0xa1, 0xf2, 0x6e,
- 0xf8, 0xce, 0xd3, 0x43, 0xe9, 0x3e, 0xe9, 0xda, 0x25, 0x67, 0x86, 0x58,
- 0xa3, 0xb5, 0x01, 0x1f, 0x61, 0x79, 0xe7, 0xb4, 0x4b, 0x96, 0xe7, 0xe1,
- 0x5b, 0xe7, 0xd3, 0x0e, 0xff, 0xbe, 0x60, 0x01, 0x21, 0x6d, 0xa1, 0x3e,
- 0xd6, 0xc7, 0x98, 0xbc, 0x58, 0xa7, 0xae, 0xf4, 0x60, 0x7d, 0x3f, 0x74,
- 0x71, 0x1b, 0x6c, 0x48, 0xc7, 0xfe, 0x11, 0xee, 0xf7, 0x14, 0xee, 0x1e,
- 0xfb, 0xb7, 0x77, 0x2a, 0xdd, 0xd0, 0xd3, 0x56, 0x4a, 0x07, 0xed, 0x1f,
- 0xab, 0x2d, 0x1d, 0xe1, 0xf7, 0xc2, 0x69, 0xaf, 0xf1, 0xbb, 0xe1, 0x3e,
- 0xad, 0x50, 0xe1, 0xdf, 0x38, 0x0c, 0xc9, 0x21, 0x8b, 0x7f, 0xff, 0xb3,
- 0x4f, 0x7b, 0xa0, 0x4a, 0x18, 0x1b, 0x7d, 0xd6, 0xe1, 0xcb, 0xb0, 0xe5,
- 0xff, 0x29, 0xdc, 0xea, 0x62, 0xdb, 0x3a, 0xcb, 0xf0, 0xfb, 0x1d, 0xe7,
- 0xc7, 0x4d, 0xdd, 0xe4, 0x34, 0x71, 0x12, 0x27, 0xca, 0xc0, 0xc7, 0x39,
- 0x49, 0x3d, 0x39, 0xd5, 0x4e, 0xa2, 0x14, 0x22, 0x88, 0x84, 0xe5, 0xfc,
- 0xcc, 0x63, 0x14, 0x3c, 0xc8, 0xa6, 0x4e, 0x42, 0x55, 0x94, 0x74, 0x5b,
- 0x27, 0xee, 0xb8, 0x40, 0x5c, 0x80, 0x6a, 0x39, 0x69, 0xe9, 0x86, 0x3d,
- 0xa7, 0x5b, 0xba, 0x00, 0x57, 0x9e, 0xe3, 0xa4, 0x4d, 0xe7, 0xcc, 0x1a,
- 0x03, 0x69, 0x70, 0x41, 0x23, 0x33, 0x6d, 0xe3, 0x66, 0x37, 0x48, 0x5c,
- 0x57, 0x29, 0x83, 0x02, 0x6b, 0x2b, 0xb8, 0xe1, 0xef, 0xe2, 0xf0, 0x3c,
- 0xdf, 0x39, 0x76, 0xd3, 0xc0, 0x44, 0x24, 0xeb, 0x7c, 0xe7, 0x3b, 0xdf,
- 0xff, 0xf7, 0xbe, 0xcf, 0xfb, 0x9b, 0x6e, 0xb9, 0x08, 0x3a, 0xce, 0x8d,
- 0xb5, 0xfa, 0xfe, 0xd6, 0x0e, 0x9f, 0x87, 0x07, 0xfb, 0x7c, 0x19, 0xa5,
- 0x75, 0xc9, 0x9c, 0xd6, 0xa7, 0xbb, 0x0e, 0x7d, 0x7b, 0x16, 0x6b, 0x8a,
- 0xe0, 0x1c, 0x1e, 0xe9, 0xd3, 0x78, 0x64, 0xf0, 0xbd, 0xff, 0xd0, 0x7b,
- 0xdf, 0xa1, 0xf7, 0xde, 0xff, 0xd1, 0x9e, 0xe5, 0xc3, 0xf4, 0xc0, 0x75,
- 0x5a, 0x53, 0x1a, 0xfd, 0xf2, 0x93, 0x6a, 0x39, 0x6f, 0x25, 0xa9, 0x0b,
- 0xcc, 0x88, 0xab, 0x66, 0x9c, 0x36, 0x60, 0x5c, 0x9b, 0xac, 0xae, 0x83,
- 0xe6, 0xb1, 0x8f, 0x76, 0x9b, 0xf1, 0xf2, 0x89, 0x3e, 0xf2, 0x4c, 0x10,
- 0xd7, 0x60, 0xd8, 0xc3, 0x11, 0xb4, 0x73, 0x5f, 0x74, 0x12, 0xe6, 0x39,
- 0xed, 0xbf, 0xa1, 0x0e, 0xe3, 0xaa, 0x9c, 0xce, 0xfd, 0x60, 0x9b, 0x16,
- 0xb9, 0x6d, 0xa7, 0xba, 0xfd, 0xdc, 0x20, 0xd8, 0xbb, 0xa9, 0x3e, 0xea,
- 0x17, 0x2f, 0x38, 0xcd, 0x3a, 0x73, 0x5f, 0x98, 0x77, 0x05, 0xa2, 0x79,
- 0x4a, 0xa4, 0x54, 0x11, 0xb9, 0x86, 0xdf, 0x6f, 0x2a, 0x7e, 0xfc, 0x42,
- 0xd1, 0xd6, 0x9e, 0x96, 0x1b, 0xc5, 0x2f, 0x48, 0x15, 0x32, 0x67, 0xc7,
- 0x71, 0xdd, 0x3b, 0x4e, 0x54, 0x9f, 0xf9, 0x0f, 0xf2, 0x4a, 0x62, 0xe3,
- 0x94, 0x69, 0x6d, 0xf2, 0xc3, 0x75, 0xe6, 0xd5, 0x59, 0xe6, 0x1d, 0x61,
- 0x7e, 0x5b, 0x44, 0xd2, 0xe1, 0x80, 0xd6, 0x4b, 0xe5, 0x69, 0x68, 0x12,
- 0xf8, 0xf6, 0x87, 0xf5, 0xb3, 0x7d, 0xf4, 0xb9, 0x7c, 0xbc, 0xce, 0x77,
- 0x03, 0x4f, 0x43, 0xea, 0x76, 0x00, 0xfa, 0x2b, 0x80, 0xc7, 0xe4, 0xb9,
- 0x73, 0xbf, 0xcf, 0x73, 0x6d, 0xa8, 0xa3, 0x0d, 0xdb, 0x26, 0xb9, 0x11,
- 0xe0, 0xa0, 0x1a, 0xd6, 0xf9, 0x47, 0xf5, 0xb0, 0xc6, 0xe5, 0x40, 0x99,
- 0x7e, 0x7b, 0xf3, 0xa8, 0xc6, 0xe8, 0xd4, 0xee, 0xf7, 0xf4, 0x5e, 0x50,
- 0xce, 0x96, 0x1d, 0xd2, 0xaa, 0x29, 0x3b, 0xe0, 0xb5, 0xeb, 0xb5, 0x37,
- 0xfa, 0x79, 0x57, 0x37, 0x6a, 0xdf, 0xef, 0xf3, 0x6c, 0x34, 0xd6, 0x5d,
- 0xe8, 0xf3, 0xea, 0xa2, 0xbe, 0xcd, 0x45, 0xdb, 0xac, 0x84, 0xbd, 0x7d,
- 0x5b, 0x6a, 0x1b, 0xdf, 0x95, 0x77, 0x8b, 0xdf, 0x91, 0x5f, 0x6c, 0x9c,
- 0x81, 0xce, 0x61, 0x95, 0xb2, 0x90, 0x27, 0x6f, 0xd7, 0x5c, 0xf7, 0x6d,
- 0x67, 0x01, 0xf6, 0x81, 0xeb, 0xfe, 0xd6, 0xd9, 0x93, 0xd8, 0xc4, 0x37,
- 0xb1, 0xe7, 0x0c, 0x78, 0x88, 0x58, 0x98, 0x06, 0xbd, 0x7d, 0xb1, 0x5f,
- 0x3a, 0x42, 0x9a, 0x4e, 0x86, 0x27, 0x5a, 0xb1, 0x07, 0xc3, 0xd7, 0xc3,
- 0xb9, 0x97, 0xe9, 0x7e, 0xd2, 0x8c, 0x51, 0xfb, 0x09, 0xe6, 0x6f, 0x05,
- 0x5f, 0x1c, 0xc5, 0x4f, 0xc9, 0x9d, 0x71, 0xac, 0x75, 0x9c, 0xb4, 0xd7,
- 0x2a, 0xb1, 0xc7, 0xb0, 0x8f, 0x4c, 0x8b, 0xdc, 0xcb, 0x6f, 0xf6, 0xd1,
- 0x9f, 0x77, 0x2f, 0xcf, 0xb2, 0xf1, 0xb9, 0x4e, 0x71, 0xa5, 0x05, 0xf2,
- 0x7b, 0x75, 0xd2, 0xd3, 0x95, 0x7e, 0xad, 0x4e, 0xa0, 0xbd, 0x9d, 0x7d,
- 0x4f, 0x51, 0xb7, 0xcb, 0xba, 0xad, 0xd0, 0xc5, 0xe7, 0xa0, 0x03, 0xa5,
- 0x6a, 0x17, 0xa4, 0x3e, 0x1e, 0x42, 0x1b, 0xea, 0x28, 0x1a, 0x4b, 0x64,
- 0x26, 0xcf, 0x7c, 0x2d, 0xe6, 0x4e, 0x61, 0x8d, 0x0b, 0xc4, 0x0d, 0xae,
- 0xb1, 0x8d, 0x31, 0x38, 0xbf, 0xce, 0x06, 0x8d, 0xb0, 0x8e, 0xf4, 0x9d,
- 0x04, 0x4f, 0x26, 0x29, 0x37, 0x31, 0xde, 0x18, 0xc6, 0x63, 0xb9, 0x13,
- 0xe3, 0x5d, 0x90, 0x94, 0xd3, 0x18, 0x73, 0x0a, 0x6d, 0x88, 0x33, 0x53,
- 0xd0, 0x1f, 0x86, 0xd4, 0xec, 0x7a, 0x18, 0xf2, 0xbb, 0x4f, 0x66, 0xcd,
- 0x23, 0x07, 0xf6, 0x98, 0xd5, 0xf6, 0x81, 0x61, 0x8c, 0xf9, 0x6b, 0xea,
- 0x3c, 0xb0, 0x26, 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x6a, 0x7d, 0x0d, 0x38,
- 0xb5, 0xf6, 0x61, 0xca, 0x39, 0x2b, 0x33, 0x61, 0xae, 0x89, 0xf5, 0x61,
- 0xac, 0x99, 0x7e, 0xac, 0x67, 0x81, 0x43, 0x47, 0xfc, 0x3a, 0xb6, 0x15,
- 0x23, 0x85, 0xb3, 0xf7, 0xec, 0x5a, 0xd6, 0x7d, 0x56, 0x52, 0x6b, 0x19,
- 0x99, 0xd7, 0xfd, 0x78, 0x86, 0x83, 0x5a, 0xf7, 0x20, 0xaf, 0xc6, 0x7a,
- 0x70, 0x96, 0x89, 0x07, 0x36, 0x70, 0xb4, 0x47, 0xcb, 0xcc, 0x7e, 0x8f,
- 0x67, 0xf1, 0xad, 0x87, 0x77, 0xd4, 0x26, 0xb1, 0x6f, 0x40, 0x46, 0xe6,
- 0x1b, 0xf5, 0x21, 0xf9, 0x24, 0xdf, 0xd1, 0xcf, 0x38, 0xcb, 0xdd, 0xbc,
- 0x29, 0x1f, 0xe7, 0x75, 0x2c, 0x74, 0x31, 0x20, 0xd6, 0x79, 0xcf, 0x3e,
- 0x1f, 0x59, 0x5c, 0x55, 0xfc, 0x3e, 0x72, 0x7e, 0x4b, 0x05, 0xd1, 0x36,
- 0x84, 0x76, 0x5c, 0x87, 0x29, 0x73, 0xf9, 0xbf, 0xb9, 0x4b, 0xa3, 0xae,
- 0x3b, 0xaf, 0xf3, 0xc3, 0x12, 0xe6, 0xaa, 0x6a, 0xe8, 0xe4, 0x71, 0xc9,
- 0x87, 0xdb, 0x31, 0x57, 0xc2, 0xdc, 0x52, 0x23, 0x58, 0x0f, 0xcb, 0x3d,
- 0xe4, 0x89, 0xc8, 0x9e, 0x70, 0x7c, 0x2b, 0xbd, 0xa9, 0x12, 0xd1, 0x61,
- 0x65, 0x25, 0x73, 0xf8, 0xb5, 0x28, 0x1d, 0x47, 0x8c, 0x44, 0x15, 0x78,
- 0x17, 0x7b, 0xb2, 0x4f, 0xba, 0x6e, 0xda, 0x66, 0x7d, 0xc2, 0x0c, 0x29,
- 0xfa, 0x5b, 0x3a, 0x74, 0xbc, 0xf1, 0x72, 0x6f, 0xc2, 0x3c, 0xa9, 0x8e,
- 0xfb, 0xef, 0x53, 0xc0, 0xcc, 0xe6, 0x78, 0x67, 0x36, 0x95, 0x29, 0x2f,
- 0xe5, 0x13, 0xd1, 0x65, 0x65, 0x65, 0x30, 0x66, 0x66, 0x56, 0x11, 0x37,
- 0x12, 0x66, 0x87, 0xa2, 0x4f, 0xb4, 0x5d, 0xef, 0x3b, 0x8d, 0xfe, 0x09,
- 0xd5, 0xe2, 0xaf, 0x87, 0xf7, 0xf5, 0xe3, 0x7e, 0x8f, 0x67, 0x88, 0x39,
- 0xa3, 0xc0, 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x64, 0x6c, 0x62, 0x54,
- 0x63, 0xe8, 0xfd, 0x53, 0x7f, 0x47, 0x1d, 0xca, 0x25, 0xd6, 0xc5, 0x7d,
- 0x7e, 0x1b, 0xd5, 0x3a, 0xf3, 0xfd, 0x53, 0x59, 0x9d, 0xc7, 0x58, 0x57,
- 0x31, 0x7f, 0xdf, 0xcd, 0x3b, 0x8b, 0xa6, 0x9c, 0x47, 0x38, 0xce, 0x5a,
- 0x60, 0xba, 0x5d, 0x98, 0x23, 0x3a, 0x57, 0x6c, 0xd0, 0x06, 0xfd, 0x01,
- 0xcc, 0x17, 0x68, 0xc4, 0xbd, 0x2f, 0x88, 0x31, 0x11, 0x3c, 0x40, 0x27,
- 0xd0, 0x35, 0xa1, 0xa3, 0x56, 0x30, 0x4e, 0x6e, 0x5d, 0xb2, 0x5e, 0x7f,
- 0x09, 0x32, 0x27, 0x35, 0x57, 0xf9, 0xb4, 0x31, 0x38, 0x37, 0xe6, 0xc0,
- 0xfb, 0xfd, 0x53, 0xa4, 0x4f, 0x9e, 0x4d, 0x54, 0xcd, 0x6d, 0x70, 0x3d,
- 0x83, 0x32, 0xbf, 0x3e, 0x24, 0xcb, 0xf8, 0xad, 0xae, 0x7b, 0xf7, 0xb6,
- 0x0d, 0xdd, 0x7a, 0x3e, 0x6f, 0x6a, 0x7e, 0x5d, 0x76, 0x18, 0x33, 0x01,
- 0xaf, 0xe8, 0x9c, 0x2a, 0xf6, 0x65, 0x5e, 0xe1, 0x10, 0xe5, 0xa3, 0x53,
- 0x87, 0x5c, 0xdd, 0xae, 0x51, 0x4f, 0x65, 0xbd, 0x35, 0x15, 0x0d, 0x74,
- 0xc9, 0x2a, 0xf0, 0xae, 0x0c, 0xd9, 0x99, 0x7b, 0x25, 0x24, 0xcb, 0x79,
- 0x1d, 0x4f, 0x8e, 0xfe, 0x5e, 0x39, 0x52, 0xad, 0x4d, 0xca, 0x6e, 0x2d,
- 0xae, 0xbf, 0x51, 0xae, 0xe5, 0x5e, 0x37, 0xe4, 0xf9, 0x51, 0x9d, 0x57,
- 0x17, 0x2f, 0x4b, 0xef, 0x00, 0x75, 0x9e, 0x2d, 0x9d, 0x63, 0x07, 0xec,
- 0x80, 0xce, 0xf1, 0x33, 0xe8, 0x1c, 0xef, 0x40, 0xe7, 0xf8, 0x69, 0x11,
- 0xf8, 0x52, 0x4c, 0xfb, 0xf8, 0xbf, 0x08, 0x1c, 0xa2, 0xac, 0xb6, 0xce,
- 0xe0, 0x4e, 0x17, 0xb3, 0xa0, 0xc1, 0x5b, 0x92, 0x06, 0xde, 0xa6, 0xe4,
- 0xfa, 0xc6, 0xbc, 0xec, 0x6c, 0x78, 0x79, 0xc8, 0x1f, 0x30, 0x07, 0x6c,
- 0x9c, 0xf7, 0x14, 0x07, 0x0e, 0x1d, 0x91, 0xd8, 0x49, 0xe2, 0x47, 0x50,
- 0x36, 0x0b, 0xef, 0x68, 0x1c, 0xda, 0x2c, 0xb0, 0x1c, 0x10, 0x9d, 0x4f,
- 0xb6, 0xb0, 0x27, 0x65, 0xe7, 0x97, 0xa8, 0x3f, 0xa6, 0x7d, 0x40, 0x9e,
- 0x4f, 0x9e, 0x78, 0xf9, 0x67, 0xff, 0xee, 0x95, 0xce, 0xb3, 0x5b, 0x32,
- 0xbb, 0xd0, 0xae, 0x81, 0x5d, 0xc3, 0x5e, 0xcc, 0x5b, 0xfd, 0x05, 0x6d,
- 0x30, 0x47, 0xb1, 0x4b, 0xb6, 0x21, 0x43, 0xea, 0xf1, 0x2e, 0xad, 0xfb,
- 0xd5, 0xe3, 0x43, 0x3a, 0x17, 0x97, 0xe3, 0xe4, 0x0a, 0xb6, 0xac, 0x14,
- 0xac, 0x68, 0x16, 0xf4, 0xb7, 0x0b, 0x5b, 0xed, 0x3a, 0xee, 0x60, 0x07,
- 0x67, 0x70, 0xa3, 0x46, 0x39, 0x7f, 0x57, 0x63, 0xef, 0x66, 0xed, 0x4f,
- 0x18, 0xc7, 0x3a, 0x93, 0x94, 0x3f, 0xf6, 0x13, 0x03, 0xe9, 0x8f, 0x9a,
- 0xd1, 0xfd, 0xbd, 0x7e, 0xd7, 0xd1, 0x76, 0xa7, 0x46, 0x3c, 0x16, 0xb9,
- 0x94, 0xb7, 0x21, 0x4b, 0x5e, 0x8f, 0x50, 0x07, 0x28, 0xa9, 0x46, 0x3f,
- 0xd7, 0x5f, 0xb3, 0xeb, 0x1e, 0xb5, 0xb9, 0xae, 0xb8, 0x8f, 0xdb, 0x94,
- 0xfd, 0x7b, 0x5a, 0xee, 0xe7, 0x8b, 0x67, 0xe5, 0x2d, 0xdc, 0xb7, 0xa7,
- 0xe3, 0x64, 0xe4, 0x4d, 0xe8, 0x78, 0xb5, 0x62, 0x23, 0x6f, 0x7b, 0x1a,
- 0xe7, 0x64, 0xa9, 0x95, 0x2b, 0x2f, 0xcb, 0xe5, 0xab, 0xfb, 0xea, 0xa5,
- 0xab, 0x31, 0xf5, 0xf2, 0x95, 0x61, 0x95, 0xbb, 0xe2, 0xba, 0xff, 0x74,
- 0x96, 0xe4, 0xdd, 0x0d, 0x57, 0x4e, 0x3b, 0xc6, 0x40, 0x40, 0x1a, 0xb9,
- 0x75, 0xae, 0x1b, 0x04, 0x36, 0xdf, 0xe8, 0x75, 0xdd, 0x47, 0xc7, 0xc7,
- 0x25, 0xde, 0x4b, 0x1d, 0xe5, 0xf3, 0x11, 0xe6, 0xbb, 0x12, 0x73, 0x52,
- 0xb6, 0x7d, 0xbe, 0xac, 0x14, 0xf0, 0xad, 0xcb, 0xd3, 0x5f, 0x1e, 0x3b,
- 0xe6, 0xc7, 0x4a, 0x7e, 0xf4, 0x22, 0x7d, 0xc9, 0x91, 0xff, 0xf2, 0x25,
- 0x9b, 0x72, 0xae, 0xf0, 0x19, 0xf4, 0x0f, 0xcb, 0xb7, 0x0a, 0xa1, 0x43,
- 0x65, 0x13, 0xcf, 0x31, 0x95, 0x2b, 0xdc, 0x73, 0x87, 0x75, 0xcc, 0x00,
- 0x3a, 0x89, 0xe9, 0xba, 0xcb, 0x0e, 0xe7, 0xeb, 0xc2, 0x7c, 0x7b, 0xe6,
- 0x31, 0xc8, 0xff, 0xd3, 0x5a, 0x3e, 0x9f, 0x53, 0xb0, 0x7d, 0xc1, 0xdf,
- 0x61, 0x99, 0x2d, 0x40, 0xc6, 0x2b, 0xe6, 0x9c, 0x52, 0x57, 0xb0, 0x22,
- 0xcb, 0xc0, 0x8e, 0x25, 0xe0, 0xcd, 0x93, 0x3a, 0xb6, 0xda, 0xa3, 0xb1,
- 0x67, 0x85, 0xe5, 0x8c, 0x24, 0xcb, 0x4e, 0xb7, 0x3e, 0xbf, 0xfd, 0xdd,
- 0x57, 0x23, 0xde, 0x9d, 0x83, 0x8f, 0x33, 0x4a, 0xda, 0x60, 0x03, 0xcd,
- 0x6c, 0x2d, 0x80, 0x27, 0x22, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x75, 0xc8,
- 0xef, 0xba, 0xf6, 0x23, 0x7a, 0xf1, 0x8a, 0xba, 0xc9, 0x76, 0xcf, 0xa0,
- 0x5f, 0xbb, 0xa4, 0xae, 0xb4, 0x69, 0x5c, 0x7d, 0xb8, 0x2e, 0x09, 0x3d,
- 0xe4, 0x69, 0x94, 0x03, 0xa8, 0x8b, 0xfa, 0x65, 0x03, 0xe5, 0x45, 0x94,
- 0x5b, 0xf0, 0x64, 0x9b, 0x11, 0xe8, 0x15, 0x78, 0xbe, 0x81, 0xf1, 0xc6,
- 0xb1, 0xe6, 0x8c, 0x29, 0x1f, 0x9d, 0xa2, 0x2c, 0x19, 0x53, 0xcc, 0x4b,
- 0x5e, 0xb6, 0xf1, 0xac, 0x0e, 0xab, 0x99, 0x35, 0x96, 0xf1, 0x2c, 0x79,
- 0xdf, 0x1f, 0xc2, 0x24, 0xf4, 0x49, 0x5d, 0xf5, 0x30, 0xe9, 0xa3, 0x26,
- 0x26, 0xb1, 0xae, 0x5d, 0x66, 0xaf, 0x90, 0xd7, 0x4d, 0xd0, 0x5b, 0x87,
- 0xcc, 0x5c, 0x0d, 0x6b, 0x7d, 0xb4, 0x0c, 0x5a, 0xdc, 0x06, 0x5d, 0x6d,
- 0x82, 0xa6, 0x52, 0x05, 0x6b, 0x6a, 0x51, 0x45, 0xb5, 0x2f, 0xe0, 0x09,
- 0xd0, 0x6b, 0xf0, 0x15, 0xea, 0xa2, 0xe4, 0xe5, 0x38, 0x68, 0x4f, 0xdc,
- 0xa0, 0x6d, 0xa7, 0xe3, 0xca, 0x06, 0x0d, 0x82, 0x2e, 0x0b, 0x1e, 0x4f,
- 0xbf, 0xa7, 0x34, 0xae, 0x4e, 0xdd, 0x96, 0x44, 0xf2, 0xb6, 0x58, 0xc0,
- 0x02, 0xcb, 0xf9, 0x50, 0x1c, 0x8c, 0x39, 0x29, 0xd7, 0x30, 0x8f, 0x01,
- 0xfe, 0x1e, 0x3d, 0xa1, 0xf9, 0x7b, 0x4a, 0x02, 0x87, 0x79, 0x1c, 0xf4,
- 0x06, 0x0c, 0xf2, 0x78, 0x3a, 0xe9, 0xd3, 0xe8, 0xd7, 0xc1, 0xbf, 0x16,
- 0x2c, 0xb1, 0xb0, 0xac, 0x82, 0xff, 0xb7, 0xf1, 0xfd, 0x66, 0x6d, 0x44,
- 0xad, 0xac, 0x29, 0x3f, 0x97, 0xe4, 0x19, 0xe8, 0xc9, 0xb7, 0x70, 0x76,
- 0x9d, 0x5a, 0x77, 0x8f, 0x8d, 0x33, 0x7e, 0x96, 0x56, 0x97, 0xed, 0x93,
- 0xb2, 0x3f, 0x36, 0x89, 0xf2, 0x31, 0x3c, 0x0d, 0x9c, 0x43, 0x48, 0xc7,
- 0xbf, 0x37, 0xf3, 0x8e, 0xf2, 0xfe, 0x67, 0x61, 0x42, 0xe7, 0xe7, 0x1b,
- 0x76, 0x2f, 0xbe, 0xd3, 0x17, 0xc3, 0xbd, 0x41, 0x67, 0x52, 0x11, 0x9d,
- 0x6f, 0x5a, 0x86, 0x2e, 0xb1, 0x85, 0xf1, 0xde, 0xa7, 0x2f, 0xaf, 0x0a,
- 0x1e, 0x1e, 0xfb, 0x97, 0x9b, 0x0c, 0x33, 0x47, 0xfd, 0x6e, 0xc4, 0x93,
- 0x7f, 0x9f, 0xb8, 0xfb, 0xf6, 0xca, 0x94, 0x81, 0x97, 0x5b, 0x66, 0x18,
- 0x6d, 0x21, 0xcb, 0x20, 0x8b, 0x4a, 0x9a, 0x7e, 0xd9, 0xce, 0xeb, 0x9b,
- 0xab, 0x26, 0xcc, 0x0f, 0xc4, 0xeb, 0xbb, 0x6a, 0x53, 0xee, 0xb4, 0x03,
- 0x5f, 0xa2, 0x5a, 0xaf, 0x7c, 0xdf, 0xce, 0x02, 0x15, 0xac, 0x68, 0x1a,
- 0x34, 0xda, 0x26, 0x56, 0x7c, 0x4e, 0x1e, 0xcc, 0xbb, 0xac, 0xfb, 0xb2,
- 0x6d, 0xa3, 0x6f, 0x63, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b,
- 0x36, 0x35, 0x8d, 0xd6, 0xab, 0xdd, 0x03, 0x1e, 0x8d, 0x36, 0xf6, 0x11,
- 0xfe, 0x3f, 0xfb, 0x20, 0x9d, 0x38, 0xca, 0xcb, 0xbb, 0xc0, 0xb3, 0xca,
- 0xf3, 0x1c, 0x01, 0x6d, 0x1c, 0xa4, 0x9f, 0x86, 0x6f, 0xd1, 0xa3, 0x9f,
- 0x47, 0x9b, 0xf4, 0x43, 0xba, 0xe9, 0x90, 0xd9, 0xab, 0xb6, 0xcc, 0x17,
- 0xf4, 0x7d, 0x43, 0xd7, 0xa4, 0xcf, 0x68, 0x12, 0x74, 0x43, 0x5a, 0x27,
- 0x6f, 0x99, 0x52, 0x02, 0x1d, 0x95, 0x80, 0x4f, 0x25, 0xd0, 0x54, 0x19,
- 0xf8, 0x56, 0x02, 0xbe, 0x95, 0x6a, 0x56, 0xbc, 0x82, 0x3d, 0x53, 0x66,
- 0x6f, 0x81, 0x8e, 0xb6, 0x6b, 0xbc, 0x7f, 0xbd, 0x66, 0x93, 0x72, 0xf0,
- 0x66, 0xf3, 0xee, 0xff, 0x81, 0xbb, 0x1f, 0x92, 0x5d, 0xd8, 0x2d, 0x6f,
- 0x15, 0xc7, 0x80, 0x49, 0x02, 0x8c, 0x72, 0x40, 0x1b, 0x53, 0x72, 0xbd,
- 0x38, 0x2d, 0x3b, 0x90, 0x4f, 0x37, 0x36, 0x62, 0xd0, 0xa7, 0x23, 0xb2,
- 0xf2, 0xda, 0xa8, 0xbc, 0xb9, 0xa1, 0x64, 0x09, 0xf4, 0x9b, 0xdb, 0xa4,
- 0xdf, 0x1d, 0xf4, 0x5c, 0xea, 0xd0, 0x71, 0xfa, 0xd9, 0x8a, 0xe7, 0x7f,
- 0x9f, 0xab, 0x74, 0xca, 0x7c, 0xc5, 0x94, 0xc7, 0x2b, 0xdd, 0xf2, 0xe5,
- 0x4a, 0x58, 0x4e, 0xc3, 0x0e, 0xfc, 0x4a, 0x65, 0x50, 0x9e, 0xac, 0x0c,
- 0xc9, 0x57, 0xab, 0x51, 0xf9, 0x5a, 0xd5, 0x96, 0x4c, 0x35, 0x2e, 0xe9,
- 0xea, 0x98, 0x3c, 0x51, 0xa5, 0x5f, 0x1d, 0xf3, 0xe1, 0x37, 0xd3, 0xf4,
- 0x57, 0x70, 0x5d, 0x41, 0xac, 0x2b, 0xae, 0xe6, 0x74, 0x9c, 0x52, 0x32,
- 0x9e, 0xcf, 0x43, 0xe4, 0x39, 0x8c, 0x75, 0xf1, 0x35, 0x25, 0x65, 0x3d,
- 0x7f, 0xe3, 0xff, 0x46, 0x42, 0xda, 0x36, 0x7a, 0xae, 0x34, 0x88, 0x36,
- 0x90, 0x7b, 0xf9, 0x86, 0xef, 0xa3, 0xe1, 0xf3, 0x6f, 0xd8, 0x5e, 0x86,
- 0xf6, 0x5b, 0xdf, 0xa4, 0xed, 0xa5, 0xcf, 0x9e, 0xf8, 0x41, 0x3b, 0xe7,
- 0x9a, 0xf6, 0x9b, 0x3c, 0x88, 0x6d, 0x34, 0xe6, 0xbd, 0x98, 0x79, 0xf8,
- 0xff, 0x53, 0xbc, 0x18, 0xd5, 0xb9, 0xea, 0x20, 0xff, 0x4f, 0x05, 0x6b,
- 0xf9, 0xf4, 0xdc, 0xf1, 0xf9, 0xe2, 0xac, 0x7a, 0xbc, 0x48, 0x8d, 0xc6,
- 0x95, 0x8b, 0xcd, 0x9c, 0xb8, 0x2f, 0xc9, 0xa6, 0x13, 0xd2, 0x6b, 0xf0,
- 0xf3, 0x1f, 0x75, 0x7e, 0xdc, 0xec, 0x09, 0xd2, 0x1f, 0x63, 0x6f, 0x9d,
- 0x7e, 0x3c, 0x01, 0xba, 0xad, 0x63, 0xca, 0xa5, 0x8a, 0xe7, 0xb3, 0x5a,
- 0xd1, 0xf4, 0xf2, 0x2b, 0xd0, 0x1c, 0x63, 0x0e, 0xde, 0x33, 0x5b, 0xf2,
- 0xfa, 0xce, 0xe0, 0xde, 0x60, 0x8f, 0x63, 0xbf, 0x46, 0x37, 0xe7, 0xe2,
- 0xff, 0xe9, 0xa0, 0xec, 0xaf, 0x97, 0xb9, 0xc6, 0xb6, 0xa6, 0x45, 0x2f,
- 0xae, 0x1b, 0x97, 0x17, 0x70, 0x7e, 0x65, 0x93, 0xeb, 0x0f, 0x4a, 0x39,
- 0x4e, 0xdb, 0x96, 0xf8, 0x7d, 0x42, 0x4a, 0x98, 0xa7, 0x1c, 0x6f, 0xf8,
- 0xc3, 0x3c, 0x9c, 0x2d, 0x9b, 0x0f, 0xe6, 0x5d, 0x2c, 0x1d, 0xc7, 0x3b,
- 0xea, 0xe2, 0xd0, 0x99, 0x16, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0x56,
- 0xf0, 0x8c, 0xf8, 0x75, 0xd5, 0x01, 0xad, 0xab, 0x4f, 0x3f, 0xe8, 0xb7,
- 0x54, 0xb2, 0xb2, 0xa9, 0x40, 0x42, 0x19, 0xaf, 0xfe, 0x7c, 0x80, 0x98,
- 0x7b, 0xdc, 0xe6, 0x2f, 0x24, 0x7f, 0x35, 0xb5, 0x4f, 0xc1, 0xff, 0x76,
- 0x44, 0x9e, 0x32, 0x99, 0xc7, 0x9e, 0x54, 0xb3, 0xc5, 0x9c, 0x9f, 0xe3,
- 0x9b, 0x50, 0xc7, 0xcb, 0x37, 0x07, 0xbc, 0x9c, 0x77, 0x8e, 0x7d, 0x30,
- 0xcf, 0xfd, 0x20, 0x9d, 0x30, 0xdf, 0xbd, 0xbd, 0xf9, 0x3f, 0x52, 0xe5,
- 0x3c, 0xf0, 0xce, 0x6e, 0xd1, 0xfc, 0x98, 0xab, 0xfe, 0xdb, 0xdd, 0xd3,
- 0xfc, 0xdc, 0xf0, 0x31, 0xfc, 0x6e, 0x80, 0xb6, 0x2d, 0x71, 0xe3, 0x92,
- 0x97, 0x3b, 0xaa, 0x6d, 0x68, 0x60, 0x05, 0xea, 0xc8, 0xab, 0xe0, 0x93,
- 0x66, 0x5b, 0xfe, 0xfd, 0x07, 0x69, 0x3f, 0x51, 0x42, 0x6c, 0x67, 0x00,
- 0x00, 0x00 };
+ 0xec, 0x5c, 0x7d, 0x6c, 0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x8e,
+ 0xd4, 0x91, 0x5c, 0x1e, 0x4f, 0xcc, 0x51, 0xa6, 0xed, 0x5b, 0x71, 0x25,
+ 0x9e, 0x4d, 0xc6, 0x59, 0xd1, 0x07, 0x9b, 0x28, 0x0e, 0xc9, 0x66, 0xef,
+ 0x24, 0xb1, 0x86, 0x5b, 0x53, 0x35, 0x1d, 0x1b, 0x6d, 0xea, 0xb2, 0x47,
+ 0xb5, 0x29, 0x8c, 0x06, 0x90, 0xbf, 0x00, 0x17, 0xa8, 0xe4, 0xcb, 0x91,
+ 0x8a, 0x55, 0xf7, 0xc0, 0xbd, 0xc8, 0x8c, 0x18, 0x20, 0x6e, 0x7d, 0x25,
+ 0x29, 0x4a, 0x08, 0x0e, 0x3a, 0xa6, 0x71, 0x1a, 0xfd, 0x61, 0xd7, 0x04,
+ 0x2b, 0x1b, 0x6e, 0x91, 0xd6, 0x72, 0xe3, 0xb6, 0x46, 0x50, 0x04, 0x84,
+ 0xec, 0x34, 0x6e, 0xd0, 0x0f, 0xa1, 0x2e, 0x6c, 0x03, 0x96, 0xbd, 0xfd,
+ 0xbd, 0xd9, 0x5d, 0xf2, 0x48, 0x5b, 0x76, 0xd0, 0x3f, 0xfa, 0x4f, 0x77,
+ 0x80, 0xc3, 0xce, 0xcc, 0xbe, 0xf7, 0xe6, 0xcd, 0x9b, 0xf7, 0x39, 0x4b,
+ 0xe9, 0xb7, 0xe3, 0xd4, 0x4e, 0x41, 0xeb, 0xc0, 0x2f, 0x7d, 0xf4, 0xb1,
+ 0x87, 0x6e, 0xb9, 0xfd, 0x96, 0x5b, 0xd1, 0xdd, 0xaf, 0x2a, 0x3b, 0xd4,
+ 0x70, 0x3e, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
+ 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d,
+ 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a,
+ 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51,
+ 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b,
+ 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0xed, 0xff, 0x7b, 0x53, 0x89,
+ 0x74, 0x7e, 0x76, 0x04, 0x3f, 0x8a, 0x89, 0x5c, 0xfa, 0x01, 0xc7, 0xa4,
+ 0x98, 0x9a, 0xeb, 0x3f, 0x3e, 0x65, 0x12, 0xd9, 0xf5, 0xa1, 0x74, 0x9e,
+ 0x3e, 0xf0, 0x4a, 0x49, 0x8d, 0x78, 0xfe, 0xfa, 0xdc, 0xd5, 0x67, 0x9e,
+ 0xbf, 0xdd, 0xb8, 0x52, 0x53, 0x29, 0xa6, 0xe7, 0x66, 0xf6, 0xeb, 0xfb,
+ 0x28, 0xd6, 0x0f, 0x9c, 0xa7, 0x07, 0xff, 0xb1, 0x93, 0x3a, 0x43, 0x5a,
+ 0x44, 0x0b, 0x15, 0xc3, 0x3a, 0x88, 0xe7, 0x72, 0x7d, 0xc8, 0x5a, 0x23,
+ 0x8d, 0x56, 0x75, 0x7f, 0xc5, 0x72, 0x45, 0x61, 0x3a, 0x54, 0xae, 0xc7,
+ 0x68, 0x5d, 0xfe, 0x3b, 0x0f, 0xac, 0x69, 0x72, 0xff, 0x82, 0xe2, 0x34,
+ 0x3c, 0xef, 0x8c, 0xe5, 0x79, 0x2f, 0xe1, 0xf7, 0x33, 0x0b, 0x63, 0xf7,
+ 0x43, 0xcf, 0xd6, 0x54, 0x12, 0xe6, 0x1f, 0x2b, 0xce, 0x62, 0x2b, 0x95,
+ 0xe7, 0x89, 0xa6, 0xdd, 0x18, 0x9d, 0x74, 0x4b, 0x4a, 0xa1, 0x51, 0x51,
+ 0x0e, 0x9c, 0x9d, 0x55, 0x0e, 0x9e, 0x3d, 0xa9, 0x1c, 0x3a, 0x5b, 0x55,
+ 0x9c, 0xb3, 0x54, 0x12, 0xfb, 0xe3, 0x64, 0xeb, 0xe7, 0x94, 0x7c, 0xa3,
+ 0x57, 0x71, 0xe6, 0xaf, 0x7a, 0x8e, 0x65, 0xe8, 0xbf, 0x4e, 0x9a, 0xcd,
+ 0xeb, 0x39, 0x15, 0x0f, 0x63, 0x8d, 0xec, 0xa4, 0xe7, 0x89, 0x9c, 0xf7,
+ 0xb8, 0x93, 0x35, 0x75, 0xa1, 0xc4, 0xa8, 0xdc, 0x68, 0x07, 0x5d, 0x4d,
+ 0xc9, 0xbb, 0xde, 0x0b, 0x8e, 0xb5, 0x0c, 0x3a, 0x75, 0xe0, 0x93, 0x2e,
+ 0x72, 0xcc, 0x4f, 0xc8, 0x63, 0x49, 0xc9, 0x0f, 0x86, 0xfc, 0x50, 0x9a,
+ 0xf9, 0x2d, 0x2e, 0x09, 0xf0, 0xb5, 0x93, 0x8a, 0x35, 0x9d, 0x26, 0x97,
+ 0xb6, 0xc3, 0xaf, 0x7b, 0xcf, 0x0f, 0xea, 0xb4, 0xd2, 0x30, 0x4a, 0x25,
+ 0xec, 0x7d, 0xc6, 0x4d, 0x93, 0xc8, 0x91, 0xed, 0x64, 0xfb, 0xe9, 0x85,
+ 0x46, 0x8a, 0xfe, 0xbc, 0x61, 0xa6, 0xca, 0xb4, 0x83, 0x8a, 0xc9, 0x24,
+ 0x7d, 0x17, 0x38, 0xd3, 0x58, 0x5b, 0x98, 0xa6, 0x5e, 0x06, 0x6c, 0xb9,
+ 0xf1, 0x23, 0xfe, 0xb7, 0x31, 0xfa, 0x54, 0x56, 0xe2, 0x94, 0xc0, 0x67,
+ 0x00, 0xcb, 0x7c, 0x4b, 0x58, 0xc9, 0xbb, 0x0f, 0x4b, 0xa5, 0xa9, 0x2c,
+ 0xe6, 0x1a, 0x4e, 0x20, 0xfb, 0x56, 0xec, 0x8f, 0x9f, 0x37, 0x28, 0xf9,
+ 0xf9, 0x1b, 0x20, 0x03, 0x4a, 0x0a, 0xda, 0x9b, 0x2a, 0x62, 0x66, 0xba,
+ 0x11, 0xc7, 0x98, 0x79, 0xf1, 0xbc, 0x43, 0x16, 0xe9, 0x65, 0xab, 0x0b,
+ 0xb2, 0x4a, 0x53, 0xd9, 0xea, 0x04, 0x4e, 0x0b, 0x75, 0x9b, 0xbc, 0x07,
+ 0xa6, 0xdb, 0x86, 0x79, 0xaf, 0x43, 0xcd, 0x79, 0xde, 0x54, 0x96, 0x3a,
+ 0xfd, 0xb9, 0x21, 0xd0, 0xd0, 0x68, 0x72, 0x5c, 0x01, 0xdc, 0xdb, 0xcc,
+ 0x5f, 0x2c, 0x91, 0xe3, 0x3e, 0x3f, 0xb3, 0xe4, 0xcc, 0xa6, 0x83, 0x75,
+ 0xe3, 0x54, 0x76, 0xaf, 0x0f, 0xfa, 0x90, 0xad, 0x8b, 0x3d, 0x5b, 0x7d,
+ 0x18, 0x2b, 0x37, 0x82, 0x8e, 0x55, 0x26, 0x5e, 0x63, 0x17, 0xad, 0x25,
+ 0x49, 0x5c, 0xb6, 0x7a, 0x02, 0xb8, 0x4e, 0xf0, 0x1a, 0x9e, 0x71, 0x3b,
+ 0xcd, 0xcc, 0xb7, 0xd2, 0x89, 0x79, 0x96, 0x6d, 0x05, 0x67, 0x21, 0x68,
+ 0xcf, 0x6d, 0x25, 0xc5, 0x6e, 0x9c, 0x44, 0x5f, 0xa3, 0x29, 0xd3, 0x7b,
+ 0x61, 0xc6, 0x9a, 0x55, 0xf2, 0x67, 0x97, 0x95, 0x02, 0xce, 0xfc, 0xc0,
+ 0xd9, 0x0b, 0xca, 0xc1, 0xc6, 0xcb, 0x1d, 0xd4, 0x6e, 0x40, 0xbb, 0x34,
+ 0x3a, 0xe1, 0x2a, 0xc4, 0xfc, 0x2e, 0x40, 0x5e, 0xb6, 0x0e, 0xc9, 0x9b,
+ 0x9d, 0xca, 0x41, 0xd0, 0x6a, 0x31, 0xbf, 0x1e, 0xa7, 0x4e, 0x95, 0x76,
+ 0x98, 0x21, 0x6c, 0x8c, 0xbe, 0x0e, 0xde, 0xd6, 0xac, 0x24, 0xe0, 0xa8,
+ 0xcb, 0xc7, 0xe9, 0x0e, 0xf8, 0x61, 0xdd, 0x61, 0xbd, 0x11, 0x76, 0x61,
+ 0xee, 0x8f, 0x7a, 0xca, 0xc3, 0x3b, 0x19, 0x06, 0xf6, 0x60, 0x3f, 0x30,
+ 0x65, 0x3a, 0xdd, 0x1a, 0x95, 0x74, 0x41, 0x86, 0x9e, 0xa7, 0x1b, 0x69,
+ 0xc6, 0x22, 0xca, 0x43, 0x9f, 0x85, 0xa9, 0x41, 0x46, 0x26, 0x64, 0xb4,
+ 0xb7, 0xa4, 0x8a, 0x7b, 0x41, 0xa2, 0xa4, 0x68, 0x81, 0x3c, 0x17, 0xe8,
+ 0x0e, 0x89, 0x2f, 0x72, 0x16, 0x74, 0xb0, 0x9d, 0xfb, 0x58, 0x37, 0x26,
+ 0xd7, 0x55, 0x73, 0x66, 0x6a, 0x91, 0x48, 0x11, 0xb9, 0x21, 0xd0, 0x63,
+ 0xdd, 0x64, 0x38, 0x17, 0x3c, 0x32, 0xef, 0xdc, 0x37, 0x81, 0x13, 0x23,
+ 0xc7, 0xea, 0x68, 0xe2, 0x13, 0xfc, 0x24, 0x59, 0xe6, 0x2c, 0x43, 0xb9,
+ 0x4f, 0x65, 0x73, 0x9f, 0xef, 0x7b, 0x83, 0x23, 0x1a, 0xbd, 0x24, 0xf7,
+ 0xcb, 0x76, 0xc4, 0x70, 0x72, 0x8f, 0xc4, 0xf2, 0x99, 0x76, 0x49, 0x29,
+ 0x5a, 0xfa, 0x06, 0x2d, 0xe8, 0x85, 0x50, 0x73, 0x71, 0xca, 0x4b, 0xfe,
+ 0x46, 0xb1, 0x16, 0xdb, 0x17, 0xec, 0xc4, 0xe4, 0xbd, 0xf0, 0x5c, 0x0e,
+ 0xb6, 0x6a, 0x48, 0xfd, 0x29, 0x56, 0xd9, 0xfe, 0x99, 0xb7, 0x55, 0x43,
+ 0x50, 0x48, 0x4f, 0xf4, 0xaa, 0xd4, 0x45, 0xe3, 0xd6, 0x55, 0x4f, 0xec,
+ 0xc3, 0xfb, 0xe1, 0x14, 0x78, 0x33, 0xd2, 0xb0, 0xb6, 0x84, 0x4a, 0xb0,
+ 0x73, 0x6b, 0x28, 0xa5, 0x93, 0x89, 0xbd, 0x25, 0xc8, 0x1e, 0x5f, 0x85,
+ 0xe0, 0xaf, 0xc5, 0xa7, 0x4f, 0x17, 0x6c, 0xda, 0x0e, 0x78, 0x74, 0xac,
+ 0x5b, 0xa5, 0xcc, 0x74, 0xec, 0x5f, 0x9d, 0x65, 0xf9, 0xb6, 0x43, 0xff,
+ 0x15, 0x2a, 0x5a, 0x4c, 0x3b, 0xa4, 0x21, 0x68, 0xf0, 0xb6, 0x66, 0x1a,
+ 0xe1, 0xd9, 0xb2, 0xfe, 0x6a, 0x34, 0x32, 0xc2, 0xb0, 0x0c, 0xc7, 0xf0,
+ 0xc6, 0x68, 0x5a, 0xbc, 0xef, 0xed, 0xdf, 0xb2, 0xa6, 0x49, 0x62, 0x16,
+ 0x3c, 0xfb, 0x67, 0x01, 0x19, 0x7e, 0x1a, 0x2c, 0x9f, 0xc3, 0x76, 0x79,
+ 0x33, 0x6c, 0x33, 0x1c, 0x74, 0xa8, 0x97, 0x79, 0xa8, 0xc7, 0x7d, 0x7b,
+ 0x0c, 0x79, 0x0a, 0xcf, 0x52, 0x09, 0x68, 0x7c, 0xd2, 0x3e, 0x18, 0x1e,
+ 0x7e, 0xc2, 0x85, 0x9f, 0x70, 0xe1, 0x1f, 0x5c, 0xf8, 0x11, 0x97, 0xfd,
+ 0x4a, 0x9a, 0x9e, 0x1f, 0x84, 0xdf, 0xdb, 0xf4, 0x43, 0x68, 0x63, 0xe8,
+ 0x0b, 0x52, 0xe1, 0x87, 0xa6, 0x6b, 0x02, 0xb6, 0x0e, 0x9b, 0x5b, 0xe2,
+ 0x39, 0x1d, 0xcf, 0x02, 0x9e, 0x26, 0xfc, 0x2c, 0xeb, 0x61, 0xe8, 0x5f,
+ 0xd9, 0x2f, 0xa5, 0xe0, 0x83, 0xd8, 0xef, 0xb0, 0x7f, 0x62, 0x58, 0xcf,
+ 0x2b, 0x58, 0x8c, 0xeb, 0xe1, 0x1c, 0xd9, 0xee, 0xe2, 0x24, 0x12, 0x25,
+ 0xe5, 0xf0, 0x20, 0x6c, 0xf2, 0xe6, 0x16, 0xf0, 0xca, 0xb6, 0x79, 0x1d,
+ 0xbb, 0x16, 0xb4, 0xf7, 0x3b, 0xfc, 0x7f, 0xb7, 0xb7, 0x03, 0x30, 0xd2,
+ 0xc6, 0x3b, 0xfd, 0x71, 0x77, 0xe0, 0x7f, 0xf8, 0xbd, 0x91, 0xb6, 0x69,
+ 0x5f, 0x30, 0xe6, 0xfe, 0x06, 0xbf, 0x96, 0xb8, 0x2d, 0x46, 0x7b, 0x96,
+ 0x7d, 0xbf, 0xb9, 0x67, 0x01, 0x9a, 0xb1, 0xec, 0xf3, 0xb8, 0xe7, 0x7c,
+ 0xe8, 0x3f, 0x3b, 0x40, 0x0f, 0xfc, 0xb9, 0x9b, 0x71, 0x84, 0xe8, 0xbf,
+ 0x14, 0x98, 0x16, 0xe6, 0xb6, 0xcb, 0xc2, 0xf3, 0x66, 0x2c, 0xb6, 0x4f,
+ 0xbd, 0xd9, 0x3e, 0xf7, 0xc3, 0x3e, 0xad, 0x56, 0x32, 0xac, 0xbf, 0x82,
+ 0x7d, 0x3e, 0x61, 0x29, 0x90, 0x0d, 0xd1, 0xc5, 0x4a, 0x1c, 0xbe, 0x41,
+ 0x4b, 0xbd, 0x41, 0x7b, 0xd3, 0xd3, 0xd0, 0xcb, 0x33, 0x3c, 0x87, 0x23,
+ 0x3a, 0x21, 0xfd, 0xb5, 0xef, 0x0f, 0xd6, 0xd5, 0x6f, 0x80, 0x2f, 0xcf,
+ 0x9b, 0x06, 0xcd, 0xe2, 0xb0, 0x1a, 0xd8, 0x62, 0x38, 0x6f, 0x23, 0x26,
+ 0x3a, 0x37, 0xa9, 0x54, 0xca, 0xb4, 0x90, 0x91, 0x59, 0x00, 0xed, 0x29,
+ 0xcb, 0xb7, 0x7b, 0xb6, 0x8d, 0x45, 0xd0, 0x9f, 0x71, 0x07, 0xe1, 0x17,
+ 0xd8, 0x6e, 0xc0, 0x17, 0xe8, 0x2f, 0x82, 0xfe, 0x4c, 0xa3, 0x85, 0xbe,
+ 0xa6, 0x85, 0xb1, 0x36, 0xdc, 0x0f, 0x44, 0x6d, 0x86, 0xeb, 0x1e, 0xa5,
+ 0x3b, 0xdc, 0x84, 0xe2, 0x3c, 0xc5, 0x7e, 0xb9, 0x9c, 0x81, 0x5d, 0x29,
+ 0x65, 0x8b, 0xd7, 0x56, 0x69, 0x71, 0x03, 0x86, 0xec, 0xb2, 0x6f, 0xb3,
+ 0xb6, 0x33, 0x58, 0x4a, 0xa9, 0xd2, 0xf7, 0x10, 0x1d, 0xac, 0x68, 0x80,
+ 0xe1, 0x31, 0xcf, 0xfb, 0x73, 0x63, 0x95, 0x5e, 0xf8, 0x52, 0x1e, 0x5f,
+ 0xf5, 0xa6, 0x2c, 0x7f, 0xee, 0x97, 0x2b, 0x0f, 0xf0, 0x19, 0x61, 0x2f,
+ 0x94, 0x2e, 0x5b, 0x3f, 0xf7, 0xa0, 0xbf, 0x5b, 0x70, 0x3e, 0x9e, 0x8e,
+ 0x31, 0xe6, 0xeb, 0x2c, 0x29, 0x87, 0x4c, 0xd1, 0xdb, 0x1a, 0xf8, 0xbc,
+ 0x43, 0x98, 0x3c, 0x50, 0x29, 0xf7, 0xb4, 0xd2, 0x55, 0x95, 0x63, 0xeb,
+ 0x65, 0x38, 0x01, 0xa7, 0xb2, 0x0f, 0xf2, 0x28, 0x77, 0x37, 0xcd, 0xc5,
+ 0x0a, 0x15, 0x8f, 0xd6, 0x2c, 0x1f, 0x07, 0xe3, 0x78, 0xbe, 0x22, 0x7a,
+ 0x63, 0xb4, 0x31, 0xd6, 0x19, 0x67, 0x89, 0xf6, 0x65, 0x16, 0x49, 0xe2,
+ 0xf6, 0xc4, 0x36, 0x71, 0x93, 0x85, 0x4a, 0xb9, 0xbb, 0x69, 0x9c, 0xca,
+ 0x83, 0x96, 0xd8, 0xbf, 0x81, 0xdb, 0xbf, 0x89, 0xbb, 0x8b, 0xd2, 0xdd,
+ 0x8c, 0x2f, 0x7a, 0xdb, 0x36, 0x69, 0xa7, 0x03, 0x7e, 0x7a, 0xda, 0x36,
+ 0x69, 0x98, 0x4c, 0xb3, 0x69, 0x9c, 0x61, 0x9a, 0x7b, 0x36, 0x69, 0x0e,
+ 0x6f, 0xe5, 0xe7, 0x28, 0xc1, 0x07, 0xc5, 0x5a, 0x73, 0xb4, 0xff, 0x62,
+ 0x65, 0x60, 0xfc, 0x0e, 0x42, 0x8c, 0x1c, 0xde, 0x11, 0xf8, 0x70, 0x6d,
+ 0xbf, 0x03, 0x59, 0x69, 0xc4, 0x3e, 0x51, 0xa1, 0x32, 0xce, 0xf9, 0x81,
+ 0x3a, 0xed, 0x5f, 0xab, 0x53, 0xa0, 0x4b, 0xac, 0x13, 0x6f, 0xc1, 0xc6,
+ 0xa8, 0xb4, 0x3b, 0x17, 0x9f, 0xd4, 0x72, 0x3a, 0x6c, 0x8d, 0xc6, 0xcb,
+ 0xf0, 0xe1, 0x6a, 0x6e, 0xef, 0xeb, 0x79, 0xf5, 0x71, 0x4f, 0x35, 0xd9,
+ 0x1f, 0xc6, 0x47, 0x9d, 0x2c, 0xe6, 0xeb, 0x6c, 0x5b, 0xf0, 0x2b, 0x0d,
+ 0xa6, 0xfd, 0x4c, 0x17, 0x75, 0x22, 0x8e, 0xd6, 0xcf, 0xec, 0xf2, 0x6d,
+ 0x87, 0x34, 0x0d, 0xbe, 0x79, 0x26, 0xcb, 0x71, 0xbf, 0x35, 0x06, 0xf8,
+ 0x49, 0x35, 0x37, 0xd6, 0x77, 0xa4, 0x7e, 0x67, 0x5f, 0xb1, 0x5e, 0xea,
+ 0x2b, 0x56, 0x74, 0xb6, 0x13, 0xe1, 0x64, 0xd1, 0x97, 0xb9, 0x54, 0x0a,
+ 0x36, 0xc1, 0x6b, 0x27, 0xb1, 0xe6, 0x0f, 0x60, 0x7f, 0x6c, 0xdf, 0x44,
+ 0xe3, 0x2e, 0xd6, 0x18, 0xf9, 0x00, 0xe7, 0x0e, 0xde, 0xe0, 0xd3, 0x6c,
+ 0xec, 0x5a, 0x8c, 0xfc, 0x6b, 0x60, 0x9f, 0xdc, 0x7f, 0xc7, 0xf3, 0xe3,
+ 0xc3, 0xdd, 0x5d, 0xfe, 0xdc, 0x8f, 0x03, 0x9b, 0x0e, 0x69, 0x31, 0x9d,
+ 0x8c, 0x32, 0x8e, 0x1c, 0x66, 0xbc, 0xa1, 0x29, 0xec, 0x9f, 0xf3, 0x2e,
+ 0xe7, 0x1e, 0x9c, 0x77, 0x4c, 0x07, 0x7e, 0x8e, 0x6c, 0xe4, 0x4f, 0x9e,
+ 0x40, 0x2e, 0x52, 0x84, 0xdd, 0x68, 0xb9, 0x2b, 0x34, 0x23, 0x7d, 0x24,
+ 0xc5, 0x5a, 0x72, 0x8f, 0x01, 0xe6, 0xdf, 0x60, 0x73, 0xdd, 0x5d, 0x81,
+ 0x1e, 0x06, 0x3e, 0x5e, 0xfa, 0x5d, 0xc0, 0xbe, 0xb5, 0x0d, 0xf6, 0xcd,
+ 0x66, 0x58, 0xbc, 0x5f, 0xdf, 0xf6, 0xfe, 0x9f, 0xd9, 0x7e, 0xf1, 0x6e,
+ 0x15, 0xfe, 0xb4, 0x35, 0xb0, 0xfd, 0x8b, 0x54, 0x84, 0x6f, 0xd5, 0x4c,
+ 0xce, 0x2d, 0x0f, 0x02, 0x17, 0xe3, 0x3a, 0x78, 0x84, 0xbf, 0x40, 0x8c,
+ 0x85, 0xbc, 0x11, 0x13, 0x92, 0x37, 0x72, 0x3e, 0x05, 0xd8, 0x34, 0x60,
+ 0xd9, 0xff, 0x32, 0xec, 0x85, 0x38, 0xcb, 0xbc, 0x58, 0x67, 0x1c, 0xf6,
+ 0x55, 0xe4, 0x39, 0xd9, 0x36, 0x68, 0x94, 0xf7, 0x82, 0x6a, 0x86, 0xb0,
+ 0x21, 0xdd, 0xed, 0xb0, 0x9c, 0xdf, 0x30, 0xed, 0xae, 0x20, 0x6f, 0x18,
+ 0x23, 0xbb, 0x61, 0xe3, 0x57, 0xa2, 0xa9, 0xa7, 0x90, 0xbb, 0x99, 0x2d,
+ 0x2c, 0x0b, 0x9e, 0xd7, 0x7d, 0x19, 0x85, 0x78, 0xa5, 0x9e, 0xad, 0xe3,
+ 0xdf, 0x4a, 0x6c, 0xfa, 0x4a, 0xb6, 0x34, 0xb2, 0x11, 0x2b, 0x20, 0xe3,
+ 0xf4, 0xa4, 0xc8, 0x25, 0x29, 0x5f, 0xf7, 0xe5, 0x8b, 0xf8, 0x0c, 0xff,
+ 0x28, 0xfd, 0x07, 0xce, 0x3d, 0xf4, 0x83, 0xe1, 0x99, 0xb3, 0x9e, 0xd9,
+ 0x38, 0x9b, 0x34, 0x74, 0x69, 0x0c, 0xb8, 0x74, 0x14, 0x34, 0x38, 0x6e,
+ 0x5b, 0x22, 0x97, 0xa0, 0xa2, 0xce, 0xf9, 0x85, 0xcc, 0x0d, 0x6d, 0xf6,
+ 0x03, 0x22, 0xd7, 0x86, 0x39, 0xee, 0xff, 0x41, 0x97, 0x7f, 0xd6, 0x1d,
+ 0x3c, 0x1e, 0x17, 0xb9, 0xae, 0x6d, 0xf3, 0x7f, 0xd7, 0xe1, 0xf3, 0x26,
+ 0xc7, 0x98, 0xff, 0xc9, 0xb6, 0xf1, 0xa3, 0x89, 0xad, 0xe3, 0xaf, 0xf6,
+ 0x85, 0xfa, 0x20, 0x72, 0x8f, 0x05, 0xfc, 0xb2, 0x9e, 0x6e, 0xe7, 0xf5,
+ 0x17, 0xd1, 0x97, 0x3f, 0x01, 0x4d, 0xa9, 0xe3, 0xbf, 0x80, 0xbe, 0x6c,
+ 0xc0, 0x5e, 0x43, 0x5f, 0x9a, 0x79, 0xd8, 0xa8, 0x3b, 0xaa, 0x02, 0x39,
+ 0xac, 0x93, 0xdd, 0x9b, 0x2e, 0xc3, 0xc6, 0x0b, 0x0d, 0xc8, 0x6e, 0x23,
+ 0xae, 0x6e, 0xc0, 0x94, 0x36, 0x61, 0xfc, 0xb8, 0x53, 0x68, 0x78, 0xc8,
+ 0xfb, 0x9a, 0x63, 0x70, 0x06, 0xfd, 0x12, 0xf6, 0xba, 0x42, 0x53, 0xee,
+ 0x9a, 0x2d, 0xcc, 0x93, 0x32, 0x6f, 0x15, 0xe6, 0x93, 0x4a, 0x61, 0x91,
+ 0x73, 0xda, 0x18, 0xfa, 0xb2, 0x3e, 0x41, 0x8c, 0x3b, 0xa5, 0xd8, 0x67,
+ 0xe7, 0x90, 0xcf, 0x2e, 0xe1, 0x77, 0x0e, 0xbf, 0x3a, 0x7e, 0x61, 0xdd,
+ 0xf0, 0x2d, 0xd4, 0x1d, 0xd2, 0xdf, 0x23, 0x36, 0xf9, 0xeb, 0xff, 0x74,
+ 0x09, 0xf9, 0xf4, 0x5c, 0x92, 0x9e, 0x30, 0x45, 0x8f, 0xf0, 0x7d, 0x9c,
+ 0x8d, 0x5c, 0x5c, 0x7f, 0x8b, 0x7e, 0x25, 0xc8, 0xe9, 0x88, 0xde, 0xa8,
+ 0xe2, 0x2c, 0x87, 0x0f, 0x05, 0xfe, 0xe9, 0xe4, 0x57, 0x1c, 0xe9, 0xcb,
+ 0x83, 0x9c, 0x0d, 0x7e, 0xc7, 0x96, 0x50, 0xaf, 0x40, 0x3e, 0x0a, 0xfd,
+ 0x0c, 0x7a, 0xfc, 0x46, 0xb5, 0x1d, 0xfc, 0x98, 0x54, 0x9c, 0x30, 0x46,
+ 0x49, 0x19, 0xd0, 0x77, 0x28, 0xed, 0xc8, 0xdb, 0xe0, 0x77, 0xe4, 0x98,
+ 0x65, 0x46, 0xc7, 0x17, 0x2a, 0x02, 0xb0, 0x90, 0x79, 0x16, 0x7d, 0xe8,
+ 0xdf, 0xe5, 0x2a, 0xe3, 0x09, 0x7a, 0xb3, 0xaa, 0xd2, 0xbf, 0x20, 0x0f,
+ 0xc4, 0xbb, 0xe3, 0xb0, 0xc1, 0x5e, 0xc4, 0xab, 0x7e, 0x95, 0xf6, 0x72,
+ 0xcc, 0xd8, 0xa3, 0xe1, 0x59, 0xc0, 0xef, 0x20, 0xf2, 0xc2, 0x6b, 0xe0,
+ 0x5c, 0x03, 0x9e, 0x79, 0x8b, 0x01, 0x87, 0xe1, 0x35, 0xf0, 0xd6, 0x09,
+ 0x1d, 0x34, 0xf4, 0x49, 0xfa, 0x8c, 0x2e, 0x73, 0x27, 0x85, 0xe7, 0x7d,
+ 0x3f, 0xf9, 0xd1, 0x79, 0x96, 0xb3, 0x0a, 0x1d, 0xe2, 0x31, 0xbf, 0x63,
+ 0x7f, 0xce, 0xf4, 0x8c, 0x51, 0x1b, 0x9b, 0xb9, 0x5c, 0xf5, 0xfb, 0xe1,
+ 0x1c, 0x29, 0x61, 0x4c, 0x65, 0x3f, 0x5d, 0x80, 0xad, 0xf2, 0x78, 0x9c,
+ 0xe4, 0x19, 0x6c, 0x39, 0x4f, 0xa9, 0x47, 0xc7, 0x66, 0x4c, 0x3e, 0x57,
+ 0x9d, 0xa6, 0x2b, 0xe1, 0xb9, 0xf2, 0x19, 0xa1, 0x0e, 0xad, 0x3e, 0x89,
+ 0x73, 0x15, 0x41, 0xcd, 0x02, 0x3f, 0x30, 0xc7, 0xe7, 0x8b, 0x3a, 0xb2,
+ 0x8a, 0x3c, 0xac, 0x4a, 0x09, 0xbf, 0xe6, 0x3a, 0x85, 0x3a, 0x05, 0xe7,
+ 0x57, 0x99, 0x03, 0x8d, 0x24, 0x9e, 0x4b, 0x78, 0xa6, 0xf0, 0x3c, 0x87,
+ 0x67, 0x3f, 0x9e, 0x75, 0xb6, 0x8f, 0x20, 0xef, 0xf9, 0x08, 0x3f, 0xb0,
+ 0x93, 0x02, 0xdb, 0x34, 0xfd, 0x65, 0x23, 0x47, 0x3f, 0x68, 0x8c, 0xd2,
+ 0x5f, 0x34, 0xb2, 0xf4, 0xfd, 0x86, 0x45, 0xcf, 0x36, 0x86, 0xe9, 0x7b,
+ 0x8d, 0x0c, 0xd7, 0x90, 0xc8, 0xe1, 0xd2, 0xf0, 0xcd, 0x17, 0xe8, 0x2b,
+ 0x6e, 0x03, 0x3e, 0x47, 0xfa, 0xcb, 0xe3, 0x76, 0xfd, 0x3a, 0x2a, 0x3e,
+ 0xa5, 0x23, 0xcf, 0x54, 0xb9, 0x8e, 0xa3, 0x47, 0xad, 0xbb, 0x13, 0x7c,
+ 0xf6, 0xc2, 0xe4, 0xba, 0xe6, 0x04, 0xc3, 0xa1, 0x1e, 0x56, 0x90, 0xbf,
+ 0xb4, 0xd0, 0x64, 0xd2, 0x58, 0x71, 0xd4, 0x74, 0xe0, 0x8f, 0x26, 0x00,
+ 0x87, 0x35, 0xdd, 0x38, 0xad, 0x9d, 0x86, 0x2d, 0x58, 0xa8, 0xa5, 0x93,
+ 0x31, 0xf8, 0x3e, 0x99, 0x9f, 0x48, 0xdf, 0xe2, 0xfb, 0xd2, 0xb0, 0xc6,
+ 0xe4, 0x39, 0x3b, 0x98, 0xe3, 0xf8, 0xa8, 0x03, 0xb6, 0x11, 0xc4, 0x90,
+ 0xed, 0x34, 0xd9, 0x37, 0x4e, 0x04, 0xfe, 0x71, 0x85, 0x1e, 0x76, 0x07,
+ 0xec, 0xb7, 0x11, 0x7b, 0x94, 0x96, 0x30, 0x2f, 0xda, 0x0d, 0xde, 0x3c,
+ 0xef, 0x30, 0xea, 0xf3, 0x74, 0x42, 0xa3, 0xbf, 0x9f, 0x35, 0xf4, 0xc3,
+ 0x02, 0x01, 0xae, 0xdd, 0xf3, 0xc6, 0x4d, 0xa3, 0x64, 0x8b, 0x0e, 0xfa,
+ 0xa7, 0x53, 0x1c, 0x93, 0xd7, 0x8f, 0xbd, 0x08, 0x3d, 0xa8, 0x2d, 0xb5,
+ 0x52, 0xad, 0xa6, 0xd1, 0xe5, 0x91, 0x01, 0xb9, 0x6e, 0xad, 0x9e, 0x40,
+ 0x9e, 0xd7, 0x46, 0x8b, 0xbd, 0x52, 0xd9, 0xe1, 0xb7, 0x33, 0xd2, 0x6f,
+ 0x3b, 0x26, 0x9e, 0xf5, 0xb4, 0xbe, 0x95, 0x97, 0x67, 0xa9, 0xe8, 0x76,
+ 0xa2, 0x42, 0xd9, 0x0d, 0x99, 0x70, 0x7f, 0x40, 0x77, 0x04, 0x62, 0xa0,
+ 0x36, 0xa0, 0x1f, 0x12, 0xff, 0xed, 0x7d, 0x51, 0x63, 0x39, 0xbe, 0x8e,
+ 0xd8, 0xc2, 0xb1, 0x52, 0x91, 0x7a, 0xb7, 0xb0, 0xf4, 0xa6, 0xce, 0xfe,
+ 0xe5, 0x7b, 0xf5, 0xdd, 0xc1, 0x98, 0xfd, 0x3b, 0x8f, 0xdb, 0xe9, 0xfb,
+ 0xb5, 0x9d, 0xb4, 0x58, 0xe3, 0xf7, 0xad, 0xb4, 0x50, 0x1b, 0xb8, 0xf2,
+ 0x90, 0xe8, 0xa5, 0xd5, 0xeb, 0x6e, 0xd6, 0x3f, 0x2f, 0x20, 0x93, 0x89,
+ 0x0f, 0xe9, 0xdd, 0x91, 0x2e, 0x7a, 0xf5, 0x5e, 0xa3, 0x7a, 0xbf, 0x80,
+ 0x3e, 0x8e, 0xc4, 0xd9, 0xce, 0xd0, 0xe7, 0x79, 0xe3, 0x4a, 0x5a, 0xb0,
+ 0x9e, 0xbd, 0x0c, 0xfd, 0x32, 0x4e, 0xfa, 0x3a, 0xc9, 0xb4, 0x99, 0x2e,
+ 0xce, 0xc7, 0x7c, 0x05, 0x34, 0xf1, 0xae, 0x3e, 0x00, 0x5a, 0xaf, 0x48,
+ 0x59, 0x1c, 0xb6, 0x8c, 0x2b, 0x08, 0x51, 0xde, 0x65, 0x73, 0x20, 0x23,
+ 0xc4, 0x6e, 0xaa, 0xa5, 0x6e, 0xd6, 0xbf, 0x8b, 0x78, 0x80, 0x9a, 0xab,
+ 0xb4, 0x4e, 0xeb, 0xc7, 0x2e, 0x9a, 0xac, 0x8b, 0x6c, 0xc3, 0x3f, 0x44,
+ 0x4e, 0xaa, 0xd3, 0x53, 0x75, 0xf6, 0x5d, 0x4c, 0x8b, 0xeb, 0x82, 0x7d,
+ 0xfa, 0xdd, 0xe0, 0xc1, 0x19, 0xc6, 0x3b, 0xcc, 0xab, 0x9f, 0xe5, 0x73,
+ 0x6b, 0x61, 0xdc, 0x4c, 0x9a, 0x37, 0xb3, 0x45, 0x46, 0x03, 0xfa, 0x5e,
+ 0xc1, 0xeb, 0xbd, 0x8b, 0x75, 0xdf, 0x01, 0xaf, 0x03, 0xc0, 0x45, 0x0c,
+ 0x4d, 0x35, 0xaf, 0xf1, 0x9a, 0x5c, 0xe3, 0x54, 0x1d, 0x39, 0xe0, 0xc6,
+ 0x1a, 0x98, 0xab, 0x0b, 0xec, 0xf3, 0x57, 0x65, 0xfe, 0xac, 0x22, 0xff,
+ 0xb9, 0x3c, 0xf2, 0x4c, 0x90, 0x5f, 0x3c, 0x07, 0x59, 0xc7, 0xe8, 0xb5,
+ 0x59, 0xae, 0x2f, 0x0f, 0x51, 0x39, 0xb1, 0x7e, 0x6c, 0xca, 0x44, 0x4d,
+ 0x8f, 0x38, 0x50, 0xde, 0x37, 0xe0, 0xeb, 0x55, 0x3f, 0xe3, 0x3c, 0x27,
+ 0xcf, 0xa4, 0x2c, 0x5a, 0xe9, 0x8b, 0x5a, 0x1a, 0xf8, 0x3c, 0x77, 0x29,
+ 0x38, 0xcf, 0x6f, 0x83, 0x1f, 0xf4, 0xeb, 0x3d, 0x81, 0xff, 0x4b, 0x40,
+ 0x57, 0x87, 0xf4, 0xc3, 0x14, 0x0b, 0xfc, 0x5f, 0x82, 0x5e, 0x3d, 0xad,
+ 0x42, 0x87, 0x58, 0x7f, 0xfa, 0xbb, 0x37, 0xf5, 0x87, 0xdf, 0xad, 0x1f,
+ 0x73, 0xc0, 0x63, 0x7e, 0xae, 0x95, 0x0a, 0xd5, 0x18, 0x4d, 0x65, 0x91,
+ 0x73, 0x23, 0xfe, 0xe4, 0xa1, 0x4b, 0x85, 0x1a, 0xeb, 0x72, 0x29, 0xd0,
+ 0xe5, 0x78, 0x40, 0xfb, 0x6f, 0xa0, 0xcb, 0x46, 0x7a, 0x55, 0x70, 0x7d,
+ 0xd5, 0x27, 0x6b, 0x64, 0x15, 0xf6, 0x55, 0xac, 0x70, 0x2c, 0x62, 0xdb,
+ 0xa2, 0xe3, 0xcc, 0x7f, 0xb1, 0x32, 0x2a, 0x8a, 0x8d, 0xac, 0x28, 0xba,
+ 0xcc, 0xdf, 0x3e, 0xf0, 0xad, 0xc8, 0x3a, 0x78, 0xa1, 0xf1, 0xae, 0xb7,
+ 0xb0, 0x6f, 0x07, 0xfa, 0xd0, 0xfd, 0x71, 0x3e, 0xdf, 0xeb, 0x99, 0xaf,
+ 0xb4, 0x2d, 0x58, 0xde, 0x49, 0x5a, 0x1e, 0x7c, 0xa9, 0x8b, 0x73, 0xb4,
+ 0xb3, 0x83, 0x4c, 0x1f, 0x7c, 0x24, 0x93, 0xb4, 0xe8, 0xf2, 0x1a, 0x2c,
+ 0x17, 0xf8, 0xba, 0x39, 0x9d, 0x1e, 0x96, 0xe7, 0xc7, 0xba, 0xc5, 0xf7,
+ 0x4d, 0x2a, 0xe5, 0x13, 0x03, 0xfa, 0x43, 0x64, 0x5c, 0x59, 0x53, 0x8d,
+ 0xea, 0x24, 0xe2, 0xea, 0xc2, 0xbc, 0x4a, 0x7b, 0x64, 0x1d, 0xc6, 0x67,
+ 0x64, 0x9c, 0x84, 0x35, 0x06, 0x7b, 0xff, 0x8d, 0xa6, 0xbd, 0x77, 0xd2,
+ 0xc5, 0xd3, 0x9f, 0x85, 0xdd, 0xb3, 0x5c, 0xb5, 0xf4, 0x11, 0xe4, 0x19,
+ 0x73, 0x04, 0xf9, 0x22, 0x7f, 0xb6, 0x53, 0xe1, 0xb9, 0xb0, 0xbc, 0x77,
+ 0x49, 0xf9, 0x0b, 0x29, 0xff, 0x1b, 0xa8, 0xdc, 0xeb, 0xdb, 0x38, 0xbf,
+ 0x13, 0xa0, 0xe1, 0xbf, 0xe3, 0xf1, 0x67, 0x90, 0x1f, 0xf1, 0xbb, 0x9a,
+ 0x8f, 0x47, 0x3d, 0x4c, 0x07, 0xef, 0xfe, 0x10, 0x6b, 0xb2, 0x8c, 0xc3,
+ 0xf9, 0x0e, 0xf2, 0x6d, 0x29, 0x94, 0x3b, 0x12, 0x8c, 0x7a, 0x92, 0x7e,
+ 0xad, 0x9e, 0xa2, 0x89, 0x7a, 0x3f, 0x15, 0xea, 0x69, 0x9c, 0xc1, 0x13,
+ 0xdd, 0xbc, 0xb7, 0xfc, 0x12, 0xf6, 0x23, 0x98, 0xd7, 0x1a, 0x1d, 0x71,
+ 0x43, 0x7e, 0xe2, 0x01, 0x7f, 0x5a, 0x30, 0x8e, 0x05, 0x3c, 0x34, 0xd3,
+ 0x8b, 0x83, 0x96, 0x0d, 0x3a, 0x67, 0x02, 0x3a, 0xec, 0x47, 0xc0, 0xeb,
+ 0x44, 0x8a, 0x96, 0x5c, 0xe6, 0x63, 0x27, 0x95, 0x93, 0xdc, 0x7f, 0x0e,
+ 0x7a, 0xc6, 0x74, 0x76, 0x70, 0x7e, 0xb3, 0x45, 0xc6, 0x47, 0xeb, 0x25,
+ 0xc8, 0x98, 0xe5, 0xcb, 0x70, 0x71, 0x5a, 0xf8, 0x25, 0x3e, 0xbf, 0x21,
+ 0xe4, 0xf8, 0xac, 0x0b, 0x3b, 0x03, 0xbd, 0xf2, 0xd7, 0x2c, 0xcc, 0x75,
+ 0xe2, 0xac, 0x78, 0xdd, 0x76, 0xba, 0x07, 0x76, 0x9f, 0xaf, 0xf1, 0xfa,
+ 0x13, 0xd0, 0xa3, 0x1f, 0xcb, 0xf5, 0x0b, 0x4b, 0xbd, 0x01, 0x3e, 0xe3,
+ 0x76, 0x6e, 0xc3, 0x6d, 0xa5, 0x03, 0x55, 0xfd, 0x63, 0xf0, 0x7f, 0x13,
+ 0xf8, 0x82, 0xce, 0x64, 0x19, 0x9f, 0xe9, 0x00, 0xae, 0x96, 0xfc, 0x04,
+ 0x3a, 0x09, 0x59, 0xef, 0xe7, 0x6b, 0xad, 0x94, 0xaf, 0x86, 0xb4, 0x98,
+ 0xce, 0x87, 0xa8, 0x87, 0xbf, 0x2c, 0x69, 0x4d, 0x49, 0x5a, 0x78, 0x5f,
+ 0x63, 0x9f, 0x73, 0x3b, 0xf0, 0xe3, 0xec, 0xff, 0x69, 0x21, 0xd1, 0x41,
+ 0x0b, 0xb2, 0xa6, 0x6f, 0xf7, 0x7d, 0x4d, 0xa2, 0x0d, 0xef, 0x77, 0xc1,
+ 0xe6, 0x87, 0x90, 0x5b, 0x74, 0x62, 0x2e, 0xbd, 0x6d, 0x6e, 0x3b, 0xff,
+ 0xb1, 0x6d, 0xfc, 0xeb, 0x80, 0xeb, 0xc1, 0x9a, 0x3e, 0x5c, 0x01, 0x70,
+ 0xd3, 0x73, 0x90, 0xb3, 0xc5, 0x7e, 0x85, 0xe3, 0xe4, 0x75, 0x92, 0x97,
+ 0xe9, 0x25, 0x05, 0x70, 0xbd, 0xc0, 0x0d, 0xc7, 0xbe, 0x1c, 0xaa, 0xa0,
+ 0xf3, 0xcd, 0x9a, 0xbc, 0xbb, 0xc0, 0x19, 0xf4, 0x24, 0x78, 0xef, 0xe5,
+ 0xda, 0xa7, 0xc9, 0xec, 0xba, 0x26, 0x79, 0xb1, 0xac, 0x98, 0x5f, 0xe6,
+ 0x15, 0x7a, 0x8a, 0x38, 0xe4, 0x58, 0xa8, 0x0b, 0x13, 0x2a, 0x15, 0xb2,
+ 0x3a, 0xf2, 0x73, 0xbe, 0xb7, 0x65, 0xbb, 0xd4, 0xf9, 0xae, 0x34, 0x26,
+ 0x4c, 0x8e, 0xb5, 0x9a, 0xdc, 0xfb, 0x91, 0x25, 0xbe, 0xbb, 0x4d, 0xf3,
+ 0x5d, 0x5f, 0x86, 0xb0, 0xf7, 0x07, 0x97, 0x4c, 0x7a, 0xa4, 0x9e, 0xa1,
+ 0x87, 0xea, 0x86, 0x7e, 0x3f, 0x7c, 0x40, 0x71, 0xe3, 0x4e, 0xf7, 0x73,
+ 0x09, 0xae, 0x45, 0x34, 0xe4, 0x81, 0x2d, 0xa6, 0x9f, 0x17, 0x94, 0xb9,
+ 0x66, 0x9b, 0x33, 0xf8, 0x1e, 0x47, 0xaf, 0xd1, 0xf6, 0xdc, 0xe1, 0xff,
+ 0x32, 0x6f, 0xe0, 0xf5, 0xd9, 0x5f, 0x23, 0x4f, 0x70, 0x91, 0x27, 0xb8,
+ 0xc8, 0x13, 0x5c, 0xe4, 0x09, 0x2e, 0xf2, 0x04, 0x17, 0x79, 0x82, 0x8b,
+ 0x3c, 0xc1, 0x45, 0x9e, 0x80, 0xd8, 0xed, 0xd7, 0x0b, 0x63, 0xc8, 0x7f,
+ 0xe1, 0xbf, 0xdc, 0xcf, 0x43, 0x4e, 0x7c, 0xdf, 0xc9, 0x31, 0x87, 0x63,
+ 0x33, 0xcf, 0xad, 0xee, 0x70, 0xf8, 0xdc, 0xa4, 0xef, 0xbb, 0x13, 0x73,
+ 0xe3, 0x41, 0x3e, 0xc2, 0x30, 0x61, 0xec, 0x66, 0x38, 0x1a, 0x75, 0x2c,
+ 0x05, 0x36, 0xc6, 0xf9, 0x8a, 0x1f, 0xb3, 0xfc, 0x5c, 0xf9, 0x75, 0xe4,
+ 0x2c, 0x69, 0xe4, 0x2c, 0xfd, 0xc8, 0x4f, 0xf8, 0x8e, 0x3b, 0xbc, 0x63,
+ 0xb2, 0x95, 0xc3, 0xee, 0x98, 0x72, 0xb7, 0xcb, 0xb9, 0xb4, 0x99, 0x2e,
+ 0x0a, 0x31, 0xd7, 0x43, 0x1e, 0xe5, 0x47, 0xbe, 0x86, 0xbc, 0xf5, 0x9b,
+ 0xf2, 0x3e, 0x6d, 0x7c, 0x90, 0xcf, 0x7c, 0xe5, 0x1a, 0xb9, 0x6b, 0x28,
+ 0x5f, 0xff, 0x1e, 0x50, 0x2c, 0xb0, 0xfc, 0x88, 0xba, 0xcf, 0x43, 0xe0,
+ 0xe7, 0x63, 0x94, 0x58, 0xde, 0x89, 0x39, 0x9d, 0x7a, 0xe4, 0x5d, 0x12,
+ 0x8e, 0xf2, 0xbc, 0xd6, 0x43, 0xed, 0x26, 0x89, 0xf3, 0x7c, 0xe3, 0xc0,
+ 0x74, 0xd9, 0xbf, 0x5e, 0x3a, 0x96, 0xaf, 0x5d, 0x92, 0x3a, 0x75, 0xb8,
+ 0x5e, 0x40, 0x7d, 0xd4, 0x07, 0x18, 0x0d, 0xb5, 0x55, 0x48, 0x9b, 0x69,
+ 0x5e, 0x4d, 0xc8, 0x9a, 0xe7, 0xfc, 0xc6, 0x79, 0xe2, 0xac, 0x79, 0x9d,
+ 0x4b, 0xc7, 0xca, 0x55, 0x23, 0xc5, 0xb5, 0xb2, 0xad, 0x5f, 0x3a, 0x76,
+ 0x02, 0x34, 0x16, 0x91, 0x1b, 0xa8, 0x72, 0xed, 0x4b, 0xc7, 0xa6, 0xab,
+ 0xfe, 0x7d, 0x96, 0xcf, 0x03, 0xe2, 0x60, 0xb6, 0x9d, 0xd4, 0x05, 0xff,
+ 0x5e, 0x4b, 0x48, 0x5c, 0xc6, 0x63, 0x7c, 0x0d, 0x78, 0x7c, 0x6e, 0x19,
+ 0xe0, 0xf2, 0xd9, 0x31, 0x0f, 0x97, 0x8e, 0x95, 0x6a, 0xcd, 0x3c, 0x30,
+ 0x1d, 0xa6, 0x1b, 0xee, 0x87, 0xf7, 0x92, 0x20, 0xb1, 0xec, 0x79, 0xc5,
+ 0x91, 0xfe, 0x20, 0xef, 0x3a, 0x81, 0xfc, 0x4e, 0x93, 0x7a, 0xee, 0x8f,
+ 0xff, 0x4c, 0xc6, 0xa9, 0xb4, 0xe0, 0x79, 0x7e, 0xe2, 0x5d, 0xf6, 0x3b,
+ 0x98, 0xc3, 0x78, 0x31, 0x84, 0x15, 0x01, 0x6c, 0x47, 0x93, 0x3c, 0x5b,
+ 0x82, 0xf5, 0x98, 0x27, 0xde, 0xe7, 0xcf, 0xb1, 0x7f, 0x79, 0x07, 0xc7,
+ 0xf9, 0x18, 0xd6, 0xc5, 0x59, 0xba, 0xff, 0x5b, 0xd9, 0x37, 0xef, 0x89,
+ 0x65, 0xaa, 0x01, 0x87, 0xe1, 0x99, 0x46, 0x88, 0x83, 0x17, 0xe7, 0x7d,
+ 0x3c, 0xb1, 0x71, 0xff, 0xf7, 0x49, 0xeb, 0x36, 0xf3, 0x1a, 0xae, 0x1f,
+ 0xd2, 0xc9, 0xf8, 0xe7, 0xb6, 0x81, 0x2f, 0xff, 0x4f, 0x31, 0x3c, 0xa1,
+ 0x8b, 0x1f, 0xb9, 0x47, 0xcd, 0x34, 0xd5, 0xa1, 0xe1, 0xfd, 0x05, 0xdf,
+ 0x07, 0x70, 0x7d, 0xcf, 0xdf, 0x1a, 0x9a, 0x6b, 0xc5, 0x67, 0x83, 0x58,
+ 0xd6, 0x47, 0xb6, 0xc6, 0x75, 0xc3, 0x85, 0x60, 0xbc, 0x0b, 0xb1, 0x8d,
+ 0xc7, 0x0d, 0xc8, 0x17, 0xba, 0x6c, 0xb5, 0x07, 0x75, 0x4b, 0xc2, 0xff,
+ 0x26, 0x94, 0x61, 0x3b, 0xe2, 0xba, 0xaf, 0x2d, 0x98, 0x0b, 0xed, 0x88,
+ 0xfd, 0xb0, 0x16, 0xcc, 0xb1, 0xbf, 0x15, 0xa8, 0x5d, 0xb8, 0x0f, 0x3a,
+ 0x8b, 0xcd, 0xb6, 0x14, 0x3e, 0x13, 0x74, 0x6e, 0x3e, 0xf4, 0x5b, 0xf0,
+ 0x29, 0x83, 0x5a, 0xe0, 0xfb, 0xe3, 0xf0, 0x7d, 0x9d, 0x74, 0x00, 0x3e,
+ 0xeb, 0x20, 0x7c, 0xd6, 0x21, 0xd4, 0x8b, 0x63, 0x4b, 0xcd, 0xf7, 0xbc,
+ 0x5c, 0xa3, 0x76, 0x2a, 0x47, 0xe4, 0xf9, 0x97, 0x3c, 0xd5, 0xfc, 0x10,
+ 0x3a, 0xc0, 0x75, 0x57, 0xa8, 0x13, 0xf0, 0xb7, 0x56, 0x02, 0x3a, 0xb1,
+ 0xfd, 0x3e, 0x39, 0x03, 0xdb, 0x68, 0xb7, 0x85, 0xcc, 0xe5, 0x7c, 0xd9,
+ 0x97, 0x6b, 0xbe, 0xec, 0xe1, 0x97, 0x41, 0x5f, 0xa3, 0x52, 0x5d, 0xa7,
+ 0x12, 0xd6, 0x2d, 0x61, 0xdd, 0x12, 0xea, 0xbc, 0xe9, 0x7a, 0xf3, 0x77,
+ 0xaf, 0x8e, 0x80, 0x77, 0xc6, 0x0d, 0xfb, 0x7a, 0xd3, 0xfe, 0xc3, 0xe7,
+ 0x49, 0xc8, 0xff, 0x11, 0xc8, 0xff, 0x28, 0xea, 0x9b, 0xdf, 0x47, 0x7d,
+ 0xf3, 0x7b, 0xa8, 0x6f, 0x8e, 0xa0, 0xbe, 0x99, 0x44, 0x7d, 0xf3, 0x65,
+ 0xf8, 0x8f, 0xfb, 0xe0, 0x3f, 0x26, 0xe0, 0x3f, 0xc6, 0xe5, 0xdd, 0xd3,
+ 0x61, 0x77, 0xfb, 0x9d, 0x4a, 0xb8, 0x16, 0xb7, 0x9f, 0x12, 0x99, 0x25,
+ 0xec, 0x69, 0x8c, 0x6a, 0x0d, 0xae, 0x6f, 0x2c, 0x72, 0x46, 0xb9, 0xbe,
+ 0x99, 0x50, 0x26, 0x91, 0xbf, 0xdf, 0x3f, 0xcc, 0x75, 0x4f, 0x42, 0xc9,
+ 0xcb, 0xba, 0xc7, 0xb8, 0xe0, 0x20, 0x75, 0x43, 0xee, 0x87, 0x3d, 0x1b,
+ 0xe7, 0xf2, 0xe0, 0xc5, 0xcf, 0xf9, 0xba, 0x03, 0xbf, 0x17, 0xa7, 0xc5,
+ 0x59, 0xd4, 0x0c, 0xee, 0x3f, 0x28, 0x45, 0xe9, 0x1b, 0x75, 0x8c, 0x51,
+ 0x2b, 0xbb, 0xaf, 0x06, 0xe3, 0x11, 0x9a, 0x9a, 0x47, 0x6d, 0x7b, 0xfa,
+ 0x6f, 0x95, 0xbc, 0x1c, 0x5b, 0x18, 0x23, 0xdf, 0x3d, 0xfd, 0xd7, 0xc1,
+ 0xb8, 0x14, 0xe8, 0x43, 0xc0, 0xab, 0x6e, 0xe1, 0xd9, 0x15, 0xe4, 0x1c,
+ 0x2f, 0xf6, 0x6c, 0xfd, 0x3f, 0xef, 0xb8, 0xb5, 0x28, 0x64, 0x1e, 0xdf,
+ 0xe5, 0xd7, 0x67, 0xcd, 0xf3, 0x9d, 0x4d, 0xf3, 0xba, 0xfc, 0x0e, 0x5b,
+ 0xac, 0xb4, 0xbd, 0x07, 0x0f, 0x4c, 0x4b, 0x83, 0x46, 0xd5, 0xa6, 0x0f,
+ 0x3d, 0xfe, 0x5e, 0xe8, 0x88, 0x76, 0xf9, 0x0d, 0xcf, 0x91, 0xf7, 0x7a,
+ 0xb0, 0xf3, 0x91, 0x27, 0x77, 0xf9, 0xbe, 0x80, 0xfb, 0x49, 0xc5, 0xf7,
+ 0xef, 0x8f, 0x83, 0x0e, 0x64, 0xed, 0x36, 0xd7, 0x70, 0x7a, 0x70, 0x97,
+ 0xa2, 0x1f, 0x9f, 0xe1, 0xb3, 0x96, 0xb4, 0xb9, 0xd6, 0xe3, 0xba, 0x2f,
+ 0x8c, 0x01, 0x21, 0xad, 0xff, 0x48, 0xfa, 0x7c, 0xdf, 0x87, 0x9a, 0x8e,
+ 0x61, 0xc2, 0x71, 0x73, 0xfd, 0x17, 0x0f, 0xee, 0xe1, 0x98, 0xd7, 0x58,
+ 0xc0, 0xab, 0x16, 0xd0, 0xfb, 0x77, 0xcf, 0xf7, 0x3d, 0x8c, 0xaf, 0x37,
+ 0xe1, 0x5f, 0x40, 0xae, 0xc7, 0x77, 0x26, 0xbb, 0xe5, 0x77, 0xc9, 0x77,
+ 0x66, 0x3b, 0xe8, 0xed, 0x53, 0xc8, 0x59, 0x2d, 0x23, 0x73, 0x09, 0xb5,
+ 0xc7, 0x32, 0xdb, 0xc9, 0x08, 0xf3, 0x39, 0x90, 0x9e, 0xa6, 0x9b, 0x7b,
+ 0xfc, 0x5c, 0xfc, 0xab, 0xca, 0x47, 0xf9, 0x16, 0xc1, 0x3a, 0x3f, 0x6a,
+ 0x5a, 0x27, 0xdd, 0xb4, 0xce, 0x0a, 0xdb, 0x6c, 0xed, 0x4b, 0xd8, 0x73,
+ 0x69, 0xf7, 0xcd, 0x7a, 0x32, 0xa8, 0xcb, 0x1e, 0x1e, 0x69, 0xa3, 0x6a,
+ 0xaf, 0xb1, 0xf2, 0x1a, 0xf2, 0xf5, 0xe2, 0x08, 0xe6, 0x92, 0x03, 0x78,
+ 0xc7, 0xf3, 0x46, 0x8d, 0x84, 0xb1, 0x52, 0xa3, 0xcf, 0x01, 0xdf, 0x28,
+ 0x11, 0xf1, 0x3c, 0xf7, 0x25, 0x6f, 0xb5, 0xc0, 0x07, 0xa4, 0xd6, 0xb0,
+ 0xe7, 0x49, 0xd4, 0x5f, 0x47, 0x37, 0xea, 0x61, 0x5e, 0xe7, 0x56, 0x65,
+ 0x4d, 0xe6, 0xc6, 0xfb, 0x95, 0x52, 0xd2, 0xdf, 0xe3, 0xef, 0xc2, 0x5f,
+ 0xa8, 0x82, 0x71, 0xdf, 0x01, 0x6d, 0x85, 0x16, 0x4e, 0xa9, 0xf2, 0x0e,
+ 0xb6, 0x38, 0xc2, 0x67, 0xcd, 0xcf, 0x8f, 0x93, 0x5d, 0xb8, 0xa7, 0x3f,
+ 0x0d, 0xf6, 0x34, 0x16, 0xd4, 0xd3, 0xe1, 0x9e, 0x62, 0xf4, 0xe6, 0xac,
+ 0x0e, 0xdc, 0x9b, 0x20, 0x8f, 0x02, 0x2d, 0x35, 0xd2, 0x9f, 0x42, 0xa7,
+ 0xd2, 0x24, 0x1b, 0x6d, 0xdb, 0x19, 0x96, 0x36, 0x6b, 0xf8, 0xf1, 0x14,
+ 0xec, 0xf0, 0x78, 0x4f, 0x78, 0x37, 0xac, 0x9a, 0x1e, 0xd7, 0x3d, 0x68,
+ 0x3c, 0xdf, 0x0f, 0x5b, 0x4c, 0xc3, 0x3e, 0x39, 0x67, 0x2a, 0x70, 0xad,
+ 0xc2, 0xf6, 0xa4, 0x3b, 0xaa, 0xa1, 0x4f, 0x50, 0x06, 0xf5, 0x0e, 0xef,
+ 0x3f, 0x47, 0x8b, 0x8d, 0x90, 0x87, 0x2c, 0xec, 0x71, 0x14, 0xbf, 0x61,
+ 0xbc, 0xb3, 0xf0, 0xe3, 0x5a, 0x69, 0x85, 0x1e, 0x95, 0xb9, 0x38, 0x72,
+ 0xed, 0x41, 0xe6, 0xef, 0x4e, 0xc0, 0xb3, 0x3e, 0xb3, 0x9e, 0xde, 0x49,
+ 0x4e, 0x2f, 0xfb, 0x8a, 0x14, 0x68, 0x03, 0xc7, 0x5d, 0x87, 0xad, 0xf7,
+ 0xe3, 0x69, 0xe8, 0x45, 0x96, 0xad, 0xa4, 0xef, 0x79, 0x6a, 0x96, 0xbf,
+ 0x51, 0x5c, 0x08, 0xc6, 0x03, 0xfa, 0x3d, 0xac, 0x7b, 0xa9, 0x1b, 0x68,
+ 0x65, 0x3e, 0x8c, 0x83, 0x67, 0x60, 0x83, 0x7c, 0x67, 0x3b, 0x06, 0xb9,
+ 0xf0, 0x58, 0x09, 0xe2, 0x21, 0xe6, 0x17, 0x91, 0x94, 0xb4, 0xe7, 0x68,
+ 0x19, 0xf5, 0x3f, 0xf5, 0xf2, 0x13, 0xf9, 0xae, 0xbb, 0x33, 0xd0, 0xf7,
+ 0xad, 0xf8, 0xaa, 0xc9, 0xfd, 0x31, 0xf0, 0xa7, 0x35, 0xe1, 0x33, 0x8e,
+ 0x5f, 0x9f, 0xac, 0x11, 0xe2, 0x71, 0xca, 0xfb, 0x82, 0xc8, 0x3d, 0x4d,
+ 0xbf, 0x23, 0xf7, 0x54, 0xa7, 0x23, 0xf3, 0xa8, 0x6d, 0xb3, 0x03, 0x99,
+ 0x45, 0x32, 0x32, 0x27, 0x68, 0x48, 0x3f, 0x40, 0xaa, 0xfc, 0xd6, 0x97,
+ 0x16, 0xde, 0x17, 0x5a, 0x72, 0x9e, 0x77, 0x06, 0xbc, 0xbf, 0x28, 0xd7,
+ 0x79, 0x1a, 0xfc, 0x43, 0x56, 0xb2, 0x26, 0x61, 0x5e, 0xf1, 0x4c, 0x32,
+ 0xbf, 0x15, 0x3a, 0xd2, 0xf8, 0x61, 0x70, 0x36, 0x8f, 0x90, 0xe3, 0xbe,
+ 0xa5, 0x3a, 0x66, 0x05, 0xb0, 0xdf, 0x09, 0x78, 0xcb, 0x81, 0x5f, 0xac,
+ 0xdf, 0x58, 0x4f, 0xb2, 0x6f, 0xe0, 0x33, 0x77, 0x90, 0x35, 0x3a, 0x23,
+ 0xc8, 0xa3, 0x92, 0xd7, 0xf2, 0x03, 0x09, 0xda, 0xea, 0x07, 0x18, 0x2f,
+ 0xf1, 0x31, 0xba, 0xc2, 0x7c, 0x94, 0xa4, 0xff, 0x94, 0x71, 0x4b, 0xd2,
+ 0x53, 0xb7, 0xf9, 0x82, 0x6f, 0xc9, 0xe7, 0xaa, 0xca, 0xbe, 0x89, 0xe3,
+ 0x1f, 0xeb, 0x70, 0x27, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x9c, 0x9f, 0xe7,
+ 0xfb, 0x89, 0x41, 0xbe, 0x57, 0x3a, 0x57, 0xc0, 0xd9, 0x2e, 0xf0, 0xf7,
+ 0xc7, 0xa4, 0x5f, 0x63, 0xfa, 0xf5, 0x57, 0x9a, 0x7d, 0x21, 0xda, 0x92,
+ 0xf4, 0x93, 0x05, 0xf9, 0xbd, 0x31, 0x01, 0x18, 0x8f, 0x7d, 0x67, 0xd3,
+ 0xdf, 0x58, 0xbc, 0x6c, 0xfb, 0x7f, 0x63, 0x11, 0x7c, 0xfb, 0xad, 0xf9,
+ 0x79, 0xc4, 0x83, 0x75, 0x8d, 0x26, 0xeb, 0xe1, 0xdf, 0x5c, 0xf0, 0x39,
+ 0xc0, 0x37, 0xd7, 0xc3, 0xdc, 0xc1, 0x93, 0xf1, 0xa5, 0xbc, 0xe5, 0x2c,
+ 0x97, 0x82, 0x9c, 0x88, 0x6b, 0x00, 0x96, 0x21, 0xc6, 0x8b, 0xfe, 0xf9,
+ 0x2d, 0x88, 0x3d, 0x38, 0x3f, 0xc8, 0x1c, 0x7c, 0xbd, 0x39, 0xeb, 0xd7,
+ 0xb9, 0x65, 0xf6, 0x8b, 0xfd, 0x61, 0xdd, 0xbb, 0x9b, 0xca, 0x13, 0xfc,
+ 0x3e, 0x46, 0x6f, 0xcc, 0xc6, 0xe4, 0xfb, 0x22, 0xc5, 0x82, 0xf7, 0x3c,
+ 0x4e, 0x50, 0x51, 0xbe, 0xaf, 0x05, 0xf4, 0x50, 0xa7, 0xdd, 0x17, 0x8e,
+ 0x35, 0xe5, 0x48, 0xc3, 0xc7, 0x9b, 0x6a, 0xd4, 0xe8, 0xd1, 0xc6, 0x2a,
+ 0xf6, 0xaf, 0x50, 0x7e, 0xbc, 0x44, 0x37, 0x98, 0xba, 0x8c, 0xfb, 0x4e,
+ 0x82, 0x75, 0x8c, 0xf5, 0x6b, 0x4c, 0xd6, 0x9d, 0x25, 0xe4, 0x0b, 0xc5,
+ 0x11, 0xfe, 0xc6, 0xf3, 0xde, 0x5d, 0xc5, 0x8a, 0xa1, 0xdb, 0xf4, 0x81,
+ 0xe7, 0x68, 0x3c, 0x26, 0x21, 0x72, 0xab, 0x77, 0x3d, 0x58, 0xbf, 0x78,
+ 0x97, 0xbf, 0x57, 0xbc, 0xaf, 0x33, 0xac, 0x2a, 0xbf, 0xcd, 0xfe, 0xe4,
+ 0x76, 0x8d, 0xd6, 0x6e, 0xf7, 0xbc, 0xfb, 0x2d, 0x9d, 0x9c, 0xa0, 0x76,
+ 0xf5, 0xbf, 0xb9, 0xb7, 0xcb, 0x1c, 0xc4, 0x19, 0x49, 0x2b, 0x05, 0xd8,
+ 0xeb, 0xb2, 0x8b, 0x3a, 0x47, 0x18, 0xa3, 0xab, 0x42, 0x47, 0xcc, 0xe5,
+ 0x3b, 0x80, 0x3b, 0x7a, 0xf8, 0x7b, 0xf3, 0x8c, 0xc5, 0x30, 0x7d, 0xfe,
+ 0x5d, 0xd7, 0x2d, 0xf7, 0x49, 0x3f, 0x4b, 0x14, 0xc4, 0x9e, 0x5b, 0x9a,
+ 0x6d, 0xa2, 0x39, 0xb7, 0x64, 0x5b, 0xa0, 0x49, 0x0d, 0xbc, 0x94, 0x2b,
+ 0x61, 0x9e, 0xc6, 0x7f, 0x4b, 0xb0, 0x7a, 0xd7, 0x37, 0xc0, 0xe7, 0x34,
+ 0xf8, 0xe4, 0x7d, 0x4c, 0xd7, 0x43, 0x9d, 0x0b, 0x6b, 0x05, 0xee, 0x23,
+ 0xe6, 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x22, 0xe6,
+ 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x8e, 0x07, 0x79,
+ 0xda, 0x63, 0x1b, 0x79, 0xda, 0x4a, 0x83, 0xbf, 0x43, 0x49, 0x5e, 0x4a,
+ 0x25, 0xf2, 0xf3, 0x5c, 0x12, 0x9c, 0xd3, 0x84, 0x79, 0xee, 0xc7, 0x7f,
+ 0x13, 0xf1, 0xf1, 0x38, 0xc7, 0x63, 0xbc, 0x92, 0x22, 0x4c, 0xc6, 0xf3,
+ 0xf3, 0x3c, 0xae, 0xad, 0xb6, 0xe2, 0x20, 0x5f, 0xcb, 0xb1, 0x3f, 0x63,
+ 0xbb, 0x48, 0xfa, 0xf5, 0x62, 0xee, 0xf5, 0x2f, 0xa1, 0x76, 0x3c, 0x5e,
+ 0xac, 0xcb, 0x18, 0x8c, 0xf1, 0x7b, 0x18, 0x6b, 0xac, 0x73, 0xfc, 0xee,
+ 0x5e, 0xae, 0x27, 0x8a, 0xf5, 0x14, 0x95, 0x16, 0xc3, 0xfc, 0x07, 0x78,
+ 0xee, 0x90, 0x52, 0xa8, 0xf2, 0xd9, 0x0a, 0x9a, 0x4e, 0x42, 0x28, 0x66,
+ 0x73, 0x5e, 0x77, 0x49, 0xd6, 0x48, 0xfe, 0xdf, 0x05, 0x0d, 0x83, 0xb7,
+ 0xf0, 0x1e, 0x97, 0x48, 0x9d, 0x4d, 0xca, 0xbf, 0x31, 0x48, 0x98, 0x83,
+ 0xf2, 0x6f, 0x1d, 0xba, 0xb1, 0x8e, 0x98, 0xdd, 0x13, 0xfe, 0xed, 0x06,
+ 0xd7, 0x5d, 0xf6, 0xe6, 0xfd, 0x2b, 0xef, 0x23, 0x09, 0x7b, 0xbd, 0xa7,
+ 0x0f, 0x7b, 0xc3, 0xb9, 0x5e, 0xd9, 0x25, 0xf3, 0x6e, 0xf8, 0xce, 0x33,
+ 0x83, 0x37, 0xf5, 0x52, 0xe7, 0x6e, 0x5a, 0x1e, 0xe4, 0x1a, 0xad, 0x0d,
+ 0xf4, 0x18, 0xd6, 0xc8, 0xd8, 0x62, 0x37, 0x9d, 0x9d, 0x87, 0x6f, 0x9d,
+ 0x37, 0x2c, 0xfe, 0xfb, 0x82, 0x85, 0xc1, 0x24, 0x7c, 0xf2, 0x78, 0x2f,
+ 0xc7, 0xe4, 0xc5, 0x06, 0xeb, 0x4a, 0x37, 0xf0, 0xfb, 0xa1, 0x8b, 0x3b,
+ 0x60, 0x43, 0x02, 0xeb, 0x87, 0xb4, 0xff, 0x53, 0xd2, 0xee, 0x36, 0xf3,
+ 0x7d, 0x52, 0x37, 0x84, 0xa1, 0xa7, 0x05, 0x78, 0xff, 0x48, 0x6d, 0x69,
+ 0x11, 0x7f, 0x2f, 0x9c, 0x76, 0x9b, 0xbf, 0x1b, 0x0e, 0x29, 0xc5, 0x2a,
+ 0xff, 0x8d, 0xc3, 0x20, 0xfd, 0x4f, 0xe1, 0x56, 0x17, 0xd3, 0xd6, 0x79,
+ 0x86, 0xdf, 0xcf, 0xe6, 0x2f, 0xc4, 0x81, 0x13, 0xe2, 0x80, 0x41, 0x54,
+ 0xf3, 0x31, 0x07, 0xe2, 0xca, 0x44, 0x3d, 0x20, 0x32, 0x59, 0x15, 0x52,
+ 0x2d, 0xdb, 0x50, 0xb7, 0x5d, 0x36, 0x77, 0xcb, 0xa6, 0x4c, 0xda, 0x22,
+ 0x06, 0x49, 0x9b, 0x6a, 0xd2, 0x2e, 0x76, 0x31, 0xed, 0x2e, 0x96, 0x81,
+ 0x34, 0xcd, 0xec, 0x1a, 0x56, 0x32, 0xa4, 0x5d, 0x4c, 0xae, 0x31, 0x04,
+ 0x88, 0x53, 0xab, 0x5b, 0x2f, 0x32, 0x4d, 0x53, 0x90, 0x57, 0x25, 0xdd,
+ 0x4d, 0x6f, 0x76, 0x3f, 0x55, 0x64, 0xad, 0x72, 0xd1, 0x25, 0x6a, 0xa7,
+ 0x6a, 0x7f, 0x17, 0x67, 0xcf, 0xf3, 0x9d, 0x63, 0x20, 0x6c, 0xd5, 0x90,
+ 0xac, 0xf3, 0x9d, 0xef, 0x7c, 0xff, 0xdf, 0xfb, 0x3e, 0xef, 0x2f, 0x53,
+ 0xa0, 0x2f, 0xc3, 0x8a, 0xa9, 0x4b, 0x65, 0xb6, 0xb1, 0x50, 0xa6, 0x1d,
+ 0x7e, 0x13, 0xbc, 0xdc, 0x23, 0x8b, 0xa0, 0xe3, 0xfc, 0x68, 0xab, 0xe7,
+ 0x6f, 0xed, 0xf4, 0x78, 0x38, 0xd2, 0xeb, 0xc9, 0x28, 0xad, 0x4b, 0xe6,
+ 0xb5, 0x3e, 0xdd, 0x7d, 0xe8, 0xdb, 0x0f, 0xb0, 0xa6, 0x10, 0xce, 0x61,
+ 0xb8, 0x57, 0xe3, 0x91, 0x8f, 0xef, 0x7d, 0x87, 0xde, 0x7b, 0x0f, 0xbd,
+ 0x9f, 0xfc, 0x1f, 0xed, 0x59, 0x3e, 0x4c, 0x0f, 0x5c, 0xa7, 0x19, 0xe7,
+ 0x2c, 0xf9, 0xc2, 0x84, 0x9a, 0x2b, 0x98, 0x09, 0xea, 0x02, 0x29, 0x71,
+ 0x54, 0xca, 0x6e, 0x03, 0xc6, 0xb5, 0xc9, 0xc2, 0x0a, 0x68, 0x1e, 0xfb,
+ 0x68, 0xb7, 0x18, 0x2f, 0x7f, 0xb6, 0x97, 0x3c, 0xd3, 0x81, 0x6b, 0xf0,
+ 0x59, 0x43, 0x21, 0xb4, 0x73, 0x5e, 0xb3, 0x63, 0xc6, 0x45, 0xed, 0xbf,
+ 0xa1, 0x0e, 0xe3, 0xa8, 0xbc, 0xce, 0xfd, 0x60, 0x9b, 0x16, 0x79, 0x60,
+ 0x25, 0x7b, 0xbc, 0x5c, 0x22, 0xd8, 0xbb, 0x2f, 0xf6, 0x52, 0xbf, 0x78,
+ 0xd5, 0xde, 0xab, 0x33, 0x76, 0x85, 0x79, 0x5a, 0x20, 0x9a, 0x97, 0x45,
+ 0xca, 0x55, 0x91, 0x9b, 0xf8, 0xfd, 0xb1, 0xea, 0xc5, 0x2f, 0x14, 0x6d,
+ 0xed, 0x49, 0xd9, 0x2e, 0x3d, 0x2b, 0x35, 0xc8, 0x9c, 0x2d, 0xdb, 0x71,
+ 0x1e, 0xda, 0x61, 0x7d, 0xe6, 0xaf, 0x17, 0x94, 0x44, 0xc6, 0x28, 0xd3,
+ 0xda, 0xe4, 0x67, 0x2b, 0xcc, 0xbb, 0x33, 0x8d, 0x87, 0xc2, 0xfc, 0xb7,
+ 0x90, 0x64, 0x82, 0x7e, 0xad, 0x97, 0xca, 0xb7, 0x45, 0x3e, 0xc1, 0xb7,
+ 0x4f, 0x56, 0x5e, 0xe9, 0xa5, 0xcf, 0xe5, 0xe3, 0x15, 0xbe, 0xfb, 0xf0,
+ 0xf4, 0x49, 0xc3, 0xf2, 0x43, 0x7f, 0x05, 0xf0, 0x18, 0x3c, 0x77, 0xee,
+ 0xf7, 0x47, 0x5c, 0x1b, 0xea, 0x68, 0xc3, 0xb6, 0x49, 0x7e, 0x18, 0x38,
+ 0xa8, 0x86, 0x74, 0xbe, 0x52, 0x23, 0xa8, 0x71, 0xd9, 0x5f, 0x61, 0x5e,
+ 0x9d, 0x71, 0x54, 0x63, 0x74, 0xf2, 0xf6, 0x82, 0xde, 0x0b, 0xca, 0xb9,
+ 0x8a, 0x4d, 0x5a, 0x35, 0x64, 0x0b, 0xbc, 0xb6, 0x59, 0xdf, 0xea, 0xe3,
+ 0x5d, 0x6d, 0xd7, 0x17, 0x7b, 0x5d, 0x1b, 0x8d, 0x75, 0xaf, 0xf7, 0xba,
+ 0x75, 0x61, 0xcf, 0xe6, 0xa2, 0x6d, 0x56, 0xc6, 0xde, 0x7e, 0x2c, 0xf5,
+ 0xd5, 0x9f, 0xca, 0x9d, 0xd2, 0x4f, 0xe4, 0xb7, 0xab, 0xe7, 0xa1, 0x73,
+ 0x98, 0xe5, 0x1c, 0xe4, 0xc9, 0xbb, 0x75, 0xc7, 0x79, 0xd7, 0x3e, 0x07,
+ 0xfb, 0xc0, 0x71, 0xfe, 0x64, 0xef, 0x48, 0x64, 0xfc, 0x7b, 0xd8, 0x73,
+ 0x16, 0x3c, 0x44, 0x2c, 0xcc, 0x80, 0xde, 0x52, 0x7d, 0xd2, 0x19, 0xd0,
+ 0x74, 0x32, 0x34, 0xde, 0x8a, 0x3d, 0xf8, 0x3c, 0x3d, 0x9c, 0x7b, 0x49,
+ 0xf7, 0x91, 0x66, 0x7c, 0xf5, 0x0a, 0xe6, 0x6f, 0x05, 0x5f, 0x1c, 0xc5,
+ 0x4f, 0xc9, 0xc3, 0x31, 0xac, 0x75, 0x8c, 0xb4, 0xd7, 0x2a, 0x91, 0x67,
+ 0xb0, 0x8f, 0x6c, 0x8b, 0x3c, 0x2a, 0xdc, 0xea, 0xa5, 0x3f, 0xef, 0x51,
+ 0x81, 0x65, 0xdf, 0x57, 0xbb, 0xc4, 0x91, 0x16, 0xc8, 0xef, 0x85, 0x09,
+ 0x57, 0x57, 0xfa, 0x83, 0x3a, 0x85, 0xf6, 0x56, 0xee, 0x7d, 0x45, 0xdd,
+ 0x2e, 0xe7, 0xb4, 0x42, 0x17, 0x9f, 0x82, 0x0e, 0x94, 0xac, 0x5f, 0x91,
+ 0xc6, 0x58, 0x00, 0x6d, 0xa8, 0xa3, 0x68, 0x2c, 0x91, 0x54, 0x81, 0xf9,
+ 0x5d, 0xcc, 0xb5, 0xc2, 0x1a, 0xcf, 0x11, 0x37, 0xb8, 0xc6, 0x36, 0xc6,
+ 0xe0, 0xbc, 0x3a, 0x0b, 0x34, 0xc2, 0x3a, 0xd2, 0x77, 0x02, 0x3c, 0x99,
+ 0xa0, 0xdc, 0xc4, 0x78, 0xa3, 0x18, 0x8f, 0xe5, 0x2e, 0x8c, 0x77, 0x45,
+ 0x92, 0x76, 0x73, 0xcc, 0x38, 0xda, 0x10, 0x67, 0xe2, 0xd0, 0x1f, 0x06,
+ 0x55, 0x7a, 0x25, 0x08, 0xf9, 0xdd, 0x2b, 0x69, 0xe3, 0xc8, 0x81, 0x3d,
+ 0xe6, 0xb4, 0x7d, 0xe0, 0xf3, 0x8d, 0x7a, 0x6b, 0xea, 0x3a, 0xb0, 0x26,
+ 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x72, 0x65, 0x09, 0x38, 0xb5, 0xf4, 0x41,
+ 0xd2, 0xbe, 0x20, 0xa9, 0x20, 0xd7, 0xc4, 0xfa, 0x20, 0xd6, 0x4c, 0x3f,
+ 0xd6, 0x77, 0x81, 0x43, 0x47, 0xbc, 0x3a, 0xb6, 0x15, 0x5f, 0x12, 0x67,
+ 0xef, 0xda, 0xb5, 0xac, 0xfb, 0x8a, 0x24, 0x97, 0xb2, 0x32, 0xad, 0xfb,
+ 0xf1, 0x0c, 0x07, 0xb4, 0xee, 0x41, 0x5e, 0x8d, 0x9c, 0xc0, 0x59, 0xc6,
+ 0xf6, 0x6d, 0xe0, 0xf0, 0x09, 0x72, 0x91, 0xd1, 0xe7, 0xf2, 0x2c, 0xbe,
+ 0x9d, 0xe0, 0x1d, 0xb5, 0x49, 0xe4, 0x5b, 0x90, 0x91, 0x85, 0x66, 0x7d,
+ 0x40, 0x3e, 0x2d, 0xf4, 0xf4, 0x31, 0xce, 0xf2, 0xd7, 0x82, 0x21, 0x1f,
+ 0x17, 0x74, 0x2c, 0x74, 0xc6, 0x2f, 0xe6, 0x65, 0xd7, 0x3e, 0x1f, 0x9e,
+ 0x59, 0x50, 0xfc, 0x3e, 0x7c, 0x79, 0x5d, 0x75, 0xa0, 0x6d, 0x00, 0xed,
+ 0xb8, 0x0e, 0x43, 0xa6, 0x0a, 0x9f, 0x3b, 0xb3, 0x23, 0x8e, 0x33, 0xad,
+ 0xf3, 0xc3, 0x62, 0xc6, 0x82, 0x6a, 0xea, 0xe4, 0x51, 0x29, 0x04, 0xdb,
+ 0x31, 0x57, 0xcc, 0x58, 0x57, 0xc3, 0x58, 0x0f, 0xcb, 0x27, 0xc8, 0x13,
+ 0xa1, 0x1d, 0xe1, 0xf8, 0x66, 0x66, 0x4d, 0xc5, 0xc2, 0x43, 0xca, 0x4c,
+ 0xe4, 0xf1, 0x6b, 0x51, 0x3a, 0x8e, 0x18, 0x0a, 0x2b, 0xf0, 0x2e, 0xf6,
+ 0x64, 0x9d, 0x76, 0x9c, 0x8c, 0xc5, 0xfa, 0x98, 0x11, 0x50, 0xf4, 0xb7,
+ 0x74, 0xea, 0x78, 0xe3, 0xb5, 0x93, 0x31, 0xe3, 0xb4, 0x3a, 0xee, 0xbd,
+ 0xc7, 0x81, 0x99, 0x7b, 0xe3, 0x9d, 0x5f, 0x53, 0x86, 0xbc, 0x51, 0x88,
+ 0x85, 0xe7, 0x94, 0x99, 0xc5, 0x98, 0xd9, 0xb4, 0x22, 0x6e, 0xc4, 0x8c,
+ 0x4e, 0x45, 0x9f, 0x68, 0xbb, 0xde, 0x77, 0x06, 0xfd, 0x63, 0xaa, 0xc5,
+ 0x5b, 0x0f, 0xef, 0xeb, 0xed, 0x3e, 0x97, 0x67, 0x88, 0x39, 0x23, 0xc0,
+ 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x44, 0x64, 0x7c, 0x44, 0x63, 0xe8,
+ 0xe3, 0x33, 0x7f, 0x47, 0x1d, 0xca, 0x65, 0xd6, 0x45, 0x3d, 0x7e, 0x1b,
+ 0xd1, 0x3a, 0xf3, 0xe3, 0x33, 0x39, 0x9d, 0xf7, 0xd8, 0x50, 0x11, 0x6f,
+ 0xdf, 0x7b, 0x77, 0x16, 0x4e, 0xda, 0x4f, 0x71, 0x9c, 0x25, 0xff, 0x64,
+ 0xbb, 0x30, 0xa7, 0x74, 0xaa, 0xd4, 0xa4, 0x0d, 0xfa, 0x03, 0x98, 0x2f,
+ 0xd0, 0x8c, 0x7b, 0x5f, 0x11, 0xdf, 0x78, 0xc7, 0x01, 0x3a, 0x81, 0xae,
+ 0x09, 0x1d, 0xb5, 0x8a, 0x71, 0xf2, 0x2b, 0x92, 0x73, 0xfb, 0x4b, 0x07,
+ 0x73, 0x58, 0xf3, 0xd5, 0x2f, 0x1b, 0x83, 0x73, 0x63, 0x0e, 0xbc, 0x3f,
+ 0x3e, 0x43, 0xfa, 0xe4, 0xd9, 0x84, 0xd5, 0xd4, 0x2a, 0xd7, 0x33, 0x20,
+ 0xd3, 0x2b, 0x83, 0x32, 0x87, 0xdf, 0xc2, 0x8a, 0x7b, 0x6f, 0x1b, 0xd0,
+ 0xad, 0xa7, 0x0b, 0x86, 0xe6, 0xd7, 0x39, 0x9b, 0x31, 0x13, 0xf0, 0x8a,
+ 0xce, 0xa9, 0x62, 0x5f, 0xc6, 0x89, 0x06, 0x29, 0x1f, 0xed, 0x06, 0xe4,
+ 0xea, 0x46, 0x9d, 0x7a, 0x2a, 0xeb, 0xcd, 0x78, 0xd8, 0xdf, 0x2d, 0x0b,
+ 0xc0, 0xbb, 0x0a, 0x64, 0x67, 0xfe, 0xcd, 0x80, 0xcc, 0x15, 0x74, 0x3c,
+ 0x39, 0xfc, 0x17, 0x65, 0x4b, 0xad, 0x3e, 0x21, 0xb7, 0xeb, 0x51, 0xfd,
+ 0x8d, 0x72, 0x2d, 0xff, 0x0b, 0x9f, 0xbc, 0x32, 0xa2, 0xf3, 0xea, 0xa2,
+ 0x15, 0x79, 0xaa, 0x9f, 0x3a, 0xcf, 0xba, 0xce, 0xb1, 0x03, 0x76, 0x40,
+ 0xe7, 0x78, 0x0f, 0x3a, 0xc7, 0x6f, 0xa0, 0x73, 0xfc, 0xba, 0x04, 0x7c,
+ 0x29, 0x65, 0x3c, 0xfc, 0x9f, 0x01, 0x0e, 0x51, 0x56, 0x9b, 0xe7, 0x71,
+ 0xa7, 0x33, 0x39, 0xd0, 0xe0, 0x47, 0x92, 0x01, 0xde, 0x26, 0x65, 0x73,
+ 0x75, 0x5a, 0xb6, 0x56, 0xdd, 0x3c, 0xe5, 0xfb, 0xcc, 0x01, 0x1b, 0xe3,
+ 0x3d, 0x45, 0x81, 0x43, 0x47, 0x24, 0x72, 0x9a, 0xf8, 0xd1, 0x21, 0x6b,
+ 0xc5, 0xdf, 0x69, 0x1c, 0x5a, 0x2b, 0xb2, 0xec, 0x17, 0x9d, 0x4f, 0x76,
+ 0x6e, 0x47, 0x2a, 0x76, 0x03, 0xf5, 0xc7, 0xb4, 0x0f, 0xc8, 0xf5, 0xc9,
+ 0x13, 0x2f, 0x3f, 0xf7, 0xee, 0x5e, 0xe9, 0x3c, 0xbb, 0x59, 0xa3, 0x1b,
+ 0xed, 0x9a, 0xd8, 0x35, 0xe4, 0xc6, 0xbc, 0xd5, 0xdf, 0xd0, 0x06, 0x73,
+ 0x94, 0xba, 0x65, 0x03, 0x32, 0xa4, 0x11, 0xed, 0xd6, 0xba, 0x5f, 0x23,
+ 0x3a, 0xa8, 0x73, 0x77, 0x39, 0x4e, 0xbe, 0x68, 0xc9, 0x7c, 0xd1, 0x0c,
+ 0xe7, 0x40, 0x7f, 0xb7, 0x61, 0xab, 0x6d, 0xe2, 0x0e, 0xb6, 0x70, 0x06,
+ 0xdb, 0x75, 0xca, 0xf9, 0x2f, 0x34, 0xf6, 0xae, 0xd5, 0x3f, 0xc3, 0x38,
+ 0xe6, 0xf9, 0x84, 0x3c, 0xee, 0x23, 0x06, 0xd2, 0x1f, 0x95, 0xd2, 0xfd,
+ 0xdd, 0x7e, 0x9b, 0x68, 0xbb, 0x55, 0x27, 0x1e, 0x8b, 0x5c, 0x2d, 0x58,
+ 0x90, 0x25, 0xbf, 0x0a, 0x51, 0x07, 0x28, 0xab, 0x66, 0x3f, 0xc7, 0x5b,
+ 0xb3, 0xe3, 0x1c, 0xb5, 0xb8, 0xae, 0xa8, 0x87, 0xdb, 0x94, 0xfd, 0x3b,
+ 0x5a, 0xee, 0x17, 0x4a, 0x17, 0xe4, 0x1d, 0xdc, 0xb7, 0xab, 0xe3, 0x64,
+ 0xe5, 0x16, 0x74, 0xbc, 0x7a, 0xa9, 0x99, 0xd7, 0x3d, 0x89, 0x73, 0x32,
+ 0xd5, 0xfc, 0xf2, 0x75, 0xb9, 0x76, 0x63, 0x57, 0xbd, 0x71, 0x23, 0xa2,
+ 0xae, 0x2f, 0x0f, 0xa9, 0xfc, 0xb2, 0xe3, 0xfc, 0xd3, 0x9e, 0x95, 0x3b,
+ 0xab, 0x8e, 0x9c, 0xb5, 0x7d, 0xfd, 0x7e, 0x69, 0xe6, 0xd6, 0x39, 0x4e,
+ 0x07, 0xb0, 0x79, 0xfb, 0xa4, 0xe3, 0x3c, 0x3d, 0x36, 0x26, 0xd1, 0x93,
+ 0xd4, 0x51, 0x9e, 0x0b, 0x31, 0x3f, 0x96, 0x98, 0x93, 0xb4, 0xac, 0xcb,
+ 0x15, 0xa5, 0x80, 0x6f, 0xdd, 0xae, 0xfe, 0xf2, 0xcc, 0x31, 0x2f, 0x56,
+ 0x72, 0xe7, 0x35, 0xfa, 0x92, 0x43, 0xff, 0xe5, 0x4b, 0x36, 0xe4, 0x62,
+ 0x71, 0x04, 0xfd, 0x83, 0xf2, 0xc3, 0x62, 0xe0, 0x50, 0xd9, 0xc0, 0x73,
+ 0x54, 0xe5, 0x8b, 0x8f, 0x9c, 0x21, 0x1d, 0x33, 0x80, 0x4e, 0x62, 0x38,
+ 0xce, 0x9c, 0xcd, 0xf9, 0xba, 0x31, 0xdf, 0x8e, 0x71, 0x0c, 0xf2, 0xff,
+ 0xac, 0x96, 0xcf, 0x17, 0x15, 0x6c, 0x5f, 0xf0, 0x77, 0x50, 0xd2, 0x45,
+ 0xc8, 0x78, 0xc5, 0x9c, 0x53, 0xea, 0x0a, 0x66, 0x68, 0x0e, 0xd8, 0x31,
+ 0x0b, 0xbc, 0x79, 0x49, 0xc7, 0x56, 0x4f, 0x68, 0xec, 0x99, 0x67, 0x39,
+ 0x2b, 0x89, 0x8a, 0xdd, 0xa3, 0xcf, 0x6f, 0xf7, 0xf6, 0x2f, 0x43, 0xee,
+ 0x9d, 0x83, 0x8f, 0xb3, 0x4a, 0xda, 0x60, 0x03, 0xa5, 0xd6, 0xcf, 0x81,
+ 0x27, 0x42, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xc8, 0xef, 0x86, 0xf6,
+ 0x23, 0xba, 0xf1, 0x8a, 0x86, 0xc1, 0x76, 0x17, 0xd0, 0xaf, 0x5d, 0x92,
+ 0xcb, 0x6d, 0x1a, 0x57, 0x9f, 0xac, 0x4b, 0x40, 0x0f, 0xf9, 0x3e, 0xca,
+ 0x7e, 0xd4, 0x85, 0xbd, 0xb2, 0x0f, 0xe5, 0x19, 0x94, 0x5b, 0xf0, 0x64,
+ 0x9b, 0x61, 0xe8, 0x15, 0x78, 0xbe, 0x8d, 0xf1, 0xc6, 0xb0, 0xe6, 0xac,
+ 0x21, 0x1f, 0x9e, 0xa1, 0x2c, 0x19, 0x55, 0xcc, 0x63, 0x9e, 0xb3, 0xf0,
+ 0xac, 0x0d, 0xa9, 0xd4, 0x12, 0xcb, 0x78, 0x96, 0xdd, 0xef, 0x4f, 0x60,
+ 0x12, 0xfa, 0x24, 0x6f, 0xb8, 0x98, 0xf4, 0xe1, 0x1e, 0x26, 0xb1, 0xae,
+ 0x5d, 0xd2, 0xcb, 0xe4, 0x75, 0x03, 0xf4, 0xd6, 0x29, 0xa9, 0x1b, 0x41,
+ 0xad, 0x8f, 0x56, 0x40, 0x8b, 0x1b, 0xa0, 0xab, 0x35, 0xd0, 0x54, 0xb2,
+ 0x68, 0xc6, 0x67, 0x54, 0x58, 0xfb, 0x02, 0x5e, 0x00, 0xbd, 0x76, 0xbc,
+ 0x49, 0x5d, 0x94, 0xbc, 0x1c, 0x05, 0xed, 0x89, 0xd3, 0x61, 0x59, 0x99,
+ 0xa8, 0xb2, 0x40, 0x83, 0xa0, 0xcb, 0xa2, 0xcb, 0xd3, 0xef, 0x2b, 0x8d,
+ 0xab, 0xf1, 0x07, 0x12, 0x4b, 0x3c, 0x10, 0x13, 0x58, 0x60, 0xda, 0x1f,
+ 0x88, 0x8d, 0x31, 0x27, 0xe4, 0x26, 0xe6, 0xf1, 0x81, 0xbf, 0x47, 0x4e,
+ 0x69, 0xfe, 0x8e, 0x8b, 0xff, 0x30, 0x8f, 0x83, 0xde, 0x80, 0x41, 0x2e,
+ 0x4f, 0x27, 0x3c, 0x1a, 0xfd, 0x26, 0xf8, 0xd7, 0x84, 0x25, 0x16, 0x94,
+ 0x05, 0xf0, 0xff, 0x06, 0xbe, 0xdf, 0xad, 0x0f, 0xab, 0xf9, 0x25, 0xe5,
+ 0xe5, 0x92, 0x7c, 0x07, 0x7a, 0xf2, 0x43, 0x9c, 0x5d, 0x97, 0xd6, 0xdd,
+ 0x23, 0x63, 0x8c, 0x9f, 0x65, 0xd4, 0x35, 0xeb, 0xb4, 0xec, 0x8e, 0x4e,
+ 0xa0, 0x7c, 0x0c, 0x4f, 0x1f, 0xce, 0x21, 0xa0, 0xe3, 0xdf, 0x6b, 0x05,
+ 0x5b, 0xb9, 0xff, 0xd3, 0x30, 0x8e, 0xbe, 0xc4, 0xb2, 0x93, 0xf8, 0x4e,
+ 0x5f, 0x0c, 0xf7, 0x06, 0x9d, 0x49, 0x85, 0x74, 0xbe, 0x69, 0x05, 0xba,
+ 0xc4, 0x3a, 0xc6, 0xbb, 0x47, 0x5f, 0x5e, 0x0d, 0x3c, 0x3c, 0xfa, 0x2f,
+ 0x27, 0x11, 0x64, 0x4e, 0xfb, 0x17, 0x21, 0x57, 0xfe, 0x7d, 0xea, 0xec,
+ 0x5a, 0xf3, 0x71, 0x1f, 0x5e, 0x3e, 0x32, 0x82, 0x68, 0x0b, 0x59, 0x06,
+ 0x59, 0x54, 0xd6, 0xf4, 0xcb, 0x76, 0x6e, 0xdf, 0x7c, 0x2d, 0x66, 0xdc,
+ 0x17, 0xb7, 0xef, 0x82, 0x45, 0xb9, 0xd3, 0x0e, 0x7c, 0x09, 0x6b, 0xbd,
+ 0xf2, 0x9e, 0x95, 0x03, 0x2a, 0x98, 0xe1, 0x0c, 0x68, 0xb4, 0x4d, 0xcc,
+ 0xe8, 0x94, 0xec, 0xcf, 0x3b, 0xa7, 0xfb, 0xb2, 0x6d, 0xb3, 0x6f, 0x73,
+ 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, 0x36, 0x34, 0x8d, 0x36,
+ 0x6a, 0x03, 0xfd, 0x2e, 0x8d, 0x36, 0xf7, 0x11, 0xfc, 0x3f, 0xfb, 0x20,
+ 0x9d, 0xd8, 0xca, 0x8d, 0xd3, 0xe3, 0x59, 0xe3, 0x79, 0x0e, 0x83, 0x36,
+ 0x0e, 0xd2, 0x4f, 0xd3, 0xb7, 0xe8, 0xd2, 0xcf, 0xd3, 0x7b, 0xf4, 0x43,
+ 0xba, 0xe9, 0x94, 0xf4, 0x0d, 0x4b, 0xa6, 0x8b, 0xfa, 0xbe, 0xa1, 0x6b,
+ 0xd2, 0x67, 0x34, 0x01, 0xba, 0x21, 0xad, 0x93, 0xb7, 0x0c, 0x29, 0x83,
+ 0x8e, 0xca, 0xc0, 0xa7, 0x32, 0x68, 0xaa, 0x02, 0x7c, 0x2b, 0x03, 0xdf,
+ 0xca, 0x75, 0x33, 0x5a, 0xc5, 0x9e, 0x29, 0xb3, 0xd7, 0x41, 0x47, 0x1b,
+ 0x75, 0xde, 0xbf, 0x5e, 0xb3, 0x41, 0x39, 0x78, 0x77, 0xef, 0xee, 0xff,
+ 0x81, 0xbb, 0x1f, 0x94, 0xdb, 0xb0, 0x5b, 0xde, 0x29, 0x8d, 0x02, 0x93,
+ 0x04, 0x18, 0x65, 0x83, 0x36, 0xe2, 0xb2, 0x59, 0x9a, 0x94, 0x2d, 0xc8,
+ 0xa7, 0xed, 0xd5, 0x08, 0xf4, 0xe9, 0x90, 0xcc, 0xbf, 0x35, 0x22, 0xb7,
+ 0x56, 0x95, 0xcc, 0x82, 0x7e, 0xf3, 0x6b, 0xf4, 0xbb, 0x83, 0x9e, 0xcb,
+ 0x9d, 0x3a, 0x4e, 0x9f, 0xae, 0xba, 0xfe, 0xf7, 0xa9, 0x6a, 0x97, 0x4c,
+ 0x57, 0x0d, 0x79, 0xbe, 0xda, 0x23, 0x2f, 0x56, 0x83, 0x72, 0x16, 0x76,
+ 0xe0, 0xd7, 0xaa, 0x03, 0xf2, 0x52, 0x75, 0x50, 0xbe, 0x5e, 0x0b, 0xcb,
+ 0x37, 0x6a, 0x96, 0x64, 0x6b, 0x51, 0xc9, 0xd4, 0x46, 0xe5, 0x85, 0x1a,
+ 0xfd, 0xea, 0x98, 0x0f, 0xbf, 0xd4, 0x9e, 0xbf, 0x82, 0xeb, 0xea, 0xc0,
+ 0xba, 0xa2, 0x6a, 0x4a, 0xc7, 0x29, 0x25, 0xeb, 0xfa, 0x3c, 0x44, 0x2e,
+ 0x61, 0xac, 0xc5, 0xb7, 0x94, 0x54, 0xf4, 0xfc, 0xcd, 0xff, 0x33, 0x09,
+ 0x68, 0xdb, 0xe8, 0x52, 0x79, 0x00, 0x6d, 0x20, 0xf7, 0x0a, 0x4d, 0xdf,
+ 0x47, 0xd3, 0xe7, 0xdf, 0xb4, 0xbd, 0x7c, 0xda, 0x6f, 0x7d, 0x97, 0xb6,
+ 0x97, 0x3e, 0x7b, 0xe2, 0x07, 0xed, 0x9c, 0x9b, 0xda, 0x6f, 0xb2, 0x1f,
+ 0xdb, 0x68, 0xce, 0xbb, 0x98, 0x7d, 0xf2, 0xff, 0x59, 0xdc, 0x18, 0xd5,
+ 0xc5, 0xda, 0x00, 0xff, 0xaf, 0x05, 0x6b, 0xf9, 0xf2, 0xdc, 0xf1, 0xe9,
+ 0x52, 0x5a, 0x3d, 0x5f, 0xa2, 0x46, 0xe3, 0xc8, 0xe2, 0x5e, 0x4e, 0xdc,
+ 0x73, 0xb2, 0x66, 0x07, 0xf4, 0x1a, 0x5c, 0x5f, 0x7d, 0x42, 0xe7, 0xc7,
+ 0xa5, 0x4f, 0x91, 0xfe, 0x18, 0x7b, 0xeb, 0xf2, 0xe2, 0x09, 0xd0, 0x6d,
+ 0x6d, 0x43, 0xae, 0x56, 0x5d, 0x9f, 0xd5, 0xbc, 0xa6, 0x97, 0x7b, 0xa0,
+ 0x39, 0xc6, 0x1c, 0xdc, 0x67, 0xae, 0xec, 0xf6, 0x4d, 0xe1, 0xde, 0x60,
+ 0x8f, 0x63, 0xbf, 0xbe, 0x1e, 0xce, 0xc5, 0xff, 0xe3, 0x41, 0xd9, 0x5b,
+ 0x2f, 0x73, 0x8d, 0x2d, 0x4d, 0x8b, 0x6e, 0x5c, 0x37, 0x2a, 0xaf, 0xe2,
+ 0xfc, 0x2a, 0x06, 0xd7, 0xdf, 0x21, 0x95, 0x28, 0x6d, 0x5b, 0xe2, 0xf7,
+ 0x29, 0x29, 0x63, 0x9e, 0x4a, 0xb4, 0xe9, 0x0f, 0x73, 0x71, 0xb6, 0x62,
+ 0xec, 0xcf, 0x3b, 0x53, 0x3e, 0x8e, 0x77, 0xd4, 0x45, 0xa1, 0x33, 0x9d,
+ 0xe3, 0xfb, 0x22, 0xca, 0xf4, 0x8d, 0xcc, 0xe3, 0x19, 0xf2, 0xea, 0xde,
+ 0xeb, 0xd7, 0xba, 0xfa, 0xe4, 0x7e, 0xbf, 0xd9, 0xb2, 0x99, 0x4b, 0xfa,
+ 0x63, 0xca, 0xf7, 0xf3, 0xdf, 0xf7, 0x13, 0x73, 0x8f, 0x5b, 0xfc, 0x05,
+ 0xe4, 0x33, 0x43, 0xfb, 0x14, 0xbc, 0x6f, 0x47, 0xe4, 0x65, 0x83, 0x79,
+ 0xec, 0x09, 0x95, 0x2e, 0x5d, 0xf7, 0x72, 0x7c, 0x63, 0xea, 0x78, 0xe5,
+ 0x7e, 0xbf, 0x9b, 0xf3, 0xce, 0xb1, 0x0f, 0xe6, 0xb9, 0x1f, 0xa4, 0x13,
+ 0xe6, 0xbb, 0xb7, 0xef, 0xfd, 0x0f, 0x55, 0xa5, 0x00, 0xbc, 0xb3, 0x5a,
+ 0x34, 0x3f, 0xe6, 0x6b, 0xff, 0x76, 0x76, 0x34, 0x3f, 0x37, 0x7d, 0x0c,
+ 0x7f, 0xee, 0xa7, 0x6d, 0x4b, 0xdc, 0xb8, 0xea, 0xe6, 0x8e, 0x6a, 0x1b,
+ 0x1a, 0x58, 0x81, 0x3a, 0xf2, 0x2a, 0xf8, 0x64, 0xaf, 0x2d, 0xff, 0xfe,
+ 0x03, 0x9a, 0xb8, 0x8a, 0x6c, 0x8c, 0x67, 0x00, 0x00, 0x00 };
static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = {
- 0x08004050, 0x08003f50, 0x08003ff4, 0x0800400c, 0x08004024, 0x08004044,
- 0x08004050, 0x08004050, 0x08003f58, 0x00000000, 0x08004a0c, 0x08004a44,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004a7c, 0x08004c40,
- 0x08004b88, 0x08004bc0, 0x08004c40, 0x08004b10, 0x08004c40, 0x08004c40,
- 0x08004bc0, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c00,
- 0x08004c40, 0x08004c00, 0x08004b88, 0x08004c40, 0x08004c40, 0x08004c00,
- 0x08004c00, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40,
- 0x08004aec, 0x00000000, 0x08006058, 0x08006070, 0x08006070, 0x08006070,
- 0x08006058, 0x08006070, 0x08006070, 0x08006070, 0x08006058, 0x08006070,
- 0x08006070, 0x08006070, 0x08006058, 0x08006070, 0x08006070, 0x08006070,
- 0x08006064, 0x00000000, 0x00000000 };
+ 0x08004070, 0x08003f70, 0x08004014, 0x0800402c, 0x08004044, 0x08004064,
+ 0x08004070, 0x08004070, 0x08003f78, 0x00000000, 0x08004a2c, 0x08004a64,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004a9c, 0x08004c60,
+ 0x08004ba8, 0x08004be0, 0x08004c60, 0x08004b30, 0x08004c60, 0x08004c60,
+ 0x08004be0, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c20,
+ 0x08004c60, 0x08004c20, 0x08004ba8, 0x08004c60, 0x08004c60, 0x08004c20,
+ 0x08004c20, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
+ 0x08004b0c, 0x00000000, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
+ 0x08006078, 0x08006090, 0x08006090, 0x08006090, 0x08006078, 0x08006090,
+ 0x08006090, 0x08006090, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
+ 0x08006084, 0x00000000, 0x00000000 };
static struct fw_info bnx2_rxp_fw_09 = {
+ /* Firmware version: 3.7.1 */
.ver_major = 0x3,
- .ver_minor = 0x4,
- .ver_fix = 0x3,
+ .ver_minor = 0x7,
+ .ver_fix = 0x1,
.start_addr = 0x08003184,
.text_addr = 0x08000000,
- .text_len = 0x6768,
+ .text_len = 0x6788,
.text_index = 0x0,
.gz_text = bnx2_RXP_b09FwText,
.gz_text_len = sizeof(bnx2_RXP_b09FwText),
- .data_addr = 0x08006a00,
+ .data_addr = 0x08006a20,
.data_len = 0x0,
.data_index = 0x0,
.data = bnx2_RXP_b09FwData,
- .sbss_addr = 0x08006a00,
+ .sbss_addr = 0x08006a20,
.sbss_len = 0x20,
.sbss_index = 0x0,
- .bss_addr = 0x08006a20,
+ .bss_addr = 0x08006a40,
.bss_len = 0x13dc,
.bss_index = 0x0,
- .rodata_addr = 0x08006768,
+ .rodata_addr = 0x08006788,
.rodata_len = 0x278,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b09FwRodata,
};
static u8 bnx2_TPAT_b09FwText[] = {
-/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
- 0xcd, 0x58,
- 0x5d, 0x68, 0x1c, 0xd7, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0x52, 0x24, 0xeb,
- 0x5a, 0xd9, 0xa6, 0xeb, 0xa0, 0x34, 0x33, 0xda, 0x91, 0xac, 0x22, 0x13,
- 0x4f, 0x9d, 0x25, 0x16, 0x65, 0x21, 0x93, 0xd9, 0x91, 0xac, 0x98, 0x3c,
- 0x28, 0xc5, 0x90, 0x87, 0x52, 0x50, 0x57, 0x32, 0x09, 0x79, 0x69, 0xda,
- 0xc6, 0x90, 0x3e, 0x79, 0x3b, 0x2b, 0xc7, 0x0e, 0x6c, 0xbc, 0x8d, 0x52,
- 0xe4, 0x52, 0xfa, 0x60, 0xd6, 0xb1, 0x05, 0xcd, 0x46, 0x93, 0xd4, 0x7e,
- 0x35, 0x36, 0x4e, 0x93, 0xa7, 0x42, 0x9f, 0x52, 0xf4, 0x18, 0xd2, 0x12,
- 0xda, 0x52, 0x8a, 0x69, 0xa1, 0x09, 0x8d, 0xeb, 0xdb, 0xef, 0xdc, 0x99,
- 0x91, 0x57, 0xb6, 0xec, 0xa4, 0x25, 0x85, 0x0a, 0x56, 0x77, 0xe6, 0xce,
- 0x3d, 0xe7, 0x9e, 0x7b, 0xee, 0x77, 0xbe, 0x73, 0xee, 0x2d, 0xeb, 0x34,
- 0x48, 0xd9, 0xdf, 0x30, 0x7e, 0x2f, 0x7e, 0xf7, 0x85, 0x17, 0xab, 0x8f,
- 0x3c, 0xea, 0x10, 0x3d, 0xfa, 0x88, 0x66, 0x98, 0x06, 0x7d, 0x09, 0x7f,
- 0x50, 0x22, 0x72, 0xfd, 0xfc, 0x23, 0x5b, 0xaf, 0x9d, 0x72, 0x42, 0x8f,
- 0x6c, 0xa3, 0x26, 0xbe, 0xbe, 0xe4, 0x11, 0x05, 0xbd, 0x69, 0xa7, 0x4e,
- 0xff, 0x92, 0xcd, 0x92, 0x49, 0xdc, 0xff, 0x50, 0xed, 0xc6, 0xfe, 0xcb,
- 0x07, 0xdd, 0xeb, 0x67, 0x0d, 0xb2, 0x45, 0x6d, 0xd1, 0x16, 0x93, 0x64,
- 0x8f, 0xd5, 0x9a, 0xce, 0x2f, 0xf6, 0x1e, 0x28, 0xd0, 0xae, 0x5c, 0x97,
- 0xa0, 0xb8, 0x43, 0x4d, 0xab, 0x66, 0x53, 0xd4, 0x7e, 0x49, 0x0b, 0x3b,
- 0x9e, 0x98, 0x85, 0x8e, 0xa0, 0x04, 0xfd, 0x1e, 0xde, 0x13, 0x53, 0x8b,
- 0xce, 0xd8, 0xa4, 0xd7, 0x02, 0x3c, 0x4f, 0x51, 0xab, 0x23, 0xe5, 0x2b,
- 0xbe, 0x46, 0x4b, 0xbe, 0x4d, 0x8b, 0xc2, 0x0d, 0x1c, 0xed, 0xa6, 0xac,
- 0x4c, 0x48, 0xf9, 0x9c, 0xaf, 0x93, 0xee, 0xcd, 0x69, 0xe1, 0xfa, 0xbc,
- 0x56, 0x5f, 0x9f, 0x67, 0x7f, 0xc0, 0xbe, 0x39, 0x2d, 0x58, 0xe7, 0xb6,
- 0x66, 0xd7, 0xdb, 0xbb, 0x68, 0xb1, 0x44, 0x23, 0xba, 0x37, 0x85, 0xf9,
- 0x4a, 0xd0, 0xe3, 0x50, 0xe8, 0x4f, 0x0b, 0x9d, 0x2a, 0xf8, 0x0d, 0xd0,
- 0xac, 0x4f, 0x03, 0xba, 0xa7, 0x53, 0xa3, 0xa4, 0xd1, 0x1b, 0x55, 0x0b,
- 0xbf, 0xc3, 0x5a, 0xb4, 0xfe, 0x7c, 0xa6, 0x87, 0xc7, 0xdb, 0xf8, 0xc6,
- 0x36, 0xb3, 0x7c, 0xbf, 0xec, 0x30, 0x9e, 0x9f, 0xc3, 0x38, 0x8b, 0xc2,
- 0xea, 0xed, 0xdf, 0x06, 0xf0, 0xac, 0xa1, 0xff, 0x30, 0xec, 0x62, 0x3d,
- 0x0e, 0xec, 0x28, 0xd3, 0x4a, 0x67, 0x1e, 0xeb, 0x29, 0x50, 0x53, 0x4c,
- 0x4c, 0x35, 0xc8, 0x84, 0x8c, 0x41, 0x41, 0xe9, 0x8a, 0xd4, 0x6b, 0x52,
- 0x86, 0x55, 0x6f, 0xaa, 0xab, 0xe6, 0xd0, 0xc9, 0xf0, 0x0a, 0x14, 0xf9,
- 0xc3, 0xd4, 0x12, 0x06, 0xc5, 0xfb, 0x2c, 0x0a, 0x16, 0x4c, 0xac, 0x71,
- 0x14, 0x72, 0x1a, 0xe4, 0x5f, 0xcb, 0xf6, 0xbc, 0x48, 0xb1, 0x28, 0xa0,
- 0x7f, 0x84, 0xe2, 0xd2, 0x6e, 0x4d, 0xaf, 0xbd, 0x82, 0xfe, 0x09, 0xd1,
- 0xa5, 0x53, 0x68, 0x35, 0xbc, 0xef, 0xc6, 0x58, 0x7e, 0xd7, 0xa0, 0x8f,
- 0x44, 0x98, 0x78, 0xd4, 0x4a, 0x72, 0x59, 0xee, 0x4f, 0xfb, 0x9a, 0xc9,
- 0xed, 0xfb, 0xed, 0xc1, 0x4e, 0x41, 0x27, 0x3a, 0xb3, 0x98, 0x8f, 0x9a,
- 0x46, 0x0d, 0xe3, 0xb0, 0x37, 0xbc, 0xbf, 0x81, 0xc2, 0xc1, 0xe3, 0xdc,
- 0xcf, 0x7f, 0xe8, 0x77, 0xc8, 0xa8, 0xf1, 0xb7, 0x6f, 0x52, 0xfa, 0x2d,
- 0xb5, 0x3f, 0xf4, 0x1f, 0xcb, 0xde, 0x4b, 0x22, 0x3c, 0xf3, 0x28, 0xd6,
- 0xa8, 0x60, 0x83, 0xe7, 0x02, 0xf0, 0x11, 0xcf, 0xe8, 0xd4, 0x2c, 0x17,
- 0xc9, 0xf5, 0x8f, 0xa2, 0xf7, 0xd7, 0x6d, 0x83, 0xea, 0xec, 0x2b, 0xdf,
- 0xcc, 0x64, 0x18, 0x1b, 0x1f, 0x64, 0x76, 0x0a, 0x5a, 0x3c, 0x22, 0xe5,
- 0x8a, 0x2f, 0xa5, 0x55, 0xf3, 0x9c, 0x13, 0x34, 0x5d, 0x36, 0x69, 0x52,
- 0xa0, 0x85, 0x8f, 0xbd, 0x72, 0x83, 0x2c, 0x60, 0xa1, 0x1f, 0xff, 0xfc,
- 0xf7, 0xa6, 0x86, 0x25, 0xd0, 0xb5, 0x36, 0xeb, 0x98, 0x70, 0x66, 0x95,
- 0x8c, 0x94, 0xf1, 0xcc, 0xbd, 0x64, 0x2e, 0x65, 0x32, 0x52, 0x46, 0x55,
- 0x81, 0x3d, 0x6f, 0x0a, 0xd8, 0x87, 0x75, 0x31, 0xc6, 0x89, 0xa2, 0x9e,
- 0x6f, 0x37, 0xda, 0xb0, 0xd1, 0x43, 0xdb, 0x13, 0xf0, 0x0f, 0x51, 0x0b,
- 0x63, 0xf5, 0xea, 0x7d, 0x8c, 0x0d, 0xec, 0xef, 0x82, 0x1d, 0xb5, 0xdd,
- 0xf2, 0x29, 0x5a, 0xb0, 0xeb, 0xbd, 0xe9, 0xf2, 0x32, 0x3d, 0xc4, 0x73,
- 0xd8, 0x56, 0xed, 0x88, 0xdd, 0x55, 0x72, 0x88, 0xc4, 0x41, 0x3c, 0xf7,
- 0x88, 0xe2, 0x36, 0x69, 0xa1, 0x7f, 0x1f, 0xaf, 0x15, 0x72, 0xf3, 0x99,
- 0xdc, 0x7c, 0x26, 0x37, 0x92, 0xc9, 0x3d, 0xd5, 0x27, 0xf7, 0x14, 0xcb,
- 0x61, 0x6c, 0x90, 0x8d, 0x0d, 0xb2, 0xb1, 0x66, 0x36, 0x36, 0xca, 0xc6,
- 0xa2, 0xed, 0x8d, 0xc1, 0x36, 0x77, 0xca, 0xd1, 0x6c, 0x8a, 0x3d, 0xf9,
- 0x70, 0xe8, 0x53, 0x50, 0xf7, 0xdc, 0xcd, 0xba, 0x31, 0x42, 0xe7, 0xfc,
- 0x21, 0x5a, 0x49, 0xc6, 0x28, 0x4e, 0x56, 0x28, 0x4c, 0x74, 0xc8, 0x8e,
- 0x50, 0xd7, 0xbb, 0x2e, 0x67, 0x7d, 0x1f, 0x7b, 0x66, 0xb3, 0x5c, 0x79,
- 0x96, 0x1c, 0x7c, 0x9f, 0x16, 0xcb, 0xe4, 0x03, 0x2b, 0x3a, 0xf6, 0xad,
- 0xa2, 0x9e, 0xe3, 0xc4, 0xe7, 0x35, 0x37, 0xf5, 0xaa, 0x2b, 0x62, 0x72,
- 0xcb, 0xa1, 0x41, 0x42, 0xaf, 0xc1, 0x4f, 0x49, 0x93, 0xa2, 0xc4, 0xa6,
- 0x0f, 0x8d, 0x97, 0x54, 0x8c, 0xc6, 0x9d, 0x4d, 0x79, 0x79, 0xaf, 0x43,
- 0x57, 0x30, 0xcf, 0xc5, 0xa4, 0x4c, 0xbf, 0x4a, 0x4a, 0xf4, 0x4e, 0x42,
- 0x7a, 0xe8, 0x03, 0xc3, 0x25, 0x41, 0x6f, 0x27, 0xfd, 0x3e, 0xff, 0x88,
- 0x7d, 0x6e, 0xdf, 0x5f, 0x23, 0x7b, 0xb4, 0xc6, 0x38, 0x4b, 0x39, 0xa0,
- 0x9e, 0x72, 0x80, 0xc2, 0x52, 0xab, 0x13, 0x3f, 0x68, 0x80, 0x7f, 0x96,
- 0xfc, 0x60, 0xb7, 0xa1, 0xf6, 0xa3, 0x89, 0x3d, 0xcc, 0x5b, 0xde, 0x9b,
- 0xab, 0xce, 0x92, 0xe7, 0x9e, 0xaa, 0x33, 0x6a, 0x4f, 0x5b, 0x39, 0x2e,
- 0xfb, 0xe6, 0xf8, 0x33, 0xe6, 0x18, 0xa2, 0x06, 0xe2, 0xec, 0x09, 0x13,
- 0xb1, 0xe3, 0xfd, 0xdd, 0x60, 0x5c, 0x39, 0x1b, 0x8c, 0x6f, 0xa2, 0xf1,
- 0x0d, 0x9b, 0xd6, 0xdb, 0x45, 0x72, 0xba, 0x43, 0xb4, 0xd4, 0x19, 0xa4,
- 0xca, 0x05, 0x13, 0x63, 0xef, 0xa3, 0xca, 0xaa, 0x5e, 0xe2, 0x38, 0xae,
- 0xc3, 0xc7, 0xe3, 0x5d, 0x09, 0x7c, 0x0e, 0xd2, 0xf8, 0x9a, 0xab, 0xb0,
- 0xb3, 0xe4, 0xb5, 0x7c, 0x83, 0x7e, 0x4c, 0xd7, 0xf6, 0x15, 0xb0, 0xa6,
- 0x12, 0xf9, 0x93, 0xfd, 0xf3, 0xe9, 0x80, 0x18, 0xf7, 0xc5, 0x45, 0xda,
- 0xe5, 0x3a, 0xa4, 0xb3, 0x3e, 0x9b, 0xc6, 0x2f, 0xd8, 0x5a, 0xbd, 0xc3,
- 0x3e, 0x63, 0xfc, 0xd9, 0x19, 0xfe, 0x4c, 0x2d, 0x3c, 0x53, 0xc4, 0x5c,
- 0x7f, 0x91, 0xa1, 0x27, 0xb1, 0x0f, 0x3a, 0x2d, 0x55, 0x7f, 0x04, 0xfb,
- 0xd0, 0xd7, 0xe5, 0x6f, 0xd7, 0xb3, 0x7e, 0xd6, 0x01, 0x7e, 0xf0, 0xef,
- 0xa7, 0x90, 0xb9, 0xe0, 0x08, 0xcb, 0x14, 0x69, 0x7c, 0x95, 0xf9, 0x05,
- 0x6d, 0x97, 0xdf, 0x79, 0x6d, 0x03, 0xd4, 0x80, 0x57, 0x1a, 0x53, 0x25,
- 0xd8, 0xa5, 0x2b, 0xbe, 0x68, 0x80, 0x3f, 0x74, 0x6f, 0x10, 0x2d, 0xcf,
- 0xf7, 0x73, 0x23, 0x8f, 0xa9, 0xb8, 0x33, 0x44, 0x75, 0xe0, 0xd7, 0x84,
- 0x3d, 0xcb, 0x34, 0x51, 0x3e, 0xaa, 0xbe, 0xa1, 0xaf, 0xc7, 0xdf, 0xc4,
- 0x6d, 0xdf, 0xf0, 0xde, 0xcb, 0x6d, 0x40, 0x6c, 0x7b, 0x2d, 0xcc, 0x62,
- 0x65, 0x7e, 0xe1, 0xf1, 0xcd, 0x32, 0xf6, 0x06, 0x7c, 0x46, 0xf0, 0x25,
- 0x51, 0xb7, 0x6d, 0x82, 0x6f, 0xf4, 0xaf, 0xea, 0x2c, 0x57, 0x62, 0x3d,
- 0x58, 0xff, 0x9a, 0xa9, 0xd5, 0xcf, 0x78, 0xce, 0x1f, 0x88, 0xe5, 0x2b,
- 0xf0, 0xc1, 0xc4, 0x4c, 0x8b, 0xc7, 0xf7, 0x2c, 0xf2, 0x56, 0x9b, 0xc2,
- 0xc4, 0x9e, 0xc2, 0x73, 0x54, 0xff, 0xc9, 0x08, 0xf6, 0xda, 0x75, 0x5a,
- 0xf4, 0x5b, 0xd8, 0x53, 0x20, 0xaf, 0x6b, 0xd2, 0x1b, 0x6d, 0xf6, 0x85,
- 0x4d, 0x95, 0x35, 0x29, 0x4f, 0xfa, 0xbc, 0x27, 0xbf, 0x83, 0x5f, 0x08,
- 0x2b, 0x9c, 0x98, 0xf9, 0x08, 0xfb, 0xb3, 0xde, 0xe3, 0xbd, 0xb1, 0x94,
- 0x4f, 0xbc, 0xd5, 0x29, 0xec, 0xeb, 0x54, 0x66, 0x23, 0xef, 0x97, 0x49,
- 0x2b, 0x55, 0x9d, 0xce, 0x57, 0x3f, 0x93, 0xba, 0xc7, 0xfc, 0x5a, 0x80,
- 0x6f, 0x31, 0xae, 0x8b, 0x71, 0x49, 0x01, 0x3e, 0xfc, 0x07, 0x78, 0x45,
- 0xca, 0xf3, 0x55, 0xf4, 0xaf, 0x1e, 0x87, 0xad, 0x06, 0x64, 0x53, 0x8c,
- 0xb1, 0x3d, 0x73, 0xed, 0x7c, 0x7d, 0xde, 0xcc, 0x7b, 0x4a, 0xdf, 0x10,
- 0x4d, 0x6e, 0x0c, 0xd1, 0xb3, 0xbd, 0x21, 0x1a, 0x3f, 0xcd, 0x32, 0xe0,
- 0xa6, 0xaa, 0x27, 0x22, 0xc6, 0xa8, 0xa7, 0xfc, 0x50, 0x36, 0x74, 0x5e,
- 0x27, 0xbe, 0x6f, 0x10, 0x2d, 0xf7, 0x78, 0x0e, 0xb3, 0x4f, 0xa7, 0x4e,
- 0x87, 0x7e, 0x4a, 0x74, 0xa8, 0xc7, 0xb2, 0x5b, 0xbe, 0x83, 0x5e, 0x01,
- 0x9d, 0x82, 0x38, 0x0f, 0x19, 0x1e, 0xf2, 0xdd, 0x7a, 0x88, 0xfc, 0x15,
- 0xe1, 0x37, 0x87, 0x9c, 0xc6, 0xeb, 0x9f, 0x42, 0xfc, 0x31, 0x8f, 0xdf,
- 0xc4, 0xda, 0x0b, 0xb4, 0xe2, 0xcf, 0x63, 0x0c, 0xef, 0xf1, 0x61, 0x7c,
- 0x1f, 0x46, 0x1e, 0xc8, 0xf2, 0x84, 0xe0, 0x3c, 0xb1, 0x1b, 0x71, 0x30,
- 0x00, 0xee, 0xdf, 0x63, 0x6e, 0xcf, 0x13, 0x18, 0x57, 0xda, 0x83, 0xbc,
- 0x70, 0x3f, 0xfa, 0x59, 0xd7, 0x28, 0xda, 0x01, 0xbc, 0xef, 0xc1, 0xd8,
- 0xfe, 0x1c, 0x91, 0xcb, 0xdd, 0x2d, 0x3f, 0x20, 0x26, 0x56, 0x11, 0x2b,
- 0x6b, 0x9c, 0x27, 0x38, 0x16, 0x79, 0x4f, 0x8b, 0xe0, 0x6f, 0x1b, 0x3a,
- 0x78, 0x6f, 0x8b, 0xd8, 0x43, 0xce, 0x71, 0x82, 0x2a, 0x1b, 0x3b, 0xe5,
- 0x0f, 0x5e, 0x0f, 0x38, 0xec, 0x34, 0xaf, 0xc5, 0x15, 0x0d, 0xf0, 0x59,
- 0xb8, 0x31, 0x8d, 0xef, 0xc8, 0x85, 0x22, 0xb2, 0x1b, 0xa7, 0x53, 0x2e,
- 0x6b, 0x6c, 0x8c, 0x29, 0x9c, 0xc6, 0x89, 0xc0, 0x3b, 0x73, 0x59, 0xce,
- 0x5d, 0x8c, 0x25, 0x0a, 0x20, 0xbb, 0x19, 0x1a, 0x52, 0x2e, 0xf9, 0x23,
- 0xd4, 0x00, 0x2e, 0x03, 0xf0, 0x59, 0x03, 0x7c, 0x56, 0xef, 0xe3, 0xb3,
- 0xfa, 0xe7, 0xf2, 0x19, 0xb8, 0xaa, 0x03, 0xae, 0xea, 0x80, 0xab, 0x50,
- 0x1b, 0xbc, 0x03, 0xec, 0xbf, 0xdd, 0xd9, 0x89, 0xe3, 0x98, 0xdf, 0x98,
- 0xe7, 0xa6, 0xe8, 0xf2, 0xde, 0xff, 0x94, 0xe7, 0x8e, 0x83, 0x13, 0x6c,
- 0xfa, 0xfe, 0xde, 0x7b, 0x73, 0xdd, 0x09, 0x70, 0x9d, 0xf5, 0xf9, 0x5c,
- 0xd7, 0x64, 0xae, 0x33, 0x81, 0xbd, 0x26, 0x78, 0x40, 0x5f, 0xed, 0x9f,
- 0xe7, 0x24, 0xe6, 0xe1, 0x3e, 0x33, 0xcb, 0xa5, 0x3a, 0x75, 0x81, 0x7b,
- 0xc3, 0xe3, 0x79, 0x60, 0x73, 0x92, 0x72, 0xd1, 0x13, 0x66, 0x89, 0xac,
- 0x49, 0xe0, 0x61, 0x75, 0x88, 0x8c, 0xd3, 0xb7, 0xf0, 0x8e, 0x7a, 0x00,
- 0x71, 0x8e, 0x7f, 0x1b, 0xb9, 0x8e, 0x41, 0x70, 0x8d, 0x49, 0x85, 0x55,
- 0x0b, 0xef, 0xda, 0xb6, 0x71, 0x87, 0x90, 0x6f, 0x8c, 0x9a, 0x3b, 0xf3,
- 0x7b, 0x7e, 0xee, 0xf1, 0x98, 0x41, 0xd2, 0xd7, 0x5c, 0xc7, 0xd1, 0x5d,
- 0xff, 0x1a, 0xb8, 0xe1, 0x7d, 0x8f, 0xf9, 0x2f, 0x06, 0x0a, 0x0a, 0x64,
- 0xae, 0xca, 0xe3, 0x56, 0x8d, 0xe7, 0x6e, 0x3a, 0x88, 0x73, 0xe7, 0x35,
- 0xe0, 0x87, 0x73, 0xe7, 0xf9, 0x2a, 0xd7, 0x7b, 0x69, 0x8c, 0xb6, 0x7a,
- 0xf9, 0x9c, 0xa3, 0xb0, 0xdb, 0x82, 0x4c, 0xff, 0x58, 0xc6, 0x8b, 0x94,
- 0xcf, 0x62, 0x4d, 0x06, 0xe6, 0xb1, 0xd6, 0x6c, 0x2a, 0xac, 0xb1, 0x5f,
- 0x5c, 0xc8, 0x57, 0xc4, 0x1c, 0x6d, 0x6e, 0xe3, 0x83, 0x93, 0xbd, 0x0f,
- 0x4c, 0xe6, 0x50, 0x03, 0xb1, 0x59, 0xc4, 0xbc, 0xd6, 0x96, 0x2e, 0xca,
- 0x74, 0xb1, 0xbc, 0x57, 0x7e, 0x76, 0x4b, 0x9e, 0x79, 0x6d, 0xa2, 0xcc,
- 0xfc, 0xc5, 0x76, 0x18, 0x8a, 0x4b, 0x07, 0x33, 0x2e, 0xad, 0x60, 0x3f,
- 0x07, 0x55, 0x5c, 0xea, 0xde, 0xc3, 0x19, 0x9f, 0xee, 0x46, 0xcb, 0x7d,
- 0x37, 0xb2, 0x38, 0x31, 0x61, 0x2f, 0xeb, 0x1d, 0x24, 0x03, 0x76, 0x45,
- 0x6a, 0x4d, 0x7f, 0x93, 0x4b, 0x1e, 0x73, 0x04, 0xe3, 0x53, 0x71, 0x29,
- 0xfa, 0x27, 0x60, 0x33, 0xf3, 0x02, 0xcb, 0xb1, 0xfc, 0x4e, 0x72, 0x7f,
- 0x85, 0x9c, 0xd8, 0x41, 0x0e, 0x7d, 0x1b, 0x2c, 0xc3, 0xdc, 0x30, 0x8a,
- 0xf1, 0x21, 0xf3, 0x02, 0x7c, 0xc6, 0xb2, 0xe5, 0x2c, 0x0e, 0x23, 0x7c,
- 0xe3, 0xba, 0x97, 0xe3, 0x23, 0x20, 0xab, 0xc6, 0xeb, 0xe0, 0x9a, 0x98,
- 0xf3, 0x22, 0xd7, 0xa1, 0x5c, 0x6f, 0xe6, 0xf5, 0xa9, 0x37, 0x35, 0x7b,
- 0xb7, 0x5a, 0x53, 0xf4, 0xd7, 0x9a, 0xe8, 0xd8, 0xb1, 0xd6, 0xf4, 0xac,
- 0xb4, 0xd6, 0xac, 0x58, 0x77, 0xaf, 0x35, 0x73, 0xd9, 0x7b, 0xd7, 0x9a,
- 0x71, 0x87, 0xf7, 0x08, 0xb9, 0x54, 0xf0, 0x5a, 0xa8, 0x69, 0x66, 0x7c,
- 0x11, 0xdd, 0xc6, 0x17, 0xd1, 0x69, 0xb7, 0x7c, 0x8e, 0x38, 0xa6, 0xdd,
- 0x72, 0x8b, 0x6b, 0xa0, 0x0d, 0xae, 0x81, 0x0c, 0xe4, 0xd2, 0x7e, 0xce,
- 0xc8, 0x7d, 0xc2, 0xbe, 0x1c, 0x04, 0x27, 0xb3, 0x1f, 0x8b, 0x19, 0x3f,
- 0xa0, 0xf5, 0x3e, 0x05, 0x3f, 0xe4, 0xbc, 0xc2, 0x3e, 0xfb, 0x7f, 0xe2,
- 0x15, 0xb2, 0x07, 0xc0, 0x0f, 0x36, 0xea, 0xcd, 0x46, 0x47, 0xd9, 0x02,
- 0x5f, 0x48, 0x39, 0xe7, 0x33, 0xf6, 0x53, 0xbe, 0x50, 0x3e, 0x51, 0x78,
- 0x2c, 0xd2, 0xbb, 0x3e, 0x63, 0x01, 0xe7, 0x23, 0x8f, 0x73, 0x22, 0xf3,
- 0xef, 0x4d, 0xf9, 0xae, 0x17, 0xa2, 0x2f, 0xc2, 0x9e, 0x33, 0x0e, 0xe6,
- 0xb5, 0x43, 0xeb, 0x36, 0xe4, 0x18, 0x0b, 0xe5, 0x3b, 0xce, 0x3d, 0xe9,
- 0xf9, 0x84, 0x6b, 0xe1, 0xff, 0x16, 0x1b, 0x17, 0xef, 0x82, 0x8d, 0x37,
- 0x33, 0x6c, 0xfc, 0xf2, 0x1e, 0xd8, 0xb8, 0xf8, 0x05, 0xb1, 0xe1, 0x3a,
- 0x1f, 0xa3, 0x5e, 0x7a, 0xcf, 0x63, 0x7c, 0x48, 0xf9, 0xb1, 0xbf, 0x53,
- 0x3e, 0x09, 0x6c, 0xe3, 0xd5, 0x9b, 0x32, 0xce, 0x72, 0x89, 0xfe, 0xd6,
- 0xad, 0x5c, 0x32, 0xfe, 0x6a, 0x8a, 0x8b, 0xf1, 0xb7, 0xa4, 0x3c, 0xb7,
- 0x03, 0x0e, 0xb8, 0x56, 0xbe, 0x0a, 0x1e, 0x68, 0xd1, 0xff, 0xa2, 0x56,
- 0x66, 0xce, 0xae, 0xda, 0x47, 0xdb, 0xf9, 0xbe, 0xe7, 0x7b, 0x5e, 0xa0,
- 0xb3, 0x62, 0x17, 0xfc, 0xb5, 0x9f, 0x5a, 0xaf, 0x9b, 0x7c, 0x7e, 0x00,
- 0x1e, 0x1e, 0x37, 0x39, 0x56, 0x71, 0x56, 0xc4, 0x73, 0x7f, 0x3d, 0x0d,
- 0x3c, 0xfa, 0xbc, 0x76, 0xb5, 0xee, 0x3e, 0xae, 0xff, 0x1e, 0x4a, 0x92,
- 0x3b, 0xf2, 0xc8, 0xb6, 0x73, 0xb3, 0x81, 0x73, 0x73, 0x5d, 0xe9, 0xe0,
- 0xb3, 0x55, 0xea, 0xbf, 0x13, 0xea, 0xac, 0x7c, 0x53, 0x9e, 0x53, 0xe7,
- 0xe5, 0xd1, 0x02, 0x0d, 0xce, 0x67, 0x58, 0x61, 0x5f, 0x0c, 0xab, 0x7a,
- 0x82, 0x31, 0xd5, 0x42, 0xbe, 0x5d, 0x82, 0x3f, 0x1a, 0x2a, 0x16, 0xb0,
- 0xf6, 0xcc, 0x1f, 0x2d, 0xf8, 0xa3, 0x9e, 0xa4, 0x31, 0xf1, 0xe5, 0x9e,
- 0x1d, 0xfe, 0x88, 0x7c, 0x6a, 0x2f, 0x9a, 0x38, 0x6f, 0x5f, 0x49, 0x54,
- 0xfe, 0x5c, 0x68, 0xb5, 0xa9, 0xf9, 0x60, 0xed, 0x38, 0xd7, 0x6d, 0x5c,
- 0x77, 0xcd, 0x2c, 0x55, 0xd1, 0xd7, 0xb3, 0x29, 0x84, 0x4f, 0xbe, 0x7d,
- 0x90, 0x16, 0x8d, 0x1a, 0xe3, 0x17, 0xef, 0x09, 0x35, 0xc3, 0x83, 0xa8,
- 0xa5, 0x92, 0xb1, 0x45, 0xbd, 0x36, 0x06, 0x1c, 0x35, 0x29, 0x80, 0x9d,
- 0x01, 0x74, 0xcf, 0xb5, 0x6d, 0x7b, 0xb9, 0xcd, 0x67, 0xa4, 0x26, 0xf1,
- 0x19, 0xbc, 0xdb, 0xbb, 0x0e, 0x7d, 0x03, 0xcf, 0xe0, 0xcc, 0xea, 0xc4,
- 0xc0, 0xd5, 0xcb, 0x89, 0x45, 0xad, 0x12, 0xdf, 0x51, 0x30, 0x57, 0x96,
- 0xa1, 0xe3, 0x99, 0x42, 0x8a, 0xcb, 0x32, 0xf4, 0x70, 0xcc, 0x10, 0xe6,
- 0x63, 0xff, 0xe5, 0x58, 0x2b, 0xf7, 0xd5, 0xee, 0x85, 0xec, 0xbc, 0x4a,
- 0xca, 0x07, 0xec, 0xdf, 0xd0, 0x7b, 0xbe, 0x90, 0xdf, 0xc7, 0xb4, 0x10,
- 0xf3, 0x8d, 0x7d, 0x8c, 0x43, 0x0d, 0x78, 0xc3, 0x98, 0x84, 0xfb, 0x90,
- 0x57, 0xf6, 0x21, 0x37, 0x97, 0x8a, 0xaa, 0x6d, 0x26, 0xc7, 0xb2, 0xf1,
- 0xba, 0x1a, 0xc7, 0x39, 0x21, 0x4e, 0xd4, 0x59, 0x41, 0x8b, 0x3a, 0xe4,
- 0x34, 0x7c, 0x9c, 0x81, 0x50, 0x5b, 0xac, 0x24, 0x9c, 0xcf, 0xf7, 0xd9,
- 0xba, 0xe2, 0xb9, 0x4d, 0xc8, 0xe0, 0x79, 0x83, 0xf4, 0x86, 0xcf, 0xf7,
- 0x07, 0xd9, 0xdd, 0x46, 0x89, 0x86, 0x21, 0x0f, 0xbb, 0xc6, 0xd8, 0xae,
- 0xa0, 0xa1, 0x6a, 0x11, 0xd6, 0xbd, 0x5f, 0x4f, 0xef, 0x5c, 0x7e, 0x93,
- 0xcd, 0x65, 0x83, 0x5f, 0x08, 0xe7, 0x1d, 0x9f, 0xf3, 0xda, 0xd7, 0x0c,
- 0xba, 0x4e, 0x8a, 0x23, 0xc5, 0x37, 0x90, 0xef, 0x0e, 0x42, 0x26, 0x50,
- 0xfc, 0x92, 0x9e, 0x19, 0x72, 0x99, 0x8a, 0xb1, 0x5d, 0xc7, 0x77, 0xcc,
- 0xed, 0xef, 0x01, 0x62, 0xab, 0x9a, 0xcd, 0xd7, 0x8f, 0xd3, 0x4d, 0xe0,
- 0x74, 0xb3, 0xb0, 0x75, 0xee, 0x28, 0x15, 0x30, 0x8e, 0x6d, 0x64, 0x2e,
- 0x61, 0x99, 0x4f, 0xac, 0xed, 0x7a, 0x2a, 0x3b, 0xe8, 0xf8, 0x53, 0x9f,
- 0x8e, 0x12, 0xaf, 0x4d, 0x34, 0xd2, 0xf3, 0xb3, 0xfa, 0x6b, 0xc0, 0xcf,
- 0x38, 0x6f, 0x3c, 0xa0, 0x63, 0x1d, 0x5c, 0x7f, 0xd5, 0x55, 0x3f, 0x0e,
- 0x56, 0xdb, 0xf4, 0xfe, 0x30, 0x9b, 0x67, 0x5f, 0x1a, 0x0f, 0x1e, 0xda,
- 0x64, 0xb3, 0xcf, 0x76, 0x6b, 0x87, 0x79, 0x91, 0xd8, 0xbd, 0x19, 0x8d,
- 0xf1, 0x66, 0xd4, 0x38, 0x07, 0xe3, 0x79, 0x0b, 0x1f, 0x8c, 0xd5, 0xcf,
- 0xc7, 0xa8, 0xf5, 0x05, 0x31, 0xfa, 0x46, 0x9b, 0xb9, 0x22, 0xc5, 0x68,
- 0xe3, 0x0e, 0x8c, 0xa2, 0x06, 0x2a, 0xe5, 0xf8, 0xe4, 0x78, 0xc9, 0xf1,
- 0x99, 0x3f, 0xf3, 0xfd, 0x08, 0x38, 0x38, 0xe3, 0xb6, 0x18, 0xdc, 0x16,
- 0xa9, 0x1c, 0xe7, 0x96, 0x23, 0x4a, 0xe3, 0x78, 0x19, 0x71, 0x1c, 0x19,
- 0x9c, 0xf3, 0x38, 0x86, 0x59, 0x8e, 0xe3, 0x98, 0xe5, 0x46, 0x32, 0x39,
- 0xb4, 0x88, 0xe7, 0x28, 0x8b, 0xe7, 0x16, 0x78, 0x37, 0xca, 0xe2, 0xb9,
- 0x85, 0x18, 0x5e, 0xc9, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0xdf, 0xdb, 0x19,
- 0x55, 0x95, 0x8b, 0x9d, 0x3a, 0x78, 0x6d, 0x45, 0xe9, 0x6c, 0x62, 0x9d,
- 0xb0, 0xb1, 0x93, 0xc7, 0xc5, 0x1d, 0xf7, 0x5b, 0x58, 0xcf, 0xad, 0xbc,
- 0x32, 0x8b, 0xbc, 0x72, 0x0e, 0x79, 0xa5, 0xdb, 0x77, 0xbf, 0x75, 0x56,
- 0xe5, 0x95, 0x27, 0x8b, 0x79, 0x5e, 0xe9, 0x66, 0x79, 0xa5, 0xab, 0xf2,
- 0xca, 0x13, 0x45, 0xce, 0x2b, 0x31, 0x05, 0xc5, 0xfe, 0xbc, 0x12, 0x6f,
- 0xcb, 0x2b, 0xb9, 0x2c, 0xf7, 0xef, 0x94, 0x57, 0x72, 0x9f, 0x71, 0x6e,
- 0xb1, 0x72, 0x5e, 0xbd, 0x2d, 0x9f, 0xe4, 0x63, 0xd8, 0x56, 0xe6, 0x25,
- 0xe6, 0xe0, 0xb4, 0xae, 0xbf, 0x92, 0xe4, 0xb1, 0x74, 0x0c, 0xf3, 0xe0,
- 0xbd, 0xb3, 0x53, 0x2c, 0xd9, 0x59, 0x2c, 0x0d, 0xa7, 0x32, 0x9d, 0xfe,
- 0x78, 0x3a, 0x56, 0xdc, 0x1e, 0x4f, 0xb9, 0x9e, 0x3c, 0x9e, 0x52, 0x9d,
- 0x1f, 0x1a, 0x65, 0xae, 0x07, 0x70, 0x96, 0x76, 0xfd, 0x39, 0xf4, 0x5e,
- 0xe8, 0x4d, 0xa3, 0xae, 0x36, 0xe9, 0x6a, 0xce, 0x37, 0xea, 0xbe, 0x07,
- 0x6d, 0x2f, 0xb7, 0xb5, 0xb8, 0xf5, 0xad, 0x8b, 0xda, 0xfa, 0x7d, 0xf0,
- 0xc8, 0x79, 0xf5, 0xfd, 0x33, 0x79, 0xb5, 0x84, 0x33, 0xb0, 0x97, 0x8f,
- 0x7b, 0x1d, 0xf3, 0xb9, 0xe2, 0x2c, 0x9e, 0x5e, 0xee, 0xdd, 0x82, 0xf9,
- 0x8a, 0xc7, 0x7d, 0xff, 0x44, 0x0e, 0x41, 0x5d, 0xbe, 0x35, 0x96, 0xcf,
- 0x38, 0x1e, 0xd6, 0xec, 0xd0, 0xa5, 0x6d, 0xe7, 0x9c, 0xf4, 0x7c, 0x83,
- 0x75, 0xa3, 0x3e, 0xe1, 0x3a, 0x25, 0xfc, 0x8a, 0x4e, 0x2f, 0xd1, 0xb7,
- 0x7c, 0xee, 0xd3, 0x69, 0xf6, 0x31, 0x29, 0x5f, 0x40, 0xcd, 0xf2, 0xf4,
- 0xb6, 0x9a, 0xa5, 0x48, 0xe3, 0x07, 0xfa, 0xcf, 0x87, 0x37, 0xe5, 0xf8,
- 0xa4, 0x7b, 0x36, 0xa0, 0x40, 0x9b, 0x5d, 0xe7, 0x5a, 0x76, 0xab, 0x76,
- 0x25, 0x1a, 0xbd, 0x21, 0xf5, 0x49, 0xce, 0x85, 0x57, 0x33, 0x5f, 0xe1,
- 0xdb, 0x99, 0x1b, 0xe0, 0xd6, 0x48, 0xdd, 0xf1, 0x06, 0xeb, 0x3c, 0x0f,
- 0xbf, 0xa3, 0x4d, 0xb8, 0xbe, 0xb9, 0xdb, 0xbd, 0xab, 0x89, 0x7d, 0x71,
- 0x9d, 0xa3, 0x06, 0xa9, 0xbb, 0x8b, 0x25, 0xdf, 0xfd, 0x59, 0x8b, 0x52,
- 0x9e, 0x88, 0xfc, 0x05, 0xd8, 0x02, 0x9c, 0x8b, 0x45, 0xec, 0xcd, 0x24,
- 0x78, 0xc9, 0x75, 0x0e, 0xe8, 0x42, 0x61, 0x7f, 0x19, 0xba, 0x8d, 0x03,
- 0x5c, 0x3f, 0x7e, 0x2a, 0x97, 0x7b, 0x2a, 0x07, 0xfb, 0x8c, 0x91, 0x7a,
- 0xb2, 0x5b, 0xe7, 0x36, 0x48, 0xf8, 0xb9, 0x80, 0x79, 0x9c, 0xbb, 0xe0,
- 0xa7, 0x24, 0xa2, 0x33, 0x8e, 0x98, 0xed, 0x38, 0x62, 0xae, 0xa3, 0x03,
- 0xdd, 0xb6, 0x4d, 0xbb, 0xb0, 0x27, 0xc8, 0xc1, 0xf4, 0x00, 0x6c, 0xb9,
- 0xe0, 0x88, 0x3a, 0x6a, 0xc1, 0x1f, 0x18, 0xae, 0x78, 0x9a, 0x3e, 0xc1,
- 0x1a, 0x6f, 0xc8, 0xf4, 0xde, 0xc5, 0x11, 0xd1, 0xd6, 0xdc, 0x37, 0x30,
- 0x37, 0xdb, 0xc4, 0x31, 0xca, 0xf9, 0x72, 0x5e, 0x5b, 0x80, 0x8f, 0x8e,
- 0xac, 0x6b, 0xe0, 0x35, 0xce, 0x97, 0x23, 0xd9, 0xfd, 0x12, 0xf6, 0x07,
- 0xeb, 0xbf, 0x74, 0x47, 0xad, 0x99, 0xd7, 0x94, 0xe9, 0xdd, 0x69, 0x3c,
- 0xc3, 0xf3, 0x13, 0x6c, 0x99, 0x98, 0xba, 0xa0, 0xce, 0x3d, 0xd3, 0xa8,
- 0xf1, 0xb8, 0x95, 0xa8, 0x83, 0xf8, 0xae, 0x8b, 0x6b, 0x27, 0x89, 0xf8,
- 0x4f, 0x9f, 0x63, 0x3e, 0x13, 0xcd, 0xb0, 0x0e, 0x3e, 0x1b, 0x71, 0xfc,
- 0xfc, 0x1b, 0x2f, 0xf3, 0x0a, 0xbd, 0x68, 0x18, 0x00, 0x00, 0x00 };
+ 0xcd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0xde,
+ 0x38, 0xf1, 0x24, 0x19, 0xca, 0xa6, 0x72, 0xe9, 0x8c, 0x3d, 0x76, 0x8c,
+ 0x6c, 0x35, 0xd3, 0x76, 0xd5, 0x58, 0x68, 0xa4, 0x4e, 0x67, 0x76, 0x1d,
+ 0x2b, 0xf4, 0xc1, 0x85, 0x48, 0x3c, 0xf0, 0xe2, 0xae, 0x1d, 0x05, 0x78,
+ 0x2a, 0x28, 0x0f, 0x11, 0x2f, 0x59, 0x76, 0x37, 0xfd, 0x41, 0xdb, 0x2c,
+ 0x35, 0xc8, 0x41, 0x02, 0xa4, 0xb0, 0x69, 0xe2, 0x97, 0xad, 0x27, 0x2d,
+ 0x45, 0xea, 0x4b, 0x95, 0x28, 0x55, 0x2b, 0xc4, 0x13, 0x2f, 0x54, 0x79,
+ 0xac, 0x52, 0x5a, 0xf1, 0x00, 0x28, 0x42, 0x15, 0xaa, 0x68, 0xf0, 0xe5,
+ 0x3b, 0x77, 0x66, 0xdc, 0xdd, 0xc4, 0x49, 0xcb, 0x9f, 0x84, 0xa5, 0xf5,
+ 0x9d, 0xb9, 0xf7, 0x9e, 0x73, 0xcf, 0x3d, 0x3f, 0xdf, 0x39, 0x67, 0xca,
+ 0x2a, 0x95, 0x28, 0xfb, 0xdb, 0x8d, 0xdf, 0xc9, 0xa7, 0x9f, 0x39, 0x79,
+ 0xf8, 0xa1, 0x47, 0x1d, 0xa2, 0x87, 0x1f, 0x52, 0x94, 0xa2, 0x46, 0xff,
+ 0x85, 0x3f, 0x30, 0xb1, 0x72, 0xfe, 0xfc, 0x23, 0x53, 0x0d, 0x7e, 0xe3,
+ 0x44, 0x1e, 0x99, 0x5a, 0xb0, 0xf4, 0xe5, 0x15, 0x8f, 0x28, 0xec, 0xcf,
+ 0x3a, 0x31, 0xfd, 0x43, 0x34, 0x6c, 0x9d, 0x78, 0xfe, 0x81, 0xe0, 0xd6,
+ 0xa1, 0x37, 0x0f, 0xbb, 0x37, 0xcf, 0x6b, 0x64, 0x5a, 0xc1, 0xb2, 0x69,
+ 0x4d, 0x93, 0x39, 0x1e, 0x5c, 0x75, 0x7e, 0x7e, 0x30, 0x28, 0xd0, 0x9e,
+ 0x9c, 0x97, 0x4d, 0xcd, 0x2e, 0x35, 0xf4, 0xc0, 0xa4, 0x5a, 0xe7, 0x94,
+ 0x12, 0x75, 0x3d, 0xab, 0x0a, 0x1e, 0xa1, 0x0d, 0xfe, 0x1e, 0xde, 0x13,
+ 0x5d, 0xa9, 0x9e, 0x33, 0x49, 0x0d, 0x42, 0x3c, 0xcf, 0x51, 0xab, 0x2b,
+ 0xc4, 0x0f, 0x7d, 0x85, 0x56, 0x7c, 0x93, 0x96, 0x2d, 0x77, 0x31, 0x54,
+ 0xb6, 0x44, 0x3c, 0x25, 0xc4, 0xb7, 0x7d, 0x95, 0x54, 0x6f, 0x41, 0x89,
+ 0x36, 0x16, 0x95, 0x78, 0x63, 0x91, 0xf5, 0x01, 0xf9, 0x16, 0x94, 0x70,
+ 0x83, 0xc7, 0xc0, 0x8c, 0x3b, 0x7b, 0x68, 0xd9, 0xa6, 0x31, 0xd5, 0x9b,
+ 0xc3, 0x79, 0x65, 0xf0, 0x71, 0x28, 0xf2, 0x67, 0x2d, 0x95, 0x26, 0xf1,
+ 0x1b, 0xa1, 0x9a, 0x4f, 0x23, 0xaa, 0xa7, 0x52, 0xdd, 0x56, 0xe8, 0xe5,
+ 0x8a, 0x81, 0xdf, 0x51, 0xa5, 0xba, 0xf1, 0x9d, 0x8c, 0x0f, 0xef, 0x37,
+ 0xb1, 0xc6, 0x32, 0x33, 0xfd, 0x20, 0xed, 0x6e, 0x3c, 0x7f, 0x0b, 0xfb,
+ 0x0c, 0x8a, 0x2a, 0xb7, 0xaf, 0x8d, 0xe0, 0x59, 0xc1, 0xfc, 0x51, 0xc8,
+ 0xc5, 0x7c, 0x1c, 0xc8, 0x31, 0x4e, 0xed, 0xee, 0x22, 0xee, 0x53, 0xa0,
+ 0x86, 0x35, 0x35, 0x53, 0x27, 0x1d, 0x34, 0x1a, 0x85, 0xf6, 0x15, 0xa1,
+ 0x06, 0x42, 0x44, 0x15, 0x6f, 0xa6, 0x27, 0xcf, 0x50, 0x49, 0xf3, 0x0a,
+ 0x54, 0xf5, 0x77, 0x53, 0xcb, 0xd2, 0xa8, 0x39, 0x67, 0x50, 0xb8, 0xa4,
+ 0xe3, 0x8e, 0xfb, 0x40, 0xa7, 0x80, 0xfe, 0xa5, 0xcc, 0xe6, 0x45, 0x6a,
+ 0x5a, 0x05, 0xcc, 0x8f, 0x51, 0xd3, 0xde, 0xab, 0xa8, 0xc1, 0x0b, 0x98,
+ 0x9f, 0xb2, 0x7a, 0xf4, 0x3c, 0x46, 0x05, 0xef, 0x7b, 0xb1, 0x97, 0xdf,
+ 0x15, 0xf0, 0x23, 0x2b, 0x4a, 0x66, 0xa8, 0x95, 0xe4, 0xb4, 0x3c, 0x9f,
+ 0xce, 0x35, 0x92, 0xdb, 0xed, 0x8d, 0x7d, 0xdd, 0x1a, 0x74, 0xcc, 0xb6,
+ 0xc1, 0x9e, 0xdc, 0x2e, 0xd2, 0x07, 0x1e, 0xe7, 0x79, 0xfe, 0xc3, 0xbc,
+ 0x43, 0x5a, 0xe0, 0x59, 0x31, 0x7d, 0x85, 0xd2, 0xb5, 0x54, 0xf6, 0xc8,
+ 0x7f, 0x2c, 0x7b, 0xb7, 0xad, 0xe8, 0xdc, 0xa3, 0xb8, 0x9f, 0x74, 0x19,
+ 0x3c, 0xdb, 0xb8, 0x7f, 0x01, 0xfe, 0xd1, 0x0c, 0x55, 0x6a, 0x94, 0x4d,
+ 0x72, 0xe7, 0x57, 0xb1, 0xf2, 0x41, 0x47, 0xa3, 0x98, 0x75, 0xe5, 0xeb,
+ 0x19, 0x1d, 0xfb, 0xc6, 0xbb, 0x90, 0xb3, 0x61, 0x99, 0x70, 0xbc, 0xe5,
+ 0x63, 0x42, 0x5c, 0xf4, 0x85, 0x28, 0x04, 0xde, 0xcc, 0x25, 0x9a, 0x2d,
+ 0x1b, 0x34, 0x6d, 0x61, 0x84, 0x8e, 0xbd, 0x72, 0x9d, 0x8c, 0x5c, 0x9e,
+ 0xdc, 0x37, 0xf1, 0xd7, 0x57, 0x08, 0x3e, 0x79, 0xa3, 0xf3, 0x7b, 0xd6,
+ 0xc7, 0xcc, 0x82, 0xa4, 0x11, 0xa2, 0x37, 0x7f, 0x2f, 0x9a, 0x5f, 0x67,
+ 0x34, 0x42, 0xd4, 0x2a, 0x7c, 0xae, 0x8b, 0x3b, 0xb3, 0x7f, 0x13, 0xd5,
+ 0xfa, 0xbe, 0x59, 0xef, 0x40, 0x3e, 0x0f, 0x63, 0x9f, 0xa8, 0xde, 0xe5,
+ 0x7b, 0x98, 0xd4, 0x84, 0xde, 0x5a, 0xd8, 0xaf, 0x56, 0x76, 0xb1, 0x7f,
+ 0xc0, 0xc6, 0x4b, 0x66, 0xb5, 0xe3, 0x96, 0x5f, 0xa0, 0x25, 0x33, 0xee,
+ 0xcf, 0x96, 0x57, 0xe9, 0x01, 0x3e, 0xc7, 0x34, 0x82, 0x63, 0x66, 0x4f,
+ 0xd2, 0x1b, 0x1a, 0x95, 0xf0, 0x0c, 0x1e, 0xcd, 0x0e, 0x29, 0x91, 0xbf,
+ 0x8b, 0xef, 0x0b, 0xba, 0xc5, 0x8c, 0x6e, 0x31, 0xa3, 0x1b, 0xcb, 0xe8,
+ 0x9e, 0x1c, 0xa0, 0x7b, 0x92, 0xe9, 0xb0, 0x37, 0xcc, 0xf6, 0x86, 0xd9,
+ 0x5e, 0x3d, 0xdb, 0x5b, 0xcd, 0xf6, 0x62, 0xec, 0x3b, 0x90, 0xcf, 0x9d,
+ 0x09, 0x15, 0xc8, 0xe8, 0x89, 0x07, 0x23, 0x9f, 0xc2, 0xd8, 0x73, 0xaf,
+ 0xc7, 0xda, 0x18, 0x5d, 0xf0, 0x2d, 0x6a, 0x27, 0x0e, 0x64, 0x6f, 0x53,
+ 0x94, 0xa8, 0xa0, 0x1d, 0xa3, 0x9e, 0x77, 0x53, 0xd4, 0xfc, 0x0a, 0x6c,
+ 0x37, 0xca, 0x74, 0xe5, 0x1a, 0x14, 0xd1, 0x4c, 0x66, 0xad, 0x55, 0xaa,
+ 0xc0, 0x5f, 0x54, 0xd8, 0x6f, 0x52, 0x3e, 0x37, 0x93, 0x0a, 0xd6, 0xa9,
+ 0xa1, 0x56, 0x5c, 0xab, 0x49, 0x6e, 0x39, 0xd2, 0xc8, 0x52, 0x03, 0x1b,
+ 0x7b, 0x1a, 0x54, 0x4d, 0x4c, 0x7a, 0x4f, 0x3b, 0x25, 0xe3, 0xb4, 0xd9,
+ 0xbd, 0x2e, 0xde, 0x3c, 0xe8, 0xd0, 0x95, 0x64, 0x9c, 0x7e, 0x95, 0x94,
+ 0xe9, 0xb5, 0xc4, 0xa6, 0x57, 0x13, 0x52, 0x23, 0x1f, 0x7e, 0x6c, 0x5b,
+ 0x74, 0x39, 0x19, 0xd4, 0xfb, 0x07, 0xac, 0x77, 0x73, 0x7f, 0x40, 0xe6,
+ 0xbe, 0x80, 0x1a, 0x5a, 0x90, 0xe2, 0x40, 0x9c, 0xe2, 0x80, 0xf4, 0xa9,
+ 0x56, 0xb7, 0x79, 0xbf, 0x06, 0x0c, 0x5a, 0xf1, 0xc3, 0xbd, 0x1a, 0xec,
+ 0x12, 0x23, 0x0a, 0xd4, 0xed, 0x51, 0xda, 0xc8, 0x5d, 0xf1, 0xdc, 0xe7,
+ 0x63, 0xec, 0xf6, 0xce, 0x1a, 0x98, 0xbd, 0xdd, 0xb6, 0x7f, 0xc6, 0x19,
+ 0xa3, 0xb0, 0x9b, 0x46, 0x4f, 0xe8, 0x88, 0x1f, 0xef, 0x23, 0x8d, 0x63,
+ 0xc0, 0xd9, 0xb4, 0xe9, 0x4c, 0x97, 0x68, 0x62, 0xd3, 0xa4, 0x8d, 0x4e,
+ 0x91, 0x9c, 0xde, 0x28, 0xad, 0x74, 0x4b, 0x34, 0x79, 0x49, 0xc7, 0xde,
+ 0x5d, 0x34, 0xb9, 0xa6, 0xda, 0x1c, 0xcb, 0x31, 0x74, 0x3c, 0xd1, 0x13,
+ 0xf0, 0xd1, 0x12, 0x4d, 0xac, 0xbb, 0xd2, 0x7f, 0x56, 0xbc, 0x96, 0xaf,
+ 0xd1, 0x0f, 0xe8, 0xda, 0x5c, 0x01, 0x77, 0xb2, 0xc9, 0x9f, 0x1e, 0x3c,
+ 0xcf, 0x80, 0x9b, 0xf1, 0x1c, 0x98, 0xee, 0x71, 0x1d, 0x52, 0x99, 0x9f,
+ 0x49, 0x13, 0x97, 0x4c, 0x25, 0xee, 0xb2, 0xce, 0xd8, 0x07, 0xcd, 0xcc,
+ 0x07, 0x75, 0x25, 0x3a, 0x57, 0xc4, 0x59, 0x7f, 0x12, 0x91, 0x07, 0xdf,
+ 0x03, 0x96, 0xad, 0x54, 0xbe, 0x0f, 0xf9, 0x30, 0xd7, 0xe3, 0xb5, 0x9b,
+ 0xd9, 0x3c, 0xf3, 0x00, 0x46, 0xf8, 0xfb, 0x29, 0x62, 0x3c, 0x38, 0xc6,
+ 0x34, 0x45, 0x9a, 0x58, 0x63, 0x8c, 0xc1, 0xd8, 0xe3, 0x77, 0xbe, 0xdb,
+ 0x08, 0xd5, 0xa1, 0x95, 0xfa, 0x8c, 0x0d, 0xb9, 0x54, 0x89, 0x19, 0x75,
+ 0x60, 0x88, 0xea, 0x95, 0x30, 0xf2, 0x79, 0x3f, 0xd3, 0xd2, 0xf8, 0xb7,
+ 0xa5, 0xbd, 0x63, 0xf8, 0xaf, 0x0e, 0x79, 0x56, 0x69, 0xaa, 0x7c, 0x5c,
+ 0xae, 0x61, 0xae, 0xcf, 0x6b, 0xd6, 0x6d, 0x6b, 0x78, 0xef, 0xe7, 0x32,
+ 0x20, 0xc6, 0xbd, 0x16, 0x4e, 0x31, 0x32, 0xbd, 0xf0, 0xfe, 0x46, 0x19,
+ 0xb6, 0x01, 0xa6, 0x11, 0x74, 0x49, 0xd4, 0xeb, 0xe8, 0xc0, 0x1c, 0xf5,
+ 0x8b, 0x2a, 0xd3, 0xd9, 0xcc, 0x07, 0xf7, 0x5f, 0xd7, 0x95, 0xf8, 0x9c,
+ 0xe7, 0xfc, 0x81, 0x98, 0x7e, 0x12, 0x3a, 0x98, 0x9a, 0x6f, 0xf1, 0xfe,
+ 0xbe, 0x41, 0xde, 0x5a, 0xc3, 0xd2, 0x61, 0x53, 0x15, 0x06, 0x8d, 0x7f,
+ 0x34, 0x06, 0x5b, 0xbb, 0x4e, 0x8b, 0x7e, 0x07, 0x79, 0x0a, 0xe4, 0xf5,
+ 0x74, 0x7a, 0xb9, 0xc3, 0xba, 0x30, 0x69, 0x72, 0x5d, 0x88, 0xe7, 0x7c,
+ 0xb6, 0xc9, 0xbb, 0xd0, 0x0b, 0xe1, 0x86, 0x53, 0xf3, 0x37, 0x60, 0x9f,
+ 0x8d, 0x3e, 0xdb, 0xc6, 0x90, 0x3a, 0xf1, 0xd6, 0xe6, 0x60, 0xd7, 0x99,
+ 0x4c, 0x46, 0xb6, 0x97, 0x4e, 0xed, 0x8a, 0x4a, 0x17, 0x2b, 0x9f, 0x08,
+ 0xd5, 0x63, 0x8c, 0x2d, 0x40, 0xb7, 0xd8, 0xd7, 0xc3, 0xbe, 0xa4, 0x00,
+ 0x1d, 0xfe, 0x4d, 0x18, 0xc0, 0xdf, 0x8b, 0x15, 0xcc, 0xaf, 0x9d, 0x86,
+ 0xac, 0x1a, 0x68, 0x53, 0x1f, 0x63, 0x79, 0x16, 0x3a, 0xf9, 0xfd, 0xbc,
+ 0xf9, 0xb7, 0x25, 0xbf, 0x51, 0x9a, 0xde, 0x1c, 0xa5, 0x13, 0xfd, 0x51,
+ 0x9a, 0x38, 0xcb, 0x34, 0x42, 0xb4, 0x2b, 0x8c, 0x91, 0xf0, 0x51, 0x4f,
+ 0xea, 0xa1, 0xac, 0xa9, 0x7c, 0x4f, 0xac, 0x6f, 0x12, 0xad, 0xf6, 0xf9,
+ 0x0c, 0x7d, 0x80, 0xa7, 0x4a, 0x47, 0x7e, 0x42, 0x74, 0xa4, 0xcf, 0xb4,
+ 0xdb, 0xba, 0x03, 0x5f, 0x0b, 0x3c, 0x2d, 0xe2, 0x5c, 0xa4, 0x79, 0xc8,
+ 0x79, 0x1b, 0x11, 0x72, 0x58, 0x15, 0xbf, 0x05, 0xe4, 0x35, 0xbe, 0xff,
+ 0x1c, 0xe2, 0x8f, 0xb1, 0x7c, 0x0b, 0x77, 0x2f, 0x50, 0xdb, 0x5f, 0xc4,
+ 0x1e, 0xb6, 0xf1, 0x51, 0xac, 0xef, 0x46, 0x2e, 0xc8, 0x72, 0x85, 0xc5,
+ 0xb9, 0x62, 0x2f, 0xe2, 0x60, 0x04, 0xf8, 0x7f, 0xbf, 0x3e, 0x9c, 0x2b,
+ 0xb0, 0xcf, 0x3e, 0x80, 0xdc, 0x80, 0x44, 0x5d, 0x62, 0x5e, 0xfb, 0x31,
+ 0x8e, 0xe0, 0xfd, 0x00, 0xf6, 0x0e, 0xe6, 0x89, 0x9c, 0xee, 0x6e, 0x39,
+ 0x02, 0x31, 0xb1, 0x86, 0x58, 0x59, 0x9f, 0x61, 0xcc, 0x80, 0x3d, 0xd8,
+ 0xa6, 0x45, 0x60, 0xb8, 0x09, 0x1e, 0x6c, 0xdb, 0x22, 0x6c, 0xc8, 0x79,
+ 0xce, 0xa2, 0xc9, 0x4d, 0x8e, 0xeb, 0x34, 0x8f, 0xc4, 0xdb, 0x79, 0x84,
+ 0x64, 0x4c, 0x34, 0x13, 0xf6, 0x89, 0xd0, 0x8c, 0xce, 0x6e, 0x09, 0xc4,
+ 0x70, 0x39, 0x66, 0x5c, 0xdb, 0x9c, 0x05, 0xbd, 0x86, 0xf8, 0xa8, 0x9a,
+ 0xf5, 0xb3, 0x29, 0xa6, 0xd5, 0x37, 0x1d, 0xe9, 0x93, 0xcd, 0xc4, 0xc2,
+ 0x3b, 0x63, 0x5a, 0x8e, 0x61, 0x4c, 0x4f, 0x61, 0x04, 0x7c, 0x8b, 0x34,
+ 0x21, 0x56, 0xfc, 0x31, 0xaa, 0xc3, 0x3f, 0x43, 0xe0, 0x5a, 0x1d, 0xb8,
+ 0x16, 0x0f, 0xe0, 0x5a, 0xfc, 0x99, 0xb8, 0x06, 0xcc, 0xea, 0x02, 0xb3,
+ 0x50, 0x23, 0xbc, 0x06, 0x8c, 0x7f, 0x15, 0xe7, 0x5d, 0xee, 0xee, 0x84,
+ 0x75, 0x8c, 0x73, 0x8c, 0x77, 0x33, 0xf4, 0xe6, 0xc1, 0x7f, 0x15, 0xef,
+ 0xda, 0xc0, 0x06, 0x93, 0xbe, 0x7b, 0xf0, 0xde, 0x98, 0x77, 0x06, 0x98,
+ 0x67, 0x7c, 0x36, 0xe6, 0x35, 0x18, 0xf3, 0x74, 0xf8, 0x60, 0x03, 0x78,
+ 0xa0, 0xae, 0x0d, 0x9e, 0xd3, 0xc1, 0x39, 0x3c, 0xa7, 0x67, 0x79, 0x55,
+ 0xa5, 0x1e, 0xfc, 0x5f, 0xf3, 0xf8, 0x9c, 0x39, 0xd6, 0xbb, 0xd4, 0xff,
+ 0x13, 0xba, 0x4d, 0xc6, 0x34, 0xfc, 0x62, 0x6d, 0x94, 0xb4, 0xb3, 0x9f,
+ 0xfa, 0x3d, 0x6a, 0x03, 0xc4, 0x3b, 0xfe, 0x6d, 0xe6, 0x3c, 0x4a, 0xc0,
+ 0x1c, 0x9d, 0x0a, 0x6b, 0x06, 0xde, 0x95, 0xa1, 0x7d, 0x47, 0x90, 0x77,
+ 0xb4, 0xc0, 0x9d, 0x7f, 0x9f, 0x9f, 0xfb, 0xbc, 0xa7, 0x44, 0xea, 0xba,
+ 0xeb, 0x38, 0xaa, 0xeb, 0x5f, 0x03, 0x46, 0xbc, 0xe3, 0x31, 0x0e, 0x36,
+ 0xe1, 0x0d, 0x05, 0xd2, 0xd7, 0xc4, 0x69, 0x23, 0xe0, 0xb3, 0x1b, 0x0e,
+ 0xe2, 0xdd, 0x79, 0x09, 0x7e, 0xc4, 0x39, 0xf4, 0x22, 0xe2, 0xa7, 0x96,
+ 0xc5, 0x6a, 0xab, 0x9f, 0x9f, 0xb9, 0x0f, 0x72, 0x1b, 0xa0, 0x19, 0xdc,
+ 0xcb, 0x71, 0x20, 0xc4, 0x09, 0xdc, 0x49, 0xc3, 0x39, 0xc6, 0xba, 0x49,
+ 0x85, 0x75, 0xd6, 0x8b, 0x0b, 0xfa, 0x49, 0x6b, 0x81, 0xae, 0x0f, 0xe1,
+ 0xc2, 0x73, 0xfd, 0xeb, 0x3a, 0x63, 0xa9, 0x86, 0x18, 0x2d, 0xe2, 0x5c,
+ 0x63, 0x9b, 0x17, 0x65, 0xbc, 0x98, 0xde, 0x2b, 0x9f, 0xd8, 0xa6, 0x67,
+ 0x7c, 0x9b, 0x2a, 0x33, 0x8e, 0xb1, 0x1c, 0x9a, 0xc4, 0xd4, 0x52, 0x86,
+ 0xa9, 0x93, 0xb0, 0x67, 0x49, 0xc6, 0xa7, 0xea, 0x3d, 0x98, 0xe1, 0xea,
+ 0x5e, 0x8c, 0x3c, 0x27, 0xb2, 0x78, 0xd1, 0x21, 0x2f, 0xf3, 0x2d, 0x91,
+ 0xb6, 0xce, 0x35, 0x04, 0xdf, 0xe9, 0xaf, 0xf0, 0x6d, 0xc6, 0x0a, 0xf6,
+ 0x4f, 0x89, 0xa9, 0x98, 0x9f, 0x82, 0xcc, 0x8c, 0x0f, 0x4c, 0xc7, 0xf4,
+ 0x3b, 0xd1, 0xfd, 0x05, 0x74, 0xd6, 0x0e, 0x74, 0x98, 0xdb, 0x64, 0x1a,
+ 0xc6, 0x88, 0x7d, 0xd8, 0x1f, 0x31, 0x3e, 0x40, 0x67, 0x4c, 0x3b, 0x9e,
+ 0xc5, 0x63, 0x15, 0x6b, 0x5c, 0x03, 0xcb, 0xf8, 0x22, 0x23, 0xe0, 0x7b,
+ 0x70, 0x7d, 0xcc, 0xf9, 0x91, 0x6b, 0x52, 0xae, 0x3d, 0xf3, 0x5a, 0xd5,
+ 0x9b, 0xa9, 0xdd, 0xad, 0xee, 0xb4, 0x06, 0xeb, 0xce, 0x43, 0xc6, 0xce,
+ 0x75, 0xe7, 0x41, 0x23, 0xad, 0x3b, 0xa7, 0x8d, 0xbb, 0xd7, 0x9d, 0x39,
+ 0xed, 0xbd, 0xeb, 0xce, 0x66, 0x97, 0xcf, 0xdc, 0x19, 0x2f, 0x56, 0xe0,
+ 0xaf, 0xad, 0x24, 0xbf, 0x27, 0xf7, 0x06, 0xa1, 0x59, 0x3b, 0x9b, 0xda,
+ 0xbe, 0x29, 0x7d, 0x11, 0x38, 0xb2, 0x39, 0x0b, 0x3b, 0xa2, 0xa6, 0x1e,
+ 0xc2, 0x8e, 0x9c, 0x86, 0x75, 0x5a, 0x02, 0x46, 0xb3, 0x3e, 0x8b, 0x19,
+ 0x4e, 0x60, 0xf4, 0x3e, 0x06, 0x4e, 0xe4, 0xf8, 0xc2, 0xfc, 0xfe, 0x9f,
+ 0xf0, 0x85, 0xcc, 0x11, 0xe0, 0x84, 0x19, 0x30, 0x5e, 0x4a, 0x59, 0x50,
+ 0x93, 0x0b, 0xb1, 0xe0, 0x73, 0x0c, 0x0c, 0xf6, 0x4c, 0xec, 0x0f, 0x45,
+ 0x7a, 0xcb, 0x67, 0x9f, 0x40, 0xcf, 0xe4, 0x71, 0x8e, 0x64, 0x3c, 0xde,
+ 0x12, 0x6f, 0x79, 0x11, 0xe6, 0xaa, 0xb0, 0x3d, 0xfb, 0xc3, 0xa2, 0x72,
+ 0x64, 0xc3, 0x04, 0x1d, 0xfb, 0xc4, 0xf8, 0x1d, 0xbd, 0x50, 0xda, 0xb3,
+ 0x70, 0x7d, 0xfc, 0xef, 0xfa, 0xc8, 0x1b, 0x77, 0xf1, 0x91, 0xcb, 0x99,
+ 0x8f, 0x24, 0xf7, 0xf0, 0x91, 0x37, 0x3e, 0xa7, 0x8f, 0xb8, 0xe5, 0x0f,
+ 0x51, 0x3f, 0xbd, 0x0d, 0x39, 0x42, 0x4b, 0x88, 0x0f, 0xfd, 0x9d, 0xfa,
+ 0x94, 0xd0, 0xd4, 0x5f, 0x64, 0x9d, 0xa5, 0x79, 0xa5, 0x85, 0x77, 0xed,
+ 0x15, 0xae, 0x97, 0x39, 0xe7, 0xa4, 0xb9, 0x65, 0xe2, 0xc5, 0xd4, 0x3f,
+ 0x26, 0x5e, 0x11, 0xe2, 0xc2, 0x0e, 0xfe, 0xc0, 0x35, 0xf4, 0x55, 0xf8,
+ 0x55, 0x8b, 0xfe, 0x17, 0x35, 0x34, 0x63, 0x78, 0xc5, 0x3c, 0xde, 0xc9,
+ 0xed, 0x9f, 0xdb, 0xbe, 0x40, 0xe7, 0xad, 0x3d, 0xd0, 0xdb, 0xa3, 0xd4,
+ 0xfa, 0xb1, 0xce, 0x7d, 0x05, 0xfc, 0xe2, 0x71, 0x9d, 0x63, 0x17, 0x7d,
+ 0x24, 0x9e, 0x07, 0xeb, 0x6c, 0xf8, 0xa5, 0x5f, 0xc8, 0xe3, 0x65, 0x00,
+ 0xfb, 0x4f, 0xa1, 0x54, 0xb9, 0x23, 0xaf, 0x0c, 0xf5, 0xd4, 0x1a, 0x7a,
+ 0xea, 0x58, 0xf2, 0xe0, 0xbe, 0x2b, 0xd5, 0x63, 0x5b, 0xf6, 0xd1, 0x5b,
+ 0xa2, 0x25, 0x7b, 0xe9, 0x03, 0x05, 0x2a, 0x2d, 0x66, 0x3e, 0xe3, 0x20,
+ 0x1f, 0xb9, 0x7e, 0x03, 0xfc, 0xb9, 0xd6, 0x80, 0x1c, 0xb4, 0x8a, 0x58,
+ 0xbc, 0x80, 0x3c, 0xbc, 0x02, 0xbd, 0xd4, 0x65, 0x6c, 0x8c, 0xd1, 0x35,
+ 0xe4, 0xfe, 0x36, 0xf2, 0xf3, 0x19, 0xe8, 0xa6, 0x05, 0xdd, 0xc4, 0x49,
+ 0x1a, 0x27, 0xd7, 0xa0, 0x9b, 0x85, 0x01, 0xdd, 0x2c, 0xfc, 0x47, 0xfd,
+ 0xc5, 0x1f, 0x91, 0x6b, 0xcd, 0x65, 0x1d, 0xf3, 0x57, 0x12, 0x99, 0x5b,
+ 0x97, 0x5a, 0x1d, 0x6a, 0xdc, 0x1f, 0x9c, 0xe6, 0xda, 0x8e, 0x6b, 0xb3,
+ 0xf9, 0x95, 0x0a, 0xe6, 0xfa, 0x26, 0x45, 0xd0, 0xcf, 0x37, 0x0f, 0xd3,
+ 0xb2, 0x16, 0xb0, 0x4f, 0xe3, 0x3d, 0xa1, 0x46, 0x74, 0x18, 0xf5, 0x56,
+ 0x32, 0xbe, 0x8c, 0x7e, 0x1c, 0xbe, 0xd5, 0xa0, 0x10, 0x72, 0x86, 0xe0,
+ 0xbd, 0xd0, 0x31, 0xcd, 0xd5, 0x0e, 0xf7, 0x51, 0x0d, 0xe2, 0x5e, 0xbd,
+ 0xd7, 0xbf, 0x09, 0x7e, 0x23, 0xdf, 0x40, 0x7f, 0xeb, 0x34, 0x81, 0xd3,
+ 0xcf, 0xc2, 0x6d, 0x5b, 0x36, 0x7f, 0xcb, 0x60, 0x1c, 0x1d, 0x07, 0x8f,
+ 0xa7, 0x0b, 0xa9, 0xaf, 0x8e, 0x83, 0x0f, 0xc7, 0x11, 0xe1, 0x3c, 0xd6,
+ 0x65, 0xee, 0x7f, 0xe5, 0x81, 0xfa, 0xbe, 0x40, 0x39, 0x86, 0x35, 0xa1,
+ 0x37, 0xd6, 0x75, 0xe4, 0x9d, 0x2c, 0xe4, 0xdf, 0x6d, 0x5a, 0xc0, 0x81,
+ 0xfa, 0x1c, 0x63, 0x96, 0x02, 0xdf, 0xa3, 0xb4, 0xaf, 0x44, 0x1f, 0x52,
+ 0x9f, 0x43, 0xde, 0xb6, 0x8b, 0x72, 0x6c, 0x24, 0xa7, 0xb3, 0xfd, 0xaa,
+ 0xdc, 0xc7, 0xf9, 0xa2, 0x99, 0xc8, 0x7e, 0x42, 0xa9, 0x76, 0xc9, 0xa9,
+ 0xfb, 0xe8, 0x93, 0x50, 0x7b, 0xb4, 0x13, 0xce, 0xf5, 0x73, 0xa6, 0x2a,
+ 0xb1, 0xef, 0x06, 0x68, 0xf0, 0xbc, 0x49, 0x6a, 0xdd, 0xe7, 0xef, 0x0c,
+ 0xfc, 0x0d, 0x04, 0xf1, 0x63, 0xd3, 0x6e, 0xd0, 0x43, 0xae, 0x71, 0x96,
+ 0x2b, 0xac, 0xcb, 0x3a, 0x85, 0x79, 0x1f, 0x52, 0xd3, 0x6f, 0x33, 0xef,
+ 0x66, 0x67, 0x99, 0x88, 0x1f, 0xc6, 0x5d, 0x9f, 0x73, 0xde, 0x97, 0x34,
+ 0xba, 0x49, 0x12, 0x37, 0xad, 0x87, 0x91, 0x0b, 0x0f, 0x83, 0x26, 0x94,
+ 0x98, 0x93, 0xf6, 0x15, 0x39, 0x8d, 0xa7, 0x0d, 0xf3, 0x58, 0xd6, 0x87,
+ 0xdf, 0x43, 0xc4, 0x59, 0x25, 0x3b, 0x6f, 0xd0, 0x67, 0xdf, 0x87, 0xcf,
+ 0xde, 0xc8, 0xf6, 0x00, 0x87, 0xed, 0x02, 0xf6, 0xb1, 0x8c, 0x8c, 0x2f,
+ 0x4c, 0xb3, 0x65, 0x0c, 0xf3, 0x99, 0xdc, 0x81, 0xc7, 0x47, 0x03, 0x3c,
+ 0x6c, 0xbe, 0x9b, 0x55, 0x4f, 0x7b, 0x6c, 0xf9, 0x57, 0x87, 0x9e, 0xd1,
+ 0x93, 0xdc, 0xa7, 0xe2, 0x1e, 0x5c, 0x9b, 0xc5, 0x72, 0xfe, 0x97, 0xc5,
+ 0x61, 0xbe, 0xa7, 0xb2, 0x73, 0xfc, 0x34, 0x36, 0x3c, 0x8c, 0xc9, 0x8d,
+ 0x01, 0xd9, 0x8d, 0x1d, 0xce, 0xdd, 0xa5, 0xa3, 0x35, 0x50, 0xd8, 0xdf,
+ 0xb4, 0x80, 0xf3, 0x33, 0x9e, 0xb7, 0xfd, 0x83, 0x7d, 0xf5, 0xb3, 0x7d,
+ 0xd4, 0xf8, 0x9c, 0x3e, 0xfa, 0x72, 0x87, 0x71, 0x23, 0xf5, 0xd1, 0xfa,
+ 0x1d, 0x3e, 0x8a, 0xfa, 0xc8, 0xce, 0xfd, 0x93, 0xe3, 0x25, 0xf7, 0xcf,
+ 0xfc, 0x99, 0x63, 0x1c, 0xb8, 0x9c, 0xe1, 0x5c, 0x13, 0x38, 0x57, 0x95,
+ 0x79, 0xcf, 0x2d, 0x57, 0x29, 0x8d, 0xe5, 0x55, 0xc4, 0x72, 0x55, 0xe3,
+ 0x3c, 0xc8, 0x31, 0xcc, 0x74, 0x1c, 0xc7, 0x4c, 0x37, 0x96, 0xd1, 0x61,
+ 0x44, 0x3c, 0x57, 0xb3, 0x78, 0x6e, 0x75, 0x5d, 0xa7, 0x9a, 0xc5, 0x73,
+ 0x0b, 0x31, 0xdc, 0xce, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0x7f, 0xdf, 0xd3,
+ 0x2a, 0x9c, 0x1b, 0x5d, 0x27, 0x06, 0xc6, 0xb5, 0x25, 0xcf, 0x06, 0xee,
+ 0x09, 0x19, 0xbb, 0x79, 0x5c, 0xdc, 0xf1, 0x1d, 0x0c, 0xf7, 0xf9, 0x34,
+ 0xd7, 0xd4, 0x90, 0x6b, 0x2e, 0x20, 0xd7, 0xf4, 0x06, 0xbe, 0x83, 0x9d,
+ 0x97, 0xb9, 0xe6, 0xeb, 0xc5, 0x3c, 0xd7, 0xf4, 0xb2, 0x5c, 0xd3, 0x93,
+ 0xb9, 0xe6, 0xab, 0x45, 0xce, 0x35, 0x4d, 0x3a, 0x5a, 0x1c, 0xcc, 0x35,
+ 0xcd, 0xa1, 0x5c, 0x93, 0xd3, 0xf2, 0xfc, 0x4e, 0xb9, 0x26, 0xd7, 0xd9,
+ 0xbd, 0x6a, 0x92, 0x7c, 0x0f, 0xcb, 0xca, 0xb8, 0xc4, 0x78, 0x9c, 0xd6,
+ 0xfc, 0x57, 0x92, 0x3c, 0x96, 0x4e, 0xe3, 0x1c, 0xbc, 0x77, 0x77, 0x8a,
+ 0x25, 0x33, 0x8b, 0xa5, 0xdd, 0x29, 0x4d, 0x77, 0x30, 0x9e, 0x4e, 0x17,
+ 0x87, 0xe3, 0x29, 0xe7, 0x93, 0xc7, 0x53, 0xca, 0xf3, 0x3d, 0xad, 0xcc,
+ 0x35, 0x02, 0xfa, 0x6d, 0xd7, 0x5f, 0xc0, 0xec, 0xa5, 0xfe, 0x2c, 0x6a,
+ 0x6e, 0x9d, 0xae, 0xe6, 0x78, 0x23, 0xbf, 0x09, 0x61, 0xec, 0xe7, 0xb2,
+ 0x16, 0xb7, 0xd7, 0x7a, 0xa8, 0xbb, 0xdf, 0x01, 0x8e, 0x5c, 0x94, 0xeb,
+ 0x9f, 0x88, 0xab, 0x68, 0x09, 0xdb, 0x5e, 0xbe, 0xef, 0x17, 0x38, 0xcf,
+ 0xb5, 0xce, 0xe3, 0xe9, 0xd9, 0x7e, 0xae, 0x13, 0x5e, 0xe7, 0xb9, 0xbf,
+ 0x23, 0x9f, 0xa0, 0x66, 0xdf, 0xde, 0xcb, 0xfd, 0x8f, 0x87, 0x3b, 0x3b,
+ 0xf4, 0xfa, 0x50, 0x0f, 0x94, 0xf6, 0x3e, 0x75, 0xf9, 0x8d, 0x97, 0x6b,
+ 0x97, 0xe8, 0x0b, 0x2a, 0x9d, 0xa2, 0xaf, 0xf9, 0x3c, 0xa7, 0x52, 0xed,
+ 0x31, 0x21, 0x9e, 0x41, 0x1d, 0xf3, 0xd4, 0x50, 0x1d, 0x53, 0xa4, 0x89,
+ 0x47, 0x06, 0x7b, 0xc8, 0x2d, 0x31, 0x31, 0xed, 0x9e, 0x0f, 0x29, 0x54,
+ 0x6a, 0x1b, 0x5c, 0xe7, 0x6e, 0xd7, 0xb5, 0x44, 0xfb, 0x6e, 0x09, 0x75,
+ 0x9a, 0xf3, 0xe2, 0x6f, 0x33, 0x5d, 0x61, 0xed, 0xdc, 0x2d, 0x60, 0x6b,
+ 0x55, 0x7e, 0x0b, 0x0e, 0x37, 0xf8, 0x1c, 0x7e, 0xc7, 0x98, 0x70, 0xcd,
+ 0x73, 0xb7, 0xef, 0xb3, 0x3a, 0xec, 0xe2, 0x3a, 0xc7, 0x35, 0x92, 0xdf,
+ 0x37, 0x56, 0x7c, 0xf7, 0xa7, 0x2d, 0x4a, 0x71, 0xa2, 0xea, 0x2f, 0x41,
+ 0x16, 0xd4, 0x9d, 0xd6, 0x32, 0x6c, 0x33, 0x0d, 0x5c, 0x72, 0x9d, 0x47,
+ 0x54, 0x5b, 0xe2, 0xf8, 0x2a, 0x78, 0x6b, 0x8f, 0x70, 0x4d, 0xf9, 0xb1,
+ 0x58, 0xed, 0xcb, 0x7c, 0xec, 0xb3, 0x8f, 0xc4, 0xc9, 0x5e, 0x95, 0xc7,
+ 0x30, 0xe1, 0xe7, 0x02, 0x71, 0x2d, 0xb9, 0xb3, 0xff, 0xd8, 0x56, 0xf5,
+ 0x9c, 0x63, 0xd5, 0xba, 0x8e, 0xb5, 0xd0, 0x55, 0xe1, 0xdd, 0xfb, 0x4c,
+ 0xda, 0x03, 0x9b, 0x20, 0x1f, 0xd3, 0x7d, 0x90, 0xe5, 0x92, 0x63, 0xc5,
+ 0xa8, 0x0f, 0xbf, 0xa7, 0xb9, 0xd6, 0x53, 0xa4, 0x98, 0x54, 0xba, 0x25,
+ 0xd2, 0x6f, 0x33, 0x8e, 0x55, 0xdd, 0x3e, 0xfb, 0x16, 0xce, 0x66, 0x99,
+ 0x38, 0x46, 0x39, 0x5f, 0x2e, 0x2a, 0x4b, 0xd0, 0xd1, 0xb1, 0x8d, 0x5d,
+ 0xc0, 0x35, 0xce, 0x97, 0x07, 0xb2, 0x6f, 0x50, 0xb0, 0x0f, 0xee, 0xff,
+ 0xfa, 0x1d, 0xf5, 0x67, 0x5e, 0x67, 0x32, 0xbd, 0x10, 0xcd, 0x79, 0x3e,
+ 0x9f, 0x20, 0xcb, 0xd4, 0xcc, 0x25, 0xd9, 0x13, 0xcd, 0xa2, 0xee, 0xe3,
+ 0x51, 0xa0, 0x26, 0xe2, 0xef, 0x61, 0xae, 0x55, 0xc7, 0x73, 0x35, 0x7b,
+ 0x6e, 0x72, 0xbf, 0x34, 0xcf, 0x3c, 0xb8, 0x6f, 0xe2, 0xf8, 0xf9, 0x27,
+ 0x6e, 0xb7, 0x92, 0x82, 0x90, 0x18, 0x00, 0x00, 0x00 };
static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 };
static struct fw_info bnx2_tpat_fw_09 = {
+ /* Firmware version: 3.7.1 */
.ver_major = 0x3,
- .ver_minor = 0x4,
- .ver_fix = 0x3,
+ .ver_minor = 0x7,
+ .ver_fix = 0x1,
.start_addr = 0x08000860,
.text_addr = 0x08000800,
- .text_len = 0x1864,
+ .text_len = 0x188c,
.text_index = 0x0,
.gz_text = bnx2_TPAT_b09FwText,
.gz_text_len = sizeof(bnx2_TPAT_b09FwText),
- .data_addr = 0x08002080,
+ .data_addr = 0x080020c0,
.data_len = 0x0,
.data_index = 0x0,
.data = bnx2_TPAT_b09FwData,
- .sbss_addr = 0x08002088,
- .sbss_len = 0x2c,
+ .sbss_addr = 0x080020c8,
+ .sbss_len = 0x30,
.sbss_index = 0x0,
- .bss_addr = 0x080020c0,
+ .bss_addr = 0x08002100,
.bss_len = 0x850,
.bss_index = 0x0,
@@ -3267,768 +3289,770 @@ static struct fw_info bnx2_tpat_fw_09 = {
};
static u8 bnx2_TXP_b09FwText[] = {
-/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
- 0xcd, 0x7c,
- 0x6f, 0x70, 0x5b, 0xd7, 0x95, 0xdf, 0x79, 0xef, 0x81, 0x24, 0x48, 0xd1,
- 0xd4, 0x13, 0x17, 0x56, 0x60, 0x87, 0x71, 0x00, 0xf1, 0x81, 0x66, 0x42,
- 0xae, 0x04, 0x2b, 0x4c, 0xc2, 0x6d, 0xd1, 0xf8, 0x05, 0x00, 0x29, 0x48,
- 0xd1, 0x6c, 0x68, 0x95, 0x49, 0x94, 0x54, 0xe3, 0x62, 0x41, 0x52, 0xf1,
- 0xb6, 0xce, 0x54, 0x9b, 0x78, 0x5a, 0x4d, 0xeb, 0xad, 0x11, 0x90, 0xfa,
- 0xe7, 0x85, 0x04, 0xda, 0x62, 0x44, 0x7f, 0xc8, 0x07, 0x18, 0x80, 0x24,
- 0x6f, 0xf2, 0x44, 0x28, 0x9b, 0x7f, 0xfd, 0xd0, 0xac, 0x50, 0x4a, 0xd6,
- 0xba, 0x9b, 0xb4, 0xa3, 0xed, 0x66, 0x67, 0x3b, 0xd3, 0x2f, 0x1c, 0x49,
- 0xf6, 0x7a, 0x77, 0x67, 0x36, 0xda, 0x6e, 0xb6, 0xab, 0xb6, 0xb2, 0xd1,
- 0xdf, 0xef, 0xbe, 0xf7, 0x28, 0x90, 0xa6, 0x6c, 0xcb, 0xb3, 0xed, 0x94,
- 0x33, 0x18, 0xe0, 0xdd, 0x77, 0xdf, 0xb9, 0xe7, 0x9e, 0x73, 0xee, 0x39,
- 0xe7, 0x77, 0xee, 0x7d, 0x0c, 0x8b, 0x74, 0x89, 0xf7, 0xf7, 0x00, 0x3e,
- 0x91, 0x43, 0x87, 0x9f, 0xd9, 0x3e, 0xb2, 0xfd, 0x13, 0xf8, 0xf9, 0x09,
- 0x31, 0x02, 0x06, 0x6f, 0xbe, 0x69, 0x88, 0x64, 0xff, 0x42, 0x3e, 0xf0,
- 0x1f, 0x1e, 0x37, 0x7d, 0xfa, 0xfc, 0x48, 0x50, 0x4f, 0x4c, 0xec, 0x4a,
- 0x5a, 0x12, 0x34, 0x12, 0xb2, 0x6f, 0xca, 0x12, 0xb1, 0x9d, 0xa1, 0x48,
- 0x4a, 0xde, 0x6a, 0xe6, 0x43, 0x01, 0x61, 0xfb, 0x47, 0x12, 0x77, 0x9e,
- 0xfb, 0xc9, 0xa7, 0xa3, 0xb7, 0xca, 0x86, 0x04, 0xcd, 0x44, 0x56, 0xcc,
- 0x01, 0x09, 0xf6, 0xe1, 0x99, 0x6f, 0x3f, 0x6a, 0x18, 0xd2, 0xb3, 0xca,
- 0xab, 0xcc, 0x95, 0x56, 0x9a, 0x3f, 0x79, 0x34, 0x2c, 0xbf, 0x57, 0x0f,
- 0xc9, 0xf7, 0xea, 0xa6, 0x5c, 0xac, 0x07, 0xb4, 0xf1, 0x92, 0x29, 0xb3,
- 0xa5, 0x69, 0xfd, 0x48, 0x31, 0x2f, 0xa9, 0x7a, 0x56, 0x2f, 0x2c, 0x98,
- 0x3d, 0xc9, 0xf3, 0x39, 0x7d, 0x76, 0xa1, 0xb7, 0x27, 0x75, 0x7e, 0x5a,
- 0x2f, 0x14, 0xc3, 0x3d, 0xc9, 0xba, 0xd9, 0x93, 0x5a, 0x0c, 0xe1, 0xba,
- 0xb7, 0x27, 0xb9, 0x18, 0x9d, 0x17, 0xd9, 0x8a, 0x3e, 0xe1, 0x9e, 0x54,
- 0x29, 0x9a, 0x15, 0xe9, 0x8f, 0xbf, 0x2a, 0x7d, 0x3d, 0xa9, 0xfa, 0x3f,
- 0xd1, 0x1b, 0xa6, 0x26, 0x85, 0x5f, 0x15, 0x33, 0x9c, 0xb8, 0xd5, 0x7c,
- 0xc8, 0xd2, 0xc4, 0xb4, 0x6e, 0x37, 0xb7, 0x58, 0x41, 0xc9, 0x9d, 0xee,
- 0x14, 0x5b, 0xcd, 0xc9, 0x94, 0xdc, 0xe2, 0x90, 0xb9, 0x2c, 0x6d, 0x62,
- 0x87, 0xfc, 0xeb, 0x66, 0x33, 0x19, 0xff, 0x32, 0xe5, 0x8a, 0x71, 0xa4,
- 0x67, 0xbc, 0x2e, 0x92, 0x2c, 0x05, 0x25, 0x19, 0x7f, 0xab, 0xe9, 0x3e,
- 0x13, 0xc4, 0x98, 0x81, 0x9e, 0xb1, 0x52, 0xb3, 0x99, 0x8e, 0x83, 0x7e,
- 0xdc, 0x7f, 0xb6, 0x4d, 0xca, 0x21, 0xbb, 0x3c, 0x1b, 0xff, 0x6f, 0xba,
- 0xab, 0x13, 0xce, 0x91, 0xd7, 0xb6, 0xe8, 0x56, 0x5e, 0x72, 0x21, 0x29,
- 0x17, 0xe2, 0x9f, 0x92, 0x13, 0xf1, 0x30, 0xe6, 0x17, 0x94, 0x63, 0x71,
- 0xc8, 0xd1, 0x3a, 0xac, 0x25, 0xeb, 0xd1, 0x48, 0x56, 0x9e, 0x97, 0xe4,
- 0x62, 0xbf, 0x99, 0x16, 0x8c, 0x6d, 0x35, 0x3f, 0x9a, 0x8c, 0x63, 0xbc,
- 0xe1, 0xff, 0xd5, 0xb4, 0x43, 0xd1, 0x6c, 0x59, 0x06, 0xa5, 0x50, 0xea,
- 0x8f, 0xff, 0x4c, 0x34, 0x09, 0x5a, 0x62, 0x4f, 0x59, 0x26, 0xe4, 0x16,
- 0x1d, 0x4c, 0x19, 0x4d, 0xd9, 0x83, 0xf1, 0x93, 0x16, 0xee, 0xd7, 0x65,
- 0xb3, 0x6e, 0xb5, 0x4b, 0xc1, 0x94, 0x50, 0x97, 0x3c, 0x22, 0x85, 0xd3,
- 0x68, 0x8f, 0xdb, 0xbd, 0x3a, 0x9e, 0xc9, 0x8c, 0xb0, 0x4d, 0x34, 0x23,
- 0x11, 0x33, 0x53, 0xe0, 0xa8, 0xe2, 0x0c, 0x62, 0xfc, 0x98, 0xdd, 0xa9,
- 0x99, 0xb2, 0x62, 0x06, 0xa4, 0xea, 0xc4, 0xec, 0xb0, 0xd6, 0x2e, 0xc7,
- 0x62, 0x5d, 0x90, 0x69, 0x18, 0xb4, 0xe5, 0x9b, 0x7a, 0x22, 0x16, 0xce,
- 0x41, 0x51, 0x3a, 0x64, 0x35, 0x07, 0x7e, 0xe6, 0xe2, 0x59, 0x2d, 0x55,
- 0xff, 0x8a, 0x96, 0x3c, 0xbf, 0x5f, 0xdb, 0x75, 0x1e, 0x7d, 0xea, 0xe7,
- 0x3c, 0xbb, 0x0b, 0x83, 0x37, 0x1d, 0xcf, 0xb2, 0x1d, 0x3c, 0x2b, 0xde,
- 0xd1, 0x06, 0x5d, 0x36, 0x26, 0x43, 0x3d, 0x49, 0xa5, 0x4b, 0xf2, 0xa6,
- 0x4b, 0x6e, 0x42, 0x93, 0x5e, 0xcb, 0x96, 0xe0, 0x27, 0xa1, 0xcf, 0x45,
- 0xe8, 0x72, 0x31, 0x22, 0x47, 0x4a, 0x12, 0xd2, 0x85, 0x63, 0x65, 0xf5,
- 0xaa, 0x43, 0x7b, 0x80, 0x6e, 0xa1, 0xfb, 0x82, 0xc3, 0x67, 0xa1, 0xc3,
- 0x52, 0x1a, 0xf2, 0xc9, 0x60, 0xec, 0x7d, 0xda, 0x9e, 0xea, 0xa4, 0x96,
- 0x81, 0x9d, 0x14, 0x4e, 0x0f, 0x41, 0x77, 0xd1, 0xc8, 0x8a, 0x6c, 0x96,
- 0x82, 0x65, 0x45, 0xbe, 0x2c, 0xdd, 0x72, 0x6c, 0xd1, 0x92, 0x23, 0x8b,
- 0x21, 0xc9, 0x9b, 0x51, 0xb3, 0x26, 0x7d, 0xd9, 0x4d, 0x89, 0x1e, 0x79,
- 0xfe, 0x74, 0x34, 0x53, 0x96, 0x7e, 0xfb, 0x75, 0xdc, 0xcf, 0x9d, 0xa4,
- 0x4e, 0x25, 0x9f, 0x8a, 0x1b, 0x92, 0x85, 0x4d, 0x18, 0xd6, 0x1f, 0x81,
- 0xff, 0xe6, 0x73, 0xc9, 0x78, 0x34, 0x2c, 0xa2, 0x4b, 0xea, 0x0b, 0xfd,
- 0xe6, 0x6e, 0x89, 0x9a, 0x19, 0xca, 0x3f, 0x3e, 0x04, 0x3d, 0xfc, 0x77,
- 0xca, 0x1e, 0xb4, 0xa8, 0xe3, 0xa1, 0xf0, 0x31, 0xe8, 0x32, 0xab, 0x74,
- 0xdc, 0x83, 0xf1, 0x03, 0x9e, 0xed, 0xf4, 0x48, 0xbe, 0x7a, 0xc3, 0x93,
- 0x43, 0x8f, 0xcc, 0x57, 0xbb, 0xa5, 0x00, 0x1d, 0x16, 0xc4, 0x92, 0xc2,
- 0xf9, 0x3f, 0xf7, 0xda, 0x2d, 0x99, 0x3b, 0xff, 0x32, 0xec, 0xe1, 0xb0,
- 0xb6, 0xbf, 0xfe, 0x0b, 0xcd, 0xb3, 0x1f, 0xd8, 0x5f, 0x50, 0xec, 0x89,
- 0xa0, 0x9c, 0xab, 0xbb, 0xf6, 0x57, 0xc1, 0x1a, 0xb3, 0x4d, 0x1b, 0xb6,
- 0xf4, 0xc6, 0x6a, 0x9f, 0x73, 0xf5, 0x3e, 0x3c, 0x1b, 0x94, 0x23, 0x75,
- 0xf6, 0xcf, 0xc3, 0xc6, 0x82, 0xb2, 0xf4, 0x68, 0xb7, 0x64, 0xd1, 0x5e,
- 0x58, 0x14, 0x3b, 0x19, 0xd7, 0xf1, 0x4c, 0x0f, 0xe6, 0xb2, 0x15, 0x9f,
- 0x2e, 0x99, 0xaa, 0x76, 0xd8, 0x86, 0x15, 0x92, 0xa9, 0x3a, 0xf5, 0x8f,
- 0xef, 0x92, 0x6f, 0x03, 0x94, 0x2f, 0xdb, 0xf9, 0x1c, 0xdb, 0x4d, 0xb4,
- 0xb7, 0xb6, 0xd1, 0xb6, 0x37, 0x53, 0xa6, 0x83, 0x82, 0xb6, 0x5c, 0x29,
- 0x66, 0xee, 0xe7, 0x77, 0x9d, 0xf6, 0xd0, 0x6a, 0x0b, 0x01, 0xf4, 0x87,
- 0x1e, 0xab, 0x18, 0xeb, 0xf4, 0x9d, 0x66, 0xdb, 0x08, 0xae, 0x2d, 0x2c,
- 0xaa, 0x2e, 0x8e, 0x1d, 0x00, 0x5f, 0xba, 0x64, 0xab, 0x8a, 0xb7, 0x08,
- 0x6d, 0xc0, 0x9d, 0x47, 0x9f, 0xcc, 0x2e, 0x76, 0xf7, 0xa4, 0x17, 0xd9,
- 0x9e, 0x0c, 0x1b, 0x98, 0xe7, 0x54, 0x5c, 0x1a, 0x73, 0x71, 0xbd, 0x3f,
- 0x00, 0xbe, 0xa6, 0xb1, 0xe0, 0x30, 0x0f, 0x8f, 0xc7, 0x06, 0xee, 0xf7,
- 0xca, 0xd4, 0x79, 0xf6, 0xe5, 0x18, 0x85, 0x2d, 0xba, 0x24, 0xc0, 0x1b,
- 0x3e, 0x56, 0x14, 0xf7, 0x3b, 0x31, 0x4e, 0x37, 0x6c, 0x27, 0x83, 0x31,
- 0x9b, 0x8f, 0x27, 0xe3, 0xbd, 0x92, 0x5d, 0xed, 0x2b, 0xb0, 0x3b, 0xf6,
- 0x1f, 0x5c, 0xd7, 0x17, 0xf2, 0x3d, 0x0f, 0x9a, 0x8b, 0x9d, 0x90, 0x21,
- 0xdb, 0x75, 0xf0, 0xdc, 0x01, 0x1e, 0x82, 0x98, 0x4f, 0x3f, 0xd6, 0x43,
- 0x07, 0xe8, 0x6f, 0xc2, 0x9c, 0x3a, 0x65, 0xfa, 0x74, 0x2f, 0x74, 0x61,
- 0xa2, 0x6f, 0x50, 0x9e, 0x2f, 0x45, 0x61, 0x03, 0xec, 0x0f, 0x1d, 0x2c,
- 0x46, 0xc3, 0x55, 0xb1, 0x65, 0x2e, 0xde, 0x01, 0xfb, 0x6a, 0x36, 0x67,
- 0x60, 0x1f, 0xdf, 0x51, 0xfe, 0x62, 0xc8, 0x1c, 0xd3, 0x24, 0xdf, 0x91,
- 0x38, 0x0c, 0x7e, 0xa2, 0x4f, 0x89, 0xf0, 0x7a, 0x87, 0xc6, 0x35, 0x0b,
- 0x39, 0x72, 0x6c, 0xf8, 0xa4, 0xad, 0x90, 0x21, 0xfd, 0x56, 0x1f, 0xec,
- 0x39, 0xac, 0xfc, 0xc9, 0xd8, 0x86, 0xfe, 0x24, 0x3a, 0x51, 0xc6, 0x58,
- 0x85, 0xf3, 0x01, 0xfa, 0xb0, 0x51, 0x2c, 0x57, 0x79, 0x00, 0x6b, 0x6f,
- 0x56, 0xd9, 0xc7, 0x09, 0xce, 0xb7, 0xf9, 0xf9, 0x38, 0xf9, 0xe2, 0x7c,
- 0x6d, 0x3c, 0x4b, 0x1b, 0x8c, 0x1e, 0xb6, 0xd5, 0xf8, 0x27, 0xbc, 0xf1,
- 0x5d, 0xde, 0x0b, 0xa5, 0x1e, 0x2d, 0xa5, 0x78, 0xf0, 0xe9, 0x88, 0x2c,
- 0x9f, 0xec, 0x37, 0xf7, 0xc0, 0x86, 0xe9, 0xa7, 0x96, 0x2f, 0x50, 0xc7,
- 0xa0, 0x31, 0x42, 0x1d, 0x9b, 0x8a, 0xbf, 0xe4, 0x22, 0xd7, 0x9e, 0xf4,
- 0x19, 0x42, 0x1f, 0x01, 0x9f, 0x8b, 0xb5, 0x38, 0xeb, 0xad, 0xc5, 0x9c,
- 0x43, 0xfb, 0x7b, 0x06, 0xcf, 0xea, 0x32, 0x16, 0xa3, 0x7f, 0x78, 0x5e,
- 0x52, 0xf0, 0x91, 0xd0, 0xa3, 0x54, 0x31, 0x97, 0x4a, 0xa9, 0xd5, 0x6f,
- 0xc1, 0xb6, 0x86, 0xff, 0xae, 0xe9, 0xfa, 0x43, 0xfa, 0x06, 0xfa, 0x9a,
- 0x82, 0xa9, 0x43, 0x72, 0x3a, 0x9c, 0x21, 0x74, 0x13, 0x4f, 0x1a, 0xd1,
- 0x4c, 0x16, 0x7c, 0x4d, 0x59, 0x4d, 0xb1, 0x1e, 0x13, 0x44, 0x0c, 0xf4,
- 0xa9, 0xcb, 0x4e, 0xdf, 0x3f, 0x2d, 0x3b, 0xbe, 0x2e, 0xa8, 0x57, 0xea,
- 0xc1, 0xf7, 0x11, 0x01, 0xb9, 0x0c, 0xdf, 0x35, 0x57, 0xea, 0x96, 0x06,
- 0x78, 0xba, 0xe2, 0xf8, 0xb6, 0x66, 0x78, 0xb6, 0xc6, 0x67, 0xba, 0xf1,
- 0x7c, 0x00, 0x7e, 0x4d, 0xf2, 0x46, 0x02, 0xbf, 0x8b, 0xa4, 0xc9, 0x36,
- 0xdf, 0xce, 0xb9, 0x66, 0xa2, 0x76, 0x59, 0xda, 0x25, 0x13, 0x43, 0xfc,
- 0x58, 0xd4, 0x31, 0x56, 0x1f, 0x7c, 0x79, 0x40, 0x0e, 0x96, 0x42, 0xf2,
- 0xd5, 0x12, 0xe7, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xb1, 0x09, 0x9d,
- 0x8f, 0xc3, 0xe7, 0x65, 0xb4, 0x31, 0xf8, 0x9f, 0xdd, 0xd5, 0xaf, 0x68,
- 0xe9, 0xf3, 0x59, 0x6d, 0xbc, 0xbe, 0x5f, 0xcb, 0x9c, 0x9f, 0xd4, 0x76,
- 0xb5, 0xf8, 0x22, 0xd1, 0xde, 0xdd, 0x17, 0x9d, 0x38, 0xcd, 0x31, 0xfb,
- 0xe3, 0x1b, 0xfb, 0xa2, 0x5f, 0x6a, 0xad, 0xbe, 0xa8, 0x1f, 0xbe, 0x28,
- 0x03, 0x5f, 0x34, 0x7e, 0xdf, 0xbe, 0xa8, 0x5d, 0xdf, 0xd8, 0x17, 0x75,
- 0xeb, 0x77, 0x7d, 0x11, 0x63, 0xcf, 0xbf, 0xc6, 0xb5, 0x29, 0xdb, 0x76,
- 0xfa, 0x72, 0x0e, 0xc3, 0x0f, 0x6f, 0x82, 0xac, 0xbb, 0xb8, 0x76, 0x22,
- 0x05, 0xd8, 0xfd, 0x34, 0xc6, 0xfa, 0x4d, 0xd8, 0xfb, 0xb6, 0x98, 0x65,
- 0x3e, 0xa1, 0xc6, 0x7d, 0xa7, 0xce, 0xc7, 0x56, 0x75, 0x4e, 0x1e, 0xdf,
- 0x53, 0xe7, 0xb6, 0xab, 0x73, 0xea, 0xba, 0x53, 0x66, 0xd4, 0xb8, 0x4d,
- 0x09, 0x3c, 0x26, 0xf0, 0x2a, 0xf2, 0x59, 0x23, 0x11, 0x05, 0x3d, 0x1d,
- 0xe3, 0x53, 0x5f, 0x31, 0xf0, 0x20, 0xd0, 0x6f, 0xb7, 0xf2, 0x45, 0xbb,
- 0xa0, 0xf7, 0x65, 0xe7, 0xfe, 0x74, 0x95, 0x69, 0xd1, 0xd5, 0x9e, 0x35,
- 0xba, 0xea, 0x90, 0xe1, 0x98, 0xaf, 0xa3, 0xcd, 0x92, 0x8c, 0x51, 0x67,
- 0xf7, 0xa3, 0xab, 0x7f, 0xaa, 0xff, 0xfd, 0xe8, 0xea, 0xb7, 0xee, 0xa1,
- 0xab, 0x7f, 0xb5, 0x4e, 0x57, 0x96, 0xf9, 0x82, 0x46, 0xda, 0x8c, 0x1f,
- 0xf4, 0x47, 0xcd, 0x8f, 0x4e, 0x31, 0x7f, 0xa8, 0x73, 0x4d, 0xfb, 0x79,
- 0x07, 0xd7, 0xf3, 0xa5, 0xa6, 0x61, 0x59, 0x90, 0x1d, 0xd7, 0x34, 0xe5,
- 0x16, 0x35, 0x3f, 0x4f, 0xfe, 0x11, 0x3b, 0xa6, 0x10, 0x6b, 0x5c, 0x1e,
- 0xda, 0xa5, 0xbc, 0xc5, 0xed, 0x3f, 0x55, 0x6a, 0xfe, 0x42, 0x4f, 0xbc,
- 0xdd, 0x4c, 0x8e, 0x58, 0x5e, 0x1c, 0x08, 0xca, 0xd7, 0xaa, 0xd1, 0xac,
- 0xad, 0x75, 0x4b, 0xfe, 0x41, 0xc4, 0x9e, 0x12, 0xfd, 0xd7, 0xd6, 0x7b,
- 0xc4, 0xe8, 0x3e, 0x2f, 0x46, 0x57, 0xc1, 0x2b, 0xf3, 0xab, 0xef, 0xbe,
- 0xd5, 0x08, 0xf1, 0x3b, 0x66, 0xee, 0x93, 0x2f, 0x73, 0x8e, 0x88, 0xf7,
- 0x8c, 0xfb, 0x16, 0x73, 0x9e, 0x7c, 0x20, 0xd1, 0x25, 0xf9, 0x2d, 0x5c,
- 0x8f, 0xf4, 0x73, 0xf4, 0x5d, 0xed, 0x1e, 0xdf, 0x7e, 0x8e, 0xa4, 0x78,
- 0x33, 0x30, 0x65, 0xf4, 0x41, 0x3e, 0x54, 0xe2, 0x3c, 0xde, 0xf2, 0xec,
- 0x89, 0xb9, 0x82, 0xb4, 0xb9, 0xbe, 0x61, 0x2f, 0x72, 0x01, 0xda, 0x81,
- 0xaf, 0x73, 0xea, 0x9b, 0x39, 0x82, 0x44, 0x74, 0x8b, 0x39, 0x82, 0x98,
- 0x46, 0x62, 0x9f, 0x66, 0x43, 0xf7, 0x36, 0x74, 0x6f, 0x43, 0xf7, 0x36,
- 0x74, 0x9f, 0xac, 0x1f, 0xc6, 0x3d, 0x95, 0x87, 0x80, 0x17, 0x97, 0x7e,
- 0xda, 0xa5, 0x0f, 0x3e, 0xb7, 0x4a, 0x4e, 0xe9, 0x84, 0xf3, 0x45, 0xae,
- 0xa1, 0xfc, 0xf5, 0xb8, 0xe6, 0xfa, 0x6b, 0xd2, 0xcb, 0xe0, 0xf9, 0xdb,
- 0x98, 0xa7, 0xad, 0xeb, 0xd6, 0x5d, 0x99, 0xcc, 0xb5, 0xc8, 0x64, 0xd6,
- 0xa1, 0x8c, 0xd8, 0x9f, 0x3e, 0x77, 0x5a, 0xaf, 0xac, 0xca, 0x65, 0x2f,
- 0x78, 0xe8, 0xe0, 0xdc, 0xbd, 0x79, 0x90, 0x7e, 0xaf, 0x47, 0xff, 0x6f,
- 0xd1, 0x87, 0xfe, 0x75, 0xa3, 0x71, 0x39, 0x26, 0x73, 0xc6, 0x77, 0x9b,
- 0x0f, 0x72, 0x66, 0xac, 0x81, 0xef, 0x21, 0x96, 0x5f, 0x44, 0x2c, 0x59,
- 0x31, 0x22, 0xf2, 0x93, 0x47, 0xaf, 0x21, 0x97, 0x96, 0xfc, 0xc3, 0x89,
- 0x66, 0x24, 0x90, 0x78, 0xab, 0x39, 0x37, 0x82, 0x18, 0x97, 0x88, 0x86,
- 0x93, 0xc6, 0xb0, 0x5c, 0xaa, 0x0f, 0xca, 0x8f, 0xea, 0x96, 0xfc, 0xb0,
- 0x1e, 0x91, 0x1f, 0x20, 0xe6, 0x7f, 0xbf, 0xde, 0x9a, 0x73, 0x47, 0x68,
- 0x4f, 0x3d, 0xe9, 0xfa, 0x46, 0xb9, 0x7f, 0x13, 0x34, 0xde, 0x82, 0x9d,
- 0x04, 0xb2, 0xc8, 0xf5, 0x19, 0xbf, 0x26, 0x0e, 0x15, 0x9f, 0x6b, 0x82,
- 0xb7, 0x6c, 0x5b, 0xc2, 0xca, 0xeb, 0x7a, 0xf7, 0xa8, 0xf9, 0x29, 0xb4,
- 0x39, 0xa3, 0x81, 0x6a, 0xb1, 0x53, 0xe5, 0x8b, 0xd0, 0x91, 0xd8, 0xf5,
- 0x60, 0xb0, 0x56, 0xbc, 0x85, 0x7e, 0xcd, 0xe6, 0xa1, 0xf8, 0x6f, 0xed,
- 0x30, 0xff, 0x81, 0x85, 0x35, 0xdd, 0xf9, 0x25, 0x23, 0xb1, 0x49, 0x66,
- 0x43, 0xdf, 0x6f, 0x98, 0x03, 0x7d, 0x59, 0x3d, 0x11, 0x94, 0x74, 0x91,
- 0x6b, 0x2a, 0x24, 0xb3, 0x55, 0x28, 0xff, 0x3c, 0xd7, 0x85, 0x3c, 0x3b,
- 0x17, 0xef, 0x86, 0xed, 0xff, 0x9a, 0xe1, 0xae, 0x03, 0x18, 0x50, 0x75,
- 0x50, 0xf2, 0xe0, 0x37, 0x5f, 0x7f, 0xcb, 0xc3, 0x0e, 0xf0, 0x2a, 0x5b,
- 0x21, 0xf8, 0xc4, 0x70, 0xda, 0x76, 0xfe, 0x30, 0x88, 0xb6, 0xe0, 0x56,
- 0xeb, 0xce, 0x26, 0x7c, 0x3f, 0x10, 0xb2, 0x88, 0x4d, 0x24, 0xf3, 0x05,
- 0x7c, 0xff, 0x4a, 0x42, 0x36, 0xf7, 0xe2, 0x7b, 0x4b, 0x02, 0x26, 0x99,
- 0x60, 0xcc, 0xd5, 0x5a, 0x62, 0xae, 0x68, 0x69, 0xc8, 0x6e, 0x0e, 0x73,
- 0x4f, 0x43, 0x9e, 0x5f, 0xac, 0x07, 0xb5, 0xd4, 0xe9, 0x47, 0xc0, 0x87,
- 0x9f, 0x3b, 0x23, 0x3f, 0x33, 0x97, 0xb7, 0x04, 0xe4, 0x16, 0x7c, 0x5c,
- 0x12, 0x7e, 0xcc, 0x46, 0x6e, 0xb1, 0x03, 0xcb, 0x35, 0xfa, 0x5f, 0xbf,
- 0x20, 0x5f, 0xf3, 0x78, 0x6b, 0x93, 0x05, 0x65, 0xa3, 0x6c, 0xcf, 0x67,
- 0xfe, 0xcd, 0xc0, 0xdd, 0xf6, 0x17, 0x57, 0xdb, 0xcb, 0x99, 0x7f, 0xb8,
- 0xda, 0xde, 0xdb, 0xe6, 0xf2, 0x3f, 0xaa, 0x4d, 0xd4, 0xf7, 0x78, 0x6d,
- 0xb7, 0xa1, 0xb3, 0x66, 0x93, 0xb9, 0x45, 0x01, 0xd8, 0x24, 0x1d, 0xa7,
- 0x2f, 0xbe, 0x1f, 0x5f, 0xbb, 0xc6, 0xcf, 0x9a, 0x49, 0x83, 0xb6, 0x10,
- 0x14, 0x97, 0x26, 0xef, 0x77, 0x20, 0x7f, 0xbf, 0x8d, 0xdf, 0x8c, 0xa3,
- 0x7e, 0x6e, 0xce, 0x3e, 0x7c, 0xfe, 0xcd, 0x7b, 0xd8, 0x4b, 0x08, 0xf6,
- 0xf2, 0xff, 0xab, 0x5d, 0x5c, 0xba, 0x1f, 0xbb, 0xc0, 0x9f, 0xb2, 0x0b,
- 0xd5, 0xff, 0xd2, 0xea, 0x5a, 0x09, 0x43, 0x3e, 0x8c, 0x07, 0x83, 0xd0,
- 0xf1, 0x66, 0x99, 0xb5, 0xc8, 0x8f, 0x15, 0xc9, 0xc1, 0x5f, 0x9e, 0x58,
- 0x17, 0xbb, 0xbb, 0x10, 0x0f, 0x8e, 0x9f, 0x8e, 0x8e, 0x32, 0x1e, 0xc4,
- 0xe0, 0x1b, 0x93, 0xef, 0x88, 0x07, 0x37, 0x8c, 0xd6, 0x78, 0x60, 0x20,
- 0x1e, 0xec, 0x7a, 0x97, 0x78, 0x70, 0xe2, 0x1d, 0xf1, 0x40, 0x83, 0x6c,
- 0x38, 0xbf, 0xbf, 0x35, 0xfc, 0x78, 0x50, 0x58, 0x13, 0x0f, 0x7c, 0x5d,
- 0x59, 0x0a, 0x0b, 0xdc, 0xd5, 0x5b, 0x97, 0xa7, 0x2b, 0x09, 0x06, 0x12,
- 0x8d, 0xcc, 0x9c, 0xf5, 0xb0, 0xb4, 0xc1, 0xe7, 0x5e, 0xaa, 0x8f, 0x40,
- 0x67, 0x97, 0x30, 0xf7, 0x68, 0x9c, 0x89, 0x65, 0x5b, 0x82, 0xeb, 0xe1,
- 0xcd, 0x08, 0x30, 0xe2, 0x6e, 0xe0, 0xbe, 0xdd, 0x67, 0xd5, 0xfa, 0x78,
- 0x33, 0xea, 0x61, 0xf7, 0x6d, 0xc0, 0xee, 0x78, 0x3e, 0x00, 0x4c, 0xc8,
- 0xf6, 0x2b, 0x66, 0x12, 0x7a, 0xaa, 0x3a, 0xf6, 0xee, 0x02, 0x3e, 0x73,
- 0xaa, 0xef, 0xad, 0x08, 0xfb, 0x76, 0x24, 0x12, 0xd1, 0x3f, 0xc3, 0x77,
- 0x7b, 0x22, 0xbc, 0xed, 0xaa, 0x45, 0xba, 0x87, 0xa2, 0x67, 0x15, 0x8d,
- 0x80, 0x14, 0xd4, 0xb3, 0x91, 0x6d, 0x7c, 0xf6, 0x18, 0x62, 0xf6, 0x51,
- 0xc7, 0x94, 0x23, 0x4e, 0x76, 0x77, 0x0e, 0x1f, 0x62, 0xd5, 0x4b, 0x25,
- 0xde, 0x1f, 0xc5, 0xfd, 0x80, 0x30, 0x97, 0xfc, 0x2a, 0xfa, 0x1c, 0x44,
- 0x9f, 0x19, 0xc7, 0xd7, 0x05, 0xef, 0x37, 0x32, 0x29, 0xdc, 0x9f, 0x29,
- 0x36, 0x32, 0xe9, 0x22, 0xf3, 0xd6, 0xa1, 0xf0, 0x11, 0xc8, 0x33, 0x8b,
- 0x5c, 0xcd, 0x96, 0xe8, 0x60, 0x5e, 0x9e, 0xee, 0x1c, 0x07, 0x4e, 0x3a,
- 0x87, 0x1c, 0xc2, 0x9e, 0x8c, 0xc6, 0xcb, 0xf2, 0xe1, 0xce, 0xe4, 0x69,
- 0xe4, 0x0b, 0xf1, 0xed, 0x90, 0x61, 0x23, 0xa3, 0xc7, 0x04, 0xb6, 0x1e,
- 0x87, 0x5f, 0x1e, 0xd1, 0x53, 0xc5, 0x7e, 0x73, 0x56, 0x1e, 0x95, 0x86,
- 0x19, 0x0d, 0x8f, 0xcb, 0x26, 0x49, 0x05, 0xd0, 0x6f, 0xf0, 0x43, 0x92,
- 0x0d, 0x53, 0xd6, 0x0f, 0xc2, 0xdf, 0x6b, 0xd2, 0x61, 0xb5, 0xc6, 0x9e,
- 0x5b, 0x10, 0x6f, 0x2e, 0x40, 0x9f, 0xdd, 0x61, 0x75, 0x7a, 0x3a, 0xd9,
- 0x24, 0xcb, 0xef, 0xe8, 0x77, 0xbb, 0xa5, 0x5f, 0x6b, 0xfb, 0xdb, 0x68,
- 0xdf, 0x84, 0x9c, 0xb3, 0x91, 0x09, 0xc4, 0x20, 0x7f, 0xcc, 0xa1, 0x0d,
- 0x76, 0x72, 0x15, 0xf3, 0x61, 0x1c, 0x2c, 0x94, 0x99, 0xf7, 0x18, 0x52,
- 0x36, 0x71, 0xcf, 0x69, 0x36, 0x2b, 0x16, 0xf8, 0xbd, 0x40, 0x9e, 0x83,
- 0x32, 0xee, 0x0c, 0x88, 0x5d, 0xa3, 0x1c, 0xa2, 0xf0, 0x4a, 0x0f, 0x77,
- 0xa5, 0x16, 0xa3, 0x76, 0x1e, 0x14, 0x8d, 0x0b, 0x7d, 0x5d, 0x49, 0xe4,
- 0x39, 0xfa, 0x85, 0x48, 0x57, 0x0a, 0x36, 0x6b, 0x5c, 0x78, 0xa8, 0x2b,
- 0x7d, 0x9a, 0x7c, 0x19, 0xc8, 0x73, 0x3e, 0x0a, 0x9c, 0xdf, 0x94, 0xdf,
- 0x45, 0x2e, 0x5b, 0x18, 0x44, 0x0e, 0x80, 0xd5, 0xaf, 0x83, 0xef, 0xbc,
- 0x29, 0xc1, 0xae, 0xc4, 0xab, 0xe0, 0x6f, 0x18, 0xb2, 0xd9, 0x84, 0x3e,
- 0x06, 0xda, 0x07, 0x58, 0x13, 0x68, 0x69, 0xb7, 0xba, 0x10, 0x4f, 0x11,
- 0xbb, 0x24, 0x98, 0x1c, 0xe9, 0x06, 0xfd, 0x2b, 0x01, 0xe6, 0x82, 0xc1,
- 0xd8, 0x6a, 0xfb, 0x37, 0xdd, 0xf6, 0x41, 0xf0, 0xc2, 0xe7, 0x88, 0x09,
- 0x24, 0x38, 0x35, 0x62, 0x82, 0x07, 0xf6, 0x0d, 0xa9, 0xbe, 0xe9, 0x45,
- 0xda, 0x40, 0x23, 0x53, 0xb1, 0x1e, 0x91, 0xd4, 0xc2, 0x56, 0x19, 0x5f,
- 0xe8, 0x95, 0x5d, 0x0b, 0xc4, 0x30, 0xac, 0x69, 0x60, 0x2a, 0xc0, 0x18,
- 0xfa, 0x05, 0xe6, 0x76, 0xd1, 0xf0, 0x41, 0xe9, 0x0f, 0x7f, 0x15, 0xeb,
- 0x60, 0xca, 0x8a, 0x45, 0x66, 0xb1, 0xc6, 0x02, 0x8a, 0x4e, 0xd8, 0x1f,
- 0x93, 0x36, 0xba, 0x66, 0xdc, 0xf4, 0xe2, 0xbd, 0xe8, 0x62, 0xe1, 0x5c,
- 0x08, 0xaf, 0xa3, 0xfb, 0x57, 0x1e, 0x5d, 0x13, 0x74, 0xfb, 0x40, 0x93,
- 0x73, 0x7c, 0xa8, 0x73, 0xec, 0xb4, 0xd8, 0x1d, 0xe0, 0x2f, 0x1d, 0x7b,
- 0x58, 0x66, 0x41, 0xe7, 0xe8, 0x02, 0xfd, 0xa4, 0x6c, 0xc5, 0x67, 0xb8,
- 0x4d, 0x62, 0x83, 0xe7, 0x81, 0x73, 0xc6, 0x14, 0x0d, 0x17, 0x73, 0xe8,
- 0x17, 0x12, 0xc0, 0xa9, 0x1f, 0x07, 0x3f, 0xcc, 0xb1, 0x38, 0xe7, 0x00,
- 0xe6, 0x9b, 0xc0, 0x3a, 0x64, 0x7d, 0x85, 0xeb, 0x1b, 0xbf, 0xcf, 0x87,
- 0x3b, 0x53, 0xa7, 0xdb, 0xb1, 0xee, 0xe4, 0x11, 0x43, 0xc5, 0x7e, 0xea,
- 0xc5, 0xea, 0x4c, 0x96, 0x14, 0xdf, 0x9d, 0xa9, 0x12, 0x65, 0x14, 0xef,
- 0x4c, 0x97, 0x28, 0x23, 0x01, 0x3f, 0x71, 0xd8, 0x64, 0x40, 0x22, 0x5b,
- 0xa8, 0xc7, 0x43, 0xe8, 0xf7, 0x57, 0x01, 0xe2, 0xb8, 0xa4, 0xc5, 0xdf,
- 0xf0, 0xb5, 0x17, 0x0e, 0xa3, 0x2f, 0x7f, 0x6f, 0x07, 0xdd, 0xfe, 0xc1,
- 0x82, 0xb4, 0x0f, 0xce, 0xc0, 0x4f, 0xe8, 0x23, 0xc0, 0x91, 0xca, 0xce,
- 0x9b, 0xc0, 0xd8, 0x3b, 0x30, 0x1f, 0xac, 0x8d, 0x98, 0x25, 0xd3, 0xf3,
- 0x94, 0xab, 0x7c, 0x08, 0x73, 0xc0, 0xfc, 0x63, 0xf0, 0x2d, 0x9c, 0x03,
- 0xc7, 0x16, 0xe4, 0x36, 0x4b, 0x92, 0x9b, 0x0f, 0x2a, 0x2c, 0x6b, 0x9b,
- 0x1c, 0x5f, 0xd3, 0xf4, 0x44, 0x17, 0x74, 0xcc, 0xb9, 0xcd, 0x81, 0xb7,
- 0x67, 0x10, 0xff, 0xa2, 0x0a, 0x43, 0x19, 0x17, 0xb8, 0x56, 0x46, 0xb1,
- 0x4e, 0xc8, 0xbf, 0x67, 0x7b, 0x5a, 0x03, 0x3e, 0x45, 0xf9, 0x7f, 0xe4,
- 0xea, 0x09, 0xf8, 0x91, 0x51, 0xf9, 0x7d, 0xf8, 0x92, 0x1f, 0xd7, 0xe3,
- 0xc8, 0x1b, 0x86, 0x91, 0x37, 0x0c, 0x22, 0x6f, 0xb0, 0x90, 0x37, 0x44,
- 0x90, 0x37, 0xf4, 0x21, 0x6f, 0x08, 0x23, 0x3e, 0x88, 0x1c, 0xad, 0xe7,
- 0x61, 0x63, 0x0d, 0xf8, 0x41, 0x33, 0x68, 0xd7, 0x43, 0xc1, 0x64, 0x3d,
- 0x1c, 0x4c, 0xd5, 0x03, 0x98, 0xd3, 0x01, 0x8e, 0x89, 0xf9, 0xe5, 0x3b,
- 0xc7, 0x4a, 0xc3, 0x88, 0x39, 0x36, 0xfc, 0x52, 0x1a, 0xf1, 0x36, 0x2e,
- 0x47, 0xf0, 0xcc, 0xf2, 0x7c, 0x04, 0xcf, 0x34, 0x25, 0x1d, 0x6f, 0x93,
- 0x59, 0x33, 0x0e, 0x1a, 0x5b, 0x94, 0x9d, 0x22, 0xdf, 0x6a, 0x83, 0x9d,
- 0x4a, 0xae, 0xc8, 0x7c, 0xab, 0x0f, 0xf4, 0x3a, 0x11, 0x97, 0xe9, 0x1f,
- 0xe8, 0x0b, 0xec, 0xdd, 0x5f, 0xb2, 0xb8, 0xe6, 0xba, 0xb4, 0xe4, 0xe9,
- 0xbc, 0x10, 0x6b, 0x22, 0x0e, 0xc2, 0x2e, 0xd8, 0x36, 0x81, 0xe7, 0xf8,
- 0xfb, 0x6d, 0xcf, 0xef, 0x7f, 0x24, 0x28, 0x30, 0xde, 0x4b, 0x8c, 0xf9,
- 0x16, 0xe8, 0x39, 0xad, 0xeb, 0xb5, 0xa6, 0x8b, 0xe5, 0xdf, 0x67, 0xfd,
- 0x8d, 0x35, 0xc7, 0xd7, 0xc0, 0x73, 0xbf, 0xb9, 0x8c, 0x1c, 0xd9, 0xde,
- 0xbf, 0x82, 0xdf, 0xad, 0xfd, 0xeb, 0xe8, 0xaf, 0xda, 0x82, 0x66, 0x22,
- 0xce, 0x7c, 0x18, 0x3e, 0x73, 0x10, 0xfe, 0xf1, 0x56, 0x46, 0x5f, 0xba,
- 0x89, 0x79, 0x42, 0x9e, 0xc5, 0x5b, 0x99, 0xc0, 0xc0, 0xb5, 0xe6, 0x8b,
- 0xc0, 0x37, 0x63, 0x4b, 0x23, 0x92, 0x5a, 0xea, 0x0f, 0x5f, 0x96, 0xce,
- 0xdb, 0xb6, 0x5c, 0x6b, 0xce, 0x3a, 0xd1, 0xe3, 0xb6, 0x10, 0x6f, 0x99,
- 0x52, 0x01, 0xa9, 0x6d, 0x3b, 0x3b, 0x88, 0x19, 0x2f, 0x8a, 0x1e, 0x91,
- 0xe4, 0x29, 0x5b, 0x46, 0x76, 0xfa, 0xb9, 0xfb, 0x9d, 0x0e, 0xe9, 0x42,
- 0xdb, 0x52, 0x04, 0x7d, 0x88, 0x53, 0x39, 0xef, 0x2c, 0xe6, 0xac, 0xb9,
- 0xcf, 0x78, 0xf5, 0xc9, 0x42, 0x09, 0x73, 0xaf, 0xdf, 0xca, 0x5c, 0x3e,
- 0x05, 0xec, 0x0e, 0x1d, 0x25, 0x4f, 0xb1, 0xae, 0xb0, 0x09, 0x72, 0x1a,
- 0x83, 0xad, 0xd0, 0x06, 0xfa, 0xf1, 0x6c, 0x53, 0xbe, 0x11, 0xa7, 0x5d,
- 0xbc, 0x04, 0x59, 0x82, 0x56, 0xc0, 0x9f, 0x0f, 0x70, 0xde, 0x3c, 0xe5,
- 0x17, 0x46, 0x6e, 0xce, 0xb1, 0x25, 0xd8, 0x99, 0x58, 0x9f, 0x77, 0xdf,
- 0xca, 0x2c, 0x9f, 0x02, 0xfd, 0x01, 0xd6, 0xde, 0xe0, 0xb3, 0x8b, 0xac,
- 0x1d, 0x32, 0x27, 0xdd, 0x05, 0x3d, 0xed, 0x55, 0xb5, 0xb8, 0x64, 0x35,
- 0x2e, 0xd6, 0x49, 0xfa, 0x2c, 0x89, 0x18, 0xd6, 0x7e, 0xe4, 0xaf, 0x62,
- 0xea, 0x89, 0x49, 0xdc, 0xa3, 0x3c, 0x35, 0xe4, 0x1c, 0xb8, 0x7f, 0x61,
- 0x45, 0xe9, 0xc4, 0x80, 0xee, 0x72, 0x3b, 0x99, 0x84, 0xc9, 0xbc, 0x91,
- 0x80, 0x2f, 0x1c, 0xe1, 0x1c, 0xd4, 0xd8, 0xc8, 0xc7, 0xb9, 0xfe, 0x30,
- 0x67, 0xd8, 0x55, 0x4b, 0x5e, 0xae, 0xfe, 0x66, 0x4b, 0x47, 0x60, 0xd3,
- 0x92, 0x6f, 0x43, 0x3e, 0x90, 0x1c, 0xc1, 0x6f, 0x38, 0x81, 0xa3, 0xd0,
- 0xe7, 0xd9, 0x11, 0xd6, 0x3f, 0x5f, 0x02, 0xb6, 0x27, 0xdf, 0xb1, 0xc8,
- 0x11, 0xb5, 0x86, 0x71, 0xed, 0x30, 0x97, 0xdb, 0x24, 0x97, 0xd5, 0xfc,
- 0x1e, 0x22, 0xf6, 0x80, 0x9e, 0xee, 0x67, 0x7e, 0xe3, 0xf7, 0x39, 0x3f,
- 0x97, 0x3e, 0x63, 0x57, 0xd2, 0x8a, 0x48, 0xaa, 0x78, 0xa9, 0x19, 0xb0,
- 0x2c, 0x60, 0x67, 0x57, 0x8f, 0x29, 0x27, 0x08, 0x3e, 0x58, 0x6b, 0xdb,
- 0xa9, 0x74, 0x09, 0x3e, 0x68, 0x3b, 0xf9, 0x60, 0x62, 0xb3, 0x9c, 0x9b,
- 0xef, 0x91, 0xca, 0xfc, 0xcf, 0xa5, 0x3a, 0xdf, 0x25, 0xe7, 0xe7, 0x9b,
- 0x72, 0x35, 0xae, 0x7c, 0x93, 0xd5, 0xae, 0xd6, 0xb5, 0x3c, 0xec, 0xd6,
- 0x61, 0x62, 0xa3, 0xd7, 0xe5, 0x79, 0x39, 0x57, 0x76, 0x79, 0xcf, 0xb4,
- 0xf0, 0x7e, 0x15, 0xb6, 0xf6, 0xaa, 0x45, 0xfe, 0x47, 0xa4, 0x52, 0x24,
- 0xef, 0xfb, 0x14, 0xef, 0xbb, 0x56, 0x79, 0x97, 0xac, 0x61, 0x91, 0xff,
- 0x8d, 0x78, 0xef, 0x90, 0xec, 0x56, 0xf2, 0x1f, 0xc1, 0xb3, 0xef, 0xb4,
- 0xbf, 0x8a, 0x73, 0xad, 0xb9, 0x5c, 0x6c, 0x53, 0x3c, 0x1b, 0x89, 0x11,
- 0xc8, 0xe7, 0x5a, 0xb3, 0xe1, 0x70, 0x1d, 0xe1, 0xb7, 0xf3, 0x2f, 0xe0,
- 0xab, 0x7a, 0x55, 0xce, 0x92, 0x9b, 0xec, 0xee, 0x4c, 0x2e, 0x8e, 0x42,
- 0xb7, 0x9d, 0x6a, 0x1d, 0xc2, 0x6d, 0x40, 0x67, 0xff, 0x1e, 0xfd, 0xbf,
- 0xcd, 0xf5, 0xa6, 0xe4, 0x92, 0x86, 0x5c, 0x0a, 0xc5, 0xf1, 0x76, 0xe0,
- 0x27, 0x8c, 0xd3, 0xc8, 0x64, 0x1d, 0x3e, 0xd3, 0x07, 0xdf, 0xc6, 0xef,
- 0xf7, 0x6d, 0x0f, 0x79, 0xf8, 0x5c, 0xe8, 0x1c, 0x79, 0x05, 0xd7, 0xf3,
- 0x48, 0x03, 0x31, 0x36, 0x36, 0x58, 0x51, 0xfb, 0x10, 0x71, 0x85, 0x85,
- 0x67, 0x9d, 0x6f, 0xe3, 0xe3, 0x8e, 0x37, 0x56, 0xe7, 0x98, 0x6b, 0xe7,
- 0x54, 0x70, 0x1a, 0xc8, 0xdf, 0x2d, 0xd0, 0xe5, 0xb8, 0x79, 0x31, 0x12,
- 0x06, 0xc6, 0x65, 0x5b, 0x37, 0x7c, 0x4c, 0x04, 0x3e, 0x6b, 0x18, 0xbe,
- 0x9f, 0x6b, 0x99, 0x7e, 0xde, 0xe7, 0x7d, 0x18, 0x34, 0xe9, 0x7f, 0x87,
- 0x31, 0x67, 0xe6, 0xd8, 0xf4, 0x9f, 0x88, 0x27, 0xb5, 0x70, 0x57, 0xf2,
- 0xb4, 0x5b, 0x1b, 0x74, 0x7f, 0xf3, 0xbe, 0x04, 0x1f, 0x49, 0x44, 0xcb,
- 0x79, 0xe4, 0x7e, 0x29, 0xac, 0xd1, 0xa4, 0x85, 0x3c, 0xbb, 0x16, 0x7d,
- 0x85, 0x98, 0x5b, 0xa7, 0x0c, 0x96, 0x28, 0x27, 0xd6, 0xa9, 0x4c, 0xc9,
- 0x57, 0xbe, 0x0b, 0x79, 0x04, 0x65, 0x8b, 0x95, 0x85, 0x4f, 0x01, 0xff,
- 0x98, 0xfb, 0x5c, 0x89, 0xb5, 0xc8, 0x7e, 0xc4, 0x31, 0x03, 0x42, 0x40,
- 0x4e, 0xb5, 0x64, 0xc8, 0x67, 0x03, 0x43, 0xc8, 0x01, 0x9f, 0x45, 0xdf,
- 0x80, 0xe4, 0x97, 0x18, 0x0f, 0x02, 0x32, 0xb7, 0x24, 0x72, 0xfd, 0x14,
- 0xfd, 0x8a, 0xfa, 0x83, 0xcc, 0x1b, 0x99, 0x69, 0x62, 0xed, 0x79, 0xfa,
- 0x18, 0xfa, 0x89, 0x07, 0xa1, 0x8b, 0xd8, 0x4b, 0xdf, 0x40, 0x6c, 0x9a,
- 0x2d, 0xf6, 0xc3, 0x67, 0x4a, 0x43, 0x87, 0x4c, 0x11, 0xd3, 0x98, 0xa3,
- 0x6f, 0x50, 0x77, 0xf4, 0x6b, 0x8e, 0x41, 0x29, 0x9c, 0x62, 0xbd, 0x31,
- 0x08, 0x5e, 0x98, 0xb7, 0x1a, 0x2a, 0x0f, 0x7a, 0x50, 0xf9, 0x56, 0x7e,
- 0x07, 0x5a, 0xc6, 0x8d, 0x1d, 0xdf, 0xa6, 0xd3, 0x8f, 0x3d, 0x22, 0xf6,
- 0xc4, 0xa1, 0xce, 0x5d, 0xa5, 0x76, 0x29, 0xf7, 0xd2, 0x2e, 0xa9, 0xff,
- 0xac, 0x4e, 0x5f, 0x8b, 0x3c, 0x0c, 0xf4, 0x58, 0x23, 0x08, 0xa0, 0x5f,
- 0xc8, 0xeb, 0x47, 0xb9, 0xfe, 0xb6, 0x4c, 0xed, 0xfc, 0x3b, 0xf0, 0xe5,
- 0xfa, 0xb5, 0xdc, 0x4e, 0xf8, 0xdb, 0x09, 0x5d, 0x1e, 0xfb, 0x54, 0x1a,
- 0xcf, 0x32, 0x16, 0xde, 0xf2, 0xf0, 0x38, 0xdb, 0x58, 0xa3, 0x45, 0x9e,
- 0x7e, 0xce, 0xc4, 0x77, 0xaf, 0xe4, 0xcf, 0x05, 0x21, 0x07, 0xe4, 0xc4,
- 0x15, 0x97, 0x16, 0xf3, 0xde, 0xe3, 0xd0, 0x91, 0x7e, 0x32, 0x28, 0x6d,
- 0x27, 0x7b, 0x25, 0xf0, 0xad, 0x2e, 0x69, 0xff, 0xd6, 0x80, 0x18, 0xdf,
- 0x62, 0x2d, 0x29, 0x1a, 0x39, 0xaa, 0xea, 0x58, 0x69, 0x39, 0x86, 0xf8,
- 0xa5, 0x23, 0x16, 0x2b, 0x3b, 0x35, 0xb7, 0x8a, 0x81, 0xc4, 0x55, 0x7f,
- 0xc1, 0x96, 0xaf, 0xef, 0xfc, 0x85, 0xaa, 0xa3, 0x26, 0x47, 0x70, 0xfd,
- 0x72, 0x06, 0xd8, 0x44, 0x83, 0xad, 0x34, 0x32, 0xd7, 0x1e, 0xf5, 0x73,
- 0xcb, 0x41, 0x55, 0x93, 0xff, 0xfa, 0x4e, 0x37, 0xb7, 0x9c, 0x45, 0x6e,
- 0x99, 0x56, 0xb9, 0x25, 0xfc, 0x6b, 0x80, 0xfd, 0xb6, 0x8a, 0x8e, 0xb1,
- 0x72, 0xc2, 0x5c, 0xfd, 0xa3, 0x62, 0x1f, 0xc0, 0xba, 0x38, 0x23, 0xf3,
- 0x7a, 0x42, 0x53, 0x34, 0x8d, 0x17, 0xe8, 0xa7, 0xe8, 0xbf, 0x68, 0xe3,
- 0xac, 0x69, 0xa1, 0xed, 0x65, 0xfa, 0x28, 0xd7, 0xb6, 0xc7, 0x5a, 0x7c,
- 0xdd, 0x5c, 0xa9, 0x0e, 0x1d, 0x22, 0xa7, 0xb7, 0xda, 0x30, 0x7f, 0xc4,
- 0x74, 0x8b, 0xd7, 0x9c, 0x3f, 0x7c, 0x67, 0x28, 0xa4, 0xae, 0x0b, 0x65,
- 0xb7, 0x86, 0xe1, 0xd2, 0x67, 0xfe, 0x01, 0x1f, 0x53, 0x27, 0x1f, 0x1c,
- 0xb7, 0x4f, 0x8c, 0x33, 0x21, 0x09, 0x9c, 0xa1, 0xfd, 0x45, 0x23, 0x69,
- 0xc8, 0x6f, 0xce, 0x22, 0x06, 0x3c, 0x04, 0x6c, 0xf4, 0x88, 0xe8, 0xe7,
- 0x06, 0xb1, 0x76, 0xa2, 0xe1, 0xb2, 0xc4, 0xc4, 0xa8, 0x04, 0xe5, 0x8d,
- 0x53, 0xd1, 0x08, 0xed, 0xe5, 0x2c, 0xe2, 0xd5, 0x91, 0x7a, 0xe7, 0xed,
- 0x86, 0xe2, 0x82, 0x6d, 0xdf, 0x08, 0x00, 0x3b, 0x0c, 0xda, 0x7a, 0xb7,
- 0xdc, 0x80, 0xbe, 0xb3, 0xaa, 0xed, 0x11, 0xd0, 0x05, 0x0f, 0x67, 0x58,
- 0x1b, 0x24, 0xdd, 0xa3, 0xa0, 0x49, 0xda, 0x8d, 0xcc, 0x32, 0x73, 0xd3,
- 0x53, 0xb4, 0xdd, 0x5e, 0xd8, 0x1d, 0xae, 0xeb, 0xed, 0x92, 0x9d, 0x8c,
- 0x88, 0x7e, 0x6a, 0x8f, 0xf4, 0xef, 0xd4, 0xdd, 0xf9, 0xa8, 0x39, 0xb2,
- 0x8d, 0x35, 0xe7, 0x11, 0xb5, 0x1e, 0xf5, 0x25, 0xd8, 0xcc, 0x3e, 0xea,
- 0x18, 0xb1, 0x1f, 0x71, 0x8c, 0x7e, 0xcc, 0x40, 0x1c, 0x4b, 0xd5, 0x5d,
- 0xbd, 0x97, 0xf7, 0x6d, 0x95, 0x63, 0x67, 0x68, 0x4f, 0xb8, 0xb7, 0x6a,
- 0x53, 0xfe, 0xde, 0x10, 0xef, 0x59, 0x72, 0xfc, 0x45, 0xe6, 0x1e, 0xcc,
- 0x39, 0x98, 0x67, 0x45, 0xc3, 0xbb, 0x30, 0x1f, 0xfd, 0x31, 0xfa, 0x03,
- 0x5d, 0xd9, 0x6e, 0x0e, 0x3e, 0xba, 0x50, 0xa7, 0xde, 0x86, 0xb9, 0x7f,
- 0x66, 0x32, 0x5f, 0xb3, 0xc3, 0xae, 0xbc, 0x0b, 0x68, 0x9b, 0x85, 0xef,
- 0x4f, 0x39, 0x6d, 0xb2, 0x32, 0x69, 0x43, 0xf7, 0x5f, 0x02, 0x5f, 0x07,
- 0x3a, 0x59, 0x23, 0x58, 0x99, 0x4c, 0xe3, 0xfa, 0x80, 0xca, 0xd1, 0x8c,
- 0xc7, 0x6c, 0xd0, 0xd8, 0xca, 0x75, 0xe4, 0xe9, 0x29, 0xae, 0x17, 0xe6,
- 0x1f, 0xd3, 0x67, 0xe1, 0xb3, 0xc7, 0xe3, 0x8c, 0xf1, 0xdc, 0x4b, 0xe8,
- 0x00, 0x1f, 0xdd, 0x0a, 0x57, 0xe8, 0xd6, 0x4e, 0xbd, 0x50, 0xa6, 0x9f,
- 0xcf, 0x87, 0xdb, 0x85, 0x78, 0xc4, 0xd4, 0x2b, 0x16, 0x75, 0xa2, 0xc9,
- 0x65, 0xb5, 0xef, 0x20, 0x92, 0x76, 0x0e, 0x61, 0xac, 0xb8, 0x5e, 0x2d,
- 0xef, 0xd4, 0xf3, 0x65, 0x43, 0x56, 0x42, 0xe4, 0x3b, 0xa2, 0xf2, 0xf8,
- 0x9d, 0xca, 0xd6, 0x8a, 0x88, 0x25, 0xb0, 0x99, 0xf8, 0x87, 0x31, 0xae,
- 0x6a, 0x83, 0x4d, 0x51, 0xf7, 0xd4, 0xbb, 0xf2, 0x91, 0x9e, 0xee, 0x37,
- 0x8a, 0x99, 0x45, 0xf8, 0x5f, 0xd6, 0x2f, 0x3a, 0xbc, 0x5a, 0xe3, 0x4b,
- 0x5e, 0x3e, 0xf4, 0x8c, 0x30, 0x4f, 0x99, 0x2b, 0x91, 0x97, 0x22, 0xfc,
- 0xe1, 0x46, 0xb6, 0x44, 0x39, 0xba, 0x3e, 0xe5, 0x10, 0xec, 0x42, 0x5f,
- 0x32, 0x3d, 0x1b, 0xe0, 0xdf, 0x28, 0xee, 0x31, 0x06, 0xe0, 0xbb, 0xde,
- 0x86, 0xf5, 0xbe, 0x17, 0x32, 0xa2, 0x6e, 0xa0, 0xbf, 0x25, 0xee, 0xbb,
- 0x42, 0x7f, 0x4b, 0x57, 0xde, 0xb6, 0x7b, 0xe9, 0xf3, 0x46, 0xe4, 0x18,
- 0xfc, 0xe8, 0xd1, 0x45, 0xf2, 0x93, 0xf6, 0x70, 0xd9, 0x30, 0x64, 0x42,
- 0x1f, 0x3f, 0x2c, 0x6f, 0xd4, 0x7e, 0xa0, 0x70, 0xe0, 0xb6, 0x9d, 0x0d,
- 0x99, 0x86, 0x7f, 0x98, 0x71, 0x20, 0x7f, 0x33, 0x82, 0xf5, 0x19, 0x56,
- 0xfe, 0x71, 0xe6, 0xfd, 0xe5, 0x24, 0x01, 0x37, 0x66, 0x7f, 0xf6, 0x3e,
- 0x63, 0xf6, 0x03, 0xc0, 0x61, 0xef, 0x8b, 0xbe, 0xe1, 0xd2, 0xff, 0x33,
- 0xe8, 0xea, 0xd7, 0x55, 0xfd, 0x22, 0xb7, 0x73, 0x2b, 0x65, 0xfa, 0x5e,
- 0xcf, 0xe9, 0xee, 0x73, 0x9f, 0xbb, 0x4f, 0xbe, 0x4c, 0xa9, 0x01, 0x2b,
- 0xe4, 0x55, 0x1c, 0x65, 0xae, 0xd8, 0xe6, 0xe9, 0x6f, 0x10, 0x18, 0x9a,
- 0x74, 0x7d, 0xdf, 0xdb, 0x21, 0xf9, 0x5e, 0x3f, 0xff, 0x84, 0xcf, 0x5e,
- 0x6d, 0xf7, 0xf3, 0x59, 0x3e, 0xbf, 0x92, 0x41, 0xfe, 0x0c, 0x1b, 0x60,
- 0x2c, 0x60, 0x5b, 0x5c, 0xf9, 0xa1, 0x77, 0xe7, 0x9b, 0xf5, 0x0b, 0xf2,
- 0xbd, 0x5b, 0xf1, 0x9d, 0x56, 0x7c, 0xb3, 0x06, 0xb9, 0x5f, 0x4b, 0x9d,
- 0x67, 0x1d, 0xd2, 0xaf, 0x3b, 0x92, 0x1e, 0xb0, 0x01, 0xf4, 0xfd, 0x63,
- 0xd0, 0xfd, 0x11, 0xf4, 0xfa, 0xc3, 0x12, 0xb0, 0x41, 0x09, 0xd8, 0xa0,
- 0x04, 0x6c, 0x50, 0x02, 0x36, 0x28, 0x85, 0xbd, 0x3a, 0x8b, 0x4d, 0x6c,
- 0xff, 0x3e, 0x6d, 0xd7, 0xaf, 0x6d, 0xac, 0xb7, 0x4b, 0xb7, 0xb6, 0x99,
- 0xaa, 0xfb, 0x18, 0x39, 0xc8, 0x5a, 0x2b, 0xb0, 0x9a, 0x5f, 0xf7, 0xf0,
- 0x62, 0x44, 0x8d, 0xfb, 0x5e, 0x88, 0x11, 0x35, 0x1b, 0xeb, 0x66, 0x28,
- 0x6c, 0x00, 0x1b, 0x1a, 0x12, 0xc6, 0x6f, 0x13, 0xbe, 0x17, 0xb4, 0x86,
- 0xfb, 0xb1, 0x92, 0xda, 0x55, 0x5d, 0xef, 0x88, 0xaa, 0x3b, 0x58, 0x32,
- 0x5b, 0xf6, 0x73, 0xb7, 0x98, 0x8c, 0xcd, 0x13, 0x6f, 0xca, 0x16, 0x3d,
- 0x01, 0x1d, 0x38, 0xc4, 0x88, 0xdc, 0x27, 0xe4, 0xf8, 0xb1, 0xc1, 0x2a,
- 0xc6, 0x2c, 0x58, 0x2e, 0x7f, 0x47, 0x9c, 0xbb, 0xcf, 0xec, 0x82, 0x7f,
- 0xce, 0x14, 0x23, 0x32, 0x5e, 0x74, 0x31, 0x01, 0xf2, 0x9f, 0x75, 0xf5,
- 0xe5, 0x5b, 0xd0, 0xc3, 0xad, 0xcc, 0x94, 0xb5, 0x6a, 0x1b, 0x91, 0xcb,
- 0x71, 0xca, 0x98, 0xfa, 0xdf, 0xab, 0xf6, 0x29, 0x76, 0x55, 0xdd, 0xbd,
- 0xa4, 0x71, 0x65, 0x0b, 0x01, 0xfa, 0x19, 0xd0, 0x89, 0xbb, 0x6b, 0x18,
- 0x76, 0x91, 0x73, 0x7c, 0xb9, 0xb4, 0xe2, 0x91, 0x2f, 0x6a, 0x62, 0x6d,
- 0xd4, 0xfe, 0x1b, 0x2d, 0xed, 0xab, 0xf7, 0x3d, 0x7e, 0xe1, 0xfb, 0x56,
- 0x6b, 0x0d, 0xf4, 0x53, 0x77, 0xdb, 0x81, 0xdd, 0x24, 0xa0, 0xee, 0xc3,
- 0x87, 0xd7, 0x42, 0x92, 0xaa, 0x59, 0x92, 0x2e, 0xb3, 0x1f, 0xeb, 0x17,
- 0xf4, 0x47, 0x7f, 0x22, 0x29, 0xe4, 0xab, 0xd9, 0x50, 0x34, 0x6e, 0xcb,
- 0x7f, 0x96, 0xe5, 0x85, 0x7c, 0x84, 0xe7, 0x0a, 0xf2, 0x13, 0x1a, 0x9e,
- 0xfb, 0x19, 0xae, 0xc9, 0xb3, 0x25, 0x33, 0x45, 0xc6, 0x9d, 0xa1, 0x70,
- 0x0d, 0xf7, 0xb2, 0x93, 0xac, 0xd9, 0x7c, 0x07, 0x36, 0x19, 0x8d, 0x94,
- 0xa1, 0xef, 0x2b, 0x45, 0x8e, 0x07, 0x6c, 0x54, 0x64, 0x5d, 0xc7, 0xbf,
- 0xff, 0x27, 0xc0, 0x81, 0xf0, 0xd5, 0x21, 0xaf, 0x8f, 0x9a, 0xab, 0x6d,
- 0x06, 0x60, 0xe3, 0x0d, 0xcf, 0xdf, 0x56, 0x8a, 0x6e, 0x1d, 0xe5, 0x2c,
- 0xf9, 0x70, 0xfe, 0x77, 0xb3, 0x11, 0x42, 0x0e, 0xb4, 0x3a, 0xc7, 0xab,
- 0xa4, 0x6f, 0xc2, 0xdd, 0xca, 0x51, 0xc7, 0x97, 0x05, 0xef, 0xb3, 0x8d,
- 0x67, 0x27, 0x9a, 0xcd, 0xb3, 0xd6, 0x07, 0xad, 0x99, 0xf5, 0x6d, 0x4f,
- 0x5a, 0xf9, 0xdd, 0x15, 0x27, 0xef, 0xd5, 0xcc, 0xbe, 0xbd, 0xc3, 0xad,
- 0x99, 0xd5, 0x76, 0xac, 0xad, 0x99, 0x59, 0xdb, 0xdd, 0x9a, 0xd9, 0xfc,
- 0xee, 0x02, 0x3e, 0x6e, 0xcd, 0x2c, 0xbb, 0xdd, 0xad, 0x99, 0x95, 0xb7,
- 0xbb, 0x35, 0x33, 0x67, 0x87, 0x5b, 0x33, 0xfb, 0xf9, 0xf6, 0xb5, 0x35,
- 0xb3, 0x1f, 0xec, 0x58, 0x5b, 0x33, 0xbb, 0xb8, 0x3b, 0x87, 0xcf, 0xdd,
- 0x9a, 0xd9, 0xcf, 0x76, 0xdc, 0xbb, 0x66, 0xf6, 0x9a, 0x8f, 0xd7, 0x31,
- 0x9f, 0x11, 0xcc, 0x21, 0x0e, 0xbc, 0x3e, 0x0c, 0xbc, 0xfe, 0x6e, 0x75,
- 0xfe, 0x00, 0xe6, 0x39, 0xe8, 0xc5, 0x83, 0x0f, 0x82, 0xdb, 0x47, 0xbc,
- 0x67, 0x6d, 0xe4, 0xbb, 0x11, 0x2f, 0x57, 0x21, 0x76, 0xdf, 0xec, 0xe5,
- 0x6c, 0xff, 0xa8, 0xf3, 0xee, 0xb9, 0x97, 0xd6, 0xef, 0x0f, 0x21, 0xf5,
- 0xf6, 0xf1, 0x3c, 0xe7, 0x95, 0x47, 0xee, 0x47, 0x39, 0xd8, 0xe8, 0x3f,
- 0xbf, 0xfb, 0x1b, 0x16, 0x31, 0xfe, 0x73, 0x58, 0xab, 0xf6, 0x16, 0x43,
- 0x9d, 0x01, 0x60, 0x8c, 0x3a, 0x2e, 0x29, 0xf4, 0x4f, 0xa9, 0xfe, 0xd7,
- 0x5a, 0xfa, 0xaf, 0xa0, 0x3f, 0xe9, 0x46, 0xff, 0x1d, 0x3e, 0x2f, 0x29,
- 0xfb, 0xb6, 0x5c, 0x0c, 0x9f, 0x2e, 0xf9, 0x78, 0x2b, 0xe0, 0x61, 0xe7,
- 0x46, 0xc6, 0x76, 0x3e, 0x8f, 0x67, 0xa2, 0x17, 0x6d, 0xb9, 0xa9, 0xf0,
- 0xbb, 0x91, 0x88, 0x5e, 0xcc, 0xaa, 0x7c, 0xad, 0x91, 0xc9, 0x39, 0x7e,
- 0xfe, 0x8d, 0x1c, 0x6a, 0x80, 0x39, 0x0c, 0xec, 0x7d, 0x69, 0x10, 0x71,
- 0xac, 0x35, 0xc7, 0x66, 0x5e, 0xad, 0x7b, 0x79, 0xb5, 0x29, 0x9f, 0xd9,
- 0xd9, 0x8a, 0xcd, 0x2f, 0xee, 0xfe, 0xc7, 0x0a, 0x9b, 0x6f, 0x42, 0x6e,
- 0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7a, 0x01, 0xf3,
- 0x19, 0xc6, 0x46, 0xe6, 0x37, 0x21, 0x7c, 0x78, 0x26, 0xc9, 0xc7, 0xe8,
- 0xed, 0x9e, 0x7f, 0x67, 0x5e, 0xe4, 0x63, 0x95, 0xe4, 0x26, 0x37, 0x37,
- 0xda, 0xa4, 0xb9, 0xf9, 0x67, 0xc4, 0xeb, 0x13, 0x58, 0xc5, 0xc2, 0x81,
- 0x55, 0x2c, 0xbc, 0x66, 0x1f, 0x4b, 0xd4, 0xf9, 0x27, 0xb5, 0x1f, 0xc6,
- 0xfd, 0xb1, 0x46, 0xe6, 0xca, 0x80, 0x68, 0x7a, 0x82, 0xfb, 0x64, 0xc0,
- 0x3a, 0x16, 0xf7, 0xcd, 0xe8, 0x3b, 0xf7, 0x69, 0xa9, 0x2a, 0xe3, 0x0f,
- 0xf1, 0x91, 0xbf, 0x17, 0xee, 0xeb, 0x89, 0xb2, 0x63, 0xdb, 0x1f, 0x6b,
- 0xc8, 0x79, 0xe3, 0xed, 0xd6, 0x53, 0xe0, 0x25, 0x83, 0x6f, 0x5f, 0xa6,
- 0x9f, 0x55, 0xb1, 0xaf, 0x03, 0xb6, 0x7b, 0xa4, 0x44, 0xec, 0xba, 0x59,
- 0x6a, 0x1e, 0x7e, 0x3d, 0x37, 0xef, 0x62, 0xd7, 0xc0, 0x5a, 0xec, 0x1a,
- 0x5f, 0x16, 0x97, 0xc7, 0x5d, 0x1b, 0xf2, 0x48, 0xbc, 0x4a, 0xfe, 0x18,
- 0x77, 0xf6, 0xc2, 0xff, 0x35, 0x80, 0x69, 0x19, 0x73, 0x18, 0x6f, 0x22,
- 0xc0, 0xf6, 0xf7, 0xe2, 0x4f, 0xb5, 0x1d, 0xea, 0xb0, 0x82, 0xf8, 0x4c,
- 0xc3, 0x7f, 0x4c, 0xe0, 0x99, 0x8c, 0xcc, 0x9e, 0xfe, 0x1a, 0xe6, 0x36,
- 0x2d, 0x57, 0xe6, 0x27, 0xc1, 0xdf, 0x73, 0x32, 0x17, 0xcf, 0xc3, 0x8f,
- 0x70, 0xcf, 0x83, 0xb8, 0xad, 0xdf, 0xfb, 0x9e, 0xd6, 0xcf, 0x5a, 0x51,
- 0xe2, 0x46, 0xa9, 0x16, 0xe9, 0x83, 0xb9, 0x67, 0xc8, 0xbd, 0x61, 0xda,
- 0x0f, 0xeb, 0x27, 0xc8, 0x5d, 0x99, 0xc3, 0x9e, 0xe2, 0xf8, 0x6b, 0x75,
- 0xb2, 0xec, 0x10, 0x7f, 0x35, 0x32, 0x8d, 0x25, 0xe2, 0xc7, 0xf7, 0x8b,
- 0x25, 0xa9, 0x07, 0xe2, 0xc9, 0xfb, 0xc1, 0x91, 0xd1, 0x79, 0x60, 0xc8,
- 0x57, 0x1a, 0x7a, 0x2b, 0x8e, 0x74, 0x31, 0x64, 0x72, 0x29, 0x0b, 0x9a,
- 0x71, 0x85, 0x95, 0x91, 0xc7, 0xc1, 0xed, 0xf5, 0xe3, 0xd9, 0x7e, 0xe4,
- 0xe4, 0x2e, 0x66, 0x4c, 0x01, 0x33, 0xfe, 0x06, 0x30, 0xe3, 0xac, 0x74,
- 0x76, 0x11, 0x33, 0xda, 0x1e, 0x66, 0x4c, 0xc3, 0x9e, 0x73, 0x6b, 0xec,
- 0x59, 0x53, 0xb5, 0x28, 0xde, 0xcb, 0x01, 0xf3, 0xa5, 0x4e, 0x45, 0xef,
- 0x03, 0x27, 0x6a, 0x12, 0x52, 0xe7, 0x52, 0x02, 0x2d, 0x34, 0x7d, 0x3c,
- 0xb8, 0x4d, 0xe1, 0xbc, 0xdd, 0xa5, 0x4d, 0xc8, 0x51, 0x14, 0xee, 0xf3,
- 0xf6, 0x4b, 0x03, 0xeb, 0xf6, 0x90, 0x03, 0x2d, 0x7b, 0xc8, 0x77, 0xf1,
- 0x21, 0x9e, 0xf3, 0x6a, 0x7d, 0x6d, 0xf0, 0x05, 0xff, 0x13, 0x3c, 0x71,
- 0x7d, 0x71, 0x2d, 0x68, 0xee, 0x7a, 0x59, 0x83, 0x13, 0xff, 0x7a, 0x1d,
- 0x4e, 0x44, 0xec, 0x3a, 0x17, 0x92, 0x24, 0x30, 0xa2, 0xbd, 0x44, 0x5a,
- 0x5c, 0xd3, 0xc3, 0xd2, 0x8e, 0xf9, 0x75, 0x9c, 0xea, 0x05, 0x36, 0xea,
- 0x92, 0x20, 0x30, 0x52, 0x9b, 0xc2, 0x48, 0x03, 0xc4, 0x32, 0x83, 0x33,
- 0xc0, 0x36, 0xb5, 0x55, 0x9c, 0x14, 0x8d, 0xff, 0x01, 0xf4, 0xf2, 0x94,
- 0xf2, 0x3d, 0x69, 0x39, 0x01, 0x5f, 0xda, 0xbe, 0x04, 0x7c, 0x77, 0xce,
- 0xc5, 0x4f, 0x6d, 0xeb, 0xf0, 0xd3, 0xc1, 0x0d, 0xf1, 0x93, 0xaa, 0xdf,
- 0x8f, 0x52, 0x26, 0x37, 0x1c, 0xb7, 0x7e, 0x7f, 0xdd, 0x71, 0xeb, 0xf7,
- 0x37, 0x9c, 0xd6, 0xfa, 0xfd, 0x47, 0xa4, 0x60, 0x46, 0xed, 0x15, 0x59,
- 0x57, 0xbf, 0x9f, 0x60, 0x3d, 0xdc, 0xe9, 0x72, 0xeb, 0xf4, 0x5d, 0x5e,
- 0xfd, 0x3e, 0x2a, 0x85, 0x35, 0xed, 0xa6, 0xbc, 0x69, 0xf9, 0xf5, 0xfb,
- 0xef, 0xa2, 0xad, 0x1b, 0x63, 0xac, 0xad, 0xdd, 0x5f, 0x77, 0x58, 0xbb,
- 0x0f, 0xb1, 0x9f, 0x57, 0xbb, 0x67, 0x3f, 0xe4, 0xf2, 0x0e, 0xeb, 0xf6,
- 0x8f, 0x40, 0x16, 0x5b, 0x21, 0x87, 0x5e, 0x69, 0x3f, 0x13, 0x66, 0x1f,
- 0x55, 0xaf, 0x5f, 0x71, 0x42, 0x78, 0xce, 0xad, 0xab, 0xcf, 0xc0, 0xae,
- 0x0e, 0xae, 0xd6, 0xeb, 0xdd, 0x31, 0x6e, 0x3a, 0x6b, 0xe9, 0xaf, 0xa5,
- 0xd3, 0xe7, 0xd1, 0x09, 0x81, 0x4e, 0x78, 0x1d, 0x9d, 0xbb, 0xf5, 0xf9,
- 0x9b, 0x8e, 0x5b, 0x9b, 0x4f, 0x9f, 0x16, 0xbb, 0x1d, 0xbe, 0xf9, 0xe2,
- 0xc0, 0xc3, 0x1e, 0x8d, 0xd5, 0xda, 0x3c, 0x7d, 0x08, 0x70, 0x7b, 0x4c,
- 0x9d, 0xbd, 0x9a, 0xf9, 0x7f, 0x50, 0x9b, 0x67, 0x5d, 0xde, 0xdd, 0x5f,
- 0xe1, 0xfa, 0x04, 0x3e, 0x7f, 0xd1, 0xad, 0xc9, 0x8f, 0x95, 0xfc, 0x5a,
- 0x3b, 0xf3, 0x47, 0xff, 0x5c, 0x54, 0x7f, 0xe4, 0x88, 0xd0, 0x56, 0xc8,
- 0x1f, 0xe9, 0x76, 0xcb, 0x94, 0xc2, 0x47, 0xb0, 0xa9, 0xd8, 0xbd, 0x31,
- 0x72, 0xe5, 0x94, 0x8f, 0x91, 0x43, 0x0a, 0x23, 0x57, 0x96, 0x7c, 0x8c,
- 0x9c, 0xbc, 0x07, 0x46, 0x6e, 0x76, 0xb9, 0x71, 0x20, 0x28, 0x79, 0x85,
- 0x91, 0xef, 0x75, 0x96, 0x8c, 0xf7, 0xba, 0x88, 0x07, 0xc4, 0x3d, 0x5f,
- 0xd0, 0x7b, 0x8f, 0xb5, 0xe6, 0xe3, 0x66, 0xc6, 0xfe, 0xad, 0x32, 0x71,
- 0xe6, 0x2e, 0x6e, 0x76, 0xb1, 0x71, 0x34, 0x72, 0x48, 0xc5, 0x44, 0xe0,
- 0x84, 0x3a, 0xeb, 0xdf, 0xc4, 0xbe, 0x8c, 0x39, 0x01, 0x85, 0xcf, 0x72,
- 0x45, 0xe6, 0x01, 0x6c, 0x23, 0x16, 0xee, 0xe4, 0x31, 0x2b, 0x2f, 0x26,
- 0xf9, 0x58, 0xd3, 0x3f, 0xd7, 0xc2, 0x3d, 0x86, 0x37, 0x8d, 0xa4, 0x85,
- 0x76, 0xc7, 0xcf, 0x15, 0xe2, 0xea, 0x3c, 0x50, 0x12, 0x58, 0x72, 0x6a,
- 0x15, 0x4b, 0xd2, 0x57, 0xfc, 0xf4, 0x6d, 0xdb, 0xa4, 0x5f, 0xf3, 0xb1,
- 0x22, 0x72, 0xa2, 0x12, 0xd7, 0xb6, 0x8f, 0x15, 0x5d, 0x9c, 0x98, 0x72,
- 0x1a, 0xc0, 0xcb, 0x01, 0x19, 0x03, 0x4e, 0x6f, 0x7c, 0x89, 0x35, 0x28,
- 0x1f, 0x1b, 0xd9, 0xf8, 0x6e, 0xad, 0x49, 0xf1, 0xba, 0x5d, 0xed, 0x05,
- 0x5e, 0x1e, 0x08, 0xb6, 0xb4, 0x3f, 0x0b, 0xff, 0x8d, 0xfc, 0x08, 0xd8,
- 0xc4, 0xc5, 0x44, 0x3b, 0xa0, 0x83, 0x91, 0x7b, 0x60, 0xa2, 0xf5, 0x31,
- 0x8a, 0x31, 0xf3, 0x6e, 0x8c, 0x4a, 0xd7, 0xe9, 0xcf, 0xef, 0xc6, 0xa8,
- 0x7b, 0xc7, 0x50, 0xb6, 0x61, 0x76, 0x56, 0x06, 0x9f, 0x69, 0x29, 0xac,
- 0x8b, 0x51, 0x73, 0x1f, 0x20, 0x46, 0xb9, 0xf8, 0xc0, 0xe5, 0xfb, 0xf7,
- 0x21, 0x9b, 0x1f, 0x43, 0xa6, 0x3f, 0x02, 0xe6, 0xfa, 0x21, 0xe6, 0xf5,
- 0x03, 0xe0, 0xa1, 0xef, 0x97, 0xd6, 0x9f, 0x07, 0x19, 0x15, 0xe6, 0x87,
- 0x2e, 0x66, 0x72, 0x31, 0xfd, 0x0c, 0x56, 0x57, 0xad, 0xd8, 0xc8, 0x4c,
- 0x15, 0x87, 0xcc, 0x69, 0x77, 0x1f, 0x35, 0x92, 0x95, 0xa7, 0x3b, 0x53,
- 0x8b, 0x8c, 0x19, 0xea, 0x3a, 0xcc, 0xfa, 0x25, 0xb1, 0x43, 0x55, 0xe5,
- 0x99, 0x03, 0x52, 0xae, 0xb9, 0x78, 0x6b, 0x6e, 0xd1, 0xa5, 0x31, 0xe5,
- 0xe1, 0xad, 0x9c, 0x87, 0xb7, 0xb2, 0xb5, 0xe5, 0x48, 0x00, 0xfd, 0xe7,
- 0xe2, 0x6b, 0x31, 0xd6, 0x8c, 0x87, 0xb1, 0xa6, 0x3f, 0x20, 0xc6, 0xe2,
- 0x58, 0x39, 0x3c, 0x33, 0x3e, 0x1f, 0x91, 0x5d, 0x90, 0xf3, 0x58, 0x91,
- 0xfa, 0xe2, 0x19, 0xb2, 0xf7, 0xd2, 0x19, 0xf5, 0xe5, 0xea, 0x2a, 0x10,
- 0xdb, 0xa7, 0x8d, 0x43, 0x57, 0x63, 0xef, 0xa9, 0x2b, 0x31, 0xdf, 0x18,
- 0x09, 0xe2, 0xf3, 0xf7, 0xa5, 0x2b, 0xce, 0x83, 0xfa, 0x5a, 0x8f, 0xc5,
- 0xee, 0x07, 0x93, 0xad, 0xc5, 0x63, 0xb6, 0xc2, 0x63, 0xed, 0x5e, 0x1f,
- 0xd9, 0x33, 0x0e, 0x5d, 0xfe, 0x27, 0xf4, 0xf9, 0x99, 0xd5, 0x2d, 0x3f,
- 0x85, 0xff, 0xfe, 0x43, 0xe8, 0xe4, 0x3f, 0x22, 0x57, 0x78, 0xcd, 0xea,
- 0x93, 0x3f, 0x40, 0xdb, 0x5d, 0x9c, 0xc3, 0xfe, 0xc1, 0xc7, 0x92, 0xd6,
- 0x35, 0xe0, 0x93, 0x6b, 0x1e, 0x3e, 0x79, 0x3a, 0x99, 0xb4, 0x26, 0x59,
- 0x37, 0x87, 0x9c, 0x0f, 0xa4, 0xa6, 0x14, 0x36, 0xf1, 0x31, 0xc9, 0xed,
- 0x34, 0xc7, 0x9f, 0x75, 0x56, 0x80, 0x7d, 0x56, 0x3c, 0xec, 0x73, 0x60,
- 0xcc, 0xc5, 0x3e, 0xc1, 0xcf, 0x50, 0xff, 0x2e, 0xee, 0x59, 0xb1, 0x93,
- 0x18, 0xa7, 0x0a, 0x4c, 0x52, 0x71, 0x0e, 0x48, 0xbe, 0xbe, 0x57, 0x7d,
- 0x8e, 0x94, 0xec, 0x68, 0x1b, 0xe4, 0xc4, 0xda, 0xeb, 0x49, 0xae, 0x4a,
- 0x27, 0x6a, 0x16, 0xf1, 0x9d, 0x75, 0xa2, 0xe1, 0xdf, 0xf1, 0xae, 0x9f,
- 0xf7, 0xae, 0x4f, 0x78, 0xd7, 0xc7, 0x11, 0x87, 0x8f, 0xa9, 0x58, 0xca,
- 0x76, 0xb6, 0x41, 0xc9, 0x0e, 0x68, 0x01, 0x7b, 0x9c, 0x1d, 0xfe, 0x8b,
- 0x66, 0x59, 0xe9, 0x98, 0xf4, 0x27, 0xf0, 0x39, 0x8e, 0xcf, 0x34, 0x3e,
- 0xfb, 0xf1, 0xc9, 0xe3, 0xb3, 0x2a, 0x53, 0x2d, 0x55, 0x9a, 0x84, 0x8d,
- 0x0c, 0x4a, 0xaa, 0xfe, 0x12, 0xf4, 0xf8, 0x1c, 0x74, 0x7b, 0x58, 0x0a,
- 0xd5, 0x3f, 0x95, 0xd9, 0x79, 0x4d, 0xba, 0x2c, 0xe8, 0xb4, 0x0a, 0x5b,
- 0x9e, 0x77, 0xf7, 0x13, 0x3b, 0x13, 0x7b, 0xd1, 0xb7, 0x29, 0x4f, 0xc5,
- 0x9f, 0x13, 0xfd, 0xb1, 0x39, 0xf4, 0x13, 0xbd, 0x30, 0xfc, 0x31, 0xb5,
- 0x6f, 0x56, 0x8d, 0xbb, 0x32, 0xde, 0x65, 0xd9, 0x51, 0xe8, 0x7c, 0xf0,
- 0x18, 0x68, 0x27, 0xd5, 0xd9, 0xd8, 0x8c, 0x1c, 0x3d, 0xbd, 0xbc, 0xc5,
- 0xf5, 0xad, 0x51, 0xf3, 0x26, 0xf5, 0x8e, 0x79, 0xd8, 0xf0, 0x85, 0x19,
- 0xd8, 0xfb, 0x41, 0x27, 0xa0, 0x8d, 0x21, 0xde, 0x8c, 0x39, 0x37, 0x55,
- 0xbc, 0x81, 0xef, 0xca, 0xc4, 0x4e, 0x86, 0x70, 0xcd, 0xb3, 0x45, 0x88,
- 0x8b, 0xea, 0x6c, 0xe5, 0x32, 0xf0, 0x8d, 0xa6, 0xea, 0x80, 0xb3, 0xab,
- 0xfb, 0x43, 0x86, 0xf2, 0x5b, 0xb1, 0x98, 0x2e, 0xb9, 0x11, 0xe2, 0xdc,
- 0xbd, 0x2a, 0x36, 0xd5, 0x8a, 0xf6, 0x43, 0xcc, 0x15, 0x6f, 0x08, 0xe3,
- 0xdc, 0xe3, 0xe8, 0xd7, 0x07, 0x7f, 0x8c, 0x7b, 0x75, 0xda, 0x27, 0xe7,
- 0xca, 0x67, 0xa6, 0xa5, 0x5a, 0x1e, 0xc5, 0x7c, 0xbd, 0x1c, 0x49, 0xe5,
- 0x12, 0x11, 0xd8, 0xa3, 0xbf, 0x17, 0xe5, 0xd6, 0x4f, 0xaa, 0x8e, 0x8f,
- 0x29, 0xba, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xee, 0x9f, 0xa9, 0xbd,
- 0xb3, 0x82, 0x33, 0x0a, 0x39, 0x25, 0xd1, 0xce, 0x5a, 0x35, 0x7e, 0x97,
- 0x75, 0x55, 0x13, 0x58, 0x31, 0x66, 0xa4, 0x56, 0x6e, 0x82, 0x5f, 0xc4,
- 0xdc, 0x2d, 0x33, 0x52, 0x29, 0x4f, 0xcb, 0x2b, 0xe5, 0x9f, 0x77, 0x03,
- 0x53, 0x41, 0xa6, 0xe4, 0xbf, 0x5b, 0xee, 0x9e, 0xbf, 0xf5, 0xdb, 0x21,
- 0xcf, 0xd3, 0xf9, 0xb0, 0x9b, 0xe7, 0xe6, 0x55, 0x2d, 0xc6, 0xfd, 0xb6,
- 0xf5, 0x29, 0x2b, 0x1a, 0x9e, 0x45, 0xcf, 0x83, 0x0b, 0xb4, 0xcd, 0xfc,
- 0xf8, 0x9c, 0xb5, 0x43, 0xae, 0xc6, 0x37, 0xcb, 0x72, 0x5c, 0xe5, 0xc5,
- 0xc4, 0x0f, 0x58, 0xeb, 0x51, 0xb3, 0x21, 0x7b, 0xe4, 0x28, 0xd6, 0xed,
- 0xd5, 0xf8, 0xd3, 0xb0, 0xd3, 0x67, 0x61, 0x0b, 0xac, 0x01, 0x1c, 0x62,
- 0xae, 0x25, 0x0d, 0x55, 0x23, 0x6b, 0x36, 0xc7, 0xd5, 0x19, 0xee, 0x76,
- 0x59, 0x56, 0x58, 0xcc, 0xad, 0x9d, 0x2f, 0x4f, 0xba, 0x6b, 0xc4, 0x50,
- 0x76, 0xff, 0xc7, 0xe0, 0xc7, 0x84, 0xed, 0xb6, 0xa9, 0x3e, 0x46, 0xa2,
- 0xc3, 0xeb, 0xa3, 0xf4, 0xdb, 0xd2, 0xe7, 0x95, 0x44, 0xd2, 0xda, 0xff,
- 0x89, 0xa4, 0x75, 0x73, 0xb7, 0x5b, 0x6f, 0x89, 0x9a, 0xb6, 0xc6, 0xf7,
- 0x52, 0xdc, 0xf5, 0x98, 0xc1, 0xba, 0xba, 0xb4, 0x8a, 0xa1, 0x61, 0xa4,
- 0x2f, 0x5f, 0x81, 0x7e, 0x03, 0xd2, 0x7e, 0xb2, 0xf9, 0xf8, 0x54, 0x7c,
- 0x28, 0x72, 0x50, 0x78, 0x02, 0x8b, 0x79, 0x75, 0x34, 0x9e, 0x95, 0x2b,
- 0x88, 0x93, 0x77, 0x88, 0x1d, 0x06, 0x2f, 0xcb, 0x9d, 0xc7, 0x93, 0xf1,
- 0x51, 0xad, 0x32, 0x89, 0xac, 0xe5, 0xe5, 0x49, 0xc6, 0xd9, 0x43, 0x22,
- 0xc0, 0x97, 0x27, 0x47, 0x24, 0x5d, 0x54, 0xef, 0xa9, 0xf0, 0x9c, 0xad,
- 0x36, 0x0d, 0xf9, 0xe1, 0xf9, 0x09, 0x06, 0x46, 0xdd, 0xea, 0x8f, 0xa4,
- 0xe5, 0x69, 0xd6, 0xc0, 0x24, 0xb7, 0x20, 0xdb, 0x92, 0xf0, 0xab, 0xf6,
- 0x44, 0xbb, 0x4c, 0xd7, 0x1a, 0x99, 0xfe, 0x53, 0xcf, 0x82, 0xc6, 0x14,
- 0x68, 0xed, 0x45, 0x6e, 0x92, 0x45, 0xac, 0xa6, 0x7c, 0xe9, 0xbb, 0x9f,
- 0x81, 0x8c, 0x3e, 0xc2, 0x3d, 0xe5, 0xd1, 0xac, 0x44, 0x27, 0xf2, 0x8a,
- 0xee, 0x5b, 0x5a, 0x6e, 0xf8, 0x57, 0x10, 0xeb, 0x02, 0xb2, 0x2b, 0x26,
- 0xfa, 0xde, 0x58, 0xe0, 0xed, 0x29, 0x8b, 0x6d, 0x41, 0xb6, 0xe9, 0x68,
- 0x0b, 0xfc, 0x7a, 0x2c, 0xa8, 0x27, 0x63, 0xd1, 0x51, 0x9e, 0x8f, 0x36,
- 0xac, 0x29, 0xee, 0x4d, 0x3c, 0x20, 0x5d, 0x7b, 0xa5, 0xe7, 0x42, 0x74,
- 0xf4, 0x06, 0x78, 0x09, 0x28, 0x5f, 0x3f, 0x25, 0xba, 0xd7, 0xde, 0xbd,
- 0xda, 0x1e, 0xf0, 0xda, 0xf7, 0x4a, 0xd7, 0x85, 0x21, 0xf3, 0x75, 0x99,
- 0x01, 0x4d, 0x43, 0xae, 0x23, 0xd7, 0xb1, 0x06, 0xa6, 0x60, 0x8b, 0x4f,
- 0x92, 0x97, 0xfd, 0xc0, 0x1a, 0x58, 0x1b, 0xc8, 0xbf, 0xad, 0x0f, 0xcb,
- 0x57, 0xcd, 0x4e, 0xc9, 0xa9, 0x5c, 0x37, 0xe0, 0xd6, 0x52, 0x61, 0xef,
- 0x8f, 0x0e, 0x1c, 0xec, 0x71, 0xeb, 0x05, 0xdc, 0xef, 0x18, 0x46, 0xdb,
- 0x9d, 0xe6, 0x39, 0x8b, 0x6d, 0xbc, 0x77, 0xa7, 0x59, 0xb5, 0x86, 0xcc,
- 0x94, 0x16, 0xf4, 0xf6, 0xbd, 0x0f, 0xa9, 0xb9, 0xe7, 0xcb, 0xfd, 0x66,
- 0x45, 0x1e, 0xd5, 0x52, 0x0f, 0x22, 0x5e, 0x38, 0xd3, 0xe8, 0x7b, 0x87,
- 0xe7, 0x29, 0x54, 0x7d, 0xbf, 0x22, 0xfe, 0x35, 0xe9, 0x0c, 0x99, 0xe3,
- 0xea, 0xd9, 0x21, 0xf3, 0xa8, 0xd6, 0xfa, 0x6c, 0x58, 0x1b, 0x5f, 0xf3,
- 0x6c, 0x97, 0x92, 0x91, 0x61, 0xb9, 0x7d, 0x66, 0xcb, 0x7b, 0xe5, 0x79,
- 0x87, 0xfd, 0xee, 0x34, 0x53, 0xd6, 0x03, 0xda, 0xd1, 0x07, 0xe9, 0x0b,
- 0xd9, 0xf7, 0xf6, 0xba, 0x71, 0x78, 0x7d, 0xaf, 0x31, 0x9a, 0xb2, 0x76,
- 0x8c, 0x4d, 0xaa, 0xcf, 0x55, 0xd5, 0x27, 0xa0, 0x64, 0xbd, 0x76, 0x9c,
- 0xbf, 0x91, 0xb5, 0xe3, 0x74, 0xad, 0xce, 0x79, 0x16, 0x34, 0x8f, 0xa1,
- 0x6f, 0xd1, 0xe9, 0x0f, 0x57, 0xe5, 0x76, 0x33, 0x67, 0xbd, 0x29, 0x57,
- 0x57, 0x69, 0xff, 0x12, 0xd7, 0xad, 0x3c, 0xfd, 0xd2, 0xe3, 0x91, 0xbf,
- 0xd9, 0xf6, 0x2f, 0x95, 0xbc, 0x1f, 0xb0, 0xfa, 0xf7, 0x57, 0xb4, 0xe8,
- 0xe8, 0x5f, 0x0a, 0x75, 0xf5, 0xcf, 0x94, 0xaf, 0xf9, 0x18, 0xf4, 0xb4,
- 0xed, 0x05, 0xac, 0xdd, 0xe1, 0xa4, 0xea, 0x73, 0xdd, 0xda, 0x2b, 0xdb,
- 0x4e, 0xf6, 0x9b, 0xd7, 0xe5, 0x33, 0x92, 0x0e, 0xf1, 0x1a, 0x39, 0x94,
- 0xc5, 0xf7, 0x52, 0x3e, 0xc1, 0xbc, 0x00, 0xba, 0xec, 0x1f, 0xfc, 0x4b,
- 0x79, 0x56, 0x8e, 0x96, 0xe6, 0xe0, 0x7b, 0xa6, 0x64, 0xf0, 0x05, 0xfa,
- 0x9f, 0xbc, 0xe9, 0xd6, 0x6a, 0xdc, 0x98, 0x98, 0xf2, 0x62, 0xe2, 0x9c,
- 0xf2, 0x73, 0xaf, 0x79, 0xe7, 0x22, 0xfa, 0x07, 0xcf, 0xe1, 0xd9, 0x57,
- 0x94, 0x0f, 0xf8, 0x3d, 0xa9, 0x62, 0x2d, 0x44, 0x5e, 0xde, 0x2c, 0x0f,
- 0x3c, 0x41, 0x9b, 0x44, 0x06, 0xf0, 0xb1, 0x36, 0xf5, 0x1e, 0x8c, 0x6e,
- 0x75, 0x88, 0x6c, 0xa1, 0xfd, 0x5c, 0x86, 0xad, 0x4d, 0xb9, 0x7b, 0x5f,
- 0x6b, 0xae, 0xa3, 0x13, 0x2b, 0xf2, 0x1f, 0x94, 0x1d, 0x7e, 0xfc, 0x82,
- 0xfb, 0x3d, 0x7c, 0x01, 0xe9, 0x72, 0x6c, 0xaf, 0x6c, 0xbf, 0xe0, 0xda,
- 0xdd, 0xec, 0xfc, 0xb3, 0x4a, 0xbe, 0x53, 0x4a, 0xbe, 0x4d, 0x99, 0x89,
- 0x53, 0xf6, 0x9c, 0x13, 0xcf, 0x4f, 0xba, 0x32, 0xf9, 0x9c, 0x67, 0x47,
- 0xfd, 0x2f, 0xf0, 0x3d, 0x35, 0xca, 0x88, 0x7c, 0xcf, 0xf4, 0x70, 0x3f,
- 0x76, 0xdb, 0x05, 0xce, 0xb7, 0x6f, 0xcd, 0x7c, 0x4f, 0xc0, 0xc7, 0x0e,
- 0x0c, 0xb8, 0x73, 0x7e, 0x6d, 0xfe, 0xfd, 0xcf, 0xf9, 0x77, 0x57, 0xe7,
- 0x6c, 0x48, 0x55, 0xe5, 0xb9, 0xb1, 0xcd, 0xd2, 0x95, 0x93, 0x06, 0xec,
- 0xe3, 0xcf, 0x85, 0x67, 0xc6, 0xc9, 0x8b, 0x3b, 0xee, 0xb2, 0x43, 0x9e,
- 0xfc, 0x39, 0x90, 0xaf, 0x29, 0x4f, 0x7f, 0xe4, 0xe3, 0xd9, 0x0d, 0xef,
- 0x5d, 0x97, 0x46, 0x66, 0x10, 0x6d, 0xba, 0xd2, 0xe1, 0x98, 0xb7, 0xde,
- 0xf6, 0x8a, 0xae, 0x74, 0x98, 0x5c, 0xd5, 0xe1, 0x0d, 0xe8, 0xb0, 0x2a,
- 0x9f, 0xc6, 0x9c, 0xb0, 0xbe, 0x5f, 0x18, 0x32, 0x67, 0x64, 0xab, 0xd2,
- 0xbf, 0x35, 0x00, 0x9f, 0xea, 0xe9, 0xb2, 0xfd, 0x3e, 0x74, 0xf9, 0xba,
- 0x28, 0x7d, 0xaa, 0x73, 0x44, 0x55, 0x45, 0x87, 0xbe, 0x8d, 0x73, 0x6b,
- 0x57, 0x3e, 0x81, 0x3c, 0xaa, 0xb3, 0x01, 0x13, 0xae, 0x7e, 0xd5, 0x9a,
- 0xf7, 0xf4, 0x9b, 0x9d, 0xa0, 0x0e, 0x7f, 0xad, 0xc7, 0xd5, 0x67, 0x87,
- 0xea, 0x73, 0x2a, 0x36, 0xaa, 0xd6, 0xbb, 0x35, 0xf0, 0xe9, 0x1e, 0xea,
- 0xf4, 0x79, 0xc7, 0xfd, 0x2e, 0x22, 0xce, 0x9d, 0x72, 0xde, 0x4b, 0xaf,
- 0xae, 0x4e, 0xc7, 0xc4, 0x5d, 0x57, 0xeb, 0xf5, 0xa9, 0x5f, 0x08, 0x28,
- 0x1b, 0x1e, 0x83, 0x0c, 0x8f, 0x97, 0x1e, 0xf4, 0xec, 0xde, 0x9d, 0xf3,
- 0xc0, 0xfb, 0x9c, 0xf3, 0x91, 0x62, 0xbf, 0xf9, 0x26, 0xee, 0x8d, 0x63,
- 0xce, 0x33, 0xd2, 0x26, 0x29, 0x6f, 0xce, 0x91, 0xd5, 0x39, 0xfb, 0x3c,
- 0xba, 0xfd, 0x52, 0xcc, 0x63, 0x1d, 0xfa, 0xaf, 0x7f, 0xab, 0xde, 0x37,
- 0xb9, 0x59, 0xa4, 0xdf, 0x06, 0x56, 0x0a, 0xf5, 0xca, 0xf5, 0x5a, 0x44,
- 0xae, 0x13, 0x83, 0x8c, 0xe0, 0xdb, 0x99, 0xf3, 0x62, 0x78, 0x50, 0x5e,
- 0x2f, 0x6e, 0xc4, 0xc7, 0xb0, 0xdc, 0x28, 0xfa, 0xbc, 0x10, 0x0b, 0x33,
- 0x5f, 0x98, 0x92, 0x37, 0xe6, 0xfb, 0xa5, 0x31, 0x81, 0xb8, 0x3f, 0x40,
- 0x99, 0x0c, 0x99, 0x7b, 0xd4, 0x7b, 0x48, 0x77, 0x9a, 0x97, 0x2d, 0xd0,
- 0x5f, 0x68, 0xca, 0x41, 0xee, 0x67, 0xf3, 0x77, 0xed, 0x21, 0x69, 0x30,
- 0xa7, 0x18, 0xe8, 0x95, 0xca, 0x02, 0xf2, 0xf9, 0x22, 0xe9, 0x53, 0x6e,
- 0x7b, 0xd5, 0xef, 0x71, 0x8c, 0xf7, 0x39, 0xbe, 0x1f, 0x10, 0xa2, 0x6e,
- 0xee, 0x34, 0x97, 0x2d, 0xee, 0x67, 0x4e, 0x49, 0x0d, 0xfa, 0xfb, 0xe7,
- 0x31, 0xee, 0xb7, 0xe7, 0xd4, 0xf9, 0xdb, 0x4a, 0x6d, 0x02, 0xb9, 0xc3,
- 0x9d, 0xe6, 0x9c, 0x75, 0x56, 0xe9, 0xad, 0x56, 0x7e, 0xc2, 0x6b, 0xe7,
- 0x35, 0xef, 0x35, 0x32, 0xdb, 0x06, 0x98, 0xaf, 0x3e, 0x81, 0x7c, 0x81,
- 0xb9, 0xea, 0x04, 0xf0, 0x1a, 0x65, 0x12, 0x91, 0xd9, 0x22, 0x69, 0x49,
- 0x68, 0x13, 0xf2, 0xfb, 0x9c, 0x8c, 0x83, 0x9f, 0x08, 0x72, 0x7b, 0xc6,
- 0x87, 0x47, 0x65, 0x39, 0xe4, 0xc6, 0x01, 0x9e, 0xfb, 0x5a, 0x46, 0x6c,
- 0x58, 0x5e, 0x8d, 0x0d, 0x5b, 0x71, 0xdd, 0xc8, 0xc4, 0x07, 0xfe, 0x06,
- 0xf4, 0x59, 0xb7, 0x61, 0x6c, 0x18, 0x45, 0x7f, 0xb6, 0xf5, 0xca, 0xec,
- 0x02, 0x92, 0x08, 0xe4, 0x2c, 0x15, 0xe1, 0x99, 0x8e, 0xac, 0x9c, 0xaa,
- 0xf5, 0x87, 0x2f, 0x6b, 0x69, 0x75, 0xf6, 0x23, 0x36, 0xc0, 0xf3, 0x2c,
- 0xbd, 0x52, 0x5b, 0x90, 0x88, 0x91, 0x78, 0x52, 0x9c, 0x9a, 0x8b, 0xd9,
- 0xe7, 0x34, 0x9e, 0x69, 0xb1, 0xa5, 0xb6, 0xb6, 0x8f, 0x89, 0xdc, 0x57,
- 0xbe, 0xe3, 0xf5, 0x49, 0xab, 0x3e, 0x7f, 0xdd, 0xc3, 0x3d, 0xb4, 0x9a,
- 0xd3, 0x03, 0x1e, 0xc8, 0xdb, 0xc3, 0xad, 0xe3, 0x46, 0xee, 0x8e, 0xcb,
- 0x31, 0x91, 0xcd, 0x6c, 0xb1, 0x31, 0xee, 0x4d, 0x3c, 0xf3, 0x24, 0xf8,
- 0xb8, 0x63, 0xe8, 0xd6, 0x93, 0x52, 0xa8, 0xad, 0x1f, 0xa3, 0x95, 0x07,
- 0x3e, 0x43, 0xfa, 0x1c, 0xe7, 0x00, 0xf8, 0xbb, 0xa3, 0xe9, 0xd6, 0x01,
- 0xc8, 0xd2, 0x1d, 0xc3, 0x38, 0x13, 0x35, 0x7f, 0x2a, 0x03, 0xa2, 0x9f,
- 0xd3, 0x94, 0xfc, 0xf5, 0xca, 0x30, 0x16, 0x48, 0x46, 0xba, 0x96, 0x26,
- 0xc5, 0x58, 0x62, 0x0d, 0xe1, 0xb5, 0xce, 0xb4, 0xda, 0xbf, 0xdd, 0x84,
- 0xf5, 0x2d, 0x76, 0xc0, 0x62, 0xbd, 0x80, 0xf5, 0xe0, 0x9f, 0x6e, 0x96,
- 0x1e, 0xd6, 0x0b, 0x98, 0x37, 0xec, 0xc7, 0x37, 0x73, 0x87, 0x4b, 0x4d,
- 0xe4, 0x7a, 0x9b, 0x19, 0x5f, 0x73, 0x35, 0xde, 0x8f, 0x46, 0x44, 0x78,
- 0x8f, 0x7e, 0xa3, 0x57, 0xda, 0xbe, 0x35, 0x08, 0x5f, 0xf1, 0x34, 0xb0,
- 0x37, 0xe8, 0x9e, 0x1c, 0x90, 0x80, 0x7b, 0x66, 0x42, 0xd5, 0x5b, 0xde,
- 0x58, 0x88, 0x7a, 0xef, 0x73, 0xc9, 0xb6, 0xcb, 0x71, 0xd6, 0x44, 0xfb,
- 0x58, 0xf3, 0x41, 0x3f, 0xd1, 0x97, 0x91, 0x9f, 0x5e, 0xaf, 0x59, 0x9b,
- 0x79, 0x7e, 0xf3, 0x86, 0x83, 0x6b, 0x62, 0xff, 0x90, 0xc2, 0x98, 0xde,
- 0x3d, 0xfe, 0x46, 0xbe, 0xf4, 0x8e, 0x77, 0x13, 0x98, 0x4f, 0x4d, 0x7a,
- 0x67, 0xe7, 0x1a, 0x99, 0xa3, 0x6b, 0x72, 0xaa, 0x41, 0x55, 0xef, 0x6d,
- 0x38, 0x16, 0xfc, 0xe3, 0x08, 0xec, 0x93, 0x6b, 0xa0, 0xa9, 0x3d, 0x01,
- 0x6c, 0x16, 0xe9, 0x55, 0x39, 0xd1, 0xf1, 0x27, 0xc4, 0xb5, 0x77, 0x58,
- 0x99, 0xf2, 0x65, 0x8d, 0xb2, 0x9b, 0x83, 0x2c, 0x97, 0x33, 0xf2, 0x47,
- 0xce, 0x15, 0x55, 0x6b, 0x9d, 0x47, 0x5e, 0x12, 0x38, 0xa5, 0x72, 0xb2,
- 0x16, 0x7c, 0x0b, 0xbf, 0xf7, 0xe2, 0xd7, 0xb1, 0x16, 0xa3, 0xea, 0x8c,
- 0x82, 0x7e, 0xae, 0xd9, 0x4c, 0xc1, 0x7f, 0xe8, 0x96, 0x65, 0x16, 0x10,
- 0x0f, 0x53, 0xea, 0x9c, 0x0b, 0xd7, 0xf1, 0x6f, 0x2b, 0xff, 0x2c, 0x15,
- 0xc8, 0xe6, 0x4c, 0x04, 0x74, 0x34, 0x65, 0x9f, 0x86, 0xd2, 0xc3, 0x13,
- 0x0a, 0xf3, 0x1a, 0xe7, 0xe0, 0xb0, 0x96, 0x06, 0x44, 0xce, 0x65, 0x64,
- 0x0e, 0x6b, 0x38, 0xb0, 0x44, 0x1d, 0x50, 0xb6, 0x93, 0xd2, 0x06, 0xd9,
- 0x1f, 0x01, 0xf6, 0x30, 0x4e, 0x51, 0xc6, 0x61, 0xac, 0x8b, 0x5e, 0x09,
- 0x9c, 0x81, 0x8c, 0x4f, 0x01, 0x23, 0x2c, 0xb4, 0xcb, 0xf7, 0x6a, 0xbe,
- 0x4c, 0x2f, 0xf1, 0x5c, 0xbf, 0x3e, 0x35, 0xd2, 0x47, 0x1c, 0x25, 0xd5,
- 0xda, 0x9c, 0xcc, 0x9d, 0x66, 0xce, 0x3e, 0xa9, 0xce, 0x0c, 0x04, 0xd4,
- 0x99, 0x15, 0x37, 0x67, 0x76, 0xbf, 0x5d, 0x8c, 0x59, 0x15, 0xee, 0xb5,
- 0x09, 0x6c, 0x67, 0x18, 0xe3, 0x6e, 0x24, 0x5f, 0x37, 0x57, 0x1d, 0x07,
- 0xbf, 0x97, 0xe7, 0xa3, 0x99, 0xbc, 0xc4, 0x79, 0x76, 0x7a, 0xc2, 0xc6,
- 0xfc, 0x97, 0xe1, 0x3f, 0xe7, 0x4a, 0x3c, 0x27, 0x5d, 0xc0, 0x0a, 0xcb,
- 0xc8, 0xe5, 0x22, 0x73, 0xc6, 0x8f, 0x43, 0x6f, 0xbc, 0x2e, 0x8c, 0x1a,
- 0xf0, 0x03, 0x2b, 0xea, 0xdd, 0xcf, 0xa8, 0xdd, 0x40, 0x0e, 0x1b, 0xd1,
- 0xf6, 0x43, 0xd7, 0x79, 0xb3, 0xcd, 0xb3, 0x07, 0x9e, 0xc5, 0x3f, 0x0b,
- 0x3f, 0x7a, 0x5e, 0xf8, 0x4e, 0xd6, 0xed, 0x26, 0xf3, 0xa5, 0xab, 0xf0,
- 0x7b, 0x99, 0x58, 0x06, 0x36, 0x94, 0x0f, 0x77, 0x80, 0xe7, 0xdf, 0xc4,
- 0xbd, 0x9c, 0xc3, 0x71, 0xa2, 0xf1, 0x15, 0x29, 0x44, 0x02, 0x32, 0x14,
- 0xb9, 0x22, 0x9b, 0xe1, 0xc9, 0x34, 0x79, 0xdd, 0x8a, 0x8e, 0x8a, 0xa6,
- 0xe8, 0x0d, 0xee, 0x86, 0x0d, 0xde, 0x84, 0xbf, 0x6b, 0xf7, 0x72, 0xfd,
- 0x54, 0x91, 0x18, 0xea, 0x59, 0x75, 0xb6, 0xe0, 0xaa, 0xc5, 0x3a, 0x20,
- 0xdf, 0xc5, 0xfe, 0x1f, 0x6a, 0x8c, 0xbb, 0x7b, 0x77, 0xac, 0x43, 0x93,
- 0x3f, 0x77, 0x8e, 0xbb, 0x2c, 0x97, 0x47, 0xd2, 0x69, 0x6b, 0xa1, 0x73,
- 0xd9, 0xa3, 0x73, 0xd6, 0xa3, 0x53, 0xf1, 0xe8, 0x5c, 0x5d, 0xa5, 0xb3,
- 0x07, 0x76, 0xd0, 0x6c, 0x9e, 0x00, 0xde, 0x48, 0xc6, 0x9b, 0xcd, 0x34,
- 0xf2, 0xb2, 0xd9, 0xe1, 0x69, 0xb5, 0xe7, 0xaa, 0x27, 0x46, 0xc7, 0x93,
- 0x96, 0x2b, 0x7f, 0x58, 0x81, 0x4c, 0xc3, 0x1e, 0xf3, 0xe2, 0x62, 0x75,
- 0xee, 0x07, 0xba, 0xfb, 0x85, 0x5d, 0xf0, 0x03, 0x4f, 0x23, 0x96, 0x5c,
- 0x1c, 0x3f, 0x6f, 0x49, 0x7e, 0xdb, 0x27, 0x75, 0xd8, 0x7b, 0x0f, 0xdf,
- 0x27, 0x35, 0xa5, 0xeb, 0xe2, 0x78, 0xb5, 0xf6, 0x34, 0xf2, 0x23, 0xf6,
- 0xdf, 0x4e, 0x0c, 0xb6, 0xab, 0x52, 0x8b, 0xec, 0x3a, 0xcb, 0xfd, 0x21,
- 0xf4, 0xab, 0xd4, 0xba, 0x21, 0xf7, 0x6e, 0x55, 0x57, 0xb9, 0x52, 0x0c,
- 0x41, 0x8f, 0x26, 0x6c, 0x3e, 0x84, 0xb6, 0x30, 0xec, 0xa0, 0x0f, 0xed,
- 0x3f, 0xc7, 0xda, 0x8e, 0xa0, 0x7d, 0xa5, 0x73, 0x5c, 0xe1, 0x58, 0x4b,
- 0xce, 0x39, 0x37, 0x11, 0x73, 0xdf, 0x84, 0x1f, 0x1d, 0x44, 0x9f, 0x61,
- 0xf4, 0xf9, 0x14, 0xc6, 0xe1, 0x3b, 0xcd, 0x1b, 0xf1, 0xd4, 0x00, 0x4f,
- 0x7a, 0x0b, 0x4f, 0x0d, 0xf0, 0x03, 0xdf, 0x79, 0x92, 0x35, 0xe8, 0x61,
- 0x39, 0x5a, 0xe4, 0x19, 0x29, 0xbe, 0x17, 0x6f, 0x4a, 0x00, 0x98, 0xb4,
- 0xed, 0x64, 0x34, 0xdc, 0x50, 0xb5, 0x1e, 0xda, 0xd6, 0x50, 0xbc, 0x2a,
- 0x2a, 0xce, 0x44, 0x8e, 0x22, 0x7e, 0xdd, 0x74, 0xba, 0xe5, 0x75, 0x6f,
- 0xac, 0x15, 0xe1, 0xfe, 0xe5, 0xda, 0xb1, 0x8e, 0x95, 0xae, 0x8d, 0xbf,
- 0x6a, 0x19, 0xde, 0xbc, 0x7a, 0x31, 0xd6, 0xaf, 0xa2, 0xef, 0xb5, 0xf1,
- 0xcb, 0xb5, 0x8d, 0xfa, 0xde, 0x44, 0xdf, 0xb6, 0x96, 0xbe, 0x37, 0xd1,
- 0xaf, 0x1b, 0x71, 0xb0, 0x5b, 0xcd, 0x69, 0x16, 0x7c, 0x5d, 0x2f, 0xaa,
- 0xf7, 0xb4, 0x21, 0x77, 0x8e, 0x69, 0x12, 0x53, 0x67, 0xdc, 0x5a, 0x49,
- 0xd4, 0x8c, 0x68, 0xef, 0xa8, 0xf7, 0x28, 0x1b, 0x18, 0xb3, 0x80, 0x7b,
- 0xe7, 0x27, 0xb4, 0x54, 0x35, 0x87, 0x98, 0xf5, 0x30, 0xf1, 0x53, 0xdc,
- 0x46, 0xcc, 0xac, 0x80, 0x5e, 0xad, 0xd8, 0xe0, 0x79, 0x6a, 0xd8, 0xc5,
- 0x2d, 0xe2, 0xec, 0x87, 0x0d, 0x75, 0xae, 0x21, 0xad, 0x6a, 0x76, 0x95,
- 0xa2, 0x98, 0xc9, 0x11, 0x9e, 0x65, 0xf8, 0x0c, 0xd6, 0xe5, 0x57, 0xd0,
- 0x96, 0x44, 0x7c, 0x3c, 0xa0, 0x25, 0xcf, 0x8f, 0xe3, 0xfa, 0x49, 0x5c,
- 0xc3, 0x1f, 0x2f, 0x64, 0x71, 0xff, 0x49, 0x5c, 0x4f, 0x6b, 0xa9, 0x7a,
- 0x16, 0xd7, 0x4f, 0xe1, 0x7a, 0xca, 0x64, 0x9e, 0xf2, 0xaa, 0x95, 0xd1,
- 0x6c, 0xd0, 0xb2, 0xcf, 0x8f, 0xe3, 0xd3, 0x4a, 0x8f, 0xf7, 0xa0, 0xa7,
- 0x22, 0xf7, 0xda, 0x62, 0xe0, 0x69, 0x9f, 0x96, 0xae, 0x76, 0x81, 0xc6,
- 0x00, 0x9e, 0xa7, 0x4d, 0xed, 0xf7, 0xc6, 0x67, 0xcd, 0xe9, 0x63, 0xaa,
- 0xe6, 0x64, 0x24, 0x32, 0xc0, 0xc9, 0x87, 0x91, 0x07, 0x68, 0x92, 0xb6,
- 0x9e, 0x93, 0x42, 0x1c, 0x7e, 0xa5, 0x6a, 0x48, 0x2a, 0x94, 0xc7, 0xef,
- 0xbc, 0x24, 0x47, 0x71, 0xbf, 0x4a, 0x5b, 0x60, 0xbf, 0x3f, 0x95, 0x42,
- 0x99, 0xb8, 0x9f, 0x75, 0x26, 0xd6, 0xa6, 0x58, 0x5f, 0xca, 0x41, 0x06,
- 0x21, 0xda, 0xef, 0x06, 0x35, 0x31, 0xf7, 0x8c, 0x34, 0xe2, 0xb2, 0x96,
- 0xac, 0x72, 0xdf, 0xaf, 0x91, 0xb9, 0x6c, 0xf1, 0xfd, 0xb1, 0x69, 0xee,
- 0x23, 0x16, 0x8c, 0x04, 0xeb, 0x23, 0xaa, 0xbe, 0x1e, 0x77, 0xf7, 0x07,
- 0x5b, 0xcf, 0xa4, 0xf8, 0xeb, 0x85, 0xe3, 0x7e, 0x0d, 0xcf, 0xbb, 0xf5,
- 0xac, 0x54, 0xfd, 0x9d, 0xba, 0xe0, 0x3b, 0x00, 0xe7, 0xa0, 0x8b, 0xcb,
- 0x2a, 0x37, 0xe6, 0x1e, 0xee, 0xbb, 0xe5, 0x54, 0xc8, 0x61, 0x8a, 0xac,
- 0x91, 0xf9, 0xfb, 0x76, 0xbe, 0x1c, 0xd7, 0xf3, 0x4a, 0x3e, 0x67, 0x40,
- 0x53, 0xe2, 0xf4, 0xbb, 0xd9, 0x10, 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf3,
- 0x2e, 0xdf, 0xe4, 0x99, 0xf2, 0x38, 0x0c, 0xff, 0xc9, 0xf7, 0x2b, 0x9e,
- 0x93, 0x5c, 0x9c, 0x35, 0x1e, 0x03, 0xb1, 0x31, 0x8f, 0xdf, 0x77, 0xe5,
- 0x37, 0xeb, 0xc9, 0x2f, 0x57, 0xfe, 0x2f, 0x4a, 0x87, 0x15, 0x8b, 0xe3,
- 0xf9, 0xb5, 0x8f, 0xbd, 0x4a, 0x77, 0x15, 0x75, 0x7e, 0xd7, 0x97, 0x81,
- 0x5f, 0xbf, 0xdb, 0xd8, 0xf6, 0xc6, 0x2d, 0xf2, 0xf6, 0x10, 0xcf, 0x43,
- 0x0c, 0xda, 0x42, 0xfe, 0x39, 0x0f, 0xc6, 0x30, 0x7f, 0xaf, 0xd5, 0x9f,
- 0x83, 0x3f, 0xcf, 0xfb, 0x95, 0x0f, 0xf9, 0xfd, 0xe4, 0x16, 0xe9, 0xca,
- 0x98, 0x86, 0xc5, 0xd8, 0xf0, 0xb8, 0xb7, 0x3f, 0xf0, 0x7f, 0x43, 0xce,
- 0xae, 0x2c, 0x02, 0x09, 0x99, 0xf5, 0xde, 0xbf, 0xde, 0xc0, 0x1e, 0xd6,
- 0xef, 0x35, 0x37, 0x32, 0x67, 0xad, 0xbb, 0xf3, 0xae, 0x6c, 0x30, 0xef,
- 0x8a, 0x37, 0xef, 0xea, 0x7d, 0xf2, 0x5b, 0x99, 0xb7, 0x31, 0x67, 0xda,
- 0xdc, 0x46, 0xf6, 0x28, 0xea, 0xdd, 0xb0, 0x15, 0x23, 0x18, 0xb4, 0x9d,
- 0x7b, 0xd5, 0x50, 0x99, 0x57, 0xbb, 0x76, 0x79, 0x16, 0xb1, 0xb0, 0x5c,
- 0x76, 0x73, 0xec, 0xb2, 0xc3, 0x5a, 0xf6, 0xbb, 0xf1, 0xc0, 0x77, 0xb9,
- 0xbe, 0xa8, 0xce, 0xbb, 0xcc, 0x3a, 0x6e, 0xdd, 0xab, 0x5c, 0x6e, 0x8d,
- 0xa9, 0x0f, 0x32, 0x9e, 0x0e, 0xe6, 0x65, 0x82, 0xef, 0x94, 0xe3, 0xfa,
- 0x11, 0xb9, 0xb2, 0xa0, 0xf6, 0xac, 0xbc, 0xbd, 0x21, 0xee, 0xf9, 0xa8,
- 0xfd, 0x6f, 0xf8, 0xb5, 0x49, 0xe5, 0xd7, 0x97, 0x17, 0xd4, 0x3d, 0x17,
- 0x2b, 0x39, 0x13, 0xf0, 0xfb, 0xc8, 0x25, 0xac, 0x07, 0xa4, 0x80, 0x9c,
- 0xfb, 0xac, 0x75, 0x78, 0x0b, 0x71, 0x0e, 0x69, 0x2d, 0x83, 0xd6, 0xe5,
- 0x05, 0xd9, 0xc2, 0x33, 0x25, 0x65, 0xb5, 0xcf, 0xe6, 0xd6, 0xc5, 0xa7,
- 0xc5, 0xff, 0x7f, 0x1d, 0x41, 0x2f, 0x16, 0xf2, 0x5c, 0x0b, 0xdf, 0x73,
- 0xa6, 0xaf, 0x40, 0x1e, 0x34, 0xc1, 0x7d, 0x9c, 0x66, 0xd3, 0xad, 0x9b,
- 0x37, 0xb1, 0x2e, 0xda, 0xf8, 0x0e, 0x05, 0xfe, 0x0e, 0xc3, 0x7e, 0xb0,
- 0x4e, 0x56, 0xdb, 0x79, 0xcd, 0xdc, 0xc3, 0xbf, 0x66, 0x60, 0xfb, 0x3f,
- 0xe8, 0xf3, 0x49, 0x14, 0x38, 0x46, 0x00, 0x00, 0x00 };
+ 0xbd, 0x7c, 0x7d, 0x70, 0x1c, 0xe7, 0x79, 0xdf, 0xb3, 0xbb, 0x07, 0xe0,
+ 0x00, 0x82, 0xe0, 0x12, 0x39, 0x52, 0x27, 0x0a, 0xa6, 0x6e, 0x89, 0x3d,
+ 0x08, 0x32, 0x20, 0x71, 0xc5, 0x20, 0x36, 0x26, 0xb9, 0xca, 0xab, 0xbb,
+ 0x03, 0x78, 0x94, 0x31, 0x31, 0xc4, 0xc2, 0x16, 0xed, 0x70, 0xd4, 0xeb,
+ 0x01, 0xa4, 0x95, 0x54, 0x9e, 0xb2, 0xb6, 0xda, 0x72, 0x5a, 0x35, 0x3a,
+ 0x1f, 0xc0, 0x0f, 0x29, 0x47, 0x1c, 0x24, 0xc0, 0x84, 0xfe, 0x70, 0x93,
+ 0x13, 0x0e, 0x24, 0x64, 0xf7, 0x88, 0x93, 0xfc, 0xd9, 0x3f, 0x62, 0x0b,
+ 0x03, 0xd2, 0xb4, 0x5a, 0xbb, 0xb5, 0xda, 0x28, 0x13, 0xcf, 0xf4, 0x63,
+ 0x30, 0x14, 0xa5, 0x28, 0x71, 0xa7, 0x56, 0x9b, 0x4c, 0xa2, 0x36, 0x94,
+ 0xaf, 0xbf, 0xdf, 0xbb, 0xbb, 0xe0, 0x01, 0x22, 0x65, 0x51, 0x93, 0x14,
+ 0x33, 0x37, 0x77, 0xfb, 0xee, 0xbb, 0xef, 0xfb, 0x7c, 0xbd, 0xcf, 0xf3,
+ 0xfc, 0x9e, 0xf7, 0x5d, 0x44, 0x45, 0xda, 0xc4, 0xff, 0xdb, 0x8a, 0x4f,
+ 0xec, 0xd8, 0xf1, 0xc7, 0xef, 0xfd, 0xf8, 0xbd, 0xbf, 0x8a, 0x9f, 0xf7,
+ 0x89, 0xd6, 0x62, 0xf0, 0xe6, 0x5b, 0x86, 0x48, 0xf6, 0xcf, 0xe5, 0x43,
+ 0xff, 0xe1, 0x71, 0x33, 0x18, 0x9f, 0x1f, 0x09, 0xeb, 0x89, 0x57, 0x87,
+ 0x93, 0xb6, 0x84, 0x8d, 0x44, 0xfe, 0xa1, 0x71, 0x5b, 0xc4, 0xad, 0xf6,
+ 0xc5, 0x52, 0xf2, 0x6e, 0x3d, 0x1f, 0x09, 0x09, 0xdb, 0x3f, 0x92, 0xb8,
+ 0xf6, 0xe4, 0xf7, 0x3e, 0x6e, 0xbd, 0x5d, 0x36, 0x24, 0x6c, 0x26, 0xb2,
+ 0x62, 0xf6, 0x48, 0xb8, 0x0b, 0xcf, 0x7c, 0xf5, 0xae, 0x47, 0x0d, 0xe9,
+ 0x08, 0xc6, 0x7a, 0xab, 0xfe, 0xbd, 0xbb, 0x24, 0xbf, 0x2b, 0x51, 0x8f,
+ 0x85, 0x12, 0xef, 0xd6, 0xa7, 0x06, 0xc2, 0xa2, 0x27, 0xac, 0x68, 0xd2,
+ 0x88, 0xc8, 0xcb, 0x35, 0x53, 0x5e, 0xac, 0xc5, 0x64, 0xb2, 0x26, 0x1d,
+ 0xe9, 0xda, 0x8d, 0x68, 0xaa, 0xa3, 0xef, 0xbb, 0xf5, 0xe4, 0x40, 0x28,
+ 0x6b, 0x24, 0xa4, 0x23, 0x59, 0x93, 0xd1, 0x63, 0xc5, 0xd6, 0x87, 0x9b,
+ 0x12, 0x4f, 0xd6, 0x75, 0x5b, 0xb2, 0xa1, 0x84, 0x9d, 0xd7, 0xf5, 0xf6,
+ 0x41, 0xf3, 0x63, 0x68, 0xaf, 0x0e, 0x86, 0x26, 0x8b, 0xa6, 0x9c, 0x1b,
+ 0x68, 0x15, 0xdd, 0x0e, 0x4b, 0xb2, 0xd6, 0xfa, 0xb0, 0x9e, 0x88, 0x88,
+ 0x5b, 0xab, 0xd7, 0x8f, 0x39, 0xff, 0x64, 0xaf, 0xf9, 0xeb, 0xe1, 0xf0,
+ 0x64, 0x51, 0xde, 0x0e, 0xd9, 0x76, 0x74, 0x42, 0x7a, 0xcc, 0x9c, 0x68,
+ 0x92, 0xec, 0xef, 0x89, 0x1e, 0xc1, 0xf7, 0x78, 0x7f, 0xdc, 0x4c, 0xc9,
+ 0x16, 0x71, 0xcd, 0x6f, 0xae, 0x98, 0x3d, 0x5d, 0x59, 0x3d, 0x11, 0x96,
+ 0x74, 0x51, 0x13, 0xc3, 0x8e, 0xc8, 0x64, 0xc5, 0x96, 0xfc, 0x52, 0x87,
+ 0xe4, 0x2b, 0xf2, 0xc4, 0x94, 0xd3, 0x2e, 0x53, 0x4b, 0x47, 0x7d, 0x5d,
+ 0x44, 0xd0, 0xd6, 0x2b, 0xf9, 0x5a, 0x14, 0x9f, 0x9f, 0xf8, 0xfc, 0xea,
+ 0x22, 0x3b, 0x05, 0xcf, 0xf7, 0xa7, 0xdd, 0xea, 0xd7, 0xc2, 0x5e, 0xdb,
+ 0x7f, 0xd9, 0xe2, 0x7d, 0x83, 0xdf, 0x12, 0xf8, 0x2d, 0x85, 0x65, 0xcd,
+ 0x88, 0xca, 0xf7, 0xee, 0x8a, 0xc9, 0x54, 0x69, 0x0d, 0xb2, 0x89, 0xca,
+ 0x37, 0x6a, 0x11, 0x79, 0x49, 0xc9, 0x22, 0xa4, 0x0d, 0xa3, 0xcf, 0x64,
+ 0x69, 0x42, 0x3f, 0x51, 0xcc, 0x4b, 0xaa, 0x96, 0xd5, 0x0b, 0x73, 0x66,
+ 0x47, 0x72, 0x29, 0xa7, 0x4f, 0xce, 0x75, 0x76, 0xa4, 0x96, 0x26, 0xf4,
+ 0x42, 0x31, 0x0a, 0x39, 0x98, 0x1d, 0xa9, 0xf9, 0x08, 0xae, 0x3b, 0x3b,
+ 0x92, 0xf3, 0xd6, 0x0c, 0x26, 0x45, 0x9f, 0x68, 0x47, 0xaa, 0x64, 0x65,
+ 0x45, 0xba, 0x9d, 0x1f, 0x48, 0x57, 0x47, 0xaa, 0xf6, 0x5b, 0xfa, 0x8a,
+ 0xa9, 0x49, 0xe1, 0x1e, 0x31, 0xa3, 0x89, 0xb7, 0xeb, 0xb7, 0xdb, 0x9a,
+ 0x98, 0xf6, 0x3b, 0xf5, 0xed, 0x90, 0x4d, 0x6e, 0xb6, 0x15, 0xbc, 0x92,
+ 0x26, 0x53, 0x72, 0xf3, 0x7d, 0xe6, 0xaa, 0x34, 0x89, 0x1b, 0x09, 0xae,
+ 0xeb, 0xf5, 0xa4, 0xf3, 0x07, 0xe4, 0x91, 0xf2, 0xee, 0x18, 0x86, 0x5e,
+ 0x92, 0xa0, 0x39, 0xe9, 0xbc, 0x5b, 0xf7, 0x9e, 0x09, 0x63, 0xce, 0x50,
+ 0xc7, 0x50, 0xa9, 0x5e, 0x4f, 0x3b, 0x18, 0xdf, 0x09, 0x9e, 0x6d, 0x92,
+ 0x72, 0xc4, 0x2d, 0x4f, 0x3a, 0x96, 0xe1, 0xc9, 0x87, 0xba, 0xe7, 0xb5,
+ 0x0b, 0x7d, 0xe4, 0x25, 0x17, 0x91, 0x72, 0xc1, 0xf9, 0x98, 0x3c, 0xe5,
+ 0x44, 0xc1, 0x5f, 0x58, 0x4e, 0x39, 0xb0, 0x2f, 0xfb, 0xb8, 0x96, 0xac,
+ 0x59, 0xb1, 0xac, 0x3c, 0x2d, 0xc9, 0xf9, 0x6e, 0x33, 0x2d, 0x98, 0xdb,
+ 0xae, 0xdf, 0x99, 0x74, 0x30, 0x5f, 0xff, 0xff, 0xad, 0xbb, 0x11, 0x2b,
+ 0x5b, 0x96, 0x5e, 0x29, 0x94, 0xba, 0x9d, 0x1f, 0x43, 0x4f, 0x61, 0x5b,
+ 0xdc, 0x71, 0xdb, 0x84, 0xdc, 0xac, 0xde, 0x94, 0x51, 0x97, 0x07, 0x31,
+ 0x7f, 0xd2, 0xc6, 0xfd, 0x9a, 0x6c, 0xd3, 0xed, 0x66, 0x29, 0x98, 0x12,
+ 0x69, 0x93, 0xdd, 0x52, 0x98, 0x45, 0xbb, 0xe3, 0x76, 0xea, 0x78, 0x26,
+ 0x33, 0xc0, 0x36, 0xd1, 0x8c, 0x04, 0x75, 0x2c, 0xb2, 0x50, 0xed, 0xc5,
+ 0xfc, 0x71, 0xb7, 0x55, 0x33, 0x65, 0xcd, 0x0c, 0x49, 0xa5, 0x1a, 0x77,
+ 0xa3, 0x5a, 0xb3, 0x9c, 0x8a, 0xb7, 0x41, 0xa6, 0x51, 0x8c, 0x2d, 0x5f,
+ 0xd6, 0x13, 0xf1, 0x68, 0x0e, 0x4a, 0xa3, 0x1d, 0x4d, 0x81, 0x9e, 0x29,
+ 0x27, 0xab, 0xa5, 0x6a, 0x9f, 0xd3, 0x92, 0x4b, 0x87, 0xb4, 0xfd, 0x4b,
+ 0xe8, 0x53, 0xfb, 0x1f, 0xbe, 0x0d, 0x44, 0x41, 0x9b, 0x8e, 0x67, 0xd9,
+ 0x0e, 0x9a, 0x15, 0xed, 0x68, 0x83, 0x2e, 0x57, 0xc6, 0x22, 0x1d, 0x49,
+ 0xa5, 0x4b, 0xd2, 0xa6, 0x4b, 0x6e, 0x54, 0x93, 0x4e, 0xdb, 0x95, 0xf0,
+ 0xaf, 0x41, 0x9f, 0xf3, 0xd0, 0xe5, 0x7c, 0x4c, 0x4e, 0x94, 0x24, 0xa2,
+ 0x0b, 0xe7, 0xca, 0xea, 0x95, 0x2a, 0xed, 0x01, 0xba, 0x85, 0xee, 0x0b,
+ 0x55, 0x3e, 0x0b, 0x1d, 0x96, 0xd2, 0x90, 0x4f, 0x06, 0x73, 0x1f, 0xd4,
+ 0x1e, 0xac, 0x8c, 0x69, 0x19, 0xd8, 0x49, 0x61, 0xb6, 0x0f, 0xba, 0xb3,
+ 0x62, 0x6b, 0xb2, 0x4d, 0x0a, 0xb6, 0x1d, 0xfb, 0xac, 0xb4, 0xcb, 0xa9,
+ 0x79, 0x5b, 0x4e, 0xcc, 0xc3, 0x1e, 0x4d, 0xcb, 0x5c, 0x94, 0xae, 0xec,
+ 0x96, 0x44, 0x87, 0x3c, 0x3d, 0x6b, 0x65, 0xca, 0xd2, 0xed, 0xbe, 0x81,
+ 0xfb, 0xb9, 0x33, 0xd4, 0xa9, 0xe4, 0x53, 0x8e, 0x21, 0x59, 0x93, 0x76,
+ 0x7d, 0x9b, 0x26, 0x6d, 0xf5, 0x27, 0x93, 0x8e, 0x15, 0xa5, 0xcd, 0xa6,
+ 0x3e, 0xdd, 0x6d, 0x1e, 0x10, 0xcb, 0xcc, 0x50, 0xfe, 0x4e, 0x1f, 0xf4,
+ 0xf0, 0xbf, 0x29, 0x7b, 0x8c, 0x45, 0x1d, 0xf7, 0x45, 0x4f, 0x41, 0x97,
+ 0x59, 0xa5, 0xe3, 0x0e, 0xcc, 0x1f, 0xf2, 0x6d, 0x87, 0x6b, 0xe2, 0x6e,
+ 0xcd, 0x93, 0x43, 0x87, 0xcc, 0x54, 0xda, 0xa5, 0x00, 0x1d, 0x16, 0xc4,
+ 0x96, 0xc2, 0xd2, 0x5e, 0xbf, 0xdd, 0xc6, 0x7a, 0xf9, 0x53, 0x5d, 0xda,
+ 0x8e, 0x6b, 0x87, 0x6a, 0x3f, 0xd7, 0x7c, 0xfb, 0x81, 0xfd, 0x85, 0xc5,
+ 0x1d, 0x0d, 0xcb, 0xf9, 0x9a, 0x67, 0x7f, 0x0b, 0xf0, 0x3d, 0xae, 0xe9,
+ 0xc2, 0x96, 0xde, 0x5c, 0xef, 0x73, 0xbe, 0xd6, 0x85, 0x67, 0xc3, 0x72,
+ 0xa2, 0xc6, 0xfe, 0x79, 0xd8, 0x58, 0x58, 0x96, 0xef, 0x6a, 0x97, 0x2c,
+ 0xda, 0x0b, 0xf3, 0xe2, 0x26, 0x1d, 0x1d, 0xcf, 0x74, 0x80, 0x97, 0x9d,
+ 0xf8, 0xb4, 0xc9, 0x78, 0xa5, 0xc5, 0xe5, 0x7a, 0x1d, 0xaf, 0x51, 0xff,
+ 0xf8, 0x2e, 0x05, 0x36, 0x40, 0xf9, 0xb2, 0x9d, 0xcf, 0xb1, 0xdd, 0x44,
+ 0x7b, 0x63, 0x1b, 0x6d, 0x7b, 0x1b, 0x65, 0xda, 0xcb, 0x35, 0x9a, 0x2b,
+ 0xc5, 0xcd, 0x43, 0xfc, 0xae, 0xd1, 0x1e, 0x1a, 0x6d, 0x21, 0x84, 0xfe,
+ 0xd0, 0x63, 0x05, 0x73, 0xcd, 0x5e, 0xab, 0x37, 0x0d, 0xe0, 0xda, 0xfe,
+ 0x1d, 0xf0, 0xc9, 0xb9, 0x43, 0xa0, 0x4b, 0x97, 0x6c, 0x45, 0xd1, 0x16,
+ 0xa3, 0x0d, 0x78, 0x7c, 0x74, 0xc9, 0xe4, 0x7c, 0x7b, 0x47, 0x7a, 0x9e,
+ 0xed, 0xc9, 0xa8, 0x01, 0x3e, 0xc7, 0x1d, 0x59, 0x99, 0x72, 0xf4, 0xee,
+ 0x10, 0xe8, 0x9a, 0xc0, 0x82, 0x03, 0x1f, 0x3e, 0x8d, 0x2b, 0xb8, 0xdf,
+ 0x29, 0xe3, 0x4b, 0xec, 0xcb, 0x39, 0x0a, 0xdb, 0x75, 0x49, 0x80, 0x36,
+ 0x7c, 0x6c, 0x0b, 0xf7, 0x5b, 0x31, 0x4f, 0x3b, 0x6c, 0x67, 0x9a, 0xba,
+ 0xfb, 0x44, 0xd2, 0xe9, 0x94, 0xec, 0x7a, 0x5f, 0x81, 0xdd, 0xb1, 0x7f,
+ 0xef, 0xa6, 0xbe, 0x90, 0xef, 0x12, 0xc6, 0x9c, 0x6f, 0x85, 0x0c, 0xd9,
+ 0xae, 0x83, 0xe6, 0x16, 0xd0, 0x00, 0x1f, 0x6c, 0x77, 0x63, 0x3d, 0xb4,
+ 0x60, 0xfc, 0x2d, 0xe0, 0xa9, 0x55, 0x26, 0x66, 0x3b, 0xa1, 0x0b, 0x13,
+ 0x7d, 0xc3, 0xf2, 0x74, 0xc9, 0x82, 0x0d, 0xb0, 0x3f, 0x74, 0x30, 0x6f,
+ 0x45, 0x2b, 0xe2, 0xca, 0x94, 0xd3, 0x02, 0xfb, 0xaa, 0xd7, 0x8f, 0xc0,
+ 0x3e, 0xbe, 0xae, 0xfc, 0x45, 0x9f, 0x39, 0xa4, 0x49, 0xbe, 0x25, 0xf1,
+ 0x7d, 0xd0, 0x63, 0x3d, 0x2a, 0xc2, 0xeb, 0xbd, 0x1a, 0xd7, 0x2c, 0xe4,
+ 0xc8, 0xb9, 0xe1, 0x93, 0x76, 0x42, 0x86, 0xf4, 0x5b, 0x5d, 0xb0, 0xe7,
+ 0xa8, 0xf2, 0x27, 0x43, 0x37, 0xf4, 0x27, 0xd6, 0x68, 0x19, 0x73, 0x15,
+ 0x96, 0x42, 0xf4, 0x61, 0x83, 0x58, 0xae, 0xb2, 0x15, 0x6b, 0x6f, 0x52,
+ 0xd9, 0xc7, 0x4f, 0xc8, 0x6f, 0xfd, 0x53, 0x0e, 0xe9, 0x22, 0xbf, 0x2e,
+ 0x9e, 0xa5, 0x0d, 0x5a, 0xc7, 0x5d, 0x35, 0xff, 0x4f, 0xfc, 0xf9, 0x3d,
+ 0xda, 0x0b, 0xa5, 0x0e, 0x2d, 0xa5, 0x68, 0x08, 0xc6, 0x11, 0x59, 0x3d,
+ 0xd3, 0x6d, 0x3e, 0x08, 0x1b, 0xa6, 0x9f, 0x5a, 0xbd, 0x40, 0x1d, 0x63,
+ 0x8c, 0x01, 0xea, 0xd8, 0x54, 0xf4, 0x25, 0xe7, 0xb9, 0xf6, 0xa4, 0xcb,
+ 0x10, 0xfa, 0x08, 0xf8, 0x5c, 0xac, 0xc5, 0x49, 0x7f, 0x2d, 0xe6, 0xaa,
+ 0xb4, 0xbf, 0xc7, 0xf1, 0xac, 0x2e, 0x43, 0x71, 0xfa, 0x87, 0xa7, 0x25,
+ 0x05, 0x1f, 0x09, 0x3d, 0x4a, 0x05, 0xbc, 0x2c, 0x94, 0x1a, 0xfd, 0x16,
+ 0x6c, 0xab, 0xff, 0xaf, 0xeb, 0x9e, 0x3f, 0xa4, 0x6f, 0xa0, 0xaf, 0x29,
+ 0x98, 0x3a, 0x24, 0x87, 0xc8, 0xe0, 0x42, 0x37, 0x4e, 0xd2, 0xb0, 0x32,
+ 0x59, 0xc6, 0x1c, 0xbb, 0x2e, 0xf6, 0x7d, 0x82, 0x48, 0xda, 0xcb, 0xf8,
+ 0xb7, 0x2f, 0xf0, 0x4f, 0xab, 0xd5, 0x40, 0x17, 0xd4, 0x2b, 0xf5, 0x10,
+ 0xf8, 0x88, 0x90, 0x5c, 0x84, 0xef, 0x9a, 0x2a, 0xb5, 0xcb, 0x0a, 0x68,
+ 0xba, 0x54, 0x0d, 0x6c, 0xcd, 0xf0, 0x6d, 0x8d, 0xcf, 0xb4, 0xe3, 0xf9,
+ 0x10, 0xfc, 0x9a, 0xe4, 0x8d, 0x04, 0x7e, 0x17, 0x39, 0x26, 0xdb, 0x02,
+ 0x3b, 0xe7, 0x9a, 0xb1, 0xdc, 0xb2, 0x34, 0x4b, 0x26, 0x8e, 0xf8, 0x31,
+ 0xaf, 0x63, 0xae, 0x2e, 0xf8, 0xf2, 0x90, 0x1c, 0x2d, 0x45, 0xe4, 0xf3,
+ 0x25, 0xf2, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xbe, 0x0e, 0x9d, 0x0f,
+ 0xc3, 0xe7, 0x65, 0xb4, 0x21, 0xf8, 0x9f, 0x03, 0x95, 0xcf, 0x69, 0xe9,
+ 0xa5, 0xac, 0x36, 0x5c, 0x3b, 0xa4, 0x65, 0x96, 0xc6, 0xb4, 0xfd, 0x0d,
+ 0xbe, 0x48, 0xb4, 0xf7, 0xf7, 0x45, 0x4f, 0xcd, 0x72, 0xce, 0x6e, 0xe7,
+ 0xc6, 0xbe, 0xe8, 0xd7, 0xf5, 0x46, 0x5f, 0xd4, 0x0d, 0x5f, 0x94, 0x81,
+ 0x2f, 0x1a, 0xbe, 0x65, 0x5f, 0x34, 0xa2, 0xdf, 0xd8, 0x17, 0x1d, 0xd4,
+ 0xaf, 0xfb, 0x22, 0xc6, 0x9e, 0x15, 0x5c, 0x9b, 0xb2, 0x67, 0x5f, 0x20,
+ 0xe7, 0x28, 0xfc, 0xf0, 0x16, 0xc8, 0xba, 0x8d, 0x6b, 0x27, 0x56, 0x80,
+ 0xdd, 0x4f, 0x60, 0xae, 0xdf, 0x86, 0xbd, 0xef, 0x89, 0xdb, 0xe6, 0x43,
+ 0x6a, 0xde, 0xf7, 0xea, 0x7c, 0x68, 0x5d, 0xe7, 0xa4, 0xf1, 0x97, 0xea,
+ 0xdc, 0xf5, 0x74, 0x4e, 0x5d, 0xb7, 0xca, 0x11, 0x35, 0x6f, 0x5d, 0x42,
+ 0xf7, 0x09, 0xbc, 0x8a, 0x3c, 0x60, 0x24, 0x2c, 0x8c, 0xa7, 0x63, 0x7e,
+ 0xea, 0x2b, 0x0e, 0x1a, 0x04, 0xfa, 0x6d, 0x57, 0xbe, 0x68, 0x3f, 0xf4,
+ 0xbe, 0x5a, 0xbd, 0x35, 0x5d, 0x65, 0x1a, 0x74, 0xf5, 0xe0, 0x06, 0x5d,
+ 0xb5, 0x48, 0x7f, 0x3c, 0xd0, 0xd1, 0x36, 0x49, 0xc6, 0xa9, 0xb3, 0x5b,
+ 0xd1, 0xd5, 0xb9, 0xbf, 0x25, 0x5d, 0x7d, 0xf7, 0x26, 0xba, 0xfa, 0xde,
+ 0x26, 0x5d, 0xd9, 0xe6, 0x33, 0x1a, 0xc7, 0x66, 0xfc, 0xa0, 0x3f, 0xaa,
+ 0xdf, 0x39, 0xce, 0xfc, 0xa1, 0xc6, 0x35, 0x1d, 0xe4, 0x1d, 0x5c, 0xcf,
+ 0x2f, 0xd7, 0x0d, 0xdb, 0x86, 0xec, 0xb8, 0xa6, 0x29, 0x37, 0xcb, 0xfc,
+ 0x14, 0xe9, 0x47, 0xec, 0x18, 0x47, 0xac, 0xf1, 0x68, 0x68, 0x96, 0xf2,
+ 0x76, 0xaf, 0xff, 0x78, 0xa9, 0xfe, 0x73, 0x3d, 0xf1, 0x0b, 0xe4, 0x95,
+ 0xb6, 0x1f, 0x07, 0xc2, 0xf2, 0x85, 0x8a, 0x95, 0x75, 0xb5, 0x76, 0xc9,
+ 0xef, 0x40, 0xec, 0x29, 0xd1, 0x7f, 0xed, 0xbc, 0x49, 0x8c, 0xee, 0xf2,
+ 0x63, 0xf4, 0x9f, 0x81, 0x56, 0xe6, 0x57, 0xff, 0xe6, 0xdd, 0x95, 0x08,
+ 0xbf, 0xe3, 0xe6, 0x41, 0xf9, 0x2c, 0x79, 0x44, 0xbc, 0x67, 0xdc, 0xb7,
+ 0x99, 0xf3, 0xe4, 0x43, 0x89, 0x36, 0xc9, 0x6f, 0xe7, 0x7a, 0xa4, 0x9f,
+ 0xa3, 0xef, 0x6a, 0xf6, 0xe9, 0x0e, 0x72, 0x24, 0xfe, 0xb5, 0x18, 0x60,
+ 0x19, 0x7d, 0x90, 0x0f, 0x95, 0xc8, 0xc7, 0xbb, 0xbe, 0x3d, 0x31, 0x57,
+ 0x90, 0x26, 0xcf, 0x37, 0x8c, 0x20, 0x17, 0xa0, 0x1d, 0x04, 0x3a, 0xa7,
+ 0xbe, 0x99, 0x23, 0x48, 0x4c, 0xb7, 0x99, 0x23, 0x88, 0x69, 0x24, 0x0e,
+ 0x6a, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0xc9,
+ 0xda, 0x71, 0xdc, 0x53, 0x79, 0x08, 0x68, 0xf1, 0xc6, 0x4f, 0x7b, 0xe3,
+ 0x83, 0xce, 0x9d, 0x92, 0x53, 0x3a, 0x21, 0xbf, 0xc8, 0x35, 0x94, 0xbf,
+ 0x1e, 0xd6, 0x3c, 0x7f, 0xcd, 0xf1, 0x32, 0x78, 0xfe, 0x7e, 0xe4, 0x73,
+ 0xae, 0xae, 0xdb, 0xd7, 0x65, 0x32, 0xd5, 0x20, 0x93, 0xc9, 0x2a, 0x65,
+ 0xc4, 0xfe, 0xf4, 0xb9, 0x13, 0xfa, 0xc2, 0xba, 0x5c, 0x46, 0x40, 0x43,
+ 0x0b, 0x79, 0xf7, 0xf9, 0xe0, 0xf8, 0x9d, 0xfe, 0xf8, 0xbf, 0x81, 0x31,
+ 0xe9, 0x5f, 0x6f, 0x34, 0x2f, 0xe7, 0x64, 0xce, 0xf8, 0x7e, 0xfc, 0x20,
+ 0x67, 0xc6, 0x1a, 0x78, 0x69, 0x3d, 0x9f, 0x8e, 0x21, 0x9f, 0x7e, 0x07,
+ 0xb9, 0x74, 0xbd, 0xce, 0x38, 0x55, 0x40, 0x9e, 0x9b, 0x76, 0xb8, 0xae,
+ 0x6f, 0x65, 0xdd, 0x6e, 0x58, 0xb3, 0x66, 0xd2, 0xe0, 0xb8, 0x61, 0xf1,
+ 0xc6, 0xe4, 0xfd, 0x16, 0xe4, 0x82, 0xef, 0xe0, 0x37, 0x7d, 0x72, 0x90,
+ 0xe7, 0xb1, 0x0f, 0x9f, 0x7f, 0x15, 0x73, 0xf7, 0x03, 0xcf, 0xf4, 0xca,
+ 0x77, 0x6a, 0xb6, 0x7c, 0x1b, 0x98, 0xe6, 0x5b, 0xc8, 0x2d, 0xbe, 0x59,
+ 0x0b, 0x72, 0xfb, 0xbd, 0x30, 0x75, 0xe6, 0xf7, 0x12, 0xde, 0x69, 0x13,
+ 0x57, 0xe5, 0xf7, 0x7f, 0xda, 0x96, 0xad, 0x11, 0xfc, 0xfe, 0x95, 0x84,
+ 0x6c, 0xeb, 0xc4, 0xf7, 0xf6, 0x04, 0x4c, 0x27, 0xc1, 0xd8, 0xa8, 0x35,
+ 0xc4, 0x46, 0xd1, 0xd2, 0xe0, 0x71, 0x0a, 0xe3, 0xa5, 0xc1, 0xf7, 0x67,
+ 0x6a, 0x61, 0x2d, 0x35, 0xbb, 0x1b, 0x98, 0x24, 0xc8, 0x71, 0x91, 0x47,
+ 0x99, 0xab, 0xdb, 0x43, 0xf2, 0x36, 0x78, 0x4a, 0x82, 0x76, 0x17, 0x39,
+ 0xc0, 0x3f, 0xc5, 0x5c, 0xd6, 0x4f, 0x3f, 0x2d, 0xff, 0xda, 0xcf, 0xc3,
+ 0x9b, 0x64, 0x4e, 0xf1, 0xc8, 0x76, 0xc9, 0xfc, 0xcb, 0x9e, 0xeb, 0xed,
+ 0xcf, 0xae, 0xb7, 0xc7, 0x32, 0xbf, 0xb1, 0xde, 0x7e, 0x35, 0xe4, 0xe1,
+ 0x95, 0x41, 0x6d, 0xb4, 0xf6, 0x2f, 0x8c, 0x00, 0xeb, 0x14, 0x66, 0x7b,
+ 0x31, 0xd7, 0x36, 0x99, 0xb4, 0xdf, 0x06, 0xf6, 0xb2, 0x63, 0x39, 0xac,
+ 0xaf, 0xa7, 0x36, 0xf9, 0xfa, 0x36, 0xf8, 0x8f, 0xd3, 0xb3, 0xd6, 0x20,
+ 0xfd, 0x47, 0x1c, 0x6b, 0x29, 0xf9, 0x1e, 0xff, 0xf1, 0x6d, 0xa3, 0xd1,
+ 0x7f, 0x18, 0xf0, 0x1f, 0xfb, 0xdf, 0xc7, 0x7f, 0x3c, 0xf5, 0x1e, 0xff,
+ 0xa1, 0xc1, 0x2e, 0xe8, 0x3f, 0x7e, 0x68, 0x04, 0xfe, 0xa3, 0xb0, 0xc1,
+ 0x7f, 0x04, 0xfa, 0xb0, 0x55, 0xee, 0xe8, 0xfd, 0x26, 0xfe, 0x6c, 0xf3,
+ 0x31, 0xa7, 0x84, 0x43, 0x09, 0x37, 0x33, 0x65, 0xef, 0x92, 0x26, 0xac,
+ 0xd1, 0x97, 0x6b, 0x03, 0xf0, 0x25, 0xbf, 0x0f, 0x9c, 0x66, 0x39, 0x4c,
+ 0x44, 0x9a, 0x12, 0xd4, 0xcd, 0x48, 0x2c, 0x69, 0xbf, 0x90, 0x59, 0xa8,
+ 0xbe, 0x90, 0x39, 0xa7, 0x74, 0x35, 0x61, 0x79, 0x18, 0xf8, 0x09, 0x0b,
+ 0x18, 0x18, 0xcf, 0x87, 0x80, 0x21, 0xd8, 0xde, 0x6e, 0x26, 0x91, 0xa3,
+ 0x54, 0xaa, 0x2b, 0x99, 0x02, 0x3e, 0x53, 0xaa, 0xef, 0x58, 0x8c, 0x7d,
+ 0x5b, 0x12, 0xe5, 0xd8, 0x9f, 0xe2, 0xbb, 0x39, 0x31, 0x67, 0x5d, 0xb6,
+ 0x39, 0xee, 0x6b, 0xb1, 0x73, 0x6a, 0x8c, 0x90, 0x14, 0xd4, 0xb3, 0x5f,
+ 0xb5, 0xf8, 0xec, 0x29, 0xf8, 0xf8, 0x93, 0x55, 0x53, 0x4e, 0x54, 0xd7,
+ 0x32, 0x39, 0x7c, 0x88, 0x6d, 0x5e, 0x2e, 0xf1, 0xfe, 0xb7, 0x70, 0x3f,
+ 0x24, 0xcc, 0x3d, 0x3e, 0x8f, 0x3e, 0x47, 0xd1, 0xe7, 0x48, 0x35, 0xc0,
+ 0x8d, 0xbc, 0xef, 0x66, 0x52, 0xb8, 0x7f, 0xa4, 0xe8, 0x66, 0xd2, 0x45,
+ 0xe6, 0x39, 0x7d, 0xd1, 0x13, 0x90, 0x67, 0x16, 0xb1, 0xdd, 0x15, 0xab,
+ 0x37, 0x2f, 0x8f, 0xb5, 0x0e, 0x23, 0xaf, 0x3e, 0x8f, 0x98, 0xe3, 0x8e,
+ 0x59, 0x4e, 0x19, 0xcc, 0x4d, 0x95, 0xee, 0x90, 0xc2, 0x0c, 0x62, 0x8c,
+ 0x73, 0x0f, 0x73, 0xed, 0x8c, 0x1e, 0x77, 0xe0, 0x13, 0x06, 0x80, 0x27,
+ 0xbb, 0x81, 0x85, 0xef, 0x92, 0x15, 0xd3, 0x8a, 0x0e, 0x03, 0x03, 0xa7,
+ 0x42, 0xe8, 0xd3, 0x7b, 0x9b, 0x64, 0xa3, 0x94, 0xf5, 0x0e, 0xf8, 0x07,
+ 0x4d, 0x5a, 0xec, 0x46, 0x5f, 0xf5, 0x17, 0x10, 0x2f, 0x92, 0xdf, 0x36,
+ 0xb6, 0xb7, 0xfa, 0x3a, 0xd9, 0x22, 0xab, 0xef, 0xe9, 0xf7, 0x37, 0x0d,
+ 0xfd, 0x1a, 0xdb, 0x35, 0x4d, 0xd0, 0x7f, 0x0d, 0x34, 0x84, 0xe2, 0x90,
+ 0x3f, 0x78, 0x68, 0x82, 0x9d, 0x5c, 0x06, 0x3f, 0xf4, 0x9b, 0x85, 0x32,
+ 0xe3, 0xa4, 0x21, 0x65, 0x13, 0xf7, 0xaa, 0xf5, 0xfa, 0x82, 0x0d, 0x5a,
+ 0x2f, 0x90, 0xde, 0xb0, 0x0c, 0x57, 0x7b, 0xc4, 0x5d, 0xa4, 0x1c, 0x2c,
+ 0xac, 0x8e, 0x5d, 0x6d, 0xa9, 0x79, 0xcb, 0xcd, 0x63, 0x44, 0xe3, 0x42,
+ 0x57, 0x5b, 0x12, 0x71, 0x51, 0xbf, 0x10, 0x6b, 0x4b, 0xc1, 0x1f, 0x18,
+ 0x17, 0x6e, 0x6f, 0x4b, 0xcf, 0x92, 0x2e, 0x03, 0x71, 0xf1, 0x4e, 0xe0,
+ 0xc2, 0xba, 0x7c, 0x0d, 0xb9, 0x4f, 0xa1, 0x17, 0x31, 0x03, 0xab, 0x44,
+ 0x07, 0xdd, 0x79, 0x53, 0xc2, 0x6d, 0x89, 0x79, 0xd0, 0xd7, 0xdf, 0x9a,
+ 0x9c, 0xdd, 0x82, 0x3e, 0x06, 0xda, 0x7b, 0x88, 0x21, 0x1b, 0xda, 0xed,
+ 0x36, 0xf8, 0x5f, 0xf8, 0x3a, 0x09, 0x27, 0x07, 0xda, 0x31, 0xfe, 0xd9,
+ 0x10, 0x73, 0x87, 0x70, 0x7c, 0xbd, 0xfd, 0xcb, 0x5e, 0x7b, 0x2f, 0x68,
+ 0xe1, 0x73, 0xcc, 0x21, 0x25, 0x3c, 0x3e, 0x60, 0x82, 0x06, 0xf6, 0x8d,
+ 0xa8, 0xbe, 0xe9, 0x79, 0xda, 0x80, 0x9b, 0x59, 0xb0, 0x77, 0x4b, 0x6a,
+ 0x6e, 0xa7, 0x0c, 0xcf, 0x75, 0xca, 0xfe, 0x39, 0xe6, 0xbc, 0xc4, 0xc0,
+ 0x60, 0x05, 0x39, 0xa9, 0x7e, 0x81, 0xb9, 0x80, 0x15, 0x3d, 0x2a, 0xdd,
+ 0xd1, 0xcf, 0x63, 0x1d, 0x8c, 0xdb, 0xf1, 0xd8, 0x24, 0xd6, 0x58, 0x48,
+ 0x8d, 0x13, 0x0d, 0xe6, 0xa4, 0x8d, 0x6e, 0x98, 0x37, 0x3d, 0x7f, 0xb3,
+ 0x71, 0xb1, 0x70, 0x2e, 0x44, 0x37, 0x8d, 0xfb, 0x3f, 0xfd, 0x71, 0x4d,
+ 0x8c, 0xdb, 0x85, 0x31, 0xc9, 0xe3, 0xed, 0xad, 0x43, 0xb3, 0xe2, 0xb6,
+ 0x80, 0xbe, 0x74, 0x7c, 0x97, 0x4c, 0x62, 0x9c, 0x93, 0x73, 0xf4, 0x85,
+ 0xb2, 0x13, 0x9f, 0xfe, 0x26, 0x89, 0xf7, 0x2e, 0x21, 0x2f, 0x1e, 0x52,
+ 0x63, 0x78, 0x39, 0xaa, 0x7e, 0x21, 0x01, 0x5c, 0xf3, 0x51, 0xd0, 0xc3,
+ 0x98, 0x4c, 0x9e, 0x43, 0xe0, 0x37, 0x81, 0x75, 0x48, 0x3c, 0xce, 0xf5,
+ 0x8d, 0xdf, 0x4b, 0xd1, 0xd6, 0xd4, 0x6c, 0x33, 0xd6, 0x9d, 0xec, 0x36,
+ 0x54, 0xac, 0xa0, 0x5e, 0xec, 0xd6, 0x64, 0x49, 0xd1, 0xdd, 0x9a, 0x2a,
+ 0x51, 0x46, 0x4e, 0x6b, 0xba, 0x44, 0x19, 0x09, 0xe8, 0x71, 0xe0, 0x63,
+ 0x43, 0x12, 0xdb, 0x4e, 0x3d, 0x1e, 0x43, 0xbf, 0x95, 0x10, 0xf3, 0xfe,
+ 0xa4, 0xcd, 0xdf, 0xc0, 0x2b, 0x17, 0x8e, 0xa3, 0x2f, 0x7f, 0xdf, 0x8b,
+ 0x71, 0xbb, 0x7b, 0x0b, 0xd2, 0xdc, 0x7b, 0x04, 0x7e, 0x42, 0x1f, 0x00,
+ 0xee, 0x50, 0x76, 0x5e, 0x07, 0x26, 0xdb, 0x0b, 0x7e, 0xb0, 0x36, 0xe2,
+ 0xb6, 0x4c, 0xcc, 0x50, 0xae, 0x72, 0x1b, 0x78, 0x00, 0xff, 0x71, 0xf8,
+ 0x16, 0xf2, 0xc0, 0xb9, 0x05, 0x76, 0xbf, 0x2c, 0xb9, 0x99, 0xb0, 0xc2,
+ 0x3e, 0xae, 0xc9, 0xf9, 0x35, 0x4d, 0x4f, 0xb4, 0x41, 0xc7, 0xe4, 0x6d,
+ 0x0a, 0xb4, 0x3d, 0x0e, 0x3f, 0x6c, 0xa9, 0x9c, 0xdb, 0x40, 0xff, 0x42,
+ 0x69, 0x50, 0x4f, 0x15, 0x49, 0xbf, 0x6f, 0x7b, 0xda, 0x0a, 0x7c, 0x8a,
+ 0xaa, 0x63, 0x21, 0xb7, 0x4b, 0xc0, 0x8f, 0x0c, 0xca, 0xf7, 0xe1, 0x4b,
+ 0xbe, 0x5b, 0x73, 0xe0, 0xff, 0xfb, 0xe1, 0xff, 0x7b, 0xe1, 0xff, 0x6d,
+ 0xf8, 0xff, 0x18, 0xfc, 0x7f, 0x17, 0xfc, 0x7f, 0x94, 0xbe, 0x5f, 0x4e,
+ 0xd6, 0xf2, 0xb0, 0xb1, 0x15, 0xf8, 0x41, 0x33, 0xec, 0xd6, 0x22, 0xe1,
+ 0x64, 0x2d, 0x1a, 0x4e, 0xd5, 0x42, 0xe0, 0xe9, 0x30, 0xe7, 0x04, 0x7f,
+ 0xf9, 0xd6, 0xa1, 0x52, 0x3f, 0xe2, 0x8a, 0x0b, 0xbf, 0x94, 0x86, 0xdf,
+ 0x77, 0x80, 0x7f, 0xf3, 0xb2, 0x3a, 0x13, 0xc3, 0x33, 0x75, 0x49, 0x3b,
+ 0x4d, 0x32, 0x69, 0x3a, 0x18, 0x63, 0xbb, 0xb2, 0x53, 0x23, 0xb1, 0xab,
+ 0x09, 0x76, 0x2a, 0xb9, 0x22, 0xe3, 0x73, 0x17, 0xc6, 0x6b, 0x45, 0x7c,
+ 0xa0, 0x7f, 0xa0, 0x2f, 0x58, 0xc9, 0x3c, 0x6c, 0x73, 0xcd, 0xb5, 0x69,
+ 0x49, 0xe0, 0x67, 0x62, 0x13, 0xc4, 0x3a, 0xd8, 0x05, 0xdb, 0xf6, 0xe0,
+ 0x39, 0xfe, 0xfe, 0x6f, 0x7e, 0x8d, 0xea, 0xaf, 0x5a, 0x04, 0xc6, 0xfb,
+ 0x32, 0x63, 0x8f, 0x8d, 0xf1, 0xaa, 0x8d, 0xeb, 0x75, 0x49, 0x17, 0x3b,
+ 0xb8, 0xcf, 0x7a, 0x0d, 0x6b, 0x54, 0xaf, 0x80, 0xde, 0x7a, 0x7d, 0x55,
+ 0x61, 0x48, 0xe4, 0x33, 0x87, 0xd6, 0xc0, 0x43, 0xe3, 0x33, 0xdf, 0xc0,
+ 0x33, 0xaa, 0x2d, 0x6c, 0x26, 0x1c, 0xe6, 0x50, 0xf0, 0x9b, 0x2f, 0xc0,
+ 0x47, 0x1e, 0xcb, 0xe8, 0xcb, 0x57, 0xf1, 0x2c, 0x64, 0x5a, 0x3c, 0x96,
+ 0x09, 0xf5, 0xbc, 0x5a, 0x7f, 0x16, 0x39, 0xf1, 0xd0, 0xf2, 0x80, 0xa4,
+ 0x96, 0xbb, 0xa3, 0x17, 0xa5, 0xf5, 0x1d, 0x17, 0xb1, 0x74, 0xb2, 0x6a,
+ 0x9d, 0x76, 0x85, 0x39, 0xba, 0x29, 0x0b, 0xc0, 0xd5, 0x7b, 0xf6, 0x3d,
+ 0x0f, 0xda, 0xad, 0x17, 0x45, 0x8f, 0xe1, 0x37, 0x31, 0x0c, 0x79, 0x5c,
+ 0x03, 0x7f, 0x1a, 0xae, 0x5b, 0xd6, 0x6b, 0x57, 0x85, 0x12, 0xf8, 0xac,
+ 0x1d, 0xcb, 0x5c, 0x9c, 0x06, 0xae, 0x83, 0x3e, 0x92, 0xd3, 0xc4, 0x9c,
+ 0x5b, 0x20, 0x93, 0x21, 0xd8, 0x05, 0xf5, 0x1d, 0xc7, 0xb3, 0x75, 0xf9,
+ 0x92, 0x43, 0x1b, 0x78, 0x0e, 0x72, 0xc3, 0x58, 0xa1, 0x80, 0x6e, 0x60,
+ 0x80, 0x19, 0xca, 0x6a, 0x17, 0xf2, 0x36, 0x57, 0x06, 0xf6, 0x49, 0x78,
+ 0x47, 0x62, 0x73, 0x4e, 0x76, 0x2c, 0xb3, 0x3a, 0x8d, 0xf1, 0x7b, 0x80,
+ 0x79, 0x84, 0xb5, 0x19, 0xfa, 0x60, 0x81, 0xed, 0xec, 0x87, 0x7e, 0x98,
+ 0x7b, 0x33, 0x47, 0xa3, 0x6f, 0x3a, 0xa8, 0xa5, 0x2a, 0x65, 0x43, 0x3a,
+ 0x0e, 0x21, 0xb7, 0x71, 0x64, 0x71, 0x9a, 0x39, 0x1a, 0xf3, 0x99, 0x20,
+ 0x7f, 0xd1, 0x90, 0x4b, 0xa0, 0x7d, 0xf9, 0x25, 0xa5, 0x07, 0x03, 0xfa,
+ 0xca, 0xed, 0xbb, 0x9f, 0x7c, 0xcd, 0x18, 0x09, 0xf8, 0xbf, 0x01, 0xf2,
+ 0xa2, 0x68, 0x40, 0xce, 0xc6, 0x35, 0x17, 0x03, 0x5f, 0xf8, 0x5c, 0xcf,
+ 0xdd, 0xd4, 0xdf, 0x64, 0xe9, 0x04, 0xec, 0x58, 0xf2, 0x4d, 0x09, 0xf0,
+ 0x36, 0x80, 0xdf, 0x58, 0xf8, 0x27, 0xa1, 0xc3, 0x73, 0x03, 0xac, 0x91,
+ 0x3d, 0x07, 0xfc, 0x47, 0xfa, 0xe3, 0xb1, 0x13, 0x6a, 0xdd, 0xe2, 0xba,
+ 0xca, 0x3c, 0x62, 0x8b, 0x5c, 0x54, 0x7c, 0xde, 0xc1, 0xfc, 0x14, 0x7a,
+ 0xb9, 0x15, 0x3e, 0x87, 0x3f, 0x24, 0x9f, 0xde, 0x3c, 0x8c, 0x5b, 0x49,
+ 0x3b, 0x26, 0xa9, 0xe2, 0xcb, 0x75, 0xaf, 0x0e, 0xfb, 0x47, 0xb0, 0x2b,
+ 0x5c, 0x57, 0xc3, 0xa0, 0x87, 0x75, 0x99, 0x01, 0xa5, 0x5b, 0xd0, 0x43,
+ 0x9b, 0xc9, 0x87, 0x13, 0xdb, 0xe4, 0xfc, 0x4c, 0x87, 0x2c, 0xcc, 0xbc,
+ 0x26, 0x95, 0x99, 0x36, 0x59, 0x9a, 0xa9, 0xcb, 0x65, 0x47, 0xf9, 0x25,
+ 0xbb, 0x59, 0xad, 0x69, 0xd9, 0xe5, 0x61, 0xf6, 0xf8, 0xe0, 0x15, 0x79,
+ 0x5a, 0xce, 0x97, 0x3d, 0x1e, 0x32, 0x0d, 0x3c, 0xbc, 0x0a, 0x1b, 0xeb,
+ 0xec, 0x21, 0x0f, 0xb4, 0x07, 0xf2, 0xc3, 0xdc, 0x83, 0x39, 0xe6, 0x41,
+ 0xac, 0xa3, 0x11, 0x60, 0xa3, 0x83, 0x5a, 0xd2, 0xe7, 0x21, 0xe5, 0xf1,
+ 0x90, 0x7d, 0x2f, 0x0f, 0x2d, 0x92, 0xdd, 0x49, 0x3e, 0xa0, 0x83, 0x69,
+ 0xea, 0x25, 0xc0, 0x1b, 0x1e, 0xfd, 0xc9, 0xe5, 0x57, 0xeb, 0xfa, 0x74,
+ 0x93, 0xa2, 0xdd, 0x48, 0x0c, 0xc0, 0xae, 0x5e, 0xad, 0xcb, 0x32, 0xd7,
+ 0x12, 0x7e, 0x57, 0xff, 0x31, 0xfc, 0x55, 0xa7, 0xca, 0x5b, 0x72, 0x63,
+ 0xed, 0xad, 0xc9, 0xf9, 0x41, 0xe8, 0xba, 0x55, 0xad, 0x45, 0xb8, 0x0e,
+ 0xe8, 0xf0, 0x0f, 0xd1, 0xff, 0xab, 0x5c, 0x73, 0x4a, 0x3e, 0x69, 0xc8,
+ 0xa7, 0x50, 0xbc, 0xbd, 0x19, 0x39, 0x37, 0xe6, 0x71, 0x33, 0xd9, 0x2a,
+ 0x9f, 0xe9, 0x82, 0x7f, 0xe3, 0xf7, 0x07, 0xb6, 0x8f, 0x3c, 0xfc, 0x2e,
+ 0x6c, 0x00, 0xb9, 0x05, 0xd7, 0xf4, 0xc0, 0x0a, 0xe2, 0x6c, 0xbc, 0x77,
+ 0x41, 0xd5, 0xf4, 0x1d, 0x85, 0x9f, 0x26, 0xab, 0x5f, 0xc5, 0xc7, 0x9b,
+ 0x6f, 0xa8, 0xc6, 0x39, 0x37, 0xf2, 0x84, 0x9c, 0x06, 0xb9, 0xa4, 0x8d,
+ 0x71, 0x39, 0x6f, 0x5e, 0x8c, 0x84, 0x81, 0x79, 0xd9, 0xd6, 0x0e, 0x3f,
+ 0x13, 0x83, 0xdf, 0xea, 0x87, 0xff, 0xe7, 0x5a, 0xa6, 0xaf, 0x0f, 0x68,
+ 0xef, 0xc7, 0x98, 0xf4, 0xc1, 0xfd, 0xe0, 0x99, 0xb9, 0x34, 0x7d, 0x28,
+ 0x62, 0xca, 0x62, 0xb4, 0x2d, 0x39, 0xeb, 0xd5, 0x93, 0xbc, 0xdf, 0xbc,
+ 0x2f, 0xe1, 0xdd, 0x09, 0xab, 0x9c, 0x47, 0xfe, 0x97, 0xc2, 0xda, 0x4d,
+ 0xda, 0xc8, 0xa7, 0x17, 0xad, 0x17, 0x88, 0xd3, 0x74, 0xca, 0x60, 0x99,
+ 0x72, 0x62, 0x6d, 0xc3, 0x94, 0xfc, 0xc2, 0xef, 0x42, 0x1e, 0x61, 0xd9,
+ 0x6e, 0x67, 0xe1, 0x53, 0x98, 0xb7, 0xb8, 0xe0, 0x8d, 0xbe, 0xa7, 0x1b,
+ 0xb1, 0xcc, 0x80, 0x10, 0x90, 0x57, 0x2d, 0x1b, 0xf2, 0x40, 0xa8, 0x0f,
+ 0x79, 0xe0, 0xa7, 0xd0, 0x37, 0x24, 0xf9, 0x65, 0xc6, 0x84, 0x90, 0x4c,
+ 0x2d, 0x8b, 0x5c, 0x99, 0xa6, 0x5f, 0x51, 0x7f, 0x90, 0xb9, 0x9b, 0x99,
+ 0x20, 0x3e, 0x9b, 0xa1, 0x8f, 0xa1, 0xff, 0xd8, 0x01, 0x5d, 0xc4, 0x9f,
+ 0xfb, 0x12, 0xe2, 0xd3, 0x64, 0xb1, 0x1b, 0x7e, 0x53, 0x56, 0x74, 0xc8,
+ 0x14, 0x71, 0x8d, 0xf5, 0xaa, 0x1b, 0xd4, 0xaa, 0x82, 0x3a, 0x55, 0x58,
+ 0x0a, 0xd3, 0xac, 0x51, 0x85, 0x41, 0x0b, 0x73, 0x57, 0x43, 0xe5, 0x42,
+ 0x3b, 0x94, 0x7f, 0xe5, 0x77, 0xa8, 0x61, 0xde, 0xf8, 0xe9, 0x3d, 0x3a,
+ 0xfd, 0xd8, 0x6e, 0x71, 0x47, 0x8f, 0xb5, 0xee, 0x2f, 0x01, 0x8b, 0x76,
+ 0xd2, 0x3e, 0xa9, 0xff, 0xac, 0x4e, 0x7f, 0x3b, 0x55, 0x1a, 0xc0, 0x78,
+ 0xc4, 0x95, 0x21, 0xf4, 0x8b, 0xf8, 0xfd, 0x28, 0xd7, 0x7f, 0x25, 0xe3,
+ 0xfb, 0xfe, 0x1a, 0x74, 0x79, 0xfe, 0x8e, 0x75, 0xee, 0xdc, 0x67, 0x74,
+ 0xb9, 0xef, 0x63, 0x69, 0x3c, 0xcb, 0x78, 0xf8, 0xb6, 0x8f, 0xe1, 0xd8,
+ 0xc6, 0xba, 0x1e, 0x72, 0xf5, 0xf3, 0x26, 0xbe, 0x3b, 0x25, 0x7f, 0x3e,
+ 0x0c, 0x39, 0x20, 0x2f, 0x5e, 0xf0, 0xc6, 0x62, 0xee, 0x7b, 0x1a, 0x3a,
+ 0xd2, 0xcf, 0x84, 0xa5, 0xe9, 0x4c, 0xa7, 0x84, 0xbe, 0xd2, 0x26, 0xcd,
+ 0x5f, 0xe9, 0x11, 0xe3, 0x2b, 0xac, 0x3f, 0x58, 0xb1, 0x93, 0xaa, 0xf6,
+ 0x91, 0x96, 0x53, 0x88, 0x61, 0x3a, 0xe2, 0xb1, 0xb2, 0x53, 0x73, 0xa7,
+ 0x18, 0x48, 0x5e, 0xf5, 0x67, 0x5c, 0xf9, 0xe2, 0xbe, 0x9f, 0xab, 0xda,
+ 0x1b, 0x70, 0xb3, 0xe8, 0xcf, 0x67, 0xc4, 0xad, 0xbd, 0x46, 0x3b, 0xcd,
+ 0xbc, 0x7a, 0xd7, 0x1d, 0xd0, 0x39, 0x73, 0xcb, 0x5e, 0x55, 0xc7, 0xfd,
+ 0xe2, 0x3e, 0xc6, 0x4c, 0x2f, 0xbf, 0x4c, 0x23, 0xbf, 0x9c, 0x94, 0x6e,
+ 0xf8, 0x59, 0xf6, 0xdb, 0x29, 0x3a, 0xe6, 0xca, 0x09, 0xf3, 0xf5, 0x3b,
+ 0xc5, 0x3d, 0x8c, 0x75, 0x71, 0x56, 0x66, 0xf4, 0x84, 0xa6, 0xc6, 0x34,
+ 0x9e, 0xa1, 0xdf, 0xa2, 0x3f, 0xa3, 0x8d, 0xb3, 0x0e, 0x82, 0xb6, 0xe7,
+ 0xe9, 0xb3, 0x3c, 0xdb, 0x1e, 0x6a, 0xf0, 0x7d, 0x53, 0xa5, 0x1a, 0x74,
+ 0x88, 0xbc, 0xde, 0x6e, 0x02, 0xff, 0x88, 0xeb, 0x36, 0xaf, 0xc9, 0x3f,
+ 0x7c, 0x69, 0x24, 0xa2, 0xae, 0x0b, 0x65, 0x0f, 0xf7, 0x7a, 0xe3, 0x33,
+ 0x07, 0x81, 0xaf, 0xa9, 0x91, 0x0e, 0xce, 0xdb, 0x25, 0xc6, 0xd9, 0x88,
+ 0x84, 0xce, 0xd2, 0xfe, 0xac, 0x58, 0x1a, 0xf2, 0x9b, 0xb2, 0x89, 0xf5,
+ 0x0e, 0xc0, 0x17, 0xec, 0x16, 0xfd, 0x7c, 0x2f, 0xd6, 0x8e, 0x15, 0x2d,
+ 0x4b, 0x5c, 0x8c, 0x85, 0xb0, 0xbc, 0x09, 0xdf, 0x41, 0x7b, 0x39, 0x87,
+ 0x78, 0x75, 0xa2, 0xd6, 0xfa, 0xce, 0x8a, 0xa2, 0x82, 0x6d, 0x43, 0xc0,
+ 0x4b, 0x56, 0xaf, 0xab, 0xb7, 0xcb, 0xeb, 0xd0, 0x77, 0x56, 0xb5, 0xed,
+ 0xc6, 0xb8, 0xa0, 0xe1, 0x2c, 0xeb, 0x49, 0x1c, 0xf7, 0x1f, 0x60, 0x4c,
+ 0x8e, 0xed, 0x66, 0x56, 0x99, 0x9f, 0x4e, 0xd3, 0x76, 0x3b, 0x61, 0x77,
+ 0xb8, 0xae, 0x35, 0x4b, 0x76, 0x2c, 0x26, 0xfa, 0xf4, 0x83, 0xd2, 0xbd,
+ 0x4f, 0xf7, 0xf8, 0x51, 0x3c, 0xb2, 0x8d, 0x75, 0xca, 0x16, 0xb5, 0x1e,
+ 0xf5, 0x65, 0xd8, 0xcc, 0x41, 0xea, 0x18, 0xf1, 0x1f, 0xf1, 0x8d, 0xfe,
+ 0xcc, 0x40, 0x7c, 0x4b, 0xd5, 0x3c, 0xbd, 0x97, 0x0f, 0xee, 0x94, 0x53,
+ 0x67, 0x69, 0x4f, 0xb8, 0xb7, 0x6e, 0x53, 0xc1, 0x7e, 0x02, 0xef, 0xd9,
+ 0x72, 0xfa, 0x59, 0xe6, 0x1f, 0xcc, 0x3b, 0x98, 0x6b, 0x59, 0xd1, 0xfd,
+ 0xe0, 0x47, 0xbf, 0x8f, 0xfe, 0x40, 0x57, 0xb6, 0x9b, 0x83, 0xaf, 0x2e,
+ 0xd4, 0xa8, 0xb7, 0x7e, 0xee, 0xb9, 0x98, 0xcc, 0xd9, 0xdc, 0xa8, 0x27,
+ 0xef, 0x02, 0xda, 0x26, 0x11, 0x07, 0x52, 0xd5, 0x26, 0x59, 0x1b, 0x73,
+ 0xa1, 0xfb, 0x8f, 0x82, 0xae, 0xc3, 0xad, 0xc4, 0xab, 0x6b, 0x63, 0x69,
+ 0x5c, 0x1f, 0x56, 0x79, 0x9a, 0x71, 0x9f, 0x8b, 0x31, 0x76, 0x72, 0x1d,
+ 0xf9, 0x7a, 0x72, 0xf4, 0xc2, 0xcc, 0x7d, 0xfa, 0x24, 0x7c, 0xf7, 0xb0,
+ 0xc3, 0x18, 0xcf, 0xfa, 0x73, 0x0b, 0xe8, 0x68, 0x57, 0xd8, 0x42, 0xb7,
+ 0xf7, 0xe9, 0x85, 0x32, 0xfd, 0x7d, 0x3e, 0xda, 0x2c, 0x0e, 0x7d, 0x96,
+ 0xbe, 0x60, 0x53, 0x27, 0x9a, 0x5c, 0x54, 0xb5, 0x6a, 0x44, 0xa0, 0x6a,
+ 0x0a, 0x73, 0x39, 0x7a, 0xa5, 0xbc, 0x4f, 0xcf, 0xc3, 0x55, 0xaf, 0x45,
+ 0x48, 0x77, 0x4c, 0xe5, 0xf2, 0xfb, 0x94, 0xad, 0x15, 0x11, 0x53, 0x60,
+ 0x33, 0xce, 0x1d, 0x98, 0x57, 0xb5, 0xc1, 0xa6, 0xa8, 0x7b, 0xea, 0x5d,
+ 0xf9, 0x48, 0x5f, 0xf7, 0x37, 0x8a, 0xa1, 0x45, 0xf8, 0x5f, 0x62, 0xe9,
+ 0x16, 0xbf, 0x3e, 0xf5, 0xcf, 0xfd, 0x9c, 0xe8, 0x71, 0x61, 0x9e, 0x32,
+ 0x55, 0x22, 0x2d, 0x45, 0xf8, 0xc3, 0x1b, 0xd9, 0x12, 0xe5, 0xe8, 0xf9,
+ 0x94, 0x63, 0xb0, 0x0b, 0x7d, 0xd9, 0xf4, 0x6d, 0x40, 0xe1, 0x67, 0xdc,
+ 0x63, 0x0c, 0xc0, 0x77, 0xad, 0x09, 0xeb, 0x7d, 0x04, 0x32, 0xa2, 0x6e,
+ 0xa0, 0xbf, 0x65, 0xee, 0xd5, 0x41, 0x7f, 0xcb, 0x97, 0x7e, 0xe1, 0x76,
+ 0xd2, 0xe7, 0x0d, 0xc8, 0x29, 0xf8, 0xd1, 0x93, 0xf3, 0xa4, 0x27, 0xad,
+ 0xd6, 0xce, 0x14, 0xe4, 0x7d, 0x42, 0xf9, 0xf8, 0x7e, 0x79, 0x73, 0xf1,
+ 0x5b, 0x0a, 0x0b, 0xee, 0xd9, 0xb7, 0x22, 0x13, 0xf0, 0x0f, 0x47, 0xaa,
+ 0x90, 0xb7, 0x19, 0xc3, 0xfa, 0xdc, 0xa5, 0xfc, 0xe3, 0x17, 0x3f, 0x78,
+ 0xae, 0x12, 0xd2, 0x13, 0x0f, 0x7c, 0xc8, 0x18, 0xbe, 0x55, 0xdc, 0xce,
+ 0x0f, 0x3c, 0x8f, 0xa1, 0x27, 0xfe, 0x10, 0x3a, 0xfb, 0x4d, 0xcc, 0x15,
+ 0x06, 0x9d, 0x6a, 0x3f, 0xe4, 0x83, 0x3c, 0xa7, 0xeb, 0x89, 0x4f, 0x7e,
+ 0x48, 0xfa, 0x4c, 0x59, 0x04, 0x7e, 0xc8, 0xab, 0xb8, 0xca, 0xdc, 0xb1,
+ 0xc9, 0xd7, 0xe7, 0x0b, 0xc0, 0xd5, 0xc0, 0xd2, 0xc5, 0xc0, 0x17, 0xb7,
+ 0x48, 0xbe, 0x33, 0xc8, 0x47, 0xe1, 0xc3, 0xd7, 0xdb, 0x83, 0x1c, 0x97,
+ 0xcf, 0x67, 0x33, 0xc8, 0xa9, 0x61, 0x13, 0xb7, 0x61, 0x8d, 0xb2, 0x4d,
+ 0xe5, 0xb0, 0x37, 0xa1, 0xdf, 0xa3, 0x3d, 0x57, 0x6c, 0xcc, 0x2d, 0x0e,
+ 0xa8, 0xdc, 0x62, 0x68, 0x43, 0x6e, 0x11, 0xd4, 0xb4, 0x02, 0xba, 0x39,
+ 0x2e, 0x70, 0x03, 0xec, 0xe0, 0xbb, 0x18, 0xff, 0x3b, 0xd0, 0xf7, 0xb7,
+ 0x4b, 0xc0, 0x0d, 0x25, 0xe0, 0x86, 0x12, 0x70, 0x43, 0x09, 0xb8, 0xa1,
+ 0x14, 0xf5, 0xeb, 0x5b, 0x2e, 0x71, 0xff, 0x07, 0xb4, 0xe9, 0xa0, 0xee,
+ 0xb1, 0xd9, 0x5e, 0xbd, 0x3a, 0x59, 0xaa, 0x16, 0xe0, 0xe7, 0x30, 0xeb,
+ 0x76, 0xc0, 0x71, 0x41, 0x4d, 0xc4, 0x8f, 0x1d, 0x8b, 0xdc, 0x43, 0x41,
+ 0xec, 0x58, 0x74, 0xb1, 0x9e, 0xfa, 0xa2, 0x06, 0x70, 0xa3, 0x21, 0x51,
+ 0xfc, 0x36, 0xe1, 0x93, 0xb9, 0x67, 0xde, 0x8d, 0x15, 0xd6, 0xac, 0x6a,
+ 0x4f, 0x27, 0x54, 0x4d, 0xc2, 0x96, 0xc9, 0x72, 0x90, 0xdb, 0xc5, 0x65,
+ 0x68, 0x86, 0x58, 0x54, 0xb6, 0xeb, 0x09, 0xe8, 0xa2, 0x4a, 0xfc, 0xc8,
+ 0x3d, 0x27, 0xce, 0x1f, 0xef, 0xad, 0x60, 0xce, 0x82, 0xed, 0xd1, 0x77,
+ 0xa2, 0xaa, 0xce, 0x05, 0xf8, 0xcf, 0x05, 0x67, 0x01, 0xe2, 0xb2, 0x7f,
+ 0x86, 0x7b, 0xef, 0x31, 0x19, 0x2d, 0x3a, 0xc8, 0x65, 0x55, 0x8e, 0x84,
+ 0x78, 0xe0, 0xc9, 0x7d, 0xc8, 0x97, 0x7b, 0x0e, 0xd8, 0x61, 0xdc, 0x0e,
+ 0xe4, 0x4e, 0x79, 0x8f, 0x68, 0xc3, 0x90, 0xf5, 0x7e, 0x5f, 0xd6, 0xe9,
+ 0x25, 0x31, 0x91, 0xff, 0xc4, 0x8c, 0x7d, 0x63, 0xda, 0x68, 0x4d, 0x61,
+ 0x16, 0xfa, 0x23, 0x8c, 0xe5, 0x78, 0x6b, 0x1d, 0xf6, 0x92, 0xab, 0x6e,
+ 0xde, 0x8f, 0x6f, 0xc4, 0x2f, 0x9f, 0xd5, 0xc4, 0x0e, 0xe4, 0xd8, 0xd8,
+ 0x3e, 0xd1, 0xd0, 0xbe, 0x7e, 0xdf, 0xe7, 0x01, 0xbe, 0x72, 0xbd, 0x3e,
+ 0x41, 0xbf, 0x76, 0xbd, 0x1d, 0x78, 0x4f, 0x42, 0xea, 0x3e, 0x7c, 0xfe,
+ 0x62, 0x44, 0x52, 0x8b, 0xb6, 0xa4, 0xcb, 0xec, 0xc7, 0x9a, 0x07, 0xfd,
+ 0xd7, 0x1f, 0x4b, 0x0a, 0x79, 0x6e, 0x36, 0x62, 0x39, 0xae, 0xfc, 0x47,
+ 0x59, 0x9d, 0xcb, 0xc7, 0xb8, 0x77, 0x9d, 0x1f, 0xd5, 0xf0, 0xdc, 0x8f,
+ 0x71, 0x4d, 0xda, 0x6d, 0xac, 0x0f, 0xc6, 0xa9, 0xbe, 0xe8, 0x22, 0xee,
+ 0x65, 0xc7, 0x58, 0xe7, 0x79, 0x2a, 0x2c, 0x6d, 0x56, 0xac, 0x0c, 0x3b,
+ 0xb8, 0x54, 0xe4, 0x7c, 0xc0, 0x52, 0x45, 0xd6, 0x82, 0x82, 0xfb, 0x7f,
+ 0x0c, 0xec, 0xa8, 0x13, 0x3b, 0x79, 0x7d, 0x94, 0xbe, 0x5c, 0x33, 0x84,
+ 0x35, 0xb0, 0xe2, 0xfb, 0xe7, 0x85, 0xa2, 0x57, 0x7b, 0x39, 0x47, 0x3a,
+ 0xaa, 0x7f, 0x53, 0x5f, 0x89, 0x20, 0x67, 0x5a, 0xe7, 0xf1, 0x1c, 0xc7,
+ 0x37, 0xe1, 0x9e, 0xe5, 0x64, 0x35, 0x90, 0x05, 0xef, 0xb3, 0x8d, 0xfb,
+ 0xf3, 0xf5, 0xfa, 0x39, 0xfb, 0xc3, 0xd6, 0xd9, 0x9e, 0xbb, 0x27, 0x69,
+ 0xcb, 0x81, 0x85, 0xaa, 0x1c, 0xf0, 0xea, 0x6c, 0xd1, 0xbd, 0x5e, 0x9d,
+ 0x2d, 0xb6, 0x77, 0x63, 0x9d, 0xad, 0x7c, 0x8f, 0x57, 0x67, 0x33, 0x0f,
+ 0xc0, 0x07, 0x1f, 0xf0, 0xea, 0x6c, 0xff, 0xf5, 0x1e, 0xaf, 0xce, 0xd6,
+ 0x75, 0xaf, 0x57, 0x67, 0xeb, 0xdd, 0xeb, 0xd5, 0xd9, 0x46, 0xef, 0xdd,
+ 0x58, 0x67, 0x73, 0xf6, 0x6e, 0xac, 0xb3, 0x39, 0x07, 0x72, 0xf8, 0x5c,
+ 0xaf, 0xb3, 0x65, 0xf6, 0xde, 0xbc, 0xce, 0xf6, 0x4a, 0x80, 0xf1, 0xc1,
+ 0xcf, 0x00, 0x78, 0x70, 0x80, 0xf1, 0xfb, 0x81, 0xf1, 0x6f, 0x56, 0xe3,
+ 0x55, 0xe7, 0x37, 0xc0, 0xa7, 0xe6, 0xc7, 0x8f, 0x0f, 0x83, 0xf5, 0xb7,
+ 0xfa, 0xcf, 0xba, 0xc8, 0x8f, 0x63, 0x7e, 0x6e, 0x43, 0xbc, 0xbf, 0xcd,
+ 0xcf, 0xf1, 0xba, 0x5a, 0xaf, 0x9f, 0xad, 0x68, 0xfc, 0xbe, 0x0d, 0xa9,
+ 0x7a, 0x50, 0x03, 0x20, 0x5f, 0x72, 0xe0, 0x61, 0x25, 0x87, 0x3b, 0xd1,
+ 0xdf, 0x3c, 0xf0, 0x25, 0x9b, 0x75, 0x81, 0x27, 0xb1, 0x86, 0xdd, 0xed,
+ 0x86, 0xda, 0x67, 0x66, 0x4c, 0x3b, 0x2d, 0x29, 0xf4, 0x4f, 0xa9, 0xfe,
+ 0xa3, 0x0d, 0xfd, 0xb3, 0xe8, 0xcf, 0x71, 0xad, 0x7f, 0x8b, 0xcf, 0x73,
+ 0xca, 0xbe, 0x6d, 0x0f, 0xf7, 0xa7, 0x4b, 0x01, 0x4e, 0x0b, 0xf9, 0x18,
+ 0xdc, 0xcd, 0xb8, 0xd5, 0x7b, 0xf1, 0x8c, 0xf5, 0xa2, 0x2b, 0x57, 0x15,
+ 0xde, 0x37, 0x12, 0xd6, 0x8b, 0x59, 0x95, 0xdf, 0xb9, 0x99, 0x5c, 0x75,
+ 0x3d, 0x5f, 0x07, 0x0e, 0x63, 0xce, 0x03, 0x7b, 0x5f, 0xee, 0x45, 0xdc,
+ 0x6b, 0xcc, 0xc9, 0x99, 0x87, 0xeb, 0x7e, 0x1e, 0x6e, 0xca, 0xfd, 0xfb,
+ 0x1a, 0x31, 0xbe, 0x73, 0xe0, 0xef, 0x2b, 0x8c, 0xbf, 0x05, 0xb9, 0x3c,
+ 0x31, 0x3c, 0x71, 0x0f, 0x31, 0x07, 0x71, 0x3e, 0xeb, 0x0b, 0xcc, 0x7f,
+ 0x18, 0x4b, 0x99, 0x0f, 0x45, 0xf0, 0xe1, 0xb9, 0x97, 0x00, 0xeb, 0x37,
+ 0xfb, 0xfe, 0x9f, 0x79, 0x54, 0x80, 0x6d, 0xac, 0x2d, 0x5e, 0x2e, 0xb5,
+ 0x45, 0xf3, 0xf2, 0xd5, 0x98, 0xdf, 0x27, 0xb4, 0x8e, 0xa5, 0x43, 0xeb,
+ 0x58, 0x7a, 0xc3, 0x5e, 0x89, 0xa8, 0x33, 0x36, 0x6a, 0xcf, 0x85, 0x7b,
+ 0x30, 0x6e, 0xe6, 0x52, 0x0f, 0xf1, 0x30, 0xf7, 0x62, 0x80, 0x8d, 0xec,
+ 0xc6, 0x58, 0xc5, 0x38, 0x45, 0x3c, 0x15, 0xec, 0xb7, 0x06, 0x7a, 0xa2,
+ 0xec, 0xd8, 0xf6, 0x47, 0x1a, 0x72, 0x64, 0xa7, 0xd9, 0xde, 0x0f, 0x5a,
+ 0x32, 0xf8, 0x0e, 0x64, 0xfa, 0x80, 0x8a, 0x91, 0x2d, 0xb0, 0xdd, 0x13,
+ 0x25, 0x62, 0xde, 0x6d, 0xb2, 0xe8, 0xe3, 0xde, 0xf3, 0x33, 0x1e, 0xe6,
+ 0x0d, 0x6d, 0xc4, 0xbc, 0xce, 0xaa, 0x78, 0x34, 0xee, 0xbf, 0x21, 0x8d,
+ 0xc4, 0xb7, 0xa4, 0x8f, 0x31, 0x89, 0xfe, 0xd1, 0xcd, 0x5c, 0xee, 0x61,
+ 0x3c, 0x62, 0x2c, 0x8a, 0xc9, 0xea, 0x4d, 0xe9, 0x53, 0x6d, 0xc7, 0x5a,
+ 0xec, 0x30, 0x3e, 0x13, 0xf0, 0x1f, 0xa3, 0x78, 0x26, 0x23, 0x93, 0xb3,
+ 0x5f, 0x00, 0x6f, 0x13, 0x72, 0x69, 0x66, 0x0c, 0xf4, 0x3d, 0x29, 0x53,
+ 0x4e, 0x1e, 0x7e, 0x84, 0x7b, 0x21, 0xc4, 0x79, 0xdd, 0xfe, 0xf7, 0x84,
+ 0x7e, 0xce, 0xb6, 0x88, 0x33, 0xa5, 0x52, 0xa4, 0x0f, 0xe6, 0xbe, 0x14,
+ 0xf7, 0x1f, 0x69, 0x3f, 0xac, 0xc3, 0x20, 0xd7, 0x65, 0xce, 0x3b, 0xcd,
+ 0xf9, 0x37, 0xea, 0x64, 0xb5, 0x4a, 0xbc, 0xe6, 0x66, 0x56, 0x96, 0x89,
+ 0x37, 0x3f, 0x28, 0xf6, 0xa4, 0x1e, 0x88, 0x3f, 0x6f, 0x05, 0x77, 0x5a,
+ 0x33, 0xc0, 0x9c, 0x2f, 0xac, 0xe8, 0x8d, 0xb8, 0xd3, 0xc3, 0x9c, 0xc9,
+ 0xe5, 0x2c, 0xc6, 0x74, 0x14, 0xb6, 0x46, 0xde, 0x07, 0xb7, 0xd7, 0x8d,
+ 0x67, 0xbb, 0x91, 0xc3, 0x7b, 0x18, 0x33, 0x05, 0x8c, 0xf9, 0x0f, 0x81,
+ 0x31, 0x27, 0xe5, 0xad, 0x56, 0x62, 0x4c, 0xd7, 0xc7, 0x98, 0x69, 0xd8,
+ 0x73, 0x6e, 0x83, 0x3d, 0x6b, 0xaa, 0x76, 0xc5, 0x7b, 0x39, 0x60, 0xc4,
+ 0xd4, 0xb4, 0x75, 0x0b, 0xb8, 0x52, 0x93, 0x88, 0x3a, 0xfb, 0x10, 0x6a,
+ 0x18, 0x33, 0xc0, 0x8f, 0x7b, 0x14, 0x2e, 0x3c, 0x50, 0xda, 0x82, 0x1c,
+ 0x46, 0xe1, 0x44, 0x7f, 0x4f, 0x2e, 0xb4, 0x69, 0x9f, 0x32, 0xd4, 0xb0,
+ 0x4f, 0x79, 0x1d, 0x4f, 0xe2, 0x39, 0xbf, 0x3e, 0xd8, 0x04, 0x5f, 0xf0,
+ 0x7f, 0x40, 0x13, 0xd7, 0x17, 0xd7, 0x82, 0xe6, 0xad, 0x97, 0xd1, 0x46,
+ 0x5c, 0xf9, 0xbf, 0x36, 0xe1, 0x4a, 0xc4, 0xae, 0xf3, 0x11, 0x49, 0x02,
+ 0x53, 0xba, 0xcb, 0x1c, 0x8b, 0x6b, 0xba, 0x5f, 0x9a, 0xc1, 0x5f, 0xcb,
+ 0x74, 0x27, 0xb0, 0x54, 0x9b, 0x84, 0x81, 0xa9, 0x9a, 0x14, 0xa6, 0xea,
+ 0x21, 0xf6, 0xe9, 0x3d, 0x02, 0x2c, 0xb4, 0xb8, 0x8e, 0xab, 0x2c, 0xe7,
+ 0x87, 0xd0, 0xcb, 0xa3, 0xca, 0xf7, 0xa4, 0xe5, 0x29, 0xf8, 0xd2, 0xe6,
+ 0x65, 0xe0, 0xc1, 0xf3, 0x1e, 0xde, 0x6a, 0xda, 0x84, 0xb7, 0x8e, 0xde,
+ 0x10, 0x6f, 0xa9, 0x9a, 0xff, 0x20, 0x65, 0xf2, 0x7a, 0xd5, 0xab, 0xf9,
+ 0x5f, 0xa9, 0x7a, 0x35, 0xff, 0xd7, 0xab, 0x8d, 0x35, 0xff, 0x8f, 0x48,
+ 0xc1, 0xb4, 0xdc, 0x35, 0xd9, 0x54, 0xf3, 0x1f, 0x65, 0x0d, 0xfd, 0xf7,
+ 0xda, 0xbc, 0xda, 0x7e, 0x9b, 0x5f, 0xf3, 0xb7, 0xa4, 0xb0, 0xa1, 0xdd,
+ 0x94, 0xb7, 0xec, 0xa0, 0xe6, 0xff, 0x34, 0xda, 0xda, 0x31, 0xc7, 0xc6,
+ 0x7a, 0xff, 0x95, 0x2a, 0xeb, 0xfd, 0x11, 0xf6, 0xf3, 0xeb, 0xfd, 0xec,
+ 0x87, 0xdc, 0xbf, 0xca, 0x5a, 0xff, 0x6e, 0xc8, 0x62, 0x27, 0xe4, 0xd0,
+ 0x29, 0xcd, 0x67, 0xa3, 0xec, 0xa3, 0x6a, 0xfc, 0x6b, 0xc8, 0x37, 0xae,
+ 0x54, 0xbd, 0x5a, 0xfc, 0x11, 0xd8, 0xd5, 0xd1, 0xf5, 0x1a, 0xbf, 0x37,
+ 0xc7, 0xd5, 0xea, 0xc6, 0xf1, 0x37, 0x8e, 0xd3, 0xe5, 0x8f, 0x13, 0xc1,
+ 0x38, 0xd1, 0x4d, 0xe3, 0x5c, 0xaf, 0xe9, 0x5f, 0xad, 0x7a, 0xf5, 0xfc,
+ 0xf4, 0xac, 0xb8, 0xcd, 0xf0, 0xcd, 0x2f, 0xf6, 0xec, 0xf2, 0xc7, 0x58,
+ 0xaf, 0xe7, 0xd3, 0x87, 0x00, 0xe7, 0xc7, 0xd5, 0xf9, 0x9e, 0x23, 0xff,
+ 0x1f, 0xea, 0xf9, 0xac, 0xe5, 0x7b, 0x7b, 0x32, 0x5c, 0x9f, 0xc0, 0xf3,
+ 0xcf, 0x7a, 0x75, 0xfc, 0xa1, 0x52, 0x50, 0x9f, 0x67, 0x5e, 0x19, 0x9c,
+ 0xbd, 0xe9, 0x8e, 0x9d, 0x10, 0xda, 0x0a, 0xe9, 0xe3, 0xb8, 0xed, 0x32,
+ 0xae, 0xf0, 0x14, 0x6c, 0x2a, 0x7e, 0x73, 0x4c, 0xbd, 0x30, 0x1d, 0x60,
+ 0xea, 0x88, 0xc2, 0xd4, 0x0b, 0xcb, 0x01, 0xa6, 0x4e, 0xde, 0x04, 0x53,
+ 0xff, 0xf7, 0x36, 0x2f, 0x0e, 0x84, 0x25, 0xaf, 0x30, 0xf5, 0xcd, 0xce,
+ 0x2b, 0xf1, 0x5e, 0x1b, 0xf1, 0x82, 0x78, 0x7b, 0xd8, 0x9d, 0x37, 0x59,
+ 0x6b, 0x01, 0xce, 0x66, 0xec, 0xdf, 0x29, 0xa3, 0x67, 0xaf, 0xe3, 0x6c,
+ 0x0f, 0x4b, 0x5b, 0xb1, 0x63, 0x2a, 0x26, 0x02, 0xd7, 0xd5, 0x58, 0x2f,
+ 0x27, 0x56, 0x66, 0xcc, 0x09, 0x29, 0x3c, 0x97, 0x2b, 0x32, 0x0f, 0x60,
+ 0x1b, 0xb1, 0x73, 0x2b, 0x8f, 0xf2, 0xf8, 0x31, 0x29, 0xc0, 0xa6, 0xc1,
+ 0xd9, 0x09, 0xee, 0x4b, 0xbc, 0x65, 0x24, 0x6d, 0xb4, 0x57, 0x83, 0x5c,
+ 0xc1, 0x51, 0x67, 0x4e, 0x92, 0xc0, 0x3f, 0xe3, 0xeb, 0xd8, 0x93, 0xbe,
+ 0xe2, 0x47, 0xbf, 0x70, 0x4d, 0xfa, 0xb5, 0x00, 0x5b, 0x22, 0x27, 0x2a,
+ 0x71, 0x6d, 0x07, 0xd8, 0xd2, 0xc3, 0x95, 0xa9, 0xea, 0x0a, 0xf0, 0x75,
+ 0x48, 0x86, 0x80, 0xeb, 0x57, 0x1e, 0x66, 0xcd, 0x2a, 0xc0, 0x4e, 0x2e,
+ 0xbe, 0x1b, 0x6b, 0x58, 0xbc, 0x6e, 0x56, 0x7b, 0x87, 0x17, 0x7b, 0xc2,
+ 0x0d, 0xed, 0xbf, 0x05, 0xff, 0x8d, 0xfc, 0x08, 0x98, 0xc5, 0xc3, 0x4c,
+ 0x7b, 0xa1, 0x83, 0x01, 0x85, 0x99, 0xa6, 0xde, 0x83, 0x99, 0x36, 0xc7,
+ 0x28, 0xc6, 0xcc, 0xeb, 0x31, 0x2a, 0x5d, 0xa3, 0x3f, 0xbf, 0x1e, 0xa3,
+ 0x6e, 0x1e, 0x43, 0xd9, 0x06, 0xee, 0xec, 0x0c, 0x3e, 0x13, 0x52, 0xd8,
+ 0x14, 0xa3, 0xa6, 0x3e, 0x44, 0x8c, 0x1a, 0x56, 0x31, 0xca, 0xa3, 0xfb,
+ 0xfb, 0x90, 0xcd, 0x77, 0x21, 0xd3, 0xef, 0x00, 0x8b, 0x7d, 0x1b, 0x7c,
+ 0x7d, 0x0b, 0x38, 0xe9, 0x9b, 0xa5, 0xcd, 0x67, 0x0e, 0x06, 0x85, 0xf9,
+ 0xa1, 0x87, 0xa5, 0xbc, 0x1a, 0xc0, 0x11, 0xac, 0xae, 0xc5, 0xa2, 0x9b,
+ 0x19, 0x2f, 0xf6, 0x99, 0x13, 0xde, 0xde, 0x6b, 0x2c, 0x2b, 0x8f, 0xb5,
+ 0xa6, 0xe6, 0x19, 0x33, 0xd4, 0x75, 0x94, 0xf5, 0x4e, 0x62, 0x87, 0x8a,
+ 0xca, 0x33, 0x7b, 0xa4, 0xbc, 0xe8, 0xe1, 0xb0, 0xa9, 0x79, 0x6f, 0x8c,
+ 0x71, 0x1f, 0x87, 0xe5, 0x7c, 0x1c, 0x96, 0x5d, 0x5c, 0x8d, 0x85, 0xd0,
+ 0x7f, 0xca, 0xd9, 0x88, 0xbd, 0x8e, 0xf8, 0xd8, 0x6b, 0xe2, 0x43, 0x61,
+ 0x2f, 0x6f, 0xae, 0x1c, 0x9e, 0x19, 0x9e, 0x89, 0xc9, 0x7e, 0xc8, 0x79,
+ 0xa8, 0x48, 0x7d, 0xf1, 0x9c, 0xd2, 0x2f, 0xd3, 0x19, 0xf5, 0xe5, 0xe9,
+ 0x2a, 0x14, 0x3f, 0xa8, 0x0d, 0x43, 0x57, 0x43, 0xbf, 0x54, 0x57, 0x62,
+ 0xbe, 0x39, 0x10, 0xc6, 0xe7, 0x6f, 0x4b, 0x57, 0xe4, 0x83, 0xfa, 0xda,
+ 0x8c, 0xc5, 0x6e, 0x05, 0x93, 0x6d, 0xc4, 0x63, 0xae, 0xc2, 0x63, 0xcd,
+ 0x7e, 0x9f, 0xfc, 0x81, 0x61, 0xe8, 0xf2, 0x3f, 0xa0, 0xcf, 0x8f, 0xed,
+ 0x76, 0xf9, 0x11, 0xfc, 0xf7, 0xbf, 0x87, 0x4e, 0xfe, 0x1d, 0x72, 0x85,
+ 0x57, 0xec, 0x2e, 0xf9, 0x21, 0xda, 0xae, 0xe3, 0x1c, 0xf6, 0x9f, 0x72,
+ 0x92, 0xf6, 0x28, 0xf0, 0xc9, 0xa8, 0x8f, 0x4f, 0xde, 0x7a, 0x20, 0x69,
+ 0x8f, 0xb1, 0xce, 0x0e, 0x39, 0xff, 0x34, 0x39, 0xae, 0xb0, 0x49, 0x80,
+ 0x49, 0x1e, 0x4f, 0x73, 0xfe, 0xc9, 0x6a, 0x16, 0xd8, 0x27, 0xeb, 0x63,
+ 0x9f, 0x9f, 0xa6, 0x3d, 0xec, 0x33, 0xf5, 0xf7, 0xa8, 0x7f, 0x0f, 0xf7,
+ 0x1c, 0x76, 0x93, 0x98, 0x07, 0xb8, 0x07, 0xd7, 0x87, 0x25, 0x5f, 0x1b,
+ 0x51, 0x9f, 0x13, 0x25, 0xd7, 0x6a, 0x82, 0x9c, 0x58, 0xab, 0x3d, 0xc3,
+ 0x55, 0x59, 0xb5, 0xcc, 0x22, 0xbe, 0xb3, 0x55, 0x2b, 0xfa, 0x7b, 0xfe,
+ 0xf5, 0xd3, 0xfe, 0xf5, 0x53, 0xfe, 0xf5, 0x69, 0xc4, 0xe1, 0x53, 0x2a,
+ 0x96, 0xb2, 0x9d, 0x6d, 0x50, 0x72, 0x15, 0x63, 0x01, 0x7b, 0x9c, 0xeb,
+ 0xff, 0xf3, 0x7a, 0x59, 0xe9, 0x98, 0xe3, 0x8f, 0xe2, 0x73, 0x1a, 0x9f,
+ 0x09, 0x7c, 0x0e, 0xe1, 0x93, 0xc7, 0x67, 0x5d, 0xa6, 0x5a, 0xaa, 0x34,
+ 0x06, 0x1b, 0xe9, 0x95, 0x54, 0xed, 0x39, 0xe8, 0xf1, 0x49, 0xe8, 0xf6,
+ 0xb8, 0x14, 0x2a, 0x7f, 0x22, 0x93, 0x33, 0x9a, 0xb4, 0xd9, 0xd0, 0x69,
+ 0x05, 0xb6, 0x3c, 0xe3, 0xed, 0x41, 0xb6, 0x26, 0x46, 0xd0, 0xb7, 0x2e,
+ 0x8f, 0x3a, 0x4f, 0x8a, 0x7e, 0xdf, 0x14, 0xfa, 0x89, 0x5e, 0xe8, 0xbf,
+ 0x5b, 0xed, 0xbf, 0x55, 0x1c, 0x4f, 0xc6, 0xfb, 0x6d, 0xd7, 0x82, 0xce,
+ 0x7b, 0x4f, 0x61, 0xec, 0xa4, 0x3a, 0x7f, 0x99, 0x91, 0x93, 0xb3, 0xab,
+ 0xdb, 0x3d, 0xdf, 0x6a, 0x99, 0x57, 0xa9, 0x77, 0xf0, 0xe1, 0xc2, 0x17,
+ 0x66, 0x60, 0xef, 0x47, 0xab, 0x21, 0x6d, 0x08, 0xf1, 0x66, 0xa8, 0x7a,
+ 0x55, 0xc5, 0x9b, 0x54, 0xd5, 0xcd, 0xc4, 0xcf, 0x44, 0x70, 0xcd, 0x73,
+ 0x31, 0x88, 0x8b, 0xea, 0xfc, 0xde, 0x2a, 0xf0, 0x8d, 0xa6, 0xea, 0x86,
+ 0x93, 0xeb, 0xfb, 0x4a, 0xea, 0x7c, 0x71, 0x26, 0x1e, 0xd7, 0x25, 0x37,
+ 0x40, 0x9c, 0x3b, 0xa2, 0x62, 0x13, 0xd6, 0xea, 0xed, 0xcc, 0x15, 0x5f,
+ 0xe7, 0xbb, 0x00, 0xf6, 0x27, 0xd0, 0xaf, 0x0b, 0xfe, 0x18, 0xf7, 0x6a,
+ 0xb4, 0x4f, 0xf2, 0xca, 0x67, 0x26, 0xa4, 0x52, 0x1e, 0x04, 0xbf, 0x7e,
+ 0x8e, 0xa4, 0x72, 0x89, 0x18, 0xec, 0x31, 0xd8, 0xc3, 0xf2, 0xea, 0x2a,
+ 0x95, 0x6a, 0x80, 0x29, 0xda, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xed,
+ 0xbf, 0xa9, 0xbd, 0xb7, 0x42, 0x75, 0x10, 0x72, 0x4a, 0xa2, 0x9d, 0xb5,
+ 0x6d, 0xfc, 0x2e, 0xeb, 0xaa, 0x26, 0xb0, 0x66, 0x1c, 0x91, 0xc5, 0x72,
+ 0x1d, 0xf4, 0x22, 0xe6, 0x6e, 0x3f, 0x22, 0x0b, 0xe5, 0x09, 0x79, 0xa1,
+ 0xfc, 0xcd, 0x76, 0x60, 0x2a, 0xc8, 0x94, 0xf4, 0xb7, 0xcb, 0xf5, 0x33,
+ 0x9e, 0x41, 0x3b, 0xe4, 0x39, 0x9b, 0x8f, 0x7a, 0x79, 0x6e, 0x5e, 0xd5,
+ 0x68, 0xbc, 0x6f, 0x57, 0x1f, 0xb7, 0xad, 0xe8, 0x24, 0x7a, 0x1e, 0x9d,
+ 0x53, 0xb6, 0x39, 0x3c, 0x65, 0xef, 0x95, 0xcb, 0xce, 0x36, 0x59, 0x75,
+ 0x54, 0x5e, 0x4c, 0xfc, 0x80, 0xb5, 0x6e, 0x99, 0x2b, 0xf2, 0xa0, 0x9c,
+ 0xc4, 0xba, 0xbd, 0xec, 0x3c, 0x06, 0x3b, 0x7d, 0x02, 0xb6, 0xc0, 0x1a,
+ 0xc0, 0x31, 0xe6, 0x5a, 0xb2, 0xa2, 0x6a, 0x68, 0xf5, 0xfa, 0xb0, 0x3a,
+ 0x27, 0xdc, 0x2c, 0xab, 0x0a, 0x8b, 0x79, 0xb5, 0xf6, 0xd5, 0x31, 0x6f,
+ 0x8d, 0x18, 0xca, 0xee, 0xbf, 0x01, 0x7a, 0x8a, 0xb0, 0xdd, 0x26, 0xd5,
+ 0xc7, 0x48, 0xb4, 0xf8, 0x7d, 0x14, 0x06, 0x6d, 0xe8, 0x63, 0x27, 0x92,
+ 0xf6, 0x6b, 0xfb, 0x92, 0xf6, 0xc4, 0x81, 0x5c, 0xd5, 0xf3, 0x99, 0xae,
+ 0xb6, 0xb6, 0x5e, 0xff, 0xc9, 0x60, 0x5d, 0xbd, 0xbc, 0x8e, 0xa1, 0x61,
+ 0xa4, 0xcf, 0x5f, 0x82, 0x7e, 0x43, 0xd2, 0x7c, 0xa6, 0xfe, 0x89, 0x71,
+ 0xa7, 0x2f, 0x76, 0x54, 0x78, 0x32, 0x8b, 0x79, 0xb5, 0xe5, 0x64, 0xe5,
+ 0x12, 0xe2, 0xe4, 0x35, 0x62, 0x87, 0xde, 0x8b, 0x72, 0xed, 0x13, 0x49,
+ 0x67, 0x50, 0x5b, 0x18, 0x43, 0xd6, 0xf2, 0xfc, 0x18, 0xe3, 0xec, 0x31,
+ 0x11, 0xe0, 0xcb, 0x33, 0x03, 0x92, 0x2e, 0xaa, 0x77, 0x21, 0x78, 0x96,
+ 0x53, 0x9b, 0x80, 0xfc, 0xf0, 0xfc, 0x28, 0x03, 0xa3, 0x6e, 0x77, 0xc7,
+ 0xd2, 0xf2, 0x18, 0x6b, 0x63, 0x92, 0x9b, 0x93, 0x3d, 0x49, 0xf8, 0x55,
+ 0x77, 0xb4, 0x59, 0x26, 0x16, 0xdd, 0x4c, 0xf7, 0xf4, 0x13, 0x18, 0x63,
+ 0x1c, 0x63, 0x8d, 0x20, 0x37, 0xc9, 0x22, 0x56, 0x53, 0xbe, 0xf4, 0xdd,
+ 0x8f, 0x43, 0x46, 0x1f, 0xe1, 0x59, 0xd7, 0xc1, 0xac, 0x58, 0xa3, 0x79,
+ 0x35, 0xee, 0xbb, 0x5a, 0xae, 0xff, 0x57, 0x10, 0xeb, 0x42, 0xb2, 0x3f,
+ 0x2e, 0xfa, 0x48, 0x3c, 0xf4, 0x8b, 0x71, 0x9b, 0x6d, 0x61, 0xb6, 0xe9,
+ 0x68, 0x0b, 0xfd, 0x66, 0x3c, 0xac, 0x27, 0xe3, 0xd6, 0x20, 0xcf, 0xe0,
+ 0x1a, 0xf6, 0xb8, 0x18, 0xcf, 0xd7, 0x21, 0x8b, 0x11, 0xe9, 0xb8, 0x60,
+ 0x0d, 0xbe, 0x0e, 0x5a, 0x42, 0xca, 0xd7, 0x8f, 0x8b, 0xee, 0xb7, 0xb7,
+ 0xaf, 0xb7, 0x87, 0xfc, 0xf6, 0x11, 0x69, 0xbb, 0xd0, 0x67, 0xbe, 0x21,
+ 0x47, 0x30, 0xa6, 0x21, 0x57, 0x90, 0xeb, 0xd8, 0x3d, 0xe3, 0xb0, 0xc5,
+ 0x47, 0x48, 0xcb, 0x21, 0xd6, 0x1b, 0x5d, 0xd8, 0x5f, 0x8b, 0x7d, 0x87,
+ 0x7c, 0xde, 0x6c, 0x95, 0x9c, 0xca, 0x75, 0x43, 0xea, 0xbd, 0x85, 0x1c,
+ 0xec, 0xfd, 0xae, 0x9e, 0xa1, 0x0e, 0xaf, 0x5e, 0xc0, 0xfd, 0x91, 0x7e,
+ 0xb4, 0x5d, 0xab, 0x9f, 0xb7, 0xd9, 0xc6, 0x7b, 0xd7, 0xea, 0x15, 0xbb,
+ 0xcf, 0x4c, 0x69, 0x61, 0x7f, 0xff, 0xfc, 0x98, 0xe2, 0x3d, 0x5f, 0xee,
+ 0x36, 0x17, 0xe4, 0x2e, 0x2d, 0xb5, 0x03, 0xf1, 0xa2, 0x9a, 0x42, 0xdf,
+ 0x6b, 0x3c, 0x83, 0xa1, 0xf6, 0x03, 0x16, 0x24, 0xb8, 0xe6, 0x38, 0x7d,
+ 0xe6, 0xb0, 0x7a, 0xb6, 0xcf, 0x3c, 0xa9, 0x35, 0x3e, 0x1b, 0xd5, 0x86,
+ 0x37, 0x3c, 0xdb, 0xa6, 0x64, 0x64, 0xd8, 0x5e, 0x9f, 0xc9, 0xf2, 0x88,
+ 0x3c, 0x5d, 0x65, 0xbf, 0x6b, 0xf5, 0x94, 0xbd, 0x55, 0x3b, 0xb9, 0x83,
+ 0xbe, 0x90, 0x7d, 0xdf, 0xd9, 0x34, 0x0f, 0xaf, 0x6f, 0x36, 0x47, 0x5d,
+ 0x36, 0xce, 0xb1, 0x45, 0xf5, 0xb9, 0xac, 0xfa, 0x84, 0x94, 0xac, 0x37,
+ 0xce, 0xf3, 0x17, 0xb2, 0x71, 0x9e, 0xb6, 0x75, 0x9e, 0x27, 0x31, 0xe6,
+ 0x29, 0xf4, 0x2d, 0x56, 0xbb, 0xa3, 0x15, 0x79, 0xa7, 0x9e, 0xb3, 0xdf,
+ 0x92, 0xcb, 0xeb, 0x63, 0xff, 0x25, 0xae, 0x1b, 0x69, 0xfa, 0x4b, 0x9f,
+ 0x46, 0xfe, 0x66, 0xdb, 0x3f, 0x53, 0xf2, 0xde, 0x6a, 0x77, 0x1f, 0x5a,
+ 0xd0, 0xac, 0xc1, 0x9f, 0x09, 0x75, 0xf5, 0x3b, 0xca, 0xd7, 0xdc, 0x0d,
+ 0x3d, 0xed, 0x79, 0x06, 0x6b, 0xb7, 0x3f, 0xa9, 0xfa, 0x5c, 0xb1, 0x47,
+ 0x64, 0xcf, 0x99, 0x6e, 0xf3, 0x8a, 0xdc, 0x2f, 0xe9, 0x08, 0xaf, 0x91,
+ 0x43, 0xd9, 0x7c, 0xf7, 0xe1, 0x57, 0x99, 0x17, 0x40, 0x97, 0xdd, 0xbd,
+ 0x3f, 0x93, 0x27, 0xe4, 0x64, 0x69, 0x0a, 0xbe, 0x67, 0x5c, 0x7a, 0x9f,
+ 0xa1, 0xff, 0xc9, 0x9b, 0x5e, 0xad, 0xc6, 0x8b, 0x89, 0x29, 0x3f, 0x26,
+ 0x4e, 0x29, 0x3f, 0xf7, 0x8a, 0x7f, 0x8e, 0xa2, 0xbb, 0xf7, 0x3c, 0x9e,
+ 0x7d, 0x41, 0xf9, 0x80, 0x6f, 0x48, 0x05, 0x6b, 0x21, 0xf6, 0xfc, 0x36,
+ 0xd9, 0xfa, 0x10, 0x6d, 0x12, 0x19, 0xc0, 0xdd, 0x4d, 0xea, 0x5d, 0x0b,
+ 0xdd, 0x6e, 0x11, 0xd9, 0x4e, 0xfb, 0x59, 0xd8, 0x2a, 0x6d, 0xe3, 0xde,
+ 0x5e, 0xd9, 0x86, 0x6b, 0x6b, 0x74, 0x4d, 0xca, 0x5b, 0x69, 0x87, 0x1f,
+ 0xbd, 0xe0, 0x7d, 0xf7, 0x5f, 0x40, 0xba, 0x1c, 0x1f, 0x91, 0x7b, 0x2f,
+ 0x78, 0x76, 0x37, 0x39, 0xf3, 0x84, 0x92, 0xef, 0xb8, 0x92, 0x6f, 0x5d,
+ 0x8e, 0x38, 0x94, 0x3d, 0x79, 0xe2, 0xb9, 0x4a, 0x4f, 0x26, 0x9f, 0xf4,
+ 0xed, 0xa8, 0xfb, 0x19, 0xbe, 0x23, 0x46, 0x19, 0x91, 0xee, 0x74, 0x07,
+ 0xf7, 0x6f, 0xf7, 0x5c, 0x20, 0xbf, 0x5d, 0x1b, 0xf8, 0x7d, 0x0a, 0x3e,
+ 0xb6, 0xa7, 0xc7, 0xe3, 0xf9, 0x95, 0x99, 0x0f, 0xce, 0xf3, 0xd7, 0xd6,
+ 0x79, 0x36, 0xa4, 0xa2, 0xf2, 0xdc, 0xd0, 0x36, 0x69, 0xcb, 0xc9, 0x0a,
+ 0xec, 0xe3, 0xcf, 0x84, 0xe7, 0x92, 0x49, 0x8b, 0x37, 0xef, 0x6a, 0x95,
+ 0x34, 0x05, 0x3c, 0x90, 0xae, 0xa4, 0xaf, 0x3f, 0xd2, 0xf1, 0xc4, 0x0d,
+ 0xef, 0x5d, 0x11, 0x37, 0xd3, 0x8b, 0x36, 0x5d, 0xe9, 0x70, 0xc8, 0x5f,
+ 0x6f, 0x23, 0xa2, 0x2b, 0x1d, 0x26, 0xd7, 0x75, 0xf8, 0x3a, 0x74, 0x58,
+ 0x91, 0x8f, 0x83, 0x27, 0xac, 0xef, 0x67, 0xfa, 0xcc, 0x23, 0xb2, 0x53,
+ 0xe9, 0xdf, 0xee, 0x81, 0x4f, 0xf5, 0x75, 0xd9, 0x7c, 0x0b, 0xba, 0x7c,
+ 0x43, 0x94, 0x3e, 0xd5, 0xd9, 0xa3, 0x8a, 0x1a, 0x87, 0xbe, 0x8d, 0xbc,
+ 0x35, 0x2b, 0x9f, 0x40, 0x1a, 0xd5, 0x59, 0x82, 0x51, 0x4f, 0xbf, 0x6a,
+ 0xcd, 0xfb, 0xfa, 0xcd, 0x8e, 0x52, 0x87, 0xd1, 0x0e, 0x4f, 0x9f, 0x2d,
+ 0xaa, 0xcf, 0x74, 0xfc, 0x36, 0xb5, 0xde, 0xed, 0x9e, 0x9d, 0x1d, 0xd4,
+ 0xe9, 0xd3, 0x55, 0xef, 0xbb, 0x88, 0x38, 0x37, 0x5d, 0xfd, 0x65, 0x7a,
+ 0xf5, 0x74, 0x3a, 0x24, 0xde, 0xba, 0xda, 0xac, 0x4f, 0xfd, 0x42, 0x48,
+ 0xd9, 0xf0, 0x10, 0x64, 0x78, 0xba, 0xb4, 0xc3, 0xb7, 0x7b, 0x8f, 0xe7,
+ 0x9e, 0x0f, 0xc8, 0xf3, 0x89, 0x62, 0xb7, 0xf9, 0x16, 0xee, 0x0d, 0x83,
+ 0xe7, 0x23, 0xd2, 0x24, 0x29, 0x9f, 0xe7, 0xd8, 0x3a, 0xcf, 0x01, 0x8d,
+ 0x5e, 0xbf, 0x14, 0xf3, 0xd8, 0x2a, 0xfd, 0xd7, 0xef, 0xaa, 0x77, 0x1a,
+ 0xae, 0x16, 0xe9, 0xb7, 0x81, 0x95, 0x22, 0x9d, 0x72, 0x65, 0x31, 0x26,
+ 0x57, 0x88, 0x41, 0x06, 0xf0, 0x5d, 0x9d, 0xf2, 0x63, 0x78, 0x58, 0xde,
+ 0x28, 0xde, 0x88, 0x8e, 0x7e, 0x79, 0xbd, 0x18, 0xd0, 0x42, 0x2c, 0xcc,
+ 0x7c, 0x61, 0x5c, 0xde, 0x9c, 0xe9, 0x96, 0x95, 0x51, 0xc4, 0xfd, 0x1e,
+ 0xca, 0xa4, 0xcf, 0x7c, 0x50, 0xbd, 0xeb, 0x72, 0xad, 0x7e, 0xd1, 0xc6,
+ 0xf8, 0x73, 0x75, 0x39, 0xca, 0xfd, 0x6f, 0xfe, 0x5e, 0xbc, 0x5d, 0x56,
+ 0x98, 0x53, 0xf4, 0x74, 0xca, 0xc2, 0x1c, 0xf2, 0xf9, 0x22, 0xc7, 0xa7,
+ 0xdc, 0x46, 0xd4, 0xef, 0x61, 0xcc, 0xf7, 0x49, 0x9e, 0x41, 0x8f, 0x50,
+ 0x37, 0xd7, 0xea, 0xab, 0x36, 0xf7, 0x3f, 0xc7, 0x65, 0x11, 0xfa, 0xfb,
+ 0x47, 0x71, 0xee, 0xcf, 0xe7, 0xd4, 0xfb, 0x85, 0x0b, 0x8b, 0xa3, 0xc8,
+ 0x1d, 0xae, 0xd5, 0xa7, 0xec, 0x29, 0xa5, 0xb7, 0xc5, 0xf2, 0x43, 0x7e,
+ 0x3b, 0xaf, 0x79, 0xcf, 0xcd, 0xec, 0xe9, 0x61, 0xbe, 0xfa, 0x10, 0xf2,
+ 0x05, 0xe6, 0xaa, 0xa3, 0xc0, 0x6b, 0x94, 0x49, 0x4c, 0x26, 0x8b, 0x1c,
+ 0x4b, 0x22, 0x5b, 0x90, 0xdf, 0xe7, 0x64, 0x18, 0xf4, 0xc4, 0x90, 0xdb,
+ 0x33, 0x3e, 0xdc, 0x25, 0xab, 0x11, 0x2f, 0x0e, 0xf0, 0xac, 0xd8, 0x2a,
+ 0x62, 0xc3, 0xea, 0x7a, 0x6c, 0xd8, 0x89, 0x6b, 0x37, 0xe3, 0xf4, 0xfc,
+ 0x67, 0x8c, 0xcf, 0xba, 0x0d, 0x63, 0xc3, 0x20, 0xfa, 0xb3, 0xad, 0x53,
+ 0x26, 0xe7, 0x90, 0x44, 0x20, 0x67, 0x59, 0x10, 0x9e, 0x01, 0xc9, 0xca,
+ 0xf4, 0x62, 0x77, 0xf4, 0xa2, 0x96, 0x56, 0x67, 0x45, 0xe2, 0x98, 0x73,
+ 0xa1, 0xd8, 0x29, 0x8b, 0x73, 0x12, 0x33, 0x12, 0x8f, 0x48, 0x75, 0xd1,
+ 0xc3, 0xec, 0x53, 0x1a, 0xda, 0xab, 0xae, 0x2c, 0x6e, 0xec, 0x63, 0x1a,
+ 0x89, 0xc3, 0xf2, 0x75, 0xbf, 0x4f, 0x5a, 0xf5, 0x79, 0xb5, 0x83, 0x7b,
+ 0x6c, 0x8b, 0xd5, 0x0e, 0xd0, 0x40, 0xda, 0x76, 0x35, 0xce, 0x1b, 0xbb,
+ 0x3e, 0x2f, 0xe7, 0x44, 0x36, 0xb3, 0xdd, 0xc5, 0xbc, 0x17, 0xf1, 0xcc,
+ 0x23, 0xa0, 0xe3, 0x9a, 0xa1, 0xdb, 0x8f, 0x48, 0x61, 0x71, 0xf3, 0x1c,
+ 0x8d, 0x34, 0xf0, 0x19, 0x8e, 0xcf, 0x79, 0x0e, 0x83, 0xbe, 0x6b, 0x9a,
+ 0x6e, 0x1f, 0x86, 0x2c, 0xbd, 0x39, 0x8c, 0xb3, 0x96, 0xf9, 0x23, 0xe9,
+ 0x11, 0xfd, 0xbc, 0xa6, 0xe4, 0xaf, 0x2f, 0xf4, 0x63, 0x81, 0x64, 0xa4,
+ 0x6d, 0x79, 0x4c, 0x8c, 0x65, 0xd6, 0x10, 0x5e, 0x69, 0x4d, 0xab, 0xfd,
+ 0xde, 0x2d, 0x58, 0xdf, 0xe2, 0x86, 0x6c, 0xd6, 0x0b, 0x58, 0x0f, 0xfe,
+ 0xfa, 0x36, 0xe9, 0x60, 0xbd, 0x80, 0x79, 0xc3, 0x21, 0x7c, 0x33, 0x77,
+ 0x78, 0xb9, 0x9e, 0x74, 0x7e, 0xa6, 0xe2, 0x6b, 0x6e, 0x91, 0xf7, 0xad,
+ 0x98, 0x08, 0xef, 0xd1, 0x6f, 0x74, 0x4a, 0xd3, 0x57, 0x7a, 0xe1, 0x2b,
+ 0x1e, 0x03, 0xf6, 0xc6, 0xb8, 0x67, 0x7a, 0x24, 0xe4, 0x9d, 0xb1, 0x50,
+ 0xf5, 0x96, 0x37, 0xe7, 0x2c, 0xff, 0x9d, 0x21, 0xd9, 0x73, 0xd1, 0x61,
+ 0x4d, 0xb4, 0x8b, 0x35, 0x1f, 0xf4, 0x13, 0x7d, 0x15, 0xf9, 0xe9, 0x95,
+ 0x45, 0x63, 0x1b, 0xcf, 0x7c, 0xbe, 0x5e, 0xc5, 0x35, 0xb1, 0x7f, 0x44,
+ 0x61, 0x4c, 0xff, 0x1e, 0x7f, 0x23, 0x5f, 0x7a, 0xcf, 0xf9, 0x77, 0xe6,
+ 0x53, 0x63, 0xfe, 0x59, 0x3b, 0x37, 0x73, 0x72, 0x43, 0x4e, 0xd5, 0xab,
+ 0xea, 0xbd, 0x2b, 0x55, 0x1b, 0xfe, 0x71, 0x00, 0xf6, 0xc9, 0x35, 0x50,
+ 0xd7, 0x1e, 0x02, 0x36, 0x8b, 0x75, 0xaa, 0x9c, 0xe8, 0xf4, 0x43, 0xe2,
+ 0xd9, 0x3b, 0xac, 0x4c, 0xf9, 0xb2, 0x95, 0xb2, 0x97, 0x83, 0xac, 0x96,
+ 0x33, 0xf2, 0x9f, 0xaa, 0x97, 0x54, 0xad, 0x75, 0x06, 0x79, 0x49, 0x68,
+ 0x5a, 0xe5, 0x64, 0x0d, 0xf8, 0x16, 0x7e, 0xef, 0xd9, 0x2f, 0x62, 0x2d,
+ 0x5a, 0xea, 0x4c, 0x83, 0x7e, 0xbe, 0x5e, 0x4f, 0xc1, 0x7f, 0xe8, 0xb6,
+ 0x6d, 0x16, 0x10, 0x0f, 0x53, 0xea, 0x5c, 0x0c, 0xd7, 0xf1, 0x61, 0xe5,
+ 0x9f, 0x65, 0x01, 0xb2, 0x39, 0x1b, 0xc3, 0x38, 0x9a, 0xb2, 0x4f, 0x43,
+ 0xe9, 0xe1, 0x21, 0x85, 0x79, 0x8d, 0xf3, 0x70, 0x58, 0xcb, 0x3d, 0x22,
+ 0xe7, 0x33, 0x32, 0x85, 0x35, 0x1c, 0x5a, 0xa6, 0x0e, 0x28, 0xdb, 0x31,
+ 0x69, 0x82, 0xec, 0x4f, 0x00, 0x7b, 0x18, 0xd3, 0x94, 0x71, 0x14, 0xeb,
+ 0xa2, 0x53, 0x42, 0x67, 0x21, 0xe3, 0x69, 0x60, 0x84, 0xb9, 0x66, 0x79,
+ 0x69, 0x31, 0x90, 0xe9, 0xcb, 0x3c, 0xef, 0xaf, 0x8f, 0x0f, 0x74, 0x11,
+ 0x47, 0x49, 0x65, 0x71, 0x4a, 0xa6, 0x66, 0x99, 0xb3, 0x8f, 0xa9, 0x33,
+ 0x06, 0x21, 0x75, 0xc6, 0xc5, 0xcb, 0x99, 0xbd, 0x6f, 0x0f, 0x63, 0x56,
+ 0x84, 0x7b, 0x6d, 0x02, 0xdb, 0xe9, 0xc7, 0xbc, 0x37, 0x92, 0xaf, 0x97,
+ 0xab, 0x0e, 0x83, 0xde, 0x8b, 0x33, 0x56, 0x26, 0x2f, 0x0e, 0xcf, 0x5b,
+ 0x8f, 0xba, 0xe0, 0x7f, 0x15, 0xfe, 0x73, 0xaa, 0x74, 0x2f, 0xf8, 0x2c,
+ 0x60, 0x85, 0x65, 0xe4, 0x62, 0x91, 0x39, 0xe3, 0x47, 0xa1, 0x37, 0x5e,
+ 0x17, 0x06, 0x0d, 0xf8, 0x81, 0x35, 0xf5, 0x7e, 0xa1, 0xe5, 0xae, 0x20,
+ 0x87, 0x8d, 0x69, 0x87, 0xa0, 0xeb, 0xbc, 0xd9, 0xe4, 0xdb, 0x03, 0xdf,
+ 0x35, 0x3e, 0x07, 0x3f, 0xba, 0x24, 0x7c, 0xef, 0xe7, 0x9d, 0x3a, 0xf3,
+ 0xa5, 0xcb, 0xf0, 0x7b, 0x99, 0x78, 0x06, 0x36, 0x94, 0x8f, 0xb6, 0x80,
+ 0xe6, 0xdf, 0xc6, 0xbd, 0x5c, 0x95, 0xf3, 0x58, 0xce, 0x9a, 0x14, 0x62,
+ 0x21, 0xe9, 0x8b, 0x5d, 0x92, 0x6d, 0xf0, 0x64, 0x9a, 0xbc, 0x61, 0x5b,
+ 0x83, 0xa2, 0xa9, 0xf1, 0x7a, 0x0f, 0xc0, 0x06, 0xaf, 0xc2, 0xdf, 0x35,
+ 0xfb, 0xb9, 0x7e, 0xaa, 0x48, 0x0c, 0xf5, 0x84, 0x3a, 0x8b, 0x70, 0xd9,
+ 0x66, 0x1d, 0x90, 0xef, 0xfb, 0xfe, 0x95, 0x9a, 0xe3, 0xfa, 0xde, 0x1d,
+ 0xeb, 0xd0, 0xa4, 0xcf, 0xe3, 0x71, 0xbf, 0xed, 0xd1, 0xc8, 0x71, 0x9a,
+ 0x1a, 0xc6, 0xb9, 0xe8, 0x8f, 0x73, 0xce, 0x1f, 0x67, 0xc1, 0x1f, 0xe7,
+ 0xf2, 0xfa, 0x38, 0x0f, 0xc2, 0x0e, 0xea, 0xf5, 0xa7, 0x80, 0x37, 0x92,
+ 0x4e, 0xbd, 0x9e, 0x46, 0x5e, 0x36, 0xd9, 0x3f, 0xa1, 0xf6, 0x5e, 0xf5,
+ 0xc4, 0x8b, 0x43, 0x49, 0xdb, 0x93, 0x3f, 0xac, 0x40, 0x26, 0x60, 0x8f,
+ 0x79, 0xf1, 0xb0, 0x3a, 0xf7, 0x03, 0xbd, 0xfd, 0xc2, 0x36, 0xf8, 0x81,
+ 0xc7, 0x10, 0x4b, 0x9c, 0xe1, 0x25, 0x5b, 0xf2, 0x7b, 0x7e, 0x4d, 0x87,
+ 0xbd, 0x77, 0x20, 0x2e, 0xbd, 0x09, 0xdb, 0x71, 0x86, 0x2b, 0x8b, 0x8f,
+ 0xa9, 0x3d, 0xe1, 0xa6, 0xc4, 0xbd, 0xd0, 0x67, 0x79, 0x78, 0x61, 0xb1,
+ 0x3c, 0x7c, 0x8e, 0xfb, 0x43, 0xe8, 0xb7, 0xb0, 0xd8, 0x0e, 0xb9, 0xb7,
+ 0xab, 0xba, 0xca, 0xa5, 0x62, 0x04, 0x7a, 0x34, 0x61, 0xf3, 0x11, 0xb4,
+ 0x45, 0x61, 0x07, 0x5d, 0x68, 0x7f, 0x0d, 0x6b, 0x3b, 0x86, 0xf6, 0xb5,
+ 0xd6, 0x61, 0x85, 0x63, 0x6d, 0x39, 0x5f, 0xbd, 0x8a, 0x98, 0xfb, 0x16,
+ 0xfc, 0x68, 0x2f, 0xfa, 0xf4, 0xa3, 0xcf, 0x0e, 0x13, 0xf8, 0x2a, 0x53,
+ 0xbe, 0x21, 0x4d, 0x2e, 0x68, 0xd2, 0x1b, 0x68, 0x72, 0x41, 0x0f, 0x7c,
+ 0xe7, 0x19, 0xd6, 0xa0, 0xfb, 0xe5, 0x64, 0x91, 0x67, 0xaa, 0xf8, 0xee,
+ 0xb5, 0x29, 0x21, 0x60, 0xd2, 0xa6, 0x33, 0x56, 0x74, 0x45, 0xd5, 0x7a,
+ 0x68, 0x5b, 0x7d, 0x4e, 0x45, 0x54, 0x9c, 0x89, 0x9d, 0x44, 0xfc, 0xba,
+ 0x5a, 0x6d, 0x97, 0x37, 0xfc, 0xb9, 0xd6, 0x84, 0xfb, 0x97, 0x1b, 0xe7,
+ 0x3a, 0x55, 0x1a, 0x1d, 0xfe, 0x81, 0x6d, 0xf8, 0x7c, 0x75, 0x62, 0xae,
+ 0x76, 0xf4, 0x1d, 0x1d, 0xbe, 0xb8, 0x78, 0xa3, 0xbe, 0x13, 0xe8, 0xdb,
+ 0xd4, 0xd0, 0x77, 0x02, 0xfd, 0xda, 0x11, 0x07, 0xdb, 0x15, 0x4f, 0x93,
+ 0xa0, 0xeb, 0x4a, 0x51, 0xbd, 0x0b, 0x0c, 0xb9, 0x73, 0x4e, 0x93, 0x98,
+ 0x3a, 0xe3, 0xd5, 0x4a, 0x2c, 0x33, 0xa6, 0xbd, 0xa7, 0xde, 0xa3, 0x6c,
+ 0x60, 0xc8, 0x06, 0xee, 0x9d, 0x19, 0xd5, 0x52, 0x95, 0x1c, 0x62, 0xd6,
+ 0x2e, 0xe2, 0x27, 0xc7, 0x45, 0xcc, 0x5c, 0xc0, 0x78, 0x8b, 0xc5, 0x15,
+ 0x9e, 0xc1, 0x86, 0x5d, 0xbc, 0x4d, 0x9c, 0xbd, 0xcb, 0x50, 0x67, 0x1e,
+ 0xd2, 0xaa, 0x66, 0xb7, 0x50, 0x14, 0x33, 0x39, 0xc0, 0x33, 0x0e, 0xf7,
+ 0x63, 0x5d, 0x7e, 0x0e, 0x6d, 0x49, 0xc4, 0xc7, 0xc3, 0x5a, 0x72, 0x69,
+ 0x18, 0xd7, 0x8f, 0xe0, 0x1a, 0xfe, 0x78, 0x2e, 0x8b, 0xfb, 0x8f, 0xe0,
+ 0x7a, 0x42, 0x4b, 0xd5, 0xb2, 0xb8, 0x7e, 0x14, 0xd7, 0x49, 0x93, 0x79,
+ 0xca, 0x0f, 0xec, 0x8c, 0xe6, 0x62, 0x2c, 0x77, 0x69, 0x18, 0x9f, 0xc6,
+ 0xf1, 0x78, 0x0f, 0x7a, 0x2a, 0x72, 0xaf, 0x2d, 0x0e, 0x9a, 0x0e, 0x6a,
+ 0xe9, 0x4a, 0x1b, 0xc6, 0xe8, 0xc1, 0xf3, 0xb4, 0xa9, 0x43, 0xfe, 0xfc,
+ 0xac, 0x39, 0xdd, 0xad, 0x6a, 0x4e, 0x46, 0x22, 0x03, 0x9c, 0x7c, 0x1c,
+ 0x79, 0x80, 0x26, 0x69, 0xfb, 0x49, 0x29, 0x38, 0xf0, 0x2b, 0x15, 0x43,
+ 0x52, 0x91, 0x3c, 0x7e, 0xe7, 0x25, 0x39, 0x88, 0xfb, 0x15, 0xda, 0x02,
+ 0xfb, 0xfd, 0x89, 0x14, 0xca, 0xc4, 0xfd, 0xac, 0x33, 0xb1, 0x36, 0xc5,
+ 0xfa, 0x52, 0x0e, 0x32, 0x88, 0xd0, 0x7e, 0x6f, 0x50, 0x13, 0xf3, 0xce,
+ 0x55, 0x23, 0x2e, 0x6b, 0xc9, 0x0a, 0xf7, 0xfd, 0xdc, 0xcc, 0x45, 0x9b,
+ 0xef, 0x28, 0x4d, 0x70, 0x1f, 0xb1, 0x60, 0x24, 0x58, 0x1f, 0x51, 0xf5,
+ 0x75, 0xc7, 0xdb, 0x1f, 0xe4, 0xb8, 0x63, 0xe0, 0xb7, 0xb1, 0x6e, 0xc5,
+ 0x79, 0xbf, 0x80, 0xe7, 0xbd, 0x7a, 0x56, 0xaa, 0xf6, 0x5e, 0x5d, 0xf0,
+ 0xbd, 0x81, 0xf3, 0xd0, 0xc5, 0x45, 0x95, 0x1b, 0x73, 0x0f, 0xf7, 0xfd,
+ 0x72, 0x2a, 0xe4, 0x30, 0x45, 0xd6, 0xc8, 0x82, 0x7d, 0xbb, 0x40, 0x8e,
+ 0x9b, 0x69, 0x25, 0x9d, 0x47, 0x30, 0xa6, 0x38, 0xf4, 0xbb, 0xd9, 0x08,
+ 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf9, 0x3a, 0xdd, 0xa4, 0x99, 0xf2, 0x38,
+ 0x0e, 0xff, 0xc9, 0x77, 0x32, 0x9e, 0x94, 0x9c, 0xc3, 0x1a, 0x8f, 0x81,
+ 0xd8, 0x98, 0xc7, 0xef, 0xeb, 0xf2, 0x9b, 0xf4, 0xe5, 0x97, 0x2b, 0xbf,
+ 0xa4, 0x74, 0xb8, 0x60, 0x73, 0xbe, 0xa0, 0xf6, 0x31, 0xa2, 0x74, 0xb7,
+ 0xa0, 0xce, 0xfd, 0x06, 0x32, 0x08, 0xea, 0x77, 0x37, 0xb6, 0xbd, 0x61,
+ 0x9b, 0xb4, 0xdd, 0xce, 0xf3, 0x10, 0xbd, 0xae, 0x90, 0x7e, 0xf2, 0xc1,
+ 0x18, 0x16, 0xec, 0xb5, 0x06, 0x3c, 0x04, 0x7c, 0xde, 0xaa, 0x7c, 0x48,
+ 0x6f, 0x64, 0xbb, 0xb4, 0x65, 0x4c, 0xc3, 0x66, 0x6c, 0xf8, 0x84, 0xbf,
+ 0x3f, 0xf0, 0x77, 0x21, 0x67, 0x4f, 0x16, 0xa1, 0x84, 0x4c, 0xfa, 0xef,
+ 0xf8, 0xde, 0xc0, 0x1e, 0x36, 0xef, 0x35, 0xbb, 0x99, 0x73, 0xf6, 0x75,
+ 0xbe, 0x17, 0x6e, 0xc0, 0xf7, 0x82, 0xcf, 0x77, 0xe5, 0x16, 0xe9, 0x5d,
+ 0x98, 0x71, 0xc1, 0x33, 0x6d, 0xee, 0x46, 0xf6, 0x28, 0xea, 0x7f, 0x5f,
+ 0xac, 0x19, 0xe1, 0xb0, 0x5b, 0xbd, 0x59, 0x0d, 0x95, 0x79, 0xb5, 0x67,
+ 0x97, 0xe7, 0x10, 0x0b, 0xcb, 0x65, 0x2f, 0xc7, 0x2e, 0x57, 0x59, 0xcb,
+ 0x7e, 0x3f, 0x1a, 0xf8, 0xfe, 0xd7, 0x67, 0xd4, 0x79, 0x97, 0xc9, 0xaa,
+ 0x57, 0xf7, 0x2a, 0x97, 0x1b, 0x63, 0xea, 0x0e, 0xc6, 0xd3, 0xde, 0xbc,
+ 0x8c, 0xf2, 0xbd, 0x65, 0x5c, 0xef, 0x96, 0x4b, 0x73, 0x6a, 0xcf, 0xca,
+ 0xdf, 0x1b, 0xe2, 0x9e, 0x8f, 0xda, 0xff, 0x86, 0x5f, 0x1b, 0x53, 0x7e,
+ 0x7d, 0x75, 0x4e, 0xdd, 0xf3, 0xb0, 0x52, 0x75, 0x14, 0x7e, 0x1f, 0xb9,
+ 0x84, 0xbd, 0x55, 0x0a, 0xc8, 0xb9, 0xcf, 0xd9, 0x0f, 0x6f, 0x27, 0xce,
+ 0xe1, 0x58, 0xab, 0x18, 0xeb, 0xe2, 0x9c, 0x6c, 0xe7, 0x99, 0x92, 0xb2,
+ 0xda, 0x67, 0xf3, 0xea, 0xe2, 0x13, 0x12, 0xfc, 0x4f, 0x88, 0xb0, 0x1f,
+ 0x0b, 0x79, 0xae, 0x85, 0xef, 0xd2, 0xd2, 0x57, 0x20, 0x0f, 0x1a, 0xe5,
+ 0x3e, 0x4e, 0xbd, 0xee, 0xd5, 0xcd, 0xeb, 0x58, 0x17, 0x4d, 0x7c, 0xef,
+ 0x02, 0x7f, 0xc7, 0x61, 0x3f, 0x58, 0x27, 0xeb, 0xed, 0xbc, 0x66, 0xee,
+ 0x11, 0x5c, 0x33, 0xb0, 0xfd, 0x3f, 0xd4, 0x46, 0x90, 0x7c, 0xb4, 0x45,
+ 0x00, 0x00, 0x00 };
static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010,
@@ -4041,37 +4065,38 @@ static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
- 0x08004060, 0x0800408c, 0x080040d4, 0x080040d4, 0x08003f60, 0x08003f8c,
- 0x08003f8c, 0x080040d4, 0x080040d4, 0x080040d4, 0x08003ff4, 0x00000000,
+ 0x08003fdc, 0x08004008, 0x08004050, 0x08004050, 0x08003edc, 0x08003f08,
+ 0x08003f08, 0x08004050, 0x08004050, 0x08004050, 0x08003f70, 0x00000000,
0x00000000 };
static struct fw_info bnx2_txp_fw_09 = {
+ /* Firmware version: 3.7.1 */
.ver_major = 0x3,
- .ver_minor = 0x4,
- .ver_fix = 0x3,
+ .ver_minor = 0x7,
+ .ver_fix = 0x1,
.start_addr = 0x08000060,
.text_addr = 0x08000000,
- .text_len = 0x4634,
+ .text_len = 0x45b0,
.text_index = 0x0,
.gz_text = bnx2_TXP_b09FwText,
.gz_text_len = sizeof(bnx2_TXP_b09FwText),
- .data_addr = 0x08004680,
+ .data_addr = 0x08004600,
.data_len = 0xd0,
.data_index = 0x0,
.data = bnx2_TXP_b09FwData,
- .sbss_addr = 0x08004750,
+ .sbss_addr = 0x080046d0,
.sbss_len = 0x8c,
.sbss_index = 0x0,
- .bss_addr = 0x080047e0,
+ .bss_addr = 0x08004760,
.bss_len = 0xa20,
.bss_index = 0x0,
- .rodata_addr = 0x08004638,
+ .rodata_addr = 0x080045b0,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_TXP_b09FwRodata,
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 64bfec32e2a..6f85cc31f8a 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -98,6 +98,7 @@ static char *xmit_hash_policy = NULL;
static int arp_interval = BOND_LINK_ARP_INTERV;
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
static char *arp_validate = NULL;
+static int fail_over_mac = 0;
struct bond_params bonding_defaults;
module_param(max_bonds, int, 0);
@@ -131,6 +132,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
module_param(arp_validate, charp, 0);
MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
+module_param(fail_over_mac, int, 0);
+MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. 0 of off (default), 1 for on.");
/*----------------------------- Global variables ----------------------------*/
@@ -1096,7 +1099,21 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (new_active) {
bond_set_slave_active_flags(new_active);
}
- bond_send_gratuitous_arp(bond);
+
+ /* when bonding does not set the slave MAC address, the bond MAC
+ * address is the one of the active slave.
+ */
+ if (new_active && bond->params.fail_over_mac)
+ memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
+ new_active->dev->addr_len);
+ if (bond->curr_active_slave &&
+ test_bit(__LINK_STATE_LINKWATCH_PENDING,
+ &bond->curr_active_slave->dev->state)) {
+ dprintk("delaying gratuitous arp on %s\n",
+ bond->curr_active_slave->dev->name);
+ bond->send_grat_arp = 1;
+ } else
+ bond_send_gratuitous_arp(bond);
}
}
@@ -1217,7 +1234,8 @@ static int bond_compute_features(struct bonding *bond)
struct slave *slave;
struct net_device *bond_dev = bond->dev;
unsigned long features = bond_dev->features;
- unsigned short max_hard_header_len = ETH_HLEN;
+ unsigned short max_hard_header_len = max((u16)ETH_HLEN,
+ bond_dev->hard_header_len);
int i;
features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
@@ -1238,6 +1256,24 @@ static int bond_compute_features(struct bonding *bond)
return 0;
}
+
+static void bond_setup_by_slave(struct net_device *bond_dev,
+ struct net_device *slave_dev)
+{
+ struct bonding *bond = bond_dev->priv;
+
+ bond_dev->neigh_setup = slave_dev->neigh_setup;
+ bond_dev->header_ops = slave_dev->header_ops;
+
+ bond_dev->type = slave_dev->type;
+ bond_dev->hard_header_len = slave_dev->hard_header_len;
+ bond_dev->addr_len = slave_dev->addr_len;
+
+ memcpy(bond_dev->broadcast, slave_dev->broadcast,
+ slave_dev->addr_len);
+ bond->setup_by_slave = 1;
+}
+
/* enslave device <slave> to bond device <master> */
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
@@ -1258,8 +1294,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* bond must be initialized by bond_open() before enslaving */
if (!(bond_dev->flags & IFF_UP)) {
- dprintk("Error, master_dev is not up\n");
- return -EPERM;
+ printk(KERN_WARNING DRV_NAME
+ " %s: master_dev is not up in bond_enslave\n",
+ bond_dev->name);
}
/* already enslaved */
@@ -1312,14 +1349,42 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
goto err_undo_flags;
}
+ /* set bonding device ether type by slave - bonding netdevices are
+ * created with ether_setup, so when the slave type is not ARPHRD_ETHER
+ * there is a need to override some of the type dependent attribs/funcs.
+ *
+ * bond ether type mutual exclusion - don't allow slaves of dissimilar
+ * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond
+ */
+ if (bond->slave_cnt == 0) {
+ if (slave_dev->type != ARPHRD_ETHER)
+ bond_setup_by_slave(bond_dev, slave_dev);
+ } else if (bond_dev->type != slave_dev->type) {
+ printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
+ "from other slaves (%d), can not enslave it.\n",
+ slave_dev->name,
+ slave_dev->type, bond_dev->type);
+ res = -EINVAL;
+ goto err_undo_flags;
+ }
+
if (slave_dev->set_mac_address == NULL) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: The slave device you specified does "
- "not support setting the MAC address. "
- "Your kernel likely does not support slave "
- "devices.\n", bond_dev->name);
- res = -EOPNOTSUPP;
- goto err_undo_flags;
+ if (bond->slave_cnt == 0) {
+ printk(KERN_WARNING DRV_NAME
+ ": %s: Warning: The first slave device "
+ "specified does not support setting the MAC "
+ "address. Enabling the fail_over_mac option.",
+ bond_dev->name);
+ bond->params.fail_over_mac = 1;
+ } else if (!bond->params.fail_over_mac) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: Error: The slave device specified "
+ "does not support setting the MAC address, "
+ "but fail_over_mac is not enabled.\n"
+ , bond_dev->name);
+ res = -EOPNOTSUPP;
+ goto err_undo_flags;
+ }
}
new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
@@ -1340,16 +1405,18 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
*/
memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
- /*
- * Set slave to master's mac address. The application already
- * set the master's mac address to that of the first slave
- */
- memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
- addr.sa_family = slave_dev->type;
- res = dev_set_mac_address(slave_dev, &addr);
- if (res) {
- dprintk("Error %d calling set_mac_address\n", res);
- goto err_free;
+ if (!bond->params.fail_over_mac) {
+ /*
+ * Set slave to master's mac address. The application already
+ * set the master's mac address to that of the first slave
+ */
+ memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
+ addr.sa_family = slave_dev->type;
+ res = dev_set_mac_address(slave_dev, &addr);
+ if (res) {
+ dprintk("Error %d calling set_mac_address\n", res);
+ goto err_free;
+ }
}
res = netdev_set_master(slave_dev, bond_dev);
@@ -1574,9 +1641,11 @@ err_close:
dev_close(slave_dev);
err_restore_mac:
- memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
- addr.sa_family = slave_dev->type;
- dev_set_mac_address(slave_dev, &addr);
+ if (!bond->params.fail_over_mac) {
+ memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
+ addr.sa_family = slave_dev->type;
+ dev_set_mac_address(slave_dev, &addr);
+ }
err_free:
kfree(new_slave);
@@ -1749,10 +1818,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
- /* restore original ("permanent") mac address */
- memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
- addr.sa_family = slave_dev->type;
- dev_set_mac_address(slave_dev, &addr);
+ if (!bond->params.fail_over_mac) {
+ /* restore original ("permanent") mac address */
+ memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+ addr.sa_family = slave_dev->type;
+ dev_set_mac_address(slave_dev, &addr);
+ }
slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
IFF_SLAVE_INACTIVE | IFF_BONDING |
@@ -1764,6 +1835,35 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
}
/*
+* Destroy a bonding device.
+* Must be under rtnl_lock when this function is called.
+*/
+void bond_destroy(struct bonding *bond)
+{
+ bond_deinit(bond->dev);
+ bond_destroy_sysfs_entry(bond);
+ unregister_netdevice(bond->dev);
+}
+
+/*
+* First release a slave and than destroy the bond if no more slaves iare left.
+* Must be under rtnl_lock when this function is called.
+*/
+int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
+{
+ struct bonding *bond = bond_dev->priv;
+ int ret;
+
+ ret = bond_release(bond_dev, slave_dev);
+ if ((ret == 0) && (bond->slave_cnt == 0)) {
+ printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
+ bond_dev->name, bond_dev->name);
+ bond_destroy(bond);
+ }
+ return ret;
+}
+
+/*
* This function releases all slaves.
*/
static int bond_release_all(struct net_device *bond_dev)
@@ -1839,10 +1939,12 @@ static int bond_release_all(struct net_device *bond_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
- /* restore original ("permanent") mac address*/
- memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
- addr.sa_family = slave_dev->type;
- dev_set_mac_address(slave_dev, &addr);
+ if (!bond->params.fail_over_mac) {
+ /* restore original ("permanent") mac address*/
+ memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+ addr.sa_family = slave_dev->type;
+ dev_set_mac_address(slave_dev, &addr);
+ }
slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
IFF_SLAVE_INACTIVE);
@@ -2013,6 +2115,17 @@ void bond_mii_monitor(struct net_device *bond_dev)
* program could monitor the link itself if needed.
*/
+ if (bond->send_grat_arp) {
+ if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING,
+ &bond->curr_active_slave->dev->state))
+ dprintk("Needs to send gratuitous arp but not yet\n");
+ else {
+ dprintk("sending delayed gratuitous arp on on %s\n",
+ bond->curr_active_slave->dev->name);
+ bond_send_gratuitous_arp(bond);
+ bond->send_grat_arp = 0;
+ }
+ }
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
@@ -2414,7 +2527,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
- bond->master_ip, 0);
+ bond->master_ip, 0);
}
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
@@ -2951,9 +3064,15 @@ static void bond_info_show_master(struct seq_file *seq)
curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
- seq_printf(seq, "Bonding Mode: %s\n",
+ seq_printf(seq, "Bonding Mode: %s",
bond_mode_name(bond->params.mode));
+ if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
+ bond->params.fail_over_mac)
+ seq_printf(seq, " (fail_over_mac)");
+
+ seq_printf(seq, "\n");
+
if (bond->params.mode == BOND_MODE_XOR ||
bond->params.mode == BOND_MODE_8023AD) {
seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
@@ -3233,7 +3352,10 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
switch (event) {
case NETDEV_UNREGISTER:
if (bond_dev) {
- bond_release(bond_dev, slave_dev);
+ if (bond->setup_by_slave)
+ bond_release_and_destroy(bond_dev, slave_dev);
+ else
+ bond_release(bond_dev, slave_dev);
}
break;
case NETDEV_CHANGE:
@@ -3880,6 +4002,13 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
+ /*
+ * If fail_over_mac is enabled, do nothing and return success.
+ * Returning an error causes ifenslave to fail.
+ */
+ if (bond->params.fail_over_mac)
+ return 0;
+
if (!is_valid_ether_addr(sa->sa_data)) {
return -EADDRNOTAVAIL;
}
@@ -4217,6 +4346,8 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
bond->current_arp_slave = NULL;
bond->primary_slave = NULL;
bond->dev = bond_dev;
+ bond->send_grat_arp = 0;
+ bond->setup_by_slave = 0;
INIT_LIST_HEAD(&bond->vlan_list);
/* Initialize the device entry points */
@@ -4265,7 +4396,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
#ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond);
#endif
-
list_add_tail(&bond->bond_list, &bond_dev_list);
return 0;
@@ -4599,6 +4729,11 @@ static int bond_check_params(struct bond_params *params)
primary = NULL;
}
+ if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP))
+ printk(KERN_WARNING DRV_NAME
+ ": Warning: fail_over_mac only affects "
+ "active-backup mode.\n");
+
/* fill params struct with the proper values */
params->mode = bond_mode;
params->xmit_policy = xmit_hashtype;
@@ -4610,6 +4745,7 @@ static int bond_check_params(struct bond_params *params)
params->use_carrier = use_carrier;
params->lacp_fast = lacp_fast;
params->primary[0] = 0;
+ params->fail_over_mac = fail_over_mac;
if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6f49ca7e9b6..80c0c8c415e 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -164,9 +164,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
printk(KERN_INFO DRV_NAME
": %s is being deleted...\n",
bond->dev->name);
- bond_deinit(bond->dev);
- bond_destroy_sysfs_entry(bond);
- unregister_netdevice(bond->dev);
+ bond_destroy(bond);
rtnl_unlock();
goto out;
}
@@ -260,17 +258,16 @@ static ssize_t bonding_store_slaves(struct device *d,
char command[IFNAMSIZ + 1] = { 0, };
char *ifname;
int i, res, found, ret = count;
+ u32 original_mtu;
struct slave *slave;
struct net_device *dev = NULL;
struct bonding *bond = to_bond(d);
/* Quick sanity check -- is the bond interface up? */
if (!(bond->dev->flags & IFF_UP)) {
- printk(KERN_ERR DRV_NAME
- ": %s: Unable to update slaves because interface is down.\n",
+ printk(KERN_WARNING DRV_NAME
+ ": %s: doing slave updates when interface is down.\n",
bond->dev->name);
- ret = -EPERM;
- goto out;
}
/* Note: We can't hold bond->lock here, as bond_create grabs it. */
@@ -327,6 +324,7 @@ static ssize_t bonding_store_slaves(struct device *d,
}
/* Set the slave's MTU to match the bond */
+ original_mtu = dev->mtu;
if (dev->mtu != bond->dev->mtu) {
if (dev->change_mtu) {
res = dev->change_mtu(dev,
@@ -341,6 +339,9 @@ static ssize_t bonding_store_slaves(struct device *d,
}
rtnl_lock();
res = bond_enslave(bond->dev, dev);
+ bond_for_each_slave(bond, slave, i)
+ if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
+ slave->original_mtu = original_mtu;
rtnl_unlock();
if (res) {
ret = res;
@@ -353,13 +354,17 @@ static ssize_t bonding_store_slaves(struct device *d,
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
dev = slave->dev;
+ original_mtu = slave->original_mtu;
break;
}
if (dev) {
printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
bond->dev->name, dev->name);
rtnl_lock();
- res = bond_release(bond->dev, dev);
+ if (bond->setup_by_slave)
+ res = bond_release_and_destroy(bond->dev, dev);
+ else
+ res = bond_release(bond->dev, dev);
rtnl_unlock();
if (res) {
ret = res;
@@ -367,9 +372,9 @@ static ssize_t bonding_store_slaves(struct device *d,
}
/* set the slave MTU to the default */
if (dev->change_mtu) {
- dev->change_mtu(dev, 1500);
+ dev->change_mtu(dev, original_mtu);
} else {
- dev->mtu = 1500;
+ dev->mtu = original_mtu;
}
}
else {
@@ -563,6 +568,54 @@ static ssize_t bonding_store_arp_validate(struct device *d,
static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
/*
+ * Show and store fail_over_mac. User only allowed to change the
+ * value when there are no slaves.
+ */
+static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1;
+}
+
+static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int new_value;
+ int ret = count;
+ struct bonding *bond = to_bond(d);
+
+ if (bond->slave_cnt != 0) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: Can't alter fail_over_mac with slaves in bond.\n",
+ bond->dev->name);
+ ret = -EPERM;
+ goto out;
+ }
+
+ if (sscanf(buf, "%d", &new_value) != 1) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: no fail_over_mac value specified.\n",
+ bond->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if ((new_value == 0) || (new_value == 1)) {
+ bond->params.fail_over_mac = new_value;
+ printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n",
+ bond->dev->name, new_value);
+ } else {
+ printk(KERN_INFO DRV_NAME
+ ": %s: Ignoring invalid fail_over_mac value %d.\n",
+ bond->dev->name, new_value);
+ }
+out:
+ return ret;
+}
+
+static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
+
+/*
* Show and set the arp timer interval. There are two tricky bits
* here. First, if ARP monitoring is activated, then we must disable
* MII monitoring. Second, if the ARP timer isn't running, we must
@@ -1383,6 +1436,7 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
static struct attribute *per_bond_attrs[] = {
&dev_attr_slaves.attr,
&dev_attr_mode.attr,
+ &dev_attr_fail_over_mac.attr,
&dev_attr_arp_validate.attr,
&dev_attr_arp_interval.attr,
&dev_attr_arp_ip_target.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 2a6af7d2372..b8180600a30 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "3.1.3"
-#define DRV_RELDATE "June 13, 2007"
+#define DRV_VERSION "3.2.1"
+#define DRV_RELDATE "October 15, 2007"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@@ -128,6 +128,7 @@ struct bond_params {
int arp_interval;
int arp_validate;
int use_carrier;
+ int fail_over_mac;
int updelay;
int downdelay;
int lacp_fast;
@@ -156,6 +157,7 @@ struct slave {
s8 link; /* one of BOND_LINK_XXXX */
s8 state; /* one of BOND_STATE_XXXX */
u32 original_flags;
+ u32 original_mtu;
u32 link_failure_count;
u16 speed;
u8 duplex;
@@ -185,6 +187,8 @@ struct bonding {
struct timer_list mii_timer;
struct timer_list arp_timer;
s8 kill_timers;
+ s8 send_grat_arp;
+ s8 setup_by_slave;
struct net_device_stats stats;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
@@ -292,6 +296,8 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_destroy(struct bonding *bond);
+int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
void bond_deinit(struct net_device *bond_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 563bf5f6fa2..7df31b5561c 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4443,7 +4443,7 @@ static struct {
{REG_MAC_COLL_EXCESS},
{REG_MAC_COLL_LATE}
};
-#define CAS_REG_LEN (sizeof(ethtool_register_table)/sizeof(int))
+#define CAS_REG_LEN ARRAY_SIZE(ethtool_register_table)
#define CAS_MAX_REGS (sizeof (u32)*CAS_REG_LEN)
static void cas_read_regs(struct cas *cp, u8 *ptr, int len)
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
new file mode 100644
index 00000000000..ed53aaab4c0
--- /dev/null
+++ b/drivers/net/cpmac.c
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (C) 2006, 2007 Eugene Konev
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <asm/gpio.h>
+
+MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
+MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");
+MODULE_LICENSE("GPL");
+
+static int debug_level = 8;
+static int dumb_switch;
+
+/* Next 2 are only used in cpmac_probe, so it's pointless to change them */
+module_param(debug_level, int, 0444);
+module_param(dumb_switch, int, 0444);
+
+MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
+MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
+
+#define CPMAC_VERSION "0.5.0"
+/* stolen from net/ieee80211.h */
+#ifndef MAC_FMT
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0], ((u8*)(x))[1], ((u8*)(x))[2], \
+ ((u8*)(x))[3], ((u8*)(x))[4], ((u8*)(x))[5]
+#endif
+/* frame size + 802.1q tag */
+#define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4)
+#define CPMAC_QUEUES 8
+
+/* Ethernet registers */
+#define CPMAC_TX_CONTROL 0x0004
+#define CPMAC_TX_TEARDOWN 0x0008
+#define CPMAC_RX_CONTROL 0x0014
+#define CPMAC_RX_TEARDOWN 0x0018
+#define CPMAC_MBP 0x0100
+# define MBP_RXPASSCRC 0x40000000
+# define MBP_RXQOS 0x20000000
+# define MBP_RXNOCHAIN 0x10000000
+# define MBP_RXCMF 0x01000000
+# define MBP_RXSHORT 0x00800000
+# define MBP_RXCEF 0x00400000
+# define MBP_RXPROMISC 0x00200000
+# define MBP_PROMISCCHAN(channel) (((channel) & 0x7) << 16)
+# define MBP_RXBCAST 0x00002000
+# define MBP_BCASTCHAN(channel) (((channel) & 0x7) << 8)
+# define MBP_RXMCAST 0x00000020
+# define MBP_MCASTCHAN(channel) ((channel) & 0x7)
+#define CPMAC_UNICAST_ENABLE 0x0104
+#define CPMAC_UNICAST_CLEAR 0x0108
+#define CPMAC_MAX_LENGTH 0x010c
+#define CPMAC_BUFFER_OFFSET 0x0110
+#define CPMAC_MAC_CONTROL 0x0160
+# define MAC_TXPTYPE 0x00000200
+# define MAC_TXPACE 0x00000040
+# define MAC_MII 0x00000020
+# define MAC_TXFLOW 0x00000010
+# define MAC_RXFLOW 0x00000008
+# define MAC_MTEST 0x00000004
+# define MAC_LOOPBACK 0x00000002
+# define MAC_FDX 0x00000001
+#define CPMAC_MAC_STATUS 0x0164
+# define MAC_STATUS_QOS 0x00000004
+# define MAC_STATUS_RXFLOW 0x00000002
+# define MAC_STATUS_TXFLOW 0x00000001
+#define CPMAC_TX_INT_ENABLE 0x0178
+#define CPMAC_TX_INT_CLEAR 0x017c
+#define CPMAC_MAC_INT_VECTOR 0x0180
+# define MAC_INT_STATUS 0x00080000
+# define MAC_INT_HOST 0x00040000
+# define MAC_INT_RX 0x00020000
+# define MAC_INT_TX 0x00010000
+#define CPMAC_MAC_EOI_VECTOR 0x0184
+#define CPMAC_RX_INT_ENABLE 0x0198
+#define CPMAC_RX_INT_CLEAR 0x019c
+#define CPMAC_MAC_INT_ENABLE 0x01a8
+#define CPMAC_MAC_INT_CLEAR 0x01ac
+#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4)
+#define CPMAC_MAC_ADDR_MID 0x01d0
+#define CPMAC_MAC_ADDR_HI 0x01d4
+#define CPMAC_MAC_HASH_LO 0x01d8
+#define CPMAC_MAC_HASH_HI 0x01dc
+#define CPMAC_TX_PTR(channel) (0x0600 + (channel) * 4)
+#define CPMAC_RX_PTR(channel) (0x0620 + (channel) * 4)
+#define CPMAC_TX_ACK(channel) (0x0640 + (channel) * 4)
+#define CPMAC_RX_ACK(channel) (0x0660 + (channel) * 4)
+#define CPMAC_REG_END 0x0680
+/*
+ * Rx/Tx statistics
+ * TODO: use some of them to fill stats in cpmac_stats()
+ */
+#define CPMAC_STATS_RX_GOOD 0x0200
+#define CPMAC_STATS_RX_BCAST 0x0204
+#define CPMAC_STATS_RX_MCAST 0x0208
+#define CPMAC_STATS_RX_PAUSE 0x020c
+#define CPMAC_STATS_RX_CRC 0x0210
+#define CPMAC_STATS_RX_ALIGN 0x0214
+#define CPMAC_STATS_RX_OVER 0x0218
+#define CPMAC_STATS_RX_JABBER 0x021c
+#define CPMAC_STATS_RX_UNDER 0x0220
+#define CPMAC_STATS_RX_FRAG 0x0224
+#define CPMAC_STATS_RX_FILTER 0x0228
+#define CPMAC_STATS_RX_QOSFILTER 0x022c
+#define CPMAC_STATS_RX_OCTETS 0x0230
+
+#define CPMAC_STATS_TX_GOOD 0x0234
+#define CPMAC_STATS_TX_BCAST 0x0238
+#define CPMAC_STATS_TX_MCAST 0x023c
+#define CPMAC_STATS_TX_PAUSE 0x0240
+#define CPMAC_STATS_TX_DEFER 0x0244
+#define CPMAC_STATS_TX_COLLISION 0x0248
+#define CPMAC_STATS_TX_SINGLECOLL 0x024c
+#define CPMAC_STATS_TX_MULTICOLL 0x0250
+#define CPMAC_STATS_TX_EXCESSCOLL 0x0254
+#define CPMAC_STATS_TX_LATECOLL 0x0258
+#define CPMAC_STATS_TX_UNDERRUN 0x025c
+#define CPMAC_STATS_TX_CARRIERSENSE 0x0260
+#define CPMAC_STATS_TX_OCTETS 0x0264
+
+#define cpmac_read(base, reg) (readl((void __iomem *)(base) + (reg)))
+#define cpmac_write(base, reg, val) (writel(val, (void __iomem *)(base) + \
+ (reg)))
+
+/* MDIO bus */
+#define CPMAC_MDIO_VERSION 0x0000
+#define CPMAC_MDIO_CONTROL 0x0004
+# define MDIOC_IDLE 0x80000000
+# define MDIOC_ENABLE 0x40000000
+# define MDIOC_PREAMBLE 0x00100000
+# define MDIOC_FAULT 0x00080000
+# define MDIOC_FAULTDETECT 0x00040000
+# define MDIOC_INTTEST 0x00020000
+# define MDIOC_CLKDIV(div) ((div) & 0xff)
+#define CPMAC_MDIO_ALIVE 0x0008
+#define CPMAC_MDIO_LINK 0x000c
+#define CPMAC_MDIO_ACCESS(channel) (0x0080 + (channel) * 8)
+# define MDIO_BUSY 0x80000000
+# define MDIO_WRITE 0x40000000
+# define MDIO_REG(reg) (((reg) & 0x1f) << 21)
+# define MDIO_PHY(phy) (((phy) & 0x1f) << 16)
+# define MDIO_DATA(data) ((data) & 0xffff)
+#define CPMAC_MDIO_PHYSEL(channel) (0x0084 + (channel) * 8)
+# define PHYSEL_LINKSEL 0x00000040
+# define PHYSEL_LINKINT 0x00000020
+
+struct cpmac_desc {
+ u32 hw_next;
+ u32 hw_data;
+ u16 buflen;
+ u16 bufflags;
+ u16 datalen;
+ u16 dataflags;
+#define CPMAC_SOP 0x8000
+#define CPMAC_EOP 0x4000
+#define CPMAC_OWN 0x2000
+#define CPMAC_EOQ 0x1000
+ struct sk_buff *skb;
+ struct cpmac_desc *next;
+ dma_addr_t mapping;
+ dma_addr_t data_mapping;
+};
+
+struct cpmac_priv {
+ spinlock_t lock;
+ spinlock_t rx_lock;
+ struct cpmac_desc *rx_head;
+ int ring_size;
+ struct cpmac_desc *desc_ring;
+ dma_addr_t dma_ring;
+ void __iomem *regs;
+ struct mii_bus *mii_bus;
+ struct phy_device *phy;
+ char phy_name[BUS_ID_SIZE];
+ int oldlink, oldspeed, oldduplex;
+ u32 msg_enable;
+ struct net_device *dev;
+ struct work_struct reset_work;
+ struct platform_device *pdev;
+};
+
+static irqreturn_t cpmac_irq(int, void *);
+static void cpmac_hw_start(struct net_device *dev);
+static void cpmac_hw_stop(struct net_device *dev);
+static int cpmac_stop(struct net_device *dev);
+static int cpmac_open(struct net_device *dev);
+
+static void cpmac_dump_regs(struct net_device *dev)
+{
+ int i;
+ struct cpmac_priv *priv = netdev_priv(dev);
+ for (i = 0; i < CPMAC_REG_END; i += 4) {
+ if (i % 16 == 0) {
+ if (i)
+ printk("\n");
+ printk(KERN_DEBUG "%s: reg[%p]:", dev->name,
+ priv->regs + i);
+ }
+ printk(" %08x", cpmac_read(priv->regs, i));
+ }
+ printk("\n");
+}
+
+static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc)
+{
+ int i;
+ printk(KERN_DEBUG "%s: desc[%p]:", dev->name, desc);
+ for (i = 0; i < sizeof(*desc) / 4; i++)
+ printk(" %08x", ((u32 *)desc)[i]);
+ printk("\n");
+}
+
+static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
+{
+ int i;
+ printk(KERN_DEBUG "%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len);
+ for (i = 0; i < skb->len; i++) {
+ if (i % 16 == 0) {
+ if (i)
+ printk("\n");
+ printk(KERN_DEBUG "%s: data[%p]:", dev->name,
+ skb->data + i);
+ }
+ printk(" %02x", ((u8 *)skb->data)[i]);
+ }
+ printk("\n");
+}
+
+static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+ u32 val;
+
+ while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY)
+ cpu_relax();
+ cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_REG(reg) |
+ MDIO_PHY(phy_id));
+ while ((val = cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0))) & MDIO_BUSY)
+ cpu_relax();
+ return MDIO_DATA(val);
+}
+
+static int cpmac_mdio_write(struct mii_bus *bus, int phy_id,
+ int reg, u16 val)
+{
+ while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY)
+ cpu_relax();
+ cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_WRITE |
+ MDIO_REG(reg) | MDIO_PHY(phy_id) | MDIO_DATA(val));
+ return 0;
+}
+
+static int cpmac_mdio_reset(struct mii_bus *bus)
+{
+ ar7_device_reset(AR7_RESET_BIT_MDIO);
+ cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE |
+ MDIOC_CLKDIV(ar7_cpmac_freq() / 2200000 - 1));
+ return 0;
+}
+
+static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, };
+
+static struct mii_bus cpmac_mii = {
+ .name = "cpmac-mii",
+ .read = cpmac_mdio_read,
+ .write = cpmac_mdio_write,
+ .reset = cpmac_mdio_reset,
+ .irq = mii_irqs,
+};
+
+static int cpmac_config(struct net_device *dev, struct ifmap *map)
+{
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ /* Don't allow changing the I/O address */
+ if (map->base_addr != dev->base_addr)
+ return -EOPNOTSUPP;
+
+ /* ignore other fields */
+ return 0;
+}
+
+static void cpmac_set_multicast_list(struct net_device *dev)
+{
+ struct dev_mc_list *iter;
+ int i;
+ u8 tmp;
+ u32 mbp, bit, hash[2] = { 0, };
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ mbp = cpmac_read(priv->regs, CPMAC_MBP);
+ if (dev->flags & IFF_PROMISC) {
+ cpmac_write(priv->regs, CPMAC_MBP, (mbp & ~MBP_PROMISCCHAN(0)) |
+ MBP_RXPROMISC);
+ } else {
+ cpmac_write(priv->regs, CPMAC_MBP, mbp & ~MBP_RXPROMISC);
+ if (dev->flags & IFF_ALLMULTI) {
+ /* enable all multicast mode */
+ cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, 0xffffffff);
+ cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, 0xffffffff);
+ } else {
+ /*
+ * cpmac uses some strange mac address hashing
+ * (not crc32)
+ */
+ for (i = 0, iter = dev->mc_list; i < dev->mc_count;
+ i++, iter = iter->next) {
+ bit = 0;
+ tmp = iter->dmi_addr[0];
+ bit ^= (tmp >> 2) ^ (tmp << 4);
+ tmp = iter->dmi_addr[1];
+ bit ^= (tmp >> 4) ^ (tmp << 2);
+ tmp = iter->dmi_addr[2];
+ bit ^= (tmp >> 6) ^ tmp;
+ tmp = iter->dmi_addr[3];
+ bit ^= (tmp >> 2) ^ (tmp << 4);
+ tmp = iter->dmi_addr[4];
+ bit ^= (tmp >> 4) ^ (tmp << 2);
+ tmp = iter->dmi_addr[5];
+ bit ^= (tmp >> 6) ^ tmp;
+ bit &= 0x3f;
+ hash[bit / 32] |= 1 << (bit % 32);
+ }
+
+ cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, hash[0]);
+ cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, hash[1]);
+ }
+ }
+}
+
+static struct sk_buff *cpmac_rx_one(struct net_device *dev,
+ struct cpmac_priv *priv,
+ struct cpmac_desc *desc)
+{
+ struct sk_buff *skb, *result = NULL;
+
+ if (unlikely(netif_msg_hw(priv)))
+ cpmac_dump_desc(dev, desc);
+ cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping);
+ if (unlikely(!desc->datalen)) {
+ if (netif_msg_rx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING "%s: rx: spurious interrupt\n",
+ dev->name);
+ return NULL;
+ }
+
+ skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+ if (likely(skb)) {
+ skb_reserve(skb, 2);
+ skb_put(desc->skb, desc->datalen);
+ desc->skb->protocol = eth_type_trans(desc->skb, dev);
+ desc->skb->ip_summed = CHECKSUM_NONE;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += desc->datalen;
+ result = desc->skb;
+ dma_unmap_single(&dev->dev, desc->data_mapping, CPMAC_SKB_SIZE,
+ DMA_FROM_DEVICE);
+ desc->skb = skb;
+ desc->data_mapping = dma_map_single(&dev->dev, skb->data,
+ CPMAC_SKB_SIZE,
+ DMA_FROM_DEVICE);
+ desc->hw_data = (u32)desc->data_mapping;
+ if (unlikely(netif_msg_pktdata(priv))) {
+ printk(KERN_DEBUG "%s: received packet:\n", dev->name);
+ cpmac_dump_skb(dev, result);
+ }
+ } else {
+ if (netif_msg_rx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING
+ "%s: low on skbs, dropping packet\n", dev->name);
+ dev->stats.rx_dropped++;
+ }
+
+ desc->buflen = CPMAC_SKB_SIZE;
+ desc->dataflags = CPMAC_OWN;
+
+ return result;
+}
+
+static int cpmac_poll(struct net_device *dev, int *budget)
+{
+ struct sk_buff *skb;
+ struct cpmac_desc *desc;
+ int received = 0, quota = min(dev->quota, *budget);
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ spin_lock(&priv->rx_lock);
+ if (unlikely(!priv->rx_head)) {
+ if (netif_msg_rx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING "%s: rx: polling, but no queue\n",
+ dev->name);
+ netif_rx_complete(dev);
+ return 0;
+ }
+
+ desc = priv->rx_head;
+ while ((received < quota) && ((desc->dataflags & CPMAC_OWN) == 0)) {
+ skb = cpmac_rx_one(dev, priv, desc);
+ if (likely(skb)) {
+ netif_receive_skb(skb);
+ received++;
+ }
+ desc = desc->next;
+ }
+
+ priv->rx_head = desc;
+ spin_unlock(&priv->rx_lock);
+ *budget -= received;
+ dev->quota -= received;
+ if (unlikely(netif_msg_rx_status(priv)))
+ printk(KERN_DEBUG "%s: poll processed %d packets\n", dev->name,
+ received);
+ if (desc->dataflags & CPMAC_OWN) {
+ netif_rx_complete(dev);
+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping);
+ cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
+ return 0;
+ }
+
+ return 1;
+}
+
+static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ int queue, len;
+ struct cpmac_desc *desc;
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ if (unlikely(skb_padto(skb, ETH_ZLEN))) {
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING
+ "%s: tx: padding failed, dropping\n", dev->name);
+ spin_lock(&priv->lock);
+ dev->stats.tx_dropped++;
+ spin_unlock(&priv->lock);
+ return -ENOMEM;
+ }
+
+ len = max(skb->len, ETH_ZLEN);
+ queue = skb->queue_mapping;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ netif_stop_subqueue(dev, queue);
+#else
+ netif_stop_queue(dev);
+#endif
+
+ desc = &priv->desc_ring[queue];
+ if (unlikely(desc->dataflags & CPMAC_OWN)) {
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING "%s: tx dma ring full, dropping\n",
+ dev->name);
+ spin_lock(&priv->lock);
+ dev->stats.tx_dropped++;
+ spin_unlock(&priv->lock);
+ dev_kfree_skb_any(skb);
+ return -ENOMEM;
+ }
+
+ spin_lock(&priv->lock);
+ dev->trans_start = jiffies;
+ spin_unlock(&priv->lock);
+ desc->dataflags = CPMAC_SOP | CPMAC_EOP | CPMAC_OWN;
+ desc->skb = skb;
+ desc->data_mapping = dma_map_single(&dev->dev, skb->data, len,
+ DMA_TO_DEVICE);
+ desc->hw_data = (u32)desc->data_mapping;
+ desc->datalen = len;
+ desc->buflen = len;
+ if (unlikely(netif_msg_tx_queued(priv)))
+ printk(KERN_DEBUG "%s: sending 0x%p, len=%d\n", dev->name, skb,
+ skb->len);
+ if (unlikely(netif_msg_hw(priv)))
+ cpmac_dump_desc(dev, desc);
+ if (unlikely(netif_msg_pktdata(priv)))
+ cpmac_dump_skb(dev, skb);
+ cpmac_write(priv->regs, CPMAC_TX_PTR(queue), (u32)desc->mapping);
+
+ return 0;
+}
+
+static void cpmac_end_xmit(struct net_device *dev, int queue)
+{
+ struct cpmac_desc *desc;
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ desc = &priv->desc_ring[queue];
+ cpmac_write(priv->regs, CPMAC_TX_ACK(queue), (u32)desc->mapping);
+ if (likely(desc->skb)) {
+ spin_lock(&priv->lock);
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += desc->skb->len;
+ spin_unlock(&priv->lock);
+ dma_unmap_single(&dev->dev, desc->data_mapping, desc->skb->len,
+ DMA_TO_DEVICE);
+
+ if (unlikely(netif_msg_tx_done(priv)))
+ printk(KERN_DEBUG "%s: sent 0x%p, len=%d\n", dev->name,
+ desc->skb, desc->skb->len);
+
+ dev_kfree_skb_irq(desc->skb);
+ desc->skb = NULL;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ if (netif_subqueue_stopped(dev, queue))
+ netif_wake_subqueue(dev, queue);
+#else
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+#endif
+ } else {
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING
+ "%s: end_xmit: spurious interrupt\n", dev->name);
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ if (netif_subqueue_stopped(dev, queue))
+ netif_wake_subqueue(dev, queue);
+#else
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+#endif
+ }
+}
+
+static void cpmac_hw_stop(struct net_device *dev)
+{
+ int i;
+ struct cpmac_priv *priv = netdev_priv(dev);
+ struct plat_cpmac_data *pdata = priv->pdev->dev.platform_data;
+
+ ar7_device_reset(pdata->reset_bit);
+ cpmac_write(priv->regs, CPMAC_RX_CONTROL,
+ cpmac_read(priv->regs, CPMAC_RX_CONTROL) & ~1);
+ cpmac_write(priv->regs, CPMAC_TX_CONTROL,
+ cpmac_read(priv->regs, CPMAC_TX_CONTROL) & ~1);
+ for (i = 0; i < 8; i++) {
+ cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0);
+ cpmac_write(priv->regs, CPMAC_RX_PTR(i), 0);
+ }
+ cpmac_write(priv->regs, CPMAC_UNICAST_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_TX_INT_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_MAC_CONTROL,
+ cpmac_read(priv->regs, CPMAC_MAC_CONTROL) & ~MAC_MII);
+}
+
+static void cpmac_hw_start(struct net_device *dev)
+{
+ int i;
+ struct cpmac_priv *priv = netdev_priv(dev);
+ struct plat_cpmac_data *pdata = priv->pdev->dev.platform_data;
+
+ ar7_device_reset(pdata->reset_bit);
+ for (i = 0; i < 8; i++) {
+ cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0);
+ cpmac_write(priv->regs, CPMAC_RX_PTR(i), 0);
+ }
+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), priv->rx_head->mapping);
+
+ cpmac_write(priv->regs, CPMAC_MBP, MBP_RXSHORT | MBP_RXBCAST |
+ MBP_RXMCAST);
+ cpmac_write(priv->regs, CPMAC_BUFFER_OFFSET, 0);
+ for (i = 0; i < 8; i++)
+ cpmac_write(priv->regs, CPMAC_MAC_ADDR_LO(i), dev->dev_addr[5]);
+ cpmac_write(priv->regs, CPMAC_MAC_ADDR_MID, dev->dev_addr[4]);
+ cpmac_write(priv->regs, CPMAC_MAC_ADDR_HI, dev->dev_addr[0] |
+ (dev->dev_addr[1] << 8) | (dev->dev_addr[2] << 16) |
+ (dev->dev_addr[3] << 24));
+ cpmac_write(priv->regs, CPMAC_MAX_LENGTH, CPMAC_SKB_SIZE);
+ cpmac_write(priv->regs, CPMAC_UNICAST_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_TX_INT_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff);
+ cpmac_write(priv->regs, CPMAC_UNICAST_ENABLE, 1);
+ cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
+ cpmac_write(priv->regs, CPMAC_TX_INT_ENABLE, 0xff);
+ cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3);
+
+ cpmac_write(priv->regs, CPMAC_RX_CONTROL,
+ cpmac_read(priv->regs, CPMAC_RX_CONTROL) | 1);
+ cpmac_write(priv->regs, CPMAC_TX_CONTROL,
+ cpmac_read(priv->regs, CPMAC_TX_CONTROL) | 1);
+ cpmac_write(priv->regs, CPMAC_MAC_CONTROL,
+ cpmac_read(priv->regs, CPMAC_MAC_CONTROL) | MAC_MII |
+ MAC_FDX);
+}
+
+static void cpmac_clear_rx(struct net_device *dev)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+ struct cpmac_desc *desc;
+ int i;
+ if (unlikely(!priv->rx_head))
+ return;
+ desc = priv->rx_head;
+ for (i = 0; i < priv->ring_size; i++) {
+ if ((desc->dataflags & CPMAC_OWN) == 0) {
+ if (netif_msg_rx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING "%s: packet dropped\n",
+ dev->name);
+ if (unlikely(netif_msg_hw(priv)))
+ cpmac_dump_desc(dev, desc);
+ desc->dataflags = CPMAC_OWN;
+ dev->stats.rx_dropped++;
+ }
+ desc = desc->next;
+ }
+}
+
+static void cpmac_clear_tx(struct net_device *dev)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+ int i;
+ if (unlikely(!priv->desc_ring))
+ return;
+ for (i = 0; i < CPMAC_QUEUES; i++)
+ if (priv->desc_ring[i].skb) {
+ dev_kfree_skb_any(priv->desc_ring[i].skb);
+ if (netif_subqueue_stopped(dev, i))
+ netif_wake_subqueue(dev, i);
+ }
+}
+
+static void cpmac_hw_error(struct work_struct *work)
+{
+ struct cpmac_priv *priv =
+ container_of(work, struct cpmac_priv, reset_work);
+
+ spin_lock(&priv->rx_lock);
+ cpmac_clear_rx(priv->dev);
+ spin_unlock(&priv->rx_lock);
+ cpmac_clear_tx(priv->dev);
+ cpmac_hw_start(priv->dev);
+ netif_start_queue(priv->dev);
+}
+
+static irqreturn_t cpmac_irq(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct cpmac_priv *priv;
+ int queue;
+ u32 status;
+
+ if (!dev)
+ return IRQ_NONE;
+
+ priv = netdev_priv(dev);
+
+ status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR);
+
+ if (unlikely(netif_msg_intr(priv)))
+ printk(KERN_DEBUG "%s: interrupt status: 0x%08x\n", dev->name,
+ status);
+
+ if (status & MAC_INT_TX)
+ cpmac_end_xmit(dev, (status & 7));
+
+ if (status & MAC_INT_RX) {
+ queue = (status >> 8) & 7;
+ netif_rx_schedule(dev);
+ cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
+ }
+
+ cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0);
+
+ if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) {
+ if (netif_msg_drv(priv) && net_ratelimit())
+ printk(KERN_ERR "%s: hw error, resetting...\n",
+ dev->name);
+ netif_stop_queue(dev);
+ cpmac_hw_stop(dev);
+ schedule_work(&priv->reset_work);
+ if (unlikely(netif_msg_hw(priv)))
+ cpmac_dump_regs(dev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void cpmac_tx_timeout(struct net_device *dev)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+ int i;
+
+ spin_lock(&priv->lock);
+ dev->stats.tx_errors++;
+ spin_unlock(&priv->lock);
+ if (netif_msg_tx_err(priv) && net_ratelimit())
+ printk(KERN_WARNING "%s: transmit timeout\n", dev->name);
+ /*
+ * FIXME: waking up random queue is not the best thing to
+ * do... on the other hand why we got here at all?
+ */
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ for (i = 0; i < CPMAC_QUEUES; i++)
+ if (priv->desc_ring[i].skb) {
+ dev_kfree_skb_any(priv->desc_ring[i].skb);
+ netif_wake_subqueue(dev, i);
+ break;
+ }
+#else
+ if (priv->desc_ring[0].skb)
+ dev_kfree_skb_any(priv->desc_ring[0].skb);
+ netif_wake_queue(dev);
+#endif
+}
+
+static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+ if (!(netif_running(dev)))
+ return -EINVAL;
+ if (!priv->phy)
+ return -EINVAL;
+ if ((cmd == SIOCGMIIPHY) || (cmd == SIOCGMIIREG) ||
+ (cmd == SIOCSMIIREG))
+ return phy_mii_ioctl(priv->phy, if_mii(ifr), cmd);
+
+ return -EOPNOTSUPP;
+}
+
+static int cpmac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ if (priv->phy)
+ return phy_ethtool_gset(priv->phy, cmd);
+
+ return -EINVAL;
+}
+
+static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (priv->phy)
+ return phy_ethtool_sset(priv->phy, cmd);
+
+ return -EINVAL;
+}
+
+static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ ring->rx_max_pending = 1024;
+ ring->rx_mini_max_pending = 1;
+ ring->rx_jumbo_max_pending = 1;
+ ring->tx_max_pending = 1;
+
+ ring->rx_pending = priv->ring_size;
+ ring->rx_mini_pending = 1;
+ ring->rx_jumbo_pending = 1;
+ ring->tx_pending = 1;
+}
+
+static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+
+ if (dev->flags && IFF_UP)
+ return -EBUSY;
+ priv->ring_size = ring->rx_pending;
+ return 0;
+}
+
+static void cpmac_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strcpy(info->driver, "cpmac");
+ strcpy(info->version, CPMAC_VERSION);
+ info->fw_version[0] = '\0';
+ sprintf(info->bus_info, "%s", "cpmac");
+ info->regdump_len = 0;
+}
+
+static const struct ethtool_ops cpmac_ethtool_ops = {
+ .get_settings = cpmac_get_settings,
+ .set_settings = cpmac_set_settings,
+ .get_drvinfo = cpmac_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_ringparam = cpmac_get_ringparam,
+ .set_ringparam = cpmac_set_ringparam,
+};
+
+static void cpmac_adjust_link(struct net_device *dev)
+{
+ struct cpmac_priv *priv = netdev_priv(dev);
+ int new_state = 0;
+
+ spin_lock(&priv->lock);
+ if (priv->phy->link) {
+ netif_start_queue(dev);
+ if (priv->phy->duplex != priv->oldduplex) {
+ new_state = 1;
+ priv->oldduplex = priv->phy->duplex;
+ }
+
+ if (priv->phy->speed != priv->oldspeed) {
+ new_state = 1;
+ priv->oldspeed = priv->phy->speed;
+ }
+
+ if (!priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 1;
+ netif_schedule(dev);
+ }
+ } else if (priv->oldlink) {
+ netif_stop_queue(dev);
+ new_state = 1;
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
+ }
+
+ if (new_state && netif_msg_link(priv) && net_ratelimit())
+ phy_print_status(priv->phy);
+
+ spin_unlock(&priv->lock);
+}
+
+static int cpmac_open(struct net_device *dev)
+{
+ int i, size, res;
+ struct cpmac_priv *priv = netdev_priv(dev);
+ struct resource *mem;
+ struct cpmac_desc *desc;
+ struct sk_buff *skb;
+
+ priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(priv->phy)) {
+ if (netif_msg_drv(priv))
+ printk(KERN_ERR "%s: Could not attach to PHY\n",
+ dev->name);
+ return PTR_ERR(priv->phy);
+ }
+
+ mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
+ if (!request_mem_region(mem->start, mem->end - mem->start, dev->name)) {
+ if (netif_msg_drv(priv))
+ printk(KERN_ERR "%s: failed to request registers\n",
+ dev->name);
+ res = -ENXIO;
+ goto fail_reserve;
+ }
+
+ priv->regs = ioremap(mem->start, mem->end - mem->start);
+ if (!priv->regs) {
+ if (netif_msg_drv(priv))
+ printk(KERN_ERR "%s: failed to remap registers\n",
+ dev->name);
+ res = -ENXIO;
+ goto fail_remap;
+ }
+
+ size = priv->ring_size + CPMAC_QUEUES;
+ priv->desc_ring = dma_alloc_coherent(&dev->dev,
+ sizeof(struct cpmac_desc) * size,
+ &priv->dma_ring,
+ GFP_KERNEL);
+ if (!priv->desc_ring) {
+ res = -ENOMEM;
+ goto fail_alloc;
+ }
+
+ for (i = 0; i < size; i++)
+ priv->desc_ring[i].mapping = priv->dma_ring + sizeof(*desc) * i;
+
+ priv->rx_head = &priv->desc_ring[CPMAC_QUEUES];
+ for (i = 0, desc = priv->rx_head; i < priv->ring_size; i++, desc++) {
+ skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+ if (unlikely(!skb)) {
+ res = -ENOMEM;
+ goto fail_desc;
+ }
+ skb_reserve(skb, 2);
+ desc->skb = skb;
+ desc->data_mapping = dma_map_single(&dev->dev, skb->data,
+ CPMAC_SKB_SIZE,
+ DMA_FROM_DEVICE);
+ desc->hw_data = (u32)desc->data_mapping;
+ desc->buflen = CPMAC_SKB_SIZE;
+ desc->dataflags = CPMAC_OWN;
+ desc->next = &priv->rx_head[(i + 1) % priv->ring_size];
+ desc->hw_next = (u32)desc->next->mapping;
+ }
+
+ if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED,
+ dev->name, dev))) {
+ if (netif_msg_drv(priv))
+ printk(KERN_ERR "%s: failed to obtain irq\n",
+ dev->name);
+ goto fail_irq;
+ }
+
+ INIT_WORK(&priv->reset_work, cpmac_hw_error);
+ cpmac_hw_start(dev);
+
+ priv->phy->state = PHY_CHANGELINK;
+ phy_start(priv->phy);
+
+ return 0;
+
+fail_irq:
+fail_desc:
+ for (i = 0; i < priv->ring_size; i++) {
+ if (priv->rx_head[i].skb) {
+ dma_unmap_single(&dev->dev,
+ priv->rx_head[i].data_mapping,
+ CPMAC_SKB_SIZE,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_head[i].skb);
+ }
+ }
+fail_alloc:
+ kfree(priv->desc_ring);
+ iounmap(priv->regs);
+
+fail_remap:
+ release_mem_region(mem->start, mem->end - mem->start);
+
+fail_reserve:
+ phy_disconnect(priv->phy);
+
+ return res;
+}
+
+static int cpmac_stop(struct net_device *dev)
+{
+ int i;
+ struct cpmac_priv *priv = netdev_priv(dev);
+ struct resource *mem;
+
+ netif_stop_queue(dev);
+
+ cancel_work_sync(&priv->reset_work);
+ phy_stop(priv->phy);
+ phy_disconnect(priv->phy);
+ priv->phy = NULL;
+
+ cpmac_hw_stop(dev);
+
+ for (i = 0; i < 8; i++)
+ cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0);
+ cpmac_write(priv->regs, CPMAC_RX_PTR(0), 0);
+ cpmac_write(priv->regs, CPMAC_MBP, 0);
+
+ free_irq(dev->irq, dev);
+ iounmap(priv->regs);
+ mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
+ release_mem_region(mem->start, mem->end - mem->start);
+ priv->rx_head = &priv->desc_ring[CPMAC_QUEUES];
+ for (i = 0; i < priv->ring_size; i++) {
+ if (priv->rx_head[i].skb) {
+ dma_unmap_single(&dev->dev,
+ priv->rx_head[i].data_mapping,
+ CPMAC_SKB_SIZE,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_head[i].skb);
+ }
+ }
+
+ dma_free_coherent(&dev->dev, sizeof(struct cpmac_desc) *
+ (CPMAC_QUEUES + priv->ring_size),
+ priv->desc_ring, priv->dma_ring);
+ return 0;
+}
+
+static int external_switch;
+
+static int __devinit cpmac_probe(struct platform_device *pdev)
+{
+ int rc, phy_id;
+ struct resource *mem;
+ struct cpmac_priv *priv;
+ struct net_device *dev;
+ struct plat_cpmac_data *pdata;
+
+ pdata = pdev->dev.platform_data;
+
+ for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
+ if (!(pdata->phy_mask & (1 << phy_id)))
+ continue;
+ if (!cpmac_mii.phy_map[phy_id])
+ continue;
+ break;
+ }
+
+ if (phy_id == PHY_MAX_ADDR) {
+ if (external_switch || dumb_switch)
+ phy_id = 0;
+ else {
+ printk(KERN_ERR "cpmac: no PHY present\n");
+ return -ENODEV;
+ }
+ }
+
+ dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
+
+ if (!dev) {
+ printk(KERN_ERR "cpmac: Unable to allocate net_device\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, dev);
+ priv = netdev_priv(dev);
+
+ priv->pdev = pdev;
+ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ if (!mem) {
+ rc = -ENODEV;
+ goto fail;
+ }
+
+ dev->irq = platform_get_irq_byname(pdev, "irq");
+
+ dev->open = cpmac_open;
+ dev->stop = cpmac_stop;
+ dev->set_config = cpmac_config;
+ dev->hard_start_xmit = cpmac_start_xmit;
+ dev->do_ioctl = cpmac_ioctl;
+ dev->set_multicast_list = cpmac_set_multicast_list;
+ dev->tx_timeout = cpmac_tx_timeout;
+ dev->ethtool_ops = &cpmac_ethtool_ops;
+ dev->poll = cpmac_poll;
+ dev->weight = 64;
+ dev->features |= NETIF_F_MULTI_QUEUE;
+
+ spin_lock_init(&priv->lock);
+ spin_lock_init(&priv->rx_lock);
+ priv->dev = dev;
+ priv->ring_size = 64;
+ priv->msg_enable = netif_msg_init(debug_level, 0xff);
+ memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
+ if (phy_id == 31) {
+ snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT,
+ cpmac_mii.id, phy_id);
+ } else
+ snprintf(priv->phy_name, BUS_ID_SIZE, "fixed@%d:%d", 100, 1);
+
+ if ((rc = register_netdev(dev))) {
+ printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
+ dev->name);
+ goto fail;
+ }
+
+ if (netif_msg_probe(priv)) {
+ printk(KERN_INFO
+ "cpmac: device %s (regs: %p, irq: %d, phy: %s, mac: "
+ MAC_FMT ")\n", dev->name, (void *)mem->start, dev->irq,
+ priv->phy_name, MAC_ARG(dev->dev_addr));
+ }
+ return 0;
+
+fail:
+ free_netdev(dev);
+ return rc;
+}
+
+static int __devexit cpmac_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ unregister_netdev(dev);
+ free_netdev(dev);
+ return 0;
+}
+
+static struct platform_driver cpmac_driver = {
+ .driver.name = "cpmac",
+ .probe = cpmac_probe,
+ .remove = __devexit_p(cpmac_remove),
+};
+
+int __devinit cpmac_init(void)
+{
+ u32 mask;
+ int i, res;
+
+ cpmac_mii.priv = ioremap(AR7_REGS_MDIO, 256);
+
+ if (!cpmac_mii.priv) {
+ printk(KERN_ERR "Can't ioremap mdio registers\n");
+ return -ENXIO;
+ }
+
+#warning FIXME: unhardcode gpio&reset bits
+ ar7_gpio_disable(26);
+ ar7_gpio_disable(27);
+ ar7_device_reset(AR7_RESET_BIT_CPMAC_LO);
+ ar7_device_reset(AR7_RESET_BIT_CPMAC_HI);
+ ar7_device_reset(AR7_RESET_BIT_EPHY);
+
+ cpmac_mii.reset(&cpmac_mii);
+
+ for (i = 0; i < 300000; i++)
+ if ((mask = cpmac_read(cpmac_mii.priv, CPMAC_MDIO_ALIVE)))
+ break;
+ else
+ cpu_relax();
+
+ mask &= 0x7fffffff;
+ if (mask & (mask - 1)) {
+ external_switch = 1;
+ mask = 0;
+ }
+
+ cpmac_mii.phy_mask = ~(mask | 0x80000000);
+
+ res = mdiobus_register(&cpmac_mii);
+ if (res)
+ goto fail_mii;
+
+ res = platform_driver_register(&cpmac_driver);
+ if (res)
+ goto fail_cpmac;
+
+ return 0;
+
+fail_cpmac:
+ mdiobus_unregister(&cpmac_mii);
+
+fail_mii:
+ iounmap(cpmac_mii.priv);
+
+ return res;
+}
+
+void __devexit cpmac_exit(void)
+{
+ platform_driver_unregister(&cpmac_driver);
+ mdiobus_unregister(&cpmac_mii);
+ iounmap(cpmac_mii.priv);
+}
+
+module_init(cpmac_init);
+module_exit(cpmac_exit);
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/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index b7a7e2ae5e1..0666e62e9ad 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -110,6 +110,7 @@ static int e1000_get_settings(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u32 status;
if (hw->media_type == e1000_media_type_copper) {
@@ -147,16 +148,16 @@ static int e1000_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
}
- if (er32(STATUS) & E1000_STATUS_LU) {
-
- adapter->hw.mac.ops.get_link_up_info(hw, &adapter->link_speed,
- &adapter->link_duplex);
- ecmd->speed = adapter->link_speed;
-
- /* unfortunately FULL_DUPLEX != DUPLEX_FULL
- * and HALF_DUPLEX != DUPLEX_HALF */
+ status = er32(STATUS);
+ if (status & E1000_STATUS_LU) {
+ if (status & E1000_STATUS_SPEED_1000)
+ ecmd->speed = 1000;
+ else if (status & E1000_STATUS_SPEED_100)
+ ecmd->speed = 100;
+ else
+ ecmd->speed = 10;
- if (adapter->link_duplex == FULL_DUPLEX)
+ if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
@@ -170,6 +171,16 @@ static int e1000_get_settings(struct net_device *netdev,
return 0;
}
+static u32 e1000_get_link(struct net_device *netdev)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ u32 status;
+
+ status = er32(STATUS);
+ return (status & E1000_STATUS_LU);
+}
+
static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
{
struct e1000_mac_info *mac = &adapter->hw.mac;
@@ -1451,11 +1462,11 @@ static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
}
*data = e1000_setup_desc_rings(adapter);
- if (data)
+ if (*data)
goto out;
*data = e1000_setup_loopback_test(adapter);
- if (data)
+ if (*data)
goto err_loopback;
*data = e1000_run_loopback_test(adapter);
@@ -1751,7 +1762,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.get_msglevel = e1000_get_msglevel,
.set_msglevel = e1000_set_msglevel,
.nway_reset = e1000_nway_reset,
- .get_link = ethtool_op_get_link,
+ .get_link = e1000_get_link,
.get_eeprom_len = e1000_get_eeprom_len,
.get_eeprom = e1000_get_eeprom,
.set_eeprom = e1000_set_eeprom,
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index aa82f1afb7f..64515789fd4 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -852,7 +852,7 @@ struct e1000_hw {
#ifdef DEBUG
#define hw_dbg(hw, format, arg...) \
- printk(KERN_DEBUG, "%s: " format, e1000e_get_hw_dev_name(hw), ##arg);
+ printk(KERN_DEBUG "%s: " format, e1000e_get_hw_dev_name(hw), ##arg)
#else
static inline int __attribute__ ((format (printf, 2, 3)))
hw_dbg(struct e1000_hw *hw, const char *format, ...)
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index ac21526b6de..b557bb44a36 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -388,7 +388,7 @@ struct ehea_port_res {
#define EHEA_MAX_PORTS 16
struct ehea_adapter {
u64 handle;
- struct ibmebus_dev *ebus_dev;
+ struct of_device *ofdev;
struct ehea_port *port[EHEA_MAX_PORTS];
struct ehea_eq *neq; /* notification event queue */
struct tasklet_struct neq_tasklet;
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 2ba57e6ace4..2809c99906e 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -98,10 +98,10 @@ struct work_struct ehea_rereg_mr_task;
struct semaphore dlpar_mem_lock;
-static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
+static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id);
-static int __devexit ehea_remove(struct ibmebus_dev *dev);
+static int __devexit ehea_remove(struct of_device *dev);
static struct of_device_id ehea_device_table[] = {
{
@@ -111,9 +111,9 @@ static struct of_device_id ehea_device_table[] = {
{},
};
-static struct ibmebus_driver ehea_driver = {
+static struct of_platform_driver ehea_driver = {
.name = "ehea",
- .id_table = ehea_device_table,
+ .match_table = ehea_device_table,
.probe = ehea_probe_adapter,
.remove = ehea_remove,
};
@@ -1044,7 +1044,7 @@ static int ehea_reg_interrupts(struct net_device *dev)
snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff",
dev->name);
- ret = ibmebus_request_irq(NULL, port->qp_eq->attr.ist1,
+ ret = ibmebus_request_irq(port->qp_eq->attr.ist1,
ehea_qp_aff_irq_handler,
IRQF_DISABLED, port->int_aff_name, port);
if (ret) {
@@ -1062,7 +1062,7 @@ static int ehea_reg_interrupts(struct net_device *dev)
pr = &port->port_res[i];
snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1,
"%s-queue%d", dev->name, i);
- ret = ibmebus_request_irq(NULL, pr->eq->attr.ist1,
+ ret = ibmebus_request_irq(pr->eq->attr.ist1,
ehea_recv_irq_handler,
IRQF_DISABLED, pr->int_send_name,
pr);
@@ -1083,11 +1083,11 @@ out:
out_free_req:
while (--i >= 0) {
u32 ist = port->port_res[i].eq->attr.ist1;
- ibmebus_free_irq(NULL, ist, &port->port_res[i]);
+ ibmebus_free_irq(ist, &port->port_res[i]);
}
out_free_qpeq:
- ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port);
+ ibmebus_free_irq(port->qp_eq->attr.ist1, port);
i = port->num_def_qps;
goto out;
@@ -1104,14 +1104,14 @@ static void ehea_free_interrupts(struct net_device *dev)
for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
pr = &port->port_res[i];
- ibmebus_free_irq(NULL, pr->eq->attr.ist1, pr);
+ ibmebus_free_irq(pr->eq->attr.ist1, pr);
if (netif_msg_intr(port))
ehea_info("free send irq for res %d with handle 0x%X",
i, pr->eq->attr.ist1);
}
/* associated events */
- ibmebus_free_irq(NULL, port->qp_eq->attr.ist1, port);
+ ibmebus_free_irq(port->qp_eq->attr.ist1, port);
if (netif_msg_intr(port))
ehea_info("associated event interrupt for handle 0x%X freed",
port->qp_eq->attr.ist1);
@@ -2832,7 +2832,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
int ret;
port->ofdev.node = of_node_get(dn);
- port->ofdev.dev.parent = &port->adapter->ebus_dev->ofdev.dev;
+ port->ofdev.dev.parent = &port->adapter->ofdev->dev;
port->ofdev.dev.bus = &ibmebus_bus_type;
sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
@@ -3011,7 +3011,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
const u32 *dn_log_port_id;
int i = 0;
- lhea_dn = adapter->ebus_dev->ofdev.node;
+ lhea_dn = adapter->ofdev->node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
@@ -3051,7 +3051,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
struct device_node *eth_dn = NULL;
const u32 *dn_log_port_id;
- lhea_dn = adapter->ebus_dev->ofdev.node;
+ lhea_dn = adapter->ofdev->node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
@@ -3157,31 +3157,31 @@ static ssize_t ehea_remove_port(struct device *dev,
static DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port);
static DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port);
-int ehea_create_device_sysfs(struct ibmebus_dev *dev)
+int ehea_create_device_sysfs(struct of_device *dev)
{
- int ret = device_create_file(&dev->ofdev.dev, &dev_attr_probe_port);
+ int ret = device_create_file(&dev->dev, &dev_attr_probe_port);
if (ret)
goto out;
- ret = device_create_file(&dev->ofdev.dev, &dev_attr_remove_port);
+ ret = device_create_file(&dev->dev, &dev_attr_remove_port);
out:
return ret;
}
-void ehea_remove_device_sysfs(struct ibmebus_dev *dev)
+void ehea_remove_device_sysfs(struct of_device *dev)
{
- device_remove_file(&dev->ofdev.dev, &dev_attr_probe_port);
- device_remove_file(&dev->ofdev.dev, &dev_attr_remove_port);
+ device_remove_file(&dev->dev, &dev_attr_probe_port);
+ device_remove_file(&dev->dev, &dev_attr_remove_port);
}
-static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
+static int __devinit ehea_probe_adapter(struct of_device *dev,
const struct of_device_id *id)
{
struct ehea_adapter *adapter;
const u64 *adapter_handle;
int ret;
- if (!dev || !dev->ofdev.node) {
+ if (!dev || !dev->node) {
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
@@ -3189,36 +3189,36 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
ret = -ENOMEM;
- dev_err(&dev->ofdev.dev, "no mem for ehea_adapter\n");
+ dev_err(&dev->dev, "no mem for ehea_adapter\n");
goto out;
}
list_add(&adapter->list, &adapter_list);
- adapter->ebus_dev = dev;
+ adapter->ofdev = dev;
- adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
+ adapter_handle = of_get_property(dev->node, "ibm,hea-handle",
NULL);
if (adapter_handle)
adapter->handle = *adapter_handle;
if (!adapter->handle) {
- dev_err(&dev->ofdev.dev, "failed getting handle for adapter"
- " '%s'\n", dev->ofdev.node->full_name);
+ dev_err(&dev->dev, "failed getting handle for adapter"
+ " '%s'\n", dev->node->full_name);
ret = -ENODEV;
goto out_free_ad;
}
adapter->pd = EHEA_PD_ID;
- dev->ofdev.dev.driver_data = adapter;
+ dev->dev.driver_data = adapter;
/* initialize adapter and ports */
/* get adapter properties */
ret = ehea_sense_adapter_attr(adapter);
if (ret) {
- dev_err(&dev->ofdev.dev, "sense_adapter_attr failed: %d", ret);
+ dev_err(&dev->dev, "sense_adapter_attr failed: %d\n", ret);
goto out_free_ad;
}
@@ -3226,18 +3226,18 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1);
if (!adapter->neq) {
ret = -EIO;
- dev_err(&dev->ofdev.dev, "NEQ creation failed");
+ dev_err(&dev->dev, "NEQ creation failed\n");
goto out_free_ad;
}
tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
(unsigned long)adapter);
- ret = ibmebus_request_irq(NULL, adapter->neq->attr.ist1,
+ ret = ibmebus_request_irq(adapter->neq->attr.ist1,
ehea_interrupt_neq, IRQF_DISABLED,
"ehea_neq", adapter);
if (ret) {
- dev_err(&dev->ofdev.dev, "requesting NEQ IRQ failed");
+ dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
goto out_kill_eq;
}
@@ -3247,7 +3247,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
ret = ehea_setup_ports(adapter);
if (ret) {
- dev_err(&dev->ofdev.dev, "setup_ports failed");
+ dev_err(&dev->dev, "setup_ports failed\n");
goto out_rem_dev_sysfs;
}
@@ -3258,7 +3258,7 @@ out_rem_dev_sysfs:
ehea_remove_device_sysfs(dev);
out_free_irq:
- ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
+ ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
out_kill_eq:
ehea_destroy_eq(adapter->neq);
@@ -3269,9 +3269,9 @@ out:
return ret;
}
-static int __devexit ehea_remove(struct ibmebus_dev *dev)
+static int __devexit ehea_remove(struct of_device *dev)
{
- struct ehea_adapter *adapter = dev->ofdev.dev.driver_data;
+ struct ehea_adapter *adapter = dev->dev.driver_data;
int i;
for (i = 0; i < EHEA_MAX_PORTS; i++)
@@ -3284,7 +3284,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
flush_scheduled_work();
- ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
+ ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
ehea_destroy_eq(adapter->neq);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index dae30b73134..70ddf1acfd8 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -128,7 +128,7 @@
#else
#define DRIVERNAPI
#endif
-#define FORCEDETH_VERSION "0.60"
+#define FORCEDETH_VERSION "0.61"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -752,7 +752,6 @@ struct fe_priv {
/* General data:
* Locking: spin_lock(&np->lock); */
- struct net_device_stats stats;
struct nv_ethtool_stats estats;
int in_shutdown;
u32 linkspeed;
@@ -993,7 +992,7 @@ static void nv_enable_irq(struct net_device *dev)
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1009,7 +1008,7 @@ static void nv_disable_irq(struct net_device *dev)
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1505,15 +1504,16 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
nv_get_hw_stats(dev);
/* copy to net_device stats */
- np->stats.tx_bytes = np->estats.tx_bytes;
- np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
- np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
- np->stats.rx_crc_errors = np->estats.rx_crc_errors;
- np->stats.rx_over_errors = np->estats.rx_over_errors;
- np->stats.rx_errors = np->estats.rx_errors_total;
- np->stats.tx_errors = np->estats.tx_errors_total;
- }
- return &np->stats;
+ dev->stats.tx_bytes = np->estats.tx_bytes;
+ dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
+ dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
+ dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
+ dev->stats.rx_over_errors = np->estats.rx_over_errors;
+ dev->stats.rx_errors = np->estats.rx_errors_total;
+ dev->stats.tx_errors = np->estats.tx_errors_total;
+ }
+
+ return &dev->stats;
}
/*
@@ -1607,7 +1607,7 @@ static void nv_do_rx_refill(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
@@ -1625,7 +1625,7 @@ static void nv_do_rx_refill(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
@@ -1733,7 +1733,7 @@ static void nv_drain_tx(struct net_device *dev)
np->tx_ring.ex[i].buflow = 0;
}
if (nv_release_txskb(dev, &np->tx_skb[i]))
- np->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
@@ -2049,13 +2049,13 @@ static void nv_tx_done(struct net_device *dev)
if (flags & NV_TX_LASTPACKET) {
if (flags & NV_TX_ERROR) {
if (flags & NV_TX_UNDERFLOW)
- np->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (flags & NV_TX_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
} else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
@@ -2064,13 +2064,13 @@ static void nv_tx_done(struct net_device *dev)
if (flags & NV_TX2_LASTPACKET) {
if (flags & NV_TX2_ERROR) {
if (flags & NV_TX2_UNDERFLOW)
- np->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (flags & NV_TX2_CARRIERLOST)
- np->stats.tx_carrier_errors++;
- np->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
} else {
- np->stats.tx_packets++;
- np->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
@@ -2107,7 +2107,7 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
if (flags & NV_TX2_LASTPACKET) {
if (!(flags & NV_TX2_ERROR))
- np->stats.tx_packets++;
+ dev->stats.tx_packets++;
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
}
@@ -2268,13 +2268,13 @@ static int nv_rx_process(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
u32 flags;
- u32 rx_processed_cnt = 0;
+ int rx_work = 0;
struct sk_buff *skb;
int len;
while((np->get_rx.orig != np->put_rx.orig) &&
!((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) &&
- (rx_processed_cnt++ < limit)) {
+ (rx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n",
dev->name, flags);
@@ -2308,7 +2308,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
if (flags & NV_RX_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2322,12 +2322,12 @@ static int nv_rx_process(struct net_device *dev, int limit)
/* the rest are hard errors */
else {
if (flags & NV_RX_MISSEDFRAME)
- np->stats.rx_missed_errors++;
+ dev->stats.rx_missed_errors++;
if (flags & NV_RX_CRCERR)
- np->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (flags & NV_RX_OVERFLOW)
- np->stats.rx_over_errors++;
- np->stats.rx_errors++;
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2343,7 +2343,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
if (flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2357,10 +2357,10 @@ static int nv_rx_process(struct net_device *dev, int limit)
/* the rest are hard errors */
else {
if (flags & NV_RX2_CRCERR)
- np->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (flags & NV_RX2_OVERFLOW)
- np->stats.rx_over_errors++;
- np->stats.rx_errors++;
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2389,16 +2389,18 @@ static int nv_rx_process(struct net_device *dev, int limit)
netif_rx(skb);
#endif
dev->last_rx = jiffies;
- np->stats.rx_packets++;
- np->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
next_pkt:
if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
np->get_rx.orig = np->first_rx.orig;
if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
np->get_rx_ctx = np->first_rx_ctx;
+
+ rx_work++;
}
- return rx_processed_cnt;
+ return rx_work;
}
static int nv_rx_process_optimized(struct net_device *dev, int limit)
@@ -2406,13 +2408,13 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
struct fe_priv *np = netdev_priv(dev);
u32 flags;
u32 vlanflags = 0;
- u32 rx_processed_cnt = 0;
+ int rx_work = 0;
struct sk_buff *skb;
int len;
while((np->get_rx.ex != np->put_rx.ex) &&
!((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) &&
- (rx_processed_cnt++ < limit)) {
+ (rx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n",
dev->name, flags);
@@ -2505,8 +2507,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
}
dev->last_rx = jiffies;
- np->stats.rx_packets++;
- np->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
} else {
dev_kfree_skb(skb);
}
@@ -2515,9 +2517,11 @@ next_pkt:
np->get_rx.ex = np->first_rx.ex;
if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
np->get_rx_ctx = np->first_rx_ctx;
+
+ rx_work++;
}
- return rx_processed_cnt;
+ return rx_work;
}
static void set_bufsize(struct net_device *dev)
@@ -3556,10 +3560,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
np->msi_flags |= NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
goto out_err;
}
@@ -3622,7 +3628,7 @@ static void nv_do_nic_poll(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq_lockdep(dev->irq);
+ disable_irq_lockdep(np->pci_dev->irq);
mask = np->irqmask;
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -3640,6 +3646,8 @@ static void nv_do_nic_poll(unsigned long data)
}
np->nic_poll_irq = 0;
+ /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
if (np->recover_error) {
np->recover_error = 0;
printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
@@ -3676,7 +3684,6 @@ static void nv_do_nic_poll(unsigned long data)
}
}
- /* FIXME: Do we need synchronize_irq(dev->irq) here? */
writel(mask, base + NvRegIrqMask);
pci_push(base);
@@ -3689,7 +3696,7 @@ static void nv_do_nic_poll(unsigned long data)
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq_lockdep(dev->irq);
+ enable_irq_lockdep(np->pci_dev->irq);
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
nv_nic_irq_rx(0, dev);
@@ -3727,7 +3734,7 @@ static void nv_do_stats_poll(unsigned long data)
static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct fe_priv *np = netdev_priv(dev);
- strcpy(info->driver, "forcedeth");
+ strcpy(info->driver, DRV_NAME);
strcpy(info->version, FORCEDETH_VERSION);
strcpy(info->bus_info, pci_name(np->pci_dev));
}
@@ -4946,7 +4953,7 @@ static int nv_close(struct net_device *dev)
#ifdef CONFIG_FORCEDETH_NAPI
napi_disable(&np->napi);
#endif
- synchronize_irq(dev->irq);
+ synchronize_irq(np->pci_dev->irq);
del_timer_sync(&np->oom_kick);
del_timer_sync(&np->nic_poll);
@@ -4991,6 +4998,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
u32 phystate_orig = 0, phystate;
int phyinitialized = 0;
DECLARE_MAC_BUF(mac);
+ static int printed_version;
+
+ if (!printed_version++)
+ printk(KERN_INFO "%s: Reverse Engineered nForce ethernet"
+ " driver. Version %s.\n", DRV_NAME, FORCEDETH_VERSION);
dev = alloc_etherdev(sizeof(struct fe_priv));
err = -ENOMEM;
@@ -5014,11 +5026,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->stats_poll.function = &nv_do_stats_poll; /* timer handler */
err = pci_enable_device(pci_dev);
- if (err) {
- printk(KERN_INFO "forcedeth: pci_enable_dev failed (%d) for device %s\n",
- err, pci_name(pci_dev));
+ if (err)
goto out_free;
- }
pci_set_master(pci_dev);
@@ -5047,8 +5056,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
}
}
if (i == DEVICE_COUNT_RESOURCE) {
- printk(KERN_INFO "forcedeth: Couldn't find register window for device %s.\n",
- pci_name(pci_dev));
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "Couldn't find register window\n");
goto out_relreg;
}
@@ -5061,16 +5070,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
np->desc_ver = DESC_VER_3;
np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
if (dma_64bit) {
- if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) {
- printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
- pci_name(pci_dev));
- } else {
+ if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK))
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "64-bit DMA failed, using 32-bit addressing\n");
+ else
dev->features |= NETIF_F_HIGHDMA;
- printk(KERN_INFO "forcedeth: using HIGHDMA\n");
- }
if (pci_set_consistent_dma_mask(pci_dev, DMA_39BIT_MASK)) {
- printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed, using 32-bit ring buffers for device %s.\n",
- pci_name(pci_dev));
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
}
}
} else if (id->driver_data & DEV_HAS_LARGEDESC) {
@@ -5205,9 +5212,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
* Bad mac address. At least one bios sets the mac address
* to 01:23:45:67:89:ab
*/
- printk(KERN_ERR "%s: Invalid Mac address detected: %s\n",
- pci_name(pci_dev), print_mac(mac, dev->dev_addr));
- printk(KERN_ERR "Please complain to your hardware vendor. Switching to a random MAC.\n");
+ dev_printk(KERN_ERR, &pci_dev->dev,
+ "Invalid Mac address detected: %s\n",
+ print_mac(mac, dev->dev_addr));
+ dev_printk(KERN_ERR, &pci_dev->dev,
+ "Please complain to your hardware vendor. Switching to a random MAC.\n");
dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0x6c;
@@ -5321,8 +5330,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
break;
}
if (i == 33) {
- printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
- pci_name(pci_dev));
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "open: Could not find a valid PHY.\n");
goto out_error;
}
@@ -5344,12 +5353,37 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
err = register_netdev(dev);
if (err) {
- printk(KERN_INFO "forcedeth: unable to register netdev: %d\n", err);
+ dev_printk(KERN_INFO, &pci_dev->dev,
+ "unable to register netdev: %d\n", err);
goto out_error;
}
- printk(KERN_INFO "%s: forcedeth.c: subsystem: %05x:%04x bound to %s\n",
- dev->name, pci_dev->subsystem_vendor, pci_dev->subsystem_device,
- pci_name(pci_dev));
+
+ dev_printk(KERN_INFO, &pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, "
+ "addr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+ dev->name,
+ np->phy_oui,
+ np->phyaddr,
+ dev->dev_addr[0],
+ dev->dev_addr[1],
+ dev->dev_addr[2],
+ dev->dev_addr[3],
+ dev->dev_addr[4],
+ dev->dev_addr[5]);
+
+ dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
+ dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
+ dev->features & (NETIF_F_HW_CSUM | NETIF_F_SG) ?
+ "csum " : "",
+ dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ?
+ "vlan " : "",
+ id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "",
+ id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "",
+ id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "",
+ np->gigabit == PHY_GIGABIT ? "gbit " : "",
+ np->need_linktimer ? "lnktim " : "",
+ np->msi_flags & NV_MSI_CAPABLE ? "msi " : "",
+ np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "",
+ np->desc_ver);
return 0;
@@ -5567,17 +5601,16 @@ static struct pci_device_id pci_tbl[] = {
};
static struct pci_driver driver = {
- .name = "forcedeth",
- .id_table = pci_tbl,
- .probe = nv_probe,
- .remove = __devexit_p(nv_remove),
- .suspend = nv_suspend,
- .resume = nv_resume,
+ .name = DRV_NAME,
+ .id_table = pci_tbl,
+ .probe = nv_probe,
+ .remove = __devexit_p(nv_remove),
+ .suspend = nv_suspend,
+ .resume = nv_resume,
};
static int __init init_nic(void)
{
- printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION);
return pci_register_driver(&driver);
}
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 04c6faec88d..f2a4d399a6e 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -88,7 +88,7 @@ static void skb_align(struct sk_buff *skb, int align)
static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
{
struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
- struct net_device *dev = to_net_dev(fep->dev);
+ struct net_device *dev = fep->ndev;
const struct fs_platform_info *fpi = fep->fpi;
cbd_t __iomem *bdp;
struct sk_buff *skb, *skbn, *skbt;
@@ -217,7 +217,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
fep->cur_rx = bdp;
- if (received >= budget) {
+ if (received < budget) {
/* done */
netif_rx_complete(dev, napi);
(*fep->ops->napi_enable_rx)(dev);
@@ -807,20 +807,23 @@ static int fs_enet_open(struct net_device *dev)
int r;
int err;
- napi_enable(&fep->napi);
+ if (fep->fpi->use_napi)
+ napi_enable(&fep->napi);
/* Install our interrupt handler. */
r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
if (r != 0) {
printk(KERN_ERR DRV_MODULE_NAME
": %s Could not allocate FS_ENET IRQ!", dev->name);
- napi_disable(&fep->napi);
+ if (fep->fpi->use_napi)
+ napi_disable(&fep->napi);
return -EINVAL;
}
err = fs_init_phy(dev);
- if(err) {
- napi_disable(&fep->napi);
+ if (err) {
+ if (fep->fpi->use_napi)
+ napi_disable(&fep->napi);
return err;
}
phy_start(fep->phydev);
@@ -1232,7 +1235,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
fpi->rx_ring = 32;
fpi->tx_ring = 32;
fpi->rx_copybreak = 240;
- fpi->use_napi = 0;
+ fpi->use_napi = 1;
fpi->napi_weight = 17;
ret = find_phy(ofdev->node, fpi);
@@ -1249,11 +1252,11 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
goto out_free_fpi;
}
- SET_MODULE_OWNER(ndev);
dev_set_drvdata(&ofdev->dev, ndev);
fep = netdev_priv(ndev);
fep->dev = &ofdev->dev;
+ fep->ndev = ndev;
fep->fpi = fpi;
fep->ops = match->data;
@@ -1288,10 +1291,11 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
ndev->stop = fs_enet_close;
ndev->get_stats = fs_enet_get_stats;
ndev->set_multicast_list = fs_set_multicast_list;
- if (fpi->use_napi) {
- ndev->poll = fs_enet_rx_napi;
- ndev->weight = fpi->napi_weight;
- }
+
+ if (fpi->use_napi)
+ netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi,
+ fpi->napi_weight);
+
ndev->ethtool_ops = &fs_ethtool_ops;
ndev->do_ioctl = fs_ioctl;
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index baf6477165a..c675e29aadc 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -75,6 +75,7 @@ struct phy_info {
struct fs_enet_private {
struct napi_struct napi;
struct device *dev; /* pointer back to the device (must be initialized first) */
+ struct net_device *ndev;
spinlock_t lock; /* during all ops except TX pckt processing */
spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */
struct fs_platform_info *fpi;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0db5e6fabe7..38268d7335a 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -168,7 +168,6 @@ static int gfar_probe(struct platform_device *pdev)
struct gfar_private *priv = NULL;
struct gianfar_platform_data *einfo;
struct resource *r;
- int idx;
int err = 0;
DECLARE_MAC_BUF(mac);
@@ -261,7 +260,9 @@ static int gfar_probe(struct platform_device *pdev)
dev->hard_start_xmit = gfar_start_xmit;
dev->tx_timeout = gfar_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_GFAR_NAPI
netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
+#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = gfar_netpoll;
#endif
@@ -931,9 +932,14 @@ tx_skb_fail:
/* Returns 0 for success. */
static int gfar_enet_open(struct net_device *dev)
{
+#ifdef CONFIG_GFAR_NAPI
+ struct gfar_private *priv = netdev_priv(dev);
+#endif
int err;
+#ifdef CONFIG_GFAR_NAPI
napi_enable(&priv->napi);
+#endif
/* Initialize a bunch of registers */
init_registers(dev);
@@ -943,13 +949,19 @@ static int gfar_enet_open(struct net_device *dev)
err = init_phy(dev);
if(err) {
+#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
+#endif
return err;
}
err = startup_gfar(dev);
- if (err)
+ if (err) {
+#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
+#endif
+ return err;
+ }
netif_start_queue(dev);
@@ -1103,7 +1115,9 @@ static int gfar_close(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
+#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
+#endif
stop_gfar(dev);
@@ -1225,8 +1239,6 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
* starting over will fix the problem. */
static void gfar_timeout(struct net_device *dev)
{
- struct gfar_private *priv = netdev_priv(dev);
-
dev->stats.tx_errors++;
if (dev->flags & IFF_UP) {
@@ -1332,8 +1344,9 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
return skb;
}
-static inline void count_errors(unsigned short status, struct gfar_private *priv)
+static inline void count_errors(unsigned short status, struct net_device *dev)
{
+ struct gfar_private *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
struct gfar_extra_stats *estats = &priv->extra_stats;
@@ -1527,7 +1540,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
dev->stats.rx_bytes += pkt_len;
} else {
- count_errors(bdp->status, priv);
+ count_errors(bdp->status, dev);
if (skb)
dev_kfree_skb_any(skb);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index c16cc8b946a..46cd7735e6f 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -749,7 +749,6 @@ struct gfar_private {
uint32_t msg_enable;
/* Network Statistics */
- struct net_device_stats stats;
struct gfar_extra_stats extra_stats;
};
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index e4fde17e284..49421d1cd3a 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -8,7 +8,7 @@
** Extended for new busmaster capable chipsets by
** Siegfried "Frieder" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>
**
-** Maintained by: Jaroslav Kysela <perex@suse.cz>
+** Maintained by: Jaroslav Kysela <perex@perex.cz>
**
** This driver has only been tested with
** -- HP J2585B 10/100 Mbit/s PCI Busmaster
@@ -2951,7 +2951,7 @@ static struct pci_driver hp100_pci_driver = {
*/
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, "
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, "
"Siegfried \"Frieder\" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>");
MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters");
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
index 4e49e8c4f87..dcd8826fc74 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.c
+++ b/drivers/net/ibm_emac/ibm_emac_mal.c
@@ -413,7 +413,10 @@ static int __init mal_probe(struct ocp_device *ocpdev)
ocpdev->def->index);
return -ENOMEM;
}
- mal->dcrbase = maldata->dcr_base;
+
+ /* XXX This only works for native dcr for now */
+ mal->dcrhost = dcr_map(NULL, maldata->dcr_base, 0);
+
mal->def = ocpdev->def;
INIT_LIST_HEAD(&mal->poll_list);
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index 8f54d621994..b8adbe6d4b0 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -191,7 +191,6 @@ struct mal_commac {
};
struct ibm_ocp_mal {
- int dcrbase;
dcr_host_t dcrhost;
struct list_head poll_list;
@@ -209,12 +208,12 @@ struct ibm_ocp_mal {
static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
{
- return dcr_read(mal->dcrhost, mal->dcrbase + reg);
+ return dcr_read(mal->dcrhost, reg);
}
static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
{
- dcr_write(mal->dcrhost, mal->dcrbase + reg, val);
+ dcr_write(mal->dcrhost, reg, val);
}
/* Register MAL devices */
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index 58854117b1a..9a88f71db00 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -45,6 +45,8 @@ int __devinit mal_register_commac(struct mal_instance *mal,
return -EBUSY;
}
+ if (list_empty(&mal->list))
+ napi_enable(&mal->napi);
mal->tx_chan_mask |= commac->tx_chan_mask;
mal->rx_chan_mask |= commac->rx_chan_mask;
list_add(&commac->list, &mal->list);
@@ -67,6 +69,8 @@ void __devexit mal_unregister_commac(struct mal_instance *mal,
mal->tx_chan_mask &= ~commac->tx_chan_mask;
mal->rx_chan_mask &= ~commac->rx_chan_mask;
list_del_init(&commac->list);
+ if (list_empty(&mal->list))
+ napi_disable(&mal->napi);
spin_unlock_irqrestore(&mal->lock, flags);
}
@@ -182,7 +186,7 @@ static inline void mal_enable_eob_irq(struct mal_instance *mal)
set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
}
-/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
+/* synchronized by NAPI state */
static inline void mal_disable_eob_irq(struct mal_instance *mal)
{
// XXX might want to cache MAL_CFG as the DCR read can be slooooow
@@ -317,8 +321,8 @@ void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac)
while (test_and_set_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags))
msleep(1);
- /* Synchronize with the MAL NAPI poller. */
- napi_disable(&mal->napi);
+ /* Synchronize with the MAL NAPI poller */
+ napi_synchronize(&mal->napi);
}
void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
@@ -326,7 +330,12 @@ void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
smp_wmb();
clear_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags);
- // XXX might want to kick a poll now...
+ /* Feels better to trigger a poll here to catch up with events that
+ * may have happened on this channel while disabled. It will most
+ * probably be delayed until the next interrupt but that's mostly a
+ * non-issue in the context where this is called.
+ */
+ napi_schedule(&mal->napi);
}
static int mal_poll(struct napi_struct *napi, int budget)
@@ -336,8 +345,7 @@ static int mal_poll(struct napi_struct *napi, int budget)
int received = 0;
unsigned long flags;
- MAL_DBG2(mal, "poll(%d) %d ->" NL, *budget,
- rx_work_limit);
+ MAL_DBG2(mal, "poll(%d)" NL, budget);
again:
/* Process TX skbs */
list_for_each(l, &mal->poll_list) {
@@ -461,6 +469,7 @@ static int __devinit mal_probe(struct of_device *ofdev,
struct mal_instance *mal;
int err = 0, i, bd_size;
int index = mal_count++;
+ unsigned int dcr_base;
const u32 *prop;
u32 cfg;
@@ -497,14 +506,14 @@ static int __devinit mal_probe(struct of_device *ofdev,
}
mal->num_rx_chans = prop[0];
- mal->dcr_base = dcr_resource_start(ofdev->node, 0);
- if (mal->dcr_base == 0) {
+ dcr_base = dcr_resource_start(ofdev->node, 0);
+ if (dcr_base == 0) {
printk(KERN_ERR
"mal%d: can't find DCR resource!\n", index);
err = -ENODEV;
goto fail;
}
- mal->dcr_host = dcr_map(ofdev->node, mal->dcr_base, 0x100);
+ mal->dcr_host = dcr_map(ofdev->node, dcr_base, 0x100);
if (!DCR_MAP_OK(mal->dcr_host)) {
printk(KERN_ERR
"mal%d: failed to map DCRs !\n", index);
@@ -527,11 +536,12 @@ static int __devinit mal_probe(struct of_device *ofdev,
}
INIT_LIST_HEAD(&mal->poll_list);
- mal->napi.weight = CONFIG_IBM_NEW_EMAC_POLL_WEIGHT;
- mal->napi.poll = mal_poll;
INIT_LIST_HEAD(&mal->list);
spin_lock_init(&mal->lock);
+ netif_napi_add(NULL, &mal->napi, mal_poll,
+ CONFIG_IBM_NEW_EMAC_POLL_WEIGHT);
+
/* Load power-on reset defaults */
mal_reset(mal);
@@ -626,7 +636,7 @@ static int __devinit mal_probe(struct of_device *ofdev,
fail2:
dma_free_coherent(&ofdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
fail_unmap:
- dcr_unmap(mal->dcr_host, mal->dcr_base, 0x100);
+ dcr_unmap(mal->dcr_host, 0x100);
fail:
kfree(mal);
diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h
index cb1a16d589f..784edb8ea82 100644
--- a/drivers/net/ibm_newemac/mal.h
+++ b/drivers/net/ibm_newemac/mal.h
@@ -185,7 +185,6 @@ struct mal_commac {
struct mal_instance {
int version;
- int dcr_base;
dcr_host_t dcr_host;
int num_tx_chans; /* Number of TX channels */
@@ -213,12 +212,12 @@ struct mal_instance {
static inline u32 get_mal_dcrn(struct mal_instance *mal, int reg)
{
- return dcr_read(mal->dcr_host, mal->dcr_base + reg);
+ return dcr_read(mal->dcr_host, reg);
}
static inline void set_mal_dcrn(struct mal_instance *mal, int reg, u32 val)
{
- dcr_write(mal->dcr_host, mal->dcr_base + reg, val);
+ dcr_write(mal->dcr_host, reg, val);
}
/* Register MAL devices */
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 3e5eca1aa98..a82d8f98383 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -840,7 +840,7 @@ toshoboe_probe (struct toshoboe_cb *self)
/* test 1: SIR filter and back to back */
- for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j)
+ for (j = 0; j < ARRAY_SIZE(bauds); ++j)
{
int fir = (j > 1);
toshoboe_stopchip (self);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 55ff0fbe525..8c09344f58d 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -23,6 +23,7 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
+#include <linux/clk.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
@@ -87,8 +88,30 @@ struct pxa_irda {
struct device *dev;
struct pxaficp_platform_data *pdata;
+ struct clk *fir_clk;
+ struct clk *sir_clk;
+ struct clk *cur_clk;
};
+static inline void pxa_irda_disable_clk(struct pxa_irda *si)
+{
+ if (si->cur_clk)
+ clk_disable(si->cur_clk);
+ si->cur_clk = NULL;
+}
+
+static inline void pxa_irda_enable_firclk(struct pxa_irda *si)
+{
+ si->cur_clk = si->fir_clk;
+ clk_enable(si->fir_clk);
+}
+
+static inline void pxa_irda_enable_sirclk(struct pxa_irda *si)
+{
+ si->cur_clk = si->sir_clk;
+ clk_enable(si->sir_clk);
+}
+
#define IS_FIR(si) ((si)->speed >= 4000000)
#define IRDA_FRAME_SIZE_LIMIT 2047
@@ -134,7 +157,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
DCSR(si->rxdma) &= ~DCSR_RUN;
/* disable FICP */
ICCR0 = 0;
- pxa_set_cken(CKEN_FICP, 0);
+ pxa_irda_disable_clk(si);
/* set board transceiver to SIR mode */
si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
@@ -144,7 +167,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
pxa_gpio_mode(GPIO47_STTXD_MD);
/* enable the STUART clock */
- pxa_set_cken(CKEN_STUART, 1);
+ pxa_irda_enable_sirclk(si);
}
/* disable STUART first */
@@ -169,7 +192,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
/* disable STUART */
STIER = 0;
STISR = 0;
- pxa_set_cken(CKEN_STUART, 0);
+ pxa_irda_disable_clk(si);
/* disable FICP first */
ICCR0 = 0;
@@ -182,7 +205,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
pxa_gpio_mode(GPIO47_ICPTXD_MD);
/* enable the FICP clock */
- pxa_set_cken(CKEN_FICP, 1);
+ pxa_irda_enable_firclk(si);
si->speed = speed;
pxa_irda_fir_dma_rx_start(si);
@@ -592,16 +615,15 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
STIER = 0;
/* disable STUART SIR mode */
STISR = 0;
- /* disable the STUART clock */
- pxa_set_cken(CKEN_STUART, 0);
/* disable DMA */
DCSR(si->txdma) &= ~DCSR_RUN;
DCSR(si->rxdma) &= ~DCSR_RUN;
/* disable FICP */
ICCR0 = 0;
- /* disable the FICP clock */
- pxa_set_cken(CKEN_FICP, 0);
+
+ /* disable the STUART or FICP clocks */
+ pxa_irda_disable_clk(si);
DRCMR17 = 0;
DRCMR18 = 0;
@@ -792,6 +814,13 @@ static int pxa_irda_probe(struct platform_device *pdev)
si->dev = &pdev->dev;
si->pdata = pdev->dev.platform_data;
+ si->sir_clk = clk_get(&pdev->dev, "UARTCLK");
+ si->fir_clk = clk_get(&pdev->dev, "FICPCLK");
+ if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) {
+ err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk);
+ goto err_mem_4;
+ }
+
/*
* Initialise the SIR buffers
*/
@@ -831,6 +860,10 @@ static int pxa_irda_probe(struct platform_device *pdev)
err_mem_5:
kfree(si->rx_buff.head);
err_mem_4:
+ if (si->sir_clk && !IS_ERR(si->sir_clk))
+ clk_put(si->sir_clk);
+ if (si->fir_clk && !IS_ERR(si->fir_clk))
+ clk_put(si->fir_clk);
free_netdev(dev);
err_mem_3:
release_mem_region(__PREG(FICP), 0x1c);
@@ -850,6 +883,8 @@ static int pxa_irda_remove(struct platform_device *_dev)
unregister_netdev(dev);
kfree(si->tx_buff.head);
kfree(si->rx_buff.head);
+ clk_put(si->fir_clk);
+ clk_put(si->sir_clk);
free_netdev(dev);
}
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index d3825c8ee99..5c154fe1385 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -208,7 +208,6 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
struct sonic_local *lp;
struct resource *res;
int err = 0;
- int i;
DECLARE_MAC_BUF(mac);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index be25aa33971..662b8d16803 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -265,17 +265,16 @@ static __net_init int loopback_net_init(struct net *net)
if (err)
goto out_free_netdev;
- err = 0;
net->loopback_dev = dev;
+ return 0;
-out:
- if (err)
- panic("loopback: Failed to register netdevice: %d\n", err);
- return err;
out_free_netdev:
free_netdev(dev);
- goto out;
+out:
+ if (net == &init_net)
+ panic("loopback: Failed to register netdevice: %d\n", err);
+ return err;
}
static __net_exit void loopback_net_exit(struct net *net)
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index d593175ab6f..37707a0c049 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -7,12 +7,12 @@
#define DEBUG
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
-#include <asm/io.h>
#include <asm/mips-boards/simint.h>
#include "mipsnet.h" /* actual device IO mapping */
@@ -33,9 +33,8 @@ static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
if (available_len < len)
return -EFAULT;
- for (; len > 0; len--, kdata++) {
+ for (; len > 0; len--, kdata++)
*kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
- }
return inl(mipsnet_reg_address(dev, rxDataCount));
}
@@ -47,16 +46,15 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
char *buf_ptr = skb->data;
pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
- dev->name, __FUNCTION__, skb->len);
+ dev->name, __FUNCTION__, skb->len);
outl(skb->len, mipsnet_reg_address(dev, txDataCount));
pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
- dev->name, __FUNCTION__, skb->len);
+ dev->name, __FUNCTION__, skb->len);
- for (; count_to_go; buf_ptr++, count_to_go--) {
+ for (; count_to_go; buf_ptr++, count_to_go--)
outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
- }
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
@@ -67,7 +65,7 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
pr_debug("%s:%s(): transmitting %d bytes\n",
- dev->name, __FUNCTION__, skb->len);
+ dev->name, __FUNCTION__, skb->len);
/* Only one packet at a time. Once TXDONE interrupt is serviced, the
* queue will be restarted.
@@ -83,7 +81,8 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
struct sk_buff *skb;
size_t len = count;
- if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
+ skb = alloc_skb(len + 2, GFP_KERNEL);
+ if (!skb) {
dev->stats.rx_dropped++;
return -ENOMEM;
}
@@ -96,7 +95,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
skb->ip_summed = CHECKSUM_UNNECESSARY;
pr_debug("%s:%s(): pushing RXed data to kernel\n",
- dev->name, __FUNCTION__);
+ dev->name, __FUNCTION__);
netif_rx(skb);
dev->stats.rx_packets++;
@@ -114,42 +113,44 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
if (irq == dev->irq) {
pr_debug("%s:%s(): irq %d for device\n",
- dev->name, __FUNCTION__, irq);
+ dev->name, __FUNCTION__, irq);
retval = IRQ_HANDLED;
interruptFlags =
inl(mipsnet_reg_address(dev, interruptControl));
pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
- __FUNCTION__, interruptFlags);
+ __FUNCTION__, interruptFlags);
if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
pr_debug("%s:%s(): got TXDone\n",
- dev->name, __FUNCTION__);
+ dev->name, __FUNCTION__);
outl(MIPSNET_INTCTL_TXDONE,
mipsnet_reg_address(dev, interruptControl));
- // only one packet at a time, we are done.
+ /* only one packet at a time, we are done. */
netif_wake_queue(dev);
} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
pr_debug("%s:%s(): got RX data\n",
- dev->name, __FUNCTION__);
+ dev->name, __FUNCTION__);
mipsnet_get_fromdev(dev,
- inl(mipsnet_reg_address(dev, rxDataCount)));
+ inl(mipsnet_reg_address(dev, rxDataCount)));
pr_debug("%s:%s(): clearing RX int\n",
- dev->name, __FUNCTION__);
+ dev->name, __FUNCTION__);
outl(MIPSNET_INTCTL_RXDONE,
mipsnet_reg_address(dev, interruptControl));
} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
pr_debug("%s:%s(): got test interrupt\n",
- dev->name, __FUNCTION__);
- // TESTBIT is cleared on read.
- // And takes effect after a write with 0
+ dev->name, __FUNCTION__);
+ /*
+ * TESTBIT is cleared on read.
+ * And takes effect after a write with 0
+ */
outl(0, mipsnet_reg_address(dev, interruptControl));
} else {
pr_debug("%s:%s(): no valid fags 0x%016llx\n",
- dev->name, __FUNCTION__, interruptFlags);
- // Maybe shared IRQ, just ignore, no clearing.
+ dev->name, __FUNCTION__, interruptFlags);
+ /* Maybe shared IRQ, just ignore, no clearing. */
retval = IRQ_NONE;
}
@@ -159,7 +160,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
retval = IRQ_NONE;
}
return retval;
-} //mipsnet_interrupt()
+}
static int mipsnet_open(struct net_device *dev)
{
@@ -171,18 +172,18 @@ static int mipsnet_open(struct net_device *dev)
if (err) {
pr_debug("%s: %s(): can't get irq %d\n",
- dev->name, __FUNCTION__, dev->irq);
+ dev->name, __FUNCTION__, dev->irq);
release_region(dev->base_addr, MIPSNET_IO_EXTENT);
return err;
}
pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
- dev->name, __FUNCTION__, dev->base_addr, dev->irq);
+ dev->name, __FUNCTION__, dev->base_addr, dev->irq);
netif_start_queue(dev);
- // test interrupt handler
+ /* test interrupt handler */
outl(MIPSNET_INTCTL_TESTBIT,
mipsnet_reg_address(dev, interruptControl));
@@ -199,8 +200,6 @@ static int mipsnet_close(struct net_device *dev)
static void mipsnet_set_mclist(struct net_device *dev)
{
- // we don't do anything
- return;
}
static int __init mipsnet_probe(struct device *dev)
@@ -226,13 +225,13 @@ static int __init mipsnet_probe(struct device *dev)
*/
netdev->base_addr = 0x4200;
netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 +
- inl(mipsnet_reg_address(netdev, interruptInfo));
+ inl(mipsnet_reg_address(netdev, interruptInfo));
- // Get the io region now, get irq on open()
+ /* Get the io region now, get irq on open() */
if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
- "for dev is not availble.\n", netdev->name,
- __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
+ "for dev is not availble.\n", netdev->name,
+ __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
err = -EBUSY;
goto out_free_netdev;
}
diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
index 026c732024c..0132c6714a4 100644
--- a/drivers/net/mipsnet.h
+++ b/drivers/net/mipsnet.h
@@ -9,32 +9,34 @@
/*
* Id of this Net device, as seen by the core.
*/
-#define MIPS_NET_DEV_ID ((uint64_t) \
- ((uint64_t)'M'<< 0)| \
- ((uint64_t)'I'<< 8)| \
- ((uint64_t)'P'<<16)| \
- ((uint64_t)'S'<<24)| \
- ((uint64_t)'N'<<32)| \
- ((uint64_t)'E'<<40)| \
- ((uint64_t)'T'<<48)| \
- ((uint64_t)'0'<<56))
+#define MIPS_NET_DEV_ID ((uint64_t) \
+ ((uint64_t) 'M' << 0)| \
+ ((uint64_t) 'I' << 8)| \
+ ((uint64_t) 'P' << 16)| \
+ ((uint64_t) 'S' << 24)| \
+ ((uint64_t) 'N' << 32)| \
+ ((uint64_t) 'E' << 40)| \
+ ((uint64_t) 'T' << 48)| \
+ ((uint64_t) '0' << 56))
/*
* Net status/control block as seen by sw in the core.
* (Why not use bit fields? can't be bothered with cross-platform struct
* packing.)
*/
-typedef struct _net_control_block {
- /// dev info for probing
- /// reads as MIPSNET%d where %d is some form of version
- uint64_t devId; /*0x00 */
+struct net_control_block {
+ /*
+ * dev info for probing
+ * reads as MIPSNET%d where %d is some form of version
+ */
+ uint64_t devId; /* 0x00 */
/*
* read only busy flag.
* Set and cleared by the Net Device to indicate that an rx or a tx
* is in progress.
*/
- uint32_t busy; /*0x08 */
+ uint32_t busy; /* 0x08 */
/*
* Set by the Net Device.
@@ -43,16 +45,16 @@ typedef struct _net_control_block {
* rxDataBuffer. The value will decrease till 0 until all the data
* from rxDataBuffer has been read.
*/
- uint32_t rxDataCount; /*0x0c */
+ uint32_t rxDataCount; /* 0x0c */
#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
/*
- * Settable from the MIPS core, cleared by the Net Device.
- * The core should set the number of bytes it wants to send,
- * then it should write those bytes of data to txDataBuffer.
- * The device will clear txDataCount has been processed (not necessarily sent).
+ * Settable from the MIPS core, cleared by the Net Device. The core
+ * should set the number of bytes it wants to send, then it should
+ * write those bytes of data to txDataBuffer. The device will clear
+ * txDataCount has been processed (not necessarily sent).
*/
- uint32_t txDataCount; /*0x10 */
+ uint32_t txDataCount; /* 0x10 */
/*
* Interrupt control
@@ -69,39 +71,42 @@ typedef struct _net_control_block {
* To clear the test interrupt, write 0 to this register.
*/
uint32_t interruptControl; /*0x14 */
-#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1<< 0))
-#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1<< 1))
-#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1<<31))
-#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
+#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1 << 0))
+#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1 << 1))
+#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1 << 31))
+#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE | \
+ MIPSNET_INTCTL_RXDONE | \
+ MIPSNET_INTCTL_TESTBIT)
/*
- * Readonly core-specific interrupt info for the device to signal the core.
- * The meaning of the contents of this field might change.
- */
- /*###\todo: the whole memIntf interrupt scheme is messy: the device should have
- * no control what so ever of what VPE/register set is being used.
- * The MemIntf should only expose interrupt lines, and something in the
- * config should be responsible for the line<->core/vpe bindings.
+ * Readonly core-specific interrupt info for the device to signal the
+ * core. The meaning of the contents of this field might change.
+ *
+ * TODO: the whole memIntf interrupt scheme is messy: the device should
+ * have no control what so ever of what VPE/register set is being
+ * used. The MemIntf should only expose interrupt lines, and
+ * something in the config should be responsible for the
+ * line<->core/vpe bindings.
*/
- uint32_t interruptInfo; /*0x18 */
+ uint32_t interruptInfo; /* 0x18 */
/*
* This is where the received data is read out.
* There is more data to read until rxDataReady is 0.
* Only 1 byte at this regs offset is used.
*/
- uint32_t rxDataBuffer; /*0x1c */
+ uint32_t rxDataBuffer; /* 0x1c */
/*
- * This is where the data to transmit is written.
- * Data should be written for the amount specified in the txDataCount register.
- * Only 1 byte at this regs offset is used.
+ * This is where the data to transmit is written. Data should be
+ * written for the amount specified in the txDataCount register. Only
+ * 1 byte at this regs offset is used.
*/
- uint32_t txDataBuffer; /*0x20 */
-} MIPS_T_NetControl;
+ uint32_t txDataBuffer; /* 0x20 */
+};
#define MIPSNET_IO_EXTENT 0x40 /* being generous */
-#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
+#define field_offset(field) (offsetof(struct net_control_block, field))
#endif /* __MIPSNET_H */
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e8afa101433..366e62a2b1e 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.3.2-1.269"
+#define MYRI10GE_VERSION_STR "1.3.2-1.287"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -214,6 +214,8 @@ struct myri10ge_priv {
unsigned long serial_number;
int vendor_specific_offset;
int fw_multicast_support;
+ unsigned long features;
+ u32 max_tso6;
u32 read_dma;
u32 write_dma;
u32 read_write_dma;
@@ -311,6 +313,7 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
static void myri10ge_set_multicast_list(struct net_device *dev);
+static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev);
static inline void put_be32(__be32 val, __be32 __iomem * p)
{
@@ -612,6 +615,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
__be32 buf[16];
u32 dma_low, dma_high, size;
int status, i;
+ struct myri10ge_cmd cmd;
size = 0;
status = myri10ge_load_hotplug_firmware(mgp, &size);
@@ -688,6 +692,14 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
dev_info(&mgp->pdev->dev, "handoff confirmed\n");
myri10ge_dummy_rdma(mgp, 1);
+ /* probe for IPv6 TSO support */
+ mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+ &cmd, 0);
+ if (status == 0) {
+ mgp->max_tso6 = cmd.data0;
+ mgp->features |= NETIF_F_TSO6;
+ }
return 0;
}
@@ -1047,7 +1059,8 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
- /* allocate an skb to attach the page(s) to. */
+ /* allocate an skb to attach the page(s) to. This is done
+ * after trying LRO, so as to avoid skb allocation overheads */
skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16);
if (unlikely(skb == NULL)) {
@@ -1217,7 +1230,8 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
static int myri10ge_poll(struct napi_struct *napi, int budget)
{
- struct myri10ge_priv *mgp = container_of(napi, struct myri10ge_priv, napi);
+ struct myri10ge_priv *mgp =
+ container_of(napi, struct myri10ge_priv, napi);
struct net_device *netdev = mgp->dev;
struct myri10ge_rx_done *rx_done = &mgp->rx_done;
int work_done;
@@ -1382,6 +1396,18 @@ static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
return 0;
}
+static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
+{
+ struct myri10ge_priv *mgp = netdev_priv(netdev);
+ unsigned long flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO);
+
+ if (tso_enabled)
+ netdev->features |= flags;
+ else
+ netdev->features &= ~flags;
+ return 0;
+}
+
static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -1506,7 +1532,7 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
.set_rx_csum = myri10ge_set_rx_csum,
.set_tx_csum = ethtool_op_set_tx_hw_csum,
.set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
+ .set_tso = myri10ge_set_tso,
.get_link = ethtool_op_get_link,
.get_strings = myri10ge_get_strings,
.get_sset_count = myri10ge_get_sset_count,
@@ -2164,7 +2190,8 @@ again:
pseudo_hdr_offset = cksum_offset + skb->csum_offset;
/* If the headers are excessively large, then we must
* fall back to a software checksum */
- if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) {
+ if (unlikely(!mss && (cksum_offset > 255 ||
+ pseudo_hdr_offset > 127))) {
if (skb_checksum_help(skb))
goto drop;
cksum_offset = 0;
@@ -2184,9 +2211,18 @@ again:
/* negative cum_len signifies to the
* send loop that we are still in the
* header portion of the TSO packet.
- * TSO header must be at most 134 bytes long */
+ * TSO header can be at most 1KB long */
cum_len = -(skb_transport_offset(skb) + tcp_hdrlen(skb));
+ /* for IPv6 TSO, the checksum offset stores the
+ * TCP header length, to save the firmware from
+ * the need to parse the headers */
+ if (skb_is_gso_v6(skb)) {
+ cksum_offset = tcp_hdrlen(skb);
+ /* Can only handle headers <= max_tso6 long */
+ if (unlikely(-cum_len > mgp->max_tso6))
+ return myri10ge_sw_tso(skb, dev);
+ }
/* for TSO, pseudo_hdr_offset holds mss.
* The firmware figures out where to put
* the checksum by parsing the header. */
@@ -2301,10 +2337,12 @@ again:
req++;
count++;
rdma_count++;
- if (unlikely(cksum_offset > seglen))
- cksum_offset -= seglen;
- else
- cksum_offset = 0;
+ if (cksum_offset != 0 && !(mss && skb_is_gso_v6(skb))) {
+ if (unlikely(cksum_offset > seglen))
+ cksum_offset -= seglen;
+ else
+ cksum_offset = 0;
+ }
}
if (frag_idx == frag_cnt)
break;
@@ -2387,6 +2425,41 @@ drop:
}
+static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
+{
+ struct sk_buff *segs, *curr;
+ struct myri10ge_priv *mgp = dev->priv;
+ int status;
+
+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
+ if (unlikely(IS_ERR(segs)))
+ goto drop;
+
+ while (segs) {
+ curr = segs;
+ segs = segs->next;
+ curr->next = NULL;
+ status = myri10ge_xmit(curr, dev);
+ if (status != 0) {
+ dev_kfree_skb_any(curr);
+ if (segs != NULL) {
+ curr = segs;
+ segs = segs->next;
+ curr->next = NULL;
+ dev_kfree_skb_any(segs);
+ }
+ goto drop;
+ }
+ }
+ dev_kfree_skb_any(skb);
+ return 0;
+
+drop:
+ dev_kfree_skb_any(skb);
+ mgp->stats.tx_dropped += 1;
+ return 0;
+}
+
static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
{
struct myri10ge_priv *mgp = netdev_priv(dev);
@@ -2706,7 +2779,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
}
#ifdef CONFIG_PM
-
static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct myri10ge_priv *mgp;
@@ -2787,7 +2859,6 @@ abort_with_enabled:
return -EIO;
}
-
#endif /* CONFIG_PM */
static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
@@ -2954,8 +3025,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp = netdev_priv(netdev);
mgp->dev = netdev;
- netif_napi_add(netdev, &mgp->napi,
- myri10ge_poll, myri10ge_napi_weight);
+ netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight);
mgp->pdev = pdev;
mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
mgp->pause = myri10ge_flow_control;
@@ -2988,7 +3058,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (status != 0) {
dac_enabled = 0;
dev_err(&pdev->dev,
- "64-bit pci address mask was refused, trying 32-bit");
+ "64-bit pci address mask was refused, "
+ "trying 32-bit\n");
status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
}
if (status != 0) {
@@ -3077,7 +3148,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->change_mtu = myri10ge_change_mtu;
netdev->set_multicast_list = myri10ge_set_multicast_list;
netdev->set_mac_address = myri10ge_set_mac_address;
- netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+ netdev->features = mgp->features;
if (dac_enabled)
netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index a1d2a22296a..58e57178c56 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -10,7 +10,7 @@ struct mcp_dma_addr {
__be32 low;
};
-/* 4 Bytes */
+/* 4 Bytes. 8 Bytes for NDIS drivers. */
struct mcp_slot {
__sum16 checksum;
__be16 length;
@@ -205,8 +205,87 @@ enum myri10ge_mcp_cmd_type {
/* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
* chipset */
- MXGEFW_CMD_UNALIGNED_STATUS
- /* return data = boolean, true if the chipset is known to be unaligned */
+ MXGEFW_CMD_UNALIGNED_STATUS,
+ /* return data = boolean, true if the chipset is known to be unaligned */
+
+ MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
+ /* data0 = number of big buffers to use. It must be 0 or a power of 2.
+ * 0 indicates that the NIC consumes as many buffers as they are required
+ * for packet. This is the default behavior.
+ * A power of 2 number indicates that the NIC always uses the specified
+ * number of buffers for each big receive packet.
+ * It is up to the driver to ensure that this value is big enough for
+ * the NIC to be able to receive maximum-sized packets.
+ */
+
+ MXGEFW_CMD_GET_MAX_RSS_QUEUES,
+ MXGEFW_CMD_ENABLE_RSS_QUEUES,
+ /* data0 = number of slices n (0, 1, ..., n-1) to enable
+ * data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue.
+ * If all queues share one interrupt, the driver must have set
+ * RSS_SHARED_INTERRUPT_DMA before enabling queues.
+ */
+ MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
+ MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
+ /* data0, data1 = bus address lsw, msw */
+ MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
+ /* get the offset of the indirection table */
+ MXGEFW_CMD_SET_RSS_TABLE_SIZE,
+ /* set the size of the indirection table */
+ MXGEFW_CMD_GET_RSS_KEY_OFFSET,
+ /* get the offset of the secret key */
+ MXGEFW_CMD_RSS_KEY_UPDATED,
+ /* tell nic that the secret key's been updated */
+ MXGEFW_CMD_SET_RSS_ENABLE,
+ /* data0 = enable/disable rss
+ * 0: disable rss. nic does not distribute receive packets.
+ * 1: enable rss. nic distributes receive packets among queues.
+ * data1 = hash type
+ * 1: IPV4
+ * 2: TCP_IPV4
+ * 3: IPV4 | TCP_IPV4
+ */
+
+ MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+ /* Return data = the max. size of the entire headers of a IPv6 TSO packet.
+ * If the header size of a IPv6 TSO packet is larger than the specified
+ * value, then the driver must not use TSO.
+ * This size restriction only applies to IPv6 TSO.
+ * For IPv4 TSO, the maximum size of the headers is fixed, and the NIC
+ * always has enough header buffer to store maximum-sized headers.
+ */
+
+ MXGEFW_CMD_SET_TSO_MODE,
+ /* data0 = TSO mode.
+ * 0: Linux/FreeBSD style (NIC default)
+ * 1: NDIS/NetBSD style
+ */
+
+ MXGEFW_CMD_MDIO_READ,
+ /* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
+ MXGEFW_CMD_MDIO_WRITE,
+ /* data0 = dev_addr, data1 = register/addr, data2 = value */
+
+ MXGEFW_CMD_XFP_I2C_READ,
+ /* Starts to get a fresh copy of one byte or of the whole xfp i2c table, the
+ * obtained data is cached inside the xaui-xfi chip :
+ * data0 : "all" flag : 0 => get one byte, 1=> get 256 bytes,
+ * data1 : if (data0 == 0): index of byte to refresh [ not used otherwise ]
+ * The operation might take ~1ms for a single byte or ~65ms when refreshing all 256 bytes
+ * During the i2c operation, MXGEFW_CMD_XFP_I2C_READ or MXGEFW_CMD_XFP_BYTE attempts
+ * will return MXGEFW_CMD_ERROR_BUSY
+ */
+ MXGEFW_CMD_XFP_BYTE,
+ /* Return the last obtained copy of a given byte in the xfp i2c table
+ * (copy cached during the last relevant MXGEFW_CMD_XFP_I2C_READ)
+ * data0 : index of the desired table entry
+ * Return data = the byte stored at the requested index in the table
+ */
+
+ MXGEFW_CMD_GET_VPUMP_OFFSET,
+ /* Return data = NIC memory offset of mcp_vpump_public_global */
+ MXGEFW_CMD_RESET_VPUMP,
+ /* Resets the VPUMP state */
};
enum myri10ge_mcp_cmd_status {
@@ -220,7 +299,10 @@ enum myri10ge_mcp_cmd_status {
MXGEFW_CMD_ERROR_BAD_PORT,
MXGEFW_CMD_ERROR_RESOURCES,
MXGEFW_CMD_ERROR_MULTICAST,
- MXGEFW_CMD_ERROR_UNALIGNED
+ MXGEFW_CMD_ERROR_UNALIGNED,
+ MXGEFW_CMD_ERROR_NO_MDIO,
+ MXGEFW_CMD_ERROR_XFP_FAILURE,
+ MXGEFW_CMD_ERROR_XFP_ABSENT
};
#define MXGEFW_OLD_IRQ_DATA_LEN 40
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 527f9dcc7f6..50e1ec67ef9 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1576,7 +1576,7 @@ static int netdev_open(struct net_device *dev)
/* Set the timer to check for link beat. */
init_timer(&np->timer);
- np->timer.expires = jiffies + NATSEMI_TIMER_FREQ;
+ np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ);
np->timer.data = (unsigned long)dev;
np->timer.function = &netdev_timer; /* timer handler */
add_timer(&np->timer);
@@ -1856,7 +1856,11 @@ static void netdev_timer(unsigned long data)
next_tick = 1;
}
}
- mod_timer(&np->timer, jiffies + next_tick);
+
+ if (next_tick > 1)
+ mod_timer(&np->timer, round_jiffies(jiffies + next_tick));
+ else
+ mod_timer(&np->timer, jiffies + next_tick);
}
static void dump_ring(struct net_device *dev)
@@ -3310,13 +3314,19 @@ static int natsemi_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
struct netdev_private *np = netdev_priv(dev);
+ int ret = 0;
rtnl_lock();
if (netif_device_present(dev))
goto out;
if (netif_running(dev)) {
BUG_ON(!np->hands_off);
- pci_enable_device(pdev);
+ ret = pci_enable_device(pdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "pci_enable_device() failed: %d\n", ret);
+ goto out;
+ }
/* pci_power_on(pdev); */
napi_enable(&np->napi);
@@ -3331,12 +3341,12 @@ static int natsemi_resume (struct pci_dev *pdev)
spin_unlock_irq(&np->lock);
enable_irq(dev->irq);
- mod_timer(&np->timer, jiffies + 1*HZ);
+ mod_timer(&np->timer, round_jiffies(jiffies + 1*HZ));
}
netif_device_attach(dev);
out:
rtnl_unlock();
- return 0;
+ return ret;
}
#endif /* CONFIG_PM */
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
index 368f2560856..fbc7531d3c7 100644
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -93,7 +93,7 @@ static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr
bus_width = *(volatile unsigned char *)ABWCR;
bus_width &= 1 << ((base_addr >> 21) & 7);
- for (i = 0; i < sizeof(reg_offset) / sizeof(u32); i++)
+ for (i = 0; i < ARRAY_SIZE(reg_offset); i++)
if (bus_width == 0)
reg_offset[i] = i * 2 + 1;
else
@@ -115,7 +115,7 @@ static int h8300_ne_irq[] = {EXT_IRQ5};
static inline int init_dev(struct net_device *dev)
{
- if (h8300_ne_count < (sizeof(h8300_ne_base) / sizeof(unsigned long))) {
+ if (h8300_ne_count < ARRAY_SIZE(h8300_ne_base)) {
dev->base_addr = h8300_ne_base[h8300_ne_count];
dev->irq = h8300_ne_irq[h8300_ne_count];
h8300_ne_count++;
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2a1d6d7ec35..601051c584e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -53,9 +53,6 @@ static char netxen_nic_driver_string[] = "NetXen Network Driver version "
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
-#define DMA_32BIT_MASK 0x00000000ffffffffULL
-#define DMA_35BIT_MASK 0x00000007ffffffffULL
-
/* Local functions to NetXen NIC driver */
static int __devinit netxen_nic_probe(struct pci_dev *pdev,
const struct pci_device_id *ent);
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 43bfe7e6b6f..ed1f9bbb2a3 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -6123,19 +6123,19 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
val = nr64(ESPC_PHY_TYPE);
switch (np->port) {
case 0:
- val = (val & ESPC_PHY_TYPE_PORT0) >>
+ val8 = (val & ESPC_PHY_TYPE_PORT0) >>
ESPC_PHY_TYPE_PORT0_SHIFT;
break;
case 1:
- val = (val & ESPC_PHY_TYPE_PORT1) >>
+ val8 = (val & ESPC_PHY_TYPE_PORT1) >>
ESPC_PHY_TYPE_PORT1_SHIFT;
break;
case 2:
- val = (val & ESPC_PHY_TYPE_PORT2) >>
+ val8 = (val & ESPC_PHY_TYPE_PORT2) >>
ESPC_PHY_TYPE_PORT2_SHIFT;
break;
case 3:
- val = (val & ESPC_PHY_TYPE_PORT3) >>
+ val8 = (val & ESPC_PHY_TYPE_PORT3) >>
ESPC_PHY_TYPE_PORT3_SHIFT;
break;
default:
@@ -6143,9 +6143,9 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
np->port);
return -EINVAL;
}
- niudbg(PROBE, "SPROM: PHY type %llx\n", (unsigned long long) val);
+ niudbg(PROBE, "SPROM: PHY type %x\n", val8);
- switch (val) {
+ switch (val8) {
case ESPC_PHY_TYPE_1G_COPPER:
/* 1G copper, MII */
np->flags &= ~(NIU_FLAGS_FIBER |
@@ -6175,8 +6175,7 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
break;
default:
- dev_err(np->device, PFX "Bogus SPROM phy type %llu\n",
- (unsigned long long) val);
+ dev_err(np->device, PFX "Bogus SPROM phy type %u\n", val8);
return -EINVAL;
}
@@ -6213,7 +6212,7 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
val = nr64(ESPC_MOD_STR_LEN);
niudbg(PROBE, "SPROM: MOD_STR_LEN[%llu]\n",
(unsigned long long) val);
- if (val > 8 * 4)
+ if (val >= 8 * 4)
return -EINVAL;
for (i = 0; i < val; i += 4) {
@@ -6229,7 +6228,7 @@ static int __devinit niu_pci_probe_sprom(struct niu *np)
val = nr64(ESPC_BD_MOD_STR_LEN);
niudbg(PROBE, "SPROM: BD_MOD_STR_LEN[%llu]\n",
(unsigned long long) val);
- if (val > 4 * 4)
+ if (val >= 4 * 4)
return -EINVAL;
for (i = 0; i < val; i += 4) {
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 5f994b5beda..ff92aca0a7b 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -282,7 +282,6 @@ struct pcnet32_private {
struct net_device *dev;
struct napi_struct napi;
- struct net_device_stats stats;
char tx_full;
char phycount; /* number of phys found */
int options;
@@ -442,7 +441,9 @@ static struct pcnet32_access pcnet32_dwio = {
static void pcnet32_netif_stop(struct net_device *dev)
{
+#ifdef CONFIG_PCNET32_NAPI
struct pcnet32_private *lp = netdev_priv(dev);
+#endif
dev->trans_start = jiffies;
#ifdef CONFIG_PCNET32_NAPI
napi_disable(&lp->napi);
@@ -452,7 +453,9 @@ static void pcnet32_netif_stop(struct net_device *dev)
static void pcnet32_netif_start(struct net_device *dev)
{
+#ifdef CONFIG_PCNET32_NAPI
struct pcnet32_private *lp = netdev_priv(dev);
+#endif
netif_wake_queue(dev);
#ifdef CONFIG_PCNET32_NAPI
napi_enable(&lp->napi);
@@ -1178,15 +1181,15 @@ static void pcnet32_rx_entry(struct net_device *dev,
* buffers, with only the last correctly noting the error.
*/
if (status & 0x01) /* Only count a general error at the */
- lp->stats.rx_errors++; /* end of a packet. */
+ dev->stats.rx_errors++; /* end of a packet. */
if (status & 0x20)
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & 0x10)
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
if (status & 0x08)
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (status & 0x04)
- lp->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
return;
}
@@ -1197,13 +1200,13 @@ static void pcnet32_rx_entry(struct net_device *dev,
if (netif_msg_drv(lp))
printk(KERN_ERR "%s: Impossible packet size %d!\n",
dev->name, pkt_len);
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
if (pkt_len < 60) {
if (netif_msg_rx_err(lp))
printk(KERN_ERR "%s: Runt packet!\n", dev->name);
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
@@ -1237,7 +1240,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
printk(KERN_ERR
"%s: Memory squeeze, dropping packet.\n",
dev->name);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb->dev = dev;
@@ -1256,7 +1259,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
pkt_len,
PCI_DMA_FROMDEVICE);
}
- lp->stats.rx_bytes += skb->len;
+ dev->stats.rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, dev);
#ifdef CONFIG_PCNET32_NAPI
netif_receive_skb(skb);
@@ -1264,7 +1267,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
netif_rx(skb);
#endif
dev->last_rx = jiffies;
- lp->stats.rx_packets++;
+ dev->stats.rx_packets++;
return;
}
@@ -1312,21 +1315,21 @@ static int pcnet32_tx(struct net_device *dev)
if (status & 0x4000) {
/* There was a major error, log it. */
int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (netif_msg_tx_err(lp))
printk(KERN_ERR
"%s: Tx error status=%04x err_status=%08x\n",
dev->name, status,
err_status);
if (err_status & 0x04000000)
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
if (err_status & 0x08000000)
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (err_status & 0x10000000)
- lp->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
#ifndef DO_DXSUFLO
if (err_status & 0x40000000) {
- lp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
/* Ackk! On FIFO errors the Tx unit is turned off! */
/* Remove this verbosity later! */
if (netif_msg_tx_err(lp))
@@ -1337,7 +1340,7 @@ static int pcnet32_tx(struct net_device *dev)
}
#else
if (err_status & 0x40000000) {
- lp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (!lp->dxsuflo) { /* If controller doesn't recover ... */
/* Ackk! On FIFO errors the Tx unit is turned off! */
/* Remove this verbosity later! */
@@ -1351,8 +1354,8 @@ static int pcnet32_tx(struct net_device *dev)
#endif
} else {
if (status & 0x1800)
- lp->stats.collisions++;
- lp->stats.tx_packets++;
+ dev->stats.collisions++;
+ dev->stats.tx_packets++;
}
/* We must free the original skb */
@@ -1849,6 +1852,9 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
lp->mii_if.mdio_read = mdio_read;
lp->mii_if.mdio_write = mdio_write;
+ /* napi.weight is used in both the napi and non-napi cases */
+ lp->napi.weight = lp->rx_ring_size / 2;
+
#ifdef CONFIG_PCNET32_NAPI
netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
#endif
@@ -2471,7 +2477,7 @@ static void pcnet32_tx_timeout(struct net_device *dev)
"%s: transmit timed out, status %4.4x, resetting.\n",
dev->name, lp->a.read_csr(ioaddr, CSR0));
lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (netif_msg_tx_err(lp)) {
int i;
printk(KERN_DEBUG
@@ -2541,7 +2547,7 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->tx_ring[entry].status = cpu_to_le16(status);
lp->cur_tx++;
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* Trigger an immediate send poll. */
lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
@@ -2586,7 +2592,7 @@ pcnet32_interrupt(int irq, void *dev_id)
/* Log misc errors. */
if (csr0 & 0x4000)
- lp->stats.tx_errors++; /* Tx babble. */
+ dev->stats.tx_errors++; /* Tx babble. */
if (csr0 & 0x1000) {
/*
* This happens when our receive ring is full. This
@@ -2599,7 +2605,7 @@ pcnet32_interrupt(int irq, void *dev_id)
* don't get a rx interrupt, but a missed frame
* interrupt sooner or later.
*/
- lp->stats.rx_errors++; /* Missed a Rx frame. */
+ dev->stats.rx_errors++; /* Missed a Rx frame. */
}
if (csr0 & 0x0800) {
if (netif_msg_drv(lp))
@@ -2661,7 +2667,7 @@ static int pcnet32_close(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+ dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
if (netif_msg_ifdown(lp))
printk(KERN_DEBUG
@@ -2698,10 +2704,10 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
unsigned long flags;
spin_lock_irqsave(&lp->lock, flags);
- lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+ dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
spin_unlock_irqrestore(&lp->lock, flags);
- return &lp->stats;
+ return &dev->stats;
}
/* taken from the sunlance driver, which it took from the depca driver */
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/saa9730.c b/drivers/net/saa9730.c
index 14361e88541..c65199df8a7 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -97,13 +97,16 @@ static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
&lp->evm_saa9730_regs->InterruptBlock1);
}
-static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
+static void __used show_saa9730_regs(struct net_device *dev)
{
+ struct lan_saa9730_private *lp = netdev_priv(dev);
int i, j;
+
printk("TxmBufferA = %p\n", lp->TxmBuffer[0][0]);
printk("TxmBufferB = %p\n", lp->TxmBuffer[1][0]);
printk("RcvBufferA = %p\n", lp->RcvBuffer[0][0]);
printk("RcvBufferB = %p\n", lp->RcvBuffer[1][0]);
+
for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
printk("TxmBuffer[%d][%d] = %x\n", i, j,
@@ -146,11 +149,13 @@ static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
readl(&lp->lan_saa9730_regs->RxCtl));
printk("lp->lan_saa9730_regs->RxStatus = %x\n",
readl(&lp->lan_saa9730_regs->RxStatus));
+
for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
writel(i, &lp->lan_saa9730_regs->CamAddress);
printk("lp->lan_saa9730_regs->CamData = %x\n",
readl(&lp->lan_saa9730_regs->CamData));
}
+
printk("dev->stats.tx_packets = %lx\n", dev->stats.tx_packets);
printk("dev->stats.tx_errors = %lx\n", dev->stats.tx_errors);
printk("dev->stats.tx_aborted_errors = %lx\n",
@@ -855,7 +860,7 @@ static void lan_saa9730_tx_timeout(struct net_device *dev)
/* Transmitter timeout, serious problems */
dev->stats.tx_errors++;
printk("%s: transmit timed out, reset\n", dev->name);
- /*show_saa9730_regs(lp); */
+ /*show_saa9730_regs(dev); */
lan_saa9730_restart(lp);
dev->trans_start = jiffies;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 2aae9fe38c5..b9961dc4760 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -36,13 +36,15 @@
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
#include <linux/mii.h>
#include <asm/irq.h>
#include "skge.h"
#define DRV_NAME "skge"
-#define DRV_VERSION "1.11"
+#define DRV_VERSION "1.12"
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
@@ -57,7 +59,10 @@
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define BLINK_MS 250
-#define LINK_HZ (HZ/2)
+#define LINK_HZ HZ
+
+#define SKGE_EEPROM_MAGIC 0x9933aabb
+
MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
@@ -445,15 +450,15 @@ static struct net_device_stats *skge_get_stats(struct net_device *dev)
else
yukon_get_stats(skge, data);
- skge->net_stats.tx_bytes = data[0];
- skge->net_stats.rx_bytes = data[1];
- skge->net_stats.tx_packets = data[2] + data[4] + data[6];
- skge->net_stats.rx_packets = data[3] + data[5] + data[7];
- skge->net_stats.multicast = data[3] + data[5];
- skge->net_stats.collisions = data[10];
- skge->net_stats.tx_aborted_errors = data[12];
+ dev->stats.tx_bytes = data[0];
+ dev->stats.rx_bytes = data[1];
+ dev->stats.tx_packets = data[2] + data[4] + data[6];
+ dev->stats.rx_packets = data[3] + data[5] + data[7];
+ dev->stats.multicast = data[3] + data[5];
+ dev->stats.collisions = data[10];
+ dev->stats.tx_aborted_errors = data[12];
- return &skge->net_stats;
+ return &dev->stats;
}
static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -798,6 +803,98 @@ static int skge_phys_id(struct net_device *dev, u32 data)
return 0;
}
+static int skge_get_eeprom_len(struct net_device *dev)
+{
+ struct skge_port *skge = netdev_priv(dev);
+ u32 reg2;
+
+ pci_read_config_dword(skge->hw->pdev, PCI_DEV_REG2, &reg2);
+ return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+}
+
+static u32 skge_vpd_read(struct pci_dev *pdev, int cap, u16 offset)
+{
+ u32 val;
+
+ pci_write_config_word(pdev, cap + PCI_VPD_ADDR, offset);
+
+ do {
+ pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
+ } while (!(offset & PCI_VPD_ADDR_F));
+
+ pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &val);
+ return val;
+}
+
+static void skge_vpd_write(struct pci_dev *pdev, int cap, u16 offset, u32 val)
+{
+ pci_write_config_dword(pdev, cap + PCI_VPD_DATA, val);
+ pci_write_config_word(pdev, cap + PCI_VPD_ADDR,
+ offset | PCI_VPD_ADDR_F);
+
+ do {
+ pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
+ } while (offset & PCI_VPD_ADDR_F);
+}
+
+static int skge_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+ u8 *data)
+{
+ struct skge_port *skge = netdev_priv(dev);
+ struct pci_dev *pdev = skge->hw->pdev;
+ int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD);
+ int length = eeprom->len;
+ u16 offset = eeprom->offset;
+
+ if (!cap)
+ return -EINVAL;
+
+ eeprom->magic = SKGE_EEPROM_MAGIC;
+
+ while (length > 0) {
+ u32 val = skge_vpd_read(pdev, cap, offset);
+ int n = min_t(int, length, sizeof(val));
+
+ memcpy(data, &val, n);
+ length -= n;
+ data += n;
+ offset += n;
+ }
+ return 0;
+}
+
+static int skge_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+ u8 *data)
+{
+ struct skge_port *skge = netdev_priv(dev);
+ struct pci_dev *pdev = skge->hw->pdev;
+ int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD);
+ int length = eeprom->len;
+ u16 offset = eeprom->offset;
+
+ if (!cap)
+ return -EINVAL;
+
+ if (eeprom->magic != SKGE_EEPROM_MAGIC)
+ return -EINVAL;
+
+ while (length > 0) {
+ u32 val;
+ int n = min_t(int, length, sizeof(val));
+
+ if (n < sizeof(val))
+ val = skge_vpd_read(pdev, cap, offset);
+ memcpy(&val, data, n);
+
+ skge_vpd_write(pdev, cap, offset, val);
+
+ length -= n;
+ data += n;
+ offset += n;
+ }
+ return 0;
+}
+
static const struct ethtool_ops skge_ethtool_ops = {
.get_settings = skge_get_settings,
.set_settings = skge_set_settings,
@@ -810,6 +907,9 @@ static const struct ethtool_ops skge_ethtool_ops = {
.set_msglevel = skge_set_msglevel,
.nway_reset = skge_nway_reset,
.get_link = ethtool_op_get_link,
+ .get_eeprom_len = skge_get_eeprom_len,
+ .get_eeprom = skge_get_eeprom,
+ .set_eeprom = skge_set_eeprom,
.get_ringparam = skge_get_ring_param,
.set_ringparam = skge_set_ring_param,
.get_pauseparam = skge_get_pauseparam,
@@ -995,19 +1095,15 @@ static void xm_link_down(struct skge_hw *hw, int port)
{
struct net_device *dev = hw->dev[port];
struct skge_port *skge = netdev_priv(dev);
- u16 cmd, msk;
+ u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
- if (hw->phy_type == SK_PHY_XMAC) {
- msk = xm_read16(hw, port, XM_IMSK);
- msk |= XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND;
- xm_write16(hw, port, XM_IMSK, msk);
- }
+ xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);
- cmd = xm_read16(hw, port, XM_MMU_CMD);
cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
xm_write16(hw, port, XM_MMU_CMD, cmd);
+
/* dummy read to ensure writing */
- (void) xm_read16(hw, port, XM_MMU_CMD);
+ xm_read16(hw, port, XM_MMU_CMD);
if (netif_carrier_ok(dev))
skge_link_down(skge);
@@ -1103,7 +1199,7 @@ static void genesis_reset(struct skge_hw *hw, int port)
/* reset the statistics module */
xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
- xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */
+ xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);
xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */
xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */
xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */
@@ -1141,7 +1237,7 @@ static void bcom_check_link(struct skge_hw *hw, int port)
u16 status;
/* read twice because of latch */
- (void) xm_phy_read(hw, port, PHY_BCOM_STAT);
+ xm_phy_read(hw, port, PHY_BCOM_STAT);
status = xm_phy_read(hw, port, PHY_BCOM_STAT);
if ((status & PHY_ST_LSYNC) == 0) {
@@ -1342,7 +1438,7 @@ static void xm_phy_init(struct skge_port *skge)
mod_timer(&skge->link_timer, jiffies + LINK_HZ);
}
-static void xm_check_link(struct net_device *dev)
+static int xm_check_link(struct net_device *dev)
{
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
@@ -1350,25 +1446,25 @@ static void xm_check_link(struct net_device *dev)
u16 status;
/* read twice because of latch */
- (void) xm_phy_read(hw, port, PHY_XMAC_STAT);
+ xm_phy_read(hw, port, PHY_XMAC_STAT);
status = xm_phy_read(hw, port, PHY_XMAC_STAT);
if ((status & PHY_ST_LSYNC) == 0) {
xm_link_down(hw, port);
- return;
+ return 0;
}
if (skge->autoneg == AUTONEG_ENABLE) {
u16 lpa, res;
if (!(status & PHY_ST_AN_OVER))
- return;
+ return 0;
lpa = xm_phy_read(hw, port, PHY_XMAC_AUNE_LP);
if (lpa & PHY_B_AN_RF) {
printk(KERN_NOTICE PFX "%s: remote fault\n",
dev->name);
- return;
+ return 0;
}
res = xm_phy_read(hw, port, PHY_XMAC_RES_ABI);
@@ -1384,7 +1480,7 @@ static void xm_check_link(struct net_device *dev)
default:
printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
dev->name);
- return;
+ return 0;
}
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
@@ -1408,11 +1504,14 @@ static void xm_check_link(struct net_device *dev)
if (!netif_carrier_ok(dev))
genesis_link_up(skge);
+ return 1;
}
/* Poll to check for link coming up.
+ *
* Since internal PHY is wired to a level triggered pin, can't
- * get an interrupt when carrier is detected.
+ * get an interrupt when carrier is detected, need to poll for
+ * link coming up.
*/
static void xm_link_timer(unsigned long arg)
{
@@ -1420,29 +1519,35 @@ static void xm_link_timer(unsigned long arg)
struct net_device *dev = skge->netdev;
struct skge_hw *hw = skge->hw;
int port = skge->port;
+ int i;
+ unsigned long flags;
if (!netif_running(dev))
return;
- if (netif_carrier_ok(dev)) {
+ spin_lock_irqsave(&hw->phy_lock, flags);
+
+ /*
+ * Verify that the link by checking GPIO register three times.
+ * This pin has the signal from the link_sync pin connected to it.
+ */
+ for (i = 0; i < 3; i++) {
+ if (xm_read16(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
+ goto link_down;
+ }
+
+ /* Re-enable interrupt to detect link down */
+ if (xm_check_link(dev)) {
+ u16 msk = xm_read16(hw, port, XM_IMSK);
+ msk &= ~XM_IS_INP_ASS;
+ xm_write16(hw, port, XM_IMSK, msk);
xm_read16(hw, port, XM_ISRC);
- if (!(xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS))
- goto nochange;
} else {
- if (xm_read32(hw, port, XM_GP_PORT) & XM_GP_INP_ASS)
- goto nochange;
- xm_read16(hw, port, XM_ISRC);
- if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)
- goto nochange;
+link_down:
+ mod_timer(&skge->link_timer,
+ round_jiffies(jiffies + LINK_HZ));
}
-
- spin_lock(&hw->phy_lock);
- xm_check_link(dev);
- spin_unlock(&hw->phy_lock);
-
-nochange:
- if (netif_running(dev))
- mod_timer(&skge->link_timer, jiffies + LINK_HZ);
+ spin_unlock_irqrestore(&hw->phy_lock, flags);
}
static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -1679,24 +1784,27 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
static void genesis_mac_intr(struct skge_hw *hw, int port)
{
- struct skge_port *skge = netdev_priv(hw->dev[port]);
+ struct net_device *dev = hw->dev[port];
+ struct skge_port *skge = netdev_priv(dev);
u16 status = xm_read16(hw, port, XM_ISRC);
if (netif_msg_intr(skge))
printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
- skge->netdev->name, status);
+ dev->name, status);
- if (hw->phy_type == SK_PHY_XMAC &&
- (status & (XM_IS_INP_ASS | XM_IS_LIPA_RC)))
- xm_link_down(hw, port);
+ if (hw->phy_type == SK_PHY_XMAC && (status & XM_IS_INP_ASS)) {
+ xm_link_down(hw, port);
+ mod_timer(&skge->link_timer, jiffies + 1);
+ }
if (status & XM_IS_TXF_UR) {
xm_write32(hw, port, XM_MODE, XM_MD_FTF);
- ++skge->net_stats.tx_fifo_errors;
+ ++dev->stats.tx_fifo_errors;
}
+
if (status & XM_IS_RXF_OV) {
xm_write32(hw, port, XM_MODE, XM_MD_FRF);
- ++skge->net_stats.rx_fifo_errors;
+ ++dev->stats.rx_fifo_errors;
}
}
@@ -1753,11 +1861,12 @@ static void genesis_link_up(struct skge_port *skge)
}
xm_write32(hw, port, XM_MODE, mode);
- msk = XM_DEF_MSK;
- if (hw->phy_type != SK_PHY_XMAC)
- msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */
+ /* Turn on detection of Tx underrun, Rx overrun */
+ msk = xm_read16(hw, port, XM_IMSK);
+ msk &= ~(XM_IS_RXF_OV | XM_IS_TXF_UR);
xm_write16(hw, port, XM_IMSK, msk);
+
xm_read16(hw, port, XM_ISRC);
/* get MMU Command Reg. */
@@ -2192,12 +2301,12 @@ static void yukon_mac_intr(struct skge_hw *hw, int port)
dev->name, status);
if (status & GM_IS_RX_FF_OR) {
- ++skge->net_stats.rx_fifo_errors;
+ ++dev->stats.rx_fifo_errors;
skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
}
if (status & GM_IS_TX_FF_UR) {
- ++skge->net_stats.tx_fifo_errors;
+ ++dev->stats.tx_fifo_errors;
skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
}
@@ -2403,32 +2512,31 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return err;
}
-static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
+/* Assign Ram Buffer allocation to queue */
+static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, u32 space)
{
u32 end;
- start /= 8;
- len /= 8;
- end = start + len - 1;
+ /* convert from K bytes to qwords used for hw register */
+ start *= 1024/8;
+ space *= 1024/8;
+ end = start + space - 1;
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
skge_write32(hw, RB_ADDR(q, RB_START), start);
+ skge_write32(hw, RB_ADDR(q, RB_END), end);
skge_write32(hw, RB_ADDR(q, RB_WP), start);
skge_write32(hw, RB_ADDR(q, RB_RP), start);
- skge_write32(hw, RB_ADDR(q, RB_END), end);
if (q == Q_R1 || q == Q_R2) {
+ u32 tp = space - space/4;
+
/* Set thresholds on receive queue's */
- skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
- start + (2*len)/3);
- skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
- start + (len/3));
- } else {
- /* Enable store & forward on Tx queue's because
- * Tx FIFO is only 4K on Genesis and 1K on Yukon
- */
+ skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
+ skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
+ } else if (hw->chip_id != CHIP_ID_GENESIS)
+ /* Genesis Tx Fifo is too small for normal store/forward */
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
- }
skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
}
@@ -2456,7 +2564,7 @@ static int skge_up(struct net_device *dev)
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
int port = skge->port;
- u32 chunk, ram_addr;
+ u32 ramaddr, ramsize, rxspace;
size_t rx_size, tx_size;
int err;
@@ -2511,14 +2619,15 @@ static int skge_up(struct net_device *dev)
spin_unlock_bh(&hw->phy_lock);
/* Configure RAMbuffers */
- chunk = hw->ram_size / ((hw->ports + 1)*2);
- ram_addr = hw->ram_offset + 2 * chunk * port;
+ ramsize = (hw->ram_size - hw->ram_offset) / hw->ports;
+ ramaddr = hw->ram_offset + port * ramsize;
+ rxspace = 8 + (2*(ramsize - 16))/3;
- skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
- skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
+ skge_ramset(hw, rxqaddr[port], ramaddr, rxspace);
+ skge_ramset(hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace);
+ skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean);
- skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
/* Start receiver BMU */
@@ -2544,6 +2653,15 @@ static int skge_up(struct net_device *dev)
return err;
}
+/* stop receiver */
+static void skge_rx_stop(struct skge_hw *hw, int port)
+{
+ skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP);
+ skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
+ RB_RST_SET|RB_DIS_OP_MD);
+ skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
+}
+
static int skge_down(struct net_device *dev)
{
struct skge_port *skge = netdev_priv(dev);
@@ -2595,11 +2713,8 @@ static int skge_down(struct net_device *dev)
/* Reset the RAM Buffer async Tx queue */
skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET);
- /* stop receiver */
- skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP);
- skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
- RB_RST_SET|RB_DIS_OP_MD);
- skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
+
+ skge_rx_stop(hw, port);
if (hw->chip_id == CHIP_ID_GENESIS) {
skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
@@ -2782,7 +2897,11 @@ static void skge_tx_timeout(struct net_device *dev)
static int skge_change_mtu(struct net_device *dev, int new_mtu)
{
+ struct skge_port *skge = netdev_priv(dev);
+ struct skge_hw *hw = skge->hw;
+ int port = skge->port;
int err;
+ u16 ctl, reg;
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
@@ -2792,13 +2911,40 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
- skge_down(dev);
+ skge_write32(hw, B0_IMSK, 0);
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ netif_stop_queue(dev);
+ napi_disable(&skge->napi);
+
+ ctl = gma_read16(hw, port, GM_GP_CTRL);
+ gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
+
+ skge_rx_clean(skge);
+ skge_rx_stop(hw, port);
dev->mtu = new_mtu;
- err = skge_up(dev);
+ reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+ if (new_mtu > 1500)
+ reg |= GM_SMOD_JUMBO_ENA;
+ gma_write16(hw, port, GM_SERIAL_MODE, reg);
+
+ skge_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
+
+ err = skge_rx_fill(dev);
+ wmb();
+ if (!err)
+ skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+
if (err)
dev_close(dev);
+ else {
+ gma_write16(hw, port, GM_GP_CTRL, ctl);
+
+ napi_enable(&skge->napi);
+ netif_wake_queue(dev);
+ }
return err;
}
@@ -2994,18 +3140,18 @@ error:
if (skge->hw->chip_id == CHIP_ID_GENESIS) {
if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
- skge->net_stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (status & XMR_FS_FRA_ERR)
- skge->net_stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & XMR_FS_FCS_ERR)
- skge->net_stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
} else {
if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
- skge->net_stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (status & GMR_FS_FRAGMENT)
- skge->net_stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & GMR_FS_CRC_ERR)
- skge->net_stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
}
resubmit:
@@ -3103,10 +3249,7 @@ static void skge_mac_parity(struct skge_hw *hw, int port)
{
struct net_device *dev = hw->dev[port];
- if (dev) {
- struct skge_port *skge = netdev_priv(dev);
- ++skge->net_stats.tx_heartbeat_errors;
- }
+ ++dev->stats.tx_heartbeat_errors;
if (hw->chip_id == CHIP_ID_GENESIS)
skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
@@ -3259,9 +3402,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1);
if (status & IS_PA_TO_RX1) {
- struct skge_port *skge = netdev_priv(hw->dev[0]);
-
- ++skge->net_stats.rx_over_errors;
+ ++hw->dev[0]->stats.rx_over_errors;
skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1);
}
@@ -3278,7 +3419,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
}
if (status & IS_PA_TO_RX2) {
- ++skge->net_stats.rx_over_errors;
+ ++hw->dev[1]->stats.rx_over_errors;
skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2);
}
@@ -3450,15 +3591,12 @@ static int skge_reset(struct skge_hw *hw)
if (hw->chip_id == CHIP_ID_GENESIS) {
if (t8 == 3) {
/* special case: 4 x 64k x 36, offset = 0x80000 */
- hw->ram_size = 0x100000;
- hw->ram_offset = 0x80000;
+ hw->ram_size = 1024;
+ hw->ram_offset = 512;
} else
hw->ram_size = t8 * 512;
- }
- else if (t8 == 0)
- hw->ram_size = 0x20000;
- else
- hw->ram_size = t8 * 4096;
+ } else /* Yukon */
+ hw->ram_size = t8 ? t8 * 4 : 128;
hw->intr_mask = IS_HW_ERR;
@@ -3540,6 +3678,145 @@ static int skge_reset(struct skge_hw *hw)
return 0;
}
+
+#ifdef CONFIG_SKGE_DEBUG
+
+static struct dentry *skge_debug;
+
+static int skge_debug_show(struct seq_file *seq, void *v)
+{
+ struct net_device *dev = seq->private;
+ const struct skge_port *skge = netdev_priv(dev);
+ const struct skge_hw *hw = skge->hw;
+ const struct skge_element *e;
+
+ if (!netif_running(dev))
+ return -ENETDOWN;
+
+ seq_printf(seq, "IRQ src=%x mask=%x\n", skge_read32(hw, B0_ISRC),
+ skge_read32(hw, B0_IMSK));
+
+ seq_printf(seq, "Tx Ring: (%d)\n", skge_avail(&skge->tx_ring));
+ for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
+ const struct skge_tx_desc *t = e->desc;
+ seq_printf(seq, "%#x dma=%#x%08x %#x csum=%#x/%x/%x\n",
+ t->control, t->dma_hi, t->dma_lo, t->status,
+ t->csum_offs, t->csum_write, t->csum_start);
+ }
+
+ seq_printf(seq, "\nRx Ring: \n");
+ for (e = skge->rx_ring.to_clean; ; e = e->next) {
+ const struct skge_rx_desc *r = e->desc;
+
+ if (r->control & BMU_OWN)
+ break;
+
+ seq_printf(seq, "%#x dma=%#x%08x %#x %#x csum=%#x/%x\n",
+ r->control, r->dma_hi, r->dma_lo, r->status,
+ r->timestamp, r->csum1, r->csum1_start);
+ }
+
+ return 0;
+}
+
+static int skge_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, skge_debug_show, inode->i_private);
+}
+
+static const struct file_operations skge_debug_fops = {
+ .owner = THIS_MODULE,
+ .open = skge_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/*
+ * Use network device events to create/remove/rename
+ * debugfs file entries
+ */
+static int skge_device_event(struct notifier_block *unused,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = ptr;
+ struct skge_port *skge;
+ struct dentry *d;
+
+ if (dev->open != &skge_up || !skge_debug)
+ goto done;
+
+ skge = netdev_priv(dev);
+ switch(event) {
+ case NETDEV_CHANGENAME:
+ if (skge->debugfs) {
+ d = debugfs_rename(skge_debug, skge->debugfs,
+ skge_debug, dev->name);
+ if (d)
+ skge->debugfs = d;
+ else {
+ pr_info(PFX "%s: rename failed\n", dev->name);
+ debugfs_remove(skge->debugfs);
+ }
+ }
+ break;
+
+ case NETDEV_GOING_DOWN:
+ if (skge->debugfs) {
+ debugfs_remove(skge->debugfs);
+ skge->debugfs = NULL;
+ }
+ break;
+
+ case NETDEV_UP:
+ d = debugfs_create_file(dev->name, S_IRUGO,
+ skge_debug, dev,
+ &skge_debug_fops);
+ if (!d || IS_ERR(d))
+ pr_info(PFX "%s: debugfs create failed\n",
+ dev->name);
+ else
+ skge->debugfs = d;
+ break;
+ }
+
+done:
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block skge_notifier = {
+ .notifier_call = skge_device_event,
+};
+
+
+static __init void skge_debug_init(void)
+{
+ struct dentry *ent;
+
+ ent = debugfs_create_dir("skge", NULL);
+ if (!ent || IS_ERR(ent)) {
+ pr_info(PFX "debugfs create directory failed\n");
+ return;
+ }
+
+ skge_debug = ent;
+ register_netdevice_notifier(&skge_notifier);
+}
+
+static __exit void skge_debug_cleanup(void)
+{
+ if (skge_debug) {
+ unregister_netdevice_notifier(&skge_notifier);
+ debugfs_remove(skge_debug);
+ skge_debug = NULL;
+ }
+}
+
+#else
+#define skge_debug_init()
+#define skge_debug_cleanup()
+#endif
+
/* Initialize network device */
static struct net_device *skge_devinit(struct skge_hw *hw, int port,
int highmem)
@@ -3904,12 +4181,14 @@ static struct pci_driver skge_driver = {
static int __init skge_init_module(void)
{
+ skge_debug_init();
return pci_register_driver(&skge_driver);
}
static void __exit skge_cleanup_module(void)
{
pci_unregister_driver(&skge_driver);
+ skge_debug_cleanup();
}
module_init(skge_init_module);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 1a57bdd1ddf..17caccbb768 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -1,5 +1,5 @@
/*
- * Definitions for the new Marvell Yukon / SysKonenct driver.
+ * Definitions for the new Marvell Yukon / SysKonnect driver.
*/
#ifndef _SKGE_H
#define _SKGE_H
@@ -8,8 +8,10 @@
#define PCI_DEV_REG1 0x40
#define PCI_PHY_COMA 0x8000000
#define PCI_VIO 0x2000000
+
#define PCI_DEV_REG2 0x44
-#define PCI_REV_DESC 0x4
+#define PCI_VPD_ROM_SZ 7L<<14 /* VPD ROM size 0=256, 1=512, ... */
+#define PCI_REV_DESC 1<<2 /* Reverse Descriptor bytes */
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -2191,11 +2193,9 @@ enum {
XM_IS_TXF_UR = 1<<2, /* Bit 2: Transmit FIFO Underrun */
XM_IS_TX_COMP = 1<<1, /* Bit 1: Frame Tx Complete */
XM_IS_RX_COMP = 1<<0, /* Bit 0: Frame Rx Complete */
-};
-
-#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | \
- XM_IS_RXF_OV | XM_IS_TXF_UR))
+ XM_IMSK_DISABLE = 0xffff,
+};
/* XM_HW_CFG 16 bit r/w Hardware Config Register */
enum {
@@ -2469,8 +2469,9 @@ struct skge_port {
void *mem; /* PCI memory for rings */
dma_addr_t dma;
unsigned long mem_size;
-
- struct net_device_stats net_stats;
+#ifdef CONFIG_SKGE_DEBUG
+ struct dentry *debugfs;
+#endif
};
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7967240534d..24cfb6275d9 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1384,13 +1384,9 @@ static int sky2_up(struct net_device *dev)
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
TX_RING_SIZE - 1);
- napi_enable(&hw->napi);
-
err = sky2_rx_start(sky2);
- if (err) {
- napi_disable(&hw->napi);
+ if (err)
goto err_out;
- }
/* Enable interrupts from phy/mac for port */
imask = sky2_read32(hw, B0_IMSK);
@@ -1679,13 +1675,13 @@ static int sky2_down(struct net_device *dev)
/* Stop more packets from being queued */
netif_stop_queue(dev);
- napi_disable(&hw->napi);
-
/* Disable port IRQ */
imask = sky2_read32(hw, B0_IMSK);
imask &= ~portirq_msk[port];
sky2_write32(hw, B0_IMSK, imask);
+ synchronize_irq(hw->pdev->irq);
+
sky2_gmac_reset(hw, port);
/* Stop transmitter */
@@ -1699,6 +1695,9 @@ static int sky2_down(struct net_device *dev)
ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
gma_write16(hw, port, GM_GP_CTRL, ctrl);
+ /* Make sure no packets are pending */
+ napi_synchronize(&hw->napi);
+
sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
/* Workaround shared GMAC reset */
@@ -1736,8 +1735,6 @@ static int sky2_down(struct net_device *dev)
/* turn off LED's */
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
- synchronize_irq(hw->pdev->irq);
-
sky2_tx_clean(dev);
sky2_rx_clean(sky2);
@@ -2048,9 +2045,6 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
err = sky2_rx_start(sky2);
sky2_write32(hw, B0_IMSK, imask);
- /* Unconditionally re-enable NAPI because even if we
- * call dev_close() that will do a napi_disable().
- */
napi_enable(&hw->napi);
if (err)
@@ -2915,6 +2909,7 @@ static void sky2_restart(struct work_struct *work)
rtnl_lock();
sky2_write32(hw, B0_IMSK, 0);
sky2_read32(hw, B0_IMSK);
+ napi_disable(&hw->napi);
for (i = 0; i < hw->ports; i++) {
dev = hw->dev[i];
@@ -2924,6 +2919,7 @@ static void sky2_restart(struct work_struct *work)
sky2_reset(hw);
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+ napi_enable(&hw->napi);
for (i = 0; i < hw->ports; i++) {
dev = hw->dev[i];
@@ -3961,7 +3957,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
struct net_device *dev = alloc_etherdev(sizeof(*sky2));
if (!dev) {
- dev_err(&hw->pdev->dev, "etherdev alloc failed");
+ dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
return NULL;
}
@@ -4191,7 +4187,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
err = -ENOMEM;
goto err_out_free_pci;
}
- netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
if (!disable_msi && pci_enable_msi(pdev) == 0) {
err = sky2_test_msi(hw);
@@ -4207,6 +4202,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_free_netdev;
}
+ netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
+
err = request_irq(pdev->irq, sky2_intr,
(hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
dev->name, hw);
@@ -4215,6 +4212,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_unregister;
}
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+ napi_enable(&hw->napi);
sky2_show_addr(dev);
@@ -4265,23 +4263,18 @@ err_out:
static void __devexit sky2_remove(struct pci_dev *pdev)
{
struct sky2_hw *hw = pci_get_drvdata(pdev);
- struct net_device *dev0, *dev1;
+ int i;
if (!hw)
return;
del_timer_sync(&hw->watchdog_timer);
+ cancel_work_sync(&hw->restart_work);
- flush_scheduled_work();
+ for (i = hw->ports; i >= 0; --i)
+ unregister_netdev(hw->dev[i]);
sky2_write32(hw, B0_IMSK, 0);
- synchronize_irq(hw->pdev->irq);
-
- dev0 = hw->dev[0];
- dev1 = hw->dev[1];
- if (dev1)
- unregister_netdev(dev1);
- unregister_netdev(dev0);
sky2_power_aux(hw);
@@ -4296,9 +4289,9 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_disable_device(pdev);
- if (dev1)
- free_netdev(dev1);
- free_netdev(dev0);
+ for (i = hw->ports; i >= 0; --i)
+ free_netdev(hw->dev[i]);
+
iounmap(hw->regs);
kfree(hw);
@@ -4328,6 +4321,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
}
sky2_write32(hw, B0_IMSK, 0);
+ napi_disable(&hw->napi);
sky2_power_aux(hw);
pci_save_state(pdev);
@@ -4362,8 +4356,8 @@ static int sky2_resume(struct pci_dev *pdev)
pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
sky2_reset(hw);
-
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+ napi_enable(&hw->napi);
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 24e610e711e..7da7589d45d 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -173,49 +173,6 @@ MODULE_LICENSE("GPL");
*/
#define MII_DELAY 1
-/* store this information for the driver.. */
-struct smc_local {
- /*
- * If I have to wait until memory is available to send a
- * packet, I will store the skbuff here, until I get the
- * desired memory. Then, I'll send it out and free it.
- */
- struct sk_buff *pending_tx_skb;
- struct tasklet_struct tx_task;
-
- /* version/revision of the SMC91x chip */
- int version;
-
- /* Contains the current active transmission mode */
- int tcr_cur_mode;
-
- /* Contains the current active receive mode */
- int rcr_cur_mode;
-
- /* Contains the current active receive/phy mode */
- int rpc_cur_mode;
- int ctl_rfduplx;
- int ctl_rspeed;
-
- u32 msg_enable;
- u32 phy_type;
- struct mii_if_info mii;
-
- /* work queue */
- struct work_struct phy_configure;
- struct net_device *dev;
- int work_pending;
-
- spinlock_t lock;
-
-#ifdef SMC_USE_PXA_DMA
- /* DMA needs the physical address of the chip */
- u_long physaddr;
-#endif
- void __iomem *base;
- void __iomem *datacs;
-};
-
#if SMC_DEBUG > 0
#define DBG(n, args...) \
do { \
@@ -2215,17 +2172,19 @@ static int smc_drv_probe(struct platform_device *pdev)
goto out_release_attrib;
}
- platform_set_drvdata(pdev, ndev);
- ret = smc_probe(ndev, addr);
- if (ret != 0)
- goto out_iounmap;
#ifdef SMC_USE_PXA_DMA
- else {
+ {
struct smc_local *lp = netdev_priv(ndev);
+ lp->device = &pdev->dev;
lp->physaddr = res->start;
}
#endif
+ platform_set_drvdata(pdev, ndev);
+ ret = smc_probe(ndev, addr);
+ if (ret != 0)
+ goto out_iounmap;
+
smc_request_datacs(pdev, ndev);
return 0;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index af9e6bf5955..729fd28c08b 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -462,6 +462,52 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#endif
+
+/* store this information for the driver.. */
+struct smc_local {
+ /*
+ * If I have to wait until memory is available to send a
+ * packet, I will store the skbuff here, until I get the
+ * desired memory. Then, I'll send it out and free it.
+ */
+ struct sk_buff *pending_tx_skb;
+ struct tasklet_struct tx_task;
+
+ /* version/revision of the SMC91x chip */
+ int version;
+
+ /* Contains the current active transmission mode */
+ int tcr_cur_mode;
+
+ /* Contains the current active receive mode */
+ int rcr_cur_mode;
+
+ /* Contains the current active receive/phy mode */
+ int rpc_cur_mode;
+ int ctl_rfduplx;
+ int ctl_rspeed;
+
+ u32 msg_enable;
+ u32 phy_type;
+ struct mii_if_info mii;
+
+ /* work queue */
+ struct work_struct phy_configure;
+ struct net_device *dev;
+ int work_pending;
+
+ spinlock_t lock;
+
+#ifdef SMC_USE_PXA_DMA
+ /* DMA needs the physical address of the chip */
+ u_long physaddr;
+ struct device *device;
+#endif
+ void __iomem *base;
+ void __iomem *datacs;
+};
+
+
#ifdef SMC_USE_PXA_DMA
/*
* Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
@@ -476,11 +522,12 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#ifdef SMC_insl
#undef SMC_insl
#define SMC_insl(a, r, p, l) \
- smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
+ smc_pxa_dma_insl(a, lp, r, dev->dma, p, l)
static inline void
-smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
+smc_pxa_dma_insl(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
u_char *buf, int len)
{
+ u_long physaddr = lp->physaddr;
dma_addr_t dmabuf;
/* fallback if no DMA available */
@@ -497,7 +544,7 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
}
len *= 4;
- dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
+ dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg;
@@ -507,18 +554,19 @@ smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax();
DCSR(dma) = 0;
- dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
+ dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
}
#endif
#ifdef SMC_insw
#undef SMC_insw
#define SMC_insw(a, r, p, l) \
- smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
+ smc_pxa_dma_insw(a, lp, r, dev->dma, p, l)
static inline void
-smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
+smc_pxa_dma_insw(void __iomem *ioaddr, struct smc_local *lp, int reg, int dma,
u_char *buf, int len)
{
+ u_long physaddr = lp->physaddr;
dma_addr_t dmabuf;
/* fallback if no DMA available */
@@ -535,7 +583,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
}
len *= 2;
- dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
+ dmabuf = dma_map_single(lp->device, buf, len, DMA_FROM_DEVICE);
DCSR(dma) = DCSR_NODESC;
DTADR(dma) = dmabuf;
DSADR(dma) = physaddr + reg;
@@ -545,7 +593,7 @@ smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
while (!(DCSR(dma) & DCSR_STOPSTATE))
cpu_relax();
DCSR(dma) = 0;
- dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
+ dma_unmap_single(lp->device, dmabuf, len, DMA_FROM_DEVICE);
}
#endif
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h
index a897beee7d5..e1d05c0f47e 100644
--- a/drivers/net/spider_net.h
+++ b/drivers/net/spider_net.h
@@ -494,7 +494,4 @@ struct spider_net_card {
struct spider_net_descr darray[0];
};
-#define pr_err(fmt,arg...) \
- printk(KERN_ERR fmt ,##arg)
-
#endif
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index a679f4310ce..8038f2882c9 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1461,7 +1461,6 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
}
return IRQ_NONE;
#else
- struct tc35815_local *lp = dev->priv;
int handled;
u32 status;
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 8d04654f0c5..4e1b84e6d66 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -1906,7 +1906,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/************** pci *****************/
if ((err = pci_enable_device(pdev))) /* it trigers interrupt, dunno why. */
- RET(err); /* it's not a problem though */
+ goto err_pci; /* it's not a problem though */
if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
!(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
@@ -2076,6 +2076,7 @@ err_out_res:
pci_release_regions(pdev);
err_dma:
pci_disable_device(pdev);
+err_pci:
vfree(nic);
RET(err);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 30b1cca8144..014dc2cfe4d 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.83"
-#define DRV_MODULE_RELDATE "October 10, 2007"
+#define DRV_MODULE_VERSION "3.84"
+#define DRV_MODULE_RELDATE "October 12, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -5056,6 +5056,12 @@ static void tg3_restore_pci_state(struct tg3 *tp)
pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd);
+ if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+ pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
+ tp->pci_cacheline_sz);
+ pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+ tp->pci_lat_timer);
+ }
/* Make sure PCI-X relaxed ordering bit is clear. */
if (tp->pcix_cap) {
u16 pcix_cmd;
@@ -9034,7 +9040,7 @@ static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
int i;
u32 j;
- for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) {
+ for (i = 0; i < ARRAY_SIZE(test_pattern); i++) {
for (j = 0; j < len; j += 4) {
u32 val;
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 7224d368b2a..5d31519a6c6 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -760,7 +760,7 @@ static int xl_open_hw(struct net_device *dev)
if (xl_priv->xl_laa[0]) { /* If using a LAA address */
for (i=10;i<16;i++) {
writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(xl_priv->xl_laa[i],xl_mmio + MMIO_MACDATA) ;
+ writeb(xl_priv->xl_laa[i-10],xl_mmio + MMIO_MACDATA) ;
}
memcpy(dev->dev_addr,xl_priv->xl_laa,dev->addr_len) ;
} else { /* Regular hardware address */
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/de4x5.c b/drivers/net/tulip/de4x5.c
index 9b9cd83fb8b..41f34bb91ca 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1041,7 +1041,7 @@ static struct InfoLeaf infoleaf_array[] = {
{DC21142, dc21142_infoleaf},
{DC21143, dc21143_infoleaf}
};
-#define INFOLEAF_SIZE (sizeof(infoleaf_array)/(sizeof(int)+sizeof(int *)))
+#define INFOLEAF_SIZE ARRAY_SIZE(infoleaf_array)
/*
** List the SROM info block functions
@@ -1056,7 +1056,7 @@ static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = {
compact_infoblock
};
-#define COMPACT (sizeof(dc_infoblock)/sizeof(int *) - 1)
+#define COMPACT (ARRAY_SIZE(dc_infoblock) - 1)
/*
** Miscellaneous defines...
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index d00e7d41f6a..bec413ba9bc 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -63,7 +63,7 @@
#define UGETH_MSG_DEFAULT (NETIF_MSG_IFUP << 1 ) - 1
void uec_set_ethtool_ops(struct net_device *netdev);
-
+
static DEFINE_SPINLOCK(ugeth_lock);
static struct {
@@ -3454,9 +3454,12 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
u16 length, howmany = 0;
u32 bd_status;
u8 *bdBuffer;
+ struct net_device * dev;
ugeth_vdbg("%s: IN", __FUNCTION__);
+ dev = ugeth->dev;
+
/* collect received buffers */
bd = ugeth->rxBd[rxQ];
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 6240b978fe3..f55a5951733 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -114,8 +114,8 @@ static void mcs7830_async_cmd_callback(struct urb *urb)
struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
if (urb->status < 0)
- printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d",
- urb->status);
+ printk(KERN_DEBUG "%s() failed with %d\n",
+ __FUNCTION__, urb->status);
kfree(req);
usb_free_urb(urb);
@@ -129,15 +129,15 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
- dev_dbg(&dev->udev->dev, "Error allocating URB "
- "in write_cmd_async!");
+ dev_dbg(&dev->udev->dev,
+ "Error allocating URB in write_cmd_async!\n");
return;
}
req = kmalloc(sizeof *req, GFP_ATOMIC);
if (!req) {
- dev_err(&dev->udev->dev, "Failed to allocate memory for "
- "control request");
+ dev_err(&dev->udev->dev,
+ "Failed to allocate memory for control request\n");
goto out;
}
req->bRequestType = MCS7830_WR_BMREQ;
@@ -153,8 +153,8 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret < 0) {
- dev_err(&dev->udev->dev, "Error submitting the control "
- "message: ret=%d", ret);
+ dev_err(&dev->udev->dev,
+ "Error submitting the control message: ret=%d\n", ret);
goto out;
}
return;
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index b39a541b250..05df0a345b6 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -1342,11 +1342,11 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map)
if (flp->initialized)
return(-EINVAL);
- for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
+ for(i=0; i < ARRAY_SIZE(valid_port); i++)
if (valid_port[i] == map->base_addr)
break;
- if (i == sizeof(valid_port) / sizeof(int))
+ if (i == ARRAY_SIZE(valid_port))
return(-EINVAL);
if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
@@ -1487,12 +1487,12 @@ got_type:
}
}
- for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
+ for(i=0; i < ARRAY_SIZE(valid_mem); i++)
if (valid_mem[i] == map->mem_start)
break;
err = -EINVAL;
- if (i == sizeof(valid_mem) / sizeof(int))
+ if (i == ARRAY_SIZE(valid_mem))
goto fail2;
if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 5a6fdfd0f14..dae5c8d5a31 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -282,6 +282,12 @@ config LIBERTAS_CS
---help---
A driver for Marvell Libertas 8385 CompactFlash devices.
+config LIBERTAS_SDIO
+ tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
+ depends on LIBERTAS && MMC
+ ---help---
+ A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+
config LIBERTAS_DEBUG
bool "Enable full debugging output in the Libertas module."
depends on LIBERTAS
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index c469d569f09..0e2787691f9 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -7,7 +7,9 @@ libertas-objs := main.o wext.o \
usb8xxx-objs += if_usb.o
libertas_cs-objs += if_cs.o
+libertas_sdio-objs += if_sdio.o
obj-$(CONFIG_LIBERTAS) += libertas.o
obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o
+obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 7c5b7f7b45d..3a0c9beefcf 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -39,6 +39,7 @@
#define LBS_DEB_FW 0x00080000
#define LBS_DEB_THREAD 0x00100000
#define LBS_DEB_HEX 0x00200000
+#define LBS_DEB_SDIO 0x00400000
extern unsigned int libertas_debug;
@@ -80,6 +81,7 @@ do { if ((libertas_debug & (grp)) == (grp)) \
#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, (dev)->bus_id, ##args)
#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args)
#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
+#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " thread", fmt, ##args)
#define lbs_pr_info(format, args...) \
printk(KERN_INFO DRV_NAME": " format, ## args)
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
new file mode 100644
index 00000000000..a8e17076e7d
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -0,0 +1,1079 @@
+/*
+ * linux/drivers/net/wireless/libertas/if_sdio.c
+ *
+ * Copyright 2007 Pierre Ossman
+ *
+ * Inspired by if_cs.c, Copyright 2007 Holger Schurig
+ *
+ * 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 hardware has more or less no CMD53 support, so all registers
+ * must be accessed using sdio_readb()/sdio_writeb().
+ *
+ * Transfers must be in one transaction or the firmware goes bonkers.
+ * This means that the transfer must either be small enough to do a
+ * byte based transfer or it must be padded to a multiple of the
+ * current block size.
+ *
+ * As SDIO is still new to the kernel, it is unfortunately common with
+ * bugs in the host controllers related to that. One such bug is that
+ * controllers cannot do transfers that aren't a multiple of 4 bytes.
+ * If you don't have time to fix the host controller driver, you can
+ * work around the problem by modifying if_sdio_host_to_card() and
+ * if_sdio_card_to_host() to pad the data.
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+#include "host.h"
+#include "decl.h"
+#include "defs.h"
+#include "dev.h"
+#include "if_sdio.h"
+
+static char *libertas_helper_name = NULL;
+module_param_named(helper_name, libertas_helper_name, charp, 0644);
+
+static char *libertas_fw_name = NULL;
+module_param_named(fw_name, libertas_fw_name, charp, 0644);
+
+static const struct sdio_device_id if_sdio_ids[] = {
+ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
+ { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
+
+struct if_sdio_model {
+ int model;
+ const char *helper;
+ const char *firmware;
+};
+
+static struct if_sdio_model if_sdio_models[] = {
+ {
+ /* 8385 */
+ .model = 0x04,
+ .helper = "sd8385_helper.bin",
+ .firmware = "sd8385.bin",
+ },
+ {
+ /* 8686 */
+ .model = 0x0B,
+ .helper = "sd8686_helper.bin",
+ .firmware = "sd8686.bin",
+ },
+};
+
+struct if_sdio_packet {
+ struct if_sdio_packet *next;
+ u16 nb;
+ u8 buffer[0] __attribute__((aligned(4)));
+};
+
+struct if_sdio_card {
+ struct sdio_func *func;
+ wlan_private *priv;
+
+ int model;
+ unsigned long ioport;
+
+ const char *helper;
+ const char *firmware;
+
+ u8 buffer[65536];
+ u8 int_cause;
+ u32 event;
+
+ spinlock_t lock;
+ struct if_sdio_packet *packets;
+ struct work_struct packet_worker;
+};
+
+/********************************************************************/
+/* I/O */
+/********************************************************************/
+
+static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
+{
+ int ret, reg;
+ u16 scratch;
+
+ if (card->model == 0x04)
+ reg = IF_SDIO_SCRATCH_OLD;
+ else
+ reg = IF_SDIO_SCRATCH;
+
+ scratch = sdio_readb(card->func, reg, &ret);
+ if (!ret)
+ scratch |= sdio_readb(card->func, reg + 1, &ret) << 8;
+
+ if (err)
+ *err = ret;
+
+ if (ret)
+ return 0xffff;
+
+ return scratch;
+}
+
+static int if_sdio_handle_cmd(struct if_sdio_card *card,
+ u8 *buffer, unsigned size)
+{
+ int ret;
+ unsigned long flags;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ spin_lock_irqsave(&card->priv->adapter->driver_lock, flags);
+
+ if (!card->priv->adapter->cur_cmd) {
+ lbs_deb_sdio("discarding spurious response\n");
+ ret = 0;
+ goto out;
+ }
+
+ if (size > MRVDRV_SIZE_OF_CMD_BUFFER) {
+ lbs_deb_sdio("response packet too large (%d bytes)\n",
+ (int)size);
+ ret = -E2BIG;
+ goto out;
+ }
+
+ memcpy(card->priv->adapter->cur_cmd->bufvirtualaddr, buffer, size);
+ card->priv->upld_len = size;
+
+ card->int_cause |= MRVDRV_CMD_UPLD_RDY;
+
+ libertas_interrupt(card->priv->dev);
+
+ ret = 0;
+
+out:
+ spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags);
+
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static int if_sdio_handle_data(struct if_sdio_card *card,
+ u8 *buffer, unsigned size)
+{
+ int ret;
+ struct sk_buff *skb;
+ char *data;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ if (size > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
+ lbs_deb_sdio("response packet too large (%d bytes)\n",
+ (int)size);
+ ret = -E2BIG;
+ goto out;
+ }
+
+ skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+ if (!skb) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ data = skb_put(skb, size);
+
+ memcpy(data, buffer, size);
+
+ libertas_process_rxed_packet(card->priv, skb);
+
+ ret = 0;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static int if_sdio_handle_event(struct if_sdio_card *card,
+ u8 *buffer, unsigned size)
+{
+ int ret;
+ unsigned long flags;
+ u32 event;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ if (card->model == 0x04) {
+ event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
+ if (ret)
+ goto out;
+ } else {
+ if (size < 4) {
+ lbs_deb_sdio("event packet too small (%d bytes)\n",
+ (int)size);
+ ret = -EINVAL;
+ goto out;
+ }
+ event = buffer[3] << 24;
+ event |= buffer[2] << 16;
+ event |= buffer[1] << 8;
+ event |= buffer[0] << 0;
+ event <<= SBI_EVENT_CAUSE_SHIFT;
+ }
+
+ spin_lock_irqsave(&card->priv->adapter->driver_lock, flags);
+
+ card->event = event;
+ card->int_cause |= MRVDRV_CARDEVENT;
+
+ libertas_interrupt(card->priv->dev);
+
+ spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags);
+
+ ret = 0;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static int if_sdio_card_to_host(struct if_sdio_card *card)
+{
+ int ret;
+ u8 status;
+ u16 size, type, chunk;
+ unsigned long timeout;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ size = if_sdio_read_scratch(card, &ret);
+ if (ret)
+ goto out;
+
+ if (size < 4) {
+ lbs_deb_sdio("invalid packet size (%d bytes) from firmware\n",
+ (int)size);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ timeout = jiffies + HZ;
+ while (1) {
+ status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
+ if (ret)
+ goto out;
+ if (status & IF_SDIO_IO_RDY)
+ break;
+ if (time_after(jiffies, timeout)) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+ mdelay(1);
+ }
+
+ /*
+ * The transfer must be in one transaction or the firmware
+ * goes suicidal.
+ */
+ chunk = size;
+ if ((chunk > card->func->cur_blksize) || (chunk > 512)) {
+ chunk = (chunk + card->func->cur_blksize - 1) /
+ card->func->cur_blksize * card->func->cur_blksize;
+ }
+
+ ret = sdio_readsb(card->func, card->buffer, card->ioport, chunk);
+ if (ret)
+ goto out;
+
+ chunk = card->buffer[0] | (card->buffer[1] << 8);
+ type = card->buffer[2] | (card->buffer[3] << 8);
+
+ lbs_deb_sdio("packet of type %d and size %d bytes\n",
+ (int)type, (int)chunk);
+
+ if (chunk > size) {
+ lbs_deb_sdio("packet fragment (%d > %d)\n",
+ (int)chunk, (int)size);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (chunk < size) {
+ lbs_deb_sdio("packet fragment (%d < %d)\n",
+ (int)chunk, (int)size);
+ }
+
+ switch (type) {
+ case MVMS_CMD:
+ ret = if_sdio_handle_cmd(card, card->buffer + 4, chunk - 4);
+ if (ret)
+ goto out;
+ break;
+ case MVMS_DAT:
+ ret = if_sdio_handle_data(card, card->buffer + 4, chunk - 4);
+ if (ret)
+ goto out;
+ break;
+ case MVMS_EVENT:
+ ret = if_sdio_handle_event(card, card->buffer + 4, chunk - 4);
+ if (ret)
+ goto out;
+ break;
+ default:
+ lbs_deb_sdio("invalid type (%d) from firmware\n",
+ (int)type);
+ ret = -EINVAL;
+ goto out;
+ }
+
+out:
+ if (ret)
+ lbs_pr_err("problem fetching packet from firmware\n");
+
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static void if_sdio_host_to_card_worker(struct work_struct *work)
+{
+ struct if_sdio_card *card;
+ struct if_sdio_packet *packet;
+ unsigned long timeout;
+ u8 status;
+ int ret;
+ unsigned long flags;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ card = container_of(work, struct if_sdio_card, packet_worker);
+
+ while (1) {
+ spin_lock_irqsave(&card->lock, flags);
+ packet = card->packets;
+ if (packet)
+ card->packets = packet->next;
+ spin_unlock_irqrestore(&card->lock, flags);
+
+ if (!packet)
+ break;
+
+ sdio_claim_host(card->func);
+
+ timeout = jiffies + HZ;
+ while (1) {
+ status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
+ if (ret)
+ goto release;
+ if (status & IF_SDIO_IO_RDY)
+ break;
+ if (time_after(jiffies, timeout)) {
+ ret = -ETIMEDOUT;
+ goto release;
+ }
+ mdelay(1);
+ }
+
+ ret = sdio_writesb(card->func, card->ioport,
+ packet->buffer, packet->nb);
+ if (ret)
+ goto release;
+release:
+ sdio_release_host(card->func);
+
+ kfree(packet);
+ }
+
+ lbs_deb_leave(LBS_DEB_SDIO);
+}
+
+/********************************************************************/
+/* Firmware */
+/********************************************************************/
+
+static int if_sdio_prog_helper(struct if_sdio_card *card)
+{
+ int ret;
+ u8 status;
+ const struct firmware *fw;
+ unsigned long timeout;
+ u8 *chunk_buffer;
+ u32 chunk_size;
+ u8 *firmware;
+ size_t size;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ ret = request_firmware(&fw, card->helper, &card->func->dev);
+ if (ret) {
+ lbs_pr_err("can't load helper firmware\n");
+ goto out;
+ }
+
+ chunk_buffer = kzalloc(64, GFP_KERNEL);
+ if (!chunk_buffer) {
+ ret = -ENOMEM;
+ goto release_fw;
+ }
+
+ sdio_claim_host(card->func);
+
+ ret = sdio_set_block_size(card->func, 32);
+ if (ret)
+ goto release;
+
+ firmware = fw->data;
+ size = fw->size;
+
+ while (size) {
+ timeout = jiffies + HZ;
+ while (1) {
+ status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
+ if (ret)
+ goto release;
+ if ((status & IF_SDIO_IO_RDY) &&
+ (status & IF_SDIO_DL_RDY))
+ break;
+ if (time_after(jiffies, timeout)) {
+ ret = -ETIMEDOUT;
+ goto release;
+ }
+ mdelay(1);
+ }
+
+ chunk_size = min(size, (size_t)60);
+
+ *((u32*)chunk_buffer) = cpu_to_le32(chunk_size);
+ memcpy(chunk_buffer + 4, firmware, chunk_size);
+/*
+ lbs_deb_sdio("sending %d bytes chunk\n", chunk_size);
+*/
+ ret = sdio_writesb(card->func, card->ioport,
+ chunk_buffer, 64);
+ if (ret)
+ goto release;
+
+ firmware += chunk_size;
+ size -= chunk_size;
+ }
+
+ /* an empty block marks the end of the transfer */
+ memset(chunk_buffer, 0, 4);
+ ret = sdio_writesb(card->func, card->ioport, chunk_buffer, 64);
+ if (ret)
+ goto release;
+
+ lbs_deb_sdio("waiting for helper to boot...\n");
+
+ /* wait for the helper to boot by looking at the size register */
+ timeout = jiffies + HZ;
+ while (1) {
+ u16 req_size;
+
+ req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
+ if (ret)
+ goto release;
+
+ req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8;
+ if (ret)
+ goto release;
+
+ if (req_size != 0)
+ break;
+
+ if (time_after(jiffies, timeout)) {
+ ret = -ETIMEDOUT;
+ goto release;
+ }
+
+ msleep(10);
+ }
+
+ ret = 0;
+
+release:
+ sdio_set_block_size(card->func, 0);
+ sdio_release_host(card->func);
+ kfree(chunk_buffer);
+release_fw:
+ release_firmware(fw);
+
+out:
+ if (ret)
+ lbs_pr_err("failed to load helper firmware\n");
+
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static int if_sdio_prog_real(struct if_sdio_card *card)
+{
+ int ret;
+ u8 status;
+ const struct firmware *fw;
+ unsigned long timeout;
+ u8 *chunk_buffer;
+ u32 chunk_size;
+ u8 *firmware;
+ size_t size, req_size;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ ret = request_firmware(&fw, card->firmware, &card->func->dev);
+ if (ret) {
+ lbs_pr_err("can't load firmware\n");
+ goto out;
+ }
+
+ chunk_buffer = kzalloc(512, GFP_KERNEL);
+ if (!chunk_buffer) {
+ ret = -ENOMEM;
+ goto release_fw;
+ }
+
+ sdio_claim_host(card->func);
+
+ ret = sdio_set_block_size(card->func, 32);
+ if (ret)
+ goto release;
+
+ firmware = fw->data;
+ size = fw->size;
+
+ while (size) {
+ timeout = jiffies + HZ;
+ while (1) {
+ status = sdio_readb(card->func, IF_SDIO_STATUS, &ret);
+ if (ret)
+ goto release;
+ if ((status & IF_SDIO_IO_RDY) &&
+ (status & IF_SDIO_DL_RDY))
+ break;
+ if (time_after(jiffies, timeout)) {
+ ret = -ETIMEDOUT;
+ goto release;
+ }
+ mdelay(1);
+ }
+
+ req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret);
+ if (ret)
+ goto release;
+
+ req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8;
+ if (ret)
+ goto release;
+/*
+ lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size);
+*/
+ if (req_size == 0) {
+ lbs_deb_sdio("firmware helper gave up early\n");
+ ret = -EIO;
+ goto release;
+ }
+
+ if (req_size & 0x01) {
+ lbs_deb_sdio("firmware helper signalled error\n");
+ ret = -EIO;
+ goto release;
+ }
+
+ if (req_size > size)
+ req_size = size;
+
+ while (req_size) {
+ chunk_size = min(req_size, (size_t)512);
+
+ memcpy(chunk_buffer, firmware, chunk_size);
+/*
+ lbs_deb_sdio("sending %d bytes (%d bytes) chunk\n",
+ chunk_size, (chunk_size + 31) / 32 * 32);
+*/
+ ret = sdio_writesb(card->func, card->ioport,
+ chunk_buffer, (chunk_size + 31) / 32 * 32);
+ if (ret)
+ goto release;
+
+ firmware += chunk_size;
+ size -= chunk_size;
+ req_size -= chunk_size;
+ }
+ }
+
+ ret = 0;
+
+ lbs_deb_sdio("waiting for firmware to boot...\n");
+
+ /* wait for the firmware to boot */
+ timeout = jiffies + HZ;
+ while (1) {
+ u16 scratch;
+
+ scratch = if_sdio_read_scratch(card, &ret);
+ if (ret)
+ goto release;
+
+ if (scratch == IF_SDIO_FIRMWARE_OK)
+ break;
+
+ if (time_after(jiffies, timeout)) {
+ ret = -ETIMEDOUT;
+ goto release;
+ }
+
+ msleep(10);
+ }
+
+ ret = 0;
+
+release:
+ sdio_set_block_size(card->func, 0);
+ sdio_release_host(card->func);
+ kfree(chunk_buffer);
+release_fw:
+ release_firmware(fw);
+
+out:
+ if (ret)
+ lbs_pr_err("failed to load firmware\n");
+
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static int if_sdio_prog_firmware(struct if_sdio_card *card)
+{
+ int ret;
+ u16 scratch;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ sdio_claim_host(card->func);
+ scratch = if_sdio_read_scratch(card, &ret);
+ sdio_release_host(card->func);
+
+ if (ret)
+ goto out;
+
+ if (scratch == IF_SDIO_FIRMWARE_OK) {
+ lbs_deb_sdio("firmware already loaded\n");
+ goto success;
+ }
+
+ ret = if_sdio_prog_helper(card);
+ if (ret)
+ goto out;
+
+ ret = if_sdio_prog_real(card);
+ if (ret)
+ goto out;
+
+success:
+ ret = 0;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+/*******************************************************************/
+/* Libertas callbacks */
+/*******************************************************************/
+
+static int if_sdio_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb)
+{
+ int ret;
+ struct if_sdio_card *card;
+ struct if_sdio_packet *packet, *cur;
+ u16 size;
+ unsigned long flags;
+
+ lbs_deb_enter_args(LBS_DEB_SDIO, "type %d, bytes %d", type, nb);
+
+ card = priv->card;
+
+ if (nb > (65536 - sizeof(struct if_sdio_packet) - 4)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * The transfer must be in one transaction or the firmware
+ * goes suicidal.
+ */
+ size = nb + 4;
+ if ((size > card->func->cur_blksize) || (size > 512)) {
+ size = (size + card->func->cur_blksize - 1) /
+ card->func->cur_blksize * card->func->cur_blksize;
+ }
+
+ packet = kzalloc(sizeof(struct if_sdio_packet) + size,
+ GFP_ATOMIC);
+ if (!packet) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ packet->next = NULL;
+ packet->nb = size;
+
+ /*
+ * SDIO specific header.
+ */
+ packet->buffer[0] = (nb + 4) & 0xff;
+ packet->buffer[1] = ((nb + 4) >> 8) & 0xff;
+ packet->buffer[2] = type;
+ packet->buffer[3] = 0;
+
+ memcpy(packet->buffer + 4, buf, nb);
+
+ spin_lock_irqsave(&card->lock, flags);
+
+ if (!card->packets)
+ card->packets = packet;
+ else {
+ cur = card->packets;
+ while (cur->next)
+ cur = cur->next;
+ cur->next = packet;
+ }
+
+ switch (type) {
+ case MVMS_CMD:
+ priv->dnld_sent = DNLD_CMD_SENT;
+ break;
+ case MVMS_DAT:
+ priv->dnld_sent = DNLD_DATA_SENT;
+ break;
+ default:
+ lbs_deb_sdio("unknown packet type %d\n", (int)type);
+ }
+
+ spin_unlock_irqrestore(&card->lock, flags);
+
+ schedule_work(&card->packet_worker);
+
+ ret = 0;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static int if_sdio_get_int_status(wlan_private *priv, u8 *ireg)
+{
+ struct if_sdio_card *card;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ card = priv->card;
+
+ *ireg = card->int_cause;
+ card->int_cause = 0;
+
+ lbs_deb_leave(LBS_DEB_SDIO);
+
+ return 0;
+}
+
+static int if_sdio_read_event_cause(wlan_private *priv)
+{
+ struct if_sdio_card *card;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ card = priv->card;
+
+ priv->adapter->eventcause = card->event;
+
+ lbs_deb_leave(LBS_DEB_SDIO);
+
+ return 0;
+}
+
+/*******************************************************************/
+/* SDIO callbacks */
+/*******************************************************************/
+
+static void if_sdio_interrupt(struct sdio_func *func)
+{
+ int ret;
+ struct if_sdio_card *card;
+ u8 cause;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ card = sdio_get_drvdata(func);
+
+ cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
+ if (ret)
+ goto out;
+
+ lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
+
+ sdio_writeb(card->func, ~cause, IF_SDIO_H_INT_STATUS, &ret);
+ if (ret)
+ goto out;
+
+ /*
+ * Ignore the define name, this really means the card has
+ * successfully received the command.
+ */
+ if (cause & IF_SDIO_H_INT_DNLD) {
+ if ((card->priv->dnld_sent == DNLD_DATA_SENT) &&
+ (card->priv->adapter->connect_status == LIBERTAS_CONNECTED))
+ netif_wake_queue(card->priv->dev);
+ card->priv->dnld_sent = DNLD_RES_RECEIVED;
+ }
+
+ if (cause & IF_SDIO_H_INT_UPLD) {
+ ret = if_sdio_card_to_host(card);
+ if (ret)
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+}
+
+static int if_sdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ struct if_sdio_card *card;
+ wlan_private *priv;
+ int ret, i;
+ unsigned int model;
+ struct if_sdio_packet *packet;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ for (i = 0;i < func->card->num_info;i++) {
+ if (sscanf(func->card->info[i],
+ "802.11 SDIO ID: %x", &model) == 1)
+ break;
+ if (sscanf(func->card->info[i],
+ "ID: %x", &model) == 1)
+ break;
+ }
+
+ if (i == func->card->num_info) {
+ lbs_pr_err("unable to identify card model\n");
+ return -ENODEV;
+ }
+
+ card = kzalloc(sizeof(struct if_sdio_card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ card->func = func;
+ card->model = model;
+ spin_lock_init(&card->lock);
+ INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
+
+ for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
+ if (card->model == if_sdio_models[i].model)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(if_sdio_models)) {
+ lbs_pr_err("unkown card model 0x%x\n", card->model);
+ ret = -ENODEV;
+ goto free;
+ }
+
+ card->helper = if_sdio_models[i].helper;
+ card->firmware = if_sdio_models[i].firmware;
+
+ if (libertas_helper_name) {
+ lbs_deb_sdio("overriding helper firmware: %s\n",
+ libertas_helper_name);
+ card->helper = libertas_helper_name;
+ }
+
+ if (libertas_fw_name) {
+ lbs_deb_sdio("overriding firmware: %s\n", libertas_fw_name);
+ card->firmware = libertas_fw_name;
+ }
+
+ sdio_claim_host(func);
+
+ ret = sdio_enable_func(func);
+ if (ret)
+ goto release;
+
+ ret = sdio_claim_irq(func, if_sdio_interrupt);
+ if (ret)
+ goto disable;
+
+ card->ioport = sdio_readb(func, IF_SDIO_IOPORT, &ret);
+ if (ret)
+ goto release_int;
+
+ card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 1, &ret) << 8;
+ if (ret)
+ goto release_int;
+
+ card->ioport |= sdio_readb(func, IF_SDIO_IOPORT + 2, &ret) << 16;
+ if (ret)
+ goto release_int;
+
+ sdio_release_host(func);
+
+ sdio_set_drvdata(func, card);
+
+ lbs_deb_sdio("class = 0x%X, vendor = 0x%X, "
+ "device = 0x%X, model = 0x%X, ioport = 0x%X\n",
+ func->class, func->vendor, func->device,
+ model, (unsigned)card->ioport);
+
+ ret = if_sdio_prog_firmware(card);
+ if (ret)
+ goto reclaim;
+
+ priv = libertas_add_card(card, &func->dev);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto reclaim;
+ }
+
+ card->priv = priv;
+
+ priv->card = card;
+ priv->hw_host_to_card = if_sdio_host_to_card;
+ priv->hw_get_int_status = if_sdio_get_int_status;
+ priv->hw_read_event_cause = if_sdio_read_event_cause;
+
+ priv->adapter->fw_ready = 1;
+
+ /*
+ * Enable interrupts now that everything is set up
+ */
+ sdio_claim_host(func);
+ sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
+ sdio_release_host(func);
+ if (ret)
+ goto reclaim;
+
+ ret = libertas_start_card(priv);
+ if (ret)
+ goto err_activate_card;
+
+out:
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+
+err_activate_card:
+ flush_scheduled_work();
+ free_netdev(priv->dev);
+ kfree(priv->adapter);
+reclaim:
+ sdio_claim_host(func);
+release_int:
+ sdio_release_irq(func);
+disable:
+ sdio_disable_func(func);
+release:
+ sdio_release_host(func);
+free:
+ while (card->packets) {
+ packet = card->packets;
+ card->packets = card->packets->next;
+ kfree(packet);
+ }
+
+ kfree(card);
+
+ goto out;
+}
+
+static void if_sdio_remove(struct sdio_func *func)
+{
+ struct if_sdio_card *card;
+ struct if_sdio_packet *packet;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ card = sdio_get_drvdata(func);
+
+ card->priv->adapter->surpriseremoved = 1;
+
+ lbs_deb_sdio("call remove card\n");
+ libertas_stop_card(card->priv);
+ libertas_remove_card(card->priv);
+
+ flush_scheduled_work();
+
+ sdio_claim_host(func);
+ sdio_release_irq(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ while (card->packets) {
+ packet = card->packets;
+ card->packets = card->packets->next;
+ kfree(packet);
+ }
+
+ kfree(card);
+
+ lbs_deb_leave(LBS_DEB_SDIO);
+}
+
+static struct sdio_driver if_sdio_driver = {
+ .name = "libertas_sdio",
+ .id_table = if_sdio_ids,
+ .probe = if_sdio_probe,
+ .remove = if_sdio_remove,
+};
+
+/*******************************************************************/
+/* Module functions */
+/*******************************************************************/
+
+static int if_sdio_init_module(void)
+{
+ int ret = 0;
+
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ printk(KERN_INFO "libertas_sdio: Libertas SDIO driver\n");
+ printk(KERN_INFO "libertas_sdio: Copyright Pierre Ossman\n");
+
+ ret = sdio_register_driver(&if_sdio_driver);
+
+ lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
+
+ return ret;
+}
+
+static void if_sdio_exit_module(void)
+{
+ lbs_deb_enter(LBS_DEB_SDIO);
+
+ sdio_unregister_driver(&if_sdio_driver);
+
+ lbs_deb_leave(LBS_DEB_SDIO);
+}
+
+module_init(if_sdio_init_module);
+module_exit(if_sdio_exit_module);
+
+MODULE_DESCRIPTION("Libertas SDIO WLAN Driver");
+MODULE_AUTHOR("Pierre Ossman");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
new file mode 100644
index 00000000000..dfcaea7b168
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -0,0 +1,45 @@
+/*
+ * linux/drivers/net/wireless/libertas/if_sdio.h
+ *
+ * Copyright 2007 Pierre Ossman
+ *
+ * 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.
+ */
+
+#ifndef LIBERTAS_IF_SDIO_H
+#define LIBERTAS_IF_SDIO_H
+
+#define IF_SDIO_IOPORT 0x00
+
+#define IF_SDIO_H_INT_MASK 0x04
+#define IF_SDIO_H_INT_OFLOW 0x08
+#define IF_SDIO_H_INT_UFLOW 0x04
+#define IF_SDIO_H_INT_DNLD 0x02
+#define IF_SDIO_H_INT_UPLD 0x01
+
+#define IF_SDIO_H_INT_STATUS 0x05
+#define IF_SDIO_H_INT_RSR 0x06
+#define IF_SDIO_H_INT_STATUS2 0x07
+
+#define IF_SDIO_RD_BASE 0x10
+
+#define IF_SDIO_STATUS 0x20
+#define IF_SDIO_IO_RDY 0x08
+#define IF_SDIO_CIS_RDY 0x04
+#define IF_SDIO_UL_RDY 0x02
+#define IF_SDIO_DL_RDY 0x01
+
+#define IF_SDIO_C_INT_MASK 0x24
+#define IF_SDIO_C_INT_STATUS 0x28
+#define IF_SDIO_C_INT_RSR 0x2C
+
+#define IF_SDIO_SCRATCH 0x34
+#define IF_SDIO_SCRATCH_OLD 0x80fe
+#define IF_SDIO_FIRMWARE_OK 0xfedc
+
+#define IF_SDIO_EVENT 0x80fc
+
+#endif
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index f464b82c7d5..2a8fc431099 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -74,22 +74,12 @@ struct netfront_info {
struct napi_struct napi;
- struct xen_netif_tx_front_ring tx;
- struct xen_netif_rx_front_ring rx;
-
- spinlock_t tx_lock;
- spinlock_t rx_lock;
-
unsigned int evtchn;
+ struct xenbus_device *xbdev;
- /* Receive-ring batched refills. */
-#define RX_MIN_TARGET 8
-#define RX_DFL_MIN_TARGET 64
-#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
- unsigned rx_min_target, rx_max_target, rx_target;
- struct sk_buff_head rx_batch;
-
- struct timer_list rx_refill_timer;
+ spinlock_t tx_lock;
+ struct xen_netif_tx_front_ring tx;
+ int tx_ring_ref;
/*
* {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries
@@ -108,14 +98,23 @@ struct netfront_info {
grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
unsigned tx_skb_freelist;
+ spinlock_t rx_lock ____cacheline_aligned_in_smp;
+ struct xen_netif_rx_front_ring rx;
+ int rx_ring_ref;
+
+ /* Receive-ring batched refills. */
+#define RX_MIN_TARGET 8
+#define RX_DFL_MIN_TARGET 64
+#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
+ unsigned rx_min_target, rx_max_target, rx_target;
+ struct sk_buff_head rx_batch;
+
+ struct timer_list rx_refill_timer;
+
struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
grant_ref_t gref_rx_head;
grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
- struct xenbus_device *xbdev;
- int tx_ring_ref;
- int rx_ring_ref;
-
unsigned long rx_pfn_array[NET_RX_RING_SIZE];
struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
struct mmu_update rx_mmu[NET_RX_RING_SIZE];
@@ -1527,7 +1526,7 @@ static int xennet_connect(struct net_device *dev)
if (!feature_rx_copy) {
dev_info(&dev->dev,
- "backend does not support copying recieve path");
+ "backend does not support copying receive path\n");
return -ENODEV;
}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 864f09fd9f8..b47bb2d7476 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -12,6 +12,7 @@
*
*/
#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/device.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
@@ -94,3 +95,23 @@ int of_bus_type_init(struct bus_type *bus, const char *name)
bus->resume = of_platform_device_resume;
return bus_register(bus);
}
+
+int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
+{
+ /* initialize common driver fields */
+ if (!drv->driver.name)
+ drv->driver.name = drv->name;
+ if (!drv->driver.owner)
+ drv->driver.owner = drv->owner;
+ drv->driver.bus = bus;
+
+ /* register with core */
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(of_register_driver);
+
+void of_unregister_driver(struct of_platform_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(of_unregister_driver);
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index ff9f3445353..5bbff2028f8 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -275,35 +275,6 @@ void parport_close(struct pardevice *dev)
parport_unregister_device(dev);
}
-/**
- * parport_device_num - convert device coordinates
- * @parport: parallel port number
- * @mux: multiplexor port number (-1 for no multiplexor)
- * @daisy: daisy chain address (-1 for no daisy chain address)
- *
- * This tries to locate a device on the given parallel port,
- * multiplexor port and daisy chain address, and returns its
- * device number or %-ENXIO if no device with those coordinates
- * exists.
- **/
-
-int parport_device_num(int parport, int mux, int daisy)
-{
- int res = -ENXIO;
- struct daisydev *dev;
-
- spin_lock(&topology_lock);
- dev = topology;
- while (dev && dev->port->portnum != parport &&
- dev->port->muxport != mux && dev->daisy != daisy)
- dev = dev->next;
- if (dev)
- res = dev->devnum;
- spin_unlock(&topology_lock);
-
- return res;
-}
-
/* Send a daisy-chain-style CPP command packet. */
static int cpp_daisy(struct parport *port, int cmd)
{
diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index bdbdab9285c..ed82e41210d 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -237,7 +237,7 @@ static int do_hardware_modes (ctl_table *table, int write,
#define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \
.mode = 0555, .child = CHILD }
#define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD }
-#define PARPORT_DEVICES_ROOT_DIR { .ctl_name = DEV_PARPORT_DEVICES, .procname = "devices", \
+#define PARPORT_DEVICES_ROOT_DIR { .procname = "devices", \
.mode = 0555, .child = NULL }
static const unsigned long parport_min_timeslice_value =
@@ -266,7 +266,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.sysctl_header = NULL,
{
{
- .ctl_name = DEV_PARPORT_SPINTIME,
.procname = "spintime",
.data = NULL,
.maxlen = sizeof(int),
@@ -276,7 +275,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.extra2 = (void*) &parport_max_spintime_value
},
{
- .ctl_name = DEV_PARPORT_BASE_ADDR,
.procname = "base-addr",
.data = NULL,
.maxlen = 0,
@@ -284,7 +282,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_hardware_base_addr
},
{
- .ctl_name = DEV_PARPORT_IRQ,
.procname = "irq",
.data = NULL,
.maxlen = 0,
@@ -292,7 +289,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_hardware_irq
},
{
- .ctl_name = DEV_PARPORT_DMA,
.procname = "dma",
.data = NULL,
.maxlen = 0,
@@ -300,7 +296,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_hardware_dma
},
{
- .ctl_name = DEV_PARPORT_MODES,
.procname = "modes",
.data = NULL,
.maxlen = 0,
@@ -310,7 +305,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
PARPORT_DEVICES_ROOT_DIR,
#ifdef CONFIG_PARPORT_1284
{
- .ctl_name = DEV_PARPORT_AUTOPROBE,
.procname = "autoprobe",
.data = NULL,
.maxlen = 0,
@@ -318,7 +312,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_autoprobe
},
{
- .ctl_name = DEV_PARPORT_AUTOPROBE + 1,
.procname = "autoprobe0",
.data = NULL,
.maxlen = 0,
@@ -326,7 +319,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_autoprobe
},
{
- .ctl_name = DEV_PARPORT_AUTOPROBE + 2,
.procname = "autoprobe1",
.data = NULL,
.maxlen = 0,
@@ -334,7 +326,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_autoprobe
},
{
- .ctl_name = DEV_PARPORT_AUTOPROBE + 3,
.procname = "autoprobe2",
.data = NULL,
.maxlen = 0,
@@ -342,7 +333,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
.proc_handler = &do_autoprobe
},
{
- .ctl_name = DEV_PARPORT_AUTOPROBE + 4,
.procname = "autoprobe3",
.data = NULL,
.maxlen = 0,
@@ -354,7 +344,6 @@ static const struct parport_sysctl_table parport_sysctl_template = {
},
{
{
- .ctl_name = DEV_PARPORT_DEVICES_ACTIVE,
.procname = "active",
.data = NULL,
.maxlen = 0,
@@ -393,7 +382,6 @@ parport_device_sysctl_template = {
.sysctl_header = NULL,
{
{
- .ctl_name = DEV_PARPORT_DEVICE_TIMESLICE,
.procname = "timeslice",
.data = NULL,
.maxlen = sizeof(int),
@@ -449,7 +437,6 @@ parport_default_sysctl_table = {
.sysctl_header = NULL,
{
{
- .ctl_name = DEV_PARPORT_DEFAULT_TIMESLICE,
.procname = "timeslice",
.data = &parport_default_timeslice,
.maxlen = sizeof(parport_default_timeslice),
@@ -459,7 +446,6 @@ parport_default_sysctl_table = {
.extra2 = (void*) &parport_max_timeslice_value
},
{
- .ctl_name = DEV_PARPORT_DEFAULT_SPINTIME,
.procname = "spintime",
.data = &parport_default_spintime,
.maxlen = sizeof(parport_default_spintime),
@@ -502,7 +488,7 @@ int parport_proc_register(struct parport *port)
t->device_dir[0].extra1 = port;
- for (i = 0; i < 8; i++)
+ for (i = 0; i < 5; i++)
t->vars[i].extra1 = port;
t->vars[0].data = &port->spintime;
@@ -512,7 +498,7 @@ int parport_proc_register(struct parport *port)
t->vars[6 + i].extra2 = &port->probe_info[i];
t->port_dir[0].procname = port->name;
- t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */
+ t->port_dir[0].ctl_name = 0;
t->port_dir[0].child = t->vars;
t->parport_dir[0].child = t->port_dir;
@@ -551,26 +537,12 @@ int parport_device_proc_register(struct pardevice *device)
t->dev_dir[0].child = t->parport_dir;
t->parport_dir[0].child = t->port_dir;
t->port_dir[0].procname = port->name;
- t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */
+ t->port_dir[0].ctl_name = 0;
t->port_dir[0].child = t->devices_root_dir;
t->devices_root_dir[0].child = t->device_dir;
-#ifdef CONFIG_PARPORT_1284
-
- t->device_dir[0].ctl_name =
- parport_device_num(port->number, port->muxport,
- device->daisy)
- + 1; /* nb 0 isn't legal here */
-
-#else /* No IEEE 1284 support */
-
- /* parport_device_num isn't available. */
- t->device_dir[0].ctl_name = 1;
-
-#endif /* IEEE 1284 support or not */
-
+ t->device_dir[0].ctl_name = 0;
t->device_dir[0].procname = device->name;
- t->device_dir[0].extra1 = device;
t->device_dir[0].child = t->vars;
t->vars[0].data = &device->timeslice;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index c0c77f82d05..519b4ff79f7 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -2,9 +2,7 @@
# PCCARD (PCMCIA/CardBus) bus subsystem configuration
#
-menu "PCCARD (PCMCIA/CardBus) support"
-
-config PCCARD
+menuconfig PCCARD
tristate "PCCard (PCMCIA/CardBus) support"
depends on HOTPLUG
---help---
@@ -271,6 +269,13 @@ config AT91_CF
Say Y here to support the CompactFlash controller on AT91 chips.
Or choose M to compile the driver as a module named "at91_cf".
+config ELECTRA_CF
+ tristate "Electra CompactFlash Controller"
+ depends on PCMCIA && PPC_PASEMI
+ help
+ Say Y here to support the CompactFlash controller on the
+ PA Semi Electra eval board.
+
config PCCARD_NONSTATIC
tristate
@@ -278,5 +283,3 @@ config PCCARD_IODYN
bool
endif # PCCARD
-
-endmenu
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 4276965517f..6f6478ba717 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
obj-$(CONFIG_OMAP_CF) += omap_cf.o
obj-$(CONFIG_AT91_CF) += at91_cf.o
+obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
sa11xx_core-y += soc_common.o sa11xx_base.o
pxa2xx_core-y += soc_common.o pxa2xx_base.o
@@ -69,4 +70,5 @@ sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o
pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
+pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x270.o
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 01874b0bb03..ce9d5c44a7b 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -50,7 +50,10 @@
#include <asm/au1000.h>
#include <asm/au1000_pcmcia.h>
-#include <asm/xxs1500.h>
+
+#define PCMCIA_MAX_SOCK 0
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+#define PCMCIA_IRQ AU1000_GPIO_4
#if 0
#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index d154dee76e7..06a85d7d5aa 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -25,6 +25,7 @@
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
@@ -401,6 +402,15 @@ EXPORT_SYMBOL(pcmcia_replace_cis);
======================================================================*/
+static inline u16 cis_get_u16(void *ptr)
+{
+ return le16_to_cpu(get_unaligned((__le16 *) ptr));
+}
+static inline u32 cis_get_u32(void *ptr)
+{
+ return le32_to_cpu(get_unaligned((__le32 *) ptr));
+}
+
typedef struct tuple_flags {
u_int link_space:4;
u_int has_link:1;
@@ -461,7 +471,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
/* Get indirect link from the MFC tuple */
read_cis_cache(s, LINK_SPACE(tuple->Flags),
tuple->LinkOffset, 5, link);
- ofs = le32_to_cpu(*(__le32 *)(link+1));
+ ofs = cis_get_u32(link + 1);
SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
/* Move to the next indirect link */
tuple->LinkOffset += 5;
@@ -668,10 +678,10 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
u_char *p;
if (tuple->TupleDataLen < 5)
return CS_BAD_TUPLE;
- p = (u_char *)tuple->TupleData;
- csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2;
- csum->len = le16_to_cpu(*(__le16 *)(p + 2));
- csum->sum = *(p+4);
+ p = (u_char *) tuple->TupleData;
+ csum->addr = tuple->CISOffset + cis_get_u16(p) - 2;
+ csum->len = cis_get_u16(p + 2);
+ csum->sum = *(p + 4);
return CS_SUCCESS;
}
@@ -681,7 +691,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
{
if (tuple->TupleDataLen < 4)
return CS_BAD_TUPLE;
- link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);
+ link->addr = cis_get_u32(tuple->TupleData);
return CS_SUCCESS;
}
@@ -700,7 +710,8 @@ static int parse_longlink_mfc(tuple_t *tuple,
return CS_BAD_TUPLE;
for (i = 0; i < link->nfn; i++) {
link->fn[i].space = *p; p++;
- link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;
+ link->fn[i].addr = cis_get_u32(p);
+ p += 4;
}
return CS_SUCCESS;
}
@@ -787,12 +798,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
{
- __le16 *p;
if (tuple->TupleDataLen < 4)
return CS_BAD_TUPLE;
- p = (__le16 *)tuple->TupleData;
- m->manf = le16_to_cpu(p[0]);
- m->card = le16_to_cpu(p[1]);
+ m->manf = cis_get_u16(tuple->TupleData);
+ m->card = cis_get_u16(tuple->TupleData + 2);
return CS_SUCCESS;
}
@@ -1091,7 +1100,7 @@ static int parse_cftable_entry(tuple_t *tuple,
break;
case 0x20:
entry->mem.nwin = 1;
- entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
+ entry->mem.win[0].len = cis_get_u16(p) << 8;
entry->mem.win[0].card_addr = 0;
entry->mem.win[0].host_addr = 0;
p += 2;
@@ -1099,9 +1108,8 @@ static int parse_cftable_entry(tuple_t *tuple,
break;
case 0x40:
entry->mem.nwin = 1;
- entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
- entry->mem.win[0].card_addr =
- le16_to_cpu(*(__le16 *)(p+2)) << 8;
+ entry->mem.win[0].len = cis_get_u16(p) << 8;
+ entry->mem.win[0].card_addr = cis_get_u16(p + 2) << 8;
entry->mem.win[0].host_addr = 0;
p += 4;
if (p > q) return CS_BAD_TUPLE;
@@ -1138,7 +1146,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
p = (u_char *)tuple->TupleData;
bar->attr = *p;
p += 2;
- bar->size = le32_to_cpu(*(__le32 *)p);
+ bar->size = cis_get_u32(p);
return CS_SUCCESS;
}
@@ -1151,7 +1159,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
return CS_BAD_TUPLE;
config->last_idx = *(++p);
p++;
- config->base = le32_to_cpu(*(__le32 *)p);
+ config->base = cis_get_u32(p);
config->subtuples = tuple->TupleDataLen - 6;
return CS_SUCCESS;
}
@@ -1267,7 +1275,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
v2->vers = p[0];
v2->comply = p[1];
- v2->dindex = le16_to_cpu(*(__le16 *)(p+2));
+ v2->dindex = cis_get_u16(p +2 );
v2->vspec8 = p[6];
v2->vspec9 = p[7];
v2->nhdr = p[8];
@@ -1308,8 +1316,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
fmt->type = p[0];
fmt->edc = p[1];
- fmt->offset = le32_to_cpu(*(__le32 *)(p+2));
- fmt->length = le32_to_cpu(*(__le32 *)(p+6));
+ fmt->offset = cis_get_u32(p + 2);
+ fmt->length = cis_get_u32(p + 6);
return CS_SUCCESS;
}
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 55baa1f0fcb..7bf78c12789 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -23,6 +23,7 @@
#include <linux/crc32.h>
#include <linux/firmware.h>
#include <linux/kref.h>
+#include <linux/dma-mapping.h>
#define IN_CARD_SERVICES
#include <pcmcia/cs_types.h>
@@ -670,6 +671,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
p_dev->dev.bus = &pcmcia_bus_type;
p_dev->dev.parent = s->dev.parent;
p_dev->dev.release = pcmcia_release_dev;
+ /* by default don't allow DMA */
+ p_dev->dma_mask = DMA_MASK_NONE;
+ p_dev->dev.dma_mask = &p_dev->dma_mask;
bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL);
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c
new file mode 100644
index 00000000000..0a6cea1316b
--- /dev/null
+++ b/drivers/pcmcia/electra_cf.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2007 PA Semi, Inc
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on drivers/pcmcia/omap_cf.c
+ *
+ * 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/kernel.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+
+#include <pcmcia/ss.h>
+#include <asm/of_platform.h>
+
+static const char driver_name[] = "electra-cf";
+
+struct electra_cf_socket {
+ struct pcmcia_socket socket;
+
+ struct timer_list timer;
+ unsigned present:1;
+ unsigned active:1;
+
+ struct of_device *ofdev;
+ unsigned long mem_phys;
+ void __iomem * mem_base;
+ unsigned long mem_size;
+ void __iomem * io_virt;
+ unsigned int io_base;
+ unsigned int io_size;
+ u_int irq;
+ struct resource iomem;
+ void __iomem * gpio_base;
+ int gpio_detect;
+ int gpio_vsense;
+ int gpio_3v;
+ int gpio_5v;
+};
+
+#define POLL_INTERVAL (2 * HZ)
+
+
+static int electra_cf_present(struct electra_cf_socket *cf)
+{
+ unsigned int gpio;
+
+ gpio = in_le32(cf->gpio_base+0x40);
+ return !(gpio & (1 << cf->gpio_detect));
+}
+
+static int electra_cf_ss_init(struct pcmcia_socket *s)
+{
+ return 0;
+}
+
+/* the timer is primarily to kick this socket's pccardd */
+static void electra_cf_timer(unsigned long _cf)
+{
+ struct electra_cf_socket *cf = (void *) _cf;
+ int present = electra_cf_present(cf);
+
+ if (present != cf->present) {
+ cf->present = present;
+ pcmcia_parse_events(&cf->socket, SS_DETECT);
+ }
+
+ if (cf->active)
+ mod_timer(&cf->timer, jiffies + POLL_INTERVAL);
+}
+
+static irqreturn_t electra_cf_irq(int irq, void *_cf)
+{
+ electra_cf_timer((unsigned long)_cf);
+ return IRQ_HANDLED;
+}
+
+static int electra_cf_get_status(struct pcmcia_socket *s, u_int *sp)
+{
+ struct electra_cf_socket *cf;
+
+ if (!sp)
+ return -EINVAL;
+
+ cf = container_of(s, struct electra_cf_socket, socket);
+
+ /* NOTE CF is always 3VCARD */
+ if (electra_cf_present(cf)) {
+ *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD;
+
+ s->pci_irq = cf->irq;
+ } else
+ *sp = 0;
+ return 0;
+}
+
+static int electra_cf_set_socket(struct pcmcia_socket *sock,
+ struct socket_state_t *s)
+{
+ unsigned int gpio;
+ unsigned int vcc;
+ struct electra_cf_socket *cf;
+
+ cf = container_of(sock, struct electra_cf_socket, socket);
+
+ /* "reset" means no power in our case */
+ vcc = (s->flags & SS_RESET) ? 0 : s->Vcc;
+
+ switch (vcc) {
+ case 0:
+ gpio = 0;
+ break;
+ case 33:
+ gpio = (1 << cf->gpio_3v);
+ break;
+ case 5:
+ gpio = (1 << cf->gpio_5v);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ gpio |= 1 << (cf->gpio_3v + 16); /* enwr */
+ gpio |= 1 << (cf->gpio_5v + 16); /* enwr */
+ out_le32(cf->gpio_base+0x90, gpio);
+
+ pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
+ driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
+
+ return 0;
+}
+
+static int electra_cf_set_io_map(struct pcmcia_socket *s,
+ struct pccard_io_map *io)
+{
+ return 0;
+}
+
+static int electra_cf_set_mem_map(struct pcmcia_socket *s,
+ struct pccard_mem_map *map)
+{
+ struct electra_cf_socket *cf;
+
+ if (map->card_start)
+ return -EINVAL;
+ cf = container_of(s, struct electra_cf_socket, socket);
+ map->static_start = cf->mem_phys;
+ map->flags &= MAP_ACTIVE|MAP_ATTRIB;
+ if (!(map->flags & MAP_ATTRIB))
+ map->static_start += 0x800;
+ return 0;
+}
+
+static struct pccard_operations electra_cf_ops = {
+ .init = electra_cf_ss_init,
+ .get_status = electra_cf_get_status,
+ .set_socket = electra_cf_set_socket,
+ .set_io_map = electra_cf_set_io_map,
+ .set_mem_map = electra_cf_set_mem_map,
+};
+
+static int __devinit electra_cf_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device *device = &ofdev->dev;
+ struct device_node *np = ofdev->node;
+ struct electra_cf_socket *cf;
+ struct resource mem, io;
+ int status;
+ const unsigned int *prop;
+ int err;
+ struct vm_struct *area;
+
+ err = of_address_to_resource(np, 0, &mem);
+ if (err)
+ return -EINVAL;
+
+ err = of_address_to_resource(np, 1, &io);
+ if (err)
+ return -EINVAL;
+
+ cf = kzalloc(sizeof *cf, GFP_KERNEL);
+ if (!cf)
+ return -ENOMEM;
+
+ setup_timer(&cf->timer, electra_cf_timer, (unsigned long)cf);
+ cf->irq = NO_IRQ;
+
+ cf->ofdev = ofdev;
+ cf->mem_phys = mem.start;
+ cf->mem_size = PAGE_ALIGN(mem.end - mem.start);
+ cf->mem_base = ioremap(cf->mem_phys, cf->mem_size);
+ cf->io_size = PAGE_ALIGN(io.end - io.start);
+
+ area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END);
+ if (area == NULL)
+ return -ENOMEM;
+
+ cf->io_virt = (void __iomem *)(area->addr);
+
+ cf->gpio_base = ioremap(0xfc103000, 0x1000);
+ dev_set_drvdata(device, cf);
+
+ if (!cf->mem_base || !cf->io_virt || !cf->gpio_base ||
+ (__ioremap_at(io.start, cf->io_virt, cf->io_size,
+ _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL)) {
+ dev_err(device, "can't ioremap ranges\n");
+ status = -ENOMEM;
+ goto fail1;
+ }
+
+
+ cf->io_base = (unsigned long)cf->io_virt - VMALLOC_END;
+
+ cf->iomem.start = (unsigned long)cf->mem_base;
+ cf->iomem.end = (unsigned long)cf->mem_base + (mem.end - mem.start);
+ cf->iomem.flags = IORESOURCE_MEM;
+
+ cf->irq = irq_of_parse_and_map(np, 0);
+
+ status = request_irq(cf->irq, electra_cf_irq, IRQF_SHARED,
+ driver_name, cf);
+ if (status < 0) {
+ dev_err(device, "request_irq failed\n");
+ goto fail1;
+ }
+
+ cf->socket.pci_irq = cf->irq;
+
+ prop = of_get_property(np, "card-detect-gpio", NULL);
+ if (!prop)
+ goto fail1;
+ cf->gpio_detect = *prop;
+
+ prop = of_get_property(np, "card-vsense-gpio", NULL);
+ if (!prop)
+ goto fail1;
+ cf->gpio_vsense = *prop;
+
+ prop = of_get_property(np, "card-3v-gpio", NULL);
+ if (!prop)
+ goto fail1;
+ cf->gpio_3v = *prop;
+
+ prop = of_get_property(np, "card-5v-gpio", NULL);
+ if (!prop)
+ goto fail1;
+ cf->gpio_5v = *prop;
+
+ cf->socket.io_offset = cf->io_base;
+
+ /* reserve chip-select regions */
+ if (!request_mem_region(cf->mem_phys, cf->mem_size, driver_name)) {
+ status = -ENXIO;
+ dev_err(device, "Can't claim memory region\n");
+ goto fail1;
+ }
+
+ if (!request_region(cf->io_base, cf->io_size, driver_name)) {
+ status = -ENXIO;
+ dev_err(device, "Can't claim I/O region\n");
+ goto fail2;
+ }
+
+ cf->socket.owner = THIS_MODULE;
+ cf->socket.dev.parent = &ofdev->dev;
+ cf->socket.ops = &electra_cf_ops;
+ cf->socket.resource_ops = &pccard_static_ops;
+ cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP |
+ SS_CAP_MEM_ALIGN;
+ cf->socket.map_size = 0x800;
+
+ status = pcmcia_register_socket(&cf->socket);
+ if (status < 0) {
+ dev_err(device, "pcmcia_register_socket failed\n");
+ goto fail3;
+ }
+
+ dev_info(device, "at mem 0x%lx io 0x%lx irq %d\n",
+ cf->mem_phys, io.start, cf->irq);
+
+ cf->active = 1;
+ electra_cf_timer((unsigned long)cf);
+ return 0;
+
+fail3:
+ release_region(cf->io_base, cf->io_size);
+fail2:
+ release_mem_region(cf->mem_phys, cf->mem_size);
+fail1:
+ if (cf->irq != NO_IRQ)
+ free_irq(cf->irq, cf);
+
+ if (cf->io_virt)
+ __iounmap_at(cf->io_virt, cf->io_size);
+ if (cf->mem_base)
+ iounmap(cf->mem_base);
+ if (cf->gpio_base)
+ iounmap(cf->gpio_base);
+ device_init_wakeup(&ofdev->dev, 0);
+ kfree(cf);
+ return status;
+
+}
+
+static int __devexit electra_cf_remove(struct of_device *ofdev)
+{
+ struct device *device = &ofdev->dev;
+ struct electra_cf_socket *cf;
+
+ cf = dev_get_drvdata(device);
+
+ cf->active = 0;
+ pcmcia_unregister_socket(&cf->socket);
+ free_irq(cf->irq, cf);
+ del_timer_sync(&cf->timer);
+
+ __iounmap_at(cf->io_virt, cf->io_size);
+ iounmap(cf->mem_base);
+ iounmap(cf->gpio_base);
+ release_mem_region(cf->mem_phys, cf->mem_size);
+ release_region(cf->io_base, cf->io_size);
+
+ kfree(cf);
+
+ return 0;
+}
+
+static struct of_device_id electra_cf_match[] = {
+ {
+ .compatible = "electra-cf",
+ },
+ {},
+};
+
+static struct of_platform_driver electra_cf_driver = {
+ .name = (char *)driver_name,
+ .match_table = electra_cf_match,
+ .probe = electra_cf_probe,
+ .remove = electra_cf_remove,
+};
+
+static int __init electra_cf_init(void)
+{
+ return of_register_platform_driver(&electra_cf_driver);
+}
+module_init(electra_cf_init);
+
+static void __exit electra_cf_exit(void)
+{
+ of_unregister_platform_driver(&electra_cf_driver);
+}
+module_exit(electra_cf_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
+MODULE_DESCRIPTION("PA Semi Electra CF driver");
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index dca9f8549b3..874923fcb2f 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -58,7 +58,7 @@ static inline u_int pxa2xx_mcxx_asst(u_int pcmcia_cycle_ns,
u_int mem_clk_10khz)
{
u_int code = pcmcia_cycle_ns * mem_clk_10khz;
- return (code / 300000) + ((code % 300000) ? 1 : 0) - 1;
+ return (code / 300000) + ((code % 300000) ? 1 : 0) + 1;
}
static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns,
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
new file mode 100644
index 00000000000..fbf2f3a6984
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -0,0 +1,175 @@
+/*
+ * linux/drivers/pcmcia/pxa/pxa_cm_x270.c
+ *
+ * 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.
+ *
+ * Compulab Ltd., 2003, 2007
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+
+#include <pcmcia/ss.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/cm-x270.h>
+
+#include "soc_common.h"
+
+static struct pcmcia_irqs irqs[] = {
+ { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
+ { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
+};
+
+static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
+ GPIO_bit(GPIO49_nPWE) |
+ GPIO_bit(GPIO50_nPIOR) |
+ GPIO_bit(GPIO51_nPIOW) |
+ GPIO_bit(GPIO85_nPCE_1) |
+ GPIO_bit(GPIO54_nPCE_2);
+
+ pxa_gpio_mode(GPIO48_nPOE_MD);
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+ pxa_gpio_mode(GPIO50_nPIOR_MD);
+ pxa_gpio_mode(GPIO51_nPIOW_MD);
+ pxa_gpio_mode(GPIO85_nPCE_1_MD);
+ pxa_gpio_mode(GPIO54_nPCE_2_MD);
+ pxa_gpio_mode(GPIO55_nPREG_MD);
+ pxa_gpio_mode(GPIO56_nPWAIT_MD);
+ pxa_gpio_mode(GPIO57_nIOIS16_MD);
+
+ /* Reset signal */
+ pxa_gpio_mode(GPIO53_nPCE_2 | GPIO_OUT);
+ GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+
+ set_irq_type(PCMCIA_S0_CD_VALID, IRQ_TYPE_EDGE_BOTH);
+ set_irq_type(PCMCIA_S1_CD_VALID, IRQ_TYPE_EDGE_BOTH);
+
+ /* irq's for slots: */
+ set_irq_type(PCMCIA_S0_RDYINT, IRQ_TYPE_EDGE_FALLING);
+ set_irq_type(PCMCIA_S1_RDYINT, IRQ_TYPE_EDGE_FALLING);
+
+ skt->irq = (skt->nr == 0) ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+ return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+}
+
+static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
+{
+ soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+ set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID), IRQ_TYPE_NONE);
+ set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID), IRQ_TYPE_NONE);
+
+ set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_RDYINT), IRQ_TYPE_NONE);
+ set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_RDYINT), IRQ_TYPE_NONE);
+}
+
+
+static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+ struct pcmcia_state *state)
+{
+ state->detect = (PCC_DETECT(skt->nr) == 0) ? 1 : 0;
+ state->ready = (PCC_READY(skt->nr) == 0) ? 0 : 1;
+ state->bvd1 = 1;
+ state->bvd2 = 1;
+ state->vs_3v = 0;
+ state->vs_Xv = 0;
+ state->wrprot = 0; /* not available */
+}
+
+
+static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+ const socket_state_t *state)
+{
+ GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+ pxa_gpio_mode(GPIO49_nPWE | GPIO_OUT);
+
+ switch (skt->nr) {
+ case 0:
+ if (state->flags & SS_RESET) {
+ GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+ GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+ udelay(10);
+ GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+ GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+ }
+ break;
+ case 1:
+ if (state->flags & SS_RESET) {
+ GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+ GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+ udelay(10);
+ GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2);
+ GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE);
+ }
+ break;
+ }
+
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+
+ return 0;
+}
+
+static void cmx270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void cmx270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+
+static struct pcmcia_low_level cmx270_pcmcia_ops = {
+ .owner = THIS_MODULE,
+ .hw_init = cmx270_pcmcia_hw_init,
+ .hw_shutdown = cmx270_pcmcia_shutdown,
+ .socket_state = cmx270_pcmcia_socket_state,
+ .configure_socket = cmx270_pcmcia_configure_socket,
+ .socket_init = cmx270_pcmcia_socket_init,
+ .socket_suspend = cmx270_pcmcia_socket_suspend,
+ .nr = 2,
+};
+
+static struct platform_device *cmx270_pcmcia_device;
+
+static int __init cmx270_pcmcia_init(void)
+{
+ int ret;
+
+ cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+
+ if (!cmx270_pcmcia_device)
+ return -ENOMEM;
+
+ cmx270_pcmcia_device->dev.platform_data = &cmx270_pcmcia_ops;
+
+ printk(KERN_INFO "Registering cm-x270 PCMCIA interface.\n");
+ ret = platform_device_add(cmx270_pcmcia_device);
+
+ if (ret)
+ platform_device_put(cmx270_pcmcia_device);
+
+ return ret;
+}
+
+static void __exit cmx270_pcmcia_exit(void)
+{
+ platform_device_unregister(cmx270_pcmcia_device);
+}
+
+module_init(cmx270_pcmcia_init);
+module_exit(cmx270_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("CM-x270 PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index 5e9b9a3fd02..1510d6cde3e 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -30,35 +30,6 @@
#include "sa1111_generic.h"
static int
-lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
- /*
- * Setup default state of GPIO outputs
- * before we enable them as outputs.
- */
- GPSR(GPIO48_nPOE) =
- GPIO_bit(GPIO48_nPOE) |
- GPIO_bit(GPIO49_nPWE) |
- GPIO_bit(GPIO50_nPIOR) |
- GPIO_bit(GPIO51_nPIOW) |
- GPIO_bit(GPIO52_nPCE_1) |
- GPIO_bit(GPIO53_nPCE_2);
-
- pxa_gpio_mode(GPIO48_nPOE_MD);
- pxa_gpio_mode(GPIO49_nPWE_MD);
- pxa_gpio_mode(GPIO50_nPIOR_MD);
- pxa_gpio_mode(GPIO51_nPIOW_MD);
- pxa_gpio_mode(GPIO52_nPCE_1_MD);
- pxa_gpio_mode(GPIO53_nPCE_2_MD);
- pxa_gpio_mode(GPIO54_pSKTSEL_MD);
- pxa_gpio_mode(GPIO55_nPREG_MD);
- pxa_gpio_mode(GPIO56_nPWAIT_MD);
- pxa_gpio_mode(GPIO57_nIOIS16_MD);
-
- return sa1111_pcmcia_hw_init(skt);
-}
-
-static int
lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
@@ -230,7 +201,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
static struct pcmcia_low_level lubbock_pcmcia_ops = {
.owner = THIS_MODULE,
- .hw_init = lubbock_pcmcia_hw_init,
+ .hw_init = sa1111_pcmcia_hw_init,
.hw_shutdown = sa1111_pcmcia_hw_shutdown,
.socket_state = sa1111_pcmcia_socket_state,
.configure_socket = lubbock_pcmcia_configure_socket,
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index f6722ba0dd1..6fa5eaaab8a 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -43,24 +43,6 @@ static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
* Setup default state of GPIO outputs
* before we enable them as outputs.
*/
- GPSR(GPIO48_nPOE) =
- GPIO_bit(GPIO48_nPOE) |
- GPIO_bit(GPIO49_nPWE) |
- GPIO_bit(GPIO50_nPIOR) |
- GPIO_bit(GPIO51_nPIOW) |
- GPIO_bit(GPIO85_nPCE_1) |
- GPIO_bit(GPIO54_nPCE_2);
-
- pxa_gpio_mode(GPIO48_nPOE_MD);
- pxa_gpio_mode(GPIO49_nPWE_MD);
- pxa_gpio_mode(GPIO50_nPIOR_MD);
- pxa_gpio_mode(GPIO51_nPIOW_MD);
- pxa_gpio_mode(GPIO85_nPCE_1_MD);
- pxa_gpio_mode(GPIO54_nPCE_2_MD);
- pxa_gpio_mode(GPIO79_pSKTSEL_MD);
- pxa_gpio_mode(GPIO55_nPREG_MD);
- pxa_gpio_mode(GPIO56_nPWAIT_MD);
- pxa_gpio_mode(GPIO57_nIOIS16_MD);
skt->irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile
index a381a92fd1b..26f5abc9c3f 100644
--- a/drivers/pnp/Makefile
+++ b/drivers/pnp/Makefile
@@ -7,3 +7,7 @@ obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quir
obj-$(CONFIG_PNPACPI) += pnpacpi/
obj-$(CONFIG_PNPBIOS) += pnpbios/
obj-$(CONFIG_ISAPNP) += isapnp/
+
+ifeq ($(CONFIG_PNP_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index 6c0440c20e3..da1c9909eb4 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -104,10 +104,6 @@ int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card)
{
struct pnp_id *ptr;
- if (!id)
- return -EINVAL;
- if (!card)
- return -EINVAL;
id->next = NULL;
ptr = card->id;
while (ptr && ptr->next)
@@ -124,8 +120,6 @@ static void pnp_free_card_ids(struct pnp_card *card)
struct pnp_id *id;
struct pnp_id *next;
- if (!card)
- return;
id = card->id;
while (id) {
next = id->next;
@@ -197,42 +191,39 @@ int pnp_add_card(struct pnp_card *card)
int error;
struct list_head *pos, *temp;
- if (!card || !card->protocol)
- return -EINVAL;
-
sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
card->number);
card->dev.parent = &card->protocol->dev;
card->dev.bus = NULL;
card->dev.release = &pnp_release_card;
error = device_register(&card->dev);
+ if (error) {
+ dev_err(&card->dev, "could not register (err=%d)\n", error);
+ return error;
+ }
- if (error == 0) {
- pnp_interface_attach_card(card);
- spin_lock(&pnp_lock);
- list_add_tail(&card->global_list, &pnp_cards);
- list_add_tail(&card->protocol_list, &card->protocol->cards);
- spin_unlock(&pnp_lock);
-
- /* we wait until now to add devices in order to ensure the drivers
- * will be able to use all of the related devices on the card
- * without waiting any unresonable length of time */
- list_for_each(pos, &card->devices) {
- struct pnp_dev *dev = card_to_pnp_dev(pos);
- __pnp_add_device(dev);
- }
+ pnp_interface_attach_card(card);
+ spin_lock(&pnp_lock);
+ list_add_tail(&card->global_list, &pnp_cards);
+ list_add_tail(&card->protocol_list, &card->protocol->cards);
+ spin_unlock(&pnp_lock);
- /* match with card drivers */
- list_for_each_safe(pos, temp, &pnp_card_drivers) {
- struct pnp_card_driver *drv =
- list_entry(pos, struct pnp_card_driver,
- global_list);
- card_probe(card, drv);
- }
- } else
- pnp_err("sysfs failure, card '%s' will be unavailable",
- card->dev.bus_id);
- return error;
+ /* we wait until now to add devices in order to ensure the drivers
+ * will be able to use all of the related devices on the card
+ * without waiting an unreasonable length of time */
+ list_for_each(pos, &card->devices) {
+ struct pnp_dev *dev = card_to_pnp_dev(pos);
+ __pnp_add_device(dev);
+ }
+
+ /* match with card drivers */
+ list_for_each_safe(pos, temp, &pnp_card_drivers) {
+ struct pnp_card_driver *drv =
+ list_entry(pos, struct pnp_card_driver,
+ global_list);
+ card_probe(card, drv);
+ }
+ return 0;
}
/**
@@ -243,8 +234,6 @@ void pnp_remove_card(struct pnp_card *card)
{
struct list_head *pos, *temp;
- if (!card)
- return;
device_unregister(&card->dev);
spin_lock(&pnp_lock);
list_del(&card->global_list);
@@ -263,8 +252,6 @@ void pnp_remove_card(struct pnp_card *card)
*/
int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev)
{
- if (!card || !dev || !dev->protocol)
- return -EINVAL;
dev->dev.parent = &card->dev;
dev->card_link = NULL;
snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%02x:%02x.%02x",
@@ -304,14 +291,15 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink,
struct pnp_card *card;
if (!clink || !id)
- goto done;
+ return NULL;
+
card = clink->card;
drv = clink->driver;
if (!from) {
pos = card->devices.next;
} else {
if (from->card != card)
- goto done;
+ return NULL;
pos = from->card_list.next;
}
while (pos != &card->devices) {
@@ -321,7 +309,6 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink,
pos = pos->next;
}
-done:
return NULL;
found:
@@ -348,8 +335,6 @@ void pnp_release_card_device(struct pnp_dev *dev)
{
struct pnp_card_driver *drv = dev->card_link->driver;
- if (!drv)
- return;
drv->link.remove = &card_remove;
device_release_driver(&dev->dev);
drv->link.remove = &card_remove_first;
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index d5964feb14d..7d366ca672d 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -125,9 +125,11 @@ int __pnp_add_device(struct pnp_dev *dev)
spin_unlock(&pnp_lock);
ret = device_register(&dev->dev);
- if (ret == 0)
- pnp_interface_attach_device(dev);
- return ret;
+ if (ret)
+ return ret;
+
+ pnp_interface_attach_device(dev);
+ return 0;
}
/*
@@ -138,12 +140,30 @@ int __pnp_add_device(struct pnp_dev *dev)
*/
int pnp_add_device(struct pnp_dev *dev)
{
+ int ret;
+
if (dev->card)
return -EINVAL;
+
dev->dev.parent = &dev->protocol->dev;
sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
dev->number);
- return __pnp_add_device(dev);
+ ret = __pnp_add_device(dev);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_PNP_DEBUG
+ {
+ struct pnp_id *id;
+
+ dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs",
+ dev->protocol->name);
+ for (id = dev->id; id; id = id->next)
+ printk(" %s", id->id);
+ printk(" (%s)\n", dev->active ? "active" : "disabled");
+ }
+#endif
+ return 0;
}
void __pnp_remove_device(struct pnp_dev *dev)
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 2fa64a6b25c..a262762c5b8 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -86,9 +86,6 @@ static int pnp_device_probe(struct device *dev)
pnp_dev = to_pnp_dev(dev);
pnp_drv = to_pnp_driver(dev->driver);
- pnp_dbg("match found with the PnP device '%s' and the driver '%s'",
- dev->bus_id, pnp_drv->name);
-
error = pnp_device_attach(pnp_dev);
if (error < 0)
return error;
@@ -116,6 +113,8 @@ static int pnp_device_probe(struct device *dev)
error = 0;
} else
goto fail;
+
+ dev_dbg(dev, "driver attached\n");
return error;
fail:
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index a0cfb75bbb8..31548044fdd 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -1,7 +1,7 @@
/*
* interface.c - contains everything related to the user interface
*
- * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@suse.cz>
+ * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2002 Adam Belay <ambx1@neo.rr.com>
*/
@@ -327,8 +327,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
if (dev->status & PNP_ATTACHED) {
retval = -EBUSY;
- pnp_info("Device %s cannot be configured because it is in use.",
- dev->dev.bus_id);
+ dev_info(&dev->dev, "in use; can't configure\n");
goto done;
}
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index b035d60a1dc..2c925b7cd93 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -1,6 +1,6 @@
/*
* ISA Plug & Play support
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ static int isapnp_rdp; /* Read Data Port */
static int isapnp_reset = 1; /* reset all PnP cards (deactivate) */
static int isapnp_verbose = 1; /* verbose mode */
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Generic ISA Plug & Play support");
module_param(isapnp_disable, int, 0);
MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
index 560ccb64081..2b8266c3d40 100644
--- a/drivers/pnp/isapnp/proc.c
+++ b/drivers/pnp/isapnp/proc.c
@@ -1,6 +1,6 @@
/*
* ISA Plug & Play support
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* 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/pnp/manager.c b/drivers/pnp/manager.c
index 0826287eef5..c6b3d4e63cc 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -1,7 +1,7 @@
/*
* manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
*
- * based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
+ * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com>
*/
@@ -22,8 +22,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
unsigned long *flags;
if (idx >= PNP_MAX_PORT) {
- pnp_err
- ("More than 4 ports is incompatible with pnp specifications.");
+ dev_err(&dev->dev, "too many I/O port resources\n");
/* pretend we were successful so at least the manager won't try again */
return 1;
}
@@ -64,8 +63,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
unsigned long *flags;
if (idx >= PNP_MAX_MEM) {
- pnp_err
- ("More than 8 mems is incompatible with pnp specifications.");
+ dev_err(&dev->dev, "too many memory resources\n");
/* pretend we were successful so at least the manager won't try again */
return 1;
}
@@ -122,8 +120,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
};
if (idx >= PNP_MAX_IRQ) {
- pnp_err
- ("More than 2 irqs is incompatible with pnp specifications.");
+ dev_err(&dev->dev, "too many IRQ resources\n");
/* pretend we were successful so at least the manager won't try again */
return 1;
}
@@ -161,7 +158,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
return 0;
}
-static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
+static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
{
resource_size_t *start, *end;
unsigned long *flags;
@@ -173,15 +170,13 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
};
if (idx >= PNP_MAX_DMA) {
- pnp_err
- ("More than 2 dmas is incompatible with pnp specifications.");
- /* pretend we were successful so at least the manager won't try again */
- return 1;
+ dev_err(&dev->dev, "too many DMA resources\n");
+ return;
}
/* check if this resource has been manually set, if so skip */
if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO))
- return 1;
+ return;
start = &dev->res.dma_resource[idx].start;
end = &dev->res.dma_resource[idx].end;
@@ -191,19 +186,17 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
*flags |= rule->flags | IORESOURCE_DMA;
*flags &= ~IORESOURCE_UNSET;
- if (!rule->map) {
- *flags |= IORESOURCE_DISABLED;
- return 1; /* skip disabled resource requests */
- }
-
for (i = 0; i < 8; i++) {
if (rule->map & (1 << xtab[i])) {
*start = *end = xtab[i];
if (pnp_check_dma(dev, idx))
- return 1;
+ return;
}
}
- return 0;
+#ifdef MAX_DMA_CHANNELS
+ *start = *end = MAX_DMA_CHANNELS;
+#endif
+ *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
}
/**
@@ -330,8 +323,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
irq = irq->next;
}
while (dma) {
- if (!pnp_assign_dma(dev, dma, ndma))
- goto fail;
+ pnp_assign_dma(dev, dma, ndma);
ndma++;
dma = dma->next;
}
@@ -367,8 +359,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
irq = irq->next;
}
while (dma) {
- if (!pnp_assign_dma(dev, dma, ndma))
- goto fail;
+ pnp_assign_dma(dev, dma, ndma);
ndma++;
dma = dma->next;
}
@@ -447,8 +438,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
int i = 1;
if (!pnp_can_configure(dev)) {
- pnp_dbg("Device %s does not support resource configuration.",
- dev->dev.bus_id);
+ dev_dbg(&dev->dev, "configuration not supported\n");
return -ENODEV;
}
@@ -465,7 +455,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
} while (dep);
}
- pnp_err("Unable to assign resources to device %s.", dev->dev.bus_id);
+ dev_err(&dev->dev, "unable to assign resources\n");
return -EBUSY;
}
@@ -478,17 +468,16 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
int pnp_start_dev(struct pnp_dev *dev)
{
if (!pnp_can_write(dev)) {
- pnp_dbg("Device %s does not support activation.",
- dev->dev.bus_id);
+ dev_dbg(&dev->dev, "activation not supported\n");
return -EINVAL;
}
if (dev->protocol->set(dev, &dev->res) < 0) {
- pnp_err("Failed to activate device %s.", dev->dev.bus_id);
+ dev_err(&dev->dev, "activation failed\n");
return -EIO;
}
- pnp_info("Device %s activated.", dev->dev.bus_id);
+ dev_info(&dev->dev, "activated\n");
return 0;
}
@@ -501,16 +490,15 @@ int pnp_start_dev(struct pnp_dev *dev)
int pnp_stop_dev(struct pnp_dev *dev)
{
if (!pnp_can_disable(dev)) {
- pnp_dbg("Device %s does not support disabling.",
- dev->dev.bus_id);
+ dev_dbg(&dev->dev, "disabling not supported\n");
return -EINVAL;
}
if (dev->protocol->disable(dev) < 0) {
- pnp_err("Failed to disable device %s.", dev->dev.bus_id);
+ dev_err(&dev->dev, "disable failed\n");
return -EIO;
}
- pnp_info("Device %s disabled.", dev->dev.bus_id);
+ dev_info(&dev->dev, "disabled\n");
return 0;
}
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index a5a372222d6..dada8990631 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -130,11 +130,16 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
#ifdef CONFIG_ACPI_SLEEP
static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{
- return acpi_bus_set_power((acpi_handle) dev->data,
- acpi_pm_device_sleep_state(&dev->dev,
- device_may_wakeup
- (&dev->dev),
- NULL));
+ int power_state;
+
+ power_state = acpi_pm_device_sleep_state(&dev->dev,
+ device_may_wakeup(&dev->dev),
+ NULL);
+ if (power_state < 0)
+ power_state = (state.event == PM_EVENT_ON) ?
+ ACPI_STATE_D0 : ACPI_STATE_D3;
+
+ return acpi_bus_set_power((acpi_handle) dev->data, power_state);
}
static int pnpacpi_resume(struct pnp_dev *dev)
@@ -166,7 +171,6 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
is_exclusive_device(device))
return 0;
- pnp_dbg("ACPI device : hid %s", acpi_device_hid(device));
dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
if (!dev) {
pnp_err("Out of memory");
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 0e3b8d0ff06..cd0a204d96d 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -85,6 +85,16 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
if (i >= PNP_MAX_IRQ)
return;
+#ifdef CONFIG_X86
+ if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE ||
+ polarity != ACPI_ACTIVE_HIGH)) {
+ pnp_warn("BIOS BUG: legacy PNP IRQ %d should be edge trigger, "
+ "active high", gsi);
+ triggering = ACPI_EDGE_SENSITIVE;
+ polarity = ACPI_ACTIVE_HIGH;
+ }
+#endif
+
res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
res->irq_resource[i].flags |= irq_flags(triggering, polarity);
irq = acpi_register_gsi(gsi, triggering, polarity);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 4e9fd37cff3..e33e03f7108 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -315,25 +315,31 @@ struct pnp_protocol pnpbios_protocol = {
.disable = pnpbios_disable_resources,
};
-static int insert_device(struct pnp_dev *dev, struct pnp_bios_node *node)
+static int insert_device(struct pnp_bios_node *node)
{
struct list_head *pos;
- struct pnp_dev *pnp_dev;
+ struct pnp_dev *dev;
struct pnp_id *dev_id;
char id[8];
/* check if the device is already added */
- dev->number = node->handle;
list_for_each(pos, &pnpbios_protocol.devices) {
- pnp_dev = list_entry(pos, struct pnp_dev, protocol_list);
- if (dev->number == pnp_dev->number)
+ dev = list_entry(pos, struct pnp_dev, protocol_list);
+ if (dev->number == node->handle)
return -1;
}
- /* set the initial values for the PnP device */
+ dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
+ if (!dev)
+ return -1;
+
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
- if (!dev_id)
+ if (!dev_id) {
+ kfree(dev);
return -1;
+ }
+
+ dev->number = node->handle;
pnpid32_to_pnpid(node->eisa_id, id);
memcpy(dev_id->id, id, 7);
pnp_add_id(dev_id, dev);
@@ -367,7 +373,6 @@ static void __init build_devlist(void)
unsigned int nodes_got = 0;
unsigned int devs = 0;
struct pnp_bios_node *node;
- struct pnp_dev *dev;
node = kzalloc(node_info.max_node_size, GFP_KERNEL);
if (!node)
@@ -388,12 +393,7 @@ static void __init build_devlist(void)
break;
}
nodes_got++;
- dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
- if (!dev)
- break;
- if (insert_device(dev, node) < 0)
- kfree(dev);
- else
+ if (insert_device(node) == 0)
devs++;
if (nodenum <= thisnodenum) {
printk(KERN_ERR
diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c
index 9d9841f24a8..bb19bc957ba 100644
--- a/drivers/pnp/pnpbios/proc.c
+++ b/drivers/pnp/pnpbios/proc.c
@@ -94,8 +94,9 @@ static int proc_read_escd(char *buf, char **start, off_t pos,
/* sanity check */
if (escd_size > MAX_SANE_ESCD_SIZE) {
- printk(KERN_ERR
- "PnPBIOS: proc_read_escd: ESCD size reported by BIOS read_escd call is too great\n");
+ printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by"
+ " BIOS read_escd call is too great\n");
+ kfree(tmpbuf);
return -EFBIG;
}
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 6b0cf0c2a08..e903b8c2b1f 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/io.h>
+#include <linux/kallsyms.h>
#include "base.h"
static void quirk_awe32_resources(struct pnp_dev *dev)
@@ -133,11 +134,18 @@ static struct pnp_fixup pnp_fixups[] = {
void pnp_fixup_device(struct pnp_dev *dev)
{
int i = 0;
+ void (*quirk)(struct pnp_dev *);
while (*pnp_fixups[i].id) {
if (compare_pnp_id(dev->id, pnp_fixups[i].id)) {
- pnp_dbg("Calling quirk for %s", dev->dev.bus_id);
- pnp_fixups[i].quirk_function(dev);
+ quirk = pnp_fixups[i].quirk_function;
+
+#ifdef DEBUG
+ dev_dbg(&dev->dev, "calling quirk 0x%p", quirk);
+ print_fn_descriptor_symbol(": %s()\n",
+ (unsigned long) *quirk);
+#endif
+ (*quirk)(dev);
}
i++;
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index ef1286900db..41d73a5e931 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -1,7 +1,7 @@
/*
* resource.c - Contains functions for registering and analyzing resource information
*
- * based on isapnp.c resource management (c) Jaroslav Kysela <perex@suse.cz>
+ * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com>
*/
@@ -51,7 +51,7 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
/* this should never happen but if it does we'll try to continue */
if (dev->independent)
- pnp_err("independent resource already registered");
+ dev_err(&dev->dev, "independent resource already registered\n");
dev->independent = option;
return option;
}
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index a06f980b3ac..55c4563986b 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -22,36 +22,39 @@ static const struct pnp_device_id pnp_dev_table[] = {
{"", 0}
};
-static void reserve_range(const char *pnpid, resource_size_t start,
+static void reserve_range(struct pnp_dev *dev, resource_size_t start,
resource_size_t end, int port)
{
- struct resource *res;
char *regionid;
+ const char *pnpid = dev->dev.bus_id;
+ struct resource *res;
regionid = kmalloc(16, GFP_KERNEL);
- if (regionid == NULL)
+ if (!regionid)
return;
+
snprintf(regionid, 16, "pnp %s", pnpid);
if (port)
res = request_region(start, end - start + 1, regionid);
else
res = request_mem_region(start, end - start + 1, regionid);
- if (res == NULL)
- kfree(regionid);
- else
+ if (res)
res->flags &= ~IORESOURCE_BUSY;
+ else
+ kfree(regionid);
+
/*
* Failures at this point are usually harmless. pci quirks for
* example do reserve stuff they know about too, so we may well
* have double reservations.
*/
- printk(KERN_INFO "pnp: %s: %s range 0x%llx-0x%llx %s reserved\n",
- pnpid, port ? "ioport" : "iomem",
- (unsigned long long)start, (unsigned long long)end,
- NULL != res ? "has been" : "could not be");
+ dev_info(&dev->dev, "%s range 0x%llx-0x%llx %s reserved\n",
+ port ? "ioport" : "iomem",
+ (unsigned long long) start, (unsigned long long) end,
+ res ? "has been" : "could not be");
}
-static void reserve_resources_of_dev(const struct pnp_dev *dev)
+static void reserve_resources_of_dev(struct pnp_dev *dev)
{
int i;
@@ -73,7 +76,7 @@ static void reserve_resources_of_dev(const struct pnp_dev *dev)
if (pnp_port_end(dev, i) < pnp_port_start(dev, i))
continue; /* invalid */
- reserve_range(dev->dev.bus_id, pnp_port_start(dev, i),
+ reserve_range(dev, pnp_port_start(dev, i),
pnp_port_end(dev, i), 1);
}
@@ -81,7 +84,7 @@ static void reserve_resources_of_dev(const struct pnp_dev *dev)
if (!pnp_mem_valid(dev, i))
continue;
- reserve_range(dev->dev.bus_id, pnp_mem_start(dev, i),
+ reserve_range(dev, pnp_mem_start(dev, i),
pnp_mem_end(dev, i), 0);
}
}
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index be7021ee361..bdb9b7285b3 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -366,7 +366,7 @@ static int ds2760_battery_probe(struct platform_device *pdev)
retval = power_supply_register(&pdev->dev, &di->bat);
if (retval) {
- dev_err(di->dev, "failed to register battery");
+ dev_err(di->dev, "failed to register battery\n");
goto batt_failed;
}
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 85e21614f86..397f4ce849d 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/notifier.h>
#include <linux/ioctl.h>
+#include <linux/fb.h>
#include <asm/firmware.h>
#include <asm/ps3av.h>
@@ -33,6 +34,8 @@
#define BUFSIZE 4096 /* vuart buf size */
#define PS3AV_BUF_SIZE 512 /* max packet size */
+static int safe_mode;
+
static int timeout = 5000; /* in msec ( 5 sec ) */
module_param(timeout, int, 0644);
@@ -491,10 +494,10 @@ static int ps3av_set_videomode(void)
return 0;
}
-static void ps3av_set_videomode_cont(u32 id, u32 old_id)
+static void ps3av_set_videomode_packet(u32 id)
{
struct ps3av_pkt_avb_param avb_param;
- int i;
+ unsigned int i;
u32 len = 0, av_video_cs;
const struct avset_video_mode *video_mode;
int res;
@@ -507,24 +510,6 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
ps3av->av_hw_conf.num_of_avmulti;
avb_param.num_of_av_audio_pkt = 0;
- /* video signal off */
- ps3av_set_video_disable_sig();
-
- /* Retail PS3 product doesn't support this */
- if (id & PS3AV_MODE_HDCP_OFF) {
- res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
- if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
- dev_dbg(&ps3av->dev->core, "Not supported\n");
- else if (res)
- dev_dbg(&ps3av->dev->core,
- "ps3av_cmd_av_hdmi_mode failed\n");
- } else if (old_id & PS3AV_MODE_HDCP_OFF) {
- res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
- if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
- dev_dbg(&ps3av->dev->core,
- "ps3av_cmd_av_hdmi_mode failed\n");
- }
-
/* video_pkt */
for (i = 0; i < avb_param.num_of_video_pkt; i++)
len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
@@ -555,6 +540,42 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
__func__);
else if (res)
dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
+}
+
+static void ps3av_set_videomode_cont(u32 id, u32 old_id)
+{
+ static int vesa = 0;
+ int res;
+
+ /* video signal off */
+ ps3av_set_video_disable_sig();
+
+ /*
+ * AV backend needs non-VESA mode setting at least one time
+ * when VESA mode is used.
+ */
+ if (vesa == 0 && (id & PS3AV_MODE_MASK) >= 11) {
+ /* vesa mode */
+ ps3av_set_videomode_packet(2); /* 480P */
+ }
+ vesa = 1;
+
+ /* Retail PS3 product doesn't support this */
+ if (id & PS3AV_MODE_HDCP_OFF) {
+ res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
+ if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
+ dev_dbg(&ps3av->dev->core, "Not supported\n");
+ else if (res)
+ dev_dbg(&ps3av->dev->core,
+ "ps3av_cmd_av_hdmi_mode failed\n");
+ } else if (old_id & PS3AV_MODE_HDCP_OFF) {
+ res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
+ if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
+ dev_dbg(&ps3av->dev->core,
+ "ps3av_cmd_av_hdmi_mode failed\n");
+ }
+
+ ps3av_set_videomode_packet(id);
msleep(1500);
/* av video mute */
@@ -567,165 +588,251 @@ static void ps3avd(struct work_struct *work)
complete(&ps3av->done);
}
-static int ps3av_vid2table_id(int vid)
-{
- int i;
-
- for (i = 1; i < ARRAY_SIZE(video_mode_table); i++)
- if (video_mode_table[i].vid == vid)
- return i;
- return -1;
-}
+#define SHIFT_50 0
+#define SHIFT_60 4
+#define SHIFT_VESA 8
+
+static const struct {
+ unsigned mask : 19;
+ unsigned id : 4;
+} ps3av_preferred_modes[] = {
+ { .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 },
+ { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 },
+ { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 },
+ { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 },
+ { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 },
+ { .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 },
+ { .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 },
+ { .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 },
+ { .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 },
+ { .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 },
+ { .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 },
+};
-static int ps3av_resbit2vid(u32 res_50, u32 res_60)
+static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa)
{
- int vid = -1;
+ unsigned int i;
+ u32 res_all;
+
+ /*
+ * We mask off the resolution bits we care about and combine the
+ * results in one bitfield, so make sure there's no overlap
+ */
+ BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
+ PS3AV_RES_MASK_60 << SHIFT_60);
+ BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
+ PS3AV_RES_MASK_VESA << SHIFT_VESA);
+ BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 &
+ PS3AV_RES_MASK_VESA << SHIFT_VESA);
+ res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 |
+ (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 |
+ (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA;
+
+ if (!res_all)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++)
+ if (res_all & ps3av_preferred_modes[i].mask)
+ return ps3av_preferred_modes[i].id;
- if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */
- if (res_50 & PS3AV_RESBIT_1920x1080P)
- vid = PS3AV_CMD_VIDEO_VID_1080P_50HZ;
- else if (res_50 & PS3AV_RESBIT_1920x1080I)
- vid = PS3AV_CMD_VIDEO_VID_1080I_50HZ;
- else if (res_50 & PS3AV_RESBIT_1280x720P)
- vid = PS3AV_CMD_VIDEO_VID_720P_50HZ;
- else if (res_50 & PS3AV_RESBIT_720x576P)
- vid = PS3AV_CMD_VIDEO_VID_576P;
- else
- vid = -1;
- } else {
- if (res_60 & PS3AV_RESBIT_1920x1080P)
- vid = PS3AV_CMD_VIDEO_VID_1080P_60HZ;
- else if (res_60 & PS3AV_RESBIT_1920x1080I)
- vid = PS3AV_CMD_VIDEO_VID_1080I_60HZ;
- else if (res_60 & PS3AV_RESBIT_1280x720P)
- vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
- else if (res_60 & PS3AV_RESBIT_720x480P)
- vid = PS3AV_CMD_VIDEO_VID_480P;
- else
- vid = -1;
- }
- return vid;
+ return 0;
}
-static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info)
+static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
{
- u32 res_50, res_60;
- int vid = -1;
+ int id;
- if (info->monitor_type != PS3AV_MONITOR_TYPE_HDMI)
- return -1;
+ if (safe_mode)
+ return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
/* check native resolution */
- res_50 = info->res_50.native & PS3AV_RES_MASK_50;
- res_60 = info->res_60.native & PS3AV_RES_MASK_60;
- if (res_50 || res_60) {
- vid = ps3av_resbit2vid(res_50, res_60);
- return vid;
+ id = ps3av_resbit2id(info->res_50.native, info->res_60.native,
+ info->res_vesa.native);
+ if (id) {
+ pr_debug("%s: Using native mode %d\n", __func__, id);
+ return id;
}
- /* check resolution */
- res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50;
- res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60;
- if (res_50 || res_60) {
- vid = ps3av_resbit2vid(res_50, res_60);
- return vid;
+ /* check supported resolutions */
+ id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits,
+ info->res_vesa.res_bits);
+ if (id) {
+ pr_debug("%s: Using supported mode %d\n", __func__, id);
+ return id;
}
if (ps3av->region & PS3AV_REGION_60)
- vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
+ id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
else
- vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
- return vid;
+ id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50;
+ pr_debug("%s: Using default mode %d\n", __func__, id);
+ return id;
}
-static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf,
- int boot)
+static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
{
- int i, res, vid = -1, dvi = 0, rgb = 0;
+ const struct ps3av_info_monitor *info = &monitor_info->info;
+ const struct ps3av_info_audio *audio = info->audio;
+ char id[sizeof(info->monitor_id)*3+1];
+ int i;
+
+ pr_debug("Monitor Info: size %u\n", monitor_info->send_hdr.size);
+
+ pr_debug("avport: %02x\n", info->avport);
+ for (i = 0; i < sizeof(info->monitor_id); i++)
+ sprintf(&id[i*3], " %02x", info->monitor_id[i]);
+ pr_debug("monitor_id: %s\n", id);
+ pr_debug("monitor_type: %02x\n", info->monitor_type);
+ pr_debug("monitor_name: %.*s\n", (int)sizeof(info->monitor_name),
+ info->monitor_name);
+
+ /* resolution */
+ pr_debug("resolution_60: bits: %08x native: %08x\n",
+ info->res_60.res_bits, info->res_60.native);
+ pr_debug("resolution_50: bits: %08x native: %08x\n",
+ info->res_50.res_bits, info->res_50.native);
+ pr_debug("resolution_other: bits: %08x native: %08x\n",
+ info->res_other.res_bits, info->res_other.native);
+ pr_debug("resolution_vesa: bits: %08x native: %08x\n",
+ info->res_vesa.res_bits, info->res_vesa.native);
+
+ /* color space */
+ pr_debug("color space rgb: %02x\n", info->cs.rgb);
+ pr_debug("color space yuv444: %02x\n", info->cs.yuv444);
+ pr_debug("color space yuv422: %02x\n", info->cs.yuv422);
+
+ /* color info */
+ pr_debug("color info red: X %04x Y %04x\n", info->color.red_x,
+ info->color.red_y);
+ pr_debug("color info green: X %04x Y %04x\n", info->color.green_x,
+ info->color.green_y);
+ pr_debug("color info blue: X %04x Y %04x\n", info->color.blue_x,
+ info->color.blue_y);
+ pr_debug("color info white: X %04x Y %04x\n", info->color.white_x,
+ info->color.white_y);
+ pr_debug("color info gamma: %08x\n", info->color.gamma);
+
+ /* other info */
+ pr_debug("supported_AI: %02x\n", info->supported_ai);
+ pr_debug("speaker_info: %02x\n", info->speaker_info);
+ pr_debug("num of audio: %02x\n", info->num_of_audio_block);
+
+ /* audio block */
+ for (i = 0; i < info->num_of_audio_block; i++) {
+ pr_debug("audio[%d] type: %02x max_ch: %02x fs: %02x sbit: "
+ "%02x\n",
+ i, audio->type, audio->max_num_of_ch, audio->fs,
+ audio->sbit);
+ audio++;
+ }
+}
+
+static const struct ps3av_monitor_quirk {
+ const char *monitor_name;
+ u32 clear_60, clear_50, clear_vesa;
+} ps3av_monitor_quirks[] = {
+ {
+ .monitor_name = "DELL 2007WFP",
+ .clear_60 = PS3AV_RESBIT_1920x1080I
+ }, {
+ .monitor_name = "L226WTQ",
+ .clear_60 = PS3AV_RESBIT_1920x1080I |
+ PS3AV_RESBIT_1920x1080P
+ }, {
+ .monitor_name = "SyncMaster",
+ .clear_60 = PS3AV_RESBIT_1920x1080I
+ }
+};
+
+static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info)
+{
+ unsigned int i;
+ const struct ps3av_monitor_quirk *quirk;
+
+ for (i = 0; i < ARRAY_SIZE(ps3av_monitor_quirks); i++) {
+ quirk = &ps3av_monitor_quirks[i];
+ if (!strncmp(info->monitor_name, quirk->monitor_name,
+ sizeof(info->monitor_name))) {
+ pr_info("%s: Applying quirk for %s\n", __func__,
+ 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;
+ }
+ }
+}
+
+static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf)
+{
+ int i, res, id = 0, dvi = 0, rgb = 0;
struct ps3av_pkt_av_get_monitor_info monitor_info;
struct ps3av_info_monitor *info;
- /* get vid for hdmi */
- for (i = 0; i < av_hw_conf->num_of_hdmi; i++) {
+ /* get mode id for hdmi */
+ for (i = 0; i < av_hw_conf->num_of_hdmi && !id; i++) {
res = ps3av_cmd_video_get_monitor_info(&monitor_info,
PS3AV_CMD_AVPORT_HDMI_0 +
i);
if (res < 0)
return -1;
- ps3av_cmd_av_monitor_info_dump(&monitor_info);
+ ps3av_monitor_info_dump(&monitor_info);
+
info = &monitor_info.info;
- /* check DVI */
- if (info->monitor_type == PS3AV_MONITOR_TYPE_DVI) {
+ ps3av_fixup_monitor_info(info);
+
+ switch (info->monitor_type) {
+ case PS3AV_MONITOR_TYPE_DVI:
dvi = PS3AV_MODE_DVI;
- break;
- }
- /* check HDMI */
- vid = ps3av_hdmi_get_vid(info);
- if (vid != -1) {
- /* got valid vid */
+ /* fall through */
+ case PS3AV_MONITOR_TYPE_HDMI:
+ id = ps3av_hdmi_get_id(info);
break;
}
}
- if (dvi) {
- /* DVI mode */
- vid = PS3AV_DEFAULT_DVI_VID;
- } else if (vid == -1) {
+ if (!id) {
/* no HDMI interface or HDMI is off */
if (ps3av->region & PS3AV_REGION_60)
- vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60;
+ id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60;
else
- vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50;
+ id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50;
if (ps3av->region & PS3AV_REGION_RGB)
rgb = PS3AV_MODE_RGB;
- } else if (boot) {
- /* HDMI: using DEFAULT HDMI_VID while booting up */
- info = &monitor_info.info;
- if (ps3av->region & PS3AV_REGION_60) {
- if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
- vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
- else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
- vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
- else {
- /* default */
- vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
- }
- } else {
- if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
- vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
- else if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
- vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
- else {
- /* default */
- vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
- }
- }
+ pr_debug("%s: Using avmulti mode %d\n", __func__, id);
}
- return (ps3av_vid2table_id(vid) | dvi | rgb);
+ return id | dvi | rgb;
}
static int ps3av_get_hw_conf(struct ps3av *ps3av)
{
int i, j, k, res;
+ const struct ps3av_pkt_av_get_hw_conf *hw_conf;
/* get av_hw_conf */
res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf);
if (res < 0)
return -1;
- ps3av_cmd_av_hw_conf_dump(&ps3av->av_hw_conf);
+ hw_conf = &ps3av->av_hw_conf;
+ pr_debug("av_h_conf: num of hdmi: %u\n", hw_conf->num_of_hdmi);
+ pr_debug("av_h_conf: num of avmulti: %u\n", hw_conf->num_of_avmulti);
+ pr_debug("av_h_conf: num of spdif: %u\n", hw_conf->num_of_spdif);
for (i = 0; i < PS3AV_HEAD_MAX; i++)
ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i;
for (i = 0; i < PS3AV_OPT_PORT_MAX; i++)
ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i;
- for (i = 0; i < ps3av->av_hw_conf.num_of_hdmi; i++)
+ for (i = 0; i < hw_conf->num_of_hdmi; i++)
ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i;
- for (j = 0; j < ps3av->av_hw_conf.num_of_avmulti; j++)
+ for (j = 0; j < hw_conf->num_of_avmulti; j++)
ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j;
- for (k = 0; k < ps3av->av_hw_conf.num_of_spdif; k++)
+ for (k = 0; k < hw_conf->num_of_spdif; k++)
ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k;
/* set all audio port */
@@ -738,7 +845,7 @@ static int ps3av_get_hw_conf(struct ps3av *ps3av)
}
/* set mode using id */
-int ps3av_set_video_mode(u32 id, int boot)
+int ps3av_set_video_mode(u32 id)
{
int size;
u32 option;
@@ -752,7 +859,7 @@ int ps3av_set_video_mode(u32 id, int boot)
/* auto mode */
option = id & ~PS3AV_MODE_MASK;
if ((id & PS3AV_MODE_MASK) == 0) {
- id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
+ id = ps3av_auto_videomode(&ps3av->av_hw_conf);
if (id < 1) {
printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
return -EINVAL;
@@ -772,34 +879,13 @@ int ps3av_set_video_mode(u32 id, int boot)
EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
-int ps3av_get_auto_mode(int boot)
+int ps3av_get_auto_mode(void)
{
- return ps3av_auto_videomode(&ps3av->av_hw_conf, boot);
+ return ps3av_auto_videomode(&ps3av->av_hw_conf);
}
EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
-int ps3av_set_mode(u32 id, int boot)
-{
- int res;
-
- res = ps3av_set_video_mode(id, boot);
- if (res)
- return res;
-
- res = ps3av_set_audio_mode(PS3AV_CMD_AUDIO_NUM_OF_CH_2,
- PS3AV_CMD_AUDIO_FS_48K,
- PS3AV_CMD_AUDIO_WORD_BITS_16,
- PS3AV_CMD_AUDIO_FORMAT_PCM,
- PS3AV_CMD_AUDIO_SOURCE_SERIAL);
- if (res)
- return res;
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(ps3av_set_mode);
-
int ps3av_get_mode(void)
{
return ps3av ? ps3av->ps3av_mode : 0;
@@ -941,7 +1027,14 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
res);
ps3av_get_hw_conf(ps3av);
- id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1);
+
+#ifdef CONFIG_FB
+ if (fb_mode_option && !strcmp(fb_mode_option, "safe"))
+ safe_mode = 1;
+#endif /* CONFIG_FB */
+ id = ps3av_auto_videomode(&ps3av->av_hw_conf);
+ safe_mode = 0;
+
mutex_lock(&ps3av->mutex);
ps3av->ps3av_mode = id;
mutex_unlock(&ps3av->mutex);
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index f72f5ddf18e..7f880c26122 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -512,7 +512,6 @@ static const u32 ps3av_ns_table[][5] = {
static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
{
u32 av_vid, ns_val;
- u8 *p = ns;
int d;
d = ns_val = 0;
@@ -551,24 +550,22 @@ static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
else
ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d];
- *p++ = ns_val & 0x000000FF;
- *p++ = (ns_val & 0x0000FF00) >> 8;
- *p = (ns_val & 0x00FF0000) >> 16;
+ *ns++ = ns_val & 0x000000FF;
+ *ns++ = (ns_val & 0x0000FF00) >> 8;
+ *ns = (ns_val & 0x00FF0000) >> 16;
}
#undef BASE
static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
{
- const u8 *p;
u8 ret = 0;
if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) {
ret = 0x03;
} else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) {
- p = enable;
- ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) |
- 0x01;
+ ret = ((enable[0] << 4) + (enable[1] << 5) + (enable[2] << 6) +
+ (enable[3] << 7)) | 0x01;
} else
printk(KERN_ERR "%s failed, source:%x\n", __func__, source);
return ret;
@@ -576,11 +573,9 @@ static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
static u8 ps3av_cnv_fifomap(const u8 *map)
{
- const u8 *p;
u8 ret = 0;
- p = map;
- ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6);
+ ret = map[0] + (map[1] << 2) + (map[2] << 4) + (map[3] << 6);
return ret;
}
@@ -927,72 +922,6 @@ int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info,
return res;
}
-#ifdef PS3AV_DEBUG
-void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf)
-{
- printk("av_h_conf:num of hdmi:%d\n", hw_conf->num_of_hdmi);
- printk("av_h_conf:num of avmulti:%d\n", hw_conf->num_of_avmulti);
- printk("av_h_conf:num of spdif:%d\n", hw_conf->num_of_spdif);
-}
-
-void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
-{
- const struct ps3av_info_monitor *info = &monitor_info->info;
- const struct ps3av_info_audio *audio = info->audio;
- int i;
-
- printk("Monitor Info: size%d\n", monitor_info->send_hdr.size);
-
- printk("avport:%02x\n", info->avport);
- printk("monitor_id:");
- for (i = 0; i < 10; i++)
- printk("%02x ", info->monitor_id[i]);
- printk("\nmonitor_type:%02x\n", info->monitor_type);
- printk("monitor_name:");
- for (i = 0; i < 16; i++)
- printk("%c", info->monitor_name[i]);
-
- /* resolution */
- printk("\nresolution_60: bits:%08x native:%08x\n",
- info->res_60.res_bits, info->res_60.native);
- printk("resolution_50: bits:%08x native:%08x\n",
- info->res_50.res_bits, info->res_50.native);
- printk("resolution_other: bits:%08x native:%08x\n",
- info->res_other.res_bits, info->res_other.native);
- printk("resolution_vesa: bits:%08x native:%08x\n",
- info->res_vesa.res_bits, info->res_vesa.native);
-
- /* color space */
- printk("color space rgb:%02x\n", info->cs.rgb);
- printk("color space yuv444:%02x\n", info->cs.yuv444);
- printk("color space yuv422:%02x\n", info->cs.yuv422);
-
- /* color info */
- printk("color info red:X %04x Y %04x\n",
- info->color.red_x, info->color.red_y);
- printk("color info green:X %04x Y %04x\n",
- info->color.green_x, info->color.green_y);
- printk("color info blue:X %04x Y %04x\n",
- info->color.blue_x, info->color.blue_y);
- printk("color info white:X %04x Y %04x\n",
- info->color.white_x, info->color.white_y);
- printk("color info gamma: %08x\n", info->color.gamma);
-
- /* other info */
- printk("supported_AI:%02x\n", info->supported_ai);
- printk("speaker_info:%02x\n", info->speaker_info);
- printk("num of audio:%02x\n", info->num_of_audio_block);
-
- /* audio block */
- for (i = 0; i < info->num_of_audio_block; i++) {
- printk("audio[%d] type:%02x max_ch:%02x fs:%02x sbit:%02x\n",
- i, audio->type, audio->max_num_of_ch, audio->fs,
- audio->sbit);
- audio++;
- }
-}
-#endif /* PS3AV_DEBUG */
-
#define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \
| PS3AV_CMD_AV_LAYOUT_44 \
| PS3AV_CMD_AV_LAYOUT_48)
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index 3a9824e3b25..55955f16ad9 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -66,7 +66,7 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev)
if (n > 1)
dev_info(&dev->sbd.core,
"%s:%u: %lu accessible regions found. Only the first "
- "one will be used",
+ "one will be used\n",
__func__, __LINE__, n);
dev->region_idx = __ffs(dev->accessible_regions);
dev_info(&dev->sbd.core,
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ff9e35cb308..6420a90a4a9 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -139,6 +139,17 @@ config RTC_DRV_DS1307
This driver can also be built as a module. If so, the module
will be called rtc-ds1307.
+config RTC_DRV_DS1374
+ tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
+ depends on RTC_CLASS && I2C
+ help
+ If you say yes here you get support for Dallas Semiconductor
+ DS1374 real-time clock chips. If an interrupt is associated
+ with the device, the alarm functionality is supported.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1374.
+
config RTC_DRV_DS1672
tristate "Dallas/Maxim DS1672"
help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index d3a33aa2696..465db4dd50b 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
+obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 10ab3b71ffc..4dfdf019fcc 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -153,6 +153,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
mutex_init(&rtc->ops_lock);
spin_lock_init(&rtc->irq_lock);
spin_lock_init(&rtc->irq_task_lock);
+ init_waitqueue_head(&rtc->irq_queue);
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index ad66c6ecf36..de0da545c7a 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -12,6 +12,7 @@
*/
#include <linux/rtc.h>
+#include <linux/log2.h>
int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
{
@@ -99,7 +100,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
}
EXPORT_SYMBOL_GPL(rtc_set_mmss);
-int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
+static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
@@ -119,6 +120,87 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
mutex_unlock(&rtc->ops_lock);
return err;
}
+
+int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
+{
+ int err;
+ struct rtc_time before, now;
+ int first_time = 1;
+
+ /* The lower level RTC driver may not be capable of filling
+ * in all fields of the rtc_time struct (eg. rtc-cmos),
+ * and so might instead return -1 in some fields.
+ * We deal with that here by grabbing a current RTC timestamp
+ * and using values from that for any missing (-1) values.
+ *
+ * But this can be racey, because some fields of the RTC timestamp
+ * may have wrapped in the interval since we read the RTC alarm,
+ * which would lead to us inserting inconsistent values in place
+ * of the -1 fields.
+ *
+ * Reading the alarm and timestamp in the reverse sequence
+ * would have the same race condition, and not solve the issue.
+ *
+ * So, we must first read the RTC timestamp,
+ * then read the RTC alarm value,
+ * and then read a second RTC timestamp.
+ *
+ * If any fields of the second timestamp have changed
+ * when compared with the first timestamp, then we know
+ * our timestamp may be inconsistent with that used by
+ * the low-level rtc_read_alarm_internal() function.
+ *
+ * So, when the two timestamps disagree, we just loop and do
+ * the process again to get a fully consistent set of values.
+ *
+ * This could all instead be done in the lower level driver,
+ * but since more than one lower level RTC implementation needs it,
+ * then it's probably best best to do it here instead of there..
+ */
+
+ /* Get the "before" timestamp */
+ err = rtc_read_time(rtc, &before);
+ if (err < 0)
+ return err;
+ do {
+ if (!first_time)
+ memcpy(&before, &now, sizeof(struct rtc_time));
+ first_time = 0;
+
+ /* get the RTC alarm values, which may be incomplete */
+ err = rtc_read_alarm_internal(rtc, alarm);
+ if (err)
+ return err;
+ if (!alarm->enabled)
+ return 0;
+
+ /* get the "after" timestamp, to detect wrapped fields */
+ err = rtc_read_time(rtc, &now);
+ if (err < 0)
+ return err;
+
+ /* note that tm_sec is a "don't care" value here: */
+ } while ( before.tm_min != now.tm_min
+ || before.tm_hour != now.tm_hour
+ || before.tm_mon != now.tm_mon
+ || before.tm_year != now.tm_year
+ || before.tm_isdst != now.tm_isdst);
+
+ /* Fill in any missing alarm fields using the timestamp */
+ if (alarm->time.tm_sec == -1)
+ alarm->time.tm_sec = now.tm_sec;
+ if (alarm->time.tm_min == -1)
+ alarm->time.tm_min = now.tm_min;
+ if (alarm->time.tm_hour == -1)
+ alarm->time.tm_hour = now.tm_hour;
+ if (alarm->time.tm_mday == -1)
+ alarm->time.tm_mday = now.tm_mday;
+ if (alarm->time.tm_mon == -1)
+ alarm->time.tm_mon = now.tm_mon;
+ if (alarm->time.tm_year == -1)
+ alarm->time.tm_year = now.tm_year;
+ return 0;
+}
EXPORT_SYMBOL_GPL(rtc_read_alarm);
int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
@@ -210,6 +292,10 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
if (task == NULL || task->func == NULL)
return -EINVAL;
+ /* Cannot register while the char dev is in use */
+ if (!(mutex_trylock(&rtc->char_lock)))
+ return -EBUSY;
+
spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == NULL) {
rtc->irq_task = task;
@@ -217,13 +303,14 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
}
spin_unlock_irq(&rtc->irq_task_lock);
+ mutex_unlock(&rtc->char_lock);
+
return retval;
}
EXPORT_SYMBOL_GPL(rtc_irq_register);
void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
{
-
spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == task)
rtc->irq_task = NULL;
@@ -231,6 +318,16 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
}
EXPORT_SYMBOL_GPL(rtc_irq_unregister);
+/**
+ * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
+ * @rtc: the rtc device
+ * @task: currently registered with rtc_irq_register()
+ * @enabled: true to enable periodic IRQs
+ * Context: any
+ *
+ * Note that rtc_irq_set_freq() should previously have been used to
+ * specify the desired frequency of periodic IRQ task->func() callbacks.
+ */
int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
{
int err = 0;
@@ -240,8 +337,10 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
return -ENXIO;
spin_lock_irqsave(&rtc->irq_task_lock, flags);
+ if (rtc->irq_task != NULL && task == NULL)
+ err = -EBUSY;
if (rtc->irq_task != task)
- err = -ENXIO;
+ err = -EACCES;
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
if (err == 0)
@@ -251,6 +350,16 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
}
EXPORT_SYMBOL_GPL(rtc_irq_set_state);
+/**
+ * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
+ * @rtc: the rtc device
+ * @task: currently registered with rtc_irq_register()
+ * @freq: positive frequency with which task->func() will be called
+ * Context: any
+ *
+ * Note that rtc_irq_set_state() is used to enable or disable the
+ * periodic IRQs.
+ */
int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
{
int err = 0;
@@ -259,9 +368,14 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
if (rtc->ops->irq_set_freq == NULL)
return -ENXIO;
+ if (!is_power_of_2(freq))
+ return -EINVAL;
+
spin_lock_irqsave(&rtc->irq_task_lock, flags);
+ if (rtc->irq_task != NULL && task == NULL)
+ err = -EBUSY;
if (rtc->irq_task != task)
- err = -ENXIO;
+ err = -EACCES;
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
if (err == 0) {
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5d760bb6c2c..e3fe83a23cf 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -246,11 +246,9 @@ static int cmos_irq_set_freq(struct device *dev, int freq)
/* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
f = ffs(freq);
- if (f != 0) {
- if (f-- > 16 || freq != (1 << f))
- return -EINVAL;
- f = 16 - f;
- }
+ if (f-- > 16)
+ return -EINVAL;
+ f = 16 - f;
spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
@@ -435,6 +433,19 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
if (!ports)
return -ENODEV;
+ /* Claim I/O ports ASAP, minimizing conflict with legacy driver.
+ *
+ * REVISIT non-x86 systems may instead use memory space resources
+ * (needing ioremap etc), not i/o space resources like this ...
+ */
+ ports = request_region(ports->start,
+ ports->end + 1 - ports->start,
+ driver_name);
+ if (!ports) {
+ dev_dbg(dev, "i/o registers already in use\n");
+ return -EBUSY;
+ }
+
cmos_rtc.irq = rtc_irq;
cmos_rtc.iomem = ports;
@@ -456,24 +467,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
cmos_rtc.rtc = rtc_device_register(driver_name, dev,
&cmos_rtc_ops, THIS_MODULE);
- if (IS_ERR(cmos_rtc.rtc))
- return PTR_ERR(cmos_rtc.rtc);
+ if (IS_ERR(cmos_rtc.rtc)) {
+ retval = PTR_ERR(cmos_rtc.rtc);
+ goto cleanup0;
+ }
cmos_rtc.dev = dev;
dev_set_drvdata(dev, &cmos_rtc);
-
- /* platform and pnp busses handle resources incompatibly.
- *
- * REVISIT for non-x86 systems we may need to handle io memory
- * resources: ioremap them, and request_mem_region().
- */
- if (is_pnp()) {
- retval = request_resource(&ioport_resource, ports);
- if (retval < 0) {
- dev_dbg(dev, "i/o registers already in use\n");
- goto cleanup0;
- }
- }
rename_region(ports, cmos_rtc.rtc->dev.bus_id);
spin_lock_irq(&rtc_lock);
@@ -536,9 +536,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
return 0;
cleanup1:
- rename_region(ports, NULL);
-cleanup0:
+ cmos_rtc.dev = NULL;
rtc_device_unregister(cmos_rtc.rtc);
+cleanup0:
+ release_region(ports->start, ports->end + 1 - ports->start);
return retval;
}
@@ -557,19 +558,21 @@ static void cmos_do_shutdown(void)
static void __exit cmos_do_remove(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ struct resource *ports;
cmos_do_shutdown();
- if (is_pnp())
- release_resource(cmos->iomem);
- rename_region(cmos->iomem, NULL);
-
if (is_valid_irq(cmos->irq))
- free_irq(cmos->irq, cmos_rtc.rtc);
+ free_irq(cmos->irq, cmos->rtc);
- rtc_device_unregister(cmos_rtc.rtc);
+ rtc_device_unregister(cmos->rtc);
+ cmos->rtc = NULL;
- cmos_rtc.dev = NULL;
+ ports = cmos->iomem;
+ release_region(ports->start, ports->end + 1 - ports->start);
+ cmos->iomem = NULL;
+
+ cmos->dev = NULL;
dev_set_drvdata(dev, NULL);
}
@@ -656,7 +659,8 @@ static int cmos_resume(struct device *dev)
/*----------------------------------------------------------------*/
/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems,
- * the device node will always be created as a PNPACPI device.
+ * the device node will always be created as a PNPACPI device. Plus
+ * pre-ACPI PCs probably list it in the PNPBIOS tables.
*/
#ifdef CONFIG_PNP
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 005fff3a350..814583bd2fe 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -142,7 +142,7 @@ static int set_uie(struct rtc_device *rtc)
static ssize_t
rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
- struct rtc_device *rtc = to_rtc_device(file->private_data);
+ struct rtc_device *rtc = file->private_data;
DECLARE_WAITQUEUE(wait, current);
unsigned long data;
@@ -196,7 +196,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
{
- struct rtc_device *rtc = to_rtc_device(file->private_data);
+ struct rtc_device *rtc = file->private_data;
unsigned long data;
poll_wait(file, &rtc->irq_queue, wait);
@@ -233,22 +233,12 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
break;
case RTC_PIE_ON:
- if (!capable(CAP_SYS_RESOURCE))
+ if (rtc->irq_freq > rtc->max_user_freq &&
+ !capable(CAP_SYS_RESOURCE))
return -EACCES;
break;
}
- /* avoid conflicting IRQ users */
- if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
- spin_lock_irq(&rtc->irq_task_lock);
- if (rtc->irq_task)
- err = -EBUSY;
- spin_unlock_irq(&rtc->irq_task_lock);
-
- if (err < 0)
- return err;
- }
-
/* try the driver's ioctl interface */
if (ops->ioctl) {
err = ops->ioctl(rtc->dev.parent, cmd, arg);
@@ -338,18 +328,20 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
err = rtc_set_time(rtc, &tm);
break;
- case RTC_IRQP_READ:
- if (ops->irq_set_freq)
- err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
- else
- err = -ENOTTY;
+ case RTC_PIE_ON:
+ err = rtc_irq_set_state(rtc, NULL, 1);
+ break;
+
+ case RTC_PIE_OFF:
+ err = rtc_irq_set_state(rtc, NULL, 0);
break;
case RTC_IRQP_SET:
- if (ops->irq_set_freq)
- err = rtc_irq_set_freq(rtc, rtc->irq_task, arg);
- else
- err = -ENOTTY;
+ err = rtc_irq_set_freq(rtc, NULL, arg);
+ break;
+
+ case RTC_IRQP_READ:
+ err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
break;
#if 0
@@ -405,7 +397,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
static int rtc_dev_release(struct inode *inode, struct file *file)
{
- struct rtc_device *rtc = to_rtc_device(file->private_data);
+ struct rtc_device *rtc = file->private_data;
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
clear_uie(rtc);
@@ -419,7 +411,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
static int rtc_dev_fasync(int fd, struct file *file, int on)
{
- struct rtc_device *rtc = to_rtc_device(file->private_data);
+ struct rtc_device *rtc = file->private_data;
return fasync_helper(fd, file, on, &rtc->async_queue);
}
@@ -449,8 +441,6 @@ void rtc_dev_prepare(struct rtc_device *rtc)
rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
mutex_init(&rtc->char_lock);
- spin_lock_init(&rtc->irq_lock);
- init_waitqueue_head(&rtc->irq_queue);
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
INIT_WORK(&rtc->uie_task, rtc_uie_task);
setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
new file mode 100644
index 00000000000..45bda186bef
--- /dev/null
+++ b/drivers/rtc/rtc-ds1374.c
@@ -0,0 +1,449 @@
+/*
+ * RTC client/driver for the Maxim/Dallas DS1374 Real-Time Clock over I2C
+ *
+ * Based on code by Randy Vinson <rvinson@mvista.com>,
+ * which was based on the m41t00.c by Mark Greer <mgreer@mvista.com>.
+ *
+ * Copyright (C) 2006-2007 Freescale Semiconductor
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+/*
+ * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
+ * recommened in .../Documentation/i2c/writing-clients section
+ * "Sending and receiving", using SMBus level communication is preferred.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/workqueue.h>
+
+#define DS1374_REG_TOD0 0x00 /* Time of Day */
+#define DS1374_REG_TOD1 0x01
+#define DS1374_REG_TOD2 0x02
+#define DS1374_REG_TOD3 0x03
+#define DS1374_REG_WDALM0 0x04 /* Watchdog/Alarm */
+#define DS1374_REG_WDALM1 0x05
+#define DS1374_REG_WDALM2 0x06
+#define DS1374_REG_CR 0x07 /* Control */
+#define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */
+#define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */
+#define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */
+#define DS1374_REG_SR 0x08 /* Status */
+#define DS1374_REG_SR_OSF 0x80 /* Oscillator Stop Flag */
+#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
+#define DS1374_REG_TCR 0x09 /* Trickle Charge */
+
+struct ds1374 {
+ struct i2c_client *client;
+ struct rtc_device *rtc;
+ struct work_struct work;
+
+ /* The mutex protects alarm operations, and prevents a race
+ * between the enable_irq() in the workqueue and the free_irq()
+ * in the remove function.
+ */
+ struct mutex mutex;
+ int exiting;
+};
+
+static struct i2c_driver ds1374_driver;
+
+static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
+ int reg, int nbytes)
+{
+ u8 buf[4];
+ int ret;
+ int i;
+
+ if (nbytes > 4) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf);
+
+ if (ret < 0)
+ return ret;
+ if (ret < nbytes)
+ return -EIO;
+
+ for (i = nbytes - 1, *time = 0; i >= 0; i--)
+ *time = (*time << 8) | buf[i];
+
+ return 0;
+}
+
+static int ds1374_write_rtc(struct i2c_client *client, u32 time,
+ int reg, int nbytes)
+{
+ u8 buf[4];
+ int i;
+
+ if (nbytes > 4) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < nbytes; i++) {
+ buf[i] = time & 0xff;
+ time >>= 8;
+ }
+
+ return i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf);
+}
+
+static int ds1374_check_rtc_status(struct i2c_client *client)
+{
+ int ret = 0;
+ int control, stat;
+
+ stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
+ if (stat < 0)
+ return stat;
+
+ if (stat & DS1374_REG_SR_OSF)
+ dev_warn(&client->dev,
+ "oscillator discontinuity flagged, "
+ "time unreliable\n");
+
+ stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF);
+
+ ret = i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
+ if (ret < 0)
+ return ret;
+
+ /* If the alarm is pending, clear it before requesting
+ * the interrupt, so an interrupt event isn't reported
+ * before everything is initialized.
+ */
+
+ control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+ if (control < 0)
+ return control;
+
+ control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
+ return i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
+}
+
+static int ds1374_read_time(struct device *dev, struct rtc_time *time)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ u32 itime;
+ int ret;
+
+ ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4);
+ if (!ret)
+ rtc_time_to_tm(itime, time);
+
+ return ret;
+}
+
+static int ds1374_set_time(struct device *dev, struct rtc_time *time)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long itime;
+
+ rtc_tm_to_time(time, &itime);
+ return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4);
+}
+
+/* The ds1374 has a decrementer for an alarm, rather than a comparator.
+ * If the time of day is changed, then the alarm will need to be
+ * reset.
+ */
+static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1374 *ds1374 = i2c_get_clientdata(client);
+ u32 now, cur_alarm;
+ int cr, sr;
+ int ret = 0;
+
+ if (client->irq < 0)
+ return -EINVAL;
+
+ mutex_lock(&ds1374->mutex);
+
+ cr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+ if (ret < 0)
+ goto out;
+
+ sr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
+ if (ret < 0)
+ goto out;
+
+ ret = ds1374_read_rtc(client, &now, DS1374_REG_TOD0, 4);
+ if (ret)
+ goto out;
+
+ ret = ds1374_read_rtc(client, &cur_alarm, DS1374_REG_WDALM0, 3);
+ if (ret)
+ goto out;
+
+ rtc_time_to_tm(now + cur_alarm, &alarm->time);
+ alarm->enabled = !!(cr & DS1374_REG_CR_WACE);
+ alarm->pending = !!(sr & DS1374_REG_SR_AF);
+
+out:
+ mutex_unlock(&ds1374->mutex);
+ return ret;
+}
+
+static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1374 *ds1374 = i2c_get_clientdata(client);
+ struct rtc_time now;
+ unsigned long new_alarm, itime;
+ int cr;
+ int ret = 0;
+
+ if (client->irq < 0)
+ return -EINVAL;
+
+ ret = ds1374_read_time(dev, &now);
+ if (ret < 0)
+ return ret;
+
+ rtc_tm_to_time(&alarm->time, &new_alarm);
+ rtc_tm_to_time(&now, &itime);
+
+ new_alarm -= itime;
+
+ /* This can happen due to races, in addition to dates that are
+ * truly in the past. To avoid requiring the caller to check for
+ * races, dates in the past are assumed to be in the recent past
+ * (i.e. not something that we'd rather the caller know about via
+ * an error), and the alarm is set to go off as soon as possible.
+ */
+ if (new_alarm <= 0)
+ new_alarm = 1;
+
+ mutex_lock(&ds1374->mutex);
+
+ ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+ if (ret < 0)
+ goto out;
+
+ /* Disable any existing alarm before setting the new one
+ * (or lack thereof). */
+ cr &= ~DS1374_REG_CR_WACE;
+
+ ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
+ if (ret < 0)
+ goto out;
+
+ ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3);
+ if (ret)
+ goto out;
+
+ if (alarm->enabled) {
+ cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
+ cr &= ~DS1374_REG_CR_WDALM;
+
+ ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
+ }
+
+out:
+ mutex_unlock(&ds1374->mutex);
+ return ret;
+}
+
+static irqreturn_t ds1374_irq(int irq, void *dev_id)
+{
+ struct i2c_client *client = dev_id;
+ struct ds1374 *ds1374 = i2c_get_clientdata(client);
+
+ disable_irq_nosync(irq);
+ schedule_work(&ds1374->work);
+ return IRQ_HANDLED;
+}
+
+static void ds1374_work(struct work_struct *work)
+{
+ struct ds1374 *ds1374 = container_of(work, struct ds1374, work);
+ struct i2c_client *client = ds1374->client;
+ int stat, control;
+
+ mutex_lock(&ds1374->mutex);
+
+ stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
+ if (stat < 0)
+ return;
+
+ if (stat & DS1374_REG_SR_AF) {
+ stat &= ~DS1374_REG_SR_AF;
+ i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
+
+ control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+ if (control < 0)
+ goto out;
+
+ control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
+ i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
+
+ /* rtc_update_irq() assumes that it is called
+ * from IRQ-disabled context.
+ */
+ local_irq_disable();
+ rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF);
+ local_irq_enable();
+ }
+
+out:
+ if (!ds1374->exiting)
+ enable_irq(client->irq);
+
+ mutex_unlock(&ds1374->mutex);
+}
+
+static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1374 *ds1374 = i2c_get_clientdata(client);
+ int ret = -ENOIOCTLCMD;
+
+ mutex_lock(&ds1374->mutex);
+
+ switch (cmd) {
+ case RTC_AIE_OFF:
+ ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+ if (ret < 0)
+ goto out;
+
+ ret &= ~DS1374_REG_CR_WACE;
+
+ ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
+ if (ret < 0)
+ goto out;
+
+ break;
+
+ case RTC_AIE_ON:
+ ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
+ if (ret < 0)
+ goto out;
+
+ ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
+ ret &= ~DS1374_REG_CR_WDALM;
+
+ ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
+ if (ret < 0)
+ goto out;
+
+ break;
+ }
+
+out:
+ mutex_unlock(&ds1374->mutex);
+ return ret;
+}
+
+static const struct rtc_class_ops ds1374_rtc_ops = {
+ .read_time = ds1374_read_time,
+ .set_time = ds1374_set_time,
+ .read_alarm = ds1374_read_alarm,
+ .set_alarm = ds1374_set_alarm,
+ .ioctl = ds1374_ioctl,
+};
+
+static int ds1374_probe(struct i2c_client *client)
+{
+ struct ds1374 *ds1374;
+ int ret;
+
+ ds1374 = kzalloc(sizeof(struct ds1374), GFP_KERNEL);
+ if (!ds1374)
+ return -ENOMEM;
+
+ ds1374->client = client;
+ i2c_set_clientdata(client, ds1374);
+
+ INIT_WORK(&ds1374->work, ds1374_work);
+ mutex_init(&ds1374->mutex);
+
+ ret = ds1374_check_rtc_status(client);
+ if (ret)
+ goto out_free;
+
+ if (client->irq >= 0) {
+ ret = request_irq(client->irq, ds1374_irq, 0,
+ "ds1374", client);
+ if (ret) {
+ dev_err(&client->dev, "unable to request IRQ\n");
+ goto out_free;
+ }
+ }
+
+ ds1374->rtc = rtc_device_register(client->name, &client->dev,
+ &ds1374_rtc_ops, THIS_MODULE);
+ if (IS_ERR(ds1374->rtc)) {
+ ret = PTR_ERR(ds1374->rtc);
+ dev_err(&client->dev, "unable to register the class device\n");
+ goto out_irq;
+ }
+
+ return 0;
+
+out_irq:
+ if (client->irq >= 0)
+ free_irq(client->irq, client);
+
+out_free:
+ i2c_set_clientdata(client, NULL);
+ kfree(ds1374);
+ return ret;
+}
+
+static int __devexit ds1374_remove(struct i2c_client *client)
+{
+ struct ds1374 *ds1374 = i2c_get_clientdata(client);
+
+ if (client->irq >= 0) {
+ mutex_lock(&ds1374->mutex);
+ ds1374->exiting = 1;
+ mutex_unlock(&ds1374->mutex);
+
+ free_irq(client->irq, client);
+ flush_scheduled_work();
+ }
+
+ rtc_device_unregister(ds1374->rtc);
+ i2c_set_clientdata(client, NULL);
+ kfree(ds1374);
+ return 0;
+}
+
+static struct i2c_driver ds1374_driver = {
+ .driver = {
+ .name = "rtc-ds1374",
+ .owner = THIS_MODULE,
+ },
+ .probe = ds1374_probe,
+ .remove = __devexit_p(ds1374_remove),
+};
+
+static int __init ds1374_init(void)
+{
+ return i2c_add_driver(&ds1374_driver);
+}
+
+static void __exit ds1374_exit(void)
+{
+ i2c_del_driver(&ds1374_driver);
+}
+
+module_init(ds1374_init);
+module_exit(ds1374_exit);
+
+MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
+MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 5ab3492817d..bb53c09bad1 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -395,7 +395,7 @@ static struct platform_driver ds1553_rtc_driver = {
.probe = ds1553_rtc_probe,
.remove = __devexit_p(ds1553_rtc_remove),
.driver = {
- .name = "ds1553",
+ .name = "rtc-ds1553",
.owner = THIS_MODULE,
},
};
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 67291b0f828..c535b78698e 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -251,7 +251,7 @@ static struct platform_driver ds1742_rtc_driver = {
.probe = ds1742_rtc_probe,
.remove = __devexit_p(ds1742_rtc_remove),
.driver = {
- .name = "ds1742",
+ .name = "rtc-ds1742",
.owner = THIS_MODULE,
},
};
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index d48b0337458..556d0e7da35 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -332,6 +332,9 @@ static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind)
}
};
+ if (!i2c_check_functionality(adap, I2C_FUNC_I2C))
+ return 0;
+
pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
if (!pcf)
return -ENOMEM;
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 69df94b4484..2ae0e8304d3 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -73,11 +73,35 @@ rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
return retval;
}
+static ssize_t
+rtc_sysfs_show_max_user_freq(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq);
+}
+
+static ssize_t
+rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ struct rtc_device *rtc = to_rtc_device(dev);
+ unsigned long val = simple_strtoul(buf, NULL, 0);
+
+ if (val >= 4096 || val == 0)
+ return -EINVAL;
+
+ rtc->max_user_freq = (int)val;
+
+ return n;
+}
+
static struct device_attribute rtc_attrs[] = {
__ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
__ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
__ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
__ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
+ __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq,
+ rtc_sysfs_set_max_user_freq),
{ },
};
@@ -176,9 +200,8 @@ void rtc_sysfs_add_device(struct rtc_device *rtc)
err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
if (err)
- dev_err(rtc->dev.parent, "failed to create "
- "alarm attribute, %d",
- err);
+ dev_err(rtc->dev.parent,
+ "failed to create alarm attribute, %d\n", err);
}
void rtc_sysfs_del_device(struct rtc_device *rtc)
diff --git a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c
index 564baca01b7..389346cda6c 100644
--- a/drivers/s390/char/defkeymap.c
+++ b/drivers/s390/char/defkeymap.c
@@ -150,7 +150,7 @@ char *func_table[MAX_NR_FUNC] = {
NULL,
};
-struct kbdiacr accent_table[MAX_DIACR] = {
+struct kbdiacruc accent_table[MAX_DIACR] = {
{'^', 'c', '\003'}, {'^', 'd', '\004'},
{'^', 'z', '\032'}, {'^', '\012', '\000'},
};
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index f62f9a4e895..cee4d4e4242 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/sysrq.h>
+#include <linux/consolemap.h>
#include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h>
#include <asm/uaccess.h>
@@ -82,11 +83,11 @@ kbd_alloc(void) {
if (!kbd->fn_handler)
goto out_func;
kbd->accent_table =
- kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL);
+ kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL);
if (!kbd->accent_table)
goto out_fn_handler;
memcpy(kbd->accent_table, accent_table,
- sizeof(struct kbdiacr)*MAX_DIACR);
+ sizeof(struct kbdiacruc)*MAX_DIACR);
kbd->accent_table_size = accent_table_size;
return kbd;
@@ -183,8 +184,8 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
* Otherwise, conclude that DIACR was not combining after all,
* queue it and return CH.
*/
-static unsigned char
-handle_diacr(struct kbd_data *kbd, unsigned char ch)
+static unsigned int
+handle_diacr(struct kbd_data *kbd, unsigned int ch)
{
int i, d;
@@ -460,7 +461,6 @@ int
kbd_ioctl(struct kbd_data *kbd, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct kbdiacrs __user *a;
void __user *argp;
int ct, perm;
@@ -481,17 +481,40 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
case KDSKBSENT:
return do_kdgkb_ioctl(kbd, argp, cmd, perm);
case KDGKBDIACR:
- a = argp;
+ {
+ struct kbdiacrs __user *a = argp;
+ struct kbdiacr diacr;
+ int i;
if (put_user(kbd->accent_table_size, &a->kb_cnt))
return -EFAULT;
+ for (i = 0; i < kbd->accent_table_size; i++) {
+ diacr.diacr = kbd->accent_table[i].diacr;
+ diacr.base = kbd->accent_table[i].base;
+ diacr.result = kbd->accent_table[i].result;
+ if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
+ return -EFAULT;
+ }
+ return 0;
+ }
+ case KDGKBDIACRUC:
+ {
+ struct kbdiacrsuc __user *a = argp;
+
ct = kbd->accent_table_size;
- if (copy_to_user(a->kbdiacr, kbd->accent_table,
- ct * sizeof(struct kbdiacr)))
+ if (put_user(ct, &a->kb_cnt))
+ return -EFAULT;
+ if (copy_to_user(a->kbdiacruc, kbd->accent_table,
+ ct * sizeof(struct kbdiacruc)))
return -EFAULT;
return 0;
+ }
case KDSKBDIACR:
- a = argp;
+ {
+ struct kbdiacrs __user *a = argp;
+ struct kbdiacr diacr;
+ int i;
+
if (!perm)
return -EPERM;
if (get_user(ct, &a->kb_cnt))
@@ -499,10 +522,31 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
if (ct >= MAX_DIACR)
return -EINVAL;
kbd->accent_table_size = ct;
- if (copy_from_user(kbd->accent_table, a->kbdiacr,
- ct * sizeof(struct kbdiacr)))
+ for (i = 0; i < ct; i++) {
+ if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr)))
+ return -EFAULT;
+ kbd->accent_table[i].diacr = diacr.diacr;
+ kbd->accent_table[i].base = diacr.base;
+ kbd->accent_table[i].result = diacr.result;
+ }
+ return 0;
+ }
+ case KDSKBDIACRUC:
+ {
+ struct kbdiacrsuc __user *a = argp;
+
+ if (!perm)
+ return -EPERM;
+ if (get_user(ct, &a->kb_cnt))
+ return -EFAULT;
+ if (ct >= MAX_DIACR)
+ return -EINVAL;
+ kbd->accent_table_size = ct;
+ if (copy_from_user(kbd->accent_table, a->kbdiacruc,
+ ct * sizeof(struct kbdiacruc)))
return -EFAULT;
return 0;
+ }
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index f7bf45c6bf0..5ccfe9cf126 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -25,9 +25,9 @@ struct kbd_data {
unsigned short **key_maps;
char **func_table;
fn_handler_fn **fn_handler;
- struct kbdiacr *accent_table;
+ struct kbdiacruc *accent_table;
unsigned int accent_table_size;
- unsigned char diacr;
+ unsigned int diacr;
unsigned short sysrq;
};
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/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 16e5563e0c6..57cac7008e0 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/mempool.h>
#include <linux/syscalls.h>
+#include <linux/scatterlist.h>
#include <linux/ioctl.h>
#include <scsi/scsi.h>
#include <scsi/scsi_tcq.h>
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 3f105fdcf23..51d92b196ee 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -590,7 +590,7 @@ zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
*/
int
zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
- struct scatterlist *sg, int sg_count, int max_sbals)
+ struct scatterlist *sgl, int sg_count, int max_sbals)
{
int sg_index;
struct scatterlist *sg_segment;
@@ -606,9 +606,7 @@ zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
sbale->flags |= sbtype;
/* process all segements of scatter-gather list */
- for (sg_index = 0, sg_segment = sg, bytes = 0;
- sg_index < sg_count;
- sg_index++, sg_segment++) {
+ for_each_sg(sgl, sg_segment, sg_count, sg_index) {
retval = zfcp_qdio_sbals_from_segment(
fsf_req,
sbtype,
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
index 63941a259b9..f1aa1389ea4 100644
--- a/drivers/sbus/char/vfc.h
+++ b/drivers/sbus/char/vfc.h
@@ -126,7 +126,7 @@ struct vfc_dev {
volatile struct vfc_regs __iomem *regs;
struct vfc_regs *phys_regs;
unsigned int control_reg;
- struct semaphore device_lock_sem;
+ struct mutex device_lock_mtx;
int instance;
int busy;
unsigned long which_io;
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 9269f7fbd36..e7a1642b2aa 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -22,6 +22,7 @@
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <linux/mm.h>
#include <asm/openprom.h>
@@ -54,12 +55,12 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
void vfc_lock_device(struct vfc_dev *dev)
{
- down(&dev->device_lock_sem);
+ mutex_lock(&dev->device_lock_mtx);
}
void vfc_unlock_device(struct vfc_dev *dev)
{
- up(&dev->device_lock_sem);
+ mutex_unlock(&dev->device_lock_mtx);
}
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index efd9d8d3a89..fb14014ee16 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1990,6 +1990,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = twa_host_attrs,
.emulated = 1
};
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index c7995fc216e..a64153b9603 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -2261,6 +2261,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = tw_host_attrs,
.emulated = 1
};
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 9b206176f71..49e1ffa4b2f 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -3575,6 +3575,7 @@ static struct scsi_host_template Bus_Logic_template = {
.unchecked_isa_dma = 1,
.max_sectors = 128,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
/*
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index eda8c48f6be..3168a179484 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -1066,7 +1066,8 @@ static struct scsi_host_template driver_template =
.sg_tablesize = 32 /*SG_ALL*/ /*SG_NONE*/,
.cmd_per_lun = 1 /* commands per lun */,
.unchecked_isa_dma = 1 /* unchecked_isa_dma */,
- .use_clustering = ENABLE_CLUSTERING
+ .use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index f608d4a1d6d..d3a6d15fb77 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -1071,6 +1071,7 @@ static struct scsi_host_template inia100_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int __devinit inia100_probe_one(struct pci_dev *pdev,
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index a7f42a17b5c..038980be763 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -944,6 +944,7 @@ static struct scsi_host_template aac_driver_template = {
.cmd_per_lun = AAC_NUM_IO_FIB,
#endif
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.emulated = 1,
};
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index cbbfbc9f3e0..961a1882cb7 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -61,15 +61,15 @@ static void BAD_DMA(void *address, unsigned int length)
}
static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
- struct scatterlist *sgpnt,
+ struct scatterlist *sgp,
int nseg,
int badseg)
{
printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
badseg, nseg,
- page_address(sgpnt[badseg].page) + sgpnt[badseg].offset,
- (unsigned long long)SCSI_SG_PA(&sgpnt[badseg]),
- sgpnt[badseg].length);
+ page_address(sgp->page) + sgp->offset,
+ (unsigned long long)SCSI_SG_PA(sgp),
+ sgp->length);
/*
* Not safe to continue.
@@ -691,7 +691,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
if (SCpnt->use_sg) {
- struct scatterlist *sgpnt;
+ struct scatterlist *sg;
struct chain *cptr;
#ifdef DEBUG
unsigned char *ptr;
@@ -699,23 +699,21 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
int i;
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
SCpnt->host_scribble = kmalloc(512, GFP_KERNEL | GFP_DMA);
- sgpnt = (struct scatterlist *) SCpnt->request_buffer;
cptr = (struct chain *) SCpnt->host_scribble;
if (cptr == NULL) {
/* free the claimed mailbox slot */
HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
return SCSI_MLQUEUE_HOST_BUSY;
}
- for (i = 0; i < SCpnt->use_sg; i++) {
- if (sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
- (((int) sgpnt[i].offset) & 1) || (sgpnt[i].length & 1)) {
+ scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
+ if (sg->length == 0 || SCpnt->use_sg > 16 ||
+ (((int) sg->offset) & 1) || (sg->length & 1)) {
unsigned char *ptr;
printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
- for (i = 0; i < SCpnt->use_sg; i++) {
+ scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
printk(KERN_CRIT "%d: %p %d\n", i,
- (page_address(sgpnt[i].page) +
- sgpnt[i].offset),
- sgpnt[i].length);
+ (page_address(sg->page) +
+ sg->offset), sg->length);
};
printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
ptr = (unsigned char *) &cptr[i];
@@ -723,10 +721,10 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
printk("%02x ", ptr[i]);
panic("Foooooooood fight!");
};
- any2scsi(cptr[i].dataptr, SCSI_SG_PA(&sgpnt[i]));
- if (SCSI_SG_PA(&sgpnt[i]) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD)
- BAD_SG_DMA(SCpnt, sgpnt, SCpnt->use_sg, i);
- any2scsi(cptr[i].datalen, sgpnt[i].length);
+ any2scsi(cptr[i].dataptr, SCSI_SG_PA(sg));
+ if (SCSI_SG_PA(sg) + sg->length - 1 > ISA_DMA_THRESHOLD)
+ BAD_SG_DMA(SCpnt, sg, SCpnt->use_sg, i);
+ any2scsi(cptr[i].datalen, sg->length);
};
any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr));
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index e4a4f3a965d..f6722fd4600 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -563,6 +563,7 @@ static struct scsi_host_template aha1740_template = {
.sg_tablesize = AHA1740_SCATTER,
.cmd_per_lun = AHA1740_CMDLUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.eh_abort_handler = aha1740_eh_abort_handler,
};
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index a055a96e3ad..42c0f14a262 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -766,6 +766,7 @@ struct scsi_host_template aic79xx_driver_template = {
.max_sectors = 8192,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.slave_alloc = ahd_linux_slave_alloc,
.slave_configure = ahd_linux_slave_configure,
.target_alloc = ahd_linux_target_alloc,
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 2e9c38f2e8a..7770befbf50 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -747,6 +747,7 @@ struct scsi_host_template aic7xxx_driver_template = {
.max_sectors = 8192,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.slave_alloc = ahc_linux_slave_alloc,
.slave_configure = ahc_linux_slave_configure,
.target_alloc = ahc_linux_target_alloc,
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 1a71b0236c9..4025608d696 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -11142,6 +11142,7 @@ static struct scsi_host_template driver_template = {
.max_sectors = 2048,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index f2b23e01401..ee0a98bffcd 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -94,7 +94,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
res = -ENOMEM;
goto err_unmap;
}
- for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
+ for_each_sg(task->scatter, sc, num_sg, i) {
struct sg_el *sg =
&((struct sg_el *)ascb->sg_arr->vaddr)[i];
sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
@@ -103,7 +103,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
sg->flags |= ASD_SG_EL_LIST_EOL;
}
- for (sc = task->scatter, i = 0; i < 2; i++, sc++) {
+ for_each_sg(task->scatter, sc, 2, i) {
sg_arr[i].bus_addr =
cpu_to_le64((u64)sg_dma_address(sc));
sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
@@ -115,7 +115,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
} else {
int i;
- for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
+ for_each_sg(task->scatter, sc, num_sg, i) {
sg_arr[i].bus_addr =
cpu_to_le64((u64)sg_dma_address(sc));
sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index cfcf40159ea..f81777586b8 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -122,6 +122,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
.max_sectors = ARCMSR_MAX_XFER_SECTORS,
.cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = arcmsr_host_attrs,
};
#ifdef CONFIG_SCSI_ARCMSR_AER
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 1591824cf4b..fd42d478920 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -4765,6 +4765,7 @@ static struct scsi_host_template dc395x_driver_template = {
.eh_bus_reset_handler = dc395x_eh_bus_reset,
.unchecked_isa_dma = 0,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index bea9d659af1..8258506ba7d 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -3295,6 +3295,7 @@ static struct scsi_host_template adpt_template = {
.this_id = 7,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static s32 adpt_scsi_register(adpt_hba* pHba)
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index ec2233114bc..7ead5210de9 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -523,7 +523,8 @@ static struct scsi_host_template driver_template = {
.slave_configure = eata2x_slave_configure,
.this_id = 7,
.unchecked_isa_dma = 1,
- .use_clustering = ENABLE_CLUSTERING
+ .use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index e8010a702e7..3ac080ee6e2 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -5213,6 +5213,10 @@ static int __init gdth_init(void)
#endif /* CONFIG_PCI */
TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
+
+ if (list_empty(&gdth_instances))
+ return -ENODEV;
+
#ifdef GDTH_STATISTICS
TRACE2(("gdth_detect(): Initializing timer !\n"));
init_timer(&gdth_timer);
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index adc9559cb6f..112ab6abe62 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -343,6 +343,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->use_clustering = sht->use_clustering;
shost->ordered_tag = sht->ordered_tag;
shost->active_mode = sht->supported_mode;
+ shost->use_sg_chaining = sht->use_sg_chaining;
if (sht->max_host_blocked)
shost->max_host_blocked = sht->max_host_blocked;
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 8b384fa7f04..8515054cdf7 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -655,6 +655,7 @@ static struct scsi_host_template driver_template = {
.unchecked_isa_dma = 0,
.emulated = 0,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.proc_name = driver_name,
.shost_attrs = hptiop_attrs,
.this_id = -1,
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 1a924e9b027..714e6273a70 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1501,6 +1501,7 @@ static struct scsi_host_template ibmmca_driver_template = {
.sg_tablesize = 16,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int ibmmca_probe(struct device *dev)
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index cda0cc3d182..22d91ee173c 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1548,6 +1548,7 @@ static struct scsi_host_template driver_template = {
.this_id = -1,
.sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = ibmvscsi_attrs,
};
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index d81bb076a15..fa7ba64483f 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -70,6 +70,7 @@ typedef struct idescsi_pc_s {
u8 *buffer; /* Data buffer */
u8 *current_position; /* Pointer into the above buffer */
struct scatterlist *sg; /* Scatter gather table */
+ unsigned int sg_cnt; /* Number of entries in sg */
int b_count; /* Bytes transferred from current entry */
struct scsi_cmnd *scsi_cmd; /* SCSI command */
void (*done)(struct scsi_cmnd *); /* Scsi completion routine */
@@ -173,12 +174,6 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
char *buf;
while (bcount) {
- if (pc->sg - scsi_sglist(pc->scsi_cmd) >
- scsi_sg_count(pc->scsi_cmd)) {
- printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
- idescsi_discard_data (drive, bcount);
- return;
- }
count = min(pc->sg->length - pc->b_count, bcount);
if (PageHighMem(pc->sg->page)) {
unsigned long flags;
@@ -197,10 +192,17 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) {
- pc->sg++;
+ if (!--pc->sg_cnt)
+ break;
+ pc->sg = sg_next(pc->sg);
pc->b_count = 0;
}
}
+
+ if (bcount) {
+ printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
+ idescsi_discard_data (drive, bcount);
+ }
}
static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
@@ -209,12 +211,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
char *buf;
while (bcount) {
- if (pc->sg - scsi_sglist(pc->scsi_cmd) >
- scsi_sg_count(pc->scsi_cmd)) {
- printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
- idescsi_output_zeros (drive, bcount);
- return;
- }
count = min(pc->sg->length - pc->b_count, bcount);
if (PageHighMem(pc->sg->page)) {
unsigned long flags;
@@ -233,10 +229,17 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
}
bcount -= count; pc->b_count += count;
if (pc->b_count == pc->sg->length) {
- pc->sg++;
+ if (!--pc->sg_cnt)
+ break;
+ pc->sg = sg_next(pc->sg);
pc->b_count = 0;
}
}
+
+ if (bcount) {
+ printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
+ idescsi_output_zeros (drive, bcount);
+ }
}
static void hexdump(u8 *x, int len)
@@ -804,6 +807,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
pc->buffer = NULL;
pc->sg = scsi_sglist(cmd);
+ pc->sg_cnt = scsi_sg_count(cmd);
pc->b_count = 0;
pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd);
pc->scsi_cmd = cmd;
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index d9dfb69ae03..22d40fd5845 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2831,6 +2831,7 @@ static struct scsi_host_template initio_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int initio_probe_one(struct pci_dev *pdev,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b41dfb53902..c316a0bcae6 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5134,6 +5134,7 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
u32 ioadl_flags = 0;
struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
+ struct ipr_ioadl_desc *last_ioadl = NULL;
int len = qc->nbytes + qc->pad_len;
struct scatterlist *sg;
@@ -5156,11 +5157,13 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd,
ata_for_each_sg(sg, qc) {
ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg));
ioadl->address = cpu_to_be32(sg_dma_address(sg));
- if (ata_sg_is_last(sg, qc))
- ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
- else
- ioadl++;
+
+ last_ioadl = ioadl;
+ ioadl++;
}
+
+ if (likely(last_ioadl))
+ last_ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
}
/**
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 2ed099e2c20..edaac2714c5 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -3252,7 +3252,7 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
*/
if ((scb->breakup) || (scb->sg_break)) {
struct scatterlist *sg;
- int sg_dma_index, ips_sg_index = 0;
+ int i, sg_dma_index, ips_sg_index = 0;
/* we had a data breakup */
scb->data_len = 0;
@@ -3261,20 +3261,22 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
/* Spin forward to last dma chunk */
sg_dma_index = scb->breakup;
+ for (i = 0; i < scb->breakup; i++)
+ sg = sg_next(sg);
/* Take care of possible partial on last chunk */
ips_fill_scb_sg_single(ha,
- sg_dma_address(&sg[sg_dma_index]),
+ sg_dma_address(sg),
scb, ips_sg_index++,
- sg_dma_len(&sg[sg_dma_index]));
+ sg_dma_len(sg));
for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
- sg_dma_index++) {
+ sg_dma_index++, sg = sg_next(sg)) {
if (ips_fill_scb_sg_single
(ha,
- sg_dma_address(&sg[sg_dma_index]),
+ sg_dma_address(sg),
scb, ips_sg_index++,
- sg_dma_len(&sg[sg_dma_index])) < 0)
+ sg_dma_len(sg)) < 0)
break;
}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index cd674938ccd..c0755565fae 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1438,6 +1438,7 @@ struct scsi_host_template lpfc_template = {
.scan_finished = lpfc_scan_finished,
.this_id = -1,
.sg_tablesize = LPFC_SG_SEG_CNT,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.cmd_per_lun = LPFC_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = lpfc_hba_attrs,
@@ -1460,6 +1461,7 @@ struct scsi_host_template lpfc_vport_template = {
.sg_tablesize = LPFC_SG_SEG_CNT,
.cmd_per_lun = LPFC_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = lpfc_vport_attrs,
.max_sectors = 0xFFFF,
};
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e5337ad4121..ce348c5c706 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1243,7 +1243,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
memcpy(&adaptermsg[0], (uint8_t *) irsp,
MAX_MSG_DATA);
- dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+ dev_warn(&((phba->pcidev)->dev),
+ "lpfc%d: %s\n",
phba->brd_no, adaptermsg);
} else {
/* Unknown IOCB command */
@@ -1430,7 +1431,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
memcpy(&adaptermsg[0], (uint8_t *) irsp,
MAX_MSG_DATA);
- dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+ dev_warn(&((phba->pcidev)->dev),
+ "lpfc%d: %s\n",
phba->brd_no, adaptermsg);
} else {
/* Unknown IOCB command */
@@ -1681,7 +1683,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
memcpy(&adaptermsg[0], (uint8_t *) irsp,
MAX_MSG_DATA);
dev_warn(&((phba->pcidev)->dev),
- "lpfc%d: %s",
+ "lpfc%d: %s\n",
phba->brd_no, adaptermsg);
} else {
/* Unknown IOCB command */
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index b12ad7c7c67..a035001f443 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -402,6 +402,7 @@ static struct scsi_host_template mac53c94_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index cdbcaa5ad6c..abe2bda6ac3 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -53,6 +53,11 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include "mac_scsi.h"
+
+/* These control the behaviour of the generic 5380 core */
+#define AUTOSENSE
+#define PSEUDO_DMA
+
#include "NCR5380.h"
#if 0
@@ -571,10 +576,6 @@ static int macscsi_pwrite (struct Scsi_Host *instance,
}
-/* These control the behaviour of the generic 5380 core */
-#define AUTOSENSE
-#define PSEUDO_DMA
-
#include "NCR5380.c"
static struct scsi_host_template driver_template = {
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index e7e11f282c8..10d1aff9938 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -4492,6 +4492,7 @@ static struct scsi_host_template megaraid_template = {
.sg_tablesize = MAX_SGLIST,
.cmd_per_lun = DEF_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.eh_abort_handler = megaraid_abort,
.eh_device_reset_handler = megaraid_reset,
.eh_bus_reset_handler = megaraid_reset,
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index c6a53dccc16..e4e4c6a39ed 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -361,6 +361,7 @@ static struct scsi_host_template megaraid_template_g = {
.eh_host_reset_handler = megaraid_reset_handler,
.change_queue_depth = megaraid_change_queue_depth,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sdev_attrs = megaraid_sdev_attrs,
.shost_attrs = megaraid_shost_attrs,
};
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index ebb948c016b..e3c5c528220 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -1110,6 +1110,7 @@ static struct scsi_host_template megasas_template = {
.eh_timed_out = megasas_reset_timer,
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
/**
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 651d09b08f2..7470ff39ab2 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1843,6 +1843,7 @@ static struct scsi_host_template mesh_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 7fed3537215..28161dc95e0 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -281,6 +281,7 @@ static struct scsi_host_template nsp32_template = {
.cmd_per_lun = 1,
.this_id = NSP32_HOST_SCSIID,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.eh_abort_handler = nsp32_eh_abort,
.eh_bus_reset_handler = nsp32_eh_bus_reset,
.eh_host_reset_handler = nsp32_eh_host_reset,
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 961839ecfe8..190e2a7d706 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -694,6 +694,7 @@ static struct scsi_host_template sym53c500_driver_template = {
.sg_tablesize = 32,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.shost_attrs = SYM53C500_shost_attrs
};
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index fba8aa8a81b..76089cf55f4 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -2775,7 +2775,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
struct device_reg __iomem *reg = ha->iobase;
struct scsi_cmnd *cmd = sp->cmd;
cmd_a64_entry_t *pkt;
- struct scatterlist *sg = NULL;
+ struct scatterlist *sg = NULL, *s;
__le32 *dword_ptr;
dma_addr_t dma_handle;
int status = 0;
@@ -2889,13 +2889,16 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
* Load data segments.
*/
if (seg_cnt) { /* If data transfer. */
+ int remseg = seg_cnt;
/* Setup packet address segment pointer. */
dword_ptr = (u32 *)&pkt->dseg_0_address;
if (cmd->use_sg) { /* If scatter gather */
/* Load command entry data segments. */
- for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) {
- dma_handle = sg_dma_address(sg);
+ for_each_sg(sg, s, seg_cnt, cnt) {
+ if (cnt == 2)
+ break;
+ dma_handle = sg_dma_address(s);
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
if (ha->flags.use_pci_vchannel)
sn_pci_set_vchan(ha->pdev,
@@ -2906,12 +2909,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
cpu_to_le32(pci_dma_lo32(dma_handle));
*dword_ptr++ =
cpu_to_le32(pci_dma_hi32(dma_handle));
- *dword_ptr++ = cpu_to_le32(sg_dma_len(sg));
- sg++;
+ *dword_ptr++ = cpu_to_le32(sg_dma_len(s));
dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
cpu_to_le32(pci_dma_hi32(dma_handle)),
cpu_to_le32(pci_dma_lo32(dma_handle)),
- cpu_to_le32(sg_dma_len(sg)));
+ cpu_to_le32(sg_dma_len(sg_next(s))));
+ remseg--;
}
dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
"command packet data - b %i, t %i, l %i \n",
@@ -2926,7 +2929,9 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
"remains\n", seg_cnt);
- while (seg_cnt > 0) {
+ while (remseg > 0) {
+ /* Update sg start */
+ sg = s;
/* Adjust ring index. */
ha->req_ring_index++;
if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@@ -2952,9 +2957,10 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
(u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
/* Load continuation entry data segments. */
- for (cnt = 0; cnt < 5 && seg_cnt;
- cnt++, seg_cnt--) {
- dma_handle = sg_dma_address(sg);
+ for_each_sg(sg, s, remseg, cnt) {
+ if (cnt == 5)
+ break;
+ dma_handle = sg_dma_address(s);
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
if (ha->flags.use_pci_vchannel)
sn_pci_set_vchan(ha->pdev,
@@ -2966,13 +2972,13 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
*dword_ptr++ =
cpu_to_le32(pci_dma_hi32(dma_handle));
*dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
+ cpu_to_le32(sg_dma_len(s));
dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
cpu_to_le32(pci_dma_hi32(dma_handle)),
cpu_to_le32(pci_dma_lo32(dma_handle)),
- cpu_to_le32(sg_dma_len(sg)));
- sg++;
+ cpu_to_le32(sg_dma_len(s)));
}
+ remseg -= cnt;
dprintk(5, "qla1280_64bit_start_scsi: "
"continuation packet data - b %i, t "
"%i, l %i \n", SCSI_BUS_32(cmd),
@@ -3062,7 +3068,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
struct device_reg __iomem *reg = ha->iobase;
struct scsi_cmnd *cmd = sp->cmd;
struct cmd_entry *pkt;
- struct scatterlist *sg = NULL;
+ struct scatterlist *sg = NULL, *s;
__le32 *dword_ptr;
int status = 0;
int cnt;
@@ -3188,6 +3194,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
* Load data segments.
*/
if (seg_cnt) {
+ int remseg = seg_cnt;
/* Setup packet address segment pointer. */
dword_ptr = &pkt->dseg_0_address;
@@ -3196,22 +3203,25 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
qla1280_dump_buffer(1, (char *)sg, 4 * 16);
/* Load command entry data segments. */
- for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) {
+ for_each_sg(sg, s, seg_cnt, cnt) {
+ if (cnt == 4)
+ break;
*dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
- *dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
+ cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
+ *dword_ptr++ = cpu_to_le32(sg_dma_len(s));
dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
- (pci_dma_lo32(sg_dma_address(sg))),
- (sg_dma_len(sg)));
- sg++;
+ (pci_dma_lo32(sg_dma_address(s))),
+ (sg_dma_len(s)));
+ remseg--;
}
/*
* Build continuation packets.
*/
dprintk(3, "S/G Building Continuation"
"...seg_cnt=0x%x remains\n", seg_cnt);
- while (seg_cnt > 0) {
+ while (remseg > 0) {
+ /* Continue from end point */
+ sg = s;
/* Adjust ring index. */
ha->req_ring_index++;
if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@@ -3239,19 +3249,20 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
&((struct cont_entry *) pkt)->dseg_0_address;
/* Load continuation entry data segments. */
- for (cnt = 0; cnt < 7 && seg_cnt;
- cnt++, seg_cnt--) {
+ for_each_sg(sg, s, remseg, cnt) {
+ if (cnt == 7)
+ break;
*dword_ptr++ =
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
+ cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
*dword_ptr++ =
- cpu_to_le32(sg_dma_len(sg));
+ cpu_to_le32(sg_dma_len(s));
dprintk(1,
"S/G Segment Cont. phys_addr=0x%x, "
"len=0x%x\n",
- cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
- cpu_to_le32(sg_dma_len(sg)));
- sg++;
+ cpu_to_le32(pci_dma_lo32(sg_dma_address(s))),
+ cpu_to_le32(sg_dma_len(s)));
}
+ remseg -= cnt;
dprintk(5, "qla1280_32bit_start_scsi: "
"continuation packet data - "
"scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd),
@@ -4248,6 +4259,7 @@ static struct scsi_host_template qla1280_driver_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index a6bb8d0ecf1..0351d380c2d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -132,6 +132,7 @@ struct scsi_host_template qla2x00_driver_template = {
.this_id = -1,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sg_tablesize = SG_ALL,
/*
@@ -163,6 +164,7 @@ struct scsi_host_template qla24xx_driver_template = {
.this_id = -1,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index b1d565c12c5..89460d27c68 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -94,6 +94,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
.this_id = -1,
.cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.sg_tablesize = SG_ALL,
.max_sectors = 0xFFFF,
@@ -1285,7 +1286,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
ret = scsi_init_shared_tag_map(host, MAX_SRBS);
if (ret) {
- dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed");
+ dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed\n");
goto probe_failed;
}
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
index 1e874f1fb5c..1769f965eed 100644
--- a/drivers/scsi/qlogicfas.c
+++ b/drivers/scsi/qlogicfas.c
@@ -197,6 +197,7 @@ static struct scsi_host_template qlogicfas_driver_template = {
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static __init int qlogicfas_init(void)
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index e93f80316a1..7a2e7986b03 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -868,7 +868,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr)
{
struct dataseg *ds;
- struct scatterlist *sg;
+ struct scatterlist *sg, *s;
int i, n;
if (Cmnd->use_sg) {
@@ -884,11 +884,12 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
n = sg_count;
if (n > 4)
n = 4;
- for (i = 0; i < n; i++, sg++) {
- ds[i].d_base = sg_dma_address(sg);
- ds[i].d_count = sg_dma_len(sg);
+ for_each_sg(sg, s, n, i) {
+ ds[i].d_base = sg_dma_address(s);
+ ds[i].d_count = sg_dma_len(s);
}
sg_count -= 4;
+ sg = s;
while (sg_count > 0) {
struct Continuation_Entry *cont;
@@ -907,9 +908,9 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
n = sg_count;
if (n > 7)
n = 7;
- for (i = 0; i < n; i++, sg++) {
- ds[i].d_base = sg_dma_address(sg);
- ds[i].d_count = sg_dma_len(sg);
+ for_each_sg(sg, s, n, i) {
+ ds[i].d_base = sg_dma_address(s);
+ ds[i].d_count = sg_dma_len(s);
}
sg_count -= n;
}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 4947dfe625a..72ee4c9cfb1 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -38,6 +38,7 @@
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
+#include <linux/scatterlist.h>
#include <linux/blkdev.h>
#include "scsi.h"
@@ -600,7 +601,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
int k, req_len, act_len, len, active;
void * kaddr;
void * kaddr_off;
- struct scatterlist * sgpnt;
+ struct scatterlist * sg;
if (0 == scp->request_bufflen)
return 0;
@@ -619,16 +620,16 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
scp->resid = req_len - act_len;
return 0;
}
- sgpnt = (struct scatterlist *)scp->request_buffer;
active = 1;
- for (k = 0, req_len = 0, act_len = 0; k < scp->use_sg; ++k, ++sgpnt) {
+ req_len = act_len = 0;
+ scsi_for_each_sg(scp, sg, scp->use_sg, k) {
if (active) {
kaddr = (unsigned char *)
- kmap_atomic(sgpnt->page, KM_USER0);
+ kmap_atomic(sg->page, KM_USER0);
if (NULL == kaddr)
return (DID_ERROR << 16);
- kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
- len = sgpnt->length;
+ kaddr_off = (unsigned char *)kaddr + sg->offset;
+ len = sg->length;
if ((req_len + len) > arr_len) {
active = 0;
len = arr_len - req_len;
@@ -637,7 +638,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
kunmap_atomic(kaddr, KM_USER0);
act_len += len;
}
- req_len += sgpnt->length;
+ req_len += sg->length;
}
if (scp->resid)
scp->resid -= act_len;
@@ -653,7 +654,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
int k, req_len, len, fin;
void * kaddr;
void * kaddr_off;
- struct scatterlist * sgpnt;
+ struct scatterlist * sg;
if (0 == scp->request_bufflen)
return 0;
@@ -668,13 +669,14 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
memcpy(arr, scp->request_buffer, len);
return len;
}
- sgpnt = (struct scatterlist *)scp->request_buffer;
- for (k = 0, req_len = 0, fin = 0; k < scp->use_sg; ++k, ++sgpnt) {
- kaddr = (unsigned char *)kmap_atomic(sgpnt->page, KM_USER0);
+ 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);
if (NULL == kaddr)
return -1;
- kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
- len = sgpnt->length;
+ kaddr_off = (unsigned char *)kaddr + sg->offset;
+ len = sg->length;
if ((req_len + len) > max_arr_len) {
len = max_arr_len - req_len;
fin = 1;
@@ -683,7 +685,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
kunmap_atomic(kaddr, KM_USER0);
if (fin)
return req_len + len;
- req_len += sgpnt->length;
+ req_len += sg->length;
}
return req_len;
}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 207f1aa0886..aac8a02cbe8 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -17,6 +17,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hardirq.h>
+#include <linux/scatterlist.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -33,35 +34,34 @@
#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools)
#define SG_MEMPOOL_SIZE 2
+/*
+ * The maximum number of SG segments that we will put inside a scatterlist
+ * (unless chaining is used). Should ideally fit inside a single page, to
+ * avoid a higher order allocation.
+ */
+#define SCSI_MAX_SG_SEGMENTS 128
+
struct scsi_host_sg_pool {
size_t size;
- char *name;
+ char *name;
struct kmem_cache *slab;
mempool_t *pool;
};
-#if (SCSI_MAX_PHYS_SEGMENTS < 32)
-#error SCSI_MAX_PHYS_SEGMENTS is too small
-#endif
-
-#define SP(x) { x, "sgpool-" #x }
+#define SP(x) { x, "sgpool-" #x }
static struct scsi_host_sg_pool scsi_sg_pools[] = {
SP(8),
SP(16),
+#if (SCSI_MAX_SG_SEGMENTS > 16)
SP(32),
-#if (SCSI_MAX_PHYS_SEGMENTS > 32)
+#if (SCSI_MAX_SG_SEGMENTS > 32)
SP(64),
-#if (SCSI_MAX_PHYS_SEGMENTS > 64)
+#if (SCSI_MAX_SG_SEGMENTS > 64)
SP(128),
-#if (SCSI_MAX_PHYS_SEGMENTS > 128)
- SP(256),
-#if (SCSI_MAX_PHYS_SEGMENTS > 256)
-#error SCSI_MAX_PHYS_SEGMENTS is too large
-#endif
#endif
#endif
#endif
-};
+};
#undef SP
static void scsi_run_queue(struct request_queue *q);
@@ -289,14 +289,16 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
struct request_queue *q = rq->q;
int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
unsigned int data_len = bufflen, len, bytes, off;
+ struct scatterlist *sg;
struct page *page;
struct bio *bio = NULL;
int i, err, nr_vecs = 0;
- for (i = 0; i < nsegs; i++) {
- page = sgl[i].page;
- off = sgl[i].offset;
- len = sgl[i].length;
+ for_each_sg(sgl, sg, nsegs, i) {
+ page = sg->page;
+ off = sg->offset;
+ len = sg->length;
+ data_len += len;
while (len > 0 && data_len > 0) {
/*
@@ -695,56 +697,170 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
return NULL;
}
-struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
-{
- struct scsi_host_sg_pool *sgp;
- struct scatterlist *sgl;
+/*
+ * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
+ * is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
+ */
+#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048
- BUG_ON(!cmd->use_sg);
+static inline unsigned int scsi_sgtable_index(unsigned short nents)
+{
+ unsigned int index;
- switch (cmd->use_sg) {
+ switch (nents) {
case 1 ... 8:
- cmd->sglist_len = 0;
+ index = 0;
break;
case 9 ... 16:
- cmd->sglist_len = 1;
+ index = 1;
break;
+#if (SCSI_MAX_SG_SEGMENTS > 16)
case 17 ... 32:
- cmd->sglist_len = 2;
+ index = 2;
break;
-#if (SCSI_MAX_PHYS_SEGMENTS > 32)
+#if (SCSI_MAX_SG_SEGMENTS > 32)
case 33 ... 64:
- cmd->sglist_len = 3;
+ index = 3;
break;
-#if (SCSI_MAX_PHYS_SEGMENTS > 64)
+#if (SCSI_MAX_SG_SEGMENTS > 64)
case 65 ... 128:
- cmd->sglist_len = 4;
- break;
-#if (SCSI_MAX_PHYS_SEGMENTS > 128)
- case 129 ... 256:
- cmd->sglist_len = 5;
+ index = 4;
break;
#endif
#endif
#endif
default:
- return NULL;
+ printk(KERN_ERR "scsi: bad segment count=%d\n", nents);
+ BUG();
}
- sgp = scsi_sg_pools + cmd->sglist_len;
- sgl = mempool_alloc(sgp->pool, gfp_mask);
- return sgl;
+ return index;
+}
+
+struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
+{
+ struct scsi_host_sg_pool *sgp;
+ struct scatterlist *sgl, *prev, *ret;
+ unsigned int index;
+ int this, left;
+
+ BUG_ON(!cmd->use_sg);
+
+ left = cmd->use_sg;
+ ret = prev = NULL;
+ do {
+ this = left;
+ if (this > SCSI_MAX_SG_SEGMENTS) {
+ this = SCSI_MAX_SG_SEGMENTS - 1;
+ index = SG_MEMPOOL_NR - 1;
+ } else
+ index = scsi_sgtable_index(this);
+
+ left -= this;
+
+ sgp = scsi_sg_pools + index;
+
+ sgl = mempool_alloc(sgp->pool, gfp_mask);
+ if (unlikely(!sgl))
+ goto enomem;
+
+ memset(sgl, 0, sizeof(*sgl) * sgp->size);
+
+ /*
+ * first loop through, set initial index and return value
+ */
+ if (!ret)
+ ret = sgl;
+
+ /*
+ * chain previous sglist, if any. we know the previous
+ * sglist must be the biggest one, or we would not have
+ * ended up doing another loop.
+ */
+ if (prev)
+ sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
+
+ /*
+ * don't allow subsequent mempool allocs to sleep, it would
+ * violate the mempool principle.
+ */
+ gfp_mask &= ~__GFP_WAIT;
+ gfp_mask |= __GFP_HIGH;
+ prev = sgl;
+ } while (left);
+
+ /*
+ * ->use_sg may get modified after dma mapping has potentially
+ * shrunk the number of segments, so keep a copy of it for free.
+ */
+ cmd->__use_sg = cmd->use_sg;
+ return ret;
+enomem:
+ if (ret) {
+ /*
+ * Free entries chained off ret. Since we were trying to
+ * allocate another sglist, we know that all entries are of
+ * the max size.
+ */
+ sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
+ prev = ret;
+ ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
+
+ while ((sgl = sg_chain_ptr(ret)) != NULL) {
+ ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
+ mempool_free(sgl, sgp->pool);
+ }
+
+ mempool_free(prev, sgp->pool);
+ }
+ return NULL;
}
EXPORT_SYMBOL(scsi_alloc_sgtable);
-void scsi_free_sgtable(struct scatterlist *sgl, int index)
+void scsi_free_sgtable(struct scsi_cmnd *cmd)
{
+ struct scatterlist *sgl = cmd->request_buffer;
struct scsi_host_sg_pool *sgp;
- BUG_ON(index >= SG_MEMPOOL_NR);
+ /*
+ * if this is the biggest size sglist, check if we have
+ * chained parts we need to free
+ */
+ if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) {
+ unsigned short this, left;
+ struct scatterlist *next;
+ unsigned int index;
+
+ left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1);
+ next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
+ while (left && next) {
+ sgl = next;
+ this = left;
+ if (this > SCSI_MAX_SG_SEGMENTS) {
+ this = SCSI_MAX_SG_SEGMENTS - 1;
+ index = SG_MEMPOOL_NR - 1;
+ } else
+ index = scsi_sgtable_index(this);
+
+ left -= this;
+
+ sgp = scsi_sg_pools + index;
+
+ if (left)
+ next = sg_chain_ptr(&sgl[sgp->size - 1]);
+
+ mempool_free(sgl, sgp->pool);
+ }
+
+ /*
+ * Restore original, will be freed below
+ */
+ sgl = cmd->request_buffer;
+ sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
+ } else
+ sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
- sgp = scsi_sg_pools + index;
mempool_free(sgl, sgp->pool);
}
@@ -770,7 +886,7 @@ EXPORT_SYMBOL(scsi_free_sgtable);
static void scsi_release_buffers(struct scsi_cmnd *cmd)
{
if (cmd->use_sg)
- scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+ scsi_free_sgtable(cmd);
/*
* Zero these out. They now point to freed memory, and it is
@@ -984,7 +1100,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
static int scsi_init_io(struct scsi_cmnd *cmd)
{
struct request *req = cmd->request;
- struct scatterlist *sgpnt;
int count;
/*
@@ -997,14 +1112,13 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
/*
* If sg table allocation fails, requeue request later.
*/
- sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
- if (unlikely(!sgpnt)) {
+ cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
+ if (unlikely(!cmd->request_buffer)) {
scsi_unprep_request(req);
return BLKPREP_DEFER;
}
req->buffer = NULL;
- cmd->request_buffer = (char *) sgpnt;
if (blk_pc_request(req))
cmd->request_bufflen = req->data_len;
else
@@ -1529,8 +1643,25 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
if (!q)
return NULL;
+ /*
+ * this limit is imposed by hardware restrictions
+ */
blk_queue_max_hw_segments(q, shost->sg_tablesize);
- blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS);
+
+ /*
+ * In the future, sg chaining support will be mandatory and this
+ * ifdef can then go away. Right now we don't have all archs
+ * converted, so better keep it safe.
+ */
+#ifdef ARCH_HAS_SG_CHAIN
+ if (shost->use_sg_chaining)
+ blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
+ else
+ blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
+#else
+ blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
+#endif
+
blk_queue_max_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
blk_queue_segment_boundary(q, shost->dma_boundary);
@@ -2193,18 +2324,19 @@ EXPORT_SYMBOL_GPL(scsi_target_unblock);
*
* Returns virtual address of the start of the mapped page
*/
-void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
+void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
size_t *offset, size_t *len)
{
int i;
size_t sg_len = 0, len_complete = 0;
+ struct scatterlist *sg;
struct page *page;
WARN_ON(!irqs_disabled());
- for (i = 0; i < sg_count; i++) {
+ for_each_sg(sgl, sg, sg_count, i) {
len_complete = sg_len; /* Complete sg-entries */
- sg_len += sg[i].length;
+ sg_len += sg->length;
if (sg_len > *offset)
break;
}
@@ -2218,10 +2350,10 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
}
/* Offset starting from the beginning of first page in this sg-entry */
- *offset = *offset - len_complete + sg[i].offset;
+ *offset = *offset - len_complete + sg->offset;
/* Assumption: contiguous pages can be accessed as "page + i" */
- page = nth_page(sg[i].page, (*offset >> PAGE_SHIFT));
+ page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
*offset &= ~PAGE_MASK;
/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 66c692ffa30..a91761c3645 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -332,7 +332,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag);
if (cmd->request_buffer)
- scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+ scsi_free_sgtable(cmd);
queue_work(scsi_tgtd, &tcmd->work);
}
@@ -373,7 +373,7 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
}
eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg);
- scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+ scsi_free_sgtable(cmd);
return -EINVAL;
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 0a3a528212c..69f542c4923 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -826,27 +826,6 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
return 0;
}
-static int sd_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- int ret = 0;
- struct scsi_device *sdp = q->queuedata;
- struct scsi_disk *sdkp;
-
- if (sdp->sdev_state != SDEV_RUNNING)
- return -ENXIO;
-
- sdkp = scsi_disk_get_from_dev(&sdp->sdev_gendev);
-
- if (!sdkp)
- return -ENODEV;
-
- if (sdkp->WCE)
- ret = sd_sync_cache(sdkp);
- scsi_disk_put(sdkp);
- return ret;
-}
-
static void sd_prepare_flush(struct request_queue *q, struct request *rq)
{
memset(rq->cmd, 0, sizeof(rq->cmd));
@@ -1697,7 +1676,6 @@ static int sd_probe(struct device *dev)
sd_revalidate_disk(gd);
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
- blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_DRIVERFS;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index f6f5fc7d0ce..7238b2dfc49 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1165,7 +1165,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
sg = rsv_schp->buffer;
sa = vma->vm_start;
for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
- ++k, ++sg) {
+ ++k, sg = sg_next(sg)) {
len = vma->vm_end - sa;
len = (len < sg->length) ? len : sg->length;
if (offset < len) {
@@ -1209,7 +1209,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
sa = vma->vm_start;
sg = rsv_schp->buffer;
for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
- ++k, ++sg) {
+ ++k, sg = sg_next(sg)) {
len = vma->vm_end - sa;
len = (len < sg->length) ? len : sg->length;
sa += len;
@@ -1840,7 +1840,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
}
for (k = 0, sg = schp->buffer, rem_sz = blk_size;
(rem_sz > 0) && (k < mx_sc_elems);
- ++k, rem_sz -= ret_sz, ++sg) {
+ ++k, rem_sz -= ret_sz, sg = sg_next(sg)) {
num = (rem_sz > scatter_elem_sz_prev) ?
scatter_elem_sz_prev : rem_sz;
@@ -1913,7 +1913,7 @@ sg_write_xfer(Sg_request * srp)
if (res)
return res;
- for (; p; ++sg, ksglen = sg->length,
+ for (; p; sg = sg_next(sg), ksglen = sg->length,
p = page_address(sg->page)) {
if (usglen <= 0)
break;
@@ -1992,7 +1992,7 @@ sg_remove_scat(Sg_scatter_hold * schp)
int k;
for (k = 0; (k < schp->k_use_sg) && sg->page;
- ++k, ++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));
@@ -2045,7 +2045,7 @@ sg_read_xfer(Sg_request * srp)
if (res)
return res;
- for (; p; ++sg, ksglen = sg->length,
+ for (; p; sg = sg_next(sg), ksglen = sg->length,
p = page_address(sg->page)) {
if (usglen <= 0)
break;
@@ -2092,7 +2092,7 @@ 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) {
+ for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
num = sg->length;
if (num > num_read_xfer) {
if (__copy_to_user(outp, page_address(sg->page),
@@ -2142,7 +2142,7 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
rem = size;
- for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+ for (k = 0; k < rsv_schp->k_use_sg; ++k, sg = sg_next(sg)) {
num = sg->length;
if (rem <= num) {
sfp->save_scat_len = num;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 72f6d801535..e3fab3a6aed 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -1123,6 +1123,7 @@ static struct scsi_host_template driver_template = {
.this_id = -1,
.sg_tablesize = ST_MAX_SG,
.cmd_per_lun = ST_CMD_PER_LUN,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
static int stex_set_dma_mask(struct pci_dev * pdev)
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index 92bfaeafe30..8befab7e983 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -854,5 +854,6 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = 1,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 3db22325ea2..db03c4c8ec1 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1808,6 +1808,7 @@ static struct scsi_host_template sym2_template = {
.eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,
.this_id = 7,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
.max_sectors = 0xFFFF,
#ifdef SYM_LINUX_PROC_INFO_SUPPORT
.proc_info = sym53c8xx_proc_info,
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index fc9f51818e8..7edd6ceb13b 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -450,7 +450,8 @@ static struct scsi_host_template driver_template = {
.slave_configure = u14_34f_slave_configure,
.this_id = 7,
.unchecked_isa_dma = 1,
- .use_clustering = ENABLE_CLUSTERING
+ .use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index c08235d5afc..ea72bbeb8f9 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -1197,5 +1197,6 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index d6fd4259c56..255c611e78b 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1671,6 +1671,7 @@ static struct scsi_host_template driver_template = {
.cmd_per_lun = 1,
.unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
+ .use_sg_chaining = ENABLE_SG_CHAINING,
};
#include "scsi_module.c"
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 1ea1ed82c35..0e357562ce9 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1036,6 +1036,7 @@ enum pci_board_num_t {
pbn_b0_2_115200,
pbn_b0_4_115200,
pbn_b0_5_115200,
+ pbn_b0_8_115200,
pbn_b0_1_921600,
pbn_b0_2_921600,
@@ -1172,6 +1173,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 115200,
.uart_offset = 8,
},
+ [pbn_b0_8_115200] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
[pbn_b0_1_921600] = {
.flags = FL_BASE0,
@@ -2566,6 +2573,119 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
0, 0, pbn_b2_8_921600 },
+
+ /*
+ * Mainpine series cards: Fairly standard layout but fools
+ * parts of the autodetect in some cases and uses otherwise
+ * unmatched communications subclasses in the PCI Express case
+ */
+
+ { /* RockForceDUO */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0200,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceQUATRO */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0300,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceDUO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0400,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceQUATRO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0500,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForce+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0600,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForce+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0700,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceOCTO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0800,
+ 0, 0, pbn_b0_8_115200 },
+ { /* RockForceDUO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0C00,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceQUARTRO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x0D00,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceOCTO+ */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x1D00,
+ 0, 0, pbn_b0_8_115200 },
+ { /* RockForceD1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2000,
+ 0, 0, pbn_b0_1_115200 },
+ { /* RockForceF1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2100,
+ 0, 0, pbn_b0_1_115200 },
+ { /* RockForceD2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2200,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceF2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2300,
+ 0, 0, pbn_b0_2_115200 },
+ { /* RockForceD4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2400,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceF4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2500,
+ 0, 0, pbn_b0_4_115200 },
+ { /* RockForceD8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2600,
+ 0, 0, pbn_b0_8_115200 },
+ { /* RockForceF8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x2700,
+ 0, 0, pbn_b0_8_115200 },
+ { /* IQ Express D1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3000,
+ 0, 0, pbn_b0_1_115200 },
+ { /* IQ Express F1 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3100,
+ 0, 0, pbn_b0_1_115200 },
+ { /* IQ Express D2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3200,
+ 0, 0, pbn_b0_2_115200 },
+ { /* IQ Express F2 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3300,
+ 0, 0, pbn_b0_2_115200 },
+ { /* IQ Express D4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3400,
+ 0, 0, pbn_b0_4_115200 },
+ { /* IQ Express F4 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3500,
+ 0, 0, pbn_b0_4_115200 },
+ { /* IQ Express D8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3C00,
+ 0, 0, pbn_b0_8_115200 },
+ { /* IQ Express F8 */
+ PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
+ PCI_VENDOR_ID_MAINPINE, 0x3D00,
+ 0, 0, pbn_b0_8_115200 },
+
+
/*
* PA Semi PA6T-1682M on-chip UART
*/
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 301c8c0be9d..926f58a674a 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "WACF004", 0 },
{ "WACF005", 0 },
{ "WACF006", 0 },
+ { "WACF007", 0 },
+ { "WACF008", 0 },
/* Compaq touchscreen */
{ "FPI2002", 0 },
/* Fujitsu Stylistic touchscreens */
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 312bef6bd58..7e8724d3571 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -514,6 +514,8 @@ struct tty_driver *serial_driver;
* TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128
* BUF_SIZE can't be > 128
*/
+#define CRIS_BUF_SIZE 512
+
/* Currently 16 descriptors x 128 bytes = 2048 bytes */
#define SERIAL_DESCR_BUF_SIZE 256
@@ -2497,55 +2499,18 @@ static void flush_to_flip_buffer(struct e100_serial *info)
return;
}
- length = tty->flip.count;
- /* Don't flip more than the ldisc has room for.
- * The return value from ldisc.receive_room(tty) - might not be up to
- * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the
- * processed and not accounted for yet.
- * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way.
- * Lets buffer data here and let flow control take care of it.
- * Since we normally flip large chunks, the ldisc don't react
- * with throttle until too late if we flip to much.
- */
- max_flip_size = tty->ldisc.receive_room(tty);
- if (max_flip_size < 0)
- max_flip_size = 0;
- if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */
- length + info->recv_cnt + /* We have this queued */
- 2*SERIAL_DESCR_BUF_SIZE + /* This could be on the way */
- TTY_THRESHOLD_THROTTLE)) { /* Some slack */
- /* check TTY_THROTTLED first so it indicates our state */
- if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
- DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size));
- rs_throttle(tty);
- }
-#if 0
- else if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */
- length + info->recv_cnt + /* We have this queued */
- SERIAL_DESCR_BUF_SIZE + /* This could be on the way */
- TTY_THRESHOLD_THROTTLE)) { /* Some slack */
- DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size));
- rs_throttle(tty);
- }
-#endif
- }
-
- if (max_flip_size > TTY_FLIPBUF_SIZE)
- max_flip_size = TTY_FLIPBUF_SIZE;
-
- while ((buffer = info->first_recv_buffer) && length < max_flip_size) {
+ while ((buffer = info->first_recv_buffer) != NULL) {
unsigned int count = buffer->length;
- if (length + count > max_flip_size)
- count = max_flip_size - length;
+ count = tty_buffer_request_room(tty, count);
+ if (count == 0) /* Throttle ?? */
+ break;
- memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count);
- memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count);
- tty->flip.flag_buf_ptr[length] = buffer->error;
+ if (count > 1)
+ tty_insert_flip_strings(tty, buffer->buffer, count - 1);
+ tty_insert_flip_char(tty, buffer->buffer[count-1], buffer->error);
- length += count;
info->recv_cnt -= count;
- DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length));
if (count == buffer->length) {
info->first_recv_buffer = buffer->next;
@@ -2560,14 +2525,6 @@ static void flush_to_flip_buffer(struct e100_serial *info)
if (!info->first_recv_buffer)
info->last_recv_buffer = NULL;
- tty->flip.count = length;
- DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) {
- DEBUG_LOG(info->line, "ldisc %lu\n",
- tty->ldisc.chars_in_buffer(tty));
- DEBUG_LOG(info->line, "flip.count %lu\n",
- tty->flip.count);
- }
- );
restore_flags(flags);
DFLIP(
@@ -2722,17 +2679,17 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
printk("!NO TTY!\n");
return info;
}
- if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) {
+ if (tty->flip.count >= CRIS_BUF_SIZE - TTY_THRESHOLD_THROTTLE) {
/* check TTY_THROTTLED first so it indicates our state */
if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count));
rs_throttle(tty);
}
}
- if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ if (tty->flip.count >= CRIS_BUF_SIZE) {
DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count);
tty->flip.work.func((void *) tty);
- if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ if (tty->flip.count >= CRIS_BUF_SIZE) {
DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count);
return info; /* if TTY_DONT_FLIP is set */
}
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 281f23a371b..94ec6637250 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -500,13 +500,11 @@ void jsm_input(struct jsm_channel *ch)
{
struct jsm_board *bd;
struct tty_struct *tp;
- struct tty_ldisc *ld;
u32 rmask;
u16 head;
u16 tail;
int data_len;
unsigned long lock_flags;
- int flip_len = 0;
int len = 0;
int n = 0;
int s = 0;
@@ -574,45 +572,13 @@ void jsm_input(struct jsm_channel *ch)
jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n");
- /*
- * If the rxbuf is empty and we are not throttled, put as much
- * as we can directly into the linux TTY buffer.
- *
- */
- flip_len = TTY_FLIPBUF_SIZE;
-
- len = min(data_len, flip_len);
- len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt);
- ld = tty_ldisc_ref(tp);
-
- /*
- * If we were unable to get a reference to the ld,
- * don't flush our buffer, and act like the ld doesn't
- * have any space to put the data right now.
- */
- if (!ld) {
- len = 0;
- } else {
- /*
- * If ld doesn't have a pointer to a receive_buf function,
- * flush the data, then act like the ld doesn't have any
- * space to put the data right now.
- */
- if (!ld->receive_buf) {
- ch->ch_r_head = ch->ch_r_tail;
- len = 0;
- }
- }
-
- if (len <= 0) {
+ if (data_len <= 0) {
spin_unlock_irqrestore(&ch->ch_lock, lock_flags);
jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n");
- if (ld)
- tty_ldisc_deref(ld);
return;
}
- len = tty_buffer_request_room(tp, len);
+ len = tty_buffer_request_room(tp, data_len);
n = len;
/*
@@ -647,7 +613,7 @@ void jsm_input(struct jsm_channel *ch)
else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE)
tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME);
else
- tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL);
+ tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL);
}
} else {
tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ;
@@ -666,9 +632,6 @@ void jsm_input(struct jsm_channel *ch)
/* Tell the tty layer its okay to "eat" the data now */
tty_flip_buffer_push(tp);
- if (ld)
- tty_ldisc_deref(ld);
-
jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n");
}
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 6e09c8b395e..348ee2c19b5 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -539,7 +539,7 @@ static void serial_do_unlink(struct irq_info *i, struct uart_sio_port *up)
static int serial_link_irq_chain(struct uart_sio_port *up)
{
struct irq_info *i = irq_lists + up->port.irq;
- int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+ int ret, irq_flags = 0;
spin_lock_irq(&i->lock);
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h
index 849f1b2c253..e9b7e11793b 100644
--- a/drivers/serial/m32r_sio.h
+++ b/drivers/serial/m32r_sio.h
@@ -46,9 +46,3 @@ struct old_serial_port {
#define PROBE_ANY (~0)
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-
-#ifdef CONFIG_SERIAL_SIO_SHARE_IRQ
-#define M32R_SIO_SHARE_IRQS 1
-#else
-#define M32R_SIO_SHARE_IRQS 0
-#endif
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index e9c6cb391a2..af3a011b2b2 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -42,6 +42,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
+#include <linux/clk.h>
#include <asm/io.h>
#include <asm/hardware.h>
@@ -55,7 +56,7 @@ struct uart_pxa_port {
unsigned char lcr;
unsigned char mcr;
unsigned int lsr_break_flag;
- unsigned int cken;
+ struct clk *clk;
char *name;
};
@@ -351,6 +352,8 @@ static int serial_pxa_startup(struct uart_port *port)
else
up->mcr = 0;
+ up->port.uartclk = clk_get_rate(up->clk);
+
/*
* Allocate the IRQ
*/
@@ -546,9 +549,11 @@ serial_pxa_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
struct uart_pxa_port *up = (struct uart_pxa_port *)port;
- pxa_set_cken(up->cken, !state);
+
if (!state)
- udelay(1);
+ clk_enable(up->clk);
+ else
+ clk_disable(up->clk);
}
static void serial_pxa_release_port(struct uart_port *port)
@@ -582,7 +587,7 @@ serial_pxa_type(struct uart_port *port)
#ifdef CONFIG_SERIAL_PXA_CONSOLE
-static struct uart_pxa_port serial_pxa_ports[];
+static struct uart_pxa_port *serial_pxa_ports[4];
static struct uart_driver serial_pxa_reg;
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
@@ -632,9 +637,11 @@ static void serial_pxa_console_putchar(struct uart_port *port, int ch)
static void
serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
{
- struct uart_pxa_port *up = &serial_pxa_ports[co->index];
+ struct uart_pxa_port *up = serial_pxa_ports[co->index];
unsigned int ier;
+ clk_enable(up->clk);
+
/*
* First save the IER then disable the interrupts
*/
@@ -649,6 +656,8 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
*/
wait_for_xmitr(up);
serial_out(up, UART_IER, ier);
+
+ clk_disable(up->clk);
}
static int __init
@@ -662,7 +671,9 @@ serial_pxa_console_setup(struct console *co, char *options)
if (co->index == -1 || co->index >= serial_pxa_reg.nr)
co->index = 0;
- up = &serial_pxa_ports[co->index];
+ up = serial_pxa_ports[co->index];
+ if (!up)
+ return -ENODEV;
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -680,15 +691,6 @@ static struct console serial_pxa_console = {
.data = &serial_pxa_reg,
};
-static int __init
-serial_pxa_console_init(void)
-{
- register_console(&serial_pxa_console);
- return 0;
-}
-
-console_initcall(serial_pxa_console_init);
-
#define PXA_CONSOLE &serial_pxa_console
#else
#define PXA_CONSOLE NULL
@@ -714,73 +716,13 @@ struct uart_ops serial_pxa_pops = {
.verify_port = serial_pxa_verify_port,
};
-static struct uart_pxa_port serial_pxa_ports[] = {
- { /* FFUART */
- .name = "FFUART",
- .cken = CKEN_FFUART,
- .port = {
- .type = PORT_PXA,
- .iotype = UPIO_MEM,
- .membase = (void *)&FFUART,
- .mapbase = __PREG(FFUART),
- .irq = IRQ_FFUART,
- .uartclk = 921600 * 16,
- .fifosize = 64,
- .ops = &serial_pxa_pops,
- .line = 0,
- },
- }, { /* BTUART */
- .name = "BTUART",
- .cken = CKEN_BTUART,
- .port = {
- .type = PORT_PXA,
- .iotype = UPIO_MEM,
- .membase = (void *)&BTUART,
- .mapbase = __PREG(BTUART),
- .irq = IRQ_BTUART,
- .uartclk = 921600 * 16,
- .fifosize = 64,
- .ops = &serial_pxa_pops,
- .line = 1,
- },
- }, { /* STUART */
- .name = "STUART",
- .cken = CKEN_STUART,
- .port = {
- .type = PORT_PXA,
- .iotype = UPIO_MEM,
- .membase = (void *)&STUART,
- .mapbase = __PREG(STUART),
- .irq = IRQ_STUART,
- .uartclk = 921600 * 16,
- .fifosize = 64,
- .ops = &serial_pxa_pops,
- .line = 2,
- },
- }, { /* HWUART */
- .name = "HWUART",
- .cken = CKEN_HWUART,
- .port = {
- .type = PORT_PXA,
- .iotype = UPIO_MEM,
- .membase = (void *)&HWUART,
- .mapbase = __PREG(HWUART),
- .irq = IRQ_HWUART,
- .uartclk = 921600 * 16,
- .fifosize = 64,
- .ops = &serial_pxa_pops,
- .line = 3,
- },
- }
-};
-
static struct uart_driver serial_pxa_reg = {
.owner = THIS_MODULE,
.driver_name = "PXA serial",
.dev_name = "ttyS",
.major = TTY_MAJOR,
.minor = 64,
- .nr = ARRAY_SIZE(serial_pxa_ports),
+ .nr = 4,
.cons = PXA_CONSOLE,
};
@@ -806,10 +748,68 @@ static int serial_pxa_resume(struct platform_device *dev)
static int serial_pxa_probe(struct platform_device *dev)
{
- serial_pxa_ports[dev->id].port.dev = &dev->dev;
- uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port);
- platform_set_drvdata(dev, &serial_pxa_ports[dev->id]);
+ struct uart_pxa_port *sport;
+ struct resource *mmres, *irqres;
+ int ret;
+
+ mmres = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ irqres = platform_get_resource(dev, IORESOURCE_IRQ, 0);
+ if (!mmres || !irqres)
+ return -ENODEV;
+
+ sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL);
+ if (!sport)
+ return -ENOMEM;
+
+ sport->clk = clk_get(&dev->dev, "UARTCLK");
+ if (IS_ERR(sport->clk)) {
+ ret = PTR_ERR(sport->clk);
+ goto err_free;
+ }
+
+ sport->port.type = PORT_PXA;
+ sport->port.iotype = UPIO_MEM;
+ sport->port.mapbase = mmres->start;
+ sport->port.irq = irqres->start;
+ sport->port.fifosize = 64;
+ sport->port.ops = &serial_pxa_pops;
+ sport->port.line = dev->id;
+ sport->port.dev = &dev->dev;
+ sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
+ sport->port.uartclk = clk_get_rate(sport->clk);
+
+ /*
+ * Is it worth keeping this?
+ */
+ if (mmres->start == __PREG(FFUART))
+ sport->name = "FFUART";
+ else if (mmres->start == __PREG(BTUART))
+ sport->name = "BTUART";
+ else if (mmres->start == __PREG(STUART))
+ sport->name = "STUART";
+ else if (mmres->start == __PREG(HWUART))
+ sport->name = "HWUART";
+ else
+ sport->name = "???";
+
+ sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1);
+ if (!sport->port.membase) {
+ ret = -ENOMEM;
+ goto err_clk;
+ }
+
+ serial_pxa_ports[dev->id] = sport;
+
+ uart_add_one_port(&serial_pxa_reg, &sport->port);
+ platform_set_drvdata(dev, sport);
+
return 0;
+
+ err_clk:
+ clk_put(sport->clk);
+ err_free:
+ kfree(sport);
+ return ret;
}
static int serial_pxa_remove(struct platform_device *dev)
@@ -818,8 +818,9 @@ static int serial_pxa_remove(struct platform_device *dev)
platform_set_drvdata(dev, NULL);
- if (sport)
- uart_remove_one_port(&serial_pxa_reg, &sport->port);
+ uart_remove_one_port(&serial_pxa_reg, &sport->port);
+ clk_put(sport->clk);
+ kfree(sport);
return 0;
}
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index a055f58f342..103189095c8 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1938,18 +1938,41 @@ static void uart_change_pm(struct uart_state *state, int pm_state)
}
}
+struct uart_match {
+ struct uart_port *port;
+ struct uart_driver *driver;
+};
+
+static int serial_match_port(struct device *dev, void *data)
+{
+ struct uart_match *match = data;
+ dev_t devt = MKDEV(match->driver->major, match->driver->minor) + match->port->line;
+
+ return dev->devt == devt; /* Actually, only one tty per port */
+}
+
int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
{
struct uart_state *state = drv->state + port->line;
+ struct device *tty_dev;
+ struct uart_match match = {port, drv};
mutex_lock(&state->mutex);
-#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND
- if (uart_console(port)) {
+ if (!console_suspend_enabled && uart_console(port)) {
+ /* we're going to avoid suspending serial console */
mutex_unlock(&state->mutex);
return 0;
}
-#endif
+
+ tty_dev = device_find_child(port->dev, &match, serial_match_port);
+ if (device_may_wakeup(tty_dev)) {
+ enable_irq_wake(port->irq);
+ put_device(tty_dev);
+ mutex_unlock(&state->mutex);
+ return 0;
+ }
+ port->suspended = 1;
if (state->info && state->info->flags & UIF_INITIALIZED) {
const struct uart_ops *ops = port->ops;
@@ -1992,12 +2015,18 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
mutex_lock(&state->mutex);
-#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND
- if (uart_console(port)) {
+ if (!console_suspend_enabled && uart_console(port)) {
+ /* no need to resume serial console, it wasn't suspended */
mutex_unlock(&state->mutex);
return 0;
}
-#endif
+
+ if (!port->suspended) {
+ disable_irq_wake(port->irq);
+ mutex_unlock(&state->mutex);
+ return 0;
+ }
+ port->suspended = 0;
uart_change_pm(state, 0);
@@ -2127,6 +2156,14 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
spin_unlock_irqrestore(&port->lock, flags);
/*
+ * If this driver supports console, and it hasn't been
+ * successfully registered yet, try to re-register it.
+ * It may be that the port was not available.
+ */
+ if (port->cons && !(port->cons->flags & CON_ENABLED))
+ register_console(port->cons);
+
+ /*
* Power down all ports by default, except the
* console if we have one.
*/
@@ -2270,6 +2307,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
{
struct uart_state *state;
int ret = 0;
+ struct device *tty_dev;
BUG_ON(in_interrupt());
@@ -2286,6 +2324,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
}
state->port = port;
+ state->pm_state = -1;
port->cons = drv->cons;
port->info = state->info;
@@ -2305,16 +2344,13 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
* Register the port whether it's detected or not. This allows
* setserial to be used to alter this ports parameters.
*/
- tty_register_device(drv->tty_driver, port->line, port->dev);
-
- /*
- * If this driver supports console, and it hasn't been
- * successfully registered yet, try to re-register it.
- * It may be that the port was not available.
- */
- if (port->type != PORT_UNKNOWN &&
- port->cons && !(port->cons->flags & CON_ENABLED))
- register_console(port->cons);
+ tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev);
+ if (likely(!IS_ERR(tty_dev))) {
+ device_can_wakeup(tty_dev) = 1;
+ device_set_wakeup_enable(tty_dev, 0);
+ } else
+ printk(KERN_ERR "Cannot register tty device on line %d\n",
+ port->line);
/*
* Ensure UPF_DEAD is not set.
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7c8d78fbbbf..5afcb2fa7cd 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -911,6 +911,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 0930e2a8551..6846a6c38b6 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -25,19 +25,15 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
-#include <linux/sysrq.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
-#include <linux/mutex.h>
#include <asm/io.h>
-static char *serial_version = "1.10";
+static char *serial_version = "1.11";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -68,8 +64,6 @@ static char *serial_name = "TX39/49 Serial driver";
*/
#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS
-#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-
struct uart_txx9_port {
struct uart_port port;
/* No additional info for now */
@@ -756,21 +750,6 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags)
serial_txx9_initialize(port);
}
-static int
-serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
- unsigned long new_port = ser->port;
- if (HIGH_BITS_OFFSET)
- new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET;
- if (ser->type != port->type ||
- ser->irq != port->irq ||
- ser->io_type != port->iotype ||
- new_port != port->iobase ||
- (unsigned long)ser->iomem_base != port->mapbase)
- return -EINVAL;
- return 0;
-}
-
static const char *
serial_txx9_type(struct uart_port *port)
{
@@ -794,7 +773,6 @@ static struct uart_ops serial_txx9_pops = {
.release_port = serial_txx9_release_port,
.request_port = serial_txx9_request_port,
.config_port = serial_txx9_config_port,
- .verify_port = serial_txx9_verify_port,
};
static struct uart_txx9_port serial_txx9_ports[UART_NR];
@@ -950,7 +928,8 @@ int __init early_serial_txx9_setup(struct uart_port *port)
serial_txx9_ports[port->line].port = *port;
serial_txx9_ports[port->line].port.ops = &serial_txx9_pops;
- serial_txx9_ports[port->line].port.flags |= UPF_BOOT_AUTOCONF;
+ serial_txx9_ports[port->line].port.flags |=
+ UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
return 0;
}
@@ -995,7 +974,8 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
uart->port.irq = port->irq;
uart->port.uartclk = port->uartclk;
uart->port.iotype = port->iotype;
- uart->port.flags = port->flags | UPF_BOOT_AUTOCONF;
+ uart->port.flags = port->flags
+ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
uart->port.mapbase = port->mapbase;
if (port->dev)
uart->port.dev = port->dev;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b91571122da..a77ede598d3 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -124,16 +124,17 @@ config SPI_MPC52xx_PSC
Controller in master SPI mode.
config SPI_MPC83xx
- tristate "Freescale MPC83xx SPI controller"
- depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
+ tristate "Freescale MPC83xx/QUICC Engine SPI controller"
+ depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
select SPI_BITBANG
help
- This enables using the Freescale MPC83xx SPI controller in master
- mode.
+ This enables using the Freescale MPC83xx and QUICC Engine SPI
+ controllers in master mode.
Note, this driver uniquely supports the SPI controller on the MPC83xx
- family of PowerPC processors. The MPC83xx uses a simple set of shift
- registers for data (opposed to the CPM based descriptor model).
+ family of PowerPC processors, plus processors with QUICC Engine
+ technology. This driver uses a simple set of shift registers for data
+ (opposed to the CPM based descriptor model).
config SPI_OMAP_UWIRE
tristate "OMAP1 MicroWire"
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index b0469749310..0d342dcdd30 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -211,7 +211,7 @@ static void atmel_spi_next_message(struct spi_master *master)
msg = list_entry(as->queue.next, struct spi_message, queue);
spi = msg->spi;
- dev_dbg(master->cdev.dev, "start message %p for %s\n",
+ dev_dbg(master->dev.parent, "start message %p for %s\n",
msg, spi->dev.bus_id);
/* select chip if it's not still active */
@@ -266,10 +266,10 @@ static void atmel_spi_dma_unmap_xfer(struct spi_master *master,
struct spi_transfer *xfer)
{
if (xfer->tx_dma != INVALID_DMA_ADDRESS)
- dma_unmap_single(master->cdev.dev, xfer->tx_dma,
+ dma_unmap_single(master->dev.parent, xfer->tx_dma,
xfer->len, DMA_TO_DEVICE);
if (xfer->rx_dma != INVALID_DMA_ADDRESS)
- dma_unmap_single(master->cdev.dev, xfer->rx_dma,
+ dma_unmap_single(master->dev.parent, xfer->rx_dma,
xfer->len, DMA_FROM_DEVICE);
}
@@ -285,7 +285,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
list_del(&msg->queue);
msg->status = status;
- dev_dbg(master->cdev.dev,
+ dev_dbg(master->dev.parent,
"xfer complete: %u bytes transferred\n",
msg->actual_length);
@@ -348,7 +348,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
if (xfer->delay_usecs)
udelay(xfer->delay_usecs);
- dev_warn(master->cdev.dev, "fifo overrun (%u/%u remaining)\n",
+ dev_warn(master->dev.parent, "fifo overrun (%u/%u remaining)\n",
spi_readl(as, TCR), spi_readl(as, RCR));
/*
@@ -363,7 +363,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
break;
if (!timeout)
- dev_warn(master->cdev.dev,
+ dev_warn(master->dev.parent,
"timeout waiting for TXEMPTY");
while (spi_readl(as, SR) & SPI_BIT(RDRF))
spi_readl(as, RDR);
@@ -526,7 +526,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
struct atmel_spi *as;
struct spi_transfer *xfer;
unsigned long flags;
- struct device *controller = spi->master->cdev.dev;
+ struct device *controller = spi->master->dev.parent;
as = spi_master_get_devdata(spi->master);
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index d2a4b2bdb07..e9aba932f21 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -503,7 +503,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
INIT_LIST_HEAD(&mps->queue);
mps->workqueue = create_singlethread_workqueue(
- master->cdev.dev->bus_id);
+ master->dev.parent->bus_id);
if (mps->workqueue == NULL) {
ret = -EBUSY;
goto free_irq;
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 6b357cdb9ea..3cdab131c4a 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -645,7 +645,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
clk_enable(mcspi->ick);
clk_enable(mcspi->fck);
- ret = omap2_mcspi_setup_transfer(spi, NULL);
+ ret = omap2_mcspi_setup_transfer(spi, NULL);
clk_disable(mcspi->fck);
clk_disable(mcspi->ick);
@@ -693,7 +693,6 @@ static void omap2_mcspi_work(struct work_struct *work)
struct spi_device *spi;
struct spi_transfer *t = NULL;
int cs_active = 0;
- struct omap2_mcspi_device_config *conf;
struct omap2_mcspi_cs *cs;
int par_override = 0;
int status = 0;
@@ -706,7 +705,6 @@ static void omap2_mcspi_work(struct work_struct *work)
spin_unlock_irq(&mcspi->lock);
spi = m->spi;
- conf = spi->controller_data;
cs = spi->controller_state;
omap2_mcspi_set_enable(spi, 1);
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index d275c615a73..8245b5153f3 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -481,7 +481,7 @@ static void uwire_off(struct uwire_spi *uwire)
spi_master_put(uwire->bitbang.master);
}
-static int uwire_probe(struct platform_device *pdev)
+static int __init uwire_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct uwire_spi *uwire;
@@ -525,7 +525,7 @@ static int uwire_probe(struct platform_device *pdev)
return status;
}
-static int uwire_remove(struct platform_device *pdev)
+static int __exit uwire_remove(struct platform_device *pdev)
{
struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev);
int status;
@@ -543,8 +543,7 @@ static struct platform_driver uwire_driver = {
.bus = &platform_bus_type,
.owner = THIS_MODULE,
},
- .probe = uwire_probe,
- .remove = uwire_remove,
+ .remove = __exit_p(uwire_remove),
// suspend ... unuse ck
// resume ... use ck
};
@@ -566,7 +565,7 @@ static int __init omap_uwire_init(void)
omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
}
- return platform_driver_register(&uwire_driver);
+ return platform_driver_probe(&uwire_driver, uwire_probe);
}
static void __exit omap_uwire_exit(void)
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index e51311b2da0..5f3d808cbc2 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -26,7 +26,6 @@
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/workqueue.h>
-#include <linux/errno.h>
#include <linux/delay.h>
#include <asm/io.h>
@@ -1230,7 +1229,7 @@ static void cleanup(struct spi_device *spi)
kfree(chip);
}
-static int init_queue(struct driver_data *drv_data)
+static int __init init_queue(struct driver_data *drv_data)
{
INIT_LIST_HEAD(&drv_data->queue);
spin_lock_init(&drv_data->lock);
@@ -1243,7 +1242,7 @@ static int init_queue(struct driver_data *drv_data)
INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->cdev.dev->bus_id);
+ drv_data->master->dev.parent->bus_id);
if (drv_data->workqueue == NULL)
return -EBUSY;
@@ -1318,7 +1317,7 @@ static int destroy_queue(struct driver_data *drv_data)
return 0;
}
-static int pxa2xx_spi_probe(struct platform_device *pdev)
+static int __init pxa2xx_spi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pxa2xx_spi_master *platform_info;
@@ -1622,8 +1621,7 @@ static struct platform_driver driver = {
.bus = &platform_bus_type,
.owner = THIS_MODULE,
},
- .probe = pxa2xx_spi_probe,
- .remove = __devexit_p(pxa2xx_spi_remove),
+ .remove = pxa2xx_spi_remove,
.shutdown = pxa2xx_spi_shutdown,
.suspend = pxa2xx_spi_suspend,
.resume = pxa2xx_spi_resume,
@@ -1631,9 +1629,7 @@ static struct platform_driver driver = {
static int __init pxa2xx_spi_init(void)
{
- platform_driver_register(&driver);
-
- return 0;
+ return platform_driver_probe(&driver, pxa2xx_spi_probe);
}
module_init(pxa2xx_spi_init);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index bcb8dd5fb0b..89769ce16f8 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -204,7 +204,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
struct spi_board_info *chip)
{
struct spi_device *proxy;
- struct device *dev = master->cdev.dev;
+ struct device *dev = master->dev.parent;
int status;
/* NOTE: caller did any chip->bus_num checks necessary.
@@ -239,7 +239,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
proxy->modalias = chip->modalias;
snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
- "%s.%u", master->cdev.class_id,
+ "%s.%u", master->dev.bus_id,
chip->chip_select);
proxy->dev.parent = dev;
proxy->dev.bus = &spi_bus_type;
@@ -338,18 +338,18 @@ static void scan_boardinfo(struct spi_master *master)
/*-------------------------------------------------------------------------*/
-static void spi_master_release(struct class_device *cdev)
+static void spi_master_release(struct device *dev)
{
struct spi_master *master;
- master = container_of(cdev, struct spi_master, cdev);
+ master = container_of(dev, struct spi_master, dev);
kfree(master);
}
static struct class spi_master_class = {
.name = "spi_master",
.owner = THIS_MODULE,
- .release = spi_master_release,
+ .dev_release = spi_master_release,
};
@@ -357,7 +357,7 @@ static struct class spi_master_class = {
* spi_alloc_master - allocate SPI master controller
* @dev: the controller, possibly using the platform_bus
* @size: how much zeroed driver-private data to allocate; the pointer to this
- * memory is in the class_data field of the returned class_device,
+ * memory is in the driver_data field of the returned device,
* accessible with spi_master_get_devdata().
* Context: can sleep
*
@@ -383,9 +383,9 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
if (!master)
return NULL;
- class_device_initialize(&master->cdev);
- master->cdev.class = &spi_master_class;
- master->cdev.dev = get_device(dev);
+ device_initialize(&master->dev);
+ master->dev.class = &spi_master_class;
+ master->dev.parent = get_device(dev);
spi_master_set_devdata(master, &master[1]);
return master;
@@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
int spi_register_master(struct spi_master *master)
{
static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
- struct device *dev = master->cdev.dev;
+ struct device *dev = master->dev.parent;
int status = -ENODEV;
int dynamic = 0;
@@ -440,12 +440,12 @@ int spi_register_master(struct spi_master *master)
/* register the device, then userspace will see it.
* registration fails if the bus ID is in use.
*/
- snprintf(master->cdev.class_id, sizeof master->cdev.class_id,
+ snprintf(master->dev.bus_id, sizeof master->dev.bus_id,
"spi%u", master->bus_num);
- status = class_device_add(&master->cdev);
+ status = device_add(&master->dev);
if (status < 0)
goto done;
- dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id,
+ dev_dbg(dev, "registered master %s%s\n", master->dev.bus_id,
dynamic ? " (dynamic)" : "");
/* populate children from any spi device tables */
@@ -478,8 +478,8 @@ void spi_unregister_master(struct spi_master *master)
{
int dummy;
- dummy = device_for_each_child(master->cdev.dev, NULL, __unregister);
- class_device_unregister(&master->cdev);
+ dummy = device_for_each_child(master->dev.parent, NULL, __unregister);
+ device_unregister(&master->dev);
}
EXPORT_SYMBOL_GPL(spi_unregister_master);
@@ -495,13 +495,13 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
*/
struct spi_master *spi_busnum_to_master(u16 bus_num)
{
- struct class_device *cdev;
+ struct device *dev;
struct spi_master *master = NULL;
struct spi_master *m;
down(&spi_master_class.sem);
- list_for_each_entry(cdev, &spi_master_class.children, node) {
- m = container_of(cdev, struct spi_master, cdev);
+ list_for_each_entry(dev, &spi_master_class.children, node) {
+ m = container_of(dev, struct spi_master, dev);
if (m->bus_num == bus_num) {
master = spi_master_get(m);
break;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index f540ed77a10..2ef11bb70b2 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -39,7 +39,6 @@
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/workqueue.h>
-#include <linux/errno.h>
#include <linux/delay.h>
#include <asm/io.h>
@@ -1071,7 +1070,7 @@ static int setup(struct spi_device *spi)
return -ENODEV;
}
- dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d,",
+ dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n",
spi->modalias, chip->width, chip->enable_dma);
dev_dbg(&spi->dev, "ctl_reg is 0x%x, flag_reg is 0x%x\n",
chip->ctl_reg, chip->flag);
@@ -1107,7 +1106,7 @@ static inline int init_queue(struct driver_data *drv_data)
/* init messages workqueue */
INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue =
- create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id);
+ create_singlethread_workqueue(drv_data->master->dev.parent->bus_id);
if (drv_data->workqueue == NULL)
return -EBUSY;
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 0c85c984ccb..81639c6be1c 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -472,7 +472,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
/* this task is the only thing to touch the SPI bits */
bitbang->busy = 0;
bitbang->workqueue = create_singlethread_workqueue(
- bitbang->master->cdev.dev->bus_id);
+ bitbang->master->dev.parent->bus_id);
if (bitbang->workqueue == NULL) {
status = -EBUSY;
goto err1;
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index bd9177f51de..7686ba34430 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1194,7 +1194,7 @@ static int setup(struct spi_device *spi)
chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
if (!chip) {
dev_err(&spi->dev,
- "setup - cannot allocate controller state");
+ "setup - cannot allocate controller state\n");
return -ENOMEM;
}
chip->control = SPI_DEFAULT_CONTROL;
@@ -1206,7 +1206,7 @@ static int setup(struct spi_device *spi)
if (!chip_info) {
dev_err(&spi->dev,
"setup - "
- "cannot allocate controller data");
+ "cannot allocate controller data\n");
status = -ENOMEM;
goto err_first_setup;
}
@@ -1361,7 +1361,7 @@ static void cleanup(struct spi_device *spi)
kfree(spi_get_ctldata(spi));
}
-static int init_queue(struct driver_data *drv_data)
+static int __init init_queue(struct driver_data *drv_data)
{
INIT_LIST_HEAD(&drv_data->queue);
spin_lock_init(&drv_data->lock);
@@ -1374,7 +1374,7 @@ static int init_queue(struct driver_data *drv_data)
INIT_WORK(&drv_data->work, pump_messages);
drv_data->workqueue = create_singlethread_workqueue(
- drv_data->master->cdev.dev->bus_id);
+ drv_data->master->dev.parent->bus_id);
if (drv_data->workqueue == NULL)
return -EBUSY;
@@ -1444,7 +1444,7 @@ static int destroy_queue(struct driver_data *drv_data)
return 0;
}
-static int spi_imx_probe(struct platform_device *pdev)
+static int __init spi_imx_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_imx_master *platform_info;
@@ -1622,7 +1622,7 @@ err_no_mem:
return status;
}
-static int __devexit spi_imx_remove(struct platform_device *pdev)
+static int __exit spi_imx_remove(struct platform_device *pdev)
{
struct driver_data *drv_data = platform_get_drvdata(pdev);
int irq;
@@ -1739,8 +1739,7 @@ static struct platform_driver driver = {
.bus = &platform_bus_type,
.owner = THIS_MODULE,
},
- .probe = spi_imx_probe,
- .remove = __devexit_p(spi_imx_remove),
+ .remove = __exit_p(spi_imx_remove),
.shutdown = spi_imx_shutdown,
.suspend = spi_imx_suspend,
.resume = spi_imx_resume,
@@ -1748,7 +1747,7 @@ static struct platform_driver driver = {
static int __init spi_imx_init(void)
{
- return platform_driver_register(&driver);
+ return platform_driver_probe(&driver, spi_imx_probe);
}
module_init(spi_imx_init);
diff --git a/drivers/spi/spi_lm70llp.c b/drivers/spi/spi_lm70llp.c
index 4ea68ac1611..39d8d8ad65c 100644
--- a/drivers/spi/spi_lm70llp.c
+++ b/drivers/spi/spi_lm70llp.c
@@ -82,7 +82,7 @@ struct spi_lm70llp {
struct pardevice *pd;
struct spi_device *spidev_lm70;
struct spi_board_info info;
- struct class_device *cdev;
+ //struct device *dev;
};
/* REVISIT : ugly global ; provides "exclusive open" facility */
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 32cda77b31c..4580b9cf625 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -511,7 +511,7 @@ err:
return ret;
}
-static int __devexit mpc83xx_spi_remove(struct platform_device *dev)
+static int __exit mpc83xx_spi_remove(struct platform_device *dev)
{
struct mpc83xx_spi *mpc83xx_spi;
struct spi_master *master;
@@ -529,8 +529,7 @@ static int __devexit mpc83xx_spi_remove(struct platform_device *dev)
MODULE_ALIAS("mpc83xx_spi"); /* for platform bus hotplug */
static struct platform_driver mpc83xx_spi_driver = {
- .probe = mpc83xx_spi_probe,
- .remove = __devexit_p(mpc83xx_spi_remove),
+ .remove = __exit_p(mpc83xx_spi_remove),
.driver = {
.name = "mpc83xx_spi",
},
@@ -538,7 +537,7 @@ static struct platform_driver mpc83xx_spi_driver = {
static int __init mpc83xx_spi_init(void)
{
- return platform_driver_register(&mpc83xx_spi_driver);
+ return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe);
}
static void __exit mpc83xx_spi_exit(void)
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index e9b683f7d7b..89d6685a5ca 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -233,7 +233,7 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
return IRQ_HANDLED;
}
-static int s3c24xx_spi_probe(struct platform_device *pdev)
+static int __init s3c24xx_spi_probe(struct platform_device *pdev)
{
struct s3c24xx_spi *hw;
struct spi_master *master;
@@ -382,7 +382,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
return err;
}
-static int s3c24xx_spi_remove(struct platform_device *dev)
+static int __exit s3c24xx_spi_remove(struct platform_device *dev)
{
struct s3c24xx_spi *hw = platform_get_drvdata(dev);
@@ -429,8 +429,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
MODULE_ALIAS("s3c2410_spi"); /* for platform bus hotplug */
static struct platform_driver s3c24xx_spidrv = {
- .probe = s3c24xx_spi_probe,
- .remove = s3c24xx_spi_remove,
+ .remove = __exit_p(s3c24xx_spi_remove),
.suspend = s3c24xx_spi_suspend,
.resume = s3c24xx_spi_resume,
.driver = {
@@ -441,7 +440,7 @@ static struct platform_driver s3c24xx_spidrv = {
static int __init s3c24xx_spi_init(void)
{
- return platform_driver_register(&s3c24xx_spidrv);
+ return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
}
static void __exit s3c24xx_spi_exit(void)
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index b7f4bb239ea..cc5094f37dd 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -400,7 +400,7 @@ static int __init txx9spi_probe(struct platform_device *dev)
goto exit;
}
- c->workqueue = create_singlethread_workqueue(master->cdev.dev->bus_id);
+ c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
if (!c->workqueue)
goto exit;
c->last_chipselect = -1;
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index b4a5e5e9d9f..d976660cb7f 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -22,7 +22,7 @@ config SSB
config SSB_PCIHOST_POSSIBLE
bool
- depends on SSB && PCI
+ depends on SSB && (PCI = y || PCI = SSB)
default y
config SSB_PCIHOST
@@ -37,7 +37,7 @@ config SSB_PCIHOST
config SSB_PCMCIAHOST_POSSIBLE
bool
- depends on SSB && PCMCIA && EXPERIMENTAL
+ depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL
default y
config SSB_PCMCIAHOST
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index ab8691a3258..3d3dd32bf3a 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -173,7 +173,7 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
void ssb_mipscore_init(struct ssb_mipscore *mcore)
{
- struct ssb_bus *bus = mcore->dev->bus;
+ struct ssb_bus *bus;
struct ssb_device *dev;
unsigned long hz, ns;
unsigned int irq, i;
@@ -183,6 +183,7 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
+ bus = mcore->dev->bus;
hz = ssb_clockspeed(bus);
if (!hz)
hz = 100000000;
diff --git a/drivers/tc/.gitignore b/drivers/tc/.gitignore
deleted file mode 100644
index acc0e1e6a65..00000000000
--- a/drivers/tc/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-lk201-map.c
diff --git a/drivers/tc/Makefile b/drivers/tc/Makefile
index c899246bd36..623b2106322 100644
--- a/drivers/tc/Makefile
+++ b/drivers/tc/Makefile
@@ -5,18 +5,3 @@
# Object file lists.
obj-$(CONFIG_TC) += tc.o tc-driver.o
-obj-$(CONFIG_VT) += lk201.o lk201-map.o lk201-remap.o
-
-$(obj)/lk201-map.o: $(obj)/lk201-map.c
-
-# Uncomment if you're changing the keymap and have an appropriate
-# loadkeys version for the map. By default, we'll use the shipped
-# versions.
-# GENERATE_KEYMAP := 1
-
-ifdef GENERATE_KEYMAP
-
-$(obj)/lk201-map.c: $(obj)/%.c: $(src)/%.map
- loadkeys --mktable $< > $@
-
-endif
diff --git a/drivers/tc/lk201-map.c_shipped b/drivers/tc/lk201-map.c_shipped
deleted file mode 100644
index a9df8f5bf62..00000000000
--- a/drivers/tc/lk201-map.c_shipped
+++ /dev/null
@@ -1,265 +0,0 @@
-
-/* Do not edit this file! It was automatically generated by */
-/* loadkeys --mktable defkeymap.map > defkeymap.c */
-
-#include <linux/types.h>
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-
-u_short plain_map[NR_KEYS] = {
- 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106,
- 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf11b,
- 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf060, 0xf031, 0xf032,
- 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 0xf038, 0xf039, 0xf030,
- 0xf02d, 0xf03d, 0xf07f, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf009, 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74,
- 0xfb79, 0xfb75, 0xfb69, 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201,
- 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702,
- 0xf207, 0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a,
- 0xfb6b, 0xfb6c, 0xf03b, 0xf027, 0xf05c, 0xf603, 0xf304, 0xf305,
- 0xf306, 0xf200, 0xf700, 0xf03e, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
- 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf200, 0xf601,
- 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703,
- 0xf020, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-static u_short shift_map[NR_KEYS] = {
- 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106,
- 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf203,
- 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf07e, 0xf021, 0xf040,
- 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a, 0xf028, 0xf029,
- 0xf05f, 0xf02b, 0xf07f, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf009, 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54,
- 0xfb59, 0xfb55, 0xfb49, 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201,
- 0xf117, 0xf20b, 0xf20a, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702,
- 0xf207, 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a,
- 0xfb4b, 0xfb4c, 0xf03a, 0xf022, 0xf07c, 0xf603, 0xf304, 0xf305,
- 0xf306, 0xf200, 0xf700, 0xf03c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
- 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf200, 0xf601,
- 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703,
- 0xf020, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-static u_short altgr_map[NR_KEYS] = {
- 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106,
- 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf202,
- 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf200, 0xf200, 0xf040,
- 0xf200, 0xf024, 0xf200, 0xf200, 0xf07b, 0xf05b, 0xf05d, 0xf07d,
- 0xf05c, 0xf200, 0xf200, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74,
- 0xfb79, 0xfb75, 0xfb69, 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201,
- 0xf117, 0xf118, 0xf119, 0xf911, 0xf912, 0xf913, 0xf30b, 0xf702,
- 0xf207, 0xf914, 0xfb73, 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a,
- 0xfb6b, 0xfb6c, 0xf200, 0xf200, 0xf200, 0xf603, 0xf90e, 0xf90f,
- 0xf910, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
- 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf601,
- 0xf600, 0xf602, 0xf90b, 0xf90c, 0xf90d, 0xf30e, 0xf200, 0xf703,
- 0xf200, 0xf200, 0xf200, 0xf90a, 0xf310, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-static u_short ctrl_map[NR_KEYS] = {
- 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106,
- 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf204,
- 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf81b, 0xf200, 0xf000,
- 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 0xf07f, 0xf200, 0xf200,
- 0xf01f, 0xf200, 0xf008, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf011, 0xf017, 0xf005, 0xf012, 0xf014,
- 0xf019, 0xf015, 0xf009, 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201,
- 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702,
- 0xf207, 0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a,
- 0xf00b, 0xf00c, 0xf200, 0xf007, 0xf01c, 0xf603, 0xf304, 0xf305,
- 0xf306, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
- 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf200, 0xf601,
- 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703,
- 0xf000, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-static u_short shift_ctrl_map[NR_KEYS] = {
- 0xf200, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, 0xf105, 0xf106,
- 0xf107, 0xf108, 0xf109, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf200,
- 0xf11c, 0xf110, 0xf111, 0xf112, 0xf113, 0xf200, 0xf200, 0xf000,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf01f, 0xf200, 0xf200, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf011, 0xf017, 0xf005, 0xf012, 0xf014,
- 0xf019, 0xf015, 0xf009, 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201,
- 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702,
- 0xf207, 0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a,
- 0xf00b, 0xf00c, 0xf200, 0xf200, 0xf200, 0xf603, 0xf304, 0xf305,
- 0xf306, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
- 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf601,
- 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703,
- 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-static u_short alt_map[NR_KEYS] = {
- 0xf200, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506,
- 0xf507, 0xf508, 0xf509, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf200,
- 0xf11c, 0xf510, 0xf511, 0xf512, 0xf513, 0xf01b, 0xf831, 0xf832,
- 0xf833, 0xf834, 0xf835, 0xf836, 0xf837, 0xf838, 0xf839, 0xf830,
- 0xf82d, 0xf83d, 0xf87f, 0xf114, 0xf115, 0xf116, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf809, 0xf871, 0xf877, 0xf865, 0xf872, 0xf874,
- 0xf879, 0xf875, 0xf869, 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d,
- 0xf117, 0xf118, 0xf119, 0xf907, 0xf908, 0xf909, 0xf30b, 0xf702,
- 0xf207, 0xf861, 0xf873, 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a,
- 0xf86b, 0xf86c, 0xf83b, 0xf827, 0xf85c, 0xf603, 0xf904, 0xf905,
- 0xf906, 0xf200, 0xf700, 0xf200, 0xf87a, 0xf878, 0xf863, 0xf876,
- 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf200, 0xf210,
- 0xf600, 0xf211, 0xf901, 0xf902, 0xf903, 0xf30e, 0xf200, 0xf703,
- 0xf820, 0xf200, 0xf200, 0xf900, 0xf310, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-static u_short ctrl_alt_map[NR_KEYS] = {
- 0xf200, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, 0xf505, 0xf506,
- 0xf507, 0xf508, 0xf509, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf200,
- 0xf11c, 0xf510, 0xf511, 0xf512, 0xf513, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf114, 0xf115, 0xf20c, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf811, 0xf817, 0xf805, 0xf812, 0xf814,
- 0xf819, 0xf815, 0xf809, 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201,
- 0xf117, 0xf118, 0xf119, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf702,
- 0xf207, 0xf801, 0xf813, 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a,
- 0xf80b, 0xf80c, 0xf200, 0xf200, 0xf200, 0xf603, 0xf304, 0xf305,
- 0xf306, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
- 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf601,
- 0xf600, 0xf602, 0xf301, 0xf302, 0xf303, 0xf30e, 0xf200, 0xf703,
- 0xf200, 0xf200, 0xf200, 0xf300, 0xf20c, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-};
-
-ushort *key_maps[MAX_NR_KEYMAPS] = {
- plain_map, shift_map, altgr_map, 0,
- ctrl_map, shift_ctrl_map, 0, 0,
- alt_map, 0, 0, 0,
- ctrl_alt_map, 0
-};
-
-unsigned int keymap_count = 7;
-
-
-/*
- * Philosophy: most people do not define more strings, but they who do
- * often want quite a lot of string space. So, we statically allocate
- * the default and allocate dynamically in chunks of 512 bytes.
- */
-
-char func_buf[] = {
- '\033', '[', '[', 'A', 0,
- '\033', '[', '[', 'B', 0,
- '\033', '[', '[', 'C', 0,
- '\033', '[', '[', 'D', 0,
- '\033', '[', '[', 'E', 0,
- '\033', '[', '1', '7', '~', 0,
- '\033', '[', '1', '8', '~', 0,
- '\033', '[', '1', '9', '~', 0,
- '\033', '[', '2', '0', '~', 0,
- '\033', '[', '2', '1', '~', 0,
- '\033', '[', '2', '3', '~', 0,
- '\033', '[', '2', '4', '~', 0,
- '\033', '[', '2', '5', '~', 0,
- '\033', '[', '2', '6', '~', 0,
- '\033', '[', '2', '8', '~', 0,
- '\033', '[', '2', '9', '~', 0,
- '\033', '[', '3', '1', '~', 0,
- '\033', '[', '3', '2', '~', 0,
- '\033', '[', '3', '3', '~', 0,
- '\033', '[', '3', '4', '~', 0,
- '\033', '[', '1', '~', 0,
- '\033', '[', '2', '~', 0,
- '\033', '[', '3', '~', 0,
- '\033', '[', '4', '~', 0,
- '\033', '[', '5', '~', 0,
- '\033', '[', '6', '~', 0,
- '\033', '[', 'M', 0,
- '\033', '[', 'P', 0,
-};
-
-
-char *funcbufptr = func_buf;
-int funcbufsize = sizeof(func_buf);
-int funcbufleft = 0; /* space left */
-
-char *func_table[MAX_NR_FUNC] = {
- func_buf + 0,
- func_buf + 5,
- func_buf + 10,
- func_buf + 15,
- func_buf + 20,
- func_buf + 25,
- func_buf + 31,
- func_buf + 37,
- func_buf + 43,
- func_buf + 49,
- func_buf + 55,
- func_buf + 61,
- func_buf + 67,
- func_buf + 73,
- func_buf + 79,
- func_buf + 85,
- func_buf + 91,
- func_buf + 97,
- func_buf + 103,
- func_buf + 109,
- func_buf + 115,
- func_buf + 120,
- func_buf + 125,
- func_buf + 130,
- func_buf + 135,
- func_buf + 140,
- func_buf + 145,
- 0,
- 0,
- func_buf + 149,
- 0,
-};
-
-struct kbdiacr accent_table[MAX_DIACR] = {
- {'`', 'A', 'À'}, {'`', 'a', 'à'},
- {'\'', 'A', 'Á'}, {'\'', 'a', 'á'},
- {'^', 'A', 'Â'}, {'^', 'a', 'â'},
- {'~', 'A', 'Ã'}, {'~', 'a', 'ã'},
- {'"', 'A', 'Ä'}, {'"', 'a', 'ä'},
- {'O', 'A', 'Å'}, {'o', 'a', 'å'},
- {'0', 'A', 'Å'}, {'0', 'a', 'å'},
- {'A', 'A', 'Å'}, {'a', 'a', 'å'},
- {'A', 'E', 'Æ'}, {'a', 'e', 'æ'},
- {',', 'C', 'Ç'}, {',', 'c', 'ç'},
- {'`', 'E', 'È'}, {'`', 'e', 'è'},
- {'\'', 'E', 'É'}, {'\'', 'e', 'é'},
- {'^', 'E', 'Ê'}, {'^', 'e', 'ê'},
- {'"', 'E', 'Ë'}, {'"', 'e', 'ë'},
- {'`', 'I', 'Ì'}, {'`', 'i', 'ì'},
- {'\'', 'I', 'Í'}, {'\'', 'i', 'í'},
- {'^', 'I', 'Î'}, {'^', 'i', 'î'},
- {'"', 'I', 'Ï'}, {'"', 'i', 'ï'},
- {'-', 'D', 'Ð'}, {'-', 'd', 'ð'},
- {'~', 'N', 'Ñ'}, {'~', 'n', 'ñ'},
- {'`', 'O', 'Ò'}, {'`', 'o', 'ò'},
- {'\'', 'O', 'Ó'}, {'\'', 'o', 'ó'},
- {'^', 'O', 'Ô'}, {'^', 'o', 'ô'},
- {'~', 'O', 'Õ'}, {'~', 'o', 'õ'},
- {'"', 'O', 'Ö'}, {'"', 'o', 'ö'},
- {'/', 'O', 'Ø'}, {'/', 'o', 'ø'},
- {'`', 'U', 'Ù'}, {'`', 'u', 'ù'},
- {'\'', 'U', 'Ú'}, {'\'', 'u', 'ú'},
- {'^', 'U', 'Û'}, {'^', 'u', 'û'},
- {'"', 'U', 'Ü'}, {'"', 'u', 'ü'},
- {'\'', 'Y', 'Ý'}, {'\'', 'y', 'ý'},
- {'T', 'H', 'Þ'}, {'t', 'h', 'þ'},
- {'s', 's', 'ß'}, {'"', 'y', 'ÿ'},
- {'s', 'z', 'ß'}, {'i', 'j', 'ÿ'},
-};
-
-unsigned int accent_table_size = 68;
diff --git a/drivers/tc/lk201-map.map b/drivers/tc/lk201-map.map
deleted file mode 100644
index 2c636b4b782..00000000000
--- a/drivers/tc/lk201-map.map
+++ /dev/null
@@ -1,356 +0,0 @@
-# Default kernel keymap. This uses 7 modifier combinations.
-keymaps 0-2,4-5,8,12
-# Change the above line into
-# keymaps 0-2,4-6,8,12
-# in case you want the entries
-# altgr control keycode 83 = Boot
-# altgr control keycode 111 = Boot
-# below.
-#
-# In fact AltGr is used very little, and one more keymap can
-# be saved by mapping AltGr to Alt (and adapting a few entries):
-# keycode 100 = Alt
-#
-keycode 0x15 = grave tilde
- alt keycode 0x15 = Escape
- control keycode 0x15 = Meta_Escape
-keycode 0x16 = one exclam
- alt keycode 0x16 = Meta_one
-keycode 0x17 = two at at
- control keycode 0x17 = nul
- shift control keycode 0x17 = nul
- alt keycode 0x17 = Meta_two
-keycode 0x18 = three numbersign
- control keycode 0x18 = Escape
- alt keycode 0x18 = Meta_three
-keycode 0x19 = four dollar dollar
- control keycode 0x19 = Control_backslash
- alt keycode 0x19 = Meta_four
-keycode 0x1a = five percent
- control keycode 0x1a = Control_bracketright
- alt keycode 0x1a = Meta_five
-keycode 0x1b = six asciicircum
- control keycode 0x1b = Control_asciicircum
- alt keycode 0x1b = Meta_six
-keycode 0x1c = seven ampersand braceleft
- control keycode 0x1c = Control_underscore
- alt keycode 0x1c = Meta_seven
-keycode 0x1d = eight asterisk bracketleft
- control keycode 0x1d = Delete
- alt keycode 0x1d = Meta_eight
-keycode 0x1e = nine parenleft bracketright
- alt keycode 0x1e = Meta_nine
-keycode 0x1f = zero parenright braceright
- alt keycode 0x1f = Meta_zero
-keycode 0x20 = minus underscore backslash
- control keycode 0x20 = Control_underscore
- shift control keycode 0x20 = Control_underscore
- alt keycode 0x20 = Meta_minus
-keycode 0x21 = equal plus
- alt keycode 0x21 = Meta_equal
-keycode 0x22 = Delete Delete
- control keycode 0x22 = BackSpace
- alt keycode 0x22 = Meta_Delete
-keycode 0x2a = Tab Tab
- alt keycode 0x2a = Meta_Tab
-keycode 0x2b = q
-keycode 0x2c = w
-keycode 0x2d = e
- altgr keycode 0x2d = Hex_E
-keycode 0x2e = r
-keycode 0x2f = t
-keycode 0x30 = y
-keycode 0x31 = u
-keycode 0x32 = i
-keycode 0x33 = o
-keycode 0x34 = p
-keycode 0x35 = bracketleft braceleft
- control keycode 0x35 = Escape
- alt keycode 0x35 = Meta_bracketleft
-keycode 0x36 = bracketright braceright asciitilde
- control keycode 0x36 = Control_bracketright
- alt keycode 0x36 = Meta_bracketright
-keycode 0x37 = Return
- alt keycode 0x37 = Meta_Control_m
-keycode 0x3f = Control
-keycode 0x41 = a
- altgr keycode 0x41 = Hex_A
-keycode 0x42 = s
-keycode 0x43 = d
- altgr keycode 0x43 = Hex_D
-keycode 0x44 = f
- altgr keycode 0x44 = Hex_F
-keycode 0x45 = g
-keycode 0x46 = h
-keycode 0x47 = j
-keycode 0x48 = k
-keycode 0x49 = l
-keycode 0x4a = semicolon colon
- alt keycode 0x4a = Meta_semicolon
-keycode 0x4b = apostrophe quotedbl
- control keycode 0x4b = Control_g
- alt keycode 0x4b = Meta_apostrophe
-# keycode 41 = grave asciitilde
-# control keycode 41 = nul
-# alt keycode 41 = Meta_grave
-keycode 0x52 = Shift
-keycode 0x4c = backslash bar
- control keycode 0x4c = Control_backslash
- alt keycode 0x4c = Meta_backslash
-keycode 0x53 = greater less
-keycode 0x54 = z
-keycode 0x55 = x
-keycode 0x56 = c
- altgr keycode 0x56 = Hex_C
-keycode 0x57 = v
-keycode 0x58 = b
- altgr keycode 0x58 = Hex_B
-keycode 0x59 = n
-keycode 0x5a = m
-keycode 0x5b = comma less
- alt keycode 0x5b = Meta_comma
-keycode 0x5c = period greater
- control keycode 0x5c = Compose
- alt keycode 0x5c = Meta_period
-keycode 0x5d = slash question
- control keycode 0x5d = Delete
- alt keycode 0x5d = Meta_slash
-
-keycode 0x67 = Alt
-keycode 0x68 = space space
- control keycode 0x68 = nul
- alt keycode 0x68 = Meta_space
-keycode 0x40 = Caps_Lock
-keycode 0x01 = F1
- control keycode 0x01 = F1
- alt keycode 0x01 = Console_1
- control alt keycode 0x01 = Console_1
-keycode 0x02 = F2
- control keycode 0x02 = F2
- alt keycode 0x02 = Console_2
- control alt keycode 0x02 = Console_2
-keycode 0x03 = F3
- control keycode 0x03 = F3
- alt keycode 0x03 = Console_3
- control alt keycode 0x03 = Console_3
-keycode 0x04 = F4
- control keycode 0x04 = F4
- alt keycode 0x04 = Console_4
- control alt keycode 0x04 = Console_4
-keycode 0x05 = F5
- control keycode 0x05 = F5
- alt keycode 0x05 = Console_5
- control alt keycode 0x05 = Console_5
-keycode 0x06 = F6
- control keycode 0x06 = F6
- alt keycode 0x06 = Console_6
- control alt keycode 0x06 = Console_6
-keycode 0x07 = F7
- control keycode 0x07 = F7
- alt keycode 0x07 = Console_7
- control alt keycode 0x07 = Console_7
-keycode 0x08 = F8
- control keycode 0x08 = F8
- alt keycode 0x08 = Console_8
- control alt keycode 0x08 = Console_8
-keycode 0x09 = F9
- control keycode 0x09 = F9
- alt keycode 0x09 = Console_9
- control alt keycode 0x09 = Console_9
-keycode 0x0a = F10
- control keycode 0x0a = F10
- alt keycode 0x0a = Console_10
- control alt keycode 0x0a = Console_10
-keycode 0x0b = F11
- control keycode 0x0b = F11
- alt keycode 0x0b = Console_11
- control alt keycode 0x0b = Console_11
-keycode 0x0c = F12
- control keycode 0x0c = F12
- alt keycode 0x0c = Console_12
- control alt keycode 0x0c = Console_12
-keycode 0x0d = F13
- control keycode 0x0d = F13
- alt keycode 0x0d = Console_13
- control alt keycode 0x0d = Console_13
-keycode 0x0e = F14
- control keycode 0x0e = F14
- alt keycode 0x0e = Console_14
- control alt keycode 0x0e = Console_14
-
-keycode 0x11 = F17
- control keycode 0x11 = F17
- alt keycode 0x11 = Console_17
- control alt keycode 0x11 = Console_17
-keycode 0x12 = F18
- control keycode 0x12 = F18
- alt keycode 0x12 = Console_18
- control alt keycode 0x12 = Console_18
-keycode 0x13 = F19
- control keycode 0x13 = F19
- alt keycode 0x13 = Console_19
- control alt keycode 0x13 = Console_19
-keycode 0x14 = F20
- control keycode 0x14 = F20
- alt keycode 0x14 = Console_20
- control alt keycode 0x14 = Console_20
-
-
-keycode 0x3b = KP_7
- alt keycode 0x3b = Ascii_7
- altgr keycode 0x3b = Hex_7
-keycode 0x3c = KP_8
- alt keycode 0x3c = Ascii_8
- altgr keycode 0x3c = Hex_8
-keycode 0x3d = KP_9
- alt keycode 0x3d = Ascii_9
- altgr keycode 0x3d = Hex_9
-keycode 0x3e = KP_Subtract
-keycode 0x4e = KP_4
- alt keycode 0x4e = Ascii_4
- altgr keycode 0x4e = Hex_4
-keycode 0x4f = KP_5
- alt keycode 0x4f = Ascii_5
- altgr keycode 0x4f = Hex_5
-keycode 0x50 = KP_6
- alt keycode 0x50 = Ascii_6
- altgr keycode 0x50 = Hex_6
-keycode 0x62 = KP_1
- alt keycode 0x62 = Ascii_1
- altgr keycode 0x62 = Hex_1
-keycode 0x63 = KP_2
- alt keycode 0x63 = Ascii_2
- altgr keycode 0x63 = Hex_2
-keycode 0x64 = KP_3
- alt keycode 0x64 = Ascii_3
- altgr keycode 0x64 = Hex_3
-keycode 0x6b = KP_0
- alt keycode 0x6b = Ascii_0
- altgr keycode 0x6b = Hex_0
-keycode 0x6c = KP_Period
-# altgr control keycode 0x6c = Boot
- control alt keycode 0x6c = Boot
-keycode 0x65 = KP_Enter
-
-keycode 0x3f = Control
-
-# keycode 100 = AltGr
-
-keycode 0x23 = Find
-keycode 0x4d = Up
-keycode 0x39 = Prior
- shift keycode 0x39 = Scroll_Backward
-keycode 0x5f = Left
- alt keycode 0x5f = Decr_Console
-keycode 0x61 = Right
- alt keycode 0x61 = Incr_Console
-keycode 0x38 = Select
-keycode 0x60 = Down
-keycode 0x3a = Next
- shift keycode 0x3a = Scroll_Forward
-keycode 0x24 = Insert
-keycode 0x25 = Remove
-# altgr control keycode 0x25 = Boot
- control alt keycode 0x25 = Boot
-
-keycode 0x0f = Help Show_Memory Show_Registers
- control keycode 0x0f = Show_State
-
-keycode 0x10 = Do
-
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
diff --git a/drivers/tc/lk201-remap.c b/drivers/tc/lk201-remap.c
deleted file mode 100644
index d39098c2720..00000000000
--- a/drivers/tc/lk201-remap.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Keyboard mappings for DEC LK201/401/501 keyboards
- *
- * 17.05.99 Michael Engel (engel@unix-ag.org)
- *
- * DEC US keyboards generate keycodes in the range 0x55 - 0xfb
- *
- * This conflicts with Linux scancode conventions which define
- * 0x00-0x7f as "normal" and 0x80-0xff as "shifted" scancodes, so we
- * have to remap the keycodes to 0x00-0x7f with the scancodeRemap
- * array. The generated scancode is simply the number of the key counted
- * from the left upper to the right lower corner of the keyboard ...
- *
- * These scancodes are then being remapped (I hope ;-)) with the
- * lk501*map[] arrays which define scancode -> Linux code mapping
- *
- * Oh man is this horrible ;-)
- *
- * Scancodes with dual labels exist for keyboards as follows:
- *
- * code: left label / right label
- *
- * 0x73: LKx01, LK421 / LK443, LK444
- * 0x74: LKx01, LK421 / LK443, LK444
- * 0x7c: LKx01, LK421 / LK443, LK444
- * 0x8a: LKx01, LK421 / LK443, LK444
- * 0x8b: LKx01, LK421 / LK443, LK444
- * 0x8c: LKx01, LK421 / LK443, LK444
- * 0x8d: LKx01, LK421 / LK443, LK444
- * 0x8e: LKx01, LK421 / LK443, LK444
- * 0x8f: LKx01, LK421 / LK443, LK444
- * 0x9c: LKx01, LK421 / LK443, LK444
- * 0xa1: LKx01, LK421 / LK443, LK444
- * 0xa2: LKx01, LK421 / LK443, LK444
- * 0xa3: LKx01, LK421 / LK443, LK444
- * 0xa4: LKx01, LK421 / LK443, LK444
- * 0xad: LK421 / LK443, LK444
- * 0xc9: LKx01, LK421, LK443 / LK444
- * 0xf7: LKx01, LK443 / LK444
- */
-
-unsigned char scancodeRemap[256] = {
-/* ----- */
-/* 0 */ 0, 0, 0, 0,
-/* ----- */
-/* 4 */ 0, 0, 0, 0,
-/* ----- */
-/* 8 */ 0, 0, 0, 0,
-/* ----- */
-/* c */ 0, 0, 0, 0,
-/* ----- */
-/* 10 */ 0, 0, 0, 0,
-/* ----- */
-/* 14 */ 0, 0, 0, 0,
-/* ----- */
-/* 18 */ 0, 0, 0, 0,
-/* ----- */
-/* 1c */ 0, 0, 0, 0,
-/* ----- */
-/* 20 */ 0, 0, 0, 0,
-/* ----- */
-/* 24 */ 0, 0, 0, 0,
-/* ----- */
-/* 28 */ 0, 0, 0, 0,
-/* ----- */
-/* 2c */ 0, 0, 0, 0,
-/* ----- */
-/* 30 */ 0, 0, 0, 0,
-/* ----- */
-/* 34 */ 0, 0, 0, 0,
-/* ----- */
-/* 38 */ 0, 0, 0, 0,
-/* ----- */
-/* 3c */ 0, 0, 0, 0,
-/* ----- */
-/* 40 */ 0, 0, 0, 0,
-/* ----- */
-/* 44 */ 0, 0, 0, 0,
-/* ----- */
-/* 48 */ 0, 0, 0, 0,
-/* ----- */
-/* 4c */ 0, 0, 0, 0,
-/* ----- */
-/* 50 */ 0, 0, 0, 0,
-/* ----- ESC F1 F2 */
-/* 54 */ 0, 0, 0x01, 0x02,
-/* ----- F3 F4 F5 */
-/* 58 */ 0x03, 0x04, 0x05, 0,
-/* ----- */
-/* 5c */ 0, 0, 0, 0,
-/* ----- */
-/* 60 */ 0, 0, 0, 0,
-/* ----- F6 F7 F8 F9 */
-/* 64 */ 0x06, 0x07, 0x08, 0x09,
-/* ----- F10 */
-/* 68 */ 0x0a, 0, 0, 0,
-/* ----- */
-/* 6c */ 0, 0, 0, 0,
-/* ----- F11 F12 F13/PRNT SCRN */
-/* 70 */ 0, 0x0b, 0x0c, 0x0d,
-/* ----- F14/SCRL LCK */
-/* 74 */ 0x0e, 0, 0, 0,
-/* ----- */
-/* 78 */ 0, 0, 0, 0,
-/* ----- HELP/PAUSE DO */
-/* 7c */ 0x0f, 0x10, 0, 0,
-/* ----- F17 F18 F19 F20 */
-/* 80 */ 0x11, 0x12, 0x13, 0x14,
-/* ----- */
-/* 84 */ 0, 0, 0, 0,
-/* ----- FIND/INSERT INSERT/HOME */
-/* 88 */ 0, 0, 0x23, 0x24,
-/* ----- REMOVE/PG UP SELECT/DELETE PREVIOUS/END NEXT/PG DN */
-/* 8c */ 0x25, 0x38, 0x39, 0x3a,
-/* ----- KP 0 */
-/* 90 */ 0, 0, 0x6b, 0,
-/* ----- KP . KP ENTER KP 1 KP 2 */
-/* 94 */ 0x6c, 0x65, 0x62, 0x63,
-/* ----- KP 3 KP 4 KP 5 KP 6 */
-/* 98 */ 0x64, 0x4e, 0x4f, 0x50,
-/* ----- KP ,/KP + KP 7 KP 8 KP 9 */
-/* 9c */ 0x51, 0x3b, 0x3c, 0x3d,
-/* ----- KP - KP F1/NUM LCK KP F2/KP / KP F3/KP * */
-/* a0 */ 0x3e, 0x26, 0x27, 0x28,
-/* ----- KP F4/KP - LEFT */
-/* a4 */ 0x29, 0, 0, 0x5f,
-/* ----- RIGHT DOWN UP SHIFT Rt */
-/* a8 */ 0x61, 0x60, 0x4d, 0x5e,
-/* ----- ALT COMP Rt/CTRL Rt SHIFT CONTROL */
-/* ac */ 0, 0, 0x52, 0x3f,
-/* ----- CAPS COMPOSE ALT Rt */
-/* b0 */ 0x40, 0x67, 0, 0,
-/* ----- */
-/* b4 */ 0, 0, 0, 0,
-/* ----- */
-/* b8 */ 0, 0, 0, 0,
-/* ----- BKSP RET TAB ` */
-/* bc */ 0x22, 0x37, 0x2a, 0x15,
-/* ----- 1 q a z */
-/* c0 */ 0x16, 0x2b, 0x41, 0x54,
-/* ----- 2 w s */
-/* c4 */ 0, 0x17, 0x2c, 0x42,
-/* ----- x </\\ 3 */
-/* c8 */ 0x55, 0x53, 0, 0x18,
-/* ----- e d c */
-/* cc */ 0x2d, 0x43, 0x56, 0,
-/* ----- 4 r f v */
-/* d0 */ 0x19, 0x2e, 0x44, 0x57,
-/* ----- SPACE 5 t */
-/* d4 */ 0x68, 0, 0x1a, 0x2f,
-/* ----- g b 6 */
-/* d8 */ 0x45, 0x58, 0, 0x1b,
-/* ----- y h n */
-/* dc */ 0x30, 0x46, 0x59, 0,
-/* ----- 7 u j m */
-/* e0 */ 0x1c, 0x31, 0x47, 0x5a,
-/* ----- 8 i k */
-/* e4 */ 0, 0x1d, 0x32, 0x48,
-/* ----- , 9 o */
-/* e8 */ 0x5b, 0, 0x1e, 0x33,
-/* ----- l . 0 */
-/* ec */ 0x49, 0x5c, 0, 0x1f,
-/* ----- p ; / */
-/* f0 */ 0x34, 0, 0x4a, 0x5d,
-/* ----- = ] \\/\' */
-/* f4 */ 0, 0x21, 0x36, 0x4c,
-/* ----- - [ \' */
-/* f8 */ 0, 0x20, 0x35, 0x4b,
-/* ----- */
-/* fc */ 0, 0, 0, 0,
-};
-
diff --git a/drivers/tc/lk201.c b/drivers/tc/lk201.c
deleted file mode 100644
index a90c255f079..00000000000
--- a/drivers/tc/lk201.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- *
- * 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) 1999-2002 Harald Koerfgen <hkoerfg@web.de>
- * Copyright (C) 2001, 2002, 2003, 2004 Maciej W. Rozycki
- */
-
-
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kbd_ll.h>
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-
-#include <asm/keyboard.h>
-#include <asm/dec/tc.h>
-#include <asm/dec/machtype.h>
-#include <asm/dec/serial.h>
-
-#include "lk201.h"
-
-/*
- * Only handle DECstations that have an LK201 interface.
- * Maxine uses LK501 at the Access.Bus and various DECsystems
- * have no keyboard interface at all.
- */
-#define LK_IFACE (mips_machtype == MACH_DS23100 || \
- mips_machtype == MACH_DS5000_200 || \
- mips_machtype == MACH_DS5000_1XX || \
- mips_machtype == MACH_DS5000_2X0)
-/*
- * These use the Z8530 SCC. Others use the DZ11.
- */
-#define LK_IFACE_ZS (mips_machtype == MACH_DS5000_1XX || \
- mips_machtype == MACH_DS5000_2X0)
-
-/* Simple translation table for the SysRq keys */
-
-#ifdef CONFIG_MAGIC_SYSRQ
-/*
- * Actually no translation at all, at least until we figure out
- * how to define SysRq for LK201 and friends. --macro
- */
-unsigned char lk201_sysrq_xlate[128];
-unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
-
-unsigned char kbd_sysrq_key = -1;
-#endif
-
-#define KEYB_LINE 3
-
-static int __init lk201_init(void *);
-static void __init lk201_info(void *);
-static void lk201_rx_char(unsigned char, unsigned char);
-
-static struct dec_serial_hook lk201_hook = {
- .init_channel = lk201_init,
- .init_info = lk201_info,
- .rx_char = NULL,
- .poll_rx_char = NULL,
- .poll_tx_char = NULL,
- .cflags = B4800 | CS8 | CSTOPB | CLOCAL,
-};
-
-/*
- * This is used during keyboard initialisation
- */
-static unsigned char lk201_reset_string[] = {
- LK_CMD_SET_DEFAULTS,
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 3),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 4),
- LK_CMD_MODE(LK_MODE_DOWN_UP, 5),
- LK_CMD_MODE(LK_MODE_DOWN_UP, 6),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 7),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 8),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 9),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 10),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 11),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
- LK_CMD_MODE(LK_MODE_DOWN, 13),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
- LK_CMD_DIS_KEYCLK,
- LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
-};
-
-static void *lk201_handle;
-
-static int lk201_send(unsigned char ch)
-{
- if (lk201_hook.poll_tx_char(lk201_handle, ch)) {
- printk(KERN_ERR "lk201: transmit timeout\n");
- return -EIO;
- }
- return 0;
-}
-
-static inline int lk201_get_id(void)
-{
- return lk201_send(LK_CMD_REQ_ID);
-}
-
-static int lk201_reset(void)
-{
- int i, r;
-
- for (i = 0; i < sizeof(lk201_reset_string); i++) {
- r = lk201_send(lk201_reset_string[i]);
- if (r < 0)
- return r;
- }
- return 0;
-}
-
-static void lk201_report(unsigned char id[6])
-{
- char *report = "lk201: keyboard attached, ";
-
- switch (id[2]) {
- case LK_STAT_PWRUP_OK:
- printk(KERN_INFO "%sself-test OK\n", report);
- break;
- case LK_STAT_PWRUP_KDOWN:
- /* The keyboard will resend the power-up ID
- after all keys are released, so we don't
- bother handling the error specially. Still
- there may be a short-circuit inside.
- */
- printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n",
- report, id[3]);
- break;
- case LK_STAT_PWRUP_ERROR:
- printk(KERN_ERR "%sself-test failure\n", report);
- break;
- default:
- printk(KERN_ERR "%sunknown error: 0x%02x\n",
- report, id[2]);
- }
-}
-
-static void lk201_id(unsigned char id[6])
-{
- /*
- * Report whether there is an LK201 or an LK401
- * The LK401 has ALT keys...
- */
- switch (id[4]) {
- case 1:
- printk(KERN_INFO "lk201: LK201 detected\n");
- break;
- case 2:
- printk(KERN_INFO "lk201: LK401 detected\n");
- break;
- case 3:
- printk(KERN_INFO "lk201: LK443 detected\n");
- break;
- case 4:
- printk(KERN_INFO "lk201: LK421 detected\n");
- break;
- default:
- printk(KERN_WARNING
- "lk201: unknown keyboard detected, ID %d\n", id[4]);
- printk(KERN_WARNING "lk201: ... please report to "
- "<linux-mips@linux-mips.org>\n");
- }
-}
-
-#define DEFAULT_KEYB_REP_DELAY (250/5) /* [5ms] */
-#define DEFAULT_KEYB_REP_RATE 30 /* [cps] */
-
-static struct kbd_repeat kbdrate = {
- DEFAULT_KEYB_REP_DELAY,
- DEFAULT_KEYB_REP_RATE
-};
-
-static void parse_kbd_rate(struct kbd_repeat *r)
-{
- if (r->delay <= 0)
- r->delay = kbdrate.delay;
- if (r->rate <= 0)
- r->rate = kbdrate.rate;
-
- if (r->delay < 5)
- r->delay = 5;
- if (r->delay > 630)
- r->delay = 630;
- if (r->rate < 12)
- r->rate = 12;
- if (r->rate > 127)
- r->rate = 127;
- if (r->rate == 125)
- r->rate = 124;
-}
-
-static int write_kbd_rate(struct kbd_repeat *rep)
-{
- int delay, rate;
- int i;
-
- delay = rep->delay / 5;
- rate = rep->rate;
- for (i = 0; i < 4; i++) {
- if (lk201_hook.poll_tx_char(lk201_handle,
- LK_CMD_RPT_RATE(i)))
- return 1;
- if (lk201_hook.poll_tx_char(lk201_handle,
- LK_PARAM_DELAY(delay)))
- return 1;
- if (lk201_hook.poll_tx_char(lk201_handle,
- LK_PARAM_RATE(rate)))
- return 1;
- }
- return 0;
-}
-
-static int lk201_kbd_rate(struct kbd_repeat *rep)
-{
- if (rep == NULL)
- return -EINVAL;
-
- parse_kbd_rate(rep);
-
- if (write_kbd_rate(rep)) {
- memcpy(rep, &kbdrate, sizeof(struct kbd_repeat));
- return -EIO;
- }
-
- memcpy(&kbdrate, rep, sizeof(struct kbd_repeat));
-
- return 0;
-}
-
-static void lk201_kd_mksound(unsigned int hz, unsigned int ticks)
-{
- if (!ticks)
- return;
-
- /*
- * Can't set frequency and we "approximate"
- * duration by volume. ;-)
- */
- ticks /= HZ / 32;
- if (ticks > 7)
- ticks = 7;
- ticks = 7 - ticks;
-
- if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_ENB_BELL))
- return;
- if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_VOLUME(ticks)))
- return;
- if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_BELL))
- return;
-}
-
-void kbd_leds(unsigned char leds)
-{
- unsigned char l = 0;
-
- if (!lk201_handle) /* FIXME */
- return;
-
- /* FIXME -- Only Hold and Lock LEDs for now. --macro */
- if (leds & LED_SCR)
- l |= LK_LED_HOLD;
- if (leds & LED_CAP)
- l |= LK_LED_LOCK;
-
- if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_ON))
- return;
- if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(l)))
- return;
- if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_OFF))
- return;
- if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(~l)))
- return;
-}
-
-int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
-{
- return -EINVAL;
-}
-
-int kbd_getkeycode(unsigned int scancode)
-{
- return -EINVAL;
-}
-
-int kbd_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode)
-{
- *keycode = scancode;
- return 1;
-}
-
-char kbd_unexpected_up(unsigned char keycode)
-{
- return 0x80;
-}
-
-static void lk201_rx_char(unsigned char ch, unsigned char fl)
-{
- static unsigned char id[6];
- static int id_i;
-
- static int shift_state = 0;
- static int prev_scancode;
- unsigned char c = scancodeRemap[ch];
-
- if (fl != TTY_NORMAL && fl != TTY_OVERRUN) {
- printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl);
- return;
- }
-
- /* Assume this is a power-up ID. */
- if (ch == LK_STAT_PWRUP_ID && !id_i) {
- id[id_i++] = ch;
- return;
- }
-
- /* Handle the power-up sequence. */
- if (id_i) {
- id[id_i++] = ch;
- if (id_i == 4) {
- /* OK, the power-up concluded. */
- lk201_report(id);
- if (id[2] == LK_STAT_PWRUP_OK)
- lk201_get_id();
- else {
- id_i = 0;
- printk(KERN_ERR "lk201: keyboard power-up "
- "error, skipping initialization\n");
- }
- } else if (id_i == 6) {
- /* We got the ID; report it and start operation. */
- id_i = 0;
- lk201_id(id);
- lk201_reset();
- }
- return;
- }
-
- /* Everything else is a scancode/status response. */
- id_i = 0;
- switch (ch) {
- case LK_STAT_RESUME_ERR:
- case LK_STAT_ERROR:
- case LK_STAT_INHIBIT_ACK:
- case LK_STAT_TEST_ACK:
- case LK_STAT_MODE_KEYDOWN:
- case LK_STAT_MODE_ACK:
- break;
- case LK_KEY_LOCK:
- shift_state ^= LK_LOCK;
- handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0);
- break;
- case LK_KEY_SHIFT:
- shift_state ^= LK_SHIFT;
- handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0);
- break;
- case LK_KEY_CTRL:
- shift_state ^= LK_CTRL;
- handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0);
- break;
- case LK_KEY_COMP:
- shift_state ^= LK_COMP;
- handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0);
- break;
- case LK_KEY_RELEASE:
- if (shift_state & LK_SHIFT)
- handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
- if (shift_state & LK_CTRL)
- handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
- if (shift_state & LK_COMP)
- handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
- if (shift_state & LK_LOCK)
- handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
- shift_state = 0;
- break;
- case LK_KEY_REPEAT:
- handle_scancode(prev_scancode, 1);
- break;
- default:
- prev_scancode = c;
- handle_scancode(c, 1);
- break;
- }
- tasklet_schedule(&keyboard_tasklet);
-}
-
-static void __init lk201_info(void *handle)
-{
-}
-
-static int __init lk201_init(void *handle)
-{
- /* First install handlers. */
- lk201_handle = handle;
- kbd_rate = lk201_kbd_rate;
- kd_mksound = lk201_kd_mksound;
-
- lk201_hook.rx_char = lk201_rx_char;
-
- /* Then just issue a reset -- the handlers will do the rest. */
- lk201_send(LK_CMD_POWER_UP);
-
- return 0;
-}
-
-void __init kbd_init_hw(void)
-{
- /* Maxine uses LK501 at the Access.Bus. */
- if (!LK_IFACE)
- return;
-
- printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n");
-
- if (LK_IFACE_ZS) {
- /*
- * kbd_init_hw() is being called before
- * rs_init() so just register the kbd hook
- * and let zs_init do the rest :-)
- */
- if (!register_dec_serial_hook(KEYB_LINE, &lk201_hook))
- unregister_dec_serial_hook(KEYB_LINE);
- } else {
- /*
- * TODO: modify dz.c to allow similar hooks
- * for LK201 handling on DS2100, DS3100, and DS5000/200
- */
- printk(KERN_ERR "lk201: support for DZ11 not yet ready.\n");
- }
-}
diff --git a/drivers/tc/lk201.h b/drivers/tc/lk201.h
deleted file mode 100644
index 99f3203c41b..00000000000
--- a/drivers/tc/lk201.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Commands to the keyboard processor
- */
-
-#define LK_PARAM 0x80 /* start/end parameter list */
-
-#define LK_CMD_RESUME 0x8b /* resume transmission to the host */
-#define LK_CMD_INHIBIT 0x89 /* stop transmission to the host */
-#define LK_CMD_LEDS_ON 0x13 /* light LEDs */
- /* 1st param: led bitmask */
-#define LK_CMD_LEDS_OFF 0x11 /* turn off LEDs */
- /* 1st param: led bitmask */
-#define LK_CMD_DIS_KEYCLK 0x99 /* disable the keyclick */
-#define LK_CMD_ENB_KEYCLK 0x1b /* enable the keyclick */
- /* 1st param: volume */
-#define LK_CMD_DIS_CTLCLK 0xb9 /* disable the Ctrl keyclick */
-#define LK_CMD_ENB_CTLCLK 0xbb /* enable the Ctrl keyclick */
-#define LK_CMD_SOUND_CLK 0x9f /* emit a keyclick */
-#define LK_CMD_DIS_BELL 0xa1 /* disable the bell */
-#define LK_CMD_ENB_BELL 0x23 /* enable the bell */
- /* 1st param: volume */
-#define LK_CMD_BELL 0xa7 /* emit a bell */
-#define LK_CMD_TMP_NORPT 0xd1 /* disable typematic */
- /* for the currently pressed key */
-#define LK_CMD_ENB_RPT 0xe3 /* enable typematic */
- /* for RPT_DOWN groups */
-#define LK_CMD_DIS_RPT 0xe1 /* disable typematic */
- /* for RPT_DOWN groups */
-#define LK_CMD_RPT_TO_DOWN 0xd9 /* set RPT_DOWN groups to DOWN */
-#define LK_CMD_REQ_ID 0xab /* request the keyboard ID */
-#define LK_CMD_POWER_UP 0xfd /* init power-up sequence */
-#define LK_CMD_TEST_MODE 0xcb /* enter the factory test mode */
-#define LK_CMD_TEST_EXIT 0x80 /* exit the factory test mode */
-#define LK_CMD_SET_DEFAULTS 0xd3 /* set power-up defaults */
-
-#define LK_CMD_MODE(m,div) (LK_PARAM|(((div)&0xf)<<3)|(((m)&0x3)<<1))
- /* select the repeat mode */
- /* for the selected key group */
-#define LK_CMD_MODE_AR(m,div) ((((div)&0xf)<<3)|(((m)&0x3)<<1))
- /* select the repeat mode */
- /* and the repeat register */
- /* for the selected key group */
- /* 1st param: register number */
-#define LK_CMD_RPT_RATE(r) (0x78|(((r)&0x3)<<1))
- /* set the delay and repeat rate */
- /* for the selected repeat register */
- /* 1st param: initial delay */
- /* 2nd param: repeat rate */
-
-/* there are 4 leds, represent them in the low 4 bits of a byte */
-#define LK_PARAM_LED_MASK(ledbmap) (LK_PARAM|((ledbmap)&0xf))
-#define LK_LED_WAIT 0x1 /* Wait LED */
-#define LK_LED_COMP 0x2 /* Compose LED */
-#define LK_LED_LOCK 0x4 /* Lock LED */
-#define LK_LED_HOLD 0x8 /* Hold Screen LED */
-
-/* max volume is 0, lowest is 0x7 */
-#define LK_PARAM_VOLUME(v) (LK_PARAM|((v)&0x7))
-
-/* mode set command details, div is a key group number */
-#define LK_MODE_DOWN 0x0 /* make only */
-#define LK_MODE_RPT_DOWN 0x1 /* make and typematic */
-#define LK_MODE_DOWN_UP 0x3 /* make and release */
-
-/* there are 4 repeat registers */
-#define LK_PARAM_AR(r) (LK_PARAM|((v)&0x3))
-
-/*
- * Mappings between key groups and keycodes are as follows:
- *
- * 1: 0xbf - 0xff -- alphanumeric,
- * 2: 0x91 - 0xa5 -- numeric keypad,
- * 3: 0xbc -- Backspace,
- * 4: 0xbd - 0xbe -- Tab, Return,
- * 5: 0xb0 - 0xb2 -- Lock, Compose Character,
- * 6: 0xad - 0xaf -- Ctrl, Shift,
- * 7: 0xa6 - 0xa8 -- Left Arrow, Right Arrow,
- * 8: 0xa9 - 0xac -- Up Arrow, Down Arrow, Right Shift,
- * 9: 0x88 - 0x90 -- editor keypad,
- * 10: 0x56 - 0x62 -- F1 - F5,
- * 11: 0x63 - 0x6e -- F6 - F10,
- * 12: 0x6f - 0x7a -- F11 - F14,
- * 13: 0x7b - 0x7d -- Help, Do,
- * 14: 0x7e - 0x87 -- F17 - F20.
- *
- * Notes:
- * 1. Codes in the 0x00 - 0x40 range are reserved.
- * 2. The assignment of the 0x41 - 0x55 range is undiscovered, probably 10.
- */
-
-/* delay is 5 - 630 ms; 0x00 and 0x7f are reserved */
-#define LK_PARAM_DELAY(t) ((t)&0x7f)
-
-/* rate is 12 - 127 Hz; 0x00 - 0x0b and 0x7d (power-up!) are reserved */
-#define LK_PARAM_RATE(r) (LK_PARAM|((r)&0x7f))
-
-#define LK_SHIFT 1<<0
-#define LK_CTRL 1<<1
-#define LK_LOCK 1<<2
-#define LK_COMP 1<<3
-
-#define LK_KEY_SHIFT 0xae
-#define LK_KEY_CTRL 0xaf
-#define LK_KEY_LOCK 0xb0
-#define LK_KEY_COMP 0xb1
-
-#define LK_KEY_RELEASE 0xb3 /* all keys released */
-#define LK_KEY_REPEAT 0xb4 /* repeat the last key */
-
-/* status responses */
-#define LK_STAT_RESUME_ERR 0xb5 /* keystrokes lost while inhibited */
-#define LK_STAT_ERROR 0xb6 /* an invalid command received */
-#define LK_STAT_INHIBIT_ACK 0xb7 /* transmission inhibited */
-#define LK_STAT_TEST_ACK 0xb8 /* the factory test mode entered */
-#define LK_STAT_MODE_KEYDOWN 0xb9 /* a key is down on a change */
- /* to the DOWN_UP mode; */
- /* the keycode follows */
-#define LK_STAT_MODE_ACK 0xba /* the mode command succeeded */
-
-#define LK_STAT_PWRUP_ID 0x01 /* the power-up response start mark */
-#define LK_STAT_PWRUP_OK 0x00 /* the power-up self test OK */
-#define LK_STAT_PWRUP_KDOWN 0x3d /* a key was down during the test */
-#define LK_STAT_PWRUP_ERROR 0x3e /* keyboard self test failure */
-
-extern unsigned char scancodeRemap[256];
diff --git a/drivers/telephony/Kconfig b/drivers/telephony/Kconfig
index 5f98f673f1b..b5f78b6ed2b 100644
--- a/drivers/telephony/Kconfig
+++ b/drivers/telephony/Kconfig
@@ -19,7 +19,7 @@ if PHONE
config PHONE_IXJ
tristate "QuickNet Internet LineJack/PhoneJack support"
- depends ISA || PCI
+ depends on ISA || PCI
---help---
Say M if you have a telephony card manufactured by Quicknet
Technologies, Inc. These include the Internet PhoneJACK and
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index f51e22490ed..912d97aaf9b 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -332,7 +332,7 @@ static void acm_read_bulk(struct urb *urb)
return;
if (status)
- dev_dbg(&acm->data->dev, "bulk rx status %d", status);
+ dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
buf = rcv->buffer;
buf->size = urb->actual_length;
@@ -831,13 +831,13 @@ static int acm_probe (struct usb_interface *intf,
/* normal probing*/
if (!buffer) {
- err("Wierd descriptor references\n");
+ err("Weird descriptor references\n");
return -EINVAL;
}
if (!buflen) {
if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
- dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
+ dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
buflen = intf->cur_altsetting->endpoint->extralen;
buffer = intf->cur_altsetting->endpoint->extra;
} else {
@@ -887,24 +887,24 @@ next_desc:
if (!union_header) {
if (call_interface_num > 0) {
- dev_dbg(&intf->dev,"No union descriptor, using call management descriptor");
+ dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
control_interface = intf;
} else {
- dev_dbg(&intf->dev,"No union descriptor, giving up");
+ dev_dbg(&intf->dev,"No union descriptor, giving up\n");
return -ENODEV;
}
} else {
control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
if (!control_interface || !data_interface) {
- dev_dbg(&intf->dev,"no interfaces");
+ dev_dbg(&intf->dev,"no interfaces\n");
return -ENODEV;
}
}
if (data_interface_num != call_interface_num)
- dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
+ dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
skip_normal_probe:
@@ -912,7 +912,7 @@ skip_normal_probe:
if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
struct usb_interface *t;
- dev_dbg(&intf->dev,"Your device has switched interfaces.");
+ dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
t = control_interface;
control_interface = data_interface;
@@ -927,7 +927,7 @@ skip_normal_probe:
return -ENODEV;
if (usb_interface_claimed(data_interface)) { /* valid in this context */
- dev_dbg(&intf->dev,"The data interface isn't available");
+ dev_dbg(&intf->dev,"The data interface isn't available\n");
return -EBUSY;
}
@@ -944,7 +944,7 @@ skip_normal_probe:
if (!usb_endpoint_dir_in(epread)) {
/* descriptors are swapped */
struct usb_endpoint_descriptor *t;
- dev_dbg(&intf->dev,"The data interface has switched endpoints");
+ dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
t = epread;
epread = epwrite;
@@ -959,7 +959,7 @@ skip_normal_probe:
}
if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
- dev_dbg(&intf->dev, "out of memory (acm kzalloc)");
+ dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
goto alloc_fail;
}
@@ -985,26 +985,26 @@ skip_normal_probe:
buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
- dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)");
+ dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
goto alloc_fail2;
}
acm->ctrl_buffer = buf;
if (acm_write_buffers_alloc(acm) < 0) {
- dev_dbg(&intf->dev, "out of memory (write buffer alloc)");
+ dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
goto alloc_fail4;
}
acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->ctrlurb) {
- dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)");
+ dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
goto alloc_fail5;
}
for (i = 0; i < num_rx_buf; i++) {
struct acm_ru *rcv = &(acm->ru[i]);
if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
- dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)");
+ dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
goto alloc_fail7;
}
@@ -1015,13 +1015,13 @@ skip_normal_probe:
struct acm_rb *buf = &(acm->rb[i]);
if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
- dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)");
+ dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
goto alloc_fail7;
}
}
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->writeurb) {
- dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)");
+ dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
goto alloc_fail7;
}
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 7dc123d6b2d..99e5a68a3f1 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -291,7 +291,7 @@ int usb_create_ep_files(struct device *parent,
retval = endpoint_get_minor(ep_dev);
if (retval) {
- dev_err(parent, "can not allocate minor number for %s",
+ dev_err(parent, "can not allocate minor number for %s\n",
ep_dev->dev.bus_id);
goto error_register;
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d20cb545a6e..036c3dea855 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1407,7 +1407,11 @@ fail:
/**
- * Similar to usb_disconnect()
+ * usb_deauthorize_device - deauthorize a device (usbcore-internal)
+ * @usb_dev: USB device
+ *
+ * Move the USB device to a very basic state where interfaces are disabled
+ * and the device is in fact unconfigured and unusable.
*
* We share a lock (that we have) with device_del(), so we need to
* defer its call.
@@ -2866,10 +2870,9 @@ static int hub_thread(void *__unused)
set_freezable();
do {
hub_events();
- wait_event_interruptible(khubd_wait,
+ wait_event_freezable(khubd_wait,
!list_empty(&hub_event_list) ||
kthread_should_stop());
- try_to_freeze();
} while (!kthread_should_stop() || !list_empty(&hub_event_list));
pr_debug("%s: khubd exiting\n", usbcore_name);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index c021af39037..8dd5a6afd51 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1526,7 +1526,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
GFP_KERNEL);
if (!new_interfaces) {
- dev_err(&dev->dev, "Out of memory");
+ dev_err(&dev->dev, "Out of memory\n");
return -ENOMEM;
}
@@ -1535,7 +1535,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
sizeof(struct usb_interface),
GFP_KERNEL);
if (!new_interfaces[n]) {
- dev_err(&dev->dev, "Out of memory");
+ dev_err(&dev->dev, "Out of memory\n");
ret = -ENOMEM;
free_interfaces:
while (--n >= 0)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index c99938d5f78..69aa68287d3 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -982,7 +982,6 @@ EXPORT_SYMBOL(usb_altnum_to_altsetting);
EXPORT_SYMBOL(__usb_get_extra_descriptor);
-EXPORT_SYMBOL(usb_find_device);
EXPORT_SYMBOL(usb_get_current_frame_number);
EXPORT_SYMBOL(usb_buffer_alloc);
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 3e715082de3..3173b39f0bf 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -43,6 +43,8 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <asm/byteorder.h>
#include <asm/dma.h>
@@ -1157,7 +1159,7 @@ static void udc_disable(struct pxa2xx_udc *dev)
#ifdef CONFIG_ARCH_PXA
/* Disable clock for USB device */
- pxa_set_cken(CKEN_USB, 0);
+ clk_disable(dev->clk);
#endif
ep0_idle (dev);
@@ -1202,8 +1204,7 @@ static void udc_enable (struct pxa2xx_udc *dev)
#ifdef CONFIG_ARCH_PXA
/* Enable clock for USB device */
- pxa_set_cken(CKEN_USB, 1);
- udelay(5);
+ clk_enable(dev->clk);
#endif
/* try to clear these bits before we enable the udc */
@@ -2137,6 +2138,14 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
if (irq < 0)
return -ENODEV;
+#ifdef CONFIG_ARCH_PXA
+ dev->clk = clk_get(&pdev->dev, "UDCCLK");
+ if (IS_ERR(dev->clk)) {
+ retval = PTR_ERR(dev->clk);
+ goto err_clk;
+ }
+#endif
+
pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
dev->has_cfr ? "" : " (!cfr)",
SIZE_STR "(pio)"
@@ -2152,11 +2161,10 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev,
"can't get vbus gpio %d, err: %d\n",
dev->mach->gpio_vbus, retval);
- return -EBUSY;
+ goto err_gpio_vbus;
}
gpio_direction_input(dev->mach->gpio_vbus);
vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
- set_irq_type(vbus_irq, IRQT_BOTHEDGE);
} else
vbus_irq = 0;
@@ -2166,9 +2174,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev,
"can't get pullup gpio %d, err: %d\n",
dev->mach->gpio_pullup, retval);
- if (dev->mach->gpio_vbus)
- gpio_free(dev->mach->gpio_vbus);
- return -EBUSY;
+ goto err_gpio_pullup;
}
gpio_direction_output(dev->mach->gpio_pullup, 0);
}
@@ -2195,11 +2201,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
if (retval != 0) {
printk(KERN_ERR "%s: can't get irq %d, err %d\n",
driver_name, irq, retval);
- if (dev->mach->gpio_pullup)
- gpio_free(dev->mach->gpio_pullup);
- if (dev->mach->gpio_vbus)
- gpio_free(dev->mach->gpio_vbus);
- return -EBUSY;
+ goto err_irq1;
}
dev->got_irq = 1;
@@ -2213,12 +2215,7 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
printk(KERN_ERR "%s: can't get irq %i, err %d\n",
driver_name, LUBBOCK_USB_DISC_IRQ, retval);
lubbock_fail0:
- free_irq(irq, dev);
- if (dev->mach->gpio_pullup)
- gpio_free(dev->mach->gpio_pullup);
- if (dev->mach->gpio_vbus)
- gpio_free(dev->mach->gpio_vbus);
- return -EBUSY;
+ goto err_irq_lub;
}
retval = request_irq(LUBBOCK_USB_IRQ,
lubbock_vbus_irq,
@@ -2234,22 +2231,37 @@ lubbock_fail0:
#endif
if (vbus_irq) {
retval = request_irq(vbus_irq, udc_vbus_irq,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
driver_name, dev);
if (retval != 0) {
printk(KERN_ERR "%s: can't get irq %i, err %d\n",
driver_name, vbus_irq, retval);
- free_irq(irq, dev);
- if (dev->mach->gpio_pullup)
- gpio_free(dev->mach->gpio_pullup);
- if (dev->mach->gpio_vbus)
- gpio_free(dev->mach->gpio_vbus);
- return -EBUSY;
+ goto err_vbus_irq;
}
}
create_proc_files();
return 0;
+
+ err_vbus_irq:
+#ifdef CONFIG_ARCH_LUBBOCK
+ free_irq(LUBBOCK_USB_DISC_IRQ, dev);
+ err_irq_lub:
+#endif
+ free_irq(irq, dev);
+ err_irq1:
+ if (dev->mach->gpio_pullup)
+ gpio_free(dev->mach->gpio_pullup);
+ err_gpio_pullup:
+ if (dev->mach->gpio_vbus)
+ gpio_free(dev->mach->gpio_vbus);
+ err_gpio_vbus:
+#ifdef CONFIG_ARCH_PXA
+ clk_put(dev->clk);
+ err_clk:
+#endif
+ return retval;
}
static void pxa2xx_udc_shutdown(struct platform_device *_dev)
@@ -2284,6 +2296,10 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
if (dev->mach->gpio_pullup)
gpio_free(dev->mach->gpio_pullup);
+#ifdef CONFIG_ARCH_PXA
+ clk_put(dev->clk);
+#endif
+
platform_set_drvdata(pdev, NULL);
the_controller = NULL;
return 0;
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index 0e5d0e6fb0e..1db46d70577 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -125,6 +125,7 @@ struct pxa2xx_udc {
struct timer_list timer;
struct device *dev;
+ struct clk *clk;
struct pxa2xx_udc_mach_info *mach;
u64 dma_mask;
struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS];
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 6829814b7aa..44b79e8a6e2 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -358,7 +358,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- dev_err(&dev->dev, "request_mem_region failed");
+ dev_err(&dev->dev, "request_mem_region failed\n");
retval = -EBUSY;
goto err_put;
}
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 5131cbfb2f5..c567aa7a41e 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -805,7 +805,7 @@ static int adu_probe(struct usb_interface *interface,
dev->minor = interface->minor;
/* let the user know what node this device is now attached to */
- dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d",
+ dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n",
udev->descriptor.idProduct, dev->serial_number,
(dev->minor - ADU_MINOR_BASE));
exit:
@@ -851,7 +851,7 @@ static void adu_disconnect(struct usb_interface *interface)
mutex_unlock(&dev->mtx);
}
- dev_info(&interface->dev, "ADU device adutux%d now disconnected",
+ dev_info(&interface->dev, "ADU device adutux%d now disconnected\n",
(minor - ADU_MINOR_BASE));
dbg(2," %s : leave", __FUNCTION__);
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 46d9f27ec17..d372fbc4eff 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -216,7 +216,7 @@ static void iowarrior_callback(struct urb *urb)
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
+ dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n",
__FUNCTION__, retval);
}
@@ -451,7 +451,7 @@ static ssize_t iowarrior_write(struct file *file,
break;
default:
/* what do we have here ? An unsupported Product-ID ? */
- dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
+ dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n",
__FUNCTION__, dev->product_id);
retval = -EFAULT;
goto exit;
@@ -526,7 +526,7 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file,
} else {
retval = -EINVAL;
dev_err(&dev->interface->dev,
- "ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+ "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n",
dev->product_id);
}
break;
@@ -752,7 +752,7 @@ static int iowarrior_probe(struct usb_interface *interface,
/* allocate memory for our device state and intialize it */
dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
if (dev == NULL) {
- dev_err(&interface->dev, "Out of memory");
+ dev_err(&interface->dev, "Out of memory\n");
return retval;
}
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
index df0ebcdb9d6..2ad09b1f484 100644
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ b/drivers/usb/misc/phidgetmotorcontrol.c
@@ -155,7 +155,7 @@ resubmit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
dev_err(&mc->intf->dev,
- "can't resubmit intr, %s-%s/motorcontrol0, retval %d",
+ "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n",
mc->udev->bus->bus_name,
mc->udev->devpath, retval);
}
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 43722e5a49d..b624320df90 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -1042,7 +1042,8 @@ sisusbcon_set_origin(struct vc_data *c)
/* Interface routine */
static int
-sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows)
+sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows,
+ unsigned int user)
{
struct sisusb_usb_data *sisusb;
int fh;
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index ebb04ac4857..5e3e4e9b6c7 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -87,7 +87,7 @@ struct mon_reader_text {
static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */
-static void mon_text_ctor(void *, struct kmem_cache *, unsigned long);
+static void mon_text_ctor(struct kmem_cache *, void *);
struct mon_text_ptr {
int cnt, limit;
@@ -720,7 +720,7 @@ void mon_text_del(struct mon_bus *mbus)
/*
* Slab interface: constructor.
*/
-static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sflags)
+static void mon_text_ctor(struct kmem_cache *slab, void *mem)
{
/*
* Nothing to initialize. No, really!
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index e4c248c98e8..65257867b34 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1071,7 +1071,7 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
(char*) &latency, 1, WDR_TIMEOUT);
if (rv < 0) {
- dev_err(dev, "Unable to read latency timer: %i", rv);
+ dev_err(dev, "Unable to read latency timer: %i\n", rv);
return -EIO;
}
return sprintf(buf, "%i\n", latency);
@@ -1098,7 +1098,7 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute *
buf, 0, WDR_TIMEOUT);
if (rv < 0) {
- dev_err(dev, "Unable to write latency timer: %i", rv);
+ dev_err(dev, "Unable to write latency timer: %i\n", rv);
return -EIO;
}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 2ecb1d2a034..8dd3abc99d6 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2882,7 +2882,7 @@ static int edge_startup (struct usb_serial *serial)
(edge_serial->product_info.NumPorts != serial->num_ports)) {
dev_warn(&serial->dev->dev, "Device Reported %d serial ports "
"vs. core thinking we have %d ports, email "
- "greg@kroah.com this information.",
+ "greg@kroah.com this information.\n",
edge_serial->product_info.NumPorts,
serial->num_ports);
}
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 1b94daa6158..cbe5530f3db 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -227,7 +227,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
0,
100000);
if (result < 0)
- dev_err(&port->dev, "Init of modem failed (error = %d)", result);
+ dev_err(&port->dev, "Init of modem failed (error = %d)\n", result);
/* reset the bulk pipes */
usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress));
@@ -255,7 +255,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
0,
100000);
if (result < 0)
- dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)", result);
+ dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result);
/*--4: setup the initial flowcontrol */
dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init);
@@ -268,7 +268,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
0x10,
200000);
if (result < 0)
- dev_err(&port->dev, "initial flowcontrol failed (error = %d)", result);
+ dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result);
/*--5: raise the dtr */
@@ -282,7 +282,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
0,
200000);
if (result < 0)
- dev_err(&port->dev, "setting dtr failed (error = %d)", result);
+ dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
/*--6: raise the rts */
dbg("%s:raising rts",__FUNCTION__);
@@ -295,7 +295,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp)
0,
200000);
if (result < 0)
- dev_err(&port->dev, "setting dtr failed (error = %d)", result);
+ dev_err(&port->dev, "setting dtr failed (error = %d)\n", result);
kfree(buf_flow_init);
return 0;
@@ -322,7 +322,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
0,
200000);
if (result < 0)
- dev_err(&port->dev, "dropping dtr failed (error = %d)", result);
+ dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result);
/*--2: drop the rts */
dbg("%s:dropping rts",__FUNCTION__);
@@ -334,7 +334,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
0,
200000);
if (result < 0)
- dev_err(&port->dev, "dropping rts failed (error = %d)", result);
+ dev_err(&port->dev, "dropping rts failed (error = %d)\n", result);
/*--3: purge */
@@ -347,7 +347,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
0,
200000);
if (result < 0)
- dev_err(&port->dev, "purge failed (error = %d)", result);
+ dev_err(&port->dev, "purge failed (error = %d)\n", result);
/* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */
@@ -361,7 +361,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp)
100000);
if (result < 0)
- dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)", result);
+ dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result);
/* shutdown any in-flight urbs that we know about */
usb_kill_urb(port->read_urb);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 01e811becec..e02c198016b 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -478,7 +478,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL);
if (response)
dev_err(&port->dev,
- "%s - Error %d submitting control urb",
+ "%s - Error %d submitting control urb\n",
__FUNCTION__, response);
}
@@ -492,7 +492,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp)
response = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (response)
dev_err(&port->dev,
- "%s - Error %d submitting read urb", __FUNCTION__, response);
+ "%s - Error %d submitting read urb\n", __FUNCTION__, response);
/* initialize our icount structure */
memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount));
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index d19861166b5..eea226ae37b 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -256,7 +256,7 @@ static void setup_line(struct work_struct *work)
100);
if (result != OTI6858_CTRL_PKT_SIZE) {
- dev_err(&port->dev, "%s(): error reading status", __FUNCTION__);
+ dev_err(&port->dev, "%s(): error reading status\n", __FUNCTION__);
kfree(new_setup);
/* we will try again */
schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2));
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 0bb8de4cc52..959b3e4e907 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -48,7 +48,7 @@ enum devicetype {
static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
{
int result;
- dev_dbg(&udev->dev, "%s", "SET POWER STATE");
+ dev_dbg(&udev->dev, "%s", "SET POWER STATE\n");
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
0x00, /* __u8 request */
0x40, /* __u8 request type */
@@ -63,7 +63,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState)
static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode)
{
int result;
- dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH");
+ dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n");
result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
SWIMS_USB_REQUEST_SetMode, /* __u8 request */
SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */
@@ -397,7 +397,7 @@ static void sierra_indat_callback(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
dev_err(&port->dev, "resubmit read urb failed."
- "(%d)", err);
+ "(%d)\n", err);
}
}
return;
@@ -525,7 +525,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
result = usb_submit_urb(urb, GFP_KERNEL);
if (result) {
- dev_err(&port->dev, "submit urb %d failed (%d) %d",
+ dev_err(&port->dev, "submit urb %d failed (%d) %d\n",
i, result, urb->transfer_buffer_length);
}
}
@@ -538,7 +538,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp)
if (port->interrupt_in_urb) {
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result)
- dev_err(&port->dev, "submit irq_in urb failed %d",
+ dev_err(&port->dev, "submit irq_in urb failed %d\n",
result);
}
return 0;
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 4d3cbb12b71..8d3711a7ff0 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -798,12 +798,13 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
{
unsigned char *buffer;
u16 lba, max_lba;
- unsigned int page, len, index, offset;
+ unsigned int page, len, offset;
unsigned int blockshift = MEDIA_INFO(us).blockshift;
unsigned int pageshift = MEDIA_INFO(us).pageshift;
unsigned int blocksize = MEDIA_INFO(us).blocksize;
unsigned int pagesize = MEDIA_INFO(us).pagesize;
unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+ struct scatterlist *sg;
int result;
/*
@@ -827,7 +828,8 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);
result = USB_STOR_TRANSPORT_GOOD;
- index = offset = 0;
+ offset = 0;
+ sg = NULL;
while (sectors > 0) {
unsigned int zone = lba / uzonesize; /* integer division */
@@ -873,7 +875,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
/* Store the data in the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &index, &offset, TO_XFER_BUF);
+ &sg, &offset, TO_XFER_BUF);
page = 0;
lba++;
@@ -891,11 +893,12 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
unsigned int sectors)
{
unsigned char *buffer, *blockbuffer;
- unsigned int page, len, index, offset;
+ unsigned int page, len, offset;
unsigned int blockshift = MEDIA_INFO(us).blockshift;
unsigned int pageshift = MEDIA_INFO(us).pageshift;
unsigned int blocksize = MEDIA_INFO(us).blocksize;
unsigned int pagesize = MEDIA_INFO(us).pagesize;
+ struct scatterlist *sg;
u16 lba, max_lba;
int result;
@@ -929,7 +932,8 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);
result = USB_STOR_TRANSPORT_GOOD;
- index = offset = 0;
+ offset = 0;
+ sg = NULL;
while (sectors > 0) {
/* Write as many sectors as possible in this block */
@@ -946,7 +950,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
/* Get the data from the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &index, &offset, FROM_XFER_BUF);
+ &sg, &offset, FROM_XFER_BUF);
result = alauda_write_lba(us, lba, page, pages, buffer,
blockbuffer);
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index c87ad1bae1d..579e9f52053 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -98,7 +98,8 @@ static int datafab_read_data(struct us_data *us,
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_idx = 0, sg_offset = 0;
+ unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Datafab
@@ -155,7 +156,7 @@ static int datafab_read_data(struct us_data *us,
// Store the data in the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg_idx, &sg_offset, TO_XFER_BUF);
+ &sg, &sg_offset, TO_XFER_BUF);
sector += thistime;
totallen -= len;
@@ -181,7 +182,8 @@ static int datafab_write_data(struct us_data *us,
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_idx = 0, sg_offset = 0;
+ unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Datafab
@@ -217,7 +219,7 @@ static int datafab_write_data(struct us_data *us,
// Get the data from the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg_idx, &sg_offset, FROM_XFER_BUF);
+ &sg, &sg_offset, FROM_XFER_BUF);
command[0] = 0;
command[1] = thistime;
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index 003fcf54588..61097cbb158 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -119,7 +119,8 @@ static int jumpshot_read_data(struct us_data *us,
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_idx = 0, sg_offset = 0;
+ unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Jumpshot
@@ -170,7 +171,7 @@ static int jumpshot_read_data(struct us_data *us,
// Store the data in the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg_idx, &sg_offset, TO_XFER_BUF);
+ &sg, &sg_offset, TO_XFER_BUF);
sector += thistime;
totallen -= len;
@@ -195,7 +196,8 @@ static int jumpshot_write_data(struct us_data *us,
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result, waitcount;
- unsigned int sg_idx = 0, sg_offset = 0;
+ unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
// we're working in LBA mode. according to the ATA spec,
// we can support up to 28-bit addressing. I don't know if Jumpshot
@@ -225,7 +227,7 @@ static int jumpshot_write_data(struct us_data *us,
// Get the data from the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg_idx, &sg_offset, FROM_XFER_BUF);
+ &sg, &sg_offset, FROM_XFER_BUF);
command[0] = 0;
command[1] = thistime;
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
index 06d1107dbd4..55b952084f0 100644
--- a/drivers/usb/storage/libusual.c
+++ b/drivers/usb/storage/libusual.c
@@ -30,7 +30,7 @@ static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS);
#define BIAS_NAME_SIZE (sizeof("usb-storage"))
static const char *bias_names[3] = { "none", "usb-storage", "ub" };
-static DECLARE_MUTEX_LOCKED(usu_init_notify);
+static struct semaphore usu_init_notify;
static DECLARE_COMPLETION(usu_end_notify);
static atomic_t total_threads = ATOMIC_INIT(0);
@@ -204,6 +204,8 @@ static int __init usb_usual_init(void)
{
int rc;
+ sema_init(&usu_init_notify, 0);
+
rc = usb_register(&usu_driver);
up(&usu_init_notify);
return rc;
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 9ad30428d2d..cc8f7c52c72 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -157,7 +157,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
* pick up from where this one left off. */
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
+ unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
unsigned int *offset, enum xfer_buf_dir dir)
{
unsigned int cnt;
@@ -184,16 +184,17 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* located in high memory -- then kmap() will map it to a temporary
* position in the kernel's virtual address space. */
} else {
- struct scatterlist *sg =
- (struct scatterlist *) srb->request_buffer
- + *index;
+ struct scatterlist *sg = *sgptr;
+
+ if (!sg)
+ sg = (struct scatterlist *) srb->request_buffer;
/* This loop handles a single s-g list entry, which may
* include multiple pages. Find the initial page structure
* and the starting offset within the page, and update
* the *offset and *index values for the next loop. */
cnt = 0;
- while (cnt < buflen && *index < srb->use_sg) {
+ while (cnt < buflen) {
struct page *page = sg->page +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
@@ -209,8 +210,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
/* Transfer continues to next s-g entry */
*offset = 0;
- ++*index;
- ++sg;
+ sg = sg_next(sg);
}
/* Transfer the data for all the pages in this
@@ -234,6 +234,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
sglen -= plen;
}
}
+ *sgptr = sg;
}
/* Return the amount actually transferred */
@@ -245,9 +246,10 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
void usb_stor_set_xfer_buf(unsigned char *buffer,
unsigned int buflen, struct scsi_cmnd *srb)
{
- unsigned int index = 0, offset = 0;
+ unsigned int offset = 0;
+ struct scatterlist *sg = NULL;
- usb_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
+ usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
TO_XFER_BUF);
if (buflen < srb->request_bufflen)
srb->resid = srb->request_bufflen - buflen;
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
index 845bed4b803..8737a36891c 100644
--- a/drivers/usb/storage/protocol.h
+++ b/drivers/usb/storage/protocol.h
@@ -52,7 +52,7 @@ extern void usb_stor_transparent_scsi_command(struct scsi_cmnd*,
enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF};
extern unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
- unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index,
+ unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **,
unsigned int *offset, enum xfer_buf_dir dir);
extern void usb_stor_set_xfer_buf(unsigned char *buffer,
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index b2ed2a3e6fc..b12202c5da2 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -705,7 +705,8 @@ sddr09_read_data(struct us_data *us,
unsigned char *buffer;
unsigned int lba, maxlba, pba;
unsigned int page, pages;
- unsigned int len, index, offset;
+ unsigned int len, offset;
+ struct scatterlist *sg;
int result;
// Figure out the initial LBA and page
@@ -730,7 +731,8 @@ sddr09_read_data(struct us_data *us,
// contiguous LBA's. Another exercise left to the student.
result = 0;
- index = offset = 0;
+ offset = 0;
+ sg = NULL;
while (sectors > 0) {
@@ -777,7 +779,7 @@ sddr09_read_data(struct us_data *us,
// Store the data in the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &index, &offset, TO_XFER_BUF);
+ &sg, &offset, TO_XFER_BUF);
page = 0;
lba++;
@@ -931,7 +933,8 @@ sddr09_write_data(struct us_data *us,
unsigned int pagelen, blocklen;
unsigned char *blockbuffer;
unsigned char *buffer;
- unsigned int len, index, offset;
+ unsigned int len, offset;
+ struct scatterlist *sg;
int result;
// Figure out the initial LBA and page
@@ -968,7 +971,8 @@ sddr09_write_data(struct us_data *us,
}
result = 0;
- index = offset = 0;
+ offset = 0;
+ sg = NULL;
while (sectors > 0) {
@@ -987,7 +991,7 @@ sddr09_write_data(struct us_data *us,
// Get the data from the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &index, &offset, FROM_XFER_BUF);
+ &sg, &offset, FROM_XFER_BUF);
result = sddr09_write_lba(us, lba, page, pages,
buffer, blockbuffer);
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index 0b1b5b59ca7..d43a3415e12 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -167,7 +167,8 @@ static int sddr55_read_data(struct us_data *us,
unsigned long address;
unsigned short pages;
- unsigned int len, index, offset;
+ unsigned int len, offset;
+ struct scatterlist *sg;
// Since we only read in one block at a time, we have to create
// a bounce buffer and move the data a piece at a time between the
@@ -178,7 +179,8 @@ static int sddr55_read_data(struct us_data *us,
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR; /* out of memory */
- index = offset = 0;
+ offset = 0;
+ sg = NULL;
while (sectors>0) {
@@ -255,7 +257,7 @@ static int sddr55_read_data(struct us_data *us,
// Store the data in the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &index, &offset, TO_XFER_BUF);
+ &sg, &offset, TO_XFER_BUF);
page = 0;
lba++;
@@ -287,7 +289,8 @@ static int sddr55_write_data(struct us_data *us,
unsigned short pages;
int i;
- unsigned int len, index, offset;
+ unsigned int len, offset;
+ struct scatterlist *sg;
/* check if we are allowed to write */
if (info->read_only || info->force_read_only) {
@@ -304,7 +307,8 @@ static int sddr55_write_data(struct us_data *us,
buffer = kmalloc(len, GFP_NOIO);
if (buffer == NULL)
return USB_STOR_TRANSPORT_ERROR;
- index = offset = 0;
+ offset = 0;
+ sg = NULL;
while (sectors > 0) {
@@ -322,7 +326,7 @@ static int sddr55_write_data(struct us_data *us,
// Get the data from the transfer buffer
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &index, &offset, FROM_XFER_BUF);
+ &sg, &offset, FROM_XFER_BUF);
US_DEBUGP("Write %02X pages, to PBA %04X"
" (LBA %04X) page %02X\n",
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 17ca4d73577..cb22a9ad169 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -993,7 +993,8 @@ static int usbat_flash_read_data(struct us_data *us,
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_idx = 0, sg_offset = 0;
+ unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
result = usbat_flash_check_media(us, info);
if (result != USB_STOR_TRANSPORT_GOOD)
@@ -1047,7 +1048,7 @@ static int usbat_flash_read_data(struct us_data *us,
/* Store the data in the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg_idx, &sg_offset, TO_XFER_BUF);
+ &sg, &sg_offset, TO_XFER_BUF);
sector += thistime;
totallen -= len;
@@ -1083,7 +1084,8 @@ static int usbat_flash_write_data(struct us_data *us,
unsigned char thistime;
unsigned int totallen, alloclen;
int len, result;
- unsigned int sg_idx = 0, sg_offset = 0;
+ unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
result = usbat_flash_check_media(us, info);
if (result != USB_STOR_TRANSPORT_GOOD)
@@ -1122,7 +1124,7 @@ static int usbat_flash_write_data(struct us_data *us,
/* Get the data from the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, us->srb,
- &sg_idx, &sg_offset, FROM_XFER_BUF);
+ &sg, &sg_offset, FROM_XFER_BUF);
/* ATA command 0x30 (WRITE SECTORS) */
usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30);
@@ -1162,8 +1164,8 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
unsigned char *buffer;
unsigned int len;
unsigned int sector;
- unsigned int sg_segment = 0;
unsigned int sg_offset = 0;
+ struct scatterlist *sg = NULL;
US_DEBUGP("handle_read10: transfersize %d\n",
srb->transfersize);
@@ -1220,9 +1222,6 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
sector |= short_pack(data[7+5], data[7+4]);
transferred = 0;
- sg_segment = 0; /* for keeping track of where we are in */
- sg_offset = 0; /* the scatter/gather list */
-
while (transferred != srb->request_bufflen) {
if (len > srb->request_bufflen - transferred)
@@ -1255,7 +1254,7 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
/* Store the data in the transfer buffer */
usb_stor_access_xfer_buf(buffer, len, srb,
- &sg_segment, &sg_offset, TO_XFER_BUF);
+ &sg, &sg_offset, TO_XFER_BUF);
/* Update the amount transferred and the sector number */
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3451e8d03ab..ac6114eea0c 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -907,12 +907,9 @@ static int usb_stor_scan_thread(void * __us)
if (delay_use > 0) {
printk(KERN_DEBUG "usb-storage: waiting for device "
"to settle before scanning\n");
-retry:
- wait_event_interruptible_timeout(us->delay_wait,
+ wait_event_freezable_timeout(us->delay_wait,
test_bit(US_FLIDX_DISCONNECTING, &us->flags),
delay_use * HZ);
- if (try_to_freeze())
- goto retry;
}
/* If the device is still connected, perform the scanning */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5216c11d4de..b3bf4ecc983 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,8 +5,9 @@
menu "Graphics support"
depends on HAS_IOMEM
-source "drivers/video/backlight/Kconfig"
-source "drivers/video/display/Kconfig"
+source "drivers/char/agp/Kconfig"
+
+source "drivers/char/drm/Kconfig"
config VGASTATE
tristate
@@ -14,12 +15,11 @@ config VGASTATE
config VIDEO_OUTPUT_CONTROL
tristate "Lowlevel video output switch controls"
- default m
help
This framework adds support for low-level control of the video
output switch.
-config FB
+menuconfig FB
tristate "Support for frame buffer devices"
---help---
The frame buffer device provides an abstraction for the graphics
@@ -103,6 +103,15 @@ config FB_CFB_IMAGEBLIT
blitting. This is used by drivers that don't provide their own
(accelerated) version.
+config FB_CFB_REV_PIXELS_IN_BYTE
+ bool
+ depends on FB
+ default n
+ ---help---
+ Allow generic frame-buffer functions to work on displays with 1, 2
+ and 4 bits per pixel depths which has opposite order of pixels in
+ byte order to bytes in long order.
+
config FB_SYS_FILLRECT
tristate
depends on FB
@@ -535,6 +544,15 @@ config FB_VGA16
To compile this driver as a module, choose M here: the
module will be called vga16fb.
+config FB_BF54X_LQ043
+ tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
+ depends on FB && (BF54x)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
+
config FB_STI
tristate "HP STI frame buffer device support"
depends on FB && PARISC
@@ -592,6 +610,24 @@ config FB_TGA
Say Y if you have one of those.
+config FB_UVESA
+ tristate "Userspace VESA VGA graphics support"
+ depends on FB && CONNECTOR
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ help
+ This is the frame buffer driver for generic VBE 2.0 compliant
+ graphic cards. It can also take advantage of VBE 3.0 features,
+ such as refresh rate adjustment.
+
+ This driver generally provides more features than vesafb but
+ requires a userspace helper application called 'v86d'. See
+ <file:Documentation/fb/uvesafb.txt> for more information.
+
+ If unsure, say N.
+
config FB_VESA
bool "VESA VGA graphics support"
depends on (FB = y) && X86
@@ -1625,7 +1661,7 @@ config FB_PMAG_BA
config FB_PMAGB_B
tristate "PMAGB-B TURBOchannel framebuffer support"
- depends on TC
+ depends on FB && TC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -1793,7 +1829,7 @@ config FB_PNX4008_DUM_RGB
config FB_IBM_GXT4500
tristate "Framebuffer support for IBM GXT4500P adaptor"
- depends on PPC
+ depends on FB && PPC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -1833,10 +1869,6 @@ config FB_XILINX
framebuffer. ML300 carries a 640*480 LCD display on the board,
ML403 uses a standard DB15 VGA connector.
-if ARCH_OMAP
- source "drivers/video/omap/Kconfig"
-endif
-
config FB_VIRTUAL
tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
depends on FB
@@ -1860,6 +1892,13 @@ config FB_VIRTUAL
If unsure, say N.
+if ARCH_OMAP
+ source "drivers/video/omap/Kconfig"
+endif
+
+source "drivers/video/backlight/Kconfig"
+source "drivers/video/display/Kconfig"
+
if VT
source "drivers/video/console/Kconfig"
endif
@@ -1869,4 +1908,3 @@ if FB || SGI_NEWPORT_CONSOLE
endif
endmenu
-
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 06eec7b182b..59d6c45a910 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -115,10 +115,12 @@ obj-$(CONFIG_FB_XILINX) += xilinxfb.o
obj-$(CONFIG_FB_OMAP) += omap/
# Platform or fallback drivers go here
+obj-$(CONFIG_FB_UVESA) += uvesafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o
obj-$(CONFIG_FB_IMAC) += imacfb.o
obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
+obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 1a849b870bc..f2e243c353f 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -52,7 +52,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index db15baca3f7..c3431691c9f 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -48,7 +48,7 @@
#include <linux/arcfb.h>
#include <linux/platform_device.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#define floor8(a) (a&(~0x07))
#define floorXres(a,xres) (a&(~(xres - 1)))
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 0038a0541c7..5d4fbaa53a6 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -58,7 +58,7 @@
#include <linux/interrupt.h>
#include <asm/setup.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/io.h>
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index dca2eb8f2dd..3e9d28bcd9f 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -188,6 +188,7 @@
#define PCI_CHIP_MACH64VT 0x5654
#define PCI_CHIP_MACH64VU 0x5655
#define PCI_CHIP_MACH64VV 0x5656
+#define PCI_CHIP_RC410_5A62 0x5A62
#define PCI_CHIP_RS300_5834 0x5834
#define PCI_CHIP_RS300_5835 0x5835
#define PCI_CHIP_RS300_5836 0x5836
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index cfcbe37d2d7..cbd3308b669 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -56,7 +56,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index dc62f8e282b..7691e73823d 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -126,6 +126,7 @@ union aty_pll {
*/
struct atyfb_par {
+ u32 pseudo_palette[16];
struct { u8 red, green, blue; } palette[256];
const struct aty_dac_ops *dac_ops;
const struct aty_pll_ops *pll_ops;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index bc6f0096aa0..abe0c435a66 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -68,7 +68,7 @@
#include <linux/backlight.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <video/mach64.h>
#include "atyfb.h"
@@ -541,8 +541,6 @@ static char ram_off[] __devinitdata = "OFF";
#endif /* CONFIG_FB_ATY_CT */
-static u32 pseudo_palette[16];
-
#ifdef CONFIG_FB_ATY_GX
static char *aty_gx_ram[8] __devinitdata = {
ram_dram, ram_vram, ram_vram, ram_dram,
@@ -2577,7 +2575,7 @@ static int __devinit aty_init(struct fb_info *info)
#endif
info->fbops = &atyfb_ops;
- info->pseudo_palette = pseudo_palette;
+ info->pseudo_palette = par->pseudo_palette;
info->flags = FBINFO_DEFAULT |
FBINFO_HWACCEL_IMAGEBLIT |
FBINFO_HWACCEL_FILLRECT |
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index fe2c6ad01a8..faf95da8fcb 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -8,7 +8,6 @@
#include <linux/string.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
#ifdef __sparc__
#include <asm/fbio.h>
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 4b747bdaeea..1e32b3d13f2 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -69,7 +69,7 @@
#include <linux/device.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#ifdef CONFIG_PPC_OF
@@ -145,6 +145,8 @@ static struct pci_device_id radeonfb_pci_table[] = {
/* 9000/Pro */
CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2),
CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2),
+
+ CHIP_DEF(PCI_CHIP_RC410_5A62, RC410, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
/* Mobility 9100 IGP (U3) */
CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
@@ -1999,6 +2001,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
if ((rinfo->family == CHIP_FAMILY_RS100) ||
(rinfo->family == CHIP_FAMILY_RS200) ||
(rinfo->family == CHIP_FAMILY_RS300) ||
+ (rinfo->family == CHIP_FAMILY_RC410) ||
(rinfo->family == CHIP_FAMILY_RS480) ) {
u32 tom = INREG(NB_TOM);
tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 7c922c7b460..5eac1ce52e7 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -48,6 +48,7 @@ enum radeon_family {
CHIP_FAMILY_RV350,
CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
CHIP_FAMILY_R420, /* R420/R423/M18 */
+ CHIP_FAMILY_RC410,
CHIP_FAMILY_RS480,
CHIP_FAMILY_LAST,
};
@@ -66,7 +67,8 @@ enum radeon_family {
((rinfo)->family == CHIP_FAMILY_R350) || \
((rinfo)->family == CHIP_FAMILY_RV380) || \
((rinfo)->family == CHIP_FAMILY_R420) || \
- ((rinfo)->family == CHIP_FAMILY_RS480) )
+ ((rinfo)->family == CHIP_FAMILY_RC410) || \
+ ((rinfo)->family == CHIP_FAMILY_RS480))
/*
* Chip flags
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 832e4613673..62bd4441b5e 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops =
/* AU1100 LCD controller device driver */
-int au1100fb_drv_probe(struct device *dev)
+static int __init au1100fb_drv_probe(struct device *dev)
{
struct au1100fb_device *fbdev = NULL;
struct resource *regs_res;
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 92e201e81fb..26add889860 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -36,7 +36,6 @@
#include <linux/backlight.h>
#include <linux/lcd.h>
#include <linux/pci.h>
-#include <asm/uaccess.h>
/* The LVDS- and panel power controls sits on the
* GPIO port of the ISA bridge.
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 836ab4df0ef..15fb4d58b5b 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -23,7 +23,6 @@
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/pci.h>
-#include <asm/uaccess.h>
#define PMU_LPCR 0xB0
#define SB_MPS1 0x61
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
new file mode 100644
index 00000000000..74d11c31898
--- /dev/null
+++ b/drivers/video/bf54x-lq043fb.c
@@ -0,0 +1,786 @@
+/*
+ * File: drivers/video/bf54x-lq043.c
+ * Based on:
+ * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
+ *
+ * Created:
+ * Description: ADSP-BF54x Framebufer driver
+ *
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/device.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+#include <asm/dpmc.h>
+#include <asm/dma-mapping.h>
+#include <asm/dma.h>
+#include <asm/gpio.h>
+#include <asm/portmux.h>
+
+#include <asm/mach/bf54x-lq043.h>
+
+#define NO_BL_SUPPORT
+
+#define DRIVER_NAME "bf54x-lq043"
+static char driver_name[] = DRIVER_NAME;
+
+#define BFIN_LCD_NBR_PALETTE_ENTRIES 256
+
+#define EPPI0_18 {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, \
+ P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, \
+ P_PPI0_D11, P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, P_PPI0_D16, P_PPI0_D17, 0}
+
+#define EPPI0_24 {P_PPI0_D18, P_PPI0_D19, P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23, 0}
+
+struct bfin_bf54xfb_info {
+ struct fb_info *fb;
+ struct device *dev;
+
+ struct bfin_bf54xfb_mach_info *mach_info;
+
+ unsigned char *fb_buffer; /* RGB Buffer */
+
+ dma_addr_t dma_handle;
+ int lq043_mmap;
+ int lq043_open_cnt;
+ int irq;
+ spinlock_t lock; /* lock */
+};
+
+static int nocursor;
+module_param(nocursor, int, 0644);
+MODULE_PARM_DESC(nocursor, "cursor enable/disable");
+
+static int outp_rgb666;
+module_param(outp_rgb666, int, 0);
+MODULE_PARM_DESC(outp_rgb666, "Output 18-bit RGB666");
+
+#define LCD_X_RES 480 /*Horizontal Resolution */
+#define LCD_Y_RES 272 /* Vertical Resolution */
+
+#define LCD_BPP 24 /* Bit Per Pixel */
+#define DMA_BUS_SIZE 32
+
+/* -- Horizontal synchronizing --
+ *
+ * Timing characteristics taken from the SHARP LQ043T1DG01 datasheet
+ * (LCY-W-06602A Page 9 of 22)
+ *
+ * Clock Frequency 1/Tc Min 7.83 Typ 9.00 Max 9.26 MHz
+ *
+ * Period TH - 525 - Clock
+ * Pulse width THp - 41 - Clock
+ * Horizontal period THd - 480 - Clock
+ * Back porch THb - 2 - Clock
+ * Front porch THf - 2 - Clock
+ *
+ * -- Vertical synchronizing --
+ * Period TV - 286 - Line
+ * Pulse width TVp - 10 - Line
+ * Vertical period TVd - 272 - Line
+ * Back porch TVb - 2 - Line
+ * Front porch TVf - 2 - Line
+ */
+
+#define LCD_CLK (8*1000*1000) /* 8MHz */
+
+/* # active data to transfer after Horizontal Delay clock */
+#define EPPI_HCOUNT LCD_X_RES
+
+/* # active lines to transfer after Vertical Delay clock */
+#define EPPI_VCOUNT LCD_Y_RES
+
+/* Samples per Line = 480 (active data) + 45 (padding) */
+#define EPPI_LINE 525
+
+/* Lines per Frame = 272 (active data) + 14 (padding) */
+#define EPPI_FRAME 286
+
+/* FS1 (Hsync) Width (Typical)*/
+#define EPPI_FS1W_HBL 41
+
+/* FS1 (Hsync) Period (Typical) */
+#define EPPI_FS1P_AVPL EPPI_LINE
+
+/* Horizontal Delay clock after assertion of Hsync (Typical) */
+#define EPPI_HDELAY 43
+
+/* FS2 (Vsync) Width = FS1 (Hsync) Period * 10 */
+#define EPPI_FS2W_LVB (EPPI_LINE * 10)
+
+ /* FS2 (Vsync) Period = FS1 (Hsync) Period * Lines per Frame */
+#define EPPI_FS2P_LAVF (EPPI_LINE * EPPI_FRAME)
+
+/* Vertical Delay after assertion of Vsync (2 Lines) */
+#define EPPI_VDELAY 12
+
+#define EPPI_CLIP 0xFF00FF00
+
+/* EPPI Control register configuration value for RGB out
+ * - EPPI as Output
+ * GP 2 frame sync mode,
+ * Internal Clock generation disabled, Internal FS generation enabled,
+ * Receives samples on EPPI_CLK raising edge, Transmits samples on EPPI_CLK falling edge,
+ * FS1 & FS2 are active high,
+ * DLEN = 6 (24 bits for RGB888 out) or 5 (18 bits for RGB666 out)
+ * DMA Unpacking disabled when RGB Formating is enabled, otherwise DMA unpacking enabled
+ * Swapping Enabled,
+ * One (DMA) Channel Mode,
+ * RGB Formatting Enabled for RGB666 output, disabled for RGB888 output
+ * Regular watermark - when FIFO is 100% full,
+ * Urgent watermark - when FIFO is 75% full
+ */
+
+#define EPPI_CONTROL (0x20136E2E | SWAPEN)
+
+static inline u16 get_eppi_clkdiv(u32 target_ppi_clk)
+{
+ u32 sclk = get_sclk();
+
+ /* EPPI_CLK = (SCLK) / (2 * (EPPI_CLKDIV[15:0] + 1)) */
+
+ return (((sclk / target_ppi_clk) / 2) - 1);
+}
+
+static void config_ppi(struct bfin_bf54xfb_info *fbi)
+{
+
+ u16 eppi_clkdiv = get_eppi_clkdiv(LCD_CLK);
+
+ bfin_write_EPPI0_FS1W_HBL(EPPI_FS1W_HBL);
+ bfin_write_EPPI0_FS1P_AVPL(EPPI_FS1P_AVPL);
+ bfin_write_EPPI0_FS2W_LVB(EPPI_FS2W_LVB);
+ bfin_write_EPPI0_FS2P_LAVF(EPPI_FS2P_LAVF);
+ bfin_write_EPPI0_CLIP(EPPI_CLIP);
+
+ bfin_write_EPPI0_FRAME(EPPI_FRAME);
+ bfin_write_EPPI0_LINE(EPPI_LINE);
+
+ bfin_write_EPPI0_HCOUNT(EPPI_HCOUNT);
+ bfin_write_EPPI0_HDELAY(EPPI_HDELAY);
+ bfin_write_EPPI0_VCOUNT(EPPI_VCOUNT);
+ bfin_write_EPPI0_VDELAY(EPPI_VDELAY);
+
+ bfin_write_EPPI0_CLKDIV(eppi_clkdiv);
+
+/*
+ * DLEN = 6 (24 bits for RGB888 out) or 5 (18 bits for RGB666 out)
+ * RGB Formatting Enabled for RGB666 output, disabled for RGB888 output
+ */
+ if (outp_rgb666)
+ bfin_write_EPPI0_CONTROL((EPPI_CONTROL & ~DLENGTH) | DLEN_18 |
+ RGB_FMT_EN);
+ else
+ bfin_write_EPPI0_CONTROL(((EPPI_CONTROL & ~DLENGTH) | DLEN_24) &
+ ~RGB_FMT_EN);
+
+
+}
+
+static int config_dma(struct bfin_bf54xfb_info *fbi)
+{
+
+ set_dma_config(CH_EPPI0,
+ set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO,
+ INTR_DISABLE, DIMENSION_2D,
+ DATA_SIZE_32));
+ set_dma_x_count(CH_EPPI0, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE);
+ set_dma_x_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
+ set_dma_y_count(CH_EPPI0, LCD_Y_RES);
+ set_dma_y_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
+ set_dma_start_addr(CH_EPPI0, (unsigned long)fbi->fb_buffer);
+
+ return 0;
+}
+
+static int request_ports(struct bfin_bf54xfb_info *fbi)
+{
+
+ u16 eppi_req_18[] = EPPI0_18;
+ u16 disp = fbi->mach_info->disp;
+
+ if (gpio_request(disp, NULL)) {
+ printk(KERN_ERR "Requesting GPIO %d faild\n", disp);
+ return -EFAULT;
+ }
+
+ if (peripheral_request_list(eppi_req_18, DRIVER_NAME)) {
+ printk(KERN_ERR "Requesting Peripherals faild\n");
+ gpio_free(disp);
+ return -EFAULT;
+ }
+
+ if (!outp_rgb666) {
+
+ u16 eppi_req_24[] = EPPI0_24;
+
+ if (peripheral_request_list(eppi_req_24, DRIVER_NAME)) {
+ printk(KERN_ERR "Requesting Peripherals faild\n");
+ peripheral_free_list(eppi_req_18);
+ gpio_free(disp);
+ return -EFAULT;
+ }
+ }
+
+ gpio_direction_output(disp);
+ gpio_set_value(disp, 1);
+
+ return 0;
+}
+
+static void free_ports(struct bfin_bf54xfb_info *fbi)
+{
+
+ u16 eppi_req_18[] = EPPI0_18;
+
+ gpio_free(fbi->mach_info->disp);
+
+ peripheral_free_list(eppi_req_18);
+
+ if (!outp_rgb666) {
+ u16 eppi_req_24[] = EPPI0_24;
+ peripheral_free_list(eppi_req_24);
+ }
+}
+
+static int bfin_bf54x_fb_open(struct fb_info *info, int user)
+{
+ struct bfin_bf54xfb_info *fbi = info->par;
+
+ spin_lock(&fbi->lock);
+ fbi->lq043_open_cnt++;
+
+ if (fbi->lq043_open_cnt <= 1) {
+
+ bfin_write_EPPI0_CONTROL(0);
+ SSYNC();
+
+ config_dma(fbi);
+ config_ppi(fbi);
+
+ /* start dma */
+ enable_dma(CH_EPPI0);
+ bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
+ }
+
+ spin_unlock(&fbi->lock);
+
+ return 0;
+}
+
+static int bfin_bf54x_fb_release(struct fb_info *info, int user)
+{
+ struct bfin_bf54xfb_info *fbi = info->par;
+
+ spin_lock(&fbi->lock);
+
+ fbi->lq043_open_cnt--;
+ fbi->lq043_mmap = 0;
+
+ if (fbi->lq043_open_cnt <= 0) {
+
+ bfin_write_EPPI0_CONTROL(0);
+ SSYNC();
+ disable_dma(CH_EPPI0);
+ memset(fbi->fb_buffer, 0, info->fix.smem_len);
+ }
+
+ spin_unlock(&fbi->lock);
+
+ return 0;
+}
+
+static int bfin_bf54x_fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+
+ if (var->bits_per_pixel != LCD_BPP) {
+ pr_debug("%s: depth not supported: %u BPP\n", __FUNCTION__,
+ var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ if (info->var.xres != var->xres || info->var.yres != var->yres ||
+ info->var.xres_virtual != var->xres_virtual ||
+ info->var.yres_virtual != var->yres_virtual) {
+ pr_debug("%s: Resolution not supported: X%u x Y%u \n",
+ __FUNCTION__, var->xres, var->yres);
+ return -EINVAL;
+ }
+
+ /*
+ * Memory limit
+ */
+
+ if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) {
+ pr_debug("%s: Memory Limit requested yres_virtual = %u\n",
+ __FUNCTION__, var->yres_virtual);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+
+ struct bfin_bf54xfb_info *fbi = info->par;
+
+ if (fbi->lq043_mmap)
+ return -1;
+
+ spin_lock(&fbi->lock);
+ fbi->lq043_mmap = 1;
+ spin_unlock(&fbi->lock);
+
+ vma->vm_start = (unsigned long)(fbi->fb_buffer);
+
+ vma->vm_end = vma->vm_start + info->fix.smem_len;
+ /* For those who don't understand how mmap works, go read
+ * Documentation/nommu-mmap.txt.
+ * For those that do, you will know that the VM_MAYSHARE flag
+ * must be set in the vma->vm_flags structure on noMMU
+ * Other flags can be set, and are documented in
+ * include/linux/mm.h
+ */
+ vma->vm_flags |= VM_MAYSHARE;
+
+ return 0;
+}
+
+int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ if (nocursor)
+ return 0;
+ else
+ return -EINVAL; /* just to force soft_cursor() call */
+}
+
+static int bfin_bf54x_fb_setcolreg(u_int regno, u_int red, u_int green,
+ u_int blue, u_int transp,
+ struct fb_info *info)
+{
+ if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES)
+ return -EINVAL;
+
+ if (info->var.grayscale) {
+ /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ }
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+
+ u32 value;
+ /* Place color in the pseudopalette */
+ if (regno > 16)
+ return -EINVAL;
+
+ red >>= (16 - info->var.red.length);
+ green >>= (16 - info->var.green.length);
+ blue >>= (16 - info->var.blue.length);
+
+ value = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset);
+ value &= 0xFFFFFF;
+
+ ((u32 *) (info->pseudo_palette))[regno] = value;
+
+ }
+
+ return 0;
+}
+
+static struct fb_ops bfin_bf54x_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = bfin_bf54x_fb_open,
+ .fb_release = bfin_bf54x_fb_release,
+ .fb_check_var = bfin_bf54x_fb_check_var,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = bfin_bf54x_fb_mmap,
+ .fb_cursor = bfin_bf54x_fb_cursor,
+ .fb_setcolreg = bfin_bf54x_fb_setcolreg,
+};
+
+#ifndef NO_BL_SUPPORT
+static int bl_get_brightness(struct backlight_device *bd)
+{
+ return 0;
+}
+
+static struct backlight_ops bfin_lq043fb_bl_ops = {
+ .get_brightness = bl_get_brightness,
+};
+
+static struct backlight_device *bl_dev;
+
+static int bfin_lcd_get_power(struct lcd_device *dev)
+{
+ return 0;
+}
+
+static int bfin_lcd_set_power(struct lcd_device *dev, int power)
+{
+ return 0;
+}
+
+static int bfin_lcd_get_contrast(struct lcd_device *dev)
+{
+ return 0;
+}
+
+static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast)
+{
+
+ return 0;
+}
+
+static int bfin_lcd_check_fb(struct fb_info *fi)
+{
+ if (!fi || (fi == &bfin_bf54x_fb))
+ return 1;
+ return 0;
+}
+
+static struct lcd_ops bfin_lcd_ops = {
+ .get_power = bfin_lcd_get_power,
+ .set_power = bfin_lcd_set_power,
+ .get_contrast = bfin_lcd_get_contrast,
+ .set_contrast = bfin_lcd_set_contrast,
+ .check_fb = bfin_lcd_check_fb,
+};
+
+static struct lcd_device *lcd_dev;
+#endif
+
+static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
+{
+
+ /*struct bfin_bf54xfb_info *info = (struct bfin_bf54xfb_info *)dev_id;*/
+
+ u16 status = bfin_read_EPPI0_STATUS();
+
+ bfin_write_EPPI0_STATUS(0xFFFF);
+
+ if (status) {
+ bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
+ disable_dma(CH_EPPI0);
+
+ /* start dma */
+ enable_dma(CH_EPPI0);
+ bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
+ bfin_write_EPPI0_STATUS(0xFFFF);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __init bfin_bf54x_probe(struct platform_device *pdev)
+{
+ struct bfin_bf54xfb_info *info;
+ struct fb_info *fbinfo;
+ int ret;
+
+ printk(KERN_INFO DRIVER_NAME ": FrameBuffer initializing...\n");
+
+ if (request_dma(CH_EPPI0, "CH_EPPI0") < 0) {
+ printk(KERN_ERR DRIVER_NAME
+ ": couldn't request CH_EPPI0 DMA\n");
+ ret = -EFAULT;
+ goto out1;
+ }
+
+ fbinfo =
+ framebuffer_alloc(sizeof(struct bfin_bf54xfb_info), &pdev->dev);
+ if (!fbinfo) {
+ ret = -ENOMEM;
+ goto out2;
+ }
+
+ info = fbinfo->par;
+ info->fb = fbinfo;
+ info->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, fbinfo);
+
+ strcpy(fbinfo->fix.id, driver_name);
+
+ info->mach_info = pdev->dev.platform_data;
+
+ if (info->mach_info == NULL) {
+ dev_err(&pdev->dev,
+ "no platform data for lcd, cannot attach\n");
+ ret = -EINVAL;
+ goto out3;
+ }
+
+ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
+ fbinfo->fix.type_aux = 0;
+ fbinfo->fix.xpanstep = 0;
+ fbinfo->fix.ypanstep = 0;
+ fbinfo->fix.ywrapstep = 0;
+ fbinfo->fix.accel = FB_ACCEL_NONE;
+ fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;
+
+ fbinfo->var.nonstd = 0;
+ fbinfo->var.activate = FB_ACTIVATE_NOW;
+ fbinfo->var.height = info->mach_info->height;
+ fbinfo->var.width = info->mach_info->width;
+ fbinfo->var.accel_flags = 0;
+ fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
+
+ fbinfo->fbops = &bfin_bf54x_fb_ops;
+ fbinfo->flags = FBINFO_FLAG_DEFAULT;
+
+ fbinfo->var.xres = info->mach_info->xres.defval;
+ fbinfo->var.xres_virtual = info->mach_info->xres.defval;
+ fbinfo->var.yres = info->mach_info->yres.defval;
+ fbinfo->var.yres_virtual = info->mach_info->yres.defval;
+ fbinfo->var.bits_per_pixel = info->mach_info->bpp.defval;
+
+ fbinfo->var.upper_margin = 0;
+ fbinfo->var.lower_margin = 0;
+ fbinfo->var.vsync_len = 0;
+
+ fbinfo->var.left_margin = 0;
+ fbinfo->var.right_margin = 0;
+ fbinfo->var.hsync_len = 0;
+
+ fbinfo->var.red.offset = 16;
+ fbinfo->var.green.offset = 8;
+ fbinfo->var.blue.offset = 0;
+ fbinfo->var.transp.offset = 0;
+ fbinfo->var.red.length = 8;
+ fbinfo->var.green.length = 8;
+ fbinfo->var.blue.length = 8;
+ fbinfo->var.transp.length = 0;
+ fbinfo->fix.smem_len = info->mach_info->xres.max *
+ info->mach_info->yres.max * info->mach_info->bpp.max / 8;
+
+ fbinfo->fix.line_length = fbinfo->var.xres_virtual *
+ fbinfo->var.bits_per_pixel / 8;
+
+ info->fb_buffer =
+ dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle,
+ GFP_KERNEL);
+
+ if (NULL == info->fb_buffer) {
+ printk(KERN_ERR DRIVER_NAME
+ ": couldn't allocate dma buffer.\n");
+ ret = -ENOMEM;
+ goto out3;
+ }
+
+ memset(info->fb_buffer, 0, fbinfo->fix.smem_len);
+
+ fbinfo->screen_base = (void *)info->fb_buffer;
+ fbinfo->fix.smem_start = (int)info->fb_buffer;
+
+ fbinfo->fbops = &bfin_bf54x_fb_ops;
+
+ fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+ if (!fbinfo->pseudo_palette) {
+ printk(KERN_ERR DRIVER_NAME
+ "Fail to allocate pseudo_palette\n");
+
+ ret = -ENOMEM;
+ goto out4;
+ }
+
+ memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16);
+
+ if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0)
+ < 0) {
+ printk(KERN_ERR DRIVER_NAME
+ "Fail to allocate colormap (%d entries)\n",
+ BFIN_LCD_NBR_PALETTE_ENTRIES);
+ ret = -EFAULT;
+ goto out5;
+ }
+
+ if (request_ports(info)) {
+ printk(KERN_ERR DRIVER_NAME ": couldn't request gpio port.\n");
+ ret = -EFAULT;
+ goto out6;
+ }
+
+ info->irq = platform_get_irq(pdev, 0);
+ if (info->irq < 0) {
+ ret = -EINVAL;
+ goto out7;
+ }
+
+ if (request_irq(info->irq, (void *)bfin_bf54x_irq_error, IRQF_DISABLED,
+ "PPI ERROR", info) < 0) {
+ printk(KERN_ERR DRIVER_NAME
+ ": unable to request PPI ERROR IRQ\n");
+ ret = -EFAULT;
+ goto out7;
+ }
+
+ if (register_framebuffer(fbinfo) < 0) {
+ printk(KERN_ERR DRIVER_NAME
+ ": unable to register framebuffer.\n");
+ ret = -EINVAL;
+ goto out8;
+ }
+#ifndef NO_BL_SUPPORT
+ bl_dev =
+ backlight_device_register("bf54x-bl", NULL, NULL,
+ &bfin_lq043fb_bl_ops);
+ bl_dev->props.max_brightness = 255;
+
+ lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
+ lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
+#endif
+
+ return 0;
+
+out8:
+ free_irq(info->irq, info);
+out7:
+ free_ports(info);
+out6:
+ fb_dealloc_cmap(&fbinfo->cmap);
+out5:
+ kfree(fbinfo->pseudo_palette);
+out4:
+ dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
+ info->dma_handle);
+out3:
+ framebuffer_release(fbinfo);
+out2:
+ free_dma(CH_EPPI0);
+out1:
+ platform_set_drvdata(pdev, NULL);
+
+ return ret;
+}
+
+static int bfin_bf54x_remove(struct platform_device *pdev)
+{
+
+ struct fb_info *fbinfo = platform_get_drvdata(pdev);
+ struct bfin_bf54xfb_info *info = fbinfo->par;
+
+ free_dma(CH_EPPI0);
+ free_irq(info->irq, info);
+
+ if (info->fb_buffer != NULL)
+ dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
+ info->dma_handle);
+
+ kfree(fbinfo->pseudo_palette);
+ fb_dealloc_cmap(&fbinfo->cmap);
+
+#ifndef NO_BL_SUPPORT
+ lcd_device_unregister(lcd_dev);
+ backlight_device_unregister(bl_dev);
+#endif
+
+ unregister_framebuffer(fbinfo);
+
+ free_ports(info);
+
+ printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int bfin_bf54x_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct fb_info *fbinfo = platform_get_drvdata(pdev);
+ struct bfin_bf54xfb_info *info = fbinfo->par;
+
+ bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
+ disable_dma(CH_EPPI0);
+ bfin_write_EPPI0_STATUS(0xFFFF);
+
+ return 0;
+}
+
+static int bfin_bf54x_resume(struct platform_device *pdev)
+{
+ struct fb_info *fbinfo = platform_get_drvdata(pdev);
+ struct bfin_bf54xfb_info *info = fbinfo->par;
+
+ enable_dma(CH_EPPI0);
+ bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
+
+ return 0;
+}
+#else
+#define bfin_bf54x_suspend NULL
+#define bfin_bf54x_resume NULL
+#endif
+
+static struct platform_driver bfin_bf54x_driver = {
+ .probe = bfin_bf54x_probe,
+ .remove = bfin_bf54x_remove,
+ .suspend = bfin_bf54x_suspend,
+ .resume = bfin_bf54x_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __devinit bfin_bf54x_driver_init(void)
+{
+ return platform_driver_register(&bfin_bf54x_driver);
+}
+
+static void __exit bfin_bf54x_driver_cleanup(void)
+{
+ platform_driver_unregister(&bfin_bf54x_driver);
+}
+
+MODULE_DESCRIPTION("Blackfin BF54x TFT LCD Driver");
+MODULE_LICENSE("GPL");
+
+module_init(bfin_bf54x_driver_init);
+module_exit(bfin_bf54x_driver_cleanup);
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 032210f45be..b07e419b12d 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -45,14 +45,14 @@
static void
bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src,
- int src_idx, int bits, unsigned n)
+ int src_idx, int bits, unsigned n, u32 bswapmask)
{
unsigned long first, last;
int const shift = dst_idx-src_idx;
int left, right;
- first = FB_SHIFT_HIGH(~0UL, dst_idx);
- last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+ first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
+ last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
if (!shift) {
// Same alignment for source and dest
@@ -94,29 +94,34 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
}
} else {
+ /* Different alignment for source and dest */
unsigned long d0, d1;
int m;
- // Different alignment for source and dest
right = shift & (bits - 1);
left = -shift & (bits - 1);
+ bswapmask &= shift;
if (dst_idx+n <= bits) {
// Single destination word
if (last)
first &= last;
+ d0 = FB_READL(src);
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
if (shift > 0) {
// Single source word
- FB_WRITEL( comp( FB_READL(src) >> right, FB_READL(dst), first), dst);
+ d0 >>= right;
} else if (src_idx+n <= bits) {
// Single source word
- FB_WRITEL( comp(FB_READL(src) << left, FB_READL(dst), first), dst);
+ d0 <<= left;;
} else {
// 2 source words
- d0 = FB_READL(src++);
- d1 = FB_READL(src);
- FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst);
+ d1 = FB_READL(src + 1);
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
+ d0 = d0<<left | d1>>right;
}
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
} else {
// Multiple destination words
/** We must always remember the last value read, because in case
@@ -125,25 +130,31 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
overlap with the current long from SRC. We store this value in
'd0'. */
d0 = FB_READL(src++);
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
// Leading bits
if (shift > 0) {
// Single source word
- FB_WRITEL( comp(d0 >> right, FB_READL(dst), first), dst);
+ d1 = d0;
+ d0 >>= right;
dst++;
n -= bits - dst_idx;
} else {
// 2 source words
d1 = FB_READL(src++);
- FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst);
- d0 = d1;
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
+
+ d0 = d0<<left | d1>>right;
dst++;
n -= bits - dst_idx;
}
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
+ d0 = d1;
// Main chunk
m = n % bits;
n /= bits;
- while (n >= 4) {
+ while ((n >= 4) && !bswapmask) {
d1 = FB_READL(src++);
FB_WRITEL(d0 << left | d1 >> right, dst++);
d0 = d1;
@@ -160,7 +171,10 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
}
while (n--) {
d1 = FB_READL(src++);
- FB_WRITEL(d0 << left | d1 >> right, dst++);
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
+ d0 = d0 << left | d1 >> right;
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(d0, dst++);
d0 = d1;
}
@@ -168,12 +182,16 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
if (last) {
if (m <= right) {
// Single source word
- FB_WRITEL( comp(d0 << left, FB_READL(dst), last), dst);
+ d0 <<= left;
} else {
// 2 source words
d1 = FB_READL(src);
- FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), last), dst);
+ d1 = fb_rev_pixels_in_long(d1,
+ bswapmask);
+ d0 = d0<<left | d1>>right;
}
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
}
}
}
@@ -185,7 +203,7 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
static void
bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src,
- int src_idx, int bits, unsigned n)
+ int src_idx, int bits, unsigned n, u32 bswapmask)
{
unsigned long first, last;
int shift;
@@ -203,8 +221,8 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
shift = dst_idx-src_idx;
- first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx);
- last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits)));
+ first = fb_shifted_pixels_mask_long(bits - 1 - dst_idx, bswapmask);
+ last = ~fb_shifted_pixels_mask_long(bits - 1 - ((dst_idx-n) % bits), bswapmask);
if (!shift) {
// Same alignment for source and dest
@@ -247,24 +265,32 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
}
} else {
// Different alignment for source and dest
+ unsigned long d0, d1;
+ int m;
int const left = -shift & (bits-1);
int const right = shift & (bits-1);
+ bswapmask &= shift;
if ((unsigned long)dst_idx+1 >= n) {
// Single destination word
if (last)
first &= last;
+ d0 = FB_READL(src);
if (shift < 0) {
// Single source word
- FB_WRITEL( comp( FB_READL(src)<<left, FB_READL(dst), first), dst);
+ d0 <<= left;
} else if (1+(unsigned long)src_idx >= n) {
// Single source word
- FB_WRITEL( comp( FB_READL(src)>>right, FB_READL(dst), first), dst);
+ d0 >>= right;
} else {
// 2 source words
- FB_WRITEL( comp( (FB_READL(src)>>right | FB_READL(src-1)<<left), FB_READL(dst), first), dst);
+ d1 = FB_READL(src - 1);
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
+ d0 = d0>>right | d1<<left;
}
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
} else {
// Multiple destination words
/** We must always remember the last value read, because in case
@@ -272,27 +298,30 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
1bpp), we always collect one full long for DST and that might
overlap with the current long from SRC. We store this value in
'd0'. */
- unsigned long d0, d1;
- int m;
d0 = FB_READL(src--);
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
// Leading bits
if (shift < 0) {
// Single source word
- FB_WRITEL( comp( (d0 << left), FB_READL(dst), first), dst);
+ d1 = d0;
+ d0 <<= left;
} else {
// 2 source words
d1 = FB_READL(src--);
- FB_WRITEL( comp( (d0>>right | d1<<left), FB_READL(dst), first), dst);
- d0 = d1;
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
+ d0 = d0>>right | d1<<left;
}
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
+ d0 = d1;
dst--;
n -= dst_idx+1;
// Main chunk
m = n % bits;
n /= bits;
- while (n >= 4) {
+ while ((n >= 4) && !bswapmask) {
d1 = FB_READL(src--);
FB_WRITEL(d0 >> right | d1 << left, dst--);
d0 = d1;
@@ -309,7 +338,10 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
}
while (n--) {
d1 = FB_READL(src--);
- FB_WRITEL(d0 >> right | d1 << left, dst--);
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
+ d0 = d0 >> right | d1 << left;
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(d0, dst--);
d0 = d1;
}
@@ -317,12 +349,16 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
if (last) {
if (m <= left) {
// Single source word
- FB_WRITEL( comp(d0 >> right, FB_READL(dst), last), dst);
+ d0 >>= right;
} else {
// 2 source words
d1 = FB_READL(src);
- FB_WRITEL( comp(d0>>right | d1<<left, FB_READL(dst), last), dst);
+ d1 = fb_rev_pixels_in_long(d1,
+ bswapmask);
+ d0 = d0>>right | d1<<left;
}
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
+ FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
}
}
}
@@ -336,6 +372,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
unsigned long __iomem *dst = NULL, *src = NULL;
int bits = BITS_PER_LONG, bytes = bits >> 3;
int dst_idx = 0, src_idx = 0, rev_copy = 0;
+ u32 bswapmask = fb_compute_bswapmask(p);
if (p->state != FBINFO_STATE_RUNNING)
return;
@@ -368,7 +405,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
src += src_idx >> (ffs(bits) - 1);
src_idx &= (bytes - 1);
bitcpy_rev(dst, dst_idx, src, src_idx, bits,
- width*p->var.bits_per_pixel);
+ width*p->var.bits_per_pixel, bswapmask);
}
} else {
while (height--) {
@@ -377,7 +414,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
src += src_idx >> (ffs(bits) - 1);
src_idx &= (bytes - 1);
bitcpy(dst, dst_idx, src, src_idx, bits,
- width*p->var.bits_per_pixel);
+ width*p->var.bits_per_pixel, bswapmask);
dst_idx += bits_per_line;
src_idx += bits_per_line;
}
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index 71623b4f8ca..23d70a12e4d 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -36,15 +36,16 @@
*/
static void
-bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits)
+bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
+ unsigned n, int bits, u32 bswapmask)
{
unsigned long first, last;
if (!n)
return;
- first = FB_SHIFT_HIGH(~0UL, dst_idx);
- last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+ first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
+ last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
if (dst_idx+n <= bits) {
// Single word
@@ -146,7 +147,8 @@ bitfill_unaligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
* Aligned pattern invert using 32/64-bit memory accesses
*/
static void
-bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits)
+bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
+ unsigned n, int bits, u32 bswapmask)
{
unsigned long val = pat, dat;
unsigned long first, last;
@@ -154,8 +156,8 @@ bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
if (!n)
return;
- first = FB_SHIFT_HIGH(~0UL, dst_idx);
- last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+ first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
+ last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
if (dst_idx+n <= bits) {
// Single word
@@ -303,8 +305,10 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
if (p->fbops->fb_sync)
p->fbops->fb_sync(p);
if (!left) {
+ u32 bswapmask = fb_compute_bswapmask(p);
void (*fill_op32)(unsigned long __iomem *dst, int dst_idx,
- unsigned long pat, unsigned n, int bits) = NULL;
+ unsigned long pat, unsigned n, int bits,
+ u32 bswapmask) = NULL;
switch (rect->rop) {
case ROP_XOR:
@@ -321,7 +325,7 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
while (height--) {
dst += dst_idx >> (ffs(bits) - 1);
dst_idx &= (bits - 1);
- fill_op32(dst, dst_idx, pat, width*bpp, bits);
+ fill_op32(dst, dst_idx, pat, width*bpp, bits, bswapmask);
dst_idx += p->fix.line_length*8;
}
} else {
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 261004473c8..f598907b42a 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -33,6 +33,7 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
+#include "fb_draw.h"
#define DEBUG
@@ -87,6 +88,7 @@ static inline void color_imageblit(const struct fb_image *image,
u32 null_bits = 32 - bpp;
u32 *palette = (u32 *) p->pseudo_palette;
const u8 *src = image->data;
+ u32 bswapmask = fb_compute_bswapmask(p);
dst2 = (u32 __iomem *) dst1;
for (i = image->height; i--; ) {
@@ -96,7 +98,7 @@ static inline void color_imageblit(const struct fb_image *image,
val = 0;
if (start_index) {
- u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index));
+ u32 start_mask = ~fb_shifted_pixels_mask_u32(start_index, bswapmask);
val = FB_READL(dst) & start_mask;
shift = start_index;
}
@@ -107,7 +109,7 @@ static inline void color_imageblit(const struct fb_image *image,
else
color = *src;
color <<= FB_LEFT_POS(bpp);
- val |= FB_SHIFT_HIGH(color, shift);
+ val |= FB_SHIFT_HIGH(color, shift ^ bswapmask);
if (shift >= null_bits) {
FB_WRITEL(val, dst++);
@@ -119,7 +121,7 @@ static inline void color_imageblit(const struct fb_image *image,
src++;
}
if (shift) {
- u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
+ u32 end_mask = fb_shifted_pixels_mask_u32(shift, bswapmask);
FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
}
@@ -147,7 +149,8 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
u32 spitch = (image->width+7)/8;
const u8 *src = image->data, *s;
u32 i, j, l;
-
+ u32 bswapmask = fb_compute_bswapmask(p);
+
dst2 = (u32 __iomem *) dst1;
fgcolor <<= FB_LEFT_POS(bpp);
bgcolor <<= FB_LEFT_POS(bpp);
@@ -161,7 +164,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
/* write leading bits */
if (start_index) {
- u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
+ u32 start_mask = ~fb_shifted_pixels_mask_u32(start_index, bswapmask);
val = FB_READL(dst) & start_mask;
shift = start_index;
}
@@ -169,7 +172,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
while (j--) {
l--;
color = (*s & (1 << l)) ? fgcolor : bgcolor;
- val |= FB_SHIFT_HIGH(color, shift);
+ val |= FB_SHIFT_HIGH(color, shift ^ bswapmask);
/* Did the bitshift spill bits to the next long? */
if (shift >= null_bits) {
@@ -184,7 +187,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
/* write trailing bits */
if (shift) {
- u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
+ u32 end_mask = fb_shifted_pixels_mask_u32(shift, bswapmask);
FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
}
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 8269d704ab2..f99cb77e7b4 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -45,7 +45,6 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <linux/selection.h>
#include <asm/pgtable.h>
#ifdef CONFIG_ZORRO
@@ -59,14 +58,13 @@
#endif
#ifdef CONFIG_PPC_PREP
#include <asm/machdep.h>
-#define isPReP (machine_is(prep))
+#define isPReP machine_is(prep)
#else
#define isPReP 0
#endif
-#include "video/vga.h"
-#include "video/cirrus.h"
-
+#include <video/vga.h>
+#include <video/cirrus.h>
/*****************************************************************
*
@@ -82,7 +80,8 @@
/* debug output */
#ifdef CIRRUSFB_DEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#define DPRINTK(fmt, args...) \
+ printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
#else
#define DPRINTK(fmt, args...)
#endif
@@ -90,19 +89,15 @@
/* debugging assertions */
#ifndef CIRRUSFB_NDEBUG
#define assert(expr) \
- if(!(expr)) { \
- printk( "Assertion failed! %s,%s,%s,line=%d\n",\
- #expr,__FILE__,__FUNCTION__,__LINE__); \
- }
+ if (!(expr)) { \
+ printk("Assertion failed! %s,%s,%s,line=%d\n", \
+ #expr, __FILE__, __FUNCTION__, __LINE__); \
+ }
#else
#define assert(expr)
#endif
-#define MB_ (1024*1024)
-#define KB_ (1024)
-
-#define MAX_NUM_BOARDS 7
-
+#define MB_ (1024 * 1024)
/*****************************************************************
*
@@ -111,7 +106,7 @@
*/
/* board types */
-typedef enum {
+enum cirrus_board {
BT_NONE = 0,
BT_SD64,
BT_PICCOLO,
@@ -121,13 +116,12 @@ typedef enum {
BT_ALPINE, /* GD543x/4x */
BT_GD5480,
BT_LAGUNA, /* GD546x */
-} cirrusfb_board_t;
-
+};
/*
* per-board-type information, used for enumerating and abstracting
* chip-specific information
- * NOTE: MUST be in the same order as cirrusfb_board_t in order to
+ * NOTE: MUST be in the same order as enum cirrus_board in order to
* use direct indexing on this array
* NOTE: '__initdata' cannot be used as some of this info
* is required at runtime. Maybe separate into an init-only and
@@ -139,7 +133,8 @@ static const struct cirrusfb_board_info_rec {
/* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
bool init_sr07 : 1; /* init SR07 during init_vgachip() */
bool init_sr1f : 1; /* write SR1F during init_vgachip() */
- bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
+ /* construct bit 19 of screen start address */
+ bool scrn_start_bit19 : 1;
/* initial SR07 value, then for each mode */
unsigned char sr07;
@@ -261,30 +256,28 @@ static const struct cirrusfb_board_info_rec {
}
};
-
#ifdef CONFIG_PCI
#define CHIP(id, btype) \
{ PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
static struct pci_device_id cirrusfb_pci_table[] = {
- CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ),
- CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ),
- CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ),
- CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */
- CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ),
- CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ),
- CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */
- CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */
- CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */
- CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */
- CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/
+ CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
+ CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
+ CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
+ CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
+ CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
+ CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
+ CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
+ CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
+ CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
+ CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
+ CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
{ 0, }
};
MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
#undef CHIP
#endif /* CONFIG_PCI */
-
#ifdef CONFIG_ZORRO
static const struct zorro_device_id cirrusfb_zorro_table[] = {
{
@@ -294,7 +287,7 @@ static const struct zorro_device_id cirrusfb_zorro_table[] = {
.id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
.driver_data = BT_PICCOLO,
}, {
- .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
+ .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
.driver_data = BT_PICASSO,
}, {
.id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
@@ -333,12 +326,7 @@ static const struct {
};
#endif /* CONFIG_ZORRO */
-
struct cirrusfb_regs {
- __u32 line_length; /* in BYTES! */
- __u32 visual;
- __u32 type;
-
long freq;
long nom;
long den;
@@ -364,37 +352,23 @@ struct cirrusfb_regs {
long VertBlankEnd;
};
-
-
#ifdef CIRRUSFB_DEBUG
-typedef enum {
- CRT,
- SEQ
-} cirrusfb_dbg_reg_class_t;
-#endif /* CIRRUSFB_DEBUG */
-
-
-
+enum cirrusfb_dbg_reg_class {
+ CRT,
+ SEQ
+};
+#endif /* CIRRUSFB_DEBUG */
/* info about board */
struct cirrusfb_info {
- struct fb_info *info;
-
- u8 __iomem *fbmem;
u8 __iomem *regbase;
- u8 __iomem *mem;
- unsigned long size;
- cirrusfb_board_t btype;
+ enum cirrus_board btype;
unsigned char SFR; /* Shadow of special function register */
- unsigned long fbmem_phys;
- unsigned long fbregs_phys;
-
struct cirrusfb_regs currentmode;
int blank_mode;
u32 pseudo_palette[16];
- struct { u8 red, green, blue, pad; } palette[256];
#ifdef CONFIG_ZORRO
struct zorro_dev *zdev;
@@ -402,12 +376,11 @@ struct cirrusfb_info {
#ifdef CONFIG_PCI
struct pci_dev *pdev;
#endif
- void (*unmap)(struct cirrusfb_info *cinfo);
+ void (*unmap)(struct fb_info *info);
};
-
static unsigned cirrusfb_def_mode = 1;
-static int noaccel = 0;
+static int noaccel;
/*
* Predefined Video Modes
@@ -441,7 +414,7 @@ static const struct {
.lower_margin = 8,
.hsync_len = 96,
.vsync_len = 4,
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED
}
}, {
@@ -502,27 +475,29 @@ static const struct {
/****************************************************************************/
/**** BEGIN PROTOTYPES ******************************************************/
-
/*--- Interface used by the world ------------------------------------------*/
-static int cirrusfb_init (void);
+static int cirrusfb_init(void);
#ifndef MODULE
-static int cirrusfb_setup (char *options);
+static int cirrusfb_setup(char *options);
#endif
-static int cirrusfb_open (struct fb_info *info, int user);
-static int cirrusfb_release (struct fb_info *info, int user);
-static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info);
-static int cirrusfb_check_var (struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int cirrusfb_set_par (struct fb_info *info);
-static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int cirrusfb_blank (int blank_mode, struct fb_info *info);
-static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region);
-static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image);
+static int cirrusfb_open(struct fb_info *info, int user);
+static int cirrusfb_release(struct fb_info *info, int user);
+static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info);
+static int cirrusfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+static int cirrusfb_set_par(struct fb_info *info);
+static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info);
+static int cirrusfb_blank(int blank_mode, struct fb_info *info);
+static void cirrusfb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *region);
+static void cirrusfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area);
+static void cirrusfb_imageblit(struct fb_info *info,
+ const struct fb_image *image);
/* function table of the above functions */
static struct fb_ops cirrusfb_ops = {
@@ -540,68 +515,68 @@ static struct fb_ops cirrusfb_ops = {
};
/*--- Hardware Specific Routines -------------------------------------------*/
-static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
+static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
struct cirrusfb_regs *regs,
- const struct fb_info *info);
+ struct fb_info *info);
/*--- Internal routines ----------------------------------------------------*/
-static void init_vgachip (struct cirrusfb_info *cinfo);
-static void switch_monitor (struct cirrusfb_info *cinfo, int on);
-static void WGen (const struct cirrusfb_info *cinfo,
- int regnum, unsigned char val);
-static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum);
-static void AttrOn (const struct cirrusfb_info *cinfo);
-static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val);
-static void WSFR (struct cirrusfb_info *cinfo, unsigned char val);
-static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val);
-static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
- unsigned char green,
- unsigned char blue);
+static void init_vgachip(struct fb_info *info);
+static void switch_monitor(struct cirrusfb_info *cinfo, int on);
+static void WGen(const struct cirrusfb_info *cinfo,
+ int regnum, unsigned char val);
+static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
+static void AttrOn(const struct cirrusfb_info *cinfo);
+static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
+static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
+static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
+static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
+ unsigned char red, unsigned char green, unsigned char blue);
#if 0
-static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
- unsigned char *green,
- unsigned char *blue);
+static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
+ unsigned char *red, unsigned char *green,
+ unsigned char *blue);
#endif
-static void cirrusfb_WaitBLT (u8 __iomem *regbase);
-static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
- u_short curx, u_short cury,
- u_short destx, u_short desty,
- u_short width, u_short height,
- u_short line_length);
-static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
- u_short x, u_short y,
- u_short width, u_short height,
- u_char color, u_short line_length);
-
-static void bestclock (long freq, long *best,
- long *nom, long *den,
- long *div, long maxfreq);
+static void cirrusfb_WaitBLT(u8 __iomem *regbase);
+static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
+ u_short curx, u_short cury,
+ u_short destx, u_short desty,
+ u_short width, u_short height,
+ u_short line_length);
+static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
+ u_short x, u_short y,
+ u_short width, u_short height,
+ u_char color, u_short line_length);
+
+static void bestclock(long freq, long *best,
+ long *nom, long *den,
+ long *div, long maxfreq);
#ifdef CIRRUSFB_DEBUG
-static void cirrusfb_dump (void);
-static void cirrusfb_dbg_reg_dump (caddr_t regbase);
-static void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...);
-static void cirrusfb_dbg_print_byte (const char *name, unsigned char val);
+static void cirrusfb_dump(void);
+static void cirrusfb_dbg_reg_dump(caddr_t regbase);
+static void cirrusfb_dbg_print_regs(caddr_t regbase,
+ enum cirrusfb_dbg_reg_class reg_class, ...);
+static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
#endif /* CIRRUSFB_DEBUG */
/*** END PROTOTYPES ********************************************************/
/*****************************************************************************/
/*** BEGIN Interface Used by the World ***************************************/
-static int opencount = 0;
+static int opencount;
/*--- Open /dev/fbx ---------------------------------------------------------*/
-static int cirrusfb_open (struct fb_info *info, int user)
+static int cirrusfb_open(struct fb_info *info, int user)
{
if (opencount++ == 0)
- switch_monitor (info->par, 1);
+ switch_monitor(info->par, 1);
return 0;
}
/*--- Close /dev/fbx --------------------------------------------------------*/
-static int cirrusfb_release (struct fb_info *info, int user)
+static int cirrusfb_release(struct fb_info *info, int user)
{
if (--opencount == 0)
- switch_monitor (info->par, 0);
+ switch_monitor(info->par, 0);
return 0;
}
@@ -610,11 +585,11 @@ static int cirrusfb_release (struct fb_info *info, int user)
/**** BEGIN Hardware specific Routines **************************************/
/* Get a good MCLK value */
-static long cirrusfb_get_mclk (long freq, int bpp, long *div)
+static long cirrusfb_get_mclk(long freq, int bpp, long *div)
{
long mclk;
- assert (div != NULL);
+ assert(div != NULL);
/* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
* Assume a 64-bit data path for now. The formula is:
@@ -624,23 +599,23 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
mclk = (mclk * 12) / 10;
if (mclk < 50000)
mclk = 50000;
- DPRINTK ("Use MCLK of %ld kHz\n", mclk);
+ DPRINTK("Use MCLK of %ld kHz\n", mclk);
/* Calculate value for SR1F. Multiply by 2 so we can round up. */
mclk = ((mclk * 16) / 14318);
mclk = (mclk + 1) / 2;
- DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk);
+ DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
/* Determine if we should use MCLK instead of VCLK, and if so, what we
* should divide it by to get VCLK */
switch (freq) {
case 24751 ... 25249:
*div = 2;
- DPRINTK ("Using VCLK = MCLK/2\n");
+ DPRINTK("Using VCLK = MCLK/2\n");
break;
case 49501 ... 50499:
*div = 1;
- DPRINTK ("Using VCLK = MCLK\n");
+ DPRINTK("Using VCLK = MCLK\n");
break;
default:
*div = 0;
@@ -653,7 +628,6 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
static int cirrusfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- struct cirrusfb_info *cinfo = info->par;
int nom, den; /* translyting from pixels->bytes */
int yres, i;
static struct { int xres, yres; } modes[] =
@@ -665,63 +639,55 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
{ -1, -1 } };
switch (var->bits_per_pixel) {
- case 0 ... 1:
- var->bits_per_pixel = 1;
+ case 1:
nom = 4;
den = 8;
break; /* 8 pixel per byte, only 1/4th of mem usable */
- case 2 ... 8:
- var->bits_per_pixel = 8;
- nom = 1;
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ nom = var->bits_per_pixel / 8;
den = 1;
break; /* 1 pixel == 1 byte */
- case 9 ... 16:
- var->bits_per_pixel = 16;
- nom = 2;
- den = 1;
- break; /* 2 bytes per pixel */
- case 17 ... 24:
- var->bits_per_pixel = 24;
- nom = 3;
- den = 1;
- break; /* 3 bytes per pixel */
- case 25 ... 32:
- var->bits_per_pixel = 32;
- nom = 4;
- den = 1;
- break; /* 4 bytes per pixel */
default:
- printk ("cirrusfb: mode %dx%dx%d rejected...color depth not supported.\n",
+ printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
+ "color depth not supported.\n",
var->xres, var->yres, var->bits_per_pixel);
- DPRINTK ("EXIT - EINVAL error\n");
+ DPRINTK("EXIT - EINVAL error\n");
return -EINVAL;
}
- if (var->xres * nom / den * var->yres > cinfo->size) {
- printk ("cirrusfb: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
+ if (var->xres * nom / den * var->yres > info->screen_size) {
+ printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
+ "resolution too high to fit into video memory!\n",
var->xres, var->yres, var->bits_per_pixel);
- DPRINTK ("EXIT - EINVAL error\n");
+ DPRINTK("EXIT - EINVAL error\n");
return -EINVAL;
}
/* use highest possible virtual resolution */
if (var->xres_virtual == -1 &&
var->yres_virtual == -1) {
- printk ("cirrusfb: using maximum available virtual resolution\n");
+ printk(KERN_INFO
+ "cirrusfb: using maximum available virtual resolution\n");
for (i = 0; modes[i].xres != -1; i++) {
- if (modes[i].xres * nom / den * modes[i].yres < cinfo->size / 2)
+ int size = modes[i].xres * nom / den * modes[i].yres;
+ if (size < info->screen_size / 2)
break;
}
if (modes[i].xres == -1) {
- printk ("cirrusfb: could not find a virtual resolution that fits into video memory!!\n");
- DPRINTK ("EXIT - EINVAL error\n");
+ printk(KERN_ERR "cirrusfb: could not find a virtual "
+ "resolution that fits into video memory!!\n");
+ DPRINTK("EXIT - EINVAL error\n");
return -EINVAL;
}
var->xres_virtual = modes[i].xres;
var->yres_virtual = modes[i].yres;
- printk ("cirrusfb: virtual resolution set to maximum of %dx%d\n",
- var->xres_virtual, var->yres_virtual);
+ printk(KERN_INFO "cirrusfb: virtual resolution set to "
+ "maximum of %dx%d\n", var->xres_virtual,
+ var->yres_virtual);
}
if (var->xres_virtual < var->xres)
@@ -744,23 +710,19 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
case 1:
var->red.offset = 0;
var->red.length = 1;
- var->green.offset = 0;
- var->green.length = 1;
- var->blue.offset = 0;
- var->blue.length = 1;
+ var->green = var->red;
+ var->blue = var->red;
break;
case 8:
var->red.offset = 0;
var->red.length = 6;
- var->green.offset = 0;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 6;
+ var->green = var->red;
+ var->blue = var->red;
break;
case 16:
- if(isPReP) {
+ if (isPReP) {
var->red.offset = 2;
var->green.offset = -3;
var->blue.offset = 8;
@@ -775,22 +737,8 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
break;
case 24:
- if(isPReP) {
- var->red.offset = 8;
- var->green.offset = 16;
- var->blue.offset = 24;
- } else {
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- }
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- break;
-
case 32:
- if(isPReP) {
+ if (isPReP) {
var->red.offset = 8;
var->green.offset = 16;
var->blue.offset = 24;
@@ -825,54 +773,42 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
yres = (yres + 1) / 2;
if (yres >= 1280) {
- printk (KERN_WARNING "cirrusfb: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n");
- DPRINTK ("EXIT - EINVAL error\n");
+ printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; "
+ "special treatment required! (TODO)\n");
+ DPRINTK("EXIT - EINVAL error\n");
return -EINVAL;
}
return 0;
}
-static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
+static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
struct cirrusfb_regs *regs,
- const struct fb_info *info)
+ struct fb_info *info)
{
long freq;
long maxclock;
- int maxclockidx = 0;
+ int maxclockidx = var->bits_per_pixel >> 3;
struct cirrusfb_info *cinfo = info->par;
int xres, hfront, hsync, hback;
int yres, vfront, vsync, vback;
- switch(var->bits_per_pixel) {
+ switch (var->bits_per_pixel) {
case 1:
- regs->line_length = var->xres_virtual / 8;
- regs->visual = FB_VISUAL_MONO10;
- maxclockidx = 0;
+ info->fix.line_length = var->xres_virtual / 8;
+ info->fix.visual = FB_VISUAL_MONO10;
break;
case 8:
- regs->line_length = var->xres_virtual;
- regs->visual = FB_VISUAL_PSEUDOCOLOR;
- maxclockidx = 1;
+ info->fix.line_length = var->xres_virtual;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
break;
case 16:
- regs->line_length = var->xres_virtual * 2;
- regs->visual = FB_VISUAL_DIRECTCOLOR;
- maxclockidx = 2;
- break;
-
case 24:
- regs->line_length = var->xres_virtual * 3;
- regs->visual = FB_VISUAL_DIRECTCOLOR;
- maxclockidx = 3;
- break;
-
case 32:
- regs->line_length = var->xres_virtual * 4;
- regs->visual = FB_VISUAL_DIRECTCOLOR;
- maxclockidx = 4;
+ info->fix.line_length = var->xres_virtual * maxclockidx;
+ info->fix.visual = FB_VISUAL_DIRECTCOLOR;
break;
default:
@@ -882,12 +818,12 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
break;
}
- regs->type = FB_TYPE_PACKED_PIXELS;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
/* convert from ps to kHz */
- freq = 1000000000 / var->pixclock;
+ freq = PICOS2KHZ(var->pixclock);
- DPRINTK ("desired pixclock: %ld kHz\n", freq);
+ DPRINTK("desired pixclock: %ld kHz\n", freq);
maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
regs->multiplexing = 0;
@@ -902,8 +838,9 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
break;
default:
- printk (KERN_WARNING "cirrusfb: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock);
- DPRINTK ("EXIT - return -EINVAL\n");
+ printk(KERN_ERR "cirrusfb: Frequency greater "
+ "than maxclock (%ld kHz)\n", maxclock);
+ DPRINTK("EXIT - return -EINVAL\n");
return -EINVAL;
}
}
@@ -914,14 +851,16 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
case 16:
case 32:
if (regs->HorizRes <= 800)
- freq /= 2; /* Xbh has this type of clock for 32-bit */
+ /* Xbh has this type of clock for 32-bit */
+ freq /= 2;
break;
}
#endif
- bestclock (freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
- maxclock);
- regs->mclk = cirrusfb_get_mclk (freq, var->bits_per_pixel, &regs->divMCLK);
+ bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
+ maxclock);
+ regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
+ &regs->divMCLK);
xres = var->xres;
hfront = var->right_margin;
@@ -948,7 +887,8 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
regs->HorizDispEnd = xres / 8 - 1;
regs->HorizBlankStart = xres / 8;
- regs->HorizBlankEnd = regs->HorizTotal + 5; /* does not count with "-5" */
+ /* does not count with "-5" */
+ regs->HorizBlankEnd = regs->HorizTotal + 5;
regs->HorizSyncStart = (xres + hfront) / 8 + 1;
regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
@@ -976,23 +916,23 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
return 0;
}
-
-static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int div)
+static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
+ int div)
{
- assert (cinfo != NULL);
+ assert(cinfo != NULL);
if (div == 2) {
/* VCLK = MCLK/2 */
- unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E);
- vga_wseq (cinfo->regbase, CL_SEQR1E, old | 0x1);
- vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
+ unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
+ vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
+ vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
} else if (div == 1) {
/* VCLK = MCLK */
- unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E);
- vga_wseq (cinfo->regbase, CL_SEQR1E, old & ~0x1);
- vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
+ unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
+ vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
+ vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
} else {
- vga_wseq (cinfo->regbase, CL_SEQR1F, val & 0x3f);
+ vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
}
}
@@ -1001,7 +941,7 @@ static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int d
actually writes the values for a new video mode into the hardware,
**************************************************************************/
-static int cirrusfb_set_par_foo (struct fb_info *info)
+static int cirrusfb_set_par_foo(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
struct fb_var_screeninfo *var = &info->var;
@@ -1011,15 +951,15 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
int offset = 0, err;
const struct cirrusfb_board_info_rec *bi;
- DPRINTK ("ENTER\n");
- DPRINTK ("Requested mode: %dx%dx%d\n",
+ DPRINTK("ENTER\n");
+ DPRINTK("Requested mode: %dx%dx%d\n",
var->xres, var->yres, var->bits_per_pixel);
- DPRINTK ("pixclock: %d\n", var->pixclock);
+ DPRINTK("pixclock: %d\n", var->pixclock);
- init_vgachip (cinfo);
+ init_vgachip(info);
err = cirrusfb_decode_var(var, &regs, info);
- if(err) {
+ if (err) {
/* should never happen */
DPRINTK("mode change aborted. invalid var.\n");
return -EINVAL;
@@ -1027,34 +967,35 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
bi = &cirrusfb_board_info[cinfo->btype];
-
/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
- vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
+ vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
/* if debugging is enabled, all parameters get output before writing */
- DPRINTK ("CRT0: %ld\n", regs.HorizTotal);
- vga_wcrt (regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
+ DPRINTK("CRT0: %ld\n", regs.HorizTotal);
+ vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
- DPRINTK ("CRT1: %ld\n", regs.HorizDispEnd);
- vga_wcrt (regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
+ DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
+ vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
- DPRINTK ("CRT2: %ld\n", regs.HorizBlankStart);
- vga_wcrt (regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
+ DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
+ vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
- DPRINTK ("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32); /* + 128: Compatible read */
- vga_wcrt (regbase, VGA_CRTC_H_BLANK_END, 128 + (regs.HorizBlankEnd % 32));
+ /* + 128: Compatible read */
+ DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
+ vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
+ 128 + (regs.HorizBlankEnd % 32));
- DPRINTK ("CRT4: %ld\n", regs.HorizSyncStart);
- vga_wcrt (regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
+ DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
+ vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
tmp = regs.HorizSyncEnd % 32;
if (regs.HorizBlankEnd & 32)
tmp += 128;
- DPRINTK ("CRT5: %d\n", tmp);
- vga_wcrt (regbase, VGA_CRTC_H_SYNC_END, tmp);
+ DPRINTK("CRT5: %d\n", tmp);
+ vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
- DPRINTK ("CRT6: %ld\n", regs.VertTotal & 0xff);
- vga_wcrt (regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
+ DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
tmp = 16; /* LineCompare bit #9 */
if (regs.VertTotal & 256)
@@ -1071,34 +1012,34 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
tmp |= 64;
if (regs.VertSyncStart & 512)
tmp |= 128;
- DPRINTK ("CRT7: %d\n", tmp);
- vga_wcrt (regbase, VGA_CRTC_OVERFLOW, tmp);
+ DPRINTK("CRT7: %d\n", tmp);
+ vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
tmp = 0x40; /* LineCompare bit #8 */
if (regs.VertBlankStart & 512)
tmp |= 0x20;
if (var->vmode & FB_VMODE_DOUBLE)
tmp |= 0x80;
- DPRINTK ("CRT9: %d\n", tmp);
- vga_wcrt (regbase, VGA_CRTC_MAX_SCAN, tmp);
+ DPRINTK("CRT9: %d\n", tmp);
+ vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
- DPRINTK ("CRT10: %ld\n", regs.VertSyncStart & 0xff);
- vga_wcrt (regbase, VGA_CRTC_V_SYNC_START, (regs.VertSyncStart & 0xff));
+ DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
- DPRINTK ("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
- vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, (regs.VertSyncEnd % 16 + 64 + 32));
+ DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
+ vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
- DPRINTK ("CRT12: %ld\n", regs.VertDispEnd & 0xff);
- vga_wcrt (regbase, VGA_CRTC_V_DISP_END, (regs.VertDispEnd & 0xff));
+ DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
- DPRINTK ("CRT15: %ld\n", regs.VertBlankStart & 0xff);
- vga_wcrt (regbase, VGA_CRTC_V_BLANK_START, (regs.VertBlankStart & 0xff));
+ DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
- DPRINTK ("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
- vga_wcrt (regbase, VGA_CRTC_V_BLANK_END, (regs.VertBlankEnd & 0xff));
+ DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
- DPRINTK ("CRT18: 0xff\n");
- vga_wcrt (regbase, VGA_CRTC_LINE_COMPARE, 0xff);
+ DPRINTK("CRT18: 0xff\n");
+ vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
tmp = 0;
if (var->vmode & FB_VMODE_INTERLACED)
@@ -1112,57 +1053,63 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
if (regs.VertBlankEnd & 512)
tmp |= 128;
- DPRINTK ("CRT1a: %d\n", tmp);
- vga_wcrt (regbase, CL_CRT1A, tmp);
+ DPRINTK("CRT1a: %d\n", tmp);
+ vga_wcrt(regbase, CL_CRT1A, tmp);
/* set VCLK0 */
/* hardware RefClock: 14.31818 MHz */
/* formula: VClk = (OSC * N) / (D * (1+P)) */
/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
- vga_wseq (regbase, CL_SEQRB, regs.nom);
+ vga_wseq(regbase, CL_SEQRB, regs.nom);
tmp = regs.den << 1;
if (regs.div != 0)
tmp |= 1;
+ /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
if ((cinfo->btype == BT_SD64) ||
(cinfo->btype == BT_ALPINE) ||
(cinfo->btype == BT_GD5480))
- tmp |= 0x80; /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
+ tmp |= 0x80;
- DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp);
- vga_wseq (regbase, CL_SEQR1B, tmp);
+ DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
+ vga_wseq(regbase, CL_SEQR1B, tmp);
if (regs.VertRes >= 1024)
/* 1280x1024 */
- vga_wcrt (regbase, VGA_CRTC_MODE, 0xc7);
+ vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
else
/* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
* address wrap, no compat. */
- vga_wcrt (regbase, VGA_CRTC_MODE, 0xc3);
+ vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
-/* HAEH? vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20); * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
+/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
+ * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
/* don't know if it would hurt to also program this if no interlaced */
/* mode is used, but I feel better this way.. :-) */
if (var->vmode & FB_VMODE_INTERLACED)
- vga_wcrt (regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
+ vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
else
- vga_wcrt (regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
+ vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
- vga_wseq (regbase, VGA_SEQ_CHARACTER_MAP, 0);
+ vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
/* adjust horizontal/vertical sync type (low/high) */
- tmp = 0x03; /* enable display memory & CRTC I/O address for color mode */
+ /* enable display memory & CRTC I/O address for color mode */
+ tmp = 0x03;
if (var->sync & FB_SYNC_HOR_HIGH_ACT)
tmp |= 0x40;
if (var->sync & FB_SYNC_VERT_HIGH_ACT)
tmp |= 0x80;
- WGen (cinfo, VGA_MIS_W, tmp);
+ WGen(cinfo, VGA_MIS_W, tmp);
- vga_wcrt (regbase, VGA_CRTC_PRESET_ROW, 0); /* Screen A Preset Row-Scan register */
- vga_wcrt (regbase, VGA_CRTC_CURSOR_START, 0); /* text cursor on and start line */
- vga_wcrt (regbase, VGA_CRTC_CURSOR_END, 31); /* text cursor end line */
+ /* Screen A Preset Row-Scan register */
+ vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
+ /* text cursor on and start line */
+ vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
+ /* text cursor end line */
+ vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
/******************************************************
*
@@ -1172,8 +1119,8 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
/* programming for different color depths */
if (var->bits_per_pixel == 1) {
- DPRINTK ("cirrusfb: preparing for 1 bit deep display\n");
- vga_wgfx (regbase, VGA_GFX_MODE, 0); /* mode register */
+ DPRINTK("cirrusfb: preparing for 1 bit deep display\n");
+ vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
/* SR07 */
switch (cinfo->btype) {
@@ -1184,71 +1131,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
case BT_PICASSO4:
case BT_ALPINE:
case BT_GD5480:
- DPRINTK (" (for GD54xx)\n");
- vga_wseq (regbase, CL_SEQR7,
+ DPRINTK(" (for GD54xx)\n");
+ vga_wseq(regbase, CL_SEQR7,
regs.multiplexing ?
bi->sr07_1bpp_mux : bi->sr07_1bpp);
break;
case BT_LAGUNA:
- DPRINTK (" (for GD546x)\n");
- vga_wseq (regbase, CL_SEQR7,
- vga_rseq (regbase, CL_SEQR7) & ~0x01);
+ DPRINTK(" (for GD546x)\n");
+ vga_wseq(regbase, CL_SEQR7,
+ vga_rseq(regbase, CL_SEQR7) & ~0x01);
break;
default:
- printk (KERN_WARNING "cirrusfb: unknown Board\n");
+ printk(KERN_WARNING "cirrusfb: unknown Board\n");
break;
}
/* Extended Sequencer Mode */
switch (cinfo->btype) {
case BT_SD64:
- /* setting the SEQRF on SD64 is not necessary (only during init) */
- DPRINTK ("(for SD64)\n");
- vga_wseq (regbase, CL_SEQR1F, 0x1a); /* MCLK select */
+ /* setting the SEQRF on SD64 is not necessary
+ * (only during init)
+ */
+ DPRINTK("(for SD64)\n");
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x1a);
break;
case BT_PICCOLO:
- DPRINTK ("(for Piccolo)\n");
-/* ### ueberall 0x22? */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
+ case BT_SPECTRUM:
+ DPRINTK("(for Piccolo/Spectrum)\n");
+ /* ### ueberall 0x22? */
+ /* ##vorher 1c MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
+ /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
+ vga_wseq(regbase, CL_SEQRF, 0xb0);
break;
case BT_PICASSO:
- DPRINTK ("(for Picasso)\n");
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 22 MCLK select */
- vga_wseq (regbase, CL_SEQRF, 0xd0); /* ## vorher d0 avoid FIFO underruns..? */
- break;
-
- case BT_SPECTRUM:
- DPRINTK ("(for Spectrum)\n");
-/* ### ueberall 0x22? */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */
+ DPRINTK("(for Picasso)\n");
+ /* ##vorher 22 MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
+ /* ## vorher d0 avoid FIFO underruns..? */
+ vga_wseq(regbase, CL_SEQRF, 0xd0);
break;
case BT_PICASSO4:
case BT_ALPINE:
case BT_GD5480:
case BT_LAGUNA:
- DPRINTK (" (for GD54xx)\n");
+ DPRINTK(" (for GD54xx)\n");
/* do nothing */
break;
default:
- printk (KERN_WARNING "cirrusfb: unknown Board\n");
+ printk(KERN_WARNING "cirrusfb: unknown Board\n");
break;
}
- WGen (cinfo, VGA_PEL_MSK, 0x01); /* pixel mask: pass-through for first plane */
+ /* pixel mask: pass-through for first plane */
+ WGen(cinfo, VGA_PEL_MSK, 0x01);
if (regs.multiplexing)
- WHDR (cinfo, 0x4a); /* hidden dac reg: 1280x1024 */
+ /* hidden dac reg: 1280x1024 */
+ WHDR(cinfo, 0x4a);
else
- WHDR (cinfo, 0); /* hidden dac: nothing */
- vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x06); /* memory mode: odd/even, ext. memory */
- vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0x01); /* plane mask: only write to first plane */
+ /* hidden dac: nothing */
+ WHDR(cinfo, 0);
+ /* memory mode: odd/even, ext. memory */
+ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
+ /* plane mask: only write to first plane */
+ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
offset = var->xres_virtual / 16;
}
@@ -1259,7 +1212,7 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
*/
else if (var->bits_per_pixel == 8) {
- DPRINTK ("cirrusfb: preparing for 8 bit deep display\n");
+ DPRINTK("cirrusfb: preparing for 8 bit deep display\n");
switch (cinfo->btype) {
case BT_SD64:
case BT_PICCOLO:
@@ -1268,75 +1221,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
case BT_PICASSO4:
case BT_ALPINE:
case BT_GD5480:
- DPRINTK (" (for GD54xx)\n");
- vga_wseq (regbase, CL_SEQR7,
+ DPRINTK(" (for GD54xx)\n");
+ vga_wseq(regbase, CL_SEQR7,
regs.multiplexing ?
bi->sr07_8bpp_mux : bi->sr07_8bpp);
break;
case BT_LAGUNA:
- DPRINTK (" (for GD546x)\n");
- vga_wseq (regbase, CL_SEQR7,
- vga_rseq (regbase, CL_SEQR7) | 0x01);
+ DPRINTK(" (for GD546x)\n");
+ vga_wseq(regbase, CL_SEQR7,
+ vga_rseq(regbase, CL_SEQR7) | 0x01);
break;
default:
- printk (KERN_WARNING "cirrusfb: unknown Board\n");
+ printk(KERN_WARNING "cirrusfb: unknown Board\n");
break;
}
switch (cinfo->btype) {
case BT_SD64:
- vga_wseq (regbase, CL_SEQR1F, 0x1d); /* MCLK select */
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x1d);
break;
case BT_PICCOLO:
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- break;
-
case BT_PICASSO:
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- break;
-
case BT_SPECTRUM:
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ /* ### vorher 1c MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
+ /* Fast Page-Mode writes */
+ vga_wseq(regbase, CL_SEQRF, 0xb0);
break;
case BT_PICASSO4:
#ifdef CONFIG_ZORRO
- vga_wseq (regbase, CL_SEQRF, 0xb8); /* ### INCOMPLETE!! */
+ /* ### INCOMPLETE!! */
+ vga_wseq(regbase, CL_SEQRF, 0xb8);
#endif
-/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */
+/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
break;
case BT_ALPINE:
- DPRINTK (" (for GD543x)\n");
- cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK);
+ DPRINTK(" (for GD543x)\n");
+ cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
/* We already set SRF and SR1F */
break;
case BT_GD5480:
case BT_LAGUNA:
- DPRINTK (" (for GD54xx)\n");
+ DPRINTK(" (for GD54xx)\n");
/* do nothing */
break;
default:
- printk (KERN_WARNING "cirrusfb: unknown Board\n");
+ printk(KERN_WARNING "cirrusfb: unknown Board\n");
break;
}
- vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */
- WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */
+ /* mode register: 256 color mode */
+ vga_wgfx(regbase, VGA_GFX_MODE, 64);
+ /* pixel mask: pass-through all planes */
+ WGen(cinfo, VGA_PEL_MSK, 0xff);
if (regs.multiplexing)
- WHDR (cinfo, 0x4a); /* hidden dac reg: 1280x1024 */
+ /* hidden dac reg: 1280x1024 */
+ WHDR(cinfo, 0x4a);
else
- WHDR (cinfo, 0); /* hidden dac: nothing */
- vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */
- vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */
+ /* hidden dac: nothing */
+ WHDR(cinfo, 0);
+ /* memory mode: chain4, ext. memory */
+ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
+ /* plane mask: enable writing to all 4 planes */
+ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
offset = var->xres_virtual / 8;
}
@@ -1347,72 +1302,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
*/
else if (var->bits_per_pixel == 16) {
- DPRINTK ("cirrusfb: preparing for 16 bit deep display\n");
+ DPRINTK("cirrusfb: preparing for 16 bit deep display\n");
switch (cinfo->btype) {
case BT_SD64:
- vga_wseq (regbase, CL_SEQR7, 0xf7); /* Extended Sequencer Mode: 256c col. mode */
- vga_wseq (regbase, CL_SEQR1F, 0x1e); /* MCLK select */
+ /* Extended Sequencer Mode: 256c col. mode */
+ vga_wseq(regbase, CL_SEQR7, 0xf7);
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x1e);
break;
case BT_PICCOLO:
- vga_wseq (regbase, CL_SEQR7, 0x87);
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
+ case BT_SPECTRUM:
+ vga_wseq(regbase, CL_SEQR7, 0x87);
+ /* Fast Page-Mode writes */
+ vga_wseq(regbase, CL_SEQRF, 0xb0);
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
case BT_PICASSO:
- vga_wseq (regbase, CL_SEQR7, 0x27);
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
- break;
-
- case BT_SPECTRUM:
- vga_wseq (regbase, CL_SEQR7, 0x87);
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
+ vga_wseq(regbase, CL_SEQR7, 0x27);
+ /* Fast Page-Mode writes */
+ vga_wseq(regbase, CL_SEQRF, 0xb0);
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
case BT_PICASSO4:
- vga_wseq (regbase, CL_SEQR7, 0x27);
-/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */
+ vga_wseq(regbase, CL_SEQR7, 0x27);
+/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
break;
case BT_ALPINE:
- DPRINTK (" (for GD543x)\n");
+ DPRINTK(" (for GD543x)\n");
if (regs.HorizRes >= 1024)
- vga_wseq (regbase, CL_SEQR7, 0xa7);
+ vga_wseq(regbase, CL_SEQR7, 0xa7);
else
- vga_wseq (regbase, CL_SEQR7, 0xa3);
- cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK);
+ vga_wseq(regbase, CL_SEQR7, 0xa3);
+ cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
break;
case BT_GD5480:
- DPRINTK (" (for GD5480)\n");
- vga_wseq (regbase, CL_SEQR7, 0x17);
+ DPRINTK(" (for GD5480)\n");
+ vga_wseq(regbase, CL_SEQR7, 0x17);
/* We already set SRF and SR1F */
break;
case BT_LAGUNA:
- DPRINTK (" (for GD546x)\n");
- vga_wseq (regbase, CL_SEQR7,
- vga_rseq (regbase, CL_SEQR7) & ~0x01);
+ DPRINTK(" (for GD546x)\n");
+ vga_wseq(regbase, CL_SEQR7,
+ vga_rseq(regbase, CL_SEQR7) & ~0x01);
break;
default:
- printk (KERN_WARNING "CIRRUSFB: unknown Board\n");
+ printk(KERN_WARNING "CIRRUSFB: unknown Board\n");
break;
}
- vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */
- WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */
+ /* mode register: 256 color mode */
+ vga_wgfx(regbase, VGA_GFX_MODE, 64);
+ /* pixel mask: pass-through all planes */
+ WGen(cinfo, VGA_PEL_MSK, 0xff);
#ifdef CONFIG_PCI
- WHDR (cinfo, 0xc0); /* Copy Xbh */
+ WHDR(cinfo, 0xc0); /* Copy Xbh */
#elif defined(CONFIG_ZORRO)
/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
- WHDR (cinfo, 0xa0); /* hidden dac reg: nothing special */
+ WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
#endif
- vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */
- vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */
+ /* memory mode: chain4, ext. memory */
+ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
+ /* plane mask: enable writing to all 4 planes */
+ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
offset = var->xres_virtual / 4;
}
@@ -1423,64 +1383,70 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
*/
else if (var->bits_per_pixel == 32) {
- DPRINTK ("cirrusfb: preparing for 24/32 bit deep display\n");
+ DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n");
switch (cinfo->btype) {
case BT_SD64:
- vga_wseq (regbase, CL_SEQR7, 0xf9); /* Extended Sequencer Mode: 256c col. mode */
- vga_wseq (regbase, CL_SEQR1F, 0x1e); /* MCLK select */
+ /* Extended Sequencer Mode: 256c col. mode */
+ vga_wseq(regbase, CL_SEQR7, 0xf9);
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x1e);
break;
case BT_PICCOLO:
- vga_wseq (regbase, CL_SEQR7, 0x85);
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
+ case BT_SPECTRUM:
+ vga_wseq(regbase, CL_SEQR7, 0x85);
+ /* Fast Page-Mode writes */
+ vga_wseq(regbase, CL_SEQRF, 0xb0);
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
case BT_PICASSO:
- vga_wseq (regbase, CL_SEQR7, 0x25);
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
- break;
-
- case BT_SPECTRUM:
- vga_wseq (regbase, CL_SEQR7, 0x85);
- vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
- vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
+ vga_wseq(regbase, CL_SEQR7, 0x25);
+ /* Fast Page-Mode writes */
+ vga_wseq(regbase, CL_SEQRF, 0xb0);
+ /* MCLK select */
+ vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
case BT_PICASSO4:
- vga_wseq (regbase, CL_SEQR7, 0x25);
-/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */
+ vga_wseq(regbase, CL_SEQR7, 0x25);
+/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
break;
case BT_ALPINE:
- DPRINTK (" (for GD543x)\n");
- vga_wseq (regbase, CL_SEQR7, 0xa9);
- cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK);
+ DPRINTK(" (for GD543x)\n");
+ vga_wseq(regbase, CL_SEQR7, 0xa9);
+ cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
break;
case BT_GD5480:
- DPRINTK (" (for GD5480)\n");
- vga_wseq (regbase, CL_SEQR7, 0x19);
+ DPRINTK(" (for GD5480)\n");
+ vga_wseq(regbase, CL_SEQR7, 0x19);
/* We already set SRF and SR1F */
break;
case BT_LAGUNA:
- DPRINTK (" (for GD546x)\n");
- vga_wseq (regbase, CL_SEQR7,
- vga_rseq (regbase, CL_SEQR7) & ~0x01);
+ DPRINTK(" (for GD546x)\n");
+ vga_wseq(regbase, CL_SEQR7,
+ vga_rseq(regbase, CL_SEQR7) & ~0x01);
break;
default:
- printk (KERN_WARNING "cirrusfb: unknown Board\n");
+ printk(KERN_WARNING "cirrusfb: unknown Board\n");
break;
}
- vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */
- WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */
- WHDR (cinfo, 0xc5); /* hidden dac reg: 8-8-8 mode (24 or 32) */
- vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */
- vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */
+ /* mode register: 256 color mode */
+ vga_wgfx(regbase, VGA_GFX_MODE, 64);
+ /* pixel mask: pass-through all planes */
+ WGen(cinfo, VGA_PEL_MSK, 0xff);
+ /* hidden dac reg: 8-8-8 mode (24 or 32) */
+ WHDR(cinfo, 0xc5);
+ /* memory mode: chain4, ext. memory */
+ vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
+ /* plane mask: enable writing to all 4 planes */
+ vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
offset = var->xres_virtual / 4;
}
@@ -1490,48 +1456,67 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
*
*/
- else {
- printk (KERN_ERR "cirrusfb: What's this?? requested color depth == %d.\n",
+ else
+ printk(KERN_ERR "cirrusfb: What's this?? "
+ " requested color depth == %d.\n",
var->bits_per_pixel);
- }
- vga_wcrt (regbase, VGA_CRTC_OFFSET, offset & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
tmp = 0x22;
if (offset & 0x100)
tmp |= 0x10; /* offset overflow bit */
- vga_wcrt (regbase, CL_CRT1B, tmp); /* screen start addr #16-18, fastpagemode cycles */
+ /* screen start addr #16-18, fastpagemode cycles */
+ vga_wcrt(regbase, CL_CRT1B, tmp);
if (cinfo->btype == BT_SD64 ||
cinfo->btype == BT_PICASSO4 ||
cinfo->btype == BT_ALPINE ||
cinfo->btype == BT_GD5480)
- vga_wcrt (regbase, CL_CRT1D, 0x00); /* screen start address bit 19 */
-
- vga_wcrt (regbase, VGA_CRTC_CURSOR_HI, 0); /* text cursor location high */
- vga_wcrt (regbase, VGA_CRTC_CURSOR_LO, 0); /* text cursor location low */
- vga_wcrt (regbase, VGA_CRTC_UNDERLINE, 0); /* underline row scanline = at very bottom */
-
- vga_wattr (regbase, VGA_ATC_MODE, 1); /* controller mode */
- vga_wattr (regbase, VGA_ATC_OVERSCAN, 0); /* overscan (border) color */
- vga_wattr (regbase, VGA_ATC_PLANE_ENABLE, 15); /* color plane enable */
- vga_wattr (regbase, CL_AR33, 0); /* pixel panning */
- vga_wattr (regbase, VGA_ATC_COLOR_PAGE, 0); /* color select */
+ /* screen start address bit 19 */
+ vga_wcrt(regbase, CL_CRT1D, 0x00);
+
+ /* text cursor location high */
+ vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
+ /* text cursor location low */
+ vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
+ /* underline row scanline = at very bottom */
+ vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
+
+ /* controller mode */
+ vga_wattr(regbase, VGA_ATC_MODE, 1);
+ /* overscan (border) color */
+ vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
+ /* color plane enable */
+ vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
+ /* pixel panning */
+ vga_wattr(regbase, CL_AR33, 0);
+ /* color select */
+ vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
/* [ EGS: SetOffset(); ] */
/* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
- AttrOn (cinfo);
-
- vga_wgfx (regbase, VGA_GFX_SR_VALUE, 0); /* set/reset register */
- vga_wgfx (regbase, VGA_GFX_SR_ENABLE, 0); /* set/reset enable */
- vga_wgfx (regbase, VGA_GFX_COMPARE_VALUE, 0); /* color compare */
- vga_wgfx (regbase, VGA_GFX_DATA_ROTATE, 0); /* data rotate */
- vga_wgfx (regbase, VGA_GFX_PLANE_READ, 0); /* read map select */
- vga_wgfx (regbase, VGA_GFX_MISC, 1); /* miscellaneous register */
- vga_wgfx (regbase, VGA_GFX_COMPARE_MASK, 15); /* color don't care */
- vga_wgfx (regbase, VGA_GFX_BIT_MASK, 255); /* bit mask */
-
- vga_wseq (regbase, CL_SEQR12, 0x0); /* graphics cursor attributes: nothing special */
+ AttrOn(cinfo);
+
+ /* set/reset register */
+ vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
+ /* set/reset enable */
+ vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
+ /* color compare */
+ vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
+ /* data rotate */
+ vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
+ /* read map select */
+ vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
+ /* miscellaneous register */
+ vga_wgfx(regbase, VGA_GFX_MISC, 1);
+ /* color don't care */
+ vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
+ /* bit mask */
+ vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
+
+ /* graphics cursor attributes: nothing special */
+ vga_wseq(regbase, CL_SEQR12, 0x0);
/* finally, turn on everything - turn off "FullBandwidth" bit */
/* also, set "DotClock%2" bit where requested */
@@ -1542,36 +1527,33 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
tmp |= 0x08;
*/
- vga_wseq (regbase, VGA_SEQ_CLOCK_MODE, tmp);
- DPRINTK ("CL_SEQR1: %d\n", tmp);
+ vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
+ DPRINTK("CL_SEQR1: %d\n", tmp);
cinfo->currentmode = regs;
- info->fix.type = regs.type;
- info->fix.visual = regs.visual;
- info->fix.line_length = regs.line_length;
/* pan to requested offset */
- cirrusfb_pan_display (var, info);
+ cirrusfb_pan_display(var, info);
#ifdef CIRRUSFB_DEBUG
- cirrusfb_dump ();
+ cirrusfb_dump();
#endif
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
return 0;
}
/* for some reason incomprehensible to me, cirrusfb requires that you write
* the registers twice for the settings to take..grr. -dte */
-static int cirrusfb_set_par (struct fb_info *info)
+static int cirrusfb_set_par(struct fb_info *info)
{
- cirrusfb_set_par_foo (info);
- return cirrusfb_set_par_foo (info);
+ cirrusfb_set_par_foo(info);
+ return cirrusfb_set_par_foo(info);
}
-static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
+static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
@@ -1584,34 +1566,18 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
green >>= (16 - info->var.green.length);
blue >>= (16 - info->var.blue.length);
- if (regno>=16)
+ if (regno >= 16)
return 1;
v = (red << info->var.red.offset) |
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
- switch (info->var.bits_per_pixel) {
- case 8:
- cinfo->pseudo_palette[regno] = v;
- break;
- case 16:
- cinfo->pseudo_palette[regno] = v;
- break;
- case 24:
- case 32:
- cinfo->pseudo_palette[regno] = v;
- break;
- }
+ cinfo->pseudo_palette[regno] = v;
return 0;
}
- cinfo->palette[regno].red = red;
- cinfo->palette[regno].green = green;
- cinfo->palette[regno].blue = blue;
-
- if (info->var.bits_per_pixel == 8) {
- WClut (cinfo, regno, red >> 10, green >> 10, blue >> 10);
- }
+ if (info->var.bits_per_pixel == 8)
+ WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
return 0;
@@ -1622,8 +1588,8 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
performs display panning - provided hardware permits this
**************************************************************************/
-static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
- struct fb_info *info)
+static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
int xoffset = 0;
int yoffset = 0;
@@ -1631,8 +1597,8 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
unsigned char tmp = 0, tmp2 = 0, xpix;
struct cirrusfb_info *cinfo = info->par;
- DPRINTK ("ENTER\n");
- DPRINTK ("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
+ DPRINTK("ENTER\n");
+ DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
/* no range checks for xoffset and yoffset, */
/* as fb_pan_display has already done this */
@@ -1645,7 +1611,7 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
xoffset = var->xoffset * info->var.bits_per_pixel / 8;
yoffset = var->yoffset;
- base = yoffset * cinfo->currentmode.line_length + xoffset;
+ base = yoffset * info->fix.line_length + xoffset;
if (info->var.bits_per_pixel == 1) {
/* base is already correct */
@@ -1655,11 +1621,13 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
xpix = (unsigned char) ((xoffset % 4) * 2);
}
- cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
+ cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
/* lower 8 + 8 bits of screen start address */
- vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, (unsigned char) (base & 0xff));
- vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, (unsigned char) (base >> 8));
+ vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
+ (unsigned char) (base & 0xff));
+ vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
+ (unsigned char) (base >> 8));
/* construct bits 16, 17 and 18 of screen start address */
if (base & 0x10000)
@@ -1669,50 +1637,49 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
if (base & 0x40000)
tmp |= 0x08;
- tmp2 = (vga_rcrt (cinfo->regbase, CL_CRT1B) & 0xf2) | tmp; /* 0xf2 is %11110010, exclude tmp bits */
- vga_wcrt (cinfo->regbase, CL_CRT1B, tmp2);
+ /* 0xf2 is %11110010, exclude tmp bits */
+ tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
+ vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
/* construct bit 19 of screen start address */
- if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
- tmp2 = 0;
- if (base & 0x80000)
- tmp2 = 0x80;
- vga_wcrt (cinfo->regbase, CL_CRT1D, tmp2);
- }
+ if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
+ vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
- /* write pixel panning value to AR33; this does not quite work in 8bpp */
- /* ### Piccolo..? Will this work? */
+ /* write pixel panning value to AR33; this does not quite work in 8bpp
+ *
+ * ### Piccolo..? Will this work?
+ */
if (info->var.bits_per_pixel == 1)
- vga_wattr (cinfo->regbase, CL_AR33, xpix);
+ vga_wattr(cinfo->regbase, CL_AR33, xpix);
- cirrusfb_WaitBLT (cinfo->regbase);
+ cirrusfb_WaitBLT(cinfo->regbase);
- DPRINTK ("EXIT\n");
- return (0);
+ DPRINTK("EXIT\n");
+ return 0;
}
-
-static int cirrusfb_blank (int blank_mode, struct fb_info *info)
+static int cirrusfb_blank(int blank_mode, struct fb_info *info)
{
/*
- * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
- * then the caller blanks by setting the CLUT (Color Look Up Table) to all
- * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
- * to e.g. a video mode which doesn't support it. Implements VESA suspend
- * and powerdown modes on hardware that supports disabling hsync/vsync:
- * blank_mode == 2: suspend vsync
- * blank_mode == 3: suspend hsync
- * blank_mode == 4: powerdown
+ * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+ * then the caller blanks by setting the CLUT (Color Look Up Table)
+ * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
+ * failed due to e.g. a video mode which doesn't support it.
+ * Implements VESA suspend and powerdown modes on hardware that
+ * supports disabling hsync/vsync:
+ * blank_mode == 2: suspend vsync
+ * blank_mode == 3: suspend hsync
+ * blank_mode == 4: powerdown
*/
unsigned char val;
struct cirrusfb_info *cinfo = info->par;
int current_mode = cinfo->blank_mode;
- DPRINTK ("ENTER, blank mode = %d\n", blank_mode);
+ DPRINTK("ENTER, blank mode = %d\n", blank_mode);
if (info->state != FBINFO_STATE_RUNNING ||
current_mode == blank_mode) {
- DPRINTK ("EXIT, returning 0\n");
+ DPRINTK("EXIT, returning 0\n");
return 0;
}
@@ -1720,17 +1687,19 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
if (current_mode == FB_BLANK_NORMAL ||
current_mode == FB_BLANK_UNBLANK) {
/* unblank the screen */
- val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE);
- vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); /* clear "FullBandwidth" bit */
+ val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
+ /* clear "FullBandwidth" bit */
+ vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
/* and undo VESA suspend trickery */
- vga_wgfx (cinfo->regbase, CL_GRE, 0x00);
+ vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
}
/* set new */
- if(blank_mode > FB_BLANK_NORMAL) {
+ if (blank_mode > FB_BLANK_NORMAL) {
/* blank the screen */
- val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE);
- vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); /* set "FullBandwidth" bit */
+ val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
+ /* set "FullBandwidth" bit */
+ vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
}
switch (blank_mode) {
@@ -1738,21 +1707,21 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
case FB_BLANK_NORMAL:
break;
case FB_BLANK_VSYNC_SUSPEND:
- vga_wgfx (cinfo->regbase, CL_GRE, 0x04);
+ vga_wgfx(cinfo->regbase, CL_GRE, 0x04);
break;
case FB_BLANK_HSYNC_SUSPEND:
- vga_wgfx (cinfo->regbase, CL_GRE, 0x02);
+ vga_wgfx(cinfo->regbase, CL_GRE, 0x02);
break;
case FB_BLANK_POWERDOWN:
- vga_wgfx (cinfo->regbase, CL_GRE, 0x06);
+ vga_wgfx(cinfo->regbase, CL_GRE, 0x06);
break;
default:
- DPRINTK ("EXIT, returning 1\n");
+ DPRINTK("EXIT, returning 1\n");
return 1;
}
cinfo->blank_mode = blank_mode;
- DPRINTK ("EXIT, returning 0\n");
+ DPRINTK("EXIT, returning 0\n");
/* Let fbcon do a soft blank for us */
return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
@@ -1761,45 +1730,51 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
/****************************************************************************/
/**** BEGIN Internal Routines ***********************************************/
-static void init_vgachip (struct cirrusfb_info *cinfo)
+static void init_vgachip(struct fb_info *info)
{
+ struct cirrusfb_info *cinfo = info->par;
const struct cirrusfb_board_info_rec *bi;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- assert (cinfo != NULL);
+ assert(cinfo != NULL);
bi = &cirrusfb_board_info[cinfo->btype];
/* reset board globally */
switch (cinfo->btype) {
case BT_PICCOLO:
- WSFR (cinfo, 0x01);
- udelay (500);
- WSFR (cinfo, 0x51);
- udelay (500);
+ WSFR(cinfo, 0x01);
+ udelay(500);
+ WSFR(cinfo, 0x51);
+ udelay(500);
break;
case BT_PICASSO:
- WSFR2 (cinfo, 0xff);
- udelay (500);
+ WSFR2(cinfo, 0xff);
+ udelay(500);
break;
case BT_SD64:
case BT_SPECTRUM:
- WSFR (cinfo, 0x1f);
- udelay (500);
- WSFR (cinfo, 0x4f);
- udelay (500);
+ WSFR(cinfo, 0x1f);
+ udelay(500);
+ WSFR(cinfo, 0x4f);
+ udelay(500);
break;
case BT_PICASSO4:
- vga_wcrt (cinfo->regbase, CL_CRT51, 0x00); /* disable flickerfixer */
- mdelay (100);
- vga_wgfx (cinfo->regbase, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */
- vga_wgfx (cinfo->regbase, CL_GR33, 0x00); /* put blitter into 542x compat */
- vga_wgfx (cinfo->regbase, CL_GR31, 0x00); /* mode */
+ /* disable flickerfixer */
+ vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
+ mdelay(100);
+ /* from Klaus' NetBSD driver: */
+ vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
+ /* put blitter into 542x compat */
+ vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
+ /* mode */
+ vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
break;
case BT_GD5480:
- vga_wgfx (cinfo->regbase, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */
+ /* from Klaus' NetBSD driver: */
+ vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
break;
case BT_ALPINE:
@@ -1807,153 +1782,208 @@ static void init_vgachip (struct cirrusfb_info *cinfo)
break;
default:
- printk (KERN_ERR "cirrusfb: Warning: Unknown board type\n");
+ printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");
break;
}
- assert (cinfo->size > 0); /* make sure RAM size set by this point */
+ /* make sure RAM size set by this point */
+ assert(info->screen_size > 0);
/* the P4 is not fully initialized here; I rely on it having been */
/* inited under AmigaOS already, which seems to work just fine */
- /* (Klaus advised to do it this way) */
+ /* (Klaus advised to do it this way) */
if (cinfo->btype != BT_PICASSO4) {
- WGen (cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
- WGen (cinfo, CL_POS102, 0x01);
- WGen (cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
+ WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
+ WGen(cinfo, CL_POS102, 0x01);
+ WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
if (cinfo->btype != BT_SD64)
- WGen (cinfo, CL_VSSM2, 0x01);
+ WGen(cinfo, CL_VSSM2, 0x01);
- vga_wseq (cinfo->regbase, CL_SEQR0, 0x03); /* reset sequencer logic */
+ /* reset sequencer logic */
+ vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
- vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); /* FullBandwidth (video off) and 8/9 dot clock */
- WGen (cinfo, VGA_MIS_W, 0xc1); /* polarity (-/-), disable access to display memory, VGA_CRTC_START_HI base address: color */
+ /* FullBandwidth (video off) and 8/9 dot clock */
+ vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
+ /* polarity (-/-), disable access to display memory,
+ * VGA_CRTC_START_HI base address: color
+ */
+ WGen(cinfo, VGA_MIS_W, 0xc1);
-/* vga_wgfx (cinfo->regbase, CL_GRA, 0xce); "magic cookie" - doesn't make any sense to me.. */
- vga_wseq (cinfo->regbase, CL_SEQR6, 0x12); /* unlock all extension registers */
+ /* "magic cookie" - doesn't make any sense to me.. */
+/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
+ /* unlock all extension registers */
+ vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
- vga_wgfx (cinfo->regbase, CL_GR31, 0x04); /* reset blitter */
+ /* reset blitter */
+ vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
switch (cinfo->btype) {
case BT_GD5480:
- vga_wseq (cinfo->regbase, CL_SEQRF, 0x98);
+ vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
break;
case BT_ALPINE:
break;
case BT_SD64:
- vga_wseq (cinfo->regbase, CL_SEQRF, 0xb8);
+ vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
break;
default:
- vga_wseq (cinfo->regbase, CL_SEQR16, 0x0f);
- vga_wseq (cinfo->regbase, CL_SEQRF, 0xb0);
+ vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
+ vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
break;
}
}
- vga_wseq (cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: nothing */
- vga_wseq (cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); /* character map select: doesn't even matter in gx mode */
- vga_wseq (cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e); /* memory mode: chain-4, no odd/even, ext. memory */
+ /* plane mask: nothing */
+ vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
+ /* character map select: doesn't even matter in gx mode */
+ vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
+ /* memory mode: chain-4, no odd/even, ext. memory */
+ vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
/* controller-internal base address of video memory */
if (bi->init_sr07)
- vga_wseq (cinfo->regbase, CL_SEQR7, bi->sr07);
+ vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
- /* vga_wseq (cinfo->regbase, CL_SEQR8, 0x00); *//* EEPROM control: shouldn't be necessary to write to this at all.. */
+ /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
+ /* EEPROM control: shouldn't be necessary to write to this at all.. */
- vga_wseq (cinfo->regbase, CL_SEQR10, 0x00); /* graphics cursor X position (incomplete; position gives rem. 3 bits */
- vga_wseq (cinfo->regbase, CL_SEQR11, 0x00); /* graphics cursor Y position (..."... ) */
- vga_wseq (cinfo->regbase, CL_SEQR12, 0x00); /* graphics cursor attributes */
- vga_wseq (cinfo->regbase, CL_SEQR13, 0x00); /* graphics cursor pattern address */
+ /* graphics cursor X position (incomplete; position gives rem. 3 bits */
+ vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
+ /* graphics cursor Y position (..."... ) */
+ vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
+ /* graphics cursor attributes */
+ vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
+ /* graphics cursor pattern address */
+ vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
/* writing these on a P4 might give problems.. */
if (cinfo->btype != BT_PICASSO4) {
- vga_wseq (cinfo->regbase, CL_SEQR17, 0x00); /* configuration readback and ext. color */
- vga_wseq (cinfo->regbase, CL_SEQR18, 0x02); /* signature generator */
+ /* configuration readback and ext. color */
+ vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
+ /* signature generator */
+ vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
}
/* MCLK select etc. */
if (bi->init_sr1f)
- vga_wseq (cinfo->regbase, CL_SEQR1F, bi->sr1f);
-
- vga_wcrt (cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); /* Screen A preset row scan: none */
- vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); /* Text cursor start: disable text cursor */
- vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); /* Text cursor end: - */
- vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, 0x00); /* Screen start address high: 0 */
- vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, 0x00); /* Screen start address low: 0 */
- vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); /* text cursor location high: 0 */
- vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00); /* text cursor location low: 0 */
-
- vga_wcrt (cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); /* Underline Row scanline: - */
- vga_wcrt (cinfo->regbase, VGA_CRTC_MODE, 0xc3); /* mode control: timing enable, byte mode, no compat modes */
- vga_wcrt (cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00); /* Line Compare: not needed */
+ vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
+
+ /* Screen A preset row scan: none */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
+ /* Text cursor start: disable text cursor */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
+ /* Text cursor end: - */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
+ /* Screen start address high: 0 */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
+ /* Screen start address low: 0 */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
+ /* text cursor location high: 0 */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
+ /* text cursor location low: 0 */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
+
+ /* Underline Row scanline: - */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
+ /* mode control: timing enable, byte mode, no compat modes */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
+ /* Line Compare: not needed */
+ vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
/* ### add 0x40 for text modes with > 30 MHz pixclock */
- vga_wcrt (cinfo->regbase, CL_CRT1B, 0x02); /* ext. display controls: ext.adr. wrap */
-
- vga_wgfx (cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); /* Set/Reset registes: - */
- vga_wgfx (cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); /* Set/Reset enable: - */
- vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00); /* Color Compare: - */
- vga_wgfx (cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00); /* Data Rotate: - */
- vga_wgfx (cinfo->regbase, VGA_GFX_PLANE_READ, 0x00); /* Read Map Select: - */
- vga_wgfx (cinfo->regbase, VGA_GFX_MODE, 0x00); /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
- vga_wgfx (cinfo->regbase, VGA_GFX_MISC, 0x01); /* Miscellaneous: memory map base address, graphics mode */
- vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); /* Color Don't care: involve all planes */
- vga_wgfx (cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); /* Bit Mask: no mask at all */
+ /* ext. display controls: ext.adr. wrap */
+ vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
+
+ /* Set/Reset registes: - */
+ vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
+ /* Set/Reset enable: - */
+ vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
+ /* Color Compare: - */
+ vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
+ /* Data Rotate: - */
+ vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
+ /* Read Map Select: - */
+ vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
+ /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
+ vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
+ /* Miscellaneous: memory map base address, graphics mode */
+ vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
+ /* Color Don't care: involve all planes */
+ vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
+ /* Bit Mask: no mask at all */
+ vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
if (cinfo->btype == BT_ALPINE)
- vga_wgfx (cinfo->regbase, CL_GRB, 0x20); /* (5434 can't have bit 3 set for bitblt) */
+ /* (5434 can't have bit 3 set for bitblt) */
+ vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
else
- vga_wgfx (cinfo->regbase, CL_GRB, 0x28); /* Graphics controller mode extensions: finer granularity, 8byte data latches */
-
- vga_wgfx (cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
- vga_wgfx (cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
- vga_wgfx (cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
- /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); *//* Background color byte 1: - */
-/* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
-
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE0, 0x00); /* Attribute Controller palette registers: "identity mapping" */
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
- vga_wattr (cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
-
- vga_wattr (cinfo->regbase, VGA_ATC_MODE, 0x01); /* Attribute Controller mode: graphics mode */
- vga_wattr (cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); /* Overscan color reg.: reg. 0 */
- vga_wattr (cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); /* Color Plane enable: Enable all 4 planes */
-/* ### vga_wattr (cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
- vga_wattr (cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); /* Color Select: - */
-
- WGen (cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
+ /* Graphics controller mode extensions: finer granularity,
+ * 8byte data latches
+ */
+ vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
+
+ vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
+ vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
+ vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
+ /* Background color byte 1: - */
+ /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
+ /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
+
+ /* Attribute Controller palette registers: "identity mapping" */
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
+ vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
+
+ /* Attribute Controller mode: graphics mode */
+ vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
+ /* Overscan color reg.: reg. 0 */
+ vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
+ /* Color Plane enable: Enable all 4 planes */
+ vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
+/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
+ /* Color Select: - */
+ vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
+
+ WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
- WGen (cinfo, VGA_MIS_W, 0xc3); /* polarity (-/-), enable display mem, VGA_CRTC_START_HI i/o base = color */
+ /* polarity (-/-), enable display mem,
+ * VGA_CRTC_START_HI i/o base = color
+ */
+ WGen(cinfo, VGA_MIS_W, 0xc3);
- vga_wgfx (cinfo->regbase, CL_GR31, 0x04); /* BLT Start/status: Blitter reset */
- vga_wgfx (cinfo->regbase, CL_GR31, 0x00); /* - " - : "end-of-reset" */
+ /* BLT Start/status: Blitter reset */
+ vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
+ /* - " - : "end-of-reset" */
+ vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
/* misc... */
- WHDR (cinfo, 0); /* Hidden DAC register: - */
+ WHDR(cinfo, 0); /* Hidden DAC register: - */
- printk (KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n", cinfo->size);
- DPRINTK ("EXIT\n");
+ printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
+ info->screen_size);
+ DPRINTK("EXIT\n");
return;
}
-static void switch_monitor (struct cirrusfb_info *cinfo, int on)
+static void switch_monitor(struct cirrusfb_info *cinfo, int on)
{
#ifdef CONFIG_ZORRO /* only works on Zorro boards */
static int IsOn = 0; /* XXX not ok for multiple boards */
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
if (cinfo->btype == BT_PICASSO4)
return; /* nothing to switch */
@@ -1963,77 +1993,56 @@ static void switch_monitor (struct cirrusfb_info *cinfo, int on)
return; /* nothing to switch */
if (cinfo->btype == BT_PICASSO) {
if ((on && !IsOn) || (!on && IsOn))
- WSFR (cinfo, 0xff);
+ WSFR(cinfo, 0xff);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
return;
}
if (on) {
switch (cinfo->btype) {
case BT_SD64:
- WSFR (cinfo, cinfo->SFR | 0x21);
+ WSFR(cinfo, cinfo->SFR | 0x21);
break;
case BT_PICCOLO:
- WSFR (cinfo, cinfo->SFR | 0x28);
+ WSFR(cinfo, cinfo->SFR | 0x28);
break;
case BT_SPECTRUM:
- WSFR (cinfo, 0x6f);
+ WSFR(cinfo, 0x6f);
break;
default: /* do nothing */ break;
}
} else {
switch (cinfo->btype) {
case BT_SD64:
- WSFR (cinfo, cinfo->SFR & 0xde);
+ WSFR(cinfo, cinfo->SFR & 0xde);
break;
case BT_PICCOLO:
- WSFR (cinfo, cinfo->SFR & 0xd7);
+ WSFR(cinfo, cinfo->SFR & 0xd7);
break;
case BT_SPECTRUM:
- WSFR (cinfo, 0x4f);
+ WSFR(cinfo, 0x4f);
break;
default: /* do nothing */ break;
}
}
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
#endif /* CONFIG_ZORRO */
}
-
/******************************************/
/* Linux 2.6-style accelerated functions */
/******************************************/
-static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo,
- const struct fb_fillrect *region)
-{
- int m; /* bytes per pixel */
- u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ?
- cinfo->pseudo_palette[region->color] : region->color;
-
- if(cinfo->info->var.bits_per_pixel == 1) {
- cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
- region->dx / 8, region->dy,
- region->width / 8, region->height,
- color,
- cinfo->currentmode.line_length);
- } else {
- m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
- cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
- region->dx * m, region->dy,
- region->width * m, region->height,
- color,
- cinfo->currentmode.line_length);
- }
- return;
-}
-
-static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
+static void cirrusfb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *region)
{
- struct cirrusfb_info *cinfo = info->par;
struct fb_fillrect modded;
int vxres, vyres;
+ struct cirrusfb_info *cinfo = info->par;
+ int m = info->var.bits_per_pixel;
+ u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+ cinfo->pseudo_palette[region->color] : region->color;
if (info->state != FBINFO_STATE_RUNNING)
return;
@@ -2047,49 +2056,30 @@ static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *r
memcpy(&modded, region, sizeof(struct fb_fillrect));
- if(!modded.width || !modded.height ||
+ if (!modded.width || !modded.height ||
modded.dx >= vxres || modded.dy >= vyres)
return;
- if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
- if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
-
- cirrusfb_prim_fillrect(cinfo, &modded);
-}
-
-static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo,
- const struct fb_copyarea *area)
-{
- int m; /* bytes per pixel */
- if(cinfo->info->var.bits_per_pixel == 1) {
- cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
- area->sx / 8, area->sy,
- area->dx / 8, area->dy,
- area->width / 8, area->height,
- cinfo->currentmode.line_length);
- } else {
- m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
- cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
- area->sx * m, area->sy,
- area->dx * m, area->dy,
- area->width * m, area->height,
- cinfo->currentmode.line_length);
- }
- return;
+ if (modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if (modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ cirrusfb_RectFill(cinfo->regbase,
+ info->var.bits_per_pixel,
+ (region->dx * m) / 8, region->dy,
+ (region->width * m) / 8, region->height,
+ color,
+ info->fix.line_length);
}
-
-static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void cirrusfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
{
- struct cirrusfb_info *cinfo = info->par;
struct fb_copyarea modded;
u32 vxres, vyres;
- modded.sx = area->sx;
- modded.sy = area->sy;
- modded.dx = area->dx;
- modded.dy = area->dy;
- modded.width = area->width;
- modded.height = area->height;
+ struct cirrusfb_info *cinfo = info->par;
+ int m = info->var.bits_per_pixel;
if (info->state != FBINFO_STATE_RUNNING)
return;
@@ -2100,90 +2090,106 @@ static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *ar
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
+ memcpy(&modded, area, sizeof(struct fb_copyarea));
- if(!modded.width || !modded.height ||
+ if (!modded.width || !modded.height ||
modded.sx >= vxres || modded.sy >= vyres ||
modded.dx >= vxres || modded.dy >= vyres)
return;
- if(modded.sx + modded.width > vxres) modded.width = vxres - modded.sx;
- if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
- if(modded.sy + modded.height > vyres) modded.height = vyres - modded.sy;
- if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
+ if (modded.sx + modded.width > vxres)
+ modded.width = vxres - modded.sx;
+ if (modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if (modded.sy + modded.height > vyres)
+ modded.height = vyres - modded.sy;
+ if (modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
+ (area->sx * m) / 8, area->sy,
+ (area->dx * m) / 8, area->dy,
+ (area->width * m) / 8, area->height,
+ info->fix.line_length);
- cirrusfb_prim_copyarea(cinfo, &modded);
}
-static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void cirrusfb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
{
struct cirrusfb_info *cinfo = info->par;
- cirrusfb_WaitBLT(cinfo->regbase);
+ cirrusfb_WaitBLT(cinfo->regbase);
cfb_imageblit(info, image);
}
-
#ifdef CONFIG_PPC_PREP
#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
-static void get_prep_addrs (unsigned long *display, unsigned long *registers)
+static void get_prep_addrs(unsigned long *display, unsigned long *registers)
{
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
*display = PREP_VIDEO_BASE;
*registers = (unsigned long) PREP_IO_BASE;
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
#endif /* CONFIG_PPC_PREP */
-
#ifdef CONFIG_PCI
-static int release_io_ports = 0;
+static int release_io_ports;
/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
* based on the DRAM bandwidth bit and DRAM bank switching bit. This
* works with 1MB, 2MB and 4MB configurations (which the Motorola boards
* seem to have. */
-static unsigned int cirrusfb_get_memsize (u8 __iomem *regbase)
+static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
{
unsigned long mem;
unsigned char SRF;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- SRF = vga_rseq (regbase, CL_SEQRF);
+ SRF = vga_rseq(regbase, CL_SEQRF);
switch ((SRF & 0x18)) {
- case 0x08: mem = 512 * 1024; break;
- case 0x10: mem = 1024 * 1024; break;
- /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
- * on the 5430. */
- case 0x18: mem = 2048 * 1024; break;
- default: printk ("CLgenfb: Unknown memory size!\n");
+ case 0x08:
+ mem = 512 * 1024;
+ break;
+ case 0x10:
+ mem = 1024 * 1024;
+ break;
+ /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
+ * on the 5430.
+ */
+ case 0x18:
+ mem = 2048 * 1024;
+ break;
+ default:
+ printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");
mem = 1024 * 1024;
}
- if (SRF & 0x80) {
- /* If DRAM bank switching is enabled, there must be twice as much
- * memory installed. (4MB on the 5434) */
+ if (SRF & 0x80)
+ /* If DRAM bank switching is enabled, there must be twice as much
+ * memory installed. (4MB on the 5434)
+ */
mem *= 2;
- }
+
/* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
return mem;
}
-
-
-static void get_pci_addrs (const struct pci_dev *pdev,
- unsigned long *display, unsigned long *registers)
+static void get_pci_addrs(const struct pci_dev *pdev,
+ unsigned long *display, unsigned long *registers)
{
- assert (pdev != NULL);
- assert (display != NULL);
- assert (registers != NULL);
+ assert(pdev != NULL);
+ assert(display != NULL);
+ assert(registers != NULL);
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
*display = 0;
*registers = 0;
@@ -2198,51 +2204,48 @@ static void get_pci_addrs (const struct pci_dev *pdev,
*registers = pci_resource_start(pdev, 1);
}
- assert (*display != 0);
+ assert(*display != 0);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
-
-static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
+static void cirrusfb_pci_unmap(struct fb_info *info)
{
+ struct cirrusfb_info *cinfo = info->par;
struct pci_dev *pdev = cinfo->pdev;
- iounmap(cinfo->fbmem);
+ iounmap(info->screen_base);
#if 0 /* if system didn't claim this region, we would... */
release_mem_region(0xA0000, 65535);
#endif
if (release_io_ports)
release_region(0x3C0, 32);
pci_release_regions(pdev);
- framebuffer_release(cinfo->info);
}
#endif /* CONFIG_PCI */
-
#ifdef CONFIG_ZORRO
-static void __devexit cirrusfb_zorro_unmap (struct cirrusfb_info *cinfo)
+static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
{
+ struct cirrusfb_info *cinfo = info->par;
zorro_release_device(cinfo->zdev);
if (cinfo->btype == BT_PICASSO4) {
cinfo->regbase -= 0x600000;
- iounmap ((void *)cinfo->regbase);
- iounmap ((void *)cinfo->fbmem);
+ iounmap((void *)cinfo->regbase);
+ iounmap(info->screen_base);
} else {
if (zorro_resource_start(cinfo->zdev) > 0x01000000)
- iounmap ((void *)cinfo->fbmem);
+ iounmap(info->screen_base);
}
- framebuffer_release(cinfo->info);
}
#endif /* CONFIG_ZORRO */
-static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
+static int cirrusfb_set_fbinfo(struct fb_info *info)
{
- struct fb_info *info = cinfo->info;
+ struct cirrusfb_info *cinfo = info->par;
struct fb_var_screeninfo *var = &info->var;
- info->par = cinfo;
info->pseudo_palette = cinfo->pseudo_palette;
info->flags = FBINFO_DEFAULT
| FBINFO_HWACCEL_XPAN
@@ -2252,7 +2255,6 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
if (noaccel)
info->flags |= FBINFO_HWACCEL_DISABLED;
info->fbops = &cirrusfb_ops;
- info->screen_base = cinfo->fbmem;
if (cinfo->btype == BT_GD5480) {
if (var->bits_per_pixel == 16)
info->screen_base += 1 * MB_;
@@ -2266,18 +2268,15 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
/* monochrome: only 1 memory plane */
/* 8 bit and above: Use whole memory area */
- info->fix.smem_start = cinfo->fbmem_phys;
- info->fix.smem_len = (var->bits_per_pixel == 1) ? cinfo->size / 4 : cinfo->size;
- info->fix.type = cinfo->currentmode.type;
+ info->fix.smem_len = info->screen_size;
+ if (var->bits_per_pixel == 1)
+ info->fix.smem_len /= 4;
info->fix.type_aux = 0;
- info->fix.visual = cinfo->currentmode.visual;
info->fix.xpanstep = 1;
info->fix.ypanstep = 1;
info->fix.ywrapstep = 0;
- info->fix.line_length = cinfo->currentmode.line_length;
/* FIXME: map region at 0xB8000 if available, fill in here */
- info->fix.mmio_start = cinfo->fbregs_phys;
info->fix.mmio_len = 0;
info->fix.accel = FB_ACCEL_NONE;
@@ -2286,23 +2285,23 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
return 0;
}
-static int cirrusfb_register(struct cirrusfb_info *cinfo)
+static int cirrusfb_register(struct fb_info *info)
{
- struct fb_info *info;
+ struct cirrusfb_info *cinfo = info->par;
int err;
- cirrusfb_board_t btype;
+ enum cirrus_board btype;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- printk (KERN_INFO "cirrusfb: Driver for Cirrus Logic based graphic boards, v" CIRRUSFB_VERSION "\n");
+ printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
+ "graphic boards, v" CIRRUSFB_VERSION "\n");
- info = cinfo->info;
btype = cinfo->btype;
/* sanity checks */
- assert (btype != BT_NONE);
+ assert(btype != BT_NONE);
- DPRINTK ("cirrusfb: (RAM start set to: 0x%p)\n", cinfo->fbmem);
+ DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
/* Make pretend we've set the var so our structures are in a "good" */
/* state, even though we haven't written the mode to the hw yet... */
@@ -2317,47 +2316,49 @@ static int cirrusfb_register(struct cirrusfb_info *cinfo)
}
/* set all the vital stuff */
- cirrusfb_set_fbinfo(cinfo);
+ cirrusfb_set_fbinfo(info);
err = register_framebuffer(info);
if (err < 0) {
- printk (KERN_ERR "cirrusfb: could not register fb device; err = %d!\n", err);
+ printk(KERN_ERR "cirrusfb: could not register "
+ "fb device; err = %d!\n", err);
goto err_dealloc_cmap;
}
- DPRINTK ("EXIT, returning 0\n");
+ DPRINTK("EXIT, returning 0\n");
return 0;
err_dealloc_cmap:
fb_dealloc_cmap(&info->cmap);
err_unmap_cirrusfb:
- cinfo->unmap(cinfo);
+ cinfo->unmap(info);
+ framebuffer_release(info);
return err;
}
-static void __devexit cirrusfb_cleanup (struct fb_info *info)
+static void __devexit cirrusfb_cleanup(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- switch_monitor (cinfo, 0);
+ switch_monitor(cinfo, 0);
- unregister_framebuffer (info);
- fb_dealloc_cmap (&info->cmap);
- printk ("Framebuffer unregistered\n");
- cinfo->unmap(cinfo);
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ printk("Framebuffer unregistered\n");
+ cinfo->unmap(info);
+ framebuffer_release(info);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
-
#ifdef CONFIG_PCI
-static int cirrusfb_pci_register (struct pci_dev *pdev,
+static int cirrusfb_pci_register(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct cirrusfb_info *cinfo;
struct fb_info *info;
- cirrusfb_board_t btype;
+ enum cirrus_board btype;
unsigned long board_addr, board_size;
int ret;
@@ -2375,35 +2376,37 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
}
cinfo = info->par;
- cinfo->info = info;
cinfo->pdev = pdev;
- cinfo->btype = btype = (cirrusfb_board_t) ent->driver_data;
+ cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
- DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n",
+ DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
pdev->resource[0].start, btype);
- DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start);
+ DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);
- if(isPReP) {
- pci_write_config_dword (pdev, PCI_BASE_ADDRESS_0, 0x00000000);
+ if (isPReP) {
+ pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
#ifdef CONFIG_PPC_PREP
- get_prep_addrs (&board_addr, &cinfo->fbregs_phys);
+ get_prep_addrs(&board_addr, &info->fix.mmio_start);
#endif
- /* PReP dies if we ioremap the IO registers, but it works w/out... */
- cinfo->regbase = (char __iomem *) cinfo->fbregs_phys;
+ /* PReP dies if we ioremap the IO registers, but it works w/out... */
+ cinfo->regbase = (char __iomem *) info->fix.mmio_start;
} else {
- DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
- get_pci_addrs (pdev, &board_addr, &cinfo->fbregs_phys);
- cinfo->regbase = NULL; /* FIXME: this forces VGA. alternatives? */
+ DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");
+ get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
+ /* FIXME: this forces VGA. alternatives? */
+ cinfo->regbase = NULL;
}
- DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, cinfo->fbregs_phys);
+ DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",
+ board_addr, info->fix.mmio_start);
board_size = (btype == BT_GD5480) ?
- 32 * MB_ : cirrusfb_get_memsize (cinfo->regbase);
+ 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);
ret = pci_request_regions(pdev, "cirrusfb");
- if (ret <0) {
- printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n",
+ if (ret < 0) {
+ printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
+ "abort\n",
board_addr);
goto err_release_fb;
}
@@ -2419,23 +2422,24 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
if (request_region(0x3C0, 32, "cirrusfb"))
release_io_ports = 1;
- cinfo->fbmem = ioremap(board_addr, board_size);
- if (!cinfo->fbmem) {
+ info->screen_base = ioremap(board_addr, board_size);
+ if (!info->screen_base) {
ret = -EIO;
goto err_release_legacy;
}
- cinfo->fbmem_phys = board_addr;
- cinfo->size = board_size;
+ info->fix.smem_start = board_addr;
+ info->screen_size = board_size;
cinfo->unmap = cirrusfb_pci_unmap;
- printk (" RAM (%lu kB) at 0xx%lx, ", cinfo->size / KB_, board_addr);
- printk ("Cirrus Logic chipset on PCI bus\n");
+ printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ",
+ info->screen_size >> 10, board_addr);
+ printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n");
pci_set_drvdata(pdev, info);
- ret = cirrusfb_register(cinfo);
+ ret = cirrusfb_register(info);
if (ret)
- iounmap(cinfo->fbmem);
+ iounmap(info->screen_base);
return ret;
err_release_legacy:
@@ -2453,14 +2457,14 @@ err_out:
return ret;
}
-static void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
+static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- cirrusfb_cleanup (info);
+ cirrusfb_cleanup(info);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
static struct pci_driver cirrusfb_pci_driver = {
@@ -2477,14 +2481,13 @@ static struct pci_driver cirrusfb_pci_driver = {
};
#endif /* CONFIG_PCI */
-
#ifdef CONFIG_ZORRO
static int cirrusfb_zorro_register(struct zorro_dev *z,
const struct zorro_device_id *ent)
{
struct cirrusfb_info *cinfo;
struct fb_info *info;
- cirrusfb_board_t btype;
+ enum cirrus_board btype;
struct zorro_dev *z2 = NULL;
unsigned long board_addr, board_size, size;
int ret;
@@ -2498,83 +2501,86 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
if (!info) {
- printk (KERN_ERR "cirrusfb: could not allocate memory\n");
+ printk(KERN_ERR "cirrusfb: could not allocate memory\n");
ret = -ENOMEM;
goto err_out;
}
cinfo = info->par;
- cinfo->info = info;
cinfo->btype = btype;
- assert (z > 0);
- assert (z2 >= 0);
- assert (btype != BT_NONE);
+ assert(z > 0);
+ assert(z2 >= 0);
+ assert(btype != BT_NONE);
cinfo->zdev = z;
board_addr = zorro_resource_start(z);
board_size = zorro_resource_len(z);
- cinfo->size = size;
+ info->screen_size = size;
if (!zorro_request_device(z, "cirrusfb")) {
- printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n",
+ printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
+ "abort\n",
board_addr);
ret = -EBUSY;
goto err_release_fb;
}
- printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
+ printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
ret = -EIO;
if (btype == BT_PICASSO4) {
- printk (" REG at $%lx\n", board_addr + 0x600000);
+ printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);
/* To be precise, for the P4 this is not the */
/* begin of the board, but the begin of RAM. */
/* for P4, map in its address space in 2 chunks (### TEST! ) */
/* (note the ugly hardcoded 16M number) */
- cinfo->regbase = ioremap (board_addr, 16777216);
+ cinfo->regbase = ioremap(board_addr, 16777216);
if (!cinfo->regbase)
goto err_release_region;
- DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase);
+ DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
+ cinfo->regbase);
cinfo->regbase += 0x600000;
- cinfo->fbregs_phys = board_addr + 0x600000;
+ info->fix.mmio_start = board_addr + 0x600000;
- cinfo->fbmem_phys = board_addr + 16777216;
- cinfo->fbmem = ioremap (cinfo->fbmem_phys, 16777216);
- if (!cinfo->fbmem)
+ info->fix.smem_start = board_addr + 16777216;
+ info->screen_base = ioremap(info->fix.smem_start, 16777216);
+ if (!info->screen_base)
goto err_unmap_regbase;
} else {
- printk (" REG at $%lx\n", (unsigned long) z2->resource.start);
+ printk(KERN_INFO " REG at $%lx\n",
+ (unsigned long) z2->resource.start);
- cinfo->fbmem_phys = board_addr;
+ info->fix.smem_start = board_addr;
if (board_addr > 0x01000000)
- cinfo->fbmem = ioremap (board_addr, board_size);
+ info->screen_base = ioremap(board_addr, board_size);
else
- cinfo->fbmem = (caddr_t) ZTWO_VADDR (board_addr);
- if (!cinfo->fbmem)
+ info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
+ if (!info->screen_base)
goto err_release_region;
/* set address for REG area of board */
- cinfo->regbase = (caddr_t) ZTWO_VADDR (z2->resource.start);
- cinfo->fbregs_phys = z2->resource.start;
+ cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
+ info->fix.mmio_start = z2->resource.start;
- DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase);
+ DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
+ cinfo->regbase);
}
cinfo->unmap = cirrusfb_zorro_unmap;
- printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
+ printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
zorro_set_drvdata(z, info);
- ret = cirrusfb_register(cinfo);
+ ret = cirrusfb_register(info);
if (ret) {
if (btype == BT_PICASSO4) {
- iounmap(cinfo->fbmem);
+ iounmap(info->screen_base);
iounmap(cinfo->regbase - 0x600000);
} else if (board_addr > 0x01000000)
- iounmap(cinfo->fbmem);
+ iounmap(info->screen_base);
}
return ret;
@@ -2592,11 +2598,11 @@ err_out:
void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
{
struct fb_info *info = zorro_get_drvdata(z);
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- cirrusfb_cleanup (info);
+ cirrusfb_cleanup(info);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
static struct zorro_driver cirrusfb_zorro_driver = {
@@ -2628,26 +2634,24 @@ static int __init cirrusfb_init(void)
return error;
}
-
-
#ifndef MODULE
static int __init cirrusfb_setup(char *options) {
char *this_opt, s[32];
int i;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
if (!options || !*options)
return 0;
- while ((this_opt = strsep (&options, ",")) != NULL) {
+ while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt) continue;
DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
for (i = 0; i < NUM_TOTAL_MODES; i++) {
- sprintf (s, "mode:%s", cirrusfb_predefined[i].name);
- if (strcmp (this_opt, s) == 0)
+ sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
+ if (strcmp(this_opt, s) == 0)
cirrusfb_def_mode = i;
}
if (!strcmp(this_opt, "noaccel"))
@@ -2657,7 +2661,6 @@ static int __init cirrusfb_setup(char *options) {
}
#endif
-
/*
* Modularization
*/
@@ -2666,7 +2669,7 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
MODULE_LICENSE("GPL");
-static void __exit cirrusfb_exit (void)
+static void __exit cirrusfb_exit(void)
{
#ifdef CONFIG_PCI
pci_unregister_driver(&cirrusfb_pci_driver);
@@ -2682,66 +2685,67 @@ module_init(cirrusfb_init);
module_exit(cirrusfb_exit);
#endif
-
/**********************************************************************/
/* about the following functions - I have used the same names for the */
/* functions as Markus Wild did in his Retina driver for NetBSD as */
/* they just made sense for this purpose. Apart from that, I wrote */
-/* these functions myself. */
+/* these functions myself. */
/**********************************************************************/
/*** WGen() - write into one of the external/general registers ***/
-static void WGen (const struct cirrusfb_info *cinfo,
+static void WGen(const struct cirrusfb_info *cinfo,
int regnum, unsigned char val)
{
unsigned long regofs = 0;
if (cinfo->btype == BT_PICASSO) {
/* Picasso II specific hack */
-/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
+/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
+ regnum == CL_VSSM2) */
if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
regofs = 0xfff;
}
- vga_w (cinfo->regbase, regofs + regnum, val);
+ vga_w(cinfo->regbase, regofs + regnum, val);
}
/*** RGen() - read out one of the external/general registers ***/
-static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum)
+static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
{
unsigned long regofs = 0;
if (cinfo->btype == BT_PICASSO) {
/* Picasso II specific hack */
-/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
+/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
+ regnum == CL_VSSM2) */
if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
regofs = 0xfff;
}
- return vga_r (cinfo->regbase, regofs + regnum);
+ return vga_r(cinfo->regbase, regofs + regnum);
}
/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
-static void AttrOn (const struct cirrusfb_info *cinfo)
+static void AttrOn(const struct cirrusfb_info *cinfo)
{
- assert (cinfo != NULL);
+ assert(cinfo != NULL);
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
- if (vga_rcrt (cinfo->regbase, CL_CRT24) & 0x80) {
+ if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
/* if we're just in "write value" mode, write back the */
/* same value as before to not modify anything */
- vga_w (cinfo->regbase, VGA_ATT_IW,
- vga_r (cinfo->regbase, VGA_ATT_R));
+ vga_w(cinfo->regbase, VGA_ATT_IW,
+ vga_r(cinfo->regbase, VGA_ATT_R));
}
/* turn on video bit */
-/* vga_w (cinfo->regbase, VGA_ATT_IW, 0x20); */
- vga_w (cinfo->regbase, VGA_ATT_IW, 0x33);
+/* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
+ vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
/* dummy write on Reg0 to be on "write index" mode next time */
- vga_w (cinfo->regbase, VGA_ATT_IW, 0x00);
+ vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
/*** WHDR() - write into the Hidden DAC register ***/
@@ -2750,119 +2754,115 @@ static void AttrOn (const struct cirrusfb_info *cinfo)
* registers of their functional group) here is a specialized routine for
* accessing the HDR
*/
-static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val)
+static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
{
unsigned char dummy;
if (cinfo->btype == BT_PICASSO) {
/* Klaus' hint for correct access to HDR on some boards */
/* first write 0 to pixel mask (3c6) */
- WGen (cinfo, VGA_PEL_MSK, 0x00);
- udelay (200);
+ WGen(cinfo, VGA_PEL_MSK, 0x00);
+ udelay(200);
/* next read dummy from pixel address (3c8) */
- dummy = RGen (cinfo, VGA_PEL_IW);
- udelay (200);
+ dummy = RGen(cinfo, VGA_PEL_IW);
+ udelay(200);
}
/* now do the usual stuff to access the HDR */
- dummy = RGen (cinfo, VGA_PEL_MSK);
- udelay (200);
- dummy = RGen (cinfo, VGA_PEL_MSK);
- udelay (200);
- dummy = RGen (cinfo, VGA_PEL_MSK);
- udelay (200);
- dummy = RGen (cinfo, VGA_PEL_MSK);
- udelay (200);
+ dummy = RGen(cinfo, VGA_PEL_MSK);
+ udelay(200);
+ dummy = RGen(cinfo, VGA_PEL_MSK);
+ udelay(200);
+ dummy = RGen(cinfo, VGA_PEL_MSK);
+ udelay(200);
+ dummy = RGen(cinfo, VGA_PEL_MSK);
+ udelay(200);
- WGen (cinfo, VGA_PEL_MSK, val);
- udelay (200);
+ WGen(cinfo, VGA_PEL_MSK, val);
+ udelay(200);
if (cinfo->btype == BT_PICASSO) {
/* now first reset HDR access counter */
- dummy = RGen (cinfo, VGA_PEL_IW);
- udelay (200);
+ dummy = RGen(cinfo, VGA_PEL_IW);
+ udelay(200);
/* and at the end, restore the mask value */
/* ## is this mask always 0xff? */
- WGen (cinfo, VGA_PEL_MSK, 0xff);
- udelay (200);
+ WGen(cinfo, VGA_PEL_MSK, 0xff);
+ udelay(200);
}
}
-
/*** WSFR() - write to the "special function register" (SFR) ***/
-static void WSFR (struct cirrusfb_info *cinfo, unsigned char val)
+static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
{
#ifdef CONFIG_ZORRO
- assert (cinfo->regbase != NULL);
+ assert(cinfo->regbase != NULL);
cinfo->SFR = val;
- z_writeb (val, cinfo->regbase + 0x8000);
+ z_writeb(val, cinfo->regbase + 0x8000);
#endif
}
/* The Picasso has a second register for switching the monitor bit */
-static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val)
+static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
{
#ifdef CONFIG_ZORRO
/* writing an arbitrary value to this one causes the monitor switcher */
/* to flip to Amiga display */
- assert (cinfo->regbase != NULL);
+ assert(cinfo->regbase != NULL);
cinfo->SFR = val;
- z_writeb (val, cinfo->regbase + 0x9000);
+ z_writeb(val, cinfo->regbase + 0x9000);
#endif
}
-
/*** WClut - set CLUT entry (range: 0..63) ***/
-static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
+static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
unsigned char green, unsigned char blue)
{
unsigned int data = VGA_PEL_D;
/* address write mode register is not translated.. */
- vga_w (cinfo->regbase, VGA_PEL_IW, regnum);
+ vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
/* but DAC data register IS, at least for Picasso II */
if (cinfo->btype == BT_PICASSO)
data += 0xfff;
- vga_w (cinfo->regbase, data, red);
- vga_w (cinfo->regbase, data, green);
- vga_w (cinfo->regbase, data, blue);
+ vga_w(cinfo->regbase, data, red);
+ vga_w(cinfo->regbase, data, green);
+ vga_w(cinfo->regbase, data, blue);
} else {
- vga_w (cinfo->regbase, data, blue);
- vga_w (cinfo->regbase, data, green);
- vga_w (cinfo->regbase, data, red);
+ vga_w(cinfo->regbase, data, blue);
+ vga_w(cinfo->regbase, data, green);
+ vga_w(cinfo->regbase, data, red);
}
}
-
#if 0
/*** RClut - read CLUT entry (range 0..63) ***/
-static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
+static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
unsigned char *green, unsigned char *blue)
{
unsigned int data = VGA_PEL_D;
- vga_w (cinfo->regbase, VGA_PEL_IR, regnum);
+ vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
if (cinfo->btype == BT_PICASSO)
data += 0xfff;
- *red = vga_r (cinfo->regbase, data);
- *green = vga_r (cinfo->regbase, data);
- *blue = vga_r (cinfo->regbase, data);
+ *red = vga_r(cinfo->regbase, data);
+ *green = vga_r(cinfo->regbase, data);
+ *blue = vga_r(cinfo->regbase, data);
} else {
- *blue = vga_r (cinfo->regbase, data);
- *green = vga_r (cinfo->regbase, data);
- *red = vga_r (cinfo->regbase, data);
+ *blue = vga_r(cinfo->regbase, data);
+ *green = vga_r(cinfo->regbase, data);
+ *red = vga_r(cinfo->regbase, data);
}
}
#endif
-
/*******************************************************************
cirrusfb_WaitBLT()
@@ -2870,10 +2870,10 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c
*********************************************************************/
/* FIXME: use interrupts instead */
-static void cirrusfb_WaitBLT (u8 __iomem *regbase)
+static void cirrusfb_WaitBLT(u8 __iomem *regbase)
{
/* now busy-wait until we're done */
- while (vga_rgfx (regbase, CL_GR31) & 0x08)
+ while (vga_rgfx(regbase, CL_GR31) & 0x08)
/* do nothing */ ;
}
@@ -2883,15 +2883,17 @@ static void cirrusfb_WaitBLT (u8 __iomem *regbase)
perform accelerated "scrolling"
********************************************************************/
-static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
- u_short curx, u_short cury, u_short destx, u_short desty,
- u_short width, u_short height, u_short line_length)
+static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
+ u_short curx, u_short cury,
+ u_short destx, u_short desty,
+ u_short width, u_short height,
+ u_short line_length)
{
u_short nwidth, nheight;
u_long nsrc, ndest;
u_char bltmode;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
nwidth = width - 1;
nheight = height - 1;
@@ -2911,9 +2913,13 @@ static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
nsrc = (cury * line_length) + curx;
ndest = (desty * line_length) + destx;
} else {
- /* this means start addresses are at the end, counting backwards */
- nsrc = cury * line_length + curx + nheight * line_length + nwidth;
- ndest = desty * line_length + destx + nheight * line_length + nwidth;
+ /* this means start addresses are at the end,
+ * counting backwards
+ */
+ nsrc = cury * line_length + curx +
+ nheight * line_length + nwidth;
+ ndest = desty * line_length + destx +
+ nheight * line_length + nwidth;
}
/*
@@ -2929,52 +2935,65 @@ static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
start/stop
*/
- cirrusfb_WaitBLT(regbase);
+ cirrusfb_WaitBLT(regbase);
/* pitch: set to line_length */
- vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
- vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */
- vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */
- vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */
+ /* dest pitch low */
+ vga_wgfx(regbase, CL_GR24, line_length & 0xff);
+ /* dest pitch hi */
+ vga_wgfx(regbase, CL_GR25, line_length >> 8);
+ /* source pitch low */
+ vga_wgfx(regbase, CL_GR26, line_length & 0xff);
+ /* source pitch hi */
+ vga_wgfx(regbase, CL_GR27, line_length >> 8);
/* BLT width: actual number of pixels - 1 */
- vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
- vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */
+ /* BLT width low */
+ vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
+ /* BLT width hi */
+ vga_wgfx(regbase, CL_GR21, nwidth >> 8);
/* BLT height: actual number of lines -1 */
- vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */
- vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */
+ /* BLT height low */
+ vga_wgfx(regbase, CL_GR22, nheight & 0xff);
+ /* BLT width hi */
+ vga_wgfx(regbase, CL_GR23, nheight >> 8);
/* BLT destination */
- vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */
- vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */
- vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */
+ /* BLT dest low */
+ vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
+ /* BLT dest mid */
+ vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
+ /* BLT dest hi */
+ vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
/* BLT source */
- vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff)); /* BLT src low */
- vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8)); /* BLT src mid */
- vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16)); /* BLT src hi */
+ /* BLT src low */
+ vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
+ /* BLT src mid */
+ vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
+ /* BLT src hi */
+ vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
/* BLT mode */
- vga_wgfx (regbase, CL_GR30, bltmode); /* BLT mode */
+ vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
/* BLT ROP: SrcCopy */
- vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */
+ vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
/* and finally: GO! */
- vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */
+ vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
-
/*******************************************************************
cirrusfb_RectFill()
perform accelerated rectangle fill
********************************************************************/
-static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
+static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
u_short x, u_short y, u_short width, u_short height,
u_char color, u_short line_length)
{
@@ -2982,93 +3001,95 @@ static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
u_long ndest;
u_char op;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
nwidth = width - 1;
nheight = height - 1;
ndest = (y * line_length) + x;
- cirrusfb_WaitBLT(regbase);
+ cirrusfb_WaitBLT(regbase);
/* pitch: set to line_length */
- vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
- vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */
- vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */
- vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */
+ vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
+ vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */
+ vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
+ vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */
/* BLT width: actual number of pixels - 1 */
- vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
- vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */
+ vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
+ vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */
/* BLT height: actual number of lines -1 */
- vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */
- vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */
+ vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */
+ vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */
/* BLT destination */
- vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */
- vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */
- vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */
+ /* BLT dest low */
+ vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
+ /* BLT dest mid */
+ vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
+ /* BLT dest hi */
+ vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
/* BLT source: set to 0 (is a dummy here anyway) */
- vga_wgfx (regbase, CL_GR2C, 0x00); /* BLT src low */
- vga_wgfx (regbase, CL_GR2D, 0x00); /* BLT src mid */
- vga_wgfx (regbase, CL_GR2E, 0x00); /* BLT src hi */
+ vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */
+ vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */
+ vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */
/* This is a ColorExpand Blt, using the */
/* same color for foreground and background */
- vga_wgfx (regbase, VGA_GFX_SR_VALUE, color); /* foreground color */
- vga_wgfx (regbase, VGA_GFX_SR_ENABLE, color); /* background color */
+ vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */
+ vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */
op = 0xc0;
if (bits_per_pixel == 16) {
- vga_wgfx (regbase, CL_GR10, color); /* foreground color */
- vga_wgfx (regbase, CL_GR11, color); /* background color */
+ vga_wgfx(regbase, CL_GR10, color); /* foreground color */
+ vga_wgfx(regbase, CL_GR11, color); /* background color */
op = 0x50;
op = 0xd0;
} else if (bits_per_pixel == 32) {
- vga_wgfx (regbase, CL_GR10, color); /* foreground color */
- vga_wgfx (regbase, CL_GR11, color); /* background color */
- vga_wgfx (regbase, CL_GR12, color); /* foreground color */
- vga_wgfx (regbase, CL_GR13, color); /* background color */
- vga_wgfx (regbase, CL_GR14, 0); /* foreground color */
- vga_wgfx (regbase, CL_GR15, 0); /* background color */
+ vga_wgfx(regbase, CL_GR10, color); /* foreground color */
+ vga_wgfx(regbase, CL_GR11, color); /* background color */
+ vga_wgfx(regbase, CL_GR12, color); /* foreground color */
+ vga_wgfx(regbase, CL_GR13, color); /* background color */
+ vga_wgfx(regbase, CL_GR14, 0); /* foreground color */
+ vga_wgfx(regbase, CL_GR15, 0); /* background color */
op = 0x50;
op = 0xf0;
}
/* BLT mode: color expand, Enable 8x8 copy (faster?) */
- vga_wgfx (regbase, CL_GR30, op); /* BLT mode */
+ vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
/* BLT ROP: SrcCopy */
- vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */
+ vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
/* and finally: GO! */
- vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */
+ vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
-
/**************************************************************************
* bestclock() - determine closest possible clock lower(?) than the
* desired pixel clock
**************************************************************************/
-static void bestclock (long freq, long *best, long *nom,
+static void bestclock(long freq, long *best, long *nom,
long *den, long *div, long maxfreq)
{
long n, h, d, f;
- assert (best != NULL);
- assert (nom != NULL);
- assert (den != NULL);
- assert (div != NULL);
- assert (maxfreq > 0);
+ assert(best != NULL);
+ assert(nom != NULL);
+ assert(den != NULL);
+ assert(div != NULL);
+ assert(maxfreq > 0);
*nom = 0;
*den = 0;
*div = 0;
- DPRINTK ("ENTER\n");
+ DPRINTK("ENTER\n");
if (freq < 8000)
freq = 8000;
@@ -3085,7 +3106,7 @@ static void bestclock (long freq, long *best, long *nom,
if (d > 31)
d = (d / 2) * 2;
h = (14318 * n) / d;
- if (abs (h - freq) < abs (*best - freq)) {
+ if (abs(h - freq) < abs(*best - freq)) {
*best = h;
*nom = n;
if (d < 32) {
@@ -3102,7 +3123,7 @@ static void bestclock (long freq, long *best, long *nom,
if (d > 31)
d = (d / 2) * 2;
h = (14318 * n) / d;
- if (abs (h - freq) < abs (*best - freq)) {
+ if (abs(h - freq) < abs(*best - freq)) {
*best = h;
*nom = n;
if (d < 32) {
@@ -3116,14 +3137,13 @@ static void bestclock (long freq, long *best, long *nom,
}
}
- DPRINTK ("Best possible values for given frequency:\n");
- DPRINTK (" best: %ld kHz nom: %ld den: %ld div: %ld\n",
- freq, *nom, *den, *div);
+ DPRINTK("Best possible values for given frequency:\n");
+ DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n",
+ freq, *nom, *den, *div);
- DPRINTK ("EXIT\n");
+ DPRINTK("EXIT\n");
}
-
/* -------------------------------------------------------------------------
*
* debugging functions
@@ -3145,21 +3165,20 @@ static void bestclock (long freq, long *best, long *nom,
*/
static
-void cirrusfb_dbg_print_byte (const char *name, unsigned char val)
+void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
{
- DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
- name, val,
- val & 0x80 ? '1' : '0',
- val & 0x40 ? '1' : '0',
- val & 0x20 ? '1' : '0',
- val & 0x10 ? '1' : '0',
- val & 0x08 ? '1' : '0',
- val & 0x04 ? '1' : '0',
- val & 0x02 ? '1' : '0',
- val & 0x01 ? '1' : '0');
+ DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
+ name, val,
+ val & 0x80 ? '1' : '0',
+ val & 0x40 ? '1' : '0',
+ val & 0x20 ? '1' : '0',
+ val & 0x10 ? '1' : '0',
+ val & 0x08 ? '1' : '0',
+ val & 0x04 ? '1' : '0',
+ val & 0x02 ? '1' : '0',
+ val & 0x01 ? '1' : '0');
}
-
/**
* cirrusfb_dbg_print_regs
* @base: If using newmmio, the newmmio base address, otherwise %NULL
@@ -3172,25 +3191,26 @@ void cirrusfb_dbg_print_byte (const char *name, unsigned char val)
*/
static
-void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...)
+void cirrusfb_dbg_print_regs(caddr_t regbase,
+ enum cirrusfb_dbg_reg_class reg_class, ...)
{
va_list list;
unsigned char val = 0;
unsigned reg;
char *name;
- va_start (list, reg_class);
+ va_start(list, reg_class);
- name = va_arg (list, char *);
+ name = va_arg(list, char *);
while (name != NULL) {
- reg = va_arg (list, int);
+ reg = va_arg(list, int);
switch (reg_class) {
case CRT:
- val = vga_rcrt (regbase, (unsigned char) reg);
+ val = vga_rcrt(regbase, (unsigned char) reg);
break;
case SEQ:
- val = vga_rseq (regbase, (unsigned char) reg);
+ val = vga_rseq(regbase, (unsigned char) reg);
break;
default:
/* should never occur */
@@ -3198,15 +3218,14 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
break;
}
- cirrusfb_dbg_print_byte (name, val);
+ cirrusfb_dbg_print_byte(name, val);
- name = va_arg (list, char *);
+ name = va_arg(list, char *);
}
- va_end (list);
+ va_end(list);
}
-
/**
* cirrusfb_dump
* @cirrusfbinfo:
@@ -3214,13 +3233,11 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
* DESCRIPTION:
*/
-static
-void cirrusfb_dump (void)
+static void cirrusfb_dump(void)
{
- cirrusfb_dbg_reg_dump (NULL);
+ cirrusfb_dbg_reg_dump(NULL);
}
-
/**
* cirrusfb_dbg_reg_dump
* @base: If using newmmio, the newmmio base address, otherwise %NULL
@@ -3232,11 +3249,11 @@ void cirrusfb_dump (void)
*/
static
-void cirrusfb_dbg_reg_dump (caddr_t regbase)
+void cirrusfb_dbg_reg_dump(caddr_t regbase)
{
- DPRINTK ("CIRRUSFB VGA CRTC register dump:\n");
+ DPRINTK("CIRRUSFB VGA CRTC register dump:\n");
- cirrusfb_dbg_print_regs (regbase, CRT,
+ cirrusfb_dbg_print_regs(regbase, CRT,
"CR00", 0x00,
"CR01", 0x01,
"CR02", 0x02,
@@ -3286,11 +3303,11 @@ void cirrusfb_dbg_reg_dump (caddr_t regbase)
"CR3F", 0x3F,
NULL);
- DPRINTK ("\n");
+ DPRINTK("\n");
- DPRINTK ("CIRRUSFB VGA SEQ register dump:\n");
+ DPRINTK("CIRRUSFB VGA SEQ register dump:\n");
- cirrusfb_dbg_print_regs (regbase, SEQ,
+ cirrusfb_dbg_print_regs(regbase, SEQ,
"SR00", 0x00,
"SR01", 0x01,
"SR02", 0x02,
@@ -3319,7 +3336,7 @@ void cirrusfb_dbg_reg_dump (caddr_t regbase)
"SR1F", 0x1F,
NULL);
- DPRINTK ("\n");
+ DPRINTK("\n");
}
#endif /* CIRRUSFB_DEBUG */
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index dea6579941b..17b5267f44d 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -29,7 +29,7 @@
#include <asm/hardware.h>
#include <asm/mach-types.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/hardware/clps7111.h>
#include <asm/arch/syspld.h>
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index d9315d99445..b63860f7bea 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -18,8 +18,8 @@
*/
#if defined(__arm__)
-#define DUMMY_COLUMNS ORIG_VIDEO_COLS
-#define DUMMY_ROWS ORIG_VIDEO_LINES
+#define DUMMY_COLUMNS screen_info.orig_video_cols
+#define DUMMY_ROWS screen_info.orig_video_lines
#elif defined(__hppa__)
/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */
#define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index e58c87b3e3a..0f32f4a00b2 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -78,7 +78,6 @@
#include <asm/fb.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#ifdef CONFIG_ATARI
#include <asm/atariints.h>
#endif
@@ -2169,7 +2168,7 @@ static __inline__ void updatescrollmode(struct display *p,
}
static int fbcon_resize(struct vc_data *vc, unsigned int width,
- unsigned int height)
+ unsigned int height, unsigned int user)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par;
@@ -2406,7 +2405,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
update_screen(vc);
}
- if (fbcon_is_inactive(vc, info) ||
+ if (mode_switch || fbcon_is_inactive(vc, info) ||
ops->blank_state != FB_BLANK_UNBLANK)
fbcon_del_cursor_timer(info);
else
diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c
index e6aa0eab5bb..6be72bb218e 100644
--- a/drivers/video/console/font_10x18.c
+++ b/drivers/video/console/font_10x18.c
@@ -5133,14 +5133,14 @@ static const unsigned char fontdata_10x18[FONTDATAMAX] = {
const struct font_desc font_10x18 = {
- FONT10x18_IDX,
- "10x18",
- 10,
- 18,
- fontdata_10x18,
+ .idx = FONT10x18_IDX,
+ .name = "10x18",
+ .width = 10,
+ .height = 18,
+ .data = fontdata_10x18,
#ifdef __sparc__
- 5
+ .pref = 5,
#else
- -1
+ .pref = -1,
#endif
};
diff --git a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c
index 89976cd9749..46e86e67aa6 100644
--- a/drivers/video/console/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
@@ -3342,10 +3342,11 @@ static const unsigned char fontdata_6x11[FONTDATAMAX] = {
const struct font_desc font_vga_6x11 = {
- VGA6x11_IDX,
- "ProFont6x11",
- 6,
- 11,
- fontdata_6x11,
- -2000 /* Try avoiding this font if possible unless on MAC */
+ .idx = VGA6x11_IDX,
+ .name = "ProFont6x11",
+ .width = 6,
+ .height = 11,
+ .data = fontdata_6x11,
+ /* Try avoiding this font if possible unless on MAC */
+ .pref = -2000,
};
diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c
index bbf11664739..3b7dbf9c060 100644
--- a/drivers/video/console/font_7x14.c
+++ b/drivers/video/console/font_7x14.c
@@ -4109,10 +4109,10 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
const struct font_desc font_7x14 = {
- FONT7x14_IDX,
- "7x14",
- 7,
- 14,
- fontdata_7x14,
- 0
+ .idx = FONT7x14_IDX,
+ .name = "7x14",
+ .width = 7,
+ .height = 14,
+ .data = fontdata_7x14,
+ .pref = 0,
};
diff --git a/drivers/video/console/font_8x16.c b/drivers/video/console/font_8x16.c
index 74fe86f28ff..00a0c67a5c7 100644
--- a/drivers/video/console/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
@@ -5,6 +5,7 @@
/**********************************************/
#include <linux/font.h>
+#include <linux/module.h>
#define FONTDATAMAX 4096
@@ -4622,10 +4623,11 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
const struct font_desc font_vga_8x16 = {
- VGA8x16_IDX,
- "VGA8x16",
- 8,
- 16,
- fontdata_8x16,
- 0
+ .idx = VGA8x16_IDX,
+ .name = "VGA8x16",
+ .width = 8,
+ .height = 16,
+ .data = fontdata_8x16,
+ .pref = 0,
};
+EXPORT_SYMBOL(font_vga_8x16);
diff --git a/drivers/video/console/font_8x8.c b/drivers/video/console/font_8x8.c
index 26199f8ee90..9f56efe2cee 100644
--- a/drivers/video/console/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
@@ -2574,10 +2574,10 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
const struct font_desc font_vga_8x8 = {
- VGA8x8_IDX,
- "VGA8x8",
- 8,
- 8,
- fontdata_8x8,
- 0
+ .idx = VGA8x8_IDX,
+ .name = "VGA8x8",
+ .width = 8,
+ .height = 8,
+ .data = fontdata_8x8,
+ .pref = 0,
};
diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index 40f3d4eeb19..639e31ae110 100644
--- a/drivers/video/console/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -262,14 +262,14 @@ static const unsigned char acorndata_8x8[] = {
};
const struct font_desc font_acorn_8x8 = {
- ACORN8x8_IDX,
- "Acorn8x8",
- 8,
- 8,
- acorndata_8x8,
+ .idx = ACORN8x8_IDX,
+ .name = "Acorn8x8",
+ .width = 8,
+ .height = 8,
+ .data = acorndata_8x8,
#ifdef CONFIG_ARCH_ACORN
- 20
+ .pref = 20,
#else
- 0
+ .pref = 0,
#endif
};
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index d818234fdf1..a19a7f33133 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -2148,11 +2148,11 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
};
const struct font_desc font_mini_4x6 = {
- MINI4x6_IDX,
- "MINI4x6",
- 4,
- 6,
- fontdata_mini_4x6,
- 3
+ .idx = MINI4x6_IDX,
+ .name = "MINI4x6",
+ .width = 4,
+ .height = 6,
+ .data = fontdata_mini_4x6,
+ .pref = 3,
};
diff --git a/drivers/video/console/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index e646c88f55c..dc6ad539ca4 100644
--- a/drivers/video/console/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
@@ -2578,10 +2578,10 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
};
const struct font_desc font_pearl_8x8 = {
- PEARL8x8_IDX,
- "PEARL8x8",
- 8,
- 8,
- fontdata_pearl8x8,
- 2
+ .idx = PEARL8x8_IDX,
+ .name = "PEARL8x8",
+ .width = 8,
+ .height = 8,
+ .data = fontdata_pearl8x8,
+ .pref = 2,
};
diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index ab5eb93407b..d3643853c33 100644
--- a/drivers/video/console/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -6152,14 +6152,14 @@ static const unsigned char fontdata_sun12x22[FONTDATAMAX] = {
const struct font_desc font_sun_12x22 = {
- SUN12x22_IDX,
- "SUN12x22",
- 12,
- 22,
- fontdata_sun12x22,
+ .idx = SUN12x22_IDX,
+ .name = "SUN12x22",
+ .width = 12,
+ .height = 22,
+ .data = fontdata_sun12x22,
#ifdef __sparc__
- 5
+ .pref = 5,
#else
- -1
+ .pref = -1,
#endif
};
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 41f910f5529..5abf290c6eb 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -262,14 +262,14 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
};
const struct font_desc font_sun_8x16 = {
- SUN8x16_IDX,
- "SUN8x16",
- 8,
- 16,
- fontdata_sun8x16,
+ .idx = SUN8x16_IDX,
+ .name = "SUN8x16",
+ .width = 8,
+ .height = 16,
+ .data = fontdata_sun8x16,
#ifdef __sparc__
- 10
+ .pref = 10,
#else
- -1
+ .pref = -1,
#endif
};
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index dda0586ab3f..d31b203bf65 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -98,14 +98,19 @@ static inline void newport_init_cmap(void)
}
}
-static void newport_show_logo(void)
+static const struct linux_logo *newport_show_logo(void)
{
#ifdef CONFIG_LOGO_SGI_CLUT224
const struct linux_logo *logo = fb_find_logo(8);
- const unsigned char *clut = logo->clut;
- const unsigned char *data = logo->data;
+ const unsigned char *clut;
+ const unsigned char *data;
unsigned long i;
+ if (!logo)
+ return NULL;
+ clut = logo->clut;
+ data = logo->data;
+
for (i = 0; i < logo->clutsize; i++) {
newport_bfwait(npregs);
newport_cmap_setaddr(npregs, i + 0x20);
@@ -123,6 +128,8 @@ static void newport_show_logo(void)
for (i = 0; i < logo->width*logo->height; i++)
npregs->go.hostrw0 = *data++ << 24;
+
+ return logo;
#endif /* CONFIG_LOGO_SGI_CLUT224 */
}
@@ -465,9 +472,10 @@ static int newport_switch(struct vc_data *vc)
npregs->cset.topscan = 0x3ff;
if (!logo_drawn) {
- newport_show_logo();
- logo_drawn = 1;
- logo_active = 1;
+ if (newport_show_logo()) {
+ logo_drawn = 1;
+ logo_active = 1;
+ }
}
return 1;
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 03cfb7ac573..25f835bf3d7 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -15,7 +15,6 @@
#include <linux/fb.h>
#include <linux/slab.h>
-#include <asm/uaccess.h>
#include <asm/io.h>
#include "fbcon.h"
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d18b73aafa0..f65bcd314d5 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -362,7 +362,7 @@ static const char *vgacon_startup(void)
u16 saved1, saved2;
volatile u16 *p;
- if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
+ if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB) {
no_vga:
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -372,29 +372,30 @@ static const char *vgacon_startup(void)
#endif
}
- /* SCREEN_INFO initialized? */
- if ((ORIG_VIDEO_MODE == 0) &&
- (ORIG_VIDEO_LINES == 0) &&
- (ORIG_VIDEO_COLS == 0))
+ /* boot_params.screen_info initialized? */
+ if ((screen_info.orig_video_mode == 0) &&
+ (screen_info.orig_video_lines == 0) &&
+ (screen_info.orig_video_cols == 0))
goto no_vga;
/* VGA16 modes are not handled by VGACON */
- if ((ORIG_VIDEO_MODE == 0x0D) || /* 320x200/4 */
- (ORIG_VIDEO_MODE == 0x0E) || /* 640x200/4 */
- (ORIG_VIDEO_MODE == 0x10) || /* 640x350/4 */
- (ORIG_VIDEO_MODE == 0x12) || /* 640x480/4 */
- (ORIG_VIDEO_MODE == 0x6A)) /* 800x600/4, 0x6A is very common */
+ if ((screen_info.orig_video_mode == 0x0D) || /* 320x200/4 */
+ (screen_info.orig_video_mode == 0x0E) || /* 640x200/4 */
+ (screen_info.orig_video_mode == 0x10) || /* 640x350/4 */
+ (screen_info.orig_video_mode == 0x12) || /* 640x480/4 */
+ (screen_info.orig_video_mode == 0x6A)) /* 800x600/4 (VESA) */
goto no_vga;
- vga_video_num_lines = ORIG_VIDEO_LINES;
- vga_video_num_columns = ORIG_VIDEO_COLS;
+ vga_video_num_lines = screen_info.orig_video_lines;
+ vga_video_num_columns = screen_info.orig_video_cols;
state.vgabase = NULL;
- if (ORIG_VIDEO_MODE == 7) { /* Is this a monochrome display? */
+ if (screen_info.orig_video_mode == 7) {
+ /* Monochrome display */
vga_vram_base = 0xb0000;
vga_video_port_reg = VGA_CRT_IM;
vga_video_port_val = VGA_CRT_DM;
- if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
+ if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
static struct resource ega_console_resource =
{ .name = "ega", .start = 0x3B0, .end = 0x3BF };
vga_video_type = VIDEO_TYPE_EGAM;
@@ -422,12 +423,12 @@ static const char *vgacon_startup(void)
vga_vram_base = 0xb8000;
vga_video_port_reg = VGA_CRT_IC;
vga_video_port_val = VGA_CRT_DC;
- if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
+ if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
int i;
vga_vram_size = 0x8000;
- if (!ORIG_VIDEO_ISVGA) {
+ if (!screen_info.orig_video_isVGA) {
static struct resource ega_console_resource
= { .name = "ega", .start = 0x3C0, .end = 0x3DF };
vga_video_type = VIDEO_TYPE_EGAC;
@@ -521,14 +522,14 @@ static const char *vgacon_startup(void)
|| vga_video_type == VIDEO_TYPE_VGAC
|| vga_video_type == VIDEO_TYPE_EGAM) {
vga_hardscroll_enabled = vga_hardscroll_user_enable;
- vga_default_font_height = ORIG_VIDEO_POINTS;
- vga_video_font_height = ORIG_VIDEO_POINTS;
+ vga_default_font_height = screen_info.orig_video_points;
+ vga_video_font_height = screen_info.orig_video_points;
/* This may be suboptimal but is a safe bet - go with it */
vga_scan_lines =
vga_video_font_height * vga_video_num_lines;
}
- vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
+ vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH;
vgacon_yres = vga_scan_lines;
if (!vga_init_done) {
@@ -798,7 +799,7 @@ static int vgacon_switch(struct vc_data *c)
{
int x = c->vc_cols * VGA_FONTWIDTH;
int y = c->vc_rows * c->vc_font.height;
- int rows = ORIG_VIDEO_LINES * vga_default_font_height/
+ int rows = screen_info.orig_video_lines * vga_default_font_height/
c->vc_font.height;
/*
* We need to save screen size here as it's the only way
@@ -818,7 +819,7 @@ static int vgacon_switch(struct vc_data *c)
if ((vgacon_xres != x || vgacon_yres != y) &&
(!(vga_video_num_columns % 2) &&
- vga_video_num_columns <= ORIG_VIDEO_COLS &&
+ vga_video_num_columns <= screen_info.orig_video_cols &&
vga_video_num_lines <= rows))
vgacon_doresize(c, c->vc_cols, c->vc_rows);
}
@@ -1278,13 +1279,14 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
#endif
static int vgacon_resize(struct vc_data *c, unsigned int width,
- unsigned int height)
+ unsigned int height, unsigned int user)
{
- if (width % 2 || width > ORIG_VIDEO_COLS ||
- height > (ORIG_VIDEO_LINES * vga_default_font_height)/
+ if (width % 2 || width > screen_info.orig_video_cols ||
+ height > (screen_info.orig_video_lines * vga_default_font_height)/
c->vc_font.height)
- /* let svgatextmode tinker with video timings */
- return 0;
+ /* let svgatextmode tinker with video timings and
+ return success */
+ return (user) ? 0 : -EINVAL;
if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
vgacon_doresize(c, width, height);
@@ -1312,8 +1314,8 @@ static void vgacon_save_screen(struct vc_data *c)
* console initialization routines.
*/
vga_bootup_console = 1;
- c->vc_x = ORIG_X;
- c->vc_y = ORIG_Y;
+ c->vc_x = screen_info.orig_x;
+ c->vc_y = screen_info.orig_y;
}
/* We can't copy in more then the size of the video buffer,
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 30ede6e8830..9bb2cbfe4a3 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -50,7 +50,6 @@
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#ifdef __arm__
#include <asm/mach-types.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 33be46ccb54..cc2810ef5de 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -57,7 +57,7 @@
#include <asm/types.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <video/epson1355.h>
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 1a8643f053d..a0c5d9d90d7 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -19,7 +19,6 @@
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/list.h>
-#include <asm/uaccess.h>
/* to support deferred IO */
#include <linux/rmap.h>
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
index c5c45203833..cdafbe14ef1 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fb_draw.h
@@ -2,6 +2,7 @@
#define _FB_DRAW_H
#include <asm/types.h>
+#include <linux/fb.h>
/*
* Compose two values, using a bitmask as decision value
@@ -69,4 +70,97 @@ pixel_to_pat( u32 bpp, u32 pixel)
}
}
#endif
+
+#ifdef CONFIG_FB_CFB_REV_PIXELS_IN_BYTE
+#if BITS_PER_LONG == 64
+#define REV_PIXELS_MASK1 0x5555555555555555ul
+#define REV_PIXELS_MASK2 0x3333333333333333ul
+#define REV_PIXELS_MASK4 0x0f0f0f0f0f0f0f0ful
+#else
+#define REV_PIXELS_MASK1 0x55555555ul
+#define REV_PIXELS_MASK2 0x33333333ul
+#define REV_PIXELS_MASK4 0x0f0f0f0ful
+#endif
+
+static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
+ u32 bswapmask)
+{
+ if (bswapmask & 1)
+ val = comp(val >> 1, val << 1, REV_PIXELS_MASK1);
+ if (bswapmask & 2)
+ val = comp(val >> 2, val << 2, REV_PIXELS_MASK2);
+ if (bswapmask & 3)
+ val = comp(val >> 4, val << 4, REV_PIXELS_MASK4);
+}
+
+static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask)
+{
+ u32 mask;
+
+ if (!bswapmask) {
+ mask = FB_SHIFT_HIGH(~(u32)0, index);
+ } else {
+ mask = 0xff << FB_LEFT_POS(8);
+ mask = FB_SHIFT_LOW(mask, index & (bswapmask)) & mask;
+ mask = FB_SHIFT_HIGH(mask, index & ~(bswapmask));
+#if defined(__i386__) || defined(__x86_64__)
+ /* Shift argument is limited to 0 - 31 on x86 based CPU's */
+ if(index + bswapmask < 32)
+#endif
+ mask |= FB_SHIFT_HIGH(~(u32)0,
+ (index + bswapmask) & ~(bswapmask));
+ }
+ return mask;
+}
+
+static inline unsigned long fb_shifted_pixels_mask_long(u32 index, u32 bswapmask)
+{
+ unsigned long mask;
+
+ if (!bswapmask) {
+ mask = FB_SHIFT_HIGH(~0UL, index);
+ } else {
+ mask = 0xff << FB_LEFT_POS(8);
+ mask = FB_SHIFT_LOW(mask, index & (bswapmask)) & mask;
+ mask = FB_SHIFT_HIGH(mask, index & ~(bswapmask));
+#if defined(__i386__) || defined(__x86_64__)
+ /* Shift argument is limited to 0 - 31 on x86 based CPU's */
+ if(index + bswapmask < BITS_PER_LONG)
+#endif
+ mask |= FB_SHIFT_HIGH(~0UL,
+ (index + bswapmask) & ~(bswapmask));
+ }
+ return mask;
+}
+
+
+static inline u32 fb_compute_bswapmask(struct fb_info *info)
+{
+ u32 bswapmask = 0;
+ unsigned bpp = info->var.bits_per_pixel;
+
+ if ((bpp < 8) && (info->var.nonstd & FB_NONSTD_REV_PIX_IN_B)) {
+ /*
+ * Reversed order of pixel layout in bytes
+ * works only for 1, 2 and 4 bpp
+ */
+ bswapmask = 7 - bpp + 1;
+ }
+ return bswapmask;
+}
+
+#else /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
+
+static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
+ u32 bswapmask)
+{
+ return val;
+}
+
+#define fb_shifted_pixels_mask_u32(i, b) FB_SHIFT_HIGH(~(u32)0, (i))
+#define fb_shifted_pixels_mask_long(i, b) FB_SHIFT_HIGH(~0UL, (i))
+#define fb_compute_bswapmask(...) 0
+
+#endif /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
+
#endif /* FB_DRAW_H */
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
index cf2538d669c..ff275d7f3ea 100644
--- a/drivers/video/fb_sys_fops.c
+++ b/drivers/video/fb_sys_fops.c
@@ -11,7 +11,7 @@
*/
#include <linux/fb.h>
#include <linux/module.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
loff_t *ppos)
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 148108afdd5..91b78e69150 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -15,8 +15,7 @@
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/slab.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
static u16 red2[] __read_mostly = {
0x0000, 0xaaaa
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 07402720470..1194f5e060e 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1567,8 +1567,6 @@ int fb_new_modelist(struct fb_info *info)
static char *video_options[FB_MAX] __read_mostly;
static int ofonly __read_mostly;
-extern const char *global_mode_option;
-
/**
* fb_get_options - get kernel boot parameters
* @name: framebuffer name as it would appear in
@@ -1636,7 +1634,7 @@ static int __init video_setup(char *options)
}
if (!global && !strstr(options, "fb:")) {
- global_mode_option = options;
+ fb_mode_option = options;
global = 1;
}
@@ -1663,7 +1661,6 @@ EXPORT_SYMBOL(register_framebuffer);
EXPORT_SYMBOL(unregister_framebuffer);
EXPORT_SYMBOL(num_registered_fb);
EXPORT_SYMBOL(registered_fb);
-EXPORT_SYMBOL(fb_prepare_logo);
EXPORT_SYMBOL(fb_show_logo);
EXPORT_SYMBOL(fb_set_var);
EXPORT_SYMBOL(fb_blank);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 438b9411905..4ba9c089441 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -591,7 +591,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
{
struct fb_videomode *mode, *m;
unsigned char *block;
- int num = 0, i;
+ int num = 0, i, first = 1;
mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
if (mode == NULL)
@@ -608,8 +608,6 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
DPRINTK(" Detailed Timings\n");
block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
- int first = 1;
-
if (!(block[0] == 0x00 && block[1] == 0x00)) {
get_detailed_timing(block, &mode[num]);
if (first) {
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 5e30b40c8c0..583185fd7c9 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -566,12 +566,7 @@ static int __init lxfb_setup(char *options)
if (!options || !*options)
return 0;
- while (1) {
- char *opt = strsep(&options, ",");
-
- if (opt == NULL)
- break;
-
+ while ((opt = strsep(&options, ",")) != NULL) {
if (!*opt)
continue;
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
index 23a6bcc3e3c..e92337bef50 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/gxt4500.c
@@ -636,7 +636,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev,
info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);
if (!info) {
- dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record");
+ dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n");
goto err_free_fb;
}
par = info->par;
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index abfcb50364c..94e0df8a6f6 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -45,7 +45,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/list.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
/* Apollo controller specific defines */
#define APOLLO_START_NEW_IMG 0xA0
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 94f4511023d..3ab91bf2157 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -29,7 +29,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#if defined(CONFIG_PPC)
#include <linux/nvram.h>
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index a1258989859..11609552a38 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -34,7 +34,6 @@
#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
#include <asm/arch/imxfb.h>
/*
@@ -467,7 +466,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
info->var.vmode = FB_VMODE_NONINTERLACED;
info->fbops = &imxfb_ops;
- info->flags = FBINFO_FLAG_DEFAULT;
+ info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
fbi->rgb[RGB_16] = &def_rgb_16;
fbi->rgb[RGB_8] = &def_rgb_8;
@@ -480,6 +479,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
info->var.yres_virtual = inf->yres;
fbi->max_bpp = inf->bpp;
info->var.bits_per_pixel = inf->bpp;
+ info->var.nonstd = inf->nonstd;
info->var.pixclock = inf->pixclock;
info->var.hsync_len = inf->hsync_len;
info->var.left_margin = inf->left_margin;
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 6148300fadd..2fe3f7def53 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -231,8 +231,8 @@ struct intelfb_hwstate {
struct intelfb_heap_data {
u32 physical;
u8 __iomem *virtual;
- u32 offset; // in GATT pages
- u32 size; // in bytes
+ u32 offset; /* in GATT pages */
+ u32 size; /* in bytes */
};
#ifdef CONFIG_FB_INTEL_I2C
@@ -270,9 +270,9 @@ struct intelfb_info {
struct intelfb_hwstate save_state;
/* agpgart structs */
- struct agp_memory *gtt_fb_mem; // use all stolen memory or vram
- struct agp_memory *gtt_ring_mem; // ring buffer
- struct agp_memory *gtt_cursor_mem; // hw cursor
+ struct agp_memory *gtt_fb_mem; /* use all stolen memory or vram */
+ struct agp_memory *gtt_ring_mem; /* ring buffer */
+ struct agp_memory *gtt_cursor_mem; /* hw cursor */
/* use a gart reserved fb mem */
u8 fbmem_gart;
@@ -346,7 +346,7 @@ struct intelfb_info {
/* driver registered */
int registered;
-
+
/* index into plls */
int pll_index;
@@ -355,7 +355,10 @@ struct intelfb_info {
struct intelfb_output_rec output[MAX_OUTPUTS];
};
-#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM))
+#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G) || \
+ ((dinfo)->chipset == INTEL_915GM) || \
+ ((dinfo)->chipset == INTEL_945G) || \
+ ((dinfo)->chipset==INTEL_945GM))
#ifndef FBIO_WAITFORVSYNC
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index 61e4c8759b2..94c08bb5acf 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -58,7 +58,8 @@ static void intelfb_gpio_setscl(void *data, int state)
struct intelfb_info *dinfo = chan->dinfo;
u32 val;
- OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
+ OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) |
+ SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
val = INREG(chan->reg);
}
@@ -68,7 +69,8 @@ static void intelfb_gpio_setsda(void *data, int state)
struct intelfb_info *dinfo = chan->dinfo;
u32 val;
- OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
+ OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) |
+ SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
val = INREG(chan->reg);
}
@@ -97,26 +99,26 @@ static int intelfb_gpio_getsda(void *data)
}
static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
- struct intelfb_i2c_chan *chan,
- const u32 reg, const char *name)
+ struct intelfb_i2c_chan *chan,
+ const u32 reg, const char *name)
{
int rc;
- chan->dinfo = dinfo;
- chan->reg = reg;
+ chan->dinfo = dinfo;
+ chan->reg = reg;
snprintf(chan->adapter.name, sizeof(chan->adapter.name),
"intelfb %s", name);
- chan->adapter.owner = THIS_MODULE;
- chan->adapter.id = I2C_HW_B_INTELFB;
+ chan->adapter.owner = THIS_MODULE;
+ chan->adapter.id = I2C_HW_B_INTELFB;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
- chan->algo.setsda = intelfb_gpio_setsda;
- chan->algo.setscl = intelfb_gpio_setscl;
- chan->algo.getsda = intelfb_gpio_getsda;
- chan->algo.getscl = intelfb_gpio_getscl;
- chan->algo.udelay = 40;
- chan->algo.timeout = 20;
- chan->algo.data = chan;
+ chan->algo.setsda = intelfb_gpio_setsda;
+ chan->algo.setscl = intelfb_gpio_setscl;
+ chan->algo.getsda = intelfb_gpio_getsda;
+ chan->algo.getscl = intelfb_gpio_getscl;
+ chan->algo.udelay = 40;
+ chan->algo.timeout = 20;
+ chan->algo.data = chan;
i2c_set_adapdata(&chan->adapter, chan);
@@ -142,40 +144,44 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
/* setup the DDC bus for analog output */
- intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A");
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA,
+ "CRTDDC_A");
i++;
- /* need to add the output busses for each device
- - this function is very incomplete
- - i915GM has LVDS and TVOUT for example
- */
- switch(dinfo->chipset) {
+ /* need to add the output busses for each device
+ - this function is very incomplete
+ - i915GM has LVDS and TVOUT for example
+ */
+ switch(dinfo->chipset) {
case INTEL_830M:
case INTEL_845G:
case INTEL_855GM:
case INTEL_865G:
dinfo->output[i].type = INTELFB_OUTPUT_DVO;
- intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D");
- intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E");
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus,
+ GPIOD, "DVODDC_D");
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
+ GPIOE, "DVOI2C_E");
i++;
break;
case INTEL_915G:
case INTEL_915GM:
- /* has some LVDS + tv-out */
+ /* has some LVDS + tv-out */
case INTEL_945G:
case INTEL_945GM:
/* SDVO ports have a single control bus - 2 devices */
dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
- intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E");
+ intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
+ GPIOE, "SDVOCTRL_E");
/* TODO: initialize the SDVO */
-// I830SDVOInit(pScrn, i, DVOB);
+ /* I830SDVOInit(pScrn, i, DVOB); */
i++;
/* set up SDVOC */
dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
/* TODO: initialize the SDVO */
-// I830SDVOInit(pScrn, i, DVOC);
+ /* I830SDVOInit(pScrn, i, DVOC); */
i++;
break;
}
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index b75eda84858..e8e38edb9b5 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -99,13 +99,6 @@
* Add vram option to reserve more memory than stolen by BIOS
* Fix intelfbhw_pan_display typo
* Add __initdata annotations
- *
- * TODO:
- *
- *
- * Wish List:
- *
- *
*/
#include <linux/module.h>
@@ -222,8 +215,8 @@ static struct pci_driver intelfb_driver = {
/* Module description/parameters */
MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, "
"Sylvain Meyer <sylvain.meyer@worldonline.fr>");
-MODULE_DESCRIPTION(
- "Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS " chipsets");
+MODULE_DESCRIPTION("Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS
+ " chipsets");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
@@ -271,8 +264,7 @@ MODULE_PARM_DESC(mode,
#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0)
#define OPT_STRVAL(opt, name) (opt + strlen(name))
-static __inline__ char *
-get_opt_string(const char *this_opt, const char *name)
+static __inline__ char * get_opt_string(const char *this_opt, const char *name)
{
const char *p;
int i;
@@ -290,8 +282,8 @@ get_opt_string(const char *this_opt, const char *name)
return ret;
}
-static __inline__ int
-get_opt_int(const char *this_opt, const char *name, int *ret)
+static __inline__ int get_opt_int(const char *this_opt, const char *name,
+ int *ret)
{
if (!ret)
return 0;
@@ -303,8 +295,8 @@ get_opt_int(const char *this_opt, const char *name, int *ret)
return 1;
}
-static __inline__ int
-get_opt_bool(const char *this_opt, const char *name, int *ret)
+static __inline__ int get_opt_bool(const char *this_opt, const char *name,
+ int *ret)
{
if (!ret)
return 0;
@@ -324,8 +316,7 @@ get_opt_bool(const char *this_opt, const char *name, int *ret)
return 1;
}
-static int __init
-intelfb_setup(char *options)
+static int __init intelfb_setup(char *options)
{
char *this_opt;
@@ -355,7 +346,7 @@ intelfb_setup(char *options)
continue;
if (get_opt_bool(this_opt, "accel", &accel))
;
- else if (get_opt_int(this_opt, "vram", &vram))
+ else if (get_opt_int(this_opt, "vram", &vram))
;
else if (get_opt_bool(this_opt, "hwcursor", &hwcursor))
;
@@ -376,8 +367,7 @@ intelfb_setup(char *options)
#endif
-static int __init
-intelfb_init(void)
+static int __init intelfb_init(void)
{
#ifndef MODULE
char *option = NULL;
@@ -401,8 +391,7 @@ intelfb_init(void)
return pci_register_driver(&intelfb_driver);
}
-static void __exit
-intelfb_exit(void)
+static void __exit intelfb_exit(void)
{
DBG_MSG("intelfb_exit\n");
pci_unregister_driver(&intelfb_driver);
@@ -428,8 +417,8 @@ static inline void __devinit set_mtrr(struct intelfb_info *dinfo)
}
static inline void unset_mtrr(struct intelfb_info *dinfo)
{
- if (dinfo->has_mtrr)
- mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
+ if (dinfo->has_mtrr)
+ mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
dinfo->aperture.size);
}
#else
@@ -442,8 +431,7 @@ static inline void unset_mtrr(struct intelfb_info *dinfo)
* driver init / cleanup *
***************************************************************/
-static void
-cleanup(struct intelfb_info *dinfo)
+static void cleanup(struct intelfb_info *dinfo)
{
DBG_MSG("cleanup\n");
@@ -499,8 +487,8 @@ cleanup(struct intelfb_info *dinfo)
} while (0)
-static int __devinit
-intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit intelfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct fb_info *info;
struct intelfb_info *dinfo;
@@ -510,8 +498,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
int agp_memtype;
const char *s;
struct agp_bridge_data *bridge;
- int aperture_bar = 0;
- int mmio_bar = 1;
+ int aperture_bar = 0;
+ int mmio_bar = 1;
int offset;
DBG_MSG("intelfb_pci_register\n");
@@ -637,9 +625,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
dinfo->ring.size = RINGBUFFER_SIZE;
dinfo->ring_tail_mask = dinfo->ring.size - 1;
}
- if (dinfo->hwcursor) {
+ if (dinfo->hwcursor)
dinfo->cursor.size = HW_CURSOR_SIZE;
- }
/* Use agpgart to manage the GATT */
if (!(bridge = agp_backend_acquire(pdev))) {
@@ -662,18 +649,15 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
/* set the mem offsets - set them after the already used pages */
- if (dinfo->accel) {
+ if (dinfo->accel)
dinfo->ring.offset = offset + gtt_info.current_memory;
- }
- if (dinfo->hwcursor) {
+ if (dinfo->hwcursor)
dinfo->cursor.offset = offset +
+ gtt_info.current_memory + (dinfo->ring.size >> 12);
- }
- if (dinfo->fbmem_gart) {
+ if (dinfo->fbmem_gart)
dinfo->fb.offset = offset +
+ gtt_info.current_memory + (dinfo->ring.size >> 12)
+ (dinfo->cursor.size >> 12);
- }
/* Allocate memories (which aren't stolen) */
/* Map the fb and MMIO regions */
@@ -689,7 +673,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
dinfo->mmio_base =
(u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
- INTEL_REG_SIZE);
+ INTEL_REG_SIZE);
if (!dinfo->mmio_base) {
ERR_MSG("Cannot remap MMIO region.\n");
cleanup(dinfo);
@@ -820,7 +804,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
if (bailearly == 1)
bailout(dinfo);
- if (FIXED_MODE(dinfo) && ORIG_VIDEO_ISVGA != VIDEO_TYPE_VLFB) {
+ if (FIXED_MODE(dinfo) &&
+ screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) {
ERR_MSG("Video mode must be programmed at boot time.\n");
cleanup(dinfo);
return -ENODEV;
@@ -831,16 +816,14 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Initialise dinfo and related data. */
/* If an initial mode was programmed at boot time, get its details. */
- if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB)
+ if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB)
get_initial_mode(dinfo);
if (bailearly == 3)
bailout(dinfo);
- if (FIXED_MODE(dinfo)) {
- /* remap fb address */
+ if (FIXED_MODE(dinfo)) /* remap fb address */
update_dinfo(dinfo, &dinfo->initial_var);
- }
if (bailearly == 4)
bailout(dinfo);
@@ -939,8 +922,7 @@ intelfb_pci_unregister(struct pci_dev *pdev)
* helper functions *
***************************************************************/
-int __inline__
-intelfb_var_to_depth(const struct fb_var_screeninfo *var)
+int __inline__ intelfb_var_to_depth(const struct fb_var_screeninfo *var)
{
DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n",
var->bits_per_pixel, var->green.length);
@@ -956,8 +938,7 @@ intelfb_var_to_depth(const struct fb_var_screeninfo *var)
}
-static __inline__ int
-var_to_refresh(const struct fb_var_screeninfo *var)
+static __inline__ int var_to_refresh(const struct fb_var_screeninfo *var)
{
int xtot = var->xres + var->left_margin + var->right_margin +
var->hsync_len;
@@ -971,8 +952,7 @@ var_to_refresh(const struct fb_var_screeninfo *var)
* Various intialisation functions *
***************************************************************/
-static void __devinit
-get_initial_mode(struct intelfb_info *dinfo)
+static void __devinit get_initial_mode(struct intelfb_info *dinfo)
{
struct fb_var_screeninfo *var;
int xtot, ytot;
@@ -1039,8 +1019,7 @@ get_initial_mode(struct intelfb_info *dinfo)
}
}
-static int __devinit
-intelfb_init_var(struct intelfb_info *dinfo)
+static int __devinit intelfb_init_var(struct intelfb_info *dinfo)
{
struct fb_var_screeninfo *var;
int msrc = 0;
@@ -1087,10 +1066,9 @@ intelfb_init_var(struct intelfb_info *dinfo)
}
- if (!msrc) {
+ if (!msrc)
msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE,
NULL, 0, NULL, 0);
- }
}
if (!msrc) {
@@ -1122,8 +1100,7 @@ intelfb_init_var(struct intelfb_info *dinfo)
return 0;
}
-static int __devinit
-intelfb_set_fbinfo(struct intelfb_info *dinfo)
+static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo)
{
struct fb_info *info = dinfo->info;
@@ -1159,8 +1136,8 @@ intelfb_set_fbinfo(struct intelfb_info *dinfo)
}
/* Update dinfo to match the active video mode. */
-static void
-update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
+static void update_dinfo(struct intelfb_info *dinfo,
+ struct fb_var_screeninfo *var)
{
DBG_MSG("update_dinfo\n");
@@ -1208,36 +1185,32 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
* fbdev interface *
***************************************************************/
-static int
-intelfb_open(struct fb_info *info, int user)
+static int intelfb_open(struct fb_info *info, int user)
{
struct intelfb_info *dinfo = GET_DINFO(info);
- if (user) {
+ if (user)
dinfo->open++;
- }
return 0;
}
-static int
-intelfb_release(struct fb_info *info, int user)
+static int intelfb_release(struct fb_info *info, int user)
{
struct intelfb_info *dinfo = GET_DINFO(info);
if (user) {
dinfo->open--;
msleep(1);
- if (!dinfo->open) {
+ if (!dinfo->open)
intelfbhw_disable_irq(dinfo);
- }
}
return 0;
}
-static int
-intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+static int intelfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
int change_var = 0;
struct fb_var_screeninfo v;
@@ -1271,15 +1244,15 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
/* Check for a supported bpp. */
- if (v.bits_per_pixel <= 8) {
+ if (v.bits_per_pixel <= 8)
v.bits_per_pixel = 8;
- } else if (v.bits_per_pixel <= 16) {
+ else if (v.bits_per_pixel <= 16) {
if (v.bits_per_pixel == 16)
v.green.length = 6;
v.bits_per_pixel = 16;
- } else if (v.bits_per_pixel <= 32) {
+ } else if (v.bits_per_pixel <= 32)
v.bits_per_pixel = 32;
- } else
+ else
return -EINVAL;
change_var = ((info->var.xres != var->xres) ||
@@ -1361,10 +1334,9 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return 0;
}
-static int
-intelfb_set_par(struct fb_info *info)
+static int intelfb_set_par(struct fb_info *info)
{
- struct intelfb_hwstate *hw;
+ struct intelfb_hwstate *hw;
struct intelfb_info *dinfo = GET_DINFO(info);
if (FIXED_MODE(dinfo)) {
@@ -1372,9 +1344,9 @@ intelfb_set_par(struct fb_info *info)
return -EINVAL;
}
- hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
- if (!hw)
- return -ENOMEM;
+ hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
+ if (!hw)
+ return -ENOMEM;
DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
info->var.yres, info->var.bits_per_pixel);
@@ -1384,15 +1356,15 @@ intelfb_set_par(struct fb_info *info)
if (ACCEL(dinfo, info))
intelfbhw_2d_stop(dinfo);
- memcpy(hw, &dinfo->save_state, sizeof(*hw));
- if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
- goto invalid_mode;
- if (intelfbhw_program_mode(dinfo, hw, 0))
- goto invalid_mode;
+ memcpy(hw, &dinfo->save_state, sizeof(*hw));
+ if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
+ goto invalid_mode;
+ if (intelfbhw_program_mode(dinfo, hw, 0))
+ goto invalid_mode;
#if REGDUMP > 0
- intelfbhw_read_hw_state(dinfo, hw, 0);
- intelfbhw_print_hw_state(dinfo, hw);
+ intelfbhw_read_hw_state(dinfo, hw, 0);
+ intelfbhw_print_hw_state(dinfo, hw);
#endif
update_dinfo(dinfo, &info->var);
@@ -1408,9 +1380,9 @@ intelfb_set_par(struct fb_info *info)
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
FBINFO_HWACCEL_IMAGEBLIT;
- } else {
+ } else
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
- }
+
kfree(hw);
return 0;
invalid_mode:
@@ -1418,9 +1390,9 @@ invalid_mode:
return -EINVAL;
}
-static int
-intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp, struct fb_info *info)
+static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
{
struct intelfb_info *dinfo = GET_DINFO(info);
@@ -1463,23 +1435,22 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0;
}
-static int
-intelfb_blank(int blank, struct fb_info *info)
+static int intelfb_blank(int blank, struct fb_info *info)
{
intelfbhw_do_blank(blank, info);
return 0;
}
-static int
-intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+static int intelfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
intelfbhw_pan_display(var, info);
return 0;
}
/* When/if we have our own ioctls. */
-static int
-intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int intelfb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{
int retval = 0;
struct intelfb_info *dinfo = GET_DINFO(info);
@@ -1499,8 +1470,8 @@ intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
return retval;
}
-static void
-intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
+static void intelfb_fillrect (struct fb_info *info,
+ const struct fb_fillrect *rect)
{
struct intelfb_info *dinfo = GET_DINFO(info);
u32 rop, color;
@@ -1514,7 +1485,7 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
if (rect->rop == ROP_COPY)
rop = PAT_ROP_GXCOPY;
- else // ROP_XOR
+ else /* ROP_XOR */
rop = PAT_ROP_GXXOR;
if (dinfo->depth != 8)
@@ -1528,8 +1499,8 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
rop);
}
-static void
-intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
+static void intelfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *region)
{
struct intelfb_info *dinfo = GET_DINFO(info);
@@ -1545,8 +1516,8 @@ intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
dinfo->pitch, info->var.bits_per_pixel);
}
-static void
-intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void intelfb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
{
struct intelfb_info *dinfo = GET_DINFO(info);
u32 fgcolor, bgcolor;
@@ -1574,8 +1545,7 @@ intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
return cfb_imageblit(info, image);
}
-static int
-intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct intelfb_info *dinfo = GET_DINFO(info);
u32 physical;
@@ -1689,8 +1659,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
return 0;
}
-static int
-intelfb_sync(struct fb_info *info)
+static int intelfb_sync(struct fb_info *info)
{
struct intelfb_info *dinfo = GET_DINFO(info);
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 6a47682d861..2a0e32074f7 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -56,17 +56,16 @@ static struct pll_min_max plls[PLLS_MAX] = {
6, 16, 3, 16,
4, 128, 0, 31,
930000, 1400000, 165000, 48000,
- 4, 2 }, //I8xx
+ 4, 2 }, /* I8xx */
{ 75, 120, 10, 20,
5, 9, 4, 7,
5, 80, 1, 8,
1400000, 2800000, 200000, 96000,
- 10, 5 } //I9xx
+ 10, 5 } /* I9xx */
};
-int
-intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
+int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
{
u32 tmp;
if (!pdev || !dinfo)
@@ -149,9 +148,8 @@ intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
}
}
-int
-intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
- int *stolen_size)
+int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
+ int *stolen_size)
{
struct pci_dev *bridge_dev;
u16 tmp;
@@ -254,8 +252,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
}
}
-int
-intelfbhw_check_non_crt(struct intelfb_info *dinfo)
+int intelfbhw_check_non_crt(struct intelfb_info *dinfo)
{
int dvo = 0;
@@ -271,8 +268,7 @@ intelfbhw_check_non_crt(struct intelfb_info *dinfo)
return dvo;
}
-const char *
-intelfbhw_dvo_to_string(int dvo)
+const char * intelfbhw_dvo_to_string(int dvo)
{
if (dvo & DVOA_PORT)
return "DVO port A";
@@ -287,9 +283,8 @@ intelfbhw_dvo_to_string(int dvo)
}
-int
-intelfbhw_validate_mode(struct intelfb_info *dinfo,
- struct fb_var_screeninfo *var)
+int intelfbhw_validate_mode(struct intelfb_info *dinfo,
+ struct fb_var_screeninfo *var)
{
int bytes_per_pixel;
int tmp;
@@ -322,17 +317,26 @@ intelfbhw_validate_mode(struct intelfb_info *dinfo,
var->yres, VACTIVE_MASK + 1);
return 1;
}
-
- /* Check for interlaced/doublescan modes. */
- if (var->vmode & FB_VMODE_INTERLACED) {
- WRN_MSG("Mode is interlaced.\n");
+ if (var->xres < 4) {
+ WRN_MSG("X resolution too small (%d vs 4).\n", var->xres);
+ return 1;
+ }
+ if (var->yres < 4) {
+ WRN_MSG("Y resolution too small (%d vs 4).\n", var->yres);
return 1;
}
+
+ /* Check for doublescan modes. */
if (var->vmode & FB_VMODE_DOUBLE) {
WRN_MSG("Mode is double-scan.\n");
return 1;
}
+ if ((var->vmode & FB_VMODE_INTERLACED) && (var->yres & 1)) {
+ WRN_MSG("Odd number of lines in interlaced mode\n");
+ return 1;
+ }
+
/* Check if clock is OK. */
tmp = 1000000000 / var->pixclock;
if (tmp < MIN_CLOCK) {
@@ -349,8 +353,7 @@ intelfbhw_validate_mode(struct intelfb_info *dinfo,
return 0;
}
-int
-intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct intelfb_info *dinfo = GET_DINFO(info);
u32 offset, xoffset, yoffset;
@@ -372,9 +375,10 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
offset += dinfo->fb.offset << 12;
dinfo->vsync.pan_offset = offset;
- if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) {
+ if ((var->activate & FB_ACTIVATE_VBL) &&
+ !intelfbhw_enable_irq(dinfo))
dinfo->vsync.pan_display = 1;
- } else {
+ else {
dinfo->vsync.pan_display = 0;
OUTREG(DSPABASE, offset);
}
@@ -383,8 +387,7 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
}
/* Blank the screen. */
-void
-intelfbhw_do_blank(int blank, struct fb_info *info)
+void intelfbhw_do_blank(int blank, struct fb_info *info)
{
struct intelfb_info *dinfo = GET_DINFO(info);
u32 tmp;
@@ -409,11 +412,10 @@ intelfbhw_do_blank(int blank, struct fb_info *info)
DBG_MSG("cursor_on is %d\n", dinfo->cursor_on);
#endif
if (dinfo->cursor_on) {
- if (blank) {
+ if (blank)
intelfbhw_cursor_hide(dinfo);
- } else {
+ else
intelfbhw_cursor_show(dinfo);
- }
dinfo->cursor_on = 1;
}
dinfo->cursor_blanked = blank;
@@ -441,19 +443,18 @@ intelfbhw_do_blank(int blank, struct fb_info *info)
}
-void
-intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
- unsigned red, unsigned green, unsigned blue,
- unsigned transp)
+void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp)
{
+ u32 palette_reg = (dinfo->pipe == PIPE_A) ?
+ PALETTE_A : PALETTE_B;
+
#if VERBOSE > 0
DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n",
regno, red, green, blue);
#endif
- u32 palette_reg = (dinfo->pipe == PIPE_A) ?
- PALETTE_A : PALETTE_B;
-
OUTREG(palette_reg + (regno << 2),
(red << PALETTE_8_RED_SHIFT) |
(green << PALETTE_8_GREEN_SHIFT) |
@@ -461,9 +462,8 @@ intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
}
-int
-intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
- int flag)
+int intelfbhw_read_hw_state(struct intelfb_info *dinfo,
+ struct intelfb_hwstate *hw, int flag)
{
int i;
@@ -610,7 +610,8 @@ static int calc_vclock3(int index, int m, int n, int p)
return plls[index].ref_clk * m / n / p;
}
-static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds)
+static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2,
+ int lvds)
{
struct pll_min_max *pll = &plls[index];
u32 m, vco, p;
@@ -619,17 +620,16 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd
n += 2;
vco = pll->ref_clk * m / n;
- if (index == PLLS_I8xx) {
+ if (index == PLLS_I8xx)
p = ((p1 + 2) * (1 << (p2 + 1)));
- } else {
+ else
p = ((p1) * (p2 ? 5 : 10));
- }
return vco / p;
}
#if REGDUMP
-static void
-intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
+static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll,
+ int *o_p1, int *o_p2)
{
int p1, p2;
@@ -638,7 +638,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
p1 = 1;
else
p1 = (dpll >> DPLL_P1_SHIFT) & 0xff;
-
+
p1 = ffs(p1);
p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK;
@@ -656,8 +656,8 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
#endif
-void
-intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
+void intelfbhw_print_hw_state(struct intelfb_info *dinfo,
+ struct intelfb_hwstate *hw)
{
#if REGDUMP
int i, m1, m2, n, p1, p2;
@@ -670,7 +670,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
printk("hw state dump start\n");
printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor);
printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor);
- printk(" VGAPD: 0x%08x\n", hw->vga_pd);
+ printk(" VGAPD: 0x%08x\n", hw->vga_pd);
n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
@@ -689,7 +689,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
m1, m2, n, p1, p2);
- printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0));
+ printk(" VGA1: clock is %d\n",
+ calc_vclock(index, m1, m2, n, p1, p2, 0));
printk(" DPLL_A: 0x%08x\n", hw->dpll_a);
printk(" DPLL_B: 0x%08x\n", hw->dpll_b);
@@ -706,7 +707,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
m1, m2, n, p1, p2);
- printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0));
+ printk(" PLLA0: clock is %d\n",
+ calc_vclock(index, m1, m2, n, p1, p2, 0));
n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
@@ -716,7 +718,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
m1, m2, n, p1, p2);
- printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0));
+ printk(" PLLA1: clock is %d\n",
+ calc_vclock(index, m1, m2, n, p1, p2, 0));
#if 0
printk(" PALETTE_A:\n");
@@ -821,8 +824,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
/* Split the M parameter into M1 and M2. */
-static int
-splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2)
+static int splitm(int index, unsigned int m, unsigned int *retm1,
+ unsigned int *retm2)
{
int m1, m2;
int testm;
@@ -843,8 +846,8 @@ splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2)
}
/* Split the P parameter into P1 and P2. */
-static int
-splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
+static int splitp(int index, unsigned int p, unsigned int *retp1,
+ unsigned int *retp2)
{
int p1, p2;
struct pll_min_max *pll = &plls[index];
@@ -878,9 +881,8 @@ splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
}
}
-static int
-calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
- u32 *retp2, u32 *retclock)
+static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2,
+ u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock)
{
u32 m1, m2, n, p1, p2, n1, testm;
u32 f_vco, p, p_best = 0, m, f_out = 0;
@@ -975,8 +977,8 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
return 0;
}
-static __inline__ int
-check_overflow(u32 value, u32 limit, const char *description)
+static __inline__ int check_overflow(u32 value, u32 limit,
+ const char *description)
{
if (value > limit) {
WRN_MSG("%s value %d exceeds limit %d\n",
@@ -987,9 +989,9 @@ check_overflow(u32 value, u32 limit, const char *description)
}
/* It is assumed that hw is filled in with the initial state information. */
-int
-intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
- struct fb_var_screeninfo *var)
+int intelfbhw_mode_to_hw(struct intelfb_info *dinfo,
+ struct intelfb_hwstate *hw,
+ struct fb_var_screeninfo *var)
{
int pipe = PIPE_A;
u32 *dpll, *fp0, *fp1;
@@ -1093,9 +1095,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
if (IS_I9XX(dinfo)) {
*dpll |= (p2 << DPLL_I9XX_P2_SHIFT);
*dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT;
- } else {
+ } else
*dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT);
- }
*fp0 = (n << FP_N_DIVISOR_SHIFT) |
(m1 << FP_M1_DIVISOR_SHIFT) |
@@ -1139,6 +1140,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
hblank_end);
vactive = var->yres;
+ if (var->vmode & FB_VMODE_INTERLACED)
+ vactive--; /* the chip adds 2 halflines automatically */
vsync_start = vactive + var->lower_margin;
vsync_end = vsync_start + var->vsync_len;
vtotal = vsync_end + var->upper_margin;
@@ -1220,19 +1223,24 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
/* Set the palette to 8-bit mode. */
*pipe_conf &= ~PIPECONF_GAMMA;
+
+ if (var->vmode & FB_VMODE_INTERLACED)
+ *pipe_conf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
+ else
+ *pipe_conf &= ~PIPECONF_INTERLACE_MASK;
+
return 0;
}
/* Program a (non-VGA) video mode. */
-int
-intelfbhw_program_mode(struct intelfb_info *dinfo,
- const struct intelfb_hwstate *hw, int blank)
+int intelfbhw_program_mode(struct intelfb_info *dinfo,
+ const struct intelfb_hwstate *hw, int blank)
{
int pipe = PIPE_A;
u32 tmp;
const u32 *dpll, *fp0, *fp1, *pipe_conf;
const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss;
- u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg;
+ u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg, pipe_stat_reg;
u32 hsync_reg, htotal_reg, hblank_reg;
u32 vsync_reg, vtotal_reg, vblank_reg;
u32 src_size_reg;
@@ -1273,6 +1281,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
fp0_reg = FPB0;
fp1_reg = FPB1;
pipe_conf_reg = PIPEBCONF;
+ pipe_stat_reg = PIPEBSTAT;
hsync_reg = HSYNC_B;
htotal_reg = HTOTAL_B;
hblank_reg = HBLANK_B;
@@ -1296,6 +1305,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
fp0_reg = FPA0;
fp1_reg = FPA1;
pipe_conf_reg = PIPEACONF;
+ pipe_stat_reg = PIPEASTAT;
hsync_reg = HSYNC_A;
htotal_reg = HTOTAL_A;
hblank_reg = HBLANK_A;
@@ -1312,8 +1322,8 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
count = 0;
do {
- tmp_val[count%3] = INREG(0x70000);
- if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2]))
+ tmp_val[count % 3] = INREG(PIPEA_DSL);
+ if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1] == tmp_val[2]))
break;
count++;
udelay(1);
@@ -1322,7 +1332,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
tmp &= ~PIPECONF_ENABLE;
OUTREG(pipe_conf_reg, tmp);
}
- } while(count < 2000);
+ } while (count < 2000);
OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
@@ -1382,6 +1392,17 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
OUTREG(vtotal_reg, *vt);
OUTREG(src_size_reg, *ss);
+ switch (dinfo->info->var.vmode & (FB_VMODE_INTERLACED |
+ FB_VMODE_ODD_FLD_FIRST)) {
+ case FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST:
+ OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_ODD_EN);
+ break;
+ case FB_VMODE_INTERLACED: /* even lines first */
+ OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_EVEN_EN);
+ break;
+ default: /* non-interlaced */
+ OUTREG(pipe_stat_reg, 0xFFFF); /* clear all status bits only */
+ }
/* Enable pipe */
OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE);
@@ -1446,8 +1467,7 @@ static u32 get_ring_space(struct intelfb_info *dinfo)
return ring_space;
}
-static int
-wait_ring(struct intelfb_info *dinfo, int n)
+static int wait_ring(struct intelfb_info *dinfo, int n)
{
int i = 0;
unsigned long end;
@@ -1489,16 +1509,15 @@ wait_ring(struct intelfb_info *dinfo, int n)
return i;
}
-static void
-do_flush(struct intelfb_info *dinfo) {
+static void do_flush(struct intelfb_info *dinfo)
+{
START_RING(2);
OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
OUT_RING(MI_NOOP);
ADVANCE_RING();
}
-void
-intelfbhw_do_sync(struct intelfb_info *dinfo)
+void intelfbhw_do_sync(struct intelfb_info *dinfo)
{
#if VERBOSE > 0
DBG_MSG("intelfbhw_do_sync\n");
@@ -1517,8 +1536,7 @@ intelfbhw_do_sync(struct intelfb_info *dinfo)
dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE;
}
-static void
-refresh_ring(struct intelfb_info *dinfo)
+static void refresh_ring(struct intelfb_info *dinfo)
{
#if VERBOSE > 0
DBG_MSG("refresh_ring\n");
@@ -1529,8 +1547,7 @@ refresh_ring(struct intelfb_info *dinfo)
dinfo->ring_space = get_ring_space(dinfo);
}
-static void
-reset_state(struct intelfb_info *dinfo)
+static void reset_state(struct intelfb_info *dinfo)
{
int i;
u32 tmp;
@@ -1560,12 +1577,11 @@ reset_state(struct intelfb_info *dinfo)
}
/* Stop the 2D engine, and turn off the ring buffer. */
-void
-intelfbhw_2d_stop(struct intelfb_info *dinfo)
+void intelfbhw_2d_stop(struct intelfb_info *dinfo)
{
#if VERBOSE > 0
- DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", dinfo->accel,
- dinfo->ring_active);
+ DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n",
+ dinfo->accel, dinfo->ring_active);
#endif
if (!dinfo->accel)
@@ -1580,8 +1596,7 @@ intelfbhw_2d_stop(struct intelfb_info *dinfo)
* It is assumed that the graphics engine has been stopped by previously
* calling intelfb_2d_stop().
*/
-void
-intelfbhw_2d_start(struct intelfb_info *dinfo)
+void intelfbhw_2d_start(struct intelfb_info *dinfo)
{
#if VERBOSE > 0
DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n",
@@ -1605,9 +1620,8 @@ intelfbhw_2d_start(struct intelfb_info *dinfo)
}
/* 2D fillrect (solid fill or invert) */
-void
-intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, u32 h,
- u32 color, u32 pitch, u32 bpp, u32 rop)
+void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w,
+ u32 h, u32 color, u32 pitch, u32 bpp, u32 rop)
{
u32 br00, br09, br13, br14, br16;
@@ -1696,9 +1710,9 @@ intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,
ADVANCE_RING();
}
-int
-intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
- u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, u32 bpp)
+int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
+ u32 h, const u8* cdat, u32 x, u32 y, u32 pitch,
+ u32 bpp)
{
int nbytes, ndwords, pad, tmp;
u32 br00, br09, br13, br18, br19, br22, br23;
@@ -1785,8 +1799,7 @@ intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
}
/* HW cursor functions. */
-void
-intelfbhw_cursor_init(struct intelfb_info *dinfo)
+void intelfbhw_cursor_init(struct intelfb_info *dinfo)
{
u32 tmp;
@@ -1817,8 +1830,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo)
}
}
-void
-intelfbhw_cursor_hide(struct intelfb_info *dinfo)
+void intelfbhw_cursor_hide(struct intelfb_info *dinfo)
{
u32 tmp;
@@ -1843,8 +1855,7 @@ intelfbhw_cursor_hide(struct intelfb_info *dinfo)
}
}
-void
-intelfbhw_cursor_show(struct intelfb_info *dinfo)
+void intelfbhw_cursor_show(struct intelfb_info *dinfo)
{
u32 tmp;
@@ -1873,8 +1884,7 @@ intelfbhw_cursor_show(struct intelfb_info *dinfo)
}
}
-void
-intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
+void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
{
u32 tmp;
@@ -1892,13 +1902,11 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
OUTREG(CURSOR_A_POSITION, tmp);
- if (IS_I9XX(dinfo)) {
+ if (IS_I9XX(dinfo))
OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
- }
}
-void
-intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
+void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
{
#if VERBOSE > 0
DBG_MSG("intelfbhw_cursor_setcolor\n");
@@ -1910,9 +1918,8 @@ intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK);
}
-void
-intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
- u8 *data)
+void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
+ u8 *data)
{
u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
int i, j, w = width / 8;
@@ -1940,8 +1947,8 @@ intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
}
}
-void
-intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
+void intelfbhw_cursor_reset(struct intelfb_info *dinfo)
+{
u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
int i, j;
@@ -1961,72 +1968,72 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
}
}
-static irqreturn_t
-intelfbhw_irq(int irq, void *dev_id) {
- int handled = 0;
+static irqreturn_t intelfbhw_irq(int irq, void *dev_id)
+{
u16 tmp;
struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
spin_lock(&dinfo->int_lock);
tmp = INREG16(IIR);
- tmp &= VSYNC_PIPE_A_INTERRUPT;
+ if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
+ tmp &= PIPE_A_EVENT_INTERRUPT;
+ else
+ tmp &= VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
if (tmp == 0) {
spin_unlock(&dinfo->int_lock);
- return IRQ_RETVAL(handled);
+ return IRQ_RETVAL(0); /* not us */
}
- OUTREG16(IIR, tmp);
+ /* clear status bits 0-15 ASAP and don't touch bits 16-31 */
+ OUTREG(PIPEASTAT, INREG(PIPEASTAT));
- if (tmp & VSYNC_PIPE_A_INTERRUPT) {
- dinfo->vsync.count++;
- if (dinfo->vsync.pan_display) {
- dinfo->vsync.pan_display = 0;
- OUTREG(DSPABASE, dinfo->vsync.pan_offset);
- }
- wake_up_interruptible(&dinfo->vsync.wait);
- handled = 1;
+ OUTREG16(IIR, tmp);
+ if (dinfo->vsync.pan_display) {
+ dinfo->vsync.pan_display = 0;
+ OUTREG(DSPABASE, dinfo->vsync.pan_offset);
}
+ dinfo->vsync.count++;
+ wake_up_interruptible(&dinfo->vsync.wait);
+
spin_unlock(&dinfo->int_lock);
- return IRQ_RETVAL(handled);
+ return IRQ_RETVAL(1);
}
-int
-intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) {
-
+int intelfbhw_enable_irq(struct intelfb_info *dinfo)
+{
+ u16 tmp;
if (!test_and_set_bit(0, &dinfo->irq_flags)) {
if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED,
- "intelfb", dinfo)) {
+ "intelfb", dinfo)) {
clear_bit(0, &dinfo->irq_flags);
return -EINVAL;
}
spin_lock_irq(&dinfo->int_lock);
- OUTREG16(HWSTAM, 0xfffe);
- OUTREG16(IMR, 0x0);
- OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT);
- spin_unlock_irq(&dinfo->int_lock);
- } else if (reenable) {
- u16 ier;
-
+ OUTREG16(HWSTAM, 0xfffe); /* i830 DRM uses ffff */
+ OUTREG16(IMR, 0);
+ } else
spin_lock_irq(&dinfo->int_lock);
- ier = INREG16(IER);
- if ((ier & VSYNC_PIPE_A_INTERRUPT)) {
- DBG_MSG("someone disabled the IRQ [%08X]\n", ier);
- OUTREG(IER, VSYNC_PIPE_A_INTERRUPT);
- }
- spin_unlock_irq(&dinfo->int_lock);
+
+ if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
+ tmp = PIPE_A_EVENT_INTERRUPT;
+ else
+ tmp = VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
+ if (tmp != INREG16(IER)) {
+ DBG_MSG("changing IER to 0x%X\n", tmp);
+ OUTREG16(IER, tmp);
}
+
+ spin_unlock_irq(&dinfo->int_lock);
return 0;
}
-void
-intelfbhw_disable_irq(struct intelfb_info *dinfo) {
- u16 tmp;
-
+void intelfbhw_disable_irq(struct intelfb_info *dinfo)
+{
if (test_and_clear_bit(0, &dinfo->irq_flags)) {
if (dinfo->vsync.pan_display) {
dinfo->vsync.pan_display = 0;
@@ -2037,16 +2044,15 @@ intelfbhw_disable_irq(struct intelfb_info *dinfo) {
OUTREG16(IMR, 0xffff);
OUTREG16(IER, 0x0);
- tmp = INREG16(IIR);
- OUTREG16(IIR, tmp);
+ OUTREG16(IIR, INREG16(IIR)); /* clear IRQ requests */
spin_unlock_irq(&dinfo->int_lock);
free_irq(dinfo->pdev->irq, dinfo);
}
}
-int
-intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) {
+int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe)
+{
struct intelfb_vsync *vsync;
unsigned int count;
int ret;
@@ -2059,18 +2065,16 @@ intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) {
return -ENODEV;
}
- ret = intelfbhw_enable_irq(dinfo, 0);
- if (ret) {
+ ret = intelfbhw_enable_irq(dinfo);
+ if (ret)
return ret;
- }
count = vsync->count;
- ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10);
- if (ret < 0) {
+ ret = wait_event_interruptible_timeout(vsync->wait,
+ count != vsync->count, HZ / 10);
+ if (ret < 0)
return ret;
- }
if (ret == 0) {
- intelfbhw_enable_irq(dinfo, 1);
DBG_MSG("wait_for_vsync timed out!\n");
return -ETIMEDOUT;
}
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h
index 8c54ba8fbdd..0b076bac321 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/intelfb/intelfbhw.h
@@ -83,7 +83,7 @@
*/
#define RING_MIN_FREE 64
-#define IPEHR 0x2088
+#define IPEHR 0x2088
#define INSTDONE 0x2090
#define PRI_RING_EMPTY 1
@@ -93,7 +93,7 @@
#define IIR 0x20A4
#define IMR 0x20A8
#define VSYNC_PIPE_A_INTERRUPT (1 << 7)
-#define PIPE_A_EVENT_INTERRUPT (1 << 4)
+#define PIPE_A_EVENT_INTERRUPT (1 << 6)
#define VSYNC_PIPE_B_INTERRUPT (1 << 5)
#define PIPE_B_EVENT_INTERRUPT (1 << 4)
#define HOST_PORT_EVENT_INTERRUPT (1 << 3)
@@ -128,9 +128,9 @@
#define GPIOA 0x5010
#define GPIOB 0x5014
-#define GPIOC 0x5018 // this may be external DDC on i830
-#define GPIOD 0x501C // this is DVO DDC
-#define GPIOE 0x5020 // this is DVO i2C
+#define GPIOC 0x5018 /* this may be external DDC on i830 */
+#define GPIOD 0x501C /* this is DVO DDC */
+#define GPIOE 0x5020 /* this is DVO i2C */
#define GPIOF 0x5024
/* PLL registers */
@@ -269,15 +269,20 @@
#define PORT_ENABLE (1 << 31)
#define PORT_PIPE_SELECT_SHIFT 30
#define PORT_TV_FLAGS_MASK 0xFF
-#define PORT_TV_FLAGS 0xC4 // ripped from my BIOS
- // to understand and correct
+#define PORT_TV_FLAGS 0xC4 /* ripped from my BIOS
+ to understand and correct */
#define DVOA_SRCDIM 0x61124
#define DVOB_SRCDIM 0x61144
#define DVOC_SRCDIM 0x61164
+#define PIPEA_DSL 0x70000
+#define PIPEB_DSL 0x71000
#define PIPEACONF 0x70008
#define PIPEBCONF 0x71008
+#define PIPEASTAT 0x70024 /* bits 0-15 are "write 1 to clear" */
+#define PIPEBSTAT 0x71024
+
#define PIPECONF_ENABLE (1 << 31)
#define PIPECONF_DISABLE 0
#define PIPECONF_DOUBLE_WIDE (1 << 30)
@@ -286,6 +291,35 @@
#define PIPECONF_UNLOCKED 0
#define PIPECONF_GAMMA (1 << 24)
#define PIPECONF_PALETTE 0
+#define PIPECONF_PROGRESSIVE (0 << 21)
+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
+#define PIPECONF_INTERLACE_MASK (7 << 21)
+
+/* enable bits, write 1 to enable */
+#define PIPESTAT_FIFO_UNDERRUN (1 << 31)
+#define PIPESTAT_CRC_ERROR_EN (1 << 29)
+#define PIPESTAT_CRC_DONE_EN (1 << 28)
+#define PIPESTAT_HOTPLUG_EN (1 << 26)
+#define PIPESTAT_VERTICAL_SYNC_EN (1 << 25)
+#define PIPESTAT_DISPLINE_COMP_EN (1 << 24)
+#define PIPESTAT_FLD_EVT_ODD_EN (1 << 21)
+#define PIPESTAT_FLD_EVT_EVEN_EN (1 << 20)
+#define PIPESTAT_TV_HOTPLUG_EN (1 << 18)
+#define PIPESTAT_VBLANK_EN (1 << 17)
+#define PIPESTAT_OVL_UPDATE_EN (1 << 16)
+/* status bits, write 1 to clear */
+#define PIPESTAT_HOTPLUG_STATE (1 << 15)
+#define PIPESTAT_CRC_ERROR (1 << 13)
+#define PIPESTAT_CRC_DONE (1 << 12)
+#define PIPESTAT_HOTPLUG (1 << 10)
+#define PIPESTAT_VSYNC (1 << 9)
+#define PIPESTAT_DISPLINE_COMP (1 << 8)
+#define PIPESTAT_FLD_EVT_ODD (1 << 5)
+#define PIPESTAT_FLD_EVT_EVEN (1 << 4)
+#define PIPESTAT_TV_HOTPLUG (1 << 2)
+#define PIPESTAT_VBLANK (1 << 1)
+#define PIPESTAT_OVL_UPDATE (1 << 0)
#define DISPARB 0x70030
#define DISPARB_AEND_MASK 0x1ff
@@ -365,7 +399,7 @@
#define DISPPLANE_8BPP (0x2<<26)
#define DISPPLANE_15_16BPP (0x4<<26)
#define DISPPLANE_16BPP (0x5<<26)
-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
#define DISPPLANE_32BPP (0x7<<26)
#define DISPPLANE_STEREO_ENABLE (1<<25)
#define DISPPLANE_STEREO_DISABLE 0
@@ -567,7 +601,7 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
int height, u8 *data);
extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
-extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable);
+extern int intelfbhw_enable_irq(struct intelfb_info *dinfo);
extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);
extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe);
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index 1c557990739..acb9370fdb1 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -21,7 +21,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 2b0f799aa8d..fc72684aae5 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -34,6 +34,10 @@ extern const struct linux_logo logo_superh_vga16;
extern const struct linux_logo logo_superh_clut224;
extern const struct linux_logo logo_m32r_clut224;
+static int nologo;
+module_param(nologo, bool, 0);
+MODULE_PARM_DESC(nologo, "Disables startup logo");
+
/* logo's are marked __initdata. Use __init_refok to tell
* modpost that it is intended that this function uses data
* marked __initdata.
@@ -42,6 +46,9 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
{
const struct linux_logo *logo = NULL;
+ if (nologo)
+ return NULL;
+
if (depth >= 1) {
#ifdef CONFIG_LOGO_LINUX_MONO
/* Generic Linux logo */
@@ -71,10 +78,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
#endif
#ifdef CONFIG_LOGO_DEC_CLUT224
/* DEC Linux logo on MIPS/MIPS64 or ALPHA */
-#ifndef CONFIG_ALPHA
- if (mips_machgroup == MACH_GROUP_DEC)
-#endif
- logo = &logo_dec_clut224;
+ logo = &logo_dec_clut224;
#endif
#ifdef CONFIG_LOGO_MAC_CLUT224
/* Macintosh Linux logo on m68k */
@@ -87,10 +91,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
#endif
#ifdef CONFIG_LOGO_SGI_CLUT224
/* SGI Linux logo on MIPS/MIPS64 and VISWS */
-#ifndef CONFIG_X86_VISWS
- if (mips_machgroup == MACH_GROUP_SGI)
-#endif
- logo = &logo_sgi_clut224;
+ logo = &logo_sgi_clut224;
#endif
#ifdef CONFIG_LOGO_SUN_CLUT224
/* Sun Linux logo */
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 86ca7b17900..b25972ac6ee 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -113,7 +113,7 @@
#include "matroxfb_g450.h"
#include <linux/matroxfb.h>
#include <linux/interrupt.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 4b3344e0369..a6ab5b6a58d 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -15,7 +15,7 @@
#include "matroxfb_misc.h"
#include "matroxfb_DAC1064.h"
#include <linux/matroxfb.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
/* **************************************************** */
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c
index 4d610b405d4..6209a761f67 100644
--- a/drivers/video/matrox/matroxfb_g450.c
+++ b/drivers/video/matrox/matroxfb_g450.c
@@ -17,7 +17,6 @@
#include "matroxfb_DAC1064.h"
#include "g450_pll.h"
#include <linux/matroxfb.h>
-#include <asm/uaccess.h>
#include <asm/div64.h>
#include "matroxfb_g450.h"
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index de0d755f901..49cd53e46c0 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -18,7 +18,6 @@
#include <linux/i2c.h>
#include <linux/matroxfb.h>
#include <asm/div64.h>
-#include <asm/uaccess.h>
#define MAVEN_I2CID (0x1B)
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 980d5f62390..80cd117ca65 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/video/mbx/mbxfb.c
*
- * Copyright (C) 2006 8D Technologies inc
+ * Copyright (C) 2006-2007 8D Technologies inc
* Raphael Assenat <raph@8d.com>
* - Added video overlay support
* - Various improvements
@@ -334,8 +334,8 @@ static int mbxfb_blank(int blank, struct fb_info *info)
static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
{
- u32 vsctrl, vbbase, vscadr, vsadr;
- u32 sssize, spoctrl, svctrl, shctrl;
+ u32 vsctrl, vscadr, vsadr;
+ u32 sssize, spoctrl, shctrl;
u32 vubase, vvbase;
u32 vovrclk;
@@ -349,13 +349,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
vscadr = readl(VSCADR);
vubase = readl(VUBASE);
vvbase = readl(VVBASE);
+ shctrl = readl(SHCTRL);
spoctrl = readl(SPOCTRL);
sssize = readl(SSSIZE);
-
- vbbase = Vbbase_Glalpha(set->alpha);
-
vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) |
FMsk(VSCTRL_VSHEIGHT) |
FMsk(VSCTRL_VPIXFMT) |
@@ -364,38 +362,41 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) |
VSCTRL_CSC_EN;
- vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC |
- FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) |
- FMsk(VSCADR_VBASE_ADR) );
+ vscadr &= ~(VSCADR_STR_EN | FMsk(VSCADR_VBASE_ADR) );
vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR));
vvbase &= ~(FMsk(VVBASE_VBASE_ADR));
- switch (set->fmt)
- {
- case MBXFB_FMT_YUV12:
- vsctrl |= VSCTRL_VPIXFMT_YUV12;
+ switch (set->fmt) {
+ case MBXFB_FMT_YUV16:
+ vsctrl |= VSCTRL_VPIXFMT_YUV12;
- set->Y_stride = ((set->width) + 0xf ) & ~0xf;
+ set->Y_stride = ((set->width) + 0xf ) & ~0xf;
+ break;
+ case MBXFB_FMT_YUV12:
+ vsctrl |= VSCTRL_VPIXFMT_YUV12;
+ set->Y_stride = ((set->width) + 0xf ) & ~0xf;
+ vubase |= VUBASE_UVHALFSTR;
+
+ break;
+ case MBXFB_FMT_UY0VY1:
+ vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
+ set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+ break;
+ case MBXFB_FMT_VY0UY1:
+ vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
+ set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+ break;
+ case MBXFB_FMT_Y0UY1V:
+ vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
+ set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
+ break;
+ case MBXFB_FMT_Y0VY1U:
+ vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
+ set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
break;
- case MBXFB_FMT_UY0VY1:
- vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
- set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
- break;
- case MBXFB_FMT_VY0UY1:
- vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
- set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
- break;
- case MBXFB_FMT_Y0UY1V:
- vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
- set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
- break;
- case MBXFB_FMT_Y0VY1U:
- vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
- set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
- break;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
/* VSCTRL has the bits which sets the Video Pixel Format.
@@ -417,8 +418,7 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
(0x60000 + set->mem_offset + set->V_offset)>>3);
- vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB |
- Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
+ vscadr |= Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
if (set->enable)
vscadr |= VSCADR_STR_EN;
@@ -433,9 +433,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP |
SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C |
- FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH));
- spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height)
- | SPOCTRL_VORDER_2TAP;
+ FMsk(SPOCTRL_VPITCH));
+ spoctrl |= Spoctrl_Vpitch((set->height<<11)/set->scaled_height);
/* Bypass horiz/vert scaler when same size */
if (set->scaled_width == set->width)
@@ -443,14 +442,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
if (set->scaled_height == set->height)
spoctrl |= SPOCTRL_V_SC_BP;
- svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);
-
- shctrl = Shctrl_Hinitial(4<<11)
- | Shctrl_Hpitch((set->width<<11)/set->scaled_width);
+ shctrl &= ~(FMsk(SHCTRL_HPITCH) | SHCTRL_HDECIM);
+ shctrl |= Shctrl_Hpitch((set->width<<11)/set->scaled_width);
/* Video plane registers */
write_reg(vsctrl, VSCTRL);
- write_reg(vbbase, VBBASE);
write_reg(vscadr, VSCADR);
write_reg(vubase, VUBASE);
write_reg(vvbase, VVBASE);
@@ -459,28 +455,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
/* Video scaler registers */
write_reg(sssize, SSSIZE);
write_reg(spoctrl, SPOCTRL);
- write_reg(svctrl, SVCTRL);
write_reg(shctrl, SHCTRL);
- /* RAPH: Using those coefficients, the scaled
- * image is quite blurry. I dont know how
- * to improve them ; The chip documentation
- * was not helpful.. */
- write_reg(0x21212121, VSCOEFF0);
- write_reg(0x21212121, VSCOEFF1);
- write_reg(0x21212121, VSCOEFF2);
- write_reg(0x21212121, VSCOEFF3);
- write_reg(0x21212121, VSCOEFF4);
- write_reg(0x00000000, HSCOEFF0);
- write_reg(0x00000000, HSCOEFF1);
- write_reg(0x00000000, HSCOEFF2);
- write_reg(0x03020201, HSCOEFF3);
- write_reg(0x09070604, HSCOEFF4);
- write_reg(0x0f0e0c0a, HSCOEFF5);
- write_reg(0x15141211, HSCOEFF6);
- write_reg(0x19181716, HSCOEFF7);
- write_reg(0x00000019, HSCOEFF8);
-
/* Clock */
if (set->enable)
vovrclk |= 1;
@@ -492,27 +468,206 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
return 0;
}
+static int mbxfb_ioctl_planeorder(struct mbxfb_planeorder *porder)
+{
+ unsigned long gscadr, vscadr;
+
+ if (porder->bottom == porder->top)
+ return -EINVAL;
+
+ gscadr = readl(GSCADR);
+ vscadr = readl(VSCADR);
+
+ gscadr &= ~(FMsk(GSCADR_BLEND_POS));
+ vscadr &= ~(FMsk(VSCADR_BLEND_POS));
+
+ switch (porder->bottom) {
+ case MBXFB_PLANE_GRAPHICS:
+ gscadr |= GSCADR_BLEND_GFX;
+ break;
+ case MBXFB_PLANE_VIDEO:
+ vscadr |= VSCADR_BLEND_GFX;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (porder->top) {
+ case MBXFB_PLANE_GRAPHICS:
+ gscadr |= GSCADR_BLEND_VID;
+ break;
+ case MBXFB_PLANE_VIDEO:
+ vscadr |= GSCADR_BLEND_VID;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ write_reg_dly(vscadr, VSCADR);
+ write_reg_dly(gscadr, GSCADR);
+
+ return 0;
+
+}
+
+static int mbxfb_ioctl_alphactl(struct mbxfb_alphaCtl *alpha)
+{
+ unsigned long vscadr, vbbase, vcmsk;
+ unsigned long gscadr, gbbase, gdrctrl;
+
+ vbbase = Vbbase_Glalpha(alpha->overlay_global_alpha) |
+ Vbbase_Colkey(alpha->overlay_colorkey);
+
+ gbbase = Gbbase_Glalpha(alpha->graphics_global_alpha) |
+ Gbbase_Colkey(alpha->graphics_colorkey);
+
+ vcmsk = readl(VCMSK);
+ vcmsk &= ~(FMsk(VCMSK_COLKEY_M));
+ vcmsk |= Vcmsk_colkey_m(alpha->overlay_colorkey_mask);
+
+ gdrctrl = readl(GDRCTRL);
+ gdrctrl &= ~(FMsk(GDRCTRL_COLKEYM));
+ gdrctrl |= Gdrctrl_Colkeym(alpha->graphics_colorkey_mask);
+
+ vscadr = readl(VSCADR);
+ vscadr &= ~(FMsk(VSCADR_BLEND_M) | VSCADR_COLKEYSRC | VSCADR_COLKEY_EN);
+
+ gscadr = readl(GSCADR);
+ gscadr &= ~(FMsk(GSCADR_BLEND_M) | GSCADR_COLKEY_EN | GSCADR_COLKEYSRC);
+
+ switch (alpha->overlay_colorkey_mode) {
+ case MBXFB_COLORKEY_DISABLED:
+ break;
+ case MBXFB_COLORKEY_PREVIOUS:
+ vscadr |= VSCADR_COLKEY_EN;
+ break;
+ case MBXFB_COLORKEY_CURRENT:
+ vscadr |= VSCADR_COLKEY_EN | VSCADR_COLKEYSRC;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (alpha->overlay_blend_mode) {
+ case MBXFB_ALPHABLEND_NONE:
+ vscadr |= VSCADR_BLEND_NONE;
+ break;
+ case MBXFB_ALPHABLEND_GLOBAL:
+ vscadr |= VSCADR_BLEND_GLOB;
+ break;
+ case MBXFB_ALPHABLEND_PIXEL:
+ vscadr |= VSCADR_BLEND_PIX;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (alpha->graphics_colorkey_mode) {
+ case MBXFB_COLORKEY_DISABLED:
+ break;
+ case MBXFB_COLORKEY_PREVIOUS:
+ gscadr |= GSCADR_COLKEY_EN;
+ break;
+ case MBXFB_COLORKEY_CURRENT:
+ gscadr |= GSCADR_COLKEY_EN | GSCADR_COLKEYSRC;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (alpha->graphics_blend_mode) {
+ case MBXFB_ALPHABLEND_NONE:
+ gscadr |= GSCADR_BLEND_NONE;
+ break;
+ case MBXFB_ALPHABLEND_GLOBAL:
+ gscadr |= GSCADR_BLEND_GLOB;
+ break;
+ case MBXFB_ALPHABLEND_PIXEL:
+ gscadr |= GSCADR_BLEND_PIX;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ write_reg_dly(vbbase, VBBASE);
+ write_reg_dly(gbbase, GBBASE);
+ write_reg_dly(vcmsk, VCMSK);
+ write_reg_dly(gdrctrl, GDRCTRL);
+ write_reg_dly(gscadr, GSCADR);
+ write_reg_dly(vscadr, VSCADR);
+
+ return 0;
+}
+
static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
- struct mbxfb_overlaySetup setup;
+ struct mbxfb_overlaySetup setup;
+ struct mbxfb_planeorder porder;
+ struct mbxfb_alphaCtl alpha;
+ struct mbxfb_reg reg;
int res;
+ __u32 tmp;
- if (cmd == MBXFB_IOCX_OVERLAY)
+ switch (cmd)
{
- if (copy_from_user(&setup, (void __user*)arg,
- sizeof(struct mbxfb_overlaySetup)))
+ case MBXFB_IOCX_OVERLAY:
+ if (copy_from_user(&setup, (void __user*)arg,
+ sizeof(struct mbxfb_overlaySetup)))
+ return -EFAULT;
+
+ res = mbxfb_setupOverlay(&setup);
+ if (res)
+ return res;
+
+ if (copy_to_user((void __user*)arg, &setup,
+ sizeof(struct mbxfb_overlaySetup)))
+ return -EFAULT;
+
+ return 0;
+
+ case MBXFB_IOCS_PLANEORDER:
+ if (copy_from_user(&porder, (void __user*)arg,
+ sizeof(struct mbxfb_planeorder)))
return -EFAULT;
- res = mbxfb_setupOverlay(&setup);
- if (res)
- return res;
+ return mbxfb_ioctl_planeorder(&porder);
- if (copy_to_user((void __user*)arg, &setup,
- sizeof(struct mbxfb_overlaySetup)))
+ case MBXFB_IOCS_ALPHA:
+ if (copy_from_user(&alpha, (void __user*)arg,
+ sizeof(struct mbxfb_alphaCtl)))
return -EFAULT;
- return 0;
+ return mbxfb_ioctl_alphactl(&alpha);
+
+ case MBXFB_IOCS_REG:
+ if (copy_from_user(&reg, (void __user*)arg,
+ sizeof(struct mbxfb_reg)))
+ return -EFAULT;
+
+ if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */
+ return -EINVAL;
+
+ tmp = readl(virt_base_2700 + reg.addr);
+ tmp &= ~reg.mask;
+ tmp |= reg.val & reg.mask;
+ writel(tmp, virt_base_2700 + reg.addr);
+
+ return 0;
+ case MBXFB_IOCX_REG:
+ if (copy_from_user(&reg, (void __user*)arg,
+ sizeof(struct mbxfb_reg)))
+ return -EFAULT;
+
+ if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */
+ return -EINVAL;
+ reg.val = readl(virt_base_2700 + reg.addr);
+
+ if (copy_to_user((void __user*)arg, &reg,
+ sizeof(struct mbxfb_reg)))
+ return -EFAULT;
+
+ return 0;
}
return -EINVAL;
}
@@ -558,7 +713,6 @@ static void __devinit setup_memc(struct fb_info *fbi)
LMTYPE);
/* enable memory controller */
write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
-
/* perform dummy reads */
for ( i = 0; i < 16; i++ ) {
tmp = readl(fbi->screen_base);
@@ -588,8 +742,8 @@ static void enable_clocks(struct fb_info *fbi)
write_reg_dly(0x00000000, VOVRCLK);
write_reg_dly(PIXCLK_EN, PIXCLK);
write_reg_dly(MEMCLK_EN, MEMCLK);
- write_reg_dly(0x00000006, M24CLK);
- write_reg_dly(0x00000006, MBXCLK);
+ write_reg_dly(0x00000001, M24CLK);
+ write_reg_dly(0x00000001, MBXCLK);
write_reg_dly(SDCLK_EN, SDCLK);
write_reg_dly(0x00000001, PIXCLKDIV);
}
@@ -597,6 +751,7 @@ static void enable_clocks(struct fb_info *fbi)
static void __devinit setup_graphics(struct fb_info *fbi)
{
unsigned long gsctrl;
+ unsigned long vscadr;
gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
Gsctrl_Height(fbi->var.yres);
@@ -620,6 +775,11 @@ static void __devinit setup_graphics(struct fb_info *fbi)
write_reg_dly(0x00ffffff, GDRCTRL);
write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
write_reg_dly(0x00000000, GPLUT);
+
+ vscadr = readl(VSCADR);
+ vscadr &= ~(FMsk(VSCADR_BLEND_POS) | FMsk(VSCADR_BLEND_M));
+ vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_NONE;
+ write_reg_dly(vscadr, VSCADR);
}
static void __devinit setup_display(struct fb_info *fbi)
@@ -638,13 +798,47 @@ static void __devinit setup_display(struct fb_info *fbi)
static void __devinit enable_controller(struct fb_info *fbi)
{
+ u32 svctrl, shctrl;
+
write_reg_dly(SYSRST_RST, SYSRST);
+ /* setup a timeout, raise drive strength */
+ write_reg_dly(0xffffff0c, SYSCFG);
enable_clocks(fbi);
setup_memc(fbi);
setup_graphics(fbi);
setup_display(fbi);
+
+ shctrl = readl(SHCTRL);
+ shctrl &= ~(FMsk(SHCTRL_HINITIAL));
+ shctrl |= Shctrl_Hinitial(4<<11);
+ writel(shctrl, SHCTRL);
+
+ svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);
+ writel(svctrl, SVCTRL);
+
+ writel(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | SPOCTRL_VORDER_4TAP
+ , SPOCTRL);
+
+ /* Those coefficients are good for scaling up. For scaling
+ * down, the application has to calculate them. */
+ write_reg(0xff000100, VSCOEFF0);
+ write_reg(0xfdfcfdfe, VSCOEFF1);
+ write_reg(0x170d0500, VSCOEFF2);
+ write_reg(0x3d372d22, VSCOEFF3);
+ write_reg(0x00000040, VSCOEFF4);
+
+ write_reg(0xff010100, HSCOEFF0);
+ write_reg(0x00000000, HSCOEFF1);
+ write_reg(0x02010000, HSCOEFF2);
+ write_reg(0x01020302, HSCOEFF3);
+ write_reg(0xf9fbfe00, HSCOEFF4);
+ write_reg(0xfbf7f6f7, HSCOEFF5);
+ write_reg(0x1c110700, HSCOEFF6);
+ write_reg(0x3e393127, HSCOEFF7);
+ write_reg(0x00000040, HSCOEFF8);
+
}
#ifdef CONFIG_PM
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
index 9a24fb0c7d4..5f14b4befd7 100644
--- a/drivers/video/mbx/reg_bits.h
+++ b/drivers/video/mbx/reg_bits.h
@@ -215,7 +215,7 @@
/* GSCADR graphics stream control address register fields */
#define GSCADR_STR_EN (1 << 31)
#define GSCADR_COLKEY_EN (1 << 30)
-#define GSCADR_COLKEYSCR (1 << 29)
+#define GSCADR_COLKEYSRC (1 << 29)
#define GSCADR_BLEND_M Fld(2,27)
#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M))
#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M))
@@ -303,6 +303,67 @@
#define VSADR_YSTART Fld(11,0)
#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
+/* VSCTRL - Video Surface Control Register */
+#define VSCTRL_VPIXFMT Fld(4,27)
+#define VSCTRL_VPIXFMT_YUV12 ((0x9) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_UY0VY1 ((0xc) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_VY0UY1 ((0xd) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_Y0UY1V ((0xe) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_VPIXFMT_Y0VY1U ((0xf) << FShft(VSCTRL_VPIXFMT))
+#define VSCTRL_GAMMA_EN (1 << 26)
+#define VSCTRL_CSC_EN (1 << 25)
+#define VSCTRL_COSITED (1 << 22)
+#define VSCTRL_VSWIDTH Fld(11,11)
+#define Vsctrl_Width(Pixels) /* Video Width [1-2048] */ \
+ (((Pixels) - 1) << FShft(VSCTRL_VSWIDTH))
+#define VSCTRL_VSHEIGHT Fld(11,0)
+#define Vsctrl_Height(Pixels) /* Video Height [1-2048] */ \
+ (((Pixels) - 1) << FShft(VSCTRL_VSHEIGHT))
+
+/* VBBASE - Video Blending Base Register */
+#define VBBASE_GLALPHA Fld(8,24)
+#define Vbbase_Glalpha(x) ((x) << FShft(VBBASE_GLALPHA))
+
+#define VBBASE_COLKEY Fld(24,0)
+#define Vbbase_Colkey(x) ((x) << FShft(VBBASE_COLKEY))
+
+/* VCMSK - Video Color Key Mask Register */
+#define VCMSK_COLKEY_M Fld(24,0)
+#define Vcmsk_colkey_m(x) ((x) << FShft(VCMSK_COLKEY_M))
+
+/* VSCADR - Video Stream Control Rddress Register */
+#define VSCADR_STR_EN (1 << 31)
+#define VSCADR_COLKEY_EN (1 << 30)
+#define VSCADR_COLKEYSRC (1 << 29)
+#define VSCADR_BLEND_M Fld(2,27)
+#define VSCADR_BLEND_NONE ((0x0) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_INV ((0x1) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_GLOB ((0x2) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_PIX ((0x3) << FShft(VSCADR_BLEND_M))
+#define VSCADR_BLEND_POS Fld(2,24)
+#define VSCADR_BLEND_GFX ((0x0) << FShft(VSCADR_BLEND_POS))
+#define VSCADR_BLEND_VID ((0x1) << FShft(VSCADR_BLEND_POS))
+#define VSCADR_BLEND_CUR ((0x2) << FShft(VSCADR_BLEND_POS))
+#define VSCADR_VBASE_ADR Fld(23,0)
+#define Vscadr_Vbase_Adr(x) ((x) << FShft(VSCADR_VBASE_ADR))
+
+/* VUBASE - Video U Base Register */
+#define VUBASE_UVHALFSTR (1 << 31)
+#define VUBASE_UBASE_ADR Fld(24,0)
+#define Vubase_Ubase_Adr(x) ((x) << FShft(VUBASE_UBASE_ADR))
+
+/* VVBASE - Video V Base Register */
+#define VVBASE_VBASE_ADR Fld(24,0)
+#define Vvbase_Vbase_Adr(x) ((x) << FShft(VVBASE_VBASE_ADR))
+
+/* VSADR - Video Stride Address Register */
+#define VSADR_SRCSTRIDE Fld(10,22)
+#define Vsadr_Srcstride(x) ((x) << FShft(VSADR_SRCSTRIDE))
+#define VSADR_XSTART Fld(11,11)
+#define Vsadr_Xstart(x) ((x) << FShft(VSADR_XSTART))
+#define VSADR_YSTART Fld(11,0)
+#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
+
/* HCCTRL - Hardware Cursor Register fields */
#define HCCTRL_CUR_EN (1 << 31)
#define HCCTRL_COLKEY_EN (1 << 29)
@@ -479,6 +540,30 @@
#define DINTRE_HBLNK1_EN (1 << 1)
#define DINTRE_HBLNK0_EN (1 << 0)
+/* DINTRS - Display Interrupt Status Register */
+#define DINTRS_CUR_OR_S (1 << 18)
+#define DINTRS_STR2_OR_S (1 << 17)
+#define DINTRS_STR1_OR_S (1 << 16)
+#define DINTRS_CUR_UR_S (1 << 6)
+#define DINTRS_STR2_UR_S (1 << 5)
+#define DINTRS_STR1_UR_S (1 << 4)
+#define DINTRS_VEVENT1_S (1 << 3)
+#define DINTRS_VEVENT0_S (1 << 2)
+#define DINTRS_HBLNK1_S (1 << 1)
+#define DINTRS_HBLNK0_S (1 << 0)
+
+/* DINTRE - Display Interrupt Enable Register */
+#define DINTRE_CUR_OR_EN (1 << 18)
+#define DINTRE_STR2_OR_EN (1 << 17)
+#define DINTRE_STR1_OR_EN (1 << 16)
+#define DINTRE_CUR_UR_EN (1 << 6)
+#define DINTRE_STR2_UR_EN (1 << 5)
+#define DINTRE_STR1_UR_EN (1 << 4)
+#define DINTRE_VEVENT1_EN (1 << 3)
+#define DINTRE_VEVENT0_EN (1 << 2)
+#define DINTRE_HBLNK1_EN (1 << 1)
+#define DINTRE_HBLNK0_EN (1 << 0)
+
/* DLSTS - display load status register */
#define DLSTS_RLD_ADONE (1 << 23)
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
index a7c63d865aa..063099d4883 100644
--- a/drivers/video/mbx/regs.h
+++ b/drivers/video/mbx/regs.h
@@ -30,7 +30,7 @@
#define VOVRCLK __REG_2700G(0x00000044)
#define PIXCLK __REG_2700G(0x00000048)
#define MEMCLK __REG_2700G(0x0000004c)
-#define M24CLK __REG_2700G(0x00000054)
+#define M24CLK __REG_2700G(0x00000050)
#define MBXCLK __REG_2700G(0x00000054)
#define SDCLK __REG_2700G(0x00000058)
#define PIXCLKDIV __REG_2700G(0x0000005c)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3741ad72940..8d81ef019c6 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -27,7 +27,7 @@
#define DPRINTK(fmt, args...)
#endif
-const char *global_mode_option;
+const char *fb_mode_option;
/*
* Standard video mode definitions (taken from XFree86)
@@ -72,7 +72,7 @@ static const struct fb_videomode modedb[] = {
0, FB_VMODE_NONINTERLACED
}, {
/* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
- NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
+ NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
0, FB_VMODE_INTERLACED
}, {
/* 800x600 @ 72 Hz, 48.0 kHz hsync */
@@ -120,11 +120,11 @@ static const struct fb_videomode modedb[] = {
0, FB_VMODE_NONINTERLACED
}, {
/* 1400x1050 @ 60Hz, 63.9 kHz hsync */
- NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
+ NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
0, FB_VMODE_NONINTERLACED
}, {
/* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
- NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
+ NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
@@ -253,7 +253,7 @@ static const struct fb_videomode modedb[] = {
FB_VMODE_NONINTERLACED
}, {
/* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
- NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
+ NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}, {
/* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
@@ -306,7 +306,7 @@ const struct fb_videomode vesa_modes[] = {
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
/* 12 1024x768i-43 VESA */
- { NULL, 53, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
+ { NULL, 43, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_INTERLACED, FB_MODE_IS_VESA },
/* 13 1024x768-60 VESA */
@@ -383,7 +383,7 @@ const struct fb_videomode vesa_modes[] = {
{ NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3,
FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
/* 33 1920x1440-75 VESA */
- { NULL, 60, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
+ { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
};
EXPORT_SYMBOL(vesa_modes);
@@ -510,7 +510,9 @@ int fb_find_mode(struct fb_var_screeninfo *var,
default_bpp = 8;
/* Did the user specify a video mode? */
- if (mode_option || (mode_option = global_mode_option)) {
+ if (!mode_option)
+ mode_option = fb_mode_option;
+ if (mode_option) {
const char *name = mode_option;
unsigned int namelen = strlen(name);
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
@@ -606,26 +608,43 @@ done:
DPRINTK("Trying specified video mode%s %ix%i\n",
refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
- diff = refresh;
+ if (!refresh_specified) {
+ /*
+ * If the caller has provided a custom mode database and a
+ * valid monspecs structure, we look for the mode with the
+ * highest refresh rate. Otherwise we play it safe it and
+ * try to find a mode with a refresh rate closest to the
+ * standard 60 Hz.
+ */
+ if (db != modedb &&
+ info->monspecs.vfmin && info->monspecs.vfmax &&
+ info->monspecs.hfmin && info->monspecs.hfmax &&
+ info->monspecs.dclkmax) {
+ refresh = 1000;
+ } else {
+ refresh = 60;
+ }
+ }
+
+ diff = -1;
best = -1;
for (i = 0; i < dbsize; i++) {
- if (name_matches(db[i], name, namelen) ||
- (res_specified && res_matches(db[i], xres, yres))) {
- if(!fb_try_mode(var, info, &db[i], bpp)) {
- if(!refresh_specified || db[i].refresh == refresh)
- return 1;
- else {
- if(diff > abs(db[i].refresh - refresh)) {
- diff = abs(db[i].refresh - refresh);
- best = i;
- }
+ if ((name_matches(db[i], name, namelen) ||
+ (res_specified && res_matches(db[i], xres, yres))) &&
+ !fb_try_mode(var, info, &db[i], bpp)) {
+ if (refresh_specified && db[i].refresh == refresh) {
+ return 1;
+ } else {
+ if (abs(db[i].refresh - refresh) < diff) {
+ diff = abs(db[i].refresh - refresh);
+ best = i;
}
}
}
}
if (best != -1) {
fb_try_mode(var, info, &db[best], bpp);
- return 2;
+ return (refresh_specified) ? 2 : 1;
}
diff = xres + yres;
@@ -938,6 +957,7 @@ void fb_destroy_modelist(struct list_head *head)
kfree(pos);
}
}
+EXPORT_SYMBOL_GPL(fb_destroy_modelist);
/**
* fb_videomode_to_modelist: convert mode array to mode list
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 731d7a5c5aa..4b6a99b5be0 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -72,7 +72,6 @@
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index afe4567e1ff..6fd7cb8f9b8 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -125,11 +125,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
par->chan[1].par = par;
par->chan[2].par = par;
- par->chan[0].ddc_base = 0x36;
- nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON);
+ par->chan[0].ddc_base = (par->reverse_i2c) ? 0x36 : 0x3e;
+ nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0",
+ (par->reverse_i2c) ? I2C_CLASS_HWMON : 0);
- par->chan[1].ddc_base = 0x3e;
- nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0);
+ par->chan[1].ddc_base = (par->reverse_i2c) ? 0x3e : 0x36;
+ nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1",
+ (par->reverse_i2c) ? 0 : I2C_CLASS_HWMON);
par->chan[2].ddc_base = 0x50;
nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index 2fdf77ec39f..f132aab8c5d 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -135,6 +135,7 @@ struct nvidia_par {
int paneltweak;
int LVDS;
int pm_state;
+ int reverse_i2c;
u32 crtcSync_read;
u32 fpSyncs;
u32 dmaPut;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index a7fe214f0f7..30e14eb1f51 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -79,6 +79,7 @@ static int noscale __devinitdata = 0;
static int paneltweak __devinitdata = 0;
static int vram __devinitdata = 0;
static int bpp __devinitdata = 8;
+static int reverse_i2c __devinitdata;
#ifdef CONFIG_MTRR
static int nomtrr __devinitdata = 0;
#endif
@@ -1305,6 +1306,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
par->CRTCnumber = forceCRTC;
par->FpScale = (!noscale);
par->paneltweak = paneltweak;
+ par->reverse_i2c = reverse_i2c;
/* enable IO and mem if not already done */
pci_read_config_word(pd, PCI_COMMAND, &cmd);
@@ -1486,6 +1488,8 @@ static int __devinit nvidiafb_setup(char *options)
noaccel = 1;
} else if (!strncmp(this_opt, "noscale", 7)) {
noscale = 1;
+ } else if (!strncmp(this_opt, "reverse_i2c", 11)) {
+ reverse_i2c = 1;
} else if (!strncmp(this_opt, "paneltweak:", 11)) {
paneltweak = simple_strtoul(this_opt+11, NULL, 0);
} else if (!strncmp(this_opt, "vram:", 5)) {
@@ -1582,6 +1586,8 @@ MODULE_PARM_DESC(mode_option, "Specify initial video mode");
module_param(bpp, int, 0);
MODULE_PARM_DESC(bpp, "pixel width in bits"
"(default=8)");
+module_param(reverse_i2c, int, 0);
+MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
#ifdef CONFIG_MTRR
module_param(nomtrr, bool, 0);
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index e682940a97a..4d8ad9cd0e1 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -225,7 +225,7 @@ static void blizzard_restart_sdram(void)
while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
if (time_after(jiffies, tmo)) {
dev_err(blizzard.fbdev->dev,
- "s1d1374x: SDRAM not ready");
+ "s1d1374x: SDRAM not ready\n");
break;
}
msleep(1);
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index f4c23434de6..ab32ceb0617 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -880,19 +880,19 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
static int get_dss_clocks(void)
{
if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) {
- dev_err(dispc.fbdev->dev, "can't get dss_ick");
+ dev_err(dispc.fbdev->dev, "can't get dss_ick\n");
return PTR_ERR(dispc.dss_ick);
}
if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) {
- dev_err(dispc.fbdev->dev, "can't get dss1_fck");
+ dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
clk_put(dispc.dss_ick);
return PTR_ERR(dispc.dss1_fck);
}
if (IS_ERR((dispc.dss_54m_fck =
clk_get(dispc.fbdev->dev, "dss_54m_fck")))) {
- dev_err(dispc.fbdev->dev, "can't get dss_54m_fck");
+ dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n");
clk_put(dispc.dss_ick);
clk_put(dispc.dss1_fck);
return PTR_ERR(dispc.dss_54m_fck);
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index dc48e02f215..1e642b7a20f 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -508,7 +508,7 @@ int hwa742_update_window_async(struct fb_info *fbi,
if (unlikely(win->format &
~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE |
OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) {
- dev_dbg(hwa742.fbdev->dev, "invalid window flag");
+ dev_dbg(hwa742.fbdev->dev, "invalid window flag\n");
r = -EINVAL;
goto out;
}
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
index 51807b4e26d..c604d935c18 100644
--- a/drivers/video/omap/lcd_h3.c
+++ b/drivers/video/omap/lcd_h3.c
@@ -28,8 +28,6 @@
#define MODULE_NAME "omapfb-lcd_h3"
-#define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args)
-
static int h3_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
{
return 0;
@@ -48,7 +46,7 @@ static int h3_panel_enable(struct lcd_panel *panel)
if (!r)
r = tps65010_set_gpio_out_value(GPIO2, HIGH);
if (r)
- pr_err("Unable to turn on LCD panel\n");
+ pr_err(MODULE_NAME ": Unable to turn on LCD panel\n");
return r;
}
@@ -62,7 +60,7 @@ static void h3_panel_disable(struct lcd_panel *panel)
if (!r)
tps65010_set_gpio_out_value(GPIO2, LOW);
if (r)
- pr_err("Unable to turn off LCD panel\n");
+ pr_err(MODULE_NAME ": Unable to turn off LCD panel\n");
}
static unsigned long h3_panel_get_caps(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 95604ca4330..5ef119c813e 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -27,20 +27,18 @@
#define MODULE_NAME "omapfb-lcd_h3"
-#define pr_err(fmt, args...) printk(KERN_ERR MODULE_NAME ": " fmt, ## args)
-
static int innovator1610_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
int r = 0;
if (omap_request_gpio(14)) {
- pr_err("can't request GPIO 14\n");
+ pr_err(MODULE_NAME ": can't request GPIO 14\n");
r = -1;
goto exit;
}
if (omap_request_gpio(15)) {
- pr_err("can't request GPIO 15\n");
+ pr_err(MODULE_NAME ": can't request GPIO 15\n");
omap_free_gpio(14);
r = -1;
goto exit;
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index 2b4269813b2..789cfd23c36 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -84,12 +84,12 @@ static inline u32 rfbi_read_reg(int idx)
static int rfbi_get_clocks(void)
{
if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) {
- dev_err(rfbi.fbdev->dev, "can't get dss_ick");
+ dev_err(rfbi.fbdev->dev, "can't get dss_ick\n");
return PTR_ERR(rfbi.dss_ick);
}
if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) {
- dev_err(rfbi.fbdev->dev, "can't get dss1_fck");
+ dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
clk_put(rfbi.dss_ick);
return PTR_ERR(rfbi.dss1_fck);
}
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 10c0cc6e93f..5591dfb22b1 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -11,7 +11,7 @@
* and additional input from James Simmon's port of Hannu Mallat's tdfx
* driver.
*
- * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I
+ * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I
* have no access to other pm2fb implementations. Sparc (and thus
* hopefully other big-endian) devices now work, thanks to a lot of
* testing work by Ron Murray. I have no access to CVision hardware,
@@ -38,6 +38,9 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
#include <video/permedia2.h>
#include <video/cvisionppc.h>
@@ -52,15 +55,19 @@
#undef PM2FB_MASTER_DEBUG
#ifdef PM2FB_MASTER_DEBUG
-#define DPRINTK(a,b...) printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
+#define DPRINTK(a, b...) \
+ printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
#else
-#define DPRINTK(a,b...)
+#define DPRINTK(a, b...)
#endif
+#define PM2_PIXMAP_SIZE (1600 * 4)
+
/*
* Driver data
*/
-static char *mode __devinitdata = NULL;
+static int hwcursor = 1;
+static char *mode __devinitdata;
/*
* The XFree GLINT driver will (I think to implement hardware cursor
@@ -73,6 +80,11 @@ static char *mode __devinitdata = NULL;
*/
static int lowhsync;
static int lowvsync;
+static int noaccel __devinitdata;
+/* mtrr option */
+#ifdef CONFIG_MTRR
+static int nomtrr __devinitdata;
+#endif
/*
* The hardware state of the graphics card that isn't part of the
@@ -88,6 +100,7 @@ struct pm2fb_par
u32 mem_control; /* MemControl reg at probe */
u32 boot_address; /* BootAddress reg at probe */
u32 palette[16];
+ int mtrr_handle;
};
/*
@@ -135,60 +148,39 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = {
* Utility functions
*/
-static inline u32 RD32(unsigned char __iomem *base, s32 off)
-{
- return fb_readl(base + off);
-}
-
-static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
+static inline u32 pm2_RD(struct pm2fb_par *p, s32 off)
{
- fb_writel(v, base + off);
+ return fb_readl(p->v_regs + off);
}
-static inline u32 pm2_RD(struct pm2fb_par* p, s32 off)
+static inline void pm2_WR(struct pm2fb_par *p, s32 off, u32 v)
{
- return RD32(p->v_regs, off);
+ fb_writel(v, p->v_regs + off);
}
-static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
+static inline u32 pm2_RDAC_RD(struct pm2fb_par *p, s32 idx)
{
- WR32(p->v_regs, off, v);
+ pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
+ mb();
+ return pm2_RD(p, PM2R_RD_INDEXED_DATA);
}
-static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
+static inline u32 pm2v_RDAC_RD(struct pm2fb_par *p, s32 idx)
{
- int index = PM2R_RD_INDEXED_DATA;
- switch (p->type) {
- case PM2_TYPE_PERMEDIA2:
- pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
- break;
- case PM2_TYPE_PERMEDIA2V:
- pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
- index = PM2VR_RD_INDEXED_DATA;
- break;
- }
+ pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
mb();
- return pm2_RD(p, index);
+ return pm2_RD(p, PM2VR_RD_INDEXED_DATA);
}
-static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2_RDAC_WR(struct pm2fb_par *p, s32 idx, u32 v)
{
- int index = PM2R_RD_INDEXED_DATA;
- switch (p->type) {
- case PM2_TYPE_PERMEDIA2:
- pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
- break;
- case PM2_TYPE_PERMEDIA2V:
- pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
- index = PM2VR_RD_INDEXED_DATA;
- break;
- }
+ pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
wmb();
- pm2_WR(p, index, v);
+ pm2_WR(p, PM2R_RD_INDEXED_DATA, v);
wmb();
}
-static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2v_RDAC_WR(struct pm2fb_par *p, s32 idx, u32 v)
{
pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
wmb();
@@ -199,10 +191,10 @@ static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
#define WAIT_FIFO(p, a)
#else
-static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
+static inline void WAIT_FIFO(struct pm2fb_par *p, u32 a)
{
- while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
- mb();
+ while (pm2_RD(p, PM2R_IN_FIFO_SPACE) < a)
+ cpu_relax();
}
#endif
@@ -238,7 +230,7 @@ static u32 partprod(u32 xres)
for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++)
;
- if ( pp_table[i].width == 0 )
+ if (pp_table[i].width == 0)
DPRINTK("invalid width %u\n", xres);
return pp_table[i].pp;
}
@@ -246,25 +238,22 @@ static u32 partprod(u32 xres)
static u32 to3264(u32 timing, int bpp, int is64)
{
switch (bpp) {
+ case 24:
+ timing *= 3;
case 8:
- timing >>= 2 + is64;
- break;
+ timing >>= 1;
case 16:
- timing >>= 1 + is64;
- break;
- case 24:
- timing = (timing * 3) >> (2 + is64);
- break;
+ timing >>= 1;
case 32:
- if (is64)
- timing >>= 1;
break;
}
+ if (is64)
+ timing >>= 1;
return timing;
}
-static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
- unsigned char* pp)
+static void pm2_mnp(u32 clk, unsigned char *mm, unsigned char *nn,
+ unsigned char *pp)
{
unsigned char m;
unsigned char n;
@@ -278,13 +267,13 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
for (m = 2; m; m++) {
f = PM2_REFERENCE_CLOCK * m / n;
if (f >= 150000 && f <= 300000) {
- for ( p = 0; p < 5; p++, f >>= 1) {
- curr = ( clk > f ) ? clk - f : f - clk;
- if ( curr < delta ) {
- delta=curr;
- *mm=m;
- *nn=n;
- *pp=p;
+ for (p = 0; p < 5; p++, f >>= 1) {
+ curr = (clk > f) ? clk - f : f - clk;
+ if (curr < delta) {
+ delta = curr;
+ *mm = m;
+ *nn = n;
+ *pp = p;
}
}
}
@@ -292,8 +281,8 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
}
}
-static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
- unsigned char* pp)
+static void pm2v_mnp(u32 clk, unsigned char *mm, unsigned char *nn,
+ unsigned char *pp)
{
unsigned char m;
unsigned char n;
@@ -302,23 +291,24 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
s32 delta = 1000;
*mm = *nn = *pp = 0;
- for ( m = 1; m < 128; m++) {
+ for (m = 1; m < 128; m++) {
for (n = 2 * m + 1; n; n++) {
- for ( p = 0; p < 2; p++) {
- f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m;
- if ( clk > f - delta && clk < f + delta ) {
- delta = ( clk > f ) ? clk - f : f - clk;
- *mm=m;
- *nn=n;
- *pp=p;
+ for (p = 0; p < 2; p++) {
+ f = (PM2_REFERENCE_CLOCK >> (p + 1)) * n / m;
+ if (clk > f - delta && clk < f + delta) {
+ delta = (clk > f) ? clk - f : f - clk;
+ *mm = m;
+ *nn = n;
+ *pp = p;
}
}
}
}
}
-static void clear_palette(struct pm2fb_par* p) {
- int i=256;
+static void clear_palette(struct pm2fb_par *p)
+{
+ int i = 256;
WAIT_FIFO(p, 1);
pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
@@ -331,14 +321,14 @@ static void clear_palette(struct pm2fb_par* p) {
}
}
-static void reset_card(struct pm2fb_par* p)
+static void reset_card(struct pm2fb_par *p)
{
if (p->type == PM2_TYPE_PERMEDIA2V)
pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0);
pm2_WR(p, PM2R_RESET_STATUS, 0);
mb();
while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET)
- ;
+ cpu_relax();
mb();
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
DPRINTK("FIFO disconnect enabled\n");
@@ -354,11 +344,11 @@ static void reset_card(struct pm2fb_par* p)
pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config);
}
-static void reset_config(struct pm2fb_par* p)
+static void reset_config(struct pm2fb_par *p)
{
- WAIT_FIFO(p, 52);
+ WAIT_FIFO(p, 53);
pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) &
- ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED));
+ ~(PM2F_VGA_ENABLE | PM2F_VGA_FIXED));
pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L));
pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L));
pm2_WR(p, PM2R_FIFO_CONTROL, 0);
@@ -393,31 +383,32 @@ static void reset_config(struct pm2fb_par* p)
pm2_WR(p, PM2R_STATISTICS_MODE, 0);
pm2_WR(p, PM2R_SCISSOR_MODE, 0);
pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION);
+ pm2_WR(p, PM2R_RD_PIXEL_MASK, 0xff);
switch (p->type) {
case PM2_TYPE_PERMEDIA2:
pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */
pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0);
pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8);
+ pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
+ pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
+ pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
+ pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
+ pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
break;
case PM2_TYPE_PERMEDIA2V:
pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */
break;
}
- pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
- pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
- pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
- pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
- pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
}
-static void set_aperture(struct pm2fb_par* p, u32 depth)
+static void set_aperture(struct pm2fb_par *p, u32 depth)
{
/*
* The hardware is little-endian. When used in big-endian
* hosts, the on-chip aperture settings are used where
* possible to translate from host to card byte order.
*/
- WAIT_FIFO(p, 4);
+ WAIT_FIFO(p, 2);
#ifdef __LITTLE_ENDIAN
pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
#else
@@ -440,11 +431,11 @@ static void set_aperture(struct pm2fb_par* p, u32 depth)
}
#endif
- // We don't use aperture two, so this may be superflous
+ /* We don't use aperture two, so this may be superflous */
pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD);
}
-static void set_color(struct pm2fb_par* p, unsigned char regno,
+static void set_color(struct pm2fb_par *p, unsigned char regno,
unsigned char r, unsigned char g, unsigned char b)
{
WAIT_FIFO(p, 4);
@@ -457,7 +448,7 @@ static void set_color(struct pm2fb_par* p, unsigned char regno,
pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
}
-static void set_memclock(struct pm2fb_par* par, u32 clk)
+static void set_memclock(struct pm2fb_par *par, u32 clk)
{
int i;
unsigned char m, n, p;
@@ -465,7 +456,7 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
switch (par->type) {
case PM2_TYPE_PERMEDIA2V:
pm2v_mnp(clk/2, &m, &n, &p);
- WAIT_FIFO(par, 8);
+ WAIT_FIFO(par, 12);
pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
@@ -473,10 +464,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
rmb();
- for (i = 256;
- i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2);
- i--)
- ;
+ for (i = 256; i; i--)
+ if (pm2v_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2)
+ break;
pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
break;
case PM2_TYPE_PERMEDIA2:
@@ -488,15 +478,14 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
rmb();
- for (i = 256;
- i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
- i--)
- ;
+ for (i = 256; i; i--)
+ if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED)
+ break;
break;
}
}
-static void set_pixclock(struct pm2fb_par* par, u32 clk)
+static void set_pixclock(struct pm2fb_par *par, u32 clk)
{
int i;
unsigned char m, n, p;
@@ -504,17 +493,16 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
switch (par->type) {
case PM2_TYPE_PERMEDIA2:
pm2_mnp(clk, &m, &n, &p);
- WAIT_FIFO(par, 8);
+ WAIT_FIFO(par, 10);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
rmb();
- for (i = 256;
- i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
- i--)
- ;
+ for (i = 256; i; i--)
+ if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED)
+ break;
break;
case PM2_TYPE_PERMEDIA2V:
pm2v_mnp(clk/2, &m, &n, &p);
@@ -528,11 +516,10 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
}
}
-static void set_video(struct pm2fb_par* p, u32 video) {
+static void set_video(struct pm2fb_par *p, u32 video)
+{
u32 tmp;
- u32 vsync;
-
- vsync = video;
+ u32 vsync = video;
DPRINTK("video = 0x%x\n", video);
@@ -542,10 +529,10 @@ static void set_video(struct pm2fb_par* p, u32 video) {
* driver may well. So always set +hsync/+vsync and then set
* the RAMDAC to invert the sync if necessary.
*/
- vsync &= ~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK);
- vsync |= PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH;
+ vsync &= ~(PM2F_HSYNC_MASK | PM2F_VSYNC_MASK);
+ vsync |= PM2F_HSYNC_ACT_HIGH | PM2F_VSYNC_ACT_HIGH;
- WAIT_FIFO(p, 5);
+ WAIT_FIFO(p, 3);
pm2_WR(p, PM2R_VIDEO_CONTROL, vsync);
switch (p->type) {
@@ -564,16 +551,11 @@ static void set_video(struct pm2fb_par* p, u32 video) {
if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
tmp |= 4; /* invert vsync */
pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp);
- pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1);
break;
}
}
/*
- *
- */
-
-/**
* pm2fb_check_var - Optional function. Validates a var passed in.
* @var: frame buffer variable screen structure
* @info: frame buffer structure that represents a single frame buffer
@@ -594,15 +576,22 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
if (var->xres != var->xres_virtual) {
- DPRINTK("virtual x resolution != physical x resolution not supported\n");
+ DPRINTK("virtual x resolution != "
+ "physical x resolution not supported\n");
return -EINVAL;
}
if (var->yres > var->yres_virtual) {
- DPRINTK("virtual y resolution < physical y resolution not possible\n");
+ DPRINTK("virtual y resolution < "
+ "physical y resolution not possible\n");
return -EINVAL;
}
+ /* permedia cannot blit over 2048 */
+ if (var->yres_virtual > 2047) {
+ var->yres_virtual = 2047;
+ }
+
if (var->xoffset) {
DPRINTK("xoffset not supported\n");
return -EINVAL;
@@ -614,7 +603,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
- lpitch = var->xres * ((var->bits_per_pixel + 7)>>3);
+ lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
if (var->xres < 320 || var->xres > 1600) {
DPRINTK("width not supported: %u\n", var->xres);
@@ -633,15 +622,18 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) {
- DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock));
+ DPRINTK("pixclock too high (%ldKHz)\n",
+ PICOS2KHZ(var->pixclock));
return -EINVAL;
}
var->transp.offset = 0;
var->transp.length = 0;
- switch(var->bits_per_pixel) {
+ switch (var->bits_per_pixel) {
case 8:
- var->red.length = var->green.length = var->blue.length = 8;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
break;
case 16:
var->red.offset = 11;
@@ -657,7 +649,9 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->red.offset = 16;
var->green.offset = 8;
var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 8;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
break;
case 24:
#ifdef __BIG_ENDIAN
@@ -668,10 +662,13 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->blue.offset = 0;
#endif
var->green.offset = 8;
- var->red.length = var->green.length = var->blue.length = 8;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
break;
}
- var->height = var->width = -1;
+ var->height = -1;
+ var->width = -1;
var->accel_flags = 0; /* Can't mmap if this is on */
@@ -691,7 +688,9 @@ static int pm2fb_set_par(struct fb_info *info)
{
struct pm2fb_par *par = info->par;
u32 pixclock;
- u32 width, height, depth;
+ u32 width = (info->var.xres_virtual + 7) & ~7;
+ u32 height = info->var.yres_virtual;
+ u32 depth = (info->var.bits_per_pixel + 7) & ~7;
u32 hsstart, hsend, hbend, htotal;
u32 vsstart, vsend, vbend, vtotal;
u32 stride;
@@ -701,22 +700,19 @@ static int pm2fb_set_par(struct fb_info *info)
u32 txtmap = 0;
u32 pixsize = 0;
u32 clrformat = 0;
- u32 xres;
+ u32 misc = 1; /* 8-bit DAC */
+ u32 xres = (info->var.xres + 31) & ~31;
int data64;
reset_card(par);
reset_config(par);
clear_palette(par);
- if ( par->memclock )
+ if (par->memclock)
set_memclock(par, par->memclock);
- width = (info->var.xres_virtual + 7) & ~7;
- height = info->var.yres_virtual;
- depth = (info->var.bits_per_pixel + 7) & ~7;
depth = (depth > 32) ? 32 : depth;
data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V;
- xres = (info->var.xres + 31) & ~31;
pixclock = PICOS2KHZ(info->var.pixclock);
if (pixclock > PM2_MAX_PIXCLOCK) {
DPRINTK("pixclock too high (%uKHz)\n", pixclock);
@@ -731,7 +727,8 @@ static int pm2fb_set_par(struct fb_info *info)
? info->var.lower_margin - 1
: 0; /* FIXME! */
vsend = info->var.lower_margin + info->var.vsync_len - 1;
- vbend = info->var.lower_margin + info->var.vsync_len + info->var.upper_margin;
+ vbend = info->var.lower_margin + info->var.vsync_len +
+ info->var.upper_margin;
vtotal = info->var.yres + vbend - 1;
stride = to3264(width, depth, 1);
base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1);
@@ -744,25 +741,25 @@ static int pm2fb_set_par(struct fb_info *info)
video |= PM2F_HSYNC_ACT_LOW;
} else
video |= PM2F_HSYNC_ACT_HIGH;
- }
- else
+ } else
video |= PM2F_HSYNC_ACT_LOW;
+
if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) {
if (lowvsync) {
DPRINTK("ignoring +vsync, using -vsync.\n");
video |= PM2F_VSYNC_ACT_LOW;
} else
video |= PM2F_VSYNC_ACT_HIGH;
- }
- else
+ } else
video |= PM2F_VSYNC_ACT_LOW;
- if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) {
+
+ if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
DPRINTK("interlaced not supported\n");
return -EINVAL;
}
- if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
+ if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
video |= PM2F_LINE_DOUBLE;
- if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW)
+ if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
video |= PM2F_VIDEO_ENABLE;
par->video = video;
@@ -783,12 +780,10 @@ static int pm2fb_set_par(struct fb_info *info)
mb();
WAIT_FIFO(par, 19);
- pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
- ( depth == 8 ) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
switch (depth) {
case 8:
pm2_WR(par, PM2R_FB_READ_PIXEL, 0);
- clrformat = 0x0e;
+ clrformat = 0x2e;
break;
case 16:
pm2_WR(par, PM2R_FB_READ_PIXEL, 1);
@@ -796,6 +791,7 @@ static int pm2fb_set_par(struct fb_info *info)
txtmap = PM2F_TEXTEL_SIZE_16;
pixsize = 1;
clrformat = 0x70;
+ misc |= 8;
break;
case 32:
pm2_WR(par, PM2R_FB_READ_PIXEL, 2);
@@ -803,6 +799,7 @@ static int pm2fb_set_par(struct fb_info *info)
txtmap = PM2F_TEXTEL_SIZE_32;
pixsize = 2;
clrformat = 0x20;
+ misc |= 8;
break;
case 24:
pm2_WR(par, PM2R_FB_READ_PIXEL, 4);
@@ -810,6 +807,7 @@ static int pm2fb_set_par(struct fb_info *info)
txtmap = PM2F_TEXTEL_SIZE_24;
pixsize = 4;
clrformat = 0x20;
+ misc |= 8;
break;
}
pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
@@ -834,14 +832,19 @@ static int pm2fb_set_par(struct fb_info *info)
pm2_WR(par, PM2R_SCREEN_BASE, base);
wmb();
set_video(par, video);
- WAIT_FIFO(par, 4);
+ WAIT_FIFO(par, 10);
switch (par->type) {
case PM2_TYPE_PERMEDIA2:
pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode);
+ pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
+ (depth == 8) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
break;
case PM2_TYPE_PERMEDIA2V:
+ pm2v_RDAC_WR(par, PM2VI_RD_DAC_CONTROL, 0);
pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize);
pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat);
+ pm2v_RDAC_WR(par, PM2VI_RD_MISC_CONTROL, misc);
+ pm2v_RDAC_WR(par, PM2VI_RD_OVERLAY_KEY, 0);
break;
}
set_pixclock(par, pixclock);
@@ -872,16 +875,15 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
struct pm2fb_par *par = info->par;
if (regno >= info->cmap.len) /* no. of hw registers */
- return 1;
+ return -EINVAL;
/*
* Program hardware... do anything you want with transp
*/
/* grayscale works only partially under directcolor */
- if (info->var.grayscale) {
- /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ if (info->var.grayscale)
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
- }
/* Directcolor:
* var->{color}.offset contains start of bitfield
@@ -931,7 +933,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
u32 v;
if (regno >= 16)
- return 1;
+ return -EINVAL;
v = (red << info->var.red.offset) |
(green << info->var.green.offset) |
@@ -948,8 +950,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
break;
}
return 0;
- }
- else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
+ } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
set_color(par, regno, red, green, blue);
return 0;
@@ -972,11 +973,9 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
{
struct pm2fb_par *p = info->par;
u32 base;
- u32 depth;
- u32 xres;
+ u32 depth = (var->bits_per_pixel + 7) & ~7;
+ u32 xres = (var->xres + 31) & ~31;
- xres = (var->xres + 31) & ~31;
- depth = (var->bits_per_pixel + 7) & ~7;
depth = (depth > 32) ? 32 : depth;
base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
WAIT_FIFO(p, 1);
@@ -1018,15 +1017,15 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info)
break;
case FB_BLANK_VSYNC_SUSPEND:
/* VSync: Off */
- video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW );
+ video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW);
break;
case FB_BLANK_HSYNC_SUSPEND:
/* HSync: Off */
- video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW );
+ video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW);
break;
case FB_BLANK_POWERDOWN:
/* HSync: Off, VSync: Off */
- video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK| PM2F_BLANK_LOW);
+ video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK | PM2F_BLANK_LOW);
break;
}
set_video(par, video);
@@ -1042,48 +1041,20 @@ static int pm2fb_sync(struct fb_info *info)
mb();
do {
while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0)
- udelay(10);
- rmb();
+ cpu_relax();
} while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
return 0;
}
-/*
- * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
- */
-static void pm2fb_block_op(struct fb_info* info, int copy,
- s32 xsrc, s32 ysrc,
- s32 x, s32 y, s32 w, s32 h,
- u32 color) {
- struct pm2fb_par *par = info->par;
-
- if (!w || !h)
- return;
- WAIT_FIFO(par, 5);
- pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
- PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
- if (copy)
- pm2_WR(par, PM2R_FB_SOURCE_DELTA,
- ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
- else
- pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
- pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
- pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
- wmb();
- pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE |
- (x<xsrc ? PM2F_INCREASE_X : 0) |
- (y<ysrc ? PM2F_INCREASE_Y : 0) |
- (copy ? 0 : PM2F_RENDER_FASTFILL));
-}
-
-static void pm2fb_fillrect (struct fb_info *info,
+static void pm2fb_fillrect(struct fb_info *info,
const struct fb_fillrect *region)
{
+ struct pm2fb_par *par = info->par;
struct fb_fillrect modded;
int vxres, vyres;
u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
- ((u32*)info->pseudo_palette)[region->color] : region->color;
+ ((u32 *)info->pseudo_palette)[region->color] : region->color;
if (info->state != FBINFO_STATE_RUNNING)
return;
@@ -1098,31 +1069,46 @@ static void pm2fb_fillrect (struct fb_info *info,
memcpy(&modded, region, sizeof(struct fb_fillrect));
- if(!modded.width || !modded.height ||
- modded.dx >= vxres || modded.dy >= vyres)
+ if (!modded.width || !modded.height ||
+ modded.dx >= vxres || modded.dy >= vyres)
return;
- if(modded.dx + modded.width > vxres)
+ if (modded.dx + modded.width > vxres)
modded.width = vxres - modded.dx;
- if(modded.dy + modded.height > vyres)
+ if (modded.dy + modded.height > vyres)
modded.height = vyres - modded.dy;
- if(info->var.bits_per_pixel == 8)
+ if (info->var.bits_per_pixel == 8)
color |= color << 8;
- if(info->var.bits_per_pixel <= 16)
+ if (info->var.bits_per_pixel <= 16)
color |= color << 16;
- if(info->var.bits_per_pixel != 24)
- pm2fb_block_op(info, 0, 0, 0,
- modded.dx, modded.dy,
- modded.width, modded.height, color);
- else
- cfb_fillrect(info, region);
+ WAIT_FIFO(par, 3);
+ pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE);
+ pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx);
+ pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width);
+ if (info->var.bits_per_pixel != 24) {
+ WAIT_FIFO(par, 2);
+ pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
+ wmb();
+ pm2_WR(par, PM2R_RENDER,
+ PM2F_RENDER_RECTANGLE | PM2F_RENDER_FASTFILL);
+ } else {
+ WAIT_FIFO(par, 4);
+ pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
+ pm2_WR(par, PM2R_CONSTANT_COLOR, color);
+ wmb();
+ pm2_WR(par, PM2R_RENDER,
+ PM2F_RENDER_RECTANGLE |
+ PM2F_INCREASE_X | PM2F_INCREASE_Y );
+ pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
+ }
}
static void pm2fb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
+ struct pm2fb_par *par = info->par;
struct fb_copyarea modded;
u32 vxres, vyres;
@@ -1138,23 +1124,359 @@ static void pm2fb_copyarea(struct fb_info *info,
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
- if(!modded.width || !modded.height ||
- modded.sx >= vxres || modded.sy >= vyres ||
- modded.dx >= vxres || modded.dy >= vyres)
+ if (!modded.width || !modded.height ||
+ modded.sx >= vxres || modded.sy >= vyres ||
+ modded.dx >= vxres || modded.dy >= vyres)
return;
- if(modded.sx + modded.width > vxres)
+ if (modded.sx + modded.width > vxres)
modded.width = vxres - modded.sx;
- if(modded.dx + modded.width > vxres)
+ if (modded.dx + modded.width > vxres)
modded.width = vxres - modded.dx;
- if(modded.sy + modded.height > vyres)
+ if (modded.sy + modded.height > vyres)
modded.height = vyres - modded.sy;
- if(modded.dy + modded.height > vyres)
+ if (modded.dy + modded.height > vyres)
modded.height = vyres - modded.dy;
- pm2fb_block_op(info, 1, modded.sx, modded.sy,
- modded.dx, modded.dy,
- modded.width, modded.height, 0);
+ WAIT_FIFO(par, 5);
+ pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
+ PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+ pm2_WR(par, PM2R_FB_SOURCE_DELTA,
+ ((modded.sy - modded.dy) & 0xfff) << 16 |
+ ((modded.sx - modded.dx) & 0xfff));
+ pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx);
+ pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width);
+ wmb();
+ pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE |
+ (modded.dx < modded.sx ? PM2F_INCREASE_X : 0) |
+ (modded.dy < modded.sy ? PM2F_INCREASE_Y : 0));
+}
+
+static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct pm2fb_par *par = info->par;
+ u32 height = image->height;
+ u32 fgx, bgx;
+ const u32 *src = (const u32 *)image->data;
+ u32 xres = (info->var.xres + 31) & ~31;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) {
+ cfb_imageblit(info, image);
+ return;
+ }
+ switch (info->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ fgx = image->fg_color;
+ bgx = image->bg_color;
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ default:
+ fgx = par->palette[image->fg_color];
+ bgx = par->palette[image->bg_color];
+ break;
+ }
+ if (info->var.bits_per_pixel == 8) {
+ fgx |= fgx << 8;
+ bgx |= bgx << 8;
+ }
+ if (info->var.bits_per_pixel <= 16) {
+ fgx |= fgx << 16;
+ bgx |= bgx << 16;
+ }
+
+ WAIT_FIFO(par, 13);
+ pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
+ pm2_WR(par, PM2R_SCISSOR_MIN_XY,
+ ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
+ pm2_WR(par, PM2R_SCISSOR_MAX_XY,
+ (((image->dy + image->height) & 0x0fff) << 16) |
+ ((image->dx + image->width) & 0x0fff));
+ pm2_WR(par, PM2R_SCISSOR_MODE, 1);
+ /* GXcopy & UNIT_ENABLE */
+ pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1);
+ pm2_WR(par, PM2R_RECTANGLE_ORIGIN,
+ ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
+ pm2_WR(par, PM2R_RECTANGLE_SIZE,
+ ((image->height & 0x0fff) << 16) |
+ ((image->width) & 0x0fff));
+ if (info->var.bits_per_pixel == 24) {
+ pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
+ /* clear area */
+ pm2_WR(par, PM2R_CONSTANT_COLOR, bgx);
+ pm2_WR(par, PM2R_RENDER,
+ PM2F_RENDER_RECTANGLE |
+ PM2F_INCREASE_X | PM2F_INCREASE_Y);
+ /* BitMapPackEachScanline & invert bits and byte order*/
+ /* force background */
+ pm2_WR(par, PM2R_RASTERIZER_MODE, (1 << 9) | 1 | (3 << 7));
+ pm2_WR(par, PM2R_CONSTANT_COLOR, fgx);
+ pm2_WR(par, PM2R_RENDER,
+ PM2F_RENDER_RECTANGLE |
+ PM2F_INCREASE_X | PM2F_INCREASE_Y |
+ PM2F_RENDER_SYNC_ON_BIT_MASK);
+ } else {
+ pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
+ /* clear area */
+ pm2_WR(par, PM2R_FB_BLOCK_COLOR, bgx);
+ pm2_WR(par, PM2R_RENDER,
+ PM2F_RENDER_RECTANGLE |
+ PM2F_RENDER_FASTFILL |
+ PM2F_INCREASE_X | PM2F_INCREASE_Y);
+ /* invert bits and byte order*/
+ pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3 << 7));
+ pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx);
+ pm2_WR(par, PM2R_RENDER,
+ PM2F_RENDER_RECTANGLE |
+ PM2F_INCREASE_X | PM2F_INCREASE_Y |
+ PM2F_RENDER_FASTFILL |
+ PM2F_RENDER_SYNC_ON_BIT_MASK);
+ }
+
+ while (height--) {
+ int width = ((image->width + 7) >> 3)
+ + info->pixmap.scan_align - 1;
+ width >>= 2;
+ WAIT_FIFO(par, width);
+ while (width--) {
+ pm2_WR(par, PM2R_BIT_MASK_PATTERN, *src);
+ src++;
+ }
+ }
+ WAIT_FIFO(par, 3);
+ pm2_WR(par, PM2R_RASTERIZER_MODE, 0);
+ pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
+ pm2_WR(par, PM2R_SCISSOR_MODE, 0);
+}
+
+/*
+ * Hardware cursor support.
+ */
+static const u8 cursor_bits_lookup[16] = {
+ 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
+ 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
+};
+
+static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ struct pm2fb_par *par = info->par;
+ u8 mode = PM2F_CURSORMODE_TYPE_X;
+ int x = cursor->image.dx - info->var.xoffset;
+ int y = cursor->image.dy - info->var.yoffset;
+
+ if (cursor->enable)
+ mode |= PM2F_CURSORMODE_CURSOR_ENABLE;
+
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_MODE, mode);
+
+ if (!cursor->enable)
+ x = 2047; /* push it outside display */
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_LOW, x & 0xff);
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_HIGH, (x >> 8) & 0xf);
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_LOW, y & 0xff);
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_HIGH, (y >> 8) & 0xf);
+
+ /*
+ * If the cursor is not be changed this means either we want the
+ * current cursor state (if enable is set) or we want to query what
+ * we can do with the cursor (if enable is not set)
+ */
+ if (!cursor->set)
+ return 0;
+
+ if (cursor->set & FB_CUR_SETHOT) {
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_HOT,
+ cursor->hot.x & 0x3f);
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_HOT,
+ cursor->hot.y & 0x3f);
+ }
+
+ if (cursor->set & FB_CUR_SETCMAP) {
+ u32 fg_idx = cursor->image.fg_color;
+ u32 bg_idx = cursor->image.bg_color;
+ struct fb_cmap cmap = info->cmap;
+
+ /* the X11 driver says one should use these color registers */
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CURSOR_PALETTE >> 8);
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 0,
+ cmap.red[bg_idx] >> 8 );
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 1,
+ cmap.green[bg_idx] >> 8 );
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 2,
+ cmap.blue[bg_idx] >> 8 );
+
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 3,
+ cmap.red[fg_idx] >> 8 );
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 4,
+ cmap.green[fg_idx] >> 8 );
+ pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 5,
+ cmap.blue[fg_idx] >> 8 );
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
+ }
+
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
+ u8 *bitmap = (u8 *)cursor->image.data;
+ u8 *mask = (u8 *)cursor->mask;
+ int i;
+ int pos = PM2VI_RD_CURSOR_PATTERN;
+
+ for (i = 0; i < cursor->image.height; i++) {
+ int j = (cursor->image.width + 7) >> 3;
+ int k = 8 - j;
+
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, pos >> 8);
+
+ for (; j > 0; j--) {
+ u8 data = *bitmap ^ *mask;
+
+ if (cursor->rop == ROP_COPY)
+ data = *mask & *bitmap;
+ /* Upper 4 bits of bitmap data */
+ pm2v_RDAC_WR(par, pos++,
+ cursor_bits_lookup[data >> 4] |
+ (cursor_bits_lookup[*mask >> 4] << 1));
+ /* Lower 4 bits of bitmap */
+ pm2v_RDAC_WR(par, pos++,
+ cursor_bits_lookup[data & 0xf] |
+ (cursor_bits_lookup[*mask & 0xf] << 1));
+ bitmap++;
+ mask++;
+ }
+ for (; k > 0; k--) {
+ pm2v_RDAC_WR(par, pos++, 0);
+ pm2v_RDAC_WR(par, pos++, 0);
+ }
+ }
+
+ while (pos < (1024 + PM2VI_RD_CURSOR_PATTERN)) {
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, pos >> 8);
+ pm2v_RDAC_WR(par, pos++, 0);
+ }
+
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
+ }
+ return 0;
+}
+
+static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ struct pm2fb_par *par = info->par;
+ u8 mode;
+
+ if (!hwcursor)
+ return -EINVAL; /* just to force soft_cursor() call */
+
+ /* Too large of a cursor or wrong bpp :-( */
+ if (cursor->image.width > 64 ||
+ cursor->image.height > 64 ||
+ cursor->image.depth > 1)
+ return -EINVAL;
+
+ if (par->type == PM2_TYPE_PERMEDIA2V)
+ return pm2vfb_cursor(info, cursor);
+
+ mode = 0x40;
+ if (cursor->enable)
+ mode = 0x43;
+
+ pm2_RDAC_WR(par, PM2I_RD_CURSOR_CONTROL, mode);
+
+ /*
+ * If the cursor is not be changed this means either we want the
+ * current cursor state (if enable is set) or we want to query what
+ * we can do with the cursor (if enable is not set)
+ */
+ if (!cursor->set)
+ return 0;
+
+ if (cursor->set & FB_CUR_SETPOS) {
+ int x = cursor->image.dx - info->var.xoffset + 63;
+ int y = cursor->image.dy - info->var.yoffset + 63;
+
+ WAIT_FIFO(par, 4);
+ pm2_WR(par, PM2R_RD_CURSOR_X_LSB, x & 0xff);
+ pm2_WR(par, PM2R_RD_CURSOR_X_MSB, (x >> 8) & 0x7);
+ pm2_WR(par, PM2R_RD_CURSOR_Y_LSB, y & 0xff);
+ pm2_WR(par, PM2R_RD_CURSOR_Y_MSB, (y >> 8) & 0x7);
+ }
+
+ if (cursor->set & FB_CUR_SETCMAP) {
+ u32 fg_idx = cursor->image.fg_color;
+ u32 bg_idx = cursor->image.bg_color;
+
+ WAIT_FIFO(par, 7);
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_ADDRESS, 1);
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
+ info->cmap.red[bg_idx] >> 8);
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
+ info->cmap.green[bg_idx] >> 8);
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
+ info->cmap.blue[bg_idx] >> 8);
+
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
+ info->cmap.red[fg_idx] >> 8);
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
+ info->cmap.green[fg_idx] >> 8);
+ pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
+ info->cmap.blue[fg_idx] >> 8);
+ }
+
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
+ u8 *bitmap = (u8 *)cursor->image.data;
+ u8 *mask = (u8 *)cursor->mask;
+ int i;
+
+ WAIT_FIFO(par, 1);
+ pm2_WR(par, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
+
+ for (i = 0; i < cursor->image.height; i++) {
+ int j = (cursor->image.width + 7) >> 3;
+ int k = 8 - j;
+
+ WAIT_FIFO(par, 8);
+ for (; j > 0; j--) {
+ u8 data = *bitmap ^ *mask;
+
+ if (cursor->rop == ROP_COPY)
+ data = *mask & *bitmap;
+ /* bitmap data */
+ pm2_WR(par, PM2R_RD_CURSOR_DATA, data);
+ bitmap++;
+ mask++;
+ }
+ for (; k > 0; k--)
+ pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
+ }
+ for (; i < 64; i++) {
+ int j = 8;
+ WAIT_FIFO(par, 8);
+ while (j-- > 0)
+ pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
+ }
+
+ mask = (u8 *)cursor->mask;
+ for (i = 0; i < cursor->image.height; i++) {
+ int j = (cursor->image.width + 7) >> 3;
+ int k = 8 - j;
+
+ WAIT_FIFO(par, 8);
+ for (; j > 0; j--) {
+ /* mask */
+ pm2_WR(par, PM2R_RD_CURSOR_DATA, *mask);
+ mask++;
+ }
+ for (; k > 0; k--)
+ pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
+ }
+ for (; i < 64; i++) {
+ int j = 8;
+ WAIT_FIFO(par, 8);
+ while (j-- > 0)
+ pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
+ }
+ }
+ return 0;
}
/* ------------ Hardware Independent Functions ------------ */
@@ -1172,8 +1494,9 @@ static struct fb_ops pm2fb_ops = {
.fb_pan_display = pm2fb_pan_display,
.fb_fillrect = pm2fb_fillrect,
.fb_copyarea = pm2fb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_imageblit = pm2fb_imageblit,
.fb_sync = pm2fb_sync,
+ .fb_cursor = pm2fb_cursor,
};
/*
@@ -1194,16 +1517,17 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
{
struct pm2fb_par *default_par;
struct fb_info *info;
- int err, err_retval = -ENXIO;
+ int err;
+ int retval = -ENXIO;
err = pci_enable_device(pdev);
- if ( err ) {
+ if (err) {
printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err);
return err;
}
info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
- if ( !info )
+ if (!info)
return -ENOMEM;
default_par = info->par;
@@ -1236,14 +1560,14 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start);
/* Registers - request region and map it. */
- if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
- "pm2fb regbase") ) {
+ if (!request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
+ "pm2fb regbase")) {
printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n");
goto err_exit_neither;
}
default_par->v_regs =
ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
- if ( !default_par->v_regs ) {
+ if (!default_par->v_regs) {
printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n",
pm2fb_fix.id);
release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
@@ -1258,72 +1582,101 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
default_par->mem_control, default_par->boot_address,
default_par->mem_config);
- if(default_par->mem_control == 0 &&
+ if (default_par->mem_control == 0 &&
default_par->boot_address == 0x31 &&
default_par->mem_config == 0x259fffff) {
default_par->memclock = CVPPC_MEMCLOCK;
- default_par->mem_control=0;
- default_par->boot_address=0x20;
- default_par->mem_config=0xe6002021;
+ default_par->mem_control = 0;
+ default_par->boot_address = 0x20;
+ default_par->mem_config = 0xe6002021;
if (pdev->subsystem_vendor == 0x1048 &&
pdev->subsystem_device == 0x0a31) {
- DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ DPRINTK("subsystem_vendor: %04x, "
+ "subsystem_device: %04x\n",
pdev->subsystem_vendor, pdev->subsystem_device);
- DPRINTK("We have not been initialized by VGA BIOS "
- "and are running on an Elsa Winner 2000 Office\n");
+ DPRINTK("We have not been initialized by VGA BIOS and "
+ "are running on an Elsa Winner 2000 Office\n");
DPRINTK("Initializing card timings manually...\n");
- default_par->memclock=70000;
+ default_par->memclock = 100000;
}
if (pdev->subsystem_vendor == 0x3d3d &&
pdev->subsystem_device == 0x0100) {
- DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ DPRINTK("subsystem_vendor: %04x, "
+ "subsystem_device: %04x\n",
pdev->subsystem_vendor, pdev->subsystem_device);
- DPRINTK("We have not been initialized by VGA BIOS "
- "and are running on an 3dlabs reference board\n");
+ DPRINTK("We have not been initialized by VGA BIOS and "
+ "are running on an 3dlabs reference board\n");
DPRINTK("Initializing card timings manually...\n");
- default_par->memclock=74894;
+ default_par->memclock = 74894;
}
}
/* Now work out how big lfb is going to be. */
- switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
+ switch (default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
case PM2F_MEM_BANKS_1:
- pm2fb_fix.smem_len=0x200000;
+ pm2fb_fix.smem_len = 0x200000;
break;
case PM2F_MEM_BANKS_2:
- pm2fb_fix.smem_len=0x400000;
+ pm2fb_fix.smem_len = 0x400000;
break;
case PM2F_MEM_BANKS_3:
- pm2fb_fix.smem_len=0x600000;
+ pm2fb_fix.smem_len = 0x600000;
break;
case PM2F_MEM_BANKS_4:
- pm2fb_fix.smem_len=0x800000;
+ pm2fb_fix.smem_len = 0x800000;
break;
}
pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
/* Linear frame buffer - request region and map it. */
- if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
- "pm2fb smem") ) {
+ if (!request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
+ "pm2fb smem")) {
printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
goto err_exit_mmio;
}
info->screen_base =
ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
- if ( !info->screen_base ) {
+ if (!info->screen_base) {
printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
goto err_exit_mmio;
}
+#ifdef CONFIG_MTRR
+ default_par->mtrr_handle = -1;
+ if (!nomtrr)
+ default_par->mtrr_handle =
+ mtrr_add(pm2fb_fix.smem_start,
+ pm2fb_fix.smem_len,
+ MTRR_TYPE_WRCOMB, 1);
+#endif
+
info->fbops = &pm2fb_ops;
info->fix = pm2fb_fix;
info->pseudo_palette = default_par->palette;
info->flags = FBINFO_DEFAULT |
FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_IMAGEBLIT |
FBINFO_HWACCEL_FILLRECT;
+ info->pixmap.addr = kmalloc(PM2_PIXMAP_SIZE, GFP_KERNEL);
+ if (!info->pixmap.addr) {
+ retval = -ENOMEM;
+ goto err_exit_pixmap;
+ }
+ info->pixmap.size = PM2_PIXMAP_SIZE;
+ info->pixmap.buf_align = 4;
+ info->pixmap.scan_align = 4;
+ info->pixmap.access_align = 32;
+ info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
+ if (noaccel) {
+ printk(KERN_DEBUG "disabling acceleration\n");
+ info->flags |= FBINFO_HWACCEL_DISABLED;
+ info->pixmap.scan_align = 1;
+ }
+
if (!mode)
mode = "640x480@60";
@@ -1350,6 +1703,8 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
err_exit_all:
fb_dealloc_cmap(&info->cmap);
err_exit_both:
+ kfree(info->pixmap.addr);
+ err_exit_pixmap:
iounmap(info->screen_base);
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
err_exit_mmio:
@@ -1357,7 +1712,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
err_exit_neither:
framebuffer_release(info);
- return err_retval;
+ return retval;
}
/**
@@ -1369,34 +1724,34 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
*/
static void __devexit pm2fb_remove(struct pci_dev *pdev)
{
- struct fb_info* info = pci_get_drvdata(pdev);
- struct fb_fix_screeninfo* fix = &info->fix;
+ struct fb_info *info = pci_get_drvdata(pdev);
+ struct fb_fix_screeninfo *fix = &info->fix;
struct pm2fb_par *par = info->par;
unregister_framebuffer(info);
+#ifdef CONFIG_MTRR
+ if (par->mtrr_handle >= 0)
+ mtrr_del(par->mtrr_handle, info->fix.smem_start,
+ info->fix.smem_len);
+#endif /* CONFIG_MTRR */
iounmap(info->screen_base);
release_mem_region(fix->smem_start, fix->smem_len);
iounmap(par->v_regs);
release_mem_region(fix->mmio_start, fix->mmio_len);
pci_set_drvdata(pdev, NULL);
+ kfree(info->pixmap.addr);
kfree(info);
}
static struct pci_device_id pm2fb_id_table[] = {
{ PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
- { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
- PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8,
- 0xff00, 0 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};
@@ -1418,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
*/
static int __init pm2fb_setup(char *options)
{
- char* this_opt;
+ char *this_opt;
if (!options || !*options)
return 0;
@@ -1426,13 +1781,20 @@ static int __init pm2fb_setup(char *options)
while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt)
continue;
- if(!strcmp(this_opt, "lowhsync")) {
+ if (!strcmp(this_opt, "lowhsync"))
lowhsync = 1;
- } else if(!strcmp(this_opt, "lowvsync")) {
+ else if (!strcmp(this_opt, "lowvsync"))
lowvsync = 1;
- } else {
+ else if (!strncmp(this_opt, "hwcursor=", 9))
+ hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
+#ifdef CONFIG_MTRR
+ else if (!strncmp(this_opt, "nomtrr", 6))
+ nomtrr = 1;
+#endif
+ else if (!strncmp(this_opt, "noaccel", 7))
+ noaccel = 1;
+ else
mode = this_opt;
- }
}
return 0;
}
@@ -1474,6 +1836,15 @@ module_param(lowhsync, bool, 0);
MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode");
module_param(lowvsync, bool, 0);
MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode");
+module_param(noaccel, bool, 0);
+MODULE_PARM_DESC(noaccel, "Disable acceleration");
+module_param(hwcursor, int, 0644);
+MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
+ "(1=enable, 0=disable, default=1)");
+#ifdef CONFIG_MTRR
+module_param(nomtrr, bool, 0);
+MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
+#endif
MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
MODULE_DESCRIPTION("Permedia2 framebuffer device driver");
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 5b3f54c0918..070659992c1 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -32,6 +32,9 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
#include <video/pm3fb.h>
@@ -41,15 +44,25 @@
#undef PM3FB_MASTER_DEBUG
#ifdef PM3FB_MASTER_DEBUG
-#define DPRINTK(a,b...) printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b)
+#define DPRINTK(a, b...) \
+ printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b)
#else
-#define DPRINTK(a,b...)
+#define DPRINTK(a, b...)
#endif
+#define PM3_PIXMAP_SIZE (2048 * 4)
+
/*
* Driver data
*/
+static int hwcursor = 1;
static char *mode_option __devinitdata;
+static int noaccel __devinitdata;
+
+/* mtrr option */
+#ifdef CONFIG_MTRR
+static int nomtrr __devinitdata;
+#endif
/*
* This structure defines the hardware state of the graphics card. Normally
@@ -61,8 +74,9 @@ static char *mode_option __devinitdata;
struct pm3_par {
unsigned char __iomem *v_regs;/* virtual address of p_regs */
u32 video; /* video flags before blanking */
- u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */
+ u32 base; /* screen base in 128 bits unit */
u32 palette[16];
+ int mtrr_handle;
};
/*
@@ -96,7 +110,8 @@ static inline void PM3_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
static inline void PM3_WAIT(struct pm3_par *par, u32 n)
{
- while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
+ while (PM3_READ_REG(par, PM3InFIFOSpace) < n)
+ cpu_relax();
}
static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
@@ -133,7 +148,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
}
-/* Calculating various clock parameter */
+/* Calculating various clock parameters */
static void pm3fb_calculate_clock(unsigned long reqclock,
unsigned char *prescale,
unsigned char *feedback,
@@ -164,7 +179,7 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
{
- if ( var->bits_per_pixel == 16 )
+ if (var->bits_per_pixel == 16)
return var->red.length + var->green.length
+ var->blue.length;
@@ -195,8 +210,8 @@ static int pm3fb_sync(struct fb_info *info)
PM3_WRITE_REG(par, PM3Sync, 0);
mb();
do {
- while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0);
- rmb();
+ while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0)
+ cpu_relax();
} while ((PM3_READ_REG(par, PM3OutputFifo)) != PM3Sync_Tag);
return 0;
@@ -276,15 +291,22 @@ static void pm3fb_init_engine(struct fb_info *info)
PM3_WAIT(par, 2);
{
- unsigned long rm = 1;
+ /* invert bits in bitmask */
+ unsigned long rm = 1 | (3 << 7);
switch (info->var.bits_per_pixel) {
case 8:
PM3_WRITE_REG(par, PM3PixelSize,
PM3PixelSize_GLOBAL_8BIT);
+#ifdef __BIG_ENDIAN
+ rm |= 3 << 15;
+#endif
break;
case 16:
PM3_WRITE_REG(par, PM3PixelSize,
PM3PixelSize_GLOBAL_16BIT);
+#ifdef __BIG_ENDIAN
+ rm |= 2 << 15;
+#endif
break;
case 32:
PM3_WRITE_REG(par, PM3PixelSize,
@@ -342,7 +364,7 @@ static void pm3fb_init_engine(struct fb_info *info)
PM3_WRITE_REG(par, PM3dXDom, 0x0);
PM3_WRITE_REG(par, PM3dXSub, 0x0);
- PM3_WRITE_REG(par, PM3dY, (1 << 16));
+ PM3_WRITE_REG(par, PM3dY, 1 << 16);
PM3_WRITE_REG(par, PM3StartXDom, 0x0);
PM3_WRITE_REG(par, PM3StartXSub, 0x0);
PM3_WRITE_REG(par, PM3StartY, 0x0);
@@ -357,71 +379,350 @@ static void pm3fb_init_engine(struct fb_info *info)
pm3fb_sync(info);
}
-static void pm3fb_fillrect (struct fb_info *info,
+static void pm3fb_fillrect(struct fb_info *info,
const struct fb_fillrect *region)
{
struct pm3_par *par = info->par;
struct fb_fillrect modded;
int vxres, vyres;
+ int rop;
u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
- ((u32*)info->pseudo_palette)[region->color] : region->color;
+ ((u32 *)info->pseudo_palette)[region->color] : region->color;
if (info->state != FBINFO_STATE_RUNNING)
return;
- if ((info->flags & FBINFO_HWACCEL_DISABLED) ||
- region->rop != ROP_COPY ) {
+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
cfb_fillrect(info, region);
return;
}
+ if (region->rop == ROP_COPY )
+ rop = PM3Config2D_ForegroundROP(0x3); /* GXcopy */
+ else
+ rop = PM3Config2D_ForegroundROP(0x6) | /* GXxor */
+ PM3Config2D_FBDestReadEnable;
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
memcpy(&modded, region, sizeof(struct fb_fillrect));
- if(!modded.width || !modded.height ||
- modded.dx >= vxres || modded.dy >= vyres)
+ if (!modded.width || !modded.height ||
+ modded.dx >= vxres || modded.dy >= vyres)
return;
- if(modded.dx + modded.width > vxres)
+ if (modded.dx + modded.width > vxres)
modded.width = vxres - modded.dx;
- if(modded.dy + modded.height > vyres)
+ if (modded.dy + modded.height > vyres)
modded.height = vyres - modded.dy;
- if(info->var.bits_per_pixel == 8)
+ if (info->var.bits_per_pixel == 8)
color |= color << 8;
- if(info->var.bits_per_pixel <= 16)
+ if (info->var.bits_per_pixel <= 16)
color |= color << 16;
PM3_WAIT(par, 4);
-
+ /* ROP Ox3 is GXcopy */
PM3_WRITE_REG(par, PM3Config2D,
- PM3Config2D_UseConstantSource |
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
+ PM3Config2D_UseConstantSource |
+ PM3Config2D_ForegroundROPEnable |
+ rop |
+ PM3Config2D_FBWriteEnable);
PM3_WRITE_REG(par, PM3ForegroundColor, color);
PM3_WRITE_REG(par, PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(modded.dx)) |
- (PM3RectanglePosition_YOffset(modded.dy)));
+ PM3RectanglePosition_XOffset(modded.dx) |
+ PM3RectanglePosition_YOffset(modded.dy));
PM3_WRITE_REG(par, PM3Render2D,
PM3Render2D_XPositive |
PM3Render2D_YPositive |
PM3Render2D_Operation_Normal |
PM3Render2D_SpanOperation |
- (PM3Render2D_Width(modded.width)) |
- (PM3Render2D_Height(modded.height)));
+ PM3Render2D_Width(modded.width) |
+ PM3Render2D_Height(modded.height));
+}
+
+static void pm3fb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct pm3_par *par = info->par;
+ struct fb_copyarea modded;
+ u32 vxres, vyres;
+ int x_align, o_x, o_y;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
+ cfb_copyarea(info, area);
+ return;
+ }
+
+ memcpy(&modded, area, sizeof(struct fb_copyarea));
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ if (!modded.width || !modded.height ||
+ modded.sx >= vxres || modded.sy >= vyres ||
+ modded.dx >= vxres || modded.dy >= vyres)
+ return;
+
+ if (modded.sx + modded.width > vxres)
+ modded.width = vxres - modded.sx;
+ if (modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if (modded.sy + modded.height > vyres)
+ modded.height = vyres - modded.sy;
+ if (modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ o_x = modded.sx - modded.dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */
+ o_y = modded.sy - modded.dy; /*(sy > dy ) ? (sy - dy) : (dy - sy); */
+
+ x_align = (modded.sx & 0x1f);
+
+ PM3_WAIT(par, 6);
+
+ PM3_WRITE_REG(par, PM3Config2D,
+ PM3Config2D_UserScissorEnable |
+ PM3Config2D_ForegroundROPEnable |
+ PM3Config2D_Blocking |
+ PM3Config2D_ForegroundROP(0x3) | /* Ox3 is GXcopy */
+ PM3Config2D_FBWriteEnable);
+
+ PM3_WRITE_REG(par, PM3ScissorMinXY,
+ ((modded.dy & 0x0fff) << 16) | (modded.dx & 0x0fff));
+ PM3_WRITE_REG(par, PM3ScissorMaxXY,
+ (((modded.dy + modded.height) & 0x0fff) << 16) |
+ ((modded.dx + modded.width) & 0x0fff));
+
+ PM3_WRITE_REG(par, PM3FBSourceReadBufferOffset,
+ PM3FBSourceReadBufferOffset_XOffset(o_x) |
+ PM3FBSourceReadBufferOffset_YOffset(o_y));
+
+ PM3_WRITE_REG(par, PM3RectanglePosition,
+ PM3RectanglePosition_XOffset(modded.dx - x_align) |
+ PM3RectanglePosition_YOffset(modded.dy));
+
+ PM3_WRITE_REG(par, PM3Render2D,
+ ((modded.sx > modded.dx) ? PM3Render2D_XPositive : 0) |
+ ((modded.sy > modded.dy) ? PM3Render2D_YPositive : 0) |
+ PM3Render2D_Operation_Normal |
+ PM3Render2D_SpanOperation |
+ PM3Render2D_FBSourceReadEnable |
+ PM3Render2D_Width(modded.width + x_align) |
+ PM3Render2D_Height(modded.height));
+}
+
+static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct pm3_par *par = info->par;
+ u32 height = image->height;
+ u32 fgx, bgx;
+ const u32 *src = (const u32 *)image->data;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
+ cfb_imageblit(info, image);
+ return;
+ }
+ switch (info->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ fgx = image->fg_color;
+ bgx = image->bg_color;
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ default:
+ fgx = par->palette[image->fg_color];
+ bgx = par->palette[image->bg_color];
+ break;
+ }
+ if (image->depth != 1)
+ return cfb_imageblit(info, image);
+
+ if (info->var.bits_per_pixel == 8) {
+ fgx |= fgx << 8;
+ bgx |= bgx << 8;
+ }
+ if (info->var.bits_per_pixel <= 16) {
+ fgx |= fgx << 16;
+ bgx |= bgx << 16;
+ }
+
+ PM3_WAIT(par, 7);
+
+ PM3_WRITE_REG(par, PM3ForegroundColor, fgx);
+ PM3_WRITE_REG(par, PM3BackgroundColor, bgx);
+
+ /* ROP Ox3 is GXcopy */
+ PM3_WRITE_REG(par, PM3Config2D,
+ PM3Config2D_UserScissorEnable |
+ PM3Config2D_UseConstantSource |
+ PM3Config2D_ForegroundROPEnable |
+ PM3Config2D_ForegroundROP(0x3) |
+ PM3Config2D_OpaqueSpan |
+ PM3Config2D_FBWriteEnable);
+ PM3_WRITE_REG(par, PM3ScissorMinXY,
+ ((image->dy & 0x0fff) << 16) | (image->dx & 0x0fff));
+ PM3_WRITE_REG(par, PM3ScissorMaxXY,
+ (((image->dy + image->height) & 0x0fff) << 16) |
+ ((image->dx + image->width) & 0x0fff));
+ PM3_WRITE_REG(par, PM3RectanglePosition,
+ PM3RectanglePosition_XOffset(image->dx) |
+ PM3RectanglePosition_YOffset(image->dy));
+ PM3_WRITE_REG(par, PM3Render2D,
+ PM3Render2D_XPositive |
+ PM3Render2D_YPositive |
+ PM3Render2D_Operation_SyncOnBitMask |
+ PM3Render2D_SpanOperation |
+ PM3Render2D_Width(image->width) |
+ PM3Render2D_Height(image->height));
+
+
+ while (height--) {
+ int width = ((image->width + 7) >> 3)
+ + info->pixmap.scan_align - 1;
+ width >>= 2;
+
+ while (width >= PM3_FIFO_SIZE) {
+ int i = PM3_FIFO_SIZE - 1;
+
+ PM3_WAIT(par, PM3_FIFO_SIZE);
+ while (i--) {
+ PM3_WRITE_REG(par, PM3BitMaskPattern, *src);
+ src++;
+ }
+ width -= PM3_FIFO_SIZE - 1;
+ }
+
+ PM3_WAIT(par, width + 1);
+ while (width--) {
+ PM3_WRITE_REG(par, PM3BitMaskPattern, *src);
+ src++;
+ }
+ }
}
/* end of acceleration functions */
+/*
+ * Hardware Cursor support.
+ */
+static const u8 cursor_bits_lookup[16] = {
+ 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
+ 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
+};
+
+static int pm3fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ struct pm3_par *par = info->par;
+ u8 mode;
+
+ if (!hwcursor)
+ return -EINVAL; /* just to force soft_cursor() call */
+
+ /* Too large of a cursor or wrong bpp :-( */
+ if (cursor->image.width > 64 ||
+ cursor->image.height > 64 ||
+ cursor->image.depth > 1)
+ return -EINVAL;
+
+ mode = PM3RD_CursorMode_TYPE_X;
+ if (cursor->enable)
+ mode |= PM3RD_CursorMode_CURSOR_ENABLE;
+
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, mode);
+
+ /*
+ * If the cursor is not be changed this means either we want the
+ * current cursor state (if enable is set) or we want to query what
+ * we can do with the cursor (if enable is not set)
+ */
+ if (!cursor->set)
+ return 0;
+
+ if (cursor->set & FB_CUR_SETPOS) {
+ int x = cursor->image.dx - info->var.xoffset;
+ int y = cursor->image.dy - info->var.yoffset;
+
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorXLow, x & 0xff);
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorXHigh, (x >> 8) & 0xf);
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorYLow, y & 0xff);
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorYHigh, (y >> 8) & 0xf);
+ }
+
+ if (cursor->set & FB_CUR_SETHOT) {
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorHotSpotX,
+ cursor->hot.x & 0x3f);
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorHotSpotY,
+ cursor->hot.y & 0x3f);
+ }
+
+ if (cursor->set & FB_CUR_SETCMAP) {
+ u32 fg_idx = cursor->image.fg_color;
+ u32 bg_idx = cursor->image.bg_color;
+ struct fb_cmap cmap = info->cmap;
+
+ /* the X11 driver says one should use these color registers */
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(39),
+ cmap.red[fg_idx] >> 8 );
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(40),
+ cmap.green[fg_idx] >> 8 );
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(41),
+ cmap.blue[fg_idx] >> 8 );
+
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(42),
+ cmap.red[bg_idx] >> 8 );
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(43),
+ cmap.green[bg_idx] >> 8 );
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(44),
+ cmap.blue[bg_idx] >> 8 );
+ }
+
+ if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
+ u8 *bitmap = (u8 *)cursor->image.data;
+ u8 *mask = (u8 *)cursor->mask;
+ int i;
+ int pos = PM3RD_CursorPattern(0);
+
+ for (i = 0; i < cursor->image.height; i++) {
+ int j = (cursor->image.width + 7) >> 3;
+ int k = 8 - j;
+
+ for (; j > 0; j--) {
+ u8 data = *bitmap ^ *mask;
+
+ if (cursor->rop == ROP_COPY)
+ data = *mask & *bitmap;
+ /* Upper 4 bits of bitmap data */
+ PM3_WRITE_DAC_REG(par, pos++,
+ cursor_bits_lookup[data >> 4] |
+ (cursor_bits_lookup[*mask >> 4] << 1));
+ /* Lower 4 bits of bitmap */
+ PM3_WRITE_DAC_REG(par, pos++,
+ cursor_bits_lookup[data & 0xf] |
+ (cursor_bits_lookup[*mask & 0xf] << 1));
+ bitmap++;
+ mask++;
+ }
+ for (; k > 0; k--) {
+ PM3_WRITE_DAC_REG(par, pos++, 0);
+ PM3_WRITE_DAC_REG(par, pos++, 0);
+ }
+ }
+ while (pos < PM3RD_CursorPattern(1024))
+ PM3_WRITE_DAC_REG(par, pos++, 0);
+ }
+ return 0;
+}
+
/* write the mode to registers */
static void pm3fb_write_mode(struct fb_info *info)
{
struct pm3_par *par = info->par;
- char tempsync = 0x00, tempmisc = 0x00;
+ char tempsync = 0x00;
+ char tempmisc = 0x00;
const u32 hsstart = info->var.right_margin;
const u32 hsend = hsstart + info->var.hsync_len;
const u32 hbend = hsend + info->var.left_margin;
@@ -618,47 +919,57 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
unsigned bpp = var->red.length + var->green.length
+ var->blue.length + var->transp.length;
- if ( bpp != var->bits_per_pixel ) {
+ if (bpp != var->bits_per_pixel) {
/* set predefined mode for bits_per_pixel settings */
- switch(var->bits_per_pixel) {
+ switch (var->bits_per_pixel) {
case 8:
- var->red.length = var->green.length = var->blue.length = 8;
- var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 16:
- var->red.length = var->blue.length = 5;
+ var->red.length = 5;
+ var->blue.length = 5;
var->green.length = 6;
var->transp.length = 0;
break;
case 32:
- var->red.length = var->green.length = var->blue.length = 8;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
var->transp.length = 8;
break;
default:
- DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
+ DPRINTK("depth not supported: %u\n",
+ var->bits_per_pixel);
return -EINVAL;
}
}
/* it is assumed BGRA order */
- if (var->bits_per_pixel > 8 )
- {
+ if (var->bits_per_pixel > 8 ) {
var->blue.offset = 0;
var->green.offset = var->blue.length;
var->red.offset = var->green.offset + var->green.length;
var->transp.offset = var->red.offset + var->red.length;
}
- var->height = var->width = -1;
+ var->height = -1;
+ var->width = -1;
if (var->xres != var->xres_virtual) {
- DPRINTK("virtual x resolution != physical x resolution not supported\n");
+ DPRINTK("virtual x resolution != "
+ "physical x resolution not supported\n");
return -EINVAL;
}
if (var->yres > var->yres_virtual) {
- DPRINTK("virtual y resolution < physical y resolution not possible\n");
+ DPRINTK("virtual y resolution < "
+ "physical y resolution not possible\n");
return -EINVAL;
}
@@ -673,7 +984,7 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
var->xres = (var->xres + 31) & ~31; /* could sometimes be 8 */
- lpitch = var->xres * ((var->bits_per_pixel + 7)>>3);
+ lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
if (var->xres < 200 || var->xres > 2048) {
DPRINTK("width not supported: %u\n", var->xres);
@@ -692,7 +1003,8 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) {
- DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock));
+ DPRINTK("pixclock too high (%ldKHz)\n",
+ PICOS2KHZ(var->pixclock));
return -EINVAL;
}
@@ -709,7 +1021,7 @@ static int pm3fb_set_par(struct fb_info *info)
const u32 xres = (info->var.xres + 31) & ~31;
const unsigned bpp = info->var.bits_per_pixel;
- par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres)
+ par->base = pm3fb_shift_bpp(bpp, (info->var.yoffset * xres)
+ info->var.xoffset);
par->video = 0;
@@ -725,15 +1037,12 @@ static int pm3fb_set_par(struct fb_info *info)
if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
par->video |= PM3VideoControl_LINE_DOUBLE_ON;
- else
- par->video |= PM3VideoControl_LINE_DOUBLE_OFF;
if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
par->video |= PM3VideoControl_ENABLE;
- else {
- par->video |= PM3VideoControl_DISABLE;
+ else
DPRINTK("PM3Video disabled\n");
- }
+
switch (bpp) {
case 8:
par->video |= PM3VideoControl_PIXELSIZE_8BIT;
@@ -751,13 +1060,11 @@ static int pm3fb_set_par(struct fb_info *info)
info->fix.visual =
(bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- info->fix.line_length = ((info->var.xres_virtual + 7) & ~7)
- * bpp / 8;
+ info->fix.line_length = ((info->var.xres_virtual + 7) >> 3) * bpp;
/* pm3fb_clear_memory(info, 0);*/
pm3fb_clear_colormap(par, 0, 0, 0);
- PM3_WRITE_DAC_REG(par, PM3RD_CursorMode,
- PM3RD_CursorMode_CURSOR_DISABLE);
+ PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, 0);
pm3fb_init_engine(info);
pm3fb_write_mode(info);
return 0;
@@ -773,10 +1080,9 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
return -EINVAL;
/* grayscale works only partially under directcolor */
- if (info->var.grayscale) {
- /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ if (info->var.grayscale)
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
- }
/* Directcolor:
* var->{color}.offset contains start of bitfield
@@ -790,8 +1096,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
*
* Pseudocolor:
* var->{color}.offset is 0
- * var->{color}.length contains width of DAC or the number of unique
- * colors available (color depth)
+ * var->{color}.length contains width of DAC or the number
+ * of unique colors available (color depth)
* pseudo_palette is not used
* RAMDAC[X] is programmed to (red, green, blue)
* color depth = var->{color}.length
@@ -801,7 +1107,7 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
* This is the point where the color is converted to something that
* is acceptable by the hardware.
*/
-#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
red = CNVT_TOHW(red, info->var.red.length);
green = CNVT_TOHW(green, info->var.green.length);
blue = CNVT_TOHW(blue, info->var.blue.length);
@@ -825,12 +1131,11 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
break;
case 16:
case 32:
- ((u32*)(info->pseudo_palette))[regno] = v;
+ ((u32 *)(info->pseudo_palette))[regno] = v;
break;
}
return 0;
- }
- else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
+ } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
pm3fb_set_color(par, regno, red, green, blue);
return 0;
@@ -871,7 +1176,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
video |= PM3VideoControl_ENABLE;
break;
case FB_BLANK_NORMAL:
- video &= ~(PM3VideoControl_ENABLE);
+ video &= ~PM3VideoControl_ENABLE;
break;
case FB_BLANK_HSYNC_SUSPEND:
video &= ~(PM3VideoControl_HSYNC_MASK |
@@ -892,7 +1197,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
}
PM3_WAIT(par, 1);
- PM3_WRITE_REG(par,PM3VideoControl, video);
+ PM3_WRITE_REG(par, PM3VideoControl, video);
return 0;
}
@@ -907,10 +1212,11 @@ static struct fb_ops pm3fb_ops = {
.fb_setcolreg = pm3fb_setcolreg,
.fb_pan_display = pm3fb_pan_display,
.fb_fillrect = pm3fb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_copyarea = pm3fb_copyarea,
+ .fb_imageblit = pm3fb_imageblit,
.fb_blank = pm3fb_blank,
.fb_sync = pm3fb_sync,
+ .fb_cursor = pm3fb_cursor,
};
/* ------------------------------------------------------------------------- */
@@ -923,7 +1229,8 @@ static struct fb_ops pm3fb_ops = {
/* the pm3fb_fix.smem_start is also set */
static unsigned long pm3fb_size_memory(struct pm3_par *par)
{
- unsigned long memsize = 0, tempBypass, i, temp1, temp2;
+ unsigned long memsize = 0;
+ unsigned long tempBypass, i, temp1, temp2;
unsigned char __iomem *screen_mem;
pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
@@ -951,7 +1258,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
PM3_WAIT(par, 1);
PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
- /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
+ /* pm3 split up memory, replicates, and do a lot of
+ * nasty stuff IMHO ;-)
+ */
for (i = 0; i < 32; i++) {
fb_writel(i * 0x00345678,
(screen_mem + (i * 1048576)));
@@ -1008,8 +1317,9 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
{
struct fb_info *info;
struct pm3_par *par;
- struct device* device = &dev->dev; /* for pci drivers */
- int err, retval = -ENXIO;
+ struct device *device = &dev->dev; /* for pci drivers */
+ int err;
+ int retval = -ENXIO;
err = pci_enable_device(dev);
if (err) {
@@ -1031,6 +1341,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
*/
pm3fb_fix.mmio_start = pci_resource_start(dev, 0);
pm3fb_fix.mmio_len = PM3_REGS_SIZE;
+#if defined(__BIG_ENDIAN)
+ pm3fb_fix.mmio_start += PM3_REGS_SIZE;
+ DPRINTK("Adjusting register base for big-endian.\n");
+#endif
/* Registers - request region and map it. */
if (!request_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len,
@@ -1047,15 +1361,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
goto err_exit_neither;
}
-#if defined(__BIG_ENDIAN)
- pm3fb_fix.mmio_start += PM3_REGS_SIZE;
- DPRINTK("Adjusting register base for big-endian.\n");
-#endif
/* Linear frame buffer - request region and map it. */
pm3fb_fix.smem_start = pci_resource_start(dev, 1);
pm3fb_fix.smem_len = pm3fb_size_memory(par);
- if (!pm3fb_fix.smem_len)
- {
+ if (!pm3fb_fix.smem_len) {
printk(KERN_WARNING "pm3fb: Can't find memory on board.\n");
goto err_exit_mmio;
}
@@ -1073,6 +1382,12 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
}
info->screen_size = pm3fb_fix.smem_len;
+#ifdef CONFIG_MTRR
+ if (!nomtrr)
+ par->mtrr_handle = mtrr_add(pm3fb_fix.smem_start,
+ pm3fb_fix.smem_len,
+ MTRR_TYPE_WRCOMB, 1);
+#endif
info->fbops = &pm3fb_ops;
par->video = PM3_READ_REG(par, PM3VideoControl);
@@ -1080,7 +1395,26 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
info->fix = pm3fb_fix;
info->pseudo_palette = par->palette;
info->flags = FBINFO_DEFAULT |
- FBINFO_HWACCEL_FILLRECT;/* | FBINFO_HWACCEL_YPAN;*/
+ FBINFO_HWACCEL_XPAN |
+ FBINFO_HWACCEL_YPAN |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_IMAGEBLIT |
+ FBINFO_HWACCEL_FILLRECT;
+
+ if (noaccel) {
+ printk(KERN_DEBUG "disabling acceleration\n");
+ info->flags |= FBINFO_HWACCEL_DISABLED;
+ }
+ info->pixmap.addr = kmalloc(PM3_PIXMAP_SIZE, GFP_KERNEL);
+ if (!info->pixmap.addr) {
+ retval = -ENOMEM;
+ goto err_exit_pixmap;
+ }
+ info->pixmap.size = PM3_PIXMAP_SIZE;
+ info->pixmap.buf_align = 4;
+ info->pixmap.scan_align = 4;
+ info->pixmap.access_align = 32;
+ info->pixmap.flags = FB_PIXMAP_SYSTEM;
/*
* This should give a reasonable default video mode. The following is
@@ -1118,6 +1452,8 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
err_exit_all:
fb_dealloc_cmap(&info->cmap);
err_exit_both:
+ kfree(info->pixmap.addr);
+ err_exit_pixmap:
iounmap(info->screen_base);
release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
err_exit_mmio:
@@ -1142,12 +1478,18 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
+#ifdef CONFIG_MTRR
+ if (par->mtrr_handle >= 0)
+ mtrr_del(par->mtrr_handle, info->fix.smem_start,
+ info->fix.smem_len);
+#endif /* CONFIG_MTRR */
iounmap(info->screen_base);
release_mem_region(fix->smem_start, fix->smem_len);
iounmap(par->v_regs);
release_mem_region(fix->mmio_start, fix->mmio_len);
pci_set_drvdata(dev, NULL);
+ kfree(info->pixmap.addr);
framebuffer_release(info);
}
}
@@ -1168,21 +1510,76 @@ static struct pci_driver pm3fb_driver = {
MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
+#ifndef MODULE
+ /*
+ * Setup
+ */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+static int __init pm3fb_setup(char *options)
+{
+ char *this_opt;
+
+ /* Parse user speficied options (`video=pm3fb:') */
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+ else if (!strncmp(this_opt, "noaccel", 7))
+ noaccel = 1;
+ else if (!strncmp(this_opt, "hwcursor=", 9))
+ hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
+#ifdef CONFIG_MTRR
+ else if (!strncmp(this_opt, "nomtrr", 6))
+ nomtrr = 1;
+#endif
+ else
+ mode_option = this_opt;
+ }
+ return 0;
+}
+#endif /* MODULE */
+
static int __init pm3fb_init(void)
{
+ /*
+ * For kernel boot options (in 'video=pm3fb:<options>' format)
+ */
#ifndef MODULE
- if (fb_get_options("pm3fb", NULL))
+ char *option = NULL;
+
+ if (fb_get_options("pm3fb", &option))
return -ENODEV;
+ pm3fb_setup(option);
#endif
+
return pci_register_driver(&pm3fb_driver);
}
+#ifdef MODULE
static void __exit pm3fb_exit(void)
{
pci_unregister_driver(&pm3fb_driver);
}
-module_init(pm3fb_init);
module_exit(pm3fb_exit);
+#endif
+module_init(pm3fb_init);
+
+module_param(noaccel, bool, 0);
+MODULE_PARM_DESC(noaccel, "Disable acceleration");
+module_param(hwcursor, int, 0644);
+MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
+ "(1=enable, 0=disable, default=1)");
+#ifdef CONFIG_MTRR
+module_param(nomtrr, bool, 0);
+MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
+#endif
+MODULE_DESCRIPTION("Permedia3 framebuffer device driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 264d37243fa..3a3f80f6521 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -147,16 +147,23 @@ static int __init pmagbafb_probe(struct device *dev)
resource_size_t start, len;
struct fb_info *info;
struct pmagbafb_par *par;
+ int err;
info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
- if (!info)
+ if (!info) {
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
return -ENOMEM;
+ }
par = info->par;
dev_set_drvdata(dev, info);
- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ printk(KERN_ERR "%s: Cannot allocate color map\n",
+ dev->bus_id);
+ err = -ENOMEM;
goto err_alloc;
+ }
info->fbops = &pmagbafb_ops;
info->fix = pmagbafb_fix;
@@ -166,28 +173,41 @@ static int __init pmagbafb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id))
+ if (!request_mem_region(start, len, dev->bus_id)) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ err = -EBUSY;
goto err_cmap;
+ }
/* MMIO mapping setup. */
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
- if (!par->mmio)
+ if (!par->mmio) {
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ err = -ENOMEM;
goto err_resource;
+ }
par->dac = par->mmio + PMAG_BA_BT459;
/* Frame buffer mapping setup. */
info->fix.smem_start = start + PMAG_BA_FBMEM;
info->screen_base = ioremap_nocache(info->fix.smem_start,
info->fix.smem_len);
- if (!info->screen_base)
+ if (!info->screen_base) {
+ printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ err = -ENOMEM;
goto err_mmio_map;
+ }
info->screen_size = info->fix.smem_len;
pmagbafb_erase_cursor(info);
- if (register_framebuffer(info) < 0)
+ err = register_framebuffer(info);
+ if (err < 0) {
+ printk(KERN_ERR "%s: Cannot register framebuffer\n",
+ dev->bus_id);
goto err_smem_map;
+ }
get_device(dev);
@@ -211,7 +231,7 @@ err_cmap:
err_alloc:
framebuffer_release(info);
- return -ENXIO;
+ return err;
}
static int __exit pmagbafb_remove(struct device *dev)
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 7a0ce7d5af6..9b80597241b 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -254,16 +254,23 @@ static int __init pmagbbfb_probe(struct device *dev)
struct pmagbbfb_par *par;
char freq0[12], freq1[12];
u32 vid_base;
+ int err;
info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
- if (!info)
+ if (!info) {
+ printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
return -ENOMEM;
+ }
par = info->par;
dev_set_drvdata(dev, info);
- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ printk(KERN_ERR "%s: Cannot allocate color map\n",
+ dev->bus_id);
+ err = -ENOMEM;
goto err_alloc;
+ }
info->fbops = &pmagbbfb_ops;
info->fix = pmagbbfb_fix;
@@ -273,22 +280,31 @@ static int __init pmagbbfb_probe(struct device *dev)
/* Request the I/O MEM resource. */
start = tdev->resource.start;
len = tdev->resource.end - start + 1;
- if (!request_mem_region(start, len, dev->bus_id))
+ if (!request_mem_region(start, len, dev->bus_id)) {
+ printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
+ err = -EBUSY;
goto err_cmap;
+ }
/* MMIO mapping setup. */
info->fix.mmio_start = start;
par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
- if (!par->mmio)
+ if (!par->mmio) {
+ printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
+ err = -ENOMEM;
goto err_resource;
+ }
par->sfb = par->mmio + PMAGB_B_SFB;
par->dac = par->mmio + PMAGB_B_BT459;
/* Frame buffer mapping setup. */
info->fix.smem_start = start + PMAGB_B_FBMEM;
par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
- if (!par->smem)
+ if (!par->smem) {
+ printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
+ err = -ENOMEM;
goto err_mmio_map;
+ }
vid_base = sfb_read(par, SFB_REG_VID_BASE);
info->screen_base = (void __iomem *)par->smem + vid_base * 0x1000;
info->screen_size = info->fix.smem_len - 2 * vid_base * 0x1000;
@@ -297,8 +313,12 @@ static int __init pmagbbfb_probe(struct device *dev)
pmagbbfb_screen_setup(info);
pmagbbfb_osc_setup(info);
- if (register_framebuffer(info) < 0)
+ err = register_framebuffer(info);
+ if (err < 0) {
+ printk(KERN_ERR "%s: Cannot register framebuffer\n",
+ dev->bus_id);
goto err_smem_map;
+ }
get_device(dev);
@@ -330,7 +350,7 @@ err_cmap:
err_alloc:
framebuffer_release(info);
- return -ENXIO;
+ return err;
}
static int __exit pmagbbfb_remove(struct device *dev)
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index f29e66e2d77..685761a0732 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -26,7 +26,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <asm/uaccess.h>
#include "sdum.h"
#include "fbcommon.h"
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 646ec823c16..b3463ddcfd6 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -22,22 +22,14 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/console.h>
#include <linux/ioctl.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
-#include <asm/time.h>
#include <asm/abs_addr.h>
#include <asm/lv1call.h>
@@ -48,12 +40,6 @@
#define DEVICE_NAME "ps3fb"
-#ifdef PS3FB_DEBUG
-#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
@@ -66,8 +52,10 @@
#define L1GPU_DISPLAY_SYNC_VSYNC 2
#define DDR_SIZE (0) /* used no ddr */
-#define GPU_OFFSET (64 * 1024)
+#define GPU_CMD_BUF_SIZE (64 * 1024)
#define GPU_IOIF (0x0d000000UL)
+#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
+#define GPU_MAX_LINE_LENGTH (65536 - 64)
#define PS3FB_FULL_MODE_BIT 0x80
@@ -131,13 +119,12 @@ struct ps3fb_priv {
u64 context_handle, memory_handle;
void *xdr_ea;
+ size_t xdr_size;
struct gpu_driver_info *dinfo;
- u32 res_index;
u64 vblank_count; /* frame count */
wait_queue_head_t wait_vsync;
- u32 num_frames; /* num of frame buffers */
atomic_t ext_flip; /* on/off flip with vsync */
atomic_t f_count; /* fb_open count */
int is_blanked;
@@ -146,6 +133,18 @@ struct ps3fb_priv {
};
static struct ps3fb_priv ps3fb;
+struct ps3fb_par {
+ u32 pseudo_palette[16];
+ int mode_id, new_mode_id;
+ int res_index;
+ unsigned int num_frames; /* num of frame buffers */
+ unsigned int width;
+ unsigned int height;
+ unsigned long full_offset; /* start of fullscreen DDR fb */
+ unsigned long fb_offset; /* start of actual DDR fb */
+ unsigned long pan_offset;
+};
+
struct ps3fb_res_table {
u32 xres;
u32 yres;
@@ -294,29 +293,31 @@ static const struct fb_videomode ps3fb_modedb[] = {
#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */
#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */
#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */
-#define BPP 4 /* number of bytes per pixel */
-#define VP_OFF(i) (WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP)
-#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
+#define BPP 4 /* number of bytes per pixel */
+
+/* Start of the virtual frame buffer (relative to fullscreen ) */
+#define VP_OFF(i) ((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
+
static int ps3fb_mode;
module_param(ps3fb_mode, int, 0);
static char *mode_option __devinitdata;
-static int ps3fb_get_res_table(u32 xres, u32 yres)
+static int ps3fb_get_res_table(u32 xres, u32 yres, int mode)
{
int full_mode;
unsigned int i;
u32 x, y, f;
- full_mode = (ps3fb_mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0;
+ full_mode = (mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0;
for (i = 0;; i++) {
x = ps3fb_res[i].xres;
y = ps3fb_res[i].yres;
f = ps3fb_res[i].type;
if (!x) {
- DPRINTK("ERROR: ps3fb_get_res_table()\n");
+ pr_debug("ERROR: ps3fb_get_res_table()\n");
return -1;
}
@@ -335,7 +336,7 @@ static int ps3fb_get_res_table(u32 xres, u32 yres)
}
static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
- u32 *line_length)
+ u32 *ddr_line_length, u32 *xdr_line_length)
{
unsigned int i, mode;
@@ -350,31 +351,41 @@ static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
var->upper_margin == ps3fb_modedb[i].upper_margin &&
var->lower_margin == ps3fb_modedb[i].lower_margin &&
var->sync == ps3fb_modedb[i].sync &&
- (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) {
- /* Cropped broadcast modes use the full line_length */
- *line_length =
- ps3fb_modedb[i < 10 ? i + 13 : i].xres * 4;
- /* Full broadcast modes have the full mode bit set */
- mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
-
- DPRINTK("ps3fb_find_mode: mode %u\n", mode);
- return mode;
- }
+ (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode)
+ goto found;
- DPRINTK("ps3fb_find_mode: mode not found\n");
+ pr_debug("ps3fb_find_mode: mode not found\n");
return 0;
+found:
+ /* Cropped broadcast modes use the full line length */
+ *ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP;
+
+ if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
+ *xdr_line_length = GPU_ALIGN_UP(max(var->xres,
+ var->xres_virtual) * BPP);
+ if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
+ *xdr_line_length = GPU_MAX_LINE_LENGTH;
+ } else
+ *xdr_line_length = *ddr_line_length;
+
+ /* Full broadcast modes have the full mode bit set */
+ mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
+
+ pr_debug("ps3fb_find_mode: mode %u\n", mode);
+
+ return mode;
}
-static const struct fb_videomode *ps3fb_default_mode(void)
+static const struct fb_videomode *ps3fb_default_mode(int id)
{
- u32 mode = ps3fb_mode & PS3AV_MODE_MASK;
+ u32 mode = id & PS3AV_MODE_MASK;
u32 flags;
if (mode < 1 || mode > 13)
return NULL;
- flags = ps3fb_mode & ~PS3AV_MODE_MASK;
+ flags = id & ~PS3AV_MODE_MASK;
if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) {
/* Full broadcast mode */
@@ -384,55 +395,77 @@ static const struct fb_videomode *ps3fb_default_mode(void)
return &ps3fb_modedb[mode - 1];
}
-static int ps3fb_sync(u32 frame)
+static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
+ u64 dst_offset, u64 src_offset, u32 width,
+ u32 height, u32 dst_line_length,
+ u32 src_line_length)
{
- int i, status;
- u32 xres, yres;
- u64 fb_ioif, offset;
-
- i = ps3fb.res_index;
- xres = ps3fb_res[i].xres;
- yres = ps3fb_res[i].yres;
+ int status;
+ u64 line_length;
- if (frame > ps3fb.num_frames - 1) {
- printk(KERN_WARNING "%s: invalid frame number (%u)\n",
- __func__, frame);
- return -EINVAL;
- }
- offset = xres * yres * BPP * frame;
+ line_length = dst_line_length;
+ if (src_line_length != dst_line_length)
+ line_length |= (u64)src_line_length << 32;
- fb_ioif = GPU_IOIF + FB_OFF(i) + offset;
status = lv1_gpu_context_attribute(ps3fb.context_handle,
L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
- offset, fb_ioif,
+ dst_offset, GPU_IOIF + src_offset,
L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
- (xres << 16) | yres,
- xres * BPP); /* line_length */
+ (width << 16) | height,
+ line_length);
if (status)
- printk(KERN_ERR
- "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
- __func__, status);
+ dev_err(dev,
+ "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
+ __func__, status);
#ifdef HEAD_A
status = lv1_gpu_context_attribute(ps3fb.context_handle,
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
- 0, offset, 0, 0);
+ 0, frame_offset, 0, 0);
if (status)
- printk(KERN_ERR
- "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
- __func__, status);
+ dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+ __func__, status);
#endif
#ifdef HEAD_B
status = lv1_gpu_context_attribute(ps3fb.context_handle,
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
- 1, offset, 0, 0);
+ 1, frame_offset, 0, 0);
if (status)
- printk(KERN_ERR
- "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
- __func__, status);
+ dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+ __func__, status);
#endif
- return 0;
}
+static int ps3fb_sync(struct fb_info *info, u32 frame)
+{
+ struct ps3fb_par *par = info->par;
+ int i, error = 0;
+ u32 ddr_line_length, xdr_line_length;
+ u64 ddr_base, xdr_base;
+
+ acquire_console_sem();
+
+ if (frame > par->num_frames - 1) {
+ dev_dbg(info->device, "%s: invalid frame number (%u)\n",
+ __func__, frame);
+ error = -EINVAL;
+ goto out;
+ }
+
+ i = par->res_index;
+ xdr_line_length = info->fix.line_length;
+ ddr_line_length = ps3fb_res[i].xres * BPP;
+ xdr_base = frame * info->var.yres_virtual * xdr_line_length;
+ ddr_base = frame * ps3fb_res[i].yres * ddr_line_length;
+
+ ps3fb_sync_image(info->device, ddr_base + par->full_offset,
+ ddr_base + par->fb_offset, xdr_base + par->pan_offset,
+ par->width, par->height, ddr_line_length,
+ xdr_line_length);
+
+out:
+ release_console_sem();
+ return error;
+}
static int ps3fb_open(struct fb_info *info, int user)
{
@@ -445,7 +478,7 @@ static int ps3fb_release(struct fb_info *info, int user)
if (atomic_dec_and_test(&ps3fb.f_count)) {
if (atomic_read(&ps3fb.ext_flip)) {
atomic_set(&ps3fb.ext_flip, 0);
- ps3fb_sync(0); /* single buffer */
+ ps3fb_sync(info, 0); /* single buffer */
}
}
return 0;
@@ -461,39 +494,37 @@ static int ps3fb_release(struct fb_info *info, int user)
static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- u32 line_length;
+ u32 xdr_line_length, ddr_line_length;
int mode;
- int i;
- DPRINTK("var->xres:%u info->var.xres:%u\n", var->xres, info->var.xres);
- DPRINTK("var->yres:%u info->var.yres:%u\n", var->yres, info->var.yres);
+ dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
+ info->var.xres);
+ dev_dbg(info->device, "var->yres:%u info->var.yres:%u\n", var->yres,
+ info->var.yres);
/* FIXME For now we do exact matches only */
- mode = ps3fb_find_mode(var, &line_length);
+ mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
if (!mode)
return -EINVAL;
- /*
- * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
- * as FB_VMODE_SMOOTH_XPAN is only used internally
- */
+ /* Virtual screen */
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
- if (var->vmode & FB_VMODE_CONUPDATE) {
- var->vmode |= FB_VMODE_YWRAP;
- var->xoffset = info->var.xoffset;
- var->yoffset = info->var.yoffset;
+ if (var->xres_virtual > xdr_line_length / BPP) {
+ dev_dbg(info->device,
+ "Horizontal virtual screen size too large\n");
+ return -EINVAL;
}
- /* Virtual screen and panning are not supported */
- if (var->xres_virtual > var->xres || var->yres_virtual > var->yres ||
- var->xoffset || var->yoffset) {
- DPRINTK("Virtual screen and panning are not supported\n");
+ if (var->xoffset + var->xres > var->xres_virtual ||
+ var->yoffset + var->yres > var->yres_virtual) {
+ dev_dbg(info->device, "panning out-of-range\n");
return -EINVAL;
}
- var->xres_virtual = var->xres;
- var->yres_virtual = var->yres;
-
/* We support ARGB8888 only */
if (var->bits_per_pixel > 32 || var->grayscale ||
var->red.offset > 16 || var->green.offset > 8 ||
@@ -502,7 +533,7 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->blue.length > 8 || var->transp.length > 8 ||
var->red.msb_right || var->green.msb_right ||
var->blue.msb_right || var->transp.msb_right || var->nonstd) {
- DPRINTK("We support ARGB8888 only\n");
+ dev_dbg(info->device, "We support ARGB8888 only\n");
return -EINVAL;
}
@@ -522,14 +553,13 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
/* Rotation is not supported */
if (var->rotate) {
- DPRINTK("Rotation is not supported\n");
+ dev_dbg(info->device, "Rotation is not supported\n");
return -EINVAL;
}
/* Memory limit */
- i = ps3fb_get_res_table(var->xres, var->yres);
- if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP > ps3fb_videomemory.size) {
- DPRINTK("Not enough memory\n");
+ if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) {
+ dev_dbg(info->device, "Not enough memory\n");
return -ENOMEM;
}
@@ -545,36 +575,69 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
static int ps3fb_set_par(struct fb_info *info)
{
- unsigned int mode;
+ struct ps3fb_par *par = info->par;
+ unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
int i;
unsigned long offset;
- static int first = 1;
+ u64 dst;
- DPRINTK("xres:%d xv:%d yres:%d yv:%d clock:%d\n",
+ dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
info->var.xres, info->var.xres_virtual,
info->var.yres, info->var.yres_virtual, info->var.pixclock);
- i = ps3fb_get_res_table(info->var.xres, info->var.yres);
- ps3fb.res_index = i;
- mode = ps3fb_find_mode(&info->var, &info->fix.line_length);
+ mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
if (!mode)
return -EINVAL;
- offset = FB_OFF(i) + VP_OFF(i);
- info->fix.smem_len = ps3fb_videomemory.size - offset;
- info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
- memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
+ i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
+ par->res_index = i;
+
+ info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
+ info->fix.smem_len = ps3fb.xdr_size;
+ info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
+ info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
+ info->fix.line_length = xdr_line_length;
+
+ info->screen_base = (char __iomem *)ps3fb.xdr_ea;
- ps3fb.num_frames = ps3fb_videomemory.size/
- (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
+ par->num_frames = ps3fb.xdr_size /
+ max(ps3fb_res[i].yres * ddr_line_length,
+ info->var.yres_virtual * xdr_line_length);
/* Keep the special bits we cannot set using fb_var_screeninfo */
- ps3fb_mode = (ps3fb_mode & ~PS3AV_MODE_MASK) | mode;
+ par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
+
+ par->width = info->var.xres;
+ par->height = info->var.yres;
+ offset = VP_OFF(i);
+ par->fb_offset = GPU_ALIGN_UP(offset);
+ par->full_offset = par->fb_offset - offset;
+ par->pan_offset = info->var.yoffset * xdr_line_length +
+ info->var.xoffset * BPP;
+
+ if (par->new_mode_id != par->mode_id) {
+ if (ps3av_set_video_mode(par->new_mode_id)) {
+ par->new_mode_id = par->mode_id;
+ return -EINVAL;
+ }
+ par->mode_id = par->new_mode_id;
+ }
- if (ps3av_set_video_mode(ps3fb_mode, first))
- return -EINVAL;
+ /* Clear XDR frame buffer memory */
+ memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
+
+ /* Clear DDR frame buffer memory */
+ lines = ps3fb_res[i].yres * par->num_frames;
+ if (par->full_offset)
+ lines++;
+ maxlines = ps3fb.xdr_size / ddr_line_length;
+ for (dst = 0; lines; dst += maxlines * ddr_line_length) {
+ unsigned int l = min(lines, maxlines);
+ ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
+ ddr_line_length, ddr_line_length);
+ lines -= l;
+ }
- first = 0;
return 0;
}
@@ -601,6 +664,16 @@ static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
return 0;
}
+static int ps3fb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct ps3fb_par *par = info->par;
+
+ par->pan_offset = var->yoffset * info->fix.line_length +
+ var->xoffset * BPP;
+ return 0;
+}
+
/*
* As we have a virtual frame buffer, we need our own mmap function
*/
@@ -608,24 +681,19 @@ static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
unsigned long size, offset;
- int i;
-
- i = ps3fb_get_res_table(info->var.xres, info->var.yres);
- if (i == -1)
- return -EINVAL;
size = vma->vm_end - vma->vm_start;
offset = vma->vm_pgoff << PAGE_SHIFT;
if (offset + size > info->fix.smem_len)
return -EINVAL;
- offset += info->fix.smem_start + FB_OFF(i) + VP_OFF(i);
+ offset += info->fix.smem_start;
if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
size, vma->vm_page_prot))
return -EAGAIN;
- printk(KERN_DEBUG "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", offset,
- vma->vm_start);
+ dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
+ offset, vma->vm_start);
return 0;
}
@@ -637,7 +705,7 @@ static int ps3fb_blank(int blank, struct fb_info *info)
{
int retval;
- DPRINTK("%s: blank:%d\n", __func__, blank);
+ dev_dbg(info->device, "%s: blank:%d\n", __func__, blank);
switch (blank) {
case FB_BLANK_POWERDOWN:
case FB_BLANK_HSYNC_SUSPEND:
@@ -664,7 +732,7 @@ static int ps3fb_get_vblank(struct fb_vblank *vblank)
return 0;
}
-int ps3fb_wait_for_vsync(u32 crtc)
+static int ps3fb_wait_for_vsync(u32 crtc)
{
int ret;
u64 count;
@@ -679,9 +747,7 @@ int ps3fb_wait_for_vsync(u32 crtc)
return 0;
}
-EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
-
-void ps3fb_flip_ctl(int on, void *data)
+static void ps3fb_flip_ctl(int on, void *data)
{
struct ps3fb_priv *priv = data;
if (on)
@@ -699,14 +765,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
void __user *argp = (void __user *)arg;
- u32 val, old_mode;
+ u32 val;
int retval = -EFAULT;
switch (cmd) {
case FBIOGET_VBLANK:
{
struct fb_vblank vblank;
- DPRINTK("FBIOGET_VBLANK:\n");
+ dev_dbg(info->device, "FBIOGET_VBLANK:\n");
retval = ps3fb_get_vblank(&vblank);
if (retval)
break;
@@ -719,7 +785,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
case FBIO_WAITFORVSYNC:
{
u32 crt;
- DPRINTK("FBIO_WAITFORVSYNC:\n");
+ dev_dbg(info->device, "FBIO_WAITFORVSYNC:\n");
if (get_user(crt, (u32 __user *) arg))
break;
@@ -729,6 +795,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
case PS3FB_IOCTL_SETMODE:
{
+ struct ps3fb_par *par = info->par;
const struct fb_videomode *mode;
struct fb_var_screeninfo var;
@@ -736,15 +803,13 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
break;
if (!(val & PS3AV_MODE_MASK)) {
- u32 id = ps3av_get_auto_mode(0);
+ u32 id = ps3av_get_auto_mode();
if (id > 0)
val = (val & ~PS3AV_MODE_MASK) | id;
}
- DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val);
+ dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
retval = -EINVAL;
- old_mode = ps3fb_mode;
- ps3fb_mode = val;
- mode = ps3fb_default_mode();
+ mode = ps3fb_default_mode(val);
if (mode) {
var = info->var;
fb_videomode_to_var(&var, mode);
@@ -752,45 +817,44 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
info->flags |= FBINFO_MISC_USEREVENT;
/* Force, in case only special bits changed */
var.activate |= FB_ACTIVATE_FORCE;
+ par->new_mode_id = val;
retval = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
}
- if (retval)
- ps3fb_mode = old_mode;
break;
}
case PS3FB_IOCTL_GETMODE:
val = ps3av_get_mode();
- DPRINTK("PS3FB_IOCTL_GETMODE:%x\n", val);
+ dev_dbg(info->device, "PS3FB_IOCTL_GETMODE:%x\n", val);
if (!copy_to_user(argp, &val, sizeof(val)))
retval = 0;
break;
case PS3FB_IOCTL_SCREENINFO:
{
+ struct ps3fb_par *par = info->par;
struct ps3fb_ioctl_res res;
- int i = ps3fb.res_index;
- DPRINTK("PS3FB_IOCTL_SCREENINFO:\n");
- res.xres = ps3fb_res[i].xres;
- res.yres = ps3fb_res[i].yres;
- res.xoff = ps3fb_res[i].xoff;
- res.yoff = ps3fb_res[i].yoff;
- res.num_frames = ps3fb.num_frames;
+ dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n");
+ res.xres = info->fix.line_length / BPP;
+ res.yres = info->var.yres_virtual;
+ res.xoff = (res.xres - info->var.xres) / 2;
+ res.yoff = (res.yres - info->var.yres) / 2;
+ res.num_frames = par->num_frames;
if (!copy_to_user(argp, &res, sizeof(res)))
retval = 0;
break;
}
case PS3FB_IOCTL_ON:
- DPRINTK("PS3FB_IOCTL_ON:\n");
+ dev_dbg(info->device, "PS3FB_IOCTL_ON:\n");
atomic_inc(&ps3fb.ext_flip);
retval = 0;
break;
case PS3FB_IOCTL_OFF:
- DPRINTK("PS3FB_IOCTL_OFF:\n");
+ dev_dbg(info->device, "PS3FB_IOCTL_OFF:\n");
atomic_dec_if_positive(&ps3fb.ext_flip);
retval = 0;
break;
@@ -799,8 +863,8 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
if (copy_from_user(&val, argp, sizeof(val)))
break;
- DPRINTK("PS3FB_IOCTL_FSEL:%d\n", val);
- retval = ps3fb_sync(val);
+ dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val);
+ retval = ps3fb_sync(info, val);
break;
default:
@@ -812,13 +876,15 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
static int ps3fbd(void *arg)
{
+ struct fb_info *info = arg;
+
set_freezable();
while (!kthread_should_stop()) {
try_to_freeze();
set_current_state(TASK_INTERRUPTIBLE);
if (ps3fb.is_kicked) {
ps3fb.is_kicked = 0;
- ps3fb_sync(0); /* single buffer */
+ ps3fb_sync(info, 0); /* single buffer */
}
schedule();
}
@@ -827,14 +893,15 @@ static int ps3fbd(void *arg)
static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
{
+ struct device *dev = ptr;
u64 v1;
int status;
struct display_head *head = &ps3fb.dinfo->display_head[1];
status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
if (status) {
- printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n",
- __func__, status);
+ dev_err(dev, "%s: lv1_gpu_context_intr failed: %d\n", __func__,
+ status);
return IRQ_NONE;
}
@@ -854,35 +921,35 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
- struct ps3_system_bus_device *dev)
+ struct device *dev)
{
int error;
- DPRINTK("version_driver:%x\n", dinfo->version_driver);
- DPRINTK("irq outlet:%x\n", dinfo->irq.irq_outlet);
- DPRINTK("version_gpu:%x memory_size:%x ch:%x core_freq:%d mem_freq:%d\n",
+ dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
+ dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
+ dev_dbg(dev,
+ "version_gpu: %x memory_size: %x ch: %x core_freq: %d "
+ "mem_freq:%d\n",
dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
- printk(KERN_ERR "%s: version_driver err:%x\n", __func__,
- dinfo->version_driver);
+ dev_err(dev, "%s: version_driver err:%x\n", __func__,
+ dinfo->version_driver);
return -EINVAL;
}
error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
&ps3fb.irq_no);
if (error) {
- printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__,
- error);
+ dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
return error;
}
error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
DEVICE_NAME, dev);
if (error) {
- printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
- error);
+ dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
ps3_irq_plug_destroy(ps3fb.irq_no);
return error;
}
@@ -892,29 +959,31 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
return 0;
}
-static int ps3fb_xdr_settings(u64 xdr_lpar)
+static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
{
int status;
status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
xdr_lpar, ps3fb_videomemory.size, 0);
if (status) {
- printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n",
- __func__, status);
+ dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
+ __func__, status);
return -ENXIO;
}
- DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
+ dev_dbg(dev,
+ "video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar,
virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
status = lv1_gpu_context_attribute(ps3fb.context_handle,
L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
- xdr_lpar, ps3fb_videomemory.size,
- GPU_IOIF, 0);
+ xdr_lpar + ps3fb.xdr_size,
+ GPU_CMD_BUF_SIZE,
+ GPU_IOIF + ps3fb.xdr_size, 0);
if (status) {
- printk(KERN_ERR
- "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
- __func__, status);
+ dev_err(dev,
+ "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
+ __func__, status);
return -ENXIO;
}
return 0;
@@ -928,6 +997,7 @@ static struct fb_ops ps3fb_ops = {
.fb_check_var = ps3fb_check_var,
.fb_set_par = ps3fb_set_par,
.fb_setcolreg = ps3fb_setcolreg,
+ .fb_pan_display = ps3fb_pan_display,
.fb_fillrect = sys_fillrect,
.fb_copyarea = sys_copyarea,
.fb_imageblit = sys_imageblit,
@@ -944,7 +1014,7 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
.accel = FB_ACCEL_NONE,
};
-static int ps3fb_set_sync(void)
+static int ps3fb_set_sync(struct device *dev)
{
int status;
@@ -953,8 +1023,10 @@ static int ps3fb_set_sync(void)
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
if (status) {
- printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC "
- "failed: %d\n", __func__, status);
+ dev_err(dev,
+ "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
+ "%d\n",
+ __func__, status);
return -1;
}
#endif
@@ -964,8 +1036,10 @@ static int ps3fb_set_sync(void)
1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
if (status) {
- printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE "
- "failed: %d\n", __func__, status);
+ dev_err(dev,
+ "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
+ "%d\n",
+ __func__, status);
return -1;
}
#endif
@@ -975,6 +1049,7 @@ static int ps3fb_set_sync(void)
static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
{
struct fb_info *info;
+ struct ps3fb_par *par;
int retval = -ENOMEM;
u32 xres, yres;
u64 ddr_lpar = 0;
@@ -983,98 +1058,106 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
u64 lpar_reports = 0;
u64 lpar_reports_size = 0;
u64 xdr_lpar;
- int status;
- unsigned long offset;
+ int status, res_index;
struct task_struct *task;
status = ps3_open_hv_device(dev);
if (status) {
- printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__);
+ dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
+ __func__);
goto err;
}
if (!ps3fb_mode)
ps3fb_mode = ps3av_get_mode();
- DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
+ dev_dbg(&dev->core, "ps3av_mode:%d\n", ps3fb_mode);
if (ps3fb_mode > 0 &&
!ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
- ps3fb.res_index = ps3fb_get_res_table(xres, yres);
- DPRINTK("res_index:%d\n", ps3fb.res_index);
+ res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
+ dev_dbg(&dev->core, "res_index:%d\n", res_index);
} else
- ps3fb.res_index = GPU_RES_INDEX;
+ res_index = GPU_RES_INDEX;
atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
init_waitqueue_head(&ps3fb.wait_vsync);
- ps3fb.num_frames = 1;
- ps3fb_set_sync();
+ ps3fb_set_sync(&dev->core);
/* get gpu context handle */
status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
&ps3fb.memory_handle, &ddr_lpar);
if (status) {
- printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n",
- __func__, status);
+ dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
+ __func__, status);
goto err;
}
- DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar);
+ dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar);
status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0,
&ps3fb.context_handle,
&lpar_dma_control, &lpar_driver_info,
&lpar_reports, &lpar_reports_size);
if (status) {
- printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n",
- __func__, status);
+ dev_err(&dev->core,
+ "%s: lv1_gpu_context_attribute failed: %d\n", __func__,
+ status);
goto err_gpu_memory_free;
}
/* vsync interrupt */
ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
if (!ps3fb.dinfo) {
- printk(KERN_ERR "%s: ioremap failed\n", __func__);
+ dev_err(&dev->core, "%s: ioremap failed\n", __func__);
goto err_gpu_context_free;
}
- retval = ps3fb_vsync_settings(ps3fb.dinfo, dev);
+ retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core);
if (retval)
goto err_iounmap_dinfo;
- /* xdr frame buffer */
+ /* XDR frame buffer */
ps3fb.xdr_ea = ps3fb_videomemory.address;
xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
- retval = ps3fb_xdr_settings(xdr_lpar);
+
+ /* Clear memory to prevent kernel info leakage into userspace */
+ memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
+
+ /* The GPU command buffer is at the end of video memory */
+ ps3fb.xdr_size = ps3fb_videomemory.size - GPU_CMD_BUF_SIZE;
+
+ retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
if (retval)
goto err_free_irq;
- /*
- * ps3fb must clear memory to prevent kernel info
- * leakage into userspace
- */
- memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
- info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
+ info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
if (!info)
goto err_free_irq;
- offset = FB_OFF(ps3fb.res_index) + VP_OFF(ps3fb.res_index);
- info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
+ par = info->par;
+ par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
+ par->new_mode_id = ps3fb_mode;
+ par->res_index = res_index;
+ par->num_frames = 1;
+
+ info->screen_base = (char __iomem *)ps3fb.xdr_ea;
info->fbops = &ps3fb_ops;
info->fix = ps3fb_fix;
info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
- info->fix.smem_len = ps3fb_videomemory.size - offset;
- info->pseudo_palette = info->par;
- info->par = NULL;
- info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST;
+ info->fix.smem_len = ps3fb.xdr_size;
+ info->pseudo_palette = par->pseudo_palette;
+ info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
+ FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
retval = fb_alloc_cmap(&info->cmap, 256, 0);
if (retval < 0)
goto err_framebuffer_release;
if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
- ARRAY_SIZE(ps3fb_modedb), ps3fb_default_mode(), 32)) {
+ ARRAY_SIZE(ps3fb_modedb),
+ ps3fb_default_mode(par->new_mode_id), 32)) {
retval = -EINVAL;
goto err_fb_dealloc;
}
@@ -1088,9 +1171,9 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
dev->core.driver_data = info;
- printk(KERN_INFO
- "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
- info->node, ps3fb_videomemory.size >> 10);
+ dev_info(info->device, "%s %s, using %lu KiB of video memory\n",
+ dev_driver_string(info->dev), info->dev->bus_id,
+ ps3fb.xdr_size >> 10);
task = kthread_run(ps3fbd, info, DEVICE_NAME);
if (IS_ERR(task)) {
@@ -1127,7 +1210,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
int status;
struct fb_info *info = dev->core.driver_data;
- DPRINTK(" -> %s:%d\n", __func__, __LINE__);
+ dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
ps3fb_flip_ctl(0, &ps3fb); /* flip off */
ps3fb.dinfo->irq.mask = 0;
@@ -1152,14 +1235,16 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
status = lv1_gpu_context_free(ps3fb.context_handle);
if (status)
- DPRINTK("lv1_gpu_context_free failed: %d\n", status);
+ dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n",
+ status);
status = lv1_gpu_memory_free(ps3fb.memory_handle);
if (status)
- DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
+ dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
+ status);
ps3_close_hv_device(dev);
- DPRINTK(" <- %s:%d\n", __func__, __LINE__);
+ dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
return 0;
}
@@ -1212,9 +1297,9 @@ static int __init ps3fb_init(void)
static void __exit ps3fb_exit(void)
{
- DPRINTK(" -> %s:%d\n", __func__, __LINE__);
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
ps3_system_bus_driver_unregister(&ps3fb_driver);
- DPRINTK(" <- %s:%d\n", __func__, __LINE__);
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
}
module_init(ps3fb_init);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 06805c9b237..6a3d0b57489 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -72,7 +72,7 @@
#endif
#ifdef CONFIG_SH_STORE_QUEUES
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/cpu/sq.h>
#endif
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index a280a52f8ef..10f912df2da 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -37,11 +37,12 @@
#include <linux/cpufreq.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/err.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/uaccess.h>
#include <asm/div64.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/bitfield.h>
@@ -106,20 +107,38 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
u_int trans, struct fb_info *info)
{
struct pxafb_info *fbi = (struct pxafb_info *)info;
- u_int val, ret = 1;
+ u_int val;
- if (regno < fbi->palette_size) {
- if (fbi->fb.var.grayscale) {
- val = ((blue >> 8) & 0x00ff);
- } else {
- val = ((red >> 0) & 0xf800);
- val |= ((green >> 5) & 0x07e0);
- val |= ((blue >> 11) & 0x001f);
- }
+ if (regno >= fbi->palette_size)
+ return 1;
+
+ if (fbi->fb.var.grayscale) {
+ fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff);
+ return 0;
+ }
+
+ switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) {
+ case LCCR4_PAL_FOR_0:
+ val = ((red >> 0) & 0xf800);
+ val |= ((green >> 5) & 0x07e0);
+ val |= ((blue >> 11) & 0x001f);
fbi->palette_cpu[regno] = val;
- ret = 0;
+ break;
+ case LCCR4_PAL_FOR_1:
+ val = ((red << 8) & 0x00f80000);
+ val |= ((green >> 0) & 0x0000fc00);
+ val |= ((blue >> 8) & 0x000000f8);
+ ((u32*)(fbi->palette_cpu))[regno] = val;
+ break;
+ case LCCR4_PAL_FOR_2:
+ val = ((red << 8) & 0x00fc0000);
+ val |= ((green >> 0) & 0x0000fc00);
+ val |= ((blue >> 8) & 0x000000fc);
+ ((u32*)(fbi->palette_cpu))[regno] = val;
+ break;
}
- return ret;
+
+ return 0;
}
static int
@@ -361,7 +380,10 @@ static int pxafb_set_par(struct fb_info *info)
else
fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
- palette_mem_size = fbi->palette_size * sizeof(u16);
+ if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+ palette_mem_size = fbi->palette_size * sizeof(u16);
+ else
+ palette_mem_size = fbi->palette_size * sizeof(u32);
pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
@@ -506,15 +528,15 @@ static struct fb_ops pxafb_ops = {
*
* Factoring the 10^4 and 10^-12 out gives 10^-8 == 1 / 100000000 as used below.
*/
-static inline unsigned int get_pcd(unsigned int pixclock)
+static inline unsigned int get_pcd(struct pxafb_info *fbi, unsigned int pixclock)
{
unsigned long long pcd;
/* FIXME: Need to take into account Double Pixel Clock mode
- * (DPC) bit? or perhaps set it based on the various clock
- * speeds */
-
- pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
+ * (DPC) bit? or perhaps set it based on the various clock
+ * speeds */
+ pcd = (unsigned long long)(clk_get_rate(fbi->clk) / 10000);
+ pcd *= pixclock;
do_div(pcd, 100000000 * 2);
/* no need for this, since we should subtract 1 anyway. they cancel */
/* pcd += 1; */ /* make up for integer math truncations */
@@ -523,19 +545,21 @@ static inline unsigned int get_pcd(unsigned int pixclock)
/*
* Some touchscreens need hsync information from the video driver to
- * function correctly. We export it here.
+ * function correctly. We export it here. Note that 'hsync_time' and
+ * the value returned from pxafb_get_hsync_time() is the *reciprocal*
+ * of the hsync period in seconds.
*/
static inline void set_hsync_time(struct pxafb_info *fbi, unsigned int pcd)
{
- unsigned long long htime;
+ unsigned long htime;
if ((pcd == 0) || (fbi->fb.var.hsync_len == 0)) {
fbi->hsync_time=0;
return;
}
- htime = (unsigned long long)get_lcdclk_frequency_10khz() * 10000;
- do_div(htime, pcd * fbi->fb.var.hsync_len);
+ htime = clk_get_rate(fbi->clk) / (pcd * fbi->fb.var.hsync_len);
+
fbi->hsync_time = htime;
}
@@ -560,7 +584,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
{
struct pxafb_lcd_reg new_regs;
u_long flags;
- u_int lines_per_panel, pcd = get_pcd(var->pixclock);
+ u_int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
pr_debug("pxafb: Configuring PXA LCD\n");
@@ -676,7 +700,13 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
fbi->dmadesc_palette_cpu->fidr = 0;
- fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
+ if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+ fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
+ sizeof(u16);
+ else
+ fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
+ sizeof(u32);
+ fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL;
if (var->bits_per_pixel == 16) {
/* palette shouldn't be loaded in true-color mode */
@@ -715,6 +745,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
fbi->reg_lccr1 = new_regs.lccr1;
fbi->reg_lccr2 = new_regs.lccr2;
fbi->reg_lccr3 = new_regs.lccr3;
+ fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK);
+ fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
set_hsync_time(fbi, pcd);
local_irq_restore(flags);
@@ -803,7 +835,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
/* enable LCD controller clock */
- pxa_set_cken(CKEN_LCD, 1);
+ clk_enable(fbi->clk);
/* Sequence from 11.7.10 */
LCCR3 = fbi->reg_lccr3;
@@ -821,6 +853,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
+ pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4);
}
static void pxafb_disable_controller(struct pxafb_info *fbi)
@@ -840,7 +873,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
remove_wait_queue(&fbi->ctrlr_wait, &wait);
/* disable LCD controller clock */
- pxa_set_cken(CKEN_LCD, 0);
+ clk_disable(fbi->clk);
}
/*
@@ -994,7 +1027,7 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
break;
case CPUFREQ_POSTCHANGE:
- pcd = get_pcd(fbi->fb.var.pixclock);
+ pcd = get_pcd(fbi, fbi->fb.var.pixclock);
set_hsync_time(fbi, pcd);
fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
@@ -1090,10 +1123,13 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
* dma_writecombine_mmap)
*/
fbi->fb.fix.smem_start = fbi->screen_dma;
-
fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
- palette_mem_size = fbi->palette_size * sizeof(u16);
+ if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
+ palette_mem_size = fbi->palette_size * sizeof(u16);
+ else
+ palette_mem_size = fbi->palette_size * sizeof(u32);
+
pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
@@ -1119,6 +1155,12 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
memset(fbi, 0, sizeof(struct pxafb_info));
fbi->dev = dev;
+ fbi->clk = clk_get(dev, "LCDCLK");
+ if (IS_ERR(fbi->clk)) {
+ kfree(fbi);
+ return NULL;
+ }
+
strcpy(fbi->fb.fix.id, PXA_NAME);
fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
@@ -1150,6 +1192,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
fbi->lccr0 = inf->lccr0;
fbi->lccr3 = inf->lccr3;
+ fbi->lccr4 = inf->lccr4;
fbi->state = C_STARTUP;
fbi->task_state = (u_char)-1;
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 7499a1c4bf7..d920b8a14c3 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -40,6 +40,7 @@ struct pxafb_dma_descriptor {
struct pxafb_info {
struct fb_info fb;
struct device *dev;
+ struct clk *clk;
/*
* These are the addresses we mapped
@@ -70,6 +71,7 @@ struct pxafb_info {
u_int lccr0;
u_int lccr3;
+ u_int lccr4;
u_int cmap_inverse:1,
cmap_static:1,
unused:30;
@@ -78,6 +80,7 @@ struct pxafb_info {
u_int reg_lccr1;
u_int reg_lccr2;
u_int reg_lccr3;
+ u_int reg_lccr4;
unsigned long hsync_time;
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 8a4c6470d79..ae08d458709 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -20,7 +20,7 @@
*
* 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
* - Added the possibility to set on or off the
- * debugging mesaages
+ * debugging messages
* - Replaced 0 and 1 by on or off when reading the
* /sys files
*
@@ -31,8 +31,8 @@
* - add pixel clock divisor control
*
* 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
- * - Removed the use of currcon as it no more exist
- * - Added LCD power sysfs interface
+ * - Removed the use of currcon as it no more exists
+ * - Added LCD power sysfs interface
*
* 2004-11-03: Ben Dooks <ben-linux@fluff.org>
* - minor cleanups
@@ -49,12 +49,12 @@
* - Suppress command line options
*
* 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
- * - code cleanup
+ * - code cleanup
*
* 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
- * - Renamed from h1940fb.c to s3c2410fb.c
- * - Add support for different devices
- * - Backlight support
+ * - Renamed from h1940fb.c to s3c2410fb.c
+ * - Add support for different devices
+ * - Backlight support
*
* 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
* - added clock (de-)allocation code
@@ -82,13 +82,10 @@
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
#include <asm/div64.h>
#include <asm/mach/map.h>
@@ -102,14 +99,11 @@
#include "s3c2410fb.h"
-
-static struct s3c2410fb_mach_info *mach_info;
-
/* Debugging stuff */
#ifdef CONFIG_FB_S3C2410_DEBUG
-static int debug = 1;
+static int debug = 1;
#else
-static int debug = 0;
+static int debug = 0;
#endif
#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
@@ -119,48 +113,48 @@ static int debug = 0;
/* s3c2410fb_set_lcdaddr
*
* initialise lcd controller address pointers
-*/
-
-static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
+ */
+static void s3c2410fb_set_lcdaddr(struct fb_info *info)
{
- struct fb_var_screeninfo *var = &fbi->fb->var;
unsigned long saddr1, saddr2, saddr3;
+ struct s3c2410fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
- saddr1 = fbi->fb->fix.smem_start >> 1;
- saddr2 = fbi->fb->fix.smem_start;
- saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
- saddr2>>= 1;
+ saddr1 = info->fix.smem_start >> 1;
+ saddr2 = info->fix.smem_start;
+ saddr2 += info->fix.line_length * info->var.yres;
+ saddr2 >>= 1;
- saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff);
+ saddr3 = S3C2410_OFFSIZE(0) |
+ S3C2410_PAGEWIDTH((info->fix.line_length / 2) & 0x3ff);
dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
- writel(saddr1, S3C2410_LCDSADDR1);
- writel(saddr2, S3C2410_LCDSADDR2);
- writel(saddr3, S3C2410_LCDSADDR3);
+ writel(saddr1, regs + S3C2410_LCDSADDR1);
+ writel(saddr2, regs + S3C2410_LCDSADDR2);
+ writel(saddr3, regs + S3C2410_LCDSADDR3);
}
/* s3c2410fb_calc_pixclk()
*
* calculate divisor for clk->pixclk
-*/
-
+ */
static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
unsigned long pixclk)
{
unsigned long clk = clk_get_rate(fbi->clk);
unsigned long long div;
- /* pixclk is in picoseoncds, our clock is in Hz
+ /* pixclk is in picoseconds, our clock is in Hz
*
* Hz -> picoseconds is / 10^-12
*/
div = (unsigned long long)clk * pixclk;
- do_div(div,1000000UL);
- do_div(div,1000000UL);
+ div >>= 12; /* div / 2^12 */
+ do_div(div, 625 * 625UL * 625); /* div / 5^12 */
dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div);
return div;
@@ -176,246 +170,278 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct s3c2410fb_info *fbi = info->par;
+ struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
+ struct s3c2410fb_display *display = NULL;
+ struct s3c2410fb_display *default_display = mach_info->displays +
+ mach_info->default_display;
+ int type = default_display->type;
+ unsigned i;
dprintk("check_var(var=%p, info=%p)\n", var, info);
/* validate x/y resolution */
+ /* choose default mode if possible */
+ if (var->yres == default_display->yres &&
+ var->xres == default_display->xres &&
+ var->bits_per_pixel == default_display->bpp)
+ display = default_display;
+ else
+ for (i = 0; i < mach_info->num_displays; i++)
+ if (type == mach_info->displays[i].type &&
+ var->yres == mach_info->displays[i].yres &&
+ var->xres == mach_info->displays[i].xres &&
+ var->bits_per_pixel == mach_info->displays[i].bpp) {
+ display = mach_info->displays + i;
+ break;
+ }
- if (var->yres > fbi->mach_info->yres.max)
- var->yres = fbi->mach_info->yres.max;
- else if (var->yres < fbi->mach_info->yres.min)
- var->yres = fbi->mach_info->yres.min;
-
- if (var->xres > fbi->mach_info->xres.max)
- var->yres = fbi->mach_info->xres.max;
- else if (var->xres < fbi->mach_info->xres.min)
- var->xres = fbi->mach_info->xres.min;
-
- /* validate bpp */
-
- if (var->bits_per_pixel > fbi->mach_info->bpp.max)
- var->bits_per_pixel = fbi->mach_info->bpp.max;
- else if (var->bits_per_pixel < fbi->mach_info->bpp.min)
- var->bits_per_pixel = fbi->mach_info->bpp.min;
+ if (!display) {
+ dprintk("wrong resolution or depth %dx%d at %d bpp\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return -EINVAL;
+ }
+ /* it is always the size as the display */
+ var->xres_virtual = display->xres;
+ var->yres_virtual = display->yres;
+ var->height = display->height;
+ var->width = display->width;
+
+ /* copy lcd settings */
+ var->pixclock = display->pixclock;
+ var->left_margin = display->left_margin;
+ var->right_margin = display->right_margin;
+ var->upper_margin = display->upper_margin;
+ var->lower_margin = display->lower_margin;
+ var->vsync_len = display->vsync_len;
+ var->hsync_len = display->hsync_len;
+
+ fbi->regs.lcdcon5 = display->lcdcon5;
+ /* set display type */
+ fbi->regs.lcdcon1 = display->type;
+
+ var->transp.offset = 0;
+ var->transp.length = 0;
/* set r/g/b positions */
switch (var->bits_per_pixel) {
- case 1:
- case 2:
- case 4:
- var->red.offset = 0;
- var->red.length = var->bits_per_pixel;
- var->green = var->red;
- var->blue = var->red;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- case 8:
- if ( fbi->mach_info->type != S3C2410_LCDCON1_TFT ) {
- /* 8 bpp 332 */
- var->red.length = 3;
- var->red.offset = 5;
- var->green.length = 3;
- var->green.offset = 2;
- var->blue.length = 2;
- var->blue.offset = 0;
- var->transp.length = 0;
- } else {
- var->red.offset = 0;
- var->red.length = var->bits_per_pixel;
- var->green = var->red;
- var->blue = var->red;
- var->transp.offset = 0;
- var->transp.length = 0;
- }
- break;
- case 12:
- /* 12 bpp 444 */
- var->red.length = 4;
- var->red.offset = 8;
- var->green.length = 4;
- var->green.offset = 4;
- var->blue.length = 4;
+ case 1:
+ case 2:
+ case 4:
+ var->red.offset = 0;
+ var->red.length = var->bits_per_pixel;
+ var->green = var->red;
+ var->blue = var->red;
+ break;
+ case 8:
+ if (display->type != S3C2410_LCDCON1_TFT) {
+ /* 8 bpp 332 */
+ var->red.length = 3;
+ var->red.offset = 5;
+ var->green.length = 3;
+ var->green.offset = 2;
+ var->blue.length = 2;
var->blue.offset = 0;
- var->transp.length = 0;
- break;
-
- default:
- case 16:
- if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565 ) {
- /* 16 bpp, 565 format */
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- var->red.length = 5;
- var->green.length = 6;
- var->blue.length = 5;
- var->transp.length = 0;
- } else {
- /* 16 bpp, 5551 format */
- var->red.offset = 11;
- var->green.offset = 6;
- var->blue.offset = 1;
- var->red.length = 5;
- var->green.length = 5;
- var->blue.length = 5;
- var->transp.length = 0;
- }
- break;
- case 24:
- /* 24 bpp 888 */
+ } else {
+ var->red.offset = 0;
var->red.length = 8;
- var->red.offset = 16;
- var->green.length = 8;
- var->green.offset = 8;
- var->blue.length = 8;
- var->blue.offset = 0;
- var->transp.length = 0;
- break;
-
+ var->green = var->red;
+ var->blue = var->red;
+ }
+ break;
+ case 12:
+ /* 12 bpp 444 */
+ var->red.length = 4;
+ var->red.offset = 8;
+ var->green.length = 4;
+ var->green.offset = 4;
+ var->blue.length = 4;
+ var->blue.offset = 0;
+ break;
+ default:
+ case 16:
+ if (display->lcdcon5 & S3C2410_LCDCON5_FRM565) {
+ /* 16 bpp, 565 format */
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ } else {
+ /* 16 bpp, 5551 format */
+ var->red.offset = 11;
+ var->green.offset = 6;
+ var->blue.offset = 1;
+ var->red.length = 5;
+ var->green.length = 5;
+ var->blue.length = 5;
+ }
+ break;
+ case 32:
+ /* 24 bpp 888 and 8 dummy */
+ var->red.length = 8;
+ var->red.offset = 16;
+ var->green.length = 8;
+ var->green.offset = 8;
+ var->blue.length = 8;
+ var->blue.offset = 0;
+ break;
}
return 0;
}
-
-/* s3c2410fb_activate_var
+/* s3c2410fb_calculate_stn_lcd_regs
*
- * activate (set) the controller from the given framebuffer
- * information
-*/
-
-static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
- struct fb_var_screeninfo *var)
+ * calculate register values from var settings
+ */
+static void s3c2410fb_calculate_stn_lcd_regs(const struct fb_info *info,
+ struct s3c2410fb_hw *regs)
{
- int hs;
+ const struct s3c2410fb_info *fbi = info->par;
+ const struct fb_var_screeninfo *var = &info->var;
+ int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT;
+ int hs = var->xres >> 2;
+ unsigned wdly = (var->left_margin >> 4) - 1;
+ unsigned wlh = (var->hsync_len >> 4) - 1;
- fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
- fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT;
+ if (type != S3C2410_LCDCON1_STN4)
+ hs >>= 1;
- dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
- dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
- dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
+ switch (var->bits_per_pixel) {
+ case 1:
+ regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
+ break;
+ case 2:
+ regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
+ break;
+ case 4:
+ regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
+ break;
+ case 8:
+ regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
+ hs *= 3;
+ break;
+ case 12:
+ regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
+ hs *= 3;
+ break;
- fbi->regs.lcdcon1 |= fbi->mach_info->type;
-
- if (fbi->mach_info->type == S3C2410_LCDCON1_TFT)
- switch (var->bits_per_pixel) {
- case 1:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
- break;
- case 2:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
- break;
- case 4:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
- break;
- case 8:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
- break;
- case 16:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
- break;
-
- default:
- /* invalid pixel depth */
- dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
- }
- else
- switch (var->bits_per_pixel) {
- case 1:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
- break;
- case 2:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
- break;
- case 4:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
- break;
- case 8:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
- break;
- case 12:
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
- break;
-
- default:
- /* invalid pixel depth */
- dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
- }
+ default:
+ /* invalid pixel depth */
+ dev_err(fbi->dev, "invalid bpp %d\n",
+ var->bits_per_pixel);
+ }
+ /* update X/Y info */
+ dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
+ var->left_margin, var->right_margin, var->hsync_len);
- /* check to see if we need to update sync/borders */
+ regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1);
- if (!fbi->mach_info->fixed_syncs) {
- dprintk("setting vert: up=%d, low=%d, sync=%d\n",
- var->upper_margin, var->lower_margin,
- var->vsync_len);
+ if (wdly > 3)
+ wdly = 3;
- dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
- var->left_margin, var->right_margin,
- var->hsync_len);
+ if (wlh > 3)
+ wlh = 3;
- fbi->regs.lcdcon2 =
- S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
- S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
- S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
+ regs->lcdcon3 = S3C2410_LCDCON3_WDLY(wdly) |
+ S3C2410_LCDCON3_LINEBLANK(var->right_margin / 8) |
+ S3C2410_LCDCON3_HOZVAL(hs - 1);
- fbi->regs.lcdcon3 =
- S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
- S3C2410_LCDCON3_HFPD(var->left_margin - 1);
+ regs->lcdcon4 = S3C2410_LCDCON4_WLH(wlh);
+}
- fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff);
- fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
- }
+/* s3c2410fb_calculate_tft_lcd_regs
+ *
+ * calculate register values from var settings
+ */
+static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info,
+ struct s3c2410fb_hw *regs)
+{
+ const struct s3c2410fb_info *fbi = info->par;
+ const struct fb_var_screeninfo *var = &info->var;
+ switch (var->bits_per_pixel) {
+ case 1:
+ regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
+ break;
+ case 2:
+ regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
+ break;
+ case 4:
+ regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
+ break;
+ case 8:
+ regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
+ regs->lcdcon5 |= S3C2410_LCDCON5_BSWP |
+ S3C2410_LCDCON5_FRM565;
+ regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP;
+ break;
+ case 16:
+ regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
+ regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP;
+ regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP;
+ break;
+ case 32:
+ regs->lcdcon1 |= S3C2410_LCDCON1_TFT24BPP;
+ regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP |
+ S3C2410_LCDCON5_HWSWP |
+ S3C2410_LCDCON5_BPP24BL);
+ break;
+ default:
+ /* invalid pixel depth */
+ dev_err(fbi->dev, "invalid bpp %d\n",
+ var->bits_per_pixel);
+ }
/* update X/Y info */
+ dprintk("setting vert: up=%d, low=%d, sync=%d\n",
+ var->upper_margin, var->lower_margin, var->vsync_len);
- fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
- fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
-
- switch(fbi->mach_info->type) {
- case S3C2410_LCDCON1_DSCAN4:
- case S3C2410_LCDCON1_STN8:
- hs = var->xres / 8;
- break;
- case S3C2410_LCDCON1_STN4:
- hs = var->xres / 4;
- break;
- default:
- case S3C2410_LCDCON1_TFT:
- hs = var->xres;
- break;
-
- }
+ dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
+ var->left_margin, var->right_margin, var->hsync_len);
- /* Special cases : STN color displays */
- if ( ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) \
- || ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP) ) {
- hs = hs * 3;
- }
+ regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) |
+ S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
+ S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
+ S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
+ regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
+ S3C2410_LCDCON3_HFPD(var->left_margin - 1) |
+ S3C2410_LCDCON3_HOZVAL(var->xres - 1);
- fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
- fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1);
+ regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
+}
- if (var->pixclock > 0) {
- int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
+/* s3c2410fb_activate_var
+ *
+ * activate (set) the controller from the given framebuffer
+ * information
+ */
+static void s3c2410fb_activate_var(struct fb_info *info)
+{
+ struct s3c2410fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
+ int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;
+ struct fb_var_screeninfo *var = &info->var;
+ int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2;
- if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) {
- clkdiv = (clkdiv / 2) -1;
- if (clkdiv < 0)
- clkdiv = 0;
- }
- else {
- clkdiv = (clkdiv / 2);
- if (clkdiv < 2)
- clkdiv = 2;
- }
+ dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
+ dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
+ dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
- fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff);
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
+ if (type == S3C2410_LCDCON1_TFT) {
+ s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);
+ --clkdiv;
+ if (clkdiv < 0)
+ clkdiv = 0;
+ } else {
+ s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);
+ if (clkdiv < 2)
+ clkdiv = 2;
}
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
+
/* write new registers */
dprintk("new register set:\n");
@@ -425,47 +451,48 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4);
dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5);
- writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1);
- writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
- writel(fbi->regs.lcdcon3, S3C2410_LCDCON3);
- writel(fbi->regs.lcdcon4, S3C2410_LCDCON4);
- writel(fbi->regs.lcdcon5, S3C2410_LCDCON5);
+ writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID,
+ regs + S3C2410_LCDCON1);
+ writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
+ writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
+ writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
+ writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
/* set lcd address pointers */
- s3c2410fb_set_lcdaddr(fbi);
+ s3c2410fb_set_lcdaddr(info);
- writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
+ fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID,
+ writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
}
-
/*
- * s3c2410fb_set_par - Optional function. Alters the hardware state.
+ * s3c2410fb_set_par - Alters the hardware state.
* @info: frame buffer structure that represents a single frame buffer
*
*/
static int s3c2410fb_set_par(struct fb_info *info)
{
- struct s3c2410fb_info *fbi = info->par;
struct fb_var_screeninfo *var = &info->var;
- switch (var->bits_per_pixel)
- {
- case 16:
- fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR;
- break;
- case 1:
- fbi->fb->fix.visual = FB_VISUAL_MONO01;
- break;
- default:
- fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- break;
+ switch (var->bits_per_pixel) {
+ case 32:
+ case 16:
+ case 12:
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+ case 1:
+ info->fix.visual = FB_VISUAL_MONO01;
+ break;
+ default:
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
}
- fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8;
+ info->fix.line_length = (var->width * var->bits_per_pixel) / 8;
/* activate this new configuration */
- s3c2410fb_activate_var(fbi, var);
+ s3c2410fb_activate_var(info);
return 0;
}
@@ -493,7 +520,8 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
}
/* from pxafb.c */
-static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
+static inline unsigned int chan_to_field(unsigned int chan,
+ struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= 16 - bf->length;
@@ -505,20 +533,22 @@ static int s3c2410fb_setcolreg(unsigned regno,
unsigned transp, struct fb_info *info)
{
struct s3c2410fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
unsigned int val;
- /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", regno, red, green, blue); */
+ /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n",
+ regno, red, green, blue); */
- switch (fbi->fb->fix.visual) {
+ switch (info->fix.visual) {
case FB_VISUAL_TRUECOLOR:
- /* true-colour, use pseuo-palette */
+ /* true-colour, use pseudo-palette */
if (regno < 16) {
- u32 *pal = fbi->fb->pseudo_palette;
+ u32 *pal = info->pseudo_palette;
- val = chan_to_field(red, &fbi->fb->var.red);
- val |= chan_to_field(green, &fbi->fb->var.green);
- val |= chan_to_field(blue, &fbi->fb->var.blue);
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue, &info->var.blue);
pal[regno] = val;
}
@@ -528,25 +558,24 @@ static int s3c2410fb_setcolreg(unsigned regno,
if (regno < 256) {
/* currently assume RGB 5-6-5 mode */
- val = ((red >> 0) & 0xf800);
- val |= ((green >> 5) & 0x07e0);
- val |= ((blue >> 11) & 0x001f);
+ val = (red >> 0) & 0xf800;
+ val |= (green >> 5) & 0x07e0;
+ val |= (blue >> 11) & 0x001f;
- writel(val, S3C2410_TFTPAL(regno));
+ writel(val, regs + S3C2410_TFTPAL(regno));
schedule_palette_update(fbi, regno, val);
}
break;
default:
- return 1; /* unknown type */
+ return 1; /* unknown type */
}
return 0;
}
-
-/**
+/*
* s3c2410fb_blank
* @blank_mode: the blank mode we want.
* @info: frame buffer structure that represents a single frame buffer
@@ -564,31 +593,31 @@ static int s3c2410fb_setcolreg(unsigned regno,
*/
static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
{
- dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
+ struct s3c2410fb_info *fbi = info->par;
+ void __iomem *regs = fbi->io;
- if (mach_info == NULL)
- return -EINVAL;
+ dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
if (blank_mode == FB_BLANK_UNBLANK)
- writel(0x0, S3C2410_TPAL);
+ writel(0x0, regs + S3C2410_TPAL);
else {
dprintk("setting TPAL to output 0x000000\n");
- writel(S3C2410_TPAL_EN, S3C2410_TPAL);
+ writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL);
}
return 0;
}
-static int s3c2410fb_debug_show(struct device *dev, struct device_attribute *attr, char *buf)
+static int s3c2410fb_debug_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off");
}
-static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t len)
-{
- if (mach_info == NULL)
- return -EINVAL;
+static int s3c2410fb_debug_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
if (len < 1)
return -EINVAL;
@@ -607,10 +636,7 @@ static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *at
return len;
}
-
-static DEVICE_ATTR(debug, 0666,
- s3c2410fb_debug_show,
- s3c2410fb_debug_store);
+static DEVICE_ATTR(debug, 0666, s3c2410fb_debug_show, s3c2410fb_debug_store);
static struct fb_ops s3c2410fb_ops = {
.owner = THIS_MODULE,
@@ -623,7 +649,6 @@ static struct fb_ops s3c2410fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-
/*
* s3c2410fb_map_video_memory():
* Allocates the DRAM memory for the frame buffer. This buffer is
@@ -632,36 +657,38 @@ static struct fb_ops s3c2410fb_ops = {
* cache. Once this area is remapped, all virtual memory
* access to the video memory should occur at the new region.
*/
-static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi)
+static int __init s3c2410fb_map_video_memory(struct fb_info *info)
{
- dprintk("map_video_memory(fbi=%p)\n", fbi);
+ struct s3c2410fb_info *fbi = info->par;
+ dma_addr_t map_dma;
+ unsigned map_size = PAGE_ALIGN(info->fix.smem_len);
- fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE);
- fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
- &fbi->map_dma, GFP_KERNEL);
+ dprintk("map_video_memory(fbi=%p)\n", fbi);
- fbi->map_size = fbi->fb->fix.smem_len;
+ info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
+ &map_dma, GFP_KERNEL);
- if (fbi->map_cpu) {
+ if (info->screen_base) {
/* prevent initial garbage on screen */
dprintk("map_video_memory: clear %p:%08x\n",
- fbi->map_cpu, fbi->map_size);
- memset(fbi->map_cpu, 0xf0, fbi->map_size);
+ info->screen_base, map_size);
+ memset(info->screen_base, 0xf0, map_size);
- fbi->screen_dma = fbi->map_dma;
- fbi->fb->screen_base = fbi->map_cpu;
- fbi->fb->fix.smem_start = fbi->screen_dma;
+ info->fix.smem_start = map_dma;
- dprintk("map_video_memory: dma=%08x cpu=%p size=%08x\n",
- fbi->map_dma, fbi->map_cpu, fbi->fb->fix.smem_len);
+ dprintk("map_video_memory: dma=%08lx cpu=%p size=%08x\n",
+ info->fix.smem_start, info->screen_base, map_size);
}
- return fbi->map_cpu ? 0 : -ENOMEM;
+ return info->screen_base ? 0 : -ENOMEM;
}
-static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi)
+static inline void s3c2410fb_unmap_video_memory(struct fb_info *info)
{
- dma_free_writecombine(fbi->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma);
+ struct s3c2410fb_info *fbi = info->par;
+
+ dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
+ info->screen_base, info->fix.smem_start);
}
static inline void modify_gpio(void __iomem *reg,
@@ -673,13 +700,13 @@ static inline void modify_gpio(void __iomem *reg,
writel(tmp | set, reg);
}
-
/*
* s3c2410fb_init_registers - Initialise all LCD-related registers
*/
-
-static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
+static int s3c2410fb_init_registers(struct fb_info *info)
{
+ struct s3c2410fb_info *fbi = info->par;
+ struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
unsigned long flags;
void __iomem *regs = fbi->io;
@@ -696,14 +723,6 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
local_irq_restore(flags);
- writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
- writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
- writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
- writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
- writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
-
- s3c2410fb_set_lcdaddr(fbi);
-
dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
writel(mach_info->lpcsel, regs + S3C2410_LPCSEL);
@@ -712,22 +731,19 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
/* ensure temporary palette disabled */
writel(0x00, regs + S3C2410_TPAL);
- /* Enable video by setting the ENVID bit to 1 */
- fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID;
- writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
return 0;
}
static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
{
unsigned int i;
- unsigned long ent;
void __iomem *regs = fbi->io;
fbi->palette_ready = 0;
for (i = 0; i < 256; i++) {
- if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR)
+ unsigned long ent = fbi->palette_buffer[i];
+ if (ent == PALETTE_BUFF_CLEAR)
continue;
writel(ent, regs + S3C2410_TFTPAL(i));
@@ -761,13 +777,14 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static char driver_name[]="s3c2410fb";
+static char driver_name[] = "s3c2410fb";
static int __init s3c2410fb_probe(struct platform_device *pdev)
{
struct s3c2410fb_info *info;
- struct fb_info *fbinfo;
- struct s3c2410fb_hw *mregs;
+ struct s3c2410fb_display *display;
+ struct fb_info *fbinfo;
+ struct s3c2410fb_mach_info *mach_info;
struct resource *res;
int ret;
int irq;
@@ -777,11 +794,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
mach_info = pdev->dev.platform_data;
if (mach_info == NULL) {
- dev_err(&pdev->dev,"no platform data for lcd, cannot attach\n");
+ dev_err(&pdev->dev,
+ "no platform data for lcd, cannot attach\n");
return -EINVAL;
}
- mregs = &mach_info->regs;
+ display = mach_info->displays + mach_info->default_display;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -790,22 +808,22 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
}
fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);
- if (!fbinfo) {
+ if (!fbinfo)
return -ENOMEM;
- }
+
+ platform_set_drvdata(pdev, fbinfo);
info = fbinfo->par;
- info->fb = fbinfo;
info->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
- dev_err(&pdev->dev, "failed to get memory registersn");
+ dev_err(&pdev->dev, "failed to get memory registers\n");
ret = -ENXIO;
goto dealloc_fb;
}
- size = (res->end - res->start)+1;
+ size = (res->end - res->start) + 1;
info->mem = request_mem_region(res->start, size, pdev->name);
if (info->mem == NULL) {
dev_err(&pdev->dev, "failed to get memory region\n");
@@ -820,21 +838,14 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
goto release_mem;
}
- platform_set_drvdata(pdev, fbinfo);
-
dprintk("devinit\n");
strcpy(fbinfo->fix.id, driver_name);
- memcpy(&info->regs, &mach_info->regs, sizeof(info->regs));
-
- /* Stop the video and unset ENVID if set */
- info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
+ /* Stop the video */
lcdcon1 = readl(info->io + S3C2410_LCDCON1);
writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
- info->mach_info = pdev->dev.platform_data;
-
fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
fbinfo->fix.type_aux = 0;
fbinfo->fix.xpanstep = 0;
@@ -844,8 +855,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->var.nonstd = 0;
fbinfo->var.activate = FB_ACTIVATE_NOW;
- fbinfo->var.height = mach_info->height;
- fbinfo->var.width = mach_info->width;
fbinfo->var.accel_flags = 0;
fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
@@ -853,32 +862,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
fbinfo->flags = FBINFO_FLAG_DEFAULT;
fbinfo->pseudo_palette = &info->pseudo_pal;
- fbinfo->var.xres = mach_info->xres.defval;
- fbinfo->var.xres_virtual = mach_info->xres.defval;
- fbinfo->var.yres = mach_info->yres.defval;
- fbinfo->var.yres_virtual = mach_info->yres.defval;
- fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
-
- fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
- fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1;
- fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
-
- fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
- fbinfo->var.right_margin = S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1;
- fbinfo->var.hsync_len = S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;
-
- fbinfo->var.red.offset = 11;
- fbinfo->var.green.offset = 5;
- fbinfo->var.blue.offset = 0;
- fbinfo->var.transp.offset = 0;
- fbinfo->var.red.length = 5;
- fbinfo->var.green.length = 6;
- fbinfo->var.blue.length = 5;
- fbinfo->var.transp.length = 0;
- fbinfo->fix.smem_len = mach_info->xres.max *
- mach_info->yres.max *
- mach_info->bpp.max / 8;
-
for (i = 0; i < 256; i++)
info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
@@ -901,23 +884,39 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
msleep(1);
+ /* find maximum required memory size for display */
+ for (i = 0; i < mach_info->num_displays; i++) {
+ unsigned long smem_len = mach_info->displays[i].xres;
+
+ smem_len *= mach_info->displays[i].yres;
+ smem_len *= mach_info->displays[i].bpp;
+ smem_len >>= 3;
+ if (fbinfo->fix.smem_len < smem_len)
+ fbinfo->fix.smem_len = smem_len;
+ }
+
/* Initialize video memory */
- ret = s3c2410fb_map_video_memory(info);
+ ret = s3c2410fb_map_video_memory(fbinfo);
if (ret) {
- printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret);
+ printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
ret = -ENOMEM;
goto release_clock;
}
dprintk("got video memory\n");
- ret = s3c2410fb_init_registers(info);
+ fbinfo->var.xres = display->xres;
+ fbinfo->var.yres = display->yres;
+ fbinfo->var.bits_per_pixel = display->bpp;
+
+ s3c2410fb_init_registers(fbinfo);
- ret = s3c2410fb_check_var(&fbinfo->var, fbinfo);
+ s3c2410fb_check_var(&fbinfo->var, fbinfo);
ret = register_framebuffer(fbinfo);
if (ret < 0) {
- printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret);
+ printk(KERN_ERR "Failed to register framebuffer device: %d\n",
+ ret);
goto free_video_memory;
}
@@ -930,18 +929,19 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
return 0;
free_video_memory:
- s3c2410fb_unmap_video_memory(info);
+ s3c2410fb_unmap_video_memory(fbinfo);
release_clock:
clk_disable(info->clk);
clk_put(info->clk);
release_irq:
- free_irq(irq,info);
+ free_irq(irq, info);
release_regs:
iounmap(info->io);
release_mem:
release_resource(info->mem);
kfree(info->mem);
dealloc_fb:
+ platform_set_drvdata(pdev, NULL);
framebuffer_release(fbinfo);
return ret;
}
@@ -949,8 +949,7 @@ dealloc_fb:
/* s3c2410fb_stop_lcd
*
* shutdown the lcd controller
-*/
-
+ */
static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
{
unsigned long flags;
@@ -968,28 +967,33 @@ static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
*/
static int s3c2410fb_remove(struct platform_device *pdev)
{
- struct fb_info *fbinfo = platform_get_drvdata(pdev);
+ struct fb_info *fbinfo = platform_get_drvdata(pdev);
struct s3c2410fb_info *info = fbinfo->par;
int irq;
+ unregister_framebuffer(fbinfo);
+
s3c2410fb_stop_lcd(info);
msleep(1);
- s3c2410fb_unmap_video_memory(info);
+ s3c2410fb_unmap_video_memory(fbinfo);
- if (info->clk) {
- clk_disable(info->clk);
- clk_put(info->clk);
- info->clk = NULL;
+ if (info->clk) {
+ clk_disable(info->clk);
+ clk_put(info->clk);
+ info->clk = NULL;
}
irq = platform_get_irq(pdev, 0);
- free_irq(irq,info);
+ free_irq(irq, info);
+
+ iounmap(info->io);
release_resource(info->mem);
kfree(info->mem);
- iounmap(info->io);
- unregister_framebuffer(fbinfo);
+
+ platform_set_drvdata(pdev, NULL);
+ framebuffer_release(fbinfo);
return 0;
}
@@ -997,7 +1001,6 @@ static int s3c2410fb_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
/* suspend and resume support for the lcd controller */
-
static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
{
struct fb_info *fbinfo = platform_get_drvdata(dev);
@@ -1044,7 +1047,7 @@ static struct platform_driver s3c2410fb_driver = {
},
};
-int __devinit s3c2410fb_init(void)
+int __init s3c2410fb_init(void)
{
return platform_driver_register(&s3c2410fb_driver);
}
@@ -1054,10 +1057,10 @@ static void __exit s3c2410fb_cleanup(void)
platform_driver_unregister(&s3c2410fb_driver);
}
-
module_init(s3c2410fb_init);
module_exit(s3c2410fb_cleanup);
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, Ben Dooks <ben-linux@fluff.org>");
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
+ "Ben Dooks <ben-linux@fluff.org>");
MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index 17c7915b7ac..6ce5dc26c5f 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -16,7 +16,7 @@
*
* 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
* - Renamed from h1940fb.h to s3c2410fb.h
- * - Chenged h1940 to s3c2410
+ * - Changed h1940 to s3c2410
*
* 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
* - First version
@@ -26,25 +26,14 @@
#define __S3C2410FB_H
struct s3c2410fb_info {
- struct fb_info *fb;
struct device *dev;
struct clk *clk;
struct resource *mem;
void __iomem *io;
- struct s3c2410fb_mach_info *mach_info;
-
- /* raw memory addresses */
- dma_addr_t map_dma; /* physical */
- u_char * map_cpu; /* virtual */
- u_int map_size;
-
struct s3c2410fb_hw regs;
- /* addresses of pieces placed in raw buffer */
- u_char * screen_cpu; /* virtual address of buffer */
- dma_addr_t screen_dma; /* physical address of buffer */
unsigned int palette_ready;
/* keep these registers in case we need to re-write palette */
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index d11735895a0..7d53bc23b9c 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -400,11 +400,17 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct s3fb_info *par = info->par;
int rv, mem, step;
+ u16 m, n, r;
/* Find appropriate format */
rv = svga_match_format (s3fb_formats, var, NULL);
- if ((rv < 0) || ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6)))
- { /* 24bpp on VIRGE VX, 32bpp on others */
+
+ /* 32bpp mode is not supported on VIRGE VX,
+ 24bpp is not supported on others */
+ if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6))
+ rv = -EINVAL;
+
+ if (rv < 0) {
printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node);
return rv;
}
@@ -422,20 +428,26 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
/* Check whether have enough memory */
mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;
- if (mem > info->screen_size)
- {
+ if (mem > info->screen_size) {
printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n",
info->node, mem >> 10, (unsigned int) (info->screen_size >> 10));
return -EINVAL;
}
rv = svga_check_timings (&s3_timing_regs, var, info->node);
- if (rv < 0)
- {
+ if (rv < 0) {
printk(KERN_ERR "fb%d: invalid timings requested\n", info->node);
return rv;
}
+ rv = svga_compute_pll(&s3_pll, PICOS2KHZ(var->pixclock), &m, &n, &r,
+ info->node);
+ if (rv < 0) {
+ printk(KERN_ERR "fb%d: invalid pixclock value requested\n",
+ info->node);
+ return rv;
+ }
+
return 0;
}
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 5d2a4a4b731..ab2b2110478 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -178,7 +178,6 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/mach-types.h>
-#include <asm/uaccess.h>
#include <asm/arch/assabet.h>
#include <asm/arch/shannon.h>
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index b855f4a34af..37b135d5d12 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -57,7 +57,6 @@
#include <asm/irq.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <asm/uaccess.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index e8ccace0125..bc7d2368373 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -58,7 +58,7 @@
#include <linux/capability.h>
#include <linux/fs.h>
#include <linux/types.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/io.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 64779e70408..62321458f71 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -780,7 +780,7 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
*
* NOTE: This field is currently unused.
*/
- info->pixmap.scan_align = 32;
+ info->pixmap.access_align = 32;
/***************************** End optional stage ***************************/
/*
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index c86df126f93..1be95a68d69 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -28,6 +28,7 @@
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/console.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -62,6 +63,8 @@ struct sm501fb_info {
struct resource *regs_res; /* registers resource */
struct sm501_platdata_fb *pdata; /* our platform data */
+ unsigned long pm_crt_ctrl; /* pm: crt ctrl save */
+
int irq;
int swap_endian; /* set to swap rgb=>bgr */
void __iomem *regs; /* remapped registers */
@@ -774,6 +777,11 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
sm501fb_sync_regs(fbi);
+ /* ensure the panel interface is not tristated at this point */
+
+ sm501_modify_reg(fbi->dev->parent, SM501_SYSTEM_CONTROL,
+ 0, SM501_SYSCTRL_PANEL_TRISTATE);
+
/* power the panel up */
sm501fb_panel_power(fbi, 1);
return 0;
@@ -1687,19 +1695,25 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
goto err_nocursor;
}
+ dev_dbg(info->dev, "suspending screen to %p\n", par->store_fb);
+ dev_dbg(info->dev, "suspending cursor to %p\n", par->store_cursor);
+
memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size);
memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size);
-
/* blank the relevant interface to ensure unit power minimised */
(par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi);
+ acquire_console_sem();
+ fb_set_suspend(fbi, 1);
+ release_console_sem();
+
return 0;
err_nocursor:
vfree(par->store_fb);
+ par->store_fb = NULL;
return -ENOMEM;
-
}
static void sm501fb_resume_fb(struct sm501fb_info *info,
@@ -1717,8 +1731,20 @@ static void sm501fb_resume_fb(struct sm501fb_info *info,
/* restore the data */
- memcpy_toio(par->screen.k_addr, par->store_fb, par->screen.size);
- memcpy_toio(par->cursor.k_addr, par->store_cursor, par->cursor.size);
+ dev_dbg(info->dev, "restoring screen from %p\n", par->store_fb);
+ dev_dbg(info->dev, "restoring cursor from %p\n", par->store_cursor);
+
+ if (par->store_fb)
+ memcpy_toio(par->screen.k_addr, par->store_fb,
+ par->screen.size);
+
+ if (par->store_cursor)
+ memcpy_toio(par->cursor.k_addr, par->store_cursor,
+ par->cursor.size);
+
+ acquire_console_sem();
+ fb_set_suspend(fbi, 0);
+ release_console_sem();
vfree(par->store_fb);
vfree(par->store_cursor);
@@ -1731,6 +1757,9 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
{
struct sm501fb_info *info = platform_get_drvdata(pdev);
+ /* store crt control to resume with */
+ info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+
sm501fb_suspend_fb(info, HEAD_CRT);
sm501fb_suspend_fb(info, HEAD_PANEL);
@@ -1740,12 +1769,24 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
+#define SM501_CRT_CTRL_SAVE (SM501_DC_CRT_CONTROL_TVP | \
+ SM501_DC_CRT_CONTROL_SEL)
+
+
static int sm501fb_resume(struct platform_device *pdev)
{
struct sm501fb_info *info = platform_get_drvdata(pdev);
+ unsigned long crt_ctrl;
sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 1);
+ /* restore the items we want to be saved for crt control */
+
+ crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
+ crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
+ crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
+ writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
+
sm501fb_resume_fb(info, HEAD_CRT);
sm501fb_resume_fb(info, HEAD_PANEL);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 5eff28ce4f4..97784f9c184 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -88,7 +88,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <video/sstfb.h>
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 25df928d37d..9c710670157 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -598,9 +598,11 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
/* ------------------------------------------------------------------------- */
-int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix)
+static inline int match_format(const struct svga_fb_format *frm,
+ struct fb_var_screeninfo *var)
{
int i = 0;
+ int stored = -EINVAL;
while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
{
@@ -609,25 +611,38 @@ int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo
(var->green.length <= frm->green.length) &&
(var->blue.length <= frm->blue.length) &&
(var->transp.length <= frm->transp.length) &&
- (var->nonstd == frm->nonstd)) {
- var->bits_per_pixel = frm->bits_per_pixel;
- var->red = frm->red;
- var->green = frm->green;
- var->blue = frm->blue;
- var->transp = frm->transp;
- var->nonstd = frm->nonstd;
- if (fix != NULL) {
- fix->type = frm->type;
- fix->type_aux = frm->type_aux;
- fix->visual = frm->visual;
- fix->xpanstep = frm->xpanstep;
- }
+ (var->nonstd == frm->nonstd))
return i;
- }
+ if (var->bits_per_pixel == frm->bits_per_pixel)
+ stored = i;
i++;
frm++;
}
- return -EINVAL;
+ return stored;
+}
+
+int svga_match_format(const struct svga_fb_format *frm,
+ struct fb_var_screeninfo *var,
+ struct fb_fix_screeninfo *fix)
+{
+ int i = match_format(frm, var);
+
+ if (i >= 0) {
+ var->bits_per_pixel = frm[i].bits_per_pixel;
+ var->red = frm[i].red;
+ var->green = frm[i].green;
+ var->blue = frm[i].blue;
+ var->transp = frm[i].transp;
+ var->nonstd = frm[i].nonstd;
+ if (fix != NULL) {
+ fix->type = frm[i].type;
+ fix->type_aux = frm[i].type_aux;
+ fix->visual = frm[i].visual;
+ fix->xpanstep = frm[i].xpanstep;
+ }
+ }
+
+ return i;
}
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 689ce0270b8..057bdd59380 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -4,13 +4,13 @@
*
* Author: Hannu Mallat <hmallat@cc.hut.fi>
*
- * Copyright © 1999 Hannu Mallat
+ * Copyright © 1999 Hannu Mallat
* All rights reserved
*
* Created : Thu Sep 23 18:17:43 1999, hmallat
* Last modified: Tue Nov 2 21:19:47 1999, hmallat
*
- * Lots of the information here comes from the Daryll Strauss' Banshee
+ * Lots of the information here comes from the Daryll Strauss' Banshee
* patches to the XF86 server, and the rest comes from the 3dfx
* Banshee specification. I'm very much indebted to Daryll for his
* work on the X server.
@@ -23,7 +23,7 @@
* behave very differently from the Voodoo3/4/5. For anyone wanting to
* use frame buffer on the Voodoo1/2, see the sstfb driver (which is
* located at http://www.sourceforge.net/projects/sstfb).
- *
+ *
* While I _am_ grateful to 3Dfx for releasing the specs for Banshee,
* I do wish the next version is a bit more complete. Without the XF86
* patches I couldn't have gotten even this far... for instance, the
@@ -33,9 +33,8 @@
*
* The structure of this driver comes pretty much from the Permedia
* driver by Ilario Nardinocchi, which in turn is based on skeletonfb.
- *
+ *
* TODO:
- * - support for 16/32 bpp needs fixing (funky bootup penguin)
* - multihead support (basically need to support an array of fb_infos)
* - support other architectures (PPC, Alpha); does the fact that the VGA
* core can be accessed only thru I/O (not memory mapped) complicate
@@ -43,18 +42,18 @@
*
* Version history:
*
- * 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons
+ * 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons
*
- * 0.1.3 (released 1999-11-02) added Attila's panning support, code
- * reorg, hwcursor address page size alignment
- * (for mmaping both frame buffer and regs),
- * and my changes to get rid of hardcoded
- * VGA i/o register locations (uses PCI
- * configuration info now)
- * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and
- * improvements
- * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga.
- * 0.1.0 (released 1999-10-06) initial version
+ * 0.1.3 (released 1999-11-02) added Attila's panning support, code
+ * reorg, hwcursor address page size alignment
+ * (for mmaping both frame buffer and regs),
+ * and my changes to get rid of hardcoded
+ * VGA i/o register locations (uses PCI
+ * configuration info now)
+ * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and
+ * improvements
+ * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga.
+ * 0.1.0 (released 1999-10-06) initial version
*
*/
@@ -64,24 +63,32 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
-#include <linux/nvram.h>
#include <asm/io.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
#include <video/tdfx.h>
-#undef TDFXFB_DEBUG
-#ifdef TDFXFB_DEBUG
-#define DPRINTK(a,b...) printk(KERN_DEBUG "fb: %s: " a, __FUNCTION__ , ## b)
+#define DPRINTK(a, b...) pr_debug("fb: %s: " a, __FUNCTION__ , ## b)
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
#else
-#define DPRINTK(a,b...)
-#endif
+/* duplicate asm/mtrr.h defines to work on archs without mtrr */
+#define MTRR_TYPE_WRCOMB 1
+
+static inline int mtrr_add(unsigned long base, unsigned long size,
+ unsigned int type, char increment)
+{
+ return -ENODEV;
+}
+static inline int mtrr_del(int reg, unsigned long base,
+ unsigned long size)
+{
+ return -ENODEV;
+}
+#endif
#define BANSHEE_MAX_PIXCLOCK 270000
#define VOODOO3_MAX_PIXCLOCK 300000
@@ -90,9 +97,9 @@
static struct fb_fix_screeninfo tdfx_fix __devinitdata = {
.id = "3Dfx",
.type = FB_TYPE_PACKED_PIXELS,
- .visual = FB_VISUAL_PSEUDOCOLOR,
+ .visual = FB_VISUAL_PSEUDOCOLOR,
.ypanstep = 1,
- .ywrapstep = 1,
+ .ywrapstep = 1,
.accel = FB_ACCEL_3DFX_BANSHEE
};
@@ -102,7 +109,7 @@ static struct fb_var_screeninfo tdfx_var __devinitdata = {
.yres = 480,
.xres_virtual = 640,
.yres_virtual = 1024,
- .bits_per_pixel =8,
+ .bits_per_pixel = 8,
.red = {0, 8, 0},
.blue = {0, 8, 0},
.green = {0, 8, 0},
@@ -142,103 +149,79 @@ static struct pci_device_id tdfxfb_id_table[] = {
static struct pci_driver tdfxfb_driver = {
.name = "tdfxfb",
- .id_table = tdfxfb_id_table,
- .probe = tdfxfb_probe,
- .remove = __devexit_p(tdfxfb_remove),
+ .id_table = tdfxfb_id_table,
+ .probe = tdfxfb_probe,
+ .remove = __devexit_p(tdfxfb_remove),
};
MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
/*
- * Frame buffer device API
+ * Driver data
*/
-static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb);
-static int tdfxfb_set_par(struct fb_info *info);
-static int tdfxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-static int tdfxfb_blank(int blank, struct fb_info *info);
-static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
-static int banshee_wait_idle(struct fb_info *info);
-#ifdef CONFIG_FB_3DFX_ACCEL
-static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
-static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image);
-#endif /* CONFIG_FB_3DFX_ACCEL */
-
-static struct fb_ops tdfxfb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = tdfxfb_check_var,
- .fb_set_par = tdfxfb_set_par,
- .fb_setcolreg = tdfxfb_setcolreg,
- .fb_blank = tdfxfb_blank,
- .fb_pan_display = tdfxfb_pan_display,
- .fb_sync = banshee_wait_idle,
-#ifdef CONFIG_FB_3DFX_ACCEL
- .fb_fillrect = tdfxfb_fillrect,
- .fb_copyarea = tdfxfb_copyarea,
- .fb_imageblit = tdfxfb_imageblit,
-#else
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-#endif
-};
-
-/*
- * do_xxx: Hardware-specific functions
- */
-static u32 do_calc_pll(int freq, int *freq_out);
-static void do_write_regs(struct fb_info *info, struct banshee_reg *reg);
-static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short);
-
-/*
- * Driver data
- */
-static int nopan = 0;
-static int nowrap = 1; // not implemented (yet)
-static char *mode_option __devinitdata = NULL;
-
-/* -------------------------------------------------------------------------
- * Hardware-specific funcions
+static int nopan;
+static int nowrap = 1; /* not implemented (yet) */
+static int hwcursor = 1;
+static char *mode_option __devinitdata;
+/* mtrr option */
+static int nomtrr __devinitdata;
+
+/* -------------------------------------------------------------------------
+ * Hardware-specific funcions
* ------------------------------------------------------------------------- */
-#ifdef VGA_REG_IO
-static inline u8 vga_inb(struct tdfx_par *par, u32 reg) { return inb(reg); }
-
-static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) { outb(val, reg); }
-#else
-static inline u8 vga_inb(struct tdfx_par *par, u32 reg) {
- return inb(par->iobase + reg - 0x300);
+static inline u8 vga_inb(struct tdfx_par *par, u32 reg)
+{
+ return inb(par->iobase + reg - 0x300);
}
-static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) {
- outb(val, par->iobase + reg - 0x300);
+
+static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val)
+{
+ outb(val, par->iobase + reg - 0x300);
}
-#endif
-static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) {
- vga_outb(par, GRA_I, idx); vga_outb(par, GRA_D, val);
+static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val)
+{
+ vga_outb(par, GRA_I, idx);
+ wmb();
+ vga_outb(par, GRA_D, val);
+ wmb();
}
-static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) {
- vga_outb(par, SEQ_I, idx); vga_outb(par, SEQ_D, val);
+static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val)
+{
+ vga_outb(par, SEQ_I, idx);
+ wmb();
+ vga_outb(par, SEQ_D, val);
+ wmb();
}
-static inline u8 seq_inb(struct tdfx_par *par, u32 idx) {
- vga_outb(par, SEQ_I, idx); return vga_inb(par, SEQ_D);
+static inline u8 seq_inb(struct tdfx_par *par, u32 idx)
+{
+ vga_outb(par, SEQ_I, idx);
+ mb();
+ return vga_inb(par, SEQ_D);
}
-static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) {
- vga_outb(par, CRT_I, idx); vga_outb(par, CRT_D, val);
+static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val)
+{
+ vga_outb(par, CRT_I, idx);
+ wmb();
+ vga_outb(par, CRT_D, val);
+ wmb();
}
-static inline u8 crt_inb(struct tdfx_par *par, u32 idx) {
- vga_outb(par, CRT_I, idx); return vga_inb(par, CRT_D);
+static inline u8 crt_inb(struct tdfx_par *par, u32 idx)
+{
+ vga_outb(par, CRT_I, idx);
+ mb();
+ return vga_inb(par, CRT_D);
}
-static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val)
+static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val)
{
unsigned char tmp;
-
+
tmp = vga_inb(par, IS1_R);
vga_outb(par, ATT_IW, idx);
vga_outb(par, ATT_IW, val);
@@ -267,10 +250,11 @@ static inline void vga_enable_video(struct tdfx_par *par)
static inline void vga_enable_palette(struct tdfx_par *par)
{
vga_inb(par, IS1_R);
+ mb();
vga_outb(par, ATT_IW, 0x20);
}
-static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg)
+static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg)
{
return readl(par->regbase_virt + reg);
}
@@ -284,9 +268,10 @@ static inline void banshee_make_room(struct tdfx_par *par, int size)
{
/* Note: The Voodoo3's onboard FIFO has 32 slots. This loop
* won't quit if you ask for more. */
- while((tdfx_inl(par, STATUS) & 0x1f) < size-1);
+ while ((tdfx_inl(par, STATUS) & 0x1f) < size - 1)
+ cpu_relax();
}
-
+
static int banshee_wait_idle(struct fb_info *info)
{
struct tdfx_par *par = info->par;
@@ -295,28 +280,31 @@ static int banshee_wait_idle(struct fb_info *info)
banshee_make_room(par, 1);
tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP);
- while(1) {
- i = (tdfx_inl(par, STATUS) & STATUS_BUSY) ? 0 : i + 1;
- if(i == 3) break;
- }
+ do {
+ if ((tdfx_inl(par, STATUS) & STATUS_BUSY) == 0)
+ i++;
+ } while (i < 3);
+
return 0;
}
/*
- * Set the color of a palette entry in 8bpp mode
+ * Set the color of a palette entry in 8bpp mode
*/
static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
-{
+{
banshee_make_room(par, 2);
tdfx_outl(par, DACADDR, regno);
+ /* read after write makes it working */
+ tdfx_inl(par, DACADDR);
tdfx_outl(par, DACDATA, c);
}
-static u32 do_calc_pll(int freq, int* freq_out)
+static u32 do_calc_pll(int freq, int *freq_out)
{
int m, n, k, best_m, best_n, best_k, best_error;
int fref = 14318;
-
+
best_error = freq;
best_n = best_m = best_k = 0;
@@ -326,27 +314,28 @@ static u32 do_calc_pll(int freq, int* freq_out)
* Estimate value of n that produces target frequency
* with current m and k
*/
- int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2;
+ int n_estimated = ((freq * (m + 2) << k) / fref) - 2;
/* Search neighborhood of estimated n */
- for (n = max(0, n_estimated - 1);
- n <= min(255, n_estimated + 1); n++) {
+ for (n = max(0, n_estimated);
+ n <= min(255, n_estimated + 1);
+ n++) {
/*
* Calculate PLL freqency with current m, k and
* estimated n
*/
- int f = fref * (n + 2) / (m + 2) / (1 << k);
- int error = abs (f - freq);
+ int f = (fref * (n + 2) / (m + 2)) >> k;
+ int error = abs(f - freq);
/*
- * If this is the closest we've come to the
+ * If this is the closest we've come to the
* target frequency then remember n, m and k
*/
- if (error < best_error) {
+ if (error < best_error) {
best_error = error;
- best_n = n;
- best_m = m;
- best_k = k;
+ best_n = n;
+ best_m = m;
+ best_k = k;
}
}
}
@@ -355,12 +344,12 @@ static u32 do_calc_pll(int freq, int* freq_out)
n = best_n;
m = best_m;
k = best_k;
- *freq_out = fref*(n + 2)/(m + 2)/(1 << k);
+ *freq_out = (fref * (n + 2) / (m + 2)) >> k;
return (n << 8) | (m << 2) | k;
}
-static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
+static void do_write_regs(struct fb_info *info, struct banshee_reg *reg)
{
struct tdfx_par *par = info->par;
int i;
@@ -372,13 +361,13 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */
banshee_make_room(par, 3);
- tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF);
- tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001);
+ tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF);
+ tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001);
#if 0
tdfx_outl(par, PLLCTRL1, reg->mempll);
tdfx_outl(par, PLLCTRL2, reg->gfxpll);
#endif
- tdfx_outl(par, PLLCTRL0, reg->vidpll);
+ tdfx_outl(par, PLLCTRL0, reg->vidpll);
vga_outb(par, MISC_W, reg->misc[0x00] | 0x01);
@@ -400,72 +389,65 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
vga_enable_palette(par);
vga_enable_video(par);
- banshee_make_room(par, 11);
- tdfx_outl(par, VGAINIT0, reg->vgainit0);
- tdfx_outl(par, DACMODE, reg->dacmode);
- tdfx_outl(par, VIDDESKSTRIDE, reg->stride);
- tdfx_outl(par, HWCURPATADDR, 0);
-
- tdfx_outl(par, VIDSCREENSIZE,reg->screensize);
- tdfx_outl(par, VIDDESKSTART, reg->startaddr);
- tdfx_outl(par, VIDPROCCFG, reg->vidcfg);
- tdfx_outl(par, VGAINIT1, reg->vgainit1);
- tdfx_outl(par, MISCINIT0, reg->miscinit0);
-
- banshee_make_room(par, 8);
- tdfx_outl(par, SRCBASE, reg->srcbase);
- tdfx_outl(par, DSTBASE, reg->dstbase);
- tdfx_outl(par, COMMANDEXTRA_2D, 0);
- tdfx_outl(par, CLIP0MIN, 0);
- tdfx_outl(par, CLIP0MAX, 0x0fff0fff);
- tdfx_outl(par, CLIP1MIN, 0);
- tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
- tdfx_outl(par, SRCXY, 0);
+ banshee_make_room(par, 9);
+ tdfx_outl(par, VGAINIT0, reg->vgainit0);
+ tdfx_outl(par, DACMODE, reg->dacmode);
+ tdfx_outl(par, VIDDESKSTRIDE, reg->stride);
+ tdfx_outl(par, HWCURPATADDR, reg->curspataddr);
+
+ tdfx_outl(par, VIDSCREENSIZE, reg->screensize);
+ tdfx_outl(par, VIDDESKSTART, reg->startaddr);
+ tdfx_outl(par, VIDPROCCFG, reg->vidcfg);
+ tdfx_outl(par, VGAINIT1, reg->vgainit1);
+ tdfx_outl(par, MISCINIT0, reg->miscinit0);
+
+ banshee_make_room(par, 8);
+ tdfx_outl(par, SRCBASE, reg->startaddr);
+ tdfx_outl(par, DSTBASE, reg->startaddr);
+ tdfx_outl(par, COMMANDEXTRA_2D, 0);
+ tdfx_outl(par, CLIP0MIN, 0);
+ tdfx_outl(par, CLIP0MAX, 0x0fff0fff);
+ tdfx_outl(par, CLIP1MIN, 0);
+ tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
+ tdfx_outl(par, SRCXY, 0);
banshee_wait_idle(info);
}
-static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
+static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
{
- u32 draminit0;
- u32 draminit1;
+ u32 draminit0 = tdfx_inl(par, DRAMINIT0);
+ u32 draminit1 = tdfx_inl(par, DRAMINIT1);
u32 miscinit1;
-
- int num_chips;
+ int num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
int chip_size; /* in MB */
- u32 lfbsize;
- int has_sgram;
+ int has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
- draminit0 = tdfx_inl(par, DRAMINIT0);
- draminit1 = tdfx_inl(par, DRAMINIT1);
-
- num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
-
if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) {
/* Banshee/Voodoo3 */
- has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
- chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1)
- : 2;
+ chip_size = 2;
+ if (has_sgram && (draminit0 & DRAMINIT0_SGRAM_TYPE))
+ chip_size = 1;
} else {
/* Voodoo4/5 */
has_sgram = 0;
- chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT);
+ chip_size = draminit0 & DRAMINIT0_SGRAM_TYPE_MASK;
+ chip_size = 1 << (chip_size >> DRAMINIT0_SGRAM_TYPE_SHIFT);
}
- lfbsize = num_chips * chip_size * 1024 * 1024;
/* disable block writes for SDRAM */
miscinit1 = tdfx_inl(par, MISCINIT1);
miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS;
miscinit1 |= MISCINIT1_CLUT_INV;
- banshee_make_room(par, 1);
+ banshee_make_room(par, 1);
tdfx_outl(par, MISCINIT1, miscinit1);
- return lfbsize;
+ return num_chips * chip_size * 1024l * 1024;
}
/* ------------------------------------------------------------------------- */
-static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info)
+static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct tdfx_par *par = info->par;
u32 lpitch;
@@ -486,103 +468,113 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info)
DPRINTK("xoffset not supported\n");
return -EINVAL;
}
+ var->yoffset = 0;
- /* Banshee doesn't support interlace, but Voodoo4/5 and probably Voodoo3 do. */
- /* no direct information about device id now? use max_pixclock for this... */
+ /*
+ * Banshee doesn't support interlace, but Voodoo4/5 and probably
+ * Voodoo3 do.
+ * no direct information about device id now?
+ * use max_pixclock for this...
+ */
if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) &&
- (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) {
+ (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) {
DPRINTK("interlace not supported\n");
return -EINVAL;
}
var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
- lpitch = var->xres * ((var->bits_per_pixel + 7)>>3);
-
+ lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
+
if (var->xres < 320 || var->xres > 2048) {
DPRINTK("width not supported: %u\n", var->xres);
return -EINVAL;
}
-
+
if (var->yres < 200 || var->yres > 2048) {
DPRINTK("height not supported: %u\n", var->yres);
return -EINVAL;
}
-
+
if (lpitch * var->yres_virtual > info->fix.smem_len) {
- var->yres_virtual = info->fix.smem_len/lpitch;
+ var->yres_virtual = info->fix.smem_len / lpitch;
if (var->yres_virtual < var->yres) {
DPRINTK("no memory for screen (%ux%ux%u)\n",
- var->xres, var->yres_virtual, var->bits_per_pixel);
+ var->xres, var->yres_virtual,
+ var->bits_per_pixel);
return -EINVAL;
}
}
-
+
if (PICOS2KHZ(var->pixclock) > par->max_pixclock) {
- DPRINTK("pixclock too high (%ldKHz)\n",PICOS2KHZ(var->pixclock));
+ DPRINTK("pixclock too high (%ldKHz)\n",
+ PICOS2KHZ(var->pixclock));
return -EINVAL;
}
- switch(var->bits_per_pixel) {
- case 8:
- var->red.length = var->green.length = var->blue.length = 8;
- break;
- case 16:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- break;
- case 24:
- var->red.offset=16;
- var->green.offset=8;
- var->blue.offset=0;
- var->red.length = var->green.length = var->blue.length = 8;
- case 32:
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 8;
- break;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ switch (var->bits_per_pixel) {
+ case 8:
+ var->red.length = 8;
+ var->red.offset = 0;
+ var->green = var->red;
+ var->blue = var->red;
+ break;
+ case 16:
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ break;
+ case 32:
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ case 24:
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 8;
+ break;
}
- var->height = var->width = -1;
-
+ var->width = -1;
+ var->height = -1;
+
var->accel_flags = FB_ACCELF_TEXT;
-
- DPRINTK("Checking graphics mode at %dx%d depth %d\n", var->xres, var->yres, var->bits_per_pixel);
+
+ DPRINTK("Checking graphics mode at %dx%d depth %d\n",
+ var->xres, var->yres, var->bits_per_pixel);
return 0;
}
static int tdfxfb_set_par(struct fb_info *info)
{
struct tdfx_par *par = info->par;
- u32 hdispend, hsyncsta, hsyncend, htotal;
+ u32 hdispend = info->var.xres;
+ u32 hsyncsta = hdispend + info->var.right_margin;
+ u32 hsyncend = hsyncsta + info->var.hsync_len;
+ u32 htotal = hsyncend + info->var.left_margin;
u32 hd, hs, he, ht, hbs, hbe;
u32 vd, vs, ve, vt, vbs, vbe;
struct banshee_reg reg;
int fout, freq;
- u32 wd, cpp;
-
- par->baseline = 0;
-
+ u32 wd;
+ u32 cpp = (info->var.bits_per_pixel + 7) >> 3;
+
memset(&reg, 0, sizeof(reg));
- cpp = (info->var.bits_per_pixel + 7)/8;
-
- reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE | VIDCFG_CURS_X11 | ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) | (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
+
+ reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE |
+ VIDCFG_CURS_X11 |
+ ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
+ (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
/* PLL settings */
freq = PICOS2KHZ(info->var.pixclock);
- reg.dacmode = 0;
- reg.vidcfg &= ~VIDCFG_2X;
-
- hdispend = info->var.xres;
- hsyncsta = hdispend + info->var.right_margin;
- hsyncend = hsyncsta + info->var.hsync_len;
- htotal = hsyncend + info->var.left_margin;
+ reg.vidcfg &= ~VIDCFG_2X;
- if (freq > par->max_pixclock/2) {
+ if (freq > par->max_pixclock / 2) {
freq = freq > par->max_pixclock ? par->max_pixclock : freq;
reg.dacmode |= DACMODE_2X;
reg.vidcfg |= VIDCFG_2X;
@@ -591,8 +583,9 @@ static int tdfxfb_set_par(struct fb_info *info)
hsyncend >>= 1;
htotal >>= 1;
}
-
- hd = wd = (hdispend >> 3) - 1;
+
+ wd = (hdispend >> 3) - 1;
+ hd = wd;
hs = (hsyncsta >> 3) - 1;
he = (hsyncend >> 3) - 1;
ht = (htotal >> 3) - 1;
@@ -600,28 +593,30 @@ static int tdfxfb_set_par(struct fb_info *info)
hbe = ht;
if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- vbs = vd = (info->var.yres << 1) - 1;
+ vd = (info->var.yres << 1) - 1;
vs = vd + (info->var.lower_margin << 1);
ve = vs + (info->var.vsync_len << 1);
- vbe = vt = ve + (info->var.upper_margin << 1) - 1;
+ vt = ve + (info->var.upper_margin << 1) - 1;
+ reg.screensize = info->var.xres | (info->var.yres << 13);
+ reg.vidcfg |= VIDCFG_HALF_MODE;
+ reg.crt[0x09] = 0x80;
} else {
- vbs = vd = info->var.yres - 1;
+ vd = info->var.yres - 1;
vs = vd + info->var.lower_margin;
ve = vs + info->var.vsync_len;
- vbe = vt = ve + info->var.upper_margin - 1;
+ vt = ve + info->var.upper_margin - 1;
+ reg.screensize = info->var.xres | (info->var.yres << 12);
+ reg.vidcfg &= ~VIDCFG_HALF_MODE;
}
-
+ vbs = vd;
+ vbe = vt;
+
/* this is all pretty standard VGA register stuffing */
- reg.misc[0x00] = 0x0f |
+ reg.misc[0x00] = 0x0f |
(info->var.xres < 400 ? 0xa0 :
info->var.xres < 480 ? 0x60 :
info->var.xres < 768 ? 0xe0 : 0x20);
-
- reg.gra[0x00] = 0x00;
- reg.gra[0x01] = 0x00;
- reg.gra[0x02] = 0x00;
- reg.gra[0x03] = 0x00;
- reg.gra[0x04] = 0x00;
+
reg.gra[0x05] = 0x40;
reg.gra[0x06] = 0x05;
reg.gra[0x07] = 0x0f;
@@ -644,10 +639,7 @@ static int tdfxfb_set_par(struct fb_info *info)
reg.att[0x0e] = 0x0e;
reg.att[0x0f] = 0x0f;
reg.att[0x10] = 0x41;
- reg.att[0x11] = 0x00;
reg.att[0x12] = 0x0f;
- reg.att[0x13] = 0x00;
- reg.att[0x14] = 0x00;
reg.seq[0x00] = 0x03;
reg.seq[0x01] = 0x01; /* fixme: clkdiv2? */
@@ -660,146 +652,133 @@ static int tdfxfb_set_par(struct fb_info *info)
reg.crt[0x02] = hbs;
reg.crt[0x03] = 0x80 | (hbe & 0x1f);
reg.crt[0x04] = hs;
- reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+ reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
reg.crt[0x06] = vt;
reg.crt[0x07] = ((vs & 0x200) >> 2) |
((vd & 0x200) >> 3) |
((vt & 0x200) >> 4) | 0x10 |
((vbs & 0x100) >> 5) |
- ((vs & 0x100) >> 6) |
- ((vd & 0x100) >> 7) |
- ((vt & 0x100) >> 8);
- reg.crt[0x08] = 0x00;
- reg.crt[0x09] = 0x40 | ((vbs & 0x200) >> 4);
- reg.crt[0x0a] = 0x00;
- reg.crt[0x0b] = 0x00;
- reg.crt[0x0c] = 0x00;
- reg.crt[0x0d] = 0x00;
- reg.crt[0x0e] = 0x00;
- reg.crt[0x0f] = 0x00;
+ ((vs & 0x100) >> 6) |
+ ((vd & 0x100) >> 7) |
+ ((vt & 0x100) >> 8);
+ reg.crt[0x09] |= 0x40 | ((vbs & 0x200) >> 4);
reg.crt[0x10] = vs;
- reg.crt[0x11] = (ve & 0x0f) | 0x20;
+ reg.crt[0x11] = (ve & 0x0f) | 0x20;
reg.crt[0x12] = vd;
reg.crt[0x13] = wd;
- reg.crt[0x14] = 0x00;
reg.crt[0x15] = vbs;
- reg.crt[0x16] = vbe + 1;
+ reg.crt[0x16] = vbe + 1;
reg.crt[0x17] = 0xc3;
reg.crt[0x18] = 0xff;
-
+
/* Banshee's nonvga stuff */
- reg.ext[0x00] = (((ht & 0x100) >> 8) |
- ((hd & 0x100) >> 6) |
+ reg.ext[0x00] = (((ht & 0x100) >> 8) |
+ ((hd & 0x100) >> 6) |
((hbs & 0x100) >> 4) |
- ((hbe & 0x40) >> 1) |
- ((hs & 0x100) >> 2) |
- ((he & 0x20) << 2));
- reg.ext[0x01] = (((vt & 0x400) >> 10) |
- ((vd & 0x400) >> 8) |
- ((vbs & 0x400) >> 6) |
- ((vbe & 0x400) >> 4));
-
- reg.vgainit0 = VGAINIT0_8BIT_DAC |
+ ((hbe & 0x40) >> 1) |
+ ((hs & 0x100) >> 2) |
+ ((he & 0x20) << 2));
+ reg.ext[0x01] = (((vt & 0x400) >> 10) |
+ ((vd & 0x400) >> 8) |
+ ((vbs & 0x400) >> 6) |
+ ((vbe & 0x400) >> 4));
+
+ reg.vgainit0 = VGAINIT0_8BIT_DAC |
VGAINIT0_EXT_ENABLE |
VGAINIT0_WAKEUP_3C3 |
VGAINIT0_ALT_READBACK |
VGAINIT0_EXTSHIFTOUT;
reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff;
+ if (hwcursor)
+ reg.curspataddr = info->fix.smem_len;
+
reg.cursloc = 0;
-
- reg.cursc0 = 0;
+
+ reg.cursc0 = 0;
reg.cursc1 = 0xffffff;
-
- reg.stride = info->var.xres * cpp;
- reg.startaddr = par->baseline * reg.stride;
- reg.srcbase = reg.startaddr;
- reg.dstbase = reg.startaddr;
- /* PLL settings */
- freq = PICOS2KHZ(info->var.pixclock);
+ reg.stride = info->var.xres * cpp;
+ reg.startaddr = info->var.yoffset * reg.stride
+ + info->var.xoffset * cpp;
- reg.dacmode &= ~DACMODE_2X;
- reg.vidcfg &= ~VIDCFG_2X;
- if (freq > par->max_pixclock/2) {
- freq = freq > par->max_pixclock ? par->max_pixclock : freq;
- reg.dacmode |= DACMODE_2X;
- reg.vidcfg |= VIDCFG_2X;
- }
reg.vidpll = do_calc_pll(freq, &fout);
#if 0
reg.mempll = do_calc_pll(..., &fout);
reg.gfxpll = do_calc_pll(..., &fout);
#endif
- if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
- reg.screensize = info->var.xres | (info->var.yres << 13);
- reg.vidcfg |= VIDCFG_HALF_MODE;
- reg.crt[0x09] |= 0x80;
- } else {
- reg.screensize = info->var.xres | (info->var.yres << 12);
- reg.vidcfg &= ~VIDCFG_HALF_MODE;
- }
if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
reg.vidcfg |= VIDCFG_INTERLACE;
reg.miscinit0 = tdfx_inl(par, MISCINIT0);
#if defined(__BIG_ENDIAN)
switch (info->var.bits_per_pixel) {
- case 8:
- case 24:
- reg.miscinit0 &= ~(1 << 30);
- reg.miscinit0 &= ~(1 << 31);
- break;
- case 16:
- reg.miscinit0 |= (1 << 30);
- reg.miscinit0 |= (1 << 31);
- break;
- case 32:
- reg.miscinit0 |= (1 << 30);
- reg.miscinit0 &= ~(1 << 31);
- break;
+ case 8:
+ case 24:
+ reg.miscinit0 &= ~(1 << 30);
+ reg.miscinit0 &= ~(1 << 31);
+ break;
+ case 16:
+ reg.miscinit0 |= (1 << 30);
+ reg.miscinit0 |= (1 << 31);
+ break;
+ case 32:
+ reg.miscinit0 |= (1 << 30);
+ reg.miscinit0 &= ~(1 << 31);
+ break;
}
-#endif
+#endif
do_write_regs(info, &reg);
/* Now change fb_fix_screeninfo according to changes in par */
- info->fix.line_length = info->var.xres * ((info->var.bits_per_pixel + 7)>>3);
- info->fix.visual = (info->var.bits_per_pixel == 8)
+ info->fix.line_length = reg.stride;
+ info->fix.visual = (info->var.bits_per_pixel == 8)
? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_TRUECOLOR;
- DPRINTK("Graphics mode is now set at %dx%d depth %d\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
- return 0;
+ DPRINTK("Graphics mode is now set at %dx%d depth %d\n",
+ info->var.xres, info->var.yres, info->var.bits_per_pixel);
+ return 0;
}
/* A handy macro shamelessly pinched from matroxfb */
-#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
-static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue,unsigned transp,struct fb_info *info)
+static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
{
struct tdfx_par *par = info->par;
u32 rgbcol;
-
- if (regno >= info->cmap.len || regno > 255) return 1;
-
+
+ if (regno >= info->cmap.len || regno > 255)
+ return 1;
+
+ /* grayscale works only partially under directcolor */
+ if (info->var.grayscale) {
+ /* grayscale = 0.30*R + 0.59*G + 0.11*B */
+ blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ green = blue;
+ red = blue;
+ }
+
switch (info->fix.visual) {
case FB_VISUAL_PSEUDOCOLOR:
- rgbcol =(((u32)red & 0xff00) << 8) |
- (((u32)green & 0xff00) << 0) |
- (((u32)blue & 0xff00) >> 8);
+ rgbcol = (((u32)red & 0xff00) << 8) |
+ (((u32)green & 0xff00) << 0) |
+ (((u32)blue & 0xff00) >> 8);
do_setpalentry(par, regno, rgbcol);
break;
/* Truecolor has no hardware color palettes. */
case FB_VISUAL_TRUECOLOR:
if (regno < 16) {
- rgbcol = (CNVT_TOHW( red, info->var.red.length) <<
+ rgbcol = (CNVT_TOHW(red, info->var.red.length) <<
info->var.red.offset) |
- (CNVT_TOHW( green, info->var.green.length) <<
+ (CNVT_TOHW(green, info->var.green.length) <<
info->var.green.offset) |
- (CNVT_TOHW( blue, info->var.blue.length) <<
+ (CNVT_TOHW(blue, info->var.blue.length) <<
info->var.blue.offset) |
- (CNVT_TOHW( transp, info->var.transp.length) <<
+ (CNVT_TOHW(transp, info->var.transp.length) <<
info->var.transp.offset);
par->palette[regno] = rgbcol;
}
@@ -815,287 +794,325 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
static int tdfxfb_blank(int blank, struct fb_info *info)
-{
+{
struct tdfx_par *par = info->par;
- u32 dacmode, state = 0, vgablank = 0;
+ int vgablank = 1;
+ u32 dacmode = tdfx_inl(par, DACMODE);
- dacmode = tdfx_inl(par, DACMODE);
+ dacmode &= ~(BIT(1) | BIT(3));
switch (blank) {
- case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */
- state = 0;
- vgablank = 0;
- break;
- case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */
- state = 0;
- vgablank = 1;
- break;
- case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */
- state = BIT(3);
- vgablank = 1;
- break;
- case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */
- state = BIT(1);
- vgablank = 1;
- break;
- case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
- state = BIT(1) | BIT(3);
- vgablank = 1;
- break;
+ case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */
+ vgablank = 0;
+ break;
+ case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */
+ break;
+ case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */
+ dacmode |= BIT(3);
+ break;
+ case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */
+ dacmode |= BIT(1);
+ break;
+ case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
+ dacmode |= BIT(1) | BIT(3);
+ break;
}
- dacmode &= ~(BIT(1) | BIT(3));
- dacmode |= state;
- banshee_make_room(par, 1);
+ banshee_make_room(par, 1);
tdfx_outl(par, DACMODE, dacmode);
- if (vgablank)
+ if (vgablank)
vga_disable_video(par);
else
vga_enable_video(par);
return 0;
}
-/*
+/*
* Set the starting position of the visible screen to var->yoffset
- */
+ */
static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
+ struct fb_info *info)
{
struct tdfx_par *par = info->par;
- u32 addr;
+ u32 addr = var->yoffset * info->fix.line_length;
if (nopan || var->xoffset || (var->yoffset > var->yres_virtual))
return -EINVAL;
if ((var->yoffset + var->yres > var->yres_virtual && nowrap))
return -EINVAL;
- addr = var->yoffset * info->fix.line_length;
banshee_make_room(par, 1);
tdfx_outl(par, VIDDESKSTART, addr);
-
+
info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
+ info->var.yoffset = var->yoffset;
return 0;
}
#ifdef CONFIG_FB_3DFX_ACCEL
/*
- * FillRect 2D command (solidfill or invert (via ROP_XOR))
+ * FillRect 2D command (solidfill or invert (via ROP_XOR))
*/
-static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+static void tdfxfb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
{
struct tdfx_par *par = info->par;
u32 bpp = info->var.bits_per_pixel;
u32 stride = info->fix.line_length;
- u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13);
+ u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
int tdfx_rop;
-
- if (rect->rop == ROP_COPY)
+ u32 dx = rect->dx;
+ u32 dy = rect->dy;
+ u32 dstbase = 0;
+
+ if (rect->rop == ROP_COPY)
tdfx_rop = TDFX_ROP_COPY;
- else
+ else
tdfx_rop = TDFX_ROP_XOR;
- banshee_make_room(par, 5);
- tdfx_outl(par, DSTFORMAT, fmt);
+ /* asume always rect->height < 4096 */
+ if (dy + rect->height > 4095) {
+ dstbase = stride * dy;
+ dy = 0;
+ }
+ /* asume always rect->width < 4096 */
+ if (dx + rect->width > 4095) {
+ dstbase += dx * bpp >> 3;
+ dx = 0;
+ }
+ banshee_make_room(par, 6);
+ tdfx_outl(par, DSTFORMAT, fmt);
if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
- tdfx_outl(par, COLORFORE, rect->color);
+ tdfx_outl(par, COLORFORE, rect->color);
} else { /* FB_VISUAL_TRUECOLOR */
tdfx_outl(par, COLORFORE, par->palette[rect->color]);
}
- tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
- tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
- tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16));
+ tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
+ tdfx_outl(par, DSTBASE, dstbase);
+ tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
+ tdfx_outl(par, LAUNCH_2D, dx | (dy << 16));
}
/*
- * Screen-to-Screen BitBlt 2D command (for the bmove fb op.)
+ * Screen-to-Screen BitBlt 2D command (for the bmove fb op.)
*/
-static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void tdfxfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
{
struct tdfx_par *par = info->par;
- u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
+ u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
u32 bpp = info->var.bits_per_pixel;
u32 stride = info->fix.line_length;
u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
- u32 fmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13);
-
+ u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
+ u32 dstbase = 0;
+ u32 srcbase = 0;
+
+ /* asume always area->height < 4096 */
+ if (sy + area->height > 4095) {
+ srcbase = stride * sy;
+ sy = 0;
+ }
+ /* asume always area->width < 4096 */
+ if (sx + area->width > 4095) {
+ srcbase += sx * bpp >> 3;
+ sx = 0;
+ }
+ /* asume always area->height < 4096 */
+ if (dy + area->height > 4095) {
+ dstbase = stride * dy;
+ dy = 0;
+ }
+ /* asume always area->width < 4096 */
+ if (dx + area->width > 4095) {
+ dstbase += dx * bpp >> 3;
+ dx = 0;
+ }
+
if (area->sx <= area->dx) {
- //-X
+ /* -X */
blitcmd |= BIT(14);
sx += area->width - 1;
dx += area->width - 1;
}
if (area->sy <= area->dy) {
- //-Y
+ /* -Y */
blitcmd |= BIT(15);
sy += area->height - 1;
dy += area->height - 1;
}
-
- banshee_make_room(par, 6);
- tdfx_outl(par, SRCFORMAT, fmt);
- tdfx_outl(par, DSTFORMAT, fmt);
- tdfx_outl(par, COMMAND_2D, blitcmd);
- tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
- tdfx_outl(par, DSTXY, dx | (dy << 16));
- tdfx_outl(par, LAUNCH_2D, sx | (sy << 16));
+ banshee_make_room(par, 8);
+
+ tdfx_outl(par, SRCFORMAT, fmt);
+ tdfx_outl(par, DSTFORMAT, fmt);
+ tdfx_outl(par, COMMAND_2D, blitcmd);
+ tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
+ tdfx_outl(par, DSTXY, dx | (dy << 16));
+ tdfx_outl(par, SRCBASE, srcbase);
+ tdfx_outl(par, DSTBASE, dstbase);
+ tdfx_outl(par, LAUNCH_2D, sx | (sy << 16));
}
-static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct tdfx_par *par = info->par;
- int size = image->height * ((image->width * image->depth + 7)>>3);
+ int size = image->height * ((image->width * image->depth + 7) >> 3);
int fifo_free;
int i, stride = info->fix.line_length;
u32 bpp = info->var.bits_per_pixel;
- u32 dstfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13);
+ u32 dstfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
u8 *chardata = (u8 *) image->data;
u32 srcfmt;
+ u32 dx = image->dx;
+ u32 dy = image->dy;
+ u32 dstbase = 0;
if (image->depth != 1) {
- //banshee_make_room(par, 6 + ((size + 3) >> 2));
- //srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
+#ifdef BROKEN_CODE
+ banshee_make_room(par, 6 + ((size + 3) >> 2));
+ srcfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13) |
+ 0x400000;
+#else
cfb_imageblit(info, image);
+#endif
return;
- } else {
- banshee_make_room(par, 8);
- switch (info->fix.visual) {
- case FB_VISUAL_PSEUDOCOLOR:
+ }
+ banshee_make_room(par, 9);
+ switch (info->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
tdfx_outl(par, COLORFORE, image->fg_color);
tdfx_outl(par, COLORBACK, image->bg_color);
- break;
- case FB_VISUAL_TRUECOLOR:
- default:
- tdfx_outl(par, COLORFORE,
- par->palette[image->fg_color]);
- tdfx_outl(par, COLORBACK,
- par->palette[image->bg_color]);
- }
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ default:
+ tdfx_outl(par, COLORFORE,
+ par->palette[image->fg_color]);
+ tdfx_outl(par, COLORBACK,
+ par->palette[image->bg_color]);
+ }
#ifdef __BIG_ENDIAN
- srcfmt = 0x400000 | BIT(20);
+ srcfmt = 0x400000 | BIT(20);
#else
- srcfmt = 0x400000;
+ srcfmt = 0x400000;
#endif
- }
+ /* asume always image->height < 4096 */
+ if (dy + image->height > 4095) {
+ dstbase = stride * dy;
+ dy = 0;
+ }
+ /* asume always image->width < 4096 */
+ if (dx + image->width > 4095) {
+ dstbase += dx * bpp >> 3;
+ dx = 0;
+ }
- tdfx_outl(par, SRCXY, 0);
- tdfx_outl(par, DSTXY, image->dx | (image->dy << 16));
- tdfx_outl(par, COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
- tdfx_outl(par, SRCFORMAT, srcfmt);
- tdfx_outl(par, DSTFORMAT, dstfmt);
- tdfx_outl(par, DSTSIZE, image->width | (image->height << 16));
+ tdfx_outl(par, DSTBASE, dstbase);
+ tdfx_outl(par, SRCXY, 0);
+ tdfx_outl(par, DSTXY, dx | (dy << 16));
+ tdfx_outl(par, COMMAND_2D,
+ COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
+ tdfx_outl(par, SRCFORMAT, srcfmt);
+ tdfx_outl(par, DSTFORMAT, dstfmt);
+ tdfx_outl(par, DSTSIZE, image->width | (image->height << 16));
/* A count of how many free FIFO entries we've requested.
* When this goes negative, we need to request more. */
fifo_free = 0;
- /* Send four bytes at a time of data */
- for (i = (size >> 2) ; i > 0; i--) {
- if(--fifo_free < 0) {
- fifo_free=31;
- banshee_make_room(par,fifo_free);
+ /* Send four bytes at a time of data */
+ for (i = (size >> 2); i > 0; i--) {
+ if (--fifo_free < 0) {
+ fifo_free = 31;
+ banshee_make_room(par, fifo_free);
}
- tdfx_outl(par, LAUNCH_2D,*(u32*)chardata);
- chardata += 4;
- }
-
- /* Send the leftovers now */
- banshee_make_room(par,3);
- i = size%4;
- switch (i) {
- case 0: break;
- case 1: tdfx_outl(par, LAUNCH_2D,*chardata); break;
- case 2: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata); break;
- case 3: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
+ tdfx_outl(par, LAUNCH_2D, *(u32 *)chardata);
+ chardata += 4;
+ }
+
+ /* Send the leftovers now */
+ banshee_make_room(par, 3);
+ switch (size % 4) {
+ case 0:
+ break;
+ case 1:
+ tdfx_outl(par, LAUNCH_2D, *chardata);
+ break;
+ case 2:
+ tdfx_outl(par, LAUNCH_2D, *(u16 *)chardata);
+ break;
+ case 3:
+ tdfx_outl(par, LAUNCH_2D,
+ *(u16 *)chardata | (chardata[3] << 24));
+ break;
}
}
#endif /* CONFIG_FB_3DFX_ACCEL */
-#ifdef TDFX_HARDWARE_CURSOR
static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
struct tdfx_par *par = info->par;
- unsigned long flags;
+ u32 vidcfg;
- /*
- * If the cursor is not be changed this means either we want the
- * current cursor state (if enable is set) or we want to query what
- * we can do with the cursor (if enable is not set)
- */
- if (!cursor->set) return 0;
+ if (!hwcursor)
+ return -EINVAL; /* just to force soft_cursor() call */
- /* Too large of a cursor :-( */
- if (cursor->image.width > 64 || cursor->image.height > 64)
- return -ENXIO;
+ /* Too large of a cursor or wrong bpp :-( */
+ if (cursor->image.width > 64 ||
+ cursor->image.height > 64 ||
+ cursor->image.depth > 1)
+ return -EINVAL;
- /*
- * If we are going to be changing things we should disable
- * the cursor first
- */
- if (info->cursor.enable) {
- spin_lock_irqsave(&par->DAClock, flags);
- info->cursor.enable = 0;
- del_timer(&(par->hwcursor.timer));
- tdfx_outl(par, VIDPROCCFG, par->hwcursor.disable);
- spin_unlock_irqrestore(&par->DAClock, flags);
- }
+ vidcfg = tdfx_inl(par, VIDPROCCFG);
+ if (cursor->enable)
+ tdfx_outl(par, VIDPROCCFG, vidcfg | VIDCFG_HWCURSOR_ENABLE);
+ else
+ tdfx_outl(par, VIDPROCCFG, vidcfg & ~VIDCFG_HWCURSOR_ENABLE);
- /* Disable the Cursor */
- if ((cursor->set && FB_CUR_SETCUR) && !cursor->enable)
+ /*
+ * If the cursor is not be changed this means either we want the
+ * current cursor state (if enable is set) or we want to query what
+ * we can do with the cursor (if enable is not set)
+ */
+ if (!cursor->set)
return 0;
/* fix cursor color - XFree86 forgets to restore it properly */
- if (cursor->set && FB_CUR_SETCMAP) {
- struct fb_cmap cmap = cursor->image.cmap;
+ if (cursor->set & FB_CUR_SETCMAP) {
+ struct fb_cmap cmap = info->cmap;
+ u32 bg_idx = cursor->image.bg_color;
+ u32 fg_idx = cursor->image.fg_color;
unsigned long bg_color, fg_color;
- cmap.len = 2; /* Voodoo 3+ only support 2 color cursors */
- fg_color = ((cmap.red[cmap.start] << 16) |
- (cmap.green[cmap.start] << 8) |
- (cmap.blue[cmap.start]));
- bg_color = ((cmap.red[cmap.start+1] << 16) |
- (cmap.green[cmap.start+1] << 8) |
- (cmap.blue[cmap.start+1]));
- fb_copy_cmap(&cmap, &info->cursor.image.cmap);
- spin_lock_irqsave(&par->DAClock, flags);
+ fg_color = (((u32)cmap.red[fg_idx] & 0xff00) << 8) |
+ (((u32)cmap.green[fg_idx] & 0xff00) << 0) |
+ (((u32)cmap.blue[fg_idx] & 0xff00) >> 8);
+ bg_color = (((u32)cmap.red[bg_idx] & 0xff00) << 8) |
+ (((u32)cmap.green[bg_idx] & 0xff00) << 0) |
+ (((u32)cmap.blue[bg_idx] & 0xff00) >> 8);
banshee_make_room(par, 2);
tdfx_outl(par, HWCURC0, bg_color);
tdfx_outl(par, HWCURC1, fg_color);
- spin_unlock_irqrestore(&par->DAClock, flags);
}
- if (cursor->set && FB_CUR_SETPOS) {
- int x, y;
+ if (cursor->set & FB_CUR_SETPOS) {
+ int x = cursor->image.dx;
+ int y = cursor->image.dy - info->var.yoffset;
- x = cursor->image.dx;
- y = cursor->image.dy;
- y -= info->var.yoffset;
- info->cursor.image.dx = x;
- info->cursor.image.dy = y;
x += 63;
y += 63;
- spin_lock_irqsave(&par->DAClock, flags);
banshee_make_room(par, 1);
tdfx_outl(par, HWCURLOC, (y << 16) + x);
- spin_unlock_irqrestore(&par->DAClock, flags);
}
-
- /* Not supported so we fake it */
- if (cursor->set && FB_CUR_SETHOT) {
- info->cursor.hot.x = cursor->hot.x;
- info->cursor.hot.y = cursor->hot.y;
- }
-
- if (cursor->set && FB_CUR_SETSHAPE) {
+ if (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
/*
- * Voodoo 3 and above cards use 2 monochrome cursor patterns.
+ * Voodoo 3 and above cards use 2 monochrome cursor patterns.
* The reason is so the card can fetch 8 words at a time
* and are stored on chip for use for the next 8 scanlines.
* This reduces the number of times for access to draw the
* cursor for each screen refresh.
* Each pattern is a bitmap of 64 bit wide and 64 bit high
- * (total of 8192 bits or 1024 Kbytes). The two patterns are
+ * (total of 8192 bits or 1024 bytes). The two patterns are
* stored in such a way that pattern 0 always resides in the
* lower half (least significant 64 bits) of a 128 bit word
* and pattern 1 the upper half. If you examine the data of
@@ -1106,50 +1123,54 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
* (128 bits) which is the maximum cursor width times two for
* the two monochrome patterns.
*/
- u8 *cursorbase = (u8 *) info->cursor.image.data;
- char *bitmap = (char *)cursor->image.data;
- char *mask = (char *) cursor->mask;
- int i, j, k, h = 0;
-
- for (i = 0; i < 64; i++) {
- if (i < cursor->image.height) {
- j = (cursor->image.width + 7) >> 3;
- k = 8 - j;
-
- for (;j > 0; j--) {
- /* Pattern 0. Copy the cursor bitmap to it */
- fb_writeb(*bitmap, cursorbase + h);
- bitmap++;
- /* Pattern 1. Copy the cursor mask to it */
- fb_writeb(*mask, cursorbase + h + 8);
- mask++;
- h++;
- }
- for (;k > 0; k--) {
- fb_writeb(0, cursorbase + h);
- fb_writeb(~0, cursorbase + h + 8);
- h++;
- }
- } else {
- fb_writel(0, cursorbase + h);
- fb_writel(0, cursorbase + h + 4);
- fb_writel(~0, cursorbase + h + 8);
- fb_writel(~0, cursorbase + h + 12);
- h += 16;
+ u8 __iomem *cursorbase = info->screen_base + info->fix.smem_len;
+ u8 *bitmap = (u8 *)cursor->image.data;
+ u8 *mask = (u8 *)cursor->mask;
+ int i;
+
+ fb_memset(cursorbase, 0, 1024);
+
+ for (i = 0; i < cursor->image.height; i++) {
+ int h = 0;
+ int j = (cursor->image.width + 7) >> 3;
+
+ for (; j > 0; j--) {
+ u8 data = *mask ^ *bitmap;
+ if (cursor->rop == ROP_COPY)
+ data = *mask & *bitmap;
+ /* Pattern 0. Copy the cursor mask to it */
+ fb_writeb(*mask, cursorbase + h);
+ mask++;
+ /* Pattern 1. Copy the cursor bitmap to it */
+ fb_writeb(data, cursorbase + h + 8);
+ bitmap++;
+ h++;
}
+ cursorbase += 16;
}
}
- /* Turn the cursor on */
- cursor->enable = 1;
- info->cursor = *cursor;
- mod_timer(&par->hwcursor.timer, jiffies+HZ/2);
- spin_lock_irqsave(&par->DAClock, flags);
- banshee_make_room(par, 1);
- tdfx_outl(par, VIDPROCCFG, par->hwcursor.enable);
- spin_unlock_irqrestore(&par->DAClock, flags);
return 0;
}
+
+static struct fb_ops tdfxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = tdfxfb_check_var,
+ .fb_set_par = tdfxfb_set_par,
+ .fb_setcolreg = tdfxfb_setcolreg,
+ .fb_blank = tdfxfb_blank,
+ .fb_pan_display = tdfxfb_pan_display,
+ .fb_sync = banshee_wait_idle,
+ .fb_cursor = tdfxfb_cursor,
+#ifdef CONFIG_FB_3DFX_ACCEL
+ .fb_fillrect = tdfxfb_fillrect,
+ .fb_copyarea = tdfxfb_copyarea,
+ .fb_imageblit = tdfxfb_imageblit,
+#else
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
#endif
+};
/**
* tdfxfb_probe - Device Initializiation
@@ -1161,14 +1182,15 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
*
*/
static int __devinit tdfxfb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+ const struct pci_device_id *id)
{
struct tdfx_par *default_par;
struct fb_info *info;
int err, lpitch;
- if ((err = pci_enable_device(pdev))) {
- printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err);
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "tdfxfb: Can't enable pdev: %d\n", err);
return err;
}
@@ -1176,139 +1198,145 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
if (!info)
return -ENOMEM;
-
+
default_par = info->par;
-
+
/* Configure the default fb_fix_screeninfo first */
switch (pdev->device) {
- case PCI_DEVICE_ID_3DFX_BANSHEE:
- strcat(tdfx_fix.id, " Banshee");
- default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
- break;
- case PCI_DEVICE_ID_3DFX_VOODOO3:
- strcat(tdfx_fix.id, " Voodoo3");
- default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
- break;
- case PCI_DEVICE_ID_3DFX_VOODOO5:
- strcat(tdfx_fix.id, " Voodoo5");
- default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
- break;
+ case PCI_DEVICE_ID_3DFX_BANSHEE:
+ strcat(tdfx_fix.id, " Banshee");
+ default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
+ break;
+ case PCI_DEVICE_ID_3DFX_VOODOO3:
+ strcat(tdfx_fix.id, " Voodoo3");
+ default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
+ break;
+ case PCI_DEVICE_ID_3DFX_VOODOO5:
+ strcat(tdfx_fix.id, " Voodoo5");
+ default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
+ break;
}
tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
- default_par->regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
- if (!default_par->regbase_virt) {
- printk("fb: Can't remap %s register area.\n", tdfx_fix.id);
+ if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
+ "tdfx regbase")) {
+ printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
goto out_err;
}
-
- if (!request_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0), "tdfx regbase")) {
- printk(KERN_WARNING "tdfxfb: Can't reserve regbase\n");
- goto out_err;
- }
+
+ default_par->regbase_virt =
+ ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+ if (!default_par->regbase_virt) {
+ printk(KERN_ERR "fb: Can't remap %s register area.\n",
+ tdfx_fix.id);
+ goto out_err_regbase;
+ }
tdfx_fix.smem_start = pci_resource_start(pdev, 1);
- if (!(tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device))) {
- printk("fb: Can't count %s memory.\n", tdfx_fix.id);
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- goto out_err;
+ tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device);
+ if (!tdfx_fix.smem_len) {
+ printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id);
+ goto out_err_regbase;
}
- if (!request_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1), "tdfx smem")) {
- printk(KERN_WARNING "tdfxfb: Can't reserve smem\n");
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- goto out_err;
+ if (!request_mem_region(tdfx_fix.smem_start,
+ pci_resource_len(pdev, 1), "tdfx smem")) {
+ printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
+ goto out_err_regbase;
}
- info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
+ info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
tdfx_fix.smem_len);
if (!info->screen_base) {
- printk("fb: Can't remap %s framebuffer.\n", tdfx_fix.id);
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- goto out_err;
+ printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
+ tdfx_fix.id);
+ goto out_err_screenbase;
}
default_par->iobase = pci_resource_start(pdev, 2);
-
+
if (!request_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2), "tdfx iobase")) {
- printk(KERN_WARNING "tdfxfb: Can't reserve iobase\n");
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- goto out_err;
+ pci_resource_len(pdev, 2), "tdfx iobase")) {
+ printk(KERN_ERR "tdfxfb: Can't reserve iobase\n");
+ goto out_err_screenbase;
}
- printk("fb: %s memory = %dK\n", tdfx_fix.id, tdfx_fix.smem_len >> 10);
+ printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id,
+ tdfx_fix.smem_len >> 10);
+
+ default_par->mtrr_handle = -1;
+ if (!nomtrr)
+ default_par->mtrr_handle =
+ mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len,
+ MTRR_TYPE_WRCOMB, 1);
tdfx_fix.ypanstep = nopan ? 0 : 1;
tdfx_fix.ywrapstep = nowrap ? 0 : 1;
-
+
info->fbops = &tdfxfb_ops;
- info->fix = tdfx_fix;
+ info->fix = tdfx_fix;
info->pseudo_palette = default_par->palette;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
#ifdef CONFIG_FB_3DFX_ACCEL
- info->flags |= FBINFO_HWACCEL_FILLRECT |
- FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_IMAGEBLIT;
+ info->flags |= FBINFO_HWACCEL_FILLRECT |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_IMAGEBLIT |
+ FBINFO_READS_FAST;
#endif
+ /* reserve 8192 bits for cursor */
+ /* the 2.4 driver says PAGE_MASK boundary is not enough for Voodoo4 */
+ if (hwcursor)
+ info->fix.smem_len = (info->fix.smem_len - 1024) &
+ (PAGE_MASK << 1);
if (!mode_option)
mode_option = "640x480@60";
-
- err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
+
+ err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
if (!err || err == 4)
info->var = tdfx_var;
/* maximize virtual vertical length */
lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3);
- info->var.yres_virtual = info->fix.smem_len/lpitch;
+ info->var.yres_virtual = info->fix.smem_len / lpitch;
if (info->var.yres_virtual < info->var.yres)
- goto out_err;
-
-#ifdef CONFIG_FB_3DFX_ACCEL
- /*
- * FIXME: Limit var->yres_virtual to 4096 because of screen artifacts
- * during scrolling. This is only present if 2D acceleration is
- * enabled.
- */
- if (info->var.yres_virtual > 4096)
- info->var.yres_virtual = 4096;
-#endif /* CONFIG_FB_3DFX_ACCEL */
+ goto out_err_iobase;
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
- printk(KERN_WARNING "tdfxfb: Can't allocate color map\n");
- goto out_err;
+ printk(KERN_ERR "tdfxfb: Can't allocate color map\n");
+ goto out_err_iobase;
}
if (register_framebuffer(info) < 0) {
- printk("tdfxfb: can't register framebuffer\n");
+ printk(KERN_ERR "tdfxfb: can't register framebuffer\n");
fb_dealloc_cmap(&info->cmap);
- goto out_err;
+ goto out_err_iobase;
}
/*
* Our driver data
*/
pci_set_drvdata(pdev, info);
- return 0;
+ return 0;
-out_err:
+out_err_iobase:
+ if (default_par->mtrr_handle >= 0)
+ mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
+ info->fix.smem_len);
+ release_mem_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
+out_err_screenbase:
+ if (info->screen_base)
+ iounmap(info->screen_base);
+ release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
+out_err_regbase:
/*
* Cleanup after anything that was remapped/allocated.
*/
if (default_par->regbase_virt)
iounmap(default_par->regbase_virt);
- if (info->screen_base)
- iounmap(info->screen_base);
+ release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+out_err:
framebuffer_release(info);
return -ENXIO;
}
@@ -1316,7 +1344,7 @@ out_err:
#ifndef MODULE
static void tdfxfb_setup(char *options)
{
- char* this_opt;
+ char *this_opt;
if (!options || !*options)
return;
@@ -1324,10 +1352,16 @@ static void tdfxfb_setup(char *options)
while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt)
continue;
- if(!strcmp(this_opt, "nopan")) {
+ if (!strcmp(this_opt, "nopan")) {
nopan = 1;
- } else if(!strcmp(this_opt, "nowrap")) {
+ } else if (!strcmp(this_opt, "nowrap")) {
nowrap = 1;
+ } else if (!strncmp(this_opt, "hwcursor=", 9)) {
+ hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
+#ifdef CONFIG_MTRR
+ } else if (!strncmp(this_opt, "nomtrr", 6)) {
+ nomtrr = 1;
+#endif
} else {
mode_option = this_opt;
}
@@ -1350,6 +1384,9 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
struct tdfx_par *par = info->par;
unregister_framebuffer(info);
+ if (par->mtrr_handle >= 0)
+ mtrr_del(par->mtrr_handle, info->fix.smem_start,
+ info->fix.smem_len);
iounmap(par->regbase_virt);
iounmap(info->screen_base);
@@ -1374,17 +1411,25 @@ static int __init tdfxfb_init(void)
tdfxfb_setup(option);
#endif
- return pci_register_driver(&tdfxfb_driver);
+ return pci_register_driver(&tdfxfb_driver);
}
static void __exit tdfxfb_exit(void)
{
- pci_unregister_driver(&tdfxfb_driver);
+ pci_unregister_driver(&tdfxfb_driver);
}
MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
MODULE_DESCRIPTION("3Dfx framebuffer device driver");
MODULE_LICENSE("GPL");
-
+
+module_param(hwcursor, int, 0644);
+MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
+ "(1=enable, 0=disable, default=1)");
+#ifdef CONFIG_MTRR
+module_param(nomtrr, bool, 0);
+MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)");
+#endif
+
module_init(tdfxfb_init);
module_exit(tdfxfb_exit);
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index d292a37ec7d..680642c089c 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -5,7 +5,7 @@
* Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
* Copyright (C) 2002 Richard Henderson
- * Copyright (C) 2006 Maciej W. Rozycki
+ * Copyright (C) 2006, 2007 Maciej W. Rozycki
*
* 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
@@ -13,6 +13,7 @@
*/
#include <linux/bitrev.h>
+#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
@@ -636,15 +637,6 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
is8bpp = info->var.bits_per_pixel == 8;
- /* For copies that aren't pixel expansion, there's little we
- can do better than the generic code. */
- /* ??? There is a DMA write mode; I wonder if that could be
- made to pull the data from the image buffer... */
- if (image->depth > 1) {
- cfb_imageblit(info, image);
- return;
- }
-
dx = image->dx;
dy = image->dy;
width = image->width;
@@ -654,6 +646,9 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
line_length = info->fix.line_length;
rincr = (width + 7) / 8;
+ /* A shift below cannot cope with. */
+ if (unlikely(width == 0))
+ return;
/* Crop the image to the screen. */
if (dx > vxres || dy > vyres)
return;
@@ -709,9 +704,10 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
unsigned long bwidth;
/* Handle common case of imaging a single character, in
- a font less than 32 pixels wide. */
+ a font less than or 32 pixels wide. */
- pixelmask = (1 << width) - 1;
+ /* Avoid a shift by 32; width > 0 implied. */
+ pixelmask = (2ul << (width - 1)) - 1;
pixelmask <<= shift;
__raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
wmb();
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index c699864b6f4..70fb4ee2b42 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1,18 +1,19 @@
/*
* Frame buffer driver for Trident Blade and Image series
*
- * Copyright 2001,2002 - Jani Monoses <jani@iv.ro>
+ * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro>
*
*
* CREDITS:(in order of appearance)
- * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
- * Special thanks ;) to Mattia Crivellini <tia@mclink.it>
- * much inspired by the XFree86 4.x Trident driver sources by Alan Hourihane
- * the FreeVGA project
- * Francesco Salvestrini <salvestrini@users.sf.net> XP support,code,suggestions
+ * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
+ * Special thanks ;) to Mattia Crivellini <tia@mclink.it>
+ * much inspired by the XFree86 4.x Trident driver sources
+ * by Alan Hourihane the FreeVGA project
+ * Francesco Salvestrini <salvestrini@users.sf.net> XP support,
+ * code, suggestions
* TODO:
- * timing value tweaking so it looks good on every monitor in every mode
- * TGUI acceleration
+ * timing value tweaking so it looks good on every monitor in every mode
+ * TGUI acceleration
*/
#include <linux/module.h>
@@ -26,11 +27,11 @@
#define VERSION "0.7.8-NEWAPI"
struct tridentfb_par {
- int vclk; //in MHz
- void __iomem * io_virt; //iospace virtual memory address
+ int vclk; /* in MHz */
+ void __iomem *io_virt; /* iospace virtual memory address */
};
-static unsigned char eng_oper; //engine operation...
+static unsigned char eng_oper; /* engine operation... */
static struct fb_ops tridentfb_ops;
static struct tridentfb_par default_par;
@@ -39,11 +40,10 @@ static struct tridentfb_par default_par;
static struct fb_info fb_info;
static u32 pseudo_pal[16];
-
static struct fb_var_screeninfo default_var;
static struct fb_fix_screeninfo tridentfb_fix = {
- .id = "Trident",
+ .id = "Trident",
.type = FB_TYPE_PACKED_PIXELS,
.ypanstep = 1,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -55,11 +55,10 @@ static int chip_id;
static int defaultaccel;
static int displaytype;
-
/* defaults which are normally overriden by user values */
/* video mode */
-static char * mode = "640x480";
+static char *mode = "640x480";
static int bpp = 8;
static int noaccel;
@@ -74,7 +73,6 @@ static int memsize;
static int memdiff;
static int nativex;
-
module_param(mode, charp, 0);
module_param(bpp, int, 0);
module_param(center, int, 0);
@@ -86,88 +84,85 @@ module_param(nativex, int, 0);
module_param(fp, int, 0);
module_param(crt, int, 0);
-
static int chip3D;
static int chipcyber;
static int is3Dchip(int id)
{
- return ((id == BLADE3D) || (id == CYBERBLADEE4) ||
- (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
- (id == CYBER9397) || (id == CYBER9397DVD) ||
- (id == CYBER9520) || (id == CYBER9525DVD) ||
- (id == IMAGE975) || (id == IMAGE985) ||
- (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
- (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
- (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
- (id == CYBERBLADEXPAi1));
+ return ((id == BLADE3D) || (id == CYBERBLADEE4) ||
+ (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
+ (id == CYBER9397) || (id == CYBER9397DVD) ||
+ (id == CYBER9520) || (id == CYBER9525DVD) ||
+ (id == IMAGE975) || (id == IMAGE985) ||
+ (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
+ (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
+ (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
+ (id == CYBERBLADEXPAi1));
}
static int iscyber(int id)
{
switch (id) {
- case CYBER9388:
- case CYBER9382:
- case CYBER9385:
- case CYBER9397:
- case CYBER9397DVD:
- case CYBER9520:
- case CYBER9525DVD:
- case CYBERBLADEE4:
- case CYBERBLADEi7D:
- case CYBERBLADEi1:
- case CYBERBLADEi1D:
- case CYBERBLADEAi1:
- case CYBERBLADEAi1D:
- case CYBERBLADEXPAi1:
- return 1;
-
- case CYBER9320:
- case TGUI9660:
- case IMAGE975:
- case IMAGE985:
- case BLADE3D:
- case CYBERBLADEi7: /* VIA MPV4 integrated version */
+ case CYBER9388:
+ case CYBER9382:
+ case CYBER9385:
+ case CYBER9397:
+ case CYBER9397DVD:
+ case CYBER9520:
+ case CYBER9525DVD:
+ case CYBERBLADEE4:
+ case CYBERBLADEi7D:
+ case CYBERBLADEi1:
+ case CYBERBLADEi1D:
+ case CYBERBLADEAi1:
+ case CYBERBLADEAi1D:
+ case CYBERBLADEXPAi1:
+ return 1;
- default:
- /* case CYBERBLDAEXPm8: Strange */
- /* case CYBERBLDAEXPm16: Strange */
- return 0;
+ case CYBER9320:
+ case TGUI9660:
+ case IMAGE975:
+ case IMAGE985:
+ case BLADE3D:
+ case CYBERBLADEi7: /* VIA MPV4 integrated version */
+
+ default:
+ /* case CYBERBLDAEXPm8: Strange */
+ /* case CYBERBLDAEXPm16: Strange */
+ return 0;
}
}
-#define CRT 0x3D0 //CRTC registers offset for color display
+#define CRT 0x3D0 /* CRTC registers offset for color display */
#ifndef TRIDENT_MMIO
#define TRIDENT_MMIO 1
#endif
#if TRIDENT_MMIO
- #define t_outb(val,reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg)
+ #define t_outb(val, reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg)
#define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg)
#else
- #define t_outb(val,reg) outb(val,reg)
+ #define t_outb(val, reg) outb(val, reg)
#define t_inb(reg) inb(reg)
#endif
static struct accel_switch {
- void (*init_accel)(int,int);
- void (*wait_engine)(void);
- void (*fill_rect)(__u32,__u32,__u32,__u32,__u32,__u32);
- void (*copy_rect)(__u32,__u32,__u32,__u32,__u32,__u32);
+ void (*init_accel) (int, int);
+ void (*wait_engine) (void);
+ void (*fill_rect) (u32, u32, u32, u32, u32, u32);
+ void (*copy_rect) (u32, u32, u32, u32, u32, u32);
} *acc;
-#define writemmr(r,v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r)
+#define writemmr(r, v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r)
#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r)
-
-
/*
* Blade specific acceleration.
*/
-#define point(x,y) ((y)<<16|(x))
+#define point(x, y) ((y) << 16 | (x))
#define STA 0x2120
#define CMD 0x2144
#define ROP 0x2148
@@ -179,64 +174,71 @@ static struct accel_switch {
#define ROP_S 0xCC
-static void blade_init_accel(int pitch,int bpp)
+static void blade_init_accel(int pitch, int bpp)
{
- int v1 = (pitch>>3)<<20;
- int tmp = 0,v2;
+ int v1 = (pitch >> 3) << 20;
+ int tmp = 0, v2;
switch (bpp) {
- case 8:tmp = 0;break;
- case 15:tmp = 5;break;
- case 16:tmp = 1;break;
- case 24:
- case 32:tmp = 2;break;
+ case 8:
+ tmp = 0;
+ break;
+ case 15:
+ tmp = 5;
+ break;
+ case 16:
+ tmp = 1;
+ break;
+ case 24:
+ case 32:
+ tmp = 2;
+ break;
}
- v2 = v1 | (tmp<<29);
- writemmr(0x21C0,v2);
- writemmr(0x21C4,v2);
- writemmr(0x21B8,v2);
- writemmr(0x21BC,v2);
- writemmr(0x21D0,v1);
- writemmr(0x21D4,v1);
- writemmr(0x21C8,v1);
- writemmr(0x21CC,v1);
- writemmr(0x216C,0);
+ v2 = v1 | (tmp << 29);
+ writemmr(0x21C0, v2);
+ writemmr(0x21C4, v2);
+ writemmr(0x21B8, v2);
+ writemmr(0x21BC, v2);
+ writemmr(0x21D0, v1);
+ writemmr(0x21D4, v1);
+ writemmr(0x21C8, v1);
+ writemmr(0x21CC, v1);
+ writemmr(0x216C, 0);
}
static void blade_wait_engine(void)
{
- while(readmmr(STA) & 0xFA800000);
+ while (readmmr(STA) & 0xFA800000) ;
}
-static void blade_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop)
+static void blade_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
{
- writemmr(CLR,c);
- writemmr(ROP,rop ? 0x66:ROP_S);
- writemmr(CMD,0x20000000|1<<19|1<<4|2<<2);
+ writemmr(CLR, c);
+ writemmr(ROP, rop ? 0x66 : ROP_S);
+ writemmr(CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
- writemmr(DR1,point(x,y));
- writemmr(DR2,point(x+w-1,y+h-1));
+ writemmr(DR1, point(x, y));
+ writemmr(DR2, point(x + w - 1, y + h - 1));
}
-static void blade_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
+static void blade_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
{
- __u32 s1,s2,d1,d2;
+ u32 s1, s2, d1, d2;
int direction = 2;
- s1 = point(x1,y1);
- s2 = point(x1+w-1,y1+h-1);
- d1 = point(x2,y2);
- d2 = point(x2+w-1,y2+h-1);
+ s1 = point(x1, y1);
+ s2 = point(x1 + w - 1, y1 + h - 1);
+ d1 = point(x2, y2);
+ d2 = point(x2 + w - 1, y2 + h - 1);
if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
- direction = 0;
-
+ direction = 0;
- writemmr(ROP,ROP_S);
- writemmr(CMD,0xE0000000|1<<19|1<<4|1<<2|direction);
+ writemmr(ROP, ROP_S);
+ writemmr(CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction);
- writemmr(SR1,direction?s2:s1);
- writemmr(SR2,direction?s1:s2);
- writemmr(DR1,direction?d2:d1);
- writemmr(DR2,direction?d1:d2);
+ writemmr(SR1, direction ? s2 : s1);
+ writemmr(SR2, direction ? s1 : s2);
+ writemmr(DR1, direction ? d2 : d1);
+ writemmr(DR2, direction ? d1 : d2);
}
static struct accel_switch accel_blade = {
@@ -246,51 +248,72 @@ static struct accel_switch accel_blade = {
blade_copy_rect,
};
-
/*
* BladeXP specific acceleration functions
*/
#define ROP_P 0xF0
-#define masked_point(x,y) ((y & 0xffff)<<16|(x & 0xffff))
+#define masked_point(x, y) ((y & 0xffff)<<16|(x & 0xffff))
-static void xp_init_accel(int pitch,int bpp)
+static void xp_init_accel(int pitch, int bpp)
{
- int tmp = 0,v1;
+ int tmp = 0, v1;
unsigned char x = 0;
switch (bpp) {
- case 8: x = 0; break;
- case 16: x = 1; break;
- case 24: x = 3; break;
- case 32: x = 2; break;
+ case 8:
+ x = 0;
+ break;
+ case 16:
+ x = 1;
+ break;
+ case 24:
+ x = 3;
+ break;
+ case 32:
+ x = 2;
+ break;
}
switch (pitch << (bpp >> 3)) {
- case 8192:
- case 512: x |= 0x00; break;
- case 1024: x |= 0x04; break;
- case 2048: x |= 0x08; break;
- case 4096: x |= 0x0C; break;
+ case 8192:
+ case 512:
+ x |= 0x00;
+ break;
+ case 1024:
+ x |= 0x04;
+ break;
+ case 2048:
+ x |= 0x08;
+ break;
+ case 4096:
+ x |= 0x0C;
+ break;
}
- t_outb(x,0x2125);
+ t_outb(x, 0x2125);
eng_oper = x | 0x40;
switch (bpp) {
- case 8: tmp = 18; break;
- case 15:
- case 16: tmp = 19; break;
- case 24:
- case 32: tmp = 20; break;
+ case 8:
+ tmp = 18;
+ break;
+ case 15:
+ case 16:
+ tmp = 19;
+ break;
+ case 24:
+ case 32:
+ tmp = 20;
+ break;
}
v1 = pitch << tmp;
- writemmr(0x2154,v1);
- writemmr(0x2150,v1);
- t_outb(3,0x2126);
+ writemmr(0x2154, v1);
+ writemmr(0x2150, v1);
+ t_outb(3, 0x2126);
}
static void xp_wait_engine(void)
@@ -318,24 +341,24 @@ static void xp_wait_engine(void)
}
}
-static void xp_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop)
+static void xp_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
{
- writemmr(0x2127,ROP_P);
- writemmr(0x2158,c);
- writemmr(0x2128,0x4000);
- writemmr(0x2140,masked_point(h,w));
- writemmr(0x2138,masked_point(y,x));
- t_outb(0x01,0x2124);
- t_outb(eng_oper,0x2125);
+ writemmr(0x2127, ROP_P);
+ writemmr(0x2158, c);
+ writemmr(0x2128, 0x4000);
+ writemmr(0x2140, masked_point(h, w));
+ writemmr(0x2138, masked_point(y, x));
+ t_outb(0x01, 0x2124);
+ t_outb(eng_oper, 0x2125);
}
-static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
+static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
{
int direction;
- __u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
+ u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
direction = 0x0004;
-
+
if ((x1 < x2) && (y1 == y2)) {
direction |= 0x0200;
x1_tmp = x1 + w - 1;
@@ -344,53 +367,60 @@ static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
x1_tmp = x1;
x2_tmp = x2;
}
-
+
if (y1 < y2) {
direction |= 0x0100;
y1_tmp = y1 + h - 1;
y2_tmp = y2 + h - 1;
- } else {
+ } else {
y1_tmp = y1;
y2_tmp = y2;
}
- writemmr(0x2128,direction);
- t_outb(ROP_S,0x2127);
- writemmr(0x213C,masked_point(y1_tmp,x1_tmp));
- writemmr(0x2138,masked_point(y2_tmp,x2_tmp));
- writemmr(0x2140,masked_point(h,w));
- t_outb(0x01,0x2124);
+ writemmr(0x2128, direction);
+ t_outb(ROP_S, 0x2127);
+ writemmr(0x213C, masked_point(y1_tmp, x1_tmp));
+ writemmr(0x2138, masked_point(y2_tmp, x2_tmp));
+ writemmr(0x2140, masked_point(h, w));
+ t_outb(0x01, 0x2124);
}
static struct accel_switch accel_xp = {
- xp_init_accel,
+ xp_init_accel,
xp_wait_engine,
xp_fill_rect,
xp_copy_rect,
};
-
/*
* Image specific acceleration functions
*/
-static void image_init_accel(int pitch,int bpp)
+static void image_init_accel(int pitch, int bpp)
{
int tmp = 0;
- switch (bpp) {
- case 8:tmp = 0;break;
- case 15:tmp = 5;break;
- case 16:tmp = 1;break;
- case 24:
- case 32:tmp = 2;break;
+ switch (bpp) {
+ case 8:
+ tmp = 0;
+ break;
+ case 15:
+ tmp = 5;
+ break;
+ case 16:
+ tmp = 1;
+ break;
+ case 24:
+ case 32:
+ tmp = 2;
+ break;
}
writemmr(0x2120, 0xF0000000);
- writemmr(0x2120, 0x40000000|tmp);
+ writemmr(0x2120, 0x40000000 | tmp);
writemmr(0x2120, 0x80000000);
writemmr(0x2144, 0x00000000);
writemmr(0x2148, 0x00000000);
writemmr(0x2150, 0x00000000);
writemmr(0x2154, 0x00000000);
- writemmr(0x2120, 0x60000000|(pitch<<16) |pitch);
+ writemmr(0x2120, 0x60000000 | (pitch << 16) | pitch);
writemmr(0x216C, 0x00000000);
writemmr(0x2170, 0x00000000);
writemmr(0x217C, 0x00000000);
@@ -400,44 +430,43 @@ static void image_init_accel(int pitch,int bpp)
static void image_wait_engine(void)
{
- while(readmmr(0x2164) & 0xF0000000);
+ while (readmmr(0x2164) & 0xF0000000) ;
}
-static void image_fill_rect(__u32 x, __u32 y, __u32 w, __u32 h, __u32 c, __u32 rop)
+static void image_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
{
- writemmr(0x2120,0x80000000);
- writemmr(0x2120,0x90000000|ROP_S);
+ writemmr(0x2120, 0x80000000);
+ writemmr(0x2120, 0x90000000 | ROP_S);
- writemmr(0x2144,c);
+ writemmr(0x2144, c);
- writemmr(DR1,point(x,y));
- writemmr(DR2,point(x+w-1,y+h-1));
+ writemmr(DR1, point(x, y));
+ writemmr(DR2, point(x + w - 1, y + h - 1));
- writemmr(0x2124,0x80000000|3<<22|1<<10|1<<9);
+ writemmr(0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9);
}
-static void image_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
+static void image_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
{
- __u32 s1,s2,d1,d2;
+ u32 s1, s2, d1, d2;
int direction = 2;
- s1 = point(x1,y1);
- s2 = point(x1+w-1,y1+h-1);
- d1 = point(x2,y2);
- d2 = point(x2+w-1,y2+h-1);
-
- if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
- direction = 0;
-
- writemmr(0x2120,0x80000000);
- writemmr(0x2120,0x90000000|ROP_S);
-
- writemmr(SR1,direction?s2:s1);
- writemmr(SR2,direction?s1:s2);
- writemmr(DR1,direction?d2:d1);
- writemmr(DR2,direction?d1:d2);
- writemmr(0x2124,0x80000000|1<<22|1<<10|1<<7|direction);
-}
+ s1 = point(x1, y1);
+ s2 = point(x1 + w - 1, y1 + h - 1);
+ d1 = point(x2, y2);
+ d2 = point(x2 + w - 1, y2 + h - 1);
+ if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
+ direction = 0;
+
+ writemmr(0x2120, 0x80000000);
+ writemmr(0x2120, 0x90000000 | ROP_S);
+
+ writemmr(SR1, direction ? s2 : s1);
+ writemmr(SR2, direction ? s1 : s2);
+ writemmr(DR1, direction ? d2 : d1);
+ writemmr(DR2, direction ? d1 : d2);
+ writemmr(0x2124, 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction);
+}
static struct accel_switch accel_image = {
image_init_accel,
@@ -450,30 +479,34 @@ static struct accel_switch accel_image = {
* Accel functions called by the upper layers
*/
#ifdef CONFIG_FB_TRIDENT_ACCEL
-static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr)
+static void tridentfb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *fr)
{
int bpp = info->var.bits_per_pixel;
int col = 0;
-
+
switch (bpp) {
- default:
- case 8: col |= fr->color;
- col |= col << 8;
- col |= col << 16;
- break;
- case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
-
- break;
- case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
- break;
- }
-
+ default:
+ case 8:
+ col |= fr->color;
+ col |= col << 8;
+ col |= col << 16;
+ break;
+ case 16:
+ col = ((u32 *)(info->pseudo_palette))[fr->color];
+ break;
+ case 32:
+ col = ((u32 *)(info->pseudo_palette))[fr->color];
+ break;
+ }
+
acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop);
acc->wait_engine();
}
-static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *ca)
+static void tridentfb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *ca)
{
- acc->copy_rect(ca->sx,ca->sy,ca->dx,ca->dy,ca->width,ca->height);
+ acc->copy_rect(ca->sx, ca->sy, ca->dx, ca->dy, ca->width, ca->height);
acc->wait_engine();
}
#else /* !CONFIG_FB_TRIDENT_ACCEL */
@@ -488,14 +521,14 @@ static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *c
static inline unsigned char read3X4(int reg)
{
- struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par;
+ struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par;
writeb(reg, par->io_virt + CRT + 4);
- return readb( par->io_virt + CRT + 5);
+ return readb(par->io_virt + CRT + 5);
}
static inline void write3X4(int reg, unsigned char val)
{
- struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par;
+ struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par;
writeb(reg, par->io_virt + CRT + 4);
writeb(val, par->io_virt + CRT + 5);
}
@@ -520,7 +553,7 @@ static inline unsigned char read3CE(int reg)
static inline void writeAttr(int reg, unsigned char val)
{
- readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); //flip-flop to index
+ readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); /* flip-flop to index */
t_outb(reg, 0x3C0);
t_outb(val, 0x3C0);
}
@@ -540,32 +573,41 @@ static inline void enable_mmio(void)
/* Unprotect registers */
outb(NewMode1, 0x3C4);
outb(0x80, 0x3C5);
-
+
/* Enable MMIO */
- outb(PCIReg, 0x3D4);
+ outb(PCIReg, 0x3D4);
outb(inb(0x3D5) | 0x01, 0x3D5);
}
-
#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
/* Return flat panel's maximum x resolution */
static int __devinit get_nativex(void)
{
- int x,y,tmp;
+ int x, y, tmp;
if (nativex)
return nativex;
- tmp = (read3CE(VertStretch) >> 4) & 3;
+ tmp = (read3CE(VertStretch) >> 4) & 3;
switch (tmp) {
- case 0: x = 1280; y = 1024; break;
- case 2: x = 1024; y = 768; break;
- case 3: x = 800; y = 600; break;
- case 4: x = 1400; y = 1050; break;
- case 1:
- default:x = 640; y = 480; break;
+ case 0:
+ x = 1280; y = 1024;
+ break;
+ case 2:
+ x = 1024; y = 768;
+ break;
+ case 3:
+ x = 800; y = 600;
+ break;
+ case 4:
+ x = 1400; y = 1050;
+ break;
+ case 1:
+ default:
+ x = 640; y = 480;
+ break;
}
output("%dx%d flat panel found\n", x, y);
@@ -576,25 +618,26 @@ static int __devinit get_nativex(void)
static void set_lwidth(int width)
{
write3X4(Offset, width & 0xFF);
- write3X4(AddColReg, (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >>4));
+ write3X4(AddColReg,
+ (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >> 4));
}
/* For resolutions smaller than FP resolution stretch */
static void screen_stretch(void)
{
- if (chip_id != CYBERBLADEXPAi1)
- write3CE(BiosReg,0);
- else
- write3CE(BiosReg,8);
- write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 1);
- write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 1);
+ if (chip_id != CYBERBLADEXPAi1)
+ write3CE(BiosReg, 0);
+ else
+ write3CE(BiosReg, 8);
+ write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 1);
+ write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 1);
}
/* For resolutions smaller than FP resolution center */
static void screen_center(void)
{
- write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 0x80);
- write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 0x80);
+ write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 0x80);
+ write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 0x80);
}
/* Address of first shown pixel in display memory */
@@ -602,40 +645,42 @@ static void set_screen_start(int base)
{
write3X4(StartAddrLow, base & 0xFF);
write3X4(StartAddrHigh, (base & 0xFF00) >> 8);
- write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));
- write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
+ write3X4(CRTCModuleTest,
+ (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));
+ write3X4(CRTHiOrd,
+ (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
}
/* Use 20.12 fixed-point for NTSC value and frequency calculation */
-#define calc_freq(n,m,k) ( ((unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12 )
+#define calc_freq(n, m, k) ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 )
/* Set dotclock frequency */
static void set_vclk(int freq)
{
- int m,n,k;
- int f,fi,d,di;
- unsigned char lo=0,hi=0;
+ int m, n, k;
+ int f, fi, d, di;
+ unsigned char lo = 0, hi = 0;
d = 20;
- for(k = 2;k>=0;k--)
- for(m = 0;m<63;m++)
- for(n = 0;n<128;n++) {
- fi = calc_freq(n,m,k);
- if ((di = abs(fi - freq)) < d) {
- d = di;
- f = fi;
- lo = n;
- hi = (k<<6) | m;
- }
- }
+ for (k = 2; k >= 0; k--)
+ for (m = 0; m < 63; m++)
+ for (n = 0; n < 128; n++) {
+ fi = calc_freq(n, m, k);
+ if ((di = abs(fi - freq)) < d) {
+ d = di;
+ f = fi;
+ lo = n;
+ hi = (k << 6) | m;
+ }
+ }
if (chip3D) {
- write3C4(ClockHigh,hi);
- write3C4(ClockLow,lo);
+ write3C4(ClockHigh, hi);
+ write3C4(ClockLow, lo);
} else {
- outb(lo,0x43C8);
- outb(hi,0x43C9);
+ outb(lo, 0x43C8);
+ outb(hi, 0x43C9);
}
- debug("VCLK = %X %X\n",hi,lo);
+ debug("VCLK = %X %X\n", hi, lo);
}
/* Set number of lines for flat panels*/
@@ -663,7 +708,7 @@ static unsigned int __devinit get_displaytype(void)
return DISPLAY_FP;
if (crt || !chipcyber)
return DISPLAY_CRT;
- return (read3CE(FPConfig) & 0x10)?DISPLAY_FP:DISPLAY_CRT;
+ return (read3CE(FPConfig) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
}
/* Try detecting the video memory size */
@@ -676,100 +721,136 @@ static unsigned int __devinit get_memsize(void)
if (memsize)
k = memsize * Kb;
else
- switch (chip_id) {
- case CYBER9525DVD: k = 2560 * Kb; break;
+ switch (chip_id) {
+ case CYBER9525DVD:
+ k = 2560 * Kb;
+ break;
default:
tmp = read3X4(SPR) & 0x0F;
switch (tmp) {
- case 0x01: k = 512; break;
- case 0x02: k = 6 * Mb; break; /* XP */
- case 0x03: k = 1 * Mb; break;
- case 0x04: k = 8 * Mb; break;
- case 0x06: k = 10 * Mb; break; /* XP */
- case 0x07: k = 2 * Mb; break;
- case 0x08: k = 12 * Mb; break; /* XP */
- case 0x0A: k = 14 * Mb; break; /* XP */
- case 0x0C: k = 16 * Mb; break; /* XP */
- case 0x0E: /* XP */
-
- tmp2 = read3C4(0xC1);
- switch (tmp2) {
- case 0x00: k = 20 * Mb; break;
- case 0x01: k = 24 * Mb; break;
- case 0x10: k = 28 * Mb; break;
- case 0x11: k = 32 * Mb; break;
- default: k = 1 * Mb; break;
- }
+ case 0x01:
+ k = 512;
+ break;
+ case 0x02:
+ k = 6 * Mb; /* XP */
+ break;
+ case 0x03:
+ k = 1 * Mb;
+ break;
+ case 0x04:
+ k = 8 * Mb;
+ break;
+ case 0x06:
+ k = 10 * Mb; /* XP */
+ break;
+ case 0x07:
+ k = 2 * Mb;
+ break;
+ case 0x08:
+ k = 12 * Mb; /* XP */
+ break;
+ case 0x0A:
+ k = 14 * Mb; /* XP */
+ break;
+ case 0x0C:
+ k = 16 * Mb; /* XP */
+ break;
+ case 0x0E: /* XP */
+
+ tmp2 = read3C4(0xC1);
+ switch (tmp2) {
+ case 0x00:
+ k = 20 * Mb;
+ break;
+ case 0x01:
+ k = 24 * Mb;
+ break;
+ case 0x10:
+ k = 28 * Mb;
+ break;
+ case 0x11:
+ k = 32 * Mb;
+ break;
+ default:
+ k = 1 * Mb;
+ break;
+ }
+ break;
+
+ case 0x0F:
+ k = 4 * Mb;
+ break;
+ default:
+ k = 1 * Mb;
break;
-
- case 0x0F: k = 4 * Mb; break;
- default: k = 1 * Mb;
}
- }
+ }
k -= memdiff * Kb;
- output("framebuffer size = %d Kb\n", k/Kb);
+ output("framebuffer size = %d Kb\n", k / Kb);
return k;
}
/* See if we can handle the video mode described in var */
-static int tridentfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+static int tridentfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
int bpp = var->bits_per_pixel;
debug("enter\n");
/* check color depth */
- if (bpp == 24 )
+ if (bpp == 24)
bpp = var->bits_per_pixel = 32;
- /* check whether resolution fits on panel and in memory*/
+ /* check whether resolution fits on panel and in memory */
if (flatpanel && nativex && var->xres > nativex)
return -EINVAL;
- if (var->xres * var->yres_virtual * bpp/8 > info->fix.smem_len)
+ if (var->xres * var->yres_virtual * bpp / 8 > info->fix.smem_len)
return -EINVAL;
switch (bpp) {
- case 8:
- var->red.offset = 0;
- var->green.offset = 0;
- var->blue.offset = 0;
- var->red.length = 6;
- var->green.length = 6;
- var->blue.length = 6;
- break;
- case 16:
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- var->red.length = 5;
- var->green.length = 6;
- var->blue.length = 5;
- break;
- case 32:
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- break;
- default:
- return -EINVAL;
+ case 8:
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
+ break;
+ case 16:
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+ case 32:
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ default:
+ return -EINVAL;
}
debug("exit\n");
return 0;
}
+
/* Pan the display */
static int tridentfb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
+ struct fb_info *info)
{
unsigned int offset;
debug("enter\n");
offset = (var->xoffset + (var->yoffset * var->xres))
- * var->bits_per_pixel/32;
+ * var->bits_per_pixel / 32;
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
set_screen_start(offset);
@@ -777,36 +858,38 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var,
return 0;
}
-#define shadowmode_on() write3CE(CyberControl,read3CE(CyberControl) | 0x81)
-#define shadowmode_off() write3CE(CyberControl,read3CE(CyberControl) & 0x7E)
+#define shadowmode_on() write3CE(CyberControl, read3CE(CyberControl) | 0x81)
+#define shadowmode_off() write3CE(CyberControl, read3CE(CyberControl) & 0x7E)
/* Set the hardware to the requested video mode */
static int tridentfb_set_par(struct fb_info *info)
{
- struct tridentfb_par * par = (struct tridentfb_par *)(info->par);
- u32 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,
- vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend;
- struct fb_var_screeninfo *var = &info->var;
+ struct tridentfb_par *par = (struct tridentfb_par *)(info->par);
+ u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend;
+ u32 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend;
+ struct fb_var_screeninfo *var = &info->var;
int bpp = var->bits_per_pixel;
unsigned char tmp;
debug("enter\n");
- htotal = (var->xres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10;
- hdispend = var->xres/8 - 1;
- hsyncstart = (var->xres + var->right_margin)/8;
- hsyncend = var->hsync_len/8;
+ hdispend = var->xres / 8 - 1;
+ hsyncstart = (var->xres + var->right_margin) / 8;
+ hsyncend = var->hsync_len / 8;
+ htotal =
+ (var->xres + var->left_margin + var->right_margin +
+ var->hsync_len) / 8 - 10;
hblankstart = hdispend + 1;
hblankend = htotal + 5;
- vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len - 2;
vdispend = var->yres - 1;
vsyncstart = var->yres + var->lower_margin;
vsyncend = var->vsync_len;
+ vtotal = var->upper_margin + vsyncstart + vsyncend - 2;
vblankstart = var->yres;
vblankend = vtotal + 2;
enable_mmio();
crtc_unlock();
- write3CE(CyberControl,8);
+ write3CE(CyberControl, 8);
if (flatpanel && var->xres < nativex) {
/*
@@ -814,18 +897,18 @@ static int tridentfb_set_par(struct fb_info *info)
* than requested resolution decide whether
* we stretch or center
*/
- t_outb(0xEB,0x3C2);
+ t_outb(0xEB, 0x3C2);
shadowmode_on();
- if (center)
+ if (center)
screen_center();
else if (stretch)
screen_stretch();
} else {
- t_outb(0x2B,0x3C2);
- write3CE(CyberControl,8);
+ t_outb(0x2B, 0x3C2);
+ write3CE(CyberControl, 8);
}
/* vertical timing values */
@@ -834,15 +917,15 @@ static int tridentfb_set_par(struct fb_info *info)
write3X4(CRTVSyncStart, vsyncstart & 0xFF);
write3X4(CRTVSyncEnd, (vsyncend & 0x0F));
write3X4(CRTVBlankStart, vblankstart & 0xFF);
- write3X4(CRTVBlankEnd, 0/*p->vblankend & 0xFF*/);
+ write3X4(CRTVBlankEnd, 0 /* p->vblankend & 0xFF */ );
/* horizontal timing values */
write3X4(CRTHTotal, htotal & 0xFF);
write3X4(CRTHDispEnd, hdispend & 0xFF);
write3X4(CRTHSyncStart, hsyncstart & 0xFF);
- write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20)<<2));
+ write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
write3X4(CRTHBlankStart, hblankstart & 0xFF);
- write3X4(CRTHBlankEnd, 0/*(p->hblankend & 0x1F)*/);
+ write3X4(CRTHBlankEnd, 0 /* (p->hblankend & 0x1F) */ );
/* higher bits of vertical timing values */
tmp = 0x10;
@@ -856,7 +939,7 @@ static int tridentfb_set_par(struct fb_info *info)
if (vsyncstart & 0x200) tmp |= 0x80;
write3X4(CRTOverflow, tmp);
- tmp = read3X4(CRTHiOrd) | 0x08; //line compare bit 10
+ tmp = read3X4(CRTHiOrd) | 0x08; /* line compare bit 10 */
if (vtotal & 0x400) tmp |= 0x80;
if (vblankstart & 0x400) tmp |= 0x40;
if (vsyncstart & 0x400) tmp |= 0x20;
@@ -867,84 +950,100 @@ static int tridentfb_set_par(struct fb_info *info)
if (htotal & 0x800) tmp |= 0x800 >> 11;
if (hblankstart & 0x800) tmp |= 0x800 >> 7;
write3X4(HorizOverflow, tmp);
-
+
tmp = 0x40;
if (vblankstart & 0x200) tmp |= 0x20;
-//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; //double scan for 200 line modes
+//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */
write3X4(CRTMaxScanLine, tmp);
- write3X4(CRTLineCompare,0xFF);
- write3X4(CRTPRowScan,0);
- write3X4(CRTModeControl,0xC3);
+ write3X4(CRTLineCompare, 0xFF);
+ write3X4(CRTPRowScan, 0);
+ write3X4(CRTModeControl, 0xC3);
- write3X4(LinearAddReg,0x20); //enable linear addressing
+ write3X4(LinearAddReg, 0x20); /* enable linear addressing */
- tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80;
- write3X4(CRTCModuleTest,tmp); //enable access extended memory
+ tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80;
+ write3X4(CRTCModuleTest, tmp); /* enable access extended memory */
- write3X4(GraphEngReg, 0x80); //enable GE for text acceleration
+ write3X4(GraphEngReg, 0x80); /* enable GE for text acceleration */
-#ifdef CONFIG_FB_TRIDENT_ACCEL
- acc->init_accel(info->var.xres,bpp);
+#ifdef CONFIG_FB_TRIDENT_ACCEL
+ acc->init_accel(info->var.xres, bpp);
#endif
-
+
switch (bpp) {
- case 8: tmp = 0x00; break;
- case 16: tmp = 0x05; break;
- case 24: tmp = 0x29; break;
- case 32: tmp = 0x09;
+ case 8:
+ tmp = 0x00;
+ break;
+ case 16:
+ tmp = 0x05;
+ break;
+ case 24:
+ tmp = 0x29;
+ break;
+ case 32:
+ tmp = 0x09;
+ break;
}
write3X4(PixelBusReg, tmp);
tmp = 0x10;
if (chipcyber)
- tmp |= 0x20;
- write3X4(DRAMControl, tmp); //both IO,linear enable
+ tmp |= 0x20;
+ write3X4(DRAMControl, tmp); /* both IO, linear enable */
write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
- write3X4(Performance,0x92);
- write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable
+ write3X4(Performance, 0x92);
+ write3X4(PCIReg, 0x07); /* MMIO & PCI read and write burst enable */
/* convert from picoseconds to MHz */
- par->vclk = 1000000/info->var.pixclock;
+ par->vclk = 1000000 / info->var.pixclock;
if (bpp == 32)
- par->vclk *=2;
+ par->vclk *= 2;
set_vclk(par->vclk);
- write3C4(0,3);
- write3C4(1,1); //set char clock 8 dots wide
- write3C4(2,0x0F); //enable 4 maps because needed in chain4 mode
- write3C4(3,0);
- write3C4(4,0x0E); //memory mode enable bitmaps ??
+ write3C4(0, 3);
+ write3C4(1, 1); /* set char clock 8 dots wide */
+ write3C4(2, 0x0F); /* enable 4 maps because needed in chain4 mode */
+ write3C4(3, 0);
+ write3C4(4, 0x0E); /* memory mode enable bitmaps ?? */
- write3CE(MiscExtFunc,(bpp==32)?0x1A:0x12); //divide clock by 2 if 32bpp
- //chain4 mode display and CPU path
- write3CE(0x5,0x40); //no CGA compat,allow 256 col
- write3CE(0x6,0x05); //graphics mode
- write3CE(0x7,0x0F); //planes?
+ write3CE(MiscExtFunc, (bpp == 32) ? 0x1A : 0x12); /* divide clock by 2 if 32bpp */
+ /* chain4 mode display and CPU path */
+ write3CE(0x5, 0x40); /* no CGA compat, allow 256 col */
+ write3CE(0x6, 0x05); /* graphics mode */
+ write3CE(0x7, 0x0F); /* planes? */
if (chip_id == CYBERBLADEXPAi1) {
/* This fixes snow-effect in 32 bpp */
- write3X4(CRTHSyncStart,0x84);
+ write3X4(CRTHSyncStart, 0x84);
}
- writeAttr(0x10,0x41); //graphics mode and support 256 color modes
- writeAttr(0x12,0x0F); //planes
- writeAttr(0x13,0); //horizontal pel panning
+ writeAttr(0x10, 0x41); /* graphics mode and support 256 color modes */
+ writeAttr(0x12, 0x0F); /* planes */
+ writeAttr(0x13, 0); /* horizontal pel panning */
- //colors
- for(tmp = 0;tmp < 0x10;tmp++)
- writeAttr(tmp,tmp);
- readb(par->io_virt + CRT + 0x0A); //flip-flop to index
- t_outb(0x20, 0x3C0); //enable attr
+ /* colors */
+ for (tmp = 0; tmp < 0x10; tmp++)
+ writeAttr(tmp, tmp);
+ readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */
+ t_outb(0x20, 0x3C0); /* enable attr */
switch (bpp) {
- case 8: tmp = 0;break; //256 colors
- case 15: tmp = 0x10;break;
- case 16: tmp = 0x30;break; //hicolor
- case 24: //truecolor
- case 32: tmp = 0xD0;break;
+ case 8:
+ tmp = 0;
+ break;
+ case 15:
+ tmp = 0x10;
+ break;
+ case 16:
+ tmp = 0x30;
+ break;
+ case 24:
+ case 32:
+ tmp = 0xD0;
+ break;
}
t_inb(0x3C8);
@@ -952,37 +1051,36 @@ static int tridentfb_set_par(struct fb_info *info)
t_inb(0x3C6);
t_inb(0x3C6);
t_inb(0x3C6);
- t_outb(tmp,0x3C6);
+ t_outb(tmp, 0x3C6);
t_inb(0x3C8);
if (flatpanel)
set_number_of_lines(info->var.yres);
- set_lwidth(info->var.xres * bpp/(4*16));
+ set_lwidth(info->var.xres * bpp / (4 * 16));
info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- info->fix.line_length = info->var.xres * (bpp >> 3);
- info->cmap.len = (bpp == 8) ? 256: 16;
+ info->fix.line_length = info->var.xres * (bpp >> 3);
+ info->cmap.len = (bpp == 8) ? 256 : 16;
debug("exit\n");
return 0;
}
/* Set one color register */
static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
{
int bpp = info->var.bits_per_pixel;
if (regno >= info->cmap.len)
return 1;
-
if (bpp == 8) {
- t_outb(0xFF,0x3C6);
- t_outb(regno,0x3C8);
+ t_outb(0xFF, 0x3C6);
+ t_outb(regno, 0x3C8);
- t_outb(red>>10,0x3C9);
- t_outb(green>>10,0x3C9);
- t_outb(blue>>10,0x3C9);
+ t_outb(red >> 10, 0x3C9);
+ t_outb(green >> 10, 0x3C9);
+ t_outb(blue >> 10, 0x3C9);
} else if (regno < 16) {
if (bpp == 16) { /* RGB 565 */
@@ -994,29 +1092,28 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
((u32 *)(info->pseudo_palette))[regno] = col;
} else if (bpp == 32) /* ARGB 8888 */
((u32*)info->pseudo_palette)[regno] =
- ((transp & 0xFF00) <<16) |
- ((red & 0xFF00) << 8) |
+ ((transp & 0xFF00) << 16) |
+ ((red & 0xFF00) << 8) |
((green & 0xFF00)) |
- ((blue & 0xFF00)>>8);
+ ((blue & 0xFF00) >> 8);
}
-// debug("exit\n");
+/* debug("exit\n"); */
return 0;
}
/* Try blanking the screen.For flat panels it does nothing */
static int tridentfb_blank(int blank_mode, struct fb_info *info)
{
- unsigned char PMCont,DPMSCont;
+ unsigned char PMCont, DPMSCont;
debug("enter\n");
if (flatpanel)
return 0;
- t_outb(0x04,0x83C8); /* Read DPMS Control */
+ t_outb(0x04, 0x83C8); /* Read DPMS Control */
PMCont = t_inb(0x83C6) & 0xFC;
DPMSCont = read3CE(PowerStatus) & 0xFC;
- switch (blank_mode)
- {
+ switch (blank_mode) {
case FB_BLANK_UNBLANK:
/* Screen: On, HSync: On, VSync: On */
case FB_BLANK_NORMAL:
@@ -1039,11 +1136,11 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
PMCont |= 0x00;
DPMSCont |= 0x03;
break;
- }
+ }
- write3CE(PowerStatus,DPMSCont);
- t_outb(4,0x83C8);
- t_outb(PMCont,0x83C6);
+ write3CE(PowerStatus, DPMSCont);
+ t_outb(4, 0x83C8);
+ t_outb(PMCont, 0x83C6);
debug("exit\n");
@@ -1051,7 +1148,20 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
}
-static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id)
+static struct fb_ops tridentfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = tridentfb_setcolreg,
+ .fb_pan_display = tridentfb_pan_display,
+ .fb_blank = tridentfb_blank,
+ .fb_check_var = tridentfb_check_var,
+ .fb_set_par = tridentfb_set_par,
+ .fb_fillrect = tridentfb_fillrect,
+ .fb_copyarea = tridentfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static int __devinit trident_pci_probe(struct pci_dev * dev,
+ const struct pci_device_id * id)
{
int err;
unsigned char revision;
@@ -1062,31 +1172,42 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
chip_id = id->device;
- if(chip_id == CYBERBLADEi1)
+ if (chip_id == CYBERBLADEi1)
output("*** Please do use cyblafb, Cyberblade/i1 support "
"will soon be removed from tridentfb!\n");
/* If PCI id is 0x9660 then further detect chip type */
-
+
if (chip_id == TGUI9660) {
- outb(RevisionID,0x3C4);
- revision = inb(0x3C5);
-
+ outb(RevisionID, 0x3C4);
+ revision = inb(0x3C5);
+
switch (revision) {
- case 0x22:
- case 0x23: chip_id = CYBER9397;break;
- case 0x2A: chip_id = CYBER9397DVD;break;
- case 0x30:
- case 0x33:
- case 0x34:
- case 0x35:
- case 0x38:
- case 0x3A:
- case 0xB3: chip_id = CYBER9385;break;
- case 0x40 ... 0x43: chip_id = CYBER9382;break;
- case 0x4A: chip_id = CYBER9388;break;
- default:break;
+ case 0x22:
+ case 0x23:
+ chip_id = CYBER9397;
+ break;
+ case 0x2A:
+ chip_id = CYBER9397DVD;
+ break;
+ case 0x30:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x38:
+ case 0x3A:
+ case 0xB3:
+ chip_id = CYBER9385;
+ break;
+ case 0x40 ... 0x43:
+ chip_id = CYBER9382;
+ break;
+ case 0x4A:
+ chip_id = CYBER9388;
+ break;
+ default:
+ break;
}
}
@@ -1095,8 +1216,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
if (is_xp(chip_id)) {
acc = &accel_xp;
- } else
- if (is_blade(chip_id)) {
+ } else if (is_blade(chip_id)) {
acc = &accel_blade;
} else {
acc = &accel_image;
@@ -1108,8 +1228,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
fb_info.par = &default_par;
/* setup MMIO region */
- tridentfb_fix.mmio_start = pci_resource_start(dev,1);
- tridentfb_fix.mmio_len = chip3D ? 0x20000:0x10000;
+ tridentfb_fix.mmio_start = pci_resource_start(dev, 1);
+ tridentfb_fix.mmio_len = chip3D ? 0x20000 : 0x10000;
if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) {
debug("request_region failed!\n");
@@ -1125,11 +1245,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
}
enable_mmio();
-
+
/* setup framebuffer memory */
- tridentfb_fix.smem_start = pci_resource_start(dev,0);
+ tridentfb_fix.smem_start = pci_resource_start(dev, 0);
tridentfb_fix.smem_len = get_memsize();
-
+
if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
debug("request_mem_region failed!\n");
err = -1;
@@ -1137,7 +1257,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
}
fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
- tridentfb_fix.smem_len);
+ tridentfb_fix.smem_len);
if (!fb_info.screen_base) {
release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
@@ -1147,13 +1267,13 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
}
output("%s board found\n", pci_name(dev));
-#if 0
- output("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",
+#if 0
+ output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n",
tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);
#endif
displaytype = get_displaytype();
- if(flatpanel)
+ if (flatpanel)
nativex = get_nativex();
fb_info.fix = tridentfb_fix;
@@ -1166,11 +1286,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
#endif
fb_info.pseudo_palette = pseudo_pal;
- if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) {
+ if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) {
err = -EINVAL;
goto out_unmap;
}
- fb_alloc_cmap(&fb_info.cmap,256,0);
+ fb_alloc_cmap(&fb_info.cmap, 256, 0);
if (defaultaccel && acc)
default_var.accel_flags |= FB_ACCELF_TEXT;
else
@@ -1184,8 +1304,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
goto out_unmap;
}
output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
- fb_info.node, fb_info.fix.id,default_var.xres,
- default_var.yres,default_var.bits_per_pixel);
+ fb_info.node, fb_info.fix.id, default_var.xres,
+ default_var.yres, default_var.bits_per_pixel);
return 0;
out_unmap:
@@ -1196,7 +1316,7 @@ out_unmap:
return err;
}
-static void __devexit trident_pci_remove(struct pci_dev * dev)
+static void __devexit trident_pci_remove(struct pci_dev *dev)
{
struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par;
unregister_framebuffer(&fb_info);
@@ -1208,69 +1328,70 @@ static void __devexit trident_pci_remove(struct pci_dev * dev)
/* List of boards that we are trying to support */
static struct pci_device_id trident_devices[] = {
- {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+ {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0,}
-};
-
-MODULE_DEVICE_TABLE(pci,trident_devices);
+};
+
+MODULE_DEVICE_TABLE(pci, trident_devices);
static struct pci_driver tridentfb_pci_driver = {
- .name = "tridentfb",
- .id_table = trident_devices,
- .probe = trident_pci_probe,
- .remove = __devexit_p(trident_pci_remove)
+ .name = "tridentfb",
+ .id_table = trident_devices,
+ .probe = trident_pci_probe,
+ .remove = __devexit_p(trident_pci_remove)
};
/*
* Parse user specified options (`video=trident:')
* example:
- * video=trident:800x600,bpp=16,noaccel
+ * video=trident:800x600,bpp=16,noaccel
*/
#ifndef MODULE
static int tridentfb_setup(char *options)
{
- char * opt;
+ char *opt;
if (!options || !*options)
return 0;
- while((opt = strsep(&options,",")) != NULL ) {
- if (!*opt) continue;
- if (!strncmp(opt,"noaccel",7))
+ while ((opt = strsep(&options, ",")) != NULL) {
+ if (!*opt)
+ continue;
+ if (!strncmp(opt, "noaccel", 7))
noaccel = 1;
- else if (!strncmp(opt,"fp",2))
+ else if (!strncmp(opt, "fp", 2))
displaytype = DISPLAY_FP;
- else if (!strncmp(opt,"crt",3))
+ else if (!strncmp(opt, "crt", 3))
displaytype = DISPLAY_CRT;
- else if (!strncmp(opt,"bpp=",4))
- bpp = simple_strtoul(opt+4,NULL,0);
- else if (!strncmp(opt,"center",6))
+ else if (!strncmp(opt, "bpp=", 4))
+ bpp = simple_strtoul(opt + 4, NULL, 0);
+ else if (!strncmp(opt, "center", 6))
center = 1;
- else if (!strncmp(opt,"stretch",7))
+ else if (!strncmp(opt, "stretch", 7))
stretch = 1;
- else if (!strncmp(opt,"memsize=",8))
- memsize = simple_strtoul(opt+8,NULL,0);
- else if (!strncmp(opt,"memdiff=",8))
- memdiff = simple_strtoul(opt+8,NULL,0);
- else if (!strncmp(opt,"nativex=",8))
- nativex = simple_strtoul(opt+8,NULL,0);
+ else if (!strncmp(opt, "memsize=", 8))
+ memsize = simple_strtoul(opt + 8, NULL, 0);
+ else if (!strncmp(opt, "memdiff=", 8))
+ memdiff = simple_strtoul(opt + 8, NULL, 0);
+ else if (!strncmp(opt, "nativex=", 8))
+ nativex = simple_strtoul(opt + 8, NULL, 0);
else
mode = opt;
}
@@ -1296,18 +1417,6 @@ static void __exit tridentfb_exit(void)
pci_unregister_driver(&tridentfb_pci_driver);
}
-static struct fb_ops tridentfb_ops = {
- .owner = THIS_MODULE,
- .fb_setcolreg = tridentfb_setcolreg,
- .fb_pan_display = tridentfb_pan_display,
- .fb_blank = tridentfb_blank,
- .fb_check_var = tridentfb_check_var,
- .fb_set_par = tridentfb_set_par,
- .fb_fillrect = tridentfb_fillrect,
- .fb_copyarea= tridentfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-};
-
module_init(tridentfb_init);
module_exit(tridentfb_exit);
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
new file mode 100644
index 00000000000..b983d262ab7
--- /dev/null
+++ b/drivers/video/uvesafb.c
@@ -0,0 +1,2066 @@
+/*
+ * A framebuffer driver for VBE 2.0+ compliant video cards
+ *
+ * (c) 2007 Michal Januszewski <spock@gentoo.org>
+ * Loosely based upon the vesafb driver.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/skbuff.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+#include <linux/connector.h>
+#include <linux/random.h>
+#include <linux/platform_device.h>
+#include <linux/limits.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <video/edid.h>
+#include <video/uvesafb.h>
+#ifdef CONFIG_X86
+#include <video/vga.h>
+#endif
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+#include "edid.h"
+
+static struct cb_id uvesafb_cn_id = {
+ .idx = CN_IDX_V86D,
+ .val = CN_VAL_V86D_UVESAFB
+};
+static char v86d_path[PATH_MAX] = "/sbin/v86d";
+static char v86d_started; /* has v86d been started by uvesafb? */
+
+static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
+ .id = "VESA VGA",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .accel = FB_ACCEL_NONE,
+ .visual = FB_VISUAL_TRUECOLOR,
+};
+
+static int mtrr __devinitdata = 3; /* enable mtrr by default */
+static int blank __devinitdata = 1; /* enable blanking by default */
+static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
+static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
+static int nocrtc __devinitdata; /* ignore CRTC settings */
+static int noedid __devinitdata; /* don't try DDC transfers */
+static int vram_remap __devinitdata; /* set amt. of memory to be used */
+static int vram_total __devinitdata; /* set total amount of memory */
+static u16 maxclk __devinitdata; /* maximum pixel clock */
+static u16 maxvf __devinitdata; /* maximum vertical frequency */
+static u16 maxhf __devinitdata; /* maximum horizontal frequency */
+static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
+static char *mode_option __devinitdata;
+
+static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
+static DEFINE_MUTEX(uvfb_lock);
+
+/*
+ * A handler for replies from userspace.
+ *
+ * Make sure each message passes consistency checks and if it does,
+ * find the kernel part of the task struct, copy the registers and
+ * the buffer contents and then complete the task.
+ */
+static void uvesafb_cn_callback(void *data)
+{
+ struct cn_msg *msg = data;
+ struct uvesafb_task *utask;
+ struct uvesafb_ktask *task;
+
+ if (msg->seq >= UVESAFB_TASKS_MAX)
+ return;
+
+ mutex_lock(&uvfb_lock);
+ task = uvfb_tasks[msg->seq];
+
+ if (!task || msg->ack != task->ack) {
+ mutex_unlock(&uvfb_lock);
+ return;
+ }
+
+ utask = (struct uvesafb_task *)msg->data;
+
+ /* Sanity checks for the buffer length. */
+ if (task->t.buf_len < utask->buf_len ||
+ utask->buf_len > msg->len - sizeof(*utask)) {
+ mutex_unlock(&uvfb_lock);
+ return;
+ }
+
+ uvfb_tasks[msg->seq] = NULL;
+ mutex_unlock(&uvfb_lock);
+
+ memcpy(&task->t, utask, sizeof(*utask));
+
+ if (task->t.buf_len && task->buf)
+ memcpy(task->buf, utask + 1, task->t.buf_len);
+
+ complete(task->done);
+ return;
+}
+
+static int uvesafb_helper_start(void)
+{
+ char *envp[] = {
+ "HOME=/",
+ "PATH=/sbin:/bin",
+ NULL,
+ };
+
+ char *argv[] = {
+ v86d_path,
+ NULL,
+ };
+
+ return call_usermodehelper(v86d_path, argv, envp, 1);
+}
+
+/*
+ * Execute a uvesafb task.
+ *
+ * Returns 0 if the task is executed successfully.
+ *
+ * A message sent to the userspace consists of the uvesafb_task
+ * struct and (optionally) a buffer. The uvesafb_task struct is
+ * a simplified version of uvesafb_ktask (its kernel counterpart)
+ * containing only the register values, flags and the length of
+ * the buffer.
+ *
+ * Each message is assigned a sequence number (increased linearly)
+ * and a random ack number. The sequence number is used as a key
+ * for the uvfb_tasks array which holds pointers to uvesafb_ktask
+ * structs for all requests.
+ */
+static int uvesafb_exec(struct uvesafb_ktask *task)
+{
+ static int seq;
+ struct cn_msg *m;
+ int err;
+ int len = sizeof(task->t) + task->t.buf_len;
+
+ /*
+ * Check whether the message isn't longer than the maximum
+ * allowed by connector.
+ */
+ if (sizeof(*m) + len > CONNECTOR_MAX_MSG_SIZE) {
+ printk(KERN_WARNING "uvesafb: message too long (%d), "
+ "can't execute task\n", (int)(sizeof(*m) + len));
+ return -E2BIG;
+ }
+
+ m = kzalloc(sizeof(*m) + len, GFP_KERNEL);
+ if (!m)
+ return -ENOMEM;
+
+ init_completion(task->done);
+
+ memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
+ m->seq = seq;
+ m->len = len;
+ m->ack = random32();
+
+ /* uvesafb_task structure */
+ memcpy(m + 1, &task->t, sizeof(task->t));
+
+ /* Buffer */
+ memcpy((u8 *)(m + 1) + sizeof(task->t), task->buf, task->t.buf_len);
+
+ /*
+ * Save the message ack number so that we can find the kernel
+ * part of this task when a reply is received from userspace.
+ */
+ task->ack = m->ack;
+
+ mutex_lock(&uvfb_lock);
+
+ /* If all slots are taken -- bail out. */
+ if (uvfb_tasks[seq]) {
+ mutex_unlock(&uvfb_lock);
+ return -EBUSY;
+ }
+
+ /* Save a pointer to the kernel part of the task struct. */
+ uvfb_tasks[seq] = task;
+ mutex_unlock(&uvfb_lock);
+
+ err = cn_netlink_send(m, 0, gfp_any());
+ if (err == -ESRCH) {
+ /*
+ * Try to start the userspace helper if sending
+ * the request failed the first time.
+ */
+ err = uvesafb_helper_start();
+ if (err) {
+ printk(KERN_ERR "uvesafb: failed to execute %s\n",
+ v86d_path);
+ printk(KERN_ERR "uvesafb: make sure that the v86d "
+ "helper is installed and executable\n");
+ } else {
+ v86d_started = 1;
+ err = cn_netlink_send(m, 0, gfp_any());
+ }
+ }
+ kfree(m);
+
+ if (!err && !(task->t.flags & TF_EXIT))
+ err = !wait_for_completion_timeout(task->done,
+ msecs_to_jiffies(UVESAFB_TIMEOUT));
+
+ mutex_lock(&uvfb_lock);
+ uvfb_tasks[seq] = NULL;
+ mutex_unlock(&uvfb_lock);
+
+ seq++;
+ if (seq >= UVESAFB_TASKS_MAX)
+ seq = 0;
+
+ return err;
+}
+
+/*
+ * Free a uvesafb_ktask struct.
+ */
+static void uvesafb_free(struct uvesafb_ktask *task)
+{
+ if (task) {
+ if (task->done)
+ kfree(task->done);
+ kfree(task);
+ }
+}
+
+/*
+ * Prepare a uvesafb_ktask struct to be used again.
+ */
+static void uvesafb_reset(struct uvesafb_ktask *task)
+{
+ struct completion *cpl = task->done;
+
+ memset(task, 0, sizeof(*task));
+ task->done = cpl;
+}
+
+/*
+ * Allocate and prepare a uvesafb_ktask struct.
+ */
+static struct uvesafb_ktask *uvesafb_prep(void)
+{
+ struct uvesafb_ktask *task;
+
+ task = kzalloc(sizeof(*task), GFP_KERNEL);
+ if (task) {
+ task->done = kzalloc(sizeof(*task->done), GFP_KERNEL);
+ if (!task->done) {
+ kfree(task);
+ task = NULL;
+ }
+ }
+ return task;
+}
+
+static void uvesafb_setup_var(struct fb_var_screeninfo *var,
+ struct fb_info *info, struct vbe_mode_ib *mode)
+{
+ struct uvesafb_par *par = info->par;
+
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->sync = FB_SYNC_VERT_HIGH_ACT;
+
+ var->xres = mode->x_res;
+ var->yres = mode->y_res;
+ var->xres_virtual = mode->x_res;
+ var->yres_virtual = (par->ypan) ?
+ info->fix.smem_len / mode->bytes_per_scan_line :
+ mode->y_res;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->bits_per_pixel = mode->bits_per_pixel;
+
+ if (var->bits_per_pixel == 15)
+ var->bits_per_pixel = 16;
+
+ if (var->bits_per_pixel > 8) {
+ var->red.offset = mode->red_off;
+ var->red.length = mode->red_len;
+ var->green.offset = mode->green_off;
+ var->green.length = mode->green_len;
+ var->blue.offset = mode->blue_off;
+ var->blue.length = mode->blue_len;
+ var->transp.offset = mode->rsvd_off;
+ var->transp.length = mode->rsvd_len;
+ } else {
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
+ var->transp.offset = 0;
+
+ /*
+ * We're assuming that we can switch the DAC to 8 bits. If
+ * this proves to be incorrect, we'll update the fields
+ * later in set_par().
+ */
+ if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->transp.length = 0;
+ } else {
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
+ var->transp.length = 0;
+ }
+ }
+}
+
+static int uvesafb_vbe_find_mode(struct uvesafb_par *par,
+ int xres, int yres, int depth, unsigned char flags)
+{
+ int i, match = -1, h = 0, d = 0x7fffffff;
+
+ for (i = 0; i < par->vbe_modes_cnt; i++) {
+ h = abs(par->vbe_modes[i].x_res - xres) +
+ abs(par->vbe_modes[i].y_res - yres) +
+ abs(depth - par->vbe_modes[i].depth);
+
+ /*
+ * We have an exact match in terms of resolution
+ * and depth.
+ */
+ if (h == 0)
+ return i;
+
+ if (h < d || (h == d && par->vbe_modes[i].depth > depth)) {
+ d = h;
+ match = i;
+ }
+ }
+ i = 1;
+
+ if (flags & UVESAFB_EXACT_DEPTH &&
+ par->vbe_modes[match].depth != depth)
+ i = 0;
+
+ if (flags & UVESAFB_EXACT_RES && d > 24)
+ i = 0;
+
+ if (i != 0)
+ return match;
+ else
+ return -1;
+}
+
+static u8 *uvesafb_vbe_state_save(struct uvesafb_par *par)
+{
+ struct uvesafb_ktask *task;
+ u8 *state;
+ int err;
+
+ if (!par->vbe_state_size)
+ return NULL;
+
+ state = kmalloc(par->vbe_state_size, GFP_KERNEL);
+ if (!state)
+ return NULL;
+
+ task = uvesafb_prep();
+ if (!task) {
+ kfree(state);
+ return NULL;
+ }
+
+ task->t.regs.eax = 0x4f04;
+ task->t.regs.ecx = 0x000f;
+ task->t.regs.edx = 0x0001;
+ task->t.flags = TF_BUF_RET | TF_BUF_ESBX;
+ task->t.buf_len = par->vbe_state_size;
+ task->buf = state;
+ err = uvesafb_exec(task);
+
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
+ printk(KERN_WARNING "uvesafb: VBE get state call "
+ "failed (eax=0x%x, err=%d)\n",
+ task->t.regs.eax, err);
+ kfree(state);
+ state = NULL;
+ }
+
+ uvesafb_free(task);
+ return state;
+}
+
+static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
+{
+ struct uvesafb_ktask *task;
+ int err;
+
+ if (!state_buf)
+ return;
+
+ task = uvesafb_prep();
+ if (!task)
+ return;
+
+ task->t.regs.eax = 0x4f04;
+ task->t.regs.ecx = 0x000f;
+ task->t.regs.edx = 0x0002;
+ task->t.buf_len = par->vbe_state_size;
+ task->t.flags = TF_BUF_ESBX;
+ task->buf = state_buf;
+
+ err = uvesafb_exec(task);
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f)
+ printk(KERN_WARNING "uvesafb: VBE state restore call "
+ "failed (eax=0x%x, err=%d)\n",
+ task->t.regs.eax, err);
+
+ uvesafb_free(task);
+}
+
+static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
+{
+ int err;
+
+ task->t.regs.eax = 0x4f00;
+ task->t.flags = TF_VBEIB;
+ task->t.buf_len = sizeof(struct vbe_ib);
+ task->buf = &par->vbe_ib;
+ strncpy(par->vbe_ib.vbe_signature, "VBE2", 4);
+
+ err = uvesafb_exec(task);
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
+ printk(KERN_ERR "uvesafb: Getting VBE info block failed "
+ "(eax=0x%x, err=%d)\n", (u32)task->t.regs.eax,
+ err);
+ return -EINVAL;
+ }
+
+ if (par->vbe_ib.vbe_version < 0x0200) {
+ printk(KERN_ERR "uvesafb: Sorry, pre-VBE 2.0 cards are "
+ "not supported.\n");
+ return -EINVAL;
+ }
+
+ if (!par->vbe_ib.mode_list_ptr) {
+ printk(KERN_ERR "uvesafb: Missing mode list!\n");
+ return -EINVAL;
+ }
+
+ printk(KERN_INFO "uvesafb: ");
+
+ /*
+ * Convert string pointers and the mode list pointer into
+ * usable addresses. Print informational messages about the
+ * video adapter and its vendor.
+ */
+ if (par->vbe_ib.oem_vendor_name_ptr)
+ printk("%s, ",
+ ((char *)task->buf) + par->vbe_ib.oem_vendor_name_ptr);
+
+ if (par->vbe_ib.oem_product_name_ptr)
+ printk("%s, ",
+ ((char *)task->buf) + par->vbe_ib.oem_product_name_ptr);
+
+ if (par->vbe_ib.oem_product_rev_ptr)
+ printk("%s, ",
+ ((char *)task->buf) + par->vbe_ib.oem_product_rev_ptr);
+
+ if (par->vbe_ib.oem_string_ptr)
+ printk("OEM: %s, ",
+ ((char *)task->buf) + par->vbe_ib.oem_string_ptr);
+
+ printk("VBE v%d.%d\n", ((par->vbe_ib.vbe_version & 0xff00) >> 8),
+ par->vbe_ib.vbe_version & 0xff);
+
+ return 0;
+}
+
+static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
+{
+ int off = 0, err;
+ u16 *mode;
+
+ par->vbe_modes_cnt = 0;
+
+ /* Count available modes. */
+ mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
+ while (*mode != 0xffff) {
+ par->vbe_modes_cnt++;
+ mode++;
+ }
+
+ par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) *
+ par->vbe_modes_cnt, GFP_KERNEL);
+ if (!par->vbe_modes)
+ return -ENOMEM;
+
+ /* Get info about all available modes. */
+ mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
+ while (*mode != 0xffff) {
+ struct vbe_mode_ib *mib;
+
+ uvesafb_reset(task);
+ task->t.regs.eax = 0x4f01;
+ task->t.regs.ecx = (u32) *mode;
+ task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
+ task->t.buf_len = sizeof(struct vbe_mode_ib);
+ task->buf = par->vbe_modes + off;
+
+ err = uvesafb_exec(task);
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
+ printk(KERN_ERR "uvesafb: Getting mode info block "
+ "for mode 0x%x failed (eax=0x%x, err=%d)\n",
+ *mode, (u32)task->t.regs.eax, err);
+ return -EINVAL;
+ }
+
+ mib = task->buf;
+ mib->mode_id = *mode;
+
+ /*
+ * We only want modes that are supported with the current
+ * hardware configuration, color, graphics and that have
+ * support for the LFB.
+ */
+ if ((mib->mode_attr & VBE_MODE_MASK) == VBE_MODE_MASK &&
+ mib->bits_per_pixel >= 8)
+ off++;
+ else
+ par->vbe_modes_cnt--;
+
+ mode++;
+ mib->depth = mib->red_len + mib->green_len + mib->blue_len;
+
+ /*
+ * Handle 8bpp modes and modes with broken color component
+ * lengths.
+ */
+ if (mib->depth == 0 || (mib->depth == 24 &&
+ mib->bits_per_pixel == 32))
+ mib->depth = mib->bits_per_pixel;
+ }
+
+ return 0;
+}
+
+/*
+ * The Protected Mode Interface is 32-bit x86 code, so we only run it on
+ * x86 and not x86_64.
+ */
+#ifdef CONFIG_X86_32
+static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
+{
+ int i, err;
+
+ uvesafb_reset(task);
+ task->t.regs.eax = 0x4f0a;
+ task->t.regs.ebx = 0x0;
+ err = uvesafb_exec(task);
+
+ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
+ par->pmi_setpal = par->ypan = 0;
+ } else {
+ par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
+ + task->t.regs.edi);
+ par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
+ par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
+ printk(KERN_INFO "uvesafb: protected mode interface info at "
+ "%04x:%04x\n",
+ (u16)task->t.regs.es, (u16)task->t.regs.edi);
+ printk(KERN_INFO "uvesafb: pmi: set display start = %p, "
+ "set palette = %p\n", par->pmi_start,
+ par->pmi_pal);
+
+ if (par->pmi_base[3]) {
+ printk(KERN_INFO "uvesafb: pmi: ports = ");
+ for (i = par->pmi_base[3]/2;
+ par->pmi_base[i] != 0xffff; i++)
+ printk("%x ", par->pmi_base[i]);
+ printk("\n");
+
+ if (par->pmi_base[i] != 0xffff) {
+ printk(KERN_INFO "uvesafb: can't handle memory"
+ " requests, pmi disabled\n");
+ par->ypan = par->pmi_setpal = 0;
+ }
+ }
+ }
+ return 0;
+}
+#endif /* CONFIG_X86_32 */
+
+/*
+ * Check whether a video mode is supported by the Video BIOS and is
+ * compatible with the monitor limits.
+ */
+static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
+ struct fb_info *info)
+{
+ if (info->monspecs.gtf) {
+ fb_videomode_to_var(&info->var, mode);
+ if (fb_validate_mode(&info->var, info))
+ return 0;
+ }
+
+ if (uvesafb_vbe_find_mode(info->par, mode->xres, mode->yres, 8,
+ UVESAFB_EXACT_RES) == -1)
+ return 0;
+
+ return 1;
+}
+
+static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
+ struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+ int err = 0;
+
+ if (noedid || par->vbe_ib.vbe_version < 0x0300)
+ return -EINVAL;
+
+ task->t.regs.eax = 0x4f15;
+ task->t.regs.ebx = 0;
+ task->t.regs.ecx = 0;
+ task->t.buf_len = 0;
+ task->t.flags = 0;
+
+ err = uvesafb_exec(task);
+
+ if ((task->t.regs.eax & 0xffff) != 0x004f || err)
+ return -EINVAL;
+
+ if ((task->t.regs.ebx & 0x3) == 3) {
+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports both "
+ "DDC1 and DDC2 transfers\n");
+ } else if ((task->t.regs.ebx & 0x3) == 2) {
+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC2 "
+ "transfers\n");
+ } else if ((task->t.regs.ebx & 0x3) == 1) {
+ printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC1 "
+ "transfers\n");
+ } else {
+ printk(KERN_INFO "uvesafb: VBIOS/hardware doesn't support "
+ "DDC transfers\n");
+ return -EINVAL;
+ }
+
+ task->t.regs.eax = 0x4f15;
+ task->t.regs.ebx = 1;
+ task->t.regs.ecx = task->t.regs.edx = 0;
+ task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
+ task->t.buf_len = EDID_LENGTH;
+ task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
+
+ err = uvesafb_exec(task);
+
+ if ((task->t.regs.eax & 0xffff) == 0x004f && !err) {
+ fb_edid_to_monspecs(task->buf, &info->monspecs);
+
+ if (info->monspecs.vfmax && info->monspecs.hfmax) {
+ /*
+ * If the maximum pixel clock wasn't specified in
+ * the EDID block, set it to 300 MHz.
+ */
+ if (info->monspecs.dclkmax == 0)
+ info->monspecs.dclkmax = 300 * 1000000;
+ info->monspecs.gtf = 1;
+ }
+ } else {
+ err = -EINVAL;
+ }
+
+ kfree(task->buf);
+ return err;
+}
+
+static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
+ struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+ int i;
+
+ memset(&info->monspecs, 0, sizeof(info->monspecs));
+
+ /*
+ * If we don't get all necessary data from the EDID block,
+ * mark it as incompatible with the GTF and set nocrtc so
+ * that we always use the default BIOS refresh rate.
+ */
+ if (uvesafb_vbe_getedid(task, info)) {
+ info->monspecs.gtf = 0;
+ par->nocrtc = 1;
+ }
+
+ /* Kernel command line overrides. */
+ if (maxclk)
+ info->monspecs.dclkmax = maxclk * 1000000;
+ if (maxvf)
+ info->monspecs.vfmax = maxvf;
+ if (maxhf)
+ info->monspecs.hfmax = maxhf * 1000;
+
+ /*
+ * In case DDC transfers are not supported, the user can provide
+ * monitor limits manually. Lower limits are set to "safe" values.
+ */
+ if (info->monspecs.gtf == 0 && maxclk && maxvf && maxhf) {
+ info->monspecs.dclkmin = 0;
+ info->monspecs.vfmin = 60;
+ info->monspecs.hfmin = 29000;
+ info->monspecs.gtf = 1;
+ par->nocrtc = 0;
+ }
+
+ if (info->monspecs.gtf)
+ printk(KERN_INFO
+ "uvesafb: monitor limits: vf = %d Hz, hf = %d kHz, "
+ "clk = %d MHz\n", info->monspecs.vfmax,
+ (int)(info->monspecs.hfmax / 1000),
+ (int)(info->monspecs.dclkmax / 1000000));
+ else
+ printk(KERN_INFO "uvesafb: no monitor limits have been set, "
+ "default refresh rate will be used\n");
+
+ /* Add VBE modes to the modelist. */
+ for (i = 0; i < par->vbe_modes_cnt; i++) {
+ struct fb_var_screeninfo var;
+ struct vbe_mode_ib *mode;
+ struct fb_videomode vmode;
+
+ mode = &par->vbe_modes[i];
+ memset(&var, 0, sizeof(var));
+
+ var.xres = mode->x_res;
+ var.yres = mode->y_res;
+
+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, &var, info);
+ fb_var_to_videomode(&vmode, &var);
+ fb_add_videomode(&vmode, &info->modelist);
+ }
+
+ /* Add valid VESA modes to our modelist. */
+ for (i = 0; i < VESA_MODEDB_SIZE; i++) {
+ if (uvesafb_is_valid_mode((struct fb_videomode *)
+ &vesa_modes[i], info))
+ fb_add_videomode(&vesa_modes[i], &info->modelist);
+ }
+
+ for (i = 0; i < info->monspecs.modedb_len; i++) {
+ if (uvesafb_is_valid_mode(&info->monspecs.modedb[i], info))
+ fb_add_videomode(&info->monspecs.modedb[i],
+ &info->modelist);
+ }
+
+ return;
+}
+
+static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
+ struct uvesafb_par *par)
+{
+ int err;
+
+ uvesafb_reset(task);
+
+ /*
+ * Get the VBE state buffer size. We want all available
+ * hardware state data (CL = 0x0f).
+ */
+ task->t.regs.eax = 0x4f04;
+ task->t.regs.ecx = 0x000f;
+ task->t.regs.edx = 0x0000;
+ task->t.flags = 0;
+
+ err = uvesafb_exec(task);
+
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
+ printk(KERN_WARNING "uvesafb: VBE state buffer size "
+ "cannot be determined (eax=0x%x, err=%d)\n",
+ task->t.regs.eax, err);
+ par->vbe_state_size = 0;
+ return;
+ }
+
+ par->vbe_state_size = 64 * (task->t.regs.ebx & 0xffff);
+}
+
+static int __devinit uvesafb_vbe_init(struct fb_info *info)
+{
+ struct uvesafb_ktask *task = NULL;
+ struct uvesafb_par *par = info->par;
+ int err;
+
+ task = uvesafb_prep();
+ if (!task)
+ return -ENOMEM;
+
+ err = uvesafb_vbe_getinfo(task, par);
+ if (err)
+ goto out;
+
+ err = uvesafb_vbe_getmodes(task, par);
+ if (err)
+ goto out;
+
+ par->nocrtc = nocrtc;
+#ifdef CONFIG_X86_32
+ par->pmi_setpal = pmi_setpal;
+ par->ypan = ypan;
+
+ if (par->pmi_setpal || par->ypan)
+ uvesafb_vbe_getpmi(task, par);
+#else
+ /* The protected mode interface is not available on non-x86. */
+ par->pmi_setpal = par->ypan = 0;
+#endif
+
+ INIT_LIST_HEAD(&info->modelist);
+ uvesafb_vbe_getmonspecs(task, info);
+ uvesafb_vbe_getstatesize(task, par);
+
+out: uvesafb_free(task);
+ return err;
+}
+
+static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
+{
+ struct list_head *pos;
+ struct fb_modelist *modelist;
+ struct fb_videomode *mode;
+ struct uvesafb_par *par = info->par;
+ int i, modeid;
+
+ /* Has the user requested a specific VESA mode? */
+ if (vbemode) {
+ for (i = 0; i < par->vbe_modes_cnt; i++) {
+ if (par->vbe_modes[i].mode_id == vbemode) {
+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
+ &info->var, info);
+ /*
+ * With pixclock set to 0, the default BIOS
+ * timings will be used in set_par().
+ */
+ info->var.pixclock = 0;
+ modeid = i;
+ goto gotmode;
+ }
+ }
+ printk(KERN_INFO "uvesafb: requested VBE mode 0x%x is "
+ "unavailable\n", vbemode);
+ vbemode = 0;
+ }
+
+ /* Count the modes in the modelist */
+ i = 0;
+ list_for_each(pos, &info->modelist)
+ i++;
+
+ /*
+ * Convert the modelist into a modedb so that we can use it with
+ * fb_find_mode().
+ */
+ mode = kzalloc(i * sizeof(*mode), GFP_KERNEL);
+ if (mode) {
+ i = 0;
+ list_for_each(pos, &info->modelist) {
+ modelist = list_entry(pos, struct fb_modelist, list);
+ mode[i] = modelist->mode;
+ i++;
+ }
+
+ if (!mode_option)
+ mode_option = UVESAFB_DEFAULT_MODE;
+
+ i = fb_find_mode(&info->var, info, mode_option, mode, i,
+ NULL, 8);
+
+ kfree(mode);
+ }
+
+ /* fb_find_mode() failed */
+ if (i == 0 || i >= 3) {
+ info->var.xres = 640;
+ info->var.yres = 480;
+ mode = (struct fb_videomode *)
+ fb_find_best_mode(&info->var, &info->modelist);
+
+ if (mode) {
+ fb_videomode_to_var(&info->var, mode);
+ } else {
+ modeid = par->vbe_modes[0].mode_id;
+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
+ &info->var, info);
+ goto gotmode;
+ }
+ }
+
+ /* Look for a matching VBE mode. */
+ modeid = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres,
+ info->var.bits_per_pixel, UVESAFB_EXACT_RES);
+
+ if (modeid == -1)
+ return -EINVAL;
+
+gotmode:
+ uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
+
+ /*
+ * If we are not VBE3.0+ compliant, we're done -- the BIOS will
+ * ignore our timings anyway.
+ */
+ if (par->vbe_ib.vbe_version < 0x0300 || par->nocrtc)
+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
+ &info->var, info);
+
+ return modeid;
+}
+
+static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
+ int start, struct fb_info *info)
+{
+ struct uvesafb_ktask *task;
+ struct uvesafb_par *par = info->par;
+ int i = par->mode_idx;
+ int err = 0;
+
+ /*
+ * We support palette modifications for 8 bpp modes only, so
+ * there can never be more than 256 entries.
+ */
+ if (start + count > 256)
+ return -EINVAL;
+
+#ifdef CONFIG_X86
+ /* Use VGA registers if mode is VGA-compatible. */
+ if (i >= 0 && i < par->vbe_modes_cnt &&
+ par->vbe_modes[i].mode_attr & VBE_MODE_VGACOMPAT) {
+ for (i = 0; i < count; i++) {
+ outb_p(start + i, dac_reg);
+ outb_p(entries[i].red, dac_val);
+ outb_p(entries[i].green, dac_val);
+ outb_p(entries[i].blue, dac_val);
+ }
+ }
+#ifdef CONFIG_X86_32
+ else if (par->pmi_setpal) {
+ __asm__ __volatile__(
+ "call *(%%esi)"
+ : /* no return value */
+ : "a" (0x4f09), /* EAX */
+ "b" (0), /* EBX */
+ "c" (count), /* ECX */
+ "d" (start), /* EDX */
+ "D" (entries), /* EDI */
+ "S" (&par->pmi_pal)); /* ESI */
+ }
+#endif /* CONFIG_X86_32 */
+ else
+#endif /* CONFIG_X86 */
+ {
+ task = uvesafb_prep();
+ if (!task)
+ return -ENOMEM;
+
+ task->t.regs.eax = 0x4f09;
+ task->t.regs.ebx = 0x0;
+ task->t.regs.ecx = count;
+ task->t.regs.edx = start;
+ task->t.flags = TF_BUF_ESDI;
+ task->t.buf_len = sizeof(struct uvesafb_pal_entry) * count;
+ task->buf = entries;
+
+ err = uvesafb_exec(task);
+ if ((task->t.regs.eax & 0xffff) != 0x004f)
+ err = 1;
+
+ uvesafb_free(task);
+ }
+ return err;
+}
+
+static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ struct uvesafb_pal_entry entry;
+ int shift = 16 - info->var.green.length;
+ int err = 0;
+
+ if (regno >= info->cmap.len)
+ return -EINVAL;
+
+ if (info->var.bits_per_pixel == 8) {
+ entry.red = red >> shift;
+ entry.green = green >> shift;
+ entry.blue = blue >> shift;
+ entry.pad = 0;
+
+ err = uvesafb_setpalette(&entry, 1, regno, info);
+ } else if (regno < 16) {
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ if (info->var.red.offset == 10) {
+ /* 1:5:5:5 */
+ ((u32 *) (info->pseudo_palette))[regno] =
+ ((red & 0xf800) >> 1) |
+ ((green & 0xf800) >> 6) |
+ ((blue & 0xf800) >> 11);
+ } else {
+ /* 0:5:6:5 */
+ ((u32 *) (info->pseudo_palette))[regno] =
+ ((red & 0xf800) ) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
+ }
+ break;
+
+ case 24:
+ case 32:
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ ((u32 *)(info->pseudo_palette))[regno] =
+ (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset);
+ break;
+ }
+ }
+ return err;
+}
+
+static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ struct uvesafb_pal_entry *entries;
+ int shift = 16 - info->var.green.length;
+ int i, err = 0;
+
+ if (info->var.bits_per_pixel == 8) {
+ if (cmap->start + cmap->len > info->cmap.start +
+ info->cmap.len || cmap->start < info->cmap.start)
+ return -EINVAL;
+
+ entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL);
+ if (!entries)
+ return -ENOMEM;
+
+ for (i = 0; i < cmap->len; i++) {
+ entries[i].red = cmap->red[i] >> shift;
+ entries[i].green = cmap->green[i] >> shift;
+ entries[i].blue = cmap->blue[i] >> shift;
+ entries[i].pad = 0;
+ }
+ err = uvesafb_setpalette(entries, cmap->len, cmap->start, info);
+ kfree(entries);
+ } else {
+ /*
+ * For modes with bpp > 8, we only set the pseudo palette in
+ * the fb_info struct. We rely on uvesafb_setcolreg to do all
+ * sanity checking.
+ */
+ for (i = 0; i < cmap->len; i++) {
+ err |= uvesafb_setcolreg(cmap->start + i, cmap->red[i],
+ cmap->green[i], cmap->blue[i],
+ 0, info);
+ }
+ }
+ return err;
+}
+
+static int uvesafb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+#ifdef CONFIG_X86_32
+ int offset;
+ struct uvesafb_par *par = info->par;
+
+ offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
+
+ /*
+ * It turns out it's not the best idea to do panning via vm86,
+ * so we only allow it if we have a PMI.
+ */
+ if (par->pmi_start) {
+ __asm__ __volatile__(
+ "call *(%%edi)"
+ : /* no return value */
+ : "a" (0x4f07), /* EAX */
+ "b" (0), /* EBX */
+ "c" (offset), /* ECX */
+ "d" (offset >> 16), /* EDX */
+ "D" (&par->pmi_start)); /* EDI */
+ }
+#endif
+ return 0;
+}
+
+static int uvesafb_blank(int blank, struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+ struct uvesafb_ktask *task;
+ int err = 1;
+
+#ifdef CONFIG_X86
+ if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
+ int loop = 10000;
+ u8 seq = 0, crtc17 = 0;
+
+ if (blank == FB_BLANK_POWERDOWN) {
+ seq = 0x20;
+ crtc17 = 0x00;
+ err = 0;
+ } else {
+ seq = 0x00;
+ crtc17 = 0x80;
+ err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
+ }
+
+ vga_wseq(NULL, 0x00, 0x01);
+ seq |= vga_rseq(NULL, 0x01) & ~0x20;
+ vga_wseq(NULL, 0x00, seq);
+
+ crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
+ while (loop--);
+ vga_wcrt(NULL, 0x17, crtc17);
+ vga_wseq(NULL, 0x00, 0x03);
+ } else
+#endif /* CONFIG_X86 */
+ {
+ task = uvesafb_prep();
+ if (!task)
+ return -ENOMEM;
+
+ task->t.regs.eax = 0x4f10;
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ task->t.regs.ebx = 0x0001;
+ break;
+ case FB_BLANK_NORMAL:
+ task->t.regs.ebx = 0x0101; /* standby */
+ break;
+ case FB_BLANK_POWERDOWN:
+ task->t.regs.ebx = 0x0401; /* powerdown */
+ break;
+ default:
+ goto out;
+ }
+
+ err = uvesafb_exec(task);
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f)
+ err = 1;
+out: uvesafb_free(task);
+ }
+ return err;
+}
+
+static int uvesafb_open(struct fb_info *info, int user)
+{
+ struct uvesafb_par *par = info->par;
+ int cnt = atomic_read(&par->ref_count);
+
+ if (!cnt && par->vbe_state_size)
+ par->vbe_state_orig = uvesafb_vbe_state_save(par);
+
+ atomic_inc(&par->ref_count);
+ return 0;
+}
+
+static int uvesafb_release(struct fb_info *info, int user)
+{
+ struct uvesafb_ktask *task = NULL;
+ struct uvesafb_par *par = info->par;
+ int cnt = atomic_read(&par->ref_count);
+
+ if (!cnt)
+ return -EINVAL;
+
+ if (cnt != 1)
+ goto out;
+
+ task = uvesafb_prep();
+ if (!task)
+ goto out;
+
+ /* First, try to set the standard 80x25 text mode. */
+ task->t.regs.eax = 0x0003;
+ uvesafb_exec(task);
+
+ /*
+ * Now try to restore whatever hardware state we might have
+ * saved when the fb device was first opened.
+ */
+ uvesafb_vbe_state_restore(par, par->vbe_state_orig);
+out:
+ atomic_dec(&par->ref_count);
+ if (task)
+ uvesafb_free(task);
+ return 0;
+}
+
+static int uvesafb_set_par(struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+ struct uvesafb_ktask *task = NULL;
+ struct vbe_crtc_ib *crtc = NULL;
+ struct vbe_mode_ib *mode = NULL;
+ int i, err = 0, depth = info->var.bits_per_pixel;
+
+ if (depth > 8 && depth != 32)
+ depth = info->var.red.length + info->var.green.length +
+ info->var.blue.length;
+
+ i = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres, depth,
+ UVESAFB_EXACT_RES | UVESAFB_EXACT_DEPTH);
+ if (i >= 0)
+ mode = &par->vbe_modes[i];
+ else
+ return -EINVAL;
+
+ task = uvesafb_prep();
+ if (!task)
+ return -ENOMEM;
+setmode:
+ task->t.regs.eax = 0x4f02;
+ task->t.regs.ebx = mode->mode_id | 0x4000; /* use LFB */
+
+ if (par->vbe_ib.vbe_version >= 0x0300 && !par->nocrtc &&
+ info->var.pixclock != 0) {
+ task->t.regs.ebx |= 0x0800; /* use CRTC data */
+ task->t.flags = TF_BUF_ESDI;
+ crtc = kzalloc(sizeof(struct vbe_crtc_ib), GFP_KERNEL);
+ if (!crtc) {
+ err = -ENOMEM;
+ goto out;
+ }
+ crtc->horiz_start = info->var.xres + info->var.right_margin;
+ crtc->horiz_end = crtc->horiz_start + info->var.hsync_len;
+ crtc->horiz_total = crtc->horiz_end + info->var.left_margin;
+
+ crtc->vert_start = info->var.yres + info->var.lower_margin;
+ crtc->vert_end = crtc->vert_start + info->var.vsync_len;
+ crtc->vert_total = crtc->vert_end + info->var.upper_margin;
+
+ crtc->pixel_clock = PICOS2KHZ(info->var.pixclock) * 1000;
+ crtc->refresh_rate = (u16)(100 * (crtc->pixel_clock /
+ (crtc->vert_total * crtc->horiz_total)));
+
+ if (info->var.vmode & FB_VMODE_DOUBLE)
+ crtc->flags |= 0x1;
+ if (info->var.vmode & FB_VMODE_INTERLACED)
+ crtc->flags |= 0x2;
+ if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
+ crtc->flags |= 0x4;
+ if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
+ crtc->flags |= 0x8;
+ memcpy(&par->crtc, crtc, sizeof(*crtc));
+ } else {
+ memset(&par->crtc, 0, sizeof(*crtc));
+ }
+
+ task->t.buf_len = sizeof(struct vbe_crtc_ib);
+ task->buf = &par->crtc;
+
+ err = uvesafb_exec(task);
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
+ /*
+ * The mode switch might have failed because we tried to
+ * use our own timings. Try again with the default timings.
+ */
+ if (crtc != NULL) {
+ printk(KERN_WARNING "uvesafb: mode switch failed "
+ "(eax=0x%x, err=%d). Trying again with "
+ "default timings.\n", task->t.regs.eax, err);
+ uvesafb_reset(task);
+ kfree(crtc);
+ crtc = NULL;
+ info->var.pixclock = 0;
+ goto setmode;
+ } else {
+ printk(KERN_ERR "uvesafb: mode switch failed (eax="
+ "0x%x, err=%d)\n", task->t.regs.eax, err);
+ err = -EINVAL;
+ goto out;
+ }
+ }
+ par->mode_idx = i;
+
+ /* For 8bpp modes, always try to set the DAC to 8 bits. */
+ if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC &&
+ mode->bits_per_pixel <= 8) {
+ uvesafb_reset(task);
+ task->t.regs.eax = 0x4f08;
+ task->t.regs.ebx = 0x0800;
+
+ err = uvesafb_exec(task);
+ if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
+ ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
+ /*
+ * We've failed to set the DAC palette format -
+ * time to correct var.
+ */
+ info->var.red.length = 6;
+ info->var.green.length = 6;
+ info->var.blue.length = 6;
+ }
+ }
+
+ info->fix.visual = (info->var.bits_per_pixel == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ info->fix.line_length = mode->bytes_per_scan_line;
+
+out: if (crtc != NULL)
+ kfree(crtc);
+ uvesafb_free(task);
+
+ return err;
+}
+
+static void uvesafb_check_limits(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ const struct fb_videomode *mode;
+ struct uvesafb_par *par = info->par;
+
+ /*
+ * If pixclock is set to 0, then we're using default BIOS timings
+ * and thus don't have to perform any checks here.
+ */
+ if (!var->pixclock)
+ return;
+
+ if (par->vbe_ib.vbe_version < 0x0300) {
+ fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, var, info);
+ return;
+ }
+
+ if (!fb_validate_mode(var, info))
+ return;
+
+ mode = fb_find_best_mode(var, &info->modelist);
+ if (mode) {
+ if (mode->xres == var->xres && mode->yres == var->yres &&
+ !(mode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))) {
+ fb_videomode_to_var(var, mode);
+ return;
+ }
+ }
+
+ if (info->monspecs.gtf && !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
+ return;
+ /* Use default refresh rate */
+ var->pixclock = 0;
+}
+
+static int uvesafb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+ struct vbe_mode_ib *mode = NULL;
+ int match = -1;
+ int depth = var->red.length + var->green.length + var->blue.length;
+
+ /*
+ * Various apps will use bits_per_pixel to set the color depth,
+ * which is theoretically incorrect, but which we'll try to handle
+ * here.
+ */
+ if (depth == 0 || abs(depth - var->bits_per_pixel) >= 8)
+ depth = var->bits_per_pixel;
+
+ match = uvesafb_vbe_find_mode(par, var->xres, var->yres, depth,
+ UVESAFB_EXACT_RES);
+ if (match == -1)
+ return -EINVAL;
+
+ mode = &par->vbe_modes[match];
+ uvesafb_setup_var(var, info, mode);
+
+ /*
+ * Check whether we have remapped enough memory for this mode.
+ * We might be called at an early stage, when we haven't remapped
+ * any memory yet, in which case we simply skip the check.
+ */
+ if (var->yres * mode->bytes_per_scan_line > info->fix.smem_len
+ && info->fix.smem_len)
+ return -EINVAL;
+
+ if ((var->vmode & FB_VMODE_DOUBLE) &&
+ !(par->vbe_modes[match].mode_attr & 0x100))
+ var->vmode &= ~FB_VMODE_DOUBLE;
+
+ if ((var->vmode & FB_VMODE_INTERLACED) &&
+ !(par->vbe_modes[match].mode_attr & 0x200))
+ var->vmode &= ~FB_VMODE_INTERLACED;
+
+ uvesafb_check_limits(var, info);
+
+ var->xres_virtual = var->xres;
+ var->yres_virtual = (par->ypan) ?
+ info->fix.smem_len / mode->bytes_per_scan_line :
+ var->yres;
+ return 0;
+}
+
+static void uvesafb_save_state(struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+
+ if (par->vbe_state_saved)
+ kfree(par->vbe_state_saved);
+
+ par->vbe_state_saved = uvesafb_vbe_state_save(par);
+}
+
+static void uvesafb_restore_state(struct fb_info *info)
+{
+ struct uvesafb_par *par = info->par;
+
+ uvesafb_vbe_state_restore(par, par->vbe_state_saved);
+}
+
+static struct fb_ops uvesafb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = uvesafb_open,
+ .fb_release = uvesafb_release,
+ .fb_setcolreg = uvesafb_setcolreg,
+ .fb_setcmap = uvesafb_setcmap,
+ .fb_pan_display = uvesafb_pan_display,
+ .fb_blank = uvesafb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_check_var = uvesafb_check_var,
+ .fb_set_par = uvesafb_set_par,
+ .fb_save_state = uvesafb_save_state,
+ .fb_restore_state = uvesafb_restore_state,
+};
+
+static void __devinit uvesafb_init_info(struct fb_info *info,
+ struct vbe_mode_ib *mode)
+{
+ unsigned int size_vmode;
+ unsigned int size_remap;
+ unsigned int size_total;
+ struct uvesafb_par *par = info->par;
+ int i, h;
+
+ info->pseudo_palette = ((u8 *)info->par + sizeof(struct uvesafb_par));
+ info->fix = uvesafb_fix;
+ info->fix.ypanstep = par->ypan ? 1 : 0;
+ info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
+
+ /*
+ * If we were unable to get the state buffer size, disable
+ * functions for saving and restoring the hardware state.
+ */
+ if (par->vbe_state_size == 0) {
+ info->fbops->fb_save_state = NULL;
+ info->fbops->fb_restore_state = NULL;
+ }
+
+ /* Disable blanking if the user requested so. */
+ if (!blank)
+ info->fbops->fb_blank = NULL;
+
+ /*
+ * Find out how much IO memory is required for the mode with
+ * the highest resolution.
+ */
+ size_remap = 0;
+ for (i = 0; i < par->vbe_modes_cnt; i++) {
+ h = par->vbe_modes[i].bytes_per_scan_line *
+ par->vbe_modes[i].y_res;
+ if (h > size_remap)
+ size_remap = h;
+ }
+ size_remap *= 2;
+
+ /*
+ * size_vmode -- that is the amount of memory needed for the
+ * used video mode, i.e. the minimum amount of
+ * memory we need.
+ */
+ if (mode != NULL) {
+ size_vmode = info->var.yres * mode->bytes_per_scan_line;
+ } else {
+ size_vmode = info->var.yres * info->var.xres *
+ ((info->var.bits_per_pixel + 7) >> 3);
+ }
+
+ /*
+ * size_total -- all video memory we have. Used for mtrr
+ * entries, resource allocation and bounds
+ * checking.
+ */
+ size_total = par->vbe_ib.total_memory * 65536;
+ if (vram_total)
+ size_total = vram_total * 1024 * 1024;
+ if (size_total < size_vmode)
+ size_total = size_vmode;
+
+ /*
+ * size_remap -- the amount of video memory we are going to
+ * use for vesafb. With modern cards it is no
+ * option to simply use size_total as th
+ * wastes plenty of kernel address space.
+ */
+ if (vram_remap)
+ size_remap = vram_remap * 1024 * 1024;
+ if (size_remap < size_vmode)
+ size_remap = size_vmode;
+ if (size_remap > size_total)
+ size_remap = size_total;
+
+ info->fix.smem_len = size_remap;
+ info->fix.smem_start = mode->phys_base_ptr;
+
+ /*
+ * We have to set yres_virtual here because when setup_var() was
+ * called, smem_len wasn't defined yet.
+ */
+ info->var.yres_virtual = info->fix.smem_len /
+ mode->bytes_per_scan_line;
+
+ if (par->ypan && info->var.yres_virtual > info->var.yres) {
+ printk(KERN_INFO "uvesafb: scrolling: %s "
+ "using protected mode interface, "
+ "yres_virtual=%d\n",
+ (par->ypan > 1) ? "ywrap" : "ypan",
+ info->var.yres_virtual);
+ } else {
+ printk(KERN_INFO "uvesafb: scrolling: redraw\n");
+ info->var.yres_virtual = info->var.yres;
+ par->ypan = 0;
+ }
+
+ info->flags = FBINFO_FLAG_DEFAULT |
+ (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
+
+ if (!par->ypan)
+ info->fbops->fb_pan_display = NULL;
+}
+
+static void uvesafb_init_mtrr(struct fb_info *info)
+{
+#ifdef CONFIG_MTRR
+ if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
+ int temp_size = info->fix.smem_len;
+ unsigned int type = 0;
+
+ switch (mtrr) {
+ case 1:
+ type = MTRR_TYPE_UNCACHABLE;
+ break;
+ case 2:
+ type = MTRR_TYPE_WRBACK;
+ break;
+ case 3:
+ type = MTRR_TYPE_WRCOMB;
+ break;
+ case 4:
+ type = MTRR_TYPE_WRTHROUGH;
+ break;
+ default:
+ type = 0;
+ break;
+ }
+
+ if (type) {
+ int rc;
+
+ /* Find the largest power-of-two */
+ while (temp_size & (temp_size - 1))
+ temp_size &= (temp_size - 1);
+
+ /* Try and find a power of two to add */
+ do {
+ rc = mtrr_add(info->fix.smem_start,
+ temp_size, type, 1);
+ temp_size >>= 1;
+ } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
+ }
+ }
+#endif /* CONFIG_MTRR */
+}
+
+
+static ssize_t uvesafb_show_vbe_ver(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);
+}
+
+static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);
+
+static ssize_t uvesafb_show_vbe_modes(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+ int ret = 0, i;
+
+ for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "%dx%d-%d, 0x%.4x\n",
+ par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,
+ par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);
+ }
+
+ return ret;
+}
+
+static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);
+
+static ssize_t uvesafb_show_vendor(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ if (par->vbe_ib.oem_vendor_name_ptr)
+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
+ (&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr);
+ else
+ return 0;
+}
+
+static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);
+
+static ssize_t uvesafb_show_product_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ if (par->vbe_ib.oem_product_name_ptr)
+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
+ (&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr);
+ else
+ return 0;
+}
+
+static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);
+
+static ssize_t uvesafb_show_product_rev(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ if (par->vbe_ib.oem_product_rev_ptr)
+ return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
+ (&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr);
+ else
+ return 0;
+}
+
+static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);
+
+static ssize_t uvesafb_show_oem_string(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ if (par->vbe_ib.oem_string_ptr)
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ (char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr);
+ else
+ return 0;
+}
+
+static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);
+
+static ssize_t uvesafb_show_nocrtc(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);
+}
+
+static ssize_t uvesafb_store_nocrtc(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
+ struct uvesafb_par *par = info->par;
+
+ if (count > 0) {
+ if (buf[0] == '0')
+ par->nocrtc = 0;
+ else
+ par->nocrtc = 1;
+ }
+ return count;
+}
+
+static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,
+ uvesafb_store_nocrtc);
+
+static struct attribute *uvesafb_dev_attrs[] = {
+ &dev_attr_vbe_version.attr,
+ &dev_attr_vbe_modes.attr,
+ &dev_attr_oem_vendor.attr,
+ &dev_attr_oem_product_name.attr,
+ &dev_attr_oem_product_rev.attr,
+ &dev_attr_oem_string.attr,
+ &dev_attr_nocrtc.attr,
+ NULL,
+};
+
+static struct attribute_group uvesafb_dev_attgrp = {
+ .name = NULL,
+ .attrs = uvesafb_dev_attrs,
+};
+
+static int __devinit uvesafb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ struct vbe_mode_ib *mode = NULL;
+ struct uvesafb_par *par;
+ int err = 0, i;
+
+ info = framebuffer_alloc(sizeof(*par) + sizeof(u32) * 256, &dev->dev);
+ if (!info)
+ return -ENOMEM;
+
+ par = info->par;
+
+ err = uvesafb_vbe_init(info);
+ if (err) {
+ printk(KERN_ERR "uvesafb: vbe_init() failed with %d\n", err);
+ goto out;
+ }
+
+ info->fbops = &uvesafb_ops;
+
+ i = uvesafb_vbe_init_mode(info);
+ if (i < 0) {
+ err = -EINVAL;
+ goto out;
+ } else {
+ mode = &par->vbe_modes[i];
+ }
+
+ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+ err = -ENXIO;
+ goto out;
+ }
+
+ uvesafb_init_info(info, mode);
+
+ if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
+ "uvesafb")) {
+ printk(KERN_ERR "uvesafb: cannot reserve video memory at "
+ "0x%lx\n", info->fix.smem_start);
+ err = -EIO;
+ goto out_mode;
+ }
+
+ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+
+ if (!info->screen_base) {
+ printk(KERN_ERR
+ "uvesafb: abort, cannot ioremap 0x%x bytes of video "
+ "memory at 0x%lx\n",
+ info->fix.smem_len, info->fix.smem_start);
+ err = -EIO;
+ goto out_mem;
+ }
+
+ if (!request_region(0x3c0, 32, "uvesafb")) {
+ printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
+ err = -EIO;
+ goto out_unmap;
+ }
+
+ uvesafb_init_mtrr(info);
+ platform_set_drvdata(dev, info);
+
+ if (register_framebuffer(info) < 0) {
+ printk(KERN_ERR
+ "uvesafb: failed to register framebuffer device\n");
+ err = -EINVAL;
+ goto out_reg;
+ }
+
+ printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
+ "using %dk, total %dk\n", info->fix.smem_start,
+ info->screen_base, info->fix.smem_len/1024,
+ par->vbe_ib.total_memory * 64);
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+ info->fix.id);
+
+ err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
+ if (err != 0)
+ printk(KERN_WARNING "fb%d: failed to register attributes\n",
+ info->node);
+
+ return 0;
+
+out_reg:
+ release_region(0x3c0, 32);
+out_unmap:
+ iounmap(info->screen_base);
+out_mem:
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
+out_mode:
+ if (!list_empty(&info->modelist))
+ fb_destroy_modelist(&info->modelist);
+ fb_destroy_modedb(info->monspecs.modedb);
+ fb_dealloc_cmap(&info->cmap);
+out:
+ if (par->vbe_modes)
+ kfree(par->vbe_modes);
+
+ framebuffer_release(info);
+ return err;
+}
+
+static int uvesafb_remove(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ if (info) {
+ struct uvesafb_par *par = info->par;
+
+ sysfs_remove_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
+ unregister_framebuffer(info);
+ release_region(0x3c0, 32);
+ iounmap(info->screen_base);
+ release_mem_region(info->fix.smem_start, info->fix.smem_len);
+ fb_destroy_modedb(info->monspecs.modedb);
+ fb_dealloc_cmap(&info->cmap);
+
+ if (par) {
+ if (par->vbe_modes)
+ kfree(par->vbe_modes);
+ if (par->vbe_state_orig)
+ kfree(par->vbe_state_orig);
+ if (par->vbe_state_saved)
+ kfree(par->vbe_state_saved);
+ }
+
+ framebuffer_release(info);
+ }
+ return 0;
+}
+
+static struct platform_driver uvesafb_driver = {
+ .probe = uvesafb_probe,
+ .remove = uvesafb_remove,
+ .driver = {
+ .name = "uvesafb",
+ },
+};
+
+static struct platform_device *uvesafb_device;
+
+#ifndef MODULE
+static int __devinit uvesafb_setup(char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt) continue;
+
+ if (!strcmp(this_opt, "redraw"))
+ ypan = 0;
+ else if (!strcmp(this_opt, "ypan"))
+ ypan = 1;
+ else if (!strcmp(this_opt, "ywrap"))
+ ypan = 2;
+ else if (!strcmp(this_opt, "vgapal"))
+ pmi_setpal = 0;
+ else if (!strcmp(this_opt, "pmipal"))
+ pmi_setpal = 1;
+ else if (!strncmp(this_opt, "mtrr:", 5))
+ mtrr = simple_strtoul(this_opt+5, NULL, 0);
+ else if (!strcmp(this_opt, "nomtrr"))
+ mtrr = 0;
+ else if (!strcmp(this_opt, "nocrtc"))
+ nocrtc = 1;
+ else if (!strcmp(this_opt, "noedid"))
+ noedid = 1;
+ else if (!strcmp(this_opt, "noblank"))
+ blank = 0;
+ else if (!strncmp(this_opt, "vtotal:", 7))
+ vram_total = simple_strtoul(this_opt + 7, NULL, 0);
+ else if (!strncmp(this_opt, "vremap:", 7))
+ vram_remap = simple_strtoul(this_opt + 7, NULL, 0);
+ else if (!strncmp(this_opt, "maxhf:", 6))
+ maxhf = simple_strtoul(this_opt + 6, NULL, 0);
+ else if (!strncmp(this_opt, "maxvf:", 6))
+ maxvf = simple_strtoul(this_opt + 6, NULL, 0);
+ else if (!strncmp(this_opt, "maxclk:", 7))
+ maxclk = simple_strtoul(this_opt + 7, NULL, 0);
+ else if (!strncmp(this_opt, "vbemode:", 8))
+ vbemode = simple_strtoul(this_opt + 8, NULL, 0);
+ else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
+ mode_option = this_opt;
+ } else {
+ printk(KERN_WARNING
+ "uvesafb: unrecognized option %s\n", this_opt);
+ }
+ }
+
+ return 0;
+}
+#endif /* !MODULE */
+
+static ssize_t show_v86d(struct device_driver *dev, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
+}
+
+static ssize_t store_v86d(struct device_driver *dev, const char *buf,
+ size_t count)
+{
+ strncpy(v86d_path, buf, PATH_MAX);
+ return count;
+}
+
+static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
+
+static int __devinit uvesafb_init(void)
+{
+ int err;
+
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("uvesafb", &option))
+ return -ENODEV;
+ uvesafb_setup(option);
+#endif
+ err = cn_add_callback(&uvesafb_cn_id, "uvesafb", uvesafb_cn_callback);
+ if (err)
+ return err;
+
+ err = platform_driver_register(&uvesafb_driver);
+
+ if (!err) {
+ uvesafb_device = platform_device_alloc("uvesafb", 0);
+ if (uvesafb_device)
+ err = platform_device_add(uvesafb_device);
+ else
+ err = -ENOMEM;
+
+ if (err) {
+ platform_device_put(uvesafb_device);
+ platform_driver_unregister(&uvesafb_driver);
+ cn_del_callback(&uvesafb_cn_id);
+ return err;
+ }
+
+ err = driver_create_file(&uvesafb_driver.driver,
+ &driver_attr_v86d);
+ if (err) {
+ printk(KERN_WARNING "uvesafb: failed to register "
+ "attributes\n");
+ err = 0;
+ }
+ }
+ return err;
+}
+
+module_init(uvesafb_init);
+
+static void __devexit uvesafb_exit(void)
+{
+ struct uvesafb_ktask *task;
+
+ if (v86d_started) {
+ task = uvesafb_prep();
+ if (task) {
+ task->t.flags = TF_EXIT;
+ uvesafb_exec(task);
+ uvesafb_free(task);
+ }
+ }
+
+ cn_del_callback(&uvesafb_cn_id);
+ driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
+ platform_device_unregister(uvesafb_device);
+ platform_driver_unregister(&uvesafb_driver);
+}
+
+module_exit(uvesafb_exit);
+
+static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
+{
+ return 0;
+}
+
+static inline int param_set_scroll(const char *val, struct kernel_param *kp)
+{
+ ypan = 0;
+
+ if (!strcmp(val, "redraw"))
+ ypan = 0;
+ else if (!strcmp(val, "ypan"))
+ ypan = 1;
+ else if (!strcmp(val, "ywrap"))
+ ypan = 2;
+
+ return 0;
+}
+
+#define param_check_scroll(name, p) __param_check(name, p, void);
+
+module_param_named(scroll, ypan, scroll, 0);
+MODULE_PARM_DESC(scroll,
+ "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'");
+module_param_named(vgapal, pmi_setpal, invbool, 0);
+MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
+module_param_named(pmipal, pmi_setpal, bool, 0);
+MODULE_PARM_DESC(pmipal, "Set palette using PMI calls");
+module_param(mtrr, uint, 0);
+MODULE_PARM_DESC(mtrr,
+ "Memory Type Range Registers setting. Use 0 to disable.");
+module_param(blank, bool, 0);
+MODULE_PARM_DESC(blank, "Enable hardware blanking");
+module_param(nocrtc, bool, 0);
+MODULE_PARM_DESC(nocrtc, "Ignore CRTC timings when setting modes");
+module_param(noedid, bool, 0);
+MODULE_PARM_DESC(noedid,
+ "Ignore EDID-provided monitor limits when setting modes");
+module_param(vram_remap, uint, 0);
+MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");
+module_param(vram_total, uint, 0);
+MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]");
+module_param(maxclk, ushort, 0);
+MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");
+module_param(maxhf, ushort, 0);
+MODULE_PARM_DESC(maxhf,
+ "Maximum horizontal frequency [kHz], overrides EDID data");
+module_param(maxvf, ushort, 0);
+MODULE_PARM_DESC(maxvf,
+ "Maximum vertical frequency [Hz], overrides EDID data");
+module_param_named(mode, mode_option, charp, 0);
+MODULE_PARM_DESC(mode,
+ "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
+module_param(vbemode, ushort, 0);
+MODULE_PARM_DESC(vbemode,
+ "VBE mode number to set, overrides the 'mode' option");
+module_param_string(v86d, v86d_path, PATH_MAX, 0660);
+MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");
+MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");
+
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index de531c90771..ff9e805c43b 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -39,7 +39,6 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <linux/mmzone.h>
-#include <asm/uaccess.h>
/* #define VERMILION_DEBUG */
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 64ee78c3c12..072638a9528 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -21,7 +21,6 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
@@ -38,6 +37,48 @@ static void *videomemory;
static u_long videomemorysize = VIDEOMEMSIZE;
module_param(videomemorysize, ulong, 0);
+/**********************************************************************
+ *
+ * Memory management
+ *
+ **********************************************************************/
+static void *rvmalloc(unsigned long size)
+{
+ void *mem;
+ unsigned long adr;
+
+ size = PAGE_ALIGN(size);
+ mem = vmalloc_32(size);
+ if (!mem)
+ return NULL;
+
+ memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+ adr = (unsigned long) mem;
+ while (size > 0) {
+ SetPageReserved(vmalloc_to_page((void *)adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ return mem;
+}
+
+static void rvfree(void *mem, unsigned long size)
+{
+ unsigned long adr;
+
+ if (!mem)
+ return;
+
+ adr = (unsigned long) mem;
+ while ((long) size > 0) {
+ ClearPageReserved(vmalloc_to_page((void *)adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ vfree(mem);
+}
+
static struct fb_var_screeninfo vfb_default __initdata = {
.xres = 640,
.yres = 480,
@@ -372,7 +413,33 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
static int vfb_mmap(struct fb_info *info,
struct vm_area_struct *vma)
{
- return -EINVAL;
+ unsigned long start = vma->vm_start;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ unsigned long page, pos;
+
+ if (offset + size > info->fix.smem_len) {
+ return -EINVAL;
+ }
+
+ pos = (unsigned long)info->fix.smem_start + offset;
+
+ while (size > 0) {
+ page = vmalloc_to_pfn((void *)pos);
+ if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
+ return -EAGAIN;
+ }
+ start += PAGE_SIZE;
+ pos += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+
+ vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
+ return 0;
+
}
#ifndef MODULE
@@ -407,7 +474,7 @@ static int __init vfb_probe(struct platform_device *dev)
/*
* For real video cards we use ioremap.
*/
- if (!(videomemory = vmalloc(videomemorysize)))
+ if (!(videomemory = rvmalloc(videomemorysize)))
return retval;
/*
@@ -430,6 +497,8 @@ static int __init vfb_probe(struct platform_device *dev)
if (!retval || (retval == 4))
info->var = vfb_default;
+ vfb_fix.smem_start = (unsigned long) videomemory;
+ vfb_fix.smem_len = videomemorysize;
info->fix = vfb_fix;
info->pseudo_palette = info->par;
info->par = NULL;
@@ -453,7 +522,7 @@ err2:
err1:
framebuffer_release(info);
err:
- vfree(videomemory);
+ rvfree(videomemory, videomemorysize);
return retval;
}
@@ -463,7 +532,7 @@ static int vfb_remove(struct platform_device *dev)
if (info) {
unregister_framebuffer(info);
- vfree(videomemory);
+ rvfree(videomemory, videomemorysize);
framebuffer_release(info);
}
return 0;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 2a14d28c416..9b3c5923365 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1364,7 +1364,7 @@ static int __init vga16fb_probe(struct platform_device *dev)
par = info->par;
mutex_init(&par->open_lock);
- par->isVGA = ORIG_VIDEO_ISVGA;
+ par->isVGA = screen_info.orig_video_isVGA;
par->palette_blanked = 0;
par->vesa_blanked = 0;
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 4b696641ce3..5747997f8d7 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -307,7 +307,7 @@ static void ds1wm_search(void *data, u8 search_type,
rom_id |= (unsigned long long) r << (i * 4);
}
- dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id);
+ dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX\n", rom_id);
ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
ds1wm_reset(ds1wm_data);
diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c
index d356da5709f..1550431ccb6 100644
--- a/drivers/w1/masters/matrox_w1.c
+++ b/drivers/w1/masters/matrox_w1.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/pci_ids.h>
#include <linux/pci.h>
-#include <linux/timer.h>
#include "../w1.h"
#include "../w1_int.h"
diff --git a/drivers/char/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 37bddc1802d..37bddc1802d 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
diff --git a/drivers/char/watchdog/Makefile b/drivers/watchdog/Makefile
index 389f8b14ccc..389f8b14ccc 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 85269c365a1..85269c365a1 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 8121cc24734..8121cc24734 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index c404fc69e7e..c404fc69e7e 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 67aed9f8c36..67aed9f8c36 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
diff --git a/drivers/char/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index 54a516169d0..54a516169d0 100644
--- a/drivers/char/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
diff --git a/drivers/char/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 38bd3737259..38bd3737259 100644
--- a/drivers/char/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
diff --git a/drivers/char/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 309d27913fc..309d27913fc 100644
--- a/drivers/char/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index d362f5bf658..d362f5bf658 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 5941ca601a3..5941ca601a3 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
diff --git a/drivers/char/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 19db5302ba6..19db5302ba6 100644
--- a/drivers/char/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 0e4787a0bb8..0e4787a0bb8 100644
--- a/drivers/char/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index b14e9d1f164..b14e9d1f164 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index c5982502c03..c5982502c03 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
diff --git a/drivers/char/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index 41508399009..41508399009 100644
--- a/drivers/char/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index cd5a565bc3a..cd5a565bc3a 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index c3a60f52ccb..c3a60f52ccb 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c
index 94155f6136c..94155f6136c 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/watchdog/ibmasr.c
diff --git a/drivers/char/watchdog/indydog.c b/drivers/watchdog/indydog.c
index 788245bdaa7..788245bdaa7 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
diff --git a/drivers/char/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
index bbbd91af754..bbbd91af754 100644
--- a/drivers/char/watchdog/iop_wdt.c
+++ b/drivers/watchdog/iop_wdt.c
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index dc7548dcaf3..dc7548dcaf3 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 5864bb865cf..5864bb865cf 100644
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
diff --git a/drivers/char/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index 7150fb945ea..7150fb945ea 100644
--- a/drivers/char/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 6d35bb112a5..6d35bb112a5 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 1adf1d56027..1adf1d56027 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
diff --git a/drivers/char/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
index 9cfb9757662..9cfb9757662 100644
--- a/drivers/char/watchdog/mpc5200_wdt.c
+++ b/drivers/watchdog/mpc5200_wdt.c
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/watchdog/mpc83xx_wdt.c
index a0bf95fb976..a0bf95fb976 100644
--- a/drivers/char/watchdog/mpc83xx_wdt.c
+++ b/drivers/watchdog/mpc83xx_wdt.c
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/watchdog/mpc8xx_wdt.c
index 85b5734403a..85b5734403a 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/watchdog/mpc8xx_wdt.c
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index 0d2b2773541..0d2b2773541 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
diff --git a/drivers/char/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index dcfd401a7ad..dcfd401a7ad 100644
--- a/drivers/char/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index 0365c317f7e..0365c317f7e 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 719b066f73c..719b066f73c 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
diff --git a/drivers/char/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
index 52a532a5114..52a532a5114 100644
--- a/drivers/char/watchdog/omap_wdt.h
+++ b/drivers/watchdog/omap_wdt.h
diff --git a/drivers/char/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 3d3deae0d64..3d3deae0d64 100644
--- a/drivers/char/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index 7b41434fac8..7b41434fac8 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 61a89e95964..61a89e95964 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 0f3fd6c9c35..0f3fd6c9c35 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 22f8873dd09..22f8873dd09 100644
--- a/drivers/char/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
diff --git a/drivers/char/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index 5c921e47156..5c921e47156 100644
--- a/drivers/char/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 5d1c15f83d2..5d1c15f83d2 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index 3475f47aaa4..3475f47aaa4 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c
index e4f3cb6090b..e4f3cb6090b 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/watchdog/sbc60xxwdt.c
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c
index 285d8528953..285d8528953 100644
--- a/drivers/char/watchdog/sbc8360.c
+++ b/drivers/watchdog/sbc8360.c
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c
index 82cbd8809a6..82cbd8809a6 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/watchdog/sbc_epx_c3.c
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index 9670d47190d..9670d47190d 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/watchdog/sc520_wdt.c
index e8594c64d1e..e8594c64d1e 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/watchdog/sc520_wdt.c
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/watchdog/scx200_wdt.c
index d4fd0fa2f17..d4fd0fa2f17 100644
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/watchdog/scx200_wdt.c
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index cecbedd473a..cecbedd473a 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c
index d3cb0a76602..d3cb0a76602 100644
--- a/drivers/char/watchdog/smsc37b787_wdt.c
+++ b/drivers/watchdog/smsc37b787_wdt.c
diff --git a/drivers/char/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 9c369490924..9c369490924 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index df33b3b5a53..df33b3b5a53 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index d9e821d08de..d9e821d08de 100644
--- a/drivers/char/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c
index 3c88fe18f4f..3c88fe18f4f 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/watchdog/w83877f_wdt.c
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index 15796844289..15796844289 100644
--- a/drivers/char/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c
index 950905d3c39..950905d3c39 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/watchdog/wafer5823wdt.c
diff --git a/drivers/char/watchdog/wd501p.h b/drivers/watchdog/wd501p.h
index a4504f40394..a4504f40394 100644
--- a/drivers/char/watchdog/wd501p.h
+++ b/drivers/watchdog/wd501p.h
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 1d64e277567..1d64e277567 100644
--- a/drivers/char/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
diff --git a/drivers/char/watchdog/wdt.c b/drivers/watchdog/wdt.c
index 0a3de6a0244..0a3de6a0244 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/watchdog/wdt285.c
index e4cf661dc89..e4cf661dc89 100644
--- a/drivers/char/watchdog/wdt285.c
+++ b/drivers/watchdog/wdt285.c
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/watchdog/wdt977.c
index 7d300ff7ab0..7d300ff7ab0 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/watchdog/wdt977.c
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 6baf4ae42c9..6baf4ae42c9 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 0b769f7c4a4..4750de316ad 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -185,13 +185,14 @@ static void otherend_changed(struct xenbus_watch *watch,
if (!dev->otherend ||
strncmp(dev->otherend, vec[XS_WATCH_PATH],
strlen(dev->otherend))) {
- dev_dbg(&dev->dev, "Ignoring watch at %s", vec[XS_WATCH_PATH]);
+ dev_dbg(&dev->dev, "Ignoring watch at %s\n",
+ vec[XS_WATCH_PATH]);
return;
}
state = xenbus_read_driver_state(dev->otherend);
- dev_dbg(&dev->dev, "state is %d, (%s), %s, %s",
+ dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n",
state, xenbus_strstate(state), dev->otherend_watch.node,
vec[XS_WATCH_PATH]);
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 15e05a15b57..b364da70ff2 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -1,6 +1,7 @@
/*
* V9FS FID Management
*
+ * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -34,9 +35,9 @@
#include "fid.h"
/**
- * v9fs_fid_insert - add a fid to a dentry
+ * v9fs_fid_add - add a fid to a dentry
+ * @dentry: dentry that the fid is being added to
* @fid: fid to add
- * @dentry: dentry that it is being added to
*
*/
@@ -66,52 +67,144 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
}
/**
- * v9fs_fid_lookup - return a locked fid from a dentry
+ * v9fs_fid_find - retrieve a fid that belongs to the specified uid
* @dentry: dentry to look for fid in
- *
- * find a fid in the dentry, obtain its semaphore and return a reference to it.
- * code calling lookup is responsible for releasing lock
- *
- * TODO: only match fids that have the same uid as current user
+ * @uid: return fid that belongs to the specified user
+ * @any: if non-zero, return any fid associated with the dentry
*
*/
-struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
+static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any)
{
struct v9fs_dentry *dent;
- struct p9_fid *fid;
-
- P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
- dent = dentry->d_fsdata;
- if (dent)
- fid = list_entry(dent->fidlist.next, struct p9_fid, dlist);
- else
- fid = ERR_PTR(-EBADF);
+ struct p9_fid *fid, *ret;
+
+ P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
+ dentry->d_iname, dentry, uid, any);
+ dent = (struct v9fs_dentry *) dentry->d_fsdata;
+ ret = NULL;
+ if (dent) {
+ spin_lock(&dent->lock);
+ list_for_each_entry(fid, &dent->fidlist, dlist) {
+ if (any || fid->uid == uid) {
+ ret = fid;
+ break;
+ }
+ }
+ spin_unlock(&dent->lock);
+ }
- P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid);
- return fid;
+ return ret;
}
/**
- * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
- * release it
+ * v9fs_fid_lookup - lookup for a fid, try to walk if not found
* @dentry: dentry to look for fid in
*
- * find a fid in the dentry and then clone to a new private fid
- *
- * TODO: only match fids that have the same uid as current user
- *
+ * Look for a fid in the specified dentry for the current user.
+ * If no fid is found, try to create one walking from a fid from the parent
+ * dentry (if it has one), or the root dentry. If the user haven't accessed
+ * the fs yet, attach now and walk from the root.
*/
-struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
+struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
{
- struct p9_fid *ofid, *fid;
+ int i, n, l, clone, any, access;
+ u32 uid;
+ struct p9_fid *fid;
+ struct dentry *d, *ds;
+ struct v9fs_session_info *v9ses;
+ char **wnames, *uname;
+
+ v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ access = v9ses->flags & V9FS_ACCESS_MASK;
+ switch (access) {
+ case V9FS_ACCESS_SINGLE:
+ case V9FS_ACCESS_USER:
+ uid = current->fsuid;
+ any = 0;
+ break;
+
+ case V9FS_ACCESS_ANY:
+ uid = v9ses->uid;
+ any = 1;
+ break;
+
+ default:
+ uid = ~0;
+ any = 0;
+ break;
+ }
- P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
- ofid = v9fs_fid_lookup(dentry);
- if (IS_ERR(ofid))
- return ofid;
+ fid = v9fs_fid_find(dentry, uid, any);
+ if (fid)
+ return fid;
+
+ ds = dentry->d_parent;
+ fid = v9fs_fid_find(ds, uid, any);
+ if (!fid) { /* walk from the root */
+ n = 0;
+ for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent)
+ n++;
+
+ fid = v9fs_fid_find(ds, uid, any);
+ if (!fid) { /* the user is not attached to the fs yet */
+ if (access == V9FS_ACCESS_SINGLE)
+ return ERR_PTR(-EPERM);
+
+ if (v9fs_extended(v9ses))
+ uname = NULL;
+ else
+ uname = v9ses->uname;
+
+ fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
+ v9ses->aname);
+
+ if (IS_ERR(fid))
+ return fid;
+
+ v9fs_fid_add(ds, fid);
+ }
+ } else /* walk from the parent */
+ n = 1;
+
+ if (ds == dentry)
+ return fid;
+
+ wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL);
+ if (!wnames)
+ return ERR_PTR(-ENOMEM);
+
+ for (d = dentry, i = n; i >= 0; i--, d = d->d_parent)
+ wnames[i] = (char *) d->d_name.name;
+
+ clone = 1;
+ i = 0;
+ while (i < n) {
+ l = min(n - i, P9_MAXWELEM);
+ fid = p9_client_walk(fid, l, &wnames[i], clone);
+ if (!fid) {
+ kfree(wnames);
+ return fid;
+ }
+
+ i += l;
+ clone = 0;
+ }
- fid = p9_client_walk(ofid, 0, NULL, 1);
+ kfree(wnames);
+ v9fs_fid_add(dentry, fid);
return fid;
}
+
+struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
+{
+ struct p9_fid *fid, *ret;
+
+ fid = v9fs_fid_lookup(dentry);
+ if (IS_ERR(fid))
+ return fid;
+
+ ret = p9_client_walk(fid, 0, NULL, 1);
+ return ret;
+}
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 0a7068e30ec..873802de21c 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -38,56 +38,41 @@
/*
* Option Parsing (code inspired by NFS code)
- *
+ * NOTE: each transport will parse its own options
*/
enum {
/* Options that take integer arguments */
- Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid,
- Opt_rfdno, Opt_wfdno,
+ Opt_debug, Opt_msize, Opt_dfltuid, Opt_dfltgid, Opt_afid,
/* String options */
- Opt_uname, Opt_remotename,
+ Opt_uname, Opt_remotename, Opt_trans,
/* Options that take no arguments */
- Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci,
+ Opt_legacy, Opt_nodevmap,
/* Cache options */
Opt_cache_loose,
+ /* Access options */
+ Opt_access,
/* Error token */
Opt_err
};
static match_table_t tokens = {
{Opt_debug, "debug=%x"},
- {Opt_port, "port=%u"},
{Opt_msize, "msize=%u"},
- {Opt_uid, "uid=%u"},
- {Opt_gid, "gid=%u"},
+ {Opt_dfltuid, "dfltuid=%u"},
+ {Opt_dfltgid, "dfltgid=%u"},
{Opt_afid, "afid=%u"},
- {Opt_rfdno, "rfdno=%u"},
- {Opt_wfdno, "wfdno=%u"},
{Opt_uname, "uname=%s"},
{Opt_remotename, "aname=%s"},
- {Opt_unix, "proto=unix"},
- {Opt_tcp, "proto=tcp"},
- {Opt_fd, "proto=fd"},
-#ifdef CONFIG_PCI_9P
- {Opt_pci, "proto=pci"},
-#endif
- {Opt_tcp, "tcp"},
- {Opt_unix, "unix"},
- {Opt_fd, "fd"},
+ {Opt_trans, "trans=%s"},
{Opt_legacy, "noextend"},
{Opt_nodevmap, "nodevmap"},
{Opt_cache_loose, "cache=loose"},
{Opt_cache_loose, "loose"},
+ {Opt_access, "access=%s"},
{Opt_err, NULL}
};
-extern struct p9_transport *p9pci_trans_create(void);
-
-/*
- * Parse option string.
- */
-
/**
* v9fs_parse_options - parse mount options into session structure
* @options: options string passed from mount
@@ -95,23 +80,21 @@ extern struct p9_transport *p9pci_trans_create(void);
*
*/
-static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
+static void v9fs_parse_options(struct v9fs_session_info *v9ses)
{
- char *p;
+ char *options = v9ses->options;
substring_t args[MAX_OPT_ARGS];
+ char *p;
int option;
int ret;
+ char *s, *e;
/* setup defaults */
- v9ses->port = V9FS_PORT;
- v9ses->maxdata = 9000;
- v9ses->proto = PROTO_TCP;
- v9ses->extended = 1;
+ v9ses->maxdata = 8192;
v9ses->afid = ~0;
v9ses->debug = 0;
- v9ses->rfdno = ~0;
- v9ses->wfdno = ~0;
v9ses->cache = 0;
+ v9ses->trans = v9fs_default_trans();
if (!options)
return;
@@ -135,47 +118,29 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
p9_debug_level = option;
#endif
break;
- case Opt_port:
- v9ses->port = option;
- break;
case Opt_msize:
v9ses->maxdata = option;
break;
- case Opt_uid:
- v9ses->uid = option;
+ case Opt_dfltuid:
+ v9ses->dfltuid = option;
break;
- case Opt_gid:
- v9ses->gid = option;
+ case Opt_dfltgid:
+ v9ses->dfltgid = option;
break;
case Opt_afid:
v9ses->afid = option;
break;
- case Opt_rfdno:
- v9ses->rfdno = option;
- break;
- case Opt_wfdno:
- v9ses->wfdno = option;
- break;
- case Opt_tcp:
- v9ses->proto = PROTO_TCP;
- break;
- case Opt_unix:
- v9ses->proto = PROTO_UNIX;
- break;
- case Opt_pci:
- v9ses->proto = PROTO_PCI;
- break;
- case Opt_fd:
- v9ses->proto = PROTO_FD;
+ case Opt_trans:
+ v9ses->trans = v9fs_match_trans(&args[0]);
break;
case Opt_uname:
- match_strcpy(v9ses->name, &args[0]);
+ match_strcpy(v9ses->uname, &args[0]);
break;
case Opt_remotename:
- match_strcpy(v9ses->remotename, &args[0]);
+ match_strcpy(v9ses->aname, &args[0]);
break;
case Opt_legacy:
- v9ses->extended = 0;
+ v9ses->flags &= ~V9FS_EXTENDED;
break;
case Opt_nodevmap:
v9ses->nodev = 1;
@@ -183,6 +148,22 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
case Opt_cache_loose:
v9ses->cache = CACHE_LOOSE;
break;
+
+ case Opt_access:
+ s = match_strdup(&args[0]);
+ v9ses->flags &= ~V9FS_ACCESS_MASK;
+ if (strcmp(s, "user") == 0)
+ v9ses->flags |= V9FS_ACCESS_USER;
+ else if (strcmp(s, "any") == 0)
+ v9ses->flags |= V9FS_ACCESS_ANY;
+ else {
+ v9ses->flags |= V9FS_ACCESS_SINGLE;
+ v9ses->uid = simple_strtol(s, &e, 10);
+ if (*e != '\0')
+ v9ses->uid = ~0;
+ }
+ break;
+
default:
continue;
}
@@ -201,56 +182,46 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
const char *dev_name, char *data)
{
int retval = -EINVAL;
- struct p9_transport *trans;
+ struct p9_trans *trans = NULL;
struct p9_fid *fid;
- v9ses->name = __getname();
- if (!v9ses->name)
+ v9ses->uname = __getname();
+ if (!v9ses->uname)
return ERR_PTR(-ENOMEM);
- v9ses->remotename = __getname();
- if (!v9ses->remotename) {
- __putname(v9ses->name);
+ v9ses->aname = __getname();
+ if (!v9ses->aname) {
+ __putname(v9ses->uname);
return ERR_PTR(-ENOMEM);
}
- strcpy(v9ses->name, V9FS_DEFUSER);
- strcpy(v9ses->remotename, V9FS_DEFANAME);
-
- v9fs_parse_options(data, v9ses);
-
- switch (v9ses->proto) {
- case PROTO_TCP:
- trans = p9_trans_create_tcp(dev_name, v9ses->port);
- break;
- case PROTO_UNIX:
- trans = p9_trans_create_unix(dev_name);
- *v9ses->remotename = 0;
- break;
- case PROTO_FD:
- trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno);
- *v9ses->remotename = 0;
- break;
-#ifdef CONFIG_PCI_9P
- case PROTO_PCI:
- trans = p9pci_trans_create();
- *v9ses->remotename = 0;
- break;
-#endif
- default:
- printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto);
- retval = -ENOPROTOOPT;
+ v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER;
+ strcpy(v9ses->uname, V9FS_DEFUSER);
+ strcpy(v9ses->aname, V9FS_DEFANAME);
+ v9ses->uid = ~0;
+ v9ses->dfltuid = V9FS_DEFUID;
+ v9ses->dfltgid = V9FS_DEFGID;
+ v9ses->options = kstrdup(data, GFP_KERNEL);
+ v9fs_parse_options(v9ses);
+
+ if (v9ses->trans == NULL) {
+ retval = -EPROTONOSUPPORT;
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "No transport defined or default transport\n");
goto error;
- };
+ }
+ trans = v9ses->trans->create(dev_name, v9ses->options);
if (IS_ERR(trans)) {
retval = PTR_ERR(trans);
trans = NULL;
goto error;
}
+ if ((v9ses->maxdata+P9_IOHDRSZ) > v9ses->trans->maxsize)
+ v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ;
- v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ,
- v9ses->extended);
+ v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ,
+ v9fs_extended(v9ses));
if (IS_ERR(v9ses->clnt)) {
retval = PTR_ERR(v9ses->clnt);
@@ -259,8 +230,20 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
goto error;
}
- fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name,
- v9ses->remotename);
+ if (!v9ses->clnt->dotu)
+ v9ses->flags &= ~V9FS_EXTENDED;
+
+ /* for legacy mode, fall back to V9FS_ACCESS_ANY */
+ if (!v9fs_extended(v9ses) &&
+ ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
+
+ v9ses->flags &= ~V9FS_ACCESS_MASK;
+ v9ses->flags |= V9FS_ACCESS_ANY;
+ v9ses->uid = ~0;
+ }
+
+ fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0,
+ v9ses->aname);
if (IS_ERR(fid)) {
retval = PTR_ERR(fid);
fid = NULL;
@@ -268,6 +251,11 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
goto error;
}
+ if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
+ fid->uid = v9ses->uid;
+ else
+ fid->uid = ~0;
+
return fid;
error:
@@ -288,8 +276,9 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
v9ses->clnt = NULL;
}
- __putname(v9ses->name);
- __putname(v9ses->remotename);
+ __putname(v9ses->uname);
+ __putname(v9ses->aname);
+ kfree(v9ses->options);
}
/**
@@ -311,7 +300,7 @@ extern int v9fs_error_init(void);
static int __init init_v9fs(void)
{
printk(KERN_INFO "Installing v9fs 9p2000 file system support\n");
-
+ /* TODO: Setup list of registered trasnport modules */
return register_filesystem(&v9fs_fs_type);
}
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index abc4b1668ac..db4b4193f2e 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -29,31 +29,30 @@
struct v9fs_session_info {
/* options */
unsigned int maxdata;
- unsigned char extended; /* set to 1 if we are using UNIX extensions */
+ unsigned char flags; /* session flags */
unsigned char nodev; /* set to 1 if no disable device mapping */
- unsigned short port; /* port to connect to */
unsigned short debug; /* debug level */
- unsigned short proto; /* protocol to use */
unsigned int afid; /* authentication fid */
- unsigned int rfdno; /* read file descriptor number */
- unsigned int wfdno; /* write file descriptor number */
unsigned int cache; /* cache mode */
- char *name; /* user name to mount as */
- char *remotename; /* name of remote hierarchy being mounted */
- unsigned int uid; /* default uid/muid for legacy support */
- unsigned int gid; /* default gid for legacy support */
-
+ char *options; /* copy of mount options */
+ char *uname; /* user name to mount as */
+ char *aname; /* name of remote hierarchy being mounted */
+ unsigned int dfltuid; /* default uid/muid for legacy support */
+ unsigned int dfltgid; /* default gid for legacy support */
+ u32 uid; /* if ACCESS_SINGLE, the uid that has access */
+ struct p9_trans_module *trans; /* 9p transport */
struct p9_client *clnt; /* 9p client */
struct dentry *debugfs_dir;
};
-/* possible values of ->proto */
+/* session flags */
enum {
- PROTO_TCP,
- PROTO_UNIX,
- PROTO_FD,
- PROTO_PCI,
+ V9FS_EXTENDED = 0x01, /* 9P2000.u */
+ V9FS_ACCESS_MASK = 0x06, /* access mask */
+ V9FS_ACCESS_SINGLE = 0x02, /* only one user can access the files */
+ V9FS_ACCESS_USER = 0x04, /* attache per user */
+ V9FS_ACCESS_ANY = 0x06, /* use the same attach for all users */
};
/* possible values of ->cache */
@@ -73,11 +72,18 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses);
#define V9FS_MAGIC 0x01021997
/* other default globals */
-#define V9FS_PORT 564
+#define V9FS_PORT 564
#define V9FS_DEFUSER "nobody"
#define V9FS_DEFANAME ""
+#define V9FS_DEFUID (-2)
+#define V9FS_DEFGID (-2)
static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
{
return (inode->i_sb->s_fs_info);
}
+
+static inline int v9fs_extended(struct v9fs_session_info *v9ses)
+{
+ return v9ses->flags & V9FS_EXTENDED;
+}
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 2a40c2946d0..ba4b1caa9c4 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -105,7 +105,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
/* No mandatory locks */
- if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ if (__mandatory_lock(inode))
return -ENOLCK;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
@@ -162,15 +162,17 @@ v9fs_file_write(struct file *filp, const char __user * data,
fid = filp->private_data;
ret = p9_client_uwrite(fid, data, *offset, count);
- if (ret > 0)
+ if (ret > 0) {
+ invalidate_inode_pages2_range(inode->i_mapping, *offset,
+ *offset+ret);
*offset += ret;
+ }
if (*offset > inode->i_size) {
inode->i_size = *offset;
inode->i_blocks = (inode->i_size + 512 - 1) >> 9;
}
- invalidate_inode_pages2(inode->i_mapping);
return ret;
}
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index e5c45eed58a..175b4d9bf3f 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -59,7 +59,7 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
res = mode & 0777;
if (S_ISDIR(mode))
res |= P9_DMDIR;
- if (v9ses->extended) {
+ if (v9fs_extended(v9ses)) {
if (S_ISLNK(mode))
res |= P9_DMSYMLINK;
if (v9ses->nodev == 0) {
@@ -99,21 +99,21 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
if ((mode & P9_DMDIR) == P9_DMDIR)
res |= S_IFDIR;
- else if ((mode & P9_DMSYMLINK) && (v9ses->extended))
+ else if ((mode & P9_DMSYMLINK) && (v9fs_extended(v9ses)))
res |= S_IFLNK;
- else if ((mode & P9_DMSOCKET) && (v9ses->extended)
+ else if ((mode & P9_DMSOCKET) && (v9fs_extended(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFSOCK;
- else if ((mode & P9_DMNAMEDPIPE) && (v9ses->extended)
+ else if ((mode & P9_DMNAMEDPIPE) && (v9fs_extended(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFIFO;
- else if ((mode & P9_DMDEVICE) && (v9ses->extended)
+ else if ((mode & P9_DMDEVICE) && (v9fs_extended(v9ses))
&& (v9ses->nodev == 0))
res |= S_IFBLK;
else
res |= S_IFREG;
- if (v9ses->extended) {
+ if (v9fs_extended(v9ses)) {
if ((mode & P9_DMSETUID) == P9_DMSETUID)
res |= S_ISUID;
@@ -214,7 +214,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
case S_IFBLK:
case S_IFCHR:
case S_IFSOCK:
- if(!v9ses->extended) {
+ if (!v9fs_extended(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"special files without extended mode\n");
return ERR_PTR(-EINVAL);
@@ -227,7 +227,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
inode->i_fop = &v9fs_file_operations;
break;
case S_IFLNK:
- if(!v9ses->extended) {
+ if (!v9fs_extended(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR,
"extended modes used w/o 9P2000.u\n");
return ERR_PTR(-EINVAL);
@@ -236,7 +236,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
break;
case S_IFDIR:
inc_nlink(inode);
- if(v9ses->extended)
+ if (v9fs_extended(v9ses))
inode->i_op = &v9fs_dir_inode_operations_ext;
else
inode->i_op = &v9fs_dir_inode_operations;
@@ -364,7 +364,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
file_inode = file->d_inode;
v9ses = v9fs_inode2v9ses(file_inode);
v9fid = v9fs_fid_clone(file);
- if(IS_ERR(v9fid))
+ if (IS_ERR(v9fid))
return PTR_ERR(v9fid);
return p9_client_remove(v9fid);
@@ -398,7 +398,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
fid = NULL;
name = (char *) dentry->d_name.name;
dfid = v9fs_fid_clone(dentry->d_parent);
- if(IS_ERR(dfid)) {
+ if (IS_ERR(dfid)) {
err = PTR_ERR(dfid);
dfid = NULL;
goto error;
@@ -432,7 +432,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
goto error;
}
- if(v9ses->cache)
+ if (v9ses->cache)
dentry->d_op = &v9fs_cached_dentry_operations;
else
dentry->d_op = &v9fs_dentry_operations;
@@ -593,7 +593,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
if (result < 0)
goto error;
- if((fid->qid.version)&&(v9ses->cache))
+ if ((fid->qid.version) && (v9ses->cache))
dentry->d_op = &v9fs_cached_dentry_operations;
else
dentry->d_op = &v9fs_dentry_operations;
@@ -658,17 +658,17 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
old_inode = old_dentry->d_inode;
v9ses = v9fs_inode2v9ses(old_inode);
oldfid = v9fs_fid_lookup(old_dentry);
- if(IS_ERR(oldfid))
+ if (IS_ERR(oldfid))
return PTR_ERR(oldfid);
olddirfid = v9fs_fid_clone(old_dentry->d_parent);
- if(IS_ERR(olddirfid)) {
+ if (IS_ERR(olddirfid)) {
retval = PTR_ERR(olddirfid);
goto done;
}
newdirfid = v9fs_fid_clone(new_dentry->d_parent);
- if(IS_ERR(newdirfid)) {
+ if (IS_ERR(newdirfid)) {
retval = PTR_ERR(newdirfid);
goto clunk_olddir;
}
@@ -682,7 +682,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
}
v9fs_blank_wstat(&wstat);
- wstat.muid = v9ses->name;
+ wstat.muid = v9ses->uname;
wstat.name = (char *) new_dentry->d_name.name;
retval = p9_client_wstat(oldfid, &wstat);
@@ -768,7 +768,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (iattr->ia_valid & ATTR_SIZE)
wstat.length = iattr->ia_size;
- if (v9ses->extended) {
+ if (v9fs_extended(v9ses)) {
if (iattr->ia_valid & ATTR_UID)
wstat.n_uid = iattr->ia_uid;
@@ -805,10 +805,10 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode,
inode->i_mtime.tv_sec = stat->mtime;
inode->i_ctime.tv_sec = stat->mtime;
- inode->i_uid = v9ses->uid;
- inode->i_gid = v9ses->gid;
+ inode->i_uid = v9ses->dfltuid;
+ inode->i_gid = v9ses->dfltgid;
- if (v9ses->extended) {
+ if (v9fs_extended(v9ses)) {
inode->i_uid = stat->n_uid;
inode->i_gid = stat->n_gid;
}
@@ -887,10 +887,10 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
retval = -EPERM;
v9ses = v9fs_inode2v9ses(dentry->d_inode);
fid = v9fs_fid_lookup(dentry);
- if(IS_ERR(fid))
+ if (IS_ERR(fid))
return PTR_ERR(fid);
- if (!v9ses->extended)
+ if (!v9fs_extended(v9ses))
return -EBADF;
st = p9_client_stat(fid);
@@ -1011,7 +1011,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
struct p9_fid *fid;
v9ses = v9fs_inode2v9ses(dir);
- if (!v9ses->extended) {
+ if (!v9fs_extended(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n");
return -EPERM;
}
@@ -1070,7 +1070,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
old_dentry->d_name.name);
oldfid = v9fs_fid_clone(old_dentry);
- if(IS_ERR(oldfid))
+ if (IS_ERR(oldfid))
return PTR_ERR(oldfid);
name = __getname();
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index ba904371218..bb0cef9a6b8 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -216,24 +216,7 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
{
struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
- if (v9ses->debug != 0)
- seq_printf(m, ",debug=%x", v9ses->debug);
- if (v9ses->port != V9FS_PORT)
- seq_printf(m, ",port=%u", v9ses->port);
- if (v9ses->maxdata != 9000)
- seq_printf(m, ",msize=%u", v9ses->maxdata);
- if (v9ses->afid != ~0)
- seq_printf(m, ",afid=%u", v9ses->afid);
- if (v9ses->proto == PROTO_UNIX)
- seq_puts(m, ",proto=unix");
- if (v9ses->extended == 0)
- seq_puts(m, ",noextend");
- if (v9ses->nodev == 1)
- seq_puts(m, ",nodevmap");
- seq_printf(m, ",name=%s", v9ses->name);
- seq_printf(m, ",aname=%s", v9ses->remotename);
- seq_printf(m, ",uid=%u", v9ses->uid);
- seq_printf(m, ",gid=%u", v9ses->gid);
+ seq_printf(m, "%s", v9ses->options);
return 0;
}
diff --git a/fs/Kconfig b/fs/Kconfig
index bb02b39380a..e31f3691b15 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -140,6 +140,7 @@ config EXT4DEV_FS
tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
depends on EXPERIMENTAL
select JBD2
+ select CRC16
help
Ext4dev is a predecessor filesystem of the next generation
extended fs ext4, based on ext3 filesystem code. It will be
@@ -534,6 +535,24 @@ config QUOTA
with the quota tools. Probably the quota support is only useful for
multi user systems. If unsure, say N.
+config QUOTA_NETLINK_INTERFACE
+ bool "Report quota messages through netlink interface"
+ depends on QUOTA && NET
+ help
+ If you say Y here, quota warnings (about exceeding softlimit, reaching
+ hardlimit, etc.) will be reported through netlink interface. If unsure,
+ say Y.
+
+config PRINT_QUOTA_WARNING
+ bool "Print quota warnings to console (OBSOLETE)"
+ depends on QUOTA
+ default y
+ help
+ If you say Y here, quota warnings (about exceeding softlimit, reaching
+ hardlimit, etc.) will be printed to the process' controlling terminal.
+ Note that this behavior is currently deprecated and may go away in
+ future. Please use notification via netlink socket instead.
+
config QFMT_V1
tristate "Old quota format support"
depends on QUOTA
@@ -555,7 +574,7 @@ config QUOTACTL
default y
config DNOTIFY
- bool "Dnotify support" if EMBEDDED
+ bool "Dnotify support"
default y
help
Dnotify is a directory-based per-fd file change notification system
@@ -563,7 +582,7 @@ config DNOTIFY
superior alternatives, but some applications may still rely on
dnotify.
- Because of this, if unsure, say Y.
+ If unsure, say Y.
config AUTOFS_FS
tristate "Kernel automounter support"
@@ -999,20 +1018,6 @@ config HUGETLBFS
config HUGETLB_PAGE
def_bool HUGETLBFS
-config RAMFS
- bool
- default y
- ---help---
- Ramfs is a file system which keeps all files in RAM. It allows
- read and write access.
-
- It is more of an programming example than a useable file system. If
- you need a file system which lives in RAM with limit checking use
- tmpfs.
-
- To compile this as a module, choose M here: the module will be called
- ramfs.
-
config CONFIGFS_FS
tristate "Userspace-driven configuration filesystem (EXPERIMENTAL)"
depends on SYSFS && EXPERIMENTAL
@@ -1543,8 +1548,20 @@ config UFS_DEBUG
endmenu
-menu "Network File Systems"
+menuconfig NETWORK_FILESYSTEMS
+ bool "Network File Systems"
+ default y
depends on NET
+ ---help---
+ Say Y here to get to see options for network filesystems and
+ filesystem-related networking code, such as NFS daemon and
+ RPCSEC security modules.
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and
+ disabled; if unsure, say Y here.
+
+if NETWORK_FILESYSTEMS
config NFS_FS
tristate "NFS file system support"
@@ -1755,6 +1772,14 @@ config SUNRPC
config SUNRPC_GSS
tristate
+config SUNRPC_XPRT_RDMA
+ tristate "RDMA transport for sunrpc (EXPERIMENTAL)"
+ depends on SUNRPC && INFINIBAND && EXPERIMENTAL
+ default m
+ help
+ Adds a client RPC transport for supporting kernel NFS over RDMA
+ mounts, including Infiniband and iWARP. Experimental.
+
config SUNRPC_BIND34
bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)"
depends on SUNRPC && EXPERIMENTAL
@@ -2082,7 +2107,7 @@ config 9P_FS
If unsure, say N.
-endmenu
+endif # NETWORK_FILESYSTEMS
if BLOCK
menu "Partition Types"
diff --git a/fs/Makefile b/fs/Makefile
index 720c29d57a6..500cf15cdb4 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -72,7 +72,7 @@ obj-$(CONFIG_JBD) += jbd/
obj-$(CONFIG_JBD2) += jbd2/
obj-$(CONFIG_EXT2_FS) += ext2/
obj-$(CONFIG_CRAMFS) += cramfs/
-obj-$(CONFIG_RAMFS) += ramfs/
+obj-y += ramfs/
obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
obj-$(CONFIG_CODA_FS) += coda/
obj-$(CONFIG_MINIX_FS) += minix/
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 7e7a04be127..e647200262a 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -61,10 +61,14 @@ static int adfs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, adfs_get_block);
}
-static int adfs_prepare_write(struct file *file, struct page *page, unsigned int from, unsigned int to)
+static int adfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return cont_prepare_write(page, from, to, adfs_get_block,
- &ADFS_I(page->mapping->host)->mmu_private);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ adfs_get_block,
+ &ADFS_I(mapping->host)->mmu_private);
}
static sector_t _adfs_bmap(struct address_space *mapping, sector_t block)
@@ -76,8 +80,8 @@ static const struct address_space_operations adfs_aops = {
.readpage = adfs_readpage,
.writepage = adfs_writepage,
.sync_page = block_sync_page,
- .prepare_write = adfs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = adfs_write_begin,
+ .write_end = generic_write_end,
.bmap = _adfs_bmap
};
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 1c9fd302949..b36695ae5c2 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -228,7 +228,7 @@ static void adfs_destroy_inode(struct inode *inode)
kmem_cache_free(adfs_inode_cachep, ADFS_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct adfs_inode_info *ei = (struct adfs_inode_info *) foo;
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c
index b330009fe42..c4a5ad09ddf 100644
--- a/fs/affs/bitmap.c
+++ b/fs/affs/bitmap.c
@@ -11,7 +11,7 @@
/* This is, of course, shamelessly stolen from fs/minix */
-static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
+static const int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
static u32
affs_count_free_bits(u32 blocksize, const void *data)
diff --git a/fs/affs/file.c b/fs/affs/file.c
index c314a35f091..6e0c9399200 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -395,25 +395,33 @@ static int affs_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, affs_get_block, wbc);
}
+
static int affs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page, affs_get_block);
}
-static int affs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+static int affs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return cont_prepare_write(page, from, to, affs_get_block,
- &AFFS_I(page->mapping->host)->mmu_private);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ affs_get_block,
+ &AFFS_I(mapping->host)->mmu_private);
}
+
static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,affs_get_block);
}
+
const struct address_space_operations affs_aops = {
.readpage = affs_readpage,
.writepage = affs_writepage,
.sync_page = block_sync_page,
- .prepare_write = affs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = affs_write_begin,
+ .write_end = generic_write_end,
.bmap = _affs_bmap
};
@@ -603,54 +611,65 @@ affs_readpage_ofs(struct file *file, struct page *page)
return err;
}
-static int affs_prepare_write_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
+static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct inode *inode = page->mapping->host;
- u32 size, offset;
- u32 tmp;
+ struct inode *inode = mapping->host;
+ struct page *page;
+ pgoff_t index;
int err = 0;
- pr_debug("AFFS: prepare_write(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to);
- offset = page->index << PAGE_CACHE_SHIFT;
- if (offset + from > AFFS_I(inode)->mmu_private) {
- err = affs_extent_file_ofs(inode, offset + from);
+ pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
+ if (pos > AFFS_I(inode)->mmu_private) {
+ /* XXX: this probably leaves a too-big i_size in case of
+ * failure. Should really be updating i_size at write_end time
+ */
+ err = affs_extent_file_ofs(inode, pos);
if (err)
return err;
}
- size = inode->i_size;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
if (PageUptodate(page))
return 0;
- if (from) {
- err = affs_do_readpage_ofs(file, page, 0, from);
- if (err)
- return err;
- }
- if (to < PAGE_CACHE_SIZE) {
- zero_user_page(page, to, PAGE_CACHE_SIZE - to, KM_USER0);
- if (size > offset + to) {
- if (size < offset + PAGE_CACHE_SIZE)
- tmp = size & ~PAGE_CACHE_MASK;
- else
- tmp = PAGE_CACHE_SIZE;
- err = affs_do_readpage_ofs(file, page, to, tmp);
- }
+ /* XXX: inefficient but safe in the face of short writes */
+ err = affs_do_readpage_ofs(file, page, 0, PAGE_CACHE_SIZE);
+ if (err) {
+ unlock_page(page);
+ page_cache_release(page);
}
return err;
}
-static int affs_commit_write_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
+static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = mapping->host;
struct super_block *sb = inode->i_sb;
struct buffer_head *bh, *prev_bh;
char *data;
u32 bidx, boff, bsize;
+ unsigned from, to;
u32 tmp;
int written;
- pr_debug("AFFS: commit_write(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to);
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = pos + len;
+ /*
+ * XXX: not sure if this can handle short copies (len < copied), but
+ * we don't have to, because the page should always be uptodate here,
+ * due to write_begin.
+ */
+
+ pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
bsize = AFFS_SB(sb)->s_data_blksize;
data = page_address(page);
@@ -748,6 +767,9 @@ done:
if (tmp > inode->i_size)
inode->i_size = AFFS_I(inode)->mmu_private = tmp;
+ unlock_page(page);
+ page_cache_release(page);
+
return written;
out:
@@ -761,8 +783,8 @@ const struct address_space_operations affs_aops_ofs = {
.readpage = affs_readpage_ofs,
//.writepage = affs_writepage_ofs,
//.sync_page = affs_sync_page_ofs,
- .prepare_write = affs_prepare_write_ofs,
- .commit_write = affs_commit_write_ofs
+ .write_begin = affs_write_begin_ofs,
+ .write_end = affs_write_end_ofs
};
/* Free any preallocated blocks. */
@@ -805,18 +827,13 @@ affs_truncate(struct inode *inode)
if (inode->i_size > AFFS_I(inode)->mmu_private) {
struct address_space *mapping = inode->i_mapping;
struct page *page;
- u32 size = inode->i_size - 1;
+ void *fsdata;
+ u32 size = inode->i_size;
int res;
- page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT);
- if (!page)
- return;
- size = (size & (PAGE_CACHE_SIZE - 1)) + 1;
- res = mapping->a_ops->prepare_write(NULL, page, size, size);
+ res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
if (!res)
- res = mapping->a_ops->commit_write(NULL, page, size, size);
- unlock_page(page);
- page_cache_release(page);
+ res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
mark_inode_dirty(inode);
return;
} else if (inode->i_size == AFFS_I(inode)->mmu_private)
diff --git a/fs/affs/super.c b/fs/affs/super.c
index c80191ae205..b53e5d0ec65 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -84,7 +84,7 @@ static void affs_destroy_inode(struct inode *inode)
kmem_cache_free(affs_inode_cachep, AFFS_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct affs_inode_info *ei = (struct affs_inode_info *) foo;
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index b8243945818..a78d5b236bb 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -20,7 +20,9 @@
#include <linux/sched.h>
#include "internal.h"
+#if 0
unsigned afs_vnode_update_timeout = 10;
+#endif /* 0 */
#define afs_breakring_space(server) \
CIRC_SPACE((server)->cb_break_head, (server)->cb_break_tail, \
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 175a567db78..970d38f3056 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -33,6 +33,7 @@ static struct afs_cell *afs_cell_root;
static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
{
struct afs_cell *cell;
+ struct key *key;
size_t namelen;
char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
int ret;
@@ -89,20 +90,14 @@ static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
do {
*dp++ = toupper(*cp);
} while (*cp++);
- cell->anonymous_key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current,
- KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
- if (IS_ERR(cell->anonymous_key)) {
- _debug("no key");
- ret = PTR_ERR(cell->anonymous_key);
- goto error;
- }
- ret = key_instantiate_and_link(cell->anonymous_key, NULL, 0,
- NULL, NULL);
- if (ret < 0) {
- _debug("instantiate failed");
+ key = rxrpc_get_null_key(keyname);
+ if (IS_ERR(key)) {
+ _debug("no key");
+ ret = PTR_ERR(key);
goto error;
}
+ cell->anonymous_key = key;
_debug("anon key %p{%x}",
cell->anonymous_key, key_serial(cell->anonymous_key));
@@ -265,6 +260,7 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz)
return cell;
}
+#if 0
/*
* try and get a cell record
*/
@@ -280,6 +276,7 @@ struct afs_cell *afs_get_cell_maybe(struct afs_cell *cell)
write_unlock(&afs_cells_lock);
return cell;
}
+#endif /* 0 */
/*
* destroy a cell record
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index d5b2ad6575b..47b71c8947f 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -16,7 +16,9 @@
#include "internal.h"
#include "afs_cm.h"
+#if 0
struct workqueue_struct *afs_cm_workqueue;
+#endif /* 0 */
static int afs_deliver_cb_init_call_back_state(struct afs_call *,
struct sk_buff *, bool);
diff --git a/fs/afs/flock.c b/fs/afs/flock.c
index af6952e39a1..210acafe4a9 100644
--- a/fs/afs/flock.c
+++ b/fs/afs/flock.c
@@ -524,8 +524,7 @@ int afs_lock(struct file *file, int cmd, struct file_lock *fl)
(long long) fl->fl_start, (long long) fl->fl_end);
/* AFS doesn't support mandatory locks */
- if ((vnode->vfs_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
- fl->fl_type != F_UNLCK)
+ if (__mandatory_lock(&vnode->vfs_inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
if (IS_GETLK(cmd))
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 6306438f331..5ca3625cd39 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -570,7 +570,6 @@ extern int afs_abort_to_error(u32);
*/
extern const struct inode_operations afs_mntpt_inode_operations;
extern const struct file_operations afs_mntpt_file_operations;
-extern unsigned long afs_mntpt_expiry_timeout;
extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *);
extern void afs_mntpt_kill_timer(void);
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 6f8c96fb29e..5ce43b63c60 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -42,7 +42,7 @@ const struct inode_operations afs_mntpt_inode_operations = {
static LIST_HEAD(afs_vfsmounts);
static DECLARE_DELAYED_WORK(afs_mntpt_expiry_timer, afs_mntpt_expiry_timed_out);
-unsigned long afs_mntpt_expiry_timeout = 10 * 60;
+static unsigned long afs_mntpt_expiry_timeout = 10 * 60;
/*
* check a symbolic link to see whether it actually encodes a mountpoint
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 6edb56683b9..846c7615ac9 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -513,7 +513,7 @@ static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v)
up_read(&cell->vl_sem);
}
-const char afs_vlocation_states[][4] = {
+static const char afs_vlocation_states[][4] = {
[AFS_VL_NEW] = "New",
[AFS_VL_CREATING] = "Crt",
[AFS_VL_VALID] = "Val",
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 8ccee9ee1d9..bde3f19c099 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -239,7 +239,8 @@ void afs_flat_call_destructor(struct afs_call *call)
/*
* attach the data from a bunch of pages on an inode to a call
*/
-int afs_send_pages(struct afs_call *call, struct msghdr *msg, struct kvec *iov)
+static int afs_send_pages(struct afs_call *call, struct msghdr *msg,
+ struct kvec *iov)
{
struct page *pages[8];
unsigned count, n, loop, offset, to;
diff --git a/fs/afs/server.c b/fs/afs/server.c
index 231ae415027..28f2451419e 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -13,7 +13,7 @@
#include <linux/slab.h>
#include "internal.h"
-unsigned afs_server_timeout = 10; /* server timeout in seconds */
+static unsigned afs_server_timeout = 10; /* server timeout in seconds */
static void afs_reap_server(struct work_struct *);
diff --git a/fs/afs/super.c b/fs/afs/super.c
index b8808b40f82..4b2558c4221 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -27,8 +27,7 @@
#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
-static void afs_i_init_once(void *foo, struct kmem_cache *cachep,
- unsigned long flags);
+static void afs_i_init_once(struct kmem_cache *cachep, void *foo);
static int afs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name,
void *data, struct vfsmount *mnt);
@@ -446,8 +445,7 @@ static void afs_put_super(struct super_block *sb)
/*
* initialise an inode cache slab element prior to any use
*/
-static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep,
- unsigned long flags)
+static void afs_i_init_once(struct kmem_cache *cachep, void *_vnode)
{
struct afs_vnode *vnode = _vnode;
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c
index 09e3ad0fc7c..7b4bbe48112 100644
--- a/fs/afs/vlocation.c
+++ b/fs/afs/vlocation.c
@@ -15,8 +15,8 @@
#include <linux/sched.h>
#include "internal.h"
-unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */
-unsigned afs_vlocation_update_timeout = 10 * 60;
+static unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */
+static unsigned afs_vlocation_update_timeout = 10 * 60;
static void afs_vlocation_reaper(struct work_struct *);
static void afs_vlocation_updater(struct work_struct *);
@@ -335,7 +335,7 @@ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl,
/*
* queue a vlocation record for updates
*/
-void afs_vlocation_queue_for_updates(struct afs_vlocation *vl)
+static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl)
{
struct afs_vlocation *xvl;
diff --git a/fs/afs/write.c b/fs/afs/write.c
index a03b92a0fe1..9a849ad3c48 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
+#include <linux/backing-dev.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
@@ -510,9 +510,9 @@ int afs_writepage(struct page *page, struct writeback_control *wbc)
/*
* write a region of pages back to the server
*/
-int afs_writepages_region(struct address_space *mapping,
- struct writeback_control *wbc,
- pgoff_t index, pgoff_t end, pgoff_t *_next)
+static int afs_writepages_region(struct address_space *mapping,
+ struct writeback_control *wbc,
+ pgoff_t index, pgoff_t end, pgoff_t *_next)
{
struct backing_dev_info *bdi = mapping->backing_dev_info;
struct afs_writeback *wb;
diff --git a/fs/aio.c b/fs/aio.c
index ea2e1982038..f12db415c0f 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -303,7 +303,7 @@ static void wait_for_all_aios(struct kioctx *ctx)
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
while (ctx->reqs_active) {
spin_unlock_irq(&ctx->ctx_lock);
- schedule();
+ io_schedule();
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
spin_lock_irq(&ctx->ctx_lock);
}
@@ -323,7 +323,7 @@ ssize_t fastcall wait_on_sync_kiocb(struct kiocb *iocb)
set_current_state(TASK_UNINTERRUPTIBLE);
if (!iocb->ki_users)
break;
- schedule();
+ io_schedule();
}
__set_current_state(TASK_RUNNING);
return iocb->ki_user_data;
@@ -710,18 +710,9 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
/*
* Now we are all set to call the retry method in async
- * context. By setting this thread's io_wait context
- * to point to the wait queue entry inside the currently
- * running iocb for the duration of the retry, we ensure
- * that async notification wakeups are queued by the
- * operation instead of blocking waits, and when notified,
- * cause the iocb to be kicked for continuation (through
- * the aio_wake_function callback).
+ * context.
*/
- BUG_ON(current->io_wait != NULL);
- current->io_wait = &iocb->ki_wait;
ret = retry(iocb);
- current->io_wait = NULL;
if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
BUG_ON(!list_empty(&iocb->ki_wait.task_list));
@@ -1170,7 +1161,7 @@ retry:
ret = 0;
if (to.timed_out) /* Only check after read evt */
break;
- schedule();
+ io_schedule();
if (signal_pending(tsk)) {
ret = -EINTR;
break;
@@ -1508,10 +1499,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb)
* Simply triggers a retry of the operation via kick_iocb.
*
* This callback is specified in the wait queue entry in
- * a kiocb (current->io_wait points to this wait queue
- * entry when an aio operation executes; it is used
- * instead of a synchronous wait when an i/o blocking
- * condition is encountered during aio).
+ * a kiocb.
*
* Note:
* This routine is executed with the wait queue lock held.
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index b4a75880f6f..23321889d9b 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -76,7 +76,6 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
{
struct qstr this;
struct dentry *dentry;
- struct inode *inode;
struct file *file;
int error, fd;
@@ -86,15 +85,9 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
if (!file)
return -ENFILE;
- inode = igrab(anon_inode_inode);
- if (IS_ERR(inode)) {
- error = PTR_ERR(inode);
- goto err_put_filp;
- }
-
error = get_unused_fd();
if (error < 0)
- goto err_iput;
+ goto err_put_filp;
fd = error;
/*
@@ -108,14 +101,22 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
if (!dentry)
goto err_put_unused_fd;
+
+ /*
+ * We know the anon_inode inode count is always greater than zero,
+ * so we can avoid doing an igrab() and we can use an open-coded
+ * atomic_inc().
+ */
+ atomic_inc(&anon_inode_inode->i_count);
+
dentry->d_op = &anon_inodefs_dentry_operations;
/* Do not publish this dentry inside the global dentry hash table */
dentry->d_flags &= ~DCACHE_UNHASHED;
- d_instantiate(dentry, inode);
+ d_instantiate(dentry, anon_inode_inode);
file->f_path.mnt = mntget(anon_inode_mnt);
file->f_path.dentry = dentry;
- file->f_mapping = inode->i_mapping;
+ file->f_mapping = anon_inode_inode->i_mapping;
file->f_pos = 0;
file->f_flags = O_RDWR;
@@ -127,14 +128,12 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
fd_install(fd, file);
*pfd = fd;
- *pinode = inode;
+ *pinode = anon_inode_inode;
*pfile = file;
return 0;
err_put_unused_fd:
put_unused_fd(fd);
-err_iput:
- iput(inode);
err_put_filp:
put_filp(file);
return error;
diff --git a/fs/attr.c b/fs/attr.c
index f8dfc2269d8..966b73e25f8 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -103,12 +103,11 @@ EXPORT_SYMBOL(inode_setattr);
int notify_change(struct dentry * dentry, struct iattr * attr)
{
struct inode *inode = dentry->d_inode;
- mode_t mode;
+ mode_t mode = inode->i_mode;
int error;
struct timespec now;
unsigned int ia_valid = attr->ia_valid;
- mode = inode->i_mode;
now = current_fs_time(inode->i_sb);
attr->ia_ctime = now;
@@ -116,18 +115,34 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
attr->ia_atime = now;
if (!(ia_valid & ATTR_MTIME_SET))
attr->ia_mtime = now;
+ if (ia_valid & ATTR_KILL_PRIV) {
+ attr->ia_valid &= ~ATTR_KILL_PRIV;
+ ia_valid &= ~ATTR_KILL_PRIV;
+ error = security_inode_need_killpriv(dentry);
+ if (error > 0)
+ error = security_inode_killpriv(dentry);
+ if (error)
+ return error;
+ }
+
+ /*
+ * We now pass ATTR_KILL_S*ID to the lower level setattr function so
+ * that the function has the ability to reinterpret a mode change
+ * that's due to these bits. This adds an implicit restriction that
+ * no function will ever call notify_change with both ATTR_MODE and
+ * ATTR_KILL_S*ID set.
+ */
+ if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) &&
+ (ia_valid & ATTR_MODE))
+ BUG();
+
if (ia_valid & ATTR_KILL_SUID) {
- attr->ia_valid &= ~ATTR_KILL_SUID;
if (mode & S_ISUID) {
- if (!(ia_valid & ATTR_MODE)) {
- ia_valid = attr->ia_valid |= ATTR_MODE;
- attr->ia_mode = inode->i_mode;
- }
- attr->ia_mode &= ~S_ISUID;
+ ia_valid = attr->ia_valid |= ATTR_MODE;
+ attr->ia_mode = (inode->i_mode & ~S_ISUID);
}
}
if (ia_valid & ATTR_KILL_SGID) {
- attr->ia_valid &= ~ ATTR_KILL_SGID;
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
if (!(ia_valid & ATTR_MODE)) {
ia_valid = attr->ia_valid |= ATTR_MODE;
@@ -136,7 +151,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
attr->ia_mode &= ~S_ISGID;
}
}
- if (!attr->ia_valid)
+ if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID)))
return 0;
if (ia_valid & ATTR_SIZE)
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index 19a9cafb5dd..be46805972f 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -182,7 +182,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_toke
{
struct autofs_wait_queue *wq, **wql;
- for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) {
+ for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
if ( wq->wait_queue_token == wait_queue_token )
break;
}
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 692364e8ffc..cd81f083667 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -312,13 +312,11 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
struct autofs_sb_info *sbi;
struct autofs_info *ino;
- sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
+ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
goto fail_unlock;
DPRINTK("starting up, sbi = %p",sbi);
- memset(sbi, 0, sizeof(*sbi));
-
s->s_fs_info = sbi;
sbi->magic = AUTOFS_SBI_MAGIC;
sbi->pipefd = -1;
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 0d041a9cb34..1fe28e4754c 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -376,7 +376,7 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok
struct autofs_wait_queue *wq, **wql;
mutex_lock(&sbi->wq_mutex);
- for (wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next) {
+ for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
if (wq->wait_queue_token == wait_queue_token)
break;
}
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index a4514182768..b28a20e61b8 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -289,7 +289,7 @@ befs_destroy_inode(struct inode *inode)
kmem_cache_free(befs_inode_cachep, BEFS_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct befs_inode_info *bi = (struct befs_inode_info *) foo;
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index 24310e9ee05..911b4ccf470 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -145,9 +145,13 @@ static int bfs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, bfs_get_block);
}
-static int bfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int bfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page, from, to, bfs_get_block);
+ *pagep = NULL;
+ return block_write_begin(file, mapping, pos, len, flags,
+ pagep, fsdata, bfs_get_block);
}
static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
@@ -159,8 +163,8 @@ const struct address_space_operations bfs_aops = {
.readpage = bfs_readpage,
.writepage = bfs_writepage,
.sync_page = block_sync_page,
- .prepare_write = bfs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = bfs_write_begin,
+ .write_end = generic_write_end,
.bmap = bfs_bmap,
};
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index f346eb14e86..7bd9c2bbe6e 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -244,7 +244,7 @@ static void bfs_destroy_inode(struct inode *inode)
kmem_cache_free(bfs_inode_cachep, BFS_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct bfs_inode_info *bi = foo;
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 813a887cd2b..e176d195e7e 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -31,7 +31,7 @@
static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
static int load_aout_library(struct file*);
-static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
+static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
static struct linux_binfmt aout_format = {
.module = THIS_MODULE,
@@ -88,7 +88,7 @@ if (file->f_op->llseek) { \
* dumping of the process results in another error..
*/
-static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
+static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
mm_segment_t fs;
int has_dumped = 0;
@@ -123,23 +123,19 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
/* If the size of the dump file exceeds the rlimit, then see what would happen
if we wrote the stack, but not the data area. */
#ifdef __sparc__
- if ((dump.u_dsize+dump.u_ssize) >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if ((dump.u_dsize + dump.u_ssize) > limit)
dump.u_dsize = 0;
#else
- if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
dump.u_dsize = 0;
#endif
/* Make sure we have enough room to write the stack and data areas. */
#ifdef __sparc__
- if ((dump.u_ssize) >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if (dump.u_ssize > limit)
dump.u_ssize = 0;
#else
- if ((dump.u_ssize+1) * PAGE_SIZE >
- current->signal->rlim[RLIMIT_CORE].rlim_cur)
+ if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
dump.u_ssize = 0;
#endif
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b1013f34085..6e2f3b8dde7 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -52,7 +52,7 @@ static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, i
* don't even try.
*/
#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
-static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file);
+static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
#else
#define elf_core_dump NULL
#endif
@@ -151,6 +151,14 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
struct vm_area_struct *vma;
/*
+ * In some cases (e.g. Hyper-Threading), we want to avoid L1
+ * evictions by the processes running on the same package. One
+ * thing we can do is to shuffle the initial stack for them.
+ */
+
+ p = arch_align_stack(p);
+
+ /*
* If this architecture has a platform capability string, copy it
* to userspace. In some cases (Sparc), this info is impossible
* for userspace to get any other way, in others (i386) it is
@@ -160,14 +168,6 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
if (k_platform) {
size_t len = strlen(k_platform) + 1;
- /*
- * In some cases (e.g. Hyper-Threading), we want to avoid L1
- * evictions by the processes running on the same package. One
- * thing we can do is to shuffle the initial stack for them.
- */
-
- p = arch_align_stack(p);
-
u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
if (__copy_to_user(u_platform, k_platform, len))
return -EFAULT;
@@ -175,6 +175,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
/* Create the ELF interpreter info */
elf_info = (elf_addr_t *)current->mm->saved_auxv;
+ /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
#define NEW_AUX_ENT(id, val) \
do { \
elf_info[ei_index++] = id; \
@@ -185,6 +186,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
/*
* ARCH_DLINFO must come first so PPC can do its special alignment of
* AUXV.
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT() in
+ * ARCH_DLINFO changes
*/
ARCH_DLINFO;
#endif
@@ -730,6 +733,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
/* Some simple consistency checks for the interpreter */
if (elf_interpreter) {
+ static int warn;
interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
/* Now figure out which format our binary is */
@@ -741,6 +745,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
interpreter_type &= ~INTERPRETER_ELF;
+ if (interpreter_type == INTERPRETER_AOUT && warn < 10) {
+ printk(KERN_WARNING "a.out ELF interpreter %s is "
+ "deprecated and will not be supported "
+ "after Linux 2.6.25\n", elf_interpreter);
+ warn++;
+ }
+
retval = -ELIBBAD;
if (!interpreter_type)
goto out_free_dentry;
@@ -1193,35 +1204,68 @@ static int dump_seek(struct file *file, loff_t off)
}
/*
- * Decide whether a segment is worth dumping; default is yes to be
- * sure (missing info is worse than too much; etc).
- * Personally I'd include everything, and use the coredump limit...
- *
- * I think we should skip something. But I am not sure how. H.J.
+ * Decide what to dump of a segment, part, all or none.
*/
-static int maydump(struct vm_area_struct *vma, unsigned long mm_flags)
+static unsigned long vma_dump_size(struct vm_area_struct *vma,
+ unsigned long mm_flags)
{
/* The vma can be set up to tell us the answer directly. */
if (vma->vm_flags & VM_ALWAYSDUMP)
- return 1;
+ goto whole;
/* Do not dump I/O mapped devices or special mappings */
if (vma->vm_flags & (VM_IO | VM_RESERVED))
return 0;
+#define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
+
/* By default, dump shared memory if mapped from an anonymous file. */
if (vma->vm_flags & VM_SHARED) {
- if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0)
- return test_bit(MMF_DUMP_ANON_SHARED, &mm_flags);
- else
- return test_bit(MMF_DUMP_MAPPED_SHARED, &mm_flags);
+ if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ?
+ FILTER(ANON_SHARED) : FILTER(MAPPED_SHARED))
+ goto whole;
+ return 0;
}
- /* By default, if it hasn't been written to, don't write it out. */
- if (!vma->anon_vma)
- return test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags);
+ /* Dump segments that have been written to. */
+ if (vma->anon_vma && FILTER(ANON_PRIVATE))
+ goto whole;
+ if (vma->vm_file == NULL)
+ return 0;
+
+ if (FILTER(MAPPED_PRIVATE))
+ goto whole;
- return test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags);
+ /*
+ * If this looks like the beginning of a DSO or executable mapping,
+ * check for an ELF header. If we find one, dump the first page to
+ * aid in determining what was mapped here.
+ */
+ if (FILTER(ELF_HEADERS) && vma->vm_file != NULL && vma->vm_pgoff == 0) {
+ u32 __user *header = (u32 __user *) vma->vm_start;
+ u32 word;
+ /*
+ * Doing it this way gets the constant folded by GCC.
+ */
+ union {
+ u32 cmp;
+ char elfmag[SELFMAG];
+ } magic;
+ BUILD_BUG_ON(SELFMAG != sizeof word);
+ magic.elfmag[EI_MAG0] = ELFMAG0;
+ magic.elfmag[EI_MAG1] = ELFMAG1;
+ magic.elfmag[EI_MAG2] = ELFMAG2;
+ magic.elfmag[EI_MAG3] = ELFMAG3;
+ if (get_user(word, header) == 0 && word == magic.cmp)
+ return PAGE_SIZE;
+ }
+
+#undef FILTER
+
+ return 0;
+
+whole:
+ return vma->vm_end - vma->vm_start;
}
/* An ELF note in memory */
@@ -1411,7 +1455,7 @@ struct elf_thread_status
elf_fpregset_t fpu; /* NT_PRFPREG */
struct task_struct *thread;
#ifdef ELF_CORE_COPY_XFPREGS
- elf_fpxregset_t xfpu; /* NT_PRXFPREG */
+ elf_fpxregset_t xfpu; /* ELF_CORE_XFPREG_TYPE */
#endif
struct memelfnote notes[3];
int num_notes;
@@ -1446,8 +1490,8 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
#ifdef ELF_CORE_COPY_XFPREGS
if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
- fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu),
- &t->xfpu);
+ fill_note(&t->notes[2], "LINUX", ELF_CORE_XFPREG_TYPE,
+ sizeof(t->xfpu), &t->xfpu);
t->num_notes++;
sz += notesize(&t->notes[2]);
}
@@ -1488,7 +1532,7 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
* and then they are actually written out. If we run out of core limit
* we just truncate.
*/
-static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
+static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
#define NUM_NOTES 6
int has_dumped = 0;
@@ -1499,7 +1543,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
struct vm_area_struct *vma, *gate_vma;
struct elfhdr *elf = NULL;
loff_t offset = 0, dataoff, foffset;
- unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
int numnote;
struct memelfnote *notes = NULL;
struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1621,7 +1664,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
#ifdef ELF_CORE_COPY_XFPREGS
if (elf_core_copy_task_xfpregs(current, xfpu))
fill_note(notes + numnote++,
- "LINUX", NT_PRXFPREG, sizeof(*xfpu), xfpu);
+ "LINUX", ELF_CORE_XFPREG_TYPE, sizeof(*xfpu), xfpu);
#endif
fs = get_fs();
@@ -1662,16 +1705,13 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
for (vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma)) {
struct elf_phdr phdr;
- size_t sz;
-
- sz = vma->vm_end - vma->vm_start;
phdr.p_type = PT_LOAD;
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
- phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
- phdr.p_memsz = sz;
+ phdr.p_filesz = vma_dump_size(vma, mm_flags);
+ phdr.p_memsz = vma->vm_end - vma->vm_start;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
if (vma->vm_flags & VM_WRITE)
@@ -1711,13 +1751,11 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
for (vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma)) {
unsigned long addr;
+ unsigned long end;
- if (!maydump(vma, mm_flags))
- continue;
+ end = vma->vm_start + vma_dump_size(vma, mm_flags);
- for (addr = vma->vm_start;
- addr < vma->vm_end;
- addr += PAGE_SIZE) {
+ for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
struct page *page;
struct vm_area_struct *vma;
@@ -1725,7 +1763,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
&page, &vma) <= 0) {
DUMP_SEEK(PAGE_SIZE);
} else {
- if (page == ZERO_PAGE(addr)) {
+ if (page == ZERO_PAGE(0)) {
if (!dump_seek(file, PAGE_SIZE)) {
page_cache_release(page);
goto end_coredump;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 2f5d8dbe676..033861c6b8f 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -75,7 +75,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *,
struct file *, struct mm_struct *);
#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
-static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *);
+static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *, unsigned long limit);
#endif
static struct linux_binfmt elf_fdpic_format = {
@@ -1417,7 +1417,7 @@ struct elf_thread_status
elf_fpregset_t fpu; /* NT_PRFPREG */
struct task_struct *thread;
#ifdef ELF_CORE_COPY_XFPREGS
- elf_fpxregset_t xfpu; /* NT_PRXFPREG */
+ elf_fpxregset_t xfpu; /* ELF_CORE_XFPREG_TYPE */
#endif
struct memelfnote notes[3];
int num_notes;
@@ -1453,8 +1453,8 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
#ifdef ELF_CORE_COPY_XFPREGS
if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
- fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu),
- &t->xfpu);
+ fill_note(&t->notes[2], "LINUX", ELF_CORE_XFPREG_TYPE,
+ sizeof(t->xfpu), &t->xfpu);
t->num_notes++;
sz += notesize(&t->notes[2]);
}
@@ -1488,7 +1488,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
&page, &vma) <= 0) {
DUMP_SEEK(file->f_pos + PAGE_SIZE);
}
- else if (page == ZERO_PAGE(addr)) {
+ else if (page == ZERO_PAGE(0)) {
page_cache_release(page);
DUMP_SEEK(file->f_pos + PAGE_SIZE);
}
@@ -1552,7 +1552,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
* we just truncate.
*/
static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
- struct file *file)
+ struct file *file, unsigned long limit)
{
#define NUM_NOTES 6
int has_dumped = 0;
@@ -1563,7 +1563,6 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
struct vm_area_struct *vma;
struct elfhdr *elf = NULL;
loff_t offset = 0, dataoff;
- unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
int numnote;
struct memelfnote *notes = NULL;
struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1690,7 +1689,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
#ifdef ELF_CORE_COPY_XFPREGS
if (elf_core_copy_task_xfpregs(current, xfpu))
fill_note(notes + numnote++,
- "LINUX", NT_PRXFPREG, sizeof(*xfpu), xfpu);
+ "LINUX", ELF_CORE_XFPREG_TYPE, sizeof(*xfpu), xfpu);
#endif
fs = get_fs();
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index fcb3405bb14..33764fd6db6 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -75,7 +75,7 @@ static int load_flat_shared_library(int id, struct lib_info *p);
#endif
static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
-static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file);
+static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
static struct linux_binfmt flat_format = {
.module = THIS_MODULE,
@@ -90,7 +90,7 @@ static struct linux_binfmt flat_format = {
* Currently only a stub-function.
*/
-static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file)
+static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
printk("Process %s:%d received signr %d and should have core dumped\n",
current->comm, current->pid, (int) signr);
@@ -113,7 +113,7 @@ static unsigned long create_flat_tables(
char * p = (char*)pp;
int argc = bprm->argc;
int envc = bprm->envc;
- char dummy;
+ char uninitialized_var(dummy);
sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p);
@@ -290,7 +290,6 @@ out_free_buf:
kfree(buf);
out_free:
kfree(strm.workspace);
-out:
return retval;
}
@@ -459,7 +458,9 @@ static int load_flat_file(struct linux_binprm * bprm,
printk("BINFMT_FLAT: Loading file: %s\n", bprm->filename);
if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {
- printk("BINFMT_FLAT: bad flat file version 0x%x (supported 0x%x and 0x%x)\n", rev, FLAT_VERSION, OLD_FLAT_VERSION);
+ printk("BINFMT_FLAT: bad flat file version 0x%x (supported "
+ "0x%lx and 0x%lx)\n",
+ rev, FLAT_VERSION, OLD_FLAT_VERSION);
ret = -ENOEXEC;
goto err;
}
@@ -515,7 +516,8 @@ static int load_flat_file(struct linux_binprm * bprm,
/*
* calculate the extra space we need to map in
*/
- extra = max(bss_len + stack_len, relocs * sizeof(unsigned long));
+ extra = max_t(unsigned long, bss_len + stack_len,
+ relocs * sizeof(unsigned long));
/*
* there are a couple of cases here, the separate code/data
@@ -546,7 +548,7 @@ static int load_flat_file(struct linux_binprm * bprm,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
/* Remap to use all availabe slack region space */
if (realdatastart && (realdatastart < (unsigned long)-4096)) {
- reallen = ksize(realdatastart);
+ reallen = ksize((void *)realdatastart);
if (reallen > len) {
realdatastart = do_mremap(realdatastart, len,
reallen, MREMAP_FIXED, realdatastart);
@@ -598,7 +600,7 @@ static int load_flat_file(struct linux_binprm * bprm,
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
/* Remap to use all availabe slack region space */
if (textpos && (textpos < (unsigned long) -4096)) {
- reallen = ksize(textpos);
+ reallen = ksize((void *)textpos);
if (reallen > len) {
textpos = do_mremap(textpos, len, reallen,
MREMAP_FIXED, textpos);
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 5bcdaaf4eae..9208c41209f 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -44,7 +44,7 @@ static int load_som_library(struct file *);
* don't even try.
*/
#if 0
-static int som_core_dump(long signr, struct pt_regs * regs);
+static int som_core_dump(long signr, struct pt_regs *regs, unsigned long limit);
#else
#define som_core_dump NULL
#endif
diff --git a/fs/bio.c b/fs/bio.c
index 5f604f269df..d59ddbf7962 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -109,11 +109,14 @@ static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned lon
void bio_free(struct bio *bio, struct bio_set *bio_set)
{
- const int pool_idx = BIO_POOL_IDX(bio);
+ if (bio->bi_io_vec) {
+ const int pool_idx = BIO_POOL_IDX(bio);
- BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
+ BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
+
+ mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
+ }
- mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
mempool_free(bio, bio_set->bio_pool);
}
@@ -127,21 +130,9 @@ static void bio_fs_destructor(struct bio *bio)
void bio_init(struct bio *bio)
{
- bio->bi_next = NULL;
- bio->bi_bdev = NULL;
+ memset(bio, 0, sizeof(*bio));
bio->bi_flags = 1 << BIO_UPTODATE;
- bio->bi_rw = 0;
- bio->bi_vcnt = 0;
- bio->bi_idx = 0;
- bio->bi_phys_segments = 0;
- bio->bi_hw_segments = 0;
- bio->bi_hw_front_size = 0;
- bio->bi_hw_back_size = 0;
- bio->bi_size = 0;
- bio->bi_max_vecs = 0;
- bio->bi_end_io = NULL;
atomic_set(&bio->bi_cnt, 1);
- bio->bi_private = NULL;
}
/**
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 6339a30879b..993f78c5522 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -378,14 +378,26 @@ static int blkdev_readpage(struct file * file, struct page * page)
return block_read_full_page(page, blkdev_get_block);
}
-static int blkdev_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int blkdev_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page, from, to, blkdev_get_block);
+ *pagep = NULL;
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ blkdev_get_block);
}
-static int blkdev_commit_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int blkdev_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- return block_commit_write(page, from, to);
+ int ret;
+ ret = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret;
}
/*
@@ -453,7 +465,7 @@ static void bdev_destroy_inode(struct inode *inode)
kmem_cache_free(bdev_cachep, bdi);
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct bdev_inode *ei = (struct bdev_inode *) foo;
struct block_device *bdev = &ei->bdev;
@@ -1327,8 +1339,8 @@ const struct address_space_operations def_blk_aops = {
.readpage = blkdev_readpage,
.writepage = blkdev_writepage,
.sync_page = block_sync_page,
- .prepare_write = blkdev_prepare_write,
- .commit_write = blkdev_commit_write,
+ .write_begin = blkdev_write_begin,
+ .write_end = blkdev_write_end,
.writepages = generic_writepages,
.direct_IO = blkdev_direct_IO,
};
diff --git a/fs/buffer.c b/fs/buffer.c
index 75b51dfa5e0..76403b1764c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -110,10 +110,14 @@ static void buffer_io_error(struct buffer_head *bh)
}
/*
- * Default synchronous end-of-IO handler.. Just mark it up-to-date and
- * unlock the buffer. This is what ll_rw_block uses too.
+ * End-of-IO handler helper function which does not touch the bh after
+ * unlocking it.
+ * Note: unlock_buffer() sort-of does touch the bh after unlocking it, but
+ * a race there is benign: unlock_buffer() only use the bh's address for
+ * hashing after unlocking the buffer, so it doesn't actually touch the bh
+ * itself.
*/
-void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
+static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)
{
if (uptodate) {
set_buffer_uptodate(bh);
@@ -122,6 +126,15 @@ void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
clear_buffer_uptodate(bh);
}
unlock_buffer(bh);
+}
+
+/*
+ * Default synchronous end-of-IO handler.. Just mark it up-to-date and
+ * unlock the buffer. This is what ll_rw_block uses too.
+ */
+void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
+{
+ __end_buffer_read_notouch(bh, uptodate);
put_bh(bh);
}
@@ -697,6 +710,8 @@ static int __set_page_dirty(struct page *page,
if (mapping_cap_account_dirty(mapping)) {
__inc_zone_page_state(page, NR_FILE_DIRTY);
+ __inc_bdi_stat(mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
task_io_account_write(PAGE_CACHE_SIZE);
}
radix_tree_tag_set(&mapping->page_tree,
@@ -1715,7 +1730,6 @@ done:
* The page and buffer_heads can be released at any time from
* here on.
*/
- wbc->pages_skipped++; /* We didn't write this page */
}
return err;
@@ -1757,6 +1771,48 @@ recover:
goto done;
}
+/*
+ * If a page has any new buffers, zero them out here, and mark them uptodate
+ * and dirty so they'll be written out (in order to prevent uninitialised
+ * block data from leaking). And clear the new bit.
+ */
+void page_zero_new_buffers(struct page *page, unsigned from, unsigned to)
+{
+ unsigned int block_start, block_end;
+ struct buffer_head *head, *bh;
+
+ BUG_ON(!PageLocked(page));
+ if (!page_has_buffers(page))
+ return;
+
+ bh = head = page_buffers(page);
+ block_start = 0;
+ do {
+ block_end = block_start + bh->b_size;
+
+ if (buffer_new(bh)) {
+ if (block_end > from && block_start < to) {
+ if (!PageUptodate(page)) {
+ unsigned start, size;
+
+ start = max(from, block_start);
+ size = min(to, block_end) - start;
+
+ zero_user_page(page, start, size, KM_USER0);
+ set_buffer_uptodate(bh);
+ }
+
+ clear_buffer_new(bh);
+ mark_buffer_dirty(bh);
+ }
+ }
+
+ block_start = block_end;
+ bh = bh->b_this_page;
+ } while (bh != head);
+}
+EXPORT_SYMBOL(page_zero_new_buffers);
+
static int __block_prepare_write(struct inode *inode, struct page *page,
unsigned from, unsigned to, get_block_t *get_block)
{
@@ -1800,7 +1856,9 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
unmap_underlying_metadata(bh->b_bdev,
bh->b_blocknr);
if (PageUptodate(page)) {
+ clear_buffer_new(bh);
set_buffer_uptodate(bh);
+ mark_buffer_dirty(bh);
continue;
}
if (block_end > to || block_start < from) {
@@ -1839,38 +1897,8 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
if (!buffer_uptodate(*wait_bh))
err = -EIO;
}
- if (!err) {
- bh = head;
- do {
- if (buffer_new(bh))
- clear_buffer_new(bh);
- } while ((bh = bh->b_this_page) != head);
- return 0;
- }
- /* Error case: */
- /*
- * Zero out any newly allocated blocks to avoid exposing stale
- * data. If BH_New is set, we know that the block was newly
- * allocated in the above loop.
- */
- bh = head;
- block_start = 0;
- do {
- block_end = block_start+blocksize;
- if (block_end <= from)
- goto next_bh;
- if (block_start >= to)
- break;
- if (buffer_new(bh)) {
- clear_buffer_new(bh);
- zero_user_page(page, block_start, bh->b_size, KM_USER0);
- set_buffer_uptodate(bh);
- mark_buffer_dirty(bh);
- }
-next_bh:
- block_start = block_end;
- bh = bh->b_this_page;
- } while (bh != head);
+ if (unlikely(err))
+ page_zero_new_buffers(page, from, to);
return err;
}
@@ -1895,6 +1923,7 @@ static int __block_commit_write(struct inode *inode, struct page *page,
set_buffer_uptodate(bh);
mark_buffer_dirty(bh);
}
+ clear_buffer_new(bh);
}
/*
@@ -1909,6 +1938,130 @@ static int __block_commit_write(struct inode *inode, struct page *page,
}
/*
+ * block_write_begin takes care of the basic task of block allocation and
+ * bringing partial write blocks uptodate first.
+ *
+ * If *pagep is not NULL, then block_write_begin uses the locked page
+ * at *pagep rather than allocating its own. In this case, the page will
+ * not be unlocked or deallocated on failure.
+ */
+int block_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata,
+ get_block_t *get_block)
+{
+ struct inode *inode = mapping->host;
+ int status = 0;
+ struct page *page;
+ pgoff_t index;
+ unsigned start, end;
+ int ownpage = 0;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ start = pos & (PAGE_CACHE_SIZE - 1);
+ end = start + len;
+
+ page = *pagep;
+ if (page == NULL) {
+ ownpage = 1;
+ page = __grab_cache_page(mapping, index);
+ if (!page) {
+ status = -ENOMEM;
+ goto out;
+ }
+ *pagep = page;
+ } else
+ BUG_ON(!PageLocked(page));
+
+ status = __block_prepare_write(inode, page, start, end, get_block);
+ if (unlikely(status)) {
+ ClearPageUptodate(page);
+
+ if (ownpage) {
+ unlock_page(page);
+ page_cache_release(page);
+ *pagep = NULL;
+
+ /*
+ * prepare_write() may have instantiated a few blocks
+ * outside i_size. Trim these off again. Don't need
+ * i_size_read because we hold i_mutex.
+ */
+ if (pos + len > inode->i_size)
+ vmtruncate(inode, inode->i_size);
+ }
+ goto out;
+ }
+
+out:
+ return status;
+}
+EXPORT_SYMBOL(block_write_begin);
+
+int block_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+ unsigned start;
+
+ start = pos & (PAGE_CACHE_SIZE - 1);
+
+ if (unlikely(copied < len)) {
+ /*
+ * The buffers that were written will now be uptodate, so we
+ * don't have to worry about a readpage reading them and
+ * overwriting a partial write. However if we have encountered
+ * a short write and only partially written into a buffer, it
+ * will not be marked uptodate, so a readpage might come in and
+ * destroy our partial write.
+ *
+ * Do the simplest thing, and just treat any short write to a
+ * non uptodate page as a zero-length write, and force the
+ * caller to redo the whole thing.
+ */
+ if (!PageUptodate(page))
+ copied = 0;
+
+ page_zero_new_buffers(page, start+copied, start+len);
+ }
+ flush_dcache_page(page);
+
+ /* This could be a short (even 0-length) commit */
+ __block_commit_write(inode, page, start, start+copied);
+
+ return copied;
+}
+EXPORT_SYMBOL(block_write_end);
+
+int generic_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+
+ copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+
+ /*
+ * No need to use i_size_read() here, the i_size
+ * cannot change under us because we hold i_mutex.
+ *
+ * But it's important to update i_size while still holding page lock:
+ * page writeout could otherwise come in and zero beyond i_size.
+ */
+ if (pos+copied > inode->i_size) {
+ i_size_write(inode, pos+copied);
+ mark_inode_dirty(inode);
+ }
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ return copied;
+}
+EXPORT_SYMBOL(generic_write_end);
+
+/*
* Generic "read page" function for block devices that have the normal
* get_block functionality. This is most of the block device filesystems.
* Reads the page asynchronously --- the unlock_buffer() and
@@ -2004,14 +2157,14 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
}
/* utility function for filesystems that need to do work on expanding
- * truncates. Uses prepare/commit_write to allow the filesystem to
+ * truncates. Uses filesystem pagecache writes to allow the filesystem to
* deal with the hole.
*/
-static int __generic_cont_expand(struct inode *inode, loff_t size,
- pgoff_t index, unsigned int offset)
+int generic_cont_expand_simple(struct inode *inode, loff_t size)
{
struct address_space *mapping = inode->i_mapping;
struct page *page;
+ void *fsdata;
unsigned long limit;
int err;
@@ -2024,140 +2177,115 @@ static int __generic_cont_expand(struct inode *inode, loff_t size,
if (size > inode->i_sb->s_maxbytes)
goto out;
- err = -ENOMEM;
- page = grab_cache_page(mapping, index);
- if (!page)
- goto out;
- err = mapping->a_ops->prepare_write(NULL, page, offset, offset);
- if (err) {
- /*
- * ->prepare_write() may have instantiated a few blocks
- * outside i_size. Trim these off again.
- */
- unlock_page(page);
- page_cache_release(page);
- vmtruncate(inode, inode->i_size);
+ err = pagecache_write_begin(NULL, mapping, size, 0,
+ AOP_FLAG_UNINTERRUPTIBLE|AOP_FLAG_CONT_EXPAND,
+ &page, &fsdata);
+ if (err)
goto out;
- }
- err = mapping->a_ops->commit_write(NULL, page, offset, offset);
+ err = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata);
+ BUG_ON(err > 0);
- unlock_page(page);
- page_cache_release(page);
- if (err > 0)
- err = 0;
out:
return err;
}
-int generic_cont_expand(struct inode *inode, loff_t size)
+int cont_expand_zero(struct file *file, struct address_space *mapping,
+ loff_t pos, loff_t *bytes)
{
- pgoff_t index;
- unsigned int offset;
+ struct inode *inode = mapping->host;
+ unsigned blocksize = 1 << inode->i_blkbits;
+ struct page *page;
+ void *fsdata;
+ pgoff_t index, curidx;
+ loff_t curpos;
+ unsigned zerofrom, offset, len;
+ int err = 0;
- offset = (size & (PAGE_CACHE_SIZE - 1)); /* Within page */
+ index = pos >> PAGE_CACHE_SHIFT;
+ offset = pos & ~PAGE_CACHE_MASK;
- /* ugh. in prepare/commit_write, if from==to==start of block, we
- ** skip the prepare. make sure we never send an offset for the start
- ** of a block
- */
- if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
- /* caller must handle this extra byte. */
- offset++;
- }
- index = size >> PAGE_CACHE_SHIFT;
+ while (index > (curidx = (curpos = *bytes)>>PAGE_CACHE_SHIFT)) {
+ zerofrom = curpos & ~PAGE_CACHE_MASK;
+ if (zerofrom & (blocksize-1)) {
+ *bytes |= (blocksize-1);
+ (*bytes)++;
+ }
+ len = PAGE_CACHE_SIZE - zerofrom;
- return __generic_cont_expand(inode, size, index, offset);
-}
+ err = pagecache_write_begin(file, mapping, curpos, len,
+ AOP_FLAG_UNINTERRUPTIBLE,
+ &page, &fsdata);
+ if (err)
+ goto out;
+ zero_user_page(page, zerofrom, len, KM_USER0);
+ err = pagecache_write_end(file, mapping, curpos, len, len,
+ page, fsdata);
+ if (err < 0)
+ goto out;
+ BUG_ON(err != len);
+ err = 0;
+ }
-int generic_cont_expand_simple(struct inode *inode, loff_t size)
-{
- loff_t pos = size - 1;
- pgoff_t index = pos >> PAGE_CACHE_SHIFT;
- unsigned int offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1;
+ /* page covers the boundary, find the boundary offset */
+ if (index == curidx) {
+ zerofrom = curpos & ~PAGE_CACHE_MASK;
+ /* if we will expand the thing last block will be filled */
+ if (offset <= zerofrom) {
+ goto out;
+ }
+ if (zerofrom & (blocksize-1)) {
+ *bytes |= (blocksize-1);
+ (*bytes)++;
+ }
+ len = offset - zerofrom;
- /* prepare/commit_write can handle even if from==to==start of block. */
- return __generic_cont_expand(inode, size, index, offset);
+ err = pagecache_write_begin(file, mapping, curpos, len,
+ AOP_FLAG_UNINTERRUPTIBLE,
+ &page, &fsdata);
+ if (err)
+ goto out;
+ zero_user_page(page, zerofrom, len, KM_USER0);
+ err = pagecache_write_end(file, mapping, curpos, len, len,
+ page, fsdata);
+ if (err < 0)
+ goto out;
+ BUG_ON(err != len);
+ err = 0;
+ }
+out:
+ return err;
}
/*
* For moronic filesystems that do not allow holes in file.
* We may have to extend the file.
*/
-
-int cont_prepare_write(struct page *page, unsigned offset,
- unsigned to, get_block_t *get_block, loff_t *bytes)
+int cont_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata,
+ get_block_t *get_block, loff_t *bytes)
{
- struct address_space *mapping = page->mapping;
struct inode *inode = mapping->host;
- struct page *new_page;
- pgoff_t pgpos;
- long status;
- unsigned zerofrom;
unsigned blocksize = 1 << inode->i_blkbits;
+ unsigned zerofrom;
+ int err;
- while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) {
- status = -ENOMEM;
- new_page = grab_cache_page(mapping, pgpos);
- if (!new_page)
- goto out;
- /* we might sleep */
- if (*bytes>>PAGE_CACHE_SHIFT != pgpos) {
- unlock_page(new_page);
- page_cache_release(new_page);
- continue;
- }
- zerofrom = *bytes & ~PAGE_CACHE_MASK;
- if (zerofrom & (blocksize-1)) {
- *bytes |= (blocksize-1);
- (*bytes)++;
- }
- status = __block_prepare_write(inode, new_page, zerofrom,
- PAGE_CACHE_SIZE, get_block);
- if (status)
- goto out_unmap;
- zero_user_page(new_page, zerofrom, PAGE_CACHE_SIZE - zerofrom,
- KM_USER0);
- generic_commit_write(NULL, new_page, zerofrom, PAGE_CACHE_SIZE);
- unlock_page(new_page);
- page_cache_release(new_page);
- }
-
- if (page->index < pgpos) {
- /* completely inside the area */
- zerofrom = offset;
- } else {
- /* page covers the boundary, find the boundary offset */
- zerofrom = *bytes & ~PAGE_CACHE_MASK;
-
- /* if we will expand the thing last block will be filled */
- if (to > zerofrom && (zerofrom & (blocksize-1))) {
- *bytes |= (blocksize-1);
- (*bytes)++;
- }
+ err = cont_expand_zero(file, mapping, pos, bytes);
+ if (err)
+ goto out;
- /* starting below the boundary? Nothing to zero out */
- if (offset <= zerofrom)
- zerofrom = offset;
- }
- status = __block_prepare_write(inode, page, zerofrom, to, get_block);
- if (status)
- goto out1;
- if (zerofrom < offset) {
- zero_user_page(page, zerofrom, offset - zerofrom, KM_USER0);
- __block_commit_write(inode, page, zerofrom, offset);
+ zerofrom = *bytes & ~PAGE_CACHE_MASK;
+ if (pos+len > *bytes && zerofrom & (blocksize-1)) {
+ *bytes |= (blocksize-1);
+ (*bytes)++;
}
- return 0;
-out1:
- ClearPageUptodate(page);
- return status;
-out_unmap:
- ClearPageUptodate(new_page);
- unlock_page(new_page);
- page_cache_release(new_page);
+ *pagep = NULL;
+ err = block_write_begin(file, mapping, pos, len,
+ flags, pagep, fsdata, get_block);
out:
- return status;
+ return err;
}
int block_prepare_write(struct page *page, unsigned from, unsigned to,
@@ -2242,81 +2370,129 @@ out_unlock:
}
/*
- * nobh_prepare_write()'s prereads are special: the buffer_heads are freed
+ * nobh_write_begin()'s prereads are special: the buffer_heads are freed
* immediately, while under the page lock. So it needs a special end_io
* handler which does not touch the bh after unlocking it.
- *
- * Note: unlock_buffer() sort-of does touch the bh after unlocking it, but
- * a race there is benign: unlock_buffer() only use the bh's address for
- * hashing after unlocking the buffer, so it doesn't actually touch the bh
- * itself.
*/
static void end_buffer_read_nobh(struct buffer_head *bh, int uptodate)
{
- if (uptodate) {
- set_buffer_uptodate(bh);
- } else {
- /* This happens, due to failed READA attempts. */
- clear_buffer_uptodate(bh);
- }
- unlock_buffer(bh);
+ __end_buffer_read_notouch(bh, uptodate);
+}
+
+/*
+ * Attach the singly-linked list of buffers created by nobh_write_begin, to
+ * the page (converting it to circular linked list and taking care of page
+ * dirty races).
+ */
+static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
+{
+ struct buffer_head *bh;
+
+ BUG_ON(!PageLocked(page));
+
+ spin_lock(&page->mapping->private_lock);
+ bh = head;
+ do {
+ if (PageDirty(page))
+ set_buffer_dirty(bh);
+ if (!bh->b_this_page)
+ bh->b_this_page = head;
+ bh = bh->b_this_page;
+ } while (bh != head);
+ attach_page_buffers(page, head);
+ spin_unlock(&page->mapping->private_lock);
}
/*
* On entry, the page is fully not uptodate.
* On exit the page is fully uptodate in the areas outside (from,to)
*/
-int nobh_prepare_write(struct page *page, unsigned from, unsigned to,
+int nobh_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata,
get_block_t *get_block)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = mapping->host;
const unsigned blkbits = inode->i_blkbits;
const unsigned blocksize = 1 << blkbits;
- struct buffer_head map_bh;
- struct buffer_head *read_bh[MAX_BUF_PER_PAGE];
+ struct buffer_head *head, *bh;
+ struct page *page;
+ pgoff_t index;
+ unsigned from, to;
unsigned block_in_page;
- unsigned block_start;
+ unsigned block_start, block_end;
sector_t block_in_file;
char *kaddr;
int nr_reads = 0;
- int i;
int ret = 0;
int is_mapped_to_disk = 1;
+ index = pos >> PAGE_CACHE_SHIFT;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
+
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+ *fsdata = NULL;
+
+ if (page_has_buffers(page)) {
+ unlock_page(page);
+ page_cache_release(page);
+ *pagep = NULL;
+ return block_write_begin(file, mapping, pos, len, flags, pagep,
+ fsdata, get_block);
+ }
+
if (PageMappedToDisk(page))
return 0;
+ /*
+ * Allocate buffers so that we can keep track of state, and potentially
+ * attach them to the page if an error occurs. In the common case of
+ * no error, they will just be freed again without ever being attached
+ * to the page (which is all OK, because we're under the page lock).
+ *
+ * Be careful: the buffer linked list is a NULL terminated one, rather
+ * than the circular one we're used to.
+ */
+ head = alloc_page_buffers(page, blocksize, 0);
+ if (!head) {
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
- map_bh.b_page = page;
/*
* We loop across all blocks in the page, whether or not they are
* part of the affected region. This is so we can discover if the
* page is fully mapped-to-disk.
*/
- for (block_start = 0, block_in_page = 0;
+ for (block_start = 0, block_in_page = 0, bh = head;
block_start < PAGE_CACHE_SIZE;
- block_in_page++, block_start += blocksize) {
- unsigned block_end = block_start + blocksize;
+ block_in_page++, block_start += blocksize, bh = bh->b_this_page) {
int create;
- map_bh.b_state = 0;
+ block_end = block_start + blocksize;
+ bh->b_state = 0;
create = 1;
if (block_start >= to)
create = 0;
- map_bh.b_size = blocksize;
ret = get_block(inode, block_in_file + block_in_page,
- &map_bh, create);
+ bh, create);
if (ret)
goto failed;
- if (!buffer_mapped(&map_bh))
+ if (!buffer_mapped(bh))
is_mapped_to_disk = 0;
- if (buffer_new(&map_bh))
- unmap_underlying_metadata(map_bh.b_bdev,
- map_bh.b_blocknr);
- if (PageUptodate(page))
+ if (buffer_new(bh))
+ unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
+ if (PageUptodate(page)) {
+ set_buffer_uptodate(bh);
continue;
- if (buffer_new(&map_bh) || !buffer_mapped(&map_bh)) {
+ }
+ if (buffer_new(bh) || !buffer_mapped(bh)) {
kaddr = kmap_atomic(page, KM_USER0);
if (block_start < from)
memset(kaddr+block_start, 0, from-block_start);
@@ -2326,49 +2502,26 @@ int nobh_prepare_write(struct page *page, unsigned from, unsigned to,
kunmap_atomic(kaddr, KM_USER0);
continue;
}
- if (buffer_uptodate(&map_bh))
+ if (buffer_uptodate(bh))
continue; /* reiserfs does this */
if (block_start < from || block_end > to) {
- struct buffer_head *bh = alloc_buffer_head(GFP_NOFS);
-
- if (!bh) {
- ret = -ENOMEM;
- goto failed;
- }
- bh->b_state = map_bh.b_state;
- atomic_set(&bh->b_count, 0);
- bh->b_this_page = NULL;
- bh->b_page = page;
- bh->b_blocknr = map_bh.b_blocknr;
- bh->b_size = blocksize;
- bh->b_data = (char *)(long)block_start;
- bh->b_bdev = map_bh.b_bdev;
- bh->b_private = NULL;
- read_bh[nr_reads++] = bh;
+ lock_buffer(bh);
+ bh->b_end_io = end_buffer_read_nobh;
+ submit_bh(READ, bh);
+ nr_reads++;
}
}
if (nr_reads) {
- struct buffer_head *bh;
-
/*
* The page is locked, so these buffers are protected from
* any VM or truncate activity. Hence we don't need to care
* for the buffer_head refcounts.
*/
- for (i = 0; i < nr_reads; i++) {
- bh = read_bh[i];
- lock_buffer(bh);
- bh->b_end_io = end_buffer_read_nobh;
- submit_bh(READ, bh);
- }
- for (i = 0; i < nr_reads; i++) {
- bh = read_bh[i];
+ for (bh = head; bh; bh = bh->b_this_page) {
wait_on_buffer(bh);
if (!buffer_uptodate(bh))
ret = -EIO;
- free_buffer_head(bh);
- read_bh[i] = NULL;
}
if (ret)
goto failed;
@@ -2377,44 +2530,70 @@ int nobh_prepare_write(struct page *page, unsigned from, unsigned to,
if (is_mapped_to_disk)
SetPageMappedToDisk(page);
+ *fsdata = head; /* to be released by nobh_write_end */
+
return 0;
failed:
- for (i = 0; i < nr_reads; i++) {
- if (read_bh[i])
- free_buffer_head(read_bh[i]);
- }
-
+ BUG_ON(!ret);
/*
- * Error recovery is pretty slack. Clear the page and mark it dirty
- * so we'll later zero out any blocks which _were_ allocated.
+ * Error recovery is a bit difficult. We need to zero out blocks that
+ * were newly allocated, and dirty them to ensure they get written out.
+ * Buffers need to be attached to the page at this point, otherwise
+ * the handling of potential IO errors during writeout would be hard
+ * (could try doing synchronous writeout, but what if that fails too?)
*/
- zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0);
- SetPageUptodate(page);
- set_page_dirty(page);
+ attach_nobh_buffers(page, head);
+ page_zero_new_buffers(page, from, to);
+
+out_release:
+ unlock_page(page);
+ page_cache_release(page);
+ *pagep = NULL;
+
+ if (pos + len > inode->i_size)
+ vmtruncate(inode, inode->i_size);
+
return ret;
}
-EXPORT_SYMBOL(nobh_prepare_write);
+EXPORT_SYMBOL(nobh_write_begin);
-/*
- * Make sure any changes to nobh_commit_write() are reflected in
- * nobh_truncate_page(), since it doesn't call commit_write().
- */
-int nobh_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+int nobh_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
struct inode *inode = page->mapping->host;
- loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ struct buffer_head *head = NULL;
+ struct buffer_head *bh;
+
+ if (!PageMappedToDisk(page)) {
+ if (unlikely(copied < len) && !page_has_buffers(page))
+ attach_nobh_buffers(page, head);
+ if (page_has_buffers(page))
+ return generic_write_end(file, mapping, pos, len,
+ copied, page, fsdata);
+ }
SetPageUptodate(page);
set_page_dirty(page);
- if (pos > inode->i_size) {
- i_size_write(inode, pos);
+ if (pos+copied > inode->i_size) {
+ i_size_write(inode, pos+copied);
mark_inode_dirty(inode);
}
- return 0;
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ head = fsdata;
+ while (head) {
+ bh = head;
+ head = head->b_this_page;
+ free_buffer_head(bh);
+ }
+
+ return copied;
}
-EXPORT_SYMBOL(nobh_commit_write);
+EXPORT_SYMBOL(nobh_write_end);
/*
* nobh_writepage() - based on block_full_write_page() except
@@ -2467,44 +2646,79 @@ out:
}
EXPORT_SYMBOL(nobh_writepage);
-/*
- * This function assumes that ->prepare_write() uses nobh_prepare_write().
- */
-int nobh_truncate_page(struct address_space *mapping, loff_t from)
+int nobh_truncate_page(struct address_space *mapping,
+ loff_t from, get_block_t *get_block)
{
- struct inode *inode = mapping->host;
- unsigned blocksize = 1 << inode->i_blkbits;
pgoff_t index = from >> PAGE_CACHE_SHIFT;
unsigned offset = from & (PAGE_CACHE_SIZE-1);
- unsigned to;
+ unsigned blocksize;
+ sector_t iblock;
+ unsigned length, pos;
+ struct inode *inode = mapping->host;
struct page *page;
- const struct address_space_operations *a_ops = mapping->a_ops;
- int ret = 0;
+ struct buffer_head map_bh;
+ int err;
- if ((offset & (blocksize - 1)) == 0)
- goto out;
+ blocksize = 1 << inode->i_blkbits;
+ length = offset & (blocksize - 1);
+
+ /* Block boundary? Nothing to do */
+ if (!length)
+ return 0;
+
+ length = blocksize - length;
+ iblock = (sector_t)index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
- ret = -ENOMEM;
page = grab_cache_page(mapping, index);
+ err = -ENOMEM;
if (!page)
goto out;
- to = (offset + blocksize) & ~(blocksize - 1);
- ret = a_ops->prepare_write(NULL, page, offset, to);
- if (ret == 0) {
- zero_user_page(page, offset, PAGE_CACHE_SIZE - offset,
- KM_USER0);
- /*
- * It would be more correct to call aops->commit_write()
- * here, but this is more efficient.
- */
- SetPageUptodate(page);
- set_page_dirty(page);
+ if (page_has_buffers(page)) {
+has_buffers:
+ unlock_page(page);
+ page_cache_release(page);
+ return block_truncate_page(mapping, from, get_block);
}
+
+ /* Find the buffer that contains "offset" */
+ pos = blocksize;
+ while (offset >= pos) {
+ iblock++;
+ pos += blocksize;
+ }
+
+ err = get_block(inode, iblock, &map_bh, 0);
+ if (err)
+ goto unlock;
+ /* unmapped? It's a hole - nothing to do */
+ if (!buffer_mapped(&map_bh))
+ goto unlock;
+
+ /* Ok, it's mapped. Make sure it's up-to-date */
+ if (!PageUptodate(page)) {
+ err = mapping->a_ops->readpage(NULL, page);
+ if (err) {
+ page_cache_release(page);
+ goto out;
+ }
+ lock_page(page);
+ if (!PageUptodate(page)) {
+ err = -EIO;
+ goto unlock;
+ }
+ if (page_has_buffers(page))
+ goto has_buffers;
+ }
+ zero_user_page(page, offset, length, KM_USER0);
+ set_page_dirty(page);
+ err = 0;
+
+unlock:
unlock_page(page);
page_cache_release(page);
out:
- return ret;
+ return err;
}
EXPORT_SYMBOL(nobh_truncate_page);
@@ -2956,7 +3170,8 @@ static void recalc_bh_state(void)
struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
{
- struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
+ struct buffer_head *ret = kmem_cache_zalloc(bh_cachep,
+ set_migrateflags(gfp_flags, __GFP_RECLAIMABLE));
if (ret) {
INIT_LIST_HEAD(&ret->b_assoc_buffers);
get_cpu_var(bh_accounting).nr++;
@@ -3024,14 +3239,13 @@ EXPORT_SYMBOL(block_read_full_page);
EXPORT_SYMBOL(block_sync_page);
EXPORT_SYMBOL(block_truncate_page);
EXPORT_SYMBOL(block_write_full_page);
-EXPORT_SYMBOL(cont_prepare_write);
+EXPORT_SYMBOL(cont_write_begin);
EXPORT_SYMBOL(end_buffer_read_sync);
EXPORT_SYMBOL(end_buffer_write_sync);
EXPORT_SYMBOL(file_fsync);
EXPORT_SYMBOL(fsync_bdev);
EXPORT_SYMBOL(generic_block_bmap);
EXPORT_SYMBOL(generic_commit_write);
-EXPORT_SYMBOL(generic_cont_expand);
EXPORT_SYMBOL(generic_cont_expand_simple);
EXPORT_SYMBOL(init_buffer);
EXPORT_SYMBOL(invalidate_bdev);
diff --git a/fs/char_dev.c b/fs/char_dev.c
index bbbf07baa14..c3bfa76765c 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -545,6 +545,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
void __init chrdev_init(void)
{
cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
+ bdi_init(&directly_mappable_cdev_bdi);
}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index cabb6a55d7d..ba8f7868cb2 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -704,7 +704,7 @@ const struct file_operations cifs_dir_ops = {
};
static void
-cifs_init_once(void *inode, struct kmem_cache *cachep, unsigned long flags)
+cifs_init_once(struct kmem_cache *cachep, void *inode)
{
struct cifsInodeInfo *cifsi = inode;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index dd4167762a8..279f3c5e0ce 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1538,6 +1538,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
}
time_buf.Attributes = 0;
+
+ /* skip mode change if it's just for clearing setuid/setgid */
+ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+ attrs->ia_valid &= ~ATTR_MODE;
+
if (attrs->ia_valid & ATTR_MODE) {
cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
mode = attrs->ia_mode;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 342f4e0d582..2f58dfc7008 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -58,7 +58,7 @@ static void coda_destroy_inode(struct inode *inode)
kmem_cache_free(coda_inode_cachep, ITOC(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct coda_inode_info *ei = (struct coda_inode_info *) foo;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 9c3fd07f35e..a4284ccac1f 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -108,7 +108,6 @@
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/video.h>
-#include <linux/lp.h>
#ifdef CONFIG_SPARC
#include <asm/fbio.h>
@@ -3002,7 +3001,7 @@ static int __init init_sys32_ioctl(void)
int i;
for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
- if (ioctl_start[i].next != 0) {
+ if (ioctl_start[i].next) {
printk("ioctl translation %d bad\n",i);
return -1;
}
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
index 3b0185fdf9a..cca98609aa7 100644
--- a/fs/configfs/configfs_internal.h
+++ b/fs/configfs/configfs_internal.h
@@ -56,6 +56,8 @@ extern int configfs_is_root(struct config_item *item);
extern struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent *);
extern int configfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+extern int configfs_inode_init(void);
+extern void configfs_inode_exit(void);
extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
extern int configfs_make_dirent(struct configfs_dirent *,
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 2f436d4f1d6..50ed691098b 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -142,7 +142,7 @@ static int init_dir(struct inode * inode)
return 0;
}
-static int init_file(struct inode * inode)
+static int configfs_init_file(struct inode * inode)
{
inode->i_size = PAGE_SIZE;
inode->i_fop = &configfs_file_operations;
@@ -283,7 +283,8 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den
dentry->d_fsdata = configfs_get(sd);
sd->s_dentry = dentry;
- error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file);
+ error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG,
+ configfs_init_file);
if (error) {
configfs_put(sd);
return error;
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index ddc003a9d21..4c1ebff778e 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -41,8 +41,8 @@ extern struct super_block * configfs_sb;
static const struct address_space_operations configfs_aops = {
.readpage = simple_readpage,
- .prepare_write = simple_prepare_write,
- .commit_write = simple_commit_write
+ .write_begin = simple_write_begin,
+ .write_end = simple_write_end,
};
static struct backing_dev_info configfs_backing_dev_info = {
@@ -256,4 +256,12 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
mutex_unlock(&dir->d_inode->i_mutex);
}
+int __init configfs_inode_init(void)
+{
+ return bdi_init(&configfs_backing_dev_info);
+}
+void __exit configfs_inode_exit(void)
+{
+ bdi_destroy(&configfs_backing_dev_info);
+}
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index 871b0cb6183..3bf0278ea84 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -154,8 +154,16 @@ static int __init configfs_init(void)
subsystem_unregister(&config_subsys);
kmem_cache_destroy(configfs_dir_cachep);
configfs_dir_cachep = NULL;
+ goto out;
}
+ err = configfs_inode_init();
+ if (err) {
+ unregister_filesystem(&configfs_fs_type);
+ subsystem_unregister(&config_subsys);
+ kmem_cache_destroy(configfs_dir_cachep);
+ configfs_dir_cachep = NULL;
+ }
out:
return err;
}
@@ -166,6 +174,7 @@ static void __exit configfs_exit(void)
subsystem_unregister(&config_subsys);
kmem_cache_destroy(configfs_dir_cachep);
configfs_dir_cachep = NULL;
+ configfs_inode_exit();
}
MODULE_AUTHOR("Oracle");
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 3d194a2be3f..350680fd7da 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -148,7 +148,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
{
struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
struct page *pages[BLKS_PER_BUF];
- unsigned i, blocknr, buffer, unread;
+ unsigned i, blocknr, buffer;
unsigned long devsize;
char *data;
@@ -175,7 +175,6 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT;
/* Ok, read in BLKS_PER_BUF pages completely first. */
- unread = 0;
for (i = 0; i < BLKS_PER_BUF; i++) {
struct page *page = NULL;
@@ -258,12 +257,21 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
/* Do sanity checks on the superblock */
if (super.magic != CRAMFS_MAGIC) {
+ /* check for wrong endianess */
+ if (super.magic == CRAMFS_MAGIC_WEND) {
+ if (!silent)
+ printk(KERN_ERR "cramfs: wrong endianess\n");
+ goto out;
+ }
+
/* check at 512 byte offset */
mutex_lock(&read_mutex);
memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
mutex_unlock(&read_mutex);
if (super.magic != CRAMFS_MAGIC) {
- if (!silent)
+ if (super.magic == CRAMFS_MAGIC_WEND && !silent)
+ printk(KERN_ERR "cramfs: wrong endianess\n");
+ else if (!silent)
printk(KERN_ERR "cramfs: wrong magic\n");
goto out;
}
@@ -353,7 +361,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (offset & 3)
return -EINVAL;
- buf = kmalloc(256, GFP_KERNEL);
+ buf = kmalloc(CRAMFS_MAXPATHLEN, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -367,7 +375,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int namelen, error;
mutex_lock(&read_mutex);
- de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256);
+ de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
name = (char *)(de+1);
/*
@@ -417,7 +425,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s
char *name;
int namelen, retval;
- de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
+ de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
name = (char *)(de+1);
/* Try to take advantage of sorted directories */
diff --git a/fs/dcache.c b/fs/dcache.c
index 678d39deb60..5489b2d98a0 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -381,20 +381,17 @@ restart:
* Throw away a dentry - free the inode, dput the parent. This requires that
* the LRU list has already been removed.
*
- * If prune_parents is true, try to prune ancestors as well.
+ * Try to prune ancestors as well. This is necessary to prevent
+ * quadratic behavior of shrink_dcache_parent(), but is also expected
+ * to be beneficial in reducing dentry cache fragmentation.
*
* Called with dcache_lock, drops it and then regains.
* Called with dentry->d_lock held, drops it.
*/
-static void prune_one_dentry(struct dentry * dentry, int prune_parents)
+static void prune_one_dentry(struct dentry * dentry)
{
__d_drop(dentry);
dentry = d_kill(dentry);
- if (!prune_parents) {
- dput(dentry);
- spin_lock(&dcache_lock);
- return;
- }
/*
* Prune ancestors. Locking is simpler than in dput(),
@@ -422,7 +419,6 @@ static void prune_one_dentry(struct dentry * dentry, int prune_parents)
* @count: number of entries to try and free
* @sb: if given, ignore dentries for other superblocks
* which are being unmounted.
- * @prune_parents: if true, try to prune ancestors as well in one go
*
* Shrink the dcache. This is done when we need
* more memory, or simply when we need to unmount
@@ -433,7 +429,7 @@ static void prune_one_dentry(struct dentry * dentry, int prune_parents)
* all the dentries are in use.
*/
-static void prune_dcache(int count, struct super_block *sb, int prune_parents)
+static void prune_dcache(int count, struct super_block *sb)
{
spin_lock(&dcache_lock);
for (; count ; count--) {
@@ -493,7 +489,7 @@ static void prune_dcache(int count, struct super_block *sb, int prune_parents)
* without taking the s_umount lock (I already hold it).
*/
if (sb && dentry->d_sb == sb) {
- prune_one_dentry(dentry, prune_parents);
+ prune_one_dentry(dentry);
continue;
}
/*
@@ -508,7 +504,7 @@ static void prune_dcache(int count, struct super_block *sb, int prune_parents)
s_umount = &dentry->d_sb->s_umount;
if (down_read_trylock(s_umount)) {
if (dentry->d_sb->s_root != NULL) {
- prune_one_dentry(dentry, prune_parents);
+ prune_one_dentry(dentry);
up_read(s_umount);
continue;
}
@@ -557,18 +553,18 @@ void shrink_dcache_sb(struct super_block * sb)
* superblock to the most recent end of the unused list.
*/
spin_lock(&dcache_lock);
- list_for_each_safe(tmp, next, &dentry_unused) {
+ list_for_each_prev_safe(tmp, next, &dentry_unused) {
dentry = list_entry(tmp, struct dentry, d_lru);
if (dentry->d_sb != sb)
continue;
- list_move(tmp, &dentry_unused);
+ list_move_tail(tmp, &dentry_unused);
}
/*
* Pass two ... free the dentries for this superblock.
*/
repeat:
- list_for_each_safe(tmp, next, &dentry_unused) {
+ list_for_each_prev_safe(tmp, next, &dentry_unused) {
dentry = list_entry(tmp, struct dentry, d_lru);
if (dentry->d_sb != sb)
continue;
@@ -579,7 +575,7 @@ repeat:
spin_unlock(&dentry->d_lock);
continue;
}
- prune_one_dentry(dentry, 1);
+ prune_one_dentry(dentry);
cond_resched_lock(&dcache_lock);
goto repeat;
}
@@ -858,7 +854,7 @@ void shrink_dcache_parent(struct dentry * parent)
int found;
while ((found = select_parent(parent)) != 0)
- prune_dcache(found, parent->d_sb, 1);
+ prune_dcache(found, parent->d_sb);
}
/*
@@ -878,7 +874,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
if (nr) {
if (!(gfp_mask & __GFP_FS))
return -1;
- prune_dcache(nr, NULL, 1);
+ prune_dcache(nr, NULL);
}
return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
@@ -903,7 +899,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
struct dentry *dentry;
char *dname;
- dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
+ dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
if (!dentry)
return NULL;
@@ -1514,8 +1510,8 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
* This forceful removal will result in ugly /proc output if
* somebody holds a file open that got deleted due to a rename.
* We could be nicer about the deleted file, and let it show
- * up under the name it got deleted rather than the name that
- * deleted it.
+ * up under the name it had before it was deleted rather than
+ * under the original name of the file that was moved on top of it.
*/
/*
@@ -1546,7 +1542,7 @@ static void d_move_locked(struct dentry * dentry, struct dentry * target)
}
/* Move the dentry to the target hash queue, if on different bucket */
- if (dentry->d_flags & DCACHE_UNHASHED)
+ if (d_unhashed(dentry))
goto already_unhashed;
hlist_del_rcu(&dentry->d_hash);
@@ -2108,7 +2104,7 @@ static void __init dcache_init_early(void)
INIT_HLIST_HEAD(&dentry_hashtable[loop]);
}
-static void __init dcache_init(unsigned long mempages)
+static void __init dcache_init(void)
{
int loop;
@@ -2170,10 +2166,10 @@ void __init vfs_caches_init(unsigned long mempages)
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
- dcache_init(mempages);
- inode_init(mempages);
+ dcache_init();
+ inode_init();
files_init(mempages);
- mnt_init(mempages);
+ mnt_init();
bdev_cache_init();
chrdev_init();
}
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index a9b99c0dc2e..fa6b7f7ff91 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -227,15 +227,24 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n"
DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n");
-/**
- * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
- * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
- * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
+/*
+ * debugfs_create_x{8,16,32} - create a debugfs file that is used to read and write an unsigned {8,16,32}-bit value
*
- * These functions are exactly the same as the above functions, (but use a hex
- * output for the decimal challenged) for details look at the above unsigned
+ * These functions are exactly the same as the above functions (but use a hex
+ * output for the decimal challenged). For details look at the above unsigned
* decimal functions.
*/
+
+/**
+ * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is %NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ */
struct dentry *debugfs_create_x8(const char *name, mode_t mode,
struct dentry *parent, u8 *value)
{
@@ -243,6 +252,16 @@ struct dentry *debugfs_create_x8(const char *name, mode_t mode,
}
EXPORT_SYMBOL_GPL(debugfs_create_x8);
+/**
+ * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is %NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ */
struct dentry *debugfs_create_x16(const char *name, mode_t mode,
struct dentry *parent, u16 *value)
{
@@ -250,6 +269,16 @@ struct dentry *debugfs_create_x16(const char *name, mode_t mode,
}
EXPORT_SYMBOL_GPL(debugfs_create_x16);
+/**
+ * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this parameter is %NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @value: a pointer to the variable that the file should read to and write
+ * from.
+ */
struct dentry *debugfs_create_x32(const char *name, mode_t mode,
struct dentry *parent, u32 *value)
{
diff --git a/fs/direct-io.c b/fs/direct-io.c
index b5928a7b6a5..acf0da1bd25 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -163,7 +163,7 @@ static int dio_refill_pages(struct dio *dio)
up_read(&current->mm->mmap_sem);
if (ret < 0 && dio->blocks_available && (dio->rw & WRITE)) {
- struct page *page = ZERO_PAGE(dio->curr_user_address);
+ struct page *page = ZERO_PAGE(0);
/*
* A memory fault, but the filesystem has some outstanding
* mapped blocks. We need to use those blocks up to avoid
@@ -763,7 +763,7 @@ static void dio_zero_block(struct dio *dio, int end)
this_chunk_bytes = this_chunk_blocks << dio->blkbits;
- page = ZERO_PAGE(dio->curr_user_address);
+ page = ZERO_PAGE(0);
if (submit_page_section(dio, page, 0, this_chunk_bytes,
dio->next_block_for_io))
return;
diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig
index 54bcc00ec8d..2dbb422e811 100644
--- a/fs/dlm/Kconfig
+++ b/fs/dlm/Kconfig
@@ -1,8 +1,6 @@
-menu "Distributed Lock Manager"
- depends on EXPERIMENTAL && INET
-
-config DLM
+menuconfig DLM
tristate "Distributed Lock Manager (DLM)"
+ depends on EXPERIMENTAL && INET
depends on SYSFS && (IPV6 || IPV6=n)
select CONFIGFS_FS
select IP_SCTP
@@ -17,5 +15,3 @@ config DLM_DEBUG
Under the debugfs mount point, the name of each lockspace will
appear as a file in the "dlm" directory. The output is the
list of resource and locks the local node knows about.
-
-endmenu
diff --git a/fs/dquot.c b/fs/dquot.c
index de9a29f64ff..2809768d9c4 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -79,6 +79,10 @@
#include <linux/capability.h>
#include <linux/quotaops.h>
#include <linux/writeback.h> /* for inode_lock, oddly enough.. */
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#endif
#include <asm/uaccess.h>
@@ -823,6 +827,7 @@ static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
clear_bit(DQ_BLKS_B, &dquot->dq_flags);
}
+#ifdef CONFIG_PRINT_QUOTA_WARNING
static int flag_print_warnings = 1;
static inline int need_print_warning(struct dquot *dquot)
@@ -839,22 +844,15 @@ static inline int need_print_warning(struct dquot *dquot)
return 0;
}
-/* Values of warnings */
-#define NOWARN 0
-#define IHARDWARN 1
-#define ISOFTLONGWARN 2
-#define ISOFTWARN 3
-#define BHARDWARN 4
-#define BSOFTLONGWARN 5
-#define BSOFTWARN 6
-
/* Print warning to user which exceeded quota */
static void print_warning(struct dquot *dquot, const char warntype)
{
char *msg = NULL;
struct tty_struct *tty;
- int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS_B :
- ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES_B : 0);
+ int flag = (warntype == QUOTA_NL_BHARDWARN ||
+ warntype == QUOTA_NL_BSOFTLONGWARN) ? DQ_BLKS_B :
+ ((warntype == QUOTA_NL_IHARDWARN ||
+ warntype == QUOTA_NL_ISOFTLONGWARN) ? DQ_INODES_B : 0);
if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
return;
@@ -864,28 +862,28 @@ static void print_warning(struct dquot *dquot, const char warntype)
if (!tty)
goto out_lock;
tty_write_message(tty, dquot->dq_sb->s_id);
- if (warntype == ISOFTWARN || warntype == BSOFTWARN)
+ if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
tty_write_message(tty, ": warning, ");
else
tty_write_message(tty, ": write failed, ");
tty_write_message(tty, quotatypes[dquot->dq_type]);
switch (warntype) {
- case IHARDWARN:
+ case QUOTA_NL_IHARDWARN:
msg = " file limit reached.\r\n";
break;
- case ISOFTLONGWARN:
+ case QUOTA_NL_ISOFTLONGWARN:
msg = " file quota exceeded too long.\r\n";
break;
- case ISOFTWARN:
+ case QUOTA_NL_ISOFTWARN:
msg = " file quota exceeded.\r\n";
break;
- case BHARDWARN:
+ case QUOTA_NL_BHARDWARN:
msg = " block limit reached.\r\n";
break;
- case BSOFTLONGWARN:
+ case QUOTA_NL_BSOFTLONGWARN:
msg = " block quota exceeded too long.\r\n";
break;
- case BSOFTWARN:
+ case QUOTA_NL_BSOFTWARN:
msg = " block quota exceeded.\r\n";
break;
}
@@ -893,14 +891,93 @@ static void print_warning(struct dquot *dquot, const char warntype)
out_lock:
mutex_unlock(&tty_mutex);
}
+#endif
+
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+
+/* Size of quota netlink message - actually an upperbound for buffer size */
+#define QUOTA_NL_MSG_SIZE 32
+
+/* Netlink family structure for quota */
+static struct genl_family quota_genl_family = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = "VFS_DQUOT",
+ .version = 1,
+ .maxattr = QUOTA_NL_A_MAX,
+};
+
+/* Send warning to userspace about user which exceeded quota */
+static void send_warning(const struct dquot *dquot, const char warntype)
+{
+ static atomic_t seq;
+ struct sk_buff *skb;
+ void *msg_head;
+ int ret;
+
+ /* We have to allocate using GFP_NOFS as we are called from a
+ * filesystem performing write and thus further recursion into
+ * the fs to free some data could cause deadlocks. */
+ skb = genlmsg_new(QUOTA_NL_MSG_SIZE, GFP_NOFS);
+ if (!skb) {
+ printk(KERN_ERR
+ "VFS: Not enough memory to send quota warning.\n");
+ return;
+ }
+ msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
+ &quota_genl_family, 0, QUOTA_NL_C_WARNING);
+ if (!msg_head) {
+ printk(KERN_ERR
+ "VFS: Cannot store netlink header in quota warning.\n");
+ goto err_out;
+ }
+ ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, dquot->dq_type);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, dquot->dq_id);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR,
+ MAJOR(dquot->dq_sb->s_dev));
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR,
+ MINOR(dquot->dq_sb->s_dev));
+ if (ret)
+ goto attr_err_out;
+ ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current->user->uid);
+ if (ret)
+ goto attr_err_out;
+ genlmsg_end(skb, msg_head);
+
+ ret = genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
+ if (ret < 0 && ret != -ESRCH)
+ printk(KERN_ERR
+ "VFS: Failed to send notification message: %d\n", ret);
+ return;
+attr_err_out:
+ printk(KERN_ERR "VFS: Failed to compose quota message: %d\n", ret);
+err_out:
+ kfree_skb(skb);
+}
+#endif
static inline void flush_warnings(struct dquot **dquots, char *warntype)
{
int i;
for (i = 0; i < MAXQUOTAS; i++)
- if (dquots[i] != NODQUOT && warntype[i] != NOWARN)
+ if (dquots[i] != NODQUOT && warntype[i] != QUOTA_NL_NOWARN) {
+#ifdef CONFIG_PRINT_QUOTA_WARNING
print_warning(dquots[i], warntype[i]);
+#endif
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+ send_warning(dquots[i], warntype[i]);
+#endif
+ }
}
static inline char ignore_hardlimit(struct dquot *dquot)
@@ -914,14 +991,14 @@ static inline char ignore_hardlimit(struct dquot *dquot)
/* needs dq_data_lock */
static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
{
- *warntype = NOWARN;
+ *warntype = QUOTA_NL_NOWARN;
if (inodes <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags))
return QUOTA_OK;
if (dquot->dq_dqb.dqb_ihardlimit &&
(dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit &&
!ignore_hardlimit(dquot)) {
- *warntype = IHARDWARN;
+ *warntype = QUOTA_NL_IHARDWARN;
return NO_QUOTA;
}
@@ -929,14 +1006,14 @@ static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
(dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
dquot->dq_dqb.dqb_itime && get_seconds() >= dquot->dq_dqb.dqb_itime &&
!ignore_hardlimit(dquot)) {
- *warntype = ISOFTLONGWARN;
+ *warntype = QUOTA_NL_ISOFTLONGWARN;
return NO_QUOTA;
}
if (dquot->dq_dqb.dqb_isoftlimit &&
(dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
dquot->dq_dqb.dqb_itime == 0) {
- *warntype = ISOFTWARN;
+ *warntype = QUOTA_NL_ISOFTWARN;
dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
}
@@ -946,7 +1023,7 @@ static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
/* needs dq_data_lock */
static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
{
- *warntype = 0;
+ *warntype = QUOTA_NL_NOWARN;
if (space <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags))
return QUOTA_OK;
@@ -954,7 +1031,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit &&
!ignore_hardlimit(dquot)) {
if (!prealloc)
- *warntype = BHARDWARN;
+ *warntype = QUOTA_NL_BHARDWARN;
return NO_QUOTA;
}
@@ -963,7 +1040,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
!ignore_hardlimit(dquot)) {
if (!prealloc)
- *warntype = BSOFTLONGWARN;
+ *warntype = QUOTA_NL_BSOFTLONGWARN;
return NO_QUOTA;
}
@@ -971,7 +1048,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
dquot->dq_dqb.dqb_btime == 0) {
if (!prealloc) {
- *warntype = BSOFTWARN;
+ *warntype = QUOTA_NL_BSOFTWARN;
dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
}
else
@@ -1066,7 +1143,7 @@ out_add:
return QUOTA_OK;
}
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
- warntype[cnt] = NOWARN;
+ warntype[cnt] = QUOTA_NL_NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */
@@ -1112,7 +1189,7 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
if (IS_NOQUOTA(inode))
return QUOTA_OK;
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
- warntype[cnt] = NOWARN;
+ warntype[cnt] = QUOTA_NL_NOWARN;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
if (IS_NOQUOTA(inode)) {
up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1234,7 +1311,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
/* Clear the arrays */
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
- warntype[cnt] = NOWARN;
+ warntype[cnt] = QUOTA_NL_NOWARN;
}
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
/* Now recheck reliably when holding dqptr_sem */
@@ -1808,6 +1885,7 @@ static ctl_table fs_dqstats_table[] = {
.mode = 0444,
.proc_handler = &proc_dointvec,
},
+#ifdef CONFIG_PRINT_QUOTA_WARNING
{
.ctl_name = FS_DQ_WARNINGS,
.procname = "warnings",
@@ -1816,6 +1894,7 @@ static ctl_table fs_dqstats_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+#endif
{ .ctl_name = 0 },
};
@@ -1877,6 +1956,11 @@ static int __init dquot_init(void)
register_shrinker(&dqcache_shrinker);
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+ if (genl_register_family(&quota_genl_family) != 0)
+ printk(KERN_ERR "VFS: Failed to create quota netlink interface.\n");
+#endif
+
return 0;
}
module_init(dquot_init);
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile
index 1f1107237ea..76885701551 100644
--- a/fs/ecryptfs/Makefile
+++ b/fs/ecryptfs/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
-ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o messaging.o netlink.o debug.o
+ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o debug.o
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 6ac630625b7..1ae90ef2c74 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -123,9 +123,9 @@ out:
return rc;
}
-int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
- char *cipher_name,
- char *chaining_modifier)
+static int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
+ char *cipher_name,
+ char *chaining_modifier)
{
int cipher_name_len = strlen(cipher_name);
int chaining_modifier_len = strlen(chaining_modifier);
@@ -149,7 +149,7 @@ out:
* ecryptfs_derive_iv
* @iv: destination for the derived iv vale
* @crypt_stat: Pointer to crypt_stat struct for the current inode
- * @offset: Offset of the page whose's iv we are to derive
+ * @offset: Offset of the extent whose IV we are to derive
*
* Generate the initialization vector from the given root IV and page
* offset.
@@ -157,7 +157,7 @@ out:
* Returns zero on success; non-zero on error.
*/
static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
- pgoff_t offset)
+ loff_t offset)
{
int rc = 0;
char dst[MD5_DIGEST_SIZE];
@@ -173,7 +173,7 @@ static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
* hashing business. -Halcrow */
memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes);
memset((src + crypt_stat->iv_bytes), 0, 16);
- snprintf((src + crypt_stat->iv_bytes), 16, "%ld", offset);
+ snprintf((src + crypt_stat->iv_bytes), 16, "%lld", offset);
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(KERN_DEBUG, "source:\n");
ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16));
@@ -204,6 +204,8 @@ void
ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
{
memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
+ INIT_LIST_HEAD(&crypt_stat->keysig_list);
+ mutex_init(&crypt_stat->keysig_list_mutex);
mutex_init(&crypt_stat->cs_mutex);
mutex_init(&crypt_stat->cs_tfm_mutex);
mutex_init(&crypt_stat->cs_hash_tfm_mutex);
@@ -211,27 +213,48 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
}
/**
- * ecryptfs_destruct_crypt_stat
+ * ecryptfs_destroy_crypt_stat
* @crypt_stat: Pointer to the crypt_stat struct to initialize.
*
* Releases all memory associated with a crypt_stat struct.
*/
-void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
+void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
{
+ struct ecryptfs_key_sig *key_sig, *key_sig_tmp;
+
if (crypt_stat->tfm)
crypto_free_blkcipher(crypt_stat->tfm);
if (crypt_stat->hash_tfm)
crypto_free_hash(crypt_stat->hash_tfm);
+ mutex_lock(&crypt_stat->keysig_list_mutex);
+ list_for_each_entry_safe(key_sig, key_sig_tmp,
+ &crypt_stat->keysig_list, crypt_stat_list) {
+ list_del(&key_sig->crypt_stat_list);
+ kmem_cache_free(ecryptfs_key_sig_cache, key_sig);
+ }
+ mutex_unlock(&crypt_stat->keysig_list_mutex);
memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
}
-void ecryptfs_destruct_mount_crypt_stat(
+void ecryptfs_destroy_mount_crypt_stat(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
- if (mount_crypt_stat->global_auth_tok_key)
- key_put(mount_crypt_stat->global_auth_tok_key);
- if (mount_crypt_stat->global_key_tfm)
- crypto_free_blkcipher(mount_crypt_stat->global_key_tfm);
+ struct ecryptfs_global_auth_tok *auth_tok, *auth_tok_tmp;
+
+ if (!(mount_crypt_stat->flags & ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED))
+ return;
+ mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
+ list_for_each_entry_safe(auth_tok, auth_tok_tmp,
+ &mount_crypt_stat->global_auth_tok_list,
+ mount_crypt_stat_list) {
+ list_del(&auth_tok->mount_crypt_stat_list);
+ mount_crypt_stat->num_global_auth_toks--;
+ if (auth_tok->global_auth_tok_key
+ && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID))
+ key_put(auth_tok->global_auth_tok_key);
+ kmem_cache_free(ecryptfs_global_auth_tok_cache, auth_tok);
+ }
+ mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
}
@@ -330,114 +353,82 @@ out:
return rc;
}
-static void
-ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx,
- int *byte_offset,
- struct ecryptfs_crypt_stat *crypt_stat,
- unsigned long extent_num)
+/**
+ * ecryptfs_lower_offset_for_extent
+ *
+ * Convert an eCryptfs page index into a lower byte offset
+ */
+void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
+ struct ecryptfs_crypt_stat *crypt_stat)
{
- unsigned long lower_extent_num;
- int extents_occupied_by_headers_at_front;
- int bytes_occupied_by_headers_at_front;
- int extent_offset;
- int extents_per_page;
-
- bytes_occupied_by_headers_at_front =
- ( crypt_stat->header_extent_size
- * crypt_stat->num_header_extents_at_front );
- extents_occupied_by_headers_at_front =
- ( bytes_occupied_by_headers_at_front
- / crypt_stat->extent_size );
- lower_extent_num = extents_occupied_by_headers_at_front + extent_num;
- extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
- (*lower_page_idx) = lower_extent_num / extents_per_page;
- extent_offset = lower_extent_num % extents_per_page;
- (*byte_offset) = extent_offset * crypt_stat->extent_size;
- ecryptfs_printk(KERN_DEBUG, " * crypt_stat->header_extent_size = "
- "[%d]\n", crypt_stat->header_extent_size);
- ecryptfs_printk(KERN_DEBUG, " * crypt_stat->"
- "num_header_extents_at_front = [%d]\n",
- crypt_stat->num_header_extents_at_front);
- ecryptfs_printk(KERN_DEBUG, " * extents_occupied_by_headers_at_"
- "front = [%d]\n", extents_occupied_by_headers_at_front);
- ecryptfs_printk(KERN_DEBUG, " * lower_extent_num = [0x%.16x]\n",
- lower_extent_num);
- ecryptfs_printk(KERN_DEBUG, " * extents_per_page = [%d]\n",
- extents_per_page);
- ecryptfs_printk(KERN_DEBUG, " * (*lower_page_idx) = [0x%.16x]\n",
- (*lower_page_idx));
- ecryptfs_printk(KERN_DEBUG, " * extent_offset = [%d]\n",
- extent_offset);
- ecryptfs_printk(KERN_DEBUG, " * (*byte_offset) = [%d]\n",
- (*byte_offset));
+ (*offset) = ((crypt_stat->extent_size
+ * crypt_stat->num_header_extents_at_front)
+ + (crypt_stat->extent_size * extent_num));
}
-static int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx,
- struct page *lower_page,
- struct inode *lower_inode,
- int byte_offset_in_page, int bytes_to_write)
+/**
+ * ecryptfs_encrypt_extent
+ * @enc_extent_page: Allocated page into which to encrypt the data in
+ * @page
+ * @crypt_stat: crypt_stat containing cryptographic context for the
+ * encryption operation
+ * @page: Page containing plaintext data extent to encrypt
+ * @extent_offset: Page extent offset for use in generating IV
+ *
+ * Encrypts one extent of data.
+ *
+ * Return zero on success; non-zero otherwise
+ */
+static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
+ struct ecryptfs_crypt_stat *crypt_stat,
+ struct page *page,
+ unsigned long extent_offset)
{
- int rc = 0;
+ loff_t extent_base;
+ char extent_iv[ECRYPTFS_MAX_IV_BYTES];
+ int rc;
- if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
- rc = ecryptfs_commit_lower_page(lower_page, lower_inode,
- ctx->param.lower_file,
- byte_offset_in_page,
- bytes_to_write);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error calling lower "
- "commit; rc = [%d]\n", rc);
- goto out;
- }
- } else {
- rc = ecryptfs_writepage_and_release_lower_page(lower_page,
- lower_inode,
- ctx->param.wbc);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error calling lower "
- "writepage(); rc = [%d]\n", rc);
- goto out;
- }
+ extent_base = (((loff_t)page->index)
+ * (PAGE_CACHE_SIZE / crypt_stat->extent_size));
+ rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
+ (extent_base + extent_offset));
+ if (rc) {
+ ecryptfs_printk(KERN_ERR, "Error attempting to "
+ "derive IV for extent [0x%.16x]; "
+ "rc = [%d]\n", (extent_base + extent_offset),
+ rc);
+ goto out;
}
-out:
- return rc;
-}
-
-static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx,
- struct page **lower_page,
- struct inode *lower_inode,
- unsigned long lower_page_idx,
- int byte_offset_in_page)
-{
- int rc = 0;
-
- if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
- /* TODO: Limit this to only the data extents that are
- * needed */
- rc = ecryptfs_get_lower_page(lower_page, lower_inode,
- ctx->param.lower_file,
- lower_page_idx,
- byte_offset_in_page,
- (PAGE_CACHE_SIZE
- - byte_offset_in_page));
- if (rc) {
- ecryptfs_printk(
- KERN_ERR, "Error attempting to grab, map, "
- "and prepare_write lower page with index "
- "[0x%.16x]; rc = [%d]\n", lower_page_idx, rc);
- goto out;
- }
- } else {
- *lower_page = grab_cache_page(lower_inode->i_mapping,
- lower_page_idx);
- if (!(*lower_page)) {
- rc = -EINVAL;
- ecryptfs_printk(
- KERN_ERR, "Error attempting to grab and map "
- "lower page with index [0x%.16x]; rc = [%d]\n",
- lower_page_idx, rc);
- goto out;
- }
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
+ "with iv:\n");
+ ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+ ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+ "encryption:\n");
+ ecryptfs_dump_hex((char *)
+ (page_address(page)
+ + (extent_offset * crypt_stat->extent_size)),
+ 8);
+ }
+ rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
+ page, (extent_offset
+ * crypt_stat->extent_size),
+ crypt_stat->extent_size, extent_iv);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error attempting to encrypt page with "
+ "page->index = [%ld], extent_offset = [%ld]; "
+ "rc = [%d]\n", __FUNCTION__, page->index, extent_offset,
+ rc);
+ goto out;
+ }
+ rc = 0;
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
+ "rc = [%d]\n", (extent_base + extent_offset),
+ rc);
+ ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+ "encryption:\n");
+ ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
}
out:
return rc;
@@ -445,7 +436,9 @@ out:
/**
* ecryptfs_encrypt_page
- * @ctx: The context of the page
+ * @page: Page mapped from the eCryptfs inode for the file; contains
+ * decrypted content that needs to be encrypted (to a temporary
+ * page; not in place) and written out to the lower file
*
* Encrypt an eCryptfs page. This is done on a per-extent basis. Note
* that eCryptfs pages may straddle the lower pages -- for instance,
@@ -455,128 +448,122 @@ out:
* file, 24K of page 0 of the lower file will be read and decrypted,
* and then 8K of page 1 of the lower file will be read and decrypted.
*
- * The actual operations performed on each page depends on the
- * contents of the ecryptfs_page_crypt_context struct.
- *
* Returns zero on success; negative on error
*/
-int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx)
+int ecryptfs_encrypt_page(struct page *page)
{
- char extent_iv[ECRYPTFS_MAX_IV_BYTES];
- unsigned long base_extent;
- unsigned long extent_offset = 0;
- unsigned long lower_page_idx = 0;
- unsigned long prior_lower_page_idx = 0;
- struct page *lower_page;
- struct inode *lower_inode;
- struct ecryptfs_inode_info *inode_info;
+ struct inode *ecryptfs_inode;
struct ecryptfs_crypt_stat *crypt_stat;
+ char *enc_extent_virt = NULL;
+ struct page *enc_extent_page;
+ loff_t extent_offset;
int rc = 0;
- int lower_byte_offset = 0;
- int orig_byte_offset = 0;
- int num_extents_per_page;
-#define ECRYPTFS_PAGE_STATE_UNREAD 0
-#define ECRYPTFS_PAGE_STATE_READ 1
-#define ECRYPTFS_PAGE_STATE_MODIFIED 2
-#define ECRYPTFS_PAGE_STATE_WRITTEN 3
- int page_state;
-
- lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host);
- inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host);
- crypt_stat = &inode_info->crypt_stat;
+
+ ecryptfs_inode = page->mapping->host;
+ crypt_stat =
+ &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
- rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode,
- ctx->param.lower_file);
+ rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, page,
+ 0, PAGE_CACHE_SIZE);
if (rc)
- ecryptfs_printk(KERN_ERR, "Error attempting to copy "
- "page at index [0x%.16x]\n",
- ctx->page->index);
+ printk(KERN_ERR "%s: Error attempting to copy "
+ "page at index [%ld]\n", __FUNCTION__,
+ page->index);
goto out;
}
- num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
- base_extent = (ctx->page->index * num_extents_per_page);
- page_state = ECRYPTFS_PAGE_STATE_UNREAD;
- while (extent_offset < num_extents_per_page) {
- ecryptfs_extent_to_lwr_pg_idx_and_offset(
- &lower_page_idx, &lower_byte_offset, crypt_stat,
- (base_extent + extent_offset));
- if (prior_lower_page_idx != lower_page_idx
- && page_state == ECRYPTFS_PAGE_STATE_MODIFIED) {
- rc = ecryptfs_write_out_page(ctx, lower_page,
- lower_inode,
- orig_byte_offset,
- (PAGE_CACHE_SIZE
- - orig_byte_offset));
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting "
- "to write out page; rc = [%d]"
- "\n", rc);
- goto out;
- }
- page_state = ECRYPTFS_PAGE_STATE_WRITTEN;
- }
- if (page_state == ECRYPTFS_PAGE_STATE_UNREAD
- || page_state == ECRYPTFS_PAGE_STATE_WRITTEN) {
- rc = ecryptfs_read_in_page(ctx, &lower_page,
- lower_inode, lower_page_idx,
- lower_byte_offset);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting "
- "to read in lower page with "
- "index [0x%.16x]; rc = [%d]\n",
- lower_page_idx, rc);
- goto out;
- }
- orig_byte_offset = lower_byte_offset;
- prior_lower_page_idx = lower_page_idx;
- page_state = ECRYPTFS_PAGE_STATE_READ;
- }
- BUG_ON(!(page_state == ECRYPTFS_PAGE_STATE_MODIFIED
- || page_state == ECRYPTFS_PAGE_STATE_READ));
- rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
- (base_extent + extent_offset));
+ enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
+ if (!enc_extent_virt) {
+ rc = -ENOMEM;
+ ecryptfs_printk(KERN_ERR, "Error allocating memory for "
+ "encrypted extent\n");
+ goto out;
+ }
+ enc_extent_page = virt_to_page(enc_extent_virt);
+ for (extent_offset = 0;
+ extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
+ extent_offset++) {
+ loff_t offset;
+
+ rc = ecryptfs_encrypt_extent(enc_extent_page, crypt_stat, page,
+ extent_offset);
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting to "
- "derive IV for extent [0x%.16x]; "
- "rc = [%d]\n",
- (base_extent + extent_offset), rc);
+ printk(KERN_ERR "%s: Error encrypting extent; "
+ "rc = [%d]\n", __FUNCTION__, rc);
goto out;
}
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
- "with iv:\n");
- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
- "encryption:\n");
- ecryptfs_dump_hex((char *)
- (page_address(ctx->page)
- + (extent_offset
- * crypt_stat->extent_size)), 8);
- }
- rc = ecryptfs_encrypt_page_offset(
- crypt_stat, lower_page, lower_byte_offset, ctx->page,
- (extent_offset * crypt_stat->extent_size),
- crypt_stat->extent_size, extent_iv);
- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
- "rc = [%d]\n",
- (base_extent + extent_offset), rc);
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
- "encryption:\n");
- ecryptfs_dump_hex((char *)(page_address(lower_page)
- + lower_byte_offset), 8);
+ ecryptfs_lower_offset_for_extent(
+ &offset, ((((loff_t)page->index)
+ * (PAGE_CACHE_SIZE
+ / crypt_stat->extent_size))
+ + extent_offset), crypt_stat);
+ rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt,
+ offset, crypt_stat->extent_size);
+ if (rc) {
+ ecryptfs_printk(KERN_ERR, "Error attempting "
+ "to write lower page; rc = [%d]"
+ "\n", rc);
+ goto out;
}
- page_state = ECRYPTFS_PAGE_STATE_MODIFIED;
extent_offset++;
}
- BUG_ON(orig_byte_offset != 0);
- rc = ecryptfs_write_out_page(ctx, lower_page, lower_inode, 0,
- (lower_byte_offset
- + crypt_stat->extent_size));
+out:
+ kfree(enc_extent_virt);
+ return rc;
+}
+
+static int ecryptfs_decrypt_extent(struct page *page,
+ struct ecryptfs_crypt_stat *crypt_stat,
+ struct page *enc_extent_page,
+ unsigned long extent_offset)
+{
+ loff_t extent_base;
+ char extent_iv[ECRYPTFS_MAX_IV_BYTES];
+ int rc;
+
+ extent_base = (((loff_t)page->index)
+ * (PAGE_CACHE_SIZE / crypt_stat->extent_size));
+ rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
+ (extent_base + extent_offset));
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting to write out "
- "page; rc = [%d]\n", rc);
- goto out;
+ ecryptfs_printk(KERN_ERR, "Error attempting to "
+ "derive IV for extent [0x%.16x]; "
+ "rc = [%d]\n", (extent_base + extent_offset),
+ rc);
+ goto out;
+ }
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
+ "with iv:\n");
+ ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+ ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+ "decryption:\n");
+ ecryptfs_dump_hex((char *)
+ (page_address(enc_extent_page)
+ + (extent_offset * crypt_stat->extent_size)),
+ 8);
+ }
+ rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
+ (extent_offset
+ * crypt_stat->extent_size),
+ enc_extent_page, 0,
+ crypt_stat->extent_size, extent_iv);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error attempting to decrypt to page with "
+ "page->index = [%ld], extent_offset = [%ld]; "
+ "rc = [%d]\n", __FUNCTION__, page->index, extent_offset,
+ rc);
+ goto out;
+ }
+ rc = 0;
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; "
+ "rc = [%d]\n", (extent_base + extent_offset),
+ rc);
+ ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+ "decryption:\n");
+ ecryptfs_dump_hex((char *)(page_address(page)
+ + (extent_offset
+ * crypt_stat->extent_size)), 8);
}
out:
return rc;
@@ -584,8 +571,9 @@ out:
/**
* ecryptfs_decrypt_page
- * @file: The ecryptfs file
- * @page: The page in ecryptfs to decrypt
+ * @page: Page mapped from the eCryptfs inode for the file; data read
+ * and decrypted from the lower file will be written into this
+ * page
*
* Decrypt an eCryptfs page. This is done on a per-extent basis. Note
* that eCryptfs pages may straddle the lower pages -- for instance,
@@ -597,108 +585,75 @@ out:
*
* Returns zero on success; negative on error
*/
-int ecryptfs_decrypt_page(struct file *file, struct page *page)
+int ecryptfs_decrypt_page(struct page *page)
{
- char extent_iv[ECRYPTFS_MAX_IV_BYTES];
- unsigned long base_extent;
- unsigned long extent_offset = 0;
- unsigned long lower_page_idx = 0;
- unsigned long prior_lower_page_idx = 0;
- struct page *lower_page;
- char *lower_page_virt = NULL;
- struct inode *lower_inode;
+ struct inode *ecryptfs_inode;
struct ecryptfs_crypt_stat *crypt_stat;
+ char *enc_extent_virt = NULL;
+ struct page *enc_extent_page;
+ unsigned long extent_offset;
int rc = 0;
- int byte_offset;
- int num_extents_per_page;
- int page_state;
- crypt_stat = &(ecryptfs_inode_to_private(
- page->mapping->host)->crypt_stat);
- lower_inode = ecryptfs_inode_to_lower(page->mapping->host);
+ ecryptfs_inode = page->mapping->host;
+ crypt_stat =
+ &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
- rc = ecryptfs_do_readpage(file, page, page->index);
+ rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
+ PAGE_CACHE_SIZE,
+ ecryptfs_inode);
if (rc)
- ecryptfs_printk(KERN_ERR, "Error attempting to copy "
- "page at index [0x%.16x]\n",
- page->index);
+ printk(KERN_ERR "%s: Error attempting to copy "
+ "page at index [%ld]\n", __FUNCTION__,
+ page->index);
goto out;
}
- num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
- base_extent = (page->index * num_extents_per_page);
- lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache,
- GFP_KERNEL);
- if (!lower_page_virt) {
+ enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
+ if (!enc_extent_virt) {
rc = -ENOMEM;
- ecryptfs_printk(KERN_ERR, "Error getting page for encrypted "
- "lower page(s)\n");
+ ecryptfs_printk(KERN_ERR, "Error allocating memory for "
+ "encrypted extent\n");
goto out;
}
- lower_page = virt_to_page(lower_page_virt);
- page_state = ECRYPTFS_PAGE_STATE_UNREAD;
- while (extent_offset < num_extents_per_page) {
- ecryptfs_extent_to_lwr_pg_idx_and_offset(
- &lower_page_idx, &byte_offset, crypt_stat,
- (base_extent + extent_offset));
- if (prior_lower_page_idx != lower_page_idx
- || page_state == ECRYPTFS_PAGE_STATE_UNREAD) {
- rc = ecryptfs_do_readpage(file, lower_page,
- lower_page_idx);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error reading "
- "lower encrypted page; rc = "
- "[%d]\n", rc);
- goto out;
- }
- prior_lower_page_idx = lower_page_idx;
- page_state = ECRYPTFS_PAGE_STATE_READ;
- }
- rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
- (base_extent + extent_offset));
+ enc_extent_page = virt_to_page(enc_extent_virt);
+ for (extent_offset = 0;
+ extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
+ extent_offset++) {
+ loff_t offset;
+
+ ecryptfs_lower_offset_for_extent(
+ &offset, ((page->index * (PAGE_CACHE_SIZE
+ / crypt_stat->extent_size))
+ + extent_offset), crypt_stat);
+ rc = ecryptfs_read_lower(enc_extent_virt, offset,
+ crypt_stat->extent_size,
+ ecryptfs_inode);
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting to "
- "derive IV for extent [0x%.16x]; rc = "
- "[%d]\n",
- (base_extent + extent_offset), rc);
+ ecryptfs_printk(KERN_ERR, "Error attempting "
+ "to read lower page; rc = [%d]"
+ "\n", rc);
goto out;
}
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
- "with iv:\n");
- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
- "decryption:\n");
- ecryptfs_dump_hex((lower_page_virt + byte_offset), 8);
- }
- rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
- (extent_offset
- * crypt_stat->extent_size),
- lower_page, byte_offset,
- crypt_stat->extent_size,
- extent_iv);
- if (rc != crypt_stat->extent_size) {
- ecryptfs_printk(KERN_ERR, "Error attempting to "
- "decrypt extent [0x%.16x]\n",
- (base_extent + extent_offset));
+ rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page,
+ extent_offset);
+ if (rc) {
+ printk(KERN_ERR "%s: Error encrypting extent; "
+ "rc = [%d]\n", __FUNCTION__, rc);
goto out;
}
- rc = 0;
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
- "decryption:\n");
- ecryptfs_dump_hex((char *)(page_address(page)
- + byte_offset), 8);
- }
extent_offset++;
}
out:
- if (lower_page_virt)
- kmem_cache_free(ecryptfs_lower_page_cache, lower_page_virt);
+ kfree(enc_extent_virt);
return rc;
}
/**
* decrypt_scatterlist
+ * @crypt_stat: Cryptographic context
+ * @dest_sg: The destination scatterlist to decrypt into
+ * @src_sg: The source scatterlist to decrypt from
+ * @size: The number of bytes to decrypt
+ * @iv: The initialization vector to use for the decryption
*
* Returns the number of bytes decrypted; negative value on error
*/
@@ -740,6 +695,13 @@ out:
/**
* ecryptfs_encrypt_page_offset
+ * @crypt_stat: The cryptographic context
+ * @dst_page: The page to encrypt into
+ * @dst_offset: The offset in the page to encrypt into
+ * @src_page: The page to encrypt from
+ * @src_offset: The offset in the page to encrypt from
+ * @size: The number of bytes to encrypt
+ * @iv: The initialization vector to use for the encryption
*
* Returns the number of bytes encrypted
*/
@@ -762,6 +724,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
/**
* ecryptfs_decrypt_page_offset
+ * @crypt_stat: The cryptographic context
+ * @dst_page: The page to decrypt into
+ * @dst_offset: The offset in the page to decrypt into
+ * @src_page: The page to decrypt from
+ * @src_offset: The offset in the page to decrypt from
+ * @size: The number of bytes to decrypt
+ * @iv: The initialization vector to use for the decryption
*
* Returns the number of bytes decrypted
*/
@@ -857,15 +826,17 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
set_extent_mask_and_shift(crypt_stat);
crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
- if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
- crypt_stat->header_extent_size =
- ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
- } else
- crypt_stat->header_extent_size = PAGE_CACHE_SIZE;
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
crypt_stat->num_header_extents_at_front = 0;
- else
- crypt_stat->num_header_extents_at_front = 1;
+ else {
+ if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
+ crypt_stat->num_header_extents_at_front =
+ (ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE
+ / crypt_stat->extent_size);
+ else
+ crypt_stat->num_header_extents_at_front =
+ (PAGE_CACHE_SIZE / crypt_stat->extent_size);
+ }
}
/**
@@ -917,6 +888,8 @@ static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
/**
* ecryptfs_copy_mount_wide_flags_to_inode_flags
+ * @crypt_stat: The inode's cryptographic context
+ * @mount_crypt_stat: The mount point's cryptographic context
*
* This function propagates the mount-wide flags to individual inode
* flags.
@@ -931,9 +904,34 @@ static void ecryptfs_copy_mount_wide_flags_to_inode_flags(
crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED;
}
+static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs(
+ struct ecryptfs_crypt_stat *crypt_stat,
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+ struct ecryptfs_global_auth_tok *global_auth_tok;
+ int rc = 0;
+
+ mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
+ list_for_each_entry(global_auth_tok,
+ &mount_crypt_stat->global_auth_tok_list,
+ mount_crypt_stat_list) {
+ rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig);
+ if (rc) {
+ printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc);
+ mutex_unlock(
+ &mount_crypt_stat->global_auth_tok_list_mutex);
+ goto out;
+ }
+ }
+ mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
+out:
+ return rc;
+}
+
/**
* ecryptfs_set_default_crypt_stat_vals
- * @crypt_stat
+ * @crypt_stat: The inode's cryptographic context
+ * @mount_crypt_stat: The mount point's cryptographic context
*
* Default values in the event that policy does not override them.
*/
@@ -953,7 +951,7 @@ static void ecryptfs_set_default_crypt_stat_vals(
/**
* ecryptfs_new_file_context
- * @ecryptfs_dentry
+ * @ecryptfs_dentry: The eCryptfs dentry
*
* If the crypto context for the file has not yet been established,
* this is where we do that. Establishing a new crypto context
@@ -970,49 +968,42 @@ static void ecryptfs_set_default_crypt_stat_vals(
*
* Returns zero on success; non-zero otherwise
*/
-/* Associate an authentication token(s) with the file */
int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
{
- int rc = 0;
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
int cipher_name_len;
+ int rc = 0;
ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat);
- /* See if there are mount crypt options */
- if (mount_crypt_stat->global_auth_tok) {
- ecryptfs_printk(KERN_DEBUG, "Initializing context for new "
- "file using mount_crypt_stat\n");
- crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
- crypt_stat->flags |= ECRYPTFS_KEY_VALID;
- ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
- mount_crypt_stat);
- memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++],
- mount_crypt_stat->global_auth_tok_sig,
- ECRYPTFS_SIG_SIZE_HEX);
- cipher_name_len =
- strlen(mount_crypt_stat->global_default_cipher_name);
- memcpy(crypt_stat->cipher,
- mount_crypt_stat->global_default_cipher_name,
- cipher_name_len);
- crypt_stat->cipher[cipher_name_len] = '\0';
- crypt_stat->key_size =
- mount_crypt_stat->global_default_cipher_key_size;
- ecryptfs_generate_new_key(crypt_stat);
- } else
- /* We should not encounter this scenario since we
- * should detect lack of global_auth_tok at mount time
- * TODO: Applies to 0.1 release only; remove in future
- * release */
- BUG();
+ crypt_stat->flags |= (ECRYPTFS_ENCRYPTED | ECRYPTFS_KEY_VALID);
+ ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
+ mount_crypt_stat);
+ rc = ecryptfs_copy_mount_wide_sigs_to_inode_sigs(crypt_stat,
+ mount_crypt_stat);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to copy mount-wide key sigs "
+ "to the inode key sigs; rc = [%d]\n", rc);
+ goto out;
+ }
+ cipher_name_len =
+ strlen(mount_crypt_stat->global_default_cipher_name);
+ memcpy(crypt_stat->cipher,
+ mount_crypt_stat->global_default_cipher_name,
+ cipher_name_len);
+ crypt_stat->cipher[cipher_name_len] = '\0';
+ crypt_stat->key_size =
+ mount_crypt_stat->global_default_cipher_key_size;
+ ecryptfs_generate_new_key(crypt_stat);
rc = ecryptfs_init_crypt_ctx(crypt_stat);
if (rc)
ecryptfs_printk(KERN_ERR, "Error initializing cryptographic "
"context for cipher [%s]: rc = [%d]\n",
crypt_stat->cipher, rc);
+out:
return rc;
}
@@ -1054,7 +1045,7 @@ static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = {
/**
* ecryptfs_process_flags
- * @crypt_stat
+ * @crypt_stat: The cryptographic context
* @page_virt: Source data to be parsed
* @bytes_read: Updated with the number of bytes read
*
@@ -1142,7 +1133,7 @@ ecryptfs_cipher_code_str_map[] = {
/**
* ecryptfs_code_for_cipher_string
- * @str: The string representing the cipher name
+ * @crypt_stat: The cryptographic context
*
* Returns zero on no match, or the cipher code on match
*/
@@ -1198,59 +1189,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
return rc;
}
-/**
- * ecryptfs_read_header_region
- * @data
- * @dentry
- * @nd
- *
- * Returns zero on success; non-zero otherwise
- */
-static int ecryptfs_read_header_region(char *data, struct dentry *dentry,
- struct vfsmount *mnt)
+int ecryptfs_read_and_validate_header_region(char *data,
+ struct inode *ecryptfs_inode)
{
- struct file *lower_file;
- mm_segment_t oldfs;
+ struct ecryptfs_crypt_stat *crypt_stat =
+ &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
int rc;
- if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt,
- O_RDONLY))) {
- printk(KERN_ERR
- "Error opening lower_file to read header region\n");
- goto out;
- }
- lower_file->f_pos = 0;
- oldfs = get_fs();
- set_fs(get_ds());
- /* For releases 0.1 and 0.2, all of the header information
- * fits in the first data extent-sized region. */
- rc = lower_file->f_op->read(lower_file, (char __user *)data,
- ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
- set_fs(oldfs);
- if ((rc = ecryptfs_close_lower_file(lower_file))) {
- printk(KERN_ERR "Error closing lower_file\n");
+ rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size,
+ ecryptfs_inode);
+ if (rc) {
+ printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n",
+ __FUNCTION__, rc);
goto out;
}
- rc = 0;
-out:
- return rc;
-}
-
-int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry,
- struct vfsmount *mnt)
-{
- int rc;
-
- rc = ecryptfs_read_header_region(data, dentry, mnt);
- if (rc)
- goto out;
- if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES))
+ if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) {
rc = -EINVAL;
+ ecryptfs_printk(KERN_DEBUG, "Valid marker not found\n");
+ }
out:
return rc;
}
-
void
ecryptfs_write_header_metadata(char *virt,
struct ecryptfs_crypt_stat *crypt_stat,
@@ -1259,7 +1219,7 @@ ecryptfs_write_header_metadata(char *virt,
u32 header_extent_size;
u16 num_header_extents_at_front;
- header_extent_size = (u32)crypt_stat->header_extent_size;
+ header_extent_size = (u32)crypt_stat->extent_size;
num_header_extents_at_front =
(u16)crypt_stat->num_header_extents_at_front;
header_extent_size = cpu_to_be32(header_extent_size);
@@ -1276,9 +1236,10 @@ struct kmem_cache *ecryptfs_header_cache_2;
/**
* ecryptfs_write_headers_virt
- * @page_virt
- * @crypt_stat
- * @ecryptfs_dentry
+ * @page_virt: The virtual address to write the headers to
+ * @size: Set to the number of bytes written by this function
+ * @crypt_stat: The cryptographic context
+ * @ecryptfs_dentry: The eCryptfs dentry
*
* Format version: 1
*
@@ -1332,53 +1293,50 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size,
return rc;
}
-static int ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
- struct file *lower_file,
- char *page_virt)
+static int
+ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
+ struct dentry *ecryptfs_dentry,
+ char *page_virt)
{
- mm_segment_t oldfs;
int current_header_page;
int header_pages;
- ssize_t size;
- int rc = 0;
+ int rc;
- lower_file->f_pos = 0;
- oldfs = get_fs();
- set_fs(get_ds());
- size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE,
- &lower_file->f_pos);
- if (size < 0) {
- rc = (int)size;
- printk(KERN_ERR "Error attempting to write lower page; "
- "rc = [%d]\n", rc);
- set_fs(oldfs);
+ rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, page_virt,
+ 0, PAGE_CACHE_SIZE);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to write header "
+ "information to lower file; rc = [%d]\n", __FUNCTION__,
+ rc);
goto out;
}
- header_pages = ((crypt_stat->header_extent_size
+ header_pages = ((crypt_stat->extent_size
* crypt_stat->num_header_extents_at_front)
/ PAGE_CACHE_SIZE);
memset(page_virt, 0, PAGE_CACHE_SIZE);
current_header_page = 1;
while (current_header_page < header_pages) {
- size = vfs_write(lower_file, (char __user *)page_virt,
- PAGE_CACHE_SIZE, &lower_file->f_pos);
- if (size < 0) {
- rc = (int)size;
- printk(KERN_ERR "Error attempting to write lower page; "
- "rc = [%d]\n", rc);
- set_fs(oldfs);
+ loff_t offset;
+
+ offset = (((loff_t)current_header_page) << PAGE_CACHE_SHIFT);
+ if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode,
+ page_virt, offset,
+ PAGE_CACHE_SIZE))) {
+ printk(KERN_ERR "%s: Error attempting to write header "
+ "information to lower file; rc = [%d]\n",
+ __FUNCTION__, rc);
goto out;
}
current_header_page++;
}
- set_fs(oldfs);
out:
return rc;
}
-static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
- struct ecryptfs_crypt_stat *crypt_stat,
- char *page_virt, size_t size)
+static int
+ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
+ struct ecryptfs_crypt_stat *crypt_stat,
+ char *page_virt, size_t size)
{
int rc;
@@ -1389,7 +1347,7 @@ static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
/**
* ecryptfs_write_metadata
- * @lower_file: The lower file struct, which was returned from dentry_open
+ * @ecryptfs_dentry: The eCryptfs dentry
*
* Write the file headers out. This will likely involve a userspace
* callout, in which the session key is encrypted with one or more
@@ -1397,22 +1355,21 @@ static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
* retrieved via a prompt. Exactly what happens at this point should
* be policy-dependent.
*
+ * TODO: Support header information spanning multiple pages
+ *
* Returns zero on success; non-zero on error
*/
-int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
- struct file *lower_file)
+int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
{
- struct ecryptfs_crypt_stat *crypt_stat;
+ struct ecryptfs_crypt_stat *crypt_stat =
+ &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
char *page_virt;
- size_t size;
+ size_t size = 0;
int rc = 0;
- crypt_stat = &ecryptfs_inode_to_private(
- ecryptfs_dentry->d_inode)->crypt_stat;
if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
- ecryptfs_printk(KERN_DEBUG, "Key is "
- "invalid; bailing out\n");
+ printk(KERN_ERR "Key is invalid; bailing out\n");
rc = -EINVAL;
goto out;
}
@@ -1441,7 +1398,8 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
crypt_stat, page_virt,
size);
else
- rc = ecryptfs_write_metadata_to_contents(crypt_stat, lower_file,
+ rc = ecryptfs_write_metadata_to_contents(crypt_stat,
+ ecryptfs_dentry,
page_virt);
if (rc) {
printk(KERN_ERR "Error writing metadata out to lower file; "
@@ -1464,28 +1422,28 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
u32 header_extent_size;
u16 num_header_extents_at_front;
- memcpy(&header_extent_size, virt, 4);
+ memcpy(&header_extent_size, virt, sizeof(u32));
header_extent_size = be32_to_cpu(header_extent_size);
- virt += 4;
- memcpy(&num_header_extents_at_front, virt, 2);
+ virt += sizeof(u32);
+ memcpy(&num_header_extents_at_front, virt, sizeof(u16));
num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front);
- crypt_stat->header_extent_size = (int)header_extent_size;
crypt_stat->num_header_extents_at_front =
(int)num_header_extents_at_front;
- (*bytes_read) = 6;
+ (*bytes_read) = (sizeof(u32) + sizeof(u16));
if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
- && ((crypt_stat->header_extent_size
+ && ((crypt_stat->extent_size
* crypt_stat->num_header_extents_at_front)
< ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
rc = -EINVAL;
- ecryptfs_printk(KERN_WARNING, "Invalid header extent size: "
- "[%d]\n", crypt_stat->header_extent_size);
+ printk(KERN_WARNING "Invalid number of header extents: [%zd]\n",
+ crypt_stat->num_header_extents_at_front);
}
return rc;
}
/**
* set_default_header_data
+ * @crypt_stat: The cryptographic context
*
* For version 0 file format; this function is only for backwards
* compatibility for files created with the prior versions of
@@ -1493,12 +1451,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
*/
static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
{
- crypt_stat->header_extent_size = 4096;
- crypt_stat->num_header_extents_at_front = 1;
+ crypt_stat->num_header_extents_at_front = 2;
}
/**
* ecryptfs_read_headers_virt
+ * @page_virt: The virtual address into which to read the headers
+ * @crypt_stat: The cryptographic context
+ * @ecryptfs_dentry: The eCryptfs dentry
+ * @validate_header_size: Whether to validate the header size while reading
*
* Read/parse the header data. The header format is detailed in the
* comment block for the ecryptfs_write_headers_virt() function.
@@ -1558,19 +1519,25 @@ out:
/**
* ecryptfs_read_xattr_region
+ * @page_virt: The vitual address into which to read the xattr data
+ * @ecryptfs_inode: The eCryptfs inode
*
* Attempts to read the crypto metadata from the extended attribute
* region of the lower file.
+ *
+ * Returns zero on success; non-zero on error
*/
-int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry)
+int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode)
{
+ struct dentry *lower_dentry =
+ ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry;
ssize_t size;
int rc = 0;
- size = ecryptfs_getxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME,
- page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE);
+ size = ecryptfs_getxattr_lower(lower_dentry, ECRYPTFS_XATTR_NAME,
+ page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE);
if (size < 0) {
- printk(KERN_DEBUG "Error attempting to read the [%s] "
+ printk(KERN_ERR "Error attempting to read the [%s] "
"xattr from the lower file; return value = [%zd]\n",
ECRYPTFS_XATTR_NAME, size);
rc = -EINVAL;
@@ -1585,7 +1552,7 @@ int ecryptfs_read_and_validate_xattr_region(char *page_virt,
{
int rc;
- rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry);
+ rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry->d_inode);
if (rc)
goto out;
if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) {
@@ -1609,15 +1576,13 @@ out:
*
* Returns zero if valid headers found and parsed; non-zero otherwise
*/
-int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
- struct file *lower_file)
+int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
{
int rc = 0;
char *page_virt = NULL;
- mm_segment_t oldfs;
- ssize_t bytes_read;
+ struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
struct ecryptfs_crypt_stat *crypt_stat =
- &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+ &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -1628,27 +1593,18 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER);
if (!page_virt) {
rc = -ENOMEM;
- ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n");
+ printk(KERN_ERR "%s: Unable to allocate page_virt\n",
+ __FUNCTION__);
goto out;
}
- lower_file->f_pos = 0;
- oldfs = get_fs();
- set_fs(get_ds());
- bytes_read = lower_file->f_op->read(lower_file,
- (char __user *)page_virt,
- ECRYPTFS_DEFAULT_EXTENT_SIZE,
- &lower_file->f_pos);
- set_fs(oldfs);
- if (bytes_read != ECRYPTFS_DEFAULT_EXTENT_SIZE) {
- rc = -EINVAL;
- goto out;
- }
- rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
- ecryptfs_dentry,
- ECRYPTFS_VALIDATE_HEADER_SIZE);
+ rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size,
+ ecryptfs_inode);
+ if (!rc)
+ rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
+ ecryptfs_dentry,
+ ECRYPTFS_VALIDATE_HEADER_SIZE);
if (rc) {
- rc = ecryptfs_read_xattr_region(page_virt,
- ecryptfs_dentry);
+ rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
if (rc) {
printk(KERN_DEBUG "Valid eCryptfs headers not found in "
"file header region or xattr region\n");
@@ -1776,7 +1732,7 @@ out:
}
/**
- * ecryptfs_process_cipher - Perform cipher initialization.
+ * ecryptfs_process_key_cipher - Perform key cipher initialization.
* @key_tfm: Crypto context for key material, set by this function
* @cipher_name: Name of the cipher
* @key_size: Size of the key in bytes
@@ -1785,9 +1741,9 @@ out:
* should be released by other functions, such as on a superblock put
* event, regardless of whether this function succeeds for fails.
*/
-int
-ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
- size_t *key_size)
+static int
+ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
+ char *cipher_name, size_t *key_size)
{
char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
char *full_alg_name;
@@ -1829,3 +1785,100 @@ ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
out:
return rc;
}
+
+struct kmem_cache *ecryptfs_key_tfm_cache;
+struct list_head key_tfm_list;
+struct mutex key_tfm_list_mutex;
+
+int ecryptfs_init_crypto(void)
+{
+ mutex_init(&key_tfm_list_mutex);
+ INIT_LIST_HEAD(&key_tfm_list);
+ return 0;
+}
+
+int ecryptfs_destroy_crypto(void)
+{
+ struct ecryptfs_key_tfm *key_tfm, *key_tfm_tmp;
+
+ mutex_lock(&key_tfm_list_mutex);
+ list_for_each_entry_safe(key_tfm, key_tfm_tmp, &key_tfm_list,
+ key_tfm_list) {
+ list_del(&key_tfm->key_tfm_list);
+ if (key_tfm->key_tfm)
+ crypto_free_blkcipher(key_tfm->key_tfm);
+ kmem_cache_free(ecryptfs_key_tfm_cache, key_tfm);
+ }
+ mutex_unlock(&key_tfm_list_mutex);
+ return 0;
+}
+
+int
+ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
+ size_t key_size)
+{
+ struct ecryptfs_key_tfm *tmp_tfm;
+ int rc = 0;
+
+ tmp_tfm = kmem_cache_alloc(ecryptfs_key_tfm_cache, GFP_KERNEL);
+ if (key_tfm != NULL)
+ (*key_tfm) = tmp_tfm;
+ if (!tmp_tfm) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Error attempting to allocate from "
+ "ecryptfs_key_tfm_cache\n");
+ goto out;
+ }
+ mutex_init(&tmp_tfm->key_tfm_mutex);
+ strncpy(tmp_tfm->cipher_name, cipher_name,
+ ECRYPTFS_MAX_CIPHER_NAME_SIZE);
+ tmp_tfm->key_size = key_size;
+ rc = ecryptfs_process_key_cipher(&tmp_tfm->key_tfm,
+ tmp_tfm->cipher_name,
+ &tmp_tfm->key_size);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to initialize key TFM "
+ "cipher with name = [%s]; rc = [%d]\n",
+ tmp_tfm->cipher_name, rc);
+ kmem_cache_free(ecryptfs_key_tfm_cache, tmp_tfm);
+ if (key_tfm != NULL)
+ (*key_tfm) = NULL;
+ goto out;
+ }
+ mutex_lock(&key_tfm_list_mutex);
+ list_add(&tmp_tfm->key_tfm_list, &key_tfm_list);
+ mutex_unlock(&key_tfm_list_mutex);
+out:
+ return rc;
+}
+
+int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
+ struct mutex **tfm_mutex,
+ char *cipher_name)
+{
+ struct ecryptfs_key_tfm *key_tfm;
+ int rc = 0;
+
+ (*tfm) = NULL;
+ (*tfm_mutex) = NULL;
+ mutex_lock(&key_tfm_list_mutex);
+ list_for_each_entry(key_tfm, &key_tfm_list, key_tfm_list) {
+ if (strcmp(key_tfm->cipher_name, cipher_name) == 0) {
+ (*tfm) = key_tfm->key_tfm;
+ (*tfm_mutex) = &key_tfm->key_tfm_mutex;
+ mutex_unlock(&key_tfm_list_mutex);
+ goto out;
+ }
+ }
+ mutex_unlock(&key_tfm_list_mutex);
+ rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0);
+ if (rc) {
+ printk(KERN_ERR "Error adding new key_tfm to list; rc = [%d]\n",
+ rc);
+ goto out;
+ }
+ (*tfm) = key_tfm->key_tfm;
+ (*tfm_mutex) = &key_tfm->key_tfm_mutex;
+out:
+ return rc;
+}
diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c
index 434c7efd80f..3d2bdf546ec 100644
--- a/fs/ecryptfs/debug.c
+++ b/fs/ecryptfs/debug.c
@@ -38,8 +38,6 @@ void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok)
auth_tok);
if (auth_tok->flags & ECRYPTFS_PRIVATE_KEY) {
ecryptfs_printk(KERN_DEBUG, " * private key type\n");
- ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT "
- "IN ECRYPTFS VERSION 0.1)\n");
} else {
ecryptfs_printk(KERN_DEBUG, " * passphrase type\n");
ecryptfs_to_hex(salt, auth_tok->token.password.salt,
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 1b9dd9a96f1..ce7a5d4aec3 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -38,7 +38,7 @@
/* Version verification for shared data structures w/ userspace */
#define ECRYPTFS_VERSION_MAJOR 0x00
#define ECRYPTFS_VERSION_MINOR 0x04
-#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x02
+#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
/* These flags indicate which features are supported by the kernel
* module; userspace tools such as the mount helper read
* ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
@@ -48,10 +48,12 @@
#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
#define ECRYPTFS_VERSIONING_POLICY 0x00000008
#define ECRYPTFS_VERSIONING_XATTR 0x00000010
+#define ECRYPTFS_VERSIONING_MULTKEY 0x00000020
#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
| ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
| ECRYPTFS_VERSIONING_PUBKEY \
- | ECRYPTFS_VERSIONING_XATTR)
+ | ECRYPTFS_VERSIONING_XATTR \
+ | ECRYPTFS_VERSIONING_MULTKEY)
#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
#define ECRYPTFS_SALT_SIZE 8
@@ -65,8 +67,7 @@
#define ECRYPTFS_MAX_KEY_BYTES 64
#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
#define ECRYPTFS_DEFAULT_IV_BYTES 16
-#define ECRYPTFS_FILE_VERSION 0x02
-#define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192
+#define ECRYPTFS_FILE_VERSION 0x03
#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
#define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32
@@ -144,6 +145,7 @@ struct ecryptfs_private_key {
struct ecryptfs_auth_tok {
u16 version; /* 8-bit major and 8-bit minor */
u16 token_type;
+#define ECRYPTFS_ENCRYPT_ONLY 0x00000001
u32 flags;
struct ecryptfs_session_key session_key;
u8 reserved[32];
@@ -194,12 +196,11 @@ ecryptfs_get_key_payload_data(struct key *key)
#define ECRYPTFS_MAX_KEYSET_SIZE 1024
#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32
#define ECRYPTFS_MAX_NUM_ENC_KEYS 64
-#define ECRYPTFS_MAX_NUM_KEYSIGS 2 /* TODO: Make this a linked list */
#define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */
#define ECRYPTFS_SALT_BYTES 2
#define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5
#define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */
-#define ECRYPTFS_FILE_SIZE_BYTES 8
+#define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64))
#define ECRYPTFS_DEFAULT_CIPHER "aes"
#define ECRYPTFS_DEFAULT_KEY_BYTES 16
#define ECRYPTFS_DEFAULT_HASH "md5"
@@ -212,6 +213,11 @@ ecryptfs_get_key_payload_data(struct key *key)
#define ECRYPTFS_TAG_67_PACKET_TYPE 0x43
#define MD5_DIGEST_SIZE 16
+struct ecryptfs_key_sig {
+ struct list_head crypt_stat_list;
+ char keysig[ECRYPTFS_SIG_SIZE_HEX];
+};
+
/**
* This is the primary struct associated with each encrypted file.
*
@@ -231,8 +237,6 @@ struct ecryptfs_crypt_stat {
u32 flags;
unsigned int file_version;
size_t iv_bytes;
- size_t num_keysigs;
- size_t header_extent_size;
size_t num_header_extents_at_front;
size_t extent_size; /* Data extent size; default is 4096 */
size_t key_size;
@@ -245,7 +249,8 @@ struct ecryptfs_crypt_stat {
unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
- unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
+ struct list_head keysig_list;
+ struct mutex keysig_list_mutex;
struct mutex cs_tfm_mutex;
struct mutex cs_hash_tfm_mutex;
struct mutex cs_mutex;
@@ -255,6 +260,8 @@ struct ecryptfs_crypt_stat {
struct ecryptfs_inode_info {
struct inode vfs_inode;
struct inode *wii_inode;
+ struct file *lower_file;
+ struct mutex lower_file_mutex;
struct ecryptfs_crypt_stat crypt_stat;
};
@@ -266,6 +273,59 @@ struct ecryptfs_dentry_info {
};
/**
+ * ecryptfs_global_auth_tok - A key used to encrypt all new files under the mountpoint
+ * @flags: Status flags
+ * @mount_crypt_stat_list: These auth_toks hang off the mount-wide
+ * cryptographic context. Every time a new
+ * inode comes into existence, eCryptfs copies
+ * the auth_toks on that list to the set of
+ * auth_toks on the inode's crypt_stat
+ * @global_auth_tok_key: The key from the user's keyring for the sig
+ * @global_auth_tok: The key contents
+ * @sig: The key identifier
+ *
+ * ecryptfs_global_auth_tok structs refer to authentication token keys
+ * in the user keyring that apply to newly created files. A list of
+ * these objects hangs off of the mount_crypt_stat struct for any
+ * given eCryptfs mount. This struct maintains a reference to both the
+ * key contents and the key itself so that the key can be put on
+ * unmount.
+ */
+struct ecryptfs_global_auth_tok {
+#define ECRYPTFS_AUTH_TOK_INVALID 0x00000001
+ u32 flags;
+ struct list_head mount_crypt_stat_list;
+ struct key *global_auth_tok_key;
+ struct ecryptfs_auth_tok *global_auth_tok;
+ unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+};
+
+/**
+ * ecryptfs_key_tfm - Persistent key tfm
+ * @key_tfm: crypto API handle to the key
+ * @key_size: Key size in bytes
+ * @key_tfm_mutex: Mutex to ensure only one operation in eCryptfs is
+ * using the persistent TFM at any point in time
+ * @key_tfm_list: Handle to hang this off the module-wide TFM list
+ * @cipher_name: String name for the cipher for this TFM
+ *
+ * Typically, eCryptfs will use the same ciphers repeatedly throughout
+ * the course of its operations. In order to avoid unnecessarily
+ * destroying and initializing the same cipher repeatedly, eCryptfs
+ * keeps a list of crypto API contexts around to use when needed.
+ */
+struct ecryptfs_key_tfm {
+ struct crypto_blkcipher *key_tfm;
+ size_t key_size;
+ struct mutex key_tfm_mutex;
+ struct list_head key_tfm_list;
+ unsigned char cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
+};
+
+extern struct list_head key_tfm_list;
+extern struct mutex key_tfm_list_mutex;
+
+/**
* This struct is to enable a mount-wide passphrase/salt combo. This
* is more or less a stopgap to provide similar functionality to other
* crypto filesystems like EncFS or CFS until full policy support is
@@ -276,15 +336,14 @@ struct ecryptfs_mount_crypt_stat {
#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001
#define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002
#define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004
+#define ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED 0x00000008
u32 flags;
- struct ecryptfs_auth_tok *global_auth_tok;
- struct key *global_auth_tok_key;
+ struct list_head global_auth_tok_list;
+ struct mutex global_auth_tok_list_mutex;
+ size_t num_global_auth_toks;
size_t global_default_cipher_key_size;
- struct crypto_blkcipher *global_key_tfm;
- struct mutex global_key_tfm_mutex;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+ 1];
- unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
};
/* superblock private data. */
@@ -468,6 +527,9 @@ extern struct kmem_cache *ecryptfs_header_cache_2;
extern struct kmem_cache *ecryptfs_xattr_cache;
extern struct kmem_cache *ecryptfs_lower_page_cache;
extern struct kmem_cache *ecryptfs_key_record_cache;
+extern struct kmem_cache *ecryptfs_key_sig_cache;
+extern struct kmem_cache *ecryptfs_global_auth_tok_cache;
+extern struct kmem_cache *ecryptfs_key_tfm_cache;
int ecryptfs_interpose(struct dentry *hidden_dentry,
struct dentry *this_dentry, struct super_block *sb,
@@ -486,44 +548,18 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat);
void ecryptfs_rotate_iv(unsigned char *iv);
void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
-void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
-void ecryptfs_destruct_mount_crypt_stat(
+void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_destroy_mount_crypt_stat(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
-int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
- char *cipher_name,
- char *chaining_modifier);
-#define ECRYPTFS_LOWER_I_MUTEX_NOT_HELD 0
-#define ECRYPTFS_LOWER_I_MUTEX_HELD 1
-int ecryptfs_write_inode_size_to_metadata(struct file *lower_file,
- struct inode *lower_inode,
- struct inode *inode,
- struct dentry *ecryptfs_dentry,
- int lower_i_mutex_held);
-int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
- struct file *lower_file,
- unsigned long lower_page_index, int byte_offset,
- int region_bytes);
-int
-ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
- struct file *lower_file, int byte_offset,
- int region_size);
-int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
- struct file *lower_file);
-int ecryptfs_do_readpage(struct file *file, struct page *page,
- pgoff_t lower_page_index);
-int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
- struct inode *lower_inode,
- struct writeback_control *wbc);
-int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx);
-int ecryptfs_decrypt_page(struct file *file, struct page *page);
-int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
- struct file *lower_file);
-int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
- struct file *lower_file);
+int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode);
+int ecryptfs_encrypt_page(struct page *page);
+int ecryptfs_decrypt_page(struct page *page);
+int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
+int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
-int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry,
- struct vfsmount *mnt);
+int ecryptfs_read_and_validate_header_region(char *data,
+ struct inode *ecryptfs_inode);
int ecryptfs_read_and_validate_xattr_region(char *page_virt,
struct dentry *ecryptfs_dentry);
u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
@@ -533,27 +569,22 @@ int ecryptfs_generate_key_packet_set(char *dest_base,
struct ecryptfs_crypt_stat *crypt_stat,
struct dentry *ecryptfs_dentry,
size_t *len, size_t max);
-int process_request_key_err(long err_code);
int
ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
unsigned char *src, struct dentry *ecryptfs_dentry);
int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
-int
-ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
- size_t *key_size);
int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
-int ecryptfs_open_lower_file(struct file **lower_file,
- struct dentry *lower_dentry,
- struct vfsmount *lower_mnt, int flags);
-int ecryptfs_close_lower_file(struct file *lower_file);
ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
size_t size);
+ssize_t
+ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
+ void *value, size_t size);
int
ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t size, int flags);
-int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry);
+int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid);
int ecryptfs_process_quit(uid_t uid, pid_t pid);
int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid,
@@ -580,7 +611,43 @@ void
ecryptfs_write_header_metadata(char *virt,
struct ecryptfs_crypt_stat *crypt_stat,
size_t *written);
+int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig);
+int
+ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
+ char *sig);
+int ecryptfs_get_global_auth_tok_for_sig(
+ struct ecryptfs_global_auth_tok **global_auth_tok,
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig);
+int
+ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
+ size_t key_size);
+int ecryptfs_init_crypto(void);
+int ecryptfs_destroy_crypto(void);
+int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
+ struct mutex **tfm_mutex,
+ char *cipher_name);
+int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
+ struct ecryptfs_auth_tok **auth_tok,
+ char *sig);
int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start,
int num_zeros);
+void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
+ struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
+ loff_t offset, size_t size);
+int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
+ struct page *page_for_lower,
+ size_t offset_in_page, size_t size);
+int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
+ size_t size);
+int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
+ struct inode *ecryptfs_inode);
+int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
+ pgoff_t page_index,
+ size_t offset_in_page, size_t size,
+ struct inode *ecryptfs_inode);
+int ecryptfs_read(char *data, loff_t offset, size_t size,
+ struct file *ecryptfs_file);
+struct page *ecryptfs_get_locked_page(struct file *file, loff_t index);
#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 94f456fe4d9..c98c4690a77 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -141,34 +141,6 @@ retry:
struct kmem_cache *ecryptfs_file_info_cache;
-int ecryptfs_open_lower_file(struct file **lower_file,
- struct dentry *lower_dentry,
- struct vfsmount *lower_mnt, int flags)
-{
- int rc = 0;
-
- flags |= O_LARGEFILE;
- dget(lower_dentry);
- mntget(lower_mnt);
- *lower_file = dentry_open(lower_dentry, lower_mnt, flags);
- if (IS_ERR(*lower_file)) {
- printk(KERN_ERR "Error opening lower file for lower_dentry "
- "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n",
- lower_dentry, lower_mnt, flags);
- rc = PTR_ERR(*lower_file);
- *lower_file = NULL;
- goto out;
- }
-out:
- return rc;
-}
-
-int ecryptfs_close_lower_file(struct file *lower_file)
-{
- fput(lower_file);
- return 0;
-}
-
/**
* ecryptfs_open
* @inode: inode speciying file to open
@@ -187,11 +159,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
/* Private value of ecryptfs_dentry allocated in
* ecryptfs_lookup() */
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
- struct inode *lower_inode = NULL;
- struct file *lower_file = NULL;
- struct vfsmount *lower_mnt;
struct ecryptfs_file_info *file_info;
- int lower_flags;
mount_crypt_stat = &ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -219,25 +187,12 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n");
/* Policy code enabled in future release */
- crypt_stat->flags |= ECRYPTFS_POLICY_APPLIED;
- crypt_stat->flags |= ECRYPTFS_ENCRYPTED;
+ crypt_stat->flags |= (ECRYPTFS_POLICY_APPLIED
+ | ECRYPTFS_ENCRYPTED);
}
mutex_unlock(&crypt_stat->cs_mutex);
- lower_flags = file->f_flags;
- if ((lower_flags & O_ACCMODE) == O_WRONLY)
- lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
- if (file->f_flags & O_APPEND)
- lower_flags &= ~O_APPEND;
- lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
- /* Corresponding fput() in ecryptfs_release() */
- if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
- lower_flags))) {
- ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
- goto out_puts;
- }
- ecryptfs_set_file_lower(file, lower_file);
- /* Isn't this check the same as the one in lookup? */
- lower_inode = lower_dentry->d_inode;
+ ecryptfs_set_file_lower(
+ file, ecryptfs_inode_to_private(inode)->lower_file);
if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
@@ -247,7 +202,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
mutex_lock(&crypt_stat->cs_mutex);
if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
|| !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
- rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file);
+ rc = ecryptfs_read_metadata(ecryptfs_dentry);
if (rc) {
ecryptfs_printk(KERN_DEBUG,
"Valid headers not found\n");
@@ -259,7 +214,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
"and plaintext passthrough mode is not "
"enabled; returning -EIO\n");
mutex_unlock(&crypt_stat->cs_mutex);
- goto out_puts;
+ goto out_free;
}
rc = 0;
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
@@ -271,11 +226,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] "
"size: [0x%.16x]\n", inode, inode->i_ino,
i_size_read(inode));
- ecryptfs_set_file_lower(file, lower_file);
goto out;
-out_puts:
- mntput(lower_mnt);
- dput(lower_dentry);
+out_free:
kmem_cache_free(ecryptfs_file_info_cache,
ecryptfs_file_to_private(file));
out:
@@ -295,19 +247,9 @@ static int ecryptfs_flush(struct file *file, fl_owner_t td)
static int ecryptfs_release(struct inode *inode, struct file *file)
{
- struct file *lower_file = ecryptfs_file_to_lower(file);
- struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
- struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
- int rc;
-
- if ((rc = ecryptfs_close_lower_file(lower_file))) {
- printk(KERN_ERR "Error closing lower_file\n");
- goto out;
- }
- inode->i_blocks = lower_inode->i_blocks;
- kmem_cache_free(ecryptfs_file_info_cache, file_info);
-out:
- return rc;
+ kmem_cache_free(ecryptfs_file_info_cache,
+ ecryptfs_file_to_private(file));
+ return 0;
}
static int
@@ -338,21 +280,6 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
return rc;
}
-static ssize_t ecryptfs_splice_read(struct file *file, loff_t * ppos,
- struct pipe_inode_info *pipe, size_t count,
- unsigned int flags)
-{
- struct file *lower_file = NULL;
- int rc = -EINVAL;
-
- lower_file = ecryptfs_file_to_lower(file);
- if (lower_file->f_op && lower_file->f_op->splice_read)
- rc = lower_file->f_op->splice_read(lower_file, ppos, pipe,
- count, flags);
-
- return rc;
-}
-
static int ecryptfs_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
@@ -365,7 +292,7 @@ const struct file_operations ecryptfs_dir_fops = {
.release = ecryptfs_release,
.fsync = ecryptfs_fsync,
.fasync = ecryptfs_fasync,
- .splice_read = ecryptfs_splice_read,
+ .splice_read = generic_file_splice_read,
};
const struct file_operations ecryptfs_main_fops = {
@@ -382,7 +309,7 @@ const struct file_operations ecryptfs_main_fops = {
.release = ecryptfs_release,
.fsync = ecryptfs_fsync,
.fasync = ecryptfs_fasync,
- .splice_read = ecryptfs_splice_read,
+ .splice_read = generic_file_splice_read,
};
static int
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 131954b3fb9..0b1ab016fa2 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -119,10 +119,23 @@ ecryptfs_do_create(struct inode *directory_inode,
}
rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
ecryptfs_dentry, mode, nd);
- if (unlikely(rc)) {
- ecryptfs_printk(KERN_ERR,
- "Failure to create underlying file\n");
- goto out_lock;
+ if (rc) {
+ struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
+ struct ecryptfs_inode_info *inode_info =
+ ecryptfs_inode_to_private(ecryptfs_inode);
+
+ printk(KERN_WARNING "%s: Error creating underlying file; "
+ "rc = [%d]; checking for existing\n", __FUNCTION__, rc);
+ if (inode_info) {
+ mutex_lock(&inode_info->lower_file_mutex);
+ if (!inode_info->lower_file) {
+ mutex_unlock(&inode_info->lower_file_mutex);
+ printk(KERN_ERR "%s: Failure to set underlying "
+ "file; rc = [%d]\n", __FUNCTION__, rc);
+ goto out_lock;
+ }
+ mutex_unlock(&inode_info->lower_file_mutex);
+ }
}
rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
directory_inode->i_sb, 0);
@@ -140,39 +153,30 @@ out:
/**
* grow_file
- * @ecryptfs_dentry: the ecryptfs dentry
- * @lower_file: The lower file
- * @inode: The ecryptfs inode
- * @lower_inode: The lower inode
+ * @ecryptfs_dentry: the eCryptfs dentry
*
* This is the code which will grow the file to its correct size.
*/
-static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file,
- struct inode *inode, struct inode *lower_inode)
+static int grow_file(struct dentry *ecryptfs_dentry)
{
- int rc = 0;
+ struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
struct file fake_file;
struct ecryptfs_file_info tmp_file_info;
+ char zero_virt[] = { 0x00 };
+ int rc = 0;
memset(&fake_file, 0, sizeof(fake_file));
fake_file.f_path.dentry = ecryptfs_dentry;
memset(&tmp_file_info, 0, sizeof(tmp_file_info));
ecryptfs_set_file_private(&fake_file, &tmp_file_info);
- ecryptfs_set_file_lower(&fake_file, lower_file);
- rc = ecryptfs_fill_zeros(&fake_file, 1);
- if (rc) {
- ecryptfs_inode_to_private(inode)->crypt_stat.flags |=
- ECRYPTFS_SECURITY_WARNING;
- ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros "
- "in file; rc = [%d]\n", rc);
- goto out;
- }
- i_size_write(inode, 0);
- rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode,
- inode, ecryptfs_dentry,
- ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
- ecryptfs_inode_to_private(inode)->crypt_stat.flags |= ECRYPTFS_NEW_FILE;
-out:
+ ecryptfs_set_file_lower(
+ &fake_file,
+ ecryptfs_inode_to_private(ecryptfs_inode)->lower_file);
+ rc = ecryptfs_write(&fake_file, zero_virt, 0, 1);
+ i_size_write(ecryptfs_inode, 0);
+ rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
+ ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |=
+ ECRYPTFS_NEW_FILE;
return rc;
}
@@ -186,51 +190,31 @@ out:
*/
static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
{
+ struct ecryptfs_crypt_stat *crypt_stat =
+ &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
int rc = 0;
- int lower_flags;
- struct ecryptfs_crypt_stat *crypt_stat;
- struct dentry *lower_dentry;
- struct file *lower_file;
- struct inode *inode, *lower_inode;
- struct vfsmount *lower_mnt;
- lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
- ecryptfs_printk(KERN_DEBUG, "lower_dentry->d_name.name = [%s]\n",
- lower_dentry->d_name.name);
- inode = ecryptfs_dentry->d_inode;
- crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
- lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR;
- lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
- /* Corresponding fput() at end of this function */
- if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
- lower_flags))) {
- ecryptfs_printk(KERN_ERR,
- "Error opening dentry; rc = [%i]\n", rc);
- goto out;
- }
- lower_inode = lower_dentry->d_inode;
if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
- goto out_fput;
+ goto out;
}
crypt_stat->flags |= ECRYPTFS_NEW_FILE;
ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
rc = ecryptfs_new_file_context(ecryptfs_dentry);
if (rc) {
- ecryptfs_printk(KERN_DEBUG, "Error creating new file "
- "context\n");
- goto out_fput;
+ ecryptfs_printk(KERN_ERR, "Error creating new file "
+ "context; rc = [%d]\n", rc);
+ goto out;
}
- rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file);
+ rc = ecryptfs_write_metadata(ecryptfs_dentry);
if (rc) {
- ecryptfs_printk(KERN_DEBUG, "Error writing headers\n");
- goto out_fput;
+ printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
+ goto out;
}
- rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
-out_fput:
- if ((rc = ecryptfs_close_lower_file(lower_file)))
- printk(KERN_ERR "Error closing lower_file\n");
+ rc = grow_file(ecryptfs_dentry);
+ if (rc)
+ printk(KERN_ERR "Error growing file; rc = [%d]\n", rc);
out:
return rc;
}
@@ -252,6 +236,8 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
{
int rc;
+ /* ecryptfs_do_create() calls ecryptfs_interpose(), which opens
+ * the crypt_stat->lower_file (persistent file) */
rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd);
if (unlikely(rc)) {
ecryptfs_printk(KERN_WARNING, "Failed to create file in"
@@ -374,8 +360,8 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
ecryptfs_set_default_sizes(crypt_stat);
- rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry,
- nd->mnt);
+ rc = ecryptfs_read_and_validate_header_region(page_virt,
+ dentry->d_inode);
if (rc) {
rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry);
if (rc) {
@@ -392,7 +378,8 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
dentry->d_sb)->mount_crypt_stat;
if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
- file_size = (crypt_stat->header_extent_size
+ file_size = ((crypt_stat->extent_size
+ * crypt_stat->num_header_extents_at_front)
+ i_size_read(lower_dentry->d_inode));
else
file_size = i_size_read(lower_dentry->d_inode);
@@ -722,8 +709,8 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
{
loff_t lower_size;
- lower_size = ( crypt_stat->header_extent_size
- * crypt_stat->num_header_extents_at_front );
+ lower_size = (crypt_stat->extent_size
+ * crypt_stat->num_header_extents_at_front);
if (upper_size != 0) {
loff_t num_extents;
@@ -752,8 +739,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
int rc = 0;
struct inode *inode = dentry->d_inode;
struct dentry *lower_dentry;
- struct vfsmount *lower_mnt;
- struct file fake_ecryptfs_file, *lower_file = NULL;
+ struct file fake_ecryptfs_file;
struct ecryptfs_crypt_stat *crypt_stat;
loff_t i_size = i_size_read(inode);
loff_t lower_size_before_truncate;
@@ -776,62 +762,52 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
goto out;
}
lower_dentry = ecryptfs_dentry_to_lower(dentry);
- /* This dget & mntget is released through fput at out_fput: */
- lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
- if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
- O_RDWR))) {
- ecryptfs_printk(KERN_ERR,
- "Error opening dentry; rc = [%i]\n", rc);
- goto out_free;
- }
- ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
+ ecryptfs_set_file_lower(
+ &fake_ecryptfs_file,
+ ecryptfs_inode_to_private(dentry->d_inode)->lower_file);
/* Switch on growing or shrinking file */
if (new_length > i_size) {
- rc = ecryptfs_fill_zeros(&fake_ecryptfs_file, new_length);
- if (rc) {
- ecryptfs_printk(KERN_ERR,
- "Problem with fill_zeros\n");
- goto out_fput;
- }
- i_size_write(inode, new_length);
- rc = ecryptfs_write_inode_size_to_metadata(
- lower_file, lower_dentry->d_inode, inode, dentry,
- ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
- if (rc) {
- printk(KERN_ERR "Problem with "
- "ecryptfs_write_inode_size_to_metadata; "
- "rc = [%d]\n", rc);
- goto out_fput;
- }
+ char zero[] = { 0x00 };
+
+ /* Write a single 0 at the last position of the file;
+ * this triggers code that will fill in 0's throughout
+ * the intermediate portion of the previous end of the
+ * file and the new and of the file */
+ rc = ecryptfs_write(&fake_ecryptfs_file, zero,
+ (new_length - 1), 1);
} else { /* new_length < i_size_read(inode) */
- pgoff_t index = 0;
- int end_pos_in_page = -1;
+ /* We're chopping off all the pages down do the page
+ * in which new_length is located. Fill in the end of
+ * that page from (new_length & ~PAGE_CACHE_MASK) to
+ * PAGE_CACHE_SIZE with zeros. */
+ size_t num_zeros = (PAGE_CACHE_SIZE
+ - (new_length & ~PAGE_CACHE_MASK));
- if (new_length != 0) {
- index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
- end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
- }
- if (end_pos_in_page != (PAGE_CACHE_SIZE - 1)) {
- if ((rc = ecryptfs_write_zeros(&fake_ecryptfs_file,
- index,
- (end_pos_in_page + 1),
- ((PAGE_CACHE_SIZE - 1)
- - end_pos_in_page)))) {
+ if (num_zeros) {
+ char *zeros_virt;
+
+ zeros_virt = kzalloc(num_zeros, GFP_KERNEL);
+ if (!zeros_virt) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
+ rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt,
+ new_length, num_zeros);
+ kfree(zeros_virt);
+ if (rc) {
printk(KERN_ERR "Error attempting to zero out "
"the remainder of the end page on "
"reducing truncate; rc = [%d]\n", rc);
- goto out_fput;
+ goto out_free;
}
}
vmtruncate(inode, new_length);
- rc = ecryptfs_write_inode_size_to_metadata(
- lower_file, lower_dentry->d_inode, inode, dentry,
- ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
+ rc = ecryptfs_write_inode_size_to_metadata(inode);
if (rc) {
printk(KERN_ERR "Problem with "
"ecryptfs_write_inode_size_to_metadata; "
"rc = [%d]\n", rc);
- goto out_fput;
+ goto out_free;
}
/* We are reducing the size of the ecryptfs file, and need to
* know if we need to reduce the size of the lower file. */
@@ -843,13 +819,6 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
vmtruncate(lower_dentry->d_inode,
lower_size_after_truncate);
}
- /* Update the access times */
- lower_dentry->d_inode->i_mtime = lower_dentry->d_inode->i_ctime
- = CURRENT_TIME;
- mark_inode_dirty_sync(inode);
-out_fput:
- if ((rc = ecryptfs_close_lower_file(lower_file)))
- printk(KERN_ERR "Error closing lower_file\n");
out_free:
if (ecryptfs_file_to_private(&fake_ecryptfs_file))
kmem_cache_free(ecryptfs_file_info_cache,
@@ -909,23 +878,12 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
else if (S_ISREG(dentry->d_inode->i_mode)
&& (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
|| !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) {
- struct vfsmount *lower_mnt;
- struct file *lower_file = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
- int lower_flags;
-
- lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
- lower_flags = O_RDONLY;
- if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry,
- lower_mnt, lower_flags))) {
- printk(KERN_ERR
- "Error opening lower file; rc = [%d]\n", rc);
- mutex_unlock(&crypt_stat->cs_mutex);
- goto out;
- }
+
mount_crypt_stat = &ecryptfs_superblock_to_private(
dentry->d_sb)->mount_crypt_stat;
- if ((rc = ecryptfs_read_metadata(dentry, lower_file))) {
+ rc = ecryptfs_read_metadata(dentry);
+ if (rc) {
if (!(mount_crypt_stat->flags
& ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
rc = -EIO;
@@ -935,16 +893,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
"enabled; returning -EIO\n");
mutex_unlock(&crypt_stat->cs_mutex);
- fput(lower_file);
goto out;
}
rc = 0;
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
mutex_unlock(&crypt_stat->cs_mutex);
- fput(lower_file);
goto out;
}
- fput(lower_file);
}
mutex_unlock(&crypt_stat->cs_mutex);
if (ia->ia_valid & ATTR_SIZE) {
@@ -959,6 +914,14 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
if (rc < 0)
goto out;
}
+
+ /*
+ * mode change is for clearing setuid/setgid bits. Allow lower fs
+ * to interpret this in its own way.
+ */
+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+ ia->ia_valid &= ~ATTR_MODE;
+
rc = notify_change(lower_dentry, ia);
out:
fsstack_copy_attr_all(inode, lower_inode, NULL);
@@ -986,13 +949,11 @@ out:
}
ssize_t
-ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
- size_t size)
+ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
+ void *value, size_t size)
{
int rc = 0;
- struct dentry *lower_dentry;
- lower_dentry = ecryptfs_dentry_to_lower(dentry);
if (!lower_dentry->d_inode->i_op->getxattr) {
rc = -ENOSYS;
goto out;
@@ -1005,6 +966,14 @@ out:
return rc;
}
+ssize_t
+ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
+ size_t size)
+{
+ return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), name,
+ value, size);
+}
+
static ssize_t
ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
{
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index b550dea8eee..89d9710dd63 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -39,7 +39,7 @@
* determine the type of error, make appropriate log entries, and
* return an error code.
*/
-int process_request_key_err(long err_code)
+static int process_request_key_err(long err_code)
{
int rc = 0;
@@ -71,7 +71,7 @@ int process_request_key_err(long err_code)
* address; zero on error
* @length_size: The number of bytes occupied by the encoded length
*
- * Returns Zero on success
+ * Returns zero on success; non-zero on error
*/
static int parse_packet_length(unsigned char *data, size_t *size,
size_t *length_size)
@@ -106,11 +106,11 @@ out:
/**
* write_packet_length
- * @dest: The byte array target into which to write the
- * length. Must have at least 5 bytes allocated.
+ * @dest: The byte array target into which to write the length. Must
+ * have at least 5 bytes allocated.
* @size: The length to write.
- * @packet_size_length: The number of bytes used to encode the
- * packet length is written to this address.
+ * @packet_size_length: The number of bytes used to encode the packet
+ * length is written to this address.
*
* Returns zero on success; non-zero on error.
*/
@@ -396,26 +396,53 @@ out:
return rc;
}
+static int
+ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok)
+{
+ int rc = 0;
+
+ (*sig) = NULL;
+ switch (auth_tok->token_type) {
+ case ECRYPTFS_PASSWORD:
+ (*sig) = auth_tok->token.password.signature;
+ break;
+ case ECRYPTFS_PRIVATE_KEY:
+ (*sig) = auth_tok->token.private_key.signature;
+ break;
+ default:
+ printk(KERN_ERR "Cannot get sig for auth_tok of type [%d]\n",
+ auth_tok->token_type);
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
/**
- * decrypt_pki_encrypted_session_key - Decrypt the session key with
- * the given auth_tok.
+ * decrypt_pki_encrypted_session_key - Decrypt the session key with the given auth_tok.
+ * @auth_tok: The key authentication token used to decrypt the session key
+ * @crypt_stat: The cryptographic context
*
- * Returns Zero on success; non-zero error otherwise.
+ * Returns zero on success; non-zero error otherwise.
*/
-static int decrypt_pki_encrypted_session_key(
- struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
- struct ecryptfs_auth_tok *auth_tok,
- struct ecryptfs_crypt_stat *crypt_stat)
+static int
+decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_crypt_stat *crypt_stat)
{
u16 cipher_code = 0;
struct ecryptfs_msg_ctx *msg_ctx;
struct ecryptfs_message *msg = NULL;
+ char *auth_tok_sig;
char *netlink_message;
size_t netlink_message_length;
int rc;
- rc = write_tag_64_packet(mount_crypt_stat->global_auth_tok_sig,
- &(auth_tok->session_key),
+ rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
+ if (rc) {
+ printk(KERN_ERR "Unrecognized auth tok type: [%d]\n",
+ auth_tok->token_type);
+ goto out;
+ }
+ rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key),
&netlink_message, &netlink_message_length);
if (rc) {
ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet");
@@ -465,40 +492,33 @@ out:
static void wipe_auth_tok_list(struct list_head *auth_tok_list_head)
{
- struct list_head *walker;
struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
+ struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
- walker = auth_tok_list_head->next;
- while (walker != auth_tok_list_head) {
- auth_tok_list_item =
- list_entry(walker, struct ecryptfs_auth_tok_list_item,
- list);
- walker = auth_tok_list_item->list.next;
- memset(auth_tok_list_item, 0,
- sizeof(struct ecryptfs_auth_tok_list_item));
+ list_for_each_entry_safe(auth_tok_list_item, auth_tok_list_item_tmp,
+ auth_tok_list_head, list) {
+ list_del(&auth_tok_list_item->list);
kmem_cache_free(ecryptfs_auth_tok_list_item_cache,
auth_tok_list_item);
}
- auth_tok_list_head->next = NULL;
}
struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
-
/**
* parse_tag_1_packet
- * @crypt_stat: The cryptographic context to modify based on packet
- * contents.
+ * @crypt_stat: The cryptographic context to modify based on packet contents
* @data: The raw bytes of the packet.
* @auth_tok_list: eCryptfs parses packets into authentication tokens;
- * a new authentication token will be placed at the end
- * of this list for this packet.
+ * a new authentication token will be placed at the
+ * end of this list for this packet.
* @new_auth_tok: Pointer to a pointer to memory that this function
* allocates; sets the memory address of the pointer to
* NULL on error. This object is added to the
* auth_tok_list.
* @packet_size: This function writes the size of the parsed packet
* into this memory location; zero on error.
+ * @max_packet_size: The maximum allowable packet size
*
* Returns zero on success; non-zero on error.
*/
@@ -515,72 +535,65 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat,
(*packet_size) = 0;
(*new_auth_tok) = NULL;
-
- /* we check that:
- * one byte for the Tag 1 ID flag
- * two bytes for the body size
- * do not exceed the maximum_packet_size
+ /**
+ * This format is inspired by OpenPGP; see RFC 2440
+ * packet tag 1
+ *
+ * Tag 1 identifier (1 byte)
+ * Max Tag 1 packet size (max 3 bytes)
+ * Version (1 byte)
+ * Key identifier (8 bytes; ECRYPTFS_SIG_SIZE)
+ * Cipher identifier (1 byte)
+ * Encrypted key size (arbitrary)
+ *
+ * 12 bytes minimum packet size
*/
- if (unlikely((*packet_size) + 3 > max_packet_size)) {
- ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+ if (unlikely(max_packet_size < 12)) {
+ printk(KERN_ERR "Invalid max packet size; must be >=12\n");
rc = -EINVAL;
goto out;
}
- /* check for Tag 1 identifier - one byte */
if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) {
- ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n",
- ECRYPTFS_TAG_1_PACKET_TYPE);
+ printk(KERN_ERR "Enter w/ first byte != 0x%.2x\n",
+ ECRYPTFS_TAG_1_PACKET_TYPE);
rc = -EINVAL;
goto out;
}
/* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or
* at end of function upon failure */
auth_tok_list_item =
- kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache,
- GFP_KERNEL);
+ kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache,
+ GFP_KERNEL);
if (!auth_tok_list_item) {
- ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n");
+ printk(KERN_ERR "Unable to allocate memory\n");
rc = -ENOMEM;
goto out;
}
- memset(auth_tok_list_item, 0,
- sizeof(struct ecryptfs_auth_tok_list_item));
(*new_auth_tok) = &auth_tok_list_item->auth_tok;
- /* check for body size - one to two bytes
- *
- * ***** TAG 1 Packet Format *****
- * | version number | 1 byte |
- * | key ID | 8 bytes |
- * | public key algorithm | 1 byte |
- * | encrypted session key | arbitrary |
- */
rc = parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
if (rc) {
- ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
- "rc = [%d]\n", rc);
+ printk(KERN_WARNING "Error parsing packet length; "
+ "rc = [%d]\n", rc);
goto out_free;
}
- if (unlikely(body_size < (0x02 + ECRYPTFS_SIG_SIZE))) {
- ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
- body_size);
+ if (unlikely(body_size < (ECRYPTFS_SIG_SIZE + 2))) {
+ printk(KERN_WARNING "Invalid body size ([%td])\n", body_size);
rc = -EINVAL;
goto out_free;
}
(*packet_size) += length_size;
if (unlikely((*packet_size) + body_size > max_packet_size)) {
- ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+ printk(KERN_WARNING "Packet size exceeds max\n");
rc = -EINVAL;
goto out_free;
}
- /* Version 3 (from RFC2440) - one byte */
if (unlikely(data[(*packet_size)++] != 0x03)) {
- ecryptfs_printk(KERN_DEBUG, "Unknown version number "
- "[%d]\n", data[(*packet_size) - 1]);
+ printk(KERN_WARNING "Unknown version number [%d]\n",
+ data[(*packet_size) - 1]);
rc = -EINVAL;
goto out_free;
}
- /* Read Signature */
ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature,
&data[(*packet_size)], ECRYPTFS_SIG_SIZE);
*packet_size += ECRYPTFS_SIG_SIZE;
@@ -588,27 +601,23 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat,
* know which public key encryption algorithm was used */
(*packet_size)++;
(*new_auth_tok)->session_key.encrypted_key_size =
- body_size - (0x02 + ECRYPTFS_SIG_SIZE);
+ body_size - (ECRYPTFS_SIG_SIZE + 2);
if ((*new_auth_tok)->session_key.encrypted_key_size
> ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
- ecryptfs_printk(KERN_ERR, "Tag 1 packet contains key larger "
- "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES");
+ printk(KERN_WARNING "Tag 1 packet contains key larger "
+ "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES");
rc = -EINVAL;
goto out;
}
- ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
- (*new_auth_tok)->session_key.encrypted_key_size);
memcpy((*new_auth_tok)->session_key.encrypted_key,
- &data[(*packet_size)], (body_size - 0x02 - ECRYPTFS_SIG_SIZE));
+ &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2)));
(*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size;
(*new_auth_tok)->session_key.flags &=
~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
(*new_auth_tok)->session_key.flags |=
ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
(*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY;
- (*new_auth_tok)->flags |= ECRYPTFS_PRIVATE_KEY;
- /* TODO: Why are we setting this flag here? Don't we want the
- * userspace to decrypt the session key? */
+ (*new_auth_tok)->flags = 0;
(*new_auth_tok)->session_key.flags &=
~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
(*new_auth_tok)->session_key.flags &=
@@ -658,22 +667,30 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
(*packet_size) = 0;
(*new_auth_tok) = NULL;
-
- /* we check that:
- * one byte for the Tag 3 ID flag
- * two bytes for the body size
- * do not exceed the maximum_packet_size
+ /**
+ *This format is inspired by OpenPGP; see RFC 2440
+ * packet tag 3
+ *
+ * Tag 3 identifier (1 byte)
+ * Max Tag 3 packet size (max 3 bytes)
+ * Version (1 byte)
+ * Cipher code (1 byte)
+ * S2K specifier (1 byte)
+ * Hash identifier (1 byte)
+ * Salt (ECRYPTFS_SALT_SIZE)
+ * Hash iterations (1 byte)
+ * Encrypted key (arbitrary)
+ *
+ * (ECRYPTFS_SALT_SIZE + 7) minimum packet size
*/
- if (unlikely((*packet_size) + 3 > max_packet_size)) {
- ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+ if (max_packet_size < (ECRYPTFS_SALT_SIZE + 7)) {
+ printk(KERN_ERR "Max packet size too large\n");
rc = -EINVAL;
goto out;
}
-
- /* check for Tag 3 identifyer - one byte */
if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) {
- ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n",
- ECRYPTFS_TAG_3_PACKET_TYPE);
+ printk(KERN_ERR "First byte != 0x%.2x; invalid packet\n",
+ ECRYPTFS_TAG_3_PACKET_TYPE);
rc = -EINVAL;
goto out;
}
@@ -682,56 +699,37 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
auth_tok_list_item =
kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL);
if (!auth_tok_list_item) {
- ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n");
+ printk(KERN_ERR "Unable to allocate memory\n");
rc = -ENOMEM;
goto out;
}
(*new_auth_tok) = &auth_tok_list_item->auth_tok;
-
- /* check for body size - one to two bytes */
rc = parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
if (rc) {
- ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
- "rc = [%d]\n", rc);
+ printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n",
+ rc);
goto out_free;
}
- if (unlikely(body_size < (0x05 + ECRYPTFS_SALT_SIZE))) {
- ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
- body_size);
+ if (unlikely(body_size < (ECRYPTFS_SALT_SIZE + 5))) {
+ printk(KERN_WARNING "Invalid body size ([%td])\n", body_size);
rc = -EINVAL;
goto out_free;
}
(*packet_size) += length_size;
-
- /* now we know the length of the remainting Tag 3 packet size:
- * 5 fix bytes for: version string, cipher, S2K ID, hash algo,
- * number of hash iterations
- * ECRYPTFS_SALT_SIZE bytes for salt
- * body_size bytes minus the stuff above is the encrypted key size
- */
if (unlikely((*packet_size) + body_size > max_packet_size)) {
- ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+ printk(KERN_ERR "Packet size exceeds max\n");
rc = -EINVAL;
goto out_free;
}
-
- /* There are 5 characters of additional information in the
- * packet */
(*new_auth_tok)->session_key.encrypted_key_size =
- body_size - (0x05 + ECRYPTFS_SALT_SIZE);
- ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
- (*new_auth_tok)->session_key.encrypted_key_size);
-
- /* Version 4 (from RFC2440) - one byte */
+ (body_size - (ECRYPTFS_SALT_SIZE + 5));
if (unlikely(data[(*packet_size)++] != 0x04)) {
- ecryptfs_printk(KERN_DEBUG, "Unknown version number "
- "[%d]\n", data[(*packet_size) - 1]);
+ printk(KERN_WARNING "Unknown version number [%d]\n",
+ data[(*packet_size) - 1]);
rc = -EINVAL;
goto out_free;
}
-
- /* cipher - one byte */
ecryptfs_cipher_code_to_string(crypt_stat->cipher,
(u16)data[(*packet_size)]);
/* A little extra work to differentiate among the AES key
@@ -745,33 +743,26 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
(*new_auth_tok)->session_key.encrypted_key_size;
}
ecryptfs_init_crypt_ctx(crypt_stat);
- /* S2K identifier 3 (from RFC2440) */
if (unlikely(data[(*packet_size)++] != 0x03)) {
- ecryptfs_printk(KERN_ERR, "Only S2K ID 3 is currently "
- "supported\n");
+ printk(KERN_WARNING "Only S2K ID 3 is currently supported\n");
rc = -ENOSYS;
goto out_free;
}
-
/* TODO: finish the hash mapping */
- /* hash algorithm - one byte */
switch (data[(*packet_size)++]) {
case 0x01: /* See RFC2440 for these numbers and their mappings */
/* Choose MD5 */
- /* salt - ECRYPTFS_SALT_SIZE bytes */
memcpy((*new_auth_tok)->token.password.salt,
&data[(*packet_size)], ECRYPTFS_SALT_SIZE);
(*packet_size) += ECRYPTFS_SALT_SIZE;
-
/* This conversion was taken straight from RFC2440 */
- /* number of hash iterations - one byte */
(*new_auth_tok)->token.password.hash_iterations =
((u32) 16 + (data[(*packet_size)] & 15))
<< ((data[(*packet_size)] >> 4) + 6);
(*packet_size)++;
-
- /* encrypted session key -
- * (body_size-5-ECRYPTFS_SALT_SIZE) bytes */
+ /* Friendly reminder:
+ * (*new_auth_tok)->session_key.encrypted_key_size =
+ * (body_size - (ECRYPTFS_SALT_SIZE + 5)); */
memcpy((*new_auth_tok)->session_key.encrypted_key,
&data[(*packet_size)],
(*new_auth_tok)->session_key.encrypted_key_size);
@@ -781,7 +772,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
(*new_auth_tok)->session_key.flags |=
ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
- (*new_auth_tok)->token.password.hash_algo = 0x01;
+ (*new_auth_tok)->token.password.hash_algo = 0x01; /* MD5 */
break;
default:
ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: "
@@ -837,82 +828,61 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
(*packet_size) = 0;
(*tag_11_contents_size) = 0;
-
- /* check that:
- * one byte for the Tag 11 ID flag
- * two bytes for the Tag 11 length
- * do not exceed the maximum_packet_size
+ /* This format is inspired by OpenPGP; see RFC 2440
+ * packet tag 11
+ *
+ * Tag 11 identifier (1 byte)
+ * Max Tag 11 packet size (max 3 bytes)
+ * Binary format specifier (1 byte)
+ * Filename length (1 byte)
+ * Filename ("_CONSOLE") (8 bytes)
+ * Modification date (4 bytes)
+ * Literal data (arbitrary)
+ *
+ * We need at least 16 bytes of data for the packet to even be
+ * valid.
*/
- if (unlikely((*packet_size) + 3 > max_packet_size)) {
- ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+ if (max_packet_size < 16) {
+ printk(KERN_ERR "Maximum packet size too small\n");
rc = -EINVAL;
goto out;
}
-
- /* check for Tag 11 identifyer - one byte */
if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) {
- ecryptfs_printk(KERN_WARNING,
- "Invalid tag 11 packet format\n");
+ printk(KERN_WARNING "Invalid tag 11 packet format\n");
rc = -EINVAL;
goto out;
}
-
- /* get Tag 11 content length - one or two bytes */
rc = parse_packet_length(&data[(*packet_size)], &body_size,
&length_size);
if (rc) {
- ecryptfs_printk(KERN_WARNING,
- "Invalid tag 11 packet format\n");
+ printk(KERN_WARNING "Invalid tag 11 packet format\n");
goto out;
}
- (*packet_size) += length_size;
-
- if (body_size < 13) {
- ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
- body_size);
+ if (body_size < 14) {
+ printk(KERN_WARNING "Invalid body size ([%td])\n", body_size);
rc = -EINVAL;
goto out;
}
- /* We have 13 bytes of surrounding packet values */
- (*tag_11_contents_size) = (body_size - 13);
-
- /* now we know the length of the remainting Tag 11 packet size:
- * 14 fix bytes for: special flag one, special flag two,
- * 12 skipped bytes
- * body_size bytes minus the stuff above is the Tag 11 content
- */
- /* FIXME why is the body size one byte smaller than the actual
- * size of the body?
- * this seems to be an error here as well as in
- * write_tag_11_packet() */
+ (*packet_size) += length_size;
+ (*tag_11_contents_size) = (body_size - 14);
if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) {
- ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
+ printk(KERN_ERR "Packet size exceeds max\n");
rc = -EINVAL;
goto out;
}
-
- /* special flag one - one byte */
if (data[(*packet_size)++] != 0x62) {
- ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n");
+ printk(KERN_WARNING "Unrecognizable packet\n");
rc = -EINVAL;
goto out;
}
-
- /* special flag two - one byte */
if (data[(*packet_size)++] != 0x08) {
- ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n");
+ printk(KERN_WARNING "Unrecognizable packet\n");
rc = -EINVAL;
goto out;
}
-
- /* skip the next 12 bytes */
- (*packet_size) += 12; /* We don't care about the filename or
- * the timestamp */
-
- /* get the Tag 11 contents - tag_11_contents_size bytes */
+ (*packet_size) += 12; /* Ignore filename and modification date */
memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size));
(*packet_size) += (*tag_11_contents_size);
-
out:
if (rc) {
(*packet_size) = 0;
@@ -921,130 +891,229 @@ out:
return rc;
}
+static int
+ecryptfs_find_global_auth_tok_for_sig(
+ struct ecryptfs_global_auth_tok **global_auth_tok,
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig)
+{
+ struct ecryptfs_global_auth_tok *walker;
+ int rc = 0;
+
+ (*global_auth_tok) = NULL;
+ mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
+ list_for_each_entry(walker,
+ &mount_crypt_stat->global_auth_tok_list,
+ mount_crypt_stat_list) {
+ if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) {
+ (*global_auth_tok) = walker;
+ goto out;
+ }
+ }
+ rc = -EINVAL;
+out:
+ mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
+ return rc;
+}
+
/**
- * decrypt_session_key - Decrypt the session key with the given auth_tok.
+ * ecryptfs_verify_version
+ * @version: The version number to confirm
*
- * Returns Zero on success; non-zero error otherwise.
+ * Returns zero on good version; non-zero otherwise
*/
-static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
- struct ecryptfs_crypt_stat *crypt_stat)
+static int ecryptfs_verify_version(u16 version)
{
- struct ecryptfs_password *password_s_ptr;
- struct scatterlist src_sg[2], dst_sg[2];
- struct mutex *tfm_mutex = NULL;
- char *encrypted_session_key;
- char *session_key;
+ int rc = 0;
+ unsigned char major;
+ unsigned char minor;
+
+ major = ((version >> 8) & 0xFF);
+ minor = (version & 0xFF);
+ if (major != ECRYPTFS_VERSION_MAJOR) {
+ ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
+ "Expected [%d]; got [%d]\n",
+ ECRYPTFS_VERSION_MAJOR, major);
+ rc = -EINVAL;
+ goto out;
+ }
+ if (minor != ECRYPTFS_VERSION_MINOR) {
+ ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
+ "Expected [%d]; got [%d]\n",
+ ECRYPTFS_VERSION_MINOR, minor);
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
+ struct ecryptfs_auth_tok **auth_tok,
+ char *sig)
+{
+ int rc = 0;
+
+ (*auth_tok_key) = request_key(&key_type_user, sig, NULL);
+ if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
+ printk(KERN_ERR "Could not find key with description: [%s]\n",
+ sig);
+ process_request_key_err(PTR_ERR(*auth_tok_key));
+ rc = -EINVAL;
+ goto out;
+ }
+ (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
+ if (ecryptfs_verify_version((*auth_tok)->version)) {
+ printk(KERN_ERR
+ "Data structure version mismatch. "
+ "Userspace tools must match eCryptfs "
+ "kernel module with major version [%d] "
+ "and minor version [%d]\n",
+ ECRYPTFS_VERSION_MAJOR,
+ ECRYPTFS_VERSION_MINOR);
+ rc = -EINVAL;
+ goto out;
+ }
+ if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
+ && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
+ printk(KERN_ERR "Invalid auth_tok structure "
+ "returned from key query\n");
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_find_auth_tok_for_sig
+ * @auth_tok: Set to the matching auth_tok; NULL if not found
+ * @crypt_stat: inode crypt_stat crypto context
+ * @sig: Sig of auth_tok to find
+ *
+ * For now, this function simply looks at the registered auth_tok's
+ * linked off the mount_crypt_stat, so all the auth_toks that can be
+ * used must be registered at mount time. This function could
+ * potentially try a lot harder to find auth_tok's (e.g., by calling
+ * out to ecryptfsd to dynamically retrieve an auth_tok object) so
+ * that static registration of auth_tok's will no longer be necessary.
+ *
+ * Returns zero on no error; non-zero on error
+ */
+static int
+ecryptfs_find_auth_tok_for_sig(
+ struct ecryptfs_auth_tok **auth_tok,
+ struct ecryptfs_crypt_stat *crypt_stat, char *sig)
+{
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+ crypt_stat->mount_crypt_stat;
+ struct ecryptfs_global_auth_tok *global_auth_tok;
+ int rc = 0;
+
+ (*auth_tok) = NULL;
+ if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
+ mount_crypt_stat, sig)) {
+ struct key *auth_tok_key;
+
+ rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok,
+ sig);
+ } else
+ (*auth_tok) = global_auth_tok->global_auth_tok;
+ return rc;
+}
+
+/**
+ * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok.
+ * @auth_tok: The passphrase authentication token to use to encrypt the FEK
+ * @crypt_stat: The cryptographic context
+ *
+ * Returns zero on success; non-zero error otherwise
+ */
+static int
+decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_crypt_stat *crypt_stat)
+{
+ struct scatterlist dst_sg;
+ struct scatterlist src_sg;
+ struct mutex *tfm_mutex;
struct blkcipher_desc desc = {
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
};
int rc = 0;
- password_s_ptr = &auth_tok->token.password;
- if (password_s_ptr->flags & ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)
- ecryptfs_printk(KERN_DEBUG, "Session key encryption key "
- "set; skipping key generation\n");
- ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])"
- ":\n",
- password_s_ptr->session_key_encryption_key_bytes);
- if (ecryptfs_verbosity > 0)
- ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key,
- password_s_ptr->
- session_key_encryption_key_bytes);
- if (!strcmp(crypt_stat->cipher,
- crypt_stat->mount_crypt_stat->global_default_cipher_name)
- && crypt_stat->mount_crypt_stat->global_key_tfm) {
- desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
- tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
- } else {
- char *full_alg_name;
-
- rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
- crypt_stat->cipher,
- "ecb");
- if (rc)
- goto out;
- desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
- CRYPTO_ALG_ASYNC);
- kfree(full_alg_name);
- if (IS_ERR(desc.tfm)) {
- rc = PTR_ERR(desc.tfm);
- printk(KERN_ERR "Error allocating crypto context; "
- "rc = [%d]\n", rc);
- goto out;
- }
- crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(
+ KERN_DEBUG, "Session key encryption key (size [%d]):\n",
+ auth_tok->token.password.session_key_encryption_key_bytes);
+ ecryptfs_dump_hex(
+ auth_tok->token.password.session_key_encryption_key,
+ auth_tok->token.password.session_key_encryption_key_bytes);
+ }
+ rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,
+ crypt_stat->cipher);
+ if (unlikely(rc)) {
+ printk(KERN_ERR "Internal error whilst attempting to get "
+ "tfm and mutex for cipher name [%s]; rc = [%d]\n",
+ crypt_stat->cipher, rc);
+ goto out;
}
- if (tfm_mutex)
- mutex_lock(tfm_mutex);
- rc = crypto_blkcipher_setkey(desc.tfm,
- password_s_ptr->session_key_encryption_key,
- crypt_stat->key_size);
- if (rc < 0) {
+ rc = virt_to_scatterlist(auth_tok->session_key.encrypted_key,
+ auth_tok->session_key.encrypted_key_size,
+ &src_sg, 1);
+ if (rc != 1) {
+ printk(KERN_ERR "Internal error whilst attempting to convert "
+ "auth_tok->session_key.encrypted_key to scatterlist; "
+ "expected rc = 1; got rc = [%d]. "
+ "auth_tok->session_key.encrypted_key_size = [%d]\n", rc,
+ auth_tok->session_key.encrypted_key_size);
+ goto out;
+ }
+ auth_tok->session_key.decrypted_key_size =
+ auth_tok->session_key.encrypted_key_size;
+ rc = virt_to_scatterlist(auth_tok->session_key.decrypted_key,
+ auth_tok->session_key.decrypted_key_size,
+ &dst_sg, 1);
+ if (rc != 1) {
+ printk(KERN_ERR "Internal error whilst attempting to convert "
+ "auth_tok->session_key.decrypted_key to scatterlist; "
+ "expected rc = 1; got rc = [%d]\n", rc);
+ goto out;
+ }
+ mutex_lock(tfm_mutex);
+ rc = crypto_blkcipher_setkey(
+ desc.tfm, auth_tok->token.password.session_key_encryption_key,
+ crypt_stat->key_size);
+ if (unlikely(rc < 0)) {
+ mutex_unlock(tfm_mutex);
printk(KERN_ERR "Error setting key for crypto context\n");
rc = -EINVAL;
- goto out_free_tfm;
- }
- /* TODO: virt_to_scatterlist */
- encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
- if (!encrypted_session_key) {
- ecryptfs_printk(KERN_ERR, "Out of memory\n");
- rc = -ENOMEM;
- goto out_free_tfm;
+ goto out;
}
- session_key = (char *)__get_free_page(GFP_KERNEL);
- if (!session_key) {
- kfree(encrypted_session_key);
- ecryptfs_printk(KERN_ERR, "Out of memory\n");
- rc = -ENOMEM;
- goto out_free_tfm;
- }
- memcpy(encrypted_session_key, auth_tok->session_key.encrypted_key,
- auth_tok->session_key.encrypted_key_size);
- src_sg[0].page = virt_to_page(encrypted_session_key);
- src_sg[0].offset = 0;
- BUG_ON(auth_tok->session_key.encrypted_key_size > PAGE_CACHE_SIZE);
- src_sg[0].length = auth_tok->session_key.encrypted_key_size;
- dst_sg[0].page = virt_to_page(session_key);
- dst_sg[0].offset = 0;
- auth_tok->session_key.decrypted_key_size =
- auth_tok->session_key.encrypted_key_size;
- dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
- rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
+ rc = crypto_blkcipher_decrypt(&desc, &dst_sg, &src_sg,
auth_tok->session_key.encrypted_key_size);
- if (rc) {
+ mutex_unlock(tfm_mutex);
+ if (unlikely(rc)) {
printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc);
- goto out_free_memory;
+ goto out;
}
- auth_tok->session_key.decrypted_key_size =
- auth_tok->session_key.encrypted_key_size;
- memcpy(auth_tok->session_key.decrypted_key, session_key,
- auth_tok->session_key.decrypted_key_size);
auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY;
memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
auth_tok->session_key.decrypted_key_size);
crypt_stat->flags |= ECRYPTFS_KEY_VALID;
- ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n");
- if (ecryptfs_verbosity > 0)
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(KERN_DEBUG, "FEK of size [%d]:\n",
+ crypt_stat->key_size);
ecryptfs_dump_hex(crypt_stat->key,
crypt_stat->key_size);
-out_free_memory:
- memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
- free_page((unsigned long)encrypted_session_key);
- memset(session_key, 0, PAGE_CACHE_SIZE);
- free_page((unsigned long)session_key);
-out_free_tfm:
- if (tfm_mutex)
- mutex_unlock(tfm_mutex);
- else
- crypto_free_blkcipher(desc.tfm);
+ }
out:
return rc;
}
/**
* ecryptfs_parse_packet_set
- * @dest: The header page in memory
- * @version: Version of file format, to guide parsing behavior
+ * @crypt_stat: The cryptographic context
+ * @src: Virtual address of region of memory containing the packets
+ * @ecryptfs_dentry: The eCryptfs dentry associated with the packet set
*
* Get crypt_stat to have the file's session key if the requisite key
* is available to decrypt the session key.
@@ -1058,25 +1127,22 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
struct dentry *ecryptfs_dentry)
{
size_t i = 0;
- size_t found_auth_tok = 0;
+ size_t found_auth_tok;
size_t next_packet_is_auth_tok_packet;
- char sig[ECRYPTFS_SIG_SIZE_HEX];
struct list_head auth_tok_list;
- struct list_head *walker;
- struct ecryptfs_auth_tok *chosen_auth_tok = NULL;
- struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
- &ecryptfs_superblock_to_private(
- ecryptfs_dentry->d_sb)->mount_crypt_stat;
- struct ecryptfs_auth_tok *candidate_auth_tok = NULL;
+ struct ecryptfs_auth_tok *matching_auth_tok;
+ struct ecryptfs_auth_tok *candidate_auth_tok;
+ char *candidate_auth_tok_sig;
size_t packet_size;
struct ecryptfs_auth_tok *new_auth_tok;
unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE];
+ struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
size_t tag_11_contents_size;
size_t tag_11_packet_size;
int rc = 0;
INIT_LIST_HEAD(&auth_tok_list);
- /* Parse the header to find as many packets as we can, these will be
+ /* Parse the header to find as many packets as we can; these will be
* added the our &auth_tok_list */
next_packet_is_auth_tok_packet = 1;
while (next_packet_is_auth_tok_packet) {
@@ -1155,73 +1221,85 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
}
}
if (list_empty(&auth_tok_list)) {
- rc = -EINVAL; /* Do not support non-encrypted files in
- * the 0.1 release */
+ printk(KERN_ERR "The lower file appears to be a non-encrypted "
+ "eCryptfs file; this is not supported in this version "
+ "of the eCryptfs kernel module\n");
+ rc = -EINVAL;
goto out;
}
- /* If we have a global auth tok, then we should try to use
- * it */
- if (mount_crypt_stat->global_auth_tok) {
- memcpy(sig, mount_crypt_stat->global_auth_tok_sig,
- ECRYPTFS_SIG_SIZE_HEX);
- chosen_auth_tok = mount_crypt_stat->global_auth_tok;
- } else
- BUG(); /* We should always have a global auth tok in
- * the 0.1 release */
- /* Scan list to see if our chosen_auth_tok works */
- list_for_each(walker, &auth_tok_list) {
- struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
- auth_tok_list_item =
- list_entry(walker, struct ecryptfs_auth_tok_list_item,
- list);
+ /* auth_tok_list contains the set of authentication tokens
+ * parsed from the metadata. We need to find a matching
+ * authentication token that has the secret component(s)
+ * necessary to decrypt the EFEK in the auth_tok parsed from
+ * the metadata. There may be several potential matches, but
+ * just one will be sufficient to decrypt to get the FEK. */
+find_next_matching_auth_tok:
+ found_auth_tok = 0;
+ list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
candidate_auth_tok = &auth_tok_list_item->auth_tok;
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(KERN_DEBUG,
"Considering cadidate auth tok:\n");
ecryptfs_dump_auth_tok(candidate_auth_tok);
}
- /* TODO: Replace ECRYPTFS_SIG_SIZE_HEX w/ dynamic value */
- if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD
- && !strncmp(candidate_auth_tok->token.password.signature,
- sig, ECRYPTFS_SIG_SIZE_HEX)) {
- found_auth_tok = 1;
- goto leave_list;
- /* TODO: Transfer the common salt into the
- * crypt_stat salt */
- } else if ((candidate_auth_tok->token_type
- == ECRYPTFS_PRIVATE_KEY)
- && !strncmp(candidate_auth_tok->token.private_key.signature,
- sig, ECRYPTFS_SIG_SIZE_HEX)) {
+ rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig,
+ candidate_auth_tok);
+ if (rc) {
+ printk(KERN_ERR
+ "Unrecognized candidate auth tok type: [%d]\n",
+ candidate_auth_tok->token_type);
+ rc = -EINVAL;
+ goto out_wipe_list;
+ }
+ ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, crypt_stat,
+ candidate_auth_tok_sig);
+ if (matching_auth_tok) {
found_auth_tok = 1;
- goto leave_list;
+ goto found_matching_auth_tok;
}
}
if (!found_auth_tok) {
- ecryptfs_printk(KERN_ERR, "Could not find authentication "
- "token on temporary list for sig [%.*s]\n",
- ECRYPTFS_SIG_SIZE_HEX, sig);
+ ecryptfs_printk(KERN_ERR, "Could not find a usable "
+ "authentication token\n");
rc = -EIO;
goto out_wipe_list;
}
-leave_list:
- rc = -ENOTSUPP;
+found_matching_auth_tok:
if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
memcpy(&(candidate_auth_tok->token.private_key),
- &(chosen_auth_tok->token.private_key),
+ &(matching_auth_tok->token.private_key),
sizeof(struct ecryptfs_private_key));
- rc = decrypt_pki_encrypted_session_key(mount_crypt_stat,
- candidate_auth_tok,
+ rc = decrypt_pki_encrypted_session_key(candidate_auth_tok,
crypt_stat);
} else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) {
memcpy(&(candidate_auth_tok->token.password),
- &(chosen_auth_tok->token.password),
+ &(matching_auth_tok->token.password),
sizeof(struct ecryptfs_password));
- rc = decrypt_session_key(candidate_auth_tok, crypt_stat);
+ rc = decrypt_passphrase_encrypted_session_key(
+ candidate_auth_tok, crypt_stat);
}
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error decrypting the "
- "session key; rc = [%d]\n", rc);
- goto out_wipe_list;
+ struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
+
+ ecryptfs_printk(KERN_WARNING, "Error decrypting the "
+ "session key for authentication token with sig "
+ "[%.*s]; rc = [%d]. Removing auth tok "
+ "candidate from the list and searching for "
+ "the next match.\n", candidate_auth_tok_sig,
+ ECRYPTFS_SIG_SIZE_HEX, rc);
+ list_for_each_entry_safe(auth_tok_list_item,
+ auth_tok_list_item_tmp,
+ &auth_tok_list, list) {
+ if (candidate_auth_tok
+ == &auth_tok_list_item->auth_tok) {
+ list_del(&auth_tok_list_item->list);
+ kmem_cache_free(
+ ecryptfs_auth_tok_list_item_cache,
+ auth_tok_list_item);
+ goto find_next_matching_auth_tok;
+ }
+ }
+ BUG();
}
rc = ecryptfs_compute_root_iv(crypt_stat);
if (rc) {
@@ -1240,6 +1318,7 @@ out_wipe_list:
out:
return rc;
}
+
static int
pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_crypt_stat *crypt_stat,
@@ -1284,22 +1363,25 @@ out:
/**
* write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet
* @dest: Buffer into which to write the packet
- * @max: Maximum number of bytes that can be writtn
+ * @remaining_bytes: Maximum number of bytes that can be writtn
+ * @auth_tok: The authentication token used for generating the tag 1 packet
+ * @crypt_stat: The cryptographic context
+ * @key_rec: The key record struct for the tag 1 packet
* @packet_size: This function will write the number of bytes that end
* up constituting the packet; set to zero on error
*
* Returns zero on success; non-zero on error.
*/
static int
-write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
+write_tag_1_packet(char *dest, size_t *remaining_bytes,
+ struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_crypt_stat *crypt_stat,
- struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
struct ecryptfs_key_record *key_rec, size_t *packet_size)
{
size_t i;
size_t encrypted_session_key_valid = 0;
- size_t key_rec_size;
size_t packet_size_length;
+ size_t max_packet_size;
int rc = 0;
(*packet_size) = 0;
@@ -1329,37 +1411,23 @@ write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size);
}
encrypted_session_key_set:
- /* Now we have a valid key_rec. Append it to the
- * key_rec set. */
- key_rec_size = (sizeof(struct ecryptfs_key_record)
- - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
- + (key_rec->enc_key_size));
- /* TODO: Include a packet size limit as a parameter to this
- * function once we have multi-packet headers (for versions
- * later than 0.1 */
- if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) {
- ecryptfs_printk(KERN_ERR, "Keyset too large\n");
- rc = -EINVAL;
- goto out;
- }
- /* ***** TAG 1 Packet Format *****
- * | version number | 1 byte |
- * | key ID | 8 bytes |
- * | public key algorithm | 1 byte |
- * | encrypted session key | arbitrary |
- */
- if ((0x02 + ECRYPTFS_SIG_SIZE + key_rec->enc_key_size) >= max) {
- ecryptfs_printk(KERN_ERR,
- "Authentication token is too large\n");
+ /* This format is inspired by OpenPGP; see RFC 2440
+ * packet tag 1 */
+ max_packet_size = (1 /* Tag 1 identifier */
+ + 3 /* Max Tag 1 packet size */
+ + 1 /* Version */
+ + ECRYPTFS_SIG_SIZE /* Key identifier */
+ + 1 /* Cipher identifier */
+ + key_rec->enc_key_size); /* Encrypted key size */
+ if (max_packet_size > (*remaining_bytes)) {
+ printk(KERN_ERR "Packet length larger than maximum allowable; "
+ "need up to [%td] bytes, but there are only [%td] "
+ "available\n", max_packet_size, (*remaining_bytes));
rc = -EINVAL;
goto out;
}
dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE;
- /* This format is inspired by OpenPGP; see RFC 2440
- * packet tag 1 */
- rc = write_packet_length(&dest[(*packet_size)],
- (0x02 + ECRYPTFS_SIG_SIZE +
- key_rec->enc_key_size),
+ rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),
&packet_size_length);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet "
@@ -1377,13 +1445,15 @@ encrypted_session_key_set:
out:
if (rc)
(*packet_size) = 0;
+ else
+ (*remaining_bytes) -= (*packet_size);
return rc;
}
/**
* write_tag_11_packet
* @dest: Target into which Tag 11 packet is to be written
- * @max: Maximum packet length
+ * @remaining_bytes: Maximum packet length
* @contents: Byte array of contents to copy in
* @contents_length: Number of bytes in contents
* @packet_length: Length of the Tag 11 packet written; zero on error
@@ -1391,54 +1461,59 @@ out:
* Returns zero on success; non-zero on error.
*/
static int
-write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length,
- size_t *packet_length)
+write_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents,
+ size_t contents_length, size_t *packet_length)
{
size_t packet_size_length;
+ size_t max_packet_size;
int rc = 0;
(*packet_length) = 0;
- if ((13 + contents_length) > max) {
+ /* This format is inspired by OpenPGP; see RFC 2440
+ * packet tag 11 */
+ max_packet_size = (1 /* Tag 11 identifier */
+ + 3 /* Max Tag 11 packet size */
+ + 1 /* Binary format specifier */
+ + 1 /* Filename length */
+ + 8 /* Filename ("_CONSOLE") */
+ + 4 /* Modification date */
+ + contents_length); /* Literal data */
+ if (max_packet_size > (*remaining_bytes)) {
+ printk(KERN_ERR "Packet length larger than maximum allowable; "
+ "need up to [%td] bytes, but there are only [%td] "
+ "available\n", max_packet_size, (*remaining_bytes));
rc = -EINVAL;
- ecryptfs_printk(KERN_ERR, "Packet length larger than "
- "maximum allowable\n");
goto out;
}
- /* General packet header */
- /* Packet tag */
dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE;
- /* Packet length */
rc = write_packet_length(&dest[(*packet_length)],
- (13 + contents_length), &packet_size_length);
+ (max_packet_size - 4), &packet_size_length);
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error generating tag 11 packet "
- "header; cannot generate packet length\n");
+ printk(KERN_ERR "Error generating tag 11 packet header; cannot "
+ "generate packet length. rc = [%d]\n", rc);
goto out;
}
(*packet_length) += packet_size_length;
- /* Tag 11 specific */
- /* One-octet field that describes how the data is formatted */
- dest[(*packet_length)++] = 0x62; /* binary data */
- /* One-octet filename length followed by filename */
+ dest[(*packet_length)++] = 0x62; /* binary data format specifier */
dest[(*packet_length)++] = 8;
memcpy(&dest[(*packet_length)], "_CONSOLE", 8);
(*packet_length) += 8;
- /* Four-octet number indicating modification date */
memset(&dest[(*packet_length)], 0x00, 4);
(*packet_length) += 4;
- /* Remainder is literal data */
memcpy(&dest[(*packet_length)], contents, contents_length);
(*packet_length) += contents_length;
out:
if (rc)
(*packet_length) = 0;
+ else
+ (*remaining_bytes) -= (*packet_length);
return rc;
}
/**
* write_tag_3_packet
* @dest: Buffer into which to write the packet
- * @max: Maximum number of bytes that can be written
+ * @remaining_bytes: Maximum number of bytes that can be written
* @auth_tok: Authentication token
* @crypt_stat: The cryptographic context
* @key_rec: encrypted key
@@ -1448,19 +1523,22 @@ write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length,
* Returns zero on success; non-zero on error.
*/
static int
-write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
+write_tag_3_packet(char *dest, size_t *remaining_bytes,
+ struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_crypt_stat *crypt_stat,
struct ecryptfs_key_record *key_rec, size_t *packet_size)
{
size_t i;
size_t encrypted_session_key_valid = 0;
char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
- struct scatterlist dest_sg[2];
- struct scatterlist src_sg[2];
+ struct scatterlist dst_sg;
+ struct scatterlist src_sg;
struct mutex *tfm_mutex = NULL;
- size_t key_rec_size;
- size_t packet_size_length;
size_t cipher_code;
+ size_t packet_size_length;
+ size_t max_packet_size;
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+ crypt_stat->mount_crypt_stat;
struct blkcipher_desc desc = {
.tfm = NULL,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP
@@ -1470,16 +1548,25 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
(*packet_size) = 0;
ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature,
ECRYPTFS_SIG_SIZE);
- encrypted_session_key_valid = 0;
- for (i = 0; i < crypt_stat->key_size; i++)
- encrypted_session_key_valid |=
- auth_tok->session_key.encrypted_key[i];
- if (encrypted_session_key_valid) {
- memcpy(key_rec->enc_key,
- auth_tok->session_key.encrypted_key,
- auth_tok->session_key.encrypted_key_size);
- goto encrypted_session_key_set;
+ rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,
+ crypt_stat->cipher);
+ if (unlikely(rc)) {
+ printk(KERN_ERR "Internal error whilst attempting to get "
+ "tfm and mutex for cipher name [%s]; rc = [%d]\n",
+ crypt_stat->cipher, rc);
+ goto out;
+ }
+ if (mount_crypt_stat->global_default_cipher_key_size == 0) {
+ struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm);
+
+ printk(KERN_WARNING "No key size specified at mount; "
+ "defaulting to [%d]\n", alg->max_keysize);
+ mount_crypt_stat->global_default_cipher_key_size =
+ alg->max_keysize;
}
+ if (crypt_stat->key_size == 0)
+ crypt_stat->key_size =
+ mount_crypt_stat->global_default_cipher_key_size;
if (auth_tok->session_key.encrypted_key_size == 0)
auth_tok->session_key.encrypted_key_size =
crypt_stat->key_size;
@@ -1487,9 +1574,24 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
&& strcmp("aes", crypt_stat->cipher) == 0) {
memset((crypt_stat->key + 24), 0, 8);
auth_tok->session_key.encrypted_key_size = 32;
- }
+ } else
+ auth_tok->session_key.encrypted_key_size = crypt_stat->key_size;
key_rec->enc_key_size =
auth_tok->session_key.encrypted_key_size;
+ encrypted_session_key_valid = 0;
+ for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++)
+ encrypted_session_key_valid |=
+ auth_tok->session_key.encrypted_key[i];
+ if (encrypted_session_key_valid) {
+ ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; "
+ "using auth_tok->session_key.encrypted_key, "
+ "where key_rec->enc_key_size = [%d]\n",
+ key_rec->enc_key_size);
+ memcpy(key_rec->enc_key,
+ auth_tok->session_key.encrypted_key,
+ key_rec->enc_key_size);
+ goto encrypted_session_key_set;
+ }
if (auth_tok->token.password.flags &
ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) {
ecryptfs_printk(KERN_DEBUG, "Using previously generated "
@@ -1508,54 +1610,32 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n");
ecryptfs_dump_hex(session_key_encryption_key, 16);
}
- rc = virt_to_scatterlist(crypt_stat->key,
- key_rec->enc_key_size, src_sg, 2);
- if (!rc) {
+ rc = virt_to_scatterlist(crypt_stat->key, key_rec->enc_key_size,
+ &src_sg, 1);
+ if (rc != 1) {
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
- "for crypt_stat session key\n");
+ "for crypt_stat session key; expected rc = 1; "
+ "got rc = [%d]. key_rec->enc_key_size = [%d]\n",
+ rc, key_rec->enc_key_size);
rc = -ENOMEM;
goto out;
}
- rc = virt_to_scatterlist(key_rec->enc_key,
- key_rec->enc_key_size, dest_sg, 2);
- if (!rc) {
+ rc = virt_to_scatterlist(key_rec->enc_key, key_rec->enc_key_size,
+ &dst_sg, 1);
+ if (rc != 1) {
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
- "for crypt_stat encrypted session key\n");
+ "for crypt_stat encrypted session key; "
+ "expected rc = 1; got rc = [%d]. "
+ "key_rec->enc_key_size = [%d]\n", rc,
+ key_rec->enc_key_size);
rc = -ENOMEM;
goto out;
}
- if (!strcmp(crypt_stat->cipher,
- crypt_stat->mount_crypt_stat->global_default_cipher_name)
- && crypt_stat->mount_crypt_stat->global_key_tfm) {
- desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
- tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
- } else {
- char *full_alg_name;
-
- rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
- crypt_stat->cipher,
- "ecb");
- if (rc)
- goto out;
- desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
- CRYPTO_ALG_ASYNC);
- kfree(full_alg_name);
- if (IS_ERR(desc.tfm)) {
- rc = PTR_ERR(desc.tfm);
- ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
- "context for cipher [%s]; rc = [%d]\n",
- crypt_stat->cipher, rc);
- goto out;
- }
- crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- }
- if (tfm_mutex)
- mutex_lock(tfm_mutex);
+ mutex_lock(tfm_mutex);
rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,
crypt_stat->key_size);
if (rc < 0) {
- if (tfm_mutex)
- mutex_unlock(tfm_mutex);
+ mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
"context; rc = [%d]\n", rc);
goto out;
@@ -1563,56 +1643,53 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
rc = 0;
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
crypt_stat->key_size);
- rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg,
+ rc = crypto_blkcipher_encrypt(&desc, &dst_sg, &src_sg,
(*key_rec).enc_key_size);
+ mutex_unlock(tfm_mutex);
if (rc) {
printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);
goto out;
}
- if (tfm_mutex)
- mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
- if (ecryptfs_verbosity > 0)
+ if (ecryptfs_verbosity > 0) {
+ ecryptfs_printk(KERN_DEBUG, "EFEK of size [%d]:\n",
+ key_rec->enc_key_size);
ecryptfs_dump_hex(key_rec->enc_key,
key_rec->enc_key_size);
-encrypted_session_key_set:
- /* Now we have a valid key_rec. Append it to the
- * key_rec set. */
- key_rec_size = (sizeof(struct ecryptfs_key_record)
- - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
- + (key_rec->enc_key_size));
- /* TODO: Include a packet size limit as a parameter to this
- * function once we have multi-packet headers (for versions
- * later than 0.1 */
- if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) {
- ecryptfs_printk(KERN_ERR, "Keyset too large\n");
- rc = -EINVAL;
- goto out;
}
- /* TODO: Packet size limit */
- /* We have 5 bytes of surrounding packet data */
- if ((0x05 + ECRYPTFS_SALT_SIZE
- + key_rec->enc_key_size) >= max) {
- ecryptfs_printk(KERN_ERR, "Authentication token is too "
- "large\n");
+encrypted_session_key_set:
+ /* This format is inspired by OpenPGP; see RFC 2440
+ * packet tag 3 */
+ max_packet_size = (1 /* Tag 3 identifier */
+ + 3 /* Max Tag 3 packet size */
+ + 1 /* Version */
+ + 1 /* Cipher code */
+ + 1 /* S2K specifier */
+ + 1 /* Hash identifier */
+ + ECRYPTFS_SALT_SIZE /* Salt */
+ + 1 /* Hash iterations */
+ + key_rec->enc_key_size); /* Encrypted key size */
+ if (max_packet_size > (*remaining_bytes)) {
+ printk(KERN_ERR "Packet too large; need up to [%td] bytes, but "
+ "there are only [%td] available\n", max_packet_size,
+ (*remaining_bytes));
rc = -EINVAL;
goto out;
}
- /* This format is inspired by OpenPGP; see RFC 2440
- * packet tag 3 */
dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE;
- /* ver+cipher+s2k+hash+salt+iter+enc_key */
- rc = write_packet_length(&dest[(*packet_size)],
- (0x05 + ECRYPTFS_SALT_SIZE
- + key_rec->enc_key_size),
+ /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3)
+ * to get the number of octets in the actual Tag 3 packet */
+ rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),
&packet_size_length);
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet "
- "header; cannot generate packet length\n");
+ printk(KERN_ERR "Error generating tag 3 packet header; cannot "
+ "generate packet length. rc = [%d]\n", rc);
goto out;
}
(*packet_size) += packet_size_length;
dest[(*packet_size)++] = 0x04; /* version 4 */
+ /* TODO: Break from RFC2440 so that arbitrary ciphers can be
+ * specified with strings */
cipher_code = ecryptfs_code_for_cipher_string(crypt_stat);
if (cipher_code == 0) {
ecryptfs_printk(KERN_WARNING, "Unable to generate code for "
@@ -1631,10 +1708,10 @@ encrypted_session_key_set:
key_rec->enc_key_size);
(*packet_size) += key_rec->enc_key_size;
out:
- if (desc.tfm && !tfm_mutex)
- crypto_free_blkcipher(desc.tfm);
if (rc)
(*packet_size) = 0;
+ else
+ (*remaining_bytes) -= (*packet_size);
return rc;
}
@@ -1642,7 +1719,7 @@ struct kmem_cache *ecryptfs_key_record_cache;
/**
* ecryptfs_generate_key_packet_set
- * @dest: Virtual address from which to write the key record set
+ * @dest_base: Virtual address from which to write the key record set
* @crypt_stat: The cryptographic context from which the
* authentication tokens will be retrieved
* @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat
@@ -1662,24 +1739,43 @@ ecryptfs_generate_key_packet_set(char *dest_base,
size_t max)
{
struct ecryptfs_auth_tok *auth_tok;
+ struct ecryptfs_global_auth_tok *global_auth_tok;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
size_t written;
struct ecryptfs_key_record *key_rec;
+ struct ecryptfs_key_sig *key_sig;
int rc = 0;
(*len) = 0;
+ mutex_lock(&crypt_stat->keysig_list_mutex);
key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL);
if (!key_rec) {
rc = -ENOMEM;
goto out;
}
- if (mount_crypt_stat->global_auth_tok) {
- auth_tok = mount_crypt_stat->global_auth_tok;
+ list_for_each_entry(key_sig, &crypt_stat->keysig_list,
+ crypt_stat_list) {
+ memset(key_rec, 0, sizeof(*key_rec));
+ rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
+ mount_crypt_stat,
+ key_sig->keysig);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to get the global "
+ "auth_tok; rc = [%d]\n", rc);
+ goto out_free;
+ }
+ if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) {
+ printk(KERN_WARNING
+ "Skipping invalid auth tok with sig = [%s]\n",
+ global_auth_tok->sig);
+ continue;
+ }
+ auth_tok = global_auth_tok->global_auth_tok;
if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
rc = write_tag_3_packet((dest_base + (*len)),
- max, auth_tok,
+ &max, auth_tok,
crypt_stat, key_rec,
&written);
if (rc) {
@@ -1689,10 +1785,9 @@ ecryptfs_generate_key_packet_set(char *dest_base,
}
(*len) += written;
/* Write auth tok signature packet */
- rc = write_tag_11_packet(
- (dest_base + (*len)),
- (max - (*len)),
- key_rec->sig, ECRYPTFS_SIG_SIZE, &written);
+ rc = write_tag_11_packet((dest_base + (*len)), &max,
+ key_rec->sig,
+ ECRYPTFS_SIG_SIZE, &written);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error writing "
"auth tok signature packet\n");
@@ -1701,9 +1796,8 @@ ecryptfs_generate_key_packet_set(char *dest_base,
(*len) += written;
} else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
rc = write_tag_1_packet(dest_base + (*len),
- max, auth_tok,
- crypt_stat,mount_crypt_stat,
- key_rec, &written);
+ &max, auth_tok,
+ crypt_stat, key_rec, &written);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error "
"writing tag 1 packet\n");
@@ -1716,19 +1810,69 @@ ecryptfs_generate_key_packet_set(char *dest_base,
rc = -EINVAL;
goto out_free;
}
- } else
- BUG();
- if (likely((max - (*len)) > 0)) {
+ }
+ if (likely(max > 0)) {
dest_base[(*len)] = 0x00;
} else {
ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");
rc = -EIO;
}
-
out_free:
kmem_cache_free(ecryptfs_key_record_cache, key_rec);
out:
if (rc)
(*len) = 0;
+ mutex_unlock(&crypt_stat->keysig_list_mutex);
return rc;
}
+
+struct kmem_cache *ecryptfs_key_sig_cache;
+
+int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig)
+{
+ struct ecryptfs_key_sig *new_key_sig;
+ int rc = 0;
+
+ new_key_sig = kmem_cache_alloc(ecryptfs_key_sig_cache, GFP_KERNEL);
+ if (!new_key_sig) {
+ rc = -ENOMEM;
+ printk(KERN_ERR
+ "Error allocating from ecryptfs_key_sig_cache\n");
+ goto out;
+ }
+ memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX);
+ mutex_lock(&crypt_stat->keysig_list_mutex);
+ list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list);
+ mutex_unlock(&crypt_stat->keysig_list_mutex);
+out:
+ return rc;
+}
+
+struct kmem_cache *ecryptfs_global_auth_tok_cache;
+
+int
+ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
+ char *sig)
+{
+ struct ecryptfs_global_auth_tok *new_auth_tok;
+ int rc = 0;
+
+ new_auth_tok = kmem_cache_alloc(ecryptfs_global_auth_tok_cache,
+ GFP_KERNEL);
+ if (!new_auth_tok) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Error allocating from "
+ "ecryptfs_global_auth_tok_cache\n");
+ goto out;
+ }
+ memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX);
+ new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+ mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
+ list_add(&new_auth_tok->mount_crypt_stat_list,
+ &mount_crypt_stat->global_auth_tok_list);
+ mount_crypt_stat->num_global_auth_toks++;
+ mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
+out:
+ return rc;
+}
+
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index a98497264fe..b83a512b7e0 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -32,7 +32,6 @@
#include <linux/crypto.h>
#include <linux/netlink.h>
#include <linux/mount.h>
-#include <linux/dcache.h>
#include <linux/pagemap.h>
#include <linux/key.h>
#include <linux/parser.h>
@@ -99,6 +98,64 @@ void __ecryptfs_printk(const char *fmt, ...)
}
/**
+ * ecryptfs_init_persistent_file
+ * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with
+ * the lower dentry and the lower mount set
+ *
+ * eCryptfs only ever keeps a single open file for every lower
+ * inode. All I/O operations to the lower inode occur through that
+ * file. When the first eCryptfs dentry that interposes with the first
+ * lower dentry for that inode is created, this function creates the
+ * persistent file struct and associates it with the eCryptfs
+ * inode. When the eCryptfs inode is destroyed, the file is closed.
+ *
+ * The persistent file will be opened with read/write permissions, if
+ * possible. Otherwise, it is opened read-only.
+ *
+ * This function does nothing if a lower persistent file is already
+ * associated with the eCryptfs inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
+{
+ struct ecryptfs_inode_info *inode_info =
+ ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
+ int rc = 0;
+
+ mutex_lock(&inode_info->lower_file_mutex);
+ if (!inode_info->lower_file) {
+ struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt =
+ ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
+
+ lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+ /* Corresponding dput() and mntput() are done when the
+ * persistent file is fput() when the eCryptfs inode
+ * is destroyed. */
+ dget(lower_dentry);
+ mntget(lower_mnt);
+ inode_info->lower_file = dentry_open(lower_dentry,
+ lower_mnt,
+ (O_RDWR | O_LARGEFILE));
+ if (IS_ERR(inode_info->lower_file))
+ inode_info->lower_file = dentry_open(lower_dentry,
+ lower_mnt,
+ (O_RDONLY
+ | O_LARGEFILE));
+ if (IS_ERR(inode_info->lower_file)) {
+ printk(KERN_ERR "Error opening lower persistent file "
+ "for lower_dentry [0x%p] and lower_mnt [0x%p]\n",
+ lower_dentry, lower_mnt);
+ rc = PTR_ERR(inode_info->lower_file);
+ inode_info->lower_file = NULL;
+ }
+ }
+ mutex_unlock(&inode_info->lower_file_mutex);
+ return rc;
+}
+
+/**
* ecryptfs_interpose
* @lower_dentry: Existing dentry in the lower filesystem
* @dentry: ecryptfs' dentry
@@ -155,6 +212,13 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
/* This size will be overwritten for real files w/ headers and
* other metadata */
fsstack_copy_inode_size(inode, lower_inode);
+ rc = ecryptfs_init_persistent_file(dentry);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to initialize the "
+ "persistent file for the dentry with name [%s]; "
+ "rc = [%d]\n", __FUNCTION__, dentry->d_name.name, rc);
+ goto out;
+ }
out:
return rc;
}
@@ -179,38 +243,41 @@ static match_table_t tokens = {
{ecryptfs_opt_err, NULL}
};
-/**
- * ecryptfs_verify_version
- * @version: The version number to confirm
- *
- * Returns zero on good version; non-zero otherwise
- */
-static int ecryptfs_verify_version(u16 version)
+static int ecryptfs_init_global_auth_toks(
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
+ struct ecryptfs_global_auth_tok *global_auth_tok;
int rc = 0;
- unsigned char major;
- unsigned char minor;
-
- major = ((version >> 8) & 0xFF);
- minor = (version & 0xFF);
- if (major != ECRYPTFS_VERSION_MAJOR) {
- ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
- "Expected [%d]; got [%d]\n",
- ECRYPTFS_VERSION_MAJOR, major);
- rc = -EINVAL;
- goto out;
- }
- if (minor != ECRYPTFS_VERSION_MINOR) {
- ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
- "Expected [%d]; got [%d]\n",
- ECRYPTFS_VERSION_MINOR, minor);
- rc = -EINVAL;
- goto out;
+
+ list_for_each_entry(global_auth_tok,
+ &mount_crypt_stat->global_auth_tok_list,
+ mount_crypt_stat_list) {
+ rc = ecryptfs_keyring_auth_tok_for_sig(
+ &global_auth_tok->global_auth_tok_key,
+ &global_auth_tok->global_auth_tok,
+ global_auth_tok->sig);
+ if (rc) {
+ printk(KERN_ERR "Could not find valid key in user "
+ "session keyring for sig specified in mount "
+ "option: [%s]\n", global_auth_tok->sig);
+ global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID;
+ rc = 0;
+ } else
+ global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID;
}
-out:
return rc;
}
+static void ecryptfs_init_mount_crypt_stat(
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+ memset((void *)mount_crypt_stat, 0,
+ sizeof(struct ecryptfs_mount_crypt_stat));
+ INIT_LIST_HEAD(&mount_crypt_stat->global_auth_tok_list);
+ mutex_init(&mount_crypt_stat->global_auth_tok_list_mutex);
+ mount_crypt_stat->flags |= ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED;
+}
+
/**
* ecryptfs_parse_options
* @sb: The ecryptfs super block
@@ -238,14 +305,11 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
int cipher_name_set = 0;
int cipher_key_bytes;
int cipher_key_bytes_set = 0;
- struct key *auth_tok_key = NULL;
- struct ecryptfs_auth_tok *auth_tok = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
substring_t args[MAX_OPT_ARGS];
int token;
char *sig_src;
- char *sig_dst;
char *debug_src;
char *cipher_name_dst;
char *cipher_name_src;
@@ -256,6 +320,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
rc = -EINVAL;
goto out;
}
+ ecryptfs_init_mount_crypt_stat(mount_crypt_stat);
while ((p = strsep(&options, ",")) != NULL) {
if (!*p)
continue;
@@ -264,14 +329,13 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
case ecryptfs_opt_sig:
case ecryptfs_opt_ecryptfs_sig:
sig_src = args[0].from;
- sig_dst =
- mount_crypt_stat->global_auth_tok_sig;
- memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX);
- sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0';
- ecryptfs_printk(KERN_DEBUG,
- "The mount_crypt_stat "
- "global_auth_tok_sig set to: "
- "[%s]\n", sig_dst);
+ rc = ecryptfs_add_global_auth_tok(mount_crypt_stat,
+ sig_src);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to register "
+ "global sig; rc = [%d]\n", rc);
+ goto out;
+ }
sig_set = 1;
break;
case ecryptfs_opt_debug:
@@ -333,12 +397,10 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
p);
}
}
- /* Do not support lack of mount-wide signature in 0.1
- * release */
if (!sig_set) {
rc = -EINVAL;
- ecryptfs_printk(KERN_ERR, "You must supply a valid "
- "passphrase auth tok signature as a mount "
+ ecryptfs_printk(KERN_ERR, "You must supply at least one valid "
+ "auth tok signature as a mount "
"parameter; see the eCryptfs README\n");
goto out;
}
@@ -358,55 +420,23 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
if (!cipher_key_bytes_set) {
mount_crypt_stat->global_default_cipher_key_size = 0;
}
- rc = ecryptfs_process_cipher(
- &mount_crypt_stat->global_key_tfm,
- mount_crypt_stat->global_default_cipher_name,
- &mount_crypt_stat->global_default_cipher_key_size);
+ rc = ecryptfs_add_new_key_tfm(
+ NULL, mount_crypt_stat->global_default_cipher_name,
+ mount_crypt_stat->global_default_cipher_key_size);
if (rc) {
- printk(KERN_ERR "Error attempting to initialize cipher [%s] "
- "with key size [%Zd] bytes; rc = [%d]\n",
+ printk(KERN_ERR "Error attempting to initialize cipher with "
+ "name = [%s] and key size = [%td]; rc = [%d]\n",
mount_crypt_stat->global_default_cipher_name,
mount_crypt_stat->global_default_cipher_key_size, rc);
- mount_crypt_stat->global_key_tfm = NULL;
- mount_crypt_stat->global_auth_tok_key = NULL;
rc = -EINVAL;
goto out;
}
- mutex_init(&mount_crypt_stat->global_key_tfm_mutex);
- ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: "
- "[%s]\n", mount_crypt_stat->global_auth_tok_sig);
- /* The reference to this key is held until umount is done The
- * call to key_put is done in ecryptfs_put_super() */
- auth_tok_key = request_key(&key_type_user,
- mount_crypt_stat->global_auth_tok_sig,
- NULL);
- if (!auth_tok_key || IS_ERR(auth_tok_key)) {
- ecryptfs_printk(KERN_ERR, "Could not find key with "
- "description: [%s]\n",
- mount_crypt_stat->global_auth_tok_sig);
- process_request_key_err(PTR_ERR(auth_tok_key));
- rc = -EINVAL;
- goto out;
- }
- auth_tok = ecryptfs_get_key_payload_data(auth_tok_key);
- if (ecryptfs_verify_version(auth_tok->version)) {
- ecryptfs_printk(KERN_ERR, "Data structure version mismatch. "
- "Userspace tools must match eCryptfs kernel "
- "module with major version [%d] and minor "
- "version [%d]\n", ECRYPTFS_VERSION_MAJOR,
- ECRYPTFS_VERSION_MINOR);
- rc = -EINVAL;
- goto out;
- }
- if (auth_tok->token_type != ECRYPTFS_PASSWORD
- && auth_tok->token_type != ECRYPTFS_PRIVATE_KEY) {
- ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure "
- "returned from key query\n");
- rc = -EINVAL;
- goto out;
+ rc = ecryptfs_init_global_auth_toks(mount_crypt_stat);
+ if (rc) {
+ printk(KERN_WARNING "One or more global auth toks could not "
+ "properly register; rc = [%d]\n", rc);
}
- mount_crypt_stat->global_auth_tok_key = auth_tok_key;
- mount_crypt_stat->global_auth_tok = auth_tok;
+ rc = 0;
out:
return rc;
}
@@ -495,7 +525,8 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
ecryptfs_set_dentry_lower(sb->s_root, lower_root);
ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt);
- if ((rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0)))
+ rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0);
+ if (rc)
goto out_free;
rc = 0;
goto out;
@@ -579,7 +610,7 @@ static struct file_system_type ecryptfs_fs_type = {
* Initializes the ecryptfs_inode_info_cache when it is created
*/
static void
-inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags)
+inode_info_init_once(struct kmem_cache *cachep, void *vptr)
{
struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr;
@@ -590,7 +621,7 @@ static struct ecryptfs_cache_info {
struct kmem_cache **cache;
const char *name;
size_t size;
- void (*ctor)(void*, struct kmem_cache *, unsigned long);
+ void (*ctor)(struct kmem_cache *cache, void *obj);
} ecryptfs_cache_infos[] = {
{
.cache = &ecryptfs_auth_tok_list_item_cache,
@@ -639,15 +670,25 @@ static struct ecryptfs_cache_info {
.size = PAGE_CACHE_SIZE,
},
{
- .cache = &ecryptfs_lower_page_cache,
- .name = "ecryptfs_lower_page_cache",
- .size = PAGE_CACHE_SIZE,
- },
- {
.cache = &ecryptfs_key_record_cache,
.name = "ecryptfs_key_record_cache",
.size = sizeof(struct ecryptfs_key_record),
},
+ {
+ .cache = &ecryptfs_key_sig_cache,
+ .name = "ecryptfs_key_sig_cache",
+ .size = sizeof(struct ecryptfs_key_sig),
+ },
+ {
+ .cache = &ecryptfs_global_auth_tok_cache,
+ .name = "ecryptfs_global_auth_tok_cache",
+ .size = sizeof(struct ecryptfs_global_auth_tok),
+ },
+ {
+ .cache = &ecryptfs_key_tfm_cache,
+ .name = "ecryptfs_key_tfm_cache",
+ .size = sizeof(struct ecryptfs_key_tfm),
+ },
};
static void ecryptfs_free_kmem_caches(void)
@@ -750,7 +791,8 @@ static struct ecryptfs_version_str_map_elem {
{ECRYPTFS_VERSIONING_PUBKEY, "pubkey"},
{ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"},
{ECRYPTFS_VERSIONING_POLICY, "policy"},
- {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"}
+ {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"},
+ {ECRYPTFS_VERSIONING_MULTKEY, "multiple keys per file"}
};
static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff)
@@ -786,7 +828,8 @@ static int do_sysfs_registration(void)
{
int rc;
- if ((rc = subsystem_register(&ecryptfs_subsys))) {
+ rc = subsystem_register(&ecryptfs_subsys);
+ if (rc) {
printk(KERN_ERR
"Unable to register ecryptfs sysfs subsystem\n");
goto out;
@@ -845,33 +888,49 @@ static int __init ecryptfs_init(void)
rc = register_filesystem(&ecryptfs_fs_type);
if (rc) {
printk(KERN_ERR "Failed to register filesystem\n");
- ecryptfs_free_kmem_caches();
- goto out;
+ goto out_free_kmem_caches;
}
kobj_set_kset_s(&ecryptfs_subsys, fs_subsys);
rc = do_sysfs_registration();
if (rc) {
printk(KERN_ERR "sysfs registration failed\n");
- unregister_filesystem(&ecryptfs_fs_type);
- ecryptfs_free_kmem_caches();
- goto out;
+ goto out_unregister_filesystem;
}
rc = ecryptfs_init_messaging(ecryptfs_transport);
if (rc) {
ecryptfs_printk(KERN_ERR, "Failure occured while attempting to "
"initialize the eCryptfs netlink socket\n");
- do_sysfs_unregistration();
- unregister_filesystem(&ecryptfs_fs_type);
- ecryptfs_free_kmem_caches();
+ goto out_do_sysfs_unregistration;
+ }
+ rc = ecryptfs_init_crypto();
+ if (rc) {
+ printk(KERN_ERR "Failure whilst attempting to init crypto; "
+ "rc = [%d]\n", rc);
+ goto out_release_messaging;
}
+ goto out;
+out_release_messaging:
+ ecryptfs_release_messaging(ecryptfs_transport);
+out_do_sysfs_unregistration:
+ do_sysfs_unregistration();
+out_unregister_filesystem:
+ unregister_filesystem(&ecryptfs_fs_type);
+out_free_kmem_caches:
+ ecryptfs_free_kmem_caches();
out:
return rc;
}
static void __exit ecryptfs_exit(void)
{
- do_sysfs_unregistration();
+ int rc;
+
+ rc = ecryptfs_destroy_crypto();
+ if (rc)
+ printk(KERN_ERR "Failure whilst attempting to destroy crypto; "
+ "rc = [%d]\n", rc);
ecryptfs_release_messaging(ecryptfs_transport);
+ do_sysfs_unregistration();
unregister_filesystem(&ecryptfs_fs_type);
ecryptfs_free_kmem_caches();
}
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index a9d87c47f72..a96d341d154 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -419,8 +419,9 @@ int ecryptfs_init_messaging(unsigned int transport)
}
mutex_init(&ecryptfs_daemon_id_hash_mux);
mutex_lock(&ecryptfs_daemon_id_hash_mux);
- ecryptfs_hash_buckets = 0;
- while (ecryptfs_number_of_users >> ++ecryptfs_hash_buckets);
+ ecryptfs_hash_buckets = 1;
+ while (ecryptfs_number_of_users >> ecryptfs_hash_buckets)
+ ecryptfs_hash_buckets++;
ecryptfs_daemon_id_hash = kmalloc(sizeof(struct hlist_head)
* ecryptfs_hash_buckets, GFP_KERNEL);
if (!ecryptfs_daemon_id_hash) {
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index fd3f94d4a66..16a7a555f39 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -37,130 +37,27 @@
struct kmem_cache *ecryptfs_lower_page_cache;
/**
- * ecryptfs_get1page
+ * ecryptfs_get_locked_page
*
* Get one page from cache or lower f/s, return error otherwise.
*
- * Returns unlocked and up-to-date page (if ok), with increased
+ * Returns locked and up-to-date page (if ok), with increased
* refcnt.
*/
-static struct page *ecryptfs_get1page(struct file *file, int index)
+struct page *ecryptfs_get_locked_page(struct file *file, loff_t index)
{
struct dentry *dentry;
struct inode *inode;
struct address_space *mapping;
+ struct page *page;
dentry = file->f_path.dentry;
inode = dentry->d_inode;
mapping = inode->i_mapping;
- return read_mapping_page(mapping, index, (void *)file);
-}
-
-/**
- * ecryptfs_fill_zeros
- * @file: The ecryptfs file
- * @new_length: The new length of the data in the underlying file;
- * everything between the prior end of the file and the
- * new end of the file will be filled with zero's.
- * new_length must be greater than current length
- *
- * Function for handling lseek-ing past the end of the file.
- *
- * This function does not support shrinking, only growing a file.
- *
- * Returns zero on success; non-zero otherwise.
- */
-int ecryptfs_fill_zeros(struct file *file, loff_t new_length)
-{
- int rc = 0;
- struct dentry *dentry = file->f_path.dentry;
- struct inode *inode = dentry->d_inode;
- pgoff_t old_end_page_index = 0;
- pgoff_t index = old_end_page_index;
- int old_end_pos_in_page = -1;
- pgoff_t new_end_page_index;
- int new_end_pos_in_page;
- loff_t cur_length = i_size_read(inode);
-
- if (cur_length != 0) {
- index = old_end_page_index =
- ((cur_length - 1) >> PAGE_CACHE_SHIFT);
- old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK);
- }
- new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
- new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
- ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; "
- "old_end_pos_in_page = [%d]; "
- "new_end_page_index = [0x%.16x]; "
- "new_end_pos_in_page = [%d]\n",
- old_end_page_index, old_end_pos_in_page,
- new_end_page_index, new_end_pos_in_page);
- if (old_end_page_index == new_end_page_index) {
- /* Start and end are in the same page; we just need to
- * set a portion of the existing page to zero's */
- rc = ecryptfs_write_zeros(file, index,
- (old_end_pos_in_page + 1),
- (new_end_pos_in_page
- - old_end_pos_in_page));
- if (rc)
- ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros("
- "file=[%p], "
- "index=[0x%.16x], "
- "old_end_pos_in_page=[d], "
- "(PAGE_CACHE_SIZE - new_end_pos_in_page"
- "=[%d]"
- ")=[d]) returned [%d]\n", file, index,
- old_end_pos_in_page,
- new_end_pos_in_page,
- (PAGE_CACHE_SIZE - new_end_pos_in_page),
- rc);
- goto out;
- }
- /* Fill the remainder of the previous last page with zeros */
- rc = ecryptfs_write_zeros(file, index, (old_end_pos_in_page + 1),
- ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page));
- if (rc) {
- ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=[%p], "
- "index=[0x%.16x], old_end_pos_in_page=[d], "
- "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) "
- "returned [%d]\n", file, index,
- old_end_pos_in_page,
- (PAGE_CACHE_SIZE - old_end_pos_in_page), rc);
- goto out;
- }
- index++;
- while (index < new_end_page_index) {
- /* Fill all intermediate pages with zeros */
- rc = ecryptfs_write_zeros(file, index, 0, PAGE_CACHE_SIZE);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros("
- "file=[%p], "
- "index=[0x%.16x], "
- "old_end_pos_in_page=[d], "
- "(PAGE_CACHE_SIZE - new_end_pos_in_page"
- "=[%d]"
- ")=[d]) returned [%d]\n", file, index,
- old_end_pos_in_page,
- new_end_pos_in_page,
- (PAGE_CACHE_SIZE - new_end_pos_in_page),
- rc);
- goto out;
- }
- index++;
- }
- /* Fill the portion at the beginning of the last new page with
- * zero's */
- rc = ecryptfs_write_zeros(file, index, 0, (new_end_pos_in_page + 1));
- if (rc) {
- ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file="
- "[%p], index=[0x%.16x], 0, "
- "new_end_pos_in_page=[%d]"
- "returned [%d]\n", file, index,
- new_end_pos_in_page, rc);
- goto out;
- }
-out:
- return rc;
+ page = read_mapping_page(mapping, index, (void *)file);
+ if (!IS_ERR(page))
+ lock_page(page);
+ return page;
}
/**
@@ -171,13 +68,9 @@ out:
*/
static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
{
- struct ecryptfs_page_crypt_context ctx;
int rc;
- ctx.page = page;
- ctx.mode = ECRYPTFS_WRITEPAGE_MODE;
- ctx.param.wbc = wbc;
- rc = ecryptfs_encrypt_page(&ctx);
+ rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting "
"page (upper index [0x%.16x])\n", page->index);
@@ -191,58 +84,6 @@ out:
}
/**
- * Reads the data from the lower file file at index lower_page_index
- * and copies that data into page.
- *
- * @param page Page to fill
- * @param lower_page_index Index of the page in the lower file to get
- */
-int ecryptfs_do_readpage(struct file *file, struct page *page,
- pgoff_t lower_page_index)
-{
- int rc;
- struct dentry *dentry;
- struct file *lower_file;
- struct dentry *lower_dentry;
- struct inode *inode;
- struct inode *lower_inode;
- char *page_data;
- struct page *lower_page = NULL;
- char *lower_page_data;
- const struct address_space_operations *lower_a_ops;
-
- dentry = file->f_path.dentry;
- lower_file = ecryptfs_file_to_lower(file);
- lower_dentry = ecryptfs_dentry_to_lower(dentry);
- inode = dentry->d_inode;
- lower_inode = ecryptfs_inode_to_lower(inode);
- lower_a_ops = lower_inode->i_mapping->a_ops;
- lower_page = read_cache_page(lower_inode->i_mapping, lower_page_index,
- (filler_t *)lower_a_ops->readpage,
- (void *)lower_file);
- if (IS_ERR(lower_page)) {
- rc = PTR_ERR(lower_page);
- lower_page = NULL;
- ecryptfs_printk(KERN_ERR, "Error reading from page cache\n");
- goto out;
- }
- page_data = kmap_atomic(page, KM_USER0);
- lower_page_data = kmap_atomic(lower_page, KM_USER1);
- memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
- kunmap_atomic(lower_page_data, KM_USER1);
- kunmap_atomic(page_data, KM_USER0);
- flush_dcache_page(page);
- rc = 0;
-out:
- if (likely(lower_page))
- page_cache_release(lower_page);
- if (rc == 0)
- SetPageUptodate(page);
- else
- ClearPageUptodate(page);
- return rc;
-}
-/**
* Header Extent:
* Octets 0-7: Unencrypted file size (big-endian)
* Octets 8-15: eCryptfs special marker
@@ -271,9 +112,77 @@ static void set_header_info(char *page_virt,
}
/**
+ * ecryptfs_copy_up_encrypted_with_header
+ * @page: Sort of a ``virtual'' representation of the encrypted lower
+ * file. The actual lower file does not have the metadata in
+ * the header. This is locked.
+ * @crypt_stat: The eCryptfs inode's cryptographic context
+ *
+ * The ``view'' is the version of the file that userspace winds up
+ * seeing, with the header information inserted.
+ */
+static int
+ecryptfs_copy_up_encrypted_with_header(struct page *page,
+ struct ecryptfs_crypt_stat *crypt_stat)
+{
+ loff_t extent_num_in_page = 0;
+ loff_t num_extents_per_page = (PAGE_CACHE_SIZE
+ / crypt_stat->extent_size);
+ int rc = 0;
+
+ while (extent_num_in_page < num_extents_per_page) {
+ loff_t view_extent_num = ((((loff_t)page->index)
+ * num_extents_per_page)
+ + extent_num_in_page);
+
+ if (view_extent_num < crypt_stat->num_header_extents_at_front) {
+ /* This is a header extent */
+ char *page_virt;
+
+ page_virt = kmap_atomic(page, KM_USER0);
+ memset(page_virt, 0, PAGE_CACHE_SIZE);
+ /* TODO: Support more than one header extent */
+ if (view_extent_num == 0) {
+ rc = ecryptfs_read_xattr_region(
+ page_virt, page->mapping->host);
+ set_header_info(page_virt, crypt_stat);
+ }
+ kunmap_atomic(page_virt, KM_USER0);
+ flush_dcache_page(page);
+ if (rc) {
+ printk(KERN_ERR "%s: Error reading xattr "
+ "region; rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ } else {
+ /* This is an encrypted data extent */
+ loff_t lower_offset =
+ ((view_extent_num -
+ crypt_stat->num_header_extents_at_front)
+ * crypt_stat->extent_size);
+
+ rc = ecryptfs_read_lower_page_segment(
+ page, (lower_offset >> PAGE_CACHE_SHIFT),
+ (lower_offset & ~PAGE_CACHE_MASK),
+ crypt_stat->extent_size, page->mapping->host);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to read "
+ "extent at offset [%lld] in the lower "
+ "file; rc = [%d]\n", __FUNCTION__,
+ lower_offset, rc);
+ goto out;
+ }
+ }
+ extent_num_in_page++;
+ }
+out:
+ return rc;
+}
+
+/**
* ecryptfs_readpage
- * @file: This is an ecryptfs file
- * @page: ecryptfs associated page to stick the read data into
+ * @file: An eCryptfs file
+ * @page: Page from eCryptfs inode mapping into which to stick the read data
*
* Read in a page, decrypting if necessary.
*
@@ -281,59 +190,35 @@ static void set_header_info(char *page_virt,
*/
static int ecryptfs_readpage(struct file *file, struct page *page)
{
+ struct ecryptfs_crypt_stat *crypt_stat =
+ &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
int rc = 0;
- struct ecryptfs_crypt_stat *crypt_stat;
- BUG_ON(!(file && file->f_path.dentry && file->f_path.dentry->d_inode));
- crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
- ->crypt_stat;
if (!crypt_stat
|| !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
|| (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
ecryptfs_printk(KERN_DEBUG,
"Passing through unencrypted page\n");
- rc = ecryptfs_do_readpage(file, page, page->index);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error reading page; rc = "
- "[%d]\n", rc);
- goto out;
- }
+ rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
+ PAGE_CACHE_SIZE,
+ page->mapping->host);
} else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
- int num_pages_in_header_region =
- (crypt_stat->header_extent_size
- / PAGE_CACHE_SIZE);
-
- if (page->index < num_pages_in_header_region) {
- char *page_virt;
-
- page_virt = kmap_atomic(page, KM_USER0);
- memset(page_virt, 0, PAGE_CACHE_SIZE);
- if (page->index == 0) {
- rc = ecryptfs_read_xattr_region(
- page_virt, file->f_path.dentry);
- set_header_info(page_virt, crypt_stat);
- }
- kunmap_atomic(page_virt, KM_USER0);
- flush_dcache_page(page);
- if (rc) {
- printk(KERN_ERR "Error reading xattr "
- "region\n");
- goto out;
- }
- } else {
- rc = ecryptfs_do_readpage(
- file, page,
- (page->index
- - num_pages_in_header_region));
- if (rc) {
- printk(KERN_ERR "Error reading page; "
- "rc = [%d]\n", rc);
- goto out;
- }
+ rc = ecryptfs_copy_up_encrypted_with_header(page,
+ crypt_stat);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to copy "
+ "the encrypted content from the lower "
+ "file whilst inserting the metadata "
+ "from the xattr into the header; rc = "
+ "[%d]\n", __FUNCTION__, rc);
+ goto out;
}
+
} else {
- rc = ecryptfs_do_readpage(file, page, page->index);
+ rc = ecryptfs_read_lower_page_segment(
+ page, page->index, 0, PAGE_CACHE_SIZE,
+ page->mapping->host);
if (rc) {
printk(KERN_ERR "Error reading page; rc = "
"[%d]\n", rc);
@@ -341,17 +226,18 @@ static int ecryptfs_readpage(struct file *file, struct page *page)
}
}
} else {
- rc = ecryptfs_decrypt_page(file, page);
+ rc = ecryptfs_decrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error decrypting page; "
"rc = [%d]\n", rc);
goto out;
}
}
- SetPageUptodate(page);
out:
if (rc)
ClearPageUptodate(page);
+ else
+ SetPageUptodate(page);
ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
page->index);
unlock_page(page);
@@ -377,27 +263,6 @@ out:
return 0;
}
-/**
- * eCryptfs does not currently support holes. When writing after a
- * seek past the end of the file, eCryptfs fills in 0's through to the
- * current location. The code to fill in the 0's to all the
- * intermediate pages calls ecryptfs_prepare_write_no_truncate().
- */
-static int
-ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- int rc = 0;
-
- if (from == 0 && to == PAGE_CACHE_SIZE)
- goto out; /* If we are writing a full page, it will be
- up to date. */
- if (!PageUptodate(page))
- rc = ecryptfs_do_readpage(file, page, page->index);
-out:
- return rc;
-}
-
static int ecryptfs_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
@@ -406,10 +271,21 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
if (from == 0 && to == PAGE_CACHE_SIZE)
goto out; /* If we are writing a full page, it will be
up to date. */
- if (!PageUptodate(page))
- rc = ecryptfs_do_readpage(file, page, page->index);
+ if (!PageUptodate(page)) {
+ rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
+ PAGE_CACHE_SIZE,
+ page->mapping->host);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attemping to read lower "
+ "page segment; rc = [%d]\n", __FUNCTION__, rc);
+ ClearPageUptodate(page);
+ goto out;
+ } else
+ SetPageUptodate(page);
+ }
if (page->index != 0) {
- loff_t end_of_prev_pg_pos = page_offset(page) - 1;
+ loff_t end_of_prev_pg_pos =
+ (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) {
rc = ecryptfs_truncate(file->f_path.dentry,
@@ -428,32 +304,6 @@ out:
return rc;
}
-int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
- struct inode *lower_inode,
- struct writeback_control *wbc)
-{
- int rc = 0;
-
- rc = lower_inode->i_mapping->a_ops->writepage(lower_page, wbc);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error calling lower writepage(); "
- "rc = [%d]\n", rc);
- goto out;
- }
- lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
- page_cache_release(lower_page);
-out:
- return rc;
-}
-
-static
-void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
-{
- if (page_locked)
- unlock_page(lower_page);
- page_cache_release(lower_page);
-}
-
/**
* ecryptfs_write_inode_size_to_header
*
@@ -461,67 +311,48 @@ void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
*
* Returns zero on success; non-zero on error.
*/
-static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
- struct inode *lower_inode,
- struct inode *inode)
+static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode)
{
- int rc = 0;
- struct page *header_page;
- char *header_virt;
- const struct address_space_operations *lower_a_ops;
u64 file_size;
+ char *file_size_virt;
+ int rc;
-retry:
- header_page = grab_cache_page(lower_inode->i_mapping, 0);
- if (!header_page) {
- ecryptfs_printk(KERN_ERR, "grab_cache_page for "
- "lower_page_index 0 failed\n");
- rc = -EINVAL;
- goto out;
- }
- lower_a_ops = lower_inode->i_mapping->a_ops;
- rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
- if (rc) {
- if (rc == AOP_TRUNCATED_PAGE) {
- ecryptfs_release_lower_page(header_page, 0);
- goto retry;
- } else
- ecryptfs_release_lower_page(header_page, 1);
+ file_size_virt = kmalloc(sizeof(u64), GFP_KERNEL);
+ if (!file_size_virt) {
+ rc = -ENOMEM;
goto out;
}
- file_size = (u64)i_size_read(inode);
- ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
+ file_size = (u64)i_size_read(ecryptfs_inode);
file_size = cpu_to_be64(file_size);
- header_virt = kmap_atomic(header_page, KM_USER0);
- memcpy(header_virt, &file_size, sizeof(u64));
- kunmap_atomic(header_virt, KM_USER0);
- flush_dcache_page(header_page);
- rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8);
- if (rc < 0)
- ecryptfs_printk(KERN_ERR, "Error commiting header page "
- "write\n");
- if (rc == AOP_TRUNCATED_PAGE) {
- ecryptfs_release_lower_page(header_page, 0);
- goto retry;
- } else
- ecryptfs_release_lower_page(header_page, 1);
- lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty_sync(inode);
+ memcpy(file_size_virt, &file_size, sizeof(u64));
+ rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0,
+ sizeof(u64));
+ kfree(file_size_virt);
+ if (rc)
+ printk(KERN_ERR "%s: Error writing file size to header; "
+ "rc = [%d]\n", __FUNCTION__, rc);
out:
return rc;
}
-static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode,
- struct inode *inode,
- struct dentry *ecryptfs_dentry,
- int lower_i_mutex_held)
+struct kmem_cache *ecryptfs_xattr_cache;
+
+static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
{
ssize_t size;
void *xattr_virt;
- struct dentry *lower_dentry;
+ struct dentry *lower_dentry =
+ ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry;
+ struct inode *lower_inode = lower_dentry->d_inode;
u64 file_size;
int rc;
+ if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) {
+ printk(KERN_WARNING
+ "No support for setting xattr in lower filesystem\n");
+ rc = -ENOSYS;
+ goto out;
+ }
xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL);
if (!xattr_virt) {
printk(KERN_ERR "Out of memory whilst attempting to write "
@@ -529,35 +360,17 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode,
rc = -ENOMEM;
goto out;
}
- lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
- if (!lower_dentry->d_inode->i_op->getxattr ||
- !lower_dentry->d_inode->i_op->setxattr) {
- printk(KERN_WARNING
- "No support for setting xattr in lower filesystem\n");
- rc = -ENOSYS;
- kmem_cache_free(ecryptfs_xattr_cache, xattr_virt);
- goto out;
- }
- if (!lower_i_mutex_held)
- mutex_lock(&lower_dentry->d_inode->i_mutex);
- size = lower_dentry->d_inode->i_op->getxattr(lower_dentry,
- ECRYPTFS_XATTR_NAME,
- xattr_virt,
- PAGE_CACHE_SIZE);
- if (!lower_i_mutex_held)
- mutex_unlock(&lower_dentry->d_inode->i_mutex);
+ mutex_lock(&lower_inode->i_mutex);
+ size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
+ xattr_virt, PAGE_CACHE_SIZE);
if (size < 0)
size = 8;
- file_size = (u64)i_size_read(inode);
+ file_size = (u64)i_size_read(ecryptfs_inode);
file_size = cpu_to_be64(file_size);
memcpy(xattr_virt, &file_size, sizeof(u64));
- if (!lower_i_mutex_held)
- mutex_lock(&lower_dentry->d_inode->i_mutex);
- rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry,
- ECRYPTFS_XATTR_NAME,
- xattr_virt, size, 0);
- if (!lower_i_mutex_held)
- mutex_unlock(&lower_dentry->d_inode->i_mutex);
+ rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
+ xattr_virt, size, 0);
+ mutex_unlock(&lower_inode->i_mutex);
if (rc)
printk(KERN_ERR "Error whilst attempting to write inode size "
"to lower file xattr; rc = [%d]\n", rc);
@@ -566,122 +379,18 @@ out:
return rc;
}
-int
-ecryptfs_write_inode_size_to_metadata(struct file *lower_file,
- struct inode *lower_inode,
- struct inode *inode,
- struct dentry *ecryptfs_dentry,
- int lower_i_mutex_held)
+int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
{
struct ecryptfs_crypt_stat *crypt_stat;
- crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
+ crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
- return ecryptfs_write_inode_size_to_xattr(lower_inode, inode,
- ecryptfs_dentry,
- lower_i_mutex_held);
+ return ecryptfs_write_inode_size_to_xattr(ecryptfs_inode);
else
- return ecryptfs_write_inode_size_to_header(lower_file,
- lower_inode,
- inode);
-}
-
-int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
- struct file *lower_file,
- unsigned long lower_page_index, int byte_offset,
- int region_bytes)
-{
- int rc = 0;
-
-retry:
- *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index);
- if (!(*lower_page)) {
- rc = -EINVAL;
- ecryptfs_printk(KERN_ERR, "Error attempting to grab "
- "lower page with index [0x%.16x]\n",
- lower_page_index);
- goto out;
- }
- rc = lower_inode->i_mapping->a_ops->prepare_write(lower_file,
- (*lower_page),
- byte_offset,
- region_bytes);
- if (rc) {
- if (rc == AOP_TRUNCATED_PAGE) {
- ecryptfs_release_lower_page(*lower_page, 0);
- goto retry;
- } else {
- ecryptfs_printk(KERN_ERR, "prepare_write for "
- "lower_page_index = [0x%.16x] failed; rc = "
- "[%d]\n", lower_page_index, rc);
- ecryptfs_release_lower_page(*lower_page, 1);
- (*lower_page) = NULL;
- }
- }
-out:
- return rc;
-}
-
-/**
- * ecryptfs_commit_lower_page
- *
- * Returns zero on success; non-zero on error
- */
-int
-ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
- struct file *lower_file, int byte_offset,
- int region_size)
-{
- int page_locked = 1;
- int rc = 0;
-
- rc = lower_inode->i_mapping->a_ops->commit_write(
- lower_file, lower_page, byte_offset, region_size);
- if (rc == AOP_TRUNCATED_PAGE)
- page_locked = 0;
- if (rc < 0) {
- ecryptfs_printk(KERN_ERR,
- "Error committing write; rc = [%d]\n", rc);
- } else
- rc = 0;
- ecryptfs_release_lower_page(lower_page, page_locked);
- return rc;
+ return ecryptfs_write_inode_size_to_header(ecryptfs_inode);
}
/**
- * ecryptfs_copy_page_to_lower
- *
- * Used for plaintext pass-through; no page index interpolation
- * required.
- */
-int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
- struct file *lower_file)
-{
- int rc = 0;
- struct page *lower_page;
-
- rc = ecryptfs_get_lower_page(&lower_page, lower_inode, lower_file,
- page->index, 0, PAGE_CACHE_SIZE);
- if (rc) {
- ecryptfs_printk(KERN_ERR, "Error attempting to get page "
- "at index [0x%.16x]\n", page->index);
- goto out;
- }
- /* TODO: aops */
- memcpy((char *)page_address(lower_page), page_address(page),
- PAGE_CACHE_SIZE);
- rc = ecryptfs_commit_lower_page(lower_page, lower_inode, lower_file,
- 0, PAGE_CACHE_SIZE);
- if (rc)
- ecryptfs_printk(KERN_ERR, "Error attempting to commit page "
- "at index [0x%.16x]\n", page->index);
-out:
- return rc;
-}
-
-struct kmem_cache *ecryptfs_xattr_cache;
-
-/**
* ecryptfs_commit_write
* @file: The eCryptfs file object
* @page: The eCryptfs page
@@ -695,20 +404,12 @@ struct kmem_cache *ecryptfs_xattr_cache;
static int ecryptfs_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
- struct ecryptfs_page_crypt_context ctx;
loff_t pos;
- struct inode *inode;
- struct inode *lower_inode;
- struct file *lower_file;
- struct ecryptfs_crypt_stat *crypt_stat;
+ struct inode *ecryptfs_inode = page->mapping->host;
+ struct ecryptfs_crypt_stat *crypt_stat =
+ &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
int rc;
- inode = page->mapping->host;
- lower_inode = ecryptfs_inode_to_lower(inode);
- lower_file = ecryptfs_file_to_lower(file);
- mutex_lock(&lower_inode->i_mutex);
- crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
- ->crypt_stat;
if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
"crypt_stat at memory location [%p]\n", crypt_stat);
@@ -718,6 +419,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
"(page w/ index = [0x%.16x], to = [%d])\n", page->index,
to);
+ /* Fills in zeros if 'to' goes beyond inode size */
rc = fill_zeros_to_end_of_page(page, to);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
@@ -725,82 +427,22 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
page->index);
goto out;
}
- ctx.page = page;
- ctx.mode = ECRYPTFS_PREPARE_COMMIT_MODE;
- ctx.param.lower_file = lower_file;
- rc = ecryptfs_encrypt_page(&ctx);
+ rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
"index [0x%.16x])\n", page->index);
goto out;
}
- inode->i_blocks = lower_inode->i_blocks;
- pos = page_offset(page) + to;
- if (pos > i_size_read(inode)) {
- i_size_write(inode, pos);
+ pos = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + to;
+ if (pos > i_size_read(ecryptfs_inode)) {
+ i_size_write(ecryptfs_inode, pos);
ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
- "[0x%.16x]\n", i_size_read(inode));
+ "[0x%.16x]\n", i_size_read(ecryptfs_inode));
}
- rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode,
- inode, file->f_dentry,
- ECRYPTFS_LOWER_I_MUTEX_HELD);
+ rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
if (rc)
printk(KERN_ERR "Error writing inode size to metadata; "
"rc = [%d]\n", rc);
- lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty_sync(inode);
-out:
- if (rc < 0)
- ClearPageUptodate(page);
- else
- SetPageUptodate(page);
- mutex_unlock(&lower_inode->i_mutex);
- return rc;
-}
-
-/**
- * ecryptfs_write_zeros
- * @file: The ecryptfs file
- * @index: The index in which we are writing
- * @start: The position after the last block of data
- * @num_zeros: The number of zeros to write
- *
- * Write a specified number of zero's to a page.
- *
- * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE
- */
-int
-ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, int num_zeros)
-{
- int rc = 0;
- struct page *tmp_page;
-
- tmp_page = ecryptfs_get1page(file, index);
- if (IS_ERR(tmp_page)) {
- ecryptfs_printk(KERN_ERR, "Error getting page at index "
- "[0x%.16x]\n", index);
- rc = PTR_ERR(tmp_page);
- goto out;
- }
- if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start,
- (start + num_zeros)))) {
- ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
- "to page at index [0x%.16x]\n",
- index);
- page_cache_release(tmp_page);
- goto out;
- }
- zero_user_page(tmp_page, start, num_zeros, KM_USER0);
- rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros);
- if (rc < 0) {
- ecryptfs_printk(KERN_ERR, "Error attempting to write zero's "
- "to remainder of page at index [0x%.16x]\n",
- index);
- page_cache_release(tmp_page);
- goto out;
- }
- rc = 0;
- page_cache_release(tmp_page);
out:
return rc;
}
@@ -819,34 +461,10 @@ static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
return rc;
}
-static void ecryptfs_sync_page(struct page *page)
-{
- struct inode *inode;
- struct inode *lower_inode;
- struct page *lower_page;
-
- inode = page->mapping->host;
- lower_inode = ecryptfs_inode_to_lower(inode);
- /* NOTE: Recently swapped with grab_cache_page(), since
- * sync_page() just makes sure that pending I/O gets done. */
- lower_page = find_lock_page(lower_inode->i_mapping, page->index);
- if (!lower_page) {
- ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n");
- return;
- }
- if (lower_page->mapping->a_ops->sync_page)
- lower_page->mapping->a_ops->sync_page(lower_page);
- ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
- lower_page->index);
- unlock_page(lower_page);
- page_cache_release(lower_page);
-}
-
struct address_space_operations ecryptfs_aops = {
.writepage = ecryptfs_writepage,
.readpage = ecryptfs_readpage,
.prepare_write = ecryptfs_prepare_write,
.commit_write = ecryptfs_commit_write,
.bmap = ecryptfs_bmap,
- .sync_page = ecryptfs_sync_page,
};
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
new file mode 100644
index 00000000000..2150edf9a58
--- /dev/null
+++ b/fs/ecryptfs/read_write.c
@@ -0,0 +1,358 @@
+/**
+ * eCryptfs: Linux filesystem encryption layer
+ *
+ * Copyright (C) 2007 International Business Machines Corp.
+ * Author(s): Michael A. Halcrow <mahalcro@us.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 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/fs.h>
+#include <linux/pagemap.h>
+#include "ecryptfs_kernel.h"
+
+/**
+ * ecryptfs_write_lower
+ * @ecryptfs_inode: The eCryptfs inode
+ * @data: Data to write
+ * @offset: Byte offset in the lower file to which to write the data
+ * @size: Number of bytes from @data to write at @offset in the lower
+ * file
+ *
+ * Write data to the lower file.
+ *
+ * Returns zero on success; non-zero on error
+ */
+int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
+ loff_t offset, size_t size)
+{
+ struct ecryptfs_inode_info *inode_info;
+ ssize_t octets_written;
+ mm_segment_t fs_save;
+ int rc = 0;
+
+ inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
+ mutex_lock(&inode_info->lower_file_mutex);
+ BUG_ON(!inode_info->lower_file);
+ inode_info->lower_file->f_pos = offset;
+ fs_save = get_fs();
+ set_fs(get_ds());
+ octets_written = vfs_write(inode_info->lower_file, data, size,
+ &inode_info->lower_file->f_pos);
+ set_fs(fs_save);
+ if (octets_written < 0) {
+ printk(KERN_ERR "%s: octets_written = [%td]; "
+ "expected [%td]\n", __FUNCTION__, octets_written, size);
+ rc = -EINVAL;
+ }
+ mutex_unlock(&inode_info->lower_file_mutex);
+ mark_inode_dirty_sync(ecryptfs_inode);
+ return rc;
+}
+
+/**
+ * ecryptfs_write_lower_page_segment
+ * @ecryptfs_inode: The eCryptfs inode
+ * @page_for_lower: The page containing the data to be written to the
+ * lower file
+ * @offset_in_page: The offset in the @page_for_lower from which to
+ * start writing the data
+ * @size: The amount of data from @page_for_lower to write to the
+ * lower file
+ *
+ * Determines the byte offset in the file for the given page and
+ * offset within the page, maps the page, and makes the call to write
+ * the contents of @page_for_lower to the lower inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
+ struct page *page_for_lower,
+ size_t offset_in_page, size_t size)
+{
+ char *virt;
+ loff_t offset;
+ int rc;
+
+ offset = ((((off_t)page_for_lower->index) << PAGE_CACHE_SHIFT)
+ + offset_in_page);
+ virt = kmap(page_for_lower);
+ rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);
+ kunmap(page_for_lower);
+ return rc;
+}
+
+/**
+ * ecryptfs_write
+ * @ecryptfs_file: The eCryptfs file into which to write
+ * @data: Virtual address where data to write is located
+ * @offset: Offset in the eCryptfs file at which to begin writing the
+ * data from @data
+ * @size: The number of bytes to write from @data
+ *
+ * Write an arbitrary amount of data to an arbitrary location in the
+ * eCryptfs inode page cache. This is done on a page-by-page, and then
+ * by an extent-by-extent, basis; individual extents are encrypted and
+ * written to the lower page cache (via VFS writes). This function
+ * takes care of all the address translation to locations in the lower
+ * filesystem; it also handles truncate events, writing out zeros
+ * where necessary.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
+ size_t size)
+{
+ struct page *ecryptfs_page;
+ char *ecryptfs_page_virt;
+ loff_t ecryptfs_file_size =
+ i_size_read(ecryptfs_file->f_dentry->d_inode);
+ loff_t data_offset = 0;
+ loff_t pos;
+ int rc = 0;
+
+ if (offset > ecryptfs_file_size)
+ pos = ecryptfs_file_size;
+ else
+ pos = offset;
+ while (pos < (offset + size)) {
+ pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
+ size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
+ size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
+ size_t total_remaining_bytes = ((offset + size) - pos);
+
+ if (num_bytes > total_remaining_bytes)
+ num_bytes = total_remaining_bytes;
+ if (pos < offset) {
+ size_t total_remaining_zeros = (offset - pos);
+
+ if (num_bytes > total_remaining_zeros)
+ num_bytes = total_remaining_zeros;
+ }
+ ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file,
+ ecryptfs_page_idx);
+ if (IS_ERR(ecryptfs_page)) {
+ rc = PTR_ERR(ecryptfs_page);
+ printk(KERN_ERR "%s: Error getting page at "
+ "index [%ld] from eCryptfs inode "
+ "mapping; rc = [%d]\n", __FUNCTION__,
+ ecryptfs_page_idx, rc);
+ goto out;
+ }
+ if (start_offset_in_page) {
+ /* Read in the page from the lower
+ * into the eCryptfs inode page cache,
+ * decrypting */
+ rc = ecryptfs_decrypt_page(ecryptfs_page);
+ if (rc) {
+ printk(KERN_ERR "%s: Error decrypting "
+ "page; rc = [%d]\n",
+ __FUNCTION__, rc);
+ ClearPageUptodate(ecryptfs_page);
+ page_cache_release(ecryptfs_page);
+ goto out;
+ }
+ }
+ ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
+ if (pos >= offset) {
+ memcpy(((char *)ecryptfs_page_virt
+ + start_offset_in_page),
+ (data + data_offset), num_bytes);
+ data_offset += num_bytes;
+ } else {
+ /* We are extending past the previous end of the file.
+ * Fill in zero values up to the start of where we
+ * will be writing data. */
+ memset(((char *)ecryptfs_page_virt
+ + start_offset_in_page), 0, num_bytes);
+ }
+ kunmap_atomic(ecryptfs_page_virt, KM_USER0);
+ flush_dcache_page(ecryptfs_page);
+ SetPageUptodate(ecryptfs_page);
+ unlock_page(ecryptfs_page);
+ rc = ecryptfs_encrypt_page(ecryptfs_page);
+ page_cache_release(ecryptfs_page);
+ if (rc) {
+ printk(KERN_ERR "%s: Error encrypting "
+ "page; rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ pos += num_bytes;
+ }
+ if ((offset + size) > ecryptfs_file_size) {
+ i_size_write(ecryptfs_file->f_dentry->d_inode, (offset + size));
+ rc = ecryptfs_write_inode_size_to_metadata(
+ ecryptfs_file->f_dentry->d_inode);
+ if (rc) {
+ printk(KERN_ERR "Problem with "
+ "ecryptfs_write_inode_size_to_metadata; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_read_lower
+ * @data: The read data is stored here by this function
+ * @offset: Byte offset in the lower file from which to read the data
+ * @size: Number of bytes to read from @offset of the lower file and
+ * store into @data
+ * @ecryptfs_inode: The eCryptfs inode
+ *
+ * Read @size bytes of data at byte offset @offset from the lower
+ * inode into memory location @data.
+ *
+ * Returns zero on success; non-zero on error
+ */
+int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
+ struct inode *ecryptfs_inode)
+{
+ struct ecryptfs_inode_info *inode_info =
+ ecryptfs_inode_to_private(ecryptfs_inode);
+ ssize_t octets_read;
+ mm_segment_t fs_save;
+ int rc = 0;
+
+ mutex_lock(&inode_info->lower_file_mutex);
+ BUG_ON(!inode_info->lower_file);
+ inode_info->lower_file->f_pos = offset;
+ fs_save = get_fs();
+ set_fs(get_ds());
+ octets_read = vfs_read(inode_info->lower_file, data, size,
+ &inode_info->lower_file->f_pos);
+ set_fs(fs_save);
+ if (octets_read < 0) {
+ printk(KERN_ERR "%s: octets_read = [%td]; "
+ "expected [%td]\n", __FUNCTION__, octets_read, size);
+ rc = -EINVAL;
+ }
+ mutex_unlock(&inode_info->lower_file_mutex);
+ return rc;
+}
+
+/**
+ * ecryptfs_read_lower_page_segment
+ * @page_for_ecryptfs: The page into which data for eCryptfs will be
+ * written
+ * @offset_in_page: Offset in @page_for_ecryptfs from which to start
+ * writing
+ * @size: The number of bytes to write into @page_for_ecryptfs
+ * @ecryptfs_inode: The eCryptfs inode
+ *
+ * Determines the byte offset in the file for the given page and
+ * offset within the page, maps the page, and makes the call to read
+ * the contents of @page_for_ecryptfs from the lower inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
+ pgoff_t page_index,
+ size_t offset_in_page, size_t size,
+ struct inode *ecryptfs_inode)
+{
+ char *virt;
+ loff_t offset;
+ int rc;
+
+ offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page);
+ virt = kmap(page_for_ecryptfs);
+ rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);
+ kunmap(page_for_ecryptfs);
+ flush_dcache_page(page_for_ecryptfs);
+ return rc;
+}
+
+/**
+ * ecryptfs_read
+ * @data: The virtual address into which to write the data read (and
+ * possibly decrypted) from the lower file
+ * @offset: The offset in the decrypted view of the file from which to
+ * read into @data
+ * @size: The number of bytes to read into @data
+ * @ecryptfs_file: The eCryptfs file from which to read
+ *
+ * Read an arbitrary amount of data from an arbitrary location in the
+ * eCryptfs page cache. This is done on an extent-by-extent basis;
+ * individual extents are decrypted and read from the lower page
+ * cache (via VFS reads). This function takes care of all the
+ * address translation to locations in the lower filesystem.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_read(char *data, loff_t offset, size_t size,
+ struct file *ecryptfs_file)
+{
+ struct page *ecryptfs_page;
+ char *ecryptfs_page_virt;
+ loff_t ecryptfs_file_size =
+ i_size_read(ecryptfs_file->f_dentry->d_inode);
+ loff_t data_offset = 0;
+ loff_t pos;
+ int rc = 0;
+
+ if ((offset + size) > ecryptfs_file_size) {
+ rc = -EINVAL;
+ printk(KERN_ERR "%s: Attempt to read data past the end of the "
+ "file; offset = [%lld]; size = [%td]; "
+ "ecryptfs_file_size = [%lld]\n",
+ __FUNCTION__, offset, size, ecryptfs_file_size);
+ goto out;
+ }
+ pos = offset;
+ while (pos < (offset + size)) {
+ pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
+ size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
+ size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
+ size_t total_remaining_bytes = ((offset + size) - pos);
+
+ if (num_bytes > total_remaining_bytes)
+ num_bytes = total_remaining_bytes;
+ ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file,
+ ecryptfs_page_idx);
+ if (IS_ERR(ecryptfs_page)) {
+ rc = PTR_ERR(ecryptfs_page);
+ printk(KERN_ERR "%s: Error getting page at "
+ "index [%ld] from eCryptfs inode "
+ "mapping; rc = [%d]\n", __FUNCTION__,
+ ecryptfs_page_idx, rc);
+ goto out;
+ }
+ rc = ecryptfs_decrypt_page(ecryptfs_page);
+ if (rc) {
+ printk(KERN_ERR "%s: Error decrypting "
+ "page; rc = [%d]\n", __FUNCTION__, rc);
+ ClearPageUptodate(ecryptfs_page);
+ page_cache_release(ecryptfs_page);
+ goto out;
+ }
+ ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
+ memcpy((data + data_offset),
+ ((char *)ecryptfs_page_virt + start_offset_in_page),
+ num_bytes);
+ kunmap_atomic(ecryptfs_page_virt, KM_USER0);
+ flush_dcache_page(ecryptfs_page);
+ SetPageUptodate(ecryptfs_page);
+ unlock_page(ecryptfs_page);
+ page_cache_release(ecryptfs_page);
+ pos += num_bytes;
+ data_offset += num_bytes;
+ }
+out:
+ return rc;
+}
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 7b3f0cc09a6..f8cdab2bee3 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -27,6 +27,7 @@
#include <linux/mount.h>
#include <linux/key.h>
#include <linux/seq_file.h>
+#include <linux/file.h>
#include <linux/crypto.h>
#include "ecryptfs_kernel.h"
@@ -46,15 +47,16 @@ struct kmem_cache *ecryptfs_inode_info_cache;
*/
static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
{
- struct ecryptfs_inode_info *ecryptfs_inode;
+ struct ecryptfs_inode_info *inode_info;
struct inode *inode = NULL;
- ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache,
- GFP_KERNEL);
- if (unlikely(!ecryptfs_inode))
+ inode_info = kmem_cache_alloc(ecryptfs_inode_info_cache, GFP_KERNEL);
+ if (unlikely(!inode_info))
goto out;
- ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat);
- inode = &ecryptfs_inode->vfs_inode;
+ ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
+ mutex_init(&inode_info->lower_file_mutex);
+ inode_info->lower_file = NULL;
+ inode = &inode_info->vfs_inode;
out:
return inode;
}
@@ -63,9 +65,10 @@ out:
* ecryptfs_destroy_inode
* @inode: The ecryptfs inode
*
- * This is used during the final destruction of the inode.
- * All allocation of memory related to the inode, including allocated
- * memory in the crypt_stat struct, will be released here.
+ * This is used during the final destruction of the inode. All
+ * allocation of memory related to the inode, including allocated
+ * memory in the crypt_stat struct, will be released here. This
+ * function also fput()'s the persistent file for the lower inode.
* There should be no chance that this deallocation will be missed.
*/
static void ecryptfs_destroy_inode(struct inode *inode)
@@ -73,7 +76,21 @@ static void ecryptfs_destroy_inode(struct inode *inode)
struct ecryptfs_inode_info *inode_info;
inode_info = ecryptfs_inode_to_private(inode);
- ecryptfs_destruct_crypt_stat(&inode_info->crypt_stat);
+ mutex_lock(&inode_info->lower_file_mutex);
+ if (inode_info->lower_file) {
+ struct dentry *lower_dentry =
+ inode_info->lower_file->f_dentry;
+
+ BUG_ON(!lower_dentry);
+ if (lower_dentry->d_inode) {
+ fput(inode_info->lower_file);
+ inode_info->lower_file = NULL;
+ d_drop(lower_dentry);
+ d_delete(lower_dentry);
+ }
+ }
+ mutex_unlock(&inode_info->lower_file_mutex);
+ ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
}
@@ -104,7 +121,7 @@ static void ecryptfs_put_super(struct super_block *sb)
{
struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
- ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat);
+ ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
ecryptfs_set_superblock_private(sb, NULL);
}
diff --git a/fs/efs/super.c b/fs/efs/super.c
index ce4acb8ff81..25d0326c5f1 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -69,7 +69,7 @@ static void efs_destroy_inode(struct inode *inode)
kmem_cache_free(efs_inode_cachep, INODE_INFO(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct efs_inode_info *ei = (struct efs_inode_info *) foo;
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 77b9953624f..de618929195 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -463,7 +463,7 @@ static void ep_free(struct eventpoll *ep)
* holding "epmutex" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
*/
- while ((rbp = rb_first(&ep->rbr)) != 0) {
+ while ((rbp = rb_first(&ep->rbr)) != NULL) {
epi = rb_entry(rbp, struct epitem, rbn);
ep_remove(ep, epi);
}
diff --git a/fs/exec.c b/fs/exec.c
index 073b0b8c6d0..070ddf13cb7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -29,6 +29,7 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/smp_lock.h>
+#include <linux/string.h>
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
@@ -63,52 +64,28 @@ int core_uses_pid;
char core_pattern[CORENAME_MAX_SIZE] = "core";
int suid_dumpable = 0;
-EXPORT_SYMBOL(suid_dumpable);
/* The maximal length of core_pattern is also specified in sysctl.c */
-static struct linux_binfmt *formats;
+static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);
int register_binfmt(struct linux_binfmt * fmt)
{
- struct linux_binfmt ** tmp = &formats;
-
if (!fmt)
return -EINVAL;
- if (fmt->next)
- return -EBUSY;
write_lock(&binfmt_lock);
- while (*tmp) {
- if (fmt == *tmp) {
- write_unlock(&binfmt_lock);
- return -EBUSY;
- }
- tmp = &(*tmp)->next;
- }
- fmt->next = formats;
- formats = fmt;
+ list_add(&fmt->lh, &formats);
write_unlock(&binfmt_lock);
return 0;
}
EXPORT_SYMBOL(register_binfmt);
-int unregister_binfmt(struct linux_binfmt * fmt)
+void unregister_binfmt(struct linux_binfmt * fmt)
{
- struct linux_binfmt ** tmp = &formats;
-
write_lock(&binfmt_lock);
- while (*tmp) {
- if (fmt == *tmp) {
- *tmp = fmt->next;
- fmt->next = NULL;
- write_unlock(&binfmt_lock);
- return 0;
- }
- tmp = &(*tmp)->next;
- }
+ list_del(&fmt->lh);
write_unlock(&binfmt_lock);
- return -EINVAL;
}
EXPORT_SYMBOL(unregister_binfmt);
@@ -134,9 +111,6 @@ asmlinkage long sys_uselib(const char __user * library)
if (error)
goto out;
- error = -EACCES;
- if (nd.mnt->mnt_flags & MNT_NOEXEC)
- goto exit;
error = -EINVAL;
if (!S_ISREG(nd.dentry->d_inode->i_mode))
goto exit;
@@ -155,7 +129,7 @@ asmlinkage long sys_uselib(const char __user * library)
struct linux_binfmt * fmt;
read_lock(&binfmt_lock);
- for (fmt = formats ; fmt ; fmt = fmt->next) {
+ list_for_each_entry(fmt, &formats, lh) {
if (!fmt->load_shlib)
continue;
if (!try_module_get(fmt->module))
@@ -680,8 +654,7 @@ struct file *open_exec(const char *name)
if (!err) {
struct inode *inode = nd.dentry->d_inode;
file = ERR_PTR(-EACCES);
- if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
- S_ISREG(inode->i_mode)) {
+ if (S_ISREG(inode->i_mode)) {
int err = vfs_permission(&nd, MAY_EXEC);
file = ERR_PTR(err);
if (!err) {
@@ -773,24 +746,11 @@ static int exec_mmap(struct mm_struct *mm)
static int de_thread(struct task_struct *tsk)
{
struct signal_struct *sig = tsk->signal;
- struct sighand_struct *newsighand, *oldsighand = tsk->sighand;
+ struct sighand_struct *oldsighand = tsk->sighand;
spinlock_t *lock = &oldsighand->siglock;
struct task_struct *leader = NULL;
int count;
- /*
- * If we don't share sighandlers, then we aren't sharing anything
- * and we can just re-use it all.
- */
- if (atomic_read(&oldsighand->count) <= 1) {
- exit_itimers(sig);
- return 0;
- }
-
- newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
- if (!newsighand)
- return -ENOMEM;
-
if (thread_group_empty(tsk))
goto no_thread_group;
@@ -807,7 +767,6 @@ static int de_thread(struct task_struct *tsk)
*/
spin_unlock_irq(lock);
read_unlock(&tasklist_lock);
- kmem_cache_free(sighand_cachep, newsighand);
return -EAGAIN;
}
@@ -841,16 +800,15 @@ static int de_thread(struct task_struct *tsk)
hrtimer_restart(&sig->real_timer);
spin_lock_irq(lock);
}
+
+ sig->notify_count = count;
+ sig->group_exit_task = tsk;
while (atomic_read(&sig->count) > count) {
- sig->group_exit_task = tsk;
- sig->notify_count = count;
__set_current_state(TASK_UNINTERRUPTIBLE);
spin_unlock_irq(lock);
schedule();
spin_lock_irq(lock);
}
- sig->group_exit_task = NULL;
- sig->notify_count = 0;
spin_unlock_irq(lock);
/*
@@ -859,14 +817,17 @@ static int de_thread(struct task_struct *tsk)
* and to assume its PID:
*/
if (!thread_group_leader(tsk)) {
- /*
- * Wait for the thread group leader to be a zombie.
- * It should already be zombie at this point, most
- * of the time.
- */
leader = tsk->group_leader;
- while (leader->exit_state != EXIT_ZOMBIE)
- yield();
+
+ sig->notify_count = -1;
+ for (;;) {
+ write_lock_irq(&tasklist_lock);
+ if (likely(leader->exit_state))
+ break;
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ write_unlock_irq(&tasklist_lock);
+ schedule();
+ }
/*
* The only record we have of the real-time age of a
@@ -880,8 +841,6 @@ static int de_thread(struct task_struct *tsk)
*/
tsk->start_time = leader->start_time;
- write_lock_irq(&tasklist_lock);
-
BUG_ON(leader->tgid != tsk->tgid);
BUG_ON(tsk->pid == tsk->tgid);
/*
@@ -914,6 +873,8 @@ static int de_thread(struct task_struct *tsk)
write_unlock_irq(&tasklist_lock);
}
+ sig->group_exit_task = NULL;
+ sig->notify_count = 0;
/*
* There may be one thread left which is just exiting,
* but it's safe to stop telling the group to kill themselves.
@@ -925,29 +886,23 @@ no_thread_group:
if (leader)
release_task(leader);
- if (atomic_read(&oldsighand->count) == 1) {
- /*
- * Now that we nuked the rest of the thread group,
- * it turns out we are not sharing sighand any more either.
- * So we can just keep it.
- */
- kmem_cache_free(sighand_cachep, newsighand);
- } else {
+ if (atomic_read(&oldsighand->count) != 1) {
+ struct sighand_struct *newsighand;
/*
- * Move our state over to newsighand and switch it in.
+ * This ->sighand is shared with the CLONE_SIGHAND
+ * but not CLONE_THREAD task, switch to the new one.
*/
+ newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
+ if (!newsighand)
+ return -ENOMEM;
+
atomic_set(&newsighand->count, 1);
memcpy(newsighand->action, oldsighand->action,
sizeof(newsighand->action));
write_lock_irq(&tasklist_lock);
spin_lock(&oldsighand->siglock);
- spin_lock_nested(&newsighand->siglock, SINGLE_DEPTH_NESTING);
-
rcu_assign_pointer(tsk->sighand, newsighand);
- recalc_sigpending();
-
- spin_unlock(&newsighand->siglock);
spin_unlock(&oldsighand->siglock);
write_unlock_irq(&tasklist_lock);
@@ -957,12 +912,11 @@ no_thread_group:
BUG_ON(!thread_group_leader(tsk));
return 0;
}
-
+
/*
* These functions flushes out all traces of the currently running executable
* so that a new one can be started
*/
-
static void flush_old_files(struct files_struct * files)
{
long j = -1;
@@ -1284,7 +1238,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
retval = -ENOENT;
for (try=0; try<2; try++) {
read_lock(&binfmt_lock);
- for (fmt = formats ; fmt ; fmt = fmt->next) {
+ list_for_each_entry(fmt, &formats, lh) {
int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
if (!fn)
continue;
@@ -1537,6 +1491,14 @@ static int format_corename(char *corename, const char *pattern, long signr)
goto out;
out_ptr += rc;
break;
+ /* core limit size */
+ case 'c':
+ rc = snprintf(out_ptr, out_end - out_ptr,
+ "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
+ if (rc > out_end - out_ptr)
+ goto out;
+ out_ptr += rc;
+ break;
default:
break;
}
@@ -1699,7 +1661,6 @@ void set_dumpable(struct mm_struct *mm, int value)
break;
}
}
-EXPORT_SYMBOL_GPL(set_dumpable);
int get_dumpable(struct mm_struct *mm)
{
@@ -1720,6 +1681,10 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
int fsuid = current->fsuid;
int flag = 0;
int ispipe = 0;
+ unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
+ char **helper_argv = NULL;
+ int helper_argc = 0;
+ char *delimit;
audit_core_dumps(signr);
@@ -1753,9 +1718,6 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
*/
clear_thread_flag(TIF_SIGPENDING);
- if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
- goto fail_unlock;
-
/*
* lock_kernel() because format_corename() is controlled by sysctl, which
* uses lock_kernel()
@@ -1763,9 +1725,39 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
lock_kernel();
ispipe = format_corename(corename, core_pattern, signr);
unlock_kernel();
+ /*
+ * Don't bother to check the RLIMIT_CORE value if core_pattern points
+ * to a pipe. Since we're not writing directly to the filesystem
+ * RLIMIT_CORE doesn't really apply, as no actual core file will be
+ * created unless the pipe reader choses to write out the core file
+ * at which point file size limits and permissions will be imposed
+ * as it does with any other process
+ */
+ if ((!ispipe) && (core_limit < binfmt->min_coredump))
+ goto fail_unlock;
+
if (ispipe) {
+ helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
+ /* Terminate the string before the first option */
+ delimit = strchr(corename, ' ');
+ if (delimit)
+ *delimit = '\0';
+ delimit = strrchr(helper_argv[0], '/');
+ if (delimit)
+ delimit++;
+ else
+ delimit = helper_argv[0];
+ if (!strcmp(delimit, current->comm)) {
+ printk(KERN_NOTICE "Recursive core dump detected, "
+ "aborting\n");
+ goto fail_unlock;
+ }
+
+ core_limit = RLIM_INFINITY;
+
/* SIGPIPE can happen, but it's just never processed */
- if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) {
+ if (call_usermodehelper_pipe(corename+1, helper_argv, NULL,
+ &file)) {
printk(KERN_INFO "Core dump to %s pipe failed\n",
corename);
goto fail_unlock;
@@ -1793,13 +1785,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0)
goto close_fail;
- retval = binfmt->core_dump(signr, regs, file);
+ retval = binfmt->core_dump(signr, regs, file, core_limit);
if (retval)
current->signal->group_exit_code |= 0x80;
close_fail:
filp_close(file, NULL);
fail_unlock:
+ if (helper_argv)
+ argv_free(helper_argv);
+
current->fsuid = fsuid;
complete_all(&mm->core_done);
fail:
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index baf71dd721f..18a42de25b5 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -69,6 +69,14 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
return desc + offset;
}
+static inline int
+block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
+{
+ return ext2_test_bit ((block -
+ le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
+ EXT2_BLOCKS_PER_GROUP(sb), map);
+}
+
/*
* Read the bitmap for a given block_group, reading into the specified
* slot in the superblock's bitmap cache.
@@ -78,55 +86,51 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
static struct buffer_head *
read_block_bitmap(struct super_block *sb, unsigned int block_group)
{
+ int i;
struct ext2_group_desc * desc;
struct buffer_head * bh = NULL;
-
+ unsigned int bitmap_blk;
+
desc = ext2_get_group_desc (sb, block_group, NULL);
if (!desc)
- goto error_out;
- bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+ return NULL;
+ bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+ bh = sb_bread(sb, bitmap_blk);
if (!bh)
- ext2_error (sb, "read_block_bitmap",
+ ext2_error (sb, __FUNCTION__,
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %u",
block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
- return bh;
-}
-
-/*
- * Set sb->s_dirt here because the superblock was "logically" altered. We
- * need to recalculate its free blocks count and flush it out.
- */
-static int reserve_blocks(struct super_block *sb, int count)
-{
- struct ext2_sb_info *sbi = EXT2_SB(sb);
- struct ext2_super_block *es = sbi->s_es;
- unsigned free_blocks;
- unsigned root_blocks;
-
- free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
- root_blocks = le32_to_cpu(es->s_r_blocks_count);
- if (free_blocks < count)
- count = free_blocks;
-
- if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
- sbi->s_resuid != current->fsuid &&
- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
- /*
- * We are too close to reserve and we are not privileged.
- * Can we allocate anything at all?
- */
- if (free_blocks > root_blocks)
- count = free_blocks - root_blocks;
- else
- return 0;
+ /* check whether block bitmap block number is set */
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
}
+ /* check whether the inode bitmap block number is set */
+ bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ /* check whether the inode table block number is set */
+ bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+ for (i = 0; i < EXT2_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ }
+
+ return bh;
- percpu_counter_mod(&sbi->s_freeblocks_counter, -count);
- sb->s_dirt = 1;
- return count;
+error_out:
+ brelse(bh);
+ ext2_error(sb, __FUNCTION__,
+ "Invalid block bitmap - "
+ "block_group = %d, block = %u",
+ block_group, bitmap_blk);
+ return NULL;
}
static void release_blocks(struct super_block *sb, int count)
@@ -134,30 +138,12 @@ static void release_blocks(struct super_block *sb, int count)
if (count) {
struct ext2_sb_info *sbi = EXT2_SB(sb);
- percpu_counter_mod(&sbi->s_freeblocks_counter, count);
+ percpu_counter_add(&sbi->s_freeblocks_counter, count);
sb->s_dirt = 1;
}
}
-static int group_reserve_blocks(struct ext2_sb_info *sbi, int group_no,
- struct ext2_group_desc *desc, struct buffer_head *bh, int count)
-{
- unsigned free_blocks;
-
- if (!desc->bg_free_blocks_count)
- return 0;
-
- spin_lock(sb_bgl_lock(sbi, group_no));
- free_blocks = le16_to_cpu(desc->bg_free_blocks_count);
- if (free_blocks < count)
- count = free_blocks;
- desc->bg_free_blocks_count = cpu_to_le16(free_blocks - count);
- spin_unlock(sb_bgl_lock(sbi, group_no));
- mark_buffer_dirty(bh);
- return count;
-}
-
-static void group_release_blocks(struct super_block *sb, int group_no,
+static void group_adjust_blocks(struct super_block *sb, int group_no,
struct ext2_group_desc *desc, struct buffer_head *bh, int count)
{
if (count) {
@@ -173,7 +159,306 @@ static void group_release_blocks(struct super_block *sb, int group_no,
}
}
-/* Free given blocks, update quota and i_blocks field */
+/*
+ * The reservation window structure operations
+ * --------------------------------------------
+ * Operations include:
+ * dump, find, add, remove, is_empty, find_next_reservable_window, etc.
+ *
+ * We use a red-black tree to represent per-filesystem reservation
+ * windows.
+ *
+ */
+
+/**
+ * __rsv_window_dump() -- Dump the filesystem block allocation reservation map
+ * @rb_root: root of per-filesystem reservation rb tree
+ * @verbose: verbose mode
+ * @fn: function which wishes to dump the reservation map
+ *
+ * If verbose is turned on, it will print the whole block reservation
+ * windows(start, end). Otherwise, it will only print out the "bad" windows,
+ * those windows that overlap with their immediate neighbors.
+ */
+#if 1
+static void __rsv_window_dump(struct rb_root *root, int verbose,
+ const char *fn)
+{
+ struct rb_node *n;
+ struct ext2_reserve_window_node *rsv, *prev;
+ int bad;
+
+restart:
+ n = rb_first(root);
+ bad = 0;
+ prev = NULL;
+
+ printk("Block Allocation Reservation Windows Map (%s):\n", fn);
+ while (n) {
+ rsv = rb_entry(n, struct ext2_reserve_window_node, rsv_node);
+ if (verbose)
+ printk("reservation window 0x%p "
+ "start: %lu, end: %lu\n",
+ rsv, rsv->rsv_start, rsv->rsv_end);
+ if (rsv->rsv_start && rsv->rsv_start >= rsv->rsv_end) {
+ printk("Bad reservation %p (start >= end)\n",
+ rsv);
+ bad = 1;
+ }
+ if (prev && prev->rsv_end >= rsv->rsv_start) {
+ printk("Bad reservation %p (prev->end >= start)\n",
+ rsv);
+ bad = 1;
+ }
+ if (bad) {
+ if (!verbose) {
+ printk("Restarting reservation walk in verbose mode\n");
+ verbose = 1;
+ goto restart;
+ }
+ }
+ n = rb_next(n);
+ prev = rsv;
+ }
+ printk("Window map complete.\n");
+ if (bad)
+ BUG();
+}
+#define rsv_window_dump(root, verbose) \
+ __rsv_window_dump((root), (verbose), __FUNCTION__)
+#else
+#define rsv_window_dump(root, verbose) do {} while (0)
+#endif
+
+/**
+ * goal_in_my_reservation()
+ * @rsv: inode's reservation window
+ * @grp_goal: given goal block relative to the allocation block group
+ * @group: the current allocation block group
+ * @sb: filesystem super block
+ *
+ * Test if the given goal block (group relative) is within the file's
+ * own block reservation window range.
+ *
+ * If the reservation window is outside the goal allocation group, return 0;
+ * grp_goal (given goal block) could be -1, which means no specific
+ * goal block. In this case, always return 1.
+ * If the goal block is within the reservation window, return 1;
+ * otherwise, return 0;
+ */
+static int
+goal_in_my_reservation(struct ext2_reserve_window *rsv, ext2_grpblk_t grp_goal,
+ unsigned int group, struct super_block * sb)
+{
+ ext2_fsblk_t group_first_block, group_last_block;
+
+ group_first_block = ext2_group_first_block_no(sb, group);
+ group_last_block = group_first_block + EXT2_BLOCKS_PER_GROUP(sb) - 1;
+
+ if ((rsv->_rsv_start > group_last_block) ||
+ (rsv->_rsv_end < group_first_block))
+ return 0;
+ if ((grp_goal >= 0) && ((grp_goal + group_first_block < rsv->_rsv_start)
+ || (grp_goal + group_first_block > rsv->_rsv_end)))
+ return 0;
+ return 1;
+}
+
+/**
+ * search_reserve_window()
+ * @rb_root: root of reservation tree
+ * @goal: target allocation block
+ *
+ * Find the reserved window which includes the goal, or the previous one
+ * if the goal is not in any window.
+ * Returns NULL if there are no windows or if all windows start after the goal.
+ */
+static struct ext2_reserve_window_node *
+search_reserve_window(struct rb_root *root, ext2_fsblk_t goal)
+{
+ struct rb_node *n = root->rb_node;
+ struct ext2_reserve_window_node *rsv;
+
+ if (!n)
+ return NULL;
+
+ do {
+ rsv = rb_entry(n, struct ext2_reserve_window_node, rsv_node);
+
+ if (goal < rsv->rsv_start)
+ n = n->rb_left;
+ else if (goal > rsv->rsv_end)
+ n = n->rb_right;
+ else
+ return rsv;
+ } while (n);
+ /*
+ * We've fallen off the end of the tree: the goal wasn't inside
+ * any particular node. OK, the previous node must be to one
+ * side of the interval containing the goal. If it's the RHS,
+ * we need to back up one.
+ */
+ if (rsv->rsv_start > goal) {
+ n = rb_prev(&rsv->rsv_node);
+ rsv = rb_entry(n, struct ext2_reserve_window_node, rsv_node);
+ }
+ return rsv;
+}
+
+/*
+ * ext2_rsv_window_add() -- Insert a window to the block reservation rb tree.
+ * @sb: super block
+ * @rsv: reservation window to add
+ *
+ * Must be called with rsv_lock held.
+ */
+void ext2_rsv_window_add(struct super_block *sb,
+ struct ext2_reserve_window_node *rsv)
+{
+ struct rb_root *root = &EXT2_SB(sb)->s_rsv_window_root;
+ struct rb_node *node = &rsv->rsv_node;
+ ext2_fsblk_t start = rsv->rsv_start;
+
+ struct rb_node ** p = &root->rb_node;
+ struct rb_node * parent = NULL;
+ struct ext2_reserve_window_node *this;
+
+ while (*p)
+ {
+ parent = *p;
+ this = rb_entry(parent, struct ext2_reserve_window_node, rsv_node);
+
+ if (start < this->rsv_start)
+ p = &(*p)->rb_left;
+ else if (start > this->rsv_end)
+ p = &(*p)->rb_right;
+ else {
+ rsv_window_dump(root, 1);
+ BUG();
+ }
+ }
+
+ rb_link_node(node, parent, p);
+ rb_insert_color(node, root);
+}
+
+/**
+ * rsv_window_remove() -- unlink a window from the reservation rb tree
+ * @sb: super block
+ * @rsv: reservation window to remove
+ *
+ * Mark the block reservation window as not allocated, and unlink it
+ * from the filesystem reservation window rb tree. Must be called with
+ * rsv_lock held.
+ */
+static void rsv_window_remove(struct super_block *sb,
+ struct ext2_reserve_window_node *rsv)
+{
+ rsv->rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ rsv->rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ rsv->rsv_alloc_hit = 0;
+ rb_erase(&rsv->rsv_node, &EXT2_SB(sb)->s_rsv_window_root);
+}
+
+/*
+ * rsv_is_empty() -- Check if the reservation window is allocated.
+ * @rsv: given reservation window to check
+ *
+ * returns 1 if the end block is EXT2_RESERVE_WINDOW_NOT_ALLOCATED.
+ */
+static inline int rsv_is_empty(struct ext2_reserve_window *rsv)
+{
+ /* a valid reservation end block could not be 0 */
+ return (rsv->_rsv_end == EXT2_RESERVE_WINDOW_NOT_ALLOCATED);
+}
+
+/**
+ * ext2_init_block_alloc_info()
+ * @inode: file inode structure
+ *
+ * Allocate and initialize the reservation window structure, and
+ * link the window to the ext2 inode structure at last
+ *
+ * The reservation window structure is only dynamically allocated
+ * and linked to ext2 inode the first time the open file
+ * needs a new block. So, before every ext2_new_block(s) call, for
+ * regular files, we should check whether the reservation window
+ * structure exists or not. In the latter case, this function is called.
+ * Fail to do so will result in block reservation being turned off for that
+ * open file.
+ *
+ * This function is called from ext2_get_blocks_handle(), also called
+ * when setting the reservation window size through ioctl before the file
+ * is open for write (needs block allocation).
+ *
+ * Needs truncate_mutex protection prior to calling this function.
+ */
+void ext2_init_block_alloc_info(struct inode *inode)
+{
+ struct ext2_inode_info *ei = EXT2_I(inode);
+ struct ext2_block_alloc_info *block_i = ei->i_block_alloc_info;
+ struct super_block *sb = inode->i_sb;
+
+ block_i = kmalloc(sizeof(*block_i), GFP_NOFS);
+ if (block_i) {
+ struct ext2_reserve_window_node *rsv = &block_i->rsv_window_node;
+
+ rsv->rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ rsv->rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+
+ /*
+ * if filesystem is mounted with NORESERVATION, the goal
+ * reservation window size is set to zero to indicate
+ * block reservation is off
+ */
+ if (!test_opt(sb, RESERVATION))
+ rsv->rsv_goal_size = 0;
+ else
+ rsv->rsv_goal_size = EXT2_DEFAULT_RESERVE_BLOCKS;
+ rsv->rsv_alloc_hit = 0;
+ block_i->last_alloc_logical_block = 0;
+ block_i->last_alloc_physical_block = 0;
+ }
+ ei->i_block_alloc_info = block_i;
+}
+
+/**
+ * ext2_discard_reservation()
+ * @inode: inode
+ *
+ * Discard(free) block reservation window on last file close, or truncate
+ * or at last iput().
+ *
+ * It is being called in three cases:
+ * ext2_release_file(): last writer closes the file
+ * ext2_clear_inode(): last iput(), when nobody links to this file.
+ * ext2_truncate(): when the block indirect map is about to change.
+ */
+void ext2_discard_reservation(struct inode *inode)
+{
+ struct ext2_inode_info *ei = EXT2_I(inode);
+ struct ext2_block_alloc_info *block_i = ei->i_block_alloc_info;
+ struct ext2_reserve_window_node *rsv;
+ spinlock_t *rsv_lock = &EXT2_SB(inode->i_sb)->s_rsv_window_lock;
+
+ if (!block_i)
+ return;
+
+ rsv = &block_i->rsv_window_node;
+ if (!rsv_is_empty(&rsv->rsv_window)) {
+ spin_lock(rsv_lock);
+ if (!rsv_is_empty(&rsv->rsv_window))
+ rsv_window_remove(inode->i_sb, rsv);
+ spin_unlock(rsv_lock);
+ }
+}
+
+/**
+ * ext2_free_blocks_sb() -- Free given blocks and update quota and i_blocks
+ * @inode: inode
+ * @block: start physcial block to free
+ * @count: number of blocks to free
+ */
void ext2_free_blocks (struct inode * inode, unsigned long block,
unsigned long count)
{
@@ -248,7 +533,7 @@ do_more:
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bitmap_bh);
- group_release_blocks(sb, block_group, desc, bh2, group_freed);
+ group_adjust_blocks(sb, block_group, desc, bh2, group_freed);
freed += group_freed;
if (overflow) {
@@ -262,16 +547,46 @@ error_return:
DQUOT_FREE_BLOCK(inode, freed);
}
-static int grab_block(spinlock_t *lock, char *map, unsigned size, int goal)
+/**
+ * bitmap_search_next_usable_block()
+ * @start: the starting block (group relative) of the search
+ * @bh: bufferhead contains the block group bitmap
+ * @maxblocks: the ending block (group relative) of the reservation
+ *
+ * The bitmap search --- search forward through the actual bitmap on disk until
+ * we find a bit free.
+ */
+static ext2_grpblk_t
+bitmap_search_next_usable_block(ext2_grpblk_t start, struct buffer_head *bh,
+ ext2_grpblk_t maxblocks)
{
- int k;
- char *p, *r;
+ ext2_grpblk_t next;
- if (!ext2_test_bit(goal, map))
- goto got_it;
+ next = ext2_find_next_zero_bit(bh->b_data, maxblocks, start);
+ if (next >= maxblocks)
+ return -1;
+ return next;
+}
-repeat:
- if (goal) {
+/**
+ * find_next_usable_block()
+ * @start: the starting block (group relative) to find next
+ * allocatable block in bitmap.
+ * @bh: bufferhead contains the block group bitmap
+ * @maxblocks: the ending block (group relative) for the search
+ *
+ * Find an allocatable block in a bitmap. We perform the "most
+ * appropriate allocation" algorithm of looking for a free block near
+ * the initial goal; then for a free byte somewhere in the bitmap;
+ * then for any free bit in the bitmap.
+ */
+static ext2_grpblk_t
+find_next_usable_block(int start, struct buffer_head *bh, int maxblocks)
+{
+ ext2_grpblk_t here, next;
+ char *p, *r;
+
+ if (start > 0) {
/*
* The goal was occupied; search forward for a free
* block within the next XX blocks.
@@ -280,249 +595,812 @@ repeat:
* less than EXT2_BLOCKS_PER_GROUP. Aligning up to the
* next 64-bit boundary is simple..
*/
- k = (goal + 63) & ~63;
- goal = ext2_find_next_zero_bit(map, k, goal);
- if (goal < k)
- goto got_it;
+ ext2_grpblk_t end_goal = (start + 63) & ~63;
+ if (end_goal > maxblocks)
+ end_goal = maxblocks;
+ here = ext2_find_next_zero_bit(bh->b_data, end_goal, start);
+ if (here < end_goal)
+ return here;
+ ext2_debug("Bit not found near goal\n");
+ }
+
+ here = start;
+ if (here < 0)
+ here = 0;
+
+ p = ((char *)bh->b_data) + (here >> 3);
+ r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3));
+ next = (r - ((char *)bh->b_data)) << 3;
+
+ if (next < maxblocks && next >= here)
+ return next;
+
+ here = bitmap_search_next_usable_block(here, bh, maxblocks);
+ return here;
+}
+
+/*
+ * ext2_try_to_allocate()
+ * @sb: superblock
+ * @handle: handle to this transaction
+ * @group: given allocation block group
+ * @bitmap_bh: bufferhead holds the block bitmap
+ * @grp_goal: given target block within the group
+ * @count: target number of blocks to allocate
+ * @my_rsv: reservation window
+ *
+ * Attempt to allocate blocks within a give range. Set the range of allocation
+ * first, then find the first free bit(s) from the bitmap (within the range),
+ * and at last, allocate the blocks by claiming the found free bit as allocated.
+ *
+ * To set the range of this allocation:
+ * if there is a reservation window, only try to allocate block(s)
+ * from the file's own reservation window;
+ * Otherwise, the allocation range starts from the give goal block,
+ * ends at the block group's last block.
+ *
+ * If we failed to allocate the desired block then we may end up crossing to a
+ * new bitmap.
+ */
+static int
+ext2_try_to_allocate(struct super_block *sb, int group,
+ struct buffer_head *bitmap_bh, ext2_grpblk_t grp_goal,
+ unsigned long *count,
+ struct ext2_reserve_window *my_rsv)
+{
+ ext2_fsblk_t group_first_block;
+ ext2_grpblk_t start, end;
+ unsigned long num = 0;
+
+ /* we do allocation within the reservation window if we have a window */
+ if (my_rsv) {
+ group_first_block = ext2_group_first_block_no(sb, group);
+ if (my_rsv->_rsv_start >= group_first_block)
+ start = my_rsv->_rsv_start - group_first_block;
+ else
+ /* reservation window cross group boundary */
+ start = 0;
+ end = my_rsv->_rsv_end - group_first_block + 1;
+ if (end > EXT2_BLOCKS_PER_GROUP(sb))
+ /* reservation window crosses group boundary */
+ end = EXT2_BLOCKS_PER_GROUP(sb);
+ if ((start <= grp_goal) && (grp_goal < end))
+ start = grp_goal;
+ else
+ grp_goal = -1;
+ } else {
+ if (grp_goal > 0)
+ start = grp_goal;
+ else
+ start = 0;
+ end = EXT2_BLOCKS_PER_GROUP(sb);
+ }
+
+ BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb));
+
+repeat:
+ if (grp_goal < 0) {
+ grp_goal = find_next_usable_block(start, bitmap_bh, end);
+ if (grp_goal < 0)
+ goto fail_access;
+ if (!my_rsv) {
+ int i;
+
+ for (i = 0; i < 7 && grp_goal > start &&
+ !ext2_test_bit(grp_goal - 1,
+ bitmap_bh->b_data);
+ i++, grp_goal--)
+ ;
+ }
+ }
+ start = grp_goal;
+
+ if (ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group), grp_goal,
+ bitmap_bh->b_data)) {
+ /*
+ * The block was allocated by another thread, or it was
+ * allocated and then freed by another thread
+ */
+ start++;
+ grp_goal++;
+ if (start >= end)
+ goto fail_access;
+ goto repeat;
+ }
+ num++;
+ grp_goal++;
+ while (num < *count && grp_goal < end
+ && !ext2_set_bit_atomic(sb_bgl_lock(EXT2_SB(sb), group),
+ grp_goal, bitmap_bh->b_data)) {
+ num++;
+ grp_goal++;
+ }
+ *count = num;
+ return grp_goal - num;
+fail_access:
+ *count = num;
+ return -1;
+}
+
+/**
+ * find_next_reservable_window():
+ * find a reservable space within the given range.
+ * It does not allocate the reservation window for now:
+ * alloc_new_reservation() will do the work later.
+ *
+ * @search_head: the head of the searching list;
+ * This is not necessarily the list head of the whole filesystem
+ *
+ * We have both head and start_block to assist the search
+ * for the reservable space. The list starts from head,
+ * but we will shift to the place where start_block is,
+ * then start from there, when looking for a reservable space.
+ *
+ * @size: the target new reservation window size
+ *
+ * @group_first_block: the first block we consider to start
+ * the real search from
+ *
+ * @last_block:
+ * the maximum block number that our goal reservable space
+ * could start from. This is normally the last block in this
+ * group. The search will end when we found the start of next
+ * possible reservable space is out of this boundary.
+ * This could handle the cross boundary reservation window
+ * request.
+ *
+ * basically we search from the given range, rather than the whole
+ * reservation double linked list, (start_block, last_block)
+ * to find a free region that is of my size and has not
+ * been reserved.
+ *
+ */
+static int find_next_reservable_window(
+ struct ext2_reserve_window_node *search_head,
+ struct ext2_reserve_window_node *my_rsv,
+ struct super_block * sb,
+ ext2_fsblk_t start_block,
+ ext2_fsblk_t last_block)
+{
+ struct rb_node *next;
+ struct ext2_reserve_window_node *rsv, *prev;
+ ext2_fsblk_t cur;
+ int size = my_rsv->rsv_goal_size;
+
+ /* TODO: make the start of the reservation window byte-aligned */
+ /* cur = *start_block & ~7;*/
+ cur = start_block;
+ rsv = search_head;
+ if (!rsv)
+ return -1;
+
+ while (1) {
+ if (cur <= rsv->rsv_end)
+ cur = rsv->rsv_end + 1;
+
+ /* TODO?
+ * in the case we could not find a reservable space
+ * that is what is expected, during the re-search, we could
+ * remember what's the largest reservable space we could have
+ * and return that one.
+ *
+ * For now it will fail if we could not find the reservable
+ * space with expected-size (or more)...
+ */
+ if (cur > last_block)
+ return -1; /* fail */
+
+ prev = rsv;
+ next = rb_next(&rsv->rsv_node);
+ rsv = rb_entry(next,struct ext2_reserve_window_node,rsv_node);
+
+ /*
+ * Reached the last reservation, we can just append to the
+ * previous one.
+ */
+ if (!next)
+ break;
+
+ if (cur + size <= rsv->rsv_start) {
+ /*
+ * Found a reserveable space big enough. We could
+ * have a reservation across the group boundary here
+ */
+ break;
+ }
+ }
+ /*
+ * we come here either :
+ * when we reach the end of the whole list,
+ * and there is empty reservable space after last entry in the list.
+ * append it to the end of the list.
+ *
+ * or we found one reservable space in the middle of the list,
+ * return the reservation window that we could append to.
+ * succeed.
+ */
+
+ if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
+ rsv_window_remove(sb, my_rsv);
+
+ /*
+ * Let's book the whole avaliable window for now. We will check the
+ * disk bitmap later and then, if there are free blocks then we adjust
+ * the window size if it's larger than requested.
+ * Otherwise, we will remove this node from the tree next time
+ * call find_next_reservable_window.
+ */
+ my_rsv->rsv_start = cur;
+ my_rsv->rsv_end = cur + size - 1;
+ my_rsv->rsv_alloc_hit = 0;
+
+ if (prev != my_rsv)
+ ext2_rsv_window_add(sb, my_rsv);
+
+ return 0;
+}
+
+/**
+ * alloc_new_reservation()--allocate a new reservation window
+ *
+ * To make a new reservation, we search part of the filesystem
+ * reservation list (the list that inside the group). We try to
+ * allocate a new reservation window near the allocation goal,
+ * or the beginning of the group, if there is no goal.
+ *
+ * We first find a reservable space after the goal, then from
+ * there, we check the bitmap for the first free block after
+ * it. If there is no free block until the end of group, then the
+ * whole group is full, we failed. Otherwise, check if the free
+ * block is inside the expected reservable space, if so, we
+ * succeed.
+ * If the first free block is outside the reservable space, then
+ * start from the first free block, we search for next available
+ * space, and go on.
+ *
+ * on succeed, a new reservation will be found and inserted into the list
+ * It contains at least one free block, and it does not overlap with other
+ * reservation windows.
+ *
+ * failed: we failed to find a reservation window in this group
+ *
+ * @rsv: the reservation
+ *
+ * @grp_goal: The goal (group-relative). It is where the search for a
+ * free reservable space should start from.
+ * if we have a goal(goal >0 ), then start from there,
+ * no goal(goal = -1), we start from the first block
+ * of the group.
+ *
+ * @sb: the super block
+ * @group: the group we are trying to allocate in
+ * @bitmap_bh: the block group block bitmap
+ *
+ */
+static int alloc_new_reservation(struct ext2_reserve_window_node *my_rsv,
+ ext2_grpblk_t grp_goal, struct super_block *sb,
+ unsigned int group, struct buffer_head *bitmap_bh)
+{
+ struct ext2_reserve_window_node *search_head;
+ ext2_fsblk_t group_first_block, group_end_block, start_block;
+ ext2_grpblk_t first_free_block;
+ struct rb_root *fs_rsv_root = &EXT2_SB(sb)->s_rsv_window_root;
+ unsigned long size;
+ int ret;
+ spinlock_t *rsv_lock = &EXT2_SB(sb)->s_rsv_window_lock;
+
+ group_first_block = ext2_group_first_block_no(sb, group);
+ group_end_block = group_first_block + (EXT2_BLOCKS_PER_GROUP(sb) - 1);
+
+ if (grp_goal < 0)
+ start_block = group_first_block;
+ else
+ start_block = grp_goal + group_first_block;
+
+ size = my_rsv->rsv_goal_size;
+
+ if (!rsv_is_empty(&my_rsv->rsv_window)) {
/*
- * Search in the remainder of the current group.
+ * if the old reservation is cross group boundary
+ * and if the goal is inside the old reservation window,
+ * we will come here when we just failed to allocate from
+ * the first part of the window. We still have another part
+ * that belongs to the next group. In this case, there is no
+ * point to discard our window and try to allocate a new one
+ * in this group(which will fail). we should
+ * keep the reservation window, just simply move on.
+ *
+ * Maybe we could shift the start block of the reservation
+ * window to the first block of next group.
*/
+
+ if ((my_rsv->rsv_start <= group_end_block) &&
+ (my_rsv->rsv_end > group_end_block) &&
+ (start_block >= my_rsv->rsv_start))
+ return -1;
+
+ if ((my_rsv->rsv_alloc_hit >
+ (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) {
+ /*
+ * if the previously allocation hit ratio is
+ * greater than 1/2, then we double the size of
+ * the reservation window the next time,
+ * otherwise we keep the same size window
+ */
+ size = size * 2;
+ if (size > EXT2_MAX_RESERVE_BLOCKS)
+ size = EXT2_MAX_RESERVE_BLOCKS;
+ my_rsv->rsv_goal_size= size;
+ }
}
- p = map + (goal >> 3);
- r = memscan(p, 0, (size - goal + 7) >> 3);
- k = (r - map) << 3;
- if (k < size) {
- /*
- * We have succeeded in finding a free byte in the block
- * bitmap. Now search backwards to find the start of this
- * group of free blocks - won't take more than 7 iterations.
+ spin_lock(rsv_lock);
+ /*
+ * shift the search start to the window near the goal block
+ */
+ search_head = search_reserve_window(fs_rsv_root, start_block);
+
+ /*
+ * find_next_reservable_window() simply finds a reservable window
+ * inside the given range(start_block, group_end_block).
+ *
+ * To make sure the reservation window has a free bit inside it, we
+ * need to check the bitmap after we found a reservable window.
+ */
+retry:
+ ret = find_next_reservable_window(search_head, my_rsv, sb,
+ start_block, group_end_block);
+
+ if (ret == -1) {
+ if (!rsv_is_empty(&my_rsv->rsv_window))
+ rsv_window_remove(sb, my_rsv);
+ spin_unlock(rsv_lock);
+ return -1;
+ }
+
+ /*
+ * On success, find_next_reservable_window() returns the
+ * reservation window where there is a reservable space after it.
+ * Before we reserve this reservable space, we need
+ * to make sure there is at least a free block inside this region.
+ *
+ * Search the first free bit on the block bitmap. Search starts from
+ * the start block of the reservable space we just found.
+ */
+ spin_unlock(rsv_lock);
+ first_free_block = bitmap_search_next_usable_block(
+ my_rsv->rsv_start - group_first_block,
+ bitmap_bh, group_end_block - group_first_block + 1);
+
+ if (first_free_block < 0) {
+ /*
+ * no free block left on the bitmap, no point
+ * to reserve the space. return failed.
*/
- for (goal = k; goal && !ext2_test_bit (goal - 1, map); goal--)
- ;
- goto got_it;
+ spin_lock(rsv_lock);
+ if (!rsv_is_empty(&my_rsv->rsv_window))
+ rsv_window_remove(sb, my_rsv);
+ spin_unlock(rsv_lock);
+ return -1; /* failed */
}
- k = ext2_find_next_zero_bit ((u32 *)map, size, goal);
- if (k < size) {
- goal = k;
- goto got_it;
+ start_block = first_free_block + group_first_block;
+ /*
+ * check if the first free block is within the
+ * free space we just reserved
+ */
+ if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end)
+ return 0; /* success */
+ /*
+ * if the first free bit we found is out of the reservable space
+ * continue search for next reservable space,
+ * start from where the free block is,
+ * we also shift the list head to where we stopped last time
+ */
+ search_head = my_rsv;
+ spin_lock(rsv_lock);
+ goto retry;
+}
+
+/**
+ * try_to_extend_reservation()
+ * @my_rsv: given reservation window
+ * @sb: super block
+ * @size: the delta to extend
+ *
+ * Attempt to expand the reservation window large enough to have
+ * required number of free blocks
+ *
+ * Since ext2_try_to_allocate() will always allocate blocks within
+ * the reservation window range, if the window size is too small,
+ * multiple blocks allocation has to stop at the end of the reservation
+ * window. To make this more efficient, given the total number of
+ * blocks needed and the current size of the window, we try to
+ * expand the reservation window size if necessary on a best-effort
+ * basis before ext2_new_blocks() tries to allocate blocks.
+ */
+static void try_to_extend_reservation(struct ext2_reserve_window_node *my_rsv,
+ struct super_block *sb, int size)
+{
+ struct ext2_reserve_window_node *next_rsv;
+ struct rb_node *next;
+ spinlock_t *rsv_lock = &EXT2_SB(sb)->s_rsv_window_lock;
+
+ if (!spin_trylock(rsv_lock))
+ return;
+
+ next = rb_next(&my_rsv->rsv_node);
+
+ if (!next)
+ my_rsv->rsv_end += size;
+ else {
+ next_rsv = rb_entry(next, struct ext2_reserve_window_node, rsv_node);
+
+ if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size)
+ my_rsv->rsv_end += size;
+ else
+ my_rsv->rsv_end = next_rsv->rsv_start - 1;
}
- return -1;
-got_it:
- if (ext2_set_bit_atomic(lock, goal, (void *) map))
- goto repeat;
- return goal;
+ spin_unlock(rsv_lock);
+}
+
+/**
+ * ext2_try_to_allocate_with_rsv()
+ * @sb: superblock
+ * @group: given allocation block group
+ * @bitmap_bh: bufferhead holds the block bitmap
+ * @grp_goal: given target block within the group
+ * @count: target number of blocks to allocate
+ * @my_rsv: reservation window
+ *
+ * This is the main function used to allocate a new block and its reservation
+ * window.
+ *
+ * Each time when a new block allocation is need, first try to allocate from
+ * its own reservation. If it does not have a reservation window, instead of
+ * looking for a free bit on bitmap first, then look up the reservation list to
+ * see if it is inside somebody else's reservation window, we try to allocate a
+ * reservation window for it starting from the goal first. Then do the block
+ * allocation within the reservation window.
+ *
+ * This will avoid keeping on searching the reservation list again and
+ * again when somebody is looking for a free block (without
+ * reservation), and there are lots of free blocks, but they are all
+ * being reserved.
+ *
+ * We use a red-black tree for the per-filesystem reservation list.
+ */
+static ext2_grpblk_t
+ext2_try_to_allocate_with_rsv(struct super_block *sb, unsigned int group,
+ struct buffer_head *bitmap_bh, ext2_grpblk_t grp_goal,
+ struct ext2_reserve_window_node * my_rsv,
+ unsigned long *count)
+{
+ ext2_fsblk_t group_first_block, group_last_block;
+ ext2_grpblk_t ret = 0;
+ unsigned long num = *count;
+
+ /*
+ * we don't deal with reservation when
+ * filesystem is mounted without reservation
+ * or the file is not a regular file
+ * or last attempt to allocate a block with reservation turned on failed
+ */
+ if (my_rsv == NULL) {
+ return ext2_try_to_allocate(sb, group, bitmap_bh,
+ grp_goal, count, NULL);
+ }
+ /*
+ * grp_goal is a group relative block number (if there is a goal)
+ * 0 <= grp_goal < EXT2_BLOCKS_PER_GROUP(sb)
+ * first block is a filesystem wide block number
+ * first block is the block number of the first block in this group
+ */
+ group_first_block = ext2_group_first_block_no(sb, group);
+ group_last_block = group_first_block + (EXT2_BLOCKS_PER_GROUP(sb) - 1);
+
+ /*
+ * Basically we will allocate a new block from inode's reservation
+ * window.
+ *
+ * We need to allocate a new reservation window, if:
+ * a) inode does not have a reservation window; or
+ * b) last attempt to allocate a block from existing reservation
+ * failed; or
+ * c) we come here with a goal and with a reservation window
+ *
+ * We do not need to allocate a new reservation window if we come here
+ * at the beginning with a goal and the goal is inside the window, or
+ * we don't have a goal but already have a reservation window.
+ * then we could go to allocate from the reservation window directly.
+ */
+ while (1) {
+ if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
+ !goal_in_my_reservation(&my_rsv->rsv_window,
+ grp_goal, group, sb)) {
+ if (my_rsv->rsv_goal_size < *count)
+ my_rsv->rsv_goal_size = *count;
+ ret = alloc_new_reservation(my_rsv, grp_goal, sb,
+ group, bitmap_bh);
+ if (ret < 0)
+ break; /* failed */
+
+ if (!goal_in_my_reservation(&my_rsv->rsv_window,
+ grp_goal, group, sb))
+ grp_goal = -1;
+ } else if (grp_goal >= 0) {
+ int curr = my_rsv->rsv_end -
+ (grp_goal + group_first_block) + 1;
+
+ if (curr < *count)
+ try_to_extend_reservation(my_rsv, sb,
+ *count - curr);
+ }
+
+ if ((my_rsv->rsv_start > group_last_block) ||
+ (my_rsv->rsv_end < group_first_block)) {
+ rsv_window_dump(&EXT2_SB(sb)->s_rsv_window_root, 1);
+ BUG();
+ }
+ ret = ext2_try_to_allocate(sb, group, bitmap_bh, grp_goal,
+ &num, &my_rsv->rsv_window);
+ if (ret >= 0) {
+ my_rsv->rsv_alloc_hit += num;
+ *count = num;
+ break; /* succeed */
+ }
+ num = *count;
+ }
+ return ret;
+}
+
+/**
+ * ext2_has_free_blocks()
+ * @sbi: in-core super block structure.
+ *
+ * Check if filesystem has at least 1 free block available for allocation.
+ */
+static int ext2_has_free_blocks(struct ext2_sb_info *sbi)
+{
+ ext2_fsblk_t free_blocks, root_blocks;
+
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
+ root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
+ if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
+ sbi->s_resuid != current->fsuid &&
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
+ return 0;
+ }
+ return 1;
}
/*
- * ext2_new_block uses a goal block to assist allocation. If the goal is
+ * ext2_new_blocks() -- core block(s) allocation function
+ * @inode: file inode
+ * @goal: given target block(filesystem wide)
+ * @count: target number of blocks to allocate
+ * @errp: error code
+ *
+ * ext2_new_blocks uses a goal block to assist allocation. If the goal is
* free, or there is a free block within 32 blocks of the goal, that block
* is allocated. Otherwise a forward search is made for a free block; within
* each block group the search first looks for an entire free byte in the block
* bitmap, and then for any free bit if that fails.
* This function also updates quota and i_blocks field.
*/
-int ext2_new_block(struct inode *inode, unsigned long goal,
- u32 *prealloc_count, u32 *prealloc_block, int *err)
+ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
+ unsigned long *count, int *errp)
{
struct buffer_head *bitmap_bh = NULL;
- struct buffer_head *gdp_bh; /* bh2 */
- struct ext2_group_desc *desc;
- int group_no; /* i */
- int ret_block; /* j */
- int group_idx; /* k */
- int target_block; /* tmp */
- int block = 0;
- struct super_block *sb = inode->i_sb;
- struct ext2_sb_info *sbi = EXT2_SB(sb);
- struct ext2_super_block *es = sbi->s_es;
- unsigned group_size = EXT2_BLOCKS_PER_GROUP(sb);
- unsigned prealloc_goal = es->s_prealloc_blocks;
- unsigned group_alloc = 0, es_alloc, dq_alloc;
- int nr_scanned_groups;
-
- if (!prealloc_goal--)
- prealloc_goal = EXT2_DEFAULT_PREALLOC_BLOCKS - 1;
- if (!prealloc_count || *prealloc_count)
- prealloc_goal = 0;
-
- if (DQUOT_ALLOC_BLOCK(inode, 1)) {
- *err = -EDQUOT;
- goto out;
+ struct buffer_head *gdp_bh;
+ int group_no;
+ int goal_group;
+ ext2_grpblk_t grp_target_blk; /* blockgroup relative goal block */
+ ext2_grpblk_t grp_alloc_blk; /* blockgroup-relative allocated block*/
+ ext2_fsblk_t ret_block; /* filesyetem-wide allocated block */
+ int bgi; /* blockgroup iteration index */
+ int performed_allocation = 0;
+ ext2_grpblk_t free_blocks; /* number of free blocks in a group */
+ struct super_block *sb;
+ struct ext2_group_desc *gdp;
+ struct ext2_super_block *es;
+ struct ext2_sb_info *sbi;
+ struct ext2_reserve_window_node *my_rsv = NULL;
+ struct ext2_block_alloc_info *block_i;
+ unsigned short windowsz = 0;
+ unsigned long ngroups;
+ unsigned long num = *count;
+
+ *errp = -ENOSPC;
+ sb = inode->i_sb;
+ if (!sb) {
+ printk("ext2_new_blocks: nonexistent device");
+ return 0;
}
- while (prealloc_goal && DQUOT_PREALLOC_BLOCK(inode, prealloc_goal))
- prealloc_goal--;
+ /*
+ * Check quota for allocation of this block.
+ */
+ if (DQUOT_ALLOC_BLOCK(inode, num)) {
+ *errp = -EDQUOT;
+ return 0;
+ }
- dq_alloc = prealloc_goal + 1;
- es_alloc = reserve_blocks(sb, dq_alloc);
- if (!es_alloc) {
- *err = -ENOSPC;
- goto out_dquot;
+ sbi = EXT2_SB(sb);
+ es = EXT2_SB(sb)->s_es;
+ ext2_debug("goal=%lu.\n", goal);
+ /*
+ * Allocate a block from reservation only when
+ * filesystem is mounted with reservation(default,-o reservation), and
+ * it's a regular file, and
+ * the desired window size is greater than 0 (One could use ioctl
+ * command EXT2_IOC_SETRSVSZ to set the window size to 0 to turn off
+ * reservation on that particular file)
+ */
+ block_i = EXT2_I(inode)->i_block_alloc_info;
+ if (block_i) {
+ windowsz = block_i->rsv_window_node.rsv_goal_size;
+ if (windowsz > 0)
+ my_rsv = &block_i->rsv_window_node;
}
- ext2_debug ("goal=%lu.\n", goal);
+ if (!ext2_has_free_blocks(sbi)) {
+ *errp = -ENOSPC;
+ goto out;
+ }
+ /*
+ * First, test whether the goal block is free.
+ */
if (goal < le32_to_cpu(es->s_first_data_block) ||
goal >= le32_to_cpu(es->s_blocks_count))
goal = le32_to_cpu(es->s_first_data_block);
- group_no = (goal - le32_to_cpu(es->s_first_data_block)) / group_size;
- desc = ext2_get_group_desc (sb, group_no, &gdp_bh);
- if (!desc) {
- /*
- * gdp_bh may still be uninitialised. But group_release_blocks
- * will not touch it because group_alloc is zero.
- */
+ group_no = (goal - le32_to_cpu(es->s_first_data_block)) /
+ EXT2_BLOCKS_PER_GROUP(sb);
+ goal_group = group_no;
+retry_alloc:
+ gdp = ext2_get_group_desc(sb, group_no, &gdp_bh);
+ if (!gdp)
goto io_error;
- }
- group_alloc = group_reserve_blocks(sbi, group_no, desc,
- gdp_bh, es_alloc);
- if (group_alloc) {
- ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
- group_size);
- brelse(bitmap_bh);
+ free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
+ /*
+ * if there is not enough free blocks to make a new resevation
+ * turn off reservation for this allocation
+ */
+ if (my_rsv && (free_blocks < windowsz)
+ && (rsv_is_empty(&my_rsv->rsv_window)))
+ my_rsv = NULL;
+
+ if (free_blocks > 0) {
+ grp_target_blk = ((goal - le32_to_cpu(es->s_first_data_block)) %
+ EXT2_BLOCKS_PER_GROUP(sb));
bitmap_bh = read_block_bitmap(sb, group_no);
if (!bitmap_bh)
goto io_error;
-
- ext2_debug("goal is at %d:%d.\n", group_no, ret_block);
-
- ret_block = grab_block(sb_bgl_lock(sbi, group_no),
- bitmap_bh->b_data, group_size, ret_block);
- if (ret_block >= 0)
- goto got_block;
- group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
- group_alloc = 0;
+ grp_alloc_blk = ext2_try_to_allocate_with_rsv(sb, group_no,
+ bitmap_bh, grp_target_blk,
+ my_rsv, &num);
+ if (grp_alloc_blk >= 0)
+ goto allocated;
}
- ext2_debug ("Bit not found in block group %d.\n", group_no);
+ ngroups = EXT2_SB(sb)->s_groups_count;
+ smp_rmb();
/*
* Now search the rest of the groups. We assume that
- * i and desc correctly point to the last group visited.
+ * i and gdp correctly point to the last group visited.
*/
- nr_scanned_groups = 0;
-retry:
- for (group_idx = 0; !group_alloc &&
- group_idx < sbi->s_groups_count; group_idx++) {
+ for (bgi = 0; bgi < ngroups; bgi++) {
group_no++;
- if (group_no >= sbi->s_groups_count)
+ if (group_no >= ngroups)
group_no = 0;
- desc = ext2_get_group_desc(sb, group_no, &gdp_bh);
- if (!desc)
+ gdp = ext2_get_group_desc(sb, group_no, &gdp_bh);
+ if (!gdp)
goto io_error;
- group_alloc = group_reserve_blocks(sbi, group_no, desc,
- gdp_bh, es_alloc);
- }
- if (!group_alloc) {
- *err = -ENOSPC;
- goto out_release;
- }
- brelse(bitmap_bh);
- bitmap_bh = read_block_bitmap(sb, group_no);
- if (!bitmap_bh)
- goto io_error;
- ret_block = grab_block(sb_bgl_lock(sbi, group_no), bitmap_bh->b_data,
- group_size, 0);
- if (ret_block < 0) {
+ free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
/*
- * If a free block counter is corrupted we can loop inifintely.
- * Detect that here.
+ * skip this group if the number of
+ * free blocks is less than half of the reservation
+ * window size.
*/
- nr_scanned_groups++;
- if (nr_scanned_groups > 2 * sbi->s_groups_count) {
- ext2_error(sb, "ext2_new_block",
- "corrupted free blocks counters");
+ if (free_blocks <= (windowsz/2))
+ continue;
+
+ brelse(bitmap_bh);
+ bitmap_bh = read_block_bitmap(sb, group_no);
+ if (!bitmap_bh)
goto io_error;
- }
/*
- * Someone else grabbed the last free block in this blockgroup
- * before us. Retry the scan.
+ * try to allocate block(s) from this group, without a goal(-1).
*/
- group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
- group_alloc = 0;
- goto retry;
+ grp_alloc_blk = ext2_try_to_allocate_with_rsv(sb, group_no,
+ bitmap_bh, -1, my_rsv, &num);
+ if (grp_alloc_blk >= 0)
+ goto allocated;
+ }
+ /*
+ * We may end up a bogus ealier ENOSPC error due to
+ * filesystem is "full" of reservations, but
+ * there maybe indeed free blocks avaliable on disk
+ * In this case, we just forget about the reservations
+ * just do block allocation as without reservations.
+ */
+ if (my_rsv) {
+ my_rsv = NULL;
+ windowsz = 0;
+ group_no = goal_group;
+ goto retry_alloc;
}
+ /* No space left on the device */
+ *errp = -ENOSPC;
+ goto out;
+
+allocated:
-got_block:
ext2_debug("using block group %d(%d)\n",
- group_no, desc->bg_free_blocks_count);
+ group_no, gdp->bg_free_blocks_count);
- target_block = ret_block + group_no * group_size +
- le32_to_cpu(es->s_first_data_block);
+ ret_block = grp_alloc_blk + ext2_group_first_block_no(sb, group_no);
- if (target_block == le32_to_cpu(desc->bg_block_bitmap) ||
- target_block == le32_to_cpu(desc->bg_inode_bitmap) ||
- in_range(target_block, le32_to_cpu(desc->bg_inode_table),
- sbi->s_itb_per_group))
- ext2_error (sb, "ext2_new_block",
+ if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) ||
+ in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) ||
+ in_range(ret_block, le32_to_cpu(gdp->bg_inode_table),
+ EXT2_SB(sb)->s_itb_per_group) ||
+ in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
+ EXT2_SB(sb)->s_itb_per_group))
+ ext2_error(sb, "ext2_new_blocks",
"Allocating block in system zone - "
- "block = %u", target_block);
+ "blocks from "E2FSBLK", length %lu",
+ ret_block, num);
+
+ performed_allocation = 1;
- if (target_block >= le32_to_cpu(es->s_blocks_count)) {
- ext2_error (sb, "ext2_new_block",
- "block(%d) >= blocks count(%d) - "
+ if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
+ ext2_error(sb, "ext2_new_blocks",
+ "block("E2FSBLK") >= blocks count(%d) - "
"block_group = %d, es == %p ", ret_block,
le32_to_cpu(es->s_blocks_count), group_no, es);
- goto io_error;
+ goto out;
}
- block = target_block;
- /* OK, we _had_ allocated something */
- ext2_debug("found bit %d\n", ret_block);
-
- dq_alloc--;
- es_alloc--;
- group_alloc--;
-
- /*
- * Do block preallocation now if required.
- */
- write_lock(&EXT2_I(inode)->i_meta_lock);
- if (group_alloc && !*prealloc_count) {
- unsigned n;
-
- for (n = 0; n < group_alloc && ++ret_block < group_size; n++) {
- if (ext2_set_bit_atomic(sb_bgl_lock(sbi, group_no),
- ret_block,
- (void*) bitmap_bh->b_data))
- break;
- }
- *prealloc_block = block + 1;
- *prealloc_count = n;
- es_alloc -= n;
- dq_alloc -= n;
- group_alloc -= n;
- }
- write_unlock(&EXT2_I(inode)->i_meta_lock);
+ group_adjust_blocks(sb, group_no, gdp, gdp_bh, -num);
+ percpu_counter_sub(&sbi->s_freeblocks_counter, num);
mark_buffer_dirty(bitmap_bh);
if (sb->s_flags & MS_SYNCHRONOUS)
sync_dirty_buffer(bitmap_bh);
- ext2_debug ("allocating block %d. ", block);
+ *errp = 0;
+ brelse(bitmap_bh);
+ DQUOT_FREE_BLOCK(inode, *count-num);
+ *count = num;
+ return ret_block;
- *err = 0;
-out_release:
- group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
- release_blocks(sb, es_alloc);
-out_dquot:
- DQUOT_FREE_BLOCK(inode, dq_alloc);
+io_error:
+ *errp = -EIO;
out:
+ /*
+ * Undo the block allocation
+ */
+ if (!performed_allocation)
+ DQUOT_FREE_BLOCK(inode, *count);
brelse(bitmap_bh);
- return block;
+ return 0;
+}
-io_error:
- *err = -EIO;
- goto out_release;
+ext2_fsblk_t ext2_new_block(struct inode *inode, unsigned long goal, int *errp)
+{
+ unsigned long count = 1;
+
+ return ext2_new_blocks(inode, goal, &count, errp);
}
#ifdef EXT2FS_DEBUG
-static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
{
@@ -583,13 +1461,6 @@ unsigned long ext2_count_free_blocks (struct super_block * sb)
#endif
}
-static inline int
-block_in_use(unsigned long block, struct super_block *sb, unsigned char *map)
-{
- return ext2_test_bit ((block -
- le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block)) %
- EXT2_BLOCKS_PER_GROUP(sb), map);
-}
static inline int test_root(int a, int b)
{
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 2bf49d7ef84..05d9342bb64 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -22,7 +22,9 @@
*/
#include "ext2.h"
+#include <linux/buffer_head.h>
#include <linux/pagemap.h>
+#include <linux/swap.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
@@ -61,16 +63,25 @@ ext2_last_byte(struct inode *inode, unsigned long page_nr)
return last_byte;
}
-static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
+static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
- struct inode *dir = page->mapping->host;
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
int err = 0;
+
dir->i_version++;
- page->mapping->a_ops->commit_write(NULL, page, from, to);
+ block_write_end(NULL, mapping, pos, len, len, page, NULL);
+
+ if (pos+len > dir->i_size) {
+ i_size_write(dir, pos+len);
+ mark_inode_dirty(dir);
+ }
+
if (IS_DIRSYNC(dir))
err = write_one_page(page, 1);
else
unlock_page(page);
+
return err;
}
@@ -412,16 +423,18 @@ ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
struct page *page, struct inode *inode)
{
- unsigned from = (char *) de - (char *) page_address(page);
- unsigned to = from + le16_to_cpu(de->rec_len);
+ loff_t pos = page_offset(page) +
+ (char *) de - (char *) page_address(page);
+ unsigned len = le16_to_cpu(de->rec_len);
int err;
lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __ext2_write_begin(NULL, page->mapping, pos, len,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
BUG_ON(err);
de->inode = cpu_to_le32(inode->i_ino);
- ext2_set_de_type (de, inode);
- err = ext2_commit_chunk(page, from, to);
+ ext2_set_de_type(de, inode);
+ err = ext2_commit_chunk(page, pos, len);
ext2_put_page(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
@@ -444,7 +457,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
unsigned long npages = dir_pages(dir);
unsigned long n;
char *kaddr;
- unsigned from, to;
+ loff_t pos;
int err;
/*
@@ -497,9 +510,10 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
return -EINVAL;
got_it:
- from = (char*)de - (char*)page_address(page);
- to = from + rec_len;
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ pos = page_offset(page) +
+ (char*)de - (char*)page_address(page);
+ err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
+ &page, NULL);
if (err)
goto out_unlock;
if (de->inode) {
@@ -509,10 +523,10 @@ got_it:
de = de1;
}
de->name_len = namelen;
- memcpy (de->name, name, namelen);
+ memcpy(de->name, name, namelen);
de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type (de, inode);
- err = ext2_commit_chunk(page, from, to);
+ err = ext2_commit_chunk(page, pos, rec_len);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
mark_inode_dirty(dir);
@@ -537,6 +551,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
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);
+ loff_t pos;
ext2_dirent * pde = NULL;
ext2_dirent * de = (ext2_dirent *) (kaddr + from);
int err;
@@ -553,13 +568,15 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
}
if (pde)
from = (char*)pde - (char*)page_address(page);
+ pos = page_offset(page) + from;
lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
+ &page, NULL);
BUG_ON(err);
if (pde)
- pde->rec_len = cpu_to_le16(to-from);
+ pde->rec_len = cpu_to_le16(to - from);
dir->inode = 0;
- err = ext2_commit_chunk(page, from, to);
+ err = ext2_commit_chunk(page, pos, to - from);
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
mark_inode_dirty(inode);
@@ -582,7 +599,9 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
if (!page)
return -ENOMEM;
- err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
+
+ err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
+ &page, NULL);
if (err) {
unlock_page(page);
goto fail;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 9fd0ec5ba0d..7730388c493 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -33,22 +33,9 @@ struct ext2_inode_info {
*/
__u32 i_block_group;
- /*
- * i_next_alloc_block is the logical (file-relative) number of the
- * most-recently-allocated block in this file. Yes, it is misnamed.
- * We use this for detecting linearly ascending allocation requests.
- */
- __u32 i_next_alloc_block;
+ /* block reservation info */
+ struct ext2_block_alloc_info *i_block_alloc_info;
- /*
- * i_next_alloc_goal is the *physical* companion to i_next_alloc_block.
- * it the the physical block number of the block which was most-recently
- * allocated to this file. This give us the goal (target) for the next
- * allocation when we detect linearly ascending requests.
- */
- __u32 i_next_alloc_goal;
- __u32 i_prealloc_block;
- __u32 i_prealloc_count;
__u32 i_dir_start_lookup;
#ifdef CONFIG_EXT2_FS_XATTR
/*
@@ -65,7 +52,16 @@ struct ext2_inode_info {
struct posix_acl *i_default_acl;
#endif
rwlock_t i_meta_lock;
+
+ /*
+ * truncate_mutex is for serialising ext2_truncate() against
+ * ext2_getblock(). It also protects the internals of the inode's
+ * reservation data structures: ext2_reserve_window and
+ * ext2_reserve_window_node.
+ */
+ struct mutex truncate_mutex;
struct inode vfs_inode;
+ struct list_head i_orphan; /* unlinked but open inodes */
};
/*
@@ -91,8 +87,9 @@ static inline struct ext2_inode_info *EXT2_I(struct inode *inode)
/* balloc.c */
extern int ext2_bg_has_super(struct super_block *sb, int group);
extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
-extern int ext2_new_block (struct inode *, unsigned long,
- __u32 *, __u32 *, int *);
+extern ext2_fsblk_t ext2_new_block(struct inode *, unsigned long, int *);
+extern ext2_fsblk_t ext2_new_blocks(struct inode *, unsigned long,
+ unsigned long *, int *);
extern void ext2_free_blocks (struct inode *, unsigned long,
unsigned long);
extern unsigned long ext2_count_free_blocks (struct super_block *);
@@ -101,6 +98,10 @@ extern void ext2_check_blocks_bitmap (struct super_block *);
extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
unsigned int block_group,
struct buffer_head ** bh);
+extern void ext2_discard_reservation (struct inode *);
+extern int ext2_should_retry_alloc(struct super_block *sb, int *retries);
+extern void ext2_init_block_alloc_info(struct inode *);
+extern void ext2_rsv_window_add(struct super_block *sb, struct ext2_reserve_window_node *rsv);
/* dir.c */
extern int ext2_add_link (struct dentry *, struct inode *);
@@ -128,12 +129,14 @@ extern int ext2_write_inode (struct inode *, int);
extern void ext2_put_inode (struct inode *);
extern void ext2_delete_inode (struct inode *);
extern int ext2_sync_inode (struct inode *);
-extern void ext2_discard_prealloc (struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern void ext2_truncate (struct inode *);
extern int ext2_setattr (struct dentry *, struct iattr *);
extern void ext2_set_inode_flags(struct inode *inode);
extern void ext2_get_inode_flags(struct ext2_inode_info *);
+int __ext2_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
/* ioctl.c */
extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index ab7961260c4..c051798459a 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -30,8 +30,11 @@
*/
static int ext2_release_file (struct inode * inode, struct file * filp)
{
- if (filp->f_mode & FMODE_WRITE)
- ext2_discard_prealloc (inode);
+ if (filp->f_mode & FMODE_WRITE) {
+ mutex_lock(&EXT2_I(inode)->truncate_mutex);
+ ext2_discard_reservation(inode);
+ mutex_unlock(&EXT2_I(inode)->truncate_mutex);
+ }
return 0;
}
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 2cb545bf0f3..5deb8b74e64 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -177,7 +177,6 @@ static void ext2_preread_inode(struct inode *inode)
unsigned long block_group;
unsigned long offset;
unsigned long block;
- struct buffer_head *bh;
struct ext2_group_desc * gdp;
struct backing_dev_info *bdi;
@@ -188,7 +187,7 @@ static void ext2_preread_inode(struct inode *inode)
return;
block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
- gdp = ext2_get_group_desc(inode->i_sb, block_group, &bh);
+ gdp = ext2_get_group_desc(inode->i_sb, block_group, NULL);
if (gdp == NULL)
return;
@@ -217,11 +216,10 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
int ngroups = EXT2_SB(sb)->s_groups_count;
int avefreei = ext2_count_free_inodes(sb) / ngroups;
struct ext2_group_desc *desc, *best_desc = NULL;
- struct buffer_head *bh, *best_bh = NULL;
int group, best_group = -1;
for (group = 0; group < ngroups; group++) {
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
@@ -231,7 +229,6 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
le16_to_cpu(best_desc->bg_free_blocks_count))) {
best_group = group;
best_desc = desc;
- best_bh = bh;
}
}
if (!best_desc)
@@ -284,7 +281,6 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
int max_debt, max_dirs, min_blocks, min_inodes;
int group = -1, i;
struct ext2_group_desc *desc;
- struct buffer_head *bh;
freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
avefreei = freei / ngroups;
@@ -295,7 +291,6 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
if ((parent == sb->s_root->d_inode) ||
(EXT2_I(parent)->i_flags & EXT2_TOPDIR_FL)) {
struct ext2_group_desc *best_desc = NULL;
- struct buffer_head *best_bh = NULL;
int best_ndir = inodes_per_group;
int best_group = -1;
@@ -303,7 +298,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
parent_group = (unsigned)group % ngroups;
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
@@ -315,11 +310,9 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
best_group = group;
best_ndir = le16_to_cpu(desc->bg_used_dirs_count);
best_desc = desc;
- best_bh = bh;
}
if (best_group >= 0) {
desc = best_desc;
- bh = best_bh;
group = best_group;
goto found;
}
@@ -345,7 +338,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (sbi->s_debts[group] >= max_debt)
@@ -362,7 +355,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
fallback:
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
@@ -389,14 +382,13 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
int parent_group = EXT2_I(parent)->i_block_group;
int ngroups = EXT2_SB(sb)->s_groups_count;
struct ext2_group_desc *desc;
- struct buffer_head *bh;
int group, i;
/*
* Try to place the inode in its parent directory
*/
group = parent_group;
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
le16_to_cpu(desc->bg_free_blocks_count))
goto found;
@@ -420,7 +412,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
group += i;
if (group >= ngroups)
group -= ngroups;
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
le16_to_cpu(desc->bg_free_blocks_count))
goto found;
@@ -434,7 +426,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
for (i = 0; i < ngroups; i++) {
if (++group >= ngroups)
group = 0;
- desc = ext2_get_group_desc (sb, group, &bh);
+ desc = ext2_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count))
goto found;
}
@@ -542,7 +534,7 @@ got:
goto fail;
}
- percpu_counter_mod(&sbi->s_freeinodes_counter, -1);
+ percpu_counter_add(&sbi->s_freeinodes_counter, -1);
if (S_ISDIR(mode))
percpu_counter_inc(&sbi->s_dirs_counter);
@@ -589,11 +581,8 @@ got:
ei->i_file_acl = 0;
ei->i_dir_acl = 0;
ei->i_dtime = 0;
+ ei->i_block_alloc_info = NULL;
ei->i_block_group = group;
- ei->i_next_alloc_block = 0;
- ei->i_next_alloc_goal = 0;
- ei->i_prealloc_block = 0;
- ei->i_prealloc_count = 0;
ei->i_dir_start_lookup = 0;
ei->i_state = EXT2_STATE_NEW;
ext2_set_inode_flags(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 0079b2cd531..b1ab32ab5a7 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -54,19 +54,6 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode)
}
/*
- * Called at each iput().
- *
- * The inode may be "bad" if ext2_read_inode() saw an error from
- * ext2_get_inode(), so we need to check that to avoid freeing random disk
- * blocks.
- */
-void ext2_put_inode(struct inode *inode)
-{
- if (!is_bad_inode(inode))
- ext2_discard_prealloc(inode);
-}
-
-/*
* Called at the last iput() if i_nlink is zero.
*/
void ext2_delete_inode (struct inode * inode)
@@ -89,61 +76,6 @@ no_delete:
clear_inode(inode); /* We must guarantee clearing of inode... */
}
-void ext2_discard_prealloc (struct inode * inode)
-{
-#ifdef EXT2_PREALLOCATE
- struct ext2_inode_info *ei = EXT2_I(inode);
- write_lock(&ei->i_meta_lock);
- if (ei->i_prealloc_count) {
- unsigned short total = ei->i_prealloc_count;
- unsigned long block = ei->i_prealloc_block;
- ei->i_prealloc_count = 0;
- ei->i_prealloc_block = 0;
- write_unlock(&ei->i_meta_lock);
- ext2_free_blocks (inode, block, total);
- return;
- } else
- write_unlock(&ei->i_meta_lock);
-#endif
-}
-
-static int ext2_alloc_block (struct inode * inode, unsigned long goal, int *err)
-{
-#ifdef EXT2FS_DEBUG
- static unsigned long alloc_hits, alloc_attempts;
-#endif
- unsigned long result;
-
-
-#ifdef EXT2_PREALLOCATE
- struct ext2_inode_info *ei = EXT2_I(inode);
- write_lock(&ei->i_meta_lock);
- if (ei->i_prealloc_count &&
- (goal == ei->i_prealloc_block || goal + 1 == ei->i_prealloc_block))
- {
- result = ei->i_prealloc_block++;
- ei->i_prealloc_count--;
- write_unlock(&ei->i_meta_lock);
- ext2_debug ("preallocation hit (%lu/%lu).\n",
- ++alloc_hits, ++alloc_attempts);
- } else {
- write_unlock(&ei->i_meta_lock);
- ext2_discard_prealloc (inode);
- ext2_debug ("preallocation miss (%lu/%lu).\n",
- alloc_hits, ++alloc_attempts);
- if (S_ISREG(inode->i_mode))
- result = ext2_new_block (inode, goal,
- &ei->i_prealloc_count,
- &ei->i_prealloc_block, err);
- else
- result = ext2_new_block(inode, goal, NULL, NULL, err);
- }
-#else
- result = ext2_new_block (inode, goal, 0, 0, err);
-#endif
- return result;
-}
-
typedef struct {
__le32 *p;
__le32 key;
@@ -228,7 +160,8 @@ static int ext2_block_to_path(struct inode *inode,
ext2_warning (inode->i_sb, "ext2_block_to_path", "block > big");
}
if (boundary)
- *boundary = (i_block & (ptrs - 1)) == (final - 1);
+ *boundary = final - 1 - (i_block & (ptrs - 1));
+
return n;
}
@@ -355,39 +288,129 @@ static unsigned long ext2_find_near(struct inode *inode, Indirect *ind)
* @block: block we want
* @chain: chain of indirect blocks
* @partial: pointer to the last triple within a chain
- * @goal: place to store the result.
*
- * Normally this function find the prefered place for block allocation,
- * stores it in *@goal and returns zero. If the branch had been changed
- * under us we return -EAGAIN.
+ * Returns preferred place for a block (the goal).
*/
static inline int ext2_find_goal(struct inode *inode,
long block,
Indirect chain[4],
- Indirect *partial,
- unsigned long *goal)
+ Indirect *partial)
{
- struct ext2_inode_info *ei = EXT2_I(inode);
- write_lock(&ei->i_meta_lock);
- if ((block == ei->i_next_alloc_block + 1) && ei->i_next_alloc_goal) {
- ei->i_next_alloc_block++;
- ei->i_next_alloc_goal++;
- }
- if (verify_chain(chain, partial)) {
- /*
- * try the heuristic for sequential allocation,
- * failing that at least try to get decent locality.
- */
- if (block == ei->i_next_alloc_block)
- *goal = ei->i_next_alloc_goal;
- if (!*goal)
- *goal = ext2_find_near(inode, partial);
- write_unlock(&ei->i_meta_lock);
- return 0;
+ struct ext2_block_alloc_info *block_i;
+
+ block_i = EXT2_I(inode)->i_block_alloc_info;
+
+ /*
+ * try the heuristic for sequential allocation,
+ * failing that at least try to get decent locality.
+ */
+ if (block_i && (block == block_i->last_alloc_logical_block + 1)
+ && (block_i->last_alloc_physical_block != 0)) {
+ return block_i->last_alloc_physical_block + 1;
+ }
+
+ return ext2_find_near(inode, partial);
+}
+
+/**
+ * ext2_blks_to_allocate: Look up the block map and count the number
+ * of direct blocks need to be allocated for the given branch.
+ *
+ * @branch: chain of indirect blocks
+ * @k: number of blocks need for indirect blocks
+ * @blks: number of data blocks to be mapped.
+ * @blocks_to_boundary: the offset in the indirect block
+ *
+ * return the total number of blocks to be allocate, including the
+ * direct and indirect blocks.
+ */
+static int
+ext2_blks_to_allocate(Indirect * branch, int k, unsigned long blks,
+ int blocks_to_boundary)
+{
+ unsigned long count = 0;
+
+ /*
+ * Simple case, [t,d]Indirect block(s) has not allocated yet
+ * then it's clear blocks on that path have not allocated
+ */
+ if (k > 0) {
+ /* right now don't hanel cross boundary allocation */
+ if (blks < blocks_to_boundary + 1)
+ count += blks;
+ else
+ count += blocks_to_boundary + 1;
+ return count;
+ }
+
+ count++;
+ while (count < blks && count <= blocks_to_boundary
+ && le32_to_cpu(*(branch[0].p + count)) == 0) {
+ count++;
}
- write_unlock(&ei->i_meta_lock);
- return -EAGAIN;
+ return count;
+}
+
+/**
+ * ext2_alloc_blocks: multiple allocate blocks needed for a branch
+ * @indirect_blks: the number of blocks need to allocate for indirect
+ * blocks
+ *
+ * @new_blocks: on return it will store the new block numbers for
+ * the indirect blocks(if needed) and the first direct block,
+ * @blks: on return it will store the total number of allocated
+ * direct blocks
+ */
+static int ext2_alloc_blocks(struct inode *inode,
+ ext2_fsblk_t goal, int indirect_blks, int blks,
+ ext2_fsblk_t new_blocks[4], int *err)
+{
+ int target, i;
+ unsigned long count = 0;
+ int index = 0;
+ ext2_fsblk_t current_block = 0;
+ int ret = 0;
+
+ /*
+ * Here we try to allocate the requested multiple blocks at once,
+ * on a best-effort basis.
+ * To build a branch, we should allocate blocks for
+ * the indirect blocks(if not allocated yet), and at least
+ * the first direct block of this branch. That's the
+ * minimum number of blocks need to allocate(required)
+ */
+ target = blks + indirect_blks;
+
+ while (1) {
+ count = target;
+ /* allocating blocks for indirect blocks and direct blocks */
+ current_block = ext2_new_blocks(inode,goal,&count,err);
+ if (*err)
+ goto failed_out;
+
+ target -= count;
+ /* allocate blocks for indirect blocks */
+ while (index < indirect_blks && count) {
+ new_blocks[index++] = current_block++;
+ count--;
+ }
+
+ if (count > 0)
+ break;
+ }
+
+ /* save the new block number for the first direct block */
+ new_blocks[index] = current_block;
+
+ /* total number of blocks allocated for direct blocks */
+ ret = count;
+ *err = 0;
+ return ret;
+failed_out:
+ for (i = 0; i <index; i++)
+ ext2_free_blocks(inode, new_blocks[i], 1);
+ return ret;
}
/**
@@ -416,39 +439,49 @@ static inline int ext2_find_goal(struct inode *inode,
*/
static int ext2_alloc_branch(struct inode *inode,
- int num,
- unsigned long goal,
- int *offsets,
- Indirect *branch)
+ int indirect_blks, int *blks, ext2_fsblk_t goal,
+ int *offsets, Indirect *branch)
{
int blocksize = inode->i_sb->s_blocksize;
- int n = 0;
- int err;
- int i;
- int parent = ext2_alloc_block(inode, goal, &err);
-
- branch[0].key = cpu_to_le32(parent);
- if (parent) for (n = 1; n < num; n++) {
- struct buffer_head *bh;
- /* Allocate the next block */
- int nr = ext2_alloc_block(inode, parent, &err);
- if (!nr)
- break;
- branch[n].key = cpu_to_le32(nr);
+ int i, n = 0;
+ int err = 0;
+ struct buffer_head *bh;
+ int num;
+ ext2_fsblk_t new_blocks[4];
+ ext2_fsblk_t current_block;
+
+ num = ext2_alloc_blocks(inode, goal, indirect_blks,
+ *blks, new_blocks, &err);
+ if (err)
+ return err;
+
+ branch[0].key = cpu_to_le32(new_blocks[0]);
+ /*
+ * metadata blocks and data blocks are allocated.
+ */
+ for (n = 1; n <= indirect_blks; n++) {
/*
- * Get buffer_head for parent block, zero it out and set
- * the pointer to new one, then send parent to disk.
+ * Get buffer_head for parent block, zero it out
+ * and set the pointer to new one, then send
+ * parent to disk.
*/
- bh = sb_getblk(inode->i_sb, parent);
- if (!bh) {
- err = -EIO;
- break;
- }
+ bh = sb_getblk(inode->i_sb, new_blocks[n-1]);
+ branch[n].bh = bh;
lock_buffer(bh);
memset(bh->b_data, 0, blocksize);
- branch[n].bh = bh;
branch[n].p = (__le32 *) bh->b_data + offsets[n];
+ branch[n].key = cpu_to_le32(new_blocks[n]);
*branch[n].p = branch[n].key;
+ if ( n == indirect_blks) {
+ current_block = new_blocks[n];
+ /*
+ * End of chain, update the last new metablock of
+ * the chain to point to the new allocated
+ * data blocks numbers
+ */
+ for (i=1; i < num; i++)
+ *(branch[n].p + i) = cpu_to_le32(++current_block);
+ }
set_buffer_uptodate(bh);
unlock_buffer(bh);
mark_buffer_dirty_inode(bh, inode);
@@ -458,77 +491,68 @@ static int ext2_alloc_branch(struct inode *inode,
*/
if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode))
sync_dirty_buffer(bh);
- parent = nr;
}
- if (n == num)
- return 0;
-
- /* Allocation failed, free what we already allocated */
- for (i = 1; i < n; i++)
- bforget(branch[i].bh);
- for (i = 0; i < n; i++)
- ext2_free_blocks(inode, le32_to_cpu(branch[i].key), 1);
+ *blks = num;
return err;
}
/**
- * ext2_splice_branch - splice the allocated branch onto inode.
- * @inode: owner
- * @block: (logical) number of block we are adding
- * @chain: chain of indirect blocks (with a missing link - see
- * ext2_alloc_branch)
- * @where: location of missing link
- * @num: number of blocks we are adding
+ * ext2_splice_branch - splice the allocated branch onto inode.
+ * @inode: owner
+ * @block: (logical) number of block we are adding
+ * @chain: chain of indirect blocks (with a missing link - see
+ * ext2_alloc_branch)
+ * @where: location of missing link
+ * @num: number of indirect blocks we are adding
+ * @blks: number of direct blocks we are adding
*
- * This function verifies that chain (up to the missing link) had not
- * changed, fills the missing link and does all housekeeping needed in
- * inode (->i_blocks, etc.). In case of success we end up with the full
- * chain to new block and return 0. Otherwise (== chain had been changed)
- * we free the new blocks (forgetting their buffer_heads, indeed) and
- * return -EAGAIN.
+ * This function fills the missing link and does all housekeeping needed in
+ * inode (->i_blocks, etc.). In case of success we end up with the full
+ * chain to new block and return 0.
*/
-
-static inline int ext2_splice_branch(struct inode *inode,
- long block,
- Indirect chain[4],
- Indirect *where,
- int num)
+static void ext2_splice_branch(struct inode *inode,
+ long block, Indirect *where, int num, int blks)
{
- struct ext2_inode_info *ei = EXT2_I(inode);
int i;
+ struct ext2_block_alloc_info *block_i;
+ ext2_fsblk_t current_block;
- /* Verify that place we are splicing to is still there and vacant */
-
- write_lock(&ei->i_meta_lock);
- if (!verify_chain(chain, where-1) || *where->p)
- goto changed;
+ block_i = EXT2_I(inode)->i_block_alloc_info;
+ /* XXX LOCKING probably should have i_meta_lock ?*/
/* That's it */
*where->p = where->key;
- ei->i_next_alloc_block = block;
- ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key);
- write_unlock(&ei->i_meta_lock);
+ /*
+ * Update the host buffer_head or inode to point to more just allocated
+ * direct blocks blocks
+ */
+ if (num == 0 && blks > 1) {
+ current_block = le32_to_cpu(where->key) + 1;
+ for (i = 1; i < blks; i++)
+ *(where->p + i ) = cpu_to_le32(current_block++);
+ }
+
+ /*
+ * update the most recently allocated logical & physical block
+ * in i_block_alloc_info, to assist find the proper goal block for next
+ * allocation
+ */
+ if (block_i) {
+ block_i->last_alloc_logical_block = block + blks - 1;
+ block_i->last_alloc_physical_block =
+ le32_to_cpu(where[num].key) + blks - 1;
+ }
/* We are done with atomic stuff, now do the rest of housekeeping */
- inode->i_ctime = CURRENT_TIME_SEC;
-
/* had we spliced it onto indirect block? */
if (where->bh)
mark_buffer_dirty_inode(where->bh, inode);
+ inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
- return 0;
-
-changed:
- write_unlock(&ei->i_meta_lock);
- for (i = 1; i < num; i++)
- bforget(where[i].bh);
- for (i = 0; i < num; i++)
- ext2_free_blocks(inode, le32_to_cpu(where[i].key), 1);
- return -EAGAIN;
}
/*
@@ -542,64 +566,99 @@ changed:
* That has a nice additional property: no special recovery from the failed
* allocations is needed - we simply release blocks and do not touch anything
* reachable from inode.
+ *
+ * `handle' can be NULL if create == 0.
+ *
+ * The BKL may not be held on entry here. Be sure to take it early.
+ * return > 0, # of blocks mapped or allocated.
+ * return = 0, if plain lookup failed.
+ * return < 0, error case.
*/
-
-int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
+static int ext2_get_blocks(struct inode *inode,
+ sector_t iblock, unsigned long maxblocks,
+ struct buffer_head *bh_result,
+ int create)
{
int err = -EIO;
int offsets[4];
Indirect chain[4];
Indirect *partial;
- unsigned long goal;
- int left;
- int boundary = 0;
- int depth = ext2_block_to_path(inode, iblock, offsets, &boundary);
+ ext2_fsblk_t goal;
+ int indirect_blks;
+ int blocks_to_boundary = 0;
+ int depth;
+ struct ext2_inode_info *ei = EXT2_I(inode);
+ int count = 0;
+ ext2_fsblk_t first_block = 0;
- if (depth == 0)
- goto out;
+ depth = ext2_block_to_path(inode,iblock,offsets,&blocks_to_boundary);
+ if (depth == 0)
+ return (err);
reread:
partial = ext2_get_branch(inode, depth, offsets, chain, &err);
/* Simplest case - block found, no allocation needed */
if (!partial) {
-got_it:
- map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
- if (boundary)
- set_buffer_boundary(bh_result);
- /* Clean up and exit */
- partial = chain+depth-1; /* the whole chain */
- goto cleanup;
+ first_block = le32_to_cpu(chain[depth - 1].key);
+ clear_buffer_new(bh_result); /* What's this do? */
+ count++;
+ /*map more blocks*/
+ while (count < maxblocks && count <= blocks_to_boundary) {
+ ext2_fsblk_t blk;
+
+ if (!verify_chain(chain, partial)) {
+ /*
+ * Indirect block might be removed by
+ * truncate while we were reading it.
+ * Handling of that case: forget what we've
+ * got now, go to reread.
+ */
+ count = 0;
+ goto changed;
+ }
+ blk = le32_to_cpu(*(chain[depth-1].p + count));
+ if (blk == first_block + count)
+ count++;
+ else
+ break;
+ }
+ goto got_it;
}
/* Next simple case - plain lookup or failed read of indirect block */
- if (!create || err == -EIO) {
-cleanup:
- while (partial > chain) {
- brelse(partial->bh);
- partial--;
- }
-out:
- return err;
- }
+ if (!create || err == -EIO)
+ goto cleanup;
+
+ mutex_lock(&ei->truncate_mutex);
/*
- * Indirect block might be removed by truncate while we were
- * reading it. Handling of that case (forget what we've got and
- * reread) is taken out of the main path.
- */
- if (err == -EAGAIN)
- goto changed;
+ * Okay, we need to do block allocation. Lazily initialize the block
+ * allocation info here if necessary
+ */
+ if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info))
+ ext2_init_block_alloc_info(inode);
- goal = 0;
- if (ext2_find_goal(inode, iblock, chain, partial, &goal) < 0)
- goto changed;
+ goal = ext2_find_goal(inode, iblock, chain, partial);
- left = (chain + depth) - partial;
- err = ext2_alloc_branch(inode, left, goal,
- offsets+(partial-chain), partial);
- if (err)
+ /* the number of blocks need to allocate for [d,t]indirect blocks */
+ indirect_blks = (chain + depth) - partial - 1;
+ /*
+ * Next look up the indirect map to count the totoal number of
+ * direct blocks to allocate for this branch.
+ */
+ count = ext2_blks_to_allocate(partial, indirect_blks,
+ maxblocks, blocks_to_boundary);
+ /*
+ * XXX ???? Block out ext2_truncate while we alter the tree
+ */
+ err = ext2_alloc_branch(inode, indirect_blks, &count, goal,
+ offsets + (partial - chain), partial);
+
+ if (err) {
+ mutex_unlock(&ei->truncate_mutex);
goto cleanup;
+ }
if (ext2_use_xip(inode->i_sb)) {
/*
@@ -607,16 +666,28 @@ out:
*/
err = ext2_clear_xip_target (inode,
le32_to_cpu(chain[depth-1].key));
- if (err)
+ if (err) {
+ mutex_unlock(&ei->truncate_mutex);
goto cleanup;
+ }
}
- if (ext2_splice_branch(inode, iblock, chain, partial, left) < 0)
- goto changed;
-
+ ext2_splice_branch(inode, iblock, partial, indirect_blks, count);
+ mutex_unlock(&ei->truncate_mutex);
set_buffer_new(bh_result);
- goto got_it;
-
+got_it:
+ map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
+ if (count > blocks_to_boundary)
+ set_buffer_boundary(bh_result);
+ err = count;
+ /* Clean up and exit */
+ partial = chain + depth - 1; /* the whole chain */
+cleanup:
+ while (partial > chain) {
+ brelse(partial->bh);
+ partial--;
+ }
+ return err;
changed:
while (partial > chain) {
brelse(partial->bh);
@@ -625,6 +696,19 @@ changed:
goto reread;
}
+int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
+{
+ unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
+ int ret = ext2_get_blocks(inode, iblock, max_blocks,
+ bh_result, create);
+ if (ret > 0) {
+ bh_result->b_size = (ret << inode->i_blkbits);
+ ret = 0;
+ }
+ return ret;
+
+}
+
static int ext2_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, ext2_get_block, wbc);
@@ -642,18 +726,35 @@ ext2_readpages(struct file *file, struct address_space *mapping,
return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
}
+int __ext2_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ext2_get_block);
+}
+
static int
-ext2_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+ext2_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page,from,to,ext2_get_block);
+ *pagep = NULL;
+ return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata);
}
static int
-ext2_nobh_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+ext2_nobh_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return nobh_prepare_write(page,from,to,ext2_get_block);
+ /*
+ * Dir-in-pagecache still uses ext2_write_begin. Would have to rework
+ * directory handling code to pass around offsets rather than struct
+ * pages in order to make this work easily.
+ */
+ return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ext2_get_block);
}
static int ext2_nobh_writepage(struct page *page,
@@ -689,8 +790,8 @@ const struct address_space_operations ext2_aops = {
.readpages = ext2_readpages,
.writepage = ext2_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext2_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = ext2_write_begin,
+ .write_end = generic_write_end,
.bmap = ext2_bmap,
.direct_IO = ext2_direct_IO,
.writepages = ext2_writepages,
@@ -707,8 +808,8 @@ const struct address_space_operations ext2_nobh_aops = {
.readpages = ext2_readpages,
.writepage = ext2_nobh_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext2_nobh_prepare_write,
- .commit_write = nobh_commit_write,
+ .write_begin = ext2_nobh_write_begin,
+ .write_end = nobh_write_end,
.bmap = ext2_bmap,
.direct_IO = ext2_direct_IO,
.writepages = ext2_writepages,
@@ -896,9 +997,10 @@ static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int de
ext2_free_data(inode, p, q);
}
-void ext2_truncate (struct inode * inode)
+void ext2_truncate(struct inode *inode)
{
__le32 *i_data = EXT2_I(inode)->i_data;
+ struct ext2_inode_info *ei = EXT2_I(inode);
int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
int offsets[4];
Indirect chain[4];
@@ -916,8 +1018,6 @@ void ext2_truncate (struct inode * inode)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
return;
- ext2_discard_prealloc(inode);
-
blocksize = inode->i_sb->s_blocksize;
iblock = (inode->i_size + blocksize-1)
>> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
@@ -925,7 +1025,8 @@ void ext2_truncate (struct inode * inode)
if (mapping_is_xip(inode->i_mapping))
xip_truncate_page(inode->i_mapping, inode->i_size);
else if (test_opt(inode->i_sb, NOBH))
- nobh_truncate_page(inode->i_mapping, inode->i_size);
+ nobh_truncate_page(inode->i_mapping,
+ inode->i_size, ext2_get_block);
else
block_truncate_page(inode->i_mapping,
inode->i_size, ext2_get_block);
@@ -934,6 +1035,12 @@ void ext2_truncate (struct inode * inode)
if (n == 0)
return;
+ /*
+ * From here we block out all ext2_get_block() callers who want to
+ * modify the block allocation tree.
+ */
+ mutex_lock(&ei->truncate_mutex);
+
if (n == 1) {
ext2_free_data(inode, i_data+offsets[0],
i_data + EXT2_NDIR_BLOCKS);
@@ -986,6 +1093,10 @@ do_indirects:
case EXT2_TIND_BLOCK:
;
}
+
+ ext2_discard_reservation(inode);
+
+ mutex_unlock(&ei->truncate_mutex);
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
if (inode_needs_sync(inode)) {
sync_mapping_buffers(inode->i_mapping);
@@ -1010,7 +1121,7 @@ static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino,
goto Einval;
block_group = (ino - 1) / EXT2_INODES_PER_GROUP(sb);
- gdp = ext2_get_group_desc(sb, block_group, &bh);
+ gdp = ext2_get_group_desc(sb, block_group, NULL);
if (!gdp)
goto Egdp;
/*
@@ -1086,6 +1197,8 @@ void ext2_read_inode (struct inode * inode)
ei->i_acl = EXT2_ACL_NOT_CACHED;
ei->i_default_acl = EXT2_ACL_NOT_CACHED;
#endif
+ ei->i_block_alloc_info = NULL;
+
if (IS_ERR(raw_inode))
goto bad_inode;
@@ -1127,9 +1240,6 @@ void ext2_read_inode (struct inode * inode)
ei->i_dtime = 0;
inode->i_generation = le32_to_cpu(raw_inode->i_generation);
ei->i_state = 0;
- ei->i_next_alloc_block = 0;
- ei->i_next_alloc_goal = 0;
- ei->i_prealloc_count = 0;
ei->i_block_group = (ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
ei->i_dir_start_lookup = 0;
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 3bcd25422ee..c2324d5fe4a 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -22,6 +22,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
{
struct ext2_inode_info *ei = EXT2_I(inode);
unsigned int flags;
+ unsigned short rsv_window_size;
ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);
@@ -83,6 +84,50 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
return 0;
+ case EXT2_IOC_GETRSVSZ:
+ if (test_opt(inode->i_sb, RESERVATION)
+ && S_ISREG(inode->i_mode)
+ && ei->i_block_alloc_info) {
+ rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
+ return put_user(rsv_window_size, (int __user *)arg);
+ }
+ return -ENOTTY;
+ case EXT2_IOC_SETRSVSZ: {
+
+ if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
+ return -ENOTTY;
+
+ if (IS_RDONLY(inode))
+ return -EROFS;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+ return -EACCES;
+
+ if (get_user(rsv_window_size, (int __user *)arg))
+ return -EFAULT;
+
+ if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS)
+ rsv_window_size = EXT2_MAX_RESERVE_BLOCKS;
+
+ /*
+ * need to allocate reservation structure for this inode
+ * before set the window size
+ */
+ /*
+ * XXX What lock should protect the rsv_goal_size?
+ * Accessed in ext2_get_block only. ext3 uses i_truncate.
+ */
+ mutex_lock(&ei->truncate_mutex);
+ if (!ei->i_block_alloc_info)
+ ext2_init_block_alloc_info(inode);
+
+ if (ei->i_block_alloc_info){
+ struct ext2_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
+ rsv->rsv_goal_size = rsv_window_size;
+ }
+ mutex_unlock(&ei->truncate_mutex);
+ return 0;
+ }
default:
return -ENOTTY;
}
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 639a32c3c9c..77bd5f9262f 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -30,6 +30,7 @@
#include <linux/vfs.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
+#include <linux/log2.h>
#include <asm/uaccess.h>
#include "ext2.h"
#include "xattr.h"
@@ -148,6 +149,7 @@ static struct inode *ext2_alloc_inode(struct super_block *sb)
ei->i_acl = EXT2_ACL_NOT_CACHED;
ei->i_default_acl = EXT2_ACL_NOT_CACHED;
#endif
+ ei->i_block_alloc_info = NULL;
ei->vfs_inode.i_version = 1;
return &ei->vfs_inode;
}
@@ -157,7 +159,7 @@ static void ext2_destroy_inode(struct inode *inode)
kmem_cache_free(ext2_inode_cachep, EXT2_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct ext2_inode_info *ei = (struct ext2_inode_info *) foo;
@@ -165,6 +167,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
#ifdef CONFIG_EXT2_FS_XATTR
init_rwsem(&ei->xattr_sem);
#endif
+ mutex_init(&ei->truncate_mutex);
inode_init_once(&ei->vfs_inode);
}
@@ -187,6 +190,7 @@ static void destroy_inodecache(void)
static void ext2_clear_inode(struct inode *inode)
{
+ struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info;
#ifdef CONFIG_EXT2_FS_POSIX_ACL
struct ext2_inode_info *ei = EXT2_I(inode);
@@ -199,14 +203,74 @@ static void ext2_clear_inode(struct inode *inode)
ei->i_default_acl = EXT2_ACL_NOT_CACHED;
}
#endif
+ ext2_discard_reservation(inode);
+ EXT2_I(inode)->i_block_alloc_info = NULL;
+ if (unlikely(rsv))
+ kfree(rsv);
}
static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
- struct ext2_sb_info *sbi = EXT2_SB(vfs->mnt_sb);
+ struct super_block *sb = vfs->mnt_sb;
+ struct ext2_sb_info *sbi = EXT2_SB(sb);
+ struct ext2_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts;
+
+ def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
- if (sbi->s_mount_opt & EXT2_MOUNT_GRPID)
+ if (sbi->s_sb_block != 1)
+ seq_printf(seq, ",sb=%lu", sbi->s_sb_block);
+ if (test_opt(sb, MINIX_DF))
+ seq_puts(seq, ",minixdf");
+ if (test_opt(sb, GRPID))
seq_puts(seq, ",grpid");
+ if (!test_opt(sb, GRPID) && (def_mount_opts & EXT2_DEFM_BSDGROUPS))
+ seq_puts(seq, ",nogrpid");
+ if (sbi->s_resuid != EXT2_DEF_RESUID ||
+ le16_to_cpu(es->s_def_resuid) != EXT2_DEF_RESUID) {
+ seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+ }
+ if (sbi->s_resgid != EXT2_DEF_RESGID ||
+ le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) {
+ seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+ }
+ if (test_opt(sb, ERRORS_CONT)) {
+ int def_errors = le16_to_cpu(es->s_errors);
+
+ if (def_errors == EXT2_ERRORS_PANIC ||
+ def_errors == EXT2_ERRORS_RO) {
+ seq_puts(seq, ",errors=continue");
+ }
+ }
+ if (test_opt(sb, ERRORS_RO))
+ seq_puts(seq, ",errors=remount-ro");
+ if (test_opt(sb, ERRORS_PANIC))
+ seq_puts(seq, ",errors=panic");
+ if (test_opt(sb, NO_UID32))
+ seq_puts(seq, ",nouid32");
+ if (test_opt(sb, DEBUG))
+ seq_puts(seq, ",debug");
+ if (test_opt(sb, OLDALLOC))
+ seq_puts(seq, ",oldalloc");
+
+#ifdef CONFIG_EXT2_FS_XATTR
+ if (test_opt(sb, XATTR_USER))
+ seq_puts(seq, ",user_xattr");
+ if (!test_opt(sb, XATTR_USER) &&
+ (def_mount_opts & EXT2_DEFM_XATTR_USER)) {
+ seq_puts(seq, ",nouser_xattr");
+ }
+#endif
+
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
+ if (test_opt(sb, POSIX_ACL))
+ seq_puts(seq, ",acl");
+ if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT2_DEFM_ACL))
+ seq_puts(seq, ",noacl");
+#endif
+
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");
#if defined(CONFIG_QUOTA)
if (sbi->s_mount_opt & EXT2_MOUNT_USRQUOTA)
@@ -234,7 +298,6 @@ static const struct super_operations ext2_sops = {
.destroy_inode = ext2_destroy_inode,
.read_inode = ext2_read_inode,
.write_inode = ext2_write_inode,
- .put_inode = ext2_put_inode,
.delete_inode = ext2_delete_inode,
.put_super = ext2_put_super,
.write_super = ext2_write_super,
@@ -322,7 +385,7 @@ enum {
Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
- Opt_usrquota, Opt_grpquota
+ Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation
};
static match_table_t tokens = {
@@ -354,6 +417,8 @@ static match_table_t tokens = {
{Opt_ignore, "noquota"},
{Opt_quota, "quota"},
{Opt_usrquota, "usrquota"},
+ {Opt_reservation, "reservation"},
+ {Opt_noreservation, "noreservation"},
{Opt_err, NULL}
};
@@ -486,6 +551,14 @@ static int parse_options (char * options,
break;
#endif
+ case Opt_reservation:
+ set_opt(sbi->s_mount_opt, RESERVATION);
+ printk("reservations ON\n");
+ break;
+ case Opt_noreservation:
+ clear_opt(sbi->s_mount_opt, RESERVATION);
+ printk("reservations OFF\n");
+ break;
case Opt_ignore:
break;
default:
@@ -653,11 +726,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
int db_count;
int i, j;
__le32 features;
+ int err;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
return -ENOMEM;
sb->s_fs_info = sbi;
+ sbi->s_sb_block = sb_block;
/*
* See what the current blocksize for the device is, and
@@ -725,6 +800,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
+ set_opt(sbi->s_mount_opt, RESERVATION);
+
if (!parse_options ((char *) data, sbi))
goto failed_mount;
@@ -804,7 +881,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) ||
- (sbi->s_inode_size & (sbi->s_inode_size - 1)) ||
+ !is_power_of_2(sbi->s_inode_size) ||
(sbi->s_inode_size > blocksize)) {
printk ("EXT2-fs: unsupported inode size: %d\n",
sbi->s_inode_size);
@@ -906,12 +983,35 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock);
- percpu_counter_init(&sbi->s_freeblocks_counter,
+ /* per fileystem reservation list head & lock */
+ spin_lock_init(&sbi->s_rsv_window_lock);
+ sbi->s_rsv_window_root = RB_ROOT;
+ /*
+ * Add a single, static dummy reservation to the start of the
+ * reservation window list --- it gives us a placeholder for
+ * append-at-start-of-list which makes the allocation logic
+ * _much_ simpler.
+ */
+ sbi->s_rsv_window_head.rsv_start = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ sbi->s_rsv_window_head.rsv_end = EXT2_RESERVE_WINDOW_NOT_ALLOCATED;
+ sbi->s_rsv_window_head.rsv_alloc_hit = 0;
+ sbi->s_rsv_window_head.rsv_goal_size = 0;
+ ext2_rsv_window_add(sb, &sbi->s_rsv_window_head);
+
+ err = percpu_counter_init(&sbi->s_freeblocks_counter,
ext2_count_free_blocks(sb));
- percpu_counter_init(&sbi->s_freeinodes_counter,
+ if (!err) {
+ err = percpu_counter_init(&sbi->s_freeinodes_counter,
ext2_count_free_inodes(sb));
- percpu_counter_init(&sbi->s_dirs_counter,
+ }
+ if (!err) {
+ err = percpu_counter_init(&sbi->s_dirs_counter,
ext2_count_dirs(sb));
+ }
+ if (err) {
+ printk(KERN_ERR "EXT2-fs: insufficient memory\n");
+ goto failed_mount3;
+ }
/*
* set up enough so that it can read an inode
*/
@@ -1193,7 +1293,7 @@ static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data,
tmp_bh.b_state = 0;
err = ext2_get_block(inode, blk, &tmp_bh, 0);
- if (err)
+ if (err < 0)
return err;
if (!buffer_mapped(&tmp_bh)) /* A hole? */
memset(data, 0, tocopy);
@@ -1232,7 +1332,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type,
tmp_bh.b_state = 0;
err = ext2_get_block(inode, blk, &tmp_bh, 1);
- if (err)
+ if (err < 0)
goto out;
if (offset || tocopy != EXT2_BLOCK_SIZE(sb))
bh = sb_bread(sb, tmp_bh.b_blocknr);
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 247efd0b51d..3e8683dbb13 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -664,8 +664,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
s_first_data_block) +
EXT2_I(inode)->i_block_group *
EXT2_BLOCKS_PER_GROUP(sb);
- int block = ext2_new_block(inode, goal,
- NULL, NULL, &error);
+ int block = ext2_new_block(inode, goal, &error);
if (error)
goto cleanup;
ea_idebug(inode, "creating block %d", block);
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ca8aee6efe3..7a87d15523b 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -80,6 +80,14 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
return desc + offset;
}
+static inline int
+block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+ return ext3_test_bit ((block -
+ le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
+ EXT3_BLOCKS_PER_GROUP(sb), map);
+}
+
/**
* read_block_bitmap()
* @sb: super block
@@ -93,20 +101,51 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
static struct buffer_head *
read_block_bitmap(struct super_block *sb, unsigned int block_group)
{
+ int i;
struct ext3_group_desc * desc;
struct buffer_head * bh = NULL;
+ ext3_fsblk_t bitmap_blk;
desc = ext3_get_group_desc (sb, block_group, NULL);
if (!desc)
- goto error_out;
- bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
+ return NULL;
+ bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
+ bh = sb_bread(sb, bitmap_blk);
if (!bh)
- ext3_error (sb, "read_block_bitmap",
+ ext3_error (sb, __FUNCTION__,
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %u",
block_group, le32_to_cpu(desc->bg_block_bitmap));
-error_out:
+
+ /* check whether block bitmap block number is set */
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ /* check whether the inode bitmap block number is set */
+ bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ /* check whether the inode table block number is set */
+ bitmap_blk = le32_to_cpu(desc->bg_inode_table);
+ for (i = 0; i < EXT3_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ }
+
return bh;
+
+error_out:
+ brelse(bh);
+ ext3_error(sb, __FUNCTION__,
+ "Invalid block bitmap - "
+ "block_group = %d, block = %lu",
+ block_group, bitmap_blk);
+ return NULL;
}
/*
* The reservation window structure operations
@@ -570,7 +609,7 @@ do_more:
cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
group_freed);
spin_unlock(sb_bgl_lock(sbi, block_group));
- percpu_counter_mod(&sbi->s_freeblocks_counter, count);
+ percpu_counter_add(&sbi->s_freeblocks_counter, count);
/* We dirtied the bitmap block */
BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
@@ -1633,7 +1672,7 @@ allocated:
gdp->bg_free_blocks_count =
cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num);
spin_unlock(sb_bgl_lock(sbi, group_no));
- percpu_counter_mod(&sbi->s_freeblocks_counter, -num);
+ percpu_counter_sub(&sbi->s_freeblocks_counter, num);
BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
err = ext3_journal_dirty_metadata(handle, gdp_bh);
@@ -1733,13 +1772,6 @@ ext3_fsblk_t ext3_count_free_blocks(struct super_block *sb)
#endif
}
-static inline int
-block_in_use(ext3_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
- return ext3_test_bit ((block -
- le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) %
- EXT3_BLOCKS_PER_GROUP(sb), map);
-}
static inline int test_root(int a, int b)
{
diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
index b9176eed98d..6afc39d8025 100644
--- a/fs/ext3/bitmap.c
+++ b/fs/ext3/bitmap.c
@@ -13,7 +13,7 @@
#ifdef EXT3FS_DEBUG
-static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
unsigned long ext3_count_free (struct buffer_head * map, unsigned int numchars)
{
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index c00723a99f4..c8e4ee3af1d 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -47,9 +47,7 @@ const struct file_operations ext3_dir_operations = {
.compat_ioctl = ext3_compat_ioctl,
#endif
.fsync = ext3_sync_file, /* BKL held */
-#ifdef CONFIG_EXT3_INDEX
.release = ext3_release_dir,
-#endif
};
@@ -107,7 +105,6 @@ static int ext3_readdir(struct file * filp,
sb = inode->i_sb;
-#ifdef CONFIG_EXT3_INDEX
if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb,
EXT3_FEATURE_COMPAT_DIR_INDEX) &&
((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) ||
@@ -123,7 +120,6 @@ static int ext3_readdir(struct file * filp,
*/
EXT3_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL;
}
-#endif
stored = 0;
offset = filp->f_pos & (sb->s_blocksize - 1);
@@ -143,7 +139,7 @@ static int ext3_readdir(struct file * filp,
sb->s_bdev->bd_inode->i_mapping,
&filp->f_ra, filp,
index, 1);
- filp->f_ra.prev_index = index;
+ filp->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
bh = ext3_bread(NULL, inode, blk, 0, &err);
}
@@ -210,7 +206,7 @@ revalidate:
* not the directory has been modified
* during the copy operation.
*/
- unsigned long version = filp->f_version;
+ u64 version = filp->f_version;
error = filldir(dirent, de->name,
de->name_len,
@@ -232,7 +228,6 @@ out:
return ret;
}
-#ifdef CONFIG_EXT3_INDEX
/*
* These functions convert from the major/minor hash to an f_pos
* value.
@@ -518,5 +513,3 @@ static int ext3_release_dir (struct inode * inode, struct file * filp)
return 0;
}
-
-#endif
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index dd1fd3c0fc0..a588e23841d 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -47,7 +47,7 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
struct inode *inode = dentry->d_inode;
int ret = 0;
- J_ASSERT(ext3_journal_current_handle() == 0);
+ J_ASSERT(ext3_journal_current_handle() == NULL);
/*
* data=writeback:
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index e45dbd65173..1bc8cd89c51 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -204,14 +204,13 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
int ngroups = EXT3_SB(sb)->s_groups_count;
unsigned int freei, avefreei;
struct ext3_group_desc *desc, *best_desc = NULL;
- struct buffer_head *bh;
int group, best_group = -1;
freei = percpu_counter_read_positive(&EXT3_SB(sb)->s_freeinodes_counter);
avefreei = freei / ngroups;
for (group = 0; group < ngroups; group++) {
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
@@ -269,7 +268,6 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
ext3_grpblk_t min_blocks;
int group = -1, i;
struct ext3_group_desc *desc;
- struct buffer_head *bh;
freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
avefreei = freei / ngroups;
@@ -286,7 +284,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
parent_group = (unsigned)group % ngroups;
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
@@ -319,7 +317,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
@@ -334,7 +332,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
fallback:
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
@@ -358,14 +356,13 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
int parent_group = EXT3_I(parent)->i_block_group;
int ngroups = EXT3_SB(sb)->s_groups_count;
struct ext3_group_desc *desc;
- struct buffer_head *bh;
int group, i;
/*
* Try to place the inode in its parent directory
*/
group = parent_group;
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
le16_to_cpu(desc->bg_free_blocks_count))
return group;
@@ -389,7 +386,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
group += i;
if (group >= ngroups)
group -= ngroups;
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
le16_to_cpu(desc->bg_free_blocks_count))
return group;
@@ -403,7 +400,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
for (i = 0; i < ngroups; i++) {
if (++group >= ngroups)
group = 0;
- desc = ext3_get_group_desc (sb, group, &bh);
+ desc = ext3_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count))
return group;
}
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index de4e3161e47..3dec003b773 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1028,7 +1028,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode *inode,
}
if (buffer_new(&dummy)) {
J_ASSERT(create != 0);
- J_ASSERT(handle != 0);
+ J_ASSERT(handle != NULL);
/*
* Now that we do not always journal data, we should
@@ -1147,51 +1147,68 @@ static int do_journal_get_write_access(handle_t *handle,
return ext3_journal_get_write_access(handle, bh);
}
-static int ext3_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ext3_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = mapping->host;
int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
handle_t *handle;
int retries = 0;
+ struct page *page;
+ pgoff_t index;
+ unsigned from, to;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
retry:
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
handle = ext3_journal_start(inode, needed_blocks);
if (IS_ERR(handle)) {
+ unlock_page(page);
+ page_cache_release(page);
ret = PTR_ERR(handle);
goto out;
}
- if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
- ret = nobh_prepare_write(page, from, to, ext3_get_block);
- else
- ret = block_prepare_write(page, from, to, ext3_get_block);
+ ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ext3_get_block);
if (ret)
- goto prepare_write_failed;
+ goto write_begin_failed;
if (ext3_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
from, to, NULL, do_journal_get_write_access);
}
-prepare_write_failed:
- if (ret)
+write_begin_failed:
+ if (ret) {
ext3_journal_stop(handle);
+ unlock_page(page);
+ page_cache_release(page);
+ }
if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
goto retry;
out:
return ret;
}
+
int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
{
int err = journal_dirty_data(handle, bh);
if (err)
ext3_journal_abort_handle(__FUNCTION__, __FUNCTION__,
- bh, handle,err);
+ bh, handle, err);
return err;
}
-/* For commit_write() in data=journal mode */
-static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
+/* For write_end() in data=journal mode */
+static int write_end_fn(handle_t *handle, struct buffer_head *bh)
{
if (!buffer_mapped(bh) || buffer_freed(bh))
return 0;
@@ -1200,84 +1217,130 @@ static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
}
/*
+ * Generic write_end handler for ordered and writeback ext3 journal modes.
+ * We can't use generic_write_end, because that unlocks the page and we need to
+ * unlock the page after ext3_journal_stop, but ext3_journal_stop must run
+ * after block_write_end.
+ */
+static int ext3_generic_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = file->f_mapping->host;
+
+ copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+
+ if (pos+copied > inode->i_size) {
+ i_size_write(inode, pos+copied);
+ mark_inode_dirty(inode);
+ }
+
+ return copied;
+}
+
+/*
* We need to pick up the new inode size which generic_commit_write gave us
* `file' can be NULL - eg, when called from page_symlink().
*
* ext3 never places buffers on inode->i_mapping->private_list. metadata
* buffers are managed internally.
*/
-static int ext3_ordered_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ext3_ordered_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext3_journal_current_handle();
- struct inode *inode = page->mapping->host;
+ struct inode *inode = file->f_mapping->host;
+ unsigned from, to;
int ret = 0, ret2;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
+
ret = walk_page_buffers(handle, page_buffers(page),
from, to, NULL, ext3_journal_dirty_data);
if (ret == 0) {
/*
- * generic_commit_write() will run mark_inode_dirty() if i_size
+ * generic_write_end() will run mark_inode_dirty() if i_size
* changes. So let's piggyback the i_disksize mark_inode_dirty
* into that.
*/
loff_t new_i_size;
- new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ new_i_size = pos + copied;
if (new_i_size > EXT3_I(inode)->i_disksize)
EXT3_I(inode)->i_disksize = new_i_size;
- ret = generic_commit_write(file, page, from, to);
+ copied = ext3_generic_write_end(file, mapping, pos, len, copied,
+ page, fsdata);
+ if (copied < 0)
+ ret = copied;
}
ret2 = ext3_journal_stop(handle);
if (!ret)
ret = ret2;
- return ret;
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret ? ret : copied;
}
-static int ext3_writeback_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ext3_writeback_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext3_journal_current_handle();
- struct inode *inode = page->mapping->host;
+ struct inode *inode = file->f_mapping->host;
int ret = 0, ret2;
loff_t new_i_size;
- new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ new_i_size = pos + copied;
if (new_i_size > EXT3_I(inode)->i_disksize)
EXT3_I(inode)->i_disksize = new_i_size;
- if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
- ret = nobh_commit_write(file, page, from, to);
- else
- ret = generic_commit_write(file, page, from, to);
+ copied = ext3_generic_write_end(file, mapping, pos, len, copied,
+ page, fsdata);
+ if (copied < 0)
+ ret = copied;
ret2 = ext3_journal_stop(handle);
if (!ret)
ret = ret2;
- return ret;
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret ? ret : copied;
}
-static int ext3_journalled_commit_write(struct file *file,
- struct page *page, unsigned from, unsigned to)
+static int ext3_journalled_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext3_journal_current_handle();
- struct inode *inode = page->mapping->host;
+ struct inode *inode = mapping->host;
int ret = 0, ret2;
int partial = 0;
- loff_t pos;
+ unsigned from, to;
- /*
- * Here we duplicate the generic_commit_write() functionality
- */
- pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
+
+ if (copied < len) {
+ if (!PageUptodate(page))
+ copied = 0;
+ page_zero_new_buffers(page, from+copied, to);
+ }
ret = walk_page_buffers(handle, page_buffers(page), from,
- to, &partial, commit_write_fn);
+ to, &partial, write_end_fn);
if (!partial)
SetPageUptodate(page);
- if (pos > inode->i_size)
- i_size_write(inode, pos);
+ if (pos+copied > inode->i_size)
+ i_size_write(inode, pos+copied);
EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
if (inode->i_size > EXT3_I(inode)->i_disksize) {
EXT3_I(inode)->i_disksize = inode->i_size;
@@ -1285,10 +1348,14 @@ static int ext3_journalled_commit_write(struct file *file,
if (!ret)
ret = ret2;
}
+
ret2 = ext3_journal_stop(handle);
if (!ret)
ret = ret2;
- return ret;
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret ? ret : copied;
}
/*
@@ -1546,7 +1613,7 @@ static int ext3_journalled_writepage(struct page *page,
PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
err = walk_page_buffers(handle, page_buffers(page), 0,
- PAGE_CACHE_SIZE, NULL, commit_write_fn);
+ PAGE_CACHE_SIZE, NULL, write_end_fn);
if (ret == 0)
ret = err;
EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
@@ -1706,8 +1773,8 @@ static const struct address_space_operations ext3_ordered_aops = {
.readpages = ext3_readpages,
.writepage = ext3_ordered_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext3_prepare_write,
- .commit_write = ext3_ordered_commit_write,
+ .write_begin = ext3_write_begin,
+ .write_end = ext3_ordered_write_end,
.bmap = ext3_bmap,
.invalidatepage = ext3_invalidatepage,
.releasepage = ext3_releasepage,
@@ -1720,8 +1787,8 @@ static const struct address_space_operations ext3_writeback_aops = {
.readpages = ext3_readpages,
.writepage = ext3_writeback_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext3_prepare_write,
- .commit_write = ext3_writeback_commit_write,
+ .write_begin = ext3_write_begin,
+ .write_end = ext3_writeback_write_end,
.bmap = ext3_bmap,
.invalidatepage = ext3_invalidatepage,
.releasepage = ext3_releasepage,
@@ -1734,8 +1801,8 @@ static const struct address_space_operations ext3_journalled_aops = {
.readpages = ext3_readpages,
.writepage = ext3_journalled_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext3_prepare_write,
- .commit_write = ext3_journalled_commit_write,
+ .write_begin = ext3_write_begin,
+ .write_end = ext3_journalled_write_end,
.set_page_dirty = ext3_journalled_set_page_dirty,
.bmap = ext3_bmap,
.invalidatepage = ext3_invalidatepage,
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index c1fa1908dba..ec8170adac5 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -144,7 +144,6 @@ struct dx_map_entry
u16 size;
};
-#ifdef CONFIG_EXT3_INDEX
static inline unsigned dx_get_block (struct dx_entry *entry);
static void dx_set_block (struct dx_entry *entry, unsigned value);
static inline unsigned dx_get_hash (struct dx_entry *entry);
@@ -768,8 +767,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
dx_set_block(new, block);
dx_set_count(entries, count + 1);
}
-#endif
-
static void ext3_update_dx_flag(struct inode *inode)
{
@@ -871,7 +868,6 @@ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
name = dentry->d_name.name;
if (namelen > EXT3_NAME_LEN)
return NULL;
-#ifdef CONFIG_EXT3_INDEX
if (is_dx(dir)) {
bh = ext3_dx_find_entry(dentry, res_dir, &err);
/*
@@ -883,7 +879,6 @@ static struct buffer_head * ext3_find_entry (struct dentry *dentry,
return bh;
dxtrace(printk("ext3_find_entry: dx failed, falling back\n"));
}
-#endif
nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb);
start = EXT3_I(dir)->i_dir_start_lookup;
if (start >= nblocks)
@@ -959,7 +954,6 @@ cleanup_and_exit:
return ret;
}
-#ifdef CONFIG_EXT3_INDEX
static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
struct ext3_dir_entry_2 **res_dir, int *err)
{
@@ -1027,7 +1021,6 @@ errout:
dx_release (frames);
return NULL;
}
-#endif
static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
{
@@ -1123,7 +1116,6 @@ static inline void ext3_set_de_type(struct super_block *sb,
de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
}
-#ifdef CONFIG_EXT3_INDEX
/*
* Move count entries from end of map between two memory locations.
* Returns pointer to last entry moved.
@@ -1268,7 +1260,6 @@ errout:
*error = err;
return NULL;
}
-#endif
/*
@@ -1366,7 +1357,6 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
return 0;
}
-#ifdef CONFIG_EXT3_INDEX
/*
* This converts a one block unindexed directory to a 3 block indexed
* directory, and adds the dentry to the indexed directory.
@@ -1445,7 +1435,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
-#endif
/*
* ext3_add_entry()
@@ -1466,9 +1455,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
struct ext3_dir_entry_2 *de;
struct super_block * sb;
int retval;
-#ifdef CONFIG_EXT3_INDEX
int dx_fallback=0;
-#endif
unsigned blocksize;
u32 block, blocks;
@@ -1476,7 +1463,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
blocksize = sb->s_blocksize;
if (!dentry->d_name.len)
return -EINVAL;
-#ifdef CONFIG_EXT3_INDEX
if (is_dx(dir)) {
retval = ext3_dx_add_entry(handle, dentry, inode);
if (!retval || (retval != ERR_BAD_DX_DIR))
@@ -1485,7 +1471,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
dx_fallback++;
ext3_mark_inode_dirty(handle, dir);
}
-#endif
blocks = dir->i_size >> sb->s_blocksize_bits;
for (block = 0, offset = 0; block < blocks; block++) {
bh = ext3_bread(handle, dir, block, 0, &retval);
@@ -1495,11 +1480,9 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
if (retval != -ENOSPC)
return retval;
-#ifdef CONFIG_EXT3_INDEX
if (blocks == 1 && !dx_fallback &&
EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX))
return make_indexed_dir(handle, dentry, inode, bh);
-#endif
brelse(bh);
}
bh = ext3_append(handle, dir, &block, &retval);
@@ -1511,7 +1494,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
-#ifdef CONFIG_EXT3_INDEX
/*
* Returns 0 for success, or a negative error value
*/
@@ -1646,7 +1628,6 @@ cleanup:
dx_release(frames);
return err;
}
-#endif
/*
* ext3_delete_entry deletes a directory entry by merging it with the
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 2c97e09c6c6..44de1453c30 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -154,6 +154,34 @@ static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
}
/*
+ * If we have fewer than thresh credits, extend by EXT3_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
+ */
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+ struct buffer_head *bh)
+{
+ int err;
+
+ if (handle->h_buffer_credits >= thresh)
+ return 0;
+
+ err = ext3_journal_extend(handle, EXT3_MAX_TRANS_DATA);
+ if (err < 0)
+ return err;
+ if (err) {
+ err = ext3_journal_restart(handle, EXT3_MAX_TRANS_DATA);
+ if (err)
+ return err;
+ err = ext3_journal_get_write_access(handle, bh);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+/*
* Set up the block and inode bitmaps, and the inode table for the new group.
* This doesn't need to be part of the main transaction, since we are only
* changing blocks outside the actual filesystem. We still do journaling to
@@ -175,8 +203,9 @@ static int setup_new_group_blocks(struct super_block *sb,
int i;
int err = 0, err2;
- handle = ext3_journal_start_sb(sb, reserved_gdb + gdblocks +
- 2 + sbi->s_itb_per_group);
+ /* This transaction may be extended/restarted along the way */
+ handle = ext3_journal_start_sb(sb, EXT3_MAX_TRANS_DATA);
+
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -203,6 +232,10 @@ static int setup_new_group_blocks(struct super_block *sb,
ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
+ err = extend_or_restart_transaction(handle, 1, bh);
+ if (err)
+ goto exit_bh;
+
gdb = sb_getblk(sb, block);
if (!gdb) {
err = -EIO;
@@ -212,10 +245,10 @@ static int setup_new_group_blocks(struct super_block *sb,
brelse(gdb);
goto exit_bh;
}
- lock_buffer(bh);
- memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+ lock_buffer(gdb);
+ memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
set_buffer_uptodate(gdb);
- unlock_buffer(bh);
+ unlock_buffer(gdb);
ext3_journal_dirty_metadata(handle, gdb);
ext3_set_bit(bit, bh->b_data);
brelse(gdb);
@@ -228,6 +261,10 @@ static int setup_new_group_blocks(struct super_block *sb,
ext3_debug("clear reserved block %#04lx (+%d)\n", block, bit);
+ err = extend_or_restart_transaction(handle, 1, bh);
+ if (err)
+ goto exit_bh;
+
if (IS_ERR(gdb = bclean(handle, sb, block))) {
err = PTR_ERR(bh);
goto exit_bh;
@@ -249,6 +286,11 @@ static int setup_new_group_blocks(struct super_block *sb,
struct buffer_head *it;
ext3_debug("clear inode block %#04lx (+%d)\n", block, bit);
+
+ err = extend_or_restart_transaction(handle, 1, bh);
+ if (err)
+ goto exit_bh;
+
if (IS_ERR(it = bclean(handle, sb, block))) {
err = PTR_ERR(it);
goto exit_bh;
@@ -257,6 +299,11 @@ static int setup_new_group_blocks(struct super_block *sb,
brelse(it);
ext3_set_bit(bit, bh->b_data);
}
+
+ err = extend_or_restart_transaction(handle, 2, bh);
+ if (err)
+ goto exit_bh;
+
mark_bitmap_end(input->blocks_count, EXT3_BLOCKS_PER_GROUP(sb),
bh->b_data);
ext3_journal_dirty_metadata(handle, bh);
@@ -884,9 +931,9 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
input->reserved_blocks);
/* Update the free space counts */
- percpu_counter_mod(&sbi->s_freeblocks_counter,
+ percpu_counter_add(&sbi->s_freeblocks_counter,
input->free_blocks_count);
- percpu_counter_mod(&sbi->s_freeinodes_counter,
+ percpu_counter_add(&sbi->s_freeinodes_counter,
EXT3_INODES_PER_GROUP(sb));
ext3_journal_dirty_metadata(handle, sbi->s_sbh);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 9537316a071..81868c0bc40 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -472,7 +472,7 @@ static void ext3_destroy_inode(struct inode *inode)
kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct ext3_inode_info *ei = (struct ext3_inode_info *) foo;
@@ -545,9 +545,78 @@ static inline void ext3_show_quota_options(struct seq_file *seq, struct super_bl
#endif
}
+/*
+ * Show an option if
+ * - it's set to a non-default value OR
+ * - if the per-sb default is different from the global default
+ */
static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
struct super_block *sb = vfs->mnt_sb;
+ struct ext3_sb_info *sbi = EXT3_SB(sb);
+ struct ext3_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts;
+
+ def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+
+ if (sbi->s_sb_block != 1)
+ seq_printf(seq, ",sb=%lu", sbi->s_sb_block);
+ if (test_opt(sb, MINIX_DF))
+ seq_puts(seq, ",minixdf");
+ if (test_opt(sb, GRPID))
+ seq_puts(seq, ",grpid");
+ if (!test_opt(sb, GRPID) && (def_mount_opts & EXT3_DEFM_BSDGROUPS))
+ seq_puts(seq, ",nogrpid");
+ if (sbi->s_resuid != EXT3_DEF_RESUID ||
+ le16_to_cpu(es->s_def_resuid) != EXT3_DEF_RESUID) {
+ seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+ }
+ if (sbi->s_resgid != EXT3_DEF_RESGID ||
+ le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) {
+ seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+ }
+ if (test_opt(sb, ERRORS_CONT)) {
+ int def_errors = le16_to_cpu(es->s_errors);
+
+ if (def_errors == EXT3_ERRORS_PANIC ||
+ def_errors == EXT3_ERRORS_RO) {
+ seq_puts(seq, ",errors=continue");
+ }
+ }
+ if (test_opt(sb, ERRORS_RO))
+ seq_puts(seq, ",errors=remount-ro");
+ if (test_opt(sb, ERRORS_PANIC))
+ seq_puts(seq, ",errors=panic");
+ if (test_opt(sb, NO_UID32))
+ seq_puts(seq, ",nouid32");
+ if (test_opt(sb, DEBUG))
+ seq_puts(seq, ",debug");
+ if (test_opt(sb, OLDALLOC))
+ seq_puts(seq, ",oldalloc");
+#ifdef CONFIG_EXT3_FS_XATTR
+ if (test_opt(sb, XATTR_USER))
+ seq_puts(seq, ",user_xattr");
+ if (!test_opt(sb, XATTR_USER) &&
+ (def_mount_opts & EXT3_DEFM_XATTR_USER)) {
+ seq_puts(seq, ",nouser_xattr");
+ }
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
+ if (test_opt(sb, POSIX_ACL))
+ seq_puts(seq, ",acl");
+ if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT3_DEFM_ACL))
+ seq_puts(seq, ",noacl");
+#endif
+ if (!test_opt(sb, RESERVATION))
+ seq_puts(seq, ",noreservation");
+ if (sbi->s_commit_interval) {
+ seq_printf(seq, ",commit=%u",
+ (unsigned) (sbi->s_commit_interval / HZ));
+ }
+ if (test_opt(sb, BARRIER))
+ seq_puts(seq, ",barrier=1");
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");
if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
seq_puts(seq, ",data=journal");
@@ -1416,6 +1485,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
int i;
int needs_recovery;
__le32 features;
+ int err;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
@@ -1424,6 +1494,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
sbi->s_mount_opt = 0;
sbi->s_resuid = EXT3_DEF_RESUID;
sbi->s_resgid = EXT3_DEF_RESGID;
+ sbi->s_sb_block = sb_block;
unlock_kernel();
@@ -1549,7 +1620,11 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
}
brelse (bh);
- sb_set_blocksize(sb, blocksize);
+ if (!sb_set_blocksize(sb, blocksize)) {
+ printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n",
+ blocksize);
+ goto out_fail;
+ }
logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize;
offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize;
bh = sb_bread(sb, logic_sb_block);
@@ -1675,12 +1750,20 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock);
- percpu_counter_init(&sbi->s_freeblocks_counter,
- ext3_count_free_blocks(sb));
- percpu_counter_init(&sbi->s_freeinodes_counter,
- ext3_count_free_inodes(sb));
- percpu_counter_init(&sbi->s_dirs_counter,
- ext3_count_dirs(sb));
+ err = percpu_counter_init(&sbi->s_freeblocks_counter,
+ ext3_count_free_blocks(sb));
+ if (!err) {
+ err = percpu_counter_init(&sbi->s_freeinodes_counter,
+ ext3_count_free_inodes(sb));
+ }
+ if (!err) {
+ err = percpu_counter_init(&sbi->s_dirs_counter,
+ ext3_count_dirs(sb));
+ }
+ if (err) {
+ printk(KERN_ERR "EXT3-fs: insufficient memory\n");
+ goto failed_mount3;
+ }
/* per fileystem reservation list head & lock */
spin_lock_init(&sbi->s_rsv_window_lock);
@@ -2472,13 +2555,13 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
buf->f_type = EXT3_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
- buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
+ buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
buf->f_bavail = 0;
buf->f_files = le32_to_cpu(es->s_inodes_count);
- buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
+ buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
buf->f_namelen = EXT3_NAME_LEN;
fsid = le64_to_cpup((void *)es->s_uuid) ^
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index e53b4af52f1..e906b65448e 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -20,6 +20,7 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
+#include "group.h"
/*
* balloc.c contains the blocks allocation and deallocation routines
*/
@@ -42,6 +43,94 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
}
+/* Initializes an uninitialized block bitmap if given, and returns the
+ * number of blocks free in the group. */
+unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
+ int block_group, struct ext4_group_desc *gdp)
+{
+ unsigned long start;
+ int bit, bit_max;
+ unsigned free_blocks, group_blocks;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ if (bh) {
+ J_ASSERT_BH(bh, buffer_locked(bh));
+
+ /* If checksum is bad mark all blocks used to prevent allocation
+ * essentially implementing a per-group read-only flag. */
+ if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+ ext4_error(sb, __FUNCTION__,
+ "Checksum bad for group %u\n", block_group);
+ gdp->bg_free_blocks_count = 0;
+ gdp->bg_free_inodes_count = 0;
+ gdp->bg_itable_unused = 0;
+ memset(bh->b_data, 0xff, sb->s_blocksize);
+ return 0;
+ }
+ memset(bh->b_data, 0, sb->s_blocksize);
+ }
+
+ /* Check for superblock and gdt backups in this group */
+ bit_max = ext4_bg_has_super(sb, block_group);
+
+ if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) ||
+ block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) *
+ sbi->s_desc_per_block) {
+ if (bit_max) {
+ bit_max += ext4_bg_num_gdb(sb, block_group);
+ bit_max +=
+ le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks);
+ }
+ } else { /* For META_BG_BLOCK_GROUPS */
+ int group_rel = (block_group -
+ le32_to_cpu(sbi->s_es->s_first_meta_bg)) %
+ EXT4_DESC_PER_BLOCK(sb);
+ if (group_rel == 0 || group_rel == 1 ||
+ (group_rel == EXT4_DESC_PER_BLOCK(sb) - 1))
+ bit_max += 1;
+ }
+
+ if (block_group == sbi->s_groups_count - 1) {
+ /*
+ * Even though mke2fs always initialize first and last group
+ * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need
+ * to make sure we calculate the right free blocks
+ */
+ group_blocks = ext4_blocks_count(sbi->s_es) -
+ le32_to_cpu(sbi->s_es->s_first_data_block) -
+ (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count -1));
+ } else {
+ group_blocks = EXT4_BLOCKS_PER_GROUP(sb);
+ }
+
+ free_blocks = group_blocks - bit_max;
+
+ if (bh) {
+ for (bit = 0; bit < bit_max; bit++)
+ ext4_set_bit(bit, bh->b_data);
+
+ start = block_group * EXT4_BLOCKS_PER_GROUP(sb) +
+ le32_to_cpu(sbi->s_es->s_first_data_block);
+
+ /* Set bits for block and inode bitmaps, and inode table */
+ ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data);
+ ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data);
+ for (bit = (ext4_inode_table(sb, gdp) - start),
+ bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++)
+ ext4_set_bit(bit, bh->b_data);
+
+ /*
+ * Also if the number of blocks within the group is
+ * less than the blocksize * 8 ( which is the size
+ * of bitmap ), set rest of the block bitmap to 1
+ */
+ mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data);
+ }
+
+ return free_blocks - sbi->s_itb_per_group - 2;
+}
+
+
/*
* The free blocks are managed by bitmaps. A file system contains several
* blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap
@@ -100,6 +189,15 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
return desc;
}
+static inline int
+block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
+{
+ ext4_grpblk_t offset;
+
+ ext4_get_group_no_and_offset(sb, block, NULL, &offset);
+ return ext4_test_bit (offset, map);
+}
+
/**
* read_block_bitmap()
* @sb: super block
@@ -110,24 +208,69 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
*
* Return buffer_head on success or NULL in case of failure.
*/
-static struct buffer_head *
+struct buffer_head *
read_block_bitmap(struct super_block *sb, unsigned int block_group)
{
+ int i;
struct ext4_group_desc * desc;
struct buffer_head * bh = NULL;
+ ext4_fsblk_t bitmap_blk;
- desc = ext4_get_group_desc (sb, block_group, NULL);
+ desc = ext4_get_group_desc(sb, block_group, NULL);
if (!desc)
- goto error_out;
- bh = sb_bread(sb, ext4_block_bitmap(sb, desc));
+ return NULL;
+ bitmap_blk = ext4_block_bitmap(sb, desc);
+ if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+ bh = sb_getblk(sb, bitmap_blk);
+ if (!buffer_uptodate(bh)) {
+ lock_buffer(bh);
+ if (!buffer_uptodate(bh)) {
+ ext4_init_block_bitmap(sb, bh, block_group,
+ desc);
+ set_buffer_uptodate(bh);
+ }
+ unlock_buffer(bh);
+ }
+ } else {
+ bh = sb_bread(sb, bitmap_blk);
+ }
if (!bh)
- ext4_error (sb, "read_block_bitmap",
+ ext4_error (sb, __FUNCTION__,
"Cannot read block bitmap - "
"block_group = %d, block_bitmap = %llu",
- block_group,
- ext4_block_bitmap(sb, desc));
-error_out:
+ block_group, bitmap_blk);
+
+ /* check whether block bitmap block number is set */
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+
+ /* check whether the inode bitmap block number is set */
+ bitmap_blk = ext4_inode_bitmap(sb, desc);
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ /* check whether the inode table block number is set */
+ bitmap_blk = ext4_inode_table(sb, desc);
+ for (i = 0; i < EXT4_SB(sb)->s_itb_per_group; i++, bitmap_blk++) {
+ if (!block_in_use(bitmap_blk, sb, bh->b_data)) {
+ /* bad block bitmap */
+ goto error_out;
+ }
+ }
+
return bh;
+
+error_out:
+ brelse(bh);
+ ext4_error(sb, __FUNCTION__,
+ "Invalid block bitmap - "
+ "block_group = %d, block = %llu",
+ block_group, bitmap_blk);
+ return NULL;
+
}
/*
* The reservation window structure operations
@@ -586,8 +729,9 @@ do_more:
desc->bg_free_blocks_count =
cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
group_freed);
+ desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
spin_unlock(sb_bgl_lock(sbi, block_group));
- percpu_counter_mod(&sbi->s_freeblocks_counter, count);
+ percpu_counter_add(&sbi->s_freeblocks_counter, count);
/* We dirtied the bitmap block */
BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
@@ -1644,10 +1788,13 @@ allocated:
ret_block, goal_hits, goal_attempts);
spin_lock(sb_bgl_lock(sbi, group_no));
+ if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
+ gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
gdp->bg_free_blocks_count =
cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num);
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
spin_unlock(sb_bgl_lock(sbi, group_no));
- percpu_counter_mod(&sbi->s_freeblocks_counter, -num);
+ percpu_counter_sub(&sbi->s_freeblocks_counter, num);
BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
err = ext4_journal_dirty_metadata(handle, gdp_bh);
@@ -1747,15 +1894,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
#endif
}
-static inline int
-block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map)
-{
- ext4_grpblk_t offset;
-
- ext4_get_group_no_and_offset(sb, block, NULL, &offset);
- return ext4_test_bit (offset, map);
-}
-
static inline int test_root(int a, int b)
{
int num = b;
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c
index 11e93c169bc..420554f8f79 100644
--- a/fs/ext4/bitmap.c
+++ b/fs/ext4/bitmap.c
@@ -13,7 +13,7 @@
#ifdef EXT4FS_DEBUG
-static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
+static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
unsigned long ext4_count_free (struct buffer_head * map, unsigned int numchars)
{
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 3ab01c04e00..f612bef9831 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -47,9 +47,7 @@ const struct file_operations ext4_dir_operations = {
.compat_ioctl = ext4_compat_ioctl,
#endif
.fsync = ext4_sync_file, /* BKL held */
-#ifdef CONFIG_EXT4_INDEX
.release = ext4_release_dir,
-#endif
};
@@ -107,7 +105,6 @@ static int ext4_readdir(struct file * filp,
sb = inode->i_sb;
-#ifdef CONFIG_EXT4_INDEX
if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
EXT4_FEATURE_COMPAT_DIR_INDEX) &&
((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) ||
@@ -123,7 +120,6 @@ static int ext4_readdir(struct file * filp,
*/
EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL;
}
-#endif
stored = 0;
offset = filp->f_pos & (sb->s_blocksize - 1);
@@ -142,7 +138,7 @@ static int ext4_readdir(struct file * filp,
sb->s_bdev->bd_inode->i_mapping,
&filp->f_ra, filp,
index, 1);
- filp->f_ra.prev_index = index;
+ filp->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
bh = ext4_bread(NULL, inode, blk, 0, &err);
}
@@ -210,7 +206,7 @@ revalidate:
* not the directory has been modified
* during the copy operation.
*/
- unsigned long version = filp->f_version;
+ u64 version = filp->f_version;
error = filldir(dirent, de->name,
de->name_len,
@@ -232,7 +228,6 @@ out:
return ret;
}
-#ifdef CONFIG_EXT4_INDEX
/*
* These functions convert from the major/minor hash to an f_pos
* value.
@@ -518,5 +513,3 @@ static int ext4_release_dir (struct inode * inode, struct file * filp)
return 0;
}
-
-#endif
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 78beb096f57..85287742f2a 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -33,7 +33,7 @@
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/ext4_jbd2.h>
-#include <linux/jbd.h>
+#include <linux/jbd2.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
@@ -52,7 +52,7 @@ static ext4_fsblk_t ext_pblock(struct ext4_extent *ex)
{
ext4_fsblk_t block;
- block = le32_to_cpu(ex->ee_start);
+ block = le32_to_cpu(ex->ee_start_lo);
block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1;
return block;
}
@@ -65,7 +65,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
{
ext4_fsblk_t block;
- block = le32_to_cpu(ix->ei_leaf);
+ block = le32_to_cpu(ix->ei_leaf_lo);
block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1;
return block;
}
@@ -77,7 +77,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix)
*/
static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
{
- ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+ ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
}
@@ -88,7 +88,7 @@ static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
*/
static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
{
- ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff));
+ ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
}
@@ -1409,8 +1409,7 @@ has_space:
eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1);
nearex = path[depth].p_ext;
nearex->ee_block = newext->ee_block;
- nearex->ee_start = newext->ee_start;
- nearex->ee_start_hi = newext->ee_start_hi;
+ ext4_ext_store_pblock(nearex, ext_pblock(newext));
nearex->ee_len = newext->ee_len;
merge:
@@ -2177,7 +2176,6 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode,
}
/* ex2: iblock to iblock + maxblocks-1 : initialised */
ex2->ee_block = cpu_to_le32(iblock);
- ex2->ee_start = cpu_to_le32(newblock);
ext4_ext_store_pblock(ex2, newblock);
ex2->ee_len = cpu_to_le16(allocated);
if (ex2 != ex)
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 2a167d7131f..8d50879d1c2 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -47,7 +47,7 @@ int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync)
struct inode *inode = dentry->d_inode;
int ret = 0;
- J_ASSERT(ext4_journal_current_handle() == 0);
+ J_ASSERT(ext4_journal_current_handle() == NULL);
/*
* data=writeback:
diff --git a/fs/ext4/group.h b/fs/ext4/group.h
new file mode 100644
index 00000000000..1577910bb58
--- /dev/null
+++ b/fs/ext4/group.h
@@ -0,0 +1,27 @@
+/*
+ * linux/fs/ext4/group.h
+ *
+ * Copyright (C) 2007 Cluster File Systems, Inc
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ */
+
+#ifndef _LINUX_EXT4_GROUP_H
+#define _LINUX_EXT4_GROUP_H
+
+extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group,
+ struct ext4_group_desc *gdp);
+extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group,
+ struct ext4_group_desc *gdp);
+struct buffer_head *read_block_bitmap(struct super_block *sb,
+ unsigned int block_group);
+extern unsigned ext4_init_block_bitmap(struct super_block *sb,
+ struct buffer_head *bh, int group,
+ struct ext4_group_desc *desc);
+#define ext4_free_blocks_after_init(sb, group, desc) \
+ ext4_init_block_bitmap(sb, NULL, group, desc)
+extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
+ struct buffer_head *bh, int group,
+ struct ext4_group_desc *desc);
+extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
+#endif /* _LINUX_EXT4_GROUP_H */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 427f83066a0..c61f37fd3f0 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -28,6 +28,7 @@
#include "xattr.h"
#include "acl.h"
+#include "group.h"
/*
* ialloc.c contains the inodes allocation and deallocation routines
@@ -43,6 +44,52 @@
* the free blocks count in the block.
*/
+/*
+ * To avoid calling the atomic setbit hundreds or thousands of times, we only
+ * need to use it within a single byte (to ensure we get endianness right).
+ * We can use memset for the rest of the bitmap as there are no other users.
+ */
+void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+ int i;
+
+ if (start_bit >= end_bit)
+ return;
+
+ ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
+ for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+ ext4_set_bit(i, bitmap);
+ if (i < end_bit)
+ memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+}
+
+/* Initializes an uninitialized inode bitmap */
+unsigned ext4_init_inode_bitmap(struct super_block *sb,
+ struct buffer_head *bh, int block_group,
+ struct ext4_group_desc *gdp)
+{
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ J_ASSERT_BH(bh, buffer_locked(bh));
+
+ /* If checksum is bad mark all blocks and inodes use to prevent
+ * allocation, essentially implementing a per-group read-only flag. */
+ if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
+ ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n",
+ block_group);
+ gdp->bg_free_blocks_count = 0;
+ gdp->bg_free_inodes_count = 0;
+ gdp->bg_itable_unused = 0;
+ memset(bh->b_data, 0xff, sb->s_blocksize);
+ return 0;
+ }
+
+ memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
+ mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb),
+ bh->b_data);
+
+ return EXT4_INODES_PER_GROUP(sb);
+}
/*
* Read the inode allocation bitmap for a given block_group, reading
@@ -59,8 +106,20 @@ read_inode_bitmap(struct super_block * sb, unsigned long block_group)
desc = ext4_get_group_desc(sb, block_group, NULL);
if (!desc)
goto error_out;
-
- bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+ if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+ bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc));
+ if (!buffer_uptodate(bh)) {
+ lock_buffer(bh);
+ if (!buffer_uptodate(bh)) {
+ ext4_init_inode_bitmap(sb, bh, block_group,
+ desc);
+ set_buffer_uptodate(bh);
+ }
+ unlock_buffer(bh);
+ }
+ } else {
+ bh = sb_bread(sb, ext4_inode_bitmap(sb, desc));
+ }
if (!bh)
ext4_error(sb, "read_inode_bitmap",
"Cannot read inode bitmap - "
@@ -169,6 +228,8 @@ void ext4_free_inode (handle_t *handle, struct inode * inode)
if (is_directory)
gdp->bg_used_dirs_count = cpu_to_le16(
le16_to_cpu(gdp->bg_used_dirs_count) - 1);
+ gdp->bg_checksum = ext4_group_desc_csum(sbi,
+ block_group, gdp);
spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_inc(&sbi->s_freeinodes_counter);
if (is_directory)
@@ -204,14 +265,13 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
int ngroups = EXT4_SB(sb)->s_groups_count;
unsigned int freei, avefreei;
struct ext4_group_desc *desc, *best_desc = NULL;
- struct buffer_head *bh;
int group, best_group = -1;
freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter);
avefreei = freei / ngroups;
for (group = 0; group < ngroups; group++) {
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei)
@@ -269,7 +329,6 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
ext4_grpblk_t min_blocks;
int group = -1, i;
struct ext4_group_desc *desc;
- struct buffer_head *bh;
freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
avefreei = freei / ngroups;
@@ -287,7 +346,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
parent_group = (unsigned)group % ngroups;
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir)
@@ -322,7 +381,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
@@ -337,7 +396,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
fallback:
for (i = 0; i < ngroups; i++) {
group = (parent_group + i) % ngroups;
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count)
continue;
if (le16_to_cpu(desc->bg_free_inodes_count) >= avefreei)
@@ -361,14 +420,13 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
int parent_group = EXT4_I(parent)->i_block_group;
int ngroups = EXT4_SB(sb)->s_groups_count;
struct ext4_group_desc *desc;
- struct buffer_head *bh;
int group, i;
/*
* Try to place the inode in its parent directory
*/
group = parent_group;
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
le16_to_cpu(desc->bg_free_blocks_count))
return group;
@@ -392,7 +450,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
group += i;
if (group >= ngroups)
group -= ngroups;
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) &&
le16_to_cpu(desc->bg_free_blocks_count))
return group;
@@ -406,7 +464,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
for (i = 0; i < ngroups; i++) {
if (++group >= ngroups)
group = 0;
- desc = ext4_get_group_desc (sb, group, &bh);
+ desc = ext4_get_group_desc (sb, group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count))
return group;
}
@@ -438,7 +496,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
struct ext4_sb_info *sbi;
int err = 0;
struct inode *ret;
- int i;
+ int i, free = 0;
/* Cannot create files in a deleted directory */
if (!dir || !dir->i_nlink)
@@ -520,11 +578,13 @@ repeat_in_this_group:
goto out;
got:
- ino += group * EXT4_INODES_PER_GROUP(sb) + 1;
- if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
- ext4_error (sb, "ext4_new_inode",
- "reserved inode or inode > inodes count - "
- "block_group = %d, inode=%lu", group, ino);
+ ino++;
+ if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
+ ino > EXT4_INODES_PER_GROUP(sb)) {
+ ext4_error(sb, __FUNCTION__,
+ "reserved inode or inode > inodes count - "
+ "block_group = %d, inode=%lu", group,
+ ino + group * EXT4_INODES_PER_GROUP(sb));
err = -EIO;
goto fail;
}
@@ -532,13 +592,78 @@ got:
BUFFER_TRACE(bh2, "get_write_access");
err = ext4_journal_get_write_access(handle, bh2);
if (err) goto fail;
+
+ /* We may have to initialize the block bitmap if it isn't already */
+ if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) &&
+ gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+ struct buffer_head *block_bh = read_block_bitmap(sb, group);
+
+ BUFFER_TRACE(block_bh, "get block bitmap access");
+ err = ext4_journal_get_write_access(handle, block_bh);
+ if (err) {
+ brelse(block_bh);
+ goto fail;
+ }
+
+ free = 0;
+ spin_lock(sb_bgl_lock(sbi, group));
+ /* recheck and clear flag under lock if we still need to */
+ if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
+ gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+ free = ext4_free_blocks_after_init(sb, group, gdp);
+ gdp->bg_free_blocks_count = cpu_to_le16(free);
+ }
+ spin_unlock(sb_bgl_lock(sbi, group));
+
+ /* Don't need to dirty bitmap block if we didn't change it */
+ if (free) {
+ BUFFER_TRACE(block_bh, "dirty block bitmap");
+ err = ext4_journal_dirty_metadata(handle, block_bh);
+ }
+
+ brelse(block_bh);
+ if (err)
+ goto fail;
+ }
+
spin_lock(sb_bgl_lock(sbi, group));
+ /* If we didn't allocate from within the initialized part of the inode
+ * table then we need to initialize up to this inode. */
+ if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+ gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
+
+ /* When marking the block group with
+ * ~EXT4_BG_INODE_UNINIT we don't want to depend
+ * on the value of bg_itable_unsed even though
+ * mke2fs could have initialized the same for us.
+ * Instead we calculated the value below
+ */
+
+ free = 0;
+ } else {
+ free = EXT4_INODES_PER_GROUP(sb) -
+ le16_to_cpu(gdp->bg_itable_unused);
+ }
+
+ /*
+ * Check the relative inode number against the last used
+ * relative inode number in this group. if it is greater
+ * we need to update the bg_itable_unused count
+ *
+ */
+ if (ino > free)
+ gdp->bg_itable_unused =
+ cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino);
+ }
+
gdp->bg_free_inodes_count =
cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
if (S_ISDIR(mode)) {
gdp->bg_used_dirs_count =
cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
}
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
spin_unlock(sb_bgl_lock(sbi, group));
BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata");
err = ext4_journal_dirty_metadata(handle, bh2);
@@ -560,7 +685,7 @@ got:
inode->i_gid = current->fsgid;
inode->i_mode = mode;
- inode->i_ino = ino;
+ inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
/* This is the optimal IO size (for stat), not the fs block size */
inode->i_blocks = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
@@ -576,11 +701,6 @@ got:
/* dirsync only applies to directories */
if (!S_ISDIR(mode))
ei->i_flags &= ~EXT4_DIRSYNC_FL;
-#ifdef EXT4_FRAGMENTS
- ei->i_faddr = 0;
- ei->i_frag_no = 0;
- ei->i_frag_size = 0;
-#endif
ei->i_file_acl = 0;
ei->i_dir_acl = 0;
ei->i_dtime = 0;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a4848e04a5e..5489703d957 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1027,7 +1027,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
}
if (buffer_new(&dummy)) {
J_ASSERT(create != 0);
- J_ASSERT(handle != 0);
+ J_ASSERT(handle != NULL);
/*
* Now that we do not always journal data, we should
@@ -1146,34 +1146,50 @@ static int do_journal_get_write_access(handle_t *handle,
return ext4_journal_get_write_access(handle, bh);
}
-static int ext4_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ext4_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct inode *inode = page->mapping->host;
+ struct inode *inode = mapping->host;
int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
handle_t *handle;
int retries = 0;
+ struct page *page;
+ pgoff_t index;
+ unsigned from, to;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
retry:
- handle = ext4_journal_start(inode, needed_blocks);
- if (IS_ERR(handle)) {
- ret = PTR_ERR(handle);
- goto out;
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
+ handle = ext4_journal_start(inode, needed_blocks);
+ if (IS_ERR(handle)) {
+ unlock_page(page);
+ page_cache_release(page);
+ ret = PTR_ERR(handle);
+ goto out;
}
- if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
- ret = nobh_prepare_write(page, from, to, ext4_get_block);
- else
- ret = block_prepare_write(page, from, to, ext4_get_block);
- if (ret)
- goto prepare_write_failed;
- if (ext4_should_journal_data(inode)) {
+ ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ext4_get_block);
+
+ if (!ret && ext4_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
from, to, NULL, do_journal_get_write_access);
}
-prepare_write_failed:
- if (ret)
+
+ if (ret) {
ext4_journal_stop(handle);
+ unlock_page(page);
+ page_cache_release(page);
+ }
+
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
goto retry;
out:
@@ -1185,12 +1201,12 @@ int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
int err = jbd2_journal_dirty_data(handle, bh);
if (err)
ext4_journal_abort_handle(__FUNCTION__, __FUNCTION__,
- bh, handle,err);
+ bh, handle, err);
return err;
}
-/* For commit_write() in data=journal mode */
-static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
+/* For write_end() in data=journal mode */
+static int write_end_fn(handle_t *handle, struct buffer_head *bh)
{
if (!buffer_mapped(bh) || buffer_freed(bh))
return 0;
@@ -1199,84 +1215,130 @@ static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
}
/*
+ * Generic write_end handler for ordered and writeback ext4 journal modes.
+ * We can't use generic_write_end, because that unlocks the page and we need to
+ * unlock the page after ext4_journal_stop, but ext4_journal_stop must run
+ * after block_write_end.
+ */
+static int ext4_generic_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = file->f_mapping->host;
+
+ copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+
+ if (pos+copied > inode->i_size) {
+ i_size_write(inode, pos+copied);
+ mark_inode_dirty(inode);
+ }
+
+ return copied;
+}
+
+/*
* We need to pick up the new inode size which generic_commit_write gave us
* `file' can be NULL - eg, when called from page_symlink().
*
* ext4 never places buffers on inode->i_mapping->private_list. metadata
* buffers are managed internally.
*/
-static int ext4_ordered_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ext4_ordered_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext4_journal_current_handle();
- struct inode *inode = page->mapping->host;
+ struct inode *inode = file->f_mapping->host;
+ unsigned from, to;
int ret = 0, ret2;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
+
ret = walk_page_buffers(handle, page_buffers(page),
from, to, NULL, ext4_journal_dirty_data);
if (ret == 0) {
/*
- * generic_commit_write() will run mark_inode_dirty() if i_size
+ * generic_write_end() will run mark_inode_dirty() if i_size
* changes. So let's piggyback the i_disksize mark_inode_dirty
* into that.
*/
loff_t new_i_size;
- new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ new_i_size = pos + copied;
if (new_i_size > EXT4_I(inode)->i_disksize)
EXT4_I(inode)->i_disksize = new_i_size;
- ret = generic_commit_write(file, page, from, to);
+ copied = ext4_generic_write_end(file, mapping, pos, len, copied,
+ page, fsdata);
+ if (copied < 0)
+ ret = copied;
}
ret2 = ext4_journal_stop(handle);
if (!ret)
ret = ret2;
- return ret;
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret ? ret : copied;
}
-static int ext4_writeback_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ext4_writeback_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext4_journal_current_handle();
- struct inode *inode = page->mapping->host;
+ struct inode *inode = file->f_mapping->host;
int ret = 0, ret2;
loff_t new_i_size;
- new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ new_i_size = pos + copied;
if (new_i_size > EXT4_I(inode)->i_disksize)
EXT4_I(inode)->i_disksize = new_i_size;
- if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
- ret = nobh_commit_write(file, page, from, to);
- else
- ret = generic_commit_write(file, page, from, to);
+ copied = ext4_generic_write_end(file, mapping, pos, len, copied,
+ page, fsdata);
+ if (copied < 0)
+ ret = copied;
ret2 = ext4_journal_stop(handle);
if (!ret)
ret = ret2;
- return ret;
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret ? ret : copied;
}
-static int ext4_journalled_commit_write(struct file *file,
- struct page *page, unsigned from, unsigned to)
+static int ext4_journalled_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
handle_t *handle = ext4_journal_current_handle();
- struct inode *inode = page->mapping->host;
+ struct inode *inode = mapping->host;
int ret = 0, ret2;
int partial = 0;
- loff_t pos;
+ unsigned from, to;
- /*
- * Here we duplicate the generic_commit_write() functionality
- */
- pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+ to = from + len;
+
+ if (copied < len) {
+ if (!PageUptodate(page))
+ copied = 0;
+ page_zero_new_buffers(page, from+copied, to);
+ }
ret = walk_page_buffers(handle, page_buffers(page), from,
- to, &partial, commit_write_fn);
+ to, &partial, write_end_fn);
if (!partial)
SetPageUptodate(page);
- if (pos > inode->i_size)
- i_size_write(inode, pos);
+ if (pos+copied > inode->i_size)
+ i_size_write(inode, pos+copied);
EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
if (inode->i_size > EXT4_I(inode)->i_disksize) {
EXT4_I(inode)->i_disksize = inode->i_size;
@@ -1284,10 +1346,14 @@ static int ext4_journalled_commit_write(struct file *file,
if (!ret)
ret = ret2;
}
+
ret2 = ext4_journal_stop(handle);
if (!ret)
ret = ret2;
- return ret;
+ unlock_page(page);
+ page_cache_release(page);
+
+ return ret ? ret : copied;
}
/*
@@ -1545,7 +1611,7 @@ static int ext4_journalled_writepage(struct page *page,
PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
err = walk_page_buffers(handle, page_buffers(page), 0,
- PAGE_CACHE_SIZE, NULL, commit_write_fn);
+ PAGE_CACHE_SIZE, NULL, write_end_fn);
if (ret == 0)
ret = err;
EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
@@ -1705,8 +1771,8 @@ static const struct address_space_operations ext4_ordered_aops = {
.readpages = ext4_readpages,
.writepage = ext4_ordered_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext4_prepare_write,
- .commit_write = ext4_ordered_commit_write,
+ .write_begin = ext4_write_begin,
+ .write_end = ext4_ordered_write_end,
.bmap = ext4_bmap,
.invalidatepage = ext4_invalidatepage,
.releasepage = ext4_releasepage,
@@ -1719,8 +1785,8 @@ static const struct address_space_operations ext4_writeback_aops = {
.readpages = ext4_readpages,
.writepage = ext4_writeback_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext4_prepare_write,
- .commit_write = ext4_writeback_commit_write,
+ .write_begin = ext4_write_begin,
+ .write_end = ext4_writeback_write_end,
.bmap = ext4_bmap,
.invalidatepage = ext4_invalidatepage,
.releasepage = ext4_releasepage,
@@ -1733,8 +1799,8 @@ static const struct address_space_operations ext4_journalled_aops = {
.readpages = ext4_readpages,
.writepage = ext4_journalled_writepage,
.sync_page = block_sync_page,
- .prepare_write = ext4_prepare_write,
- .commit_write = ext4_journalled_commit_write,
+ .write_begin = ext4_write_begin,
+ .write_end = ext4_journalled_write_end,
.set_page_dirty = ext4_journalled_set_page_dirty,
.bmap = ext4_bmap,
.invalidatepage = ext4_invalidatepage,
@@ -2645,11 +2711,6 @@ void ext4_read_inode(struct inode * inode)
}
inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
ei->i_flags = le32_to_cpu(raw_inode->i_flags);
-#ifdef EXT4_FRAGMENTS
- ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
- ei->i_frag_no = raw_inode->i_frag;
- ei->i_frag_size = raw_inode->i_fsize;
-#endif
ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl);
if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
cpu_to_le32(EXT4_OS_HURD))
@@ -2794,11 +2855,6 @@ static int ext4_do_update_inode(handle_t *handle,
raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
raw_inode->i_flags = cpu_to_le32(ei->i_flags);
-#ifdef EXT4_FRAGMENTS
- raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);
- raw_inode->i_frag = ei->i_frag_no;
- raw_inode->i_fsize = ei->i_frag_size;
-#endif
if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
cpu_to_le32(EXT4_OS_HURD))
raw_inode->i_file_acl_high =
@@ -3177,12 +3233,14 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
iloc, handle);
if (ret) {
EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND;
- if (mnt_count != sbi->s_es->s_mnt_count) {
+ if (mnt_count !=
+ le16_to_cpu(sbi->s_es->s_mnt_count)) {
ext4_warning(inode->i_sb, __FUNCTION__,
"Unable to expand inode %lu. Delete"
" some EAs or run e2fsck.",
inode->i_ino);
- mnt_count = sbi->s_es->s_mnt_count;
+ mnt_count =
+ le16_to_cpu(sbi->s_es->s_mnt_count);
}
}
}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5fdb862e71c..94ee6f315dc 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -144,7 +144,6 @@ struct dx_map_entry
u16 size;
};
-#ifdef CONFIG_EXT4_INDEX
static inline unsigned dx_get_block (struct dx_entry *entry);
static void dx_set_block (struct dx_entry *entry, unsigned value);
static inline unsigned dx_get_hash (struct dx_entry *entry);
@@ -766,8 +765,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
dx_set_block(new, block);
dx_set_count(entries, count + 1);
}
-#endif
-
static void ext4_update_dx_flag(struct inode *inode)
{
@@ -869,7 +866,6 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,
name = dentry->d_name.name;
if (namelen > EXT4_NAME_LEN)
return NULL;
-#ifdef CONFIG_EXT4_INDEX
if (is_dx(dir)) {
bh = ext4_dx_find_entry(dentry, res_dir, &err);
/*
@@ -881,7 +877,6 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry,
return bh;
dxtrace(printk("ext4_find_entry: dx failed, falling back\n"));
}
-#endif
nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
start = EXT4_I(dir)->i_dir_start_lookup;
if (start >= nblocks)
@@ -957,7 +952,6 @@ cleanup_and_exit:
return ret;
}
-#ifdef CONFIG_EXT4_INDEX
static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
struct ext4_dir_entry_2 **res_dir, int *err)
{
@@ -1025,7 +1019,6 @@ errout:
dx_release (frames);
return NULL;
}
-#endif
static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
{
@@ -1121,7 +1114,6 @@ static inline void ext4_set_de_type(struct super_block *sb,
de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
}
-#ifdef CONFIG_EXT4_INDEX
/*
* Move count entries from end of map between two memory locations.
* Returns pointer to last entry moved.
@@ -1266,8 +1258,6 @@ errout:
*error = err;
return NULL;
}
-#endif
-
/*
* Add a new entry into a directory (leaf) block. If de is non-NULL,
@@ -1364,7 +1354,6 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
return 0;
}
-#ifdef CONFIG_EXT4_INDEX
/*
* This converts a one block unindexed directory to a 3 block indexed
* directory, and adds the dentry to the indexed directory.
@@ -1443,7 +1432,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
-#endif
/*
* ext4_add_entry()
@@ -1464,9 +1452,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
struct ext4_dir_entry_2 *de;
struct super_block * sb;
int retval;
-#ifdef CONFIG_EXT4_INDEX
int dx_fallback=0;
-#endif
unsigned blocksize;
u32 block, blocks;
@@ -1474,7 +1460,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
blocksize = sb->s_blocksize;
if (!dentry->d_name.len)
return -EINVAL;
-#ifdef CONFIG_EXT4_INDEX
if (is_dx(dir)) {
retval = ext4_dx_add_entry(handle, dentry, inode);
if (!retval || (retval != ERR_BAD_DX_DIR))
@@ -1483,7 +1468,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
dx_fallback++;
ext4_mark_inode_dirty(handle, dir);
}
-#endif
blocks = dir->i_size >> sb->s_blocksize_bits;
for (block = 0, offset = 0; block < blocks; block++) {
bh = ext4_bread(handle, dir, block, 0, &retval);
@@ -1493,11 +1477,9 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
if (retval != -ENOSPC)
return retval;
-#ifdef CONFIG_EXT4_INDEX
if (blocks == 1 && !dx_fallback &&
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
return make_indexed_dir(handle, dentry, inode, bh);
-#endif
brelse(bh);
}
bh = ext4_append(handle, dir, &block, &retval);
@@ -1509,7 +1491,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
-#ifdef CONFIG_EXT4_INDEX
/*
* Returns 0 for success, or a negative error value
*/
@@ -1644,7 +1625,6 @@ cleanup:
dx_release(frames);
return err;
}
-#endif
/*
* ext4_delete_entry deletes a directory entry by merging it with the
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index aa11d7dbe97..bd8a52bb399 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -16,6 +16,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
+#include "group.h"
#define outside(b, first, last) ((b) < (first) || (b) >= (last))
#define inside(b, first, last) ((b) >= (first) && (b) < (last))
@@ -140,22 +141,29 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
}
/*
- * To avoid calling the atomic setbit hundreds or thousands of times, we only
- * need to use it within a single byte (to ensure we get endianness right).
- * We can use memset for the rest of the bitmap as there are no other users.
+ * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
*/
-static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+ struct buffer_head *bh)
{
- int i;
+ int err;
+
+ if (handle->h_buffer_credits >= thresh)
+ return 0;
- if (start_bit >= end_bit)
- return;
+ err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
+ if (err < 0)
+ return err;
+ if (err) {
+ if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
+ return err;
+ if ((err = ext4_journal_get_write_access(handle, bh)))
+ return err;
+ }
- ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit);
- for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
- ext4_set_bit(i, bitmap);
- if (i < end_bit)
- memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+ return 0;
}
/*
@@ -180,8 +188,9 @@ static int setup_new_group_blocks(struct super_block *sb,
int i;
int err = 0, err2;
- handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks +
- 2 + sbi->s_itb_per_group);
+ /* This transaction may be extended/restarted along the way */
+ handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
+
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -208,6 +217,9 @@ static int setup_new_group_blocks(struct super_block *sb,
ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
gdb = sb_getblk(sb, block);
if (!gdb) {
err = -EIO;
@@ -217,10 +229,10 @@ static int setup_new_group_blocks(struct super_block *sb,
brelse(gdb);
goto exit_bh;
}
- lock_buffer(bh);
- memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+ lock_buffer(gdb);
+ memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
set_buffer_uptodate(gdb);
- unlock_buffer(bh);
+ unlock_buffer(gdb);
ext4_journal_dirty_metadata(handle, gdb);
ext4_set_bit(bit, bh->b_data);
brelse(gdb);
@@ -233,6 +245,9 @@ static int setup_new_group_blocks(struct super_block *sb,
ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
if (IS_ERR(gdb = bclean(handle, sb, block))) {
err = PTR_ERR(bh);
goto exit_bh;
@@ -254,6 +269,10 @@ static int setup_new_group_blocks(struct super_block *sb,
struct buffer_head *it;
ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
+
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
if (IS_ERR(it = bclean(handle, sb, block))) {
err = PTR_ERR(it);
goto exit_bh;
@@ -262,6 +281,10 @@ static int setup_new_group_blocks(struct super_block *sb,
brelse(it);
ext4_set_bit(bit, bh->b_data);
}
+
+ if ((err = extend_or_restart_transaction(handle, 2, bh)))
+ goto exit_bh;
+
mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
bh->b_data);
ext4_journal_dirty_metadata(handle, bh);
@@ -289,7 +312,6 @@ exit_journal:
return err;
}
-
/*
* Iterate through the groups which hold BACKUP superblock/GDT copies in an
* ext4 filesystem. The counters should be initialized to 1, 5, and 7 before
@@ -842,6 +864,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count);
gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb));
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
/*
* Make the new blocks and inodes valid next. We do this before
@@ -893,9 +916,9 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
input->reserved_blocks);
/* Update the free space counts */
- percpu_counter_mod(&sbi->s_freeblocks_counter,
+ percpu_counter_add(&sbi->s_freeblocks_counter,
input->free_blocks_count);
- percpu_counter_mod(&sbi->s_freeinodes_counter,
+ percpu_counter_add(&sbi->s_freeinodes_counter,
EXT4_INODES_PER_GROUP(sb));
ext4_journal_dirty_metadata(handle, sbi->s_sbh);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3c1397fa83d..b11e9e2bcd0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -37,12 +37,14 @@
#include <linux/quotaops.h>
#include <linux/seq_file.h>
#include <linux/log2.h>
+#include <linux/crc16.h>
#include <asm/uaccess.h>
#include "xattr.h"
#include "acl.h"
#include "namei.h"
+#include "group.h"
static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
unsigned long journal_devnum);
@@ -68,31 +70,31 @@ static void ext4_write_super_lockfs(struct super_block *sb);
ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
struct ext4_group_desc *bg)
{
- return le32_to_cpu(bg->bg_block_bitmap) |
+ return le32_to_cpu(bg->bg_block_bitmap_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
- (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
+ (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0);
}
ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
struct ext4_group_desc *bg)
{
- return le32_to_cpu(bg->bg_inode_bitmap) |
+ return le32_to_cpu(bg->bg_inode_bitmap_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
- (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
+ (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0);
}
ext4_fsblk_t ext4_inode_table(struct super_block *sb,
struct ext4_group_desc *bg)
{
- return le32_to_cpu(bg->bg_inode_table) |
+ return le32_to_cpu(bg->bg_inode_table_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
- (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
+ (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
}
void ext4_block_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
- bg->bg_block_bitmap = cpu_to_le32((u32)blk);
+ bg->bg_block_bitmap_lo = cpu_to_le32((u32)blk);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32);
}
@@ -100,7 +102,7 @@ void ext4_block_bitmap_set(struct super_block *sb,
void ext4_inode_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
- bg->bg_inode_bitmap = cpu_to_le32((u32)blk);
+ bg->bg_inode_bitmap_lo = cpu_to_le32((u32)blk);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32);
}
@@ -108,7 +110,7 @@ void ext4_inode_bitmap_set(struct super_block *sb,
void ext4_inode_table_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk)
{
- bg->bg_inode_table = cpu_to_le32((u32)blk);
+ bg->bg_inode_table_lo = cpu_to_le32((u32)blk);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
}
@@ -523,7 +525,7 @@ static void ext4_destroy_inode(struct inode *inode)
kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct ext4_inode_info *ei = (struct ext4_inode_info *) foo;
@@ -596,9 +598,80 @@ static inline void ext4_show_quota_options(struct seq_file *seq, struct super_bl
#endif
}
+/*
+ * Show an option if
+ * - it's set to a non-default value OR
+ * - if the per-sb default is different from the global default
+ */
static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
struct super_block *sb = vfs->mnt_sb;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct ext4_super_block *es = sbi->s_es;
+ unsigned long def_mount_opts;
+
+ def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
+
+ if (sbi->s_sb_block != 1)
+ seq_printf(seq, ",sb=%llu", sbi->s_sb_block);
+ if (test_opt(sb, MINIX_DF))
+ seq_puts(seq, ",minixdf");
+ if (test_opt(sb, GRPID))
+ seq_puts(seq, ",grpid");
+ if (!test_opt(sb, GRPID) && (def_mount_opts & EXT4_DEFM_BSDGROUPS))
+ seq_puts(seq, ",nogrpid");
+ if (sbi->s_resuid != EXT4_DEF_RESUID ||
+ le16_to_cpu(es->s_def_resuid) != EXT4_DEF_RESUID) {
+ seq_printf(seq, ",resuid=%u", sbi->s_resuid);
+ }
+ if (sbi->s_resgid != EXT4_DEF_RESGID ||
+ le16_to_cpu(es->s_def_resgid) != EXT4_DEF_RESGID) {
+ seq_printf(seq, ",resgid=%u", sbi->s_resgid);
+ }
+ if (test_opt(sb, ERRORS_CONT)) {
+ int def_errors = le16_to_cpu(es->s_errors);
+
+ if (def_errors == EXT4_ERRORS_PANIC ||
+ def_errors == EXT4_ERRORS_RO) {
+ seq_puts(seq, ",errors=continue");
+ }
+ }
+ if (test_opt(sb, ERRORS_RO))
+ seq_puts(seq, ",errors=remount-ro");
+ if (test_opt(sb, ERRORS_PANIC))
+ seq_puts(seq, ",errors=panic");
+ if (test_opt(sb, NO_UID32))
+ seq_puts(seq, ",nouid32");
+ if (test_opt(sb, DEBUG))
+ seq_puts(seq, ",debug");
+ if (test_opt(sb, OLDALLOC))
+ seq_puts(seq, ",oldalloc");
+#ifdef CONFIG_EXT4_FS_XATTR
+ if (test_opt(sb, XATTR_USER))
+ seq_puts(seq, ",user_xattr");
+ if (!test_opt(sb, XATTR_USER) &&
+ (def_mount_opts & EXT4_DEFM_XATTR_USER)) {
+ seq_puts(seq, ",nouser_xattr");
+ }
+#endif
+#ifdef CONFIG_EXT4_FS_POSIX_ACL
+ if (test_opt(sb, POSIX_ACL))
+ seq_puts(seq, ",acl");
+ if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))
+ seq_puts(seq, ",noacl");
+#endif
+ if (!test_opt(sb, RESERVATION))
+ seq_puts(seq, ",noreservation");
+ if (sbi->s_commit_interval) {
+ seq_printf(seq, ",commit=%u",
+ (unsigned) (sbi->s_commit_interval / HZ));
+ }
+ if (test_opt(sb, BARRIER))
+ seq_puts(seq, ",barrier=1");
+ if (test_opt(sb, NOBH))
+ seq_puts(seq, ",nobh");
+ if (!test_opt(sb, EXTENTS))
+ seq_puts(seq, ",noextents");
if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
seq_puts(seq, ",data=journal");
@@ -966,7 +1039,7 @@ static int parse_options (char *options, struct super_block *sb,
if (option < 0)
return 0;
if (option == 0)
- option = JBD_DEFAULT_MAX_COMMIT_AGE;
+ option = JBD2_DEFAULT_MAX_COMMIT_AGE;
sbi->s_commit_interval = HZ * option;
break;
case Opt_data_journal:
@@ -1237,6 +1310,43 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
return res;
}
+__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group,
+ struct ext4_group_desc *gdp)
+{
+ __u16 crc = 0;
+
+ if (sbi->s_es->s_feature_ro_compat &
+ cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+ int offset = offsetof(struct ext4_group_desc, bg_checksum);
+ __le32 le_group = cpu_to_le32(block_group);
+
+ crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
+ crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
+ crc = crc16(crc, (__u8 *)gdp, offset);
+ offset += sizeof(gdp->bg_checksum); /* skip checksum */
+ /* for checksum of struct ext4_group_desc do the rest...*/
+ if ((sbi->s_es->s_feature_incompat &
+ cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) &&
+ offset < le16_to_cpu(sbi->s_es->s_desc_size))
+ crc = crc16(crc, (__u8 *)gdp + offset,
+ le16_to_cpu(sbi->s_es->s_desc_size) -
+ offset);
+ }
+
+ return cpu_to_le16(crc);
+}
+
+int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group,
+ struct ext4_group_desc *gdp)
+{
+ if ((sbi->s_es->s_feature_ro_compat &
+ cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) &&
+ (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp)))
+ return 0;
+
+ return 1;
+}
+
/* Called at mount-time, super-block is locked */
static int ext4_check_descriptors (struct super_block * sb)
{
@@ -1248,13 +1358,17 @@ static int ext4_check_descriptors (struct super_block * sb)
ext4_fsblk_t inode_table;
struct ext4_group_desc * gdp = NULL;
int desc_block = 0;
+ int flexbg_flag = 0;
int i;
+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+ flexbg_flag = 1;
+
ext4_debug ("Checking group descriptors");
for (i = 0; i < sbi->s_groups_count; i++)
{
- if (i == sbi->s_groups_count - 1)
+ if (i == sbi->s_groups_count - 1 || flexbg_flag)
last_block = ext4_blocks_count(sbi->s_es) - 1;
else
last_block = first_block +
@@ -1291,7 +1405,16 @@ static int ext4_check_descriptors (struct super_block * sb)
i, inode_table);
return 0;
}
- first_block += EXT4_BLOCKS_PER_GROUP(sb);
+ if (!ext4_group_desc_csum_verify(sbi, i, gdp)) {
+ ext4_error(sb, __FUNCTION__,
+ "Checksum for group %d failed (%u!=%u)\n", i,
+ le16_to_cpu(ext4_group_desc_csum(sbi, i,
+ gdp)),
+ le16_to_cpu(gdp->bg_checksum));
+ return 0;
+ }
+ if (!flexbg_flag)
+ first_block += EXT4_BLOCKS_PER_GROUP(sb);
gdp = (struct ext4_group_desc *)
((__u8 *)gdp + EXT4_DESC_SIZE(sb));
}
@@ -1415,8 +1538,6 @@ static void ext4_orphan_cleanup (struct super_block * sb,
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
}
-#define log2(n) ffz(~(n))
-
/*
* Maximal file size. There is a direct, and {,double-,triple-}indirect
* block limit, and also a limit of (2^32 - 1) 512-byte sectors in i_blocks.
@@ -1479,6 +1600,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
int needs_recovery;
__le32 features;
__u64 blocks_count;
+ int err;
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
if (!sbi)
@@ -1487,6 +1609,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
sbi->s_mount_opt = 0;
sbi->s_resuid = EXT4_DEF_RESUID;
sbi->s_resgid = EXT4_DEF_RESGID;
+ sbi->s_sb_block = sb_block;
unlock_kernel();
@@ -1655,19 +1778,11 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE)
sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2);
}
- sbi->s_frag_size = EXT4_MIN_FRAG_SIZE <<
- le32_to_cpu(es->s_log_frag_size);
- if (blocksize != sbi->s_frag_size) {
- printk(KERN_ERR
- "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n",
- sbi->s_frag_size, blocksize);
- goto failed_mount;
- }
sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
- sbi->s_desc_size & (sbi->s_desc_size - 1)) {
+ !is_power_of_2(sbi->s_desc_size)) {
printk(KERN_ERR
"EXT4-fs: unsupported descriptor size %lu\n",
sbi->s_desc_size);
@@ -1676,7 +1791,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
} else
sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
- sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
if (EXT4_INODE_SIZE(sb) == 0)
goto cantfind_ext4;
@@ -1688,8 +1802,8 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
sbi->s_sbh = bh;
sbi->s_mount_state = le16_to_cpu(es->s_state);
- sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb));
- sbi->s_desc_per_block_bits = log2(EXT4_DESC_PER_BLOCK(sb));
+ sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb));
+ sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb));
for (i=0; i < 4; i++)
sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
sbi->s_def_hash_version = es->s_def_hash_version;
@@ -1700,12 +1814,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
sbi->s_blocks_per_group);
goto failed_mount;
}
- if (sbi->s_frags_per_group > blocksize * 8) {
- printk (KERN_ERR
- "EXT4-fs: #fragments per group too big: %lu\n",
- sbi->s_frags_per_group);
- goto failed_mount;
- }
if (sbi->s_inodes_per_group > blocksize * 8) {
printk (KERN_ERR
"EXT4-fs: #inodes per group too big: %lu\n",
@@ -1759,12 +1867,20 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock);
- percpu_counter_init(&sbi->s_freeblocks_counter,
- ext4_count_free_blocks(sb));
- percpu_counter_init(&sbi->s_freeinodes_counter,
- ext4_count_free_inodes(sb));
- percpu_counter_init(&sbi->s_dirs_counter,
- ext4_count_dirs(sb));
+ err = percpu_counter_init(&sbi->s_freeblocks_counter,
+ ext4_count_free_blocks(sb));
+ if (!err) {
+ err = percpu_counter_init(&sbi->s_freeinodes_counter,
+ ext4_count_free_inodes(sb));
+ }
+ if (!err) {
+ err = percpu_counter_init(&sbi->s_dirs_counter,
+ ext4_count_dirs(sb));
+ }
+ if (err) {
+ printk(KERN_ERR "EXT4-fs: insufficient memory\n");
+ goto failed_mount3;
+ }
/* per fileystem reservation list head & lock */
spin_lock_init(&sbi->s_rsv_window_lock);
@@ -2551,7 +2667,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
if (test_opt(sb, MINIX_DF)) {
sbi->s_overhead_last = 0;
- } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
+ } else if (sbi->s_blocks_last != ext4_blocks_count(es)) {
unsigned long ngroups = sbi->s_groups_count, i;
ext4_fsblk_t overhead = 0;
smp_rmb();
@@ -2586,19 +2702,19 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf)
overhead += ngroups * (2 + sbi->s_itb_per_group);
sbi->s_overhead_last = overhead;
smp_wmb();
- sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
+ sbi->s_blocks_last = ext4_blocks_count(es);
}
buf->f_type = EXT4_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize;
buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
- buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
- es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
+ buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter);
+ ext4_free_blocks_count_set(es, buf->f_bfree);
buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
if (buf->f_bfree < ext4_r_blocks_count(es))
buf->f_bavail = 0;
buf->f_files = le32_to_cpu(es->s_inodes_count);
- buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
+ buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
buf->f_namelen = EXT4_NAME_LEN;
fsid = le64_to_cpup((void *)es->s_uuid) ^
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index b10d68fffb5..86387302c2a 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -750,12 +750,11 @@ ext4_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(EXT4_XATTR_MAGIC);
header(s->base)->h_blocks = cpu_to_le32(1);
header(s->base)->h_refcount = cpu_to_le32(1);
@@ -1121,7 +1120,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
int total_ino, total_blk;
void *base, *start, *end;
int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
- int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize;
+ int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
down_write(&EXT4_I(inode)->xattr_sem);
retry:
@@ -1293,7 +1292,7 @@ retry:
i.name = b_entry_name;
i.value = buffer;
- i.value_len = cpu_to_le32(size);
+ i.value_len = size;
error = ext4_xattr_block_find(inode, &i, bs);
if (error)
goto cleanup;
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index be6f89b152c..639b3b4f86d 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -36,7 +36,7 @@ static inline int fat_max_cache(struct inode *inode)
static struct kmem_cache *fat_cache_cachep;
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct fat_cache *cache = (struct fat_cache *)foo;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 4baa5f20536..c0c5e9c55b5 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -141,19 +141,24 @@ static int fat_readpages(struct file *file, struct address_space *mapping,
return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
}
-static int fat_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int fat_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return cont_prepare_write(page, from, to, fat_get_block,
- &MSDOS_I(page->mapping->host)->mmu_private);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ fat_get_block,
+ &MSDOS_I(mapping->host)->mmu_private);
}
-static int fat_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int fat_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *pagep, void *fsdata)
{
- struct inode *inode = page->mapping->host;
- int err = generic_commit_write(file, page, from, to);
- if (!err && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
+ struct inode *inode = mapping->host;
+ int err;
+ err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
+ if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
mark_inode_dirty(inode);
@@ -202,8 +207,8 @@ static const struct address_space_operations fat_aops = {
.writepage = fat_writepage,
.writepages = fat_writepages,
.sync_page = block_sync_page,
- .prepare_write = fat_prepare_write,
- .commit_write = fat_commit_write,
+ .write_begin = fat_write_begin,
+ .write_end = fat_write_end,
.direct_IO = fat_direct_IO,
.bmap = _fat_bmap
};
@@ -496,7 +501,7 @@ static void fat_destroy_inode(struct inode *inode)
kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 78b2ff04405..c9db73fc5e3 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -110,7 +110,7 @@ out:
return error;
}
-static int dupfd(struct file *file, unsigned int start)
+static int dupfd(struct file *file, unsigned int start, int cloexec)
{
struct files_struct * files = current->files;
struct fdtable *fdt;
@@ -122,7 +122,10 @@ static int dupfd(struct file *file, unsigned int start)
/* locate_fd() may have expanded fdtable, load the ptr */
fdt = files_fdtable(files);
FD_SET(fd, fdt->open_fds);
- FD_CLR(fd, fdt->close_on_exec);
+ if (cloexec)
+ FD_SET(fd, fdt->close_on_exec);
+ else
+ FD_CLR(fd, fdt->close_on_exec);
spin_unlock(&files->file_lock);
fd_install(fd, file);
} else {
@@ -195,7 +198,7 @@ asmlinkage long sys_dup(unsigned int fildes)
struct file * file = fget(fildes);
if (file)
- ret = dupfd(file, 0);
+ ret = dupfd(file, 0, 0);
return ret;
}
@@ -319,8 +322,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
switch (cmd) {
case F_DUPFD:
+ case F_DUPFD_CLOEXEC:
get_file(filp);
- err = dupfd(filp, arg);
+ err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC);
break;
case F_GETFD:
err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
diff --git a/fs/file_table.c b/fs/file_table.c
index d17fd691b83..3176fefc92e 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -98,16 +98,15 @@ struct file *get_empty_filp(void)
* percpu_counters are inaccurate. Do an expensive check before
* we go and fail.
*/
- if (percpu_counter_sum(&nr_files) >= files_stat.max_files)
+ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files)
goto over;
}
- f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
+ f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL);
if (f == NULL)
goto fail;
percpu_counter_inc(&nr_files);
- memset(f, 0, sizeof(*f));
if (security_file_alloc(f))
goto fail_sec;
@@ -138,6 +137,66 @@ fail:
EXPORT_SYMBOL(get_empty_filp);
+/**
+ * alloc_file - allocate and initialize a 'struct file'
+ * @mnt: the vfsmount on which the file will reside
+ * @dentry: the dentry representing the new file
+ * @mode: the mode with which the new file will be opened
+ * @fop: the 'struct file_operations' for the new file
+ *
+ * Use this instead of get_empty_filp() to get a new
+ * 'struct file'. Do so because of the same initialization
+ * pitfalls reasons listed for init_file(). This is a
+ * preferred interface to using init_file().
+ *
+ * If all the callers of init_file() are eliminated, its
+ * code should be moved into this function.
+ */
+struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
+ mode_t mode, const struct file_operations *fop)
+{
+ struct file *file;
+ struct path;
+
+ file = get_empty_filp();
+ if (!file)
+ return NULL;
+
+ init_file(file, mnt, dentry, mode, fop);
+ return file;
+}
+EXPORT_SYMBOL(alloc_file);
+
+/**
+ * init_file - initialize a 'struct file'
+ * @file: the already allocated 'struct file' to initialized
+ * @mnt: the vfsmount on which the file resides
+ * @dentry: the dentry representing this file
+ * @mode: the mode the file is opened with
+ * @fop: the 'struct file_operations' for this file
+ *
+ * Use this instead of setting the members directly. Doing so
+ * avoids making mistakes like forgetting the mntget() or
+ * forgetting to take a write on the mnt.
+ *
+ * Note: This is a crappy interface. It is here to make
+ * merging with the existing users of get_empty_filp()
+ * who have complex failure logic easier. All users
+ * of this should be moving to alloc_file().
+ */
+int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
+ mode_t mode, const struct file_operations *fop)
+{
+ int error = 0;
+ file->f_path.dentry = dentry;
+ file->f_path.mnt = mntget(mnt);
+ file->f_mapping = dentry->d_inode->i_mapping;
+ file->f_mode = mode;
+ file->f_op = fop;
+ return error;
+}
+EXPORT_SYMBOL(init_file);
+
void fastcall fput(struct file *file)
{
if (atomic_dec_and_test(&file->f_count))
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 8d23b0b3871..686734ff973 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -100,11 +100,11 @@ void __mark_inode_dirty(struct inode *inode, int flags)
inode->i_state |= flags;
/*
- * If the inode is locked, just update its dirty state.
+ * If the inode is being synced, just update its dirty state.
* The unlocker will place the inode on the appropriate
* superblock list, based upon its state.
*/
- if (inode->i_state & I_LOCK)
+ if (inode->i_state & I_SYNC)
goto out;
/*
@@ -119,7 +119,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
goto out;
/*
- * If the inode was already on s_dirty or s_io, don't
+ * If the inode was already on s_dirty/s_io/s_more_io, don't
* reposition it (that would break s_dirty time-ordering).
*/
if (!was_dirty) {
@@ -141,6 +141,82 @@ static int write_inode(struct inode *inode, int sync)
}
/*
+ * Redirty an inode: set its when-it-was dirtied timestamp and move it to the
+ * furthest end of its superblock's dirty-inode list.
+ *
+ * Before stamping the inode's ->dirtied_when, we check to see whether it is
+ * already the most-recently-dirtied inode on the s_dirty list. If that is
+ * the case then the inode must have been redirtied while it was being written
+ * out and we don't reset its dirtied_when.
+ */
+static void redirty_tail(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+
+ if (!list_empty(&sb->s_dirty)) {
+ struct inode *tail_inode;
+
+ tail_inode = list_entry(sb->s_dirty.next, struct inode, i_list);
+ if (!time_after_eq(inode->dirtied_when,
+ tail_inode->dirtied_when))
+ inode->dirtied_when = jiffies;
+ }
+ list_move(&inode->i_list, &sb->s_dirty);
+}
+
+/*
+ * requeue inode for re-scanning after sb->s_io list is exhausted.
+ */
+static void requeue_io(struct inode *inode)
+{
+ list_move(&inode->i_list, &inode->i_sb->s_more_io);
+}
+
+static void inode_sync_complete(struct inode *inode)
+{
+ /*
+ * Prevent speculative execution through spin_unlock(&inode_lock);
+ */
+ smp_mb();
+ wake_up_bit(&inode->i_state, __I_SYNC);
+}
+
+/*
+ * Move expired dirty inodes from @delaying_queue to @dispatch_queue.
+ */
+static void move_expired_inodes(struct list_head *delaying_queue,
+ struct list_head *dispatch_queue,
+ unsigned long *older_than_this)
+{
+ while (!list_empty(delaying_queue)) {
+ struct inode *inode = list_entry(delaying_queue->prev,
+ struct inode, i_list);
+ if (older_than_this &&
+ time_after(inode->dirtied_when, *older_than_this))
+ break;
+ list_move(&inode->i_list, dispatch_queue);
+ }
+}
+
+/*
+ * Queue all expired dirty inodes for io, eldest first.
+ */
+static void queue_io(struct super_block *sb,
+ unsigned long *older_than_this)
+{
+ list_splice_init(&sb->s_more_io, sb->s_io.prev);
+ move_expired_inodes(&sb->s_dirty, &sb->s_io, older_than_this);
+}
+
+int sb_has_dirty_inodes(struct super_block *sb)
+{
+ return !list_empty(&sb->s_dirty) ||
+ !list_empty(&sb->s_io) ||
+ !list_empty(&sb->s_more_io);
+}
+EXPORT_SYMBOL(sb_has_dirty_inodes);
+
+/*
* Write a single inode's dirty pages and inode data out to disk.
* If `wait' is set, wait on the writeout.
*
@@ -155,15 +231,14 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
{
unsigned dirty;
struct address_space *mapping = inode->i_mapping;
- struct super_block *sb = inode->i_sb;
int wait = wbc->sync_mode == WB_SYNC_ALL;
int ret;
- BUG_ON(inode->i_state & I_LOCK);
+ BUG_ON(inode->i_state & I_SYNC);
- /* Set I_LOCK, reset I_DIRTY */
+ /* Set I_SYNC, reset I_DIRTY */
dirty = inode->i_state & I_DIRTY;
- inode->i_state |= I_LOCK;
+ inode->i_state |= I_SYNC;
inode->i_state &= ~I_DIRTY;
spin_unlock(&inode_lock);
@@ -184,24 +259,32 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
}
spin_lock(&inode_lock);
- inode->i_state &= ~I_LOCK;
+ inode->i_state &= ~I_SYNC;
if (!(inode->i_state & I_FREEING)) {
if (!(inode->i_state & I_DIRTY) &&
mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
/*
* We didn't write back all the pages. nfs_writepages()
* sometimes bales out without doing anything. Redirty
- * the inode. It is still on sb->s_io.
+ * the inode; Move it from s_io onto s_more_io/s_dirty.
+ */
+ /*
+ * akpm: if the caller was the kupdate function we put
+ * this inode at the head of s_dirty so it gets first
+ * consideration. Otherwise, move it to the tail, for
+ * the reasons described there. I'm not really sure
+ * how much sense this makes. Presumably I had a good
+ * reasons for doing it this way, and I'd rather not
+ * muck with it at present.
*/
if (wbc->for_kupdate) {
/*
- * For the kupdate function we leave the inode
- * at the head of sb_dirty so it will get more
- * writeout as soon as the queue becomes
- * uncongested.
+ * For the kupdate function we move the inode
+ * to s_more_io so it will get more writeout as
+ * soon as the queue becomes uncongested.
*/
inode->i_state |= I_DIRTY_PAGES;
- list_move_tail(&inode->i_list, &sb->s_dirty);
+ requeue_io(inode);
} else {
/*
* Otherwise fully redirty the inode so that
@@ -211,15 +294,14 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
* all the other files.
*/
inode->i_state |= I_DIRTY_PAGES;
- inode->dirtied_when = jiffies;
- list_move(&inode->i_list, &sb->s_dirty);
+ redirty_tail(inode);
}
} else if (inode->i_state & I_DIRTY) {
/*
* Someone redirtied the inode while were writing back
* the pages.
*/
- list_move(&inode->i_list, &sb->s_dirty);
+ redirty_tail(inode);
} else if (atomic_read(&inode->i_count)) {
/*
* The inode is clean, inuse
@@ -232,7 +314,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
list_move(&inode->i_list, &inode_unused);
}
}
- wake_up_inode(inode);
+ inode_sync_complete(inode);
return ret;
}
@@ -251,11 +333,18 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
else
WARN_ON(inode->i_state & I_WILL_FREE);
- if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
+ if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_SYNC)) {
struct address_space *mapping = inode->i_mapping;
int ret;
- list_move(&inode->i_list, &inode->i_sb->s_dirty);
+ /*
+ * We're skipping this inode because it's locked, and we're not
+ * doing writeback-for-data-integrity. Move it to s_more_io so
+ * that writeback can proceed with the other inodes on s_io.
+ * We'll have another go at writing back this inode when we
+ * completed a full scan of s_io.
+ */
+ requeue_io(inode);
/*
* Even if we don't actually write the inode itself here,
@@ -270,16 +359,16 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
/*
* It's a data-integrity sync. We must wait.
*/
- if (inode->i_state & I_LOCK) {
- DEFINE_WAIT_BIT(wq, &inode->i_state, __I_LOCK);
+ if (inode->i_state & I_SYNC) {
+ DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
- wqh = bit_waitqueue(&inode->i_state, __I_LOCK);
+ wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
do {
spin_unlock(&inode_lock);
__wait_on_bit(wqh, &wq, inode_wait,
TASK_UNINTERRUPTIBLE);
spin_lock(&inode_lock);
- } while (inode->i_state & I_LOCK);
+ } while (inode->i_state & I_SYNC);
}
return __sync_single_inode(inode, wbc);
}
@@ -312,7 +401,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
* The inodes to be written are parked on sb->s_io. They are moved back onto
* sb->s_dirty as they are selected for writing. This way, none can be missed
* on the writer throttling path, and we get decent balancing between many
- * throttled threads: we don't want them all piling up on __wait_on_inode.
+ * throttled threads: we don't want them all piling up on inode_sync_wait.
*/
static void
sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
@@ -320,7 +409,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
const unsigned long start = jiffies; /* livelock avoidance */
if (!wbc->for_kupdate || list_empty(&sb->s_io))
- list_splice_init(&sb->s_dirty, &sb->s_io);
+ queue_io(sb, wbc->older_than_this);
while (!list_empty(&sb->s_io)) {
struct inode *inode = list_entry(sb->s_io.prev,
@@ -330,7 +419,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
long pages_skipped;
if (!bdi_cap_writeback_dirty(bdi)) {
- list_move(&inode->i_list, &sb->s_dirty);
+ redirty_tail(inode);
if (sb_is_blkdev_sb(sb)) {
/*
* Dirty memory-backed blockdev: the ramdisk
@@ -350,14 +439,14 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
wbc->encountered_congestion = 1;
if (!sb_is_blkdev_sb(sb))
break; /* Skip a congested fs */
- list_move(&inode->i_list, &sb->s_dirty);
+ requeue_io(inode);
continue; /* Skip a congested blockdev */
}
if (wbc->bdi && bdi != wbc->bdi) {
if (!sb_is_blkdev_sb(sb))
break; /* fs has the wrong queue */
- list_move(&inode->i_list, &sb->s_dirty);
+ requeue_io(inode);
continue; /* blockdev has wrong queue */
}
@@ -365,11 +454,6 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
if (time_after(inode->dirtied_when, start))
break;
- /* Was this inode dirtied too recently? */
- if (wbc->older_than_this && time_after(inode->dirtied_when,
- *wbc->older_than_this))
- break;
-
/* Is another pdflush already flushing this queue? */
if (current_is_pdflush() && !writeback_acquire(bdi))
break;
@@ -389,7 +473,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
* writeback is not making progress due to locked
* buffers. Skip this inode for now.
*/
- list_move(&inode->i_list, &sb->s_dirty);
+ redirty_tail(inode);
}
spin_unlock(&inode_lock);
iput(inode);
@@ -398,6 +482,8 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
if (wbc->nr_to_write <= 0)
break;
}
+ if (!list_empty(&sb->s_more_io))
+ wbc->more_io = 1;
return; /* Leave any unwritten inodes on s_io */
}
@@ -407,7 +493,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
* Note:
* We don't need to grab a reference to superblock here. If it has non-empty
* ->s_dirty it's hadn't been killed yet and kill_super() won't proceed
- * past sync_inodes_sb() until both the ->s_dirty and ->s_io lists are
+ * past sync_inodes_sb() until the ->s_dirty/s_io/s_more_io lists are all
* empty. Since __sync_single_inode() regains inode_lock before it finally moves
* inode from superblock lists we are OK.
*
@@ -430,7 +516,7 @@ writeback_inodes(struct writeback_control *wbc)
restart:
sb = sb_entry(super_blocks.prev);
for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
- if (!list_empty(&sb->s_dirty) || !list_empty(&sb->s_io)) {
+ if (sb_has_dirty_inodes(sb)) {
/* we're making our own get_super here */
sb->s_count++;
spin_unlock(&sb_lock);
@@ -584,7 +670,7 @@ int write_inode_now(struct inode *inode, int sync)
ret = __writeback_single_inode(inode, &wbc);
spin_unlock(&inode_lock);
if (sync)
- wait_on_inode(inode);
+ inode_sync_wait(inode);
return ret;
}
EXPORT_SYMBOL(write_inode_now);
@@ -659,7 +745,7 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int
err = err2;
}
else
- wait_on_inode(inode);
+ inode_sync_wait(inode);
return err;
}
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 3ad22beb24c..db534bcde45 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -129,7 +129,7 @@ static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
struct fuse_file *ff = file->private_data;
do {
- wait_event(fc->blocked_waitq, ff->reserved_req);
+ wait_event(fc->reserved_req_waitq, ff->reserved_req);
spin_lock(&fc->lock);
if (ff->reserved_req) {
req = ff->reserved_req;
@@ -155,7 +155,7 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
fuse_request_init(req);
BUG_ON(ff->reserved_req);
ff->reserved_req = req;
- wake_up(&fc->blocked_waitq);
+ wake_up_all(&fc->reserved_req_waitq);
spin_unlock(&fc->lock);
fput(file);
}
@@ -224,13 +224,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
fc->blocked = 0;
wake_up_all(&fc->blocked_waitq);
}
+ if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
+ clear_bdi_congested(&fc->bdi, READ);
+ clear_bdi_congested(&fc->bdi, WRITE);
+ }
fc->num_background--;
}
spin_unlock(&fc->lock);
- dput(req->dentry);
- mntput(req->vfsmount);
- if (req->file)
- fput(req->file);
wake_up(&req->waitq);
if (end)
end(fc, req);
@@ -273,28 +273,41 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
queue_interrupt(fc, req);
}
- if (req->force) {
- spin_unlock(&fc->lock);
- wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
- spin_lock(&fc->lock);
- } else {
+ if (!req->force) {
sigset_t oldset;
/* Only fatal signals may interrupt this */
block_sigs(&oldset);
wait_answer_interruptible(fc, req);
restore_sigs(&oldset);
+
+ if (req->aborted)
+ goto aborted;
+ if (req->state == FUSE_REQ_FINISHED)
+ return;
+
+ /* Request is not yet in userspace, bail out */
+ if (req->state == FUSE_REQ_PENDING) {
+ list_del(&req->list);
+ __fuse_put_request(req);
+ req->out.h.error = -EINTR;
+ return;
+ }
}
- if (req->aborted)
- goto aborted;
- if (req->state == FUSE_REQ_FINISHED)
- return;
+ /*
+ * Either request is already in userspace, or it was forced.
+ * Wait it out.
+ */
+ spin_unlock(&fc->lock);
+ wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
+ spin_lock(&fc->lock);
- req->out.h.error = -EINTR;
- req->aborted = 1;
+ if (!req->aborted)
+ return;
aborted:
+ BUG_ON(req->state != FUSE_REQ_FINISHED);
if (req->locked) {
/* This is uninterruptible sleep, because data is
being copied to/from the buffers of req. During
@@ -305,14 +318,6 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
wait_event(req->waitq, !req->locked);
spin_lock(&fc->lock);
}
- if (req->state == FUSE_REQ_PENDING) {
- list_del(&req->list);
- __fuse_put_request(req);
- } else if (req->state == FUSE_REQ_SENT) {
- spin_unlock(&fc->lock);
- wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
- spin_lock(&fc->lock);
- }
}
static unsigned len_args(unsigned numargs, struct fuse_arg *args)
@@ -378,6 +383,10 @@ static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
fc->num_background++;
if (fc->num_background == FUSE_MAX_BACKGROUND)
fc->blocked = 1;
+ if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
+ set_bdi_congested(&fc->bdi, READ);
+ set_bdi_congested(&fc->bdi, WRITE);
+ }
queue_request(fc, req);
spin_unlock(&fc->lock);
@@ -738,11 +747,12 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
fuse_copy_finish(&cs);
spin_lock(&fc->lock);
req->locked = 0;
- if (!err && req->aborted)
- err = -ENOENT;
+ if (req->aborted) {
+ request_end(fc, req);
+ return -ENODEV;
+ }
if (err) {
- if (!req->aborted)
- req->out.h.error = -EIO;
+ req->out.h.error = -EIO;
request_end(fc, req);
return err;
}
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index bd5a772d8cc..3763757f9fe 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -63,13 +63,21 @@ static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
* Set dentry and possibly attribute timeouts from the lookup/mk*
* replies
*/
-static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
+static void fuse_change_entry_timeout(struct dentry *entry,
+ struct fuse_entry_out *o)
{
fuse_dentry_settime(entry,
time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
- if (entry->d_inode)
- get_fuse_inode(entry->d_inode)->i_time =
- time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+static u64 attr_timeout(struct fuse_attr_out *o)
+{
+ return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+static u64 entry_attr_timeout(struct fuse_entry_out *o)
+{
+ return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
}
/*
@@ -108,13 +116,19 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
struct dentry *entry,
struct fuse_entry_out *outarg)
{
+ struct fuse_conn *fc = get_fuse_conn(dir);
+
+ memset(outarg, 0, sizeof(struct fuse_entry_out));
req->in.h.opcode = FUSE_LOOKUP;
req->in.h.nodeid = get_node_id(dir);
req->in.numargs = 1;
req->in.args[0].size = entry->d_name.len + 1;
req->in.args[0].value = entry->d_name.name;
req->out.numargs = 1;
- req->out.args[0].size = sizeof(struct fuse_entry_out);
+ if (fc->minor < 9)
+ req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+ else
+ req->out.args[0].size = sizeof(struct fuse_entry_out);
req->out.args[0].value = outarg;
}
@@ -140,6 +154,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
struct fuse_req *req;
struct fuse_req *forget_req;
struct dentry *parent;
+ u64 attr_version;
/* For negative dentries, always do a fresh lookup */
if (!inode)
@@ -156,6 +171,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
return 0;
}
+ spin_lock(&fc->lock);
+ attr_version = fc->attr_version;
+ spin_unlock(&fc->lock);
+
parent = dget_parent(entry);
fuse_lookup_init(req, parent->d_inode, entry, &outarg);
request_send(fc, req);
@@ -180,8 +199,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
return 0;
- fuse_change_attributes(inode, &outarg.attr);
- fuse_change_timeout(entry, &outarg);
+ fuse_change_attributes(inode, &outarg.attr,
+ entry_attr_timeout(&outarg),
+ attr_version);
+ fuse_change_entry_timeout(entry, &outarg);
}
return 1;
}
@@ -228,6 +249,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req;
struct fuse_req *forget_req;
+ u64 attr_version;
if (entry->d_name.len > FUSE_NAME_MAX)
return ERR_PTR(-ENAMETOOLONG);
@@ -242,6 +264,10 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
return ERR_PTR(PTR_ERR(forget_req));
}
+ spin_lock(&fc->lock);
+ attr_version = fc->attr_version;
+ spin_unlock(&fc->lock);
+
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
err = req->out.h.error;
@@ -253,7 +279,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
err = -EIO;
if (!err && outarg.nodeid) {
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
- &outarg.attr);
+ &outarg.attr, entry_attr_timeout(&outarg),
+ attr_version);
if (!inode) {
fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
return ERR_PTR(-ENOMEM);
@@ -276,7 +303,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
entry->d_op = &fuse_dentry_operations;
if (!err)
- fuse_change_timeout(entry, &outarg);
+ fuse_change_entry_timeout(entry, &outarg);
else
fuse_invalidate_entry_cache(entry);
return NULL;
@@ -288,12 +315,11 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff,
u64 nodeid, int flags)
{
- struct fuse_req *req;
-
- req = fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE);
- req->force = 1;
- request_send(fc, req);
- fuse_put_request(fc, req);
+ fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE);
+ ff->reserved_req->force = 1;
+ request_send(fc, ff->reserved_req);
+ fuse_put_request(fc, ff->reserved_req);
+ kfree(ff);
}
/*
@@ -336,6 +362,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
flags &= ~O_NOCTTY;
memset(&inarg, 0, sizeof(inarg));
+ memset(&outentry, 0, sizeof(outentry));
inarg.flags = flags;
inarg.mode = mode;
req->in.h.opcode = FUSE_CREATE;
@@ -346,7 +373,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
req->in.args[1].size = entry->d_name.len + 1;
req->in.args[1].value = entry->d_name.name;
req->out.numargs = 2;
- req->out.args[0].size = sizeof(outentry);
+ if (fc->minor < 9)
+ req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+ else
+ req->out.args[0].size = sizeof(outentry);
req->out.args[0].value = &outentry;
req->out.args[1].size = sizeof(outopen);
req->out.args[1].value = &outopen;
@@ -364,7 +394,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
fuse_put_request(fc, req);
inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
- &outentry.attr);
+ &outentry.attr, entry_attr_timeout(&outentry), 0);
if (!inode) {
flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
ff->fh = outopen.fh;
@@ -374,7 +404,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
}
fuse_put_request(fc, forget_req);
d_instantiate(entry, inode);
- fuse_change_timeout(entry, &outentry);
+ fuse_change_entry_timeout(entry, &outentry);
file = lookup_instantiate_filp(nd, entry, generic_file_open);
if (IS_ERR(file)) {
ff->fh = outopen.fh;
@@ -411,9 +441,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
return PTR_ERR(forget_req);
}
+ memset(&outarg, 0, sizeof(outarg));
req->in.h.nodeid = get_node_id(dir);
req->out.numargs = 1;
- req->out.args[0].size = sizeof(outarg);
+ if (fc->minor < 9)
+ req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+ else
+ req->out.args[0].size = sizeof(outarg);
req->out.args[0].value = &outarg;
request_send(fc, req);
err = req->out.h.error;
@@ -429,7 +463,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
goto out_put_forget_req;
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
- &outarg.attr);
+ &outarg.attr, entry_attr_timeout(&outarg), 0);
if (!inode) {
fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
return -ENOMEM;
@@ -452,7 +486,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
} else
d_instantiate(entry, inode);
- fuse_change_timeout(entry, &outarg);
+ fuse_change_entry_timeout(entry, &outarg);
fuse_invalidate_attr(dir);
return 0;
@@ -664,32 +698,78 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
return err;
}
-int fuse_do_getattr(struct inode *inode)
+static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
+ struct kstat *stat)
+{
+ stat->dev = inode->i_sb->s_dev;
+ stat->ino = attr->ino;
+ stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
+ stat->nlink = attr->nlink;
+ stat->uid = attr->uid;
+ stat->gid = attr->gid;
+ stat->rdev = inode->i_rdev;
+ stat->atime.tv_sec = attr->atime;
+ stat->atime.tv_nsec = attr->atimensec;
+ stat->mtime.tv_sec = attr->mtime;
+ stat->mtime.tv_nsec = attr->mtimensec;
+ stat->ctime.tv_sec = attr->ctime;
+ stat->ctime.tv_nsec = attr->ctimensec;
+ stat->size = attr->size;
+ stat->blocks = attr->blocks;
+ stat->blksize = (1 << inode->i_blkbits);
+}
+
+static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
+ struct file *file)
{
int err;
- struct fuse_attr_out arg;
+ struct fuse_getattr_in inarg;
+ struct fuse_attr_out outarg;
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req = fuse_get_req(fc);
+ struct fuse_req *req;
+ u64 attr_version;
+
+ req = fuse_get_req(fc);
if (IS_ERR(req))
return PTR_ERR(req);
+ spin_lock(&fc->lock);
+ attr_version = fc->attr_version;
+ spin_unlock(&fc->lock);
+
+ memset(&inarg, 0, sizeof(inarg));
+ memset(&outarg, 0, sizeof(outarg));
+ /* Directories have separate file-handle space */
+ if (file && S_ISREG(inode->i_mode)) {
+ struct fuse_file *ff = file->private_data;
+
+ inarg.getattr_flags |= FUSE_GETATTR_FH;
+ inarg.fh = ff->fh;
+ }
req->in.h.opcode = FUSE_GETATTR;
req->in.h.nodeid = get_node_id(inode);
+ req->in.numargs = 1;
+ req->in.args[0].size = sizeof(inarg);
+ req->in.args[0].value = &inarg;
req->out.numargs = 1;
- req->out.args[0].size = sizeof(arg);
- req->out.args[0].value = &arg;
+ if (fc->minor < 9)
+ req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+ else
+ req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].value = &outarg;
request_send(fc, req);
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err) {
- if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
+ if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
make_bad_inode(inode);
err = -EIO;
} else {
- struct fuse_inode *fi = get_fuse_inode(inode);
- fuse_change_attributes(inode, &arg.attr);
- fi->i_time = time_to_jiffies(arg.attr_valid,
- arg.attr_valid_nsec);
+ fuse_change_attributes(inode, &outarg.attr,
+ attr_timeout(&outarg),
+ attr_version);
+ if (stat)
+ fuse_fillattr(inode, &outarg.attr, stat);
}
}
return err;
@@ -708,7 +788,7 @@ int fuse_do_getattr(struct inode *inode)
* for which the owner of the mount has ptrace privilege. This
* excludes processes started by other users, suid or sgid processes.
*/
-static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
{
if (fc->flags & FUSE_ALLOW_OTHER)
return 1;
@@ -724,30 +804,6 @@ static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
return 0;
}
-/*
- * Check whether the inode attributes are still valid
- *
- * If the attribute validity timeout has expired, then fetch the fresh
- * attributes with a 'getattr' request
- *
- * I'm not sure why cached attributes are never returned for the root
- * inode, this is probably being too cautious.
- */
-static int fuse_revalidate(struct dentry *entry)
-{
- struct inode *inode = entry->d_inode;
- struct fuse_inode *fi = get_fuse_inode(inode);
- struct fuse_conn *fc = get_fuse_conn(inode);
-
- if (!fuse_allow_task(fc, current))
- return -EACCES;
- if (get_node_id(inode) != FUSE_ROOT_ID &&
- fi->i_time >= get_jiffies_64())
- return 0;
-
- return fuse_do_getattr(inode);
-}
-
static int fuse_access(struct inode *inode, int mask)
{
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -795,17 +851,35 @@ static int fuse_access(struct inode *inode, int mask)
static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct fuse_conn *fc = get_fuse_conn(inode);
+ bool refreshed = false;
+ int err = 0;
if (!fuse_allow_task(fc, current))
return -EACCES;
- else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
+
+ /*
+ * If attributes are needed, refresh them before proceeding
+ */
+ if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
+ ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ if (fi->i_time < get_jiffies_64()) {
+ err = fuse_do_getattr(inode, NULL, NULL);
+ if (err)
+ return err;
+
+ refreshed = true;
+ }
+ }
+
+ if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
int err = generic_permission(inode, mask, NULL);
/* If permission is denied, try to refresh file
attributes. This is also needed, because the root
node will at first have no permissions */
- if (err == -EACCES) {
- err = fuse_do_getattr(inode);
+ if (err == -EACCES && !refreshed) {
+ err = fuse_do_getattr(inode, NULL, NULL);
if (!err)
err = generic_permission(inode, mask, NULL);
}
@@ -814,17 +888,19 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
exist. So if permissions are revoked this won't be
noticed immediately, only after the attribute
timeout has expired */
-
- return err;
- } else {
- int mode = inode->i_mode;
- if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
- return -EACCES;
-
- if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
- return fuse_access(inode, mask);
- return 0;
+ } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) {
+ err = fuse_access(inode, mask);
+ } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
+ if (!(inode->i_mode & S_IXUGO)) {
+ if (refreshed)
+ return -EACCES;
+
+ err = fuse_do_getattr(inode, NULL, NULL);
+ if (!err && !(inode->i_mode & S_IXUGO))
+ return -EACCES;
+ }
}
+ return err;
}
static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
@@ -859,6 +935,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
struct page *page;
struct inode *inode = file->f_path.dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
+ struct fuse_file *ff = file->private_data;
struct fuse_req *req;
if (is_bad_inode(inode))
@@ -875,7 +952,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
}
req->num_pages = 1;
req->pages[0] = page;
- fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
+ fuse_read_fill(req, ff, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
request_send(fc, req);
nbytes = req->out.args[0].size;
err = req->out.h.error;
@@ -955,6 +1032,20 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
}
+static bool update_mtime(unsigned ivalid)
+{
+ /* Always update if mtime is explicitly set */
+ if (ivalid & ATTR_MTIME_SET)
+ return true;
+
+ /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
+ if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
+ return false;
+
+ /* In all other cases update */
+ return true;
+}
+
static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
{
unsigned ivalid = iattr->ia_valid;
@@ -967,33 +1058,19 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid;
if (ivalid & ATTR_SIZE)
arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
- /* You can only _set_ these together (they may change by themselves) */
- if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
- arg->valid |= FATTR_ATIME | FATTR_MTIME;
+ if (ivalid & ATTR_ATIME) {
+ arg->valid |= FATTR_ATIME;
arg->atime = iattr->ia_atime.tv_sec;
- arg->mtime = iattr->ia_mtime.tv_sec;
+ arg->atimensec = iattr->ia_atime.tv_nsec;
+ if (!(ivalid & ATTR_ATIME_SET))
+ arg->valid |= FATTR_ATIME_NOW;
}
- if (ivalid & ATTR_FILE) {
- struct fuse_file *ff = iattr->ia_file->private_data;
- arg->valid |= FATTR_FH;
- arg->fh = ff->fh;
- }
-}
-
-static void fuse_vmtruncate(struct inode *inode, loff_t offset)
-{
- struct fuse_conn *fc = get_fuse_conn(inode);
- int need_trunc;
-
- spin_lock(&fc->lock);
- need_trunc = inode->i_size > offset;
- i_size_write(inode, offset);
- spin_unlock(&fc->lock);
-
- if (need_trunc) {
- struct address_space *mapping = inode->i_mapping;
- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
- truncate_inode_pages(mapping, offset);
+ if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
+ arg->valid |= FATTR_MTIME;
+ arg->mtime = iattr->ia_mtime.tv_sec;
+ arg->mtimensec = iattr->ia_mtime.tv_nsec;
+ if (!(ivalid & ATTR_MTIME_SET))
+ arg->valid |= FATTR_MTIME_NOW;
}
}
@@ -1005,16 +1082,18 @@ static void fuse_vmtruncate(struct inode *inode, loff_t offset)
* vmtruncate() doesn't allow for this case, so do the rlimit checking
* and the actual truncation by hand.
*/
-static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+ struct file *file)
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_inode *fi = get_fuse_inode(inode);
struct fuse_req *req;
struct fuse_setattr_in inarg;
struct fuse_attr_out outarg;
int err;
- int is_truncate = 0;
+
+ if (!fuse_allow_task(fc, current))
+ return -EACCES;
if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
err = inode_change_ok(inode, attr);
@@ -1022,9 +1101,11 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
return err;
}
+ if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
+ return 0;
+
if (attr->ia_valid & ATTR_SIZE) {
unsigned long limit;
- is_truncate = 1;
if (IS_SWAPFILE(inode))
return -ETXTBSY;
limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
@@ -1039,42 +1120,73 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
return PTR_ERR(req);
memset(&inarg, 0, sizeof(inarg));
+ memset(&outarg, 0, sizeof(outarg));
iattr_to_fattr(attr, &inarg);
+ if (file) {
+ struct fuse_file *ff = file->private_data;
+ inarg.valid |= FATTR_FH;
+ inarg.fh = ff->fh;
+ }
+ if (attr->ia_valid & ATTR_SIZE) {
+ /* For mandatory locking in truncate */
+ inarg.valid |= FATTR_LOCKOWNER;
+ inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
+ }
req->in.h.opcode = FUSE_SETATTR;
req->in.h.nodeid = get_node_id(inode);
req->in.numargs = 1;
req->in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg;
req->out.numargs = 1;
- req->out.args[0].size = sizeof(outarg);
+ if (fc->minor < 9)
+ req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+ else
+ req->out.args[0].size = sizeof(outarg);
req->out.args[0].value = &outarg;
request_send(fc, req);
err = req->out.h.error;
fuse_put_request(fc, req);
- if (!err) {
- if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
- make_bad_inode(inode);
- err = -EIO;
- } else {
- if (is_truncate)
- fuse_vmtruncate(inode, outarg.attr.size);
- fuse_change_attributes(inode, &outarg.attr);
- fi->i_time = time_to_jiffies(outarg.attr_valid,
- outarg.attr_valid_nsec);
- }
- } else if (err == -EINTR)
- fuse_invalidate_attr(inode);
+ if (err) {
+ if (err == -EINTR)
+ fuse_invalidate_attr(inode);
+ return err;
+ }
- return err;
+ if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+ make_bad_inode(inode);
+ return -EIO;
+ }
+
+ fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0);
+ return 0;
+}
+
+static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+{
+ if (attr->ia_valid & ATTR_FILE)
+ return fuse_do_setattr(entry, attr, attr->ia_file);
+ else
+ return fuse_do_setattr(entry, attr, NULL);
}
static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
struct kstat *stat)
{
struct inode *inode = entry->d_inode;
- int err = fuse_revalidate(entry);
- if (!err)
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ int err;
+
+ if (!fuse_allow_task(fc, current))
+ return -EACCES;
+
+ if (fi->i_time < get_jiffies_64())
+ err = fuse_do_getattr(inode, stat, NULL);
+ else {
+ err = 0;
generic_fillattr(inode, stat);
+ stat->mode = fi->orig_i_mode;
+ }
return err;
}
@@ -1176,6 +1288,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
struct fuse_getxattr_out outarg;
ssize_t ret;
+ if (!fuse_allow_task(fc, current))
+ return -EACCES;
+
if (fc->no_listxattr)
return -EOPNOTSUPP;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f79de7c8cdf..0fcdba9d47c 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -28,7 +28,9 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
return PTR_ERR(req);
memset(&inarg, 0, sizeof(inarg));
- inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+ inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
+ if (!fc->atomic_o_trunc)
+ inarg.flags &= ~O_TRUNC;
req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
req->in.h.nodeid = get_node_id(inode);
req->in.numargs = 1;
@@ -54,6 +56,8 @@ struct fuse_file *fuse_file_alloc(void)
kfree(ff);
ff = NULL;
}
+ INIT_LIST_HEAD(&ff->write_entry);
+ atomic_set(&ff->count, 0);
}
return ff;
}
@@ -64,15 +68,39 @@ void fuse_file_free(struct fuse_file *ff)
kfree(ff);
}
+static struct fuse_file *fuse_file_get(struct fuse_file *ff)
+{
+ atomic_inc(&ff->count);
+ return ff;
+}
+
+static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req)
+{
+ dput(req->dentry);
+ mntput(req->vfsmount);
+ fuse_put_request(fc, req);
+}
+
+static void fuse_file_put(struct fuse_file *ff)
+{
+ if (atomic_dec_and_test(&ff->count)) {
+ struct fuse_req *req = ff->reserved_req;
+ struct fuse_conn *fc = get_fuse_conn(req->dentry->d_inode);
+ req->end = fuse_release_end;
+ request_send_background(fc, req);
+ kfree(ff);
+ }
+}
+
void fuse_finish_open(struct inode *inode, struct file *file,
struct fuse_file *ff, struct fuse_open_out *outarg)
{
if (outarg->open_flags & FOPEN_DIRECT_IO)
file->f_op = &fuse_direct_io_file_operations;
if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
- invalidate_mapping_pages(inode->i_mapping, 0, -1);
+ invalidate_inode_pages2(inode->i_mapping);
ff->fh = outarg->fh;
- file->private_data = ff;
+ file->private_data = fuse_file_get(ff);
}
int fuse_open_common(struct inode *inode, struct file *file, int isdir)
@@ -89,14 +117,6 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
if (err)
return err;
- /* If opening the root node, no lookup has been performed on
- it, so the attributes must be refreshed */
- if (get_node_id(inode) == FUSE_ROOT_ID) {
- err = fuse_do_getattr(inode);
- if (err)
- return err;
- }
-
ff = fuse_file_alloc();
if (!ff)
return -ENOMEM;
@@ -113,8 +133,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
return err;
}
-struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags,
- int opcode)
+void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode)
{
struct fuse_req *req = ff->reserved_req;
struct fuse_release_in *inarg = &req->misc.release_in;
@@ -126,9 +145,6 @@ struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags,
req->in.numargs = 1;
req->in.args[0].size = sizeof(struct fuse_release_in);
req->in.args[0].value = inarg;
- kfree(ff);
-
- return req;
}
int fuse_release_common(struct inode *inode, struct file *file, int isdir)
@@ -136,15 +152,23 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir)
struct fuse_file *ff = file->private_data;
if (ff) {
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req;
- req = fuse_release_fill(ff, get_node_id(inode), file->f_flags,
- isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
+ fuse_release_fill(ff, get_node_id(inode), file->f_flags,
+ isdir ? FUSE_RELEASEDIR : FUSE_RELEASE);
/* Hold vfsmount and dentry until release is finished */
- req->vfsmount = mntget(file->f_path.mnt);
- req->dentry = dget(file->f_path.dentry);
- request_send_background(fc, req);
+ ff->reserved_req->vfsmount = mntget(file->f_path.mnt);
+ ff->reserved_req->dentry = dget(file->f_path.dentry);
+
+ spin_lock(&fc->lock);
+ list_del(&ff->write_entry);
+ spin_unlock(&fc->lock);
+ /*
+ * Normally this will send the RELEASE request,
+ * however if some asynchronous READ or WRITE requests
+ * are outstanding, the sending will be delayed
+ */
+ fuse_file_put(ff);
}
/* Return value is ignored by VFS */
@@ -165,7 +189,7 @@ static int fuse_release(struct inode *inode, struct file *file)
* Scramble the ID space with XTEA, so that the value of the files_struct
* pointer is not exposed to userspace.
*/
-static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
+u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
{
u32 *k = fc->scramble_key;
u64 v = (unsigned long) id;
@@ -264,10 +288,9 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
return fuse_fsync_common(file, de, datasync, 0);
}
-void fuse_read_fill(struct fuse_req *req, struct file *file,
+void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff,
struct inode *inode, loff_t pos, size_t count, int opcode)
{
- struct fuse_file *ff = file->private_data;
struct fuse_read_in *inarg = &req->misc.read_in;
inarg->fh = ff->fh;
@@ -285,10 +308,19 @@ void fuse_read_fill(struct fuse_req *req, struct file *file,
}
static size_t fuse_send_read(struct fuse_req *req, struct file *file,
- struct inode *inode, loff_t pos, size_t count)
+ struct inode *inode, loff_t pos, size_t count,
+ fl_owner_t owner)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
+ struct fuse_file *ff = file->private_data;
+
+ fuse_read_fill(req, ff, inode, pos, count, FUSE_READ);
+ if (owner != NULL) {
+ struct fuse_read_in *inarg = &req->misc.read_in;
+
+ inarg->read_flags |= FUSE_READ_LOCKOWNER;
+ inarg->lock_owner = fuse_lock_owner_id(fc, owner);
+ }
request_send(fc, req);
return req->out.args[0].size;
}
@@ -312,7 +344,8 @@ static int fuse_readpage(struct file *file, struct page *page)
req->out.page_zeroing = 1;
req->num_pages = 1;
req->pages[0] = page;
- fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
+ fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE,
+ NULL);
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err)
@@ -337,20 +370,21 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req)
SetPageError(page);
unlock_page(page);
}
+ if (req->ff)
+ fuse_file_put(req->ff);
fuse_put_request(fc, req);
}
-static void fuse_send_readpages(struct fuse_req *req, struct file *file,
+static void fuse_send_readpages(struct fuse_req *req, struct fuse_file *ff,
struct inode *inode)
{
struct fuse_conn *fc = get_fuse_conn(inode);
loff_t pos = page_offset(req->pages[0]);
size_t count = req->num_pages << PAGE_CACHE_SHIFT;
req->out.page_zeroing = 1;
- fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
+ fuse_read_fill(req, ff, inode, pos, count, FUSE_READ);
if (fc->async_read) {
- get_file(file);
- req->file = file;
+ req->ff = fuse_file_get(ff);
req->end = fuse_readpages_end;
request_send_background(fc, req);
} else {
@@ -359,15 +393,15 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file,
}
}
-struct fuse_readpages_data {
+struct fuse_fill_data {
struct fuse_req *req;
- struct file *file;
+ struct fuse_file *ff;
struct inode *inode;
};
static int fuse_readpages_fill(void *_data, struct page *page)
{
- struct fuse_readpages_data *data = _data;
+ struct fuse_fill_data *data = _data;
struct fuse_req *req = data->req;
struct inode *inode = data->inode;
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -376,7 +410,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
(req->num_pages == FUSE_MAX_PAGES_PER_REQ ||
(req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read ||
req->pages[req->num_pages - 1]->index + 1 != page->index)) {
- fuse_send_readpages(req, data->file, inode);
+ fuse_send_readpages(req, data->ff, inode);
data->req = req = fuse_get_req(fc);
if (IS_ERR(req)) {
unlock_page(page);
@@ -393,14 +427,14 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
{
struct inode *inode = mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_readpages_data data;
+ struct fuse_fill_data data;
int err;
err = -EIO;
if (is_bad_inode(inode))
goto out;
- data.file = file;
+ data.ff = file->private_data;
data.inode = inode;
data.req = fuse_get_req(fc);
err = PTR_ERR(data.req);
@@ -410,7 +444,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data);
if (!err) {
if (data.req->num_pages)
- fuse_send_readpages(data.req, file, inode);
+ fuse_send_readpages(data.req, data.ff, inode);
else
fuse_put_request(fc, data.req);
}
@@ -418,48 +452,69 @@ out:
return err;
}
-static size_t fuse_send_write(struct fuse_req *req, struct file *file,
- struct inode *inode, loff_t pos, size_t count)
+static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
+ struct inode *inode, loff_t pos, size_t count,
+ int writepage)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_file *ff = file->private_data;
- struct fuse_write_in inarg;
- struct fuse_write_out outarg;
+ struct fuse_write_in *inarg = &req->misc.write.in;
+ struct fuse_write_out *outarg = &req->misc.write.out;
- memset(&inarg, 0, sizeof(struct fuse_write_in));
- inarg.fh = ff->fh;
- inarg.offset = pos;
- inarg.size = count;
+ memset(inarg, 0, sizeof(struct fuse_write_in));
+ inarg->fh = ff->fh;
+ inarg->offset = pos;
+ inarg->size = count;
+ inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0;
req->in.h.opcode = FUSE_WRITE;
req->in.h.nodeid = get_node_id(inode);
req->in.argpages = 1;
req->in.numargs = 2;
- req->in.args[0].size = sizeof(struct fuse_write_in);
- req->in.args[0].value = &inarg;
+ if (fc->minor < 9)
+ req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
+ else
+ req->in.args[0].size = sizeof(struct fuse_write_in);
+ req->in.args[0].value = inarg;
req->in.args[1].size = count;
req->out.numargs = 1;
req->out.args[0].size = sizeof(struct fuse_write_out);
- req->out.args[0].value = &outarg;
+ req->out.args[0].value = outarg;
+}
+
+static size_t fuse_send_write(struct fuse_req *req, struct file *file,
+ struct inode *inode, loff_t pos, size_t count,
+ fl_owner_t owner)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ fuse_write_fill(req, file->private_data, inode, pos, count, 0);
+ if (owner != NULL) {
+ struct fuse_write_in *inarg = &req->misc.write.in;
+ inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
+ inarg->lock_owner = fuse_lock_owner_id(fc, owner);
+ }
request_send(fc, req);
- return outarg.size;
+ return req->misc.write.out.size;
}
-static int fuse_prepare_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+static int fuse_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- /* No op */
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+
+ *pagep = __grab_cache_page(mapping, index);
+ if (!*pagep)
+ return -ENOMEM;
return 0;
}
-static int fuse_commit_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+static int fuse_buffered_write(struct file *file, struct inode *inode,
+ loff_t pos, unsigned count, struct page *page)
{
int err;
size_t nres;
- unsigned count = to - offset;
- struct inode *inode = page->mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
- loff_t pos = page_offset(page) + offset;
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
struct fuse_req *req;
if (is_bad_inode(inode))
@@ -472,23 +527,39 @@ static int fuse_commit_write(struct file *file, struct page *page,
req->num_pages = 1;
req->pages[0] = page;
req->page_offset = offset;
- nres = fuse_send_write(req, file, inode, pos, count);
+ nres = fuse_send_write(req, file, inode, pos, count, NULL);
err = req->out.h.error;
fuse_put_request(fc, req);
- if (!err && nres != count)
+ if (!err && !nres)
err = -EIO;
if (!err) {
- pos += count;
+ pos += nres;
spin_lock(&fc->lock);
+ fi->attr_version = ++fc->attr_version;
if (pos > inode->i_size)
i_size_write(inode, pos);
spin_unlock(&fc->lock);
- if (offset == 0 && to == PAGE_CACHE_SIZE)
+ if (count == PAGE_CACHE_SIZE)
SetPageUptodate(page);
}
fuse_invalidate_attr(inode);
- return err;
+ return err ? err : nres;
+}
+
+static int fuse_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+ int res = 0;
+
+ if (copied)
+ res = fuse_buffered_write(file, inode, pos, copied, page);
+
+ unlock_page(page);
+ page_cache_release(page);
+ return res;
}
static void fuse_release_user_pages(struct fuse_req *req, int write)
@@ -557,9 +628,11 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
nbytes = min(count, nbytes);
if (write)
- nres = fuse_send_write(req, file, inode, pos, nbytes);
+ nres = fuse_send_write(req, file, inode, pos, nbytes,
+ current->files);
else
- nres = fuse_send_read(req, file, inode, pos, nbytes);
+ nres = fuse_send_read(req, file, inode, pos, nbytes,
+ current->files);
fuse_release_user_pages(req, !write);
if (req->out.h.error) {
if (!res)
@@ -661,7 +734,8 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
}
static void fuse_lk_fill(struct fuse_req *req, struct file *file,
- const struct file_lock *fl, int opcode, pid_t pid)
+ const struct file_lock *fl, int opcode, pid_t pid,
+ int flock)
{
struct inode *inode = file->f_path.dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -674,6 +748,8 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file,
arg->lk.end = fl->fl_end;
arg->lk.type = fl->fl_type;
arg->lk.pid = pid;
+ if (flock)
+ arg->lk_flags |= FUSE_LK_FLOCK;
req->in.h.opcode = opcode;
req->in.h.nodeid = get_node_id(inode);
req->in.numargs = 1;
@@ -693,7 +769,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
if (IS_ERR(req))
return PTR_ERR(req);
- fuse_lk_fill(req, file, fl, FUSE_GETLK, 0);
+ fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0);
req->out.numargs = 1;
req->out.args[0].size = sizeof(outarg);
req->out.args[0].value = &outarg;
@@ -706,7 +782,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl)
return err;
}
-static int fuse_setlk(struct file *file, struct file_lock *fl)
+static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
{
struct inode *inode = file->f_path.dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -723,7 +799,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl)
if (IS_ERR(req))
return PTR_ERR(req);
- fuse_lk_fill(req, file, fl, opcode, pid);
+ fuse_lk_fill(req, file, fl, opcode, pid, flock);
request_send(fc, req);
err = req->out.h.error;
/* locking is restartable */
@@ -749,8 +825,25 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
if (fc->no_lock)
err = posix_lock_file_wait(file, fl);
else
- err = fuse_setlk(file, fl);
+ err = fuse_setlk(file, fl, 0);
+ }
+ return err;
+}
+
+static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ int err;
+
+ if (fc->no_lock) {
+ err = flock_lock_file_wait(file, fl);
+ } else {
+ /* emulate flock with POSIX locks */
+ fl->fl_owner = (fl_owner_t) file;
+ err = fuse_setlk(file, fl, 1);
}
+
return err;
}
@@ -802,6 +895,7 @@ static const struct file_operations fuse_file_operations = {
.release = fuse_release,
.fsync = fuse_fsync,
.lock = fuse_file_lock,
+ .flock = fuse_file_flock,
.splice_read = generic_file_splice_read,
};
@@ -814,13 +908,14 @@ static const struct file_operations fuse_direct_io_file_operations = {
.release = fuse_release,
.fsync = fuse_fsync,
.lock = fuse_file_lock,
+ .flock = fuse_file_flock,
/* no mmap and splice_read */
};
static const struct address_space_operations fuse_file_aops = {
.readpage = fuse_readpage,
- .prepare_write = fuse_prepare_write,
- .commit_write = fuse_commit_write,
+ .write_begin = fuse_write_begin,
+ .write_end = fuse_write_end,
.readpages = fuse_readpages,
.set_page_dirty = fuse_set_page_dirty,
.bmap = fuse_bmap,
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 68ae87cbafa..6c5461de1a5 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -20,7 +20,10 @@
#define FUSE_MAX_PAGES_PER_REQ 32
/** Maximum number of outstanding background requests */
-#define FUSE_MAX_BACKGROUND 10
+#define FUSE_MAX_BACKGROUND 12
+
+/** Congestion starts at 75% of maximum */
+#define FUSE_CONGESTION_THRESHOLD (FUSE_MAX_BACKGROUND * 75 / 100)
/** It could be as large as PATH_MAX, but would that have any uses? */
#define FUSE_NAME_MAX 1024
@@ -60,6 +63,16 @@ struct fuse_inode {
/** Time in jiffies until the file attributes are valid */
u64 i_time;
+
+ /** The sticky bit in inode->i_mode may have been removed, so
+ preserve the original mode */
+ mode_t orig_i_mode;
+
+ /** Version of last attribute change */
+ u64 attr_version;
+
+ /** Files usable in writepage. Protected by fc->lock */
+ struct list_head write_files;
};
/** FUSE specific file data */
@@ -69,6 +82,12 @@ struct fuse_file {
/** File handle used by userspace */
u64 fh;
+
+ /** Refcount */
+ atomic_t count;
+
+ /** Entry on inode's write_files list */
+ struct list_head write_entry;
};
/** One input argument of a request */
@@ -200,6 +219,10 @@ struct fuse_req {
struct fuse_init_in init_in;
struct fuse_init_out init_out;
struct fuse_read_in read_in;
+ struct {
+ struct fuse_write_in in;
+ struct fuse_write_out out;
+ } write;
struct fuse_lk_in lk_in;
} misc;
@@ -213,7 +236,7 @@ struct fuse_req {
unsigned page_offset;
/** File used in the request (or NULL) */
- struct file *file;
+ struct fuse_file *ff;
/** vfsmount used in release */
struct vfsmount *vfsmount;
@@ -286,6 +309,9 @@ struct fuse_conn {
/** waitq for blocked connection */
wait_queue_head_t blocked_waitq;
+ /** waitq for reserved requests */
+ wait_queue_head_t reserved_req_waitq;
+
/** The next unique request id */
u64 reqctr;
@@ -304,6 +330,9 @@ struct fuse_conn {
/** Do readpages asynchronously? Only set in INIT */
unsigned async_read : 1;
+ /** Do not send separate SETATTR request before open(O_TRUNC) */
+ unsigned atomic_o_trunc : 1;
+
/*
* The following bitfields are only for optimization purposes
* and hence races in setting them will not cause malfunction
@@ -374,6 +403,9 @@ struct fuse_conn {
/** Reserved request for the DESTROY message */
struct fuse_req *destroy_req;
+
+ /** Version counter for attribute changes */
+ u64 attr_version;
};
static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
@@ -403,7 +435,8 @@ extern const struct file_operations fuse_dev_operations;
* Get a filled in inode
*/
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
- int generation, struct fuse_attr *attr);
+ int generation, struct fuse_attr *attr,
+ u64 attr_valid, u64 attr_version);
/**
* Send FORGET command
@@ -414,7 +447,7 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
/**
* Initialize READ or READDIR request
*/
-void fuse_read_fill(struct fuse_req *req, struct file *file,
+void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff,
struct inode *inode, loff_t pos, size_t count, int opcode);
/**
@@ -427,9 +460,9 @@ void fuse_file_free(struct fuse_file *ff);
void fuse_finish_open(struct inode *inode, struct file *file,
struct fuse_file *ff, struct fuse_open_out *outarg);
-/** */
-struct fuse_req *fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags,
- int opcode);
+/** Fill in ff->reserved_req with a RELEASE request */
+void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode);
+
/**
* Send RELEASE or RELEASEDIR request
*/
@@ -464,7 +497,8 @@ void fuse_init_symlink(struct inode *inode);
/**
* Change attributes of an inode
*/
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr);
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+ u64 attr_valid, u64 attr_version);
/**
* Initialize the client device
@@ -524,11 +558,6 @@ void request_send_background(struct fuse_conn *fc, struct fuse_req *req);
void fuse_abort_conn(struct fuse_conn *fc);
/**
- * Get the attributes of a file
- */
-int fuse_do_getattr(struct inode *inode);
-
-/**
* Invalidate inode attributes
*/
void fuse_invalidate_attr(struct inode *inode);
@@ -557,3 +586,10 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc);
* Is file type valid?
*/
int fuse_valid_type(int m);
+
+/**
+ * Is task allowed to perform filesystem operation?
+ */
+int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task);
+
+u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 5448f625ab5..9a68d697084 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -56,6 +56,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
fi->i_time = 0;
fi->nodeid = 0;
fi->nlookup = 0;
+ INIT_LIST_HEAD(&fi->write_files);
fi->forget_req = fuse_request_alloc();
if (!fi->forget_req) {
kmem_cache_free(fuse_inode_cachep, inode);
@@ -68,6 +69,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb)
static void fuse_destroy_inode(struct inode *inode)
{
struct fuse_inode *fi = get_fuse_inode(inode);
+ BUG_ON(!list_empty(&fi->write_files));
if (fi->forget_req)
fuse_request_free(fi->forget_req);
kmem_cache_free(fuse_inode_cachep, inode);
@@ -109,20 +111,35 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
return 0;
}
-void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
+static void fuse_truncate(struct address_space *mapping, loff_t offset)
+{
+ /* See vmtruncate() */
+ 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);
+}
+
+
+void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
+ u64 attr_valid, u64 attr_version)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
- invalidate_mapping_pages(inode->i_mapping, 0, -1);
+ struct fuse_inode *fi = get_fuse_inode(inode);
+ loff_t oldsize;
+
+ spin_lock(&fc->lock);
+ if (attr_version != 0 && fi->attr_version > attr_version) {
+ spin_unlock(&fc->lock);
+ return;
+ }
+ fi->attr_version = ++fc->attr_version;
+ fi->i_time = attr_valid;
inode->i_ino = attr->ino;
- inode->i_mode = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
+ inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
inode->i_nlink = attr->nlink;
inode->i_uid = attr->uid;
inode->i_gid = attr->gid;
- spin_lock(&fc->lock);
- i_size_write(inode, attr->size);
- spin_unlock(&fc->lock);
inode->i_blocks = attr->blocks;
inode->i_atime.tv_sec = attr->atime;
inode->i_atime.tv_nsec = attr->atimensec;
@@ -130,6 +147,30 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
inode->i_mtime.tv_nsec = attr->mtimensec;
inode->i_ctime.tv_sec = attr->ctime;
inode->i_ctime.tv_nsec = attr->ctimensec;
+
+ if (attr->blksize != 0)
+ inode->i_blkbits = ilog2(attr->blksize);
+ else
+ inode->i_blkbits = inode->i_sb->s_blocksize_bits;
+
+ /*
+ * Don't set the sticky bit in i_mode, unless we want the VFS
+ * to check permissions. This prevents failures due to the
+ * check in may_delete().
+ */
+ fi->orig_i_mode = inode->i_mode;
+ if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
+ inode->i_mode &= ~S_ISVTX;
+
+ oldsize = inode->i_size;
+ i_size_write(inode, attr->size);
+ spin_unlock(&fc->lock);
+
+ if (S_ISREG(inode->i_mode) && oldsize != attr->size) {
+ if (attr->size < oldsize)
+ fuse_truncate(inode->i_mapping, attr->size);
+ invalidate_inode_pages2(inode->i_mapping);
+ }
}
static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
@@ -169,7 +210,8 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp)
}
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
- int generation, struct fuse_attr *attr)
+ int generation, struct fuse_attr *attr,
+ u64 attr_valid, u64 attr_version)
{
struct inode *inode;
struct fuse_inode *fi;
@@ -197,7 +239,8 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
spin_lock(&fc->lock);
fi->nlookup ++;
spin_unlock(&fc->lock);
- fuse_change_attributes(inode, attr);
+ fuse_change_attributes(inode, attr, attr_valid, attr_version);
+
return inode;
}
@@ -232,6 +275,7 @@ static void fuse_put_super(struct super_block *sb)
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
wake_up_all(&fc->waitq);
wake_up_all(&fc->blocked_waitq);
+ wake_up_all(&fc->reserved_req_waitq);
mutex_lock(&fuse_mutex);
list_del(&fc->entry);
fuse_ctl_remove_conn(fc);
@@ -261,6 +305,11 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
struct fuse_statfs_out outarg;
int err;
+ if (!fuse_allow_task(fc, current)) {
+ buf->f_type = FUSE_SUPER_MAGIC;
+ return 0;
+ }
+
req = fuse_get_req(fc);
if (IS_ERR(req))
return PTR_ERR(req);
@@ -401,6 +450,7 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
static struct fuse_conn *new_conn(void)
{
struct fuse_conn *fc;
+ int err;
fc = kzalloc(sizeof(*fc), GFP_KERNEL);
if (fc) {
@@ -409,6 +459,7 @@ static struct fuse_conn *new_conn(void)
atomic_set(&fc->count, 1);
init_waitqueue_head(&fc->waitq);
init_waitqueue_head(&fc->blocked_waitq);
+ init_waitqueue_head(&fc->reserved_req_waitq);
INIT_LIST_HEAD(&fc->pending);
INIT_LIST_HEAD(&fc->processing);
INIT_LIST_HEAD(&fc->io);
@@ -416,10 +467,18 @@ static struct fuse_conn *new_conn(void)
atomic_set(&fc->num_waiting, 0);
fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
fc->bdi.unplug_io_fn = default_unplug_io_fn;
+ err = bdi_init(&fc->bdi);
+ if (err) {
+ kfree(fc);
+ fc = NULL;
+ goto out;
+ }
fc->reqctr = 0;
fc->blocked = 1;
+ fc->attr_version = 1;
get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
}
+out:
return fc;
}
@@ -429,6 +488,7 @@ void fuse_conn_put(struct fuse_conn *fc)
if (fc->destroy_req)
fuse_request_free(fc->destroy_req);
mutex_destroy(&fc->inst_mutex);
+ bdi_destroy(&fc->bdi);
kfree(fc);
}
}
@@ -446,7 +506,8 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
attr.mode = mode;
attr.ino = FUSE_ROOT_ID;
- return fuse_iget(sb, 1, 0, &attr);
+ attr.nlink = 1;
+ return fuse_iget(sb, 1, 0, &attr, 0, 0);
}
static const struct super_operations fuse_super_operations = {
@@ -477,6 +538,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
fc->async_read = 1;
if (!(arg->flags & FUSE_POSIX_LOCKS))
fc->no_lock = 1;
+ if (arg->flags & FUSE_ATOMIC_O_TRUNC)
+ fc->atomic_o_trunc = 1;
} else {
ra_pages = fc->max_read / PAGE_CACHE_SIZE;
fc->no_lock = 1;
@@ -499,7 +562,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
arg->major = FUSE_KERNEL_VERSION;
arg->minor = FUSE_KERNEL_MINOR_VERSION;
arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
- arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
+ arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS |
+ FUSE_ATOMIC_O_TRUNC;
req->in.h.opcode = FUSE_INIT;
req->in.numargs = 1;
req->in.args[0].size = sizeof(*arg);
@@ -683,8 +747,7 @@ static inline void unregister_fuseblk(void)
static decl_subsys(fuse, NULL, NULL);
static decl_subsys(connections, NULL, NULL);
-static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep,
- unsigned long flags)
+static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo)
{
struct inode * inode = foo;
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 79c91fd8381..7ecfe0d3a49 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -24,7 +24,7 @@
#include "util.h"
#include "glock.h"
-static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo)
{
struct gfs2_inode *ip = foo;
@@ -34,7 +34,7 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned
memset(ip->i_cache, 0, sizeof(ip->i_cache));
}
-static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo)
{
struct gfs2_glock *gl = foo;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 873a511ef2b..9679f8b9870 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -17,6 +17,7 @@
#include <linux/mpage.h>
#include <linux/fs.h>
#include <linux/writeback.h>
+#include <linux/swap.h>
#include <linux/gfs2_ondisk.h>
#include <linux/lm_interface.h>
@@ -349,45 +350,49 @@ out_unlock:
}
/**
- * gfs2_prepare_write - Prepare to write a page to a file
+ * gfs2_write_begin - Begin to write to a file
* @file: The file to write to
- * @page: The page which is to be prepared for writing
- * @from: From (byte range within page)
- * @to: To (byte range within page)
+ * @mapping: The mapping in which to write
+ * @pos: The file offset at which to start writing
+ * @len: Length of the write
+ * @flags: Various flags
+ * @pagep: Pointer to return the page
+ * @fsdata: Pointer to return fs data (unused by GFS2)
*
* Returns: errno
*/
-static int gfs2_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int gfs2_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct gfs2_inode *ip = GFS2_I(page->mapping->host);
- struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
+ struct gfs2_inode *ip = GFS2_I(mapping->host);
+ struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
unsigned int data_blocks, ind_blocks, rblocks;
int alloc_required;
int error = 0;
- loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + from;
- loff_t end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
struct gfs2_alloc *al;
- unsigned int write_len = to - from;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned to = from + len;
+ struct page *page;
-
- gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|LM_FLAG_TRY_1CB, &ip->i_gh);
+ gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &ip->i_gh);
error = gfs2_glock_nq_atime(&ip->i_gh);
- if (unlikely(error)) {
- if (error == GLR_TRYFAILED) {
- unlock_page(page);
- error = AOP_TRUNCATED_PAGE;
- yield();
- }
+ if (unlikely(error))
goto out_uninit;
- }
- gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks);
+ error = -ENOMEM;
+ page = __grab_cache_page(mapping, index);
+ *pagep = page;
+ if (!page)
+ goto out_unlock;
+
+ gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
- error = gfs2_write_alloc_required(ip, pos, write_len, &alloc_required);
+ error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
if (error)
- goto out_unlock;
+ goto out_putpage;
ip->i_alloc.al_requested = 0;
@@ -420,7 +425,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
goto out_trans_fail;
if (gfs2_is_stuffed(ip)) {
- if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
+ if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
error = gfs2_unstuff_dinode(ip, page);
if (error == 0)
goto prepare_write;
@@ -443,6 +448,10 @@ out_qunlock:
out_alloc_put:
gfs2_alloc_put(ip);
}
+out_putpage:
+ page_cache_release(page);
+ if (pos + len > ip->i_inode.i_size)
+ vmtruncate(&ip->i_inode, ip->i_inode.i_size);
out_unlock:
gfs2_glock_dq_m(1, &ip->i_gh);
out_uninit:
@@ -478,65 +487,117 @@ static void adjust_fs_space(struct inode *inode)
}
/**
- * gfs2_commit_write - Commit write to a file
+ * gfs2_stuffed_write_end - Write end for stuffed files
+ * @inode: The inode
+ * @dibh: The buffer_head containing the on-disk inode
+ * @pos: The file position
+ * @len: The length of the write
+ * @copied: How much was actually copied by the VFS
+ * @page: The page
+ *
+ * This copies the data from the page into the inode block after
+ * the inode data structure itself.
+ *
+ * Returns: errno
+ */
+static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page)
+{
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
+ u64 to = pos + copied;
+ void *kaddr;
+ unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode);
+ struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
+
+ BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
+ kaddr = kmap_atomic(page, KM_USER0);
+ memcpy(buf + pos, kaddr + pos, copied);
+ memset(kaddr + pos + copied, 0, len - copied);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ if (!PageUptodate(page))
+ SetPageUptodate(page);
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (inode->i_size < to) {
+ i_size_write(inode, to);
+ ip->i_di.di_size = inode->i_size;
+ di->di_size = cpu_to_be64(inode->i_size);
+ mark_inode_dirty(inode);
+ }
+
+ if (inode == sdp->sd_rindex)
+ adjust_fs_space(inode);
+
+ brelse(dibh);
+ gfs2_trans_end(sdp);
+ gfs2_glock_dq(&ip->i_gh);
+ gfs2_holder_uninit(&ip->i_gh);
+ return copied;
+}
+
+/**
+ * gfs2_write_end
* @file: The file to write to
- * @page: The page containing the data
- * @from: From (byte range within page)
- * @to: To (byte range within page)
+ * @mapping: The address space to write to
+ * @pos: The file position
+ * @len: The length of the data
+ * @copied:
+ * @page: The page that has been written
+ * @fsdata: The fsdata (unused in GFS2)
+ *
+ * The main write_end function for GFS2. We have a separate one for
+ * stuffed files as they are slightly different, otherwise we just
+ * put our locking around the VFS provided functions.
*
* Returns: errno
*/
-static int gfs2_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int gfs2_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
struct inode *inode = page->mapping->host;
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
- int error = -EOPNOTSUPP;
struct buffer_head *dibh;
struct gfs2_alloc *al = &ip->i_alloc;
struct gfs2_dinode *di;
+ unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned int to = from + len;
+ int ret;
- if (gfs2_assert_withdraw(sdp, gfs2_glock_is_locked_by_me(ip->i_gl)))
- goto fail_nounlock;
+ BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == 0);
- error = gfs2_meta_inode_buffer(ip, &dibh);
- if (error)
- goto fail_endtrans;
+ ret = gfs2_meta_inode_buffer(ip, &dibh);
+ if (unlikely(ret)) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto failed;
+ }
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- di = (struct gfs2_dinode *)dibh->b_data;
-
- if (gfs2_is_stuffed(ip)) {
- u64 file_size;
- void *kaddr;
- file_size = ((u64)page->index << PAGE_CACHE_SHIFT) + to;
+ if (gfs2_is_stuffed(ip))
+ return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page);
- kaddr = kmap_atomic(page, KM_USER0);
- memcpy(dibh->b_data + sizeof(struct gfs2_dinode) + from,
- kaddr + from, to - from);
- kunmap_atomic(kaddr, KM_USER0);
+ if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
+ gfs2_page_add_databufs(ip, page, from, to);
- SetPageUptodate(page);
+ ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
- if (inode->i_size < file_size) {
- i_size_write(inode, file_size);
+ if (likely(ret >= 0)) {
+ copied = ret;
+ if ((pos + copied) > inode->i_size) {
+ di = (struct gfs2_dinode *)dibh->b_data;
+ ip->i_di.di_size = inode->i_size;
+ di->di_size = cpu_to_be64(inode->i_size);
mark_inode_dirty(inode);
}
- } else {
- if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED ||
- gfs2_is_jdata(ip))
- gfs2_page_add_databufs(ip, page, from, to);
- error = generic_commit_write(file, page, from, to);
- if (error)
- goto fail;
- }
-
- if (ip->i_di.di_size < inode->i_size) {
- ip->i_di.di_size = inode->i_size;
- di->di_size = cpu_to_be64(inode->i_size);
}
if (inode == sdp->sd_rindex)
@@ -544,33 +605,15 @@ static int gfs2_commit_write(struct file *file, struct page *page,
brelse(dibh);
gfs2_trans_end(sdp);
+failed:
if (al->al_requested) {
gfs2_inplace_release(ip);
gfs2_quota_unlock(ip);
gfs2_alloc_put(ip);
}
- unlock_page(page);
- gfs2_glock_dq_m(1, &ip->i_gh);
- lock_page(page);
+ gfs2_glock_dq(&ip->i_gh);
gfs2_holder_uninit(&ip->i_gh);
- return 0;
-
-fail:
- brelse(dibh);
-fail_endtrans:
- gfs2_trans_end(sdp);
- if (al->al_requested) {
- gfs2_inplace_release(ip);
- gfs2_quota_unlock(ip);
- gfs2_alloc_put(ip);
- }
- unlock_page(page);
- gfs2_glock_dq_m(1, &ip->i_gh);
- lock_page(page);
- gfs2_holder_uninit(&ip->i_gh);
-fail_nounlock:
- ClearPageUptodate(page);
- return error;
+ return ret;
}
/**
@@ -799,8 +842,8 @@ const struct address_space_operations gfs2_file_aops = {
.readpage = gfs2_readpage,
.readpages = gfs2_readpages,
.sync_page = block_sync_page,
- .prepare_write = gfs2_prepare_write,
- .commit_write = gfs2_commit_write,
+ .write_begin = gfs2_write_begin,
+ .write_end = gfs2_write_end,
.set_page_dirty = gfs2_set_page_dirty,
.bmap = gfs2_bmap,
.invalidatepage = gfs2_invalidatepage,
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 46a9e10ff17..bb11fd6752d 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -406,7 +406,7 @@ static int gfs2_open(struct inode *inode, struct file *file)
if (!(file->f_flags & O_LARGEFILE) &&
ip->i_di.di_size > MAX_NON_LFS) {
- error = -EFBIG;
+ error = -EOVERFLOW;
goto fail_gunlock;
}
@@ -535,7 +535,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_POSIX))
return -ENOLCK;
- if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ if (__mandatory_lock(&ip->i_inode))
return -ENOLCK;
if (sdp->sd_args.ar_localflocks) {
@@ -636,7 +636,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK;
- if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ if (__mandatory_lock(&ip->i_inode))
return -ENOLCK;
if (sdp->sd_args.ar_localflocks)
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
index 5ea6b3d45ea..c176f67ba0a 100644
--- a/fs/hfs/extent.c
+++ b/fs/hfs/extent.c
@@ -464,23 +464,20 @@ void hfs_file_truncate(struct inode *inode)
(long long)HFS_I(inode)->phys_size, inode->i_size);
if (inode->i_size > HFS_I(inode)->phys_size) {
struct address_space *mapping = inode->i_mapping;
+ void *fsdata;
struct page *page;
int res;
+ /* XXX: Can use generic_cont_expand? */
size = inode->i_size - 1;
- page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT);
- if (!page)
- return;
- size &= PAGE_CACHE_SIZE - 1;
- size++;
- res = mapping->a_ops->prepare_write(NULL, page, size, size);
- if (!res)
- res = mapping->a_ops->commit_write(NULL, page, size, size);
+ res = pagecache_write_begin(NULL, mapping, size+1, 0,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
+ if (!res) {
+ res = pagecache_write_end(NULL, mapping, size+1, 0, 0,
+ page, fsdata);
+ }
if (res)
inode->i_size = HFS_I(inode)->phys_size;
- unlock_page(page);
- page_cache_release(page);
- mark_inode_dirty(inode);
return;
} else if (inode->i_size == HFS_I(inode)->phys_size)
return;
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index bc835f272a6..97f8446c4ff 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -35,10 +35,14 @@ static int hfs_readpage(struct file *file, struct page *page)
return block_read_full_page(page, hfs_get_block);
}
-static int hfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int hfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return cont_prepare_write(page, from, to, hfs_get_block,
- &HFS_I(page->mapping->host)->phys_size);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ hfs_get_block,
+ &HFS_I(mapping->host)->phys_size);
}
static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
@@ -119,8 +123,8 @@ const struct address_space_operations hfs_btree_aops = {
.readpage = hfs_readpage,
.writepage = hfs_writepage,
.sync_page = block_sync_page,
- .prepare_write = hfs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = hfs_write_begin,
+ .write_end = generic_write_end,
.bmap = hfs_bmap,
.releasepage = hfs_releasepage,
};
@@ -129,8 +133,8 @@ const struct address_space_operations hfs_aops = {
.readpage = hfs_readpage,
.writepage = hfs_writepage,
.sync_page = block_sync_page,
- .prepare_write = hfs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = hfs_write_begin,
+ .write_end = generic_write_end,
.bmap = hfs_bmap,
.direct_IO = hfs_direct_IO,
.writepages = hfs_writepages,
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 6c5f92dfb50..16cbd902f8b 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -430,7 +430,7 @@ static struct file_system_type hfs_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
-static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flags)
+static void hfs_init_once(struct kmem_cache *cachep, void *p)
{
struct hfs_inode_info *i = p;
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index 1a7480089e8..12e899cd788 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -443,21 +443,18 @@ void hfsplus_file_truncate(struct inode *inode)
if (inode->i_size > HFSPLUS_I(inode).phys_size) {
struct address_space *mapping = inode->i_mapping;
struct page *page;
- u32 size = inode->i_size - 1;
+ void *fsdata;
+ u32 size = inode->i_size;
int res;
- page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT);
- if (!page)
- return;
- size &= PAGE_CACHE_SIZE - 1;
- size++;
- res = mapping->a_ops->prepare_write(NULL, page, size, size);
- if (!res)
- res = mapping->a_ops->commit_write(NULL, page, size, size);
+ res = pagecache_write_begin(NULL, mapping, size, 0,
+ AOP_FLAG_UNINTERRUPTIBLE,
+ &page, &fsdata);
if (res)
- inode->i_size = HFSPLUS_I(inode).phys_size;
- unlock_page(page);
- page_cache_release(page);
+ return;
+ res = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata);
+ if (res < 0)
+ return;
mark_inode_dirty(inode);
return;
} else if (inode->i_size == HFSPLUS_I(inode).phys_size)
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 6f7c662174d..37744cf3706 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -27,10 +27,14 @@ static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
return block_write_full_page(page, hfsplus_get_block, wbc);
}
-static int hfsplus_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+static int hfsplus_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return cont_prepare_write(page, from, to, hfsplus_get_block,
- &HFSPLUS_I(page->mapping->host).phys_size);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ hfsplus_get_block,
+ &HFSPLUS_I(mapping->host).phys_size);
}
static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
@@ -114,8 +118,8 @@ const struct address_space_operations hfsplus_btree_aops = {
.readpage = hfsplus_readpage,
.writepage = hfsplus_writepage,
.sync_page = block_sync_page,
- .prepare_write = hfsplus_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = hfsplus_write_begin,
+ .write_end = generic_write_end,
.bmap = hfsplus_bmap,
.releasepage = hfsplus_releasepage,
};
@@ -124,8 +128,8 @@ const struct address_space_operations hfsplus_aops = {
.readpage = hfsplus_readpage,
.writepage = hfsplus_writepage,
.sync_page = block_sync_page,
- .prepare_write = hfsplus_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = hfsplus_write_begin,
+ .write_end = generic_write_end,
.bmap = hfsplus_bmap,
.direct_IO = hfsplus_direct_IO,
.writepages = hfsplus_writepages,
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 7b0f2e5a44e..ecf70dafb64 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -466,7 +466,7 @@ static struct file_system_type hfsplus_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
-static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long flags)
+static void hfsplus_init_once(struct kmem_cache *cachep, void *p)
{
struct hfsplus_inode_info *i = p;
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 06e5930515f..6ae9011b95e 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -3,7 +3,8 @@
#include "os.h"
-/* These are exactly the same definitions as in fs.h, but the names are
+/*
+ * These are exactly the same definitions as in fs.h, but the names are
* changed so that this file can be included in both kernel and user files.
*/
@@ -21,7 +22,8 @@
#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
#define HOSTFS_ATTR_ATTR_FLAG 1024
-/* If you are very careful, you'll notice that these two are missing:
+/*
+ * If you are very careful, you'll notice that these two are missing:
*
* #define ATTR_KILL_SUID 2048
* #define ATTR_KILL_SGID 4096
@@ -76,7 +78,8 @@ extern int make_symlink(const char *from, const char *to);
extern int unlink_file(const char *file);
extern int do_mkdir(const char *file, int mode);
extern int do_rmdir(const char *file);
-extern int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor);
+extern int do_mknod(const char *file, int mode, unsigned int major,
+ unsigned int minor);
extern int link_file(const char *from, const char *to);
extern int do_readlink(char *file, char *buf, int size);
extern int rename_file(char *from, char *to);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index c77862032e8..8966b050196 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -6,21 +6,14 @@
* 2003-02-10 Petr Baudis <pasky@ucw.cz>
*/
-#include <linux/stddef.h>
#include <linux/fs.h>
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
+#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/blkdev.h>
-#include <linux/list.h>
#include <linux/statfs.h>
-#include <linux/kdev_t.h>
-#include <asm/uaccess.h>
#include "hostfs.h"
-#include "kern_util.h"
-#include "kern.h"
#include "init.h"
+#include "kern.h"
struct hostfs_inode_info {
char *host_filename;
@@ -61,18 +54,18 @@ static int __init hostfs_args(char *options, int *add)
char *ptr;
ptr = strchr(options, ',');
- if(ptr != NULL)
+ if (ptr != NULL)
*ptr++ = '\0';
- if(*options != '\0')
+ if (*options != '\0')
root_ino = options;
options = ptr;
- while(options){
+ while (options) {
ptr = strchr(options, ',');
- if(ptr != NULL)
+ if (ptr != NULL)
*ptr++ = '\0';
- if(*options != '\0'){
- if(!strcmp(options, "append"))
+ if (*options != '\0') {
+ if (!strcmp(options, "append"))
append = 1;
else printf("hostfs_args - unsupported option - %s\n",
options);
@@ -102,7 +95,7 @@ static char *dentry_name(struct dentry *dentry, int extra)
len = 0;
parent = dentry;
- while(parent->d_parent != parent){
+ while (parent->d_parent != parent) {
len += parent->d_name.len + 1;
parent = parent->d_parent;
}
@@ -110,12 +103,12 @@ static char *dentry_name(struct dentry *dentry, int extra)
root = HOSTFS_I(parent->d_inode)->host_filename;
len += strlen(root);
name = kmalloc(len + extra + 1, GFP_KERNEL);
- if(name == NULL)
+ if (name == NULL)
return NULL;
name[len] = '\0';
parent = dentry;
- while(parent->d_parent != parent){
+ while (parent->d_parent != parent) {
len -= parent->d_name.len + 1;
name[len] = '/';
strncpy(&name[len + 1], parent->d_name.name,
@@ -136,7 +129,8 @@ static char *inode_name(struct inode *ino, int extra)
static int read_name(struct inode *ino, char *name)
{
- /* The non-int inode fields are copied into ints by stat_file and
+ /*
+ * The non-int inode fields are copied into ints by stat_file and
* then copied into the inode because passing the actual pointers
* in and having them treated as int * breaks on big-endian machines
*/
@@ -149,7 +143,7 @@ static int read_name(struct inode *ino, char *name)
err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
&ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
&ino->i_ctime, &i_blksize, &i_blocks, -1);
- if(err)
+ if (err)
return err;
ino->i_ino = i_ino;
@@ -166,33 +160,33 @@ static char *follow_link(char *link)
char *name, *resolved, *end;
len = 64;
- while(1){
+ while (1) {
n = -ENOMEM;
name = kmalloc(len, GFP_KERNEL);
- if(name == NULL)
+ if (name == NULL)
goto out;
n = do_readlink(link, name, len);
- if(n < len)
+ if (n < len)
break;
len *= 2;
kfree(name);
}
- if(n < 0)
+ if (n < 0)
goto out_free;
- if(*name == '/')
+ if (*name == '/')
return name;
end = strrchr(link, '/');
- if(end == NULL)
+ if (end == NULL)
return name;
*(end + 1) = '\0';
len = strlen(link) + strlen(name) + 1;
resolved = kmalloc(len, GFP_KERNEL);
- if(resolved == NULL){
+ if (resolved == NULL) {
n = -ENOMEM;
goto out_free;
}
@@ -213,20 +207,21 @@ static int read_inode(struct inode *ino)
char *name;
int err = 0;
- /* Unfortunately, we are called from iget() when we don't have a dentry
+ /*
+ * Unfortunately, we are called from iget() when we don't have a dentry
* allocated yet.
*/
- if(list_empty(&ino->i_dentry))
+ if (list_empty(&ino->i_dentry))
goto out;
err = -ENOMEM;
name = inode_name(ino, 0);
- if(name == NULL)
+ if (name == NULL)
goto out;
- if(file_type(name, NULL, NULL) == OS_TYPE_SYMLINK){
+ if (file_type(name, NULL, NULL) == OS_TYPE_SYMLINK) {
name = follow_link(name);
- if(IS_ERR(name)){
+ if (IS_ERR(name)) {
err = PTR_ERR(name);
goto out;
}
@@ -240,7 +235,8 @@ static int read_inode(struct inode *ino)
int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
{
- /* do_statfs uses struct statfs64 internally, but the linux kernel
+ /*
+ * do_statfs uses struct statfs64 internally, but the linux kernel
* struct statfs still has 32-bit versions for most of these fields,
* so we convert them here
*/
@@ -255,7 +251,7 @@ int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
&sf->f_namelen, sf->f_spare);
- if(err)
+ if (err)
return err;
sf->f_blocks = f_blocks;
sf->f_bfree = f_bfree;
@@ -271,7 +267,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
struct hostfs_inode_info *hi;
hi = kmalloc(sizeof(*hi), GFP_KERNEL);
- if(hi == NULL)
+ if (hi == NULL)
return NULL;
*hi = ((struct hostfs_inode_info) { .host_filename = NULL,
@@ -284,7 +280,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
static void hostfs_delete_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
- if(HOSTFS_I(inode)->fd != -1) {
+ if (HOSTFS_I(inode)->fd != -1) {
close_file(&HOSTFS_I(inode)->fd);
HOSTFS_I(inode)->fd = -1;
}
@@ -295,9 +291,11 @@ static void hostfs_destroy_inode(struct inode *inode)
{
kfree(HOSTFS_I(inode)->host_filename);
- /*XXX: This should not happen, probably. The check is here for
- * additional safety.*/
- if(HOSTFS_I(inode)->fd != -1) {
+ /*
+ * XXX: This should not happen, probably. The check is here for
+ * additional safety.
+ */
+ if (HOSTFS_I(inode)->fd != -1) {
close_file(&HOSTFS_I(inode)->fd);
printk(KERN_DEBUG "Closing host fd in .destroy_inode\n");
}
@@ -327,17 +325,17 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
int error, len;
name = dentry_name(file->f_path.dentry, 0);
- if(name == NULL)
+ if (name == NULL)
return -ENOMEM;
dir = open_dir(name, &error);
kfree(name);
- if(dir == NULL)
+ if (dir == NULL)
return -error;
next = file->f_pos;
- while((name = read_dir(dir, &next, &ino, &len)) != NULL){
+ while ((name = read_dir(dir, &next, &ino, &len)) != NULL) {
error = (*filldir)(ent, name, len, file->f_pos,
ino, DT_UNKNOWN);
- if(error) break;
+ if (error) break;
file->f_pos = next;
}
close_dir(dir);
@@ -350,32 +348,33 @@ int hostfs_file_open(struct inode *ino, struct file *file)
int mode = 0, r = 0, w = 0, fd;
mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
- if((mode & HOSTFS_I(ino)->mode) == mode)
+ if ((mode & HOSTFS_I(ino)->mode) == mode)
return 0;
- /* The file may already have been opened, but with the wrong access,
+ /*
+ * The file may already have been opened, but with the wrong access,
* so this resets things and reopens the file with the new access.
*/
- if(HOSTFS_I(ino)->fd != -1){
+ if (HOSTFS_I(ino)->fd != -1) {
close_file(&HOSTFS_I(ino)->fd);
HOSTFS_I(ino)->fd = -1;
}
HOSTFS_I(ino)->mode |= mode;
- if(HOSTFS_I(ino)->mode & FMODE_READ)
+ if (HOSTFS_I(ino)->mode & FMODE_READ)
r = 1;
- if(HOSTFS_I(ino)->mode & FMODE_WRITE)
+ if (HOSTFS_I(ino)->mode & FMODE_WRITE)
w = 1;
- if(w)
+ if (w)
r = 1;
name = dentry_name(file->f_path.dentry, 0);
- if(name == NULL)
+ if (name == NULL)
return -ENOMEM;
fd = open_file(name, r, w, append);
kfree(name);
- if(fd < 0)
+ if (fd < 0)
return fd;
FILE_HOSTFS_I(file)->fd = fd;
@@ -423,7 +422,7 @@ int hostfs_writepage(struct page *page, struct writeback_control *wbc)
base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
- if(err != count){
+ if (err != count) {
ClearPageUptodate(page);
goto out;
}
@@ -452,7 +451,8 @@ int hostfs_readpage(struct file *file, struct page *page)
buffer = kmap(page);
err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
PAGE_CACHE_SIZE);
- if(err < 0) goto out;
+ if (err < 0)
+ goto out;
memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
@@ -466,56 +466,43 @@ int hostfs_readpage(struct file *file, struct page *page)
return err;
}
-int hostfs_prepare_write(struct file *file, struct page *page,
- unsigned int from, unsigned int to)
+int hostfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- char *buffer;
- long long start, tmp;
- int err;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
- start = (long long) page->index << PAGE_CACHE_SHIFT;
- buffer = kmap(page);
- if(from != 0){
- tmp = start;
- err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
- from);
- if(err < 0) goto out;
- }
- if(to != PAGE_CACHE_SIZE){
- start += to;
- err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
- PAGE_CACHE_SIZE - to);
- if(err < 0) goto out;
- }
- err = 0;
- out:
- kunmap(page);
- return err;
+ *pagep = __grab_cache_page(mapping, index);
+ if (!*pagep)
+ return -ENOMEM;
+ return 0;
}
-int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
- unsigned to)
+int hostfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- struct address_space *mapping = page->mapping;
struct inode *inode = mapping->host;
- char *buffer;
- long long start;
- int err = 0;
+ void *buffer;
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ int err;
- start = (((long long) page->index) << PAGE_CACHE_SHIFT) + from;
buffer = kmap(page);
- err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from,
- to - from);
- if(err > 0) err = 0;
+ err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
+ kunmap(page);
- /* Actually, if !err, write_file has added to-from to start, so, despite
- * the appearance, we are comparing i_size against the _last_ written
- * location, as we should. */
+ if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
+ SetPageUptodate(page);
- if(!err && (start > inode->i_size))
- inode->i_size = start;
+ /*
+ * If err > 0, write_file has added err to pos, so we are comparing
+ * i_size against the last byte written.
+ */
+ if (err > 0 && (pos > inode->i_size))
+ inode->i_size = pos;
+ unlock_page(page);
+ page_cache_release(page);
- kunmap(page);
return err;
}
@@ -523,8 +510,8 @@ static const struct address_space_operations hostfs_aops = {
.writepage = hostfs_writepage,
.readpage = hostfs_readpage,
.set_page_dirty = __set_page_dirty_nobuffers,
- .prepare_write = hostfs_prepare_write,
- .commit_write = hostfs_commit_write
+ .write_begin = hostfs_write_begin,
+ .write_end = hostfs_write_end,
};
static int init_inode(struct inode *inode, struct dentry *dentry)
@@ -534,28 +521,28 @@ static int init_inode(struct inode *inode, struct dentry *dentry)
int maj, min;
dev_t rdev = 0;
- if(dentry){
+ if (dentry) {
name = dentry_name(dentry, 0);
- if(name == NULL)
+ if (name == NULL)
goto out;
type = file_type(name, &maj, &min);
- /*Reencode maj and min with the kernel encoding.*/
+ /* Reencode maj and min with the kernel encoding.*/
rdev = MKDEV(maj, min);
kfree(name);
}
else type = OS_TYPE_DIR;
err = 0;
- if(type == OS_TYPE_SYMLINK)
+ if (type == OS_TYPE_SYMLINK)
inode->i_op = &page_symlink_inode_operations;
- else if(type == OS_TYPE_DIR)
+ else if (type == OS_TYPE_DIR)
inode->i_op = &hostfs_dir_iops;
else inode->i_op = &hostfs_iops;
- if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
+ if (type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
else inode->i_fop = &hostfs_file_fops;
- if(type == OS_TYPE_SYMLINK)
+ if (type == OS_TYPE_SYMLINK)
inode->i_mapping->a_ops = &hostfs_link_aops;
else inode->i_mapping->a_ops = &hostfs_aops;
@@ -578,7 +565,7 @@ static int init_inode(struct inode *inode, struct dentry *dentry)
}
int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
- struct nameidata *nd)
+ struct nameidata *nd)
{
struct inode *inode;
char *name;
@@ -586,27 +573,28 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
error = -ENOMEM;
inode = iget(dir->i_sb, 0);
- if(inode == NULL) goto out;
+ if (inode == NULL)
+ goto out;
error = init_inode(inode, dentry);
- if(error)
+ if (error)
goto out_put;
error = -ENOMEM;
name = dentry_name(dentry, 0);
- if(name == NULL)
+ if (name == NULL)
goto out_put;
fd = file_create(name,
mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
- if(fd < 0)
+ if (fd < 0)
error = fd;
else error = read_name(inode, name);
kfree(name);
- if(error)
+ if (error)
goto out_put;
HOSTFS_I(inode)->fd = fd;
@@ -629,25 +617,25 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
err = -ENOMEM;
inode = iget(ino->i_sb, 0);
- if(inode == NULL)
+ if (inode == NULL)
goto out;
err = init_inode(inode, dentry);
- if(err)
+ if (err)
goto out_put;
err = -ENOMEM;
name = dentry_name(dentry, 0);
- if(name == NULL)
+ if (name == NULL)
goto out_put;
err = read_name(inode, name);
kfree(name);
- if(err == -ENOENT){
+ if (err == -ENOENT) {
iput(inode);
inode = NULL;
}
- else if(err)
+ else if (err)
goto out_put;
d_add(dentry, inode);
@@ -666,7 +654,7 @@ static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
int len;
file = inode_name(ino, dentry->d_name.len + 1);
- if(file == NULL)
+ if (file == NULL)
return NULL;
strcat(file, "/");
len = strlen(file);
@@ -680,10 +668,10 @@ int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
char *from_name, *to_name;
int err;
- if((from_name = inode_dentry_name(ino, from)) == NULL)
+ if ((from_name = inode_dentry_name(ino, from)) == NULL)
return -ENOMEM;
to_name = dentry_name(to, 0);
- if(to_name == NULL){
+ if (to_name == NULL) {
kfree(from_name);
return -ENOMEM;
}
@@ -698,9 +686,9 @@ int hostfs_unlink(struct inode *ino, struct dentry *dentry)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = inode_dentry_name(ino, dentry)) == NULL)
return -ENOMEM;
- if(append)
+ if (append)
return -EPERM;
err = unlink_file(file);
@@ -713,7 +701,7 @@ int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = inode_dentry_name(ino, dentry)) == NULL)
return -ENOMEM;
err = make_symlink(file, to);
kfree(file);
@@ -725,7 +713,7 @@ int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = inode_dentry_name(ino, dentry)) == NULL)
return -ENOMEM;
err = do_mkdir(file, mode);
kfree(file);
@@ -737,7 +725,7 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = inode_dentry_name(ino, dentry)) == NULL)
return -ENOMEM;
err = do_rmdir(file);
kfree(file);
@@ -751,26 +739,26 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
int err = -ENOMEM;
inode = iget(dir->i_sb, 0);
- if(inode == NULL)
+ if (inode == NULL)
goto out;
err = init_inode(inode, dentry);
- if(err)
+ if (err)
goto out_put;
err = -ENOMEM;
name = dentry_name(dentry, 0);
- if(name == NULL)
+ if (name == NULL)
goto out_put;
init_special_inode(inode, mode, dev);
err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
- if(err)
+ if (err)
goto out_free;
err = read_name(inode, name);
kfree(name);
- if(err)
+ if (err)
goto out_put;
d_instantiate(dentry, inode);
@@ -790,9 +778,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
char *from_name, *to_name;
int err;
- if((from_name = inode_dentry_name(from_ino, from)) == NULL)
+ if ((from_name = inode_dentry_name(from_ino, from)) == NULL)
return -ENOMEM;
- if((to_name = inode_dentry_name(to_ino, to)) == NULL){
+ if ((to_name = inode_dentry_name(to_ino, to)) == NULL) {
kfree(from_name);
return -ENOMEM;
}
@@ -815,12 +803,12 @@ int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
return -ENOMEM;
if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
- S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
+ S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
err = 0;
else
err = access_file(name, r, w, x);
kfree(name);
- if(!err)
+ if (!err)
err = generic_permission(ino, desired, NULL);
return err;
}
@@ -837,62 +825,55 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
if (err)
return err;
- if(append)
+ if (append)
attr->ia_valid &= ~ATTR_SIZE;
attrs.ia_valid = 0;
- if(attr->ia_valid & ATTR_MODE){
+ if (attr->ia_valid & ATTR_MODE) {
attrs.ia_valid |= HOSTFS_ATTR_MODE;
attrs.ia_mode = attr->ia_mode;
}
- if(attr->ia_valid & ATTR_UID){
+ if (attr->ia_valid & ATTR_UID) {
attrs.ia_valid |= HOSTFS_ATTR_UID;
attrs.ia_uid = attr->ia_uid;
}
- if(attr->ia_valid & ATTR_GID){
+ if (attr->ia_valid & ATTR_GID) {
attrs.ia_valid |= HOSTFS_ATTR_GID;
attrs.ia_gid = attr->ia_gid;
}
- if(attr->ia_valid & ATTR_SIZE){
+ if (attr->ia_valid & ATTR_SIZE) {
attrs.ia_valid |= HOSTFS_ATTR_SIZE;
attrs.ia_size = attr->ia_size;
}
- if(attr->ia_valid & ATTR_ATIME){
+ if (attr->ia_valid & ATTR_ATIME) {
attrs.ia_valid |= HOSTFS_ATTR_ATIME;
attrs.ia_atime = attr->ia_atime;
}
- if(attr->ia_valid & ATTR_MTIME){
+ if (attr->ia_valid & ATTR_MTIME) {
attrs.ia_valid |= HOSTFS_ATTR_MTIME;
attrs.ia_mtime = attr->ia_mtime;
}
- if(attr->ia_valid & ATTR_CTIME){
+ if (attr->ia_valid & ATTR_CTIME) {
attrs.ia_valid |= HOSTFS_ATTR_CTIME;
attrs.ia_ctime = attr->ia_ctime;
}
- if(attr->ia_valid & ATTR_ATIME_SET){
+ if (attr->ia_valid & ATTR_ATIME_SET) {
attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
}
- if(attr->ia_valid & ATTR_MTIME_SET){
+ if (attr->ia_valid & ATTR_MTIME_SET) {
attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
}
name = dentry_name(dentry, 0);
- if(name == NULL)
+ if (name == NULL)
return -ENOMEM;
err = set_attr(name, &attrs, fd);
kfree(name);
- if(err)
+ if (err)
return err;
return inode_setattr(dentry->d_inode, attr);
}
-int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
- struct kstat *stat)
-{
- generic_fillattr(dentry->d_inode, stat);
- return 0;
-}
-
static const struct inode_operations hostfs_iops = {
.create = hostfs_create,
.link = hostfs_link,
@@ -904,7 +885,6 @@ static const struct inode_operations hostfs_iops = {
.rename = hostfs_rename,
.permission = hostfs_permission,
.setattr = hostfs_setattr,
- .getattr = hostfs_getattr,
};
static const struct inode_operations hostfs_dir_iops = {
@@ -919,7 +899,6 @@ static const struct inode_operations hostfs_dir_iops = {
.rename = hostfs_rename,
.permission = hostfs_permission,
.setattr = hostfs_setattr,
- .getattr = hostfs_getattr,
};
int hostfs_link_readpage(struct file *file, struct page *page)
@@ -929,13 +908,13 @@ int hostfs_link_readpage(struct file *file, struct page *page)
buffer = kmap(page);
name = inode_name(page->mapping->host, 0);
- if(name == NULL)
+ if (name == NULL)
return -ENOMEM;
err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
kfree(name);
- if(err == PAGE_CACHE_SIZE)
+ if (err == PAGE_CACHE_SIZE)
err = -E2BIG;
- else if(err > 0){
+ else if (err > 0) {
flush_dcache_page(page);
SetPageUptodate(page);
if (PageError(page)) ClearPageError(page);
@@ -968,31 +947,33 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
err = -ENOMEM;
host_root_path = kmalloc(strlen(root_ino) + 1
+ strlen(req_root) + 1, GFP_KERNEL);
- if(host_root_path == NULL)
+ if (host_root_path == NULL)
goto out;
sprintf(host_root_path, "%s/%s", root_ino, req_root);
root_inode = iget(sb, 0);
- if(root_inode == NULL)
+ if (root_inode == NULL)
goto out_free;
err = init_inode(root_inode, NULL);
- if(err)
+ if (err)
goto out_put;
HOSTFS_I(root_inode)->host_filename = host_root_path;
- /* Avoid that in the error path, iput(root_inode) frees again
- * host_root_path through hostfs_destroy_inode! */
+ /*
+ * Avoid that in the error path, iput(root_inode) frees again
+ * host_root_path through hostfs_destroy_inode!
+ */
host_root_path = NULL;
err = -ENOMEM;
sb->s_root = d_alloc_root(root_inode);
- if(sb->s_root == NULL)
+ if (sb->s_root == NULL)
goto out_put;
err = read_inode(root_inode);
- if(err){
+ if (err) {
/* No iput in this case because the dput does that for us */
dput(sb->s_root);
sb->s_root = NULL;
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 5625e2481dd..35c1a9f33f4 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -3,19 +3,21 @@
* Licensed under the GPL
*/
-#include <unistd.h>
#include <stdio.h>
-#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
#include <dirent.h>
#include <errno.h>
-#include <utime.h>
+#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <sys/vfs.h>
#include "hostfs.h"
-#include "kern_util.h"
+#include "os.h"
#include "user.h"
+#include <utime.h>
int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
int *nlink_out, int *uid_out, int *gid_out,
@@ -25,33 +27,41 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
{
struct stat64 buf;
- if(fd >= 0) {
+ if (fd >= 0) {
if (fstat64(fd, &buf) < 0)
return -errno;
- } else if(lstat64(path, &buf) < 0) {
+ } else if (lstat64(path, &buf) < 0) {
return -errno;
}
- if(inode_out != NULL) *inode_out = buf.st_ino;
- if(mode_out != NULL) *mode_out = buf.st_mode;
- if(nlink_out != NULL) *nlink_out = buf.st_nlink;
- if(uid_out != NULL) *uid_out = buf.st_uid;
- if(gid_out != NULL) *gid_out = buf.st_gid;
- if(size_out != NULL) *size_out = buf.st_size;
- if(atime_out != NULL) {
+ if (inode_out != NULL)
+ *inode_out = buf.st_ino;
+ if (mode_out != NULL)
+ *mode_out = buf.st_mode;
+ if (nlink_out != NULL)
+ *nlink_out = buf.st_nlink;
+ if (uid_out != NULL)
+ *uid_out = buf.st_uid;
+ if (gid_out != NULL)
+ *gid_out = buf.st_gid;
+ if (size_out != NULL)
+ *size_out = buf.st_size;
+ if (atime_out != NULL) {
atime_out->tv_sec = buf.st_atime;
atime_out->tv_nsec = 0;
}
- if(mtime_out != NULL) {
+ if (mtime_out != NULL) {
mtime_out->tv_sec = buf.st_mtime;
mtime_out->tv_nsec = 0;
}
- if(ctime_out != NULL) {
+ if (ctime_out != NULL) {
ctime_out->tv_sec = buf.st_ctime;
ctime_out->tv_nsec = 0;
}
- if(blksize_out != NULL) *blksize_out = buf.st_blksize;
- if(blocks_out != NULL) *blocks_out = buf.st_blocks;
+ if (blksize_out != NULL)
+ *blksize_out = buf.st_blksize;
+ if (blocks_out != NULL)
+ *blocks_out = buf.st_blocks;
return 0;
}
@@ -59,21 +69,29 @@ int file_type(const char *path, int *maj, int *min)
{
struct stat64 buf;
- if(lstat64(path, &buf) < 0)
+ if (lstat64(path, &buf) < 0)
return -errno;
- /*We cannot pass rdev as is because glibc and the kernel disagree
- *about its definition.*/
- if(maj != NULL)
+ /*
+ * We cannot pass rdev as is because glibc and the kernel disagree
+ * about its definition.
+ */
+ if (maj != NULL)
*maj = major(buf.st_rdev);
- if(min != NULL)
+ if (min != NULL)
*min = minor(buf.st_rdev);
- if(S_ISDIR(buf.st_mode)) return OS_TYPE_DIR;
- else if(S_ISLNK(buf.st_mode)) return OS_TYPE_SYMLINK;
- else if(S_ISCHR(buf.st_mode)) return OS_TYPE_CHARDEV;
- else if(S_ISBLK(buf.st_mode)) return OS_TYPE_BLOCKDEV;
- else if(S_ISFIFO(buf.st_mode))return OS_TYPE_FIFO;
- else if(S_ISSOCK(buf.st_mode))return OS_TYPE_SOCK;
+ if (S_ISDIR(buf.st_mode))
+ return OS_TYPE_DIR;
+ else if (S_ISLNK(buf.st_mode))
+ return OS_TYPE_SYMLINK;
+ else if (S_ISCHR(buf.st_mode))
+ return OS_TYPE_CHARDEV;
+ else if (S_ISBLK(buf.st_mode))
+ return OS_TYPE_BLOCKDEV;
+ else if (S_ISFIFO(buf.st_mode))
+ return OS_TYPE_FIFO;
+ else if (S_ISSOCK(buf.st_mode))
+ return OS_TYPE_SOCK;
else return OS_TYPE_FILE;
}
@@ -81,10 +99,13 @@ int access_file(char *path, int r, int w, int x)
{
int mode = 0;
- if(r) mode = R_OK;
- if(w) mode |= W_OK;
- if(x) mode |= X_OK;
- if(access(path, mode) != 0)
+ if (r)
+ mode = R_OK;
+ if (w)
+ mode |= W_OK;
+ if (x)
+ mode |= X_OK;
+ if (access(path, mode) != 0)
return -errno;
else return 0;
}
@@ -93,18 +114,18 @@ int open_file(char *path, int r, int w, int append)
{
int mode = 0, fd;
- if(r && !w)
+ if (r && !w)
mode = O_RDONLY;
- else if(!r && w)
+ else if (!r && w)
mode = O_WRONLY;
- else if(r && w)
+ else if (r && w)
mode = O_RDWR;
else panic("Impossible mode in open_file");
- if(append)
+ if (append)
mode |= O_APPEND;
fd = open64(path, mode);
- if(fd < 0)
+ if (fd < 0)
return -errno;
else return fd;
}
@@ -115,7 +136,7 @@ void *open_dir(char *path, int *err_out)
dir = opendir(path);
*err_out = errno;
- if(dir == NULL)
+ if (dir == NULL)
return NULL;
return dir;
}
@@ -128,7 +149,7 @@ char *read_dir(void *stream, unsigned long long *pos,
seekdir(dir, *pos);
ent = readdir(dir);
- if(ent == NULL)
+ if (ent == NULL)
return NULL;
*len_out = strlen(ent->d_name);
*ino_out = ent->d_ino;
@@ -141,7 +162,7 @@ int read_file(int fd, unsigned long long *offset, char *buf, int len)
int n;
n = pread64(fd, buf, len, *offset);
- if(n < 0)
+ if (n < 0)
return -errno;
*offset += n;
return n;
@@ -152,7 +173,7 @@ int write_file(int fd, unsigned long long *offset, const char *buf, int len)
int n;
n = pwrite64(fd, buf, len, *offset);
- if(n < 0)
+ if (n < 0)
return -errno;
*offset += n;
return n;
@@ -163,7 +184,7 @@ int lseek_file(int fd, long long offset, int whence)
int ret;
ret = lseek64(fd, offset, whence);
- if(ret < 0)
+ if (ret < 0)
return -errno;
return 0;
}
@@ -207,7 +228,7 @@ int file_create(char *name, int ur, int uw, int ux, int gr,
mode |= ow ? S_IWOTH : 0;
mode |= ox ? S_IXOTH : 0;
fd = open64(name, O_CREAT | O_RDWR, mode);
- if(fd < 0)
+ if (fd < 0)
return -errno;
return fd;
}
@@ -230,7 +251,7 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
if (fd >= 0) {
if (fchown(fd, attrs->ia_uid, -1))
return -errno;
- } else if(chown(file, attrs->ia_uid, -1)) {
+ } else if (chown(file, attrs->ia_uid, -1)) {
return -errno;
}
}
@@ -251,9 +272,11 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
}
}
- /* Update accessed and/or modified time, in two parts: first set
+ /*
+ * Update accessed and/or modified time, in two parts: first set
* times according to the changes to perform, and then call futimes()
- * or utimes() to apply them. */
+ * or utimes() to apply them.
+ */
ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
if (attrs->ia_valid & ma) {
err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -283,12 +306,12 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
}
}
- if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
- if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
+ /* Note: ctime is not handled */
+ if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) {
err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
&attrs->ia_atime, &attrs->ia_mtime, NULL,
NULL, NULL, fd);
- if(err != 0)
+ if (err != 0)
return err;
}
return 0;
@@ -299,7 +322,7 @@ int make_symlink(const char *from, const char *to)
int err;
err = symlink(to, from);
- if(err)
+ if (err)
return -errno;
return 0;
}
@@ -309,7 +332,7 @@ int unlink_file(const char *file)
int err;
err = unlink(file);
- if(err)
+ if (err)
return -errno;
return 0;
}
@@ -319,7 +342,7 @@ int do_mkdir(const char *file, int mode)
int err;
err = mkdir(file, mode);
- if(err)
+ if (err)
return -errno;
return 0;
}
@@ -329,7 +352,7 @@ int do_rmdir(const char *file)
int err;
err = rmdir(file);
- if(err)
+ if (err)
return -errno;
return 0;
}
@@ -339,7 +362,7 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
int err;
err = mknod(file, mode, makedev(major, minor));
- if(err)
+ if (err)
return -errno;
return 0;
}
@@ -349,7 +372,7 @@ int link_file(const char *to, const char *from)
int err;
err = link(to, from);
- if(err)
+ if (err)
return -errno;
return 0;
}
@@ -359,9 +382,9 @@ int do_readlink(char *file, char *buf, int size)
int n;
n = readlink(file, buf, size);
- if(n < 0)
+ if (n < 0)
return -errno;
- if(n < size)
+ if (n < size)
buf[n] = '\0';
return n;
}
@@ -371,7 +394,7 @@ int rename_file(char *from, char *to)
int err;
err = rename(from, to);
- if(err < 0)
+ if (err < 0)
return -errno;
return 0;
}
@@ -386,7 +409,7 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out,
int err;
err = statfs64(root, &buf);
- if(err < 0)
+ if (err < 0)
return -errno;
*bsize_out = buf.f_bsize;
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index 5b53e5c5d8d..be8be5040e0 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -86,25 +86,33 @@ static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page,hpfs_get_block, wbc);
}
+
static int hpfs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,hpfs_get_block);
}
-static int hpfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+static int hpfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return cont_prepare_write(page,from,to,hpfs_get_block,
- &hpfs_i(page->mapping->host)->mmu_private);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ hpfs_get_block,
+ &hpfs_i(mapping->host)->mmu_private);
}
+
static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,hpfs_get_block);
}
+
const struct address_space_operations hpfs_aops = {
.readpage = hpfs_readpage,
.writepage = hpfs_writepage,
.sync_page = block_sync_page,
- .prepare_write = hpfs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = hpfs_write_begin,
+ .write_end = generic_write_end,
.bmap = _hpfs_bmap
};
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 89612ee7c80..00971d99996 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -173,7 +173,7 @@ static void hpfs_destroy_inode(struct inode *inode)
kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 950c2fbb815..12aca8ed605 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -179,6 +179,130 @@ full_search:
}
#endif
+static int
+hugetlbfs_read_actor(struct page *page, unsigned long offset,
+ char __user *buf, unsigned long count,
+ unsigned long size)
+{
+ char *kaddr;
+ unsigned long left, copied = 0;
+ int i, chunksize;
+
+ if (size > count)
+ size = count;
+
+ /* Find which 4k chunk and offset with in that chunk */
+ i = offset >> PAGE_CACHE_SHIFT;
+ offset = offset & ~PAGE_CACHE_MASK;
+
+ while (size) {
+ chunksize = PAGE_CACHE_SIZE;
+ if (offset)
+ chunksize -= offset;
+ if (chunksize > size)
+ chunksize = size;
+ kaddr = kmap(&page[i]);
+ left = __copy_to_user(buf, kaddr + offset, chunksize);
+ kunmap(&page[i]);
+ if (left) {
+ copied += (chunksize - left);
+ break;
+ }
+ offset = 0;
+ size -= chunksize;
+ buf += chunksize;
+ copied += chunksize;
+ i++;
+ }
+ return copied ? copied : -EFAULT;
+}
+
+/*
+ * Support for read() - Find the page attached to f_mapping and copy out the
+ * data. Its *very* similar to do_generic_mapping_read(), we can't use that
+ * since it has PAGE_CACHE_SIZE assumptions.
+ */
+static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct address_space *mapping = filp->f_mapping;
+ struct inode *inode = mapping->host;
+ unsigned long index = *ppos >> HPAGE_SHIFT;
+ unsigned long offset = *ppos & ~HPAGE_MASK;
+ unsigned long end_index;
+ loff_t isize;
+ ssize_t retval = 0;
+
+ mutex_lock(&inode->i_mutex);
+
+ /* validate length */
+ if (len == 0)
+ goto out;
+
+ isize = i_size_read(inode);
+ if (!isize)
+ goto out;
+
+ end_index = (isize - 1) >> HPAGE_SHIFT;
+ for (;;) {
+ struct page *page;
+ int nr, ret;
+
+ /* nr is the maximum number of bytes to copy from this page */
+ nr = HPAGE_SIZE;
+ if (index >= end_index) {
+ if (index > end_index)
+ goto out;
+ nr = ((isize - 1) & ~HPAGE_MASK) + 1;
+ if (nr <= offset) {
+ goto out;
+ }
+ }
+ nr = nr - offset;
+
+ /* Find the page */
+ page = find_get_page(mapping, index);
+ if (unlikely(page == NULL)) {
+ /*
+ * We have a HOLE, zero out the user-buffer for the
+ * length of the hole or request.
+ */
+ ret = len < nr ? len : nr;
+ if (clear_user(buf, ret))
+ ret = -EFAULT;
+ } else {
+ /*
+ * We have the page, copy it to user space buffer.
+ */
+ ret = hugetlbfs_read_actor(page, offset, buf, len, nr);
+ }
+ if (ret < 0) {
+ if (retval == 0)
+ retval = ret;
+ if (page)
+ page_cache_release(page);
+ goto out;
+ }
+
+ offset += ret;
+ retval += ret;
+ len -= ret;
+ index += offset >> HPAGE_SHIFT;
+ offset &= ~HPAGE_MASK;
+
+ if (page)
+ page_cache_release(page);
+
+ /* short read or no more work */
+ if ((ret != nr) || (len == 0))
+ break;
+ }
+out:
+ *ppos = ((loff_t)index << HPAGE_SHIFT) + offset;
+ mutex_unlock(&inode->i_mutex);
+ return retval;
+}
+
/*
* Read a page. Again trivial. If it didn't already exist
* in the page cache, it is zero-filled.
@@ -189,15 +313,19 @@ static int hugetlbfs_readpage(struct file *file, struct page * page)
return -EINVAL;
}
-static int hugetlbfs_prepare_write(struct file *file,
- struct page *page, unsigned offset, unsigned to)
+static int hugetlbfs_write_begin(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
return -EINVAL;
}
-static int hugetlbfs_commit_write(struct file *file,
- struct page *page, unsigned offset, unsigned to)
+static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
+ BUG();
return -EINVAL;
}
@@ -256,7 +384,7 @@ static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
struct super_block *sb = inode->i_sb;
if (!hlist_unhashed(&inode->i_hash)) {
- if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+ if (!(inode->i_state & (I_DIRTY|I_SYNC)))
list_move(&inode->i_list, &inode_unused);
inodes_stat.nr_unused++;
if (!sb || (sb->s_flags & MS_ACTIVE)) {
@@ -318,21 +446,15 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
}
}
-/*
- * Expanding truncates are not allowed.
- */
static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
{
pgoff_t pgoff;
struct address_space *mapping = inode->i_mapping;
- if (offset > inode->i_size)
- return -EINVAL;
-
BUG_ON(offset & ~HPAGE_MASK);
pgoff = offset >> PAGE_SHIFT;
- inode->i_size = offset;
+ i_size_write(inode, offset);
spin_lock(&mapping->i_mmap_lock);
if (!prio_tree_empty(&mapping->i_mmap))
hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
@@ -569,13 +691,13 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
static const struct address_space_operations hugetlbfs_aops = {
.readpage = hugetlbfs_readpage,
- .prepare_write = hugetlbfs_prepare_write,
- .commit_write = hugetlbfs_commit_write,
+ .write_begin = hugetlbfs_write_begin,
+ .write_end = hugetlbfs_write_end,
.set_page_dirty = hugetlbfs_set_page_dirty,
};
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
@@ -583,6 +705,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
}
const struct file_operations hugetlbfs_file_operations = {
+ .read = hugetlbfs_read,
.mmap = hugetlbfs_file_mmap,
.fsync = simple_sync_file,
.get_unmapped_area = hugetlb_get_unmapped_area,
@@ -810,16 +933,11 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
if (!dentry)
goto out_shm_unlock;
- error = -ENFILE;
- file = get_empty_filp();
- if (!file)
- goto out_dentry;
-
error = -ENOSPC;
inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
current->fsgid, S_IFREG | S_IRWXUGO, 0);
if (!inode)
- goto out_file;
+ goto out_dentry;
error = -ENOMEM;
if (hugetlb_reserve_pages(inode, 0, size >> HPAGE_SHIFT))
@@ -828,17 +946,18 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
d_instantiate(dentry, inode);
inode->i_size = size;
inode->i_nlink = 0;
- file->f_path.mnt = mntget(hugetlbfs_vfsmount);
- file->f_path.dentry = dentry;
- file->f_mapping = inode->i_mapping;
- file->f_op = &hugetlbfs_file_operations;
- file->f_mode = FMODE_WRITE | FMODE_READ;
+
+ error = -ENFILE;
+ file = alloc_file(hugetlbfs_vfsmount, dentry,
+ FMODE_WRITE | FMODE_READ,
+ &hugetlbfs_file_operations);
+ if (!file)
+ goto out_inode;
+
return file;
out_inode:
iput(inode);
-out_file:
- put_filp(file);
out_dentry:
dput(dentry);
out_shm_unlock:
@@ -851,11 +970,15 @@ static int __init init_hugetlbfs_fs(void)
int error;
struct vfsmount *vfsmount;
+ error = bdi_init(&hugetlbfs_backing_dev_info);
+ if (error)
+ return error;
+
hugetlbfs_inode_cachep = kmem_cache_create("hugetlbfs_inode_cache",
sizeof(struct hugetlbfs_inode_info),
0, 0, init_once);
if (hugetlbfs_inode_cachep == NULL)
- return -ENOMEM;
+ goto out2;
error = register_filesystem(&hugetlbfs_fs_type);
if (error)
@@ -873,6 +996,8 @@ static int __init init_hugetlbfs_fs(void)
out:
if (error)
kmem_cache_destroy(hugetlbfs_inode_cachep);
+ out2:
+ bdi_destroy(&hugetlbfs_backing_dev_info);
return error;
}
@@ -880,6 +1005,7 @@ static void __exit exit_hugetlbfs_fs(void)
{
kmem_cache_destroy(hugetlbfs_inode_cachep);
unregister_filesystem(&hugetlbfs_fs_type);
+ bdi_destroy(&hugetlbfs_backing_dev_info);
}
module_init(init_hugetlbfs_fs)
diff --git a/fs/inode.c b/fs/inode.c
index 29f5068f819..ed35383d0b6 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -99,6 +99,15 @@ struct inodes_stat_t inodes_stat;
static struct kmem_cache * inode_cachep __read_mostly;
+static void wake_up_inode(struct inode *inode)
+{
+ /*
+ * Prevent speculative execution through spin_unlock(&inode_lock);
+ */
+ smp_mb();
+ wake_up_bit(&inode->i_state, __I_LOCK);
+}
+
static struct inode *alloc_inode(struct super_block *sb)
{
static const struct address_space_operations empty_aops;
@@ -142,6 +151,15 @@ static struct inode *alloc_inode(struct super_block *sb)
return NULL;
}
+ spin_lock_init(&inode->i_lock);
+ lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
+
+ mutex_init(&inode->i_mutex);
+ lockdep_set_class(&inode->i_mutex, &sb->s_type->i_mutex_key);
+
+ init_rwsem(&inode->i_alloc_sem);
+ lockdep_set_class(&inode->i_alloc_sem, &sb->s_type->i_alloc_sem_key);
+
mapping->a_ops = &empty_aops;
mapping->host = inode;
mapping->flags = 0;
@@ -190,8 +208,6 @@ void inode_init_once(struct inode *inode)
INIT_HLIST_NODE(&inode->i_hash);
INIT_LIST_HEAD(&inode->i_dentry);
INIT_LIST_HEAD(&inode->i_devices);
- mutex_init(&inode->i_mutex);
- init_rwsem(&inode->i_alloc_sem);
INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
rwlock_init(&inode->i_data.tree_lock);
spin_lock_init(&inode->i_data.i_mmap_lock);
@@ -199,7 +215,6 @@ void inode_init_once(struct inode *inode)
spin_lock_init(&inode->i_data.private_lock);
INIT_RAW_PRIO_TREE_ROOT(&inode->i_data.i_mmap);
INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear);
- spin_lock_init(&inode->i_lock);
i_size_ordered_init(inode);
#ifdef CONFIG_INOTIFY
INIT_LIST_HEAD(&inode->inotify_watches);
@@ -209,7 +224,7 @@ void inode_init_once(struct inode *inode)
EXPORT_SYMBOL(inode_init_once);
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct inode * inode = (struct inode *) foo;
@@ -226,7 +241,7 @@ void __iget(struct inode * inode)
return;
}
atomic_inc(&inode->i_count);
- if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+ if (!(inode->i_state & (I_DIRTY|I_SYNC)))
list_move(&inode->i_list, &inode_in_use);
inodes_stat.nr_unused--;
}
@@ -247,7 +262,7 @@ void clear_inode(struct inode *inode)
BUG_ON(inode->i_data.nrpages);
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
- wait_on_inode(inode);
+ inode_sync_wait(inode);
DQUOT_DROP(inode);
if (inode->i_sb->s_op->clear_inode)
inode->i_sb->s_op->clear_inode(inode);
@@ -561,6 +576,18 @@ EXPORT_SYMBOL(new_inode);
void unlock_new_inode(struct inode *inode)
{
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ if (inode->i_mode & S_IFDIR) {
+ struct file_system_type *type = inode->i_sb->s_type;
+
+ /*
+ * ensure nobody is actually holding i_mutex
+ */
+ mutex_destroy(&inode->i_mutex);
+ mutex_init(&inode->i_mutex);
+ lockdep_set_class(&inode->i_mutex, &type->i_mutex_dir_key);
+ }
+#endif
/*
* This is special! We do not need the spinlock
* when clearing I_LOCK, because we're guaranteed
@@ -1053,7 +1080,7 @@ static void generic_forget_inode(struct inode *inode)
struct super_block *sb = inode->i_sb;
if (!hlist_unhashed(&inode->i_hash)) {
- if (!(inode->i_state & (I_DIRTY|I_LOCK)))
+ if (!(inode->i_state & (I_DIRTY|I_SYNC)))
list_move(&inode->i_list, &inode_unused);
inodes_stat.nr_unused++;
if (sb->s_flags & MS_ACTIVE) {
@@ -1296,15 +1323,6 @@ static void __wait_on_freeing_inode(struct inode *inode)
spin_lock(&inode_lock);
}
-void wake_up_inode(struct inode *inode)
-{
- /*
- * Prevent speculative execution through spin_unlock(&inode_lock);
- */
- smp_mb();
- wake_up_bit(&inode->i_state, __I_LOCK);
-}
-
/*
* We rarely want to lock two inodes that do not have a parent/child
* relationship (such as directory, child inode) simultaneously. The
@@ -1378,7 +1396,7 @@ void __init inode_init_early(void)
INIT_HLIST_HEAD(&inode_hashtable[loop]);
}
-void __init inode_init(unsigned long mempages)
+void __init inode_init(void)
{
int loop;
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
index 9bf2f6c09df..5e009331c01 100644
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -31,6 +31,7 @@
#include <linux/list.h>
#include <linux/inotify.h>
#include <linux/syscalls.h>
+#include <linux/magic.h>
#include <asm/ioctls.h>
@@ -684,7 +685,8 @@ static int
inotify_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
{
- return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA, mnt);
+ return get_sb_pseudo(fs_type, "inotify", NULL,
+ INOTIFYFS_SUPER_MAGIC, mnt);
}
static struct file_system_type inotify_fs_type = {
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
index 6bbbdb53581..37dbd640478 100644
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -33,7 +33,7 @@ static char zisofs_sink_page[PAGE_CACHE_SIZE];
* allocation; this avoids failures at block-decompression time.
*/
static void *zisofs_zlib_workspace;
-static struct semaphore zisofs_zlib_semaphore;
+static DEFINE_MUTEX(zisofs_zlib_lock);
/*
* When decompressing, we typically obtain more than one page
@@ -180,9 +180,9 @@ static int zisofs_readpage(struct file *file, struct page *page)
/* First block is special since it may be fractional.
We also wait for it before grabbing the zlib
- semaphore; odds are that the subsequent blocks are
+ mutex; odds are that the subsequent blocks are
going to come in in short order so we don't hold
- the zlib semaphore longer than necessary. */
+ the zlib mutex longer than necessary. */
if ( !bh || (wait_on_buffer(bh), !buffer_uptodate(bh)) ) {
printk(KERN_DEBUG "zisofs: Hit null buffer, fpage = %d, xpage = %d, csize = %ld\n",
@@ -194,7 +194,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
csize -= stream.avail_in;
stream.workspace = zisofs_zlib_workspace;
- down(&zisofs_zlib_semaphore);
+ mutex_lock(&zisofs_zlib_lock);
zerr = zlib_inflateInit(&stream);
if ( zerr != Z_OK ) {
@@ -281,7 +281,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
zlib_inflateEnd(&stream);
z_eio:
- up(&zisofs_zlib_semaphore);
+ mutex_unlock(&zisofs_zlib_lock);
b_eio:
for ( i = 0 ; i < haveblocks ; i++ ) {
@@ -317,31 +317,16 @@ const struct address_space_operations zisofs_aops = {
/* No bmap operation supported */
};
-static int initialized;
-
int __init zisofs_init(void)
{
- if ( initialized ) {
- printk("zisofs_init: called more than once\n");
- return 0;
- }
-
zisofs_zlib_workspace = vmalloc(zlib_inflate_workspacesize());
if ( !zisofs_zlib_workspace )
return -ENOMEM;
- init_MUTEX(&zisofs_zlib_semaphore);
- initialized = 1;
return 0;
}
void zisofs_cleanup(void)
{
- if ( !initialized ) {
- printk("zisofs_cleanup: called without initialization\n");
- return;
- }
-
vfree(zisofs_zlib_workspace);
- initialized = 0;
}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 043b470fd3b..aa359a2e4ce 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -73,7 +73,7 @@ static void isofs_destroy_inode(struct inode *inode)
kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
}
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct iso_inode_info *ei = foo;
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index c8c7e5138a0..e2b4dad39ca 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -158,7 +158,8 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
int found;
- unsigned long block, offset;
+ unsigned long uninitialized_var(block);
+ unsigned long uninitialized_var(offset);
struct inode *inode;
struct page *page;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index a003d50edcd..a263d82761d 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -375,7 +375,7 @@ void journal_commit_transaction(journal_t *journal)
struct buffer_head *bh = jh2bh(jh);
jbd_lock_bh_state(bh);
- jbd_slab_free(jh->b_committed_data, bh->b_size);
+ jbd_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
jbd_unlock_bh_state(bh);
}
@@ -792,14 +792,14 @@ restart_loop:
* Otherwise, we can just throw away the frozen data now.
*/
if (jh->b_committed_data) {
- jbd_slab_free(jh->b_committed_data, bh->b_size);
+ jbd_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
if (jh->b_frozen_data) {
jh->b_committed_data = jh->b_frozen_data;
jh->b_frozen_data = NULL;
}
} else if (jh->b_frozen_data) {
- jbd_slab_free(jh->b_frozen_data, bh->b_size);
+ jbd_free(jh->b_frozen_data, bh->b_size);
jh->b_frozen_data = NULL;
}
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 06ab3c10b1b..5d9fec0b7eb 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -83,7 +83,6 @@ EXPORT_SYMBOL(journal_force_commit);
static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
static void __journal_abort_soft (journal_t *journal, int errno);
-static int journal_create_jbd_slab(size_t slab_size);
/*
* Helper function used to manage commit timeouts
@@ -218,7 +217,7 @@ static int journal_start_thread(journal_t *journal)
if (IS_ERR(t))
return PTR_ERR(t);
- wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+ wait_event(journal->j_wait_done_commit, journal->j_task != NULL);
return 0;
}
@@ -230,7 +229,8 @@ static void journal_kill_thread(journal_t *journal)
while (journal->j_task) {
wake_up(&journal->j_wait_commit);
spin_unlock(&journal->j_state_lock);
- wait_event(journal->j_wait_done_commit, journal->j_task == 0);
+ wait_event(journal->j_wait_done_commit,
+ journal->j_task == NULL);
spin_lock(&journal->j_state_lock);
}
spin_unlock(&journal->j_state_lock);
@@ -334,10 +334,10 @@ repeat:
char *tmp;
jbd_unlock_bh_state(bh_in);
- tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS);
+ tmp = jbd_alloc(bh_in->b_size, GFP_NOFS);
jbd_lock_bh_state(bh_in);
if (jh_in->b_frozen_data) {
- jbd_slab_free(tmp, bh_in->b_size);
+ jbd_free(tmp, bh_in->b_size);
goto repeat;
}
@@ -654,7 +654,7 @@ static journal_t * journal_init_common (void)
journal_t *journal;
int err;
- journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+ journal = kmalloc(sizeof(*journal), GFP_KERNEL);
if (!journal)
goto fail;
memset(journal, 0, sizeof(*journal));
@@ -1095,13 +1095,6 @@ int journal_load(journal_t *journal)
}
}
- /*
- * Create a slab for this blocksize
- */
- err = journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
- if (err)
- return err;
-
/* Let the recovery code check whether it needs to recover any
* data from the journal. */
if (journal_recover(journal))
@@ -1615,86 +1608,6 @@ int journal_blocks_per_page(struct inode *inode)
}
/*
- * Simple support for retrying memory allocations. Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
- return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size) (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
- "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k"
-};
-
-static void journal_destroy_jbd_slabs(void)
-{
- int i;
-
- for (i = 0; i < JBD_MAX_SLABS; i++) {
- if (jbd_slab[i])
- kmem_cache_destroy(jbd_slab[i]);
- jbd_slab[i] = NULL;
- }
-}
-
-static int journal_create_jbd_slab(size_t slab_size)
-{
- int i = JBD_SLAB_INDEX(slab_size);
-
- BUG_ON(i >= JBD_MAX_SLABS);
-
- /*
- * Check if we already have a slab created for this size
- */
- if (jbd_slab[i])
- return 0;
-
- /*
- * Create a slab and force alignment to be same as slabsize -
- * this will make sure that allocations won't cross the page
- * boundary.
- */
- jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
- slab_size, slab_size, 0, NULL);
- if (!jbd_slab[i]) {
- printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
- return -ENOMEM;
- }
- return 0;
-}
-
-void * jbd_slab_alloc(size_t size, gfp_t flags)
-{
- int idx;
-
- idx = JBD_SLAB_INDEX(size);
- BUG_ON(jbd_slab[idx] == NULL);
- return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd_slab_free(void *ptr, size_t size)
-{
- int idx;
-
- idx = JBD_SLAB_INDEX(size);
- BUG_ON(jbd_slab[idx] == NULL);
- kmem_cache_free(jbd_slab[idx], ptr);
-}
-
-/*
* Journal_head storage management
*/
static struct kmem_cache *journal_head_cache;
@@ -1710,7 +1623,7 @@ static int journal_init_journal_head_cache(void)
journal_head_cache = kmem_cache_create("journal_head",
sizeof(struct journal_head),
0, /* offset */
- 0, /* flags */
+ SLAB_TEMPORARY, /* flags */
NULL); /* ctor */
retval = 0;
if (journal_head_cache == 0) {
@@ -1739,14 +1652,14 @@ static struct journal_head *journal_alloc_journal_head(void)
atomic_inc(&nr_journal_heads);
#endif
ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
- if (ret == 0) {
+ if (ret == NULL) {
jbd_debug(1, "out of memory for journal_head\n");
if (time_after(jiffies, last_warning + 5*HZ)) {
printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
__FUNCTION__);
last_warning = jiffies;
}
- while (ret == 0) {
+ while (ret == NULL) {
yield();
ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
}
@@ -1881,13 +1794,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh)
printk(KERN_WARNING "%s: freeing "
"b_frozen_data\n",
__FUNCTION__);
- jbd_slab_free(jh->b_frozen_data, bh->b_size);
+ jbd_free(jh->b_frozen_data, bh->b_size);
}
if (jh->b_committed_data) {
printk(KERN_WARNING "%s: freeing "
"b_committed_data\n",
__FUNCTION__);
- jbd_slab_free(jh->b_committed_data, bh->b_size);
+ jbd_free(jh->b_committed_data, bh->b_size);
}
bh->b_private = NULL;
jh->b_bh = NULL; /* debug, really */
@@ -2006,7 +1919,7 @@ static int __init journal_init_handle_cache(void)
jbd_handle_cache = kmem_cache_create("journal_handle",
sizeof(handle_t),
0, /* offset */
- 0, /* flags */
+ SLAB_TEMPORARY, /* flags */
NULL); /* ctor */
if (jbd_handle_cache == NULL) {
printk(KERN_EMERG "JBD: failed to create handle cache\n");
@@ -2042,7 +1955,6 @@ static void journal_destroy_caches(void)
journal_destroy_revoke_caches();
journal_destroy_journal_head_cache();
journal_destroy_handle_cache();
- journal_destroy_jbd_slabs();
}
static int __init journal_init(void)
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index 62e13c8db13..ad2eacf570c 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -170,13 +170,15 @@ int __init journal_init_revoke_caches(void)
{
revoke_record_cache = kmem_cache_create("revoke_record",
sizeof(struct jbd_revoke_record_s),
- 0, SLAB_HWCACHE_ALIGN, NULL);
+ 0,
+ SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
+ NULL);
if (revoke_record_cache == 0)
return -ENOMEM;
revoke_table_cache = kmem_cache_create("revoke_table",
sizeof(struct jbd_revoke_table_s),
- 0, 0, NULL);
+ 0, SLAB_TEMPORARY, NULL);
if (revoke_table_cache == 0) {
kmem_cache_destroy(revoke_record_cache);
revoke_record_cache = NULL;
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 772b6531a2a..9841b1e5af0 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -96,8 +96,8 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
alloc_transaction:
if (!journal->j_running_transaction) {
- new_transaction = jbd_kmalloc(sizeof(*new_transaction),
- GFP_NOFS);
+ new_transaction = kmalloc(sizeof(*new_transaction),
+ GFP_NOFS|__GFP_NOFAIL);
if (!new_transaction) {
ret = -ENOMEM;
goto out;
@@ -233,6 +233,8 @@ out:
return ret;
}
+static struct lock_class_key jbd_handle_key;
+
/* Allocate a new handle. This should probably be in a slab... */
static handle_t *new_handle(int nblocks)
{
@@ -243,6 +245,8 @@ static handle_t *new_handle(int nblocks)
handle->h_buffer_credits = nblocks;
handle->h_ref = 1;
+ lockdep_init_map(&handle->h_lockdep_map, "jbd_handle", &jbd_handle_key, 0);
+
return handle;
}
@@ -286,6 +290,9 @@ handle_t *journal_start(journal_t *journal, int nblocks)
current->journal_info = NULL;
handle = ERR_PTR(err);
}
+
+ lock_acquire(&handle->h_lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+
return handle;
}
@@ -668,7 +675,7 @@ repeat:
JBUFFER_TRACE(jh, "allocate memory for buffer");
jbd_unlock_bh_state(bh);
frozen_buffer =
- jbd_slab_alloc(jh2bh(jh)->b_size,
+ jbd_alloc(jh2bh(jh)->b_size,
GFP_NOFS);
if (!frozen_buffer) {
printk(KERN_EMERG
@@ -728,7 +735,7 @@ done:
out:
if (unlikely(frozen_buffer)) /* It's usually NULL */
- jbd_slab_free(frozen_buffer, bh->b_size);
+ jbd_free(frozen_buffer, bh->b_size);
JBUFFER_TRACE(jh, "exit");
return error;
@@ -881,7 +888,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
repeat:
if (!jh->b_committed_data) {
- committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+ committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS);
if (!committed_data) {
printk(KERN_EMERG "%s: No memory for committed data\n",
__FUNCTION__);
@@ -908,7 +915,7 @@ repeat:
out:
journal_put_journal_head(jh);
if (unlikely(committed_data))
- jbd_slab_free(committed_data, bh->b_size);
+ jbd_free(committed_data, bh->b_size);
return err;
}
@@ -1165,7 +1172,7 @@ int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
}
/* That test should have eliminated the following case: */
- J_ASSERT_JH(jh, jh->b_frozen_data == 0);
+ J_ASSERT_JH(jh, jh->b_frozen_data == NULL);
JBUFFER_TRACE(jh, "file as BJ_Metadata");
spin_lock(&journal->j_list_lock);
@@ -1411,6 +1418,8 @@ int journal_stop(handle_t *handle)
spin_unlock(&journal->j_state_lock);
}
+ lock_release(&handle->h_lockdep_map, 1, _THIS_IP_);
+
jbd_free_handle(handle);
return err;
}
@@ -1513,7 +1522,7 @@ static void __journal_temp_unlink_buffer(struct journal_head *jh)
J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
if (jh->b_jlist != BJ_None)
- J_ASSERT_JH(jh, transaction != 0);
+ J_ASSERT_JH(jh, transaction != NULL);
switch (jh->b_jlist) {
case BJ_None:
@@ -1582,11 +1591,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
if (buffer_locked(bh) || buffer_dirty(bh))
goto out;
- if (jh->b_next_transaction != 0)
+ if (jh->b_next_transaction != NULL)
goto out;
spin_lock(&journal->j_list_lock);
- if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
+ if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) {
if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) {
/* A written-back ordered data buffer */
JBUFFER_TRACE(jh, "release data");
@@ -1594,7 +1603,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
journal_remove_journal_head(bh);
__brelse(bh);
}
- } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) {
+ } else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) {
/* written-back checkpointed metadata buffer */
if (jh->b_jlist == BJ_None) {
JBUFFER_TRACE(jh, "remove from checkpoint list");
@@ -1954,7 +1963,7 @@ void __journal_file_buffer(struct journal_head *jh,
J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
J_ASSERT_JH(jh, jh->b_transaction == transaction ||
- jh->b_transaction == 0);
+ jh->b_transaction == NULL);
if (jh->b_transaction && jh->b_jlist == jlist)
return;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index c0f59d1b13d..6986f334c64 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -278,7 +278,7 @@ static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag,
unsigned long long block)
{
tag->t_blocknr = cpu_to_be32(block & (u32)~0);
- if (tag_bytes > JBD_TAG_SIZE32)
+ if (tag_bytes > JBD2_TAG_SIZE32)
tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1);
}
@@ -384,7 +384,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
struct buffer_head *bh = jh2bh(jh);
jbd_lock_bh_state(bh);
- jbd2_slab_free(jh->b_committed_data, bh->b_size);
+ jbd2_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
jbd_unlock_bh_state(bh);
}
@@ -475,7 +475,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
spin_unlock(&journal->j_list_lock);
if (err)
- __jbd2_journal_abort_hard(journal);
+ jbd2_journal_abort(journal, err);
jbd2_journal_write_revoke_records(journal, commit_transaction);
@@ -533,7 +533,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
descriptor = jbd2_journal_get_descriptor_buffer(journal);
if (!descriptor) {
- __jbd2_journal_abort_hard(journal);
+ jbd2_journal_abort(journal, -EIO);
continue;
}
@@ -566,7 +566,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
and repeat this loop: we'll fall into the
refile-on-abort condition above. */
if (err) {
- __jbd2_journal_abort_hard(journal);
+ jbd2_journal_abort(journal, err);
continue;
}
@@ -757,7 +757,7 @@ wait_for_iobuf:
err = -EIO;
if (err)
- __jbd2_journal_abort_hard(journal);
+ jbd2_journal_abort(journal, err);
/* End of a transaction! Finally, we can do checkpoint
processing: any buffers committed as a result of this
@@ -801,14 +801,14 @@ restart_loop:
* Otherwise, we can just throw away the frozen data now.
*/
if (jh->b_committed_data) {
- jbd2_slab_free(jh->b_committed_data, bh->b_size);
+ jbd2_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
if (jh->b_frozen_data) {
jh->b_committed_data = jh->b_frozen_data;
jh->b_frozen_data = NULL;
}
} else if (jh->b_frozen_data) {
- jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+ jbd2_free(jh->b_frozen_data, bh->b_size);
jh->b_frozen_data = NULL;
}
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index f37324aee81..6ddc5531587 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -84,7 +84,6 @@ EXPORT_SYMBOL(jbd2_journal_force_commit);
static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
static void __journal_abort_soft (journal_t *journal, int errno);
-static int jbd2_journal_create_jbd_slab(size_t slab_size);
/*
* Helper function used to manage commit timeouts
@@ -335,10 +334,10 @@ repeat:
char *tmp;
jbd_unlock_bh_state(bh_in);
- tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS);
+ tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS);
jbd_lock_bh_state(bh_in);
if (jh_in->b_frozen_data) {
- jbd2_slab_free(tmp, bh_in->b_size);
+ jbd2_free(tmp, bh_in->b_size);
goto repeat;
}
@@ -655,10 +654,9 @@ static journal_t * journal_init_common (void)
journal_t *journal;
int err;
- journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL);
+ journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL);
if (!journal)
goto fail;
- memset(journal, 0, sizeof(*journal));
init_waitqueue_head(&journal->j_wait_transaction_locked);
init_waitqueue_head(&journal->j_wait_logspace);
@@ -672,7 +670,7 @@ static journal_t * journal_init_common (void)
spin_lock_init(&journal->j_list_lock);
spin_lock_init(&journal->j_state_lock);
- journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE);
+ journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE);
/* The journal is marked for error until we succeed with recovery! */
journal->j_flags = JBD2_ABORT;
@@ -1096,13 +1094,6 @@ int jbd2_journal_load(journal_t *journal)
}
}
- /*
- * Create a slab for this blocksize
- */
- err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize));
- if (err)
- return err;
-
/* Let the recovery code check whether it needs to recover any
* data from the journal. */
if (jbd2_journal_recover(journal))
@@ -1621,89 +1612,9 @@ int jbd2_journal_blocks_per_page(struct inode *inode)
size_t journal_tag_bytes(journal_t *journal)
{
if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT))
- return JBD_TAG_SIZE64;
+ return JBD2_TAG_SIZE64;
else
- return JBD_TAG_SIZE32;
-}
-
-/*
- * Simple support for retrying memory allocations. Introduced to help to
- * debug different VM deadlock avoidance strategies.
- */
-void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry)
-{
- return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0));
-}
-
-/*
- * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed
- * and allocate frozen and commit buffers from these slabs.
- *
- * Reason for doing this is to avoid, SLAB_DEBUG - since it could
- * cause bh to cross page boundary.
- */
-
-#define JBD_MAX_SLABS 5
-#define JBD_SLAB_INDEX(size) (size >> 11)
-
-static struct kmem_cache *jbd_slab[JBD_MAX_SLABS];
-static const char *jbd_slab_names[JBD_MAX_SLABS] = {
- "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k"
-};
-
-static void jbd2_journal_destroy_jbd_slabs(void)
-{
- int i;
-
- for (i = 0; i < JBD_MAX_SLABS; i++) {
- if (jbd_slab[i])
- kmem_cache_destroy(jbd_slab[i]);
- jbd_slab[i] = NULL;
- }
-}
-
-static int jbd2_journal_create_jbd_slab(size_t slab_size)
-{
- int i = JBD_SLAB_INDEX(slab_size);
-
- BUG_ON(i >= JBD_MAX_SLABS);
-
- /*
- * Check if we already have a slab created for this size
- */
- if (jbd_slab[i])
- return 0;
-
- /*
- * Create a slab and force alignment to be same as slabsize -
- * this will make sure that allocations won't cross the page
- * boundary.
- */
- jbd_slab[i] = kmem_cache_create(jbd_slab_names[i],
- slab_size, slab_size, 0, NULL);
- if (!jbd_slab[i]) {
- printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n");
- return -ENOMEM;
- }
- return 0;
-}
-
-void * jbd2_slab_alloc(size_t size, gfp_t flags)
-{
- int idx;
-
- idx = JBD_SLAB_INDEX(size);
- BUG_ON(jbd_slab[idx] == NULL);
- return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL);
-}
-
-void jbd2_slab_free(void *ptr, size_t size)
-{
- int idx;
-
- idx = JBD_SLAB_INDEX(size);
- BUG_ON(jbd_slab[idx] == NULL);
- kmem_cache_free(jbd_slab[idx], ptr);
+ return JBD2_TAG_SIZE32;
}
/*
@@ -1770,7 +1681,7 @@ static void journal_free_journal_head(struct journal_head *jh)
{
#ifdef CONFIG_JBD2_DEBUG
atomic_dec(&nr_journal_heads);
- memset(jh, JBD_POISON_FREE, sizeof(*jh));
+ memset(jh, JBD2_POISON_FREE, sizeof(*jh));
#endif
kmem_cache_free(jbd2_journal_head_cache, jh);
}
@@ -1893,13 +1804,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh)
printk(KERN_WARNING "%s: freeing "
"b_frozen_data\n",
__FUNCTION__);
- jbd2_slab_free(jh->b_frozen_data, bh->b_size);
+ jbd2_free(jh->b_frozen_data, bh->b_size);
}
if (jh->b_committed_data) {
printk(KERN_WARNING "%s: freeing "
"b_committed_data\n",
__FUNCTION__);
- jbd2_slab_free(jh->b_committed_data, bh->b_size);
+ jbd2_free(jh->b_committed_data, bh->b_size);
}
bh->b_private = NULL;
jh->b_bh = NULL; /* debug, really */
@@ -1953,16 +1864,14 @@ void jbd2_journal_put_journal_head(struct journal_head *jh)
/*
* debugfs tunables
*/
-#if defined(CONFIG_JBD2_DEBUG)
-u8 jbd2_journal_enable_debug;
+#ifdef CONFIG_JBD2_DEBUG
+u8 jbd2_journal_enable_debug __read_mostly;
EXPORT_SYMBOL(jbd2_journal_enable_debug);
-#endif
-
-#if defined(CONFIG_JBD2_DEBUG) && defined(CONFIG_DEBUG_FS)
#define JBD2_DEBUG_NAME "jbd2-debug"
-struct dentry *jbd2_debugfs_dir, *jbd2_debug;
+static struct dentry *jbd2_debugfs_dir;
+static struct dentry *jbd2_debug;
static void __init jbd2_create_debugfs_entry(void)
{
@@ -1975,24 +1884,18 @@ static void __init jbd2_create_debugfs_entry(void)
static void __exit jbd2_remove_debugfs_entry(void)
{
- if (jbd2_debug)
- debugfs_remove(jbd2_debug);
- if (jbd2_debugfs_dir)
- debugfs_remove(jbd2_debugfs_dir);
+ debugfs_remove(jbd2_debug);
+ debugfs_remove(jbd2_debugfs_dir);
}
#else
static void __init jbd2_create_debugfs_entry(void)
{
- do {
- } while (0);
}
static void __exit jbd2_remove_debugfs_entry(void)
{
- do {
- } while (0);
}
#endif
@@ -2040,7 +1943,6 @@ static void jbd2_journal_destroy_caches(void)
jbd2_journal_destroy_revoke_caches();
jbd2_journal_destroy_jbd2_journal_head_cache();
jbd2_journal_destroy_handle_cache();
- jbd2_journal_destroy_jbd_slabs();
}
static int __init journal_init(void)
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index b50be8a044e..d0ce627539e 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -311,7 +311,7 @@ int jbd2_journal_skip_recovery(journal_t *journal)
static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag)
{
unsigned long long block = be32_to_cpu(tag->t_blocknr);
- if (tag_bytes > JBD_TAG_SIZE32)
+ if (tag_bytes > JBD2_TAG_SIZE32)
block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32;
return block;
}
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index 01d88975e0c..3595fd432d5 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -352,7 +352,7 @@ int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr,
if (bh)
BUFFER_TRACE(bh, "found on hash");
}
-#ifdef JBD_EXPENSIVE_CHECKING
+#ifdef JBD2_EXPENSIVE_CHECKING
else {
struct buffer_head *bh2;
@@ -453,7 +453,7 @@ int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
}
}
-#ifdef JBD_EXPENSIVE_CHECKING
+#ifdef JBD2_EXPENSIVE_CHECKING
/* There better not be one left behind by now! */
record = find_revoke_record(journal, bh->b_blocknr);
J_ASSERT_JH(jh, record == NULL);
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 7946ff43fc4..b1fcf2b3dca 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/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 = jbd_kmalloc(sizeof(*new_transaction),
- GFP_NOFS);
+ 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);
@@ -236,7 +235,7 @@ out:
/* Allocate a new handle. This should probably be in a slab... */
static handle_t *new_handle(int nblocks)
{
- handle_t *handle = jbd_alloc_handle(GFP_NOFS);
+ handle_t *handle = jbd2_alloc_handle(GFP_NOFS);
if (!handle)
return NULL;
memset(handle, 0, sizeof(*handle));
@@ -282,7 +281,7 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
err = start_this_handle(journal, handle);
if (err < 0) {
- jbd_free_handle(handle);
+ jbd2_free_handle(handle);
current->journal_info = NULL;
handle = ERR_PTR(err);
}
@@ -668,7 +667,7 @@ repeat:
JBUFFER_TRACE(jh, "allocate memory for buffer");
jbd_unlock_bh_state(bh);
frozen_buffer =
- jbd2_slab_alloc(jh2bh(jh)->b_size,
+ jbd2_alloc(jh2bh(jh)->b_size,
GFP_NOFS);
if (!frozen_buffer) {
printk(KERN_EMERG
@@ -728,7 +727,7 @@ done:
out:
if (unlikely(frozen_buffer)) /* It's usually NULL */
- jbd2_slab_free(frozen_buffer, bh->b_size);
+ jbd2_free(frozen_buffer, bh->b_size);
JBUFFER_TRACE(jh, "exit");
return error;
@@ -881,7 +880,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
repeat:
if (!jh->b_committed_data) {
- committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS);
+ committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS);
if (!committed_data) {
printk(KERN_EMERG "%s: No memory for committed data\n",
__FUNCTION__);
@@ -908,7 +907,7 @@ repeat:
out:
jbd2_journal_put_journal_head(jh);
if (unlikely(committed_data))
- jbd2_slab_free(committed_data, bh->b_size);
+ jbd2_free(committed_data, bh->b_size);
return err;
}
@@ -1411,7 +1410,7 @@ int jbd2_journal_stop(handle_t *handle)
spin_unlock(&journal->j_state_lock);
}
- jbd_free_handle(handle);
+ jbd2_free_handle(handle);
return err;
}
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index c2530197be0..023a17539dd 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -19,10 +19,12 @@
#include <linux/jffs2.h>
#include "nodelist.h"
-static int jffs2_commit_write (struct file *filp, struct page *pg,
- unsigned start, unsigned end);
-static int jffs2_prepare_write (struct file *filp, struct page *pg,
- unsigned start, unsigned end);
+static int jffs2_write_end(struct file *filp, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *pg, void *fsdata);
+static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
static int jffs2_readpage (struct file *filp, struct page *pg);
int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
@@ -65,8 +67,8 @@ const struct inode_operations jffs2_file_inode_operations =
const struct address_space_operations jffs2_file_address_operations =
{
.readpage = jffs2_readpage,
- .prepare_write =jffs2_prepare_write,
- .commit_write = jffs2_commit_write
+ .write_begin = jffs2_write_begin,
+ .write_end = jffs2_write_end,
};
static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
@@ -119,15 +121,23 @@ static int jffs2_readpage (struct file *filp, struct page *pg)
return ret;
}
-static int jffs2_prepare_write (struct file *filp, struct page *pg,
- unsigned start, unsigned end)
+static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct inode *inode = pg->mapping->host;
+ struct page *pg;
+ struct inode *inode = mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ uint32_t pageofs = pos & (PAGE_CACHE_SIZE - 1);
int ret = 0;
- D1(printk(KERN_DEBUG "jffs2_prepare_write()\n"));
+ pg = __grab_cache_page(mapping, index);
+ if (!pg)
+ return -ENOMEM;
+ *pagep = pg;
+
+ D1(printk(KERN_DEBUG "jffs2_write_begin()\n"));
if (pageofs > inode->i_size) {
/* Make new hole frag from old EOF to new page */
@@ -142,7 +152,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
if (ret)
- return ret;
+ goto out_page;
down(&f->sem);
memset(&ri, 0, sizeof(ri));
@@ -172,7 +182,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
ret = PTR_ERR(fn);
jffs2_complete_reservation(c);
up(&f->sem);
- return ret;
+ goto out_page;
}
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
if (f->metadata) {
@@ -181,65 +191,79 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
f->metadata = NULL;
}
if (ret) {
- D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
+ D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", ret));
jffs2_mark_node_obsolete(c, fn->raw);
jffs2_free_full_dnode(fn);
jffs2_complete_reservation(c);
up(&f->sem);
- return ret;
+ goto out_page;
}
jffs2_complete_reservation(c);
inode->i_size = pageofs;
up(&f->sem);
}
- /* Read in the page if it wasn't already present, unless it's a whole page */
- if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
+ /*
+ * Read in the page if it wasn't already present. Cannot optimize away
+ * the whole page write case until jffs2_write_end can handle the
+ * case of a short-copy.
+ */
+ if (!PageUptodate(pg)) {
down(&f->sem);
ret = jffs2_do_readpage_nolock(inode, pg);
up(&f->sem);
+ if (ret)
+ goto out_page;
}
- D1(printk(KERN_DEBUG "end prepare_write(). pg->flags %lx\n", pg->flags));
+ D1(printk(KERN_DEBUG "end write_begin(). pg->flags %lx\n", pg->flags));
+ return ret;
+
+out_page:
+ unlock_page(pg);
+ page_cache_release(pg);
return ret;
}
-static int jffs2_commit_write (struct file *filp, struct page *pg,
- unsigned start, unsigned end)
+static int jffs2_write_end(struct file *filp, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *pg, void *fsdata)
{
/* Actually commit the write from the page cache page we're looking at.
* For now, we write the full page out each time. It sucks, but it's simple
*/
- struct inode *inode = pg->mapping->host;
+ struct inode *inode = mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_raw_inode *ri;
+ unsigned start = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned end = start + copied;
unsigned aligned_start = start & ~3;
int ret = 0;
uint32_t writtenlen = 0;
- D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
+ D1(printk(KERN_DEBUG "jffs2_write_end(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
+ /* We need to avoid deadlock with page_cache_read() in
+ jffs2_garbage_collect_pass(). So the page must be
+ up to date to prevent page_cache_read() from trying
+ to re-lock it. */
+ BUG_ON(!PageUptodate(pg));
+
if (end == PAGE_CACHE_SIZE) {
- if (!start) {
- /* We need to avoid deadlock with page_cache_read() in
- jffs2_garbage_collect_pass(). So we have to mark the
- page up to date, to prevent page_cache_read() from
- trying to re-lock it. */
- SetPageUptodate(pg);
- } else {
- /* When writing out the end of a page, write out the
- _whole_ page. This helps to reduce the number of
- nodes in files which have many short writes, like
- syslog files. */
- start = aligned_start = 0;
- }
+ /* When writing out the end of a page, write out the
+ _whole_ page. This helps to reduce the number of
+ nodes in files which have many short writes, like
+ syslog files. */
+ start = aligned_start = 0;
}
ri = jffs2_alloc_raw_inode();
if (!ri) {
- D1(printk(KERN_DEBUG "jffs2_commit_write(): Allocation of raw inode failed\n"));
+ D1(printk(KERN_DEBUG "jffs2_write_end(): Allocation of raw inode failed\n"));
+ unlock_page(pg);
+ page_cache_release(pg);
return -ENOMEM;
}
@@ -287,11 +311,14 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
/* generic_file_write has written more to the page cache than we've
actually written to the medium. Mark the page !Uptodate so that
it gets reread */
- D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n"));
+ D1(printk(KERN_DEBUG "jffs2_write_end(): Not all bytes written. Marking page !uptodate\n"));
SetPageError(pg);
ClearPageUptodate(pg);
}
- D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",start+writtenlen==end?0:ret));
- return start+writtenlen==end?0:ret;
+ D1(printk(KERN_DEBUG "jffs2_write_end() returning %d\n",
+ writtenlen > 0 ? writtenlen : ret));
+ unlock_page(pg);
+ page_cache_release(pg);
+ return writtenlen > 0 ? writtenlen : ret;
}
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index be2b70c2ec1..ffa447511e6 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -43,7 +43,7 @@ static void jffs2_destroy_inode(struct inode *inode)
kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode));
}
-static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void jffs2_i_init_once(struct kmem_cache *cachep, void *foo)
{
struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 3467dde27e5..4672013802e 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -255,7 +255,7 @@ int jfs_get_block(struct inode *ip, sector_t lblock,
static int jfs_writepage(struct page *page, struct writeback_control *wbc)
{
- return nobh_writepage(page, jfs_get_block, wbc);
+ return block_write_full_page(page, jfs_get_block, wbc);
}
static int jfs_writepages(struct address_space *mapping,
@@ -275,10 +275,12 @@ static int jfs_readpages(struct file *file, struct address_space *mapping,
return mpage_readpages(mapping, pages, nr_pages, jfs_get_block);
}
-static int jfs_prepare_write(struct file *file,
- struct page *page, unsigned from, unsigned to)
+static int jfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return nobh_prepare_write(page, from, to, jfs_get_block);
+ return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ jfs_get_block);
}
static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
@@ -302,8 +304,8 @@ const struct address_space_operations jfs_aops = {
.writepage = jfs_writepage,
.writepages = jfs_writepages,
.sync_page = block_sync_page,
- .prepare_write = jfs_prepare_write,
- .commit_write = nobh_commit_write,
+ .write_begin = jfs_write_begin,
+ .write_end = nobh_write_end,
.bmap = jfs_bmap,
.direct_IO = jfs_direct_IO,
};
@@ -356,7 +358,7 @@ void jfs_truncate(struct inode *ip)
{
jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size);
- nobh_truncate_page(ip->i_mapping, ip->i_size);
+ nobh_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block);
IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
jfs_truncate_nolock(ip, ip->i_size);
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 941369c1ac8..f5cd8d38af7 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -180,7 +180,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp)
#endif
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct metapage *mp = (struct metapage *)foo;
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 7aa1f7004ea..e7c60ae6b5b 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -1289,7 +1289,14 @@ int txCommit(tid_t tid, /* transaction identifier */
* commit the transaction synchronously, so the last iput
* will be done by the calling thread (or later)
*/
- if (tblk->u.ip->i_state & I_LOCK)
+ /*
+ * I believe this code is no longer needed. Splitting I_LOCK
+ * into two bits, I_LOCK and I_SYNC should prevent this
+ * deadlock as well. But since I don't have a JFS testload
+ * to verify this, only a trivial s/I_LOCK/I_SYNC/ was done.
+ * Joern
+ */
+ if (tblk->u.ip->i_state & I_SYNC)
tblk->xflag &= ~COMMIT_LAZY;
}
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 4b372f55065..cff60c17194 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -750,7 +750,7 @@ static struct file_system_type jfs_fs_type = {
.fs_flags = FS_REQUIRES_DEV,
};
-static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
diff --git a/fs/libfs.c b/fs/libfs.c
index 5294de1f40c..ae51481e45e 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -351,8 +351,28 @@ int simple_prepare_write(struct file *file, struct page *page,
return 0;
}
-int simple_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+int simple_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ struct page *page;
+ pgoff_t index;
+ unsigned from;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ from = pos & (PAGE_CACHE_SIZE - 1);
+
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+
+ *pagep = page;
+
+ return simple_prepare_write(file, page, from, from+len);
+}
+
+static int simple_commit_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
@@ -369,6 +389,28 @@ int simple_commit_write(struct file *file, struct page *page,
return 0;
}
+int simple_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+
+ /* zero the stale part of the page if we did a short copy */
+ if (copied < len) {
+ void *kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr + from + copied, 0, len - copied);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+
+ simple_commit_write(file, page, from, from+copied);
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ return copied;
+}
+
/*
* the inodes created here are not hashed. If you use iunique to generate
* unique inode values later for this filesystem, then you must take care
@@ -642,7 +684,8 @@ EXPORT_SYMBOL(dcache_dir_open);
EXPORT_SYMBOL(dcache_readdir);
EXPORT_SYMBOL(generic_read_dir);
EXPORT_SYMBOL(get_sb_pseudo);
-EXPORT_SYMBOL(simple_commit_write);
+EXPORT_SYMBOL(simple_write_begin);
+EXPORT_SYMBOL(simple_write_end);
EXPORT_SYMBOL(simple_dir_inode_operations);
EXPORT_SYMBOL(simple_dir_operations);
EXPORT_SYMBOL(simple_empty);
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 3353ed8421a..908b23fadd0 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -10,6 +10,7 @@
#include <linux/utsname.h>
#include <linux/kernel.h>
#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/xprtsock.h>
#include <linux/sunrpc/svc.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/sm_inter.h>
@@ -132,7 +133,7 @@ nsm_create(void)
.sin_port = 0,
};
struct rpc_create_args args = {
- .protocol = IPPROTO_UDP,
+ .protocol = XPRT_TRANSPORT_UDP,
.address = (struct sockaddr *)&sin,
.addrsize = sizeof(sin),
.servername = "localhost",
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 5316e307a49..633653bff94 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -62,8 +62,9 @@ static __be32 *nlm_decode_cookie(__be32 *p, struct nlm_cookie *c)
}
else
{
- printk(KERN_NOTICE
- "lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len, NLM_MAXCOOKIELEN);
+ dprintk("lockd: bad cookie size %d (only cookies under "
+ "%d bytes are supported.)\n",
+ len, NLM_MAXCOOKIELEN);
return NULL;
}
return p;
@@ -84,8 +85,7 @@ nlm_decode_fh(__be32 *p, struct nfs_fh *f)
unsigned int len;
if ((len = ntohl(*p++)) != NFS2_FHSIZE) {
- printk(KERN_NOTICE
- "lockd: bad fhandle size %d (should be %d)\n",
+ dprintk("lockd: bad fhandle size %d (should be %d)\n",
len, NFS2_FHSIZE);
return NULL;
}
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 846fc1d639d..43ff9397e6c 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -64,8 +64,9 @@ nlm4_decode_cookie(__be32 *p, struct nlm_cookie *c)
}
else
{
- printk(KERN_NOTICE
- "lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len, NLM_MAXCOOKIELEN);
+ dprintk("lockd: bad cookie size %d (only cookies under "
+ "%d bytes are supported.)\n",
+ len, NLM_MAXCOOKIELEN);
return NULL;
}
return p;
@@ -86,8 +87,7 @@ nlm4_decode_fh(__be32 *p, struct nfs_fh *f)
memset(f->data, 0, sizeof(f->data));
f->size = ntohl(*p++);
if (f->size > NFS_MAXFHSIZE) {
- printk(KERN_NOTICE
- "lockd: bad fhandle size %d (should be <=%d)\n",
+ dprintk("lockd: bad fhandle size %d (should be <=%d)\n",
f->size, NFS_MAXFHSIZE);
return NULL;
}
diff --git a/fs/locks.c b/fs/locks.c
index c795eaaf6c4..0127a284681 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(locks_init_lock);
* Initialises the fields of the file lock which are invariant for
* free file_locks.
*/
-static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags)
+static void init_once(struct kmem_cache *cache, void *foo)
{
struct file_lock *lock = (struct file_lock *) foo;
@@ -534,7 +534,9 @@ static void locks_insert_block(struct file_lock *blocker,
static void locks_wake_up_blocks(struct file_lock *blocker)
{
while (!list_empty(&blocker->fl_block)) {
- struct file_lock *waiter = list_entry(blocker->fl_block.next,
+ struct file_lock *waiter;
+
+ waiter = list_first_entry(&blocker->fl_block,
struct file_lock, fl_block);
__locks_delete_block(waiter);
if (waiter->fl_lmops && waiter->fl_lmops->fl_notify)
@@ -668,7 +670,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
if (!IS_POSIX(cfl))
continue;
- if (posix_locks_conflict(cfl, fl))
+ if (posix_locks_conflict(fl, cfl))
break;
}
if (cfl)
@@ -698,13 +700,12 @@ EXPORT_SYMBOL(posix_test_lock);
static int posix_locks_deadlock(struct file_lock *caller_fl,
struct file_lock *block_fl)
{
- struct list_head *tmp;
+ struct file_lock *fl;
next_task:
if (posix_same_owner(caller_fl, block_fl))
return 1;
- list_for_each(tmp, &blocked_list) {
- struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
+ list_for_each_entry(fl, &blocked_list, fl_link) {
if (posix_same_owner(fl, block_fl)) {
fl = fl->fl_next;
block_fl = fl;
@@ -715,8 +716,7 @@ next_task:
}
/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
- * at the head of the list, but that's secret knowledge known only to
- * flock_lock_file and posix_lock_file.
+ * after any leases, but before any posix locks.
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
@@ -733,6 +733,15 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
lock_kernel();
if (request->fl_flags & FL_ACCESS)
goto find_conflict;
+
+ if (request->fl_type != F_UNLCK) {
+ error = -ENOMEM;
+ new_fl = locks_alloc_lock();
+ if (new_fl == NULL)
+ goto out;
+ error = 0;
+ }
+
for_each_lock(inode, before) {
struct file_lock *fl = *before;
if (IS_POSIX(fl))
@@ -754,10 +763,6 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
goto out;
}
- error = -ENOMEM;
- new_fl = locks_alloc_lock();
- if (new_fl == NULL)
- goto out;
/*
* If a higher-priority process was blocked on the old file lock,
* give it the opportunity to lock the file.
@@ -819,7 +824,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
lock_kernel();
if (request->fl_type != F_UNLCK) {
for_each_lock(inode, before) {
- struct file_lock *fl = *before;
+ fl = *before;
if (!IS_POSIX(fl))
continue;
if (!posix_locks_conflict(request, fl))
@@ -1113,7 +1118,7 @@ int locks_mandatory_area(int read_write, struct inode *inode,
* If we've been sleeping someone might have
* changed the permissions behind our back.
*/
- if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+ if (__mandatory_lock(inode))
continue;
}
@@ -1337,6 +1342,7 @@ int fcntl_getlease(struct file *filp)
int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
{
struct file_lock *fl, **before, **my_before = NULL, *lease;
+ struct file_lock *new_fl = NULL;
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
int error, rdlease_count = 0, wrlease_count = 0;
@@ -1363,6 +1369,11 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|| (atomic_read(&inode->i_count) > 1)))
goto out;
+ error = -ENOMEM;
+ new_fl = locks_alloc_lock();
+ if (new_fl == NULL)
+ goto out;
+
/*
* At this point, we know that if there is an exclusive
* lease on this file, then we hold it on this filp
@@ -1405,18 +1416,15 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
if (!leases_enable)
goto out;
- error = -ENOMEM;
- fl = locks_alloc_lock();
- if (fl == NULL)
- goto out;
-
- locks_copy_lock(fl, lease);
+ locks_copy_lock(new_fl, lease);
+ locks_insert_lock(before, new_fl);
- locks_insert_lock(before, fl);
+ *flp = new_fl;
+ return 0;
- *flp = fl;
- error = 0;
out:
+ if (new_fl != NULL)
+ locks_free_lock(new_fl);
return error;
}
EXPORT_SYMBOL(generic_setlease);
@@ -1752,9 +1760,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
/* Don't allow mandatory locks on files that may be memory mapped
* and shared.
*/
- if (IS_MANDLOCK(inode) &&
- (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
- mapping_writably_mapped(filp->f_mapping)) {
+ if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
error = -EAGAIN;
goto out;
}
@@ -1878,9 +1884,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
/* Don't allow mandatory locks on files that may be memory mapped
* and shared.
*/
- if (IS_MANDLOCK(inode) &&
- (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
- mapping_writably_mapped(filp->f_mapping)) {
+ if (mandatory_lock(inode) && mapping_writably_mapped(filp->f_mapping)) {
error = -EAGAIN;
goto out;
}
@@ -2062,138 +2066,114 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
EXPORT_SYMBOL_GPL(vfs_cancel_lock);
-static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
+#ifdef CONFIG_PROC_FS
+#include <linux/seq_file.h>
+
+static void lock_get_status(struct seq_file *f, struct file_lock *fl,
+ int id, char *pfx)
{
struct inode *inode = NULL;
if (fl->fl_file != NULL)
inode = fl->fl_file->f_path.dentry->d_inode;
- out += sprintf(out, "%d:%s ", id, pfx);
+ seq_printf(f, "%d:%s ", id, pfx);
if (IS_POSIX(fl)) {
- out += sprintf(out, "%6s %s ",
+ seq_printf(f, "%6s %s ",
(fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ",
(inode == NULL) ? "*NOINODE*" :
- (IS_MANDLOCK(inode) &&
- (inode->i_mode & (S_IXGRP | S_ISGID)) == S_ISGID) ?
- "MANDATORY" : "ADVISORY ");
+ mandatory_lock(inode) ? "MANDATORY" : "ADVISORY ");
} else if (IS_FLOCK(fl)) {
if (fl->fl_type & LOCK_MAND) {
- out += sprintf(out, "FLOCK MSNFS ");
+ seq_printf(f, "FLOCK MSNFS ");
} else {
- out += sprintf(out, "FLOCK ADVISORY ");
+ seq_printf(f, "FLOCK ADVISORY ");
}
} else if (IS_LEASE(fl)) {
- out += sprintf(out, "LEASE ");
+ seq_printf(f, "LEASE ");
if (fl->fl_type & F_INPROGRESS)
- out += sprintf(out, "BREAKING ");
+ seq_printf(f, "BREAKING ");
else if (fl->fl_file)
- out += sprintf(out, "ACTIVE ");
+ seq_printf(f, "ACTIVE ");
else
- out += sprintf(out, "BREAKER ");
+ seq_printf(f, "BREAKER ");
} else {
- out += sprintf(out, "UNKNOWN UNKNOWN ");
+ seq_printf(f, "UNKNOWN UNKNOWN ");
}
if (fl->fl_type & LOCK_MAND) {
- out += sprintf(out, "%s ",
+ seq_printf(f, "%s ",
(fl->fl_type & LOCK_READ)
? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ "
: (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
} else {
- out += sprintf(out, "%s ",
+ seq_printf(f, "%s ",
(fl->fl_type & F_INPROGRESS)
? (fl->fl_type & F_UNLCK) ? "UNLCK" : "READ "
: (fl->fl_type & F_WRLCK) ? "WRITE" : "READ ");
}
if (inode) {
#ifdef WE_CAN_BREAK_LSLK_NOW
- out += sprintf(out, "%d %s:%ld ", fl->fl_pid,
+ seq_printf(f, "%d %s:%ld ", fl->fl_pid,
inode->i_sb->s_id, inode->i_ino);
#else
/* userspace relies on this representation of dev_t ;-( */
- out += sprintf(out, "%d %02x:%02x:%ld ", fl->fl_pid,
+ seq_printf(f, "%d %02x:%02x:%ld ", fl->fl_pid,
MAJOR(inode->i_sb->s_dev),
MINOR(inode->i_sb->s_dev), inode->i_ino);
#endif
} else {
- out += sprintf(out, "%d <none>:0 ", fl->fl_pid);
+ seq_printf(f, "%d <none>:0 ", fl->fl_pid);
}
if (IS_POSIX(fl)) {
if (fl->fl_end == OFFSET_MAX)
- out += sprintf(out, "%Ld EOF\n", fl->fl_start);
+ seq_printf(f, "%Ld EOF\n", fl->fl_start);
else
- out += sprintf(out, "%Ld %Ld\n", fl->fl_start,
- fl->fl_end);
+ seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end);
} else {
- out += sprintf(out, "0 EOF\n");
+ seq_printf(f, "0 EOF\n");
}
}
-static void move_lock_status(char **p, off_t* pos, off_t offset)
+static int locks_show(struct seq_file *f, void *v)
{
- int len;
- len = strlen(*p);
- if(*pos >= offset) {
- /* the complete line is valid */
- *p += len;
- *pos += len;
- return;
- }
- if(*pos+len > offset) {
- /* use the second part of the line */
- int i = offset-*pos;
- memmove(*p,*p+i,len-i);
- *p += len-i;
- *pos += len;
- return;
- }
- /* discard the complete line */
- *pos += len;
+ struct file_lock *fl, *bfl;
+
+ fl = list_entry(v, struct file_lock, fl_link);
+
+ lock_get_status(f, fl, (long)f->private, "");
+
+ list_for_each_entry(bfl, &fl->fl_block, fl_block)
+ lock_get_status(f, bfl, (long)f->private, " ->");
+
+ f->private++;
+ return 0;
}
-/**
- * get_locks_status - reports lock usage in /proc/locks
- * @buffer: address in userspace to write into
- * @start: ?
- * @offset: how far we are through the buffer
- * @length: how much to read
- */
+static void *locks_start(struct seq_file *f, loff_t *pos)
+{
+ lock_kernel();
+ f->private = (void *)1;
+ return seq_list_start(&file_lock_list, *pos);
+}
-int get_locks_status(char *buffer, char **start, off_t offset, int length)
+static void *locks_next(struct seq_file *f, void *v, loff_t *pos)
{
- struct list_head *tmp;
- char *q = buffer;
- off_t pos = 0;
- int i = 0;
+ return seq_list_next(v, &file_lock_list, pos);
+}
- lock_kernel();
- list_for_each(tmp, &file_lock_list) {
- struct list_head *btmp;
- struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
- lock_get_status(q, fl, ++i, "");
- move_lock_status(&q, &pos, offset);
-
- if(pos >= offset+length)
- goto done;
-
- list_for_each(btmp, &fl->fl_block) {
- struct file_lock *bfl = list_entry(btmp,
- struct file_lock, fl_block);
- lock_get_status(q, bfl, i, " ->");
- move_lock_status(&q, &pos, offset);
-
- if(pos >= offset+length)
- goto done;
- }
- }
-done:
+static void locks_stop(struct seq_file *f, void *v)
+{
unlock_kernel();
- *start = buffer;
- if(q-buffer < length)
- return (q-buffer);
- return length;
}
+struct seq_operations locks_seq_operations = {
+ .start = locks_start,
+ .next = locks_next,
+ .stop = locks_stop,
+ .show = locks_show,
+};
+#endif
+
/**
* lock_may_read - checks that the region is free of locks
* @inode: the inode that is being read
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 99a12f12776..703cc35e04b 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -17,7 +17,7 @@
#include <linux/bitops.h>
#include <linux/sched.h>
-static int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
+static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits)
{
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index e207cbe7095..f70433816a3 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -9,8 +9,10 @@
*/
#include "minix.h"
+#include <linux/buffer_head.h>
#include <linux/highmem.h>
#include <linux/smp_lock.h>
+#include <linux/swap.h>
typedef struct minix_dir_entry minix_dirent;
typedef struct minix3_dir_entry minix3_dirent;
@@ -48,11 +50,17 @@ static inline unsigned long dir_pages(struct inode *inode)
return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
}
-static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
+static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
- struct inode *dir = (struct inode *)page->mapping->host;
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
int err = 0;
- page->mapping->a_ops->commit_write(NULL, page, from, to);
+ block_write_end(NULL, mapping, pos, len, len, page, NULL);
+
+ if (pos+len > dir->i_size) {
+ i_size_write(dir, pos+len);
+ mark_inode_dirty(dir);
+ }
if (IS_DIRSYNC(dir))
err = write_one_page(page, 1);
else
@@ -220,7 +228,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
char *kaddr, *p;
minix_dirent *de;
minix3_dirent *de3;
- unsigned from, to;
+ loff_t pos;
int err;
char *namx = NULL;
__u32 inumber;
@@ -272,9 +280,9 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
return -EINVAL;
got_it:
- from = p - (char*)page_address(page);
- to = from + sbi->s_dirsize;
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ pos = (page->index >> PAGE_CACHE_SHIFT) + p - (char*)page_address(page);
+ err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err)
goto out_unlock;
memcpy (namx, name, namelen);
@@ -285,7 +293,7 @@ got_it:
memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2);
de->inode = inode->i_ino;
}
- err = dir_commit_chunk(page, from, to);
+ err = dir_commit_chunk(page, pos, sbi->s_dirsize);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
out_put:
@@ -302,15 +310,16 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
struct address_space *mapping = page->mapping;
struct inode *inode = (struct inode*)mapping->host;
char *kaddr = page_address(page);
- unsigned from = (char*)de - kaddr;
- unsigned to = from + minix_sb(inode->i_sb)->s_dirsize;
+ loff_t pos = page_offset(page) + (char*)de - kaddr;
+ unsigned len = minix_sb(inode->i_sb)->s_dirsize;
int err;
lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __minix_write_begin(NULL, mapping, pos, len,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err == 0) {
de->inode = 0;
- err = dir_commit_chunk(page, from, to);
+ err = dir_commit_chunk(page, pos, len);
} else {
unlock_page(page);
}
@@ -330,7 +339,8 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
if (!page)
return -ENOMEM;
- err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * sbi->s_dirsize);
+ err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err) {
unlock_page(page);
goto fail;
@@ -421,17 +431,20 @@ not_empty:
void minix_set_link(struct minix_dir_entry *de, struct page *page,
struct inode *inode)
{
- struct inode *dir = (struct inode*)page->mapping->host;
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
struct minix_sb_info *sbi = minix_sb(dir->i_sb);
- unsigned from = (char *)de-(char*)page_address(page);
- unsigned to = from + sbi->s_dirsize;
+ loff_t pos = page_offset(page) +
+ (char *)de-(char*)page_address(page);
int err;
lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+
+ err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err == 0) {
de->inode = inode->i_ino;
- err = dir_commit_chunk(page, from, to);
+ err = dir_commit_chunk(page, pos, sbi->s_dirsize);
} else {
unlock_page(page);
}
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 43668d7d668..bf4cd316af8 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -69,7 +69,7 @@ static void minix_destroy_inode(struct inode *inode)
kmem_cache_free(minix_inode_cachep, minix_i(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct minix_inode_info *ei = (struct minix_inode_info *) foo;
@@ -346,24 +346,39 @@ static int minix_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page, minix_get_block, wbc);
}
+
static int minix_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,minix_get_block);
}
-static int minix_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+int __minix_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page,from,to,minix_get_block);
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ minix_get_block);
}
+
+static int minix_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ *pagep = NULL;
+ return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+}
+
static sector_t minix_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,minix_get_block);
}
+
static const struct address_space_operations minix_aops = {
.readpage = minix_readpage,
.writepage = minix_writepage,
.sync_page = block_sync_page,
- .prepare_write = minix_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = minix_write_begin,
+ .write_end = generic_write_end,
.bmap = minix_bmap
};
diff --git a/fs/minix/itree_v1.c b/fs/minix/itree_v1.c
index 1a5f3bf0bce..82d6554b02f 100644
--- a/fs/minix/itree_v1.c
+++ b/fs/minix/itree_v1.c
@@ -23,11 +23,16 @@ static inline block_t *i_data(struct inode *inode)
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
int n = 0;
+ char b[BDEVNAME_SIZE];
if (block < 0) {
- printk("minix_bmap: block<0\n");
+ printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
+ block, bdevname(inode->i_sb->s_bdev, b));
} else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
- printk("minix_bmap: block>big\n");
+ if (printk_ratelimit())
+ printk("MINIX-fs: block_to_path: "
+ "block %ld too big on dev %s\n",
+ block, bdevname(inode->i_sb->s_bdev, b));
} else if (block < 7) {
offsets[n++] = block;
} else if ((block -= 7) < 512) {
diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c
index ad8f0dec4ef..f2301096936 100644
--- a/fs/minix/itree_v2.c
+++ b/fs/minix/itree_v2.c
@@ -23,12 +23,17 @@ static inline block_t *i_data(struct inode *inode)
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
int n = 0;
+ char b[BDEVNAME_SIZE];
struct super_block *sb = inode->i_sb;
if (block < 0) {
- printk("minix_bmap: block<0\n");
+ printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
+ block, bdevname(sb->s_bdev, b));
} else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) {
- printk("minix_bmap: block>big\n");
+ if (printk_ratelimit())
+ printk("MINIX-fs: block_to_path: "
+ "block %ld too big on dev %s\n",
+ block, bdevname(sb->s_bdev, b));
} else if (block < 7) {
offsets[n++] = block;
} else if ((block -= 7) < 256) {
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index 73ef84f8fb0..ac5d3a75cb0 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -54,6 +54,9 @@ extern int minix_new_block(struct inode * inode);
extern void minix_free_block(struct inode *inode, unsigned long block);
extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi);
extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern int __minix_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
extern void V1_minix_truncate(struct inode *);
extern void V2_minix_truncate(struct inode *);
diff --git a/fs/mpage.c b/fs/mpage.c
index b1c3e589050..d54f8f89722 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -379,31 +379,25 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
struct bio *bio = NULL;
unsigned page_idx;
sector_t last_block_in_bio = 0;
- struct pagevec lru_pvec;
struct buffer_head map_bh;
unsigned long first_logical_block = 0;
clear_buffer_mapped(&map_bh);
- pagevec_init(&lru_pvec, 0);
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
struct page *page = list_entry(pages->prev, struct page, lru);
prefetchw(&page->flags);
list_del(&page->lru);
- if (!add_to_page_cache(page, mapping,
+ if (!add_to_page_cache_lru(page, mapping,
page->index, GFP_KERNEL)) {
bio = do_mpage_readpage(bio, page,
nr_pages - page_idx,
&last_block_in_bio, &map_bh,
&first_logical_block,
get_block);
- if (!pagevec_add(&lru_pvec, page))
- __pagevec_lru_add(&lru_pvec);
- } else {
- page_cache_release(page);
}
+ page_cache_release(page);
}
- pagevec_lru_add(&lru_pvec);
BUG_ON(!list_empty(pages));
if (bio)
mpage_bio_submit(READ, bio);
diff --git a/fs/namei.c b/fs/namei.c
index a83160acd74..1e5c7166916 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -30,7 +30,6 @@
#include <linux/capability.h>
#include <linux/file.h>
#include <linux/fcntl.h>
-#include <linux/namei.h>
#include <asm/namei.h>
#include <asm/uaccess.h>
@@ -228,10 +227,14 @@ int generic_permission(struct inode *inode, int mask,
int permission(struct inode *inode, int mask, struct nameidata *nd)
{
- umode_t mode = inode->i_mode;
int retval, submask;
+ struct vfsmount *mnt = NULL;
+
+ if (nd)
+ mnt = nd->mnt;
if (mask & MAY_WRITE) {
+ umode_t mode = inode->i_mode;
/*
* Nobody gets write access to a read-only fs.
@@ -247,22 +250,34 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
return -EACCES;
}
-
- /*
- * MAY_EXEC on regular files requires special handling: We override
- * filesystem execute permissions if the mode bits aren't set or
- * the fs is mounted with the "noexec" flag.
- */
- if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) ||
- (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC))))
- return -EACCES;
+ if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
+ /*
+ * MAY_EXEC on regular files is denied if the fs is mounted
+ * with the "noexec" flag.
+ */
+ if (mnt && (mnt->mnt_flags & MNT_NOEXEC))
+ return -EACCES;
+ }
/* Ordinary permission routines do not understand MAY_APPEND. */
submask = mask & ~MAY_APPEND;
- if (inode->i_op && inode->i_op->permission)
+ if (inode->i_op && inode->i_op->permission) {
retval = inode->i_op->permission(inode, submask, nd);
- else
+ if (!retval) {
+ /*
+ * Exec permission on a regular file is denied if none
+ * of the execute bits are set.
+ *
+ * This check should be done by the ->permission()
+ * method.
+ */
+ if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode) &&
+ !(inode->i_mode & S_IXUGO))
+ return -EACCES;
+ }
+ } else {
retval = generic_permission(inode, submask, NULL);
+ }
if (retval)
return retval;
@@ -1273,7 +1288,8 @@ int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
return err;
}
-static inline struct dentry *__lookup_hash_kern(struct qstr *name, struct dentry *base, struct nameidata *nd)
+static struct dentry *__lookup_hash(struct qstr *name,
+ struct dentry *base, struct nameidata *nd)
{
struct dentry *dentry;
struct inode *inode;
@@ -1313,31 +1329,18 @@ out:
* needs parent already locked. Doesn't follow mounts.
* SMP-safe.
*/
-static inline struct dentry * __lookup_hash(struct qstr *name, struct dentry *base, struct nameidata *nd)
+static struct dentry *lookup_hash(struct nameidata *nd)
{
- struct dentry *dentry;
- struct inode *inode;
int err;
- inode = base->d_inode;
-
- err = permission(inode, MAY_EXEC, nd);
- dentry = ERR_PTR(err);
+ err = permission(nd->dentry->d_inode, MAY_EXEC, nd);
if (err)
- goto out;
-
- dentry = __lookup_hash_kern(name, base, nd);
-out:
- return dentry;
-}
-
-static struct dentry *lookup_hash(struct nameidata *nd)
-{
+ return ERR_PTR(err);
return __lookup_hash(&nd->last, nd->dentry, nd);
}
-/* SMP-safe */
-static inline int __lookup_one_len(const char *name, struct qstr *this, struct dentry *base, int len)
+static int __lookup_one_len(const char *name, struct qstr *this,
+ struct dentry *base, int len)
{
unsigned long hash;
unsigned int c;
@@ -1358,6 +1361,17 @@ static inline int __lookup_one_len(const char *name, struct qstr *this, struct d
return 0;
}
+/**
+ * lookup_one_len: filesystem helper to lookup single pathname component
+ * @name: pathname component to lookup
+ * @base: base directory to lookup from
+ * @len: maximum length @len should be interpreted to
+ *
+ * Note that this routine is purely a helper for filesystem useage and should
+ * not be called by generic code. Also note that by using this function to
+ * nameidata argument is passed to the filesystem methods and a filesystem
+ * using this helper needs to be prepared for that.
+ */
struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
{
int err;
@@ -1366,18 +1380,33 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
err = __lookup_one_len(name, &this, base, len);
if (err)
return ERR_PTR(err);
+
+ err = permission(base->d_inode, MAY_EXEC, NULL);
+ if (err)
+ return ERR_PTR(err);
return __lookup_hash(&this, base, NULL);
}
-struct dentry *lookup_one_len_kern(const char *name, struct dentry *base, int len)
+/**
+ * lookup_one_noperm - bad hack for sysfs
+ * @name: pathname component to lookup
+ * @base: base directory to lookup from
+ *
+ * This is a variant of lookup_one_len that doesn't perform any permission
+ * checks. It's a horrible hack to work around the braindead sysfs
+ * architecture and should not be used anywhere else.
+ *
+ * DON'T USE THIS FUNCTION EVER, thanks.
+ */
+struct dentry *lookup_one_noperm(const char *name, struct dentry *base)
{
int err;
struct qstr this;
- err = __lookup_one_len(name, &this, base, len);
+ err = __lookup_one_len(name, &this, base, strlen(name));
if (err)
return ERR_PTR(err);
- return __lookup_hash_kern(&this, base, NULL);
+ return __lookup_hash(&this, base, NULL);
}
int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
@@ -1579,10 +1608,6 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
return -EISDIR;
- error = vfs_permission(nd, acc_mode);
- if (error)
- return error;
-
/*
* FIFO's, sockets and device files are special: they don't
* actually live on the filesystem itself, and as such you
@@ -1597,6 +1622,10 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
flag &= ~O_TRUNC;
} else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
return -EROFS;
+
+ error = vfs_permission(nd, acc_mode);
+ if (error)
+ return error;
/*
* An append-only file must be opened in append mode for writing.
*/
@@ -1630,8 +1659,10 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
error = locks_verify_locked(inode);
if (!error) {
DQUOT_INIT(inode);
-
- error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
+
+ error = do_truncate(dentry, 0,
+ ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
+ NULL);
}
put_write_access(inode);
if (error)
@@ -2729,53 +2760,29 @@ int __page_symlink(struct inode *inode, const char *symname, int len,
{
struct address_space *mapping = inode->i_mapping;
struct page *page;
+ void *fsdata;
int err;
char *kaddr;
retry:
- err = -ENOMEM;
- page = find_or_create_page(mapping, 0, gfp_mask);
- if (!page)
- goto fail;
- err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
- if (err == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- goto retry;
- }
+ err = pagecache_write_begin(NULL, mapping, 0, len-1,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
if (err)
- goto fail_map;
+ goto fail;
+
kaddr = kmap_atomic(page, KM_USER0);
memcpy(kaddr, symname, len-1);
kunmap_atomic(kaddr, KM_USER0);
- err = mapping->a_ops->commit_write(NULL, page, 0, len-1);
- if (err == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- goto retry;
- }
- if (err)
- goto fail_map;
- /*
- * Notice that we are _not_ going to block here - end of page is
- * unmapped, so this will only try to map the rest of page, see
- * that it is unmapped (typically even will not look into inode -
- * ->i_size will be enough for everything) and zero it out.
- * OTOH it's obviously correct and should make the page up-to-date.
- */
- if (!PageUptodate(page)) {
- err = mapping->a_ops->readpage(NULL, page);
- if (err != AOP_TRUNCATED_PAGE)
- wait_on_page_locked(page);
- } else {
- unlock_page(page);
- }
- page_cache_release(page);
+
+ err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
+ page, fsdata);
if (err < 0)
goto fail;
+ if (err < len-1)
+ goto retry;
+
mark_inode_dirty(inode);
return 0;
-fail_map:
- unlock_page(page);
- page_cache_release(page);
fail:
return err;
}
diff --git a/fs/namespace.c b/fs/namespace.c
index ddbda13c2d3..07daa797259 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1791,7 +1791,7 @@ static void __init init_mount_tree(void)
set_fs_root(current->fs, ns->root, ns->root->mnt_root);
}
-void __init mnt_init(unsigned long mempages)
+void __init mnt_init(void)
{
struct list_head *d;
unsigned int nr_hash;
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 7f8536dbded..e1cb70c643f 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -56,7 +56,7 @@ static void ncp_destroy_inode(struct inode *inode)
kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index b55cb236cf7..df0f41e0988 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -16,4 +16,3 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
nfs4namespace.o
nfs-$(CONFIG_NFS_DIRECTIO) += direct.o
nfs-$(CONFIG_SYSCTL) += sysctl.o
-nfs-objs := $(nfs-y)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index a204484072f..70587f383f1 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -23,6 +23,8 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/metrics.h>
+#include <linux/sunrpc/xprtsock.h>
+#include <linux/sunrpc/xprtrdma.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
@@ -340,7 +342,8 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
to->to_retries = 2;
switch (proto) {
- case IPPROTO_TCP:
+ case XPRT_TRANSPORT_TCP:
+ case XPRT_TRANSPORT_RDMA:
if (!to->to_initval)
to->to_initval = 60 * HZ;
if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
@@ -349,7 +352,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
to->to_exponential = 0;
break;
- case IPPROTO_UDP:
+ case XPRT_TRANSPORT_UDP:
default:
if (!to->to_initval)
to->to_initval = 11 * HZ / 10;
@@ -501,9 +504,9 @@ static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t
/*
* Initialise an NFS2 or NFS3 client
*/
-static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *data)
+static int nfs_init_client(struct nfs_client *clp,
+ const struct nfs_parsed_mount_data *data)
{
- int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
int error;
if (clp->cl_cons_state == NFS_CS_READY) {
@@ -522,8 +525,8 @@ static int nfs_init_client(struct nfs_client *clp, const struct nfs_mount_data *
* Create a client RPC handle for doing FSSTAT with UNIX auth only
* - RFC 2623, sec 2.3.2
*/
- error = nfs_create_rpc_client(clp, proto, data->timeo, data->retrans,
- RPC_AUTH_UNIX, 0);
+ error = nfs_create_rpc_client(clp, data->nfs_server.protocol,
+ data->timeo, data->retrans, RPC_AUTH_UNIX, 0);
if (error < 0)
goto error;
nfs_mark_client_ready(clp, NFS_CS_READY);
@@ -538,7 +541,8 @@ error:
/*
* Create a version 2 or 3 client
*/
-static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_data *data)
+static int nfs_init_server(struct nfs_server *server,
+ const struct nfs_parsed_mount_data *data)
{
struct nfs_client *clp;
int error, nfsvers = 2;
@@ -551,7 +555,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
#endif
/* Allocate or find a client reference we can use */
- clp = nfs_get_client(data->hostname, &data->addr, nfsvers);
+ clp = nfs_get_client(data->nfs_server.hostname,
+ &data->nfs_server.address, nfsvers);
if (IS_ERR(clp)) {
dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));
return PTR_ERR(clp);
@@ -581,7 +586,7 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
if (error < 0)
goto error;
- error = nfs_init_server_rpcclient(server, data->pseudoflavor);
+ error = nfs_init_server_rpcclient(server, data->auth_flavors[0]);
if (error < 0)
goto error;
@@ -622,6 +627,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
if (server->rsize > NFS_MAX_FILE_IO_SIZE)
server->rsize = NFS_MAX_FILE_IO_SIZE;
server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
if (server->wsize > max_rpc_payload)
@@ -672,6 +678,10 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
goto out_error;
nfs_server_set_fsinfo(server, &fsinfo);
+ error = bdi_init(&server->backing_dev_info);
+ if (error)
+ goto out_error;
+
/* Get some general file system info */
if (server->namelen == 0) {
@@ -751,6 +761,7 @@ void nfs_free_server(struct nfs_server *server)
nfs_put_client(server->nfs_client);
nfs_free_iostats(server->io_stats);
+ bdi_destroy(&server->backing_dev_info);
kfree(server);
nfs_release_automount_timer();
dprintk("<-- nfs_free_server()\n");
@@ -760,7 +771,7 @@ void nfs_free_server(struct nfs_server *server)
* Create a version 2 or 3 volume record
* - keyed on server and FSID
*/
-struct nfs_server *nfs_create_server(const struct nfs_mount_data *data,
+struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
struct nfs_fh *mntfh)
{
struct nfs_server *server;
@@ -906,7 +917,7 @@ error:
* Create a version 4 volume record
*/
static int nfs4_init_server(struct nfs_server *server,
- const struct nfs4_mount_data *data, rpc_authflavor_t authflavour)
+ const struct nfs_parsed_mount_data *data)
{
int error;
@@ -926,7 +937,7 @@ static int nfs4_init_server(struct nfs_server *server,
server->acdirmin = data->acdirmin * HZ;
server->acdirmax = data->acdirmax * HZ;
- error = nfs_init_server_rpcclient(server, authflavour);
+ error = nfs_init_server_rpcclient(server, data->auth_flavors[0]);
/* Done */
dprintk("<-- nfs4_init_server() = %d\n", error);
@@ -937,12 +948,7 @@ static int nfs4_init_server(struct nfs_server *server,
* Create a version 4 volume record
* - keyed on server and FSID
*/
-struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
- const char *hostname,
- const struct sockaddr_in *addr,
- const char *mntpath,
- const char *ip_addr,
- rpc_authflavor_t authflavour,
+struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
struct nfs_fh *mntfh)
{
struct nfs_fattr fattr;
@@ -956,13 +962,18 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
return ERR_PTR(-ENOMEM);
/* Get a client record */
- error = nfs4_set_client(server, hostname, addr, ip_addr, authflavour,
- data->proto, data->timeo, data->retrans);
+ error = nfs4_set_client(server,
+ data->nfs_server.hostname,
+ &data->nfs_server.address,
+ data->client_address,
+ data->auth_flavors[0],
+ data->nfs_server.protocol,
+ data->timeo, data->retrans);
if (error < 0)
goto error;
/* set up the general RPC client */
- error = nfs4_init_server(server, data, authflavour);
+ error = nfs4_init_server(server, data);
if (error < 0)
goto error;
@@ -971,7 +982,7 @@ struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *data,
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
/* Probe the root fh to retrieve its FSID */
- error = nfs4_path_walk(server, mntfh, mntpath);
+ error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
if (error < 0)
goto error;
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index c55a761c22b..af8b235d405 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -52,7 +52,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue;
- if ((struct nfs_open_context *)fl->fl_file->private_data != ctx)
+ if (nfs_file_open_context(fl->fl_file) != ctx)
continue;
status = nfs4_lock_delegation_recall(state, fl);
if (status >= 0)
@@ -109,6 +109,7 @@ again:
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
{
struct nfs_delegation *delegation = NFS_I(inode)->delegation;
+ struct rpc_cred *oldcred;
if (delegation == NULL)
return;
@@ -116,11 +117,12 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, st
sizeof(delegation->stateid.data));
delegation->type = res->delegation_type;
delegation->maxsize = res->maxsize;
- put_rpccred(cred);
+ oldcred = delegation->cred;
delegation->cred = get_rpccred(cred);
delegation->flags &= ~NFS_DELEGATION_NEED_RECLAIM;
NFS_I(inode)->delegation_state = delegation->type;
smp_wmb();
+ put_rpccred(oldcred);
}
/*
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e4a04d16b8b..8ec7fbd8240 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -200,9 +200,6 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
desc->timestamp = timestamp;
desc->timestamp_valid = 1;
SetPageUptodate(page);
- spin_lock(&inode->i_lock);
- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
- spin_unlock(&inode->i_lock);
/* Ensure consistent page alignment of the data.
* Note: assumes we have exclusive access to this mapping either
* through inode->i_mutex or some other mechanism.
@@ -214,9 +211,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
unlock_page(page);
return 0;
error:
- SetPageError(page);
unlock_page(page);
- nfs_zap_caches(inode);
desc->error = error;
return -EIO;
}
@@ -407,7 +402,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
struct file *file = desc->file;
struct nfs_entry *entry = desc->entry;
struct dentry *dentry = NULL;
- unsigned long fileid;
+ u64 fileid;
int loop_count = 0,
res;
@@ -418,7 +413,7 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
unsigned d_type = DT_UNKNOWN;
/* Note: entry->prev_cookie contains the cookie for
* retrieving the current dirent on the server */
- fileid = nfs_fileid_to_ino_t(entry->ino);
+ fileid = entry->ino;
/* Get a dentry if we have one */
if (dentry != NULL)
@@ -428,11 +423,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
/* Use readdirplus info */
if (dentry != NULL && dentry->d_inode != NULL) {
d_type = dt_type(dentry->d_inode);
- fileid = dentry->d_inode->i_ino;
+ fileid = NFS_FILEID(dentry->d_inode);
}
res = filldir(dirent, entry->name, entry->len,
- file->f_pos, fileid, d_type);
+ file->f_pos, nfs_compat_user_ino64(fileid),
+ d_type);
if (res < 0)
break;
file->f_pos++;
@@ -490,9 +486,6 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
page,
NFS_SERVER(inode)->dtsize,
desc->plus);
- spin_lock(&inode->i_lock);
- NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
- spin_unlock(&inode->i_lock);
desc->page = page;
desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
if (desc->error >= 0) {
@@ -558,7 +551,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
memset(desc, 0, sizeof(*desc));
desc->file = filp;
- desc->dir_cookie = &((struct nfs_open_context *)filp->private_data)->dir_cookie;
+ desc->dir_cookie = &nfs_file_open_context(filp)->dir_cookie;
desc->decode = NFS_PROTO(inode)->decode_dirent;
desc->plus = NFS_USE_READDIRPLUS(inode);
@@ -623,7 +616,7 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
}
if (offset != filp->f_pos) {
filp->f_pos = offset;
- ((struct nfs_open_context *)filp->private_data)->dir_cookie = 0;
+ nfs_file_open_context(filp)->dir_cookie = 0;
}
out:
mutex_unlock(&filp->f_path.dentry->d_inode->i_mutex);
@@ -650,36 +643,18 @@ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
*/
static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
{
- unsigned long verf;
-
if (IS_ROOT(dentry))
return 1;
- verf = dentry->d_time;
- if (nfs_caches_unstable(dir)
- || verf != NFS_I(dir)->cache_change_attribute)
+ if (!nfs_verify_change_attribute(dir, dentry->d_time))
+ return 0;
+ /* Revalidate nfsi->cache_change_attribute before we declare a match */
+ if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
+ return 0;
+ if (!nfs_verify_change_attribute(dir, dentry->d_time))
return 0;
return 1;
}
-static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
-{
- dentry->d_time = verf;
-}
-
-static void nfs_refresh_verifier(struct dentry * dentry, unsigned long verf)
-{
- nfs_set_verifier(dentry, verf);
-}
-
-/*
- * Whenever an NFS operation succeeds, we know that the dentry
- * is valid, so we update the revalidation timestamp.
- */
-static inline void nfs_renew_times(struct dentry * dentry)
-{
- dentry->d_time = jiffies;
-}
-
/*
* Return the intent data that applies to this particular path component
*
@@ -695,6 +670,19 @@ static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigne
}
/*
+ * Use intent information to check whether or not we're going to do
+ * an O_EXCL create using this path component.
+ */
+static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
+{
+ if (NFS_PROTO(dir)->version == 2)
+ return 0;
+ if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
+ return 0;
+ return (nd->intent.open.flags & O_EXCL) != 0;
+}
+
+/*
* Inode and filehandle revalidation for lookups.
*
* We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
@@ -717,6 +705,7 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
(S_ISREG(inode->i_mode) ||
S_ISDIR(inode->i_mode)))
goto out_force;
+ return 0;
}
return nfs_revalidate_inode(server, inode);
out_force:
@@ -759,7 +748,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
int error;
struct nfs_fh fhandle;
struct nfs_fattr fattr;
- unsigned long verifier;
parent = dget_parent(dentry);
lock_kernel();
@@ -767,10 +755,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE);
inode = dentry->d_inode;
- /* Revalidate parent directory attribute cache */
- if (nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
- goto out_zap_parent;
-
if (!inode) {
if (nfs_neg_need_reval(dir, dentry, nd))
goto out_bad;
@@ -785,7 +769,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
}
/* Force a full look up iff the parent directory has changed */
- if (nfs_check_verifier(dir, dentry)) {
+ if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) {
if (nfs_lookup_verify_inode(inode, nd))
goto out_zap_parent;
goto out_valid;
@@ -794,7 +778,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
if (NFS_STALE(inode))
goto out_bad;
- verifier = nfs_save_change_attribute(dir);
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
if (error)
goto out_bad;
@@ -803,8 +786,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
goto out_bad;
- nfs_renew_times(dentry);
- nfs_refresh_verifier(dentry, verifier);
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_valid:
unlock_kernel();
dput(parent);
@@ -815,7 +797,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
out_zap_parent:
nfs_zap_caches(dir);
out_bad:
- NFS_CACHEINV(dir);
+ nfs_mark_for_revalidate(dir);
if (inode && S_ISDIR(inode->i_mode)) {
/* Purge readdir caches. */
nfs_zap_caches(inode);
@@ -872,8 +854,6 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
nfs_complete_unlink(dentry, inode);
unlock_kernel();
}
- /* When creating a negative dentry, we want to renew d_time */
- nfs_renew_times(dentry);
iput(inode);
}
@@ -883,30 +863,6 @@ struct dentry_operations nfs_dentry_operations = {
.d_iput = nfs_dentry_iput,
};
-/*
- * Use intent information to check whether or not we're going to do
- * an O_EXCL create using this path component.
- */
-static inline
-int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
-{
- if (NFS_PROTO(dir)->version == 2)
- return 0;
- if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
- return 0;
- return (nd->intent.open.flags & O_EXCL) != 0;
-}
-
-static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr)
-{
- struct nfs_server *server = NFS_SERVER(dir);
-
- if (!nfs_fsid_equal(&server->fsid, &fattr->fsid))
- /* Revalidate fsid using the parent directory */
- return __nfs_revalidate_inode(server, dir);
- return 0;
-}
-
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
struct dentry *res;
@@ -945,11 +901,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
res = ERR_PTR(error);
goto out_unlock;
}
- error = nfs_reval_fsid(dir, &fattr);
- if (error < 0) {
- res = ERR_PTR(error);
- goto out_unlock;
- }
inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
res = (struct dentry *)inode;
if (IS_ERR(res))
@@ -958,17 +909,10 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
no_entry:
res = d_materialise_unique(dentry, inode);
if (res != NULL) {
- struct dentry *parent;
if (IS_ERR(res))
goto out_unlock;
- /* Was a directory renamed! */
- parent = dget_parent(res);
- if (!IS_ROOT(parent))
- nfs_mark_for_revalidate(parent->d_inode);
- dput(parent);
dentry = res;
}
- nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_unlock:
unlock_kernel();
@@ -1020,28 +964,16 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
}
dentry->d_op = NFS_PROTO(dir)->dentry_ops;
- /* Let vfs_create() deal with O_EXCL */
+ /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash
+ * the dentry. */
if (nd->intent.open.flags & O_EXCL) {
- d_add(dentry, NULL);
+ d_instantiate(dentry, NULL);
goto out;
}
/* Open the file on the server */
lock_kernel();
- /* Revalidate parent directory attribute cache */
- error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
- if (error < 0) {
- res = ERR_PTR(error);
- unlock_kernel();
- goto out;
- }
-
- if (nd->intent.open.flags & O_CREAT) {
- nfs_begin_data_update(dir);
- res = nfs4_atomic_open(dir, dentry, nd);
- nfs_end_data_update(dir);
- } else
- res = nfs4_atomic_open(dir, dentry, nd);
+ res = nfs4_atomic_open(dir, dentry, nd);
unlock_kernel();
if (IS_ERR(res)) {
error = PTR_ERR(res);
@@ -1063,8 +995,6 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
}
} else if (res != NULL)
dentry = res;
- nfs_renew_times(dentry);
- nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out:
return res;
no_open:
@@ -1076,7 +1006,6 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
struct dentry *parent = NULL;
struct inode *inode = dentry->d_inode;
struct inode *dir;
- unsigned long verifier;
int openflags, ret = 0;
parent = dget_parent(dentry);
@@ -1086,8 +1015,12 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
/* We can't create new files in nfs_open_revalidate(), so we
* optimize away revalidation of negative dentries.
*/
- if (inode == NULL)
+ if (inode == NULL) {
+ if (!nfs_neg_need_reval(dir, dentry, nd))
+ ret = 1;
goto out;
+ }
+
/* NFS only supports OPEN on regular files */
if (!S_ISREG(inode->i_mode))
goto no_open;
@@ -1104,10 +1037,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
* change attribute *before* we do the RPC call.
*/
lock_kernel();
- verifier = nfs_save_change_attribute(dir);
ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
- if (!ret)
- nfs_refresh_verifier(dentry, verifier);
unlock_kernel();
out:
dput(parent);
@@ -1133,6 +1063,7 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
.len = entry->len,
};
struct inode *inode;
+ unsigned long verf = nfs_save_change_attribute(dir);
switch (name.len) {
case 2:
@@ -1143,6 +1074,14 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
if (name.name[0] == '.')
return dget(parent);
}
+
+ spin_lock(&dir->i_lock);
+ if (NFS_I(dir)->cache_validity & NFS_INO_INVALID_DATA) {
+ spin_unlock(&dir->i_lock);
+ return NULL;
+ }
+ spin_unlock(&dir->i_lock);
+
name.hash = full_name_hash(name.name, name.len);
dentry = d_lookup(parent, &name);
if (dentry != NULL) {
@@ -1183,12 +1122,8 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
dentry = alias;
}
- nfs_renew_times(dentry);
- nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
- return dentry;
out_renew:
- nfs_renew_times(dentry);
- nfs_refresh_verifier(dentry, nfs_save_change_attribute(dir));
+ nfs_set_verifier(dentry, verf);
return dentry;
}
@@ -1198,32 +1133,40 @@ out_renew:
int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
struct nfs_fattr *fattr)
{
+ struct dentry *parent = dget_parent(dentry);
+ struct inode *dir = parent->d_inode;
struct inode *inode;
int error = -EACCES;
+ d_drop(dentry);
+
/* We may have been initialized further down */
if (dentry->d_inode)
- return 0;
+ goto out;
if (fhandle->size == 0) {
- struct inode *dir = dentry->d_parent->d_inode;
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
if (error)
- return error;
+ goto out_error;
}
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
if (!(fattr->valid & NFS_ATTR_FATTR)) {
struct nfs_server *server = NFS_SB(dentry->d_sb);
error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr);
if (error < 0)
- return error;
+ goto out_error;
}
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
error = PTR_ERR(inode);
if (IS_ERR(inode))
- return error;
- d_instantiate(dentry, inode);
- if (d_unhashed(dentry))
- d_rehash(dentry);
+ goto out_error;
+ d_add(dentry, inode);
+out:
+ dput(parent);
return 0;
+out_error:
+ nfs_mark_for_revalidate(dir);
+ dput(parent);
+ return error;
}
/*
@@ -1249,13 +1192,9 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
open_flags = nd->intent.open.flags;
lock_kernel();
- nfs_begin_data_update(dir);
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
- nfs_end_data_update(dir);
if (error != 0)
goto out_err;
- nfs_renew_times(dentry);
- nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return 0;
out_err:
@@ -1283,13 +1222,9 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
attr.ia_valid = ATTR_MODE;
lock_kernel();
- nfs_begin_data_update(dir);
status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
- nfs_end_data_update(dir);
if (status != 0)
goto out_err;
- nfs_renew_times(dentry);
- nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return 0;
out_err:
@@ -1313,13 +1248,9 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
attr.ia_mode = mode | S_IFDIR;
lock_kernel();
- nfs_begin_data_update(dir);
error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
- nfs_end_data_update(dir);
if (error != 0)
goto out_err;
- nfs_renew_times(dentry);
- nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return 0;
out_err:
@@ -1336,12 +1267,10 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
lock_kernel();
- nfs_begin_data_update(dir);
error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
/* Ensure the VFS deletes this inode */
if (error == 0 && dentry->d_inode != NULL)
clear_nlink(dentry->d_inode);
- nfs_end_data_update(dir);
unlock_kernel();
return error;
@@ -1350,9 +1279,9 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
{
static unsigned int sillycounter;
- const int i_inosize = sizeof(dir->i_ino)*2;
+ const int fileidsize = sizeof(NFS_FILEID(dentry->d_inode))*2;
const int countersize = sizeof(sillycounter)*2;
- const int slen = sizeof(".nfs") + i_inosize + countersize - 1;
+ const int slen = sizeof(".nfs")+fileidsize+countersize-1;
char silly[slen+1];
struct qstr qsilly;
struct dentry *sdentry;
@@ -1370,8 +1299,9 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
goto out;
- sprintf(silly, ".nfs%*.*lx",
- i_inosize, i_inosize, dentry->d_inode->i_ino);
+ sprintf(silly, ".nfs%*.*Lx",
+ fileidsize, fileidsize,
+ (unsigned long long)NFS_FILEID(dentry->d_inode));
/* Return delegation in anticipation of the rename */
nfs_inode_return_delegation(dentry->d_inode);
@@ -1398,19 +1328,14 @@ static int nfs_sillyrename(struct inode *dir, struct dentry *dentry)
qsilly.name = silly;
qsilly.len = strlen(silly);
- nfs_begin_data_update(dir);
if (dentry->d_inode) {
- nfs_begin_data_update(dentry->d_inode);
error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
dir, &qsilly);
nfs_mark_for_revalidate(dentry->d_inode);
- nfs_end_data_update(dentry->d_inode);
} else
error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
dir, &qsilly);
- nfs_end_data_update(dir);
if (!error) {
- nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
d_move(dentry, sdentry);
error = nfs_async_unlink(dir, dentry);
@@ -1443,19 +1368,15 @@ static int nfs_safe_remove(struct dentry *dentry)
goto out;
}
- nfs_begin_data_update(dir);
if (inode != NULL) {
nfs_inode_return_delegation(inode);
- nfs_begin_data_update(inode);
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
/* The VFS may want to delete this inode */
if (error == 0)
drop_nlink(inode);
nfs_mark_for_revalidate(inode);
- nfs_end_data_update(inode);
} else
error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
- nfs_end_data_update(dir);
out:
return error;
}
@@ -1493,7 +1414,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
spin_unlock(&dcache_lock);
error = nfs_safe_remove(dentry);
if (!error) {
- nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
} else if (need_rehash)
d_rehash(dentry);
@@ -1548,9 +1468,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
kunmap_atomic(kaddr, KM_USER0);
- nfs_begin_data_update(dir);
error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
- nfs_end_data_update(dir);
if (error != 0) {
dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s) error %d\n",
dir->i_sb->s_id, dir->i_ino,
@@ -1590,15 +1508,12 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
dentry->d_parent->d_name.name, dentry->d_name.name);
lock_kernel();
- nfs_begin_data_update(dir);
- nfs_begin_data_update(inode);
+ d_drop(dentry);
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
if (error == 0) {
atomic_inc(&inode->i_count);
- d_instantiate(dentry, inode);
+ d_add(dentry, inode);
}
- nfs_end_data_update(inode);
- nfs_end_data_update(dir);
unlock_kernel();
return error;
}
@@ -1701,22 +1616,16 @@ go_ahead:
d_delete(new_dentry);
}
- nfs_begin_data_update(old_dir);
- nfs_begin_data_update(new_dir);
- nfs_begin_data_update(old_inode);
error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
new_dir, &new_dentry->d_name);
nfs_mark_for_revalidate(old_inode);
- nfs_end_data_update(old_inode);
- nfs_end_data_update(new_dir);
- nfs_end_data_update(old_dir);
out:
if (rehash)
d_rehash(rehash);
if (!error) {
d_move(old_dentry, new_dentry);
- nfs_renew_times(new_dentry);
- nfs_refresh_verifier(new_dentry, nfs_save_change_attribute(new_dir));
+ nfs_set_verifier(new_dentry,
+ nfs_save_change_attribute(new_dir));
}
/* new dentry created? */
@@ -1842,7 +1751,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, st
return NULL;
}
-int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
+static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
{
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_access_entry *cache;
@@ -1854,7 +1763,7 @@ int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs
cache = nfs_access_search_rbtree(inode, cred);
if (cache == NULL)
goto out;
- if (time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)))
+ if (!time_in_range(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
goto out_stale;
res->jiffies = cache->jiffies;
res->cred = cache->cred;
@@ -1909,7 +1818,7 @@ found:
nfs_access_free_entry(entry);
}
-void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
+static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
{
struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
if (cache == NULL)
@@ -1957,6 +1866,24 @@ out:
return -EACCES;
}
+static int nfs_open_permission_mask(int openflags)
+{
+ int mask = 0;
+
+ if (openflags & FMODE_READ)
+ mask |= MAY_READ;
+ if (openflags & FMODE_WRITE)
+ mask |= MAY_WRITE;
+ if (openflags & FMODE_EXEC)
+ mask |= MAY_EXEC;
+ return mask;
+}
+
+int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
+{
+ return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
+}
+
int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct rpc_cred *cred;
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index fcf4d384610..32fe97211ee 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -368,7 +368,7 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size
return -ENOMEM;
dreq->inode = inode;
- dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data);
+ dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
if (!is_sync_kiocb(iocb))
dreq->iocb = iocb;
@@ -510,7 +510,6 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
nfs_direct_write_reschedule(dreq);
break;
default:
- nfs_end_data_update(inode);
if (dreq->commit_data != NULL)
nfs_commit_free(dreq->commit_data);
nfs_direct_free_writedata(dreq);
@@ -533,7 +532,6 @@ static inline void nfs_alloc_commit_data(struct nfs_direct_req *dreq)
static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
{
- nfs_end_data_update(inode);
nfs_direct_free_writedata(dreq);
nfs_zap_mapping(inode, inode->i_mapping);
nfs_direct_complete(dreq);
@@ -718,14 +716,12 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
sync = FLUSH_STABLE;
dreq->inode = inode;
- dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data);
+ dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
if (!is_sync_kiocb(iocb))
dreq->iocb = iocb;
nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, count);
- nfs_begin_data_update(inode);
-
rpc_clnt_sigmask(clnt, &oldset);
result = nfs_direct_write_schedule(dreq, user_addr, count, pos, sync);
if (!result)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 579cf8a7d4a..d29f90d00aa 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -33,6 +33,7 @@
#include <asm/system.h>
#include "delegation.h"
+#include "internal.h"
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_FILE
@@ -55,6 +56,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
+static struct vm_operations_struct nfs_file_vm_ops;
+
const struct file_operations nfs_file_operations = {
.llseek = nfs_file_llseek,
.read = do_sync_read,
@@ -174,13 +177,38 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
}
/*
+ * Helper for nfs_file_flush() and nfs_fsync()
+ *
+ * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to
+ * disk, but it retrieves and clears ctx->error after synching, despite
+ * the two being set at the same time in nfs_context_set_write_error().
+ * This is because the former is used to notify the _next_ call to
+ * nfs_file_write() that a write error occured, and hence cause it to
+ * fall back to doing a synchronous write.
+ */
+static int nfs_do_fsync(struct nfs_open_context *ctx, struct inode *inode)
+{
+ int have_error, status;
+ int ret = 0;
+
+ have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
+ status = nfs_wb_all(inode);
+ have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
+ if (have_error)
+ ret = xchg(&ctx->error, 0);
+ if (!ret)
+ ret = status;
+ return ret;
+}
+
+/*
* Flush all dirty pages, and check for write errors.
*
*/
static int
nfs_file_flush(struct file *file, fl_owner_t id)
{
- struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
+ struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = file->f_path.dentry->d_inode;
int status;
@@ -189,16 +217,11 @@ nfs_file_flush(struct file *file, fl_owner_t id)
if ((file->f_mode & FMODE_WRITE) == 0)
return 0;
nfs_inc_stats(inode, NFSIOS_VFSFLUSH);
- lock_kernel();
+
/* Ensure that data+attribute caches are up to date after close() */
- status = nfs_wb_all(inode);
- if (!status) {
- status = ctx->error;
- ctx->error = 0;
- if (!status)
- nfs_revalidate_inode(NFS_SERVER(inode), inode);
- }
- unlock_kernel();
+ status = nfs_do_fsync(ctx, inode);
+ if (!status)
+ nfs_revalidate_inode(NFS_SERVER(inode), inode);
return status;
}
@@ -257,8 +280,11 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
dentry->d_parent->d_name.name, dentry->d_name.name);
status = nfs_revalidate_mapping(inode, file->f_mapping);
- if (!status)
- status = generic_file_mmap(file, vma);
+ if (!status) {
+ vma->vm_ops = &nfs_file_vm_ops;
+ vma->vm_flags |= VM_CAN_NONLINEAR;
+ file_accessed(file);
+ }
return status;
}
@@ -270,45 +296,60 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
static int
nfs_fsync(struct file *file, struct dentry *dentry, int datasync)
{
- struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
+ struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = dentry->d_inode;
- int status;
dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino);
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
- lock_kernel();
- status = nfs_wb_all(inode);
- if (!status) {
- status = ctx->error;
- ctx->error = 0;
- }
- unlock_kernel();
- return status;
+ return nfs_do_fsync(ctx, inode);
}
/*
- * This does the "real" work of the write. The generic routine has
- * allocated the page, locked it, done all the page alignment stuff
- * calculations etc. Now we should just copy the data from user
- * space and write it back to the real medium..
+ * This does the "real" work of the write. We must allocate and lock the
+ * page to be sent back to the generic routine, which then copies the
+ * data from user space.
*
* If the writer ends up delaying the write, the writer needs to
* increment the page use counts until he is done with the page.
*/
-static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int nfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return nfs_flush_incompatible(file, page);
+ int ret;
+ pgoff_t index;
+ struct page *page;
+ index = pos >> PAGE_CACHE_SHIFT;
+
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
+ ret = nfs_flush_incompatible(file, page);
+ if (ret) {
+ unlock_page(page);
+ page_cache_release(page);
+ }
+ return ret;
}
-static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+static int nfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- long status;
+ unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+ int status;
lock_kernel();
- status = nfs_updatepage(file, page, offset, to-offset);
+ status = nfs_updatepage(file, page, offset, copied);
unlock_kernel();
- return status;
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ return status < 0 ? status : copied;
}
static void nfs_invalidate_page(struct page *page, unsigned long offset)
@@ -333,11 +374,11 @@ static int nfs_launder_page(struct page *page)
const struct address_space_operations nfs_file_aops = {
.readpage = nfs_readpage,
.readpages = nfs_readpages,
- .set_page_dirty = nfs_set_page_dirty,
+ .set_page_dirty = __set_page_dirty_nobuffers,
.writepage = nfs_writepage,
.writepages = nfs_writepages,
- .prepare_write = nfs_prepare_write,
- .commit_write = nfs_commit_write,
+ .write_begin = nfs_write_begin,
+ .write_end = nfs_write_end,
.invalidatepage = nfs_invalidate_page,
.releasepage = nfs_release_page,
#ifdef CONFIG_NFS_DIRECTIO
@@ -346,6 +387,60 @@ const struct address_space_operations nfs_file_aops = {
.launder_page = nfs_launder_page,
};
+static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+{
+ struct file *filp = vma->vm_file;
+ unsigned pagelen;
+ int ret = -EINVAL;
+ void *fsdata;
+ struct address_space *mapping;
+ loff_t offset;
+
+ lock_page(page);
+ mapping = page->mapping;
+ if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) {
+ unlock_page(page);
+ return -EINVAL;
+ }
+ pagelen = nfs_page_length(page);
+ offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+ unlock_page(page);
+
+ /*
+ * we can use mapping after releasing the page lock, because:
+ * we hold mmap_sem on the fault path, which should pin the vma
+ * which should pin the file, which pins the dentry which should
+ * hold a reference on inode.
+ */
+
+ if (pagelen) {
+ struct page *page2 = NULL;
+ ret = nfs_write_begin(filp, mapping, offset, pagelen,
+ 0, &page2, &fsdata);
+ if (!ret)
+ ret = nfs_write_end(filp, mapping, offset, pagelen,
+ pagelen, page2, fsdata);
+ }
+ return ret;
+}
+
+static struct vm_operations_struct nfs_file_vm_ops = {
+ .fault = filemap_fault,
+ .page_mkwrite = nfs_vm_page_mkwrite,
+};
+
+static int nfs_need_sync_write(struct file *filp, struct inode *inode)
+{
+ struct nfs_open_context *ctx;
+
+ if (IS_SYNC(inode) || (filp->f_flags & O_SYNC))
+ return 1;
+ ctx = nfs_file_open_context(filp);
+ if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags))
+ return 1;
+ return 0;
+}
+
static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
@@ -382,8 +477,8 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
result = generic_file_aio_write(iocb, iov, nr_segs, pos);
/* Return error values for O_SYNC and IS_SYNC() */
- if (result >= 0 && (IS_SYNC(inode) || (iocb->ki_filp->f_flags & O_SYNC))) {
- int err = nfs_fsync(iocb->ki_filp, dentry, 1);
+ if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
+ int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
if (err < 0)
result = err;
}
@@ -522,8 +617,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
nfs_inc_stats(inode, NFSIOS_VFSLOCK);
/* No mandatory locks over NFS */
- if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
- fl->fl_type != F_UNLCK)
+ if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
if (IS_GETLK(cmd))
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 71a49c3acab..6d2f2a3eccf 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -49,6 +49,11 @@
#define NFSDBG_FACILITY NFSDBG_VFS
+#define NFS_64_BIT_INODE_NUMBERS_ENABLED 1
+
+/* Default is to see 64-bit inode numbers */
+static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
+
static void nfs_invalidate_inode(struct inode *);
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
@@ -62,6 +67,25 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
return nfs_fileid_to_ino_t(fattr->fileid);
}
+/**
+ * nfs_compat_user_ino64 - returns the user-visible inode number
+ * @fileid: 64-bit fileid
+ *
+ * This function returns a 32-bit inode number if the boot parameter
+ * nfs.enable_ino64 is zero.
+ */
+u64 nfs_compat_user_ino64(u64 fileid)
+{
+ int ino;
+
+ if (enable_ino64)
+ return fileid;
+ ino = fileid;
+ if (sizeof(ino) < sizeof(fileid))
+ ino ^= fileid >> (sizeof(fileid)-sizeof(ino)) * 8;
+ return ino;
+}
+
int nfs_write_inode(struct inode *inode, int sync)
{
int ret;
@@ -85,7 +109,6 @@ void nfs_clear_inode(struct inode *inode)
*/
BUG_ON(nfs_have_writebacks(inode));
BUG_ON(!list_empty(&NFS_I(inode)->open_files));
- BUG_ON(atomic_read(&NFS_I(inode)->data_updates) != 0);
nfs_zap_acl_cache(inode);
nfs_access_zap_cache(inode);
}
@@ -118,8 +141,8 @@ static void nfs_zap_caches_locked(struct inode *inode)
nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
- NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
- NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
+ nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
+ nfsi->attrtimeo_timestamp = jiffies;
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
@@ -156,6 +179,13 @@ static void nfs_zap_acl_cache(struct inode *inode)
spin_unlock(&inode->i_lock);
}
+void nfs_invalidate_atime(struct inode *inode)
+{
+ spin_lock(&inode->i_lock);
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+ spin_unlock(&inode->i_lock);
+}
+
/*
* Invalidate, but do not unhash, the inode.
* NB: must be called with inode->i_lock held!
@@ -327,6 +357,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
+ /* skip mode change if it's just for clearing setuid/setgid */
+ if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+ attr->ia_valid &= ~ATTR_MODE;
+
if (attr->ia_valid & ATTR_SIZE) {
if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode))
attr->ia_valid &= ~ATTR_SIZE;
@@ -338,7 +372,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
return 0;
lock_kernel();
- nfs_begin_data_update(inode);
/* Write all dirty data */
if (S_ISREG(inode->i_mode)) {
filemap_write_and_wait(inode->i_mapping);
@@ -352,7 +385,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
if (error == 0)
nfs_refresh_inode(inode, &fattr);
- nfs_end_data_update(inode);
unlock_kernel();
return error;
}
@@ -431,7 +463,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
/* Flush out writes to the server in order to update c/mtime */
if (S_ISREG(inode->i_mode))
- nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT);
+ nfs_wb_nocommit(inode);
/*
* We may force a getattr if the user cares about atime.
@@ -450,8 +482,10 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
else
err = nfs_revalidate_inode(NFS_SERVER(inode), inode);
- if (!err)
+ if (!err) {
generic_fillattr(inode, stat);
+ stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
+ }
return err;
}
@@ -536,7 +570,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
static void nfs_file_clear_open_context(struct file *filp)
{
struct inode *inode = filp->f_path.dentry->d_inode;
- struct nfs_open_context *ctx = (struct nfs_open_context *)filp->private_data;
+ struct nfs_open_context *ctx = nfs_file_open_context(filp);
if (ctx) {
filp->private_data = NULL;
@@ -598,16 +632,10 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
status = nfs_wait_on_inode(inode);
if (status < 0)
goto out;
- if (NFS_STALE(inode)) {
- status = -ESTALE;
- /* Do we trust the cached ESTALE? */
- if (NFS_ATTRTIMEO(inode) != 0) {
- if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME)) {
- /* no */
- } else
- goto out;
- }
- }
+
+ status = -ESTALE;
+ if (NFS_STALE(inode))
+ goto out;
status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
if (status != 0) {
@@ -654,7 +682,7 @@ int nfs_attribute_timeout(struct inode *inode)
if (nfs_have_delegation(inode, FMODE_READ))
return 0;
- return time_after(jiffies, nfsi->read_cache_jiffies+nfsi->attrtimeo);
+ return !time_in_range(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
}
/**
@@ -683,11 +711,8 @@ static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_spa
}
spin_lock(&inode->i_lock);
nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
- if (S_ISDIR(inode->i_mode)) {
+ if (S_ISDIR(inode->i_mode))
memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
- /* This ensures we revalidate child dentries */
- nfsi->cache_change_attribute = jiffies;
- }
spin_unlock(&inode->i_lock);
nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
@@ -756,56 +781,27 @@ out:
return ret;
}
-/**
- * nfs_begin_data_update
- * @inode - pointer to inode
- * Declare that a set of operations will update file data on the server
- */
-void nfs_begin_data_update(struct inode *inode)
-{
- atomic_inc(&NFS_I(inode)->data_updates);
-}
-
-/**
- * nfs_end_data_update
- * @inode - pointer to inode
- * Declare end of the operations that will update file data
- * This will mark the inode as immediately needing revalidation
- * of its attribute cache.
- */
-void nfs_end_data_update(struct inode *inode)
-{
- struct nfs_inode *nfsi = NFS_I(inode);
-
- /* Directories: invalidate page cache */
- if (S_ISDIR(inode->i_mode)) {
- spin_lock(&inode->i_lock);
- nfsi->cache_validity |= NFS_INO_INVALID_DATA;
- spin_unlock(&inode->i_lock);
- }
- nfsi->cache_change_attribute = jiffies;
- atomic_dec(&nfsi->data_updates);
-}
-
static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
struct nfs_inode *nfsi = NFS_I(inode);
- unsigned long now = jiffies;
+ if ((fattr->valid & NFS_ATTR_WCC_V4) != 0 &&
+ nfsi->change_attr == fattr->pre_change_attr) {
+ nfsi->change_attr = fattr->change_attr;
+ if (S_ISDIR(inode->i_mode))
+ nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+ }
/* If we have atomic WCC data, we may update some attributes */
if ((fattr->valid & NFS_ATTR_WCC) != 0) {
- if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
+ if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime))
memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
- nfsi->cache_change_attribute = now;
- }
if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
- nfsi->cache_change_attribute = now;
+ if (S_ISDIR(inode->i_mode))
+ nfsi->cache_validity |= NFS_INO_INVALID_DATA;
}
- if (inode->i_size == fattr->pre_size && nfsi->npages == 0) {
+ if (inode->i_size == fattr->pre_size && nfsi->npages == 0)
inode->i_size = fattr->size;
- nfsi->cache_change_attribute = now;
- }
}
}
@@ -822,7 +818,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
{
struct nfs_inode *nfsi = NFS_I(inode);
loff_t cur_size, new_isize;
- int data_unstable;
+ unsigned long invalid = 0;
/* Has the inode gone and changed behind our back? */
@@ -831,37 +827,41 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
return -EIO;
}
- /* Are we in the process of updating data on the server? */
- data_unstable = nfs_caches_unstable(inode);
-
/* Do atomic weak cache consistency updates */
nfs_wcc_update_inode(inode, fattr);
if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
nfsi->change_attr != fattr->change_attr)
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
/* Verify a few of the more important attributes */
if (!timespec_equal(&inode->i_mtime, &fattr->mtime))
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
cur_size = i_size_read(inode);
new_isize = nfs_size_to_loff_t(fattr->size);
if (cur_size != new_isize && nfsi->npages == 0)
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
/* Have any file permissions changed? */
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
|| inode->i_uid != fattr->uid
|| inode->i_gid != fattr->gid)
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
+ invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
/* Has the link count changed? */
if (inode->i_nlink != fattr->nlink)
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+ invalid |= NFS_INO_INVALID_ATTR;
if (!timespec_equal(&inode->i_atime, &fattr->atime))
- nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
+ invalid |= NFS_INO_INVALID_ATIME;
+
+ if (invalid != 0)
+ nfsi->cache_validity |= invalid;
+ else
+ nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR
+ | NFS_INO_INVALID_ATIME
+ | NFS_INO_REVAL_PAGECACHE);
nfsi->read_cache_jiffies = fattr->time_start;
return 0;
@@ -911,17 +911,41 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
struct nfs_inode *nfsi = NFS_I(inode);
- int status = 0;
spin_lock(&inode->i_lock);
- if (unlikely((fattr->valid & NFS_ATTR_FATTR) == 0)) {
- nfsi->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
- goto out;
- }
- status = nfs_update_inode(inode, fattr);
-out:
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
+ if (S_ISDIR(inode->i_mode))
+ nfsi->cache_validity |= NFS_INO_INVALID_DATA;
spin_unlock(&inode->i_lock);
- return status;
+ return nfs_refresh_inode(inode, fattr);
+}
+
+/**
+ * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache
+ * @inode - pointer to inode
+ * @fattr - updated attributes
+ *
+ * After an operation that has changed the inode metadata, mark the
+ * attribute cache as being invalid, then try to update it. Fake up
+ * weak cache consistency data, if none exist.
+ *
+ * This function is mainly designed to be used by the ->write_done() functions.
+ */
+int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr)
+{
+ if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
+ (fattr->valid & NFS_ATTR_WCC_V4) == 0) {
+ fattr->pre_change_attr = NFS_I(inode)->change_attr;
+ fattr->valid |= NFS_ATTR_WCC_V4;
+ }
+ if ((fattr->valid & NFS_ATTR_FATTR) != 0 &&
+ (fattr->valid & NFS_ATTR_WCC) == 0) {
+ memcpy(&fattr->pre_ctime, &inode->i_ctime, sizeof(fattr->pre_ctime));
+ memcpy(&fattr->pre_mtime, &inode->i_mtime, sizeof(fattr->pre_mtime));
+ fattr->pre_size = inode->i_size;
+ fattr->valid |= NFS_ATTR_WCC;
+ }
+ return nfs_post_op_update_inode(inode, fattr);
}
/*
@@ -941,9 +965,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
struct nfs_server *server;
struct nfs_inode *nfsi = NFS_I(inode);
loff_t cur_isize, new_isize;
- unsigned int invalid = 0;
+ unsigned long invalid = 0;
unsigned long now = jiffies;
- int data_stable;
dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
__FUNCTION__, inode->i_sb->s_id, inode->i_ino,
@@ -968,57 +991,51 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
* Update the read time so we don't revalidate too often.
*/
nfsi->read_cache_jiffies = fattr->time_start;
- nfsi->last_updated = now;
- /* Fix a wraparound issue with nfsi->cache_change_attribute */
- if (time_before(now, nfsi->cache_change_attribute))
- nfsi->cache_change_attribute = now - 600*HZ;
-
- /* Are we racing with known updates of the metadata on the server? */
- data_stable = nfs_verify_change_attribute(inode, fattr->time_start);
- if (data_stable)
- nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATIME);
+ nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ATIME
+ | NFS_INO_REVAL_PAGECACHE);
/* Do atomic weak cache consistency updates */
nfs_wcc_update_inode(inode, fattr);
+ /* More cache consistency checks */
+ if (!(fattr->valid & NFS_ATTR_FATTR_V4)) {
+ /* NFSv2/v3: Check if the mtime agrees */
+ if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
+ dprintk("NFS: mtime change on server for file %s/%ld\n",
+ inode->i_sb->s_id, inode->i_ino);
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
+ nfsi->cache_change_attribute = now;
+ }
+ /* If ctime has changed we should definitely clear access+acl caches */
+ if (!timespec_equal(&inode->i_ctime, &fattr->ctime))
+ invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+ } else if (nfsi->change_attr != fattr->change_attr) {
+ dprintk("NFS: change_attr change on server for file %s/%ld\n",
+ inode->i_sb->s_id, inode->i_ino);
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+ nfsi->cache_change_attribute = now;
+ }
+
/* Check if our cached file size is stale */
new_isize = nfs_size_to_loff_t(fattr->size);
cur_isize = i_size_read(inode);
if (new_isize != cur_isize) {
- /* Do we perhaps have any outstanding writes? */
- if (nfsi->npages == 0) {
- /* No, but did we race with nfs_end_data_update()? */
- if (data_stable) {
- inode->i_size = new_isize;
- invalid |= NFS_INO_INVALID_DATA;
- }
- invalid |= NFS_INO_INVALID_ATTR;
- } else if (new_isize > cur_isize) {
+ /* Do we perhaps have any outstanding writes, or has
+ * the file grown beyond our last write? */
+ if (nfsi->npages == 0 || new_isize > cur_isize) {
inode->i_size = new_isize;
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
}
- nfsi->cache_change_attribute = now;
dprintk("NFS: isize change on server for file %s/%ld\n",
inode->i_sb->s_id, inode->i_ino);
}
- /* Check if the mtime agrees */
- if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
- memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
- dprintk("NFS: mtime change on server for file %s/%ld\n",
- inode->i_sb->s_id, inode->i_ino);
- invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
- nfsi->cache_change_attribute = now;
- }
- /* If ctime has changed we should definitely clear access+acl caches */
- if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
- invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
- memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
- nfsi->cache_change_attribute = now;
- }
+ memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
+ memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
+ nfsi->change_attr = fattr->change_attr;
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
inode->i_uid != fattr->uid ||
@@ -1039,31 +1056,29 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
inode->i_blocks = fattr->du.nfs2.blocks;
}
- if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
- nfsi->change_attr != fattr->change_attr) {
- dprintk("NFS: change_attr change on server for file %s/%ld\n",
- inode->i_sb->s_id, inode->i_ino);
- nfsi->change_attr = fattr->change_attr;
- invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
- nfsi->cache_change_attribute = now;
- }
-
/* Update attrtimeo value if we're out of the unstable period */
if (invalid & NFS_INO_INVALID_ATTR) {
nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
nfsi->attrtimeo_timestamp = now;
- } else if (time_after(now, nfsi->attrtimeo_timestamp+nfsi->attrtimeo)) {
- if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
- nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
- nfsi->attrtimeo_timestamp = now;
+ nfsi->last_updated = now;
+ } else {
+ if (!time_in_range(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
+ if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
+ nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
+ nfsi->attrtimeo_timestamp = now;
+ }
+ /*
+ * Avoid jiffy wraparound issues with nfsi->last_updated
+ */
+ if (!time_in_range(nfsi->last_updated, nfsi->read_cache_jiffies, now))
+ nfsi->last_updated = nfsi->read_cache_jiffies;
}
+ invalid &= ~NFS_INO_INVALID_ATTR;
/* Don't invalidate the data if we were to blame */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
|| S_ISLNK(inode->i_mode)))
invalid &= ~NFS_INO_INVALID_DATA;
- if (data_stable)
- invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
if (!nfs_have_delegation(inode, FMODE_READ) ||
(nfsi->cache_validity & NFS_INO_REVAL_FORCED))
nfsi->cache_validity |= invalid;
@@ -1143,7 +1158,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
#endif
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct nfs_inode *nfsi = (struct nfs_inode *) foo;
@@ -1152,7 +1167,6 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
INIT_LIST_HEAD(&nfsi->access_cache_entry_lru);
INIT_LIST_HEAD(&nfsi->access_cache_inode_lru);
INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
- atomic_set(&nfsi->data_updates, 0);
nfsi->ncommit = 0;
nfsi->npages = 0;
nfs4_init_once(nfsi);
@@ -1249,6 +1263,7 @@ static void __exit exit_nfs_fs(void)
/* Not quite true; I just maintain it */
MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
MODULE_LICENSE("GPL");
+module_param(enable_ino64, bool, 0644);
module_init(init_nfs_fs)
module_exit(exit_nfs_fs)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 76cf55d5710..f3acf48412b 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -5,8 +5,6 @@
#include <linux/mount.h>
struct nfs_string;
-struct nfs_mount_data;
-struct nfs4_mount_data;
/* Maximum number of readahead requests
* FIXME: this should really be a sysctl so that users may tune it to suit
@@ -27,20 +25,50 @@ struct nfs_clone_mount {
rpc_authflavor_t authflavor;
};
+/*
+ * In-kernel mount arguments
+ */
+struct nfs_parsed_mount_data {
+ int flags;
+ int rsize, wsize;
+ int timeo, retrans;
+ int acregmin, acregmax,
+ acdirmin, acdirmax;
+ int namlen;
+ unsigned int bsize;
+ unsigned int auth_flavor_len;
+ rpc_authflavor_t auth_flavors[1];
+ char *client_address;
+
+ struct {
+ struct sockaddr_in address;
+ char *hostname;
+ unsigned int program;
+ unsigned int version;
+ unsigned short port;
+ int protocol;
+ } mount_server;
+
+ struct {
+ struct sockaddr_in address;
+ char *hostname;
+ char *export_path;
+ unsigned int program;
+ int protocol;
+ } nfs_server;
+};
+
/* client.c */
extern struct rpc_program nfs_program;
extern void nfs_put_client(struct nfs_client *);
extern struct nfs_client *nfs_find_client(const struct sockaddr_in *, int);
-extern struct nfs_server *nfs_create_server(const struct nfs_mount_data *,
- struct nfs_fh *);
-extern struct nfs_server *nfs4_create_server(const struct nfs4_mount_data *,
- const char *,
- const struct sockaddr_in *,
- const char *,
- const char *,
- rpc_authflavor_t,
- struct nfs_fh *);
+extern struct nfs_server *nfs_create_server(
+ const struct nfs_parsed_mount_data *,
+ struct nfs_fh *);
+extern struct nfs_server *nfs4_create_server(
+ const struct nfs_parsed_mount_data *,
+ struct nfs_fh *);
extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
struct nfs_fh *);
extern void nfs_free_server(struct nfs_server *server);
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index c5fce756720..668ab96c7b5 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -251,6 +251,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
xdr_inline_pages(&req->rq_rcv_buf, replen,
args->pages, args->pgbase, count);
+ req->rq_rcv_buf.flags |= XDRBUF_READ;
return 0;
}
@@ -271,7 +272,7 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
res->eof = 0;
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
if (iov->iov_len < hdrlen) {
- printk(KERN_WARNING "NFS: READ reply header overflowed:"
+ dprintk("NFS: READ reply header overflowed:"
"length %d > %Zu\n", hdrlen, iov->iov_len);
return -errno_NFSERR_IO;
} else if (iov->iov_len != hdrlen) {
@@ -281,7 +282,7 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) {
- printk(KERN_WARNING "NFS: server cheating in read reply: "
+ dprintk("NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd);
count = recvd;
}
@@ -313,6 +314,7 @@ nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
/* Copy the page array */
xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
+ sndbuf->flags |= XDRBUF_WRITE;
return 0;
}
@@ -431,7 +433,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
if (iov->iov_len < hdrlen) {
- printk(KERN_WARNING "NFS: READDIR reply header overflowed:"
+ dprintk("NFS: READDIR reply header overflowed:"
"length %d > %Zu\n", hdrlen, iov->iov_len);
return -errno_NFSERR_IO;
} else if (iov->iov_len != hdrlen) {
@@ -454,7 +456,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
len = ntohl(*p++);
p += XDR_QUADLEN(len) + 1; /* name plus cookie */
if (len > NFS2_MAXNAMLEN) {
- printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)!\n",
+ dprintk("NFS: giant filename in readdir (len 0x%x)!\n",
len);
goto err_unmap;
}
@@ -471,7 +473,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
entry[0] = entry[1] = 0;
/* truncate listing ? */
if (!nr) {
- printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
+ dprintk("NFS: readdir reply truncated!\n");
entry[1] = 1;
}
goto out;
@@ -583,12 +585,12 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
/* Convert length of symlink */
len = ntohl(*p++);
if (len >= rcvbuf->page_len || len <= 0) {
- dprintk(KERN_WARNING "nfs: server returned giant symlink!\n");
+ dprintk("nfs: server returned giant symlink!\n");
return -ENAMETOOLONG;
}
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
if (iov->iov_len < hdrlen) {
- printk(KERN_WARNING "NFS: READLINK reply header overflowed:"
+ dprintk("NFS: READLINK reply header overflowed:"
"length %d > %Zu\n", hdrlen, iov->iov_len);
return -errno_NFSERR_IO;
} else if (iov->iov_len != hdrlen) {
@@ -597,7 +599,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
}
recvd = req->rq_rcv_buf.len - hdrlen;
if (recvd < len) {
- printk(KERN_WARNING "NFS: server cheating in readlink reply: "
+ dprintk("NFS: server cheating in readlink reply: "
"count %u > recvd %u\n", len, recvd);
return -EIO;
}
@@ -695,7 +697,7 @@ nfs_stat_to_errno(int stat)
if (nfs_errtbl[i].stat == stat)
return nfs_errtbl[i].errno;
}
- printk(KERN_ERR "nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
+ dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
return nfs_errtbl[i].errno;
}
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 7322da4d205..9b7362565c0 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -317,13 +317,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
}
dprintk("NFS call setacl\n");
- nfs_begin_data_update(inode);
msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
status = rpc_call_sync(server->client_acl, &msg, 0);
spin_lock(&inode->i_lock);
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS;
spin_unlock(&inode->i_lock);
- nfs_end_data_update(inode);
dprintk("NFS reply setacl: %d\n", status);
/* pages may have been allocated at the xdr layer. */
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index c7ca5d70870..4cdc2361a66 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -166,6 +166,7 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
nfs_fattr_init(&dir_attr);
nfs_fattr_init(fattr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ nfs_refresh_inode(dir, &dir_attr);
if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
msg.rpc_argp = fhandle;
@@ -173,8 +174,6 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
}
dprintk("NFS reply lookup: %d\n", status);
- if (status >= 0)
- status = nfs_refresh_inode(dir, &dir_attr);
return status;
}
@@ -607,6 +606,9 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
nfs_fattr_init(&dir_attr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+
+ nfs_invalidate_atime(dir);
+
nfs_refresh_inode(dir, &dir_attr);
dprintk("NFS reply readdir: %d\n", status);
return status;
@@ -724,9 +726,9 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
{
if (nfs3_async_handle_jukebox(task, data->inode))
return -EAGAIN;
- /* Call back common NFS readpage processing */
- if (task->tk_status >= 0)
- nfs_refresh_inode(data->inode, &data->fattr);
+
+ nfs_invalidate_atime(data->inode);
+ nfs_refresh_inode(data->inode, &data->fattr);
return 0;
}
@@ -747,7 +749,7 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
if (nfs3_async_handle_jukebox(task, data->inode))
return -EAGAIN;
if (task->tk_status >= 0)
- nfs_post_op_update_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
return 0;
}
@@ -775,8 +777,7 @@ static int nfs3_commit_done(struct rpc_task *task, struct nfs_write_data *data)
{
if (nfs3_async_handle_jukebox(task, data->inode))
return -EAGAIN;
- if (task->tk_status >= 0)
- nfs_post_op_update_inode(data->inode, data->res.fattr);
+ nfs_refresh_inode(data->inode, data->res.fattr);
return 0;
}
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index d9e08f0cf2a..616d3267b7e 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -346,6 +346,7 @@ nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
xdr_inline_pages(&req->rq_rcv_buf, replen,
args->pages, args->pgbase, count);
+ req->rq_rcv_buf.flags |= XDRBUF_READ;
return 0;
}
@@ -367,6 +368,7 @@ nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
/* Copy the page array */
xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
+ sndbuf->flags |= XDRBUF_WRITE;
return 0;
}
@@ -524,7 +526,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
if (iov->iov_len < hdrlen) {
- printk(KERN_WARNING "NFS: READDIR reply header overflowed:"
+ dprintk("NFS: READDIR reply header overflowed:"
"length %d > %Zu\n", hdrlen, iov->iov_len);
return -errno_NFSERR_IO;
} else if (iov->iov_len != hdrlen) {
@@ -547,7 +549,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
len = ntohl(*p++); /* string length */
p += XDR_QUADLEN(len) + 2; /* name + cookie */
if (len > NFS3_MAXNAMLEN) {
- printk(KERN_WARNING "NFS: giant filename in readdir (len %x)!\n",
+ dprintk("NFS: giant filename in readdir (len %x)!\n",
len);
goto err_unmap;
}
@@ -567,7 +569,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
goto short_pkt;
len = ntohl(*p++);
if (len > NFS3_FHSIZE) {
- printk(KERN_WARNING "NFS: giant filehandle in "
+ dprintk("NFS: giant filehandle in "
"readdir (len %x)!\n", len);
goto err_unmap;
}
@@ -588,7 +590,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res
entry[0] = entry[1] = 0;
/* truncate listing ? */
if (!nr) {
- printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
+ dprintk("NFS: readdir reply truncated!\n");
entry[1] = 1;
}
goto out;
@@ -826,22 +828,23 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
/* Convert length of symlink */
len = ntohl(*p++);
if (len >= rcvbuf->page_len || len <= 0) {
- dprintk(KERN_WARNING "nfs: server returned giant symlink!\n");
+ dprintk("nfs: server returned giant symlink!\n");
return -ENAMETOOLONG;
}
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
if (iov->iov_len < hdrlen) {
- printk(KERN_WARNING "NFS: READLINK reply header overflowed:"
+ dprintk("NFS: READLINK reply header overflowed:"
"length %d > %Zu\n", hdrlen, iov->iov_len);
return -errno_NFSERR_IO;
} else if (iov->iov_len != hdrlen) {
- dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
+ dprintk("NFS: READLINK header is short. "
+ "iovec will be shifted.\n");
xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
}
recvd = req->rq_rcv_buf.len - hdrlen;
if (recvd < len) {
- printk(KERN_WARNING "NFS: server cheating in readlink reply: "
+ dprintk("NFS: server cheating in readlink reply: "
"count %u > recvd %u\n", len, recvd);
return -EIO;
}
@@ -876,13 +879,13 @@ nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
ocount = ntohl(*p++);
if (ocount != count) {
- printk(KERN_WARNING "NFS: READ count doesn't match RPC opaque count.\n");
+ dprintk("NFS: READ count doesn't match RPC opaque count.\n");
return -errno_NFSERR_IO;
}
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
if (iov->iov_len < hdrlen) {
- printk(KERN_WARNING "NFS: READ reply header overflowed:"
+ dprintk("NFS: READ reply header overflowed:"
"length %d > %Zu\n", hdrlen, iov->iov_len);
return -errno_NFSERR_IO;
} else if (iov->iov_len != hdrlen) {
@@ -892,7 +895,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) {
- printk(KERN_WARNING "NFS: server cheating in read reply: "
+ dprintk("NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd);
count = recvd;
res->eof = 0;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4b90e17555a..cb99fd90a9a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -62,10 +62,8 @@ struct nfs4_opendata;
static int _nfs4_proc_open(struct nfs4_opendata *data);
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
-static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp);
-static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags);
static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
@@ -177,7 +175,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
*p++ = xdr_one; /* bitmap length */
*p++ = htonl(FATTR4_WORD0_FILEID); /* bitmap */
*p++ = htonl(8); /* attribute buffer length */
- p = xdr_encode_hyper(p, dentry->d_inode->i_ino);
+ p = xdr_encode_hyper(p, NFS_FILEID(dentry->d_inode));
}
*p++ = xdr_one; /* next */
@@ -189,7 +187,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
*p++ = xdr_one; /* bitmap length */
*p++ = htonl(FATTR4_WORD0_FILEID); /* bitmap */
*p++ = htonl(8); /* attribute buffer length */
- p = xdr_encode_hyper(p, dentry->d_parent->d_inode->i_ino);
+ p = xdr_encode_hyper(p, NFS_FILEID(dentry->d_parent->d_inode));
readdir->pgbase = (char *)p - (char *)start;
readdir->count -= readdir->pgbase;
@@ -211,8 +209,9 @@ static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
spin_lock(&dir->i_lock);
nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA;
- if (cinfo->before == nfsi->change_attr && cinfo->atomic)
- nfsi->change_attr = cinfo->after;
+ if (!cinfo->atomic || cinfo->before != nfsi->change_attr)
+ nfsi->cache_change_attribute = jiffies;
+ nfsi->change_attr = cinfo->after;
spin_unlock(&dir->i_lock);
}
@@ -454,7 +453,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
memcpy(stateid.data, delegation->stateid.data, sizeof(stateid.data));
rcu_read_unlock();
lock_kernel();
- ret = _nfs4_do_access(state->inode, state->owner->so_cred, open_mode);
+ ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
unlock_kernel();
if (ret != 0)
goto out;
@@ -948,36 +947,6 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
return 0;
}
-static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags)
-{
- struct nfs_access_entry cache;
- int mask = 0;
- int status;
-
- if (openflags & FMODE_READ)
- mask |= MAY_READ;
- if (openflags & FMODE_WRITE)
- mask |= MAY_WRITE;
- if (openflags & FMODE_EXEC)
- mask |= MAY_EXEC;
- status = nfs_access_get_cached(inode, cred, &cache);
- if (status == 0)
- goto out;
-
- /* Be clever: ask server to check for all possible rights */
- cache.mask = MAY_EXEC | MAY_WRITE | MAY_READ;
- cache.cred = cred;
- cache.jiffies = jiffies;
- status = _nfs4_proc_access(inode, &cache);
- if (status != 0)
- return status;
- nfs_access_add_cache(inode, &cache);
-out:
- if ((cache.mask & mask) == mask)
- return 0;
- return -EACCES;
-}
-
static int nfs4_recover_expired_lease(struct nfs_server *server)
{
struct nfs_client *clp = server->nfs_client;
@@ -1381,7 +1350,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
/* If the open_intent is for execute, we have an extra check to make */
if (nd->intent.open.flags & FMODE_EXEC) {
- ret = _nfs4_do_access(state->inode,
+ ret = nfs_may_open(state->inode,
state->owner->so_cred,
nd->intent.open.flags);
if (ret < 0)
@@ -1390,7 +1359,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
filp = lookup_instantiate_filp(nd, path->dentry, NULL);
if (!IS_ERR(filp)) {
struct nfs_open_context *ctx;
- ctx = (struct nfs_open_context *)filp->private_data;
+ ctx = nfs_file_open_context(filp);
ctx->state = state;
return 0;
}
@@ -1428,13 +1397,16 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
put_rpccred(cred);
if (IS_ERR(state)) {
- if (PTR_ERR(state) == -ENOENT)
+ if (PTR_ERR(state) == -ENOENT) {
d_add(dentry, NULL);
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+ }
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));
nfs4_intent_set_file(nd, &path, state);
return res;
}
@@ -1468,6 +1440,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
}
}
if (state->inode == dentry->d_inode) {
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
nfs4_intent_set_file(nd, &path, state);
return 1;
}
@@ -1757,10 +1730,16 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh
static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
{
+ struct nfs_server *server = NFS_SERVER(inode);
+ struct nfs_fattr fattr;
struct nfs4_accessargs args = {
.fh = NFS_FH(inode),
+ .bitmask = server->attr_bitmask,
+ };
+ struct nfs4_accessres res = {
+ .server = server,
+ .fattr = &fattr,
};
- struct nfs4_accessres res = { 0 };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
.rpc_argp = &args,
@@ -1786,6 +1765,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
if (mode & MAY_EXEC)
args.access |= NFS4_ACCESS_EXECUTE;
}
+ nfs_fattr_init(&fattr);
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
if (!status) {
entry->mask = 0;
@@ -1795,6 +1775,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
entry->mask |= MAY_WRITE;
if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
entry->mask |= MAY_EXEC;
+ nfs_refresh_inode(inode, &fattr);
}
return status;
}
@@ -1900,11 +1881,13 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
}
state = nfs4_do_open(dir, &path, flags, sattr, cred);
put_rpccred(cred);
+ d_drop(dentry);
if (IS_ERR(state)) {
status = PTR_ERR(state);
goto out;
}
- d_instantiate(dentry, igrab(state->inode));
+ d_add(dentry, igrab(state->inode));
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
if (flags & O_EXCL) {
struct nfs_fattr fattr;
status = nfs4_do_setattr(state->inode, &fattr, sattr, state);
@@ -2218,6 +2201,9 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
if (status == 0)
memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
+
+ nfs_invalidate_atime(dir);
+
dprintk("%s: returns %d\n", __FUNCTION__, status);
return status;
}
@@ -2414,6 +2400,8 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
rpc_restart_call(task);
return -EAGAIN;
}
+
+ nfs_invalidate_atime(data->inode);
if (task->tk_status > 0)
renew_lease(server, data->timestamp);
return 0;
@@ -2443,7 +2431,7 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
}
if (task->tk_status >= 0) {
renew_lease(NFS_SERVER(inode), data->timestamp);
- nfs_post_op_update_inode(inode, data->res.fattr);
+ nfs_post_op_update_inode_force_wcc(inode, data->res.fattr);
}
return 0;
}
@@ -2485,8 +2473,7 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
rpc_restart_call(task);
return -EAGAIN;
}
- if (task->tk_status >= 0)
- nfs_post_op_update_inode(inode, data->res.fattr);
+ nfs_refresh_inode(inode, data->res.fattr);
return 0;
}
@@ -3056,7 +3043,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
if (status == 0) {
status = data->rpc_status;
if (status == 0)
- nfs_post_op_update_inode(inode, &data->fattr);
+ nfs_refresh_inode(inode, &data->fattr);
}
rpc_put_task(task);
return status;
@@ -3303,7 +3290,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
status = -ENOMEM;
if (seqid == NULL)
goto out;
- task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid);
+ task = nfs4_do_unlck(request, nfs_file_open_context(request->fl_file), lsp, seqid);
status = PTR_ERR(task);
if (IS_ERR(task))
goto out;
@@ -3447,7 +3434,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
int ret;
dprintk("%s: begin!\n", __FUNCTION__);
- data = nfs4_alloc_lockdata(fl, fl->fl_file->private_data,
+ data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
fl->fl_u.nfs4_fl.owner);
if (data == NULL)
return -ENOMEM;
@@ -3573,7 +3560,7 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
int status;
/* verify open state */
- ctx = (struct nfs_open_context *)filp->private_data;
+ ctx = nfs_file_open_context(filp);
state = ctx->state;
if (request->fl_start < 0 || request->fl_end < 0)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 3e4adf8c831..bfb36261cec 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -774,7 +774,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s
for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) {
if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
continue;
- if (((struct nfs_open_context *)fl->fl_file->private_data)->state != state)
+ if (nfs_file_open_context(fl->fl_file)->state != state)
continue;
status = ops->recover_lock(state, fl);
if (status >= 0)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index badd73b7ca1..51dd3804866 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -376,10 +376,12 @@ static int nfs4_stat_to_errno(int);
decode_locku_maxsz)
#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
- encode_access_maxsz)
+ encode_access_maxsz + \
+ encode_getattr_maxsz)
#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- decode_access_maxsz)
+ decode_access_maxsz + \
+ decode_getattr_maxsz)
#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
@@ -562,7 +564,6 @@ struct compound_hdr {
#define RESERVE_SPACE(nbytes) do { \
p = xdr_reserve_space(xdr, nbytes); \
- if (!p) printk("RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __FUNCTION__); \
BUG_ON(!p); \
} while (0)
@@ -628,8 +629,8 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
if (iap->ia_valid & ATTR_UID) {
owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name);
if (owner_namelen < 0) {
- printk(KERN_WARNING "nfs: couldn't resolve uid %d to string\n",
- iap->ia_uid);
+ dprintk("nfs: couldn't resolve uid %d to string\n",
+ iap->ia_uid);
/* XXX */
strcpy(owner_name, "nobody");
owner_namelen = sizeof("nobody") - 1;
@@ -640,8 +641,8 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
if (iap->ia_valid & ATTR_GID) {
owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group);
if (owner_grouplen < 0) {
- printk(KERN_WARNING "nfs4: couldn't resolve gid %d to string\n",
- iap->ia_gid);
+ dprintk("nfs: couldn't resolve gid %d to string\n",
+ iap->ia_gid);
strcpy(owner_group, "nobody");
owner_grouplen = sizeof("nobody") - 1;
/* goto out; */
@@ -711,7 +712,7 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const s
* Now we backfill the bitmap and the attribute buffer length.
*/
if (len != ((char *)p - (char *)q) + 4) {
- printk ("encode_attr: Attr length calculation error! %u != %Zu\n",
+ printk(KERN_ERR "nfs: Attr length error, %u != %Zu\n",
len, ((char *)p - (char *)q) + 4);
BUG();
}
@@ -1376,14 +1377,20 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .nops = 2,
+ .nops = 3,
};
int status;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
- if ((status = encode_putfh(&xdr, args->fh)) == 0)
- status = encode_access(&xdr, args->access);
+ status = encode_putfh(&xdr, args->fh);
+ if (status != 0)
+ goto out;
+ status = encode_access(&xdr, args->access);
+ if (status != 0)
+ goto out;
+ status = encode_getfattr(&xdr, args->bitmask);
+out:
return status;
}
@@ -1857,6 +1864,7 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
xdr_inline_pages(&req->rq_rcv_buf, replen,
args->pages, args->pgbase, args->count);
+ req->rq_rcv_buf.flags |= XDRBUF_READ;
out:
return status;
}
@@ -1933,6 +1941,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
status = encode_write(&xdr, args);
if (status)
goto out;
+ req->rq_snd_buf.flags |= XDRBUF_WRITE;
status = encode_getfattr(&xdr, args->bitmask);
out:
return status;
@@ -2180,9 +2189,9 @@ out:
#define READ_BUF(nbytes) do { \
p = xdr_inline_decode(xdr, nbytes); \
if (unlikely(!p)) { \
- printk(KERN_INFO "%s: prematurely hit end of receive" \
+ dprintk("nfs: %s: prematurely hit end of receive" \
" buffer\n", __FUNCTION__); \
- printk(KERN_INFO "%s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \
+ dprintk("nfs: %s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \
__FUNCTION__, xdr->p, nbytes, xdr->end); \
return -EIO; \
} \
@@ -2223,9 +2232,8 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
READ_BUF(8);
READ32(opnum);
if (opnum != expected) {
- printk(KERN_NOTICE
- "nfs4_decode_op_hdr: Server returned operation"
- " %d but we issued a request for %d\n",
+ dprintk("nfs: Server returned operation"
+ " %d but we issued a request for %d\n",
opnum, expected);
return -EIO;
}
@@ -2758,7 +2766,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
dprintk("%s: nfs_map_name_to_uid failed!\n",
__FUNCTION__);
} else
- printk(KERN_WARNING "%s: name too long (%u)!\n",
+ dprintk("%s: name too long (%u)!\n",
__FUNCTION__, len);
bitmap[1] &= ~FATTR4_WORD1_OWNER;
}
@@ -2783,7 +2791,7 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf
dprintk("%s: nfs_map_group_to_gid failed!\n",
__FUNCTION__);
} else
- printk(KERN_WARNING "%s: name too long (%u)!\n",
+ dprintk("%s: name too long (%u)!\n",
__FUNCTION__, len);
bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
}
@@ -2950,7 +2958,8 @@ static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrl
unsigned int nwords = xdr->p - savep;
if (unlikely(attrwords != nwords)) {
- printk(KERN_WARNING "%s: server returned incorrect attribute length: %u %c %u\n",
+ dprintk("%s: server returned incorrect attribute length: "
+ "%u %c %u\n",
__FUNCTION__,
attrwords << 2,
(attrwords < nwords) ? '<' : '>',
@@ -3451,7 +3460,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_
hdrlen = (u8 *) p - (u8 *) iov->iov_base;
recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) {
- printk(KERN_WARNING "NFS: server cheating in read reply: "
+ dprintk("NFS: server cheating in read reply: "
"count %u > recvd %u\n", count, recvd);
count = recvd;
eof = 0;
@@ -3500,7 +3509,8 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n
p += 2; /* cookie */
len = ntohl(*p++); /* filename length */
if (len > NFS4_MAXNAMLEN) {
- printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len);
+ dprintk("NFS: giant filename in readdir (len 0x%x)\n",
+ len);
goto err_unmap;
}
xlen = XDR_QUADLEN(len);
@@ -3528,7 +3538,7 @@ short_pkt:
entry[0] = entry[1] = 0;
/* truncate listing ? */
if (!nr) {
- printk(KERN_NOTICE "NFS: readdir reply truncated!\n");
+ dprintk("NFS: readdir reply truncated!\n");
entry[1] = 1;
}
goto out;
@@ -3554,13 +3564,13 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
READ_BUF(4);
READ32(len);
if (len >= rcvbuf->page_len || len <= 0) {
- dprintk(KERN_WARNING "nfs: server returned giant symlink!\n");
+ dprintk("nfs: server returned giant symlink!\n");
return -ENAMETOOLONG;
}
hdrlen = (char *) xdr->p - (char *) iov->iov_base;
recvd = req->rq_rcv_buf.len - hdrlen;
if (recvd < len) {
- printk(KERN_WARNING "NFS: server cheating in readlink reply: "
+ dprintk("NFS: server cheating in readlink reply: "
"count %u > recvd %u\n", len, recvd);
return -EIO;
}
@@ -3643,7 +3653,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
recvd = req->rq_rcv_buf.len - hdrlen;
if (attrlen > recvd) {
- printk(KERN_WARNING "NFS: server cheating in getattr"
+ dprintk("NFS: server cheating in getattr"
" acl reply: attrlen %u > recvd %u\n",
attrlen, recvd);
return -EINVAL;
@@ -3688,8 +3698,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
READ_BUF(8);
READ32(opnum);
if (opnum != OP_SETCLIENTID) {
- printk(KERN_NOTICE
- "nfs4_decode_setclientid: Server returned operation"
+ dprintk("nfs: decode_setclientid: Server returned operation"
" %d\n", opnum);
return -EIO;
}
@@ -3783,8 +3792,13 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
goto out;
- if ((status = decode_putfh(&xdr)) == 0)
- status = decode_access(&xdr, res);
+ status = decode_putfh(&xdr);
+ if (status != 0)
+ goto out;
+ status = decode_access(&xdr, res);
+ if (status != 0)
+ goto out;
+ decode_getfattr(&xdr, res->fattr, res->server);
out:
return status;
}
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 3490322d114..e87b44ee9ac 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -76,6 +76,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/xprtsock.h>
#include <linux/nfs.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
@@ -491,7 +492,7 @@ static int __init root_nfs_get_handle(void)
struct sockaddr_in sin;
int status;
int protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
- IPPROTO_TCP : IPPROTO_UDP;
+ XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP;
int version = (nfs_data.flags & NFS_MOUNT_VER3) ?
NFS_MNT3_VERSION : NFS_MNT_VERSION;
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 845cdde1d8b..97669ed0550 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -476,6 +476,8 @@ nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
dprintk("NFS call readdir %d\n", (unsigned int)cookie);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ nfs_invalidate_atime(dir);
+
dprintk("NFS reply readdir: %d\n", status);
return status;
}
@@ -550,6 +552,7 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
{
+ nfs_invalidate_atime(data->inode);
if (task->tk_status >= 0) {
nfs_refresh_inode(data->inode, data->res.fattr);
/* Emulate the eof flag, which isn't normally needed in NFSv2
@@ -576,7 +579,7 @@ static void nfs_proc_read_setup(struct nfs_read_data *data)
static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
{
if (task->tk_status >= 0)
- nfs_post_op_update_inode(data->inode, data->res.fattr);
+ nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
return 0;
}
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 19e05633f4e..4587a86adaa 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -341,9 +341,6 @@ int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data)
set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode));
nfs_mark_for_revalidate(data->inode);
}
- spin_lock(&data->inode->i_lock);
- NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME;
- spin_unlock(&data->inode->i_lock);
return 0;
}
@@ -497,8 +494,7 @@ int nfs_readpage(struct file *file, struct page *page)
if (ctx == NULL)
goto out_unlock;
} else
- ctx = get_nfs_open_context((struct nfs_open_context *)
- file->private_data);
+ ctx = get_nfs_open_context(nfs_file_open_context(file));
error = nfs_readpage_async(ctx, inode, page);
@@ -576,8 +572,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
if (desc.ctx == NULL)
return -EBADF;
} else
- desc.ctx = get_nfs_open_context((struct nfs_open_context *)
- filp->private_data);
+ desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
if (rsize < PAGE_CACHE_SIZE)
nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
else
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index b878528b64c..fa517ae9207 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -33,6 +33,8 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/metrics.h>
+#include <linux/sunrpc/xprtsock.h>
+#include <linux/sunrpc/xprtrdma.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
@@ -58,36 +60,6 @@
#define NFSDBG_FACILITY NFSDBG_VFS
-
-struct nfs_parsed_mount_data {
- int flags;
- int rsize, wsize;
- int timeo, retrans;
- int acregmin, acregmax,
- acdirmin, acdirmax;
- int namlen;
- unsigned int bsize;
- unsigned int auth_flavor_len;
- rpc_authflavor_t auth_flavors[1];
- char *client_address;
-
- struct {
- struct sockaddr_in address;
- unsigned int program;
- unsigned int version;
- unsigned short port;
- int protocol;
- } mount_server;
-
- struct {
- struct sockaddr_in address;
- char *hostname;
- char *export_path;
- unsigned int program;
- int protocol;
- } nfs_server;
-};
-
enum {
/* Mount options that take no arguments */
Opt_soft, Opt_hard,
@@ -97,7 +69,7 @@ enum {
Opt_ac, Opt_noac,
Opt_lock, Opt_nolock,
Opt_v2, Opt_v3,
- Opt_udp, Opt_tcp,
+ Opt_udp, Opt_tcp, Opt_rdma,
Opt_acl, Opt_noacl,
Opt_rdirplus, Opt_nordirplus,
Opt_sharecache, Opt_nosharecache,
@@ -116,7 +88,7 @@ enum {
/* Mount options that take string arguments */
Opt_sec, Opt_proto, Opt_mountproto,
- Opt_addr, Opt_mounthost, Opt_clientaddr,
+ Opt_addr, Opt_mountaddr, Opt_clientaddr,
/* Mount options that are ignored */
Opt_userspace, Opt_deprecated,
@@ -143,6 +115,7 @@ static match_table_t nfs_mount_option_tokens = {
{ Opt_v3, "v3" },
{ Opt_udp, "udp" },
{ Opt_tcp, "tcp" },
+ { Opt_rdma, "rdma" },
{ Opt_acl, "acl" },
{ Opt_noacl, "noacl" },
{ Opt_rdirplus, "rdirplus" },
@@ -175,13 +148,14 @@ static match_table_t nfs_mount_option_tokens = {
{ Opt_mountproto, "mountproto=%s" },
{ Opt_addr, "addr=%s" },
{ Opt_clientaddr, "clientaddr=%s" },
- { Opt_mounthost, "mounthost=%s" },
+ { Opt_userspace, "mounthost=%s" },
+ { Opt_mountaddr, "mountaddr=%s" },
{ Opt_err, NULL }
};
enum {
- Opt_xprt_udp, Opt_xprt_tcp,
+ Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_rdma,
Opt_xprt_err
};
@@ -189,6 +163,7 @@ enum {
static match_table_t nfs_xprt_protocol_tokens = {
{ Opt_xprt_udp, "udp" },
{ Opt_xprt_tcp, "tcp" },
+ { Opt_xprt_rdma, "rdma" },
{ Opt_xprt_err, NULL }
};
@@ -449,7 +424,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
const char *nostr;
} nfs_info[] = {
{ NFS_MOUNT_SOFT, ",soft", ",hard" },
- { NFS_MOUNT_INTR, ",intr", "" },
+ { NFS_MOUNT_INTR, ",intr", ",nointr" },
{ NFS_MOUNT_NOCTO, ",nocto", "" },
{ NFS_MOUNT_NOAC, ",noac", "" },
{ NFS_MOUNT_NONLM, ",nolock", "" },
@@ -460,8 +435,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
};
const struct proc_nfs_info *nfs_infop;
struct nfs_client *clp = nfss->nfs_client;
- char buf[12];
- const char *proto;
seq_printf(m, ",vers=%d", clp->rpc_ops->version);
seq_printf(m, ",rsize=%d", nfss->rsize);
@@ -480,18 +453,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
else
seq_puts(m, nfs_infop->nostr);
}
- switch (nfss->client->cl_xprt->prot) {
- case IPPROTO_TCP:
- proto = "tcp";
- break;
- case IPPROTO_UDP:
- proto = "udp";
- break;
- default:
- snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
- proto = buf;
- }
- seq_printf(m, ",proto=%s", proto);
+ seq_printf(m, ",proto=%s",
+ rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO));
seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ);
seq_printf(m, ",retrans=%u", clp->retrans_count);
seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
@@ -506,8 +469,8 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
nfs_show_mount_options(m, nfss, 0);
- seq_puts(m, ",addr=");
- seq_escape(m, nfss->nfs_client->cl_hostname, " \t\n\\");
+ seq_printf(m, ",addr="NIPQUAD_FMT,
+ NIPQUAD(nfss->nfs_client->cl_addr.sin_addr));
return 0;
}
@@ -698,13 +661,19 @@ static int nfs_parse_mount_options(char *raw,
break;
case Opt_udp:
mnt->flags &= ~NFS_MOUNT_TCP;
- mnt->nfs_server.protocol = IPPROTO_UDP;
+ mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
mnt->timeo = 7;
mnt->retrans = 5;
break;
case Opt_tcp:
mnt->flags |= NFS_MOUNT_TCP;
- mnt->nfs_server.protocol = IPPROTO_TCP;
+ mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+ mnt->timeo = 600;
+ mnt->retrans = 2;
+ break;
+ case Opt_rdma:
+ mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */
+ mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
mnt->timeo = 600;
mnt->retrans = 2;
break;
@@ -913,13 +882,20 @@ static int nfs_parse_mount_options(char *raw,
switch (token) {
case Opt_xprt_udp:
mnt->flags &= ~NFS_MOUNT_TCP;
- mnt->nfs_server.protocol = IPPROTO_UDP;
+ mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
mnt->timeo = 7;
mnt->retrans = 5;
break;
case Opt_xprt_tcp:
mnt->flags |= NFS_MOUNT_TCP;
- mnt->nfs_server.protocol = IPPROTO_TCP;
+ mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+ mnt->timeo = 600;
+ mnt->retrans = 2;
+ break;
+ case Opt_xprt_rdma:
+ /* vector side protocols to TCP */
+ mnt->flags |= NFS_MOUNT_TCP;
+ mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
mnt->timeo = 600;
mnt->retrans = 2;
break;
@@ -937,11 +913,12 @@ static int nfs_parse_mount_options(char *raw,
switch (token) {
case Opt_xprt_udp:
- mnt->mount_server.protocol = IPPROTO_UDP;
+ mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
break;
case Opt_xprt_tcp:
- mnt->mount_server.protocol = IPPROTO_TCP;
+ mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
break;
+ case Opt_xprt_rdma: /* not used for side protocols */
default:
goto out_unrec_xprt;
}
@@ -961,7 +938,7 @@ static int nfs_parse_mount_options(char *raw,
goto out_nomem;
mnt->client_address = string;
break;
- case Opt_mounthost:
+ case Opt_mountaddr:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
@@ -1027,16 +1004,10 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
sin = args->mount_server.address;
else
sin = args->nfs_server.address;
- if (args->mount_server.port == 0) {
- status = rpcb_getport_sync(&sin,
- args->mount_server.program,
- args->mount_server.version,
- args->mount_server.protocol);
- if (status < 0)
- goto out_err;
- sin.sin_port = htons(status);
- } else
- sin.sin_port = htons(args->mount_server.port);
+ /*
+ * autobind will be used if mount_server.port == 0
+ */
+ sin.sin_port = htons(args->mount_server.port);
/*
* Now ask the mount server to map our export path
@@ -1049,14 +1020,11 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
args->mount_server.version,
args->mount_server.protocol,
root_fh);
- if (status < 0)
- goto out_err;
-
- return status;
+ if (status == 0)
+ return 0;
-out_err:
- dfprintk(MOUNT, "NFS: unable to contact server on host "
- NIPQUAD_FMT "\n", NIPQUAD(sin.sin_addr.s_addr));
+ dfprintk(MOUNT, "NFS: unable to mount server " NIPQUAD_FMT
+ ", error %d\n", NIPQUAD(sin.sin_addr.s_addr), status);
return status;
}
@@ -1079,15 +1047,31 @@ out_err:
* XXX: as far as I can tell, changing the NFS program number is not
* supported in the NFS client.
*/
-static int nfs_validate_mount_data(struct nfs_mount_data **options,
+static int nfs_validate_mount_data(void *options,
+ struct nfs_parsed_mount_data *args,
struct nfs_fh *mntfh,
const char *dev_name)
{
- struct nfs_mount_data *data = *options;
+ struct nfs_mount_data *data = (struct nfs_mount_data *)options;
if (data == NULL)
goto out_no_data;
+ memset(args, 0, sizeof(*args));
+ args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
+ args->rsize = NFS_MAX_FILE_IO_SIZE;
+ args->wsize = NFS_MAX_FILE_IO_SIZE;
+ args->timeo = 600;
+ args->retrans = 2;
+ args->acregmin = 3;
+ args->acregmax = 60;
+ args->acdirmin = 30;
+ args->acdirmax = 60;
+ args->mount_server.protocol = XPRT_TRANSPORT_UDP;
+ args->mount_server.program = NFS_MNT_PROGRAM;
+ args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+ args->nfs_server.program = NFS_PROGRAM;
+
switch (data->version) {
case 1:
data->namlen = 0;
@@ -1116,92 +1100,73 @@ static int nfs_validate_mount_data(struct nfs_mount_data **options,
if (mntfh->size < sizeof(mntfh->data))
memset(mntfh->data + mntfh->size, 0,
sizeof(mntfh->data) - mntfh->size);
+
+ if (!nfs_verify_server_address((struct sockaddr *) &data->addr))
+ goto out_no_address;
+
+ /*
+ * Translate to nfs_parsed_mount_data, which nfs_fill_super
+ * can deal with.
+ */
+ args->flags = data->flags;
+ args->rsize = data->rsize;
+ args->wsize = data->wsize;
+ args->flags = data->flags;
+ args->timeo = data->timeo;
+ args->retrans = data->retrans;
+ args->acregmin = data->acregmin;
+ args->acregmax = data->acregmax;
+ args->acdirmin = data->acdirmin;
+ args->acdirmax = data->acdirmax;
+ args->nfs_server.address = data->addr;
+ if (!(data->flags & NFS_MOUNT_TCP))
+ args->nfs_server.protocol = XPRT_TRANSPORT_UDP;
+ /* N.B. caller will free nfs_server.hostname in all cases */
+ args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
+ args->namlen = data->namlen;
+ args->bsize = data->bsize;
+ args->auth_flavors[0] = data->pseudoflavor;
break;
default: {
unsigned int len;
char *c;
int status;
- struct nfs_parsed_mount_data args = {
- .flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP),
- .rsize = NFS_MAX_FILE_IO_SIZE,
- .wsize = NFS_MAX_FILE_IO_SIZE,
- .timeo = 600,
- .retrans = 2,
- .acregmin = 3,
- .acregmax = 60,
- .acdirmin = 30,
- .acdirmax = 60,
- .mount_server.protocol = IPPROTO_UDP,
- .mount_server.program = NFS_MNT_PROGRAM,
- .nfs_server.protocol = IPPROTO_TCP,
- .nfs_server.program = NFS_PROGRAM,
- };
-
- if (nfs_parse_mount_options((char *) *options, &args) == 0)
- return -EINVAL;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
+ if (nfs_parse_mount_options((char *)options, args) == 0)
+ return -EINVAL;
- /*
- * NB: after this point, caller will free "data"
- * if we return an error
- */
- *options = data;
+ if (!nfs_verify_server_address((struct sockaddr *)
+ &args->nfs_server.address))
+ goto out_no_address;
c = strchr(dev_name, ':');
if (c == NULL)
return -EINVAL;
len = c - dev_name;
- if (len > sizeof(data->hostname))
- return -ENAMETOOLONG;
- strncpy(data->hostname, dev_name, len);
- args.nfs_server.hostname = data->hostname;
+ /* N.B. caller will free nfs_server.hostname in all cases */
+ args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
c++;
if (strlen(c) > NFS_MAXPATHLEN)
return -ENAMETOOLONG;
- args.nfs_server.export_path = c;
+ args->nfs_server.export_path = c;
- status = nfs_try_mount(&args, mntfh);
+ status = nfs_try_mount(args, mntfh);
if (status)
return status;
- /*
- * Translate to nfs_mount_data, which nfs_fill_super
- * can deal with.
- */
- data->version = 6;
- data->flags = args.flags;
- data->rsize = args.rsize;
- data->wsize = args.wsize;
- data->timeo = args.timeo;
- data->retrans = args.retrans;
- data->acregmin = args.acregmin;
- data->acregmax = args.acregmax;
- data->acdirmin = args.acdirmin;
- data->acdirmax = args.acdirmax;
- data->addr = args.nfs_server.address;
- data->namlen = args.namlen;
- data->bsize = args.bsize;
- data->pseudoflavor = args.auth_flavors[0];
-
break;
}
}
- if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
- data->pseudoflavor = RPC_AUTH_UNIX;
+ if (!(args->flags & NFS_MOUNT_SECFLAVOUR))
+ args->auth_flavors[0] = RPC_AUTH_UNIX;
#ifndef CONFIG_NFS_V3
- if (data->flags & NFS_MOUNT_VER3)
+ if (args->flags & NFS_MOUNT_VER3)
goto out_v3_not_compiled;
#endif /* !CONFIG_NFS_V3 */
- if (!nfs_verify_server_address((struct sockaddr *) &data->addr))
- goto out_no_address;
-
return 0;
out_no_data:
@@ -1258,7 +1223,8 @@ static inline void nfs_initialise_sb(struct super_block *sb)
/*
* Finish setting up an NFS2/3 superblock
*/
-static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data)
+static void nfs_fill_super(struct super_block *sb,
+ struct nfs_parsed_mount_data *data)
{
struct nfs_server *server = NFS_SB(sb);
@@ -1379,7 +1345,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
struct nfs_server *server = NULL;
struct super_block *s;
struct nfs_fh mntfh;
- struct nfs_mount_data *data = raw_data;
+ struct nfs_parsed_mount_data data;
struct dentry *mntroot;
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
struct nfs_sb_mountdata sb_mntdata = {
@@ -1388,12 +1354,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
int error;
/* Validate the mount data */
- error = nfs_validate_mount_data(&data, &mntfh, dev_name);
+ error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
if (error < 0)
goto out;
/* Get a volume representation */
- server = nfs_create_server(data, &mntfh);
+ server = nfs_create_server(&data, &mntfh);
if (IS_ERR(server)) {
error = PTR_ERR(server);
goto out;
@@ -1417,7 +1383,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
if (!s->s_root) {
/* initial superblock/root creation */
- nfs_fill_super(s, data);
+ nfs_fill_super(s, &data);
}
mntroot = nfs_get_root(s, &mntfh);
@@ -1432,8 +1398,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
error = 0;
out:
- if (data != raw_data)
- kfree(data);
+ kfree(data.nfs_server.hostname);
return error;
out_err_nosb:
@@ -1559,38 +1524,49 @@ static void nfs4_fill_super(struct super_block *sb)
/*
* Validate NFSv4 mount options
*/
-static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
- const char *dev_name,
- struct sockaddr_in *addr,
- rpc_authflavor_t *authflavour,
- char **hostname,
- char **mntpath,
- char **ip_addr)
+static int nfs4_validate_mount_data(void *options,
+ struct nfs_parsed_mount_data *args,
+ const char *dev_name)
{
- struct nfs4_mount_data *data = *options;
+ struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
char *c;
if (data == NULL)
goto out_no_data;
+ memset(args, 0, sizeof(*args));
+ args->rsize = NFS_MAX_FILE_IO_SIZE;
+ args->wsize = NFS_MAX_FILE_IO_SIZE;
+ args->timeo = 600;
+ args->retrans = 2;
+ args->acregmin = 3;
+ args->acregmax = 60;
+ args->acdirmin = 30;
+ args->acdirmax = 60;
+ args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+
switch (data->version) {
case 1:
- if (data->host_addrlen != sizeof(*addr))
+ if (data->host_addrlen != sizeof(args->nfs_server.address))
goto out_no_address;
- if (copy_from_user(addr, data->host_addr, sizeof(*addr)))
+ if (copy_from_user(&args->nfs_server.address,
+ data->host_addr,
+ sizeof(args->nfs_server.address)))
return -EFAULT;
- if (addr->sin_port == 0)
- addr->sin_port = htons(NFS_PORT);
- if (!nfs_verify_server_address((struct sockaddr *) addr))
+ if (args->nfs_server.address.sin_port == 0)
+ args->nfs_server.address.sin_port = htons(NFS_PORT);
+ if (!nfs_verify_server_address((struct sockaddr *)
+ &args->nfs_server.address))
goto out_no_address;
switch (data->auth_flavourlen) {
case 0:
- *authflavour = RPC_AUTH_UNIX;
+ args->auth_flavors[0] = RPC_AUTH_UNIX;
break;
case 1:
- if (copy_from_user(authflavour, data->auth_flavours,
- sizeof(*authflavour)))
+ if (copy_from_user(&args->auth_flavors[0],
+ data->auth_flavours,
+ sizeof(args->auth_flavors[0])))
return -EFAULT;
break;
default:
@@ -1600,75 +1576,57 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
if (IS_ERR(c))
return PTR_ERR(c);
- *hostname = c;
+ args->nfs_server.hostname = c;
c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
if (IS_ERR(c))
return PTR_ERR(c);
- *mntpath = c;
- dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *mntpath);
+ args->nfs_server.export_path = c;
+ dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
c = strndup_user(data->client_addr.data, 16);
if (IS_ERR(c))
return PTR_ERR(c);
- *ip_addr = c;
+ args->client_address = c;
+
+ /*
+ * Translate to nfs_parsed_mount_data, which nfs4_fill_super
+ * can deal with.
+ */
+
+ args->flags = data->flags & NFS4_MOUNT_FLAGMASK;
+ args->rsize = data->rsize;
+ args->wsize = data->wsize;
+ args->timeo = data->timeo;
+ args->retrans = data->retrans;
+ args->acregmin = data->acregmin;
+ args->acregmax = data->acregmax;
+ args->acdirmin = data->acdirmin;
+ args->acdirmax = data->acdirmax;
+ args->nfs_server.protocol = data->proto;
break;
default: {
unsigned int len;
- struct nfs_parsed_mount_data args = {
- .rsize = NFS_MAX_FILE_IO_SIZE,
- .wsize = NFS_MAX_FILE_IO_SIZE,
- .timeo = 600,
- .retrans = 2,
- .acregmin = 3,
- .acregmax = 60,
- .acdirmin = 30,
- .acdirmax = 60,
- .nfs_server.protocol = IPPROTO_TCP,
- };
-
- if (nfs_parse_mount_options((char *) *options, &args) == 0)
+
+ if (nfs_parse_mount_options((char *)options, args) == 0)
return -EINVAL;
if (!nfs_verify_server_address((struct sockaddr *)
- &args.nfs_server.address))
+ &args->nfs_server.address))
return -EINVAL;
- *addr = args.nfs_server.address;
- switch (args.auth_flavor_len) {
+ switch (args->auth_flavor_len) {
case 0:
- *authflavour = RPC_AUTH_UNIX;
+ args->auth_flavors[0] = RPC_AUTH_UNIX;
break;
case 1:
- *authflavour = (rpc_authflavor_t) args.auth_flavors[0];
break;
default:
goto out_inval_auth;
}
/*
- * Translate to nfs4_mount_data, which nfs4_fill_super
- * can deal with.
- */
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (data == NULL)
- return -ENOMEM;
- *options = data;
-
- data->version = 1;
- data->flags = args.flags & NFS4_MOUNT_FLAGMASK;
- data->rsize = args.rsize;
- data->wsize = args.wsize;
- data->timeo = args.timeo;
- data->retrans = args.retrans;
- data->acregmin = args.acregmin;
- data->acregmax = args.acregmax;
- data->acdirmin = args.acdirmin;
- data->acdirmax = args.acdirmax;
- data->proto = args.nfs_server.protocol;
-
- /*
* Split "dev_name" into "hostname:mntpath".
*/
c = strchr(dev_name, ':');
@@ -1678,27 +1636,25 @@ static int nfs4_validate_mount_data(struct nfs4_mount_data **options,
len = c - dev_name;
if (len > NFS4_MAXNAMLEN)
return -ENAMETOOLONG;
- *hostname = kzalloc(len, GFP_KERNEL);
- if (*hostname == NULL)
+ args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);
+ if (args->nfs_server.hostname == NULL)
return -ENOMEM;
- strncpy(*hostname, dev_name, len - 1);
+ strncpy(args->nfs_server.hostname, dev_name, len - 1);
c++; /* step over the ':' */
len = strlen(c);
if (len > NFS4_MAXPATHLEN)
return -ENAMETOOLONG;
- *mntpath = kzalloc(len + 1, GFP_KERNEL);
- if (*mntpath == NULL)
+ args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);
+ if (args->nfs_server.export_path == NULL)
return -ENOMEM;
- strncpy(*mntpath, c, len);
+ strncpy(args->nfs_server.export_path, c, len);
- dprintk("MNTPATH: %s\n", *mntpath);
+ dprintk("MNTPATH: %s\n", args->nfs_server.export_path);
- if (args.client_address == NULL)
+ if (args->client_address == NULL)
goto out_no_client_address;
- *ip_addr = args.client_address;
-
break;
}
}
@@ -1729,14 +1685,11 @@ out_no_client_address:
static int nfs4_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
{
- struct nfs4_mount_data *data = raw_data;
+ struct nfs_parsed_mount_data data;
struct super_block *s;
struct nfs_server *server;
- struct sockaddr_in addr;
- rpc_authflavor_t authflavour;
struct nfs_fh mntfh;
struct dentry *mntroot;
- char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL;
int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
struct nfs_sb_mountdata sb_mntdata = {
.mntflags = flags,
@@ -1744,14 +1697,12 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
int error;
/* Validate the mount data */
- error = nfs4_validate_mount_data(&data, dev_name, &addr, &authflavour,
- &hostname, &mntpath, &ip_addr);
+ error = nfs4_validate_mount_data(raw_data, &data, dev_name);
if (error < 0)
goto out;
/* Get a volume representation */
- server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
- authflavour, &mntfh);
+ server = nfs4_create_server(&data, &mntfh);
if (IS_ERR(server)) {
error = PTR_ERR(server);
goto out;
@@ -1790,9 +1741,9 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
error = 0;
out:
- kfree(ip_addr);
- kfree(mntpath);
- kfree(hostname);
+ kfree(data.client_address);
+ kfree(data.nfs_server.export_path);
+ kfree(data.nfs_server.hostname);
return error;
out_free:
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 045ab805c17..1aed850d18f 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -66,7 +66,6 @@ static void nfs_async_unlink_init(struct rpc_task *task, void *calldata)
.rpc_cred = data->cred,
};
- nfs_begin_data_update(dir);
NFS_PROTO(dir)->unlink_setup(&msg, dir);
rpc_call_setup(task, &msg, 0);
}
@@ -84,8 +83,6 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
if (!NFS_PROTO(dir)->unlink_done(task, dir))
rpc_restart_call(task);
- else
- nfs_end_data_update(dir);
}
/**
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0d7a77cc394..0cf9d1cd9bd 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -110,6 +110,13 @@ void nfs_writedata_release(void *wdata)
nfs_writedata_free(wdata);
}
+static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
+{
+ ctx->error = error;
+ smp_wmb();
+ set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
+}
+
static struct nfs_page *nfs_page_find_request_locked(struct page *page)
{
struct nfs_page *req = NULL;
@@ -235,18 +242,13 @@ static void nfs_end_page_writeback(struct page *page)
struct nfs_server *nfss = NFS_SERVER(inode);
end_page_writeback(page);
- if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
+ if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
clear_bdi_congested(&nfss->backing_dev_info, WRITE);
- congestion_end(WRITE);
- }
}
/*
* Find an associated nfs write request, and prepare to flush it out
- * Returns 1 if there was no write request, or if the request was
- * already tagged by nfs_set_page_dirty.Returns 0 if the request
- * was not tagged.
- * May also return an error if the user signalled nfs_wait_on_request().
+ * May return an error if the user signalled nfs_wait_on_request().
*/
static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
struct page *page)
@@ -261,7 +263,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
req = nfs_page_find_request_locked(page);
if (req == NULL) {
spin_unlock(&inode->i_lock);
- return 1;
+ return 0;
}
if (nfs_lock_request_dontget(req))
break;
@@ -282,7 +284,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
spin_unlock(&inode->i_lock);
nfs_unlock_request(req);
nfs_pageio_complete(pgio);
- return 1;
+ return 0;
}
if (nfs_set_page_writeback(page) != 0) {
spin_unlock(&inode->i_lock);
@@ -290,70 +292,56 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
}
radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index,
NFS_PAGE_TAG_LOCKED);
- ret = test_bit(PG_NEED_FLUSH, &req->wb_flags);
spin_unlock(&inode->i_lock);
nfs_pageio_add_request(pgio, req);
- return ret;
+ return 0;
}
-/*
- * Write an mmapped page to the server.
- */
-static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc)
+static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio)
{
- struct nfs_pageio_descriptor mypgio, *pgio;
- struct nfs_open_context *ctx;
struct inode *inode = page->mapping->host;
- unsigned offset;
- int err;
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);
- if (wbc->for_writepages)
- pgio = wbc->fs_private;
- else {
- nfs_pageio_init_write(&mypgio, inode, wb_priority(wbc));
- pgio = &mypgio;
- }
-
nfs_pageio_cond_complete(pgio, page->index);
+ return nfs_page_async_flush(pgio, page);
+}
- err = nfs_page_async_flush(pgio, page);
- if (err <= 0)
- goto out;
- err = 0;
- offset = nfs_page_length(page);
- if (!offset)
- goto out;
-
- nfs_pageio_cond_complete(pgio, page->index);
+/*
+ * Write an mmapped page to the server.
+ */
+static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc)
+{
+ struct nfs_pageio_descriptor pgio;
+ int err;
- ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
- if (ctx == NULL) {
- err = -EBADF;
- goto out;
- }
- err = nfs_writepage_setup(ctx, page, 0, offset);
- put_nfs_open_context(ctx);
- if (err != 0)
- goto out;
- err = nfs_page_async_flush(pgio, page);
- if (err > 0)
- err = 0;
-out:
- if (!wbc->for_writepages)
- nfs_pageio_complete(pgio);
- return err;
+ nfs_pageio_init_write(&pgio, page->mapping->host, wb_priority(wbc));
+ err = nfs_do_writepage(page, wbc, &pgio);
+ nfs_pageio_complete(&pgio);
+ if (err < 0)
+ return err;
+ if (pgio.pg_error < 0)
+ return pgio.pg_error;
+ return 0;
}
int nfs_writepage(struct page *page, struct writeback_control *wbc)
{
- int err;
+ int ret;
+
+ ret = nfs_writepage_locked(page, wbc);
+ unlock_page(page);
+ return ret;
+}
+
+static int nfs_writepages_callback(struct page *page, struct writeback_control *wbc, void *data)
+{
+ int ret;
- err = nfs_writepage_locked(page, wbc);
+ ret = nfs_do_writepage(page, wbc, data);
unlock_page(page);
- return err;
+ return ret;
}
int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
@@ -365,12 +353,11 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
nfs_pageio_init_write(&pgio, inode, wb_priority(wbc));
- wbc->fs_private = &pgio;
- err = generic_writepages(mapping, wbc);
+ err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
nfs_pageio_complete(&pgio);
- if (err)
+ if (err < 0)
return err;
- if (pgio.pg_error)
+ if (pgio.pg_error < 0)
return pgio.pg_error;
return 0;
}
@@ -389,14 +376,11 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
return error;
if (!nfsi->npages) {
igrab(inode);
- nfs_begin_data_update(inode);
if (nfs_have_delegation(inode, FMODE_WRITE))
nfsi->change_attr++;
}
SetPagePrivate(req->wb_page);
set_page_private(req->wb_page, (unsigned long)req);
- if (PageDirty(req->wb_page))
- set_bit(PG_NEED_FLUSH, &req->wb_flags);
nfsi->npages++;
kref_get(&req->wb_kref);
return 0;
@@ -416,12 +400,9 @@ static void nfs_inode_remove_request(struct nfs_page *req)
set_page_private(req->wb_page, 0);
ClearPagePrivate(req->wb_page);
radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
- if (test_and_clear_bit(PG_NEED_FLUSH, &req->wb_flags))
- __set_page_dirty_nobuffers(req->wb_page);
nfsi->npages--;
if (!nfsi->npages) {
spin_unlock(&inode->i_lock);
- nfs_end_data_update(inode);
iput(inode);
} else
spin_unlock(&inode->i_lock);
@@ -466,6 +447,7 @@ nfs_mark_request_commit(struct nfs_page *req)
NFS_PAGE_TAG_COMMIT);
spin_unlock(&inode->i_lock);
inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
+ inc_bdi_stat(req->wb_page->mapping->backing_dev_info, BDI_RECLAIMABLE);
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
}
@@ -552,6 +534,8 @@ static void nfs_cancel_commit_list(struct list_head *head)
while(!list_empty(head)) {
req = nfs_list_entry(head->next);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
+ dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
nfs_list_remove_request(req);
clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
nfs_inode_remove_request(req);
@@ -682,7 +666,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
int nfs_flush_incompatible(struct file *file, struct page *page)
{
- struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
+ struct nfs_open_context *ctx = nfs_file_open_context(file);
struct nfs_page *req;
int do_flush, status;
/*
@@ -716,7 +700,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
int nfs_updatepage(struct file *file, struct page *page,
unsigned int offset, unsigned int count)
{
- struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
+ struct nfs_open_context *ctx = nfs_file_open_context(file);
struct inode *inode = page->mapping->host;
int status = 0;
@@ -967,7 +951,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
if (task->tk_status < 0) {
nfs_set_pageerror(page);
- req->wb_context->error = task->tk_status;
+ nfs_context_set_write_error(req->wb_context, task->tk_status);
dprintk(", error = %d\n", task->tk_status);
goto out;
}
@@ -1030,7 +1014,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
if (task->tk_status < 0) {
nfs_set_pageerror(page);
- req->wb_context->error = task->tk_status;
+ nfs_context_set_write_error(req->wb_context, task->tk_status);
dprintk(", error = %d\n", task->tk_status);
goto remove_request;
}
@@ -1212,6 +1196,8 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
nfs_list_remove_request(req);
nfs_mark_request_commit(req);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
+ dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
nfs_clear_page_tag_locked(req);
}
return -ENOMEM;
@@ -1237,6 +1223,8 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
nfs_list_remove_request(req);
clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
+ dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
dprintk("NFS: commit (%s/%Ld %d@%Ld)",
req->wb_context->path.dentry->d_inode->i_sb->s_id,
@@ -1244,7 +1232,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
req->wb_bytes,
(long long)req_offset(req));
if (task->tk_status < 0) {
- req->wb_context->error = task->tk_status;
+ nfs_context_set_write_error(req->wb_context, task->tk_status);
nfs_inode_remove_request(req);
dprintk(", error = %d\n", task->tk_status);
goto next;
@@ -1347,53 +1335,52 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
return ret;
}
-/*
- * flush the inode to disk.
- */
-int nfs_wb_all(struct inode *inode)
+static int __nfs_write_mapping(struct address_space *mapping, struct writeback_control *wbc, int how)
{
- struct address_space *mapping = inode->i_mapping;
- struct writeback_control wbc = {
- .bdi = mapping->backing_dev_info,
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = LONG_MAX,
- .for_writepages = 1,
- .range_cyclic = 1,
- };
int ret;
- ret = nfs_writepages(mapping, &wbc);
+ ret = nfs_writepages(mapping, wbc);
if (ret < 0)
goto out;
- ret = nfs_sync_mapping_wait(mapping, &wbc, 0);
- if (ret >= 0)
- return 0;
+ ret = nfs_sync_mapping_wait(mapping, wbc, how);
+ if (ret < 0)
+ goto out;
+ return 0;
out:
__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
return ret;
}
-int nfs_sync_mapping_range(struct address_space *mapping, loff_t range_start, loff_t range_end, int how)
+/* Two pass sync: first using WB_SYNC_NONE, then WB_SYNC_ALL */
+static int nfs_write_mapping(struct address_space *mapping, int how)
{
struct writeback_control wbc = {
.bdi = mapping->backing_dev_info,
- .sync_mode = WB_SYNC_ALL,
+ .sync_mode = WB_SYNC_NONE,
.nr_to_write = LONG_MAX,
- .range_start = range_start,
- .range_end = range_end,
.for_writepages = 1,
+ .range_cyclic = 1,
};
int ret;
- ret = nfs_writepages(mapping, &wbc);
+ ret = __nfs_write_mapping(mapping, &wbc, how);
if (ret < 0)
- goto out;
- ret = nfs_sync_mapping_wait(mapping, &wbc, how);
- if (ret >= 0)
- return 0;
-out:
- __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
- return ret;
+ return ret;
+ wbc.sync_mode = WB_SYNC_ALL;
+ return __nfs_write_mapping(mapping, &wbc, how);
+}
+
+/*
+ * flush the inode to disk.
+ */
+int nfs_wb_all(struct inode *inode)
+{
+ return nfs_write_mapping(inode->i_mapping, 0);
+}
+
+int nfs_wb_nocommit(struct inode *inode)
+{
+ return nfs_write_mapping(inode->i_mapping, FLUSH_NOCOMMIT);
}
int nfs_wb_page_cancel(struct inode *inode, struct page *page)
@@ -1477,35 +1464,6 @@ int nfs_wb_page(struct inode *inode, struct page* page)
return nfs_wb_page_priority(inode, page, FLUSH_STABLE);
}
-int nfs_set_page_dirty(struct page *page)
-{
- struct address_space *mapping = page->mapping;
- struct inode *inode;
- struct nfs_page *req;
- int ret;
-
- if (!mapping)
- goto out_raced;
- inode = mapping->host;
- if (!inode)
- goto out_raced;
- spin_lock(&inode->i_lock);
- req = nfs_page_find_request_locked(page);
- if (req != NULL) {
- /* Mark any existing write requests for flushing */
- ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags);
- spin_unlock(&inode->i_lock);
- nfs_release_request(req);
- return ret;
- }
- ret = __set_page_dirty_nobuffers(page);
- spin_unlock(&inode->i_lock);
- return ret;
-out_raced:
- return !TestSetPageDirty(page);
-}
-
-
int __init nfs_init_writepagecache(void)
{
nfs_wdata_cachep = kmem_cache_create("nfs_write_data",
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index cba899a3494..04b26672980 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -861,9 +861,9 @@ exp_get_fsid_key(svc_client *clp, int fsid)
return exp_find_key(clp, FSID_NUM, fsidv, NULL);
}
-svc_export *
-exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
- struct cache_req *reqp)
+static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
+ struct dentry *dentry,
+ struct cache_req *reqp)
{
struct svc_export *exp, key;
int err;
@@ -887,9 +887,9 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
/*
* Find the export entry for a given dentry.
*/
-struct svc_export *
-exp_parent(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
- struct cache_req *reqp)
+static struct svc_export *exp_parent(svc_client *clp, struct vfsmount *mnt,
+ struct dentry *dentry,
+ struct cache_req *reqp)
{
svc_export *exp;
@@ -1214,9 +1214,8 @@ out:
return err;
}
-struct svc_export *
-exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
- struct cache_req *reqp)
+static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
+ u32 *fsidv, struct cache_req *reqp)
{
struct svc_export *exp;
struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6f182d25793..31673cd251c 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2035,7 +2035,7 @@ static inline int
io_during_grace_disallowed(struct inode *inode, int flags)
{
return nfs4_in_grace() && (flags & (RD_STATE | WR_STATE))
- && MANDATORY_LOCK(inode);
+ && mandatory_lock(inode);
}
/*
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index e15f2cf8ac1..57333944af7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -102,7 +102,8 @@ check_filename(char *str, int len, __be32 err)
out: \
return status; \
xdr_error: \
- printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); \
+ dprintk("NFSD: xdr error (%s:%d)\n", \
+ __FILE__, __LINE__); \
status = nfserr_bad_xdr; \
goto out
@@ -124,7 +125,8 @@ xdr_error: \
if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
savemem(argp, p, nbytes) : \
(char *)p)) { \
- printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); \
+ dprintk("NFSD: xdr error (%s:%d)\n", \
+ __FILE__, __LINE__); \
goto xdr_error; \
} \
p += XDR_QUADLEN(nbytes); \
@@ -140,7 +142,8 @@ xdr_error: \
p = argp->p; \
argp->p += XDR_QUADLEN(nbytes); \
} else if (!(p = read_buf(argp, nbytes))) { \
- printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); \
+ dprintk("NFSD: xdr error (%s:%d)\n", \
+ __FILE__, __LINE__); \
goto xdr_error; \
} \
} while (0)
@@ -948,7 +951,8 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
*/
avail = (char*)argp->end - (char*)argp->p;
if (avail + argp->pagelen < write->wr_buflen) {
- printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__);
+ dprintk("NFSD: xdr error (%s:%d)\n",
+ __FILE__, __LINE__);
goto xdr_error;
}
argp->rqstp->rq_vec[0].iov_base = p;
@@ -1019,7 +1023,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
if (!argp->ops) {
argp->ops = argp->iops;
- printk(KERN_INFO "nfsd: couldn't allocate room for COMPOUND\n");
+ dprintk("nfsd: couldn't allocate room for COMPOUND\n");
goto xdr_error;
}
}
@@ -1326,7 +1330,7 @@ static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *
path = exp->ex_path;
if (strncmp(path, rootpath, strlen(rootpath))) {
- printk("nfsd: fs_locations failed;"
+ dprintk("nfsd: fs_locations failed;"
"%s is not contained in %s\n", path, rootpath);
*stat = nfserr_notsupp;
return NULL;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index cec78c82b1f..46934c97f8f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -61,12 +61,6 @@
#define NFSDDBG_FACILITY NFSDDBG_FILEOP
-/* We must ignore files (but only files) which might have mandatory
- * locks on them because there is no way to know if the accesser has
- * the lock.
- */
-#define IS_ISMNDLK(i) (S_ISREG((i)->i_mode) && MANDATORY_LOCK(i))
-
/*
* This is a cache of readahead params that help us choose the proper
* readahead strategy. Initially, we set all readahead parameters to 0
@@ -370,14 +364,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
if (iap->ia_valid & ATTR_MODE) {
iap->ia_mode &= S_IALLUGO;
imode = iap->ia_mode |= (imode & ~S_IALLUGO);
+ /* if changing uid/gid revoke setuid/setgid in mode */
+ if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) {
+ iap->ia_valid |= ATTR_KILL_PRIV;
+ iap->ia_mode &= ~S_ISUID;
+ }
+ if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
+ iap->ia_mode &= ~S_ISGID;
+ } else {
+ /*
+ * Revoke setuid/setgid bit on chown/chgrp
+ */
+ if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
+ iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV;
+ if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
+ iap->ia_valid |= ATTR_KILL_SGID;
}
- /* Revoke setuid/setgid bit on chown/chgrp */
- if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid)
- iap->ia_valid |= ATTR_KILL_SUID;
- if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid)
- iap->ia_valid |= ATTR_KILL_SGID;
-
/* Change the attributes. */
iap->ia_valid |= ATTR_CTIME;
@@ -689,7 +692,12 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
err = nfserr_perm;
if (IS_APPEND(inode) && (access & MAY_WRITE))
goto out;
- if (IS_ISMNDLK(inode))
+ /*
+ * We must ignore files (but only files) which might have mandatory
+ * locks on them because there is no way to know if the accesser has
+ * the lock.
+ */
+ if (S_ISREG((inode)->i_mode) && mandatory_lock(inode))
goto out;
if (!inode->i_fop)
@@ -866,6 +874,15 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
}
+static inline int svc_msnfs(struct svc_fh *ffhp)
+{
+#ifdef MSNFS
+ return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
+#else
+ return 0;
+#endif
+}
+
static __be32
nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -878,11 +895,9 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
err = nfserr_perm;
inode = file->f_path.dentry->d_inode;
-#ifdef MSNFS
- if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
- (!lock_may_read(inode, offset, *count)))
+
+ if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
goto out;
-#endif
/* Get readahead parameters */
ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
@@ -931,7 +946,7 @@ out:
static void kill_suid(struct dentry *dentry)
{
struct iattr ia;
- ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
+ ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
mutex_lock(&dentry->d_inode->i_mutex);
notify_change(dentry, &ia);
diff --git a/fs/nls/Kconfig b/fs/nls/Kconfig
index 976ecccd6f5..a39edc41bec 100644
--- a/fs/nls/Kconfig
+++ b/fs/nls/Kconfig
@@ -2,10 +2,8 @@
# Native language support configuration
#
-menu "Native Language Support"
-
-config NLS
- tristate "Base native language support"
+menuconfig NLS
+ tristate "Native language support"
---help---
The base Native Language Support. A number of filesystems
depend on it (e.g. FAT, JOLIET, NT, BEOS filesystems), as well
@@ -17,9 +15,10 @@ config NLS
To compile this code as a module, choose M here: the module
will be called nls_base.
+if NLS
+
config NLS_DEFAULT
string "Default NLS Option"
- depends on NLS
default "iso8859-1"
---help---
The default NLS used when mounting file system. Note, that this is
@@ -39,7 +38,6 @@ config NLS_DEFAULT
config NLS_CODEPAGE_437
tristate "Codepage 437 (United States, Canada)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored
@@ -52,7 +50,6 @@ config NLS_CODEPAGE_437
config NLS_CODEPAGE_737
tristate "Codepage 737 (Greek)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored
@@ -65,7 +62,6 @@ config NLS_CODEPAGE_737
config NLS_CODEPAGE_775
tristate "Codepage 775 (Baltic Rim)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored
@@ -79,7 +75,6 @@ config NLS_CODEPAGE_775
config NLS_CODEPAGE_850
tristate "Codepage 850 (Europe)"
- depends on NLS
---help---
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -96,7 +91,6 @@ config NLS_CODEPAGE_850
config NLS_CODEPAGE_852
tristate "Codepage 852 (Central/Eastern Europe)"
- depends on NLS
---help---
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -112,7 +106,6 @@ config NLS_CODEPAGE_852
config NLS_CODEPAGE_855
tristate "Codepage 855 (Cyrillic)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -124,7 +117,6 @@ config NLS_CODEPAGE_855
config NLS_CODEPAGE_857
tristate "Codepage 857 (Turkish)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -136,7 +128,6 @@ config NLS_CODEPAGE_857
config NLS_CODEPAGE_860
tristate "Codepage 860 (Portuguese)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -148,7 +139,6 @@ config NLS_CODEPAGE_860
config NLS_CODEPAGE_861
tristate "Codepage 861 (Icelandic)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -160,7 +150,6 @@ config NLS_CODEPAGE_861
config NLS_CODEPAGE_862
tristate "Codepage 862 (Hebrew)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -172,7 +161,6 @@ config NLS_CODEPAGE_862
config NLS_CODEPAGE_863
tristate "Codepage 863 (Canadian French)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -185,7 +173,6 @@ config NLS_CODEPAGE_863
config NLS_CODEPAGE_864
tristate "Codepage 864 (Arabic)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -197,7 +184,6 @@ config NLS_CODEPAGE_864
config NLS_CODEPAGE_865
tristate "Codepage 865 (Norwegian, Danish)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -210,7 +196,6 @@ config NLS_CODEPAGE_865
config NLS_CODEPAGE_866
tristate "Codepage 866 (Cyrillic/Russian)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -223,7 +208,6 @@ config NLS_CODEPAGE_866
config NLS_CODEPAGE_869
tristate "Codepage 869 (Greek)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -235,7 +219,6 @@ config NLS_CODEPAGE_869
config NLS_CODEPAGE_936
tristate "Simplified Chinese charset (CP936, GB2312)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -248,7 +231,6 @@ config NLS_CODEPAGE_936
config NLS_CODEPAGE_950
tristate "Traditional Chinese charset (Big5)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -261,7 +243,6 @@ config NLS_CODEPAGE_950
config NLS_CODEPAGE_932
tristate "Japanese charsets (Shift-JIS, EUC-JP)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -275,7 +256,6 @@ config NLS_CODEPAGE_932
config NLS_CODEPAGE_949
tristate "Korean charset (CP949, EUC-KR)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -287,7 +267,6 @@ config NLS_CODEPAGE_949
config NLS_CODEPAGE_874
tristate "Thai charset (CP874, TIS-620)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -299,7 +278,6 @@ config NLS_CODEPAGE_874
config NLS_ISO8859_8
tristate "Hebrew charsets (ISO-8859-8, CP1255)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -309,7 +287,6 @@ config NLS_ISO8859_8
config NLS_CODEPAGE_1250
tristate "Windows CP1250 (Slavic/Central European Languages)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CDROMs
@@ -321,7 +298,6 @@ config NLS_CODEPAGE_1250
config NLS_CODEPAGE_1251
tristate "Windows CP1251 (Bulgarian, Belarusian)"
- depends on NLS
help
The Microsoft FAT file system family can deal with filenames in
native language character sets. These character sets are stored in
@@ -334,7 +310,6 @@ config NLS_CODEPAGE_1251
config NLS_ASCII
tristate "ASCII (United States)"
- depends on NLS
help
An ASCII NLS module is needed if you want to override the
DEFAULT NLS with this very basic charset and don't want any
@@ -342,7 +317,6 @@ config NLS_ASCII
config NLS_ISO8859_1
tristate "NLS ISO 8859-1 (Latin 1; Western European Languages)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -355,7 +329,6 @@ config NLS_ISO8859_1
config NLS_ISO8859_2
tristate "NLS ISO 8859-2 (Latin 2; Slavic/Central European Languages)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -367,7 +340,6 @@ config NLS_ISO8859_2
config NLS_ISO8859_3
tristate "NLS ISO 8859-3 (Latin 3; Esperanto, Galician, Maltese, Turkish)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -378,7 +350,6 @@ config NLS_ISO8859_3
config NLS_ISO8859_4
tristate "NLS ISO 8859-4 (Latin 4; old Baltic charset)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -389,7 +360,6 @@ config NLS_ISO8859_4
config NLS_ISO8859_5
tristate "NLS ISO 8859-5 (Cyrillic)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -401,7 +371,6 @@ config NLS_ISO8859_5
config NLS_ISO8859_6
tristate "NLS ISO 8859-6 (Arabic)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -411,7 +380,6 @@ config NLS_ISO8859_6
config NLS_ISO8859_7
tristate "NLS ISO 8859-7 (Modern Greek)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -421,7 +389,6 @@ config NLS_ISO8859_7
config NLS_ISO8859_9
tristate "NLS ISO 8859-9 (Latin 5; Turkish)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -432,7 +399,6 @@ config NLS_ISO8859_9
config NLS_ISO8859_13
tristate "NLS ISO 8859-13 (Latin 7; Baltic)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -443,7 +409,6 @@ config NLS_ISO8859_13
config NLS_ISO8859_14
tristate "NLS ISO 8859-14 (Latin 8; Celtic)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -455,7 +420,6 @@ config NLS_ISO8859_14
config NLS_ISO8859_15
tristate "NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)"
- depends on NLS
---help---
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -472,7 +436,6 @@ config NLS_ISO8859_15
config NLS_KOI8_R
tristate "NLS KOI8-R (Russian)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -482,7 +445,6 @@ config NLS_KOI8_R
config NLS_KOI8_U
tristate "NLS KOI8-U/RU (Ukrainian, Belarusian)"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -492,7 +454,6 @@ config NLS_KOI8_U
config NLS_UTF8
tristate "NLS UTF-8"
- depends on NLS
help
If you want to display filenames with native language characters
from the Microsoft FAT file system family or from JOLIET CD-ROMs
@@ -500,5 +461,4 @@ config NLS_UTF8
input/output character sets. Say Y here for the UTF-8 encoding of
the Unicode/ISO9646 universal character set.
-endmenu
-
+endif # NLS
diff --git a/fs/nls/nls_ascii.c b/fs/nls/nls_ascii.c
index 6993faea28a..7020e940f74 100644
--- a/fs/nls/nls_ascii.c
+++ b/fs/nls/nls_ascii.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -56,7 +56,7 @@ static wchar_t charset2uni[256] = {
0x007c, 0x007d, 0x007e, 0x007f,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -75,11 +75,11 @@ static unsigned char page00[256] = {
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -98,7 +98,7 @@ static unsigned char charset2lower[256] = {
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -119,7 +119,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 7dfdab98729..64965e1c21c 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -34,7 +34,7 @@ struct utf8_table {
long lval;
};
-static struct utf8_table utf8_table[] =
+static const struct utf8_table utf8_table[] =
{
{0x80, 0x00, 0*6, 0x7F, 0, /* 1 byte sequence */},
{0xE0, 0xC0, 1*6, 0x7FF, 0x80, /* 2 byte sequence */},
@@ -50,7 +50,7 @@ utf8_mbtowc(wchar_t *p, const __u8 *s, int n)
{
long l;
int c0, c, nc;
- struct utf8_table *t;
+ const struct utf8_table *t;
nc = 0;
c0 = *s;
@@ -109,9 +109,9 @@ utf8_wctomb(__u8 *s, wchar_t wc, int maxlen)
{
long l;
int c, nc;
- struct utf8_table *t;
+ const struct utf8_table *t;
- if (s == 0)
+ if (!s)
return 0;
l = wc;
@@ -240,7 +240,7 @@ void unload_nls(struct nls_table *nls)
module_put(nls->owner);
}
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -323,7 +323,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x00fd, 0x00fe, 0x00ff,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -359,11 +359,11 @@ static unsigned char page00[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -399,7 +399,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -438,7 +438,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp1250.c b/fs/nls/nls_cp1250.c
index 570aa69846a..c8471fe78e4 100644
--- a/fs/nls/nls_cp1250.c
+++ b/fs/nls/nls_cp1250.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x00fd, 0x0163, 0x02d9,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0xc3, 0xe3, 0xa5, 0xb9, 0xc6, 0xe6, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */
0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -152,7 +152,7 @@ static unsigned char page01[256] = {
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page02[256] = {
0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -210,7 +210,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
};
-static unsigned char page21[256] = {
+static const unsigned char page21[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -218,7 +218,7 @@ static unsigned char page21[256] = {
0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, page02, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -226,7 +226,7 @@ static unsigned char *page_uni2charset[256] = {
page20, page21, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -262,7 +262,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -300,7 +300,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp1251.c b/fs/nls/nls_cp1251.c
index f114afa069d..1939b46e772 100644
--- a/fs/nls/nls_cp1251.c
+++ b/fs/nls/nls_cp1251.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x044c, 0x044d, 0x044e, 0x044f,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page04[256] = {
+static const unsigned char page04[256] = {
0x00, 0xa8, 0x80, 0x81, 0xaa, 0xbd, 0xb2, 0xaf, /* 0x00-0x07 */
0xa3, 0x8a, 0x8c, 0x8e, 0x8d, 0x00, 0xa1, 0x8f, /* 0x08-0x0f */
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */
@@ -155,7 +155,7 @@ static unsigned char page04[256] = {
0x00, 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -166,7 +166,7 @@ static unsigned char page20[256] = {
0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
};
-static unsigned char page21[256] = {
+static const unsigned char page21[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */
@@ -174,7 +174,7 @@ static unsigned char page21[256] = {
0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -182,7 +182,7 @@ static unsigned char *page_uni2charset[256] = {
page20, page21, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -217,7 +217,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -254,7 +254,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp1255.c b/fs/nls/nls_cp1255.c
index e57f2cbf5bc..8120ae2e091 100644
--- a/fs/nls/nls_cp1255.c
+++ b/fs/nls/nls_cp1255.c
@@ -11,7 +11,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -94,7 +94,7 @@ static wchar_t charset2uni[256] = {
0x0000, 0x0000, 0x0000, 0x0000,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -129,7 +129,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -152,7 +152,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
};
-static unsigned char page05[256] = {
+static const unsigned char page05[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -219,7 +219,7 @@ static unsigned char page05[256] = {
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfe, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -245,7 +245,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0xa4, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
};
-static unsigned char page21[256] = {
+static const unsigned char page21[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */
@@ -253,7 +253,7 @@ static unsigned char page21[256] = {
0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, page02, NULL, NULL, page05, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -261,7 +261,7 @@ static unsigned char *page_uni2charset[256] = {
page20, page21, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -297,7 +297,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -335,7 +335,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp437.c b/fs/nls/nls_cp437.c
index d41930ce4a4..ff37a4628ce 100644
--- a/fs/nls/nls_cp437.c
+++ b/fs/nls/nls_cp437.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -155,7 +155,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page03[256] = {
0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -209,7 +209,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -225,7 +225,7 @@ static unsigned char page22[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -233,7 +233,7 @@ static unsigned char page23[256] = {
0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -258,7 +258,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -266,7 +266,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -302,7 +302,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -340,7 +340,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp737.c b/fs/nls/nls_cp737.c
index d21f8790aa1..f5576b8be1b 100644
--- a/fs/nls/nls_cp737.c
+++ b/fs/nls/nls_cp737.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -131,7 +131,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -161,7 +161,7 @@ static unsigned char page03[256] = {
0xaf, 0xe0, 0xe4, 0xe8, 0xe6, 0xe7, 0xe9, 0x00, /* 0xc8-0xcf */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -180,7 +180,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -196,7 +196,7 @@ static unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -221,7 +221,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -229,7 +229,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -265,7 +265,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -303,7 +303,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp775.c b/fs/nls/nls_cp775.c
index c97714c38a9..4905635d1c0 100644
--- a/fs/nls/nls_cp775.c
+++ b/fs/nls/nls_cp775.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00b3, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x9b, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0xa0, 0x83, 0x00, 0x00, 0xb5, 0xd0, 0x80, 0x87, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xb6, 0xd1, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0xed, 0x89, 0x00, 0x00, 0xb8, 0xd3, /* 0x10-0x17 */
@@ -151,21 +151,21 @@ static unsigned char page01[256] = {
0x00, 0x8d, 0xa5, 0xa3, 0xa4, 0xcf, 0xd8, 0x00, /* 0x78-0x7f */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
0x00, 0xef, 0x00, 0x00, 0xf2, 0xa6, 0xf7, 0x00, /* 0x18-0x1f */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -190,7 +190,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -198,7 +198,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -234,7 +234,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -272,7 +272,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp850.c b/fs/nls/nls_cp850.c
index 843b7d975ba..fe5bdad50e2 100644
--- a/fs/nls/nls_cp850.c
+++ b/fs/nls/nls_cp850.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00b3, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x9b, 0x97, 0xa3, 0x96, 0x81, 0xec, 0xe7, 0x98, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -155,13 +155,13 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, /* 0x10-0x17 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -186,7 +186,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -194,7 +194,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, NULL, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -230,7 +230,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -268,7 +268,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp852.c b/fs/nls/nls_cp852.c
index 83cfd844d5c..ceb1c0166dd 100644
--- a/fs/nls/nls_cp852.c
+++ b/fs/nls/nls_cp852.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x0158, 0x0159, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0xa3, 0x00, 0x81, 0xec, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0xc6, 0xc7, 0xa4, 0xa5, 0x8f, 0x86, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xac, 0x9f, 0xd2, 0xd4, /* 0x08-0x0f */
0xd1, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -151,7 +151,7 @@ static unsigned char page01[256] = {
0x00, 0x8d, 0xab, 0xbd, 0xbe, 0xa6, 0xa7, 0x00, /* 0x78-0x7f */
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -183,7 +183,7 @@ static unsigned char page02[256] = {
0xf4, 0xfa, 0x00, 0xf2, 0x00, 0xf1, 0x00, 0x00, /* 0xd8-0xdf */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -208,7 +208,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, page02, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -216,7 +216,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -252,7 +252,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfd, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -290,7 +290,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp855.c b/fs/nls/nls_cp855.c
index 9190b7b574f..cc7f5fb2e0c 100644
--- a/fs/nls/nls_cp855.c
+++ b/fs/nls/nls_cp855.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x0427, 0x00a7, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -124,7 +124,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
};
-static unsigned char page04[256] = {
+static const unsigned char page04[256] = {
0x00, 0x85, 0x81, 0x83, 0x87, 0x89, 0x8b, 0x8d, /* 0x00-0x07 */
0x8f, 0x91, 0x93, 0x95, 0x97, 0x00, 0x99, 0x9b, /* 0x08-0x0f */
0xa1, 0xa3, 0xec, 0xad, 0xa7, 0xa9, 0xea, 0xf4, /* 0x10-0x17 */
@@ -139,13 +139,13 @@ static unsigned char page04[256] = {
0x8e, 0x90, 0x92, 0x94, 0x96, 0x00, 0x98, 0x9a, /* 0x58-0x5f */
};
-static unsigned char page21[256] = {
+static const unsigned char page21[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, /* 0x10-0x17 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -170,7 +170,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -178,7 +178,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, page21, NULL, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -214,7 +214,7 @@ static unsigned char charset2lower[256] = {
0xf7, 0xf9, 0xf9, 0xfb, 0xfb, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -252,7 +252,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp857.c b/fs/nls/nls_cp857.c
index ef3d36db808..e418e198e8d 100644
--- a/fs/nls/nls_cp857.c
+++ b/fs/nls/nls_cp857.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00b3, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x9b, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0xed, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -147,7 +147,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x9f, /* 0x58-0x5f */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -172,7 +172,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -180,7 +180,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -216,7 +216,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -254,7 +254,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp860.c b/fs/nls/nls_cp860.c
index 7e2fb664589..a86c97d1aa3 100644
--- a/fs/nls/nls_cp860.c
+++ b/fs/nls/nls_cp860.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x97, 0xa3, 0x00, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -161,7 +161,7 @@ static unsigned char page03[256] = {
0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -186,7 +186,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -202,7 +202,7 @@ static unsigned char page22[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -210,7 +210,7 @@ static unsigned char page23[256] = {
0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -235,7 +235,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -243,7 +243,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -279,7 +279,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -317,7 +317,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp861.c b/fs/nls/nls_cp861.c
index 66d8d808ccf..bd920227acd 100644
--- a/fs/nls/nls_cp861.c
+++ b/fs/nls/nls_cp861.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x9b, 0x00, 0xa3, 0x96, 0x81, 0x98, 0x95, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -155,7 +155,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page03[256] = {
0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -209,7 +209,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -225,7 +225,7 @@ static unsigned char page22[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -233,7 +233,7 @@ static unsigned char page23[256] = {
0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -258,7 +258,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -266,7 +266,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -302,7 +302,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -340,7 +340,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp862.c b/fs/nls/nls_cp862.c
index 360ba388485..e9b68eb3daf 100644
--- a/fs/nls/nls_cp862.c
+++ b/fs/nls/nls_cp862.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -155,7 +155,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page03[256] = {
0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page05[256] = {
+static const unsigned char page05[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -218,7 +218,7 @@ static unsigned char page05[256] = {
0x98, 0x99, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -243,7 +243,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -259,7 +259,7 @@ static unsigned char page22[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -267,7 +267,7 @@ static unsigned char page23[256] = {
0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -292,7 +292,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, page03, NULL, page05, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -300,7 +300,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -336,7 +336,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -374,7 +374,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp863.c b/fs/nls/nls_cp863.c
index 656a93113e3..f8a9b07ab4e 100644
--- a/fs/nls/nls_cp863.c
+++ b/fs/nls/nls_cp863.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -155,7 +155,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page03[256] = {
0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, /* 0x10-0x17 */
@@ -203,7 +203,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, /* 0x78-0x7f */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -219,7 +219,7 @@ static unsigned char page22[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -227,7 +227,7 @@ static unsigned char page23[256] = {
0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -252,7 +252,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -260,7 +260,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -296,7 +296,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -334,7 +334,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp864.c b/fs/nls/nls_cp864.c
index 01ca7309753..8d31f435fc6 100644
--- a/fs/nls/nls_cp864.c
+++ b/fs/nls/nls_cp864.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0xfed9, 0xfef1, 0x25a0, 0x0000,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -131,7 +131,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, /* 0xf0-0xf7 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -160,7 +160,7 @@ static unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page06[256] = {
+static const unsigned char page06[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -177,7 +177,7 @@ static unsigned char page06[256] = {
0xb8, 0xb9, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -190,7 +190,7 @@ static unsigned char page22[256] = {
0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0x85, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x8c, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -215,7 +215,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char pagefe[256] = {
+static const unsigned char pagefe[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -251,7 +251,7 @@ static unsigned char pagefe[256] = {
0x9a, 0x00, 0x00, 0x9d, 0x9e, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, page03, NULL, NULL, page06, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -286,7 +286,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, pagefe, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -322,7 +322,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -360,7 +360,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp865.c b/fs/nls/nls_cp865.c
index 5ba6ee13e10..4bd902fe3ec 100644
--- a/fs/nls/nls_cp865.c
+++ b/fs/nls/nls_cp865.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x207f, 0x00b2, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x9b, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -155,7 +155,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -184,7 +184,7 @@ static unsigned char page03[256] = {
0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -209,7 +209,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xa0-0xa7 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -225,7 +225,7 @@ static unsigned char page22[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -233,7 +233,7 @@ static unsigned char page23[256] = {
0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -258,7 +258,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -266,7 +266,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -302,7 +302,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -340,7 +340,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp866.c b/fs/nls/nls_cp866.c
index c5f82221c9f..bdc7cb39139 100644
--- a/fs/nls/nls_cp866.c
+++ b/fs/nls/nls_cp866.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x2116, 0x00a4, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -123,7 +123,7 @@ static unsigned char page00[256] = {
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */
};
-static unsigned char page04[256] = {
+static const unsigned char page04[256] = {
0x00, 0xf0, 0x00, 0x00, 0xf2, 0x00, 0x00, 0xf4, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, /* 0x08-0x0f */
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */
@@ -138,20 +138,20 @@ static unsigned char page04[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, /* 0x58-0x5f */
};
-static unsigned char page21[256] = {
+static const unsigned char page21[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, /* 0x10-0x17 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -176,7 +176,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -184,7 +184,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, page21, page22, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -220,7 +220,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -258,7 +258,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp869.c b/fs/nls/nls_cp869.c
index 8d4015124d1..9f283a2b151 100644
--- a/fs/nls/nls_cp869.c
+++ b/fs/nls/nls_cp869.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x03b0, 0x03ce, 0x25a0, 0x00a0,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -124,7 +124,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0xaf, 0x00, 0xab, 0x00, 0x00, /* 0xb8-0xbf */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -154,14 +154,14 @@ static unsigned char page03[256] = {
0xf6, 0xfa, 0xa0, 0xfb, 0xa2, 0xa3, 0xfd, 0x00, /* 0xc8-0xcf */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, /* 0x10-0x17 */
0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -186,7 +186,7 @@ static unsigned char page25[256] = {
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -194,7 +194,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, NULL, NULL, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -230,7 +230,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -268,7 +268,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp874.c b/fs/nls/nls_cp874.c
index df042052c2d..0b3c4886f8c 100644
--- a/fs/nls/nls_cp874.c
+++ b/fs/nls/nls_cp874.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x0000, 0x0000, 0x0000, 0x0000,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -121,7 +121,7 @@ static unsigned char page00[256] = {
0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char page0e[256] = {
+static const unsigned char page0e[256] = {
0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x08-0x0f */
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */
@@ -136,7 +136,7 @@ static unsigned char page0e[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -144,7 +144,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, page0e, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -152,7 +152,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -188,7 +188,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -226,7 +226,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_cp932.c b/fs/nls/nls_cp932.c
index 2a9ccf3bc7e..0ffed6f1ceb 100644
--- a/fs/nls/nls_cp932.c
+++ b/fs/nls/nls_cp932.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t c2u_81[256] = {
+static const wchar_t c2u_81[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -49,7 +49,7 @@ static wchar_t c2u_81[256] = {
0x0000,0x0000,0x0000,0x0000,0x25EF,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_82[256] = {
+static const wchar_t c2u_82[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -84,7 +84,7 @@ static wchar_t c2u_82[256] = {
0x3092,0x3093,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_83[256] = {
+static const wchar_t c2u_83[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -115,7 +115,7 @@ static wchar_t c2u_83[256] = {
0x03C3,0x03C4,0x03C5,0x03C6,0x03C7,0x03C8,0x03C9,0x0000,/* 0xD0-0xD7 */
};
-static wchar_t c2u_84[256] = {
+static const wchar_t c2u_84[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -143,7 +143,7 @@ static wchar_t c2u_84[256] = {
0x2537,0x253F,0x251D,0x2530,0x2525,0x2538,0x2542,0x0000,/* 0xB8-0xBF */
};
-static wchar_t c2u_87[256] = {
+static const wchar_t c2u_87[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -167,7 +167,7 @@ static wchar_t c2u_87[256] = {
0x221F,0x22BF,0x2235,0x2229,0x222A,0x0000,0x0000,0x0000,/* 0x98-0x9F */
};
-static wchar_t c2u_88[256] = {
+static const wchar_t c2u_88[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -203,7 +203,7 @@ static wchar_t c2u_88[256] = {
0x5F15,0x98F2,0x6DEB,0x80E4,0x852D,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_89[256] = {
+static const wchar_t c2u_89[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -239,7 +239,7 @@ static wchar_t c2u_89[256] = {
0x6062,0x61D0,0x6212,0x62D0,0x6539,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8A[256] = {
+static const wchar_t c2u_8A[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -275,7 +275,7 @@ static wchar_t c2u_8A[256] = {
0x65D7,0x65E2,0x671F,0x68CB,0x68C4,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8B[256] = {
+static const wchar_t c2u_8B[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -311,7 +311,7 @@ static wchar_t c2u_8B[256] = {
0x4E32,0x6ADB,0x91E7,0x5C51,0x5C48,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8C[256] = {
+static const wchar_t c2u_8C[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -347,7 +347,7 @@ static wchar_t c2u_8C[256] = {
0x52B9,0x52FE,0x539A,0x53E3,0x5411,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8D[256] = {
+static const wchar_t c2u_8D[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -383,7 +383,7 @@ static wchar_t c2u_8D[256] = {
0x9BAD,0x7B39,0x5319,0x518A,0x5237,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8E[256] = {
+static const wchar_t c2u_8E[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -419,7 +419,7 @@ static wchar_t c2u_8E[256] = {
0x7DAC,0x9700,0x56DA,0x53CE,0x5468,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8F[256] = {
+static const wchar_t c2u_8F[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -455,7 +455,7 @@ static wchar_t c2u_8F[256] = {
0x91B8,0x9320,0x5631,0x57F4,0x98FE,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_90[256] = {
+static const wchar_t c2u_90[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -491,7 +491,7 @@ static wchar_t c2u_90[256] = {
0x717D,0x65CB,0x7A7F,0x7BAD,0x7DDA,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_91[256] = {
+static const wchar_t c2u_91[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -527,7 +527,7 @@ static wchar_t c2u_91[256] = {
0x8AFE,0x8338,0x51E7,0x86F8,0x53EA,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_92[256] = {
+static const wchar_t c2u_92[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -563,7 +563,7 @@ static wchar_t c2u_92[256] = {
0x8247,0x8A02,0x8AE6,0x8E44,0x9013,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_93[256] = {
+static const wchar_t c2u_93[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -599,7 +599,7 @@ static wchar_t c2u_93[256] = {
0x8679,0x5EFF,0x65E5,0x4E73,0x5165,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_94[256] = {
+static const wchar_t c2u_94[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -635,7 +635,7 @@ static wchar_t c2u_94[256] = {
0x6787,0x6BD8,0x7435,0x7709,0x7F8E,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_95[256] = {
+static const wchar_t c2u_95[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -671,7 +671,7 @@ static wchar_t c2u_95[256] = {
0x62B1,0x6367,0x653E,0x65B9,0x670B,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_96[256] = {
+static const wchar_t c2u_96[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -707,7 +707,7 @@ static wchar_t c2u_96[256] = {
0x9453,0x6109,0x6108,0x6CB9,0x7652,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_97[256] = {
+static const wchar_t c2u_97[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -743,7 +743,7 @@ static wchar_t c2u_97[256] = {
0x6F23,0x7149,0x7C3E,0x7DF4,0x806F,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_98[256] = {
+static const wchar_t c2u_98[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -779,7 +779,7 @@ static wchar_t c2u_98[256] = {
0x5080,0x509A,0x5085,0x50B4,0x50B2,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_99[256] = {
+static const wchar_t c2u_99[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -815,7 +815,7 @@ static wchar_t c2u_99[256] = {
0x54A5,0x54AC,0x54C4,0x54C8,0x54A8,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9A[256] = {
+static const wchar_t c2u_9A[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -851,7 +851,7 @@ static wchar_t c2u_9A[256] = {
0x5962,0x5960,0x5967,0x596C,0x5969,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9B[256] = {
+static const wchar_t c2u_9B[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -887,7 +887,7 @@ static wchar_t c2u_9B[256] = {
0x5EC1,0x5EC2,0x5EC8,0x5ED0,0x5ECF,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9C[256] = {
+static const wchar_t c2u_9C[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -923,7 +923,7 @@ static wchar_t c2u_9C[256] = {
0x6209,0x620D,0x620C,0x6214,0x621B,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9D[256] = {
+static const wchar_t c2u_9D[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -959,7 +959,7 @@ static wchar_t c2u_9D[256] = {
0x66C1,0x66B9,0x66C9,0x66BE,0x66BC,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9E[256] = {
+static const wchar_t c2u_9E[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -995,7 +995,7 @@ static wchar_t c2u_9E[256] = {
0x6A8D,0x6AA0,0x6A84,0x6AA2,0x6AA3,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9F[256] = {
+static const wchar_t c2u_9F[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1031,7 +1031,7 @@ static wchar_t c2u_9F[256] = {
0x6EF2,0x6F31,0x6EEF,0x6F32,0x6ECC,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E0[256] = {
+static const wchar_t c2u_E0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1067,7 +1067,7 @@ static wchar_t c2u_E0[256] = {
0x74A7,0x74CA,0x74CF,0x74D4,0x73F1,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E1[256] = {
+static const wchar_t c2u_E1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1103,7 +1103,7 @@ static wchar_t c2u_E1[256] = {
0x78BE,0x78BC,0x78C5,0x78CA,0x78EC,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E2[256] = {
+static const wchar_t c2u_E2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1139,7 +1139,7 @@ static wchar_t c2u_E2[256] = {
0x7CF2,0x7CF4,0x7CF6,0x7CFA,0x7D06,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E3[256] = {
+static const wchar_t c2u_E3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1175,7 +1175,7 @@ static wchar_t c2u_E3[256] = {
0x811B,0x8129,0x8123,0x812F,0x814B,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E4[256] = {
+static const wchar_t c2u_E4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1211,7 +1211,7 @@ static wchar_t c2u_E4[256] = {
0x84FC,0x8540,0x8563,0x8558,0x8548,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E5[256] = {
+static const wchar_t c2u_E5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1247,7 +1247,7 @@ static wchar_t c2u_E5[256] = {
0x8938,0x894C,0x891D,0x8960,0x895E,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E6[256] = {
+static const wchar_t c2u_E6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1283,7 +1283,7 @@ static wchar_t c2u_E6[256] = {
0x8E42,0x8E35,0x8E30,0x8E34,0x8E4A,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E7[256] = {
+static const wchar_t c2u_E7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1319,7 +1319,7 @@ static wchar_t c2u_E7[256] = {
0x92E9,0x930F,0x92FA,0x9344,0x932E,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E8[256] = {
+static const wchar_t c2u_E8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1355,7 +1355,7 @@ static wchar_t c2u_E8[256] = {
0x984F,0x984B,0x986B,0x986F,0x9870,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E9[256] = {
+static const wchar_t c2u_E9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1391,7 +1391,7 @@ static wchar_t c2u_E9[256] = {
0x9D41,0x9D3F,0x9D3E,0x9D46,0x9D48,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EA[256] = {
+static const wchar_t c2u_EA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1416,7 +1416,7 @@ static wchar_t c2u_EA[256] = {
0x69C7,0x9059,0x7464,0x51DC,0x7199,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_ED[256] = {
+static const wchar_t c2u_ED[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1452,7 +1452,7 @@ static wchar_t c2u_ED[256] = {
0x7147,0xFA15,0x71C1,0x71FE,0x72B1,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EE[256] = {
+static const wchar_t c2u_EE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1488,7 +1488,7 @@ static wchar_t c2u_EE[256] = {
0x2179,0xFFE2,0xFFE4,0xFF07,0xFF02,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FA[256] = {
+static const wchar_t c2u_FA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1524,7 +1524,7 @@ static wchar_t c2u_FA[256] = {
0x6C6F,0x6CDA,0x6D04,0x6D87,0x6D6F,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FB[256] = {
+static const wchar_t c2u_FB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1560,7 +1560,7 @@ static wchar_t c2u_FB[256] = {
0x9927,0xFA2C,0x999E,0x9A4E,0x9AD9,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FC[256] = {
+static const wchar_t c2u_FC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1573,7 +1573,7 @@ static wchar_t c2u_FC[256] = {
0x9D6B,0xFA2D,0x9E19,0x9ED1,0x0000,0x0000,0x0000,0x0000,/* 0x48-0x4F */
};
-static wchar_t *page_charset2uni[256] = {
+static const wchar_t *page_charset2uni[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1608,7 +1608,7 @@ static wchar_t *page_charset2uni[256] = {
NULL, NULL, c2u_FA, c2u_FB, c2u_FC, NULL, NULL, NULL,
};
-static unsigned char u2c_00hi[256 - 0xA0][2] = {
+static const unsigned char u2c_00hi[256 - 0xA0][2] = {
{0x00, 0x00}, {0x00, 0x00}, {0x81, 0x91}, {0x81, 0x92},/* 0xA0-0xA3 */
{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x81, 0x98},/* 0xA4-0xA7 */
{0x81, 0x4E}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},/* 0xA8-0xAB */
@@ -1635,7 +1635,7 @@ static unsigned char u2c_00hi[256 - 0xA0][2] = {
{0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},/* 0xFC-0xFF */
};
-static unsigned char u2c_03[512] = {
+static const unsigned char u2c_03[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1690,7 +1690,7 @@ static unsigned char u2c_03[512] = {
0x83, 0xD5, 0x83, 0xD6, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */
};
-static unsigned char u2c_04[512] = {
+static const unsigned char u2c_04[512] = {
0x00, 0x00, 0x84, 0x46, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1714,7 +1714,7 @@ static unsigned char u2c_04[512] = {
0x00, 0x00, 0x84, 0x76, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x53 */
};
-static unsigned char u2c_20[512] = {
+static const unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1732,7 +1732,7 @@ static unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xA6, /* 0x38-0x3B */
};
-static unsigned char u2c_21[512] = {
+static const unsigned char u2c_21[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x8E, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1790,7 +1790,7 @@ static unsigned char u2c_21[512] = {
0x81, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD4-0xD7 */
};
-static unsigned char u2c_22[512] = {
+static const unsigned char u2c_22[512] = {
0x81, 0xCD, 0x00, 0x00, 0x81, 0xDD, 0x81, 0xCE, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xDE, /* 0x04-0x07 */
0x81, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x81, 0xB9, /* 0x08-0x0B */
@@ -1842,7 +1842,7 @@ static unsigned char u2c_22[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x99, /* 0xBC-0xBF */
};
-static unsigned char u2c_23[512] = {
+static const unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1850,7 +1850,7 @@ static unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0x81, 0xDC, 0x00, 0x00, /* 0x10-0x13 */
};
-static unsigned char u2c_24[512] = {
+static const unsigned char u2c_24[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1882,7 +1882,7 @@ static unsigned char u2c_24[512] = {
0x87, 0x50, 0x87, 0x51, 0x87, 0x52, 0x87, 0x53, /* 0x70-0x73 */
};
-static unsigned char u2c_25[512] = {
+static const unsigned char u2c_25[512] = {
0x84, 0x9F, 0x84, 0xAA, 0x84, 0xA0, 0x84, 0xAB, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1946,7 +1946,7 @@ static unsigned char u2c_25[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xFC, /* 0xEC-0xEF */
};
-static unsigned char u2c_26[512] = {
+static const unsigned char u2c_26[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x81, 0x9A, 0x81, 0x99, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -1977,7 +1977,7 @@ static unsigned char u2c_26[512] = {
0x00, 0x00, 0x81, 0xF3, 0x00, 0x00, 0x81, 0xF2, /* 0x6C-0x6F */
};
-static unsigned char u2c_30[512] = {
+static const unsigned char u2c_30[512] = {
0x81, 0x40, 0x81, 0x41, 0x81, 0x42, 0x81, 0x56, /* 0x00-0x03 */
0x00, 0x00, 0x81, 0x58, 0x81, 0x59, 0x81, 0x5A, /* 0x04-0x07 */
0x81, 0x71, 0x81, 0x72, 0x81, 0x73, 0x81, 0x74, /* 0x08-0x0B */
@@ -2045,7 +2045,7 @@ static unsigned char u2c_30[512] = {
0x81, 0x5B, 0x81, 0x52, 0x81, 0x53, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_32[512] = {
+static const unsigned char u2c_32[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -2092,7 +2092,7 @@ static unsigned char u2c_32[512] = {
0x87, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA8-0xAB */
};
-static unsigned char u2c_33[512] = {
+static const unsigned char u2c_33[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x65, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -2148,7 +2148,7 @@ static unsigned char u2c_33[512] = {
0x00, 0x00, 0x87, 0x83, 0x00, 0x00, 0x00, 0x00, /* 0xCC-0xCF */
};
-static unsigned char u2c_4E[512] = {
+static const unsigned char u2c_4E[512] = {
0x88, 0xEA, 0x92, 0x9A, 0x00, 0x00, 0x8E, 0xB5, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x9C, /* 0x04-0x07 */
0x8F, 0xE4, 0x8E, 0x4F, 0x8F, 0xE3, 0x89, 0xBA, /* 0x08-0x0B */
@@ -2216,7 +2216,7 @@ static unsigned char u2c_4E[512] = {
0xED, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_4F[512] = {
+static const unsigned char u2c_4F[512] = {
0xED, 0x4F, 0x8A, 0xE9, 0x00, 0x00, 0xED, 0x50, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x98, 0xC2, 0x88, 0xC9, 0x00, 0x00, /* 0x08-0x0B */
@@ -2284,7 +2284,7 @@ static unsigned char u2c_4F[512] = {
0x00, 0x00, 0x00, 0x00, 0x98, 0xEA, 0xED, 0x5A, /* 0xFC-0xFF */
};
-static unsigned char u2c_50[512] = {
+static const unsigned char u2c_50[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x98, 0xE4, 0x98, 0xED, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x91, 0x71, 0x00, 0x00, 0x8C, 0xC2, /* 0x08-0x0B */
@@ -2351,7 +2351,7 @@ static unsigned char u2c_50[512] = {
0x00, 0x00, 0x99, 0x4A, 0x00, 0x00, 0x95, 0xC6, /* 0xF8-0xFB */
};
-static unsigned char u2c_51[512] = {
+static const unsigned char u2c_51[512] = {
0x8B, 0x56, 0x99, 0x4D, 0x99, 0x4E, 0x00, 0x00, /* 0x00-0x03 */
0x89, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x99, 0x4C, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -2419,7 +2419,7 @@ static unsigned char u2c_51[512] = {
0x00, 0x00, 0x94, 0x9F, 0x99, 0x82, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_52[512] = {
+static const unsigned char u2c_52[512] = {
0x93, 0x81, 0x00, 0x00, 0x00, 0x00, 0x90, 0x6E, /* 0x00-0x03 */
0x99, 0x83, 0x00, 0x00, 0x95, 0xAA, 0x90, 0xD8, /* 0x04-0x07 */
0x8A, 0xA0, 0x00, 0x00, 0x8A, 0xA7, 0x99, 0x84, /* 0x08-0x0B */
@@ -2487,7 +2487,7 @@ static unsigned char u2c_52[512] = {
0x00, 0x00, 0x00, 0x00, 0x8C, 0xF9, 0x96, 0xDC, /* 0xFC-0xFF */
};
-static unsigned char u2c_53[512] = {
+static const unsigned char u2c_53[512] = {
0xED, 0x6C, 0x96, 0xE6, 0x93, 0xF5, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x95, 0xEF, 0x99, 0xB0, 0xED, 0x6D, /* 0x04-0x07 */
0x99, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -2554,7 +2554,7 @@ static unsigned char u2c_53[512] = {
0x8E, 0x69, 0x00, 0x00, 0x99, 0xDB, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_54[512] = {
+static const unsigned char u2c_54[512] = {
0x00, 0x00, 0x99, 0xDC, 0x00, 0x00, 0x8B, 0x68, /* 0x00-0x03 */
0x8A, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x8D, 0x87, 0x8B, 0x67, 0x92, 0xDD, 0x89, 0x44, /* 0x08-0x0B */
@@ -2622,7 +2622,7 @@ static unsigned char u2c_54[512] = {
0x00, 0x00, 0x9A, 0x4A, 0x00, 0x00, 0xED, 0x77, /* 0xFC-0xFF */
};
-static unsigned char u2c_55[512] = {
+static const unsigned char u2c_55[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x89, 0x53, 0x00, 0x00, 0x8D, 0xB4, 0x90, 0x4F, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -2690,7 +2690,7 @@ static unsigned char u2c_55[512] = {
0x00, 0x00, 0x9A, 0x75, 0x9A, 0x74, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_56[512] = {
+static const unsigned char u2c_56[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x92, 0x51, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x89, 0xC3, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -2758,7 +2758,7 @@ static unsigned char u2c_56[512] = {
0x00, 0x00, 0x8D, 0x91, 0x00, 0x00, 0x9A, 0x9C, /* 0xFC-0xFF */
};
-static unsigned char u2c_57[512] = {
+static const unsigned char u2c_57[512] = {
0x9A, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x95, 0xDE, /* 0x00-0x03 */
0x9A, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x9A, 0x9F, 0x9A, 0x9E, 0x00, 0x00, 0x9A, 0xA0, /* 0x08-0x0B */
@@ -2826,7 +2826,7 @@ static unsigned char u2c_57[512] = {
0x8D, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_58[512] = {
+static const unsigned char u2c_58[512] = {
0x96, 0x78, 0x00, 0x00, 0x93, 0xB0, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x8C, 0x98, 0x91, 0xCD, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x9A, 0xBF, 0x9A, 0xC2, /* 0x08-0x0B */
@@ -2894,7 +2894,7 @@ static unsigned char u2c_58[512] = {
0x9A, 0xE5, 0x9A, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_59[512] = {
+static const unsigned char u2c_59[512] = {
0x00, 0x00, 0x00, 0x00, 0x9A, 0xE7, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x95, 0xCF, 0x9A, 0xE8, 0xED, 0x83, /* 0x08-0x0B */
@@ -2962,7 +2962,7 @@ static unsigned char u2c_59[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x70, /* 0xFC-0xFF */
};
-static unsigned char u2c_5A[512] = {
+static const unsigned char u2c_5A[512] = {
0x00, 0x00, 0x88, 0xD0, 0x00, 0x00, 0x88, 0xA1, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x9B, 0x51, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3029,7 +3029,7 @@ static unsigned char u2c_5A[512] = {
0x00, 0x00, 0x00, 0x00, 0x9B, 0x65, 0x9B, 0x66, /* 0xF8-0xFB */
};
-static unsigned char u2c_5B[512] = {
+static const unsigned char u2c_5B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x8A, 0xF0, 0x00, 0x00, 0x9B, 0x68, /* 0x08-0x0B */
@@ -3097,7 +3097,7 @@ static unsigned char u2c_5B[512] = {
0x00, 0x00, 0x00, 0x00, 0x91, 0xCE, 0x8E, 0xF5, /* 0xFC-0xFF */
};
-static unsigned char u2c_5C[512] = {
+static const unsigned char u2c_5C[512] = {
0x00, 0x00, 0x95, 0x95, 0x90, 0xEA, 0x00, 0x00, /* 0x00-0x03 */
0x8E, 0xCB, 0x9B, 0x91, 0x8F, 0xAB, 0x9B, 0x92, /* 0x04-0x07 */
0x9B, 0x93, 0x88, 0xD1, 0x91, 0xB8, 0x90, 0x71, /* 0x08-0x0B */
@@ -3165,7 +3165,7 @@ static unsigned char u2c_5C[512] = {
0x00, 0x00, 0x9B, 0xB5, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_5D[512] = {
+static const unsigned char u2c_5D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x92, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xBA, /* 0x08-0x0B */
@@ -3233,7 +3233,7 @@ static unsigned char u2c_5D[512] = {
0x00, 0x00, 0x92, 0x46, 0x8B, 0xD0, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_5E[512] = {
+static const unsigned char u2c_5E[512] = {
0x00, 0x00, 0x00, 0x00, 0x8E, 0x73, 0x95, 0x7A, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x94, 0xBF, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xE1, /* 0x08-0x0B */
@@ -3301,7 +3301,7 @@ static unsigned char u2c_5E[512] = {
0x94, 0x55, 0x00, 0x00, 0x9C, 0x4F, 0x93, 0xF9, /* 0xFC-0xFF */
};
-static unsigned char u2c_5F[512] = {
+static const unsigned char u2c_5F[512] = {
0x00, 0x00, 0x95, 0xD9, 0x00, 0x00, 0x9C, 0x50, /* 0x00-0x03 */
0x98, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x9C, 0x51, 0x95, 0xBE, 0x9C, 0x54, /* 0x08-0x0B */
@@ -3369,7 +3369,7 @@ static unsigned char u2c_5F[512] = {
0x00, 0x00, 0x8D, 0x9A, 0x00, 0x00, 0x9C, 0x7C, /* 0xFC-0xFF */
};
-static unsigned char u2c_60[512] = {
+static const unsigned char u2c_60[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3436,7 +3436,7 @@ static unsigned char u2c_60[512] = {
0x00, 0x00, 0x8E, 0xE4, 0x9C, 0xB7, 0x9C, 0xBA, /* 0xF8-0xFB */
};
-static unsigned char u2c_61[512] = {
+static const unsigned char u2c_61[512] = {
0x9C, 0xB5, 0x8F, 0x44, 0x00, 0x00, 0x9C, 0xB8, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x9C, 0xB2, 0x00, 0x00, /* 0x04-0x07 */
0x96, 0xFA, 0x96, 0xF9, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3504,7 +3504,7 @@ static unsigned char u2c_61[512] = {
0x9C, 0xF4, 0x9C, 0xF3, 0x9C, 0xF5, 0x9C, 0xF2, /* 0xFC-0xFF */
};
-static unsigned char u2c_62[512] = {
+static const unsigned char u2c_62[512] = {
0x9C, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x9C, 0xF7, 0x9C, 0xF8, 0x95, 0xE8, 0x00, 0x00, /* 0x08-0x0B */
@@ -3572,7 +3572,7 @@ static unsigned char u2c_62[512] = {
0x00, 0x00, 0x00, 0x00, 0x8F, 0x45, 0x9D, 0x5C, /* 0xFC-0xFF */
};
-static unsigned char u2c_63[512] = {
+static const unsigned char u2c_63[512] = {
0x00, 0x00, 0x8E, 0x9D, 0x9D, 0x6B, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x77, /* 0x04-0x07 */
0x9D, 0x6C, 0x88, 0xC2, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3639,7 +3639,7 @@ static unsigned char u2c_63[512] = {
0x00, 0x00, 0x00, 0x00, 0x97, 0x68, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_64[512] = {
+static const unsigned char u2c_64[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x9D, 0x8C, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3707,7 +3707,7 @@ static unsigned char u2c_64[512] = {
0x00, 0x00, 0x9D, 0xB4, 0x8F, 0xEF, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_65[512] = {
+static const unsigned char u2c_65[512] = {
0x9D, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x9D, 0xB7, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3774,7 +3774,7 @@ static unsigned char u2c_65[512] = {
0x00, 0x00, 0x00, 0x00, 0x89, 0xA0, 0x9D, 0xDF, /* 0xF8-0xFB */
};
-static unsigned char u2c_66[512] = {
+static const unsigned char u2c_66[512] = {
0xED, 0xB2, 0x00, 0x00, 0x8D, 0x56, 0x9D, 0xDE, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x8D, 0xA9, 0x8F, 0xB8, /* 0x04-0x07 */
0x00, 0x00, 0xED, 0xB5, 0x9D, 0xDD, 0x00, 0x00, /* 0x08-0x0B */
@@ -3842,7 +3842,7 @@ static unsigned char u2c_66[512] = {
0x99, 0xD6, 0x91, 0x5D, 0x91, 0x5C, 0x91, 0xD6, /* 0xFC-0xFF */
};
-static unsigned char u2c_67[512] = {
+static const unsigned char u2c_67[512] = {
0x8D, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x98, 0xF0, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x8C, 0x8E, 0x97, 0x4C, 0x00, 0x00, 0x95, 0xFC, /* 0x08-0x0B */
@@ -3910,7 +3910,7 @@ static unsigned char u2c_67[512] = {
0x00, 0x00, 0x00, 0x00, 0x96, 0x8F, 0x8A, 0x60, /* 0xFC-0xFF */
};
-static unsigned char u2c_68[512] = {
+static const unsigned char u2c_68[512] = {
0x00, 0x00, 0xED, 0xC9, 0x92, 0xCC, 0x93, 0xC8, /* 0x00-0x03 */
0x89, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3977,7 +3977,7 @@ static unsigned char u2c_68[512] = {
0x00, 0x00, 0x9E, 0xA8, 0x8A, 0xBB, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_69[512] = {
+static const unsigned char u2c_69[512] = {
0x98, 0x6F, 0x9E, 0x96, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x9E, 0xA4, 0x88, 0xD6, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x9E, 0x98, 0x00, 0x00, 0x00, 0x00, 0x96, 0xB8, /* 0x08-0x0B */
@@ -4045,7 +4045,7 @@ static unsigned char u2c_69[512] = {
0x00, 0x00, 0x91, 0x85, 0x00, 0x00, 0x9E, 0xDB, /* 0xFC-0xFF */
};
-static unsigned char u2c_6A[512] = {
+static const unsigned char u2c_6A[512] = {
0x00, 0x00, 0x00, 0x00, 0x9E, 0xD9, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x9E, 0xE0, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x9E, 0xE6, 0x94, 0xF3, /* 0x08-0x0B */
@@ -4112,7 +4112,7 @@ static unsigned char u2c_6A[512] = {
0x00, 0x00, 0x00, 0x00, 0x9F, 0x51, 0x9F, 0x4E, /* 0xF8-0xFB */
};
-static unsigned char u2c_6B[512] = {
+static const unsigned char u2c_6B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x97, 0x93, 0x9F, 0x4F, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x9E, 0xDC, 0x00, 0x00, /* 0x08-0x0B */
@@ -4177,7 +4177,7 @@ static unsigned char u2c_6B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0x7D, /* 0xF0-0xF3 */
};
-static unsigned char u2c_6C[512] = {
+static const unsigned char u2c_6C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x9F, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4242,7 +4242,7 @@ static unsigned char u2c_6C[512] = {
0x91, 0xD7, 0x9F, 0x96, 0x00, 0x00, 0x89, 0x6A, /* 0xF0-0xF3 */
};
-static unsigned char u2c_6D[512] = {
+static const unsigned char u2c_6D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xED, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x6D, /* 0x08-0x0B */
@@ -4310,7 +4310,7 @@ static unsigned char u2c_6D[512] = {
0xED, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_6E[512] = {
+static const unsigned char u2c_6E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x90, 0xB4, 0x00, 0x00, 0x8A, 0x89, /* 0x04-0x07 */
0x8D, 0xCF, 0x8F, 0xC2, 0x9F, 0xBB, 0x8F, 0x61, /* 0x08-0x0B */
@@ -4378,7 +4378,7 @@ static unsigned char u2c_6E[512] = {
0x00, 0x00, 0x00, 0x00, 0x9F, 0xF6, 0x9F, 0xDE, /* 0xFC-0xFF */
};
-static unsigned char u2c_6F[512] = {
+static const unsigned char u2c_6F[512] = {
0x00, 0x00, 0x8B, 0x99, 0x95, 0x59, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x8E, 0xBD, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x8D, 0x97, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4446,7 +4446,7 @@ static unsigned char u2c_6F[512] = {
0x00, 0x00, 0x00, 0x00, 0xE0, 0x68, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_70[512] = {
+static const unsigned char u2c_70[512] = {
0x00, 0x00, 0xE0, 0x66, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xED, 0xEF, 0x00, 0x00, 0xED, 0xF0, /* 0x04-0x07 */
0x00, 0x00, 0xE0, 0x62, 0x00, 0x00, 0xE0, 0x63, /* 0x08-0x0B */
@@ -4514,7 +4514,7 @@ static unsigned char u2c_70[512] = {
0x00, 0x00, 0xE0, 0x82, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_71[512] = {
+static const unsigned char u2c_71[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xED, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE0, 0x81, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4582,7 +4582,7 @@ static unsigned char u2c_71[512] = {
0xE0, 0x9E, 0x00, 0x00, 0xED, 0xFB, 0xE0, 0xA0, /* 0xFC-0xFF */
};
-static unsigned char u2c_72[512] = {
+static const unsigned char u2c_72[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4650,7 +4650,7 @@ static unsigned char u2c_72[512] = {
0x98, 0x54, 0x94, 0x82, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_73[512] = {
+static const unsigned char u2c_73[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE0, 0xC7, 0x00, 0x00, /* 0x08-0x0B */
@@ -4718,7 +4718,7 @@ static unsigned char u2c_73[512] = {
0x00, 0x00, 0x00, 0x00, 0x8C, 0xBB, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_74[512] = {
+static const unsigned char u2c_74[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x85, /* 0x00-0x03 */
0x00, 0x00, 0xE0, 0xE4, 0x97, 0x9D, 0xEE, 0x49, /* 0x04-0x07 */
0x00, 0x00, 0x97, 0xAE, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4785,7 +4785,7 @@ static unsigned char u2c_74[512] = {
0xE1, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_75[512] = {
+static const unsigned char u2c_75[512] = {
0x00, 0x00, 0xEE, 0x52, 0x00, 0x00, 0xE1, 0x4B, /* 0x00-0x03 */
0xE1, 0x4A, 0xE1, 0x4C, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4853,7 +4853,7 @@ static unsigned char u2c_75[512] = {
0xE1, 0x80, 0x00, 0x00, 0xE1, 0x7D, 0xE1, 0x7E, /* 0xFC-0xFF */
};
-static unsigned char u2c_76[512] = {
+static const unsigned char u2c_76[512] = {
0x00, 0x00, 0xE1, 0x81, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE1, 0x88, 0x00, 0x00, 0xE1, 0x86, /* 0x08-0x0B */
@@ -4921,7 +4921,7 @@ static unsigned char u2c_76[512] = {
0x00, 0x00, 0x00, 0x00, 0x8F, 0x82, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_77[512] = {
+static const unsigned char u2c_77[512] = {
0x00, 0x00, 0x8F, 0xC8, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xE1, 0xBE, 0x00, 0x00, 0x00, 0x00, 0xE1, 0xBD, /* 0x04-0x07 */
0xE1, 0xBC, 0x94, 0xFB, 0x00, 0x00, 0x8A, 0xC5, /* 0x08-0x0B */
@@ -4989,7 +4989,7 @@ static unsigned char u2c_77[512] = {
0xE1, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_78[512] = {
+static const unsigned char u2c_78[512] = {
0x00, 0x00, 0x00, 0x00, 0x8D, 0xBB, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5057,7 +5057,7 @@ static unsigned char u2c_78[512] = {
0x00, 0x00, 0xE2, 0x42, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_79[512] = {
+static const unsigned char u2c_79[512] = {
0x00, 0x00, 0x8F, 0xCA, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x44, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5124,7 +5124,7 @@ static unsigned char u2c_79[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xDA, /* 0xF8-0xFB */
};
-static unsigned char u2c_7A[512] = {
+static const unsigned char u2c_7A[512] = {
0x8B, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xE2, 0x62, 0x00, 0x00, 0x00, 0x00, 0x92, 0xF6, /* 0x08-0x0B */
@@ -5192,7 +5192,7 @@ static unsigned char u2c_7A[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xC6, /* 0xFC-0xFF */
};
-static unsigned char u2c_7B[512] = {
+static const unsigned char u2c_7B[512] = {
0x00, 0x00, 0x00, 0x00, 0xE2, 0x93, 0x00, 0x00, /* 0x00-0x03 */
0xE2, 0xA0, 0x00, 0x00, 0xE2, 0x96, 0x00, 0x00, /* 0x04-0x07 */
0x8B, 0x88, 0x00, 0x00, 0xE2, 0x95, 0xE2, 0xA2, /* 0x08-0x0B */
@@ -5258,7 +5258,7 @@ static unsigned char u2c_7B[512] = {
0x00, 0x00, 0x00, 0x00, 0xE2, 0xCC, 0xE2, 0xC9, /* 0xF4-0xF7 */
};
-static unsigned char u2c_7C[512] = {
+static const unsigned char u2c_7C[512] = {
0xE2, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xC6, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5326,7 +5326,7 @@ static unsigned char u2c_7C[512] = {
0x00, 0x00, 0x00, 0x00, 0x8B, 0x8A, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_7D[512] = {
+static const unsigned char u2c_7D[512] = {
0x8B, 0x49, 0x00, 0x00, 0xE3, 0x40, 0x00, 0x00, /* 0x00-0x03 */
0x96, 0xF1, 0x8D, 0x67, 0xE2, 0xFC, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE3, 0x43, 0x96, 0xE4, /* 0x08-0x0B */
@@ -5393,7 +5393,7 @@ static unsigned char u2c_7D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x6B, /* 0xF8-0xFB */
};
-static unsigned char u2c_7E[512] = {
+static const unsigned char u2c_7E[512] = {
0x00, 0x00, 0x89, 0x8F, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x93, 0xEA, 0xE3, 0x6E, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE3, 0x75, 0xE3, 0x6F, 0xE3, 0x76, /* 0x08-0x0B */
@@ -5437,7 +5437,7 @@ static unsigned char u2c_7E[512] = {
0xE3, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */
};
-static unsigned char u2c_7F[512] = {
+static const unsigned char u2c_7F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5505,7 +5505,7 @@ static unsigned char u2c_7F[512] = {
0x97, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_80[512] = {
+static const unsigned char u2c_80[512] = {
0x97, 0x73, 0x98, 0x56, 0x00, 0x00, 0x8D, 0x6C, /* 0x00-0x03 */
0xE3, 0xCC, 0x8E, 0xD2, 0xE3, 0xCB, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0xCD, /* 0x08-0x0B */
@@ -5573,7 +5573,7 @@ static unsigned char u2c_80[512] = {
0xE4, 0x45, 0x94, 0x5C, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_81[512] = {
+static const unsigned char u2c_81[512] = {
0x00, 0x00, 0x00, 0x00, 0x8E, 0x89, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x8B, 0xBA, 0x90, 0xC6, 0x98, 0x65, /* 0x04-0x07 */
0x96, 0xAC, 0xE3, 0xF5, 0x90, 0xD2, 0x00, 0x00, /* 0x08-0x0B */
@@ -5641,7 +5641,7 @@ static unsigned char u2c_81[512] = {
0x89, 0x50, 0x00, 0x00, 0xE4, 0x6B, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_82[512] = {
+static const unsigned char u2c_82[512] = {
0x00, 0x00, 0xE4, 0x6C, 0xE4, 0x6D, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xE4, 0x6E, 0x00, 0x00, 0xE4, 0x6F, /* 0x04-0x07 */
0x8B, 0xBB, 0x9D, 0xA8, 0xE4, 0x70, 0x00, 0x00, /* 0x08-0x0B */
@@ -5708,7 +5708,7 @@ static unsigned char u2c_82[512] = {
0x00, 0x00, 0xE4, 0x99, 0xE4, 0x95, 0xE4, 0x98, /* 0xF8-0xFB */
};
-static unsigned char u2c_83[512] = {
+static const unsigned char u2c_83[512] = {
0x00, 0x00, 0xEE, 0x76, 0x96, 0xCE, 0xE4, 0x97, /* 0x00-0x03 */
0x89, 0xD6, 0x8A, 0x9D, 0xE4, 0x9B, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE4, 0x9D, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5776,7 +5776,7 @@ static unsigned char u2c_83[512] = {
0x00, 0x00, 0xE4, 0xC1, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_84[512] = {
+static const unsigned char u2c_84[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xC2, /* 0x00-0x03 */
0x93, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xC7, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xC4, /* 0x08-0x0B */
@@ -5844,7 +5844,7 @@ static unsigned char u2c_84[512] = {
0xE4, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xE4, 0xF0, /* 0xFC-0xFF */
};
-static unsigned char u2c_85[512] = {
+static const unsigned char u2c_85[512] = {
0x8E, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xE4, 0xCF, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5912,7 +5912,7 @@ static unsigned char u2c_85[512] = {
0x00, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_86[512] = {
+static const unsigned char u2c_86[512] = {
0x00, 0x00, 0x00, 0x00, 0xE5, 0x41, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xE5, 0x62, 0x91, 0x68, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE5, 0x5D, 0xE5, 0x5F, /* 0x08-0x0B */
@@ -5980,7 +5980,7 @@ static unsigned char u2c_86[512] = {
0x00, 0x00, 0x00, 0x00, 0x89, 0xE9, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_87[512] = {
+static const unsigned char u2c_87[512] = {
0xE5, 0x86, 0x00, 0x00, 0x96, 0x49, 0xE5, 0x87, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xE5, 0x84, 0x00, 0x00, /* 0x04-0x07 */
0xE5, 0x85, 0xE5, 0x8A, 0xE5, 0x8D, 0x00, 0x00, /* 0x08-0x0B */
@@ -6048,7 +6048,7 @@ static unsigned char u2c_87[512] = {
0x00, 0x00, 0x00, 0x00, 0xE5, 0xB7, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_88[512] = {
+static const unsigned char u2c_88[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xE5, 0xA2, 0x00, 0x00, 0xEE, 0x85, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6116,7 +6116,7 @@ static unsigned char u2c_88[512] = {
0xE5, 0xE7, 0x90, 0xBB, 0x90, 0x9E, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_89[512] = {
+static const unsigned char u2c_89[512] = {
0x00, 0x00, 0x00, 0x00, 0xE5, 0xE6, 0x00, 0x00, /* 0x00-0x03 */
0xE5, 0xEB, 0x00, 0x00, 0x00, 0x00, 0x95, 0xA1, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE5, 0xED, 0x00, 0x00, /* 0x08-0x0B */
@@ -6183,7 +6183,7 @@ static unsigned char u2c_89[512] = {
0xE6, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_8A[512] = {
+static const unsigned char u2c_8A[512] = {
0x8C, 0xBE, 0x00, 0x00, 0x92, 0xF9, 0xE6, 0x5D, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x8C, 0x76, 0x00, 0x00, 0x90, 0x75, 0x00, 0x00, /* 0x08-0x0B */
@@ -6251,7 +6251,7 @@ static unsigned char u2c_8A[512] = {
0x00, 0x00, 0x00, 0x00, 0x91, 0xF8, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8B[512] = {
+static const unsigned char u2c_8B[512] = {
0x96, 0x64, 0x89, 0x79, 0x88, 0xE0, 0x00, 0x00, /* 0x00-0x03 */
0x93, 0xA3, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x89, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6294,7 +6294,7 @@ static unsigned char u2c_8B[512] = {
0x00, 0x00, 0xE6, 0xAA, 0xE6, 0xAB, 0x00, 0x00, /* 0x98-0x9B */
};
-static unsigned char u2c_8C[512] = {
+static const unsigned char u2c_8C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6362,7 +6362,7 @@ static unsigned char u2c_8C[512] = {
0x8D, 0x77, 0xE6, 0xCE, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8D[512] = {
+static const unsigned char u2c_8D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xE6, 0xD1, 0xE6, 0xD2, 0x00, 0x00, 0xE6, 0xD4, /* 0x04-0x07 */
0x91, 0xA1, 0x00, 0x00, 0xE6, 0xD3, 0x8A, 0xE4, /* 0x08-0x0B */
@@ -6430,7 +6430,7 @@ static unsigned char u2c_8D[512] = {
0xE6, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xF3, /* 0xFC-0xFF */
};
-static unsigned char u2c_8E[512] = {
+static const unsigned char u2c_8E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xE6, 0xF1, 0xE6, 0xF2, 0x97, 0x78, 0x00, 0x00, /* 0x08-0x0B */
@@ -6498,7 +6498,7 @@ static unsigned char u2c_8E[512] = {
0xE7, 0x64, 0x8C, 0x79, 0xE7, 0x67, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8F[512] = {
+static const unsigned char u2c_8F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x72, /* 0x00-0x03 */
0x00, 0x00, 0xE7, 0x69, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x8D, 0xDA, 0xE7, 0x68, 0x00, 0x00, /* 0x08-0x0B */
@@ -6566,7 +6566,7 @@ static unsigned char u2c_8F[512] = {
0x00, 0x00, 0x92, 0xC7, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_90[512] = {
+static const unsigned char u2c_90[512] = {
0x91, 0xDE, 0x91, 0x97, 0x00, 0x00, 0x93, 0xA6, /* 0x00-0x03 */
0x00, 0x00, 0xE7, 0x90, 0x8B, 0x74, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x99, /* 0x08-0x0B */
@@ -6634,7 +6634,7 @@ static unsigned char u2c_90[512] = {
0x00, 0x00, 0x93, 0x73, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_91[512] = {
+static const unsigned char u2c_91[512] = {
0x00, 0x00, 0x00, 0x00, 0xE7, 0xBD, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6702,7 +6702,7 @@ static unsigned char u2c_91[512] = {
0xE7, 0xDD, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xE1, /* 0xFC-0xFF */
};
-static unsigned char u2c_92[512] = {
+static const unsigned char u2c_92[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xEE, 0xA5, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xEE, 0xA7, 0x00, 0x00, /* 0x08-0x0B */
@@ -6770,7 +6770,7 @@ static unsigned char u2c_92[512] = {
0x8D, 0x7C, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xC0, /* 0xFC-0xFF */
};
-static unsigned char u2c_93[512] = {
+static const unsigned char u2c_93[512] = {
0x00, 0x00, 0x00, 0x00, 0xEE, 0xC2, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x8E, 0x4B, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6837,7 +6837,7 @@ static unsigned char u2c_93[512] = {
0xEE, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_94[512] = {
+static const unsigned char u2c_94[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x5E, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x5F, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6874,7 +6874,7 @@ static unsigned char u2c_94[512] = {
0x00, 0x00, 0xE8, 0x76, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x83 */
};
-static unsigned char u2c_95[512] = {
+static const unsigned char u2c_95[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6936,7 +6936,7 @@ static unsigned char u2c_95[512] = {
0x00, 0x00, 0xE8, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char u2c_96[512] = {
+static const unsigned char u2c_96[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7003,7 +7003,7 @@ static unsigned char u2c_96[512] = {
0x00, 0x00, 0xE8, 0xB9, 0x00, 0x00, 0x93, 0x64, /* 0xF8-0xFB */
};
-static unsigned char u2c_97[512] = {
+static const unsigned char u2c_97[512] = {
0x8E, 0xF9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xE8, 0xBA, 0x00, 0x00, 0xE8, 0xBB, 0x90, 0x6B, /* 0x04-0x07 */
0xE8, 0xBC, 0x00, 0x00, 0x97, 0xEC, 0x00, 0x00, /* 0x08-0x0B */
@@ -7071,7 +7071,7 @@ static unsigned char u2c_97[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xBF, /* 0xFC-0xFF */
};
-static unsigned char u2c_98[512] = {
+static const unsigned char u2c_98[512] = {
0x00, 0x00, 0x95, 0xC5, 0x92, 0xB8, 0x8D, 0xA0, /* 0x00-0x03 */
0x00, 0x00, 0x8D, 0x80, 0x8F, 0x87, 0x00, 0x00, /* 0x04-0x07 */
0x90, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7139,7 +7139,7 @@ static unsigned char u2c_98[512] = {
0x8E, 0x94, 0x96, 0x4F, 0x8F, 0xFC, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_99[512] = {
+static const unsigned char u2c_99[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0x4C, /* 0x00-0x03 */
0x00, 0x00, 0x96, 0xDD, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE9, 0x4D, 0x97, 0x7B, 0x00, 0x00, /* 0x08-0x0B */
@@ -7207,7 +7207,7 @@ static unsigned char u2c_99[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x78, /* 0xFC-0xFF */
};
-static unsigned char u2c_9A[512] = {
+static const unsigned char u2c_9A[512] = {
0x00, 0x00, 0xE9, 0x74, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xE9, 0x76, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7274,7 +7274,7 @@ static unsigned char u2c_9A[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0x9F, /* 0xF8-0xFB */
};
-static unsigned char u2c_9B[512] = {
+static const unsigned char u2c_9B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xE9, 0xA0, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7340,7 +7340,7 @@ static unsigned char u2c_9B[512] = {
0x00, 0x00, 0x88, 0xB1, 0x00, 0x00, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_9C[512] = {
+static const unsigned char u2c_9C[512] = {
0xEE, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xE9, 0xD8, 0x00, 0x00, 0xE9, 0xD4, 0x00, 0x00, /* 0x04-0x07 */
0xE9, 0xD5, 0xE9, 0xD1, 0xE9, 0xD7, 0x00, 0x00, /* 0x08-0x0B */
@@ -7406,7 +7406,7 @@ static unsigned char u2c_9C[512] = {
0x96, 0xC2, 0x00, 0x00, 0x93, 0xCE, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_9D[512] = {
+static const unsigned char u2c_9D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0xEE, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xE9, 0xEF, 0x93, 0xBC, /* 0x04-0x07 */
0xE9, 0xEC, 0xE9, 0xEB, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7474,7 +7474,7 @@ static unsigned char u2c_9D[512] = {
0x00, 0x00, 0xEA, 0x5E, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_9E[512] = {
+static const unsigned char u2c_9E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7542,7 +7542,7 @@ static unsigned char u2c_9E[512] = {
0xEA, 0x85, 0xEA, 0x86, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_9F[512] = {
+static const unsigned char u2c_9F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x87, /* 0x04-0x07 */
0xEA, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7587,11 +7587,11 @@ static unsigned char u2c_9F[512] = {
0xEA, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA0-0xA3 */
};
-static unsigned char u2c_DC[512] = {
+static const unsigned char u2c_DC[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
};
-static unsigned char u2c_F9[512] = {
+static const unsigned char u2c_F9[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7651,7 +7651,7 @@ static unsigned char u2c_F9[512] = {
0xEE, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */
};
-static unsigned char u2c_FA[512] = {
+static const unsigned char u2c_FA[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7666,7 +7666,7 @@ static unsigned char u2c_FA[512] = {
0xEE, 0xDD, 0xEE, 0xEA, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */
};
-static unsigned char u2c_FF[512] = {
+static const unsigned char u2c_FF[512] = {
0x00, 0x00, 0x81, 0x49, 0xEE, 0xFC, 0x81, 0x94, /* 0x00-0x03 */
0x81, 0x90, 0x81, 0x93, 0x81, 0x95, 0xEE, 0xFB, /* 0x04-0x07 */
0x81, 0x69, 0x81, 0x6A, 0x81, 0x96, 0x81, 0x7B, /* 0x08-0x0B */
@@ -7728,7 +7728,7 @@ static unsigned char u2c_FF[512] = {
0xEE, 0xFA, 0x81, 0x8F, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
NULL, NULL, NULL, u2c_03, u2c_04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -7762,7 +7762,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, u2c_F9, u2c_FA, NULL, NULL, NULL, NULL, u2c_FF, };
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -7798,7 +7798,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -7837,7 +7837,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(const wchar_t uni,
unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni&0xFF;
unsigned char ch = (uni>>8)&0xFF;
@@ -7878,7 +7878,7 @@ static int char2uni(const unsigned char *rawstring, int boundlen,
wchar_t *uni)
{
unsigned char ch, cl;
- wchar_t *charset2uni;
+ const wchar_t *charset2uni;
if (boundlen <= 0)
return -ENAMETOOLONG;
diff --git a/fs/nls/nls_cp936.c b/fs/nls/nls_cp936.c
index 65e640c61c8..82770301bc3 100644
--- a/fs/nls/nls_cp936.c
+++ b/fs/nls/nls_cp936.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t c2u_81[256] = {
+static const wchar_t c2u_81[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -49,7 +49,7 @@ static wchar_t c2u_81[256] = {
0x4F99,0x4F9A,0x4F9C,0x4F9E,0x4F9F,0x4FA1,0x4FA2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_82[256] = {
+static const wchar_t c2u_82[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -85,7 +85,7 @@ static wchar_t c2u_82[256] = {
0x50B4,0x50B5,0x50B6,0x50B7,0x50B8,0x50B9,0x50BC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_83[256] = {
+static const wchar_t c2u_83[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -121,7 +121,7 @@ static wchar_t c2u_83[256] = {
0x51D0,0x51D2,0x51D3,0x51D4,0x51D5,0x51D6,0x51D7,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_84[256] = {
+static const wchar_t c2u_84[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -157,7 +157,7 @@ static wchar_t c2u_84[256] = {
0x5304,0x5307,0x5309,0x530A,0x530B,0x530C,0x530E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_85[256] = {
+static const wchar_t c2u_85[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -193,7 +193,7 @@ static wchar_t c2u_85[256] = {
0x5497,0x5498,0x549C,0x549E,0x549F,0x54A0,0x54A1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_86[256] = {
+static const wchar_t c2u_86[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -229,7 +229,7 @@ static wchar_t c2u_86[256] = {
0x55FB,0x55FC,0x55FF,0x5602,0x5603,0x5604,0x5605,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_87[256] = {
+static const wchar_t c2u_87[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -265,7 +265,7 @@ static wchar_t c2u_87[256] = {
0x570B,0x570C,0x570D,0x570E,0x570F,0x5710,0x5711,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_88[256] = {
+static const wchar_t c2u_88[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -301,7 +301,7 @@ static wchar_t c2u_88[256] = {
0x5837,0x5838,0x5839,0x583A,0x583B,0x583C,0x583D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_89[256] = {
+static const wchar_t c2u_89[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -337,7 +337,7 @@ static wchar_t c2u_89[256] = {
0x592C,0x5930,0x5932,0x5933,0x5935,0x5936,0x593B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8A[256] = {
+static const wchar_t c2u_8A[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -373,7 +373,7 @@ static wchar_t c2u_8A[256] = {
0x5A59,0x5A5B,0x5A5C,0x5A5D,0x5A5E,0x5A5F,0x5A60,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8B[256] = {
+static const wchar_t c2u_8B[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -409,7 +409,7 @@ static wchar_t c2u_8B[256] = {
0x5B41,0x5B42,0x5B43,0x5B44,0x5B45,0x5B46,0x5B47,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8C[256] = {
+static const wchar_t c2u_8C[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -445,7 +445,7 @@ static wchar_t c2u_8C[256] = {
0x5CA0,0x5CA1,0x5CA4,0x5CA5,0x5CA6,0x5CA7,0x5CA8,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8D[256] = {
+static const wchar_t c2u_8D[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -481,7 +481,7 @@ static wchar_t c2u_8D[256] = {
0x5D98,0x5D9A,0x5D9B,0x5D9C,0x5D9E,0x5D9F,0x5DA0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8E[256] = {
+static const wchar_t c2u_8E[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -517,7 +517,7 @@ static wchar_t c2u_8E[256] = {
0x5EBF,0x5EC0,0x5EC1,0x5EC2,0x5EC3,0x5EC4,0x5EC5,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8F[256] = {
+static const wchar_t c2u_8F[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -553,7 +553,7 @@ static wchar_t c2u_8F[256] = {
0x5FF4,0x5FF6,0x5FF7,0x5FF9,0x5FFA,0x5FFC,0x6007,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_90[256] = {
+static const wchar_t c2u_90[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -589,7 +589,7 @@ static wchar_t c2u_90[256] = {
0x6140,0x6141,0x6142,0x6143,0x6144,0x6145,0x6146,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_91[256] = {
+static const wchar_t c2u_91[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -625,7 +625,7 @@ static wchar_t c2u_91[256] = {
0x623B,0x623C,0x6242,0x6244,0x6245,0x6246,0x624A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_92[256] = {
+static const wchar_t c2u_92[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -661,7 +661,7 @@ static wchar_t c2u_92[256] = {
0x63B5,0x63B6,0x63B9,0x63BB,0x63BD,0x63BF,0x63C0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_93[256] = {
+static const wchar_t c2u_93[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -697,7 +697,7 @@ static wchar_t c2u_93[256] = {
0x64D1,0x64D3,0x64D4,0x64D5,0x64D6,0x64D9,0x64DA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_94[256] = {
+static const wchar_t c2u_94[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -733,7 +733,7 @@ static wchar_t c2u_94[256] = {
0x65DE,0x65DF,0x65E1,0x65E3,0x65E4,0x65EA,0x65EB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_95[256] = {
+static const wchar_t c2u_95[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -769,7 +769,7 @@ static wchar_t c2u_95[256] = {
0x66F8,0x66FA,0x66FB,0x66FD,0x6701,0x6702,0x6703,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_96[256] = {
+static const wchar_t c2u_96[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -805,7 +805,7 @@ static wchar_t c2u_96[256] = {
0x6852,0x6856,0x6857,0x6858,0x6859,0x685A,0x685B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_97[256] = {
+static const wchar_t c2u_97[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -841,7 +841,7 @@ static wchar_t c2u_97[256] = {
0x6955,0x6956,0x6958,0x6959,0x695B,0x695C,0x695F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_98[256] = {
+static const wchar_t c2u_98[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -877,7 +877,7 @@ static wchar_t c2u_98[256] = {
0x6A52,0x6A53,0x6A54,0x6A55,0x6A56,0x6A57,0x6A5A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_99[256] = {
+static const wchar_t c2u_99[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -913,7 +913,7 @@ static wchar_t c2u_99[256] = {
0x6B28,0x6B29,0x6B2A,0x6B2B,0x6B2C,0x6B2D,0x6B2E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9A[256] = {
+static const wchar_t c2u_9A[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -949,7 +949,7 @@ static wchar_t c2u_9A[256] = {
0x6C4E,0x6C4F,0x6C51,0x6C52,0x6C53,0x6C56,0x6C58,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9B[256] = {
+static const wchar_t c2u_9B[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -985,7 +985,7 @@ static wchar_t c2u_9B[256] = {
0x6DBE,0x6DC1,0x6DC2,0x6DC3,0x6DC8,0x6DC9,0x6DCA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9C[256] = {
+static const wchar_t c2u_9C[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1021,7 +1021,7 @@ static wchar_t c2u_9C[256] = {
0x6EE7,0x6EEA,0x6EEB,0x6EEC,0x6EED,0x6EEE,0x6EEF,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9D[256] = {
+static const wchar_t c2u_9D[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1057,7 +1057,7 @@ static wchar_t c2u_9D[256] = {
0x6FDC,0x6FDD,0x6FDF,0x6FE2,0x6FE3,0x6FE4,0x6FE5,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9E[256] = {
+static const wchar_t c2u_9E[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1093,7 +1093,7 @@ static wchar_t c2u_9E[256] = {
0x70D2,0x70D3,0x70D4,0x70D5,0x70D6,0x70D7,0x70DA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9F[256] = {
+static const wchar_t c2u_9F[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1129,7 +1129,7 @@ static wchar_t c2u_9F[256] = {
0x71CC,0x71CD,0x71CF,0x71D0,0x71D1,0x71D2,0x71D3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A0[256] = {
+static const wchar_t c2u_A0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1165,7 +1165,7 @@ static wchar_t c2u_A0[256] = {
0x72D3,0x72D4,0x72D5,0x72D6,0x72D8,0x72DA,0x72DB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A1[256] = {
+static const wchar_t c2u_A1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1201,7 +1201,7 @@ static wchar_t c2u_A1[256] = {
0x25B2,0x203B,0x2192,0x2190,0x2191,0x2193,0x3013,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A2[256] = {
+static const wchar_t c2u_A2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1237,7 +1237,7 @@ static wchar_t c2u_A2[256] = {
0x2167,0x2168,0x2169,0x216A,0x216B,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A3[256] = {
+static const wchar_t c2u_A3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1273,7 +1273,7 @@ static wchar_t c2u_A3[256] = {
0xFF58,0xFF59,0xFF5A,0xFF5B,0xFF5C,0xFF5D,0xFFE3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A4[256] = {
+static const wchar_t c2u_A4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1308,7 +1308,7 @@ static wchar_t c2u_A4[256] = {
0x3090,0x3091,0x3092,0x3093,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_A5[256] = {
+static const wchar_t c2u_A5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1343,7 +1343,7 @@ static wchar_t c2u_A5[256] = {
0x30F0,0x30F1,0x30F2,0x30F3,0x30F4,0x30F5,0x30F6,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_A6[256] = {
+static const wchar_t c2u_A6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1378,7 +1378,7 @@ static wchar_t c2u_A6[256] = {
0xFE37,0xFE38,0xFE31,0x0000,0xFE33,0xFE34,0x0000,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_A7[256] = {
+static const wchar_t c2u_A7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1413,7 +1413,7 @@ static wchar_t c2u_A7[256] = {
0x044E,0x044F,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_A8[256] = {
+static const wchar_t c2u_A8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1447,7 +1447,7 @@ static wchar_t c2u_A8[256] = {
0x3128,0x3129,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE8-0xEF */
};
-static wchar_t c2u_A9[256] = {
+static const wchar_t c2u_A9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1481,7 +1481,7 @@ static wchar_t c2u_A9[256] = {
0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254A,0x254B,/* 0xE8-0xEF */
};
-static wchar_t c2u_AA[256] = {
+static const wchar_t c2u_AA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1506,7 +1506,7 @@ static wchar_t c2u_AA[256] = {
0x7371,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AB[256] = {
+static const wchar_t c2u_AB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1531,7 +1531,7 @@ static wchar_t c2u_AB[256] = {
0x73F7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AC[256] = {
+static const wchar_t c2u_AC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1556,7 +1556,7 @@ static wchar_t c2u_AC[256] = {
0x747A,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AD[256] = {
+static const wchar_t c2u_AD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1581,7 +1581,7 @@ static wchar_t c2u_AD[256] = {
0x74F2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AE[256] = {
+static const wchar_t c2u_AE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1606,7 +1606,7 @@ static wchar_t c2u_AE[256] = {
0x7587,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AF[256] = {
+static const wchar_t c2u_AF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1631,7 +1631,7 @@ static wchar_t c2u_AF[256] = {
0x7644,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_B0[256] = {
+static const wchar_t c2u_B0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1667,7 +1667,7 @@ static wchar_t c2u_B0[256] = {
0x508D,0x8C24,0x82DE,0x80DE,0x5305,0x8912,0x5265,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B1[256] = {
+static const wchar_t c2u_B1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1703,7 +1703,7 @@ static wchar_t c2u_B1[256] = {
0x5175,0x51B0,0x67C4,0x4E19,0x79C9,0x997C,0x70B3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B2[256] = {
+static const wchar_t c2u_B2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1739,7 +1739,7 @@ static wchar_t c2u_B2[256] = {
0x7F20,0x94F2,0x4EA7,0x9610,0x98A4,0x660C,0x7316,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B3[256] = {
+static const wchar_t c2u_B3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1775,7 +1775,7 @@ static wchar_t c2u_B3[256] = {
0x53A8,0x8E87,0x9504,0x96CF,0x6EC1,0x9664,0x695A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B4[256] = {
+static const wchar_t c2u_B4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1811,7 +1811,7 @@ static wchar_t c2u_B4[256] = {
0x5E26,0x6B86,0x4EE3,0x8D37,0x888B,0x5F85,0x902E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B5[256] = {
+static const wchar_t c2u_B5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1847,7 +1847,7 @@ static wchar_t c2u_B5[256] = {
0x8DCC,0x7239,0x789F,0x8776,0x8FED,0x8C0D,0x53E0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B6[256] = {
+static const wchar_t c2u_B6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1883,7 +1883,7 @@ static wchar_t c2u_B6[256] = {
0x800C,0x513F,0x8033,0x5C14,0x9975,0x6D31,0x4E8C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B7[256] = {
+static const wchar_t c2u_B7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1919,7 +1919,7 @@ static wchar_t c2u_B7[256] = {
0x8F90,0x5E45,0x6C1F,0x7B26,0x4F0F,0x4FD8,0x670D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B8[256] = {
+static const wchar_t c2u_B8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1955,7 +1955,7 @@ static wchar_t c2u_B8[256] = {
0x7ED9,0x6839,0x8DDF,0x8015,0x66F4,0x5E9A,0x7FB9,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B9[256] = {
+static const wchar_t c2u_B9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1991,7 +1991,7 @@ static wchar_t c2u_B9[256] = {
0x9505,0x90ED,0x56FD,0x679C,0x88F9,0x8FC7,0x54C8,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BA[256] = {
+static const wchar_t c2u_BA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2027,7 +2027,7 @@ static wchar_t c2u_BA[256] = {
0x58F6,0x846B,0x80E1,0x8774,0x72D0,0x7CCA,0x6E56,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BB[256] = {
+static const wchar_t c2u_BB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2063,7 +2063,7 @@ static wchar_t c2u_BB[256] = {
0x573E,0x57FA,0x673A,0x7578,0x7A3D,0x79EF,0x7B95,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BC[256] = {
+static const wchar_t c2u_BC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2099,7 +2099,7 @@ static wchar_t c2u_BC[256] = {
0x9274,0x8DF5,0x8D31,0x89C1,0x952E,0x7BAD,0x4EF6,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BD[256] = {
+static const wchar_t c2u_BD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2135,7 +2135,7 @@ static wchar_t c2u_BD[256] = {
0x8FDB,0x9773,0x664B,0x7981,0x8FD1,0x70EC,0x6D78,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BE[256] = {
+static const wchar_t c2u_BE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2171,7 +2171,7 @@ static wchar_t c2u_BE[256] = {
0x7EDD,0x5747,0x83CC,0x94A7,0x519B,0x541B,0x5CFB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BF[256] = {
+static const wchar_t c2u_BF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2207,7 +2207,7 @@ static wchar_t c2u_BF[256] = {
0x76D4,0x5CBF,0x7AA5,0x8475,0x594E,0x9B41,0x5080,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C0[256] = {
+static const wchar_t c2u_C0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2243,7 +2243,7 @@ static wchar_t c2u_C0[256] = {
0x52B1,0x783E,0x5386,0x5229,0x5088,0x4F8B,0x4FD0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C1[256] = {
+static const wchar_t c2u_C1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2279,7 +2279,7 @@ static wchar_t c2u_C1[256] = {
0x67F3,0x516D,0x9F99,0x804B,0x5499,0x7B3C,0x7ABF,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C2[256] = {
+static const wchar_t c2u_C2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2315,7 +2315,7 @@ static wchar_t c2u_C2[256] = {
0x9992,0x86EE,0x6EE1,0x8513,0x66FC,0x6162,0x6F2B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C3[256] = {
+static const wchar_t c2u_C3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2351,7 +2351,7 @@ static wchar_t c2u_C3[256] = {
0x879F,0x9E23,0x94ED,0x540D,0x547D,0x8C2C,0x6478,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C4[256] = {
+static const wchar_t c2u_C4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2387,7 +2387,7 @@ static wchar_t c2u_C4[256] = {
0x954D,0x6D85,0x60A8,0x67E0,0x72DE,0x51DD,0x5B81,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C5[256] = {
+static const wchar_t c2u_C5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2423,7 +2423,7 @@ static wchar_t c2u_C5[256] = {
0x7812,0x9739,0x6279,0x62AB,0x5288,0x7435,0x6BD7,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C6[256] = {
+static const wchar_t c2u_C6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2459,7 +2459,7 @@ static wchar_t c2u_C6[256] = {
0x6C14,0x8FC4,0x5F03,0x6C7D,0x6CE3,0x8BAB,0x6390,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C7[256] = {
+static const wchar_t c2u_C7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2495,7 +2495,7 @@ static wchar_t c2u_C7[256] = {
0x533A,0x86C6,0x66F2,0x8EAF,0x5C48,0x9A71,0x6E20,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C8[256] = {
+static const wchar_t c2u_C8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2531,7 +2531,7 @@ static wchar_t c2u_C8[256] = {
0x8428,0x816E,0x9CC3,0x585E,0x8D5B,0x4E09,0x53C1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C9[256] = {
+static const wchar_t c2u_C9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2567,7 +2567,7 @@ static wchar_t c2u_C9[256] = {
0x6E17,0x58F0,0x751F,0x7525,0x7272,0x5347,0x7EF3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CA[256] = {
+static const wchar_t c2u_CA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2603,7 +2603,7 @@ static wchar_t c2u_CA[256] = {
0x675F,0x620D,0x7AD6,0x5885,0x5EB6,0x6570,0x6F31,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CB[256] = {
+static const wchar_t c2u_CB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2639,7 +2639,7 @@ static wchar_t c2u_CB[256] = {
0x9501,0x6240,0x584C,0x4ED6,0x5B83,0x5979,0x5854,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CC[256] = {
+static const wchar_t c2u_CC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2675,7 +2675,7 @@ static wchar_t c2u_CC[256] = {
0x8DF3,0x8D34,0x94C1,0x5E16,0x5385,0x542C,0x70C3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CD[256] = {
+static const wchar_t c2u_CD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2711,7 +2711,7 @@ static wchar_t c2u_CD[256] = {
0x7F51,0x5F80,0x65FA,0x671B,0x5FD8,0x5984,0x5A01,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CE[256] = {
+static const wchar_t c2u_CE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2747,7 +2747,7 @@ static wchar_t c2u_CE[256] = {
0x7852,0x77FD,0x6670,0x563B,0x5438,0x9521,0x727A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CF[256] = {
+static const wchar_t c2u_CF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2783,7 +2783,7 @@ static wchar_t c2u_CF[256] = {
0x54EE,0x56A3,0x9500,0x6D88,0x5BB5,0x6DC6,0x6653,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D0[256] = {
+static const wchar_t c2u_D0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2819,7 +2819,7 @@ static wchar_t c2u_D0[256] = {
0x7EED,0x8F69,0x55A7,0x5BA3,0x60AC,0x65CB,0x7384,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D1[256] = {
+static const wchar_t c2u_D1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2855,7 +2855,7 @@ static wchar_t c2u_D1[256] = {
0x517B,0x6837,0x6F3E,0x9080,0x8170,0x5996,0x7476,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D2[256] = {
+static const wchar_t c2u_D2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2891,7 +2891,7 @@ static wchar_t c2u_D2[256] = {
0x94F6,0x6DEB,0x5BC5,0x996E,0x5C39,0x5F15,0x9690,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D3[256] = {
+static const wchar_t c2u_D3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2927,7 +2927,7 @@ static wchar_t c2u_D3[256] = {
0x5CEA,0x5FA1,0x6108,0x6B32,0x72F1,0x80B2,0x8A89,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D4[256] = {
+static const wchar_t c2u_D4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2963,7 +2963,7 @@ static wchar_t c2u_D4[256] = {
0x66FE,0x8D60,0x624E,0x55B3,0x6E23,0x672D,0x8F67,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D5[256] = {
+static const wchar_t c2u_D5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2999,7 +2999,7 @@ static wchar_t c2u_D5[256] = {
0x72F0,0x4E89,0x6014,0x6574,0x62EF,0x6B63,0x653F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D6[256] = {
+static const wchar_t c2u_D6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3035,7 +3035,7 @@ static wchar_t c2u_D6[256] = {
0x8457,0x67F1,0x52A9,0x86C0,0x8D2E,0x94F8,0x7B51,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D7[256] = {
+static const wchar_t c2u_D7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3071,7 +3071,7 @@ static wchar_t c2u_D7[256] = {
0x5750,0x5EA7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D8[256] = {
+static const wchar_t c2u_D8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3107,7 +3107,7 @@ static wchar_t c2u_D8[256] = {
0x4F09,0x4F2B,0x4F5E,0x4F67,0x6538,0x4F5A,0x4F5D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D9[256] = {
+static const wchar_t c2u_D9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3143,7 +3143,7 @@ static wchar_t c2u_D9[256] = {
0x5B34,0x8803,0x7FB8,0x51AB,0x51B1,0x51BD,0x51BC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DA[256] = {
+static const wchar_t c2u_DA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3179,7 +3179,7 @@ static wchar_t c2u_DA[256] = {
0x9099,0x90AC,0x90A1,0x90B4,0x90B3,0x90B6,0x90BA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DB[256] = {
+static const wchar_t c2u_DB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3215,7 +3215,7 @@ static wchar_t c2u_DB[256] = {
0x57D2,0x57B8,0x57F4,0x57EF,0x57F8,0x57E4,0x57DD,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DC[256] = {
+static const wchar_t c2u_DC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3251,7 +3251,7 @@ static wchar_t c2u_DC[256] = {
0x8317,0x8360,0x832D,0x833A,0x8333,0x8366,0x8365,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DD[256] = {
+static const wchar_t c2u_DD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3287,7 +3287,7 @@ static wchar_t c2u_DD[256] = {
0x850C,0x750D,0x8538,0x84F0,0x8539,0x851F,0x853A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DE[256] = {
+static const wchar_t c2u_DE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3323,7 +3323,7 @@ static wchar_t c2u_DE[256] = {
0x640C,0x6426,0x6421,0x645E,0x6484,0x646D,0x6496,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DF[256] = {
+static const wchar_t c2u_DF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3359,7 +3359,7 @@ static wchar_t c2u_DF[256] = {
0x5549,0x556D,0x5541,0x5555,0x553F,0x5550,0x553C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E0[256] = {
+static const wchar_t c2u_E0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3395,7 +3395,7 @@ static wchar_t c2u_E0[256] = {
0x5E0F,0x5E19,0x5E14,0x5E11,0x5E31,0x5E3B,0x5E3C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E1[256] = {
+static const wchar_t c2u_E1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3431,7 +3431,7 @@ static wchar_t c2u_E1[256] = {
0x72F2,0x72F4,0x72F7,0x7301,0x72F3,0x7303,0x72FA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E2[256] = {
+static const wchar_t c2u_E2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3467,7 +3467,7 @@ static wchar_t c2u_E2[256] = {
0x603F,0x6021,0x6078,0x6079,0x607B,0x607A,0x6042,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E3[256] = {
+static const wchar_t c2u_E3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3503,7 +3503,7 @@ static wchar_t c2u_E3[256] = {
0x6CFA,0x6CEB,0x6CEE,0x6CB1,0x6CD3,0x6CEF,0x6CFE,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E4[256] = {
+static const wchar_t c2u_E4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3539,7 +3539,7 @@ static wchar_t c2u_E4[256] = {
0x6F8D,0x6F8C,0x6F78,0x6F72,0x6F7C,0x6F7A,0x6FD1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E5[256] = {
+static const wchar_t c2u_E5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3575,7 +3575,7 @@ static wchar_t c2u_E5[256] = {
0x5C6E,0x5981,0x5983,0x598D,0x59A9,0x59AA,0x59A3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E6[256] = {
+static const wchar_t c2u_E6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3611,7 +3611,7 @@ static wchar_t c2u_E6[256] = {
0x9AA7,0x7E9F,0x7EA1,0x7EA3,0x7EA5,0x7EA8,0x7EA9,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E7[256] = {
+static const wchar_t c2u_E7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3647,7 +3647,7 @@ static wchar_t c2u_E7[256] = {
0x745B,0x7426,0x7425,0x7428,0x7430,0x742E,0x742C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E8[256] = {
+static const wchar_t c2u_E8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3683,7 +3683,7 @@ static wchar_t c2u_E8[256] = {
0x686B,0x68C2,0x696E,0x68FC,0x691F,0x6920,0x68F9,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E9[256] = {
+static const wchar_t c2u_E9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3719,7 +3719,7 @@ static wchar_t c2u_E9[256] = {
0x8F7C,0x8F7E,0x8F81,0x8F82,0x8F84,0x8F87,0x8F8B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EA[256] = {
+static const wchar_t c2u_EA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3755,7 +3755,7 @@ static wchar_t c2u_EA[256] = {
0x728B,0x728D,0x728F,0x7292,0x6308,0x6332,0x63B0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EB[256] = {
+static const wchar_t c2u_EB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3791,7 +3791,7 @@ static wchar_t c2u_EB[256] = {
0x6ED5,0x81A3,0x81AA,0x81CC,0x6726,0x81CA,0x81BB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EC[256] = {
+static const wchar_t c2u_EC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3827,7 +3827,7 @@ static wchar_t c2u_EC[256] = {
0x7985,0x798A,0x799A,0x79A7,0x79B3,0x5FD1,0x5FD0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_ED[256] = {
+static const wchar_t c2u_ED[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3863,7 +3863,7 @@ static wchar_t c2u_ED[256] = {
0x7738,0x7750,0x7751,0x7747,0x7743,0x775A,0x7768,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EE[256] = {
+static const wchar_t c2u_EE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3899,7 +3899,7 @@ static wchar_t c2u_EE[256] = {
0x94E0,0x94E2,0x94E4,0x94E5,0x94E7,0x94E8,0x94EA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EF[256] = {
+static const wchar_t c2u_EF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3935,7 +3935,7 @@ static wchar_t c2u_EF[256] = {
0x79EB,0x7A06,0x5D47,0x7A03,0x7A02,0x7A1E,0x7A14,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F0[256] = {
+static const wchar_t c2u_F0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3971,7 +3971,7 @@ static wchar_t c2u_F0[256] = {
0x760C,0x7617,0x760A,0x7625,0x7618,0x7615,0x7619,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F1[256] = {
+static const wchar_t c2u_F1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4007,7 +4007,7 @@ static wchar_t c2u_F1[256] = {
0x8052,0x8069,0x8071,0x8983,0x9878,0x9880,0x9883,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F2[256] = {
+static const wchar_t c2u_F2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4043,7 +4043,7 @@ static wchar_t c2u_F2[256] = {
0x8764,0x8759,0x8765,0x8793,0x87AF,0x87A8,0x87D2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F3[256] = {
+static const wchar_t c2u_F3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4079,7 +4079,7 @@ static wchar_t c2u_F3[256] = {
0x7BEA,0x7C0C,0x7BFE,0x7BFC,0x7C0F,0x7C16,0x7C0B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F4[256] = {
+static const wchar_t c2u_F4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4115,7 +4115,7 @@ static wchar_t c2u_F4[256] = {
0x8C47,0x8C49,0x914A,0x9150,0x914E,0x914F,0x9164,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F5[256] = {
+static const wchar_t c2u_F5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4151,7 +4151,7 @@ static wchar_t c2u_F5[256] = {
0x8C98,0x8C94,0x659B,0x89D6,0x89DE,0x89DA,0x89DC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F6[256] = {
+static const wchar_t c2u_F6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4187,7 +4187,7 @@ static wchar_t c2u_F6[256] = {
0x9CBD,0x9CC4,0x9CC5,0x9CC6,0x9CC7,0x9CCA,0x9CCB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F7[256] = {
+static const wchar_t c2u_F7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4223,7 +4223,7 @@ static wchar_t c2u_F7[256] = {
0x9F2C,0x9F2F,0x9F39,0x9F37,0x9F3D,0x9F3E,0x9F44,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F8[256] = {
+static const wchar_t c2u_F8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4248,7 +4248,7 @@ static wchar_t c2u_F8[256] = {
0x9D42,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_F9[256] = {
+static const wchar_t c2u_F9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4273,7 +4273,7 @@ static wchar_t c2u_F9[256] = {
0x9DA2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_FA[256] = {
+static const wchar_t c2u_FA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4298,7 +4298,7 @@ static wchar_t c2u_FA[256] = {
0x9E02,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_FB[256] = {
+static const wchar_t c2u_FB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4323,7 +4323,7 @@ static wchar_t c2u_FB[256] = {
0x9EAA,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_FC[256] = {
+static const wchar_t c2u_FC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4348,7 +4348,7 @@ static wchar_t c2u_FC[256] = {
0x9F31,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_FD[256] = {
+static const wchar_t c2u_FD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4373,7 +4373,7 @@ static wchar_t c2u_FD[256] = {
0xF9F1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_FE[256] = {
+static const wchar_t c2u_FE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4386,7 +4386,7 @@ static wchar_t c2u_FE[256] = {
0xFA1F,0xFA20,0xFA21,0xFA23,0xFA24,0xFA27,0xFA28,0xFA29,/* 0x48-0x4F */
};
-static wchar_t *page_charset2uni[256] = {
+static const wchar_t *page_charset2uni[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -4421,7 +4421,7 @@ static wchar_t *page_charset2uni[256] = {
c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, c2u_FE, NULL,
};
-static unsigned char u2c_00[512] = {
+static const unsigned char u2c_00[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4488,7 +4488,7 @@ static unsigned char u2c_00[512] = {
0xA8, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_01[512] = {
+static const unsigned char u2c_01[512] = {
0xA8, 0xA1, 0xA8, 0xA1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4548,7 +4548,7 @@ static unsigned char u2c_01[512] = {
0xA8, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */
};
-static unsigned char u2c_02[512] = {
+static const unsigned char u2c_02[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4607,7 +4607,7 @@ static unsigned char u2c_02[512] = {
0x00, 0x00, 0xA8, 0x42, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */
};
-static unsigned char u2c_03[512] = {
+static const unsigned char u2c_03[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4662,7 +4662,7 @@ static unsigned char u2c_03[512] = {
0xA6, 0xD7, 0xA6, 0xD8, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */
};
-static unsigned char u2c_04[512] = {
+static const unsigned char u2c_04[512] = {
0x00, 0x00, 0xA7, 0xA7, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4686,7 +4686,7 @@ static unsigned char u2c_04[512] = {
0x00, 0x00, 0xA7, 0xD7, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x53 */
};
-static unsigned char u2c_20[512] = {
+static const unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4705,7 +4705,7 @@ static unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0xA3, 0xFE, 0x00, 0x00, /* 0x3C-0x3F */
};
-static unsigned char u2c_21[512] = {
+static const unsigned char u2c_21[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xE6, /* 0x00-0x03 */
0x00, 0x00, 0xA8, 0x47, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xA8, 0x48, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4748,7 +4748,7 @@ static unsigned char u2c_21[512] = {
0xA8, 0x4B, 0xA8, 0x4C, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */
};
-static unsigned char u2c_22[512] = {
+static const unsigned char u2c_22[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xA1, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4800,7 +4800,7 @@ static unsigned char u2c_22[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x53, /* 0xBC-0xBF */
};
-static unsigned char u2c_23[512] = {
+static const unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4808,7 +4808,7 @@ static unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0xA1, 0xD0, 0x00, 0x00, /* 0x10-0x13 */
};
-static unsigned char u2c_24[512] = {
+static const unsigned char u2c_24[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4851,7 +4851,7 @@ static unsigned char u2c_24[512] = {
0xA2, 0xC1, 0xA2, 0xC2, 0xA2, 0xC3, 0xA2, 0xC4, /* 0x98-0x9B */
};
-static unsigned char u2c_25[512] = {
+static const unsigned char u2c_25[512] = {
0xA9, 0xA4, 0xA9, 0xA5, 0xA9, 0xA6, 0xA9, 0xA7, /* 0x00-0x03 */
0xA9, 0xA8, 0xA9, 0xA9, 0xA9, 0xAA, 0xA9, 0xAB, /* 0x04-0x07 */
0xA9, 0xAC, 0xA9, 0xAD, 0xA9, 0xAE, 0xA9, 0xAF, /* 0x08-0x0B */
@@ -4919,7 +4919,7 @@ static unsigned char u2c_25[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_26[512] = {
+static const unsigned char u2c_26[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA1, 0xEF, 0xA1, 0xEE, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xA8, 0x91, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4939,7 +4939,7 @@ static unsigned char u2c_26[512] = {
0xA1, 0xE2, 0x00, 0x00, 0xA1, 0xE1, 0x00, 0x00, /* 0x40-0x43 */
};
-static unsigned char u2c_30[512] = {
+static const unsigned char u2c_30[512] = {
0xA1, 0xA1, 0xA1, 0xA2, 0xA1, 0xA3, 0xA1, 0xA8, /* 0x00-0x03 */
0x00, 0x00, 0xA1, 0xA9, 0xA9, 0x65, 0xA9, 0x96, /* 0x04-0x07 */
0xA1, 0xB4, 0xA1, 0xB5, 0xA1, 0xB6, 0xA1, 0xB7, /* 0x08-0x0B */
@@ -5007,7 +5007,7 @@ static unsigned char u2c_30[512] = {
0xA9, 0x60, 0xA9, 0x63, 0xA9, 0x64, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_31[512] = {
+static const unsigned char u2c_31[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA8, 0xC5, 0xA8, 0xC6, 0xA8, 0xC7, /* 0x04-0x07 */
0xA8, 0xC8, 0xA8, 0xC9, 0xA8, 0xCA, 0xA8, 0xCB, /* 0x08-0x0B */
@@ -5051,7 +5051,7 @@ static unsigned char u2c_31[512] = {
0xB6, 0xA1, 0xCC, 0xEC, 0xB5, 0xD8, 0xC8, 0xCB, /* 0x9C-0x9F */
};
-static unsigned char u2c_32[512] = {
+static const unsigned char u2c_32[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5100,7 +5100,7 @@ static unsigned char u2c_32[512] = {
0xD2, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */
};
-static unsigned char u2c_33[512] = {
+static const unsigned char u2c_33[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5158,7 +5158,7 @@ static unsigned char u2c_33[512] = {
0x00, 0x00, 0xA9, 0x54, 0x00, 0x00, 0x00, 0x00, /* 0xD4-0xD7 */
};
-static unsigned char u2c_4E[512] = {
+static const unsigned char u2c_4E[512] = {
0xD2, 0xBB, 0xB6, 0xA1, 0x81, 0x40, 0xC6, 0xDF, /* 0x00-0x03 */
0x81, 0x41, 0x81, 0x42, 0x81, 0x43, 0xCD, 0xF2, /* 0x04-0x07 */
0xD5, 0xC9, 0xC8, 0xFD, 0xC9, 0xCF, 0xCF, 0xC2, /* 0x08-0x0B */
@@ -5226,7 +5226,7 @@ static unsigned char u2c_4E[512] = {
0x81, 0xA9, 0xB7, 0xDD, 0x81, 0xAA, 0xB7, 0xC2, /* 0xFC-0xFF */
};
-static unsigned char u2c_4F[512] = {
+static const unsigned char u2c_4F[512] = {
0x81, 0xAB, 0xC6, 0xF3, 0x81, 0xAC, 0x81, 0xAD, /* 0x00-0x03 */
0x81, 0xAE, 0x81, 0xAF, 0x81, 0xB0, 0x81, 0xB1, /* 0x04-0x07 */
0x81, 0xB2, 0xD8, 0xF8, 0xD2, 0xC1, 0x81, 0xB3, /* 0x08-0x0B */
@@ -5294,7 +5294,7 @@ static unsigned char u2c_4F[512] = {
0x82, 0x71, 0x82, 0x72, 0xD9, 0xC2, 0x82, 0x73, /* 0xFC-0xFF */
};
-static unsigned char u2c_50[512] = {
+static const unsigned char u2c_50[512] = {
0x82, 0x74, 0x82, 0x75, 0x82, 0x76, 0x82, 0x77, /* 0x00-0x03 */
0x82, 0x78, 0x82, 0x79, 0x82, 0x7A, 0x82, 0x7B, /* 0x04-0x07 */
0x82, 0x7C, 0x82, 0x7D, 0x82, 0x7E, 0x82, 0x80, /* 0x08-0x0B */
@@ -5362,7 +5362,7 @@ static unsigned char u2c_50[512] = {
0x83, 0x74, 0x83, 0x75, 0x83, 0x76, 0x83, 0x77, /* 0xFC-0xFF */
};
-static unsigned char u2c_51[512] = {
+static const unsigned char u2c_51[512] = {
0x83, 0x78, 0x83, 0x79, 0x83, 0x7A, 0x83, 0x7B, /* 0x00-0x03 */
0x83, 0x7C, 0x83, 0x7D, 0xD9, 0xD3, 0xD9, 0xD8, /* 0x04-0x07 */
0x83, 0x7E, 0x83, 0x80, 0x83, 0x81, 0xD9, 0xD9, /* 0x08-0x0B */
@@ -5430,7 +5430,7 @@ static unsigned char u2c_51[512] = {
0xDB, 0xCA, 0xBA, 0xAF, 0x84, 0x54, 0xD4, 0xE4, /* 0xFC-0xFF */
};
-static unsigned char u2c_52[512] = {
+static const unsigned char u2c_52[512] = {
0xB5, 0xB6, 0xB5, 0xF3, 0xD8, 0xD6, 0xC8, 0xD0, /* 0x00-0x03 */
0x84, 0x55, 0x84, 0x56, 0xB7, 0xD6, 0xC7, 0xD0, /* 0x04-0x07 */
0xD8, 0xD7, 0x84, 0x57, 0xBF, 0xAF, 0x84, 0x58, /* 0x08-0x0B */
@@ -5498,7 +5498,7 @@ static unsigned char u2c_52[512] = {
0x84, 0xF3, 0x84, 0xF4, 0xB9, 0xB4, 0xCE, 0xF0, /* 0xFC-0xFF */
};
-static unsigned char u2c_53[512] = {
+static const unsigned char u2c_53[512] = {
0xD4, 0xC8, 0x84, 0xF5, 0x84, 0xF6, 0x84, 0xF7, /* 0x00-0x03 */
0x84, 0xF8, 0xB0, 0xFC, 0xB4, 0xD2, 0x84, 0xF9, /* 0x04-0x07 */
0xD0, 0xD9, 0x84, 0xFA, 0x84, 0xFB, 0x84, 0xFC, /* 0x08-0x0B */
@@ -5566,7 +5566,7 @@ static unsigned char u2c_53[512] = {
0xB5, 0xF0, 0xDF, 0xB4, 0x85, 0xB6, 0x85, 0xB7, /* 0xFC-0xFF */
};
-static unsigned char u2c_54[512] = {
+static const unsigned char u2c_54[512] = {
0x85, 0xB8, 0xD3, 0xF5, 0x85, 0xB9, 0xB3, 0xD4, /* 0x00-0x03 */
0xB8, 0xF7, 0x85, 0xBA, 0xDF, 0xBA, 0x85, 0xBB, /* 0x04-0x07 */
0xBA, 0xCF, 0xBC, 0xAA, 0xB5, 0xF5, 0x85, 0xBC, /* 0x08-0x0B */
@@ -5634,7 +5634,7 @@ static unsigned char u2c_54[512] = {
0xBA, 0xDF, 0xDF, 0xEC, 0x86, 0x64, 0xDB, 0xC1, /* 0xFC-0xFF */
};
-static unsigned char u2c_55[512] = {
+static const unsigned char u2c_55[512] = {
0x86, 0x65, 0xD1, 0xE4, 0x86, 0x66, 0x86, 0x67, /* 0x00-0x03 */
0x86, 0x68, 0x86, 0x69, 0xCB, 0xF4, 0xB4, 0xBD, /* 0x04-0x07 */
0x86, 0x6A, 0xB0, 0xA6, 0x86, 0x6B, 0x86, 0x6C, /* 0x08-0x0B */
@@ -5702,7 +5702,7 @@ static unsigned char u2c_55[512] = {
0x86, 0xF9, 0xCB, 0xD4, 0xE0, 0xD5, 0x86, 0xFA, /* 0xFC-0xFF */
};
-static unsigned char u2c_56[512] = {
+static const unsigned char u2c_56[512] = {
0xE0, 0xD6, 0xE0, 0xD2, 0x86, 0xFB, 0x86, 0xFC, /* 0x00-0x03 */
0x86, 0xFD, 0x86, 0xFE, 0x87, 0x40, 0x87, 0x41, /* 0x04-0x07 */
0xE0, 0xD0, 0xBC, 0xCE, 0x87, 0x42, 0x87, 0x43, /* 0x08-0x0B */
@@ -5770,7 +5770,7 @@ static unsigned char u2c_56[512] = {
0x87, 0xF2, 0xB9, 0xFA, 0xCD, 0xBC, 0xE0, 0xF3, /* 0xFC-0xFF */
};
-static unsigned char u2c_57[512] = {
+static const unsigned char u2c_57[512] = {
0x87, 0xF3, 0x87, 0xF4, 0x87, 0xF5, 0xC6, 0xD4, /* 0x00-0x03 */
0xE0, 0xF4, 0x87, 0xF6, 0xD4, 0xB2, 0x87, 0xF7, /* 0x04-0x07 */
0xC8, 0xA6, 0xE0, 0xF6, 0xE0, 0xF5, 0x87, 0xF8, /* 0x08-0x0B */
@@ -5838,7 +5838,7 @@ static unsigned char u2c_57[512] = {
0x88, 0xCE, 0xDC, 0xA3, 0x88, 0xCF, 0x88, 0xD0, /* 0xFC-0xFF */
};
-static unsigned char u2c_58[512] = {
+static const unsigned char u2c_58[512] = {
0xDC, 0xA5, 0x88, 0xD1, 0xCC, 0xC3, 0x88, 0xD2, /* 0x00-0x03 */
0x88, 0xD3, 0x88, 0xD4, 0xB6, 0xD1, 0xDD, 0xC0, /* 0x04-0x07 */
0x88, 0xD5, 0x88, 0xD6, 0x88, 0xD7, 0xDC, 0xA1, /* 0x08-0x0B */
@@ -5906,7 +5906,7 @@ static unsigned char u2c_58[512] = {
0x89, 0xDA, 0x89, 0xDB, 0x89, 0xDC, 0x89, 0xDD, /* 0xFC-0xFF */
};
-static unsigned char u2c_59[512] = {
+static const unsigned char u2c_59[512] = {
0x89, 0xDE, 0x89, 0xDF, 0xE2, 0xBA, 0x89, 0xE0, /* 0x00-0x03 */
0xB4, 0xA6, 0x89, 0xE1, 0x89, 0xE2, 0xB1, 0xB8, /* 0x04-0x07 */
0x89, 0xE3, 0x89, 0xE4, 0x89, 0xE5, 0x89, 0xE6, /* 0x08-0x0B */
@@ -5974,7 +5974,7 @@ static unsigned char u2c_59[512] = {
0x8A, 0xB8, 0x8A, 0xB9, 0x8A, 0xBA, 0xD7, 0xCB, /* 0xFC-0xFF */
};
-static unsigned char u2c_5A[512] = {
+static const unsigned char u2c_5A[512] = {
0x8A, 0xBB, 0xCD, 0xFE, 0x8A, 0xBC, 0xCD, 0xDE, /* 0x00-0x03 */
0xC2, 0xA6, 0xE6, 0xAB, 0xE6, 0xAC, 0xBD, 0xBF, /* 0x04-0x07 */
0xE6, 0xAE, 0xE6, 0xB3, 0x8A, 0xBD, 0x8A, 0xBE, /* 0x08-0x0B */
@@ -6042,7 +6042,7 @@ static unsigned char u2c_5A[512] = {
0x8B, 0xBA, 0x8B, 0xBB, 0x8B, 0xBC, 0x8B, 0xBD, /* 0xFC-0xFF */
};
-static unsigned char u2c_5B[512] = {
+static const unsigned char u2c_5B[512] = {
0x8B, 0xBE, 0x8B, 0xBF, 0x8B, 0xC0, 0x8B, 0xC1, /* 0x00-0x03 */
0x8B, 0xC2, 0x8B, 0xC3, 0x8B, 0xC4, 0x8B, 0xC5, /* 0x04-0x07 */
0x8B, 0xC6, 0xE6, 0xD2, 0x8B, 0xC7, 0x8B, 0xC8, /* 0x08-0x0B */
@@ -6110,7 +6110,7 @@ static unsigned char u2c_5B[512] = {
0xB5, 0xBC, 0x8C, 0x9C, 0x8C, 0x9D, 0xCA, 0xD9, /* 0xFC-0xFF */
};
-static unsigned char u2c_5C[512] = {
+static const unsigned char u2c_5C[512] = {
0x8C, 0x9E, 0xB7, 0xE2, 0x8C, 0x9F, 0x8C, 0xA0, /* 0x00-0x03 */
0xC9, 0xE4, 0x8C, 0xA1, 0xBD, 0xAB, 0x8C, 0xA2, /* 0x04-0x07 */
0x8C, 0xA3, 0xCE, 0xBE, 0xD7, 0xF0, 0x8C, 0xA4, /* 0x08-0x0B */
@@ -6178,7 +6178,7 @@ static unsigned char u2c_5C[512] = {
0x8D, 0x7A, 0x8D, 0x7B, 0x8D, 0x7C, 0x8D, 0x7D, /* 0xFC-0xFF */
};
-static unsigned char u2c_5D[512] = {
+static const unsigned char u2c_5D[512] = {
0x8D, 0x7E, 0x8D, 0x80, 0xE1, 0xC0, 0xE1, 0xC1, /* 0x00-0x03 */
0x8D, 0x81, 0x8D, 0x82, 0xE1, 0xC7, 0xB3, 0xE7, /* 0x04-0x07 */
0x8D, 0x83, 0x8D, 0x84, 0x8D, 0x85, 0x8D, 0x86, /* 0x08-0x0B */
@@ -6246,7 +6246,7 @@ static unsigned char u2c_5D[512] = {
0x8E, 0x87, 0xD9, 0xE3, 0xBD, 0xED, 0x8E, 0x88, /* 0xFC-0xFF */
};
-static unsigned char u2c_5E[512] = {
+static const unsigned char u2c_5E[512] = {
0x8E, 0x89, 0xB1, 0xD2, 0xCA, 0xD0, 0xB2, 0xBC, /* 0x00-0x03 */
0x8E, 0x8A, 0xCB, 0xA7, 0xB7, 0xAB, 0x8E, 0x8B, /* 0x04-0x07 */
0xCA, 0xA6, 0x8E, 0x8C, 0x8E, 0x8D, 0x8E, 0x8E, /* 0x08-0x0B */
@@ -6314,7 +6314,7 @@ static unsigned char u2c_5E[512] = {
0x8F, 0x69, 0x8F, 0x6A, 0xDE, 0xC3, 0xD8, 0xA5, /* 0xFC-0xFF */
};
-static unsigned char u2c_5F[512] = {
+static const unsigned char u2c_5F[512] = {
0xBF, 0xAA, 0xDB, 0xCD, 0xD2, 0xEC, 0xC6, 0xFA, /* 0x00-0x03 */
0xC5, 0xAA, 0x8F, 0x6B, 0x8F, 0x6C, 0x8F, 0x6D, /* 0x04-0x07 */
0xDE, 0xC4, 0x8F, 0x6E, 0xB1, 0xD7, 0xDF, 0xAE, /* 0x08-0x0B */
@@ -6382,7 +6382,7 @@ static unsigned char u2c_5F[512] = {
0x8F, 0xFD, 0xBA, 0xF6, 0xE2, 0xE9, 0xB7, 0xDE, /* 0xFC-0xFF */
};
-static unsigned char u2c_60[512] = {
+static const unsigned char u2c_60[512] = {
0xBB, 0xB3, 0xCC, 0xAC, 0xCB, 0xCB, 0xE2, 0xE4, /* 0x00-0x03 */
0xE2, 0xE6, 0xE2, 0xEA, 0xE2, 0xEB, 0x8F, 0xFE, /* 0x04-0x07 */
0x90, 0x40, 0x90, 0x41, 0xE2, 0xF7, 0x90, 0x42, /* 0x08-0x0B */
@@ -6450,7 +6450,7 @@ static unsigned char u2c_60[512] = {
0x90, 0xC6, 0x90, 0xC7, 0x90, 0xC8, 0x90, 0xC9, /* 0xFC-0xFF */
};
-static unsigned char u2c_61[512] = {
+static const unsigned char u2c_61[512] = {
0xE3, 0xB8, 0xB3, 0xEE, 0x90, 0xCA, 0x90, 0xCB, /* 0x00-0x03 */
0x90, 0xCC, 0x90, 0xCD, 0xED, 0xA9, 0x90, 0xCE, /* 0x04-0x07 */
0xD3, 0xFA, 0xD3, 0xE4, 0x90, 0xCF, 0x90, 0xD0, /* 0x08-0x0B */
@@ -6518,7 +6518,7 @@ static unsigned char u2c_61[512] = {
0x91, 0xD6, 0x91, 0xD7, 0x91, 0xD8, 0xDC, 0xB2, /* 0xFC-0xFF */
};
-static unsigned char u2c_62[512] = {
+static const unsigned char u2c_62[512] = {
0x91, 0xD9, 0x91, 0xDA, 0x91, 0xDB, 0x91, 0xDC, /* 0x00-0x03 */
0x91, 0xDD, 0x91, 0xDE, 0xED, 0xB0, 0x91, 0xDF, /* 0x04-0x07 */
0xB8, 0xEA, 0x91, 0xE0, 0xCE, 0xEC, 0xEA, 0xA7, /* 0x08-0x0B */
@@ -6586,7 +6586,7 @@ static unsigned char u2c_62[512] = {
0xC6, 0xB4, 0xD7, 0xA7, 0xCA, 0xB0, 0xC4, 0xC3, /* 0xFC-0xFF */
};
-static unsigned char u2c_63[512] = {
+static const unsigned char u2c_63[512] = {
0x92, 0x93, 0xB3, 0xD6, 0xB9, 0xD2, 0x92, 0x94, /* 0x00-0x03 */
0x92, 0x95, 0x92, 0x96, 0x92, 0x97, 0xD6, 0xB8, /* 0x04-0x07 */
0xEA, 0xFC, 0xB0, 0xB4, 0x92, 0x98, 0x92, 0x99, /* 0x08-0x0B */
@@ -6654,7 +6654,7 @@ static unsigned char u2c_63[512] = {
0x93, 0x67, 0xC0, 0xBF, 0x93, 0x68, 0xDE, 0xEC, /* 0xFC-0xFF */
};
-static unsigned char u2c_64[512] = {
+static const unsigned char u2c_64[512] = {
0xB2, 0xF3, 0xB8, 0xE9, 0xC2, 0xA7, 0x93, 0x69, /* 0x00-0x03 */
0x93, 0x6A, 0xBD, 0xC1, 0x93, 0x6B, 0x93, 0x6C, /* 0x04-0x07 */
0x93, 0x6D, 0x93, 0x6E, 0x93, 0x6F, 0xDE, 0xF5, /* 0x08-0x0B */
@@ -6722,7 +6722,7 @@ static unsigned char u2c_64[512] = {
0x94, 0x5D, 0x94, 0x5E, 0x94, 0x5F, 0x94, 0x60, /* 0xFC-0xFF */
};
-static unsigned char u2c_65[512] = {
+static const unsigned char u2c_65[512] = {
0xC5, 0xCA, 0x94, 0x61, 0x94, 0x62, 0x94, 0x63, /* 0x00-0x03 */
0x94, 0x64, 0x94, 0x65, 0x94, 0x66, 0x94, 0x67, /* 0x04-0x07 */
0x94, 0x68, 0xDF, 0xAB, 0x94, 0x69, 0x94, 0x6A, /* 0x08-0x0B */
@@ -6790,7 +6790,7 @@ static unsigned char u2c_65[512] = {
0x95, 0x47, 0x95, 0x48, 0x95, 0x49, 0x95, 0x4A, /* 0xFC-0xFF */
};
-static unsigned char u2c_66[512] = {
+static const unsigned char u2c_66[512] = {
0xEA, 0xC0, 0x95, 0x4B, 0xB0, 0xBA, 0xEA, 0xBE, /* 0x00-0x03 */
0x95, 0x4C, 0x95, 0x4D, 0xC0, 0xA5, 0x95, 0x4E, /* 0x04-0x07 */
0x95, 0x4F, 0x95, 0x50, 0xEA, 0xBB, 0x95, 0x51, /* 0x08-0x0B */
@@ -6858,7 +6858,7 @@ static unsigned char u2c_66[512] = {
0xC2, 0xFC, 0x95, 0xFB, 0xD4, 0xF8, 0xCC, 0xE6, /* 0xFC-0xFF */
};
-static unsigned char u2c_67[512] = {
+static const unsigned char u2c_67[512] = {
0xD7, 0xEE, 0x95, 0xFC, 0x95, 0xFD, 0x95, 0xFE, /* 0x00-0x03 */
0x96, 0x40, 0x96, 0x41, 0x96, 0x42, 0x96, 0x43, /* 0x04-0x07 */
0xD4, 0xC2, 0xD3, 0xD0, 0xEB, 0xC3, 0xC5, 0xF3, /* 0x08-0x0B */
@@ -6926,7 +6926,7 @@ static unsigned char u2c_67[512] = {
0x96, 0xCC, 0xE8, 0xDF, 0x96, 0xCD, 0xCA, 0xC1, /* 0xFC-0xFF */
};
-static unsigned char u2c_68[512] = {
+static const unsigned char u2c_68[512] = {
0xE8, 0xD9, 0x96, 0xCE, 0x96, 0xCF, 0x96, 0xD0, /* 0x00-0x03 */
0x96, 0xD1, 0xD5, 0xA4, 0x96, 0xD2, 0xB1, 0xEA, /* 0x04-0x07 */
0xD5, 0xBB, 0xE8, 0xCE, 0xE8, 0xD0, 0xB6, 0xB0, /* 0x08-0x0B */
@@ -6994,7 +6994,7 @@ static unsigned char u2c_68[512] = {
0xE8, 0xFB, 0x97, 0xB2, 0x97, 0xB3, 0x97, 0xB4, /* 0xFC-0xFF */
};
-static unsigned char u2c_69[512] = {
+static const unsigned char u2c_69[512] = {
0x97, 0xB5, 0xE9, 0xA4, 0x97, 0xB6, 0x97, 0xB7, /* 0x00-0x03 */
0x97, 0xB8, 0xD2, 0xCE, 0x97, 0xB9, 0x97, 0xBA, /* 0x04-0x07 */
0x97, 0xBB, 0x97, 0xBC, 0x97, 0xBD, 0xE9, 0xA3, /* 0x08-0x0B */
@@ -7062,7 +7062,7 @@ static unsigned char u2c_69[512] = {
0x98, 0xB3, 0xB2, 0xDB, 0x98, 0xB4, 0xE9, 0xC8, /* 0xFC-0xFF */
};
-static unsigned char u2c_6A[512] = {
+static const unsigned char u2c_6A[512] = {
0x98, 0xB5, 0x98, 0xB6, 0x98, 0xB7, 0x98, 0xB8, /* 0x00-0x03 */
0x98, 0xB9, 0x98, 0xBA, 0x98, 0xBB, 0x98, 0xBC, /* 0x04-0x07 */
0x98, 0xBD, 0x98, 0xBE, 0xB7, 0xAE, 0x98, 0xBF, /* 0x08-0x0B */
@@ -7130,7 +7130,7 @@ static unsigned char u2c_6A[512] = {
0x99, 0xD2, 0x99, 0xD3, 0x99, 0xD4, 0x99, 0xD5, /* 0xFC-0xFF */
};
-static unsigned char u2c_6B[512] = {
+static const unsigned char u2c_6B[512] = {
0x99, 0xD6, 0x99, 0xD7, 0x99, 0xD8, 0x99, 0xD9, /* 0x00-0x03 */
0x99, 0xDA, 0x99, 0xDB, 0x99, 0xDC, 0x99, 0xDD, /* 0x04-0x07 */
0x99, 0xDE, 0x99, 0xDF, 0x99, 0xE0, 0x99, 0xE1, /* 0x08-0x0B */
@@ -7198,7 +7198,7 @@ static unsigned char u2c_6B[512] = {
0x9A, 0xCE, 0xEB, 0xA6, 0x9A, 0xCF, 0x9A, 0xD0, /* 0xFC-0xFF */
};
-static unsigned char u2c_6C[512] = {
+static const unsigned char u2c_6C[512] = {
0x9A, 0xD1, 0x9A, 0xD2, 0x9A, 0xD3, 0x9A, 0xD4, /* 0x00-0x03 */
0x9A, 0xD5, 0xEB, 0xA9, 0xEB, 0xAB, 0xEB, 0xAA, /* 0x04-0x07 */
0x9A, 0xD6, 0x9A, 0xD7, 0x9A, 0xD8, 0x9A, 0xD9, /* 0x08-0x0B */
@@ -7266,7 +7266,7 @@ static unsigned char u2c_6C[512] = {
0xC6, 0xC3, 0xD4, 0xF3, 0xE3, 0xFE, 0x9B, 0x8E, /* 0xFC-0xFF */
};
-static unsigned char u2c_6D[512] = {
+static const unsigned char u2c_6D[512] = {
0x9B, 0x8F, 0xBD, 0xE0, 0x9B, 0x90, 0x9B, 0x91, /* 0x00-0x03 */
0xE4, 0xA7, 0x9B, 0x92, 0x9B, 0x93, 0xE4, 0xA6, /* 0x04-0x07 */
0x9B, 0x94, 0x9B, 0x95, 0x9B, 0x96, 0xD1, 0xF3, /* 0x08-0x0B */
@@ -7334,7 +7334,7 @@ static unsigned char u2c_6D[512] = {
0xED, 0xB5, 0x9C, 0x5D, 0x9C, 0x5E, 0x9C, 0x5F, /* 0xFC-0xFF */
};
-static unsigned char u2c_6E[512] = {
+static const unsigned char u2c_6E[512] = {
0x9C, 0x60, 0x9C, 0x61, 0x9C, 0x62, 0x9C, 0x63, /* 0x00-0x03 */
0x9C, 0x64, 0xC7, 0xE5, 0x9C, 0x65, 0x9C, 0x66, /* 0x04-0x07 */
0x9C, 0x67, 0x9C, 0x68, 0xD4, 0xA8, 0x9C, 0x69, /* 0x08-0x0B */
@@ -7402,7 +7402,7 @@ static unsigned char u2c_6E[512] = {
0x9D, 0x4A, 0x9D, 0x4B, 0x9D, 0x4C, 0x9D, 0x4D, /* 0xFC-0xFF */
};
-static unsigned char u2c_6F[512] = {
+static const unsigned char u2c_6F[512] = {
0x9D, 0x4E, 0x9D, 0x4F, 0xC6, 0xAF, 0x9D, 0x50, /* 0x00-0x03 */
0x9D, 0x51, 0x9D, 0x52, 0xC6, 0xE1, 0x9D, 0x53, /* 0x04-0x07 */
0x9D, 0x54, 0xE4, 0xF5, 0x9D, 0x55, 0x9D, 0x56, /* 0x08-0x0B */
@@ -7470,7 +7470,7 @@ static unsigned char u2c_6F[512] = {
0x9E, 0x54, 0x9E, 0x55, 0x9E, 0x56, 0x9E, 0x57, /* 0xFC-0xFF */
};
-static unsigned char u2c_70[512] = {
+static const unsigned char u2c_70[512] = {
0x9E, 0x58, 0x9E, 0x59, 0x9E, 0x5A, 0x9E, 0x5B, /* 0x00-0x03 */
0x9E, 0x5C, 0x9E, 0x5D, 0x9E, 0x5E, 0x9E, 0x5F, /* 0x04-0x07 */
0x9E, 0x60, 0x9E, 0x61, 0x9E, 0x62, 0x9E, 0x63, /* 0x08-0x0B */
@@ -7538,7 +7538,7 @@ static unsigned char u2c_70[512] = {
0x9F, 0x54, 0xB7, 0xE9, 0x9F, 0x55, 0x9F, 0x56, /* 0xFC-0xFF */
};
-static unsigned char u2c_71[512] = {
+static const unsigned char u2c_71[512] = {
0x9F, 0x57, 0x9F, 0x58, 0x9F, 0x59, 0x9F, 0x5A, /* 0x00-0x03 */
0x9F, 0x5B, 0x9F, 0x5C, 0x9F, 0x5D, 0x9F, 0x5E, /* 0x04-0x07 */
0x9F, 0x5F, 0xD1, 0xC9, 0xBA, 0xB8, 0x9F, 0x60, /* 0x08-0x0B */
@@ -7606,7 +7606,7 @@ static unsigned char u2c_71[512] = {
0xA0, 0x61, 0xA0, 0x62, 0xA0, 0x63, 0xA0, 0x64, /* 0xFC-0xFF */
};
-static unsigned char u2c_72[512] = {
+static const unsigned char u2c_72[512] = {
0xA0, 0x65, 0xA0, 0x66, 0xA0, 0x67, 0xA0, 0x68, /* 0x00-0x03 */
0xA0, 0x69, 0xA0, 0x6A, 0xB1, 0xAC, 0xA0, 0x6B, /* 0x04-0x07 */
0xA0, 0x6C, 0xA0, 0x6D, 0xA0, 0x6E, 0xA0, 0x6F, /* 0x08-0x0B */
@@ -7674,7 +7674,7 @@ static unsigned char u2c_72[512] = {
0xC0, 0xC7, 0xAA, 0x4E, 0xAA, 0x4F, 0xAA, 0x50, /* 0xFC-0xFF */
};
-static unsigned char u2c_73[512] = {
+static const unsigned char u2c_73[512] = {
0xAA, 0x51, 0xE1, 0xFB, 0xAA, 0x52, 0xE1, 0xFD, /* 0x00-0x03 */
0xAA, 0x53, 0xAA, 0x54, 0xAA, 0x55, 0xAA, 0x56, /* 0x04-0x07 */
0xAA, 0x57, 0xAA, 0x58, 0xE2, 0xA5, 0xAA, 0x59, /* 0x08-0x0B */
@@ -7742,7 +7742,7 @@ static unsigned char u2c_73[512] = {
0xAC, 0x44, 0xAC, 0x45, 0xAC, 0x46, 0xAC, 0x47, /* 0xFC-0xFF */
};
-static unsigned char u2c_74[512] = {
+static const unsigned char u2c_74[512] = {
0xAC, 0x48, 0xAC, 0x49, 0xAC, 0x4A, 0xC7, 0xF2, /* 0x00-0x03 */
0xAC, 0x4B, 0xC0, 0xC5, 0xC0, 0xED, 0xAC, 0x4C, /* 0x04-0x07 */
0xAC, 0x4D, 0xC1, 0xF0, 0xE7, 0xF0, 0xAC, 0x4E, /* 0x08-0x0B */
@@ -7810,7 +7810,7 @@ static unsigned char u2c_74[512] = {
0xAE, 0x46, 0xAE, 0x47, 0xAE, 0x48, 0xEA, 0xB3, /* 0xFC-0xFF */
};
-static unsigned char u2c_75[512] = {
+static const unsigned char u2c_75[512] = {
0xAE, 0x49, 0xAE, 0x4A, 0xAE, 0x4B, 0xAE, 0x4C, /* 0x00-0x03 */
0xD5, 0xE7, 0xAE, 0x4D, 0xAE, 0x4E, 0xAE, 0x4F, /* 0x04-0x07 */
0xAE, 0x50, 0xAE, 0x51, 0xAE, 0x52, 0xAE, 0x53, /* 0x08-0x0B */
@@ -7878,7 +7878,7 @@ static unsigned char u2c_75[512] = {
0xF0, 0xF3, 0xAF, 0x79, 0xAF, 0x7A, 0xF0, 0xF4, /* 0xFC-0xFF */
};
-static unsigned char u2c_76[512] = {
+static const unsigned char u2c_76[512] = {
0xF0, 0xF6, 0xB4, 0xE1, 0xAF, 0x7B, 0xF0, 0xF1, /* 0x00-0x03 */
0xAF, 0x7C, 0xF0, 0xF7, 0xAF, 0x7D, 0xAF, 0x7E, /* 0x04-0x07 */
0xAF, 0x80, 0xAF, 0x81, 0xF0, 0xFA, 0xAF, 0x82, /* 0x08-0x0B */
@@ -7946,7 +7946,7 @@ static unsigned char u2c_76[512] = {
0xC5, 0xCE, 0xB1, 0x60, 0xB6, 0xDC, 0xB1, 0x61, /* 0xFC-0xFF */
};
-static unsigned char u2c_77[512] = {
+static const unsigned char u2c_77[512] = {
0xB1, 0x62, 0xCA, 0xA1, 0xB1, 0x63, 0xB1, 0x64, /* 0x00-0x03 */
0xED, 0xED, 0xB1, 0x65, 0xB1, 0x66, 0xED, 0xF0, /* 0x04-0x07 */
0xED, 0xF1, 0xC3, 0xBC, 0xB1, 0x67, 0xBF, 0xB4, /* 0x08-0x0B */
@@ -8014,7 +8014,7 @@ static unsigned char u2c_77[512] = {
0xB3, 0x4D, 0xCE, 0xF9, 0xB7, 0xAF, 0xBF, 0xF3, /* 0xFC-0xFF */
};
-static unsigned char u2c_78[512] = {
+static const unsigned char u2c_78[512] = {
0xED, 0xB8, 0xC2, 0xEB, 0xC9, 0xB0, 0xB3, 0x4E, /* 0x00-0x03 */
0xB3, 0x4F, 0xB3, 0x50, 0xB3, 0x51, 0xB3, 0x52, /* 0x04-0x07 */
0xB3, 0x53, 0xED, 0xB9, 0xB3, 0x54, 0xB3, 0x55, /* 0x08-0x0B */
@@ -8082,7 +8082,7 @@ static unsigned char u2c_78[512] = {
0xB4, 0x92, 0xB4, 0x93, 0xB4, 0x94, 0xB4, 0x95, /* 0xFC-0xFF */
};
-static unsigned char u2c_79[512] = {
+static const unsigned char u2c_79[512] = {
0xB4, 0x96, 0xBD, 0xB8, 0xB4, 0x97, 0xB4, 0x98, /* 0x00-0x03 */
0xB4, 0x99, 0xED, 0xE2, 0xB4, 0x9A, 0xB4, 0x9B, /* 0x04-0x07 */
0xB4, 0x9C, 0xB4, 0x9D, 0xB4, 0x9E, 0xB4, 0x9F, /* 0x08-0x0B */
@@ -8150,7 +8150,7 @@ static unsigned char u2c_79[512] = {
0xB6, 0x8B, 0xBB, 0xE0, 0xB6, 0x8C, 0xB6, 0x8D, /* 0xFC-0xFF */
};
-static unsigned char u2c_7A[512] = {
+static const unsigned char u2c_7A[512] = {
0xCF, 0xA1, 0xB6, 0x8E, 0xEF, 0xFC, 0xEF, 0xFB, /* 0x00-0x03 */
0xB6, 0x8F, 0xB6, 0x90, 0xEF, 0xF9, 0xB6, 0x91, /* 0x04-0x07 */
0xB6, 0x92, 0xB6, 0x93, 0xB6, 0x94, 0xB3, 0xCC, /* 0x08-0x0B */
@@ -8218,7 +8218,7 @@ static unsigned char u2c_7A[512] = {
0xB8, 0x86, 0xF3, 0xC4, 0xB8, 0x87, 0xB8, 0xCD, /* 0xFC-0xFF */
};
-static unsigned char u2c_7B[512] = {
+static const unsigned char u2c_7B[512] = {
0xB8, 0x88, 0xB8, 0x89, 0xB8, 0x8A, 0xF3, 0xC6, /* 0x00-0x03 */
0xF3, 0xC7, 0xB8, 0x8B, 0xB0, 0xCA, 0xB8, 0x8C, /* 0x04-0x07 */
0xF3, 0xC5, 0xB8, 0x8D, 0xF3, 0xC9, 0xCB, 0xF1, /* 0x08-0x0B */
@@ -8286,7 +8286,7 @@ static unsigned char u2c_7B[512] = {
0xF3, 0xFB, 0xBA, 0x68, 0xF3, 0xFA, 0xBA, 0x69, /* 0xFC-0xFF */
};
-static unsigned char u2c_7C[512] = {
+static const unsigned char u2c_7C[512] = {
0xBA, 0x6A, 0xBA, 0x6B, 0xBA, 0x6C, 0xBA, 0x6D, /* 0x00-0x03 */
0xBA, 0x6E, 0xBA, 0x6F, 0xBA, 0x70, 0xB4, 0xD8, /* 0x04-0x07 */
0xBA, 0x71, 0xBA, 0x72, 0xBA, 0x73, 0xF3, 0xFE, /* 0x08-0x0B */
@@ -8354,7 +8354,7 @@ static unsigned char u2c_7C[512] = {
0xBC, 0x6B, 0xBC, 0x6C, 0xBC, 0x6D, 0xBC, 0x6E, /* 0xFC-0xFF */
};
-static unsigned char u2c_7D[512] = {
+static const unsigned char u2c_7D[512] = {
0xBC, 0x6F, 0xBC, 0x70, 0xBC, 0x71, 0xBC, 0x72, /* 0x00-0x03 */
0xBC, 0x73, 0xBC, 0x74, 0xBC, 0x75, 0xBC, 0x76, /* 0x04-0x07 */
0xBC, 0x77, 0xBC, 0x78, 0xCE, 0xC9, 0xBC, 0x79, /* 0x08-0x0B */
@@ -8422,7 +8422,7 @@ static unsigned char u2c_7D[512] = {
0xBF, 0x41, 0xBF, 0x42, 0xBF, 0x43, 0xBF, 0x44, /* 0xFC-0xFF */
};
-static unsigned char u2c_7E[512] = {
+static const unsigned char u2c_7E[512] = {
0xBF, 0x45, 0xBF, 0x46, 0xBF, 0x47, 0xBF, 0x48, /* 0x00-0x03 */
0xBF, 0x49, 0xBF, 0x4A, 0xBF, 0x4B, 0xBF, 0x4C, /* 0x04-0x07 */
0xBF, 0x4D, 0xBF, 0x4E, 0xBF, 0x4F, 0xBF, 0x50, /* 0x08-0x0B */
@@ -8490,7 +8490,7 @@ static unsigned char u2c_7E[512] = {
0xD7, 0xDB, 0xD5, 0xC0, 0xE7, 0xBA, 0xC2, 0xCC, /* 0xFC-0xFF */
};
-static unsigned char u2c_7F[512] = {
+static const unsigned char u2c_7F[512] = {
0xD7, 0xBA, 0xE7, 0xBB, 0xE7, 0xBC, 0xE7, 0xBD, /* 0x00-0x03 */
0xBC, 0xEA, 0xC3, 0xE5, 0xC0, 0xC2, 0xE7, 0xBE, /* 0x04-0x07 */
0xE7, 0xBF, 0xBC, 0xA9, 0xC0, 0x88, 0xE7, 0xC0, /* 0x08-0x0B */
@@ -8558,7 +8558,7 @@ static unsigned char u2c_7F[512] = {
0xD2, 0xED, 0xC2, 0x50, 0xC2, 0x51, 0xC2, 0x52, /* 0xFC-0xFF */
};
-static unsigned char u2c_80[512] = {
+static const unsigned char u2c_80[512] = {
0xD2, 0xAB, 0xC0, 0xCF, 0xC2, 0x53, 0xBF, 0xBC, /* 0x00-0x03 */
0xEB, 0xA3, 0xD5, 0xDF, 0xEA, 0xC8, 0xC2, 0x54, /* 0x04-0x07 */
0xC2, 0x55, 0xC2, 0x56, 0xC2, 0x57, 0xF1, 0xF3, /* 0x08-0x0B */
@@ -8626,7 +8626,7 @@ static unsigned char u2c_80[512] = {
0xEB, 0xDD, 0xC4, 0xDC, 0xC3, 0x75, 0xC3, 0x76, /* 0xFC-0xFF */
};
-static unsigned char u2c_81[512] = {
+static const unsigned char u2c_81[512] = {
0xC3, 0x77, 0xC3, 0x78, 0xD6, 0xAC, 0xC3, 0x79, /* 0x00-0x03 */
0xC3, 0x7A, 0xC3, 0x7B, 0xB4, 0xE0, 0xC3, 0x7C, /* 0x04-0x07 */
0xC3, 0x7D, 0xC2, 0xF6, 0xBC, 0xB9, 0xC3, 0x7E, /* 0x08-0x0B */
@@ -8694,7 +8694,7 @@ static unsigned char u2c_81[512] = {
0xBE, 0xCA, 0xC5, 0x60, 0xF4, 0xA7, 0xC5, 0x61, /* 0xFC-0xFF */
};
-static unsigned char u2c_82[512] = {
+static const unsigned char u2c_82[512] = {
0xD2, 0xA8, 0xF4, 0xA8, 0xF4, 0xA9, 0xC5, 0x62, /* 0x00-0x03 */
0xF4, 0xAA, 0xBE, 0xCB, 0xD3, 0xDF, 0xC5, 0x63, /* 0x04-0x07 */
0xC5, 0x64, 0xC5, 0x65, 0xC5, 0x66, 0xC5, 0x67, /* 0x08-0x0B */
@@ -8762,7 +8762,7 @@ static unsigned char u2c_82[512] = {
0xC6, 0x81, 0xC6, 0x82, 0xC6, 0x83, 0xC6, 0x84, /* 0xFC-0xFF */
};
-static unsigned char u2c_83[512] = {
+static const unsigned char u2c_83[512] = {
0xC6, 0x85, 0xD7, 0xC2, 0xC3, 0xAF, 0xB7, 0xB6, /* 0x00-0x03 */
0xC7, 0xD1, 0xC3, 0xA9, 0xDC, 0xE2, 0xDC, 0xD8, /* 0x04-0x07 */
0xDC, 0xEB, 0xDC, 0xD4, 0xC6, 0x86, 0xC6, 0x87, /* 0x08-0x0B */
@@ -8830,7 +8830,7 @@ static unsigned char u2c_83[512] = {
0xC8, 0x49, 0xDD, 0xC4, 0xC8, 0x4A, 0xC8, 0x4B, /* 0xFC-0xFF */
};
-static unsigned char u2c_84[512] = {
+static const unsigned char u2c_84[512] = {
0xC8, 0x4C, 0xDD, 0xBD, 0xC8, 0x4D, 0xDD, 0xCD, /* 0x00-0x03 */
0xCC, 0xD1, 0xC8, 0x4E, 0xDD, 0xC9, 0xC8, 0x4F, /* 0x04-0x07 */
0xC8, 0x50, 0xC8, 0x51, 0xC8, 0x52, 0xDD, 0xC2, /* 0x08-0x0B */
@@ -8898,7 +8898,7 @@ static unsigned char u2c_84[512] = {
0xDE, 0xA4, 0xC9, 0x9C, 0xC9, 0x9D, 0xDE, 0xA3, /* 0xFC-0xFF */
};
-static unsigned char u2c_85[512] = {
+static const unsigned char u2c_85[512] = {
0xC9, 0x9E, 0xC9, 0x9F, 0xC9, 0xA0, 0xCA, 0x40, /* 0x00-0x03 */
0xCA, 0x41, 0xCA, 0x42, 0xCA, 0x43, 0xCA, 0x44, /* 0x04-0x07 */
0xCA, 0x45, 0xCA, 0x46, 0xCA, 0x47, 0xCA, 0x48, /* 0x08-0x0B */
@@ -8966,7 +8966,7 @@ static unsigned char u2c_85[512] = {
0xCC, 0x42, 0xCC, 0x43, 0xCC, 0x44, 0xDE, 0xBD, /* 0xFC-0xFF */
};
-static unsigned char u2c_86[512] = {
+static const unsigned char u2c_86[512] = {
0xCC, 0x45, 0xCC, 0x46, 0xCC, 0x47, 0xCC, 0x48, /* 0x00-0x03 */
0xCC, 0x49, 0xDE, 0xBF, 0xCC, 0x4A, 0xCC, 0x4B, /* 0x04-0x07 */
0xCC, 0x4C, 0xCC, 0x4D, 0xCC, 0x4E, 0xCC, 0x4F, /* 0x08-0x0B */
@@ -9034,7 +9034,7 @@ static unsigned char u2c_86[512] = {
0xCD, 0x92, 0xCD, 0x93, 0xB6, 0xEA, 0xCD, 0x94, /* 0xFC-0xFF */
};
-static unsigned char u2c_87[512] = {
+static const unsigned char u2c_87[512] = {
0xCA, 0xF1, 0xCD, 0x95, 0xB7, 0xE4, 0xF2, 0xD7, /* 0x00-0x03 */
0xCD, 0x96, 0xCD, 0x97, 0xCD, 0x98, 0xF2, 0xD8, /* 0x04-0x07 */
0xF2, 0xDA, 0xF2, 0xDD, 0xF2, 0xDB, 0xCD, 0x99, /* 0x08-0x0B */
@@ -9102,7 +9102,7 @@ static unsigned char u2c_87[512] = {
0xCF, 0x82, 0xCF, 0x83, 0xF3, 0xB8, 0xCF, 0x84, /* 0xFC-0xFF */
};
-static unsigned char u2c_88[512] = {
+static const unsigned char u2c_88[512] = {
0xCF, 0x85, 0xCF, 0x86, 0xCF, 0x87, 0xD9, 0xF9, /* 0x00-0x03 */
0xCF, 0x88, 0xCF, 0x89, 0xCF, 0x8A, 0xCF, 0x8B, /* 0x04-0x07 */
0xCF, 0x8C, 0xCF, 0x8D, 0xF3, 0xB9, 0xCF, 0x8E, /* 0x08-0x0B */
@@ -9170,7 +9170,7 @@ static unsigned char u2c_88[512] = {
0xF1, 0xD3, 0xD1, 0x75, 0xF1, 0xD5, 0xD1, 0x76, /* 0xFC-0xFF */
};
-static unsigned char u2c_89[512] = {
+static const unsigned char u2c_89[512] = {
0xD1, 0x77, 0xD1, 0x78, 0xB9, 0xD3, 0xD1, 0x79, /* 0x00-0x03 */
0xD1, 0x7A, 0xD1, 0x7B, 0xD1, 0x7C, 0xD1, 0x7D, /* 0x04-0x07 */
0xD1, 0x7E, 0xD1, 0x80, 0xF1, 0xDB, 0xD1, 0x81, /* 0x08-0x0B */
@@ -9238,7 +9238,7 @@ static unsigned char u2c_89[512] = {
0xD3, 0x81, 0xD3, 0x82, 0xD3, 0x83, 0xD3, 0x84, /* 0xFC-0xFF */
};
-static unsigned char u2c_8A[512] = {
+static const unsigned char u2c_8A[512] = {
0xD1, 0xD4, 0xD3, 0x85, 0xD3, 0x86, 0xD3, 0x87, /* 0x00-0x03 */
0xD3, 0x88, 0xD3, 0x89, 0xD3, 0x8A, 0xD9, 0xEA, /* 0x04-0x07 */
0xD3, 0x8B, 0xD3, 0x8C, 0xD3, 0x8D, 0xD3, 0x8E, /* 0x08-0x0B */
@@ -9306,7 +9306,7 @@ static unsigned char u2c_8A[512] = {
0xD6, 0x58, 0xD6, 0x59, 0xD6, 0x5A, 0xD6, 0x5B, /* 0xFC-0xFF */
};
-static unsigned char u2c_8B[512] = {
+static const unsigned char u2c_8B[512] = {
0xD6, 0x5C, 0xD6, 0x5D, 0xD6, 0x5E, 0xD6, 0x5F, /* 0x00-0x03 */
0xD6, 0x60, 0xD6, 0x61, 0xD6, 0x62, 0xE5, 0xC0, /* 0x04-0x07 */
0xD6, 0x63, 0xD6, 0x64, 0xD6, 0x65, 0xD6, 0x66, /* 0x08-0x0B */
@@ -9374,7 +9374,7 @@ static unsigned char u2c_8B[512] = {
0xDA, 0xC2, 0xB7, 0xCC, 0xBF, 0xCE, 0xDA, 0xC3, /* 0xFC-0xFF */
};
-static unsigned char u2c_8C[512] = {
+static const unsigned char u2c_8C[512] = {
0xDA, 0xC4, 0xCB, 0xAD, 0xDA, 0xC5, 0xB5, 0xF7, /* 0x00-0x03 */
0xDA, 0xC6, 0xC1, 0xC2, 0xD7, 0xBB, 0xDA, 0xC7, /* 0x04-0x07 */
0xCC, 0xB8, 0xD7, 0x9F, 0xD2, 0xEA, 0xC4, 0xB1, /* 0x08-0x0B */
@@ -9442,7 +9442,7 @@ static unsigned char u2c_8C[512] = {
0xD9, 0x8F, 0xD9, 0x90, 0xD9, 0x91, 0xD9, 0x92, /* 0xFC-0xFF */
};
-static unsigned char u2c_8D[512] = {
+static const unsigned char u2c_8D[512] = {
0xD9, 0x93, 0xD9, 0x94, 0xD9, 0x95, 0xD9, 0x96, /* 0x00-0x03 */
0xD9, 0x97, 0xD9, 0x98, 0xD9, 0x99, 0xD9, 0x9A, /* 0x04-0x07 */
0xD9, 0x9B, 0xD9, 0x9C, 0xD9, 0x9D, 0xD9, 0x9E, /* 0x08-0x0B */
@@ -9510,7 +9510,7 @@ static unsigned char u2c_8D[512] = {
0xDB, 0x52, 0xF5, 0xD5, 0xDB, 0x53, 0xDB, 0x54, /* 0xFC-0xFF */
};
-static unsigned char u2c_8E[512] = {
+static const unsigned char u2c_8E[512] = {
0xDB, 0x55, 0xDB, 0x56, 0xDB, 0x57, 0xDB, 0x58, /* 0x00-0x03 */
0xDB, 0x59, 0xF5, 0xBD, 0xDB, 0x5A, 0xDB, 0x5B, /* 0x04-0x07 */
0xDB, 0x5C, 0xF5, 0xD4, 0xD3, 0xBB, 0xDB, 0x5D, /* 0x08-0x0B */
@@ -9578,7 +9578,7 @@ static unsigned char u2c_8E[512] = {
0xDD, 0x57, 0xDD, 0x58, 0xDD, 0x59, 0xDD, 0x5A, /* 0xFC-0xFF */
};
-static unsigned char u2c_8F[512] = {
+static const unsigned char u2c_8F[512] = {
0xDD, 0x5B, 0xDD, 0x5C, 0xDD, 0x5D, 0xDD, 0x5E, /* 0x00-0x03 */
0xDD, 0x5F, 0xDD, 0x60, 0xDD, 0x61, 0xDD, 0x62, /* 0x04-0x07 */
0xDD, 0x63, 0xDD, 0x64, 0xDD, 0x65, 0xDD, 0x66, /* 0x08-0x0B */
@@ -9646,7 +9646,7 @@ static unsigned char u2c_8F[512] = {
0xDE, 0x97, 0xD7, 0xB7, 0xDE, 0x98, 0xDE, 0x99, /* 0xFC-0xFF */
};
-static unsigned char u2c_90[512] = {
+static const unsigned char u2c_90[512] = {
0xCD, 0xCB, 0xCB, 0xCD, 0xCA, 0xCA, 0xCC, 0xD3, /* 0x00-0x03 */
0xE5, 0xCC, 0xE5, 0xCB, 0xC4, 0xE6, 0xDE, 0x9A, /* 0x04-0x07 */
0xDE, 0x9B, 0xD1, 0xA1, 0xD1, 0xB7, 0xE5, 0xCD, /* 0x08-0x0B */
@@ -9714,7 +9714,7 @@ static unsigned char u2c_90[512] = {
0xE0, 0x63, 0xB6, 0xBC, 0xDB, 0xB1, 0xE0, 0x64, /* 0xFC-0xFF */
};
-static unsigned char u2c_91[512] = {
+static const unsigned char u2c_91[512] = {
0xE0, 0x65, 0xE0, 0x66, 0xB6, 0xF5, 0xE0, 0x67, /* 0x00-0x03 */
0xDB, 0xB2, 0xE0, 0x68, 0xE0, 0x69, 0xE0, 0x6A, /* 0x04-0x07 */
0xE0, 0x6B, 0xE0, 0x6C, 0xE0, 0x6D, 0xE0, 0x6E, /* 0x08-0x0B */
@@ -9782,7 +9782,7 @@ static unsigned char u2c_91[512] = {
0xE2, 0x56, 0xE2, 0x57, 0xE2, 0x58, 0xE2, 0x59, /* 0xFC-0xFF */
};
-static unsigned char u2c_92[512] = {
+static const unsigned char u2c_92[512] = {
0xE2, 0x5A, 0xE2, 0x5B, 0xE2, 0x5C, 0xE2, 0x5D, /* 0x00-0x03 */
0xE2, 0x5E, 0xE2, 0x5F, 0xE2, 0x60, 0xE2, 0x61, /* 0x04-0x07 */
0xE2, 0x62, 0xE2, 0x63, 0xE2, 0x64, 0xE2, 0x65, /* 0x08-0x0B */
@@ -9850,7 +9850,7 @@ static unsigned char u2c_92[512] = {
0xE4, 0x93, 0xE4, 0x94, 0xE4, 0x95, 0xE4, 0x96, /* 0xFC-0xFF */
};
-static unsigned char u2c_93[512] = {
+static const unsigned char u2c_93[512] = {
0xE4, 0x97, 0xE4, 0x98, 0xE4, 0x99, 0xE4, 0x9A, /* 0x00-0x03 */
0xE4, 0x9B, 0xE4, 0x9C, 0xE4, 0x9D, 0xE4, 0x9E, /* 0x04-0x07 */
0xE4, 0x9F, 0xE4, 0xA0, 0xE5, 0x40, 0xE5, 0x41, /* 0x08-0x0B */
@@ -9918,7 +9918,7 @@ static unsigned char u2c_93[512] = {
0xE7, 0x6D, 0xE7, 0x6E, 0xE7, 0x6F, 0xE7, 0x70, /* 0xFC-0xFF */
};
-static unsigned char u2c_94[512] = {
+static const unsigned char u2c_94[512] = {
0xE7, 0x71, 0xE7, 0x72, 0xE7, 0x73, 0xE7, 0x74, /* 0x00-0x03 */
0xE7, 0x75, 0xE7, 0x76, 0xE7, 0x77, 0xE7, 0x78, /* 0x04-0x07 */
0xE7, 0x79, 0xE7, 0x7A, 0xE7, 0x7B, 0xE7, 0x7C, /* 0x08-0x0B */
@@ -9986,7 +9986,7 @@ static unsigned char u2c_94[512] = {
0xEF, 0xAA, 0xEF, 0xAB, 0xC1, 0xB4, 0xEF, 0xAC, /* 0xFC-0xFF */
};
-static unsigned char u2c_95[512] = {
+static const unsigned char u2c_95[512] = {
0xCF, 0xFA, 0xCB, 0xF8, 0xEF, 0xAE, 0xEF, 0xAD, /* 0x00-0x03 */
0xB3, 0xFA, 0xB9, 0xF8, 0xEF, 0xAF, 0xEF, 0xB0, /* 0x04-0x07 */
0xD0, 0xE2, 0xEF, 0xB1, 0xEF, 0xB2, 0xB7, 0xE6, /* 0x08-0x0B */
@@ -10054,7 +10054,7 @@ static unsigned char u2c_95[512] = {
0xE3, 0xCB, 0xC3, 0xF6, 0xE3, 0xCC, 0xEA, 0x5D, /* 0xFC-0xFF */
};
-static unsigned char u2c_96[512] = {
+static const unsigned char u2c_96[512] = {
0xB7, 0xA7, 0xB8, 0xF3, 0xBA, 0xD2, 0xE3, 0xCD, /* 0x00-0x03 */
0xE3, 0xCE, 0xD4, 0xC4, 0xE3, 0xCF, 0xEA, 0x5E, /* 0x04-0x07 */
0xE3, 0xD0, 0xD1, 0xCB, 0xE3, 0xD1, 0xE3, 0xD2, /* 0x08-0x0B */
@@ -10122,7 +10122,7 @@ static unsigned char u2c_96[512] = {
0xEB, 0x8B, 0xEB, 0x8C, 0xCE, 0xED, 0xEB, 0x8D, /* 0xFC-0xFF */
};
-static unsigned char u2c_97[512] = {
+static const unsigned char u2c_97[512] = {
0xD0, 0xE8, 0xF6, 0xAB, 0xEB, 0x8E, 0xEB, 0x8F, /* 0x00-0x03 */
0xCF, 0xF6, 0xEB, 0x90, 0xF6, 0xAA, 0xD5, 0xF0, /* 0x04-0x07 */
0xF6, 0xAC, 0xC3, 0xB9, 0xEB, 0x91, 0xEB, 0x92, /* 0x08-0x0B */
@@ -10190,7 +10190,7 @@ static unsigned char u2c_97[512] = {
0xED, 0x8E, 0xED, 0x8F, 0xED, 0x90, 0xED, 0x91, /* 0xFC-0xFF */
};
-static unsigned char u2c_98[512] = {
+static const unsigned char u2c_98[512] = {
0xED, 0x92, 0xED, 0x93, 0xED, 0x94, 0xED, 0x95, /* 0x00-0x03 */
0xED, 0x96, 0xED, 0x97, 0xED, 0x98, 0xED, 0x99, /* 0x04-0x07 */
0xED, 0x9A, 0xED, 0x9B, 0xED, 0x9C, 0xED, 0x9D, /* 0x08-0x0B */
@@ -10258,7 +10258,7 @@ static unsigned char u2c_98[512] = {
0xEF, 0x95, 0xEF, 0x96, 0xEF, 0x97, 0xEF, 0x98, /* 0xFC-0xFF */
};
-static unsigned char u2c_99[512] = {
+static const unsigned char u2c_99[512] = {
0xEF, 0x99, 0xEF, 0x9A, 0xEF, 0x9B, 0xEF, 0x9C, /* 0x00-0x03 */
0xEF, 0x9D, 0xEF, 0x9E, 0xEF, 0x9F, 0xEF, 0xA0, /* 0x04-0x07 */
0xF0, 0x40, 0xF0, 0x41, 0xF0, 0x42, 0xF0, 0x43, /* 0x08-0x0B */
@@ -10326,7 +10326,7 @@ static unsigned char u2c_99[512] = {
0xF2, 0x42, 0xF2, 0x43, 0xF2, 0x44, 0xF2, 0x45, /* 0xFC-0xFF */
};
-static unsigned char u2c_9A[512] = {
+static const unsigned char u2c_9A[512] = {
0xF2, 0x46, 0xF2, 0x47, 0xF2, 0x48, 0xF2, 0x49, /* 0x00-0x03 */
0xF2, 0x4A, 0xF2, 0x4B, 0xF2, 0x4C, 0xF2, 0x4D, /* 0x04-0x07 */
0xF2, 0x4E, 0xF2, 0x4F, 0xF2, 0x50, 0xF2, 0x51, /* 0x08-0x0B */
@@ -10394,7 +10394,7 @@ static unsigned char u2c_9A[512] = {
0xF3, 0x97, 0xF3, 0x98, 0xF3, 0x99, 0xF3, 0x9A, /* 0xFC-0xFF */
};
-static unsigned char u2c_9B[512] = {
+static const unsigned char u2c_9B[512] = {
0xF3, 0x9B, 0xF3, 0x9C, 0xF3, 0x9D, 0xD7, 0xD7, /* 0x00-0x03 */
0xF3, 0x9E, 0xF3, 0x9F, 0xF3, 0xA0, 0xF4, 0x40, /* 0x04-0x07 */
0xF7, 0xDC, 0xF4, 0x41, 0xF4, 0x42, 0xF4, 0x43, /* 0x08-0x0B */
@@ -10462,7 +10462,7 @@ static unsigned char u2c_9B[512] = {
0xF6, 0x60, 0xF6, 0x61, 0xF6, 0x62, 0xF6, 0x63, /* 0xFC-0xFF */
};
-static unsigned char u2c_9C[512] = {
+static const unsigned char u2c_9C[512] = {
0xF6, 0x64, 0xF6, 0x65, 0xF6, 0x66, 0xF6, 0x67, /* 0x00-0x03 */
0xF6, 0x68, 0xF6, 0x69, 0xF6, 0x6A, 0xF6, 0x6B, /* 0x04-0x07 */
0xF6, 0x6C, 0xF6, 0x6D, 0xF6, 0x6E, 0xF6, 0x6F, /* 0x08-0x0B */
@@ -10530,7 +10530,7 @@ static unsigned char u2c_9C[512] = {
0xF8, 0x59, 0xF8, 0x5A, 0xF8, 0x5B, 0xF8, 0x5C, /* 0xFC-0xFF */
};
-static unsigned char u2c_9D[512] = {
+static const unsigned char u2c_9D[512] = {
0xF8, 0x5D, 0xF8, 0x5E, 0xF8, 0x5F, 0xF8, 0x60, /* 0x00-0x03 */
0xF8, 0x61, 0xF8, 0x62, 0xF8, 0x63, 0xF8, 0x64, /* 0x04-0x07 */
0xF8, 0x65, 0xF8, 0x66, 0xF8, 0x67, 0xF8, 0x68, /* 0x08-0x0B */
@@ -10598,7 +10598,7 @@ static unsigned char u2c_9D[512] = {
0xFA, 0x9A, 0xFA, 0x9B, 0xFA, 0x9C, 0xFA, 0x9D, /* 0xFC-0xFF */
};
-static unsigned char u2c_9E[512] = {
+static const unsigned char u2c_9E[512] = {
0xFA, 0x9E, 0xFA, 0x9F, 0xFA, 0xA0, 0xFB, 0x40, /* 0x00-0x03 */
0xFB, 0x41, 0xFB, 0x42, 0xFB, 0x43, 0xFB, 0x44, /* 0x04-0x07 */
0xFB, 0x45, 0xFB, 0x46, 0xFB, 0x47, 0xFB, 0x48, /* 0x08-0x0B */
@@ -10666,7 +10666,7 @@ static unsigned char u2c_9E[512] = {
0xED, 0xEB, 0xFC, 0x77, 0xF6, 0xBC, 0xFC, 0x78, /* 0xFC-0xFF */
};
-static unsigned char u2c_9F[512] = {
+static const unsigned char u2c_9F[512] = {
0xFC, 0x79, 0xFC, 0x7A, 0xFC, 0x7B, 0xFC, 0x7C, /* 0x00-0x03 */
0xFC, 0x7D, 0xFC, 0x7E, 0xFC, 0x80, 0xFC, 0x81, /* 0x04-0x07 */
0xFC, 0x82, 0xFC, 0x83, 0xFC, 0x84, 0xF6, 0xBD, /* 0x08-0x0B */
@@ -10712,11 +10712,11 @@ static unsigned char u2c_9F[512] = {
0xFD, 0x9A, 0xFD, 0x9B, 0x00, 0x00, 0x00, 0x00, /* 0xA4-0xA7 */
};
-static unsigned char u2c_DC[512] = {
+static const unsigned char u2c_DC[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
};
-static unsigned char u2c_F9[512] = {
+static const unsigned char u2c_F9[512] = {
0xD8, 0x4D, 0xB8, 0xFC, 0xDC, 0x87, 0xD9, 0x5A, /* 0x00-0x03 */
0xBB, 0xAC, 0xB4, 0xAE, 0xBE, 0xE4, 0xFD, 0x94, /* 0x04-0x07 */
0xFD, 0x94, 0xC6, 0xF5, 0xBD, 0xF0, 0xC0, 0xAE, /* 0x08-0x0B */
@@ -10784,7 +10784,7 @@ static unsigned char u2c_F9[512] = {
0xD7, 0x52, 0xCA, 0xB2, 0xB2, 0xE8, 0xB4, 0xCC, /* 0xFC-0xFF */
};
-static unsigned char u2c_FA[512] = {
+static const unsigned char u2c_FA[512] = {
0xC7, 0xD0, 0xB6, 0xC8, 0xCD, 0xD8, 0xCC, 0xC7, /* 0x00-0x03 */
0xD5, 0xAC, 0xB6, 0xB4, 0xB1, 0xA9, 0xDD, 0x97, /* 0x04-0x07 */
0xD0, 0xD0, 0xBD, 0xB5, 0xD2, 0x8A, 0xC0, 0xAA, /* 0x08-0x0B */
@@ -10799,7 +10799,7 @@ static unsigned char u2c_FA[512] = {
0xF0, 0x5E, 0xFA, 0x51, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */
};
-static unsigned char u2c_FE[512] = {
+static const unsigned char u2c_FE[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10829,7 +10829,7 @@ static unsigned char u2c_FE[512] = {
0xA9, 0x85, 0xA9, 0x86, 0xA9, 0x87, 0xA9, 0x88, /* 0x68-0x6B */
};
-static unsigned char u2c_FF[512] = {
+static const unsigned char u2c_FF[512] = {
0x00, 0x00, 0xA3, 0xA1, 0xA3, 0xA2, 0xA3, 0xA3, /* 0x00-0x03 */
0xA1, 0xE7, 0xA3, 0xA5, 0xA3, 0xA6, 0xA3, 0xA7, /* 0x04-0x07 */
0xA3, 0xA8, 0xA3, 0xA9, 0xA3, 0xAA, 0xA3, 0xAB, /* 0x08-0x0B */
@@ -10891,7 +10891,7 @@ static unsigned char u2c_FF[512] = {
0xA9, 0x57, 0xA3, 0xA4, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
u2c_00, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -10925,7 +10925,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, u2c_F9, u2c_FA, NULL, NULL, NULL, u2c_FE, u2c_FF, };
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -10961,7 +10961,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -11000,7 +11000,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(const wchar_t uni,
unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni&0xFF;
unsigned char ch = (uni>>8)&0xFF;
unsigned char out0,out1;
@@ -11050,7 +11050,7 @@ static int char2uni(const unsigned char *rawstring, int boundlen,
wchar_t *uni)
{
unsigned char ch, cl;
- wchar_t *charset2uni;
+ const wchar_t *charset2uni;
int n;
if (boundlen <= 0)
diff --git a/fs/nls/nls_cp949.c b/fs/nls/nls_cp949.c
index 92ae19372f0..8a7a2fe85c6 100644
--- a/fs/nls/nls_cp949.c
+++ b/fs/nls/nls_cp949.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t c2u_81[256] = {
+static const wchar_t c2u_81[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -49,7 +49,7 @@ static wchar_t c2u_81[256] = {
0xAD09,0xAD0A,0xAD0B,0xAD0E,0xAD10,0xAD12,0xAD13,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_82[256] = {
+static const wchar_t c2u_82[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -85,7 +85,7 @@ static wchar_t c2u_82[256] = {
0xADF1,0xADF2,0xADF3,0xADF4,0xADF5,0xADF6,0xADF7,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_83[256] = {
+static const wchar_t c2u_83[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -121,7 +121,7 @@ static wchar_t c2u_83[256] = {
0xAEDF,0xAEE0,0xAEE1,0xAEE2,0xAEE3,0xAEE4,0xAEE5,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_84[256] = {
+static const wchar_t c2u_84[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -157,7 +157,7 @@ static wchar_t c2u_84[256] = {
0xAFB5,0xAFB6,0xAFB7,0xAFBA,0xAFBB,0xAFBD,0xAFBE,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_85[256] = {
+static const wchar_t c2u_85[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -193,7 +193,7 @@ static wchar_t c2u_85[256] = {
0xB096,0xB097,0xB09B,0xB09D,0xB09E,0xB0A3,0xB0A4,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_86[256] = {
+static const wchar_t c2u_86[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -229,7 +229,7 @@ static wchar_t c2u_86[256] = {
0xB195,0xB196,0xB197,0xB199,0xB19A,0xB19B,0xB19D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_87[256] = {
+static const wchar_t c2u_87[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -265,7 +265,7 @@ static wchar_t c2u_87[256] = {
0xB266,0xB267,0xB26A,0xB26B,0xB26C,0xB26D,0xB26E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_88[256] = {
+static const wchar_t c2u_88[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -301,7 +301,7 @@ static wchar_t c2u_88[256] = {
0xB359,0xB35A,0xB35D,0xB360,0xB361,0xB362,0xB363,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_89[256] = {
+static const wchar_t c2u_89[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -337,7 +337,7 @@ static wchar_t c2u_89[256] = {
0xB43E,0xB43F,0xB440,0xB441,0xB442,0xB443,0xB444,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8A[256] = {
+static const wchar_t c2u_8A[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -373,7 +373,7 @@ static wchar_t c2u_8A[256] = {
0xB512,0xB513,0xB516,0xB517,0xB519,0xB51A,0xB51D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8B[256] = {
+static const wchar_t c2u_8B[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -409,7 +409,7 @@ static wchar_t c2u_8B[256] = {
0xB5F9,0xB5FA,0xB5FB,0xB5FC,0xB5FD,0xB5FE,0xB5FF,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8C[256] = {
+static const wchar_t c2u_8C[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -445,7 +445,7 @@ static wchar_t c2u_8C[256] = {
0xB6BC,0xB6BD,0xB6BE,0xB6BF,0xB6C0,0xB6C1,0xB6C2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8D[256] = {
+static const wchar_t c2u_8D[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -481,7 +481,7 @@ static wchar_t c2u_8D[256] = {
0xB793,0xB794,0xB795,0xB79A,0xB79B,0xB79D,0xB79E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8E[256] = {
+static const wchar_t c2u_8E[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -517,7 +517,7 @@ static wchar_t c2u_8E[256] = {
0xB87E,0xB87F,0xB880,0xB881,0xB882,0xB883,0xB884,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_8F[256] = {
+static const wchar_t c2u_8F[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -553,7 +553,7 @@ static wchar_t c2u_8F[256] = {
0xB950,0xB952,0xB953,0xB954,0xB955,0xB956,0xB957,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_90[256] = {
+static const wchar_t c2u_90[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -589,7 +589,7 @@ static wchar_t c2u_90[256] = {
0xBA3E,0xBA3F,0xBA41,0xBA43,0xBA44,0xBA45,0xBA46,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_91[256] = {
+static const wchar_t c2u_91[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -625,7 +625,7 @@ static wchar_t c2u_91[256] = {
0xBB21,0xBB22,0xBB23,0xBB24,0xBB25,0xBB26,0xBB27,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_92[256] = {
+static const wchar_t c2u_92[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -661,7 +661,7 @@ static wchar_t c2u_92[256] = {
0xBBF6,0xBBF7,0xBBFA,0xBBFB,0xBBFD,0xBBFE,0xBC01,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_93[256] = {
+static const wchar_t c2u_93[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -697,7 +697,7 @@ static wchar_t c2u_93[256] = {
0xBCF2,0xBCF3,0xBCF7,0xBCF9,0xBCFA,0xBCFB,0xBCFD,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_94[256] = {
+static const wchar_t c2u_94[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -733,7 +733,7 @@ static wchar_t c2u_94[256] = {
0xBDCB,0xBDCC,0xBDCD,0xBDCE,0xBDCF,0xBDD0,0xBDD1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_95[256] = {
+static const wchar_t c2u_95[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -769,7 +769,7 @@ static wchar_t c2u_95[256] = {
0xBEB1,0xBEB2,0xBEB3,0xBEB4,0xBEB5,0xBEB6,0xBEB7,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_96[256] = {
+static const wchar_t c2u_96[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -805,7 +805,7 @@ static wchar_t c2u_96[256] = {
0xBF7C,0xBF7D,0xBF7E,0xBF7F,0xBF80,0xBF81,0xBF82,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_97[256] = {
+static const wchar_t c2u_97[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -841,7 +841,7 @@ static wchar_t c2u_97[256] = {
0xC038,0xC039,0xC03A,0xC03B,0xC03D,0xC03E,0xC03F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_98[256] = {
+static const wchar_t c2u_98[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -877,7 +877,7 @@ static wchar_t c2u_98[256] = {
0xC122,0xC125,0xC128,0xC129,0xC12A,0xC12B,0xC12E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_99[256] = {
+static const wchar_t c2u_99[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -913,7 +913,7 @@ static wchar_t c2u_99[256] = {
0xC21A,0xC21B,0xC21D,0xC21E,0xC221,0xC222,0xC223,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9A[256] = {
+static const wchar_t c2u_9A[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -949,7 +949,7 @@ static wchar_t c2u_9A[256] = {
0xC305,0xC306,0xC307,0xC30A,0xC30B,0xC30E,0xC30F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9B[256] = {
+static const wchar_t c2u_9B[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -985,7 +985,7 @@ static wchar_t c2u_9B[256] = {
0xC3D2,0xC3D3,0xC3D4,0xC3D5,0xC3D6,0xC3D7,0xC3DA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9C[256] = {
+static const wchar_t c2u_9C[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1021,7 +1021,7 @@ static wchar_t c2u_9C[256] = {
0xC4A3,0xC4A4,0xC4A5,0xC4A6,0xC4A7,0xC4A8,0xC4A9,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9D[256] = {
+static const wchar_t c2u_9D[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1057,7 +1057,7 @@ static wchar_t c2u_9D[256] = {
0xC58A,0xC58B,0xC58E,0xC590,0xC592,0xC593,0xC594,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9E[256] = {
+static const wchar_t c2u_9E[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1093,7 +1093,7 @@ static wchar_t c2u_9E[256] = {
0xC69E,0xC69F,0xC6A0,0xC6A1,0xC6A2,0xC6A3,0xC6A6,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_9F[256] = {
+static const wchar_t c2u_9F[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1129,7 +1129,7 @@ static wchar_t c2u_9F[256] = {
0xC7AF,0xC7B1,0xC7B2,0xC7B3,0xC7B5,0xC7B6,0xC7B7,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A0[256] = {
+static const wchar_t c2u_A0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1165,7 +1165,7 @@ static wchar_t c2u_A0[256] = {
0xC89B,0xC89C,0xC89E,0xC8A0,0xC8A2,0xC8A3,0xC8A4,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A1[256] = {
+static const wchar_t c2u_A1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1201,7 +1201,7 @@ static wchar_t c2u_A1[256] = {
0x2282,0x2283,0x222A,0x2229,0x2227,0x2228,0xFFE2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A2[256] = {
+static const wchar_t c2u_A2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1234,7 +1234,7 @@ static wchar_t c2u_A2[256] = {
0x2116,0x33C7,0x2122,0x33C2,0x33D8,0x2121,0x20AC,0x00AE,/* 0xE0-0xE7 */
};
-static wchar_t c2u_A3[256] = {
+static const wchar_t c2u_A3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1270,7 +1270,7 @@ static wchar_t c2u_A3[256] = {
0xFF58,0xFF59,0xFF5A,0xFF5B,0xFF5C,0xFF5D,0xFFE3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A4[256] = {
+static const wchar_t c2u_A4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1306,7 +1306,7 @@ static wchar_t c2u_A4[256] = {
0x3188,0x3189,0x318A,0x318B,0x318C,0x318D,0x318E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A5[256] = {
+static const wchar_t c2u_A5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1342,7 +1342,7 @@ static wchar_t c2u_A5[256] = {
0x03C9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A6[256] = {
+static const wchar_t c2u_A6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1375,7 +1375,7 @@ static wchar_t c2u_A6[256] = {
0x2546,0x2547,0x2548,0x2549,0x254A,0x0000,0x0000,0x0000,/* 0xE0-0xE7 */
};
-static wchar_t c2u_A7[256] = {
+static const wchar_t c2u_A7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1409,7 +1409,7 @@ static wchar_t c2u_A7[256] = {
0x33AC,0x33DD,0x33D0,0x33D3,0x33C3,0x33C9,0x33DC,0x33C6,/* 0xE8-0xEF */
};
-static wchar_t c2u_A8[256] = {
+static const wchar_t c2u_A8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1445,7 +1445,7 @@ static wchar_t c2u_A8[256] = {
0x2154,0x00BC,0x00BE,0x215B,0x215C,0x215D,0x215E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A9[256] = {
+static const wchar_t c2u_A9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1481,7 +1481,7 @@ static wchar_t c2u_A9[256] = {
0x00B3,0x2074,0x207F,0x2081,0x2082,0x2083,0x2084,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AA[256] = {
+static const wchar_t c2u_AA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1516,7 +1516,7 @@ static wchar_t c2u_AA[256] = {
0x3090,0x3091,0x3092,0x3093,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_AB[256] = {
+static const wchar_t c2u_AB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1551,7 +1551,7 @@ static wchar_t c2u_AB[256] = {
0x30F0,0x30F1,0x30F2,0x30F3,0x30F4,0x30F5,0x30F6,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_AC[256] = {
+static const wchar_t c2u_AC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1586,7 +1586,7 @@ static wchar_t c2u_AC[256] = {
0x044E,0x044F,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xF0-0xF7 */
};
-static wchar_t c2u_AD[256] = {
+static const wchar_t c2u_AD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1611,7 +1611,7 @@ static wchar_t c2u_AD[256] = {
0xCDC5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AE[256] = {
+static const wchar_t c2u_AE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1636,7 +1636,7 @@ static wchar_t c2u_AE[256] = {
0xCE2B,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_AF[256] = {
+static const wchar_t c2u_AF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1661,7 +1661,7 @@ static wchar_t c2u_AF[256] = {
0xCE99,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xA0-0xA7 */
};
-static wchar_t c2u_B0[256] = {
+static const wchar_t c2u_B0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1697,7 +1697,7 @@ static wchar_t c2u_B0[256] = {
0xACF5,0xACF6,0xACFC,0xACFD,0xAD00,0xAD04,0xAD06,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B1[256] = {
+static const wchar_t c2u_B1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1733,7 +1733,7 @@ static wchar_t c2u_B1[256] = {
0xAE61,0xAE65,0xAE68,0xAE69,0xAE6C,0xAE70,0xAE78,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B2[256] = {
+static const wchar_t c2u_B2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1769,7 +1769,7 @@ static wchar_t c2u_B2[256] = {
0xB04C,0xB04E,0xB053,0xB054,0xB055,0xB057,0xB059,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B3[256] = {
+static const wchar_t c2u_B3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1805,7 +1805,7 @@ static wchar_t c2u_B3[256] = {
0xB19C,0xB1A8,0xB1CC,0xB1D0,0xB1D4,0xB1DC,0xB1DD,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B4[256] = {
+static const wchar_t c2u_B4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1841,7 +1841,7 @@ static wchar_t c2u_B4[256] = {
0xB358,0xB35B,0xB35C,0xB35E,0xB35F,0xB364,0xB365,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B5[256] = {
+static const wchar_t c2u_B5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1877,7 +1877,7 @@ static wchar_t c2u_B5[256] = {
0xB528,0xB529,0xB52A,0xB530,0xB531,0xB534,0xB538,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B6[256] = {
+static const wchar_t c2u_B6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1913,7 +1913,7 @@ static wchar_t c2u_B6[256] = {
0xB78D,0xB78F,0xB790,0xB791,0xB792,0xB796,0xB797,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B7[256] = {
+static const wchar_t c2u_B7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1949,7 +1949,7 @@ static wchar_t c2u_B7[256] = {
0xB951,0xB958,0xB959,0xB95C,0xB960,0xB968,0xB969,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B8[256] = {
+static const wchar_t c2u_B8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1985,7 +1985,7 @@ static wchar_t c2u_B8[256] = {
0xBABB,0xBABD,0xBAC4,0xBAC8,0xBAD8,0xBAD9,0xBAFC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B9[256] = {
+static const wchar_t c2u_B9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2021,7 +2021,7 @@ static wchar_t c2u_B9[256] = {
0xBC88,0xBC8B,0xBC8C,0xBC8E,0xBC94,0xBC95,0xBC97,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BA[256] = {
+static const wchar_t c2u_BA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2057,7 +2057,7 @@ static wchar_t c2u_BA[256] = {
0xBE57,0xBE59,0xBE5A,0xBE5B,0xBE60,0xBE61,0xBE64,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BB[256] = {
+static const wchar_t c2u_BB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2093,7 +2093,7 @@ static wchar_t c2u_BB[256] = {
0xC0D0,0xC0D8,0xC0D9,0xC0DB,0xC0DC,0xC0DD,0xC0E4,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BC[256] = {
+static const wchar_t c2u_BC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2129,7 +2129,7 @@ static wchar_t c2u_BC[256] = {
0xC21C,0xC21F,0xC220,0xC228,0xC229,0xC22B,0xC22D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BD[256] = {
+static const wchar_t c2u_BD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2165,7 +2165,7 @@ static wchar_t c2u_BD[256] = {
0xC3F5,0xC3F8,0xC408,0xC410,0xC424,0xC42C,0xC430,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BE[256] = {
+static const wchar_t c2u_BE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2201,7 +2201,7 @@ static wchar_t c2u_BE[256] = {
0xC5C6,0xC5C7,0xC5C8,0xC5C9,0xC5CA,0xC5CC,0xC5CE,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BF[256] = {
+static const wchar_t c2u_BF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2237,7 +2237,7 @@ static wchar_t c2u_BF[256] = {
0xC6D0,0xC6D4,0xC6DC,0xC6DD,0xC6E0,0xC6E1,0xC6E8,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C0[256] = {
+static const wchar_t c2u_C0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2273,7 +2273,7 @@ static wchar_t c2u_C0[256] = {
0xC7E8,0xC7EC,0xC800,0xC801,0xC804,0xC808,0xC80A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C1[256] = {
+static const wchar_t c2u_C1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2309,7 +2309,7 @@ static wchar_t c2u_C1[256] = {
0xC9C4,0xC9C7,0xC9C8,0xC9CA,0xC9D0,0xC9D1,0xC9D3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C2[256] = {
+static const wchar_t c2u_C2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2345,7 +2345,7 @@ static wchar_t c2u_C2[256] = {
0xCC29,0xCC2C,0xCC2E,0xCC30,0xCC38,0xCC39,0xCC3B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C3[256] = {
+static const wchar_t c2u_C3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2381,7 +2381,7 @@ static wchar_t c2u_C3[256] = {
0xCE21,0xCE24,0xCE28,0xCE30,0xCE31,0xCE33,0xCE35,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C4[256] = {
+static const wchar_t c2u_C4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2417,7 +2417,7 @@ static wchar_t c2u_C4[256] = {
0xD011,0xD018,0xD02D,0xD034,0xD035,0xD038,0xD03C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C5[256] = {
+static const wchar_t c2u_C5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2453,7 +2453,7 @@ static wchar_t c2u_C5[256] = {
0xD234,0xD23C,0xD23D,0xD23F,0xD241,0xD248,0xD25C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C6[256] = {
+static const wchar_t c2u_C6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2489,7 +2489,7 @@ static wchar_t c2u_C6[256] = {
0xD3ED,0xD3F0,0xD3F4,0xD3FC,0xD3FD,0xD3FF,0xD401,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C7[256] = {
+static const wchar_t c2u_C7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2525,7 +2525,7 @@ static wchar_t c2u_C7[256] = {
0xD610,0xD611,0xD613,0xD614,0xD615,0xD61C,0xD620,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C8[256] = {
+static const wchar_t c2u_C8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2561,7 +2561,7 @@ static wchar_t c2u_C8[256] = {
0xD789,0xD78C,0xD790,0xD798,0xD799,0xD79B,0xD79D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CA[256] = {
+static const wchar_t c2u_CA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2597,7 +2597,7 @@ static wchar_t c2u_CA[256] = {
0x76E3,0x77B0,0x7D3A,0x90AF,0x9451,0x9452,0x9F95,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CB[256] = {
+static const wchar_t c2u_CB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2633,7 +2633,7 @@ static wchar_t c2u_CB[256] = {
0x5091,0x6770,0x6840,0x5109,0x528D,0x5292,0x6AA2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CC[256] = {
+static const wchar_t c2u_CC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2669,7 +2669,7 @@ static wchar_t c2u_CC[256] = {
0x5951,0x5B63,0x5C46,0x60B8,0x6212,0x6842,0x68B0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CD[256] = {
+static const wchar_t c2u_CD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2705,7 +2705,7 @@ static wchar_t c2u_CD[256] = {
0x8CA2,0x978F,0x4E32,0x5BE1,0x6208,0x679C,0x74DC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CE[256] = {
+static const wchar_t c2u_CE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2741,7 +2741,7 @@ static wchar_t c2u_CE[256] = {
0x4E18,0x4E45,0x4E5D,0x4EC7,0x4FF1,0x5177,0x52FE,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CF[256] = {
+static const wchar_t c2u_CF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2777,7 +2777,7 @@ static wchar_t c2u_CF[256] = {
0x8A6D,0x8ECC,0x994B,0xF906,0x6677,0x6B78,0x8CB4,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D0[256] = {
+static const wchar_t c2u_D0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2813,7 +2813,7 @@ static wchar_t c2u_D0[256] = {
0x5D0E,0x5DF1,0x5E7E,0x5FCC,0x6280,0x65D7,0x65E3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D1[256] = {
+static const wchar_t c2u_D1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2849,7 +2849,7 @@ static wchar_t c2u_D1[256] = {
0x6960,0x6E73,0xF922,0x7537,0xF923,0xF924,0xF925,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D2[256] = {
+static const wchar_t c2u_D2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2885,7 +2885,7 @@ static wchar_t c2u_D2[256] = {
0xF959,0x5C3C,0x6CE5,0x533F,0x6EBA,0x591A,0x8336,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D3[256] = {
+static const wchar_t c2u_D3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2921,7 +2921,7 @@ static wchar_t c2u_D3[256] = {
0x5EA6,0x5F92,0x60BC,0x6311,0x6389,0x6417,0x6843,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D4[256] = {
+static const wchar_t c2u_D4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2957,7 +2957,7 @@ static wchar_t c2u_D4[256] = {
0x9127,0x9A30,0x5587,0x61F6,0xF95B,0x7669,0x7F85,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D5[256] = {
+static const wchar_t c2u_D5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2993,7 +2993,7 @@ static wchar_t c2u_D5[256] = {
0x792B,0x8F62,0x9742,0x6190,0x6200,0x6523,0x6F23,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D6[256] = {
+static const wchar_t c2u_D6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3029,7 +3029,7 @@ static wchar_t c2u_D6[256] = {
0x5ED6,0x6599,0x71CE,0x7642,0x77AD,0x804A,0x84FC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D7[256] = {
+static const wchar_t c2u_D7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3065,7 +3065,7 @@ static wchar_t c2u_D7[256] = {
0x9E9F,0x6797,0x6DCB,0x7433,0x81E8,0x9716,0x782C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D8[256] = {
+static const wchar_t c2u_D8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3101,7 +3101,7 @@ static wchar_t c2u_D8[256] = {
0x7704,0x7720,0x7DBF,0x7DEC,0x9762,0x9EB5,0x6EC5,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D9[256] = {
+static const wchar_t c2u_D9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3137,7 +3137,7 @@ static wchar_t c2u_D9[256] = {
0x58A8,0x9ED8,0x5011,0x520E,0x543B,0x554F,0x6587,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DA[256] = {
+static const wchar_t c2u_DA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3173,7 +3173,7 @@ static wchar_t c2u_DA[256] = {
0x9812,0x98EF,0x52C3,0x62D4,0x64A5,0x6E24,0x6F51,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DB[256] = {
+static const wchar_t c2u_DB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3209,7 +3209,7 @@ static wchar_t c2u_DB[256] = {
0x50FB,0x5288,0x58C1,0x64D8,0x6A97,0x74A7,0x7656,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DC[256] = {
+static const wchar_t c2u_DC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3245,7 +3245,7 @@ static wchar_t c2u_DC[256] = {
0x5256,0x526F,0x5426,0x5490,0x57E0,0x592B,0x5A66,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DD[256] = {
+static const wchar_t c2u_DD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3281,7 +3281,7 @@ static wchar_t c2u_DD[256] = {
0x7891,0x79D5,0x79D8,0x7C83,0x7DCB,0x7FE1,0x80A5,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DE[256] = {
+static const wchar_t c2u_DE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3317,7 +3317,7 @@ static wchar_t c2u_DE[256] = {
0x98FC,0x99DF,0x9E9D,0x524A,0xF969,0x6714,0xF96A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DF[256] = {
+static const wchar_t c2u_DF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3353,7 +3353,7 @@ static wchar_t c2u_DF[256] = {
0x68F2,0x7280,0x745E,0x7B6E,0x7D6E,0x7DD6,0x7F72,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E0[256] = {
+static const wchar_t c2u_E0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3389,7 +3389,7 @@ static wchar_t c2u_E0[256] = {
0x661F,0x665F,0x7329,0x73F9,0x76DB,0x7701,0x7B6C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E1[256] = {
+static const wchar_t c2u_E1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3425,7 +3425,7 @@ static wchar_t c2u_E1[256] = {
0x58FD,0x5AC2,0x5B88,0x5CAB,0x5CC0,0x5E25,0x6101,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E2[256] = {
+static const wchar_t c2u_E2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3461,7 +3461,7 @@ static wchar_t c2u_E2[256] = {
0x99B4,0x620C,0x8853,0x8FF0,0x9265,0x5D07,0x5D27,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E3[256] = {
+static const wchar_t c2u_E3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3497,7 +3497,7 @@ static wchar_t c2u_E3[256] = {
0x5BA4,0x5BE6,0x6089,0x5BE9,0x5C0B,0x5FC3,0x6C81,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E4[256] = {
+static const wchar_t c2u_E4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3533,7 +3533,7 @@ static wchar_t c2u_E4[256] = {
0x5384,0x627C,0x6396,0x6DB2,0x7E0A,0x814B,0x984D,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E5[256] = {
+static const wchar_t c2u_E5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3569,7 +3569,7 @@ static wchar_t c2u_E5[256] = {
0x4E88,0x4F59,0xF97F,0xF980,0xF981,0x5982,0xF982,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E6[256] = {
+static const wchar_t c2u_E6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3605,7 +3605,7 @@ static wchar_t c2u_E6[256] = {
0x67D3,0xF9A5,0x708E,0x7130,0x7430,0x8276,0x82D2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E7[256] = {
+static const wchar_t c2u_E7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3641,7 +3641,7 @@ static wchar_t c2u_E7[256] = {
0x61CA,0x6556,0x65FF,0x6664,0x68A7,0x6C5A,0x6FB3,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E8[256] = {
+static const wchar_t c2u_E8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3677,7 +3677,7 @@ static wchar_t c2u_E8[256] = {
0x66DC,0xF9BF,0x6A48,0xF9C0,0x71FF,0x7464,0xF9C1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E9[256] = {
+static const wchar_t c2u_E9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3713,7 +3713,7 @@ static wchar_t c2u_E9[256] = {
0x6A52,0x6B9E,0x6F90,0x7189,0x8018,0x82B8,0x8553,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EA[256] = {
+static const wchar_t c2u_EA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3749,7 +3749,7 @@ static wchar_t c2u_EA[256] = {
0x6961,0x6962,0x6CB9,0x6D27,0xF9CA,0x6E38,0xF9CB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EB[256] = {
+static const wchar_t c2u_EB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3785,7 +3785,7 @@ static wchar_t c2u_EB[256] = {
0x77E3,0x7FA9,0x8264,0x858F,0x87FB,0x8863,0x8ABC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EC[256] = {
+static const wchar_t c2u_EC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3821,7 +3821,7 @@ static wchar_t c2u_EC[256] = {
0xF9F5,0x7A14,0xF9F6,0x834F,0x8CC3,0x5165,0x5344,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_ED[256] = {
+static const wchar_t c2u_ED[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3857,7 +3857,7 @@ static wchar_t c2u_ED[256] = {
0x8523,0x8594,0x85CF,0x88DD,0x8D13,0x91AC,0x9577,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EE[256] = {
+static const wchar_t c2u_EE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3893,7 +3893,7 @@ static wchar_t c2u_EE[256] = {
0x5EDB,0x609B,0x6230,0x6813,0x6BBF,0x6C08,0x6FB1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EF[256] = {
+static const wchar_t c2u_EF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3929,7 +3929,7 @@ static wchar_t c2u_EF[256] = {
0x914A,0x91D8,0x9266,0x92CC,0x9320,0x9706,0x9756,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F0[256] = {
+static const wchar_t c2u_F0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3965,7 +3965,7 @@ static wchar_t c2u_F0[256] = {
0x6DD9,0x742E,0x7A2E,0x7D42,0x7D9C,0x7E31,0x816B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F1[256] = {
+static const wchar_t c2u_F1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4001,7 +4001,7 @@ static wchar_t c2u_F1[256] = {
0x75C7,0x7E52,0x84B8,0x8B49,0x8D08,0x4E4B,0x53EA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F2[256] = {
+static const wchar_t c2u_F2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4037,7 +4037,7 @@ static wchar_t c2u_F2[256] = {
0x659F,0x6715,0xF9FD,0x57F7,0x6F57,0x7DDD,0x8F2F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F3[256] = {
+static const wchar_t c2u_F3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4073,7 +4073,7 @@ static wchar_t c2u_F3[256] = {
0x83DC,0x8521,0x91C7,0x91F5,0x518A,0x67F5,0x7B56,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F4[256] = {
+static const wchar_t c2u_F4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4109,7 +4109,7 @@ static wchar_t c2u_F4[256] = {
0x521D,0x527F,0x54E8,0x6194,0x6284,0x62DB,0x68A2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F5[256] = {
+static const wchar_t c2u_F5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4145,7 +4145,7 @@ static wchar_t c2u_F5[256] = {
0x6C96,0x87F2,0x885D,0x8877,0x60B4,0x81B5,0x8403,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F6[256] = {
+static const wchar_t c2u_F6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4181,7 +4181,7 @@ static wchar_t c2u_F6[256] = {
0x666B,0x67DD,0x6FC1,0x6FEF,0x7422,0x7438,0x8A17,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F7[256] = {
+static const wchar_t c2u_F7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4217,7 +4217,7 @@ static wchar_t c2u_F7[256] = {
0x5742,0x677F,0x7248,0x74E3,0x8CA9,0x8FA6,0x9211,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F8[256] = {
+static const wchar_t c2u_F8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4253,7 +4253,7 @@ static wchar_t c2u_F8[256] = {
0x74E2,0x7968,0x8868,0x8C79,0x98C7,0x98C4,0x9A43,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F9[256] = {
+static const wchar_t c2u_F9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4289,7 +4289,7 @@ static wchar_t c2u_F9[256] = {
0x676D,0x6841,0x6C86,0x6E2F,0x7F38,0x809B,0x822A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FA[256] = {
+static const wchar_t c2u_FA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4325,7 +4325,7 @@ static wchar_t c2u_FA[256] = {
0x83A2,0x92CF,0x9830,0x4EA8,0x5144,0x5211,0x578B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FB[256] = {
+static const wchar_t c2u_FB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4361,7 +4361,7 @@ static wchar_t c2u_FB[256] = {
0x9D3B,0x5316,0x548C,0x5B05,0x6A3A,0x706B,0x7575,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FC[256] = {
+static const wchar_t c2u_FC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4397,7 +4397,7 @@ static wchar_t c2u_FC[256] = {
0x5B5D,0x6548,0x6585,0x66C9,0x689F,0x6D8D,0x6DC6,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_FD[256] = {
+static const wchar_t c2u_FD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -4433,7 +4433,7 @@ static wchar_t c2u_FD[256] = {
0x71B9,0x71BA,0x72A7,0x79A7,0x7A00,0x7FB2,0x8A70,0x0000,/* 0xF8-0xFF */
};
-static wchar_t *page_charset2uni[256] = {
+static const wchar_t *page_charset2uni[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -4468,7 +4468,7 @@ static wchar_t *page_charset2uni[256] = {
c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, NULL, NULL,
};
-static unsigned char u2c_01[512] = {
+static const unsigned char u2c_01[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4497,7 +4497,7 @@ static unsigned char u2c_01[512] = {
0x00, 0x00, 0x00, 0x00, 0xA8, 0xAE, 0xA9, 0xAE, /* 0x64-0x67 */
};
-static unsigned char u2c_02[512] = {
+static const unsigned char u2c_02[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4557,7 +4557,7 @@ static unsigned char u2c_02[512] = {
0x00, 0x00, 0xA2, 0xA9, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */
};
-static unsigned char u2c_03[512] = {
+static const unsigned char u2c_03[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4612,7 +4612,7 @@ static unsigned char u2c_03[512] = {
0xA5, 0xF7, 0xA5, 0xF8, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */
};
-static unsigned char u2c_04[512] = {
+static const unsigned char u2c_04[512] = {
0x00, 0x00, 0xAC, 0xA7, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4636,7 +4636,7 @@ static unsigned char u2c_04[512] = {
0x00, 0x00, 0xAC, 0xD7, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x53 */
};
-static unsigned char u2c_11[512] = {
+static const unsigned char u2c_11[512] = {
0xA4, 0xA1, 0xA4, 0xA2, 0xA4, 0xA4, 0xA4, 0xA7, /* 0x00-0x03 */
0xA4, 0xA8, 0xA4, 0xA9, 0xA4, 0xB1, 0xA4, 0xB2, /* 0x04-0x07 */
0xA4, 0xB3, 0xA4, 0xB5, 0xA4, 0xB6, 0xA4, 0xB7, /* 0x08-0x0B */
@@ -4703,7 +4703,7 @@ static unsigned char u2c_11[512] = {
0x00, 0x00, 0xA4, 0xF6, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_20[512] = {
+static const unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4750,7 +4750,7 @@ static unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x00, /* 0xA8-0xAB */
};
-static unsigned char u2c_21[512] = {
+static const unsigned char u2c_21[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC9, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xA2, 0xB5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4808,7 +4808,7 @@ static unsigned char u2c_21[512] = {
0xA2, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD4-0xD7 */
};
-static unsigned char u2c_22[512] = {
+static const unsigned char u2c_22[512] = {
0xA2, 0xA3, 0x00, 0x00, 0xA1, 0xD3, 0xA2, 0xA4, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xD4, /* 0x04-0x07 */
0xA1, 0xF4, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xF5, /* 0x08-0x0B */
@@ -4854,7 +4854,7 @@ static unsigned char u2c_22[512] = {
0x00, 0x00, 0xA1, 0xD1, 0x00, 0x00, 0x00, 0x00, /* 0xA4-0xA7 */
};
-static unsigned char u2c_23[512] = {
+static const unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4862,7 +4862,7 @@ static unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0xA1, 0xD2, 0x00, 0x00, /* 0x10-0x13 */
};
-static unsigned char u2c_24[512] = {
+static const unsigned char u2c_24[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4925,7 +4925,7 @@ static unsigned char u2c_24[512] = {
0xA8, 0xE5, 0xA8, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 0xE8-0xEB */
};
-static unsigned char u2c_25[512] = {
+static const unsigned char u2c_25[512] = {
0xA6, 0xA1, 0xA6, 0xAC, 0xA6, 0xA2, 0xA6, 0xAD, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4982,7 +4982,7 @@ static unsigned char u2c_25[512] = {
0xA2, 0xC4, 0xA2, 0xC5, 0x00, 0x00, 0x00, 0x00, /* 0xD0-0xD3 */
};
-static unsigned char u2c_26[512] = {
+static const unsigned char u2c_26[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA1, 0xDA, 0xA1, 0xD9, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5013,7 +5013,7 @@ static unsigned char u2c_26[512] = {
0xA2, 0xDD, 0xA2, 0xDA, 0x00, 0x00, 0x00, 0x00, /* 0x6C-0x6F */
};
-static unsigned char u2c_30[512] = {
+static const unsigned char u2c_30[512] = {
0xA1, 0xA1, 0xA1, 0xA2, 0xA1, 0xA3, 0xA1, 0xA8, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xA1, 0xB4, 0xA1, 0xB5, 0xA1, 0xB6, 0xA1, 0xB7, /* 0x08-0x0B */
@@ -5079,7 +5079,7 @@ static unsigned char u2c_30[512] = {
0xAB, 0xF4, 0xAB, 0xF5, 0xAB, 0xF6, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_31[512] = {
+static const unsigned char u2c_31[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5123,7 +5123,7 @@ static unsigned char u2c_31[512] = {
0xEF, 0xCB, 0xF4, 0xB8, 0xF2, 0xA2, 0xEC, 0xD1, /* 0x9C-0x9F */
};
-static unsigned char u2c_32[512] = {
+static const unsigned char u2c_32[512] = {
0xA9, 0xB1, 0xA9, 0xB2, 0xA9, 0xB3, 0xA9, 0xB4, /* 0x00-0x03 */
0xA9, 0xB5, 0xA9, 0xB6, 0xA9, 0xB7, 0xA9, 0xB8, /* 0x04-0x07 */
0xA9, 0xB9, 0xA9, 0xBA, 0xA9, 0xBB, 0xA9, 0xBC, /* 0x08-0x0B */
@@ -5172,7 +5172,7 @@ static unsigned char u2c_32[512] = {
0xE5, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */
};
-static unsigned char u2c_33[512] = {
+static const unsigned char u2c_33[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5232,7 +5232,7 @@ static unsigned char u2c_33[512] = {
0xA7, 0xEE, 0xA7, 0xE9, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */
};
-static unsigned char u2c_4E[512] = {
+static const unsigned char u2c_4E[512] = {
0xEC, 0xE9, 0xEF, 0xCB, 0x00, 0x00, 0xF6, 0xD2, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xB2, /* 0x04-0x07 */
0xED, 0xDB, 0xDF, 0xB2, 0xDF, 0xBE, 0xF9, 0xBB, /* 0x08-0x0B */
@@ -5299,7 +5299,7 @@ static unsigned char u2c_4E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xF2, /* 0xF8-0xFB */
};
-static unsigned char u2c_4F[512] = {
+static const unsigned char u2c_4F[512] = {
0x00, 0x00, 0xD0, 0xEA, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xF9, 0xF2, 0xEC, 0xA5, 0xD0, 0xDF, /* 0x08-0x0B */
@@ -5366,7 +5366,7 @@ static unsigned char u2c_4F[512] = {
0xDC, 0xE4, 0x00, 0x00, 0xE5, 0xEF, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_50[512] = {
+static const unsigned char u2c_50[512] = {
0x00, 0x00, 0x00, 0x00, 0xDC, 0xB1, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xD5, 0xD6, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xF3, 0xDA, 0x00, 0x00, 0xCB, 0xC1, /* 0x08-0x0B */
@@ -5434,7 +5434,7 @@ static unsigned char u2c_50[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xC7, /* 0xFC-0xFF */
};
-static unsigned char u2c_51[512] = {
+static const unsigned char u2c_51[512] = {
0xEB, 0xF0, 0xF1, 0xD6, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xE5, 0xE2, 0x00, 0x00, 0xCC, 0xCC, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xCB, 0xFB, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5502,7 +5502,7 @@ static unsigned char u2c_51[512] = {
0x00, 0x00, 0xF9, 0xDE, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_52[512] = {
+static const unsigned char u2c_52[512] = {
0xD3, 0xEF, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xD3, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xDD, 0xC2, 0xEF, 0xB7, /* 0x04-0x07 */
0xE7, 0xD4, 0x00, 0x00, 0xCA, 0xCA, 0x00, 0x00, /* 0x08-0x0B */
@@ -5570,7 +5570,7 @@ static unsigned char u2c_52[512] = {
0x00, 0x00, 0x00, 0x00, 0xCE, 0xFE, 0xDA, 0xA8, /* 0xFC-0xFF */
};
-static unsigned char u2c_53[512] = {
+static const unsigned char u2c_53[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xF8, 0xD0, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xFD, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5637,7 +5637,7 @@ static unsigned char u2c_53[512] = {
0xDE, 0xC9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_54[512] = {
+static const unsigned char u2c_54[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xDE, /* 0x00-0x03 */
0xCA, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xF9, 0xEA, 0xD1, 0xCE, 0xEE, 0xD4, 0x00, 0x00, /* 0x08-0x0B */
@@ -5704,7 +5704,7 @@ static unsigned char u2c_54[512] = {
0x00, 0x00, 0x00, 0x00, 0xF8, 0xD4, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_55[512] = {
+static const unsigned char u2c_55[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xF8, 0xA6, 0x00, 0x00, 0xDE, 0xCA, 0xF2, 0xC6, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5772,7 +5772,7 @@ static unsigned char u2c_55[512] = {
0x00, 0x00, 0xE1, 0xF5, 0xF1, 0xB3, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_56[512] = {
+static const unsigned char u2c_56[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xF7, 0xA3, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xCA, 0xA9, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5839,7 +5839,7 @@ static unsigned char u2c_56[512] = {
0x00, 0x00, 0xD6, 0xB7, 0xCD, 0xB3, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_57[512] = {
+static const unsigned char u2c_57[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xD5, /* 0x00-0x03 */
0xE5, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xCF, 0xEA, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xD0, /* 0x08-0x0B */
@@ -5907,7 +5907,7 @@ static unsigned char u2c_57[512] = {
0xD0, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_58[512] = {
+static const unsigned char u2c_58[512] = {
0xCF, 0xDC, 0x00, 0x00, 0xD3, 0xD1, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xCC, 0xB1, 0xF7, 0xD8, 0x00, 0x00, /* 0x04-0x07 */
0xCB, 0xA8, 0xEB, 0xBC, 0xE4, 0xBE, 0x00, 0x00, /* 0x08-0x0B */
@@ -5975,7 +5975,7 @@ static unsigned char u2c_58[512] = {
0x00, 0x00, 0xE1, 0xF8, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_59[512] = {
+static const unsigned char u2c_59[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6043,7 +6043,7 @@ static unsigned char u2c_59[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED, 0xAC, /* 0xFC-0xFF */
};
-static unsigned char u2c_5A[512] = {
+static const unsigned char u2c_5A[512] = {
0x00, 0x00, 0xEA, 0xCE, 0x00, 0x00, 0xE8, 0xDF, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6106,7 +6106,7 @@ static unsigned char u2c_5A[512] = {
0x00, 0x00, 0xD2, 0xEC, 0x00, 0x00, 0x00, 0x00, /* 0xE8-0xEB */
};
-static unsigned char u2c_5B[512] = {
+static const unsigned char u2c_5B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xFB, 0xFB, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xFD, 0xF0, 0x00, 0x00, 0xE0, 0xBD, /* 0x08-0x0B */
@@ -6173,7 +6173,7 @@ static unsigned char u2c_5B[512] = {
0xF5, 0xBB, 0x00, 0x00, 0xDE, 0xD1, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_5C[512] = {
+static const unsigned char u2c_5C[512] = {
0x00, 0x00, 0xDC, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xDE, 0xD2, 0x00, 0x00, 0x00, 0x00, 0xED, 0xE2, /* 0x04-0x07 */
0xEE, 0xF6, 0xEA, 0xCF, 0xF0, 0xEE, 0xE3, 0xFC, /* 0x08-0x0B */
@@ -6241,7 +6241,7 @@ static unsigned char u2c_5C[512] = {
0x00, 0x00, 0xFA, 0xF2, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_5D[512] = {
+static const unsigned char u2c_5D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0xFD, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6309,7 +6309,7 @@ static unsigned char u2c_5D[512] = {
0x00, 0x00, 0xE1, 0xDE, 0xCB, 0xEE, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_5E[512] = {
+static const unsigned char u2c_5E[512] = {
0x00, 0x00, 0x00, 0x00, 0xE3, 0xBC, 0xF8, 0xD6, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xDB, 0xEE, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6376,7 +6376,7 @@ static unsigned char u2c_5E[512] = {
0x00, 0x00, 0x00, 0x00, 0xCB, 0xEF, 0xFC, 0xDF, /* 0xF8-0xFB */
};
-static unsigned char u2c_5F[512] = {
+static const unsigned char u2c_5F[512] = {
0x00, 0x00, 0xDC, 0xA7, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xD6, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xF8, 0xC9, 0x00, 0x00, /* 0x08-0x0B */
@@ -6444,7 +6444,7 @@ static unsigned char u2c_5F[512] = {
0x00, 0x00, 0xFB, 0xEC, 0x00, 0x00, 0xDD, 0xC8, /* 0xFC-0xFF */
};
-static unsigned char u2c_60[512] = {
+static const unsigned char u2c_60[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6511,7 +6511,7 @@ static unsigned char u2c_60[512] = {
0x00, 0x00, 0xE5, 0xA9, 0xE0, 0xF6, 0xF6, 0xB3, /* 0xF8-0xFB */
};
-static unsigned char u2c_61[512] = {
+static const unsigned char u2c_61[512] = {
0x00, 0x00, 0xE1, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xCB, 0xF0, 0x00, 0x00, /* 0x04-0x07 */
0xEA, 0xEF, 0xEA, 0xF0, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6579,7 +6579,7 @@ static unsigned char u2c_61[512] = {
0xCF, 0xAB, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xF3, /* 0xFC-0xFF */
};
-static unsigned char u2c_62[512] = {
+static const unsigned char u2c_62[512] = {
0xD5, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xD4, /* 0x04-0x07 */
0xCD, 0xFC, 0x00, 0x00, 0xD9, 0xE6, 0x00, 0x00, /* 0x08-0x0B */
@@ -6647,7 +6647,7 @@ static unsigned char u2c_62[512] = {
0x00, 0x00, 0x00, 0x00, 0xE3, 0xA6, 0xD1, 0xDA, /* 0xFC-0xFF */
};
-static unsigned char u2c_63[512] = {
+static const unsigned char u2c_63[512] = {
0x00, 0x00, 0xF2, 0xA5, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xA6, /* 0x04-0x07 */
0x00, 0x00, 0xE4, 0xCE, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6713,7 +6713,7 @@ static unsigned char u2c_63[512] = {
0xEA, 0xB5, 0x00, 0x00, 0xE5, 0xAA, 0xDF, 0xBA, /* 0xF4-0xF7 */
};
-static unsigned char u2c_64[512] = {
+static const unsigned char u2c_64[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6781,7 +6781,7 @@ static unsigned char u2c_64[512] = {
0x00, 0x00, 0x00, 0x00, 0xE8, 0xF6, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_65[512] = {
+static const unsigned char u2c_65[512] = {
0xDA, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xF7, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6849,7 +6849,7 @@ static unsigned char u2c_65[512] = {
0xDA, 0xC4, 0xD4, 0xC5, 0x00, 0x00, 0xE7, 0xFA, /* 0xFC-0xFF */
};
-static unsigned char u2c_66[512] = {
+static const unsigned char u2c_66[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xCD, 0xE0, 0xE3, 0xB0, /* 0x04-0x07 */
0x00, 0x00, 0xDB, 0xB2, 0xFB, 0xC4, 0x00, 0x00, /* 0x08-0x0B */
@@ -6917,7 +6917,7 @@ static unsigned char u2c_66[512] = {
0xD8, 0xBA, 0x00, 0x00, 0xF1, 0xF4, 0xF4, 0xF0, /* 0xFC-0xFF */
};
-static unsigned char u2c_67[512] = {
+static const unsigned char u2c_67[512] = {
0xF5, 0xCC, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xE5, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xEA, 0xC5, 0xEA, 0xF3, 0x00, 0x00, 0xDD, 0xDB, /* 0x08-0x0B */
@@ -6985,7 +6985,7 @@ static unsigned char u2c_67[512] = {
0x00, 0x00, 0x00, 0x00, 0xEF, 0xDE, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_68[512] = {
+static const unsigned char u2c_68[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7052,7 +7052,7 @@ static unsigned char u2c_68[512] = {
0x00, 0x00, 0xD4, 0xA1, 0xCE, 0xB2, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_69[512] = {
+static const unsigned char u2c_69[512] = {
0xE8, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xEB, 0xF5, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7120,7 +7120,7 @@ static unsigned char u2c_69[512] = {
0x00, 0x00, 0xF0, 0xCB, 0x00, 0x00, 0xD0, 0xC7, /* 0xFC-0xFF */
};
-static unsigned char u2c_6A[512] = {
+static const unsigned char u2c_6A[512] = {
0x00, 0x00, 0x00, 0x00, 0xE4, 0xC5, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xDB, 0xE0, 0x00, 0x00, /* 0x08-0x0B */
@@ -7187,7 +7187,7 @@ static unsigned char u2c_6A[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xA1, /* 0xF8-0xFB */
};
-static unsigned char u2c_6B[512] = {
+static const unsigned char u2c_6B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xD5, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xCF, 0xED, 0x00, 0x00, /* 0x08-0x0B */
@@ -7251,7 +7251,7 @@ static unsigned char u2c_6B[512] = {
0xCF, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xEC-0xEF */
};
-static unsigned char u2c_6C[512] = {
+static const unsigned char u2c_6C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xEE, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7316,7 +7316,7 @@ static unsigned char u2c_6C[512] = {
0xF7, 0xC1, 0x00, 0x00, 0x00, 0x00, 0xE7, 0xB6, /* 0xF0-0xF3 */
};
-static unsigned char u2c_6D[512] = {
+static const unsigned char u2c_6D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xC7, /* 0x08-0x0B */
@@ -7383,7 +7383,7 @@ static unsigned char u2c_6D[512] = {
0xF4, 0xE8, 0xE5, 0xF4, 0xF4, 0xBC, 0xF4, 0xD5, /* 0xF8-0xFB */
};
-static unsigned char u2c_6E[512] = {
+static const unsigned char u2c_6E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7451,7 +7451,7 @@ static unsigned char u2c_6E[512] = {
0x00, 0x00, 0x00, 0x00, 0xCD, 0xE3, 0xD8, 0xBB, /* 0xFC-0xFF */
};
-static unsigned char u2c_6F[512] = {
+static const unsigned char u2c_6F[512] = {
0x00, 0x00, 0xE5, 0xDB, 0xF8, 0xF7, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xF6, 0xD4, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7519,7 +7519,7 @@ static unsigned char u2c_6F[512] = {
0x00, 0x00, 0x00, 0x00, 0xD5, 0xEB, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_70[512] = {
+static const unsigned char u2c_70[512] = {
0x00, 0x00, 0xE5, 0xC8, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xFB, 0xA4, 0xD4, 0xB9, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xDE, 0xE1, 0x00, 0x00, 0xE4, 0xA3, /* 0x08-0x0B */
@@ -7587,7 +7587,7 @@ static unsigned char u2c_70[512] = {
0x00, 0x00, 0xDC, 0xEB, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_71[512] = {
+static const unsigned char u2c_71[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xFD, 0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE5, 0xEA, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7655,7 +7655,7 @@ static unsigned char u2c_71[512] = {
0xE3, 0xE8, 0x00, 0x00, 0xD4, 0xA7, 0xE8, 0xFC, /* 0xFC-0xFF */
};
-static unsigned char u2c_72[512] = {
+static const unsigned char u2c_72[512] = {
0xFA, 0xD2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xF8, 0xEF, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7723,7 +7723,7 @@ static unsigned char u2c_72[512] = {
0xD5, 0xC9, 0xF8, 0xAC, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_73[512] = {
+static const unsigned char u2c_73[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE7, 0xD9, 0x00, 0x00, /* 0x08-0x0B */
@@ -7791,7 +7791,7 @@ static unsigned char u2c_73[512] = {
0x00, 0x00, 0xEF, 0xEA, 0xFA, 0xDE, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_74[512] = {
+static const unsigned char u2c_74[512] = {
0x00, 0x00, 0xE0, 0xC4, 0x00, 0x00, 0xCF, 0xB9, /* 0x00-0x03 */
0x00, 0x00, 0xD5, 0xCA, 0xD7, 0xE2, 0xE2, 0xAF, /* 0x04-0x07 */
0x00, 0x00, 0xD7, 0xB8, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7857,7 +7857,7 @@ static unsigned char u2c_74[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xED, 0xB6, /* 0xF4-0xF7 */
};
-static unsigned char u2c_75[512] = {
+static const unsigned char u2c_75[512] = {
0x00, 0x00, 0xDC, 0xBA, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xCC, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7925,7 +7925,7 @@ static unsigned char u2c_75[512] = {
0xCD, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_76[512] = {
+static const unsigned char u2c_76[512] = {
0xE5, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7993,7 +7993,7 @@ static unsigned char u2c_76[512] = {
0xDA, 0xF0, 0x00, 0x00, 0xE2, 0xEA, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_77[512] = {
+static const unsigned char u2c_77[512] = {
0x00, 0x00, 0xE0, 0xFD, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xD8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xF7, 0xAF, 0xDA, 0xB6, 0x00, 0x00, 0xCA, 0xD7, /* 0x08-0x0B */
@@ -8058,7 +8058,7 @@ static unsigned char u2c_77[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xB4, /* 0xF0-0xF3 */
};
-static unsigned char u2c_78[512] = {
+static const unsigned char u2c_78[512] = {
0x00, 0x00, 0x00, 0x00, 0xDE, 0xE3, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8125,7 +8125,7 @@ static unsigned char u2c_78[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xF2, /* 0xF8-0xFB */
};
-static unsigned char u2c_79[512] = {
+static const unsigned char u2c_79[512] = {
0x00, 0x00, 0xF5, 0xA7, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8192,7 +8192,7 @@ static unsigned char u2c_79[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xB9, /* 0xF8-0xFB */
};
-static unsigned char u2c_7A[512] = {
+static const unsigned char u2c_7A[512] = {
0xFD, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xE1, 0xAA, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xCA, 0xD9, 0x00, 0x00, 0x00, 0x00, 0xEF, 0xEF, /* 0x08-0x0B */
@@ -8260,7 +8260,7 @@ static unsigned char u2c_7A[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCA, 0xDA, /* 0xFC-0xFF */
};
-static unsigned char u2c_7B[512] = {
+static const unsigned char u2c_7B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8323,7 +8323,7 @@ static unsigned char u2c_7B[512] = {
0x00, 0x00, 0xDE, 0xE8, 0x00, 0x00, 0x00, 0x00, /* 0xE8-0xEB */
};
-static unsigned char u2c_7C[512] = {
+static const unsigned char u2c_7C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xEA, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8391,7 +8391,7 @@ static unsigned char u2c_7C[512] = {
0x00, 0x00, 0x00, 0x00, 0xD0, 0xAC, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_7D[512] = {
+static const unsigned char u2c_7D[512] = {
0xD1, 0xBA, 0x00, 0x00, 0xF1, 0xC4, 0x00, 0x00, /* 0x00-0x03 */
0xE5, 0xB3, 0xFB, 0xF5, 0xE9, 0xE1, 0xFD, 0xE0, /* 0x04-0x07 */
0xFC, 0xBC, 0x00, 0x00, 0xDA, 0xA2, 0xDA, 0xA3, /* 0x08-0x0B */
@@ -8458,7 +8458,7 @@ static unsigned char u2c_7D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 0xC6, /* 0xF8-0xFB */
};
-static unsigned char u2c_7E[512] = {
+static const unsigned char u2c_7E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xF2, 0xDB, 0xE4, 0xFC, 0x00, 0x00, /* 0x08-0x0B */
@@ -8502,7 +8502,7 @@ static unsigned char u2c_7E[512] = {
0xD5, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */
};
-static unsigned char u2c_7F[512] = {
+static const unsigned char u2c_7F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8570,7 +8570,7 @@ static unsigned char u2c_7F[512] = {
0xEC, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_80[512] = {
+static const unsigned char u2c_80[512] = {
0xE9, 0xA5, 0xD6, 0xD5, 0x00, 0x00, 0xCD, 0xC5, /* 0x00-0x03 */
0x00, 0x00, 0xED, 0xBA, 0xD1, 0xBD, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xCF, 0xBE, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8638,7 +8638,7 @@ static unsigned char u2c_80[512] = {
0x00, 0x00, 0xD2, 0xF6, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_81[512] = {
+static const unsigned char u2c_81[512] = {
0x00, 0x00, 0x00, 0x00, 0xF2, 0xB7, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xFA, 0xF6, 0xF6, 0xAA, 0xFA, 0xF7, /* 0x04-0x07 */
0xD8, 0xE6, 0x00, 0x00, 0xF4, 0xB1, 0x00, 0x00, /* 0x08-0x0B */
@@ -8706,7 +8706,7 @@ static unsigned char u2c_81[512] = {
0xCF, 0xBF, 0x00, 0x00, 0xEB, 0xAC, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_82[512] = {
+static const unsigned char u2c_82[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xCF, 0xC0, 0x00, 0x00, 0xE6, 0xA8, /* 0x04-0x07 */
0xFD, 0xE9, 0x00, 0x00, 0xCF, 0xC1, 0x00, 0x00, /* 0x08-0x0B */
@@ -8774,7 +8774,7 @@ static unsigned char u2c_82[512] = {
0x00, 0x00, 0xCD, 0xC9, 0xF9, 0xB7, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_83[512] = {
+static const unsigned char u2c_83[512] = {
0x00, 0x00, 0xF1, 0xE8, 0xD9, 0xF2, 0xDB, 0xF5, /* 0x00-0x03 */
0xCA, 0xB5, 0xD9, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xD8, 0xC9, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8842,7 +8842,7 @@ static unsigned char u2c_83[512] = {
0x00, 0x00, 0xE2, 0xDD, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_84[512] = {
+static const unsigned char u2c_84[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0xFE, /* 0x00-0x03 */
0xD4, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xD5, 0xD1, 0x00, 0x00, /* 0x08-0x0B */
@@ -8910,7 +8910,7 @@ static unsigned char u2c_84[512] = {
0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_85[512] = {
+static const unsigned char u2c_85[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8978,7 +8978,7 @@ static unsigned char u2c_85[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xAB, /* 0xFC-0xFF */
};
-static unsigned char u2c_86[512] = {
+static const unsigned char u2c_86[512] = {
0x00, 0x00, 0x00, 0x00, 0xE7, 0xDE, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xE1, 0xCC, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE8, 0xB3, 0x00, 0x00, /* 0x08-0x0B */
@@ -9046,7 +9046,7 @@ static unsigned char u2c_86[512] = {
0x00, 0x00, 0x00, 0x00, 0xE4, 0xB6, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_87[512] = {
+static const unsigned char u2c_87[512] = {
0xF5, 0xB9, 0x00, 0x00, 0xDC, 0xF0, 0xE3, 0xF1, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xE8, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9114,7 +9114,7 @@ static unsigned char u2c_87[512] = {
0x00, 0x00, 0x00, 0x00, 0xE0, 0xEA, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_88[512] = {
+static const unsigned char u2c_88[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xE3, 0xB2, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9182,7 +9182,7 @@ static unsigned char u2c_88[512] = {
0x00, 0x00, 0xF0, 0xB2, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_89[512] = {
+static const unsigned char u2c_89[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9249,7 +9249,7 @@ static unsigned char u2c_89[512] = {
0xF5, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_8A[512] = {
+static const unsigned char u2c_8A[512] = {
0xE5, 0xEB, 0x00, 0x00, 0xEF, 0xF4, 0xDD, 0xB5, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xCD, 0xAA, 0x00, 0x00, 0xE3, 0xF2, 0x00, 0x00, /* 0x08-0x0B */
@@ -9317,7 +9317,7 @@ static unsigned char u2c_8A[512] = {
0x00, 0x00, 0x00, 0x00, 0xD1, 0xE7, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8B[512] = {
+static const unsigned char u2c_8B[512] = {
0xD9, 0xC7, 0xE4, 0xD7, 0xEA, 0xDD, 0x00, 0x00, /* 0x00-0x03 */
0xD4, 0xF7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9360,7 +9360,7 @@ static unsigned char u2c_8B[512] = {
0x00, 0x00, 0x00, 0x00, 0xF3, 0xC6, 0x00, 0x00, /* 0x98-0x9B */
};
-static unsigned char u2c_8C[512] = {
+static const unsigned char u2c_8C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9428,7 +9428,7 @@ static unsigned char u2c_8C[512] = {
0xCF, 0xC5, 0xDF, 0xDF, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8D[512] = {
+static const unsigned char u2c_8D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xF2, 0xBE, 0xF6, 0xA1, 0x00, 0x00, 0xEB, 0xCB, /* 0x04-0x07 */
0xF1, 0xFC, 0x00, 0x00, 0xF3, 0xC7, 0x00, 0x00, /* 0x08-0x0B */
@@ -9493,7 +9493,7 @@ static unsigned char u2c_8D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xAF, /* 0xF0-0xF3 */
};
-static unsigned char u2c_8E[512] = {
+static const unsigned char u2c_8E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xE9, 0xC9, 0x00, 0x00, /* 0x08-0x0B */
@@ -9561,7 +9561,7 @@ static unsigned char u2c_8E[512] = {
0x00, 0x00, 0x00, 0x00, 0xE3, 0xDC, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8F[512] = {
+static const unsigned char u2c_8F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xF2, /* 0x00-0x03 */
0x00, 0x00, 0xD6, 0xD9, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xEE, 0xB0, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9629,7 +9629,7 @@ static unsigned char u2c_8F[512] = {
0x00, 0x00, 0xF5, 0xDA, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_90[512] = {
+static const unsigned char u2c_90[512] = {
0xF7, 0xDC, 0xE1, 0xEA, 0xCE, 0xC1, 0xD4, 0xB1, /* 0x00-0x03 */
0x00, 0x00, 0xFD, 0xB1, 0xE6, 0xBD, 0x00, 0x00, /* 0x04-0x07 */
0xFB, 0xAD, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xE7, /* 0x08-0x0B */
@@ -9697,7 +9697,7 @@ static unsigned char u2c_90[512] = {
0x00, 0x00, 0xD4, 0xB4, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_91[512] = {
+static const unsigned char u2c_91[512] = {
0x00, 0x00, 0x00, 0x00, 0xE4, 0xC7, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9763,7 +9763,7 @@ static unsigned char u2c_91[512] = {
0x00, 0x00, 0xF3, 0xFB, 0x00, 0x00, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_92[512] = {
+static const unsigned char u2c_92[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9831,7 +9831,7 @@ static unsigned char u2c_92[512] = {
0xCB, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_93[512] = {
+static const unsigned char u2c_93[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xD6, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9897,7 +9897,7 @@ static unsigned char u2c_93[512] = {
0x00, 0x00, 0x00, 0x00, 0xF3, 0xA1, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_94[512] = {
+static const unsigned char u2c_94[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xFC, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9932,7 +9932,7 @@ static unsigned char u2c_94[512] = {
0x00, 0x00, 0xF3, 0xC8, 0x00, 0x00, 0xF3, 0xBA, /* 0x7C-0x7F */
};
-static unsigned char u2c_95[512] = {
+static const unsigned char u2c_95[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9993,7 +9993,7 @@ static unsigned char u2c_95[512] = {
0x00, 0x00, 0xF4, 0xC5, 0xDC, 0xA3, 0x00, 0x00, /* 0xE0-0xE3 */
};
-static unsigned char u2c_96[512] = {
+static const unsigned char u2c_96[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10060,7 +10060,7 @@ static unsigned char u2c_96[512] = {
0x00, 0x00, 0xDA, 0xDF, 0x00, 0x00, 0xEF, 0xB3, /* 0xF8-0xFB */
};
-static unsigned char u2c_97[512] = {
+static const unsigned char u2c_97[512] = {
0xE2, 0xCD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xEF, 0xFD, 0xF2, 0xE8, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10128,7 +10128,7 @@ static unsigned char u2c_97[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0xC2, /* 0xFC-0xFF */
};
-static unsigned char u2c_98[512] = {
+static const unsigned char u2c_98[512] = {
0xFB, 0xE1, 0xFA, 0xED, 0xF0, 0xA2, 0xCC, 0xF1, /* 0x00-0x03 */
0x00, 0x00, 0xFA, 0xA3, 0xE2, 0xF7, 0x00, 0x00, /* 0x04-0x07 */
0xE2, 0xCE, 0x00, 0x00, 0xE9, 0xF5, 0x00, 0x00, /* 0x08-0x0B */
@@ -10196,7 +10196,7 @@ static unsigned char u2c_98[512] = {
0xDE, 0xF8, 0xF8, 0xE9, 0xE3, 0xDE, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_99[512] = {
+static const unsigned char u2c_99[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xF5, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xFA, 0xC3, 0xE5, 0xD7, 0x00, 0x00, /* 0x08-0x0B */
@@ -10264,7 +10264,7 @@ static unsigned char u2c_99[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xE7, /* 0xFC-0xFF */
};
-static unsigned char u2c_9A[512] = {
+static const unsigned char u2c_9A[512] = {
0x00, 0x00, 0xDE, 0xBE, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xDC, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10328,7 +10328,7 @@ static unsigned char u2c_9A[512] = {
0x00, 0x00, 0x00, 0x00, 0xDB, 0xA5, 0x00, 0x00, /* 0xEC-0xEF */
};
-static unsigned char u2c_9B[512] = {
+static const unsigned char u2c_9B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10391,7 +10391,7 @@ static unsigned char u2c_9B[512] = {
0xCC, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xE8-0xEB */
};
-static unsigned char u2c_9C[512] = {
+static const unsigned char u2c_9C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10457,7 +10457,7 @@ static unsigned char u2c_9C[512] = {
0xD9, 0xB0, 0x00, 0x00, 0xE6, 0xE9, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_9D[512] = {
+static const unsigned char u2c_9D[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xE4, 0xBC, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10524,7 +10524,7 @@ static unsigned char u2c_9D[512] = {
0xFD, 0xD3, 0xEB, 0xED, 0xD6, 0xDC, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_9E[512] = {
+static const unsigned char u2c_9E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10590,7 +10590,7 @@ static unsigned char u2c_9E[512] = {
0xDA, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF4-0xF7 */
};
-static unsigned char u2c_9F[512] = {
+static const unsigned char u2c_9F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xA8, /* 0x04-0x07 */
0xDC, 0xAF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -10634,7 +10634,7 @@ static unsigned char u2c_9F[512] = {
0xCF, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */
};
-static unsigned char u2c_AC[512] = {
+static const unsigned char u2c_AC[512] = {
0xB0, 0xA1, 0xB0, 0xA2, 0x81, 0x41, 0x81, 0x42, /* 0x00-0x03 */
0xB0, 0xA3, 0x81, 0x43, 0x81, 0x44, 0xB0, 0xA4, /* 0x04-0x07 */
0xB0, 0xA5, 0xB0, 0xA6, 0xB0, 0xA7, 0x81, 0x45, /* 0x08-0x0B */
@@ -10702,7 +10702,7 @@ static unsigned char u2c_AC[512] = {
0xB0, 0xFA, 0xB0, 0xFB, 0x81, 0xF0, 0x81, 0xF1, /* 0xFC-0xFF */
};
-static unsigned char u2c_AD[512] = {
+static const unsigned char u2c_AD[512] = {
0xB0, 0xFC, 0x81, 0xF2, 0x81, 0xF3, 0x81, 0xF4, /* 0x00-0x03 */
0xB0, 0xFD, 0x81, 0xF5, 0xB0, 0xFE, 0x81, 0xF6, /* 0x04-0x07 */
0x81, 0xF7, 0x81, 0xF8, 0x81, 0xF9, 0x81, 0xFA, /* 0x08-0x0B */
@@ -10770,7 +10770,7 @@ static unsigned char u2c_AD[512] = {
0xB1, 0xD9, 0x83, 0x43, 0x83, 0x44, 0xB1, 0xDA, /* 0xFC-0xFF */
};
-static unsigned char u2c_AE[512] = {
+static const unsigned char u2c_AE[512] = {
0xB1, 0xDB, 0xB1, 0xDC, 0x83, 0x45, 0x83, 0x46, /* 0x00-0x03 */
0x83, 0x47, 0x83, 0x48, 0x83, 0x49, 0x83, 0x4A, /* 0x04-0x07 */
0xB1, 0xDD, 0xB1, 0xDE, 0x83, 0x4B, 0xB1, 0xDF, /* 0x08-0x0B */
@@ -10838,7 +10838,7 @@ static unsigned char u2c_AE[512] = {
0xB2, 0xBA, 0x84, 0x52, 0x84, 0x53, 0x84, 0x54, /* 0xFC-0xFF */
};
-static unsigned char u2c_AF[512] = {
+static const unsigned char u2c_AF[512] = {
0x84, 0x55, 0x84, 0x56, 0x84, 0x57, 0x84, 0x58, /* 0x00-0x03 */
0x84, 0x59, 0x84, 0x5A, 0x84, 0x61, 0xB2, 0xBB, /* 0x04-0x07 */
0xB2, 0xBC, 0x84, 0x62, 0x84, 0x63, 0x84, 0x64, /* 0x08-0x0B */
@@ -10906,7 +10906,7 @@ static unsigned char u2c_AF[512] = {
0x85, 0x75, 0x85, 0x76, 0x85, 0x77, 0x85, 0x78, /* 0xFC-0xFF */
};
-static unsigned char u2c_B0[512] = {
+static const unsigned char u2c_B0[512] = {
0xB2, 0xEB, 0xB2, 0xEC, 0x85, 0x79, 0x85, 0x7A, /* 0x00-0x03 */
0xB2, 0xED, 0x85, 0x81, 0x85, 0x82, 0x85, 0x83, /* 0x04-0x07 */
0x85, 0x84, 0x85, 0x85, 0x85, 0x86, 0x85, 0x87, /* 0x08-0x0B */
@@ -10974,7 +10974,7 @@ static unsigned char u2c_B0[512] = {
0x86, 0x8C, 0x86, 0x8D, 0x86, 0x8E, 0x86, 0x8F, /* 0xFC-0xFF */
};
-static unsigned char u2c_B1[512] = {
+static const unsigned char u2c_B1[512] = {
0x86, 0x90, 0x86, 0x91, 0x86, 0x92, 0x86, 0x93, /* 0x00-0x03 */
0x86, 0x94, 0x86, 0x95, 0x86, 0x96, 0x86, 0x97, /* 0x04-0x07 */
0xB3, 0xCA, 0xB3, 0xCB, 0x86, 0x98, 0xB3, 0xCC, /* 0x08-0x0B */
@@ -11042,7 +11042,7 @@ static unsigned char u2c_B1[512] = {
0x87, 0x9E, 0xB4, 0xA8, 0x87, 0x9F, 0x87, 0xA0, /* 0xFC-0xFF */
};
-static unsigned char u2c_B2[512] = {
+static const unsigned char u2c_B2[512] = {
0x87, 0xA1, 0x87, 0xA2, 0x87, 0xA3, 0x87, 0xA4, /* 0x00-0x03 */
0xB4, 0xA9, 0xB4, 0xAA, 0x87, 0xA5, 0x87, 0xA6, /* 0x04-0x07 */
0xB4, 0xAB, 0x87, 0xA7, 0x87, 0xA8, 0xB4, 0xAC, /* 0x08-0x0B */
@@ -11110,7 +11110,7 @@ static unsigned char u2c_B2[512] = {
0x88, 0xAA, 0x88, 0xAB, 0x88, 0xAC, 0xB4, 0xEA, /* 0xFC-0xFF */
};
-static unsigned char u2c_B3[512] = {
+static const unsigned char u2c_B3[512] = {
0xB4, 0xEB, 0xB4, 0xEC, 0x88, 0xAD, 0x88, 0xAE, /* 0x00-0x03 */
0xB4, 0xED, 0x88, 0xAF, 0x88, 0xB0, 0x88, 0xB1, /* 0x04-0x07 */
0xB4, 0xEE, 0x88, 0xB2, 0x88, 0xB3, 0x88, 0xB4, /* 0x08-0x0B */
@@ -11178,7 +11178,7 @@ static unsigned char u2c_B3[512] = {
0xB5, 0xC5, 0x89, 0xBF, 0x89, 0xC0, 0x89, 0xC1, /* 0xFC-0xFF */
};
-static unsigned char u2c_B4[512] = {
+static const unsigned char u2c_B4[512] = {
0x89, 0xC2, 0x89, 0xC3, 0x89, 0xC4, 0x89, 0xC5, /* 0x00-0x03 */
0x89, 0xC6, 0x89, 0xC7, 0x89, 0xC8, 0x89, 0xC9, /* 0x04-0x07 */
0x89, 0xCA, 0x89, 0xCB, 0x89, 0xCC, 0x89, 0xCD, /* 0x08-0x0B */
@@ -11246,7 +11246,7 @@ static unsigned char u2c_B4[512] = {
0x8A, 0xE2, 0x8A, 0xE3, 0x8A, 0xE4, 0x8A, 0xE5, /* 0xFC-0xFF */
};
-static unsigned char u2c_B5[512] = {
+static const unsigned char u2c_B5[512] = {
0x8A, 0xE6, 0x8A, 0xE7, 0x8A, 0xE8, 0x8A, 0xE9, /* 0x00-0x03 */
0x8A, 0xEA, 0x8A, 0xEB, 0x8A, 0xEC, 0x8A, 0xED, /* 0x04-0x07 */
0x8A, 0xEE, 0x8A, 0xEF, 0x8A, 0xF0, 0x8A, 0xF1, /* 0x08-0x0B */
@@ -11314,7 +11314,7 @@ static unsigned char u2c_B5[512] = {
0x8B, 0xFB, 0x8B, 0xFC, 0x8B, 0xFD, 0x8B, 0xFE, /* 0xFC-0xFF */
};
-static unsigned char u2c_B6[512] = {
+static const unsigned char u2c_B6[512] = {
0x8C, 0x41, 0x8C, 0x42, 0x8C, 0x43, 0x8C, 0x44, /* 0x00-0x03 */
0x8C, 0x45, 0x8C, 0x46, 0x8C, 0x47, 0x8C, 0x48, /* 0x04-0x07 */
0x8C, 0x49, 0x8C, 0x4A, 0x8C, 0x4B, 0x8C, 0x4C, /* 0x08-0x0B */
@@ -11382,7 +11382,7 @@ static unsigned char u2c_B6[512] = {
0x8D, 0x82, 0x8D, 0x83, 0x8D, 0x84, 0x8D, 0x85, /* 0xFC-0xFF */
};
-static unsigned char u2c_B7[512] = {
+static const unsigned char u2c_B7[512] = {
0xB6, 0xDC, 0xB6, 0xDD, 0x8D, 0x86, 0x8D, 0x87, /* 0x00-0x03 */
0x8D, 0x88, 0xB6, 0xDE, 0x8D, 0x89, 0x8D, 0x8A, /* 0x04-0x07 */
0x8D, 0x8B, 0x8D, 0x8C, 0x8D, 0x8D, 0x8D, 0x8E, /* 0x08-0x0B */
@@ -11450,7 +11450,7 @@ static unsigned char u2c_B7[512] = {
0xB7, 0xB3, 0xB7, 0xB4, 0x8E, 0x9B, 0xB7, 0xB5, /* 0xFC-0xFF */
};
-static unsigned char u2c_B8[512] = {
+static const unsigned char u2c_B8[512] = {
0xB7, 0xB6, 0xB7, 0xB7, 0x8E, 0x9C, 0x8E, 0x9D, /* 0x00-0x03 */
0x8E, 0x9E, 0x8E, 0x9F, 0x8E, 0xA0, 0xB7, 0xB8, /* 0x04-0x07 */
0xB7, 0xB9, 0xB7, 0xBA, 0x8E, 0xA1, 0x8E, 0xA2, /* 0x08-0x0B */
@@ -11518,7 +11518,7 @@ static unsigned char u2c_B8[512] = {
0x8F, 0xAE, 0xB7, 0xEE, 0x8F, 0xAF, 0x8F, 0xB0, /* 0xFC-0xFF */
};
-static unsigned char u2c_B9[512] = {
+static const unsigned char u2c_B9[512] = {
0x8F, 0xB1, 0x8F, 0xB2, 0x8F, 0xB3, 0x8F, 0xB4, /* 0x00-0x03 */
0xB7, 0xEF, 0x8F, 0xB5, 0x8F, 0xB6, 0x8F, 0xB7, /* 0x04-0x07 */
0x8F, 0xB8, 0x8F, 0xB9, 0x8F, 0xBA, 0x8F, 0xBB, /* 0x08-0x0B */
@@ -11586,7 +11586,7 @@ static unsigned char u2c_B9[512] = {
0x90, 0xBD, 0x90, 0xBE, 0x90, 0xBF, 0x90, 0xC0, /* 0xFC-0xFF */
};
-static unsigned char u2c_BA[512] = {
+static const unsigned char u2c_BA[512] = {
0xB8, 0xCF, 0xB8, 0xD0, 0x90, 0xC1, 0x90, 0xC2, /* 0x00-0x03 */
0x90, 0xC3, 0x90, 0xC4, 0x90, 0xC5, 0x90, 0xC6, /* 0x04-0x07 */
0xB8, 0xD1, 0x90, 0xC7, 0x90, 0xC8, 0x90, 0xC9, /* 0x08-0x0B */
@@ -11654,7 +11654,7 @@ static unsigned char u2c_BA[512] = {
0xB8, 0xFE, 0x91, 0xDC, 0x91, 0xDD, 0x91, 0xDE, /* 0xFC-0xFF */
};
-static unsigned char u2c_BB[512] = {
+static const unsigned char u2c_BB[512] = {
0xB9, 0xA1, 0x91, 0xDF, 0x91, 0xE0, 0x91, 0xE1, /* 0x00-0x03 */
0xB9, 0xA2, 0x91, 0xE2, 0x91, 0xE3, 0x91, 0xE4, /* 0x04-0x07 */
0x91, 0xE5, 0x91, 0xE6, 0x91, 0xE7, 0x91, 0xE8, /* 0x08-0x0B */
@@ -11722,7 +11722,7 @@ static unsigned char u2c_BB[512] = {
0xB9, 0xCE, 0x92, 0xFC, 0x92, 0xFD, 0xB9, 0xCF, /* 0xFC-0xFF */
};
-static unsigned char u2c_BC[512] = {
+static const unsigned char u2c_BC[512] = {
0xB9, 0xD0, 0x92, 0xFE, 0xB9, 0xD1, 0x93, 0x41, /* 0x00-0x03 */
0x93, 0x42, 0x93, 0x43, 0x93, 0x44, 0x93, 0x45, /* 0x04-0x07 */
0xB9, 0xD2, 0xB9, 0xD3, 0x93, 0x46, 0xB9, 0xD4, /* 0x08-0x0B */
@@ -11790,7 +11790,7 @@ static unsigned char u2c_BC[512] = {
0xBA, 0xBC, 0x93, 0xFE, 0x94, 0x41, 0x94, 0x42, /* 0xFC-0xFF */
};
-static unsigned char u2c_BD[512] = {
+static const unsigned char u2c_BD[512] = {
0x94, 0x43, 0x94, 0x44, 0x94, 0x45, 0x94, 0x46, /* 0x00-0x03 */
0xBA, 0xBD, 0xBA, 0xBE, 0x94, 0x47, 0xBA, 0xBF, /* 0x04-0x07 */
0x94, 0x48, 0xBA, 0xC0, 0x94, 0x49, 0x94, 0x4A, /* 0x08-0x0B */
@@ -11858,7 +11858,7 @@ static unsigned char u2c_BD[512] = {
0x95, 0x69, 0x95, 0x6A, 0x95, 0x6B, 0x95, 0x6C, /* 0xFC-0xFF */
};
-static unsigned char u2c_BE[512] = {
+static const unsigned char u2c_BE[512] = {
0xBA, 0xE7, 0x95, 0x6D, 0x95, 0x6E, 0xBA, 0xE8, /* 0x00-0x03 */
0x95, 0x6F, 0xBA, 0xE9, 0x95, 0x70, 0x95, 0x71, /* 0x04-0x07 */
0x95, 0x72, 0x95, 0x73, 0x95, 0x74, 0x95, 0x75, /* 0x08-0x0B */
@@ -11926,7 +11926,7 @@ static unsigned char u2c_BE[512] = {
0x96, 0x87, 0x96, 0x88, 0x96, 0x89, 0x96, 0x8A, /* 0xFC-0xFF */
};
-static unsigned char u2c_BF[512] = {
+static const unsigned char u2c_BF[512] = {
0x96, 0x8B, 0xBB, 0xBF, 0x96, 0x8C, 0x96, 0x8D, /* 0x00-0x03 */
0x96, 0x8E, 0x96, 0x8F, 0x96, 0x90, 0x96, 0x91, /* 0x04-0x07 */
0xBB, 0xC0, 0xBB, 0xC1, 0x96, 0x92, 0x96, 0x93, /* 0x08-0x0B */
@@ -11994,7 +11994,7 @@ static unsigned char u2c_BF[512] = {
0x97, 0xBC, 0x97, 0xBD, 0x97, 0xBE, 0x97, 0xBF, /* 0xFC-0xFF */
};
-static unsigned char u2c_C0[512] = {
+static const unsigned char u2c_C0[512] = {
0x97, 0xC0, 0x97, 0xC1, 0x97, 0xC2, 0x97, 0xC3, /* 0x00-0x03 */
0x97, 0xC4, 0x97, 0xC5, 0x97, 0xC6, 0x97, 0xC7, /* 0x04-0x07 */
0x97, 0xC8, 0x97, 0xC9, 0x97, 0xCA, 0x97, 0xCB, /* 0x08-0x0B */
@@ -12062,7 +12062,7 @@ static unsigned char u2c_C0[512] = {
0x98, 0xDC, 0x98, 0xDD, 0x98, 0xDE, 0x98, 0xDF, /* 0xFC-0xFF */
};
-static unsigned char u2c_C1[512] = {
+static const unsigned char u2c_C1[512] = {
0xBC, 0xA8, 0x98, 0xE0, 0x98, 0xE1, 0x98, 0xE2, /* 0x00-0x03 */
0xBC, 0xA9, 0x98, 0xE3, 0x98, 0xE4, 0x98, 0xE5, /* 0x04-0x07 */
0xBC, 0xAA, 0x98, 0xE6, 0x98, 0xE7, 0x98, 0xE8, /* 0x08-0x0B */
@@ -12130,7 +12130,7 @@ static unsigned char u2c_C1[512] = {
0xBC, 0xEE, 0xBC, 0xEF, 0x99, 0xE4, 0x99, 0xE5, /* 0xFC-0xFF */
};
-static unsigned char u2c_C2[512] = {
+static const unsigned char u2c_C2[512] = {
0xBC, 0xF0, 0x99, 0xE6, 0x99, 0xE7, 0x99, 0xE8, /* 0x00-0x03 */
0xBC, 0xF1, 0x99, 0xE9, 0x99, 0xEA, 0x99, 0xEB, /* 0x04-0x07 */
0x99, 0xEC, 0x99, 0xED, 0x99, 0xEE, 0x99, 0xEF, /* 0x08-0x0B */
@@ -12198,7 +12198,7 @@ static unsigned char u2c_C2[512] = {
0xBD, 0xD1, 0x9A, 0xF1, 0x9A, 0xF2, 0x9A, 0xF3, /* 0xFC-0xFF */
};
-static unsigned char u2c_C3[512] = {
+static const unsigned char u2c_C3[512] = {
0xBD, 0xD2, 0x9A, 0xF4, 0x9A, 0xF5, 0x9A, 0xF6, /* 0x00-0x03 */
0x9A, 0xF7, 0x9A, 0xF8, 0x9A, 0xF9, 0x9A, 0xFA, /* 0x04-0x07 */
0xBD, 0xD3, 0xBD, 0xD4, 0x9A, 0xFB, 0x9A, 0xFC, /* 0x08-0x0B */
@@ -12266,7 +12266,7 @@ static unsigned char u2c_C3[512] = {
0x9C, 0x58, 0x9C, 0x59, 0x9C, 0x5A, 0x9C, 0x61, /* 0xFC-0xFF */
};
-static unsigned char u2c_C4[512] = {
+static const unsigned char u2c_C4[512] = {
0x9C, 0x62, 0x9C, 0x63, 0x9C, 0x64, 0x9C, 0x65, /* 0x00-0x03 */
0x9C, 0x66, 0x9C, 0x67, 0x9C, 0x68, 0x9C, 0x69, /* 0x04-0x07 */
0xBD, 0xFA, 0x9C, 0x6A, 0x9C, 0x6B, 0x9C, 0x6C, /* 0x08-0x0B */
@@ -12334,7 +12334,7 @@ static unsigned char u2c_C4[512] = {
0x9D, 0x97, 0x9D, 0x98, 0x9D, 0x99, 0xBE, 0xB7, /* 0xFC-0xFF */
};
-static unsigned char u2c_C5[512] = {
+static const unsigned char u2c_C5[512] = {
0xBE, 0xB8, 0xBE, 0xB9, 0x9D, 0x9A, 0x9D, 0x9B, /* 0x00-0x03 */
0x9D, 0x9C, 0x9D, 0x9D, 0x9D, 0x9E, 0x9D, 0x9F, /* 0x04-0x07 */
0x9D, 0xA0, 0x9D, 0xA1, 0x9D, 0xA2, 0x9D, 0xA3, /* 0x08-0x0B */
@@ -12402,7 +12402,7 @@ static unsigned char u2c_C5[512] = {
0xBF, 0xB0, 0xBF, 0xB1, 0xBF, 0xB2, 0xBF, 0xB3, /* 0xFC-0xFF */
};
-static unsigned char u2c_C6[512] = {
+static const unsigned char u2c_C6[512] = {
0xBF, 0xB4, 0xBF, 0xB5, 0x9E, 0x8E, 0x9E, 0x8F, /* 0x00-0x03 */
0x9E, 0x90, 0xBF, 0xB6, 0xBF, 0xB7, 0xBF, 0xB8, /* 0x04-0x07 */
0xBF, 0xB9, 0x9E, 0x91, 0x9E, 0x92, 0x9E, 0x93, /* 0x08-0x0B */
@@ -12470,7 +12470,7 @@ static unsigned char u2c_C6[512] = {
0x9F, 0x88, 0xC0, 0xA6, 0x9F, 0x89, 0x9F, 0x8A, /* 0xFC-0xFF */
};
-static unsigned char u2c_C7[512] = {
+static const unsigned char u2c_C7[512] = {
0x9F, 0x8B, 0x9F, 0x8C, 0x9F, 0x8D, 0x9F, 0x8E, /* 0x00-0x03 */
0xC0, 0xA7, 0xC0, 0xA8, 0x9F, 0x8F, 0x9F, 0x90, /* 0x04-0x07 */
0xC0, 0xA9, 0x9F, 0x91, 0x9F, 0x92, 0x9F, 0x93, /* 0x08-0x0B */
@@ -12538,7 +12538,7 @@ static unsigned char u2c_C7[512] = {
0xA0, 0x82, 0xA0, 0x83, 0xA0, 0x84, 0xA0, 0x85, /* 0xFC-0xFF */
};
-static unsigned char u2c_C8[512] = {
+static const unsigned char u2c_C8[512] = {
0xC0, 0xFA, 0xC0, 0xFB, 0xA0, 0x86, 0xA0, 0x87, /* 0x00-0x03 */
0xC0, 0xFC, 0xA0, 0x88, 0xA0, 0x89, 0xA0, 0x8A, /* 0x04-0x07 */
0xC0, 0xFD, 0xA0, 0x8B, 0xC0, 0xFE, 0xA0, 0x8C, /* 0x08-0x0B */
@@ -12606,7 +12606,7 @@ static unsigned char u2c_C8[512] = {
0xC1, 0xD6, 0xC1, 0xD7, 0xA1, 0x96, 0xA1, 0x97, /* 0xFC-0xFF */
};
-static unsigned char u2c_C9[512] = {
+static const unsigned char u2c_C9[512] = {
0xC1, 0xD8, 0xA1, 0x98, 0xA1, 0x99, 0xA1, 0x9A, /* 0x00-0x03 */
0xC1, 0xD9, 0xC1, 0xDA, 0xC1, 0xDB, 0xA1, 0x9B, /* 0x04-0x07 */
0xA1, 0x9C, 0xA1, 0x9D, 0xA1, 0x9E, 0xA1, 0x9F, /* 0x08-0x0B */
@@ -12674,7 +12674,7 @@ static unsigned char u2c_C9[512] = {
0xC2, 0xB2, 0xA4, 0x54, 0xA4, 0x55, 0xA4, 0x56, /* 0xFC-0xFF */
};
-static unsigned char u2c_CA[512] = {
+static const unsigned char u2c_CA[512] = {
0xC2, 0xB3, 0xA4, 0x57, 0xA4, 0x58, 0xA4, 0x59, /* 0x00-0x03 */
0xA4, 0x5A, 0xA4, 0x61, 0xA4, 0x62, 0xA4, 0x63, /* 0x04-0x07 */
0xC2, 0xB4, 0xC2, 0xB5, 0xA4, 0x64, 0xC2, 0xB6, /* 0x08-0x0B */
@@ -12742,7 +12742,7 @@ static unsigned char u2c_CA[512] = {
0xA6, 0x93, 0xA6, 0x94, 0xA6, 0x95, 0xA6, 0x96, /* 0xFC-0xFF */
};
-static unsigned char u2c_CB[512] = {
+static const unsigned char u2c_CB[512] = {
0xA6, 0x97, 0xA6, 0x98, 0xA6, 0x99, 0xA6, 0x9A, /* 0x00-0x03 */
0xA6, 0x9B, 0xA6, 0x9C, 0xA6, 0x9D, 0xA6, 0x9E, /* 0x04-0x07 */
0xC2, 0xD7, 0xA6, 0x9F, 0xA6, 0xA0, 0xA7, 0x41, /* 0x08-0x0B */
@@ -12810,7 +12810,7 @@ static unsigned char u2c_CB[512] = {
0xA9, 0x7A, 0xA9, 0x81, 0xA9, 0x82, 0xA9, 0x83, /* 0xFC-0xFF */
};
-static unsigned char u2c_CC[512] = {
+static const unsigned char u2c_CC[512] = {
0xA9, 0x84, 0xA9, 0x85, 0xA9, 0x86, 0xA9, 0x87, /* 0x00-0x03 */
0xA9, 0x88, 0xA9, 0x89, 0xA9, 0x8A, 0xA9, 0x8B, /* 0x04-0x07 */
0xA9, 0x8C, 0xA9, 0x8D, 0xA9, 0x8E, 0xA9, 0x8F, /* 0x08-0x0B */
@@ -12878,7 +12878,7 @@ static unsigned char u2c_CC[512] = {
0xAB, 0x9F, 0xAB, 0xA0, 0xAC, 0x41, 0xAC, 0x42, /* 0xFC-0xFF */
};
-static unsigned char u2c_CD[512] = {
+static const unsigned char u2c_CD[512] = {
0xAC, 0x43, 0xC3, 0xC9, 0xAC, 0x44, 0xAC, 0x45, /* 0x00-0x03 */
0xAC, 0x46, 0xAC, 0x47, 0xAC, 0x48, 0xAC, 0x49, /* 0x04-0x07 */
0xC3, 0xCA, 0xC3, 0xCB, 0xAC, 0x4A, 0xAC, 0x4B, /* 0x08-0x0B */
@@ -12946,7 +12946,7 @@ static unsigned char u2c_CD[512] = {
0xAE, 0x75, 0xC3, 0xF1, 0xAE, 0x76, 0xAE, 0x77, /* 0xFC-0xFF */
};
-static unsigned char u2c_CE[512] = {
+static const unsigned char u2c_CE[512] = {
0xAE, 0x78, 0xAE, 0x79, 0xAE, 0x7A, 0xAE, 0x81, /* 0x00-0x03 */
0xC3, 0xF2, 0xAE, 0x82, 0xAE, 0x83, 0xAE, 0x84, /* 0x04-0x07 */
0xC3, 0xF3, 0xAE, 0x85, 0xAE, 0x86, 0xAE, 0x87, /* 0x08-0x0B */
@@ -13014,7 +13014,7 @@ static unsigned char u2c_CE[512] = {
0xB0, 0x9D, 0xB0, 0x9E, 0xB0, 0x9F, 0xB0, 0xA0, /* 0xFC-0xFF */
};
-static unsigned char u2c_CF[512] = {
+static const unsigned char u2c_CF[512] = {
0xC4, 0xC9, 0xC4, 0xCA, 0xB1, 0x41, 0xB1, 0x42, /* 0x00-0x03 */
0xC4, 0xCB, 0xB1, 0x43, 0xB1, 0x44, 0xB1, 0x45, /* 0x04-0x07 */
0xC4, 0xCC, 0xB1, 0x46, 0xB1, 0x47, 0xB1, 0x48, /* 0x08-0x0B */
@@ -13082,7 +13082,7 @@ static unsigned char u2c_CF[512] = {
0xC4, 0xF5, 0xB3, 0x6F, 0xB3, 0x70, 0xB3, 0x71, /* 0xFC-0xFF */
};
-static unsigned char u2c_D0[512] = {
+static const unsigned char u2c_D0[512] = {
0xC4, 0xF6, 0xB3, 0x72, 0xB3, 0x73, 0xB3, 0x74, /* 0x00-0x03 */
0xC4, 0xF7, 0xB3, 0x75, 0xB3, 0x76, 0xB3, 0x77, /* 0x04-0x07 */
0xB3, 0x78, 0xB3, 0x79, 0xB3, 0x7A, 0xB3, 0x81, /* 0x08-0x0B */
@@ -13150,7 +13150,7 @@ static unsigned char u2c_D0[512] = {
0xB5, 0x98, 0xB5, 0x99, 0xB5, 0x9A, 0xB5, 0x9B, /* 0xFC-0xFF */
};
-static unsigned char u2c_D1[512] = {
+static const unsigned char u2c_D1[512] = {
0xB5, 0x9C, 0xB5, 0x9D, 0xB5, 0x9E, 0xB5, 0x9F, /* 0x00-0x03 */
0xB5, 0xA0, 0xB6, 0x41, 0xB6, 0x42, 0xB6, 0x43, /* 0x04-0x07 */
0xB6, 0x44, 0xB6, 0x45, 0xB6, 0x46, 0xB6, 0x47, /* 0x08-0x0B */
@@ -13218,7 +13218,7 @@ static unsigned char u2c_D1[512] = {
0xB8, 0x70, 0xB8, 0x71, 0xB8, 0x72, 0xB8, 0x73, /* 0xFC-0xFF */
};
-static unsigned char u2c_D2[512] = {
+static const unsigned char u2c_D2[512] = {
0xB8, 0x74, 0xB8, 0x75, 0xB8, 0x76, 0xB8, 0x77, /* 0x00-0x03 */
0xB8, 0x78, 0xB8, 0x79, 0xB8, 0x7A, 0xC5, 0xF2, /* 0x04-0x07 */
0xB8, 0x81, 0xC5, 0xF3, 0xB8, 0x82, 0xB8, 0x83, /* 0x08-0x0B */
@@ -13286,7 +13286,7 @@ static unsigned char u2c_D2[512] = {
0xBB, 0x42, 0xBB, 0x43, 0xBB, 0x44, 0xBB, 0x45, /* 0xFC-0xFF */
};
-static unsigned char u2c_D3[512] = {
+static const unsigned char u2c_D3[512] = {
0xC6, 0xC0, 0xC6, 0xC1, 0xBB, 0x46, 0xC6, 0xC2, /* 0x00-0x03 */
0xBB, 0x47, 0xC6, 0xC3, 0xBB, 0x48, 0xBB, 0x49, /* 0x04-0x07 */
0xBB, 0x4A, 0xBB, 0x4B, 0xBB, 0x4C, 0xBB, 0x4D, /* 0x08-0x0B */
@@ -13354,7 +13354,7 @@ static unsigned char u2c_D3[512] = {
0xC6, 0xFB, 0xC6, 0xFC, 0xBD, 0x65, 0xC6, 0xFD, /* 0xFC-0xFF */
};
-static unsigned char u2c_D4[512] = {
+static const unsigned char u2c_D4[512] = {
0xBD, 0x66, 0xC6, 0xFE, 0xBD, 0x67, 0xBD, 0x68, /* 0x00-0x03 */
0xBD, 0x69, 0xBD, 0x6A, 0xBD, 0x6B, 0xBD, 0x6C, /* 0x04-0x07 */
0xC7, 0xA1, 0xBD, 0x6D, 0xBD, 0x6E, 0xBD, 0x6F, /* 0x08-0x0B */
@@ -13422,7 +13422,7 @@ static unsigned char u2c_D4[512] = {
0xBF, 0xA0, 0xC7, 0xC0, 0xC0, 0x41, 0xC0, 0x42, /* 0xFC-0xFF */
};
-static unsigned char u2c_D5[512] = {
+static const unsigned char u2c_D5[512] = {
0xC0, 0x43, 0xC0, 0x44, 0xC0, 0x45, 0xC0, 0x46, /* 0x00-0x03 */
0xC7, 0xC1, 0xC0, 0x47, 0xC0, 0x48, 0xC0, 0x49, /* 0x04-0x07 */
0xC7, 0xC2, 0xC0, 0x4A, 0xC0, 0x4B, 0xC0, 0x4C, /* 0x08-0x0B */
@@ -13490,7 +13490,7 @@ static unsigned char u2c_D5[512] = {
0xC2, 0x6A, 0xC2, 0x6B, 0xC2, 0x6C, 0xC2, 0x6D, /* 0xFC-0xFF */
};
-static unsigned char u2c_D6[512] = {
+static const unsigned char u2c_D6[512] = {
0xC7, 0xF4, 0xC7, 0xF5, 0xC2, 0x6E, 0xC2, 0x6F, /* 0x00-0x03 */
0xC7, 0xF6, 0xC2, 0x70, 0xC2, 0x71, 0xC2, 0x72, /* 0x04-0x07 */
0xC7, 0xF7, 0xC2, 0x73, 0xC2, 0x74, 0xC2, 0x75, /* 0x08-0x0B */
@@ -13558,7 +13558,7 @@ static unsigned char u2c_D6[512] = {
0xC8, 0xD1, 0xC8, 0xD2, 0xC4, 0x8D, 0xC4, 0x8E, /* 0xFC-0xFF */
};
-static unsigned char u2c_D7[512] = {
+static const unsigned char u2c_D7[512] = {
0xC8, 0xD3, 0xC4, 0x8F, 0xC4, 0x90, 0xC4, 0x91, /* 0x00-0x03 */
0xC8, 0xD4, 0xC4, 0x92, 0xC4, 0x93, 0xC4, 0x94, /* 0x04-0x07 */
0xC4, 0x95, 0xC4, 0x96, 0xC4, 0x97, 0xC4, 0x98, /* 0x08-0x0B */
@@ -13603,11 +13603,11 @@ static unsigned char u2c_D7[512] = {
0xC6, 0x4F, 0xC6, 0x50, 0xC6, 0x51, 0xC6, 0x52, /* 0xA0-0xA3 */
};
-static unsigned char u2c_DC[512] = {
+static const unsigned char u2c_DC[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
};
-static unsigned char u2c_F9[512] = {
+static const unsigned char u2c_F9[512] = {
0xCB, 0xD0, 0xCB, 0xD6, 0xCB, 0xE7, 0xCD, 0xCF, /* 0x00-0x03 */
0xCD, 0xE8, 0xCE, 0xAD, 0xCF, 0xFB, 0xD0, 0xA2, /* 0x04-0x07 */
0xD0, 0xB8, 0xD0, 0xD0, 0xD0, 0xDD, 0xD1, 0xD4, /* 0x08-0x0B */
@@ -13675,7 +13675,7 @@ static unsigned char u2c_F9[512] = {
0xF2, 0xBD, 0xF2, 0xFA, 0xF3, 0xB1, 0xF4, 0xA7, /* 0xFC-0xFF */
};
-static unsigned char u2c_FA[512] = {
+static const unsigned char u2c_FA[512] = {
0xF4, 0xEE, 0xF6, 0xF4, 0xF6, 0xF6, 0xF7, 0xB8, /* 0x00-0x03 */
0xF7, 0xC8, 0xF7, 0xD3, 0xF8, 0xDB, 0xF8, 0xF0, /* 0x04-0x07 */
0xFA, 0xA1, 0xFA, 0xA2, 0xFA, 0xE6, 0xFC, 0xA9, /* 0x08-0x0B */
@@ -13690,7 +13690,7 @@ static unsigned char u2c_FA[512] = {
0xCE, 0xBD, 0xF9, 0xCD, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */
};
-static unsigned char u2c_FF[512] = {
+static const unsigned char u2c_FF[512] = {
0x00, 0x00, 0xA3, 0xA1, 0xA3, 0xA2, 0xA3, 0xA3, /* 0x00-0x03 */
0xA3, 0xA4, 0xA3, 0xA5, 0xA3, 0xA6, 0xA3, 0xA7, /* 0x04-0x07 */
0xA3, 0xA8, 0xA3, 0xA9, 0xA3, 0xAA, 0xA3, 0xAB, /* 0x08-0x0B */
@@ -13752,7 +13752,7 @@ static unsigned char u2c_FF[512] = {
0x00, 0x00, 0xA1, 0xCD, 0xA3, 0xDC, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
NULL, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, u2c_11, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -13786,7 +13786,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, u2c_F9, u2c_FA, NULL, NULL, NULL, NULL, u2c_FF, };
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -13822,7 +13822,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -13861,7 +13861,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(const wchar_t uni,
unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni&0xFF;
unsigned char ch = (uni>>8)&0xFF;
int n;
@@ -13893,7 +13893,7 @@ static int char2uni(const unsigned char *rawstring, int boundlen,
wchar_t *uni)
{
unsigned char ch, cl;
- wchar_t *charset2uni;
+ const wchar_t *charset2uni;
int n;
if (boundlen <= 0)
diff --git a/fs/nls/nls_cp950.c b/fs/nls/nls_cp950.c
index 5665945fb88..ef2536829aa 100644
--- a/fs/nls/nls_cp950.c
+++ b/fs/nls/nls_cp950.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t c2u_A1[256] = {
+static const wchar_t c2u_A1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -49,7 +49,7 @@ static wchar_t c2u_A1[256] = {
0x2196,0x2197,0x2199,0x2198,0x2225,0x2223,0xFF0F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A2[256] = {
+static const wchar_t c2u_A2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -85,7 +85,7 @@ static wchar_t c2u_A2[256] = {
0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A3[256] = {
+static const wchar_t c2u_A3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -118,7 +118,7 @@ static wchar_t c2u_A3[256] = {
0x0000,0x20AC,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0xE0-0xE7 */
};
-static wchar_t c2u_A4[256] = {
+static const wchar_t c2u_A4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -154,7 +154,7 @@ static wchar_t c2u_A4[256] = {
0x723B,0x7247,0x7259,0x725B,0x72AC,0x738B,0x4E19,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A5[256] = {
+static const wchar_t c2u_A5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -190,7 +190,7 @@ static wchar_t c2u_A5[256] = {
0x4F01,0x4F0B,0x5149,0x5147,0x5146,0x5148,0x5168,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A6[256] = {
+static const wchar_t c2u_A6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -226,7 +226,7 @@ static wchar_t c2u_A6[256] = {
0x4F3A,0x4F38,0x4F43,0x4F54,0x4F3C,0x4F46,0x4F63,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A7[256] = {
+static const wchar_t c2u_A7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -262,7 +262,7 @@ static wchar_t c2u_A7[256] = {
0x6751,0x675C,0x6756,0x675E,0x6749,0x6746,0x6760,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A8[256] = {
+static const wchar_t c2u_A8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -298,7 +298,7 @@ static wchar_t c2u_A8[256] = {
0x5378,0x5379,0x53D6,0x53D4,0x53D7,0x5473,0x5475,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_A9[256] = {
+static const wchar_t c2u_A9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -334,7 +334,7 @@ static wchar_t c2u_A9[256] = {
0x6606,0x6602,0x660E,0x6600,0x660F,0x6615,0x660A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AA[256] = {
+static const wchar_t c2u_AA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -370,7 +370,7 @@ static wchar_t c2u_AA[256] = {
0x9577,0x9580,0x961C,0x9640,0x963F,0x963B,0x9644,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AB[256] = {
+static const wchar_t c2u_AB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -406,7 +406,7 @@ static wchar_t c2u_AB[256] = {
0x62ED,0x6301,0x62EE,0x62FD,0x6307,0x62F1,0x62F7,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AC[256] = {
+static const wchar_t c2u_AC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -442,7 +442,7 @@ static wchar_t c2u_AC[256] = {
0x7D07,0x7D04,0x7D06,0x7F38,0x7F8E,0x7FBF,0x8004,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AD[256] = {
+static const wchar_t c2u_AD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -478,7 +478,7 @@ static wchar_t c2u_AD[256] = {
0x5514,0x54E9,0x54ED,0x54E1,0x5509,0x54EE,0x54EA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AE[256] = {
+static const wchar_t c2u_AE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -514,7 +514,7 @@ static wchar_t c2u_AE[256] = {
0x6D88,0x6D87,0x6D66,0x6D78,0x6D77,0x6D59,0x6D93,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_AF[256] = {
+static const wchar_t c2u_AF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -550,7 +550,7 @@ static wchar_t c2u_AF[256] = {
0x8339,0x8336,0x8317,0x8340,0x8331,0x8328,0x8343,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B0[256] = {
+static const wchar_t c2u_B0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -586,7 +586,7 @@ static wchar_t c2u_B0[256] = {
0x5962,0x5A36,0x5A41,0x5A49,0x5A66,0x5A6A,0x5A40,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B1[256] = {
+static const wchar_t c2u_B1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -622,7 +622,7 @@ static wchar_t c2u_B1[256] = {
0x689D,0x68A8,0x689F,0x68A1,0x6882,0x6B32,0x6BBA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B2[256] = {
+static const wchar_t c2u_B2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -658,7 +658,7 @@ static wchar_t c2u_B2[256] = {
0x838A,0x8393,0x8389,0x83A0,0x8377,0x837B,0x837C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B3[256] = {
+static const wchar_t c2u_B3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -694,7 +694,7 @@ static wchar_t c2u_B3[256] = {
0x5831,0x5821,0x581D,0x5820,0x58F9,0x58FA,0x5960,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B4[256] = {
+static const wchar_t c2u_B4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -730,7 +730,7 @@ static wchar_t c2u_B4[256] = {
0x6E4D,0x6E3A,0x6E2C,0x6E43,0x6E1D,0x6E3E,0x6ECB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B5[256] = {
+static const wchar_t c2u_B5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -766,7 +766,7 @@ static wchar_t c2u_B5[256] = {
0x8996,0x8A3B,0x8A60,0x8A55,0x8A5E,0x8A3C,0x8A41,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B6[256] = {
+static const wchar_t c2u_B6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -802,7 +802,7 @@ static wchar_t c2u_B6[256] = {
0x5967,0x5AC1,0x5AC9,0x5ACC,0x5ABE,0x5ABD,0x5ABC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B7[256] = {
+static const wchar_t c2u_B7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -838,7 +838,7 @@ static wchar_t c2u_B7[256] = {
0x76DE,0x76DF,0x775B,0x776B,0x7766,0x775E,0x7763,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B8[256] = {
+static const wchar_t c2u_B8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -874,7 +874,7 @@ static wchar_t c2u_B8[256] = {
0x8DE4,0x8DE6,0x8EB2,0x8F03,0x8F09,0x8EFE,0x8F0A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_B9[256] = {
+static const wchar_t c2u_B9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -910,7 +910,7 @@ static wchar_t c2u_B9[256] = {
0x5ED3,0x5ED6,0x5F0A,0x5F46,0x5F70,0x5FB9,0x6147,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BA[256] = {
+static const wchar_t c2u_BA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -946,7 +946,7 @@ static wchar_t c2u_BA[256] = {
0x7DBF,0x7DB5,0x7DB8,0x7DAD,0x7DD2,0x7DC7,0x7DAC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BB[256] = {
+static const wchar_t c2u_BB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -982,7 +982,7 @@ static wchar_t c2u_BB[256] = {
0x50F5,0x50F9,0x5102,0x5108,0x5109,0x5105,0x51DC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BC[256] = {
+static const wchar_t c2u_BC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1018,7 +1018,7 @@ static wchar_t c2u_BC[256] = {
0x7256,0x729B,0x734E,0x7357,0x7469,0x748B,0x7483,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BD[256] = {
+static const wchar_t c2u_BD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1054,7 +1054,7 @@ static wchar_t c2u_BD[256] = {
0x8F1B,0x8F1F,0x8F29,0x8F26,0x8F2A,0x8F1C,0x8F1E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BE[256] = {
+static const wchar_t c2u_BE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1090,7 +1090,7 @@ static wchar_t c2u_BE[256] = {
0x6A48,0x6B59,0x6B77,0x6C05,0x6FC2,0x6FB1,0x6FA1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_BF[256] = {
+static const wchar_t c2u_BF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1126,7 +1126,7 @@ static wchar_t c2u_BF[256] = {
0x9333,0x932F,0x9322,0x92FC,0x932B,0x9304,0x931A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C0[256] = {
+static const wchar_t c2u_C0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1162,7 +1162,7 @@ static wchar_t c2u_C0[256] = {
0x7642,0x764C,0x76EA,0x77B3,0x77AA,0x77B0,0x77AC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C1[256] = {
+static const wchar_t c2u_C1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1198,7 +1198,7 @@ static wchar_t c2u_C1[256] = {
0x971E,0x97A0,0x97D3,0x9846,0x98B6,0x9935,0x9A01,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C2[256] = {
+static const wchar_t c2u_C2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1234,7 +1234,7 @@ static wchar_t c2u_C2[256] = {
0x96DC,0x96D9,0x96DB,0x96DE,0x9724,0x97A3,0x97A6,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C3[256] = {
+static const wchar_t c2u_C3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1270,7 +1270,7 @@ static wchar_t c2u_C3[256] = {
0x96E3,0x972A,0x9727,0x9761,0x97DC,0x97FB,0x985E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C4[256] = {
+static const wchar_t c2u_C4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1306,7 +1306,7 @@ static wchar_t c2u_C4[256] = {
0x8822,0x8821,0x881F,0x896A,0x896C,0x89BD,0x8B74,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C5[256] = {
+static const wchar_t c2u_C5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1342,7 +1342,7 @@ static wchar_t c2u_C5[256] = {
0x7F50,0x7F88,0x8836,0x8839,0x8862,0x8B93,0x8B92,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_C6[256] = {
+static const wchar_t c2u_C6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1361,7 +1361,7 @@ static wchar_t c2u_C6[256] = {
0x9E1A,0x7228,0x9A6A,0x9B31,0x9E1B,0x9E1E,0x7C72,0x0000,/* 0x78-0x7F */
};
-static wchar_t c2u_C9[256] = {
+static const wchar_t c2u_C9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1397,7 +1397,7 @@ static wchar_t c2u_C9[256] = {
0x6C46,0x6C52,0x6C5C,0x6C4F,0x6C4A,0x6C54,0x6C4B,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CA[256] = {
+static const wchar_t c2u_CA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1433,7 +1433,7 @@ static wchar_t c2u_CA[256] = {
0x65F0,0x65F4,0x65F3,0x65F2,0x65F5,0x6745,0x6747,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CB[256] = {
+static const wchar_t c2u_CB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1469,7 +1469,7 @@ static wchar_t c2u_CB[256] = {
0x5776,0x5780,0x5775,0x577B,0x5773,0x5774,0x5762,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CC[256] = {
+static const wchar_t c2u_CC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1505,7 +1505,7 @@ static wchar_t c2u_CC[256] = {
0x6CD0,0x6CC2,0x6CBA,0x6CC3,0x6CC6,0x6CED,0x6CF2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CD[256] = {
+static const wchar_t c2u_CD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1541,7 +1541,7 @@ static wchar_t c2u_CD[256] = {
0x5399,0x5398,0x54BA,0x54A1,0x54AD,0x54A5,0x54CF,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CE[256] = {
+static const wchar_t c2u_CE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1577,7 +1577,7 @@ static wchar_t c2u_CE[256] = {
0x662E,0x670F,0x6710,0x67C1,0x67F2,0x67C8,0x67BA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_CF[256] = {
+static const wchar_t c2u_CF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1613,7 +1613,7 @@ static wchar_t c2u_CF[256] = {
0x7944,0x79D5,0x79CD,0x79CF,0x79D6,0x79CE,0x7A80,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D0[256] = {
+static const wchar_t c2u_D0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1649,7 +1649,7 @@ static wchar_t c2u_D0[256] = {
0x54FF,0x5504,0x5508,0x54EB,0x5511,0x5505,0x54F1,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D1[256] = {
+static const wchar_t c2u_D1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1685,7 +1685,7 @@ static wchar_t c2u_D1[256] = {
0x6B31,0x6B34,0x6B6D,0x8082,0x6B88,0x6BE6,0x6BE4,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D2[256] = {
+static const wchar_t c2u_D2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1721,7 +1721,7 @@ static wchar_t c2u_D2[256] = {
0x7A85,0x7A8B,0x7A8C,0x7A8A,0x7A87,0x7AD8,0x7B10,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D3[256] = {
+static const wchar_t c2u_D3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1757,7 +1757,7 @@ static wchar_t c2u_D3[256] = {
0x90E5,0x90D8,0x90DB,0x90D7,0x90DC,0x90E4,0x9150,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D4[256] = {
+static const wchar_t c2u_D4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1793,7 +1793,7 @@ static wchar_t c2u_D4[256] = {
0x5D20,0x5D0C,0x5D28,0x5D0D,0x5D26,0x5D25,0x5D0F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D5[256] = {
+static const wchar_t c2u_D5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1829,7 +1829,7 @@ static wchar_t c2u_D5[256] = {
0x6DED,0x6DF0,0x6DBA,0x6DD5,0x6DC2,0x6DCF,0x6DC9,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D6[256] = {
+static const wchar_t c2u_D6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1865,7 +1865,7 @@ static wchar_t c2u_D6[256] = {
0x7FCD,0x7FD0,0x7FD1,0x7FC7,0x7FCF,0x7FC9,0x801F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D7[256] = {
+static const wchar_t c2u_D7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1901,7 +1901,7 @@ static wchar_t c2u_D7[256] = {
0x91F4,0x91F1,0x91F3,0x91F8,0x91E4,0x91F9,0x91EA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D8[256] = {
+static const wchar_t c2u_D8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1937,7 +1937,7 @@ static wchar_t c2u_D8[256] = {
0x60C9,0x60B9,0x60CC,0x60E2,0x60CE,0x60C4,0x6114,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_D9[256] = {
+static const wchar_t c2u_D9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -1973,7 +1973,7 @@ static wchar_t c2u_D9[256] = {
0x6E4B,0x6E40,0x6E51,0x6E3B,0x6E03,0x6E2E,0x6E5E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DA[256] = {
+static const wchar_t c2u_DA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2009,7 +2009,7 @@ static wchar_t c2u_DA[256] = {
0x7D69,0x7D51,0x7D5F,0x7D4E,0x7F3E,0x7F3F,0x7F65,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DB[256] = {
+static const wchar_t c2u_DB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2045,7 +2045,7 @@ static wchar_t c2u_DB[256] = {
0x8DD9,0x8DC8,0x8DD7,0x8DC5,0x8EEF,0x8EF7,0x8EFA,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DC[256] = {
+static const wchar_t c2u_DC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2081,7 +2081,7 @@ static wchar_t c2u_DC[256] = {
0x5AB1,0x5AB5,0x5AB0,0x5ABF,0x5AC8,0x5ABB,0x5AC6,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DD[256] = {
+static const wchar_t c2u_DD[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2117,7 +2117,7 @@ static wchar_t c2u_DD[256] = {
0x6B42,0x6B48,0x6B41,0x6B9B,0xFA0D,0x6BFB,0x6BFC,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DE[256] = {
+static const wchar_t c2u_DE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2153,7 +2153,7 @@ static wchar_t c2u_DE[256] = {
0x7A18,0x7A19,0x7A12,0x7A17,0x7A15,0x7A22,0x7A13,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_DF[256] = {
+static const wchar_t c2u_DF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2189,7 +2189,7 @@ static wchar_t c2u_DF[256] = {
0x88CC,0x88D0,0x8985,0x899B,0x89DF,0x89E5,0x89E4,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E0[256] = {
+static const wchar_t c2u_E0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2225,7 +2225,7 @@ static wchar_t c2u_E0[256] = {
0x50E4,0x50D3,0x50EC,0x50F0,0x50EF,0x50E3,0x50E0,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E1[256] = {
+static const wchar_t c2u_E1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2261,7 +2261,7 @@ static wchar_t c2u_E1[256] = {
0x669F,0x6705,0x6704,0x6722,0x69B1,0x69B6,0x69C9,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E2[256] = {
+static const wchar_t c2u_E2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2297,7 +2297,7 @@ static wchar_t c2u_E2[256] = {
0x7998,0x798A,0x798B,0x7996,0x7995,0x7994,0x7993,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E3[256] = {
+static const wchar_t c2u_E3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2333,7 +2333,7 @@ static wchar_t c2u_E3[256] = {
0x88F2,0x88FA,0x88FE,0x88EE,0x88FC,0x88F6,0x88FB,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E4[256] = {
+static const wchar_t c2u_E4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2369,7 +2369,7 @@ static wchar_t c2u_E4[256] = {
0x564C,0x5635,0x5641,0x564A,0x5649,0x5646,0x5658,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E5[256] = {
+static const wchar_t c2u_E5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2405,7 +2405,7 @@ static wchar_t c2u_E5[256] = {
0x6C02,0x6F41,0x6F26,0x6F7E,0x6F87,0x6FC6,0x6F92,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E6[256] = {
+static const wchar_t c2u_E6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2441,7 +2441,7 @@ static wchar_t c2u_E6[256] = {
0x7FEC,0x7FE6,0x7FE8,0x8064,0x8067,0x81A3,0x819F,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E7[256] = {
+static const wchar_t c2u_E7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2477,7 +2477,7 @@ static wchar_t c2u_E7[256] = {
0x8E15,0x8E1B,0x8E16,0x8E11,0x8E19,0x8E26,0x8E27,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E8[256] = {
+static const wchar_t c2u_E8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2513,7 +2513,7 @@ static wchar_t c2u_E8[256] = {
0x5111,0x51DE,0x5334,0x53E1,0x5670,0x5660,0x566E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_E9[256] = {
+static const wchar_t c2u_E9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2549,7 +2549,7 @@ static wchar_t c2u_E9[256] = {
0x6FAE,0x6FBA,0x6FAC,0x6FAA,0x6FCF,0x6FBF,0x6FB8,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EA[256] = {
+static const wchar_t c2u_EA[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2585,7 +2585,7 @@ static wchar_t c2u_EA[256] = {
0x8556,0x8545,0x856B,0x854D,0x8553,0x8561,0x8558,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EB[256] = {
+static const wchar_t c2u_EB[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2621,7 +2621,7 @@ static wchar_t c2u_EB[256] = {
0x92FF,0x9329,0x9339,0x9335,0x932A,0x9314,0x930C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EC[256] = {
+static const wchar_t c2u_EC[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2657,7 +2657,7 @@ static wchar_t c2u_EC[256] = {
0x6A9F,0x6A9B,0x6AA1,0x6A9E,0x6A87,0x6A93,0x6A8E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_ED[256] = {
+static const wchar_t c2u_ED[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2693,7 +2693,7 @@ static wchar_t c2u_ED[256] = {
0x85A0,0x858B,0x85A3,0x857B,0x85A4,0x859A,0x859E,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EE[256] = {
+static const wchar_t c2u_EE[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2729,7 +2729,7 @@ static wchar_t c2u_EE[256] = {
0x971F,0x9718,0x971D,0x9719,0x979A,0x97A1,0x979C,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_EF[256] = {
+static const wchar_t c2u_EF[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2765,7 +2765,7 @@ static wchar_t c2u_EF[256] = {
0x700A,0x7201,0x71FF,0x71F9,0x7203,0x71FD,0x7376,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F0[256] = {
+static const wchar_t c2u_F0[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2801,7 +2801,7 @@ static wchar_t c2u_F0[256] = {
0x8E62,0x8E60,0x8E57,0x8E56,0x8E5E,0x8E65,0x8E67,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F1[256] = {
+static const wchar_t c2u_F1[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2837,7 +2837,7 @@ static wchar_t c2u_F1[256] = {
0x58DB,0x5912,0x5B3D,0x5B3E,0x5B3F,0x5DC3,0x5E70,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F2[256] = {
+static const wchar_t c2u_F2[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2873,7 +2873,7 @@ static wchar_t c2u_F2[256] = {
0x8B4A,0x8B40,0x8B53,0x8B56,0x8B54,0x8B4B,0x8B55,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F3[256] = {
+static const wchar_t c2u_F3[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2909,7 +2909,7 @@ static wchar_t c2u_F3[256] = {
0x9F41,0x9F4D,0x9F56,0x9F57,0x9F58,0x5337,0x56B2,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F4[256] = {
+static const wchar_t c2u_F4[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2945,7 +2945,7 @@ static wchar_t c2u_F4[256] = {
0x9416,0x9412,0x93FA,0x9409,0x93F8,0x940A,0x93FF,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F5[256] = {
+static const wchar_t c2u_F5[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -2981,7 +2981,7 @@ static wchar_t c2u_F5[256] = {
0x8627,0x862E,0x8621,0x8620,0x8629,0x861E,0x8625,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F6[256] = {
+static const wchar_t c2u_F6[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3017,7 +3017,7 @@ static wchar_t c2u_F6[256] = {
0x7A70,0x7A71,0x7C57,0x7C5C,0x7C59,0x7C5B,0x7C5A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F7[256] = {
+static const wchar_t c2u_F7[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3053,7 +3053,7 @@ static wchar_t c2u_F7[256] = {
0x8832,0x882E,0x8833,0x8976,0x8974,0x8973,0x89FE,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F8[256] = {
+static const wchar_t c2u_F8[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3089,7 +3089,7 @@ static wchar_t c2u_F8[256] = {
0x77D8,0x77D9,0x7939,0x7C69,0x7C6B,0x7CF6,0x7E9A,0x0000,/* 0xF8-0xFF */
};
-static wchar_t c2u_F9[256] = {
+static const wchar_t c2u_F9[256] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x00-0x07 */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x08-0x0F */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,/* 0x10-0x17 */
@@ -3125,7 +3125,7 @@ static wchar_t c2u_F9[256] = {
0x2551,0x2550,0x256D,0x256E,0x2570,0x256F,0x2593,0x0000,/* 0xF8-0xFF */
};
-static wchar_t *page_charset2uni[256] = {
+static const wchar_t *page_charset2uni[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -3160,7 +3160,7 @@ static wchar_t *page_charset2uni[256] = {
c2u_F8, c2u_F9, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char u2c_02[512] = {
+static const unsigned char u2c_02[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3219,7 +3219,7 @@ static unsigned char u2c_02[512] = {
0x00, 0x00, 0xA3, 0xBB, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */
};
-static unsigned char u2c_03[512] = {
+static const unsigned char u2c_03[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA1, 0xC2, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3274,7 +3274,7 @@ static unsigned char u2c_03[512] = {
0xA3, 0x72, 0xA3, 0x73, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */
};
-static unsigned char u2c_20[512] = {
+static const unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3293,7 +3293,7 @@ static unsigned char u2c_20[512] = {
0x00, 0x00, 0x00, 0x00, 0xA1, 0xC3, 0x00, 0x00, /* 0x3C-0x3F */
};
-static unsigned char u2c_21[512] = {
+static const unsigned char u2c_21[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x4A, /* 0x00-0x03 */
0x00, 0x00, 0xA1, 0xC1, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xA2, 0x4B, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3336,7 +3336,7 @@ static unsigned char u2c_21[512] = {
0xA1, 0xFB, 0xA1, 0xFA, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */
};
-static unsigned char u2c_22[512] = {
+static const unsigned char u2c_22[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3388,12 +3388,12 @@ static unsigned char u2c_22[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xE9, /* 0xBC-0xBF */
};
-static unsigned char u2c_23[512] = {
+static const unsigned char u2c_23[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x5B, /* 0x04-0x07 */
};
-static unsigned char u2c_25[512] = {
+static const unsigned char u2c_25[512] = {
0xA2, 0x77, 0x00, 0x00, 0xA2, 0x78, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3455,7 +3455,7 @@ static unsigned char u2c_25[512] = {
0xA2, 0xAB, 0xA2, 0xAA, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char u2c_26[512] = {
+static const unsigned char u2c_26[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA1, 0xB9, 0xA1, 0xB8, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xA1, 0xF3, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3475,7 +3475,7 @@ static unsigned char u2c_26[512] = {
0xA1, 0xF0, 0xA1, 0xF2, 0xA1, 0xF1, 0x00, 0x00, /* 0x40-0x43 */
};
-static unsigned char u2c_30[512] = {
+static const unsigned char u2c_30[512] = {
0xA1, 0x40, 0xA1, 0x42, 0xA1, 0x43, 0xA1, 0xB2, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xA1, 0x71, 0xA1, 0x72, 0xA1, 0x6D, 0xA1, 0x6E, /* 0x08-0x0B */
@@ -3491,7 +3491,7 @@ static unsigned char u2c_30[512] = {
0xA1, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x33 */
};
-static unsigned char u2c_31[512] = {
+static const unsigned char u2c_31[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA3, 0x74, 0xA3, 0x75, 0xA3, 0x76, /* 0x04-0x07 */
0xA3, 0x77, 0xA3, 0x78, 0xA3, 0x79, 0xA3, 0x7A, /* 0x08-0x0B */
@@ -3535,7 +3535,7 @@ static unsigned char u2c_31[512] = {
0xA4, 0x42, 0xA4, 0xD1, 0xA6, 0x61, 0xA4, 0x48, /* 0x9C-0x9F */
};
-static unsigned char u2c_32[512] = {
+static const unsigned char u2c_32[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3584,7 +3584,7 @@ static unsigned char u2c_32[512] = {
0xA9, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */
};
-static unsigned char u2c_33[512] = {
+static const unsigned char u2c_33[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -3642,7 +3642,7 @@ static unsigned char u2c_33[512] = {
0x00, 0x00, 0xA2, 0x4F, 0x00, 0x00, 0x00, 0x00, /* 0xD4-0xD7 */
};
-static unsigned char u2c_4E[512] = {
+static const unsigned char u2c_4E[512] = {
0xA4, 0x40, 0xA4, 0x42, 0x00, 0x00, 0xA4, 0x43, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x45, /* 0x04-0x07 */
0xA4, 0x56, 0xA4, 0x54, 0xA4, 0x57, 0xA4, 0x55, /* 0x08-0x0B */
@@ -3710,7 +3710,7 @@ static unsigned char u2c_4E[512] = {
0x00, 0x00, 0xA5, 0xF7, 0x00, 0x00, 0xA5, 0xE9, /* 0xFC-0xFF */
};
-static unsigned char u2c_4F[512] = {
+static const unsigned char u2c_4F[512] = {
0xC9, 0xB1, 0xA5, 0xF8, 0xC9, 0xB5, 0x00, 0x00, /* 0x00-0x03 */
0xC9, 0xB9, 0xC9, 0xB6, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xC9, 0xB3, 0xA5, 0xEA, 0xA5, 0xEC, 0xA5, 0xF9, /* 0x08-0x0B */
@@ -3778,7 +3778,7 @@ static unsigned char u2c_4F[512] = {
0x00, 0x00, 0x00, 0x00, 0xAD, 0xDA, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_50[512] = {
+static const unsigned char u2c_50[512] = {
0xAD, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xD0, 0xC9, 0xAD, 0xC7, 0xD0, 0xCA, /* 0x04-0x07 */
0x00, 0x00, 0xAD, 0xDC, 0x00, 0x00, 0xAD, 0xD3, /* 0x08-0x0B */
@@ -3846,7 +3846,7 @@ static unsigned char u2c_50[512] = {
0x00, 0x00, 0xE4, 0xF0, 0xE4, 0xED, 0xE4, 0xE6, /* 0xFC-0xFF */
};
-static unsigned char u2c_51[512] = {
+static const unsigned char u2c_51[512] = {
0xBB, 0xF6, 0x00, 0x00, 0xBB, 0xFA, 0xE4, 0xE7, /* 0x00-0x03 */
0xBB, 0xF5, 0xBB, 0xFD, 0xE4, 0xEA, 0xE4, 0xEB, /* 0x04-0x07 */
0xBB, 0xFB, 0xBB, 0xFC, 0xE4, 0xF1, 0xE4, 0xEE, /* 0x08-0x0B */
@@ -3914,7 +3914,7 @@ static unsigned char u2c_51[512] = {
0x00, 0x00, 0xA8, 0xE7, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_52[512] = {
+static const unsigned char u2c_52[512] = {
0xA4, 0x4D, 0xA4, 0x4E, 0x00, 0x00, 0xA4, 0x62, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xA4, 0xC0, 0xA4, 0xC1, /* 0x04-0x07 */
0xA4, 0xC2, 0xC9, 0xBE, 0xA5, 0x5A, 0x00, 0x00, /* 0x08-0x0B */
@@ -3982,7 +3982,7 @@ static unsigned char u2c_52[512] = {
0xC9, 0x56, 0x00, 0x00, 0xA4, 0xC4, 0xA4, 0xC5, /* 0xFC-0xFF */
};
-static unsigned char u2c_53[512] = {
+static const unsigned char u2c_53[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xA5, 0x5D, 0xA5, 0x5E, 0x00, 0x00, /* 0x04-0x07 */
0xA6, 0x49, 0xCA, 0x71, 0xCB, 0xD6, 0xCB, 0xD7, /* 0x08-0x0B */
@@ -4050,7 +4050,7 @@ static unsigned char u2c_53[512] = {
0xA5, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_54[512] = {
+static const unsigned char u2c_54[512] = {
0x00, 0x00, 0xA6, 0x53, 0x00, 0x00, 0xA6, 0x59, /* 0x00-0x03 */
0xA6, 0x55, 0x00, 0x00, 0xA6, 0x5B, 0xC9, 0xC5, /* 0x04-0x07 */
0xA6, 0x58, 0xA6, 0x4E, 0xA6, 0x51, 0xA6, 0x54, /* 0x08-0x0B */
@@ -4118,7 +4118,7 @@ static unsigned char u2c_54[512] = {
0xAD, 0xF3, 0xAE, 0x43, 0x00, 0x00, 0xD0, 0xF8, /* 0xFC-0xFF */
};
-static unsigned char u2c_55[512] = {
+static const unsigned char u2c_55[512] = {
0x00, 0x00, 0xAD, 0xF1, 0x00, 0x00, 0xD1, 0x46, /* 0x00-0x03 */
0xD0, 0xF9, 0xD0, 0xFD, 0xAD, 0xF6, 0xAE, 0x42, /* 0x04-0x07 */
0xD0, 0xFA, 0xAD, 0xFC, 0xD1, 0x40, 0xD1, 0x47, /* 0x08-0x0B */
@@ -4186,7 +4186,7 @@ static unsigned char u2c_55[512] = {
0xE1, 0x4B, 0xB9, 0xC2, 0xB9, 0xBE, 0xE1, 0x54, /* 0xFC-0xFF */
};
-static unsigned char u2c_56[512] = {
+static const unsigned char u2c_56[512] = {
0xB9, 0xBF, 0xE1, 0x4E, 0xE1, 0x50, 0x00, 0x00, /* 0x00-0x03 */
0xE1, 0x53, 0x00, 0x00, 0xB9, 0xC4, 0x00, 0x00, /* 0x04-0x07 */
0xB9, 0xCB, 0xB9, 0xC5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4254,7 +4254,7 @@ static unsigned char u2c_56[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xAA, /* 0xFC-0xFF */
};
-static unsigned char u2c_57[512] = {
+static const unsigned char u2c_57[512] = {
0x00, 0x00, 0xD1, 0x48, 0xD1, 0x49, 0xAE, 0x45, /* 0x00-0x03 */
0xAE, 0x46, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xAC, /* 0x04-0x07 */
0xB0, 0xE9, 0xB0, 0xEB, 0xD4, 0xAB, 0xB0, 0xEA, /* 0x08-0x0B */
@@ -4322,7 +4322,7 @@ static unsigned char u2c_57[512] = {
0xD4, 0xC3, 0xD4, 0xB5, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_58[512] = {
+static const unsigned char u2c_58[512] = {
0xD4, 0xB3, 0xD4, 0xC6, 0xB0, 0xF3, 0x00, 0x00, /* 0x00-0x03 */
0xD4, 0xCC, 0xB0, 0xED, 0xB0, 0xEF, 0xD4, 0xBB, /* 0x04-0x07 */
0xD4, 0xB6, 0xAE, 0x4B, 0xB0, 0xEE, 0xD4, 0xB8, /* 0x08-0x0B */
@@ -4390,7 +4390,7 @@ static unsigned char u2c_58[512] = {
0xDC, 0xF2, 0xB9, 0xD8, 0xE1, 0x69, 0xE5, 0x53, /* 0xFC-0xFF */
};
-static unsigned char u2c_59[512] = {
+static const unsigned char u2c_59[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x5A, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xCA, 0xB0, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -4458,7 +4458,7 @@ static unsigned char u2c_59[512] = {
0xCE, 0x6A, 0xCE, 0x69, 0xCE, 0x74, 0xAB, 0xBA, /* 0xFC-0xFF */
};
-static unsigned char u2c_5A[512] = {
+static const unsigned char u2c_5A[512] = {
0xCE, 0x65, 0xAB, 0xC2, 0x00, 0x00, 0xAB, 0xBD, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xAE, 0x5C, 0xD1, 0x62, 0x00, 0x00, /* 0x08-0x0B */
@@ -4526,7 +4526,7 @@ static unsigned char u2c_5A[512] = {
0x00, 0x00, 0xE5, 0x56, 0x00, 0x00, 0xE5, 0x54, /* 0xFC-0xFF */
};
-static unsigned char u2c_5B[512] = {
+static const unsigned char u2c_5B[512] = {
0x00, 0x00, 0xE5, 0x5D, 0xE5, 0x5B, 0xE5, 0x59, /* 0x00-0x03 */
0x00, 0x00, 0xE5, 0x5F, 0x00, 0x00, 0xE5, 0x5E, /* 0x04-0x07 */
0xBC, 0x63, 0xBC, 0x5E, 0x00, 0x00, 0xBC, 0x60, /* 0x08-0x0B */
@@ -4594,7 +4594,7 @@ static unsigned char u2c_5B[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_5C[512] = {
+static const unsigned char u2c_5C[512] = {
0x00, 0x00, 0xAB, 0xCA, 0x00, 0x00, 0xD1, 0x69, /* 0x00-0x03 */
0xAE, 0x67, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x4E, /* 0x04-0x07 */
0xB1, 0x4D, 0xB1, 0x4C, 0xB4, 0x4C, 0xB4, 0x4D, /* 0x08-0x0B */
@@ -4662,7 +4662,7 @@ static unsigned char u2c_5C[512] = {
0x00, 0x00, 0xAE, 0x6C, 0x00, 0x00, 0xD1, 0x6D, /* 0xFC-0xFF */
};
-static unsigned char u2c_5D[512] = {
+static const unsigned char u2c_5D[512] = {
0xD1, 0x71, 0xAE, 0x72, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xB1, 0x53, 0xB1, 0x52, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xF5, /* 0x08-0x0B */
@@ -4730,7 +4730,7 @@ static unsigned char u2c_5D[512] = {
0x00, 0x00, 0xB4, 0x53, 0xA4, 0x79, 0xC9, 0x5D, /* 0xFC-0xFF */
};
-static unsigned char u2c_5E[512] = {
+static const unsigned char u2c_5E[512] = {
0x00, 0x00, 0x00, 0x00, 0xA5, 0xAB, 0xA5, 0xAC, /* 0x00-0x03 */
0xC9, 0x78, 0x00, 0x00, 0xA6, 0x7C, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xCA, 0xCB, 0x00, 0x00, /* 0x08-0x0B */
@@ -4798,7 +4798,7 @@ static unsigned char u2c_5E[512] = {
0x00, 0x00, 0x00, 0x00, 0xA4, 0x7B, 0xA4, 0xDC, /* 0xFC-0xFF */
};
-static unsigned char u2c_5F[512] = {
+static const unsigned char u2c_5F[512] = {
0x00, 0x00, 0xA5, 0xAF, 0xC9, 0xDD, 0x00, 0x00, /* 0x00-0x03 */
0xA7, 0xCB, 0xCA, 0xD2, 0x00, 0x00, 0xCE, 0xBB, /* 0x04-0x07 */
0xAB, 0xD9, 0x00, 0x00, 0xB9, 0xFA, 0xA4, 0x7C, /* 0x08-0x0B */
@@ -4866,7 +4866,7 @@ static unsigned char u2c_5F[512] = {
0x00, 0x00, 0xA9, 0xBF, 0x00, 0x00, 0xA9, 0xC1, /* 0xFC-0xFF */
};
-static unsigned char u2c_60[512] = {
+static const unsigned char u2c_60[512] = {
0xCA, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xCC, 0xAF, 0xCC, 0xA2, 0xCC, 0x7E, /* 0x08-0x0B */
@@ -4934,7 +4934,7 @@ static unsigned char u2c_60[512] = {
0xD9, 0x47, 0x00, 0x00, 0xD9, 0x48, 0xD9, 0x4E, /* 0xFC-0xFF */
};
-static unsigned char u2c_61[512] = {
+static const unsigned char u2c_61[512] = {
0xB4, 0x73, 0xB7, 0x54, 0x00, 0x00, 0xD9, 0x4A, /* 0x00-0x03 */
0xD9, 0x4F, 0xD9, 0x43, 0xB7, 0x5E, 0x00, 0x00, /* 0x04-0x07 */
0xB7, 0x55, 0xB4, 0x72, 0xD9, 0x41, 0xD9, 0x50, /* 0x08-0x0B */
@@ -5002,7 +5002,7 @@ static unsigned char u2c_61[512] = {
0xC4, 0xDF, 0xF5, 0xCC, 0xC4, 0xE0, 0xC5, 0x74, /* 0xFC-0xFF */
};
-static unsigned char u2c_62[512] = {
+static const unsigned char u2c_62[512] = {
0xC5, 0xCA, 0xF7, 0xD9, 0x00, 0x00, 0xF7, 0xDA, /* 0x00-0x03 */
0xF7, 0xDB, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xBA, /* 0x04-0x07 */
0xA4, 0xE0, 0xC9, 0x7C, 0xA5, 0xB3, 0x00, 0x00, /* 0x08-0x0B */
@@ -5070,7 +5070,7 @@ static unsigned char u2c_62[512] = {
0xAB, 0xF7, 0xAB, 0xFB, 0xAC, 0x42, 0xAE, 0xB3, /* 0xFC-0xFF */
};
-static unsigned char u2c_63[512] = {
+static const unsigned char u2c_63[512] = {
0xCE, 0xE0, 0xAB, 0xF9, 0xAC, 0x45, 0xCE, 0xD9, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xFC, /* 0x04-0x07 */
0xAE, 0xB2, 0xAB, 0xF6, 0x00, 0x00, 0xCE, 0xD6, /* 0x08-0x0B */
@@ -5138,7 +5138,7 @@ static unsigned char u2c_63[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_64[512] = {
+static const unsigned char u2c_64[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xB7, 0x70, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xDD, 0x7C, 0xDD, 0xB1, 0xDD, 0xB6, /* 0x08-0x0B */
@@ -5206,7 +5206,7 @@ static unsigned char u2c_64[512] = {
0xEF, 0xD7, 0xEF, 0xD3, 0xC2, 0x5A, 0xEF, 0xD1, /* 0xFC-0xFF */
};
-static unsigned char u2c_65[512] = {
+static const unsigned char u2c_65[512] = {
0xC3, 0x6B, 0xEF, 0xD5, 0x00, 0x00, 0xEF, 0xD6, /* 0x00-0x03 */
0xEF, 0xD2, 0x00, 0x00, 0xC2, 0x5B, 0xF2, 0x42, /* 0x04-0x07 */
0x00, 0x00, 0xF2, 0x45, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5274,7 +5274,7 @@ static unsigned char u2c_65[512] = {
0xCC, 0xC5, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_66[512] = {
+static const unsigned char u2c_66[512] = {
0xA9, 0xFB, 0x00, 0x00, 0xA9, 0xF9, 0xCC, 0xCA, /* 0x00-0x03 */
0xCC, 0xC6, 0xCC, 0xCD, 0xA9, 0xF8, 0xAA, 0x40, /* 0x04-0x07 */
0xCC, 0xC8, 0xCC, 0xC4, 0xA9, 0xFE, 0xCC, 0xCB, /* 0x08-0x0B */
@@ -5342,7 +5342,7 @@ static unsigned char u2c_66[512] = {
0xB0, 0xD2, 0x00, 0x00, 0xB4, 0xBF, 0xB4, 0xC0, /* 0xFC-0xFF */
};
-static unsigned char u2c_67[512] = {
+static const unsigned char u2c_67[512] = {
0xB3, 0xCC, 0xD9, 0xA9, 0x00, 0x00, 0xB7, 0x7C, /* 0x00-0x03 */
0xE1, 0xFA, 0xE1, 0xF9, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xA4, 0xEB, 0xA6, 0xB3, 0xCC, 0xD2, 0xAA, 0x42, /* 0x08-0x0B */
@@ -5410,7 +5410,7 @@ static unsigned char u2c_67[512] = {
0xCF, 0x57, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x55, /* 0xFC-0xFF */
};
-static unsigned char u2c_68[512] = {
+static const unsigned char u2c_68[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5478,7 +5478,7 @@ static unsigned char u2c_68[512] = {
0xD9, 0xC8, 0xD9, 0xC7, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_69[512] = {
+static const unsigned char u2c_69[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xD9, 0xAC, 0xB4, 0xC8, 0xD9, 0xD4, 0xD9, 0xBC, /* 0x04-0x07 */
0xD9, 0xBE, 0x00, 0x00, 0xD9, 0xCB, 0xD9, 0xCA, /* 0x08-0x0B */
@@ -5546,7 +5546,7 @@ static unsigned char u2c_69[512] = {
0xE5, 0xE4, 0xBC, 0xD1, 0xE5, 0xD8, 0xE5, 0xD3, /* 0xFC-0xFF */
};
-static unsigned char u2c_6A[512] = {
+static const unsigned char u2c_6A[512] = {
0xE5, 0xCA, 0xBC, 0xCE, 0xBC, 0xD6, 0x00, 0x00, /* 0x00-0x03 */
0xE5, 0xE7, 0xBC, 0xD7, 0xE5, 0xCB, 0xE5, 0xED, /* 0x04-0x07 */
0xE5, 0xE0, 0xE5, 0xE6, 0xBC, 0xD4, 0x00, 0x00, /* 0x08-0x0B */
@@ -5614,7 +5614,7 @@ static unsigned char u2c_6A[512] = {
0xF5, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_6B[512] = {
+static const unsigned char u2c_6B[512] = {
0xF5, 0xD2, 0x00, 0x00, 0xF5, 0xCE, 0xF5, 0xD0, /* 0x00-0x03 */
0xC4, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xF6, 0xE5, 0xF6, 0xE6, 0xC5, 0x76, 0xF6, 0xE4, /* 0x08-0x0B */
@@ -5682,7 +5682,7 @@ static unsigned char u2c_6B[512] = {
0xDD, 0xFE, 0xB7, 0xB7, 0xE2, 0x6B, 0xE5, 0xF7, /* 0xFC-0xFF */
};
-static unsigned char u2c_6C[512] = {
+static const unsigned char u2c_6C[512] = {
0xE5, 0xF6, 0xE5, 0xF5, 0xE5, 0xF8, 0xE9, 0xE7, /* 0x00-0x03 */
0xE9, 0xE6, 0xBE, 0xFB, 0xE9, 0xE8, 0x00, 0x00, /* 0x04-0x07 */
0xC0, 0xD6, 0xED, 0x4D, 0x00, 0x00, 0xEF, 0xEA, /* 0x08-0x0B */
@@ -5749,7 +5749,7 @@ static unsigned char u2c_6C[512] = {
0x00, 0x00, 0xCD, 0x4C, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
};
-static unsigned char u2c_6D[512] = {
+static const unsigned char u2c_6D[512] = {
0xCF, 0x7C, 0xCF, 0xA1, 0x00, 0x00, 0xCF, 0xA4, /* 0x00-0x03 */
0xCF, 0x77, 0x00, 0x00, 0x00, 0x00, 0xCF, 0xA7, /* 0x04-0x07 */
0xCF, 0xAA, 0xCF, 0xAC, 0xCF, 0x74, 0xAC, 0x76, /* 0x08-0x0B */
@@ -5817,7 +5817,7 @@ static unsigned char u2c_6D[512] = {
0xD9, 0xE7, 0xD6, 0x43, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_6E[512] = {
+static const unsigned char u2c_6E[512] = {
0xD5, 0xEB, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xFC, /* 0x00-0x03 */
0x00, 0x00, 0xB2, 0x4D, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -5885,7 +5885,7 @@ static unsigned char u2c_6E[512] = {
0xE2, 0xB3, 0xE2, 0xAF, 0xBA, 0x75, 0xBA, 0xA1, /* 0xFC-0xFF */
};
-static unsigned char u2c_6F[512] = {
+static const unsigned char u2c_6F[512] = {
0xE6, 0x53, 0xBA, 0xAE, 0xBA, 0x7D, 0xE2, 0x6F, /* 0x00-0x03 */
0x00, 0x00, 0xE2, 0xAE, 0xBA, 0xA3, 0xE2, 0xAB, /* 0x04-0x07 */
0xE2, 0xB8, 0xE2, 0x75, 0xE2, 0x7E, 0x00, 0x00, /* 0x08-0x0B */
@@ -5953,7 +5953,7 @@ static unsigned char u2c_6F[512] = {
0xEF, 0xF6, 0x00, 0x00, 0xC2, 0x6F, 0xEF, 0xF2, /* 0xFC-0xFF */
};
-static unsigned char u2c_70[512] = {
+static const unsigned char u2c_70[512] = {
0xEF, 0xF3, 0xEF, 0xEE, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xE9, 0xF6, 0xEF, 0xEF, 0xC2, 0x70, 0xEF, 0xEB, /* 0x04-0x07 */
0x00, 0x00, 0xC2, 0x6D, 0xEF, 0xF8, 0xC2, 0x6E, /* 0x08-0x0B */
@@ -6021,7 +6021,7 @@ static unsigned char u2c_70[512] = {
0xD6, 0x52, 0xB2, 0x6C, 0x00, 0x00, 0xD6, 0x53, /* 0xFC-0xFF */
};
-static unsigned char u2c_71[512] = {
+static const unsigned char u2c_71[512] = {
0xD6, 0x56, 0x00, 0x00, 0xD6, 0x5A, 0x00, 0x00, /* 0x00-0x03 */
0xD6, 0x4F, 0x00, 0x00, 0xD6, 0x54, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xB2, 0x6A, 0xB2, 0x6B, 0xD6, 0x59, /* 0x08-0x0B */
@@ -6089,7 +6089,7 @@ static unsigned char u2c_71[512] = {
0xC2, 0x75, 0xEF, 0xFD, 0xC2, 0x76, 0xEF, 0xFA, /* 0xFC-0xFF */
};
-static unsigned char u2c_72[512] = {
+static const unsigned char u2c_72[512] = {
0x00, 0x00, 0xEF, 0xF9, 0xF2, 0x6C, 0xEF, 0xFC, /* 0x00-0x03 */
0x00, 0x00, 0xF2, 0x6D, 0xC3, 0x7A, 0xF2, 0x6B, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0xF2, 0x6A, 0x00, 0x00, /* 0x08-0x0B */
@@ -6157,7 +6157,7 @@ static unsigned char u2c_72[512] = {
0xAF, 0x54, 0xAF, 0x56, 0xD2, 0xA6, 0xD6, 0x67, /* 0xFC-0xFF */
};
-static unsigned char u2c_73[512] = {
+static const unsigned char u2c_73[512] = {
0xD2, 0xA3, 0xD2, 0xAA, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0x62, /* 0x04-0x07 */
0xD6, 0x66, 0x00, 0x00, 0xD6, 0x65, 0xDA, 0x6E, /* 0x08-0x0B */
@@ -6225,7 +6225,7 @@ static unsigned char u2c_73[512] = {
0xD6, 0x74, 0xD6, 0x70, 0xB2, 0x7B, 0xD6, 0x75, /* 0xFC-0xFF */
};
-static unsigned char u2c_74[512] = {
+static const unsigned char u2c_74[512] = {
0xD6, 0x72, 0xD6, 0x6F, 0x00, 0x00, 0xB2, 0x79, /* 0x00-0x03 */
0xD6, 0x6E, 0xB2, 0x77, 0xB2, 0x7A, 0xD6, 0x71, /* 0x04-0x07 */
0xD6, 0x79, 0xAF, 0x5B, 0xB2, 0x78, 0xD6, 0x77, /* 0x08-0x0B */
@@ -6293,7 +6293,7 @@ static unsigned char u2c_74[512] = {
0x00, 0x00, 0xDE, 0xC2, 0xDE, 0xC1, 0xDE, 0xC0, /* 0xFC-0xFF */
};
-static unsigned char u2c_75[512] = {
+static const unsigned char u2c_75[512] = {
0xE2, 0xD5, 0x00, 0x00, 0xE2, 0xD6, 0xE2, 0xD7, /* 0x00-0x03 */
0xBA, 0xC2, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xAD, /* 0x04-0x07 */
0xE6, 0xAC, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x69, /* 0x08-0x0B */
@@ -6361,7 +6361,7 @@ static unsigned char u2c_75[512] = {
0xDE, 0xCC, 0xDE, 0xD4, 0xDE, 0xCB, 0xB7, 0xF5, /* 0xFC-0xFF */
};
-static unsigned char u2c_76[512] = {
+static const unsigned char u2c_76[512] = {
0xB7, 0xEF, 0xB7, 0xF1, 0x00, 0x00, 0xDE, 0xC9, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xE2, 0xDB, 0xBA, 0xC7, 0xE2, 0xDF, 0xBA, 0xC6, /* 0x08-0x0B */
@@ -6429,7 +6429,7 @@ static unsigned char u2c_76[512] = {
0xAC, 0xDF, 0x00, 0x00, 0xAC, 0xDE, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_77[512] = {
+static const unsigned char u2c_77[512] = {
0x00, 0x00, 0xAC, 0xD9, 0x00, 0x00, 0xCF, 0xE1, /* 0x00-0x03 */
0xCF, 0xE2, 0xCF, 0xE3, 0x00, 0x00, 0xAC, 0xE0, /* 0x04-0x07 */
0xCF, 0xE0, 0xAC, 0xDC, 0xCF, 0xE4, 0xAC, 0xDD, /* 0x08-0x0B */
@@ -6497,7 +6497,7 @@ static unsigned char u2c_77[512] = {
0xCD, 0x7B, 0xAA, 0xBF, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_78[512] = {
+static const unsigned char u2c_78[512] = {
0x00, 0x00, 0x00, 0x00, 0xAC, 0xE2, 0xCF, 0xF2, /* 0x00-0x03 */
0x00, 0x00, 0xCF, 0xED, 0xCF, 0xEA, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xCF, 0xF1, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6565,7 +6565,7 @@ static unsigned char u2c_78[512] = {
0xED, 0xA9, 0xED, 0xA6, 0xED, 0xAD, 0xF0, 0x56, /* 0xFC-0xFF */
};
-static unsigned char u2c_79[512] = {
+static const unsigned char u2c_79[512] = {
0x00, 0x00, 0xC1, 0x47, 0xED, 0xA7, 0x00, 0x00, /* 0x00-0x03 */
0xED, 0xAE, 0xED, 0xAB, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0xF0, 0x5A, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -6633,7 +6633,7 @@ static unsigned char u2c_79[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_7A[512] = {
+static const unsigned char u2c_7A[512] = {
0xB5, 0x7D, 0x00, 0x00, 0xDA, 0xD6, 0xDA, 0xD8, /* 0x00-0x03 */
0xDA, 0xDA, 0xB5, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xB5, 0x7A, 0x00, 0x00, 0xDA, 0xD7, 0xB5, 0x7B, /* 0x08-0x0B */
@@ -6701,7 +6701,7 @@ static unsigned char u2c_7A[512] = {
0x00, 0x00, 0xAC, 0xF2, 0x00, 0x00, 0xAC, 0xF1, /* 0xFC-0xFF */
};
-static unsigned char u2c_7B[512] = {
+static const unsigned char u2c_7B[512] = {
0xD0, 0x42, 0xD0, 0x43, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xD3, 0x40, 0xD3, 0x42, 0xAF, 0xB9, 0x00, 0x00, /* 0x04-0x07 */
0xD3, 0x44, 0xD3, 0x47, 0xD3, 0x45, 0x00, 0x00, /* 0x08-0x0B */
@@ -6769,7 +6769,7 @@ static unsigned char u2c_7B[512] = {
0x00, 0x00, 0xED, 0xC9, 0xC1, 0x4E, 0xED, 0xBE, /* 0xFC-0xFF */
};
-static unsigned char u2c_7C[512] = {
+static const unsigned char u2c_7C[512] = {
0xED, 0xBD, 0xED, 0xC7, 0xED, 0xC4, 0xED, 0xC6, /* 0x00-0x03 */
0x00, 0x00, 0xED, 0xBA, 0xED, 0xCA, 0xC1, 0x4C, /* 0x04-0x07 */
0x00, 0x00, 0xED, 0xC5, 0xED, 0xCE, 0xED, 0xC2, /* 0x08-0x0B */
@@ -6837,7 +6837,7 @@ static unsigned char u2c_7C[512] = {
0x00, 0x00, 0xCD, 0xA9, 0xAA, 0xC8, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_7D[512] = {
+static const unsigned char u2c_7D[512] = {
0xAC, 0xF6, 0xD0, 0x4C, 0xAC, 0xF4, 0xD0, 0x4A, /* 0x00-0x03 */
0xAC, 0xF9, 0xAC, 0xF5, 0xAC, 0xFA, 0xAC, 0xF8, /* 0x04-0x07 */
0xD0, 0x4B, 0xAC, 0xF7, 0xAF, 0xBF, 0xAF, 0xBE, /* 0x08-0x0B */
@@ -6904,7 +6904,7 @@ static unsigned char u2c_7D[512] = {
0x00, 0x00, 0xBD, 0x7B, 0xE6, 0xEA, 0xBD, 0x6F, /* 0xF8-0xFB */
};
-static unsigned char u2c_7E[512] = {
+static const unsigned char u2c_7E[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xE9, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0xBF, 0xA2, 0xBF, 0xA7, 0xBF, 0x7E, 0xEA, 0xD8, /* 0x08-0x0B */
@@ -6948,7 +6948,7 @@ static unsigned char u2c_7E[512] = {
0xC6, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */
};
-static unsigned char u2c_7F[512] = {
+static const unsigned char u2c_7F[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7016,7 +7016,7 @@ static unsigned char u2c_7F[512] = {
0xC1, 0x6C, 0xF2, 0xBE, 0xF2, 0xBF, 0xF4, 0xB1, /* 0xFC-0xFF */
};
-static unsigned char u2c_80[512] = {
+static const unsigned char u2c_80[512] = {
0xC4, 0xA3, 0xA6, 0xD1, 0x00, 0x00, 0xA6, 0xD2, /* 0x00-0x03 */
0xAC, 0xFE, 0xAA, 0xCC, 0xAF, 0xCF, 0xD0, 0x51, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0xC0, /* 0x08-0x0B */
@@ -7084,7 +7084,7 @@ static unsigned char u2c_80[512] = {
0xAF, 0xE2, 0xAF, 0xE0, 0xDB, 0x48, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_81[512] = {
+static const unsigned char u2c_81[512] = {
0xD3, 0x6F, 0xD3, 0x6D, 0xAF, 0xD7, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xAF, 0xD9, 0xAF, 0xDC, 0x00, 0x00, /* 0x04-0x07 */
0xAF, 0xDF, 0x00, 0x00, 0xAF, 0xE1, 0x00, 0x00, /* 0x08-0x0B */
@@ -7152,7 +7152,7 @@ static unsigned char u2c_81[512] = {
0xA6, 0xDD, 0x00, 0x00, 0xAA, 0xD8, 0xD0, 0x68, /* 0xFC-0xFF */
};
-static unsigned char u2c_82[512] = {
+static const unsigned char u2c_82[512] = {
0xAF, 0xE6, 0xD3, 0x70, 0xB2, 0xEA, 0x00, 0x00, /* 0x00-0x03 */
0xDB, 0x57, 0xB8, 0xA4, 0x00, 0x00, 0xBB, 0x50, /* 0x04-0x07 */
0xBF, 0xB3, 0xC1, 0x7C, 0xC2, 0xC2, 0xF4, 0xB5, /* 0x08-0x0B */
@@ -7220,7 +7220,7 @@ static unsigned char u2c_82[512] = {
0x00, 0x00, 0x00, 0x00, 0xD0, 0x6C, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_83[512] = {
+static const unsigned char u2c_83[512] = {
0xD0, 0x70, 0xAD, 0x5F, 0xAD, 0x5A, 0xAD, 0x53, /* 0x00-0x03 */
0xAD, 0x58, 0xAD, 0x54, 0xAD, 0x67, 0xD0, 0x6E, /* 0x04-0x07 */
0xD3, 0xA5, 0xAD, 0x5B, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7288,7 +7288,7 @@ static unsigned char u2c_83[512] = {
0xDB, 0x65, 0xB5, 0xE0, 0xDB, 0xB0, 0xDB, 0x71, /* 0xFC-0xFF */
};
-static unsigned char u2c_84[512] = {
+static const unsigned char u2c_84[512] = {
0x00, 0x00, 0xDB, 0x6D, 0x00, 0x00, 0xB5, 0xD1, /* 0x00-0x03 */
0xB5, 0xE5, 0x00, 0x00, 0xDB, 0x7C, 0xB5, 0xE7, /* 0x04-0x07 */
0x00, 0x00, 0xDB, 0x78, 0xB5, 0xDC, 0xB5, 0xD6, /* 0x08-0x0B */
@@ -7356,7 +7356,7 @@ static unsigned char u2c_84[512] = {
0xE7, 0x64, 0xE7, 0x6E, 0xE7, 0x69, 0xBD, 0xB6, /* 0xFC-0xFF */
};
-static unsigned char u2c_85[512] = {
+static const unsigned char u2c_85[512] = {
0xE7, 0x4F, 0x00, 0x00, 0xE7, 0x6D, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xBD, 0xB7, 0xDF, 0xBD, /* 0x04-0x07 */
0xE7, 0x5B, 0xE7, 0x52, 0xE7, 0x55, 0xE7, 0x7B, /* 0x08-0x0B */
@@ -7424,7 +7424,7 @@ static unsigned char u2c_85[512] = {
0x00, 0x00, 0xF4, 0xC3, 0xF4, 0xBB, 0xF4, 0xB9, /* 0xFC-0xFF */
};
-static unsigned char u2c_86[512] = {
+static const unsigned char u2c_86[512] = {
0xF4, 0xBD, 0xF4, 0xBA, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0xF4, 0xBF, 0xF4, 0xC1, 0xC4, 0xAA, 0xC4, 0xAC, /* 0x04-0x07 */
0x00, 0x00, 0xF4, 0xC0, 0xC4, 0xAD, 0xC4, 0xAB, /* 0x08-0x0B */
@@ -7492,7 +7492,7 @@ static unsigned char u2c_86[512] = {
0x00, 0x00, 0x00, 0x00, 0xB8, 0xBF, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_87[512] = {
+static const unsigned char u2c_87[512] = {
0xB8, 0xBE, 0xDF, 0xED, 0xB8, 0xC1, 0xB8, 0xC2, /* 0x00-0x03 */
0xDF, 0xE3, 0xDF, 0xF0, 0xB8, 0xC3, 0xB8, 0xBD, /* 0x04-0x07 */
0xB8, 0xBC, 0xDF, 0xEC, 0xB8, 0xC4, 0xDF, 0xE2, /* 0x08-0x0B */
@@ -7560,7 +7560,7 @@ static unsigned char u2c_87[512] = {
0xF2, 0xE4, 0x00, 0x00, 0xC3, 0xCA, 0xF2, 0xE6, /* 0xFC-0xFF */
};
-static unsigned char u2c_88[512] = {
+static const unsigned char u2c_88[512] = {
0xF2, 0xDB, 0xF0, 0xCE, 0xF2, 0xE8, 0xF2, 0xDD, /* 0x00-0x03 */
0x00, 0x00, 0xC3, 0xC7, 0xF2, 0xE3, 0x00, 0x00, /* 0x04-0x07 */
0xF2, 0xE5, 0xF2, 0xE0, 0xF2, 0xE7, 0xF2, 0xE2, /* 0x08-0x0B */
@@ -7628,7 +7628,7 @@ static unsigned char u2c_88[512] = {
0xE3, 0xFC, 0xBB, 0x73, 0xE3, 0xFA, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_89[512] = {
+static const unsigned char u2c_89[512] = {
0x00, 0x00, 0xDB, 0xCE, 0xBB, 0x6F, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xE7, 0xC2, 0xE7, 0xC9, 0xBD, 0xC6, /* 0x04-0x07 */
0x00, 0x00, 0xE7, 0xCD, 0xBD, 0xCA, 0xE7, 0xC5, /* 0x08-0x0B */
@@ -7696,7 +7696,7 @@ static unsigned char u2c_89[512] = {
0xC5, 0xA9, 0x00, 0x00, 0xF7, 0xFE, 0xF9, 0x4C, /* 0xFC-0xFF */
};
-static unsigned char u2c_8A[512] = {
+static const unsigned char u2c_8A[512] = {
0xA8, 0xA5, 0x00, 0x00, 0xAD, 0x71, 0xAD, 0x72, /* 0x00-0x03 */
0xD0, 0xB0, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xB1, /* 0x04-0x07 */
0xAD, 0x70, 0x00, 0x00, 0xB0, 0x54, 0x00, 0x00, /* 0x08-0x0B */
@@ -7764,7 +7764,7 @@ static unsigned char u2c_8A[512] = {
0xBF, 0xDC, 0x00, 0x00, 0xBF, 0xD5, 0xEB, 0xAE, /* 0xFC-0xFF */
};
-static unsigned char u2c_8B[512] = {
+static const unsigned char u2c_8B[512] = {
0xBF, 0xD1, 0xBF, 0xD6, 0xBF, 0xD7, 0x00, 0x00, /* 0x00-0x03 */
0xC1, 0xC3, 0xEE, 0xA4, 0xEE, 0xAD, 0xEE, 0xAA, /* 0x04-0x07 */
0xEE, 0xAC, 0x00, 0x00, 0xC1, 0xC0, 0xEE, 0xA5, /* 0x08-0x0B */
@@ -7808,7 +7808,7 @@ static unsigned char u2c_8B[512] = {
0xC6, 0x6D, 0x00, 0x00, 0xF9, 0xA9, 0xF9, 0xC8, /* 0x9C-0x9F */
};
-static unsigned char u2c_8C[512] = {
+static const unsigned char u2c_8C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -7876,7 +7876,7 @@ static unsigned char u2c_8C[512] = {
0xC1, 0xCA, 0xC1, 0xC9, 0xF0, 0xF3, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_8D[512] = {
+static const unsigned char u2c_8D[512] = {
0xF0, 0xF6, 0x00, 0x00, 0xF0, 0xF5, 0x00, 0x00, /* 0x00-0x03 */
0xF0, 0xF4, 0xC2, 0xD8, 0xF3, 0x48, 0xF3, 0x49, /* 0x04-0x07 */
0xC3, 0xD8, 0xF3, 0x4A, 0xC3, 0xD9, 0x00, 0x00, /* 0x08-0x0B */
@@ -7944,7 +7944,7 @@ static unsigned char u2c_8D[512] = {
0xBB, 0xB1, 0xE4, 0x5B, 0xE4, 0x61, 0xE4, 0x59, /* 0xFC-0xFF */
};
-static unsigned char u2c_8E[512] = {
+static const unsigned char u2c_8E[512] = {
0xE4, 0x62, 0x00, 0x00, 0xE4, 0x58, 0xE4, 0x5D, /* 0x00-0x03 */
0xE4, 0x63, 0xE4, 0x60, 0xE4, 0x5F, 0xE4, 0x5E, /* 0x04-0x07 */
0x00, 0x00, 0xE4, 0x57, 0xE4, 0x5C, 0x00, 0x00, /* 0x08-0x0B */
@@ -8012,7 +8012,7 @@ static unsigned char u2c_8E[512] = {
0xB6, 0x63, 0x00, 0x00, 0xB8, 0xFD, 0xE0, 0x75, /* 0xFC-0xFF */
};
-static unsigned char u2c_8F[512] = {
+static const unsigned char u2c_8F[512] = {
0xE0, 0x77, 0xE0, 0x76, 0xE0, 0x7B, 0xB8, 0xFB, /* 0x00-0x03 */
0x00, 0x00, 0xE0, 0x78, 0xE0, 0x74, 0xE0, 0x79, /* 0x04-0x07 */
0xE0, 0x7A, 0xB8, 0xFC, 0xB8, 0xFE, 0xE0, 0x7C, /* 0x08-0x0B */
@@ -8080,7 +8080,7 @@ static unsigned char u2c_8F[512] = {
0xD3, 0xF0, 0xB0, 0x6C, 0xD3, 0xEA, 0xD3, 0xED, /* 0xFC-0xFF */
};
-static unsigned char u2c_90[512] = {
+static const unsigned char u2c_90[512] = {
0xB0, 0x68, 0xB0, 0x65, 0xD3, 0xEC, 0xB0, 0x6B, /* 0x00-0x03 */
0xD3, 0xEF, 0xB0, 0x6D, 0xB0, 0x66, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7, 0xE3, /* 0x08-0x0B */
@@ -8148,7 +8148,7 @@ static unsigned char u2c_90[512] = {
0xDC, 0x54, 0xB3, 0xA3, 0xB6, 0x6E, 0xDC, 0x53, /* 0xFC-0xFF */
};
-static unsigned char u2c_91[512] = {
+static const unsigned char u2c_91[512] = {
0xDC, 0x59, 0xDC, 0x58, 0xB6, 0x6B, 0xDC, 0x5C, /* 0x00-0x03 */
0xDC, 0x52, 0xDC, 0x5B, 0xDC, 0x50, 0xDC, 0x5A, /* 0x04-0x07 */
0xDC, 0x55, 0xB6, 0x6D, 0x00, 0x00, 0xE0, 0xAA, /* 0x08-0x0B */
@@ -8216,7 +8216,7 @@ static unsigned char u2c_91[512] = {
0x00, 0x00, 0xDC, 0x6D, 0x00, 0x00, 0xDC, 0x6C, /* 0xFC-0xFF */
};
-static unsigned char u2c_92[512] = {
+static const unsigned char u2c_92[512] = {
0xDC, 0x6A, 0xDC, 0x62, 0xDC, 0x71, 0xDC, 0x65, /* 0x00-0x03 */
0xDC, 0x6F, 0xDC, 0x76, 0xDC, 0x6E, 0xB6, 0x79, /* 0x04-0x07 */
0x00, 0x00, 0xB6, 0x75, 0xDC, 0x63, 0x00, 0x00, /* 0x08-0x0B */
@@ -8284,7 +8284,7 @@ static unsigned char u2c_92[512] = {
0xBF, 0xFB, 0x00, 0x00, 0xEC, 0x41, 0xEB, 0xF8, /* 0xFC-0xFF */
};
-static unsigned char u2c_93[512] = {
+static const unsigned char u2c_93[512] = {
0xEC, 0x43, 0xEB, 0xE9, 0xEB, 0xF6, 0x00, 0x00, /* 0x00-0x03 */
0xBF, 0xFD, 0x00, 0x00, 0xEB, 0xE1, 0x00, 0x00, /* 0x04-0x07 */
0xEB, 0xDF, 0xEC, 0x42, 0x00, 0x00, 0xEC, 0x40, /* 0x08-0x0B */
@@ -8352,7 +8352,7 @@ static unsigned char u2c_93[512] = {
0xF5, 0x40, 0xC4, 0xC3, 0xF4, 0xED, 0xF4, 0xFE, /* 0xFC-0xFF */
};
-static unsigned char u2c_94[512] = {
+static const unsigned char u2c_94[512] = {
0xF4, 0xF4, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xC2, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xF5, 0x44, 0xF4, 0xF6, /* 0x04-0x07 */
0x00, 0x00, 0xF4, 0xFB, 0xF4, 0xFD, 0xF4, 0xE7, /* 0x08-0x0B */
@@ -8389,7 +8389,7 @@ static unsigned char u2c_94[512] = {
0xF9, 0xC0, 0xF9, 0xC1, 0xF9, 0xBF, 0xF9, 0xC9, /* 0x80-0x83 */
};
-static unsigned char u2c_95[512] = {
+static const unsigned char u2c_95[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8451,7 +8451,7 @@ static unsigned char u2c_95[512] = {
0xF6, 0x6C, 0xF6, 0x6B, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char u2c_96[512] = {
+static const unsigned char u2c_96[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8519,7 +8519,7 @@ static unsigned char u2c_96[512] = {
0x00, 0x00, 0xE0, 0xD7, 0x00, 0x00, 0xE4, 0xBD, /* 0xFC-0xFF */
};
-static unsigned char u2c_97[512] = {
+static const unsigned char u2c_97[512] = {
0xBB, 0xDD, 0x00, 0x00, 0xE8, 0xAF, 0x00, 0x00, /* 0x00-0x03 */
0xBE, 0x5D, 0xE8, 0xAD, 0xBE, 0x5E, 0xBE, 0x5F, /* 0x04-0x07 */
0xE8, 0xAE, 0xBE, 0x60, 0x00, 0x00, 0xEC, 0x51, /* 0x08-0x0B */
@@ -8587,7 +8587,7 @@ static unsigned char u2c_97[512] = {
0x00, 0x00, 0xF5, 0x4C, 0xF5, 0x4D, 0xC5, 0x54, /* 0xFC-0xFF */
};
-static unsigned char u2c_98[512] = {
+static const unsigned char u2c_98[512] = {
0xF8, 0x51, 0xAD, 0xB6, 0xB3, 0xBB, 0xB3, 0xBC, /* 0x00-0x03 */
0xD8, 0x4E, 0xB6, 0xB5, 0xB6, 0xB6, 0xDC, 0xAC, /* 0x04-0x07 */
0xB6, 0xB7, 0x00, 0x00, 0xB9, 0x7A, 0x00, 0x00, /* 0x08-0x0B */
@@ -8655,7 +8655,7 @@ static unsigned char u2c_98[512] = {
0xB9, 0x7D, 0xB9, 0xA1, 0xB9, 0xA2, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_99[512] = {
+static const unsigned char u2c_99[512] = {
0xE4, 0xCF, 0x00, 0x00, 0xE4, 0xCE, 0xBB, 0xE5, /* 0x00-0x03 */
0x00, 0x00, 0xBB, 0xE6, 0x00, 0x00, 0xE4, 0xD0, /* 0x04-0x07 */
0xE8, 0xBF, 0xBB, 0xE8, 0xBE, 0x69, 0x00, 0x00, /* 0x08-0x0B */
@@ -8723,7 +8723,7 @@ static unsigned char u2c_99[512] = {
0xEF, 0x62, 0xEF, 0x60, 0xEF, 0x61, 0xC2, 0x40, /* 0xFC-0xFF */
};
-static unsigned char u2c_9A[512] = {
+static const unsigned char u2c_9A[512] = {
0x00, 0x00, 0xC1, 0xFE, 0xEF, 0x58, 0xEF, 0x63, /* 0x00-0x03 */
0xF1, 0xB3, 0xF1, 0xB6, 0xF1, 0xB8, 0xF1, 0xB7, /* 0x04-0x07 */
0x00, 0x00, 0xF1, 0xB1, 0xF1, 0xB5, 0xF1, 0xB0, /* 0x08-0x0B */
@@ -8791,7 +8791,7 @@ static unsigned char u2c_9A[512] = {
0xEF, 0x68, 0xEF, 0x66, 0xEF, 0x65, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_9B[512] = {
+static const unsigned char u2c_9B[512] = {
0x00, 0x00, 0xEF, 0x67, 0x00, 0x00, 0xC3, 0x4F, /* 0x00-0x03 */
0xF1, 0xBC, 0xF1, 0xBD, 0xC3, 0x50, 0x00, 0x00, /* 0x04-0x07 */
0xF1, 0xBB, 0x00, 0x00, 0xF3, 0xC3, 0xF3, 0xC2, /* 0x08-0x0B */
@@ -8859,7 +8859,7 @@ static unsigned char u2c_9B[512] = {
0x00, 0x00, 0xC3, 0x56, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */
};
-static unsigned char u2c_9C[512] = {
+static const unsigned char u2c_9C[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0xF5, 0x6D, 0xF5, 0x73, 0xF5, 0x71, /* 0x04-0x07 */
0xF5, 0x6B, 0xF5, 0x76, 0x00, 0x00, 0xF5, 0x6A, /* 0x08-0x0B */
@@ -8927,7 +8927,7 @@ static unsigned char u2c_9C[512] = {
0xE8, 0xE4, 0xE8, 0xE6, 0x00, 0x00, 0xE8, 0xE7, /* 0xFC-0xFF */
};
-static unsigned char u2c_9D[512] = {
+static const unsigned char u2c_9D[512] = {
0xE8, 0xEA, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xA1, /* 0x00-0x03 */
0xE8, 0xEF, 0xE8, 0xEE, 0xBE, 0x7D, 0xE8, 0xE9, /* 0x04-0x07 */
0xE8, 0xED, 0xBE, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -8995,7 +8995,7 @@ static unsigned char u2c_9D[512] = {
0x00, 0x00, 0xF8, 0xE6, 0xF8, 0xDD, 0xF8, 0xE5, /* 0xFC-0xFF */
};
-static unsigned char u2c_9E[512] = {
+static const unsigned char u2c_9E[512] = {
0xF8, 0xE2, 0xF8, 0xE3, 0xF8, 0xDC, 0xF8, 0xDF, /* 0x00-0x03 */
0xF8, 0xE7, 0xF8, 0xE1, 0xF8, 0xE0, 0xF8, 0xDE, /* 0x04-0x07 */
0x00, 0x00, 0xF8, 0xE4, 0x00, 0x00, 0xF9, 0x5D, /* 0x08-0x0B */
@@ -9063,7 +9063,7 @@ static unsigned char u2c_9E[512] = {
0xF3, 0xF5, 0xE0, 0xEF, 0x00, 0x00, 0xEF, 0xB1, /* 0xFC-0xFF */
};
-static unsigned char u2c_9F[512] = {
+static const unsigned char u2c_9F[512] = {
0xF1, 0xE2, 0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0xF8, 0x78, 0xC6, 0x52, /* 0x04-0x07 */
0x00, 0x00, 0xF9, 0x65, 0xF9, 0x7E, 0x00, 0x00, /* 0x08-0x0B */
@@ -9109,11 +9109,11 @@ static unsigned char u2c_9F[512] = {
0xF9, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA4-0xA7 */
};
-static unsigned char u2c_DC[512] = {
+static const unsigned char u2c_DC[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
};
-static unsigned char u2c_F9[512] = {
+static const unsigned char u2c_F9[512] = {
0xB0, 0x5A, 0xA7, 0xF3, 0xA8, 0xAE, 0xB8, 0xEB, /* 0x00-0x03 */
0xB7, 0xC6, 0xA6, 0xEA, 0xA5, 0x79, 0xC0, 0x74, /* 0x04-0x07 */
0xC0, 0x74, 0xAB, 0xB4, 0xAA, 0xF7, 0xB3, 0xE2, /* 0x08-0x0B */
@@ -9181,7 +9181,7 @@ static unsigned char u2c_F9[512] = {
0xC3, 0xD1, 0xA4, 0xB0, 0xAF, 0xF9, 0xA8, 0xEB, /* 0xFC-0xFF */
};
-static unsigned char u2c_FA[512] = {
+static const unsigned char u2c_FA[512] = {
0xA4, 0xC1, 0xAB, 0xD7, 0xA9, 0xDD, 0xBF, 0x7D, /* 0x00-0x03 */
0xA6, 0x76, 0xAC, 0x7D, 0xBC, 0xC9, 0xBF, 0xE7, /* 0x04-0x07 */
0xA6, 0xE6, 0xAD, 0xB0, 0xA8, 0xA3, 0xB9, 0xF8, /* 0x08-0x0B */
@@ -9196,7 +9196,7 @@ static unsigned char u2c_FA[512] = {
0xC0, 0x5D, 0xC5, 0x62, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */
};
-static unsigned char u2c_FE[512] = {
+static const unsigned char u2c_FE[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */
@@ -9226,7 +9226,7 @@ static unsigned char u2c_FE[512] = {
0xA2, 0x42, 0xA2, 0x4C, 0xA2, 0x4D, 0xA2, 0x4E, /* 0x68-0x6B */
};
-static unsigned char u2c_FF[512] = {
+static const unsigned char u2c_FF[512] = {
0x00, 0x00, 0xA1, 0x49, 0xA1, 0xA8, 0xA1, 0xAD, /* 0x00-0x03 */
0xA2, 0x43, 0xA2, 0x48, 0xA1, 0xAE, 0xA1, 0xA6, /* 0x04-0x07 */
0xA1, 0x5D, 0xA1, 0x5E, 0xA1, 0xAF, 0xA1, 0xCF, /* 0x08-0x0B */
@@ -9288,7 +9288,7 @@ static unsigned char u2c_FF[512] = {
0x00, 0x00, 0xA2, 0x44, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
NULL, NULL, u2c_02, u2c_03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -9322,7 +9322,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, u2c_F9, u2c_FA, NULL, NULL, NULL, u2c_FE, u2c_FF, };
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -9358,7 +9358,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -9397,7 +9397,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(const wchar_t uni,
unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni&0xFF;
unsigned char ch = (uni>>8)&0xFF;
int n;
@@ -9429,7 +9429,7 @@ static int char2uni(const unsigned char *rawstring, int boundlen,
wchar_t *uni)
{
unsigned char ch, cl;
- wchar_t *charset2uni;
+ const wchar_t *charset2uni;
int n;
if (boundlen <= 0)
diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c
index 73293511578..7424929a278 100644
--- a/fs/nls/nls_euc-jp.c
+++ b/fs/nls/nls_euc-jp.c
@@ -57,7 +57,7 @@ static struct nls_table *p_nls;
} while(0)
/* SJIS IBM extended characters to EUC map */
-static unsigned char sjisibm2euc_map[][2] = {
+static const unsigned char sjisibm2euc_map[][2] = {
{0xF3, 0xF3}, {0xF3, 0xF4}, {0xF3, 0xF5}, {0xF3, 0xF6}, {0xF3, 0xF7},
{0xF3, 0xF8}, {0xF3, 0xF9}, {0xF3, 0xFA}, {0xF3, 0xFB}, {0xF3, 0xFC},
{0xF3, 0xFD}, {0xF3, 0xFE}, {0xF4, 0xA1}, {0xF4, 0xA2}, {0xF4, 0xA3},
@@ -243,7 +243,7 @@ static struct {
};
/* EUC to SJIS IBM extended characters map (G3 Upper block) */
-static unsigned char euc2sjisibm_g3upper_map[][2] = {
+static const unsigned char euc2sjisibm_g3upper_map[][2] = {
{0xFA, 0x40}, {0xFA, 0x41}, {0xFA, 0x42}, {0xFA, 0x43}, {0xFA, 0x44},
{0xFA, 0x45}, {0xFA, 0x46}, {0xFA, 0x47}, {0xFA, 0x48}, {0xFA, 0x49},
{0xFA, 0x4A}, {0xFA, 0x4B}, {0xFA, 0x4C}, {0xFA, 0x4D}, {0xFA, 0x4E},
diff --git a/fs/nls/nls_iso8859-1.c b/fs/nls/nls_iso8859-1.c
index 2483c3c6c1c..7b951bb5849 100644
--- a/fs/nls/nls_iso8859-1.c
+++ b/fs/nls/nls_iso8859-1.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x00fd, 0x00fe, 0x00ff,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,11 +132,11 @@ static unsigned char page00[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -172,7 +172,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -210,7 +210,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-13.c b/fs/nls/nls_iso8859-13.c
index 7b8721d7436..c4d52ea9f09 100644
--- a/fs/nls/nls_iso8859-13.c
+++ b/fs/nls/nls_iso8859-13.c
@@ -11,7 +11,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -94,7 +94,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x017c, 0x017e, 0x2019,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -130,7 +130,7 @@ static unsigned char page00[256] = {
0xb8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0xc2, 0xe2, 0x00, 0x00, 0xc0, 0xe0, 0xc3, 0xe3, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0xc7, 0xe7, 0x00, 0x00, 0xcb, 0xeb, /* 0x10-0x17 */
@@ -149,14 +149,14 @@ static unsigned char page01[256] = {
0x00, 0xca, 0xea, 0xdd, 0xfd, 0xde, 0xfe, 0x00, /* 0x78-0x7f */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
0x00, 0xff, 0x00, 0x00, 0xb4, 0xa1, 0xa5, 0x00, /* 0x18-0x1f */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -164,7 +164,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -200,7 +200,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -238,7 +238,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-14.c b/fs/nls/nls_iso8859-14.c
index 2e895e638db..dc02600c7fe 100644
--- a/fs/nls/nls_iso8859-14.c
+++ b/fs/nls/nls_iso8859-14.c
@@ -18,7 +18,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -101,7 +101,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x00fd, 0x0177, 0x00ff,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -137,7 +137,7 @@ static unsigned char page00[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0xff, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -173,7 +173,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page1e[256] = {
+static const unsigned char page1e[256] = {
0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -209,7 +209,7 @@ static unsigned char page1e[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -220,7 +220,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -256,7 +256,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -294,7 +294,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-15.c b/fs/nls/nls_iso8859-15.c
index 5c91592779f..3c7dfc832ef 100644
--- a/fs/nls/nls_iso8859-15.c
+++ b/fs/nls/nls_iso8859-15.c
@@ -11,7 +11,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -94,7 +94,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x00fd, 0x00fe, 0x00ff,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -130,7 +130,7 @@ static unsigned char page00[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -149,7 +149,7 @@ static unsigned char page01[256] = {
0xbe, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -175,7 +175,7 @@ static unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -186,7 +186,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -222,7 +222,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -260,7 +260,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-2.c b/fs/nls/nls_iso8859-2.c
index 892d38fe953..a2d2197e4c7 100644
--- a/fs/nls/nls_iso8859-2.c
+++ b/fs/nls/nls_iso8859-2.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x00fd, 0x0163, 0x02d9,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */
0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -151,7 +151,7 @@ static unsigned char page01[256] = {
0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00, /* 0x78-0x7f */
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -183,11 +183,11 @@ static unsigned char page02[256] = {
0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, page02, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -223,7 +223,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -261,7 +261,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-3.c b/fs/nls/nls_iso8859-3.c
index 49317bcdb4b..a61e0daa3a8 100644
--- a/fs/nls/nls_iso8859-3.c
+++ b/fs/nls/nls_iso8859-3.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x016d, 0x015d, 0x02d9,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0xc6, 0xe6, 0xc5, 0xe5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -151,7 +151,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x00, 0xaf, 0xbf, 0x00, 0x00, 0x00, /* 0x78-0x7f */
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -183,11 +183,11 @@ static unsigned char page02[256] = {
0xa2, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, page02, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -223,7 +223,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -261,7 +261,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-4.c b/fs/nls/nls_iso8859-4.c
index 9f3b9368c2c..e8ff555483b 100644
--- a/fs/nls/nls_iso8859-4.c
+++ b/fs/nls/nls_iso8859-4.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x0169, 0x016b, 0x02d9,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */
0xd0, 0xf0, 0xaa, 0xba, 0x00, 0x00, 0xcc, 0xec, /* 0x10-0x17 */
@@ -151,7 +151,7 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xbe, 0x00, /* 0x78-0x7f */
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -183,11 +183,11 @@ static unsigned char page02[256] = {
0x00, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, page02, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -223,7 +223,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -261,7 +261,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-5.c b/fs/nls/nls_iso8859-5.c
index 001a2bb132c..4721e893012 100644
--- a/fs/nls/nls_iso8859-5.c
+++ b/fs/nls/nls_iso8859-5.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x045c, 0x00a7, 0x045e, 0x045f,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -122,7 +122,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */
};
-static unsigned char page04[256] = {
+static const unsigned char page04[256] = {
0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, /* 0x08-0x0f */
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */
@@ -137,13 +137,13 @@ static unsigned char page04[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff, /* 0x58-0x5f */
};
-static unsigned char page21[256] = {
+static const unsigned char page21[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, /* 0x10-0x17 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -151,7 +151,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, page21, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -187,7 +187,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -225,7 +225,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-6.c b/fs/nls/nls_iso8859-6.c
index 8cec03d6608..01a517d6d30 100644
--- a/fs/nls/nls_iso8859-6.c
+++ b/fs/nls/nls_iso8859-6.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x0000, 0x0000, 0x0000, 0x0000,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -122,7 +122,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */
};
-static unsigned char page06[256] = {
+static const unsigned char page06[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -139,11 +139,11 @@ static unsigned char page06[256] = {
0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, NULL, NULL, page06, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -179,7 +179,7 @@ static unsigned char charset2lower[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -216,7 +216,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-7.c b/fs/nls/nls_iso8859-7.c
index 1be707d5ac3..2d27b93ef19 100644
--- a/fs/nls/nls_iso8859-7.c
+++ b/fs/nls/nls_iso8859-7.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x03cc, 0x03cd, 0x03ce, 0x0000,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -124,7 +124,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */
};
-static unsigned char page02[256] = {
+static const unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -152,7 +152,7 @@ static unsigned char page02[256] = {
0x00, 0x00, 0x00, 0x00, 0xa2, 0xa1, 0x00, 0x00, /* 0xb8-0xbf */
};
-static unsigned char page03[256] = {
+static const unsigned char page03[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -182,13 +182,13 @@ static unsigned char page03[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xc8-0xcf */
};
-static unsigned char page20[256] = {
+static const unsigned char page20[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, /* 0x10-0x17 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, page02, page03, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -196,7 +196,7 @@ static unsigned char *page_uni2charset[256] = {
page20, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -232,7 +232,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -270,7 +270,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_iso8859-9.c b/fs/nls/nls_iso8859-9.c
index 8c0146f7383..694bf070c72 100644
--- a/fs/nls/nls_iso8859-9.c
+++ b/fs/nls/nls_iso8859-9.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x00fc, 0x0131, 0x015f, 0x00ff,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -132,7 +132,7 @@ static unsigned char page00[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */
};
-static unsigned char page01[256] = {
+static const unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -147,11 +147,11 @@ static unsigned char page01[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, /* 0x58-0x5f */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, page01, NULL, NULL, NULL, NULL, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -187,7 +187,7 @@ static unsigned char charset2lower[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -225,7 +225,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_koi8-r.c b/fs/nls/nls_koi8-r.c
index fefbe080726..43875310540 100644
--- a/fs/nls/nls_koi8-r.c
+++ b/fs/nls/nls_koi8-r.c
@@ -13,7 +13,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -96,7 +96,7 @@ static wchar_t charset2uni[256] = {
0x042d, 0x0429, 0x0427, 0x042a,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -131,7 +131,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */
};
-static unsigned char page04[256] = {
+static const unsigned char page04[256] = {
0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */
@@ -145,7 +145,7 @@ static unsigned char page04[256] = {
0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -161,7 +161,7 @@ static unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -169,7 +169,7 @@ static unsigned char page23[256] = {
0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -194,7 +194,7 @@ static unsigned char page25[256] = {
0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -202,7 +202,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -238,7 +238,7 @@ static unsigned char charset2lower[256] = {
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -276,7 +276,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/nls/nls_koi8-u.c b/fs/nls/nls_koi8-u.c
index 015070211f2..8c9f0292b5a 100644
--- a/fs/nls/nls_koi8-u.c
+++ b/fs/nls/nls_koi8-u.c
@@ -11,7 +11,7 @@
#include <linux/nls.h>
#include <linux/errno.h>
-static wchar_t charset2uni[256] = {
+static const wchar_t charset2uni[256] = {
/* 0x00*/
0x0000, 0x0001, 0x0002, 0x0003,
0x0004, 0x0005, 0x0006, 0x0007,
@@ -94,7 +94,7 @@ static wchar_t charset2uni[256] = {
0x042d, 0x0429, 0x0427, 0x042a,
};
-static unsigned char page00[256] = {
+static const unsigned char page00[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -129,7 +129,7 @@ static unsigned char page00[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */
};
-static unsigned char page04[256] = {
+static const unsigned char page04[256] = {
0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */
@@ -152,7 +152,7 @@ static unsigned char page04[256] = {
0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
};
-static unsigned char page22[256] = {
+static const unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -168,7 +168,7 @@ static unsigned char page22[256] = {
0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */
};
-static unsigned char page23[256] = {
+static const unsigned char page23[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -176,7 +176,7 @@ static unsigned char page23[256] = {
0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
};
-static unsigned char page25[256] = {
+static const unsigned char page25[256] = {
0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */
0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */
@@ -201,7 +201,7 @@ static unsigned char page25[256] = {
0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
};
-static unsigned char *page_uni2charset[256] = {
+static const unsigned char *const page_uni2charset[256] = {
page00, NULL, NULL, NULL, page04, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -209,7 +209,7 @@ static unsigned char *page_uni2charset[256] = {
NULL, NULL, page22, page23, NULL, page25, NULL, NULL,
};
-static unsigned char charset2lower[256] = {
+static const unsigned char charset2lower[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -245,7 +245,7 @@ static unsigned char charset2lower[256] = {
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xf8-0xff */
};
-static unsigned char charset2upper[256] = {
+static const unsigned char charset2upper[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
@@ -283,7 +283,7 @@ static unsigned char charset2upper[256] = {
static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
{
- unsigned char *uni2charset;
+ const unsigned char *uni2charset;
unsigned char cl = uni & 0x00ff;
unsigned char ch = (uni & 0xff00) >> 8;
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index c814204d4ea..6cd08dfdc2e 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -61,7 +61,7 @@ static int ntfs_file_open(struct inode *vi, struct file *filp)
{
if (sizeof(unsigned long) < 8) {
if (i_size_read(vi) > MAX_LFS_FILESIZE)
- return -EFBIG;
+ return -EOVERFLOW;
}
return generic_file_open(vi, filp);
}
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 90c4e3a2970..3e76f3b216b 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2381,14 +2381,14 @@ static void ntfs_put_super(struct super_block *sb)
*/
ntfs_commit_inode(vol->mft_ino);
write_inode_now(vol->mft_ino, 1);
- if (!list_empty(&sb->s_dirty)) {
+ if (sb_has_dirty_inodes(sb)) {
const char *s1, *s2;
mutex_lock(&vol->mft_ino->i_mutex);
truncate_inode_pages(vol->mft_ino->i_mapping, 0);
mutex_unlock(&vol->mft_ino->i_mutex);
write_inode_now(vol->mft_ino, 1);
- if (!list_empty(&sb->s_dirty)) {
+ if (sb_has_dirty_inodes(sb)) {
static const char *_s1 = "inodes";
static const char *_s2 = "";
s1 = _s1;
@@ -3080,8 +3080,7 @@ struct kmem_cache *ntfs_inode_cache;
struct kmem_cache *ntfs_big_inode_cache;
/* Init once constructor for the inode slab cache. */
-static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep,
- unsigned long flags)
+static void ntfs_big_inode_init_once(struct kmem_cache *cachep, void *foo)
{
ntfs_inode *ni = (ntfs_inode *)foo;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 34d10452c56..c69c1b30015 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1724,9 +1724,9 @@ out:
return ret;
}
-int ocfs2_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
int ret;
struct buffer_head *di_bh = NULL;
@@ -1877,9 +1877,9 @@ out_write_size:
return copied;
}
-int ocfs2_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
+static int ocfs2_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
int ret;
struct inode *inode = mapping->host;
@@ -1896,6 +1896,8 @@ int ocfs2_write_end(struct file *file, struct address_space *mapping,
const struct address_space_operations ocfs2_aops = {
.readpage = ocfs2_readpage,
.writepage = ocfs2_writepage,
+ .write_begin = ocfs2_write_begin,
+ .write_end = ocfs2_write_end,
.bmap = ocfs2_bmap,
.sync_page = block_sync_page,
.direct_IO = ocfs2_direct_IO,
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 113560877db..503e49232e1 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -44,14 +44,6 @@ int walk_page_buffers( handle_t *handle,
int (*fn)( handle_t *handle,
struct buffer_head *bh));
-int ocfs2_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata);
-
-int ocfs2_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata);
-
int ocfs2_write_end_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata);
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 7453b70c1a1..6a2f143e269 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -586,7 +586,7 @@ bail:
}
static int ocfs2_dir_foreach_blk_id(struct inode *inode,
- unsigned long *f_version,
+ u64 *f_version,
loff_t *f_pos, void *priv,
filldir_t filldir, int *filldir_err)
{
@@ -648,7 +648,7 @@ revalidate:
* not the directory has been modified
* during the copy operation.
*/
- unsigned long version = *f_version;
+ u64 version = *f_version;
unsigned char d_type = DT_UNKNOWN;
if (de->file_type < OCFS2_FT_MAX)
@@ -677,7 +677,7 @@ out:
}
static int ocfs2_dir_foreach_blk_el(struct inode *inode,
- unsigned long *f_version,
+ u64 *f_version,
loff_t *f_pos, void *priv,
filldir_t filldir, int *filldir_err)
{
@@ -798,7 +798,7 @@ out:
return stored;
}
-static int ocfs2_dir_foreach_blk(struct inode *inode, unsigned long *f_version,
+static int ocfs2_dir_foreach_blk(struct inode *inode, u64 *f_version,
loff_t *f_pos, void *priv, filldir_t filldir,
int *filldir_err)
{
@@ -818,7 +818,7 @@ int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv,
filldir_t filldir)
{
int ret = 0, filldir_err = 0;
- unsigned long version = inode->i_version;
+ u64 version = inode->i_version;
while (*f_pos < i_size_read(inode)) {
ret = ocfs2_dir_foreach_blk(inode, &version, f_pos, priv,
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index 7418dc83de1..6639baab079 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -255,9 +255,8 @@ static ssize_t dlmfs_file_write(struct file *filp,
return writelen;
}
-static void dlmfs_init_once(void *foo,
- struct kmem_cache *cachep,
- unsigned long flags)
+static void dlmfs_init_once(struct kmem_cache *cachep,
+ void *foo)
{
struct dlmfs_inode_private *ip =
(struct dlmfs_inode_private *) foo;
@@ -588,13 +587,17 @@ static int __init init_dlmfs_fs(void)
dlmfs_print_version();
+ status = bdi_init(&dlmfs_backing_dev_info);
+ if (status)
+ return status;
+
dlmfs_inode_cache = kmem_cache_create("dlmfs_inode_cache",
sizeof(struct dlmfs_inode_private),
0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD),
dlmfs_init_once);
if (!dlmfs_inode_cache)
- return -ENOMEM;
+ goto bail;
cleanup_inode = 1;
user_dlm_worker = create_singlethread_workqueue("user_dlm");
@@ -611,6 +614,7 @@ bail:
kmem_cache_destroy(dlmfs_inode_cache);
if (cleanup_worker)
destroy_workqueue(user_dlm_worker);
+ bdi_destroy(&dlmfs_backing_dev_info);
} else
printk("OCFS2 User DLM kernel interface loaded\n");
return status;
@@ -624,6 +628,8 @@ static void __exit exit_dlmfs_fs(void)
destroy_workqueue(user_dlm_worker);
kmem_cache_destroy(dlmfs_inode_cache);
+
+ bdi_destroy(&dlmfs_backing_dev_info);
}
MODULE_AUTHOR("Oracle");
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a62b14eb406..f92fe91ff26 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1881,143 +1881,13 @@ out:
return ret;
}
-static inline void
-ocfs2_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
-{
- const struct iovec *iov = *iovp;
- size_t base = *basep;
-
- do {
- int copy = min(bytes, iov->iov_len - base);
-
- bytes -= copy;
- base += copy;
- if (iov->iov_len == base) {
- iov++;
- base = 0;
- }
- } while (bytes);
- *iovp = iov;
- *basep = base;
-}
-
-static struct page * ocfs2_get_write_source(char **ret_src_buf,
- const struct iovec *cur_iov,
- size_t iov_offset)
-{
- int ret;
- char *buf = cur_iov->iov_base + iov_offset;
- struct page *src_page = NULL;
- unsigned long off;
-
- off = (unsigned long)(buf) & ~PAGE_CACHE_MASK;
-
- if (!segment_eq(get_fs(), KERNEL_DS)) {
- /*
- * Pull in the user page. We want to do this outside
- * of the meta data locks in order to preserve locking
- * order in case of page fault.
- */
- ret = get_user_pages(current, current->mm,
- (unsigned long)buf & PAGE_CACHE_MASK, 1,
- 0, 0, &src_page, NULL);
- if (ret == 1)
- *ret_src_buf = kmap(src_page) + off;
- else
- src_page = ERR_PTR(-EFAULT);
- } else {
- *ret_src_buf = buf;
- }
-
- return src_page;
-}
-
-static void ocfs2_put_write_source(struct page *page)
-{
- if (page) {
- kunmap(page);
- page_cache_release(page);
- }
-}
-
-static ssize_t ocfs2_file_buffered_write(struct file *file, loff_t *ppos,
- const struct iovec *iov,
- unsigned long nr_segs,
- size_t count,
- ssize_t o_direct_written)
-{
- int ret = 0;
- ssize_t copied, total = 0;
- size_t iov_offset = 0, bytes;
- loff_t pos;
- const struct iovec *cur_iov = iov;
- struct page *user_page, *page;
- char * uninitialized_var(buf);
- char *dst;
- void *fsdata;
-
- /*
- * handle partial DIO write. Adjust cur_iov if needed.
- */
- ocfs2_set_next_iovec(&cur_iov, &iov_offset, o_direct_written);
-
- do {
- pos = *ppos;
-
- user_page = ocfs2_get_write_source(&buf, cur_iov, iov_offset);
- if (IS_ERR(user_page)) {
- ret = PTR_ERR(user_page);
- goto out;
- }
-
- /* Stay within our page boundaries */
- bytes = min((PAGE_CACHE_SIZE - ((unsigned long)pos & ~PAGE_CACHE_MASK)),
- (PAGE_CACHE_SIZE - ((unsigned long)buf & ~PAGE_CACHE_MASK)));
- /* Stay within the vector boundary */
- bytes = min_t(size_t, bytes, cur_iov->iov_len - iov_offset);
- /* Stay within count */
- bytes = min(bytes, count);
-
- page = NULL;
- ret = ocfs2_write_begin(file, file->f_mapping, pos, bytes, 0,
- &page, &fsdata);
- if (ret) {
- mlog_errno(ret);
- goto out;
- }
-
- dst = kmap_atomic(page, KM_USER0);
- memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes);
- kunmap_atomic(dst, KM_USER0);
- flush_dcache_page(page);
- ocfs2_put_write_source(user_page);
-
- copied = ocfs2_write_end(file, file->f_mapping, pos, bytes,
- bytes, page, fsdata);
- if (copied < 0) {
- mlog_errno(copied);
- ret = copied;
- goto out;
- }
-
- total += copied;
- *ppos = pos + copied;
- count -= copied;
-
- ocfs2_set_next_iovec(&cur_iov, &iov_offset, copied);
- } while(count);
-
-out:
- return total ? total : ret;
-}
-
static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs,
loff_t pos)
{
int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
- int can_do_direct, sync = 0;
+ int can_do_direct;
ssize_t written = 0;
size_t ocount; /* original count */
size_t count; /* after file limit checks */
@@ -2033,12 +1903,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
if (iocb->ki_left == 0)
return 0;
- ret = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
- if (ret)
- return ret;
-
- count = ocount;
-
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
appending = file->f_flags & O_APPEND ? 1 : 0;
@@ -2082,33 +1946,23 @@ relock:
rw_level = -1;
direct_io = 0;
- sync = 1;
goto relock;
}
- if (!sync && ((file->f_flags & O_SYNC) || IS_SYNC(inode)))
- sync = 1;
-
- /*
- * XXX: Is it ok to execute these checks a second time?
- */
- ret = generic_write_checks(file, ppos, &count, S_ISBLK(inode->i_mode));
- if (ret)
- goto out;
-
- /*
- * Set pos so that sync_page_range_nolock() below understands
- * where to start from. We might've moved it around via the
- * calls above. The range we want to actually sync starts from
- * *ppos here.
- *
- */
- pos = *ppos;
-
/* communicate with ocfs2_dio_end_io */
ocfs2_iocb_set_rw_locked(iocb, rw_level);
if (direct_io) {
+ ret = generic_segment_checks(iov, &nr_segs, &ocount,
+ VERIFY_READ);
+ if (ret)
+ goto out_dio;
+
+ ret = generic_write_checks(file, ppos, &count,
+ S_ISBLK(inode->i_mode));
+ if (ret)
+ goto out_dio;
+
written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
ppos, count, ocount);
if (written < 0) {
@@ -2116,14 +1970,8 @@ relock:
goto out_dio;
}
} else {
- written = ocfs2_file_buffered_write(file, ppos, iov, nr_segs,
- count, written);
- if (written < 0) {
- ret = written;
- if (ret != -EFAULT || ret != -ENOSPC)
- mlog_errno(ret);
- goto out;
- }
+ written = generic_file_aio_write_nolock(iocb, iov, nr_segs,
+ *ppos);
}
out_dio:
@@ -2153,97 +2001,12 @@ out_sems:
if (have_alloc_sem)
up_read(&inode->i_alloc_sem);
- if (written > 0 && sync) {
- ssize_t err;
-
- err = sync_page_range_nolock(inode, file->f_mapping, pos, count);
- if (err < 0)
- written = err;
- }
-
mutex_unlock(&inode->i_mutex);
mlog_exit(ret);
return written ? written : ret;
}
-static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf,
- struct splice_desc *sd)
-{
- int ret, count;
- ssize_t copied = 0;
- struct file *file = sd->u.file;
- unsigned int offset;
- struct page *page = NULL;
- void *fsdata;
- char *src, *dst;
-
- ret = buf->ops->confirm(pipe, buf);
- if (ret)
- goto out;
-
- offset = sd->pos & ~PAGE_CACHE_MASK;
- count = sd->len;
- if (count + offset > PAGE_CACHE_SIZE)
- count = PAGE_CACHE_SIZE - offset;
-
- ret = ocfs2_write_begin(file, file->f_mapping, sd->pos, count, 0,
- &page, &fsdata);
- if (ret) {
- mlog_errno(ret);
- goto out;
- }
-
- src = buf->ops->map(pipe, buf, 1);
- dst = kmap_atomic(page, KM_USER1);
- memcpy(dst + offset, src + buf->offset, count);
- kunmap_atomic(dst, KM_USER1);
- buf->ops->unmap(pipe, buf, src);
-
- copied = ocfs2_write_end(file, file->f_mapping, sd->pos, count, count,
- page, fsdata);
- if (copied < 0) {
- mlog_errno(copied);
- ret = copied;
- goto out;
- }
-out:
-
- return copied ? copied : ret;
-}
-
-static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
- struct file *out,
- loff_t *ppos,
- size_t len,
- unsigned int flags)
-{
- int ret, err;
- struct address_space *mapping = out->f_mapping;
- struct inode *inode = mapping->host;
- struct splice_desc sd = {
- .total_len = len,
- .flags = flags,
- .pos = *ppos,
- .u.file = out,
- };
-
- ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
- if (ret > 0) {
- *ppos += ret;
-
- if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
- err = generic_osync_inode(inode, mapping,
- OSYNC_METADATA|OSYNC_DATA);
- if (err)
- ret = err;
- }
- }
-
- return ret;
-}
-
static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
struct file *out,
loff_t *ppos,
@@ -2273,8 +2036,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
goto out_unlock;
}
- /* ok, we're done with i_size and alloc work */
- ret = __ocfs2_file_splice_write(pipe, out, ppos, len, flags);
+ ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
out_unlock:
ocfs2_rw_unlock(inode, 1);
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 0e2a1b45bf9..be562ac3e89 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1000,9 +1000,7 @@ bail:
return status;
}
-static void ocfs2_inode_init_once(void *data,
- struct kmem_cache *cachep,
- unsigned long flags)
+static void ocfs2_inode_init_once(struct kmem_cache *cachep, void *data)
{
struct ocfs2_inode_info *oi = data;
diff --git a/fs/open.c b/fs/open.c
index 1d9e5e98bf4..75385144df7 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -658,7 +658,8 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
newattrs.ia_gid = group;
}
if (!S_ISDIR(inode->i_mode))
- newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
+ newattrs.ia_valid |=
+ ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
mutex_lock(&inode->i_mutex);
error = notify_change(dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
@@ -757,6 +758,10 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
f->f_op = fops_get(inode->i_fop);
file_move(f, &inode->i_sb->s_files);
+ error = security_dentry_open(f);
+ if (error)
+ goto cleanup_all;
+
if (!open && f->f_op)
open = f->f_op->open;
if (open) {
@@ -1173,7 +1178,7 @@ asmlinkage long sys_vhangup(void)
int generic_file_open(struct inode * inode, struct file * filp)
{
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
- return -EFBIG;
+ return -EOVERFLOW;
return 0;
}
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index dd86be2aa6c..d8817384008 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -415,7 +415,7 @@ static struct file_system_type openprom_fs_type = {
.kill_sb = kill_anon_super,
};
-static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned long flags)
+static void op_inode_init_once(struct kmem_cache * cachep, void *data)
{
struct op_inode_info *oi = (struct op_inode_info *) data;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e5d0953d4db..4fe74d15641 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -199,27 +199,6 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
(task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
security_ptrace(current,task) == 0))
-static int proc_pid_environ(struct task_struct *task, char * buffer)
-{
- int res = 0;
- struct mm_struct *mm = get_task_mm(task);
- if (mm) {
- unsigned int len;
-
- res = -ESRCH;
- if (!ptrace_may_attach(task))
- goto out;
-
- len = mm->env_end - mm->env_start;
- if (len > PAGE_SIZE)
- len = PAGE_SIZE;
- res = access_process_vm(task, mm->env_start, buffer, len, 0);
-out:
- mmput(mm);
- }
- return res;
-}
-
static int proc_pid_cmdline(struct task_struct *task, char * buffer)
{
int res = 0;
@@ -492,7 +471,7 @@ static ssize_t proc_info_read(struct file * file, char __user * buf,
count = PROC_BLOCK_SIZE;
length = -ENOMEM;
- if (!(page = __get_free_page(GFP_KERNEL)))
+ if (!(page = __get_free_page(GFP_TEMPORARY)))
goto out;
length = PROC_I(inode)->op.proc_read(task, (char*)page);
@@ -532,7 +511,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
goto out;
ret = -ENOMEM;
- page = (char *)__get_free_page(GFP_USER);
+ page = (char *)__get_free_page(GFP_TEMPORARY);
if (!page)
goto out;
@@ -602,7 +581,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
goto out;
copied = -ENOMEM;
- page = (char *)__get_free_page(GFP_USER);
+ page = (char *)__get_free_page(GFP_TEMPORARY);
if (!page)
goto out;
@@ -658,6 +637,76 @@ static const struct file_operations proc_mem_operations = {
.open = mem_open,
};
+static ssize_t environ_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
+ char *page;
+ unsigned long src = *ppos;
+ int ret = -ESRCH;
+ struct mm_struct *mm;
+
+ if (!task)
+ goto out_no_task;
+
+ if (!ptrace_may_attach(task))
+ goto out;
+
+ ret = -ENOMEM;
+ page = (char *)__get_free_page(GFP_TEMPORARY);
+ if (!page)
+ goto out;
+
+ ret = 0;
+
+ mm = get_task_mm(task);
+ if (!mm)
+ goto out_free;
+
+ while (count > 0) {
+ int this_len, retval, max_len;
+
+ this_len = mm->env_end - (mm->env_start + src);
+
+ if (this_len <= 0)
+ break;
+
+ max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+ this_len = (this_len > max_len) ? max_len : this_len;
+
+ retval = access_process_vm(task, (mm->env_start + src),
+ page, this_len, 0);
+
+ if (retval <= 0) {
+ ret = retval;
+ break;
+ }
+
+ if (copy_to_user(buf, page, retval)) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret += retval;
+ src += retval;
+ buf += retval;
+ count -= retval;
+ }
+ *ppos = src;
+
+ mmput(mm);
+out_free:
+ free_page((unsigned long) page);
+out:
+ put_task_struct(task);
+out_no_task:
+ return ret;
+}
+
+static const struct file_operations proc_environ_operations = {
+ .read = environ_read,
+};
+
static ssize_t oom_adjust_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -788,7 +837,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
/* No partial writes. */
return -EINVAL;
}
- page = (char*)__get_free_page(GFP_USER);
+ page = (char*)__get_free_page(GFP_TEMPORARY);
if (!page)
return -ENOMEM;
length = -EFAULT;
@@ -954,7 +1003,8 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
char __user *buffer, int buflen)
{
struct inode * inode;
- char *tmp = (char*)__get_free_page(GFP_KERNEL), *path;
+ char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
+ char *path;
int len;
if (!tmp)
@@ -1726,7 +1776,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
goto out;
length = -ENOMEM;
- page = (char*)__get_free_page(GFP_USER);
+ page = (char*)__get_free_page(GFP_TEMPORARY);
if (!page)
goto out;
@@ -2048,7 +2098,7 @@ static const struct pid_entry tgid_base_stuff[] = {
DIR("task", S_IRUGO|S_IXUGO, task),
DIR("fd", S_IRUSR|S_IXUSR, fd),
DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
- INF("environ", S_IRUSR, pid_environ),
+ REG("environ", S_IRUSR, environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
#ifdef CONFIG_SCHED_DEBUG
@@ -2335,7 +2385,7 @@ out_no_task:
static const struct pid_entry tid_base_stuff[] = {
DIR("fd", S_IRUSR|S_IXUSR, fd),
DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
- INF("environ", S_IRUSR, pid_environ),
+ REG("environ", S_IRUSR, environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
#ifdef CONFIG_SCHED_DEBUG
@@ -2585,7 +2635,7 @@ 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.
*/
- tid = filp->f_version;
+ tid = (int)filp->f_version;
filp->f_version = 0;
for (task = first_tid(leader, tid, pos - 2);
task;
@@ -2594,7 +2644,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
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 */
- filp->f_version = tid;
+ filp->f_version = (u64)tid;
put_task_struct(task);
break;
}
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index b5e7155d30d..1bdb6243575 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -74,7 +74,7 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes,
nbytes = MAX_NON_LFS - pos;
dp = PDE(inode);
- if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+ if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
return -ENOMEM;
while ((nbytes > 0) && !eof) {
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 0e4d37c93ee..99ca00485fc 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -107,7 +107,7 @@ static void proc_destroy_inode(struct inode *inode)
kmem_cache_free(proc_inode_cachep, PROC_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct proc_inode *ei = (struct proc_inode *) foo;
@@ -119,10 +119,8 @@ int __init proc_init_inodecache(void)
proc_inode_cachep = kmem_cache_create("proc_inode_cache",
sizeof(struct proc_inode),
0, (SLAB_RECLAIM_ACCOUNT|
- SLAB_MEM_SPREAD),
+ SLAB_MEM_SPREAD|SLAB_PANIC),
init_once);
- if (proc_inode_cachep == NULL)
- return -ENOMEM;
return 0;
}
diff --git a/fs/proc/mmu.c b/fs/proc/mmu.c
index 25d2d9c6e32..8ae221dfd01 100644
--- a/fs/proc/mmu.c
+++ b/fs/proc/mmu.c
@@ -8,27 +8,10 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/mman.h>
-#include <linux/proc_fs.h>
-#include <linux/mm.h>
-#include <linux/mmzone.h>
-#include <linux/pagemap.h>
-#include <linux/swap.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-#include <linux/seq_file.h>
-#include <linux/hugetlb.h>
+#include <linux/spinlock.h>
#include <linux/vmalloc.h>
-#include <asm/uaccess.h>
+#include <linux/highmem.h>
#include <asm/pgtable.h>
-#include <asm/tlb.h>
-#include <asm/div64.h>
#include "internal.h"
void get_vmalloc_info(struct vmalloc_info *vmi)
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index b872a01ad3a..d6dc72c78bc 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -66,7 +66,6 @@ extern int get_stram_list(char *);
extern int get_filesystem_list(char *);
extern int get_exec_domain_list(char *);
extern int get_dma_list(char *);
-extern int get_locks_status (char *, char **, off_t, int);
static int proc_calc_metrics(char *page, char **start, off_t off,
int count, int *eof, int len)
@@ -230,6 +229,19 @@ static const struct file_operations fragmentation_file_operations = {
.release = seq_release,
};
+extern struct seq_operations pagetypeinfo_op;
+static int pagetypeinfo_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &pagetypeinfo_op);
+}
+
+static const struct file_operations pagetypeinfo_file_ops = {
+ .open = pagetypeinfo_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
extern struct seq_operations zoneinfo_op;
static int zoneinfo_open(struct inode *inode, struct file *file)
{
@@ -514,11 +526,8 @@ static int show_stat(struct seq_file *p, void *v)
}
seq_printf(p, "intr %llu", (unsigned long long)sum);
-#ifndef CONFIG_SMP
- /* Touches too many cache lines on SMP setups */
for (i = 0; i < NR_IRQS; i++)
seq_printf(p, " %u", per_irq_sum[i]);
-#endif
seq_printf(p,
"\nctxt %llu\n"
@@ -624,16 +633,18 @@ static int cmdline_read_proc(char *page, char **start, off_t off,
return proc_calc_metrics(page, start, off, count, eof, len);
}
-static int locks_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int locks_open(struct inode *inode, struct file *filp)
{
- int len = get_locks_status(page, start, off, count);
-
- if (len < count)
- *eof = 1;
- return len;
+ return seq_open(filp, &locks_seq_operations);
}
+static const struct file_operations proc_locks_operations = {
+ .open = locks_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static int execdomains_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -691,7 +702,6 @@ void __init proc_misc_init(void)
#endif
{"filesystems", filesystems_read_proc},
{"cmdline", cmdline_read_proc},
- {"locks", locks_read_proc},
{"execdomains", execdomains_read_proc},
{NULL,}
};
@@ -709,6 +719,7 @@ void __init proc_misc_init(void)
entry->proc_fops = &proc_kmsg_operations;
}
#endif
+ create_seq_entry("locks", 0, &proc_locks_operations);
create_seq_entry("devices", 0, &proc_devinfo_operations);
create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
#ifdef CONFIG_BLOCK
@@ -723,6 +734,7 @@ void __init proc_misc_init(void)
#endif
#endif
create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
+ create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops);
create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
#ifdef CONFIG_BLOCK
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 1bc8d873a9e..638bdb96321 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -433,16 +433,21 @@ static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page,qnx4_get_block, wbc);
}
+
static int qnx4_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,qnx4_get_block);
}
-static int qnx4_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+
+static int qnx4_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct qnx4_inode_info *qnx4_inode = qnx4_i(page->mapping->host);
- return cont_prepare_write(page, from, to, qnx4_get_block,
- &qnx4_inode->mmu_private);
+ struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
+ *pagep = NULL;
+ return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ qnx4_get_block,
+ &qnx4_inode->mmu_private);
}
static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
{
@@ -452,8 +457,8 @@ static const struct address_space_operations qnx4_aops = {
.readpage = qnx4_readpage,
.writepage = qnx4_writepage,
.sync_page = block_sync_page,
- .prepare_write = qnx4_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = qnx4_write_begin,
+ .write_end = generic_write_end,
.bmap = qnx4_bmap
};
@@ -531,8 +536,7 @@ static void qnx4_destroy_inode(struct inode *inode)
kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
}
-static void init_once(void *foo, struct kmem_cache * cachep,
- unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
diff --git a/fs/ramfs/Makefile b/fs/ramfs/Makefile
index 5a0236e02ee..c71e65dcad2 100644
--- a/fs/ramfs/Makefile
+++ b/fs/ramfs/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux ramfs routines.
#
-obj-$(CONFIG_RAMFS) += ramfs.o
+obj-y += ramfs.o
file-mmu-y := file-nommu.o
file-mmu-$(CONFIG_MMU) := file-mmu.o
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 97bdc0b2f9d..b41a514b097 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -29,8 +29,8 @@
const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
- .prepare_write = simple_prepare_write,
- .commit_write = simple_commit_write,
+ .write_begin = simple_write_begin,
+ .write_end = simple_write_end,
.set_page_dirty = __set_page_dirty_no_writeback,
};
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 237fe8b8e81..0989bc2c2f6 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -29,8 +29,8 @@ static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
const struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
- .prepare_write = simple_prepare_write,
- .commit_write = simple_commit_write,
+ .write_begin = simple_write_begin,
+ .write_end = simple_write_end,
.set_page_dirty = __set_page_dirty_no_writeback,
};
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index ef2b46d099f..8428d5b2711 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -223,7 +223,17 @@ module_exit(exit_ramfs_fs)
int __init init_rootfs(void)
{
- return register_filesystem(&rootfs_fs_type);
+ int err;
+
+ err = bdi_init(&ramfs_backing_dev_info);
+ if (err)
+ return err;
+
+ err = register_filesystem(&rootfs_fs_type);
+ if (err)
+ bdi_destroy(&ramfs_backing_dev_info);
+
+ return err;
}
MODULE_LICENSE("GPL");
diff --git a/fs/read_write.c b/fs/read_write.c
index 507ddff48a9..124693e8d3f 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -205,7 +205,7 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count
if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
goto Einval;
- if (unlikely(inode->i_flock && MANDATORY_LOCK(inode))) {
+ if (unlikely(inode->i_flock && mandatory_lock(inode))) {
int retval = locks_mandatory_area(
read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
inode, file, pos, count);
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index b286ccb0858..2a5dd34649b 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -1201,63 +1201,6 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t * hint, b_blocknr_t * new
return ret;
}
-/* These 2 functions are here to provide blocks reservation to the rest of kernel */
-/* Reserve @blocks amount of blocks in fs pointed by @sb. Caller must make sure
- there are actually this much blocks on the FS available */
-void reiserfs_claim_blocks_to_be_allocated(struct super_block *sb, /* super block of
- filesystem where
- blocks should be
- reserved */
- int blocks /* How much to reserve */
- )
-{
-
- /* Fast case, if reservation is zero - exit immediately. */
- if (!blocks)
- return;
-
- spin_lock(&REISERFS_SB(sb)->bitmap_lock);
- REISERFS_SB(sb)->reserved_blocks += blocks;
- spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
-}
-
-/* Unreserve @blocks amount of blocks in fs pointed by @sb */
-void reiserfs_release_claimed_blocks(struct super_block *sb, /* super block of
- filesystem where
- blocks should be
- reserved */
- int blocks /* How much to unreserve */
- )
-{
-
- /* Fast case, if unreservation is zero - exit immediately. */
- if (!blocks)
- return;
-
- spin_lock(&REISERFS_SB(sb)->bitmap_lock);
- REISERFS_SB(sb)->reserved_blocks -= blocks;
- spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
- RFALSE(REISERFS_SB(sb)->reserved_blocks < 0,
- "amount of blocks reserved became zero?");
-}
-
-/* This function estimates how much pages we will be able to write to FS
- used for reiserfs_file_write() purposes for now. */
-int reiserfs_can_fit_pages(struct super_block *sb /* superblock of filesystem
- to estimate space */ )
-{
- int space;
-
- spin_lock(&REISERFS_SB(sb)->bitmap_lock);
- space =
- (SB_FREE_BLOCKS(sb) -
- REISERFS_SB(sb)->reserved_blocks) >> (PAGE_CACHE_SHIFT -
- sb->s_blocksize_bits);
- spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
-
- return space > 0 ? space : 0;
-}
-
void reiserfs_cache_bitmap_metadata(struct super_block *sb,
struct buffer_head *bh,
struct reiserfs_bitmap_info *info)
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index ffbfc2caaf2..e6b03d2020c 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -121,6 +121,16 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
continue;
d_reclen = entry_length(bh, ih, entry_num);
d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh);
+
+ if (d_reclen <= 0 ||
+ d_name + d_reclen > bh->b_data + bh->b_size) {
+ /* There is corrupted data in entry,
+ * We'd better stop here */
+ pathrelse(&path_to_entry);
+ ret = -EIO;
+ goto out;
+ }
+
if (!d_name[d_reclen - 1])
d_reclen = strlen(d_name);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 2070aeee2a5..a804903d31d 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -153,608 +153,6 @@ static int reiserfs_sync_file(struct file *p_s_filp,
return (n_err < 0) ? -EIO : 0;
}
-/* I really do not want to play with memory shortage right now, so
- to simplify the code, we are not going to write more than this much pages at
- a time. This still should considerably improve performance compared to 4k
- at a time case. This is 32 pages of 4k size. */
-#define REISERFS_WRITE_PAGES_AT_A_TIME (128 * 1024) / PAGE_CACHE_SIZE
-
-/* Allocates blocks for a file to fulfil write request.
- Maps all unmapped but prepared pages from the list.
- Updates metadata with newly allocated blocknumbers as needed */
-static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handle *th, struct inode *inode, /* Inode we work with */
- loff_t pos, /* Writing position */
- int num_pages, /* number of pages write going
- to touch */
- int write_bytes, /* amount of bytes to write */
- struct page **prepared_pages, /* array of
- prepared pages
- */
- int blocks_to_allocate /* Amount of blocks we
- need to allocate to
- fit the data into file
- */
- )
-{
- struct cpu_key key; // cpu key of item that we are going to deal with
- struct item_head *ih; // pointer to item head that we are going to deal with
- struct buffer_head *bh; // Buffer head that contains items that we are going to deal with
- __le32 *item; // pointer to item we are going to deal with
- INITIALIZE_PATH(path); // path to item, that we are going to deal with.
- b_blocknr_t *allocated_blocks; // Pointer to a place where allocated blocknumbers would be stored.
- reiserfs_blocknr_hint_t hint; // hint structure for block allocator.
- size_t res; // return value of various functions that we call.
- int curr_block; // current block used to keep track of unmapped blocks.
- int i; // loop counter
- int itempos; // position in item
- unsigned int from = (pos & (PAGE_CACHE_SIZE - 1)); // writing position in
- // first page
- unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1; /* last modified byte offset in last page */
- __u64 hole_size; // amount of blocks for a file hole, if it needed to be created.
- int modifying_this_item = 0; // Flag for items traversal code to keep track
- // of the fact that we already prepared
- // current block for journal
- int will_prealloc = 0;
- RFALSE(!blocks_to_allocate,
- "green-9004: tried to allocate zero blocks?");
-
- /* only preallocate if this is a small write */
- if (REISERFS_I(inode)->i_prealloc_count ||
- (!(write_bytes & (inode->i_sb->s_blocksize - 1)) &&
- blocks_to_allocate <
- REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
- will_prealloc =
- REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize;
-
- allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
- sizeof(b_blocknr_t), GFP_NOFS);
- if (!allocated_blocks)
- return -ENOMEM;
-
- /* First we compose a key to point at the writing position, we want to do
- that outside of any locking region. */
- make_cpu_key(&key, inode, pos + 1, TYPE_ANY, 3 /*key length */ );
-
- /* If we came here, it means we absolutely need to open a transaction,
- since we need to allocate some blocks */
- reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that.
- res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb)); // Wish I know if this number enough
- if (res)
- goto error_exit;
- reiserfs_update_inode_transaction(inode);
-
- /* Look for the in-tree position of our write, need path for block allocator */
- res = search_for_position_by_key(inode->i_sb, &key, &path);
- if (res == IO_ERROR) {
- res = -EIO;
- goto error_exit;
- }
-
- /* Allocate blocks */
- /* First fill in "hint" structure for block allocator */
- hint.th = th; // transaction handle.
- hint.path = &path; // Path, so that block allocator can determine packing locality or whatever it needs to determine.
- hint.inode = inode; // Inode is needed by block allocator too.
- hint.search_start = 0; // We have no hint on where to search free blocks for block allocator.
- hint.key = key.on_disk_key; // on disk key of file.
- hint.block = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9); // Number of disk blocks this file occupies already.
- hint.formatted_node = 0; // We are allocating blocks for unformatted node.
- hint.preallocate = will_prealloc;
-
- /* Call block allocator to allocate blocks */
- res =
- reiserfs_allocate_blocknrs(&hint, allocated_blocks,
- blocks_to_allocate, blocks_to_allocate);
- if (res != CARRY_ON) {
- if (res == NO_DISK_SPACE) {
- /* We flush the transaction in case of no space. This way some
- blocks might become free */
- SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
- res = restart_transaction(th, inode, &path);
- if (res)
- goto error_exit;
-
- /* We might have scheduled, so search again */
- res =
- search_for_position_by_key(inode->i_sb, &key,
- &path);
- if (res == IO_ERROR) {
- res = -EIO;
- goto error_exit;
- }
-
- /* update changed info for hint structure. */
- res =
- reiserfs_allocate_blocknrs(&hint, allocated_blocks,
- blocks_to_allocate,
- blocks_to_allocate);
- if (res != CARRY_ON) {
- res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
- pathrelse(&path);
- goto error_exit;
- }
- } else {
- res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
- pathrelse(&path);
- goto error_exit;
- }
- }
-#ifdef __BIG_ENDIAN
- // Too bad, I have not found any way to convert a given region from
- // cpu format to little endian format
- {
- int i;
- for (i = 0; i < blocks_to_allocate; i++)
- allocated_blocks[i] = cpu_to_le32(allocated_blocks[i]);
- }
-#endif
-
- /* Blocks allocating well might have scheduled and tree might have changed,
- let's search the tree again */
- /* find where in the tree our write should go */
- res = search_for_position_by_key(inode->i_sb, &key, &path);
- if (res == IO_ERROR) {
- res = -EIO;
- goto error_exit_free_blocks;
- }
-
- bh = get_last_bh(&path); // Get a bufferhead for last element in path.
- ih = get_ih(&path); // Get a pointer to last item head in path.
- item = get_item(&path); // Get a pointer to last item in path
-
- /* Let's see what we have found */
- if (res != POSITION_FOUND) { /* position not found, this means that we
- might need to append file with holes
- first */
- // Since we are writing past the file's end, we need to find out if
- // there is a hole that needs to be inserted before our writing
- // position, and how many blocks it is going to cover (we need to
- // populate pointers to file blocks representing the hole with zeros)
-
- {
- int item_offset = 1;
- /*
- * if ih is stat data, its offset is 0 and we don't want to
- * add 1 to pos in the hole_size calculation
- */
- if (is_statdata_le_ih(ih))
- item_offset = 0;
- hole_size = (pos + item_offset -
- (le_key_k_offset
- (get_inode_item_key_version(inode),
- &(ih->ih_key)) + op_bytes_number(ih,
- inode->
- i_sb->
- s_blocksize)))
- >> inode->i_sb->s_blocksize_bits;
- }
-
- if (hole_size > 0) {
- int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize) / UNFM_P_SIZE); // How much data to insert first time.
- /* area filled with zeroes, to supply as list of zero blocknumbers
- We allocate it outside of loop just in case loop would spin for
- several iterations. */
- char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway.
- if (!zeros) {
- res = -ENOMEM;
- goto error_exit_free_blocks;
- }
- do {
- to_paste =
- min_t(__u64, hole_size,
- MAX_ITEM_LEN(inode->i_sb->
- s_blocksize) /
- UNFM_P_SIZE);
- if (is_indirect_le_ih(ih)) {
- /* Ok, there is existing indirect item already. Need to append it */
- /* Calculate position past inserted item */
- make_cpu_key(&key, inode,
- le_key_k_offset
- (get_inode_item_key_version
- (inode),
- &(ih->ih_key)) +
- op_bytes_number(ih,
- inode->
- i_sb->
- s_blocksize),
- TYPE_INDIRECT, 3);
- res =
- reiserfs_paste_into_item(th, &path,
- &key,
- inode,
- (char *)
- zeros,
- UNFM_P_SIZE
- *
- to_paste);
- if (res) {
- kfree(zeros);
- goto error_exit_free_blocks;
- }
- } else if (is_statdata_le_ih(ih)) {
- /* No existing item, create it */
- /* item head for new item */
- struct item_head ins_ih;
-
- /* create a key for our new item */
- make_cpu_key(&key, inode, 1,
- TYPE_INDIRECT, 3);
-
- /* Create new item head for our new item */
- make_le_item_head(&ins_ih, &key,
- key.version, 1,
- TYPE_INDIRECT,
- to_paste *
- UNFM_P_SIZE,
- 0 /* free space */ );
-
- /* Find where such item should live in the tree */
- res =
- search_item(inode->i_sb, &key,
- &path);
- if (res != ITEM_NOT_FOUND) {
- /* item should not exist, otherwise we have error */
- if (res != -ENOSPC) {
- reiserfs_warning(inode->
- i_sb,
- "green-9008: search_by_key (%K) returned %d",
- &key,
- res);
- }
- res = -EIO;
- kfree(zeros);
- goto error_exit_free_blocks;
- }
- res =
- reiserfs_insert_item(th, &path,
- &key, &ins_ih,
- inode,
- (char *)zeros);
- } else {
- reiserfs_panic(inode->i_sb,
- "green-9011: Unexpected key type %K\n",
- &key);
- }
- if (res) {
- kfree(zeros);
- goto error_exit_free_blocks;
- }
- /* Now we want to check if transaction is too full, and if it is
- we restart it. This will also free the path. */
- if (journal_transaction_should_end
- (th, th->t_blocks_allocated)) {
- inode->i_size = cpu_key_k_offset(&key) +
- (to_paste << inode->i_blkbits);
- res =
- restart_transaction(th, inode,
- &path);
- if (res) {
- pathrelse(&path);
- kfree(zeros);
- goto error_exit;
- }
- }
-
- /* Well, need to recalculate path and stuff */
- set_cpu_key_k_offset(&key,
- cpu_key_k_offset(&key) +
- (to_paste << inode->
- i_blkbits));
- res =
- search_for_position_by_key(inode->i_sb,
- &key, &path);
- if (res == IO_ERROR) {
- res = -EIO;
- kfree(zeros);
- goto error_exit_free_blocks;
- }
- bh = get_last_bh(&path);
- ih = get_ih(&path);
- item = get_item(&path);
- hole_size -= to_paste;
- } while (hole_size);
- kfree(zeros);
- }
- }
- // Go through existing indirect items first
- // replace all zeroes with blocknumbers from list
- // Note that if no corresponding item was found, by previous search,
- // it means there are no existing in-tree representation for file area
- // we are going to overwrite, so there is nothing to scan through for holes.
- for (curr_block = 0, itempos = path.pos_in_item;
- curr_block < blocks_to_allocate && res == POSITION_FOUND;) {
- retry:
-
- if (itempos >= ih_item_len(ih) / UNFM_P_SIZE) {
- /* We run out of data in this indirect item, let's look for another
- one. */
- /* First if we are already modifying current item, log it */
- if (modifying_this_item) {
- journal_mark_dirty(th, inode->i_sb, bh);
- modifying_this_item = 0;
- }
- /* Then set the key to look for a new indirect item (offset of old
- item is added to old item length */
- set_cpu_key_k_offset(&key,
- le_key_k_offset
- (get_inode_item_key_version(inode),
- &(ih->ih_key)) +
- op_bytes_number(ih,
- inode->i_sb->
- s_blocksize));
- /* Search ofor position of new key in the tree. */
- res =
- search_for_position_by_key(inode->i_sb, &key,
- &path);
- if (res == IO_ERROR) {
- res = -EIO;
- goto error_exit_free_blocks;
- }
- bh = get_last_bh(&path);
- ih = get_ih(&path);
- item = get_item(&path);
- itempos = path.pos_in_item;
- continue; // loop to check all kinds of conditions and so on.
- }
- /* Ok, we have correct position in item now, so let's see if it is
- representing file hole (blocknumber is zero) and fill it if needed */
- if (!item[itempos]) {
- /* Ok, a hole. Now we need to check if we already prepared this
- block to be journaled */
- while (!modifying_this_item) { // loop until succeed
- /* Well, this item is not journaled yet, so we must prepare
- it for journal first, before we can change it */
- struct item_head tmp_ih; // We copy item head of found item,
- // here to detect if fs changed under
- // us while we were preparing for
- // journal.
- int fs_gen; // We store fs generation here to find if someone
- // changes fs under our feet
-
- copy_item_head(&tmp_ih, ih); // Remember itemhead
- fs_gen = get_generation(inode->i_sb); // remember fs generation
- reiserfs_prepare_for_journal(inode->i_sb, bh, 1); // Prepare a buffer within which indirect item is stored for changing.
- if (fs_changed(fs_gen, inode->i_sb)
- && item_moved(&tmp_ih, &path)) {
- // Sigh, fs was changed under us, we need to look for new
- // location of item we are working with
-
- /* unmark prepaerd area as journaled and search for it's
- new position */
- reiserfs_restore_prepared_buffer(inode->
- i_sb,
- bh);
- res =
- search_for_position_by_key(inode->
- i_sb,
- &key,
- &path);
- if (res == IO_ERROR) {
- res = -EIO;
- goto error_exit_free_blocks;
- }
- bh = get_last_bh(&path);
- ih = get_ih(&path);
- item = get_item(&path);
- itempos = path.pos_in_item;
- goto retry;
- }
- modifying_this_item = 1;
- }
- item[itempos] = allocated_blocks[curr_block]; // Assign new block
- curr_block++;
- }
- itempos++;
- }
-
- if (modifying_this_item) { // We need to log last-accessed block, if it
- // was modified, but not logged yet.
- journal_mark_dirty(th, inode->i_sb, bh);
- }
-
- if (curr_block < blocks_to_allocate) {
- // Oh, well need to append to indirect item, or to create indirect item
- // if there weren't any
- if (is_indirect_le_ih(ih)) {
- // Existing indirect item - append. First calculate key for append
- // position. We do not need to recalculate path as it should
- // already point to correct place.
- make_cpu_key(&key, inode,
- le_key_k_offset(get_inode_item_key_version
- (inode),
- &(ih->ih_key)) +
- op_bytes_number(ih,
- inode->i_sb->s_blocksize),
- TYPE_INDIRECT, 3);
- res =
- reiserfs_paste_into_item(th, &path, &key, inode,
- (char *)(allocated_blocks +
- curr_block),
- UNFM_P_SIZE *
- (blocks_to_allocate -
- curr_block));
- if (res) {
- goto error_exit_free_blocks;
- }
- } else if (is_statdata_le_ih(ih)) {
- // Last found item was statdata. That means we need to create indirect item.
- struct item_head ins_ih; /* itemhead for new item */
-
- /* create a key for our new item */
- make_cpu_key(&key, inode, 1, TYPE_INDIRECT, 3); // Position one,
- // because that's
- // where first
- // indirect item
- // begins
- /* Create new item head for our new item */
- make_le_item_head(&ins_ih, &key, key.version, 1,
- TYPE_INDIRECT,
- (blocks_to_allocate -
- curr_block) * UNFM_P_SIZE,
- 0 /* free space */ );
- /* Find where such item should live in the tree */
- res = search_item(inode->i_sb, &key, &path);
- if (res != ITEM_NOT_FOUND) {
- /* Well, if we have found such item already, or some error
- occured, we need to warn user and return error */
- if (res != -ENOSPC) {
- reiserfs_warning(inode->i_sb,
- "green-9009: search_by_key (%K) "
- "returned %d", &key,
- res);
- }
- res = -EIO;
- goto error_exit_free_blocks;
- }
- /* Insert item into the tree with the data as its body */
- res =
- reiserfs_insert_item(th, &path, &key, &ins_ih,
- inode,
- (char *)(allocated_blocks +
- curr_block));
- } else {
- reiserfs_panic(inode->i_sb,
- "green-9010: unexpected item type for key %K\n",
- &key);
- }
- }
- // the caller is responsible for closing the transaction
- // unless we return an error, they are also responsible for logging
- // the inode.
- //
- pathrelse(&path);
- /*
- * cleanup prellocation from previous writes
- * if this is a partial block write
- */
- if (write_bytes & (inode->i_sb->s_blocksize - 1))
- reiserfs_discard_prealloc(th, inode);
- reiserfs_write_unlock(inode->i_sb);
-
- // go through all the pages/buffers and map the buffers to newly allocated
- // blocks (so that system knows where to write these pages later).
- curr_block = 0;
- for (i = 0; i < num_pages; i++) {
- struct page *page = prepared_pages[i]; //current page
- struct buffer_head *head = page_buffers(page); // first buffer for a page
- int block_start, block_end; // in-page offsets for buffers.
-
- if (!page_buffers(page))
- reiserfs_panic(inode->i_sb,
- "green-9005: No buffers for prepared page???");
-
- /* For each buffer in page */
- for (bh = head, block_start = 0; bh != head || !block_start;
- block_start = block_end, bh = bh->b_this_page) {
- if (!bh)
- reiserfs_panic(inode->i_sb,
- "green-9006: Allocated but absent buffer for a page?");
- block_end = block_start + inode->i_sb->s_blocksize;
- if (i == 0 && block_end <= from)
- /* if this buffer is before requested data to map, skip it */
- continue;
- if (i == num_pages - 1 && block_start >= to)
- /* If this buffer is after requested data to map, abort
- processing of current page */
- break;
-
- if (!buffer_mapped(bh)) { // Ok, unmapped buffer, need to map it
- map_bh(bh, inode->i_sb,
- le32_to_cpu(allocated_blocks
- [curr_block]));
- curr_block++;
- set_buffer_new(bh);
- }
- }
- }
-
- RFALSE(curr_block > blocks_to_allocate,
- "green-9007: Used too many blocks? weird");
-
- kfree(allocated_blocks);
- return 0;
-
-// Need to deal with transaction here.
- error_exit_free_blocks:
- pathrelse(&path);
- // free blocks
- for (i = 0; i < blocks_to_allocate; i++)
- reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]),
- 1);
-
- error_exit:
- if (th->t_trans_id) {
- int err;
- // update any changes we made to blk count
- mark_inode_dirty(inode);
- err =
- journal_end(th, inode->i_sb,
- JOURNAL_PER_BALANCE_CNT * 3 + 1 +
- 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));
- if (err)
- res = err;
- }
- reiserfs_write_unlock(inode->i_sb);
- kfree(allocated_blocks);
-
- return res;
-}
-
-/* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
-static void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */
- size_t num_pages /* amount of pages */ )
-{
- int i; // loop counter
-
- for (i = 0; i < num_pages; i++) {
- struct page *page = prepared_pages[i];
-
- try_to_free_buffers(page);
- unlock_page(page);
- page_cache_release(page);
- }
-}
-
-/* This function will copy data from userspace to specified pages within
- supplied byte range */
-static int reiserfs_copy_from_user_to_file_region(loff_t pos, /* In-file position */
- int num_pages, /* Number of pages affected */
- int write_bytes, /* Amount of bytes to write */
- struct page **prepared_pages, /* pointer to
- array to
- prepared pages
- */
- const char __user * buf /* Pointer to user-supplied
- data */
- )
-{
- long page_fault = 0; // status of copy_from_user.
- int i; // loop counter.
- int offset; // offset in page
-
- for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
- i++, offset = 0) {
- size_t count = min_t(size_t, PAGE_CACHE_SIZE - offset, write_bytes); // How much of bytes to write to this page
- struct page *page = prepared_pages[i]; // Current page we process.
-
- fault_in_pages_readable(buf, count);
-
- /* Copy data from userspace to the current page */
- kmap(page);
- page_fault = __copy_from_user(page_address(page) + offset, buf, count); // Copy the data.
- /* Flush processor's dcache for this page */
- flush_dcache_page(page);
- kunmap(page);
- buf += count;
- write_bytes -= count;
-
- if (page_fault)
- break; // Was there a fault? abort.
- }
-
- return page_fault ? -EFAULT : 0;
-}
-
/* taken fs/buffer.c:__block_commit_write */
int reiserfs_commit_page(struct inode *inode, struct page *page,
unsigned from, unsigned to)
@@ -824,432 +222,6 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
return ret;
}
-/* Submit pages for write. This was separated from actual file copying
- because we might want to allocate block numbers in-between.
- This function assumes that caller will adjust file size to correct value. */
-static int reiserfs_submit_file_region_for_write(struct reiserfs_transaction_handle *th, struct inode *inode, loff_t pos, /* Writing position offset */
- size_t num_pages, /* Number of pages to write */
- size_t write_bytes, /* number of bytes to write */
- struct page **prepared_pages /* list of pages */
- )
-{
- int status; // return status of block_commit_write.
- int retval = 0; // Return value we are going to return.
- int i; // loop counter
- int offset; // Writing offset in page.
- int orig_write_bytes = write_bytes;
- int sd_update = 0;
-
- for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
- i++, offset = 0) {
- int count = min_t(int, PAGE_CACHE_SIZE - offset, write_bytes); // How much of bytes to write to this page
- struct page *page = prepared_pages[i]; // Current page we process.
-
- status =
- reiserfs_commit_page(inode, page, offset, offset + count);
- if (status)
- retval = status; // To not overcomplicate matters We are going to
- // submit all the pages even if there was error.
- // we only remember error status to report it on
- // exit.
- write_bytes -= count;
- }
- /* now that we've gotten all the ordered buffers marked dirty,
- * we can safely update i_size and close any running transaction
- */
- if (pos + orig_write_bytes > inode->i_size) {
- inode->i_size = pos + orig_write_bytes; // Set new size
- /* If the file have grown so much that tail packing is no
- * longer possible, reset "need to pack" flag */
- if ((have_large_tails(inode->i_sb) &&
- inode->i_size > i_block_size(inode) * 4) ||
- (have_small_tails(inode->i_sb) &&
- inode->i_size > i_block_size(inode)))
- REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
- else if ((have_large_tails(inode->i_sb) &&
- inode->i_size < i_block_size(inode) * 4) ||
- (have_small_tails(inode->i_sb) &&
- inode->i_size < i_block_size(inode)))
- REISERFS_I(inode)->i_flags |= i_pack_on_close_mask;
-
- if (th->t_trans_id) {
- reiserfs_write_lock(inode->i_sb);
- // this sets the proper flags for O_SYNC to trigger a commit
- mark_inode_dirty(inode);
- reiserfs_write_unlock(inode->i_sb);
- } else {
- reiserfs_write_lock(inode->i_sb);
- reiserfs_update_inode_transaction(inode);
- mark_inode_dirty(inode);
- reiserfs_write_unlock(inode->i_sb);
- }
-
- sd_update = 1;
- }
- if (th->t_trans_id) {
- reiserfs_write_lock(inode->i_sb);
- if (!sd_update)
- mark_inode_dirty(inode);
- status = journal_end(th, th->t_super, th->t_blocks_allocated);
- if (status)
- retval = status;
- reiserfs_write_unlock(inode->i_sb);
- }
- th->t_trans_id = 0;
-
- /*
- * we have to unlock the pages after updating i_size, otherwise
- * we race with writepage
- */
- for (i = 0; i < num_pages; i++) {
- struct page *page = prepared_pages[i];
- unlock_page(page);
- mark_page_accessed(page);
- page_cache_release(page);
- }
- return retval;
-}
-
-/* Look if passed writing region is going to touch file's tail
- (if it is present). And if it is, convert the tail to unformatted node */
-static int reiserfs_check_for_tail_and_convert(struct inode *inode, /* inode to deal with */
- loff_t pos, /* Writing position */
- int write_bytes /* amount of bytes to write */
- )
-{
- INITIALIZE_PATH(path); // needed for search_for_position
- struct cpu_key key; // Key that would represent last touched writing byte.
- struct item_head *ih; // item header of found block;
- int res; // Return value of various functions we call.
- int cont_expand_offset; // We will put offset for generic_cont_expand here
- // This can be int just because tails are created
- // only for small files.
-
-/* this embodies a dependency on a particular tail policy */
- if (inode->i_size >= inode->i_sb->s_blocksize * 4) {
- /* such a big files do not have tails, so we won't bother ourselves
- to look for tails, simply return */
- return 0;
- }
-
- reiserfs_write_lock(inode->i_sb);
- /* find the item containing the last byte to be written, or if
- * writing past the end of the file then the last item of the
- * file (and then we check its type). */
- make_cpu_key(&key, inode, pos + write_bytes + 1, TYPE_ANY,
- 3 /*key length */ );
- res = search_for_position_by_key(inode->i_sb, &key, &path);
- if (res == IO_ERROR) {
- reiserfs_write_unlock(inode->i_sb);
- return -EIO;
- }
- ih = get_ih(&path);
- res = 0;
- if (is_direct_le_ih(ih)) {
- /* Ok, closest item is file tail (tails are stored in "direct"
- * items), so we need to unpack it. */
- /* To not overcomplicate matters, we just call generic_cont_expand
- which will in turn call other stuff and finally will boil down to
- reiserfs_get_block() that would do necessary conversion. */
- cont_expand_offset =
- le_key_k_offset(get_inode_item_key_version(inode),
- &(ih->ih_key));
- pathrelse(&path);
- res = generic_cont_expand(inode, cont_expand_offset);
- } else
- pathrelse(&path);
-
- reiserfs_write_unlock(inode->i_sb);
- return res;
-}
-
-/* This function locks pages starting from @pos for @inode.
- @num_pages pages are locked and stored in
- @prepared_pages array. Also buffers are allocated for these pages.
- First and last page of the region is read if it is overwritten only
- partially. If last page did not exist before write (file hole or file
- append), it is zeroed, then.
- Returns number of unallocated blocks that should be allocated to cover
- new file data.*/
-static int reiserfs_prepare_file_region_for_write(struct inode *inode
- /* Inode of the file */ ,
- loff_t pos, /* position in the file */
- size_t num_pages, /* number of pages to
- prepare */
- size_t write_bytes, /* Amount of bytes to be
- overwritten from
- @pos */
- struct page **prepared_pages /* pointer to array
- where to store
- prepared pages */
- )
-{
- int res = 0; // Return values of different functions we call.
- unsigned long index = pos >> PAGE_CACHE_SHIFT; // Offset in file in pages.
- int from = (pos & (PAGE_CACHE_SIZE - 1)); // Writing offset in first page
- int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
- /* offset of last modified byte in last
- page */
- struct address_space *mapping = inode->i_mapping; // Pages are mapped here.
- int i; // Simple counter
- int blocks = 0; /* Return value (blocks that should be allocated) */
- struct buffer_head *bh, *head; // Current bufferhead and first bufferhead
- // of a page.
- unsigned block_start, block_end; // Starting and ending offsets of current
- // buffer in the page.
- struct buffer_head *wait[2], **wait_bh = wait; // Buffers for page, if
- // Page appeared to be not up
- // to date. Note how we have
- // at most 2 buffers, this is
- // because we at most may
- // partially overwrite two
- // buffers for one page. One at // the beginning of write area
- // and one at the end.
- // Everything inthe middle gets // overwritten totally.
-
- struct cpu_key key; // cpu key of item that we are going to deal with
- struct item_head *ih = NULL; // pointer to item head that we are going to deal with
- struct buffer_head *itembuf = NULL; // Buffer head that contains items that we are going to deal with
- INITIALIZE_PATH(path); // path to item, that we are going to deal with.
- __le32 *item = NULL; // pointer to item we are going to deal with
- int item_pos = -1; /* Position in indirect item */
-
- if (num_pages < 1) {
- reiserfs_warning(inode->i_sb,
- "green-9001: reiserfs_prepare_file_region_for_write "
- "called with zero number of pages to process");
- return -EFAULT;
- }
-
- /* We have 2 loops for pages. In first loop we grab and lock the pages, so
- that nobody would touch these until we release the pages. Then
- we'd start to deal with mapping buffers to blocks. */
- for (i = 0; i < num_pages; i++) {
- prepared_pages[i] = grab_cache_page(mapping, index + i); // locks the page
- if (!prepared_pages[i]) {
- res = -ENOMEM;
- goto failed_page_grabbing;
- }
- if (!page_has_buffers(prepared_pages[i]))
- create_empty_buffers(prepared_pages[i],
- inode->i_sb->s_blocksize, 0);
- }
-
- /* Let's count amount of blocks for a case where all the blocks
- overwritten are new (we will substract already allocated blocks later) */
- if (num_pages > 2)
- /* These are full-overwritten pages so we count all the blocks in
- these pages are counted as needed to be allocated */
- blocks =
- (num_pages - 2) << (PAGE_CACHE_SHIFT - inode->i_blkbits);
-
- /* count blocks needed for first page (possibly partially written) */
- blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_blkbits) + !!(from & (inode->i_sb->s_blocksize - 1)); /* roundup */
-
- /* Now we account for last page. If last page == first page (we
- overwrite only one page), we substract all the blocks past the
- last writing position in a page out of already calculated number
- of blocks */
- blocks += ((num_pages > 1) << (PAGE_CACHE_SHIFT - inode->i_blkbits)) -
- ((PAGE_CACHE_SIZE - to) >> inode->i_blkbits);
- /* Note how we do not roundup here since partial blocks still
- should be allocated */
-
- /* Now if all the write area lies past the file end, no point in
- maping blocks, since there is none, so we just zero out remaining
- parts of first and last pages in write area (if needed) */
- if ((pos & ~((loff_t) PAGE_CACHE_SIZE - 1)) > inode->i_size) {
- if (from != 0) /* First page needs to be partially zeroed */
- zero_user_page(prepared_pages[0], 0, from, KM_USER0);
-
- if (to != PAGE_CACHE_SIZE) /* Last page needs to be partially zeroed */
- zero_user_page(prepared_pages[num_pages-1], to,
- PAGE_CACHE_SIZE - to, KM_USER0);
-
- /* Since all blocks are new - use already calculated value */
- return blocks;
- }
-
- /* Well, since we write somewhere into the middle of a file, there is
- possibility we are writing over some already allocated blocks, so
- let's map these blocks and substract number of such blocks out of blocks
- we need to allocate (calculated above) */
- /* Mask write position to start on blocksize, we do it out of the
- loop for performance reasons */
- pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
- /* Set cpu key to the starting position in a file (on left block boundary) */
- make_cpu_key(&key, inode,
- 1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)),
- TYPE_ANY, 3 /*key length */ );
-
- reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
- for (i = 0; i < num_pages; i++) {
-
- head = page_buffers(prepared_pages[i]);
- /* For each buffer in the page */
- for (bh = head, block_start = 0; bh != head || !block_start;
- block_start = block_end, bh = bh->b_this_page) {
- if (!bh)
- reiserfs_panic(inode->i_sb,
- "green-9002: Allocated but absent buffer for a page?");
- /* Find where this buffer ends */
- block_end = block_start + inode->i_sb->s_blocksize;
- if (i == 0 && block_end <= from)
- /* if this buffer is before requested data to map, skip it */
- continue;
-
- if (i == num_pages - 1 && block_start >= to) {
- /* If this buffer is after requested data to map, abort
- processing of current page */
- break;
- }
-
- if (buffer_mapped(bh) && bh->b_blocknr != 0) {
- /* This is optimisation for a case where buffer is mapped
- and have blocknumber assigned. In case significant amount
- of such buffers are present, we may avoid some amount
- of search_by_key calls.
- Probably it would be possible to move parts of this code
- out of BKL, but I afraid that would overcomplicate code
- without any noticeable benefit.
- */
- item_pos++;
- /* Update the key */
- set_cpu_key_k_offset(&key,
- cpu_key_k_offset(&key) +
- inode->i_sb->s_blocksize);
- blocks--; // Decrease the amount of blocks that need to be
- // allocated
- continue; // Go to the next buffer
- }
-
- if (!itembuf || /* if first iteration */
- item_pos >= ih_item_len(ih) / UNFM_P_SIZE) { /* or if we progressed past the
- current unformatted_item */
- /* Try to find next item */
- res =
- search_for_position_by_key(inode->i_sb,
- &key, &path);
- /* Abort if no more items */
- if (res != POSITION_FOUND) {
- /* make sure later loops don't use this item */
- itembuf = NULL;
- item = NULL;
- break;
- }
-
- /* Update information about current indirect item */
- itembuf = get_last_bh(&path);
- ih = get_ih(&path);
- item = get_item(&path);
- item_pos = path.pos_in_item;
-
- RFALSE(!is_indirect_le_ih(ih),
- "green-9003: indirect item expected");
- }
-
- /* See if there is some block associated with the file
- at that position, map the buffer to this block */
- if (get_block_num(item, item_pos)) {
- map_bh(bh, inode->i_sb,
- get_block_num(item, item_pos));
- blocks--; // Decrease the amount of blocks that need to be
- // allocated
- }
- item_pos++;
- /* Update the key */
- set_cpu_key_k_offset(&key,
- cpu_key_k_offset(&key) +
- inode->i_sb->s_blocksize);
- }
- }
- pathrelse(&path); // Free the path
- reiserfs_write_unlock(inode->i_sb);
-
- /* Now zero out unmappend buffers for the first and last pages of
- write area or issue read requests if page is mapped. */
- /* First page, see if it is not uptodate */
- if (!PageUptodate(prepared_pages[0])) {
- head = page_buffers(prepared_pages[0]);
-
- /* For each buffer in page */
- for (bh = head, block_start = 0; bh != head || !block_start;
- block_start = block_end, bh = bh->b_this_page) {
-
- if (!bh)
- reiserfs_panic(inode->i_sb,
- "green-9002: Allocated but absent buffer for a page?");
- /* Find where this buffer ends */
- block_end = block_start + inode->i_sb->s_blocksize;
- if (block_end <= from)
- /* if this buffer is before requested data to map, skip it */
- continue;
- if (block_start < from) { /* Aha, our partial buffer */
- if (buffer_mapped(bh)) { /* If it is mapped, we need to
- issue READ request for it to
- not loose data */
- ll_rw_block(READ, 1, &bh);
- *wait_bh++ = bh;
- } else { /* Not mapped, zero it */
- zero_user_page(prepared_pages[0],
- block_start,
- from - block_start, KM_USER0);
- set_buffer_uptodate(bh);
- }
- }
- }
- }
-
- /* Last page, see if it is not uptodate, or if the last page is past the end of the file. */
- if (!PageUptodate(prepared_pages[num_pages - 1]) ||
- ((pos + write_bytes) >> PAGE_CACHE_SHIFT) >
- (inode->i_size >> PAGE_CACHE_SHIFT)) {
- head = page_buffers(prepared_pages[num_pages - 1]);
-
- /* for each buffer in page */
- for (bh = head, block_start = 0; bh != head || !block_start;
- block_start = block_end, bh = bh->b_this_page) {
-
- if (!bh)
- reiserfs_panic(inode->i_sb,
- "green-9002: Allocated but absent buffer for a page?");
- /* Find where this buffer ends */
- block_end = block_start + inode->i_sb->s_blocksize;
- if (block_start >= to)
- /* if this buffer is after requested data to map, skip it */
- break;
- if (block_end > to) { /* Aha, our partial buffer */
- if (buffer_mapped(bh)) { /* If it is mapped, we need to
- issue READ request for it to
- not loose data */
- ll_rw_block(READ, 1, &bh);
- *wait_bh++ = bh;
- } else { /* Not mapped, zero it */
- zero_user_page(prepared_pages[num_pages-1],
- to, block_end - to, KM_USER0);
- set_buffer_uptodate(bh);
- }
- }
- }
- }
-
- /* Wait for read requests we made to happen, if necessary */
- while (wait_bh > wait) {
- wait_on_buffer(*--wait_bh);
- if (!buffer_uptodate(*wait_bh)) {
- res = -EIO;
- goto failed_read;
- }
- }
-
- return blocks;
- failed_page_grabbing:
- num_pages = i;
- failed_read:
- reiserfs_unprepare_pages(prepared_pages, num_pages);
- return res;
-}
-
/* Write @count bytes at position @ppos in a file indicated by @file
from the buffer @buf.
@@ -1284,14 +256,9 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
* new current position before returning. */
)
{
- size_t already_written = 0; // Number of bytes already written to the file.
- loff_t pos; // Current position in the file.
- ssize_t res; // return value of various functions that we call.
- int err = 0;
struct inode *inode = file->f_path.dentry->d_inode; // Inode of the file that we are writing to.
/* To simplify coding at this time, we store
locked pages in array for now */
- struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
struct reiserfs_transaction_handle th;
th.t_trans_id = 0;
@@ -1311,212 +278,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
count = MAX_NON_LFS - (unsigned long)*ppos;
}
- if (file->f_flags & O_DIRECT)
- return do_sync_write(file, buf, count, ppos);
-
- if (unlikely((ssize_t) count < 0))
- return -EINVAL;
-
- if (unlikely(!access_ok(VERIFY_READ, buf, count)))
- return -EFAULT;
-
- mutex_lock(&inode->i_mutex); // locks the entire file for just us
-
- pos = *ppos;
-
- /* Check if we can write to specified region of file, file
- is not overly big and this kind of stuff. Adjust pos and
- count, if needed */
- res = generic_write_checks(file, &pos, &count, 0);
- if (res)
- goto out;
-
- if (count == 0)
- goto out;
-
- res = remove_suid(file->f_path.dentry);
- if (res)
- goto out;
-
- file_update_time(file);
-
- // Ok, we are done with all the checks.
-
- // Now we should start real work
-
- /* If we are going to write past the file's packed tail or if we are going
- to overwrite part of the tail, we need that tail to be converted into
- unformatted node */
- res = reiserfs_check_for_tail_and_convert(inode, pos, count);
- if (res)
- goto out;
-
- while (count > 0) {
- /* This is the main loop in which we running until some error occures
- or until we write all of the data. */
- size_t num_pages; /* amount of pages we are going to write this iteration */
- size_t write_bytes; /* amount of bytes to write during this iteration */
- size_t blocks_to_allocate; /* how much blocks we need to allocate for this iteration */
-
- /* (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos */
- num_pages = !!((pos + count) & (PAGE_CACHE_SIZE - 1)) + /* round up partial
- pages */
- ((count +
- (pos & (PAGE_CACHE_SIZE - 1))) >> PAGE_CACHE_SHIFT);
- /* convert size to amount of
- pages */
- reiserfs_write_lock(inode->i_sb);
- if (num_pages > REISERFS_WRITE_PAGES_AT_A_TIME
- || num_pages > reiserfs_can_fit_pages(inode->i_sb)) {
- /* If we were asked to write more data than we want to or if there
- is not that much space, then we shorten amount of data to write
- for this iteration. */
- num_pages =
- min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME,
- reiserfs_can_fit_pages(inode->i_sb));
- /* Also we should not forget to set size in bytes accordingly */
- write_bytes = (num_pages << PAGE_CACHE_SHIFT) -
- (pos & (PAGE_CACHE_SIZE - 1));
- /* If position is not on the
- start of the page, we need
- to substract the offset
- within page */
- } else
- write_bytes = count;
-
- /* reserve the blocks to be allocated later, so that later on
- we still have the space to write the blocks to */
- reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
- num_pages <<
- (PAGE_CACHE_SHIFT -
- inode->i_blkbits));
- reiserfs_write_unlock(inode->i_sb);
-
- if (!num_pages) { /* If we do not have enough space even for a single page... */
- if (pos >
- inode->i_size + inode->i_sb->s_blocksize -
- (pos & (inode->i_sb->s_blocksize - 1))) {
- res = -ENOSPC;
- break; // In case we are writing past the end of the last file block, break.
- }
- // Otherwise we are possibly overwriting the file, so
- // let's set write size to be equal or less than blocksize.
- // This way we get it correctly for file holes.
- // But overwriting files on absolutelly full volumes would not
- // be very efficient. Well, people are not supposed to fill
- // 100% of disk space anyway.
- write_bytes =
- min_t(size_t, count,
- inode->i_sb->s_blocksize -
- (pos & (inode->i_sb->s_blocksize - 1)));
- num_pages = 1;
- // No blocks were claimed before, so do it now.
- reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
- 1 <<
- (PAGE_CACHE_SHIFT
- -
- inode->
- i_blkbits));
- }
-
- /* Prepare for writing into the region, read in all the
- partially overwritten pages, if needed. And lock the pages,
- so that nobody else can access these until we are done.
- We get number of actual blocks needed as a result. */
- res = reiserfs_prepare_file_region_for_write(inode, pos,
- num_pages,
- write_bytes,
- prepared_pages);
- if (res < 0) {
- reiserfs_release_claimed_blocks(inode->i_sb,
- num_pages <<
- (PAGE_CACHE_SHIFT -
- inode->i_blkbits));
- break;
- }
-
- blocks_to_allocate = res;
-
- /* First we correct our estimate of how many blocks we need */
- reiserfs_release_claimed_blocks(inode->i_sb,
- (num_pages <<
- (PAGE_CACHE_SHIFT -
- inode->i_sb->
- s_blocksize_bits)) -
- blocks_to_allocate);
-
- if (blocks_to_allocate > 0) { /*We only allocate blocks if we need to */
- /* Fill in all the possible holes and append the file if needed */
- res =
- reiserfs_allocate_blocks_for_region(&th, inode, pos,
- num_pages,
- write_bytes,
- prepared_pages,
- blocks_to_allocate);
- }
-
- /* well, we have allocated the blocks, so it is time to free
- the reservation we made earlier. */
- reiserfs_release_claimed_blocks(inode->i_sb,
- blocks_to_allocate);
- if (res) {
- reiserfs_unprepare_pages(prepared_pages, num_pages);
- break;
- }
-
-/* NOTE that allocating blocks and filling blocks can be done in reverse order
- and probably we would do that just to get rid of garbage in files after a
- crash */
-
- /* Copy data from user-supplied buffer to file's pages */
- res =
- reiserfs_copy_from_user_to_file_region(pos, num_pages,
- write_bytes,
- prepared_pages, buf);
- if (res) {
- reiserfs_unprepare_pages(prepared_pages, num_pages);
- break;
- }
-
- /* Send the pages to disk and unlock them. */
- res =
- reiserfs_submit_file_region_for_write(&th, inode, pos,
- num_pages,
- write_bytes,
- prepared_pages);
- if (res)
- break;
-
- already_written += write_bytes;
- buf += write_bytes;
- *ppos = pos += write_bytes;
- count -= write_bytes;
- balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
- }
-
- /* this is only true on error */
- if (th.t_trans_id) {
- reiserfs_write_lock(inode->i_sb);
- err = journal_end(&th, th.t_super, th.t_blocks_allocated);
- reiserfs_write_unlock(inode->i_sb);
- if (err) {
- res = err;
- goto out;
- }
- }
-
- if (likely(res >= 0) &&
- (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))))
- res = generic_osync_inode(inode, file->f_mapping,
- OSYNC_METADATA | OSYNC_DATA);
-
- mutex_unlock(&inode->i_mutex);
- reiserfs_async_progress_wait(inode->i_sb);
- return (already_written != 0) ? already_written : res;
-
- out:
- mutex_unlock(&inode->i_mutex); // unlock the file on exit.
- return res;
+ return do_sync_write(file, buf, count, ppos);
}
const struct file_operations reiserfs_file_operations = {
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ddde489f1cb..0804289d355 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -17,11 +17,12 @@
#include <linux/mpage.h>
#include <linux/writeback.h>
#include <linux/quotaops.h>
+#include <linux/swap.h>
-static int reiserfs_commit_write(struct file *f, struct page *page,
- unsigned from, unsigned to);
-static int reiserfs_prepare_write(struct file *f, struct page *page,
- unsigned from, unsigned to);
+int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to);
+int reiserfs_prepare_write(struct file *f, struct page *page,
+ unsigned from, unsigned to);
void reiserfs_delete_inode(struct inode *inode)
{
@@ -207,8 +208,8 @@ static int file_capable(struct inode *inode, long block)
return 0;
}
-/*static*/ int restart_transaction(struct reiserfs_transaction_handle *th,
- struct inode *inode, struct treepath *path)
+static int restart_transaction(struct reiserfs_transaction_handle *th,
+ struct inode *inode, struct treepath *path)
{
struct super_block *s = th->t_super;
int len = th->t_blocks_allocated;
@@ -2550,8 +2551,78 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
return reiserfs_write_full_page(page, wbc);
}
-static int reiserfs_prepare_write(struct file *f, struct page *page,
- unsigned from, unsigned to)
+static int reiserfs_write_begin(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ struct inode *inode;
+ struct page *page;
+ pgoff_t index;
+ int ret;
+ int old_ref = 0;
+
+ inode = mapping->host;
+ *fsdata = 0;
+ if (flags & AOP_FLAG_CONT_EXPAND &&
+ (pos & (inode->i_sb->s_blocksize - 1)) == 0) {
+ pos ++;
+ *fsdata = (void *)(unsigned long)flags;
+ }
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
+ reiserfs_wait_on_write_block(inode->i_sb);
+ fix_tail_page_for_writing(page);
+ if (reiserfs_transaction_running(inode->i_sb)) {
+ struct reiserfs_transaction_handle *th;
+ th = (struct reiserfs_transaction_handle *)current->
+ journal_info;
+ BUG_ON(!th->t_refcount);
+ BUG_ON(!th->t_trans_id);
+ old_ref = th->t_refcount;
+ th->t_refcount++;
+ }
+ ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ reiserfs_get_block);
+ if (ret && reiserfs_transaction_running(inode->i_sb)) {
+ struct reiserfs_transaction_handle *th = current->journal_info;
+ /* this gets a little ugly. If reiserfs_get_block returned an
+ * error and left a transacstion running, we've got to close it,
+ * and we've got to free handle if it was a persistent transaction.
+ *
+ * But, if we had nested into an existing transaction, we need
+ * to just drop the ref count on the handle.
+ *
+ * If old_ref == 0, the transaction is from reiserfs_get_block,
+ * and it was a persistent trans. Otherwise, it was nested above.
+ */
+ if (th->t_refcount > old_ref) {
+ if (old_ref)
+ th->t_refcount--;
+ else {
+ int err;
+ reiserfs_write_lock(inode->i_sb);
+ err = reiserfs_end_persistent_transaction(th);
+ reiserfs_write_unlock(inode->i_sb);
+ if (err)
+ ret = err;
+ }
+ }
+ }
+ if (ret) {
+ unlock_page(page);
+ page_cache_release(page);
+ }
+ return ret;
+}
+
+int reiserfs_prepare_write(struct file *f, struct page *page,
+ unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
int ret;
@@ -2604,8 +2675,102 @@ static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block)
return generic_block_bmap(as, block, reiserfs_bmap);
}
-static int reiserfs_commit_write(struct file *f, struct page *page,
- unsigned from, unsigned to)
+static int reiserfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = page->mapping->host;
+ int ret = 0;
+ int update_sd = 0;
+ struct reiserfs_transaction_handle *th;
+ unsigned start;
+
+ if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
+ pos ++;
+
+ reiserfs_wait_on_write_block(inode->i_sb);
+ if (reiserfs_transaction_running(inode->i_sb))
+ th = current->journal_info;
+ else
+ th = NULL;
+
+ start = pos & (PAGE_CACHE_SIZE - 1);
+ if (unlikely(copied < len)) {
+ if (!PageUptodate(page))
+ copied = 0;
+
+ page_zero_new_buffers(page, start + copied, start + len);
+ }
+ flush_dcache_page(page);
+
+ reiserfs_commit_page(inode, page, start, start + copied);
+
+ /* generic_commit_write does this for us, but does not update the
+ ** transaction tracking stuff when the size changes. So, we have
+ ** to do the i_size updates here.
+ */
+ pos += copied;
+ if (pos > inode->i_size) {
+ struct reiserfs_transaction_handle myth;
+ reiserfs_write_lock(inode->i_sb);
+ /* If the file have grown beyond the border where it
+ can have a tail, unmark it as needing a tail
+ packing */
+ if ((have_large_tails(inode->i_sb)
+ && inode->i_size > i_block_size(inode) * 4)
+ || (have_small_tails(inode->i_sb)
+ && inode->i_size > i_block_size(inode)))
+ REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
+
+ ret = journal_begin(&myth, inode->i_sb, 1);
+ if (ret) {
+ reiserfs_write_unlock(inode->i_sb);
+ goto journal_error;
+ }
+ reiserfs_update_inode_transaction(inode);
+ inode->i_size = pos;
+ /*
+ * this will just nest into our transaction. It's important
+ * to use mark_inode_dirty so the inode gets pushed around on the
+ * dirty lists, and so that O_SYNC works as expected
+ */
+ mark_inode_dirty(inode);
+ reiserfs_update_sd(&myth, inode);
+ update_sd = 1;
+ ret = journal_end(&myth, inode->i_sb, 1);
+ reiserfs_write_unlock(inode->i_sb);
+ if (ret)
+ goto journal_error;
+ }
+ if (th) {
+ reiserfs_write_lock(inode->i_sb);
+ if (!update_sd)
+ mark_inode_dirty(inode);
+ ret = reiserfs_end_persistent_transaction(th);
+ reiserfs_write_unlock(inode->i_sb);
+ if (ret)
+ goto out;
+ }
+
+ out:
+ unlock_page(page);
+ page_cache_release(page);
+ return ret == 0 ? copied : ret;
+
+ journal_error:
+ if (th) {
+ reiserfs_write_lock(inode->i_sb);
+ if (!update_sd)
+ reiserfs_update_sd(th, inode);
+ ret = reiserfs_end_persistent_transaction(th);
+ reiserfs_write_unlock(inode->i_sb);
+ }
+
+ goto out;
+}
+
+int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to;
@@ -2896,7 +3061,11 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = dentry->d_inode;
int error;
- unsigned int ia_valid = attr->ia_valid;
+ unsigned int ia_valid;
+
+ /* must be turned off for recursive notify_change calls */
+ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
+
reiserfs_write_lock(inode->i_sb);
if (attr->ia_valid & ATTR_SIZE) {
/* version 2 items will be caught by the s_maxbytes check
@@ -2909,7 +3078,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
}
/* fill in hole pointers in the expanding truncate case. */
if (attr->ia_size > inode->i_size) {
- error = generic_cont_expand(inode, attr->ia_size);
+ error = generic_cont_expand_simple(inode, attr->ia_size);
if (REISERFS_I(inode)->i_prealloc_count > 0) {
int err;
struct reiserfs_transaction_handle th;
@@ -2999,8 +3168,8 @@ const struct address_space_operations reiserfs_address_space_operations = {
.releasepage = reiserfs_releasepage,
.invalidatepage = reiserfs_invalidatepage,
.sync_page = block_sync_page,
- .prepare_write = reiserfs_prepare_write,
- .commit_write = reiserfs_commit_write,
+ .write_begin = reiserfs_write_begin,
+ .write_end = reiserfs_write_end,
.bmap = reiserfs_aop_bmap,
.direct_IO = reiserfs_direct_IO,
.set_page_dirty = reiserfs_set_page_dirty,
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 11a0fcc2d40..c438a8f83f2 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -128,6 +128,10 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
}
#endif
+int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to);
+int reiserfs_prepare_write(struct file *f, struct page *page,
+ unsigned from, unsigned to);
/*
** reiserfs_unpack
** Function try to convert tail from direct item into indirect.
@@ -175,15 +179,13 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp)
if (!page) {
goto out;
}
- retval =
- mapping->a_ops->prepare_write(NULL, page, write_from, write_from);
+ retval = reiserfs_prepare_write(NULL, page, write_from, write_from);
if (retval)
goto out_unlock;
/* conversion can change page contents, must flush */
flush_dcache_page(page);
- retval =
- mapping->a_ops->commit_write(NULL, page, write_from, write_from);
+ retval = reiserfs_commit_write(NULL, page, write_from, write_from);
REISERFS_I(inode)->i_flags |= i_nopack_mask;
out_unlock:
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index f25086aeef5..4cad9e75ef5 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -615,6 +615,31 @@ static int journal_list_still_alive(struct super_block *s,
return 0;
}
+/*
+ * If page->mapping was null, we failed to truncate this page for
+ * some reason. Most likely because it was truncated after being
+ * logged via data=journal.
+ *
+ * This does a check to see if the buffer belongs to one of these
+ * lost pages before doing the final put_bh. If page->mapping was
+ * null, it tries to free buffers on the page, which should make the
+ * final page_cache_release drop the page from the lru.
+ */
+static void release_buffer_page(struct buffer_head *bh)
+{
+ struct page *page = bh->b_page;
+ if (!page->mapping && !TestSetPageLocked(page)) {
+ page_cache_get(page);
+ put_bh(bh);
+ if (!page->mapping)
+ try_to_free_buffers(page);
+ unlock_page(page);
+ page_cache_release(page);
+ } else {
+ put_bh(bh);
+ }
+}
+
static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
{
char b[BDEVNAME_SIZE];
@@ -628,8 +653,9 @@ static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
set_buffer_uptodate(bh);
else
clear_buffer_uptodate(bh);
+
unlock_buffer(bh);
- put_bh(bh);
+ release_buffer_page(bh);
}
static void reiserfs_end_ordered_io(struct buffer_head *bh, int uptodate)
@@ -966,7 +992,8 @@ static int flush_older_commits(struct super_block *s,
}
return 0;
}
-int reiserfs_async_progress_wait(struct super_block *s)
+
+static int reiserfs_async_progress_wait(struct super_block *s)
{
DEFINE_WAIT(wait);
struct reiserfs_journal *j = SB_JOURNAL(s);
@@ -1546,9 +1573,10 @@ static int flush_journal_list(struct super_block *s,
BUG_ON(!test_clear_buffer_journal_dirty
(cn->bh));
- /* undo the inc from journal_mark_dirty */
+ /* drop one ref for us */
put_bh(cn->bh);
- brelse(cn->bh);
+ /* drop one ref for journal_mark_dirty */
+ release_buffer_page(cn->bh);
}
cn = cn->next;
}
@@ -2621,6 +2649,61 @@ static int journal_init_dev(struct super_block *super,
return result;
}
+/**
+ * When creating/tuning a file system user can assign some
+ * journal params within boundaries which depend on the ratio
+ * blocksize/standard_blocksize.
+ *
+ * For blocks >= standard_blocksize transaction size should
+ * be not less then JOURNAL_TRANS_MIN_DEFAULT, and not more
+ * then JOURNAL_TRANS_MAX_DEFAULT.
+ *
+ * For blocks < standard_blocksize these boundaries should be
+ * decreased proportionally.
+ */
+#define REISERFS_STANDARD_BLKSIZE (4096)
+
+static int check_advise_trans_params(struct super_block *p_s_sb,
+ struct reiserfs_journal *journal)
+{
+ if (journal->j_trans_max) {
+ /* Non-default journal params.
+ Do sanity check for them. */
+ int ratio = 1;
+ if (p_s_sb->s_blocksize < REISERFS_STANDARD_BLKSIZE)
+ ratio = REISERFS_STANDARD_BLKSIZE / p_s_sb->s_blocksize;
+
+ if (journal->j_trans_max > JOURNAL_TRANS_MAX_DEFAULT / ratio ||
+ journal->j_trans_max < JOURNAL_TRANS_MIN_DEFAULT / ratio ||
+ SB_ONDISK_JOURNAL_SIZE(p_s_sb) / journal->j_trans_max <
+ JOURNAL_MIN_RATIO) {
+ reiserfs_warning(p_s_sb,
+ "sh-462: bad transaction max size (%u). FSCK?",
+ journal->j_trans_max);
+ return 1;
+ }
+ if (journal->j_max_batch != (journal->j_trans_max) *
+ JOURNAL_MAX_BATCH_DEFAULT/JOURNAL_TRANS_MAX_DEFAULT) {
+ reiserfs_warning(p_s_sb,
+ "sh-463: bad transaction max batch (%u). FSCK?",
+ journal->j_max_batch);
+ return 1;
+ }
+ } else {
+ /* Default journal params.
+ The file system was created by old version
+ of mkreiserfs, so some fields contain zeros,
+ and we need to advise proper values for them */
+ if (p_s_sb->s_blocksize != REISERFS_STANDARD_BLKSIZE)
+ reiserfs_panic(p_s_sb, "sh-464: bad blocksize (%u)",
+ p_s_sb->s_blocksize);
+ journal->j_trans_max = JOURNAL_TRANS_MAX_DEFAULT;
+ journal->j_max_batch = JOURNAL_MAX_BATCH_DEFAULT;
+ journal->j_max_commit_age = JOURNAL_MAX_COMMIT_AGE;
+ }
+ return 0;
+}
+
/*
** must be called once on fs mount. calls journal_read for you
*/
@@ -2716,49 +2799,8 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
le32_to_cpu(jh->jh_journal.jp_journal_max_commit_age);
journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
- if (journal->j_trans_max) {
- /* make sure these parameters are available, assign it if they are not */
- __u32 initial = journal->j_trans_max;
- __u32 ratio = 1;
-
- if (p_s_sb->s_blocksize < 4096)
- ratio = 4096 / p_s_sb->s_blocksize;
-
- if (SB_ONDISK_JOURNAL_SIZE(p_s_sb) / journal->j_trans_max <
- JOURNAL_MIN_RATIO)
- journal->j_trans_max =
- SB_ONDISK_JOURNAL_SIZE(p_s_sb) / JOURNAL_MIN_RATIO;
- if (journal->j_trans_max > JOURNAL_TRANS_MAX_DEFAULT / ratio)
- journal->j_trans_max =
- JOURNAL_TRANS_MAX_DEFAULT / ratio;
- if (journal->j_trans_max < JOURNAL_TRANS_MIN_DEFAULT / ratio)
- journal->j_trans_max =
- JOURNAL_TRANS_MIN_DEFAULT / ratio;
-
- if (journal->j_trans_max != initial)
- reiserfs_warning(p_s_sb,
- "sh-461: journal_init: wrong transaction max size (%u). Changed to %u",
- initial, journal->j_trans_max);
-
- journal->j_max_batch = journal->j_trans_max *
- JOURNAL_MAX_BATCH_DEFAULT / JOURNAL_TRANS_MAX_DEFAULT;
- }
-
- if (!journal->j_trans_max) {
- /*we have the file system was created by old version of mkreiserfs
- so this field contains zero value */
- journal->j_trans_max = JOURNAL_TRANS_MAX_DEFAULT;
- journal->j_max_batch = JOURNAL_MAX_BATCH_DEFAULT;
- journal->j_max_commit_age = JOURNAL_MAX_COMMIT_AGE;
-
- /* for blocksize >= 4096 - max transaction size is 1024. For block size < 4096
- trans max size is decreased proportionally */
- if (p_s_sb->s_blocksize < 4096) {
- journal->j_trans_max /= (4096 / p_s_sb->s_blocksize);
- journal->j_max_batch = (journal->j_trans_max) * 9 / 10;
- }
- }
-
+ if (check_advise_trans_params(p_s_sb, journal) != 0)
+ goto free_and_return;
journal->j_default_max_commit_age = journal->j_max_commit_age;
if (commit_max_age != 0) {
@@ -3708,13 +3750,8 @@ int journal_mark_freed(struct reiserfs_transaction_handle *th,
}
}
- if (bh) {
- put_bh(bh); /* get_hash grabs the buffer */
- if (atomic_read(&(bh->b_count)) < 0) {
- reiserfs_warning(p_s_sb,
- "journal-2165: bh->b_count < 0");
- }
- }
+ if (bh)
+ release_buffer_page(bh); /* get_hash grabs the buffer */
return 0;
}
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index a005451930b..b82897ae090 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -145,7 +145,7 @@ static int finish_unfinished(struct super_block *s)
{
INITIALIZE_PATH(path);
struct cpu_key max_cpu_key, obj_key;
- struct reiserfs_key save_link_key;
+ struct reiserfs_key save_link_key, last_inode_key;
int retval = 0;
struct item_head *ih;
struct buffer_head *bh;
@@ -166,6 +166,8 @@ static int finish_unfinished(struct super_block *s)
set_cpu_key_k_offset(&max_cpu_key, ~0U);
max_cpu_key.key_length = 3;
+ memset(&last_inode_key, 0, sizeof(last_inode_key));
+
#ifdef CONFIG_QUOTA
/* Needed for iput() to work correctly and not trash data */
if (s->s_flags & MS_ACTIVE) {
@@ -278,8 +280,18 @@ static int finish_unfinished(struct super_block *s)
REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
/* not completed unlink (rmdir) found */
reiserfs_info(s, "Removing %k..", INODE_PKEY(inode));
- /* removal gets completed in iput */
- retval = 0;
+ if (memcmp(&last_inode_key, INODE_PKEY(inode),
+ sizeof(last_inode_key))){
+ last_inode_key = *INODE_PKEY(inode);
+ /* removal gets completed in iput */
+ retval = 0;
+ } else {
+ reiserfs_warning(s, "Dead loop in "
+ "finish_unfinished detected, "
+ "just remove save link\n");
+ retval = remove_save_link_only(s,
+ &save_link_key, 0);
+ }
}
iput(inode);
@@ -508,7 +520,7 @@ static void reiserfs_destroy_inode(struct inode *inode)
kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
}
-static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index bf6e5821453..fab4b9b2664 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -426,6 +426,12 @@ static inline __u32 xattr_hash(const char *msg, int len)
return csum_partial(msg, len, 0);
}
+int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to);
+int reiserfs_prepare_write(struct file *f, struct page *page,
+ unsigned from, unsigned to);
+
+
/* Generic extended attribute operations that can be used by xa plugins */
/*
@@ -512,15 +518,15 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
rxh->h_hash = cpu_to_le32(xahash);
}
- err = mapping->a_ops->prepare_write(fp, page, page_offset,
- page_offset + chunk + skip);
+ err = reiserfs_prepare_write(fp, page, page_offset,
+ page_offset + chunk + skip);
if (!err) {
if (buffer)
memcpy(data + skip, buffer + buffer_pos, chunk);
err =
- mapping->a_ops->commit_write(fp, page, page_offset,
- page_offset + chunk +
- skip);
+ reiserfs_commit_write(fp, page, page_offset,
+ page_offset + chunk +
+ skip);
}
unlock_page(page);
reiserfs_put_page(page);
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index dae7945f90e..a49cf5b9a19 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -92,7 +92,7 @@ static inline unsigned long romfs_maxsize(struct super_block *sb)
static inline struct romfs_inode_info *ROMFS_I(struct inode *inode)
{
- return list_entry(inode, struct romfs_inode_info, vfs_inode);
+ return container_of(inode, struct romfs_inode_info, vfs_inode);
}
static __u32
@@ -555,7 +555,7 @@ static struct kmem_cache * romfs_inode_cachep;
static struct inode *romfs_alloc_inode(struct super_block *sb)
{
struct romfs_inode_info *ei;
- ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL);
+ ei = kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
return &ei->vfs_inode;
@@ -566,7 +566,7 @@ static void romfs_destroy_inode(struct inode *inode)
kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode));
}
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct romfs_inode_info *ei = foo;
diff --git a/fs/select.c b/fs/select.c
index 46dca31c607..7dede89658f 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -586,7 +586,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
/* Optimise the no-wait case */
if (!(*timeout))
pt = NULL;
-
+
for (;;) {
struct poll_list *walk;
long __timeout;
@@ -616,10 +616,12 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
* a poll_table to them on the next loop iteration.
*/
pt = NULL;
- if (count || !*timeout || signal_pending(current))
- break;
- count = wait->error;
- if (count)
+ if (!count) {
+ count = wait->error;
+ if (signal_pending(current))
+ count = -EINTR;
+ }
+ if (count || !*timeout)
break;
if (*timeout < 0) {
@@ -651,93 +653,89 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
{
struct poll_wqueues table;
- int fdcount, err;
- unsigned int i;
- struct poll_list *head;
- struct poll_list *walk;
+ int err = -EFAULT, fdcount, len, size;
/* Allocate small arguments on the stack to save memory and be
faster - use long to make sure the buffer is aligned properly
on 64 bit archs to avoid unaligned access */
long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
- struct poll_list *stack_pp = NULL;
+ struct poll_list *const head = (struct poll_list *)stack_pps;
+ struct poll_list *walk = head;
+ unsigned long todo = nfds;
- /* Do a sanity check on nfds ... */
if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
return -EINVAL;
- poll_initwait(&table);
+ len = min_t(unsigned int, nfds, N_STACK_PPS);
+ for (;;) {
+ walk->next = NULL;
+ walk->len = len;
+ if (!len)
+ break;
- head = NULL;
- walk = NULL;
- i = nfds;
- err = -ENOMEM;
- while(i!=0) {
- struct poll_list *pp;
- int num, size;
- if (stack_pp == NULL)
- num = N_STACK_PPS;
- else
- num = POLLFD_PER_PAGE;
- if (num > i)
- num = i;
- size = sizeof(struct poll_list) + sizeof(struct pollfd)*num;
- if (!stack_pp)
- stack_pp = pp = (struct poll_list *)stack_pps;
- else {
- pp = kmalloc(size, GFP_KERNEL);
- if (!pp)
- goto out_fds;
- }
- pp->next=NULL;
- pp->len = num;
- if (head == NULL)
- head = pp;
- else
- walk->next = pp;
+ if (copy_from_user(walk->entries, ufds + nfds-todo,
+ sizeof(struct pollfd) * walk->len))
+ goto out_fds;
+
+ todo -= walk->len;
+ if (!todo)
+ break;
- walk = pp;
- if (copy_from_user(pp->entries, ufds + nfds-i,
- sizeof(struct pollfd)*num)) {
- err = -EFAULT;
+ len = min(todo, POLLFD_PER_PAGE);
+ size = sizeof(struct poll_list) + sizeof(struct pollfd) * len;
+ walk = walk->next = kmalloc(size, GFP_KERNEL);
+ if (!walk) {
+ err = -ENOMEM;
goto out_fds;
}
- i -= pp->len;
}
+ poll_initwait(&table);
fdcount = do_poll(nfds, head, &table, timeout);
+ poll_freewait(&table);
- /* OK, now copy the revents fields back to user space. */
- walk = head;
- err = -EFAULT;
- while(walk != NULL) {
+ for (walk = head; walk; walk = walk->next) {
struct pollfd *fds = walk->entries;
int j;
- for (j=0; j < walk->len; j++, ufds++) {
- if(__put_user(fds[j].revents, &ufds->revents))
+ for (j = 0; j < walk->len; j++, ufds++)
+ if (__put_user(fds[j].revents, &ufds->revents))
goto out_fds;
- }
- walk = walk->next;
}
+
err = fdcount;
- if (!fdcount && signal_pending(current))
- err = -EINTR;
out_fds:
- walk = head;
- while(walk!=NULL) {
- struct poll_list *pp = walk->next;
- if (walk != stack_pp)
- kfree(walk);
- walk = pp;
+ walk = head->next;
+ while (walk) {
+ struct poll_list *pos = walk;
+ walk = walk->next;
+ kfree(pos);
}
- poll_freewait(&table);
+
return err;
}
+static long do_restart_poll(struct restart_block *restart_block)
+{
+ struct pollfd __user *ufds = (struct pollfd __user*)restart_block->arg0;
+ int nfds = restart_block->arg1;
+ s64 timeout = ((s64)restart_block->arg3<<32) | (s64)restart_block->arg2;
+ int ret;
+
+ ret = do_sys_poll(ufds, nfds, &timeout);
+ if (ret == -EINTR) {
+ restart_block->fn = do_restart_poll;
+ restart_block->arg2 = timeout & 0xFFFFFFFF;
+ restart_block->arg3 = (u64)timeout >> 32;
+ ret = -ERESTART_RESTARTBLOCK;
+ }
+ return ret;
+}
+
asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
long timeout_msecs)
{
s64 timeout_jiffies;
+ int ret;
if (timeout_msecs > 0) {
#if HZ > 1000
@@ -752,7 +750,18 @@ asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
timeout_jiffies = timeout_msecs;
}
- return do_sys_poll(ufds, nfds, &timeout_jiffies);
+ ret = do_sys_poll(ufds, nfds, &timeout_jiffies);
+ if (ret == -EINTR) {
+ struct restart_block *restart_block;
+ restart_block = &current_thread_info()->restart_block;
+ restart_block->fn = do_restart_poll;
+ restart_block->arg0 = (unsigned long)ufds;
+ restart_block->arg1 = nfds;
+ restart_block->arg2 = timeout_jiffies & 0xFFFFFFFF;
+ restart_block->arg3 = (u64)timeout_jiffies >> 32;
+ ret = -ERESTART_RESTARTBLOCK;
+ }
+ return ret;
}
#ifdef TIF_RESTORE_SIGMASK
diff --git a/fs/signalfd.c b/fs/signalfd.c
index aefb0be0794..fb7f7e8034d 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -74,45 +74,45 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
* If you change siginfo_t structure, please be sure
* this code is fixed accordingly.
*/
- err |= __put_user(kinfo->si_signo, &uinfo->signo);
- err |= __put_user(kinfo->si_errno, &uinfo->err);
- err |= __put_user((short)kinfo->si_code, &uinfo->code);
+ err |= __put_user(kinfo->si_signo, &uinfo->ssi_signo);
+ err |= __put_user(kinfo->si_errno, &uinfo->ssi_errno);
+ err |= __put_user((short) kinfo->si_code, &uinfo->ssi_code);
switch (kinfo->si_code & __SI_MASK) {
case __SI_KILL:
- err |= __put_user(kinfo->si_pid, &uinfo->pid);
- err |= __put_user(kinfo->si_uid, &uinfo->uid);
+ err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
break;
case __SI_TIMER:
- err |= __put_user(kinfo->si_tid, &uinfo->tid);
- err |= __put_user(kinfo->si_overrun, &uinfo->overrun);
- err |= __put_user((long)kinfo->si_ptr, &uinfo->svptr);
+ err |= __put_user(kinfo->si_tid, &uinfo->ssi_tid);
+ err |= __put_user(kinfo->si_overrun, &uinfo->ssi_overrun);
+ err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
break;
case __SI_POLL:
- err |= __put_user(kinfo->si_band, &uinfo->band);
- err |= __put_user(kinfo->si_fd, &uinfo->fd);
+ err |= __put_user(kinfo->si_band, &uinfo->ssi_band);
+ err |= __put_user(kinfo->si_fd, &uinfo->ssi_fd);
break;
case __SI_FAULT:
- err |= __put_user((long)kinfo->si_addr, &uinfo->addr);
+ err |= __put_user((long) kinfo->si_addr, &uinfo->ssi_addr);
#ifdef __ARCH_SI_TRAPNO
- err |= __put_user(kinfo->si_trapno, &uinfo->trapno);
+ err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno);
#endif
break;
case __SI_CHLD:
- err |= __put_user(kinfo->si_pid, &uinfo->pid);
- err |= __put_user(kinfo->si_uid, &uinfo->uid);
- err |= __put_user(kinfo->si_status, &uinfo->status);
- err |= __put_user(kinfo->si_utime, &uinfo->utime);
- err |= __put_user(kinfo->si_stime, &uinfo->stime);
+ err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
+ err |= __put_user(kinfo->si_status, &uinfo->ssi_status);
+ err |= __put_user(kinfo->si_utime, &uinfo->ssi_utime);
+ err |= __put_user(kinfo->si_stime, &uinfo->ssi_stime);
break;
case __SI_RT: /* This is not generated by the kernel as of now. */
case __SI_MESGQ: /* But this is */
- err |= __put_user(kinfo->si_pid, &uinfo->pid);
- err |= __put_user(kinfo->si_uid, &uinfo->uid);
- err |= __put_user((long)kinfo->si_ptr, &uinfo->svptr);
+ err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
+ err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
break;
default: /* this is just in case for now ... */
- err |= __put_user(kinfo->si_pid, &uinfo->pid);
- err |= __put_user(kinfo->si_uid, &uinfo->uid);
+ err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
+ err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
break;
}
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index c5d78a7e492..f5d14cebc75 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -292,29 +292,45 @@ out:
* If the writer ends up delaying the write, the writer needs to
* increment the page use counts until he is done with the page.
*/
-static int smb_prepare_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+static int smb_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ *pagep = __grab_cache_page(mapping, index);
+ if (!*pagep)
+ return -ENOMEM;
return 0;
}
-static int smb_commit_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+static int smb_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
int status;
+ unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
- status = -EFAULT;
lock_kernel();
- status = smb_updatepage(file, page, offset, to-offset);
+ status = smb_updatepage(file, page, offset, copied);
unlock_kernel();
+
+ if (!status) {
+ if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
+ SetPageUptodate(page);
+ status = copied;
+ }
+
+ unlock_page(page);
+ page_cache_release(page);
+
return status;
}
const struct address_space_operations smb_file_aops = {
.readpage = smb_readpage,
.writepage = smb_writepage,
- .prepare_write = smb_prepare_write,
- .commit_write = smb_commit_write
+ .write_begin = smb_write_begin,
+ .write_end = smb_write_end,
};
/*
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 73d1450a95d..ab517755ece 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -67,7 +67,7 @@ static void smb_destroy_inode(struct inode *inode)
kmem_cache_free(smb_inode_cachep, SMB_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct smb_inode_info *ei = (struct smb_inode_info *) foo;
diff --git a/fs/splice.c b/fs/splice.c
index e95a3622886..6bdcb6107bc 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -447,7 +447,7 @@ fill_it:
*/
while (page_nr < nr_pages)
page_cache_release(pages[page_nr++]);
- in->f_ra.prev_index = index;
+ in->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
if (spd.nr_pages)
return splice_to_pipe(pipe, &spd);
@@ -563,7 +563,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
struct address_space *mapping = file->f_mapping;
unsigned int offset, this_len;
struct page *page;
- pgoff_t index;
+ void *fsdata;
int ret;
/*
@@ -573,49 +573,16 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
if (unlikely(ret))
return ret;
- index = sd->pos >> PAGE_CACHE_SHIFT;
offset = sd->pos & ~PAGE_CACHE_MASK;
this_len = sd->len;
if (this_len + offset > PAGE_CACHE_SIZE)
this_len = PAGE_CACHE_SIZE - offset;
-find_page:
- page = find_lock_page(mapping, index);
- if (!page) {
- ret = -ENOMEM;
- page = page_cache_alloc_cold(mapping);
- if (unlikely(!page))
- goto out_ret;
-
- /*
- * This will also lock the page
- */
- ret = add_to_page_cache_lru(page, mapping, index,
- GFP_KERNEL);
- if (unlikely(ret))
- goto out_release;
- }
-
- ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
- if (unlikely(ret)) {
- loff_t isize = i_size_read(mapping->host);
-
- if (ret != AOP_TRUNCATED_PAGE)
- unlock_page(page);
- page_cache_release(page);
- if (ret == AOP_TRUNCATED_PAGE)
- goto find_page;
-
- /*
- * prepare_write() may have instantiated a few blocks
- * outside i_size. Trim these off again.
- */
- if (sd->pos + this_len > isize)
- vmtruncate(mapping->host, isize);
-
- goto out_ret;
- }
+ ret = pagecache_write_begin(file, mapping, sd->pos, this_len,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
+ if (unlikely(ret))
+ goto out;
if (buf->page != page) {
/*
@@ -629,31 +596,9 @@ find_page:
kunmap_atomic(dst, KM_USER1);
buf->ops->unmap(pipe, buf, src);
}
-
- ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len);
- if (ret) {
- if (ret == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- goto find_page;
- }
- if (ret < 0)
- goto out;
- /*
- * Partial write has happened, so 'ret' already initialized by
- * number of bytes written, Where is nothing we have to do here.
- */
- } else
- ret = this_len;
- /*
- * Return the number of bytes written and mark page as
- * accessed, we are now done!
- */
- mark_page_accessed(page);
+ ret = pagecache_write_end(file, mapping, sd->pos, this_len, this_len,
+ page, fsdata);
out:
- unlock_page(page);
-out_release:
- page_cache_release(page);
-out_ret:
return ret;
}
@@ -879,13 +824,18 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
{
struct address_space *mapping = out->f_mapping;
struct inode *inode = mapping->host;
+ int killsuid, killpriv;
ssize_t ret;
- int err;
+ int err = 0;
- err = should_remove_suid(out->f_path.dentry);
- if (unlikely(err)) {
+ killpriv = security_inode_need_killpriv(out->f_path.dentry);
+ killsuid = should_remove_suid(out->f_path.dentry);
+ if (unlikely(killsuid || killpriv)) {
mutex_lock(&inode->i_mutex);
- err = __remove_suid(out->f_path.dentry, err);
+ if (killpriv)
+ err = security_inode_killpriv(out->f_path.dentry);
+ if (!err && killsuid)
+ err = __remove_suid(out->f_path.dentry, killsuid);
mutex_unlock(&inode->i_mutex);
if (err)
return err;
@@ -1390,10 +1340,10 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len))
ret = -EFAULT;
+ buf->ops->unmap(pipe, buf, src);
out:
if (ret > 0)
sd->u.userptr += ret;
- buf->ops->unmap(pipe, buf, src);
return ret;
}
diff --git a/fs/super.c b/fs/super.c
index fc8ebedc6be..1bfcca2104b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -67,6 +67,7 @@ static struct super_block *alloc_super(struct file_system_type *type)
}
INIT_LIST_HEAD(&s->s_dirty);
INIT_LIST_HEAD(&s->s_io);
+ INIT_LIST_HEAD(&s->s_more_io);
INIT_LIST_HEAD(&s->s_files);
INIT_LIST_HEAD(&s->s_instances);
INIT_HLIST_HEAD(&s->s_anon);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 9161db4d6b5..7a8ce9e98b3 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -24,9 +24,9 @@
DEFINE_MUTEX(sysfs_mutex);
DEFINE_MUTEX(sysfs_rename_mutex);
-spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sysfs_assoc_lock);
-static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(sysfs_ino_lock);
static DEFINE_IDA(sysfs_ino_ida);
/**
@@ -112,8 +112,7 @@ struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
/* look it up */
parent = dentry;
mutex_lock(&parent->d_inode->i_mutex);
- dentry = lookup_one_len_kern(cur->s_name, parent,
- strlen(cur->s_name));
+ dentry = lookup_one_noperm(cur->s_name, parent);
mutex_unlock(&parent->d_inode->i_mutex);
dput(parent);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 9236635111f..d9262f74f94 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -24,8 +24,8 @@ extern struct super_block * sysfs_sb;
static const struct address_space_operations sysfs_aops = {
.readpage = simple_readpage,
- .prepare_write = simple_prepare_write,
- .commit_write = simple_commit_write
+ .write_begin = simple_write_begin,
+ .write_end = simple_write_end,
};
static struct backing_dev_info sysfs_backing_dev_info = {
@@ -37,6 +37,11 @@ static const struct inode_operations sysfs_inode_operations ={
.setattr = sysfs_setattr,
};
+int __init sysfs_inode_init(void)
+{
+ return bdi_init(&sysfs_backing_dev_info);
+}
+
int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
{
struct inode * inode = dentry->d_inode;
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index c76c540be3c..74168266cd5 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -92,6 +92,10 @@ int __init sysfs_init(void)
if (!sysfs_dir_cachep)
goto out;
+ err = sysfs_inode_init();
+ if (err)
+ goto out_err;
+
err = register_filesystem(&sysfs_fs_type);
if (!err) {
sysfs_mount = kern_mount(&sysfs_fs_type);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index f0326f281d1..f8417988f6b 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -146,6 +146,7 @@ static inline void sysfs_put(struct sysfs_dirent *sd)
struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
+int sysfs_inode_init(void);
/*
* file.c
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index e566b387fcf..56f655254bf 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -16,6 +16,7 @@
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/smp_lock.h>
+#include <linux/swap.h>
#include "sysv.h"
static int sysv_readdir(struct file *, void *, filldir_t);
@@ -37,12 +38,17 @@ static inline unsigned long dir_pages(struct inode *inode)
return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
}
-static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
+static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
- struct inode *dir = (struct inode *)page->mapping->host;
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
int err = 0;
- page->mapping->a_ops->commit_write(NULL, page, from, to);
+ block_write_end(NULL, mapping, pos, len, len, page, NULL);
+ if (pos+len > dir->i_size) {
+ i_size_write(dir, pos+len);
+ mark_inode_dirty(dir);
+ }
if (IS_DIRSYNC(dir))
err = write_one_page(page, 1);
else
@@ -186,7 +192,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
unsigned long npages = dir_pages(dir);
unsigned long n;
char *kaddr;
- unsigned from, to;
+ loff_t pos;
int err;
/* We take care of directory expansion in the same loop */
@@ -212,16 +218,17 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
return -EINVAL;
got_it:
- from = (char*)de - (char*)page_address(page);
- to = from + SYSV_DIRSIZE;
+ pos = page_offset(page) +
+ (char*)de - (char*)page_address(page);
lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err)
goto out_unlock;
memcpy (de->name, name, namelen);
memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
- err = dir_commit_chunk(page, from, to);
+ err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
out_page:
@@ -238,15 +245,15 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
struct address_space *mapping = page->mapping;
struct inode *inode = (struct inode*)mapping->host;
char *kaddr = (char*)page_address(page);
- unsigned from = (char*)de - kaddr;
- unsigned to = from + SYSV_DIRSIZE;
+ loff_t pos = page_offset(page) + (char *)de - kaddr;
int err;
lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
BUG_ON(err);
de->inode = 0;
- err = dir_commit_chunk(page, from, to);
+ err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
dir_put_page(page);
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
@@ -263,12 +270,13 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
if (!page)
return -ENOMEM;
- kmap(page);
- err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * SYSV_DIRSIZE);
+ err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err) {
unlock_page(page);
goto fail;
}
+ kmap(page);
base = (char*)page_address(page);
memset(base, 0, PAGE_CACHE_SIZE);
@@ -280,9 +288,9 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino);
strcpy(de->name,"..");
+ kunmap(page);
err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
fail:
- kunmap(page);
page_cache_release(page);
return err;
}
@@ -336,16 +344,18 @@ not_empty:
void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
struct inode *inode)
{
- struct inode *dir = (struct inode*)page->mapping->host;
- unsigned from = (char *)de-(char*)page_address(page);
- unsigned to = from + SYSV_DIRSIZE;
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
+ loff_t pos = page_offset(page) +
+ (char *)de-(char*)page_address(page);
int err;
lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
BUG_ON(err);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
- err = dir_commit_chunk(page, from, to);
+ err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
dir_put_page(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 7c4e5d302ab..81ec6c548c0 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -318,7 +318,7 @@ static void sysv_destroy_inode(struct inode *inode)
kmem_cache_free(sysv_inode_cachep, SYSV_I(inode));
}
-static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *p)
{
struct sysv_inode_info *si = (struct sysv_inode_info *)p;
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index f2bcccd1d6f..f042eec464c 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -453,23 +453,38 @@ static int sysv_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page,get_block,wbc);
}
+
static int sysv_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,get_block);
}
-static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+int __sysv_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page,from,to,get_block);
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ get_block);
}
+
+static int sysv_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ *pagep = NULL;
+ return __sysv_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+}
+
static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,get_block);
}
+
const struct address_space_operations sysv_aops = {
.readpage = sysv_readpage,
.writepage = sysv_writepage,
.sync_page = block_sync_page,
- .prepare_write = sysv_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = sysv_write_begin,
+ .write_end = generic_write_end,
.bmap = sysv_bmap
};
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 5b4fedf17cc..64c03bdf06a 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -136,6 +136,9 @@ extern unsigned long sysv_count_free_blocks(struct super_block *);
/* itree.c */
extern void sysv_truncate(struct inode *);
+extern int __sysv_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
/* inode.c */
extern int sysv_write_inode(struct inode *, int);
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 87e87dcd3f9..ab26176f6b9 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -689,7 +689,7 @@ static int udf_table_new_block(struct super_block *sb,
uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
uint32_t newblock = 0, adsize;
uint32_t elen, goal_elen = 0;
- kernel_lb_addr eloc, goal_eloc;
+ kernel_lb_addr eloc, uninitialized_var(goal_eloc);
struct extent_position epos, goal_epos;
int8_t etype;
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 5d7a4ea2775..7c7a1b39d56 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -76,36 +76,29 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb
return 0;
}
-static int udf_adinicb_prepare_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+static int udf_adinicb_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- kmap(page);
- return 0;
-}
-
-static int udf_adinicb_commit_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
-{
- struct inode *inode = page->mapping->host;
- char *kaddr = page_address(page);
+ struct inode *inode = mapping->host;
+ unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+ char *kaddr;
+ kaddr = kmap_atomic(page, KM_USER0);
memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset,
- kaddr + offset, to - offset);
- mark_inode_dirty(inode);
- SetPageUptodate(page);
- kunmap(page);
- /* only one page here */
- if (to > inode->i_size)
- inode->i_size = to;
- return 0;
+ kaddr + offset, copied);
+ kunmap_atomic(kaddr, KM_USER0);
+
+ return simple_write_end(file, mapping, pos, len, copied, page, fsdata);
}
const struct address_space_operations udf_adinicb_aops = {
.readpage = udf_adinicb_readpage,
.writepage = udf_adinicb_writepage,
.sync_page = block_sync_page,
- .prepare_write = udf_adinicb_prepare_write,
- .commit_write = udf_adinicb_commit_write,
+ .write_begin = simple_write_begin,
+ .write_end = udf_adinicb_write_end,
};
static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 1652b2c665b..6ff8151984c 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -133,10 +133,13 @@ static int udf_readpage(struct file *file, struct page *page)
return block_read_full_page(page, udf_get_block);
}
-static int udf_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int udf_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page, from, to, udf_get_block);
+ *pagep = NULL;
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ udf_get_block);
}
static sector_t udf_bmap(struct address_space *mapping, sector_t block)
@@ -148,8 +151,8 @@ const struct address_space_operations udf_aops = {
.readpage = udf_readpage,
.writepage = udf_writepage,
.sync_page = block_sync_page,
- .prepare_write = udf_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = udf_write_begin,
+ .write_end = generic_write_end,
.bmap = udf_bmap,
};
diff --git a/fs/udf/super.c b/fs/udf/super.c
index c68a6e730b9..4360c7a0574 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -134,7 +134,7 @@ static void udf_destroy_inode(struct inode *inode)
kmem_cache_free(udf_inode_cachep, UDF_I(inode));
}
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct udf_inode_info *ei = (struct udf_inode_info *)foo;
@@ -913,8 +913,7 @@ static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
udf_iget(sb, loc);
if (!UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table) {
- udf_debug("cannot load unallocSpaceTable (part %d)\n",
- i);
+ udf_debug("cannot load unallocSpaceTable (part %d)\n", i);
return 1;
}
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
@@ -944,8 +943,7 @@ static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
udf_iget(sb, loc);
if (!UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table) {
- udf_debug("cannot load freedSpaceTable (part %d)\n",
- i);
+ udf_debug("cannot load freedSpaceTable (part %d)\n", i);
return 1;
}
UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
@@ -1293,19 +1291,16 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
if (!UDF_SB_LASTBLOCK(sb)) {
udf_debug("Unable to determine Lastblock (For "
- "Virtual Partition)\n");
+ "Virtual Partition)\n");
return 1;
}
for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) {
- if (j != i && UDF_SB_PARTVSN(sb, i) ==
- UDF_SB_PARTVSN(sb, j) &&
- UDF_SB_PARTNUM(sb, i) ==
- UDF_SB_PARTNUM(sb, j)) {
+ if (j != i &&
+ UDF_SB_PARTVSN(sb, i) == UDF_SB_PARTVSN(sb, j) &&
+ UDF_SB_PARTNUM(sb, i) == UDF_SB_PARTNUM(sb, j)) {
ino.partitionReferenceNum = j;
- ino.logicalBlockNum =
- UDF_SB_LASTBLOCK(sb) -
- UDF_SB_PARTROOT(sb, j);
+ ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) - UDF_SB_PARTROOT(sb, j);
break;
}
}
@@ -1318,9 +1313,9 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) {
UDF_SB_TYPEVIRT(sb, i).s_start_offset =
- udf_ext0_offset(UDF_SB_VAT(sb));
+ udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb, i).s_num_entries =
- (UDF_SB_VAT(sb)->i_size - 36) >> 2;
+ (UDF_SB_VAT(sb)->i_size - 36) >> 2;
} else if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP20) {
struct buffer_head *bh = NULL;
uint32_t pos;
@@ -1330,19 +1325,15 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
if (!bh)
return 1;
UDF_SB_TYPEVIRT(sb, i).s_start_offset =
- le16_to_cpu(((struct
- virtualAllocationTable20 *)bh->b_data +
- udf_ext0_offset(UDF_SB_VAT(sb)))->
- lengthHeader) +
- udf_ext0_offset(UDF_SB_VAT(sb));
- UDF_SB_TYPEVIRT(sb, i).s_num_entries =
- (UDF_SB_VAT(sb)->i_size -
- UDF_SB_TYPEVIRT(sb, i).s_start_offset) >> 2;
+ le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data +
+ udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
+ udf_ext0_offset(UDF_SB_VAT(sb));
+ UDF_SB_TYPEVIRT(sb, i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
+ UDF_SB_TYPEVIRT(sb, i).s_start_offset) >> 2;
brelse(bh);
}
UDF_SB_PARTROOT(sb, i) = udf_get_pblock(sb, 0, i, 0);
- UDF_SB_PARTLEN(sb, i) = UDF_SB_PARTLEN(sb,
- ino.partitionReferenceNum);
+ UDF_SB_PARTLEN(sb, i) = UDF_SB_PARTLEN(sb, ino.partitionReferenceNum);
}
}
return 0;
@@ -1357,21 +1348,17 @@ static void udf_open_lvid(struct super_block *sb)
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
- UDF_SB_LVID(sb)->recordingDateAndTime =
- cpu_to_lets(cpu_time);
+ UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
- UDF_SB_LVID(sb)->descTag.descCRC =
- cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
- le16_to_cpu(UDF_SB_LVID(sb)->descTag.
- descCRCLength), 0));
+ UDF_SB_LVID(sb)->descTag.descCRC = cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
+ le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
for (i = 0; i < 16; i++)
if (i != 4)
UDF_SB_LVID(sb)->descTag.tagChecksum +=
- ((uint8_t *) &
- (UDF_SB_LVID(sb)->descTag))[i];
+ ((uint8_t *) &(UDF_SB_LVID(sb)->descTag))[i];
mark_buffer_dirty(UDF_SB_LVIDBH(sb));
}
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 3fd80eb66af..adcb87c2da7 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -108,10 +108,10 @@ time_t *udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
*dest = year_seconds[src.year - EPOCH_YEAR];
*dest -= offset * 60;
- yday = ((__mon_yday[__isleap (src.year)]
- [src.month - 1]) + (src.day - 1));
- *dest += ( ( (yday * 24) + src.hour ) * 60 + src.minute ) * 60 + src.second;
- *dest_usec = src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 + src.microseconds;
+ yday = ((__mon_yday[__isleap(src.year)][src.month - 1]) + src.day - 1);
+ *dest += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second;
+ *dest_usec = src.centiseconds * 10000 +
+ src.hundredsOfMicroseconds * 100 + src.microseconds;
return dest;
}
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 841ac25fd95..f63a09ce868 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -19,6 +19,7 @@
#include <linux/bitops.h>
#include <asm/byteorder.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
diff --git a/fs/ufs/cylinder.c b/fs/ufs/cylinder.c
index 09c39e5e638..2a815665644 100644
--- a/fs/ufs/cylinder.c
+++ b/fs/ufs/cylinder.c
@@ -17,6 +17,7 @@
#include <asm/byteorder.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 154452172f4..30f8c2bb0c3 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -19,7 +19,9 @@
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
+#include <linux/swap.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
@@ -38,12 +40,18 @@ static inline int ufs_match(struct super_block *sb, int len,
return !memcmp(name, de->d_name, len);
}
-static int ufs_commit_chunk(struct page *page, unsigned from, unsigned to)
+static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
{
- struct inode *dir = page->mapping->host;
+ struct address_space *mapping = page->mapping;
+ struct inode *dir = mapping->host;
int err = 0;
+
dir->i_version++;
- page->mapping->a_ops->commit_write(NULL, page, from, to);
+ block_write_end(NULL, mapping, pos, len, len, page, NULL);
+ if (pos+len > dir->i_size) {
+ i_size_write(dir, pos+len);
+ mark_inode_dirty(dir);
+ }
if (IS_DIRSYNC(dir))
err = write_one_page(page, 1);
else
@@ -81,16 +89,20 @@ ino_t ufs_inode_by_name(struct inode *dir, struct dentry *dentry)
void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
struct page *page, struct inode *inode)
{
- unsigned from = (char *) de - (char *) page_address(page);
- unsigned to = from + fs16_to_cpu(dir->i_sb, de->d_reclen);
+ loff_t pos = page_offset(page) +
+ (char *) de - (char *) page_address(page);
+ unsigned len = fs16_to_cpu(dir->i_sb, de->d_reclen);
int err;
lock_page(page);
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __ufs_write_begin(NULL, page->mapping, pos, len,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
BUG_ON(err);
+
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
ufs_set_de_type(dir->i_sb, de, inode->i_mode);
- err = ufs_commit_chunk(page, from, to);
+
+ err = ufs_commit_chunk(page, pos, len);
ufs_put_page(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
@@ -312,7 +324,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
unsigned long npages = ufs_dir_pages(dir);
unsigned long n;
char *kaddr;
- unsigned from, to;
+ loff_t pos;
int err;
UFSD("ENTER, name %s, namelen %u\n", name, namelen);
@@ -367,9 +379,10 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
return -EINVAL;
got_it:
- from = (char*)de - (char*)page_address(page);
- to = from + rec_len;
- err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ pos = page_offset(page) +
+ (char*)de - (char*)page_address(page);
+ err = __ufs_write_begin(NULL, page->mapping, pos, rec_len,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err)
goto out_unlock;
if (de->d_ino) {
@@ -386,7 +399,7 @@ got_it:
de->d_ino = cpu_to_fs32(sb, inode->i_ino);
ufs_set_de_type(sb, de, inode->i_mode);
- err = ufs_commit_chunk(page, from, to);
+ err = ufs_commit_chunk(page, pos, rec_len);
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(dir);
@@ -509,6 +522,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
char *kaddr = page_address(page);
unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
+ loff_t pos;
struct ufs_dir_entry *pde = NULL;
struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
int err;
@@ -532,13 +546,16 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
}
if (pde)
from = (char*)pde - (char*)page_address(page);
+
+ pos = page_offset(page) + from;
lock_page(page);
- err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ err = __ufs_write_begin(NULL, mapping, pos, to - from,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
BUG_ON(err);
if (pde)
- pde->d_reclen = cpu_to_fs16(sb, to-from);
+ pde->d_reclen = cpu_to_fs16(sb, to - from);
dir->d_ino = 0;
- err = ufs_commit_chunk(page, from, to);
+ err = ufs_commit_chunk(page, pos, to - from);
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
out:
@@ -559,14 +576,15 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
if (!page)
return -ENOMEM;
- kmap(page);
- err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
+
+ err = __ufs_write_begin(NULL, mapping, 0, chunk_size,
+ AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
if (err) {
unlock_page(page);
goto fail;
}
-
+ kmap(page);
base = (char*)page_address(page);
memset(base, 0, PAGE_CACHE_SIZE);
@@ -584,10 +602,10 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1));
ufs_set_de_namlen(sb, de, 2);
strcpy (de->d_name, "..");
+ kunmap(page);
err = ufs_commit_chunk(page, 0, chunk_size);
fail:
- kunmap(page);
page_cache_release(page);
return err;
}
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 6705d74c6d2..a46c97bf023 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -27,6 +27,9 @@
#include <linux/ufs_fs.h>
#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
+#include "ufs.h"
+
+
static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync)
{
struct inode *inode = dentry->d_inode;
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index c28a8b6f2fe..7e260bc0d94 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -34,6 +34,7 @@
#include <linux/bitops.h>
#include <asm/byteorder.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index f18b79122fa..4320782761a 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -38,6 +38,7 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
@@ -558,24 +559,39 @@ static int ufs_writepage(struct page *page, struct writeback_control *wbc)
{
return block_write_full_page(page,ufs_getfrag_block,wbc);
}
+
static int ufs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page,ufs_getfrag_block);
}
-static int ufs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
+
+int __ufs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- return block_prepare_write(page,from,to,ufs_getfrag_block);
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ufs_getfrag_block);
}
+
+static int ufs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ *pagep = NULL;
+ return __ufs_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+}
+
static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,ufs_getfrag_block);
}
+
const struct address_space_operations ufs_aops = {
.readpage = ufs_readpage,
.writepage = ufs_writepage,
.sync_page = block_sync_page,
- .prepare_write = ufs_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = ufs_write_begin,
+ .write_end = generic_write_end,
.bmap = ufs_bmap
};
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index a059ccd064e..d8bfbee2fe2 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -31,7 +31,7 @@
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/smp_lock.h>
-#include "swab.h" /* will go away - see comment in mknod() */
+#include "ufs.h"
#include "util.h"
static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
@@ -110,7 +110,6 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t
err = PTR_ERR(inode);
if (!IS_ERR(inode)) {
init_special_inode(inode, mode, rdev);
- /* NOTE: that'll go when we get wide dev_t */
ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev);
mark_inode_dirty(inode);
lock_kernel();
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 38eb0b7a1f3..584cf12cc40 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -88,7 +88,10 @@
#include <linux/buffer_head.h>
#include <linux/vfs.h>
#include <linux/log2.h>
+#include <linux/mount.h>
+#include <linux/seq_file.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
@@ -286,16 +289,28 @@ void ufs_warning (struct super_block * sb, const char * function,
}
enum {
- Opt_type_old, Opt_type_sunx86, Opt_type_sun, Opt_type_44bsd,
- Opt_type_ufs2, Opt_type_hp, Opt_type_nextstepcd, Opt_type_nextstep,
- Opt_type_openstep, Opt_onerror_panic, Opt_onerror_lock,
- Opt_onerror_umount, Opt_onerror_repair, Opt_err
+ Opt_type_old = UFS_MOUNT_UFSTYPE_OLD,
+ Opt_type_sunx86 = UFS_MOUNT_UFSTYPE_SUNx86,
+ Opt_type_sun = UFS_MOUNT_UFSTYPE_SUN,
+ Opt_type_sunos = UFS_MOUNT_UFSTYPE_SUNOS,
+ Opt_type_44bsd = UFS_MOUNT_UFSTYPE_44BSD,
+ Opt_type_ufs2 = UFS_MOUNT_UFSTYPE_UFS2,
+ Opt_type_hp = UFS_MOUNT_UFSTYPE_HP,
+ Opt_type_nextstepcd = UFS_MOUNT_UFSTYPE_NEXTSTEP_CD,
+ Opt_type_nextstep = UFS_MOUNT_UFSTYPE_NEXTSTEP,
+ Opt_type_openstep = UFS_MOUNT_UFSTYPE_OPENSTEP,
+ Opt_onerror_panic = UFS_MOUNT_ONERROR_PANIC,
+ Opt_onerror_lock = UFS_MOUNT_ONERROR_LOCK,
+ Opt_onerror_umount = UFS_MOUNT_ONERROR_UMOUNT,
+ Opt_onerror_repair = UFS_MOUNT_ONERROR_REPAIR,
+ Opt_err
};
static match_table_t tokens = {
{Opt_type_old, "ufstype=old"},
{Opt_type_sunx86, "ufstype=sunx86"},
{Opt_type_sun, "ufstype=sun"},
+ {Opt_type_sunos, "ufstype=sunos"},
{Opt_type_44bsd, "ufstype=44bsd"},
{Opt_type_ufs2, "ufstype=ufs2"},
{Opt_type_ufs2, "ufstype=5xbsd"},
@@ -303,6 +318,7 @@ static match_table_t tokens = {
{Opt_type_nextstepcd, "ufstype=nextstep-cd"},
{Opt_type_nextstep, "ufstype=nextstep"},
{Opt_type_openstep, "ufstype=openstep"},
+/*end of possible ufs types */
{Opt_onerror_panic, "onerror=panic"},
{Opt_onerror_lock, "onerror=lock"},
{Opt_onerror_umount, "onerror=umount"},
@@ -339,6 +355,10 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
ufs_clear_opt (*mount_options, UFSTYPE);
ufs_set_opt (*mount_options, UFSTYPE_SUN);
break;
+ case Opt_type_sunos:
+ ufs_clear_opt(*mount_options, UFSTYPE);
+ ufs_set_opt(*mount_options, UFSTYPE_SUNOS);
+ break;
case Opt_type_44bsd:
ufs_clear_opt (*mount_options, UFSTYPE);
ufs_set_opt (*mount_options, UFSTYPE_44BSD);
@@ -654,8 +674,8 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
ufs_set_opt (sbi->s_mount_opt, UFSTYPE_OLD);
}
- sbi->s_uspi = uspi =
- kmalloc (sizeof(struct ufs_sb_private_info), GFP_KERNEL);
+ uspi = kzalloc(sizeof(struct ufs_sb_private_info), GFP_KERNEL);
+ sbi->s_uspi = uspi;
if (!uspi)
goto failed;
uspi->s_dirblksize = UFS_SECTOR_SIZE;
@@ -692,10 +712,22 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
uspi->s_fshift = 10;
uspi->s_sbsize = super_block_size = 2048;
uspi->s_sbbase = 0;
- uspi->s_maxsymlinklen = 56;
+ uspi->s_maxsymlinklen = 0; /* Not supported on disk */
flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUN | UFS_CG_SUN;
break;
+ case UFS_MOUNT_UFSTYPE_SUNOS:
+ UFSD(("ufstype=sunos\n"))
+ uspi->s_fsize = block_size = 1024;
+ uspi->s_fmask = ~(1024 - 1);
+ uspi->s_fshift = 10;
+ uspi->s_sbsize = 2048;
+ super_block_size = 2048;
+ uspi->s_sbbase = 0;
+ uspi->s_maxsymlinklen = 0; /* Not supported on disk */
+ flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_SUNOS | UFS_CG_SUN;
+ break;
+
case UFS_MOUNT_UFSTYPE_SUNx86:
UFSD("ufstype=sunx86\n");
uspi->s_fsize = block_size = 1024;
@@ -703,7 +735,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
uspi->s_fshift = 10;
uspi->s_sbsize = super_block_size = 2048;
uspi->s_sbbase = 0;
- uspi->s_maxsymlinklen = 56;
+ uspi->s_maxsymlinklen = 0; /* Not supported on disk */
flags |= UFS_DE_OLD | UFS_UID_EFT | UFS_ST_SUNx86 | UFS_CG_SUN;
break;
@@ -805,11 +837,18 @@ again:
if (!ubh)
goto failed;
-
usb1 = ubh_get_usb_first(uspi);
usb2 = ubh_get_usb_second(uspi);
usb3 = ubh_get_usb_third(uspi);
+ /* Sort out mod used on SunOS 4.1.3 for fs_state */
+ uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
+ if (((flags & UFS_ST_MASK) == UFS_ST_SUNOS) &&
+ (uspi->s_postblformat != UFS_42POSTBLFMT)) {
+ flags &= ~UFS_ST_MASK;
+ flags |= UFS_ST_SUN;
+ }
+
/*
* Check ufs magic number
*/
@@ -894,18 +933,20 @@ magic_found:
goto again;
}
- sbi->s_flags = flags;/*after that line some functions use s_flags*/
+ /* Set sbi->s_flags here, used by ufs_get_fs_state() below */
+ sbi->s_flags = flags;
ufs_print_super_stuff(sb, usb1, usb2, usb3);
/*
* Check, if file system was correctly unmounted.
* If not, make it read only.
*/
- if (((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
- ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
- (((flags & UFS_ST_MASK) == UFS_ST_SUN ||
- (flags & UFS_ST_MASK) == UFS_ST_SUNx86) &&
- (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time))))) {
+ if ((((flags & UFS_ST_MASK) == UFS_ST_44BSD) ||
+ ((flags & UFS_ST_MASK) == UFS_ST_OLD) ||
+ ((flags & UFS_ST_MASK) == UFS_ST_SUN) ||
+ ((flags & UFS_ST_MASK) == UFS_ST_SUNOS) ||
+ ((flags & UFS_ST_MASK) == UFS_ST_SUNx86)) &&
+ (ufs_get_fs_state(sb, usb1, usb3) == (UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time)))) {
switch(usb1->fs_clean) {
case UFS_FSCLEAN:
UFSD("fs is clean\n");
@@ -995,7 +1036,6 @@ magic_found:
uspi->s_contigsumsize = fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_contigsumsize);
uspi->s_qbmask = ufs_get_fs_qbmask(sb, usb3);
uspi->s_qfmask = ufs_get_fs_qfmask(sb, usb3);
- uspi->s_postblformat = fs32_to_cpu(sb, usb3->fs_postblformat);
uspi->s_nrpos = fs32_to_cpu(sb, usb3->fs_nrpos);
uspi->s_postbloff = fs32_to_cpu(sb, usb3->fs_postbloff);
uspi->s_rotbloff = fs32_to_cpu(sb, usb3->fs_rotbloff);
@@ -1077,6 +1117,7 @@ static void ufs_write_super(struct super_block *sb)
if (!(sb->s_flags & MS_RDONLY)) {
usb1->fs_time = cpu_to_fs32(sb, get_seconds());
if ((flags & UFS_ST_MASK) == UFS_ST_SUN
+ || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
|| (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
ufs_set_fs_state(sb, usb1, usb3,
UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
@@ -1146,6 +1187,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
ufs_put_super_internal(sb);
usb1->fs_time = cpu_to_fs32(sb, get_seconds());
if ((flags & UFS_ST_MASK) == UFS_ST_SUN
+ || (flags & UFS_ST_MASK) == UFS_ST_SUNOS
|| (flags & UFS_ST_MASK) == UFS_ST_SUNx86)
ufs_set_fs_state(sb, usb1, usb3,
UFS_FSOK - fs32_to_cpu(sb, usb1->fs_time));
@@ -1162,6 +1204,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
return -EINVAL;
#else
if (ufstype != UFS_MOUNT_UFSTYPE_SUN &&
+ ufstype != UFS_MOUNT_UFSTYPE_SUNOS &&
ufstype != UFS_MOUNT_UFSTYPE_44BSD &&
ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
@@ -1179,6 +1222,26 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
return 0;
}
+static int ufs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+ struct ufs_sb_info *sbi = UFS_SB(vfs->mnt_sb);
+ unsigned mval = sbi->s_mount_opt & UFS_MOUNT_UFSTYPE;
+ struct match_token *tp = tokens;
+
+ while (tp->token != Opt_onerror_panic && tp->token != mval)
+ ++tp;
+ BUG_ON(tp->token == Opt_onerror_panic);
+ seq_printf(seq, ",%s", tp->pattern);
+
+ mval = sbi->s_mount_opt & UFS_MOUNT_ONERROR;
+ while (tp->token != Opt_err && tp->token != mval)
+ ++tp;
+ BUG_ON(tp->token == Opt_err);
+ seq_printf(seq, ",%s", tp->pattern);
+
+ return 0;
+}
+
static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct super_block *sb = dentry->d_sb;
@@ -1232,7 +1295,7 @@ static void ufs_destroy_inode(struct inode *inode)
kmem_cache_free(ufs_inode_cachep, UFS_I(inode));
}
-static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache * cachep, void *foo)
{
struct ufs_inode_info *ei = (struct ufs_inode_info *) foo;
@@ -1271,6 +1334,7 @@ static const struct super_operations ufs_super_ops = {
.write_super = ufs_write_super,
.statfs = ufs_statfs,
.remount_fs = ufs_remount,
+ .show_options = ufs_show_options,
#ifdef CONFIG_QUOTA
.quota_read = ufs_quota_read,
.quota_write = ufs_quota_write,
diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c
index d8549f807e8..43ac10e75a4 100644
--- a/fs/ufs/symlink.c
+++ b/fs/ufs/symlink.c
@@ -28,6 +28,8 @@
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/ufs_fs.h>
+#include "ufs.h"
+
static void *ufs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 79c54c85fb5..311ded34c2b 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -46,6 +46,7 @@
#include <linux/blkdev.h>
#include <linux/sched.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
new file mode 100644
index 00000000000..7faa4cd71a2
--- /dev/null
+++ b/fs/ufs/ufs.h
@@ -0,0 +1,157 @@
+#ifndef _UFS_UFS_H
+#define _UFS_UFS_H 1
+
+#define UFS_MAX_GROUP_LOADED 8
+#define UFS_CGNO_EMPTY ((unsigned)-1)
+
+struct ufs_sb_private_info;
+struct ufs_cg_private_info;
+struct ufs_csum;
+
+struct ufs_sb_info {
+ struct ufs_sb_private_info * s_uspi;
+ struct ufs_csum * s_csp;
+ unsigned s_bytesex;
+ unsigned s_flags;
+ struct buffer_head ** s_ucg;
+ struct ufs_cg_private_info * s_ucpi[UFS_MAX_GROUP_LOADED];
+ unsigned s_cgno[UFS_MAX_GROUP_LOADED];
+ unsigned short s_cg_loaded;
+ unsigned s_mount_opt;
+};
+
+struct ufs_inode_info {
+ union {
+ __fs32 i_data[15];
+ __u8 i_symlink[4*15];
+ __fs64 u2_i_data[15];
+ } i_u1;
+ __u32 i_flags;
+ __u32 i_shadow;
+ __u32 i_unused1;
+ __u32 i_unused2;
+ __u32 i_oeftflag;
+ __u16 i_osync;
+ __u64 i_lastfrag;
+ __u32 i_dir_start_lookup;
+ struct inode vfs_inode;
+};
+
+/* mount options */
+#define UFS_MOUNT_ONERROR 0x0000000F
+#define UFS_MOUNT_ONERROR_PANIC 0x00000001
+#define UFS_MOUNT_ONERROR_LOCK 0x00000002
+#define UFS_MOUNT_ONERROR_UMOUNT 0x00000004
+#define UFS_MOUNT_ONERROR_REPAIR 0x00000008
+
+#define UFS_MOUNT_UFSTYPE 0x0000FFF0
+#define UFS_MOUNT_UFSTYPE_OLD 0x00000010
+#define UFS_MOUNT_UFSTYPE_44BSD 0x00000020
+#define UFS_MOUNT_UFSTYPE_SUN 0x00000040
+#define UFS_MOUNT_UFSTYPE_NEXTSTEP 0x00000080
+#define UFS_MOUNT_UFSTYPE_NEXTSTEP_CD 0x00000100
+#define UFS_MOUNT_UFSTYPE_OPENSTEP 0x00000200
+#define UFS_MOUNT_UFSTYPE_SUNx86 0x00000400
+#define UFS_MOUNT_UFSTYPE_HP 0x00000800
+#define UFS_MOUNT_UFSTYPE_UFS2 0x00001000
+#define UFS_MOUNT_UFSTYPE_SUNOS 0x00002000
+
+#define ufs_clear_opt(o,opt) o &= ~UFS_MOUNT_##opt
+#define ufs_set_opt(o,opt) o |= UFS_MOUNT_##opt
+#define ufs_test_opt(o,opt) ((o) & UFS_MOUNT_##opt)
+
+/*
+ * Debug code
+ */
+#ifdef CONFIG_UFS_DEBUG
+# define UFSD(f, a...) { \
+ printk ("UFSD (%s, %d): %s:", \
+ __FILE__, __LINE__, __FUNCTION__); \
+ printk (f, ## a); \
+ }
+#else
+# define UFSD(f, a...) /**/
+#endif
+
+/* balloc.c */
+extern void ufs_free_fragments (struct inode *, u64, unsigned);
+extern void ufs_free_blocks (struct inode *, u64, unsigned);
+extern u64 ufs_new_fragments(struct inode *, void *, u64, u64,
+ unsigned, int *, struct page *);
+
+/* cylinder.c */
+extern struct ufs_cg_private_info * ufs_load_cylinder (struct super_block *, unsigned);
+extern void ufs_put_cylinder (struct super_block *, unsigned);
+
+/* dir.c */
+extern const struct inode_operations ufs_dir_inode_operations;
+extern int ufs_add_link (struct dentry *, struct inode *);
+extern ino_t ufs_inode_by_name(struct inode *, struct dentry *);
+extern int ufs_make_empty(struct inode *, struct inode *);
+extern struct ufs_dir_entry *ufs_find_entry(struct inode *, struct dentry *, struct page **);
+extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
+extern int ufs_empty_dir (struct inode *);
+extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
+extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
+ struct page *page, struct inode *inode);
+
+/* file.c */
+extern const struct inode_operations ufs_file_inode_operations;
+extern const struct file_operations ufs_file_operations;
+
+extern const struct address_space_operations ufs_aops;
+
+/* ialloc.c */
+extern void ufs_free_inode (struct inode *inode);
+extern struct inode * ufs_new_inode (struct inode *, int);
+
+/* inode.c */
+extern void ufs_read_inode (struct inode *);
+extern void ufs_put_inode (struct inode *);
+extern int ufs_write_inode (struct inode *, int);
+extern int ufs_sync_inode (struct inode *);
+extern void ufs_delete_inode (struct inode *);
+extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
+extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create);
+
+/* namei.c */
+extern const struct file_operations ufs_dir_operations;
+
+/* super.c */
+extern void ufs_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
+extern void ufs_error (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
+extern void ufs_panic (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
+
+/* symlink.c */
+extern const struct inode_operations ufs_fast_symlink_inode_operations;
+
+/* truncate.c */
+extern int ufs_truncate (struct inode *, loff_t);
+
+static inline struct ufs_sb_info *UFS_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+static inline struct ufs_inode_info *UFS_I(struct inode *inode)
+{
+ return container_of(inode, struct ufs_inode_info, vfs_inode);
+}
+
+/*
+ * Give cylinder group number for a file system block.
+ * Give cylinder group block number for a file system block.
+ */
+/* #define ufs_dtog(d) ((d) / uspi->s_fpg) */
+static inline u64 ufs_dtog(struct ufs_sb_private_info * uspi, u64 b)
+{
+ do_div(b, uspi->s_fpg);
+ return b;
+}
+/* #define ufs_dtogd(d) ((d) % uspi->s_fpg) */
+static inline u32 ufs_dtogd(struct ufs_sb_private_info * uspi, u64 b)
+{
+ return do_div(b, uspi->s_fpg);
+}
+
+#endif /* _UFS_UFS_H */
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index 84357f1ff0e..410084dae38 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -11,6 +11,7 @@
#include <linux/ufs_fs.h>
#include <linux/buffer_head.h>
+#include "ufs.h"
#include "swab.h"
#include "util.h"
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 06d344839c4..b26fc4dec1e 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -38,6 +38,10 @@ ufs_get_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1,
struct ufs_super_block_third *usb3)
{
switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+ case UFS_ST_SUNOS:
+ if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT)
+ return fs32_to_cpu(sb, usb1->fs_u0.fs_sun.fs_state);
+ /* Fall Through to UFS_ST_SUN */
case UFS_ST_SUN:
return fs32_to_cpu(sb, usb3->fs_un2.fs_sun.fs_state);
case UFS_ST_SUNx86:
@@ -53,6 +57,12 @@ ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1,
struct ufs_super_block_third *usb3, s32 value)
{
switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+ case UFS_ST_SUNOS:
+ if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) {
+ usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value);
+ break;
+ }
+ /* Fall Through to UFS_ST_SUN */
case UFS_ST_SUN:
usb3->fs_un2.fs_sun.fs_state = cpu_to_fs32(sb, value);
break;
@@ -81,6 +91,7 @@ ufs_get_fs_qbmask(struct super_block *sb, struct ufs_super_block_third *usb3)
__fs64 tmp;
switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+ case UFS_ST_SUNOS:
case UFS_ST_SUN:
((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qbmask[0];
((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qbmask[1];
@@ -104,6 +115,7 @@ ufs_get_fs_qfmask(struct super_block *sb, struct ufs_super_block_third *usb3)
__fs64 tmp;
switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
+ case UFS_ST_SUNOS:
case UFS_ST_SUN:
((__fs32 *)&tmp)[0] = usb3->fs_un2.fs_sun.fs_qfmask[0];
((__fs32 *)&tmp)[1] = usb3->fs_un2.fs_sun.fs_qfmask[1];
@@ -179,10 +191,12 @@ static inline u32
ufs_get_inode_uid(struct super_block *sb, struct ufs_inode *inode)
{
switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
- case UFS_UID_EFT:
- return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid);
case UFS_UID_44BSD:
return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_uid);
+ case UFS_UID_EFT:
+ if (inode->ui_u1.oldids.ui_suid == 0xFFFF)
+ return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_uid);
+ /* Fall through */
default:
return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_suid);
}
@@ -192,24 +206,31 @@ static inline void
ufs_set_inode_uid(struct super_block *sb, struct ufs_inode *inode, u32 value)
{
switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
- case UFS_UID_EFT:
- inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value);
- break;
case UFS_UID_44BSD:
inode->ui_u3.ui_44.ui_uid = cpu_to_fs32(sb, value);
+ inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value);
+ break;
+ case UFS_UID_EFT:
+ inode->ui_u3.ui_sun.ui_uid = cpu_to_fs32(sb, value);
+ if (value > 0xFFFF)
+ value = 0xFFFF;
+ /* Fall through */
+ default:
+ inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value);
break;
}
- inode->ui_u1.oldids.ui_suid = cpu_to_fs16(sb, value);
}
static inline u32
ufs_get_inode_gid(struct super_block *sb, struct ufs_inode *inode)
{
switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
- case UFS_UID_EFT:
- return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
case UFS_UID_44BSD:
return fs32_to_cpu(sb, inode->ui_u3.ui_44.ui_gid);
+ case UFS_UID_EFT:
+ if (inode->ui_u1.oldids.ui_suid == 0xFFFF)
+ return fs32_to_cpu(sb, inode->ui_u3.ui_sun.ui_gid);
+ /* Fall through */
default:
return fs16_to_cpu(sb, inode->ui_u1.oldids.ui_sgid);
}
@@ -219,18 +240,26 @@ static inline void
ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value)
{
switch (UFS_SB(sb)->s_flags & UFS_UID_MASK) {
- case UFS_UID_EFT:
- inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value);
- break;
case UFS_UID_44BSD:
inode->ui_u3.ui_44.ui_gid = cpu_to_fs32(sb, value);
+ inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value);
+ break;
+ case UFS_UID_EFT:
+ inode->ui_u3.ui_sun.ui_gid = cpu_to_fs32(sb, value);
+ if (value > 0xFFFF)
+ value = 0xFFFF;
+ /* Fall through */
+ default:
+ inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value);
break;
}
- inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value);
}
extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
+extern int __ufs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
/*
* These functions manipulate ufs buffers
diff --git a/fs/utimes.c b/fs/utimes.c
index 682eb63b20a..b9912ecbee2 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -38,6 +38,14 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
#endif
+static bool nsec_valid(long nsec)
+{
+ if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
+ return true;
+
+ return nsec >= 0 && nsec <= 999999999;
+}
+
/* If times==NULL, set access and modification to current time,
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
@@ -52,6 +60,11 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
struct file *f = NULL;
error = -EINVAL;
+ if (times && (!nsec_valid(times[0].tv_nsec) ||
+ !nsec_valid(times[1].tv_nsec))) {
+ goto out;
+ }
+
if (flags & ~AT_SYMLINK_NOFOLLOW)
goto out;
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index e7a9a83f008..d1491aa7a0e 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -49,7 +49,6 @@ xfs-y += xfs_alloc.o \
xfs_alloc_btree.o \
xfs_attr.o \
xfs_attr_leaf.o \
- xfs_behavior.o \
xfs_bit.o \
xfs_bmap.o \
xfs_bmap_btree.o \
@@ -108,13 +107,11 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
xfs_iops.o \
xfs_lrw.o \
xfs_super.o \
- xfs_vfs.o \
xfs_vnode.o)
# Objects in support/
xfs-y += $(addprefix support/, \
debug.o \
- move.o \
uuid.o)
xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index e6ea293f303..5e956490297 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -79,7 +79,7 @@ kmem_zone_init(int size, char *zone_name)
static inline kmem_zone_t *
kmem_zone_init_flags(int size, char *zone_name, unsigned long flags,
- void (*construct)(void *, kmem_zone_t *, unsigned long))
+ void (*construct)(kmem_zone_t *, void *))
{
return kmem_cache_create(zone_name, size, 0, flags, construct);
}
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 6f4c29e9c3d..2e34b104107 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -37,6 +37,7 @@
#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_iomap.h"
+#include "xfs_vnodeops.h"
#include <linux/mpage.h>
#include <linux/pagevec.h>
#include <linux/writeback.h>
@@ -139,9 +140,11 @@ xfs_destroy_ioend(
next = bh->b_private;
bh->b_end_io(bh, !ioend->io_error);
}
- if (unlikely(ioend->io_error))
- vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
- vn_iowake(ioend->io_vnode);
+ if (unlikely(ioend->io_error)) {
+ vn_ioerror(XFS_I(ioend->io_inode), ioend->io_error,
+ __FILE__,__LINE__);
+ }
+ vn_iowake(XFS_I(ioend->io_inode));
mempool_free(ioend, xfs_ioend_pool);
}
@@ -156,14 +159,10 @@ STATIC void
xfs_setfilesize(
xfs_ioend_t *ioend)
{
- xfs_inode_t *ip;
+ xfs_inode_t *ip = XFS_I(ioend->io_inode);
xfs_fsize_t isize;
xfs_fsize_t bsize;
- ip = xfs_vtoi(ioend->io_vnode);
- if (!ip)
- return;
-
ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
ASSERT(ioend->io_type != IOMAP_READ);
@@ -181,7 +180,7 @@ xfs_setfilesize(
ip->i_d.di_size = isize;
ip->i_update_core = 1;
ip->i_update_size = 1;
- mark_inode_dirty_sync(vn_to_inode(ioend->io_vnode));
+ mark_inode_dirty_sync(ioend->io_inode);
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -227,12 +226,12 @@ xfs_end_bio_unwritten(
{
xfs_ioend_t *ioend =
container_of(work, xfs_ioend_t, io_work);
- bhv_vnode_t *vp = ioend->io_vnode;
xfs_off_t offset = ioend->io_offset;
size_t size = ioend->io_size;
if (likely(!ioend->io_error)) {
- bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
+ xfs_bmap(XFS_I(ioend->io_inode), offset, size,
+ BMAPI_UNWRITTEN, NULL, NULL);
xfs_setfilesize(ioend);
}
xfs_destroy_ioend(ioend);
@@ -275,10 +274,10 @@ xfs_alloc_ioend(
ioend->io_error = 0;
ioend->io_list = NULL;
ioend->io_type = type;
- ioend->io_vnode = vn_from_inode(inode);
+ ioend->io_inode = inode;
ioend->io_buffer_head = NULL;
ioend->io_buffer_tail = NULL;
- atomic_inc(&ioend->io_vnode->v_iocount);
+ atomic_inc(&XFS_I(ioend->io_inode)->i_iocount);
ioend->io_offset = 0;
ioend->io_size = 0;
@@ -302,12 +301,13 @@ xfs_map_blocks(
xfs_iomap_t *mapp,
int flags)
{
- bhv_vnode_t *vp = vn_from_inode(inode);
+ xfs_inode_t *ip = XFS_I(inode);
int error, nmaps = 1;
- error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
+ error = xfs_bmap(ip, offset, count,
+ flags, mapp, &nmaps);
if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
- VMODIFY(vp);
+ xfs_iflags_set(ip, XFS_IMODIFIED);
return -error;
}
@@ -402,10 +402,9 @@ xfs_start_page_writeback(
clear_page_dirty_for_io(page);
set_page_writeback(page);
unlock_page(page);
- if (!buffers) {
+ /* If no buffers on the page are to be written, finish it here */
+ if (!buffers)
end_page_writeback(page);
- wbc->pages_skipped++; /* We didn't write this page */
- }
}
static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
@@ -498,7 +497,7 @@ xfs_cancel_ioend(
unlock_buffer(bh);
} while ((bh = next_bh) != NULL);
- vn_iowake(ioend->io_vnode);
+ vn_iowake(XFS_I(ioend->io_inode));
mempool_free(ioend, xfs_ioend_pool);
} while ((ioend = next) != NULL);
}
@@ -1238,10 +1237,7 @@ xfs_vm_writepages(
struct address_space *mapping,
struct writeback_control *wbc)
{
- struct bhv_vnode *vp = vn_from_inode(mapping->host);
-
- if (VN_TRUNC(vp))
- VUNTRUNCATE(vp);
+ xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED);
return generic_writepages(mapping, wbc);
}
@@ -1318,7 +1314,6 @@ __xfs_get_blocks(
int direct,
bmapi_flags_t flags)
{
- bhv_vnode_t *vp = vn_from_inode(inode);
xfs_iomap_t iomap;
xfs_off_t offset;
ssize_t size;
@@ -1328,7 +1323,7 @@ __xfs_get_blocks(
offset = (xfs_off_t)iblock << inode->i_blkbits;
ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
size = bh_result->b_size;
- error = bhv_vop_bmap(vp, offset, size,
+ error = xfs_bmap(XFS_I(inode), offset, size,
create ? flags : BMAPI_READ, &iomap, &niomap);
if (error)
return -error;
@@ -1476,13 +1471,13 @@ xfs_vm_direct_IO(
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
- bhv_vnode_t *vp = vn_from_inode(inode);
xfs_iomap_t iomap;
int maps = 1;
int error;
ssize_t ret;
- error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
+ error = xfs_bmap(XFS_I(inode), offset, 0,
+ BMAPI_DEVICE, &iomap, &maps);
if (error)
return -error;
@@ -1508,13 +1503,18 @@ xfs_vm_direct_IO(
}
STATIC int
-xfs_vm_prepare_write(
+xfs_vm_write_begin(
struct file *file,
- struct page *page,
- unsigned int from,
- unsigned int to)
+ struct address_space *mapping,
+ loff_t pos,
+ unsigned len,
+ unsigned flags,
+ struct page **pagep,
+ void **fsdata)
{
- return block_prepare_write(page, from, to, xfs_get_blocks);
+ *pagep = NULL;
+ return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ xfs_get_blocks);
}
STATIC sector_t
@@ -1523,12 +1523,13 @@ xfs_vm_bmap(
sector_t block)
{
struct inode *inode = (struct inode *)mapping->host;
- bhv_vnode_t *vp = vn_from_inode(inode);
+ struct xfs_inode *ip = XFS_I(inode);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
- bhv_vop_rwlock(vp, VRWLOCK_READ);
- bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
- bhv_vop_rwunlock(vp, VRWLOCK_READ);
+ vn_trace_entry(XFS_I(inode), __FUNCTION__,
+ (inst_t *)__return_address);
+ xfs_rwlock(ip, VRWLOCK_READ);
+ xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF);
+ xfs_rwunlock(ip, VRWLOCK_READ);
return generic_block_bmap(mapping, block, xfs_get_blocks);
}
@@ -1568,8 +1569,8 @@ const struct address_space_operations xfs_address_space_operations = {
.sync_page = block_sync_page,
.releasepage = xfs_vm_releasepage,
.invalidatepage = xfs_vm_invalidatepage,
- .prepare_write = xfs_vm_prepare_write,
- .commit_write = generic_commit_write,
+ .write_begin = xfs_vm_write_begin,
+ .write_end = generic_write_end,
.bmap = xfs_vm_bmap,
.direct_IO = xfs_vm_direct_IO,
.migratepage = buffer_migrate_page,
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 2244e516b66..3ba0631a381 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -32,7 +32,7 @@ typedef struct xfs_ioend {
unsigned int io_type; /* delalloc / unwritten */
int io_error; /* I/O error code */
atomic_t io_remaining; /* hold count */
- struct bhv_vnode *io_vnode; /* file being written to */
+ struct inode *io_inode; /* file being written to */
struct buffer_head *io_buffer_head;/* buffer linked list head */
struct buffer_head *io_buffer_tail;/* buffer linked list tail */
size_t io_size; /* size of the extent */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 39f44ee572e..b9c8589e05c 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -187,6 +187,19 @@ free_address(
{
a_list_t *aentry;
+#ifdef CONFIG_XEN
+ /*
+ * Xen needs to be able to make sure it can get an exclusive
+ * RO mapping of pages it wants to turn into a pagetable. If
+ * a newly allocated page is also still being vmap()ed by xfs,
+ * it will cause pagetable construction to fail. This is a
+ * quick workaround to always eagerly unmap pages so that Xen
+ * is happy.
+ */
+ vunmap(addr);
+ return;
+#endif
+
aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT);
if (likely(aentry)) {
spin_lock(&as_lock);
@@ -997,7 +1010,18 @@ xfs_buf_iodone_work(
xfs_buf_t *bp =
container_of(work, xfs_buf_t, b_iodone_work);
- if (bp->b_iodone)
+ /*
+ * We can get an EOPNOTSUPP to ordered writes. Here we clear the
+ * ordered flag and reissue them. Because we can't tell the higher
+ * layers directly that they should not issue ordered I/O anymore, they
+ * need to check if the ordered flag was cleared during I/O completion.
+ */
+ if ((bp->b_error == EOPNOTSUPP) &&
+ (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) {
+ XB_TRACE(bp, "ordered_retry", bp->b_iodone);
+ bp->b_flags &= ~XBF_ORDERED;
+ xfs_buf_iorequest(bp);
+ } else if (bp->b_iodone)
(*(bp->b_iodone))(bp);
else if (bp->b_flags & XBF_ASYNC)
xfs_buf_relse(bp);
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index e3a5fedac1b..726449d4fd2 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -17,12 +17,18 @@
*/
#include "xfs.h"
#include "xfs_types.h"
-#include "xfs_dmapi.h"
+#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
+#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_export.h"
+#include "xfs_vnodeops.h"
+#include "xfs_bmap_btree.h"
+#include "xfs_inode.h"
+#include "xfs_vfsops.h"
static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
@@ -96,9 +102,7 @@ xfs_fs_encode_fh(
int len;
int is64 = 0;
#if XFS_BIG_INUMS
- bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb);
-
- if (!(vfs->vfs_flag & VFS_32BITINODES)) {
+ if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) {
/* filesystem may contain 64bit inode numbers */
is64 = XFS_FILEID_TYPE_64FLAG;
}
@@ -138,10 +142,9 @@ xfs_fs_get_dentry(
bhv_vnode_t *vp;
struct inode *inode;
struct dentry *result;
- bhv_vfs_t *vfsp = vfs_from_sb(sb);
int error;
- error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
+ error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data);
if (error || vp == NULL)
return ERR_PTR(-ESTALE) ;
@@ -159,12 +162,11 @@ xfs_fs_get_parent(
struct dentry *child)
{
int error;
- bhv_vnode_t *vp, *cvp;
+ bhv_vnode_t *cvp;
struct dentry *parent;
cvp = NULL;
- vp = vn_from_inode(child->d_inode);
- error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
+ error = xfs_lookup(XFS_I(child->d_inode), &dotdot, &cvp);
if (unlikely(error))
return ERR_PTR(-error);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 0d4001eafd1..fb8dd34041e 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -37,6 +37,7 @@
#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_ioctl32.h"
+#include "xfs_vnodeops.h"
#include <linux/dcache.h>
#include <linux/smp_lock.h>
@@ -55,13 +56,12 @@ __xfs_file_read(
loff_t pos)
{
struct file *file = iocb->ki_filp;
- bhv_vnode_t *vp = vn_from_inode(file->f_path.dentry->d_inode);
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
- return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos,
- ioflags, NULL);
+ return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
+ nr_segs, &iocb->ki_pos, ioflags);
}
STATIC ssize_t
@@ -93,14 +93,12 @@ __xfs_file_write(
loff_t pos)
{
struct file *file = iocb->ki_filp;
- struct inode *inode = file->f_mapping->host;
- bhv_vnode_t *vp = vn_from_inode(inode);
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
- return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos,
- ioflags, NULL);
+ return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
+ &iocb->ki_pos, ioflags);
}
STATIC ssize_t
@@ -131,8 +129,8 @@ xfs_file_splice_read(
size_t len,
unsigned int flags)
{
- return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, 0, NULL);
+ return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
+ infilp, ppos, pipe, len, flags, 0);
}
STATIC ssize_t
@@ -143,9 +141,8 @@ xfs_file_splice_read_invis(
size_t len,
unsigned int flags)
{
- return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode),
- infilp, ppos, pipe, len, flags, IO_INVIS,
- NULL);
+ return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
+ infilp, ppos, pipe, len, flags, IO_INVIS);
}
STATIC ssize_t
@@ -156,8 +153,8 @@ xfs_file_splice_write(
size_t len,
unsigned int flags)
{
- return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, 0, NULL);
+ return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
+ pipe, outfilp, ppos, len, flags, 0);
}
STATIC ssize_t
@@ -168,9 +165,8 @@ xfs_file_splice_write_invis(
size_t len,
unsigned int flags)
{
- return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode),
- pipe, outfilp, ppos, len, flags, IO_INVIS,
- NULL);
+ return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
+ pipe, outfilp, ppos, len, flags, IO_INVIS);
}
STATIC int
@@ -180,7 +176,7 @@ xfs_file_open(
{
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
return -EFBIG;
- return -bhv_vop_open(vn_from_inode(inode), NULL);
+ return -xfs_open(XFS_I(inode));
}
STATIC int
@@ -188,11 +184,7 @@ xfs_file_release(
struct inode *inode,
struct file *filp)
{
- bhv_vnode_t *vp = vn_from_inode(inode);
-
- if (vp)
- return -bhv_vop_release(vp);
- return 0;
+ return -xfs_release(XFS_I(inode));
}
STATIC int
@@ -201,14 +193,13 @@ xfs_file_fsync(
struct dentry *dentry,
int datasync)
{
- bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
int flags = FSYNC_WAIT;
if (datasync)
flags |= FSYNC_DATA;
- if (VN_TRUNC(vp))
- VUNTRUNCATE(vp);
- return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
+ xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED);
+ return -xfs_fsync(XFS_I(dentry->d_inode), flags,
+ (xfs_off_t)0, (xfs_off_t)-1);
}
#ifdef CONFIG_XFS_DMAPI
@@ -233,74 +224,30 @@ xfs_file_readdir(
void *dirent,
filldir_t filldir)
{
- int error = 0;
- bhv_vnode_t *vp = vn_from_inode(filp->f_path.dentry->d_inode);
- uio_t uio;
- iovec_t iov;
- int eof = 0;
- caddr_t read_buf;
- int namelen, size = 0;
- size_t rlen = PAGE_CACHE_SIZE;
- xfs_off_t start_offset, curr_offset;
- xfs_dirent_t *dbp = NULL;
-
- /* Try fairly hard to get memory */
- do {
- if ((read_buf = kmalloc(rlen, GFP_KERNEL)))
- break;
- rlen >>= 1;
- } while (rlen >= 1024);
-
- if (read_buf == NULL)
- return -ENOMEM;
-
- uio.uio_iov = &iov;
- uio.uio_segflg = UIO_SYSSPACE;
- curr_offset = filp->f_pos;
- if (filp->f_pos != 0x7fffffff)
- uio.uio_offset = filp->f_pos;
- else
- uio.uio_offset = 0xffffffff;
-
- while (!eof) {
- uio.uio_resid = iov.iov_len = rlen;
- iov.iov_base = read_buf;
- uio.uio_iovcnt = 1;
-
- start_offset = uio.uio_offset;
-
- error = bhv_vop_readdir(vp, &uio, NULL, &eof);
- if ((uio.uio_offset == start_offset) || error) {
- size = 0;
- break;
- }
-
- size = rlen - uio.uio_resid;
- dbp = (xfs_dirent_t *)read_buf;
- while (size > 0) {
- namelen = strlen(dbp->d_name);
-
- if (filldir(dirent, dbp->d_name, namelen,
- (loff_t) curr_offset & 0x7fffffff,
- (ino_t) dbp->d_ino,
- DT_UNKNOWN)) {
- goto done;
- }
- size -= dbp->d_reclen;
- curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
- dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
- }
- }
-done:
- if (!error) {
- if (size == 0)
- filp->f_pos = uio.uio_offset & 0x7fffffff;
- else if (dbp)
- filp->f_pos = curr_offset;
- }
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ xfs_inode_t *ip = XFS_I(inode);
+ int error;
+ size_t bufsize;
+
+ /*
+ * The Linux API doesn't pass down the total size of the buffer
+ * we read into down to the filesystem. With the filldir concept
+ * it's not needed for correct information, but the XFS dir2 leaf
+ * code wants an estimate of the buffer size to calculate it's
+ * readahead window and size the buffers used for mapping to
+ * physical blocks.
+ *
+ * Try to give it an estimate that's good enough, maybe at some
+ * point we can change the ->readdir prototype to include the
+ * buffer size.
+ */
+ bufsize = (size_t)min_t(loff_t, PAGE_SIZE, inode->i_size);
- kfree(read_buf);
- return -error;
+ error = xfs_readdir(ip, dirent, bufsize,
+ (xfs_off_t *)&filp->f_pos, filldir);
+ if (error)
+ return -error;
+ return 0;
}
STATIC int
@@ -312,7 +259,7 @@ xfs_file_mmap(
vma->vm_flags |= VM_CAN_NONLINEAR;
#ifdef CONFIG_XFS_DMAPI
- if (vn_from_inode(filp->f_path.dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
+ if (XFS_M(filp->f_path.dentry->d_inode->i_sb)->m_flags & XFS_MOUNT_DMAPI)
vma->vm_ops = &xfs_dmapi_file_vm_ops;
#endif /* CONFIG_XFS_DMAPI */
@@ -328,10 +275,9 @@ xfs_file_ioctl(
{
int error;
struct inode *inode = filp->f_path.dentry->d_inode;
- bhv_vnode_t *vp = vn_from_inode(inode);
- error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
- VMODIFY(vp);
+ error = xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
+ xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
/* NOTE: some of the ioctl's return positive #'s as a
* byte count indicating success, such as
@@ -350,10 +296,9 @@ xfs_file_ioctl_invis(
{
int error;
struct inode *inode = filp->f_path.dentry->d_inode;
- bhv_vnode_t *vp = vn_from_inode(inode);
- error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
- VMODIFY(vp);
+ error = xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p);
+ xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
/* NOTE: some of the ioctl's return positive #'s as a
* byte count indicating success, such as
@@ -371,16 +316,14 @@ xfs_vm_mprotect(
struct vm_area_struct *vma,
unsigned int newflags)
{
- bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_path.dentry->d_inode);
+ struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
+ struct xfs_mount *mp = XFS_M(inode->i_sb);
int error = 0;
- if (vp->v_vfsp->vfs_flag & VFS_DMI) {
+ if (mp->m_flags & XFS_MOUNT_DMAPI) {
if ((vma->vm_flags & VM_MAYSHARE) &&
- (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE)) {
- xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
-
+ (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE))
error = XFS_SEND_MMAP(mp, vma, VM_WRITE);
- }
}
return error;
}
@@ -397,18 +340,17 @@ STATIC int
xfs_file_open_exec(
struct inode *inode)
{
- bhv_vnode_t *vp = vn_from_inode(inode);
+ struct xfs_mount *mp = XFS_M(inode->i_sb);
- if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
- xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
- xfs_inode_t *ip = xfs_vtoi(vp);
+ if (unlikely(mp->m_flags & XFS_MOUNT_DMAPI)) {
+ if (DM_EVENT_ENABLED(XFS_I(inode), DM_EVENT_READ)) {
+ bhv_vnode_t *vp = vn_from_inode(inode);
- if (!ip)
- return -EINVAL;
- if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
- return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
- 0, 0, 0, NULL);
+ return -XFS_SEND_DATA(mp, DM_EVENT_READ,
+ vp, 0, 0, 0, NULL);
+ }
}
+
return 0;
}
#endif /* HAVE_FOP_OPEN_EXEC */
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 2eb87cd082a..ac6d34cc355 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -16,66 +16,78 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
+#include "xfs_vnodeops.h"
+
+/*
+ * The following six includes are needed so that we can include
+ * xfs_inode.h. What a mess..
+ */
+#include "xfs_bmap_btree.h"
+#include "xfs_inum.h"
+#include "xfs_dir2.h"
+#include "xfs_dir2_sf.h"
+#include "xfs_attr_sf.h"
+#include "xfs_dinode.h"
+
+#include "xfs_inode.h"
int fs_noerr(void) { return 0; }
int fs_nosys(void) { return ENOSYS; }
void fs_noval(void) { return; }
void
-fs_tosspages(
- bhv_desc_t *bdp,
+xfs_tosspages(
+ xfs_inode_t *ip,
xfs_off_t first,
xfs_off_t last,
int fiopt)
{
- bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
- struct inode *ip = vn_to_inode(vp);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ struct inode *inode = vn_to_inode(vp);
if (VN_CACHED(vp))
- truncate_inode_pages(ip->i_mapping, first);
+ truncate_inode_pages(inode->i_mapping, first);
}
int
-fs_flushinval_pages(
- bhv_desc_t *bdp,
+xfs_flushinval_pages(
+ xfs_inode_t *ip,
xfs_off_t first,
xfs_off_t last,
int fiopt)
{
- bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
- struct inode *ip = vn_to_inode(vp);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ struct inode *inode = vn_to_inode(vp);
int ret = 0;
if (VN_CACHED(vp)) {
- if (VN_TRUNC(vp))
- VUNTRUNCATE(vp);
- ret = filemap_write_and_wait(ip->i_mapping);
+ xfs_iflags_clear(ip, XFS_ITRUNCATED);
+ ret = filemap_write_and_wait(inode->i_mapping);
if (!ret)
- truncate_inode_pages(ip->i_mapping, first);
+ truncate_inode_pages(inode->i_mapping, first);
}
return ret;
}
int
-fs_flush_pages(
- bhv_desc_t *bdp,
+xfs_flush_pages(
+ xfs_inode_t *ip,
xfs_off_t first,
xfs_off_t last,
uint64_t flags,
int fiopt)
{
- bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
- struct inode *ip = vn_to_inode(vp);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ struct inode *inode = vn_to_inode(vp);
int ret = 0;
int ret2;
if (VN_DIRTY(vp)) {
- if (VN_TRUNC(vp))
- VUNTRUNCATE(vp);
- ret = filemap_fdatawrite(ip->i_mapping);
+ xfs_iflags_clear(ip, XFS_ITRUNCATED);
+ ret = filemap_fdatawrite(inode->i_mapping);
if (flags & XFS_B_ASYNC)
return ret;
- ret2 = filemap_fdatawait(ip->i_mapping);
+ ret2 = filemap_fdatawait(inode->i_mapping);
if (!ret)
ret = ret2;
}
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h
index c1b53118a30..82bb19b2599 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.h
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.h
@@ -18,12 +18,8 @@
#ifndef __XFS_FS_SUBR_H__
#define __XFS_FS_SUBR_H__
-struct cred;
extern int fs_noerr(void);
extern int fs_nosys(void);
extern void fs_noval(void);
-extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
#endif /* __XFS_FS_SUBR_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index 81565dea9af..9febf9dc999 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -20,11 +20,6 @@
#include "xfs_sysctl.h"
/*
- * System memory size - used to scale certain data structures in XFS.
- */
-unsigned long xfs_physmem;
-
-/*
* Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
* other XFS code uses these values. Times are measured in centisecs (i.e.
* 100ths of a second).
diff --git a/fs/xfs/linux-2.6/xfs_globals.h b/fs/xfs/linux-2.6/xfs_globals.h
index e1a22bfcf86..2770b0085ee 100644
--- a/fs/xfs/linux-2.6/xfs_globals.h
+++ b/fs/xfs/linux-2.6/xfs_globals.h
@@ -19,7 +19,6 @@
#define __XFS_GLOBALS_H__
extern uint64_t xfs_panic_mask; /* set to cause more panics */
-extern unsigned long xfs_physmem;
extern struct cred *sys_cred;
#endif /* __XFS_GLOBALS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 5917808abbd..ffec630e7db 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -47,6 +47,7 @@
#include "xfs_utils.h"
#include "xfs_dfrag.h"
#include "xfs_fsops.h"
+#include "xfs_vnodeops.h"
#include <linux/capability.h>
#include <linux/dcache.h>
@@ -137,7 +138,8 @@ xfs_find_handle(
vp = vn_from_inode(inode);
/* now we can grab the fsid */
- memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t));
+ memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
+ sizeof(xfs_fsid_t));
hsize = sizeof(xfs_fsid_t);
if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
@@ -349,19 +351,44 @@ xfs_open_by_handle(
return new_fd;
}
+/*
+ * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
+ * unused first argument.
+ */
+STATIC int
+do_readlink(
+ char __user *buffer,
+ int buflen,
+ const char *link)
+{
+ int len;
+
+ len = PTR_ERR(link);
+ if (IS_ERR(link))
+ goto out;
+
+ len = strlen(link);
+ if (len > (unsigned) buflen)
+ len = buflen;
+ if (copy_to_user(buffer, link, len))
+ len = -EFAULT;
+ out:
+ return len;
+}
+
+
STATIC int
xfs_readlink_by_handle(
xfs_mount_t *mp,
void __user *arg,
struct inode *parinode)
{
- int error;
- struct iovec aiov;
- struct uio auio;
struct inode *inode;
xfs_fsop_handlereq_t hreq;
bhv_vnode_t *vp;
__u32 olen;
+ void *link;
+ int error;
if (!capable(CAP_SYS_ADMIN))
return -XFS_ERROR(EPERM);
@@ -374,29 +401,31 @@ xfs_readlink_by_handle(
/* Restrict this handle operation to symlinks only. */
if (!S_ISLNK(inode->i_mode)) {
- VN_RELE(vp);
- return -XFS_ERROR(EINVAL);
+ error = -XFS_ERROR(EINVAL);
+ goto out_iput;
}
if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
- VN_RELE(vp);
- return -XFS_ERROR(EFAULT);
+ error = -XFS_ERROR(EFAULT);
+ goto out_iput;
}
- aiov.iov_len = olen;
- aiov.iov_base = hreq.ohandle;
- auio.uio_iov = (struct kvec *)&aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = 0;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_resid = olen;
+ link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
+ if (!link)
+ goto out_iput;
- error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
- VN_RELE(vp);
+ error = -xfs_readlink(XFS_I(inode), link);
if (error)
- return -error;
+ goto out_kfree;
+ error = do_readlink(hreq.ohandle, olen, link);
+ if (error)
+ goto out_kfree;
- return (olen - auio.uio_resid);
+ out_kfree:
+ kfree(link);
+ out_iput:
+ iput(inode);
+ return error;
}
STATIC int
@@ -409,7 +438,6 @@ xfs_fssetdm_by_handle(
struct fsdmidata fsd;
xfs_fsop_setdm_handlereq_t dmhreq;
struct inode *inode;
- bhv_desc_t *bdp;
bhv_vnode_t *vp;
if (!capable(CAP_MKNOD))
@@ -431,8 +459,8 @@ xfs_fssetdm_by_handle(
return -XFS_ERROR(EFAULT);
}
- bdp = bhv_base_unlocked(VN_BHV_HEAD(vp));
- error = xfs_set_dmattrs(bdp, fsd.fsd_dmevmask, fsd.fsd_dmstate, NULL);
+ error = xfs_set_dmattrs(xfs_vtoi(vp),
+ fsd.fsd_dmevmask, fsd.fsd_dmstate);
VN_RELE(vp);
if (error)
@@ -470,8 +498,8 @@ xfs_attrlist_by_handle(
goto out_vn_rele;
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
- error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
- cursor, NULL);
+ error = xfs_attr_list(XFS_I(inode), kbuf, al_hreq.buflen,
+ al_hreq.flags, cursor);
if (error)
goto out_kfree;
@@ -488,7 +516,7 @@ xfs_attrlist_by_handle(
STATIC int
xfs_attrmulti_attr_get(
- bhv_vnode_t *vp,
+ struct inode *inode,
char *name,
char __user *ubuf,
__uint32_t *len,
@@ -503,7 +531,7 @@ xfs_attrmulti_attr_get(
if (!kbuf)
return ENOMEM;
- error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
+ error = xfs_attr_get(XFS_I(inode), name, kbuf, len, flags, NULL);
if (error)
goto out_kfree;
@@ -517,7 +545,7 @@ xfs_attrmulti_attr_get(
STATIC int
xfs_attrmulti_attr_set(
- bhv_vnode_t *vp,
+ struct inode *inode,
char *name,
const char __user *ubuf,
__uint32_t len,
@@ -526,9 +554,9 @@ xfs_attrmulti_attr_set(
char *kbuf;
int error = EFAULT;
- if (IS_RDONLY(&vp->v_inode))
+ if (IS_RDONLY(inode))
return -EROFS;
- if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return EPERM;
if (len > XATTR_SIZE_MAX)
return EINVAL;
@@ -540,7 +568,7 @@ xfs_attrmulti_attr_set(
if (copy_from_user(kbuf, ubuf, len))
goto out_kfree;
- error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
+ error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
out_kfree:
kfree(kbuf);
@@ -549,15 +577,15 @@ xfs_attrmulti_attr_set(
STATIC int
xfs_attrmulti_attr_remove(
- bhv_vnode_t *vp,
+ struct inode *inode,
char *name,
__uint32_t flags)
{
- if (IS_RDONLY(&vp->v_inode))
+ if (IS_RDONLY(inode))
return -EROFS;
- if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return EPERM;
- return bhv_vop_attr_remove(vp, name, flags, NULL);
+ return xfs_attr_remove(XFS_I(inode), name, flags);
}
STATIC int
@@ -613,17 +641,17 @@ xfs_attrmulti_by_handle(
switch (ops[i].am_opcode) {
case ATTR_OP_GET:
- ops[i].am_error = xfs_attrmulti_attr_get(vp,
+ ops[i].am_error = xfs_attrmulti_attr_get(inode,
attr_name, ops[i].am_attrvalue,
&ops[i].am_length, ops[i].am_flags);
break;
case ATTR_OP_SET:
- ops[i].am_error = xfs_attrmulti_attr_set(vp,
+ ops[i].am_error = xfs_attrmulti_attr_set(inode,
attr_name, ops[i].am_attrvalue,
ops[i].am_length, ops[i].am_flags);
break;
case ATTR_OP_REMOVE:
- ops[i].am_error = xfs_attrmulti_attr_remove(vp,
+ ops[i].am_error = xfs_attrmulti_attr_remove(inode,
attr_name, ops[i].am_flags);
break;
default:
@@ -649,7 +677,7 @@ xfs_attrmulti_by_handle(
STATIC int
xfs_ioc_space(
- bhv_desc_t *bdp,
+ struct xfs_inode *ip,
struct inode *inode,
struct file *filp,
int flags,
@@ -681,37 +709,37 @@ xfs_ioc_xattr(
void __user *arg);
STATIC int
+xfs_ioc_fsgetxattr(
+ xfs_inode_t *ip,
+ int attr,
+ void __user *arg);
+
+STATIC int
xfs_ioc_getbmap(
- bhv_desc_t *bdp,
+ struct xfs_inode *ip,
int flags,
unsigned int cmd,
void __user *arg);
STATIC int
xfs_ioc_getbmapx(
- bhv_desc_t *bdp,
+ struct xfs_inode *ip,
void __user *arg);
int
xfs_ioctl(
- bhv_desc_t *bdp,
- struct inode *inode,
+ xfs_inode_t *ip,
struct file *filp,
int ioflags,
unsigned int cmd,
void __user *arg)
{
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ bhv_vnode_t *vp = vn_from_inode(inode);
+ xfs_mount_t *mp = ip->i_mount;
int error;
- bhv_vnode_t *vp;
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- vp = vn_from_inode(inode);
-
- vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
+ vn_trace_entry(XFS_I(inode), "xfs_ioctl", (inst_t *)__return_address);
switch (cmd) {
@@ -731,7 +759,7 @@ xfs_ioctl(
!capable(CAP_SYS_ADMIN))
return -EPERM;
- return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg);
+ return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
case XFS_IOC_DIOINFO: {
struct dioattr da;
@@ -761,11 +789,13 @@ xfs_ioctl(
case XFS_IOC_GETVERSION:
return put_user(inode->i_generation, (int __user *)arg);
+ case XFS_IOC_FSGETXATTR:
+ return xfs_ioc_fsgetxattr(ip, 0, arg);
+ case XFS_IOC_FSGETXATTRA:
+ return xfs_ioc_fsgetxattr(ip, 1, arg);
case XFS_IOC_GETXFLAGS:
case XFS_IOC_SETXFLAGS:
- case XFS_IOC_FSGETXATTR:
case XFS_IOC_FSSETXATTR:
- case XFS_IOC_FSGETXATTRA:
return xfs_ioc_xattr(vp, ip, filp, cmd, arg);
case XFS_IOC_FSSETDM: {
@@ -774,17 +804,17 @@ xfs_ioctl(
if (copy_from_user(&dmi, arg, sizeof(dmi)))
return -XFS_ERROR(EFAULT);
- error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate,
- NULL);
+ error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
+ dmi.fsd_dmstate);
return -error;
}
case XFS_IOC_GETBMAP:
case XFS_IOC_GETBMAPA:
- return xfs_ioc_getbmap(bdp, ioflags, cmd, arg);
+ return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
case XFS_IOC_GETBMAPX:
- return xfs_ioc_getbmapx(bdp, arg);
+ return xfs_ioc_getbmapx(ip, arg);
case XFS_IOC_FD_TO_HANDLE:
case XFS_IOC_PATH_TO_HANDLE:
@@ -944,7 +974,7 @@ xfs_ioctl(
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- error = xfs_errortag_clearall(mp);
+ error = xfs_errortag_clearall(mp, 1);
return -error;
default:
@@ -954,7 +984,7 @@ xfs_ioctl(
STATIC int
xfs_ioc_space(
- bhv_desc_t *bdp,
+ struct xfs_inode *ip,
struct inode *inode,
struct file *filp,
int ioflags,
@@ -982,7 +1012,7 @@ xfs_ioc_space(
if (ioflags & IO_INVIS)
attr_flags |= ATTR_DMI;
- error = xfs_change_file_space(bdp, cmd, &bf, filp->f_pos,
+ error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos,
NULL, attr_flags);
return -error;
}
@@ -1140,6 +1170,42 @@ xfs_di2lxflags(
}
STATIC int
+xfs_ioc_fsgetxattr(
+ xfs_inode_t *ip,
+ int attr,
+ void __user *arg)
+{
+ struct fsxattr fa;
+
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ fa.fsx_xflags = xfs_ip2xflags(ip);
+ fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
+ fa.fsx_projid = ip->i_d.di_projid;
+
+ if (attr) {
+ if (ip->i_afp) {
+ if (ip->i_afp->if_flags & XFS_IFEXTENTS)
+ fa.fsx_nextents = ip->i_afp->if_bytes /
+ sizeof(xfs_bmbt_rec_t);
+ else
+ fa.fsx_nextents = ip->i_d.di_anextents;
+ } else
+ fa.fsx_nextents = 0;
+ } else {
+ if (ip->i_df.if_flags & XFS_IFEXTENTS)
+ fa.fsx_nextents = ip->i_df.if_bytes /
+ sizeof(xfs_bmbt_rec_t);
+ else
+ fa.fsx_nextents = ip->i_d.di_nextents;
+ }
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+ if (copy_to_user(arg, &fa, sizeof(fa)))
+ return -EFAULT;
+ return 0;
+}
+
+STATIC int
xfs_ioc_xattr(
bhv_vnode_t *vp,
xfs_inode_t *ip,
@@ -1158,27 +1224,6 @@ xfs_ioc_xattr(
return -ENOMEM;
switch (cmd) {
- case XFS_IOC_FSGETXATTR: {
- vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
- XFS_AT_NEXTENTS | XFS_AT_PROJID;
- error = bhv_vop_getattr(vp, vattr, 0, NULL);
- if (unlikely(error)) {
- error = -error;
- break;
- }
-
- fa.fsx_xflags = vattr->va_xflags;
- fa.fsx_extsize = vattr->va_extsize;
- fa.fsx_nextents = vattr->va_nextents;
- fa.fsx_projid = vattr->va_projid;
-
- if (copy_to_user(arg, &fa, sizeof(fa))) {
- error = -EFAULT;
- break;
- }
- break;
- }
-
case XFS_IOC_FSSETXATTR: {
if (copy_from_user(&fa, arg, sizeof(fa))) {
error = -EFAULT;
@@ -1194,34 +1239,13 @@ xfs_ioc_xattr(
vattr->va_extsize = fa.fsx_extsize;
vattr->va_projid = fa.fsx_projid;
- error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
+ error = xfs_setattr(ip, vattr, attr_flags, NULL);
if (likely(!error))
__vn_revalidate(vp, vattr); /* update flags */
error = -error;
break;
}
- case XFS_IOC_FSGETXATTRA: {
- vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
- XFS_AT_ANEXTENTS | XFS_AT_PROJID;
- error = bhv_vop_getattr(vp, vattr, 0, NULL);
- if (unlikely(error)) {
- error = -error;
- break;
- }
-
- fa.fsx_xflags = vattr->va_xflags;
- fa.fsx_extsize = vattr->va_extsize;
- fa.fsx_nextents = vattr->va_anextents;
- fa.fsx_projid = vattr->va_projid;
-
- if (copy_to_user(arg, &fa, sizeof(fa))) {
- error = -EFAULT;
- break;
- }
- break;
- }
-
case XFS_IOC_GETXFLAGS: {
flags = xfs_di2lxflags(ip->i_d.di_flags);
if (copy_to_user(arg, &flags, sizeof(flags)))
@@ -1250,7 +1274,7 @@ xfs_ioc_xattr(
vattr->va_xflags = xfs_merge_ioc_xflags(flags,
xfs_ip2xflags(ip));
- error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
+ error = xfs_setattr(ip, vattr, attr_flags, NULL);
if (likely(!error))
__vn_revalidate(vp, vattr); /* update flags */
error = -error;
@@ -1268,7 +1292,7 @@ xfs_ioc_xattr(
STATIC int
xfs_ioc_getbmap(
- bhv_desc_t *bdp,
+ struct xfs_inode *ip,
int ioflags,
unsigned int cmd,
void __user *arg)
@@ -1287,7 +1311,7 @@ xfs_ioc_getbmap(
if (ioflags & IO_INVIS)
iflags |= BMV_IF_NO_DMAPI_READ;
- error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags);
+ error = xfs_getbmap(ip, &bm, (struct getbmap __user *)arg+1, iflags);
if (error)
return -error;
@@ -1298,7 +1322,7 @@ xfs_ioc_getbmap(
STATIC int
xfs_ioc_getbmapx(
- bhv_desc_t *bdp,
+ struct xfs_inode *ip,
void __user *arg)
{
struct getbmapx bmx;
@@ -1325,7 +1349,7 @@ xfs_ioc_getbmapx(
iflags |= BMV_IF_EXTENDED;
- error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags);
+ error = xfs_getbmap(ip, &bm, (struct getbmapx __user *)arg+1, iflags);
if (error)
return -error;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 42319d75aaa..0046bdd5b7f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -43,6 +43,7 @@
#include "xfs_itable.h"
#include "xfs_error.h"
#include "xfs_dfrag.h"
+#include "xfs_vnodeops.h"
#define _NATIVE_IOC(cmd, type) \
_IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type))
@@ -370,7 +371,6 @@ xfs_compat_ioctl(
unsigned long arg)
{
struct inode *inode = file->f_path.dentry->d_inode;
- bhv_vnode_t *vp = vn_from_inode(inode);
int error;
switch (cmd) {
@@ -443,7 +443,7 @@ xfs_compat_ioctl(
case XFS_IOC_FSBULKSTAT_SINGLE_32:
case XFS_IOC_FSINUMBERS_32:
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_bulkreq);
- return xfs_ioc_bulkstat_compat(XFS_BHVTOI(VNHEAD(vp))->i_mount,
+ return xfs_ioc_bulkstat_compat(XFS_I(inode)->i_mount,
cmd, (void __user*)arg);
case XFS_IOC_FD_TO_HANDLE_32:
case XFS_IOC_PATH_TO_HANDLE_32:
@@ -457,8 +457,8 @@ xfs_compat_ioctl(
return -ENOIOCTLCMD;
}
- error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
- VMODIFY(vp);
+ error = xfs_ioctl(XFS_I(inode), file, mode, cmd, (void __user *)arg);
+ xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
return error;
}
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 0b5fa124bef..ac50f8a3758 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -46,6 +46,7 @@
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
+#include "xfs_vnodeops.h"
#include <linux/capability.h>
#include <linux/xattr.h>
@@ -53,22 +54,6 @@
#include <linux/security.h>
/*
- * Get a XFS inode from a given vnode.
- */
-xfs_inode_t *
-xfs_vtoi(
- bhv_vnode_t *vp)
-{
- bhv_desc_t *bdp;
-
- bdp = bhv_lookup_range(VN_BHV_HEAD(vp),
- VNODE_POSITION_XFS, VNODE_POSITION_XFS);
- if (unlikely(bdp == NULL))
- return NULL;
- return XFS_BHVTOI(bdp);
-}
-
-/*
* Bring the atime in the XFS inode uptodate.
* Used before logging the inode to disk or when the Linux inode goes away.
*/
@@ -80,9 +65,8 @@ xfs_synchronize_atime(
vp = XFS_ITOV_NULL(ip);
if (vp) {
- struct inode *inode = &vp->v_inode;
- ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
- ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
+ ip->i_d.di_atime.t_sec = (__int32_t)vp->i_atime.tv_sec;
+ ip->i_d.di_atime.t_nsec = (__int32_t)vp->i_atime.tv_nsec;
}
}
@@ -133,7 +117,7 @@ xfs_ichgtime(
*/
SYNCHRONIZE();
ip->i_update_core = 1;
- if (!(inode->i_state & I_LOCK))
+ if (!(inode->i_state & I_SYNC))
mark_inode_dirty_sync(inode);
}
@@ -185,7 +169,7 @@ xfs_ichgtime_fast(
*/
SYNCHRONIZE();
ip->i_update_core = 1;
- if (!(inode->i_state & I_LOCK))
+ if (!(inode->i_state & I_SYNC))
mark_inode_dirty_sync(inode);
}
@@ -195,18 +179,19 @@ xfs_ichgtime_fast(
*/
STATIC void
xfs_validate_fields(
- struct inode *ip,
- bhv_vattr_t *vattr)
+ struct inode *inode)
{
- vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
- if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
- ip->i_nlink = vattr->va_nlink;
- ip->i_blocks = vattr->va_nblocks;
-
- /* we're under i_sem so i_size can't change under us */
- if (i_size_read(ip) != vattr->va_size)
- i_size_write(ip, vattr->va_size);
- }
+ struct xfs_inode *ip = XFS_I(inode);
+ loff_t size;
+
+ inode->i_nlink = ip->i_d.di_nlink;
+ inode->i_blocks =
+ XFS_FSB_TO_BB(ip->i_mount, ip->i_d.di_nblocks +
+ ip->i_delayed_blks);
+ /* we're under i_sem so i_size can't change under us */
+ size = XFS_ISIZE(ip);
+ if (i_size_read(inode) != size)
+ i_size_write(inode, size);
}
/*
@@ -233,9 +218,10 @@ xfs_init_security(
return -error;
}
- error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
+ error = xfs_attr_set(XFS_I(ip), name, value,
+ length, ATTR_SECURE);
if (!error)
- VMODIFY(vp);
+ xfs_iflags_set(XFS_I(ip), XFS_IMODIFIED);
kfree(name);
kfree(value);
@@ -256,7 +242,7 @@ xfs_has_fs_struct(struct task_struct *task)
STATIC void
xfs_cleanup_inode(
- bhv_vnode_t *dvp,
+ struct inode *dir,
bhv_vnode_t *vp,
struct dentry *dentry,
int mode)
@@ -272,9 +258,9 @@ xfs_cleanup_inode(
teardown.d_name = dentry->d_name;
if (S_ISDIR(mode))
- bhv_vop_rmdir(dvp, &teardown, NULL);
+ xfs_rmdir(XFS_I(dir), &teardown);
else
- bhv_vop_remove(dvp, &teardown, NULL);
+ xfs_remove(XFS_I(dir), &teardown);
VN_RELE(vp);
}
@@ -286,7 +272,6 @@ xfs_vn_mknod(
dev_t rdev)
{
struct inode *ip;
- bhv_vattr_t vattr = { 0 };
bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
xfs_acl_t *default_acl = NULL;
attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
@@ -312,19 +297,14 @@ xfs_vn_mknod(
if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current))
mode &= ~current->fs->umask;
- vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
- vattr.va_mode = mode;
-
switch (mode & S_IFMT) {
case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
- vattr.va_rdev = sysv_encode_dev(rdev);
- vattr.va_mask |= XFS_AT_RDEV;
- /*FALLTHROUGH*/
+ rdev = sysv_encode_dev(rdev);
case S_IFREG:
- error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
+ error = xfs_create(XFS_I(dir), dentry, mode, rdev, &vp, NULL);
break;
case S_IFDIR:
- error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
+ error = xfs_mkdir(XFS_I(dir), dentry, mode, &vp, NULL);
break;
default:
error = EINVAL;
@@ -334,16 +314,16 @@ xfs_vn_mknod(
if (unlikely(!error)) {
error = xfs_init_security(vp, dir);
if (error)
- xfs_cleanup_inode(dvp, vp, dentry, mode);
+ xfs_cleanup_inode(dir, vp, dentry, mode);
}
if (unlikely(default_acl)) {
if (!error) {
- error = _ACL_INHERIT(vp, &vattr, default_acl);
+ error = _ACL_INHERIT(vp, mode, default_acl);
if (!error)
- VMODIFY(vp);
+ xfs_iflags_set(XFS_I(vp), XFS_IMODIFIED);
else
- xfs_cleanup_inode(dvp, vp, dentry, mode);
+ xfs_cleanup_inode(dir, vp, dentry, mode);
}
_ACL_FREE(default_acl);
}
@@ -355,9 +335,9 @@ xfs_vn_mknod(
if (S_ISCHR(mode) || S_ISBLK(mode))
ip->i_rdev = rdev;
else if (S_ISDIR(mode))
- xfs_validate_fields(ip, &vattr);
+ xfs_validate_fields(ip);
d_instantiate(dentry, ip);
- xfs_validate_fields(dir, &vattr);
+ xfs_validate_fields(dir);
}
return -error;
}
@@ -387,13 +367,13 @@ xfs_vn_lookup(
struct dentry *dentry,
struct nameidata *nd)
{
- bhv_vnode_t *vp = vn_from_inode(dir), *cvp;
+ bhv_vnode_t *cvp;
int error;
if (dentry->d_name.len >= MAXNAMELEN)
return ERR_PTR(-ENAMETOOLONG);
- error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
+ error = xfs_lookup(XFS_I(dir), dentry, &cvp);
if (unlikely(error)) {
if (unlikely(error != ENOENT))
return ERR_PTR(-error);
@@ -411,22 +391,19 @@ xfs_vn_link(
struct dentry *dentry)
{
struct inode *ip; /* inode of guy being linked to */
- bhv_vnode_t *tdvp; /* target directory for new name/link */
bhv_vnode_t *vp; /* vp of name being linked */
- bhv_vattr_t vattr;
int error;
ip = old_dentry->d_inode; /* inode being linked to */
- tdvp = vn_from_inode(dir);
vp = vn_from_inode(ip);
VN_HOLD(vp);
- error = bhv_vop_link(tdvp, vp, dentry, NULL);
+ error = xfs_link(XFS_I(dir), vp, dentry);
if (unlikely(error)) {
VN_RELE(vp);
} else {
- VMODIFY(tdvp);
- xfs_validate_fields(ip, &vattr);
+ xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
+ xfs_validate_fields(ip);
d_instantiate(dentry, ip);
}
return -error;
@@ -438,17 +415,14 @@ xfs_vn_unlink(
struct dentry *dentry)
{
struct inode *inode;
- bhv_vnode_t *dvp; /* directory containing name to remove */
- bhv_vattr_t vattr;
int error;
inode = dentry->d_inode;
- dvp = vn_from_inode(dir);
- error = bhv_vop_remove(dvp, dentry, NULL);
+ error = xfs_remove(XFS_I(dir), dentry);
if (likely(!error)) {
- xfs_validate_fields(dir, &vattr); /* size needs update */
- xfs_validate_fields(inode, &vattr);
+ xfs_validate_fields(dir); /* size needs update */
+ xfs_validate_fields(inode);
}
return -error;
}
@@ -460,28 +434,26 @@ xfs_vn_symlink(
const char *symname)
{
struct inode *ip;
- bhv_vattr_t va = { 0 };
- bhv_vnode_t *dvp; /* directory containing name of symlink */
bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
int error;
+ mode_t mode;
- dvp = vn_from_inode(dir);
cvp = NULL;
- va.va_mode = S_IFLNK |
+ mode = S_IFLNK |
(irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
- va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
- error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
+ error = xfs_symlink(XFS_I(dir), dentry, (char *)symname, mode,
+ &cvp, NULL);
if (likely(!error && cvp)) {
error = xfs_init_security(cvp, dir);
if (likely(!error)) {
ip = vn_to_inode(cvp);
d_instantiate(dentry, ip);
- xfs_validate_fields(dir, &va);
- xfs_validate_fields(ip, &va);
+ xfs_validate_fields(dir);
+ xfs_validate_fields(ip);
} else {
- xfs_cleanup_inode(dvp, cvp, dentry, 0);
+ xfs_cleanup_inode(dir, cvp, dentry, 0);
}
}
return -error;
@@ -493,14 +465,12 @@ xfs_vn_rmdir(
struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
- bhv_vnode_t *dvp = vn_from_inode(dir);
- bhv_vattr_t vattr;
int error;
- error = bhv_vop_rmdir(dvp, dentry, NULL);
+ error = xfs_rmdir(XFS_I(dir), dentry);
if (likely(!error)) {
- xfs_validate_fields(inode, &vattr);
- xfs_validate_fields(dir, &vattr);
+ xfs_validate_fields(inode);
+ xfs_validate_fields(dir);
}
return -error;
}
@@ -513,21 +483,18 @@ xfs_vn_rename(
struct dentry *ndentry)
{
struct inode *new_inode = ndentry->d_inode;
- bhv_vnode_t *fvp; /* from directory */
bhv_vnode_t *tvp; /* target directory */
- bhv_vattr_t vattr;
int error;
- fvp = vn_from_inode(odir);
tvp = vn_from_inode(ndir);
- error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
+ error = xfs_rename(XFS_I(odir), odentry, tvp, ndentry);
if (likely(!error)) {
if (new_inode)
- xfs_validate_fields(new_inode, &vattr);
- xfs_validate_fields(odir, &vattr);
+ xfs_validate_fields(new_inode);
+ xfs_validate_fields(odir);
if (ndir != odir)
- xfs_validate_fields(ndir, &vattr);
+ xfs_validate_fields(ndir);
}
return -error;
}
@@ -542,50 +509,25 @@ xfs_vn_follow_link(
struct dentry *dentry,
struct nameidata *nd)
{
- bhv_vnode_t *vp;
- uio_t *uio;
- iovec_t iov;
- int error;
char *link;
-
- ASSERT(dentry);
- ASSERT(nd);
+ int error = -ENOMEM;
link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
- if (!link) {
- nd_set_link(nd, ERR_PTR(-ENOMEM));
- return NULL;
- }
-
- uio = kmalloc(sizeof(uio_t), GFP_KERNEL);
- if (!uio) {
- kfree(link);
- nd_set_link(nd, ERR_PTR(-ENOMEM));
- return NULL;
- }
-
- vp = vn_from_inode(dentry->d_inode);
-
- iov.iov_base = link;
- iov.iov_len = MAXPATHLEN;
+ if (!link)
+ goto out_err;
- uio->uio_iov = &iov;
- uio->uio_offset = 0;
- uio->uio_segflg = UIO_SYSSPACE;
- uio->uio_resid = MAXPATHLEN;
- uio->uio_iovcnt = 1;
-
- error = bhv_vop_readlink(vp, uio, 0, NULL);
- if (unlikely(error)) {
- kfree(link);
- link = ERR_PTR(-error);
- } else {
- link[MAXPATHLEN - uio->uio_resid] = '\0';
- }
- kfree(uio);
+ error = -xfs_readlink(XFS_I(dentry->d_inode), link);
+ if (unlikely(error))
+ goto out_kfree;
nd_set_link(nd, link);
return NULL;
+
+ out_kfree:
+ kfree(link);
+ out_err:
+ nd_set_link(nd, ERR_PTR(error));
+ return NULL;
}
STATIC void
@@ -607,7 +549,7 @@ xfs_vn_permission(
int mode,
struct nameidata *nd)
{
- return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
+ return -xfs_access(XFS_I(inode), mode << 6, NULL);
}
#else
#define xfs_vn_permission NULL
@@ -620,11 +562,10 @@ xfs_vn_getattr(
struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
- bhv_vnode_t *vp = vn_from_inode(inode);
bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT };
int error;
- error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL);
+ error = xfs_getattr(XFS_I(inode), &vattr, ATTR_LAZY);
if (likely(!error)) {
stat->size = i_size_read(inode);
stat->dev = inode->i_sb->s_dev;
@@ -652,7 +593,6 @@ xfs_vn_setattr(
{
struct inode *inode = dentry->d_inode;
unsigned int ia_valid = attr->ia_valid;
- bhv_vnode_t *vp = vn_from_inode(inode);
bhv_vattr_t vattr = { 0 };
int flags = 0;
int error;
@@ -696,9 +636,9 @@ xfs_vn_setattr(
flags |= ATTR_NONBLOCK;
#endif
- error = bhv_vop_setattr(vp, &vattr, flags, NULL);
+ error = xfs_setattr(XFS_I(inode), &vattr, flags, NULL);
if (likely(!error))
- __vn_revalidate(vp, &vattr);
+ __vn_revalidate(vn_from_inode(inode), &vattr);
return -error;
}
diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/linux-2.6/xfs_iops.h
index 95a69398fce..14d0deb7aff 100644
--- a/fs/xfs/linux-2.6/xfs_iops.h
+++ b/fs/xfs/linux-2.6/xfs_iops.h
@@ -26,11 +26,15 @@ extern const struct file_operations xfs_file_operations;
extern const struct file_operations xfs_dir_file_operations;
extern const struct file_operations xfs_invis_file_operations;
-extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
- int, unsigned int, void __user *);
struct xfs_inode;
extern void xfs_ichgtime(struct xfs_inode *, int);
extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int);
+#define xfs_vtoi(vp) \
+ ((struct xfs_inode *)vn_to_inode(vp)->i_private)
+
+#define XFS_I(inode) \
+ ((struct xfs_inode *)(inode)->i_private)
+
#endif /* __XFS_IOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 330c4ba9d40..dc3752de22d 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -51,7 +51,6 @@
#include <support/ktrace.h>
#include <support/debug.h>
-#include <support/move.h>
#include <support/uuid.h>
#include <linux/mm.h>
@@ -75,6 +74,7 @@
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/delay.h>
+#include <linux/log2.h>
#include <asm/page.h>
#include <asm/div64.h>
@@ -83,7 +83,6 @@
#include <asm/byteorder.h>
#include <asm/unaligned.h>
-#include <xfs_behavior.h>
#include <xfs_vfs.h>
#include <xfs_cred.h>
#include <xfs_vnode.h>
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 765ec16a6e3..d6a8dddb226 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -48,6 +48,7 @@
#include "xfs_buf_item.h"
#include "xfs_utils.h"
#include "xfs_iomap.h"
+#include "xfs_vnodeops.h"
#include <linux/capability.h>
#include <linux/writeback.h>
@@ -134,45 +135,34 @@ xfs_iozero(
loff_t pos, /* offset in file */
size_t count) /* size of data to zero */
{
- unsigned bytes;
struct page *page;
struct address_space *mapping;
int status;
mapping = ip->i_mapping;
do {
- unsigned long index, offset;
+ unsigned offset, bytes;
+ void *fsdata;
offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
- index = pos >> PAGE_CACHE_SHIFT;
bytes = PAGE_CACHE_SIZE - offset;
if (bytes > count)
bytes = count;
- status = -ENOMEM;
- page = grab_cache_page(mapping, index);
- if (!page)
- break;
-
- status = mapping->a_ops->prepare_write(NULL, page, offset,
- offset + bytes);
+ status = pagecache_write_begin(NULL, mapping, pos, bytes,
+ AOP_FLAG_UNINTERRUPTIBLE,
+ &page, &fsdata);
if (status)
- goto unlock;
+ break;
zero_user_page(page, offset, bytes, KM_USER0);
- status = mapping->a_ops->commit_write(NULL, page, offset,
- offset + bytes);
- if (!status) {
- pos += bytes;
- count -= bytes;
- }
-
-unlock:
- unlock_page(page);
- page_cache_release(page);
- if (status)
- break;
+ status = pagecache_write_end(NULL, mapping, pos, bytes, bytes,
+ page, fsdata);
+ WARN_ON(status <= 0); /* can't return less than zero! */
+ pos += bytes;
+ count -= bytes;
+ status = 0;
} while (count);
return (-status);
@@ -180,27 +170,22 @@ unlock:
ssize_t /* bytes read, or (-) error */
xfs_read(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
struct kiocb *iocb,
const struct iovec *iovp,
unsigned int segs,
loff_t *offset,
- int ioflags,
- cred_t *credp)
+ int ioflags)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ xfs_mount_t *mp = ip->i_mount;
size_t size = 0;
ssize_t ret = 0;
xfs_fsize_t n;
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- bhv_vnode_t *vp;
unsigned long seg;
- ip = XFS_BHVTOI(bdp);
- vp = BHV_TO_VNODE(bdp);
- mp = ip->i_mount;
XFS_STATS_INC(xs_read_calls);
@@ -245,13 +230,11 @@ xfs_read(
mutex_lock(&inode->i_mutex);
xfs_ilock(ip, XFS_IOLOCK_SHARED);
- if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
- !(ioflags & IO_INVIS)) {
+ if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
bhv_vrwlock_t locktype = VRWLOCK_READ;
int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
- ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
- BHV_TO_VNODE(bdp), *offset, size,
+ ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, *offset, size,
dmflags, &locktype);
if (ret) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -263,8 +246,9 @@ xfs_read(
if (unlikely(ioflags & IO_ISDIRECT)) {
if (VN_CACHED(vp))
- ret = bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
- -1, FI_REMAPF_LOCKED);
+ ret = xfs_flushinval_pages(ip,
+ ctooff(offtoct(*offset)),
+ -1, FI_REMAPF_LOCKED);
mutex_unlock(&inode->i_mutex);
if (ret) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -288,16 +272,15 @@ xfs_read(
ssize_t
xfs_splice_read(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
struct file *infilp,
loff_t *ppos,
struct pipe_inode_info *pipe,
size_t count,
int flags,
- int ioflags,
- cred_t *credp)
+ int ioflags)
{
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
xfs_mount_t *mp = ip->i_mount;
ssize_t ret;
@@ -307,13 +290,11 @@ xfs_splice_read(
xfs_ilock(ip, XFS_IOLOCK_SHARED);
- if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
- (!(ioflags & IO_INVIS))) {
+ if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
bhv_vrwlock_t locktype = VRWLOCK_READ;
int error;
- error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
- *ppos, count,
+ error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, *ppos, count,
FILP_DELAY_FLAG(infilp), &locktype);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -332,16 +313,15 @@ xfs_splice_read(
ssize_t
xfs_splice_write(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
struct pipe_inode_info *pipe,
struct file *outfilp,
loff_t *ppos,
size_t count,
int flags,
- int ioflags,
- cred_t *credp)
+ int ioflags)
{
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
xfs_mount_t *mp = ip->i_mount;
xfs_iocore_t *io = &ip->i_iocore;
ssize_t ret;
@@ -354,13 +334,11 @@ xfs_splice_write(
xfs_ilock(ip, XFS_IOLOCK_EXCL);
- if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
- (!(ioflags & IO_INVIS))) {
+ if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) {
bhv_vrwlock_t locktype = VRWLOCK_WRITE;
int error;
- error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
- *ppos, count,
+ error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, *ppos, count,
FILP_DELAY_FLAG(outfilp), &locktype);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
@@ -594,24 +572,22 @@ out_lock:
ssize_t /* bytes written, or (-) error */
xfs_write(
- bhv_desc_t *bdp,
+ struct xfs_inode *xip,
struct kiocb *iocb,
const struct iovec *iovp,
unsigned int nsegs,
loff_t *offset,
- int ioflags,
- cred_t *credp)
+ int ioflags)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
+ bhv_vnode_t *vp = XFS_ITOV(xip);
unsigned long segs = nsegs;
- xfs_inode_t *xip;
xfs_mount_t *mp;
ssize_t ret = 0, error = 0;
xfs_fsize_t isize, new_size;
xfs_iocore_t *io;
- bhv_vnode_t *vp;
int iolock;
int eventsent = 0;
bhv_vrwlock_t locktype;
@@ -621,9 +597,6 @@ xfs_write(
XFS_STATS_INC(xs_write_calls);
- vp = BHV_TO_VNODE(bdp);
- xip = XFS_BHVTOI(bdp);
-
error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ);
if (error)
return error;
@@ -637,7 +610,7 @@ xfs_write(
io = &xip->i_iocore;
mp = io->io_mount;
- vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
+ xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
@@ -664,7 +637,7 @@ start:
goto out_unlock_mutex;
}
- if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
+ if ((DM_EVENT_ENABLED(xip, DM_EVENT_WRITE) &&
!(ioflags & IO_INVIS) && !eventsent)) {
int dmflags = FILP_DELAY_FLAG(file);
@@ -733,7 +706,7 @@ start:
*/
if (pos > xip->i_size) {
- error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size);
+ error = xfs_zero_eof(vp, io, pos, xip->i_size);
if (error) {
xfs_iunlock(xip, XFS_ILOCK_EXCL);
goto out_unlock_internal;
@@ -769,7 +742,8 @@ retry:
WARN_ON(need_i_mutex == 0);
xfs_inval_cached_trace(io, pos, -1,
ctooff(offtoct(pos)), -1);
- error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
+ error = xfs_flushinval_pages(xip,
+ ctooff(offtoct(pos)),
-1, FI_REMAPF_LOCKED);
if (error)
goto out_unlock_internal;
@@ -816,11 +790,9 @@ retry:
if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
ret = wait_on_sync_kiocb(iocb);
- if ((ret == -ENOSPC) &&
- DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) &&
- !(ioflags & IO_INVIS)) {
-
- xfs_rwunlock(bdp, locktype);
+ if (ret == -ENOSPC &&
+ DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) {
+ xfs_rwunlock(xip, locktype);
if (need_i_mutex)
mutex_unlock(&inode->i_mutex);
error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
@@ -828,7 +800,7 @@ retry:
0, 0, 0); /* Delay flag intentionally unused */
if (need_i_mutex)
mutex_lock(&inode->i_mutex);
- xfs_rwlock(bdp, locktype);
+ xfs_rwlock(xip, locktype);
if (error)
goto out_unlock_internal;
pos = xip->i_size;
@@ -855,20 +827,19 @@ retry:
/* Handle various SYNC-type writes */
if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
- error = xfs_write_sync_logforce(mp, xip);
- if (error)
- goto out_unlock_internal;
-
- xfs_rwunlock(bdp, locktype);
+ int error2;
+ xfs_rwunlock(xip, locktype);
if (need_i_mutex)
mutex_unlock(&inode->i_mutex);
-
- error = sync_page_range(inode, mapping, pos, ret);
+ error2 = sync_page_range(inode, mapping, pos, ret);
if (!error)
- error = -ret;
+ error = error2;
if (need_i_mutex)
mutex_lock(&inode->i_mutex);
- xfs_rwlock(bdp, locktype);
+ xfs_rwlock(xip, locktype);
+ error2 = xfs_write_sync_logforce(mp, xip);
+ if (!error)
+ error = error2;
}
out_unlock_internal:
@@ -886,7 +857,7 @@ retry:
xip->i_d.di_size = xip->i_size;
xfs_iunlock(xip, XFS_ILOCK_EXCL);
}
- xfs_rwunlock(bdp, locktype);
+ xfs_rwunlock(xip, locktype);
out_unlock_mutex:
if (need_i_mutex)
mutex_unlock(&inode->i_mutex);
@@ -925,14 +896,14 @@ xfs_bdstrat_cb(struct xfs_buf *bp)
int
-xfs_bmap(bhv_desc_t *bdp,
+xfs_bmap(
+ xfs_inode_t *ip,
xfs_off_t offset,
ssize_t count,
int flags,
xfs_iomap_t *iomapp,
int *niomaps)
{
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
xfs_iocore_t *io = &ip->i_iocore;
ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 7c60a1eed88..4b7747a828d 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -18,8 +18,6 @@
#ifndef __XFS_LRW_H__
#define __XFS_LRW_H__
-struct bhv_desc;
-struct bhv_vnode;
struct xfs_mount;
struct xfs_iocore;
struct xfs_inode;
@@ -71,30 +69,11 @@ extern void xfs_inval_cached_trace(struct xfs_iocore *,
#define xfs_inval_cached_trace(io, offset, len, first, last)
#endif
-/*
- * Maximum count of bmaps used by read and write paths.
- */
-#define XFS_MAX_RW_NBMAPS 4
-
-extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
- struct xfs_iomap *, int *);
extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
extern int xfs_bdstrat_cb(struct xfs_buf *);
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
+extern int xfs_zero_eof(struct inode *, struct xfs_iocore *, xfs_off_t,
xfs_fsize_t);
-extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
- const struct iovec *, unsigned int,
- loff_t *, int, struct cred *);
-extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
- const struct iovec *, unsigned int,
- loff_t *, int, struct cred *);
-extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *,
- struct pipe_inode_info *, size_t, int, int,
- struct cred *);
-extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *,
- struct file *, loff_t *, size_t, int, int,
- struct cred *);
#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 491d1f4f202..8cb63c60c04 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -46,6 +46,8 @@
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
+#include "xfs_vnodeops.h"
+#include "xfs_vfsops.h"
#include "xfs_version.h"
#include <linux/namei.h>
@@ -196,23 +198,20 @@ xfs_revalidate_inode(
inode->i_flags |= S_NOATIME;
else
inode->i_flags &= ~S_NOATIME;
- vp->v_flag &= ~VMODIFIED;
+ xfs_iflags_clear(ip, XFS_IMODIFIED);
}
void
xfs_initialize_vnode(
- bhv_desc_t *bdp,
+ struct xfs_mount *mp,
bhv_vnode_t *vp,
- bhv_desc_t *inode_bhv,
- int unlock)
+ struct xfs_inode *ip)
{
- xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
struct inode *inode = vn_to_inode(vp);
- if (!inode_bhv->bd_vobj) {
- vp->v_vfsp = bhvtovfs(bdp);
- bhv_desc_init(inode_bhv, ip, vp, &xfs_vnodeops);
- bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
+ if (!ip->i_vnode) {
+ ip->i_vnode = vp;
+ inode->i_private = ip;
}
/*
@@ -222,8 +221,8 @@ xfs_initialize_vnode(
* second time once the inode is properly set up, and then we can
* finish our work.
*/
- if (ip->i_d.di_mode != 0 && unlock && (inode->i_state & I_NEW)) {
- xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
+ if (ip->i_d.di_mode != 0 && (inode->i_state & I_NEW)) {
+ xfs_revalidate_inode(mp, vp, ip);
xfs_set_inodeops(inode);
xfs_iflags_clear(ip, XFS_INEW);
@@ -356,9 +355,8 @@ xfs_fs_destroy_inode(
STATIC void
xfs_fs_inode_init_once(
- void *vnode,
kmem_zone_t *zonep,
- unsigned long flags)
+ void *vnode)
{
inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
}
@@ -410,19 +408,22 @@ xfs_fs_write_inode(
struct inode *inode,
int sync)
{
- bhv_vnode_t *vp = vn_from_inode(inode);
int error = 0, flags = FLUSH_INODE;
- if (vp) {
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
- if (sync) {
- filemap_fdatawait(inode->i_mapping);
- flags |= FLUSH_SYNC;
- }
- error = bhv_vop_iflush(vp, flags);
- if (error == EAGAIN)
- error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
+ vn_trace_entry(XFS_I(inode), __FUNCTION__,
+ (inst_t *)__return_address);
+ if (sync) {
+ filemap_fdatawait(inode->i_mapping);
+ flags |= FLUSH_SYNC;
}
+ error = xfs_inode_flush(XFS_I(inode), flags);
+ /*
+ * if we failed to write out the inode then mark
+ * it dirty again so we'll try again later.
+ */
+ if (error)
+ mark_inode_dirty_sync(inode);
+
return -error;
}
@@ -430,35 +431,27 @@ STATIC void
xfs_fs_clear_inode(
struct inode *inode)
{
- bhv_vnode_t *vp = vn_from_inode(inode);
-
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- XFS_STATS_INC(vn_rele);
- XFS_STATS_INC(vn_remove);
- XFS_STATS_INC(vn_reclaim);
- XFS_STATS_DEC(vn_active);
+ xfs_inode_t *ip = XFS_I(inode);
/*
- * This can happen because xfs_iget_core calls xfs_idestroy if we
+ * ip can be null when xfs_iget_core calls xfs_idestroy if we
* find an inode with di_mode == 0 but without IGET_CREATE set.
*/
- if (VNHEAD(vp))
- bhv_vop_inactive(vp, NULL);
-
- VN_LOCK(vp);
- vp->v_flag &= ~VMODIFIED;
- VN_UNLOCK(vp, 0);
-
- if (VNHEAD(vp))
- if (bhv_vop_reclaim(vp))
- panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
-
- ASSERT(VNHEAD(vp) == NULL);
+ if (ip) {
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
+
+ XFS_STATS_INC(vn_rele);
+ XFS_STATS_INC(vn_remove);
+ XFS_STATS_INC(vn_reclaim);
+ XFS_STATS_DEC(vn_active);
+
+ xfs_inactive(ip);
+ xfs_iflags_clear(ip, XFS_IMODIFIED);
+ if (xfs_reclaim(ip))
+ panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, inode);
+ }
-#ifdef XFS_VNODE_TRACE
- ktrace_free(vp->v_trace);
-#endif
+ ASSERT(XFS_I(inode) == NULL);
}
/*
@@ -470,9 +463,9 @@ xfs_fs_clear_inode(
*/
STATIC void
xfs_syncd_queue_work(
- struct bhv_vfs *vfs,
+ struct xfs_mount *mp,
void *data,
- void (*syncer)(bhv_vfs_t *, void *))
+ void (*syncer)(struct xfs_mount *, void *))
{
struct bhv_vfs_sync_work *work;
@@ -480,11 +473,11 @@ xfs_syncd_queue_work(
INIT_LIST_HEAD(&work->w_list);
work->w_syncer = syncer;
work->w_data = data;
- work->w_vfs = vfs;
- spin_lock(&vfs->vfs_sync_lock);
- list_add_tail(&work->w_list, &vfs->vfs_sync_list);
- spin_unlock(&vfs->vfs_sync_lock);
- wake_up_process(vfs->vfs_sync_task);
+ work->w_mount = mp;
+ spin_lock(&mp->m_sync_lock);
+ list_add_tail(&work->w_list, &mp->m_sync_list);
+ spin_unlock(&mp->m_sync_lock);
+ wake_up_process(mp->m_sync_task);
}
/*
@@ -495,22 +488,22 @@ xfs_syncd_queue_work(
*/
STATIC void
xfs_flush_inode_work(
- bhv_vfs_t *vfs,
- void *inode)
+ struct xfs_mount *mp,
+ void *arg)
{
- filemap_flush(((struct inode *)inode)->i_mapping);
- iput((struct inode *)inode);
+ struct inode *inode = arg;
+ filemap_flush(inode->i_mapping);
+ iput(inode);
}
void
xfs_flush_inode(
xfs_inode_t *ip)
{
- struct inode *inode = vn_to_inode(XFS_ITOV(ip));
- struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
+ struct inode *inode = ip->i_vnode;
igrab(inode);
- xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
+ xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
delay(msecs_to_jiffies(500));
}
@@ -520,11 +513,12 @@ xfs_flush_inode(
*/
STATIC void
xfs_flush_device_work(
- bhv_vfs_t *vfs,
- void *inode)
+ struct xfs_mount *mp,
+ void *arg)
{
- sync_blockdev(vfs->vfs_super->s_bdev);
- iput((struct inode *)inode);
+ struct inode *inode = arg;
+ sync_blockdev(mp->m_super->s_bdev);
+ iput(inode);
}
void
@@ -532,35 +526,33 @@ xfs_flush_device(
xfs_inode_t *ip)
{
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
- struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
igrab(inode);
- xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
+ xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work);
delay(msecs_to_jiffies(500));
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
}
STATIC void
-vfs_sync_worker(
- bhv_vfs_t *vfsp,
+xfs_sync_worker(
+ struct xfs_mount *mp,
void *unused)
{
int error;
- if (!(vfsp->vfs_flag & VFS_RDONLY))
- error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
- SYNC_ATTR | SYNC_REFCACHE | SYNC_SUPER,
- NULL);
- vfsp->vfs_sync_seq++;
- wake_up(&vfsp->vfs_wait_single_sync_task);
+ if (!(mp->m_flags & XFS_MOUNT_RDONLY))
+ error = xfs_sync(mp, SYNC_FSDATA | SYNC_BDFLUSH | SYNC_ATTR |
+ SYNC_REFCACHE | SYNC_SUPER);
+ mp->m_sync_seq++;
+ wake_up(&mp->m_wait_single_sync_task);
}
STATIC int
xfssyncd(
void *arg)
{
+ struct xfs_mount *mp = arg;
long timeleft;
- bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
bhv_vfs_sync_work_t *work, *n;
LIST_HEAD (tmp);
@@ -570,31 +562,31 @@ xfssyncd(
timeleft = schedule_timeout_interruptible(timeleft);
/* swsusp */
try_to_freeze();
- if (kthread_should_stop() && list_empty(&vfsp->vfs_sync_list))
+ if (kthread_should_stop() && list_empty(&mp->m_sync_list))
break;
- spin_lock(&vfsp->vfs_sync_lock);
+ spin_lock(&mp->m_sync_lock);
/*
* We can get woken by laptop mode, to do a sync -
* that's the (only!) case where the list would be
* empty with time remaining.
*/
- if (!timeleft || list_empty(&vfsp->vfs_sync_list)) {
+ if (!timeleft || list_empty(&mp->m_sync_list)) {
if (!timeleft)
timeleft = xfs_syncd_centisecs *
msecs_to_jiffies(10);
- INIT_LIST_HEAD(&vfsp->vfs_sync_work.w_list);
- list_add_tail(&vfsp->vfs_sync_work.w_list,
- &vfsp->vfs_sync_list);
+ INIT_LIST_HEAD(&mp->m_sync_work.w_list);
+ list_add_tail(&mp->m_sync_work.w_list,
+ &mp->m_sync_list);
}
- list_for_each_entry_safe(work, n, &vfsp->vfs_sync_list, w_list)
+ list_for_each_entry_safe(work, n, &mp->m_sync_list, w_list)
list_move(&work->w_list, &tmp);
- spin_unlock(&vfsp->vfs_sync_lock);
+ spin_unlock(&mp->m_sync_lock);
list_for_each_entry_safe(work, n, &tmp, w_list) {
- (*work->w_syncer)(vfsp, work->w_data);
+ (*work->w_syncer)(mp, work->w_data);
list_del(&work->w_list);
- if (work == &vfsp->vfs_sync_work)
+ if (work == &mp->m_sync_work)
continue;
kmem_free(work, sizeof(struct bhv_vfs_sync_work));
}
@@ -603,41 +595,19 @@ xfssyncd(
return 0;
}
-STATIC int
-xfs_fs_start_syncd(
- bhv_vfs_t *vfsp)
-{
- vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
- vfsp->vfs_sync_work.w_vfs = vfsp;
- vfsp->vfs_sync_task = kthread_run(xfssyncd, vfsp, "xfssyncd");
- if (IS_ERR(vfsp->vfs_sync_task))
- return -PTR_ERR(vfsp->vfs_sync_task);
- return 0;
-}
-
-STATIC void
-xfs_fs_stop_syncd(
- bhv_vfs_t *vfsp)
-{
- kthread_stop(vfsp->vfs_sync_task);
-}
-
STATIC void
xfs_fs_put_super(
struct super_block *sb)
{
- bhv_vfs_t *vfsp = vfs_from_sb(sb);
+ struct xfs_mount *mp = XFS_M(sb);
int error;
- xfs_fs_stop_syncd(vfsp);
- bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
- error = bhv_vfs_unmount(vfsp, 0, NULL);
- if (error) {
+ kthread_stop(mp->m_sync_task);
+
+ xfs_sync(mp, SYNC_ATTR | SYNC_DELWRI);
+ error = xfs_unmount(mp, 0, NULL);
+ if (error)
printk("XFS: unmount got error=%d\n", error);
- printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
- } else {
- vfs_deallocate(vfsp);
- }
}
STATIC void
@@ -645,7 +615,7 @@ xfs_fs_write_super(
struct super_block *sb)
{
if (!(sb->s_flags & MS_RDONLY))
- bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
+ xfs_sync(XFS_M(sb), SYNC_FSDATA);
sb->s_dirt = 0;
}
@@ -654,11 +624,23 @@ xfs_fs_sync_super(
struct super_block *sb,
int wait)
{
- bhv_vfs_t *vfsp = vfs_from_sb(sb);
+ struct xfs_mount *mp = XFS_M(sb);
int error;
int flags;
- if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) {
+ /*
+ * Treat a sync operation like a freeze. This is to work
+ * around a race in sync_inodes() which works in two phases
+ * - an asynchronous flush, which can write out an inode
+ * without waiting for file size updates to complete, and a
+ * synchronous flush, which wont do anything because the
+ * async flush removed the inode's dirty flag. Also
+ * sync_inodes() will not see any files that just have
+ * outstanding transactions to be flushed because we don't
+ * dirty the Linux inode until after the transaction I/O
+ * completes.
+ */
+ if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) {
/*
* First stage of freeze - no more writers will make progress
* now we are here, so we flush delwri and delalloc buffers
@@ -669,28 +651,28 @@ xfs_fs_sync_super(
*/
flags = SYNC_DATA_QUIESCE;
} else
- flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
+ flags = SYNC_FSDATA;
- error = bhv_vfs_sync(vfsp, flags, NULL);
+ error = xfs_sync(mp, flags);
sb->s_dirt = 0;
if (unlikely(laptop_mode)) {
- int prev_sync_seq = vfsp->vfs_sync_seq;
+ int prev_sync_seq = mp->m_sync_seq;
/*
* The disk must be active because we're syncing.
* We schedule xfssyncd now (now that the disk is
* active) instead of later (when it might not be).
*/
- wake_up_process(vfsp->vfs_sync_task);
+ wake_up_process(mp->m_sync_task);
/*
* We have to wait for the sync iteration to complete.
* If we don't, the disk activity caused by the sync
* will come after the sync is completed, and that
* triggers another sync from laptop mode.
*/
- wait_event(vfsp->vfs_wait_single_sync_task,
- vfsp->vfs_sync_seq != prev_sync_seq);
+ wait_event(mp->m_wait_single_sync_task,
+ mp->m_sync_seq != prev_sync_seq);
}
return -error;
@@ -701,7 +683,7 @@ xfs_fs_statfs(
struct dentry *dentry,
struct kstatfs *statp)
{
- return -bhv_vfs_statvfs(vfs_from_sb(dentry->d_sb), statp,
+ return -xfs_statvfs(XFS_M(dentry->d_sb), statp,
vn_from_inode(dentry->d_inode));
}
@@ -711,13 +693,13 @@ xfs_fs_remount(
int *flags,
char *options)
{
- bhv_vfs_t *vfsp = vfs_from_sb(sb);
+ struct xfs_mount *mp = XFS_M(sb);
struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
int error;
- error = bhv_vfs_parseargs(vfsp, options, args, 1);
+ error = xfs_parseargs(mp, options, args, 1);
if (!error)
- error = bhv_vfs_mntupdate(vfsp, flags, args);
+ error = xfs_mntupdate(mp, flags, args);
kmem_free(args, sizeof(*args));
return -error;
}
@@ -726,7 +708,7 @@ STATIC void
xfs_fs_lockfs(
struct super_block *sb)
{
- bhv_vfs_freeze(vfs_from_sb(sb));
+ xfs_freeze(XFS_M(sb));
}
STATIC int
@@ -734,7 +716,7 @@ xfs_fs_show_options(
struct seq_file *m,
struct vfsmount *mnt)
{
- return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
+ return -xfs_showargs(XFS_M(mnt->mnt_sb), m);
}
STATIC int
@@ -742,7 +724,7 @@ xfs_fs_quotasync(
struct super_block *sb,
int type)
{
- return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
+ return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL);
}
STATIC int
@@ -750,7 +732,7 @@ xfs_fs_getxstate(
struct super_block *sb,
struct fs_quota_stat *fqs)
{
- return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
+ return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
}
STATIC int
@@ -759,7 +741,7 @@ xfs_fs_setxstate(
unsigned int flags,
int op)
{
- return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
+ return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags);
}
STATIC int
@@ -769,7 +751,7 @@ xfs_fs_getxquota(
qid_t id,
struct fs_disk_quota *fdq)
{
- return -bhv_vfs_quotactl(vfs_from_sb(sb),
+ return -XFS_QM_QUOTACTL(XFS_M(sb),
(type == USRQUOTA) ? Q_XGETQUOTA :
((type == GRPQUOTA) ? Q_XGETGQUOTA :
Q_XGETPQUOTA), id, (caddr_t)fdq);
@@ -782,7 +764,7 @@ xfs_fs_setxquota(
qid_t id,
struct fs_disk_quota *fdq)
{
- return -bhv_vfs_quotactl(vfs_from_sb(sb),
+ return -XFS_QM_QUOTACTL(XFS_M(sb),
(type == USRQUOTA) ? Q_XSETQLIM :
((type == GRPQUOTA) ? Q_XSETGQLIM :
Q_XSETPQLIM), id, (caddr_t)fdq);
@@ -794,32 +776,38 @@ xfs_fs_fill_super(
void *data,
int silent)
{
- struct bhv_vnode *rootvp;
- struct bhv_vfs *vfsp = vfs_allocate(sb);
+ struct inode *rootvp;
+ struct xfs_mount *mp = NULL;
struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
struct kstatfs statvfs;
int error;
- bhv_insert_all_vfsops(vfsp);
+ mp = xfs_mount_init();
- error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
- if (error) {
- bhv_remove_all_vfsops(vfsp, 1);
+ INIT_LIST_HEAD(&mp->m_sync_list);
+ spin_lock_init(&mp->m_sync_lock);
+ init_waitqueue_head(&mp->m_wait_single_sync_task);
+
+ mp->m_super = sb;
+ sb->s_fs_info = mp;
+
+ if (sb->s_flags & MS_RDONLY)
+ mp->m_flags |= XFS_MOUNT_RDONLY;
+
+ error = xfs_parseargs(mp, (char *)data, args, 0);
+ if (error)
goto fail_vfsop;
- }
sb_min_blocksize(sb, BBSIZE);
sb->s_export_op = &xfs_export_operations;
sb->s_qcop = &xfs_quotactl_operations;
sb->s_op = &xfs_super_operations;
- error = bhv_vfs_mount(vfsp, args, NULL);
- if (error) {
- bhv_remove_all_vfsops(vfsp, 1);
+ error = xfs_mount(mp, args, NULL);
+ if (error)
goto fail_vfsop;
- }
- error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
+ error = xfs_statvfs(mp, &statvfs, NULL);
if (error)
goto fail_unmount;
@@ -831,7 +819,7 @@ xfs_fs_fill_super(
sb->s_time_gran = 1;
set_posix_acl_flag(sb);
- error = bhv_vfs_root(vfsp, &rootvp);
+ error = xfs_root(mp, &rootvp);
if (error)
goto fail_unmount;
@@ -844,9 +832,17 @@ xfs_fs_fill_super(
error = EINVAL;
goto fail_vnrele;
}
- if ((error = xfs_fs_start_syncd(vfsp)))
+
+ mp->m_sync_work.w_syncer = xfs_sync_worker;
+ mp->m_sync_work.w_mount = mp;
+ mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd");
+ if (IS_ERR(mp->m_sync_task)) {
+ error = -PTR_ERR(mp->m_sync_task);
goto fail_vnrele;
- vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);
+ }
+
+ vn_trace_exit(XFS_I(sb->s_root->d_inode), __FUNCTION__,
+ (inst_t *)__return_address);
kmem_free(args, sizeof(*args));
return 0;
@@ -860,10 +856,9 @@ fail_vnrele:
}
fail_unmount:
- bhv_vfs_unmount(vfsp, 0, NULL);
+ xfs_unmount(mp, 0, NULL);
fail_vfsop:
- vfs_deallocate(vfsp);
kmem_free(args, sizeof(*args));
return -error;
}
@@ -915,15 +910,11 @@ STATIC int __init
init_xfs_fs( void )
{
int error;
- struct sysinfo si;
static char message[] __initdata = KERN_INFO \
XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
printk(message);
- si_meminfo(&si);
- xfs_physmem = si.totalram;
-
ktrace_init(64);
error = xfs_init_zones();
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 201cc3273c8..c78c23310fe 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -107,7 +107,8 @@ struct block_device;
extern __uint64_t xfs_max_file_offset(unsigned int);
-extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
+extern void xfs_initialize_vnode(struct xfs_mount *mp, bhv_vnode_t *vp,
+ struct xfs_inode *ip);
extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *);
@@ -119,4 +120,6 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
extern struct export_operations xfs_export_operations;
+#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
+
#endif /* __XFS_SUPER_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
deleted file mode 100644
index 6145e8bd0be..00000000000
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * 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. 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_clnt.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_imap.h"
-#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_quota.h"
-
-int
-vfs_mount(
- struct bhv_desc *bdp,
- struct xfs_mount_args *args,
- struct cred *cr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_mount)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_mount)(next, args, cr));
-}
-
-int
-vfs_parseargs(
- struct bhv_desc *bdp,
- char *s,
- struct xfs_mount_args *args,
- int f)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_parseargs)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_parseargs)(next, s, args, f));
-}
-
-int
-vfs_showargs(
- struct bhv_desc *bdp,
- struct seq_file *m)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_showargs)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_showargs)(next, m));
-}
-
-int
-vfs_unmount(
- struct bhv_desc *bdp,
- int fl,
- struct cred *cr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_unmount)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_unmount)(next, fl, cr));
-}
-
-int
-vfs_mntupdate(
- struct bhv_desc *bdp,
- int *fl,
- struct xfs_mount_args *args)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_mntupdate)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_mntupdate)(next, fl, args));
-}
-
-int
-vfs_root(
- struct bhv_desc *bdp,
- struct bhv_vnode **vpp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_root)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_root)(next, vpp));
-}
-
-int
-vfs_statvfs(
- struct bhv_desc *bdp,
- bhv_statvfs_t *statp,
- struct bhv_vnode *vp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_statvfs)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
-}
-
-int
-vfs_sync(
- struct bhv_desc *bdp,
- int fl,
- struct cred *cr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_sync)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_sync)(next, fl, cr));
-}
-
-int
-vfs_vget(
- struct bhv_desc *bdp,
- struct bhv_vnode **vpp,
- struct fid *fidp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_vget)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp));
-}
-
-int
-vfs_dmapiops(
- struct bhv_desc *bdp,
- caddr_t addr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_dmapiops)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_dmapiops)(next, addr));
-}
-
-int
-vfs_quotactl(
- struct bhv_desc *bdp,
- int cmd,
- int id,
- caddr_t addr)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_quotactl)
- next = BHV_NEXT(next);
- return ((*bhvtovfsops(next)->vfs_quotactl)(next, cmd, id, addr));
-}
-
-void
-vfs_init_vnode(
- struct bhv_desc *bdp,
- struct bhv_vnode *vp,
- struct bhv_desc *bp,
- int unlock)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_init_vnode)
- next = BHV_NEXT(next);
- ((*bhvtovfsops(next)->vfs_init_vnode)(next, vp, bp, unlock));
-}
-
-void
-vfs_force_shutdown(
- struct bhv_desc *bdp,
- int fl,
- char *file,
- int line)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_force_shutdown)
- next = BHV_NEXT(next);
- ((*bhvtovfsops(next)->vfs_force_shutdown)(next, fl, file, line));
-}
-
-void
-vfs_freeze(
- struct bhv_desc *bdp)
-{
- struct bhv_desc *next = bdp;
-
- ASSERT(next);
- while (! (bhvtovfsops(next))->vfs_freeze)
- next = BHV_NEXT(next);
- ((*bhvtovfsops(next)->vfs_freeze)(next));
-}
-
-bhv_vfs_t *
-vfs_allocate(
- struct super_block *sb)
-{
- struct bhv_vfs *vfsp;
-
- vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
- bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
- INIT_LIST_HEAD(&vfsp->vfs_sync_list);
- spin_lock_init(&vfsp->vfs_sync_lock);
- init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
-
- vfsp->vfs_super = sb;
- sb->s_fs_info = vfsp;
-
- if (sb->s_flags & MS_RDONLY)
- vfsp->vfs_flag |= VFS_RDONLY;
-
- return vfsp;
-}
-
-bhv_vfs_t *
-vfs_from_sb(
- struct super_block *sb)
-{
- return (bhv_vfs_t *)sb->s_fs_info;
-}
-
-void
-vfs_deallocate(
- struct bhv_vfs *vfsp)
-{
- bhv_head_destroy(VFS_BHVHEAD(vfsp));
- kmem_free(vfsp, sizeof(bhv_vfs_t));
-}
-
-void
-vfs_insertops(
- struct bhv_vfs *vfsp,
- struct bhv_module_vfsops *vfsops)
-{
- struct bhv_desc *bdp;
-
- bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
- bhv_desc_init(bdp, NULL, vfsp, vfsops);
- bhv_insert(&vfsp->vfs_bh, bdp);
-}
-
-void
-vfs_insertbhv(
- struct bhv_vfs *vfsp,
- struct bhv_desc *bdp,
- struct bhv_vfsops *vfsops,
- void *mount)
-{
- bhv_desc_init(bdp, mount, vfsp, vfsops);
- bhv_insert_initial(&vfsp->vfs_bh, bdp);
-}
-
-void
-bhv_remove_vfsops(
- struct bhv_vfs *vfsp,
- int pos)
-{
- struct bhv_desc *bhv;
-
- bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
- if (!bhv)
- return;
- bhv_remove(&vfsp->vfs_bh, bhv);
- kmem_free(bhv, sizeof(*bhv));
-}
-
-void
-bhv_remove_all_vfsops(
- struct bhv_vfs *vfsp,
- int freebase)
-{
- struct xfs_mount *mp;
-
- bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
- bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
- if (!freebase)
- return;
- mp = XFS_VFSTOM(vfsp);
- VFS_REMOVEBHV(vfsp, &mp->m_bhv);
- xfs_mount_free(mp, 0);
-}
-
-void
-bhv_insert_all_vfsops(
- struct bhv_vfs *vfsp)
-{
- struct xfs_mount *mp;
-
- mp = xfs_mount_init();
- vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
- vfs_insertdmapi(vfsp);
- vfs_insertquota(vfsp);
-}
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index dca3481aaaf..4da03a4e352 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -21,68 +21,25 @@
#include <linux/vfs.h>
#include "xfs_fs.h"
-struct bhv_vfs;
-struct bhv_vnode;
+struct inode;
struct fid;
struct cred;
struct seq_file;
struct super_block;
+struct xfs_inode;
+struct xfs_mount;
struct xfs_mount_args;
typedef struct kstatfs bhv_statvfs_t;
typedef struct bhv_vfs_sync_work {
struct list_head w_list;
- struct bhv_vfs *w_vfs;
+ struct xfs_mount *w_mount;
void *w_data; /* syncer routine argument */
- void (*w_syncer)(struct bhv_vfs *, void *);
+ void (*w_syncer)(struct xfs_mount *, void *);
} bhv_vfs_sync_work_t;
-typedef struct bhv_vfs {
- u_int vfs_flag; /* flags */
- xfs_fsid_t vfs_fsid; /* file system ID */
- xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
- bhv_head_t vfs_bh; /* head of vfs behavior chain */
- struct super_block *vfs_super; /* generic superblock pointer */
- struct task_struct *vfs_sync_task; /* generalised sync thread */
- bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
- struct list_head vfs_sync_list; /* sync thread work item list */
- spinlock_t vfs_sync_lock; /* work item list lock */
- int vfs_sync_seq; /* sync thread generation no. */
- wait_queue_head_t vfs_wait_single_sync_task;
-} bhv_vfs_t;
-
-#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
-#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
-#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
-#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
-
-#define VFS_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
-#define VFS_POSITION_TOP BHV_POSITION_TOP /* chain top */
-#define VFS_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
-
-typedef enum {
- VFS_BHV_UNKNOWN, /* not specified */
- VFS_BHV_XFS, /* xfs */
- VFS_BHV_DM, /* data migration */
- VFS_BHV_QM, /* quota manager */
- VFS_BHV_IO, /* IO path */
- VFS_BHV_END /* housekeeping end-of-range */
-} bhv_vfs_type_t;
-
-#define VFS_POSITION_XFS (BHV_POSITION_BASE)
-#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
-#define VFS_POSITION_QM (VFS_POSITION_BASE+20)
-#define VFS_POSITION_IO (VFS_POSITION_BASE+30)
-
-#define VFS_RDONLY 0x0001 /* read-only vfs */
-#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
-#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
-/* ---- VFS_UMOUNT ---- 0x0008 -- unneeded, fixed via kthread APIs */
-#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
-#define VFS_END 0x0010 /* max flag */
-
#define SYNC_ATTR 0x0001 /* sync attributes */
#define SYNC_CLOSE 0x0002 /* close file system down */
#define SYNC_DELWRI 0x0004 /* look at delayed writes */
@@ -115,118 +72,7 @@ typedef enum {
#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
-typedef int (*vfs_mount_t)(bhv_desc_t *,
- struct xfs_mount_args *, struct cred *);
-typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *,
- struct xfs_mount_args *, int);
-typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
-typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
-typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
- struct xfs_mount_args *);
-typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
-typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
- struct bhv_vnode *);
-typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
-typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
-typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
-typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
-typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
- struct bhv_vnode *, bhv_desc_t *, int);
-typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
-typedef void (*vfs_freeze_t)(bhv_desc_t *);
-
-typedef struct bhv_vfsops {
- bhv_position_t vf_position; /* behavior chain position */
- vfs_mount_t vfs_mount; /* mount file system */
- vfs_parseargs_t vfs_parseargs; /* parse mount options */
- vfs_showargs_t vfs_showargs; /* unparse mount options */
- vfs_unmount_t vfs_unmount; /* unmount file system */
- vfs_mntupdate_t vfs_mntupdate; /* update file system options */
- vfs_root_t vfs_root; /* get root vnode */
- vfs_statvfs_t vfs_statvfs; /* file system statistics */
- vfs_sync_t vfs_sync; /* flush files */
- vfs_vget_t vfs_vget; /* get vnode from fid */
- vfs_dmapiops_t vfs_dmapiops; /* data migration */
- vfs_quotactl_t vfs_quotactl; /* disk quota */
- vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
- vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
- vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
-} bhv_vfsops_t;
-
-/*
- * Virtual filesystem operations, operating from head bhv.
- */
-#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
-#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
-#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
-#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
-#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
-#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
-#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
-#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
-#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
-#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
-#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
-#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
-#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
-#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
-#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
-
-/*
- * Virtual filesystem operations, operating from next bhv.
- */
-#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
-#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
-#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
-#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
-#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
-#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
-#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
-#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
-#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
-#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
-#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
-#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
-#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
-#define bhv_next_vfs_freeze(b) vfs_freeze(b)
-
-extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
-extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
-extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
-extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
-extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
-extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
-extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
-extern int vfs_sync(bhv_desc_t *, int, struct cred *);
-extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
-extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
-extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
-extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
-extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
-extern void vfs_freeze(bhv_desc_t *);
-
-#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
-#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
-
-typedef struct bhv_module_vfsops {
- struct bhv_vfsops bhv_common;
- void * bhv_custom;
-} bhv_module_vfsops_t;
-
-#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
-#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
-#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
-#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
-
-extern bhv_vfs_t *vfs_allocate(struct super_block *);
-extern bhv_vfs_t *vfs_from_sb(struct super_block *);
-extern void vfs_deallocate(bhv_vfs_t *);
-extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
-
-extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
-
-extern void bhv_insert_all_vfsops(struct bhv_vfs *);
-extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
-extern void bhv_remove_vfsops(struct bhv_vfs *, int);
+#define xfs_test_for_freeze(mp) ((mp)->m_super->s_frozen)
+#define xfs_wait_for_freeze(mp,l) vfs_check_frozen((mp)->m_super, (l))
#endif /* __XFS_VFS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index ada24baf88d..814169fd7e1 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -16,9 +16,21 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
+#include "xfs_vnodeops.h"
+#include "xfs_bmap_btree.h"
+#include "xfs_inode.h"
+
+/*
+ * And this gunk is needed for xfs_mount.h"
+ */
+#include "xfs_log.h"
+#include "xfs_trans.h"
+#include "xfs_sb.h"
+#include "xfs_dmapi.h"
+#include "xfs_inum.h"
+#include "xfs_ag.h"
+#include "xfs_mount.h"
-uint64_t vn_generation; /* vnode generation number */
-DEFINE_SPINLOCK(vnumber_lock);
/*
* Dedicated vnode inactive/reclaim sync semaphores.
@@ -39,19 +51,19 @@ vn_init(void)
void
vn_iowait(
- bhv_vnode_t *vp)
+ xfs_inode_t *ip)
{
- wait_queue_head_t *wq = vptosync(vp);
+ wait_queue_head_t *wq = vptosync(ip);
- wait_event(*wq, (atomic_read(&vp->v_iocount) == 0));
+ wait_event(*wq, (atomic_read(&ip->i_iocount) == 0));
}
void
vn_iowake(
- bhv_vnode_t *vp)
+ xfs_inode_t *ip)
{
- if (atomic_dec_and_test(&vp->v_iocount))
- wake_up(vptosync(vp));
+ if (atomic_dec_and_test(&ip->i_iocount))
+ wake_up(vptosync(ip));
}
/*
@@ -61,13 +73,13 @@ vn_iowake(
*/
void
vn_ioerror(
- bhv_vnode_t *vp,
+ xfs_inode_t *ip,
int error,
char *f,
int l)
{
if (unlikely(error == -ENODEV))
- bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
+ xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l);
}
bhv_vnode_t *
@@ -79,27 +91,8 @@ vn_initialize(
XFS_STATS_INC(vn_active);
XFS_STATS_INC(vn_alloc);
- vp->v_flag = VMODIFIED;
- spinlock_init(&vp->v_lock, "v_lock");
-
- spin_lock(&vnumber_lock);
- if (!++vn_generation) /* v_number shouldn't be zero */
- vn_generation++;
- vp->v_number = vn_generation;
- spin_unlock(&vnumber_lock);
-
ASSERT(VN_CACHED(vp) == 0);
- /* Initialize the first behavior and the behavior chain head. */
- vn_bhv_head_init(VN_BHV_HEAD(vp), "vnode");
-
- atomic_set(&vp->v_iocount, 0);
-
-#ifdef XFS_VNODE_TRACE
- vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
-#endif /* XFS_VNODE_TRACE */
-
- vn_trace_exit(vp, __FUNCTION__, (inst_t *)__return_address);
return vp;
}
@@ -150,12 +143,12 @@ __vn_revalidate(
{
int error;
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(xfs_vtoi(vp), __FUNCTION__, (inst_t *)__return_address);
vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
- error = bhv_vop_getattr(vp, vattr, 0, NULL);
+ error = xfs_getattr(xfs_vtoi(vp), vattr, 0);
if (likely(!error)) {
vn_revalidate_core(vp, vattr);
- VUNMODIFY(vp);
+ xfs_iflags_clear(xfs_vtoi(vp), XFS_IMODIFIED);
}
return -error;
}
@@ -180,24 +173,35 @@ vn_hold(
XFS_STATS_INC(vn_hold);
- VN_LOCK(vp);
inode = igrab(vn_to_inode(vp));
ASSERT(inode);
- VN_UNLOCK(vp, 0);
return vp;
}
#ifdef XFS_VNODE_TRACE
-#define KTRACE_ENTER(vp, vk, s, line, ra) \
- ktrace_enter( (vp)->v_trace, \
+/*
+ * Reference count of Linux inode if present, -1 if the xfs_inode
+ * has no associated Linux inode.
+ */
+static inline int xfs_icount(struct xfs_inode *ip)
+{
+ bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
+
+ if (vp)
+ return vn_count(vp);
+ return -1;
+}
+
+#define KTRACE_ENTER(ip, vk, s, line, ra) \
+ ktrace_enter( (ip)->i_trace, \
/* 0 */ (void *)(__psint_t)(vk), \
/* 1 */ (void *)(s), \
/* 2 */ (void *)(__psint_t) line, \
-/* 3 */ (void *)(__psint_t)(vn_count(vp)), \
+/* 3 */ (void *)(__psint_t)xfs_icount(ip), \
/* 4 */ (void *)(ra), \
-/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \
+/* 5 */ NULL, \
/* 6 */ (void *)(__psint_t)current_cpu(), \
/* 7 */ (void *)(__psint_t)current_pid(), \
/* 8 */ (void *)__return_address, \
@@ -207,32 +211,32 @@ vn_hold(
* Vnode tracing code.
*/
void
-vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
+vn_trace_entry(xfs_inode_t *ip, const char *func, inst_t *ra)
{
- KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
+ KTRACE_ENTER(ip, VNODE_KTRACE_ENTRY, func, 0, ra);
}
void
-vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
+vn_trace_exit(xfs_inode_t *ip, const char *func, inst_t *ra)
{
- KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
+ KTRACE_ENTER(ip, VNODE_KTRACE_EXIT, func, 0, ra);
}
void
-vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
+vn_trace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra)
{
- KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
+ KTRACE_ENTER(ip, VNODE_KTRACE_HOLD, file, line, ra);
}
void
-vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
+vn_trace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra)
{
- KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
+ KTRACE_ENTER(ip, VNODE_KTRACE_REF, file, line, ra);
}
void
-vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
+vn_trace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra)
{
- KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
+ KTRACE_ENTER(ip, VNODE_KTRACE_RELE, file, line, ra);
}
#endif /* XFS_VNODE_TRACE */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 5742d65f078..55fb4694858 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -18,84 +18,31 @@
#ifndef __XFS_VNODE_H__
#define __XFS_VNODE_H__
-struct uio;
struct file;
-struct bhv_vfs;
struct bhv_vattr;
struct xfs_iomap;
struct attrlist_cursor_kern;
typedef struct dentry bhv_vname_t;
typedef __u64 bhv_vnumber_t;
+typedef struct inode bhv_vnode_t;
-typedef enum bhv_vflags {
- VMODIFIED = 0x08, /* XFS inode state possibly differs */
- /* to the Linux inode state. */
- VTRUNCATED = 0x40, /* truncated down so flush-on-close */
-} bhv_vflags_t;
-
-/*
- * MP locking protocols:
- * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
- */
-typedef struct bhv_vnode {
- bhv_vflags_t v_flag; /* vnode flags (see above) */
- bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
- bhv_vnumber_t v_number; /* in-core vnode number */
- bhv_head_t v_bh; /* behavior head */
- spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
- atomic_t v_iocount; /* outstanding I/O count */
-#ifdef XFS_VNODE_TRACE
- struct ktrace *v_trace; /* trace header structure */
-#endif
- struct inode v_inode; /* Linux inode */
- /* inode MUST be last */
-} bhv_vnode_t;
-
-#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
-#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
-#define VN_ISDIR(vp) S_ISDIR((vp)->v_inode.i_mode)
-#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
-#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
-
-#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
-#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
-#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
-
-typedef enum {
- VN_BHV_UNKNOWN, /* not specified */
- VN_BHV_XFS, /* xfs */
- VN_BHV_DM, /* data migration */
- VN_BHV_QM, /* quota manager */
- VN_BHV_IO, /* IO path */
- VN_BHV_END /* housekeeping end-of-range */
-} vn_bhv_t;
-
-#define VNODE_POSITION_XFS (VNODE_POSITION_BASE)
-#define VNODE_POSITION_DM (VNODE_POSITION_BASE+10)
-#define VNODE_POSITION_QM (VNODE_POSITION_BASE+20)
-#define VNODE_POSITION_IO (VNODE_POSITION_BASE+30)
-
-/*
- * Macros for dealing with the behavior descriptor inside of the vnode.
- */
-#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
-#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
-
-#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
-#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
-#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
+#define VN_ISLNK(vp) S_ISLNK((vp)->i_mode)
+#define VN_ISREG(vp) S_ISREG((vp)->i_mode)
+#define VN_ISDIR(vp) S_ISDIR((vp)->i_mode)
+#define VN_ISCHR(vp) S_ISCHR((vp)->i_mode)
+#define VN_ISBLK(vp) S_ISBLK((vp)->i_mode)
/*
* Vnode to Linux inode mapping.
*/
-static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
+static inline bhv_vnode_t *vn_from_inode(struct inode *inode)
{
- return container_of(inode, bhv_vnode_t, v_inode);
+ return inode;
}
-static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
+static inline struct inode *vn_to_inode(bhv_vnode_t *vnode)
{
- return &vnode->v_inode;
+ return vnode;
}
/*
@@ -111,7 +58,7 @@ typedef enum bhv_vrwlock {
} bhv_vrwlock_t;
/*
- * Return values for bhv_vop_inactive. A return value of
+ * Return values for xfs_inactive. A return value of
* VN_INACTIVE_NOCACHE implies that the file system behavior
* has disassociated its state and bhv_desc_t from the vnode.
*/
@@ -119,193 +66,6 @@ typedef enum bhv_vrwlock {
#define VN_INACTIVE_NOCACHE 1
/*
- * Values for the cmd code given to vop_vnode_change.
- */
-typedef enum bhv_vchange {
- VCHANGE_FLAGS_FRLOCKS = 0,
- VCHANGE_FLAGS_ENF_LOCKING = 1,
- VCHANGE_FLAGS_TRUNCATED = 2,
- VCHANGE_FLAGS_PAGE_DIRTY = 3,
- VCHANGE_FLAGS_IOEXCL_COUNT = 4
-} bhv_vchange_t;
-
-typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
-typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
- const struct iovec *, unsigned int,
- loff_t *, int, struct cred *);
-typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
- const struct iovec *, unsigned int,
- loff_t *, int, struct cred *);
-typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *,
- struct pipe_inode_info *, size_t, int, int,
- struct cred *);
-typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
- struct file *, loff_t *, size_t, int, int,
- struct cred *);
-typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
- int, unsigned int, void __user *);
-typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
- struct cred *);
-typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
- struct cred *);
-typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
-typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
- int, bhv_vnode_t *, struct cred *);
-typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
- bhv_vnode_t **, struct cred *);
-typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
-typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
- struct cred *);
-typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
- bhv_vname_t *, struct cred *);
-typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
- bhv_vnode_t **, struct cred *);
-typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
-typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
- int *);
-typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
- char *, bhv_vnode_t **, struct cred *);
-typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
- struct cred *);
-typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
- xfs_off_t, xfs_off_t);
-typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
-typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
-typedef int (*vop_release_t)(bhv_desc_t *);
-typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
-typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
-typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
- struct xfs_iomap *, int *);
-typedef int (*vop_reclaim_t)(bhv_desc_t *);
-typedef int (*vop_attr_get_t)(bhv_desc_t *, const char *, char *, int *,
- int, struct cred *);
-typedef int (*vop_attr_set_t)(bhv_desc_t *, const char *, char *, int,
- int, struct cred *);
-typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
- int, struct cred *);
-typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
- struct attrlist_cursor_kern *, struct cred *);
-typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
-typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
-typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
- uint64_t, int);
-typedef int (*vop_iflush_t)(bhv_desc_t *, int);
-
-
-typedef struct bhv_vnodeops {
- bhv_position_t vn_position; /* position within behavior chain */
- vop_open_t vop_open;
- vop_read_t vop_read;
- vop_write_t vop_write;
- vop_splice_read_t vop_splice_read;
- vop_splice_write_t vop_splice_write;
- vop_ioctl_t vop_ioctl;
- vop_getattr_t vop_getattr;
- vop_setattr_t vop_setattr;
- vop_access_t vop_access;
- vop_lookup_t vop_lookup;
- vop_create_t vop_create;
- vop_remove_t vop_remove;
- vop_link_t vop_link;
- vop_rename_t vop_rename;
- vop_mkdir_t vop_mkdir;
- vop_rmdir_t vop_rmdir;
- vop_readdir_t vop_readdir;
- vop_symlink_t vop_symlink;
- vop_readlink_t vop_readlink;
- vop_fsync_t vop_fsync;
- vop_inactive_t vop_inactive;
- vop_fid2_t vop_fid2;
- vop_rwlock_t vop_rwlock;
- vop_rwunlock_t vop_rwunlock;
- vop_bmap_t vop_bmap;
- vop_reclaim_t vop_reclaim;
- vop_attr_get_t vop_attr_get;
- vop_attr_set_t vop_attr_set;
- vop_attr_remove_t vop_attr_remove;
- vop_attr_list_t vop_attr_list;
- vop_link_removed_t vop_link_removed;
- vop_vnode_change_t vop_vnode_change;
- vop_ptossvp_t vop_tosspages;
- vop_pflushinvalvp_t vop_flushinval_pages;
- vop_pflushvp_t vop_flush_pages;
- vop_release_t vop_release;
- vop_iflush_t vop_iflush;
-} bhv_vnodeops_t;
-
-/*
- * Virtual node operations, operating from head bhv.
- */
-#define VNHEAD(vp) ((vp)->v_bh.bh_first)
-#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
-#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
-#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
- VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
-#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
- VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
-#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
- VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
-#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
- VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
-#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
- VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
-#define bhv_vop_getattr(vp, vap,f,cr) \
- VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
-#define bhv_vop_setattr(vp, vap,f,cr) \
- VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
-#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
-#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
- VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
-#define bhv_vop_create(dvp,d,vap,vpp,cr) \
- VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
-#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
-#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
-#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
- VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
-#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
- VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
-#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
-#define bhv_vop_readdir(vp,uiop,cr,eofp) \
- VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
-#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
- VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
-#define bhv_vop_readlink(vp,uiop,fl,cr) \
- VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
-#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
-#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
-#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
-#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
-#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
-#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
-#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
-#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
- VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
-#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
-#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
- VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
-#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
- VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
-#define bhv_vop_attr_remove(vp, name, flags, cred) \
- VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
-#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
- VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
-#define bhv_vop_link_removed(vp, dvp, linkzero) \
- VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
-#define bhv_vop_vnode_change(vp, cmd, val) \
- VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
-#define bhv_vop_toss_pages(vp, first, last, fiopt) \
- VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
-#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
- VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
-#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
- VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
-#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
- VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
-#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
-
-/*
* Flags for read/write calls - same values as IRIX
*/
#define IO_ISAIO 0x00001 /* don't wait for completion */
@@ -428,16 +188,19 @@ typedef struct bhv_vattr {
extern void vn_init(void);
extern bhv_vnode_t *vn_initialize(struct inode *);
-extern int vn_revalidate(struct bhv_vnode *);
-extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
-extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
-
-extern void vn_iowait(struct bhv_vnode *vp);
-extern void vn_iowake(struct bhv_vnode *vp);
+extern int vn_revalidate(bhv_vnode_t *);
+extern int __vn_revalidate(bhv_vnode_t *, bhv_vattr_t *);
+extern void vn_revalidate_core(bhv_vnode_t *, bhv_vattr_t *);
-extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
+/*
+ * Yeah, these don't take vnode anymore at all, all this should be
+ * cleaned up at some point.
+ */
+extern void vn_iowait(struct xfs_inode *ip);
+extern void vn_iowake(struct xfs_inode *ip);
+extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l);
-static inline int vn_count(struct bhv_vnode *vp)
+static inline int vn_count(bhv_vnode_t *vp)
{
return atomic_read(&vn_to_inode(vp)->i_count);
}
@@ -445,21 +208,21 @@ static inline int vn_count(struct bhv_vnode *vp)
/*
* Vnode reference counting functions (and macros for compatibility).
*/
-extern bhv_vnode_t *vn_hold(struct bhv_vnode *);
+extern bhv_vnode_t *vn_hold(bhv_vnode_t *);
#if defined(XFS_VNODE_TRACE)
#define VN_HOLD(vp) \
((void)vn_hold(vp), \
- vn_trace_hold(vp, __FILE__, __LINE__, (inst_t *)__return_address))
+ vn_trace_hold(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address))
#define VN_RELE(vp) \
- (vn_trace_rele(vp, __FILE__, __LINE__, (inst_t *)__return_address), \
+ (vn_trace_rele(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address), \
iput(vn_to_inode(vp)))
#else
#define VN_HOLD(vp) ((void)vn_hold(vp))
#define VN_RELE(vp) (iput(vn_to_inode(vp)))
#endif
-static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
+static inline bhv_vnode_t *vn_grab(bhv_vnode_t *vp)
{
struct inode *inode = igrab(vn_to_inode(vp));
return inode ? vn_from_inode(inode) : NULL;
@@ -473,43 +236,14 @@ static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
#define VNAME_TO_VNODE(dentry) (vn_from_inode((dentry)->d_inode))
/*
- * Vnode spinlock manipulation.
- */
-#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
-#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
-
-STATIC_INLINE void vn_flagset(struct bhv_vnode *vp, uint flag)
-{
- spin_lock(&vp->v_lock);
- vp->v_flag |= flag;
- spin_unlock(&vp->v_lock);
-}
-
-STATIC_INLINE uint vn_flagclr(struct bhv_vnode *vp, uint flag)
-{
- uint cleared;
-
- spin_lock(&vp->v_lock);
- cleared = (vp->v_flag & flag);
- vp->v_flag &= ~flag;
- spin_unlock(&vp->v_lock);
- return cleared;
-}
-
-#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
-#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
-#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
-#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
-
-/*
* Dealing with bad inodes
*/
-static inline void vn_mark_bad(struct bhv_vnode *vp)
+static inline void vn_mark_bad(bhv_vnode_t *vp)
{
make_bad_inode(vn_to_inode(vp));
}
-static inline int VN_BAD(struct bhv_vnode *vp)
+static inline int VN_BAD(bhv_vnode_t *vp)
{
return is_bad_inode(vn_to_inode(vp));
}
@@ -519,18 +253,18 @@ static inline int VN_BAD(struct bhv_vnode *vp)
*/
static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
{
- bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
- bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
+ bs_atime->tv_sec = vp->i_atime.tv_sec;
+ bs_atime->tv_nsec = vp->i_atime.tv_nsec;
}
static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
{
- *ts = vp->v_inode.i_atime;
+ *ts = vp->i_atime;
}
static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
{
- *tt = vp->v_inode.i_atime.tv_sec;
+ *tt = vp->i_atime.tv_sec;
}
/*
@@ -540,7 +274,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
PAGECACHE_TAG_DIRTY)
-#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
/*
* Flags to vop_setattr/getattr.
@@ -572,21 +305,17 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
#define VNODE_KTRACE_REF 4
#define VNODE_KTRACE_RELE 5
-extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
-extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
-extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
-extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
-extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
-
-#define VN_TRACE(vp) \
- vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
+extern void vn_trace_entry(struct xfs_inode *, const char *, inst_t *);
+extern void vn_trace_exit(struct xfs_inode *, const char *, inst_t *);
+extern void vn_trace_hold(struct xfs_inode *, char *, int, inst_t *);
+extern void vn_trace_ref(struct xfs_inode *, char *, int, inst_t *);
+extern void vn_trace_rele(struct xfs_inode *, char *, int, inst_t *);
#else
#define vn_trace_entry(a,b,c)
#define vn_trace_exit(a,b,c)
#define vn_trace_hold(a,b,c,d)
#define vn_trace_ref(a,b,c,d)
#define vn_trace_rele(a,b,c,d)
-#define VN_TRACE(vp)
#endif
#endif /* __XFS_VNODE_H__ */
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 6ff0f4de163..b5f91281b70 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -288,45 +288,6 @@ xfs_qm_rele_quotafs_ref(
}
/*
- * This is called at mount time from xfs_mountfs to initialize the quotainfo
- * structure and start the global quota manager (xfs_Gqm) if it hasn't done
- * so already. Note that the superblock has not been read in yet.
- */
-void
-xfs_qm_mount_quotainit(
- xfs_mount_t *mp,
- uint flags)
-{
- /*
- * User, projects or group quotas has to be on.
- */
- ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
-
- /*
- * Initialize the flags in the mount structure. From this point
- * onwards we look at m_qflags to figure out if quotas's ON/OFF, etc.
- * Note that we enforce nothing if accounting is off.
- * ie. XFSMNT_*QUOTA must be ON for XFSMNT_*QUOTAENF.
- * It isn't necessary to take the quotaoff lock to do this; this is
- * called from mount.
- */
- if (flags & XFSMNT_UQUOTA) {
- mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
- if (flags & XFSMNT_UQUOTAENF)
- mp->m_qflags |= XFS_UQUOTA_ENFD;
- }
- if (flags & XFSMNT_GQUOTA) {
- mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
- if (flags & XFSMNT_GQUOTAENF)
- mp->m_qflags |= XFS_OQUOTA_ENFD;
- } else if (flags & XFSMNT_PQUOTA) {
- mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
- if (flags & XFSMNT_PQUOTAENF)
- mp->m_qflags |= XFS_OQUOTA_ENFD;
- }
-}
-
-/*
* Just destroy the quotainfo structure.
*/
void
@@ -1039,7 +1000,7 @@ xfs_qm_dqdetach(
int
xfs_qm_sync(
xfs_mount_t *mp,
- short flags)
+ int flags)
{
int recl, restarts;
xfs_dquot_t *dqp;
@@ -1717,7 +1678,6 @@ xfs_qm_get_rtblks(
xfs_extnum_t idx; /* extent record index */
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_extnum_t nextents; /* number of extent entries */
- xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
int error;
ASSERT(XFS_IS_REALTIME_INODE(ip));
@@ -1728,10 +1688,8 @@ xfs_qm_get_rtblks(
}
rtblks = 0;
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
- for (idx = 0; idx < nextents; idx++) {
- ep = xfs_iext_get_ext(ifp, idx);
- rtblks += xfs_bmbt_get_blockcount(ep);
- }
+ for (idx = 0; idx < nextents; idx++)
+ rtblks += xfs_bmbt_get_blockcount(xfs_iext_get_ext(ifp, idx));
*O_rtblks = (xfs_qcnt_t)rtblks;
return 0;
}
@@ -2459,8 +2417,7 @@ xfs_qm_vop_dqalloc(
lockflags = XFS_ILOCK_EXCL;
xfs_ilock(ip, lockflags);
- if ((flags & XFS_QMOPT_INHERIT) &&
- XFS_INHERIT_GID(ip, XFS_MTOVFS(mp)))
+ if ((flags & XFS_QMOPT_INHERIT) && XFS_INHERIT_GID(ip))
gid = ip->i_d.di_gid;
/*
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 689407de0a2..23ccaa5fcea 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -166,12 +166,11 @@ typedef struct xfs_dquot_acct {
extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
extern int xfs_qm_mount_quotas(xfs_mount_t *, int);
-extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
extern int xfs_qm_quotacheck(xfs_mount_t *);
extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *);
extern int xfs_qm_unmount_quotas(xfs_mount_t *);
extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
-extern int xfs_qm_sync(xfs_mount_t *, short);
+extern int xfs_qm_sync(xfs_mount_t *, int);
/* dquot stuff */
extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **);
@@ -199,7 +198,8 @@ extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
/* system call interface */
-extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
+extern int xfs_qm_quotactl(struct xfs_mount *, int, int,
+ xfs_caddr_t);
#ifdef DEBUG
extern int xfs_qm_internalqcheck(xfs_mount_t *);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index d2cdb8a2aad..97bb3293758 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -48,172 +48,13 @@
#include "xfs_buf_item.h"
#include "xfs_qm.h"
-#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
-#define MNTOPT_NOQUOTA "noquota" /* no quotas */
-#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
-#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
-#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
-#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
-#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
-#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
-#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
-#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
-#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
-#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
-STATIC int
-xfs_qm_parseargs(
- struct bhv_desc *bhv,
- char *options,
- struct xfs_mount_args *args,
- int update)
-{
- size_t length;
- char *local_options = options;
- char *this_char;
- int error;
- int referenced = update;
-
- while ((this_char = strsep(&local_options, ",")) != NULL) {
- length = strlen(this_char);
- if (local_options)
- length++;
-
- if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
- args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
- args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
- referenced = update;
- } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
- !strcmp(this_char, MNTOPT_UQUOTA) ||
- !strcmp(this_char, MNTOPT_USRQUOTA)) {
- args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
- !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
- args->flags |= XFSMNT_UQUOTA;
- args->flags &= ~XFSMNT_UQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
- !strcmp(this_char, MNTOPT_PRJQUOTA)) {
- args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
- args->flags |= XFSMNT_PQUOTA;
- args->flags &= ~XFSMNT_PQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
- !strcmp(this_char, MNTOPT_GRPQUOTA)) {
- args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
- referenced = 1;
- } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
- args->flags |= XFSMNT_GQUOTA;
- args->flags &= ~XFSMNT_GQUOTAENF;
- referenced = 1;
- } else {
- if (local_options)
- *(local_options-1) = ',';
- continue;
- }
-
- while (length--)
- *this_char++ = ',';
- }
-
- if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
- cmn_err(CE_WARN,
- "XFS: cannot mount with both project and group quota");
- return XFS_ERROR(EINVAL);
- }
-
- error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
- if (!error && !referenced)
- bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
- return error;
-}
-
-STATIC int
-xfs_qm_showargs(
- struct bhv_desc *bhv,
- struct seq_file *m)
-{
- struct bhv_vfs *vfsp = bhvtovfs(bhv);
- struct xfs_mount *mp = XFS_VFSTOM(vfsp);
-
- if (mp->m_qflags & XFS_UQUOTA_ACCT) {
- (mp->m_qflags & XFS_UQUOTA_ENFD) ?
- seq_puts(m, "," MNTOPT_USRQUOTA) :
- seq_puts(m, "," MNTOPT_UQUOTANOENF);
- }
-
- if (mp->m_qflags & XFS_PQUOTA_ACCT) {
- (mp->m_qflags & XFS_OQUOTA_ENFD) ?
- seq_puts(m, "," MNTOPT_PRJQUOTA) :
- seq_puts(m, "," MNTOPT_PQUOTANOENF);
- }
-
- if (mp->m_qflags & XFS_GQUOTA_ACCT) {
- (mp->m_qflags & XFS_OQUOTA_ENFD) ?
- seq_puts(m, "," MNTOPT_GRPQUOTA) :
- seq_puts(m, "," MNTOPT_GQUOTANOENF);
- }
-
- if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
- seq_puts(m, "," MNTOPT_NOQUOTA);
-
- return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
-}
-
-STATIC int
-xfs_qm_mount(
- struct bhv_desc *bhv,
- struct xfs_mount_args *args,
- struct cred *cr)
-{
- struct bhv_vfs *vfsp = bhvtovfs(bhv);
- struct xfs_mount *mp = XFS_VFSTOM(vfsp);
-
- if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
- xfs_qm_mount_quotainit(mp, args->flags);
- return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
-}
-
-/*
- * Directory tree accounting is implemented using project quotas, where
- * the project identifier is inherited from parent directories.
- * A statvfs (df, etc.) of a directory that is using project quota should
- * return a statvfs of the project, not the entire filesystem.
- * This makes such trees appear as if they are filesystems in themselves.
- */
-STATIC int
-xfs_qm_statvfs(
- struct bhv_desc *bhv,
+STATIC void
+xfs_fill_statvfs_from_dquot(
bhv_statvfs_t *statp,
- struct bhv_vnode *vnode)
+ xfs_disk_dquot_t *dp)
{
- xfs_mount_t *mp;
- xfs_inode_t *ip;
- xfs_dquot_t *dqp;
- xfs_disk_dquot_t *dp;
__uint64_t limit;
- int error;
-
- error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
- if (error || !vnode)
- return error;
-
- mp = xfs_vfstom(bhvtovfs(bhv));
- ip = xfs_vtoi(vnode);
-
- if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
- return 0;
- if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
- return 0;
- if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
- return 0;
-
- if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
- return 0;
- dp = &dqp->q_core;
limit = dp->d_blk_softlimit ?
be64_to_cpu(dp->d_blk_softlimit) :
@@ -234,37 +75,35 @@ xfs_qm_statvfs(
(statp->f_files > be64_to_cpu(dp->d_icount)) ?
(statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0;
}
-
- xfs_qm_dqput(dqp);
- return 0;
}
-STATIC int
-xfs_qm_syncall(
- struct bhv_desc *bhv,
- int flags,
- cred_t *credp)
+
+/*
+ * Directory tree accounting is implemented using project quotas, where
+ * the project identifier is inherited from parent directories.
+ * A statvfs (df, etc.) of a directory that is using project quota should
+ * return a statvfs of the project, not the entire filesystem.
+ * This makes such trees appear as if they are filesystems in themselves.
+ */
+STATIC void
+xfs_qm_statvfs(
+ xfs_inode_t *ip,
+ bhv_statvfs_t *statp)
{
- struct bhv_vfs *vfsp = bhvtovfs(bhv);
- struct xfs_mount *mp = XFS_VFSTOM(vfsp);
- int error;
+ xfs_mount_t *mp = ip->i_mount;
+ xfs_dquot_t *dqp;
- /*
- * Get the Quota Manager to flush the dquots.
- */
- if (XFS_IS_QUOTA_ON(mp)) {
- if ((error = xfs_qm_sync(mp, flags))) {
- /*
- * If we got an IO error, we will be shutting down.
- * So, there's nothing more for us to do here.
- */
- ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
- if (XFS_FORCED_SHUTDOWN(mp)) {
- return XFS_ERROR(error);
- }
- }
+ if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
+ !((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
+ (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
+ return;
+
+ if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
+ xfs_disk_dquot_t *dp = &dqp->q_core;
+
+ xfs_fill_statvfs_from_dquot(statp, dp);
+ xfs_qm_dqput(dqp);
}
- return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
}
STATIC int
@@ -382,7 +221,7 @@ xfs_qm_dqrele_null(
}
-static struct xfs_qmops xfs_qmcore_xfs = {
+struct xfs_qmops xfs_qmcore_xfs = {
.xfs_qminit = xfs_qm_newmount,
.xfs_qmdone = xfs_qm_unmount_quotadestroy,
.xfs_qmmount = xfs_qm_endmount,
@@ -396,36 +235,24 @@ static struct xfs_qmops xfs_qmcore_xfs = {
.xfs_dqvoprename = xfs_qm_vop_rename_dqattach,
.xfs_dqvopchown = xfs_qm_vop_chown,
.xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
+ .xfs_dqstatvfs = xfs_qm_statvfs,
+ .xfs_dqsync = xfs_qm_sync,
+ .xfs_quotactl = xfs_qm_quotactl,
.xfs_dqtrxops = &xfs_trans_dquot_ops,
};
-
-struct bhv_module_vfsops xfs_qmops = { {
- BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
- .vfs_parseargs = xfs_qm_parseargs,
- .vfs_showargs = xfs_qm_showargs,
- .vfs_mount = xfs_qm_mount,
- .vfs_statvfs = xfs_qm_statvfs,
- .vfs_sync = xfs_qm_syncall,
- .vfs_quotactl = xfs_qm_quotactl, },
-};
-
+EXPORT_SYMBOL(xfs_qmcore_xfs);
void __init
xfs_qm_init(void)
{
- static char message[] __initdata =
- KERN_INFO "SGI XFS Quota Management subsystem\n";
-
- printk(message);
+ printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
mutex_init(&xfs_Gqm_lock);
- vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs);
xfs_qm_init_procfs();
}
void __exit
xfs_qm_exit(void)
{
- vfs_bhv_clr_custom(&xfs_qmops);
xfs_qm_cleanup_procfs();
if (qm_dqzone)
kmem_zone_destroy(qm_dqzone);
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 2df67fd913e..ad5579d4eac 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -81,18 +81,13 @@ STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
*/
int
xfs_qm_quotactl(
- struct bhv_desc *bdp,
+ xfs_mount_t *mp,
int cmd,
int id,
xfs_caddr_t addr)
{
- xfs_mount_t *mp;
- bhv_vfs_t *vfsp;
int error;
- vfsp = bhvtovfs(bdp);
- mp = XFS_VFSTOM(vfsp);
-
ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
/*
@@ -105,7 +100,7 @@ xfs_qm_quotactl(
*/
if (XFS_IS_QUOTA_ON(mp))
return XFS_ERROR(EINVAL);
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
return (xfs_qm_scall_trunc_qfiles(mp,
xfs_qm_import_qtype_flags(*(uint *)addr)));
@@ -121,13 +116,13 @@ xfs_qm_quotactl(
* QUOTAON - enabling quota enforcement.
* Quota accounting must be turned on at mount time.
*/
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
return (xfs_qm_scall_quotaon(mp,
xfs_qm_import_flags(*(uint *)addr)));
case Q_XQUOTAOFF:
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
break;
@@ -143,7 +138,7 @@ xfs_qm_quotactl(
switch (cmd) {
case Q_XQUOTAOFF:
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_quotaoff(mp,
xfs_qm_import_flags(*(uint *)addr),
@@ -164,19 +159,19 @@ xfs_qm_quotactl(
break;
case Q_XSETQLIM:
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
(fs_disk_quota_t *)addr);
break;
case Q_XSETGQLIM:
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
(fs_disk_quota_t *)addr);
break;
case Q_XSETPQLIM:
- if (vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
(fs_disk_quota_t *)addr);
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c
deleted file mode 100644
index ac8617ca390..00000000000
--- a/fs/xfs/support/move.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * 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. 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <xfs.h>
-
-/* Read from kernel buffer at src to user/kernel buffer defined
- * by the uio structure. Advance the pointer in the uio struct
- * as we go.
- */
-int
-xfs_uio_read(caddr_t src, size_t len, struct uio *uio)
-{
- size_t count;
-
- if (!len || !uio->uio_resid)
- return 0;
-
- count = uio->uio_iov->iov_len;
- if (!count)
- return 0;
- if (count > len)
- count = len;
-
- if (uio->uio_segflg == UIO_USERSPACE) {
- if (copy_to_user(uio->uio_iov->iov_base, src, count))
- return EFAULT;
- } else {
- ASSERT(uio->uio_segflg == UIO_SYSSPACE);
- memcpy(uio->uio_iov->iov_base, src, count);
- }
-
- uio->uio_iov->iov_base = (void*)((char*)uio->uio_iov->iov_base + count);
- uio->uio_iov->iov_len -= count;
- uio->uio_offset += count;
- uio->uio_resid -= count;
- return 0;
-}
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h
deleted file mode 100644
index 324e413dead..00000000000
--- a/fs/xfs/support/move.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * 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. 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Portions Copyright (c) 1982, 1986, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef __XFS_SUPPORT_MOVE_H__
-#define __XFS_SUPPORT_MOVE_H__
-
-#include <linux/uio.h>
-#include <asm/uaccess.h>
-
-/* Segment flag values. */
-enum uio_seg {
- UIO_USERSPACE, /* from user data space */
- UIO_SYSSPACE, /* from system space */
-};
-
-struct uio {
- struct kvec *uio_iov; /* pointer to array of iovecs */
- int uio_iovcnt; /* number of iovecs in array */
- xfs_off_t uio_offset; /* offset in file this uio corresponds to */
- int uio_resid; /* residual i/o count */
- enum uio_seg uio_segflg; /* see above */
-};
-
-typedef struct uio uio_t;
-typedef struct kvec iovec_t;
-
-extern int xfs_uio_read (caddr_t, size_t, uio_t *);
-
-#endif /* __XFS_SUPPORT_MOVE_H__ */
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 4ca4beb7bb5..5bfb66f33ca 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -32,6 +32,7 @@
#include "xfs_btree.h"
#include "xfs_acl.h"
#include "xfs_attr.h"
+#include "xfs_vnodeops.h"
#include <linux/capability.h>
#include <linux/posix_acl_xattr.h>
@@ -241,7 +242,7 @@ xfs_acl_vget(
bhv_vattr_t va;
va.va_mask = XFS_AT_MODE;
- error = bhv_vop_getattr(vp, &va, 0, sys_cred);
+ error = xfs_getattr(xfs_vtoi(vp), &va, 0);
if (error)
goto out;
xfs_acl_sync_mode(va.va_mode, xfs_acl);
@@ -265,9 +266,10 @@ xfs_acl_vremove(
VN_HOLD(vp);
error = xfs_acl_allow_set(vp, kind);
if (!error) {
- error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
+ error = xfs_attr_remove(xfs_vtoi(vp),
+ kind == _ACL_TYPE_DEFAULT?
SGI_ACL_DEFAULT: SGI_ACL_FILE,
- ATTR_ROOT, sys_cred);
+ ATTR_ROOT);
if (error == ENOATTR)
error = 0; /* 'scool */
}
@@ -370,17 +372,18 @@ xfs_acl_allow_set(
bhv_vnode_t *vp,
int kind)
{
+ xfs_inode_t *ip = xfs_vtoi(vp);
bhv_vattr_t va;
int error;
- if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
+ if (vp->i_flags & (S_IMMUTABLE|S_APPEND))
return EPERM;
if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp))
return ENOTDIR;
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+ if (vp->i_sb->s_flags & MS_RDONLY)
return EROFS;
va.va_mask = XFS_AT_UID;
- error = bhv_vop_getattr(vp, &va, 0, NULL);
+ error = xfs_getattr(ip, &va, 0);
if (error)
return error;
if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@@ -613,7 +616,8 @@ xfs_acl_get_attr(
ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
flags |= ATTR_ROOT;
- *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
+ *error = xfs_attr_get(xfs_vtoi(vp),
+ kind == _ACL_TYPE_ACCESS ?
SGI_ACL_FILE : SGI_ACL_DEFAULT,
(char *)aclp, &len, flags, sys_cred);
if (*error || (flags & ATTR_KERNOVAL))
@@ -651,9 +655,10 @@ xfs_acl_set_attr(
INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
}
INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
- *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
+ *error = xfs_attr_set(xfs_vtoi(vp),
+ kind == _ACL_TYPE_ACCESS ?
SGI_ACL_FILE: SGI_ACL_DEFAULT,
- (char *)newacl, len, ATTR_ROOT, sys_cred);
+ (char *)newacl, len, ATTR_ROOT);
_ACL_FREE(newacl);
}
@@ -675,7 +680,7 @@ xfs_acl_vtoacl(
if (!error) {
/* Got the ACL, need the mode... */
va.va_mask = XFS_AT_MODE;
- error = bhv_vop_getattr(vp, &va, 0, sys_cred);
+ error = xfs_getattr(xfs_vtoi(vp), &va, 0);
}
if (error)
@@ -699,7 +704,7 @@ xfs_acl_vtoacl(
int
xfs_acl_inherit(
bhv_vnode_t *vp,
- bhv_vattr_t *vap,
+ mode_t mode,
xfs_acl_t *pdaclp)
{
xfs_acl_t *cacl;
@@ -727,7 +732,7 @@ xfs_acl_inherit(
return ENOMEM;
memcpy(cacl, pdaclp, sizeof(xfs_acl_t));
- xfs_acl_filter_mode(vap->va_mode, cacl);
+ xfs_acl_filter_mode(mode, cacl);
xfs_acl_setmode(vp, cacl, &basicperms);
/*
@@ -773,7 +778,7 @@ xfs_acl_setmode(
* mode. The m:: bits take precedence over the g:: bits.
*/
va.va_mask = XFS_AT_MODE;
- error = bhv_vop_getattr(vp, &va, 0, sys_cred);
+ error = xfs_getattr(xfs_vtoi(vp), &va, 0);
if (error)
return error;
@@ -807,7 +812,7 @@ xfs_acl_setmode(
if (gap && nomask)
va.va_mode |= gap->ae_perm << 3;
- return bhv_vop_setattr(vp, &va, 0, sys_cred);
+ return xfs_setattr(xfs_vtoi(vp), &va, 0, sys_cred);
}
/*
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index f853cf1a627..34b7d339129 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -50,7 +50,6 @@ typedef struct xfs_acl {
#ifdef CONFIG_XFS_POSIX_ACL
struct vattr;
-struct bhv_vnode;
struct xfs_inode;
extern struct kmem_zone *xfs_acl_zone;
@@ -58,20 +57,20 @@ extern struct kmem_zone *xfs_acl_zone;
(zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
-extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
+extern int xfs_acl_inherit(bhv_vnode_t *, mode_t mode, xfs_acl_t *);
extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
-extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
-extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
-extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
-extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
-extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
-extern int xfs_acl_vremove(struct bhv_vnode *, int);
+extern int xfs_acl_vtoacl(bhv_vnode_t *, xfs_acl_t *, xfs_acl_t *);
+extern int xfs_acl_vhasacl_access(bhv_vnode_t *);
+extern int xfs_acl_vhasacl_default(bhv_vnode_t *);
+extern int xfs_acl_vset(bhv_vnode_t *, void *, size_t, int);
+extern int xfs_acl_vget(bhv_vnode_t *, void *, size_t, int);
+extern int xfs_acl_vremove(bhv_vnode_t *, int);
#define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2
#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
-#define _ACL_INHERIT(c,v,d) (xfs_acl_inherit(c,v,d))
+#define _ACL_INHERIT(c,m,d) (xfs_acl_inherit(c,m,d))
#define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0)
#define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0)
#define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access
@@ -91,7 +90,7 @@ extern int xfs_acl_vremove(struct bhv_vnode *, int);
#define xfs_acl_vhasacl_default(v) (0)
#define _ACL_ALLOC(a) (1) /* successfully allocate nothing */
#define _ACL_FREE(a) ((void)0)
-#define _ACL_INHERIT(c,v,d) (0)
+#define _ACL_INHERIT(c,m,d) (0)
#define _ACL_GET_ACCESS(pv,pa) (0)
#define _ACL_GET_DEFAULT(pv,pd) (0)
#define _ACL_ACCESS_EXISTS (NULL)
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 51c09c114a2..9381b0360c4 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -197,6 +197,10 @@ typedef struct xfs_perag
#endif
xfs_perag_busy_t *pagb_list; /* unstable blocks */
atomic_t pagf_fstrms; /* # of filestreams active in this AG */
+
+ int pag_ici_init; /* incore inode cache initialised */
+ rwlock_t pag_ici_lock; /* incore inode lock */
+ struct radix_tree_root pag_ici_root; /* incore inode cache root */
} xfs_perag_t;
#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 7ce44a7b88a..93fa64dd1be 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -49,6 +49,7 @@
#include "xfs_trans_space.h"
#include "xfs_acl.h"
#include "xfs_rw.h"
+#include "xfs_vnodeops.h"
/*
* xfs_attr.c
@@ -156,10 +157,14 @@ xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen,
}
int
-xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp,
- int flags, struct cred *cred)
+xfs_attr_get(
+ xfs_inode_t *ip,
+ const char *name,
+ char *value,
+ int *valuelenp,
+ int flags,
+ cred_t *cred)
{
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
int error, namelen;
XFS_STATS_INC(xs_attr_get);
@@ -417,10 +422,13 @@ out:
}
int
-xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int flags,
- struct cred *cred)
+xfs_attr_set(
+ xfs_inode_t *dp,
+ const char *name,
+ char *value,
+ int valuelen,
+ int flags)
{
- xfs_inode_t *dp;
int namelen;
namelen = strlen(name);
@@ -429,7 +437,6 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
XFS_STATS_INC(xs_attr_set);
- dp = XFS_BHVTOI(bdp);
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return (EIO);
@@ -563,10 +570,12 @@ out:
}
int
-xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
+xfs_attr_remove(
+ xfs_inode_t *dp,
+ const char *name,
+ int flags)
{
- xfs_inode_t *dp;
- int namelen;
+ int namelen;
namelen = strlen(name);
if (namelen >= MAXNAMELEN)
@@ -574,7 +583,6 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
XFS_STATS_INC(xs_attr_remove);
- dp = XFS_BHVTOI(bdp);
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return (EIO);
@@ -702,11 +710,14 @@ xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
* success.
*/
int
-xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
- attrlist_cursor_kern_t *cursor, struct cred *cred)
+xfs_attr_list(
+ xfs_inode_t *dp,
+ char *buffer,
+ int bufsize,
+ int flags,
+ attrlist_cursor_kern_t *cursor)
{
xfs_attr_list_context_t context;
- xfs_inode_t *dp;
int error;
XFS_STATS_INC(xs_attr_list);
@@ -731,7 +742,7 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
/*
* Initialize the output buffer.
*/
- context.dp = dp = XFS_BHVTOI(bdp);
+ context.dp = dp;
context.cursor = cursor;
context.count = 0;
context.dupcnt = 0;
@@ -2502,7 +2513,7 @@ STATIC int
attr_generic_set(
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
- return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
+ return -xfs_attr_set(xfs_vtoi(vp), name, data, size, xflags);
}
STATIC int
@@ -2511,7 +2522,8 @@ attr_generic_get(
{
int error, asize = size;
- error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
+ error = xfs_attr_get(xfs_vtoi(vp), name, data,
+ &asize, xflags, NULL);
if (!error)
return asize;
return -error;
@@ -2521,7 +2533,7 @@ STATIC int
attr_generic_remove(
bhv_vnode_t *vp, char *name, int xflags)
{
- return -bhv_vop_attr_remove(vp, name, xflags, NULL);
+ return -xfs_attr_remove(xfs_vtoi(vp), name, xflags);
}
STATIC int
@@ -2576,7 +2588,7 @@ attr_generic_list(
attrlist_cursor_kern_t cursor = { 0 };
int error;
- error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
+ error = xfs_attr_list(xfs_vtoi(vp), data, size, xflags, &cursor);
if (error > 0)
return -error;
*result = -error;
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 783977d3ea7..786eba3121c 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -36,14 +36,13 @@
*========================================================================*/
struct cred;
-struct bhv_vnode;
struct xfs_attr_list_context;
-typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
-typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
-typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
-typedef int (*attrexists_t)(struct bhv_vnode *);
-typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
+typedef int (*attrset_t)(bhv_vnode_t *, char *, void *, size_t, int);
+typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int);
+typedef int (*attrremove_t)(bhv_vnode_t *, char *, int);
+typedef int (*attrexists_t)(bhv_vnode_t *);
+typedef int (*attrcapable_t)(bhv_vnode_t *, struct cred *);
typedef struct attrnames {
char * attr_name;
@@ -64,7 +63,7 @@ extern struct attrnames attr_trusted;
extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
-extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
+extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *);
#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
@@ -159,12 +158,8 @@ struct xfs_da_args;
/*
* Overall external interface routines.
*/
-int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
-int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int);
-int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int);
-int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *);
int xfs_attr_list_int(struct xfs_attr_list_context *);
int xfs_attr_inactive(struct xfs_inode *dp);
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c
deleted file mode 100644
index 0dc17219d41..00000000000
--- a/fs/xfs/xfs_behavior.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * 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. 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-
-/*
- * Source file used to associate/disassociate behaviors with virtualized
- * objects. See xfs_behavior.h for more information about behaviors, etc.
- *
- * The implementation is split between functions in this file and macros
- * in xfs_behavior.h.
- */
-
-/*
- * Insert a new behavior descriptor into a behavior chain.
- *
- * The behavior chain is ordered based on the 'position' number which
- * lives in the first field of the ops vector (higher numbers first).
- *
- * Attempts to insert duplicate ops result in an EINVAL return code.
- * Otherwise, return 0 to indicate success.
- */
-int
-bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
-{
- bhv_desc_t *curdesc, *prev;
- int position;
-
- /*
- * Validate the position value of the new behavior.
- */
- position = BHV_POSITION(bdp);
- ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP);
-
- /*
- * Find location to insert behavior. Check for duplicates.
- */
- prev = NULL;
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- /* Check for duplication. */
- if (curdesc->bd_ops == bdp->bd_ops) {
- ASSERT(0);
- return EINVAL;
- }
-
- /* Find correct position */
- if (position >= BHV_POSITION(curdesc)) {
- ASSERT(position != BHV_POSITION(curdesc));
- break; /* found it */
- }
-
- prev = curdesc;
- }
-
- if (prev == NULL) {
- /* insert at front of chain */
- bdp->bd_next = bhp->bh_first;
- bhp->bh_first = bdp;
- } else {
- /* insert after prev */
- bdp->bd_next = prev->bd_next;
- prev->bd_next = bdp;
- }
-
- return 0;
-}
-
-/*
- * Remove a behavior descriptor from a position in a behavior chain;
- * the position is guaranteed not to be the first position.
- * Should only be called by the bhv_remove() macro.
- */
-void
-bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
-{
- bhv_desc_t *curdesc, *prev;
-
- ASSERT(bhp->bh_first != NULL);
- ASSERT(bhp->bh_first->bd_next != NULL);
-
- prev = bhp->bh_first;
- for (curdesc = bhp->bh_first->bd_next;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- if (curdesc == bdp)
- break; /* found it */
- prev = curdesc;
- }
-
- ASSERT(curdesc == bdp);
- prev->bd_next = bdp->bd_next; /* remove from after prev */
-}
-
-/*
- * Looks for the first behavior within a specified range of positions.
- * Return the associated behavior descriptor. Or NULL, if none found.
- */
-bhv_desc_t *
-bhv_lookup_range(bhv_head_t *bhp, int low, int high)
-{
- bhv_desc_t *curdesc;
-
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- int position = BHV_POSITION(curdesc);
-
- if (position <= high) {
- if (position >= low)
- return curdesc;
- return NULL;
- }
- }
-
- return NULL;
-}
-
-/*
- * Return the base behavior in the chain, or NULL if the chain
- * is empty.
- *
- * The caller has not read locked the behavior chain, so acquire the
- * lock before traversing the chain.
- */
-bhv_desc_t *
-bhv_base(bhv_head_t *bhp)
-{
- bhv_desc_t *curdesc;
-
- for (curdesc = bhp->bh_first;
- curdesc != NULL;
- curdesc = curdesc->bd_next) {
-
- if (curdesc->bd_next == NULL) {
- return curdesc;
- }
- }
-
- return NULL;
-}
-
-void
-bhv_head_init(
- bhv_head_t *bhp,
- char *name)
-{
- bhp->bh_first = NULL;
-}
-
-void
-bhv_insert_initial(
- bhv_head_t *bhp,
- bhv_desc_t *bdp)
-{
- ASSERT(bhp->bh_first == NULL);
- (bhp)->bh_first = bdp;
-}
-
-void
-bhv_head_destroy(
- bhv_head_t *bhp)
-{
- ASSERT(bhp->bh_first == NULL);
-}
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h
deleted file mode 100644
index e7ca1fed955..00000000000
--- a/fs/xfs/xfs_behavior.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * 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.
- *
- * 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. 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_BEHAVIOR_H__
-#define __XFS_BEHAVIOR_H__
-
-/*
- * Header file used to associate behaviors with virtualized objects.
- *
- * A virtualized object is an internal, virtualized representation of
- * OS entities such as persistent files, processes, or sockets. Examples
- * of virtualized objects include vnodes, vprocs, and vsockets. Often
- * a virtualized object is referred to simply as an "object."
- *
- * A behavior is essentially an implementation layer associated with
- * an object. Multiple behaviors for an object are chained together,
- * the order of chaining determining the order of invocation. Each
- * behavior of a given object implements the same set of interfaces
- * (e.g., the VOP interfaces).
- *
- * Behaviors may be dynamically inserted into an object's behavior chain,
- * such that the addition is transparent to consumers that already have
- * references to the object. Typically, a given behavior will be inserted
- * at a particular location in the behavior chain. Insertion of new
- * behaviors is synchronized with operations-in-progress (oip's) so that
- * the oip's always see a consistent view of the chain.
- *
- * The term "interposition" is used to refer to the act of inserting
- * a behavior such that it interposes on (i.e., is inserted in front
- * of) a particular other behavior. A key example of this is when a
- * system implementing distributed single system image wishes to
- * interpose a distribution layer (providing distributed coherency)
- * in front of an object that is otherwise only accessed locally.
- *
- * Note that the traditional vnode/inode combination is simply a virtualized
- * object that has exactly one associated behavior.
- *
- * Behavior synchronization is logic which is necessary under certain
- * circumstances that there is no conflict between ongoing operations
- * traversing the behavior chain and those dynamically modifying the
- * behavior chain. Because behavior synchronization adds extra overhead
- * to virtual operation invocation, we want to restrict, as much as
- * we can, the requirement for this extra code, to those situations
- * in which it is truly necessary.
- *
- * Behavior synchronization is needed whenever there's at least one class
- * of object in the system for which:
- * 1) multiple behaviors for a given object are supported,
- * -- AND --
- * 2a) insertion of a new behavior can happen dynamically at any time during
- * the life of an active object,
- * -- AND --
- * 3a) insertion of a new behavior needs to synchronize with existing
- * ops-in-progress.
- * -- OR --
- * 3b) multiple different behaviors can be dynamically inserted at
- * any time during the life of an active object
- * -- OR --
- * 3c) removal of a behavior can occur at any time during the life of
- * an active object.
- * -- OR --
- * 2b) removal of a behavior can occur at any time during the life of an
- * active object
- *
- */
-
-/*
- * Behavior head. Head of the chain of behaviors.
- * Contained within each virtualized object data structure.
- */
-typedef struct bhv_head {
- struct bhv_desc *bh_first; /* first behavior in chain */
-} bhv_head_t;
-
-/*
- * Behavior descriptor. Descriptor associated with each behavior.
- * Contained within the behavior's private data structure.
- */
-typedef struct bhv_desc {
- void *bd_pdata; /* private data for this behavior */
- void *bd_vobj; /* virtual object associated with */
- void *bd_ops; /* ops for this behavior */
- struct bhv_desc *bd_next; /* next behavior in chain */
-} bhv_desc_t;
-
-/*
- * Behavior identity field. A behavior's identity determines the position
- * where it lives within a behavior chain, and it's always the first field
- * of the behavior's ops vector. The optional id field further identifies the
- * subsystem responsible for the behavior.
- */
-typedef struct bhv_identity {
- __u16 bi_id; /* owning subsystem id */
- __u16 bi_position; /* position in chain */
-} bhv_identity_t;
-
-typedef bhv_identity_t bhv_position_t;
-
-#define BHV_IDENTITY_INIT(id,pos) {id, pos}
-#define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos)
-
-/*
- * Define boundaries of position values.
- */
-#define BHV_POSITION_INVALID 0 /* invalid position number */
-#define BHV_POSITION_BASE 1 /* base (last) implementation layer */
-#define BHV_POSITION_TOP 63 /* top (first) implementation layer */
-
-/*
- * Plumbing macros.
- */
-#define BHV_HEAD_FIRST(bhp) (ASSERT((bhp)->bh_first), (bhp)->bh_first)
-#define BHV_NEXT(bdp) (ASSERT((bdp)->bd_next), (bdp)->bd_next)
-#define BHV_NEXTNULL(bdp) ((bdp)->bd_next)
-#define BHV_VOBJ(bdp) (ASSERT((bdp)->bd_vobj), (bdp)->bd_vobj)
-#define BHV_VOBJNULL(bdp) ((bdp)->bd_vobj)
-#define BHV_PDATA(bdp) (bdp)->bd_pdata
-#define BHV_OPS(bdp) (bdp)->bd_ops
-#define BHV_IDENTITY(bdp) ((bhv_identity_t *)(bdp)->bd_ops)
-#define BHV_POSITION(bdp) (BHV_IDENTITY(bdp)->bi_position)
-
-extern void bhv_head_init(bhv_head_t *, char *);
-extern void bhv_head_destroy(bhv_head_t *);
-extern int bhv_insert(bhv_head_t *, bhv_desc_t *);
-extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
-
-/*
- * Initialize a new behavior descriptor.
- * Arguments:
- * bdp - pointer to behavior descriptor
- * pdata - pointer to behavior's private data
- * vobj - pointer to associated virtual object
- * ops - pointer to ops for this behavior
- */
-#define bhv_desc_init(bdp, pdata, vobj, ops) \
- { \
- (bdp)->bd_pdata = pdata; \
- (bdp)->bd_vobj = vobj; \
- (bdp)->bd_ops = ops; \
- (bdp)->bd_next = NULL; \
- }
-
-/*
- * Remove a behavior descriptor from a behavior chain.
- */
-#define bhv_remove(bhp, bdp) \
- { \
- if ((bhp)->bh_first == (bdp)) { \
- /* \
- * Remove from front of chain. \
- * Atomic wrt oip's. \
- */ \
- (bhp)->bh_first = (bdp)->bd_next; \
- } else { \
- /* remove from non-front of chain */ \
- bhv_remove_not_first(bhp, bdp); \
- } \
- (bdp)->bd_vobj = NULL; \
- }
-
-/*
- * Behavior module prototypes.
- */
-extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
-extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
-extern bhv_desc_t * bhv_base(bhv_head_t *bhp);
-
-/* No bhv locking on Linux */
-#define bhv_base_unlocked bhv_base
-
-#endif /* __XFS_BEHAVIOR_H__ */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 94b5c5fe268..2e9b34b7344 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -53,6 +53,7 @@
#include "xfs_trans_space.h"
#include "xfs_buf_item.h"
#include "xfs_filestream.h"
+#include "xfs_vnodeops.h"
#ifdef DEBUG
@@ -248,7 +249,7 @@ xfs_bmap_local_to_extents(
* Else, *lastxp will be set to the index of the found
* entry; *gotp will contain the entry.
*/
-STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
+STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
xfs_bmap_search_extents(
xfs_inode_t *ip, /* incore inode pointer */
xfs_fileoff_t bno, /* block number searched for */
@@ -273,21 +274,6 @@ xfs_bmap_isaeof(
#ifdef XFS_BMAP_TRACE
/*
- * Add a bmap trace buffer entry. Base routine for the others.
- */
-STATIC void
-xfs_bmap_trace_addentry(
- int opcode, /* operation */
- const char *fname, /* function name */
- char *desc, /* operation description */
- xfs_inode_t *ip, /* incore inode pointer */
- xfs_extnum_t idx, /* index of entry(ies) */
- xfs_extnum_t cnt, /* count of entries, 1 or 2 */
- xfs_bmbt_rec_t *r1, /* first record */
- xfs_bmbt_rec_t *r2, /* second record or null */
- int whichfork); /* data or attr fork */
-
-/*
* Add bmap trace entry prior to a call to xfs_iext_remove.
*/
STATIC void
@@ -714,7 +700,7 @@ xfs_bmap_add_extent_delay_real(
{
xfs_btree_cur_t *cur; /* btree cursor */
int diff; /* temp value */
- xfs_bmbt_rec_t *ep; /* extent entry for idx */
+ xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
int error; /* error return value */
int i; /* temp state */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -1270,7 +1256,7 @@ xfs_bmap_add_extent_unwritten_real(
xfs_extdelta_t *delta) /* Change made to incore extents */
{
xfs_btree_cur_t *cur; /* btree cursor */
- xfs_bmbt_rec_t *ep; /* extent entry for idx */
+ xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
int error; /* error return value */
int i; /* temp state */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -1823,7 +1809,7 @@ xfs_bmap_add_extent_hole_delay(
xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd) /* OK to allocate reserved blocks */
{
- xfs_bmbt_rec_t *ep; /* extent record for idx */
+ xfs_bmbt_rec_host_t *ep; /* extent record for idx */
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_irec_t left; /* left neighbor extent entry */
xfs_filblks_t newlen=0; /* new indirect size */
@@ -2012,7 +1998,7 @@ xfs_bmap_add_extent_hole_real(
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
+ xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */
int error; /* error return value */
int i; /* temp state */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -3070,7 +3056,7 @@ xfs_bmap_del_extent(
xfs_fileoff_t del_endoff; /* first offset past del */
int delay; /* current block is delayed allocated */
int do_fx; /* free extent at end of routine */
- xfs_bmbt_rec_t *ep; /* current extent entry pointer */
+ xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */
int error; /* error return value */
int flags; /* inode logging flags */
xfs_bmbt_irec_t got; /* current extent entry */
@@ -3418,7 +3404,7 @@ xfs_bmap_extents_to_btree(
xfs_bmbt_rec_t *arp; /* child record pointer */
xfs_bmbt_block_t *block; /* btree root block */
xfs_btree_cur_t *cur; /* bmap btree cursor */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
int error; /* error return value */
xfs_extnum_t i, cnt; /* extent record index */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -3507,8 +3493,8 @@ xfs_bmap_extents_to_btree(
for (cnt = i = 0; i < nextents; i++) {
ep = xfs_iext_get_ext(ifp, i);
if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) {
- arp->l0 = INT_GET(ep->l0, ARCH_CONVERT);
- arp->l1 = INT_GET(ep->l1, ARCH_CONVERT);
+ arp->l0 = cpu_to_be64(ep->l0);
+ arp->l1 = cpu_to_be64(ep->l1);
arp++; cnt++;
}
}
@@ -3590,7 +3576,7 @@ xfs_bmap_local_to_extents(
if (ifp->if_bytes) {
xfs_alloc_arg_t args; /* allocation arguments */
xfs_buf_t *bp; /* buffer for extent block */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep;/* extent record pointer */
args.tp = tp;
args.mp = ip->i_mount;
@@ -3655,7 +3641,7 @@ done:
* entry (null if none). Else, *lastxp will be set to the index
* of the found entry; *gotp will contain the entry.
*/
-xfs_bmbt_rec_t * /* pointer to found extent entry */
+xfs_bmbt_rec_host_t * /* pointer to found extent entry */
xfs_bmap_search_multi_extents(
xfs_ifork_t *ifp, /* inode fork pointer */
xfs_fileoff_t bno, /* block number searched for */
@@ -3664,7 +3650,7 @@ xfs_bmap_search_multi_extents(
xfs_bmbt_irec_t *gotp, /* out: extent entry found */
xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
{
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
xfs_extnum_t lastx; /* last extent index */
/*
@@ -3706,7 +3692,7 @@ xfs_bmap_search_multi_extents(
* Else, *lastxp will be set to the index of the found
* entry; *gotp will contain the entry.
*/
-STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
+STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
xfs_bmap_search_extents(
xfs_inode_t *ip, /* incore inode pointer */
xfs_fileoff_t bno, /* block number searched for */
@@ -3717,7 +3703,7 @@ xfs_bmap_search_extents(
xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
{
xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
XFS_STATS_INC(xs_look_exlist);
ifp = XFS_IFORK_PTR(ip, fork);
@@ -3757,11 +3743,11 @@ xfs_bmap_trace_addentry(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* index of entry(ies) */
xfs_extnum_t cnt, /* count of entries, 1 or 2 */
- xfs_bmbt_rec_t *r1, /* first record */
- xfs_bmbt_rec_t *r2, /* second record or null */
+ xfs_bmbt_rec_host_t *r1, /* first record */
+ xfs_bmbt_rec_host_t *r2, /* second record or null */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t tr2;
+ xfs_bmbt_rec_host_t tr2;
ASSERT(cnt == 1 || cnt == 2);
ASSERT(r1 != NULL);
@@ -3842,8 +3828,8 @@ xfs_bmap_trace_insert(
xfs_bmbt_irec_t *r2, /* inserted record 2 or null */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t tr1; /* compressed record 1 */
- xfs_bmbt_rec_t tr2; /* compressed record 2 if needed */
+ xfs_bmbt_rec_host_t tr1; /* compressed record 1 */
+ xfs_bmbt_rec_host_t tr2; /* compressed record 2 if needed */
xfs_bmbt_set_all(&tr1, r1);
if (cnt == 2) {
@@ -4316,7 +4302,6 @@ xfs_bmap_first_unused(
xfs_fileoff_t *first_unused, /* unused block */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
int error; /* error return value */
int idx; /* extent record index */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4340,7 +4325,7 @@ xfs_bmap_first_unused(
lowest = *first_unused;
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
- ep = xfs_iext_get_ext(ifp, idx);
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
off = xfs_bmbt_get_startoff(ep);
/*
* See if the hole before this extent will work.
@@ -4371,7 +4356,7 @@ xfs_bmap_last_before(
{
xfs_fileoff_t bno; /* input file offset */
int eof; /* hit end of file */
- xfs_bmbt_rec_t *ep; /* pointer to last extent */
+ xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
int error; /* error return value */
xfs_bmbt_irec_t got; /* current extent value */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4417,7 +4402,7 @@ xfs_bmap_last_offset(
xfs_fileoff_t *last_block, /* last block */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t *ep; /* pointer to last extent */
+ xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
int error; /* error return value */
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_extnum_t nextents; /* number of extent entries */
@@ -4454,7 +4439,7 @@ xfs_bmap_one_block(
xfs_inode_t *ip, /* incore inode */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t *ep; /* ptr to fork's extent */
+ xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */
xfs_ifork_t *ifp; /* inode fork pointer */
int rval; /* return value */
xfs_bmbt_irec_t s; /* internal version of extent */
@@ -4549,7 +4534,7 @@ xfs_bmap_read_extents(
* Loop over all leaf nodes. Copy information to the extent records.
*/
for (;;) {
- xfs_bmbt_rec_t *frp, *trp;
+ xfs_bmbt_rec_t *frp;
xfs_fsblock_t nextbno;
xfs_extnum_t num_recs;
xfs_extnum_t start;
@@ -4581,9 +4566,9 @@ xfs_bmap_read_extents(
frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1);
start = i;
for (j = 0; j < num_recs; j++, i++, frp++) {
- trp = xfs_iext_get_ext(ifp, i);
- trp->l0 = INT_GET(frp->l0, ARCH_CONVERT);
- trp->l1 = INT_GET(frp->l1, ARCH_CONVERT);
+ xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i);
+ trp->l0 = be64_to_cpu(frp->l0);
+ trp->l1 = be64_to_cpu(frp->l1);
}
if (exntf == XFS_EXTFMT_NOSTATE) {
/*
@@ -4631,7 +4616,7 @@ xfs_bmap_trace_exlist(
xfs_extnum_t cnt, /* count of entries in the list */
int whichfork) /* data or attr fork */
{
- xfs_bmbt_rec_t *ep; /* current extent record */
+ xfs_bmbt_rec_host_t *ep; /* current extent record */
xfs_extnum_t idx; /* extent record index */
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_irec_t s; /* file extent record */
@@ -4727,7 +4712,7 @@ xfs_bmapi(
xfs_btree_cur_t *cur; /* bmap btree cursor */
xfs_fileoff_t end; /* end of mapped file region */
int eof; /* we've hit the end of extents */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
int error; /* error return */
xfs_bmbt_irec_t got; /* current file extent record */
xfs_ifork_t *ifp; /* inode fork pointer */
@@ -5378,7 +5363,7 @@ xfs_bunmapi(
xfs_btree_cur_t *cur; /* bmap btree cursor */
xfs_bmbt_irec_t del; /* extent being deleted */
int eof; /* is deleting at eof */
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
int error; /* error return value */
xfs_extnum_t extno; /* extent number in list */
xfs_bmbt_irec_t got; /* current extent record */
@@ -5743,11 +5728,44 @@ error0:
}
/*
+ * returns 1 for success, 0 if we failed to map the extent.
+ */
+STATIC int
+xfs_getbmapx_fix_eof_hole(
+ xfs_inode_t *ip, /* xfs incore inode pointer */
+ struct getbmap *out, /* output structure */
+ int prealloced, /* this is a file with
+ * preallocated data space */
+ __int64_t end, /* last block requested */
+ xfs_fsblock_t startblock)
+{
+ __int64_t fixlen;
+ xfs_mount_t *mp; /* file system mount point */
+
+ if (startblock == HOLESTARTBLOCK) {
+ mp = ip->i_mount;
+ out->bmv_block = -1;
+ fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, ip->i_size));
+ fixlen -= out->bmv_offset;
+ if (prealloced && out->bmv_offset + out->bmv_length == end) {
+ /* Came to hole at EOF. Trim it. */
+ if (fixlen <= 0)
+ return 0;
+ out->bmv_length = fixlen;
+ }
+ } else {
+ out->bmv_block = XFS_FSB_TO_DB(ip, startblock);
+ }
+
+ return 1;
+}
+
+/*
* Fcntl interface to xfs_bmapi.
*/
int /* error code */
xfs_getbmap(
- bhv_desc_t *bdp, /* XFS behavior descriptor*/
+ xfs_inode_t *ip,
struct getbmap *bmv, /* user bmap structure */
void __user *ap, /* pointer to user's array */
int interface) /* interface flags */
@@ -5756,7 +5774,6 @@ xfs_getbmap(
int error; /* return value */
__int64_t fixlen; /* length for -1 case */
int i; /* extent number */
- xfs_inode_t *ip; /* xfs incore inode pointer */
bhv_vnode_t *vp; /* corresponding vnode */
int lock; /* lock state */
xfs_bmbt_irec_t *map; /* buffer for user's data */
@@ -5774,8 +5791,7 @@ xfs_getbmap(
int bmapi_flags; /* flags for xfs_bmapi */
__int32_t oflags; /* getbmapx bmv_oflags field */
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
+ vp = XFS_ITOV(ip);
mp = ip->i_mount;
whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
@@ -5794,10 +5810,9 @@ xfs_getbmap(
* could misinterpret holes in a DMAPI file as true holes,
* when in fact they may represent offline user data.
*/
- if ( (interface & BMV_IF_NO_DMAPI_READ) == 0
- && DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)
- && whichfork == XFS_DATA_FORK) {
-
+ if ((interface & BMV_IF_NO_DMAPI_READ) == 0 &&
+ DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
+ whichfork == XFS_DATA_FORK) {
error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL);
if (error)
return XFS_ERROR(error);
@@ -5854,7 +5869,8 @@ xfs_getbmap(
if (whichfork == XFS_DATA_FORK &&
(ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
- error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
+ error = xfs_flush_pages(ip, (xfs_off_t)0,
+ -1, 0, FI_REMAPF);
}
ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@@ -5904,18 +5920,15 @@ xfs_getbmap(
out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
if (map[i].br_startblock == HOLESTARTBLOCK &&
- ((prealloced && out.bmv_offset + out.bmv_length == bmvend) ||
- whichfork == XFS_ATTR_FORK )) {
- /*
- * came to hole at end of file or the end of
- attribute fork
- */
+ whichfork == XFS_ATTR_FORK) {
+ /* came to the end of attribute fork */
goto unlock_and_return;
} else {
- out.bmv_block =
- (map[i].br_startblock == HOLESTARTBLOCK) ?
- -1 :
- XFS_FSB_TO_DB(ip, map[i].br_startblock);
+ if (!xfs_getbmapx_fix_eof_hole(ip, &out,
+ prealloced, bmvend,
+ map[i].br_startblock)) {
+ goto unlock_and_return;
+ }
/* return either getbmap/getbmapx structure. */
if (interface & BMV_IF_EXTENDED) {
@@ -5974,7 +5987,7 @@ xfs_bmap_isaeof(
{
int error; /* error return value */
xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_t *lastrec; /* extent record pointer */
+ xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */
xfs_extnum_t nextents; /* number of file extents */
xfs_bmbt_irec_t s; /* expanded extent record */
@@ -6018,7 +6031,7 @@ xfs_bmap_eof(
xfs_fsblock_t blockcount; /* extent block count */
int error; /* error return value */
xfs_ifork_t *ifp; /* inode fork pointer */
- xfs_bmbt_rec_t *lastrec; /* extent record pointer */
+ xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */
xfs_extnum_t nextents; /* number of file extents */
xfs_fileoff_t startoff; /* extent starting file offset */
@@ -6465,10 +6478,9 @@ xfs_bmap_count_leaves(
int *count)
{
int b;
- xfs_bmbt_rec_t *frp;
for (b = 0; b < numrecs; b++) {
- frp = xfs_iext_get_ext(ifp, idx + b);
+ xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b);
*count += xfs_bmbt_get_blockcount(frp);
}
return 0;
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 524b1c9d524..68267d75ff1 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -335,7 +335,7 @@ xfs_bunmapi(
*/
int /* error code */
xfs_getbmap(
- bhv_desc_t *bdp, /* XFS behavior descriptor*/
+ xfs_inode_t *ip,
struct getbmap *bmv, /* user bmap structure */
void __user *ap, /* pointer to user's array */
int iflags); /* interface flags */
@@ -378,7 +378,7 @@ xfs_check_nostate_extents(
* entry (null if none). Else, *lastxp will be set to the index
* of the found entry; *gotp will contain the entry.
*/
-xfs_bmbt_rec_t *
+xfs_bmbt_rec_host_t *
xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 89b891f51cf..32b49ec00fb 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -260,13 +260,14 @@ xfs_bmbt_trace_cursor(
char *s,
int line)
{
- xfs_bmbt_rec_t r;
+ xfs_bmbt_rec_host_t r;
xfs_bmbt_set_all(&r, &cur->bc_rec.b);
xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line,
(cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) |
cur->bc_private.b.allocated,
- INT_GET(r.l0, ARCH_CONVERT) >> 32, (int)INT_GET(r.l0, ARCH_CONVERT), INT_GET(r.l1, ARCH_CONVERT) >> 32, (int)INT_GET(r.l1, ARCH_CONVERT),
+ r.l0 >> 32, (int)r.l0,
+ r.l1 >> 32, (int)r.l1,
(unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1],
(unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3],
(cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1],
@@ -383,7 +384,7 @@ xfs_bmbt_delrec(
if (ptr < numrecs) {
memmove(&kp[ptr - 1], &kp[ptr],
(numrecs - ptr) * sizeof(*kp));
- memmove(&pp[ptr - 1], &pp[ptr], /* INT_: direct copy */
+ memmove(&pp[ptr - 1], &pp[ptr],
(numrecs - ptr) * sizeof(*pp));
xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
@@ -815,7 +816,7 @@ xfs_bmbt_insrec(
#endif
memmove(&kp[ptr], &kp[ptr - 1],
(numrecs - ptr + 1) * sizeof(*kp));
- memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */
+ memmove(&pp[ptr], &pp[ptr - 1],
(numrecs - ptr + 1) * sizeof(*pp));
#ifdef DEBUG
if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
@@ -1250,7 +1251,7 @@ xfs_bmbt_lshift(
return error;
}
#endif
- *lpp = *rpp; /* INT_: direct copy */
+ *lpp = *rpp;
xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs);
} else {
lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur);
@@ -1388,7 +1389,7 @@ xfs_bmbt_rshift(
}
#endif
*rkp = *lkp;
- *rpp = *lpp; /* INT_: direct copy */
+ *rpp = *lpp;
xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
} else {
@@ -1826,7 +1827,7 @@ __xfs_bmbt_get_all(
void
xfs_bmbt_get_all(
- xfs_bmbt_rec_t *r,
+ xfs_bmbt_rec_host_t *r,
xfs_bmbt_irec_t *s)
{
__xfs_bmbt_get_all(r->l0, r->l1, s);
@@ -1862,7 +1863,7 @@ xfs_bmbt_get_block(
*/
xfs_filblks_t
xfs_bmbt_get_blockcount(
- xfs_bmbt_rec_t *r)
+ xfs_bmbt_rec_host_t *r)
{
return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21));
}
@@ -1872,7 +1873,7 @@ xfs_bmbt_get_blockcount(
*/
xfs_fsblock_t
xfs_bmbt_get_startblock(
- xfs_bmbt_rec_t *r)
+ xfs_bmbt_rec_host_t *r)
{
#if XFS_BIG_BLKNOS
return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
@@ -1896,7 +1897,7 @@ xfs_bmbt_get_startblock(
*/
xfs_fileoff_t
xfs_bmbt_get_startoff(
- xfs_bmbt_rec_t *r)
+ xfs_bmbt_rec_host_t *r)
{
return ((xfs_fileoff_t)r->l0 &
XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
@@ -1904,7 +1905,7 @@ xfs_bmbt_get_startoff(
xfs_exntst_t
xfs_bmbt_get_state(
- xfs_bmbt_rec_t *r)
+ xfs_bmbt_rec_host_t *r)
{
int ext_flag;
@@ -1913,19 +1914,13 @@ xfs_bmbt_get_state(
ext_flag);
}
-#ifndef XFS_NATIVE_HOST
/* Endian flipping versions of the bmbt extraction functions */
void
xfs_bmbt_disk_get_all(
xfs_bmbt_rec_t *r,
xfs_bmbt_irec_t *s)
{
- __uint64_t l0, l1;
-
- l0 = INT_GET(r->l0, ARCH_CONVERT);
- l1 = INT_GET(r->l1, ARCH_CONVERT);
-
- __xfs_bmbt_get_all(l0, l1, s);
+ __xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s);
}
/*
@@ -1935,7 +1930,7 @@ xfs_filblks_t
xfs_bmbt_disk_get_blockcount(
xfs_bmbt_rec_t *r)
{
- return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21));
+ return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21));
}
/*
@@ -1945,11 +1940,9 @@ xfs_fileoff_t
xfs_bmbt_disk_get_startoff(
xfs_bmbt_rec_t *r)
{
- return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) &
+ return ((xfs_fileoff_t)be64_to_cpu(r->l0) &
XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
}
-#endif /* XFS_NATIVE_HOST */
-
/*
* Increment cursor by one record at the level.
@@ -2290,185 +2283,131 @@ xfs_bmbt_newroot(
}
/*
- * Set all the fields in a bmap extent record from the uncompressed form.
- */
-void
-xfs_bmbt_set_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s)
-{
- int extent_flag;
-
- ASSERT((s->br_state == XFS_EXT_NORM) ||
- (s->br_state == XFS_EXT_UNWRITTEN));
- extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
- ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
-#if XFS_BIG_BLKNOS
- ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
- r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(s->br_startblock)) {
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
- r->l1 = XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- } else {
- r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9);
- r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
- }
-#endif /* XFS_BIG_BLKNOS */
-}
-
-/*
* Set all the fields in a bmap extent record from the arguments.
*/
void
xfs_bmbt_set_allf(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t o,
- xfs_fsblock_t b,
- xfs_filblks_t c,
- xfs_exntst_t v)
+ xfs_bmbt_rec_host_t *r,
+ xfs_fileoff_t startoff,
+ xfs_fsblock_t startblock,
+ xfs_filblks_t blockcount,
+ xfs_exntst_t state)
{
- int extent_flag;
+ int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
+
+ ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
+ ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
+ ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
- ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
- extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
- ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
#if XFS_BIG_BLKNOS
- ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+ ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+
r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- ((xfs_bmbt_rec_base_t)b >> 43);
- r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
+ ((xfs_bmbt_rec_base_t)startoff << 9) |
+ ((xfs_bmbt_rec_base_t)startblock >> 43);
+ r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
+ ((xfs_bmbt_rec_base_t)blockcount &
(xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(b)) {
+ if (ISNULLSTARTBLOCK(startblock)) {
r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
+ ((xfs_bmbt_rec_base_t)startoff << 9) |
(xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
r->l1 = XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
+ ((xfs_bmbt_rec_base_t)startblock << 21) |
+ ((xfs_bmbt_rec_base_t)blockcount &
(xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
} else {
r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9);
- r->l1 = ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
+ ((xfs_bmbt_rec_base_t)startoff << 9);
+ r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
+ ((xfs_bmbt_rec_base_t)blockcount &
(xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
}
#endif /* XFS_BIG_BLKNOS */
}
-#ifndef XFS_NATIVE_HOST
/*
* Set all the fields in a bmap extent record from the uncompressed form.
*/
void
-xfs_bmbt_disk_set_all(
- xfs_bmbt_rec_t *r,
- xfs_bmbt_irec_t *s)
+xfs_bmbt_set_all(
+ xfs_bmbt_rec_host_t *r,
+ xfs_bmbt_irec_t *s)
{
- int extent_flag;
-
- ASSERT((s->br_state == XFS_EXT_NORM) ||
- (s->br_state == XFS_EXT_UNWRITTEN));
- extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
- ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
-#if XFS_BIG_BLKNOS
- ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- ((xfs_bmbt_rec_base_t)s->br_startblock >> 43));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
-#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(s->br_startblock)) {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
- INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
- } else {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)s->br_startoff << 9));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
- ((xfs_bmbt_rec_base_t)s->br_blockcount &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
- }
-#endif /* XFS_BIG_BLKNOS */
+ xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock,
+ s->br_blockcount, s->br_state);
}
+
/*
* Set all the fields in a disk format bmap extent record from the arguments.
*/
void
xfs_bmbt_disk_set_allf(
- xfs_bmbt_rec_t *r,
- xfs_fileoff_t o,
- xfs_fsblock_t b,
- xfs_filblks_t c,
- xfs_exntst_t v)
+ xfs_bmbt_rec_t *r,
+ xfs_fileoff_t startoff,
+ xfs_fsblock_t startblock,
+ xfs_filblks_t blockcount,
+ xfs_exntst_t state)
{
- int extent_flag;
+ int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
+
+ ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
+ ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
+ ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
- ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
- extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
- ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
- ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
#if XFS_BIG_BLKNOS
- ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- ((xfs_bmbt_rec_base_t)b >> 43));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+ ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
+
+ r->l0 = cpu_to_be64(
+ ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)startoff << 9) |
+ ((xfs_bmbt_rec_base_t)startblock >> 43));
+ r->l1 = cpu_to_be64(
+ ((xfs_bmbt_rec_base_t)startblock << 21) |
+ ((xfs_bmbt_rec_base_t)blockcount &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
#else /* !XFS_BIG_BLKNOS */
- if (ISNULLSTARTBLOCK(b)) {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9) |
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
- INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
- ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
+ if (ISNULLSTARTBLOCK(startblock)) {
+ r->l0 = cpu_to_be64(
+ ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)startoff << 9) |
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
+ r->l1 = cpu_to_be64(XFS_MASK64HI(11) |
+ ((xfs_bmbt_rec_base_t)startblock << 21) |
+ ((xfs_bmbt_rec_base_t)blockcount &
(xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
} else {
- INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
- ((xfs_bmbt_rec_base_t)o << 9));
- INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) |
- ((xfs_bmbt_rec_base_t)c &
- (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
+ r->l0 = cpu_to_be64(
+ ((xfs_bmbt_rec_base_t)extent_flag << 63) |
+ ((xfs_bmbt_rec_base_t)startoff << 9));
+ r->l1 = cpu_to_be64(
+ ((xfs_bmbt_rec_base_t)startblock << 21) |
+ ((xfs_bmbt_rec_base_t)blockcount &
+ (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
}
#endif /* XFS_BIG_BLKNOS */
}
-#endif /* XFS_NATIVE_HOST */
+
+/*
+ * Set all the fields in a bmap extent record from the uncompressed form.
+ */
+void
+xfs_bmbt_disk_set_all(
+ xfs_bmbt_rec_t *r,
+ xfs_bmbt_irec_t *s)
+{
+ xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock,
+ s->br_blockcount, s->br_state);
+}
/*
* Set the blockcount field in a bmap extent record.
*/
void
xfs_bmbt_set_blockcount(
- xfs_bmbt_rec_t *r,
+ xfs_bmbt_rec_host_t *r,
xfs_filblks_t v)
{
ASSERT((v & XFS_MASK64HI(43)) == 0);
@@ -2481,7 +2420,7 @@ xfs_bmbt_set_blockcount(
*/
void
xfs_bmbt_set_startblock(
- xfs_bmbt_rec_t *r,
+ xfs_bmbt_rec_host_t *r,
xfs_fsblock_t v)
{
#if XFS_BIG_BLKNOS
@@ -2509,7 +2448,7 @@ xfs_bmbt_set_startblock(
*/
void
xfs_bmbt_set_startoff(
- xfs_bmbt_rec_t *r,
+ xfs_bmbt_rec_host_t *r,
xfs_fileoff_t v)
{
ASSERT((v & XFS_MASK64HI(9)) == 0);
@@ -2523,7 +2462,7 @@ xfs_bmbt_set_startoff(
*/
void
xfs_bmbt_set_state(
- xfs_bmbt_rec_t *r,
+ xfs_bmbt_rec_host_t *r,
xfs_exntst_t v)
{
ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
@@ -2624,10 +2563,8 @@ xfs_check_nostate_extents(
xfs_extnum_t idx,
xfs_extnum_t num)
{
- xfs_bmbt_rec_t *ep;
-
for (; num > 0; num--, idx++) {
- ep = xfs_iext_get_ext(ifp, idx);
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
if ((ep->l0 >>
(64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
ASSERT(0);
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index a77b1b753d0..2d950e97591 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -35,45 +35,16 @@ typedef struct xfs_bmdr_block {
/*
* Bmap btree record and extent descriptor.
- * For 32-bit kernels,
- * l0:31 is an extent flag (value 1 indicates non-normal).
- * l0:0-30 and l1:9-31 are startoff.
- * l1:0-8, l2:0-31, and l3:21-31 are startblock.
- * l3:0-20 are blockcount.
- * For 64-bit kernels,
* l0:63 is an extent flag (value 1 indicates non-normal).
* l0:9-62 are startoff.
* l0:0-8 and l1:21-63 are startblock.
* l1:0-20 are blockcount.
*/
-
-#ifndef XFS_NATIVE_HOST
-
-#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
-#define BMBT_EXNTFLAG_BITOFF 0
#define BMBT_EXNTFLAG_BITLEN 1
-#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN)
#define BMBT_STARTOFF_BITLEN 54
-#define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN)
#define BMBT_STARTBLOCK_BITLEN 52
-#define BMBT_BLOCKCOUNT_BITOFF \
- (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN)
-#define BMBT_BLOCKCOUNT_BITLEN (BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF)
-
-#else
-
-#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
-#define BMBT_EXNTFLAG_BITOFF 63
-#define BMBT_EXNTFLAG_BITLEN 1
-#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN)
-#define BMBT_STARTOFF_BITLEN 54
-#define BMBT_STARTBLOCK_BITOFF 85 /* 128 - 43 (other 9 is in first word) */
-#define BMBT_STARTBLOCK_BITLEN 52
-#define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */
#define BMBT_BLOCKCOUNT_BITLEN 21
-#endif /* XFS_NATIVE_HOST */
-
#define BMBT_USE_64 1
@@ -83,12 +54,16 @@ typedef struct xfs_bmbt_rec_32
} xfs_bmbt_rec_32_t;
typedef struct xfs_bmbt_rec_64
{
- __uint64_t l0, l1;
+ __be64 l0, l1;
} xfs_bmbt_rec_64_t;
typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */
typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+typedef struct xfs_bmbt_rec_host {
+ __uint64_t l0, l1;
+} xfs_bmbt_rec_host_t;
+
/*
* Values and macros for delayed-allocation startblock fields.
*/
@@ -281,23 +256,17 @@ extern ktrace_t *xfs_bmbt_trace_buf;
extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
-extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
+extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
int, struct xfs_buf **bpp);
-extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r);
-extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r);
-extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r);
-extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r);
+extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r);
+extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
+extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r);
+extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r);
-#ifndef XFS_NATIVE_HOST
extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
-#else
-#define xfs_bmbt_disk_get_all(r, s) xfs_bmbt_get_all(r, s)
-#define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r)
-#define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r)
-#endif /* XFS_NATIVE_HOST */
extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *);
extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *);
@@ -315,22 +284,17 @@ extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t,
*/
extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
-extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
-extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
+extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
+extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o,
xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
-extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v);
-extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v);
-extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v);
-extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v);
+extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v);
+extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v);
+extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v);
+extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v);
-#ifndef XFS_NATIVE_HOST
extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
-#else
-#define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s)
-#define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v)
-#endif /* XFS_NATIVE_HOST */
extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int);
extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t,
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index b0667cb27d6..c8f2c2886fe 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -23,6 +23,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_buf_item.h"
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index f89196cb08d..d16c1b97107 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -89,7 +89,6 @@ struct xfs_mount_args {
#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */
#define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width
* allocation */
-#define XFSMNT_IHASHSIZE 0x20000000 /* inode hash table size */
#define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename
* symlink,mkdir,rmdir,mknod */
#define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index de35d18cc00..584f1ae85cd 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -42,6 +42,7 @@
#include "xfs_dfrag.h"
#include "xfs_error.h"
#include "xfs_rw.h"
+#include "xfs_vnodeops.h"
/*
* Syssgi interface for swapext
@@ -199,7 +200,8 @@ xfs_swap_extents(
if (VN_CACHED(tvp) != 0) {
xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
- error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
+ error = xfs_flushinval_pages(tip, 0, -1,
+ FI_REMAPF_LOCKED);
if (error)
goto error0;
}
@@ -265,7 +267,7 @@ xfs_swap_extents(
* fields change.
*/
- bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
+ xfs_tosspages(ip, 0, -1, FI_REMAPF);
tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
if ((error = xfs_trans_reserve(tp, 0,
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index fefd0116bac..dedd713574e 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -34,41 +34,41 @@ struct xfs_mount;
* because we only need the core part in the in-core inode.
*/
typedef struct xfs_timestamp {
- __int32_t t_sec; /* timestamp seconds */
- __int32_t t_nsec; /* timestamp nanoseconds */
+ __be32 t_sec; /* timestamp seconds */
+ __be32 t_nsec; /* timestamp nanoseconds */
} xfs_timestamp_t;
/*
* Note: Coordinate changes to this structure with the XFS_DI_* #defines
- * below and the offsets table in xfs_ialloc_log_di().
+ * below, the offsets table in xfs_ialloc_log_di() and struct xfs_icdinode
+ * in xfs_inode.h.
*/
-typedef struct xfs_dinode_core
-{
- __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
- __uint16_t di_mode; /* mode and type of file */
- __int8_t di_version; /* inode version */
- __int8_t di_format; /* format of di_c data */
- __uint16_t di_onlink; /* old number of links to file */
- __uint32_t di_uid; /* owner's user id */
- __uint32_t di_gid; /* owner's group id */
- __uint32_t di_nlink; /* number of links to file */
- __uint16_t di_projid; /* owner's project id */
- __uint8_t di_pad[8]; /* unused, zeroed space */
- __uint16_t di_flushiter; /* incremented on flush */
+typedef struct xfs_dinode_core {
+ __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */
+ __be16 di_mode; /* mode and type of file */
+ __u8 di_version; /* inode version */
+ __u8 di_format; /* format of di_c data */
+ __be16 di_onlink; /* old number of links to file */
+ __be32 di_uid; /* owner's user id */
+ __be32 di_gid; /* owner's group id */
+ __be32 di_nlink; /* number of links to file */
+ __be16 di_projid; /* owner's project id */
+ __u8 di_pad[8]; /* unused, zeroed space */
+ __be16 di_flushiter; /* incremented on flush */
xfs_timestamp_t di_atime; /* time last accessed */
xfs_timestamp_t di_mtime; /* time last modified */
xfs_timestamp_t di_ctime; /* time created/inode modified */
- xfs_fsize_t di_size; /* number of bytes in file */
- xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
- xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
- xfs_extnum_t di_nextents; /* number of extents in data fork */
- xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
- __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
- __int8_t di_aformat; /* format of attr fork's data */
- __uint32_t di_dmevmask; /* DMIG event mask */
- __uint16_t di_dmstate; /* DMIG state info */
- __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
- __uint32_t di_gen; /* generation number */
+ __be64 di_size; /* number of bytes in file */
+ __be64 di_nblocks; /* # of direct & btree blocks used */
+ __be32 di_extsize; /* basic/minimum extent size for file */
+ __be32 di_nextents; /* number of extents in data fork */
+ __be16 di_anextents; /* number of extents in attribute fork*/
+ __u8 di_forkoff; /* attr fork offs, <<3 for 64b align */
+ __s8 di_aformat; /* format of attr fork's data */
+ __be32 di_dmevmask; /* DMIG event mask */
+ __be16 di_dmstate; /* DMIG state info */
+ __be16 di_flags; /* random flags, XFS_DIFLAG_... */
+ __be32 di_gen; /* generation number */
} xfs_dinode_core_t;
#define DI_MAX_FLUSH 0xffff
@@ -81,13 +81,13 @@ typedef struct xfs_dinode
* sure to update the macros like XFS_LITINO below and
* XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h.
*/
- xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */
+ __be32 di_next_unlinked;/* agi unlinked list ptr */
union {
xfs_bmdr_block_t di_bmbt; /* btree root block */
xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
char di_c[1]; /* local contents */
- xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
+ __be32 di_dev; /* device for S_IFCHR/S_IFBLK */
uuid_t di_muuid; /* mount point value */
char di_symlink[1]; /* local symbolic link */
} di_u;
@@ -175,8 +175,7 @@ typedef enum xfs_dinode_fmt
#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0)
#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3))
-#define XFS_CFORK_BOFF_DISK(dcp) \
- ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
+#define XFS_CFORK_BOFF_DISK(dcp) ((int)((dcp)->di_forkoff << 3))
#define XFS_CFORK_DSIZE_DISK(dcp,mp) \
(XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp))
@@ -225,8 +224,8 @@ typedef enum xfs_dinode_fmt
#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \
((w) == XFS_DATA_FORK ? \
- INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \
- INT_GET((dcp)->di_anextents, ARCH_CONVERT))
+ be32_to_cpu((dcp)->di_nextents) : \
+ be16_to_cpu((dcp)->di_anextents))
#define XFS_CFORK_NEXTENTS(dcp,w) \
((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 29e091914df..b0f1ee8fcb9 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -43,8 +43,6 @@
#include "xfs_dir2_trace.h"
#include "xfs_error.h"
-static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
-static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
void
xfs_dir_mount(
@@ -293,47 +291,33 @@ xfs_dir_removename(
* Read a directory.
*/
int
-xfs_dir_getdents(
- xfs_trans_t *tp,
+xfs_readdir(
xfs_inode_t *dp,
- uio_t *uio, /* caller's buffer control */
- int *eofp) /* out: eof reached */
+ void *dirent,
+ size_t bufsize,
+ xfs_off_t *offset,
+ filldir_t filldir)
{
- int alignment; /* alignment required for ABI */
- xfs_dirent_t *dbp; /* malloc'ed buffer */
- xfs_dir2_put_t put; /* entry formatting routine */
int rval; /* return value */
int v; /* type-checking value */
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
+
+ if (XFS_FORCED_SHUTDOWN(dp->i_mount))
+ return XFS_ERROR(EIO);
+
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
XFS_STATS_INC(xs_dir_getdents);
- /*
- * If our caller has given us a single contiguous aligned memory buffer,
- * just work directly within that buffer. If it's in user memory,
- * lock it down first.
- */
- alignment = sizeof(xfs_off_t) - 1;
- if ((uio->uio_iovcnt == 1) &&
- (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
- ((uio->uio_iov[0].iov_len & alignment) == 0)) {
- dbp = NULL;
- put = xfs_dir2_put_dirent64_direct;
- } else {
- dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
- put = xfs_dir2_put_dirent64_uio;
- }
- *eofp = 0;
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
- rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
- else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
+ rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir);
+ else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
;
else if (v)
- rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
+ rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir);
else
- rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
- if (dbp != NULL)
- kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
+ rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset,
+ filldir);
return rval;
}
@@ -613,77 +597,6 @@ xfs_dir2_isleaf(
}
/*
- * Getdents put routine for 64-bit ABI, direct form.
- */
-static int
-xfs_dir2_put_dirent64_direct(
- xfs_dir2_put_args_t *pa)
-{
- xfs_dirent_t *idbp; /* dirent pointer */
- iovec_t *iovp; /* io vector */
- int namelen; /* entry name length */
- int reclen; /* entry total length */
- uio_t *uio; /* I/O control */
-
- namelen = pa->namelen;
- reclen = DIRENTSIZE(namelen);
- uio = pa->uio;
- /*
- * Won't fit in the remaining space.
- */
- if (reclen > uio->uio_resid) {
- pa->done = 0;
- return 0;
- }
- iovp = uio->uio_iov;
- idbp = (xfs_dirent_t *)iovp->iov_base;
- iovp->iov_base = (char *)idbp + reclen;
- iovp->iov_len -= reclen;
- uio->uio_resid -= reclen;
- idbp->d_reclen = reclen;
- idbp->d_ino = pa->ino;
- idbp->d_off = pa->cook;
- idbp->d_name[namelen] = '\0';
- pa->done = 1;
- memcpy(idbp->d_name, pa->name, namelen);
- return 0;
-}
-
-/*
- * Getdents put routine for 64-bit ABI, uio form.
- */
-static int
-xfs_dir2_put_dirent64_uio(
- xfs_dir2_put_args_t *pa)
-{
- xfs_dirent_t *idbp; /* dirent pointer */
- int namelen; /* entry name length */
- int reclen; /* entry total length */
- int rval; /* return value */
- uio_t *uio; /* I/O control */
-
- namelen = pa->namelen;
- reclen = DIRENTSIZE(namelen);
- uio = pa->uio;
- /*
- * Won't fit in the remaining space.
- */
- if (reclen > uio->uio_resid) {
- pa->done = 0;
- return 0;
- }
- idbp = pa->dbp;
- idbp->d_reclen = reclen;
- idbp->d_ino = pa->ino;
- idbp->d_off = pa->cook;
- idbp->d_name[namelen] = '\0';
- memcpy(idbp->d_name, pa->name, namelen);
- rval = xfs_uio_read((caddr_t)idbp, reclen, uio);
- pa->done = (rval == 0);
- return rval;
-}
-
-/*
* Remove the given block from the directory.
* This routine is used for data and free blocks, leaf/node are done
* by xfs_da_shrink_inode.
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 86560b6f794..b265197e74c 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -60,21 +60,6 @@ typedef __uint32_t xfs_dir2_db_t;
typedef xfs_off_t xfs_dir2_off_t;
/*
- * For getdents, argument struct for put routines.
- */
-typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa);
-typedef struct xfs_dir2_put_args {
- xfs_off_t cook; /* cookie of (next) entry */
- xfs_intino_t ino; /* inode number */
- xfs_dirent_t *dbp; /* buffer pointer */
- char *name; /* directory entry name */
- int namelen; /* length of name */
- int done; /* output: set if value was stored */
- xfs_dir2_put_t put; /* put function ptr (i/o) */
- struct uio *uio; /* uio control structure */
-} xfs_dir2_put_args_t;
-
-/*
* Generic directory interface routines
*/
extern void xfs_dir_startup(void);
@@ -92,8 +77,6 @@ extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen, xfs_ino_t ino,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist, xfs_extlen_t tot);
-extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- uio_t *uio, int *eofp);
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen, xfs_ino_t inum,
xfs_fsblock_t *first,
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e4df1aaae2a..c171767e242 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@@ -432,12 +433,10 @@ xfs_dir2_block_addname(
*/
int /* error */
xfs_dir2_block_getdents(
- xfs_trans_t *tp, /* transaction (NULL) */
xfs_inode_t *dp, /* incore inode */
- uio_t *uio, /* caller's buffer control */
- int *eofp, /* eof reached? (out) */
- xfs_dirent_t *dbp, /* caller's buffer */
- xfs_dir2_put_t put) /* abi's formatting function */
+ void *dirent,
+ xfs_off_t *offset,
+ filldir_t filldir)
{
xfs_dir2_block_t *block; /* directory block structure */
xfs_dabuf_t *bp; /* buffer for block */
@@ -447,31 +446,32 @@ xfs_dir2_block_getdents(
char *endptr; /* end of the data entries */
int error; /* error return value */
xfs_mount_t *mp; /* filesystem mount point */
- xfs_dir2_put_args_t p; /* arg package for put rtn */
char *ptr; /* current data entry */
int wantoff; /* starting block offset */
+ xfs_ino_t ino;
+ xfs_off_t cook;
mp = dp->i_mount;
/*
* If the block number in the offset is out of range, we're done.
*/
- if (xfs_dir2_dataptr_to_db(mp, uio->uio_offset) > mp->m_dirdatablk) {
- *eofp = 1;
+ if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) {
return 0;
}
/*
* Can't read the block, give up, else get dabuf in bp.
*/
- if ((error =
- xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) {
+ error = xfs_da_read_buf(NULL, dp, mp->m_dirdatablk, -1,
+ &bp, XFS_DATA_FORK);
+ if (error)
return error;
- }
+
ASSERT(bp != NULL);
/*
* Extract the byte offset we start at from the seek pointer.
* We'll skip entries before this.
*/
- wantoff = xfs_dir2_dataptr_to_off(mp, uio->uio_offset);
+ wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
block = bp->data;
xfs_dir2_data_check(dp, bp);
/*
@@ -480,9 +480,7 @@ xfs_dir2_block_getdents(
btp = xfs_dir2_block_tail_p(mp, block);
ptr = (char *)block->u;
endptr = (char *)xfs_dir2_block_leaf_p(btp);
- p.dbp = dbp;
- p.put = put;
- p.uio = uio;
+
/*
* Loop over the data portion of the block.
* Each object is a real entry (dep) or an unused one (dup).
@@ -508,33 +506,24 @@ xfs_dir2_block_getdents(
*/
if ((char *)dep - (char *)block < wantoff)
continue;
- /*
- * Set up argument structure for put routine.
- */
- p.namelen = dep->namelen;
- p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
+ cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
ptr - (char *)block);
- p.ino = be64_to_cpu(dep->inumber);
+ ino = be64_to_cpu(dep->inumber);
#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
+ ino += mp->m_inoadd;
#endif
- p.name = (char *)dep->name;
-
- /*
- * Put the entry in the caller's buffer.
- */
- error = p.put(&p);
/*
* If it didn't fit, set the final offset to here & return.
*/
- if (!p.done) {
- uio->uio_offset =
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
+ if (filldir(dirent, dep->name, dep->namelen, cook,
+ ino, DT_UNKNOWN)) {
+ *offset = xfs_dir2_db_off_to_dataptr(mp,
+ mp->m_dirdatablk,
(char *)dep - (char *)block);
- xfs_da_brelse(tp, bp);
- return error;
+ xfs_da_brelse(NULL, bp);
+ return 0;
}
}
@@ -542,13 +531,8 @@ xfs_dir2_block_getdents(
* Reached the end of the block.
* Set the offset to a non-existent block 1 and return.
*/
- *eofp = 1;
-
- uio->uio_offset =
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
-
- xfs_da_brelse(tp, bp);
-
+ *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
+ xfs_da_brelse(NULL, bp);
return 0;
}
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
index e7c2606161e..10e68967638 100644
--- a/fs/xfs/xfs_dir2_block.h
+++ b/fs/xfs/xfs_dir2_block.h
@@ -80,9 +80,8 @@ xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
* Function declarations.
*/
extern int xfs_dir2_block_addname(struct xfs_da_args *args);
-extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir2_put_t put);
+extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
+ xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
extern int xfs_dir2_block_removename(struct xfs_da_args *args);
extern int xfs_dir2_block_replace(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 7ebe295bd6d..d2452699e9b 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 1b73c9ad646..e7c12fa1303 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -749,12 +749,11 @@ xfs_dir2_leaf_compact_x1(
*/
int /* error */
xfs_dir2_leaf_getdents(
- xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
- uio_t *uio, /* I/O control & vectors */
- int *eofp, /* out: reached end of dir */
- xfs_dirent_t *dbp, /* caller's buffer */
- xfs_dir2_put_t put) /* ABI formatting routine */
+ void *dirent,
+ size_t bufsize,
+ xfs_off_t *offset,
+ filldir_t filldir)
{
xfs_dabuf_t *bp; /* data block buffer */
int byteoff; /* offset in current block */
@@ -763,7 +762,6 @@ xfs_dir2_leaf_getdents(
xfs_dir2_data_t *data; /* data block structure */
xfs_dir2_data_entry_t *dep; /* data entry */
xfs_dir2_data_unused_t *dup; /* unused entry */
- int eof; /* reached end of directory */
int error = 0; /* error return value */
int i; /* temporary loop index */
int j; /* temporary loop index */
@@ -776,46 +774,38 @@ xfs_dir2_leaf_getdents(
xfs_mount_t *mp; /* filesystem mount point */
xfs_dir2_off_t newoff; /* new curoff after new blk */
int nmap; /* mappings to ask xfs_bmapi */
- xfs_dir2_put_args_t *p; /* formatting arg bundle */
char *ptr = NULL; /* pointer to current data */
int ra_current; /* number of read-ahead blks */
int ra_index; /* *map index for read-ahead */
int ra_offset; /* map entry offset for ra */
int ra_want; /* readahead count wanted */
+ xfs_ino_t ino;
/*
* If the offset is at or past the largest allowed value,
- * give up right away, return eof.
+ * give up right away.
*/
- if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) {
- *eofp = 1;
+ if (*offset >= XFS_DIR2_MAX_DATAPTR)
return 0;
- }
+
mp = dp->i_mount;
- /*
- * Setup formatting arguments.
- */
- p = kmem_alloc(sizeof(*p), KM_SLEEP);
- p->dbp = dbp;
- p->put = put;
- p->uio = uio;
+
/*
* Set up to bmap a number of blocks based on the caller's
* buffer size, the directory block size, and the filesystem
* block size.
*/
- map_size =
- howmany(uio->uio_resid + mp->m_dirblksize,
- mp->m_sb.sb_blocksize);
+ map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize);
map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
bp = NULL;
- eof = 1;
+
/*
* Inside the loop we keep the main offset value as a byte offset
* in the directory file.
*/
- curoff = xfs_dir2_dataptr_to_byte(mp, uio->uio_offset);
+ curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
+
/*
* Force this conversion through db so we truncate the offset
* down to get the start of the data block.
@@ -836,7 +826,7 @@ xfs_dir2_leaf_getdents(
* take it out of the mapping.
*/
if (bp) {
- xfs_da_brelse(tp, bp);
+ xfs_da_brelse(NULL, bp);
bp = NULL;
map_blocks -= mp->m_dirblkfsbs;
/*
@@ -862,8 +852,9 @@ xfs_dir2_leaf_getdents(
/*
* Recalculate the readahead blocks wanted.
*/
- ra_want = howmany(uio->uio_resid + mp->m_dirblksize,
+ ra_want = howmany(bufsize + mp->m_dirblksize,
mp->m_sb.sb_blocksize) - 1;
+
/*
* If we don't have as many as we want, and we haven't
* run out of data blocks, get some more mappings.
@@ -876,7 +867,7 @@ xfs_dir2_leaf_getdents(
* we already have in the table.
*/
nmap = map_size - map_valid;
- error = xfs_bmapi(tp, dp,
+ error = xfs_bmapi(NULL, dp,
map_off,
xfs_dir2_byte_to_da(mp,
XFS_DIR2_LEAF_OFFSET) - map_off,
@@ -939,7 +930,7 @@ xfs_dir2_leaf_getdents(
* mapping.
*/
curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
- error = xfs_da_read_buf(tp, dp, map->br_startoff,
+ error = xfs_da_read_buf(NULL, dp, map->br_startoff,
map->br_blockcount >= mp->m_dirblkfsbs ?
XFS_FSB_TO_DADDR(mp, map->br_startblock) :
-1,
@@ -982,7 +973,7 @@ xfs_dir2_leaf_getdents(
* is a very rare case.
*/
else if (i > ra_current) {
- (void)xfs_da_reada_buf(tp, dp,
+ (void)xfs_da_reada_buf(NULL, dp,
map[ra_index].br_startoff +
ra_offset, XFS_DATA_FORK);
ra_current = i;
@@ -1089,46 +1080,39 @@ xfs_dir2_leaf_getdents(
*/
dep = (xfs_dir2_data_entry_t *)ptr;
- p->namelen = dep->namelen;
-
- length = xfs_dir2_data_entsize(p->namelen);
-
- p->cook = xfs_dir2_byte_to_dataptr(mp, curoff + length);
+ length = xfs_dir2_data_entsize(dep->namelen);
- p->ino = be64_to_cpu(dep->inumber);
+ ino = be64_to_cpu(dep->inumber);
#if XFS_BIG_INUMS
- p->ino += mp->m_inoadd;
+ ino += mp->m_inoadd;
#endif
- p->name = (char *)dep->name;
-
- error = p->put(p);
/*
* Won't fit. Return to caller.
*/
- if (!p->done) {
- eof = 0;
+ if (filldir(dirent, dep->name, dep->namelen,
+ xfs_dir2_byte_to_dataptr(mp, curoff + length),
+ ino, DT_UNKNOWN))
break;
- }
+
/*
* Advance to next entry in the block.
*/
ptr += length;
curoff += length;
+ bufsize -= length;
}
/*
* All done. Set output offset value to current offset.
*/
- *eofp = eof;
if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
- uio->uio_offset = XFS_DIR2_MAX_DATAPTR;
+ *offset = XFS_DIR2_MAX_DATAPTR;
else
- uio->uio_offset = xfs_dir2_byte_to_dataptr(mp, curoff);
+ *offset = xfs_dir2_byte_to_dataptr(mp, curoff);
kmem_free(map, map_size * sizeof(*map));
- kmem_free(p, sizeof(*p));
if (bp)
- xfs_da_brelse(tp, bp);
+ xfs_da_brelse(NULL, bp);
return error;
}
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index 70c97f3f815..6c9539f0698 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -232,9 +232,9 @@ extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
int *lowstalep, int *highstalep,
int *lowlogp, int *highlogp);
-extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
- struct uio *uio, int *eofp,
- struct xfs_dirent *dbp, xfs_dir2_put_t put);
+extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
+ size_t bufsize, xfs_off_t *offset,
+ filldir_t filldir);
extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
struct xfs_dabuf **bpp, int magic);
extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 91c61d9632c..eb18e399e83 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 38fc4f22b76..182c70315ad 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@@ -695,19 +696,18 @@ xfs_dir2_sf_create(
int /* error */
xfs_dir2_sf_getdents(
xfs_inode_t *dp, /* incore directory inode */
- uio_t *uio, /* caller's buffer control */
- int *eofp, /* eof reached? (out) */
- xfs_dirent_t *dbp, /* caller's buffer */
- xfs_dir2_put_t put) /* abi's formatting function */
+ void *dirent,
+ xfs_off_t *offset,
+ filldir_t filldir)
{
- int error; /* error return value */
int i; /* shortform entry number */
xfs_mount_t *mp; /* filesystem mount point */
xfs_dir2_dataptr_t off; /* current entry's offset */
- xfs_dir2_put_args_t p; /* arg package for put rtn */
xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
xfs_dir2_sf_t *sfp; /* shortform structure */
- xfs_off_t dir_offset;
+ xfs_dir2_dataptr_t dot_offset;
+ xfs_dir2_dataptr_t dotdot_offset;
+ xfs_ino_t ino;
mp = dp->i_mount;
@@ -720,8 +720,6 @@ xfs_dir2_sf_getdents(
return XFS_ERROR(EIO);
}
- dir_offset = uio->uio_offset;
-
ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
ASSERT(dp->i_df.if_u1.if_data != NULL);
@@ -732,108 +730,78 @@ xfs_dir2_sf_getdents(
/*
* If the block number in the offset is out of range, we're done.
*/
- if (xfs_dir2_dataptr_to_db(mp, dir_offset) > mp->m_dirdatablk) {
- *eofp = 1;
+ if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
return 0;
- }
/*
- * Set up putargs structure.
+ * Precalculate offsets for . and .. as we will always need them.
+ *
+ * XXX(hch): the second argument is sometimes 0 and sometimes
+ * mp->m_dirdatablk.
*/
- p.dbp = dbp;
- p.put = put;
- p.uio = uio;
+ dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
+ XFS_DIR2_DATA_DOT_OFFSET);
+ dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
+ XFS_DIR2_DATA_DOTDOT_OFFSET);
+
/*
* Put . entry unless we're starting past it.
*/
- if (dir_offset <=
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOT_OFFSET)) {
- p.cook = xfs_dir2_db_off_to_dataptr(mp, 0,
- XFS_DIR2_DATA_DOTDOT_OFFSET);
- p.ino = dp->i_ino;
+ if (*offset <= dot_offset) {
+ ino = dp->i_ino;
#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
+ ino += mp->m_inoadd;
#endif
- p.name = ".";
- p.namelen = 1;
-
- error = p.put(&p);
-
- if (!p.done) {
- uio->uio_offset =
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOT_OFFSET);
- return error;
+ if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) {
+ *offset = dot_offset;
+ return 0;
}
}
/*
* Put .. entry unless we're starting past it.
*/
- if (dir_offset <=
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOTDOT_OFFSET)) {
- p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_FIRST_OFFSET);
- p.ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
+ if (*offset <= dotdot_offset) {
+ off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
+ XFS_DIR2_DATA_FIRST_OFFSET);
+ ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
+ ino += mp->m_inoadd;
#endif
- p.name = "..";
- p.namelen = 2;
-
- error = p.put(&p);
-
- if (!p.done) {
- uio->uio_offset =
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
- XFS_DIR2_DATA_DOTDOT_OFFSET);
- return error;
+ if (filldir(dirent, "..", 2, off, ino, DT_DIR)) {
+ *offset = dotdot_offset;
+ return 0;
}
}
/*
* Loop while there are more entries and put'ing works.
*/
- for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
- i < sfp->hdr.count;
- i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
-
+ sfep = xfs_dir2_sf_firstentry(sfp);
+ for (i = 0; i < sfp->hdr.count; i++) {
off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
xfs_dir2_sf_get_offset(sfep));
- if (dir_offset > off)
+ if (*offset > off) {
+ sfep = xfs_dir2_sf_nextentry(sfp, sfep);
continue;
+ }
- p.namelen = sfep->namelen;
-
- p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
- xfs_dir2_sf_get_offset(sfep) +
- xfs_dir2_data_entsize(p.namelen));
-
- p.ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
+ ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
#if XFS_BIG_INUMS
- p.ino += mp->m_inoadd;
+ ino += mp->m_inoadd;
#endif
- p.name = (char *)sfep->name;
-
- error = p.put(&p);
- if (!p.done) {
- uio->uio_offset = off;
- return error;
+ if (filldir(dirent, sfep->name, sfep->namelen,
+ off + xfs_dir2_data_entsize(sfep->namelen),
+ ino, DT_UNKNOWN)) {
+ *offset = off;
+ return 0;
}
+ sfep = xfs_dir2_sf_nextentry(sfp, sfep);
}
- /*
- * They all fit.
- */
- *eofp = 1;
-
- uio->uio_offset =
- xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
-
+ *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
return 0;
}
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
index 11e503209af..005629d702d 100644
--- a/fs/xfs/xfs_dir2_sf.h
+++ b/fs/xfs/xfs_dir2_sf.h
@@ -169,9 +169,8 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
int size, xfs_dir2_sf_hdr_t *sfhp);
extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
-extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio,
- int *eofp, struct xfs_dirent *dbp,
- xfs_dir2_put_t put);
+extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
+ xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index adc3d251240..f71784ab6a6 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -67,17 +67,15 @@ typedef enum {
#define HAVE_DM_RIGHT_T
/* Defines for determining if an event message should be sent. */
-#define DM_EVENT_ENABLED(vfsp, ip, event) ( \
- unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
+#ifdef HAVE_DMAPI
+#define DM_EVENT_ENABLED(ip, event) ( \
+ unlikely ((ip)->i_mount->m_flags & XFS_MOUNT_DMAPI) && \
( ((ip)->i_d.di_dmevmask & (1 << event)) || \
((ip)->i_mount->m_dmevmask & (1 << event)) ) \
)
-
-#define DM_EVENT_ENABLED_IO(vfsp, io, event) ( \
- unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
- ( ((io)->io_dmevmask & (1 << event)) || \
- ((io)->io_mount->m_dmevmask & (1 << event)) ) \
- )
+#else
+#define DM_EVENT_ENABLED(ip, event) (0)
+#endif
#define DM_XFS_VALID_FS_EVENTS ( \
(1 << DM_EVENT_PREUNMOUNT) | \
@@ -170,7 +168,4 @@ typedef enum {
DM_FLAGS_NDELAY : 0)
#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
-
-extern struct bhv_module_vfsops xfs_dmops;
-
#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 1e4a35ddf7f..6cd5704258a 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -19,18 +19,51 @@
#include "xfs_fs.h"
#include "xfs_types.h"
#include "xfs_log.h"
-#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_dmapi.h"
+#include "xfs_inum.h"
+#include "xfs_ag.h"
#include "xfs_mount.h"
+#include "xfs_clnt.h"
+
-xfs_dmops_t xfs_dmcore_stub = {
+static struct xfs_dmops xfs_dmcore_stub = {
.xfs_send_data = (xfs_send_data_t)fs_nosys,
.xfs_send_mmap = (xfs_send_mmap_t)fs_noerr,
.xfs_send_destroy = (xfs_send_destroy_t)fs_nosys,
.xfs_send_namesp = (xfs_send_namesp_t)fs_nosys,
- .xfs_send_unmount = (xfs_send_unmount_t)fs_noval,
+ .xfs_send_mount = (xfs_send_mount_t)fs_nosys,
+ .xfs_send_unmount = (xfs_send_unmount_t)fs_noerr,
};
+
+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;
+ }
+
+ 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_error.c b/fs/xfs/xfs_error.c
index 8c433163133..a4634d94e56 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@@ -132,10 +133,14 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
}
int
-xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud)
+xfs_errortag_clearall(xfs_mount_t *mp, int loud)
{
- int i;
+ int64_t fsid;
int cleared = 0;
+ int i;
+
+ memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
+
for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
@@ -154,20 +159,10 @@ xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud)
if (loud || cleared)
cmn_err(CE_WARN,
"Cleared all XFS error tags for filesystem \"%s\"",
- fsname);
+ mp->m_fsname);
return 0;
}
-
-int
-xfs_errortag_clearall(xfs_mount_t *mp)
-{
- int64_t fsid;
-
- memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
-
- return xfs_errortag_clearall_umount(fsid, mp->m_fsname, 1);
-}
#endif /* DEBUG || INDUCE_IO_ERROR */
static void
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 5599ada456a..10e9d9619ae 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -144,12 +144,11 @@ extern void xfs_error_test_init(void);
#endif /* __ANSI_CPP__ */
extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
-extern int xfs_errortag_clearall(xfs_mount_t *mp);
-extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
+extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud);
#else
#define XFS_TEST_ERROR(expr, mp, tag, rf) (expr)
#define xfs_errortag_add(tag, mp) (ENOSYS)
-#define xfs_errortag_clearall(mp) (ENOSYS)
+#define xfs_errortag_clearall(mp, loud) (ENOSYS)
#endif /* (DEBUG || INDUCE_IO_ERROR) */
/*
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 3b14427ee12..f938a51be81 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -23,6 +23,7 @@
#include "xfs_trans.h"
#include "xfs_buf_item.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 432e82347ed..c92d5b82102 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -136,7 +136,6 @@ xfs_growfs_data_private(
xfs_rfsblock_t nfree;
xfs_agnumber_t oagcount;
int pct;
- xfs_sb_t *sbp;
xfs_trans_t *tp;
nb = in->newblocks;
@@ -175,7 +174,7 @@ xfs_growfs_data_private(
memset(&mp->m_perag[oagcount], 0,
(nagcount - oagcount) * sizeof(xfs_perag_t));
mp->m_flags |= XFS_MOUNT_32BITINODES;
- nagimax = xfs_initialize_perag(XFS_MTOVFS(mp), mp, nagcount);
+ nagimax = xfs_initialize_perag(mp, nagcount);
up_write(&mp->m_peraglock);
}
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
@@ -377,8 +376,7 @@ xfs_growfs_data_private(
error, agno);
break;
}
- sbp = XFS_BUF_TO_SBP(bp);
- xfs_xlatesb(sbp, &mp->m_sb, -1, XFS_SB_ALL_BITS);
+ xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS);
/*
* If we get an error writing out the alternate superblocks,
* just issue a warning and continue. The real work is
@@ -435,10 +433,10 @@ xfs_growfs_data(
xfs_growfs_data_t *in)
{
int error;
- if (!cpsema(&mp->m_growlock))
+ if (!mutex_trylock(&mp->m_growlock))
return XFS_ERROR(EWOULDBLOCK);
error = xfs_growfs_data_private(mp, in);
- vsema(&mp->m_growlock);
+ mutex_unlock(&mp->m_growlock);
return error;
}
@@ -448,10 +446,10 @@ xfs_growfs_log(
xfs_growfs_log_t *in)
{
int error;
- if (!cpsema(&mp->m_growlock))
+ if (!mutex_trylock(&mp->m_growlock))
return XFS_ERROR(EWOULDBLOCK);
error = xfs_growfs_log_private(mp, in);
- vsema(&mp->m_growlock);
+ mutex_unlock(&mp->m_growlock);
return error;
}
@@ -628,8 +626,7 @@ xfs_fs_goingdown(
{
switch (inflags) {
case XFS_FSOP_GOING_FLAGS_DEFAULT: {
- struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
- struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
+ struct super_block *sb = freeze_bdev(mp->m_super->s_bdev);
if (sb && !IS_ERR(sb)) {
xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index f943368c9b9..1409c2d61c1 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -293,9 +293,9 @@ xfs_ialloc_ag_alloc(
xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
for (i = 0; i < ninodes; i++) {
free = XFS_MAKE_IPTR(args.mp, fbuf, i);
- INT_SET(free->di_core.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC);
- INT_SET(free->di_core.di_version, ARCH_CONVERT, version);
- INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
+ free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
+ free->di_core.di_version = version;
+ free->di_next_unlinked = cpu_to_be32(NULLAGINO);
xfs_ialloc_log_di(tp, fbuf, i,
XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED);
}
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index 97f4040931c..4e30ec1d13b 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -30,14 +30,9 @@ struct xfs_trans;
#define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks
/*
- * For small block file systems, move inodes in clusters of this size.
- * When we don't have a lot of memory, however, we go a bit smaller
- * to reduce the number of AGI and ialloc btree blocks we need to keep
- * around for xfs_dilocate(). We choose which one to use in
- * xfs_mount_int().
+ * Move inodes in clusters of this size.
*/
#define XFS_INODE_BIG_CLUSTER_SIZE 8192
-#define XFS_INODE_SMALL_CLUSTER_SIZE 4096
#define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size
/*
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 114433a22ba..488836e204a 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -40,131 +40,13 @@
#include "xfs_utils.h"
/*
- * Initialize the inode hash table for the newly mounted file system.
- * Choose an initial table size based on user specified value, else
- * use a simple algorithm using the maximum number of inodes as an
- * indicator for table size, and clamp it between one and some large
- * number of pages.
- */
-void
-xfs_ihash_init(xfs_mount_t *mp)
-{
- __uint64_t icount;
- uint i;
-
- if (!mp->m_ihsize) {
- icount = mp->m_maxicount ? mp->m_maxicount :
- (mp->m_sb.sb_dblocks << mp->m_sb.sb_inopblog);
- mp->m_ihsize = 1 << max_t(uint, 8,
- (xfs_highbit64(icount) + 1) / 2);
- mp->m_ihsize = min_t(uint, mp->m_ihsize,
- (64 * NBPP) / sizeof(xfs_ihash_t));
- }
-
- mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize,
- NBPC * sizeof(xfs_ihash_t),
- mp->m_ihsize * sizeof(xfs_ihash_t),
- KM_SLEEP | KM_MAYFAIL | KM_LARGE);
- mp->m_ihsize /= sizeof(xfs_ihash_t);
- for (i = 0; i < mp->m_ihsize; i++)
- rwlock_init(&(mp->m_ihash[i].ih_lock));
-}
-
-/*
- * Free up structures allocated by xfs_ihash_init, at unmount time.
- */
-void
-xfs_ihash_free(xfs_mount_t *mp)
-{
- kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t));
- mp->m_ihash = NULL;
-}
-
-/*
- * Initialize the inode cluster hash table for the newly mounted file system.
- * Its size is derived from the ihash table size.
- */
-void
-xfs_chash_init(xfs_mount_t *mp)
-{
- uint i;
-
- mp->m_chsize = max_t(uint, 1, mp->m_ihsize /
- (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog));
- mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
- mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
- * sizeof(xfs_chash_t),
- KM_SLEEP | KM_LARGE);
- for (i = 0; i < mp->m_chsize; i++) {
- spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
- }
-}
-
-/*
- * Free up structures allocated by xfs_chash_init, at unmount time.
- */
-void
-xfs_chash_free(xfs_mount_t *mp)
-{
- int i;
-
- for (i = 0; i < mp->m_chsize; i++) {
- spinlock_destroy(&mp->m_chash[i].ch_lock);
- }
-
- kmem_free(mp->m_chash, mp->m_chsize*sizeof(xfs_chash_t));
- mp->m_chash = NULL;
-}
-
-/*
- * Try to move an inode to the front of its hash list if possible
- * (and if its not there already). Called right after obtaining
- * the list version number and then dropping the read_lock on the
- * hash list in question (which is done right after looking up the
- * inode in question...).
- */
-STATIC void
-xfs_ihash_promote(
- xfs_ihash_t *ih,
- xfs_inode_t *ip,
- ulong version)
-{
- xfs_inode_t *iq;
-
- if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) {
- if (likely(version == ih->ih_version)) {
- /* remove from list */
- if ((iq = ip->i_next)) {
- iq->i_prevp = ip->i_prevp;
- }
- *ip->i_prevp = iq;
-
- /* insert at list head */
- iq = ih->ih_next;
- iq->i_prevp = &ip->i_next;
- ip->i_next = iq;
- ip->i_prevp = &ih->ih_next;
- ih->ih_next = ip;
- }
- write_unlock(&ih->ih_lock);
- }
-}
-
-/*
* Look up an inode by number in the given file system.
- * The inode is looked up in the hash table for the file system
- * represented by the mount point parameter mp. Each bucket of
- * the hash table is guarded by an individual semaphore.
- *
- * If the inode is found in the hash table, its corresponding vnode
- * is obtained with a call to vn_get(). This call takes care of
- * coordination with the reclamation of the inode and vnode. Note
- * that the vmap structure is filled in while holding the hash lock.
- * This gives us the state of the inode/vnode when we found it and
- * is used for coordination in vn_get().
+ * The inode is looked up in the cache held in each AG.
+ * If the inode is found in the cache, attach it to the provided
+ * vnode.
*
- * If it is not in core, read it in from the file system's device and
- * add the inode into the hash table.
+ * If it is not in core, read it in from the file system's device,
+ * add it to the cache and attach the provided vnode.
*
* The inode is locked according to the value of the lock_flags parameter.
* This flag parameter indicates how and if the inode's IO lock and inode lock
@@ -192,274 +74,241 @@ xfs_iget_core(
xfs_inode_t **ipp,
xfs_daddr_t bno)
{
- xfs_ihash_t *ih;
xfs_inode_t *ip;
xfs_inode_t *iq;
bhv_vnode_t *inode_vp;
- ulong version;
int error;
- /* REFERENCED */
- xfs_chash_t *ch;
- xfs_chashlist_t *chl, *chlnew;
- SPLDECL(s);
+ xfs_icluster_t *icl, *new_icl = NULL;
+ unsigned long first_index, mask;
+ xfs_perag_t *pag;
+ xfs_agino_t agino;
+
+ /* the radix tree exists only in inode capable AGs */
+ if (XFS_INO_TO_AGNO(mp, ino) >= mp->m_maxagi)
+ return EINVAL;
+
+ /* get the perag structure and ensure that it's inode capable */
+ pag = xfs_get_perag(mp, ino);
+ if (!pag->pagi_inodeok)
+ return EINVAL;
+ ASSERT(pag->pag_ici_init);
+ agino = XFS_INO_TO_AGINO(mp, ino);
+again:
+ read_lock(&pag->pag_ici_lock);
+ ip = radix_tree_lookup(&pag->pag_ici_root, agino);
- ih = XFS_IHASH(mp, ino);
+ if (ip != NULL) {
+ /*
+ * If INEW is set this inode is being set up
+ * we need to pause and try again.
+ */
+ if (xfs_iflags_test(ip, XFS_INEW)) {
+ read_unlock(&pag->pag_ici_lock);
+ delay(1);
+ XFS_STATS_INC(xs_ig_frecycle);
-again:
- read_lock(&ih->ih_lock);
+ goto again;
+ }
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == ino) {
+ inode_vp = XFS_ITOV_NULL(ip);
+ if (inode_vp == NULL) {
/*
- * If INEW is set this inode is being set up
+ * If IRECLAIM is set this inode is
+ * on its way out of the system,
* we need to pause and try again.
*/
- if (xfs_iflags_test(ip, XFS_INEW)) {
- read_unlock(&ih->ih_lock);
+ if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
+ read_unlock(&pag->pag_ici_lock);
delay(1);
XFS_STATS_INC(xs_ig_frecycle);
goto again;
}
+ ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE));
- inode_vp = XFS_ITOV_NULL(ip);
- if (inode_vp == NULL) {
- /*
- * If IRECLAIM is set this inode is
- * on its way out of the system,
- * we need to pause and try again.
- */
- if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
- read_unlock(&ih->ih_lock);
- delay(1);
- XFS_STATS_INC(xs_ig_frecycle);
-
- goto again;
- }
- ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE));
-
- /*
- * If lookup is racing with unlink, then we
- * should return an error immediately so we
- * don't remove it from the reclaim list and
- * potentially leak the inode.
- */
- if ((ip->i_d.di_mode == 0) &&
- !(flags & XFS_IGET_CREATE)) {
- read_unlock(&ih->ih_lock);
- return ENOENT;
- }
-
- /*
- * There may be transactions sitting in the
- * incore log buffers or being flushed to disk
- * at this time. We can't clear the
- * XFS_IRECLAIMABLE flag until these
- * transactions have hit the disk, otherwise we
- * will void the guarantee the flag provides
- * xfs_iunpin()
- */
- if (xfs_ipincount(ip)) {
- read_unlock(&ih->ih_lock);
- xfs_log_force(mp, 0,
- XFS_LOG_FORCE|XFS_LOG_SYNC);
- XFS_STATS_INC(xs_ig_frecycle);
- goto again;
- }
-
- vn_trace_exit(vp, "xfs_iget.alloc",
- (inst_t *)__return_address);
+ /*
+ * If lookup is racing with unlink, then we
+ * should return an error immediately so we
+ * don't remove it from the reclaim list and
+ * potentially leak the inode.
+ */
+ if ((ip->i_d.di_mode == 0) &&
+ !(flags & XFS_IGET_CREATE)) {
+ read_unlock(&pag->pag_ici_lock);
+ xfs_put_perag(mp, pag);
+ return ENOENT;
+ }
+
+ /*
+ * There may be transactions sitting in the
+ * incore log buffers or being flushed to disk
+ * at this time. We can't clear the
+ * XFS_IRECLAIMABLE flag until these
+ * transactions have hit the disk, otherwise we
+ * will void the guarantee the flag provides
+ * xfs_iunpin()
+ */
+ if (xfs_ipincount(ip)) {
+ read_unlock(&pag->pag_ici_lock);
+ xfs_log_force(mp, 0,
+ XFS_LOG_FORCE|XFS_LOG_SYNC);
+ XFS_STATS_INC(xs_ig_frecycle);
+ goto again;
+ }
- XFS_STATS_INC(xs_ig_found);
+ vn_trace_exit(ip, "xfs_iget.alloc",
+ (inst_t *)__return_address);
- xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
- version = ih->ih_version;
- read_unlock(&ih->ih_lock);
- xfs_ihash_promote(ih, ip, version);
+ XFS_STATS_INC(xs_ig_found);
- XFS_MOUNT_ILOCK(mp);
- list_del_init(&ip->i_reclaim);
- XFS_MOUNT_IUNLOCK(mp);
+ xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
+ read_unlock(&pag->pag_ici_lock);
- goto finish_inode;
+ XFS_MOUNT_ILOCK(mp);
+ list_del_init(&ip->i_reclaim);
+ XFS_MOUNT_IUNLOCK(mp);
- } else if (vp != inode_vp) {
- struct inode *inode = vn_to_inode(inode_vp);
+ goto finish_inode;
- /* The inode is being torn down, pause and
- * try again.
- */
- if (inode->i_state & (I_FREEING | I_CLEAR)) {
- read_unlock(&ih->ih_lock);
- delay(1);
- XFS_STATS_INC(xs_ig_frecycle);
+ } else if (vp != inode_vp) {
+ struct inode *inode = vn_to_inode(inode_vp);
- goto again;
- }
-/* Chances are the other vnode (the one in the inode) is being torn
- * down right now, and we landed on top of it. Question is, what do
- * we do? Unhook the old inode and hook up the new one?
- */
- cmn_err(CE_PANIC,
- "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p",
- inode_vp, vp);
+ /* The inode is being torn down, pause and
+ * try again.
+ */
+ if (inode->i_state & (I_FREEING | I_CLEAR)) {
+ read_unlock(&pag->pag_ici_lock);
+ delay(1);
+ XFS_STATS_INC(xs_ig_frecycle);
+
+ goto again;
}
+/* Chances are the other vnode (the one in the inode) is being torn
+* down right now, and we landed on top of it. Question is, what do
+* we do? Unhook the old inode and hook up the new one?
+*/
+ cmn_err(CE_PANIC,
+ "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p",
+ inode_vp, vp);
+ }
- /*
- * Inode cache hit: if ip is not at the front of
- * its hash chain, move it there now.
- * Do this with the lock held for update, but
- * do statistics after releasing the lock.
- */
- version = ih->ih_version;
- read_unlock(&ih->ih_lock);
- xfs_ihash_promote(ih, ip, version);
- XFS_STATS_INC(xs_ig_found);
+ /*
+ * Inode cache hit
+ */
+ read_unlock(&pag->pag_ici_lock);
+ XFS_STATS_INC(xs_ig_found);
finish_inode:
- if (ip->i_d.di_mode == 0) {
- if (!(flags & XFS_IGET_CREATE))
- return ENOENT;
- xfs_iocore_inode_reinit(ip);
+ if (ip->i_d.di_mode == 0) {
+ if (!(flags & XFS_IGET_CREATE)) {
+ xfs_put_perag(mp, pag);
+ return ENOENT;
}
+ xfs_iocore_inode_reinit(ip);
+ }
- if (lock_flags != 0)
- xfs_ilock(ip, lock_flags);
+ if (lock_flags != 0)
+ xfs_ilock(ip, lock_flags);
- xfs_iflags_clear(ip, XFS_ISTALE);
- vn_trace_exit(vp, "xfs_iget.found",
- (inst_t *)__return_address);
- goto return_ip;
- }
+ xfs_iflags_clear(ip, XFS_ISTALE);
+ vn_trace_exit(ip, "xfs_iget.found",
+ (inst_t *)__return_address);
+ goto return_ip;
}
/*
- * Inode cache miss: save the hash chain version stamp and unlock
- * the chain, so we don't deadlock in vn_alloc.
+ * Inode cache miss
*/
+ read_unlock(&pag->pag_ici_lock);
XFS_STATS_INC(xs_ig_missed);
- version = ih->ih_version;
-
- read_unlock(&ih->ih_lock);
-
/*
* Read the disk inode attributes into a new inode structure and get
* a new vnode for it. This should also initialize i_ino and i_mount.
*/
error = xfs_iread(mp, tp, ino, &ip, bno,
(flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
- if (error)
+ if (error) {
+ xfs_put_perag(mp, pag);
return error;
+ }
- vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
+ vn_trace_exit(ip, "xfs_iget.alloc", (inst_t *)__return_address);
xfs_inode_lock_init(ip, vp);
xfs_iocore_inode_init(ip);
-
if (lock_flags)
xfs_ilock(ip, lock_flags);
if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
xfs_idestroy(ip);
+ xfs_put_perag(mp, pag);
return ENOENT;
}
/*
- * Put ip on its hash chain, unless someone else hashed a duplicate
- * after we released the hash lock.
+ * This is a bit messy - we preallocate everything we _might_
+ * need before we pick up the ici lock. That way we don't have to
+ * juggle locks and go all the way back to the start.
*/
- write_lock(&ih->ih_lock);
+ new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP);
+ if (radix_tree_preload(GFP_KERNEL)) {
+ delay(1);
+ goto again;
+ }
+ mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
+ first_index = agino & mask;
+ write_lock(&pag->pag_ici_lock);
- if (ih->ih_version != version) {
- for (iq = ih->ih_next; iq != NULL; iq = iq->i_next) {
- if (iq->i_ino == ino) {
- write_unlock(&ih->ih_lock);
- xfs_idestroy(ip);
+ /*
+ * Find the cluster if it exists
+ */
+ icl = NULL;
+ if (radix_tree_gang_lookup(&pag->pag_ici_root, (void**)&iq,
+ first_index, 1)) {
+ if ((iq->i_ino & mask) == first_index)
+ icl = iq->i_cluster;
+ }
- XFS_STATS_INC(xs_ig_dup);
- goto again;
- }
- }
+ /*
+ * insert the new inode
+ */
+ error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
+ if (unlikely(error)) {
+ BUG_ON(error != -EEXIST);
+ write_unlock(&pag->pag_ici_lock);
+ radix_tree_preload_end();
+ xfs_idestroy(ip);
+ XFS_STATS_INC(xs_ig_dup);
+ goto again;
}
/*
* These values _must_ be set before releasing ihlock!
*/
- ip->i_hash = ih;
- if ((iq = ih->ih_next)) {
- iq->i_prevp = &ip->i_next;
- }
- ip->i_next = iq;
- ip->i_prevp = &ih->ih_next;
- ih->ih_next = ip;
ip->i_udquot = ip->i_gdquot = NULL;
- ih->ih_version++;
xfs_iflags_set(ip, XFS_INEW);
- write_unlock(&ih->ih_lock);
- /*
- * put ip on its cluster's hash chain
- */
- ASSERT(ip->i_chash == NULL && ip->i_cprev == NULL &&
- ip->i_cnext == NULL);
-
- chlnew = NULL;
- ch = XFS_CHASH(mp, ip->i_blkno);
- chlredo:
- s = mutex_spinlock(&ch->ch_lock);
- for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
- if (chl->chl_blkno == ip->i_blkno) {
-
- /* insert this inode into the doubly-linked list
- * where chl points */
- if ((iq = chl->chl_ip)) {
- ip->i_cprev = iq->i_cprev;
- iq->i_cprev->i_cnext = ip;
- iq->i_cprev = ip;
- ip->i_cnext = iq;
- } else {
- ip->i_cnext = ip;
- ip->i_cprev = ip;
- }
- chl->chl_ip = ip;
- ip->i_chash = chl;
- break;
- }
- }
+ ASSERT(ip->i_cluster == NULL);
- /* no hash list found for this block; add a new hash list */
- if (chl == NULL) {
- if (chlnew == NULL) {
- mutex_spinunlock(&ch->ch_lock, s);
- ASSERT(xfs_chashlist_zone != NULL);
- chlnew = (xfs_chashlist_t *)
- kmem_zone_alloc(xfs_chashlist_zone,
- KM_SLEEP);
- ASSERT(chlnew != NULL);
- goto chlredo;
- } else {
- ip->i_cnext = ip;
- ip->i_cprev = ip;
- ip->i_chash = chlnew;
- chlnew->chl_ip = ip;
- chlnew->chl_blkno = ip->i_blkno;
- if (ch->ch_list)
- ch->ch_list->chl_prev = chlnew;
- chlnew->chl_next = ch->ch_list;
- chlnew->chl_prev = NULL;
- ch->ch_list = chlnew;
- chlnew = NULL;
- }
+ if (!icl) {
+ spin_lock_init(&new_icl->icl_lock);
+ INIT_HLIST_HEAD(&new_icl->icl_inodes);
+ icl = new_icl;
+ new_icl = NULL;
} else {
- if (chlnew != NULL) {
- kmem_zone_free(xfs_chashlist_zone, chlnew);
- }
+ ASSERT(!hlist_empty(&icl->icl_inodes));
}
+ spin_lock(&icl->icl_lock);
+ hlist_add_head(&ip->i_cnode, &icl->icl_inodes);
+ ip->i_cluster = icl;
+ spin_unlock(&icl->icl_lock);
- mutex_spinunlock(&ch->ch_lock, s);
-
+ write_unlock(&pag->pag_ici_lock);
+ radix_tree_preload_end();
+ if (new_icl)
+ kmem_zone_free(xfs_icluster_zone, new_icl);
/*
* Link ip to its mount and thread it on the mount's inode list.
@@ -478,6 +327,7 @@ finish_inode:
mp->m_inodes = ip;
XFS_MOUNT_IUNLOCK(mp);
+ xfs_put_perag(mp, pag);
return_ip:
ASSERT(ip->i_df.if_ext_max ==
@@ -486,14 +336,14 @@ finish_inode:
ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
+ xfs_iflags_set(ip, XFS_IMODIFIED);
*ipp = ip;
/*
* If we have a real type for an on-disk inode, we can set ops(&unlock)
* now. If it's a new inode being created, xfs_ialloc will handle it.
*/
- bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
-
+ xfs_initialize_vnode(mp, vp, ip);
return 0;
}
@@ -519,7 +369,8 @@ xfs_iget(
XFS_STATS_INC(xs_ig_attempts);
retry:
- if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) {
+ inode = iget_locked(mp->m_super, ino);
+ if (inode) {
xfs_inode_t *ip;
vp = vn_from_inode(inode);
@@ -570,8 +421,8 @@ xfs_inode_lock_init(
bhv_vnode_t *vp)
{
mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
- "xfsino", (long)vp->v_number);
- mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number);
+ "xfsino", ip->i_ino);
+ mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
init_waitqueue_head(&ip->i_ipin_wait);
atomic_set(&ip->i_pincount, 0);
initnsema(&ip->i_flock, 1, "xfsfino");
@@ -587,32 +438,19 @@ xfs_inode_incore(xfs_mount_t *mp,
xfs_ino_t ino,
xfs_trans_t *tp)
{
- xfs_ihash_t *ih;
xfs_inode_t *ip;
- ulong version;
-
- ih = XFS_IHASH(mp, ino);
- read_lock(&ih->ih_lock);
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == ino) {
- /*
- * If we find it and tp matches, return it.
- * Also move it to the front of the hash list
- * if we find it and it is not already there.
- * Otherwise break from the loop and return
- * NULL.
- */
- if (ip->i_transp == tp) {
- version = ih->ih_version;
- read_unlock(&ih->ih_lock);
- xfs_ihash_promote(ih, ip, version);
- return (ip);
- }
- break;
- }
- }
- read_unlock(&ih->ih_lock);
- return (NULL);
+ xfs_perag_t *pag;
+
+ pag = xfs_get_perag(mp, ino);
+ read_lock(&pag->pag_ici_lock);
+ ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino));
+ read_unlock(&pag->pag_ici_lock);
+ xfs_put_perag(mp, pag);
+
+ /* the returned inode must match the transaction */
+ if (ip && (ip->i_transp != tp))
+ return NULL;
+ return ip;
}
/*
@@ -629,7 +467,7 @@ xfs_iput(xfs_inode_t *ip,
{
bhv_vnode_t *vp = XFS_ITOV(ip);
- vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
+ vn_trace_entry(ip, "xfs_iput", (inst_t *)__return_address);
xfs_iunlock(ip, lock_flags);
VN_RELE(vp);
}
@@ -644,7 +482,7 @@ xfs_iput_new(xfs_inode_t *ip,
bhv_vnode_t *vp = XFS_ITOV(ip);
struct inode *inode = vn_to_inode(vp);
- vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
+ vn_trace_entry(ip, "xfs_iput_new", (inst_t *)__return_address);
if ((ip->i_d.di_mode == 0)) {
ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
@@ -699,7 +537,8 @@ xfs_ireclaim(xfs_inode_t *ip)
*/
vp = XFS_ITOV_NULL(ip);
if (vp) {
- vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
+ vn_to_inode(vp)->i_private = NULL;
+ ip->i_vnode = NULL;
}
/*
@@ -718,58 +557,26 @@ void
xfs_iextract(
xfs_inode_t *ip)
{
- xfs_ihash_t *ih;
+ xfs_mount_t *mp = ip->i_mount;
+ xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino);
xfs_inode_t *iq;
- xfs_mount_t *mp;
- xfs_chash_t *ch;
- xfs_chashlist_t *chl, *chm;
- SPLDECL(s);
-
- ih = ip->i_hash;
- write_lock(&ih->ih_lock);
- if ((iq = ip->i_next)) {
- iq->i_prevp = ip->i_prevp;
- }
- *ip->i_prevp = iq;
- ih->ih_version++;
- write_unlock(&ih->ih_lock);
+
+ write_lock(&pag->pag_ici_lock);
+ radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino));
+ write_unlock(&pag->pag_ici_lock);
+ xfs_put_perag(mp, pag);
/*
- * Remove from cluster hash list
- * 1) delete the chashlist if this is the last inode on the chashlist
- * 2) unchain from list of inodes
- * 3) point chashlist->chl_ip to 'chl_next' if to this inode.
+ * Remove from cluster list
*/
mp = ip->i_mount;
- ch = XFS_CHASH(mp, ip->i_blkno);
- s = mutex_spinlock(&ch->ch_lock);
-
- if (ip->i_cnext == ip) {
- /* Last inode on chashlist */
- ASSERT(ip->i_cnext == ip && ip->i_cprev == ip);
- ASSERT(ip->i_chash != NULL);
- chm=NULL;
- chl = ip->i_chash;
- if (chl->chl_prev)
- chl->chl_prev->chl_next = chl->chl_next;
- else
- ch->ch_list = chl->chl_next;
- if (chl->chl_next)
- chl->chl_next->chl_prev = chl->chl_prev;
- kmem_zone_free(xfs_chashlist_zone, chl);
- } else {
- /* delete one inode from a non-empty list */
- iq = ip->i_cnext;
- iq->i_cprev = ip->i_cprev;
- ip->i_cprev->i_cnext = iq;
- if (ip->i_chash->chl_ip == ip) {
- ip->i_chash->chl_ip = iq;
- }
- ip->i_chash = __return_address;
- ip->i_cprev = __return_address;
- ip->i_cnext = __return_address;
- }
- mutex_spinunlock(&ch->ch_lock, s);
+ spin_lock(&ip->i_cluster->icl_lock);
+ hlist_del(&ip->i_cnode);
+ spin_unlock(&ip->i_cluster->icl_lock);
+
+ /* was last inode in cluster? */
+ if (hlist_empty(&ip->i_cluster->icl_inodes))
+ kmem_zone_free(xfs_icluster_zone, ip->i_cluster);
/*
* Remove from mount's inode list.
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index cdc4c28926d..abf509a8891 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -49,12 +49,11 @@
#include "xfs_quota.h"
#include "xfs_acl.h"
#include "xfs_filestream.h"
-
-#include <linux/log2.h>
+#include "xfs_vnodeops.h"
kmem_zone_t *xfs_ifork_zone;
kmem_zone_t *xfs_inode_zone;
-kmem_zone_t *xfs_chashlist_zone;
+kmem_zone_t *xfs_icluster_zone;
/*
* Used in xfs_itruncate(). This is the maximum number of extents
@@ -67,7 +66,6 @@ STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
-
#ifdef DEBUG
/*
* Make sure that the extents in the given memory buffer
@@ -77,28 +75,23 @@ STATIC void
xfs_validate_extents(
xfs_ifork_t *ifp,
int nrecs,
- int disk,
xfs_exntfmt_t fmt)
{
- xfs_bmbt_rec_t *ep;
xfs_bmbt_irec_t irec;
- xfs_bmbt_rec_t rec;
+ xfs_bmbt_rec_host_t rec;
int i;
for (i = 0; i < nrecs; i++) {
- ep = xfs_iext_get_ext(ifp, i);
- rec.l0 = get_unaligned((__uint64_t*)&ep->l0);
- rec.l1 = get_unaligned((__uint64_t*)&ep->l1);
- if (disk)
- xfs_bmbt_disk_get_all(&rec, &irec);
- else
- xfs_bmbt_get_all(&rec, &irec);
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
+ rec.l0 = get_unaligned(&ep->l0);
+ rec.l1 = get_unaligned(&ep->l1);
+ xfs_bmbt_get_all(&rec, &irec);
if (fmt == XFS_EXTFMT_NOSTATE)
ASSERT(irec.br_state == XFS_EXT_NORM);
}
}
#else /* DEBUG */
-#define xfs_validate_extents(ifp, nrecs, disk, fmt)
+#define xfs_validate_extents(ifp, nrecs, fmt)
#endif /* DEBUG */
/*
@@ -201,8 +194,8 @@ xfs_inotobp(
}
dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0);
di_ok =
- INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
- XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
+ be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC &&
+ XFS_DINODE_GOOD_VERSION(dip->di_core.di_version);
if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip);
@@ -346,8 +339,8 @@ xfs_itobp(
dip = (xfs_dinode_t *)xfs_buf_offset(bp,
(i << mp->m_sb.sb_inodelog));
- di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC &&
- XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT));
+ di_ok = be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC &&
+ XFS_DINODE_GOOD_VERSION(dip->di_core.di_version);
if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
@@ -361,7 +354,7 @@ xfs_itobp(
"daddr %lld #%d (magic=%x)",
XFS_BUFTARG_NAME(mp->m_ddev_targp),
(unsigned long long)imap.im_blkno, i,
- INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
+ be16_to_cpu(dip->di_core.di_magic));
#endif
XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH,
mp, dip);
@@ -407,27 +400,26 @@ xfs_iformat(
XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
error = 0;
- if (unlikely(
- INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) +
- INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) >
- INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) {
+ if (unlikely(be32_to_cpu(dip->di_core.di_nextents) +
+ be16_to_cpu(dip->di_core.di_anextents) >
+ be64_to_cpu(dip->di_core.di_nblocks))) {
xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
"corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
(unsigned long long)ip->i_ino,
- (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT)
- + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)),
+ (int)(be32_to_cpu(dip->di_core.di_nextents) +
+ be16_to_cpu(dip->di_core.di_anextents)),
(unsigned long long)
- INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT));
+ be64_to_cpu(dip->di_core.di_nblocks));
XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
- if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) {
+ if (unlikely(dip->di_core.di_forkoff > ip->i_mount->m_sb.sb_inodesize)) {
xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
"corrupt dinode %Lu, forkoff = 0x%x.",
(unsigned long long)ip->i_ino,
- (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT)));
+ dip->di_core.di_forkoff);
XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
@@ -438,25 +430,25 @@ xfs_iformat(
case S_IFCHR:
case S_IFBLK:
case S_IFSOCK:
- if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) {
+ if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) {
XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
ip->i_mount, dip);
return XFS_ERROR(EFSCORRUPTED);
}
ip->i_d.di_size = 0;
ip->i_size = 0;
- ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
+ ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev);
break;
case S_IFREG:
case S_IFLNK:
case S_IFDIR:
- switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) {
+ switch (dip->di_core.di_format) {
case XFS_DINODE_FMT_LOCAL:
/*
* no local regular files yet
*/
- if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) {
+ if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) {
xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode %Lu "
"(local format for regular file).",
@@ -467,7 +459,7 @@ xfs_iformat(
return XFS_ERROR(EFSCORRUPTED);
}
- di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT);
+ di_size = be64_to_cpu(dip->di_core.di_size);
if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
"corrupt inode %Lu "
@@ -509,7 +501,7 @@ xfs_iformat(
ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
ip->i_afp->if_ext_max =
XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
- switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) {
+ switch (dip->di_core.di_aformat) {
case XFS_DINODE_FMT_LOCAL:
atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
size = be16_to_cpu(atp->hdr.totsize);
@@ -602,7 +594,7 @@ xfs_iformat_extents(
xfs_dinode_t *dip,
int whichfork)
{
- xfs_bmbt_rec_t *ep, *dp;
+ xfs_bmbt_rec_t *dp;
xfs_ifork_t *ifp;
int nex;
int size;
@@ -637,13 +629,11 @@ xfs_iformat_extents(
ifp->if_bytes = size;
if (size) {
dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
- xfs_validate_extents(ifp, nex, 1, XFS_EXTFMT_INODE(ip));
+ xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));
for (i = 0; i < nex; i++, dp++) {
- ep = xfs_iext_get_ext(ifp, i);
- ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0),
- ARCH_CONVERT);
- ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1),
- ARCH_CONVERT);
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
+ ep->l0 = be64_to_cpu(get_unaligned(&dp->l0));
+ ep->l1 = be64_to_cpu(get_unaligned(&dp->l1));
}
XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);
if (whichfork != XFS_DATA_FORK ||
@@ -719,70 +709,74 @@ xfs_iformat_btree(
return 0;
}
-/*
- * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk
- * and native format
- *
- * buf = on-disk representation
- * dip = native representation
- * dir = direction - +ve -> disk to native
- * -ve -> native to disk
- */
void
-xfs_xlate_dinode_core(
- xfs_caddr_t buf,
- xfs_dinode_core_t *dip,
- int dir)
+xfs_dinode_from_disk(
+ xfs_icdinode_t *to,
+ xfs_dinode_core_t *from)
{
- xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf;
- xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip;
- xfs_arch_t arch = ARCH_CONVERT;
-
- ASSERT(dir);
-
- INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
- INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
- INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
- INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
- INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
- INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
- INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
- INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
- INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
-
- if (dir > 0) {
- memcpy(mem_core->di_pad, buf_core->di_pad,
- sizeof(buf_core->di_pad));
- } else {
- memcpy(buf_core->di_pad, mem_core->di_pad,
- sizeof(buf_core->di_pad));
- }
-
- INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch);
-
- INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec,
- dir, arch);
- INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec,
- dir, arch);
- INT_XLATE(buf_core->di_mtime.t_sec, mem_core->di_mtime.t_sec,
- dir, arch);
- INT_XLATE(buf_core->di_mtime.t_nsec, mem_core->di_mtime.t_nsec,
- dir, arch);
- INT_XLATE(buf_core->di_ctime.t_sec, mem_core->di_ctime.t_sec,
- dir, arch);
- INT_XLATE(buf_core->di_ctime.t_nsec, mem_core->di_ctime.t_nsec,
- dir, arch);
- INT_XLATE(buf_core->di_size, mem_core->di_size, dir, arch);
- INT_XLATE(buf_core->di_nblocks, mem_core->di_nblocks, dir, arch);
- INT_XLATE(buf_core->di_extsize, mem_core->di_extsize, dir, arch);
- INT_XLATE(buf_core->di_nextents, mem_core->di_nextents, dir, arch);
- INT_XLATE(buf_core->di_anextents, mem_core->di_anextents, dir, arch);
- INT_XLATE(buf_core->di_forkoff, mem_core->di_forkoff, dir, arch);
- INT_XLATE(buf_core->di_aformat, mem_core->di_aformat, dir, arch);
- INT_XLATE(buf_core->di_dmevmask, mem_core->di_dmevmask, dir, arch);
- INT_XLATE(buf_core->di_dmstate, mem_core->di_dmstate, dir, arch);
- INT_XLATE(buf_core->di_flags, mem_core->di_flags, dir, arch);
- INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch);
+ to->di_magic = be16_to_cpu(from->di_magic);
+ to->di_mode = be16_to_cpu(from->di_mode);
+ to->di_version = from ->di_version;
+ to->di_format = from->di_format;
+ to->di_onlink = be16_to_cpu(from->di_onlink);
+ to->di_uid = be32_to_cpu(from->di_uid);
+ to->di_gid = be32_to_cpu(from->di_gid);
+ to->di_nlink = be32_to_cpu(from->di_nlink);
+ to->di_projid = be16_to_cpu(from->di_projid);
+ memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
+ to->di_flushiter = be16_to_cpu(from->di_flushiter);
+ to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
+ to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
+ to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
+ to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
+ to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
+ to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
+ to->di_size = be64_to_cpu(from->di_size);
+ to->di_nblocks = be64_to_cpu(from->di_nblocks);
+ to->di_extsize = be32_to_cpu(from->di_extsize);
+ to->di_nextents = be32_to_cpu(from->di_nextents);
+ to->di_anextents = be16_to_cpu(from->di_anextents);
+ to->di_forkoff = from->di_forkoff;
+ to->di_aformat = from->di_aformat;
+ to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
+ to->di_dmstate = be16_to_cpu(from->di_dmstate);
+ to->di_flags = be16_to_cpu(from->di_flags);
+ to->di_gen = be32_to_cpu(from->di_gen);
+}
+
+void
+xfs_dinode_to_disk(
+ xfs_dinode_core_t *to,
+ xfs_icdinode_t *from)
+{
+ to->di_magic = cpu_to_be16(from->di_magic);
+ to->di_mode = cpu_to_be16(from->di_mode);
+ to->di_version = from ->di_version;
+ to->di_format = from->di_format;
+ to->di_onlink = cpu_to_be16(from->di_onlink);
+ to->di_uid = cpu_to_be32(from->di_uid);
+ to->di_gid = cpu_to_be32(from->di_gid);
+ to->di_nlink = cpu_to_be32(from->di_nlink);
+ to->di_projid = cpu_to_be16(from->di_projid);
+ memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
+ to->di_flushiter = cpu_to_be16(from->di_flushiter);
+ to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
+ to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
+ to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
+ to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
+ to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
+ to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
+ to->di_size = cpu_to_be64(from->di_size);
+ to->di_nblocks = cpu_to_be64(from->di_nblocks);
+ to->di_extsize = cpu_to_be32(from->di_extsize);
+ to->di_nextents = cpu_to_be32(from->di_nextents);
+ to->di_anextents = cpu_to_be16(from->di_anextents);
+ to->di_forkoff = from->di_forkoff;
+ to->di_aformat = from->di_aformat;
+ to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
+ to->di_dmstate = cpu_to_be16(from->di_dmstate);
+ to->di_flags = cpu_to_be16(from->di_flags);
+ to->di_gen = cpu_to_be32(from->di_gen);
}
STATIC uint
@@ -829,7 +823,7 @@ uint
xfs_ip2xflags(
xfs_inode_t *ip)
{
- xfs_dinode_core_t *dic = &ip->i_d;
+ xfs_icdinode_t *dic = &ip->i_d;
return _xfs_dic2xflags(dic->di_flags) |
(XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
@@ -839,7 +833,7 @@ uint
xfs_dic2xflags(
xfs_dinode_core_t *dic)
{
- return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) |
+ return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) |
(XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
}
@@ -870,6 +864,7 @@ xfs_iread(
ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP);
ip->i_ino = ino;
ip->i_mount = mp;
+ atomic_set(&ip->i_iocount, 0);
spin_lock_init(&ip->i_flags_lock);
/*
@@ -889,6 +884,9 @@ xfs_iread(
* Initialize inode's trace buffers.
* Do this before xfs_iformat in case it adds entries.
*/
+#ifdef XFS_VNODE_TRACE
+ ip->i_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
+#endif
#ifdef XFS_BMAP_TRACE
ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP);
#endif
@@ -909,14 +907,14 @@ xfs_iread(
* If we got something that isn't an inode it means someone
* (nfs or dmi) has a stale handle.
*/
- if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
+ if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
kmem_zone_free(xfs_inode_zone, ip);
xfs_trans_brelse(tp, bp);
#ifdef DEBUG
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
"dip->di_core.di_magic (0x%x) != "
"XFS_DINODE_MAGIC (0x%x)",
- INT_GET(dip->di_core.di_magic, ARCH_CONVERT),
+ be16_to_cpu(dip->di_core.di_magic),
XFS_DINODE_MAGIC);
#endif /* DEBUG */
return XFS_ERROR(EINVAL);
@@ -930,8 +928,7 @@ xfs_iread(
* Otherwise, just get the truly permanent information.
*/
if (dip->di_core.di_mode) {
- xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core,
- &(ip->i_d), 1);
+ xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
error = xfs_iformat(ip, dip);
if (error) {
kmem_zone_free(xfs_inode_zone, ip);
@@ -944,10 +941,10 @@ xfs_iread(
return error;
}
} else {
- ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT);
- ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT);
- ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT);
- ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT);
+ ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic);
+ ip->i_d.di_version = dip->di_core.di_version;
+ ip->i_d.di_gen = be32_to_cpu(dip->di_core.di_gen);
+ ip->i_d.di_flushiter = be16_to_cpu(dip->di_core.di_flushiter);
/*
* Make sure to pull in the mode here as well in
* case the inode is released without being used.
@@ -1048,7 +1045,7 @@ xfs_iread_extents(
ifp->if_flags &= ~XFS_IFEXTENTS;
return error;
}
- xfs_validate_extents(ifp, nextents, 0, XFS_EXTFMT_INODE(ip));
+ xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
return 0;
}
@@ -1161,7 +1158,7 @@ xfs_ialloc(
if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
xfs_bump_ino_vers2(tp, ip);
- if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) {
+ if (pip && XFS_INHERIT_GID(pip)) {
ip->i_d.di_gid = pip->i_d.di_gid;
if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
ip->i_d.di_mode |= S_ISGID;
@@ -1275,7 +1272,7 @@ xfs_ialloc(
xfs_trans_log_inode(tp, ip, flags);
/* now that we have an i_mode we can setup inode ops and unlock */
- bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
+ xfs_initialize_vnode(tp->t_mountp, vp, ip);
*ipp = ip;
return 0;
@@ -1462,7 +1459,7 @@ xfs_itruncate_start(
mp = ip->i_mount;
vp = XFS_ITOV(ip);
- vn_iowait(vp); /* wait for the completion of any pending DIOs */
+ vn_iowait(ip); /* wait for the completion of any pending DIOs */
/*
* Call toss_pages or flushinval_pages to get rid of pages
@@ -1497,9 +1494,11 @@ xfs_itruncate_start(
last_byte);
if (last_byte > toss_start) {
if (flags & XFS_ITRUNC_DEFINITE) {
- bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
+ xfs_tosspages(ip, toss_start,
+ -1, FI_REMAPF_LOCKED);
} else {
- error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
+ error = xfs_flushinval_pages(ip, toss_start,
+ -1, FI_REMAPF_LOCKED);
}
}
@@ -1932,9 +1931,9 @@ xfs_iunlink(
*/
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr,
XFS_FSS_TO_BB(mp, 1), 0, &agibp);
- if (error) {
+ if (error)
return error;
- }
+
/*
* Validate the magic number of the agi block.
*/
@@ -1958,6 +1957,24 @@ xfs_iunlink(
ASSERT(agi->agi_unlinked[bucket_index]);
ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
+ error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0);
+ if (error)
+ return error;
+
+ /*
+ * Clear the on-disk di_nlink. This is to prevent xfs_bulkstat
+ * from picking up this inode when it is reclaimed (its incore state
+ * initialzed but not flushed to disk yet). The in-core di_nlink is
+ * already cleared in xfs_droplink() and a corresponding transaction
+ * logged. The hack here just synchronizes the in-core to on-disk
+ * di_nlink value in advance before the actual inode sync to disk.
+ * This is OK because the inode is already unlinked and would never
+ * change its di_nlink again for this inode generation.
+ * This is a temporary hack that would require a proper fix
+ * in the future.
+ */
+ dip->di_core.di_nlink = 0;
+
if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) {
/*
* There is already another inode in the bucket we need
@@ -1965,12 +1982,7 @@ xfs_iunlink(
* Here we put the head pointer into our next pointer,
* and then we fall through to point the head at us.
*/
- error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0);
- if (error) {
- return error;
- }
- ASSERT(INT_GET(dip->di_next_unlinked, ARCH_CONVERT) == NULLAGINO);
- ASSERT(dip->di_next_unlinked);
+ ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO);
/* both on-disk, don't endian flip twice */
dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
offset = ip->i_boffset +
@@ -2081,10 +2093,10 @@ xfs_iunlink_remove(
error, mp->m_fsname);
return error;
}
- next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT);
+ next_agino = be32_to_cpu(dip->di_next_unlinked);
ASSERT(next_agino != 0);
if (next_agino != NULLAGINO) {
- INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
+ dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
offset = ip->i_boffset +
offsetof(xfs_dinode_t, di_next_unlinked);
xfs_trans_inode_buf(tp, ibp);
@@ -2128,7 +2140,7 @@ xfs_iunlink_remove(
error, mp->m_fsname);
return error;
}
- next_agino = INT_GET(last_dip->di_next_unlinked, ARCH_CONVERT);
+ next_agino = be32_to_cpu(last_dip->di_next_unlinked);
ASSERT(next_agino != NULLAGINO);
ASSERT(next_agino != 0);
}
@@ -2143,11 +2155,11 @@ xfs_iunlink_remove(
error, mp->m_fsname);
return error;
}
- next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT);
+ next_agino = be32_to_cpu(dip->di_next_unlinked);
ASSERT(next_agino != 0);
ASSERT(next_agino != agino);
if (next_agino != NULLAGINO) {
- INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
+ dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
offset = ip->i_boffset +
offsetof(xfs_dinode_t, di_next_unlinked);
xfs_trans_inode_buf(tp, ibp);
@@ -2160,7 +2172,7 @@ xfs_iunlink_remove(
/*
* Point the previous inode on the list to the next inode.
*/
- INT_SET(last_dip->di_next_unlinked, ARCH_CONVERT, next_agino);
+ last_dip->di_next_unlinked = cpu_to_be32(next_agino);
ASSERT(next_agino != 0);
offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
xfs_trans_inode_buf(tp, last_ibp);
@@ -2191,10 +2203,10 @@ xfs_ifree_cluster(
int i, j, found, pre_flushed;
xfs_daddr_t blkno;
xfs_buf_t *bp;
- xfs_ihash_t *ih;
xfs_inode_t *ip, **ip_found;
xfs_inode_log_item_t *iip;
xfs_log_item_t *lip;
+ xfs_perag_t *pag = xfs_get_perag(mp, inum);
SPLDECL(s);
if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
@@ -2229,23 +2241,20 @@ xfs_ifree_cluster(
*/
found = 0;
for (i = 0; i < ninodes; i++) {
- ih = XFS_IHASH(mp, inum + i);
- read_lock(&ih->ih_lock);
- for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
- if (ip->i_ino == inum + i)
- break;
- }
+ read_lock(&pag->pag_ici_lock);
+ ip = radix_tree_lookup(&pag->pag_ici_root,
+ XFS_INO_TO_AGINO(mp, (inum + i)));
/* Inode not in memory or we found it already,
* nothing to do
*/
if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {
- read_unlock(&ih->ih_lock);
+ read_unlock(&pag->pag_ici_lock);
continue;
}
if (xfs_inode_clean(ip)) {
- read_unlock(&ih->ih_lock);
+ read_unlock(&pag->pag_ici_lock);
continue;
}
@@ -2268,7 +2277,7 @@ xfs_ifree_cluster(
ip_found[found++] = ip;
}
}
- read_unlock(&ih->ih_lock);
+ read_unlock(&pag->pag_ici_lock);
continue;
}
@@ -2286,8 +2295,7 @@ xfs_ifree_cluster(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
}
-
- read_unlock(&ih->ih_lock);
+ read_unlock(&pag->pag_ici_lock);
}
bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
@@ -2342,6 +2350,7 @@ xfs_ifree_cluster(
}
kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *));
+ xfs_put_perag(mp, pag);
}
/*
@@ -2737,6 +2746,10 @@ xfs_idestroy(
mrfree(&ip->i_lock);
mrfree(&ip->i_iolock);
freesema(&ip->i_flock);
+
+#ifdef XFS_VNODE_TRACE
+ ktrace_free(ip->i_trace);
+#endif
#ifdef XFS_BMAP_TRACE
ktrace_free(ip->i_xtrace);
#endif
@@ -2887,12 +2900,10 @@ xfs_iunpin_wait(
int
xfs_iextents_copy(
xfs_inode_t *ip,
- xfs_bmbt_rec_t *buffer,
+ xfs_bmbt_rec_t *dp,
int whichfork)
{
int copied;
- xfs_bmbt_rec_t *dest_ep;
- xfs_bmbt_rec_t *ep;
int i;
xfs_ifork_t *ifp;
int nrecs;
@@ -2912,10 +2923,9 @@ xfs_iextents_copy(
* the delayed ones. There must be at least one
* non-delayed extent.
*/
- dest_ep = buffer;
copied = 0;
for (i = 0; i < nrecs; i++) {
- ep = xfs_iext_get_ext(ifp, i);
+ xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
start_block = xfs_bmbt_get_startblock(ep);
if (ISNULLSTARTBLOCK(start_block)) {
/*
@@ -2925,15 +2935,13 @@ xfs_iextents_copy(
}
/* Translate to on disk format */
- put_unaligned(INT_GET(ep->l0, ARCH_CONVERT),
- (__uint64_t*)&dest_ep->l0);
- put_unaligned(INT_GET(ep->l1, ARCH_CONVERT),
- (__uint64_t*)&dest_ep->l1);
- dest_ep++;
+ put_unaligned(cpu_to_be64(ep->l0), &dp->l0);
+ put_unaligned(cpu_to_be64(ep->l1), &dp->l1);
+ dp++;
copied++;
}
ASSERT(copied != 0);
- xfs_validate_extents(ifp, copied, 1, XFS_EXTFMT_INODE(ip));
+ xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip));
return (copied * (uint)sizeof(xfs_bmbt_rec_t));
}
@@ -3024,7 +3032,7 @@ xfs_iflush_fork(
case XFS_DINODE_FMT_DEV:
if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) {
ASSERT(whichfork == XFS_DATA_FORK);
- INT_SET(dip->di_u.di_dev, ARCH_CONVERT, ip->i_df.if_u2.if_rdev);
+ dip->di_u.di_dev = cpu_to_be32(ip->i_df.if_u2.if_rdev);
}
break;
@@ -3064,12 +3072,11 @@ xfs_iflush(
xfs_mount_t *mp;
int error;
/* REFERENCED */
- xfs_chash_t *ch;
xfs_inode_t *iq;
int clcount; /* count of inodes clustered */
int bufwasdelwri;
+ struct hlist_node *entry;
enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) };
- SPLDECL(s);
XFS_STATS_INC(xs_iflush_count);
@@ -3183,14 +3190,14 @@ xfs_iflush(
* inode clustering:
* see if other inodes can be gathered into this write
*/
-
- ip->i_chash->chl_buf = bp;
-
- ch = XFS_CHASH(mp, ip->i_blkno);
- s = mutex_spinlock(&ch->ch_lock);
+ spin_lock(&ip->i_cluster->icl_lock);
+ ip->i_cluster->icl_buf = bp;
clcount = 0;
- for (iq = ip->i_cnext; iq != ip; iq = iq->i_cnext) {
+ hlist_for_each_entry(iq, entry, &ip->i_cluster->icl_inodes, i_cnode) {
+ if (iq == ip)
+ continue;
+
/*
* Do an un-protected check to see if the inode is dirty and
* is a candidate for flushing. These checks will be repeated
@@ -3241,7 +3248,7 @@ xfs_iflush(
xfs_iunlock(iq, XFS_ILOCK_SHARED);
}
}
- mutex_spinunlock(&ch->ch_lock, s);
+ spin_unlock(&ip->i_cluster->icl_lock);
if (clcount) {
XFS_STATS_INC(xs_icluster_flushcnt);
@@ -3278,7 +3285,7 @@ cluster_corrupt_out:
/* Corruption detected in the clustering loop. Invalidate the
* inode buffer and shut down the filesystem.
*/
- mutex_spinunlock(&ch->ch_lock, s);
+ spin_unlock(&ip->i_cluster->icl_lock);
/*
* Clean up the buffer. If it was B_DELWRI, just release it --
@@ -3373,11 +3380,11 @@ xfs_iflush_int(
*/
xfs_synchronize_atime(ip);
- if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC,
+ if (XFS_TEST_ERROR(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC,
mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
"xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p",
- ip->i_ino, (int) INT_GET(dip->di_core.di_magic, ARCH_CONVERT), dip);
+ ip->i_ino, be16_to_cpu(dip->di_core.di_magic), dip);
goto corrupt_out;
}
if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC,
@@ -3440,7 +3447,7 @@ xfs_iflush_int(
* because if the inode is dirty at all the core must
* be.
*/
- xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1);
+ xfs_dinode_to_disk(&dip->di_core, &ip->i_d);
/* Wrap, we never let the log put out DI_MAX_FLUSH */
if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
@@ -3460,7 +3467,7 @@ xfs_iflush_int(
* Convert it back.
*/
ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
- INT_SET(dip->di_core.di_onlink, ARCH_CONVERT, ip->i_d.di_nlink);
+ dip->di_core.di_onlink = cpu_to_be16(ip->i_d.di_nlink);
} else {
/*
* The superblock version has already been bumped,
@@ -3468,7 +3475,7 @@ xfs_iflush_int(
* format permanent.
*/
ip->i_d.di_version = XFS_DINODE_VERSION_2;
- INT_SET(dip->di_core.di_version, ARCH_CONVERT, XFS_DINODE_VERSION_2);
+ dip->di_core.di_version = XFS_DINODE_VERSION_2;
ip->i_d.di_onlink = 0;
dip->di_core.di_onlink = 0;
memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
@@ -3711,7 +3718,7 @@ xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra)
/*
* Return a pointer to the extent record at file index idx.
*/
-xfs_bmbt_rec_t *
+xfs_bmbt_rec_host_t *
xfs_iext_get_ext(
xfs_ifork_t *ifp, /* inode fork pointer */
xfs_extnum_t idx) /* index of target extent */
@@ -3744,15 +3751,12 @@ xfs_iext_insert(
xfs_extnum_t count, /* number of inserted items */
xfs_bmbt_irec_t *new) /* items to insert */
{
- xfs_bmbt_rec_t *ep; /* extent record pointer */
xfs_extnum_t i; /* extent record index */
ASSERT(ifp->if_flags & XFS_IFEXTENTS);
xfs_iext_add(ifp, idx, count);
- for (i = idx; i < idx + count; i++, new++) {
- ep = xfs_iext_get_ext(ifp, i);
- xfs_bmbt_set_all(ep, new);
- }
+ for (i = idx; i < idx + count; i++, new++)
+ xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new);
}
/*
@@ -4203,7 +4207,7 @@ xfs_iext_realloc_direct(
rnew_size = xfs_iroundup(new_size);
}
if (rnew_size != ifp->if_real_bytes) {
- ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
+ ifp->if_u1.if_extents =
kmem_realloc(ifp->if_u1.if_extents,
rnew_size,
ifp->if_real_bytes,
@@ -4266,8 +4270,7 @@ xfs_iext_inline_to_direct(
xfs_ifork_t *ifp, /* inode fork pointer */
int new_size) /* number of extents in file */
{
- ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
- kmem_alloc(new_size, KM_SLEEP);
+ ifp->if_u1.if_extents = kmem_alloc(new_size, KM_SLEEP);
memset(ifp->if_u1.if_extents, 0, new_size);
if (ifp->if_bytes) {
memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
@@ -4310,7 +4313,7 @@ void
xfs_iext_indirect_to_direct(
xfs_ifork_t *ifp) /* inode fork pointer */
{
- xfs_bmbt_rec_t *ep; /* extent record pointer */
+ xfs_bmbt_rec_host_t *ep; /* extent record pointer */
xfs_extnum_t nextents; /* number of extents in file */
int size; /* size of file extents */
@@ -4362,15 +4365,15 @@ xfs_iext_destroy(
/*
* Return a pointer to the extent record for file system block bno.
*/
-xfs_bmbt_rec_t * /* pointer to found extent record */
+xfs_bmbt_rec_host_t * /* pointer to found extent record */
xfs_iext_bno_to_ext(
xfs_ifork_t *ifp, /* inode fork pointer */
xfs_fileoff_t bno, /* block number to search for */
xfs_extnum_t *idxp) /* index of target extent */
{
- xfs_bmbt_rec_t *base; /* pointer to first extent */
+ xfs_bmbt_rec_host_t *base; /* pointer to first extent */
xfs_filblks_t blockcount = 0; /* number of blocks in extent */
- xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */
+ xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */
xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
int high; /* upper boundary in search */
xfs_extnum_t idx = 0; /* index of target extent */
@@ -4545,8 +4548,7 @@ xfs_iext_irec_init(
kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP);
if (nextents == 0) {
- ifp->if_u1.if_extents = (xfs_bmbt_rec_t *)
- kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
+ ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
} else if (!ifp->if_real_bytes) {
xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ);
} else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) {
@@ -4594,8 +4596,7 @@ xfs_iext_irec_new(
/* Initialize new extent record */
erp = ifp->if_u1.if_ext_irec;
- erp[erp_idx].er_extbuf = (xfs_bmbt_rec_t *)
- kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
+ erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ);
erp[erp_idx].er_extcount = 0;
@@ -4727,7 +4728,7 @@ void
xfs_iext_irec_compact_full(
xfs_ifork_t *ifp) /* inode fork pointer */
{
- xfs_bmbt_rec_t *ep, *ep_next; /* extent record pointers */
+ xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */
xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */
int erp_idx = 0; /* extent irec index */
int ext_avail; /* empty entries in ex list */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 012dfd4a958..e5aff929cc6 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -18,6 +18,10 @@
#ifndef __XFS_INODE_H__
#define __XFS_INODE_H__
+struct xfs_dinode;
+struct xfs_dinode_core;
+
+
/*
* Fork identifiers.
*/
@@ -44,7 +48,7 @@
* it is possible that a third level of indirection may be required.
*/
typedef struct xfs_ext_irec {
- xfs_bmbt_rec_t *er_extbuf; /* block of extent records */
+ xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */
xfs_extnum_t er_extoff; /* extent offset in file */
xfs_extnum_t er_extcount; /* number of extents in page/block */
} xfs_ext_irec_t;
@@ -65,12 +69,12 @@ typedef struct xfs_ifork {
unsigned char if_ext_max; /* max # of extent records */
xfs_extnum_t if_lastex; /* last if_extents used */
union {
- xfs_bmbt_rec_t *if_extents; /* linear map file exts */
+ xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */
xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
char *if_data; /* inline file data */
} if_u1;
union {
- xfs_bmbt_rec_t if_inline_ext[XFS_INLINE_EXTS];
+ xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS];
/* very small file extents */
char if_inline_data[XFS_INLINE_DATA];
/* very small file data */
@@ -102,7 +106,6 @@ typedef struct xfs_ifork {
#ifdef __KERNEL__
struct bhv_desc;
-struct bhv_vnode;
struct cred;
struct ktrace;
struct xfs_buf;
@@ -168,41 +171,18 @@ typedef struct xfs_iocore {
extern void xfs_iocore_inode_init(struct xfs_inode *);
extern void xfs_iocore_inode_reinit(struct xfs_inode *);
-
-/*
- * This is the type used in the xfs inode hash table.
- * An array of these is allocated for each mounted
- * file system to hash the inodes for that file system.
- */
-typedef struct xfs_ihash {
- struct xfs_inode *ih_next;
- rwlock_t ih_lock;
- uint ih_version;
-} xfs_ihash_t;
-
-#define XFS_IHASH(mp,ino) ((mp)->m_ihash + (((uint)(ino)) % (mp)->m_ihsize))
-
/*
- * This is the xfs inode cluster hash. This hash is used by xfs_iflush to
- * find inodes that share a cluster and can be flushed to disk at the same
- * time.
+ * This is the xfs inode cluster structure. This structure is used by
+ * xfs_iflush to find inodes that share a cluster and can be flushed to disk at
+ * the same time.
*/
-typedef struct xfs_chashlist {
- struct xfs_chashlist *chl_next;
- struct xfs_chashlist *chl_prev;
- struct xfs_inode *chl_ip;
- xfs_daddr_t chl_blkno; /* starting block number of
+typedef struct xfs_icluster {
+ struct hlist_head icl_inodes; /* list of inodes on cluster */
+ xfs_daddr_t icl_blkno; /* starting block number of
* the cluster */
- struct xfs_buf *chl_buf; /* the inode buffer */
-} xfs_chashlist_t;
-
-typedef struct xfs_chash {
- xfs_chashlist_t *ch_list;
- lock_t ch_lock;
-} xfs_chash_t;
-
-#define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize))
-
+ struct xfs_buf *icl_buf; /* the inode buffer */
+ lock_t icl_lock; /* inode list lock */
+} xfs_icluster_t;
/*
* This is the xfs in-core inode structure.
@@ -227,25 +207,56 @@ typedef struct xfs_chash {
* chain off the mount structure by xfs_sync calls.
*/
+typedef struct xfs_ictimestamp {
+ __int32_t t_sec; /* timestamp seconds */
+ __int32_t t_nsec; /* timestamp nanoseconds */
+} xfs_ictimestamp_t;
+
+/*
+ * NOTE: This structure must be kept identical to struct xfs_dinode_core
+ * in xfs_dinode.h except for the endianess annotations.
+ */
+typedef struct xfs_icdinode {
+ __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
+ __uint16_t di_mode; /* mode and type of file */
+ __int8_t di_version; /* inode version */
+ __int8_t di_format; /* format of di_c data */
+ __uint16_t di_onlink; /* old number of links to file */
+ __uint32_t di_uid; /* owner's user id */
+ __uint32_t di_gid; /* owner's group id */
+ __uint32_t di_nlink; /* number of links to file */
+ __uint16_t di_projid; /* owner's project id */
+ __uint8_t di_pad[8]; /* unused, zeroed space */
+ __uint16_t di_flushiter; /* incremented on flush */
+ xfs_ictimestamp_t di_atime; /* time last accessed */
+ xfs_ictimestamp_t di_mtime; /* time last modified */
+ xfs_ictimestamp_t di_ctime; /* time created/inode modified */
+ xfs_fsize_t di_size; /* number of bytes in file */
+ xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
+ xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
+ xfs_extnum_t di_nextents; /* number of extents in data fork */
+ xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
+ __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
+ __int8_t di_aformat; /* format of attr fork's data */
+ __uint32_t di_dmevmask; /* DMIG event mask */
+ __uint16_t di_dmstate; /* DMIG state info */
+ __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
+ __uint32_t di_gen; /* generation number */
+} xfs_icdinode_t;
+
typedef struct {
- struct xfs_ihash *ip_hash; /* pointer to hash header */
- struct xfs_inode *ip_next; /* inode hash link forw */
struct xfs_inode *ip_mnext; /* next inode in mount list */
struct xfs_inode *ip_mprev; /* ptr to prev inode */
- struct xfs_inode **ip_prevp; /* ptr to prev i_next */
struct xfs_mount *ip_mount; /* fs mount struct ptr */
} xfs_iptr_t;
typedef struct xfs_inode {
/* Inode linking and identification information. */
- struct xfs_ihash *i_hash; /* pointer to hash header */
- struct xfs_inode *i_next; /* inode hash link forw */
struct xfs_inode *i_mnext; /* next inode in mount list */
struct xfs_inode *i_mprev; /* ptr to prev inode */
- struct xfs_inode **i_prevp; /* ptr to prev i_next */
struct xfs_mount *i_mount; /* fs mount struct ptr */
struct list_head i_reclaim; /* reclaim list */
- struct bhv_desc i_bhv_desc; /* inode behavior descriptor*/
+ bhv_vnode_t *i_vnode; /* vnode backpointer */
struct xfs_dquot *i_udquot; /* user dquot */
struct xfs_dquot *i_gdquot; /* group dquot */
@@ -282,13 +293,16 @@ typedef struct xfs_inode {
unsigned int i_gen; /* generation count */
unsigned int i_delayed_blks; /* count of delay alloc blks */
- xfs_dinode_core_t i_d; /* most of ondisk inode */
- xfs_chashlist_t *i_chash; /* cluster hash list header */
- struct xfs_inode *i_cnext; /* cluster hash link forward */
- struct xfs_inode *i_cprev; /* cluster hash link backward */
+ xfs_icdinode_t i_d; /* most of ondisk inode */
+ xfs_icluster_t *i_cluster; /* cluster list header */
+ struct hlist_node i_cnode; /* cluster link node */
xfs_fsize_t i_size; /* in-memory size */
+ atomic_t i_iocount; /* outstanding I/O count */
/* Trace buffers per inode. */
+#ifdef XFS_VNODE_TRACE
+ struct ktrace *i_trace; /* general inode trace */
+#endif
#ifdef XFS_BMAP_TRACE
struct ktrace *i_xtrace; /* inode extent list trace */
#endif
@@ -349,6 +363,19 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
spin_unlock(&ip->i_flags_lock);
return ret;
}
+
+static inline int
+xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags)
+{
+ int ret;
+
+ spin_lock(&ip->i_flags_lock);
+ ret = ip->i_flags & flags;
+ if (ret)
+ ip->i_flags &= ~flags;
+ spin_unlock(&ip->i_flags_lock);
+ return ret;
+}
#endif /* __KERNEL__ */
@@ -380,6 +407,9 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
#define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */
#define XFS_INEW 0x0040
#define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */
+#define XFS_IMODIFIED 0x0100 /* XFS inode state possibly differs */
+ /* to the Linux inode state. */
+#define XFS_ITRUNCATED 0x0200 /* truncated down so flush-on-close */
/*
* Flags for inode locking.
@@ -454,20 +484,17 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
#define XFS_ITRUNC_DEFINITE 0x1
#define XFS_ITRUNC_MAYBE 0x2
-#define XFS_ITOV(ip) BHV_TO_VNODE(XFS_ITOBHV(ip))
-#define XFS_ITOV_NULL(ip) BHV_TO_VNODE_NULL(XFS_ITOBHV(ip))
-#define XFS_ITOBHV(ip) ((struct bhv_desc *)(&((ip)->i_bhv_desc)))
-#define XFS_BHVTOI(bhvp) ((xfs_inode_t *)((char *)(bhvp) - \
- (char *)&(((xfs_inode_t *)0)->i_bhv_desc)))
-#define BHV_IS_XFS(bdp) (BHV_OPS(bdp) == &xfs_vnodeops)
+#define XFS_ITOV(ip) ((ip)->i_vnode)
+#define XFS_ITOV_NULL(ip) ((ip)->i_vnode)
/*
* For multiple groups support: if S_ISGID bit is set in the parent
* directory, group of new file is set to that of the parent, and
* new subdirectory gets S_ISGID bit from parent.
*/
-#define XFS_INHERIT_GID(pip, vfsp) \
- (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))
+#define XFS_INHERIT_GID(pip) \
+ (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
+ ((pip)->i_d.di_mode & S_ISGID))
/*
* Flags for xfs_iget()
@@ -480,11 +507,9 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
*/
void xfs_ihash_init(struct xfs_mount *);
void xfs_ihash_free(struct xfs_mount *);
-void xfs_chash_init(struct xfs_mount *);
-void xfs_chash_free(struct xfs_mount *);
xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
struct xfs_trans *);
-void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *);
+void xfs_inode_lock_init(xfs_inode_t *, bhv_vnode_t *);
int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
uint, uint, xfs_inode_t **, xfs_daddr_t);
void xfs_iput(xfs_inode_t *, uint);
@@ -506,7 +531,7 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int);
* xfs_inode.c prototypes.
*/
int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
- xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
+ xfs_inode_t *, struct xfs_dinode **, struct xfs_buf **,
xfs_daddr_t, uint);
int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
xfs_inode_t **, xfs_daddr_t, uint);
@@ -514,8 +539,11 @@ int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
-void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *,
- int);
+void xfs_dinode_from_disk(struct xfs_icdinode *,
+ struct xfs_dinode_core *);
+void xfs_dinode_to_disk(struct xfs_dinode_core *,
+ struct xfs_icdinode *);
+
uint xfs_ip2xflags(struct xfs_inode *);
uint xfs_dic2xflags(struct xfs_dinode_core *);
int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
@@ -545,11 +573,9 @@ void xfs_ichgtime(xfs_inode_t *, int);
xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
-xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
-
void xfs_synchronize_atime(xfs_inode_t *);
-xfs_bmbt_rec_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
+xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t,
xfs_bmbt_irec_t *);
void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int);
@@ -564,7 +590,7 @@ void xfs_iext_indirect_to_direct(xfs_ifork_t *);
void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
void xfs_iext_destroy(xfs_ifork_t *);
-xfs_bmbt_rec_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
+xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *);
xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int);
void xfs_iext_irec_init(xfs_ifork_t *);
@@ -589,7 +615,7 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
#define xfs_inobp_check(mp, bp)
#endif /* DEBUG */
-extern struct kmem_zone *xfs_chashlist_zone;
+extern struct kmem_zone *xfs_icluster_zone;
extern struct kmem_zone *xfs_ifork_zone;
extern struct kmem_zone *xfs_inode_zone;
extern struct kmem_zone *xfs_ili_zone;
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index 81548ec72ba..b27b5d5be84 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -57,11 +57,11 @@ xfs_size_fn(
STATIC int
xfs_ioinit(
- struct bhv_vfs *vfsp,
+ struct xfs_mount *mp,
struct xfs_mount_args *mntargs,
int flags)
{
- return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp), flags);
+ return xfs_mountfs(mp, flags);
}
xfs_ioops_t xfs_iocore_xfs = {
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index bf57b75acb9..72786e356d5 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -135,14 +135,10 @@ xfs_imap_to_bmap(
int flags)
{
xfs_mount_t *mp;
- xfs_fsize_t nisize;
int pbm;
xfs_fsblock_t start_block;
mp = io->io_mount;
- nisize = XFS_SIZE(mp, io);
- if (io->io_new_size > nisize)
- nisize = io->io_new_size;
for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) {
iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
@@ -169,10 +165,6 @@ xfs_imap_to_bmap(
iomapp->iomap_flags |= IOMAP_UNWRITTEN;
}
- if ((iomapp->iomap_offset + iomapp->iomap_bsize) >= nisize) {
- iomapp->iomap_flags |= IOMAP_EOF;
- }
-
offset += iomapp->iomap_bsize - iomapp->iomap_delta;
}
return pbm; /* Return the number filled */
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index df441ee936b..f5c09887fe9 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -23,7 +23,6 @@
typedef enum { /* iomap_flags values */
IOMAP_READ = 0, /* mapping for a read */
- IOMAP_EOF = 0x01, /* mapping contains EOF */
IOMAP_HOLE = 0x02, /* mapping covers a hole */
IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
IOMAP_REALTIME = 0x10, /* mapping on the realtime device */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 4c2454bcc71..9972992fd3c 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -57,7 +57,7 @@ xfs_bulkstat_one_iget(
xfs_bstat_t *buf, /* return buffer */
int *stat) /* BULKSTAT_RV_... */
{
- xfs_dinode_core_t *dic; /* dinode core info pointer */
+ xfs_icdinode_t *dic; /* dinode core info pointer */
xfs_inode_t *ip; /* incore inode pointer */
bhv_vnode_t *vp;
int error;
@@ -151,37 +151,37 @@ xfs_bulkstat_one_dinode(
* the new format. We don't change the version number so that we
* can distinguish this from a real new format inode.
*/
- if (INT_GET(dic->di_version, ARCH_CONVERT) == XFS_DINODE_VERSION_1) {
- buf->bs_nlink = INT_GET(dic->di_onlink, ARCH_CONVERT);
+ if (dic->di_version == XFS_DINODE_VERSION_1) {
+ buf->bs_nlink = be16_to_cpu(dic->di_onlink);
buf->bs_projid = 0;
} else {
- buf->bs_nlink = INT_GET(dic->di_nlink, ARCH_CONVERT);
- buf->bs_projid = INT_GET(dic->di_projid, ARCH_CONVERT);
+ buf->bs_nlink = be32_to_cpu(dic->di_nlink);
+ buf->bs_projid = be16_to_cpu(dic->di_projid);
}
buf->bs_ino = ino;
- buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
- buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
- buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
- buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
- buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
- buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
- buf->bs_mtime.tv_sec = INT_GET(dic->di_mtime.t_sec, ARCH_CONVERT);
- buf->bs_mtime.tv_nsec = INT_GET(dic->di_mtime.t_nsec, ARCH_CONVERT);
- buf->bs_ctime.tv_sec = INT_GET(dic->di_ctime.t_sec, ARCH_CONVERT);
- buf->bs_ctime.tv_nsec = INT_GET(dic->di_ctime.t_nsec, ARCH_CONVERT);
+ buf->bs_mode = be16_to_cpu(dic->di_mode);
+ buf->bs_uid = be32_to_cpu(dic->di_uid);
+ buf->bs_gid = be32_to_cpu(dic->di_gid);
+ buf->bs_size = be64_to_cpu(dic->di_size);
+ buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec);
+ buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec);
+ buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec);
+ buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec);
+ buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec);
+ buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec);
buf->bs_xflags = xfs_dic2xflags(dic);
- buf->bs_extsize = INT_GET(dic->di_extsize, ARCH_CONVERT) << mp->m_sb.sb_blocklog;
- buf->bs_extents = INT_GET(dic->di_nextents, ARCH_CONVERT);
- buf->bs_gen = INT_GET(dic->di_gen, ARCH_CONVERT);
+ buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
+ buf->bs_extents = be32_to_cpu(dic->di_nextents);
+ buf->bs_gen = be32_to_cpu(dic->di_gen);
memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
- buf->bs_dmevmask = INT_GET(dic->di_dmevmask, ARCH_CONVERT);
- buf->bs_dmstate = INT_GET(dic->di_dmstate, ARCH_CONVERT);
- buf->bs_aextents = INT_GET(dic->di_anextents, ARCH_CONVERT);
+ buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask);
+ buf->bs_dmstate = be16_to_cpu(dic->di_dmstate);
+ buf->bs_aextents = be16_to_cpu(dic->di_anextents);
- switch (INT_GET(dic->di_format, ARCH_CONVERT)) {
+ switch (dic->di_format) {
case XFS_DINODE_FMT_DEV:
- buf->bs_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
+ buf->bs_rdev = be32_to_cpu(dip->di_u.di_dev);
buf->bs_blksize = BLKDEV_IOSIZE;
buf->bs_blocks = 0;
break;
@@ -195,7 +195,7 @@ xfs_bulkstat_one_dinode(
case XFS_DINODE_FMT_BTREE:
buf->bs_rdev = 0;
buf->bs_blksize = mp->m_sb.sb_blocksize;
- buf->bs_blocks = INT_GET(dic->di_nblocks, ARCH_CONVERT);
+ buf->bs_blocks = be64_to_cpu(dic->di_nblocks);
break;
}
@@ -290,16 +290,23 @@ xfs_bulkstat_use_dinode(
return 1;
dip = (xfs_dinode_t *)
xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
- if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC ||
- !XFS_DINODE_GOOD_VERSION(
- INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
+ /*
+ * Check the buffer containing the on-disk inode for di_nlink == 0.
+ * This is to prevent xfs_bulkstat from picking up just reclaimed
+ * inodes that have their in-core state initialized but not flushed
+ * to disk yet. This is a temporary hack that would require a proper
+ * fix in the future.
+ */
+ if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC ||
+ !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) ||
+ !dip->di_core.di_nlink)
return 0;
if (flags & BULKSTAT_FG_QUICK) {
*dipp = dip;
return 1;
}
/* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
- aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT);
+ aformat = dip->di_core.di_aformat;
if ((XFS_CFORK_Q(&dip->di_core) == 0) ||
(aformat == XFS_DINODE_FMT_LOCAL) ||
(aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) {
@@ -612,21 +619,25 @@ xfs_bulkstat(
}
}
}
+ ino = XFS_AGINO_TO_INO(mp, agno, agino);
+ bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
/*
* Skip if this inode is free.
*/
- if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free)
+ if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) {
+ lastino = ino;
continue;
+ }
/*
* Count used inodes as free so we can tell
* when the chunk is used up.
*/
irbp->ir_freecount++;
- ino = XFS_AGINO_TO_INO(mp, agno, agino);
- bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
if (!xfs_bulkstat_use_dinode(mp, flags, bp,
- clustidx, &dip))
+ clustidx, &dip)) {
+ lastino = ino;
continue;
+ }
/*
* If we need to do an iget, cannot hold bp.
* Drop it, until starting the next cluster.
@@ -687,8 +698,7 @@ xfs_bulkstat(
if (end_of_ag) {
agno++;
agino = 0;
- } else
- agino = XFS_INO_TO_AGINO(mp, lastino);
+ }
} else
break;
}
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 9bfb69e1e88..77c12715a7d 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -252,6 +252,29 @@ xlog_grant_add_space(struct log *log, int bytes)
xlog_grant_add_space_reserve(log, bytes);
}
+static void
+xlog_tic_reset_res(xlog_ticket_t *tic)
+{
+ tic->t_res_num = 0;
+ tic->t_res_arr_sum = 0;
+ tic->t_res_num_ophdrs = 0;
+}
+
+static void
+xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type)
+{
+ if (tic->t_res_num == XLOG_TIC_LEN_MAX) {
+ /* add to overflow and start again */
+ tic->t_res_o_flow += tic->t_res_arr_sum;
+ tic->t_res_num = 0;
+ tic->t_res_arr_sum = 0;
+ }
+
+ tic->t_res_arr[tic->t_res_num].r_len = len;
+ tic->t_res_arr[tic->t_res_num].r_type = type;
+ tic->t_res_arr_sum += len;
+ tic->t_res_num++;
+}
/*
* NOTES:
@@ -486,7 +509,7 @@ xfs_log_mount(xfs_mount_t *mp,
cmn_err(CE_NOTE,
"!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.",
mp->m_fsname);
- ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
+ ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
}
mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
@@ -496,16 +519,15 @@ xfs_log_mount(xfs_mount_t *mp,
* just worked.
*/
if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
- bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
- int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
+ int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
if (readonly)
- vfsp->vfs_flag &= ~VFS_RDONLY;
+ mp->m_flags &= ~XFS_MOUNT_RDONLY;
error = xlog_recover(mp->m_log);
if (readonly)
- vfsp->vfs_flag |= VFS_RDONLY;
+ mp->m_flags |= XFS_MOUNT_RDONLY;
if (error) {
cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
xlog_dealloc_log(mp->m_log);
@@ -537,7 +559,7 @@ xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags)
error = xlog_recover_finish(mp->m_log, mfsi_flags);
else {
error = 0;
- ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY);
+ ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
}
return error;
@@ -597,7 +619,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
* Don't write out unmount record on read-only mounts.
* Or, if we are doing a forced umount (typically because of IO errors).
*/
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC);
@@ -949,6 +971,19 @@ xlog_iodone(xfs_buf_t *bp)
l = iclog->ic_log;
/*
+ * If the ordered flag has been removed by a lower
+ * layer, it means the underlyin device no longer supports
+ * barrier I/O. Warn loudly and turn off barriers.
+ */
+ if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) {
+ l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
+ xfs_fs_cmn_err(CE_WARN, l->l_mp,
+ "xlog_iodone: Barriers are no longer supported"
+ " by device. Disabling barriers\n");
+ xfs_buftrace("XLOG_IODONE BARRIERS OFF", bp);
+ }
+
+ /*
* Race to shutdown the filesystem if we see an error.
*/
if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
@@ -1012,10 +1047,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp)
/*
* Return size of each in-core log record buffer.
*
- * Low memory machines only get 2 16KB buffers. We don't want to waste
- * memory here. However, all other machines get at least 2 32KB buffers.
- * The number is hard coded because we don't care about the minimum
- * memory size, just 32MB systems.
+ * All machines get 8 x 32KB buffers by default, unless tuned otherwise.
*
* If the filesystem blocksize is too large, we may need to choose a
* larger size since the directory code currently logs entire blocks.
@@ -1028,17 +1060,10 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
int size;
int xhdrs;
- if (mp->m_logbufs <= 0) {
- if (xfs_physmem <= btoc(128*1024*1024)) {
- log->l_iclog_bufs = XLOG_MIN_ICLOGS;
- } else if (xfs_physmem <= btoc(400*1024*1024)) {
- log->l_iclog_bufs = XLOG_MED_ICLOGS;
- } else { /* 256K with 32K bufs */
- log->l_iclog_bufs = XLOG_MAX_ICLOGS;
- }
- } else {
+ if (mp->m_logbufs <= 0)
+ log->l_iclog_bufs = XLOG_MAX_ICLOGS;
+ else
log->l_iclog_bufs = mp->m_logbufs;
- }
/*
* Buffer size passed in from mount system call.
@@ -1069,18 +1094,9 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
goto done;
}
- /*
- * Special case machines that have less than 32MB of memory.
- * All machines with more memory use 32KB buffers.
- */
- if (xfs_physmem <= btoc(32*1024*1024)) {
- /* Don't change; min configuration */
- log->l_iclog_size = XLOG_RECORD_BSIZE; /* 16k */
- log->l_iclog_size_log = XLOG_RECORD_BSHIFT;
- } else {
- log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; /* 32k */
- log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
- }
+ /* All machines use 32KB buffers by default. */
+ log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
+ log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
/* the default log size is 16k or 32k which is one header sector */
log->l_iclog_hsize = BBSIZE;
@@ -1771,14 +1787,14 @@ xlog_write(xfs_mount_t * mp,
len = 0;
if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */
len += sizeof(xlog_op_header_t);
- XLOG_TIC_ADD_OPHDR(ticket);
+ ticket->t_res_num_ophdrs++;
}
for (index = 0; index < nentries; index++) {
len += sizeof(xlog_op_header_t); /* each region gets >= 1 */
- XLOG_TIC_ADD_OPHDR(ticket);
+ ticket->t_res_num_ophdrs++;
len += reg[index].i_len;
- XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type);
+ xlog_tic_add_region(ticket, reg[index].i_len, reg[index].i_type);
}
contwr = *start_lsn = 0;
@@ -1887,7 +1903,7 @@ xlog_write(xfs_mount_t * mp,
len += sizeof(xlog_op_header_t); /* from splitting of region */
/* account for new log op header */
ticket->t_curr_res -= sizeof(xlog_op_header_t);
- XLOG_TIC_ADD_OPHDR(ticket);
+ ticket->t_res_num_ophdrs++;
}
xlog_verify_dest_ptr(log, ptr);
@@ -2385,7 +2401,7 @@ restart:
*/
if (log_offset == 0) {
ticket->t_curr_res -= log->l_iclog_hsize;
- XLOG_TIC_ADD_REGION(ticket,
+ xlog_tic_add_region(ticket,
log->l_iclog_hsize,
XLOG_REG_TYPE_LRHEADER);
INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
@@ -2573,7 +2589,7 @@ xlog_regrant_write_log_space(xlog_t *log,
#endif
tic->t_curr_res = tic->t_unit_res;
- XLOG_TIC_RESET_RES(tic);
+ xlog_tic_reset_res(tic);
if (tic->t_cnt > 0)
return 0;
@@ -2714,7 +2730,7 @@ xlog_regrant_reserve_log_space(xlog_t *log,
s = GRANT_LOCK(log);
xlog_grant_sub_space(log, ticket->t_curr_res);
ticket->t_curr_res = ticket->t_unit_res;
- XLOG_TIC_RESET_RES(ticket);
+ xlog_tic_reset_res(ticket);
xlog_trace_loggrant(log, ticket,
"xlog_regrant_reserve_log_space: sub current res");
xlog_verify_grant_head(log, 1);
@@ -2731,7 +2747,7 @@ xlog_regrant_reserve_log_space(xlog_t *log,
xlog_verify_grant_head(log, 0);
GRANT_UNLOCK(log, s);
ticket->t_curr_res = ticket->t_unit_res;
- XLOG_TIC_RESET_RES(ticket);
+ xlog_tic_reset_res(ticket);
} /* xlog_regrant_reserve_log_space */
@@ -3354,7 +3370,7 @@ xlog_ticket_get(xlog_t *log,
tic->t_flags |= XLOG_TIC_PERM_RESERV;
sv_init(&(tic->t_sema), SV_DEFAULT, "logtick");
- XLOG_TIC_RESET_RES(tic);
+ xlog_tic_reset_res(tic);
return tic;
} /* xlog_ticket_get */
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 9bd3cdf11a8..752f964b369 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -30,17 +30,16 @@ struct xfs_mount;
*/
#define XLOG_MIN_ICLOGS 2
-#define XLOG_MED_ICLOGS 4
#define XLOG_MAX_ICLOGS 8
#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
#define XLOG_VERSION_1 1
#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
-#define XLOG_RECORD_BSIZE (16*1024) /* eventually 32k */
+#define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */
#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */
#define XLOG_MAX_RECORD_BSIZE (256*1024)
#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */
-#define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
+#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
@@ -250,22 +249,6 @@ typedef __uint32_t xlog_tid_t;
/* Ticket reservation region accounting */
#define XLOG_TIC_LEN_MAX 15
-#define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \
- (t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0)
-#define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++)
-#define XLOG_TIC_ADD_REGION(t, len, type) \
- do { \
- if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \
- /* add to overflow and start again */ \
- (t)->t_res_o_flow += (t)->t_res_arr_sum; \
- (t)->t_res_num = 0; \
- (t)->t_res_arr_sum = 0; \
- } \
- (t)->t_res_arr[(t)->t_res_num].r_len = (len); \
- (t)->t_res_arr[(t)->t_res_num].r_type = (type); \
- (t)->t_res_arr_sum += (len); \
- (t)->t_res_num++; \
- } while (0)
/*
* Reservation region
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 8ae6e8e5f3d..851eca8a715 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2245,7 +2245,7 @@ xlog_recover_do_inode_trans(
int error;
int attr_index;
uint fields;
- xfs_dinode_core_t *dicp;
+ xfs_icdinode_t *dicp;
int need_free = 0;
if (pass == XLOG_RECOVER_PASS1) {
@@ -2309,7 +2309,7 @@ xlog_recover_do_inode_trans(
* Make sure the place we're flushing out to really looks
* like an inode!
*/
- if (unlikely(INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC)) {
+ if (unlikely(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC)) {
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
@@ -2319,7 +2319,7 @@ xlog_recover_do_inode_trans(
error = EFSCORRUPTED;
goto error;
}
- dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
+ dicp = (xfs_icdinode_t *)(item->ri_buf[1].i_addr);
if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
@@ -2332,15 +2332,13 @@ xlog_recover_do_inode_trans(
}
/* Skip replay when the on disk inode is newer than the log one */
- if (dicp->di_flushiter <
- INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)) {
+ if (dicp->di_flushiter < be16_to_cpu(dip->di_core.di_flushiter)) {
/*
* Deal with the wrap case, DI_MAX_FLUSH is less
* than smaller numbers
*/
- if ((INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)
- == DI_MAX_FLUSH) &&
- (dicp->di_flushiter < (DI_MAX_FLUSH>>1))) {
+ if (be16_to_cpu(dip->di_core.di_flushiter) == DI_MAX_FLUSH &&
+ dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) {
/* do nothing */
} else {
xfs_buf_relse(bp);
@@ -2411,8 +2409,8 @@ xlog_recover_do_inode_trans(
}
/* The core is in in-core format */
- xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core,
- (xfs_dinode_core_t*)item->ri_buf[1].i_addr, -1);
+ xfs_dinode_to_disk(&dip->di_core,
+ (xfs_icdinode_t *)item->ri_buf[1].i_addr);
/* the rest is in on-disk format */
if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) {
@@ -2424,8 +2422,7 @@ xlog_recover_do_inode_trans(
fields = in_f->ilf_fields;
switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
case XFS_ILOG_DEV:
- INT_SET(dip->di_u.di_dev, ARCH_CONVERT, in_f->ilf_u.ilfu_rdev);
-
+ dip->di_u.di_dev = cpu_to_be32(in_f->ilf_u.ilfu_rdev);
break;
case XFS_ILOG_UUID:
dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid;
@@ -3234,8 +3231,8 @@ xlog_recover_process_iunlinks(
ASSERT(ip->i_d.di_nlink == 0);
/* setup for the next pass */
- agino = INT_GET(dip->di_next_unlinked,
- ARCH_CONVERT);
+ agino = be32_to_cpu(
+ dip->di_next_unlinked);
xfs_buf_relse(ibp);
/*
* Prevent any DMAPI event from
@@ -3837,7 +3834,10 @@ xlog_do_recover(
*/
bp = xfs_getsb(log->l_mp, 0);
XFS_BUF_UNDONE(bp);
+ ASSERT(!(XFS_BUF_ISWRITE(bp)));
+ ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
XFS_BUF_READ(bp);
+ XFS_BUF_UNASYNC(bp);
xfsbdstrat(log->l_mp, bp);
if ((error = xfs_iowait(bp))) {
xfs_ioerror_alert("xlog_do_recover",
@@ -3849,7 +3849,7 @@ xlog_do_recover(
/* Convert superblock from on-disk format */
sbp = &log->l_mp->m_sb;
- xfs_xlatesb(XFS_BUF_TO_SBP(bp), sbp, 1, XFS_SB_ALL_BITS);
+ xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
ASSERT(XFS_SB_GOOD_VERSION(sbp));
xfs_buf_relse(bp);
@@ -4027,7 +4027,7 @@ xlog_recover_check_summary(
sbbp = xfs_getsb(mp, 0);
#ifdef XFS_LOUD_RECOVERY
sbp = &mp->m_sb;
- xfs_xlatesb(XFS_BUF_TO_SBP(sbbp), sbp, 1, XFS_SB_ALL_BITS);
+ xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(sbbp));
cmn_err(CE_NOTE,
"xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
sbp->sb_icount, itotal);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index a66b3980517..ebdb76da527 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -139,7 +139,7 @@ xfs_mount_init(void)
AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail");
spinlock_init(&mp->m_sb_lock, "xfs_sb");
mutex_init(&mp->m_ilock);
- initnsema(&mp->m_growlock, 1, "xfs_grow");
+ mutex_init(&mp->m_growlock);
/*
* Initialize the AIL.
*/
@@ -157,14 +157,8 @@ xfs_mount_init(void)
*/
void
xfs_mount_free(
- xfs_mount_t *mp,
- int remove_bhv)
+ xfs_mount_t *mp)
{
- if (mp->m_ihash)
- xfs_ihash_free(mp);
- if (mp->m_chash)
- xfs_chash_free(mp);
-
if (mp->m_perag) {
int agno;
@@ -180,7 +174,7 @@ xfs_mount_free(
AIL_LOCK_DESTROY(&mp->m_ail_lock);
spinlock_destroy(&mp->m_sb_lock);
mutex_destroy(&mp->m_ilock);
- freesema(&mp->m_growlock);
+ mutex_destroy(&mp->m_growlock);
if (mp->m_quotainfo)
XFS_QM_DONE(mp);
@@ -191,15 +185,7 @@ xfs_mount_free(
if (mp->m_logname != NULL)
kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
- if (remove_bhv) {
- struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
-
- bhv_remove_all_vfsops(vfsp, 0);
- VFS_REMOVEBHV(vfsp, &mp->m_bhv);
- }
-
xfs_icsb_destroy_counters(mp);
- kmem_free(mp, sizeof(xfs_mount_t));
}
/*
@@ -342,9 +328,19 @@ xfs_mount_validate_sb(
return 0;
}
+STATIC void
+xfs_initialize_perag_icache(
+ xfs_perag_t *pag)
+{
+ if (!pag->pag_ici_init) {
+ rwlock_init(&pag->pag_ici_lock);
+ INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
+ pag->pag_ici_init = 1;
+ }
+}
+
xfs_agnumber_t
xfs_initialize_perag(
- bhv_vfs_t *vfs,
xfs_mount_t *mp,
xfs_agnumber_t agcount)
{
@@ -362,7 +358,7 @@ xfs_initialize_perag(
/* Clear the mount flag if no inode can overflow 32 bits
* on this filesystem, or if specifically requested..
*/
- if ((vfs->vfs_flag & VFS_32BITINODES) && ino > max_inum) {
+ if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) {
mp->m_flags |= XFS_MOUNT_32BITINODES;
} else {
mp->m_flags &= ~XFS_MOUNT_32BITINODES;
@@ -396,48 +392,92 @@ xfs_initialize_perag(
pag->pagi_inodeok = 1;
if (index < max_metadata)
pag->pagf_metadata = 1;
+ xfs_initialize_perag_icache(pag);
}
} else {
/* Setup default behavior for smaller filesystems */
for (index = 0; index < agcount; index++) {
pag = &mp->m_perag[index];
pag->pagi_inodeok = 1;
+ xfs_initialize_perag_icache(pag);
}
}
return index;
}
+void
+xfs_sb_from_disk(
+ xfs_sb_t *to,
+ xfs_dsb_t *from)
+{
+ to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
+ to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
+ to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
+ to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
+ to->sb_rextents = be64_to_cpu(from->sb_rextents);
+ memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
+ to->sb_logstart = be64_to_cpu(from->sb_logstart);
+ to->sb_rootino = be64_to_cpu(from->sb_rootino);
+ to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
+ to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
+ to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
+ to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
+ to->sb_agcount = be32_to_cpu(from->sb_agcount);
+ to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
+ to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
+ to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
+ to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
+ to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
+ to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
+ memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
+ to->sb_blocklog = from->sb_blocklog;
+ to->sb_sectlog = from->sb_sectlog;
+ to->sb_inodelog = from->sb_inodelog;
+ to->sb_inopblog = from->sb_inopblog;
+ to->sb_agblklog = from->sb_agblklog;
+ to->sb_rextslog = from->sb_rextslog;
+ to->sb_inprogress = from->sb_inprogress;
+ to->sb_imax_pct = from->sb_imax_pct;
+ to->sb_icount = be64_to_cpu(from->sb_icount);
+ to->sb_ifree = be64_to_cpu(from->sb_ifree);
+ to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
+ to->sb_frextents = be64_to_cpu(from->sb_frextents);
+ to->sb_uquotino = be64_to_cpu(from->sb_uquotino);
+ to->sb_gquotino = be64_to_cpu(from->sb_gquotino);
+ to->sb_qflags = be16_to_cpu(from->sb_qflags);
+ to->sb_flags = from->sb_flags;
+ to->sb_shared_vn = from->sb_shared_vn;
+ to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt);
+ to->sb_unit = be32_to_cpu(from->sb_unit);
+ to->sb_width = be32_to_cpu(from->sb_width);
+ to->sb_dirblklog = from->sb_dirblklog;
+ to->sb_logsectlog = from->sb_logsectlog;
+ to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
+ to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
+ to->sb_features2 = be32_to_cpu(from->sb_features2);
+}
+
/*
- * xfs_xlatesb
+ * Copy in core superblock to ondisk one.
*
- * data - on disk version of sb
- * sb - a superblock
- * dir - conversion direction: <0 - convert sb to buf
- * >0 - convert buf to sb
- * fields - which fields to copy (bitmask)
+ * The fields argument is mask of superblock fields to copy.
*/
void
-xfs_xlatesb(
- void *data,
- xfs_sb_t *sb,
- int dir,
+xfs_sb_to_disk(
+ xfs_dsb_t *to,
+ xfs_sb_t *from,
__int64_t fields)
{
- xfs_caddr_t buf_ptr;
- xfs_caddr_t mem_ptr;
+ xfs_caddr_t to_ptr = (xfs_caddr_t)to;
+ xfs_caddr_t from_ptr = (xfs_caddr_t)from;
xfs_sb_field_t f;
int first;
int size;
- ASSERT(dir);
ASSERT(fields);
-
if (!fields)
return;
- buf_ptr = (xfs_caddr_t)data;
- mem_ptr = (xfs_caddr_t)sb;
-
while (fields) {
f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
first = xfs_sb_info[f].offset;
@@ -446,26 +486,20 @@ xfs_xlatesb(
ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
if (size == 1 || xfs_sb_info[f].type == 1) {
- if (dir > 0) {
- memcpy(mem_ptr + first, buf_ptr + first, size);
- } else {
- memcpy(buf_ptr + first, mem_ptr + first, size);
- }
+ memcpy(to_ptr + first, from_ptr + first, size);
} else {
switch (size) {
case 2:
- INT_XLATE(*(__uint16_t*)(buf_ptr+first),
- *(__uint16_t*)(mem_ptr+first),
- dir, ARCH_CONVERT);
+ *(__be16 *)(to_ptr + first) =
+ cpu_to_be16(*(__u16 *)(from_ptr + first));
break;
case 4:
- INT_XLATE(*(__uint32_t*)(buf_ptr+first),
- *(__uint32_t*)(mem_ptr+first),
- dir, ARCH_CONVERT);
+ *(__be32 *)(to_ptr + first) =
+ cpu_to_be32(*(__u32 *)(from_ptr + first));
break;
case 8:
- INT_XLATE(*(__uint64_t*)(buf_ptr+first),
- *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT);
+ *(__be64 *)(to_ptr + first) =
+ cpu_to_be64(*(__u64 *)(from_ptr + first));
break;
default:
ASSERT(0);
@@ -487,7 +521,6 @@ xfs_readsb(xfs_mount_t *mp, int flags)
unsigned int sector_size;
unsigned int extra_flags;
xfs_buf_t *bp;
- xfs_sb_t *sbp;
int error;
ASSERT(mp->m_sb_bp == NULL);
@@ -515,8 +548,7 @@ xfs_readsb(xfs_mount_t *mp, int flags)
* Initialize the mount structure from the superblock.
* But first do some basic consistency checking.
*/
- sbp = XFS_BUF_TO_SBP(bp);
- xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS);
+ xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);
if (error) {
@@ -715,7 +747,6 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
*/
int
xfs_mountfs(
- bhv_vfs_t *vfsp,
xfs_mount_t *mp,
int mfsi_flags)
{
@@ -842,14 +873,11 @@ xfs_mountfs(
*/
if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
(mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
- __uint64_t ret64;
if (xfs_uuid_mount(mp)) {
error = XFS_ERROR(EINVAL);
goto error1;
}
uuid_mounted=1;
- ret64 = uuid_hash64(&sbp->sb_uuid);
- memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
}
/*
@@ -871,16 +899,6 @@ xfs_mountfs(
writeio_log = mp->m_writeio_log;
}
- /*
- * Set the number of readahead buffers to use based on
- * physical memory size.
- */
- if (xfs_physmem <= 4096) /* <= 16MB */
- mp->m_nreadaheads = XFS_RW_NREADAHEAD_16MB;
- else if (xfs_physmem <= 8192) /* <= 32MB */
- mp->m_nreadaheads = XFS_RW_NREADAHEAD_32MB;
- else
- mp->m_nreadaheads = XFS_RW_NREADAHEAD_K32;
if (sbp->sb_blocklog > readio_log) {
mp->m_readio_log = sbp->sb_blocklog;
} else {
@@ -895,15 +913,12 @@ xfs_mountfs(
mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);
/*
- * Set the inode cluster size based on the physical memory
- * size. This may still be overridden by the file system
+ * Set the inode cluster size.
+ * This may still be overridden by the file system
* block size if it is larger than the chosen cluster size.
*/
- if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */
- mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE;
- } else {
- mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
- }
+ mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
+
/*
* Set whether we're using inode alignment.
*/
@@ -987,16 +1002,6 @@ xfs_mountfs(
*/
uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid);
- /*
- * The vfs structure needs to have a file system independent
- * way of checking for the invariant file system ID. Since it
- * can't look at mount structures it has a pointer to the data
- * in the mount structure.
- *
- * File systems that don't support user level file handles (i.e.
- * all of them except for XFS) will leave vfs_altfsid as NULL.
- */
- vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
mp->m_dmevmask = 0; /* not persistent; set after each mount */
xfs_dir_mount(mp);
@@ -1012,20 +1017,13 @@ xfs_mountfs(
xfs_trans_init(mp);
/*
- * Allocate and initialize the inode hash table for this
- * file system.
- */
- xfs_ihash_init(mp);
- xfs_chash_init(mp);
-
- /*
* Allocate and initialize the per-ag data.
*/
init_rwsem(&mp->m_peraglock);
mp->m_perag =
kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP);
- mp->m_maxagi = xfs_initialize_perag(vfsp, mp, sbp->sb_agcount);
+ mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
/*
* log's mount-time initialization. Perform 1st part recovery if needed
@@ -1116,7 +1114,7 @@ xfs_mountfs(
* If fs is not mounted readonly, then update the superblock
* unit and width changes.
*/
- if (update_flags && !(vfsp->vfs_flag & VFS_RDONLY))
+ if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY))
xfs_mount_log_sbunit(mp, update_flags);
/*
@@ -1169,8 +1167,6 @@ xfs_mountfs(
error3:
xfs_log_unmount_dealloc(mp);
error2:
- xfs_ihash_free(mp);
- xfs_chash_free(mp);
for (agno = 0; agno < sbp->sb_agcount; agno++)
if (mp->m_perag[agno].pagb_list)
kmem_free(mp->m_perag[agno].pagb_list,
@@ -1194,10 +1190,6 @@ xfs_mountfs(
int
xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
{
- struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
-#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
- int64_t fsid;
-#endif
__uint64_t resblks;
/*
@@ -1261,21 +1253,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
xfs_uuid_unmount(mp);
#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
- /*
- * clear all error tags on this filesystem
- */
- memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t));
- xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0);
+ xfs_errortag_clearall(mp, 0);
#endif
- XFS_IODONE(vfsp);
- xfs_mount_free(mp, 1);
+ XFS_IODONE(mp);
+ xfs_mount_free(mp);
return 0;
}
void
xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
{
- if (mp->m_logdev_targp != mp->m_ddev_targp)
+ if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
xfs_free_buftarg(mp->m_logdev_targp, 1);
if (mp->m_rtdev_targp)
xfs_free_buftarg(mp->m_rtdev_targp, 1);
@@ -1295,10 +1283,8 @@ xfs_unmountfs_wait(xfs_mount_t *mp)
int
xfs_fs_writable(xfs_mount_t *mp)
{
- bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
-
- return !(vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
- (vfsp->vfs_flag & VFS_RDONLY));
+ return !(xfs_test_for_freeze(mp) || XFS_FORCED_SHUTDOWN(mp) ||
+ (mp->m_flags & XFS_MOUNT_RDONLY));
}
/*
@@ -1348,34 +1334,44 @@ xfs_log_sbcount(
return 0;
}
+STATIC void
+xfs_mark_shared_ro(
+ xfs_mount_t *mp,
+ xfs_buf_t *bp)
+{
+ xfs_dsb_t *sb = XFS_BUF_TO_SBP(bp);
+ __uint16_t version;
+
+ if (!(sb->sb_flags & XFS_SBF_READONLY))
+ sb->sb_flags |= XFS_SBF_READONLY;
+
+ version = be16_to_cpu(sb->sb_versionnum);
+ if ((version & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4 ||
+ !(version & XFS_SB_VERSION_SHAREDBIT))
+ version |= XFS_SB_VERSION_SHAREDBIT;
+ sb->sb_versionnum = cpu_to_be16(version);
+}
+
int
xfs_unmountfs_writesb(xfs_mount_t *mp)
{
xfs_buf_t *sbp;
- xfs_sb_t *sb;
int error = 0;
/*
* skip superblock write if fs is read-only, or
* if we are doing a forced umount.
*/
- if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY ||
+ if (!((mp->m_flags & XFS_MOUNT_RDONLY) ||
XFS_FORCED_SHUTDOWN(mp))) {
sbp = xfs_getsb(mp, 0);
- sb = XFS_BUF_TO_SBP(sbp);
/*
* mark shared-readonly if desired
*/
- if (mp->m_mk_sharedro) {
- if (!(sb->sb_flags & XFS_SBF_READONLY))
- sb->sb_flags |= XFS_SBF_READONLY;
- if (!XFS_SB_VERSION_HASSHARED(sb))
- XFS_SB_VERSION_ADDSHARED(sb);
- xfs_fs_cmn_err(CE_NOTE, mp,
- "Unmounting, marking shared read-only");
- }
+ if (mp->m_mk_sharedro)
+ xfs_mark_shared_ro(mp, sbp);
XFS_BUF_UNDONE(sbp);
XFS_BUF_UNREAD(sbp);
@@ -1410,7 +1406,6 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
int first;
int last;
xfs_mount_t *mp;
- xfs_sb_t *sbp;
xfs_sb_field_t f;
ASSERT(fields);
@@ -1418,13 +1413,12 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
return;
mp = tp->t_mountp;
bp = xfs_trans_getsb(tp, mp, 0);
- sbp = XFS_BUF_TO_SBP(bp);
first = sizeof(xfs_sb_t);
last = 0;
/* translate/copy */
- xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields);
+ xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
/* find modified range */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 76ad7475869..c618f7cb5f0 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -54,13 +54,8 @@ typedef struct xfs_trans_reservations {
#else
struct cred;
struct log;
-struct bhv_vfs;
-struct bhv_vnode;
struct xfs_mount_args;
-struct xfs_ihash;
-struct xfs_chash;
struct xfs_inode;
-struct xfs_perag;
struct xfs_iocore;
struct xfs_bmbt_irec;
struct xfs_bmap_free;
@@ -68,9 +63,6 @@ struct xfs_extdelta;
struct xfs_swapext;
struct xfs_mru_cache;
-extern struct bhv_vfsops xfs_vfsops;
-extern struct bhv_vnodeops xfs_vnodeops;
-
#define AIL_LOCK_T lock_t
#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
#define AIL_LOCK_DESTROY(x) spinlock_destroy(x)
@@ -82,15 +74,17 @@ extern struct bhv_vnodeops xfs_vnodeops;
* Prototypes and functions for the Data Migration subsystem.
*/
-typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
+typedef int (*xfs_send_data_t)(int, bhv_vnode_t *,
xfs_off_t, size_t, int, bhv_vrwlock_t *);
typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
-typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t);
-typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
- struct bhv_vnode *,
- dm_right_t, struct bhv_vnode *, dm_right_t,
+typedef int (*xfs_send_destroy_t)(bhv_vnode_t *, dm_right_t);
+typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *,
+ bhv_vnode_t *,
+ dm_right_t, bhv_vnode_t *, dm_right_t,
char *, char *, mode_t, int, int);
-typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *,
+typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t,
+ char *, char *);
+typedef void (*xfs_send_unmount_t)(struct xfs_mount *, bhv_vnode_t *,
dm_right_t, mode_t, int, int);
typedef struct xfs_dmops {
@@ -98,21 +92,24 @@ typedef struct xfs_dmops {
xfs_send_mmap_t xfs_send_mmap;
xfs_send_destroy_t xfs_send_destroy;
xfs_send_namesp_t xfs_send_namesp;
+ xfs_send_mount_t xfs_send_mount;
xfs_send_unmount_t xfs_send_unmount;
} xfs_dmops_t;
#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \
- (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock)
+ (*(mp)->m_dm_ops->xfs_send_data)(ev,vp,off,len,fl,lock)
#define XFS_SEND_MMAP(mp, vma,fl) \
- (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl)
+ (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl)
#define XFS_SEND_DESTROY(mp, vp,right) \
- (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right)
+ (*(mp)->m_dm_ops->xfs_send_destroy)(vp,right)
#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
- (*(mp)->m_dm_ops.xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl)
-#define XFS_SEND_PREUNMOUNT(mp, vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
- (*(mp)->m_dm_ops.xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl)
-#define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \
- (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl)
+ (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl)
+#define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
+ (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl)
+#define XFS_SEND_MOUNT(mp,right,path,name) \
+ (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name)
+#define XFS_SEND_UNMOUNT(mp, vp,right,mode,rval,fl) \
+ (*(mp)->m_dm_ops->xfs_send_unmount)(mp,vp,right,mode,rval,fl)
/*
@@ -142,6 +139,9 @@ typedef struct xfs_dquot * (*xfs_dqvopchown_t)(
struct xfs_dquot **, struct xfs_dquot *);
typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot *, struct xfs_dquot *, uint);
+typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *);
+typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags);
+typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t);
typedef struct xfs_qmops {
xfs_qminit_t xfs_qminit;
@@ -157,42 +157,51 @@ typedef struct xfs_qmops {
xfs_dqvoprename_t xfs_dqvoprename;
xfs_dqvopchown_t xfs_dqvopchown;
xfs_dqvopchownresv_t xfs_dqvopchownresv;
+ xfs_dqstatvfs_t xfs_dqstatvfs;
+ xfs_dqsync_t xfs_dqsync;
+ xfs_quotactl_t xfs_quotactl;
struct xfs_dqtrxops *xfs_dqtrxops;
} xfs_qmops_t;
#define XFS_QM_INIT(mp, mnt, fl) \
- (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl)
+ (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl)
#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \
- (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags)
+ (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl, mfsi_flags)
#define XFS_QM_UNMOUNT(mp) \
- (*(mp)->m_qm_ops.xfs_qmunmount)(mp)
+ (*(mp)->m_qm_ops->xfs_qmunmount)(mp)
#define XFS_QM_DONE(mp) \
- (*(mp)->m_qm_ops.xfs_qmdone)(mp)
+ (*(mp)->m_qm_ops->xfs_qmdone)(mp)
#define XFS_QM_DQRELE(mp, dq) \
- (*(mp)->m_qm_ops.xfs_dqrele)(dq)
+ (*(mp)->m_qm_ops->xfs_dqrele)(dq)
#define XFS_QM_DQATTACH(mp, ip, fl) \
- (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl)
+ (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl)
#define XFS_QM_DQDETACH(mp, ip) \
- (*(mp)->m_qm_ops.xfs_dqdetach)(ip)
+ (*(mp)->m_qm_ops->xfs_dqdetach)(ip)
#define XFS_QM_DQPURGEALL(mp, fl) \
- (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
+ (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl)
#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
- (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
+ (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
- (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
+ (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2)
#define XFS_QM_DQVOPRENAME(mp, ip) \
- (*(mp)->m_qm_ops.xfs_dqvoprename)(ip)
+ (*(mp)->m_qm_ops->xfs_dqvoprename)(ip)
#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \
- (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq)
+ (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq)
#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \
- (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
+ (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
+#define XFS_QM_DQSTATVFS(ip, statp) \
+ (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp)
+#define XFS_QM_DQSYNC(mp, flags) \
+ (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags)
+#define XFS_QM_QUOTACTL(mp, cmd, id, addr) \
+ (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr)
/*
* Prototypes and functions for I/O core modularization.
*/
-typedef int (*xfs_ioinit_t)(struct bhv_vfs *,
+typedef int (*xfs_ioinit_t)(struct xfs_mount *,
struct xfs_mount_args *, int);
typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
xfs_fileoff_t, xfs_filblks_t, int,
@@ -222,7 +231,7 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
typedef int (*xfs_lock_nowait_t)(void *, uint);
typedef void (*xfs_unlk_t)(void *, unsigned int);
typedef xfs_fsize_t (*xfs_size_t)(void *);
-typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *);
+typedef xfs_fsize_t (*xfs_iodone_t)(struct xfs_mount *);
typedef int (*xfs_swap_extents_t)(void *, void *,
struct xfs_swapext*);
@@ -245,8 +254,8 @@ typedef struct xfs_ioops {
xfs_swap_extents_t xfs_swap_extents_func;
} xfs_ioops_t;
-#define XFS_IOINIT(vfsp, args, flags) \
- (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
+#define XFS_IOINIT(mp, args, flags) \
+ (*(mp)->m_io_ops.xfs_ioinit)(mp, args, flags)
#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
(*(mp)->m_io_ops.xfs_bmapi_func) \
(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
@@ -280,8 +289,8 @@ typedef struct xfs_ioops {
(*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode)
#define XFS_SIZE(mp, io) \
(*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
-#define XFS_IODONE(vfsp) \
- (*(mp)->m_io_ops.xfs_iodone)(vfsp)
+#define XFS_IODONE(mp) \
+ (*(mp)->m_io_ops.xfs_iodone)(mp)
#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
(*(mp)->m_io_ops.xfs_swap_extents_func) \
((io)->io_obj, (tio)->io_obj, sxp)
@@ -318,7 +327,7 @@ extern void xfs_icsb_sync_counters_flags(struct xfs_mount *, int);
#endif
typedef struct xfs_mount {
- bhv_desc_t m_bhv; /* vfs xfs behavior */
+ struct super_block *m_super;
xfs_tid_t m_tid; /* next unused tid for fs */
AIL_LOCK_T m_ail_lock; /* fs AIL mutex */
xfs_ail_entry_t m_ail; /* fs active log item list */
@@ -335,8 +344,6 @@ typedef struct xfs_mount {
xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
lock_t m_agirotor_lock;/* .. and lock protecting it */
xfs_agnumber_t m_maxagi; /* highest inode alloc group */
- size_t m_ihsize; /* size of next field */
- struct xfs_ihash *m_ihash; /* fs private inode hash table*/
struct xfs_inode *m_inodes; /* active inode list */
struct list_head m_del_inodes; /* inodes to reclaim */
mutex_t m_ilock; /* inode list mutex */
@@ -362,7 +369,6 @@ typedef struct xfs_mount {
__uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
__uint8_t m_agno_log; /* log #ag's */
__uint8_t m_agino_log; /* #bits for agino in inum */
- __uint8_t m_nreadaheads; /* #readahead buffers */
__uint16_t m_inode_cluster_size;/* min inode buf size */
uint m_blockmask; /* sb_blocksize-1 */
uint m_blockwsize; /* sb_blocksize in words */
@@ -378,7 +384,7 @@ typedef struct xfs_mount {
uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */
struct xfs_perag *m_perag; /* per-ag accounting info */
struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */
- sema_t m_growlock; /* growfs mutex */
+ struct mutex m_growlock; /* growfs mutex */
int m_fixedfsid[2]; /* unchanged for life of FS */
uint m_dmevmask; /* DMI events for this FS */
__uint64_t m_flags; /* global mount flags */
@@ -415,8 +421,8 @@ typedef struct xfs_mount {
uint m_chsize; /* size of next field */
struct xfs_chash *m_chash; /* fs private inode per-cluster
* hash table */
- struct xfs_dmops m_dm_ops; /* vector of DMI ops */
- struct xfs_qmops m_qm_ops; /* vector of XQM ops */
+ struct xfs_dmops *m_dm_ops; /* vector of DMI ops */
+ struct xfs_qmops *m_qm_ops; /* vector of XQM ops */
struct xfs_ioops m_io_ops; /* vector of I/O ops */
atomic_t m_active_trans; /* number trans frozen */
#ifdef HAVE_PERCPU_SB
@@ -426,6 +432,12 @@ typedef struct xfs_mount {
struct mutex m_icsb_mutex; /* balancer sync lock */
#endif
struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
+ struct task_struct *m_sync_task; /* generalised sync thread */
+ bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */
+ struct list_head m_sync_list; /* sync thread work item list */
+ spinlock_t m_sync_lock; /* work item list lock */
+ int m_sync_seq; /* sync thread generation no. */
+ wait_queue_head_t m_wait_single_sync_task;
} xfs_mount_t;
/*
@@ -435,7 +447,7 @@ typedef struct xfs_mount {
must be synchronous except
for space allocations */
#define XFS_MOUNT_INO64 (1ULL << 1)
- /* (1ULL << 2) -- currently unused */
+#define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */
#define XFS_MOUNT_WAS_CLEAN (1ULL << 3)
#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
operations, typically for
@@ -445,7 +457,7 @@ typedef struct xfs_mount {
#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
allocations */
#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */
- /* (1ULL << 9) -- currently unused */
+#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */
#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
#define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */
#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
@@ -453,13 +465,13 @@ typedef struct xfs_mount {
/* osyncisdsync is now default*/
#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above
* 32 bits in size */
- /* (1ULL << 15) -- currently unused */
+#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
#define XFS_MOUNT_BARRIER (1ULL << 17)
#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/
#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width
* allocation */
-#define XFS_MOUNT_IHASHSIZE (1ULL << 20) /* inode hash table size */
+#define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */
#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */
#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred
* I/O size in stat() */
@@ -518,8 +530,10 @@ xfs_preferred_iosize(xfs_mount_t *mp)
#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \
((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
+void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
+ int lnnum);
#define xfs_force_shutdown(m,f) \
- bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
+ xfs_do_force_shutdown(m, f, __FILE__, __LINE__)
/*
* Flags for xfs_mountfs
@@ -533,28 +547,6 @@ xfs_preferred_iosize(xfs_mount_t *mp)
/* XFS_MFSI_CONVERT_SUNIT */
#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */
-/*
- * Macros for getting from mount to vfs and back.
- */
-#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
-static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
-{
- return bhvtovfs(&mp->m_bhv);
-}
-
-#define XFS_BHVTOM(bdp) xfs_bhvtom(bdp)
-static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
-{
- return (xfs_mount_t *)BHV_PDATA(bdp);
-}
-
-#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
-static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
-{
- return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs),
- VFS_POSITION_XFS, VFS_POSITION_XFS));
-}
-
#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d)
static inline xfs_agnumber_t
xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d)
@@ -573,6 +565,21 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
}
/*
+ * perag get/put wrappers for eventual ref counting
+ */
+static inline xfs_perag_t *
+xfs_get_perag(struct xfs_mount *mp, xfs_ino_t ino)
+{
+ return &mp->m_perag[XFS_INO_TO_AGNO(mp, ino)];
+}
+
+static inline void
+xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag)
+{
+ /* nothing to see here, move along */
+}
+
+/*
* Per-cpu superblock locking functions
*/
#ifdef HAVE_PERCPU_SB
@@ -609,8 +616,8 @@ typedef struct xfs_mod_sb {
extern xfs_mount_t *xfs_mount_init(void);
extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
extern int xfs_log_sbcount(xfs_mount_t *, uint);
-extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
-extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int);
+extern void xfs_mount_free(xfs_mount_t *mp);
+extern int xfs_mountfs(xfs_mount_t *mp, int);
extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
@@ -626,16 +633,19 @@ extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
extern int xfs_readsb(xfs_mount_t *, int);
extern void xfs_freesb(xfs_mount_t *);
extern int xfs_fs_writable(xfs_mount_t *);
-extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
extern int xfs_syncsub(xfs_mount_t *, int, int *);
extern int xfs_sync_inodes(xfs_mount_t *, int, int *);
-extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *,
- xfs_agnumber_t);
-extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
+extern xfs_agnumber_t xfs_initialize_perag(xfs_mount_t *, xfs_agnumber_t);
+extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *);
+extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t);
extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
-extern struct xfs_dmops xfs_dmcore_stub;
-extern struct xfs_qmops xfs_qmcore_stub;
+extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *);
+extern void xfs_dmops_put(struct xfs_mount *);
+extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *);
+extern void xfs_qmops_put(struct xfs_mount *);
+
+extern struct xfs_dmops xfs_dmcore_xfs;
extern struct xfs_ioops xfs_iocore_xfs;
extern int xfs_init(void);
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 0d594ed7efe..c266a0184b4 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -28,6 +28,8 @@
#include "xfs_mount.h"
#include "xfs_quota.h"
#include "xfs_error.h"
+#include "xfs_clnt.h"
+
STATIC struct xfs_dquot *
xfs_dqvopchown_default(
@@ -64,7 +66,7 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp)
* if the fs is readonly, let the incore superblock run
* with quotas off but don't flush the update out to disk
*/
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
#ifdef QUOTADEBUG
xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
@@ -110,7 +112,7 @@ xfs_noquota_init(
return error;
}
-xfs_qmops_t xfs_qmcore_stub = {
+static struct xfs_qmops xfs_qmcore_stub = {
.xfs_qminit = (xfs_qminit_t) xfs_noquota_init,
.xfs_qmdone = (xfs_qmdone_t) fs_noerr,
.xfs_qmmount = (xfs_qmmount_t) fs_noerr,
@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = {
.xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr,
.xfs_dqvopchown = xfs_dqvopchown_default,
.xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
+ .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval,
+ .xfs_dqsync = (xfs_dqsync_t) fs_noerr,
+ .xfs_quotactl = (xfs_quotactl_t) fs_nosys,
};
+
+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;
+ } else {
+ mp->m_qm_ops = &xfs_qmcore_stub;
+ }
+
+ return 0;
+}
+
+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_quota.h b/fs/xfs/xfs_quota.h
index 6f14df976f7..12c4ec775af 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -330,12 +330,12 @@ typedef struct xfs_dqtrxops {
} xfs_dqtrxops_t;
#define XFS_DQTRXOP(mp, tp, op, args...) \
- ((mp)->m_qm_ops.xfs_dqtrxops ? \
- ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0)
+ ((mp)->m_qm_ops->xfs_dqtrxops ? \
+ ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0)
#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \
- ((mp)->m_qm_ops.xfs_dqtrxops ? \
- ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0)
+ ((mp)->m_qm_ops->xfs_dqtrxops ? \
+ ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0)
#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \
XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp)
@@ -364,7 +364,7 @@ typedef struct xfs_dqtrxops {
extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
-extern struct bhv_module_vfsops xfs_qmops;
+extern struct xfs_qmops xfs_qmcore_xfs;
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 7679d7a7022..44ea0ba3647 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@@ -128,8 +129,7 @@ xfs_lock_for_rename(
lock_mode = xfs_ilock_map_shared(dp2);
}
- error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode,
- vname2, &inum2, &ip2);
+ error = xfs_dir_lookup_int(dp2, lock_mode, vname2, &inum2, &ip2);
if (error == ENOENT) { /* target does not need to exist. */
inum2 = 0;
} else if (error) {
@@ -221,15 +221,15 @@ xfs_lock_for_rename(
*/
int
xfs_rename(
- bhv_desc_t *src_dir_bdp,
+ xfs_inode_t *src_dp,
bhv_vname_t *src_vname,
bhv_vnode_t *target_dir_vp,
- bhv_vname_t *target_vname,
- cred_t *credp)
+ bhv_vname_t *target_vname)
{
+ bhv_vnode_t *src_dir_vp = XFS_ITOV(src_dp);
xfs_trans_t *tp;
- xfs_inode_t *src_dp, *target_dp, *src_ip, *target_ip;
- xfs_mount_t *mp;
+ xfs_inode_t *target_dp, *src_ip, *target_ip;
+ xfs_mount_t *mp = src_dp->i_mount;
int new_parent; /* moving to a new dir */
int src_is_directory; /* src_name is a directory */
int error;
@@ -239,7 +239,6 @@ xfs_rename(
int committed;
xfs_inode_t *inodes[4];
int target_ip_dropped = 0; /* dropped target_ip link? */
- bhv_vnode_t *src_dir_vp;
int spaceres;
int target_link_zero = 0;
int num_inodes;
@@ -248,9 +247,8 @@ xfs_rename(
int src_namelen = VNAMELEN(src_vname);
int target_namelen = VNAMELEN(target_vname);
- src_dir_vp = BHV_TO_VNODE(src_dir_bdp);
- vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address);
- vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address);
+ vn_trace_entry(src_dp, "xfs_rename", (inst_t *)__return_address);
+ vn_trace_entry(xfs_vtoi(target_dir_vp), "xfs_rename", (inst_t *)__return_address);
/*
* Find the XFS behavior descriptor for the target directory
@@ -261,12 +259,8 @@ xfs_rename(
return XFS_ERROR(EXDEV);
}
- src_dp = XFS_BHVTOI(src_dir_bdp);
- mp = src_dp->i_mount;
-
- if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
- DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
- target_dp, DM_EVENT_RENAME)) {
+ if (DM_EVENT_ENABLED(src_dp, DM_EVENT_RENAME) ||
+ DM_EVENT_ENABLED(target_dp, DM_EVENT_RENAME)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
src_dir_vp, DM_RIGHT_NULL,
target_dir_vp, DM_RIGHT_NULL,
@@ -592,20 +586,16 @@ xfs_rename(
/*
* Let interposed file systems know about removed links.
*/
- if (target_ip_dropped) {
- bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
- target_link_zero);
+ if (target_ip_dropped)
IRELE(target_ip);
- }
IRELE(src_ip);
/* Fall through to std_return with error = 0 or errno from
* xfs_trans_commit */
std_return:
- if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_POSTRENAME) ||
- DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
- target_dp, DM_EVENT_POSTRENAME)) {
+ if (DM_EVENT_ENABLED(src_dp, DM_EVENT_POSTRENAME) ||
+ DM_EVENT_ENABLED(target_dp, DM_EVENT_POSTRENAME)) {
(void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
src_dir_vp, DM_RIGHT_NULL,
target_dir_vp, DM_RIGHT_NULL,
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index 905d1c008be..cd3ece6cc91 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -178,18 +178,15 @@ xfs_write_sync_logforce(
* the shop, make sure that absolutely nothing persistent happens to
* this filesystem after this point.
*/
-
void
xfs_do_force_shutdown(
- bhv_desc_t *bdp,
+ xfs_mount_t *mp,
int flags,
char *fname,
int lnnum)
{
int logerror;
- xfs_mount_t *mp;
- mp = XFS_BHVTOM(bdp);
logerror = flags & SHUTDOWN_LOG_IO_ERROR;
if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index fcf28dbded7..49875e1d129 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -23,32 +23,6 @@ struct xfs_inode;
struct xfs_mount;
/*
- * Maximum count of bmaps used by read and write paths.
- */
-#define XFS_MAX_RW_NBMAPS 4
-
-/*
- * Counts of readahead buffers to use based on physical memory size.
- * None of these should be more than XFS_MAX_RW_NBMAPS.
- */
-#define XFS_RW_NREADAHEAD_16MB 2
-#define XFS_RW_NREADAHEAD_32MB 3
-#define XFS_RW_NREADAHEAD_K32 4
-#define XFS_RW_NREADAHEAD_K64 4
-
-/*
- * Maximum size of a buffer that we\'ll map. Making this
- * too big will degrade performance due to the number of
- * pages which need to be gathered. Making it too small
- * will prevent us from doing large I/O\'s to hardware that
- * needs it.
- *
- * This is currently set to 512 KB.
- */
-#define XFS_MAX_BMAP_LEN_BB 1024
-#define XFS_MAX_BMAP_LEN_BYTES 524288
-
-/*
* Convert the given file system block to a disk block.
* We have to treat it differently based on whether the
* file is a real time file or not, because the bmap code
@@ -116,14 +90,6 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
/*
* Prototypes for functions in xfs_vnodeops.c.
*/
-extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
-extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
-extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
- cred_t *credp);
-extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
- xfs_off_t offset, cred_t *credp, int flags);
-extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
- cred_t *credp);
extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip,
int flags);
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index ef42537a607..94660b1a6cc 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -87,8 +87,10 @@ struct xfs_mount;
(XFS_SB_VERSION2_OKREALFBITS | \
XFS_SB_VERSION2_OKSASHFBITS )
-typedef struct xfs_sb
-{
+/*
+ * Superblock - in core version. Must match the ondisk version below.
+ */
+typedef struct xfs_sb {
__uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
__uint32_t sb_blocksize; /* logical block size, bytes */
xfs_drfsbno_t sb_dblocks; /* number of data blocks */
@@ -146,6 +148,66 @@ typedef struct xfs_sb
} xfs_sb_t;
/*
+ * Superblock - on disk version. Must match the in core version below.
+ */
+typedef struct xfs_dsb {
+ __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */
+ __be32 sb_blocksize; /* logical block size, bytes */
+ __be64 sb_dblocks; /* number of data blocks */
+ __be64 sb_rblocks; /* number of realtime blocks */
+ __be64 sb_rextents; /* number of realtime extents */
+ uuid_t sb_uuid; /* file system unique id */
+ __be64 sb_logstart; /* starting block of log if internal */
+ __be64 sb_rootino; /* root inode number */
+ __be64 sb_rbmino; /* bitmap inode for realtime extents */
+ __be64 sb_rsumino; /* summary inode for rt bitmap */
+ __be32 sb_rextsize; /* realtime extent size, blocks */
+ __be32 sb_agblocks; /* size of an allocation group */
+ __be32 sb_agcount; /* number of allocation groups */
+ __be32 sb_rbmblocks; /* number of rt bitmap blocks */
+ __be32 sb_logblocks; /* number of log blocks */
+ __be16 sb_versionnum; /* header version == XFS_SB_VERSION */
+ __be16 sb_sectsize; /* volume sector size, bytes */
+ __be16 sb_inodesize; /* inode size, bytes */
+ __be16 sb_inopblock; /* inodes per block */
+ char sb_fname[12]; /* file system name */
+ __u8 sb_blocklog; /* log2 of sb_blocksize */
+ __u8 sb_sectlog; /* log2 of sb_sectsize */
+ __u8 sb_inodelog; /* log2 of sb_inodesize */
+ __u8 sb_inopblog; /* log2 of sb_inopblock */
+ __u8 sb_agblklog; /* log2 of sb_agblocks (rounded up) */
+ __u8 sb_rextslog; /* log2 of sb_rextents */
+ __u8 sb_inprogress; /* mkfs is in progress, don't mount */
+ __u8 sb_imax_pct; /* max % of fs for inode space */
+ /* statistics */
+ /*
+ * These fields must remain contiguous. If you really
+ * want to change their layout, make sure you fix the
+ * code in xfs_trans_apply_sb_deltas().
+ */
+ __be64 sb_icount; /* allocated inodes */
+ __be64 sb_ifree; /* free inodes */
+ __be64 sb_fdblocks; /* free data blocks */
+ __be64 sb_frextents; /* free realtime extents */
+ /*
+ * End contiguous fields.
+ */
+ __be64 sb_uquotino; /* user quota inode */
+ __be64 sb_gquotino; /* group quota inode */
+ __be16 sb_qflags; /* quota flags */
+ __u8 sb_flags; /* misc. flags */
+ __u8 sb_shared_vn; /* shared version number */
+ __be32 sb_inoalignmt; /* inode chunk alignment, fsblocks */
+ __be32 sb_unit; /* stripe or raid unit */
+ __be32 sb_width; /* stripe or raid width */
+ __u8 sb_dirblklog; /* log2 of dir block size (fsbs) */
+ __u8 sb_logsectlog; /* log2 of the log sector size */
+ __be16 sb_logsectsize; /* sector size for the log, bytes */
+ __be32 sb_logsunit; /* stripe unit size for the log */
+ __be32 sb_features2; /* additional feature bits */
+} xfs_dsb_t;
+
+/*
* Sequence number values for the fields.
*/
typedef enum {
@@ -446,7 +508,7 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
-#define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp))
+#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp))
#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 356d6627f58..8878322ee79 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -234,7 +234,7 @@ xfs_trans_alloc(
xfs_mount_t *mp,
uint type)
{
- vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
+ xfs_wait_for_freeze(mp, SB_FREEZE_TRANS);
return _xfs_trans_alloc(mp, type);
}
@@ -548,7 +548,7 @@ STATIC void
xfs_trans_apply_sb_deltas(
xfs_trans_t *tp)
{
- xfs_sb_t *sbp;
+ xfs_dsb_t *sbp;
xfs_buf_t *bp;
int whole = 0;
@@ -566,57 +566,51 @@ xfs_trans_apply_sb_deltas(
* Only update the superblock counters if we are logging them
*/
if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
- if (tp->t_icount_delta != 0) {
- INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta);
- }
- if (tp->t_ifree_delta != 0) {
- INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta);
- }
-
- if (tp->t_fdblocks_delta != 0) {
- INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta);
- }
- if (tp->t_res_fdblocks_delta != 0) {
- INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta);
- }
+ if (tp->t_icount_delta)
+ be64_add(&sbp->sb_icount, tp->t_icount_delta);
+ if (tp->t_ifree_delta)
+ be64_add(&sbp->sb_ifree, tp->t_ifree_delta);
+ if (tp->t_fdblocks_delta)
+ be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
+ if (tp->t_res_fdblocks_delta)
+ be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
}
- if (tp->t_frextents_delta != 0) {
- INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta);
- }
- if (tp->t_res_frextents_delta != 0) {
- INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta);
- }
- if (tp->t_dblocks_delta != 0) {
- INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta);
+ if (tp->t_frextents_delta)
+ be64_add(&sbp->sb_frextents, tp->t_frextents_delta);
+ if (tp->t_res_frextents_delta)
+ be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta);
+
+ if (tp->t_dblocks_delta) {
+ be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta);
whole = 1;
}
- if (tp->t_agcount_delta != 0) {
- INT_MOD(sbp->sb_agcount, ARCH_CONVERT, tp->t_agcount_delta);
+ if (tp->t_agcount_delta) {
+ be32_add(&sbp->sb_agcount, tp->t_agcount_delta);
whole = 1;
}
- if (tp->t_imaxpct_delta != 0) {
- INT_MOD(sbp->sb_imax_pct, ARCH_CONVERT, tp->t_imaxpct_delta);
+ if (tp->t_imaxpct_delta) {
+ sbp->sb_imax_pct += tp->t_imaxpct_delta;
whole = 1;
}
- if (tp->t_rextsize_delta != 0) {
- INT_MOD(sbp->sb_rextsize, ARCH_CONVERT, tp->t_rextsize_delta);
+ if (tp->t_rextsize_delta) {
+ be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta);
whole = 1;
}
- if (tp->t_rbmblocks_delta != 0) {
- INT_MOD(sbp->sb_rbmblocks, ARCH_CONVERT, tp->t_rbmblocks_delta);
+ if (tp->t_rbmblocks_delta) {
+ be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
whole = 1;
}
- if (tp->t_rblocks_delta != 0) {
- INT_MOD(sbp->sb_rblocks, ARCH_CONVERT, tp->t_rblocks_delta);
+ if (tp->t_rblocks_delta) {
+ be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta);
whole = 1;
}
- if (tp->t_rextents_delta != 0) {
- INT_MOD(sbp->sb_rextents, ARCH_CONVERT, tp->t_rextents_delta);
+ if (tp->t_rextents_delta) {
+ be64_add(&sbp->sb_rextents, tp->t_rextents_delta);
whole = 1;
}
- if (tp->t_rextslog_delta != 0) {
- INT_MOD(sbp->sb_rextslog, ARCH_CONVERT, tp->t_rextslog_delta);
+ if (tp->t_rextslog_delta) {
+ sbp->sb_rextslog += tp->t_rextslog_delta;
whole = 1;
}
@@ -624,17 +618,17 @@ xfs_trans_apply_sb_deltas(
/*
* Log the whole thing, the fields are noncontiguous.
*/
- xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1);
+ xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1);
else
/*
* Since all the modifiable fields are contiguous, we
* can get away with this.
*/
- xfs_trans_log_buf(tp, bp, offsetof(xfs_sb_t, sb_icount),
- offsetof(xfs_sb_t, sb_frextents) +
+ xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount),
+ offsetof(xfs_dsb_t, sb_frextents) +
sizeof(sbp->sb_frextents) - 1);
- XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1;
+ tp->t_mountp->m_super->s_dirt = 1;
}
/*
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index ceb4f6e9996..5b2ff59f19c 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index b290270dd4a..27cce2a9c7e 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -22,6 +22,7 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
+#include "xfs_ag.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 104f64a9879..5c89be47546 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -151,18 +151,6 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */
*/
#define MAXNAMELEN 256
-typedef struct xfs_dirent { /* data from readdir() */
- xfs_ino_t d_ino; /* inode number of entry */
- xfs_off_t d_off; /* offset of disk directory entry */
- unsigned short d_reclen; /* length of this record */
- char d_name[1]; /* name of file */
-} xfs_dirent_t;
-
-#define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0)
-#define DIRENTSIZE(namelen) \
- ((DIRENTBASESIZE + (namelen) + \
- sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
-
typedef enum {
XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
} xfs_lookup_t;
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 20ffec308e1..673b405eaa3 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -65,20 +65,15 @@ xfs_get_dir_entry(
int
xfs_dir_lookup_int(
- bhv_desc_t *dir_bdp,
+ xfs_inode_t *dp,
uint lock_mode,
bhv_vname_t *dentry,
xfs_ino_t *inum,
xfs_inode_t **ipp)
{
- bhv_vnode_t *dir_vp;
- xfs_inode_t *dp;
int error;
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- dp = XFS_BHVTOI(dir_bdp);
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum);
if (!error) {
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index fe953e98afa..a00b26d8840 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -20,13 +20,11 @@
#define IRELE(ip) VN_RELE(XFS_ITOV(ip))
#define IHOLD(ip) VN_HOLD(XFS_ITOV(ip))
-#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
+#define ITRACE(ip) vn_trace_ref(ip, __FILE__, __LINE__, \
(inst_t *)__return_address)
-extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
- bhv_vname_t *, cred_t *);
extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **);
-extern int xfs_dir_lookup_int (bhv_desc_t *, uint, bhv_vname_t *, xfs_ino_t *,
+extern int xfs_dir_lookup_int (xfs_inode_t *, uint, bhv_vname_t *, xfs_ino_t *,
xfs_inode_t **);
extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 11f5ea29a03..a5a8454f2a6 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -54,8 +54,9 @@
#include "xfs_mru_cache.h"
#include "xfs_filestream.h"
#include "xfs_fsops.h"
+#include "xfs_vnodeops.h"
+#include "xfs_vfsops.h"
-STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
int
xfs_init(void)
@@ -117,8 +118,8 @@ xfs_init(void)
xfs_ili_zone =
kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
KM_ZONE_SPREAD, NULL);
- xfs_chashlist_zone =
- kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist",
+ xfs_icluster_zone =
+ kmem_zone_init_flags(sizeof(xfs_icluster_t), "xfs_icluster",
KM_ZONE_SPREAD, NULL);
/*
@@ -163,7 +164,7 @@ xfs_cleanup(void)
extern kmem_zone_t *xfs_efd_zone;
extern kmem_zone_t *xfs_efi_zone;
extern kmem_zone_t *xfs_buf_item_zone;
- extern kmem_zone_t *xfs_chashlist_zone;
+ extern kmem_zone_t *xfs_icluster_zone;
xfs_cleanup_procfs();
xfs_sysctl_unregister();
@@ -199,7 +200,7 @@ xfs_cleanup(void)
kmem_zone_destroy(xfs_efi_zone);
kmem_zone_destroy(xfs_ifork_zone);
kmem_zone_destroy(xfs_ili_zone);
- kmem_zone_destroy(xfs_chashlist_zone);
+ kmem_zone_destroy(xfs_icluster_zone);
}
/*
@@ -210,7 +211,6 @@ xfs_cleanup(void)
*/
STATIC int
xfs_start_flags(
- struct bhv_vfs *vfs,
struct xfs_mount_args *ap,
struct xfs_mount *mp)
{
@@ -238,17 +238,14 @@ xfs_start_flags(
mp->m_logbufs = ap->logbufs;
if (ap->logbufsize != -1 &&
ap->logbufsize != 0 &&
- ap->logbufsize != 16 * 1024 &&
- ap->logbufsize != 32 * 1024 &&
- ap->logbufsize != 64 * 1024 &&
- ap->logbufsize != 128 * 1024 &&
- ap->logbufsize != 256 * 1024) {
+ (ap->logbufsize < XLOG_MIN_RECORD_BSIZE ||
+ ap->logbufsize > XLOG_MAX_RECORD_BSIZE ||
+ !is_power_of_2(ap->logbufsize))) {
cmn_err(CE_WARN,
"XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
ap->logbufsize);
return XFS_ERROR(EINVAL);
}
- mp->m_ihsize = ap->ihashsize;
mp->m_logbsize = ap->logbufsize;
mp->m_fsname_len = strlen(ap->fsname) + 1;
mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
@@ -295,8 +292,6 @@ xfs_start_flags(
mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
}
- if (ap->flags & XFSMNT_IHASHSIZE)
- mp->m_flags |= XFS_MOUNT_IHASHSIZE;
if (ap->flags & XFSMNT_IDELETE)
mp->m_flags |= XFS_MOUNT_IDELETE;
if (ap->flags & XFSMNT_DIRSYNC)
@@ -311,7 +306,7 @@ xfs_start_flags(
* no recovery flag requires a read-only mount
*/
if (ap->flags & XFSMNT_NORECOVERY) {
- if (!(vfs->vfs_flag & VFS_RDONLY)) {
+ if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
cmn_err(CE_WARN,
"XFS: tried to mount a FS read-write without recovery!");
return XFS_ERROR(EINVAL);
@@ -329,6 +324,8 @@ xfs_start_flags(
if (ap->flags2 & XFSMNT2_FILESTREAMS)
mp->m_flags |= XFS_MOUNT_FILESTREAMS;
+ if (ap->flags & XFSMNT_DMAPI)
+ mp->m_flags |= XFS_MOUNT_DMAPI;
return 0;
}
@@ -338,11 +335,10 @@ xfs_start_flags(
*/
STATIC int
xfs_finish_flags(
- struct bhv_vfs *vfs,
struct xfs_mount_args *ap,
struct xfs_mount *mp)
{
- int ronly = (vfs->vfs_flag & VFS_RDONLY);
+ int ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
/* Fail a mount where the logbuf is smaller then the log stripe */
if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
@@ -403,6 +399,22 @@ xfs_finish_flags(
return XFS_ERROR(EINVAL);
}
+ if (ap->flags & XFSMNT_UQUOTA) {
+ mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
+ if (ap->flags & XFSMNT_UQUOTAENF)
+ mp->m_qflags |= XFS_UQUOTA_ENFD;
+ }
+
+ if (ap->flags & XFSMNT_GQUOTA) {
+ mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
+ if (ap->flags & XFSMNT_GQUOTAENF)
+ mp->m_qflags |= XFS_OQUOTA_ENFD;
+ } else if (ap->flags & XFSMNT_PQUOTA) {
+ mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
+ if (ap->flags & XFSMNT_PQUOTAENF)
+ mp->m_qflags |= XFS_OQUOTA_ENFD;
+ }
+
return 0;
}
@@ -418,30 +430,26 @@ xfs_finish_flags(
* they are present. The data subvolume has already been opened by
* get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev.
*/
-STATIC int
+int
xfs_mount(
- struct bhv_desc *bhvp,
+ struct xfs_mount *mp,
struct xfs_mount_args *args,
cred_t *credp)
{
- struct bhv_vfs *vfsp = bhvtovfs(bhvp);
- struct bhv_desc *p;
- struct xfs_mount *mp = XFS_BHVTOM(bhvp);
struct block_device *ddev, *logdev, *rtdev;
int flags = 0, error;
- ddev = vfsp->vfs_super->s_bdev;
+ ddev = mp->m_super->s_bdev;
logdev = rtdev = NULL;
- /*
- * Setup xfs_mount function vectors from available behaviors
- */
- p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
- mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
- p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
- mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
- p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
- mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
+ error = xfs_dmops_get(mp, args);
+ if (error)
+ return error;
+ error = xfs_qmops_get(mp, args);
+ if (error)
+ return error;
+
+ mp->m_io_ops = xfs_iocore_xfs;
if (args->flags & XFSMNT_QUIET)
flags |= XFS_MFSI_QUIET;
@@ -482,24 +490,30 @@ xfs_mount(
}
if (rtdev) {
mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1);
- if (!mp->m_rtdev_targp)
+ if (!mp->m_rtdev_targp) {
+ xfs_blkdev_put(logdev);
+ xfs_blkdev_put(rtdev);
goto error0;
+ }
}
mp->m_logdev_targp = (logdev && logdev != ddev) ?
xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp;
- if (!mp->m_logdev_targp)
+ if (!mp->m_logdev_targp) {
+ xfs_blkdev_put(logdev);
+ xfs_blkdev_put(rtdev);
goto error0;
+ }
/*
* Setup flags based on mount(2) options and then the superblock
*/
- error = xfs_start_flags(vfsp, args, mp);
+ error = xfs_start_flags(args, mp);
if (error)
goto error1;
error = xfs_readsb(mp, flags);
if (error)
goto error1;
- error = xfs_finish_flags(vfsp, args, mp);
+ error = xfs_finish_flags(args, mp);
if (error)
goto error2;
@@ -530,10 +544,12 @@ xfs_mount(
if ((error = xfs_filestream_mount(mp)))
goto error2;
- error = XFS_IOINIT(vfsp, args, flags);
+ error = XFS_IOINIT(mp, args, flags);
if (error)
goto error2;
+ XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname);
+
return 0;
error2:
@@ -547,17 +563,17 @@ error1:
xfs_binval(mp->m_rtdev_targp);
error0:
xfs_unmountfs_close(mp, credp);
+ xfs_qmops_put(mp);
+ xfs_dmops_put(mp);
return error;
}
-STATIC int
+int
xfs_unmount(
- bhv_desc_t *bdp,
+ xfs_mount_t *mp,
int flags,
cred_t *credp)
{
- bhv_vfs_t *vfsp = bhvtovfs(bdp);
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
xfs_inode_t *rip;
bhv_vnode_t *rvp;
int unmount_event_wanted = 0;
@@ -568,8 +584,9 @@ xfs_unmount(
rip = mp->m_rootip;
rvp = XFS_ITOV(rip);
- if (vfsp->vfs_flag & VFS_DMI) {
- error = XFS_SEND_PREUNMOUNT(mp, vfsp,
+#ifdef HAVE_DMAPI
+ if (mp->m_flags & XFS_MOUNT_DMAPI) {
+ error = XFS_SEND_PREUNMOUNT(mp,
rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
NULL, NULL, 0, 0,
(mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
@@ -580,7 +597,7 @@ xfs_unmount(
unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
0 : DM_FLAGS_UNWANTED;
}
-
+#endif
/*
* First blow any referenced inode from this file system
* out of the reference cache, and delete the timer.
@@ -612,8 +629,7 @@ xfs_unmount(
* referenced vnodes as well.
*/
if (XFS_FORCED_SHUTDOWN(mp)) {
- error = xfs_sync(&mp->m_bhv,
- (SYNC_WAIT | SYNC_CLOSE), credp);
+ error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE);
ASSERT(error != EFSCORRUPTED);
}
xfs_unmountfs_needed = 1;
@@ -627,7 +643,7 @@ out:
/* Note: mp structure must still exist for
* XFS_SEND_UNMOUNT() call.
*/
- XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL,
+ XFS_SEND_UNMOUNT(mp, error == 0 ? rvp : NULL,
DM_RIGHT_NULL, 0, error, unmount_event_flags);
}
if (xfs_unmountfs_needed) {
@@ -636,6 +652,9 @@ out:
* and free the super block buffer & mount structures.
*/
xfs_unmountfs(mp, credp);
+ xfs_qmops_put(mp);
+ xfs_dmops_put(mp);
+ kmem_free(mp, sizeof(xfs_mount_t));
}
return XFS_ERROR(error);
@@ -694,29 +713,26 @@ xfs_attr_quiesce(
xfs_unmountfs_writesb(mp);
}
-STATIC int
+int
xfs_mntupdate(
- bhv_desc_t *bdp,
+ struct xfs_mount *mp,
int *flags,
struct xfs_mount_args *args)
{
- bhv_vfs_t *vfsp = bhvtovfs(bdp);
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
-
if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
- if (vfsp->vfs_flag & VFS_RDONLY)
- vfsp->vfs_flag &= ~VFS_RDONLY;
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
+ mp->m_flags &= ~XFS_MOUNT_RDONLY;
if (args->flags & XFSMNT_BARRIER) {
mp->m_flags |= XFS_MOUNT_BARRIER;
xfs_mountfs_check_barriers(mp);
} else {
mp->m_flags &= ~XFS_MOUNT_BARRIER;
}
- } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */
+ } else if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* rw -> ro */
xfs_filestream_flush(mp);
- bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL);
+ xfs_sync(mp, SYNC_DATA_QUIESCE);
xfs_attr_quiesce(mp);
- vfsp->vfs_flag |= VFS_RDONLY;
+ mp->m_flags |= XFS_MOUNT_RDONLY;
}
return 0;
}
@@ -811,14 +827,14 @@ fscorrupt_out2:
* vpp -- address of the caller's vnode pointer which should be
* set to the desired fs root vnode
*/
-STATIC int
+int
xfs_root(
- bhv_desc_t *bdp,
+ xfs_mount_t *mp,
bhv_vnode_t **vpp)
{
bhv_vnode_t *vp;
- vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
+ vp = XFS_ITOV(mp->m_rootip);
VN_HOLD(vp);
*vpp = vp;
return 0;
@@ -831,19 +847,17 @@ xfs_root(
* the superblock lock in the mount structure to ensure a consistent
* snapshot of the counters returned.
*/
-STATIC int
+int
xfs_statvfs(
- bhv_desc_t *bdp,
+ xfs_mount_t *mp,
bhv_statvfs_t *statp,
bhv_vnode_t *vp)
{
__uint64_t fakeinos;
xfs_extlen_t lsize;
- xfs_mount_t *mp;
xfs_sb_t *sbp;
unsigned long s;
- mp = XFS_BHVTOM(bdp);
sbp = &(mp->m_sb);
statp->f_type = XFS_SB_MAGIC;
@@ -874,6 +888,8 @@ xfs_statvfs(
xfs_statvfs_fsid(statp, mp);
statp->f_namelen = MAXNAMELEN - 1;
+ if (vp)
+ XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp);
return 0;
}
@@ -920,14 +936,30 @@ xfs_statvfs(
* filesystem.
*
*/
-/*ARGSUSED*/
-STATIC int
+int
xfs_sync(
- bhv_desc_t *bdp,
- int flags,
- cred_t *credp)
+ xfs_mount_t *mp,
+ int flags)
{
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
+ int error;
+
+ /*
+ * Get the Quota Manager to flush the dquots.
+ *
+ * If XFS quota support is not enabled or this filesystem
+ * instance does not use quotas XFS_QM_DQSYNC will always
+ * return zero.
+ */
+ error = XFS_QM_DQSYNC(mp, flags);
+ if (error) {
+ /*
+ * If we got an IO error, we will be shutting down.
+ * So, there's nothing more for us to do here.
+ */
+ ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return XFS_ERROR(error);
+ }
if (flags & SYNC_IOWAIT)
xfs_filestream_flush(mp);
@@ -1015,7 +1047,7 @@ xfs_sync_inodes(
if (bypassed)
*bypassed = 0;
- if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
error = 0;
last_error = 0;
@@ -1189,12 +1221,13 @@ xfs_sync_inodes(
if (flags & SYNC_CLOSE) {
/* Shutdown case. Flush and invalidate. */
if (XFS_FORCED_SHUTDOWN(mp))
- bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
+ xfs_tosspages(ip, 0, -1,
+ FI_REMAPF);
else
- error = bhv_vop_flushinval_pages(vp, 0,
- -1, FI_REMAPF);
+ error = xfs_flushinval_pages(ip,
+ 0, -1, FI_REMAPF);
} else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) {
- error = bhv_vop_flush_pages(vp, (xfs_off_t)0,
+ error = xfs_flush_pages(ip, 0,
-1, fflag, FI_NONE);
}
@@ -1204,7 +1237,7 @@ xfs_sync_inodes(
* place after this point
*/
if (flags & SYNC_IOWAIT)
- vn_iowait(vp);
+ vn_iowait(ip);
xfs_ilock(ip, XFS_ILOCK_SHARED);
}
@@ -1598,13 +1631,12 @@ xfs_syncsub(
/*
* xfs_vget - called by DMAPI and NFSD to get vnode from file handle
*/
-STATIC int
+int
xfs_vget(
- bhv_desc_t *bdp,
+ xfs_mount_t *mp,
bhv_vnode_t **vpp,
fid_t *fidp)
{
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
xfs_fid_t *xfid = (struct xfs_fid *)fidp;
xfs_inode_t *ip;
int error;
@@ -1668,7 +1700,6 @@ xfs_vget(
#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
-#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
* unwritten extent conversion */
@@ -1683,6 +1714,21 @@ xfs_vget(
#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
+#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
+#define MNTOPT_NOQUOTA "noquota" /* no quotas */
+#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
+#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
+#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
+#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
+#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
+#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
+#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
+#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
+#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
+#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
+#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
+#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
+#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
STATIC unsigned long
suffix_strtoul(char *s, char **endp, unsigned int base)
@@ -1707,19 +1753,18 @@ suffix_strtoul(char *s, char **endp, unsigned int base)
return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
}
-STATIC int
+int
xfs_parseargs(
- struct bhv_desc *bhv,
+ struct xfs_mount *mp,
char *options,
struct xfs_mount_args *args,
int update)
{
- bhv_vfs_t *vfsp = bhvtovfs(bhv);
char *this_char, *value, *eov;
int dsunit, dswidth, vol_dsunit, vol_dswidth;
int iosize;
+ int ikeep = 0;
- args->flags |= XFSMNT_IDELETE;
args->flags |= XFSMNT_BARRIER;
args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
@@ -1794,21 +1839,12 @@ xfs_parseargs(
iosize = suffix_strtoul(value, &eov, 10);
args->flags |= XFSMNT_IOSIZE;
args->iosizelog = ffs(iosize) - 1;
- } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
- if (!value || !*value) {
- cmn_err(CE_WARN,
- "XFS: %s option requires an argument",
- this_char);
- return EINVAL;
- }
- args->flags |= XFSMNT_IHASHSIZE;
- args->ihashsize = simple_strtoul(value, &eov, 10);
} else if (!strcmp(this_char, MNTOPT_GRPID) ||
!strcmp(this_char, MNTOPT_BSDGROUPS)) {
- vfsp->vfs_flag |= VFS_GRPID;
+ mp->m_flags |= XFS_MOUNT_GRPID;
} else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
!strcmp(this_char, MNTOPT_SYSVGROUPS)) {
- vfsp->vfs_flag &= ~VFS_GRPID;
+ mp->m_flags &= ~XFS_MOUNT_GRPID;
} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
args->flags |= XFSMNT_WSYNC;
} else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
@@ -1858,6 +1894,7 @@ xfs_parseargs(
} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
args->flags &= ~XFSMNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
+ ikeep = 1;
args->flags &= ~XFSMNT_IDELETE;
} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
args->flags |= XFSMNT_IDELETE;
@@ -1871,6 +1908,38 @@ xfs_parseargs(
args->flags &= ~XFSMNT_ATTR2;
} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
args->flags2 |= XFSMNT2_FILESTREAMS;
+ } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
+ args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
+ args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
+ } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
+ !strcmp(this_char, MNTOPT_UQUOTA) ||
+ !strcmp(this_char, MNTOPT_USRQUOTA)) {
+ args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
+ } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
+ !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
+ args->flags |= XFSMNT_UQUOTA;
+ args->flags &= ~XFSMNT_UQUOTAENF;
+ } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
+ !strcmp(this_char, MNTOPT_PRJQUOTA)) {
+ args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
+ } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
+ args->flags |= XFSMNT_PQUOTA;
+ args->flags &= ~XFSMNT_PQUOTAENF;
+ } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
+ !strcmp(this_char, MNTOPT_GRPQUOTA)) {
+ args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
+ } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
+ args->flags |= XFSMNT_GQUOTA;
+ args->flags &= ~XFSMNT_GQUOTAENF;
+ } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
+ args->flags |= XFSMNT_DMAPI;
+ } else if (!strcmp(this_char, MNTOPT_XDSM)) {
+ args->flags |= XFSMNT_DMAPI;
+ } else if (!strcmp(this_char, MNTOPT_DMI)) {
+ args->flags |= XFSMNT_DMAPI;
+ } else if (!strcmp(this_char, "ihashsize")) {
+ cmn_err(CE_WARN,
+ "XFS: ihashsize no longer used, option is deprecated.");
} else if (!strcmp(this_char, "osyncisdsync")) {
/* no-op, this is now the default */
cmn_err(CE_WARN,
@@ -1886,7 +1955,7 @@ xfs_parseargs(
}
if (args->flags & XFSMNT_NORECOVERY) {
- if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
+ if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {
cmn_err(CE_WARN,
"XFS: no-recovery mounts must be read-only.");
return EINVAL;
@@ -1899,6 +1968,18 @@ xfs_parseargs(
return EINVAL;
}
+ if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
+ cmn_err(CE_WARN,
+ "XFS: cannot mount with both project and group quota");
+ return EINVAL;
+ }
+
+ if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
+ printk("XFS: %s option needs the mount point option as well\n",
+ MNTOPT_DMAPI);
+ return EINVAL;
+ }
+
if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
cmn_err(CE_WARN,
"XFS: sunit and swidth must be specified together");
@@ -1912,6 +1993,18 @@ xfs_parseargs(
return EINVAL;
}
+ /*
+ * Applications using DMI filesystems often expect the
+ * inode generation number to be monotonically increasing.
+ * If we delete inode chunks we break this assumption, so
+ * keep unused inode chunks on disk for DMI filesystems
+ * until we come up with a better solution.
+ * Note that if "ikeep" or "noikeep" mount options are
+ * supplied, then they are honored.
+ */
+ if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
+ args->flags |= XFSMNT_IDELETE;
+
if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
if (dsunit) {
args->sunit = dsunit;
@@ -1927,15 +2020,15 @@ xfs_parseargs(
done:
if (args->flags & XFSMNT_32BITINODES)
- vfsp->vfs_flag |= VFS_32BITINODES;
+ mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
if (args->flags2)
args->flags |= XFSMNT_FLAGS2;
return 0;
}
-STATIC int
+int
xfs_showargs(
- struct bhv_desc *bhv,
+ struct xfs_mount *mp,
struct seq_file *m)
{
static struct proc_xfs_info {
@@ -1953,17 +2046,12 @@ xfs_showargs(
{ 0, NULL }
};
struct proc_xfs_info *xfs_infop;
- struct xfs_mount *mp = XFS_BHVTOM(bhv);
- struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
if (mp->m_flags & xfs_infop->flag)
seq_puts(m, xfs_infop->str);
}
- if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
- seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize);
-
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
(int)(1 << mp->m_writeio_log) >> 10);
@@ -1990,11 +2078,37 @@ xfs_showargs(
if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
seq_printf(m, "," MNTOPT_LARGEIO);
- if (!(vfsp->vfs_flag & VFS_32BITINODES))
+ if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS))
seq_printf(m, "," MNTOPT_64BITINODE);
- if (vfsp->vfs_flag & VFS_GRPID)
+ if (mp->m_flags & XFS_MOUNT_GRPID)
seq_printf(m, "," MNTOPT_GRPID);
+ if (mp->m_qflags & XFS_UQUOTA_ACCT) {
+ if (mp->m_qflags & XFS_UQUOTA_ENFD)
+ seq_puts(m, "," MNTOPT_USRQUOTA);
+ else
+ seq_puts(m, "," MNTOPT_UQUOTANOENF);
+ }
+
+ if (mp->m_qflags & XFS_PQUOTA_ACCT) {
+ if (mp->m_qflags & XFS_OQUOTA_ENFD)
+ seq_puts(m, "," MNTOPT_PRJQUOTA);
+ else
+ seq_puts(m, "," MNTOPT_PQUOTANOENF);
+ }
+
+ if (mp->m_qflags & XFS_GQUOTA_ACCT) {
+ if (mp->m_qflags & XFS_OQUOTA_ENFD)
+ seq_puts(m, "," MNTOPT_GRPQUOTA);
+ else
+ seq_puts(m, "," MNTOPT_GQUOTANOENF);
+ }
+
+ if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
+ seq_puts(m, "," MNTOPT_NOQUOTA);
+
+ if (mp->m_flags & XFS_MOUNT_DMAPI)
+ seq_puts(m, "," MNTOPT_DMAPI);
return 0;
}
@@ -2003,31 +2117,10 @@ xfs_showargs(
* need to take care of themetadata. Once that's done write a dummy
* record to dirty the log in case of a crash while frozen.
*/
-STATIC void
+void
xfs_freeze(
- bhv_desc_t *bdp)
+ xfs_mount_t *mp)
{
- xfs_mount_t *mp = XFS_BHVTOM(bdp);
-
xfs_attr_quiesce(mp);
xfs_fs_log_dummy(mp);
}
-
-
-bhv_vfsops_t xfs_vfsops = {
- BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
- .vfs_parseargs = xfs_parseargs,
- .vfs_showargs = xfs_showargs,
- .vfs_mount = xfs_mount,
- .vfs_unmount = xfs_unmount,
- .vfs_mntupdate = xfs_mntupdate,
- .vfs_root = xfs_root,
- .vfs_statvfs = xfs_statvfs,
- .vfs_sync = xfs_sync,
- .vfs_vget = xfs_vget,
- .vfs_dmapiops = (vfs_dmapiops_t)fs_nosys,
- .vfs_quotactl = (vfs_quotactl_t)fs_nosys,
- .vfs_init_vnode = xfs_initialize_vnode,
- .vfs_force_shutdown = xfs_do_force_shutdown,
- .vfs_freeze = xfs_freeze,
-};
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h
new file mode 100644
index 00000000000..bc99e3eb7db
--- /dev/null
+++ b/fs/xfs/xfs_vfsops.h
@@ -0,0 +1,28 @@
+#ifndef _XFS_VFSOPS_H
+#define _XFS_VFSOPS_H 1
+
+struct cred;
+struct fid;
+struct inode;
+struct kstatfs;
+struct xfs_mount;
+struct xfs_mount_args;
+
+int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args,
+ struct cred *credp);
+int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp);
+int xfs_mntupdate(struct xfs_mount *mp, int *flags,
+ struct xfs_mount_args *args);
+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_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);
+void xfs_freeze(struct xfs_mount *mp);
+void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
+ int lnnum);
+
+#endif /* _XFS_VFSOPS_H */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 60345922990..5e3c57ca998 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -52,15 +52,13 @@
#include "xfs_trans_space.h"
#include "xfs_log_priv.h"
#include "xfs_filestream.h"
+#include "xfs_vnodeops.h"
-STATIC int
+int
xfs_open(
- bhv_desc_t *bdp,
- cred_t *credp)
+ xfs_inode_t *ip)
{
int mode;
- bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
- xfs_inode_t *ip = XFS_BHVTOI(bdp);
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return XFS_ERROR(EIO);
@@ -69,7 +67,7 @@ xfs_open(
* If it's a directory with any blocks, read-ahead block 0
* as we're almost certain to have the next operation be a read there.
*/
- if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) {
+ if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) {
mode = xfs_ilock_map_shared(ip);
if (ip->i_d.di_nextents > 0)
(void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
@@ -81,22 +79,16 @@ xfs_open(
/*
* xfs_getattr
*/
-STATIC int
+int
xfs_getattr(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
bhv_vattr_t *vap,
- int flags,
- cred_t *credp)
+ int flags)
{
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- bhv_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ xfs_mount_t *mp = ip->i_mount;
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -215,14 +207,14 @@ xfs_getattr(
*/
int
xfs_setattr(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
bhv_vattr_t *vap,
int flags,
cred_t *credp)
{
- xfs_inode_t *ip;
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ xfs_mount_t *mp = ip->i_mount;
xfs_trans_t *tp;
- xfs_mount_t *mp;
int mask;
int code;
uint lock_flags;
@@ -230,17 +222,15 @@ xfs_setattr(
uid_t uid=0, iuid=0;
gid_t gid=0, igid=0;
int timeflags = 0;
- bhv_vnode_t *vp;
xfs_prid_t projid=0, iprojid=0;
int mandlock_before, mandlock_after;
struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
int file_owner;
int need_iolock = 1;
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
/*
@@ -251,9 +241,6 @@ xfs_setattr(
return XFS_ERROR(EINVAL);
}
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -337,7 +324,7 @@ xfs_setattr(
}
}
} else {
- if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
+ if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
!(flags & ATTR_DMI)) {
int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp,
@@ -605,13 +592,13 @@ xfs_setattr(
if (!code &&
(ip->i_size != ip->i_d.di_size) &&
(vap->va_size > ip->i_d.di_size)) {
- code = bhv_vop_flush_pages(XFS_ITOV(ip),
+ code = xfs_flush_pages(ip,
ip->i_d.di_size, vap->va_size,
XFS_B_ASYNC, FI_NONE);
}
/* wait for all I/O to complete */
- vn_iowait(vp);
+ vn_iowait(ip);
if (!code)
code = xfs_itruncate_data(ip, vap->va_size);
@@ -673,7 +660,7 @@ xfs_setattr(
* vnode and flush it when the file is closed, and
* do not wait the usual (long) time for writeout.
*/
- VTRUNCATE(vp);
+ xfs_iflags_set(ip, XFS_ITRUNCATED);
}
/*
* Have to do this even if the file's size doesn't change.
@@ -877,10 +864,6 @@ xfs_setattr(
* racing calls to vop_vnode_change.
*/
mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
- if (mandlock_before != mandlock_after) {
- bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING,
- mandlock_after);
- }
xfs_iunlock(ip, lock_flags);
@@ -896,7 +879,7 @@ xfs_setattr(
return code;
}
- if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) &&
+ if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
!(flags & ATTR_DMI)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL, NULL, NULL,
@@ -924,19 +907,16 @@ xfs_setattr(
* xfs_access
* Null conversion from vnode mode bits to inode mode bits, as in efs.
*/
-STATIC int
+int
xfs_access(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
int mode,
cred_t *credp)
{
- xfs_inode_t *ip;
int error;
- vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
- (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
- ip = XFS_BHVTOI(bdp);
xfs_ilock(ip, XFS_ILOCK_SHARED);
error = xfs_iaccess(ip, mode, credp);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -951,105 +931,88 @@ xfs_access(
*/
#define SYMLINK_MAPS 2
-/*
- * xfs_readlink
- *
- */
STATIC int
-xfs_readlink(
- bhv_desc_t *bdp,
- uio_t *uiop,
- int ioflags,
- cred_t *credp)
+xfs_readlink_bmap(
+ xfs_inode_t *ip,
+ char *link)
{
- xfs_inode_t *ip;
- int count;
- xfs_off_t offset;
- int pathlen;
- bhv_vnode_t *vp;
- int error = 0;
- xfs_mount_t *mp;
- int nmaps;
+ xfs_mount_t *mp = ip->i_mount;
+ int pathlen = ip->i_d.di_size;
+ int nmaps = SYMLINK_MAPS;
xfs_bmbt_irec_t mval[SYMLINK_MAPS];
xfs_daddr_t d;
int byte_cnt;
int n;
xfs_buf_t *bp;
+ int error = 0;
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
+ error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0,
+ mval, &nmaps, NULL, NULL);
+ if (error)
+ goto out;
- if (XFS_FORCED_SHUTDOWN(mp))
- return XFS_ERROR(EIO);
+ for (n = 0; n < nmaps; n++) {
+ d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
+ byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
- xfs_ilock(ip, XFS_ILOCK_SHARED);
+ bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0);
+ error = XFS_BUF_GETERROR(bp);
+ if (error) {
+ xfs_ioerror_alert("xfs_readlink",
+ ip->i_mount, bp, XFS_BUF_ADDR(bp));
+ xfs_buf_relse(bp);
+ goto out;
+ }
+ if (pathlen < byte_cnt)
+ byte_cnt = pathlen;
+ pathlen -= byte_cnt;
- ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
+ memcpy(link, XFS_BUF_PTR(bp), byte_cnt);
+ xfs_buf_relse(bp);
+ }
- offset = uiop->uio_offset;
- count = uiop->uio_resid;
+ link[ip->i_d.di_size] = '\0';
+ error = 0;
- if (offset < 0) {
- error = XFS_ERROR(EINVAL);
- goto error_return;
- }
- if (count <= 0) {
- error = 0;
- goto error_return;
- }
+ out:
+ return error;
+}
- /*
- * See if the symlink is stored inline.
- */
- pathlen = (int)ip->i_d.di_size;
+int
+xfs_readlink(
+ xfs_inode_t *ip,
+ char *link)
+{
+ xfs_mount_t *mp = ip->i_mount;
+ int pathlen;
+ int error = 0;
- if (ip->i_df.if_flags & XFS_IFINLINE) {
- error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
- }
- else {
- /*
- * Symlink not inline. Call bmap to get it in.
- */
- nmaps = SYMLINK_MAPS;
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
- error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
- 0, NULL, 0, mval, &nmaps, NULL, NULL);
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return XFS_ERROR(EIO);
- if (error) {
- goto error_return;
- }
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
- for (n = 0; n < nmaps; n++) {
- d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
- byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
- bp = xfs_buf_read(mp->m_ddev_targp, d,
- BTOBB(byte_cnt), 0);
- error = XFS_BUF_GETERROR(bp);
- if (error) {
- xfs_ioerror_alert("xfs_readlink",
- ip->i_mount, bp, XFS_BUF_ADDR(bp));
- xfs_buf_relse(bp);
- goto error_return;
- }
- if (pathlen < byte_cnt)
- byte_cnt = pathlen;
- pathlen -= byte_cnt;
+ ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
+ ASSERT(ip->i_d.di_size <= MAXPATHLEN);
- error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
- xfs_buf_relse (bp);
- }
+ pathlen = ip->i_d.di_size;
+ if (!pathlen)
+ goto out;
+ if (ip->i_df.if_flags & XFS_IFINLINE) {
+ memcpy(link, ip->i_df.if_u1.if_data, pathlen);
+ link[pathlen] = '\0';
+ } else {
+ error = xfs_readlink_bmap(ip, link);
}
-error_return:
+ out:
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return error;
}
-
/*
* xfs_fsync
*
@@ -1059,23 +1022,18 @@ error_return:
* be held while flushing the data, so acquire after we're done
* with that.
*/
-STATIC int
+int
xfs_fsync(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
int flag,
- cred_t *credp,
xfs_off_t start,
xfs_off_t stop)
{
- xfs_inode_t *ip;
xfs_trans_t *tp;
int error;
int log_flushed = 0, changed = 1;
- vn_trace_entry(BHV_TO_VNODE(bdp),
- __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
ASSERT(start >= 0 && stop >= -1);
@@ -1545,27 +1503,24 @@ xfs_inactive_attrs(
return 0;
}
-STATIC int
+int
xfs_release(
- bhv_desc_t *bdp)
+ xfs_inode_t *ip)
{
- xfs_inode_t *ip;
- bhv_vnode_t *vp;
- xfs_mount_t *mp;
+ bhv_vnode_t *vp = XFS_ITOV(ip);
+ xfs_mount_t *mp = ip->i_mount;
int error;
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0))
return 0;
/* If this is a read-only mount, don't do this (would generate I/O) */
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
return 0;
if (!XFS_FORCED_SHUTDOWN(mp)) {
+ int truncated;
+
/*
* If we are using filestreams, and we have an unlinked
* file that we are processing the last close on, then nothing
@@ -1586,8 +1541,9 @@ xfs_release(
* significantly reducing the time window where we'd otherwise
* be exposed to that problem.
*/
- if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
- bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE);
+ truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
+ if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
+ xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE);
}
#ifdef HAVE_REFCACHE
@@ -1623,13 +1579,11 @@ xfs_release(
* now be truncated. Also, we clear all of the read-ahead state
* kept for the inode here since the file is now closed.
*/
-STATIC int
+int
xfs_inactive(
- bhv_desc_t *bdp,
- cred_t *credp)
+ xfs_inode_t *ip)
{
- xfs_inode_t *ip;
- bhv_vnode_t *vp;
+ bhv_vnode_t *vp = XFS_ITOV(ip);
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
int committed;
@@ -1638,10 +1592,7 @@ xfs_inactive(
int error;
int truncate;
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
/*
* If the inode is already free, then there can be nothing
@@ -1666,15 +1617,14 @@ xfs_inactive(
mp = ip->i_mount;
- if (ip->i_d.di_nlink == 0 &&
- DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) {
+ if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) {
(void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL);
}
error = 0;
/* If this is a read-only mount, don't do this (would generate I/O) */
- if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+ if (mp->m_flags & XFS_MOUNT_RDONLY)
goto out;
if (ip->i_d.di_nlink != 0) {
@@ -1844,34 +1794,24 @@ xfs_inactive(
}
-/*
- * xfs_lookup
- */
-STATIC int
+int
xfs_lookup(
- bhv_desc_t *dir_bdp,
+ xfs_inode_t *dp,
bhv_vname_t *dentry,
- bhv_vnode_t **vpp,
- int flags,
- bhv_vnode_t *rdir,
- cred_t *credp)
+ bhv_vnode_t **vpp)
{
- xfs_inode_t *dp, *ip;
+ xfs_inode_t *ip;
xfs_ino_t e_inum;
int error;
uint lock_mode;
- bhv_vnode_t *dir_vp;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
- dp = XFS_BHVTOI(dir_bdp);
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return XFS_ERROR(EIO);
lock_mode = xfs_ilock_map_shared(dp);
- error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip);
+ error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip);
if (!error) {
*vpp = XFS_ITOV(ip);
ITRACE(ip);
@@ -1880,53 +1820,43 @@ xfs_lookup(
return error;
}
-
-/*
- * xfs_create (create a new file).
- */
-STATIC int
+int
xfs_create(
- bhv_desc_t *dir_bdp,
+ xfs_inode_t *dp,
bhv_vname_t *dentry,
- bhv_vattr_t *vap,
+ mode_t mode,
+ xfs_dev_t rdev,
bhv_vnode_t **vpp,
cred_t *credp)
{
char *name = VNAME(dentry);
- bhv_vnode_t *dir_vp;
- xfs_inode_t *dp, *ip;
+ xfs_mount_t *mp = dp->i_mount;
+ bhv_vnode_t *dir_vp = XFS_ITOV(dp);
+ xfs_inode_t *ip;
bhv_vnode_t *vp = NULL;
xfs_trans_t *tp;
- xfs_mount_t *mp;
- xfs_dev_t rdev;
int error;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
- boolean_t dp_joined_to_trans;
+ boolean_t unlock_dp_on_error = B_FALSE;
int dm_event_sent = 0;
uint cancel_flags;
int committed;
xfs_prid_t prid;
struct xfs_dquot *udqp, *gdqp;
uint resblks;
- int dm_di_mode;
int namelen;
ASSERT(!*vpp);
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
-
- dm_di_mode = vap->va_mode;
namelen = VNAMELEN(dentry);
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
dir_vp, DM_RIGHT_NULL, NULL,
DM_RIGHT_NULL, name, NULL,
- dm_di_mode, 0, 0);
+ mode, 0, 0);
if (error)
return error;
@@ -1941,8 +1871,6 @@ xfs_create(
udqp = gdqp = NULL;
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
- else if (vap->va_mask & XFS_AT_PROJID)
- prid = (xfs_prid_t)vap->va_projid;
else
prid = (xfs_prid_t)dfltprid;
@@ -1956,7 +1884,6 @@ xfs_create(
goto std_return;
ip = NULL;
- dp_joined_to_trans = B_FALSE;
tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -1976,11 +1903,11 @@ xfs_create(
}
if (error) {
cancel_flags = 0;
- dp = NULL;
goto error_return;
}
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+ unlock_dp_on_error = B_TRUE;
XFS_BMAP_INIT(&free_list, &first_block);
@@ -1995,8 +1922,7 @@ xfs_create(
if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))
goto error_return;
- rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
- error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
+ error = xfs_dir_ialloc(&tp, dp, mode, 1,
rdev, credp, prid, resblks > 0,
&ip, &committed);
if (error) {
@@ -2014,15 +1940,15 @@ xfs_create(
ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE));
/*
- * Now we join the directory inode to the transaction.
- * We do not do it earlier because xfs_dir_ialloc
- * might commit the previous transaction (and release
- * all the locks).
+ * Now we join the directory inode to the transaction. We do not do it
+ * earlier because xfs_dir_ialloc might commit the previous transaction
+ * (and release all the locks). An error from here on will result in
+ * the transaction cancel unlocking dp so don't do it explicitly in the
+ * error path.
*/
-
VN_HOLD(dir_vp);
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- dp_joined_to_trans = B_TRUE;
+ unlock_dp_on_error = B_FALSE;
error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino,
&first_block, &free_list, resblks ?
@@ -2076,25 +2002,18 @@ xfs_create(
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
- /*
- * Propagate the fact that the vnode changed after the
- * xfs_inode locks have been released.
- */
- bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3);
-
*vpp = vp;
/* Fallthrough to std_return with error = 0 */
std_return:
- if ( (*vpp || (error != 0 && dm_event_sent != 0)) &&
- DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
- DM_EVENT_POSTCREATE)) {
+ if ((*vpp || (error != 0 && dm_event_sent != 0)) &&
+ DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
dir_vp, DM_RIGHT_NULL,
*vpp ? vp:NULL,
DM_RIGHT_NULL, name, NULL,
- dm_di_mode, error, 0);
+ mode, error, 0);
}
return error;
@@ -2106,11 +2025,12 @@ std_return:
if (tp != NULL)
xfs_trans_cancel(tp, cancel_flags);
- if (!dp_joined_to_trans && (dp != NULL))
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
+ if (unlock_dp_on_error)
+ xfs_iunlock(dp, XFS_ILOCK_EXCL);
+
goto std_return;
abort_rele:
@@ -2381,22 +2301,16 @@ int remove_which_error_return = 0;
#define REMOVE_DEBUG_TRACE(x)
#endif /* ! DEBUG */
-
-/*
- * xfs_remove
- *
- */
-STATIC int
+int
xfs_remove(
- bhv_desc_t *dir_bdp,
- bhv_vname_t *dentry,
- cred_t *credp)
+ xfs_inode_t *dp,
+ bhv_vname_t *dentry)
{
- bhv_vnode_t *dir_vp;
+ bhv_vnode_t *dir_vp = XFS_ITOV(dp);
char *name = VNAME(dentry);
- xfs_inode_t *dp, *ip;
+ xfs_mount_t *mp = dp->i_mount;
+ xfs_inode_t *ip;
xfs_trans_t *tp = NULL;
- xfs_mount_t *mp;
int error = 0;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
@@ -2407,11 +2321,7 @@ xfs_remove(
uint resblks;
int namelen;
- dir_vp = BHV_TO_VNODE(dir_bdp);
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -2423,7 +2333,7 @@ xfs_remove(
IRELE(ip);
}
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
name, NULL, dm_di_mode, 0, 0);
@@ -2454,7 +2364,7 @@ xfs_remove(
dm_di_mode = ip->i_d.di_mode;
- vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
ITRACE(ip);
@@ -2588,19 +2498,13 @@ xfs_remove(
if (link_zero && xfs_inode_is_filestream(ip))
xfs_filestream_deassociate(ip);
- vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-
- /*
- * Let interposed file systems know about removed links.
- */
- bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero);
+ vn_trace_exit(ip, __FUNCTION__, (inst_t *)__return_address);
IRELE(ip);
/* Fall through to std_return with error = 0 */
std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
- DM_EVENT_POSTREMOVE)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
dir_vp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
@@ -2638,46 +2542,36 @@ xfs_remove(
goto std_return;
}
-
-/*
- * xfs_link
- *
- */
-STATIC int
+int
xfs_link(
- bhv_desc_t *target_dir_bdp,
+ xfs_inode_t *tdp,
bhv_vnode_t *src_vp,
- bhv_vname_t *dentry,
- cred_t *credp)
+ bhv_vname_t *dentry)
{
- xfs_inode_t *tdp, *sip;
+ bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp);
+ xfs_mount_t *mp = tdp->i_mount;
+ xfs_inode_t *sip = xfs_vtoi(src_vp);
xfs_trans_t *tp;
- xfs_mount_t *mp;
xfs_inode_t *ips[2];
int error;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
int cancel_flags;
int committed;
- bhv_vnode_t *target_dir_vp;
int resblks;
char *target_name = VNAME(dentry);
int target_namelen;
- target_dir_vp = BHV_TO_VNODE(target_dir_bdp);
- vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address);
- vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(tdp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(xfs_vtoi(src_vp), __FUNCTION__, (inst_t *)__return_address);
target_namelen = VNAMELEN(dentry);
ASSERT(!VN_ISDIR(src_vp));
- sip = xfs_vtoi(src_vp);
- tdp = XFS_BHVTOI(target_dir_bdp);
- mp = tdp->i_mount;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) {
+ if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
target_dir_vp, DM_RIGHT_NULL,
src_vp, DM_RIGHT_NULL,
@@ -2788,8 +2682,7 @@ xfs_link(
/* Fall through to std_return with error = 0. */
std_return:
- if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip,
- DM_EVENT_POSTLINK)) {
+ if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
target_dir_vp, DM_RIGHT_NULL,
src_vp, DM_RIGHT_NULL,
@@ -2807,57 +2700,43 @@ std_return:
}
-/*
- * xfs_mkdir
- *
- */
-STATIC int
+int
xfs_mkdir(
- bhv_desc_t *dir_bdp,
+ xfs_inode_t *dp,
bhv_vname_t *dentry,
- bhv_vattr_t *vap,
+ mode_t mode,
bhv_vnode_t **vpp,
cred_t *credp)
{
+ bhv_vnode_t *dir_vp = XFS_ITOV(dp);
char *dir_name = VNAME(dentry);
- xfs_inode_t *dp;
+ int dir_namelen = VNAMELEN(dentry);
+ xfs_mount_t *mp = dp->i_mount;
xfs_inode_t *cdp; /* inode of created dir */
bhv_vnode_t *cvp; /* vnode of created dir */
xfs_trans_t *tp;
- xfs_mount_t *mp;
int cancel_flags;
int error;
int committed;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
- bhv_vnode_t *dir_vp;
- boolean_t dp_joined_to_trans;
+ boolean_t unlock_dp_on_error = B_FALSE;
boolean_t created = B_FALSE;
int dm_event_sent = 0;
xfs_prid_t prid;
struct xfs_dquot *udqp, *gdqp;
uint resblks;
- int dm_di_mode;
- int dir_namelen;
-
- dir_vp = BHV_TO_VNODE(dir_bdp);
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- dir_namelen = VNAMELEN(dentry);
-
tp = NULL;
- dp_joined_to_trans = B_FALSE;
- dm_di_mode = vap->va_mode;
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
dir_vp, DM_RIGHT_NULL, NULL,
DM_RIGHT_NULL, dir_name, NULL,
- dm_di_mode, 0, 0);
+ mode, 0, 0);
if (error)
return error;
dm_event_sent = 1;
@@ -2865,14 +2744,12 @@ xfs_mkdir(
/* Return through std_return after this point. */
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
mp = dp->i_mount;
udqp = gdqp = NULL;
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
- else if (vap->va_mask & XFS_AT_PROJID)
- prid = (xfs_prid_t)vap->va_projid;
else
prid = (xfs_prid_t)dfltprid;
@@ -2898,11 +2775,11 @@ xfs_mkdir(
}
if (error) {
cancel_flags = 0;
- dp = NULL;
goto error_return;
}
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+ unlock_dp_on_error = B_TRUE;
/*
* Check for directory link count overflow.
@@ -2925,7 +2802,7 @@ xfs_mkdir(
/*
* create the directory inode.
*/
- error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2,
+ error = xfs_dir_ialloc(&tp, dp, mode, 2,
0, credp, prid, resblks > 0,
&cdp, NULL);
if (error) {
@@ -2939,11 +2816,13 @@ xfs_mkdir(
* Now we add the directory inode to the transaction.
* We waited until now since xfs_dir_ialloc might start
* a new transaction. Had we joined the transaction
- * earlier, the locks might have gotten released.
+ * earlier, the locks might have gotten released. An error
+ * from here on will result in the transaction cancel
+ * unlocking dp so don't do it explicitly in the error path.
*/
VN_HOLD(dir_vp);
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- dp_joined_to_trans = B_TRUE;
+ unlock_dp_on_error = B_FALSE;
XFS_BMAP_INIT(&free_list, &first_block);
@@ -3010,15 +2889,14 @@ xfs_mkdir(
* xfs_trans_commit. */
std_return:
- if ( (created || (error != 0 && dm_event_sent != 0)) &&
- DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
- DM_EVENT_POSTCREATE)) {
+ if ((created || (error != 0 && dm_event_sent != 0)) &&
+ DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
dir_vp, DM_RIGHT_NULL,
created ? XFS_ITOV(cdp):NULL,
DM_RIGHT_NULL,
dir_name, NULL,
- dm_di_mode, error, 0);
+ mode, error, 0);
}
return error;
@@ -3032,56 +2910,43 @@ std_return:
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
- if (!dp_joined_to_trans && (dp != NULL)) {
+ if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL);
- }
goto std_return;
}
-
-/*
- * xfs_rmdir
- *
- */
-STATIC int
+int
xfs_rmdir(
- bhv_desc_t *dir_bdp,
- bhv_vname_t *dentry,
- cred_t *credp)
+ xfs_inode_t *dp,
+ bhv_vname_t *dentry)
{
+ bhv_vnode_t *dir_vp = XFS_ITOV(dp);
char *name = VNAME(dentry);
- xfs_inode_t *dp;
- xfs_inode_t *cdp; /* child directory */
+ int namelen = VNAMELEN(dentry);
+ xfs_mount_t *mp = dp->i_mount;
+ xfs_inode_t *cdp; /* child directory */
xfs_trans_t *tp;
- xfs_mount_t *mp;
int error;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
int cancel_flags;
int committed;
- bhv_vnode_t *dir_vp;
int dm_di_mode = S_IFDIR;
int last_cdp_link;
- int namelen;
uint resblks;
- dir_vp = BHV_TO_VNODE(dir_bdp);
- dp = XFS_BHVTOI(dir_bdp);
- mp = dp->i_mount;
-
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
- if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount))
+ if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- namelen = VNAMELEN(dentry);
if (!xfs_get_dir_entry(dentry, &cdp)) {
dm_di_mode = cdp->i_d.di_mode;
IRELE(cdp);
}
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
dir_vp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
@@ -3260,17 +3125,12 @@ xfs_rmdir(
}
- /*
- * Let interposed file systems know about removed links.
- */
- bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link);
-
IRELE(cdp);
/* Fall through to std_return with error = 0 or the errno
* from xfs_trans_commit. */
std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
dir_vp, DM_RIGHT_NULL,
NULL, DM_RIGHT_NULL,
@@ -3289,56 +3149,24 @@ xfs_rmdir(
goto std_return;
}
-
-/*
- * Read dp's entries starting at uiop->uio_offset and translate them into
- * bufsize bytes worth of struct dirents starting at bufbase.
- */
-STATIC int
-xfs_readdir(
- bhv_desc_t *dir_bdp,
- uio_t *uiop,
- cred_t *credp,
- int *eofp)
-{
- xfs_inode_t *dp;
- xfs_trans_t *tp = NULL;
- int error = 0;
- uint lock_mode;
-
- vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
- (inst_t *)__return_address);
- dp = XFS_BHVTOI(dir_bdp);
-
- if (XFS_FORCED_SHUTDOWN(dp->i_mount))
- return XFS_ERROR(EIO);
-
- lock_mode = xfs_ilock_map_shared(dp);
- error = xfs_dir_getdents(tp, dp, uiop, eofp);
- xfs_iunlock_map_shared(dp, lock_mode);
- return error;
-}
-
-
-STATIC int
+int
xfs_symlink(
- bhv_desc_t *dir_bdp,
+ xfs_inode_t *dp,
bhv_vname_t *dentry,
- bhv_vattr_t *vap,
char *target_path,
+ mode_t mode,
bhv_vnode_t **vpp,
cred_t *credp)
{
+ bhv_vnode_t *dir_vp = XFS_ITOV(dp);
+ xfs_mount_t *mp = dp->i_mount;
xfs_trans_t *tp;
- xfs_mount_t *mp;
- xfs_inode_t *dp;
xfs_inode_t *ip;
int error;
int pathlen;
xfs_bmap_free_t free_list;
xfs_fsblock_t first_block;
- boolean_t dp_joined_to_trans;
- bhv_vnode_t *dir_vp;
+ boolean_t unlock_dp_on_error = B_FALSE;
uint cancel_flags;
int committed;
xfs_fileoff_t first_fsb;
@@ -3357,16 +3185,12 @@ xfs_symlink(
int link_namelen;
*vpp = NULL;
- dir_vp = BHV_TO_VNODE(dir_bdp);
- dp = XFS_BHVTOI(dir_bdp);
- dp_joined_to_trans = B_FALSE;
error = 0;
ip = NULL;
tp = NULL;
- vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
- mp = dp->i_mount;
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -3405,7 +3229,7 @@ xfs_symlink(
}
}
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp,
DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
link_name, target_path, 0, 0, 0);
@@ -3418,8 +3242,6 @@ xfs_symlink(
udqp = gdqp = NULL;
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
- else if (vap->va_mask & XFS_AT_PROJID)
- prid = (xfs_prid_t)vap->va_projid;
else
prid = (xfs_prid_t)dfltprid;
@@ -3452,11 +3274,11 @@ xfs_symlink(
}
if (error) {
cancel_flags = 0;
- dp = NULL;
goto error_return;
}
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+ unlock_dp_on_error = B_TRUE;
/*
* Check whether the directory allows new symlinks or not.
@@ -3488,7 +3310,7 @@ xfs_symlink(
/*
* Allocate an inode for the symlink.
*/
- error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT),
+ error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT),
1, 0, credp, prid, resblks > 0, &ip, NULL);
if (error) {
if (error == ENOSPC)
@@ -3497,9 +3319,14 @@ xfs_symlink(
}
ITRACE(ip);
+ /*
+ * An error after we've joined dp to the transaction will result in the
+ * transaction cancel unlocking dp so don't do it explicitly in the
+ * error path.
+ */
VN_HOLD(dir_vp);
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
- dp_joined_to_trans = B_TRUE;
+ unlock_dp_on_error = B_FALSE;
/*
* Also attach the dquot(s) to it, if applicable.
@@ -3605,8 +3432,7 @@ xfs_symlink(
/* Fall through to std_return with error = 0 or errno from
* xfs_trans_commit */
std_return:
- if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
- DM_EVENT_POSTSYMLINK)) {
+ if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) {
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
dir_vp, DM_RIGHT_NULL,
error ? NULL : XFS_ITOV(ip),
@@ -3633,9 +3459,8 @@ std_return:
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
- if (!dp_joined_to_trans && (dp != NULL)) {
+ if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL);
- }
goto std_return;
}
@@ -3647,20 +3472,16 @@ std_return:
* A fid routine that takes a pointer to a previously allocated
* fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
*/
-STATIC int
+int
xfs_fid2(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
fid_t *fidp)
{
- xfs_inode_t *ip;
- xfs_fid2_t *xfid;
+ xfs_fid2_t *xfid = (xfs_fid2_t *)fidp;
- vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
- (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
- xfid = (xfs_fid2_t *)fidp;
- ip = XFS_BHVTOI(bdp);
xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
xfid->fid_pad = 0;
/*
@@ -3674,21 +3495,13 @@ xfs_fid2(
}
-/*
- * xfs_rwlock
- */
int
xfs_rwlock(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
bhv_vrwlock_t locktype)
{
- xfs_inode_t *ip;
- bhv_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- if (VN_ISDIR(vp))
+ if (S_ISDIR(ip->i_d.di_mode))
return 1;
- ip = XFS_BHVTOI(bdp);
if (locktype == VRWLOCK_WRITE) {
xfs_ilock(ip, XFS_IOLOCK_EXCL);
} else if (locktype == VRWLOCK_TRY_READ) {
@@ -3705,21 +3518,13 @@ xfs_rwlock(
}
-/*
- * xfs_rwunlock
- */
void
xfs_rwunlock(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
bhv_vrwlock_t locktype)
{
- xfs_inode_t *ip;
- bhv_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- if (VN_ISDIR(vp))
- return;
- ip = XFS_BHVTOI(bdp);
+ if (S_ISDIR(ip->i_d.di_mode))
+ return;
if (locktype == VRWLOCK_WRITE) {
/*
* In the write case, we may have added a new entry to
@@ -3737,20 +3542,16 @@ xfs_rwunlock(
return;
}
-STATIC int
+
+int
xfs_inode_flush(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
int flags)
{
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- xfs_inode_log_item_t *iip;
+ xfs_mount_t *mp = ip->i_mount;
+ xfs_inode_log_item_t *iip = ip->i_itemp;
int error = 0;
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
- iip = ip->i_itemp;
-
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -3819,24 +3620,20 @@ xfs_inode_flush(
return error;
}
+
int
-xfs_set_dmattrs (
- bhv_desc_t *bdp,
+xfs_set_dmattrs(
+ xfs_inode_t *ip,
u_int evmask,
- u_int16_t state,
- cred_t *credp)
+ u_int16_t state)
{
- xfs_inode_t *ip;
+ xfs_mount_t *mp = ip->i_mount;
xfs_trans_t *tp;
- xfs_mount_t *mp;
int error;
if (!capable(CAP_SYS_ADMIN))
return XFS_ERROR(EPERM);
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
-
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -3859,17 +3656,13 @@ xfs_set_dmattrs (
return error;
}
-STATIC int
+int
xfs_reclaim(
- bhv_desc_t *bdp)
+ xfs_inode_t *ip)
{
- xfs_inode_t *ip;
- bhv_vnode_t *vp;
-
- vp = BHV_TO_VNODE(bdp);
- ip = XFS_BHVTOI(bdp);
+ bhv_vnode_t *vp = XFS_ITOV(ip);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
ASSERT(!VN_MAPPED(vp));
@@ -3879,7 +3672,7 @@ xfs_reclaim(
return 0;
}
- vn_iowait(vp);
+ vn_iowait(ip);
ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
@@ -3911,7 +3704,8 @@ xfs_reclaim(
XFS_MOUNT_ILOCK(mp);
spin_lock(&ip->i_flags_lock);
__xfs_iflags_set(ip, XFS_IRECLAIMABLE);
- vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
+ vn_to_inode(vp)->i_private = NULL;
+ ip->i_vnode = NULL;
spin_unlock(&ip->i_flags_lock);
list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
XFS_MOUNT_IUNLOCK(mp);
@@ -3925,7 +3719,7 @@ xfs_finish_reclaim(
int locked,
int sync_mode)
{
- xfs_ihash_t *ih = ip->i_hash;
+ xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino);
bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
int error;
@@ -3937,12 +3731,12 @@ xfs_finish_reclaim(
* Once we have the XFS_IRECLAIM flag set it will not touch
* us.
*/
- write_lock(&ih->ih_lock);
+ write_lock(&pag->pag_ici_lock);
spin_lock(&ip->i_flags_lock);
if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
(!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
spin_unlock(&ip->i_flags_lock);
- write_unlock(&ih->ih_lock);
+ write_unlock(&pag->pag_ici_lock);
if (locked) {
xfs_ifunlock(ip);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -3951,7 +3745,8 @@ xfs_finish_reclaim(
}
__xfs_iflags_set(ip, XFS_IRECLAIM);
spin_unlock(&ip->i_flags_lock);
- write_unlock(&ih->ih_lock);
+ write_unlock(&pag->pag_ici_lock);
+ xfs_put_perag(ip->i_mount, pag);
/*
* If the inode is still dirty, then flush it out. If the inode
@@ -4085,7 +3880,7 @@ xfs_alloc_file_space(
int committed;
int error;
- vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -4109,7 +3904,7 @@ xfs_alloc_file_space(
/* Generate a DMAPI event if needed. */
if (alloc_type != 0 && offset < ip->i_size &&
(attr_flags&ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
+ DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
xfs_off_t end_dmi_offset;
end_dmi_offset = offset+len;
@@ -4223,9 +4018,8 @@ retry:
allocatesize_fsb -= allocated_fsb;
}
dmapi_enospc_check:
- if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) {
-
+ if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 &&
+ DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) {
error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
XFS_ITOV(ip), DM_RIGHT_NULL,
XFS_ITOV(ip), DM_RIGHT_NULL,
@@ -4356,7 +4150,7 @@ xfs_free_file_space(
vp = XFS_ITOV(ip);
mp = ip->i_mount;
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
return error;
@@ -4369,9 +4163,8 @@ xfs_free_file_space(
end_dmi_offset = offset + len;
endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
- if (offset < ip->i_size &&
- (attr_flags & ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
+ if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 &&
+ DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
if (end_dmi_offset > ip->i_size)
end_dmi_offset = ip->i_size;
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
@@ -4385,7 +4178,7 @@ xfs_free_file_space(
need_iolock = 0;
if (need_iolock) {
xfs_ilock(ip, XFS_IOLOCK_EXCL);
- vn_iowait(vp); /* wait for the completion of any pending DIOs */
+ vn_iowait(ip); /* wait for the completion of any pending DIOs */
}
rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
@@ -4394,7 +4187,8 @@ xfs_free_file_space(
if (VN_CACHED(vp) != 0) {
xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
ctooff(offtoct(ioffset)), -1);
- error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
+ error = xfs_flushinval_pages(ip,
+ ctooff(offtoct(ioffset)),
-1, FI_REMAPF_LOCKED);
if (error)
goto out_unlock_iolock;
@@ -4545,35 +4339,29 @@ xfs_free_file_space(
*/
int
xfs_change_file_space(
- bhv_desc_t *bdp,
+ xfs_inode_t *ip,
int cmd,
xfs_flock64_t *bf,
xfs_off_t offset,
cred_t *credp,
int attr_flags)
{
+ xfs_mount_t *mp = ip->i_mount;
int clrprealloc;
int error;
xfs_fsize_t fsize;
- xfs_inode_t *ip;
- xfs_mount_t *mp;
int setprealloc;
xfs_off_t startoffset;
xfs_off_t llen;
xfs_trans_t *tp;
bhv_vattr_t va;
- bhv_vnode_t *vp;
- vp = BHV_TO_VNODE(bdp);
- vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
- ip = XFS_BHVTOI(bdp);
- mp = ip->i_mount;
+ vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
/*
* must be a regular file and have write permission
*/
- if (!VN_ISREG(vp))
+ if (!S_ISREG(ip->i_d.di_mode))
return XFS_ERROR(EINVAL);
xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -4655,7 +4443,7 @@ xfs_change_file_space(
va.va_mask = XFS_AT_SIZE;
va.va_size = startoffset;
- error = xfs_setattr(bdp, &va, attr_flags, credp);
+ error = xfs_setattr(ip, &va, attr_flags, credp);
if (error)
return error;
@@ -4714,46 +4502,3 @@ xfs_change_file_space(
return error;
}
-
-bhv_vnodeops_t xfs_vnodeops = {
- BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
- .vop_open = xfs_open,
- .vop_read = xfs_read,
-#ifdef HAVE_SPLICE
- .vop_splice_read = xfs_splice_read,
- .vop_splice_write = xfs_splice_write,
-#endif
- .vop_write = xfs_write,
- .vop_ioctl = xfs_ioctl,
- .vop_getattr = xfs_getattr,
- .vop_setattr = xfs_setattr,
- .vop_access = xfs_access,
- .vop_lookup = xfs_lookup,
- .vop_create = xfs_create,
- .vop_remove = xfs_remove,
- .vop_link = xfs_link,
- .vop_rename = xfs_rename,
- .vop_mkdir = xfs_mkdir,
- .vop_rmdir = xfs_rmdir,
- .vop_readdir = xfs_readdir,
- .vop_symlink = xfs_symlink,
- .vop_readlink = xfs_readlink,
- .vop_fsync = xfs_fsync,
- .vop_inactive = xfs_inactive,
- .vop_fid2 = xfs_fid2,
- .vop_rwlock = xfs_rwlock,
- .vop_rwunlock = xfs_rwunlock,
- .vop_bmap = xfs_bmap,
- .vop_reclaim = xfs_reclaim,
- .vop_attr_get = xfs_attr_get,
- .vop_attr_set = xfs_attr_set,
- .vop_attr_remove = xfs_attr_remove,
- .vop_attr_list = xfs_attr_list,
- .vop_link_removed = (vop_link_removed_t)fs_noval,
- .vop_vnode_change = (vop_vnode_change_t)fs_noval,
- .vop_tosspages = fs_tosspages,
- .vop_flushinval_pages = fs_flushinval_pages,
- .vop_flush_pages = fs_flush_pages,
- .vop_release = xfs_release,
- .vop_iflush = xfs_inode_flush,
-};
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
new file mode 100644
index 00000000000..f36e74f2f0c
--- /dev/null
+++ b/fs/xfs/xfs_vnodeops.h
@@ -0,0 +1,86 @@
+#ifndef _XFS_VNODEOPS_H
+#define _XFS_VNODEOPS_H 1
+
+struct attrlist_cursor_kern;
+struct bhv_vattr;
+struct cred;
+struct file;
+struct inode;
+struct iovec;
+struct kiocb;
+struct pipe_inode_info;
+struct uio;
+struct xfs_inode;
+struct xfs_iomap;
+
+
+int xfs_open(struct xfs_inode *ip);
+int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags);
+int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags,
+ struct cred *credp);
+int xfs_access(struct xfs_inode *ip, int mode, struct cred *credp);
+int xfs_readlink(struct xfs_inode *ip, char *link);
+int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start,
+ xfs_off_t stop);
+int xfs_release(struct xfs_inode *ip);
+int xfs_inactive(struct xfs_inode *ip);
+int xfs_lookup(struct xfs_inode *dp, bhv_vname_t *dentry,
+ bhv_vnode_t **vpp);
+int xfs_create(struct xfs_inode *dp, bhv_vname_t *dentry, mode_t mode,
+ xfs_dev_t rdev, bhv_vnode_t **vpp, struct cred *credp);
+int xfs_remove(struct xfs_inode *dp, bhv_vname_t *dentry);
+int xfs_link(struct xfs_inode *tdp, bhv_vnode_t *src_vp,
+ bhv_vname_t *dentry);
+int xfs_mkdir(struct xfs_inode *dp, bhv_vname_t *dentry,
+ mode_t mode, bhv_vnode_t **vpp, struct cred *credp);
+int xfs_rmdir(struct xfs_inode *dp, bhv_vname_t *dentry);
+int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize,
+ xfs_off_t *offset, filldir_t filldir);
+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_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);
+int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
+int xfs_reclaim(struct xfs_inode *ip);
+int xfs_change_file_space(struct xfs_inode *ip, int cmd,
+ xfs_flock64_t *bf, xfs_off_t offset,
+ struct cred *credp, int attr_flags);
+int xfs_rename(struct xfs_inode *src_dp, bhv_vname_t *src_vname,
+ bhv_vnode_t *target_dir_vp, bhv_vname_t *target_vname);
+int xfs_attr_get(struct xfs_inode *ip, const char *name, char *value,
+ int *valuelenp, int flags, cred_t *cred);
+int xfs_attr_set(struct xfs_inode *dp, const char *name, char *value,
+ int valuelen, int flags);
+int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags);
+int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
+ int flags, struct attrlist_cursor_kern *cursor);
+int xfs_ioctl(struct xfs_inode *ip, struct file *filp,
+ int ioflags, unsigned int cmd, void __user *arg);
+ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb,
+ const struct iovec *iovp, unsigned int segs,
+ loff_t *offset, int ioflags);
+ssize_t xfs_sendfile(struct xfs_inode *ip, struct file *filp,
+ loff_t *offset, int ioflags, size_t count,
+ read_actor_t actor, void *target);
+ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp,
+ loff_t *ppos, struct pipe_inode_info *pipe, size_t count,
+ int flags, int ioflags);
+ssize_t xfs_splice_write(struct xfs_inode *ip,
+ struct pipe_inode_info *pipe, struct file *outfilp,
+ loff_t *ppos, size_t count, int flags, int ioflags);
+ssize_t xfs_write(struct xfs_inode *xip, struct kiocb *iocb,
+ const struct iovec *iovp, unsigned int nsegs,
+ loff_t *offset, int ioflags);
+int xfs_bmap(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
+ int flags, struct xfs_iomap *iomapp, int *niomaps);
+void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first,
+ xfs_off_t last, int fiopt);
+int xfs_flushinval_pages(struct xfs_inode *ip, xfs_off_t first,
+ xfs_off_t last, int fiopt);
+int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
+ xfs_off_t last, uint64_t flags, int fiopt);
+
+#endif /* _XFS_VNODEOPS_H */
diff --git a/include/Kbuild b/include/Kbuild
index 2d03f995865..b5228877434 100644
--- a/include/Kbuild
+++ b/include/Kbuild
@@ -1,6 +1,5 @@
header-y += asm-generic/
header-y += linux/
-header-y += scsi/
header-y += sound/
header-y += mtd/
header-y += rdma/
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 9e71201000d..381b4f5b4d5 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -2,6 +2,7 @@
#define _ALPHA_BITOPS_H
#include <asm/compiler.h>
+#include <asm/barrier.h>
/*
* Copyright 1994, Linus Torvalds.
@@ -69,6 +70,13 @@ clear_bit(unsigned long nr, volatile void * addr)
:"Ir" (1UL << (nr & 31)), "m" (*m));
}
+static inline void
+clear_bit_unlock(unsigned long nr, volatile void * addr)
+{
+ smp_mb();
+ clear_bit(nr, addr);
+}
+
/*
* WARNING: non atomic version.
*/
@@ -81,6 +89,13 @@ __clear_bit(unsigned long nr, volatile void * addr)
}
static inline void
+__clear_bit_unlock(unsigned long nr, volatile void * addr)
+{
+ smp_mb();
+ __clear_bit(nr, addr);
+}
+
+static inline void
change_bit(unsigned long nr, volatile void * addr)
{
unsigned long temp;
@@ -117,6 +132,36 @@ test_and_set_bit(unsigned long nr, volatile void *addr)
int *m = ((int *) addr) + (nr >> 5);
__asm__ __volatile__(
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ "1: ldl_l %0,%4\n"
+ " and %0,%3,%2\n"
+ " bne %2,2f\n"
+ " xor %0,%3,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,3f\n"
+ "2:\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
+
+ return oldbit != 0;
+}
+
+static inline int
+test_and_set_bit_lock(unsigned long nr, volatile void *addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ int *m = ((int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
"1: ldl_l %0,%4\n"
" and %0,%3,%2\n"
" bne %2,2f\n"
@@ -158,6 +203,9 @@ test_and_clear_bit(unsigned long nr, volatile void * addr)
int *m = ((int *) addr) + (nr >> 5);
__asm__ __volatile__(
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
"1: ldl_l %0,%4\n"
" and %0,%3,%2\n"
" beq %2,2f\n"
@@ -199,6 +247,9 @@ test_and_change_bit(unsigned long nr, volatile void * addr)
int *m = ((int *) addr) + (nr >> 5);
__asm__ __volatile__(
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
"1: ldl_l %0,%4\n"
" and %0,%3,%2\n"
" xor %0,%3,%0\n"
diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
index 6c2d78fba26..4b518e3b952 100644
--- a/include/asm-alpha/elf.h
+++ b/include/asm-alpha/elf.h
@@ -155,6 +155,7 @@ extern int alpha_l1d_cacheshape;
extern int alpha_l2_cacheshape;
extern int alpha_l3_cacheshape;
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \
do { \
NEW_AUX_ENT(AT_L1I_CACHESHAPE, alpha_l1i_cacheshape); \
diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h
index 6a9f02af952..0be50413b2b 100644
--- a/include/asm-alpha/floppy.h
+++ b/include/asm-alpha/floppy.h
@@ -91,8 +91,6 @@ static int FDC2 = -1;
#define N_FDC 2
#define N_DRIVE 8
-#define FLOPPY_MOTOR_MASK 0xf0
-
/*
* Most Alphas have no problems with floppy DMA crossing 64k borders,
* except for certain ones, like XL and RUFFIAN.
diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h
index ab5b60dcef1..38f18cf18c9 100644
--- a/include/asm-alpha/io.h
+++ b/include/asm-alpha/io.h
@@ -551,12 +551,6 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
#endif
#define RTC_ALWAYS_BCD 0
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
/*
* Some mucking forons use if[n]def writeq to check if platform has it.
* It's a bloody bad idea and we probably want ARCH_HAS_WRITEQ for them
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h
index bae7f05716d..8cc97bfd378 100644
--- a/include/asm-alpha/page.h
+++ b/include/asm-alpha/page.h
@@ -3,11 +3,12 @@
#ifdef __KERNEL__
+#include <linux/const.h>
#include <asm/pal.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 13
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#ifndef __ASSEMBLY__
diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h
index 9933b8b3612..32c7a5cddd5 100644
--- a/include/asm-alpha/ptrace.h
+++ b/include/asm-alpha/ptrace.h
@@ -68,8 +68,6 @@ struct switch_stack {
#ifdef __KERNEL__
-#define __ARCH_SYS_PTRACE 1
-
#define user_mode(regs) (((regs)->ps & 8) != 0)
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
diff --git a/include/asm-alpha/semaphore.h b/include/asm-alpha/semaphore.h
index 1a6295f2c2d..f1e9278a9fe 100644
--- a/include/asm-alpha/semaphore.h
+++ b/include/asm-alpha/semaphore.h
@@ -30,7 +30,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init(struct semaphore *sem, int val)
{
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index 620c4d86cbf..fd9dc889f36 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -48,6 +48,7 @@
#ifndef __ASSEMBLY__
#include <linux/kernel.h>
+#define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */
/*
* This is the logout header that should be common to all platforms
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
index 7dbc7bbba65..3ed9ec8b9f0 100644
--- a/include/asm-arm/arch-imx/imxfb.h
+++ b/include/asm-arm/arch-imx/imxfb.h
@@ -7,6 +7,7 @@ struct imxfb_mach_info {
u_short xres;
u_short yres;
+ u_int nonstd;
u_char bpp;
u_char hsync_len;
u_char left_margin;
diff --git a/include/asm-arm/arch-ixp23xx/platform.h b/include/asm-arm/arch-ixp23xx/platform.h
index 56e16d66645..db8aa304c93 100644
--- a/include/asm-arm/arch-ixp23xx/platform.h
+++ b/include/asm-arm/arch-ixp23xx/platform.h
@@ -14,17 +14,17 @@
#ifndef __ASSEMBLY__
-extern inline unsigned long ixp2000_reg_read(volatile void *reg)
+static inline unsigned long ixp2000_reg_read(volatile void *reg)
{
return *((volatile unsigned long *)reg);
}
-extern inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
-extern inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
+static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
diff --git a/include/asm-arm/arch-ns9xxx/clock.h b/include/asm-arm/arch-ns9xxx/clock.h
index bf30cbdcc2b..b943d3a92a1 100644
--- a/include/asm-arm/arch-ns9xxx/clock.h
+++ b/include/asm-arm/arch-ns9xxx/clock.h
@@ -19,7 +19,7 @@
static inline u32 ns9xxx_systemclock(void) __attribute__((const));
static inline u32 ns9xxx_systemclock(void)
{
- u32 pll = SYS_PLL;
+ u32 pll = __raw_readl(SYS_PLL);
/*
* The system clock should be a multiple of HZ * TIMERCLOCKSELECT (in
@@ -46,8 +46,8 @@ static inline u32 ns9xxx_systemclock(void)
*
* Fine.
*/
- return CRYSTAL * (REGGET(pll, SYS_PLL, ND) + 1)
- >> REGGET(pll, SYS_PLL, FS);
+ return CRYSTAL * (REGGETIM(pll, SYS_PLL, ND) + 1)
+ >> REGGETIM(pll, SYS_PLL, FS);
}
static inline u32 ns9xxx_cpuclock(void) __attribute__((const));
diff --git a/include/asm-arm/arch-ns9xxx/gpio.h b/include/asm-arm/arch-ns9xxx/gpio.h
new file mode 100644
index 00000000000..adbca08583c
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/gpio.h
@@ -0,0 +1,47 @@
+/*
+ * include/asm-arm/arch-ns9xxx/gpio.h
+ *
+ * Copyright (C) 2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * 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.
+*/
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <asm/errno.h>
+
+int gpio_request(unsigned gpio, const char *label);
+
+void gpio_free(unsigned gpio);
+
+int ns9xxx_gpio_configure(unsigned gpio, int inv, int func);
+
+int gpio_direction_input(unsigned gpio);
+
+int gpio_direction_output(unsigned gpio, int value);
+
+int gpio_get_value(unsigned gpio);
+
+void gpio_set_value(unsigned gpio, int value);
+
+/*
+ * ns9xxx can use gpio pins to trigger an irq, but it's not generic
+ * enough to be supported by the gpio_to_irq/irq_to_gpio interface
+ */
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ return -EINVAL;
+}
+
+/* get the cansleep() stubs */
+#include <asm-generic/gpio.h>
+
+#endif /* ifndef __ASM_ARCH_GPIO_H */
diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h
index 25600554c4f..0b7b34603f1 100644
--- a/include/asm-arm/arch-ns9xxx/hardware.h
+++ b/include/asm-arm/arch-ns9xxx/hardware.h
@@ -27,42 +27,53 @@
#define io_v2p(x) ((((x) & 0x0f000000) << 4) \
+ ((x) & 0x00ffffff))
+#define __REGSHIFT(mask) ((mask) & (-(mask)))
+
#define __REGBIT(bit) ((u32)1 << (bit))
#define __REGBITS(hbit, lbit) ((((u32)1 << ((hbit) - (lbit) + 1)) - 1) << (lbit))
-#define __REGVAL(mask, value) (((value) * ((mask) & (-(mask))) & (mask)))
+#define __REGVAL(mask, value) (((value) * __REGSHIFT(mask)) & (mask))
#ifndef __ASSEMBLY__
-# define __REG(x) (*((volatile u32 *)io_p2v((x))))
-# define __REG2(x, y) (*((volatile u32 *)io_p2v((x)) + (y)))
+# define __REG(x) ((void __iomem __force *)io_p2v((x)))
+# define __REG2(x, y) ((void __iomem __force *)(io_p2v((x)) + 4 * (y)))
-# define __REGB(x) (*((volatile u8 *)io_p2v((x))))
-# define __REGB2(x) (*((volatile u8 *)io_p2v((x)) + (y)))
+# define __REGSET(var, field, value) \
+ ((var) = (((var) & ~((field) & ~(value))) | (value)))
# define REGSET(var, reg, field, value) \
- ((var) = (((var) \
- & ~(reg ## _ ## field & \
- ~ reg ## _ ## field ## _ ## value)) \
- | (reg ## _ ## field ## _ ## value)))
+ __REGSET(var, reg ## _ ## field, reg ## _ ## field ## _ ## value)
+
+# define REGSET_IDX(var, reg, field, idx, value) \
+ __REGSET(var, reg ## _ ## field((idx)), reg ## _ ## field ## _ ## value((idx)))
# define REGSETIM(var, reg, field, value) \
- ((var) = (((var) \
- & ~(reg ## _ ## field & \
- ~(__REGVAL(reg ## _ ## field, value)))) \
- | (__REGVAL(reg ## _ ## field, value))))
+ __REGSET(var, reg ## _ ## field, __REGVAL(reg ## _ ## field, (value)))
+
+# define REGSETIM_IDX(var, reg, field, idx, value) \
+ __REGSET(var, reg ## _ ## field((idx)), __REGVAL(reg ## _ ## field((idx)), (value)))
+
+# define __REGGET(var, field) \
+ (((var) & (field)))
# define REGGET(var, reg, field) \
- ((var & (reg ## _ ## field)) / \
- ((reg ## _ ## field) & (-(reg ## _ ## field))))
+ __REGGET(var, reg ## _ ## field)
+
+# define REGGET_IDX(var, reg, field, idx) \
+ __REGGET(var, reg ## _ ## field((idx)))
+
+# define REGGETIM(var, reg, field) \
+ __REGGET(var, reg ## _ ## field) / __REGSHIFT(reg ## _ ## field)
+
+# define REGGETIM_IDX(var, reg, field, idx) \
+ __REGGET(var, reg ## _ ## field((idx))) / \
+ __REGSHIFT(reg ## _ ## field((idx)))
#else
# define __REG(x) io_p2v(x)
# define __REG2(x, y) io_p2v((x) + (y))
-# define __REGB(x) __REG((x))
-# define __REGB2(x, y) __REG2((x), (y))
-
#endif
#endif /* ifndef __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h b/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
index c3dc532dd20..afa3a9db3e1 100644
--- a/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
+++ b/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
@@ -18,7 +18,7 @@
#define FPGA_UARTC_BASE io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x10)
#define FPGA_UARTD_BASE io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x18)
-#define FPGA_IER __REGB(NS9XXX_CSxSTAT_PHYS(0) + 0x50)
-#define FPGA_ISR __REGB(NS9XXX_CSxSTAT_PHYS(0) + 0x60)
+#define FPGA_IER __REG(NS9XXX_CSxSTAT_PHYS(0) + 0x50)
+#define FPGA_ISR __REG(NS9XXX_CSxSTAT_PHYS(0) + 0x60)
#endif /* ifndef __ASM_ARCH_REGSBOARDA9M9750_H */
diff --git a/include/asm-arm/arch-ns9xxx/system.h b/include/asm-arm/arch-ns9xxx/system.h
index e3cd4d31b3f..c1082bd8977 100644
--- a/include/asm-arm/arch-ns9xxx/system.h
+++ b/include/asm-arm/arch-ns9xxx/system.h
@@ -24,9 +24,9 @@ static inline void arch_reset(char mode)
{
u32 reg;
- reg = SYS_PLL >> 16;
+ reg = __raw_readl(SYS_PLL) >> 16;
REGSET(reg, SYS_PLL, SWC, YES);
- SYS_PLL = reg;
+ __raw_writel(reg, SYS_PLL);
BUG();
}
diff --git a/include/asm-arm/arch-omap/blizzard.h b/include/asm-arm/arch-omap/blizzard.h
new file mode 100644
index 00000000000..8d160f17137
--- /dev/null
+++ b/include/asm-arm/arch-omap/blizzard.h
@@ -0,0 +1,12 @@
+#ifndef _BLIZZARD_H
+#define _BLIZZARD_H
+
+struct blizzard_platform_data {
+ void (*power_up)(struct device *dev);
+ void (*power_down)(struct device *dev);
+ unsigned long (*get_clock_rate)(struct device *dev);
+
+ unsigned te_connected : 1;
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/board-2430sdp.h b/include/asm-arm/arch-omap/board-2430sdp.h
new file mode 100644
index 00000000000..e9c65ce3cb1
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-2430sdp.h
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-2430sdp.h
+ *
+ * Hardware definitions for TI OMAP2430 SDP board.
+ *
+ * Based on board-h4.h by Dirk Behme <dirk.behme@de.bosch.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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP_2430SDP_H
+#define __ASM_ARCH_OMAP_2430SDP_H
+
+/* Placeholder for 2430SDP specific defines */
+#define OMAP24XX_ETHR_START 0x08000300
+#define OMAP24XX_ETHR_GPIO_IRQ 149
+#define SDP2430_CS0_BASE 0x04000000
+
+#define TWL4030_IRQNUM INT_24XX_SYS_NIRQ
+
+/* TWL4030 Primary Interrupt Handler (PIH) interrupts */
+#define IH_TWL4030_BASE IH_BOARD_BASE
+#define IH_TWL4030_END (IH_TWL4030_BASE+8)
+#define NR_IRQS (IH_TWL4030_END)
+
+#endif /* __ASM_ARCH_OMAP_2430SDP_H */
diff --git a/include/asm-arm/arch-omap/board-palmte.h b/include/asm-arm/arch-omap/board-palmte.h
new file mode 100644
index 00000000000..cd22035a716
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-palmte.h
@@ -0,0 +1,34 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-palmte.h
+ *
+ * Hardware definitions for the Palm Tungsten E device.
+ *
+ * Maintainters : http://palmtelinux.sf.net
+ * palmtelinux-developpers@lists.sf.net
+ *
+ * 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.
+ */
+
+#ifndef __OMAP_BOARD_PALMTE_H
+#define __OMAP_BOARD_PALMTE_H
+
+#include <asm/arch/gpio.h>
+
+#define PALMTE_USBDETECT_GPIO 0
+#define PALMTE_USB_OR_DC_GPIO 1
+#define PALMTE_TSC_GPIO 4
+#define PALMTE_PINTDAV_GPIO 6
+#define PALMTE_MMC_WP_GPIO 8
+#define PALMTE_MMC_POWER_GPIO 9
+#define PALMTE_HDQ_GPIO 11
+#define PALMTE_HEADPHONES_GPIO 14
+#define PALMTE_SPEAKER_GPIO 15
+#define PALMTE_DC_GPIO OMAP_MPUIO(2)
+#define PALMTE_MMC_SWITCH_GPIO OMAP_MPUIO(4)
+#define PALMTE_MMC1_GPIO OMAP_MPUIO(6)
+#define PALMTE_MMC2_GPIO OMAP_MPUIO(7)
+#define PALMTE_MMC3_GPIO OMAP_MPUIO(11)
+
+#endif /* __OMAP_BOARD_PALMTE_H */
diff --git a/include/asm-arm/arch-omap/board-palmtt.h b/include/asm-arm/arch-omap/board-palmtt.h
new file mode 100644
index 00000000000..d9590b0ec90
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-palmtt.h
@@ -0,0 +1,23 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-palmte.h
+ *
+ * Hardware definitions for the Palm Tungsten|T device.
+ *
+ * Maintainters : Marek Vasut <marek.vasut@gmail.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
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __OMAP_BOARD_PALMTT_H
+#define __OMAP_BOARD_PALMTT_H
+
+#define PALMTT_USBDETECT_GPIO 0
+#define PALMTT_CABLE_GPIO 1
+#define PALMTT_LED_GPIO 3
+#define PALMTT_PENIRQ_GPIO 6
+#define PALMTT_MMC_WP_GPIO 8
+#define PALMTT_HDQ_GPIO 11
+
+#endif /* __OMAP_BOARD_PALMTT_H */
diff --git a/include/asm-arm/arch-omap/board-palmz71.h b/include/asm-arm/arch-omap/board-palmz71.h
new file mode 100644
index 00000000000..1252a859787
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-palmz71.h
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-palmz71.h
+ *
+ * Hardware definitions for the Palm Zire71 device.
+ *
+ * Maintainters : Marek Vasut <marek.vasut@gmail.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
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __OMAP_BOARD_PALMZ71_H
+#define __OMAP_BOARD_PALMZ71_H
+
+#define PALMZ71_USBDETECT_GPIO 0
+#define PALMZ71_PENIRQ_GPIO 6
+#define PALMZ71_MMC_WP_GPIO 8
+#define PALMZ71_HDQ_GPIO 11
+
+#define PALMZ71_HOTSYNC_GPIO OMAP_MPUIO(1)
+#define PALMZ71_CABLE_GPIO OMAP_MPUIO(2)
+#define PALMZ71_SLIDER_GPIO OMAP_MPUIO(3)
+#define PALMZ71_MMC_IN_GPIO OMAP_MPUIO(4)
+
+#endif /* __OMAP_BOARD_PALMZ71_H */
diff --git a/include/asm-arm/arch-omap/board-sx1.h b/include/asm-arm/arch-omap/board-sx1.h
new file mode 100644
index 00000000000..2bb8dd6e2d1
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-sx1.h
@@ -0,0 +1,46 @@
+/*
+ * Siemens SX1 board definitions
+ *
+ * Copyright: Vovan888 at gmail com
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
+#define __ASM_ARCH_SX1_I2C_CHIPS_H
+
+#define SOFIA_MAX_LIGHT_VAL 0x2B
+
+#define SOFIA_I2C_ADDR 0x32
+/* Sofia reg 3 bits masks */
+#define SOFIA_POWER1_REG 0x03
+
+#define SOFIA_USB_POWER 0x01
+#define SOFIA_MMC_POWER 0x04
+#define SOFIA_BLUETOOTH_POWER 0x08
+#define SOFIA_MMILIGHT_POWER 0x20
+
+#define SOFIA_POWER2_REG 0x04
+#define SOFIA_BACKLIGHT_REG 0x06
+#define SOFIA_KEYLIGHT_REG 0x07
+#define SOFIA_DIMMING_REG 0x09
+
+
+/* Function Prototypes for SX1 devices control on I2C bus */
+
+int sx1_setbacklight(u8 backlight);
+int sx1_getbacklight(u8 *backlight);
+int sx1_setkeylight(u8 keylight);
+int sx1_getkeylight(u8 *keylight);
+
+int sx1_setmmipower(u8 onoff);
+int sx1_setusbpower(u8 onoff);
+int sx1_setmmcpower(u8 onoff);
+
+#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
diff --git a/include/asm-arm/arch-omap/board.h b/include/asm-arm/arch-omap/board.h
index 031672c5637..db44c5d1f1a 100644
--- a/include/asm-arm/arch-omap/board.h
+++ b/include/asm-arm/arch-omap/board.h
@@ -179,4 +179,8 @@ extern const void *omap_get_var_config(u16 tag, size_t *len);
extern struct omap_board_config_kernel *omap_board_config;
extern int omap_board_config_size;
+
+/* for TI reference platforms sharing the same debug card */
+extern int debug_card_init(u32 addr, unsigned gpio);
+
#endif
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index f7774192a41..f33b467fddb 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -417,7 +417,6 @@ extern void omap_free_lcd_dma(void);
extern void omap_setup_lcd_dma(void);
extern void omap_enable_lcd_dma(void);
extern void omap_stop_lcd_dma(void);
-extern int omap_lcd_dma_ext_running(void);
extern void omap_set_lcd_dma_ext_controller(int external);
extern void omap_set_lcd_dma_single_transfer(int single);
extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
diff --git a/include/asm-arm/arch-omap/eac.h b/include/asm-arm/arch-omap/eac.h
new file mode 100644
index 00000000000..6662cb02baf
--- /dev/null
+++ b/include/asm-arm/arch-omap/eac.h
@@ -0,0 +1,101 @@
+/*
+ * linux/include/asm-arm/arch-omap2/eac.h
+ *
+ * Defines for Enhanced Audio Controller
+ *
+ * Contact: Jarkko Nikula <jarkko.nikula@nokia.com>
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_OMAP2_EAC_H
+#define __ASM_ARM_ARCH_OMAP2_EAC_H
+
+#include <asm/arch/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/irq.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+
+/* master codec clock source */
+#define EAC_MCLK_EXT_MASK 0x100
+enum eac_mclk_src {
+ EAC_MCLK_INT_11290000, /* internal 96 MHz / 8.5 = 11.29 Mhz */
+ EAC_MCLK_EXT_11289600 = EAC_MCLK_EXT_MASK,
+ EAC_MCLK_EXT_12288000,
+ EAC_MCLK_EXT_2x11289600,
+ EAC_MCLK_EXT_2x12288000,
+};
+
+/* codec port interface mode */
+enum eac_codec_mode {
+ EAC_CODEC_PCM,
+ EAC_CODEC_AC97,
+ EAC_CODEC_I2S_MASTER, /* codec port, I.e. EAC is the master */
+ EAC_CODEC_I2S_SLAVE,
+};
+
+/* configuration structure for I2S mode */
+struct eac_i2s_conf {
+ /* if enabled, then first data slot (left channel) is signaled as
+ * positive level of frame sync EAC.AC_FS */
+ unsigned polarity_changed_mode:1;
+ /* if enabled, then serial data starts one clock cycle after the
+ * of EAC.AC_FS for first audio slot */
+ unsigned sync_delay_enable:1;
+};
+
+/* configuration structure for EAC codec port */
+struct eac_codec {
+ enum eac_mclk_src mclk_src;
+
+ enum eac_codec_mode codec_mode;
+ union {
+ struct eac_i2s_conf i2s;
+ } codec_conf;
+
+ int default_rate; /* audio sampling rate */
+
+ int (* set_power)(void *private_data, int dac, int adc);
+ int (* register_controls)(void *private_data,
+ struct snd_card *card);
+ const char *short_name;
+
+ void *private_data;
+};
+
+/* structure for passing platform dependent data to the EAC driver */
+struct eac_platform_data {
+ int (* init)(struct device *eac_dev);
+ void (* cleanup)(struct device *eac_dev);
+ /* these callbacks are used to configure & control external MCLK
+ * source. NULL if not used */
+ int (* enable_ext_clocks)(struct device *eac_dev);
+ void (* disable_ext_clocks)(struct device *eac_dev);
+};
+
+extern void omap_init_eac(struct eac_platform_data *pdata);
+
+extern int eac_register_codec(struct device *eac_dev, struct eac_codec *codec);
+extern void eac_unregister_codec(struct device *eac_dev);
+
+extern int eac_set_mode(struct device *eac_dev, int play, int rec);
+
+#endif /* __ASM_ARM_ARCH_OMAP2_EAC_H */
diff --git a/include/asm-arm/arch-omap/gpmc.h b/include/asm-arm/arch-omap/gpmc.h
index 995cc83482e..6a8e07ffc2d 100644
--- a/include/asm-arm/arch-omap/gpmc.h
+++ b/include/asm-arm/arch-omap/gpmc.h
@@ -23,9 +23,10 @@
#define GPMC_CS_NAND_DATA 0x24
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
-#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 20)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29)
+#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27)
#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27)
#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
@@ -80,6 +81,8 @@ struct gpmc_timings {
};
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
+extern unsigned long gpmc_get_fclk_period(void);
extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
extern u32 gpmc_cs_read_reg(int cs, int idx);
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index e225f4f39b3..da572092e25 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -318,6 +318,10 @@
#include "board-h4.h"
#endif
+#ifdef CONFIG_MACH_OMAP_2430SDP
+#include "board-2430sdp.h"
+#endif
+
#ifdef CONFIG_MACH_OMAP_APOLLON
#include "board-apollon.h"
#endif
@@ -330,6 +334,22 @@
#include "board-voiceblue.h"
#endif
+#ifdef CONFIG_MACH_OMAP_PALMTE
+#include "board-palmte.h"
+#endif
+
+#ifdef CONFIG_MACH_OMAP_PALMZ71
+#include "board-palmz71.h"
+#endif
+
+#ifdef CONFIG_MACH_OMAP_PALMTT
+#include "board-palmtt.h"
+#endif
+
+#ifdef CONFIG_MACH_SX1
+#include "board-sx1.h"
+#endif
+
#endif /* !__ASSEMBLER__ */
#endif /* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index 4aca7e3d756..289082d07f1 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -72,6 +72,16 @@
#define L4_24XX_PHYS L4_24XX_BASE /* 0x48000000 */
#define L4_24XX_VIRT 0xd8000000
#define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */
+
+#ifdef CONFIG_ARCH_OMAP2430
+#define L4_WK_243X_PHYS L4_WK_243X_BASE /* 0x49000000 */
+#define L4_WK_243X_VIRT 0xd9000000
+#define L4_WK_243X_SIZE SZ_1M
+#define OMAP243X_GPMC_PHYS OMAP243X_GPMC_BASE /* 0x49000000 */
+#define OMAP243X_GPMC_VIRT 0xFE000000
+#define OMAP243X_GPMC_SIZE SZ_1M
+#endif
+
#define IO_OFFSET 0x90000000
#define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
#define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
diff --git a/include/asm-arm/arch-omap/menelaus.h b/include/asm-arm/arch-omap/menelaus.h
index 82d276a6bd9..69ed7ee4017 100644
--- a/include/asm-arm/arch-omap/menelaus.h
+++ b/include/asm-arm/arch-omap/menelaus.h
@@ -7,6 +7,12 @@
#ifndef __ASM_ARCH_MENELAUS_H
#define __ASM_ARCH_MENELAUS_H
+struct device;
+
+struct menelaus_platform_data {
+ int (* late_init)(struct device *dev);
+};
+
extern int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
void *data);
extern void menelaus_unregister_mmc_callback(void);
@@ -20,6 +26,19 @@ extern int menelaus_set_vaux(unsigned int mV);
extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
extern int menelaus_set_slot_sel(int enable);
extern int menelaus_get_slot_pin_states(void);
+extern int menelaus_set_vcore_sw(unsigned int mV);
+extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
+
+#define EN_VPLL_SLEEP (1 << 7)
+#define EN_VMMC_SLEEP (1 << 6)
+#define EN_VAUX_SLEEP (1 << 5)
+#define EN_VIO_SLEEP (1 << 4)
+#define EN_VMEM_SLEEP (1 << 3)
+#define EN_DC3_SLEEP (1 << 2)
+#define EN_DC2_SLEEP (1 << 1)
+#define EN_VC_SLEEP (1 << 0)
+
+extern int menelaus_set_regulator_sleep(int enable, u32 val);
#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
#define omap_has_menelaus() 1
@@ -28,4 +47,3 @@ extern int menelaus_get_slot_pin_states(void);
#endif
#endif
-
diff --git a/include/asm-arm/arch-omap/mmc.h b/include/asm-arm/arch-omap/mmc.h
new file mode 100644
index 00000000000..b70e37b6124
--- /dev/null
+++ b/include/asm-arm/arch-omap/mmc.h
@@ -0,0 +1,66 @@
+/*
+ * MMC definitions for OMAP2
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * 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.
+ */
+
+#ifndef __OMAP2_MMC_H
+#define __OMAP2_MMC_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/mmc/host.h>
+
+#define OMAP_MMC_MAX_SLOTS 2
+
+struct omap_mmc_platform_data {
+ unsigned enabled:1;
+ /* number of slots on board */
+ unsigned nr_slots:2;
+ /* nomux means "standard" muxing is wrong on this board, and that
+ * board-specific code handled it before common init logic.
+ */
+ unsigned nomux:1;
+ /* 4 wire signaling is optional, and is only used for SD/SDIO and
+ * MMCv4 */
+ unsigned wire4:1;
+ /* set if your board has components or wiring that limits the
+ * maximum frequency on the MMC bus */
+ unsigned int max_freq;
+
+ /* switch the bus to a new slot */
+ int (* switch_slot)(struct device *dev, int slot);
+ /* initialize board-specific MMC functionality, can be NULL if
+ * not supported */
+ int (* init)(struct device *dev);
+ void (* cleanup)(struct device *dev);
+
+ struct omap_mmc_slot_data {
+ int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
+ int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
+ int (* get_ro)(struct device *dev, int slot);
+
+ /* return MMC cover switch state, can be NULL if not supported.
+ *
+ * possible return values:
+ * 0 - open
+ * 1 - closed
+ */
+ int (* get_cover_state)(struct device *dev, int slot);
+
+ const char *name;
+ u32 ocr_mask;
+ } slots[OMAP_MMC_MAX_SLOTS];
+};
+
+extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
+
+/* called from board-specific card detection service routine */
+extern void omap_mmc_notify_card_detect(struct device *dev, int slot, int detected);
+extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
+
+#endif
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index f1ec2edd404..b8fff50e6a8 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -406,6 +406,29 @@ enum omap1xxx_index {
V10_1610_CF_IREQ,
W10_1610_CF_RESET,
W11_1610_CF_CD1,
+
+ /* parallel camera */
+ J15_1610_CAM_LCLK,
+ J18_1610_CAM_D7,
+ J19_1610_CAM_D6,
+ J14_1610_CAM_D5,
+ K18_1610_CAM_D4,
+ K19_1610_CAM_D3,
+ K15_1610_CAM_D2,
+ K14_1610_CAM_D1,
+ L19_1610_CAM_D0,
+ L18_1610_CAM_VS,
+ L15_1610_CAM_HS,
+ M19_1610_CAM_RSTZ,
+ Y15_1610_CAM_OUTCLK,
+
+ /* serial camera */
+ H19_1610_CAM_EXCLK,
+ Y12_1610_CCP_CLKP,
+ W13_1610_CCP_CLKM,
+ W14_1610_CCP_DATAP,
+ Y14_1610_CCP_DATAM,
+
};
enum omap24xx_index {
diff --git a/include/asm-arm/arch-omap/omap24xx.h b/include/asm-arm/arch-omap/omap24xx.h
index 708b2fac77f..14c0f949657 100644
--- a/include/asm-arm/arch-omap/omap24xx.h
+++ b/include/asm-arm/arch-omap/omap24xx.h
@@ -8,6 +8,7 @@
*/
#define L4_24XX_BASE 0x48000000
+#define L4_WK_243X_BASE 0x49000000
#define L3_24XX_BASE 0x68000000
/* interrupt controller */
@@ -16,9 +17,20 @@
#define OMAP24XX_IVA_INTC_BASE 0x40000000
#define IRQ_SIR_IRQ 0x0040
+#ifdef CONFIG_ARCH_OMAP2420
#define OMAP24XX_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
#define OMAP24XX_PRCM_BASE (L4_24XX_BASE + 0x8000)
#define OMAP24XX_SDRC_BASE (L3_24XX_BASE + 0x9000)
+#define OMAP242X_CONTROL_STATUS (L4_24XX_BASE + 0x2f8)
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+#define OMAP24XX_32KSYNCT_BASE (L4_WK_243X_BASE + 0x20000)
+#define OMAP24XX_PRCM_BASE (L4_WK_243X_BASE + 0x6000)
+#define OMAP24XX_SDRC_BASE (0x6D000000)
+#define OMAP242X_CONTROL_STATUS (L4_24XX_BASE + 0x2f8)
+#define OMAP243X_GPMC_BASE 0x6E000000
+#endif
/* DSP SS */
#define OMAP24XX_DSP_BASE 0x58000000
diff --git a/include/asm-arm/arch-omap/onenand.h b/include/asm-arm/arch-omap/onenand.h
new file mode 100644
index 00000000000..6c959d0ce47
--- /dev/null
+++ b/include/asm-arm/arch-omap/onenand.h
@@ -0,0 +1,21 @@
+/*
+ * include/asm-arm/arch-omap/onenand.h
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Juha Yrjola
+ *
+ * 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.
+ */
+
+#include <linux/mtd/partitions.h>
+
+struct omap_onenand_platform_data {
+ int cs;
+ int gpio_irq;
+ struct mtd_partition *parts;
+ int nr_parts;
+ int (*onenand_setup)(void __iomem *);
+ int dma_channel;
+};
diff --git a/include/asm-arm/arch-pxa/cm-x270.h b/include/asm-arm/arch-pxa/cm-x270.h
new file mode 100644
index 00000000000..f8fac9e1800
--- /dev/null
+++ b/include/asm-arm/arch-pxa/cm-x270.h
@@ -0,0 +1,50 @@
+/*
+ * linux/include/asm/arch-pxa/cm-x270.h
+ *
+ * Copyright Compulab Ltd., 2003, 2007
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * 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.
+ */
+
+
+/* CM-x270 device physical addresses */
+#define CMX270_CS1_PHYS (PXA_CS1_PHYS)
+#define MARATHON_PHYS (PXA_CS2_PHYS)
+#define CMX270_IDE104_PHYS (PXA_CS3_PHYS)
+#define CMX270_IT8152_PHYS (PXA_CS4_PHYS)
+
+/* Statically mapped regions */
+#define CMX270_VIRT_BASE (0xe8000000)
+#define CMX270_IT8152_VIRT (CMX270_VIRT_BASE)
+#define CMX270_IDE104_VIRT (CMX270_IT8152_VIRT + SZ_64M)
+
+/* GPIO related definitions */
+#define GPIO_IT8152_IRQ (22)
+
+#define IRQ_GPIO_IT8152_IRQ IRQ_GPIO(GPIO_IT8152_IRQ)
+#define PME_IRQ IRQ_GPIO(0)
+#define CMX270_IDE_IRQ IRQ_GPIO(100)
+#define CMX270_GPIRQ1 IRQ_GPIO(101)
+#define CMX270_TOUCHIRQ IRQ_GPIO(96)
+#define CMX270_ETHIRQ IRQ_GPIO(10)
+#define CMX270_GFXIRQ IRQ_GPIO(95)
+#define CMX270_NANDIRQ IRQ_GPIO(89)
+#define CMX270_MMC_IRQ IRQ_GPIO(83)
+
+/* PCMCIA related definitions */
+#define PCC_DETECT(x) (GPLR(84 - (x)) & GPIO_bit(84 - (x)))
+#define PCC_READY(x) (GPLR(82 - (x)) & GPIO_bit(82 - (x)))
+
+#define PCMCIA_S0_CD_VALID IRQ_GPIO(84)
+#define PCMCIA_S0_CD_VALID_EDGE GPIO_BOTH_EDGES
+
+#define PCMCIA_S1_CD_VALID IRQ_GPIO(83)
+#define PCMCIA_S1_CD_VALID_EDGE GPIO_BOTH_EDGES
+
+#define PCMCIA_S0_RDYINT IRQ_GPIO(82)
+#define PCMCIA_S1_RDYINT IRQ_GPIO(81)
+
+#define PCMCIA_RESET_GPIO 53
diff --git a/include/asm-arm/arch-pxa/dma.h b/include/asm-arm/arch-pxa/dma.h
index 3280ee2ddfa..dbe110ee266 100644
--- a/include/asm-arm/arch-pxa/dma.h
+++ b/include/asm-arm/arch-pxa/dma.h
@@ -30,6 +30,10 @@ typedef enum {
DMA_PRIO_LOW = 2
} pxa_dma_prio;
+#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+#define HAVE_ARCH_PCI_SET_DMA_MASK 1
+#endif
+
/*
* DMA registration
*/
diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h
index 9e99241f3ed..9dbc2dc794f 100644
--- a/include/asm-arm/arch-pxa/gpio.h
+++ b/include/asm-arm/arch-pxa/gpio.h
@@ -38,16 +38,8 @@ static inline void gpio_free(unsigned gpio)
return;
}
-static inline int gpio_direction_input(unsigned gpio)
-{
- return pxa_gpio_mode(gpio | GPIO_IN);
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- return pxa_gpio_mode(gpio | GPIO_OUT |
- (value ? GPIO_DFLT_HIGH : GPIO_DFLT_LOW));
-}
+extern int gpio_direction_input(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio, int value);
static inline int __gpio_get_value(unsigned gpio)
{
diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h
index 38612174641..ab2d963e742 100644
--- a/include/asm-arm/arch-pxa/hardware.h
+++ b/include/asm-arm/arch-pxa/hardware.h
@@ -62,6 +62,7 @@
#ifndef __ASSEMBLY__
+#ifdef CONFIG_PXA25x
#define __cpu_is_pxa21x(id) \
({ \
unsigned int _id = (id) >> 4 & 0xf3f; \
@@ -73,12 +74,50 @@
unsigned int _id = (id) >> 4 & 0xfff; \
_id == 0x2d0 || _id == 0x290; \
})
+#else
+#define __cpu_is_pxa21x(id) (0)
+#define __cpu_is_pxa25x(id) (0)
+#endif
+#ifdef CONFIG_PXA27x
#define __cpu_is_pxa27x(id) \
({ \
unsigned int _id = (id) >> 4 & 0xfff; \
_id == 0x411; \
})
+#else
+#define __cpu_is_pxa27x(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA300
+#define __cpu_is_pxa300(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x688; \
+ })
+#else
+#define __cpu_is_pxa300(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA310
+#define __cpu_is_pxa310(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x689; \
+ })
+#else
+#define __cpu_is_pxa310(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA320
+#define __cpu_is_pxa320(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x603 || _id == 0x682; \
+ })
+#else
+#define __cpu_is_pxa320(id) (0)
+#endif
#define cpu_is_pxa21x() \
({ \
@@ -98,6 +137,53 @@
__cpu_is_pxa27x(id); \
})
+#define cpu_is_pxa300() \
+ ({ \
+ unsigned int id = read_cpuid(CPUID_ID); \
+ __cpu_is_pxa300(id); \
+ })
+
+#define cpu_is_pxa310() \
+ ({ \
+ unsigned int id = read_cpuid(CPUID_ID); \
+ __cpu_is_pxa310(id); \
+ })
+
+#define cpu_is_pxa320() \
+ ({ \
+ unsigned int id = read_cpuid(CPUID_ID); \
+ __cpu_is_pxa320(id); \
+ })
+
+/*
+ * CPUID Core Generation Bit
+ * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
+ * == 0x3 for pxa300/pxa310/pxa320
+ */
+#define __cpu_is_pxa2xx(id) \
+ ({ \
+ unsigned int _id = (id) >> 13 & 0x7; \
+ _id <= 0x2; \
+ })
+
+#define __cpu_is_pxa3xx(id) \
+ ({ \
+ unsigned int _id = (id) >> 13 & 0x7; \
+ _id == 0x3; \
+ })
+
+#define cpu_is_pxa2xx() \
+ ({ \
+ unsigned int id = read_cpuid(CPUID_ID); \
+ __cpu_is_pxa2xx(id); \
+ })
+
+#define cpu_is_pxa3xx() \
+ ({ \
+ unsigned int id = read_cpuid(CPUID_ID); \
+ __cpu_is_pxa3xx(id); \
+ })
+
/*
* Handy routine to set GPIO alternate functions
*/
@@ -116,14 +202,23 @@ extern void pxa_gpio_set_value(unsigned gpio, int value);
/*
* Routine to enable or disable CKEN
*/
-extern void pxa_set_cken(int clock, int enable);
+static inline void __deprecated pxa_set_cken(int clock, int enable)
+{
+ extern void __pxa_set_cken(int clock, int enable);
+ __pxa_set_cken(clock, enable);
+}
/*
* return current memory and LCD clock frequency in units of 10kHz
*/
extern unsigned int get_memclk_frequency_10khz(void);
-extern unsigned int get_lcdclk_frequency_10khz(void);
#endif
+#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+#define PCIBIOS_MIN_IO 0
+#define PCIBIOS_MIN_MEM 0
+#define pcibios_assign_all_busses() 1
+#endif
+
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index a07fe0f928c..6238dbf7a23 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -66,12 +66,6 @@
#define IRQ_TO_GPIO_2_x(i) ((i) - PXA_GPIO_IRQ_BASE)
#define IRQ_TO_GPIO(i) (((i) < IRQ_GPIO(2)) ? ((i) - IRQ_GPIO0) : IRQ_TO_GPIO_2_x(i))
-#if defined(CONFIG_PXA25x)
-#define PXA_LAST_GPIO 84
-#elif defined(CONFIG_PXA27x)
-#define PXA_LAST_GPIO 127
-#endif
-
/*
* The next 16 interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
@@ -216,3 +210,24 @@
#define IRQ_LOCOMO_GPIO_BASE (IRQ_BOARD_START + 1)
#define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2)
#define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3)
+
+/* ITE8152 irqs */
+/* add IT8152 IRQs beyond BOARD_END */
+#ifdef CONFIG_PCI_HOST_ITE8152
+#define IT8152_IRQ(x) (IRQ_GPIO(IRQ_BOARD_END) + 1 + (x))
+
+/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
+#define IT8152_LD_IRQ_COUNT 9
+#define IT8152_LP_IRQ_COUNT 16
+#define IT8152_PD_IRQ_COUNT 15
+
+/* Priorities: */
+#define IT8152_PD_IRQ(i) IT8152_IRQ(i)
+#define IT8152_LP_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT)
+#define IT8152_LD_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT)
+
+#define IT8152_LAST_IRQ IT8152_LD_IRQ(IT8152_LD_IRQ_COUNT - 1)
+
+#undef NR_IRQS
+#define NR_IRQS (IT8152_LAST_IRQ+1)
+#endif
diff --git a/include/asm-arm/arch-pxa/memory.h b/include/asm-arm/arch-pxa/memory.h
index e17f9881faf..bee81d66c18 100644
--- a/include/asm-arm/arch-pxa/memory.h
+++ b/include/asm-arm/arch-pxa/memory.h
@@ -39,4 +39,14 @@
*/
#define NODE_MEM_SIZE_BITS 26
+#if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+void cmx270_pci_adjust_zones(int node, unsigned long *size,
+ unsigned long *holes);
+
+#define arch_adjust_zones(node, size, holes) \
+ cmx270_pci_adjust_zones(node, size, holes)
+
+#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1)
+#endif
+
#endif
diff --git a/include/asm-arm/arch-pxa/mfp-pxa300.h b/include/asm-arm/arch-pxa/mfp-pxa300.h
new file mode 100644
index 00000000000..7513c7a3402
--- /dev/null
+++ b/include/asm-arm/arch-pxa/mfp-pxa300.h
@@ -0,0 +1,574 @@
+/*
+ * linux/include/asm-arm/arch-pxa/mfp-pxa300.h
+ *
+ * PXA300/PXA310 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MFP_PXA300_H
+#define __ASM_ARCH_MFP_PXA300_H
+
+#include <asm/arch/mfp.h>
+
+/* GPIO */
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF1)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF3)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF2)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF3)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF3)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+
+#ifdef CONFIG_CPU_PXA310
+#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0)
+#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0)
+#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0)
+#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0)
+#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0)
+#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0)
+#endif
+
+/* Chip Select */
+#define GPIO2_nCS3 MFP_CFG(GPIO2, AF1)
+
+/* AC97 */
+#define GPIO23_AC97_nACRESET MFP_CFG(GPIO23, AF1)
+#define GPIO24_AC97_SYSCLK MFP_CFG(GPIO24, AF1)
+#define GPIO29_AC97_BITCLK MFP_CFG(GPIO29, AF1)
+#define GPIO25_AC97_SDATA_IN_0 MFP_CFG(GPIO25, AF1)
+#define GPIO26_AC97_SDATA_IN_1 MFP_CFG(GPIO26, AF1)
+#define GPIO17_AC97_SDATA_IN_2 MFP_CFG(GPIO17, AF3)
+#define GPIO21_AC97_SDATA_IN_2 MFP_CFG(GPIO21, AF2)
+#define GPIO18_AC97_SDATA_IN_3 MFP_CFG(GPIO18, AF3)
+#define GPIO22_AC97_SDATA_IN_3 MFP_CFG(GPIO22, AF2)
+#define GPIO27_AC97_SDATA_OUT MFP_CFG(GPIO27, AF1)
+#define GPIO28_AC97_SYNC MFP_CFG(GPIO28, AF1)
+
+/* I2C */
+#define GPIO21_I2C_SCL MFP_CFG_LPM(GPIO21, AF1, PULL_HIGH)
+#define GPIO22_I2C_SDA MFP_CFG_LPM(GPIO22, AF1, PULL_HIGH)
+
+/* QCI */
+#define GPIO39_CI_DD_0 MFP_CFG_DRV(GPIO39, AF1, DS04X)
+#define GPIO40_CI_DD_1 MFP_CFG_DRV(GPIO40, AF1, DS04X)
+#define GPIO41_CI_DD_2 MFP_CFG_DRV(GPIO41, AF1, DS04X)
+#define GPIO42_CI_DD_3 MFP_CFG_DRV(GPIO42, AF1, DS04X)
+#define GPIO43_CI_DD_4 MFP_CFG_DRV(GPIO43, AF1, DS04X)
+#define GPIO44_CI_DD_5 MFP_CFG_DRV(GPIO44, AF1, DS04X)
+#define GPIO45_CI_DD_6 MFP_CFG_DRV(GPIO45, AF1, DS04X)
+#define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X)
+#define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X)
+#define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X)
+#define GPIO52_CI_HSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X)
+#define GPIO51_CI_VSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X)
+#define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X)
+#define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X)
+
+/* KEYPAD */
+#define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT)
+#define GPIO4_KP_DKIN_7 MFP_CFG_LPM(GPIO4, AF2, FLOAT)
+#define GPIO16_KP_DKIN_6 MFP_CFG_LPM(GPIO16, AF6, FLOAT)
+#define GPIO83_KP_DKIN_2 MFP_CFG_LPM(GPIO83, AF5, FLOAT)
+#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF5, FLOAT)
+#define GPIO85_KP_DKIN_0 MFP_CFG_LPM(GPIO85, AF3, FLOAT)
+#define GPIO86_KP_DKIN_1 MFP_CFG_LPM(GPIO86, AF3, FLOAT)
+#define GPIO87_KP_DKIN_2 MFP_CFG_LPM(GPIO87, AF3, FLOAT)
+#define GPIO88_KP_DKIN_3 MFP_CFG_LPM(GPIO88, AF3, FLOAT)
+#define GPIO89_KP_DKIN_3 MFP_CFG_LPM(GPIO89, AF3, FLOAT)
+#define GPIO107_KP_DKIN_0 MFP_CFG_LPM(GPIO107, AF2, FLOAT)
+#define GPIO108_KP_DKIN_1 MFP_CFG_LPM(GPIO108, AF2, FLOAT)
+#define GPIO109_KP_DKIN_2 MFP_CFG_LPM(GPIO109, AF2, FLOAT)
+#define GPIO110_KP_DKIN_3 MFP_CFG_LPM(GPIO110, AF2, FLOAT)
+#define GPIO111_KP_DKIN_4 MFP_CFG_LPM(GPIO111, AF2, FLOAT)
+#define GPIO112_KP_DKIN_5 MFP_CFG_LPM(GPIO112, AF2, FLOAT)
+#define GPIO113_KP_DKIN_6 MFP_CFG_LPM(GPIO113, AF2, FLOAT)
+#define GPIO114_KP_DKIN_7 MFP_CFG_LPM(GPIO114, AF2, FLOAT)
+#define GPIO115_KP_DKIN_0 MFP_CFG_LPM(GPIO115, AF2, FLOAT)
+#define GPIO116_KP_DKIN_1 MFP_CFG_LPM(GPIO116, AF2, FLOAT)
+#define GPIO117_KP_DKIN_2 MFP_CFG_LPM(GPIO117, AF2, FLOAT)
+#define GPIO118_KP_DKIN_3 MFP_CFG_LPM(GPIO118, AF2, FLOAT)
+#define GPIO119_KP_DKIN_4 MFP_CFG_LPM(GPIO119, AF2, FLOAT)
+#define GPIO120_KP_DKIN_5 MFP_CFG_LPM(GPIO120, AF2, FLOAT)
+#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT)
+#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT)
+#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT)
+#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT)
+#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF5, FLOAT)
+#define GPIO0_2_KP_DKIN_0 MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
+#define GPIO1_2_KP_DKIN_1 MFP_CFG_LPM(GPIO1_2, AF2, FLOAT)
+#define GPIO2_2_KP_DKIN_6 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
+#define GPIO3_2_KP_DKIN_7 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
+#define GPIO4_2_KP_DKIN_1 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
+#define GPIO5_2_KP_DKIN_0 MFP_CFG_LPM(GPIO5_2, AF2, FLOAT)
+
+#define GPIO5_KP_MKIN_0 MFP_CFG_LPM(GPIO5, AF2, FLOAT)
+#define GPIO6_KP_MKIN_1 MFP_CFG_LPM(GPIO6, AF2, FLOAT)
+#define GPIO9_KP_MKIN_6 MFP_CFG_LPM(GPIO9, AF3, FLOAT)
+#define GPIO10_KP_MKIN_7 MFP_CFG_LPM(GPIO10, AF3, FLOAT)
+#define GPIO70_KP_MKIN_6 MFP_CFG_LPM(GPIO70, AF3, FLOAT)
+#define GPIO71_KP_MKIN_7 MFP_CFG_LPM(GPIO71, AF3, FLOAT)
+#define GPIO100_KP_MKIN_6 MFP_CFG_LPM(GPIO100, AF7, FLOAT)
+#define GPIO101_KP_MKIN_7 MFP_CFG_LPM(GPIO101, AF7, FLOAT)
+#define GPIO112_KP_MKIN_6 MFP_CFG_LPM(GPIO112, AF4, FLOAT)
+#define GPIO113_KP_MKIN_7 MFP_CFG_LPM(GPIO113, AF4, FLOAT)
+#define GPIO115_KP_MKIN_0 MFP_CFG_LPM(GPIO115, AF1, FLOAT)
+#define GPIO116_KP_MKIN_1 MFP_CFG_LPM(GPIO116, AF1, FLOAT)
+#define GPIO117_KP_MKIN_2 MFP_CFG_LPM(GPIO117, AF1, FLOAT)
+#define GPIO118_KP_MKIN_3 MFP_CFG_LPM(GPIO118, AF1, FLOAT)
+#define GPIO119_KP_MKIN_4 MFP_CFG_LPM(GPIO119, AF1, FLOAT)
+#define GPIO120_KP_MKIN_5 MFP_CFG_LPM(GPIO120, AF1, FLOAT)
+#define GPIO125_KP_MKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT)
+#define GPIO2_2_KP_MKIN_6 MFP_CFG_LPM(GPIO2_2, AF1, FLOAT)
+#define GPIO3_2_KP_MKIN_7 MFP_CFG_LPM(GPIO3_2, AF1, FLOAT)
+
+#define GPIO7_KP_MKOUT_5 MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
+#define GPIO11_KP_MKOUT_5 MFP_CFG_LPM(GPIO11, AF3, DRIVE_HIGH)
+#define GPIO12_KP_MKOUT_6 MFP_CFG_LPM(GPIO12, AF3, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_7 MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
+#define GPIO19_KP_MKOUT_4 MFP_CFG_LPM(GPIO19, AF3, DRIVE_HIGH)
+#define GPIO20_KP_MKOUT_5 MFP_CFG_LPM(GPIO20, AF3, DRIVE_HIGH)
+#define GPIO38_KP_MKOUT_5 MFP_CFG_LPM(GPIO38, AF5, DRIVE_HIGH)
+#define GPIO53_KP_MKOUT_6 MFP_CFG_LPM(GPIO53, AF5, DRIVE_HIGH)
+#define GPIO78_KP_MKOUT_7 MFP_CFG_LPM(GPIO78, AF5, DRIVE_HIGH)
+#define GPIO85_KP_MKOUT_0 MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
+#define GPIO86_KP_MKOUT_1 MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
+#define GPIO87_KP_MKOUT_2 MFP_CFG_LPM(GPIO87, AF2, DRIVE_HIGH)
+#define GPIO88_KP_MKOUT_3 MFP_CFG_LPM(GPIO88, AF2, DRIVE_HIGH)
+#define GPIO104_KP_MKOUT_6 MFP_CFG_LPM(GPIO104, AF5, DRIVE_HIGH)
+#define GPIO105_KP_MKOUT_7 MFP_CFG_LPM(GPIO105, AF5, DRIVE_HIGH)
+#define GPIO121_KP_MKOUT_0 MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
+#define GPIO122_KP_MKOUT_1 MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
+#define GPIO123_KP_MKOUT_2 MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
+#define GPIO124_KP_MKOUT_3 MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
+#define GPIO125_KP_MKOUT_4 MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
+#define GPIO126_KP_MKOUT_7 MFP_CFG_LPM(GPIO126, AF4, DRIVE_HIGH)
+#define GPIO5_2_KP_MKOUT_6 MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
+#define GPIO4_2_KP_MKOUT_5 MFP_CFG_LPM(GPIO4_2, AF1, DRIVE_HIGH)
+#define GPIO6_2_KP_MKOUT_7 MFP_CFG_LPM(GPIO6_2, AF1, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO54_LCD_LDD_0 MFP_CFG_DRV(GPIO54, AF1, DS01X)
+#define GPIO55_LCD_LDD_1 MFP_CFG_DRV(GPIO55, AF1, DS01X)
+#define GPIO56_LCD_LDD_2 MFP_CFG_DRV(GPIO56, AF1, DS01X)
+#define GPIO57_LCD_LDD_3 MFP_CFG_DRV(GPIO57, AF1, DS01X)
+#define GPIO58_LCD_LDD_4 MFP_CFG_DRV(GPIO58, AF1, DS01X)
+#define GPIO59_LCD_LDD_5 MFP_CFG_DRV(GPIO59, AF1, DS01X)
+#define GPIO60_LCD_LDD_6 MFP_CFG_DRV(GPIO60, AF1, DS01X)
+#define GPIO61_LCD_LDD_7 MFP_CFG_DRV(GPIO61, AF1, DS01X)
+#define GPIO62_LCD_LDD_8 MFP_CFG_DRV(GPIO62, AF1, DS01X)
+#define GPIO63_LCD_LDD_9 MFP_CFG_DRV(GPIO63, AF1, DS01X)
+#define GPIO64_LCD_LDD_10 MFP_CFG_DRV(GPIO64, AF1, DS01X)
+#define GPIO65_LCD_LDD_11 MFP_CFG_DRV(GPIO65, AF1, DS01X)
+#define GPIO66_LCD_LDD_12 MFP_CFG_DRV(GPIO66, AF1, DS01X)
+#define GPIO67_LCD_LDD_13 MFP_CFG_DRV(GPIO67, AF1, DS01X)
+#define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X)
+#define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X)
+#define GPIO70_LCD_LDD_16 MFP_CFG_DRV(GPIO70, AF1, DS01X)
+#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF1, DS01X)
+#define GPIO62_LCD_CS_N MFP_CFG_DRV(GPIO62, AF2, DS01X)
+#define GPIO72_LCD_FCLK MFP_CFG_DRV(GPIO72, AF1, DS01X)
+#define GPIO73_LCD_LCLK MFP_CFG_DRV(GPIO73, AF1, DS01X)
+#define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS01X)
+#define GPIO75_LCD_BIAS MFP_CFG_DRV(GPIO75, AF1, DS01X)
+#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF2, DS01X)
+
+#define GPIO15_LCD_CS_N MFP_CFG_DRV(GPIO15, AF2, DS01X)
+#define GPIO127_LCD_CS_N MFP_CFG_DRV(GPIO127, AF1, DS01X)
+#define GPIO63_LCD_VSYNC MFP_CFG_DRV(GPIO63, AF2, DS01X)
+
+/* Mini-LCD */
+#define GPIO72_MLCD_FCLK MFP_CFG_DRV(GPIO72, AF7, DS08X)
+#define GPIO73_MLCD_LCLK MFP_CFG_DRV(GPIO73, AF7, DS08X)
+#define GPIO54_MLCD_LDD_0 MFP_CFG_DRV(GPIO54, AF7, DS08X)
+#define GPIO55_MLCD_LDD_1 MFP_CFG_DRV(GPIO55, AF7, DS08X)
+#define GPIO56_MLCD_LDD_2 MFP_CFG_DRV(GPIO56, AF7, DS08X)
+#define GPIO57_MLCD_LDD_3 MFP_CFG_DRV(GPIO57, AF7, DS08X)
+#define GPIO58_MLCD_LDD_4 MFP_CFG_DRV(GPIO58, AF7, DS08X)
+#define GPIO59_MLCD_LDD_5 MFP_CFG_DRV(GPIO59, AF7, DS08X)
+#define GPIO60_MLCD_LDD_6 MFP_CFG_DRV(GPIO60, AF7, DS08X)
+#define GPIO61_MLCD_LDD_7 MFP_CFG_DRV(GPIO61, AF7, DS08X)
+#define GPIO62_MLCD_LDD_8 MFP_CFG_DRV(GPIO62, AF7, DS08X)
+#define GPIO63_MLCD_LDD_9 MFP_CFG_DRV(GPIO63, AF7, DS08X)
+#define GPIO64_MLCD_LDD_10 MFP_CFG_DRV(GPIO64, AF7, DS08X)
+#define GPIO65_MLCD_LDD_11 MFP_CFG_DRV(GPIO65, AF7, DS08X)
+#define GPIO66_MLCD_LDD_12 MFP_CFG_DRV(GPIO66, AF7, DS08X)
+#define GPIO67_MLCD_LDD_13 MFP_CFG_DRV(GPIO67, AF7, DS08X)
+#define GPIO68_MLCD_LDD_14 MFP_CFG_DRV(GPIO68, AF7, DS08X)
+#define GPIO69_MLCD_LDD_15 MFP_CFG_DRV(GPIO69, AF7, DS08X)
+#define GPIO74_MLCD_PCLK MFP_CFG_DRV(GPIO74, AF7, DS08X)
+#define GPIO75_MLCD_BIAS MFP_CFG_DRV(GPIO75, AF2, DS08X)
+
+/* MMC1 */
+#define GPIO7_MMC1_CLK MFP_CFG_LPM(GPIO7, AF4, DRIVE_HIGH)
+#define GPIO8_MMC1_CMD MFP_CFG_LPM(GPIO8, AF4, DRIVE_HIGH)
+#define GPIO14_MMC1_CMD MFP_CFG_LPM(GPIO14, AF5, DRIVE_HIGH)
+#define GPIO15_MMC1_CMD MFP_CFG_LPM(GPIO15, AF5, DRIVE_HIGH)
+#define GPIO3_MMC1_DAT0 MFP_CFG_LPM(GPIO3, AF4, DRIVE_HIGH)
+#define GPIO4_MMC1_DAT1 MFP_CFG_LPM(GPIO4, AF4, DRIVE_HIGH)
+#define GPIO5_MMC1_DAT2 MFP_CFG_LPM(GPIO5, AF4, DRIVE_HIGH)
+#define GPIO6_MMC1_DAT3 MFP_CFG_LPM(GPIO6, AF4, DRIVE_HIGH)
+
+/* MMC2 */
+#define GPIO9_MMC2_DAT0 MFP_CFG_LPM(GPIO9, AF4, PULL_HIGH)
+#define GPIO10_MMC2_DAT1 MFP_CFG_LPM(GPIO10, AF4, PULL_HIGH)
+#define GPIO11_MMC2_DAT2 MFP_CFG_LPM(GPIO11, AF4, PULL_HIGH)
+#define GPIO12_MMC2_DAT3 MFP_CFG_LPM(GPIO12, AF4, PULL_HIGH)
+#define GPIO13_MMC2_CLK MFP_CFG_LPM(GPIO13, AF4, PULL_HIGH)
+#define GPIO14_MMC2_CMD MFP_CFG_LPM(GPIO14, AF4, PULL_HIGH)
+#define GPIO77_MMC2_DAT0 MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
+#define GPIO78_MMC2_DAT1 MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
+#define GPIO79_MMC2_DAT2 MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
+#define GPIO80_MMC2_DAT3 MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
+#define GPIO81_MMC2_CLK MFP_CFG_LPM(GPIO81, AF4, PULL_HIGH)
+#define GPIO82_MMC2_CMD MFP_CFG_LPM(GPIO82, AF4, PULL_HIGH)
+
+/* SSP1 */
+#define GPIO89_SSP1_EXTCLK MFP_CFG(GPIO89, AF1)
+#define GPIO90_SSP1_SYSCLK MFP_CFG(GPIO90, AF1)
+#define GPIO15_SSP1_SCLK MFP_CFG(GPIO15, AF6)
+#define GPIO16_SSP1_FRM MFP_CFG(GPIO16, AF2)
+#define GPIO33_SSP1_SCLK MFP_CFG(GPIO33, AF5)
+#define GPIO34_SSP1_FRM MFP_CFG(GPIO34, AF5)
+#define GPIO85_SSP1_SCLK MFP_CFG(GPIO85, AF1)
+#define GPIO86_SSP1_FRM MFP_CFG(GPIO86, AF1)
+#define GPIO18_SSP1_TXD MFP_CFG(GPIO18, AF7)
+#define GPIO18_SSP1_RXD MFP_CFG(GPIO18, AF2)
+#define GPIO20_SSP1_TXD MFP_CFG(GPIO20, AF2)
+#define GPIO20_SSP1_RXD MFP_CFG(GPIO20, AF7)
+#define GPIO35_SSP1_TXD MFP_CFG(GPIO35, AF5)
+#define GPIO35_SSP1_RXD MFP_CFG(GPIO35, AF4)
+#define GPIO36_SSP1_TXD MFP_CFG(GPIO36, AF5)
+#define GPIO36_SSP1_RXD MFP_CFG(GPIO36, AF6)
+#define GPIO87_SSP1_TXD MFP_CFG(GPIO87, AF1)
+#define GPIO87_SSP1_RXD MFP_CFG(GPIO87, AF6)
+#define GPIO88_SSP1_TXD MFP_CFG(GPIO88, AF6)
+#define GPIO88_SSP1_RXD MFP_CFG(GPIO88, AF1)
+
+/* SSP2 */
+#define GPIO29_SSP2_EXTCLK MFP_CFG(GPIO29, AF2)
+#define GPIO23_SSP2_SCLK MFP_CFG(GPIO23, AF2)
+#define GPIO17_SSP2_FRM MFP_CFG(GPIO17, AF2)
+#define GPIO25_SSP2_SCLK MFP_CFG(GPIO25, AF2)
+#define GPIO26_SSP2_FRM MFP_CFG(GPIO26, AF2)
+#define GPIO33_SSP2_SCLK MFP_CFG(GPIO33, AF6)
+#define GPIO34_SSP2_FRM MFP_CFG(GPIO34, AF6)
+#define GPIO64_SSP2_SCLK MFP_CFG(GPIO64, AF2)
+#define GPIO65_SSP2_FRM MFP_CFG(GPIO65, AF2)
+#define GPIO19_SSP2_TXD MFP_CFG(GPIO19, AF2)
+#define GPIO19_SSP2_RXD MFP_CFG(GPIO19, AF7)
+#define GPIO24_SSP2_TXD MFP_CFG(GPIO24, AF5)
+#define GPIO24_SSP2_RXD MFP_CFG(GPIO24, AF4)
+#define GPIO27_SSP2_TXD MFP_CFG(GPIO27, AF2)
+#define GPIO27_SSP2_RXD MFP_CFG(GPIO27, AF5)
+#define GPIO28_SSP2_TXD MFP_CFG(GPIO28, AF5)
+#define GPIO28_SSP2_RXD MFP_CFG(GPIO28, AF2)
+#define GPIO35_SSP2_TXD MFP_CFG(GPIO35, AF7)
+#define GPIO35_SSP2_RXD MFP_CFG(GPIO35, AF6)
+#define GPIO66_SSP2_TXD MFP_CFG(GPIO66, AF4)
+#define GPIO66_SSP2_RXD MFP_CFG(GPIO66, AF2)
+#define GPIO67_SSP2_TXD MFP_CFG(GPIO67, AF2)
+#define GPIO67_SSP2_RXD MFP_CFG(GPIO67, AF4)
+#define GPIO36_SSP2_TXD MFP_CFG(GPIO36, AF7)
+
+/* SSP3 */
+#define GPIO69_SSP3_FRM MFP_CFG_X(GPIO69, AF2, DS08X, DRIVE_LOW)
+#define GPIO68_SSP3_SCLK MFP_CFG_X(GPIO68, AF2, DS08X, FLOAT)
+#define GPIO92_SSP3_FRM MFP_CFG_X(GPIO92, AF1, DS08X, DRIVE_LOW)
+#define GPIO91_SSP3_SCLK MFP_CFG_X(GPIO91, AF1, DS08X, FLOAT)
+#define GPIO70_SSP3_TXD MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO70_SSP3_RXD MFP_CFG_X(GPIO70, AF5, DS08X, FLOAT)
+#define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF5, DS08X, DRIVE_LOW)
+#define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF2, DS08X, FLOAT)
+#define GPIO93_SSP3_TXD MFP_CFG_X(GPIO93, AF1, DS08X, DRIVE_LOW)
+#define GPIO93_SSP3_RXD MFP_CFG_X(GPIO93, AF5, DS08X, FLOAT)
+#define GPIO94_SSP3_TXD MFP_CFG_X(GPIO94, AF5, DS08X, DRIVE_LOW)
+#define GPIO94_SSP3_RXD MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)
+
+/* SSP4 */
+#define GPIO95_SSP4_SCLK MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_SSP4_FRM MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+#define GPIO97_SSP4_TXD MFP_CFG_LPM(GPIO97, AF1, PULL_HIGH)
+#define GPIO97_SSP4_RXD MFP_CFG_LPM(GPIO97, AF5, PULL_HIGH)
+#define GPIO98_SSP4_TXD MFP_CFG_LPM(GPIO98, AF5, PULL_HIGH)
+#define GPIO98_SSP4_RXD MFP_CFG_LPM(GPIO98, AF1, PULL_HIGH)
+
+/* UART1 */
+#define GPIO32_UART1_CTS MFP_CFG_LPM(GPIO32, AF2, FLOAT)
+#define GPIO37_UART1_CTS MFP_CFG_LPM(GPIO37, AF4, FLOAT)
+#define GPIO79_UART1_CTS MFP_CFG_LPM(GPIO79, AF1, FLOAT)
+#define GPIO84_UART1_CTS MFP_CFG_LPM(GPIO84, AF3, FLOAT)
+#define GPIO101_UART1_CTS MFP_CFG_LPM(GPIO101, AF1, FLOAT)
+#define GPIO106_UART1_CTS MFP_CFG_LPM(GPIO106, AF6, FLOAT)
+
+#define GPIO32_UART1_RTS MFP_CFG_LPM(GPIO32, AF4, FLOAT)
+#define GPIO37_UART1_RTS MFP_CFG_LPM(GPIO37, AF2, FLOAT)
+#define GPIO79_UART1_RTS MFP_CFG_LPM(GPIO79, AF3, FLOAT)
+#define GPIO84_UART1_RTS MFP_CFG_LPM(GPIO84, AF1, FLOAT)
+#define GPIO101_UART1_RTS MFP_CFG_LPM(GPIO101, AF6, FLOAT)
+#define GPIO106_UART1_RTS MFP_CFG_LPM(GPIO106, AF1, FLOAT)
+
+#define GPIO34_UART1_DSR MFP_CFG_LPM(GPIO34, AF2, FLOAT)
+#define GPIO36_UART1_DSR MFP_CFG_LPM(GPIO36, AF4, FLOAT)
+#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF1, FLOAT)
+#define GPIO83_UART1_DSR MFP_CFG_LPM(GPIO83, AF3, FLOAT)
+#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
+#define GPIO105_UART1_DSR MFP_CFG_LPM(GPIO105, AF6, FLOAT)
+
+#define GPIO34_UART1_DTR MFP_CFG_LPM(GPIO34, AF4, FLOAT)
+#define GPIO36_UART1_DTR MFP_CFG_LPM(GPIO36, AF2, FLOAT)
+#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF3, FLOAT)
+#define GPIO83_UART1_DTR MFP_CFG_LPM(GPIO83, AF1, FLOAT)
+#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
+#define GPIO105_UART1_DTR MFP_CFG_LPM(GPIO105, AF1, FLOAT)
+
+#define GPIO35_UART1_RI MFP_CFG_LPM(GPIO35, AF2, FLOAT)
+#define GPIO82_UART1_RI MFP_CFG_LPM(GPIO82, AF1, FLOAT)
+#define GPIO104_UART1_RI MFP_CFG_LPM(GPIO104, AF1, FLOAT)
+
+#define GPIO33_UART1_DCD MFP_CFG_LPM(GPIO33, AF2, FLOAT)
+#define GPIO80_UART1_DCD MFP_CFG_LPM(GPIO80, AF1, FLOAT)
+#define GPIO102_UART1_DCD MFP_CFG_LPM(GPIO102, AF1, FLOAT)
+
+#define GPIO30_UART1_RXD MFP_CFG_LPM(GPIO30, AF2, FLOAT)
+#define GPIO31_UART1_RXD MFP_CFG_LPM(GPIO31, AF4, FLOAT)
+#define GPIO77_UART1_RXD MFP_CFG_LPM(GPIO77, AF1, FLOAT)
+#define GPIO78_UART1_RXD MFP_CFG_LPM(GPIO78, AF3, FLOAT)
+#define GPIO99_UART1_RXD MFP_CFG_LPM(GPIO99, AF1, FLOAT)
+#define GPIO100_UART1_RXD MFP_CFG_LPM(GPIO100, AF6, FLOAT)
+#define GPIO102_UART1_RXD MFP_CFG_LPM(GPIO102, AF6, FLOAT)
+#define GPIO104_UART1_RXD MFP_CFG_LPM(GPIO104, AF4, FLOAT)
+
+#define GPIO30_UART1_TXD MFP_CFG_LPM(GPIO30, AF4, FLOAT)
+#define GPIO31_UART1_TXD MFP_CFG_LPM(GPIO31, AF2, FLOAT)
+#define GPIO77_UART1_TXD MFP_CFG_LPM(GPIO77, AF3, FLOAT)
+#define GPIO78_UART1_TXD MFP_CFG_LPM(GPIO78, AF1, FLOAT)
+#define GPIO99_UART1_TXD MFP_CFG_LPM(GPIO99, AF6, FLOAT)
+#define GPIO100_UART1_TXD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
+#define GPIO102_UART1_TXD MFP_CFG_LPM(GPIO102, AF4, FLOAT)
+
+/* UART2 */
+#define GPIO15_UART2_CTS MFP_CFG_LPM(GPIO15, AF3, FLOAT)
+#define GPIO16_UART2_CTS MFP_CFG_LPM(GPIO16, AF5, FLOAT)
+#define GPIO111_UART2_CTS MFP_CFG_LPM(GPIO111, AF3, FLOAT)
+#define GPIO114_UART2_CTS MFP_CFG_LPM(GPIO114, AF1, FLOAT)
+
+#define GPIO15_UART2_RTS MFP_CFG_LPM(GPIO15, AF4, FLOAT)
+#define GPIO16_UART2_RTS MFP_CFG_LPM(GPIO16, AF4, FLOAT)
+#define GPIO114_UART2_RTS MFP_CFG_LPM(GPIO114, AF3, FLOAT)
+#define GPIO111_UART2_RTS MFP_CFG_LPM(GPIO111, AF1, FLOAT)
+
+#define GPIO18_UART2_RXD MFP_CFG_LPM(GPIO18, AF5, FLOAT)
+#define GPIO19_UART2_RXD MFP_CFG_LPM(GPIO19, AF4, FLOAT)
+#define GPIO112_UART2_RXD MFP_CFG_LPM(GPIO112, AF1, FLOAT)
+#define GPIO113_UART2_RXD MFP_CFG_LPM(GPIO113, AF3, FLOAT)
+
+#define GPIO18_UART2_TXD MFP_CFG_LPM(GPIO18, AF4, FLOAT)
+#define GPIO19_UART2_TXD MFP_CFG_LPM(GPIO19, AF5, FLOAT)
+#define GPIO112_UART2_TXD MFP_CFG_LPM(GPIO112, AF3, FLOAT)
+#define GPIO113_UART2_TXD MFP_CFG_LPM(GPIO113, AF1, FLOAT)
+
+/* UART3 */
+#define GPIO91_UART3_CTS MFP_CFG_LPM(GPIO91, AF2, FLOAT)
+#define GPIO92_UART3_CTS MFP_CFG_LPM(GPIO92, AF4, FLOAT)
+#define GPIO107_UART3_CTS MFP_CFG_LPM(GPIO107, AF1, FLOAT)
+#define GPIO108_UART3_CTS MFP_CFG_LPM(GPIO108, AF3, FLOAT)
+
+#define GPIO91_UART3_RTS MFP_CFG_LPM(GPIO91, AF4, FLOAT)
+#define GPIO92_UART3_RTS MFP_CFG_LPM(GPIO92, AF2, FLOAT)
+#define GPIO107_UART3_RTS MFP_CFG_LPM(GPIO107, AF3, FLOAT)
+#define GPIO108_UART3_RTS MFP_CFG_LPM(GPIO108, AF1, FLOAT)
+
+#define GPIO7_UART3_RXD MFP_CFG_LPM(GPIO7, AF2, FLOAT)
+#define GPIO8_UART3_RXD MFP_CFG_LPM(GPIO8, AF6, FLOAT)
+#define GPIO93_UART3_RXD MFP_CFG_LPM(GPIO93, AF4, FLOAT)
+#define GPIO94_UART3_RXD MFP_CFG_LPM(GPIO94, AF2, FLOAT)
+#define GPIO109_UART3_RXD MFP_CFG_LPM(GPIO109, AF3, FLOAT)
+#define GPIO110_UART3_RXD MFP_CFG_LPM(GPIO110, AF1, FLOAT)
+
+#define GPIO7_UART3_TXD MFP_CFG_LPM(GPIO7, AF6, FLOAT)
+#define GPIO8_UART3_TXD MFP_CFG_LPM(GPIO8, AF2, FLOAT)
+#define GPIO93_UART3_TXD MFP_CFG_LPM(GPIO93, AF2, FLOAT)
+#define GPIO94_UART3_TXD MFP_CFG_LPM(GPIO94, AF4, FLOAT)
+#define GPIO109_UART3_TXD MFP_CFG_LPM(GPIO109, AF1, FLOAT)
+#define GPIO110_UART3_TXD MFP_CFG_LPM(GPIO110, AF3, FLOAT)
+
+/* USB Host */
+#define GPIO0_2_USBH_PEN MFP_CFG(GPIO0_2, AF1)
+#define GPIO1_2_USBH_PWR MFP_CFG(GPIO1_2, AF1)
+
+/* USB P3 */
+#define GPIO77_USB_P3_1 MFP_CFG(GPIO77, AF2)
+#define GPIO78_USB_P3_2 MFP_CFG(GPIO78, AF2)
+#define GPIO79_USB_P3_3 MFP_CFG(GPIO79, AF2)
+#define GPIO80_USB_P3_4 MFP_CFG(GPIO80, AF2)
+#define GPIO81_USB_P3_5 MFP_CFG(GPIO81, AF2)
+#define GPIO82_USB_P3_6 MFP_CFG(GPIO82, AF2)
+
+/* PWM */
+#define GPIO17_PWM0_OUT MFP_CFG(GPIO17, AF1)
+#define GPIO18_PWM1_OUT MFP_CFG(GPIO18, AF1)
+#define GPIO19_PWM2_OUT MFP_CFG(GPIO19, AF1)
+#define GPIO20_PWM3_OUT MFP_CFG(GPIO20, AF1)
+
+/* CIR */
+#define GPIO8_CIR_OUT MFP_CFG(GPIO8, AF5)
+#define GPIO16_CIR_OUT MFP_CFG(GPIO16, AF3)
+
+#define GPIO20_OW_DQ_IN MFP_CFG(GPIO20, AF5)
+#define GPIO126_OW_DQ MFP_CFG(GPIO126, AF2)
+
+#define GPIO0_DF_RDY MFP_CFG(GPIO0, AF1)
+#define GPIO7_CLK_BYPASS_XSC MFP_CFG(GPIO7, AF7)
+#define GPIO17_EXT_SYNC_MVT_0 MFP_CFG(GPIO17, AF6)
+#define GPIO18_EXT_SYNC_MVT_1 MFP_CFG(GPIO18, AF6)
+#define GPIO19_OST_CHOUT_MVT_0 MFP_CFG(GPIO19, AF6)
+#define GPIO20_OST_CHOUT_MVT_1 MFP_CFG(GPIO20, AF6)
+#define GPIO49_48M_CLK MFP_CFG(GPIO49, AF2)
+#define GPIO126_EXT_CLK MFP_CFG(GPIO126, AF3)
+#define GPIO127_CLK_BYPASS_GB MFP_CFG(GPIO127, AF7)
+#define GPIO71_EXT_MATCH_MVT MFP_CFG(GPIO71, AF6)
+
+#define GPIO3_uIO_IN MFP_CFG(GPIO3, AF1)
+
+#define GPIO4_uSIM_CARD_STATE MFP_CFG(GPIO4, AF1)
+#define GPIO5_uSIM_uCLK MFP_CFG(GPIO5, AF1)
+#define GPIO6_uSIM_uRST MFP_CFG(GPIO6, AF1)
+#define GPIO16_uSIM_UVS_0 MFP_CFG(GPIO16, AF1)
+
+#define GPIO9_SCIO MFP_CFG(GPIO9, AF1)
+#define GPIO20_RTC_MVT MFP_CFG(GPIO20, AF4)
+#define GPIO126_RTC_MVT MFP_CFG(GPIO126, AF1)
+
+/*
+ * PXA300 specific MFP configurations
+ */
+#ifdef CONFIG_CPU_PXA300
+#define GPIO99_USB_P2_2 MFP_CFG(GPIO99, AF2)
+#define GPIO99_USB_P2_5 MFP_CFG(GPIO99, AF3)
+#define GPIO99_USB_P2_6 MFP_CFG(GPIO99, AF4)
+#define GPIO100_USB_P2_2 MFP_CFG(GPIO100, AF4)
+#define GPIO100_USB_P2_5 MFP_CFG(GPIO100, AF5)
+#define GPIO101_USB_P2_1 MFP_CFG(GPIO101, AF2)
+#define GPIO102_USB_P2_4 MFP_CFG(GPIO102, AF2)
+#define GPIO104_USB_P2_3 MFP_CFG(GPIO104, AF2)
+#define GPIO105_USB_P2_5 MFP_CFG(GPIO105, AF2)
+#define GPIO100_USB_P2_6 MFP_CFG(GPIO100, AF2)
+#define GPIO106_USB_P2_7 MFP_CFG(GPIO106, AF2)
+#define GPIO103_USB_P2_8 MFP_CFG(GPIO103, AF2)
+
+/* U2D UTMI */
+#define GPIO38_UTM_CLK MFP_CFG(GPIO38, AF1)
+#define GPIO26_U2D_RXERROR MFP_CFG(GPIO26, AF3)
+#define GPIO50_U2D_RXERROR MFP_CFG(GPIO50, AF1)
+#define GPIO89_U2D_RXERROR MFP_CFG(GPIO89, AF5)
+#define GPIO24_UTM_RXVALID MFP_CFG(GPIO24, AF3)
+#define GPIO48_UTM_RXVALID MFP_CFG(GPIO48, AF2)
+#define GPIO87_UTM_RXVALID MFP_CFG(GPIO87, AF5)
+#define GPIO25_UTM_RXACTIVE MFP_CFG(GPIO25, AF3)
+#define GPIO47_UTM_RXACTIVE MFP_CFG(GPIO47, AF2)
+#define GPIO49_UTM_RXACTIVE MFP_CFG(GPIO49, AF1)
+#define GPIO88_UTM_RXACTIVE MFP_CFG(GPIO88, AF5)
+#define GPIO53_UTM_TXREADY MFP_CFG(GPIO53, AF1)
+#define GPIO67_UTM_LINESTATE_0 MFP_CFG(GPIO67, AF3)
+#define GPIO92_UTM_LINESTATE_0 MFP_CFG(GPIO92, AF3)
+#define GPIO104_UTM_LINESTATE_0 MFP_CFG(GPIO104, AF3)
+#define GPIO109_UTM_LINESTATE_0 MFP_CFG(GPIO109, AF4)
+#define GPIO68_UTM_LINESTATE_1 MFP_CFG(GPIO68, AF3)
+#define GPIO93_UTM_LINESTATE_1 MFP_CFG(GPIO93, AF3)
+#define GPIO105_UTM_LINESTATE_1 MFP_CFG(GPIO105, AF3)
+#define GPIO27_U2D_OPMODE_0 MFP_CFG(GPIO27, AF4)
+#define GPIO51_U2D_OPMODE_0 MFP_CFG(GPIO51, AF2)
+#define GPIO90_U2D_OPMODE_0 MFP_CFG(GPIO90, AF7)
+#define GPIO28_U2D_OPMODE_1 MFP_CFG(GPIO28, AF4)
+#define GPIO52_U2D_OPMODE_1 MFP_CFG(GPIO52, AF2)
+#define GPIO106_U2D_OPMODE_1 MFP_CFG(GPIO106, AF3)
+#define GPIO110_U2D_OPMODE_1 MFP_CFG(GPIO110, AF5)
+#define GPIO76_U2D_RESET MFP_CFG(GPIO76, AF1)
+#define GPIO95_U2D_RESET MFP_CFG(GPIO95, AF2)
+#define GPIO100_U2D_RESET MFP_CFG(GPIO100, AF3)
+#define GPIO66_U2D_SUSPEND MFP_CFG(GPIO66, AF3)
+#define GPIO98_U2D_SUSPEND MFP_CFG(GPIO98, AF2)
+#define GPIO103_U2D_SUSPEND MFP_CFG(GPIO103, AF3)
+#define GPIO65_U2D_TERM_SEL MFP_CFG(GPIO65, AF5)
+#define GPIO97_U2D_TERM_SEL MFP_CFG(GPIO97, AF3)
+#define GPIO102_U2D_TERM_SEL MFP_CFG(GPIO102, AF5)
+#define GPIO29_U2D_TXVALID MFP_CFG(GPIO29, AF3)
+#define GPIO52_U2D_TXVALID MFP_CFG(GPIO52, AF4)
+#define GPIO69_U2D_TXVALID MFP_CFG(GPIO69, AF3)
+#define GPIO85_U2D_TXVALID MFP_CFG(GPIO85, AF7)
+#define GPIO64_U2D_XCVR_SEL MFP_CFG(GPIO64, AF5)
+#define GPIO96_U2D_XCVR_SEL MFP_CFG(GPIO96, AF3)
+#define GPIO101_U2D_XCVR_SEL MFP_CFG(GPIO101, AF5)
+#define GPIO30_UTM_PHYDATA_0 MFP_CFG(GPIO30, AF3)
+#define GPIO31_UTM_PHYDATA_1 MFP_CFG(GPIO31, AF3)
+#define GPIO32_UTM_PHYDATA_2 MFP_CFG(GPIO32, AF3)
+#define GPIO33_UTM_PHYDATA_3 MFP_CFG(GPIO33, AF3)
+#define GPIO34_UTM_PHYDATA_4 MFP_CFG(GPIO34, AF3)
+#define GPIO35_UTM_PHYDATA_5 MFP_CFG(GPIO35, AF3)
+#define GPIO36_UTM_PHYDATA_6 MFP_CFG(GPIO36, AF3)
+#define GPIO37_UTM_PHYDATA_7 MFP_CFG(GPIO37, AF3)
+#define GPIO39_UTM_PHYDATA_0 MFP_CFG(GPIO39, AF3)
+#define GPIO40_UTM_PHYDATA_1 MFP_CFG(GPIO40, AF3)
+#define GPIO41_UTM_PHYDATA_2 MFP_CFG(GPIO41, AF3)
+#define GPIO42_UTM_PHYDATA_3 MFP_CFG(GPIO42, AF3)
+#define GPIO43_UTM_PHYDATA_4 MFP_CFG(GPIO43, AF3)
+#define GPIO44_UTM_PHYDATA_5 MFP_CFG(GPIO44, AF3)
+#define GPIO45_UTM_PHYDATA_6 MFP_CFG(GPIO45, AF3)
+#define GPIO46_UTM_PHYDATA_7 MFP_CFG(GPIO46, AF3)
+#endif /* CONFIG_CPU_PXA300 */
+
+/*
+ * PXA310 specific MFP configurations
+ */
+#ifdef CONFIG_CPU_PXA310
+/* USB P2 */
+#define GPIO36_USB_P2_1 MFP_CFG(GPIO36, AF1)
+#define GPIO30_USB_P2_2 MFP_CFG(GPIO30, AF1)
+#define GPIO35_USB_P2_3 MFP_CFG(GPIO35, AF1)
+#define GPIO32_USB_P2_4 MFP_CFG(GPIO32, AF1)
+#define GPIO34_USB_P2_5 MFP_CFG(GPIO34, AF1)
+#define GPIO31_USB_P2_6 MFP_CFG(GPIO31, AF1)
+
+/* MMC1 */
+#define GPIO24_MMC1_CMD MFP_CFG(GPIO24, AF3)
+#define GPIO29_MMC1_DAT0 MFP_CFG(GPIO29, AF3)
+
+/* MMC3 */
+#define GPIO103_MMC3_CLK MFP_CFG(GPIO103, AF2)
+#define GPIO105_MMC3_CMD MFP_CFG(GPIO105, AF2)
+#define GPIO11_2_MMC3_CLK MFP_CFG(GPIO11_2, AF1)
+#define GPIO12_2_MMC3_CMD MFP_CFG(GPIO12_2, AF1)
+#define GPIO7_2_MMC3_DAT0 MFP_CFG(GPIO7_2, AF1)
+#define GPIO8_2_MMC3_DAT1 MFP_CFG(GPIO8_2, AF1)
+#define GPIO9_2_MMC3_DAT2 MFP_CFG(GPIO9_2, AF1)
+#define GPIO10_2_MMC3_DAT3 MFP_CFG(GPIO10_2, AF1)
+
+/* ULPI */
+#define GPIO38_ULPI_CLK MFP_CFG(GPIO38, AF1)
+#define GPIO30_ULPI_DATA_OUT_0 MFP_CFG(GPIO30, AF3)
+#define GPIO31_ULPI_DATA_OUT_1 MFP_CFG(GPIO31, AF3)
+#define GPIO32_ULPI_DATA_OUT_2 MFP_CFG(GPIO32, AF3)
+#define GPIO33_ULPI_DATA_OUT_3 MFP_CFG(GPIO33, AF3)
+#define GPIO34_ULPI_DATA_OUT_4 MFP_CFG(GPIO34, AF3)
+#define GPIO35_ULPI_DATA_OUT_5 MFP_CFG(GPIO35, AF3)
+#define GPIO36_ULPI_DATA_OUT_6 MFP_CFG(GPIO36, AF3)
+#define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3)
+#define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1)
+
+#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, MFP_AF0, MFP_DS01X)
+#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, MFP_AF0, MFP_DS01X)
+#define ULPI_STP MFP_CFG_DRV(ULPI_STP, MFP_AF0, MFP_DS01X)
+#endif /* CONFIG_CPU_PXA310 */
+
+#endif /* __ASM_ARCH_MFP_PXA300_H */
diff --git a/include/asm-arm/arch-pxa/mfp-pxa320.h b/include/asm-arm/arch-pxa/mfp-pxa320.h
new file mode 100644
index 00000000000..ae8ba34194c
--- /dev/null
+++ b/include/asm-arm/arch-pxa/mfp-pxa320.h
@@ -0,0 +1,446 @@
+/*
+ * linux/include/asm-arm/arch-pxa/mfp-pxa320.h
+ *
+ * PXA320 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ * 2007-08-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MFP_PXA320_H
+#define __ASM_ARCH_MFP_PXA320_H
+
+#include <asm/arch/mfp.h>
+
+/* GPIO */
+#define GPIO46_GPIO MFP_CFG(GPIO6, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+
+#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0)
+#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0)
+#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0)
+#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0)
+#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0)
+#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0)
+#define GPIO13_2_GPIO MFP_CFG(GPIO13_2, AF0)
+#define GPIO14_2_GPIO MFP_CFG(GPIO14_2, AF0)
+#define GPIO15_2_GPIO MFP_CFG(GPIO15_2, AF0)
+#define GPIO16_2_GPIO MFP_CFG(GPIO16_2, AF0)
+#define GPIO17_2_GPIO MFP_CFG(GPIO17_2, AF0)
+
+/* Chip Select */
+#define GPIO4_nCS3 MFP_CFG(GPIO4, AF1)
+
+/* AC97 */
+#define GPIO34_AC97_SYSCLK MFP_CFG(GPIO34, AF1)
+#define GPIO39_AC97_BITCLK MFP_CFG(GPIO39, AF1)
+#define GPIO40_AC97_nACRESET MFP_CFG(GPIO40, AF1)
+#define GPIO35_AC97_SDATA_IN_0 MFP_CFG(GPIO35, AF1)
+#define GPIO36_AC97_SDATA_IN_1 MFP_CFG(GPIO36, AF1)
+#define GPIO32_AC97_SDATA_IN_2 MFP_CFG(GPIO32, AF2)
+#define GPIO33_AC97_SDATA_IN_3 MFP_CFG(GPIO33, AF2)
+#define GPIO11_AC97_SDATA_IN_2 MFP_CFG(GPIO11, AF3)
+#define GPIO12_AC97_SDATA_IN_3 MFP_CFG(GPIO12, AF3)
+#define GPIO37_AC97_SDATA_OUT MFP_CFG(GPIO37, AF1)
+#define GPIO38_AC97_SYNC MFP_CFG(GPIO38, AF1)
+
+/* I2C */
+#define GPIO32_I2C_SCL MFP_CFG_LPM(GPIO32, AF1, PULL_HIGH)
+#define GPIO33_I2C_SDA MFP_CFG_LPM(GPIO33, AF1, PULL_HIGH)
+
+/* QCI */
+#define GPIO49_CI_DD_0 MFP_CFG_DRV(GPIO49, AF1, DS04X)
+#define GPIO50_CI_DD_1 MFP_CFG_DRV(GPIO50, AF1, DS04X)
+#define GPIO51_CI_DD_2 MFP_CFG_DRV(GPIO51, AF1, DS04X)
+#define GPIO52_CI_DD_3 MFP_CFG_DRV(GPIO52, AF1, DS04X)
+#define GPIO53_CI_DD_4 MFP_CFG_DRV(GPIO53, AF1, DS04X)
+#define GPIO54_CI_DD_5 MFP_CFG_DRV(GPIO54, AF1, DS04X)
+#define GPIO55_CI_DD_6 MFP_CFG_DRV(GPIO55, AF1, DS04X)
+#define GPIO56_CI_DD_7 MFP_CFG_DRV(GPIO56, AF0, DS04X)
+#define GPIO57_CI_DD_8 MFP_CFG_DRV(GPIO57, AF1, DS04X)
+#define GPIO58_CI_DD_9 MFP_CFG_DRV(GPIO58, AF1, DS04X)
+#define GPIO59_CI_MCLK MFP_CFG_DRV(GPIO59, AF0, DS04X)
+#define GPIO60_CI_PCLK MFP_CFG_DRV(GPIO60, AF0, DS04X)
+#define GPIO61_CI_HSYNC MFP_CFG_DRV(GPIO61, AF0, DS04X)
+#define GPIO62_CI_VSYNC MFP_CFG_DRV(GPIO62, AF0, DS04X)
+
+#define GPIO31_CIR_OUT MFP_CFG(GPIO31, AF5)
+
+#define GPIO0_2_CLK_EXT MFP_CFG(GPIO0_2, AF3)
+#define GPIO0_DRQ MFP_CFG(GPIO0, AF2)
+#define GPIO11_EXT_SYNC0 MFP_CFG(GPIO11, AF5)
+#define GPIO12_EXT_SYNC1 MFP_CFG(GPIO12, AF6)
+#define GPIO0_2_HZ_CLK MFP_CFG(GPIO0_2, AF1)
+#define GPIO14_HZ_CLK MFP_CFG(GPIO14, AF4)
+#define GPIO30_ICP_RXD MFP_CFG(GPIO30, AF1)
+#define GPIO31_ICP_TXD MFP_CFG(GPIO31, AF1)
+
+#define GPIO83_KP_DKIN_0 MFP_CFG_LPM(GPIO83, AF3, FLOAT)
+#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF3, FLOAT)
+#define GPIO85_KP_DKIN_2 MFP_CFG_LPM(GPIO85, AF3, FLOAT)
+#define GPIO86_KP_DKIN_3 MFP_CFG_LPM(GPIO86, AF3, FLOAT)
+
+#define GPIO105_KP_DKIN_0 MFP_CFG_LPM(GPIO105, AF2, FLOAT)
+#define GPIO106_KP_DKIN_1 MFP_CFG_LPM(GPIO106, AF2, FLOAT)
+#define GPIO107_KP_DKIN_2 MFP_CFG_LPM(GPIO107, AF2, FLOAT)
+#define GPIO108_KP_DKIN_3 MFP_CFG_LPM(GPIO108, AF2, FLOAT)
+#define GPIO109_KP_DKIN_4 MFP_CFG_LPM(GPIO109, AF2, FLOAT)
+#define GPIO110_KP_DKIN_5 MFP_CFG_LPM(GPIO110, AF2, FLOAT)
+#define GPIO111_KP_DKIN_6 MFP_CFG_LPM(GPIO111, AF2, FLOAT)
+#define GPIO112_KP_DKIN_7 MFP_CFG_LPM(GPIO112, AF2, FLOAT)
+
+#define GPIO113_KP_DKIN_0 MFP_CFG_LPM(GPIO113, AF2, FLOAT)
+#define GPIO114_KP_DKIN_1 MFP_CFG_LPM(GPIO114, AF2, FLOAT)
+#define GPIO115_KP_DKIN_2 MFP_CFG_LPM(GPIO115, AF2, FLOAT)
+#define GPIO116_KP_DKIN_3 MFP_CFG_LPM(GPIO116, AF2, FLOAT)
+#define GPIO117_KP_DKIN_4 MFP_CFG_LPM(GPIO117, AF2, FLOAT)
+#define GPIO118_KP_DKIN_5 MFP_CFG_LPM(GPIO118, AF2, FLOAT)
+#define GPIO119_KP_DKIN_6 MFP_CFG_LPM(GPIO119, AF2, FLOAT)
+#define GPIO120_KP_DKIN_7 MFP_CFG_LPM(GPIO120, AF2, FLOAT)
+
+#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF2, FLOAT)
+#define GPIO126_KP_DKIN_1 MFP_CFG_LPM(GPIO126, AF2, FLOAT)
+
+#define GPIO2_2_KP_DKIN_0 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
+#define GPIO3_2_KP_DKIN_1 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
+#define GPIO125_KP_DKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT)
+#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT)
+#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT)
+#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT)
+#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT)
+#define GPIO4_2_KP_DKIN_7 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
+
+#define GPIO113_KP_MKIN_0 MFP_CFG_LPM(GPIO113, AF1, FLOAT)
+#define GPIO114_KP_MKIN_1 MFP_CFG_LPM(GPIO114, AF1, FLOAT)
+#define GPIO115_KP_MKIN_2 MFP_CFG_LPM(GPIO115, AF1, FLOAT)
+#define GPIO116_KP_MKIN_3 MFP_CFG_LPM(GPIO116, AF1, FLOAT)
+#define GPIO117_KP_MKIN_4 MFP_CFG_LPM(GPIO117, AF1, FLOAT)
+#define GPIO118_KP_MKIN_5 MFP_CFG_LPM(GPIO118, AF1, FLOAT)
+#define GPIO119_KP_MKIN_6 MFP_CFG_LPM(GPIO119, AF1, FLOAT)
+#define GPIO120_KP_MKIN_7 MFP_CFG_LPM(GPIO120, AF1, FLOAT)
+
+#define GPIO83_KP_MKOUT_0 MFP_CFG_LPM(GPIO83, AF2, DRIVE_HIGH)
+#define GPIO84_KP_MKOUT_1 MFP_CFG_LPM(GPIO84, AF2, DRIVE_HIGH)
+#define GPIO85_KP_MKOUT_2 MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
+#define GPIO86_KP_MKOUT_3 MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_4 MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
+#define GPIO14_KP_MKOUT_5 MFP_CFG_LPM(GPIO14, AF3, DRIVE_HIGH)
+
+#define GPIO121_KP_MKOUT_0 MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
+#define GPIO122_KP_MKOUT_1 MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
+#define GPIO123_KP_MKOUT_2 MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
+#define GPIO124_KP_MKOUT_3 MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
+#define GPIO125_KP_MKOUT_4 MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
+#define GPIO126_KP_MKOUT_5 MFP_CFG_LPM(GPIO126, AF1, DRIVE_HIGH)
+#define GPIO127_KP_MKOUT_6 MFP_CFG_LPM(GPIO127, AF1, DRIVE_HIGH)
+#define GPIO5_2_KP_MKOUT_7 MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO6_2_LCD_LDD_0 MFP_CFG_DRV(GPIO6_2, AF1, DS01X)
+#define GPIO7_2_LCD_LDD_1 MFP_CFG_DRV(GPIO7_2, AF1, DS01X)
+#define GPIO8_2_LCD_LDD_2 MFP_CFG_DRV(GPIO8_2, AF1, DS01X)
+#define GPIO9_2_LCD_LDD_3 MFP_CFG_DRV(GPIO9_2, AF1, DS01X)
+#define GPIO10_2_LCD_LDD_4 MFP_CFG_DRV(GPIO10_2, AF1, DS01X)
+#define GPIO11_2_LCD_LDD_5 MFP_CFG_DRV(GPIO11_2, AF1, DS01X)
+#define GPIO12_2_LCD_LDD_6 MFP_CFG_DRV(GPIO12_2, AF1, DS01X)
+#define GPIO13_2_LCD_LDD_7 MFP_CFG_DRV(GPIO13_2, AF1, DS01X)
+#define GPIO63_LCD_LDD_8 MFP_CFG_DRV(GPIO63, AF1, DS01X)
+#define GPIO64_LCD_LDD_9 MFP_CFG_DRV(GPIO64, AF1, DS01X)
+#define GPIO65_LCD_LDD_10 MFP_CFG_DRV(GPIO65, AF1, DS01X)
+#define GPIO66_LCD_LDD_11 MFP_CFG_DRV(GPIO66, AF1, DS01X)
+#define GPIO67_LCD_LDD_12 MFP_CFG_DRV(GPIO67, AF1, DS01X)
+#define GPIO68_LCD_LDD_13 MFP_CFG_DRV(GPIO68, AF1, DS01X)
+#define GPIO69_LCD_LDD_14 MFP_CFG_DRV(GPIO69, AF1, DS01X)
+#define GPIO70_LCD_LDD_15 MFP_CFG_DRV(GPIO70, AF1, DS01X)
+#define GPIO71_LCD_LDD_16 MFP_CFG_DRV(GPIO71, AF1, DS01X)
+#define GPIO72_LCD_LDD_17 MFP_CFG_DRV(GPIO72, AF1, DS01X)
+#define GPIO73_LCD_CS_N MFP_CFG_DRV(GPIO73, AF2, DS01X)
+#define GPIO74_LCD_VSYNC MFP_CFG_DRV(GPIO74, AF2, DS01X)
+#define GPIO14_2_LCD_FCLK MFP_CFG_DRV(GPIO14_2, AF1, DS01X)
+#define GPIO15_2_LCD_LCLK MFP_CFG_DRV(GPIO15_2, AF1, DS01X)
+#define GPIO16_2_LCD_PCLK MFP_CFG_DRV(GPIO16_2, AF1, DS01X)
+#define GPIO17_2_LCD_BIAS MFP_CFG_DRV(GPIO17_2, AF1, DS01X)
+#define GPIO64_LCD_VSYNC MFP_CFG_DRV(GPIO64, AF2, DS01X)
+#define GPIO63_LCD_CS_N MFP_CFG_DRV(GPIO63, AF2, DS01X)
+
+#define GPIO6_2_MLCD_DD_0 MFP_CFG_DRV(GPIO6_2, AF7, DS08X)
+#define GPIO7_2_MLCD_DD_1 MFP_CFG_DRV(GPIO7_2, AF7, DS08X)
+#define GPIO8_2_MLCD_DD_2 MFP_CFG_DRV(GPIO8_2, AF7, DS08X)
+#define GPIO9_2_MLCD_DD_3 MFP_CFG_DRV(GPIO9_2, AF7, DS08X)
+#define GPIO10_2_MLCD_DD_4 MFP_CFG_DRV(GPIO10_2, AF7, DS08X)
+#define GPIO11_2_MLCD_DD_5 MFP_CFG_DRV(GPIO11_2, AF7, DS08X)
+#define GPIO12_2_MLCD_DD_6 MFP_CFG_DRV(GPIO12_2, AF7, DS08X)
+#define GPIO13_2_MLCD_DD_7 MFP_CFG_DRV(GPIO13_2, AF7, DS08X)
+#define GPIO63_MLCD_DD_8 MFP_CFG_DRV(GPIO63, AF7, DS08X)
+#define GPIO64_MLCD_DD_9 MFP_CFG_DRV(GPIO64, AF7, DS08X)
+#define GPIO65_MLCD_DD_10 MFP_CFG_DRV(GPIO65, AF7, DS08X)
+#define GPIO66_MLCD_DD_11 MFP_CFG_DRV(GPIO66, AF7, DS08X)
+#define GPIO67_MLCD_DD_12 MFP_CFG_DRV(GPIO67, AF7, DS08X)
+#define GPIO68_MLCD_DD_13 MFP_CFG_DRV(GPIO68, AF7, DS08X)
+#define GPIO69_MLCD_DD_14 MFP_CFG_DRV(GPIO69, AF7, DS08X)
+#define GPIO70_MLCD_DD_15 MFP_CFG_DRV(GPIO70, AF7, DS08X)
+#define GPIO71_MLCD_DD_16 MFP_CFG_DRV(GPIO71, AF7, DS08X)
+#define GPIO72_MLCD_DD_17 MFP_CFG_DRV(GPIO72, AF7, DS08X)
+#define GPIO73_MLCD_CS MFP_CFG_DRV(GPIO73, AF7, DS08X)
+#define GPIO74_MLCD_VSYNC MFP_CFG_DRV(GPIO74, AF7, DS08X)
+#define GPIO14_2_MLCD_FCLK MFP_CFG_DRV(GPIO14_2, AF7, DS08X)
+#define GPIO15_2_MLCD_LCLK MFP_CFG_DRV(GPIO15_2, AF7, DS08X)
+#define GPIO16_2_MLCD_PCLK MFP_CFG_DRV(GPIO16_2, AF7, DS08X)
+#define GPIO17_2_MLCD_BIAS MFP_CFG_DRV(GPIO17_2, AF7, DS08X)
+
+/* MMC1 */
+#define GPIO9_MMC1_CMD MFP_CFG_LPM(GPIO9, AF4, DRIVE_HIGH)
+#define GPIO22_MMC1_CLK MFP_CFG_LPM(GPIO22, AF4, DRIVE_HIGH)
+#define GPIO23_MMC1_CMD MFP_CFG_LPM(GPIO23, AF4, DRIVE_HIGH)
+#define GPIO30_MMC1_CLK MFP_CFG_LPM(GPIO30, AF4, DRIVE_HIGH)
+#define GPIO31_MMC1_CMD MFP_CFG_LPM(GPIO31, AF4, DRIVE_HIGH)
+#define GPIO5_MMC1_DAT0 MFP_CFG_LPM(GPIO5, AF4, DRIVE_HIGH)
+#define GPIO6_MMC1_DAT1 MFP_CFG_LPM(GPIO6, AF4, DRIVE_HIGH)
+#define GPIO7_MMC1_DAT2 MFP_CFG_LPM(GPIO7, AF4, DRIVE_HIGH)
+#define GPIO8_MMC1_DAT3 MFP_CFG_LPM(GPIO8, AF4, DRIVE_HIGH)
+#define GPIO18_MMC1_DAT0 MFP_CFG_LPM(GPIO18, AF4, DRIVE_HIGH)
+#define GPIO19_MMC1_DAT1 MFP_CFG_LPM(GPIO19, AF4, DRIVE_HIGH)
+#define GPIO20_MMC1_DAT2 MFP_CFG_LPM(GPIO20, AF4, DRIVE_HIGH)
+#define GPIO21_MMC1_DAT3 MFP_CFG_LPM(GPIO21, AF4, DRIVE_HIGH)
+
+#define GPIO28_MMC2_CLK MFP_CFG_LPM(GPIO28, AF4, PULL_HIGH)
+#define GPIO29_MMC2_CMD MFP_CFG_LPM(GPIO29, AF4, PULL_HIGH)
+#define GPIO30_MMC2_CLK MFP_CFG_LPM(GPIO30, AF3, PULL_HIGH)
+#define GPIO31_MMC2_CMD MFP_CFG_LPM(GPIO31, AF3, PULL_HIGH)
+#define GPIO79_MMC2_CLK MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
+#define GPIO80_MMC2_CMD MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
+
+#define GPIO5_MMC2_DAT0 MFP_CFG_LPM(GPIO5, AF2, PULL_HIGH)
+#define GPIO6_MMC2_DAT1 MFP_CFG_LPM(GPIO6, AF2, PULL_HIGH)
+#define GPIO7_MMC2_DAT2 MFP_CFG_LPM(GPIO7, AF2, PULL_HIGH)
+#define GPIO8_MMC2_DAT3 MFP_CFG_LPM(GPIO8, AF2, PULL_HIGH)
+#define GPIO24_MMC2_DAT0 MFP_CFG_LPM(GPIO24, AF4, PULL_HIGH)
+#define GPIO75_MMC2_DAT0 MFP_CFG_LPM(GPIO75, AF4, PULL_HIGH)
+#define GPIO25_MMC2_DAT1 MFP_CFG_LPM(GPIO25, AF4, PULL_HIGH)
+#define GPIO76_MMC2_DAT1 MFP_CFG_LPM(GPIO76, AF4, PULL_HIGH)
+#define GPIO26_MMC2_DAT2 MFP_CFG_LPM(GPIO26, AF4, PULL_HIGH)
+#define GPIO77_MMC2_DAT2 MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
+#define GPIO27_MMC2_DAT3 MFP_CFG_LPM(GPIO27, AF4, PULL_HIGH)
+#define GPIO78_MMC2_DAT3 MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
+
+/* 1-Wire */
+#define GPIO14_ONE_WIRE MFP_CFG_LPM(GPIO14, AF5, FLOAT)
+#define GPIO0_2_ONE_WIRE MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
+
+/* SSP1 */
+#define GPIO87_SSP1_EXTCLK MFP_CFG(GPIO87, AF1)
+#define GPIO88_SSP1_SYSCLK MFP_CFG(GPIO88, AF1)
+#define GPIO83_SSP1_SCLK MFP_CFG(GPIO83, AF1)
+#define GPIO84_SSP1_SFRM MFP_CFG(GPIO84, AF1)
+#define GPIO85_SSP1_RXD MFP_CFG(GPIO85, AF6)
+#define GPIO85_SSP1_TXD MFP_CFG(GPIO85, AF1)
+#define GPIO86_SSP1_RXD MFP_CFG(GPIO86, AF1)
+#define GPIO86_SSP1_TXD MFP_CFG(GPIO86, AF6)
+
+/* SSP2 */
+#define GPIO39_SSP2_EXTCLK MFP_CFG(GPIO39, AF2)
+#define GPIO40_SSP2_SYSCLK MFP_CFG(GPIO40, AF2)
+#define GPIO12_SSP2_SCLK MFP_CFG(GPIO12, AF2)
+#define GPIO35_SSP2_SCLK MFP_CFG(GPIO35, AF2)
+#define GPIO36_SSP2_SFRM MFP_CFG(GPIO36, AF2)
+#define GPIO37_SSP2_RXD MFP_CFG(GPIO37, AF5)
+#define GPIO37_SSP2_TXD MFP_CFG(GPIO37, AF2)
+#define GPIO38_SSP2_RXD MFP_CFG(GPIO38, AF2)
+#define GPIO38_SSP2_TXD MFP_CFG(GPIO38, AF5)
+
+#define GPIO69_SSP3_SCLK MFP_CFG(GPIO69, AF2, DS08X, FLOAT)
+#define GPIO70_SSP3_FRM MFP_CFG(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO89_SSP3_SCLK MFP_CFG(GPIO89, AF1, DS08X, FLOAT)
+#define GPIO90_SSP3_FRM MFP_CFG(GPIO90, AF1, DS08X, DRIVE_LOW)
+#define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT)
+#define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW)
+#define GPIO72_SSP3_RXD MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT)
+#define GPIO72_SSP3_TXD MFP_CFG_X(GPIO72, AF5, DS08X, DRIVE_LOW)
+#define GPIO91_SSP3_RXD MFP_CFG_X(GPIO91, AF5, DS08X, FLOAT)
+#define GPIO91_SSP3_TXD MFP_CFG_X(GPIO91, AF1, DS08X, DRIVE_LOW)
+#define GPIO92_SSP3_RXD MFP_CFG_X(GPIO92, AF1, DS08X, FLOAT)
+#define GPIO92_SSP3_TXD MFP_CFG_X(GPIO92, AF5, DS08X, DRIVE_LOW)
+
+#define GPIO93_SSP4_SCLK MFP_CFG_LPM(GPIO93, AF1, PULL_HIGH)
+#define GPIO94_SSP4_FRM MFP_CFG_LPM(GPIO94, AF1, PULL_HIGH)
+#define GPIO94_SSP4_RXD MFP_CFG_LPM(GPIO94, AF5, PULL_HIGH)
+#define GPIO95_SSP4_RXD MFP_CFG_LPM(GPIO95, AF5, PULL_HIGH)
+#define GPIO95_SSP4_TXD MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_SSP4_RXD MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+#define GPIO96_SSP4_TXD MFP_CFG_LPM(GPIO96, AF5, PULL_HIGH)
+
+/* UART1 */
+#define GPIO41_UART1_RXD MFP_CFG_LPM(GPIO41, AF2, FLOAT)
+#define GPIO41_UART1_TXD MFP_CFG_LPM(GPIO41, AF4, FLOAT)
+#define GPIO42_UART1_RXD MFP_CFG_LPM(GPIO42, AF4, FLOAT)
+#define GPIO42_UART1_TXD MFP_CFG_LPM(GPIO42, AF2, FLOAT)
+#define GPIO97_UART1_RXD MFP_CFG_LPM(GPIO97, AF1, FLOAT)
+#define GPIO97_UART1_TXD MFP_CFG_LPM(GPIO97, AF6, FLOAT)
+#define GPIO98_UART1_RXD MFP_CFG_LPM(GPIO98, AF6, FLOAT)
+#define GPIO98_UART1_TXD MFP_CFG_LPM(GPIO98, AF1, FLOAT)
+#define GPIO43_UART1_CTS MFP_CFG_LPM(GPIO43, AF2, FLOAT)
+#define GPIO43_UART1_RTS MFP_CFG_LPM(GPIO43, AF4, FLOAT)
+#define GPIO48_UART1_CTS MFP_CFG_LPM(GPIO48, AF4, FLOAT)
+#define GPIO48_UART1_RTS MFP_CFG_LPM(GPIO48, AF2, FLOAT)
+#define GPIO99_UART1_CTS MFP_CFG_LPM(GPIO99, AF1, FLOAT)
+#define GPIO99_UART1_RTS MFP_CFG_LPM(GPIO99, AF6, FLOAT)
+#define GPIO104_UART1_CTS MFP_CFG_LPM(GPIO104, AF6, FLOAT)
+#define GPIO104_UART1_RTS MFP_CFG_LPM(GPIO104, AF1, FLOAT)
+#define GPIO45_UART1_DTR MFP_CFG_LPM(GPIO45, AF4, FLOAT)
+#define GPIO45_UART1_DSR MFP_CFG_LPM(GPIO45, AF2, FLOAT)
+#define GPIO47_UART1_DTR MFP_CFG_LPM(GPIO47, AF2, FLOAT)
+#define GPIO47_UART1_DSR MFP_CFG_LPM(GPIO47, AF4, FLOAT)
+#define GPIO101_UART1_DTR MFP_CFG_LPM(GPIO101, AF6, FLOAT)
+#define GPIO101_UART1_DSR MFP_CFG_LPM(GPIO101, AF1, FLOAT)
+#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
+#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
+#define GPIO44_UART1_DCD MFP_CFG_LPM(GPIO44, AF2, FLOAT)
+#define GPIO100_UART1_DCD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
+#define GPIO46_UART1_RI MFP_CFG_LPM(GPIO46, AF2, FLOAT)
+#define GPIO102_UART1_RI MFP_CFG_LPM(GPIO102, AF1, FLOAT)
+
+/* UART2 */
+#define GPIO109_UART2_CTS MFP_CFG_LPM(GPIO109, AF3, FLOAT)
+#define GPIO109_UART2_RTS MFP_CFG_LPM(GPIO109, AF1, FLOAT)
+#define GPIO112_UART2_CTS MFP_CFG_LPM(GPIO112, AF1, FLOAT)
+#define GPIO112_UART2_RTS MFP_CFG_LPM(GPIO112, AF3, FLOAT)
+#define GPIO110_UART2_RXD MFP_CFG_LPM(GPIO110, AF1, FLOAT)
+#define GPIO110_UART2_TXD MFP_CFG_LPM(GPIO110, AF3, FLOAT)
+#define GPIO111_UART2_RXD MFP_CFG_LPM(GPIO111, AF3, FLOAT)
+#define GPIO111_UART2_TXD MFP_CFG_LPM(GPIO111, AF1, FLOAT)
+
+/* UART3 */
+#define GPIO89_UART3_CTS MFP_CFG_LPM(GPIO89, AF2, FLOAT)
+#define GPIO89_UART3_RTS MFP_CFG_LPM(GPIO89, AF4, FLOAT)
+#define GPIO90_UART3_CTS MFP_CFG_LPM(GPIO90, AF4, FLOAT)
+#define GPIO90_UART3_RTS MFP_CFG_LPM(GPIO90, AF2, FLOAT)
+#define GPIO105_UART3_CTS MFP_CFG_LPM(GPIO105, AF1, FLOAT)
+#define GPIO105_UART3_RTS MFP_CFG_LPM(GPIO105, AF3, FLOAT)
+#define GPIO106_UART3_CTS MFP_CFG_LPM(GPIO106, AF3, FLOAT)
+#define GPIO106_UART3_RTS MFP_CFG_LPM(GPIO106, AF1, FLOAT)
+#define GPIO30_UART3_RXD MFP_CFG_LPM(GPIO30, AF2, FLOAT)
+#define GPIO30_UART3_TXD MFP_CFG_LPM(GPIO30, AF6, FLOAT)
+#define GPIO31_UART3_RXD MFP_CFG_LPM(GPIO31, AF6, FLOAT)
+#define GPIO31_UART3_TXD MFP_CFG_LPM(GPIO31, AF2, FLOAT)
+#define GPIO91_UART3_RXD MFP_CFG_LPM(GPIO91, AF4, FLOAT)
+#define GPIO91_UART3_TXD MFP_CFG_LPM(GPIO91, AF2, FLOAT)
+#define GPIO92_UART3_RXD MFP_CFG_LPM(GPIO92, AF2, FLOAT)
+#define GPIO92_UART3_TXD MFP_CFG_LPM(GPIO92, AF4, FLOAT)
+#define GPIO107_UART3_RXD MFP_CFG_LPM(GPIO107, AF3, FLOAT)
+#define GPIO107_UART3_TXD MFP_CFG_LPM(GPIO107, AF1, FLOAT)
+#define GPIO108_UART3_RXD MFP_CFG_LPM(GPIO108, AF1, FLOAT)
+#define GPIO108_UART3_TXD MFP_CFG_LPM(GPIO108, AF3, FLOAT)
+
+
+/* USB 2.0 UTMI */
+#define GPIO10_UTM_CLK MFP_CFG(GPIO10, AF1)
+#define GPIO36_U2D_RXERROR MFP_CFG(GPIO36, AF3)
+#define GPIO60_U2D_RXERROR MFP_CFG(GPIO60, AF1)
+#define GPIO87_U2D_RXERROR MFP_CFG(GPIO87, AF5)
+#define GPIO34_UTM_RXVALID MFP_CFG(GPIO34, AF3)
+#define GPIO58_UTM_RXVALID MFP_CFG(GPIO58, AF2)
+#define GPIO85_UTM_RXVALID MFP_CFG(GPIO85, AF5)
+#define GPIO35_UTM_RXACTIVE MFP_CFG(GPIO35, AF3)
+#define GPIO59_UTM_RXACTIVE MFP_CFG(GPIO59, AF1)
+#define GPIO86_UTM_RXACTIVE MFP_CFG(GPIO86, AF5)
+#define GPIO73_UTM_TXREADY MFP_CFG(GPIO73, AF1)
+#define GPIO68_UTM_LINESTATE_0 MFP_CFG(GPIO68, AF3)
+#define GPIO90_UTM_LINESTATE_0 MFP_CFG(GPIO90, AF3)
+#define GPIO102_UTM_LINESTATE_0 MFP_CFG(GPIO102, AF3)
+#define GPIO107_UTM_LINESTATE_0 MFP_CFG(GPIO107, AF4)
+#define GPIO69_UTM_LINESTATE_1 MFP_CFG(GPIO69, AF3)
+#define GPIO91_UTM_LINESTATE_1 MFP_CFG(GPIO91, AF3)
+#define GPIO103_UTM_LINESTATE_1 MFP_CFG(GPIO103, AF3)
+
+#define GPIO41_U2D_PHYDATA_0 MFP_CFG(GPIO41, AF3)
+#define GPIO42_U2D_PHYDATA_1 MFP_CFG(GPIO42, AF3)
+#define GPIO43_U2D_PHYDATA_2 MFP_CFG(GPIO43, AF3)
+#define GPIO44_U2D_PHYDATA_3 MFP_CFG(GPIO44, AF3)
+#define GPIO45_U2D_PHYDATA_4 MFP_CFG(GPIO45, AF3)
+#define GPIO46_U2D_PHYDATA_5 MFP_CFG(GPIO46, AF3)
+#define GPIO47_U2D_PHYDATA_6 MFP_CFG(GPIO47, AF3)
+#define GPIO48_U2D_PHYDATA_7 MFP_CFG(GPIO48, AF3)
+
+#define GPIO49_U2D_PHYDATA_0 MFP_CFG(GPIO49, AF3)
+#define GPIO50_U2D_PHYDATA_1 MFP_CFG(GPIO50, AF3)
+#define GPIO51_U2D_PHYDATA_2 MFP_CFG(GPIO51, AF3)
+#define GPIO52_U2D_PHYDATA_3 MFP_CFG(GPIO52, AF3)
+#define GPIO53_U2D_PHYDATA_4 MFP_CFG(GPIO53, AF3)
+#define GPIO54_U2D_PHYDATA_5 MFP_CFG(GPIO54, AF3)
+#define GPIO55_U2D_PHYDATA_6 MFP_CFG(GPIO55, AF3)
+#define GPIO56_U2D_PHYDATA_7 MFP_CFG(GPIO56, AF3)
+
+#define GPIO37_U2D_OPMODE0 MFP_CFG(GPIO37, AF4)
+#define GPIO61_U2D_OPMODE0 MFP_CFG(GPIO61, AF2)
+#define GPIO88_U2D_OPMODE0 MFP_CFG(GPIO88, AF7)
+
+#define GPIO38_U2D_OPMODE1 MFP_CFG(GPIO38, AF4)
+#define GPIO62_U2D_OPMODE1 MFP_CFG(GPIO62, AF2)
+#define GPIO104_U2D_OPMODE1 MFP_CFG(GPIO104, AF4)
+#define GPIO108_U2D_OPMODE1 MFP_CFG(GPIO108, AF5)
+
+#define GPIO74_U2D_RESET MFP_CFG(GPIO74, AF1)
+#define GPIO93_U2D_RESET MFP_CFG(GPIO93, AF2)
+#define GPIO98_U2D_RESET MFP_CFG(GPIO98, AF3)
+
+#define GPIO67_U2D_SUSPEND MFP_CFG(GPIO67, AF3)
+#define GPIO96_U2D_SUSPEND MFP_CFG(GPIO96, AF2)
+#define GPIO101_U2D_SUSPEND MFP_CFG(GPIO101, AF3)
+
+#define GPIO66_U2D_TERM_SEL MFP_CFG(GPIO66, AF5)
+#define GPIO95_U2D_TERM_SEL MFP_CFG(GPIO95, AF3)
+#define GPIO97_U2D_TERM_SEL MFP_CFG(GPIO97, AF7)
+#define GPIO100_U2D_TERM_SEL MFP_CFG(GPIO100, AF5)
+
+#define GPIO39_U2D_TXVALID MFP_CFG(GPIO39, AF4)
+#define GPIO70_U2D_TXVALID MFP_CFG(GPIO70, AF5)
+#define GPIO83_U2D_TXVALID MFP_CFG(GPIO83, AF7)
+
+#define GPIO65_U2D_XCVR_SEL MFP_CFG(GPIO65, AF5)
+#define GPIO94_U2D_XCVR_SEL MFP_CFG(GPIO94, AF3)
+#define GPIO99_U2D_XCVR_SEL MFP_CFG(GPIO99, AF5)
+
+/* USB Host 1.1 */
+#define GPIO2_2_USBH_PEN MFP_CFG(GPIO2_2, AF1)
+#define GPIO3_2_USBH_PWR MFP_CFG(GPIO3_2, AF1)
+
+/* USB P2 */
+#define GPIO97_USB_P2_2 MFP_CFG(GPIO97, AF2)
+#define GPIO97_USB_P2_6 MFP_CFG(GPIO97, AF4)
+#define GPIO98_USB_P2_2 MFP_CFG(GPIO98, AF4)
+#define GPIO98_USB_P2_6 MFP_CFG(GPIO98, AF2)
+#define GPIO99_USB_P2_1 MFP_CFG(GPIO99, AF2)
+#define GPIO100_USB_P2_4 MFP_CFG(GPIO100, AF2)
+#define GPIO101_USB_P2_8 MFP_CFG(GPIO101, AF2)
+#define GPIO102_USB_P2_3 MFP_CFG(GPIO102, AF2)
+#define GPIO103_USB_P2_5 MFP_CFG(GPIO103, AF2)
+#define GPIO104_USB_P2_7 MFP_CFG(GPIO104, AF2)
+
+/* USB P3 */
+#define GPIO75_USB_P3_1 MFP_CFG(GPIO75, AF2)
+#define GPIO76_USB_P3_2 MFP_CFG(GPIO76, AF2)
+#define GPIO77_USB_P3_3 MFP_CFG(GPIO77, AF2)
+#define GPIO78_USB_P3_4 MFP_CFG(GPIO78, AF2)
+#define GPIO79_USB_P3_5 MFP_CFG(GPIO79, AF2)
+#define GPIO80_USB_P3_6 MFP_CFG(GPIO80, AF2)
+
+#define GPIO13_CHOUT0 MFP_CFG(GPIO13, AF6)
+#define GPIO14_CHOUT1 MFP_CFG(GPIO14, AF6)
+
+#define GPIO2_RDY MFP_CFG(GPIO2, AF1)
+#define GPIO5_NPIOR MFP_CFG(GPIO5, AF3)
+
+#define GPIO11_PWM0_OUT MFP_CFG(GPIO11, AF1)
+#define GPIO12_PWM1_OUT MFP_CFG(GPIO12, AF1)
+#define GPIO13_PWM2_OUT MFP_CFG(GPIO13, AF1)
+#define GPIO14_PWM3_OUT MFP_CFG(GPIO14, AF1)
+
+#endif /* __ASM_ARCH_MFP_PXA320_H */
diff --git a/include/asm-arm/arch-pxa/mfp.h b/include/asm-arm/arch-pxa/mfp.h
new file mode 100644
index 00000000000..60291742ffd
--- /dev/null
+++ b/include/asm-arm/arch-pxa/mfp.h
@@ -0,0 +1,576 @@
+/*
+ * linux/include/asm-arm/arch-pxa/mfp.h
+ *
+ * Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.y.miao@gmail.com>
+ * initial version
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MFP_H
+#define __ASM_ARCH_MFP_H
+
+#define MFPR_BASE (0x40e10000)
+#define MFPR_SIZE (PAGE_SIZE)
+
+#define mfp_to_gpio(m) ((m) % 128)
+
+/* list of all the configurable MFP pins */
+enum {
+ MFP_PIN_INVALID = -1,
+
+ MFP_PIN_GPIO0 = 0,
+ MFP_PIN_GPIO1,
+ MFP_PIN_GPIO2,
+ MFP_PIN_GPIO3,
+ MFP_PIN_GPIO4,
+ MFP_PIN_GPIO5,
+ MFP_PIN_GPIO6,
+ MFP_PIN_GPIO7,
+ MFP_PIN_GPIO8,
+ MFP_PIN_GPIO9,
+ MFP_PIN_GPIO10,
+ MFP_PIN_GPIO11,
+ MFP_PIN_GPIO12,
+ MFP_PIN_GPIO13,
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO16,
+ MFP_PIN_GPIO17,
+ MFP_PIN_GPIO18,
+ MFP_PIN_GPIO19,
+ MFP_PIN_GPIO20,
+ MFP_PIN_GPIO21,
+ MFP_PIN_GPIO22,
+ MFP_PIN_GPIO23,
+ MFP_PIN_GPIO24,
+ MFP_PIN_GPIO25,
+ MFP_PIN_GPIO26,
+ MFP_PIN_GPIO27,
+ MFP_PIN_GPIO28,
+ MFP_PIN_GPIO29,
+ MFP_PIN_GPIO30,
+ MFP_PIN_GPIO31,
+ MFP_PIN_GPIO32,
+ MFP_PIN_GPIO33,
+ MFP_PIN_GPIO34,
+ MFP_PIN_GPIO35,
+ MFP_PIN_GPIO36,
+ MFP_PIN_GPIO37,
+ MFP_PIN_GPIO38,
+ MFP_PIN_GPIO39,
+ MFP_PIN_GPIO40,
+ MFP_PIN_GPIO41,
+ MFP_PIN_GPIO42,
+ MFP_PIN_GPIO43,
+ MFP_PIN_GPIO44,
+ MFP_PIN_GPIO45,
+ MFP_PIN_GPIO46,
+ MFP_PIN_GPIO47,
+ MFP_PIN_GPIO48,
+ MFP_PIN_GPIO49,
+ MFP_PIN_GPIO50,
+ MFP_PIN_GPIO51,
+ MFP_PIN_GPIO52,
+ MFP_PIN_GPIO53,
+ MFP_PIN_GPIO54,
+ MFP_PIN_GPIO55,
+ MFP_PIN_GPIO56,
+ MFP_PIN_GPIO57,
+ MFP_PIN_GPIO58,
+ MFP_PIN_GPIO59,
+ MFP_PIN_GPIO60,
+ MFP_PIN_GPIO61,
+ MFP_PIN_GPIO62,
+ MFP_PIN_GPIO63,
+ MFP_PIN_GPIO64,
+ MFP_PIN_GPIO65,
+ MFP_PIN_GPIO66,
+ MFP_PIN_GPIO67,
+ MFP_PIN_GPIO68,
+ MFP_PIN_GPIO69,
+ MFP_PIN_GPIO70,
+ MFP_PIN_GPIO71,
+ MFP_PIN_GPIO72,
+ MFP_PIN_GPIO73,
+ MFP_PIN_GPIO74,
+ MFP_PIN_GPIO75,
+ MFP_PIN_GPIO76,
+ MFP_PIN_GPIO77,
+ MFP_PIN_GPIO78,
+ MFP_PIN_GPIO79,
+ MFP_PIN_GPIO80,
+ MFP_PIN_GPIO81,
+ MFP_PIN_GPIO82,
+ MFP_PIN_GPIO83,
+ MFP_PIN_GPIO84,
+ MFP_PIN_GPIO85,
+ MFP_PIN_GPIO86,
+ MFP_PIN_GPIO87,
+ MFP_PIN_GPIO88,
+ MFP_PIN_GPIO89,
+ MFP_PIN_GPIO90,
+ MFP_PIN_GPIO91,
+ MFP_PIN_GPIO92,
+ MFP_PIN_GPIO93,
+ MFP_PIN_GPIO94,
+ MFP_PIN_GPIO95,
+ MFP_PIN_GPIO96,
+ MFP_PIN_GPIO97,
+ MFP_PIN_GPIO98,
+ MFP_PIN_GPIO99,
+ MFP_PIN_GPIO100,
+ MFP_PIN_GPIO101,
+ MFP_PIN_GPIO102,
+ MFP_PIN_GPIO103,
+ MFP_PIN_GPIO104,
+ MFP_PIN_GPIO105,
+ MFP_PIN_GPIO106,
+ MFP_PIN_GPIO107,
+ MFP_PIN_GPIO108,
+ MFP_PIN_GPIO109,
+ MFP_PIN_GPIO110,
+ MFP_PIN_GPIO111,
+ MFP_PIN_GPIO112,
+ MFP_PIN_GPIO113,
+ MFP_PIN_GPIO114,
+ MFP_PIN_GPIO115,
+ MFP_PIN_GPIO116,
+ MFP_PIN_GPIO117,
+ MFP_PIN_GPIO118,
+ MFP_PIN_GPIO119,
+ MFP_PIN_GPIO120,
+ MFP_PIN_GPIO121,
+ MFP_PIN_GPIO122,
+ MFP_PIN_GPIO123,
+ MFP_PIN_GPIO124,
+ MFP_PIN_GPIO125,
+ MFP_PIN_GPIO126,
+ MFP_PIN_GPIO127,
+ MFP_PIN_GPIO0_2,
+ MFP_PIN_GPIO1_2,
+ MFP_PIN_GPIO2_2,
+ MFP_PIN_GPIO3_2,
+ MFP_PIN_GPIO4_2,
+ MFP_PIN_GPIO5_2,
+ MFP_PIN_GPIO6_2,
+ MFP_PIN_GPIO7_2,
+ MFP_PIN_GPIO8_2,
+ MFP_PIN_GPIO9_2,
+ MFP_PIN_GPIO10_2,
+ MFP_PIN_GPIO11_2,
+ MFP_PIN_GPIO12_2,
+ MFP_PIN_GPIO13_2,
+ MFP_PIN_GPIO14_2,
+ MFP_PIN_GPIO15_2,
+ MFP_PIN_GPIO16_2,
+ MFP_PIN_GPIO17_2,
+
+ MFP_PIN_ULPI_STP,
+ MFP_PIN_ULPI_NXT,
+ MFP_PIN_ULPI_DIR,
+
+ MFP_PIN_nXCVREN,
+ MFP_PIN_DF_CLE_nOE,
+ MFP_PIN_DF_nADV1_ALE,
+ MFP_PIN_DF_SCLK_E,
+ MFP_PIN_DF_SCLK_S,
+ MFP_PIN_nBE0,
+ MFP_PIN_nBE1,
+ MFP_PIN_DF_nADV2_ALE,
+ MFP_PIN_DF_INT_RnB,
+ MFP_PIN_DF_nCS0,
+ MFP_PIN_DF_nCS1,
+ MFP_PIN_nLUA,
+ MFP_PIN_nLLA,
+ MFP_PIN_DF_nWE,
+ MFP_PIN_DF_ALE_nWE,
+ MFP_PIN_DF_nRE_nOE,
+ MFP_PIN_DF_ADDR0,
+ MFP_PIN_DF_ADDR1,
+ MFP_PIN_DF_ADDR2,
+ MFP_PIN_DF_ADDR3,
+ MFP_PIN_DF_IO0,
+ MFP_PIN_DF_IO1,
+ MFP_PIN_DF_IO2,
+ MFP_PIN_DF_IO3,
+ MFP_PIN_DF_IO4,
+ MFP_PIN_DF_IO5,
+ MFP_PIN_DF_IO6,
+ MFP_PIN_DF_IO7,
+ MFP_PIN_DF_IO8,
+ MFP_PIN_DF_IO9,
+ MFP_PIN_DF_IO10,
+ MFP_PIN_DF_IO11,
+ MFP_PIN_DF_IO12,
+ MFP_PIN_DF_IO13,
+ MFP_PIN_DF_IO14,
+ MFP_PIN_DF_IO15,
+
+ MFP_PIN_MAX,
+};
+
+/*
+ * Table that determines the low power modes outputs, with actual settings
+ * used in parentheses for don't-care values. Except for the float output,
+ * the configured driven and pulled levels match, so if there is a need for
+ * non-LPM pulled output, the same configuration could probably be used.
+ *
+ * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
+ * (bit 7) (bit 8) (bit 14d) (bit 13d)
+ *
+ * Drive 0 0 0 0 X (1) 0
+ * Drive 1 0 1 X (1) 0 0
+ * Pull hi (1) 1 X(1) 1 0 0
+ * Pull lo (0) 1 X(0) 0 1 0
+ * Z (float) 1 X(0) 0 0 0
+ */
+#define MFP_LPM_DRIVE_LOW 0x8
+#define MFP_LPM_DRIVE_HIGH 0x6
+#define MFP_LPM_PULL_HIGH 0x7
+#define MFP_LPM_PULL_LOW 0x9
+#define MFP_LPM_FLOAT 0x1
+#define MFP_LPM_PULL_NEITHER 0x0
+
+/*
+ * The pullup and pulldown state of the MFP pin is by default determined by
+ * selected alternate function. In case some buggy devices need to override
+ * this default behavior, pxa3xx_mfp_set_pull() can be invoked with one of
+ * the following definition as the parameter.
+ *
+ * Definition pull_sel pullup_en pulldown_en
+ * MFP_PULL_HIGH 1 1 0
+ * MFP_PULL_LOW 1 0 1
+ * MFP_PULL_BOTH 1 1 1
+ * MFP_PULL_NONE 1 0 0
+ * MFP_PULL_DEFAULT 0 X X
+ *
+ * NOTE: pxa3xx_mfp_set_pull() will modify the PULLUP_EN and PULLDOWN_EN
+ * bits, which will cause potential conflicts with the low power mode
+ * setting, device drivers should take care of this
+ */
+#define MFP_PULL_BOTH (0x7u)
+#define MFP_PULL_HIGH (0x6u)
+#define MFP_PULL_LOW (0x5u)
+#define MFP_PULL_NONE (0x4u)
+#define MFP_PULL_DEFAULT (0x0u)
+
+#define MFP_AF0 (0)
+#define MFP_AF1 (1)
+#define MFP_AF2 (2)
+#define MFP_AF3 (3)
+#define MFP_AF4 (4)
+#define MFP_AF5 (5)
+#define MFP_AF6 (6)
+#define MFP_AF7 (7)
+
+#define MFP_DS01X (0)
+#define MFP_DS02X (1)
+#define MFP_DS03X (2)
+#define MFP_DS04X (3)
+#define MFP_DS06X (4)
+#define MFP_DS08X (5)
+#define MFP_DS10X (6)
+#define MFP_DS12X (7)
+
+#define MFP_EDGE_BOTH 0x3
+#define MFP_EDGE_RISE 0x2
+#define MFP_EDGE_FALL 0x1
+#define MFP_EDGE_NONE 0x0
+
+#define MFPR_AF_MASK 0x0007
+#define MFPR_DRV_MASK 0x1c00
+#define MFPR_RDH_MASK 0x0200
+#define MFPR_LPM_MASK 0xe180
+#define MFPR_PULL_MASK 0xe000
+#define MFPR_EDGE_MASK 0x0070
+
+#define MFPR_ALT_OFFSET 0
+#define MFPR_ERE_OFFSET 4
+#define MFPR_EFE_OFFSET 5
+#define MFPR_EC_OFFSET 6
+#define MFPR_SON_OFFSET 7
+#define MFPR_SD_OFFSET 8
+#define MFPR_SS_OFFSET 9
+#define MFPR_DRV_OFFSET 10
+#define MFPR_PD_OFFSET 13
+#define MFPR_PU_OFFSET 14
+#define MFPR_PS_OFFSET 15
+
+#define MFPR(af, drv, rdh, lpm, edge) \
+ (((af) & 0x7) | (((drv) & 0x7) << 10) |\
+ (((rdh) & 0x1) << 9) |\
+ (((lpm) & 0x3) << 7) |\
+ (((lpm) & 0x4) << 12)|\
+ (((lpm) & 0x8) << 10)|\
+ ((!(edge)) << 6) |\
+ (((edge) & 0x1) << 5) |\
+ (((edge) & 0x2) << 3))
+
+/*
+ * a possible MFP configuration is represented by a 32-bit integer
+ * bit 0..15 - MFPR value (16-bit)
+ * bit 16..31 - mfp pin index (used to obtain the MFPR offset)
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * MFPR_DEFAULT - default MFPR value, with
+ * alternate function = 0,
+ * drive strength = fast 1mA (MFP_DS01X)
+ * low power mode = default
+ * release dalay hold = false (RDH bit)
+ * edge detection = none
+ *
+ * MFP_CFG - default MFPR value with alternate function
+ * MFP_CFG_DRV - default MFPR value with alternate function and
+ * pin drive strength
+ * MFP_CFG_LPM - default MFPR value with alternate function and
+ * low power mode
+ * MFP_CFG_X - default MFPR value with alternate function,
+ * pin drive strength and low power mode
+ *
+ * use
+ *
+ * MFP_CFG_PIN - to get the MFP pin index
+ * MFP_CFG_VAL - to get the corresponding MFPR value
+ */
+
+typedef uint32_t mfp_cfg_t;
+
+#define MFP_CFG_PIN(mfp_cfg) (((mfp_cfg) >> 16) & 0xffff)
+#define MFP_CFG_VAL(mfp_cfg) ((mfp_cfg) & 0xffff)
+
+#define MFPR_DEFAULT (0x0000)
+
+#define MFP_CFG(pin, af) \
+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af))
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
+ ((MFP_##drv) << 10) | (MFP_##af))
+
+#define MFP_CFG_LPM(pin, af, lpm) \
+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af) |\
+ (((MFP_LPM_##lpm) & 0x3) << 7) |\
+ (((MFP_LPM_##lpm) & 0x4) << 12) |\
+ (((MFP_LPM_##lpm) & 0x8) << 10))
+
+#define MFP_CFG_X(pin, af, drv, lpm) \
+ ((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
+ ((MFP_##drv) << 10) | (MFP_##af) |\
+ (((MFP_LPM_##lpm) & 0x3) << 7) |\
+ (((MFP_LPM_##lpm) & 0x4) << 12) |\
+ (((MFP_LPM_##lpm) & 0x8) << 10))
+
+/* common MFP configurations - processor specific ones defined
+ * in mfp-pxa3xx.h
+ */
+#define GPIO0_GPIO MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
+
+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
+
+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
+
+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
+
+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO MFP_CFG(GPIO127, AF0)
+
+#define GPIO0_2_GPIO MFP_CFG(GPIO0_2, AF0)
+#define GPIO1_2_GPIO MFP_CFG(GPIO1_2, AF0)
+#define GPIO2_2_GPIO MFP_CFG(GPIO2_2, AF0)
+#define GPIO3_2_GPIO MFP_CFG(GPIO3_2, AF0)
+#define GPIO4_2_GPIO MFP_CFG(GPIO4_2, AF0)
+#define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0)
+#define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0)
+
+/*
+ * each MFP pin will have a MFPR register, since the offset of the
+ * register varies between processors, the processor specific code
+ * should initialize the pin offsets by pxa3xx_mfp_init_addr()
+ *
+ * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
+ * structure, which represents a range of MFP pins from "start" to
+ * "end", with the offset begining at "offset", to define a single
+ * pin, let "end" = -1
+ *
+ * use
+ *
+ * MFP_ADDR_X() to define a range of pins
+ * MFP_ADDR() to define a single pin
+ * MFP_ADDR_END to signal the end of pin offset definitions
+ */
+struct pxa3xx_mfp_addr_map {
+ unsigned int start;
+ unsigned int end;
+ unsigned long offset;
+};
+
+#define MFP_ADDR_X(start, end, offset) \
+ { MFP_PIN_##start, MFP_PIN_##end, offset }
+
+#define MFP_ADDR(pin, offset) \
+ { MFP_PIN_##pin, -1, offset }
+
+#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
+
+struct pxa3xx_mfp_pin {
+ unsigned long mfpr_off; /* MFPRxx register offset */
+ unsigned long mfpr_val; /* MFPRxx register value */
+};
+
+/*
+ * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
+ * to the MFPR register
+ */
+unsigned long pxa3xx_mfp_read(int mfp);
+void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
+
+/*
+ * pxa3xx_mfp_set_afds - set MFP alternate function and drive strength
+ * pxa3xx_mfp_set_rdh - set MFP release delay hold on/off
+ * pxa3xx_mfp_set_lpm - set MFP low power mode state
+ * pxa3xx_mfp_set_edge - set MFP edge detection in low power mode
+ *
+ * use these functions to override/change the default configuration
+ * done by pxa3xx_mfp_set_config(s)
+ */
+void pxa3xx_mfp_set_afds(int mfp, int af, int ds);
+void pxa3xx_mfp_set_rdh(int mfp, int rdh);
+void pxa3xx_mfp_set_lpm(int mfp, int lpm);
+void pxa3xx_mfp_set_edge(int mfp, int edge);
+
+/*
+ * pxa3xx_mfp_config - configure the MFPR registers
+ *
+ * used by board specific initialization code
+ */
+void pxa3xx_mfp_config(mfp_cfg_t *mfp_cfgs, int num);
+
+/*
+ * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
+ * index and MFPR register offset
+ *
+ * used by processor specific code
+ */
+void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
+void __init pxa3xx_init_mfp(void);
+
+#endif /* __ASM_ARCH_MFP_H */
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h
index 6903db7fae1..9d9f4b54b2c 100644
--- a/include/asm-arm/arch-pxa/pm.h
+++ b/include/asm-arm/arch-pxa/pm.h
@@ -7,6 +7,8 @@
*
*/
+#include <linux/suspend.h>
+
struct pxa_cpu_pm_fns {
int save_size;
void (*save)(unsigned long *);
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index e68b593d69d..bb68b598c43 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1177,7 +1177,7 @@
#define GPIO_bit(x) (1 << ((x) & 0x1f))
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
/* Interrupt Controller */
@@ -1823,6 +1823,7 @@
#define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */
#define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */
#define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */
+#define LCCR4 __REG(0x44000010) /* LCD Controller Control Register 3 */
#define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */
#define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */
#define LCSR __REG(0x44000038) /* LCD Controller Status Register */
@@ -1836,6 +1837,16 @@
#define LCCR3_8BPP (3 << 24)
#define LCCR3_16BPP (4 << 24)
+#define LCCR3_PDFOR_0 (0 << 30)
+#define LCCR3_PDFOR_1 (1 << 30)
+#define LCCR3_PDFOR_2 (2 << 30)
+#define LCCR3_PDFOR_3 (3 << 30)
+
+#define LCCR4_PAL_FOR_0 (0 << 15)
+#define LCCR4_PAL_FOR_1 (1 << 15)
+#define LCCR4_PAL_FOR_2 (2 << 15)
+#define LCCR4_PAL_FOR_MASK (3 << 15)
+
#define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */
#define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */
#define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */
diff --git a/include/asm-arm/arch-pxa/pxa3xx-regs.h b/include/asm-arm/arch-pxa/pxa3xx-regs.h
new file mode 100644
index 00000000000..3900a0ca0bc
--- /dev/null
+++ b/include/asm-arm/arch-pxa/pxa3xx-regs.h
@@ -0,0 +1,75 @@
+/*
+ * linux/include/asm-arm/arch-pxa/pxa3xx-regs.h
+ *
+ * PXA3xx specific register definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_PXA3XX_REGS_H
+#define __ASM_ARCH_PXA3XX_REGS_H
+
+/*
+ * Application Subsystem Clock
+ */
+#define ACCR __REG(0x41340000) /* Application Subsystem Clock Configuration Register */
+#define ACSR __REG(0x41340004) /* Application Subsystem Clock Status Register */
+#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */
+#define CKENA __REG(0x4134000C) /* A Clock Enable Register */
+#define CKENB __REG(0x41340010) /* B Clock Enable Register */
+#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */
+
+/*
+ * Clock Enable Bit
+ */
+#define CKEN_LCD 1 /* < LCD Clock Enable */
+#define CKEN_USBH 2 /* < USB host clock enable */
+#define CKEN_CAMERA 3 /* < Camera interface clock enable */
+#define CKEN_NAND 4 /* < NAND Flash Controller Clock Enable */
+#define CKEN_USB2 6 /* < USB 2.0 client clock enable. */
+#define CKEN_DMC 8 /* < Dynamic Memory Controller clock enable */
+#define CKEN_SMC 9 /* < Static Memory Controller clock enable */
+#define CKEN_ISC 10 /* < Internal SRAM Controller clock enable */
+#define CKEN_BOOT 11 /* < Boot rom clock enable */
+#define CKEN_MMC1 12 /* < MMC1 Clock enable */
+#define CKEN_MMC2 13 /* < MMC2 clock enable */
+#define CKEN_KEYPAD 14 /* < Keypand Controller Clock Enable */
+#define CKEN_CIR 15 /* < Consumer IR Clock Enable */
+#define CKEN_USIM0 17 /* < USIM[0] Clock Enable */
+#define CKEN_USIM1 18 /* < USIM[1] Clock Enable */
+#define CKEN_TPM 19 /* < TPM clock enable */
+#define CKEN_UDC 20 /* < UDC clock enable */
+#define CKEN_BTUART 21 /* < BTUART clock enable */
+#define CKEN_FFUART 22 /* < FFUART clock enable */
+#define CKEN_STUART 23 /* < STUART clock enable */
+#define CKEN_AC97 24 /* < AC97 clock enable */
+#define CKEN_TOUCH 25 /* < Touch screen Interface Clock Enable */
+#define CKEN_SSP1 26 /* < SSP1 clock enable */
+#define CKEN_SSP2 27 /* < SSP2 clock enable */
+#define CKEN_SSP3 28 /* < SSP3 clock enable */
+#define CKEN_SSP4 29 /* < SSP4 clock enable */
+#define CKEN_MSL0 30 /* < MSL0 clock enable */
+#define CKEN_PWM0 32 /* < PWM[0] clock enable */
+#define CKEN_PWM1 33 /* < PWM[1] clock enable */
+#define CKEN_I2C 36 /* < I2C clock enable */
+#define CKEN_INTC 38 /* < Interrupt controller clock enable */
+#define CKEN_GPIO 39 /* < GPIO clock enable */
+#define CKEN_1WIRE 40 /* < 1-wire clock enable */
+#define CKEN_HSIO2 41 /* < HSIO2 clock enable */
+#define CKEN_MINI_IM 48 /* < Mini-IM */
+#define CKEN_MINI_LCD 49 /* < Mini LCD */
+
+#if defined(CONFIG_CPU_PXA310)
+#define CKEN_MMC3 5 /* < MMC3 Clock Enable */
+#define CKEN_MVED 43 /* < MVED clock enable */
+#endif
+
+/* Note: GCU clock enable bit differs on PXA300/PXA310 and PXA320 */
+#define PXA300_CKEN_GRAPHICS 42 /* Graphics controller clock enable */
+#define PXA320_CKEN_GRAPHICS 7 /* Graphics controller clock enable */
+
+#endif /* __ASM_ARCH_PXA3XX_REGS_H */
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index 81c3928d608..ea2336aa70e 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -70,7 +70,12 @@ struct pxafb_mach_info {
* LCCR3_HSP, LCCR3_VSP, LCCR0_Pcd(x), LCCR3_Bpp
*/
u_int lccr3;
-
+ /* The following should be defined in LCCR4
+ * LCCR4_PAL_FOR_0 or LCCR4_PAL_FOR_1 or LCCR4_PAL_FOR_2
+ *
+ * All other bits in LCCR4 should be left alone.
+ */
+ u_int lccr4;
void (*pxafb_backlight_power)(int);
void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
diff --git a/include/asm-arm/arch-pxa/timex.h b/include/asm-arm/arch-pxa/timex.h
index 2473bb51d0a..8d882f0b6a1 100644
--- a/include/asm-arm/arch-pxa/timex.h
+++ b/include/asm-arm/arch-pxa/timex.h
@@ -21,4 +21,6 @@
#else
#define CLOCK_TICK_RATE 3250000
#endif
+#else
+#define CLOCK_TICK_RATE 3250000
#endif
diff --git a/include/asm-arm/arch-pxa/zylonite.h b/include/asm-arm/arch-pxa/zylonite.h
new file mode 100644
index 00000000000..f58b59162b8
--- /dev/null
+++ b/include/asm-arm/arch-pxa/zylonite.h
@@ -0,0 +1,35 @@
+#ifndef __ASM_ARCH_ZYLONITE_H
+#define __ASM_ARCH_ZYLONITE_H
+
+#define ZYLONITE_ETH_PHYS 0x14000000
+
+/* the following variables are processor specific and initialized
+ * by the corresponding zylonite_pxa3xx_init()
+ */
+extern int gpio_backlight;
+extern int gpio_eth_irq;
+
+extern int lcd_id;
+extern int lcd_orientation;
+
+#ifdef CONFIG_CPU_PXA300
+extern void zylonite_pxa300_init(void);
+#else
+static inline void zylonite_pxa300_init(void)
+{
+ if (cpu_is_pxa300() || cpu_is_pxa310())
+ panic("%s: PXA300/PXA310 not supported\n", __FUNCTION__);
+}
+#endif
+
+#ifdef CONFIG_CPU_PXA320
+extern void zylonite_pxa320_init(void);
+#else
+static inline void zylonite_pxa320_init(void)
+{
+ if (cpu_is_pxa320())
+ panic("%s: PXA320 not supported\n", __FUNCTION__);
+}
+#endif
+
+#endif /* __ASM_ARCH_ZYLONITE_H */
diff --git a/include/asm-arm/arch-rpc/uncompress.h b/include/asm-arm/arch-rpc/uncompress.h
index 06231ede54e..b8e29efd8c5 100644
--- a/include/asm-arm/arch-rpc/uncompress.h
+++ b/include/asm-arm/arch-rpc/uncompress.h
@@ -11,9 +11,11 @@
#include <asm/hardware.h>
#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/page.h>
-int video_num_columns, video_num_lines, video_size_row;
-int white, bytes_per_char_h;
+int video_size_row;
+unsigned char bytes_per_char_h;
extern unsigned long con_charconvtable[256];
struct param_struct {
@@ -64,6 +66,13 @@ extern __attribute__((pure)) struct param_struct *params(void);
#define params (params())
#ifndef STANDALONE_DEBUG
+static unsigned long video_num_cols;
+static unsigned long video_num_rows;
+static unsigned long video_x;
+static unsigned long video_y;
+static unsigned char bytes_per_char_v;
+static int white;
+
/*
* This does not append a newline
*/
@@ -73,27 +82,27 @@ static void putc(int c)
int x,y;
char *ptr;
- x = params->video_x;
- y = params->video_y;
+ x = video_x;
+ y = video_y;
if (c == '\n') {
- if (++y >= video_num_lines)
+ if (++y >= video_num_rows)
y--;
} else if (c == '\r') {
x = 0;
} else {
- ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
+ ptr = VIDMEM + ((y*video_num_cols*bytes_per_char_v+x)*bytes_per_char_h);
ll_write_char(ptr, c, white);
- if (++x >= video_num_columns) {
+ if (++x >= video_num_cols) {
x = 0;
- if ( ++y >= video_num_lines ) {
+ if ( ++y >= video_num_rows ) {
y--;
}
}
}
- params->video_x = x;
- params->video_y = y;
+ video_x = x;
+ video_y = y;
}
static inline void flush(void)
@@ -108,11 +117,44 @@ static void error(char *x);
static void arch_decomp_setup(void)
{
int i;
+ struct tag *t = (struct tag *)params;
+ unsigned int nr_pages = 0, page_size = PAGE_SIZE;
+
+ if (t->hdr.tag == ATAG_CORE)
+ {
+ for (; t->hdr.size; t = tag_next(t))
+ {
+ if (t->hdr.tag == ATAG_VIDEOTEXT)
+ {
+ video_num_rows = t->u.videotext.video_lines;
+ video_num_cols = t->u.videotext.video_cols;
+ bytes_per_char_h = t->u.videotext.video_points;
+ bytes_per_char_v = t->u.videotext.video_points;
+ video_x = t->u.videotext.x;
+ video_y = t->u.videotext.y;
+ }
+
+ if (t->hdr.tag == ATAG_MEM)
+ {
+ page_size = PAGE_SIZE;
+ nr_pages += (t->u.mem.size / PAGE_SIZE);
+ }
+ }
+ }
+ else
+ {
+ nr_pages = params->nr_pages;
+ page_size = params->page_size;
+ video_num_rows = params->video_num_rows;
+ video_num_cols = params->video_num_cols;
+ video_x = params->video_x;
+ video_y = params->video_y;
+ bytes_per_char_h = params->bytes_per_char_h;
+ bytes_per_char_v = params->bytes_per_char_v;
+ }
+
+ video_size_row = video_num_cols * bytes_per_char_h;
- video_num_lines = params->video_num_rows;
- video_num_columns = params->video_num_cols;
- bytes_per_char_h = params->bytes_per_char_h;
- video_size_row = video_num_columns * bytes_per_char_h;
if (bytes_per_char_h == 4)
for (i = 0; i < 256; i++)
con_charconvtable[i] =
@@ -146,7 +188,7 @@ static void arch_decomp_setup(void)
white = 7;
}
- if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
+ if (nr_pages * page_size < 4096*1024) error("<4M of mem\n");
}
#endif
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
index 93a58e7862b..5d0262601a7 100644
--- a/include/asm-arm/arch-s3c2410/fb.h
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -14,12 +14,6 @@
#include <asm/arch/regs-lcd.h>
-struct s3c2410fb_val {
- unsigned int defval;
- unsigned int min;
- unsigned int max;
-};
-
struct s3c2410fb_hw {
unsigned long lcdcon1;
unsigned long lcdcon2;
@@ -28,23 +22,37 @@ struct s3c2410fb_hw {
unsigned long lcdcon5;
};
-struct s3c2410fb_mach_info {
- unsigned char fixed_syncs; /* do not update sync/border */
-
- /* LCD types */
- int type;
+/* LCD description */
+struct s3c2410fb_display {
+ /* LCD type */
+ unsigned type;
/* Screen size */
- int width;
- int height;
+ unsigned short width;
+ unsigned short height;
/* Screen info */
- struct s3c2410fb_val xres;
- struct s3c2410fb_val yres;
- struct s3c2410fb_val bpp;
+ unsigned short xres;
+ unsigned short yres;
+ unsigned short bpp;
+
+ unsigned pixclock; /* pixclock in picoseconds */
+ unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
+ unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
+ unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
+ unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
+ unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
+ unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
/* lcd configuration registers */
- struct s3c2410fb_hw regs;
+ unsigned long lcdcon5;
+};
+
+struct s3c2410fb_mach_info {
+
+ struct s3c2410fb_display *displays; /* attached diplays info */
+ unsigned num_displays; /* number of defined displays */
+ unsigned default_display;
/* GPIOs */
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
index 3b49cd1c345..996f65488d2 100644
--- a/include/asm-arm/arch-s3c2410/irqs.h
+++ b/include/asm-arm/arch-s3c2410/irqs.h
@@ -112,6 +112,13 @@
#define IRQ_TC S3C2410_IRQSUB(9)
#define IRQ_ADC S3C2410_IRQSUB(10)
+/* extra irqs for s3c2412 */
+
+#define IRQ_S3C2412_CFSDI S3C2410_IRQ(21)
+
+#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13)
+#define IRQ_S3C2412_CF S3C2410_IRQSUB(14)
+
/* extra irqs for s3c2440 */
#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index dea578b8f7f..b693158b2d3 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -1140,10 +1140,16 @@
/* definitions for each pin bit */
#define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2))
-#define S3C2412_SLPCON_HI(x) ( 0x01 << ((x) * 2))
+#define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2))
#define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2))
-#define S3C2412_SLPCON_PDWN(x) ( 0x03 << ((x) * 2))
+#define S3C2412_SLPCON_PULL(x) ( 0x03 << ((x) * 2))
+#define S3C2412_SLPCON_EINT(x) ( 0x02 << ((x) * 2)) /* only IRQ pins */
#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2))
+#define S3C2412_SLPCON_ALL_LOW (0x0)
+#define S3C2412_SLPCON_ALL_HIGH (0x11111111 | 0x44444444)
+#define S3C2412_SLPCON_ALL_IN (0x22222222 | 0x88888888)
+#define S3C2412_SLPCON_ALL_PULL (0x33333333)
+
#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-power.h b/include/asm-arm/arch-s3c2410/regs-power.h
index 94ff96505b6..f79987be55e 100644
--- a/include/asm-arm/arch-s3c2410/regs-power.h
+++ b/include/asm-arm/arch-s3c2410/regs-power.h
@@ -18,6 +18,11 @@
#define S3C2412_PWRMODECON S3C24XX_PWRREG(0x20)
#define S3C2412_PWRCFG S3C24XX_PWRREG(0x24)
+#define S3C2412_INFORM0 S3C24XX_PWRREG(0x70)
+#define S3C2412_INFORM1 S3C24XX_PWRREG(0x74)
+#define S3C2412_INFORM2 S3C24XX_PWRREG(0x78)
+#define S3C2412_INFORM3 S3C24XX_PWRREG(0x7C)
+
#define S3C2412_PWRCFG_BATF_IGNORE (0<<0)
#define S3C2412_PWRCFG_BATF_SLEEP (3<<0)
#define S3C2412_PWRCFG_BATF_MASK (3<<0)
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2412.h b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
index 8ca6a3bc855..783b18f5bce 100644
--- a/include/asm-arm/arch-s3c2410/regs-s3c2412.h
+++ b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
@@ -17,5 +17,7 @@
#define S3C2412_SWRST (S3C24XX_VA_CLKPWR + 0x30)
#define S3C2412_SWRST_RESET (0x533C2412)
+/* see regs-power.h for the other registers in the power block. */
+
#endif /* __ASM_ARCH_REGS_S3C2412_H */
diff --git a/include/asm-arm/arch-sa1100/SA-1101.h b/include/asm-arm/arch-sa1100/SA-1101.h
index 527d887f1ee..65ca8c79e6d 100644
--- a/include/asm-arm/arch-sa1100/SA-1101.h
+++ b/include/asm-arm/arch-sa1100/SA-1101.h
@@ -106,7 +106,7 @@
#define SMCR_ColAdrBits( x ) /* col. addr bits 8..11 */ \
(( (x) - 8 ) << FShft (SMCR_DCAC))
#define SMCR_RowAdrBits( x ) /* row addr bits 9..12 */\
- (( (x) - 9 ) << FShft (SMCR_DRAC)
+ (( (x) - 9 ) << FShft (SMCR_DRAC))
#define SNPR_VFBstart Fld(12,0) /* Video frame buffer addr */
#define SNPR_VFBsize Fld(11,12) /* Video frame buffer size */
@@ -394,7 +394,7 @@
#define VgaStatus (*((volatile Word *) SA1101_p2v (_VgaStatus)))
#define VgaInterruptMask (*((volatile Word *) SA1101_p2v (_VgaInterruptMask)))
#define VgaPalette (*((volatile Word *) SA1101_p2v (_VgaPalette)))
-#define DacControl (*((volatile Word *) SA1101_p2v (_DacControl))
+#define DacControl (*((volatile Word *) SA1101_p2v (_DacControl)))
#define VgaTest (*((volatile Word *) SA1101_p2v (_VgaTest)))
#define VideoControl_VgaEn 0x00000000
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index b41831b6432..52fe05895de 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -286,6 +286,7 @@ static inline int constant_fls(int x)
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
/*
* Ext2 is defined to use little-endian byte ordering.
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index c8b5d0db0cf..678134bf247 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -17,7 +17,7 @@
* platforms with CONFIG_DMABOUNCE.
* Use the driver DMA support - see dma-mapping.h (dma_sync_*)
*/
-extern void consistent_sync(const void *kaddr, size_t size, int rw);
+extern void dma_cache_maint(const void *kaddr, size_t size, int rw);
/*
* Return whether the given device DMA address mask can be supported
@@ -165,7 +165,7 @@ dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction dir)
{
if (!arch_is_coherent())
- consistent_sync(cpu_addr, size, dir);
+ dma_cache_maint(cpu_addr, size, dir);
return virt_to_dma(dev, (unsigned long)cpu_addr);
}
@@ -278,7 +278,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
virt = page_address(sg->page) + sg->offset;
if (!arch_is_coherent())
- consistent_sync(virt, sg->length, dir);
+ dma_cache_maint(virt, sg->length, dir);
}
return nents;
@@ -334,7 +334,7 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
if (!arch_is_coherent())
- consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
+ dma_cache_maint((void *)dma_to_virt(dev, handle), size, dir);
}
static inline void
@@ -342,7 +342,7 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
if (!arch_is_coherent())
- consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
+ dma_cache_maint((void *)dma_to_virt(dev, handle), size, dir);
}
#else
extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction);
@@ -373,7 +373,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
for (i = 0; i < nents; i++, sg++) {
char *virt = page_address(sg->page) + sg->offset;
if (!arch_is_coherent())
- consistent_sync(virt, sg->length, dir);
+ dma_cache_maint(virt, sg->length, dir);
}
}
@@ -386,7 +386,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
for (i = 0; i < nents; i++, sg++) {
char *virt = page_address(sg->page) + sg->offset;
if (!arch_is_coherent())
- consistent_sync(virt, sg->length, dir);
+ dma_cache_maint(virt, sg->length, dir);
}
}
#else
diff --git a/include/asm-arm/floppy.h b/include/asm-arm/floppy.h
index d595c15166a..41a5e9d6bb6 100644
--- a/include/asm-arm/floppy.h
+++ b/include/asm-arm/floppy.h
@@ -128,8 +128,6 @@ static inline void fd_scandrives (void)
#define N_FDC 1
#define N_DRIVE 4
-#define FLOPPY_MOTOR_MASK 0xf0
-
#define CROSS_64KB(a,s) (0)
/*
diff --git a/include/asm-arm/hardware/it8152.h b/include/asm-arm/hardware/it8152.h
new file mode 100644
index 00000000000..aaebb61aca4
--- /dev/null
+++ b/include/asm-arm/hardware/it8152.h
@@ -0,0 +1,99 @@
+/*
+ * linux/include/arm/hardware/it8152.h
+ *
+ * Copyright Compulab Ltd., 2006,2007
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * ITE 8152 companion chip register definitions
+ */
+
+#ifndef __ASM_HARDWARE_IT8152_H
+#define __ASM_HARDWARE_IT8152_H
+extern unsigned long it8152_base_address;
+
+#define IT8152_IO_BASE (it8152_base_address + 0x03e00000)
+#define IT8152_CFGREG_BASE (it8152_base_address + 0x03f00000)
+
+#define __REG_IT8152(x) (it8152_base_address + (x))
+
+#define IT8152_PCI_CFG_ADDR __REG_IT8152(0x3f00800)
+#define IT8152_PCI_CFG_DATA __REG_IT8152(0x3f00804)
+
+#define IT8152_INTC_LDCNIRR __REG_IT8152(0x3f00300)
+#define IT8152_INTC_LDPNIRR __REG_IT8152(0x3f00304)
+#define IT8152_INTC_LDCNIMR __REG_IT8152(0x3f00308)
+#define IT8152_INTC_LDPNIMR __REG_IT8152(0x3f0030C)
+#define IT8152_INTC_LDNITR __REG_IT8152(0x3f00310)
+#define IT8152_INTC_LDNIAR __REG_IT8152(0x3f00314)
+#define IT8152_INTC_LPCNIRR __REG_IT8152(0x3f00320)
+#define IT8152_INTC_LPPNIRR __REG_IT8152(0x3f00324)
+#define IT8152_INTC_LPCNIMR __REG_IT8152(0x3f00328)
+#define IT8152_INTC_LPPNIMR __REG_IT8152(0x3f0032C)
+#define IT8152_INTC_LPNITR __REG_IT8152(0x3f00330)
+#define IT8152_INTC_LPNIAR __REG_IT8152(0x3f00334)
+#define IT8152_INTC_PDCNIRR __REG_IT8152(0x3f00340)
+#define IT8152_INTC_PDPNIRR __REG_IT8152(0x3f00344)
+#define IT8152_INTC_PDCNIMR __REG_IT8152(0x3f00348)
+#define IT8152_INTC_PDPNIMR __REG_IT8152(0x3f0034C)
+#define IT8152_INTC_PDNITR __REG_IT8152(0x3f00350)
+#define IT8152_INTC_PDNIAR __REG_IT8152(0x3f00354)
+#define IT8152_INTC_INTC_TYPER __REG_IT8152(0x3f003FC)
+
+#define IT8152_GPIO_GPDR __REG_IT8152(0x3f00500)
+
+/*
+ Interrup contoler per register summary:
+ ---------------------------------------
+ LCDNIRR:
+ IT8152_LD_IRQ(8) PCICLK stop
+ IT8152_LD_IRQ(7) MCLK ready
+ IT8152_LD_IRQ(6) s/w
+ IT8152_LD_IRQ(5) UART
+ IT8152_LD_IRQ(4) GPIO
+ IT8152_LD_IRQ(3) TIMER 4
+ IT8152_LD_IRQ(2) TIMER 3
+ IT8152_LD_IRQ(1) TIMER 2
+ IT8152_LD_IRQ(0) TIMER 1
+
+ LPCNIRR:
+ IT8152_LP_IRQ(x) serial IRQ x
+
+ PCIDNIRR:
+ IT8152_PD_IRQ(14) PCISERR
+ IT8152_PD_IRQ(13) CPU/PCI bridge target abort (h2pTADR)
+ IT8152_PD_IRQ(12) CPU/PCI bridge master abort (h2pMADR)
+ IT8152_PD_IRQ(11) PCI INTD
+ IT8152_PD_IRQ(10) PCI INTC
+ IT8152_PD_IRQ(9) PCI INTB
+ IT8152_PD_IRQ(8) PCI INTA
+ IT8152_PD_IRQ(7) serial INTD
+ IT8152_PD_IRQ(6) serial INTC
+ IT8152_PD_IRQ(5) serial INTB
+ IT8152_PD_IRQ(4) serial INTA
+ IT8152_PD_IRQ(3) serial IRQ IOCHK (IOCHKR)
+ IT8152_PD_IRQ(2) chaining DMA (CDMAR)
+ IT8152_PD_IRQ(1) USB (USBR)
+ IT8152_PD_IRQ(0) Audio controller (ACR)
+ */
+/* frequently used interrupts */
+#define IT8152_PCISERR IT8152_PD_IRQ(14)
+#define IT8152_H2PTADR IT8152_PD_IRQ(13)
+#define IT8152_H2PMAR IT8152_PD_IRQ(12)
+#define IT8152_PCI_INTD IT8152_PD_IRQ(11)
+#define IT8152_PCI_INTC IT8152_PD_IRQ(10)
+#define IT8152_PCI_INTB IT8152_PD_IRQ(9)
+#define IT8152_PCI_INTA IT8152_PD_IRQ(8)
+#define IT8152_CDMA_INT IT8152_PD_IRQ(2)
+#define IT8152_USB_INT IT8152_PD_IRQ(1)
+#define IT8152_AUDIO_INT IT8152_PD_IRQ(0)
+
+struct pci_dev;
+struct pci_sys_data;
+
+extern void it8152_irq_demux(unsigned int irq, struct irq_desc *desc);
+extern void it8152_init_irq(void);
+extern int it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
+extern int it8152_pci_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_bus *it8152_pci_scan_bus(int nr, struct pci_sys_data *sys);
+
+#endif /* __ASM_HARDWARE_IT8152_H */
diff --git a/include/asm-arm/ipc.h b/include/asm-arm/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-arm/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index b5b030ef633..46dcc4d0b9b 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -14,6 +14,8 @@
#define KEXEC_ARCH KEXEC_ARCH_ARM
+#define KEXEC_BOOT_PARAMS_SIZE 1536
+
#ifndef __ASSEMBLY__
struct kimage;
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index ed3f898191f..75feb1574a6 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -8,10 +8,17 @@
#define pcibios_scan_all_fns(a, b) 0
+#ifdef CONFIG_PCI_HOST_ITE8152
+/* ITE bridge requires setting latency timer to avoid early bus access
+ termination by PIC bus mater devices
+*/
+extern void pcibios_set_master(struct pci_dev *dev);
+#else
static inline void pcibios_set_master(struct pci_dev *dev)
{
/* No special bus mastering setup handling */
}
+#endif
static inline void pcibios_penalize_isa_irq(int irq, int active)
{
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h
index d5dc624f452..1c8b441f89e 100644
--- a/include/asm-arm/semaphore.h
+++ b/include/asm-arm/semaphore.h
@@ -28,7 +28,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INIT(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init(struct semaphore *sem, int val)
{
diff --git a/include/asm-arm/types.h b/include/asm-arm/types.h
index 22992ee0627..3141451a9bd 100644
--- a/include/asm-arm/types.h
+++ b/include/asm-arm/types.h
@@ -19,9 +19,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index d327b25c986..88e868b7aae 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -378,6 +378,7 @@
#define __NR_signalfd (__NR_SYSCALL_BASE+349)
#define __NR_timerfd (__NR_SYSCALL_BASE+350)
#define __NR_eventfd (__NR_SYSCALL_BASE+351)
+#define __NR_fallocate (__NR_SYSCALL_BASE+352)
/*
* The following SWIs are ARM private.
diff --git a/include/asm-arm26/irq_regs.h b/include/asm-arm26/irq_regs.h
new file mode 100644
index 00000000000..3dd9c0b7027
--- /dev/null
+++ b/include/asm-arm26/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-avr32/bitops.h b/include/asm-avr32/bitops.h
index 5299f8c8e11..f3faddfd46a 100644
--- a/include/asm-avr32/bitops.h
+++ b/include/asm-avr32/bitops.h
@@ -288,6 +288,7 @@ static inline int ffs(unsigned long word)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h
index 64bb92bb677..8be7ea9c904 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -298,13 +298,6 @@ extern void __iounmap(void __iomem *addr);
#define ioport_map(port, nr) ioremap(port, nr)
#define ioport_unmap(port) iounmap(port)
-#define dma_cache_wback_inv(_start, _size) \
- flush_dcache_region(_start, _size)
-#define dma_cache_inv(_start, _size) \
- invalidate_dcache_region(_start, _size)
-#define dma_cache_wback(_start, _size) \
- clean_dcache_region(_start, _size)
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h
index 7f54e2b15d1..fd7e99046b2 100644
--- a/include/asm-avr32/kdebug.h
+++ b/include/asm-avr32/kdebug.h
@@ -1,26 +1,10 @@
#ifndef __ASM_AVR32_KDEBUG_H
#define __ASM_AVR32_KDEBUG_H
-#include <linux/notifier.h>
-
/* Grossly misnamed. */
enum die_val {
DIE_BREAKPOINT,
DIE_SSTEP,
};
-/*
- * These are only here because kprobes.c wants them to implement a
- * blatant layering violation. Will hopefully go away soon once all
- * architectures are updated.
- */
-static inline int register_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-static inline int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-
#endif /* __ASM_AVR32_KDEBUG_H */
diff --git a/include/asm-avr32/kprobes.h b/include/asm-avr32/kprobes.h
index 190a6377c80..996cb656474 100644
--- a/include/asm-avr32/kprobes.h
+++ b/include/asm-avr32/kprobes.h
@@ -17,7 +17,7 @@ typedef u16 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */
#define MAX_INSN_SIZE 2
-#define ARCH_INACTIVE_KPROBE_COUNT 1
+#define kretprobe_blacklist_size 0
#define arch_remove_kprobe(p) do { } while (0)
diff --git a/include/asm-avr32/semaphore.h b/include/asm-avr32/semaphore.h
index ef99ddccc10..feaf1d45338 100644
--- a/include/asm-avr32/semaphore.h
+++ b/include/asm-avr32/semaphore.h
@@ -36,7 +36,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-avr32/types.h b/include/asm-avr32/types.h
index 2bff153a32e..8999a381940 100644
--- a/include/asm-avr32/types.h
+++ b/include/asm-avr32/types.h
@@ -25,9 +25,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h
index 27c2d0e48e1..03ecedc1f2a 100644
--- a/include/asm-blackfin/bitops.h
+++ b/include/asm-blackfin/bitops.h
@@ -199,6 +199,7 @@ static __inline__ int __test_bit(int nr, const void *addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-atomic.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h
index 525179bf43d..d1d2e6be3b5 100644
--- a/include/asm-blackfin/io.h
+++ b/include/asm-blackfin/io.h
@@ -183,10 +183,6 @@ extern void blkfin_inv_cache_all(void);
#define ioport_map(port, nr) ((void __iomem*)(port))
#define ioport_unmap(addr)
-#define dma_cache_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
-
/* Pages to physical address... */
#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT)
diff --git a/include/asm-blackfin/ipc.h b/include/asm-blackfin/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-blackfin/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-blackfin/mach-bf548/bf54x-lq043.h b/include/asm-blackfin/mach-bf548/bf54x-lq043.h
new file mode 100644
index 00000000000..9c7ca62a45e
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/bf54x-lq043.h
@@ -0,0 +1,30 @@
+#ifndef BF54X_LQ043_H
+#define BF54X_LQ043_H
+
+struct bfin_bf54xfb_val {
+ unsigned int defval;
+ unsigned int min;
+ unsigned int max;
+};
+
+struct bfin_bf54xfb_mach_info {
+ unsigned char fixed_syncs; /* do not update sync/border */
+
+ /* LCD types */
+ int type;
+
+ /* Screen size */
+ int width;
+ int height;
+
+ /* Screen info */
+ struct bfin_bf54xfb_val xres;
+ struct bfin_bf54xfb_val yres;
+ struct bfin_bf54xfb_val bpp;
+
+ /* GPIOs */
+ unsigned short disp;
+
+};
+
+#endif /* BF54X_LQ043_H */
diff --git a/include/asm-blackfin/mach-bf548/bf54x_keys.h b/include/asm-blackfin/mach-bf548/bf54x_keys.h
new file mode 100644
index 00000000000..1fb4ec77cc2
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/bf54x_keys.h
@@ -0,0 +1,17 @@
+#ifndef _BFIN_KPAD_H
+#define _BFIN_KPAD_H
+
+struct bfin_kpad_platform_data {
+ int rows;
+ int cols;
+ const unsigned int *keymap;
+ unsigned short keymapsize;
+ unsigned short repeat;
+ u32 debounce_time; /* in ns */
+ u32 coldrive_time; /* in ns */
+ u32 keyup_test_interval; /* in ms */
+};
+
+#define KEYVAL(col, row, val) (((1 << col) << 24) | ((1 << row) << 16) | (val))
+
+#endif
diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h
index 6bb3e0d4705..c571e958558 100644
--- a/include/asm-blackfin/processor.h
+++ b/include/asm-blackfin/processor.h
@@ -104,13 +104,13 @@ unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
/* Get the Silicon Revision of the chip */
-static inline __attribute_pure__ uint32_t bfin_revid(void)
+static inline uint32_t __pure bfin_revid(void)
{
/* stored in the upper 4 bits */
return bfin_read_CHIPID() >> 28;
}
-static inline __attribute_pure__ uint32_t bfin_compiled_revid(void)
+static inline uint32_t __pure bfin_compiled_revid(void)
{
#if defined(CONFIG_BF_REV_0_0)
return 0;
diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h
index 94c04d7ab23..533f90fb2e4 100644
--- a/include/asm-blackfin/semaphore.h
+++ b/include/asm-blackfin/semaphore.h
@@ -35,7 +35,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init(struct semaphore *sem, int val)
{
diff --git a/include/asm-blackfin/types.h b/include/asm-blackfin/types.h
index 36f8dc8c52b..9785a6d531c 100644
--- a/include/asm-blackfin/types.h
+++ b/include/asm-blackfin/types.h
@@ -27,9 +27,9 @@ typedef __signed__ int __s32;
typedef unsigned int __u32;
/* HK0617 -- Changes to unsigned long temporarily */
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index a569065113d..617151b9b72 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -154,6 +154,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
diff --git a/include/asm-cris/ipc.h b/include/asm-cris/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-cris/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-cris/irq_regs.h b/include/asm-cris/irq_regs.h
new file mode 100644
index 00000000000..3dd9c0b7027
--- /dev/null
+++ b/include/asm-cris/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
index 53f548b791c..31a4ac44819 100644
--- a/include/asm-cris/semaphore.h
+++ b/include/asm-cris/semaphore.h
@@ -35,7 +35,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init(struct semaphore *sem, int val)
{
diff --git a/include/asm-cris/types.h b/include/asm-cris/types.h
index 84557c9bac9..5a21c42bc6c 100644
--- a/include/asm-cris/types.h
+++ b/include/asm-cris/types.h
@@ -19,9 +19,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index f8560edf59f..8dba74b1a25 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -302,6 +302,7 @@ int __ilog2_u64(u64 n)
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
diff --git a/include/asm-frv/ipc.h b/include/asm-frv/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-frv/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
index 09586528e00..d7aaa1911a1 100644
--- a/include/asm-frv/semaphore.h
+++ b/include/asm-frv/semaphore.h
@@ -49,7 +49,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index cc5433e78b5..348b8f1df17 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -88,9 +88,8 @@ register struct thread_info *__current_thread_info asm("gr15");
({ \
struct thread_info *ret; \
\
- ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \
- if (ret) \
- memset(ret, 0, THREAD_SIZE); \
+ ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \
+ \
ret; \
})
#else
diff --git a/include/asm-frv/tlbflush.h b/include/asm-frv/tlbflush.h
index da3a3179a85..8370f97e41e 100644
--- a/include/asm-frv/tlbflush.h
+++ b/include/asm-frv/tlbflush.h
@@ -57,8 +57,7 @@ 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) \
- asm volatile("movgs %0,scr0 ! movgs %0,scr1" :: "r"(ULONG_MAX) : "memory");
+#define flush_tlb_pgtables(mm,start,end) do { } while(0)
#else
diff --git a/include/asm-frv/types.h b/include/asm-frv/types.h
index 1b6d1923b25..767e5ed71c4 100644
--- a/include/asm-frv/types.h
+++ b/include/asm-frv/types.h
@@ -30,9 +30,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 5bfeef76164..c18110ee30f 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -2,7 +2,6 @@ header-y += errno-base.h
header-y += errno.h
header-y += fcntl.h
header-y += ioctl.h
-header-y += ipc.h
header-y += mman.h
header-y += poll.h
header-y += signal.h
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index a37e95fe58d..8fd81713cfc 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -30,6 +30,5 @@ unifdef-y += unistd.h
unifdef-y += user.h
# These probably shouldn't be exported
-unifdef-y += shmparam.h
unifdef-y += elf.h
unifdef-y += page.h
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index 1f9d99193df..e022a0f59e6 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -22,6 +22,7 @@
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-generic/bitops/lock.h b/include/asm-generic/bitops/lock.h
new file mode 100644
index 00000000000..308a9e22c80
--- /dev/null
+++ b/include/asm-generic/bitops/lock.h
@@ -0,0 +1,45 @@
+#ifndef _ASM_GENERIC_BITOPS_LOCK_H_
+#define _ASM_GENERIC_BITOPS_LOCK_H_
+
+/**
+ * test_and_set_bit_lock - Set a bit and return its old value, for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and provides acquire barrier semantics.
+ * It can be used to implement bit locks.
+ */
+#define test_and_set_bit_lock(nr, addr) test_and_set_bit(nr, addr)
+
+/**
+ * clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is atomic and provides release barrier semantics.
+ */
+#define clear_bit_unlock(nr, addr) \
+do { \
+ smp_mb__before_clear_bit(); \
+ clear_bit(nr, addr); \
+} while (0)
+
+/**
+ * __clear_bit_unlock - Clear a bit in memory, for unlock
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This operation is like clear_bit_unlock, however it is not atomic.
+ * It does provide release barrier semantics so it can be used to unlock
+ * a bit lock, however it would only be used if no other CPU can modify
+ * any bits in the memory until the lock is released (a good example is
+ * if the bit lock itself protects access to the other bits in the word).
+ */
+#define __clear_bit_unlock(nr, addr) \
+do { \
+ smp_mb(); \
+ __clear_bit(nr, addr); \
+} while (0)
+
+#endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */
+
diff --git a/include/asm-generic/ipc.h b/include/asm-generic/ipc.h
deleted file mode 100644
index a40407a165c..00000000000
--- a/include/asm-generic/ipc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _ASM_GENERIC_IPC_H
-#define _ASM_GENERIC_IPC_H
-/*
- * These are used to wrap system calls.
- *
- * See architecture code for ugly details..
- */
-struct ipc_kludge {
- struct msgbuf __user *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define SEMTIMEDOP 4
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-/* Used by the DIPC package, try and avoid reusing it */
-#define DIPC 25
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* _ASM_GENERIC_IPC_H */
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
index 30d8d33491d..52226e14bd7 100644
--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -46,6 +46,12 @@
__pgdat->node_start_pfn; \
})
+#elif defined(CONFIG_SPARSEMEM_VMEMMAP)
+
+/* memmap is virtually contigious. */
+#define __pfn_to_page(pfn) (vmemmap + (pfn))
+#define __page_to_pfn(page) ((page) - vmemmap)
+
#elif defined(CONFIG_SPARSEMEM)
/*
* Note: section's mem_map is encorded to reflect its start_pfn.
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 5f0d797d33f..44ef329531c 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -125,10 +125,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
#define pgd_offset_gate(mm, addr) pgd_offset(mm, addr)
#endif
-#ifndef __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
-#define lazy_mmu_prot_update(pte) do { } while (0)
-#endif
-
#ifndef __HAVE_ARCH_MOVE_PTE
#define move_pte(pte, prot, old_addr, new_addr) (pte)
#endif
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index d76299c98b8..e64ad315656 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -194,6 +194,7 @@ static __inline__ unsigned long __ffs(unsigned long word)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
#include <asm-generic/bitops/minix.h>
diff --git a/include/asm-h8300/io.h b/include/asm-h8300/io.h
index 91b7487cb7a..7543a57b4ea 100644
--- a/include/asm-h8300/io.h
+++ b/include/asm-h8300/io.h
@@ -264,12 +264,6 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size
extern void iounmap(void *addr);
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
/* H8/300 internal I/O functions */
static __inline__ unsigned char ctrl_inb(unsigned long addr)
{
diff --git a/include/asm-h8300/ipc.h b/include/asm-h8300/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-h8300/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-h8300/semaphore.h b/include/asm-h8300/semaphore.h
index 81bae2a9919..f3ffff83ff0 100644
--- a/include/asm-h8300/semaphore.h
+++ b/include/asm-h8300/semaphore.h
@@ -39,7 +39,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-h8300/types.h b/include/asm-h8300/types.h
index 2a8b1b2be78..56566e2a09f 100644
--- a/include/asm-h8300/types.h
+++ b/include/asm-h8300/types.h
@@ -27,9 +27,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
/*
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
index 6cc517e212a..2144f1a8ed6 100644
--- a/include/asm-ia64/bitops.h
+++ b/include/asm-ia64/bitops.h
@@ -94,6 +94,38 @@ clear_bit (int nr, volatile void *addr)
}
/**
+ * clear_bit_unlock - Clears a bit in memory with release
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit_unlock() is atomic and may not be reordered. It does
+ * contain a memory barrier suitable for unlock type operations.
+ */
+static __inline__ void
+clear_bit_unlock (int nr, volatile void *addr)
+{
+ __u32 mask, old, new;
+ volatile __u32 *m;
+ CMPXCHG_BUGCHECK_DECL
+
+ m = (volatile __u32 *) addr + (nr >> 5);
+ mask = ~(1 << (nr & 31));
+ do {
+ CMPXCHG_BUGCHECK(m);
+ old = *m;
+ new = old & mask;
+ } while (cmpxchg_rel(m, old, new) != old);
+}
+
+/**
+ * __clear_bit_unlock - Non-atomically clear a bit with release
+ *
+ * This is like clear_bit_unlock, but the implementation may use a non-atomic
+ * store (this one uses an atomic, however).
+ */
+#define __clear_bit_unlock clear_bit_unlock
+
+/**
* __clear_bit - Clears a bit in memory (non-atomic version)
*/
static __inline__ void
@@ -170,6 +202,15 @@ test_and_set_bit (int nr, volatile void *addr)
}
/**
+ * test_and_set_bit_lock - Set a bit and return its old value for lock
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This is the same as test_and_set_bit on ia64
+ */
+#define test_and_set_bit_lock test_and_set_bit
+
+/**
* __test_and_set_bit - Set a bit and return its old value
* @nr: Bit to set
* @addr: Address to count from
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index 6299b51575b..f1735a22d0e 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -6,6 +6,7 @@
* David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <asm/machvec.h>
+#include <linux/scatterlist.h>
#define dma_alloc_coherent platform_dma_alloc_coherent
/* coherent mem. is cheap */
diff --git a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
index 25f9835d545..f10e29b60b0 100644
--- a/include/asm-ia64/elf.h
+++ b/include/asm-ia64/elf.h
@@ -192,6 +192,7 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
#define GATE_EHDR ((const struct elfhdr *) GATE_ADDR)
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \
do { \
extern char __kernel_syscall_via_epc[]; \
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index eb17a869296..4ebed77aa47 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -435,10 +435,6 @@ extern void memcpy_fromio(void *dst, const volatile void __iomem *src, long n);
extern void memcpy_toio(volatile void __iomem *dst, const void *src, long n);
extern void memset_io(volatile void __iomem *s, int c, long n);
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
# endif /* __KERNEL__ */
/*
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index 320cd8e754e..35e49407d06 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -26,21 +26,6 @@
* 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more
* events.
*/
-#include <linux/notifier.h>
-
-/*
- * These are only here because kprobes.c wants them to implement a
- * blatant layering violation. Will hopefully go away soon once all
- * architectures are updated.
- */
-static inline int register_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-static inline int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
enum die_val {
DIE_BREAK = 1,
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index 067d9dea68f..a93ce9ef07f 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -83,7 +83,7 @@ struct kprobe_ctlblk {
};
#define ARCH_SUPPORTS_KRETPROBES
-#define ARCH_INACTIVE_KPROBE_COUNT 1
+#define kretprobe_blacklist_size 0
#define SLOT0_OPCODE_SHIFT (37)
#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46))
diff --git a/include/asm-ia64/numa.h b/include/asm-ia64/numa.h
index 7d5e2ccc37a..6a8a27cfae3 100644
--- a/include/asm-ia64/numa.h
+++ b/include/asm-ia64/numa.h
@@ -24,6 +24,7 @@
extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+extern pg_data_t *pgdat_list[MAX_NUMNODES];
/* Stuff below this line could be architecture independent */
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index de6d01e24dd..0971ec90807 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -223,12 +223,6 @@ ia64_phys_addr_valid (unsigned long addr)
* page table.
*/
-/*
- * On some architectures, special things need to be done when setting
- * the PTE in a page table. Nothing special needs to be on IA-64.
- */
-#define set_pte(ptep, pteval) (*(ptep) = (pteval))
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL)
#ifdef CONFIG_VIRTUAL_MEM_MAP
@@ -236,8 +230,14 @@ ia64_phys_addr_valid (unsigned long addr)
# define VMALLOC_END vmalloc_end
extern unsigned long vmalloc_end;
#else
+#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_SPARSEMEM_VMEMMAP)
+/* SPARSEMEM_VMEMMAP uses half of vmalloc... */
+# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 10)))
+# define vmemmap ((struct page *)VMALLOC_END)
+#else
# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9)))
#endif
+#endif
/* fs/proc/kcore.c */
#define kc_vaddr_to_offset(v) ((v) - RGN_BASE(RGN_GATE))
@@ -315,6 +315,36 @@ ia64_phys_addr_valid (unsigned long addr)
#define pte_mkhuge(pte) (__pte(pte_val(pte)))
/*
+ * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to
+ * sync icache and dcache when we insert *new* executable page.
+ * __ia64_sync_icache_dcache() check Pg_arch_1 bit and flush icache
+ * if necessary.
+ *
+ * set_pte() is also called by the kernel, but we can expect that the kernel
+ * flushes icache explicitly if necessary.
+ */
+#define pte_present_exec_user(pte)\
+ ((pte_val(pte) & (_PAGE_P | _PAGE_PL_MASK | _PAGE_AR_RX)) == \
+ (_PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX))
+
+extern void __ia64_sync_icache_dcache(pte_t pteval);
+static inline void set_pte(pte_t *ptep, pte_t pteval)
+{
+ /* page is present && page is user && page is executable
+ * && (page swapin or new page or page migraton
+ * || copy_on_write with page copying.)
+ */
+ if (pte_present_exec_user(pteval) &&
+ (!pte_present(*ptep) ||
+ pte_pfn(*ptep) != pte_pfn(pteval)))
+ /* load_module() calles flush_icache_range() explicitly*/
+ __ia64_sync_icache_dcache(pteval);
+ *ptep = pteval;
+}
+
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+/*
* Make page protection values cacheable, uncacheable, or write-
* combining. Note that "protection" is really a misnomer here as the
* protection value contains the memory attribute bits, dirty bits, and
@@ -483,12 +513,6 @@ extern struct page *zero_page_memmap_ptr;
#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1))
#endif
-/*
- * IA-64 doesn't have any external MMU info: the page tables contain all the necessary
- * information. However, we use this routine to take care of any (delayed) i-cache
- * flushing that may be necessary.
- */
-extern void lazy_mmu_prot_update (pte_t pte);
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
/*
@@ -578,7 +602,7 @@ extern void lazy_mmu_prot_update (pte_t pte);
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
#define __HAVE_ARCH_PTE_SAME
#define __HAVE_ARCH_PGD_OFFSET_GATE
-#define __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
+
#ifndef CONFIG_PGTABLE_4
#include <asm-generic/pgtable-nopud.h>
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index a452ea24205..7d5234d5031 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -30,4 +30,6 @@ struct scatterlist {
#define sg_dma_len(sg) ((sg)->dma_length)
#define sg_dma_address(sg) ((sg)->dma_address)
+#define ARCH_HAS_SG_CHAIN
+
#endif /* _ASM_IA64_SCATTERLIST_H */
diff --git a/include/asm-ia64/semaphore.h b/include/asm-ia64/semaphore.h
index f483eeb95dd..d8393d11288 100644
--- a/include/asm-ia64/semaphore.h
+++ b/include/asm-ia64/semaphore.h
@@ -28,7 +28,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
static inline void
sema_init (struct semaphore *sem, int val)
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index 6314b29e8c4..1703c9d885b 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -58,7 +58,7 @@ extern char no_int_routing __devinitdata;
extern cpumask_t cpu_online_map;
extern cpumask_t cpu_core_map[NR_CPUS];
-extern cpumask_t cpu_sibling_map[NR_CPUS];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
extern int smp_num_siblings;
extern int smp_num_cpucores;
extern void __iomem *ipi_base_addr;
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
index 91bb8e00066..595112bca3c 100644
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -32,6 +32,8 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
+
struct pci_vector_struct {
__u16 segment; /* PCI Segment number */
__u16 bus; /* PCI Bus number */
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index 233f1caae04..2d67b72b18d 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -112,7 +112,7 @@ void build_cpu_to_node_map(void);
#define topology_physical_package_id(cpu) (cpu_data(cpu)->socket_id)
#define topology_core_id(cpu) (cpu_data(cpu)->core_id)
#define topology_core_siblings(cpu) (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#define smt_capable() (smp_num_siblings > 1)
#endif
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
index 66ab672162c..313a02c4a88 100644
--- a/include/asm-m32r/bitops.h
+++ b/include/asm-m32r/bitops.h
@@ -255,6 +255,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */
diff --git a/include/asm-m32r/ipc.h b/include/asm-m32r/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-m32r/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h
index 632b4ce4269..a0755b98202 100644
--- a/include/asm-m32r/ptrace.h
+++ b/include/asm-m32r/ptrace.h
@@ -120,7 +120,10 @@ struct pt_regs {
#include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */
-#define __ARCH_SYS_PTRACE 1
+struct task_struct;
+extern void init_debug_traps(struct task_struct *);
+#define arch_ptrace_attach(child) \
+ init_debug_traps(child)
#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h
index 41e45d7b87e..b5bf95a6f2b 100644
--- a/include/asm-m32r/semaphore.h
+++ b/include/asm-m32r/semaphore.h
@@ -35,7 +35,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index b7ccc3e6860..c039820dba7 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -100,9 +100,8 @@ static inline struct thread_info *current_thread_info(void)
({ \
struct thread_info *ret; \
\
- ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \
- if (ret) \
- memset(ret, 0, THREAD_SIZE); \
+ ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \
+ \
ret; \
})
#else
diff --git a/include/asm-m32r/types.h b/include/asm-m32r/types.h
index 27d3eb539c5..b64c16639a7 100644
--- a/include/asm-m32r/types.h
+++ b/include/asm-m32r/types.h
@@ -19,9 +19,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index 1a61fdb56aa..da151f70cdc 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -314,6 +314,7 @@ static inline int fls(int x)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
/* Bitmap functions for the minix filesystem */
diff --git a/include/asm-m68k/floppy.h b/include/asm-m68k/floppy.h
index 45dc908932a..697d50393dd 100644
--- a/include/asm-m68k/floppy.h
+++ b/include/asm-m68k/floppy.h
@@ -31,9 +31,6 @@ asmlinkage irqreturn_t floppy_hardint(int irq, void *dev_id);
#define FLOPPY0_TYPE (MACH_IS_Q40 ? 6 : 4)
#define FLOPPY1_TYPE 0
-#define FLOPPY_MOTOR_MASK 0xf0
-
-
/* basically PC init + set use_virtual_dma */
#define FDC1 m68k_floppy_init()
diff --git a/include/asm-m68k/io.h b/include/asm-m68k/io.h
index 47bb9cf107b..baf4f9b8acf 100644
--- a/include/asm-m68k/io.h
+++ b/include/asm-m68k/io.h
@@ -384,12 +384,6 @@ static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
}
-
-/* m68k caches aren't DMA coherent */
-extern void dma_cache_wback_inv(unsigned long start, unsigned long size);
-extern void dma_cache_wback(unsigned long start, unsigned long size);
-extern void dma_cache_inv(unsigned long start, unsigned long size);
-
static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
{
__builtin_memset((void __force *) addr, val, count);
diff --git a/include/asm-m68k/ipc.h b/include/asm-m68k/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-m68k/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index fd4c7cc3d3b..64d6b119bb0 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -40,7 +40,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init(struct semaphore *sem, int val)
{
diff --git a/include/asm-m68k/types.h b/include/asm-m68k/types.h
index b5a1febc97d..c35c09d93b6 100644
--- a/include/asm-m68k/types.h
+++ b/include/asm-m68k/types.h
@@ -27,9 +27,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index 7d6075d9b5c..b8b2770d687 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -160,6 +160,7 @@ static __inline__ int __test_bit(int nr, const volatile unsigned long * addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
static __inline__ int ext2_set_bit(int nr, volatile void * addr)
{
diff --git a/include/asm-m68knommu/io.h b/include/asm-m68knommu/io.h
index 8df4cee2a0c..653d9b2d7dd 100644
--- a/include/asm-m68knommu/io.h
+++ b/include/asm-m68knommu/io.h
@@ -165,12 +165,6 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size
extern void iounmap(void *addr);
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
/* Pages to physical address... */
#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT)
diff --git a/include/asm-m68knommu/ipc.h b/include/asm-m68knommu/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-m68knommu/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-m68knommu/semaphore.h b/include/asm-m68knommu/semaphore.h
index 5cc1fdd86f5..5779eb6c068 100644
--- a/include/asm-m68knommu/semaphore.h
+++ b/include/asm-m68knommu/semaphore.h
@@ -39,7 +39,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 5da43a5d12a..1bd1142685e 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -253,8 +253,7 @@ cmpxchg(volatile int *p, int old, int new)
"); \
})
#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
- defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
- defined(CONFIG_CLEOPATRA)
+ defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
#define HARD_RESET_NOW() ({ \
asm(" \
movew #0x2700, %sr; \
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 899357a72ac..77ed0c79830 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -172,6 +172,20 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
}
/*
+ * clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock.
+ */
+static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(nr, addr);
+}
+
+/*
* change_bit - Toggle a bit in memory
* @nr: Bit to change
* @addr: Address to start counting from
@@ -240,6 +254,8 @@ static inline int test_and_set_bit(unsigned long nr,
unsigned short bit = nr & SZLONG_MASK;
unsigned long res;
+ smp_llsc_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
@@ -295,6 +311,73 @@ static inline int test_and_set_bit(unsigned long nr,
}
/*
+ * test_and_set_bit_lock - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and implies acquire ordering semantics
+ * after the memory operation.
+ */
+static inline int test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long res;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " beqzl %2, 1b \n"
+ " and %2, %0, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (*m), "=&r" (res)
+ : "r" (1UL << bit), "m" (*m)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " beqz %2, 2f \n"
+ " and %2, %0, %3 \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " nop \n"
+ " .previous \n"
+ " .set pop \n"
+ : "=&r" (temp), "=m" (*m), "=&r" (res)
+ : "r" (1UL << bit), "m" (*m)
+ : "memory");
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return res != 0;
+}
+/*
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
@@ -308,6 +391,8 @@ static inline int test_and_clear_bit(unsigned long nr,
unsigned short bit = nr & SZLONG_MASK;
unsigned long res;
+ smp_llsc_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
@@ -396,6 +481,8 @@ static inline int test_and_change_bit(unsigned long nr,
unsigned short bit = nr & SZLONG_MASK;
unsigned long res;
+ smp_llsc_mb();
+
if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
unsigned long temp;
@@ -453,6 +540,21 @@ static inline int test_and_change_bit(unsigned long nr,
#include <asm-generic/bitops/non-atomic.h>
/*
+ * __clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * __clear_bit() is non-atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock if no other CPUs can concurrently
+ * modify other bits in the word.
+ */
+static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+ smp_mb();
+ __clear_bit(nr, addr);
+}
+
+/*
* Return the bit position (0..63) of the most significant 1 bit in a word
* Returns -1 if no 1 bit exists
*/
diff --git a/include/asm-mips/floppy.h b/include/asm-mips/floppy.h
index a62d0990c8a..992d232adc8 100644
--- a/include/asm-mips/floppy.h
+++ b/include/asm-mips/floppy.h
@@ -34,8 +34,6 @@ static inline void fd_cacheflush(char * addr, long size)
#define N_FDC 1 /* do you *really* want a second controller? */
#define N_DRIVE 8
-#define FLOPPY_MOTOR_MASK 0xf0
-
/*
* The DMA channel used by the floppy controller cannot access data at
* addresses >= 16MB
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h
index 2cd8323c858..e62058b0d28 100644
--- a/include/asm-mips/io.h
+++ b/include/asm-mips/io.h
@@ -554,6 +554,8 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int
* caches. Dirty lines of the caches may be written back or simply
* be discarded. This operation is necessary before dma operations
* to the memory.
+ *
+ * This API used to be exported; it now is for arch code internal use only.
*/
#ifdef CONFIG_DMA_NONCOHERENT
diff --git a/include/asm-mips/ip32/ip32_ints.h b/include/asm-mips/ip32/ip32_ints.h
index c3c280e3d59..042f821899a 100644
--- a/include/asm-mips/ip32/ip32_ints.h
+++ b/include/asm-mips/ip32/ip32_ints.h
@@ -9,86 +9,104 @@
#ifndef __ASM_IP32_INTS_H
#define __ASM_IP32_INTS_H
+#include <asm/irq.h>
+
/*
* This list reflects the assignment of interrupt numbers to
* interrupting events. Order is fairly irrelevant to handling
* priority. This differs from irix.
*/
-/* CPU */
-#define IP32_R4K_TIMER_IRQ 0
+enum ip32_irq_no {
+ /*
+ * CPU interrupts are 0 ... 7
+ */
-/* MACE */
-#define MACE_VID_IN1_IRQ 1
-#define MACE_VID_IN2_IRQ 2
-#define MACE_VID_OUT_IRQ 3
-#define MACE_ETHERNET_IRQ 4
-/* SUPERIO, MISC, and AUDIO are MACEISA */
-#define MACE_PCI_BRIDGE_IRQ 8
+ /*
+ * MACE
+ */
+ MACE_VID_IN1_IRQ = MIPS_CPU_IRQ_BASE + 8,
+ MACE_VID_IN2_IRQ,
+ MACE_VID_OUT_IRQ,
+ MACE_ETHERNET_IRQ,
+ /* SUPERIO, MISC, and AUDIO are MACEISA */
+ __MACE_SUPERIO,
+ __MACE_MISC,
+ __MACE_AUDIO,
+ MACE_PCI_BRIDGE_IRQ,
-/* MACEPCI */
-#define MACEPCI_SCSI0_IRQ 9
-#define MACEPCI_SCSI1_IRQ 10
-#define MACEPCI_SLOT0_IRQ 11
-#define MACEPCI_SLOT1_IRQ 12
-#define MACEPCI_SLOT2_IRQ 13
-#define MACEPCI_SHARED0_IRQ 14
-#define MACEPCI_SHARED1_IRQ 15
-#define MACEPCI_SHARED2_IRQ 16
+ /*
+ * MACEPCI
+ */
+ MACEPCI_SCSI0_IRQ,
+ MACEPCI_SCSI1_IRQ,
+ MACEPCI_SLOT0_IRQ,
+ MACEPCI_SLOT1_IRQ,
+ MACEPCI_SLOT2_IRQ,
+ MACEPCI_SHARED0_IRQ,
+ MACEPCI_SHARED1_IRQ,
+ MACEPCI_SHARED2_IRQ,
-/* CRIME */
-#define CRIME_GBE0_IRQ 17
-#define CRIME_GBE1_IRQ 18
-#define CRIME_GBE2_IRQ 19
-#define CRIME_GBE3_IRQ 20
-#define CRIME_CPUERR_IRQ 21
-#define CRIME_MEMERR_IRQ 22
-#define CRIME_RE_EMPTY_E_IRQ 23
-#define CRIME_RE_FULL_E_IRQ 24
-#define CRIME_RE_IDLE_E_IRQ 25
-#define CRIME_RE_EMPTY_L_IRQ 26
-#define CRIME_RE_FULL_L_IRQ 27
-#define CRIME_RE_IDLE_L_IRQ 28
-#define CRIME_SOFT0_IRQ 29
-#define CRIME_SOFT1_IRQ 30
-#define CRIME_SOFT2_IRQ 31
-#define CRIME_SYSCORERR_IRQ CRIME_SOFT2_IRQ
-#define CRIME_VICE_IRQ 32
+ /*
+ * CRIME
+ */
+ CRIME_GBE0_IRQ,
+ CRIME_GBE1_IRQ,
+ CRIME_GBE2_IRQ,
+ CRIME_GBE3_IRQ,
+ CRIME_CPUERR_IRQ,
+ CRIME_MEMERR_IRQ,
+ CRIME_RE_EMPTY_E_IRQ,
+ CRIME_RE_FULL_E_IRQ,
+ CRIME_RE_IDLE_E_IRQ,
+ CRIME_RE_EMPTY_L_IRQ,
+ CRIME_RE_FULL_L_IRQ,
+ CRIME_RE_IDLE_L_IRQ,
+ CRIME_SOFT0_IRQ,
+ CRIME_SOFT1_IRQ,
+ CRIME_SOFT2_IRQ,
+ CRIME_SYSCORERR_IRQ = CRIME_SOFT2_IRQ,
+ CRIME_VICE_IRQ,
-/* MACEISA */
-#define MACEISA_AUDIO_SW_IRQ 33
-#define MACEISA_AUDIO_SC_IRQ 34
-#define MACEISA_AUDIO1_DMAT_IRQ 35
-#define MACEISA_AUDIO1_OF_IRQ 36
-#define MACEISA_AUDIO2_DMAT_IRQ 37
-#define MACEISA_AUDIO2_MERR_IRQ 38
-#define MACEISA_AUDIO3_DMAT_IRQ 39
-#define MACEISA_AUDIO3_MERR_IRQ 40
-#define MACEISA_RTC_IRQ 41
-#define MACEISA_KEYB_IRQ 42
-/* MACEISA_KEYB_POLL is not an IRQ */
-#define MACEISA_MOUSE_IRQ 44
-/* MACEISA_MOUSE_POLL is not an IRQ */
-#define MACEISA_TIMER0_IRQ 46
-#define MACEISA_TIMER1_IRQ 47
-#define MACEISA_TIMER2_IRQ 48
-#define MACEISA_PARALLEL_IRQ 49
-#define MACEISA_PAR_CTXA_IRQ 50
-#define MACEISA_PAR_CTXB_IRQ 51
-#define MACEISA_PAR_MERR_IRQ 52
-#define MACEISA_SERIAL1_IRQ 53
-#define MACEISA_SERIAL1_TDMAT_IRQ 54
-#define MACEISA_SERIAL1_TDMAPR_IRQ 55
-#define MACEISA_SERIAL1_TDMAME_IRQ 56
-#define MACEISA_SERIAL1_RDMAT_IRQ 57
-#define MACEISA_SERIAL1_RDMAOR_IRQ 58
-#define MACEISA_SERIAL2_IRQ 59
-#define MACEISA_SERIAL2_TDMAT_IRQ 60
-#define MACEISA_SERIAL2_TDMAPR_IRQ 61
-#define MACEISA_SERIAL2_TDMAME_IRQ 62
-#define MACEISA_SERIAL2_RDMAT_IRQ 63
-#define MACEISA_SERIAL2_RDMAOR_IRQ 64
+ /*
+ * MACEISA
+ */
+ MACEISA_AUDIO_SW_IRQ,
+ MACEISA_AUDIO_SC_IRQ,
+ MACEISA_AUDIO1_DMAT_IRQ,
+ MACEISA_AUDIO1_OF_IRQ,
+ MACEISA_AUDIO2_DMAT_IRQ,
+ MACEISA_AUDIO2_MERR_IRQ,
+ MACEISA_AUDIO3_DMAT_IRQ,
+ MACEISA_AUDIO3_MERR_IRQ,
+ MACEISA_RTC_IRQ,
+ MACEISA_KEYB_IRQ,
+ /* MACEISA_KEYB_POLL is not an IRQ */
+ __MACEISA_KEYB_POLL,
+ MACEISA_MOUSE_IRQ,
+ /* MACEISA_MOUSE_POLL is not an IRQ */
+ __MACEISA_MOUSE_POLL,
+ MACEISA_TIMER0_IRQ,
+ MACEISA_TIMER1_IRQ,
+ MACEISA_TIMER2_IRQ,
+ MACEISA_PARALLEL_IRQ,
+ MACEISA_PAR_CTXA_IRQ,
+ MACEISA_PAR_CTXB_IRQ,
+ MACEISA_PAR_MERR_IRQ,
+ MACEISA_SERIAL1_IRQ,
+ MACEISA_SERIAL1_TDMAT_IRQ,
+ MACEISA_SERIAL1_TDMAPR_IRQ,
+ MACEISA_SERIAL1_TDMAME_IRQ,
+ MACEISA_SERIAL1_RDMAT_IRQ,
+ MACEISA_SERIAL1_RDMAOR_IRQ,
+ MACEISA_SERIAL2_IRQ,
+ MACEISA_SERIAL2_TDMAT_IRQ,
+ MACEISA_SERIAL2_TDMAPR_IRQ,
+ MACEISA_SERIAL2_TDMAME_IRQ,
+ MACEISA_SERIAL2_RDMAT_IRQ,
+ MACEISA_SERIAL2_RDMAOR_IRQ,
-#define IP32_IRQ_MAX MACEISA_SERIAL2_RDMAOR_IRQ
+ IP32_IRQ_MAX = MACEISA_SERIAL2_RDMAOR_IRQ
+};
#endif /* __ASM_IP32_INTS_H */
diff --git a/include/asm-mips/ipc.h b/include/asm-mips/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-mips/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-mips/lasat/lasatint.h b/include/asm-mips/lasat/lasatint.h
index 065474feecc..581dc45685a 100644
--- a/include/asm-mips/lasat/lasatint.h
+++ b/include/asm-mips/lasat/lasatint.h
@@ -1,4 +1,10 @@
-#define LASATINT_END 16
+#ifndef __ASM_LASAT_LASATINT_H
+#define __ASM_LASAT_LASATINT_H
+
+#include <linux/irq.h>
+
+#define LASATINT_BASE MIPS_CPU_IRQ_BASE
+#define LASATINT_END (LASATINT_BASE + 16)
/* lasat 100 */
#define LASAT_INT_STATUS_REG_100 (KSEG1ADDR(0x1c880000))
@@ -10,3 +16,4 @@
#define LASAT_INT_MASK_REG_200 (KSEG1ADDR(0x1104003c))
#define LASATINT_MASK_SHIFT_200 16
+#endif /* __ASM_LASAT_LASATINT_H */
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h
index 10f613f23c3..3bdce9126f1 100644
--- a/include/asm-mips/mach-au1x00/au1000.h
+++ b/include/asm-mips/mach-au1x00/au1000.h
@@ -40,7 +40,9 @@
#include <linux/delay.h>
#include <linux/types.h>
+
#include <asm/io.h>
+#include <asm/irq.h>
/* cpu pipeline flush */
void static inline au_sync(void)
@@ -91,23 +93,6 @@ static inline u32 au_readl(unsigned long reg)
}
-static __inline__ int au_ffz(unsigned int x)
-{
- if ((x = ~x) == 0)
- return 32;
- return __ilog2(x & -x);
-}
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-static __inline__ int au_ffs(int x)
-{
- return __ilog2(x & -x) + 1;
-}
-
/* arch/mips/au1000/common/clocks.c */
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
@@ -119,16 +104,16 @@ extern unsigned int get_au1x00_lcd_clock(void);
/*
* Every board describes its IRQ mapping with this table.
*/
-typedef struct au1xxx_irqmap {
+struct au1xxx_irqmap {
int im_irq;
int im_type;
int im_request;
-} au1xxx_irq_map_t;
+};
/*
* init_IRQ looks for a table with this name.
*/
-extern au1xxx_irq_map_t au1xxx_irq_map[];
+extern struct au1xxx_irqmap au1xxx_irq_map[];
#endif /* !defined (_LANGUAGE_ASSEMBLY) */
@@ -540,63 +525,67 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
/* Interrupt Numbers */
/* Au1000 */
#ifdef CONFIG_SOC_AU1000
-#define AU1000_UART0_INT 0
-#define AU1000_UART1_INT 1 /* au1000 */
-#define AU1000_UART2_INT 2 /* au1000 */
-#define AU1000_UART3_INT 3
-#define AU1000_SSI0_INT 4 /* au1000 */
-#define AU1000_SSI1_INT 5 /* au1000 */
-#define AU1000_DMA_INT_BASE 6
-#define AU1000_TOY_INT 14
-#define AU1000_TOY_MATCH0_INT 15
-#define AU1000_TOY_MATCH1_INT 16
-#define AU1000_TOY_MATCH2_INT 17
-#define AU1000_RTC_INT 18
-#define AU1000_RTC_MATCH0_INT 19
-#define AU1000_RTC_MATCH1_INT 20
-#define AU1000_RTC_MATCH2_INT 21
-#define AU1000_IRDA_TX_INT 22 /* au1000 */
-#define AU1000_IRDA_RX_INT 23 /* au1000 */
-#define AU1000_USB_DEV_REQ_INT 24
-#define AU1000_USB_DEV_SUS_INT 25
-#define AU1000_USB_HOST_INT 26
-#define AU1000_ACSYNC_INT 27
-#define AU1000_MAC0_DMA_INT 28
-#define AU1000_MAC1_DMA_INT 29
-#define AU1000_I2S_UO_INT 30 /* au1000 */
-#define AU1000_AC97C_INT 31
-#define AU1000_GPIO_0 32
-#define AU1000_GPIO_1 33
-#define AU1000_GPIO_2 34
-#define AU1000_GPIO_3 35
-#define AU1000_GPIO_4 36
-#define AU1000_GPIO_5 37
-#define AU1000_GPIO_6 38
-#define AU1000_GPIO_7 39
-#define AU1000_GPIO_8 40
-#define AU1000_GPIO_9 41
-#define AU1000_GPIO_10 42
-#define AU1000_GPIO_11 43
-#define AU1000_GPIO_12 44
-#define AU1000_GPIO_13 45
-#define AU1000_GPIO_14 46
-#define AU1000_GPIO_15 47
-#define AU1000_GPIO_16 48
-#define AU1000_GPIO_17 49
-#define AU1000_GPIO_18 50
-#define AU1000_GPIO_19 51
-#define AU1000_GPIO_20 52
-#define AU1000_GPIO_21 53
-#define AU1000_GPIO_22 54
-#define AU1000_GPIO_23 55
-#define AU1000_GPIO_24 56
-#define AU1000_GPIO_25 57
-#define AU1000_GPIO_26 58
-#define AU1000_GPIO_27 59
-#define AU1000_GPIO_28 60
-#define AU1000_GPIO_29 61
-#define AU1000_GPIO_30 62
-#define AU1000_GPIO_31 63
+enum soc_au1000_ints {
+ AU1000_FIRST_INT = MIPS_CPU_IRQ_BASE,
+ AU1000_UART0_INT = AU1000_FIRST_INT,
+ AU1000_UART1_INT, /* au1000 */
+ AU1000_UART2_INT, /* au1000 */
+ AU1000_UART3_INT,
+ AU1000_SSI0_INT, /* au1000 */
+ AU1000_SSI1_INT, /* au1000 */
+ AU1000_DMA_INT_BASE,
+
+ AU1000_TOY_INT = AU1000_FIRST_INT + 14,
+ AU1000_TOY_MATCH0_INT,
+ AU1000_TOY_MATCH1_INT,
+ AU1000_TOY_MATCH2_INT,
+ AU1000_RTC_INT,
+ AU1000_RTC_MATCH0_INT,
+ AU1000_RTC_MATCH1_INT,
+ AU1000_RTC_MATCH2_INT,
+ AU1000_IRDA_TX_INT, /* au1000 */
+ AU1000_IRDA_RX_INT, /* au1000 */
+ AU1000_USB_DEV_REQ_INT,
+ AU1000_USB_DEV_SUS_INT,
+ AU1000_USB_HOST_INT,
+ AU1000_ACSYNC_INT,
+ AU1000_MAC0_DMA_INT,
+ AU1000_MAC1_DMA_INT,
+ AU1000_I2S_UO_INT, /* au1000 */
+ AU1000_AC97C_INT,
+ AU1000_GPIO_0,
+ AU1000_GPIO_1,
+ AU1000_GPIO_2,
+ AU1000_GPIO_3,
+ AU1000_GPIO_4,
+ AU1000_GPIO_5,
+ AU1000_GPIO_6,
+ AU1000_GPIO_7,
+ AU1000_GPIO_8,
+ AU1000_GPIO_9,
+ AU1000_GPIO_10,
+ AU1000_GPIO_11,
+ AU1000_GPIO_12,
+ AU1000_GPIO_13,
+ AU1000_GPIO_14,
+ AU1000_GPIO_15,
+ AU1000_GPIO_16,
+ AU1000_GPIO_17,
+ AU1000_GPIO_18,
+ AU1000_GPIO_19,
+ AU1000_GPIO_20,
+ AU1000_GPIO_21,
+ AU1000_GPIO_22,
+ AU1000_GPIO_23,
+ AU1000_GPIO_24,
+ AU1000_GPIO_25,
+ AU1000_GPIO_26,
+ AU1000_GPIO_27,
+ AU1000_GPIO_28,
+ AU1000_GPIO_29,
+ AU1000_GPIO_30,
+ AU1000_GPIO_31,
+};
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
@@ -615,61 +604,65 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
/* Au1500 */
#ifdef CONFIG_SOC_AU1500
-#define AU1500_UART0_INT 0
-#define AU1000_PCI_INTA 1 /* au1500 */
-#define AU1000_PCI_INTB 2 /* au1500 */
-#define AU1500_UART3_INT 3
-#define AU1000_PCI_INTC 4 /* au1500 */
-#define AU1000_PCI_INTD 5 /* au1500 */
-#define AU1000_DMA_INT_BASE 6
-#define AU1000_TOY_INT 14
-#define AU1000_TOY_MATCH0_INT 15
-#define AU1000_TOY_MATCH1_INT 16
-#define AU1000_TOY_MATCH2_INT 17
-#define AU1000_RTC_INT 18
-#define AU1000_RTC_MATCH0_INT 19
-#define AU1000_RTC_MATCH1_INT 20
-#define AU1000_RTC_MATCH2_INT 21
-#define AU1500_PCI_ERR_INT 22
-#define AU1000_USB_DEV_REQ_INT 24
-#define AU1000_USB_DEV_SUS_INT 25
-#define AU1000_USB_HOST_INT 26
-#define AU1000_ACSYNC_INT 27
-#define AU1500_MAC0_DMA_INT 28
-#define AU1500_MAC1_DMA_INT 29
-#define AU1000_AC97C_INT 31
-#define AU1000_GPIO_0 32
-#define AU1000_GPIO_1 33
-#define AU1000_GPIO_2 34
-#define AU1000_GPIO_3 35
-#define AU1000_GPIO_4 36
-#define AU1000_GPIO_5 37
-#define AU1000_GPIO_6 38
-#define AU1000_GPIO_7 39
-#define AU1000_GPIO_8 40
-#define AU1000_GPIO_9 41
-#define AU1000_GPIO_10 42
-#define AU1000_GPIO_11 43
-#define AU1000_GPIO_12 44
-#define AU1000_GPIO_13 45
-#define AU1000_GPIO_14 46
-#define AU1000_GPIO_15 47
-#define AU1500_GPIO_200 48
-#define AU1500_GPIO_201 49
-#define AU1500_GPIO_202 50
-#define AU1500_GPIO_203 51
-#define AU1500_GPIO_20 52
-#define AU1500_GPIO_204 53
-#define AU1500_GPIO_205 54
-#define AU1500_GPIO_23 55
-#define AU1500_GPIO_24 56
-#define AU1500_GPIO_25 57
-#define AU1500_GPIO_26 58
-#define AU1500_GPIO_27 59
-#define AU1500_GPIO_28 60
-#define AU1500_GPIO_206 61
-#define AU1500_GPIO_207 62
-#define AU1500_GPIO_208_215 63
+enum soc_au1500_ints {
+ AU1500_FIRST_INT = MIPS_CPU_IRQ_BASE,
+ AU1500_UART0_INT = AU1500_FIRST_INT,
+ AU1000_PCI_INTA, /* au1500 */
+ AU1000_PCI_INTB, /* au1500 */
+ AU1500_UART3_INT,
+ AU1000_PCI_INTC, /* au1500 */
+ AU1000_PCI_INTD, /* au1500 */
+ AU1000_DMA_INT_BASE,
+
+ AU1000_TOY_INT = AU1500_FIRST_INT + 14,
+ AU1000_TOY_MATCH0_INT,
+ AU1000_TOY_MATCH1_INT,
+ AU1000_TOY_MATCH2_INT,
+ AU1000_RTC_INT,
+ AU1000_RTC_MATCH0_INT,
+ AU1000_RTC_MATCH1_INT,
+ AU1000_RTC_MATCH2_INT,
+ AU1500_PCI_ERR_INT,
+ AU1000_USB_DEV_REQ_INT,
+ AU1000_USB_DEV_SUS_INT,
+ AU1000_USB_HOST_INT,
+ AU1000_ACSYNC_INT,
+ AU1500_MAC0_DMA_INT,
+ AU1500_MAC1_DMA_INT,
+ AU1000_AC97C_INT = AU1500_FIRST_INT + 31,
+ AU1000_GPIO_0,
+ AU1000_GPIO_1,
+ AU1000_GPIO_2,
+ AU1000_GPIO_3,
+ AU1000_GPIO_4,
+ AU1000_GPIO_5,
+ AU1000_GPIO_6,
+ AU1000_GPIO_7,
+ AU1000_GPIO_8,
+ AU1000_GPIO_9,
+ AU1000_GPIO_10,
+ AU1000_GPIO_11,
+ AU1000_GPIO_12,
+ AU1000_GPIO_13,
+ AU1000_GPIO_14,
+ AU1000_GPIO_15,
+ AU1500_GPIO_200,
+ AU1500_GPIO_201,
+ AU1500_GPIO_202,
+ AU1500_GPIO_203,
+ AU1500_GPIO_20,
+ AU1500_GPIO_204,
+ AU1500_GPIO_205,
+ AU1500_GPIO_23,
+ AU1500_GPIO_24,
+ AU1500_GPIO_25,
+ AU1500_GPIO_26,
+ AU1500_GPIO_27,
+ AU1500_GPIO_28,
+ AU1500_GPIO_206,
+ AU1500_GPIO_207,
+ AU1500_GPIO_208_215,
+};
/* shortcuts */
#define INTA AU1000_PCI_INTA
@@ -692,63 +685,67 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
/* Au1100 */
#ifdef CONFIG_SOC_AU1100
-#define AU1100_UART0_INT 0
-#define AU1100_UART1_INT 1
-#define AU1100_SD_INT 2
-#define AU1100_UART3_INT 3
-#define AU1000_SSI0_INT 4
-#define AU1000_SSI1_INT 5
-#define AU1000_DMA_INT_BASE 6
-#define AU1000_TOY_INT 14
-#define AU1000_TOY_MATCH0_INT 15
-#define AU1000_TOY_MATCH1_INT 16
-#define AU1000_TOY_MATCH2_INT 17
-#define AU1000_RTC_INT 18
-#define AU1000_RTC_MATCH0_INT 19
-#define AU1000_RTC_MATCH1_INT 20
-#define AU1000_RTC_MATCH2_INT 21
-#define AU1000_IRDA_TX_INT 22
-#define AU1000_IRDA_RX_INT 23
-#define AU1000_USB_DEV_REQ_INT 24
-#define AU1000_USB_DEV_SUS_INT 25
-#define AU1000_USB_HOST_INT 26
-#define AU1000_ACSYNC_INT 27
-#define AU1100_MAC0_DMA_INT 28
-#define AU1100_GPIO_208_215 29
-#define AU1100_LCD_INT 30
-#define AU1000_AC97C_INT 31
-#define AU1000_GPIO_0 32
-#define AU1000_GPIO_1 33
-#define AU1000_GPIO_2 34
-#define AU1000_GPIO_3 35
-#define AU1000_GPIO_4 36
-#define AU1000_GPIO_5 37
-#define AU1000_GPIO_6 38
-#define AU1000_GPIO_7 39
-#define AU1000_GPIO_8 40
-#define AU1000_GPIO_9 41
-#define AU1000_GPIO_10 42
-#define AU1000_GPIO_11 43
-#define AU1000_GPIO_12 44
-#define AU1000_GPIO_13 45
-#define AU1000_GPIO_14 46
-#define AU1000_GPIO_15 47
-#define AU1000_GPIO_16 48
-#define AU1000_GPIO_17 49
-#define AU1000_GPIO_18 50
-#define AU1000_GPIO_19 51
-#define AU1000_GPIO_20 52
-#define AU1000_GPIO_21 53
-#define AU1000_GPIO_22 54
-#define AU1000_GPIO_23 55
-#define AU1000_GPIO_24 56
-#define AU1000_GPIO_25 57
-#define AU1000_GPIO_26 58
-#define AU1000_GPIO_27 59
-#define AU1000_GPIO_28 60
-#define AU1000_GPIO_29 61
-#define AU1000_GPIO_30 62
-#define AU1000_GPIO_31 63
+enum soc_au1100_ints {
+ AU1100_FIRST_INT = MIPS_CPU_IRQ_BASE,
+ AU1100_UART0_INT,
+ AU1100_UART1_INT,
+ AU1100_SD_INT,
+ AU1100_UART3_INT,
+ AU1000_SSI0_INT,
+ AU1000_SSI1_INT,
+ AU1000_DMA_INT_BASE,
+
+ AU1000_TOY_INT = AU1100_FIRST_INT + 14,
+ AU1000_TOY_MATCH0_INT,
+ AU1000_TOY_MATCH1_INT,
+ AU1000_TOY_MATCH2_INT,
+ AU1000_RTC_INT,
+ AU1000_RTC_MATCH0_INT,
+ AU1000_RTC_MATCH1_INT,
+ AU1000_RTC_MATCH2_INT,
+ AU1000_IRDA_TX_INT,
+ AU1000_IRDA_RX_INT,
+ AU1000_USB_DEV_REQ_INT,
+ AU1000_USB_DEV_SUS_INT,
+ AU1000_USB_HOST_INT,
+ AU1000_ACSYNC_INT,
+ AU1100_MAC0_DMA_INT,
+ AU1100_GPIO_208_215,
+ AU1100_LCD_INT,
+ AU1000_AC97C_INT,
+ AU1000_GPIO_0,
+ AU1000_GPIO_1,
+ AU1000_GPIO_2,
+ AU1000_GPIO_3,
+ AU1000_GPIO_4,
+ AU1000_GPIO_5,
+ AU1000_GPIO_6,
+ AU1000_GPIO_7,
+ AU1000_GPIO_8,
+ AU1000_GPIO_9,
+ AU1000_GPIO_10,
+ AU1000_GPIO_11,
+ AU1000_GPIO_12,
+ AU1000_GPIO_13,
+ AU1000_GPIO_14,
+ AU1000_GPIO_15,
+ AU1000_GPIO_16,
+ AU1000_GPIO_17,
+ AU1000_GPIO_18,
+ AU1000_GPIO_19,
+ AU1000_GPIO_20,
+ AU1000_GPIO_21,
+ AU1000_GPIO_22,
+ AU1000_GPIO_23,
+ AU1000_GPIO_24,
+ AU1000_GPIO_25,
+ AU1000_GPIO_26,
+ AU1000_GPIO_27,
+ AU1000_GPIO_28,
+ AU1000_GPIO_29,
+ AU1000_GPIO_30,
+ AU1000_GPIO_31,
+};
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
@@ -763,69 +760,73 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#endif /* CONFIG_SOC_AU1100 */
#ifdef CONFIG_SOC_AU1550
-#define AU1550_UART0_INT 0
-#define AU1550_PCI_INTA 1
-#define AU1550_PCI_INTB 2
-#define AU1550_DDMA_INT 3
-#define AU1550_CRYPTO_INT 4
-#define AU1550_PCI_INTC 5
-#define AU1550_PCI_INTD 6
-#define AU1550_PCI_RST_INT 7
-#define AU1550_UART1_INT 8
-#define AU1550_UART3_INT 9
-#define AU1550_PSC0_INT 10
-#define AU1550_PSC1_INT 11
-#define AU1550_PSC2_INT 12
-#define AU1550_PSC3_INT 13
-#define AU1000_TOY_INT 14
-#define AU1000_TOY_MATCH0_INT 15
-#define AU1000_TOY_MATCH1_INT 16
-#define AU1000_TOY_MATCH2_INT 17
-#define AU1000_RTC_INT 18
-#define AU1000_RTC_MATCH0_INT 19
-#define AU1000_RTC_MATCH1_INT 20
-#define AU1000_RTC_MATCH2_INT 21
-#define AU1550_NAND_INT 23
-#define AU1550_USB_DEV_REQ_INT 24
-#define AU1550_USB_DEV_SUS_INT 25
-#define AU1550_USB_HOST_INT 26
-#define AU1000_USB_DEV_REQ_INT AU1550_USB_DEV_REQ_INT
-#define AU1000_USB_DEV_SUS_INT AU1550_USB_DEV_SUS_INT
-#define AU1000_USB_HOST_INT AU1550_USB_HOST_INT
-#define AU1550_MAC0_DMA_INT 27
-#define AU1550_MAC1_DMA_INT 28
-#define AU1000_GPIO_0 32
-#define AU1000_GPIO_1 33
-#define AU1000_GPIO_2 34
-#define AU1000_GPIO_3 35
-#define AU1000_GPIO_4 36
-#define AU1000_GPIO_5 37
-#define AU1000_GPIO_6 38
-#define AU1000_GPIO_7 39
-#define AU1000_GPIO_8 40
-#define AU1000_GPIO_9 41
-#define AU1000_GPIO_10 42
-#define AU1000_GPIO_11 43
-#define AU1000_GPIO_12 44
-#define AU1000_GPIO_13 45
-#define AU1000_GPIO_14 46
-#define AU1000_GPIO_15 47
-#define AU1550_GPIO_200 48
-#define AU1500_GPIO_201_205 49 // Logical or of GPIO201:205
-#define AU1500_GPIO_16 50
-#define AU1500_GPIO_17 51
-#define AU1500_GPIO_20 52
-#define AU1500_GPIO_21 53
-#define AU1500_GPIO_22 54
-#define AU1500_GPIO_23 55
-#define AU1500_GPIO_24 56
-#define AU1500_GPIO_25 57
-#define AU1500_GPIO_26 58
-#define AU1500_GPIO_27 59
-#define AU1500_GPIO_28 60
-#define AU1500_GPIO_206 61
-#define AU1500_GPIO_207 62
-#define AU1500_GPIO_208_218 63 // Logical or of GPIO208:218
+enum soc_au1550_ints {
+ AU1550_FIRST_INT = MIPS_CPU_IRQ_BASE,
+ AU1550_UART0_INT = AU1550_FIRST_INT,
+ AU1550_PCI_INTA,
+ AU1550_PCI_INTB,
+ AU1550_DDMA_INT,
+ AU1550_CRYPTO_INT,
+ AU1550_PCI_INTC,
+ AU1550_PCI_INTD,
+ AU1550_PCI_RST_INT,
+ AU1550_UART1_INT,
+ AU1550_UART3_INT,
+ AU1550_PSC0_INT,
+ AU1550_PSC1_INT,
+ AU1550_PSC2_INT,
+ AU1550_PSC3_INT,
+ AU1000_TOY_INT,
+ AU1000_TOY_MATCH0_INT,
+ AU1000_TOY_MATCH1_INT,
+ AU1000_TOY_MATCH2_INT,
+ AU1000_RTC_INT,
+ AU1000_RTC_MATCH0_INT,
+ AU1000_RTC_MATCH1_INT,
+ AU1000_RTC_MATCH2_INT,
+
+ AU1550_NAND_INT = AU1550_FIRST_INT + 23,
+ AU1550_USB_DEV_REQ_INT,
+ AU1000_USB_DEV_REQ_INT = AU1550_USB_DEV_REQ_INT,
+ AU1550_USB_DEV_SUS_INT,
+ AU1000_USB_DEV_SUS_INT = AU1550_USB_DEV_SUS_INT,
+ AU1550_USB_HOST_INT,
+ AU1000_USB_HOST_INT = AU1550_USB_HOST_INT,
+ AU1550_MAC0_DMA_INT,
+ AU1550_MAC1_DMA_INT,
+ AU1000_GPIO_0 = AU1550_FIRST_INT + 32,
+ AU1000_GPIO_1,
+ AU1000_GPIO_2,
+ AU1000_GPIO_3,
+ AU1000_GPIO_4,
+ AU1000_GPIO_5,
+ AU1000_GPIO_6,
+ AU1000_GPIO_7,
+ AU1000_GPIO_8,
+ AU1000_GPIO_9,
+ AU1000_GPIO_10,
+ AU1000_GPIO_11,
+ AU1000_GPIO_12,
+ AU1000_GPIO_13,
+ AU1000_GPIO_14,
+ AU1000_GPIO_15,
+ AU1550_GPIO_200,
+ AU1500_GPIO_201_205, /* Logical or of GPIO201:205 */
+ AU1500_GPIO_16,
+ AU1500_GPIO_17,
+ AU1500_GPIO_20,
+ AU1500_GPIO_21,
+ AU1500_GPIO_22,
+ AU1500_GPIO_23,
+ AU1500_GPIO_24,
+ AU1500_GPIO_25,
+ AU1500_GPIO_26,
+ AU1500_GPIO_27,
+ AU1500_GPIO_28,
+ AU1500_GPIO_206,
+ AU1500_GPIO_207,
+ AU1500_GPIO_208_218, /* Logical or of GPIO208:218 */
+};
/* shortcuts */
#define INTA AU1550_PCI_INTA
@@ -849,70 +850,74 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200
-#define AU1200_UART0_INT 0
-#define AU1200_SWT_INT 1
-#define AU1200_SD_INT 2
-#define AU1200_DDMA_INT 3
-#define AU1200_MAE_BE_INT 4
-#define AU1200_GPIO_200 5
-#define AU1200_GPIO_201 6
-#define AU1200_GPIO_202 7
-#define AU1200_UART1_INT 8
-#define AU1200_MAE_FE_INT 9
-#define AU1200_PSC0_INT 10
-#define AU1200_PSC1_INT 11
-#define AU1200_AES_INT 12
-#define AU1200_CAMERA_INT 13
-#define AU1000_TOY_INT 14
-#define AU1000_TOY_MATCH0_INT 15
-#define AU1000_TOY_MATCH1_INT 16
-#define AU1000_TOY_MATCH2_INT 17
-#define AU1000_RTC_INT 18
-#define AU1000_RTC_MATCH0_INT 19
-#define AU1000_RTC_MATCH1_INT 20
-#define AU1000_RTC_MATCH2_INT 21
-#define AU1200_NAND_INT 23
-#define AU1200_GPIO_204 24
-#define AU1200_GPIO_205 25
-#define AU1200_GPIO_206 26
-#define AU1200_GPIO_207 27
-#define AU1200_GPIO_208_215 28 // Logical OR of 208:215
-#define AU1200_USB_INT 29
-#define AU1000_USB_HOST_INT AU1200_USB_INT
-#define AU1200_LCD_INT 30
-#define AU1200_MAE_BOTH_INT 31
-#define AU1000_GPIO_0 32
-#define AU1000_GPIO_1 33
-#define AU1000_GPIO_2 34
-#define AU1000_GPIO_3 35
-#define AU1000_GPIO_4 36
-#define AU1000_GPIO_5 37
-#define AU1000_GPIO_6 38
-#define AU1000_GPIO_7 39
-#define AU1000_GPIO_8 40
-#define AU1000_GPIO_9 41
-#define AU1000_GPIO_10 42
-#define AU1000_GPIO_11 43
-#define AU1000_GPIO_12 44
-#define AU1000_GPIO_13 45
-#define AU1000_GPIO_14 46
-#define AU1000_GPIO_15 47
-#define AU1000_GPIO_16 48
-#define AU1000_GPIO_17 49
-#define AU1000_GPIO_18 50
-#define AU1000_GPIO_19 51
-#define AU1000_GPIO_20 52
-#define AU1000_GPIO_21 53
-#define AU1000_GPIO_22 54
-#define AU1000_GPIO_23 55
-#define AU1000_GPIO_24 56
-#define AU1000_GPIO_25 57
-#define AU1000_GPIO_26 58
-#define AU1000_GPIO_27 59
-#define AU1000_GPIO_28 60
-#define AU1000_GPIO_29 61
-#define AU1000_GPIO_30 62
-#define AU1000_GPIO_31 63
+enum soc_au1200_ints {
+ AU1200_FIRST_INT = MIPS_CPU_IRQ_BASE,
+ AU1200_UART0_INT = AU1200_FIRST_INT,
+ AU1200_SWT_INT,
+ AU1200_SD_INT,
+ AU1200_DDMA_INT,
+ AU1200_MAE_BE_INT,
+ AU1200_GPIO_200,
+ AU1200_GPIO_201,
+ AU1200_GPIO_202,
+ AU1200_UART1_INT,
+ AU1200_MAE_FE_INT,
+ AU1200_PSC0_INT,
+ AU1200_PSC1_INT,
+ AU1200_AES_INT,
+ AU1200_CAMERA_INT,
+ AU1000_TOY_INT,
+ AU1000_TOY_MATCH0_INT,
+ AU1000_TOY_MATCH1_INT,
+ AU1000_TOY_MATCH2_INT,
+ AU1000_RTC_INT,
+ AU1000_RTC_MATCH0_INT,
+ AU1000_RTC_MATCH1_INT,
+ AU1000_RTC_MATCH2_INT,
+
+ AU1200_NAND_INT = AU1200_FIRST_INT + 23,
+ AU1200_GPIO_204,
+ AU1200_GPIO_205,
+ AU1200_GPIO_206,
+ AU1200_GPIO_207,
+ AU1200_GPIO_208_215, /* Logical OR of 208:215 */
+ AU1200_USB_INT,
+ AU1000_USB_HOST_INT = AU1200_USB_INT,
+ AU1200_LCD_INT,
+ AU1200_MAE_BOTH_INT,
+ AU1000_GPIO_0,
+ AU1000_GPIO_1,
+ AU1000_GPIO_2,
+ AU1000_GPIO_3,
+ AU1000_GPIO_4,
+ AU1000_GPIO_5,
+ AU1000_GPIO_6,
+ AU1000_GPIO_7,
+ AU1000_GPIO_8,
+ AU1000_GPIO_9,
+ AU1000_GPIO_10,
+ AU1000_GPIO_11,
+ AU1000_GPIO_12,
+ AU1000_GPIO_13,
+ AU1000_GPIO_14,
+ AU1000_GPIO_15,
+ AU1000_GPIO_16,
+ AU1000_GPIO_17,
+ AU1000_GPIO_18,
+ AU1000_GPIO_19,
+ AU1000_GPIO_20,
+ AU1000_GPIO_21,
+ AU1000_GPIO_22,
+ AU1000_GPIO_23,
+ AU1000_GPIO_24,
+ AU1000_GPIO_25,
+ AU1000_GPIO_26,
+ AU1000_GPIO_27,
+ AU1000_GPIO_28,
+ AU1000_GPIO_29,
+ AU1000_GPIO_30,
+ AU1000_GPIO_31,
+};
#define UART0_ADDR 0xB1100000
#define UART1_ADDR 0xB1200000
@@ -943,10 +948,12 @@ extern au1xxx_irq_map_t au1xxx_irq_map[];
#endif /* CONFIG_SOC_AU1200 */
-#define AU1000_LAST_INTC0_INT 31
-#define AU1000_LAST_INTC1_INT 63
-#define AU1000_MAX_INTR 63
-#define INTX 0xFF /* not valid */
+#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 0)
+#define AU1000_INTC0_INT_LAST (MIPS_CPU_IRQ_BASE + 31)
+#define AU1000_INTC1_INT_BASE (MIPS_CPU_IRQ_BASE + 32)
+#define AU1000_INTC1_INT_LAST (MIPS_CPU_IRQ_BASE + 63)
+#define AU1000_MAX_INTR (MIPS_CPU_IRQ_BASE + 63)
+#define INTX 0xFF /* not valid */
/* Programmable Counters 0 and 1 */
#define SYS_BASE 0xB1900000
diff --git a/include/asm-mips/mach-au1x00/prom.h b/include/asm-mips/mach-au1x00/prom.h
new file mode 100644
index 00000000000..e38715577c5
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/prom.h
@@ -0,0 +1,13 @@
+#ifndef __AU1X00_PROM_H
+#define __AU1X00_PROM_H
+
+extern int prom_argc;
+extern char **prom_argv;
+extern char **prom_envp;
+
+extern void prom_init_cmdline(void);
+extern char *prom_getcmdline(void);
+extern char *prom_getenv(char *envname);
+extern int prom_get_ethernet_addr(char *ethernet_addr);
+
+#endif
diff --git a/include/asm-mips/mach-db1x00/db1200.h b/include/asm-mips/mach-db1x00/db1200.h
index 647fdb54cc1..050eae87ff0 100644
--- a/include/asm-mips/mach-db1x00/db1200.h
+++ b/include/asm-mips/mach-db1x00/db1200.h
@@ -181,29 +181,34 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
#define NAND_PHYS_ADDR 0x20000000
/*
- * External Interrupts for Pb1200 as of 8/6/2004.
- * Bit positions in the CPLD registers can be calculated by taking
- * the interrupt define and subtracting the DB1200_INT_BEGIN value.
- * *example: IDE bis pos is = 64 - 64
- ETH bit pos is = 65 - 64
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the DB1200_INT_BEGIN value.
+ *
+ * Example: IDE bis pos is = 64 - 64
+ * ETH bit pos is = 65 - 64
*/
-#define DB1200_INT_BEGIN (AU1000_LAST_INTC1_INT + 1)
-#define DB1200_IDE_INT (DB1200_INT_BEGIN + 0)
-#define DB1200_ETH_INT (DB1200_INT_BEGIN + 1)
-#define DB1200_PC0_INT (DB1200_INT_BEGIN + 2)
-#define DB1200_PC0_STSCHG_INT (DB1200_INT_BEGIN + 3)
-#define DB1200_PC1_INT (DB1200_INT_BEGIN + 4)
-#define DB1200_PC1_STSCHG_INT (DB1200_INT_BEGIN + 5)
-#define DB1200_DC_INT (DB1200_INT_BEGIN + 6)
-#define DB1200_FLASHBUSY_INT (DB1200_INT_BEGIN + 7)
-#define DB1200_PC0_INSERT_INT (DB1200_INT_BEGIN + 8)
-#define DB1200_PC0_EJECT_INT (DB1200_INT_BEGIN + 9)
-#define DB1200_PC1_INSERT_INT (DB1200_INT_BEGIN + 10)
-#define DB1200_PC1_EJECT_INT (DB1200_INT_BEGIN + 11)
-#define DB1200_SD0_INSERT_INT (DB1200_INT_BEGIN + 12)
-#define DB1200_SD0_EJECT_INT (DB1200_INT_BEGIN + 13)
-
-#define DB1200_INT_END (DB1200_INT_BEGIN + 15)
+enum external_pb1200_ints {
+ DB1200_INT_BEGIN = AU1000_MAX_INTR + 1,
+
+ DB1200_IDE_INT = DB1200_INT_BEGIN,
+ DB1200_ETH_INT,
+ DB1200_PC0_INT,
+ DB1200_PC0_STSCHG_INT,
+ DB1200_PC1_INT,
+ DB1200_PC1_STSCHG_INT,
+ DB1200_DC_INT,
+ DB1200_FLASHBUSY_INT,
+ DB1200_PC0_INSERT_INT,
+ DB1200_PC0_EJECT_INT,
+ DB1200_PC1_INSERT_INT,
+ DB1200_PC1_EJECT_INT,
+ DB1200_SD0_INSERT_INT,
+ DB1200_SD0_EJECT_INT,
+
+ DB1200_INT_END = DB1200_INT_BEGIN + 15,
+};
+
/* For drivers/pcmcia/au1000_db1x00.c */
diff --git a/include/asm-mips/mach-ip27/kernel-entry-init.h b/include/asm-mips/mach-ip27/kernel-entry-init.h
index c1a10314b31..624d66c7f29 100644
--- a/include/asm-mips/mach-ip27/kernel-entry-init.h
+++ b/include/asm-mips/mach-ip27/kernel-entry-init.h
@@ -46,7 +46,14 @@
lh t1, KV_RO_NASID_OFFSET(t0)
lh t2, KV_RW_NASID_OFFSET(t0)
MAPPED_KERNEL_SETUP_TLB
- ARC64_TWIDDLE_PC
+
+ /*
+ * We might not get launched at the address the kernel is linked to,
+ * so we jump there.
+ */
+ PTR_LA t0, 0f
+ jr t0
+0:
.endm
#endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
diff --git a/include/asm-mips/mach-pb1x00/pb1200.h b/include/asm-mips/mach-pb1x00/pb1200.h
index 409d443322c..d9f384acfea 100644
--- a/include/asm-mips/mach-pb1x00/pb1200.h
+++ b/include/asm-mips/mach-pb1x00/pb1200.h
@@ -217,31 +217,35 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
/*
- * External Interrupts for Pb1200 as of 8/6/2004.
- * Bit positions in the CPLD registers can be calculated by taking
- * the interrupt define and subtracting the PB1200_INT_BEGIN value.
- * *example: IDE bis pos is = 64 - 64
- ETH bit pos is = 65 - 64
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the PB1200_INT_BEGIN value.
+ *
+ * Example: IDE bis pos is = 64 - 64
+ * ETH bit pos is = 65 - 64
*/
-#define PB1200_INT_BEGIN (AU1000_LAST_INTC1_INT + 1)
-#define PB1200_IDE_INT (PB1200_INT_BEGIN + 0)
-#define PB1200_ETH_INT (PB1200_INT_BEGIN + 1)
-#define PB1200_PC0_INT (PB1200_INT_BEGIN + 2)
-#define PB1200_PC0_STSCHG_INT (PB1200_INT_BEGIN + 3)
-#define PB1200_PC1_INT (PB1200_INT_BEGIN + 4)
-#define PB1200_PC1_STSCHG_INT (PB1200_INT_BEGIN + 5)
-#define PB1200_DC_INT (PB1200_INT_BEGIN + 6)
-#define PB1200_FLASHBUSY_INT (PB1200_INT_BEGIN + 7)
-#define PB1200_PC0_INSERT_INT (PB1200_INT_BEGIN + 8)
-#define PB1200_PC0_EJECT_INT (PB1200_INT_BEGIN + 9)
-#define PB1200_PC1_INSERT_INT (PB1200_INT_BEGIN + 10)
-#define PB1200_PC1_EJECT_INT (PB1200_INT_BEGIN + 11)
-#define PB1200_SD0_INSERT_INT (PB1200_INT_BEGIN + 12)
-#define PB1200_SD0_EJECT_INT (PB1200_INT_BEGIN + 13)
-#define PB1200_SD1_INSERT_INT (PB1200_INT_BEGIN + 14)
-#define PB1200_SD1_EJECT_INT (PB1200_INT_BEGIN + 15)
-
-#define PB1200_INT_END (PB1200_INT_BEGIN + 15)
+enum external_pb1200_ints {
+ PB1200_INT_BEGIN = AU1000_MAX_INTR + 1,
+
+ PB1200_IDE_INT = PB1200_INT_BEGIN,
+ PB1200_ETH_INT,
+ PB1200_PC0_INT,
+ PB1200_PC0_STSCHG_INT,
+ PB1200_PC1_INT,
+ PB1200_PC1_STSCHG_INT,
+ PB1200_DC_INT,
+ PB1200_FLASHBUSY_INT,
+ PB1200_PC0_INSERT_INT,
+ PB1200_PC0_EJECT_INT,
+ PB1200_PC1_INSERT_INT,
+ PB1200_PC1_EJECT_INT,
+ PB1200_SD0_INSERT_INT,
+ PB1200_SD0_EJECT_INT,
+ PB1200_SD1_INSERT_INT,
+ PB1200_SD1_EJECT_INT,
+
+ PB1200_INT_END (PB1200_INT_BEGIN + 15)
+};
/* For drivers/pcmcia/au1000_db1x00.c */
#define BOARD_PC0_INT PB1200_PC0_INT
diff --git a/include/asm-mips/pmc-sierra/msp71xx/war.h b/include/asm-mips/pmc-sierra/msp71xx/war.h
new file mode 100644
index 00000000000..0bf48fc1892
--- /dev/null
+++ b/include/asm-mips/pmc-sierra/msp71xx/war.h
@@ -0,0 +1,28 @@
+/*
+ * 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_PMC_SIERRA_WAR_H
+#define __ASM_MIPS_PMC_SIERRA_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+ defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR 1
+#endif
+
+#endif /* __ASM_MIPS_PMC_SIERRA_WAR_H */
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 85b44366343..786f7e3c99b 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -86,9 +86,9 @@ struct pt_regs {
extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
-extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
+extern NORET_TYPE void die(const char *, const struct pt_regs *) ATTRIB_NORET;
-static inline void die_if_kernel(const char *str, struct pt_regs *regs)
+static inline void die_if_kernel(const char *str, const struct pt_regs *regs)
{
if (unlikely(!user_mode(regs)))
die(str, regs);
diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h
index 080daa77f86..fdf8042b784 100644
--- a/include/asm-mips/semaphore.h
+++ b/include/asm-mips/semaphore.h
@@ -49,7 +49,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
static inline void sema_init(struct semaphore *sem, int val)
{
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 35555bd5c52..cf76f4f7435 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -40,7 +40,6 @@ extern int rtc_mips_set_mmss(unsigned long);
* mips_timer_ack may be NULL if the interrupt is self-recoverable.
*/
extern int (*mips_timer_state)(void);
-extern void (*mips_timer_ack)(void);
/*
* High precision timer clocksource.
@@ -76,6 +75,12 @@ extern int (*perf_irq)(void);
/*
* Initialize the calling CPU's compare interrupt as clockevent device
*/
+#ifdef CONFIG_CEVT_R4K
extern void mips_clockevent_init(void);
+#else
+static inline void mips_clockevent_init(void)
+{
+}
+#endif
#endif /* _ASM_TIME_H */
diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h
index 63a13c5bd83..2dd147f519d 100644
--- a/include/asm-mips/types.h
+++ b/include/asm-mips/types.h
@@ -34,9 +34,9 @@ typedef unsigned long __u64;
#else
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif
diff --git a/include/asm-mips/xxs1500.h b/include/asm-mips/xxs1500.h
deleted file mode 100644
index 4d84a90b0f2..00000000000
--- a/include/asm-mips/xxs1500.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * MyCable XXS1500 Referrence Board
- *
- * Copyright 2003 MontaVista Software Inc.
- * Author: Pete Popov, MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * ########################################################################
- *
- * This program is free software; you can distribute 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 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.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_XXS1500_H
-#define __ASM_XXS1500_H
-
-/* PCMCIA XXS1500 specific defines */
-#define PCMCIA_MAX_SOCK 0
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
-#define PCMCIA_IRQ AU1000_GPIO_4
-
-#endif /* __ASM_XXS1500_ */
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index 015cb0d379b..03ae287baf8 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -208,6 +208,7 @@ static __inline__ int fls(int x)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#endif /* __KERNEL__ */
diff --git a/include/asm-parisc/floppy.h b/include/asm-parisc/floppy.h
index da2f9c15714..4ca69f558fa 100644
--- a/include/asm-parisc/floppy.h
+++ b/include/asm-parisc/floppy.h
@@ -266,10 +266,6 @@ static int FDC2 = -1;
#define N_FDC 1
#define N_DRIVE 8
-#define FLOPPY_MOTOR_MASK 0xf0
-
-#define AUTO_DMA
-
#define EXTRA_FLOPPY_PARAMS
#endif /* __ASM_PARISC_FLOPPY_H */
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index 4cc9bcec056..95f00e11c7b 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -270,11 +270,6 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
/* IO Port space is : BBiiii where BB is HBA number. */
#define IO_SPACE_LIMIT 0x00ffffff
-
-#define dma_cache_inv(_start,_size) do { flush_kernel_dcache_range(_start,_size); } while (0)
-#define dma_cache_wback(_start,_size) do { flush_kernel_dcache_range(_start,_size); } while (0)
-#define dma_cache_wback_inv(_start,_size) do { flush_kernel_dcache_range(_start,_size); } while (0)
-
/* PA machines have an MM I/O space from 0xf0000000-0xffffffff in 32
* bit mode and from 0xfffffffff0000000-0xfffffffffffffff in 64 bit
* mode (essentially just sign extending. This macro takes in a 32
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index d45827a21f9..b771dcfcfdd 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -53,7 +53,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
extern inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-parisc/types.h b/include/asm-parisc/types.h
index d4aa33033d9..56c84802da5 100644
--- a/include/asm-parisc/types.h
+++ b/include/asm-parisc/types.h
@@ -19,9 +19,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild
index 4869513b872..5f640e54247 100644
--- a/include/asm-powerpc/Kbuild
+++ b/include/asm-powerpc/Kbuild
@@ -13,9 +13,7 @@ header-y += shmbuf.h
header-y += socket.h
header-y += termbits.h
header-y += fcntl.h
-header-y += ipc.h
header-y += poll.h
-header-y += shmparam.h
header-y += sockios.h
header-y += ucontext.h
header-y += ioctl.h
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 8144a2788db..e85c3e078ba 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -86,6 +86,24 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
: "cc" );
}
+static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+ unsigned long old;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+ LWSYNC_ON_SMP
+"1:" PPC_LLARX "%0,0,%3 # clear_bit_unlock\n"
+ "andc %0,%0,%2\n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%0,0,%3\n"
+ "bne- 1b"
+ : "=&r" (old), "+m" (*p)
+ : "r" (mask), "r" (p)
+ : "cc", "memory");
+}
+
static __inline__ void change_bit(int nr, volatile unsigned long *addr)
{
unsigned long old;
@@ -125,6 +143,27 @@ static __inline__ int test_and_set_bit(unsigned long nr,
return (old & mask) != 0;
}
+static __inline__ int test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned long old, t;
+ unsigned long mask = BITOP_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%3 # test_and_set_bit_lock\n"
+ "or %1,%0,%2 \n"
+ PPC405_ERR77(0,%3)
+ PPC_STLCX "%1,0,%3 \n"
+ "bne- 1b"
+ ISYNC_ON_SMP
+ : "=&r" (old), "=&r" (t)
+ : "r" (mask), "r" (p)
+ : "cc", "memory");
+
+ return (old & mask) != 0;
+}
+
static __inline__ int test_and_clear_bit(unsigned long nr,
volatile unsigned long *addr)
{
@@ -185,6 +224,12 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
#include <asm-generic/bitops/non-atomic.h>
+static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr)
+{
+ __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory");
+ __clear_bit(nr, addr);
+}
+
/*
* Return the zero-based bit position (LE, not IBM bit numbering) of
* the most significant 1-bit in a double word.
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index ae093ef6836..9d74338e3de 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -165,6 +165,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000)
#define CPU_FTR_DSCR LONG_ASM_CONST(0x0002000000000000)
#define CPU_FTR_1T_SEGMENT LONG_ASM_CONST(0x0004000000000000)
+#define CPU_FTR_NO_SLBIE_B LONG_ASM_CONST(0x0008000000000000)
#ifndef __ASSEMBLY__
@@ -367,7 +368,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
- CPU_FTR_PURR | CPU_FTR_REAL_LE)
+ CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
diff --git a/include/asm-powerpc/dcr-mmio.h b/include/asm-powerpc/dcr-mmio.h
index 6b82c3ba495..08532ff1899 100644
--- a/include/asm-powerpc/dcr-mmio.h
+++ b/include/asm-powerpc/dcr-mmio.h
@@ -33,16 +33,16 @@ typedef struct {
extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
unsigned int dcr_c);
-extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c);
+extern void dcr_unmap(dcr_host_t host, unsigned int dcr_c);
static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n)
{
- return in_be32(host.token + dcr_n * host.stride);
+ return in_be32(host.token + ((host.base + dcr_n) * host.stride));
}
static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value)
{
- out_be32(host.token + dcr_n * host.stride, value);
+ out_be32(host.token + ((host.base + dcr_n) * host.stride), value);
}
extern u64 of_translate_dcr_address(struct device_node *dev,
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h
index f41058c0f6c..8dbb1ab0aa0 100644
--- a/include/asm-powerpc/dcr-native.h
+++ b/include/asm-powerpc/dcr-native.h
@@ -29,9 +29,9 @@ typedef struct {
#define DCR_MAP_OK(host) (1)
#define dcr_map(dev, dcr_n, dcr_c) ((dcr_host_t){ .base = (dcr_n) })
-#define dcr_unmap(host, dcr_n, dcr_c) do {} while (0)
-#define dcr_read(host, dcr_n) mfdcr(dcr_n)
-#define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value)
+#define dcr_unmap(host, dcr_c) do {} while (0)
+#define dcr_read(host, dcr_n) mfdcr(dcr_n + host.base)
+#define dcr_write(host, dcr_n, value) mtdcr(dcr_n + host.base, value)
/* Device Control Registers */
void __mtdcr(int reg, unsigned int val);
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index d05891608f7..65be95dd03a 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -12,7 +12,7 @@
#include <linux/cache.h>
/* need struct page definitions */
#include <linux/mm.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
@@ -276,14 +276,15 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
}
static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
+ struct scatterlist *sg;
int i;
BUG_ON(direction == DMA_NONE);
- for (i = 0; i < nents; i++, sg++) {
+ for_each_sg(sgl, sg, nents, i) {
BUG_ON(!sg->page);
__dma_sync_page(sg->page, sg->offset, sg->length, direction);
sg->dma_address = page_to_bus(sg->page) + sg->offset;
@@ -318,26 +319,28 @@ static inline void dma_sync_single_for_device(struct device *dev,
}
static inline void dma_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sg, int nents,
+ struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
+ struct scatterlist *sg;
int i;
BUG_ON(direction == DMA_NONE);
- for (i = 0; i < nents; i++, sg++)
+ for_each_sg(sgl, sg, nents, i)
__dma_sync_page(sg->page, sg->offset, sg->length, direction);
}
static inline void dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sg, int nents,
+ struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
+ struct scatterlist *sg;
int i;
BUG_ON(direction == DMA_NONE);
- for (i = 0; i < nents; i++, sg++)
+ for_each_sg(sgl, sg, nents, i)
__dma_sync_page(sg->page, sg->offset, sg->length, direction);
}
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index e42820d6d25..6bd07ef78ac 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -101,6 +101,7 @@ typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];
typedef unsigned int elf_greg_t32;
typedef elf_greg_t32 elf_gregset_t32[ELF_NGREG];
+typedef elf_gregset_t32 compat_elf_gregset_t;
/*
* ELF_ARCH, CLASS, and DATA are used to set parameters in the core dumps.
@@ -175,26 +176,27 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
#define ELF_ET_DYN_BASE (0x20000000)
-/* Common routine for both 32-bit and 64-bit processes */
+/*
+ * Our registers are always unsigned longs, whether we're a 32 bit
+ * process or 64 bit, on either a 64 bit or 32 bit kernel.
+ *
+ * This macro relies on elf_regs[i] having the right type to truncate to,
+ * either u32 or u64. It defines the body of the elf_core_copy_regs
+ * function, either the native one with elf_gregset_t elf_regs or
+ * the 32-bit one with elf_gregset_t32 elf_regs.
+ */
+#define PPC_ELF_CORE_COPY_REGS(elf_regs, regs) \
+ int i, nregs = min(sizeof(*regs) / sizeof(unsigned long), \
+ (size_t)ELF_NGREG); \
+ for (i = 0; i < nregs; i++) \
+ elf_regs[i] = ((unsigned long *) regs)[i]; \
+ memset(&elf_regs[i], 0, (ELF_NGREG - i) * sizeof(elf_regs[0]))
+
+/* Common routine for both 32-bit and 64-bit native processes */
static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
- struct pt_regs *regs)
+ struct pt_regs *regs)
{
- int i, nregs;
-
- memset((void *)elf_regs, 0, sizeof(elf_gregset_t));
-
- /* Our registers are always unsigned longs, whether we're a 32 bit
- * process or 64 bit, on either a 64 bit or 32 bit kernel.
- * Don't use ELF_GREG_TYPE here. */
- nregs = sizeof(struct pt_regs) / sizeof(unsigned long);
- if (nregs > ELF_NGREG)
- nregs = ELF_NGREG;
-
- for (i = 0; i < nregs; i++) {
- /* This will correctly truncate 64 bit registers to 32 bits
- * for a 32 bit process on a 64 bit kernel. */
- elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i];
- }
+ PPC_ELF_CORE_COPY_REGS(elf_regs, regs);
}
#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
@@ -212,6 +214,14 @@ static inline int dump_task_regs(struct task_struct *tsk,
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+typedef elf_vrregset_t elf_fpxregset_t;
+
+#ifdef CONFIG_ALTIVEC
+extern int dump_task_altivec(struct task_struct *, elf_vrregset_t *vrregs);
+#define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_altivec(tsk, regs)
+#define ELF_CORE_XFPREG_TYPE NT_PPC_VMX
+#endif
+
#endif /* __KERNEL__ */
/* ELF_HWCAP yields a mask that user programs can use to figure out what
@@ -281,6 +291,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
* AT_IGNOREPPC is used for that.
* - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
* even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
*/
#define ARCH_DLINFO \
do { \
diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
index 34146f0eea6..24bd34c57e9 100644
--- a/include/asm-powerpc/floppy.h
+++ b/include/asm-powerpc/floppy.h
@@ -202,8 +202,6 @@ static int FDC2 = -1;
#define N_FDC 2 /* Don't change this! */
#define N_DRIVE 8
-#define FLOPPY_MOTOR_MASK 0xf0
-
/*
* The PowerPC has no problems with floppy DMA crossing 64k borders.
*/
diff --git a/include/asm-powerpc/ibmebus.h b/include/asm-powerpc/ibmebus.h
index 87d396e28db..1a9d9aea21f 100644
--- a/include/asm-powerpc/ibmebus.h
+++ b/include/asm-powerpc/ibmebus.h
@@ -43,42 +43,18 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
-#include <asm/of_device.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
extern struct bus_type ibmebus_bus_type;
-struct ibmebus_dev {
- struct of_device ofdev;
-};
+int ibmebus_register_driver(struct of_platform_driver *drv);
+void ibmebus_unregister_driver(struct of_platform_driver *drv);
-struct ibmebus_driver {
- char *name;
- struct of_device_id *id_table;
- int (*probe) (struct ibmebus_dev *dev, const struct of_device_id *id);
- int (*remove) (struct ibmebus_dev *dev);
- struct device_driver driver;
-};
-
-int ibmebus_register_driver(struct ibmebus_driver *drv);
-void ibmebus_unregister_driver(struct ibmebus_driver *drv);
-
-int ibmebus_request_irq(struct ibmebus_dev *dev,
- u32 ist,
- irq_handler_t handler,
- unsigned long irq_flags, const char * devname,
+int ibmebus_request_irq(u32 ist, irq_handler_t handler,
+ unsigned long irq_flags, const char *devname,
void *dev_id);
-void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id);
-
-static inline struct ibmebus_driver *to_ibmebus_driver(struct device_driver *drv)
-{
- return container_of(drv, struct ibmebus_driver, driver);
-}
-
-static inline struct ibmebus_dev *to_ibmebus_dev(struct device *dev)
-{
- return container_of(dev, struct ibmebus_dev, ofdev.dev);
-}
-
+void ibmebus_free_irq(u32 ist, void *dev_id);
#endif /* __KERNEL__ */
#endif /* _ASM_IBMEBUS_H */
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 0d0589ef8ea..bf14ab4ef4c 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -498,23 +498,6 @@ static inline void name at \
#define writeq writeq
#endif
-#ifdef CONFIG_NOT_COHERENT_CACHE
-
-#define dma_cache_inv(_start,_size) \
- invalidate_dcache_range(_start, (_start + _size))
-#define dma_cache_wback(_start,_size) \
- clean_dcache_range(_start, (_start + _size))
-#define dma_cache_wback_inv(_start,_size) \
- flush_dcache_range(_start, (_start + _size))
-
-#else /* CONFIG_NOT_COHERENT_CACHE */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
-#endif /* !CONFIG_NOT_COHERENT_CACHE */
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/include/asm-powerpc/ipc.h b/include/asm-powerpc/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-powerpc/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index 295f0162c60..ae6d206728a 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -2,25 +2,6 @@
#define _ASM_POWERPC_KDEBUG_H
#ifdef __KERNEL__
-/* nearly identical to x86_64/i386 code */
-
-#include <linux/notifier.h>
-
-/*
- * These are only here because kprobes.c wants them to implement a
- * blatant layering violation. Will hopefully go away soon once all
- * architectures are updated.
- */
-static inline int register_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-static inline int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-extern struct atomic_notifier_head powerpc_die_chain;
-
/* Grossly misnamed. */
enum die_val {
DIE_OOPS = 1,
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index 8b08b447d6f..afabad230db 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -81,8 +81,8 @@ typedef unsigned int kprobe_opcode_t;
#endif
#define ARCH_SUPPORTS_KRETPROBES
-#define ARCH_INACTIVE_KPROBE_COUNT 1
#define flush_insn_slot(p) do { } while (0)
+#define kretprobe_blacklist_size 0
void kretprobe_trampoline(void);
extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 24751df791a..568135fe52e 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -18,6 +18,8 @@
#include <asm/prom.h>
#endif /* __ASSEMBLY__ */
+#include <linux/suspend.h>
+
/* ======================================================================== */
/* Structures mapping of some unit register set */
@@ -267,9 +269,9 @@ extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
extern int __init lite5200_pm_init(void);
/* lite5200 calls mpc5200 suspend functions, so here they are */
-extern int mpc52xx_pm_prepare(suspend_state_t);
+extern int mpc52xx_pm_prepare(void);
extern int mpc52xx_pm_enter(suspend_state_t);
-extern int mpc52xx_pm_finish(suspend_state_t);
+extern void mpc52xx_pm_finish(void);
extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */
#endif
#endif /* CONFIG_PM */
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index 93262f2546a..6526e139a46 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -17,6 +17,10 @@ struct of_device
struct device dev; /* Generic device interface */
};
+extern struct of_device *of_device_alloc(struct device_node *np,
+ const char *bus_id,
+ struct device *parent);
+
extern ssize_t of_device_get_modalias(struct of_device *ofdev,
char *str, ssize_t len);
extern int of_device_uevent(struct device *dev,
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index fcd7b428ed0..98c6bd5756b 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -114,6 +114,9 @@ struct paca_struct {
u64 user_time; /* accumulated usermode TB ticks */
u64 system_time; /* accumulated system TB ticks */
u64 startpurr; /* PURR/TB value snapshot */
+ u64 startspurr; /* SPURR value snapshot */
+ u64 purrdelta; /* FIXME: document */
+ u64 spurrdelta; /* FIXME: document */
};
extern struct paca_struct paca[];
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h
index 300f9a199bf..dd4c26dc57d 100644
--- a/include/asm-powerpc/pgtable-ppc64.h
+++ b/include/asm-powerpc/pgtable-ppc64.h
@@ -68,6 +68,14 @@
#define USER_REGION_ID (0UL)
/*
+ * Defines the address of the vmemap area, in the top 16th of the
+ * kernel region.
+ */
+#define VMEMMAP_BASE (ASM_CONST(CONFIG_KERNEL_START) + \
+ (0xfUL << (REGION_SHIFT - 4)))
+#define vmemmap ((struct page *)VMEMMAP_BASE)
+
+/*
* Common bits in a linux-style PTE. These match the bits in the
* (hardware-defined) PowerPC PTE as closely as possible. Additional
* bits may be defined in pgtable-*.h
diff --git a/include/asm-powerpc/ps3av.h b/include/asm-powerpc/ps3av.h
index 7df4250802d..967930b82ed 100644
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -283,7 +283,7 @@
#define PS3AV_CMD_VIDEO_CS_YUV422 0x0002
#define PS3AV_CMD_VIDEO_CS_YUV444 0x0003
-/* for automode */
+/* for broadcast automode */
#define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */
#define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */
#define PS3AV_RESBIT_1280x720P 0x0004
@@ -298,13 +298,22 @@
| PS3AV_RESBIT_1920x1080I \
| PS3AV_RESBIT_1920x1080P)
+/* for VESA automode */
+#define PS3AV_RESBIT_VGA 0x0001
+#define PS3AV_RESBIT_WXGA 0x0002
+#define PS3AV_RESBIT_SXGA 0x0004
+#define PS3AV_RESBIT_WUXGA 0x0008
+#define PS3AV_RES_MASK_VESA (PS3AV_RESBIT_WXGA |\
+ PS3AV_RESBIT_SXGA |\
+ PS3AV_RESBIT_WUXGA)
+
#define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */
#define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */
-#define PS3AV_DEFAULT_HDMI_VID_REG_60 PS3AV_CMD_VIDEO_VID_480P
-#define PS3AV_DEFAULT_AVMULTI_VID_REG_60 PS3AV_CMD_VIDEO_VID_480I
-#define PS3AV_DEFAULT_HDMI_VID_REG_50 PS3AV_CMD_VIDEO_VID_576P
-#define PS3AV_DEFAULT_AVMULTI_VID_REG_50 PS3AV_CMD_VIDEO_VID_576I
-#define PS3AV_DEFAULT_DVI_VID PS3AV_CMD_VIDEO_VID_480P
+
+#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60 2 /* 480p */
+#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60 1 /* 480i */
+#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50 7 /* 576p */
+#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50 6 /* 576i */
#define PS3AV_REGION_60 0x01
#define PS3AV_REGION_50 0x02
@@ -697,20 +706,12 @@ extern int ps3av_cmd_audio_mute(int, u32 *, u32);
extern int ps3av_cmd_audio_active(int, u32);
extern int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *, u32);
extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *);
-#ifdef PS3AV_DEBUG
-extern void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *);
-extern void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *);
-#else
-static inline void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf) {}
-static inline void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info) {}
-#endif
extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
u32);
-extern int ps3av_set_video_mode(u32, int);
+extern int ps3av_set_video_mode(u32);
extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
-extern int ps3av_get_auto_mode(int);
-extern int ps3av_set_mode(u32, int);
+extern int ps3av_get_auto_mode(void);
extern int ps3av_get_mode(void);
extern int ps3av_get_scanmode(int);
extern int ps3av_get_refresh_rate(int);
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index 8c992d1491d..b075f619c3b 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -41,5 +41,7 @@ struct scatterlist {
#define ISA_DMA_THRESHOLD (~0UL)
#endif
+#define ARCH_HAS_SG_CHAIN
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SCATTERLIST_H */
diff --git a/include/asm-powerpc/semaphore.h b/include/asm-powerpc/semaphore.h
index 57369d2cade..48dd32e0774 100644
--- a/include/asm-powerpc/semaphore.h
+++ b/include/asm-powerpc/semaphore.h
@@ -35,7 +35,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h
index 19102bfc14c..505f35bacaa 100644
--- a/include/asm-powerpc/smp.h
+++ b/include/asm-powerpc/smp.h
@@ -26,6 +26,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#endif
+#include <asm/percpu.h>
extern int boot_cpuid;
@@ -58,7 +59,7 @@ extern int smp_hw_index[];
(smp_hw_index[(cpu)] = (phys))
#endif
-extern cpumask_t cpu_sibling_map[NR_CPUS];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
*
@@ -77,6 +78,7 @@ void smp_init_pSeries(void);
void smp_init_cell(void);
void smp_init_celleb(void);
void smp_setup_cpu_maps(void);
+void smp_setup_cpu_sibling_map(void);
extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index d10e99bf500..87be8c3bc9c 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -40,6 +40,7 @@
#define set_mb(var, value) do { var = value; mb(); } while (0)
#ifdef __KERNEL__
+#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-powerpc/topology.h b/include/asm-powerpc/topology.h
index 0ad21a849b5..ca23b681ad0 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -108,7 +108,7 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev,
#ifdef CONFIG_PPC64
#include <asm/smp.h>
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#endif
#endif
diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h
index a584341c87e..903fd193243 100644
--- a/include/asm-powerpc/types.h
+++ b/include/asm-powerpc/types.h
@@ -40,9 +40,9 @@ typedef unsigned int __u32;
typedef __signed__ long __s64;
typedef unsigned long __u64;
#else
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __powerpc64__ */
diff --git a/include/asm-ppc/floppy.h b/include/asm-ppc/floppy.h
index ae316e6d2ca..7d9b3f430d9 100644
--- a/include/asm-ppc/floppy.h
+++ b/include/asm-ppc/floppy.h
@@ -166,8 +166,6 @@ static int FDC2 = -1;
#define N_FDC 2 /* Don't change this! */
#define N_DRIVE 8
-#define FLOPPY_MOTOR_MASK 0xf0
-
/*
* The PowerPC has no problems with floppy DMA crossing 64k borders.
*/
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 8f58231a8bc..a0d409a5d80 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -478,23 +478,6 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#include <asm/mpc8260_pci9.h>
#endif
-#ifdef CONFIG_NOT_COHERENT_CACHE
-
-#define dma_cache_inv(_start,_size) \
- invalidate_dcache_range(_start, (_start + _size))
-#define dma_cache_wback(_start,_size) \
- clean_dcache_range(_start, (_start + _size))
-#define dma_cache_wback_inv(_start,_size) \
- flush_dcache_range(_start, (_start + _size))
-
-#else
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
-#endif
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/include/asm-ppc/irq_regs.h b/include/asm-ppc/irq_regs.h
new file mode 100644
index 00000000000..3dd9c0b7027
--- /dev/null
+++ b/include/asm-ppc/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-ppc/mpc52xx_psc.h b/include/asm-ppc/mpc52xx_psc.h
index 9d850b2b20b..c82b8d49a7d 100644
--- a/include/asm-ppc/mpc52xx_psc.h
+++ b/include/asm-ppc/mpc52xx_psc.h
@@ -28,6 +28,10 @@
#define MPC52xx_PSC_MAXNUM 6
/* Programmable Serial Controller (PSC) status register bits */
+#define MPC52xx_PSC_SR_UNEX_RX 0x0001
+#define MPC52xx_PSC_SR_DATA_VAL 0x0002
+#define MPC52xx_PSC_SR_DATA_OVR 0x0004
+#define MPC52xx_PSC_SR_CMDSEND 0x0008
#define MPC52xx_PSC_SR_CDE 0x0080
#define MPC52xx_PSC_SR_RXRDY 0x0100
#define MPC52xx_PSC_SR_RXFULL 0x0200
@@ -132,8 +136,10 @@ struct mpc52xx_psc {
u8 reserved5[3];
u8 ctlr; /* PSC + 0x1c */
u8 reserved6[3];
- u16 ccr; /* PSC + 0x20 */
- u8 reserved7[14];
+ u32 ccr; /* PSC + 0x20 */
+ u32 ac97_slots; /* PSC + 0x24 */
+ u32 ac97_cmd; /* PSC + 0x28 */
+ u32 ac97_data; /* PSC + 0x2c */
u8 ivr; /* PSC + 0x30 */
u8 reserved8[3];
u8 ip; /* PSC + 0x34 */
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h
index f7eadf6ac80..81dbcd43a50 100644
--- a/include/asm-ppc/time.h
+++ b/include/asm-ppc/time.h
@@ -57,7 +57,7 @@ static __inline__ void set_dec(unsigned int val)
/* Accessor functions for the timebase (RTC on 601) registers. */
/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
#ifdef CONFIG_6xx
-extern __inline__ int __attribute_pure__ __USE_RTC(void) {
+extern __inline__ int __pure __USE_RTC(void) {
return (mfspr(SPRN_PVR)>>16) == 1;
}
#else
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index f79c9b792af..d756b34d25f 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -746,6 +746,7 @@ static inline int sched_find_first_bit(unsigned long *b)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
/*
* ATTENTION: intel byte ordering convention for ext2 and minix !!
diff --git a/include/asm-s390/ipc.h b/include/asm-s390/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-s390/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h
index 04418af08f8..40db27cd6e6 100644
--- a/include/asm-s390/kdebug.h
+++ b/include/asm-s390/kdebug.h
@@ -4,24 +4,9 @@
/*
* Feb 2006 Ported to s390 <grundym@us.ibm.com>
*/
-#include <linux/notifier.h>
struct pt_regs;
-/*
- * These are only here because kprobes.c wants them to implement a
- * blatant layering violation. Will hopefully go away soon once all
- * architectures are updated.
- */
-static inline int register_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-static inline int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-
enum die_val {
DIE_OOPS = 1,
DIE_BPT,
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h
index 340ba10446e..948db3d0d05 100644
--- a/include/asm-s390/kprobes.h
+++ b/include/asm-s390/kprobes.h
@@ -47,7 +47,7 @@ typedef u16 kprobe_opcode_t;
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
#define ARCH_SUPPORTS_KRETPROBES
-#define ARCH_INACTIVE_KPROBE_COUNT 0
+#define kretprobe_blacklist_size 0
#define KPROBE_SWAP_INST 0x10
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h
index dbce058aefa..0e7001ad839 100644
--- a/include/asm-s390/semaphore.h
+++ b/include/asm-s390/semaphore.h
@@ -33,7 +33,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h
index fc5d7cf1932..2c5879ae90c 100644
--- a/include/asm-s390/types.h
+++ b/include/asm-s390/types.h
@@ -28,9 +28,9 @@ typedef __signed__ int __s32;
typedef unsigned int __u32;
#ifndef __s390x__
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#else /* __s390x__ */
typedef __signed__ long __s64;
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h
index 1c16792cee1..9d7021723a2 100644
--- a/include/asm-sh/bitops.h
+++ b/include/asm-sh/bitops.h
@@ -137,6 +137,7 @@ static inline unsigned long __ffs(unsigned long word)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 43ca244564b..12cc4b392bf 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -133,6 +133,7 @@ extern void __kernel_vsyscall;
#define VDSO_BASE ((unsigned long)current->mm->context.vdso)
#define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x))
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \
do { \
if (vdso_enabled) \
diff --git a/include/asm-sh/floppy.h b/include/asm-sh/floppy.h
index 3b59b3af777..59fbfdc90df 100644
--- a/include/asm-sh/floppy.h
+++ b/include/asm-sh/floppy.h
@@ -213,7 +213,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
}
#endif
- dma_cache_wback_inv(addr, size);
+ __flush_purge_region(addr, size);
/* actual, physical DMA */
doing_pdma = 0;
@@ -263,10 +263,6 @@ static int FDC2 = -1;
#define N_FDC 2
#define N_DRIVE 8
-#define FLOPPY_MOTOR_MASK 0xf0
-
-#define AUTO_DMA
-
#define EXTRA_FLOPPY_PARAMS
#endif /* __ASM_SH_FLOPPY_H */
diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h
index 1a336cdc75f..6ed34d8eac5 100644
--- a/include/asm-sh/io.h
+++ b/include/asm-sh/io.h
@@ -327,31 +327,6 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
__iounmap((addr))
/*
- * The caches on some architectures aren't dma-coherent and have need to
- * handle this in software. There are three types of operations that
- * can be applied to dma buffers.
- *
- * - dma_cache_wback_inv(start, size) makes caches and RAM coherent by
- * writing the content of the caches back to memory, if necessary.
- * The function also invalidates the affected part of the caches as
- * necessary before DMA transfers from outside to memory.
- * - dma_cache_inv(start, size) invalidates the affected parts of the
- * caches. Dirty lines of the caches may be written back or simply
- * be discarded. This operation is necessary before dma operations
- * to the memory.
- * - dma_cache_wback(start, size) writes back any dirty lines but does
- * not invalidate the cache. This can be used before DMA reads from
- * memory,
- */
-
-#define dma_cache_wback_inv(_start,_size) \
- __flush_purge_region(_start,_size)
-#define dma_cache_inv(_start,_size) \
- __flush_invalidate_region(_start,_size)
-#define dma_cache_wback(_start,_size) \
- __flush_wback_region(_start,_size)
-
-/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
*/
diff --git a/include/asm-sh/ipc.h b/include/asm-sh/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-sh/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h
index 382cfc7deb7..49cd69051a8 100644
--- a/include/asm-sh/kdebug.h
+++ b/include/asm-sh/kdebug.h
@@ -1,8 +1,6 @@
#ifndef __ASM_SH_KDEBUG_H
#define __ASM_SH_KDEBUG_H
-#include <linux/notifier.h>
-
/* Grossly misnamed. */
enum die_val {
DIE_TRAP,
diff --git a/include/asm-sh/semaphore.h b/include/asm-sh/semaphore.h
index 489f7847c5d..9e5a37c4dce 100644
--- a/include/asm-sh/semaphore.h
+++ b/include/asm-sh/semaphore.h
@@ -37,7 +37,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 9d849e6df26..4faa2fb8861 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -15,6 +15,7 @@
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next);
+#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */
/*
* switch_to() should switch tasks to task nr n, first
*/
diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h
index fd00dbb82f8..7ba69d9707e 100644
--- a/include/asm-sh/types.h
+++ b/include/asm-sh/types.h
@@ -19,9 +19,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h
index f3bdcdb5d04..444d5ea92ce 100644
--- a/include/asm-sh64/bitops.h
+++ b/include/asm-sh64/bitops.h
@@ -136,6 +136,7 @@ static __inline__ unsigned long ffz(unsigned long word)
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index de430996020..e661857f98d 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -42,7 +42,11 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir)
{
- dma_cache_wback_inv((unsigned long)vaddr, size);
+ unsigned long s = (unsigned long) vaddr & L1_CACHE_ALIGN_MASK;
+ unsigned long e = (vaddr + size) & L1_CACHE_ALIGN_MASK;
+
+ for (; s <= e; s += L1_CACHE_BYTES)
+ asm volatile ("ocbp %0, 0" : : "r" (s));
}
static inline dma_addr_t dma_map_single(struct device *dev,
diff --git a/include/asm-sh64/io.h b/include/asm-sh64/io.h
index 3de3ad99f45..7bd7314d38c 100644
--- a/include/asm-sh64/io.h
+++ b/include/asm-sh64/io.h
@@ -182,54 +182,6 @@ unsigned long onchip_remap(unsigned long addr, unsigned long size, const char* n
extern void onchip_unmap(unsigned long vaddr);
/*
- * The caches on some architectures aren't dma-coherent and have need to
- * handle this in software. There are three types of operations that
- * can be applied to dma buffers.
- *
- * - dma_cache_wback_inv(start, size) makes caches and RAM coherent by
- * writing the content of the caches back to memory, if necessary.
- * The function also invalidates the affected part of the caches as
- * necessary before DMA transfers from outside to memory.
- * - dma_cache_inv(start, size) invalidates the affected parts of the
- * caches. Dirty lines of the caches may be written back or simply
- * be discarded. This operation is necessary before dma operations
- * to the memory.
- * - dma_cache_wback(start, size) writes back any dirty lines but does
- * not invalidate the cache. This can be used before DMA reads from
- * memory,
- */
-
-static __inline__ void dma_cache_wback_inv (unsigned long start, unsigned long size)
-{
- unsigned long s = start & L1_CACHE_ALIGN_MASK;
- unsigned long e = (start + size) & L1_CACHE_ALIGN_MASK;
-
- for (; s <= e; s += L1_CACHE_BYTES)
- asm volatile ("ocbp %0, 0" : : "r" (s));
-}
-
-static __inline__ void dma_cache_inv (unsigned long start, unsigned long size)
-{
- // Note that caller has to be careful with overzealous
- // invalidation should there be partial cache lines at the extremities
- // of the specified range
- unsigned long s = start & L1_CACHE_ALIGN_MASK;
- unsigned long e = (start + size) & L1_CACHE_ALIGN_MASK;
-
- for (; s <= e; s += L1_CACHE_BYTES)
- asm volatile ("ocbi %0, 0" : : "r" (s));
-}
-
-static __inline__ void dma_cache_wback (unsigned long start, unsigned long size)
-{
- unsigned long s = start & L1_CACHE_ALIGN_MASK;
- unsigned long e = (start + size) & L1_CACHE_ALIGN_MASK;
-
- for (; s <= e; s += L1_CACHE_BYTES)
- asm volatile ("ocbwb %0, 0" : : "r" (s));
-}
-
-/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
*/
diff --git a/include/asm-sh64/ipc.h b/include/asm-sh64/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-sh64/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-sh64/semaphore.h b/include/asm-sh64/semaphore.h
index 46952645914..f027cc14b55 100644
--- a/include/asm-sh64/semaphore.h
+++ b/include/asm-sh64/semaphore.h
@@ -44,7 +44,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-sh64/types.h b/include/asm-sh64/types.h
index 8d41db2153b..2c7ad73b388 100644
--- a/include/asm-sh64/types.h
+++ b/include/asm-sh64/types.h
@@ -30,9 +30,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index 329e696e775..00bd0a679d7 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -96,6 +96,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
#include <asm-generic/bitops/fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
index acd06d8ff70..5da1eef0f70 100644
--- a/include/asm-sparc/floppy.h
+++ b/include/asm-sparc/floppy.h
@@ -77,8 +77,6 @@ static struct sun_floppy_ops sun_fdops;
#define fd_dma_mem_free(addr,size) (vfree((void *)(addr)))
#endif
-#define FLOPPY_MOTOR_MASK 0x10
-
/* XXX This isn't really correct. XXX */
#define get_dma_residue(x) (0)
diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h
index c23e74a0eaa..243bf8e9a05 100644
--- a/include/asm-sparc/io.h
+++ b/include/asm-sparc/io.h
@@ -310,13 +310,6 @@ extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
#define RTC_PORT(x) (rtc_port + (x))
#define RTC_ALWAYS_BCD 0
-/* Nothing to do */
-/* P3: Only IDE DMA may need these. XXX Verify that it still does... */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
#endif
#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1
diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h
index bdf77b0dfd8..058c2064f70 100644
--- a/include/asm-sparc/ioctls.h
+++ b/include/asm-sparc/ioctls.h
@@ -15,6 +15,10 @@
#define TCSETS _IOW('T', 9, struct termios)
#define TCSETSW _IOW('T', 10, struct termios)
#define TCSETSF _IOW('T', 11, struct termios)
+#define TCGETS2 _IOR('T', 12, struct termios2)
+#define TCSETS2 _IOW('T', 13, struct termios2)
+#define TCSETSW2 _IOW('T', 14, struct termios2)
+#define TCSETSF2 _IOW('T', 15, struct termios2)
/* Note that all the ioctls that are not available in Linux have a
* double underscore on the front to: a) avoid some programs to
diff --git a/include/asm-sparc/ipc.h b/include/asm-sparc/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-sparc/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-sparc/of_platform.h b/include/asm-sparc/of_platform.h
index 64a230064ef..d638737ff13 100644
--- a/include/asm-sparc/of_platform.h
+++ b/include/asm-sparc/of_platform.h
@@ -18,12 +18,9 @@
extern struct bus_type ebus_bus_type;
extern struct bus_type sbus_bus_type;
-extern struct bus_type of_platform_bus_type;
+
#define of_bus_type of_platform_bus_type /* for compatibility */
-extern int of_register_driver(struct of_platform_driver *drv,
- struct bus_type *bus);
-extern void of_unregister_driver(struct of_platform_driver *drv);
extern struct of_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent,
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index a4fcf9ac964..4055af90ad7 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -19,4 +19,6 @@ struct scatterlist {
#define ISA_DMA_THRESHOLD (~0UL)
+#define ARCH_HAS_SG_CHAIN
+
#endif /* !(_SPARC_SCATTERLIST_H) */
diff --git a/include/asm-sparc/semaphore.h b/include/asm-sparc/semaphore.h
index f74ba31e265..8018f9f4d49 100644
--- a/include/asm-sparc/semaphore.h
+++ b/include/asm-sparc/semaphore.h
@@ -26,7 +26,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h
index 5eb00a105d7..90cf2210118 100644
--- a/include/asm-sparc/termbits.h
+++ b/include/asm-sparc/termbits.h
@@ -31,6 +31,18 @@ struct termios {
#endif
};
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ cc_t _x_cc[2]; /* padding to match ktermios */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
struct ktermios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
@@ -160,6 +172,7 @@ struct ktermios {
#define CLOCAL 0x00000800
#define CBAUDEX 0x00001000
/* We'll never see these speeds with the Zilogs, but for completeness... */
+#define BOTHER 0x00001000
#define B57600 0x00001001
#define B115200 0x00001002
#define B230400 0x00001003
@@ -189,6 +202,8 @@ struct ktermios {
#define CMSPAR 0x40000000 /* mark or space (stick) parity */
#define CRTSCTS 0x80000000 /* flow control */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
/* c_lflag bits */
#define ISIG 0x00000001
#define ICANON 0x00000002
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h
index d767f206ab3..4333232abb9 100644
--- a/include/asm-sparc/termios.h
+++ b/include/asm-sparc/termios.h
@@ -108,13 +108,55 @@ struct winsize {
#define user_termios_to_kernel_termios(k, u) \
({ \
+ int err; \
+ err = get_user((k)->c_iflag, &(u)->c_iflag); \
+ err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+ err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+ err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+ err |= get_user((k)->c_line, &(u)->c_line); \
+ err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+ if ((k)->c_lflag & ICANON) { \
+ err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+ err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+ } else { \
+ err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \
+ err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+ } \
+ err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \
+ err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \
+ err; \
+})
+
+#define kernel_termios_to_user_termios(u, k) \
+({ \
+ int err; \
+ err = put_user((k)->c_iflag, &(u)->c_iflag); \
+ err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+ err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+ err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+ err |= put_user((k)->c_line, &(u)->c_line); \
+ err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+ if (!((k)->c_lflag & ICANON)) { \
+ err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \
+ err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+ } else { \
+ err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+ err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+ } \
+ err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
+ err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
+ err; \
+})
+
+#define user_termios_to_kernel_termios_1(k, u) \
+({ \
get_user((k)->c_iflag, &(u)->c_iflag); \
get_user((k)->c_oflag, &(u)->c_oflag); \
get_user((k)->c_cflag, &(u)->c_cflag); \
get_user((k)->c_lflag, &(u)->c_lflag); \
get_user((k)->c_line, &(u)->c_line); \
copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
- if((k)->c_lflag & ICANON) { \
+ if ((k)->c_lflag & ICANON) { \
get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
} else { \
@@ -124,7 +166,7 @@ struct winsize {
0; \
})
-#define kernel_termios_to_user_termios(u, k) \
+#define kernel_termios_to_user_termios_1(u, k) \
({ \
put_user((k)->c_iflag, &(u)->c_iflag); \
put_user((k)->c_oflag, &(u)->c_oflag); \
@@ -132,7 +174,7 @@ struct winsize {
put_user((k)->c_lflag, &(u)->c_lflag); \
put_user((k)->c_line, &(u)->c_line); \
copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
- if(!((k)->c_lflag & ICANON)) { \
+ if (!((k)->c_lflag & ICANON)) { \
put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \
put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
} else { \
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild
index 854fd3a65ac..a90dc82129d 100644
--- a/include/asm-sparc64/Kbuild
+++ b/include/asm-sparc64/Kbuild
@@ -10,7 +10,6 @@ header-y += bbc.h
header-y += bpp.h
header-y += display7seg.h
header-y += envctrl.h
-header-y += ipc.h
header-y += openprom.h
header-y += openpromio.h
header-y += pconf.h
diff --git a/include/asm-sparc64/backoff.h b/include/asm-sparc64/backoff.h
new file mode 100644
index 00000000000..0e32f8b62fd
--- /dev/null
+++ b/include/asm-sparc64/backoff.h
@@ -0,0 +1,28 @@
+#ifndef _SPARC64_BACKOFF_H
+#define _SPARC64_BACKOFF_H
+
+#define BACKOFF_LIMIT (4 * 1024)
+
+#ifdef CONFIG_SMP
+
+#define BACKOFF_SETUP(reg) \
+ mov 1, reg
+
+#define BACKOFF_SPIN(reg, tmp, label) \
+ mov reg, tmp; \
+88: brnz,pt tmp, 88b; \
+ sub tmp, 1, tmp; \
+ cmp reg, BACKOFF_LIMIT; \
+ bg,pn %xcc, label; \
+ nop; \
+ ba,pt %xcc, label; \
+ sllx reg, 1, reg;
+
+#else
+
+#define BACKOFF_SETUP(reg)
+#define BACKOFF_SPIN(reg, tmp, label)
+
+#endif
+
+#endif /* _SPARC64_BACKOFF_H */
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
index 3d5e1af8472..dd4bfe993b6 100644
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -81,6 +81,7 @@ static inline unsigned int hweight8(unsigned int w)
#include <asm-generic/bitops/hweight.h>
#endif
+#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */
#include <asm-generic/bitops/find.h>
diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
index 1783239c7b4..c47f58d6c15 100644
--- a/include/asm-sparc64/floppy.h
+++ b/include/asm-sparc64/floppy.h
@@ -84,8 +84,6 @@ static struct sun_floppy_ops sun_fdops;
#define fd_free_irq() sun_fdops.fd_free_irq()
#define fd_eject(drive) sun_fdops.fd_eject(drive)
-static int FLOPPY_MOTOR_MASK = 0x10;
-
/* Super paranoid... */
#undef HAVE_DISABLE_HLT
@@ -622,7 +620,6 @@ isa_done:
sun_fdops.fd_eject = sun_pci_fd_eject;
fdc_status = (unsigned long) &sun_fdc->status_82077;
- FLOPPY_MOTOR_MASK = 0xf0;
allowed_drive_mask = 0;
sun_floppy_types[0] = 0;
@@ -729,7 +726,6 @@ static unsigned long __init sun_floppy_init(void)
sun_fdops.fd_eject = sun_pci_fd_eject;
fdc_status = (unsigned long) &sun_fdc->status_82077;
- FLOPPY_MOTOR_MASK = 0xf0;
/*
* XXX: Find out on which machines this is really needed.
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h
index 9565a892801..cd7ef3097ac 100644
--- a/include/asm-sparc64/io.h
+++ b/include/asm-sparc64/io.h
@@ -474,12 +474,6 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#define sbus_iounmap(__addr, __size) \
release_region((unsigned long)(__addr), (__size))
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/include/asm-sparc64/ioctls.h b/include/asm-sparc64/ioctls.h
index 2223b6d0e5e..083c9a0f37d 100644
--- a/include/asm-sparc64/ioctls.h
+++ b/include/asm-sparc64/ioctls.h
@@ -16,6 +16,10 @@
#define TCSETS _IOW('T', 9, struct termios)
#define TCSETSW _IOW('T', 10, struct termios)
#define TCSETSF _IOW('T', 11, struct termios)
+#define TCGETS2 _IOR('T', 12, struct termios2)
+#define TCSETS2 _IOW('T', 13, struct termios2)
+#define TCSETSW2 _IOW('T', 14, struct termios2)
+#define TCSETSF2 _IOW('T', 15, struct termios2)
/* Note that all the ioctls that are not available in Linux have a
* double underscore on the front to: a) avoid some programs to
diff --git a/include/asm-sparc64/ipc.h b/include/asm-sparc64/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-sparc64/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
index 9974c7b0aeb..f905b773235 100644
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -1,26 +1,8 @@
#ifndef _SPARC64_KDEBUG_H
#define _SPARC64_KDEBUG_H
-/* Nearly identical to x86_64/i386 code. */
-
-#include <linux/notifier.h>
-
struct pt_regs;
-/*
- * These are only here because kprobes.c wants them to implement a
- * blatant layering violation. Will hopefully go away soon once all
- * architectures are updated.
- */
-static inline int register_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-static inline int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return 0;
-}
-
extern void bad_trap(struct pt_regs *, long);
/* Grossly misnamed. */
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index 7f6774dca5f..5020eaf67c2 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -10,8 +10,9 @@ typedef u32 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
#define MAX_INSN_SIZE 2
+#define kretprobe_blacklist_size 0
+
#define arch_remove_kprobe(p) do {} while (0)
-#define ARCH_INACTIVE_KPROBE_COUNT 0
#define flush_insn_slot(p) \
do { flushi(&(p)->ainsn.insn[0]); \
diff --git a/include/asm-sparc64/of_platform.h b/include/asm-sparc64/of_platform.h
index f7c1f17c7d5..f15cfa72391 100644
--- a/include/asm-sparc64/of_platform.h
+++ b/include/asm-sparc64/of_platform.h
@@ -19,12 +19,9 @@
extern struct bus_type isa_bus_type;
extern struct bus_type ebus_bus_type;
extern struct bus_type sbus_bus_type;
-extern struct bus_type of_platform_bus_type;
+
#define of_bus_type of_platform_bus_type /* for compatibility */
-extern int of_register_driver(struct of_platform_driver *drv,
- struct bus_type *bus);
-extern void of_unregister_driver(struct of_platform_driver *drv);
extern struct of_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
struct device *parent,
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 0393380d754..3167ccff64f 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -42,6 +42,9 @@
#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
#define VMALLOC_START _AC(0x0000000100000000,UL)
#define VMALLOC_END _AC(0x0000000200000000,UL)
+#define VMEMMAP_BASE _AC(0x0000000200000000,UL)
+
+#define vmemmap ((struct page *)VMEMMAP_BASE)
/* XXX All of this needs to be rethought so we can take advantage
* XXX cheetah's full 64-bit virtual address space, ie. no more hole
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 048fdb40e81..703c5bbe6c8 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -20,4 +20,6 @@ struct scatterlist {
#define ISA_DMA_THRESHOLD (~0UL)
+#define ARCH_HAS_SG_CHAIN
+
#endif /* !(_SPARC64_SCATTERLIST_H) */
diff --git a/include/asm-sparc64/semaphore.h b/include/asm-sparc64/semaphore.h
index 093dcc6788d..7f7c0c4e024 100644
--- a/include/asm-sparc64/semaphore.h
+++ b/include/asm-sparc64/semaphore.h
@@ -26,7 +26,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-sparc64/shmparam.h b/include/asm-sparc64/shmparam.h
index 911d0427de6..8c66fded8a3 100644
--- a/include/asm-sparc64/shmparam.h
+++ b/include/asm-sparc64/shmparam.h
@@ -1,7 +1,6 @@
/* $Id: shmparam.h,v 1.5 2001/09/24 21:17:57 kanoj Exp $ */
#ifndef _ASMSPARC64_SHMPARAM_H
#define _ASMSPARC64_SHMPARAM_H
-#ifdef __KERNEL__
#include <asm/spitfire.h>
@@ -9,5 +8,4 @@
/* attach addr a multiple of this */
#define SHMLBA ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE)
-#endif /* __KERNEL__ */
#endif /* _ASMSPARC64_SHMPARAM_H */
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index e8a96a31761..42c09949526 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -28,8 +28,9 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
+#include <asm/percpu.h>
-extern cpumask_t cpu_sibling_map[NR_CPUS];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
extern cpumask_t cpu_core_map[NR_CPUS];
extern int sparc64_multi_core;
diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h
index 705cd44b417..ebe31c152f1 100644
--- a/include/asm-sparc64/termbits.h
+++ b/include/asm-sparc64/termbits.h
@@ -5,8 +5,6 @@
typedef unsigned char cc_t;
typedef unsigned int speed_t;
-
-/* XXX is this right for sparc64? it was an unsigned long... XXX */
typedef unsigned int tcflag_t;
#define NCC 8
@@ -33,6 +31,18 @@ struct termios {
#endif
};
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ cc_t _x_cc[2]; /* padding to match ktermios */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
struct ktermios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
@@ -161,6 +171,7 @@ struct ktermios {
#define HUPCL 0x00000400
#define CLOCAL 0x00000800
#define CBAUDEX 0x00001000
+#define BOTHER 0x00001000
#define B57600 0x00001001
#define B115200 0x00001002
#define B230400 0x00001003
@@ -190,6 +201,8 @@ struct ktermios {
#define CMSPAR 0x40000000 /* mark or space (stick) parity */
#define CRTSCTS 0x80000000 /* flow control */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
/* c_lflag bits */
#define ISIG 0x00000001
#define ICANON 0x00000002
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
index f05d390993d..ef527211f8a 100644
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -123,6 +123,8 @@ struct winsize {
err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \
err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
} \
+ err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \
+ err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \
err; \
})
@@ -142,6 +144,46 @@ struct winsize {
err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
} \
+ err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \
+ err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \
+ err; \
+})
+
+#define user_termios_to_kernel_termios_1(k, u) \
+({ \
+ int err; \
+ err = get_user((k)->c_iflag, &(u)->c_iflag); \
+ err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+ err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+ err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+ err |= get_user((k)->c_line, &(u)->c_line); \
+ err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+ if((k)->c_lflag & ICANON) { \
+ err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+ err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+ } else { \
+ err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \
+ err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+ } \
+ err; \
+})
+
+#define kernel_termios_to_user_termios_1(u, k) \
+({ \
+ int err; \
+ err = put_user((k)->c_iflag, &(u)->c_iflag); \
+ err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+ err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+ err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+ err |= put_user((k)->c_line, &(u)->c_line); \
+ err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+ if(!((k)->c_lflag & ICANON)) { \
+ err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \
+ err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+ } else { \
+ err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+ err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+ } \
err; \
})
diff --git a/include/asm-sparc64/topology.h b/include/asm-sparc64/topology.h
index 290ac75f385..c6b557034f6 100644
--- a/include/asm-sparc64/topology.h
+++ b/include/asm-sparc64/topology.h
@@ -5,7 +5,7 @@
#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).core_id)
#define topology_core_siblings(cpu) (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#define mc_capable() (sparc64_multi_core)
#define smt_capable() (sparc64_multi_core)
#endif /* CONFIG_SMP */
diff --git a/include/asm-um/a.out.h b/include/asm-um/a.out.h
index 78bc9eed26b..9281dd8eb33 100644
--- a/include/asm-um/a.out.h
+++ b/include/asm-um/a.out.h
@@ -1,8 +1,12 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
#ifndef __UM_A_OUT_H
#define __UM_A_OUT_H
#include "asm/arch/a.out.h"
-#include "choose-mode.h"
#undef STACK_TOP
#undef STACK_TOP_MAX
@@ -13,10 +17,8 @@ extern unsigned long host_task_size;
#define STACK_ROOM (stacksizelim)
-extern int honeypot;
-#define STACK_TOP \
- CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
+#define STACK_TOP task_size
-#define STACK_TOP_MAX STACK_TOP
+#define STACK_TOP_MAX STACK_TOP
#endif
diff --git a/include/asm-um/alternative-asm.i b/include/asm-um/alternative-asm.h
index cae9faca132..9aa9fa2402a 100644
--- a/include/asm-um/alternative-asm.i
+++ b/include/asm-um/alternative-asm.h
@@ -1,6 +1,6 @@
#ifndef __UM_ALTERNATIVE_ASM_I
#define __UM_ALTERNATIVE_ASM_I
-#include "asm/arch/alternative-asm.i"
+#include "asm/arch/alternative-asm.h"
#endif
diff --git a/include/asm-um/elf-i386.h b/include/asm-um/elf-i386.h
index 9bab712dc5c..ca94a136dfe 100644
--- a/include/asm-um/elf-i386.h
+++ b/include/asm-um/elf-i386.h
@@ -5,7 +5,8 @@
#ifndef __UM_ELF_I386_H
#define __UM_ELF_I386_H
-#include <asm/user.h>
+#include <linux/sched.h>
+#include "skas.h"
#define R_386_NONE 0
#define R_386_32 1
@@ -75,6 +76,15 @@ typedef struct user_i387_struct elf_fpregset_t;
pr_reg[16] = PT_REGS_SS(regs); \
} while(0);
+static inline int elf_core_copy_fpregs(struct task_struct *t,
+ elf_fpregset_t *fpu)
+{
+ int cpu = ((struct thread_info *) t->stack)->cpu;
+ return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
+}
+
+#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu)
+
extern long elf_aux_hwcap;
#define ELF_HWCAP (elf_aux_hwcap)
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h
index 857471c49da..3c9d543eb61 100644
--- a/include/asm-um/elf-x86_64.h
+++ b/include/asm-um/elf-x86_64.h
@@ -1,5 +1,6 @@
/*
* Copyright 2003 PathScale, Inc.
+ * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*
* Licensed under the GPL
*/
@@ -36,7 +37,7 @@ typedef unsigned long elf_greg_t;
#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-typedef struct { } elf_fpregset_t;
+typedef struct user_i387_struct elf_fpregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
@@ -67,27 +68,27 @@ typedef struct { } elf_fpregset_t;
} while (0)
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
- (pr_reg)[0] = (regs)->regs.skas.regs[0]; \
- (pr_reg)[1] = (regs)->regs.skas.regs[1]; \
- (pr_reg)[2] = (regs)->regs.skas.regs[2]; \
- (pr_reg)[3] = (regs)->regs.skas.regs[3]; \
- (pr_reg)[4] = (regs)->regs.skas.regs[4]; \
- (pr_reg)[5] = (regs)->regs.skas.regs[5]; \
- (pr_reg)[6] = (regs)->regs.skas.regs[6]; \
- (pr_reg)[7] = (regs)->regs.skas.regs[7]; \
- (pr_reg)[8] = (regs)->regs.skas.regs[8]; \
- (pr_reg)[9] = (regs)->regs.skas.regs[9]; \
- (pr_reg)[10] = (regs)->regs.skas.regs[10]; \
- (pr_reg)[11] = (regs)->regs.skas.regs[11]; \
- (pr_reg)[12] = (regs)->regs.skas.regs[12]; \
- (pr_reg)[13] = (regs)->regs.skas.regs[13]; \
- (pr_reg)[14] = (regs)->regs.skas.regs[14]; \
- (pr_reg)[15] = (regs)->regs.skas.regs[15]; \
- (pr_reg)[16] = (regs)->regs.skas.regs[16]; \
- (pr_reg)[17] = (regs)->regs.skas.regs[17]; \
- (pr_reg)[18] = (regs)->regs.skas.regs[18]; \
- (pr_reg)[19] = (regs)->regs.skas.regs[19]; \
- (pr_reg)[20] = (regs)->regs.skas.regs[20]; \
+ (pr_reg)[0] = (regs)->regs.gp[0]; \
+ (pr_reg)[1] = (regs)->regs.gp[1]; \
+ (pr_reg)[2] = (regs)->regs.gp[2]; \
+ (pr_reg)[3] = (regs)->regs.gp[3]; \
+ (pr_reg)[4] = (regs)->regs.gp[4]; \
+ (pr_reg)[5] = (regs)->regs.gp[5]; \
+ (pr_reg)[6] = (regs)->regs.gp[6]; \
+ (pr_reg)[7] = (regs)->regs.gp[7]; \
+ (pr_reg)[8] = (regs)->regs.gp[8]; \
+ (pr_reg)[9] = (regs)->regs.gp[9]; \
+ (pr_reg)[10] = (regs)->regs.gp[10]; \
+ (pr_reg)[11] = (regs)->regs.gp[11]; \
+ (pr_reg)[12] = (regs)->regs.gp[12]; \
+ (pr_reg)[13] = (regs)->regs.gp[13]; \
+ (pr_reg)[14] = (regs)->regs.gp[14]; \
+ (pr_reg)[15] = (regs)->regs.gp[15]; \
+ (pr_reg)[16] = (regs)->regs.gp[16]; \
+ (pr_reg)[17] = (regs)->regs.gp[17]; \
+ (pr_reg)[18] = (regs)->regs.gp[18]; \
+ (pr_reg)[19] = (regs)->regs.gp[19]; \
+ (pr_reg)[20] = (regs)->regs.gp[20]; \
(pr_reg)[21] = current->thread.arch.fs; \
(pr_reg)[22] = 0; \
(pr_reg)[23] = 0; \
@@ -122,14 +123,3 @@ extern long elf_aux_hwcap;
#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/frame.i b/include/asm-um/frame.h
index 09d5dca5d92..8a8c1cb415b 100644
--- a/include/asm-um/frame.i
+++ b/include/asm-um/frame.h
@@ -1,6 +1,6 @@
#ifndef __UM_FRAME_I
#define __UM_FRAME_I
-#include "asm/arch/frame.i"
+#include "asm/arch/frame.h"
#endif
diff --git a/include/asm-um/ipc.h b/include/asm-um/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-um/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
index 96f82a456ce..b2553f3e87e 100644
--- a/include/asm-um/ldt.h
+++ b/include/asm-um/ldt.h
@@ -11,11 +11,7 @@
#include "asm/semaphore.h"
#include "asm/host_ldt.h"
-struct mmu_context_skas;
extern void ldt_host_info(void);
-extern long init_new_ldt(struct mmu_context_skas * to_mm,
- struct mmu_context_skas * from_mm);
-extern void free_ldt(struct mmu_context_skas * mm);
#define LDT_PAGES_MAX \
((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
index 9aa4b44e8cc..5f3b863aef9 100644
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -9,7 +9,6 @@
#include <asm-generic/mm_hooks.h>
#include "linux/sched.h"
-#include "choose-mode.h"
#include "um_mmu.h"
#define get_mmu_context(task) do ; while(0)
@@ -30,8 +29,7 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
* possible.
*/
if (old != new && (current->flags & PF_BORROWED_MM))
- CHOOSE_MODE(force_flush_all(),
- switch_mm_skas(&new->context.skas.id));
+ __switch_mm(&new->context.id);
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
@@ -43,8 +41,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
cpu_clear(cpu, prev->cpu_vm_mask);
cpu_set(cpu, next->cpu_vm_mask);
if(next != &init_mm)
- CHOOSE_MODE((void) 0,
- switch_mm_skas(&next->context.skas.id));
+ __switch_mm(&next->context.id);
}
}
@@ -53,38 +50,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm,
{
}
-extern int init_new_context_skas(struct task_struct *task,
- struct mm_struct *mm);
+extern int init_new_context(struct task_struct *task, struct mm_struct *mm);
-static inline int init_new_context_tt(struct task_struct *task,
- struct mm_struct *mm)
-{
- return(0);
-}
-
-static inline int init_new_context(struct task_struct *task,
- struct mm_struct *mm)
-{
- return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas,
- task, mm));
-}
-
-extern void destroy_context_skas(struct mm_struct *mm);
-
-static inline void destroy_context(struct mm_struct *mm)
-{
- CHOOSE_MODE((void) 0, destroy_context_skas(mm));
-}
+extern void destroy_context(struct mm_struct *mm);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 8e310d81e5b..4b424c75fca 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -9,6 +9,7 @@
struct page;
+#include <linux/types.h>
#include <asm/vm-flags.h>
/* PAGE_SHIFT determines the page size */
diff --git a/include/asm-um/pgalloc.h b/include/asm-um/pgalloc.h
index 34ab268ef40..14904876e8f 100644
--- a/include/asm-um/pgalloc.h
+++ b/include/asm-um/pgalloc.h
@@ -42,7 +42,7 @@ static inline void pte_free(struct page *pte)
#ifdef CONFIG_3_LEVEL_PGTABLES
-extern __inline__ void pmd_free(pmd_t *pmd)
+static inline void pmd_free(pmd_t *pmd)
{
free_page((unsigned long)pmd);
}
diff --git a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h
index ca0c2a92a11..aa82b88db80 100644
--- a/include/asm-um/pgtable-3level.h
+++ b/include/asm-um/pgtable-3level.h
@@ -69,7 +69,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
return pmd;
}
-extern inline void pud_clear (pud_t *pud)
+static inline void pud_clear (pud_t *pud)
{
set_pud(pud, __pud(0));
}
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index d99bbddffdb..78c0599cc80 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -11,44 +11,32 @@ struct pt_regs;
struct task_struct;
#include "asm/ptrace.h"
-#include "choose-mode.h"
#include "registers.h"
#include "sysdep/archsetjmp.h"
struct mm_struct;
struct thread_struct {
- /* This flag is set to 1 before calling do_fork (and analyzed in
+ struct task_struct *saved_task;
+ /*
+ * This flag is set to 1 before calling do_fork (and analyzed in
* copy_thread) to mark that we are begin called from userspace (fork /
* vfork / clone), and reset to 0 after. It is left to 0 when called
- * from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */
- struct task_struct *saved_task;
+ * from kernelspace (i.e. kernel_thread() or fork_idle(),
+ * as of 2.6.11).
+ */
int forking;
int nsyscalls;
struct pt_regs regs;
int singlestep_syscall;
void *fault_addr;
- void *fault_catcher;
+ jmp_buf *fault_catcher;
struct task_struct *prev_sched;
unsigned long temp_stack;
- void *exec_buf;
+ jmp_buf *exec_buf;
struct arch_thread arch;
- union {
-#ifdef CONFIG_MODE_TT
- struct {
- int extern_pid;
- int tracing;
- int switch_pipe[2];
- int vm_seq;
- } tt;
-#endif
-#ifdef CONFIG_MODE_SKAS
- struct {
- jmp_buf switch_buf;
- int mm_count;
- } skas;
-#endif
- } mode;
+ jmp_buf switch_buf;
+ int mm_count;
struct {
int op;
union {
@@ -71,7 +59,7 @@ struct thread_struct {
{ \
.forking = 0, \
.nsyscalls = 0, \
- .regs = EMPTY_REGS, \
+ .regs = EMPTY_REGS, \
.fault_addr = NULL, \
.prev_sched = NULL, \
.temp_stack = 0, \
@@ -86,7 +74,10 @@ typedef struct {
extern struct task_struct *alloc_task_struct(void);
-extern void release_thread(struct task_struct *);
+static inline void release_thread(struct task_struct *task)
+{
+}
+
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
static inline void prepare_to_copy(struct task_struct *tsk)
@@ -136,12 +127,7 @@ extern struct cpuinfo_um cpu_data[];
#endif
-#ifdef CONFIG_MODE_SKAS
-#define KSTK_REG(tsk, reg) \
- get_thread_reg(reg, &tsk->thread.mode.skas.switch_buf)
-#else
-#define KSTK_REG(tsk, reg) (0xbadbabe)
-#endif
+#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
#define get_wchan(p) (0)
#endif
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index 31c2d4d685b..d946bf2d334 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -18,7 +18,7 @@ struct arch_thread {
};
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-extern inline void rep_nop(void)
+static inline void rep_nop(void)
{
__asm__ __volatile__("rep;nop": : :"memory");
}
diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
index 99c87c5ce99..6aefcd32fc6 100644
--- a/include/asm-um/ptrace-generic.h
+++ b/include/asm-um/ptrace-generic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -9,10 +9,11 @@
#ifndef __ASSEMBLY__
#include "asm/arch/ptrace-abi.h"
+#include <asm/user.h>
#include "sysdep/ptrace.h"
struct pt_regs {
- union uml_pt_regs regs;
+ struct uml_pt_regs regs;
};
#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
@@ -35,16 +36,18 @@ struct pt_regs {
struct task_struct;
+extern long subarch_ptrace(struct task_struct *child, long request, long addr,
+ long data);
extern unsigned long getreg(struct task_struct *child, int regno);
extern int putreg(struct task_struct *child, int regno, unsigned long value);
-extern int get_fpregs(unsigned long buf, struct task_struct *child);
-extern int set_fpregs(unsigned long buf, struct task_struct *child);
-extern int get_fpxregs(unsigned long buf, struct task_struct *child);
-extern int set_fpxregs(unsigned long buf, struct task_struct *tsk);
+extern int get_fpregs(struct user_i387_struct __user *buf,
+ struct task_struct *child);
+extern int set_fpregs(struct user_i387_struct __user *buf,
+ struct task_struct *child);
extern void show_regs(struct pt_regs *regs);
-extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
+extern void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
int error_code);
extern int arch_copy_tls(struct task_struct *new);
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index 6e2528bb008..b2d24c5ea2c 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -9,10 +9,9 @@
#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
#include "linux/compiler.h"
-#include "sysdep/ptrace.h"
#include "asm/ptrace-generic.h"
-#include "asm/host_ldt.h"
-#include "choose-mode.h"
+#include <asm/user.h>
+#include "sysdep/ptrace.h"
#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
@@ -41,34 +40,21 @@
#define user_mode(r) UPT_IS_USER(&(r)->regs)
+/*
+ * Forward declaration to avoid including sysdep/tls.h, which causes a
+ * circular include, and compilation failures.
+ */
+struct user_desc;
+
+extern int get_fpxregs(struct user_fxsr_struct __user *buf,
+ struct task_struct *child);
+extern int set_fpxregs(struct user_fxsr_struct __user *buf,
+ struct task_struct *tsk);
+
extern int ptrace_get_thread_area(struct task_struct *child, int idx,
struct user_desc __user *user_desc);
extern int ptrace_set_thread_area(struct task_struct *child, int idx,
struct user_desc __user *user_desc);
-extern int do_set_thread_area_skas(struct user_desc *info);
-extern int do_get_thread_area_skas(struct user_desc *info);
-
-extern int do_set_thread_area_tt(struct user_desc *info);
-extern int do_get_thread_area_tt(struct user_desc *info);
-
-extern int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to);
-extern int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to);
-
-extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to);
-extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to);
-
-static inline int do_get_thread_area(struct user_desc *info)
-{
- return CHOOSE_MODE_PROC(do_get_thread_area_tt, do_get_thread_area_skas, info);
-}
-
-static inline int do_set_thread_area(struct user_desc *info)
-{
- return CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, info);
-}
-
-struct task_struct;
-
#endif
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index bf61d17de3f..4c475350dcf 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -76,15 +76,6 @@ static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
return -ENOSYS;
}
-static inline void arch_switch_to_tt(struct task_struct *from,
- struct task_struct *to)
-{
-}
-
-extern void arch_switch_to_skas(struct task_struct *from,
- struct task_struct *to);
-
-extern long arch_prctl_skas(struct task_struct *task, int code,
- unsigned long __user *addr);
-
+extern long arch_prctl(struct task_struct *task, int code,
+ unsigned long __user *addr);
#endif
diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h
index 84f8cf29324..f27a9631317 100644
--- a/include/asm-um/smp.h
+++ b/include/asm-um/smp.h
@@ -18,7 +18,7 @@ extern int hard_smp_processor_id(void);
extern int ncpus;
-extern inline void smp_cpus_done(unsigned int maxcpus)
+static inline void smp_cpus_done(unsigned int maxcpus)
{
}
diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h
index e78c28c1f35..9d647c55350 100644
--- a/include/asm-um/tlbflush.h
+++ b/include/asm-um/tlbflush.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -7,7 +7,6 @@
#define __UM_TLBFLUSH_H
#include <linux/mm.h>
-#include "choose-mode.h"
/*
* TLB flushing:
@@ -25,19 +24,7 @@ extern void flush_tlb_all(void);
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_skas(struct vm_area_struct *vma,
- unsigned long address);
-
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long address)
-{
- address &= PAGE_MASK;
-
- CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE),
- flush_tlb_page_skas(vma, address));
-}
-
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long address);
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);
diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
index 16c734af919..077032d4fc4 100644
--- a/include/asm-um/uaccess.h
+++ b/include/asm-um/uaccess.h
@@ -80,7 +80,7 @@
__put_user(x, private_ptr) : -EFAULT); \
})
-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+#define strlen_user(str) strnlen_user(str, ~0U >> 1)
struct exception_table_entry
{
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index 1fa99baf4e2..8eafdb1c08b 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -145,6 +145,7 @@ static inline int __test_bit (int nr, const void *addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/ext2-non-atomic.h>
#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a)
diff --git a/include/asm-v850/ipc.h b/include/asm-v850/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-v850/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-v850/irq_regs.h b/include/asm-v850/irq_regs.h
new file mode 100644
index 00000000000..3dd9c0b7027
--- /dev/null
+++ b/include/asm-v850/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-v850/semaphore.h b/include/asm-v850/semaphore.h
index 735baaf3a16..10ed0ccf37d 100644
--- a/include/asm-v850/semaphore.h
+++ b/include/asm-v850/semaphore.h
@@ -22,7 +22,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER (name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC (name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC (name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-v850/types.h b/include/asm-v850/types.h
index dcef5719687..284bda88211 100644
--- a/include/asm-v850/types.h
+++ b/include/asm-v850/types.h
@@ -27,9 +27,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild
index c5e43cb3987..559830ece75 100644
--- a/include/asm-x86/Kbuild
+++ b/include/asm-x86/Kbuild
@@ -1,41 +1,22 @@
include include/asm-generic/Kbuild.asm
header-y += boot.h
-header-y += bootsetup.h
-header-y += debugreg_32.h
-header-y += debugreg_64.h
header-y += debugreg.h
-header-y += ldt_32.h
-header-y += ldt_64.h
header-y += ldt.h
header-y += msr-index.h
header-y += prctl.h
-header-y += ptrace-abi_32.h
-header-y += ptrace-abi_64.h
header-y += ptrace-abi.h
header-y += sigcontext32.h
-header-y += ucontext_32.h
-header-y += ucontext_64.h
header-y += ucontext.h
header-y += vsyscall32.h
unifdef-y += a.out_32.h
unifdef-y += a.out_64.h
-unifdef-y += auxvec_32.h
-unifdef-y += auxvec_64.h
unifdef-y += byteorder_32.h
unifdef-y += byteorder_64.h
unifdef-y += elf_32.h
unifdef-y += elf_64.h
-unifdef-y += errno_32.h
-unifdef-y += errno_64.h
-unifdef-y += ioctls_32.h
-unifdef-y += ioctls_64.h
-unifdef-y += ipcbuf_32.h
-unifdef-y += ipcbuf_64.h
unifdef-y += mce.h
-unifdef-y += mman_32.h
-unifdef-y += mman_64.h
unifdef-y += msgbuf_32.h
unifdef-y += msgbuf_64.h
unifdef-y += msr_32.h
@@ -46,40 +27,22 @@ unifdef-y += mtrr_64.h
unifdef-y += mtrr.h
unifdef-y += page_32.h
unifdef-y += page_64.h
-unifdef-y += param_32.h
-unifdef-y += param_64.h
unifdef-y += posix_types_32.h
unifdef-y += posix_types_64.h
unifdef-y += ptrace_32.h
unifdef-y += ptrace_64.h
-unifdef-y += resource_32.h
-unifdef-y += resource_64.h
-unifdef-y += sembuf_32.h
-unifdef-y += sembuf_64.h
unifdef-y += setup_32.h
unifdef-y += setup_64.h
unifdef-y += shmbuf_32.h
unifdef-y += shmbuf_64.h
-unifdef-y += shmparam_32.h
-unifdef-y += shmparam_64.h
unifdef-y += sigcontext_32.h
unifdef-y += sigcontext_64.h
-unifdef-y += siginfo_32.h
-unifdef-y += siginfo_64.h
unifdef-y += signal_32.h
unifdef-y += signal_64.h
-unifdef-y += sockios_32.h
-unifdef-y += sockios_64.h
unifdef-y += stat_32.h
unifdef-y += stat_64.h
unifdef-y += statfs_32.h
unifdef-y += statfs_64.h
-unifdef-y += termbits_32.h
-unifdef-y += termbits_64.h
-unifdef-y += termios_32.h
-unifdef-y += termios_64.h
-unifdef-y += types_32.h
-unifdef-y += types_64.h
unifdef-y += unistd_32.h
unifdef-y += unistd_64.h
unifdef-y += user_32.h
diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h
index 9348f1e4f6f..62df2a9e713 100644
--- a/include/asm-x86/agp.h
+++ b/include/asm-x86/agp.h
@@ -1,5 +1,40 @@
-#ifdef CONFIG_X86_32
-# include "agp_32.h"
-#else
-# include "agp_64.h"
+#ifndef _ASM_X86_AGP_H
+#define _ASM_X86_AGP_H
+
+#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Functions to keep the agpgart mappings coherent with the MMU. The
+ * GART gives the CPU a physical alias of pages in memory. The alias
+ * region is mapped uncacheable. Make sure there are no conflicting
+ * mappings with different cachability attributes for the same
+ * page. This avoids data corruption on some CPUs.
+ */
+
+/*
+ * Caller's responsibility to call global_flush_tlb() for performance
+ * reasons
+ */
+#define map_page_into_agp(page) change_page_attr(page, 1, PAGE_KERNEL_NOCACHE)
+#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL)
+#define flush_agp_mappings() global_flush_tlb()
+
+/*
+ * Could use CLFLUSH here if the cpu supports it. But then it would
+ * need to be called for each cacheline of the whole page so it may
+ * not be worth it. Would need a page for it.
+ */
+#define flush_agp_cache() wbinvd()
+
+/* Convert a physical address to an address suitable for the GART. */
+#define phys_to_gart(x) (x)
+#define gart_to_phys(x) (x)
+
+/* GATT allocation. Returns/accepts GATT kernel virtual address. */
+#define alloc_gatt_pages(order) \
+ ((char *)__get_free_pages(GFP_KERNEL, (order)))
+#define free_gatt_pages(table, order) \
+ free_pages((unsigned long)(table), (order))
+
#endif
diff --git a/include/asm-x86/agp_32.h b/include/asm-x86/agp_32.h
deleted file mode 100644
index 6af173dbf12..00000000000
--- a/include/asm-x86/agp_32.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef AGP_H
-#define AGP_H 1
-
-#include <asm/pgtable.h>
-#include <asm/cacheflush.h>
-
-/*
- * Functions to keep the agpgart mappings coherent with the MMU.
- * The GART gives the CPU a physical alias of pages in memory. The alias region is
- * mapped uncacheable. Make sure there are no conflicting mappings
- * with different cachability attributes for the same page. This avoids
- * data corruption on some CPUs.
- */
-
-/* Caller's responsibility to call global_flush_tlb() for
- * performance reasons */
-#define map_page_into_agp(page) change_page_attr(page, 1, PAGE_KERNEL_NOCACHE)
-#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL)
-#define flush_agp_mappings() global_flush_tlb()
-
-/* Could use CLFLUSH here if the cpu supports it. But then it would
- need to be called for each cacheline of the whole page so it may not be
- worth it. Would need a page for it. */
-#define flush_agp_cache() wbinvd()
-
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
-/* GATT allocation. Returns/accepts GATT kernel virtual address. */
-#define alloc_gatt_pages(order) \
- ((char *)__get_free_pages(GFP_KERNEL, (order)))
-#define free_gatt_pages(table, order) \
- free_pages((unsigned long)(table), (order))
-
-#endif
diff --git a/include/asm-x86/agp_64.h b/include/asm-x86/agp_64.h
deleted file mode 100644
index de338666f3f..00000000000
--- a/include/asm-x86/agp_64.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef AGP_H
-#define AGP_H 1
-
-#include <asm/cacheflush.h>
-
-/*
- * Functions to keep the agpgart mappings coherent.
- * The GART gives the CPU a physical alias of memory. The alias is
- * mapped uncacheable. Make sure there are no conflicting mappings
- * with different cachability attributes for the same page.
- */
-
-/* Caller's responsibility to call global_flush_tlb() for
- * performance reasons */
-#define map_page_into_agp(page) change_page_attr(page, 1, PAGE_KERNEL_NOCACHE)
-#define unmap_page_from_agp(page) change_page_attr(page, 1, PAGE_KERNEL)
-#define flush_agp_mappings() global_flush_tlb()
-
-/* Could use CLFLUSH here if the cpu supports it. But then it would
- need to be called for each cacheline of the whole page so it may not be
- worth it. Would need a page for it. */
-#define flush_agp_cache() asm volatile("wbinvd":::"memory")
-
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
-/* GATT allocation. Returns/accepts GATT kernel virtual address. */
-#define alloc_gatt_pages(order) \
- ((char *)__get_free_pages(GFP_KERNEL, (order)))
-#define free_gatt_pages(table, order) \
- free_pages((unsigned long)(table), (order))
-
-#endif
diff --git a/include/asm-x86/alternative-asm.h b/include/asm-x86/alternative-asm.h
new file mode 100644
index 00000000000..e2077d343c3
--- /dev/null
+++ b/include/asm-x86/alternative-asm.h
@@ -0,0 +1,22 @@
+#ifdef __ASSEMBLY__
+
+#ifdef CONFIG_X86_32
+# define X86_ALIGN .long
+#else
+# define X86_ALIGN .quad
+#endif
+
+#ifdef CONFIG_SMP
+ .macro LOCK_PREFIX
+1: lock
+ .section .smp_locks,"a"
+ .align 4
+ X86_ALIGN 1b
+ .previous
+ .endm
+#else
+ .macro LOCK_PREFIX
+ .endm
+#endif
+
+#endif /* __ASSEMBLY__ */
diff --git a/include/asm-x86/alternative-asm.i b/include/asm-x86/alternative-asm.i
deleted file mode 100644
index 4f360cd3c88..00000000000
--- a/include/asm-x86/alternative-asm.i
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef CONFIG_X86_32
-# include "alternative-asm_32.i"
-#else
-# include "alternative-asm_64.i"
-#endif
diff --git a/include/asm-x86/alternative-asm_32.i b/include/asm-x86/alternative-asm_32.i
deleted file mode 100644
index f0510209ccb..00000000000
--- a/include/asm-x86/alternative-asm_32.i
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifdef CONFIG_SMP
- .macro LOCK_PREFIX
-1: lock
- .section .smp_locks,"a"
- .align 4
- .long 1b
- .previous
- .endm
-#else
- .macro LOCK_PREFIX
- .endm
-#endif
diff --git a/include/asm-x86/alternative-asm_64.i b/include/asm-x86/alternative-asm_64.i
deleted file mode 100644
index 0b3f1a2bb2c..00000000000
--- a/include/asm-x86/alternative-asm_64.i
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifdef CONFIG_SMP
- .macro LOCK_PREFIX
-1: lock
- .section .smp_locks,"a"
- .align 8
- .quad 1b
- .previous
- .endm
-#else
- .macro LOCK_PREFIX
- .endm
-#endif
diff --git a/include/asm-x86/atomic_64.h b/include/asm-x86/atomic_64.h
index f2e64634fa4..2d20a7a19f6 100644
--- a/include/asm-x86/atomic_64.h
+++ b/include/asm-x86/atomic_64.h
@@ -206,7 +206,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v)
/* An 64bit atomic type */
-typedef struct { volatile long counter; } atomic64_t;
+typedef struct { long counter; } atomic64_t;
#define ATOMIC64_INIT(i) { (i) }
diff --git a/include/asm-x86/auxvec.h b/include/asm-x86/auxvec.h
index 7ff866f829c..87f5e6d5a02 100644
--- a/include/asm-x86/auxvec.h
+++ b/include/asm-x86/auxvec.h
@@ -1,13 +1,12 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "auxvec_32.h"
-# else
-# include "auxvec_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "auxvec_32.h"
-# else
-# include "auxvec_64.h"
-# endif
+#ifndef _ASM_X86_AUXVEC_H
+#define _ASM_X86_AUXVEC_H
+/*
+ * Architecture-neutral AT_ values in 0-17, leave some room
+ * for more of them, start the x86-specific ones at 32.
+ */
+#ifdef __i386__
+#define AT_SYSINFO 32
+#endif
+#define AT_SYSINFO_EHDR 33
+
#endif
diff --git a/include/asm-x86/auxvec_32.h b/include/asm-x86/auxvec_32.h
deleted file mode 100644
index 395e13016bf..00000000000
--- a/include/asm-x86/auxvec_32.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __ASMi386_AUXVEC_H
-#define __ASMi386_AUXVEC_H
-
-/*
- * Architecture-neutral AT_ values in 0-17, leave some room
- * for more of them, start the x86-specific ones at 32.
- */
-#define AT_SYSINFO 32
-#define AT_SYSINFO_EHDR 33
-
-#endif
diff --git a/include/asm-x86/auxvec_64.h b/include/asm-x86/auxvec_64.h
deleted file mode 100644
index 1d5ab0d0395..00000000000
--- a/include/asm-x86/auxvec_64.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_X86_64_AUXVEC_H
-#define __ASM_X86_64_AUXVEC_H
-
-#define AT_SYSINFO_EHDR 33
-
-#endif
diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h
index a20fe9822f6..c96641f7502 100644
--- a/include/asm-x86/bitops_32.h
+++ b/include/asm-x86/bitops_32.h
@@ -402,6 +402,7 @@ static inline int fls(int x)
}
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */
diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h
index d4dbbe5f7bd..525edf2ce5c 100644
--- a/include/asm-x86/bitops_64.h
+++ b/include/asm-x86/bitops_64.h
@@ -260,7 +260,7 @@ extern long find_first_bit(const unsigned long * addr, unsigned long size);
extern long find_next_bit(const unsigned long * addr, long size, long offset);
/* return index of first bet set in val or max when no bit is set */
-static inline unsigned long __scanbit(unsigned long val, unsigned long max)
+static inline long __scanbit(unsigned long val, unsigned long max)
{
asm("bsfq %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max));
return val;
@@ -408,6 +408,7 @@ static __inline__ int fls(int x)
#define ARCH_HAS_FAST_MULTIPLIER 1
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */
diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h
index b91b01783e4..ef67b59dbdb 100644
--- a/include/asm-x86/bootparam.h
+++ b/include/asm-x86/bootparam.h
@@ -14,6 +14,9 @@ struct setup_header {
u16 root_flags;
u32 syssize;
u16 ram_size;
+#define RAMDISK_IMAGE_START_MASK 0x07FF
+#define RAMDISK_PROMPT_FLAG 0x8000
+#define RAMDISK_LOAD_FLAG 0x4000
u16 vid_mode;
u16 root_dev;
u16 boot_flag;
diff --git a/include/asm-x86/bootsetup.h b/include/asm-x86/bootsetup.h
deleted file mode 100644
index 7b1c3ad155f..00000000000
--- a/include/asm-x86/bootsetup.h
+++ /dev/null
@@ -1,40 +0,0 @@
-
-#ifndef _X86_64_BOOTSETUP_H
-#define _X86_64_BOOTSETUP_H 1
-
-#define BOOT_PARAM_SIZE 4096
-extern char x86_boot_params[BOOT_PARAM_SIZE];
-
-/*
- * This is set up by the setup-routine at boot-time
- */
-#define PARAM ((unsigned char *)x86_boot_params)
-#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
-#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
-#define ALT_MEM_K (*(unsigned int *) (PARAM+0x1e0))
-#define E820_MAP_NR (*(char*) (PARAM+E820NR))
-#define E820_MAP ((struct e820entry *) (PARAM+E820MAP))
-#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
-#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
-#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
-#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
-#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
-#define SAVED_VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
-#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
-#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
-#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
-#define KERNEL_START (*(unsigned int *) (PARAM+0x214))
-#define INITRD_START (*(unsigned int *) (PARAM+0x218))
-#define INITRD_SIZE (*(unsigned int *) (PARAM+0x21c))
-#define EDID_INFO (*(struct edid_info *) (PARAM+0x140))
-#define EDD_NR (*(unsigned char *) (PARAM+EDDNR))
-#define EDD_MBR_SIG_NR (*(unsigned char *) (PARAM+EDD_MBR_SIG_NR_BUF))
-#define EDD_MBR_SIGNATURE ((unsigned int *) (PARAM+EDD_MBR_SIG_BUF))
-#define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF))
-#define COMMAND_LINE boot_command_line
-
-#define RAMDISK_IMAGE_START_MASK 0x07FF
-#define RAMDISK_PROMPT_FLAG 0x8000
-#define RAMDISK_LOAD_FLAG 0x4000
-
-#endif
diff --git a/include/asm-x86/bug.h b/include/asm-x86/bug.h
index c655d7f3a5e..fd8bdc639c4 100644
--- a/include/asm-x86/bug.h
+++ b/include/asm-x86/bug.h
@@ -1,5 +1,42 @@
+#ifndef _ASM_X86_BUG_H
+#define _ASM_X86_BUG_H
+
+#ifdef CONFIG_BUG
+#define HAVE_ARCH_BUG
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
#ifdef CONFIG_X86_32
-# include "bug_32.h"
+# define __BUG_C0 "2:\t.long 1b, %c0\n"
#else
-# include "bug_64.h"
+# define __BUG_C0 "2:\t.quad 1b, %c0\n"
+#endif
+
+#define BUG() \
+ do { \
+ asm volatile("1:\tud2\n" \
+ ".pushsection __bug_table,\"a\"\n" \
+ __BUG_C0 \
+ "\t.word %c1, 0\n" \
+ "\t.org 2b+%c2\n" \
+ ".popsection" \
+ : : "i" (__FILE__), "i" (__LINE__), \
+ "i" (sizeof(struct bug_entry))); \
+ for(;;) ; \
+ } while(0)
+
+#else
+#define BUG() \
+ do { \
+ asm volatile("ud2"); \
+ for(;;) ; \
+ } while(0)
+#endif
+
+void out_of_line_bug(void);
+#else /* CONFIG_BUG */
+static inline void out_of_line_bug(void) { }
+#endif /* !CONFIG_BUG */
+
+#include <asm-generic/bug.h>
#endif
diff --git a/include/asm-x86/bug_32.h b/include/asm-x86/bug_32.h
deleted file mode 100644
index b0fd78ca261..00000000000
--- a/include/asm-x86/bug_32.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _I386_BUG_H
-#define _I386_BUG_H
-
-
-/*
- * Tell the user there is some problem.
- * The offending file and line are encoded encoded in the __bug_table section.
- */
-
-#ifdef CONFIG_BUG
-#define HAVE_ARCH_BUG
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#define BUG() \
- do { \
- asm volatile("1:\tud2\n" \
- ".pushsection __bug_table,\"a\"\n" \
- "2:\t.long 1b, %c0\n" \
- "\t.word %c1, 0\n" \
- "\t.org 2b+%c2\n" \
- ".popsection" \
- : : "i" (__FILE__), "i" (__LINE__), \
- "i" (sizeof(struct bug_entry))); \
- for(;;) ; \
- } while(0)
-
-#else
-#define BUG() \
- do { \
- asm volatile("ud2"); \
- for(;;) ; \
- } while(0)
-#endif
-#endif
-
-#include <asm-generic/bug.h>
-#endif
diff --git a/include/asm-x86/bug_64.h b/include/asm-x86/bug_64.h
deleted file mode 100644
index 68260641491..00000000000
--- a/include/asm-x86/bug_64.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __ASM_X8664_BUG_H
-#define __ASM_X8664_BUG_H 1
-
-#ifdef CONFIG_BUG
-#define HAVE_ARCH_BUG
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#define BUG() \
- do { \
- asm volatile("1:\tud2\n" \
- ".pushsection __bug_table,\"a\"\n" \
- "2:\t.quad 1b, %c0\n" \
- "\t.word %c1, 0\n" \
- "\t.org 2b+%c2\n" \
- ".popsection" \
- : : "i" (__FILE__), "i" (__LINE__), \
- "i" (sizeof(struct bug_entry))); \
- for(;;) ; \
- } while(0)
-#else
-#define BUG() \
- do { \
- asm volatile("ud2"); \
- for(;;) ; \
- } while(0)
-#endif
-
-void out_of_line_bug(void);
-#else
-static inline void out_of_line_bug(void) { }
-#endif
-
-#include <asm-generic/bug.h>
-#endif
diff --git a/include/asm-x86/bugs.h b/include/asm-x86/bugs.h
index ddf42d36dd5..aac8317420a 100644
--- a/include/asm-x86/bugs.h
+++ b/include/asm-x86/bugs.h
@@ -1,5 +1,6 @@
-#ifdef CONFIG_X86_32
-# include "bugs_32.h"
-#else
-# include "bugs_64.h"
-#endif
+#ifndef _ASM_X86_BUGS_H
+#define _ASM_X86_BUGS_H
+
+void check_bugs(void);
+
+#endif /* _ASM_X86_BUGS_H */
diff --git a/include/asm-x86/bugs_32.h b/include/asm-x86/bugs_32.h
deleted file mode 100644
index d28979ff73b..00000000000
--- a/include/asm-x86/bugs_32.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- * void check_bugs(void);
- */
-#ifndef _ASM_I386_BUG_H
-#define _ASM_I386_BUG_H
-
-void check_bugs(void);
-
-#endif /* _ASM_I386_BUG_H */
diff --git a/include/asm-x86/bugs_64.h b/include/asm-x86/bugs_64.h
deleted file mode 100644
index b33dc04d8f4..00000000000
--- a/include/asm-x86/bugs_64.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_X86_64_BUGS_H
-#define _ASM_X86_64_BUGS_H
-
-void check_bugs(void);
-
-#endif /* _ASM_X86_64_BUGS_H */
diff --git a/include/asm-x86/cache.h b/include/asm-x86/cache.h
index c36d190ac9d..1e0bac86f38 100644
--- a/include/asm-x86/cache.h
+++ b/include/asm-x86/cache.h
@@ -1,5 +1,20 @@
-#ifdef CONFIG_X86_32
-# include "cache_32.h"
-#else
-# include "cache_64.h"
+#ifndef _ARCH_X86_CACHE_H
+#define _ARCH_X86_CACHE_H
+
+/* L1 cache line size */
+#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
+#ifdef CONFIG_X86_VSMP
+/* vSMP Internode cacheline shift */
+#define INTERNODE_CACHE_SHIFT (12)
+#ifdef CONFIG_SMP
+#define __cacheline_aligned_in_smp \
+ __attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT)))) \
+ __attribute__((__section__(".data.page_aligned")))
+#endif
+#endif
+
#endif
diff --git a/include/asm-x86/cache_32.h b/include/asm-x86/cache_32.h
deleted file mode 100644
index 57c62f41415..00000000000
--- a/include/asm-x86/cache_32.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * include/asm-i386/cache.h
- */
-#ifndef __ARCH_I386_CACHE_H
-#define __ARCH_I386_CACHE_H
-
-
-/* L1 cache line size */
-#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
-
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
-
-#endif
diff --git a/include/asm-x86/cache_64.h b/include/asm-x86/cache_64.h
deleted file mode 100644
index 052df758ae6..00000000000
--- a/include/asm-x86/cache_64.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * include/asm-x86_64/cache.h
- */
-#ifndef __ARCH_X8664_CACHE_H
-#define __ARCH_X8664_CACHE_H
-
-
-/* L1 cache line size */
-#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
-
-#ifdef CONFIG_X86_VSMP
-
-/* vSMP Internode cacheline shift */
-#define INTERNODE_CACHE_SHIFT (12)
-#ifdef CONFIG_SMP
-#define __cacheline_aligned_in_smp \
- __attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT)))) \
- __attribute__((__section__(".data.page_aligned")))
-#endif
-
-#endif
-
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
-
-#endif
diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h
index e2df3b55034..b3d43de44c5 100644
--- a/include/asm-x86/cacheflush.h
+++ b/include/asm-x86/cacheflush.h
@@ -1,5 +1,40 @@
-#ifdef CONFIG_X86_32
-# include "cacheflush_32.h"
-#else
-# include "cacheflush_64.h"
+#ifndef _ASM_X86_CACHEFLUSH_H
+#define _ASM_X86_CACHEFLUSH_H
+
+/* Keep includes the same across arches. */
+#include <linux/mm.h>
+
+/* Caches aren't brain-dead on the intel. */
+#define flush_cache_all() do { } while (0)
+#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_mm(mm) do { } while (0)
+#define flush_cache_range(vma, start, end) do { } while (0)
+#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
+#define flush_dcache_page(page) do { } while (0)
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+#define flush_icache_range(start, end) do { } while (0)
+#define flush_icache_page(vma,pg) do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
+#define flush_cache_vmap(start, end) do { } while (0)
+#define flush_cache_vunmap(start, end) do { } while (0)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy(dst, src, len)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy(dst, src, len)
+
+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);
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+/* internal debugging function */
+void kernel_map_pages(struct page *page, int numpages, int enable);
+#endif
+
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void);
+#endif
+
#endif
diff --git a/include/asm-x86/cacheflush_32.h b/include/asm-x86/cacheflush_32.h
deleted file mode 100644
index 74e03c8f2e5..00000000000
--- a/include/asm-x86/cacheflush_32.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _I386_CACHEFLUSH_H
-#define _I386_CACHEFLUSH_H
-
-/* Keep includes the same across arches. */
-#include <linux/mm.h>
-
-/* Caches aren't brain-dead on the intel. */
-#define flush_cache_all() do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_dcache_page(page) do { } while (0)
-#define flush_dcache_mmap_lock(mapping) do { } while (0)
-#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-#define flush_icache_range(start, end) do { } while (0)
-#define flush_icache_page(vma,pg) do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
-#define flush_cache_vmap(start, end) do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
-
-void global_flush_tlb(void);
-int change_page_attr(struct page *page, int numpages, pgprot_t prot);
-
-#ifdef CONFIG_DEBUG_PAGEALLOC
-/* internal debugging function */
-void kernel_map_pages(struct page *page, int numpages, int enable);
-#endif
-
-#ifdef CONFIG_DEBUG_RODATA
-void mark_rodata_ro(void);
-#endif
-
-#endif /* _I386_CACHEFLUSH_H */
diff --git a/include/asm-x86/cacheflush_64.h b/include/asm-x86/cacheflush_64.h
deleted file mode 100644
index ab1cb5c7dc9..00000000000
--- a/include/asm-x86/cacheflush_64.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _X8664_CACHEFLUSH_H
-#define _X8664_CACHEFLUSH_H
-
-/* Keep includes the same across arches. */
-#include <linux/mm.h>
-
-/* Caches aren't brain-dead on the intel. */
-#define flush_cache_all() do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_dcache_page(page) do { } while (0)
-#define flush_dcache_mmap_lock(mapping) do { } while (0)
-#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-#define flush_icache_range(start, end) do { } while (0)
-#define flush_icache_page(vma,pg) do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
-#define flush_cache_vmap(start, end) do { } while (0)
-#define flush_cache_vunmap(start, end) do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- memcpy(dst, src, len)
-
-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);
-
-#ifdef CONFIG_DEBUG_RODATA
-void mark_rodata_ro(void);
-#endif
-
-#endif /* _X8664_CACHEFLUSH_H */
diff --git a/include/asm-x86/cpu.h b/include/asm-x86/cpu.h
index 9d914e1e4aa..b1bc7b1b64b 100644
--- a/include/asm-x86/cpu.h
+++ b/include/asm-x86/cpu.h
@@ -13,9 +13,6 @@ struct i386_cpu {
extern int arch_register_cpu(int num);
#ifdef CONFIG_HOTPLUG_CPU
extern void arch_unregister_cpu(int);
-extern int enable_cpu_hotplug;
-#else
-#define enable_cpu_hotplug 0
#endif
DECLARE_PER_CPU(int, cpu_state);
diff --git a/include/asm-x86/cpufeature_32.h b/include/asm-x86/cpufeature_32.h
index 7b3aa28ebc6..f17e688dfb0 100644
--- a/include/asm-x86/cpufeature_32.h
+++ b/include/asm-x86/cpufeature_32.h
@@ -92,6 +92,7 @@
#define X86_FEATURE_CID (4*32+10) /* Context ID */
#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
+#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */
/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
diff --git a/include/asm-x86/cputime.h b/include/asm-x86/cputime.h
index 87c37cf6b70..6d68ad7e0ea 100644
--- a/include/asm-x86/cputime.h
+++ b/include/asm-x86/cputime.h
@@ -1,5 +1 @@
-#ifdef CONFIG_X86_32
-# include "cputime_32.h"
-#else
-# include "cputime_64.h"
-#endif
+#include <asm-generic/cputime.h>
diff --git a/include/asm-x86/cputime_32.h b/include/asm-x86/cputime_32.h
deleted file mode 100644
index 398ed7cd171..00000000000
--- a/include/asm-x86/cputime_32.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __I386_CPUTIME_H
-#define __I386_CPUTIME_H
-
-#include <asm-generic/cputime.h>
-
-#endif /* __I386_CPUTIME_H */
diff --git a/include/asm-x86/cputime_64.h b/include/asm-x86/cputime_64.h
deleted file mode 100644
index a07012dc5a3..00000000000
--- a/include/asm-x86/cputime_64.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __X86_64_CPUTIME_H
-#define __X86_64_CPUTIME_H
-
-#include <asm-generic/cputime.h>
-
-#endif /* __X86_64_CPUTIME_H */
diff --git a/include/asm-x86/debugreg.h b/include/asm-x86/debugreg.h
index b6ce7e4fa00..c6344d572b0 100644
--- a/include/asm-x86/debugreg.h
+++ b/include/asm-x86/debugreg.h
@@ -1,13 +1,70 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "debugreg_32.h"
-# else
-# include "debugreg_64.h"
-# endif
+#ifndef _ASM_X86_DEBUGREG_H
+#define _ASM_X86_DEBUGREG_H
+
+
+/* Indicate the register numbers for a number of the specific
+ debug registers. Registers 0-3 contain the addresses we wish to trap on */
+#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */
+#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */
+
+#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */
+#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */
+
+/* Define a few things for the status register. We can use this to determine
+ which debugging register was responsible for the trap. The other bits
+ are either reserved or not of interest to us. */
+
+#define DR_TRAP0 (0x1) /* db0 */
+#define DR_TRAP1 (0x2) /* db1 */
+#define DR_TRAP2 (0x4) /* db2 */
+#define DR_TRAP3 (0x8) /* db3 */
+
+#define DR_STEP (0x4000) /* single-step */
+#define DR_SWITCH (0x8000) /* task switch */
+
+/* Now define a bunch of things for manipulating the control register.
+ The top two bytes of the control register consist of 4 fields of 4
+ bits - each field corresponds to one of the four debug registers,
+ and indicates what types of access we trap on, and how large the data
+ field is that we are looking at */
+
+#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
+#define DR_CONTROL_SIZE 4 /* 4 control bits per register */
+
+#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */
+#define DR_RW_WRITE (0x1)
+#define DR_RW_READ (0x3)
+
+#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
+#define DR_LEN_2 (0x4)
+#define DR_LEN_4 (0xC)
+#define DR_LEN_8 (0x8)
+
+/* The low byte to the control register determine which registers are
+ enabled. There are 4 fields of two bits. One bit is "local", meaning
+ that the processor will reset the bit after a task switch and the other
+ is global meaning that we have to explicitly reset the bit. With linux,
+ you can use either one, since we explicitly zero the register when we enter
+ kernel mode. */
+
+#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
+#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
+#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
+
+#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
+#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
+
+/* The second byte to the control register has a few special things.
+ We can slow the instruction pipeline for instructions coming via the
+ gdt or the ldt if we want to. I am not sure why this is an advantage */
+
+#ifdef __i386__
+#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */
#else
-# ifdef __i386__
-# include "debugreg_32.h"
-# else
-# include "debugreg_64.h"
-# endif
+#define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */
+#endif
+
+#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
+#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
+
#endif
diff --git a/include/asm-x86/debugreg_32.h b/include/asm-x86/debugreg_32.h
deleted file mode 100644
index f0b2b06ae0f..00000000000
--- a/include/asm-x86/debugreg_32.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _I386_DEBUGREG_H
-#define _I386_DEBUGREG_H
-
-
-/* Indicate the register numbers for a number of the specific
- debug registers. Registers 0-3 contain the addresses we wish to trap on */
-#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */
-#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */
-
-#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */
-#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */
-
-/* Define a few things for the status register. We can use this to determine
- which debugging register was responsible for the trap. The other bits
- are either reserved or not of interest to us. */
-
-#define DR_TRAP0 (0x1) /* db0 */
-#define DR_TRAP1 (0x2) /* db1 */
-#define DR_TRAP2 (0x4) /* db2 */
-#define DR_TRAP3 (0x8) /* db3 */
-
-#define DR_STEP (0x4000) /* single-step */
-#define DR_SWITCH (0x8000) /* task switch */
-
-/* Now define a bunch of things for manipulating the control register.
- The top two bytes of the control register consist of 4 fields of 4
- bits - each field corresponds to one of the four debug registers,
- and indicates what types of access we trap on, and how large the data
- field is that we are looking at */
-
-#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
-#define DR_CONTROL_SIZE 4 /* 4 control bits per register */
-
-#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */
-#define DR_RW_WRITE (0x1)
-#define DR_RW_READ (0x3)
-
-#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
-#define DR_LEN_2 (0x4)
-#define DR_LEN_4 (0xC)
-
-/* The low byte to the control register determine which registers are
- enabled. There are 4 fields of two bits. One bit is "local", meaning
- that the processor will reset the bit after a task switch and the other
- is global meaning that we have to explicitly reset the bit. With linux,
- you can use either one, since we explicitly zero the register when we enter
- kernel mode. */
-
-#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
-#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
-#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
-
-#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
-#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
-
-/* The second byte to the control register has a few special things.
- We can slow the instruction pipeline for instructions coming via the
- gdt or the ldt if we want to. I am not sure why this is an advantage */
-
-#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */
-#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
-#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
-
-#endif
diff --git a/include/asm-x86/debugreg_64.h b/include/asm-x86/debugreg_64.h
deleted file mode 100644
index bd1aab1d8c4..00000000000
--- a/include/asm-x86/debugreg_64.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _X86_64_DEBUGREG_H
-#define _X86_64_DEBUGREG_H
-
-
-/* Indicate the register numbers for a number of the specific
- debug registers. Registers 0-3 contain the addresses we wish to trap on */
-#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */
-#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */
-
-#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */
-#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */
-
-/* Define a few things for the status register. We can use this to determine
- which debugging register was responsible for the trap. The other bits
- are either reserved or not of interest to us. */
-
-#define DR_TRAP0 (0x1) /* db0 */
-#define DR_TRAP1 (0x2) /* db1 */
-#define DR_TRAP2 (0x4) /* db2 */
-#define DR_TRAP3 (0x8) /* db3 */
-
-#define DR_STEP (0x4000) /* single-step */
-#define DR_SWITCH (0x8000) /* task switch */
-
-/* Now define a bunch of things for manipulating the control register.
- The top two bytes of the control register consist of 4 fields of 4
- bits - each field corresponds to one of the four debug registers,
- and indicates what types of access we trap on, and how large the data
- field is that we are looking at */
-
-#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
-#define DR_CONTROL_SIZE 4 /* 4 control bits per register */
-
-#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */
-#define DR_RW_WRITE (0x1)
-#define DR_RW_READ (0x3)
-
-#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
-#define DR_LEN_2 (0x4)
-#define DR_LEN_4 (0xC)
-#define DR_LEN_8 (0x8)
-
-/* The low byte to the control register determine which registers are
- enabled. There are 4 fields of two bits. One bit is "local", meaning
- that the processor will reset the bit after a task switch and the other
- is global meaning that we have to explicitly reset the bit. With linux,
- you can use either one, since we explicitly zero the register when we enter
- kernel mode. */
-
-#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
-#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
-#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
-
-#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
-#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
-
-/* The second byte to the control register has a few special things.
- We can slow the instruction pipeline for instructions coming via the
- gdt or the ldt if we want to. I am not sure why this is an advantage */
-
-#define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */
-#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
-#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
-
-#endif
diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h
index 10f2c71d622..d11d47fc1a0 100644
--- a/include/asm-x86/delay.h
+++ b/include/asm-x86/delay.h
@@ -1,5 +1,31 @@
-#ifdef CONFIG_X86_32
-# include "delay_32.h"
-#else
-# include "delay_64.h"
-#endif
+#ifndef _ASM_X86_DELAY_H
+#define _ASM_X86_DELAY_H
+
+/*
+ * Copyright (C) 1993 Linus Torvalds
+ *
+ * Delay routines calling functions in arch/x86/lib/delay.c
+ */
+
+/* Undefined functions to get compile-time errors */
+extern void __bad_udelay(void);
+extern void __bad_ndelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __ndelay(unsigned long nsecs);
+extern void __const_udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+/* 0x10c7 is 2**32 / 1000000 (rounded up) */
+#define udelay(n) (__builtin_constant_p(n) ? \
+ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
+ __udelay(n))
+
+/* 0x5 is 2**32 / 1000000000 (rounded up) */
+#define ndelay(n) (__builtin_constant_p(n) ? \
+ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
+ __ndelay(n))
+
+void use_tsc_delay(void);
+
+#endif /* _ASM_X86_DELAY_H */
diff --git a/include/asm-x86/delay_32.h b/include/asm-x86/delay_32.h
deleted file mode 100644
index 9ae5e3782ed..00000000000
--- a/include/asm-x86/delay_32.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _I386_DELAY_H
-#define _I386_DELAY_H
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines calling functions in arch/i386/lib/delay.c
- */
-
-/* Undefined functions to get compile-time errors */
-extern void __bad_udelay(void);
-extern void __bad_ndelay(void);
-
-extern void __udelay(unsigned long usecs);
-extern void __ndelay(unsigned long nsecs);
-extern void __const_udelay(unsigned long usecs);
-extern void __delay(unsigned long loops);
-
-/* 0x10c7 is 2**32 / 1000000 (rounded up) */
-#define udelay(n) (__builtin_constant_p(n) ? \
- ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
- __udelay(n))
-
-/* 0x5 is 2**32 / 1000000000 (rounded up) */
-#define ndelay(n) (__builtin_constant_p(n) ? \
- ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
- __ndelay(n))
-
-void use_tsc_delay(void);
-
-#endif /* defined(_I386_DELAY_H) */
diff --git a/include/asm-x86/delay_64.h b/include/asm-x86/delay_64.h
deleted file mode 100644
index c2669f1f552..00000000000
--- a/include/asm-x86/delay_64.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _X8664_DELAY_H
-#define _X8664_DELAY_H
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines calling functions in arch/x86_64/lib/delay.c
- */
-
-/* Undefined functions to get compile-time errors */
-extern void __bad_udelay(void);
-extern void __bad_ndelay(void);
-
-extern void __udelay(unsigned long usecs);
-extern void __ndelay(unsigned long nsecs);
-extern void __const_udelay(unsigned long usecs);
-extern void __delay(unsigned long loops);
-
-/* 0x10c7 is 2**32 / 1000000 (rounded up) */
-#define udelay(n) (__builtin_constant_p(n) ? \
- ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
- __udelay(n))
-
-/* 0x5 is 2**32 / 1000000000 (rounded up) */
-#define ndelay(n) (__builtin_constant_p(n) ? \
- ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
- __ndelay(n))
-
-
-#endif /* defined(_X8664_DELAY_H) */
diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h
index e2bcf7c7dce..d9ee5e52e91 100644
--- a/include/asm-x86/device.h
+++ b/include/asm-x86/device.h
@@ -1,5 +1,10 @@
-#ifdef CONFIG_X86_32
-# include "device_32.h"
-#else
-# include "device_64.h"
+#ifndef _ASM_X86_DEVICE_H
+#define _ASM_X86_DEVICE_H
+
+struct dev_archdata {
+#ifdef CONFIG_ACPI
+ void *acpi_handle;
#endif
+};
+
+#endif /* _ASM_X86_DEVICE_H */
diff --git a/include/asm-x86/device_32.h b/include/asm-x86/device_32.h
deleted file mode 100644
index 849604c70e6..00000000000
--- a/include/asm-x86/device_32.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Arch specific extensions to struct device
- *
- * This file is released under the GPLv2
- */
-#ifndef _ASM_I386_DEVICE_H
-#define _ASM_I386_DEVICE_H
-
-struct dev_archdata {
-#ifdef CONFIG_ACPI
- void *acpi_handle;
-#endif
-};
-
-#endif /* _ASM_I386_DEVICE_H */
diff --git a/include/asm-x86/device_64.h b/include/asm-x86/device_64.h
deleted file mode 100644
index 3afa03f33a3..00000000000
--- a/include/asm-x86/device_64.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Arch specific extensions to struct device
- *
- * This file is released under the GPLv2
- */
-#ifndef _ASM_X86_64_DEVICE_H
-#define _ASM_X86_64_DEVICE_H
-
-struct dev_archdata {
-#ifdef CONFIG_ACPI
- void *acpi_handle;
-#endif
-};
-
-#endif /* _ASM_X86_64_DEVICE_H */
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index f1d72d177f6..6a2d26cb5da 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -2,10 +2,10 @@
#define _ASM_I386_DMA_MAPPING_H
#include <linux/mm.h>
+#include <linux/scatterlist.h>
#include <asm/cache.h>
#include <asm/io.h>
-#include <asm/scatterlist.h>
#include <asm/bug.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
@@ -35,18 +35,19 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
}
static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
enum dma_data_direction direction)
{
+ struct scatterlist *sg;
int i;
BUG_ON(!valid_dma_direction(direction));
- WARN_ON(nents == 0 || sg[0].length == 0);
+ WARN_ON(nents == 0 || sglist[0].length == 0);
- for (i = 0; i < nents; i++ ) {
- BUG_ON(!sg[i].page);
+ for_each_sg(sglist, sg, nents, i) {
+ BUG_ON(!sg->page);
- sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset;
+ sg->dma_address = page_to_phys(sg->page) + sg->offset;
}
flush_write_buffers();
diff --git a/include/asm-x86/dma-mapping_64.h b/include/asm-x86/dma-mapping_64.h
index 6897e2a436e..ecd0f6125ba 100644
--- a/include/asm-x86/dma-mapping_64.h
+++ b/include/asm-x86/dma-mapping_64.h
@@ -6,8 +6,7 @@
* documentation.
*/
-
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/swiotlb.h>
diff --git a/include/asm-x86/dmi.h b/include/asm-x86/dmi.h
index c9e4e8ebc27..8e2b0e6aa8e 100644
--- a/include/asm-x86/dmi.h
+++ b/include/asm-x86/dmi.h
@@ -1,5 +1,35 @@
+#ifndef _ASM_X86_DMI_H
+#define _ASM_X86_DMI_H
+
+#include <asm/io.h>
+
#ifdef CONFIG_X86_32
-# include "dmi_32.h"
-#else
-# include "dmi_64.h"
+
+/* Use early IO mappings for DMI because it's initialized early */
+#define dmi_ioremap bt_ioremap
+#define dmi_iounmap bt_iounmap
+#define dmi_alloc alloc_bootmem
+
+#else /* CONFIG_X86_32 */
+
+#define DMI_MAX_DATA 2048
+
+extern int dmi_alloc_index;
+extern char dmi_alloc_data[DMI_MAX_DATA];
+
+/* This is so early that there is no good way to allocate dynamic memory.
+ Allocate data in an BSS array. */
+static inline void *dmi_alloc(unsigned len)
+{
+ int idx = dmi_alloc_index;
+ if ((dmi_alloc_index += len) > DMI_MAX_DATA)
+ return NULL;
+ return dmi_alloc_data + idx;
+}
+
+#define dmi_ioremap early_ioremap
+#define dmi_iounmap early_iounmap
+
+#endif
+
#endif
diff --git a/include/asm-x86/dmi_32.h b/include/asm-x86/dmi_32.h
deleted file mode 100644
index 38d4eeb7fc7..00000000000
--- a/include/asm-x86/dmi_32.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _ASM_DMI_H
-#define _ASM_DMI_H 1
-
-#include <asm/io.h>
-
-/* Use early IO mappings for DMI because it's initialized early */
-#define dmi_ioremap bt_ioremap
-#define dmi_iounmap bt_iounmap
-#define dmi_alloc alloc_bootmem
-
-#endif
diff --git a/include/asm-x86/dmi_64.h b/include/asm-x86/dmi_64.h
deleted file mode 100644
index d02e32e3c3f..00000000000
--- a/include/asm-x86/dmi_64.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _ASM_DMI_H
-#define _ASM_DMI_H 1
-
-#include <asm/io.h>
-
-#define DMI_MAX_DATA 2048
-
-extern int dmi_alloc_index;
-extern char dmi_alloc_data[DMI_MAX_DATA];
-
-/* This is so early that there is no good way to allocate dynamic memory.
- Allocate data in an BSS array. */
-static inline void *dmi_alloc(unsigned len)
-{
- int idx = dmi_alloc_index;
- if ((dmi_alloc_index += len) > DMI_MAX_DATA)
- return NULL;
- return dmi_alloc_data + idx;
-}
-
-#define dmi_ioremap early_ioremap
-#define dmi_iounmap early_iounmap
-
-#endif
diff --git a/include/asm-x86/edac.h b/include/asm-x86/edac.h
index f8b888e140b..cf3200a745a 100644
--- a/include/asm-x86/edac.h
+++ b/include/asm-x86/edac.h
@@ -1,5 +1,18 @@
-#ifdef CONFIG_X86_32
-# include "edac_32.h"
-#else
-# include "edac_64.h"
+#ifndef _ASM_X86_EDAC_H
+#define _ASM_X86_EDAC_H
+
+/* ECC atomic, DMA, SMP and interrupt safe scrub function */
+
+static __inline__ void atomic_scrub(void *va, u32 size)
+{
+ u32 i, *virt_addr = va;
+
+ /*
+ * Very carefully read and write to memory atomically so we
+ * are interrupt, DMA and SMP safe.
+ */
+ for (i = 0; i < size / 4; i++, virt_addr++)
+ __asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
+}
+
#endif
diff --git a/include/asm-x86/edac_32.h b/include/asm-x86/edac_32.h
deleted file mode 100644
index 3e7dd0ab68c..00000000000
--- a/include/asm-x86/edac_32.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef ASM_EDAC_H
-#define ASM_EDAC_H
-
-/* ECC atomic, DMA, SMP and interrupt safe scrub function */
-
-static __inline__ void atomic_scrub(void *va, u32 size)
-{
- unsigned long *virt_addr = va;
- u32 i;
-
- for (i = 0; i < size / 4; i++, virt_addr++)
- /* Very carefully read and write to memory atomically
- * so we are interrupt, DMA and SMP safe.
- */
- __asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
-}
-
-#endif
diff --git a/include/asm-x86/edac_64.h b/include/asm-x86/edac_64.h
deleted file mode 100644
index cad1cd42b4e..00000000000
--- a/include/asm-x86/edac_64.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef ASM_EDAC_H
-#define ASM_EDAC_H
-
-/* ECC atomic, DMA, SMP and interrupt safe scrub function */
-
-static __inline__ void atomic_scrub(void *va, u32 size)
-{
- unsigned int *virt_addr = va;
- u32 i;
-
- for (i = 0; i < size / 4; i++, virt_addr++)
- /* Very carefully read and write to memory atomically
- * so we are interrupt, DMA and SMP safe.
- */
- __asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
-}
-
-#endif
diff --git a/include/asm-x86/elf_32.h b/include/asm-x86/elf_32.h
index b32df3a332d..b3f694eaaf3 100644
--- a/include/asm-x86/elf_32.h
+++ b/include/asm-x86/elf_32.h
@@ -129,6 +129,7 @@ extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct
#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
#define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
+#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
#define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
@@ -152,6 +153,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
extern unsigned int vdso_enabled;
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
#define ARCH_DLINFO \
do if (vdso_enabled) { \
NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
diff --git a/include/asm-x86/errno.h b/include/asm-x86/errno.h
index 9d511be8e57..4c82b503d92 100644
--- a/include/asm-x86/errno.h
+++ b/include/asm-x86/errno.h
@@ -1,13 +1 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "errno_32.h"
-# else
-# include "errno_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "errno_32.h"
-# else
-# include "errno_64.h"
-# endif
-#endif
+#include <asm-generic/errno.h>
diff --git a/include/asm-x86/errno_32.h b/include/asm-x86/errno_32.h
deleted file mode 100644
index 969b3437472..00000000000
--- a/include/asm-x86/errno_32.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _I386_ERRNO_H
-#define _I386_ERRNO_H
-
-#include <asm-generic/errno.h>
-
-#endif
diff --git a/include/asm-x86/errno_64.h b/include/asm-x86/errno_64.h
deleted file mode 100644
index 311182129e3..00000000000
--- a/include/asm-x86/errno_64.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _X8664_ERRNO_H
-#define _X8664_ERRNO_H
-
-#include <asm-generic/errno.h>
-
-#endif
diff --git a/include/asm-x86/fb.h b/include/asm-x86/fb.h
index 238c7ca4587..53018464aea 100644
--- a/include/asm-x86/fb.h
+++ b/include/asm-x86/fb.h
@@ -1,5 +1,21 @@
+#ifndef _ASM_X86_FB_H
+#define _ASM_X86_FB_H
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ if (boot_cpu_data.x86 > 3)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+}
+
#ifdef CONFIG_X86_32
-# include "fb_32.h"
+extern int fb_is_primary_device(struct fb_info *info);
#else
-# include "fb_64.h"
+static inline int fb_is_primary_device(struct fb_info *info) { return 0; }
#endif
+
+#endif /* _ASM_X86_FB_H */
diff --git a/include/asm-x86/fb_32.h b/include/asm-x86/fb_32.h
deleted file mode 100644
index d1c6297d4a6..00000000000
--- a/include/asm-x86/fb_32.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-
-extern int fb_is_primary_device(struct fb_info *info);
-
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- if (boot_cpu_data.x86 > 3)
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/include/asm-x86/fb_64.h b/include/asm-x86/fb_64.h
deleted file mode 100644
index 60548e651d1..00000000000
--- a/include/asm-x86/fb_64.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- if (boot_cpu_data.x86 > 3)
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-}
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/include/asm-x86/floppy.h b/include/asm-x86/floppy.h
index aecbb6dca21..a48d7153c09 100644
--- a/include/asm-x86/floppy.h
+++ b/include/asm-x86/floppy.h
@@ -1,5 +1,278 @@
-#ifdef CONFIG_X86_32
-# include "floppy_32.h"
-#else
-# include "floppy_64.h"
+/*
+ * Architecture specific parts of the Floppy driver
+ *
+ * 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
+ */
+#ifndef _ASM_X86_FLOPPY_H
+#define _ASM_X86_FLOPPY_H
+
+#include <linux/vmalloc.h>
+
+/*
+ * The DMA channel used by the floppy controller cannot access data at
+ * addresses >= 16MB
+ *
+ * Went back to the 1MB limit, as some people had problems with the floppy
+ * driver otherwise. It doesn't matter much for performance anyway, as most
+ * floppy accesses go through the track buffer.
+ */
+#define _CROSS_64KB(a,s,vdma) \
+(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
+
+#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
+
+
+#define SW fd_routine[use_virtual_dma&1]
+#define CSW fd_routine[can_use_virtual_dma & 1]
+
+
+#define fd_inb(port) inb_p(port)
+#define fd_outb(value,port) outb_p(value,port)
+
+#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy")
+#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)
+#define fd_enable_irq() enable_irq(FLOPPY_IRQ)
+#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
+#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
+#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA)
+#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size)
+#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
+
+#define FLOPPY_CAN_FALLBACK_ON_NODMA
+
+static int virtual_dma_count;
+static int virtual_dma_residue;
+static char *virtual_dma_addr;
+static int virtual_dma_mode;
+static int doing_pdma;
+
+static irqreturn_t floppy_hardint(int irq, void *dev_id)
+{
+ register unsigned char st;
+
+#undef TRACE_FLPY_INT
+
+#ifdef TRACE_FLPY_INT
+ static int calls=0;
+ static int bytes=0;
+ static int dma_wait=0;
#endif
+ if (!doing_pdma)
+ return floppy_interrupt(irq, dev_id);
+
+#ifdef TRACE_FLPY_INT
+ if(!calls)
+ bytes = virtual_dma_count;
+#endif
+
+ {
+ register int lcount;
+ register char *lptr;
+
+ st = 1;
+ for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
+ lcount; lcount--, lptr++) {
+ st=inb(virtual_dma_port+4) & 0xa0 ;
+ if(st != 0xa0)
+ break;
+ if(virtual_dma_mode)
+ outb_p(*lptr, virtual_dma_port+5);
+ else
+ *lptr = inb_p(virtual_dma_port+5);
+ }
+ virtual_dma_count = lcount;
+ virtual_dma_addr = lptr;
+ st = inb(virtual_dma_port+4);
+ }
+
+#ifdef TRACE_FLPY_INT
+ calls++;
+#endif
+ if(st == 0x20)
+ return IRQ_HANDLED;
+ if(!(st & 0x20)) {
+ virtual_dma_residue += virtual_dma_count;
+ virtual_dma_count=0;
+#ifdef TRACE_FLPY_INT
+ printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
+ virtual_dma_count, virtual_dma_residue, calls, bytes,
+ dma_wait);
+ calls = 0;
+ dma_wait=0;
+#endif
+ doing_pdma = 0;
+ floppy_interrupt(irq, dev_id);
+ return IRQ_HANDLED;
+ }
+#ifdef TRACE_FLPY_INT
+ if(!virtual_dma_count)
+ dma_wait++;
+#endif
+ return IRQ_HANDLED;
+}
+
+static void fd_disable_dma(void)
+{
+ if(! (can_use_virtual_dma & 1))
+ disable_dma(FLOPPY_DMA);
+ doing_pdma = 0;
+ virtual_dma_residue += virtual_dma_count;
+ virtual_dma_count=0;
+}
+
+static int vdma_request_dma(unsigned int dmanr, const char * device_id)
+{
+ return 0;
+}
+
+static void vdma_nop(unsigned int dummy)
+{
+}
+
+
+static int vdma_get_dma_residue(unsigned int dummy)
+{
+ return virtual_dma_count + virtual_dma_residue;
+}
+
+
+static int fd_request_irq(void)
+{
+ if(can_use_virtual_dma)
+ return request_irq(FLOPPY_IRQ, floppy_hardint,
+ IRQF_DISABLED, "floppy", NULL);
+ else
+ return request_irq(FLOPPY_IRQ, floppy_interrupt,
+ IRQF_DISABLED, "floppy", NULL);
+}
+
+static unsigned long dma_mem_alloc(unsigned long size)
+{
+ return __get_dma_pages(GFP_KERNEL|__GFP_NORETRY,get_order(size));
+}
+
+
+static unsigned long vdma_mem_alloc(unsigned long size)
+{
+ return (unsigned long) vmalloc(size);
+
+}
+
+#define nodma_mem_alloc(size) vdma_mem_alloc(size)
+
+static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
+{
+ if((unsigned long) addr >= (unsigned long) high_memory)
+ vfree((void *)addr);
+ else
+ free_pages(addr, get_order(size));
+}
+
+#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size)
+
+static void _fd_chose_dma_mode(char *addr, unsigned long size)
+{
+ if(can_use_virtual_dma == 2) {
+ if((unsigned long) addr >= (unsigned long) high_memory ||
+ isa_virt_to_bus(addr) >= 0x1000000 ||
+ _CROSS_64KB(addr, size, 0))
+ use_virtual_dma = 1;
+ else
+ use_virtual_dma = 0;
+ } else {
+ use_virtual_dma = can_use_virtual_dma & 1;
+ }
+}
+
+#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
+
+
+static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
+{
+ doing_pdma = 1;
+ virtual_dma_port = io;
+ virtual_dma_mode = (mode == DMA_MODE_WRITE);
+ virtual_dma_addr = addr;
+ virtual_dma_count = size;
+ virtual_dma_residue = 0;
+ return 0;
+}
+
+static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
+{
+#ifdef FLOPPY_SANITY_CHECK
+ if (CROSS_64KB(addr, size)) {
+ printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
+ return -1;
+ }
+#endif
+ /* actual, physical DMA */
+ doing_pdma = 0;
+ clear_dma_ff(FLOPPY_DMA);
+ set_dma_mode(FLOPPY_DMA,mode);
+ set_dma_addr(FLOPPY_DMA,isa_virt_to_bus(addr));
+ set_dma_count(FLOPPY_DMA,size);
+ enable_dma(FLOPPY_DMA);
+ return 0;
+}
+
+static struct fd_routine_l {
+ int (*_request_dma)(unsigned int dmanr, const char * device_id);
+ void (*_free_dma)(unsigned int dmanr);
+ int (*_get_dma_residue)(unsigned int dummy);
+ unsigned long (*_dma_mem_alloc) (unsigned long size);
+ int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
+} fd_routine[] = {
+ {
+ request_dma,
+ free_dma,
+ get_dma_residue,
+ dma_mem_alloc,
+ hard_dma_setup
+ },
+ {
+ vdma_request_dma,
+ vdma_nop,
+ vdma_get_dma_residue,
+ vdma_mem_alloc,
+ vdma_dma_setup
+ }
+};
+
+
+static int FDC1 = 0x3f0;
+static int FDC2 = -1;
+
+/*
+ * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
+ * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
+ * coincides with another rtc CMOS user. Paul G.
+ */
+#define FLOPPY0_TYPE ({ \
+ unsigned long flags; \
+ unsigned char val; \
+ spin_lock_irqsave(&rtc_lock, flags); \
+ val = (CMOS_READ(0x10) >> 4) & 15; \
+ spin_unlock_irqrestore(&rtc_lock, flags); \
+ val; \
+})
+
+#define FLOPPY1_TYPE ({ \
+ unsigned long flags; \
+ unsigned char val; \
+ spin_lock_irqsave(&rtc_lock, flags); \
+ val = CMOS_READ(0x10) & 15; \
+ spin_unlock_irqrestore(&rtc_lock, flags); \
+ val; \
+})
+
+#define N_FDC 2
+#define N_DRIVE 8
+
+#define EXTRA_FLOPPY_PARAMS
+
+#endif /* _ASM_X86_FLOPPY_H */
diff --git a/include/asm-x86/floppy_32.h b/include/asm-x86/floppy_32.h
deleted file mode 100644
index 44ef2f55a8e..00000000000
--- a/include/asm-x86/floppy_32.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Architecture specific parts of the Floppy driver
- *
- * 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
- */
-#ifndef __ASM_I386_FLOPPY_H
-#define __ASM_I386_FLOPPY_H
-
-#include <linux/vmalloc.h>
-
-
-/*
- * The DMA channel used by the floppy controller cannot access data at
- * addresses >= 16MB
- *
- * Went back to the 1MB limit, as some people had problems with the floppy
- * driver otherwise. It doesn't matter much for performance anyway, as most
- * floppy accesses go through the track buffer.
- */
-#define _CROSS_64KB(a,s,vdma) \
-(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
-
-#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
-
-
-#define SW fd_routine[use_virtual_dma&1]
-#define CSW fd_routine[can_use_virtual_dma & 1]
-
-
-#define fd_inb(port) inb_p(port)
-#define fd_outb(value,port) outb_p(value,port)
-
-#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy")
-#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)
-#define fd_enable_irq() enable_irq(FLOPPY_IRQ)
-#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
-#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
-#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA)
-#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size)
-#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
-
-#define FLOPPY_CAN_FALLBACK_ON_NODMA
-
-static int virtual_dma_count;
-static int virtual_dma_residue;
-static char *virtual_dma_addr;
-static int virtual_dma_mode;
-static int doing_pdma;
-
-static irqreturn_t floppy_hardint(int irq, void *dev_id)
-{
- register unsigned char st;
-
-#undef TRACE_FLPY_INT
-
-#ifdef TRACE_FLPY_INT
- static int calls=0;
- static int bytes=0;
- static int dma_wait=0;
-#endif
- if (!doing_pdma)
- return floppy_interrupt(irq, dev_id);
-
-#ifdef TRACE_FLPY_INT
- if(!calls)
- bytes = virtual_dma_count;
-#endif
-
- {
- register int lcount;
- register char *lptr;
-
- st = 1;
- for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
- lcount; lcount--, lptr++) {
- st=inb(virtual_dma_port+4) & 0xa0 ;
- if(st != 0xa0)
- break;
- if(virtual_dma_mode)
- outb_p(*lptr, virtual_dma_port+5);
- else
- *lptr = inb_p(virtual_dma_port+5);
- }
- virtual_dma_count = lcount;
- virtual_dma_addr = lptr;
- st = inb(virtual_dma_port+4);
- }
-
-#ifdef TRACE_FLPY_INT
- calls++;
-#endif
- if(st == 0x20)
- return IRQ_HANDLED;
- if(!(st & 0x20)) {
- virtual_dma_residue += virtual_dma_count;
- virtual_dma_count=0;
-#ifdef TRACE_FLPY_INT
- printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
- virtual_dma_count, virtual_dma_residue, calls, bytes,
- dma_wait);
- calls = 0;
- dma_wait=0;
-#endif
- doing_pdma = 0;
- floppy_interrupt(irq, dev_id);
- return IRQ_HANDLED;
- }
-#ifdef TRACE_FLPY_INT
- if(!virtual_dma_count)
- dma_wait++;
-#endif
- return IRQ_HANDLED;
-}
-
-static void fd_disable_dma(void)
-{
- if(! (can_use_virtual_dma & 1))
- disable_dma(FLOPPY_DMA);
- doing_pdma = 0;
- virtual_dma_residue += virtual_dma_count;
- virtual_dma_count=0;
-}
-
-static int vdma_request_dma(unsigned int dmanr, const char * device_id)
-{
- return 0;
-}
-
-static void vdma_nop(unsigned int dummy)
-{
-}
-
-
-static int vdma_get_dma_residue(unsigned int dummy)
-{
- return virtual_dma_count + virtual_dma_residue;
-}
-
-
-static int fd_request_irq(void)
-{
- if(can_use_virtual_dma)
- return request_irq(FLOPPY_IRQ, floppy_hardint,
- IRQF_DISABLED, "floppy", NULL);
- else
- return request_irq(FLOPPY_IRQ, floppy_interrupt,
- IRQF_DISABLED, "floppy", NULL);
-
-}
-
-static unsigned long dma_mem_alloc(unsigned long size)
-{
- return __get_dma_pages(GFP_KERNEL,get_order(size));
-}
-
-
-static unsigned long vdma_mem_alloc(unsigned long size)
-{
- return (unsigned long) vmalloc(size);
-
-}
-
-#define nodma_mem_alloc(size) vdma_mem_alloc(size)
-
-static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
-{
- if((unsigned int) addr >= (unsigned int) high_memory)
- vfree((void *)addr);
- else
- free_pages(addr, get_order(size));
-}
-
-#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size)
-
-static void _fd_chose_dma_mode(char *addr, unsigned long size)
-{
- if(can_use_virtual_dma == 2) {
- if((unsigned int) addr >= (unsigned int) high_memory ||
- isa_virt_to_bus(addr) >= 0x1000000 ||
- _CROSS_64KB(addr, size, 0))
- use_virtual_dma = 1;
- else
- use_virtual_dma = 0;
- } else {
- use_virtual_dma = can_use_virtual_dma & 1;
- }
-}
-
-#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
-
-
-static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
-{
- doing_pdma = 1;
- virtual_dma_port = io;
- virtual_dma_mode = (mode == DMA_MODE_WRITE);
- virtual_dma_addr = addr;
- virtual_dma_count = size;
- virtual_dma_residue = 0;
- return 0;
-}
-
-static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
-{
-#ifdef FLOPPY_SANITY_CHECK
- if (CROSS_64KB(addr, size)) {
- printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
- return -1;
- }
-#endif
- /* actual, physical DMA */
- doing_pdma = 0;
- clear_dma_ff(FLOPPY_DMA);
- set_dma_mode(FLOPPY_DMA,mode);
- set_dma_addr(FLOPPY_DMA,isa_virt_to_bus(addr));
- set_dma_count(FLOPPY_DMA,size);
- enable_dma(FLOPPY_DMA);
- return 0;
-}
-
-static struct fd_routine_l {
- int (*_request_dma)(unsigned int dmanr, const char * device_id);
- void (*_free_dma)(unsigned int dmanr);
- int (*_get_dma_residue)(unsigned int dummy);
- unsigned long (*_dma_mem_alloc) (unsigned long size);
- int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
-} fd_routine[] = {
- {
- request_dma,
- free_dma,
- get_dma_residue,
- dma_mem_alloc,
- hard_dma_setup
- },
- {
- vdma_request_dma,
- vdma_nop,
- vdma_get_dma_residue,
- vdma_mem_alloc,
- vdma_dma_setup
- }
-};
-
-
-static int FDC1 = 0x3f0;
-static int FDC2 = -1;
-
-/*
- * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
- * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
- * coincides with another rtc CMOS user. Paul G.
- */
-#define FLOPPY0_TYPE ({ \
- unsigned long flags; \
- unsigned char val; \
- spin_lock_irqsave(&rtc_lock, flags); \
- val = (CMOS_READ(0x10) >> 4) & 15; \
- spin_unlock_irqrestore(&rtc_lock, flags); \
- val; \
-})
-
-#define FLOPPY1_TYPE ({ \
- unsigned long flags; \
- unsigned char val; \
- spin_lock_irqsave(&rtc_lock, flags); \
- val = CMOS_READ(0x10) & 15; \
- spin_unlock_irqrestore(&rtc_lock, flags); \
- val; \
-})
-
-#define N_FDC 2
-#define N_DRIVE 8
-
-#define FLOPPY_MOTOR_MASK 0xf0
-
-#define AUTO_DMA
-
-#define EXTRA_FLOPPY_PARAMS
-
-#endif /* __ASM_I386_FLOPPY_H */
diff --git a/include/asm-x86/floppy_64.h b/include/asm-x86/floppy_64.h
deleted file mode 100644
index 6ea13c3806f..00000000000
--- a/include/asm-x86/floppy_64.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Architecture specific parts of the Floppy driver
- *
- * 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
- */
-#ifndef __ASM_X86_64_FLOPPY_H
-#define __ASM_X86_64_FLOPPY_H
-
-#include <linux/vmalloc.h>
-
-
-/*
- * The DMA channel used by the floppy controller cannot access data at
- * addresses >= 16MB
- *
- * Went back to the 1MB limit, as some people had problems with the floppy
- * driver otherwise. It doesn't matter much for performance anyway, as most
- * floppy accesses go through the track buffer.
- */
-#define _CROSS_64KB(a,s,vdma) \
-(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
-
-#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)
-
-
-#define SW fd_routine[use_virtual_dma&1]
-#define CSW fd_routine[can_use_virtual_dma & 1]
-
-
-#define fd_inb(port) inb_p(port)
-#define fd_outb(value,port) outb_p(value,port)
-
-#define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy")
-#define fd_free_dma() CSW._free_dma(FLOPPY_DMA)
-#define fd_enable_irq() enable_irq(FLOPPY_IRQ)
-#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
-#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL)
-#define fd_get_dma_residue() SW._get_dma_residue(FLOPPY_DMA)
-#define fd_dma_mem_alloc(size) SW._dma_mem_alloc(size)
-#define fd_dma_setup(addr, size, mode, io) SW._dma_setup(addr, size, mode, io)
-
-#define FLOPPY_CAN_FALLBACK_ON_NODMA
-
-static int virtual_dma_count;
-static int virtual_dma_residue;
-static char *virtual_dma_addr;
-static int virtual_dma_mode;
-static int doing_pdma;
-
-static irqreturn_t floppy_hardint(int irq, void *dev_id)
-{
- register unsigned char st;
-
-#undef TRACE_FLPY_INT
-
-#ifdef TRACE_FLPY_INT
- static int calls=0;
- static int bytes=0;
- static int dma_wait=0;
-#endif
- if (!doing_pdma)
- return floppy_interrupt(irq, dev_id);
-
-#ifdef TRACE_FLPY_INT
- if(!calls)
- bytes = virtual_dma_count;
-#endif
-
- {
- register int lcount;
- register char *lptr;
-
- st = 1;
- for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
- lcount; lcount--, lptr++) {
- st=inb(virtual_dma_port+4) & 0xa0 ;
- if(st != 0xa0)
- break;
- if(virtual_dma_mode)
- outb_p(*lptr, virtual_dma_port+5);
- else
- *lptr = inb_p(virtual_dma_port+5);
- }
- virtual_dma_count = lcount;
- virtual_dma_addr = lptr;
- st = inb(virtual_dma_port+4);
- }
-
-#ifdef TRACE_FLPY_INT
- calls++;
-#endif
- if(st == 0x20)
- return IRQ_HANDLED;
- if(!(st & 0x20)) {
- virtual_dma_residue += virtual_dma_count;
- virtual_dma_count=0;
-#ifdef TRACE_FLPY_INT
- printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n",
- virtual_dma_count, virtual_dma_residue, calls, bytes,
- dma_wait);
- calls = 0;
- dma_wait=0;
-#endif
- doing_pdma = 0;
- floppy_interrupt(irq, dev_id);
- return IRQ_HANDLED;
- }
-#ifdef TRACE_FLPY_INT
- if(!virtual_dma_count)
- dma_wait++;
-#endif
- return IRQ_HANDLED;
-}
-
-static void fd_disable_dma(void)
-{
- if(! (can_use_virtual_dma & 1))
- disable_dma(FLOPPY_DMA);
- doing_pdma = 0;
- virtual_dma_residue += virtual_dma_count;
- virtual_dma_count=0;
-}
-
-static int vdma_request_dma(unsigned int dmanr, const char * device_id)
-{
- return 0;
-}
-
-static void vdma_nop(unsigned int dummy)
-{
-}
-
-
-static int vdma_get_dma_residue(unsigned int dummy)
-{
- return virtual_dma_count + virtual_dma_residue;
-}
-
-
-static int fd_request_irq(void)
-{
- if(can_use_virtual_dma)
- return request_irq(FLOPPY_IRQ, floppy_hardint,
- IRQF_DISABLED, "floppy", NULL);
- else
- return request_irq(FLOPPY_IRQ, floppy_interrupt,
- IRQF_DISABLED, "floppy", NULL);
-}
-
-static unsigned long dma_mem_alloc(unsigned long size)
-{
- return __get_dma_pages(GFP_KERNEL|__GFP_NORETRY,get_order(size));
-}
-
-
-static unsigned long vdma_mem_alloc(unsigned long size)
-{
- return (unsigned long) vmalloc(size);
-
-}
-
-#define nodma_mem_alloc(size) vdma_mem_alloc(size)
-
-static void _fd_dma_mem_free(unsigned long addr, unsigned long size)
-{
- if((unsigned long) addr >= (unsigned long) high_memory)
- vfree((void *)addr);
- else
- free_pages(addr, get_order(size));
-}
-
-#define fd_dma_mem_free(addr, size) _fd_dma_mem_free(addr, size)
-
-static void _fd_chose_dma_mode(char *addr, unsigned long size)
-{
- if(can_use_virtual_dma == 2) {
- if((unsigned long) addr >= (unsigned long) high_memory ||
- isa_virt_to_bus(addr) >= 0x1000000 ||
- _CROSS_64KB(addr, size, 0))
- use_virtual_dma = 1;
- else
- use_virtual_dma = 0;
- } else {
- use_virtual_dma = can_use_virtual_dma & 1;
- }
-}
-
-#define fd_chose_dma_mode(addr, size) _fd_chose_dma_mode(addr, size)
-
-
-static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io)
-{
- doing_pdma = 1;
- virtual_dma_port = io;
- virtual_dma_mode = (mode == DMA_MODE_WRITE);
- virtual_dma_addr = addr;
- virtual_dma_count = size;
- virtual_dma_residue = 0;
- return 0;
-}
-
-static int hard_dma_setup(char *addr, unsigned long size, int mode, int io)
-{
-#ifdef FLOPPY_SANITY_CHECK
- if (CROSS_64KB(addr, size)) {
- printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size);
- return -1;
- }
-#endif
- /* actual, physical DMA */
- doing_pdma = 0;
- clear_dma_ff(FLOPPY_DMA);
- set_dma_mode(FLOPPY_DMA,mode);
- set_dma_addr(FLOPPY_DMA,isa_virt_to_bus(addr));
- set_dma_count(FLOPPY_DMA,size);
- enable_dma(FLOPPY_DMA);
- return 0;
-}
-
-static struct fd_routine_l {
- int (*_request_dma)(unsigned int dmanr, const char * device_id);
- void (*_free_dma)(unsigned int dmanr);
- int (*_get_dma_residue)(unsigned int dummy);
- unsigned long (*_dma_mem_alloc) (unsigned long size);
- int (*_dma_setup)(char *addr, unsigned long size, int mode, int io);
-} fd_routine[] = {
- {
- request_dma,
- free_dma,
- get_dma_residue,
- dma_mem_alloc,
- hard_dma_setup
- },
- {
- vdma_request_dma,
- vdma_nop,
- vdma_get_dma_residue,
- vdma_mem_alloc,
- vdma_dma_setup
- }
-};
-
-
-static int FDC1 = 0x3f0;
-static int FDC2 = -1;
-
-/*
- * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock
- * is needed to prevent corrupted CMOS RAM in case "insmod floppy"
- * coincides with another rtc CMOS user. Paul G.
- */
-#define FLOPPY0_TYPE ({ \
- unsigned long flags; \
- unsigned char val; \
- spin_lock_irqsave(&rtc_lock, flags); \
- val = (CMOS_READ(0x10) >> 4) & 15; \
- spin_unlock_irqrestore(&rtc_lock, flags); \
- val; \
-})
-
-#define FLOPPY1_TYPE ({ \
- unsigned long flags; \
- unsigned char val; \
- spin_lock_irqsave(&rtc_lock, flags); \
- val = CMOS_READ(0x10) & 15; \
- spin_unlock_irqrestore(&rtc_lock, flags); \
- val; \
-})
-
-#define N_FDC 2
-#define N_DRIVE 8
-
-#define FLOPPY_MOTOR_MASK 0xf0
-
-#define AUTO_DMA
-
-#define EXTRA_FLOPPY_PARAMS
-
-#endif /* __ASM_X86_64_FLOPPY_H */
diff --git a/include/asm-x86/frame.i b/include/asm-x86/frame.h
index 03620251ae1..06850a7194e 100644
--- a/include/asm-x86/frame.i
+++ b/include/asm-x86/frame.h
@@ -1,3 +1,5 @@
+#ifdef __ASSEMBLY__
+
#include <asm/dwarf2.h>
/* The annotation hides the frame from the unwinder and makes it look
@@ -21,3 +23,5 @@
.macro ENDFRAME
.endm
#endif
+
+#endif /* __ASSEMBLY__ */
diff --git a/include/asm-x86/hardirq_32.h b/include/asm-x86/hardirq_32.h
index 34649585bb5..4f85f0f4b56 100644
--- a/include/asm-x86/hardirq_32.h
+++ b/include/asm-x86/hardirq_32.h
@@ -10,10 +10,14 @@ typedef struct {
unsigned int __nmi_count; /* arch dependent */
unsigned int apic_timer_irqs; /* arch dependent */
unsigned int irq0_irqs;
+ unsigned int irq_resched_count;
+ unsigned int irq_call_count;
+ unsigned int irq_tlb_count;
+ unsigned int irq_thermal_count;
+ unsigned int irq_spurious_count;
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
-extern irq_cpustat_t irq_stat[];
#define __ARCH_IRQ_STAT
#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
diff --git a/include/asm-x86/hw_irq_64.h b/include/asm-x86/hw_irq_64.h
index 09dfc18a6dd..a470d59da67 100644
--- a/include/asm-x86/hw_irq_64.h
+++ b/include/asm-x86/hw_irq_64.h
@@ -40,22 +40,22 @@
/*
* Vectors 0x30-0x3f are used for ISA interrupts.
*/
-#define IRQ0_VECTOR FIRST_EXTERNAL_VECTOR + 0x10
-#define IRQ1_VECTOR IRQ0_VECTOR + 1
-#define IRQ2_VECTOR IRQ0_VECTOR + 2
-#define IRQ3_VECTOR IRQ0_VECTOR + 3
-#define IRQ4_VECTOR IRQ0_VECTOR + 4
-#define IRQ5_VECTOR IRQ0_VECTOR + 5
-#define IRQ6_VECTOR IRQ0_VECTOR + 6
-#define IRQ7_VECTOR IRQ0_VECTOR + 7
-#define IRQ8_VECTOR IRQ0_VECTOR + 8
-#define IRQ9_VECTOR IRQ0_VECTOR + 9
-#define IRQ10_VECTOR IRQ0_VECTOR + 10
-#define IRQ11_VECTOR IRQ0_VECTOR + 11
-#define IRQ12_VECTOR IRQ0_VECTOR + 12
-#define IRQ13_VECTOR IRQ0_VECTOR + 13
-#define IRQ14_VECTOR IRQ0_VECTOR + 14
-#define IRQ15_VECTOR IRQ0_VECTOR + 15
+#define IRQ0_VECTOR (FIRST_EXTERNAL_VECTOR + 0x10)
+#define IRQ1_VECTOR (IRQ0_VECTOR + 1)
+#define IRQ2_VECTOR (IRQ0_VECTOR + 2)
+#define IRQ3_VECTOR (IRQ0_VECTOR + 3)
+#define IRQ4_VECTOR (IRQ0_VECTOR + 4)
+#define IRQ5_VECTOR (IRQ0_VECTOR + 5)
+#define IRQ6_VECTOR (IRQ0_VECTOR + 6)
+#define IRQ7_VECTOR (IRQ0_VECTOR + 7)
+#define IRQ8_VECTOR (IRQ0_VECTOR + 8)
+#define IRQ9_VECTOR (IRQ0_VECTOR + 9)
+#define IRQ10_VECTOR (IRQ0_VECTOR + 10)
+#define IRQ11_VECTOR (IRQ0_VECTOR + 11)
+#define IRQ12_VECTOR (IRQ0_VECTOR + 12)
+#define IRQ13_VECTOR (IRQ0_VECTOR + 13)
+#define IRQ14_VECTOR (IRQ0_VECTOR + 14)
+#define IRQ15_VECTOR (IRQ0_VECTOR + 15)
/*
* Special IRQ vectors used by the SMP architecture, 0xf0-0xff
@@ -148,9 +148,6 @@ extern atomic_t irq_mis_count;
#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
#include <asm/ptrace.h>
#define IRQ_NAME2(nr) nr##_interrupt(void)
diff --git a/include/asm-x86/intel_arch_perfmon.h b/include/asm-x86/intel_arch_perfmon.h
index 4f6d4e6bf57..fa0fd068bc2 100644
--- a/include/asm-x86/intel_arch_perfmon.h
+++ b/include/asm-x86/intel_arch_perfmon.h
@@ -1,5 +1,31 @@
-#ifdef CONFIG_X86_32
-# include "intel_arch_perfmon_32.h"
-#else
-# include "intel_arch_perfmon_64.h"
-#endif
+#ifndef _ASM_X86_INTEL_ARCH_PERFMON_H
+#define _ASM_X86_INTEL_ARCH_PERFMON_H
+
+#define MSR_ARCH_PERFMON_PERFCTR0 0xc1
+#define MSR_ARCH_PERFMON_PERFCTR1 0xc2
+
+#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
+#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
+
+#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_INT (1 << 20)
+#define ARCH_PERFMON_EVENTSEL_OS (1 << 17)
+#define ARCH_PERFMON_EVENTSEL_USR (1 << 16)
+
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL (0x3c)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
+ (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
+
+union cpuid10_eax {
+ struct {
+ unsigned int version_id:8;
+ unsigned int num_counters:8;
+ unsigned int bit_width:8;
+ unsigned int mask_length:8;
+ } split;
+ unsigned int full;
+};
+
+#endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */
diff --git a/include/asm-x86/intel_arch_perfmon_32.h b/include/asm-x86/intel_arch_perfmon_32.h
deleted file mode 100644
index b52cd60a075..00000000000
--- a/include/asm-x86/intel_arch_perfmon_32.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef X86_INTEL_ARCH_PERFMON_H
-#define X86_INTEL_ARCH_PERFMON_H 1
-
-#define MSR_ARCH_PERFMON_PERFCTR0 0xc1
-#define MSR_ARCH_PERFMON_PERFCTR1 0xc2
-
-#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
-#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
-
-#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_INT (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR (1 << 16)
-
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL (0x3c)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
- (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
-
-union cpuid10_eax {
- struct {
- unsigned int version_id:8;
- unsigned int num_counters:8;
- unsigned int bit_width:8;
- unsigned int mask_length:8;
- } split;
- unsigned int full;
-};
-
-#endif /* X86_INTEL_ARCH_PERFMON_H */
diff --git a/include/asm-x86/intel_arch_perfmon_64.h b/include/asm-x86/intel_arch_perfmon_64.h
deleted file mode 100644
index 8633331420e..00000000000
--- a/include/asm-x86/intel_arch_perfmon_64.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef X86_64_INTEL_ARCH_PERFMON_H
-#define X86_64_INTEL_ARCH_PERFMON_H 1
-
-#define MSR_ARCH_PERFMON_PERFCTR0 0xc1
-#define MSR_ARCH_PERFMON_PERFCTR1 0xc2
-
-#define MSR_ARCH_PERFMON_EVENTSEL0 0x186
-#define MSR_ARCH_PERFMON_EVENTSEL1 0x187
-
-#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_INT (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR (1 << 16)
-
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL (0x3c)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
- (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
-
-union cpuid10_eax {
- struct {
- unsigned int version_id:8;
- unsigned int num_counters:8;
- unsigned int bit_width:8;
- unsigned int mask_length:8;
- } split;
- unsigned int full;
-};
-
-#endif /* X86_64_INTEL_ARCH_PERFMON_H */
diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h
index e8e0bd64112..fe881cd1e6f 100644
--- a/include/asm-x86/io_32.h
+++ b/include/asm-x86/io_32.h
@@ -199,17 +199,22 @@ static inline void writel(unsigned int b, volatile void __iomem *addr)
#define mmiowb()
-static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+static inline void
+memset_io(volatile void __iomem *addr, unsigned char val, int count)
{
- memset((void __force *) addr, val, count);
+ memset((void __force *)addr, val, count);
}
-static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
+
+static inline void
+memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
{
- __memcpy(dst, (void __force *) src, count);
+ __memcpy(dst, (const void __force *)src, count);
}
-static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+
+static inline void
+memcpy_toio(volatile void __iomem *dst, const void *src, int count)
{
- __memcpy((void __force *) dst, src, count);
+ __memcpy((void __force *)dst, src, count);
}
/*
@@ -237,18 +242,9 @@ static inline void flush_write_buffers(void)
__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
}
-#define dma_cache_inv(_start,_size) flush_write_buffers()
-#define dma_cache_wback(_start,_size) flush_write_buffers()
-#define dma_cache_wback_inv(_start,_size) flush_write_buffers()
-
#else
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-#define flush_write_buffers()
+#define flush_write_buffers() do { } while (0)
#endif
diff --git a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h
index 7475095c506..a037b079433 100644
--- a/include/asm-x86/io_64.h
+++ b/include/asm-x86/io_64.h
@@ -249,12 +249,6 @@ void memset_io(volatile void __iomem *a, int b, size_t c);
*/
#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
-
#define flush_write_buffers()
extern int iommu_bio_merge;
diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h
index 1e0fd48f18b..93c894dc515 100644
--- a/include/asm-x86/ioctls.h
+++ b/include/asm-x86/ioctls.h
@@ -1,13 +1,87 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "ioctls_32.h"
-# else
-# include "ioctls_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "ioctls_32.h"
-# else
-# include "ioctls_64.h"
-# endif
+#ifndef _ASM_X86_IOCTLS_H
+#define _ASM_X86_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+#define TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TCGETS2 _IOR('T',0x2A, struct termios2)
+#define TCSETS2 _IOW('T',0x2B, struct termios2)
+#define TCSETSW2 _IOW('T',0x2C, struct termios2)
+#define TCSETSF2 _IOW('T',0x2D, struct termios2)
+#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
+
+#define FIONCLEX 0x5450
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
+#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
+#define FIOQSIZE 0x5460
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
#endif
diff --git a/include/asm-x86/ioctls_32.h b/include/asm-x86/ioctls_32.h
deleted file mode 100644
index ef5878762dc..00000000000
--- a/include/asm-x86/ioctls_32.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef __ARCH_I386_IOCTLS_H__
-#define __ARCH_I386_IOCTLS_H__
-
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-
-#define FIONCLEX 0x5450
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
-#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
-#define FIOQSIZE 0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-#endif
diff --git a/include/asm-x86/ioctls_64.h b/include/asm-x86/ioctls_64.h
deleted file mode 100644
index 3fc0b15a0d7..00000000000
--- a/include/asm-x86/ioctls_64.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __ARCH_X8664_IOCTLS_H__
-#define __ARCH_X8664_IOCTLS_H__
-
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCSBRK 0x5427 /* BSD compatibility */
-#define TIOCCBRK 0x5428 /* BSD compatibility */
-#define TIOCGSID 0x5429 /* Return the session ID of FD */
-#define TCGETS2 _IOR('T',0x2A, struct termios2)
-#define TCSETS2 _IOW('T',0x2B, struct termios2)
-#define TCSETSW2 _IOW('T',0x2C, struct termios2)
-#define TCSETSF2 _IOW('T',0x2D, struct termios2)
-#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
-
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-#define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */
-#define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */
-#define FIOQSIZE 0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-#endif
diff --git a/include/asm-x86/ipc.h b/include/asm-x86/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/include/asm-x86/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/include/asm-x86/ipcbuf.h b/include/asm-x86/ipcbuf.h
index eb2e448c6e2..2adf8b39a40 100644
--- a/include/asm-x86/ipcbuf.h
+++ b/include/asm-x86/ipcbuf.h
@@ -1,13 +1,29 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "ipcbuf_32.h"
-# else
-# include "ipcbuf_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "ipcbuf_32.h"
-# else
-# include "ipcbuf_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_IPCBUF_H
+#define _ASM_X86_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for x86 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* _ASM_X86_IPCBUF_H */
diff --git a/include/asm-x86/ipcbuf_32.h b/include/asm-x86/ipcbuf_32.h
deleted file mode 100644
index 0dcad4f84c2..00000000000
--- a/include/asm-x86/ipcbuf_32.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __i386_IPCBUF_H__
-#define __i386_IPCBUF_H__
-
-/*
- * The ipc64_perm structure for i386 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 32-bit mode_t and seq
- * - 2 miscellaneous 32-bit values
- */
-
-struct ipc64_perm
-{
- __kernel_key_t key;
- __kernel_uid32_t uid;
- __kernel_gid32_t gid;
- __kernel_uid32_t cuid;
- __kernel_gid32_t cgid;
- __kernel_mode_t mode;
- unsigned short __pad1;
- unsigned short seq;
- unsigned short __pad2;
- unsigned long __unused1;
- unsigned long __unused2;
-};
-
-#endif /* __i386_IPCBUF_H__ */
diff --git a/include/asm-x86/ipcbuf_64.h b/include/asm-x86/ipcbuf_64.h
deleted file mode 100644
index 470cf85e3ba..00000000000
--- a/include/asm-x86/ipcbuf_64.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __x86_64_IPCBUF_H__
-#define __x86_64_IPCBUF_H__
-
-/*
- * The ipc64_perm structure for x86_64 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 32-bit mode_t and seq
- * - 2 miscellaneous 32-bit values
- */
-
-struct ipc64_perm
-{
- __kernel_key_t key;
- __kernel_uid32_t uid;
- __kernel_gid32_t gid;
- __kernel_uid32_t cuid;
- __kernel_gid32_t cgid;
- __kernel_mode_t mode;
- unsigned short __pad1;
- unsigned short seq;
- unsigned short __pad2;
- unsigned long __unused1;
- unsigned long __unused2;
-};
-
-#endif /* __x86_64_IPCBUF_H__ */
diff --git a/include/asm-x86/irqflags_32.h b/include/asm-x86/irqflags_32.h
index eff8585cb74..d058b04e008 100644
--- a/include/asm-x86/irqflags_32.h
+++ b/include/asm-x86/irqflags_32.h
@@ -160,4 +160,17 @@ static inline int raw_irqs_disabled(void)
# define TRACE_IRQS_OFF
#endif
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# define LOCKDEP_SYS_EXIT \
+ pushl %eax; \
+ pushl %ecx; \
+ pushl %edx; \
+ call lockdep_sys_exit; \
+ popl %edx; \
+ popl %ecx; \
+ popl %eax;
+#else
+# define LOCKDEP_SYS_EXIT
+#endif
+
#endif
diff --git a/include/asm-x86/irqflags_64.h b/include/asm-x86/irqflags_64.h
index 86e70fe2365..5341ea1f815 100644
--- a/include/asm-x86/irqflags_64.h
+++ b/include/asm-x86/irqflags_64.h
@@ -137,6 +137,20 @@ static inline void halt(void)
# define TRACE_IRQS_ON
# define TRACE_IRQS_OFF
# endif
+# ifdef CONFIG_DEBUG_LOCK_ALLOC
+# define LOCKDEP_SYS_EXIT call lockdep_sys_exit_thunk
+# define LOCKDEP_SYS_EXIT_IRQ \
+ TRACE_IRQS_ON; \
+ sti; \
+ SAVE_REST; \
+ LOCKDEP_SYS_EXIT; \
+ RESTORE_REST; \
+ cli; \
+ TRACE_IRQS_OFF;
+# else
+# define LOCKDEP_SYS_EXIT
+# define LOCKDEP_SYS_EXIT_IRQ
+# endif
#endif
#endif
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
index 38479106c25..e2f9b62e535 100644
--- a/include/asm-x86/kdebug.h
+++ b/include/asm-x86/kdebug.h
@@ -1,5 +1,33 @@
-#ifdef CONFIG_X86_32
-# include "kdebug_32.h"
-#else
-# include "kdebug_64.h"
+#ifndef _ASM_X86_KDEBUG_H
+#define _ASM_X86_KDEBUG_H
+
+#include <linux/notifier.h>
+
+struct pt_regs;
+
+/* Grossly misnamed. */
+enum die_val {
+ DIE_OOPS = 1,
+ DIE_INT3,
+ DIE_DEBUG,
+ DIE_PANIC,
+ DIE_NMI,
+ DIE_DIE,
+ DIE_NMIWATCHDOG,
+ DIE_KERNELDEBUG,
+ DIE_TRAP,
+ DIE_GPF,
+ DIE_CALL,
+ DIE_NMI_IPI,
+ DIE_PAGE_FAULT,
+};
+
+extern void printk_address(unsigned long address);
+extern void die(const char *,struct pt_regs *,long);
+extern void __die(const char *,struct pt_regs *,long);
+extern void show_registers(struct pt_regs *regs);
+extern void dump_pagetable(unsigned long);
+extern unsigned long oops_begin(void);
+extern void oops_end(unsigned long);
+
#endif
diff --git a/include/asm-x86/kdebug_32.h b/include/asm-x86/kdebug_32.h
deleted file mode 100644
index a185b5f73e7..00000000000
--- a/include/asm-x86/kdebug_32.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef _I386_KDEBUG_H
-#define _I386_KDEBUG_H 1
-
-/*
- * Aug-05 2004 Ported by Prasanna S Panchamukhi <prasanna@in.ibm.com>
- * from x86_64 architecture.
- */
-#include <linux/notifier.h>
-
-struct pt_regs;
-
-extern int register_page_fault_notifier(struct notifier_block *);
-extern int unregister_page_fault_notifier(struct notifier_block *);
-
-
-/* Grossly misnamed. */
-enum die_val {
- DIE_OOPS = 1,
- DIE_INT3,
- DIE_DEBUG,
- DIE_PANIC,
- DIE_NMI,
- DIE_DIE,
- DIE_NMIWATCHDOG,
- DIE_KERNELDEBUG,
- DIE_TRAP,
- DIE_GPF,
- DIE_CALL,
- DIE_NMI_IPI,
- DIE_PAGE_FAULT,
-};
-
-#endif
diff --git a/include/asm-x86/kdebug_64.h b/include/asm-x86/kdebug_64.h
deleted file mode 100644
index d7e2bcf49e4..00000000000
--- a/include/asm-x86/kdebug_64.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _X86_64_KDEBUG_H
-#define _X86_64_KDEBUG_H 1
-
-#include <linux/notifier.h>
-
-struct pt_regs;
-
-extern int register_page_fault_notifier(struct notifier_block *);
-extern int unregister_page_fault_notifier(struct notifier_block *);
-
-/* Grossly misnamed. */
-enum die_val {
- DIE_OOPS = 1,
- DIE_INT3,
- DIE_DEBUG,
- DIE_PANIC,
- DIE_NMI,
- DIE_DIE,
- DIE_NMIWATCHDOG,
- DIE_KERNELDEBUG,
- DIE_TRAP,
- DIE_GPF,
- DIE_CALL,
- DIE_NMI_IPI,
- DIE_PAGE_FAULT,
-};
-
-extern void printk_address(unsigned long address);
-extern void die(const char *,struct pt_regs *,long);
-extern void __die(const char *,struct pt_regs *,long);
-extern void show_registers(struct pt_regs *regs);
-extern void dump_pagetable(unsigned long);
-extern unsigned long oops_begin(void);
-extern void oops_end(unsigned long);
-
-#endif
diff --git a/include/asm-x86/kmap_types.h b/include/asm-x86/kmap_types.h
index e4ec724b298..5f4174132a2 100644
--- a/include/asm-x86/kmap_types.h
+++ b/include/asm-x86/kmap_types.h
@@ -1,5 +1,29 @@
-#ifdef CONFIG_X86_32
-# include "kmap_types_32.h"
+#ifndef _ASM_X86_KMAP_TYPES_H
+#define _ASM_X86_KMAP_TYPES_H
+
+#if defined(CONFIG_X86_32) && defined(CONFIG_DEBUG_HIGHMEM)
+# define D(n) __KM_FENCE_##n ,
#else
-# include "kmap_types_64.h"
+# define D(n)
+#endif
+
+enum km_type {
+D(0) KM_BOUNCE_READ,
+D(1) KM_SKB_SUNRPC_DATA,
+D(2) KM_SKB_DATA_SOFTIRQ,
+D(3) KM_USER0,
+D(4) KM_USER1,
+D(5) KM_BIO_SRC_IRQ,
+D(6) KM_BIO_DST_IRQ,
+D(7) KM_PTE0,
+D(8) KM_PTE1,
+D(9) KM_IRQ0,
+D(10) KM_IRQ1,
+D(11) KM_SOFTIRQ0,
+D(12) KM_SOFTIRQ1,
+D(13) KM_TYPE_NR
+};
+
+#undef D
+
#endif
diff --git a/include/asm-x86/kmap_types_32.h b/include/asm-x86/kmap_types_32.h
deleted file mode 100644
index 806aae3c533..00000000000
--- a/include/asm-x86/kmap_types_32.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-
-#ifdef CONFIG_DEBUG_HIGHMEM
-# define D(n) __KM_FENCE_##n ,
-#else
-# define D(n)
-#endif
-
-enum km_type {
-D(0) KM_BOUNCE_READ,
-D(1) KM_SKB_SUNRPC_DATA,
-D(2) KM_SKB_DATA_SOFTIRQ,
-D(3) KM_USER0,
-D(4) KM_USER1,
-D(5) KM_BIO_SRC_IRQ,
-D(6) KM_BIO_DST_IRQ,
-D(7) KM_PTE0,
-D(8) KM_PTE1,
-D(9) KM_IRQ0,
-D(10) KM_IRQ1,
-D(11) KM_SOFTIRQ0,
-D(12) KM_SOFTIRQ1,
-D(13) KM_TYPE_NR
-};
-
-#undef D
-
-#endif
diff --git a/include/asm-x86/kmap_types_64.h b/include/asm-x86/kmap_types_64.h
deleted file mode 100644
index 7486338c6ce..00000000000
--- a/include/asm-x86/kmap_types_64.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _ASM_KMAP_TYPES_H
-#define _ASM_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif
diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h
index 06f7303c30c..b772d5b3868 100644
--- a/include/asm-x86/kprobes_32.h
+++ b/include/asm-x86/kprobes_32.h
@@ -43,9 +43,10 @@ typedef u8 kprobe_opcode_t;
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
#define ARCH_SUPPORTS_KRETPROBES
-#define ARCH_INACTIVE_KPROBE_COUNT 0
#define flush_insn_slot(p) do { } while (0)
+extern const int kretprobe_blacklist_size;
+
void arch_remove_kprobe(struct kprobe *p);
void kretprobe_trampoline(void);
@@ -89,4 +90,5 @@ static inline void restore_interrupts(struct pt_regs *regs)
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
#endif /* _ASM_KPROBES_H */
diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h
index 7db825403e0..53f4d850735 100644
--- a/include/asm-x86/kprobes_64.h
+++ b/include/asm-x86/kprobes_64.h
@@ -42,7 +42,7 @@ typedef u8 kprobe_opcode_t;
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
#define ARCH_SUPPORTS_KRETPROBES
-#define ARCH_INACTIVE_KPROBE_COUNT 1
+extern const int kretprobe_blacklist_size;
void kretprobe_trampoline(void);
extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/asm-x86/ldt.h b/include/asm-x86/ldt.h
index 3d9cc20d2ba..20c597242b5 100644
--- a/include/asm-x86/ldt.h
+++ b/include/asm-x86/ldt.h
@@ -1,13 +1,40 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "ldt_32.h"
-# else
-# include "ldt_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "ldt_32.h"
-# else
-# include "ldt_64.h"
-# endif
+/*
+ * ldt.h
+ *
+ * Definitions of structures used with the modify_ldt system call.
+ */
+#ifndef _ASM_X86_LDT_H
+#define _ASM_X86_LDT_H
+
+/* Maximum number of LDT entries supported. */
+#define LDT_ENTRIES 8192
+/* The size of each LDT entry. */
+#define LDT_ENTRY_SIZE 8
+
+#ifndef __ASSEMBLY__
+/*
+ * Note on 64bit base and limit is ignored and you cannot set DS/ES/CS
+ * not to the default values if you still want to do syscalls. This
+ * call is more for 32bit mode therefore.
+ */
+struct user_desc {
+ unsigned int entry_number;
+ unsigned int base_addr;
+ unsigned int limit;
+ unsigned int seg_32bit:1;
+ unsigned int contents:2;
+ unsigned int read_exec_only:1;
+ unsigned int limit_in_pages:1;
+ unsigned int seg_not_present:1;
+ unsigned int useable:1;
+#ifdef __x86_64__
+ unsigned int lm:1;
+#endif
+};
+
+#define MODIFY_LDT_CONTENTS_DATA 0
+#define MODIFY_LDT_CONTENTS_STACK 1
+#define MODIFY_LDT_CONTENTS_CODE 2
+
+#endif /* !__ASSEMBLY__ */
#endif
diff --git a/include/asm-x86/ldt_32.h b/include/asm-x86/ldt_32.h
deleted file mode 100644
index e9d3de1dee6..00000000000
--- a/include/asm-x86/ldt_32.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ldt.h
- *
- * Definitions of structures used with the modify_ldt system call.
- */
-#ifndef _LINUX_LDT_H
-#define _LINUX_LDT_H
-
-/* Maximum number of LDT entries supported. */
-#define LDT_ENTRIES 8192
-/* The size of each LDT entry. */
-#define LDT_ENTRY_SIZE 8
-
-#ifndef __ASSEMBLY__
-struct user_desc {
- unsigned int entry_number;
- unsigned long base_addr;
- unsigned int limit;
- unsigned int seg_32bit:1;
- unsigned int contents:2;
- unsigned int read_exec_only:1;
- unsigned int limit_in_pages:1;
- unsigned int seg_not_present:1;
- unsigned int useable:1;
-};
-
-#define MODIFY_LDT_CONTENTS_DATA 0
-#define MODIFY_LDT_CONTENTS_STACK 1
-#define MODIFY_LDT_CONTENTS_CODE 2
-
-#endif /* !__ASSEMBLY__ */
-#endif
diff --git a/include/asm-x86/ldt_64.h b/include/asm-x86/ldt_64.h
deleted file mode 100644
index 9ef647b890d..00000000000
--- a/include/asm-x86/ldt_64.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * ldt.h
- *
- * Definitions of structures used with the modify_ldt system call.
- */
-#ifndef _LINUX_LDT_H
-#define _LINUX_LDT_H
-
-/* Maximum number of LDT entries supported. */
-#define LDT_ENTRIES 8192
-/* The size of each LDT entry. */
-#define LDT_ENTRY_SIZE 8
-
-#ifndef __ASSEMBLY__
-/* Note on 64bit base and limit is ignored and you cannot set
- DS/ES/CS not to the default values if you still want to do syscalls. This
- call is more for 32bit mode therefore. */
-struct user_desc {
- unsigned int entry_number;
- unsigned int base_addr;
- unsigned int limit;
- unsigned int seg_32bit:1;
- unsigned int contents:2;
- unsigned int read_exec_only:1;
- unsigned int limit_in_pages:1;
- unsigned int seg_not_present:1;
- unsigned int useable:1;
- unsigned int lm:1;
-};
-
-#define MODIFY_LDT_CONTENTS_DATA 0
-#define MODIFY_LDT_CONTENTS_STACK 1
-#define MODIFY_LDT_CONTENTS_CODE 2
-
-#endif /* !__ASSEMBLY__ */
-#endif
diff --git a/include/asm-x86/mach-default/mach_apicdef.h b/include/asm-x86/mach-default/mach_apicdef.h
index 7bcb350c3ee..ae984131909 100644
--- a/include/asm-x86/mach-default/mach_apicdef.h
+++ b/include/asm-x86/mach-default/mach_apicdef.h
@@ -1,11 +1,17 @@
#ifndef __ASM_MACH_APICDEF_H
#define __ASM_MACH_APICDEF_H
+#include <asm/apic.h>
+
#define APIC_ID_MASK (0xF<<24)
static inline unsigned get_apic_id(unsigned long x)
{
- return (((x)>>24)&0xF);
+ unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
+ if (APIC_XAPIC(ver))
+ return (((x)>>24)&0xFF);
+ else
+ return (((x)>>24)&0xF);
}
#define GET_APIC_ID(x) get_apic_id(x)
diff --git a/include/asm-x86/mach-visws/cobalt.h b/include/asm-x86/mach-visws/cobalt.h
index 33c36225a04..995258831b7 100644
--- a/include/asm-x86/mach-visws/cobalt.h
+++ b/include/asm-x86/mach-visws/cobalt.h
@@ -94,22 +94,22 @@
#define CO_IRQ_8259 CO_IRQ(CO_APIC_8259)
#ifdef CONFIG_X86_VISWS_APIC
-extern __inline void co_cpu_write(unsigned long reg, unsigned long v)
+static inline void co_cpu_write(unsigned long reg, unsigned long v)
{
*((volatile unsigned long *)(CO_CPU_VADDR+reg))=v;
}
-extern __inline unsigned long co_cpu_read(unsigned long reg)
+static inline unsigned long co_cpu_read(unsigned long reg)
{
return *((volatile unsigned long *)(CO_CPU_VADDR+reg));
}
-extern __inline void co_apic_write(unsigned long reg, unsigned long v)
+static inline void co_apic_write(unsigned long reg, unsigned long v)
{
*((volatile unsigned long *)(CO_APIC_VADDR+reg))=v;
}
-extern __inline unsigned long co_apic_read(unsigned long reg)
+static inline unsigned long co_apic_read(unsigned long reg)
{
return *((volatile unsigned long *)(CO_APIC_VADDR+reg));
}
diff --git a/include/asm-x86/mach-visws/lithium.h b/include/asm-x86/mach-visws/lithium.h
index d443e68d006..dfcd4f07ab8 100644
--- a/include/asm-x86/mach-visws/lithium.h
+++ b/include/asm-x86/mach-visws/lithium.h
@@ -29,22 +29,22 @@
#define LI_INTD 0x0080
/* More special purpose macros... */
-extern __inline void li_pcia_write16(unsigned long reg, unsigned short v)
+static inline void li_pcia_write16(unsigned long reg, unsigned short v)
{
*((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v;
}
-extern __inline unsigned short li_pcia_read16(unsigned long reg)
+static inline unsigned short li_pcia_read16(unsigned long reg)
{
return *((volatile unsigned short *)(LI_PCIA_VADDR+reg));
}
-extern __inline void li_pcib_write16(unsigned long reg, unsigned short v)
+static inline void li_pcib_write16(unsigned long reg, unsigned short v)
{
*((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v;
}
-extern __inline unsigned short li_pcib_read16(unsigned long reg)
+static inline unsigned short li_pcib_read16(unsigned long reg)
{
return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
}
diff --git a/include/asm-x86/mce.h b/include/asm-x86/mce.h
index cc8ca389912..df304fd89c2 100644
--- a/include/asm-x86/mce.h
+++ b/include/asm-x86/mce.h
@@ -1,5 +1,129 @@
+#ifndef _ASM_X86_MCE_H
+#define _ASM_X86_MCE_H
+
+#ifdef __x86_64__
+
+#include <asm/ioctls.h>
+#include <asm/types.h>
+
+/*
+ * Machine Check support for x86
+ */
+
+#define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */
+
+#define MCG_STATUS_RIPV (1UL<<0) /* restart ip valid */
+#define MCG_STATUS_EIPV (1UL<<1) /* eip points to correct instruction */
+#define MCG_STATUS_MCIP (1UL<<2) /* machine check in progress */
+
+#define MCI_STATUS_VAL (1UL<<63) /* valid error */
+#define MCI_STATUS_OVER (1UL<<62) /* previous errors lost */
+#define MCI_STATUS_UC (1UL<<61) /* uncorrected error */
+#define MCI_STATUS_EN (1UL<<60) /* error enabled */
+#define MCI_STATUS_MISCV (1UL<<59) /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1UL<<58) /* addr reg. valid */
+#define MCI_STATUS_PCC (1UL<<57) /* processor context corrupt */
+
+/* Fields are zero when not available */
+struct mce {
+ __u64 status;
+ __u64 misc;
+ __u64 addr;
+ __u64 mcgstatus;
+ __u64 rip;
+ __u64 tsc; /* cpu time stamp counter */
+ __u64 res1; /* for future extension */
+ __u64 res2; /* dito. */
+ __u8 cs; /* code segment */
+ __u8 bank; /* machine check bank */
+ __u8 cpu; /* cpu that raised the error */
+ __u8 finished; /* entry is valid */
+ __u32 pad;
+};
+
+/*
+ * This structure contains all data related to the MCE log. Also
+ * carries a signature to make it easier to find from external
+ * debugging tools. Each entry is only valid when its finished flag
+ * is set.
+ */
+
+#define MCE_LOG_LEN 32
+
+struct mce_log {
+ char signature[12]; /* "MACHINECHECK" */
+ unsigned len; /* = MCE_LOG_LEN */
+ unsigned next;
+ unsigned flags;
+ unsigned pad0;
+ struct mce entry[MCE_LOG_LEN];
+};
+
+#define MCE_OVERFLOW 0 /* bit 0 in flags means overflow */
+
+#define MCE_LOG_SIGNATURE "MACHINECHECK"
+
+#define MCE_GET_RECORD_LEN _IOR('M', 1, int)
+#define MCE_GET_LOG_LEN _IOR('M', 2, int)
+#define MCE_GETCLEAR_FLAGS _IOR('M', 3, int)
+
+/* Software defined banks */
+#define MCE_EXTENDED_BANK 128
+#define MCE_THERMAL_BANK MCE_EXTENDED_BANK + 0
+
+#define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1) /* MCE_AMD */
+#define K8_MCE_THRESHOLD_BANK_0 (MCE_THRESHOLD_BASE + 0 * 9)
+#define K8_MCE_THRESHOLD_BANK_1 (MCE_THRESHOLD_BASE + 1 * 9)
+#define K8_MCE_THRESHOLD_BANK_2 (MCE_THRESHOLD_BASE + 2 * 9)
+#define K8_MCE_THRESHOLD_BANK_3 (MCE_THRESHOLD_BASE + 3 * 9)
+#define K8_MCE_THRESHOLD_BANK_4 (MCE_THRESHOLD_BASE + 4 * 9)
+#define K8_MCE_THRESHOLD_BANK_5 (MCE_THRESHOLD_BASE + 5 * 9)
+#define K8_MCE_THRESHOLD_DRAM_ECC (MCE_THRESHOLD_BANK_4 + 0)
+
+#endif /* __x86_64__ */
+
+#ifdef __KERNEL__
+
#ifdef CONFIG_X86_32
-# include "mce_32.h"
+#ifdef CONFIG_X86_MCE
+extern void mcheck_init(struct cpuinfo_x86 *c);
#else
-# include "mce_64.h"
+#define mcheck_init(c) do {} while(0)
+#endif
+
+extern int mce_disabled;
+
+#else /* CONFIG_X86_32 */
+
+#include <asm/atomic.h>
+
+void mce_log(struct mce *m);
+DECLARE_PER_CPU(struct sys_device, device_mce);
+
+#ifdef CONFIG_X86_MCE_INTEL
+void mce_intel_feature_init(struct cpuinfo_x86 *c);
+#else
+static inline void mce_intel_feature_init(struct cpuinfo_x86 *c) { }
+#endif
+
+#ifdef CONFIG_X86_MCE_AMD
+void mce_amd_feature_init(struct cpuinfo_x86 *c);
+#else
+static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) { }
+#endif
+
+void mce_log_therm_throt_event(unsigned int cpu, __u64 status);
+
+extern atomic_t mce_entry;
+
+extern void do_machine_check(struct pt_regs *, long);
+extern int mce_notify_user(void);
+
+#endif /* !CONFIG_X86_32 */
+
+extern void stop_mce(void);
+extern void restart_mce(void);
+
+#endif /* __KERNEL__ */
+
#endif
diff --git a/include/asm-x86/mce_32.h b/include/asm-x86/mce_32.h
deleted file mode 100644
index d56d89742e8..00000000000
--- a/include/asm-x86/mce_32.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifdef CONFIG_X86_MCE
-extern void mcheck_init(struct cpuinfo_x86 *c);
-#else
-#define mcheck_init(c) do {} while(0)
-#endif
-
-extern int mce_disabled;
-
-extern void stop_mce(void);
-extern void restart_mce(void);
-
diff --git a/include/asm-x86/mce_64.h b/include/asm-x86/mce_64.h
deleted file mode 100644
index 7bc030a1996..00000000000
--- a/include/asm-x86/mce_64.h
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef _ASM_MCE_H
-#define _ASM_MCE_H 1
-
-#include <asm/ioctls.h>
-#include <asm/types.h>
-
-/*
- * Machine Check support for x86
- */
-
-#define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */
-
-#define MCG_STATUS_RIPV (1UL<<0) /* restart ip valid */
-#define MCG_STATUS_EIPV (1UL<<1) /* eip points to correct instruction */
-#define MCG_STATUS_MCIP (1UL<<2) /* machine check in progress */
-
-#define MCI_STATUS_VAL (1UL<<63) /* valid error */
-#define MCI_STATUS_OVER (1UL<<62) /* previous errors lost */
-#define MCI_STATUS_UC (1UL<<61) /* uncorrected error */
-#define MCI_STATUS_EN (1UL<<60) /* error enabled */
-#define MCI_STATUS_MISCV (1UL<<59) /* misc error reg. valid */
-#define MCI_STATUS_ADDRV (1UL<<58) /* addr reg. valid */
-#define MCI_STATUS_PCC (1UL<<57) /* processor context corrupt */
-
-/* Fields are zero when not available */
-struct mce {
- __u64 status;
- __u64 misc;
- __u64 addr;
- __u64 mcgstatus;
- __u64 rip;
- __u64 tsc; /* cpu time stamp counter */
- __u64 res1; /* for future extension */
- __u64 res2; /* dito. */
- __u8 cs; /* code segment */
- __u8 bank; /* machine check bank */
- __u8 cpu; /* cpu that raised the error */
- __u8 finished; /* entry is valid */
- __u32 pad;
-};
-
-/*
- * This structure contains all data related to the MCE log.
- * Also carries a signature to make it easier to find from external debugging tools.
- * Each entry is only valid when its finished flag is set.
- */
-
-#define MCE_LOG_LEN 32
-
-struct mce_log {
- char signature[12]; /* "MACHINECHECK" */
- unsigned len; /* = MCE_LOG_LEN */
- unsigned next;
- unsigned flags;
- unsigned pad0;
- struct mce entry[MCE_LOG_LEN];
-};
-
-#define MCE_OVERFLOW 0 /* bit 0 in flags means overflow */
-
-#define MCE_LOG_SIGNATURE "MACHINECHECK"
-
-#define MCE_GET_RECORD_LEN _IOR('M', 1, int)
-#define MCE_GET_LOG_LEN _IOR('M', 2, int)
-#define MCE_GETCLEAR_FLAGS _IOR('M', 3, int)
-
-/* Software defined banks */
-#define MCE_EXTENDED_BANK 128
-#define MCE_THERMAL_BANK MCE_EXTENDED_BANK + 0
-
-#define K8_MCE_THRESHOLD_BASE (MCE_EXTENDED_BANK + 1) /* MCE_AMD */
-#define K8_MCE_THRESHOLD_BANK_0 (MCE_THRESHOLD_BASE + 0 * 9)
-#define K8_MCE_THRESHOLD_BANK_1 (MCE_THRESHOLD_BASE + 1 * 9)
-#define K8_MCE_THRESHOLD_BANK_2 (MCE_THRESHOLD_BASE + 2 * 9)
-#define K8_MCE_THRESHOLD_BANK_3 (MCE_THRESHOLD_BASE + 3 * 9)
-#define K8_MCE_THRESHOLD_BANK_4 (MCE_THRESHOLD_BASE + 4 * 9)
-#define K8_MCE_THRESHOLD_BANK_5 (MCE_THRESHOLD_BASE + 5 * 9)
-#define K8_MCE_THRESHOLD_DRAM_ECC (MCE_THRESHOLD_BANK_4 + 0)
-
-#ifdef __KERNEL__
-#include <asm/atomic.h>
-
-void mce_log(struct mce *m);
-DECLARE_PER_CPU(struct sys_device, device_mce);
-
-#ifdef CONFIG_X86_MCE_INTEL
-void mce_intel_feature_init(struct cpuinfo_x86 *c);
-#else
-static inline void mce_intel_feature_init(struct cpuinfo_x86 *c)
-{
-}
-#endif
-
-#ifdef CONFIG_X86_MCE_AMD
-void mce_amd_feature_init(struct cpuinfo_x86 *c);
-#else
-static inline void mce_amd_feature_init(struct cpuinfo_x86 *c)
-{
-}
-#endif
-
-void mce_log_therm_throt_event(unsigned int cpu, __u64 status);
-
-extern atomic_t mce_entry;
-
-extern void do_machine_check(struct pt_regs *, long);
-
-extern int mce_notify_user(void);
-
-extern void stop_mce(void);
-extern void restart_mce(void);
-
-#endif
-
-#endif
diff --git a/include/asm-x86/mman.h b/include/asm-x86/mman.h
index 322db07e82c..c1682b542da 100644
--- a/include/asm-x86/mman.h
+++ b/include/asm-x86/mman.h
@@ -1,13 +1,19 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "mman_32.h"
-# else
-# include "mman_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "mman_32.h"
-# else
-# include "mman_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_MMAN_H
+#define _ASM_X86_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#define MAP_32BIT 0x40 /* only give out 32bit addresses */
+
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+#define MAP_LOCKED 0x2000 /* pages are locked */
+#define MAP_NORESERVE 0x4000 /* don't check for reservations */
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+
+#define MCL_CURRENT 1 /* lock all current mappings */
+#define MCL_FUTURE 2 /* lock all future mappings */
+
+#endif /* _ASM_X86_MMAN_H */
diff --git a/include/asm-x86/mman_32.h b/include/asm-x86/mman_32.h
deleted file mode 100644
index 8fd9d7ab7fa..00000000000
--- a/include/asm-x86/mman_32.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __I386_MMAN_H__
-#define __I386_MMAN_H__
-
-#include <asm-generic/mman.h>
-
-#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
-#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
-#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-#define MAP_LOCKED 0x2000 /* pages are locked */
-#define MAP_NORESERVE 0x4000 /* don't check for reservations */
-#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
-#define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-#define MCL_CURRENT 1 /* lock all current mappings */
-#define MCL_FUTURE 2 /* lock all future mappings */
-
-#endif /* __I386_MMAN_H__ */
diff --git a/include/asm-x86/mman_64.h b/include/asm-x86/mman_64.h
deleted file mode 100644
index dd5cb0534d3..00000000000
--- a/include/asm-x86/mman_64.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __X8664_MMAN_H__
-#define __X8664_MMAN_H__
-
-#include <asm-generic/mman.h>
-
-#define MAP_32BIT 0x40 /* only give out 32bit addresses */
-
-#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
-#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
-#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
-#define MAP_LOCKED 0x2000 /* pages are locked */
-#define MAP_NORESERVE 0x4000 /* don't check for reservations */
-#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
-#define MAP_NONBLOCK 0x10000 /* do not block on IO */
-
-#define MCL_CURRENT 1 /* lock all current mappings */
-#define MCL_FUTURE 2 /* lock all future mappings */
-
-#endif
diff --git a/include/asm-x86/mmu_32.h b/include/asm-x86/mmu_32.h
index 8358dd3df7a..5e249c51ef5 100644
--- a/include/asm-x86/mmu_32.h
+++ b/include/asm-x86/mmu_32.h
@@ -1,7 +1,7 @@
#ifndef __i386_MMU_H
#define __i386_MMU_H
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
/*
* The i386 doesn't have a mmu context, but
* we put the segment information here.
@@ -10,7 +10,7 @@
*/
typedef struct {
int size;
- struct semaphore sem;
+ struct mutex lock;
void *ldt;
void *vdso;
} mm_context_t;
diff --git a/include/asm-x86/mmu_64.h b/include/asm-x86/mmu_64.h
index d2cd4a9d984..024357c2722 100644
--- a/include/asm-x86/mmu_64.h
+++ b/include/asm-x86/mmu_64.h
@@ -2,7 +2,7 @@
#define __x86_64_MMU_H
#include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
/*
* The x86_64 doesn't have a mmu context, but
@@ -14,7 +14,7 @@ typedef struct {
void *ldt;
rwlock_t ldtlock;
int size;
- struct semaphore sem;
+ struct mutex lock;
void *vdso;
} mm_context_t;
diff --git a/include/asm-x86/namei.h b/include/asm-x86/namei.h
index 732f8f0b3dc..415ef5d9550 100644
--- a/include/asm-x86/namei.h
+++ b/include/asm-x86/namei.h
@@ -1,5 +1,11 @@
-#ifdef CONFIG_X86_32
-# include "namei_32.h"
-#else
-# include "namei_64.h"
-#endif
+#ifndef _ASM_X86_NAMEI_H
+#define _ASM_X86_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif /* _ASM_X86_NAMEI_H */
diff --git a/include/asm-x86/namei_32.h b/include/asm-x86/namei_32.h
deleted file mode 100644
index 81486508861..00000000000
--- a/include/asm-x86/namei_32.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $
- * linux/include/asm-i386/namei.h
- *
- * Included from linux/fs/namei.c
- */
-
-#ifndef __I386_NAMEI_H
-#define __I386_NAMEI_H
-
-/* This dummy routine maybe changed to something useful
- * for /usr/gnemul/ emulation stuff.
- * Look at asm-sparc/namei.h for details.
- */
-
-#define __emul_prefix() NULL
-
-#endif /* __I386_NAMEI_H */
diff --git a/include/asm-x86/namei_64.h b/include/asm-x86/namei_64.h
deleted file mode 100644
index bef239f5318..00000000000
--- a/include/asm-x86/namei_64.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __X8664_NAMEI_H
-#define __X8664_NAMEI_H
-
-/* This dummy routine maybe changed to something useful
- * for /usr/gnemul/ emulation stuff.
- * Look at asm-sparc/namei.h for details.
- */
-
-#define __emul_prefix() NULL
-
-#endif
diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h
index 933ff11ece1..0cc5c97a7fc 100644
--- a/include/asm-x86/numa_64.h
+++ b/include/asm-x86/numa_64.h
@@ -2,6 +2,7 @@
#define _ASM_X8664_NUMA_H 1
#include <linux/nodemask.h>
+#include <asm/apicdef.h>
struct bootnode {
u64 start,end;
@@ -19,7 +20,7 @@ extern void numa_set_node(int cpu, int node);
extern void srat_reserve_add_area(int nodeid);
extern int hotadd_percent;
-extern unsigned char apicid_to_node[256];
+extern unsigned char apicid_to_node[MAX_LOCAL_APIC];
#ifdef CONFIG_NUMA
extern void __init init_cpu_to_node(void);
diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
index 88adf1afb0a..c3b52bcb171 100644
--- a/include/asm-x86/page_64.h
+++ b/include/asm-x86/page_64.h
@@ -134,6 +134,7 @@ extern unsigned long __phys_addr(unsigned long);
VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#define __HAVE_ARCH_GATE_AREA 1
+#define vmemmap ((struct page *)VMEMMAP_START)
#include <asm-generic/memory_model.h>
#include <asm-generic/page.h>
diff --git a/include/asm-x86/param.h b/include/asm-x86/param.h
index 640851bab12..c996ec4da0c 100644
--- a/include/asm-x86/param.h
+++ b/include/asm-x86/param.h
@@ -1,13 +1,22 @@
+#ifndef _ASM_X86_PARAM_H
+#define _ASM_X86_PARAM_H
+
#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "param_32.h"
-# else
-# include "param_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "param_32.h"
-# else
-# include "param_64.h"
-# endif
+# define HZ CONFIG_HZ /* Internal kernel timer frequency */
+# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#endif /* _ASM_X86_PARAM_H */
diff --git a/include/asm-x86/param_32.h b/include/asm-x86/param_32.h
deleted file mode 100644
index 21b32466fcd..00000000000
--- a/include/asm-x86/param_32.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _ASMi386_PARAM_H
-#define _ASMi386_PARAM_H
-
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif
diff --git a/include/asm-x86/param_64.h b/include/asm-x86/param_64.h
deleted file mode 100644
index a728786c3c7..00000000000
--- a/include/asm-x86/param_64.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _ASMx86_64_PARAM_H
-#define _ASMx86_64_PARAM_H
-
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in "ticks */
-#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 9fa3fa9e62d..f59d370c5df 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -25,27 +25,22 @@ struct tss_struct;
struct mm_struct;
struct desc_struct;
-/* Lazy mode for batching updates / context switch */
-enum paravirt_lazy_mode {
- PARAVIRT_LAZY_NONE = 0,
- PARAVIRT_LAZY_MMU = 1,
- PARAVIRT_LAZY_CPU = 2,
- PARAVIRT_LAZY_FLUSH = 3,
-};
-
-struct paravirt_ops
-{
+/* general info */
+struct pv_info {
unsigned int kernel_rpl;
int shared_kernel_pmd;
- int paravirt_enabled;
+ int paravirt_enabled;
const char *name;
+};
+struct pv_init_ops {
/*
- * Patch may replace one of the defined code sequences with arbitrary
- * code, subject to the same register constraints. This generally
- * means the code is not free to clobber any registers other than EAX.
- * The patch function should return the number of bytes of code
- * generated, as we nop pad the rest in generic code.
+ * Patch may replace one of the defined code sequences with
+ * arbitrary code, subject to the same register constraints.
+ * This generally means the code is not free to clobber any
+ * registers other than EAX. The patch function should return
+ * the number of bytes of code generated, as we nop pad the
+ * rest in generic code.
*/
unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
unsigned long addr, unsigned len);
@@ -55,29 +50,29 @@ struct paravirt_ops
char *(*memory_setup)(void);
void (*post_allocator_init)(void);
- void (*init_IRQ)(void);
- void (*time_init)(void);
-
- /*
- * Called before/after init_mm pagetable setup. setup_start
- * may reset %cr3, and may pre-install parts of the pagetable;
- * pagetable setup is expected to preserve any existing
- * mapping.
- */
- void (*pagetable_setup_start)(pgd_t *pgd_base);
- void (*pagetable_setup_done)(pgd_t *pgd_base);
-
/* Print a banner to identify the environment */
void (*banner)(void);
+};
+
+
+struct pv_lazy_ops {
+ /* Set deferred update mode, used for batching operations. */
+ void (*enter)(void);
+ void (*leave)(void);
+};
+
+struct pv_time_ops {
+ void (*time_init)(void);
/* Set and set time of day */
unsigned long (*get_wallclock)(void);
int (*set_wallclock)(unsigned long);
- /* cpuid emulation, mostly so that caps bits can be disabled */
- void (*cpuid)(unsigned int *eax, unsigned int *ebx,
- unsigned int *ecx, unsigned int *edx);
+ unsigned long long (*sched_clock)(void);
+ unsigned long (*get_cpu_khz)(void);
+};
+struct pv_cpu_ops {
/* hooks for various privileged instructions */
unsigned long (*get_debugreg)(int regno);
void (*set_debugreg)(int regno, unsigned long value);
@@ -87,41 +82,10 @@ struct paravirt_ops
unsigned long (*read_cr0)(void);
void (*write_cr0)(unsigned long);
- unsigned long (*read_cr2)(void);
- void (*write_cr2)(unsigned long);
-
- unsigned long (*read_cr3)(void);
- void (*write_cr3)(unsigned long);
-
unsigned long (*read_cr4_safe)(void);
unsigned long (*read_cr4)(void);
void (*write_cr4)(unsigned long);
- /*
- * Get/set interrupt state. save_fl and restore_fl are only
- * expected to use X86_EFLAGS_IF; all other bits
- * returned from save_fl are undefined, and may be ignored by
- * restore_fl.
- */
- unsigned long (*save_fl)(void);
- void (*restore_fl)(unsigned long);
- void (*irq_disable)(void);
- void (*irq_enable)(void);
- void (*safe_halt)(void);
- void (*halt)(void);
-
- void (*wbinvd)(void);
-
- /* MSR, PMC and TSR operations.
- err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
- u64 (*read_msr)(unsigned int msr, int *err);
- int (*write_msr)(unsigned int msr, u64 val);
-
- u64 (*read_tsc)(void);
- u64 (*read_pmc)(void);
- unsigned long long (*sched_clock)(void);
- unsigned long (*get_cpu_khz)(void);
-
/* Segment descriptor handling */
void (*load_tr_desc)(void);
void (*load_gdt)(const struct Xgt_desc_struct *);
@@ -140,18 +104,47 @@ struct paravirt_ops
void (*load_esp0)(struct tss_struct *tss, struct thread_struct *t);
void (*set_iopl_mask)(unsigned mask);
+
+ void (*wbinvd)(void);
void (*io_delay)(void);
+ /* cpuid emulation, mostly so that caps bits can be disabled */
+ void (*cpuid)(unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx);
+
+ /* MSR, PMC and TSR operations.
+ err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
+ u64 (*read_msr)(unsigned int msr, int *err);
+ int (*write_msr)(unsigned int msr, u64 val);
+
+ u64 (*read_tsc)(void);
+ u64 (*read_pmc)(void);
+
+ /* These two are jmp to, not actually called. */
+ void (*irq_enable_sysexit)(void);
+ void (*iret)(void);
+
+ struct pv_lazy_ops lazy_mode;
+};
+
+struct pv_irq_ops {
+ void (*init_IRQ)(void);
+
/*
- * Hooks for intercepting the creation/use/destruction of an
- * mm_struct.
+ * Get/set interrupt state. save_fl and restore_fl are only
+ * expected to use X86_EFLAGS_IF; all other bits
+ * returned from save_fl are undefined, and may be ignored by
+ * restore_fl.
*/
- void (*activate_mm)(struct mm_struct *prev,
- struct mm_struct *next);
- void (*dup_mmap)(struct mm_struct *oldmm,
- struct mm_struct *mm);
- void (*exit_mmap)(struct mm_struct *mm);
+ unsigned long (*save_fl)(void);
+ void (*restore_fl)(unsigned long);
+ void (*irq_disable)(void);
+ void (*irq_enable)(void);
+ void (*safe_halt)(void);
+ void (*halt)(void);
+};
+struct pv_apic_ops {
#ifdef CONFIG_X86_LOCAL_APIC
/*
* Direct APIC operations, principally for VMI. Ideally
@@ -167,6 +160,34 @@ struct paravirt_ops
unsigned long start_eip,
unsigned long start_esp);
#endif
+};
+
+struct pv_mmu_ops {
+ /*
+ * Called before/after init_mm pagetable setup. setup_start
+ * may reset %cr3, and may pre-install parts of the pagetable;
+ * pagetable setup is expected to preserve any existing
+ * mapping.
+ */
+ void (*pagetable_setup_start)(pgd_t *pgd_base);
+ void (*pagetable_setup_done)(pgd_t *pgd_base);
+
+ unsigned long (*read_cr2)(void);
+ void (*write_cr2)(unsigned long);
+
+ unsigned long (*read_cr3)(void);
+ void (*write_cr3)(unsigned long);
+
+ /*
+ * Hooks for intercepting the creation/use/destruction of an
+ * mm_struct.
+ */
+ void (*activate_mm)(struct mm_struct *prev,
+ struct mm_struct *next);
+ void (*dup_mmap)(struct mm_struct *oldmm,
+ struct mm_struct *mm);
+ void (*exit_mmap)(struct mm_struct *mm);
+
/* TLB operations */
void (*flush_tlb_user)(void);
@@ -191,15 +212,12 @@ struct paravirt_ops
void (*pte_update_defer)(struct mm_struct *mm,
unsigned long addr, pte_t *ptep);
-#ifdef CONFIG_HIGHPTE
- void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
-#endif
-
#ifdef CONFIG_X86_PAE
void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
- void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
+ void (*set_pte_present)(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte);
void (*set_pud)(pud_t *pudp, pud_t pudval);
- void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+ void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
void (*pmd_clear)(pmd_t *pmdp);
unsigned long long (*pte_val)(pte_t);
@@ -217,21 +235,40 @@ struct paravirt_ops
pgd_t (*make_pgd)(unsigned long pgd);
#endif
- /* Set deferred update mode, used for batching operations. */
- void (*set_lazy_mode)(enum paravirt_lazy_mode mode);
+#ifdef CONFIG_HIGHPTE
+ void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
+#endif
- /* These two are jmp to, not actually called. */
- void (*irq_enable_sysexit)(void);
- void (*iret)(void);
+ struct pv_lazy_ops lazy_mode;
};
-extern struct paravirt_ops paravirt_ops;
+/* This contains all the paravirt structures: we get a convenient
+ * number for each function using the offset which we use to indicate
+ * what to patch. */
+struct paravirt_patch_template
+{
+ struct pv_init_ops pv_init_ops;
+ struct pv_time_ops pv_time_ops;
+ struct pv_cpu_ops pv_cpu_ops;
+ struct pv_irq_ops pv_irq_ops;
+ struct pv_apic_ops pv_apic_ops;
+ struct pv_mmu_ops pv_mmu_ops;
+};
+
+extern struct pv_info pv_info;
+extern struct pv_init_ops pv_init_ops;
+extern struct pv_time_ops pv_time_ops;
+extern struct pv_cpu_ops pv_cpu_ops;
+extern struct pv_irq_ops pv_irq_ops;
+extern struct pv_apic_ops pv_apic_ops;
+extern struct pv_mmu_ops pv_mmu_ops;
#define PARAVIRT_PATCH(x) \
- (offsetof(struct paravirt_ops, x) / sizeof(void *))
+ (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
-#define paravirt_type(type) \
- [paravirt_typenum] "i" (PARAVIRT_PATCH(type))
+#define paravirt_type(op) \
+ [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \
+ [paravirt_opptr] "m" (op)
#define paravirt_clobber(clobber) \
[paravirt_clobber] "i" (clobber)
@@ -258,7 +295,7 @@ unsigned paravirt_patch_call(void *insnbuf,
const void *target, u16 tgt_clobbers,
unsigned long addr, u16 site_clobbers,
unsigned len);
-unsigned paravirt_patch_jmp(const void *target, void *insnbuf,
+unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
unsigned long addr, unsigned len);
unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
unsigned long addr, unsigned len);
@@ -271,14 +308,14 @@ int paravirt_disable_iospace(void);
/*
* This generates an indirect call based on the operation type number.
* The type number, computed in PARAVIRT_PATCH, is derived from the
- * offset into the paravirt_ops structure, and can therefore be freely
- * converted back into a structure offset.
+ * offset into the paravirt_patch_template structure, and can therefore be
+ * freely converted back into a structure offset.
*/
-#define PARAVIRT_CALL "call *(paravirt_ops+%c[paravirt_typenum]*4);"
+#define PARAVIRT_CALL "call *%[paravirt_opptr];"
/*
- * These macros are intended to wrap calls into a paravirt_ops
- * operation, so that they can be later identified and patched at
+ * These macros are intended to wrap calls through one of the paravirt
+ * ops structs, so that they can be later identified and patched at
* runtime.
*
* Normally, a call to a pv_op function is a simple indirect call:
@@ -301,7 +338,7 @@ int paravirt_disable_iospace(void);
* The call instruction itself is marked by placing its start address
* and size into the .parainstructions section, so that
* apply_paravirt() in arch/i386/kernel/alternative.c can do the
- * appropriate patching under the control of the backend paravirt_ops
+ * appropriate patching under the control of the backend pv_init_ops
* implementation.
*
* Unfortunately there's no way to get gcc to generate the args setup
@@ -409,36 +446,36 @@ int paravirt_disable_iospace(void);
static inline int paravirt_enabled(void)
{
- return paravirt_ops.paravirt_enabled;
+ return pv_info.paravirt_enabled;
}
static inline void load_esp0(struct tss_struct *tss,
struct thread_struct *thread)
{
- PVOP_VCALL2(load_esp0, tss, thread);
+ PVOP_VCALL2(pv_cpu_ops.load_esp0, tss, thread);
}
-#define ARCH_SETUP paravirt_ops.arch_setup();
+#define ARCH_SETUP pv_init_ops.arch_setup();
static inline unsigned long get_wallclock(void)
{
- return PVOP_CALL0(unsigned long, get_wallclock);
+ return PVOP_CALL0(unsigned long, pv_time_ops.get_wallclock);
}
static inline int set_wallclock(unsigned long nowtime)
{
- return PVOP_CALL1(int, set_wallclock, nowtime);
+ return PVOP_CALL1(int, pv_time_ops.set_wallclock, nowtime);
}
static inline void (*choose_time_init(void))(void)
{
- return paravirt_ops.time_init;
+ return pv_time_ops.time_init;
}
/* The paravirtualized CPUID instruction. */
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
- PVOP_VCALL4(cpuid, eax, ebx, ecx, edx);
+ PVOP_VCALL4(pv_cpu_ops.cpuid, eax, ebx, ecx, edx);
}
/*
@@ -446,87 +483,87 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
*/
static inline unsigned long paravirt_get_debugreg(int reg)
{
- return PVOP_CALL1(unsigned long, get_debugreg, reg);
+ return PVOP_CALL1(unsigned long, pv_cpu_ops.get_debugreg, reg);
}
#define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)
static inline void set_debugreg(unsigned long val, int reg)
{
- PVOP_VCALL2(set_debugreg, reg, val);
+ PVOP_VCALL2(pv_cpu_ops.set_debugreg, reg, val);
}
static inline void clts(void)
{
- PVOP_VCALL0(clts);
+ PVOP_VCALL0(pv_cpu_ops.clts);
}
static inline unsigned long read_cr0(void)
{
- return PVOP_CALL0(unsigned long, read_cr0);
+ return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr0);
}
static inline void write_cr0(unsigned long x)
{
- PVOP_VCALL1(write_cr0, x);
+ PVOP_VCALL1(pv_cpu_ops.write_cr0, x);
}
static inline unsigned long read_cr2(void)
{
- return PVOP_CALL0(unsigned long, read_cr2);
+ return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr2);
}
static inline void write_cr2(unsigned long x)
{
- PVOP_VCALL1(write_cr2, x);
+ PVOP_VCALL1(pv_mmu_ops.write_cr2, x);
}
static inline unsigned long read_cr3(void)
{
- return PVOP_CALL0(unsigned long, read_cr3);
+ return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr3);
}
static inline void write_cr3(unsigned long x)
{
- PVOP_VCALL1(write_cr3, x);
+ PVOP_VCALL1(pv_mmu_ops.write_cr3, x);
}
static inline unsigned long read_cr4(void)
{
- return PVOP_CALL0(unsigned long, read_cr4);
+ return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4);
}
static inline unsigned long read_cr4_safe(void)
{
- return PVOP_CALL0(unsigned long, read_cr4_safe);
+ return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4_safe);
}
static inline void write_cr4(unsigned long x)
{
- PVOP_VCALL1(write_cr4, x);
+ PVOP_VCALL1(pv_cpu_ops.write_cr4, x);
}
static inline void raw_safe_halt(void)
{
- PVOP_VCALL0(safe_halt);
+ PVOP_VCALL0(pv_irq_ops.safe_halt);
}
static inline void halt(void)
{
- PVOP_VCALL0(safe_halt);
+ PVOP_VCALL0(pv_irq_ops.safe_halt);
}
static inline void wbinvd(void)
{
- PVOP_VCALL0(wbinvd);
+ PVOP_VCALL0(pv_cpu_ops.wbinvd);
}
-#define get_kernel_rpl() (paravirt_ops.kernel_rpl)
+#define get_kernel_rpl() (pv_info.kernel_rpl)
static inline u64 paravirt_read_msr(unsigned msr, int *err)
{
- return PVOP_CALL2(u64, read_msr, msr, err);
+ return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
}
static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
{
- return PVOP_CALL3(int, write_msr, msr, low, high);
+ return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
}
/* These should all do BUG_ON(_err), but our headers are too tangled. */
@@ -560,7 +597,7 @@ static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
static inline u64 paravirt_read_tsc(void)
{
- return PVOP_CALL0(u64, read_tsc);
+ return PVOP_CALL0(u64, pv_cpu_ops.read_tsc);
}
#define rdtscl(low) do { \
@@ -572,15 +609,15 @@ static inline u64 paravirt_read_tsc(void)
static inline unsigned long long paravirt_sched_clock(void)
{
- return PVOP_CALL0(unsigned long long, sched_clock);
+ return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
}
-#define calculate_cpu_khz() (paravirt_ops.get_cpu_khz())
+#define calculate_cpu_khz() (pv_time_ops.get_cpu_khz())
#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
static inline unsigned long long paravirt_read_pmc(int counter)
{
- return PVOP_CALL1(u64, read_pmc, counter);
+ return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter);
}
#define rdpmc(counter,low,high) do { \
@@ -591,61 +628,61 @@ static inline unsigned long long paravirt_read_pmc(int counter)
static inline void load_TR_desc(void)
{
- PVOP_VCALL0(load_tr_desc);
+ PVOP_VCALL0(pv_cpu_ops.load_tr_desc);
}
static inline void load_gdt(const struct Xgt_desc_struct *dtr)
{
- PVOP_VCALL1(load_gdt, dtr);
+ PVOP_VCALL1(pv_cpu_ops.load_gdt, dtr);
}
static inline void load_idt(const struct Xgt_desc_struct *dtr)
{
- PVOP_VCALL1(load_idt, dtr);
+ PVOP_VCALL1(pv_cpu_ops.load_idt, dtr);
}
static inline void set_ldt(const void *addr, unsigned entries)
{
- PVOP_VCALL2(set_ldt, addr, entries);
+ PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries);
}
static inline void store_gdt(struct Xgt_desc_struct *dtr)
{
- PVOP_VCALL1(store_gdt, dtr);
+ PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr);
}
static inline void store_idt(struct Xgt_desc_struct *dtr)
{
- PVOP_VCALL1(store_idt, dtr);
+ PVOP_VCALL1(pv_cpu_ops.store_idt, dtr);
}
static inline unsigned long paravirt_store_tr(void)
{
- return PVOP_CALL0(unsigned long, store_tr);
+ return PVOP_CALL0(unsigned long, pv_cpu_ops.store_tr);
}
#define store_tr(tr) ((tr) = paravirt_store_tr())
static inline void load_TLS(struct thread_struct *t, unsigned cpu)
{
- PVOP_VCALL2(load_tls, t, cpu);
+ PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu);
}
static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high)
{
- PVOP_VCALL4(write_ldt_entry, dt, entry, low, high);
+ PVOP_VCALL4(pv_cpu_ops.write_ldt_entry, dt, entry, low, high);
}
static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high)
{
- PVOP_VCALL4(write_gdt_entry, dt, entry, low, high);
+ PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, low, high);
}
static inline void write_idt_entry(void *dt, int entry, u32 low, u32 high)
{
- PVOP_VCALL4(write_idt_entry, dt, entry, low, high);
+ PVOP_VCALL4(pv_cpu_ops.write_idt_entry, dt, entry, low, high);
}
static inline void set_iopl_mask(unsigned mask)
{
- PVOP_VCALL1(set_iopl_mask, mask);
+ PVOP_VCALL1(pv_cpu_ops.set_iopl_mask, mask);
}
/* The paravirtualized I/O functions */
static inline void slow_down_io(void) {
- paravirt_ops.io_delay();
+ pv_cpu_ops.io_delay();
#ifdef REALLY_SLOW_IO
- paravirt_ops.io_delay();
- paravirt_ops.io_delay();
- paravirt_ops.io_delay();
+ pv_cpu_ops.io_delay();
+ pv_cpu_ops.io_delay();
+ pv_cpu_ops.io_delay();
#endif
}
@@ -655,121 +692,120 @@ static inline void slow_down_io(void) {
*/
static inline void apic_write(unsigned long reg, unsigned long v)
{
- PVOP_VCALL2(apic_write, reg, v);
+ PVOP_VCALL2(pv_apic_ops.apic_write, reg, v);
}
static inline void apic_write_atomic(unsigned long reg, unsigned long v)
{
- PVOP_VCALL2(apic_write_atomic, reg, v);
+ PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v);
}
static inline unsigned long apic_read(unsigned long reg)
{
- return PVOP_CALL1(unsigned long, apic_read, reg);
+ return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg);
}
static inline void setup_boot_clock(void)
{
- PVOP_VCALL0(setup_boot_clock);
+ PVOP_VCALL0(pv_apic_ops.setup_boot_clock);
}
static inline void setup_secondary_clock(void)
{
- PVOP_VCALL0(setup_secondary_clock);
+ PVOP_VCALL0(pv_apic_ops.setup_secondary_clock);
}
#endif
static inline void paravirt_post_allocator_init(void)
{
- if (paravirt_ops.post_allocator_init)
- (*paravirt_ops.post_allocator_init)();
+ if (pv_init_ops.post_allocator_init)
+ (*pv_init_ops.post_allocator_init)();
}
static inline void paravirt_pagetable_setup_start(pgd_t *base)
{
- if (paravirt_ops.pagetable_setup_start)
- (*paravirt_ops.pagetable_setup_start)(base);
+ (*pv_mmu_ops.pagetable_setup_start)(base);
}
static inline void paravirt_pagetable_setup_done(pgd_t *base)
{
- if (paravirt_ops.pagetable_setup_done)
- (*paravirt_ops.pagetable_setup_done)(base);
+ (*pv_mmu_ops.pagetable_setup_done)(base);
}
#ifdef CONFIG_SMP
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
unsigned long start_esp)
{
- PVOP_VCALL3(startup_ipi_hook, phys_apicid, start_eip, start_esp);
+ PVOP_VCALL3(pv_apic_ops.startup_ipi_hook,
+ phys_apicid, start_eip, start_esp);
}
#endif
static inline void paravirt_activate_mm(struct mm_struct *prev,
struct mm_struct *next)
{
- PVOP_VCALL2(activate_mm, prev, next);
+ PVOP_VCALL2(pv_mmu_ops.activate_mm, prev, next);
}
static inline void arch_dup_mmap(struct mm_struct *oldmm,
struct mm_struct *mm)
{
- PVOP_VCALL2(dup_mmap, oldmm, mm);
+ PVOP_VCALL2(pv_mmu_ops.dup_mmap, oldmm, mm);
}
static inline void arch_exit_mmap(struct mm_struct *mm)
{
- PVOP_VCALL1(exit_mmap, mm);
+ PVOP_VCALL1(pv_mmu_ops.exit_mmap, mm);
}
static inline void __flush_tlb(void)
{
- PVOP_VCALL0(flush_tlb_user);
+ PVOP_VCALL0(pv_mmu_ops.flush_tlb_user);
}
static inline void __flush_tlb_global(void)
{
- PVOP_VCALL0(flush_tlb_kernel);
+ PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel);
}
static inline void __flush_tlb_single(unsigned long addr)
{
- PVOP_VCALL1(flush_tlb_single, addr);
+ PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr);
}
static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
unsigned long va)
{
- PVOP_VCALL3(flush_tlb_others, &cpumask, mm, va);
+ PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va);
}
static inline void paravirt_alloc_pt(struct mm_struct *mm, unsigned pfn)
{
- PVOP_VCALL2(alloc_pt, mm, pfn);
+ PVOP_VCALL2(pv_mmu_ops.alloc_pt, mm, pfn);
}
static inline void paravirt_release_pt(unsigned pfn)
{
- PVOP_VCALL1(release_pt, pfn);
+ PVOP_VCALL1(pv_mmu_ops.release_pt, pfn);
}
static inline void paravirt_alloc_pd(unsigned pfn)
{
- PVOP_VCALL1(alloc_pd, pfn);
+ PVOP_VCALL1(pv_mmu_ops.alloc_pd, pfn);
}
static inline void paravirt_alloc_pd_clone(unsigned pfn, unsigned clonepfn,
unsigned start, unsigned count)
{
- PVOP_VCALL4(alloc_pd_clone, pfn, clonepfn, start, count);
+ PVOP_VCALL4(pv_mmu_ops.alloc_pd_clone, pfn, clonepfn, start, count);
}
static inline void paravirt_release_pd(unsigned pfn)
{
- PVOP_VCALL1(release_pd, pfn);
+ PVOP_VCALL1(pv_mmu_ops.release_pd, pfn);
}
#ifdef CONFIG_HIGHPTE
static inline void *kmap_atomic_pte(struct page *page, enum km_type type)
{
unsigned long ret;
- ret = PVOP_CALL2(unsigned long, kmap_atomic_pte, page, type);
+ ret = PVOP_CALL2(unsigned long, pv_mmu_ops.kmap_atomic_pte, page, type);
return (void *)ret;
}
#endif
@@ -777,162 +813,191 @@ static inline void *kmap_atomic_pte(struct page *page, enum km_type type)
static inline void pte_update(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
- PVOP_VCALL3(pte_update, mm, addr, ptep);
+ PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep);
}
static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
- PVOP_VCALL3(pte_update_defer, mm, addr, ptep);
+ PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep);
}
#ifdef CONFIG_X86_PAE
static inline pte_t __pte(unsigned long long val)
{
- unsigned long long ret = PVOP_CALL2(unsigned long long, make_pte,
+ unsigned long long ret = PVOP_CALL2(unsigned long long,
+ pv_mmu_ops.make_pte,
val, val >> 32);
return (pte_t) { ret, ret >> 32 };
}
static inline pmd_t __pmd(unsigned long long val)
{
- return (pmd_t) { PVOP_CALL2(unsigned long long, make_pmd, val, val >> 32) };
+ return (pmd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pmd,
+ val, val >> 32) };
}
static inline pgd_t __pgd(unsigned long long val)
{
- return (pgd_t) { PVOP_CALL2(unsigned long long, make_pgd, val, val >> 32) };
+ return (pgd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pgd,
+ val, val >> 32) };
}
static inline unsigned long long pte_val(pte_t x)
{
- return PVOP_CALL2(unsigned long long, pte_val, x.pte_low, x.pte_high);
+ return PVOP_CALL2(unsigned long long, pv_mmu_ops.pte_val,
+ x.pte_low, x.pte_high);
}
static inline unsigned long long pmd_val(pmd_t x)
{
- return PVOP_CALL2(unsigned long long, pmd_val, x.pmd, x.pmd >> 32);
+ return PVOP_CALL2(unsigned long long, pv_mmu_ops.pmd_val,
+ x.pmd, x.pmd >> 32);
}
static inline unsigned long long pgd_val(pgd_t x)
{
- return PVOP_CALL2(unsigned long long, pgd_val, x.pgd, x.pgd >> 32);
+ return PVOP_CALL2(unsigned long long, pv_mmu_ops.pgd_val,
+ x.pgd, x.pgd >> 32);
}
static inline void set_pte(pte_t *ptep, pte_t pteval)
{
- PVOP_VCALL3(set_pte, ptep, pteval.pte_low, pteval.pte_high);
+ PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, pteval.pte_low, pteval.pte_high);
}
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
/* 5 arg words */
- paravirt_ops.set_pte_at(mm, addr, ptep, pteval);
+ pv_mmu_ops.set_pte_at(mm, addr, ptep, pteval);
}
static inline void set_pte_atomic(pte_t *ptep, pte_t pteval)
{
- PVOP_VCALL3(set_pte_atomic, ptep, pteval.pte_low, pteval.pte_high);
+ PVOP_VCALL3(pv_mmu_ops.set_pte_atomic, ptep,
+ pteval.pte_low, pteval.pte_high);
}
static inline void set_pte_present(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte)
{
/* 5 arg words */
- paravirt_ops.set_pte_present(mm, addr, ptep, pte);
+ pv_mmu_ops.set_pte_present(mm, addr, ptep, pte);
}
static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
- PVOP_VCALL3(set_pmd, pmdp, pmdval.pmd, pmdval.pmd >> 32);
+ PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp,
+ pmdval.pmd, pmdval.pmd >> 32);
}
static inline void set_pud(pud_t *pudp, pud_t pudval)
{
- PVOP_VCALL3(set_pud, pudp, pudval.pgd.pgd, pudval.pgd.pgd >> 32);
+ PVOP_VCALL3(pv_mmu_ops.set_pud, pudp,
+ pudval.pgd.pgd, pudval.pgd.pgd >> 32);
}
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
- PVOP_VCALL3(pte_clear, mm, addr, ptep);
+ PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep);
}
static inline void pmd_clear(pmd_t *pmdp)
{
- PVOP_VCALL1(pmd_clear, pmdp);
+ PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp);
}
#else /* !CONFIG_X86_PAE */
static inline pte_t __pte(unsigned long val)
{
- return (pte_t) { PVOP_CALL1(unsigned long, make_pte, val) };
+ return (pte_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pte, val) };
}
static inline pgd_t __pgd(unsigned long val)
{
- return (pgd_t) { PVOP_CALL1(unsigned long, make_pgd, val) };
+ return (pgd_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pgd, val) };
}
static inline unsigned long pte_val(pte_t x)
{
- return PVOP_CALL1(unsigned long, pte_val, x.pte_low);
+ return PVOP_CALL1(unsigned long, pv_mmu_ops.pte_val, x.pte_low);
}
static inline unsigned long pgd_val(pgd_t x)
{
- return PVOP_CALL1(unsigned long, pgd_val, x.pgd);
+ return PVOP_CALL1(unsigned long, pv_mmu_ops.pgd_val, x.pgd);
}
static inline void set_pte(pte_t *ptep, pte_t pteval)
{
- PVOP_VCALL2(set_pte, ptep, pteval.pte_low);
+ PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, pteval.pte_low);
}
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
- PVOP_VCALL4(set_pte_at, mm, addr, ptep, pteval.pte_low);
+ PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pteval.pte_low);
}
static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
- PVOP_VCALL2(set_pmd, pmdp, pmdval.pud.pgd.pgd);
+ PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd);
}
#endif /* CONFIG_X86_PAE */
+/* Lazy mode for batching updates / context switch */
+enum paravirt_lazy_mode {
+ PARAVIRT_LAZY_NONE,
+ PARAVIRT_LAZY_MMU,
+ PARAVIRT_LAZY_CPU,
+};
+
+enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
+void paravirt_enter_lazy_cpu(void);
+void paravirt_leave_lazy_cpu(void);
+void paravirt_enter_lazy_mmu(void);
+void paravirt_leave_lazy_mmu(void);
+void paravirt_leave_lazy(enum paravirt_lazy_mode mode);
+
#define __HAVE_ARCH_ENTER_LAZY_CPU_MODE
static inline void arch_enter_lazy_cpu_mode(void)
{
- PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_CPU);
+ PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter);
}
static inline void arch_leave_lazy_cpu_mode(void)
{
- PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_NONE);
+ PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);
}
static inline void arch_flush_lazy_cpu_mode(void)
{
- PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_FLUSH);
+ if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) {
+ arch_leave_lazy_cpu_mode();
+ arch_enter_lazy_cpu_mode();
+ }
}
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
static inline void arch_enter_lazy_mmu_mode(void)
{
- PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_MMU);
+ PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter);
}
static inline void arch_leave_lazy_mmu_mode(void)
{
- PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_NONE);
+ PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
}
static inline void arch_flush_lazy_mmu_mode(void)
{
- PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_FLUSH);
+ if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) {
+ arch_leave_lazy_mmu_mode();
+ arch_enter_lazy_mmu_mode();
+ }
}
void _paravirt_nop(void);
@@ -957,7 +1022,7 @@ static inline unsigned long __raw_local_save_flags(void)
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
: "=a"(f)
- : paravirt_type(save_fl),
+ : paravirt_type(pv_irq_ops.save_fl),
paravirt_clobber(CLBR_EAX)
: "memory", "cc");
return f;
@@ -970,7 +1035,7 @@ static inline void raw_local_irq_restore(unsigned long f)
"popl %%edx; popl %%ecx")
: "=a"(f)
: "0"(f),
- paravirt_type(restore_fl),
+ paravirt_type(pv_irq_ops.restore_fl),
paravirt_clobber(CLBR_EAX)
: "memory", "cc");
}
@@ -981,7 +1046,7 @@ static inline void raw_local_irq_disable(void)
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
:
- : paravirt_type(irq_disable),
+ : paravirt_type(pv_irq_ops.irq_disable),
paravirt_clobber(CLBR_EAX)
: "memory", "eax", "cc");
}
@@ -992,7 +1057,7 @@ static inline void raw_local_irq_enable(void)
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
:
- : paravirt_type(irq_enable),
+ : paravirt_type(pv_irq_ops.irq_enable),
paravirt_clobber(CLBR_EAX)
: "memory", "eax", "cc");
}
@@ -1008,21 +1073,23 @@ static inline unsigned long __raw_local_irq_save(void)
#define CLI_STRING \
_paravirt_alt("pushl %%ecx; pushl %%edx;" \
- "call *paravirt_ops+%c[paravirt_cli_type]*4;" \
+ "call *%[paravirt_cli_opptr];" \
"popl %%edx; popl %%ecx", \
"%c[paravirt_cli_type]", "%c[paravirt_clobber]")
#define STI_STRING \
_paravirt_alt("pushl %%ecx; pushl %%edx;" \
- "call *paravirt_ops+%c[paravirt_sti_type]*4;" \
+ "call *%[paravirt_sti_opptr];" \
"popl %%edx; popl %%ecx", \
"%c[paravirt_sti_type]", "%c[paravirt_clobber]")
#define CLI_STI_CLOBBERS , "%eax"
#define CLI_STI_INPUT_ARGS \
, \
- [paravirt_cli_type] "i" (PARAVIRT_PATCH(irq_disable)), \
- [paravirt_sti_type] "i" (PARAVIRT_PATCH(irq_enable)), \
+ [paravirt_cli_type] "i" (PARAVIRT_PATCH(pv_irq_ops.irq_disable)), \
+ [paravirt_cli_opptr] "m" (pv_irq_ops.irq_disable), \
+ [paravirt_sti_type] "i" (PARAVIRT_PATCH(pv_irq_ops.irq_enable)), \
+ [paravirt_sti_opptr] "m" (pv_irq_ops.irq_enable), \
paravirt_clobber(CLBR_EAX)
/* Make sure as little as possible of this mess escapes. */
@@ -1042,7 +1109,7 @@ static inline unsigned long __raw_local_irq_save(void)
#else /* __ASSEMBLY__ */
-#define PARA_PATCH(off) ((off) / 4)
+#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
#define PARA_SITE(ptype, clobbers, ops) \
771:; \
@@ -1055,29 +1122,29 @@ static inline unsigned long __raw_local_irq_save(void)
.short clobbers; \
.popsection
-#define INTERRUPT_RETURN \
- PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \
- jmp *%cs:paravirt_ops+PARAVIRT_iret)
+#define INTERRUPT_RETURN \
+ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
+ jmp *%cs:pv_cpu_ops+PV_CPU_iret)
#define DISABLE_INTERRUPTS(clobbers) \
- PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \
+ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
pushl %eax; pushl %ecx; pushl %edx; \
- call *%cs:paravirt_ops+PARAVIRT_irq_disable; \
+ call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
popl %edx; popl %ecx; popl %eax) \
#define ENABLE_INTERRUPTS(clobbers) \
- PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \
+ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
pushl %eax; pushl %ecx; pushl %edx; \
- call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
+ call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
popl %edx; popl %ecx; popl %eax)
-#define ENABLE_INTERRUPTS_SYSEXIT \
- PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \
- jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
+#define ENABLE_INTERRUPTS_SYSEXIT \
+ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\
+ jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
#define GET_CR0_INTO_EAX \
push %ecx; push %edx; \
- call *paravirt_ops+PARAVIRT_read_cr0; \
+ call *pv_cpu_ops+PV_CPU_read_cr0; \
pop %edx; pop %ecx
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-x86/parport.h b/include/asm-x86/parport.h
index 2a31157349c..019cbca24a3 100644
--- a/include/asm-x86/parport.h
+++ b/include/asm-x86/parport.h
@@ -1,5 +1,10 @@
-#ifdef CONFIG_X86_32
-# include "parport_32.h"
-#else
-# include "parport_64.h"
-#endif
+#ifndef _ASM_X86_PARPORT_H
+#define _ASM_X86_PARPORT_H
+
+static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
+static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
+{
+ return parport_pc_find_isa_ports (autoirq, autodma);
+}
+
+#endif /* _ASM_X86_PARPORT_H */
diff --git a/include/asm-x86/parport_32.h b/include/asm-x86/parport_32.h
deleted file mode 100644
index fa0e321e498..00000000000
--- a/include/asm-x86/parport_32.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * parport.h: ia32-specific parport initialisation
- *
- * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-
-#ifndef _ASM_I386_PARPORT_H
-#define _ASM_I386_PARPORT_H 1
-
-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
-{
- return parport_pc_find_isa_ports (autoirq, autodma);
-}
-
-#endif /* !(_ASM_I386_PARPORT_H) */
diff --git a/include/asm-x86/parport_64.h b/include/asm-x86/parport_64.h
deleted file mode 100644
index 7135ef977c9..00000000000
--- a/include/asm-x86/parport_64.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * parport.h: ia32-specific parport initialisation
- *
- * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
- *
- * This file should only be included by drivers/parport/parport_pc.c.
- */
-
-#ifndef _ASM_X8664_PARPORT_H
-#define _ASM_X8664_PARPORT_H 1
-
-static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
-static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
-{
- return parport_pc_find_isa_ports (autoirq, autodma);
-}
-
-#endif
diff --git a/include/asm-x86/pda.h b/include/asm-x86/pda.h
index fb49f80eb94..35962bbe5e7 100644
--- a/include/asm-x86/pda.h
+++ b/include/asm-x86/pda.h
@@ -30,6 +30,12 @@ struct x8664_pda {
struct mm_struct *active_mm;
unsigned apic_timer_irqs;
unsigned irq0_irqs;
+ unsigned irq_resched_count;
+ unsigned irq_call_count;
+ unsigned irq_tlb_count;
+ unsigned irq_thermal_count;
+ unsigned irq_threshold_count;
+ unsigned irq_spurious_count;
} ____cacheline_aligned_in_smp;
extern struct x8664_pda *_cpu_pda[];
diff --git a/include/asm-x86/pgtable-3level-defs.h b/include/asm-x86/pgtable-3level-defs.h
index c0df89f66e8..448ac951631 100644
--- a/include/asm-x86/pgtable-3level-defs.h
+++ b/include/asm-x86/pgtable-3level-defs.h
@@ -2,7 +2,7 @@
#define _I386_PGTABLE_3LEVEL_DEFS_H
#ifdef CONFIG_PARAVIRT
-#define SHARED_KERNEL_PMD (paravirt_ops.shared_kernel_pmd)
+#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd)
#else
#define SHARED_KERNEL_PMD 1
#endif
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index c7fefa6b12f..acd4b339c49 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -40,7 +40,7 @@ extern spinlock_t pgd_lock;
extern struct page *pgd_list;
void check_pgt_cache(void);
-void pmd_ctor(void *, struct kmem_cache *, unsigned long);
+void pmd_ctor(struct kmem_cache *, void *);
void pgtable_cache_init(void);
void paging_init(void);
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index 57dd6b3107e..a79f5355e3b 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -137,6 +137,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
#define MAXMEM _AC(0x3fffffffffff, UL)
#define VMALLOC_START _AC(0xffffc20000000000, UL)
#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
+#define VMEMMAP_START _AC(0xffffe20000000000, UL)
#define MODULES_VADDR _AC(0xffffffff88000000, UL)
#define MODULES_END _AC(0xfffffffffff00000, UL)
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h
index 3845fe72383..83800e7496e 100644
--- a/include/asm-x86/processor_32.h
+++ b/include/asm-x86/processor_32.h
@@ -595,7 +595,9 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa
* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
* resulting in stale register contents being returned.
*/
-static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
+static inline void cpuid(unsigned int op,
+ unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
{
*eax = op;
*ecx = 0;
@@ -603,8 +605,9 @@ static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx,
}
/* Some CPUID calls want 'count' to be placed in ecx */
-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
- int *edx)
+static inline void cpuid_count(unsigned int op, int count,
+ unsigned int *eax, unsigned int *ebx,
+ unsigned int *ecx, unsigned int *edx)
{
*eax = op;
*ecx = count;
@@ -674,6 +677,17 @@ static inline unsigned int cpuid_edx(unsigned int op)
#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n"
#define K7_NOP8 K7_NOP7 ASM_NOP1
+/* P6 nops */
+/* uses eax dependencies (Intel-recommended choice) */
+#define P6_NOP1 GENERIC_NOP1
+#define P6_NOP2 ".byte 0x66,0x90\n"
+#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n"
+#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n"
+#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n"
+#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
+#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
+#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
+
#ifdef CONFIG_MK8
#define ASM_NOP1 K8_NOP1
#define ASM_NOP2 K8_NOP2
@@ -692,6 +706,17 @@ static inline unsigned int cpuid_edx(unsigned int op)
#define ASM_NOP6 K7_NOP6
#define ASM_NOP7 K7_NOP7
#define ASM_NOP8 K7_NOP8
+#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
+ defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
+ defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
+#define ASM_NOP1 P6_NOP1
+#define ASM_NOP2 P6_NOP2
+#define ASM_NOP3 P6_NOP3
+#define ASM_NOP4 P6_NOP4
+#define ASM_NOP5 P6_NOP5
+#define ASM_NOP6 P6_NOP6
+#define ASM_NOP7 P6_NOP7
+#define ASM_NOP8 P6_NOP8
#else
#define ASM_NOP1 GENERIC_NOP1
#define ASM_NOP2 GENERIC_NOP2
diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h
index 31f579b828f..f422becbddd 100644
--- a/include/asm-x86/processor_64.h
+++ b/include/asm-x86/processor_64.h
@@ -334,6 +334,16 @@ struct extended_sigtable {
};
+#if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2)
+#define ASM_NOP1 P6_NOP1
+#define ASM_NOP2 P6_NOP2
+#define ASM_NOP3 P6_NOP3
+#define ASM_NOP4 P6_NOP4
+#define ASM_NOP5 P6_NOP5
+#define ASM_NOP6 P6_NOP6
+#define ASM_NOP7 P6_NOP7
+#define ASM_NOP8 P6_NOP8
+#else
#define ASM_NOP1 K8_NOP1
#define ASM_NOP2 K8_NOP2
#define ASM_NOP3 K8_NOP3
@@ -342,6 +352,7 @@ struct extended_sigtable {
#define ASM_NOP6 K8_NOP6
#define ASM_NOP7 K8_NOP7
#define ASM_NOP8 K8_NOP8
+#endif
/* Opteron nops */
#define K8_NOP1 ".byte 0x90\n"
@@ -353,6 +364,17 @@ struct extended_sigtable {
#define K8_NOP7 K8_NOP4 K8_NOP3
#define K8_NOP8 K8_NOP4 K8_NOP4
+/* P6 nops */
+/* uses eax dependencies (Intel-recommended choice) */
+#define P6_NOP1 ".byte 0x90\n"
+#define P6_NOP2 ".byte 0x66,0x90\n"
+#define P6_NOP3 ".byte 0x0f,0x1f,0x00\n"
+#define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n"
+#define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n"
+#define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
+#define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
+#define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
+
#define ASM_NOP_MAX 8
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
@@ -389,11 +411,6 @@ static inline void prefetchw(void *x)
#define cpu_relax() rep_nop()
-static inline void serialize_cpu(void)
-{
- __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
-}
-
static inline void __monitor(const void *eax, unsigned long ecx,
unsigned long edx)
{
diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h
index 6824c49def1..7524e123383 100644
--- a/include/asm-x86/ptrace-abi.h
+++ b/include/asm-x86/ptrace-abi.h
@@ -1,13 +1,81 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "ptrace-abi_32.h"
-# else
-# include "ptrace-abi_64.h"
-# endif
+#ifndef _ASM_X86_PTRACE_ABI_H
+#define _ASM_X86_PTRACE_ABI_H
+
+#ifdef __i386__
+
+#define EBX 0
+#define ECX 1
+#define EDX 2
+#define ESI 3
+#define EDI 4
+#define EBP 5
+#define EAX 6
+#define DS 7
+#define ES 8
+#define FS 9
+#define GS 10
+#define ORIG_EAX 11
+#define EIP 12
+#define CS 13
+#define EFL 14
+#define UESP 15
+#define SS 16
+#define FRAME_SIZE 17
+
+#else /* __i386__ */
+
+#if defined(__ASSEMBLY__) || defined(__FRAME_OFFSETS)
+#define R15 0
+#define R14 8
+#define R13 16
+#define R12 24
+#define RBP 32
+#define RBX 40
+/* arguments: interrupts/non tracing syscalls only save upto here*/
+#define R11 48
+#define R10 56
+#define R9 64
+#define R8 72
+#define RAX 80
+#define RCX 88
+#define RDX 96
+#define RSI 104
+#define RDI 112
+#define ORIG_RAX 120 /* = ERROR */
+/* end of arguments */
+/* cpu exception frame or undefined in case of fast syscall. */
+#define RIP 128
+#define CS 136
+#define EFLAGS 144
+#define RSP 152
+#define SS 160
+#define ARGOFFSET R11
+#endif /* __ASSEMBLY__ */
+
+/* top of stack page */
+#define FRAME_SIZE 168
+
+#endif /* !__i386__ */
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_GETFPXREGS 18
+#define PTRACE_SETFPXREGS 19
+
+#define PTRACE_OLDSETOPTIONS 21
+
+/* only useful for access 32bit programs / kernels */
+#define PTRACE_GET_THREAD_AREA 25
+#define PTRACE_SET_THREAD_AREA 26
+
+#ifdef __x86_64__
+# define PTRACE_ARCH_PRCTL 30
#else
-# ifdef __i386__
-# include "ptrace-abi_32.h"
-# else
-# include "ptrace-abi_64.h"
-# endif
+# define PTRACE_SYSEMU 31
+# define PTRACE_SYSEMU_SINGLESTEP 32
+#endif
+
#endif
diff --git a/include/asm-x86/ptrace-abi_32.h b/include/asm-x86/ptrace-abi_32.h
deleted file mode 100644
index a44901817a2..00000000000
--- a/include/asm-x86/ptrace-abi_32.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef I386_PTRACE_ABI_H
-#define I386_PTRACE_ABI_H
-
-#define EBX 0
-#define ECX 1
-#define EDX 2
-#define ESI 3
-#define EDI 4
-#define EBP 5
-#define EAX 6
-#define DS 7
-#define ES 8
-#define FS 9
-#define GS 10
-#define ORIG_EAX 11
-#define EIP 12
-#define CS 13
-#define EFL 14
-#define UESP 15
-#define SS 16
-#define FRAME_SIZE 17
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-#define PTRACE_GETFPXREGS 18
-#define PTRACE_SETFPXREGS 19
-
-#define PTRACE_OLDSETOPTIONS 21
-
-#define PTRACE_GET_THREAD_AREA 25
-#define PTRACE_SET_THREAD_AREA 26
-
-#define PTRACE_SYSEMU 31
-#define PTRACE_SYSEMU_SINGLESTEP 32
-
-#endif
diff --git a/include/asm-x86/ptrace-abi_64.h b/include/asm-x86/ptrace-abi_64.h
deleted file mode 100644
index 19184b0806b..00000000000
--- a/include/asm-x86/ptrace-abi_64.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _X86_64_PTRACE_ABI_H
-#define _X86_64_PTRACE_ABI_H
-
-#if defined(__ASSEMBLY__) || defined(__FRAME_OFFSETS)
-#define R15 0
-#define R14 8
-#define R13 16
-#define R12 24
-#define RBP 32
-#define RBX 40
-/* arguments: interrupts/non tracing syscalls only save upto here*/
-#define R11 48
-#define R10 56
-#define R9 64
-#define R8 72
-#define RAX 80
-#define RCX 88
-#define RDX 96
-#define RSI 104
-#define RDI 112
-#define ORIG_RAX 120 /* = ERROR */
-/* end of arguments */
-/* cpu exception frame or undefined in case of fast syscall. */
-#define RIP 128
-#define CS 136
-#define EFLAGS 144
-#define RSP 152
-#define SS 160
-#define ARGOFFSET R11
-#endif /* __ASSEMBLY__ */
-
-/* top of stack page */
-#define FRAME_SIZE 168
-
-#define PTRACE_OLDSETOPTIONS 21
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-#define PTRACE_GETFPXREGS 18
-#define PTRACE_SETFPXREGS 19
-
-/* only useful for access 32bit programs */
-#define PTRACE_GET_THREAD_AREA 25
-#define PTRACE_SET_THREAD_AREA 26
-
-#define PTRACE_ARCH_PRCTL 30 /* arch_prctl for child */
-
-#endif
diff --git a/include/asm-x86/resource.h b/include/asm-x86/resource.h
index 732410a8c02..04bc4db8921 100644
--- a/include/asm-x86/resource.h
+++ b/include/asm-x86/resource.h
@@ -1,13 +1 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "resource_32.h"
-# else
-# include "resource_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "resource_32.h"
-# else
-# include "resource_64.h"
-# endif
-#endif
+#include <asm-generic/resource.h>
diff --git a/include/asm-x86/resource_32.h b/include/asm-x86/resource_32.h
deleted file mode 100644
index 6c1ea37c771..00000000000
--- a/include/asm-x86/resource_32.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _I386_RESOURCE_H
-#define _I386_RESOURCE_H
-
-#include <asm-generic/resource.h>
-
-#endif
diff --git a/include/asm-x86/resource_64.h b/include/asm-x86/resource_64.h
deleted file mode 100644
index f40b4062323..00000000000
--- a/include/asm-x86/resource_64.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _X8664_RESOURCE_H
-#define _X8664_RESOURCE_H
-
-#include <asm-generic/resource.h>
-
-#endif
diff --git a/include/asm-x86/rtc.h b/include/asm-x86/rtc.h
index 1f0c98eb2e3..f71c3b0ed36 100644
--- a/include/asm-x86/rtc.h
+++ b/include/asm-x86/rtc.h
@@ -1,5 +1 @@
-#ifdef CONFIG_X86_32
-# include "rtc_32.h"
-#else
-# include "rtc_64.h"
-#endif
+#include <asm-generic/rtc.h>
diff --git a/include/asm-x86/rtc_32.h b/include/asm-x86/rtc_32.h
deleted file mode 100644
index ffd02109a0e..00000000000
--- a/include/asm-x86/rtc_32.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _I386_RTC_H
-#define _I386_RTC_H
-
-/*
- * x86 uses the default access methods for the RTC.
- */
-
-#include <asm-generic/rtc.h>
-
-#endif
diff --git a/include/asm-x86/rtc_64.h b/include/asm-x86/rtc_64.h
deleted file mode 100644
index 18ed713ac7d..00000000000
--- a/include/asm-x86/rtc_64.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _X86_64_RTC_H
-#define _X86_64_RTC_H
-
-/*
- * x86 uses the default access methods for the RTC.
- */
-
-#include <asm-generic/rtc.h>
-
-#endif
diff --git a/include/asm-x86/rwlock.h b/include/asm-x86/rwlock.h
index a3be7d8364a..f2b64a429e6 100644
--- a/include/asm-x86/rwlock.h
+++ b/include/asm-x86/rwlock.h
@@ -1,5 +1,9 @@
-#ifdef CONFIG_X86_32
-# include "rwlock_32.h"
-#else
-# include "rwlock_64.h"
-#endif
+#ifndef _ASM_X86_RWLOCK_H
+#define _ASM_X86_RWLOCK_H
+
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+/* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */
+
+#endif /* _ASM_X86_RWLOCK_H */
diff --git a/include/asm-x86/rwlock_32.h b/include/asm-x86/rwlock_32.h
deleted file mode 100644
index c3e5db32fa4..00000000000
--- a/include/asm-x86/rwlock_32.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* include/asm-i386/rwlock.h
- *
- * Helpers used by both rw spinlocks and rw semaphores.
- *
- * Based in part on code from semaphore.h and
- * spinlock.h Copyright 1996 Linus Torvalds.
- *
- * Copyright 1999 Red Hat, Inc.
- *
- * Written by Benjamin LaHaise.
- *
- * 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.
- */
-#ifndef _ASM_I386_RWLOCK_H
-#define _ASM_I386_RWLOCK_H
-
-#define RW_LOCK_BIAS 0x01000000
-#define RW_LOCK_BIAS_STR "0x01000000"
-
-/* Code is in asm-i386/spinlock.h */
-
-#endif
diff --git a/include/asm-x86/rwlock_64.h b/include/asm-x86/rwlock_64.h
deleted file mode 100644
index 72aeebed920..00000000000
--- a/include/asm-x86/rwlock_64.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* include/asm-x86_64/rwlock.h
- *
- * Helpers used by both rw spinlocks and rw semaphores.
- *
- * Based in part on code from semaphore.h and
- * spinlock.h Copyright 1996 Linus Torvalds.
- *
- * Copyright 1999 Red Hat, Inc.
- * Copyright 2001,2002 SuSE labs
- *
- * Written by Benjamin LaHaise.
- *
- * 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.
- */
-#ifndef _ASM_X86_64_RWLOCK_H
-#define _ASM_X86_64_RWLOCK_H
-
-#define RW_LOCK_BIAS 0x01000000
-#define RW_LOCK_BIAS_STR "0x01000000"
-
-/* Actual code is in asm/spinlock.h or in arch/x86_64/lib/rwlock.S */
-
-#endif
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index d7e45a8f1aa..bd5164aa8f6 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -10,6 +10,8 @@ struct scatterlist {
unsigned int length;
};
+#define ARCH_HAS_SG_CHAIN
+
/* These macros should be used after a pci_map_sg call has been done
* to get bus addresses of each of the SG entries and their lengths.
* You should only work with the number of sg entries pci_map_sg
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index eaf7ada27e1..ef3986ba4b7 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -11,6 +11,8 @@ struct scatterlist {
unsigned int dma_length;
};
+#define ARCH_HAS_SG_CHAIN
+
#define ISA_DMA_THRESHOLD (0x00ffffff)
/* These macros should be used after a pci_map_sg call has been done
diff --git a/include/asm-x86/sections.h b/include/asm-x86/sections.h
index ae6c69d9be3..2b8c5160388 100644
--- a/include/asm-x86/sections.h
+++ b/include/asm-x86/sections.h
@@ -1,5 +1 @@
-#ifdef CONFIG_X86_32
-# include "sections_32.h"
-#else
-# include "sections_64.h"
-#endif
+#include <asm-generic/sections.h>
diff --git a/include/asm-x86/sections_32.h b/include/asm-x86/sections_32.h
deleted file mode 100644
index 2dcbb92918b..00000000000
--- a/include/asm-x86/sections_32.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _I386_SECTIONS_H
-#define _I386_SECTIONS_H
-
-/* nothing to see, move along */
-#include <asm-generic/sections.h>
-
-#endif
diff --git a/include/asm-x86/sections_64.h b/include/asm-x86/sections_64.h
deleted file mode 100644
index c746d9f1e70..00000000000
--- a/include/asm-x86/sections_64.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _X8664_SECTIONS_H
-#define _X8664_SECTIONS_H
-
-/* nothing to see, move along */
-#include <asm-generic/sections.h>
-
-#endif
diff --git a/include/asm-x86/semaphore_32.h b/include/asm-x86/semaphore_32.h
index 4e34a468c38..835c1d751a9 100644
--- a/include/asm-x86/semaphore_32.h
+++ b/include/asm-x86/semaphore_32.h
@@ -59,7 +59,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-x86/semaphore_64.h b/include/asm-x86/semaphore_64.h
index 1194888536b..79694306bf7 100644
--- a/include/asm-x86/semaphore_64.h
+++ b/include/asm-x86/semaphore_64.h
@@ -60,7 +60,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-x86/sembuf.h b/include/asm-x86/sembuf.h
index e42c971e383..ee50c801f7b 100644
--- a/include/asm-x86/sembuf.h
+++ b/include/asm-x86/sembuf.h
@@ -1,13 +1,24 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "sembuf_32.h"
-# else
-# include "sembuf_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "sembuf_32.h"
-# else
-# include "sembuf_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_SEMBUF_H
+#define _ASM_X86_SEMBUF_H
+
+/*
+ * The semid64_ds structure for x86 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+struct semid64_ds {
+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ unsigned long __unused1;
+ __kernel_time_t sem_ctime; /* last change time */
+ unsigned long __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _ASM_X86_SEMBUF_H */
diff --git a/include/asm-x86/sembuf_32.h b/include/asm-x86/sembuf_32.h
deleted file mode 100644
index 323835166c1..00000000000
--- a/include/asm-x86/sembuf_32.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _I386_SEMBUF_H
-#define _I386_SEMBUF_H
-
-/*
- * The semid64_ds structure for i386 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct semid64_ds {
- struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- unsigned long __unused1;
- __kernel_time_t sem_ctime; /* last change time */
- unsigned long __unused2;
- unsigned long sem_nsems; /* no. of semaphores in array */
- unsigned long __unused3;
- unsigned long __unused4;
-};
-
-#endif /* _I386_SEMBUF_H */
diff --git a/include/asm-x86/sembuf_64.h b/include/asm-x86/sembuf_64.h
deleted file mode 100644
index 63b52925ae2..00000000000
--- a/include/asm-x86/sembuf_64.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _X86_64_SEMBUF_H
-#define _X86_64_SEMBUF_H
-
-/*
- * The semid64_ds structure for x86_64 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- */
-
-struct semid64_ds {
- struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- unsigned long __unused1;
- __kernel_time_t sem_ctime; /* last change time */
- unsigned long __unused2;
- unsigned long sem_nsems; /* no. of semaphores in array */
- unsigned long __unused3;
- unsigned long __unused4;
-};
-
-#endif /* _X86_64_SEMBUF_H */
diff --git a/include/asm-x86/serial.h b/include/asm-x86/serial.h
index cf1b05227b2..628c801535e 100644
--- a/include/asm-x86/serial.h
+++ b/include/asm-x86/serial.h
@@ -1,5 +1,29 @@
-#ifdef CONFIG_X86_32
-# include "serial_32.h"
+#ifndef _ASM_X86_SERIAL_H
+#define _ASM_X86_SERIAL_H
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
+#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
#else
-# include "serial_64.h"
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
#endif
+
+#define SERIAL_PORT_DFNS \
+ /* UART CLK PORT IRQ FLAGS */ \
+ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
+ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
+ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
+ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
+
+#endif /* _ASM_X86_SERIAL_H */
diff --git a/include/asm-x86/serial_32.h b/include/asm-x86/serial_32.h
deleted file mode 100644
index bd67480ca10..00000000000
--- a/include/asm-x86/serial_32.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * include/asm-i386/serial.h
- */
-
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD ( 1843200 / 16 )
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#define SERIAL_PORT_DFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
diff --git a/include/asm-x86/serial_64.h b/include/asm-x86/serial_64.h
deleted file mode 100644
index b0496e0d72a..00000000000
--- a/include/asm-x86/serial_64.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * include/asm-x86_64/serial.h
- */
-
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD ( 1843200 / 16 )
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#define SERIAL_PORT_DFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
diff --git a/include/asm-x86/setup_32.h b/include/asm-x86/setup_32.h
index 7862fe858a9..7a57ca8a179 100644
--- a/include/asm-x86/setup_32.h
+++ b/include/asm-x86/setup_32.h
@@ -34,35 +34,6 @@
*/
extern struct boot_params boot_params;
-#define PARAM ((char *)&boot_params)
-#define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
-#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
-#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
-#define E820_MAP_NR (*(char*) (PARAM+E820NR))
-#define E820_MAP ((struct e820entry *) (PARAM+E820MAP))
-#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
-#define IST_INFO (*(struct ist_info *) (PARAM+0x60))
-#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
-#define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
-#define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
-#define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
-#define EFI_MEMMAP ((void *) *((unsigned long *)(PARAM+0x1d0)))
-#define EFI_MEMMAP_SIZE (*((unsigned long *) (PARAM+0x1d4)))
-#define MOUNT_ROOT_RDONLY (*(unsigned short *) (PARAM+0x1F2))
-#define RAMDISK_FLAGS (*(unsigned short *) (PARAM+0x1F8))
-#define VIDEO_MODE (*(unsigned short *) (PARAM+0x1FA))
-#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
-#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
-#define LOADER_TYPE (*(unsigned char *) (PARAM+0x210))
-#define KERNEL_START (*(unsigned long *) (PARAM+0x214))
-#define INITRD_START (*(unsigned long *) (PARAM+0x218))
-#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
-#define EDID_INFO (*(struct edid_info *) (PARAM+0x140))
-#define EDD_NR (*(unsigned char *) (PARAM+EDDNR))
-#define EDD_MBR_SIG_NR (*(unsigned char *) (PARAM+EDD_MBR_SIG_NR_BUF))
-#define EDD_MBR_SIGNATURE ((unsigned int *) (PARAM+EDD_MBR_SIG_BUF))
-#define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF))
-
/*
* Do NOT EVER look at the BIOS memory size location.
* It does not work on many machines.
diff --git a/include/asm-x86/setup_64.h b/include/asm-x86/setup_64.h
index eaeff73d6c1..a04aadcccf6 100644
--- a/include/asm-x86/setup_64.h
+++ b/include/asm-x86/setup_64.h
@@ -3,4 +3,17 @@
#define COMMAND_LINE_SIZE 2048
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <asm/bootparam.h>
+
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+extern struct boot_params boot_params;
+
+#endif /* not __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
#endif
diff --git a/include/asm-x86/shmparam.h b/include/asm-x86/shmparam.h
index 165627cc534..0880cf0917b 100644
--- a/include/asm-x86/shmparam.h
+++ b/include/asm-x86/shmparam.h
@@ -1,13 +1,6 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "shmparam_32.h"
-# else
-# include "shmparam_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "shmparam_32.h"
-# else
-# include "shmparam_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_SHMPARAM_H
+#define _ASM_X86_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _ASM_X86_SHMPARAM_H */
diff --git a/include/asm-x86/shmparam_32.h b/include/asm-x86/shmparam_32.h
deleted file mode 100644
index 786243a5b31..00000000000
--- a/include/asm-x86/shmparam_32.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASMI386_SHMPARAM_H
-#define _ASMI386_SHMPARAM_H
-
-#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
-
-#endif /* _ASMI386_SHMPARAM_H */
diff --git a/include/asm-x86/shmparam_64.h b/include/asm-x86/shmparam_64.h
deleted file mode 100644
index d7021620dcb..00000000000
--- a/include/asm-x86/shmparam_64.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASMX8664_SHMPARAM_H
-#define _ASMX8664_SHMPARAM_H
-
-#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
-
-#endif /* _ASMX8664_SHMPARAM_H */
diff --git a/include/asm-x86/siginfo.h b/include/asm-x86/siginfo.h
index 0b8e4bb47d2..a477bea0c2a 100644
--- a/include/asm-x86/siginfo.h
+++ b/include/asm-x86/siginfo.h
@@ -1,13 +1,10 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "siginfo_32.h"
-# else
-# include "siginfo_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "siginfo_32.h"
-# else
-# include "siginfo_64.h"
-# endif
+#ifndef _ASM_X86_SIGINFO_H
+#define _ASM_X86_SIGINFO_H
+
+#ifdef __x86_64__
+# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#endif
+
+#include <asm-generic/siginfo.h>
+
#endif
diff --git a/include/asm-x86/siginfo_32.h b/include/asm-x86/siginfo_32.h
deleted file mode 100644
index fe18f98fccf..00000000000
--- a/include/asm-x86/siginfo_32.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _I386_SIGINFO_H
-#define _I386_SIGINFO_H
-
-#include <asm-generic/siginfo.h>
-
-#endif
diff --git a/include/asm-x86/siginfo_64.h b/include/asm-x86/siginfo_64.h
deleted file mode 100644
index d09a1e6e724..00000000000
--- a/include/asm-x86/siginfo_64.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _X8664_SIGINFO_H
-#define _X8664_SIGINFO_H
-
-#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
-
-#include <asm-generic/siginfo.h>
-
-#endif
diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h
index 1f73bde165b..ee46038d126 100644
--- a/include/asm-x86/smp_32.h
+++ b/include/asm-x86/smp_32.h
@@ -30,8 +30,8 @@
extern void smp_alloc_memory(void);
extern int pic_mode;
extern int smp_num_siblings;
-extern cpumask_t cpu_sibling_map[];
-extern cpumask_t cpu_core_map[];
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_t, cpu_core_map);
extern void (*mtrr_hook) (void);
extern void zap_low_mappings (void);
@@ -92,12 +92,9 @@ static inline void smp_send_reschedule(int cpu)
{
smp_ops.smp_send_reschedule(cpu);
}
-static inline int smp_call_function_mask(cpumask_t mask,
- void (*func) (void *info), void *info,
- int wait)
-{
- return smp_ops.smp_call_function_mask(mask, func, info, wait);
-}
+extern int smp_call_function_mask(cpumask_t mask,
+ void (*func) (void *info), void *info,
+ int wait);
void native_smp_prepare_boot_cpu(void);
void native_smp_prepare_cpus(unsigned int max_cpus);
diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h
index 3f303d2365e..d30e9b684fd 100644
--- a/include/asm-x86/smp_64.h
+++ b/include/asm-x86/smp_64.h
@@ -38,8 +38,15 @@ extern void unlock_ipi_call_lock(void);
extern int smp_num_siblings;
extern void smp_send_reschedule(int cpu);
-extern cpumask_t cpu_sibling_map[NR_CPUS];
-extern cpumask_t cpu_core_map[NR_CPUS];
+/*
+ * cpu_sibling_map and cpu_core_map now live
+ * in the per cpu area
+ *
+ * extern cpumask_t cpu_sibling_map[NR_CPUS];
+ * extern cpumask_t cpu_core_map[NR_CPUS];
+ */
+DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_t, cpu_core_map);
extern u8 cpu_llc_id[NR_CPUS];
#define SMP_TRAMPOLINE_BASE 0x6000
@@ -78,7 +85,6 @@ static inline int hard_smp_processor_id(void)
* the real APIC ID <-> CPU # mapping.
*/
extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */
-extern u8 x86_cpu_to_log_apicid[NR_CPUS];
extern u8 bios_cpu_apicid[];
static inline int cpu_present_to_apicid(int mps_cpu)
diff --git a/include/asm-x86/sockios.h b/include/asm-x86/sockios.h
index 5a134fc70b9..49cc72b5d3c 100644
--- a/include/asm-x86/sockios.h
+++ b/include/asm-x86/sockios.h
@@ -1,13 +1,13 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "sockios_32.h"
-# else
-# include "sockios_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "sockios_32.h"
-# else
-# include "sockios_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_SOCKIOS_H
+#define _ASM_X86_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
+#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
+
+#endif /* _ASM_X86_SOCKIOS_H */
diff --git a/include/asm-x86/sockios_32.h b/include/asm-x86/sockios_32.h
deleted file mode 100644
index ff528c7d255..00000000000
--- a/include/asm-x86/sockios_32.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ARCH_I386_SOCKIOS__
-#define __ARCH_I386_SOCKIOS__
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 0x8901
-#define SIOCSPGRP 0x8902
-#define FIOGETOWN 0x8903
-#define SIOCGPGRP 0x8904
-#define SIOCATMARK 0x8905
-#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
-#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
-
-#endif
diff --git a/include/asm-x86/sockios_64.h b/include/asm-x86/sockios_64.h
deleted file mode 100644
index d726ba2513e..00000000000
--- a/include/asm-x86/sockios_64.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ARCH_X8664_SOCKIOS__
-#define __ARCH_X8664_SOCKIOS__
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 0x8901
-#define SIOCSPGRP 0x8902
-#define FIOGETOWN 0x8903
-#define SIOCGPGRP 0x8904
-#define SIOCATMARK 0x8905
-#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
-#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
-
-#endif
diff --git a/include/asm-x86/stacktrace.h b/include/asm-x86/stacktrace.h
index 6f0b5459430..70dd5bae323 100644
--- a/include/asm-x86/stacktrace.h
+++ b/include/asm-x86/stacktrace.h
@@ -15,6 +15,6 @@ struct stacktrace_ops {
};
void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
- struct stacktrace_ops *ops, void *data);
+ const struct stacktrace_ops *ops, void *data);
#endif
diff --git a/include/asm-x86/string_32.h b/include/asm-x86/string_32.h
index a9b64453bdf..55bfa308f90 100644
--- a/include/asm-x86/string_32.h
+++ b/include/asm-x86/string_32.h
@@ -26,9 +26,6 @@ extern int strncmp(const char *cs, const char *ct, size_t count);
#define __HAVE_ARCH_STRCHR
extern char *strchr(const char *s, int c);
-#define __HAVE_ARCH_STRRCHR
-extern char *strrchr(const char *s, int c);
-
#define __HAVE_ARCH_STRLEN
extern size_t strlen(const char *s);
diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h
index b897e8cb55f..9440a7a1b99 100644
--- a/include/asm-x86/suspend_64.h
+++ b/include/asm-x86/suspend_64.h
@@ -53,3 +53,5 @@ extern unsigned long saved_rdi;
/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
+extern char core_restore_code;
+extern char restore_registers;
diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h
index e7e5d426fef..db6283eb5e4 100644
--- a/include/asm-x86/system_32.h
+++ b/include/asm-x86/system_32.h
@@ -7,6 +7,7 @@
#include <asm/cmpxchg.h>
#ifdef __KERNEL__
+#define AT_VECTOR_SIZE_ARCH 2 /* entries in ARCH_DLINFO */
struct task_struct; /* one of the stranger aspects of C forward declarations.. */
extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
@@ -141,7 +142,7 @@ static inline unsigned long native_read_cr4_safe(void)
{
unsigned long val;
/* This could fault if %cr4 does not exist */
- asm("1: movl %%cr4, %0 \n"
+ asm volatile("1: movl %%cr4, %0 \n"
"2: \n"
".section __ex_table,\"a\" \n"
".long 1b,2b \n"
@@ -160,6 +161,10 @@ static inline void native_wbinvd(void)
asm volatile("wbinvd": : :"memory");
}
+static inline void clflush(volatile void *__p)
+{
+ asm volatile("clflush %0" : "+m" (*(char __force *)__p));
+}
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
diff --git a/include/asm-x86/system_64.h b/include/asm-x86/system_64.h
index 5022aecc333..4cb23848d46 100644
--- a/include/asm-x86/system_64.h
+++ b/include/asm-x86/system_64.h
@@ -7,9 +7,6 @@
#ifdef __KERNEL__
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
#define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
#define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
@@ -85,7 +82,7 @@ static inline void write_cr0(unsigned long val)
static inline unsigned long read_cr2(void)
{
unsigned long cr2;
- asm("movq %%cr2,%0" : "=r" (cr2));
+ asm volatile("movq %%cr2,%0" : "=r" (cr2));
return cr2;
}
@@ -97,7 +94,7 @@ static inline void write_cr2(unsigned long val)
static inline unsigned long read_cr3(void)
{
unsigned long cr3;
- asm("movq %%cr3,%0" : "=r" (cr3));
+ asm volatile("movq %%cr3,%0" : "=r" (cr3));
return cr3;
}
@@ -109,7 +106,7 @@ static inline void write_cr3(unsigned long val)
static inline unsigned long read_cr4(void)
{
unsigned long cr4;
- asm("movq %%cr4,%0" : "=r" (cr4));
+ asm volatile("movq %%cr4,%0" : "=r" (cr4));
return cr4;
}
@@ -121,7 +118,7 @@ static inline void write_cr4(unsigned long val)
static inline unsigned long read_cr8(void)
{
unsigned long cr8;
- asm("movq %%cr8,%0" : "=r" (cr8));
+ asm volatile("movq %%cr8,%0" : "=r" (cr8));
return cr8;
}
@@ -137,6 +134,11 @@ static inline void write_cr8(unsigned long val)
#endif /* __KERNEL__ */
+static inline void clflush(volatile void *__p)
+{
+ asm volatile("clflush %0" : "+m" (*(char __force *)__p));
+}
+
#define nop() __asm__ __volatile__ ("nop")
#ifdef CONFIG_SMP
diff --git a/include/asm-x86/termbits.h b/include/asm-x86/termbits.h
index 69f3080e2a1..af1b70ea440 100644
--- a/include/asm-x86/termbits.h
+++ b/include/asm-x86/termbits.h
@@ -1,13 +1,198 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "termbits_32.h"
-# else
-# include "termbits_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "termbits_32.h"
-# else
-# include "termbits_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_TERMBITS_H
+#define _ASM_X86_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define BOTHER 0010000 /* non standard rate */
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000 /* input baud rate */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* _ASM_X86_TERMBITS_H */
diff --git a/include/asm-x86/termbits_32.h b/include/asm-x86/termbits_32.h
deleted file mode 100644
index a21700352e7..00000000000
--- a/include/asm-x86/termbits_32.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef __ARCH_I386_TERMBITS_H__
-#define __ARCH_I386_TERMBITS_H__
-
-#include <linux/posix_types.h>
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
-
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
-};
-
-struct termios2 {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-struct ktermios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-#define IUTF8 0040000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-
-/* c_cflag bit meaning */
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define BOTHER 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define B460800 0010004
-#define B500000 0010005
-#define B576000 0010006
-#define B921600 0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-#define CIBAUD 002003600000
-#define CMSPAR 010000000000 /* mark or space (stick) parity */
-#define CRTSCTS 020000000000 /* flow control */
-
-#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#endif
diff --git a/include/asm-x86/termbits_64.h b/include/asm-x86/termbits_64.h
deleted file mode 100644
index 7405756dd41..00000000000
--- a/include/asm-x86/termbits_64.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef __ARCH_X8664_TERMBITS_H__
-#define __ARCH_X8664_TERMBITS_H__
-
-#include <linux/posix_types.h>
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
-
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
-};
-
-struct termios2 {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-struct ktermios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
- speed_t c_ispeed; /* input speed */
- speed_t c_ospeed; /* output speed */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-#define IUTF8 0040000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-
-/* c_cflag bit meaning */
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define BOTHER 0010000 /* non standard rate */
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define B460800 0010004
-#define B500000 0010005
-#define B576000 0010006
-#define B921600 0010007
-#define B1000000 0010010
-#define B1152000 0010011
-#define B1500000 0010012
-#define B2000000 0010013
-#define B2500000 0010014
-#define B3000000 0010015
-#define B3500000 0010016
-#define B4000000 0010017
-#define CIBAUD 002003600000 /* input baud rate */
-#define CMSPAR 010000000000 /* mark or space (stick) parity */
-#define CRTSCTS 020000000000 /* flow control */
-
-#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-#endif
diff --git a/include/asm-x86/termios.h b/include/asm-x86/termios.h
index a4f4ae20a59..d501748700d 100644
--- a/include/asm-x86/termios.h
+++ b/include/asm-x86/termios.h
@@ -1,13 +1,97 @@
+#ifndef _ASM_X86_TERMIOS_H
+#define _ASM_X86_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "termios_32.h"
-# else
-# include "termios_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "termios_32.h"
-# else
-# include "termios_64.h"
-# endif
-#endif
+
+/* intr=^C quit=^\ erase=del kill=^U
+ eof=^D vtime=\0 vmin=\1 sxtc=\0
+ start=^Q stop=^S susp=^Z eol=\0
+ reprint=^R discard=^U werase=^W lnext=^V
+ eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+ unsigned short __tmp; \
+ get_user(__tmp,&(termio)->x); \
+ *(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+ put_user((termios)->c_iflag, &(termio)->c_iflag); \
+ put_user((termios)->c_oflag, &(termio)->c_oflag); \
+ put_user((termios)->c_cflag, &(termio)->c_cflag); \
+ put_user((termios)->c_lflag, &(termio)->c_lflag); \
+ put_user((termios)->c_line, &(termio)->c_line); \
+ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) \
+ copy_from_user(k, u, sizeof(struct termios2))
+
+#define kernel_termios_to_user_termios(u, k) \
+ copy_to_user(u, k, sizeof(struct termios2))
+
+#define user_termios_to_kernel_termios_1(k, u) \
+ copy_from_user(k, u, sizeof(struct termios))
+
+#define kernel_termios_to_user_termios_1(u, k) \
+ copy_to_user(u, k, sizeof(struct termios))
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_X86_TERMIOS_H */
diff --git a/include/asm-x86/termios_32.h b/include/asm-x86/termios_32.h
deleted file mode 100644
index 6fdb2c841b7..00000000000
--- a/include/asm-x86/termios_32.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _I386_TERMIOS_H
-#define _I386_TERMIOS_H
-
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
-
-/* intr=^C quit=^\ erase=del kill=^U
- eof=^D vtime=\0 vmin=\1 sxtc=\0
- start=^Q stop=^S susp=^Z eol=\0
- reprint=^R discard=^U werase=^W lnext=^V
- eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
- unsigned short __tmp; \
- get_user(__tmp,&(termio)->x); \
- *(unsigned short *) &(termios)->x = __tmp; \
-}
-
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
- SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
- copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-})
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
- put_user((termios)->c_iflag, &(termio)->c_iflag); \
- put_user((termios)->c_oflag, &(termio)->c_oflag); \
- put_user((termios)->c_cflag, &(termio)->c_cflag); \
- put_user((termios)->c_lflag, &(termio)->c_lflag); \
- put_user((termios)->c_line, &(termio)->c_line); \
- copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-})
-
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
-#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
-
-#endif /* __KERNEL__ */
-
-#endif /* _I386_TERMIOS_H */
diff --git a/include/asm-x86/termios_64.h b/include/asm-x86/termios_64.h
deleted file mode 100644
index 35ee59b7832..00000000000
--- a/include/asm-x86/termios_64.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _X8664_TERMIOS_H
-#define _X8664_TERMIOS_H
-
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_OUT1 0x2000
-#define TIOCM_OUT2 0x4000
-#define TIOCM_LOOP 0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
-
-/* intr=^C quit=^\ erase=del kill=^U
- eof=^D vtime=\0 vmin=\1 sxtc=\0
- start=^Q stop=^S susp=^Z eol=\0
- reprint=^R discard=^U werase=^W lnext=^V
- eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
- unsigned short __tmp; \
- get_user(__tmp,&(termio)->x); \
- *(unsigned short *) &(termios)->x = __tmp; \
-}
-
-#define user_termio_to_kernel_termios(termios, termio) \
-({ \
- SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
- SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
- copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-})
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- */
-#define kernel_termios_to_user_termio(termio, termios) \
-({ \
- put_user((termios)->c_iflag, &(termio)->c_iflag); \
- put_user((termios)->c_oflag, &(termio)->c_oflag); \
- put_user((termios)->c_cflag, &(termio)->c_cflag); \
- put_user((termios)->c_lflag, &(termio)->c_lflag); \
- put_user((termios)->c_line, &(termio)->c_line); \
- copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
-})
-
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
-#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
-
-#endif /* __KERNEL__ */
-
-#endif /* _X8664_TERMIOS_H */
diff --git a/include/asm-x86/tlb.h b/include/asm-x86/tlb.h
index 7d55c3762b4..e4e9e2d07a9 100644
--- a/include/asm-x86/tlb.h
+++ b/include/asm-x86/tlb.h
@@ -1,5 +1,11 @@
-#ifdef CONFIG_X86_32
-# include "tlb_32.h"
-#else
-# include "tlb_64.h"
+#ifndef _ASM_X86_TLB_H
+#define _ASM_X86_TLB_H
+
+#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)
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
#endif
diff --git a/include/asm-x86/tlb_32.h b/include/asm-x86/tlb_32.h
deleted file mode 100644
index c006c5c92be..00000000000
--- a/include/asm-x86/tlb_32.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _I386_TLB_H
-#define _I386_TLB_H
-
-/*
- * x86 doesn't need any special per-pte or
- * per-vma handling..
- */
-#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)
-
-/*
- * .. because we flush the whole mm when it
- * fills up.
- */
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
-#include <asm-generic/tlb.h>
-
-#endif
diff --git a/include/asm-x86/tlb_64.h b/include/asm-x86/tlb_64.h
deleted file mode 100644
index cd4c3c590a0..00000000000
--- a/include/asm-x86/tlb_64.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef TLB_H
-#define TLB_H 1
-
-
-#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)
-
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
-
-#include <asm-generic/tlb.h>
-
-#endif
diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h
index 19b2dafd0c8..ae1074603c4 100644
--- a/include/asm-x86/topology_32.h
+++ b/include/asm-x86/topology_32.h
@@ -30,8 +30,8 @@
#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_core_siblings(cpu) (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
+#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#endif
#ifdef CONFIG_NUMA
diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h
index 36e52fba796..848c17f9222 100644
--- a/include/asm-x86/topology_64.h
+++ b/include/asm-x86/topology_64.h
@@ -58,8 +58,8 @@ extern int __node_distance(int, int);
#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_core_siblings(cpu) (cpu_core_map[cpu])
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#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)
#define smt_capable() (smp_num_siblings > 1)
#endif
diff --git a/include/asm-x86/types.h b/include/asm-x86/types.h
index a777a9b8397..63733f31568 100644
--- a/include/asm-x86/types.h
+++ b/include/asm-x86/types.h
@@ -1,13 +1,70 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "types_32.h"
-# else
-# include "types_64.h"
+#ifndef _ASM_X86_TYPES_H
+#define _ASM_X86_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#ifdef __i386__
+# ifdef __GNUC__
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
# endif
#else
-# ifdef __i386__
-# include "types_32.h"
-# else
-# include "types_64.h"
-# endif
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#ifdef CONFIG_X86_32
+# define BITS_PER_LONG 32
+#else
+# define BITS_PER_LONG 64
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+typedef u64 dma64_addr_t;
+#if defined(CONFIG_X86_64) || defined(CONFIG_HIGHMEM64G)
+/* DMA addresses come in 32-bit and 64-bit flavours. */
+typedef u64 dma_addr_t;
+#else
+typedef u32 dma_addr_t;
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
#endif
diff --git a/include/asm-x86/types_32.h b/include/asm-x86/types_32.h
deleted file mode 100644
index ad0a55bd782..00000000000
--- a/include/asm-x86/types_32.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _I386_TYPES_H
-#define _I386_TYPES_H
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
-
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#ifdef __KERNEL__
-
-#define BITS_PER_LONG 32
-
-#ifndef __ASSEMBLY__
-
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-/* DMA addresses come in generic and 64-bit flavours. */
-
-#ifdef CONFIG_HIGHMEM64G
-typedef u64 dma_addr_t;
-#else
-typedef u32 dma_addr_t;
-#endif
-typedef u64 dma64_addr_t;
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/include/asm-x86/types_64.h b/include/asm-x86/types_64.h
deleted file mode 100644
index 2d4491aae28..00000000000
--- a/include/asm-x86/types_64.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _X86_64_TYPES_H
-#define _X86_64_TYPES_H
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
-
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#ifdef __KERNEL__
-
-#define BITS_PER_LONG 64
-
-#ifndef __ASSEMBLY__
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-typedef u64 dma64_addr_t;
-typedef u64 dma_addr_t;
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/include/asm-x86/ucontext.h b/include/asm-x86/ucontext.h
index 175c8cb5973..50a79f7fcde 100644
--- a/include/asm-x86/ucontext.h
+++ b/include/asm-x86/ucontext.h
@@ -1,13 +1,12 @@
-#ifdef __KERNEL__
-# ifdef CONFIG_X86_32
-# include "ucontext_32.h"
-# else
-# include "ucontext_64.h"
-# endif
-#else
-# ifdef __i386__
-# include "ucontext_32.h"
-# else
-# include "ucontext_64.h"
-# endif
-#endif
+#ifndef _ASM_X86_UCONTEXT_H
+#define _ASM_X86_UCONTEXT_H
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+#endif /* _ASM_X86_UCONTEXT_H */
diff --git a/include/asm-x86/ucontext_32.h b/include/asm-x86/ucontext_32.h
deleted file mode 100644
index b0db36925f5..00000000000
--- a/include/asm-x86/ucontext_32.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASMi386_UCONTEXT_H
-#define _ASMi386_UCONTEXT_H
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct sigcontext uc_mcontext;
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif /* !_ASMi386_UCONTEXT_H */
diff --git a/include/asm-x86/ucontext_64.h b/include/asm-x86/ucontext_64.h
deleted file mode 100644
index 159a3da9e11..00000000000
--- a/include/asm-x86/ucontext_64.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASMX8664_UCONTEXT_H
-#define _ASMX8664_UCONTEXT_H
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct sigcontext uc_mcontext;
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif
diff --git a/include/asm-x86/unaligned.h b/include/asm-x86/unaligned.h
index 68067150fbc..913598d4f76 100644
--- a/include/asm-x86/unaligned.h
+++ b/include/asm-x86/unaligned.h
@@ -1,5 +1,37 @@
-#ifdef CONFIG_X86_32
-# include "unaligned_32.h"
-#else
-# include "unaligned_64.h"
-#endif
+#ifndef _ASM_X86_UNALIGNED_H
+#define _ASM_X86_UNALIGNED_H
+
+/*
+ * The x86 can do unaligned accesses itself.
+ *
+ * The strange macros are there to make sure these can't
+ * be misused in a way that makes them not work on other
+ * architectures where unaligned accesses aren't as simple.
+ */
+
+/**
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. retrieving a u16 value from a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define get_unaligned(ptr) (*(ptr))
+
+/**
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+
+#endif /* _ASM_X86_UNALIGNED_H */
diff --git a/include/asm-x86/unaligned_32.h b/include/asm-x86/unaligned_32.h
deleted file mode 100644
index 7acd7957621..00000000000
--- a/include/asm-x86/unaligned_32.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __I386_UNALIGNED_H
-#define __I386_UNALIGNED_H
-
-/*
- * The i386 can do unaligned accesses itself.
- *
- * The strange macros are there to make sure these can't
- * be misused in a way that makes them not work on other
- * architectures where unaligned accesses aren't as simple.
- */
-
-/**
- * get_unaligned - get value from possibly mis-aligned location
- * @ptr: pointer to value
- *
- * This macro should be used for accessing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. retrieving a u16 value from a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define get_unaligned(ptr) (*(ptr))
-
-/**
- * put_unaligned - put value to a possibly mis-aligned location
- * @val: value to place
- * @ptr: pointer to location
- *
- * This macro should be used for placing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. writing a u16 value to a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
-
-#endif
diff --git a/include/asm-x86/unaligned_64.h b/include/asm-x86/unaligned_64.h
deleted file mode 100644
index d4bf78dc6f3..00000000000
--- a/include/asm-x86/unaligned_64.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __X8664_UNALIGNED_H
-#define __X8664_UNALIGNED_H
-
-/*
- * The x86-64 can do unaligned accesses itself.
- *
- * The strange macros are there to make sure these can't
- * be misused in a way that makes them not work on other
- * architectures where unaligned accesses aren't as simple.
- */
-
-/**
- * get_unaligned - get value from possibly mis-aligned location
- * @ptr: pointer to value
- *
- * This macro should be used for accessing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. retrieving a u16 value from a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define get_unaligned(ptr) (*(ptr))
-
-/**
- * put_unaligned - put value to a possibly mis-aligned location
- * @val: value to place
- * @ptr: pointer to location
- *
- * This macro should be used for placing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. writing a u16 value to a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
-
-#endif
diff --git a/include/asm-x86/unistd_64.h b/include/asm-x86/unistd_64.h
index fc4e73f5f1f..5ff4d3e24c3 100644
--- a/include/asm-x86/unistd_64.h
+++ b/include/asm-x86/unistd_64.h
@@ -2,635 +2,638 @@
#define _ASM_X86_64_UNISTD_H_
#ifndef __SYSCALL
-#define __SYSCALL(a,b)
+#define __SYSCALL(a,b)
#endif
/*
* This file contains the system call numbers.
- *
+ *
* Note: holes are not allowed.
*/
/* at least 8 syscall per cacheline */
-#define __NR_read 0
+#define __NR_read 0
__SYSCALL(__NR_read, sys_read)
-#define __NR_write 1
+#define __NR_write 1
__SYSCALL(__NR_write, sys_write)
-#define __NR_open 2
+#define __NR_open 2
__SYSCALL(__NR_open, sys_open)
-#define __NR_close 3
+#define __NR_close 3
__SYSCALL(__NR_close, sys_close)
-#define __NR_stat 4
+#define __NR_stat 4
__SYSCALL(__NR_stat, sys_newstat)
-#define __NR_fstat 5
+#define __NR_fstat 5
__SYSCALL(__NR_fstat, sys_newfstat)
-#define __NR_lstat 6
+#define __NR_lstat 6
__SYSCALL(__NR_lstat, sys_newlstat)
-#define __NR_poll 7
+#define __NR_poll 7
__SYSCALL(__NR_poll, sys_poll)
-#define __NR_lseek 8
+#define __NR_lseek 8
__SYSCALL(__NR_lseek, sys_lseek)
-#define __NR_mmap 9
+#define __NR_mmap 9
__SYSCALL(__NR_mmap, sys_mmap)
-#define __NR_mprotect 10
+#define __NR_mprotect 10
__SYSCALL(__NR_mprotect, sys_mprotect)
-#define __NR_munmap 11
+#define __NR_munmap 11
__SYSCALL(__NR_munmap, sys_munmap)
-#define __NR_brk 12
+#define __NR_brk 12
__SYSCALL(__NR_brk, sys_brk)
-#define __NR_rt_sigaction 13
+#define __NR_rt_sigaction 13
__SYSCALL(__NR_rt_sigaction, sys_rt_sigaction)
-#define __NR_rt_sigprocmask 14
+#define __NR_rt_sigprocmask 14
__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
-#define __NR_rt_sigreturn 15
+#define __NR_rt_sigreturn 15
__SYSCALL(__NR_rt_sigreturn, stub_rt_sigreturn)
-#define __NR_ioctl 16
+#define __NR_ioctl 16
__SYSCALL(__NR_ioctl, sys_ioctl)
-#define __NR_pread64 17
+#define __NR_pread64 17
__SYSCALL(__NR_pread64, sys_pread64)
-#define __NR_pwrite64 18
+#define __NR_pwrite64 18
__SYSCALL(__NR_pwrite64, sys_pwrite64)
-#define __NR_readv 19
+#define __NR_readv 19
__SYSCALL(__NR_readv, sys_readv)
-#define __NR_writev 20
+#define __NR_writev 20
__SYSCALL(__NR_writev, sys_writev)
-#define __NR_access 21
+#define __NR_access 21
__SYSCALL(__NR_access, sys_access)
-#define __NR_pipe 22
+#define __NR_pipe 22
__SYSCALL(__NR_pipe, sys_pipe)
-#define __NR_select 23
+#define __NR_select 23
__SYSCALL(__NR_select, sys_select)
-#define __NR_sched_yield 24
+#define __NR_sched_yield 24
__SYSCALL(__NR_sched_yield, sys_sched_yield)
-#define __NR_mremap 25
+#define __NR_mremap 25
__SYSCALL(__NR_mremap, sys_mremap)
-#define __NR_msync 26
+#define __NR_msync 26
__SYSCALL(__NR_msync, sys_msync)
-#define __NR_mincore 27
+#define __NR_mincore 27
__SYSCALL(__NR_mincore, sys_mincore)
-#define __NR_madvise 28
+#define __NR_madvise 28
__SYSCALL(__NR_madvise, sys_madvise)
-#define __NR_shmget 29
+#define __NR_shmget 29
__SYSCALL(__NR_shmget, sys_shmget)
-#define __NR_shmat 30
+#define __NR_shmat 30
__SYSCALL(__NR_shmat, sys_shmat)
-#define __NR_shmctl 31
+#define __NR_shmctl 31
__SYSCALL(__NR_shmctl, sys_shmctl)
-#define __NR_dup 32
+#define __NR_dup 32
__SYSCALL(__NR_dup, sys_dup)
-#define __NR_dup2 33
+#define __NR_dup2 33
__SYSCALL(__NR_dup2, sys_dup2)
-#define __NR_pause 34
+#define __NR_pause 34
__SYSCALL(__NR_pause, sys_pause)
-#define __NR_nanosleep 35
+#define __NR_nanosleep 35
__SYSCALL(__NR_nanosleep, sys_nanosleep)
-#define __NR_getitimer 36
+#define __NR_getitimer 36
__SYSCALL(__NR_getitimer, sys_getitimer)
-#define __NR_alarm 37
+#define __NR_alarm 37
__SYSCALL(__NR_alarm, sys_alarm)
-#define __NR_setitimer 38
+#define __NR_setitimer 38
__SYSCALL(__NR_setitimer, sys_setitimer)
-#define __NR_getpid 39
+#define __NR_getpid 39
__SYSCALL(__NR_getpid, sys_getpid)
-#define __NR_sendfile 40
+#define __NR_sendfile 40
__SYSCALL(__NR_sendfile, sys_sendfile64)
-#define __NR_socket 41
+#define __NR_socket 41
__SYSCALL(__NR_socket, sys_socket)
-#define __NR_connect 42
+#define __NR_connect 42
__SYSCALL(__NR_connect, sys_connect)
-#define __NR_accept 43
+#define __NR_accept 43
__SYSCALL(__NR_accept, sys_accept)
-#define __NR_sendto 44
+#define __NR_sendto 44
__SYSCALL(__NR_sendto, sys_sendto)
-#define __NR_recvfrom 45
+#define __NR_recvfrom 45
__SYSCALL(__NR_recvfrom, sys_recvfrom)
-#define __NR_sendmsg 46
+#define __NR_sendmsg 46
__SYSCALL(__NR_sendmsg, sys_sendmsg)
-#define __NR_recvmsg 47
+#define __NR_recvmsg 47
__SYSCALL(__NR_recvmsg, sys_recvmsg)
-#define __NR_shutdown 48
+#define __NR_shutdown 48
__SYSCALL(__NR_shutdown, sys_shutdown)
-#define __NR_bind 49
+#define __NR_bind 49
__SYSCALL(__NR_bind, sys_bind)
-#define __NR_listen 50
+#define __NR_listen 50
__SYSCALL(__NR_listen, sys_listen)
-#define __NR_getsockname 51
+#define __NR_getsockname 51
__SYSCALL(__NR_getsockname, sys_getsockname)
-#define __NR_getpeername 52
+#define __NR_getpeername 52
__SYSCALL(__NR_getpeername, sys_getpeername)
-#define __NR_socketpair 53
+#define __NR_socketpair 53
__SYSCALL(__NR_socketpair, sys_socketpair)
-#define __NR_setsockopt 54
+#define __NR_setsockopt 54
__SYSCALL(__NR_setsockopt, sys_setsockopt)
-#define __NR_getsockopt 55
+#define __NR_getsockopt 55
__SYSCALL(__NR_getsockopt, sys_getsockopt)
-#define __NR_clone 56
+#define __NR_clone 56
__SYSCALL(__NR_clone, stub_clone)
-#define __NR_fork 57
-__SYSCALL(__NR_fork, stub_fork)
-#define __NR_vfork 58
+#define __NR_fork 57
+__SYSCALL(__NR_fork, stub_fork)
+#define __NR_vfork 58
__SYSCALL(__NR_vfork, stub_vfork)
-#define __NR_execve 59
+#define __NR_execve 59
__SYSCALL(__NR_execve, stub_execve)
-#define __NR_exit 60
+#define __NR_exit 60
__SYSCALL(__NR_exit, sys_exit)
-#define __NR_wait4 61
+#define __NR_wait4 61
__SYSCALL(__NR_wait4, sys_wait4)
-#define __NR_kill 62
+#define __NR_kill 62
__SYSCALL(__NR_kill, sys_kill)
-#define __NR_uname 63
+#define __NR_uname 63
__SYSCALL(__NR_uname, sys_uname)
-#define __NR_semget 64
+#define __NR_semget 64
__SYSCALL(__NR_semget, sys_semget)
-#define __NR_semop 65
+#define __NR_semop 65
__SYSCALL(__NR_semop, sys_semop)
-#define __NR_semctl 66
+#define __NR_semctl 66
__SYSCALL(__NR_semctl, sys_semctl)
-#define __NR_shmdt 67
+#define __NR_shmdt 67
__SYSCALL(__NR_shmdt, sys_shmdt)
-#define __NR_msgget 68
+#define __NR_msgget 68
__SYSCALL(__NR_msgget, sys_msgget)
-#define __NR_msgsnd 69
+#define __NR_msgsnd 69
__SYSCALL(__NR_msgsnd, sys_msgsnd)
-#define __NR_msgrcv 70
+#define __NR_msgrcv 70
__SYSCALL(__NR_msgrcv, sys_msgrcv)
-#define __NR_msgctl 71
+#define __NR_msgctl 71
__SYSCALL(__NR_msgctl, sys_msgctl)
-#define __NR_fcntl 72
+#define __NR_fcntl 72
__SYSCALL(__NR_fcntl, sys_fcntl)
-#define __NR_flock 73
+#define __NR_flock 73
__SYSCALL(__NR_flock, sys_flock)
-#define __NR_fsync 74
+#define __NR_fsync 74
__SYSCALL(__NR_fsync, sys_fsync)
-#define __NR_fdatasync 75
+#define __NR_fdatasync 75
__SYSCALL(__NR_fdatasync, sys_fdatasync)
-#define __NR_truncate 76
+#define __NR_truncate 76
__SYSCALL(__NR_truncate, sys_truncate)
-#define __NR_ftruncate 77
+#define __NR_ftruncate 77
__SYSCALL(__NR_ftruncate, sys_ftruncate)
-#define __NR_getdents 78
+#define __NR_getdents 78
__SYSCALL(__NR_getdents, sys_getdents)
-#define __NR_getcwd 79
+#define __NR_getcwd 79
__SYSCALL(__NR_getcwd, sys_getcwd)
-#define __NR_chdir 80
+#define __NR_chdir 80
__SYSCALL(__NR_chdir, sys_chdir)
-#define __NR_fchdir 81
+#define __NR_fchdir 81
__SYSCALL(__NR_fchdir, sys_fchdir)
-#define __NR_rename 82
+#define __NR_rename 82
__SYSCALL(__NR_rename, sys_rename)
-#define __NR_mkdir 83
+#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
-#define __NR_rmdir 84
+#define __NR_rmdir 84
__SYSCALL(__NR_rmdir, sys_rmdir)
-#define __NR_creat 85
+#define __NR_creat 85
__SYSCALL(__NR_creat, sys_creat)
-#define __NR_link 86
+#define __NR_link 86
__SYSCALL(__NR_link, sys_link)
-#define __NR_unlink 87
+#define __NR_unlink 87
__SYSCALL(__NR_unlink, sys_unlink)
-#define __NR_symlink 88
+#define __NR_symlink 88
__SYSCALL(__NR_symlink, sys_symlink)
-#define __NR_readlink 89
+#define __NR_readlink 89
__SYSCALL(__NR_readlink, sys_readlink)
-#define __NR_chmod 90
+#define __NR_chmod 90
__SYSCALL(__NR_chmod, sys_chmod)
-#define __NR_fchmod 91
+#define __NR_fchmod 91
__SYSCALL(__NR_fchmod, sys_fchmod)
-#define __NR_chown 92
+#define __NR_chown 92
__SYSCALL(__NR_chown, sys_chown)
-#define __NR_fchown 93
+#define __NR_fchown 93
__SYSCALL(__NR_fchown, sys_fchown)
-#define __NR_lchown 94
+#define __NR_lchown 94
__SYSCALL(__NR_lchown, sys_lchown)
-#define __NR_umask 95
+#define __NR_umask 95
__SYSCALL(__NR_umask, sys_umask)
-#define __NR_gettimeofday 96
+#define __NR_gettimeofday 96
__SYSCALL(__NR_gettimeofday, sys_gettimeofday)
-#define __NR_getrlimit 97
+#define __NR_getrlimit 97
__SYSCALL(__NR_getrlimit, sys_getrlimit)
-#define __NR_getrusage 98
+#define __NR_getrusage 98
__SYSCALL(__NR_getrusage, sys_getrusage)
-#define __NR_sysinfo 99
+#define __NR_sysinfo 99
__SYSCALL(__NR_sysinfo, sys_sysinfo)
-#define __NR_times 100
+#define __NR_times 100
__SYSCALL(__NR_times, sys_times)
-#define __NR_ptrace 101
+#define __NR_ptrace 101
__SYSCALL(__NR_ptrace, sys_ptrace)
-#define __NR_getuid 102
+#define __NR_getuid 102
__SYSCALL(__NR_getuid, sys_getuid)
-#define __NR_syslog 103
+#define __NR_syslog 103
__SYSCALL(__NR_syslog, sys_syslog)
/* at the very end the stuff that never runs during the benchmarks */
-#define __NR_getgid 104
+#define __NR_getgid 104
__SYSCALL(__NR_getgid, sys_getgid)
-#define __NR_setuid 105
+#define __NR_setuid 105
__SYSCALL(__NR_setuid, sys_setuid)
-#define __NR_setgid 106
+#define __NR_setgid 106
__SYSCALL(__NR_setgid, sys_setgid)
-#define __NR_geteuid 107
+#define __NR_geteuid 107
__SYSCALL(__NR_geteuid, sys_geteuid)
-#define __NR_getegid 108
+#define __NR_getegid 108
__SYSCALL(__NR_getegid, sys_getegid)
-#define __NR_setpgid 109
+#define __NR_setpgid 109
__SYSCALL(__NR_setpgid, sys_setpgid)
-#define __NR_getppid 110
+#define __NR_getppid 110
__SYSCALL(__NR_getppid, sys_getppid)
-#define __NR_getpgrp 111
+#define __NR_getpgrp 111
__SYSCALL(__NR_getpgrp, sys_getpgrp)
-#define __NR_setsid 112
+#define __NR_setsid 112
__SYSCALL(__NR_setsid, sys_setsid)
-#define __NR_setreuid 113
+#define __NR_setreuid 113
__SYSCALL(__NR_setreuid, sys_setreuid)
-#define __NR_setregid 114
+#define __NR_setregid 114
__SYSCALL(__NR_setregid, sys_setregid)
-#define __NR_getgroups 115
+#define __NR_getgroups 115
__SYSCALL(__NR_getgroups, sys_getgroups)
-#define __NR_setgroups 116
+#define __NR_setgroups 116
__SYSCALL(__NR_setgroups, sys_setgroups)
-#define __NR_setresuid 117
+#define __NR_setresuid 117
__SYSCALL(__NR_setresuid, sys_setresuid)
-#define __NR_getresuid 118
+#define __NR_getresuid 118
__SYSCALL(__NR_getresuid, sys_getresuid)
-#define __NR_setresgid 119
+#define __NR_setresgid 119
__SYSCALL(__NR_setresgid, sys_setresgid)
-#define __NR_getresgid 120
+#define __NR_getresgid 120
__SYSCALL(__NR_getresgid, sys_getresgid)
-#define __NR_getpgid 121
+#define __NR_getpgid 121
__SYSCALL(__NR_getpgid, sys_getpgid)
-#define __NR_setfsuid 122
+#define __NR_setfsuid 122
__SYSCALL(__NR_setfsuid, sys_setfsuid)
-#define __NR_setfsgid 123
+#define __NR_setfsgid 123
__SYSCALL(__NR_setfsgid, sys_setfsgid)
-#define __NR_getsid 124
+#define __NR_getsid 124
__SYSCALL(__NR_getsid, sys_getsid)
-#define __NR_capget 125
+#define __NR_capget 125
__SYSCALL(__NR_capget, sys_capget)
-#define __NR_capset 126
+#define __NR_capset 126
__SYSCALL(__NR_capset, sys_capset)
-#define __NR_rt_sigpending 127
+#define __NR_rt_sigpending 127
__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
-#define __NR_rt_sigtimedwait 128
+#define __NR_rt_sigtimedwait 128
__SYSCALL(__NR_rt_sigtimedwait, sys_rt_sigtimedwait)
-#define __NR_rt_sigqueueinfo 129
+#define __NR_rt_sigqueueinfo 129
__SYSCALL(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo)
-#define __NR_rt_sigsuspend 130
+#define __NR_rt_sigsuspend 130
__SYSCALL(__NR_rt_sigsuspend, stub_rt_sigsuspend)
-#define __NR_sigaltstack 131
+#define __NR_sigaltstack 131
__SYSCALL(__NR_sigaltstack, stub_sigaltstack)
-#define __NR_utime 132
+#define __NR_utime 132
__SYSCALL(__NR_utime, sys_utime)
-#define __NR_mknod 133
+#define __NR_mknod 133
__SYSCALL(__NR_mknod, sys_mknod)
/* Only needed for a.out */
-#define __NR_uselib 134
+#define __NR_uselib 134
__SYSCALL(__NR_uselib, sys_ni_syscall)
-#define __NR_personality 135
+#define __NR_personality 135
__SYSCALL(__NR_personality, sys_personality)
-#define __NR_ustat 136
+#define __NR_ustat 136
__SYSCALL(__NR_ustat, sys_ustat)
-#define __NR_statfs 137
+#define __NR_statfs 137
__SYSCALL(__NR_statfs, sys_statfs)
-#define __NR_fstatfs 138
+#define __NR_fstatfs 138
__SYSCALL(__NR_fstatfs, sys_fstatfs)
-#define __NR_sysfs 139
+#define __NR_sysfs 139
__SYSCALL(__NR_sysfs, sys_sysfs)
-#define __NR_getpriority 140
+#define __NR_getpriority 140
__SYSCALL(__NR_getpriority, sys_getpriority)
-#define __NR_setpriority 141
+#define __NR_setpriority 141
__SYSCALL(__NR_setpriority, sys_setpriority)
-#define __NR_sched_setparam 142
+#define __NR_sched_setparam 142
__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
-#define __NR_sched_getparam 143
+#define __NR_sched_getparam 143
__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
-#define __NR_sched_setscheduler 144
+#define __NR_sched_setscheduler 144
__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
-#define __NR_sched_getscheduler 145
+#define __NR_sched_getscheduler 145
__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
-#define __NR_sched_get_priority_max 146
+#define __NR_sched_get_priority_max 146
__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
-#define __NR_sched_get_priority_min 147
+#define __NR_sched_get_priority_min 147
__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
-#define __NR_sched_rr_get_interval 148
+#define __NR_sched_rr_get_interval 148
__SYSCALL(__NR_sched_rr_get_interval, sys_sched_rr_get_interval)
-#define __NR_mlock 149
+#define __NR_mlock 149
__SYSCALL(__NR_mlock, sys_mlock)
-#define __NR_munlock 150
+#define __NR_munlock 150
__SYSCALL(__NR_munlock, sys_munlock)
-#define __NR_mlockall 151
+#define __NR_mlockall 151
__SYSCALL(__NR_mlockall, sys_mlockall)
-#define __NR_munlockall 152
+#define __NR_munlockall 152
__SYSCALL(__NR_munlockall, sys_munlockall)
-#define __NR_vhangup 153
+#define __NR_vhangup 153
__SYSCALL(__NR_vhangup, sys_vhangup)
-#define __NR_modify_ldt 154
+#define __NR_modify_ldt 154
__SYSCALL(__NR_modify_ldt, sys_modify_ldt)
-#define __NR_pivot_root 155
+#define __NR_pivot_root 155
__SYSCALL(__NR_pivot_root, sys_pivot_root)
-#define __NR__sysctl 156
+#define __NR__sysctl 156
__SYSCALL(__NR__sysctl, sys_sysctl)
-#define __NR_prctl 157
+#define __NR_prctl 157
__SYSCALL(__NR_prctl, sys_prctl)
-#define __NR_arch_prctl 158
-__SYSCALL(__NR_arch_prctl, sys_arch_prctl)
+#define __NR_arch_prctl 158
+__SYSCALL(__NR_arch_prctl, sys_arch_prctl)
-#define __NR_adjtimex 159
+#define __NR_adjtimex 159
__SYSCALL(__NR_adjtimex, sys_adjtimex)
-#define __NR_setrlimit 160
+#define __NR_setrlimit 160
__SYSCALL(__NR_setrlimit, sys_setrlimit)
-#define __NR_chroot 161
+#define __NR_chroot 161
__SYSCALL(__NR_chroot, sys_chroot)
-#define __NR_sync 162
+#define __NR_sync 162
__SYSCALL(__NR_sync, sys_sync)
-#define __NR_acct 163
+#define __NR_acct 163
__SYSCALL(__NR_acct, sys_acct)
-#define __NR_settimeofday 164
+#define __NR_settimeofday 164
__SYSCALL(__NR_settimeofday, sys_settimeofday)
-#define __NR_mount 165
+#define __NR_mount 165
__SYSCALL(__NR_mount, sys_mount)
-#define __NR_umount2 166
+#define __NR_umount2 166
__SYSCALL(__NR_umount2, sys_umount)
-#define __NR_swapon 167
+#define __NR_swapon 167
__SYSCALL(__NR_swapon, sys_swapon)
-#define __NR_swapoff 168
+#define __NR_swapoff 168
__SYSCALL(__NR_swapoff, sys_swapoff)
-#define __NR_reboot 169
+#define __NR_reboot 169
__SYSCALL(__NR_reboot, sys_reboot)
-#define __NR_sethostname 170
+#define __NR_sethostname 170
__SYSCALL(__NR_sethostname, sys_sethostname)
-#define __NR_setdomainname 171
+#define __NR_setdomainname 171
__SYSCALL(__NR_setdomainname, sys_setdomainname)
-#define __NR_iopl 172
+#define __NR_iopl 172
__SYSCALL(__NR_iopl, stub_iopl)
-#define __NR_ioperm 173
+#define __NR_ioperm 173
__SYSCALL(__NR_ioperm, sys_ioperm)
-#define __NR_create_module 174
+#define __NR_create_module 174
__SYSCALL(__NR_create_module, sys_ni_syscall)
-#define __NR_init_module 175
+#define __NR_init_module 175
__SYSCALL(__NR_init_module, sys_init_module)
-#define __NR_delete_module 176
+#define __NR_delete_module 176
__SYSCALL(__NR_delete_module, sys_delete_module)
-#define __NR_get_kernel_syms 177
+#define __NR_get_kernel_syms 177
__SYSCALL(__NR_get_kernel_syms, sys_ni_syscall)
-#define __NR_query_module 178
+#define __NR_query_module 178
__SYSCALL(__NR_query_module, sys_ni_syscall)
-#define __NR_quotactl 179
+#define __NR_quotactl 179
__SYSCALL(__NR_quotactl, sys_quotactl)
-#define __NR_nfsservctl 180
+#define __NR_nfsservctl 180
__SYSCALL(__NR_nfsservctl, sys_nfsservctl)
-#define __NR_getpmsg 181 /* reserved for LiS/STREAMS */
+/* reserved for LiS/STREAMS */
+#define __NR_getpmsg 181
__SYSCALL(__NR_getpmsg, sys_ni_syscall)
-#define __NR_putpmsg 182 /* reserved for LiS/STREAMS */
+#define __NR_putpmsg 182
__SYSCALL(__NR_putpmsg, sys_ni_syscall)
-#define __NR_afs_syscall 183 /* reserved for AFS */
+/* reserved for AFS */
+#define __NR_afs_syscall 183
__SYSCALL(__NR_afs_syscall, sys_ni_syscall)
-#define __NR_tuxcall 184 /* reserved for tux */
+/* reserved for tux */
+#define __NR_tuxcall 184
__SYSCALL(__NR_tuxcall, sys_ni_syscall)
-#define __NR_security 185
+#define __NR_security 185
__SYSCALL(__NR_security, sys_ni_syscall)
-#define __NR_gettid 186
+#define __NR_gettid 186
__SYSCALL(__NR_gettid, sys_gettid)
-#define __NR_readahead 187
+#define __NR_readahead 187
__SYSCALL(__NR_readahead, sys_readahead)
-#define __NR_setxattr 188
+#define __NR_setxattr 188
__SYSCALL(__NR_setxattr, sys_setxattr)
-#define __NR_lsetxattr 189
+#define __NR_lsetxattr 189
__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
-#define __NR_fsetxattr 190
+#define __NR_fsetxattr 190
__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
-#define __NR_getxattr 191
+#define __NR_getxattr 191
__SYSCALL(__NR_getxattr, sys_getxattr)
-#define __NR_lgetxattr 192
+#define __NR_lgetxattr 192
__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
-#define __NR_fgetxattr 193
-__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
-#define __NR_listxattr 194
-__SYSCALL(__NR_listxattr, sys_listxattr)
-#define __NR_llistxattr 195
-__SYSCALL(__NR_llistxattr, sys_llistxattr)
-#define __NR_flistxattr 196
-__SYSCALL(__NR_flistxattr, sys_flistxattr)
-#define __NR_removexattr 197
-__SYSCALL(__NR_removexattr, sys_removexattr)
-#define __NR_lremovexattr 198
-__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
-#define __NR_fremovexattr 199
-__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
-#define __NR_tkill 200
-__SYSCALL(__NR_tkill, sys_tkill)
-#define __NR_time 201
+#define __NR_fgetxattr 193
+__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
+#define __NR_listxattr 194
+__SYSCALL(__NR_listxattr, sys_listxattr)
+#define __NR_llistxattr 195
+__SYSCALL(__NR_llistxattr, sys_llistxattr)
+#define __NR_flistxattr 196
+__SYSCALL(__NR_flistxattr, sys_flistxattr)
+#define __NR_removexattr 197
+__SYSCALL(__NR_removexattr, sys_removexattr)
+#define __NR_lremovexattr 198
+__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
+#define __NR_fremovexattr 199
+__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
+#define __NR_tkill 200
+__SYSCALL(__NR_tkill, sys_tkill)
+#define __NR_time 201
__SYSCALL(__NR_time, sys_time)
-#define __NR_futex 202
+#define __NR_futex 202
__SYSCALL(__NR_futex, sys_futex)
-#define __NR_sched_setaffinity 203
+#define __NR_sched_setaffinity 203
__SYSCALL(__NR_sched_setaffinity, sys_sched_setaffinity)
-#define __NR_sched_getaffinity 204
+#define __NR_sched_getaffinity 204
__SYSCALL(__NR_sched_getaffinity, sys_sched_getaffinity)
-#define __NR_set_thread_area 205
+#define __NR_set_thread_area 205
__SYSCALL(__NR_set_thread_area, sys_ni_syscall) /* use arch_prctl */
-#define __NR_io_setup 206
+#define __NR_io_setup 206
__SYSCALL(__NR_io_setup, sys_io_setup)
-#define __NR_io_destroy 207
+#define __NR_io_destroy 207
__SYSCALL(__NR_io_destroy, sys_io_destroy)
-#define __NR_io_getevents 208
+#define __NR_io_getevents 208
__SYSCALL(__NR_io_getevents, sys_io_getevents)
-#define __NR_io_submit 209
+#define __NR_io_submit 209
__SYSCALL(__NR_io_submit, sys_io_submit)
-#define __NR_io_cancel 210
+#define __NR_io_cancel 210
__SYSCALL(__NR_io_cancel, sys_io_cancel)
-#define __NR_get_thread_area 211
+#define __NR_get_thread_area 211
__SYSCALL(__NR_get_thread_area, sys_ni_syscall) /* use arch_prctl */
-#define __NR_lookup_dcookie 212
+#define __NR_lookup_dcookie 212
__SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie)
-#define __NR_epoll_create 213
+#define __NR_epoll_create 213
__SYSCALL(__NR_epoll_create, sys_epoll_create)
-#define __NR_epoll_ctl_old 214
+#define __NR_epoll_ctl_old 214
__SYSCALL(__NR_epoll_ctl_old, sys_ni_syscall)
-#define __NR_epoll_wait_old 215
+#define __NR_epoll_wait_old 215
__SYSCALL(__NR_epoll_wait_old, sys_ni_syscall)
-#define __NR_remap_file_pages 216
+#define __NR_remap_file_pages 216
__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
-#define __NR_getdents64 217
+#define __NR_getdents64 217
__SYSCALL(__NR_getdents64, sys_getdents64)
-#define __NR_set_tid_address 218
+#define __NR_set_tid_address 218
__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
-#define __NR_restart_syscall 219
+#define __NR_restart_syscall 219
__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
-#define __NR_semtimedop 220
+#define __NR_semtimedop 220
__SYSCALL(__NR_semtimedop, sys_semtimedop)
-#define __NR_fadvise64 221
+#define __NR_fadvise64 221
__SYSCALL(__NR_fadvise64, sys_fadvise64)
-#define __NR_timer_create 222
+#define __NR_timer_create 222
__SYSCALL(__NR_timer_create, sys_timer_create)
-#define __NR_timer_settime 223
+#define __NR_timer_settime 223
__SYSCALL(__NR_timer_settime, sys_timer_settime)
-#define __NR_timer_gettime 224
+#define __NR_timer_gettime 224
__SYSCALL(__NR_timer_gettime, sys_timer_gettime)
-#define __NR_timer_getoverrun 225
+#define __NR_timer_getoverrun 225
__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
-#define __NR_timer_delete 226
+#define __NR_timer_delete 226
__SYSCALL(__NR_timer_delete, sys_timer_delete)
-#define __NR_clock_settime 227
+#define __NR_clock_settime 227
__SYSCALL(__NR_clock_settime, sys_clock_settime)
-#define __NR_clock_gettime 228
+#define __NR_clock_gettime 228
__SYSCALL(__NR_clock_gettime, sys_clock_gettime)
-#define __NR_clock_getres 229
+#define __NR_clock_getres 229
__SYSCALL(__NR_clock_getres, sys_clock_getres)
-#define __NR_clock_nanosleep 230
+#define __NR_clock_nanosleep 230
__SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep)
-#define __NR_exit_group 231
+#define __NR_exit_group 231
__SYSCALL(__NR_exit_group, sys_exit_group)
-#define __NR_epoll_wait 232
+#define __NR_epoll_wait 232
__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
-#define __NR_epoll_ctl 233
+#define __NR_epoll_ctl 233
__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
-#define __NR_tgkill 234
+#define __NR_tgkill 234
__SYSCALL(__NR_tgkill, sys_tgkill)
-#define __NR_utimes 235
+#define __NR_utimes 235
__SYSCALL(__NR_utimes, sys_utimes)
-#define __NR_vserver 236
+#define __NR_vserver 236
__SYSCALL(__NR_vserver, sys_ni_syscall)
-#define __NR_mbind 237
+#define __NR_mbind 237
__SYSCALL(__NR_mbind, sys_mbind)
-#define __NR_set_mempolicy 238
+#define __NR_set_mempolicy 238
__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
-#define __NR_get_mempolicy 239
+#define __NR_get_mempolicy 239
__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
-#define __NR_mq_open 240
+#define __NR_mq_open 240
__SYSCALL(__NR_mq_open, sys_mq_open)
-#define __NR_mq_unlink 241
+#define __NR_mq_unlink 241
__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
-#define __NR_mq_timedsend 242
+#define __NR_mq_timedsend 242
__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend)
-#define __NR_mq_timedreceive 243
+#define __NR_mq_timedreceive 243
__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive)
-#define __NR_mq_notify 244
+#define __NR_mq_notify 244
__SYSCALL(__NR_mq_notify, sys_mq_notify)
-#define __NR_mq_getsetattr 245
+#define __NR_mq_getsetattr 245
__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
-#define __NR_kexec_load 246
+#define __NR_kexec_load 246
__SYSCALL(__NR_kexec_load, sys_kexec_load)
-#define __NR_waitid 247
+#define __NR_waitid 247
__SYSCALL(__NR_waitid, sys_waitid)
-#define __NR_add_key 248
+#define __NR_add_key 248
__SYSCALL(__NR_add_key, sys_add_key)
-#define __NR_request_key 249
+#define __NR_request_key 249
__SYSCALL(__NR_request_key, sys_request_key)
-#define __NR_keyctl 250
+#define __NR_keyctl 250
__SYSCALL(__NR_keyctl, sys_keyctl)
-#define __NR_ioprio_set 251
+#define __NR_ioprio_set 251
__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
-#define __NR_ioprio_get 252
+#define __NR_ioprio_get 252
__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
-#define __NR_inotify_init 253
+#define __NR_inotify_init 253
__SYSCALL(__NR_inotify_init, sys_inotify_init)
-#define __NR_inotify_add_watch 254
+#define __NR_inotify_add_watch 254
__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
-#define __NR_inotify_rm_watch 255
+#define __NR_inotify_rm_watch 255
__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
-#define __NR_migrate_pages 256
+#define __NR_migrate_pages 256
__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
-#define __NR_openat 257
+#define __NR_openat 257
__SYSCALL(__NR_openat, sys_openat)
-#define __NR_mkdirat 258
+#define __NR_mkdirat 258
__SYSCALL(__NR_mkdirat, sys_mkdirat)
-#define __NR_mknodat 259
+#define __NR_mknodat 259
__SYSCALL(__NR_mknodat, sys_mknodat)
-#define __NR_fchownat 260
+#define __NR_fchownat 260
__SYSCALL(__NR_fchownat, sys_fchownat)
-#define __NR_futimesat 261
+#define __NR_futimesat 261
__SYSCALL(__NR_futimesat, sys_futimesat)
-#define __NR_newfstatat 262
+#define __NR_newfstatat 262
__SYSCALL(__NR_newfstatat, sys_newfstatat)
-#define __NR_unlinkat 263
+#define __NR_unlinkat 263
__SYSCALL(__NR_unlinkat, sys_unlinkat)
-#define __NR_renameat 264
+#define __NR_renameat 264
__SYSCALL(__NR_renameat, sys_renameat)
-#define __NR_linkat 265
+#define __NR_linkat 265
__SYSCALL(__NR_linkat, sys_linkat)
-#define __NR_symlinkat 266
+#define __NR_symlinkat 266
__SYSCALL(__NR_symlinkat, sys_symlinkat)
-#define __NR_readlinkat 267
+#define __NR_readlinkat 267
__SYSCALL(__NR_readlinkat, sys_readlinkat)
-#define __NR_fchmodat 268
+#define __NR_fchmodat 268
__SYSCALL(__NR_fchmodat, sys_fchmodat)
-#define __NR_faccessat 269
+#define __NR_faccessat 269
__SYSCALL(__NR_faccessat, sys_faccessat)
-#define __NR_pselect6 270
+#define __NR_pselect6 270
__SYSCALL(__NR_pselect6, sys_pselect6)
-#define __NR_ppoll 271
+#define __NR_ppoll 271
__SYSCALL(__NR_ppoll, sys_ppoll)
-#define __NR_unshare 272
+#define __NR_unshare 272
__SYSCALL(__NR_unshare, sys_unshare)
-#define __NR_set_robust_list 273
+#define __NR_set_robust_list 273
__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
-#define __NR_get_robust_list 274
+#define __NR_get_robust_list 274
__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
-#define __NR_splice 275
+#define __NR_splice 275
__SYSCALL(__NR_splice, sys_splice)
-#define __NR_tee 276
+#define __NR_tee 276
__SYSCALL(__NR_tee, sys_tee)
-#define __NR_sync_file_range 277
+#define __NR_sync_file_range 277
__SYSCALL(__NR_sync_file_range, sys_sync_file_range)
-#define __NR_vmsplice 278
+#define __NR_vmsplice 278
__SYSCALL(__NR_vmsplice, sys_vmsplice)
-#define __NR_move_pages 279
+#define __NR_move_pages 279
__SYSCALL(__NR_move_pages, sys_move_pages)
-#define __NR_utimensat 280
+#define __NR_utimensat 280
__SYSCALL(__NR_utimensat, sys_utimensat)
#define __IGNORE_getcpu /* implemented as a vsyscall */
-#define __NR_epoll_pwait 281
+#define __NR_epoll_pwait 281
__SYSCALL(__NR_epoll_pwait, sys_epoll_pwait)
-#define __NR_signalfd 282
+#define __NR_signalfd 282
__SYSCALL(__NR_signalfd, sys_signalfd)
-#define __NR_timerfd 283
+#define __NR_timerfd 283
__SYSCALL(__NR_timerfd, sys_timerfd)
-#define __NR_eventfd 284
+#define __NR_eventfd 284
__SYSCALL(__NR_eventfd, sys_eventfd)
-#define __NR_fallocate 285
+#define __NR_fallocate 285
__SYSCALL(__NR_fallocate, sys_fallocate)
#ifndef __NO_STUBS
@@ -656,26 +659,9 @@ __SYSCALL(__NR_fallocate, sys_fallocate)
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_TIME
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-
-#include <linux/linkage.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <asm/ptrace.h>
-
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs);
-struct sigaction;
-asmlinkage long sys_rt_sigaction(int sig,
- const struct sigaction __user *act,
- struct sigaction __user *oact,
- size_t sigsetsize);
-
-#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* __NO_STUBS */
+#ifdef __KERNEL__
/*
* "Conditional" syscalls
*
@@ -683,5 +669,6 @@ asmlinkage long sys_rt_sigaction(int sig,
* but it doesn't work on all toolchains, so we just do it by hand
*/
#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+#endif /* __KERNEL__ */
#endif /* _ASM_X86_64_UNISTD_H_ */
diff --git a/include/asm-x86/unwind.h b/include/asm-x86/unwind.h
index 7e4d7ad5520..8b064bd9c55 100644
--- a/include/asm-x86/unwind.h
+++ b/include/asm-x86/unwind.h
@@ -1,5 +1,13 @@
-#ifdef CONFIG_X86_32
-# include "unwind_32.h"
-#else
-# include "unwind_64.h"
-#endif
+#ifndef _ASM_X86_UNWIND_H
+#define _ASM_X86_UNWIND_H
+
+#define UNW_PC(frame) ((void)(frame), 0UL)
+#define UNW_SP(frame) ((void)(frame), 0UL)
+#define UNW_FP(frame) ((void)(frame), 0UL)
+
+static inline int arch_unw_user_mode(const void *info)
+{
+ return 0;
+}
+
+#endif /* _ASM_X86_UNWIND_H */
diff --git a/include/asm-x86/unwind_32.h b/include/asm-x86/unwind_32.h
deleted file mode 100644
index 43c70c3de2f..00000000000
--- a/include/asm-x86/unwind_32.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _ASM_I386_UNWIND_H
-#define _ASM_I386_UNWIND_H
-
-#define UNW_PC(frame) ((void)(frame), 0)
-#define UNW_SP(frame) ((void)(frame), 0)
-#define UNW_FP(frame) ((void)(frame), 0)
-
-static inline int arch_unw_user_mode(const void *info)
-{
- return 0;
-}
-
-#endif /* _ASM_I386_UNWIND_H */
diff --git a/include/asm-x86/unwind_64.h b/include/asm-x86/unwind_64.h
deleted file mode 100644
index 02710f6a456..00000000000
--- a/include/asm-x86/unwind_64.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_X86_64_UNWIND_H
-#define _ASM_X86_64_UNWIND_H
-
-#define UNW_PC(frame) ((void)(frame), 0UL)
-#define UNW_SP(frame) ((void)(frame), 0UL)
-
-static inline int arch_unw_user_mode(const void *info)
-{
- return 0;
-}
-
-#endif /* _ASM_X86_64_UNWIND_H */
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index 1c1e0d933ee..78db04cf6e4 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -108,6 +108,7 @@ static inline int fls (unsigned int x)
#endif
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/minix.h>
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
index f10c3487cd4..3e04167cd9d 100644
--- a/include/asm-xtensa/semaphore.h
+++ b/include/asm-xtensa/semaphore.h
@@ -33,7 +33,6 @@ struct semaphore {
struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
static inline void sema_init (struct semaphore *sem, int val)
{
diff --git a/include/asm-xtensa/types.h b/include/asm-xtensa/types.h
index f1e84526f99..b27d841a8eb 100644
--- a/include/asm-xtensa/types.h
+++ b/include/asm-xtensa/types.h
@@ -38,9 +38,9 @@ typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
#endif
/*
diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h
index e2ee73aef0e..4ea429b1875 100644
--- a/include/keys/rxrpc-type.h
+++ b/include/keys/rxrpc-type.h
@@ -19,4 +19,6 @@
*/
extern struct key_type key_type_rxrpc;
+extern struct key *rxrpc_get_null_key(const char *);
+
#endif /* _KEYS_USER_TYPE_H */
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 818cc3a50e6..7ac8303c847 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -46,7 +46,6 @@ header-y += chio.h
header-y += coda_psdev.h
header-y += coff.h
header-y += comstats.h
-header-y += consolemap.h
header-y += const.h
header-y += cycx_cfm.h
header-y += dlm_device.h
@@ -78,7 +77,6 @@ header-y += if_arcnet.h
header-y += if_bonding.h
header-y += if_cablemodem.h
header-y += if_fc.h
-header-y += if_fddi.h
header-y += if.h
header-y += if_hippi.h
header-y += if_infiniband.h
@@ -121,7 +119,6 @@ header-y += nl80211.h
header-y += oom.h
header-y += param.h
header-y += pci_regs.h
-header-y += personality.h
header-y += pfkeyv2.h
header-y += pg.h
header-y += phantom.h
@@ -159,7 +156,6 @@ header-y += video_decoder.h
header-y += video_encoder.h
header-y += videotext.h
header-y += vt.h
-header-y += wireless.h
header-y += x25.h
unifdef-y += acct.h
@@ -286,6 +282,7 @@ unifdef-y += nfs_idmap.h
unifdef-y += n_r3964.h
unifdef-y += nubus.h
unifdef-y += nvram.h
+unifdef-y += oom.h
unifdef-y += parport.h
unifdef-y += patchkey.h
unifdef-y += pci.h
diff --git a/include/linux/aio.h b/include/linux/aio.h
index d10e608f232..7ef8de66200 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -232,18 +232,6 @@ int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
__put_ioctx(kioctx); \
} while (0)
-#define in_aio() (unlikely(!is_sync_wait(current->io_wait)))
-
-/* may be used for debugging */
-#define warn_if_async() \
-do { \
- if (in_aio()) { \
- printk(KERN_ERR "%s(%s:%d) called in async context!\n", \
- __FUNCTION__, __FILE__, __LINE__); \
- dump_stack(); \
- } \
-} while (0)
-
#define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
#include <linux/aio_abi.h>
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h
new file mode 100644
index 00000000000..06023393fba
--- /dev/null
+++ b/include/linux/atmel-ssc.h
@@ -0,0 +1,312 @@
+#ifndef __INCLUDE_ATMEL_SSC_H
+#define __INCLUDE_ATMEL_SSC_H
+
+#include <linux/platform_device.h>
+#include <linux/list.h>
+
+struct ssc_device {
+ struct list_head list;
+ void __iomem *regs;
+ struct platform_device *pdev;
+ struct clk *clk;
+ int user;
+ int irq;
+};
+
+struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
+void ssc_free(struct ssc_device *ssc);
+
+/* SSC register offsets */
+
+/* SSC Control Register */
+#define SSC_CR 0x00000000
+#define SSC_CR_RXDIS_SIZE 1
+#define SSC_CR_RXDIS_OFFSET 1
+#define SSC_CR_RXEN_SIZE 1
+#define SSC_CR_RXEN_OFFSET 0
+#define SSC_CR_SWRST_SIZE 1
+#define SSC_CR_SWRST_OFFSET 15
+#define SSC_CR_TXDIS_SIZE 1
+#define SSC_CR_TXDIS_OFFSET 9
+#define SSC_CR_TXEN_SIZE 1
+#define SSC_CR_TXEN_OFFSET 8
+
+/* SSC Clock Mode Register */
+#define SSC_CMR 0x00000004
+#define SSC_CMR_DIV_SIZE 12
+#define SSC_CMR_DIV_OFFSET 0
+
+/* SSC Receive Clock Mode Register */
+#define SSC_RCMR 0x00000010
+#define SSC_RCMR_CKG_SIZE 2
+#define SSC_RCMR_CKG_OFFSET 6
+#define SSC_RCMR_CKI_SIZE 1
+#define SSC_RCMR_CKI_OFFSET 5
+#define SSC_RCMR_CKO_SIZE 3
+#define SSC_RCMR_CKO_OFFSET 2
+#define SSC_RCMR_CKS_SIZE 2
+#define SSC_RCMR_CKS_OFFSET 0
+#define SSC_RCMR_PERIOD_SIZE 8
+#define SSC_RCMR_PERIOD_OFFSET 24
+#define SSC_RCMR_START_SIZE 4
+#define SSC_RCMR_START_OFFSET 8
+#define SSC_RCMR_STOP_SIZE 1
+#define SSC_RCMR_STOP_OFFSET 12
+#define SSC_RCMR_STTDLY_SIZE 8
+#define SSC_RCMR_STTDLY_OFFSET 16
+
+/* SSC Receive Frame Mode Register */
+#define SSC_RFMR 0x00000014
+#define SSC_RFMR_DATLEN_SIZE 5
+#define SSC_RFMR_DATLEN_OFFSET 0
+#define SSC_RFMR_DATNB_SIZE 4
+#define SSC_RFMR_DATNB_OFFSET 8
+#define SSC_RFMR_FSEDGE_SIZE 1
+#define SSC_RFMR_FSEDGE_OFFSET 24
+#define SSC_RFMR_FSLEN_SIZE 4
+#define SSC_RFMR_FSLEN_OFFSET 16
+#define SSC_RFMR_FSOS_SIZE 4
+#define SSC_RFMR_FSOS_OFFSET 20
+#define SSC_RFMR_LOOP_SIZE 1
+#define SSC_RFMR_LOOP_OFFSET 5
+#define SSC_RFMR_MSBF_SIZE 1
+#define SSC_RFMR_MSBF_OFFSET 7
+
+/* SSC Transmit Clock Mode Register */
+#define SSC_TCMR 0x00000018
+#define SSC_TCMR_CKG_SIZE 2
+#define SSC_TCMR_CKG_OFFSET 6
+#define SSC_TCMR_CKI_SIZE 1
+#define SSC_TCMR_CKI_OFFSET 5
+#define SSC_TCMR_CKO_SIZE 3
+#define SSC_TCMR_CKO_OFFSET 2
+#define SSC_TCMR_CKS_SIZE 2
+#define SSC_TCMR_CKS_OFFSET 0
+#define SSC_TCMR_PERIOD_SIZE 8
+#define SSC_TCMR_PERIOD_OFFSET 24
+#define SSC_TCMR_START_SIZE 4
+#define SSC_TCMR_START_OFFSET 8
+#define SSC_TCMR_STTDLY_SIZE 8
+#define SSC_TCMR_STTDLY_OFFSET 16
+
+/* SSC Transmit Frame Mode Register */
+#define SSC_TFMR 0x0000001c
+#define SSC_TFMR_DATDEF_SIZE 1
+#define SSC_TFMR_DATDEF_OFFSET 5
+#define SSC_TFMR_DATLEN_SIZE 5
+#define SSC_TFMR_DATLEN_OFFSET 0
+#define SSC_TFMR_DATNB_SIZE 4
+#define SSC_TFMR_DATNB_OFFSET 8
+#define SSC_TFMR_FSDEN_SIZE 1
+#define SSC_TFMR_FSDEN_OFFSET 23
+#define SSC_TFMR_FSEDGE_SIZE 1
+#define SSC_TFMR_FSEDGE_OFFSET 24
+#define SSC_TFMR_FSLEN_SIZE 4
+#define SSC_TFMR_FSLEN_OFFSET 16
+#define SSC_TFMR_FSOS_SIZE 3
+#define SSC_TFMR_FSOS_OFFSET 20
+#define SSC_TFMR_MSBF_SIZE 1
+#define SSC_TFMR_MSBF_OFFSET 7
+
+/* SSC Receive Hold Register */
+#define SSC_RHR 0x00000020
+#define SSC_RHR_RDAT_SIZE 32
+#define SSC_RHR_RDAT_OFFSET 0
+
+/* SSC Transmit Hold Register */
+#define SSC_THR 0x00000024
+#define SSC_THR_TDAT_SIZE 32
+#define SSC_THR_TDAT_OFFSET 0
+
+/* SSC Receive Sync. Holding Register */
+#define SSC_RSHR 0x00000030
+#define SSC_RSHR_RSDAT_SIZE 16
+#define SSC_RSHR_RSDAT_OFFSET 0
+
+/* SSC Transmit Sync. Holding Register */
+#define SSC_TSHR 0x00000034
+#define SSC_TSHR_TSDAT_SIZE 16
+#define SSC_TSHR_RSDAT_OFFSET 0
+
+/* SSC Receive Compare 0 Register */
+#define SSC_RC0R 0x00000038
+#define SSC_RC0R_CP0_SIZE 16
+#define SSC_RC0R_CP0_OFFSET 0
+
+/* SSC Receive Compare 1 Register */
+#define SSC_RC1R 0x0000003c
+#define SSC_RC1R_CP1_SIZE 16
+#define SSC_RC1R_CP1_OFFSET 0
+
+/* SSC Status Register */
+#define SSC_SR 0x00000040
+#define SSC_SR_CP0_SIZE 1
+#define SSC_SR_CP0_OFFSET 8
+#define SSC_SR_CP1_SIZE 1
+#define SSC_SR_CP1_OFFSET 9
+#define SSC_SR_ENDRX_SIZE 1
+#define SSC_SR_ENDRX_OFFSET 6
+#define SSC_SR_ENDTX_SIZE 1
+#define SSC_SR_ENDTX_OFFSET 2
+#define SSC_SR_OVRUN_SIZE 1
+#define SSC_SR_OVRUN_OFFSET 5
+#define SSC_SR_RXBUFF_SIZE 1
+#define SSC_SR_RXBUFF_OFFSET 7
+#define SSC_SR_RXEN_SIZE 1
+#define SSC_SR_RXEN_OFFSET 17
+#define SSC_SR_RXRDY_SIZE 1
+#define SSC_SR_RXRDY_OFFSET 4
+#define SSC_SR_RXSYN_SIZE 1
+#define SSC_SR_RXSYN_OFFSET 11
+#define SSC_SR_TXBUFE_SIZE 1
+#define SSC_SR_TXBUFE_OFFSET 3
+#define SSC_SR_TXEMPTY_SIZE 1
+#define SSC_SR_TXEMPTY_OFFSET 1
+#define SSC_SR_TXEN_SIZE 1
+#define SSC_SR_TXEN_OFFSET 16
+#define SSC_SR_TXRDY_SIZE 1
+#define SSC_SR_TXRDY_OFFSET 0
+#define SSC_SR_TXSYN_SIZE 1
+#define SSC_SR_TXSYN_OFFSET 10
+
+/* SSC Interrupt Enable Register */
+#define SSC_IER 0x00000044
+#define SSC_IER_CP0_SIZE 1
+#define SSC_IER_CP0_OFFSET 8
+#define SSC_IER_CP1_SIZE 1
+#define SSC_IER_CP1_OFFSET 9
+#define SSC_IER_ENDRX_SIZE 1
+#define SSC_IER_ENDRX_OFFSET 6
+#define SSC_IER_ENDTX_SIZE 1
+#define SSC_IER_ENDTX_OFFSET 2
+#define SSC_IER_OVRUN_SIZE 1
+#define SSC_IER_OVRUN_OFFSET 5
+#define SSC_IER_RXBUFF_SIZE 1
+#define SSC_IER_RXBUFF_OFFSET 7
+#define SSC_IER_RXRDY_SIZE 1
+#define SSC_IER_RXRDY_OFFSET 4
+#define SSC_IER_RXSYN_SIZE 1
+#define SSC_IER_RXSYN_OFFSET 11
+#define SSC_IER_TXBUFE_SIZE 1
+#define SSC_IER_TXBUFE_OFFSET 3
+#define SSC_IER_TXEMPTY_SIZE 1
+#define SSC_IER_TXEMPTY_OFFSET 1
+#define SSC_IER_TXRDY_SIZE 1
+#define SSC_IER_TXRDY_OFFSET 0
+#define SSC_IER_TXSYN_SIZE 1
+#define SSC_IER_TXSYN_OFFSET 10
+
+/* SSC Interrupt Disable Register */
+#define SSC_IDR 0x00000048
+#define SSC_IDR_CP0_SIZE 1
+#define SSC_IDR_CP0_OFFSET 8
+#define SSC_IDR_CP1_SIZE 1
+#define SSC_IDR_CP1_OFFSET 9
+#define SSC_IDR_ENDRX_SIZE 1
+#define SSC_IDR_ENDRX_OFFSET 6
+#define SSC_IDR_ENDTX_SIZE 1
+#define SSC_IDR_ENDTX_OFFSET 2
+#define SSC_IDR_OVRUN_SIZE 1
+#define SSC_IDR_OVRUN_OFFSET 5
+#define SSC_IDR_RXBUFF_SIZE 1
+#define SSC_IDR_RXBUFF_OFFSET 7
+#define SSC_IDR_RXRDY_SIZE 1
+#define SSC_IDR_RXRDY_OFFSET 4
+#define SSC_IDR_RXSYN_SIZE 1
+#define SSC_IDR_RXSYN_OFFSET 11
+#define SSC_IDR_TXBUFE_SIZE 1
+#define SSC_IDR_TXBUFE_OFFSET 3
+#define SSC_IDR_TXEMPTY_SIZE 1
+#define SSC_IDR_TXEMPTY_OFFSET 1
+#define SSC_IDR_TXRDY_SIZE 1
+#define SSC_IDR_TXRDY_OFFSET 0
+#define SSC_IDR_TXSYN_SIZE 1
+#define SSC_IDR_TXSYN_OFFSET 10
+
+/* SSC Interrupt Mask Register */
+#define SSC_IMR 0x0000004c
+#define SSC_IMR_CP0_SIZE 1
+#define SSC_IMR_CP0_OFFSET 8
+#define SSC_IMR_CP1_SIZE 1
+#define SSC_IMR_CP1_OFFSET 9
+#define SSC_IMR_ENDRX_SIZE 1
+#define SSC_IMR_ENDRX_OFFSET 6
+#define SSC_IMR_ENDTX_SIZE 1
+#define SSC_IMR_ENDTX_OFFSET 2
+#define SSC_IMR_OVRUN_SIZE 1
+#define SSC_IMR_OVRUN_OFFSET 5
+#define SSC_IMR_RXBUFF_SIZE 1
+#define SSC_IMR_RXBUFF_OFFSET 7
+#define SSC_IMR_RXRDY_SIZE 1
+#define SSC_IMR_RXRDY_OFFSET 4
+#define SSC_IMR_RXSYN_SIZE 1
+#define SSC_IMR_RXSYN_OFFSET 11
+#define SSC_IMR_TXBUFE_SIZE 1
+#define SSC_IMR_TXBUFE_OFFSET 3
+#define SSC_IMR_TXEMPTY_SIZE 1
+#define SSC_IMR_TXEMPTY_OFFSET 1
+#define SSC_IMR_TXRDY_SIZE 1
+#define SSC_IMR_TXRDY_OFFSET 0
+#define SSC_IMR_TXSYN_SIZE 1
+#define SSC_IMR_TXSYN_OFFSET 10
+
+/* SSC PDC Receive Pointer Register */
+#define SSC_PDC_RPR 0x00000100
+
+/* SSC PDC Receive Counter Register */
+#define SSC_PDC_RCR 0x00000104
+
+/* SSC PDC Transmit Pointer Register */
+#define SSC_PDC_TPR 0x00000108
+
+/* SSC PDC Receive Next Pointer Register */
+#define SSC_PDC_RNPR 0x00000110
+
+/* SSC PDC Receive Next Counter Register */
+#define SSC_PDC_RNCR 0x00000114
+
+/* SSC PDC Transmit Counter Register */
+#define SSC_PDC_TCR 0x0000010c
+
+/* SSC PDC Transmit Next Pointer Register */
+#define SSC_PDC_TNPR 0x00000118
+
+/* SSC PDC Transmit Next Counter Register */
+#define SSC_PDC_TNCR 0x0000011c
+
+/* SSC PDC Transfer Control Register */
+#define SSC_PDC_PTCR 0x00000120
+#define SSC_PDC_PTCR_RXTDIS_SIZE 1
+#define SSC_PDC_PTCR_RXTDIS_OFFSET 1
+#define SSC_PDC_PTCR_RXTEN_SIZE 1
+#define SSC_PDC_PTCR_RXTEN_OFFSET 0
+#define SSC_PDC_PTCR_TXTDIS_SIZE 1
+#define SSC_PDC_PTCR_TXTDIS_OFFSET 9
+#define SSC_PDC_PTCR_TXTEN_SIZE 1
+#define SSC_PDC_PTCR_TXTEN_OFFSET 8
+
+/* SSC PDC Transfer Status Register */
+#define SSC_PDC_PTSR 0x00000124
+#define SSC_PDC_PTSR_RXTEN_SIZE 1
+#define SSC_PDC_PTSR_RXTEN_OFFSET 0
+#define SSC_PDC_PTSR_TXTEN_SIZE 1
+#define SSC_PDC_PTSR_TXTEN_OFFSET 8
+
+/* Bit manipulation macros */
+#define SSC_BIT(name) \
+ (1 << SSC_##name##_OFFSET)
+#define SSC_BF(name, value) \
+ (((value) & ((1 << SSC_##name##_SIZE) - 1)) \
+ << SSC_##name##_OFFSET)
+#define SSC_BFEXT(name, value) \
+ (((value) >> SSC_##name##_OFFSET) \
+ & ((1 << SSC_##name##_SIZE) - 1))
+#define SSC_BFINS(name, value, old) \
+ (((old) & ~(((1 << SSC_##name##_SIZE) - 1) \
+ << SSC_##name##_OFFSET)) | SSC_BF(name, value))
+
+/* Register access macros */
+#define ssc_readl(base, reg) __raw_readl(base + SSC_##reg)
+#define ssc_writel(base, reg, value) __raw_writel((value), base + SSC_##reg)
+
+#endif /* __INCLUDE_ATMEL_SSC_H */
diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h
index d2bc0d66e65..ad895455ab7 100644
--- a/include/linux/auxvec.h
+++ b/include/linux/auxvec.h
@@ -26,6 +26,8 @@
#define AT_SECURE 23 /* secure mode boolean */
-#define AT_VECTOR_SIZE 44 /* Size of auxiliary table. */
+#ifdef __KERNEL__
+#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */
+#endif
#endif /* _LINUX_AUXVEC_H */
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 7011d625559..48a62baace5 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -8,6 +8,9 @@
#ifndef _LINUX_BACKING_DEV_H
#define _LINUX_BACKING_DEV_H
+#include <linux/percpu_counter.h>
+#include <linux/log2.h>
+#include <linux/proportions.h>
#include <asm/atomic.h>
struct page;
@@ -24,6 +27,14 @@ enum bdi_state {
typedef int (congested_fn)(void *, int);
+enum bdi_stat_item {
+ BDI_RECLAIMABLE,
+ BDI_WRITEBACK,
+ NR_BDI_STAT_ITEMS
+};
+
+#define BDI_STAT_BATCH (8*(1+ilog2(nr_cpu_ids)))
+
struct backing_dev_info {
unsigned long ra_pages; /* max readahead in PAGE_CACHE_SIZE units */
unsigned long state; /* Always use atomic bitops on this */
@@ -32,8 +43,90 @@ struct backing_dev_info {
void *congested_data; /* Pointer to aux data for congested func */
void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
void *unplug_io_data;
+
+ struct percpu_counter bdi_stat[NR_BDI_STAT_ITEMS];
+
+ struct prop_local_percpu completions;
+ int dirty_exceeded;
};
+int bdi_init(struct backing_dev_info *bdi);
+void bdi_destroy(struct backing_dev_info *bdi);
+
+static inline void __add_bdi_stat(struct backing_dev_info *bdi,
+ enum bdi_stat_item item, s64 amount)
+{
+ __percpu_counter_add(&bdi->bdi_stat[item], amount, BDI_STAT_BATCH);
+}
+
+static inline void __inc_bdi_stat(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ __add_bdi_stat(bdi, item, 1);
+}
+
+static inline void inc_bdi_stat(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __inc_bdi_stat(bdi, item);
+ local_irq_restore(flags);
+}
+
+static inline void __dec_bdi_stat(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ __add_bdi_stat(bdi, item, -1);
+}
+
+static inline void dec_bdi_stat(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __dec_bdi_stat(bdi, item);
+ local_irq_restore(flags);
+}
+
+static inline s64 bdi_stat(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ return percpu_counter_read_positive(&bdi->bdi_stat[item]);
+}
+
+static inline s64 __bdi_stat_sum(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ return percpu_counter_sum_positive(&bdi->bdi_stat[item]);
+}
+
+static inline s64 bdi_stat_sum(struct backing_dev_info *bdi,
+ enum bdi_stat_item item)
+{
+ s64 sum;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ sum = __bdi_stat_sum(bdi, item);
+ local_irq_restore(flags);
+
+ return sum;
+}
+
+/*
+ * maximal error of a stat counter.
+ */
+static inline unsigned long bdi_stat_error(struct backing_dev_info *bdi)
+{
+#ifdef CONFIG_SMP
+ return nr_cpu_ids * BDI_STAT_BATCH;
+#else
+ return 1;
+#endif
+}
/*
* Flags in backing_dev_info::capability
@@ -93,7 +186,6 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi)
void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
void set_bdi_congested(struct backing_dev_info *bdi, int rw);
long congestion_wait(int rw, long timeout);
-void congestion_end(int rw);
#define bdi_cap_writeback_dirty(bdi) \
(!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 91c8c07fe8b..b7fc55ec8d4 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -37,7 +37,8 @@ struct linux_binprm{
int sh_bang;
struct file * file;
int e_uid, e_gid;
- kernel_cap_t cap_inheritable, cap_permitted, cap_effective;
+ kernel_cap_t cap_inheritable, cap_permitted;
+ bool cap_effective;
void *security;
int argc, envc;
char * filename; /* Name of binary as seen by procps */
@@ -63,17 +64,17 @@ struct linux_binprm{
* linux accepts.
*/
struct linux_binfmt {
- struct linux_binfmt * next;
+ struct list_head lh;
struct module *module;
int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
int (*load_shlib)(struct file *);
- int (*core_dump)(long signr, struct pt_regs * regs, struct file * file);
+ int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
unsigned long min_coredump; /* minimal dump size */
int hasvdso;
};
extern int register_binfmt(struct linux_binfmt *);
-extern int unregister_binfmt(struct linux_binfmt *);
+extern void unregister_binfmt(struct linux_binfmt *);
extern int prepare_binprm(struct linux_binprm *);
extern int __must_check remove_arg_zero(struct linux_binprm *);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 089a8bc55dd..4da441337d6 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -176,13 +176,28 @@ struct bio {
#define bio_offset(bio) bio_iovec((bio))->bv_offset
#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx)
#define bio_sectors(bio) ((bio)->bi_size >> 9)
-#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9)
-#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER))
#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC))
#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META))
+#define bio_empty_barrier(bio) (bio_barrier(bio) && !(bio)->bi_size)
+
+static inline unsigned int bio_cur_sectors(struct bio *bio)
+{
+ if (bio->bi_vcnt)
+ return bio_iovec(bio)->bv_len >> 9;
+
+ return 0;
+}
+
+static inline void *bio_data(struct bio *bio)
+{
+ if (bio->bi_vcnt)
+ return page_address(bio_page(bio)) + bio_offset(bio);
+
+ return NULL;
+}
/*
* will die
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h
index 6b20af0bbb7..7113a32a86e 100644
--- a/include/linux/bit_spinlock.h
+++ b/include/linux/bit_spinlock.h
@@ -18,7 +18,7 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr)
*/
preempt_disable();
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
- while (test_and_set_bit(bitnum, addr)) {
+ while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
while (test_bit(bitnum, addr)) {
preempt_enable();
cpu_relax();
@@ -36,7 +36,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
{
preempt_disable();
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
- if (test_and_set_bit(bitnum, addr)) {
+ if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
preempt_enable();
return 0;
}
@@ -50,10 +50,28 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
*/
static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
{
+#ifdef CONFIG_DEBUG_SPINLOCK
+ BUG_ON(!test_bit(bitnum, addr));
+#endif
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+ clear_bit_unlock(bitnum, addr);
+#endif
+ preempt_enable();
+ __release(bitlock);
+}
+
+/*
+ * bit-based spin_unlock()
+ * non-atomic version, which can be used eg. if the bit lock itself is
+ * protecting the rest of the flags in the word.
+ */
+static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
BUG_ON(!test_bit(bitnum, addr));
- smp_mb__before_clear_bit();
- clear_bit(bitnum, addr);
+#endif
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+ __clear_bit_unlock(bitnum, addr);
#endif
preempt_enable();
__release(bitlock);
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 638165f571d..b9fb8ee3308 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -8,6 +8,12 @@
*/
#include <asm/bitops.h>
+#define for_each_bit(bit, addr, size) \
+ for ((bit) = find_first_bit((addr), (size)); \
+ (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
+
+
static __inline__ int get_bitmask_order(unsigned int count)
{
int order;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5ed888b04b2..bbf906a0b41 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -330,7 +330,6 @@ typedef void (unplug_fn) (struct request_queue *);
struct bio_vec;
typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *);
-typedef int (issue_flush_fn) (struct request_queue *, struct gendisk *, sector_t *);
typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
typedef void (softirq_done_fn)(struct request *);
@@ -368,7 +367,6 @@ struct request_queue
prep_rq_fn *prep_rq_fn;
unplug_fn *unplug_fn;
merge_bvec_fn *merge_bvec_fn;
- issue_flush_fn *issue_flush_fn;
prepare_flush_fn *prepare_flush_fn;
softirq_done_fn *softirq_done_fn;
@@ -540,6 +538,7 @@ enum {
#define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER)
#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA)
#define blk_bidi_rq(rq) ((rq)->next_rq != NULL)
+#define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors)
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
@@ -729,7 +728,9 @@ static inline void blk_run_address_space(struct address_space *mapping)
extern int end_that_request_first(struct request *, int, int);
extern int end_that_request_chunk(struct request *, int, int);
extern void end_that_request_last(struct request *, int);
-extern void end_request(struct request *req, int uptodate);
+extern void end_request(struct request *, int);
+extern void end_queued_request(struct request *, int);
+extern void end_dequeued_request(struct request *, int);
extern void blk_complete_request(struct request *);
/*
@@ -767,7 +768,6 @@ extern void blk_queue_dma_alignment(struct request_queue *, int);
extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
extern int blk_queue_ordered(struct request_queue *, unsigned, prepare_flush_fn *);
-extern void blk_queue_issue_flush_fn(struct request_queue *, issue_flush_fn *);
extern int blk_do_ordered(struct request_queue *, struct request **);
extern unsigned blk_ordered_cur_seq(struct request_queue *);
extern unsigned blk_ordered_req_seq(struct request *);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 35cadad84b1..da0d83fbadc 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -203,10 +203,20 @@ void block_invalidatepage(struct page *page, unsigned long offset);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
int block_read_full_page(struct page*, get_block_t*);
+int block_write_begin(struct file *, struct address_space *,
+ loff_t, unsigned, unsigned,
+ struct page **, void **, get_block_t*);
+int block_write_end(struct file *, struct address_space *,
+ loff_t, unsigned, unsigned,
+ struct page *, void *);
+int generic_write_end(struct file *, struct address_space *,
+ loff_t, unsigned, unsigned,
+ struct page *, void *);
+void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
-int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
- loff_t *);
-int generic_cont_expand(struct inode *inode, loff_t size);
+int cont_write_begin(struct file *, struct address_space *, loff_t,
+ unsigned, unsigned, struct page **, void **,
+ get_block_t *, loff_t *);
int generic_cont_expand_simple(struct inode *inode, loff_t size);
int block_commit_write(struct page *page, unsigned from, unsigned to);
int block_page_mkwrite(struct vm_area_struct *vma, struct page *page,
@@ -216,9 +226,13 @@ sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
int file_fsync(struct file *, struct dentry *, int);
-int nobh_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
-int nobh_commit_write(struct file *, struct page *, unsigned, unsigned);
-int nobh_truncate_page(struct address_space *, loff_t);
+int nobh_write_begin(struct file *, struct address_space *,
+ loff_t, unsigned, unsigned,
+ struct page **, void **, get_block_t*);
+int nobh_write_end(struct file *, struct address_space *,
+ loff_t, unsigned, unsigned,
+ struct page *, void *);
+int nobh_truncate_page(struct address_space *, loff_t, get_block_t *);
int nobh_writepage(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 2dfa5855593..7a8d7ade28a 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -1,14 +1,14 @@
/*
* This is <linux/capability.h>
*
- * Andrew G. Morgan <morgan@transmeta.com>
+ * Andrew G. Morgan <morgan@kernel.org>
* Alexander Kjeldaas <astor@guardian.no>
* with help from Aleph1, Roland Buresund and Andrew Main.
*
* See here for the libcap library ("POSIX draft" compliance):
*
- * ftp://linux.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/
- */
+ * ftp://linux.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
+ */
#ifndef _LINUX_CAPABILITY_H
#define _LINUX_CAPABILITY_H
@@ -28,23 +28,41 @@ struct task_struct;
following structure to such a composite is better handled in a user
library since the draft standard requires the use of malloc/free
etc.. */
-
+
#define _LINUX_CAPABILITY_VERSION 0x19980330
typedef struct __user_cap_header_struct {
__u32 version;
int pid;
} __user *cap_user_header_t;
-
+
typedef struct __user_cap_data_struct {
__u32 effective;
__u32 permitted;
__u32 inheritable;
} __user *cap_user_data_t;
-
-#ifdef __KERNEL__
-#include <asm/current.h>
+#define XATTR_CAPS_SUFFIX "capability"
+#define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
+
+#define XATTR_CAPS_SZ (3*sizeof(__le32))
+#define VFS_CAP_REVISION_MASK 0xFF000000
+#define VFS_CAP_REVISION_1 0x01000000
+
+#define VFS_CAP_REVISION VFS_CAP_REVISION_1
+
+#define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
+#define VFS_CAP_FLAGS_EFFECTIVE 0x000001
+
+struct vfs_cap_data {
+ __u32 magic_etc; /* Little endian */
+ struct {
+ __u32 permitted; /* Little endian */
+ __u32 inheritable; /* Little endian */
+ } data[1];
+};
+
+#ifdef __KERNEL__
/* #define STRICT_CAP_T_TYPECHECKS */
@@ -59,7 +77,7 @@ typedef struct kernel_cap_struct {
typedef __u32 kernel_cap_t;
#endif
-
+
#define _USER_CAP_HEADER_SIZE (2*sizeof(__u32))
#define _KERNEL_CAP_T_SIZE (sizeof(kernel_cap_t))
@@ -67,7 +85,7 @@ typedef __u32 kernel_cap_t;
/**
- ** POSIX-draft defined capabilities.
+ ** POSIX-draft defined capabilities.
**/
/* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
@@ -87,7 +105,7 @@ typedef __u32 kernel_cap_t;
defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */
#define CAP_DAC_READ_SEARCH 2
-
+
/* Overrides all restrictions about allowed operations on files, where
file owner ID must be equal to the user ID, except where CAP_FSETID
is applicable. It doesn't override MAC and DAC restrictions. */
@@ -257,7 +275,7 @@ typedef __u32 kernel_cap_t;
/* Override reserved space on ext2 filesystem */
/* Modify data journaling mode on ext3 filesystem (uses journaling
resources) */
-/* NOTE: ext2 honors fsuid when checking for resource overrides, so
+/* NOTE: ext2 honors fsuid when checking for resource overrides, so
you can override using fsuid too */
/* Override size restrictions on IPC message queues */
/* Allow more than 64hz interrupts from the real-time clock */
@@ -289,16 +307,14 @@ typedef __u32 kernel_cap_t;
#define CAP_AUDIT_CONTROL 30
+#define CAP_SETFCAP 31
+
#ifdef __KERNEL__
-/*
- * Bounding set
- */
-extern kernel_cap_t cap_bset;
/*
* Internal kernel functions only
*/
-
+
#ifdef STRICT_CAP_T_TYPECHECKS
#define to_cap_t(x) { x }
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 16ea3374ddd..107787aacb6 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -221,10 +221,15 @@ extern void clocksource_resume(void);
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
+extern void update_vsyscall_tz(void);
#else
static inline void update_vsyscall(struct timespec *ts, struct clocksource *c)
{
}
+
+static inline void update_vsyscall_tz(void)
+{
+}
#endif
#endif /* _LINUX_CLOCKSOURCE_H */
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 03ec2311fb2..fe23792f05c 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -1,4 +1,6 @@
-/* Never include this file directly. Include <linux/compiler.h> instead. */
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc.h> directly, include <linux/compiler.h> instead."
+#endif
/*
* Common definitions for all gcc versions go here.
@@ -34,10 +36,20 @@
#define __weak __attribute__((weak))
#define __naked __attribute__((naked))
#define __noreturn __attribute__((noreturn))
+
+/*
+ * From the GCC manual:
+ *
+ * Many functions have no effects except the return value and their
+ * return value depends only on the parameters and/or global
+ * variables. Such a function can be subject to common subexpression
+ * elimination and loop optimization just as an arithmetic operator
+ * would be.
+ * [...]
+ */
#define __pure __attribute__((pure))
#define __aligned(x) __attribute__((aligned(x)))
#define __printf(a,b) __attribute__((format(printf,a,b)))
#define noinline __attribute__((noinline))
-#define __attribute_pure__ __attribute__((pure))
#define __attribute_const__ __attribute__((__const__))
#define __maybe_unused __attribute__((unused))
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index a9e2863c2db..2d8c0f48f55 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -1,4 +1,6 @@
-/* Never include this file directly. Include <linux/compiler.h> instead. */
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead."
+#endif
/* These definitions are for GCC v3.x. */
#include <linux/compiler-gcc.h>
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 14f7494280f..ee7ca5de970 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -1,4 +1,6 @@
-/* Never include this file directly. Include <linux/compiler.h> instead. */
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead."
+#endif
/* These definitions are for GCC v4.x. */
#include <linux/compiler-gcc.h>
diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h
index b769961e6f2..d8e636e5607 100644
--- a/include/linux/compiler-intel.h
+++ b/include/linux/compiler-intel.h
@@ -1,4 +1,6 @@
-/* Never include this file directly. Include <linux/compiler.h> instead. */
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-intel.h> directly, include <linux/compiler.h> instead."
+#endif
#ifdef __ECC
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 86f9a3a6137..c811c8b979a 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -132,20 +132,6 @@ extern void __chk_io_ptr(const volatile void __iomem *);
# define __maybe_unused /* unimplemented */
#endif
-/*
- * From the GCC manual:
- *
- * Many functions have no effects except the return value and their
- * return value depends only on the parameters and/or global
- * variables. Such a function can be subject to common subexpression
- * elimination and loop optimization just as an arithmetic operator
- * would be.
- * [...]
- */
-#ifndef __attribute_pure__
-# define __attribute_pure__ /* unimplemented */
-#endif
-
#ifndef noinline
#define noinline
#endif
diff --git a/include/linux/connector.h b/include/linux/connector.h
index b62f823e90c..13fc4541bf2 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -36,14 +36,15 @@
#define CN_VAL_CIFS 0x1
#define CN_W1_IDX 0x3 /* w1 communication */
#define CN_W1_VAL 0x1
+#define CN_IDX_V86D 0x4
+#define CN_VAL_V86D_UVESAFB 0x1
-
-#define CN_NETLINK_USERS 4
+#define CN_NETLINK_USERS 5
/*
* Maximum connector's message size.
*/
-#define CONNECTOR_MAX_MSG_SIZE 1024
+#define CONNECTOR_MAX_MSG_SIZE 16384
/*
* idx and val are unique identifiers which
diff --git a/include/linux/console.h b/include/linux/console.h
index 56a7bcda49c..a5f88a6a259 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -45,7 +45,8 @@ struct consw {
int (*con_font_get)(struct vc_data *, struct console_font *);
int (*con_font_default)(struct vc_data *, struct console_font *, char *);
int (*con_font_copy)(struct vc_data *, int);
- int (*con_resize)(struct vc_data *, unsigned int, unsigned int);
+ int (*con_resize)(struct vc_data *, unsigned int, unsigned int,
+ unsigned int);
int (*con_set_palette)(struct vc_data *, unsigned char *);
int (*con_scrolldelta)(struct vc_data *, int);
int (*con_set_origin)(struct vc_data *);
@@ -121,14 +122,11 @@ extern void console_stop(struct console *);
extern void console_start(struct console *);
extern int is_console_locked(void);
-#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+extern int console_suspend_enabled;
+
/* Suspend and resume console messages over PM events */
extern void suspend_console(void);
extern void resume_console(void);
-#else
-static inline void suspend_console(void) {}
-static inline void resume_console(void) {}
-#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
int mda_console_init(void);
void prom_con_init(void);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index dc77fed7b28..d71f7c0f931 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -100,6 +100,7 @@ struct vc_data {
unsigned char vc_G1_charset;
unsigned char vc_saved_G0;
unsigned char vc_saved_G1;
+ unsigned int vc_resize_user; /* resize request from user */
unsigned int vc_bell_pitch; /* Console bell pitch */
unsigned int vc_bell_duration; /* Console bell duration */
struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */
diff --git a/include/linux/consolemap.h b/include/linux/consolemap.h
index 06b2768c603..e2bf7e5db39 100644
--- a/include/linux/consolemap.h
+++ b/include/linux/consolemap.h
@@ -16,4 +16,5 @@ extern u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode);
extern unsigned short *set_translate(int m, struct vc_data *vc);
extern int conv_uni_to_pc(struct vc_data *conp, long ucs);
extern u32 conv_8bit_to_uni(unsigned char c);
+extern int conv_uni_to_8bit(u32 uni);
void console_map_init(void);
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 0ad72c4cf31..b79c5756936 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -119,8 +119,9 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex)
#define lock_cpu_hotplug() do { } while (0)
#define unlock_cpu_hotplug() do { } while (0)
#define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0)
-#define register_hotcpu_notifier(nb) do { (void)(nb); } while (0)
-#define unregister_hotcpu_notifier(nb) do { (void)(nb); } while (0)
+/* These aren't inline functions due to a GCC bug. */
+#define register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
+#define unregister_hotcpu_notifier(nb) ({ (void)(nb); })
/* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */
static inline int cpu_is_offline(int cpu) { return 0; }
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 826b15e914e..ea44d2e768a 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -45,7 +45,8 @@ static int inline cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
__cpuset_zone_allowed_hardwall(z, gfp_mask);
}
-extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
+extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
+ const struct task_struct *tsk2);
#define cpuset_memory_pressure_bump() \
do { \
@@ -93,7 +94,7 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
return node_possible_map;
}
-#define cpuset_current_mems_allowed (node_online_map)
+#define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY])
static inline void cpuset_init_current_mems_allowed(void) {}
static inline void cpuset_update_task_memory_state(void) {}
#define cpuset_nodes_subset_current_mems_allowed(nodes) (1)
@@ -113,7 +114,8 @@ static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
return 1;
}
-static inline int cpuset_excl_nodes_overlap(const struct task_struct *p)
+static inline int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
+ const struct task_struct *tsk2)
{
return 1;
}
diff --git a/include/linux/cramfs_fs.h b/include/linux/cramfs_fs.h
index 1dba681e428..3be4e5a27d8 100644
--- a/include/linux/cramfs_fs.h
+++ b/include/linux/cramfs_fs.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#define CRAMFS_MAGIC 0x28cd3d45 /* some random number */
+#define CRAMFS_MAGIC_WEND 0x453dcd28 /* magic number with the wrong endianess */
#define CRAMFS_SIGNATURE "Compressed ROMFS"
/*
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 72aa00cc4b2..8f3dcd30828 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -512,11 +512,11 @@ struct cyclades_card {
void __iomem *base_addr;
void __iomem *ctl_addr;
int irq;
- int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */
- int first_line; /* minor number of first channel on card */
- int nports; /* Number of ports in the card */
- int bus_index; /* address shift - 0 for ISA, 1 for PCI */
- int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */
+ unsigned int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */
+ unsigned int first_line; /* minor number of first channel on card */
+ unsigned int nports; /* Number of ports in the card */
+ int bus_index; /* address shift - 0 for ISA, 1 for PCI */
+ int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */
spinlock_t card_lock;
struct cyclades_port *ports;
};
@@ -566,10 +566,9 @@ struct cyclades_port {
int rtsdtr_inv;
int chip_rev;
int custom_divisor;
- int x_char; /* to be pushed out ASAP */
+ u8 x_char; /* to be pushed out ASAP */
int close_delay;
unsigned short closing_wait;
- unsigned long event;
int count; /* # of fd on device */
int breakon;
int breakoff;
@@ -584,7 +583,6 @@ struct cyclades_port {
struct cyclades_monitor mon;
struct cyclades_idle_stats idle_stats;
struct cyclades_icount icount;
- struct work_struct tqueue;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
struct completion shutdown_wait;
@@ -592,19 +590,6 @@ struct cyclades_port {
int throttle;
};
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at cy interrupt time.
- */
-#define Cy_EVENT_READ_PROCESS 0
-#define Cy_EVENT_WRITE_WAKEUP 1
-#define Cy_EVENT_HANGUP 2
-#define Cy_EVENT_BREAK 3
-#define Cy_EVENT_OPEN_WAKEUP 4
-#define Cy_EVENT_SHUTDOWN_WAKEUP 5
-#define Cy_EVENT_DELTA_WAKEUP 6
-#define Cy_EVENT_Z_RX_FULL 7
-
#define CLOSING_WAIT_DELAY 30*HZ
#define CY_CLOSING_WAIT_NONE 65535
#define CY_CLOSING_WAIT_INF 0
diff --git a/include/linux/dca.h b/include/linux/dca.h
new file mode 100644
index 00000000000..83eaecc6f8a
--- /dev/null
+++ b/include/linux/dca.h
@@ -0,0 +1,47 @@
+#ifndef DCA_H
+#define DCA_H
+/* DCA Provider API */
+
+/* DCA Notifier Interface */
+void dca_register_notify(struct notifier_block *nb);
+void dca_unregister_notify(struct notifier_block *nb);
+
+#define DCA_PROVIDER_ADD 0x0001
+#define DCA_PROVIDER_REMOVE 0x0002
+
+struct dca_provider {
+ struct dca_ops *ops;
+ struct class_device *cd;
+ int id;
+};
+
+struct dca_ops {
+ int (*add_requester) (struct dca_provider *, struct device *);
+ int (*remove_requester) (struct dca_provider *, struct device *);
+ u8 (*get_tag) (struct dca_provider *, int cpu);
+};
+
+struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size);
+void free_dca_provider(struct dca_provider *dca);
+int register_dca_provider(struct dca_provider *dca, struct device *dev);
+void unregister_dca_provider(struct dca_provider *dca);
+
+static inline void *dca_priv(struct dca_provider *dca)
+{
+ return (void *)dca + sizeof(struct dca_provider);
+}
+
+/* Requester API */
+int dca_add_requester(struct device *dev);
+int dca_remove_requester(struct device *dev);
+u8 dca_get_tag(int cpu);
+
+/* internal stuff */
+int __init dca_sysfs_init(void);
+void __exit dca_sysfs_exit(void);
+int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev);
+void dca_sysfs_remove_provider(struct dca_provider *dca);
+int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot);
+void dca_sysfs_remove_req(struct dca_provider *dca, int slot);
+
+#endif /* DCA_H */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 2dc21cbeb30..101a2d4636b 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -13,16 +13,28 @@ enum dma_data_direction {
DMA_NONE = 3,
};
-#define DMA_64BIT_MASK 0xffffffffffffffffULL
-#define DMA_48BIT_MASK 0x0000ffffffffffffULL
-#define DMA_40BIT_MASK 0x000000ffffffffffULL
-#define DMA_39BIT_MASK 0x0000007fffffffffULL
-#define DMA_32BIT_MASK 0x00000000ffffffffULL
-#define DMA_31BIT_MASK 0x000000007fffffffULL
-#define DMA_30BIT_MASK 0x000000003fffffffULL
-#define DMA_29BIT_MASK 0x000000001fffffffULL
-#define DMA_28BIT_MASK 0x000000000fffffffULL
-#define DMA_24BIT_MASK 0x0000000000ffffffULL
+#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
+
+/*
+ * NOTE: do not use the below macros in new code and do not add new definitions
+ * here.
+ *
+ * Instead, just open-code DMA_BIT_MASK(n) within your driver
+ */
+#define DMA_64BIT_MASK DMA_BIT_MASK(64)
+#define DMA_48BIT_MASK DMA_BIT_MASK(48)
+#define DMA_47BIT_MASK DMA_BIT_MASK(47)
+#define DMA_40BIT_MASK DMA_BIT_MASK(40)
+#define DMA_39BIT_MASK DMA_BIT_MASK(39)
+#define DMA_35BIT_MASK DMA_BIT_MASK(35)
+#define DMA_32BIT_MASK DMA_BIT_MASK(32)
+#define DMA_31BIT_MASK DMA_BIT_MASK(31)
+#define DMA_30BIT_MASK DMA_BIT_MASK(30)
+#define DMA_29BIT_MASK DMA_BIT_MASK(29)
+#define DMA_28BIT_MASK DMA_BIT_MASK(28)
+#define DMA_24BIT_MASK DMA_BIT_MASK(24)
+
+#define DMA_MASK_NONE 0x0ULL
static inline int valid_dma_direction(int dma_direction)
{
@@ -31,6 +43,11 @@ static inline int valid_dma_direction(int dma_direction)
(dma_direction == DMA_FROM_DEVICE));
}
+static inline int is_device_dma_capable(struct device *dev)
+{
+ return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
+}
+
#ifdef CONFIG_HAS_DMA
#include <asm/dma-mapping.h>
#else
diff --git a/include/linux/elf.h b/include/linux/elf.h
index d2da84acf45..576e83bd6d8 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -2,7 +2,6 @@
#define _LINUX_ELF_H
#include <linux/types.h>
-#include <linux/auxvec.h>
#include <linux/elf-em.h>
#include <asm/elf.h>
@@ -355,6 +354,7 @@ typedef struct elf64_shdr {
#define NT_TASKSTRUCT 4
#define NT_AUXV 6
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
/* Note header in a PT_NOTE section */
diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h
new file mode 100644
index 00000000000..532d13adabc
--- /dev/null
+++ b/include/linux/elfcore-compat.h
@@ -0,0 +1,55 @@
+#ifndef _LINUX_ELFCORE_COMPAT_H
+#define _LINUX_ELFCORE_COMPAT_H
+
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+#include <linux/compat.h>
+
+/*
+ * Make sure these layouts match the linux/elfcore.h native definitions.
+ */
+
+struct compat_elf_siginfo
+{
+ compat_int_t si_signo;
+ compat_int_t si_code;
+ compat_int_t si_errno;
+};
+
+struct compat_elf_prstatus
+{
+ struct compat_elf_siginfo pr_info;
+ short pr_cursig;
+ compat_ulong_t pr_sigpend;
+ compat_ulong_t pr_sighold;
+ compat_pid_t pr_pid;
+ compat_pid_t pr_ppid;
+ compat_pid_t pr_pgrp;
+ compat_pid_t pr_sid;
+ struct compat_timeval pr_utime;
+ struct compat_timeval pr_stime;
+ struct compat_timeval pr_cutime;
+ struct compat_timeval pr_cstime;
+ compat_elf_gregset_t pr_reg;
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ compat_ulong_t pr_exec_fdpic_loadmap;
+ compat_ulong_t pr_interp_fdpic_loadmap;
+#endif
+ compat_int_t pr_fpvalid;
+};
+
+struct compat_elf_prpsinfo
+{
+ char pr_state;
+ char pr_sname;
+ char pr_zomb;
+ char pr_nice;
+ compat_ulong_t pr_flag;
+ compat_uid_t pr_uid;
+ compat_gid_t pr_gid;
+ compat_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ char pr_fname[16];
+ char pr_psargs[ELF_PRARGSZ];
+};
+
+#endif /* _LINUX_ELFCORE_COMPAT_H */
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 153d755376a..c77c3bbfe4b 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -29,11 +29,12 @@
#undef EXT2FS_DEBUG
/*
- * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
+ * Define EXT2_RESERVATION to reserve data blocks for expanding files
*/
-#define EXT2_PREALLOCATE
-#define EXT2_DEFAULT_PREALLOC_BLOCKS 8
-
+#define EXT2_DEFAULT_RESERVE_BLOCKS 8
+/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
+#define EXT2_MAX_RESERVE_BLOCKS 1027
+#define EXT2_RESERVE_WINDOW_NOT_ALLOCATED 0
/*
* The second extended file system version
*/
@@ -200,6 +201,8 @@ struct ext2_group_desc
#define EXT2_IOC_SETFLAGS FS_IOC_SETFLAGS
#define EXT2_IOC_GETVERSION FS_IOC_GETVERSION
#define EXT2_IOC_SETVERSION FS_IOC_SETVERSION
+#define EXT2_IOC_GETRSVSZ _IOR('f', 5, long)
+#define EXT2_IOC_SETRSVSZ _IOW('f', 6, long)
/*
* ioctl commands in 32 bit emulation
@@ -317,8 +320,9 @@ struct ext2_inode {
#define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
#define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */
#define EXT2_MOUNT_XIP 0x010000 /* Execute in place */
-#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
-#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
+#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
+#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
+#define EXT2_MOUNT_RESERVATION 0x080000 /* Preallocation */
#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
@@ -558,4 +562,11 @@ enum {
#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
~EXT2_DIR_ROUND)
+static inline ext2_fsblk_t
+ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
+{
+ return group_no * (ext2_fsblk_t)EXT2_BLOCKS_PER_GROUP(sb) +
+ le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block);
+}
+
#endif /* _LINUX_EXT2_FS_H */
diff --git a/include/linux/ext2_fs_sb.h b/include/linux/ext2_fs_sb.h
index d149f2959e6..f273415ab6f 100644
--- a/include/linux/ext2_fs_sb.h
+++ b/include/linux/ext2_fs_sb.h
@@ -18,6 +18,52 @@
#include <linux/blockgroup_lock.h>
#include <linux/percpu_counter.h>
+#include <linux/rbtree.h>
+
+/* XXX Here for now... not interested in restructing headers JUST now */
+
+/* data type for block offset of block group */
+typedef int ext2_grpblk_t;
+
+/* data type for filesystem-wide blocks number */
+typedef unsigned long ext2_fsblk_t;
+
+#define E2FSBLK "%lu"
+
+struct ext2_reserve_window {
+ ext2_fsblk_t _rsv_start; /* First byte reserved */
+ ext2_fsblk_t _rsv_end; /* Last byte reserved or 0 */
+};
+
+struct ext2_reserve_window_node {
+ struct rb_node rsv_node;
+ __u32 rsv_goal_size;
+ __u32 rsv_alloc_hit;
+ struct ext2_reserve_window rsv_window;
+};
+
+struct ext2_block_alloc_info {
+ /* information about reservation window */
+ struct ext2_reserve_window_node rsv_window_node;
+ /*
+ * was i_next_alloc_block in ext2_inode_info
+ * is the logical (file-relative) number of the
+ * most-recently-allocated block in this file.
+ * We use this for detecting linearly ascending allocation requests.
+ */
+ __u32 last_alloc_logical_block;
+ /*
+ * Was i_next_alloc_goal in ext2_inode_info
+ * is the *physical* companion to i_next_alloc_block.
+ * it the the physical block number of the block which was most-recentl
+ * allocated to this file. This give us the goal (target) for the next
+ * allocation when we detect linearly ascending requests.
+ */
+ ext2_fsblk_t last_alloc_physical_block;
+};
+
+#define rsv_start rsv_window._rsv_start
+#define rsv_end rsv_window._rsv_end
/*
* second extended-fs super-block data in memory
@@ -39,6 +85,7 @@ struct ext2_sb_info {
struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
+ unsigned long s_sb_block;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;
@@ -55,6 +102,10 @@ struct ext2_sb_info {
struct percpu_counter s_freeinodes_counter;
struct percpu_counter s_dirs_counter;
struct blockgroup_lock s_blockgroup_lock;
+ /* root of the per fs reservation window tree */
+ spinlock_t s_rsv_window_lock;
+ struct rb_root s_rsv_window_root;
+ struct ext2_reserve_window_node s_rsv_window_head;
};
#endif /* _LINUX_EXT2_FS_SB */
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index ece49a804fe..64134456ed8 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -35,10 +35,6 @@
/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
#define EXT3_MAX_RESERVE_BLOCKS 1027
#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0
-/*
- * Always enable hashed directories
- */
-#define CONFIG_EXT3_INDEX
/*
* Debug code
@@ -76,8 +72,8 @@
* Macro-instructions used to manage several block sizes
*/
#define EXT3_MIN_BLOCK_SIZE 1024
-#define EXT3_MAX_BLOCK_SIZE 4096
-#define EXT3_MIN_BLOCK_LOG_SIZE 10
+#define EXT3_MAX_BLOCK_SIZE 65536
+#define EXT3_MIN_BLOCK_LOG_SIZE 10
#ifdef __KERNEL__
# define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize)
#else
@@ -665,17 +661,11 @@ struct ext3_dir_entry_2 {
* (c) Daniel Phillips, 2001
*/
-#ifdef CONFIG_EXT3_INDEX
- #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
- EXT3_FEATURE_COMPAT_DIR_INDEX) && \
+#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \
+ EXT3_FEATURE_COMPAT_DIR_INDEX) && \
(EXT3_I(dir)->i_flags & EXT3_INDEX_FL))
#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX)
#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-#else
- #define is_dx(dir) 0
-#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
-#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-#endif
/* Legal values for the dx_root hash_version field: */
diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
index d3c08353edf..b65f0288b84 100644
--- a/include/linux/ext3_fs_sb.h
+++ b/include/linux/ext3_fs_sb.h
@@ -44,6 +44,7 @@ struct ext3_sb_info {
struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
+ ext3_fsblk_t s_sb_block;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h
index cdee7aaa57a..97dd409d5f4 100644
--- a/include/linux/ext4_fs.h
+++ b/include/linux/ext4_fs.h
@@ -36,10 +36,6 @@
/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */
#define EXT4_MAX_RESERVE_BLOCKS 1027
#define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0
-/*
- * Always enable hashed directories
- */
-#define CONFIG_EXT4_INDEX
/*
* Debug code
@@ -105,37 +101,29 @@
#define EXT4_BLOCK_ALIGN(size, blkbits) ALIGN((size), (1 << (blkbits)))
/*
- * Macro-instructions used to manage fragments
- */
-#define EXT4_MIN_FRAG_SIZE 1024
-#define EXT4_MAX_FRAG_SIZE 4096
-#define EXT4_MIN_FRAG_LOG_SIZE 10
-#ifdef __KERNEL__
-# define EXT4_FRAG_SIZE(s) (EXT4_SB(s)->s_frag_size)
-# define EXT4_FRAGS_PER_BLOCK(s) (EXT4_SB(s)->s_frags_per_block)
-#else
-# define EXT4_FRAG_SIZE(s) (EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-# define EXT4_FRAGS_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s))
-#endif
-
-/*
* Structure of a blocks group descriptor
*/
struct ext4_group_desc
{
- __le32 bg_block_bitmap; /* Blocks bitmap block */
- __le32 bg_inode_bitmap; /* Inodes bitmap block */
- __le32 bg_inode_table; /* Inodes table block */
+ __le32 bg_block_bitmap_lo; /* Blocks bitmap block */
+ __le32 bg_inode_bitmap_lo; /* Inodes bitmap block */
+ __le32 bg_inode_table_lo; /* Inodes table block */
__le16 bg_free_blocks_count; /* Free blocks count */
__le16 bg_free_inodes_count; /* Free inodes count */
__le16 bg_used_dirs_count; /* Directories count */
- __u16 bg_flags;
- __u32 bg_reserved[3];
+ __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
+ __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
+ __le16 bg_itable_unused; /* Unused inodes count */
+ __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
__le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
__le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
__le32 bg_inode_table_hi; /* Inodes table block MSB */
};
+#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
+#define EXT4_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */
+#define EXT4_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */
+
#ifdef __KERNEL__
#include <linux/ext4_fs_i.h>
#include <linux/ext4_fs_sb.h>
@@ -311,27 +299,24 @@ struct ext4_inode {
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl; /* File ACL */
__le32 i_dir_acl; /* Directory ACL */
- __le32 i_faddr; /* Fragment address */
+ __le32 i_obso_faddr; /* Obsoleted fragment address */
union {
struct {
- __u8 l_i_frag; /* Fragment number */
- __u8 l_i_fsize; /* Fragment size */
+ __le16 l_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__le16 l_i_file_acl_high;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct {
- __u8 h_i_frag; /* Fragment number */
- __u8 h_i_fsize; /* Fragment size */
+ __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
- __u8 m_i_frag; /* Fragment number */
- __u8 m_i_fsize; /* Fragment size */
+ __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__le16 m_i_file_acl_high;
__u32 m_i_reserved2[2];
} masix2;
@@ -419,8 +404,6 @@ do { \
#if defined(__KERNEL__) || defined(__linux__)
#define i_reserved1 osd1.linux1.l_i_reserved1
-#define i_frag osd2.linux2.l_i_frag
-#define i_fsize osd2.linux2.l_i_fsize
#define i_file_acl_high osd2.linux2.l_i_file_acl_high
#define i_uid_low i_uid
#define i_gid_low i_gid
@@ -431,8 +414,6 @@ do { \
#elif defined(__GNU__)
#define i_translator osd1.hurd1.h_i_translator
-#define i_frag osd2.hurd2.h_i_frag;
-#define i_fsize osd2.hurd2.h_i_fsize;
#define i_uid_high osd2.hurd2.h_i_uid_high
#define i_gid_high osd2.hurd2.h_i_gid_high
#define i_author osd2.hurd2.h_i_author
@@ -440,8 +421,6 @@ do { \
#elif defined(__masix__)
#define i_reserved1 osd1.masix1.m_i_reserved1
-#define i_frag osd2.masix2.m_i_frag
-#define i_fsize osd2.masix2.m_i_fsize
#define i_file_acl_high osd2.masix2.m_i_file_acl_high
#define i_reserved2 osd2.masix2.m_i_reserved2
@@ -522,15 +501,15 @@ do { \
*/
struct ext4_super_block {
/*00*/ __le32 s_inodes_count; /* Inodes count */
- __le32 s_blocks_count; /* Blocks count */
- __le32 s_r_blocks_count; /* Reserved blocks count */
- __le32 s_free_blocks_count; /* Free blocks count */
+ __le32 s_blocks_count_lo; /* Blocks count */
+ __le32 s_r_blocks_count_lo; /* Reserved blocks count */
+ __le32 s_free_blocks_count_lo; /* Free blocks count */
/*10*/ __le32 s_free_inodes_count; /* Free inodes count */
__le32 s_first_data_block; /* First Data Block */
__le32 s_log_block_size; /* Block size */
- __le32 s_log_frag_size; /* Fragment size */
+ __le32 s_obso_log_frag_size; /* Obsoleted fragment size */
/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */
- __le32 s_frags_per_group; /* # Fragments per group */
+ __le32 s_obso_frags_per_group; /* Obsoleted fragments per group */
__le32 s_inodes_per_group; /* # Inodes per group */
__le32 s_mtime; /* Mount time */
/*30*/ __le32 s_wtime; /* Write time */
@@ -595,13 +574,13 @@ struct ext4_super_block {
/*150*/ __le32 s_blocks_count_hi; /* Blocks count */
__le32 s_r_blocks_count_hi; /* Reserved blocks count */
__le32 s_free_blocks_count_hi; /* Free blocks count */
- __u16 s_min_extra_isize; /* All inodes have at least # bytes */
- __u16 s_want_extra_isize; /* New inodes should reserve # bytes */
- __u32 s_flags; /* Miscellaneous flags */
- __u16 s_raid_stride; /* RAID stride */
- __u16 s_mmp_interval; /* # seconds to wait in MMP checking */
- __u64 s_mmp_block; /* Block for multi-mount protection */
- __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
+ __le16 s_min_extra_isize; /* All inodes have at least # bytes */
+ __le16 s_want_extra_isize; /* New inodes should reserve # bytes */
+ __le32 s_flags; /* Miscellaneous flags */
+ __le16 s_raid_stride; /* RAID stride */
+ __le16 s_mmp_interval; /* # seconds to wait in MMP checking */
+ __le64 s_mmp_block; /* Block for multi-mount protection */
+ __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
__u32 s_reserved[163]; /* Padding to the end of the block */
};
@@ -692,6 +671,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
@@ -702,15 +682,18 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
#define EXT4_FEATURE_INCOMPAT_META_BG 0x0010
#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
+#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
#define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
#define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \
EXT4_FEATURE_INCOMPAT_RECOVER| \
EXT4_FEATURE_INCOMPAT_META_BG| \
EXT4_FEATURE_INCOMPAT_EXTENTS| \
- EXT4_FEATURE_INCOMPAT_64BIT)
+ EXT4_FEATURE_INCOMPAT_64BIT| \
+ EXT4_FEATURE_INCOMPAT_FLEX_BG)
#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
@@ -789,17 +772,11 @@ struct ext4_dir_entry_2 {
* (c) Daniel Phillips, 2001
*/
-#ifdef CONFIG_EXT4_INDEX
- #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
- EXT4_FEATURE_COMPAT_DIR_INDEX) && \
+#define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \
+ EXT4_FEATURE_COMPAT_DIR_INDEX) && \
(EXT4_I(dir)->i_flags & EXT4_INDEX_FL))
#define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX)
#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1)
-#else
- #define is_dx(dir) 0
-#define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX)
-#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
-#endif
/* Legal values for the dx_root hash_version field: */
@@ -1004,39 +981,39 @@ extern void ext4_inode_table_set(struct super_block *sb,
static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
{
return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
- le32_to_cpu(es->s_blocks_count);
+ le32_to_cpu(es->s_blocks_count_lo);
}
static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es)
{
return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
- le32_to_cpu(es->s_r_blocks_count);
+ le32_to_cpu(es->s_r_blocks_count_lo);
}
static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es)
{
return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) |
- le32_to_cpu(es->s_free_blocks_count);
+ le32_to_cpu(es->s_free_blocks_count_lo);
}
static inline void ext4_blocks_count_set(struct ext4_super_block *es,
ext4_fsblk_t blk)
{
- es->s_blocks_count = cpu_to_le32((u32)blk);
+ es->s_blocks_count_lo = cpu_to_le32((u32)blk);
es->s_blocks_count_hi = cpu_to_le32(blk >> 32);
}
static inline void ext4_free_blocks_count_set(struct ext4_super_block *es,
ext4_fsblk_t blk)
{
- es->s_free_blocks_count = cpu_to_le32((u32)blk);
+ es->s_free_blocks_count_lo = cpu_to_le32((u32)blk);
es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32);
}
static inline void ext4_r_blocks_count_set(struct ext4_super_block *es,
ext4_fsblk_t blk)
{
- es->s_r_blocks_count = cpu_to_le32((u32)blk);
+ es->s_r_blocks_count_lo = cpu_to_le32((u32)blk);
es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
}
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
index 81406f3655d..d2045a26195 100644
--- a/include/linux/ext4_fs_extents.h
+++ b/include/linux/ext4_fs_extents.h
@@ -74,7 +74,7 @@ struct ext4_extent {
__le32 ee_block; /* first logical block extent covers */
__le16 ee_len; /* number of blocks covered by extent */
__le16 ee_start_hi; /* high 16 bits of physical block */
- __le32 ee_start; /* low 32 bits of physical block */
+ __le32 ee_start_lo; /* low 32 bits of physical block */
};
/*
@@ -83,7 +83,7 @@ struct ext4_extent {
*/
struct ext4_extent_idx {
__le32 ei_block; /* index covers logical blocks from 'block' */
- __le32 ei_leaf; /* pointer to the physical block of the next *
+ __le32 ei_leaf_lo; /* pointer to the physical block of the next *
* level. leaf or next index could be there */
__le16 ei_leaf_hi; /* high 16 bits of physical block */
__u16 ei_unused;
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h
index 1a511e9905a..86ddfe2089f 100644
--- a/include/linux/ext4_fs_i.h
+++ b/include/linux/ext4_fs_i.h
@@ -78,11 +78,6 @@ struct ext4_ext_cache {
struct ext4_inode_info {
__le32 i_data[15]; /* unconverted */
__u32 i_flags;
-#ifdef EXT4_FRAGMENTS
- __u32 i_faddr;
- __u8 i_frag_no;
- __u8 i_frag_size;
-#endif
ext4_fsblk_t i_file_acl;
__u32 i_dir_acl;
__u32 i_dtime;
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h
index 1b2ffee12be..b40e827cd49 100644
--- a/include/linux/ext4_fs_sb.h
+++ b/include/linux/ext4_fs_sb.h
@@ -28,11 +28,8 @@
* third extended-fs super-block data in memory
*/
struct ext4_sb_info {
- unsigned long s_frag_size; /* Size of a fragment in bytes */
unsigned long s_desc_size; /* Size of a group descriptor in bytes */
- unsigned long s_frags_per_block;/* Number of fragments per block */
unsigned long s_inodes_per_block;/* Number of inodes per block */
- unsigned long s_frags_per_group;/* Number of fragments in a group */
unsigned long s_blocks_per_group;/* Number of blocks in a group */
unsigned long s_inodes_per_group;/* Number of inodes in a group */
unsigned long s_itb_per_group; /* Number of inode table blocks per group */
@@ -45,6 +42,7 @@ struct ext4_sb_info {
struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */
struct buffer_head ** s_group_desc;
unsigned long s_mount_opt;
+ ext4_fsblk_t s_sb_block;
uid_t s_resuid;
gid_t s_resgid;
unsigned short s_mount_state;
diff --git a/include/linux/ext4_jbd2.h b/include/linux/ext4_jbd2.h
index d716e6392cf..38c71d3c8db 100644
--- a/include/linux/ext4_jbd2.h
+++ b/include/linux/ext4_jbd2.h
@@ -12,8 +12,8 @@
* Ext4-specific journaling extensions.
*/
-#ifndef _LINUX_EXT4_JBD_H
-#define _LINUX_EXT4_JBD_H
+#ifndef _LINUX_EXT4_JBD2_H
+#define _LINUX_EXT4_JBD2_H
#include <linux/fs.h>
#include <linux/jbd2.h>
@@ -228,4 +228,4 @@ static inline int ext4_should_writeback_data(struct inode *inode)
return 0;
}
-#endif /* _LINUX_EXT4_JBD_H */
+#endif /* _LINUX_EXT4_JBD2_H */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index cec54106aa8..58c57a33e5d 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -180,6 +180,7 @@ struct fb_bitfield {
};
#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
+#define FB_NONSTD_REV_PIX_IN_B 2 /* order of pixels in each byte is reversed */
#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
@@ -206,6 +207,7 @@ struct fb_bitfield {
#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
#define FB_VMODE_INTERLACED 1 /* interlaced */
#define FB_VMODE_DOUBLE 2 /* double scan */
+#define FB_VMODE_ODD_FLD_FIRST 4 /* interlaced: top line first */
#define FB_VMODE_MASK 255
#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
@@ -1054,6 +1056,7 @@ struct fb_videomode {
u32 flag;
};
+extern const char *fb_mode_option;
extern const struct fb_videomode vesa_modes[];
struct fb_modelist {
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 40b93265d4b..86037400a6e 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -3,12 +3,17 @@
#include <asm/fcntl.h>
-/* Cancel a blocking posix lock; internal use only until we expose an
- * asynchronous lock api to userspace: */
-#define F_CANCELLK (F_LINUX_SPECIFIC_BASE+5)
+#define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
+#define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
-#define F_SETLEASE (F_LINUX_SPECIFIC_BASE+0)
-#define F_GETLEASE (F_LINUX_SPECIFIC_BASE+1)
+/*
+ * Cancel a blocking posix lock; internal use only until we expose an
+ * asynchronous lock api to userspace:
+ */
+#define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
+
+/* Create a file descriptor with FD_CLOEXEC set. */
+#define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
/*
* Request nofications on a directory.
diff --git a/include/linux/file.h b/include/linux/file.h
index 0114fbc7806..56023c74e9f 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -62,6 +62,15 @@ extern struct kmem_cache *filp_cachep;
extern void FASTCALL(__fput(struct file *));
extern void FASTCALL(fput(struct file *));
+struct file_operations;
+struct vfsmount;
+struct dentry;
+extern int init_file(struct file *, struct vfsmount *mnt,
+ struct dentry *dentry, mode_t mode,
+ const struct file_operations *fop);
+extern struct file *alloc_file(struct vfsmount *, struct dentry *dentry,
+ mode_t mode, const struct file_operations *fop);
+
static inline void fput_light(struct file *file, int fput_needed)
{
if (unlikely(fput_needed))
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 91b2e3b9251..ddfa0372a3b 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -146,6 +146,7 @@ struct sock;
extern unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen);
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
+extern int sk_detach_filter(struct sock *sk);
extern int sk_chk_filter(struct sock_filter *filter, int flen);
#endif /* __KERNEL__ */
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 1a45d6f41b0..0f0e271f97f 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -178,6 +178,7 @@ union fw_cdev_event {
#define FW_CDEV_IOC_QUEUE_ISO _IOWR('#', 0x09, struct fw_cdev_queue_iso)
#define FW_CDEV_IOC_START_ISO _IOW('#', 0x0a, struct fw_cdev_start_iso)
#define FW_CDEV_IOC_STOP_ISO _IOW('#', 0x0b, struct fw_cdev_stop_iso)
+#define FW_CDEV_IOC_GET_CYCLE_TIMER _IOR('#', 0x0c, struct fw_cdev_get_cycle_timer)
/* FW_CDEV_VERSION History
*
@@ -459,4 +460,18 @@ struct fw_cdev_stop_iso {
__u32 handle;
};
+/**
+ * struct fw_cdev_get_cycle_timer - read cycle timer register
+ * @local_time: system time, in microseconds since the Epoch
+ * @cycle_timer: isochronous cycle timer, as per OHCI 1.1 clause 5.13
+ *
+ * The %FW_CDEV_IOC_GET_CYCLE_TIMER ioctl reads the isochronous cycle timer
+ * and also the system clock. This allows to express the receive time of an
+ * isochronous packet as a system time with microsecond accuracy.
+ */
+struct fw_cdev_get_cycle_timer {
+ __u64 local_time;
+ __u32 cycle_timer;
+};
+
#endif /* _LINUX_FIREWIRE_CDEV_H */
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index efded00ad08..08934995c7a 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -4,6 +4,7 @@
#define FREEZER_H_INCLUDED
#include <linux/sched.h>
+#include <linux/wait.h>
#ifdef CONFIG_PM_SLEEP
/*
@@ -126,6 +127,36 @@ static inline void set_freezable(void)
current->flags &= ~PF_NOFREEZE;
}
+/*
+ * Freezer-friendly wrappers around wait_event_interruptible() and
+ * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
+ */
+
+#define wait_event_freezable(wq, condition) \
+({ \
+ int __retval; \
+ do { \
+ __retval = wait_event_interruptible(wq, \
+ (condition) || freezing(current)); \
+ if (__retval && !freezing(current)) \
+ break; \
+ else if (!(condition)) \
+ __retval = -ERESTARTSYS; \
+ } while (try_to_freeze()); \
+ __retval; \
+})
+
+
+#define wait_event_freezable_timeout(wq, condition, timeout) \
+({ \
+ long __retval = timeout; \
+ do { \
+ __retval = wait_event_interruptible_timeout(wq, \
+ (condition) || freezing(current), \
+ __retval); \
+ } while (try_to_freeze()); \
+ __retval; \
+})
#else /* !CONFIG_PM_SLEEP */
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
@@ -143,6 +174,13 @@ static inline void freezer_do_not_count(void) {}
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {}
+
+#define wait_event_freezable(wq, condition) \
+ wait_event_interruptible(wq, condition)
+
+#define wait_event_freezable_timeout(wq, condition, timeout) \
+ wait_event_interruptible_timeout(wq, condition, timeout)
+
#endif /* !CONFIG_PM_SLEEP */
#endif /* FREEZER_H_INCLUDED */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 16421f662a7..6a4d170ad9a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -283,7 +283,6 @@ extern int dir_notify_enable;
#include <linux/init.h>
#include <linux/pid.h>
#include <linux/mutex.h>
-#include <linux/sysctl.h>
#include <linux/capability.h>
#include <asm/atomic.h>
@@ -301,9 +300,9 @@ struct kstatfs;
struct vm_area_struct;
struct vfsmount;
-extern void __init inode_init(unsigned long);
+extern void __init inode_init(void);
extern void __init inode_init_early(void);
-extern void __init mnt_init(unsigned long);
+extern void __init mnt_init(void);
extern void __init files_init(unsigned long);
struct buffer_head;
@@ -330,6 +329,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
#define ATTR_KILL_SUID 2048
#define ATTR_KILL_SGID 4096
#define ATTR_FILE 8192
+#define ATTR_KILL_PRIV 16384
+#define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */
/*
* This is the Inode Attributes structure, used for notify_change(). It
@@ -381,7 +382,7 @@ struct iattr {
* trying again. The aop will be taking reasonable
* precautions not to livelock. If the caller held a page
* reference, it should drop it before retrying. Returned
- * by readpage(), prepare_write(), and commit_write().
+ * by readpage().
*
* address_space_operation functions return these large constants to indicate
* special semantics to the caller. These are much larger than the bytes in a
@@ -394,6 +395,9 @@ enum positive_aop_returns {
AOP_TRUNCATED_PAGE = 0x80001,
};
+#define AOP_FLAG_UNINTERRUPTIBLE 0x0001 /* will not do a short write */
+#define AOP_FLAG_CONT_EXPAND 0x0002 /* called from cont_expand */
+
/*
* oh the beauties of C type declarations.
*/
@@ -401,6 +405,39 @@ struct page;
struct address_space;
struct writeback_control;
+struct iov_iter {
+ const struct iovec *iov;
+ unsigned long nr_segs;
+ size_t iov_offset;
+ size_t count;
+};
+
+size_t iov_iter_copy_from_user_atomic(struct page *page,
+ struct iov_iter *i, unsigned long offset, size_t bytes);
+size_t iov_iter_copy_from_user(struct page *page,
+ struct iov_iter *i, unsigned long offset, size_t bytes);
+void iov_iter_advance(struct iov_iter *i, size_t bytes);
+int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
+size_t iov_iter_single_seg_count(struct iov_iter *i);
+
+static inline void iov_iter_init(struct iov_iter *i,
+ const struct iovec *iov, unsigned long nr_segs,
+ size_t count, size_t written)
+{
+ i->iov = iov;
+ i->nr_segs = nr_segs;
+ i->iov_offset = 0;
+ i->count = count + written;
+
+ iov_iter_advance(i, written);
+}
+
+static inline size_t iov_iter_count(struct iov_iter *i)
+{
+ return i->count;
+}
+
+
struct address_space_operations {
int (*writepage)(struct page *page, struct writeback_control *wbc);
int (*readpage)(struct file *, struct page *);
@@ -421,6 +458,14 @@ struct address_space_operations {
*/
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
+
+ int (*write_begin)(struct file *, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
+ int (*write_end)(struct file *, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata);
+
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidatepage) (struct page *, unsigned long);
@@ -435,6 +480,18 @@ struct address_space_operations {
int (*launder_page) (struct page *);
};
+/*
+ * pagecache_write_begin/pagecache_write_end must be used by general code
+ * to write into the pagecache.
+ */
+int pagecache_write_begin(struct file *, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
+
+int pagecache_write_end(struct file *, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata);
+
struct backing_dev_info;
struct address_space {
struct inode *host; /* owner: inode, block_device */
@@ -697,16 +754,14 @@ struct fown_struct {
* Track a single file's readahead state
*/
struct file_ra_state {
- pgoff_t start; /* where readahead started */
- unsigned long size; /* # of readahead pages */
- unsigned long async_size; /* do asynchronous readahead when
+ pgoff_t start; /* where readahead started */
+ unsigned int size; /* # of readahead pages */
+ unsigned int async_size; /* do asynchronous readahead when
there are only # of pages ahead */
- unsigned long ra_pages; /* Maximum readahead window */
- unsigned long mmap_hit; /* Cache hit stat for mmap accesses */
- unsigned long mmap_miss; /* Cache miss stat for mmap accesses */
- unsigned long prev_index; /* Cache last read() position */
- unsigned int prev_offset; /* Offset where last read() ended in a page */
+ unsigned int ra_pages; /* Maximum readahead window */
+ int mmap_miss; /* Cache miss stat for mmap accesses */
+ loff_t prev_pos; /* Cache last read() position */
};
/*
@@ -739,7 +794,7 @@ struct file {
unsigned int f_uid, f_gid;
struct file_ra_state f_ra;
- unsigned long f_version;
+ u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
@@ -883,6 +938,7 @@ extern int vfs_setlease(struct file *, long, struct file_lock **);
extern int lease_modify(struct file_lock **, int);
extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
+extern struct seq_operations locks_seq_operations;
struct fasync_struct {
int magic;
@@ -948,6 +1004,7 @@ struct super_block {
struct list_head s_inodes; /* all inodes */
struct list_head s_dirty; /* dirty inodes */
struct list_head s_io; /* parked for writeback */
+ struct list_head s_more_io; /* parked for more writeback */
struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_files;
@@ -1206,16 +1263,68 @@ struct super_operations {
#endif
};
-/* Inode state bits. Protected by inode_lock. */
-#define I_DIRTY_SYNC 1 /* Not dirty enough for O_DATASYNC */
-#define I_DIRTY_DATASYNC 2 /* Data-related inode changes pending */
-#define I_DIRTY_PAGES 4 /* Data-related inode changes pending */
-#define __I_LOCK 3
+/*
+ * Inode state bits. Protected by inode_lock.
+ *
+ * Three bits determine the dirty state of the inode, I_DIRTY_SYNC,
+ * I_DIRTY_DATASYNC and I_DIRTY_PAGES.
+ *
+ * Four bits define the lifetime of an inode. Initially, inodes are I_NEW,
+ * until that flag is cleared. I_WILL_FREE, I_FREEING and I_CLEAR are set at
+ * various stages of removing an inode.
+ *
+ * Two bits are used for locking and completion notification, I_LOCK and I_SYNC.
+ *
+ * I_DIRTY_SYNC Inode itself is dirty.
+ * I_DIRTY_DATASYNC Data-related inode changes pending
+ * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean.
+ * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both
+ * are cleared by unlock_new_inode(), called from iget().
+ * I_WILL_FREE Must be set when calling write_inode_now() if i_count
+ * is zero. I_FREEING must be set when I_WILL_FREE is
+ * cleared.
+ * I_FREEING Set when inode is about to be freed but still has dirty
+ * pages or buffers attached or the inode itself is still
+ * dirty.
+ * I_CLEAR Set by clear_inode(). In this state the inode is clean
+ * and can be destroyed.
+ *
+ * Inodes that are I_WILL_FREE, I_FREEING or I_CLEAR are
+ * prohibited for many purposes. iget() must wait for
+ * the inode to be completely released, then create it
+ * anew. Other functions will just ignore such inodes,
+ * if appropriate. I_LOCK is used for waiting.
+ *
+ * I_LOCK Serves as both a mutex and completion notification.
+ * New inodes set I_LOCK. If two processes both create
+ * the same inode, one of them will release its inode and
+ * wait for I_LOCK to be released before returning.
+ * Inodes in I_WILL_FREE, I_FREEING or I_CLEAR state can
+ * also cause waiting on I_LOCK, without I_LOCK actually
+ * being set. find_inode() uses this to prevent returning
+ * nearly-dead inodes.
+ * I_SYNC Similar to I_LOCK, but limited in scope to writeback
+ * of inode dirty data. Having a seperate lock for this
+ * purpose reduces latency and prevents some filesystem-
+ * specific deadlocks.
+ *
+ * Q: Why does I_DIRTY_DATASYNC exist? It appears as if it could be replaced
+ * by (I_DIRTY_SYNC|I_DIRTY_PAGES).
+ * Q: What is the difference between I_WILL_FREE and I_FREEING?
+ * Q: igrab() only checks on (I_FREEING|I_WILL_FREE). Should it also check on
+ * I_CLEAR? If not, why?
+ */
+#define I_DIRTY_SYNC 1
+#define I_DIRTY_DATASYNC 2
+#define I_DIRTY_PAGES 4
+#define I_NEW 8
+#define I_WILL_FREE 16
+#define I_FREEING 32
+#define I_CLEAR 64
+#define __I_LOCK 7
#define I_LOCK (1 << __I_LOCK)
-#define I_FREEING 16
-#define I_CLEAR 32
-#define I_NEW 64
-#define I_WILL_FREE 128
+#define __I_SYNC 8
+#define I_SYNC (1 << __I_SYNC)
#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
@@ -1302,8 +1411,14 @@ struct file_system_type {
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;
+
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
+
+ struct lock_class_key i_lock_key;
+ struct lock_class_key i_mutex_key;
+ struct lock_class_key i_mutex_dir_key;
+ struct lock_class_key i_alloc_sem_key;
};
extern int get_sb_bdev(struct file_system_type *fs_type,
@@ -1369,12 +1484,25 @@ extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size
* Candidates for mandatory locking have the setgid bit set
* but no group execute bit - an otherwise meaningless combination.
*/
-#define MANDATORY_LOCK(inode) \
- (IS_MANDLOCK(inode) && ((inode)->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+
+static inline int __mandatory_lock(struct inode *ino)
+{
+ return (ino->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID;
+}
+
+/*
+ * ... and these candidates should be on MS_MANDLOCK mounted fs,
+ * otherwise these will be advisory locks
+ */
+
+static inline int mandatory_lock(struct inode *ino)
+{
+ return IS_MANDLOCK(ino) && __mandatory_lock(ino);
+}
static inline int locks_verify_locked(struct inode *inode)
{
- if (MANDATORY_LOCK(inode))
+ if (mandatory_lock(inode))
return locks_mandatory_locked(inode);
return 0;
}
@@ -1385,7 +1513,7 @@ static inline int locks_verify_truncate(struct inode *inode,
struct file *filp,
loff_t size)
{
- if (inode->i_flock && MANDATORY_LOCK(inode))
+ if (inode->i_flock && mandatory_lock(inode))
return locks_mandatory_area(
FLOCK_VERIFY_WRITE, inode, filp,
size < inode->i_size ? size : inode->i_size,
@@ -1655,6 +1783,7 @@ extern int bdev_read_only(struct block_device *);
extern int set_blocksize(struct block_device *, int);
extern int sb_set_blocksize(struct super_block *, int);
extern int sb_min_blocksize(struct super_block *, int);
+extern int sb_has_dirty_inodes(struct super_block *);
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
@@ -1813,8 +1942,12 @@ extern int simple_empty(struct dentry *);
extern int simple_readpage(struct file *file, struct page *page);
extern int simple_prepare_write(struct file *file, struct page *page,
unsigned offset, unsigned to);
-extern int simple_commit_write(struct file *file, struct page *page,
- unsigned offset, unsigned to);
+extern int simple_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
+extern int simple_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata);
extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *);
extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
@@ -1952,7 +2085,8 @@ static inline void free_secdata(void *secdata)
{ }
#endif /* CONFIG_SECURITY */
-int proc_nr_files(ctl_table *table, int write, struct file *filp,
+struct ctl_table;
+int proc_nr_files(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 9fbe9d258e2..d0c437028c8 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -6,7 +6,17 @@
See the file COPYING.
*/
-/* This file defines the kernel interface of FUSE */
+/*
+ * This file defines the kernel interface of FUSE
+ *
+ * Protocol changelog:
+ *
+ * 7.9:
+ * - new fuse_getattr_in input argument of GETATTR
+ * - add lk_flags in fuse_lk_in
+ * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
+ * - add blksize field to fuse_attr
+ */
#include <asm/types.h>
#include <linux/major.h>
@@ -15,7 +25,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 8
+#define FUSE_KERNEL_MINOR_VERSION 9
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -44,6 +54,8 @@ struct fuse_attr {
__u32 uid;
__u32 gid;
__u32 rdev;
+ __u32 blksize;
+ __u32 padding;
};
struct fuse_kstatfs {
@@ -76,6 +88,9 @@ struct fuse_file_lock {
#define FATTR_ATIME (1 << 4)
#define FATTR_MTIME (1 << 5)
#define FATTR_FH (1 << 6)
+#define FATTR_ATIME_NOW (1 << 7)
+#define FATTR_MTIME_NOW (1 << 8)
+#define FATTR_LOCKOWNER (1 << 9)
/**
* Flags returned by the OPEN request
@@ -91,12 +106,38 @@ struct fuse_file_lock {
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
+#define FUSE_FILE_OPS (1 << 2)
+#define FUSE_ATOMIC_O_TRUNC (1 << 3)
/**
* Release flags
*/
#define FUSE_RELEASE_FLUSH (1 << 0)
+/**
+ * Getattr flags
+ */
+#define FUSE_GETATTR_FH (1 << 0)
+
+/**
+ * Lock flags
+ */
+#define FUSE_LK_FLOCK (1 << 0)
+
+/**
+ * WRITE flags
+ *
+ * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
+ * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
+ */
+#define FUSE_WRITE_CACHE (1 << 0)
+#define FUSE_WRITE_LOCKOWNER (1 << 1)
+
+/**
+ * Read flags
+ */
+#define FUSE_READ_LOCKOWNER (1 << 1)
+
enum fuse_opcode {
FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */
@@ -139,6 +180,8 @@ enum fuse_opcode {
/* The read buffer is required to be at least 8k, but may be much larger */
#define FUSE_MIN_READ_BUFFER 8192
+#define FUSE_COMPAT_ENTRY_OUT_SIZE 120
+
struct fuse_entry_out {
__u64 nodeid; /* Inode ID */
__u64 generation; /* Inode generation: nodeid:gen must
@@ -154,6 +197,14 @@ struct fuse_forget_in {
__u64 nlookup;
};
+struct fuse_getattr_in {
+ __u32 getattr_flags;
+ __u32 dummy;
+ __u64 fh;
+};
+
+#define FUSE_COMPAT_ATTR_OUT_SIZE 96
+
struct fuse_attr_out {
__u64 attr_valid; /* Cache timeout for the attributes */
__u32 attr_valid_nsec;
@@ -184,7 +235,7 @@ struct fuse_setattr_in {
__u32 padding;
__u64 fh;
__u64 size;
- __u64 unused1;
+ __u64 lock_owner;
__u64 atime;
__u64 mtime;
__u64 unused2;
@@ -227,14 +278,18 @@ struct fuse_read_in {
__u64 fh;
__u64 offset;
__u32 size;
- __u32 padding;
+ __u32 read_flags;
+ __u64 lock_owner;
};
+#define FUSE_COMPAT_WRITE_IN_SIZE 24
+
struct fuse_write_in {
__u64 fh;
__u64 offset;
__u32 size;
__u32 write_flags;
+ __u64 lock_owner;
};
struct fuse_write_out {
@@ -273,6 +328,8 @@ struct fuse_lk_in {
__u64 fh;
__u64 owner;
struct fuse_file_lock lk;
+ __u32 lk_flags;
+ __u32 padding;
};
struct fuse_lk_out {
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index bc68dd9a6d4..7e93a9ae706 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -48,18 +48,12 @@ struct vm_area_struct;
#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
#define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */
#define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */
-#define __GFP_MOVABLE ((__force gfp_t)0x80000u) /* Page is movable */
+#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */
+#define __GFP_MOVABLE ((__force gfp_t)0x100000u) /* Page is movable */
-#define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */
+#define __GFP_BITS_SHIFT 21 /* Room for 21 __GFP_FOO bits */
#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
-/* if you forget to add the bitmask here kernel will crash, period */
-#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
- __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
- __GFP_NOFAIL|__GFP_NORETRY|__GFP_COMP| \
- __GFP_NOMEMALLOC|__GFP_HARDWALL|__GFP_THISNODE| \
- __GFP_MOVABLE)
-
/* This equals 0, but use constants in case they ever change */
#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH)
/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */
@@ -67,6 +61,8 @@ struct vm_area_struct;
#define GFP_NOIO (__GFP_WAIT)
#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_TEMPORARY (__GFP_WAIT | __GFP_IO | __GFP_FS | \
+ __GFP_RECLAIMABLE)
#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
__GFP_HIGHMEM)
@@ -86,6 +82,19 @@ struct vm_area_struct;
#define GFP_THISNODE ((__force gfp_t)0)
#endif
+/* This mask makes up all the page movable related flags */
+#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
+
+/* Control page allocator reclaim behavior */
+#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
+ __GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
+ __GFP_NORETRY|__GFP_NOMEMALLOC)
+
+/* Control allocation constraints */
+#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE)
+
+/* Do not use these with a slab allocator */
+#define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK)
/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
platforms, used as appropriate on others */
@@ -95,25 +104,50 @@ struct vm_area_struct;
/* 4GB DMA on some platforms */
#define GFP_DMA32 __GFP_DMA32
+/* Convert GFP flags to their corresponding migrate type */
+static inline int allocflags_to_migratetype(gfp_t gfp_flags)
+{
+ WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
+
+ if (unlikely(page_group_by_mobility_disabled))
+ return MIGRATE_UNMOVABLE;
+
+ /* Group based on mobility */
+ return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
+ ((gfp_flags & __GFP_RECLAIMABLE) != 0);
+}
static inline enum zone_type gfp_zone(gfp_t flags)
{
+ int base = 0;
+
+#ifdef CONFIG_NUMA
+ if (flags & __GFP_THISNODE)
+ base = MAX_NR_ZONES;
+#endif
+
#ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
- return ZONE_DMA;
+ return base + ZONE_DMA;
#endif
#ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
- return ZONE_DMA32;
+ return base + ZONE_DMA32;
#endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
- return ZONE_MOVABLE;
+ return base + ZONE_MOVABLE;
#ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
- return ZONE_HIGHMEM;
+ return base + ZONE_HIGHMEM;
#endif
- return ZONE_NORMAL;
+ return base + ZONE_NORMAL;
+}
+
+static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
+{
+ BUG_ON((gfp & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
+ return (gfp & ~(GFP_MOVABLE_MASK)) | migrate_flags;
}
/*
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 265d17830a0..c6d3a9de563 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -8,6 +8,7 @@ struct gpio_keys_button {
int active_low;
char *desc;
int type; /* input event type (EV_KEY, EV_SW) */
+ int wakeup; /* configure the button as a wake-up source */
};
struct gpio_keys_platform_data {
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 540799bc85f..7a9398e1970 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -300,7 +300,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);
/* Precise sleep: */
extern long hrtimer_nanosleep(struct timespec *rqtp,
- struct timespec __user *rmtp,
+ struct timespec *rmtp,
const enum hrtimer_mode mode,
const clockid_t clockid);
extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 3a19b032c0e..ea0f50bfbe0 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -33,6 +33,7 @@ void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed);
extern unsigned long max_huge_pages;
extern unsigned long hugepages_treat_as_movable;
+extern int hugetlb_dynamic_pool;
extern const unsigned long hugetlb_zero, hugetlb_infinity;
extern int sysctl_hugetlb_shm_group;
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index a271b67a8e2..88c81403eb3 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -120,6 +120,7 @@
#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */
#define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */
#define I2C_DRIVERID_VP27SMPX 93 /* Panasonic VP27s tuner internal MPX */
+#define I2C_DRIVERID_CS4270 94 /* Cirrus Logic 4270 audio codec */
#define I2C_DRIVERID_I2CDEV 900
#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index 9752307d16b..7da5b98d90e 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -32,6 +32,7 @@
#include <linux/workqueue.h> /* work_struct */
#include <linux/mempool.h>
#include <linux/mutex.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/semaphore.h> /* Needed for MUTEX init macros */
@@ -837,7 +838,7 @@ static inline int i2o_dma_map_sg(struct i2o_controller *c,
if ((sizeof(dma_addr_t) > 4) && c->pae_support)
*mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
#endif
- sg++;
+ sg = sg_next(sg);
}
*sg_ptr = mptr;
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 02a27e8cbad..19db0a4ae44 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -576,7 +576,6 @@ typedef struct ide_drive_s {
select_t select; /* basic drive/head select reg value */
u8 keep_settings; /* restore settings after drive reset */
- u8 autodma; /* device can safely use dma on host */
u8 using_dma; /* disk is using dma for read/write */
u8 retry_pio; /* retrying dma capable host in pio */
u8 state; /* retry state */
@@ -600,6 +599,7 @@ typedef struct ide_drive_s {
unsigned nice0 : 1; /* give obvious excess bandwidth */
unsigned nice2 : 1; /* give a share in our own bandwidth */
unsigned doorlocking : 1; /* for removable only: door lock/unlock works */
+ unsigned nodma : 1; /* disallow DMA */
unsigned autotune : 2; /* 0=default, 1=autotune, 2=noautotune */
unsigned remap_0_to_1 : 1; /* 0=noremap, 1=remap 0->1 (for EZDrive) */
unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */
@@ -685,7 +685,6 @@ typedef struct hwif_s {
u8 pio_mask;
- u8 atapi_dma; /* host supports atapi_dma */
u8 ultra_mask;
u8 mwdma_mask;
u8 swdma_mask;
@@ -736,7 +735,6 @@ typedef struct hwif_s {
void (*dma_exec_cmd)(ide_drive_t *, u8);
void (*dma_start)(ide_drive_t *);
int (*ide_dma_end)(ide_drive_t *drive);
- int (*ide_dma_check)(ide_drive_t *drive);
int (*ide_dma_on)(ide_drive_t *drive);
void (*dma_off_quietly)(ide_drive_t *drive);
int (*ide_dma_test_irq)(ide_drive_t *drive);
@@ -772,7 +770,7 @@ typedef struct hwif_s {
unsigned int nsect;
unsigned int nleft;
- unsigned int cursg;
+ struct scatterlist *cursg;
unsigned int cursg_ofs;
int rqsize; /* max sectors per request */
@@ -798,13 +796,9 @@ typedef struct hwif_s {
unsigned serialized : 1; /* serialized all channel operation */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */
unsigned reset : 1; /* reset after probe */
- unsigned autodma : 1; /* auto-attempt using DMA at boot */
- unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */
- unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
unsigned auto_poll : 1; /* supports nop auto-poll */
unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
- unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
unsigned mmio : 1; /* host uses MMIO */
struct device gendev;
@@ -1093,11 +1087,6 @@ extern ide_startstop_t ide_do_reset (ide_drive_t *);
extern void ide_init_drive_cmd (struct request *rq);
/*
- * this function returns error location sector offset in case of a write error
- */
-extern u64 ide_get_error_location(ide_drive_t *, char *);
-
-/*
* "action" parameter type for ide_do_drive_cmd() below.
*/
typedef enum {
@@ -1218,19 +1207,6 @@ extern void default_hwif_iops(ide_hwif_t *);
extern void default_hwif_mmiops(ide_hwif_t *);
extern void default_hwif_transport(ide_hwif_t *);
-#define ON_BOARD 1
-#define NEVER_BOARD 0
-
-#ifdef CONFIG_BLK_DEV_OFFBOARD
-# define OFF_BOARD ON_BOARD
-#else /* CONFIG_BLK_DEV_OFFBOARD */
-# define OFF_BOARD NEVER_BOARD
-#endif /* CONFIG_BLK_DEV_OFFBOARD */
-
-#define NODMA 0
-#define NOAUTODMA 1
-#define AUTODMA 2
-
typedef struct ide_pci_enablebit_s {
u8 reg; /* byte pci reg holding the enable-bit */
u8 mask; /* mask to isolate the enable-bit */
@@ -1261,24 +1237,52 @@ enum {
IDE_HFLAG_POST_SET_MODE = (1 << 8),
/* don't program host/device for the transfer mode ("smart" hosts) */
IDE_HFLAG_NO_SET_MODE = (1 << 9),
+ /* trust BIOS for programming chipset/device for DMA */
+ IDE_HFLAG_TRUST_BIOS_FOR_DMA = (1 << 10),
+ /* host uses VDMA */
+ IDE_HFLAG_VDMA = (1 << 11),
+ /* ATAPI DMA is unsupported */
+ IDE_HFLAG_NO_ATAPI_DMA = (1 << 12),
+ /* set if host is a "bootable" controller */
+ IDE_HFLAG_BOOTABLE = (1 << 13),
+ /* host doesn't support DMA */
+ IDE_HFLAG_NO_DMA = (1 << 14),
+ /* check if host is PCI IDE device before allowing DMA */
+ IDE_HFLAG_NO_AUTODMA = (1 << 15),
+ /* host is CS5510/CS5520 */
+ IDE_HFLAG_CS5520 = (1 << 16),
+ /* no LBA48 */
+ IDE_HFLAG_NO_LBA48 = (1 << 17),
+ /* no LBA48 DMA */
+ IDE_HFLAG_NO_LBA48_DMA = (1 << 18),
+ /* data FIFO is cleared by an error */
+ IDE_HFLAG_ERROR_STOPS_FIFO = (1 << 19),
+ /* serialize ports */
+ IDE_HFLAG_SERIALIZE = (1 << 20),
+ /* use legacy IRQs */
+ IDE_HFLAG_LEGACY_IRQS = (1 << 21),
};
+#ifdef CONFIG_BLK_DEV_OFFBOARD
+# define IDE_HFLAG_OFF_BOARD IDE_HFLAG_BOOTABLE
+#else
+# define IDE_HFLAG_OFF_BOARD 0
+#endif
+
typedef struct ide_pci_device_s {
char *name;
- int (*init_setup)(struct pci_dev *, struct ide_pci_device_s *);
- void (*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *);
unsigned int (*init_chipset)(struct pci_dev *, const char *);
void (*init_iops)(ide_hwif_t *);
void (*init_hwif)(ide_hwif_t *);
void (*init_dma)(ide_hwif_t *, unsigned long);
void (*fixup)(ide_hwif_t *);
- u8 autodma;
ide_pci_enablebit_t enablebits[2];
- u8 bootable;
unsigned int extra;
struct ide_pci_device_s *next;
- u16 host_flags;
+ u32 host_flags;
u8 pio_mask;
+ u8 swdma_mask;
+ u8 mwdma_mask;
u8 udma_mask;
} ide_pci_device_t;
@@ -1308,7 +1312,6 @@ static inline u8 ide_max_dma_mode(ide_drive_t *drive)
return ide_find_dma_mode(drive, XFER_UDMA_6);
}
-int ide_tune_dma(ide_drive_t *);
void ide_dma_off(ide_drive_t *);
void ide_dma_verbose(ide_drive_t *);
int ide_set_dma(ide_drive_t *);
@@ -1335,7 +1338,6 @@ extern void ide_dma_timeout(ide_drive_t *);
#else
static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
-static inline int ide_tune_dma(ide_drive_t *drive) { return 0; }
static inline void ide_dma_off(ide_drive_t *drive) { ; }
static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
@@ -1385,7 +1387,6 @@ static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data)
extern char *ide_xfer_verbose(u8 xfer_rate);
extern void ide_toggle_bounce(ide_drive_t *drive, int on);
extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
-int ide_use_fast_pio(ide_drive_t *);
static inline int ide_dev_has_iordy(struct hd_driveid *id)
{
@@ -1460,4 +1461,11 @@ static inline int hwif_to_node(ide_hwif_t *hwif)
return dev ? pcibus_to_node(dev->bus) : -1;
}
+static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+
+ return &hwif->drives[(drive->dn ^ 1) & 1];
+}
+
#endif /* _IDE_H */
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 99e3a1a0009..58e43e56645 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -107,7 +107,7 @@ struct __fdb_entry
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
extern struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
struct sk_buff *skb);
-extern int (*br_should_route_hook)(struct sk_buff **pskb);
+extern int (*br_should_route_hook)(struct sk_buff *skb);
#endif
diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h
index 4aba6b0ad41..ae77daed6c2 100644
--- a/include/linux/if_fddi.h
+++ b/include/linux/if_fddi.h
@@ -24,6 +24,8 @@
#ifndef _LINUX_IF_FDDI_H
#define _LINUX_IF_FDDI_H
+#include <linux/types.h>
+
/*
* Define max and min legal sizes. The frame sizes do not include
* 4 byte FCS/CRC (frame check sequence).
diff --git a/include/linux/init.h b/include/linux/init.h
index f8d9d0b5cff..5141381a752 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -67,8 +67,10 @@
/* For assembly routines */
#define __INIT .section ".init.text","ax"
+#define __INIT_REFOK .section ".text.init.refok","ax"
#define __FINIT .previous
#define __INITDATA .section ".init.data","aw"
+#define __INITDATA_REFOK .section ".data.init.refok","aw"
#ifndef __ASSEMBLY__
/*
@@ -159,7 +161,7 @@ struct obs_kernel_param {
* obs_kernel_param "array" too far apart in .init.setup.
*/
#define __setup_param(str, unique_id, fn, early) \
- static char __setup_str_##unique_id[] __initdata = str; \
+ static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
__attribute_used__ \
__attribute__((__section__(".init.setup"))) \
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 513bc3e489f..d4b2f1c76e1 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -76,7 +76,6 @@ extern struct nsproxy init_nsproxy;
#define INIT_NSPROXY(nsproxy) { \
.pid_ns = &init_pid_ns, \
.count = ATOMIC_INIT(1), \
- .nslock = __SPIN_LOCK_UNLOCKED(nsproxy.nslock), \
.uts_ns = &init_uts_ns, \
.mnt_ns = NULL, \
INIT_NET_NS(net_ns) \
@@ -171,6 +170,7 @@ extern struct group_info init_groups;
[PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \
[PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \
}, \
+ .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
}
diff --git a/include/linux/input.h b/include/linux/input.h
index 52d1bd434a5..f30da6fc08e 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -856,7 +856,7 @@ struct ff_rumble_effect {
* defining effect parameters
*
* This structure is sent through ioctl from the application to the driver.
- * To create a new effect aplication should set its @id to -1; the kernel
+ * To create a new effect application should set its @id to -1; the kernel
* will return assigned @id which can later be used to update or delete
* this effect.
*
@@ -936,9 +936,82 @@ struct ff_effect {
#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
+ * @phys: physical path to the device in the system hierarchy
+ * @uniq: unique identification code for the device (if device has it)
+ * @id: id of the device (struct input_id)
+ * @evbit: bitmap of types of events supported by the device (EV_KEY,
+ * EV_REL, etc.)
+ * @keybit: bitmap of keys/buttons this device has
+ * @relbit: bitmap of relative axes for the device
+ * @absbit: bitmap of absolute axes for the device
+ * @mscbit: bitmap of miscellaneous events supported by the device
+ * @ledbit: bitmap of leds present on the device
+ * @sndbit: bitmap of sound effects supported by the device
+ * @ffbit: bitmap of force feedback effects supported by the device
+ * @swbit: bitmap of switches present on the device
+ * @keycodemax: size of keycode table
+ * @keycodesize: size of elements in keycode table
+ * @keycode: map of scancodes to keycodes for this device
+ * @setkeycode: optional method to alter current keymap, used to implement
+ * sparse keymaps. If not supplied default mechanism will be used
+ * @getkeycode: optional method to retrieve current keymap. If not supplied
+ * default mechanism will be used
+ * @ff: force feedback structure associated with the device if device
+ * supports force feedback effects
+ * @repeat_key: stores key code of the last key pressed; used to implement
+ * software autorepeat
+ * @timer: timer for software autorepeat
+ * @sync: set to 1 when there were no new events since last EV_SYNC
+ * @abs: current values for reports from absolute axes
+ * @rep: current values for autorepeat parameters (delay, rate)
+ * @key: reflects current state of device's keys/buttons
+ * @led: reflects current state of device's LEDs
+ * @snd: reflects current state of sound effects
+ * @sw: reflects current state of device's switches
+ * @absmax: maximum values for events coming from absolute axes
+ * @absmin: minimum values for events coming from absolute axes
+ * @absfuzz: describes noisiness for axes
+ * @absflat: size of the center flat position (used by joydev)
+ * @open: this method is called when the very first user calls
+ * input_open_device(). The driver must prepare the device
+ * to start generating events (start polling thread,
+ * request an IRQ, submit URB, etc.)
+ * @close: this method is called when the very last user calls
+ * input_close_device().
+ * @flush: purges the device. Most commonly used to get rid of force
+ * feedback effects loaded into the device when disconnecting
+ * from it
+ * @event: event handler for events sent _to_ the device, like EV_LED
+ * or EV_SND. The device is expected to carry out the requested
+ * action (turn on a LED, play sound, etc.) The call is protected
+ * by @event_lock and must not sleep
+ * @grab: input handle that currently has the device grabbed (via
+ * EVIOCGRAB ioctl). When a handle grabs a device it becomes sole
+ * recipient for all input events coming from the device
+ * @event_lock: this spinlock is is taken when input core receives
+ * and processes a new event for the device (in input_event()).
+ * Code that accesses and/or modifies parameters of a device
+ * (such as keymap or absmin, absmax, absfuzz, etc.) after device
+ * has been registered with input core must take this lock.
+ * @mutex: serializes calls to open(), close() and flush() methods
+ * @users: stores number of users (input handlers) that opened this
+ * device. It is used by input_open_device() and input_close_device()
+ * to make sure that dev->open() is only called when the first
+ * user opens device and dev->close() is called when the very
+ * last user closes the device
+ * @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
+ * @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 {
- void *private;
+ void *private; /* do not use */
const char *name;
const char *phys;
@@ -966,8 +1039,6 @@ struct input_dev {
unsigned int repeat_key;
struct timer_list timer;
- int state;
-
int sync;
int abs[ABS_MAX + 1];
@@ -990,8 +1061,11 @@ struct input_dev {
struct input_handle *grab;
- struct mutex mutex; /* serializes open and close operations */
+ spinlock_t event_lock;
+ struct mutex mutex;
+
unsigned int users;
+ int going_away;
struct device dev;
union { /* temporarily so while we switching to struct device */
@@ -1057,7 +1131,9 @@ struct input_handle;
/**
* struct input_handler - implements one of interfaces for input devices
* @private: driver-specific data
- * @event: event handler
+ * @event: event handler. This method is being called by input core with
+ * interrupts disabled and dev->event_lock spinlock held and so
+ * it may not sleep
* @connect: called when attaching a handler to an input device
* @disconnect: disconnects a handler from input device
* @start: starts handler for given handle. This function is called by
@@ -1069,10 +1145,18 @@ struct input_handle;
* @name: name of the handler, to be shown in /proc/bus/input/handlers
* @id_table: pointer to a table of input_device_ids this driver can
* handle
- * @blacklist: prointer to a table of input_device_ids this driver should
+ * @blacklist: pointer to a table of input_device_ids this driver should
* ignore even if they match @id_table
* @h_list: list of input handles associated with the handler
* @node: for placing the driver onto input_handler_list
+ *
+ * Input handlers attach to input devices and create input handles. There
+ * are likely several handlers attached to any given input device at the
+ * same time. All of them will get their copy of input event generated by
+ * the device.
+ *
+ * Note that input core serializes calls to connect() and disconnect()
+ * methods.
*/
struct input_handler {
@@ -1094,6 +1178,18 @@ struct input_handler {
struct list_head node;
};
+/**
+ * struct input_handle - links input device with an input handler
+ * @private: handler-specific data
+ * @open: counter showing whether the handle is 'open', i.e. should deliver
+ * events from its device
+ * @name: name given to the handle by handler that created it
+ * @dev: input device the handle is attached to
+ * @handler: handler that works with the device through this handle
+ * @d_node: used to put the handle on device's list of attached handles
+ * @h_node: used to put the handle on handler's list of handles from which
+ * it gets events
+ */
struct input_handle {
void *private;
@@ -1136,10 +1232,10 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data)
dev->private = data;
}
-int input_register_device(struct input_dev *);
+int __must_check input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *);
-int input_register_handler(struct input_handler *);
+int __must_check input_register_handler(struct input_handler *);
void input_unregister_handler(struct input_handler *);
int input_register_handle(struct input_handle *);
@@ -1216,7 +1312,7 @@ extern struct class input_class;
* @max_effects: maximum number of effects supported by device
* @effects: pointer to an array of effects currently loaded into device
* @effect_owners: array of effect owners; when file handle owning
- * an effect gets closed the effcet is automatically erased
+ * an effect gets closed the effect is automatically erased
*
* Every force-feedback device must implement upload() and playback()
* methods; erase() is optional. set_gain() and set_autocenter() need
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 5523f19d88d..2306920fa38 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -55,28 +55,6 @@
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
-/*
- * Migration helpers. Scheduled for removal in 9/2007
- * Do not use for new code !
- */
-static inline
-unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
-{
- return flag;
-}
-
-#define SA_INTERRUPT deprecated_irq_flag(IRQF_DISABLED)
-#define SA_SAMPLE_RANDOM deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
-#define SA_SHIRQ deprecated_irq_flag(IRQF_SHARED)
-#define SA_PROBEIRQ deprecated_irq_flag(IRQF_PROBE_SHARED)
-#define SA_PERCPU deprecated_irq_flag(IRQF_PERCPU)
-
-#define SA_TRIGGER_LOW deprecated_irq_flag(IRQF_TRIGGER_LOW)
-#define SA_TRIGGER_HIGH deprecated_irq_flag(IRQF_TRIGGER_HIGH)
-#define SA_TRIGGER_FALLING deprecated_irq_flag(IRQF_TRIGGER_FALLING)
-#define SA_TRIGGER_RISING deprecated_irq_flag(IRQF_TRIGGER_RISING)
-#define SA_TRIGGER_MASK deprecated_irq_flag(IRQF_TRIGGER_MASK)
-
typedef irqreturn_t (*irq_handler_t)(int, void *);
struct irqaction {
@@ -205,6 +183,15 @@ static inline int disable_irq_wake(unsigned int irq)
enable_irq(irq)
# endif
+static inline int enable_irq_wake(unsigned int irq)
+{
+ return 0;
+}
+
+static inline int disable_irq_wake(unsigned int irq)
+{
+ return 0;
+}
#endif /* CONFIG_GENERIC_HARDIRQS */
#ifndef __ARCH_SET_SOFTIRQ_PENDING
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ea9231924..6187a8567bc 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -110,9 +110,6 @@ extern int allocate_resource(struct resource *root, struct resource *new,
int adjust_resource(struct resource *res, resource_size_t start,
resource_size_t size);
-/* get registered SYSTEM_RAM resources in specified area */
-extern int find_next_system_ram(struct resource *res);
-
/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 3fd3ddd5f0d..ee111834091 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -49,6 +49,34 @@ struct ipc_perm
#define IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger
message sizes, etc. */
+/*
+ * These are used to wrap system calls.
+ *
+ * See architecture code for ugly details..
+ */
+struct ipc_kludge {
+ struct msgbuf __user *msgp;
+ long msgtyp;
+};
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define SEMTIMEDOP 4
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+/* Used by the DIPC package, try and avoid reusing it */
+#define DIPC 25
+
+#define IPCCALL(version,op) ((version)<<16 | (op))
+
#ifdef __KERNEL__
#include <linux/kref.h>
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 7a9db390c56..c5bd28b69ae 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -365,6 +365,16 @@ int ipmi_request_supply_msgs(ipmi_user_t user,
int priority);
/*
+ * Poll the IPMI interface for the user. This causes the IPMI code to
+ * do an immediate check for information from the driver and handle
+ * anything that is immediately pending. This will not block in any
+ * way. This is useful if you need to implement polling from the user
+ * for things like modifying the watchdog timeout when a panic occurs
+ * or disabling the watchdog timer on a reboot.
+ */
+void ipmi_poll_interface(ipmi_user_t user);
+
+/*
* When commands come in to the SMS, the user can register to receive
* them. Only one user can be listening on a specific netfn/cmd/chan tuple
* at a time, you will get an EBUSY error if the command is already
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index c0633108d05..efa292a52e7 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -148,26 +148,46 @@ struct ipmi_device_id {
/* Take a pointer to a raw data buffer and a length and extract device
id information from it. The first byte of data must point to the
- byte from the get device id response after the completion code.
- The caller is responsible for making sure the length is at least
- 11 and the command completed without error. */
-static inline void ipmi_demangle_device_id(unsigned char *data,
- unsigned int data_len,
- struct ipmi_device_id *id)
+ netfn << 2, the data should be of the format:
+ netfn << 2, cmd, completion code, data
+ as normally comes from a device interface. */
+static inline int ipmi_demangle_device_id(const unsigned char *data,
+ unsigned int data_len,
+ struct ipmi_device_id *id)
{
+ if (data_len < 9)
+ return -EINVAL;
+ if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 ||
+ data[1] != IPMI_GET_DEVICE_ID_CMD)
+ /* Strange, didn't get the response we expected. */
+ return -EINVAL;
+ if (data[2] != 0)
+ /* That's odd, it shouldn't be able to fail. */
+ return -EINVAL;
+
+ data += 3;
+ data_len -= 3;
id->device_id = data[0];
id->device_revision = data[1];
id->firmware_revision_1 = data[2];
id->firmware_revision_2 = data[3];
id->ipmi_version = data[4];
id->additional_device_support = data[5];
- id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16);
- id->product_id = data[9] | (data[10] << 8);
+ if (data_len >= 6) {
+ id->manufacturer_id = (data[6] | (data[7] << 8) |
+ (data[8] << 16));
+ id->product_id = data[9] | (data[10] << 8);
+ } else {
+ id->manufacturer_id = 0;
+ id->product_id = 0;
+ }
if (data_len >= 15) {
memcpy(id->aux_firmware_revision, data+11, 4);
id->aux_firmware_revision_set = 1;
} else
id->aux_firmware_revision_set = 0;
+
+ return 0;
}
/* Add a low-level interface to the IPMI driver. Note that if the
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index ad09506554a..d0ecc8eebfb 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -167,6 +167,7 @@ typedef struct {
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/tcp.h>
+#include <linux/mutex.h>
#define ISDN_TTY_MAJOR 43
#define ISDN_TTYAUX_MAJOR 44
@@ -286,7 +287,6 @@ typedef struct {
/* Local interface-data */
typedef struct isdn_net_local_s {
ulong magic;
- char name[10]; /* Name of device */
struct net_device_stats stats; /* Ethernet Statistics */
int isdn_device; /* Index to isdn-device */
int isdn_channel; /* Index to isdn-channel */
@@ -617,7 +617,7 @@ typedef struct isdn_devt {
int v110emu[ISDN_MAX_CHANNELS]; /* V.110 emulator-mode 0=none */
atomic_t v110use[ISDN_MAX_CHANNELS]; /* Usage-Semaphore for stream */
isdn_v110_stream *v110[ISDN_MAX_CHANNELS]; /* V.110 private data */
- struct semaphore sem; /* serialize list access*/
+ struct mutex mtx; /* serialize list access*/
unsigned long global_features;
} isdn_dev;
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 45273755126..a3abf51e488 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -30,6 +30,7 @@
#include <linux/bit_spinlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
+#include <linux/lockdep.h>
#include <asm/semaphore.h>
#endif
@@ -71,14 +72,15 @@ extern int journal_enable_debug;
#define jbd_debug(f, a...) /**/
#endif
-extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
-extern void * jbd_slab_alloc(size_t size, gfp_t flags);
-extern void jbd_slab_free(void *ptr, size_t size);
+static inline void *jbd_alloc(size_t size, gfp_t flags)
+{
+ return (void *)__get_free_pages(flags, get_order(size));
+}
-#define jbd_kmalloc(size, flags) \
- __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-#define jbd_rep_kmalloc(size, flags) \
- __jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
+static inline void jbd_free(void *ptr, size_t size)
+{
+ free_pages((unsigned long)ptr, get_order(size));
+};
#define JFS_MIN_JOURNAL_BLOCKS 1024
@@ -371,6 +373,7 @@ struct jbd_revoke_table_s;
* @h_sync: flag for sync-on-close
* @h_jdata: flag to force data journaling
* @h_aborted: flag indicating fatal error on handle
+ * @h_lockdep_map: lockdep info for debugging lock problems
**/
/* Docbook can't yet cope with the bit fields, but will leave the documentation
@@ -396,6 +399,10 @@ struct handle_s
unsigned int h_sync: 1; /* sync-on-close */
unsigned int h_jdata: 1; /* force data journaling */
unsigned int h_aborted: 1; /* fatal error on handle */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map h_lockdep_map;
+#endif
};
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 260d6d76c5f..06ef1145705 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -13,8 +13,8 @@
* filesystem journaling support.
*/
-#ifndef _LINUX_JBD_H
-#define _LINUX_JBD_H
+#ifndef _LINUX_JBD2_H
+#define _LINUX_JBD2_H
/* Allow this file to be included directly into e2fsprogs */
#ifndef __KERNEL__
@@ -37,26 +37,26 @@
#define journal_oom_retry 1
/*
- * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * Define JBD2_PARANIOD_IOFAIL to cause a kernel BUG() if ext4 finds
* certain classes of error which can occur due to failed IOs. Under
- * normal use we want ext3 to continue after such errors, because
+ * normal use we want ext4 to continue after such errors, because
* hardware _can_ fail, but for debugging purposes when running tests on
* known-good hardware we may want to trap these errors.
*/
-#undef JBD_PARANOID_IOFAIL
+#undef JBD2_PARANOID_IOFAIL
/*
* The default maximum commit age, in seconds.
*/
-#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+#define JBD2_DEFAULT_MAX_COMMIT_AGE 5
#ifdef CONFIG_JBD2_DEBUG
/*
- * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
+ * Define JBD2_EXPENSIVE_CHECKING to enable more expensive internal
* consistency checks. By default we don't do this unless
* CONFIG_JBD2_DEBUG is on.
*/
-#define JBD_EXPENSIVE_CHECKING
+#define JBD2_EXPENSIVE_CHECKING
extern u8 jbd2_journal_enable_debug;
#define jbd_debug(n, f, a...) \
@@ -71,14 +71,15 @@ extern u8 jbd2_journal_enable_debug;
#define jbd_debug(f, a...) /**/
#endif
-extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
-extern void * jbd2_slab_alloc(size_t size, gfp_t flags);
-extern void jbd2_slab_free(void *ptr, size_t size);
+static inline void *jbd2_alloc(size_t size, gfp_t flags)
+{
+ return (void *)__get_free_pages(flags, get_order(size));
+}
-#define jbd_kmalloc(size, flags) \
- __jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-#define jbd_rep_kmalloc(size, flags) \
- __jbd2_kmalloc(__FUNCTION__, (size), (flags), 1)
+static inline void jbd2_free(void *ptr, size_t size)
+{
+ free_pages((unsigned long)ptr, get_order(size));
+};
#define JBD2_MIN_JOURNAL_BLOCKS 1024
@@ -162,8 +163,8 @@ typedef struct journal_block_tag_s
__be32 t_blocknr_high; /* most-significant high 32bits. */
} journal_block_tag_t;
-#define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
-#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t))
+#define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high))
+#define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t))
/*
* The revoke descriptor: used on disk to describe a series of blocks to
@@ -255,8 +256,8 @@ typedef struct journal_superblock_s
#include <linux/fs.h>
#include <linux/sched.h>
-#define JBD_ASSERTIONS
-#ifdef JBD_ASSERTIONS
+#define JBD2_ASSERTIONS
+#ifdef JBD2_ASSERTIONS
#define J_ASSERT(assert) \
do { \
if (!(assert)) { \
@@ -283,9 +284,9 @@ void buffer_assertion_failure(struct buffer_head *bh);
#else
#define J_ASSERT(assert) do { } while (0)
-#endif /* JBD_ASSERTIONS */
+#endif /* JBD2_ASSERTIONS */
-#if defined(JBD_PARANOID_IOFAIL)
+#if defined(JBD2_PARANOID_IOFAIL)
#define J_EXPECT(expr, why...) J_ASSERT(expr)
#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr)
#define J_EXPECT_JH(jh, expr, why...) J_ASSERT_JH(jh, expr)
@@ -959,12 +960,12 @@ void jbd2_journal_put_journal_head(struct journal_head *jh);
*/
extern struct kmem_cache *jbd2_handle_cache;
-static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags)
+static inline handle_t *jbd2_alloc_handle(gfp_t gfp_flags)
{
return kmem_cache_alloc(jbd2_handle_cache, gfp_flags);
}
-static inline void jbd_free_handle(handle_t *handle)
+static inline void jbd2_free_handle(handle_t *handle)
{
kmem_cache_free(jbd2_handle_cache, handle);
}
@@ -1103,4 +1104,4 @@ extern int jbd_blocks_per_page(struct inode *inode);
#endif /* __KERNEL__ */
-#endif /* _LINUX_JBD_H */
+#endif /* _LINUX_JBD2_H */
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index d7a5e034c3a..8b080024bbc 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -109,6 +109,10 @@ static inline u64 get_jiffies_64(void)
((long)(a) - (long)(b) >= 0))
#define time_before_eq(a,b) time_after_eq(b,a)
+#define time_in_range(a,b,c) \
+ (time_after_eq(a,b) && \
+ time_before_eq(a,c))
+
/* Same as above, but does so with platform independent 64bit types.
* These must be used when utilizing jiffies_64 (i.e. return value of
* get_jiffies_64() */
@@ -144,6 +148,8 @@ static inline u64 get_jiffies_64(void)
*/
#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)
+extern unsigned long preset_lpj;
+
/*
* We want to do realistic conversions of time so we need to use the same
* values the update wall clock code uses as the jiffies size. This value
diff --git a/include/linux/kbd_diacr.h b/include/linux/kbd_diacr.h
index 1c1a3ff0535..7274ec68c24 100644
--- a/include/linux/kbd_diacr.h
+++ b/include/linux/kbd_diacr.h
@@ -2,7 +2,7 @@
#define _DIACR_H
#include <linux/kd.h>
-extern struct kbdiacr accent_table[];
+extern struct kbdiacruc accent_table[];
extern unsigned int accent_table_size;
#endif /* _DIACR_H */
diff --git a/include/linux/kd.h b/include/linux/kd.h
index 28be4fbe904..c91fc0c9c49 100644
--- a/include/linux/kd.h
+++ b/include/linux/kd.h
@@ -125,6 +125,16 @@ struct kbdiacrs {
#define KDGKBDIACR 0x4B4A /* read kernel accent table */
#define KDSKBDIACR 0x4B4B /* write kernel accent table */
+struct kbdiacruc {
+ __u32 diacr, base, result;
+};
+struct kbdiacrsuc {
+ unsigned int kb_cnt; /* number of entries in following array */
+ struct kbdiacruc kbdiacruc[256]; /* MAX_DIACR from keyboard.h */
+};
+#define KDGKBDIACRUC 0x4BFA /* read kernel accent table - UCS */
+#define KDSKBDIACRUC 0x4BFB /* write kernel accent table - UCS */
+
struct kbkeycode {
unsigned int scancode, keycode;
};
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index d9725a28a26..94bc9965696 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -35,6 +35,7 @@ extern const char linux_proc_banner[];
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
+#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0)
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
@@ -75,6 +76,13 @@ extern const char linux_proc_banner[];
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
+/*
+ * Annotation for a "continued" line of log printout (only done after a
+ * line that had no enclosing \n). Only to be used by core/arch code
+ * during early bootup (a continued line is not SMP-safe otherwise).
+ */
+#define KERN_CONT ""
+
extern int console_printk[];
#define console_loglevel (console_printk[0])
@@ -171,6 +179,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
__attribute__ ((format (printf, 1, 0)));
asmlinkage int printk(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2))) __cold;
+extern int log_buf_get_len(void);
+extern int log_buf_read(int idx);
+extern int log_buf_copy(char *dest, int idx, int len);
#else
static inline int vprintk(const char *s, va_list args)
__attribute__ ((format (printf, 1, 0)));
@@ -178,6 +189,9 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
static inline int printk(const char *s, ...)
__attribute__ ((format (printf, 1, 2)));
static inline int __cold printk(const char *s, ...) { return 0; }
+static inline int log_buf_get_len(void) { return 0; }
+static inline int log_buf_read(int idx) { return 0; }
+static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
#endif
unsigned long int_sqrt(unsigned long);
@@ -244,10 +258,25 @@ extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
const void *buf, size_t len);
#define hex_asc(x) "0123456789abcdef"[x]
+#define pr_emerg(fmt, arg...) \
+ printk(KERN_EMERG fmt, ##arg)
+#define pr_alert(fmt, arg...) \
+ printk(KERN_ALERT fmt, ##arg)
+#define pr_crit(fmt, arg...) \
+ printk(KERN_CRIT fmt, ##arg)
+#define pr_err(fmt, arg...) \
+ printk(KERN_ERR fmt, ##arg)
+#define pr_warning(fmt, arg...) \
+ printk(KERN_WARNING fmt, ##arg)
+#define pr_notice(fmt, arg...) \
+ printk(KERN_NOTICE fmt, ##arg)
+#define pr_info(fmt, arg...) \
+ printk(KERN_INFO fmt, ##arg)
+
#ifdef DEBUG
/* If you are writing a driver, please use dev_dbg instead */
-#define pr_debug(fmt,arg...) \
- printk(KERN_DEBUG fmt,##arg)
+#define pr_debug(fmt, arg...) \
+ printk(KERN_DEBUG fmt, ##arg)
#else
static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * fmt, ...)
{
@@ -255,9 +284,6 @@ static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char *
}
#endif
-#define pr_info(fmt,arg...) \
- printk(KERN_INFO fmt,##arg)
-
/*
* Display an IP address in readable format.
*/
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 12bf44f083f..e8ffce898bf 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -53,7 +53,9 @@ static inline int kstat_irqs(int irq)
}
extern void account_user_time(struct task_struct *, cputime_t);
+extern void account_user_time_scaled(struct task_struct *, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t);
+extern void account_system_time_scaled(struct task_struct *, cputime_t);
extern void account_steal_time(struct task_struct *, cputime_t);
#endif /* _LINUX_KERNEL_STAT_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 8c2c7fcd58c..ad4b82ce84a 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -121,6 +121,30 @@ extern struct page *kimage_alloc_control_pages(struct kimage *image,
extern void crash_kexec(struct pt_regs *);
int kexec_should_crash(struct task_struct *);
void crash_save_cpu(struct pt_regs *regs, int cpu);
+void crash_save_vmcoreinfo(void);
+void arch_crash_save_vmcoreinfo(void);
+void vmcoreinfo_append_str(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+unsigned long paddr_vmcoreinfo_note(void);
+
+#define VMCOREINFO_SYMBOL(name) \
+ vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
+#define VMCOREINFO_SIZE(name) \
+ vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
+ (unsigned long)sizeof(struct name))
+#define VMCOREINFO_TYPEDEF_SIZE(name) \
+ vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
+ (unsigned long)sizeof(name))
+#define VMCOREINFO_OFFSET(name, field) \
+ vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
+ (unsigned long)&(((struct name *)0)->field))
+#define VMCOREINFO_LENGTH(name, value) \
+ vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
+#define VMCOREINFO_NUMBER(name) \
+ vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
+#define VMCOREINFO_CONFIG(name) \
+ vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
+
extern struct kimage *kexec_image;
extern struct kimage *kexec_crash_image;
@@ -148,11 +172,20 @@ extern struct kimage *kexec_crash_image;
#define KEXEC_FLAGS (KEXEC_ON_CRASH) /* List of defined/legal kexec flags */
+#define VMCOREINFO_BYTES (4096)
+#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
+#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
+#define VMCOREINFO_NOTE_SIZE (KEXEC_NOTE_HEAD_BYTES*2 + VMCOREINFO_BYTES \
+ + VMCOREINFO_NOTE_NAME_BYTES)
+
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
extern note_buf_t *crash_notes;
+extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
+extern size_t vmcoreinfo_size;
+extern size_t vmcoreinfo_max_size;
#else /* !CONFIG_KEXEC */
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
new file mode 100644
index 00000000000..65833d4d599
--- /dev/null
+++ b/include/linux/key-type.h
@@ -0,0 +1,112 @@
+/* Definitions for key type implementations
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_KEY_TYPE_H
+#define _LINUX_KEY_TYPE_H
+
+#include <linux/key.h>
+
+#ifdef CONFIG_KEYS
+
+/*
+ * key under-construction record
+ * - passed to the request_key actor if supplied
+ */
+struct key_construction {
+ struct key *key; /* key being constructed */
+ struct key *authkey;/* authorisation for key being constructed */
+};
+
+typedef int (*request_key_actor_t)(struct key_construction *key,
+ const char *op, void *aux);
+
+/*
+ * kernel managed key type definition
+ */
+struct key_type {
+ /* name of the type */
+ const char *name;
+
+ /* default payload length for quota precalculation (optional)
+ * - this can be used instead of calling key_payload_reserve(), that
+ * function only needs to be called if the real datalen is different
+ */
+ size_t def_datalen;
+
+ /* instantiate a key of this type
+ * - this method should call key_payload_reserve() to determine if the
+ * user's quota will hold the payload
+ */
+ int (*instantiate)(struct key *key, const void *data, size_t datalen);
+
+ /* update a key of this type (optional)
+ * - this method should call key_payload_reserve() to recalculate the
+ * quota consumption
+ * - the key must be locked against read when modifying
+ */
+ int (*update)(struct key *key, const void *data, size_t datalen);
+
+ /* match a key against a description */
+ int (*match)(const struct key *key, const void *desc);
+
+ /* clear some of the data from a key on revokation (optional)
+ * - the key's semaphore will be write-locked by the caller
+ */
+ void (*revoke)(struct key *key);
+
+ /* clear the data from a key (optional) */
+ void (*destroy)(struct key *key);
+
+ /* describe a key */
+ void (*describe)(const struct key *key, struct seq_file *p);
+
+ /* read a key's data (optional)
+ * - permission checks will be done by the caller
+ * - the key's semaphore will be readlocked by the caller
+ * - should return the amount of data that could be read, no matter how
+ * much is copied into the buffer
+ * - shouldn't do the copy if the buffer is NULL
+ */
+ long (*read)(const struct key *key, char __user *buffer, size_t buflen);
+
+ /* handle request_key() for this type instead of invoking
+ * /sbin/request-key (optional)
+ * - key is the key to instantiate
+ * - authkey is the authority to assume when instantiating this key
+ * - op is the operation to be done, usually "create"
+ * - the call must not return until the instantiation process has run
+ * its course
+ */
+ request_key_actor_t request_key;
+
+ /* internal fields */
+ struct list_head link; /* link in types list */
+};
+
+extern struct key_type key_type_keyring;
+
+extern int register_key_type(struct key_type *ktype);
+extern void unregister_key_type(struct key_type *ktype);
+
+extern int key_payload_reserve(struct key *key, size_t datalen);
+extern int key_instantiate_and_link(struct key *key,
+ const void *data,
+ size_t datalen,
+ struct key *keyring,
+ struct key *instkey);
+extern int key_negate_and_link(struct key *key,
+ unsigned timeout,
+ struct key *keyring,
+ struct key *instkey);
+extern void complete_request_key(struct key_construction *cons, int error);
+
+#endif /* CONFIG_KEYS */
+#endif /* _LINUX_KEY_TYPE_H */
diff --git a/include/linux/key.h b/include/linux/key.h
index a9220e75782..fcdbd5ed227 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -1,6 +1,6 @@
-/* key.h: authentication token and access key management
+/* Authentication token and access key management
*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004, 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -175,78 +175,6 @@ struct key {
} payload;
};
-/*****************************************************************************/
-/*
- * kernel managed key type definition
- */
-typedef int (*request_key_actor_t)(struct key *key, struct key *authkey,
- const char *op, void *aux);
-
-struct key_type {
- /* name of the type */
- const char *name;
-
- /* default payload length for quota precalculation (optional)
- * - this can be used instead of calling key_payload_reserve(), that
- * function only needs to be called if the real datalen is different
- */
- size_t def_datalen;
-
- /* instantiate a key of this type
- * - this method should call key_payload_reserve() to determine if the
- * user's quota will hold the payload
- */
- int (*instantiate)(struct key *key, const void *data, size_t datalen);
-
- /* update a key of this type (optional)
- * - this method should call key_payload_reserve() to recalculate the
- * quota consumption
- * - the key must be locked against read when modifying
- */
- int (*update)(struct key *key, const void *data, size_t datalen);
-
- /* match a key against a description */
- int (*match)(const struct key *key, const void *desc);
-
- /* clear some of the data from a key on revokation (optional)
- * - the key's semaphore will be write-locked by the caller
- */
- void (*revoke)(struct key *key);
-
- /* clear the data from a key (optional) */
- void (*destroy)(struct key *key);
-
- /* describe a key */
- void (*describe)(const struct key *key, struct seq_file *p);
-
- /* read a key's data (optional)
- * - permission checks will be done by the caller
- * - the key's semaphore will be readlocked by the caller
- * - should return the amount of data that could be read, no matter how
- * much is copied into the buffer
- * - shouldn't do the copy if the buffer is NULL
- */
- long (*read)(const struct key *key, char __user *buffer, size_t buflen);
-
- /* handle request_key() for this type instead of invoking
- * /sbin/request-key (optional)
- * - key is the key to instantiate
- * - authkey is the authority to assume when instantiating this key
- * - op is the operation to be done, usually "create"
- * - the call must not return until the instantiation process has run
- * its course
- */
- request_key_actor_t request_key;
-
- /* internal fields */
- struct list_head link; /* link in types list */
-};
-
-extern struct key_type key_type_keyring;
-
-extern int register_key_type(struct key_type *ktype);
-extern void unregister_key_type(struct key_type *ktype);
-
extern struct key *key_alloc(struct key_type *type,
const char *desc,
uid_t uid, gid_t gid,
@@ -259,16 +187,6 @@ extern struct key *key_alloc(struct key_type *type,
#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
-extern int key_payload_reserve(struct key *key, size_t datalen);
-extern int key_instantiate_and_link(struct key *key,
- const void *data,
- size_t datalen,
- struct key *keyring,
- struct key *instkey);
-extern int key_negate_and_link(struct key *key,
- unsigned timeout,
- struct key *keyring,
- struct key *instkey);
extern void key_revoke(struct key *key);
extern void key_put(struct key *key);
@@ -293,6 +211,17 @@ extern struct key *request_key_with_auxdata(struct key_type *type,
const char *callout_info,
void *aux);
+extern struct key *request_key_async(struct key_type *type,
+ const char *description,
+ const char *callout_info);
+
+extern struct key *request_key_async_with_auxdata(struct key_type *type,
+ const char *description,
+ const char *callout_info,
+ void *aux);
+
+extern int wait_for_key_construction(struct key *key, bool intr);
+
extern int key_validate(struct key *key);
extern key_ref_t key_create_or_update(key_ref_t keyring,
@@ -328,8 +257,6 @@ extern int keyring_add_key(struct key *keyring,
extern struct key *key_lookup(key_serial_t id);
-extern void keyring_replace_payload(struct key *key, void *replacement);
-
#define key_serial(key) ((key) ? (key)->serial : 0)
/*
diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h
index 7ddbc30aa8e..33b5c2e325b 100644
--- a/include/linux/keyboard.h
+++ b/include/linux/keyboard.h
@@ -416,6 +416,7 @@ extern unsigned short plain_map[NR_KEYS];
#define K_SHIFTRLOCK K(KT_LOCK,KG_SHIFTR)
#define K_CTRLLLOCK K(KT_LOCK,KG_CTRLL)
#define K_CTRLRLOCK K(KT_LOCK,KG_CTRLR)
+#define K_CAPSSHIFTLOCK K(KT_LOCK,KG_CAPSSHIFT)
#define K_SHIFT_SLOCK K(KT_SLOCK,KG_SHIFT)
#define K_CTRL_SLOCK K(KT_SLOCK,KG_CTRL)
@@ -425,8 +426,9 @@ extern unsigned short plain_map[NR_KEYS];
#define K_SHIFTR_SLOCK K(KT_SLOCK,KG_SHIFTR)
#define K_CTRLL_SLOCK K(KT_SLOCK,KG_CTRLL)
#define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+#define K_CAPSSHIFT_SLOCK K(KT_SLOCK,KG_CAPSSHIFT)
-#define NR_LOCK 8
+#define NR_LOCK 9
#define K_BRL_BLANK K(KT_BRL, 0)
#define K_BRL_DOT1 K(KT_BRL, 1)
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 51464d12a4e..81891581e89 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -166,6 +166,12 @@ struct kretprobe_instance {
struct task_struct *task;
};
+struct kretprobe_blackpoint {
+ const char *name;
+ void *addr;
+};
+extern struct kretprobe_blackpoint kretprobe_blacklist[];
+
static inline void kretprobe_assert(struct kretprobe_instance *ri,
unsigned long orig_ret_address, unsigned long trampoline_address)
{
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 229a9ff9f92..bc3b6fc7b98 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -29,7 +29,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/ata.h>
#include <linux/workqueue.h>
@@ -416,6 +416,7 @@ struct ata_queued_cmd {
unsigned long flags; /* ATA_QCFLAG_xxx */
unsigned int tag;
unsigned int n_elem;
+ unsigned int n_iter;
unsigned int orig_n_elem;
int dma_dir;
@@ -426,7 +427,7 @@ struct ata_queued_cmd {
unsigned int nbytes;
unsigned int curbytes;
- unsigned int cursg;
+ struct scatterlist *cursg;
unsigned int cursg_ofs;
struct scatterlist sgent;
@@ -1036,21 +1037,10 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset,
/*
* qc helpers
*/
-static inline int
-ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
-{
- if (sg == &qc->pad_sgent)
- return 1;
- if (qc->pad_len)
- return 0;
- if (((sg - qc->__sg) + 1) == qc->n_elem)
- return 1;
- return 0;
-}
-
static inline struct scatterlist *
ata_qc_first_sg(struct ata_queued_cmd *qc)
{
+ qc->n_iter = 0;
if (qc->n_elem)
return qc->__sg;
if (qc->pad_len)
@@ -1063,8 +1053,8 @@ ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
{
if (sg == &qc->pad_sgent)
return NULL;
- if (++sg - qc->__sg < qc->n_elem)
- return sg;
+ if (++qc->n_iter < qc->n_elem)
+ return sg_next(sg);
if (qc->pad_len)
return &qc->pad_sgent;
return NULL;
@@ -1309,9 +1299,11 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
qc->dma_dir = DMA_NONE;
qc->__sg = NULL;
qc->flags = 0;
- qc->cursg = qc->cursg_ofs = 0;
+ qc->cursg = NULL;
+ qc->cursg_ofs = 0;
qc->nbytes = qc->curbytes = 0;
qc->n_elem = 0;
+ qc->n_iter = 0;
qc->err_mask = 0;
qc->pad_len = 0;
qc->sect_size = ATA_SECT_SIZE;
diff --git a/include/linux/list.h b/include/linux/list.h
index ad9dcb9e337..b0cf0135fe3 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -478,6 +478,18 @@ 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
+ * @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.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+ for (pos = (head)->prev, n = pos->prev; \
+ prefetch(pos->prev), pos != (head); \
+ pos = n, n = pos->prev)
+
+/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 0e843bf6587..f6279f68a82 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -238,6 +238,7 @@ extern void lockdep_info(void);
extern void lockdep_reset(void);
extern void lockdep_reset_lock(struct lockdep_map *lock);
extern void lockdep_free_key_range(void *start, unsigned long size);
+extern void lockdep_sys_exit(void);
extern void lockdep_off(void);
extern void lockdep_on(void);
@@ -252,6 +253,13 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
struct lock_class_key *key, int subclass);
/*
+ * 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), }
+
+/*
* Reinitialize a lock key - for cases where there is special locking or
* special initialization of locks so that the validator gets the scope
* of dependencies wrong: they are either too broad (they need a class-split)
@@ -317,6 +325,7 @@ static inline void lockdep_on(void)
# define INIT_LOCKDEP
# define lockdep_reset() do { debug_locks = 1; } while (0)
# define lockdep_free_key_range(start, size) do { } while (0)
+# define lockdep_sys_exit() do { } while (0)
/*
* The class key takes no space if lockdep is disabled:
*/
diff --git a/include/linux/log2.h b/include/linux/log2.h
index 1b8a2c1cb0e..c8cf5e8ef17 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -63,6 +63,15 @@ unsigned long __roundup_pow_of_two(unsigned long n)
return 1UL << fls_long(n - 1);
}
+/*
+ * round down to nearest power of two
+ */
+static inline __attribute__((const))
+unsigned long __rounddown_pow_of_two(unsigned long n)
+{
+ return 1UL << (fls_long(n) - 1);
+}
+
/**
* ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
* @n - parameter
@@ -165,4 +174,20 @@ unsigned long __roundup_pow_of_two(unsigned long n)
__roundup_pow_of_two(n) \
)
+/**
+ * rounddown_pow_of_two - round the given value down to nearest power of two
+ * @n - parameter
+ *
+ * round the given value down to the nearest power of two
+ * - the result is undefined when n == 0
+ * - this can be used to initialise global variables from constant data
+ */
+#define rounddown_pow_of_two(n) \
+( \
+ __builtin_constant_p(n) ? ( \
+ (n == 1) ? 0 : \
+ (1UL << ilog2(n))) : \
+ __rounddown_pow_of_two(n) \
+ )
+
#endif /* _LINUX_LOG2_H */
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 36cc20dfd14..722d4755060 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -38,4 +38,7 @@
#define SMB_SUPER_MAGIC 0x517B
#define USBDEVICE_SUPER_MAGIC 0x9fa2
+#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
+#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
+
#endif /* __LINUX_MAGIC_H__ */
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 7b54666cea8..8fee7a45736 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -3,7 +3,6 @@
#include <linux/mmzone.h>
#include <linux/spinlock.h>
-#include <linux/mmzone.h>
#include <linux/notifier.h>
struct page;
@@ -59,11 +58,21 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
extern void online_page(struct page *page);
/* VM interface that may be used by firmware interface */
extern int online_pages(unsigned long, unsigned long);
+extern void __offline_isolated_pages(unsigned long, unsigned long);
+extern int offline_pages(unsigned long, unsigned long, unsigned long);
/* reasonably generic interface to expand the physical pages in a zone */
extern int __add_pages(struct zone *zone, unsigned long start_pfn,
unsigned long nr_pages);
+/*
+ * Walk thorugh all memory which is registered as resource.
+ * arg is (start_pfn, nr_pages, private_arg_pointer)
+ */
+extern int walk_memory_resource(unsigned long start_pfn,
+ unsigned long nr_pages, void *arg,
+ int (*func)(unsigned long, unsigned long, void *));
+
#ifdef CONFIG_NUMA
extern int memory_add_physaddr_to_nid(u64 start);
#else
@@ -161,13 +170,6 @@ static inline int mhp_notimplemented(const char *func)
}
#endif /* ! CONFIG_MEMORY_HOTPLUG */
-static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
- unsigned long nr_pages)
-{
- printk(KERN_WARNING "%s() called, not yet supported\n", __FUNCTION__);
- dump_stack();
- return -ENOSYS;
-}
extern int add_memory(int nid, u64 start, u64 size);
extern int arch_add_memory(int nid, u64 start, u64 size);
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index a020eb2d4e2..38c04d61ee0 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -19,6 +19,7 @@
/* Flags for get_mem_policy */
#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */
#define MPOL_F_ADDR (1<<1) /* look up vma using address */
+#define MPOL_F_MEMS_ALLOWED (1<<2) /* return allowed memories */
/* Flags for mbind */
#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
@@ -143,7 +144,6 @@ struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,
extern void numa_default_policy(void);
extern void numa_policy_init(void);
-extern void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *new);
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);
@@ -235,11 +235,6 @@ static inline void numa_default_policy(void)
{
}
-static inline void mpol_rebind_policy(struct mempolicy *pol,
- const nodemask_t *new)
-{
-}
-
static inline void mpol_rebind_task(struct task_struct *tsk,
const nodemask_t *new)
{
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1692dd6cb91..520238cbae5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -10,9 +10,7 @@
#include <linux/mmzone.h>
#include <linux/rbtree.h>
#include <linux/prio_tree.h>
-#include <linux/mutex.h>
#include <linux/debug_locks.h>
-#include <linux/backing-dev.h>
#include <linux/mm_types.h>
struct mempolicy;
@@ -50,69 +48,6 @@ extern int sysctl_legacy_va_layout;
* mmap() functions).
*/
-/*
- * This struct defines a memory VMM memory area. There is one of these
- * per VM-area/task. A VM area is any part of the process virtual memory
- * space that has a special rule for the page-fault handlers (ie a shared
- * library, the executable area etc).
- */
-struct vm_area_struct {
- struct mm_struct * vm_mm; /* The address space we belong to. */
- unsigned long vm_start; /* Our start address within vm_mm. */
- unsigned long vm_end; /* The first byte after our end address
- within vm_mm. */
-
- /* linked list of VM areas per task, sorted by address */
- struct vm_area_struct *vm_next;
-
- pgprot_t vm_page_prot; /* Access permissions of this VMA. */
- unsigned long vm_flags; /* Flags, listed below. */
-
- struct rb_node vm_rb;
-
- /*
- * For areas with an address space and backing store,
- * linkage into the address_space->i_mmap prio tree, or
- * linkage to the list of like vmas hanging off its node, or
- * linkage of vma in the address_space->i_mmap_nonlinear list.
- */
- union {
- struct {
- struct list_head list;
- void *parent; /* aligns with prio_tree_node parent */
- struct vm_area_struct *head;
- } vm_set;
-
- struct raw_prio_tree_node prio_tree_node;
- } shared;
-
- /*
- * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
- * list, after a COW of one of the file pages. A MAP_SHARED vma
- * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
- * or brk vma (with NULL file) can only be in an anon_vma list.
- */
- struct list_head anon_vma_node; /* Serialized by anon_vma->lock */
- struct anon_vma *anon_vma; /* Serialized by page_table_lock */
-
- /* Function pointers to deal with this struct. */
- struct vm_operations_struct * vm_ops;
-
- /* Information about our backing store: */
- unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
- units, *not* PAGE_CACHE_SIZE */
- struct file * vm_file; /* File we map to (can be NULL). */
- void * vm_private_data; /* was vm_pte (shared mem) */
- unsigned long vm_truncate_count;/* truncate_count or restart_addr */
-
-#ifndef CONFIG_MMU
- atomic_t vm_usage; /* refcount (VMAs shared if !MMU) */
-#endif
-#ifdef CONFIG_NUMA
- struct mempolicy *vm_policy; /* NUMA policy for the VMA */
-#endif
-};
-
extern struct kmem_cache *vm_area_cachep;
/*
@@ -631,10 +566,6 @@ static inline struct address_space *page_mapping(struct page *page)
VM_BUG_ON(PageSlab(page));
if (unlikely(PageSwapCache(page)))
mapping = &swapper_space;
-#ifdef CONFIG_SLUB
- else if (unlikely(PageSlab(page)))
- mapping = NULL;
-#endif
else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON))
mapping = NULL;
return mapping;
@@ -715,9 +646,6 @@ static inline int page_mapped(struct page *page)
extern void show_free_areas(void);
#ifdef CONFIG_SHMEM
-int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new);
-struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
- unsigned long addr);
int shmem_lock(struct file *file, int lock, struct user_struct *user);
#else
static inline int shmem_lock(struct file *file, int lock,
@@ -725,18 +653,6 @@ static inline int shmem_lock(struct file *file, int lock,
{
return 0;
}
-
-static inline int shmem_set_policy(struct vm_area_struct *vma,
- struct mempolicy *new)
-{
- return 0;
-}
-
-static inline struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
- unsigned long addr)
-{
- return NULL;
-}
#endif
struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags);
@@ -779,8 +695,6 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *start_vma,
unsigned long floor, unsigned long ceiling);
int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
struct vm_area_struct *vma);
-int zeromap_page_range(struct vm_area_struct *vma, unsigned long from,
- unsigned long size, pgprot_t prot);
void unmap_mapping_range(struct address_space *mapping,
loff_t const holebegin, loff_t const holelen, int even_cows);
@@ -1106,8 +1020,6 @@ int write_one_page(struct page *page, int wait);
/* readahead.c */
#define VM_MAX_READAHEAD 128 /* kbytes */
#define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */
-#define VM_MAX_CACHE_HIT 256 /* max pages in a row in cache before
- * turning readahead off */
int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
pgoff_t offset, unsigned long nr_to_read);
@@ -1218,5 +1130,16 @@ extern int randomize_va_space;
const char * arch_vma_name(struct vm_area_struct *vma);
+struct page *sparse_mem_map_populate(unsigned long pnum, int nid);
+pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
+pud_t *vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node);
+pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node);
+pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node);
+void *vmemmap_alloc_block(unsigned long size, int node);
+void vmemmap_verify(pte_t *, int, unsigned long, unsigned long);
+int vmemmap_populate_basepages(struct page *start_page,
+ unsigned long pages, int node);
+int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index d5bb1796e12..f4c03e0b355 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1,13 +1,31 @@
#ifndef _LINUX_MM_TYPES_H
#define _LINUX_MM_TYPES_H
+#include <linux/auxvec.h>
#include <linux/types.h>
#include <linux/threads.h>
#include <linux/list.h>
#include <linux/spinlock.h>
+#include <linux/prio_tree.h>
+#include <linux/rbtree.h>
+#include <linux/rwsem.h>
+#include <linux/completion.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+
+#ifndef AT_VECTOR_SIZE_ARCH
+#define AT_VECTOR_SIZE_ARCH 0
+#endif
+#define AT_VECTOR_SIZE (2*(AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))
struct address_space;
+#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
+typedef atomic_long_t mm_counter_t;
+#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+typedef unsigned long mm_counter_t;
+#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
+
/*
* Each physical page in the system has a struct page associated with
* it to keep track of whatever it is we are using the page for at the
@@ -24,10 +42,7 @@ struct page {
* to show when page is mapped
* & limit reverse map searches.
*/
- struct { /* SLUB uses */
- short unsigned int inuse;
- short unsigned int offset;
- };
+ unsigned int inuse; /* SLUB: Nr of objects */
};
union {
struct {
@@ -49,13 +64,8 @@ struct page {
#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
spinlock_t ptl;
#endif
- struct { /* SLUB uses */
- void **lockless_freelist;
- struct kmem_cache *slab; /* Pointer to slab */
- };
- struct {
- struct page *first_page; /* Compound pages */
- };
+ struct kmem_cache *slab; /* SLUB: Pointer to slab */
+ struct page *first_page; /* Compound tail pages */
};
union {
pgoff_t index; /* Our offset within mapping. */
@@ -80,4 +90,135 @@ struct page {
#endif /* WANT_PAGE_VIRTUAL */
};
+/*
+ * This struct defines a memory VMM memory area. There is one of these
+ * per VM-area/task. A VM area is any part of the process virtual memory
+ * space that has a special rule for the page-fault handlers (ie a shared
+ * library, the executable area etc).
+ */
+struct vm_area_struct {
+ struct mm_struct * vm_mm; /* The address space we belong to. */
+ unsigned long vm_start; /* Our start address within vm_mm. */
+ unsigned long vm_end; /* The first byte after our end address
+ within vm_mm. */
+
+ /* linked list of VM areas per task, sorted by address */
+ struct vm_area_struct *vm_next;
+
+ pgprot_t vm_page_prot; /* Access permissions of this VMA. */
+ unsigned long vm_flags; /* Flags, listed below. */
+
+ struct rb_node vm_rb;
+
+ /*
+ * For areas with an address space and backing store,
+ * linkage into the address_space->i_mmap prio tree, or
+ * linkage to the list of like vmas hanging off its node, or
+ * linkage of vma in the address_space->i_mmap_nonlinear list.
+ */
+ union {
+ struct {
+ struct list_head list;
+ void *parent; /* aligns with prio_tree_node parent */
+ struct vm_area_struct *head;
+ } vm_set;
+
+ struct raw_prio_tree_node prio_tree_node;
+ } shared;
+
+ /*
+ * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
+ * list, after a COW of one of the file pages. A MAP_SHARED vma
+ * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
+ * or brk vma (with NULL file) can only be in an anon_vma list.
+ */
+ struct list_head anon_vma_node; /* Serialized by anon_vma->lock */
+ struct anon_vma *anon_vma; /* Serialized by page_table_lock */
+
+ /* Function pointers to deal with this struct. */
+ struct vm_operations_struct * vm_ops;
+
+ /* Information about our backing store: */
+ unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
+ units, *not* PAGE_CACHE_SIZE */
+ struct file * vm_file; /* File we map to (can be NULL). */
+ void * vm_private_data; /* was vm_pte (shared mem) */
+ unsigned long vm_truncate_count;/* truncate_count or restart_addr */
+
+#ifndef CONFIG_MMU
+ atomic_t vm_usage; /* refcount (VMAs shared if !MMU) */
+#endif
+#ifdef CONFIG_NUMA
+ struct mempolicy *vm_policy; /* NUMA policy for the VMA */
+#endif
+};
+
+struct mm_struct {
+ struct vm_area_struct * mmap; /* list of VMAs */
+ struct rb_root mm_rb;
+ struct vm_area_struct * mmap_cache; /* last find_vma result */
+ unsigned long (*get_unmapped_area) (struct file *filp,
+ unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags);
+ void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
+ unsigned long mmap_base; /* base of mmap area */
+ unsigned long task_size; /* size of task vm space */
+ unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
+ unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
+ pgd_t * pgd;
+ atomic_t mm_users; /* How many users with user space? */
+ atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
+ int map_count; /* number of VMAs */
+ struct rw_semaphore mmap_sem;
+ spinlock_t page_table_lock; /* Protects page tables and some counters */
+
+ struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
+ * together off init_mm.mmlist, and are protected
+ * by mmlist_lock
+ */
+
+ /* Special counters, in some configurations protected by the
+ * page_table_lock, in other configurations by being atomic.
+ */
+ mm_counter_t _file_rss;
+ mm_counter_t _anon_rss;
+
+ unsigned long hiwater_rss; /* High-watermark of RSS usage */
+ unsigned long hiwater_vm; /* High-water virtual memory usage */
+
+ unsigned long total_vm, locked_vm, shared_vm, exec_vm;
+ unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
+ unsigned long start_code, end_code, start_data, end_data;
+ unsigned long start_brk, brk, start_stack;
+ unsigned long arg_start, arg_end, env_start, env_end;
+
+ unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
+
+ cpumask_t cpu_vm_mask;
+
+ /* Architecture-specific MM context */
+ mm_context_t context;
+
+ /* Swap token stuff */
+ /*
+ * Last value of global fault stamp as seen by this process.
+ * In other words, this value gives an indication of how long
+ * it has been since this task got the token.
+ * Look at mm/thrash.c
+ */
+ unsigned int faultstamp;
+ unsigned int token_priority;
+ unsigned int last_interval;
+
+ unsigned long flags; /* Must use atomic bitops to access the bits */
+
+ /* coredumping support */
+ int core_waiters;
+ struct completion *core_startup_done, core_done;
+
+ /* aio bits */
+ rwlock_t ioctx_list_lock;
+ struct kioctx *ioctx_list;
+};
+
#endif /* _LINUX_MM_TYPES_H */
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 09306d47ff5..ea1bf5ba092 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -19,5 +19,11 @@
#define SDIO_CLASS_WLAN 0x07 /* WLAN interface */
#define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */
+/*
+ * Vendors and devices. Sort key: vendor first, device next.
+ */
+
+#define SDIO_VENDOR_ID_MARVELL 0x02df
+#define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103
#endif
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 4e5627379b0..4c4522a51a3 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -7,12 +7,14 @@
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/wait.h>
+#include <linux/bitops.h>
#include <linux/cache.h>
#include <linux/threads.h>
#include <linux/numa.h>
#include <linux/init.h>
#include <linux/seqlock.h>
#include <linux/nodemask.h>
+#include <linux/pageblock-flags.h>
#include <asm/atomic.h>
#include <asm/page.h>
@@ -32,8 +34,29 @@
*/
#define PAGE_ALLOC_COSTLY_ORDER 3
+#define MIGRATE_UNMOVABLE 0
+#define MIGRATE_RECLAIMABLE 1
+#define MIGRATE_MOVABLE 2
+#define MIGRATE_RESERVE 3
+#define MIGRATE_ISOLATE 4 /* can't allocate from here */
+#define MIGRATE_TYPES 5
+
+#define for_each_migratetype_order(order, type) \
+ for (order = 0; order < MAX_ORDER; order++) \
+ for (type = 0; type < MIGRATE_TYPES; type++)
+
+extern int page_group_by_mobility_disabled;
+
+static inline int get_pageblock_migratetype(struct page *page)
+{
+ if (unlikely(page_group_by_mobility_disabled))
+ return MIGRATE_UNMOVABLE;
+
+ return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
+}
+
struct free_area {
- struct list_head free_list;
+ struct list_head free_list[MIGRATE_TYPES];
unsigned long nr_free;
};
@@ -222,6 +245,14 @@ struct zone {
#endif
struct free_area free_area[MAX_ORDER];
+#ifndef CONFIG_SPARSEMEM
+ /*
+ * Flags for a pageblock_nr_pages block. See pageblock-flags.h.
+ * In SPARSEMEM, this map is stored in struct mem_section
+ */
+ unsigned long *pageblock_flags;
+#endif /* CONFIG_SPARSEMEM */
+
ZONE_PADDING(_pad1_)
@@ -232,10 +263,7 @@ struct zone {
unsigned long nr_scan_active;
unsigned long nr_scan_inactive;
unsigned long pages_scanned; /* since last reclaim */
- int all_unreclaimable; /* All pages pinned */
-
- /* A count of how many reclaimers are scanning this zone */
- atomic_t reclaim_in_progress;
+ unsigned long flags; /* zone flags, see below */
/* Zone statistics */
atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
@@ -313,6 +341,42 @@ struct zone {
const char *name;
} ____cacheline_internodealigned_in_smp;
+typedef enum {
+ ZONE_ALL_UNRECLAIMABLE, /* all pages pinned */
+ ZONE_RECLAIM_LOCKED, /* prevents concurrent reclaim */
+ ZONE_OOM_LOCKED, /* zone is in OOM killer zonelist */
+} zone_flags_t;
+
+static inline void zone_set_flag(struct zone *zone, zone_flags_t flag)
+{
+ set_bit(flag, &zone->flags);
+}
+
+static inline int zone_test_and_set_flag(struct zone *zone, zone_flags_t flag)
+{
+ return test_and_set_bit(flag, &zone->flags);
+}
+
+static inline void zone_clear_flag(struct zone *zone, zone_flags_t flag)
+{
+ clear_bit(flag, &zone->flags);
+}
+
+static inline int zone_is_all_unreclaimable(const struct zone *zone)
+{
+ return test_bit(ZONE_ALL_UNRECLAIMABLE, &zone->flags);
+}
+
+static inline int zone_is_reclaim_locked(const struct zone *zone)
+{
+ return test_bit(ZONE_RECLAIM_LOCKED, &zone->flags);
+}
+
+static inline int zone_is_oom_locked(const struct zone *zone)
+{
+ return test_bit(ZONE_OOM_LOCKED, &zone->flags);
+}
+
/*
* The "priority" of VM scanning is how much of the queues we will scan in one
* go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the
@@ -324,6 +388,17 @@ struct zone {
#define MAX_ZONES_PER_ZONELIST (MAX_NUMNODES * MAX_NR_ZONES)
#ifdef CONFIG_NUMA
+
+/*
+ * The NUMA zonelists are doubled becausse we need zonelists that restrict the
+ * allocations to a single node for GFP_THISNODE.
+ *
+ * [0 .. MAX_NR_ZONES -1] : Zonelists with fallback
+ * [MAZ_NR_ZONES ... MAZ_ZONELISTS -1] : No fallback (GFP_THISNODE)
+ */
+#define MAX_ZONELISTS (2 * MAX_NR_ZONES)
+
+
/*
* We cache key information from each zonelist for smaller cache
* footprint when scanning for free pages in get_page_from_freelist().
@@ -389,6 +464,7 @@ struct zonelist_cache {
unsigned long last_full_zap; /* when last zap'd (jiffies) */
};
#else
+#define MAX_ZONELISTS MAX_NR_ZONES
struct zonelist_cache;
#endif
@@ -455,7 +531,7 @@ extern struct page *mem_map;
struct bootmem_data;
typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
- struct zonelist node_zonelists[MAX_NR_ZONES];
+ struct zonelist node_zonelists[MAX_ZONELISTS];
int nr_zones;
#ifdef CONFIG_FLAT_NODE_MEM_MAP
struct page *node_mem_map;
@@ -708,6 +784,9 @@ extern struct zone *next_zone(struct zone *zone);
#define PAGES_PER_SECTION (1UL << PFN_SECTION_SHIFT)
#define PAGE_SECTION_MASK (~(PAGES_PER_SECTION-1))
+#define SECTION_BLOCKFLAGS_BITS \
+ ((1UL << (PFN_SECTION_SHIFT - pageblock_order)) * NR_PAGEBLOCK_BITS)
+
#if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS
#error Allocator MAX_ORDER exceeds SECTION_SIZE
#endif
@@ -727,6 +806,9 @@ struct mem_section {
* before using it wrong.
*/
unsigned long section_mem_map;
+
+ /* See declaration of similar field in struct zone */
+ unsigned long *pageblock_flags;
};
#ifdef CONFIG_SPARSEMEM_EXTREME
@@ -771,12 +853,17 @@ static inline struct page *__section_mem_map_addr(struct mem_section *section)
return (struct page *)map;
}
-static inline int valid_section(struct mem_section *section)
+static inline int present_section(struct mem_section *section)
{
return (section && (section->section_mem_map & SECTION_MARKED_PRESENT));
}
-static inline int section_has_mem_map(struct mem_section *section)
+static inline int present_section_nr(unsigned long nr)
+{
+ return present_section(__nr_to_section(nr));
+}
+
+static inline int valid_section(struct mem_section *section)
{
return (section && (section->section_mem_map & SECTION_HAS_MEM_MAP));
}
@@ -798,6 +885,13 @@ static inline int pfn_valid(unsigned long pfn)
return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
}
+static inline int pfn_present(unsigned long pfn)
+{
+ if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
+ return 0;
+ return present_section(__nr_to_section(pfn_to_section_nr(pfn)));
+}
+
/*
* These are _only_ used during initialisation, therefore they
* can use __initdata ... They could have names to indicate
diff --git a/include/linux/module.h b/include/linux/module.h
index b6a646cea1c..642f325e491 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -312,9 +312,6 @@ struct module
/* Arch-specific module values */
struct mod_arch_specific arch;
- /* Am I unsafe to unload? */
- int unsafe;
-
unsigned int taints; /* same bits as kernel:tainted */
#ifdef CONFIG_GENERIC_BUG
@@ -346,6 +343,9 @@ struct module
/* Section attributes */
struct module_sect_attrs *sect_attrs;
+
+ /* Notes attributes */
+ struct module_notes_attrs *notes_attrs;
#endif
/* Per-cpu data. */
@@ -441,16 +441,6 @@ static inline void __module_get(struct module *module)
__mod ? __mod->name : "kernel"; \
})
-#define __unsafe(mod) \
-do { \
- if (mod && !(mod)->unsafe) { \
- printk(KERN_WARNING \
- "Module %s cannot be unloaded due to unsafe usage in" \
- " %s:%u\n", (mod)->name, __FILE__, __LINE__); \
- (mod)->unsafe = 1; \
- } \
-} while(0)
-
/* For kallsyms to ask for address resolution. NULL means not found. */
const char *module_address_lookup(unsigned long addr,
unsigned long *symbolsize,
@@ -518,8 +508,6 @@ static inline void module_put(struct module *module)
#define module_name(mod) "kernel"
-#define __unsafe(mod)
-
/* For kallsyms to ask for address resolution. NULL means not found. */
static inline const char *module_address_lookup(unsigned long addr,
unsigned long *symbolsize,
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index c83588c8d08..13410b20600 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -38,7 +38,11 @@ struct kernel_param {
unsigned int perm;
param_set_fn set;
param_get_fn get;
- void *arg;
+ union {
+ void *arg;
+ const struct kparam_string *str;
+ const struct kparam_array *arr;
+ };
};
/* Special one for strings we want to copy into */
@@ -66,11 +70,11 @@ struct kparam_array
/* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
- static char __param_str_##name[] = prefix #name; \
+ static const char __param_str_##name[] = prefix #name; \
static struct kernel_param const __param_##name \
__attribute_used__ \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
- = { __param_str_##name, perm, set, get, arg }
+ = { __param_str_##name, perm, set, get, { arg } }
#define module_param_call(name, set, get, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
@@ -88,10 +92,10 @@ struct kparam_array
/* Actually copy string: maxlen param is usually sizeof(string). */
#define module_param_string(name, string, len, perm) \
- static struct kparam_string __param_string_##name \
+ static const struct kparam_string __param_string_##name \
= { len, string }; \
module_param_call(name, param_set_copystring, param_get_string, \
- &__param_string_##name, perm); \
+ .str = &__param_string_##name, perm); \
__MODULE_PARM_TYPE(name, "string")
/* Called on module insert or kernel boot */
@@ -149,11 +153,11 @@ extern int param_get_invbool(char *buffer, struct kernel_param *kp);
/* Comma-separated array: *nump is set to number they actually specified. */
#define module_param_array_named(name, array, type, nump, perm) \
- static struct kparam_array __param_arr_##name \
+ static const struct kparam_array __param_arr_##name \
= { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\
sizeof(array[0]), array }; \
module_param_call(name, param_array_set, param_array_get, \
- &__param_arr_##name, perm); \
+ .arr = &__param_arr_##name, perm); \
__MODULE_PARM_TYPE(name, "array of " #type)
#define module_param_array(name, type, nump, perm) \
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 0d50ea3df68..601479772b9 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -29,7 +29,8 @@
* - task may not exit with mutex held
* - memory areas where held locks reside must not be freed
* - held mutexes must not be reinitialized
- * - mutexes may not be used in irq contexts
+ * - mutexes may not be used in hardware or software interrupt
+ * contexts such as tasklets and timers
*
* These semantics are fully enforced when DEBUG_MUTEXES is
* enabled. Furthermore, besides enforcing the above rules, the mutex
@@ -120,14 +121,17 @@ static inline int fastcall mutex_is_locked(struct mutex *lock)
* See kernel/mutex.c for detailed documentation of these APIs.
* Also see Documentation/mutex-design.txt.
*/
-extern void fastcall mutex_lock(struct mutex *lock);
-extern int __must_check fastcall mutex_lock_interruptible(struct mutex *lock);
-
#ifdef CONFIG_DEBUG_LOCK_ALLOC
extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock,
unsigned int subclass);
+
+#define mutex_lock(lock) mutex_lock_nested(lock, 0)
+#define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0)
#else
+extern void fastcall mutex_lock(struct mutex *lock);
+extern int __must_check fastcall mutex_lock_interruptible(struct mutex *lock);
+
# define mutex_lock_nested(lock, subclass) mutex_lock(lock)
# define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock)
#endif
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 6c38efbd810..4cb4f8d2f78 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -81,8 +81,8 @@ extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry
extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
extern void release_open_intent(struct nameidata *);
-extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry *lookup_one_len_kern(const char *, struct dentry *, int);
+extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
+extern struct dentry *lookup_one_noperm(const char *, struct dentry *);
extern int follow_down(struct vfsmount **, struct dentry **);
extern int follow_up(struct vfsmount **, struct dentry **);
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index 0f3e6930254..cc2b47240a8 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -26,6 +26,7 @@
#define NBD_PRINT_DEBUG _IO( 0xab, 6 )
#define NBD_SET_SIZE_BLOCKS _IO( 0xab, 7 )
#define NBD_DISCONNECT _IO( 0xab, 8 )
+#define NBD_SET_TIMEOUT _IO( 0xab, 9 )
enum {
NBD_CMD_READ = 0,
@@ -65,6 +66,7 @@ struct nbd_device {
int blksize;
u64 bytesize;
pid_t pid; /* pid of nbd-client, if attached */
+ int xmit_timeout;
};
#endif
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 39dd83b183a..6f85db3535e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -407,6 +407,24 @@ static inline void napi_enable(struct napi_struct *n)
clear_bit(NAPI_STATE_SCHED, &n->state);
}
+#ifdef CONFIG_SMP
+/**
+ * napi_synchronize - wait until NAPI is not running
+ * @n: napi context
+ *
+ * Wait until NAPI is done being scheduled on this context.
+ * Waits till any outstanding processing completes but
+ * does not disable future activations.
+ */
+static inline void napi_synchronize(const struct napi_struct *n)
+{
+ while (test_bit(NAPI_STATE_SCHED, &n->state))
+ msleep(1);
+}
+#else
+# define napi_synchronize(n) barrier()
+#endif
+
/*
* The DEVICE structure.
* Actually, this whole structure is a big mistake. It mixes I/O
@@ -827,7 +845,7 @@ static inline int dev_parse_header(const struct sk_buff *skb,
{
const struct net_device *dev = skb->dev;
- if (!dev->header_ops->parse)
+ if (!dev->header_ops || !dev->header_ops->parse)
return 0;
return dev->header_ops->parse(skb, haddr);
}
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 1dd075eda59..16adac688af 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -51,7 +51,7 @@ struct sk_buff;
struct net_device;
typedef unsigned int nf_hookfn(unsigned int hooknum,
- struct sk_buff **skb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
@@ -183,7 +183,7 @@ void nf_log_packet(int pf,
struct nf_loginfo *li,
const char *fmt, ...);
-int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
+int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh);
@@ -195,7 +195,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
* value indicates the packet has been consumed by the hook.
*/
static inline int nf_hook_thresh(int pf, unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh,
@@ -207,14 +207,14 @@ static inline int nf_hook_thresh(int pf, unsigned int hook,
if (list_empty(&nf_hooks[pf][hook]))
return 1;
#endif
- return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
+ return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
}
-static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
+static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
- return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN, 1);
+ return nf_hook_thresh(pf, hook, skb, indev, outdev, okfn, INT_MIN, 1);
}
/* Activate hook; either okfn or kfree_skb called, unless a hook
@@ -241,13 +241,13 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
({int __ret; \
-if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\
+if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, thresh, 1)) == 1)\
__ret = (okfn)(skb); \
__ret;})
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \
({int __ret; \
-if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\
+if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\
__ret = (okfn)(skb); \
__ret;})
@@ -287,7 +287,7 @@ extern void nf_invalidate_cache(int pf);
/* Call this before modifying an existing packet: ensures it is
modifiable and linear to the point you care about (writable_len).
Returns true or false. */
-extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
+extern int skb_make_writable(struct sk_buff *skb, unsigned int writable_len);
static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
{
@@ -317,7 +317,7 @@ struct nf_afinfo {
unsigned int dataoff, u_int8_t protocol);
void (*saveroute)(const struct sk_buff *skb,
struct nf_info *info);
- int (*reroute)(struct sk_buff **skb,
+ int (*reroute)(struct sk_buff *skb,
const struct nf_info *info);
int route_key_size;
};
@@ -371,15 +371,15 @@ extern struct proc_dir_entry *proc_net_netfilter;
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
static inline int nf_hook_thresh(int pf, unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *), int thresh,
int cond)
{
- return okfn(*pskb);
+ return okfn(skb);
}
-static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
+static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev, struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
diff --git a/include/linux/netfilter/nf_conntrack_amanda.h b/include/linux/netfilter/nf_conntrack_amanda.h
index 26c223544ae..0bb5a6976bf 100644
--- a/include/linux/netfilter/nf_conntrack_amanda.h
+++ b/include/linux/netfilter/nf_conntrack_amanda.h
@@ -2,7 +2,7 @@
#define _NF_CONNTRACK_AMANDA_H
/* AMANDA tracking. */
-extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff **pskb,
+extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
index b7c360ffd0d..47727d7546e 100644
--- a/include/linux/netfilter/nf_conntrack_ftp.h
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -32,7 +32,7 @@ struct nf_conntrack_expect;
/* For NAT to hook in when we find a packet which describes what other
* connection we should expect. */
-extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
+extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
enum nf_ct_ftp_type type,
unsigned int matchoff,
diff --git a/include/linux/netfilter/nf_conntrack_h323.h b/include/linux/netfilter/nf_conntrack_h323.h
index 08e2f4977c2..aabd24ac763 100644
--- a/include/linux/netfilter/nf_conntrack_h323.h
+++ b/include/linux/netfilter/nf_conntrack_h323.h
@@ -36,27 +36,27 @@ extern void nf_conntrack_h245_expect(struct nf_conn *new,
struct nf_conntrack_expect *this);
extern void nf_conntrack_q931_expect(struct nf_conn *new,
struct nf_conntrack_expect *this);
-extern int (*set_h245_addr_hook) (struct sk_buff **pskb,
+extern int (*set_h245_addr_hook) (struct sk_buff *skb,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr,
union nf_conntrack_address *addr,
__be16 port);
-extern int (*set_h225_addr_hook) (struct sk_buff **pskb,
+extern int (*set_h225_addr_hook) (struct sk_buff *skb,
unsigned char **data, int dataoff,
TransportAddress *taddr,
union nf_conntrack_address *addr,
__be16 port);
-extern int (*set_sig_addr_hook) (struct sk_buff **pskb,
+extern int (*set_sig_addr_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count);
-extern int (*set_ras_addr_hook) (struct sk_buff **pskb,
+extern int (*set_ras_addr_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count);
-extern int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
+extern int (*nat_rtp_rtcp_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -64,24 +64,24 @@ extern int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
__be16 port, __be16 rtp_port,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp);
-extern int (*nat_t120_hook) (struct sk_buff **pskb, struct nf_conn *ct,
+extern int (*nat_t120_hook) (struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr, __be16 port,
struct nf_conntrack_expect *exp);
-extern int (*nat_h245_hook) (struct sk_buff **pskb, struct nf_conn *ct,
+extern int (*nat_h245_hook) (struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr, __be16 port,
struct nf_conntrack_expect *exp);
-extern int (*nat_callforwarding_hook) (struct sk_buff **pskb,
+extern int (*nat_callforwarding_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr,
__be16 port,
struct nf_conntrack_expect *exp);
-extern int (*nat_q931_hook) (struct sk_buff **pskb, struct nf_conn *ct,
+extern int (*nat_q931_hook) (struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, TransportAddress *taddr,
int idx, __be16 port,
diff --git a/include/linux/netfilter/nf_conntrack_irc.h b/include/linux/netfilter/nf_conntrack_irc.h
index 2ab6b825591..36282bf71b6 100644
--- a/include/linux/netfilter/nf_conntrack_irc.h
+++ b/include/linux/netfilter/nf_conntrack_irc.h
@@ -5,7 +5,7 @@
#define IRC_PORT 6667
-extern unsigned int (*nf_nat_irc_hook)(struct sk_buff **pskb,
+extern unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h
index c93061f3314..23435496d24 100644
--- a/include/linux/netfilter/nf_conntrack_pptp.h
+++ b/include/linux/netfilter/nf_conntrack_pptp.h
@@ -301,13 +301,13 @@ struct nf_conn;
struct nf_conntrack_expect;
extern int
-(*nf_nat_pptp_hook_outbound)(struct sk_buff **pskb,
+(*nf_nat_pptp_hook_outbound)(struct sk_buff *skb,
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq);
extern int
-(*nf_nat_pptp_hook_inbound)(struct sk_buff **pskb,
+(*nf_nat_pptp_hook_inbound)(struct sk_buff *skb,
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq);
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index bb7f2041db7..9fff19779bd 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -21,11 +21,11 @@ enum sip_header_pos {
POS_SDP_HEADER,
};
-extern unsigned int (*nf_nat_sip_hook)(struct sk_buff **pskb,
+extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr);
-extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff **pskb,
+extern unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp,
const char *dptr);
diff --git a/include/linux/netfilter/nf_conntrack_tftp.h b/include/linux/netfilter/nf_conntrack_tftp.h
index 0d79b7ae051..c78d38fdb05 100644
--- a/include/linux/netfilter/nf_conntrack_tftp.h
+++ b/include/linux/netfilter/nf_conntrack_tftp.h
@@ -13,7 +13,7 @@ struct tftphdr {
#define TFTP_OPCODE_ACK 4
#define TFTP_OPCODE_ERROR 5
-extern unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
+extern unsigned int (*nf_nat_tftp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp);
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 64f425a855b..03e6ce979ea 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -191,7 +191,7 @@ struct xt_target
/* Returns verdict. Argument order changed since 2.6.9, as this
must now handle non-linear skbs, using skb_copy_bits and
skb_ip_make_writable. */
- unsigned int (*target)(struct sk_buff **pskb,
+ unsigned int (*target)(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h
index b157897e779..dd5a4fd4cfd 100644
--- a/include/linux/netfilter/xt_sctp.h
+++ b/include/linux/netfilter/xt_sctp.h
@@ -7,9 +7,6 @@
#define XT_SCTP_VALID_FLAGS 0x07
-#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
-
-
struct xt_sctp_flag_info {
u_int8_t chunktype;
u_int8_t flag;
@@ -59,21 +56,21 @@ struct xt_sctp_info {
#define SCTP_CHUNKMAP_RESET(chunkmap) \
do { \
int i; \
- for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
+ for (i = 0; i < ARRAY_SIZE(chunkmap); i++) \
chunkmap[i] = 0; \
} while (0)
#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \
do { \
int i; \
- for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
+ for (i = 0; i < ARRAY_SIZE(chunkmap); i++) \
chunkmap[i] = ~0; \
} while (0)
#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \
do { \
int i; \
- for (i = 0; i < ELEMCOUNT(chunkmap); i++) \
+ for (i = 0; i < ARRAY_SIZE(srcmap); i++) \
destmap[i] = srcmap[i]; \
} while (0)
@@ -81,7 +78,7 @@ struct xt_sctp_info {
({ \
int i; \
int flag = 1; \
- for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
+ for (i = 0; i < ARRAY_SIZE(chunkmap); i++) { \
if (chunkmap[i]) { \
flag = 0; \
break; \
@@ -94,7 +91,7 @@ struct xt_sctp_info {
({ \
int i; \
int flag = 1; \
- for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \
+ for (i = 0; i < ARRAY_SIZE(chunkmap); i++) { \
if (chunkmap[i] != ~0) { \
flag = 0; \
break; \
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 584cd1b18f1..2fc73fa8e37 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -287,7 +287,7 @@ struct arpt_error
extern int arpt_register_table(struct arpt_table *table,
const struct arpt_replace *repl);
extern void arpt_unregister_table(struct arpt_table *table);
-extern unsigned int arpt_do_table(struct sk_buff **pskb,
+extern unsigned int arpt_do_table(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 94e0a7dc0cb..892f5b7771c 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -237,7 +237,7 @@ struct ebt_target
struct list_head list;
const char name[EBT_FUNCTION_MAXNAMELEN];
/* returns one of the standard verdicts */
- int (*target)(struct sk_buff **pskb, unsigned int hooknr,
+ int (*target)(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *targetdata, unsigned int datalen);
/* 0 == let it in */
@@ -294,7 +294,7 @@ extern int ebt_register_watcher(struct ebt_watcher *watcher);
extern void ebt_unregister_watcher(struct ebt_watcher *watcher);
extern int ebt_register_target(struct ebt_target *target);
extern void ebt_unregister_target(struct ebt_target *target);
-extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb,
+extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
struct ebt_table *table);
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index ceae87a4c89..1a63adf5c4c 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -75,8 +75,8 @@ enum nf_ip_hook_priorities {
#define SO_ORIGINAL_DST 80
#ifdef __KERNEL__
-extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
-extern int ip_xfrm_me_harder(struct sk_buff **pskb);
+extern int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type);
+extern int ip_xfrm_me_harder(struct sk_buff *skb);
extern __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol);
#endif /*__KERNEL__*/
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index e992cd6b28f..d79ed69cbc1 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -337,7 +337,7 @@ struct ipt_error
.target.errorname = "ERROR", \
}
-extern unsigned int ipt_do_table(struct sk_buff **pskb,
+extern unsigned int ipt_do_table(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 9a720f05888..7dc481ce7cb 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -336,7 +336,7 @@ extern void ip6t_init(void) __init;
extern int ip6t_register_table(struct xt_table *table,
const struct ip6t_replace *repl);
extern void ip6t_unregister_table(struct xt_table *table);
-extern unsigned int ip6t_do_table(struct sk_buff **pskb,
+extern unsigned int ip6t_do_table(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 7250eeadd7b..c5164c257f7 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -47,10 +47,8 @@
#include <linux/nfs3.h>
#include <linux/nfs4.h>
#include <linux/nfs_xdr.h>
-
#include <linux/nfs_fs_sb.h>
-#include <linux/rwsem.h>
#include <linux/mempool.h>
/*
@@ -77,6 +75,9 @@ struct nfs_open_context {
struct nfs4_state *state;
fl_owner_t lockowner;
int mode;
+
+ unsigned long flags;
+#define NFS_CONTEXT_ERROR_WRITE (0)
int error;
struct list_head list;
@@ -133,11 +134,6 @@ struct nfs_inode {
* server.
*/
unsigned long cache_change_attribute;
- /*
- * Counter indicating the number of outstanding requests that
- * will cause a file data update.
- */
- atomic_t data_updates;
struct rb_root access_cache;
struct list_head access_cache_entry_lru;
@@ -205,27 +201,18 @@ static inline struct nfs_inode *NFS_I(struct inode *inode)
#define NFS_CLIENT(inode) (NFS_SERVER(inode)->client)
#define NFS_PROTO(inode) (NFS_SERVER(inode)->nfs_client->rpc_ops)
#define NFS_COOKIEVERF(inode) (NFS_I(inode)->cookieverf)
-#define NFS_READTIME(inode) (NFS_I(inode)->read_cache_jiffies)
-#define NFS_CHANGE_ATTR(inode) (NFS_I(inode)->change_attr)
-#define NFS_ATTRTIMEO(inode) (NFS_I(inode)->attrtimeo)
#define NFS_MINATTRTIMEO(inode) \
(S_ISDIR(inode->i_mode)? NFS_SERVER(inode)->acdirmin \
: NFS_SERVER(inode)->acregmin)
#define NFS_MAXATTRTIMEO(inode) \
(S_ISDIR(inode->i_mode)? NFS_SERVER(inode)->acdirmax \
: NFS_SERVER(inode)->acregmax)
-#define NFS_ATTRTIMEO_UPDATE(inode) (NFS_I(inode)->attrtimeo_timestamp)
#define NFS_FLAGS(inode) (NFS_I(inode)->flags)
#define NFS_STALE(inode) (test_bit(NFS_INO_STALE, &NFS_FLAGS(inode)))
#define NFS_FILEID(inode) (NFS_I(inode)->fileid)
-static inline int nfs_caches_unstable(struct inode *inode)
-{
- return atomic_read(&NFS_I(inode)->data_updates) != 0;
-}
-
static inline void nfs_mark_for_revalidate(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
@@ -237,12 +224,6 @@ static inline void nfs_mark_for_revalidate(struct inode *inode)
spin_unlock(&inode->i_lock);
}
-static inline void NFS_CACHEINV(struct inode *inode)
-{
- if (!nfs_caches_unstable(inode))
- nfs_mark_for_revalidate(inode);
-}
-
static inline int nfs_server_capable(struct inode *inode, int cap)
{
return NFS_SERVER(inode)->caps & cap;
@@ -253,28 +234,33 @@ static inline int NFS_USE_READDIRPLUS(struct inode *inode)
return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
}
+static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
+{
+ dentry->d_time = verf;
+}
+
/**
* nfs_save_change_attribute - Returns the inode attribute change cookie
- * @inode - pointer to inode
+ * @dir - pointer to parent directory inode
* The "change attribute" is updated every time we finish an operation
* that will result in a metadata change on the server.
*/
-static inline long nfs_save_change_attribute(struct inode *inode)
+static inline unsigned long nfs_save_change_attribute(struct inode *dir)
{
- return NFS_I(inode)->cache_change_attribute;
+ return NFS_I(dir)->cache_change_attribute;
}
/**
- * nfs_verify_change_attribute - Detects NFS inode cache updates
- * @inode - pointer to inode
+ * nfs_verify_change_attribute - Detects NFS remote directory changes
+ * @dir - pointer to parent directory inode
* @chattr - previously saved change attribute
- * Return "false" if metadata has been updated (or is in the process of
- * being updated) since the change attribute was saved.
+ * Return "false" if the verifiers doesn't match the change attribute.
+ * This would usually indicate that the directory contents have changed on
+ * the server, and that any dentries need revalidating.
*/
-static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long chattr)
+static inline int nfs_verify_change_attribute(struct inode *dir, unsigned long chattr)
{
- return !nfs_caches_unstable(inode)
- && time_after_eq(chattr, NFS_I(inode)->cache_change_attribute);
+ return chattr == NFS_I(dir)->cache_change_attribute;
}
/*
@@ -283,15 +269,14 @@ static inline int nfs_verify_change_attribute(struct inode *inode, unsigned long
extern int nfs_sync_mapping(struct address_space *mapping);
extern void nfs_zap_mapping(struct inode *inode, struct address_space *mapping);
extern void nfs_zap_caches(struct inode *);
+extern void nfs_invalidate_atime(struct inode *);
extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
struct nfs_fattr *);
extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
+extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int nfs_permission(struct inode *, int, struct nameidata *);
-extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *);
-extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
-extern void nfs_access_zap_cache(struct inode *inode);
extern int nfs_open(struct inode *, struct file *);
extern int nfs_release(struct inode *, struct file *);
extern int nfs_attribute_timeout(struct inode *inode);
@@ -301,13 +286,10 @@ extern int nfs_revalidate_mapping(struct inode *inode, struct address_space *map
extern int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping);
extern int nfs_setattr(struct dentry *, struct iattr *);
extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
-extern void nfs_begin_attr_update(struct inode *);
-extern void nfs_end_attr_update(struct inode *);
-extern void nfs_begin_data_update(struct inode *);
-extern void nfs_end_data_update(struct inode *);
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
extern void put_nfs_open_context(struct nfs_open_context *ctx);
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode);
+extern u64 nfs_compat_user_ino64(u64 fileid);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern __be32 root_nfs_parse_addr(char *name); /*__init*/
@@ -328,14 +310,15 @@ extern const struct inode_operations nfs3_file_inode_operations;
extern const struct file_operations nfs_file_operations;
extern const struct address_space_operations nfs_file_aops;
-static inline struct rpc_cred *nfs_file_cred(struct file *file)
+static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
{
- if (file != NULL) {
- struct nfs_open_context *ctx;
+ return filp->private_data;
+}
- ctx = (struct nfs_open_context*)file->private_data;
- return ctx->cred;
- }
+static inline struct rpc_cred *nfs_file_cred(struct file *file)
+{
+ if (file != NULL)
+ return nfs_file_open_context(file)->cred;
return NULL;
}
@@ -378,6 +361,8 @@ extern const struct file_operations nfs_dir_operations;
extern struct dentry_operations nfs_dentry_operations;
extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr);
+extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags);
+extern void nfs_access_zap_cache(struct inode *inode);
/*
* linux/fs/nfs/symlink.c
@@ -420,15 +405,14 @@ extern int nfs_flush_incompatible(struct file *file, struct page *page);
extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
extern void nfs_writedata_release(void *);
-extern int nfs_set_page_dirty(struct page *);
/*
* Try to write back everything synchronously (but check the
* return value!)
*/
extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_control *, int);
-extern int nfs_sync_mapping_range(struct address_space *, loff_t, loff_t, int);
extern int nfs_wb_all(struct inode *inode);
+extern int nfs_wb_nocommit(struct inode *inode);
extern int nfs_wb_page(struct inode *inode, struct page* page);
extern int nfs_wb_page_priority(struct inode *inode, struct page* page, int how);
extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 78e60798d10..30dbcc185e6 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -30,7 +30,6 @@
#define PG_BUSY 0
#define PG_NEED_COMMIT 1
#define PG_NEED_RESCHED 2
-#define PG_NEED_FLUSH 3
struct nfs_inode;
struct nfs_page {
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index cf74a4db84a..daab252f2e5 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -62,7 +62,8 @@ struct nfs_fattr {
#define NFS_ATTR_FATTR 0x0002 /* post-op attributes */
#define NFS_ATTR_FATTR_V3 0x0004 /* NFSv3 attributes */
#define NFS_ATTR_FATTR_V4 0x0008 /* NFSv4 change attribute */
-#define NFS_ATTR_FATTR_V4_REFERRAL 0x0010 /* NFSv4 referral */
+#define NFS_ATTR_WCC_V4 0x0010 /* pre-op change attribute */
+#define NFS_ATTR_FATTR_V4_REFERRAL 0x0020 /* NFSv4 referral */
/*
* Info on the file system
@@ -538,10 +539,13 @@ typedef u64 clientid4;
struct nfs4_accessargs {
const struct nfs_fh * fh;
+ const u32 * bitmask;
u32 access;
};
struct nfs4_accessres {
+ const struct nfs_server * server;
+ struct nfs_fattr * fattr;
u32 supported;
u32 access;
};
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 5cd19246909..bcb7abafbca 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -127,17 +127,9 @@ void nfsd_export_shutdown(void);
void nfsd_export_flush(void);
void exp_readlock(void);
void exp_readunlock(void);
-struct svc_export * exp_get_by_name(struct auth_domain *clp,
- struct vfsmount *mnt,
- struct dentry *dentry,
- struct cache_req *reqp);
struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
struct vfsmount *,
struct dentry *);
-struct svc_export * exp_parent(struct auth_domain *clp,
- struct vfsmount *mnt,
- struct dentry *dentry,
- struct cache_req *reqp);
struct svc_export * rqst_exp_parent(struct svc_rqst *,
struct vfsmount *mnt,
struct dentry *dentry);
@@ -157,9 +149,6 @@ static inline void exp_get(struct svc_export *exp)
{
cache_get(&exp->h);
}
-extern struct svc_export *
-exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
- struct cache_req *reqp);
struct svc_export * rqst_exp_find(struct svc_rqst *, int, u32 *);
#endif /* __KERNEL__ */
diff --git a/include/linux/nls.h b/include/linux/nls.h
index 816c04ad738..6a882208301 100644
--- a/include/linux/nls.h
+++ b/include/linux/nls.h
@@ -7,13 +7,13 @@
typedef __u16 wchar_t;
struct nls_table {
- char *charset;
- char *alias;
+ const char *charset;
+ const char *alias;
int (*uni2char) (wchar_t uni, unsigned char *out, int boundlen);
int (*char2uni) (const unsigned char *rawstring, int boundlen,
wchar_t *uni);
- unsigned char *charset2lower;
- unsigned char *charset2upper;
+ const unsigned char *charset2lower;
+ const unsigned char *charset2upper;
struct module *owner;
struct nls_table *next;
};
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 52c54a5720f..905e18f4b41 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -338,31 +338,88 @@ static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
#endif /* MAX_NUMNODES */
/*
+ * Bitmasks that are kept for all the nodes.
+ */
+enum node_states {
+ N_POSSIBLE, /* The node could become online at some point */
+ N_ONLINE, /* The node is online */
+ N_NORMAL_MEMORY, /* The node has regular memory */
+#ifdef CONFIG_HIGHMEM
+ N_HIGH_MEMORY, /* The node has regular or high memory */
+#else
+ N_HIGH_MEMORY = N_NORMAL_MEMORY,
+#endif
+ N_CPU, /* The node has one or more cpus */
+ NR_NODE_STATES
+};
+
+/*
* The following particular system nodemasks and operations
* on them manage all possible and online nodes.
*/
-extern nodemask_t node_online_map;
-extern nodemask_t node_possible_map;
+extern nodemask_t node_states[NR_NODE_STATES];
#if MAX_NUMNODES > 1
-#define num_online_nodes() nodes_weight(node_online_map)
-#define num_possible_nodes() nodes_weight(node_possible_map)
-#define node_online(node) node_isset((node), node_online_map)
-#define node_possible(node) node_isset((node), node_possible_map)
-#define first_online_node first_node(node_online_map)
-#define next_online_node(nid) next_node((nid), node_online_map)
+static inline int node_state(int node, enum node_states state)
+{
+ return node_isset(node, node_states[state]);
+}
+
+static inline void node_set_state(int node, enum node_states state)
+{
+ __node_set(node, &node_states[state]);
+}
+
+static inline void node_clear_state(int node, enum node_states state)
+{
+ __node_clear(node, &node_states[state]);
+}
+
+static inline int num_node_state(enum node_states state)
+{
+ return nodes_weight(node_states[state]);
+}
+
+#define for_each_node_state(__node, __state) \
+ for_each_node_mask((__node), node_states[__state])
+
+#define first_online_node first_node(node_states[N_ONLINE])
+#define next_online_node(nid) next_node((nid), node_states[N_ONLINE])
+
extern int nr_node_ids;
#else
-#define num_online_nodes() 1
-#define num_possible_nodes() 1
-#define node_online(node) ((node) == 0)
-#define node_possible(node) ((node) == 0)
+
+static inline int node_state(int node, enum node_states state)
+{
+ return node == 0;
+}
+
+static inline void node_set_state(int node, enum node_states state)
+{
+}
+
+static inline void node_clear_state(int node, enum node_states state)
+{
+}
+
+static inline int num_node_state(enum node_states state)
+{
+ return 1;
+}
+
+#define for_each_node_state(node, __state) \
+ for ( (node) = 0; (node) == 0; (node) = 1)
+
#define first_online_node 0
#define next_online_node(nid) (MAX_NUMNODES)
#define nr_node_ids 1
+
#endif
+#define node_online_map node_states[N_ONLINE]
+#define node_possible_map node_states[N_POSSIBLE]
+
#define any_online_node(mask) \
({ \
int node; \
@@ -372,10 +429,15 @@ extern int nr_node_ids;
node; \
})
-#define node_set_online(node) set_bit((node), node_online_map.bits)
-#define node_set_offline(node) clear_bit((node), node_online_map.bits)
+#define num_online_nodes() num_node_state(N_ONLINE)
+#define num_possible_nodes() num_node_state(N_POSSIBLE)
+#define node_online(node) node_state((node), N_ONLINE)
+#define node_possible(node) node_state((node), N_POSSIBLE)
+
+#define node_set_online(node) node_set_state((node), N_ONLINE)
+#define node_set_offline(node) node_clear_state((node), N_ONLINE)
-#define for_each_node(node) for_each_node_mask((node), node_possible_map)
-#define for_each_online_node(node) for_each_node_mask((node), node_online_map)
+#define for_each_node(node) for_each_node_state(node, N_POSSIBLE)
+#define for_each_online_node(node) for_each_node_state(node, N_ONLINE)
#endif /* __LINUX_NODEMASK_H */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index bec4485e3d7..033a648709b 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -23,7 +23,6 @@ struct pid_namespace;
*/
struct nsproxy {
atomic_t count;
- spinlock_t nslock;
struct uts_namespace *uts_ns;
struct ipc_namespace *ipc_ns;
struct mnt_namespace *mnt_ns;
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 91bf84b9d14..212bffb2b17 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -22,5 +22,10 @@ extern int of_device_register(struct of_device *ofdev);
extern void of_device_unregister(struct of_device *ofdev);
extern void of_release_dev(struct device *dev);
+static inline void of_device_free(struct of_device *dev)
+{
+ of_release_dev(&dev->dev);
+}
+
#endif /* __KERNEL__ */
#endif /* _LINUX_OF_DEVICE_H */
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 448f70b30a0..a8efcfeea73 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -48,6 +48,10 @@ struct of_platform_driver
#define to_of_platform_driver(drv) \
container_of(drv,struct of_platform_driver, driver)
+extern int of_register_driver(struct of_platform_driver *drv,
+ struct bus_type *bus);
+extern void of_unregister_driver(struct of_platform_driver *drv);
+
#include <asm/of_platform.h>
extern struct of_device *of_find_device_by_node(struct device_node *np);
diff --git a/include/linux/oom.h b/include/linux/oom.h
index ad76463629a..3852436b652 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -7,4 +7,28 @@
#define OOM_ADJUST_MIN (-16)
#define OOM_ADJUST_MAX 15
-#endif
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+
+struct zonelist;
+struct notifier_block;
+
+/*
+ * Types of limitations to the nodes from which allocations may occur
+ */
+enum oom_constraint {
+ CONSTRAINT_NONE,
+ CONSTRAINT_CPUSET,
+ CONSTRAINT_MEMORY_POLICY,
+};
+
+extern int try_set_zone_oom(struct zonelist *zonelist);
+extern void clear_zonelist_oom(struct zonelist *zonelist);
+
+extern void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order);
+extern int register_oom_notifier(struct notifier_block *nb);
+extern int unregister_oom_notifier(struct notifier_block *nb);
+
+#endif /* __KERNEL__*/
+#endif /* _INCLUDE_LINUX_OOM_H */
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
new file mode 100644
index 00000000000..051c1b1ede4
--- /dev/null
+++ b/include/linux/page-isolation.h
@@ -0,0 +1,37 @@
+#ifndef __LINUX_PAGEISOLATION_H
+#define __LINUX_PAGEISOLATION_H
+
+/*
+ * Changes migrate type in [start_pfn, end_pfn) to be MIGRATE_ISOLATE.
+ * If specified range includes migrate types other than MOVABLE,
+ * this will fail with -EBUSY.
+ *
+ * For isolating all pages in the range finally, the caller have to
+ * free all pages in the range. test_page_isolated() can be used for
+ * test it.
+ */
+extern int
+start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
+
+/*
+ * Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE.
+ * target range is [start_pfn, end_pfn)
+ */
+extern int
+undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
+
+/*
+ * test all pages in [start_pfn, end_pfn)are isolated or not.
+ */
+extern int
+test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
+
+/*
+ * Internal funcs.Changes pageblock's migrate type.
+ * Please use make_pagetype_isolated()/make_pagetype_movable().
+ */
+extern int set_migratetype_isolate(struct page *page);
+extern void unset_migratetype_isolate(struct page *page);
+
+
+#endif
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
new file mode 100644
index 00000000000..e875905f7b1
--- /dev/null
+++ b/include/linux/pageblock-flags.h
@@ -0,0 +1,75 @@
+/*
+ * Macros for manipulating and testing flags related to a
+ * pageblock_nr_pages number of pages.
+ *
+ * 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 of the License
+ *
+ * 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 (C) IBM Corporation, 2006
+ *
+ * Original author, Mel Gorman
+ * Major cleanups and reduction of bit operations, Andy Whitcroft
+ */
+#ifndef PAGEBLOCK_FLAGS_H
+#define PAGEBLOCK_FLAGS_H
+
+#include <linux/types.h>
+
+/* Macro to aid the definition of ranges of bits */
+#define PB_range(name, required_bits) \
+ name, name ## _end = (name + required_bits) - 1
+
+/* Bit indices that affect a whole block of pages */
+enum pageblock_bits {
+ PB_range(PB_migrate, 3), /* 3 bits required for migrate types */
+ NR_PAGEBLOCK_BITS
+};
+
+#ifdef CONFIG_HUGETLB_PAGE
+
+#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
+
+/* Huge page sizes are variable */
+extern int pageblock_order;
+
+#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
+
+/* Huge pages are a constant size */
+#define pageblock_order HUGETLB_PAGE_ORDER
+
+#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
+
+#else /* CONFIG_HUGETLB_PAGE */
+
+/* If huge pages are not used, group by MAX_ORDER_NR_PAGES */
+#define pageblock_order (MAX_ORDER-1)
+
+#endif /* CONFIG_HUGETLB_PAGE */
+
+#define pageblock_nr_pages (1UL << pageblock_order)
+
+/* Forward declaration */
+struct page;
+
+/* Declarations for getting and setting flags. See mm/page_alloc.c */
+unsigned long get_pageblock_flags_group(struct page *page,
+ int start_bitidx, int end_bitidx);
+void set_pageblock_flags_group(struct page *page, unsigned long flags,
+ int start_bitidx, int end_bitidx);
+
+#define get_pageblock_flags(page) \
+ get_pageblock_flags_group(page, 0, NR_PAGEBLOCK_BITS-1)
+#define set_pageblock_flags(page) \
+ set_pageblock_flags_group(page, 0, NR_PAGEBLOCK_BITS-1)
+
+#endif /* PAGEBLOCK_FLAGS_H */
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 8a83537d697..db8a410ae9e 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -84,11 +84,11 @@ static inline struct page *page_cache_alloc_cold(struct address_space *x)
typedef int filler_t(void *, struct page *);
extern struct page * find_get_page(struct address_space *mapping,
- unsigned long index);
+ pgoff_t index);
extern struct page * find_lock_page(struct address_space *mapping,
- unsigned long index);
+ pgoff_t index);
extern struct page * find_or_create_page(struct address_space *mapping,
- unsigned long index, gfp_t gfp_mask);
+ pgoff_t index, gfp_t gfp_mask);
unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
unsigned int nr_pages, struct page **pages);
unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
@@ -96,44 +96,47 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
int tag, unsigned int nr_pages, struct page **pages);
+struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index);
+
/*
* Returns locked page at given index in given cache, creating it if needed.
*/
-static inline struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
+static inline struct page *grab_cache_page(struct address_space *mapping,
+ pgoff_t index)
{
return find_or_create_page(mapping, index, mapping_gfp_mask(mapping));
}
extern struct page * grab_cache_page_nowait(struct address_space *mapping,
- unsigned long index);
+ pgoff_t index);
extern struct page * read_cache_page_async(struct address_space *mapping,
- unsigned long index, filler_t *filler,
+ pgoff_t index, filler_t *filler,
void *data);
extern struct page * read_cache_page(struct address_space *mapping,
- unsigned long index, filler_t *filler,
+ pgoff_t index, filler_t *filler,
void *data);
extern int read_cache_pages(struct address_space *mapping,
struct list_head *pages, filler_t *filler, void *data);
static inline struct page *read_mapping_page_async(
struct address_space *mapping,
- unsigned long index, void *data)
+ pgoff_t index, void *data)
{
filler_t *filler = (filler_t *)mapping->a_ops->readpage;
return read_cache_page_async(mapping, index, filler, data);
}
static inline struct page *read_mapping_page(struct address_space *mapping,
- unsigned long index, void *data)
+ pgoff_t index, void *data)
{
filler_t *filler = (filler_t *)mapping->a_ops->readpage;
return read_cache_page(mapping, index, filler, data);
}
int add_to_page_cache(struct page *page, struct address_space *mapping,
- unsigned long index, gfp_t gfp_mask);
+ pgoff_t index, gfp_t gfp_mask);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
- unsigned long index, gfp_t gfp_mask);
+ pgoff_t index, gfp_t gfp_mask);
extern void remove_from_page_cache(struct page *page);
extern void __remove_from_page_cache(struct page *page);
@@ -218,6 +221,9 @@ static inline int fault_in_pages_writeable(char __user *uaddr, int size)
{
int ret;
+ if (unlikely(size == 0))
+ return 0;
+
/*
* Writing zeroes into userspace here is OK, because we know that if
* the zero gets there, we'll be overwriting it.
@@ -237,19 +243,23 @@ static inline int fault_in_pages_writeable(char __user *uaddr, int size)
return ret;
}
-static inline void fault_in_pages_readable(const char __user *uaddr, int size)
+static inline int fault_in_pages_readable(const char __user *uaddr, int size)
{
volatile char c;
int ret;
+ if (unlikely(size == 0))
+ return 0;
+
ret = __get_user(c, uaddr);
if (ret == 0) {
const char __user *end = uaddr + size - 1;
if (((unsigned long)uaddr & PAGE_MASK) !=
((unsigned long)end & PAGE_MASK))
- __get_user(c, end);
+ ret = __get_user(c, end);
}
+ return ret;
}
#endif /* _LINUX_PAGEMAP_H */
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 9cdd6943e01..ec3f7659832 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -510,7 +510,6 @@ extern struct pardevice *parport_open (int devnum, const char *name,
int flags, void *handle);
extern void parport_close (struct pardevice *dev);
extern ssize_t parport_device_id (int devnum, char *buffer, size_t len);
-extern int parport_device_num (int parport, int mux, int daisy);
extern void parport_daisy_deselect_all (struct parport *port);
extern int parport_daisy_select (struct parport *port, int daisy, int mode);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 2aaf1c16ce9..df948b44eda 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1636,6 +1636,7 @@
#define PCI_DEVICE_ID_ITE_8211 0x8211
#define PCI_DEVICE_ID_ITE_8212 0x8212
#define PCI_DEVICE_ID_ITE_8213 0x8213
+#define PCI_DEVICE_ID_ITE_8152 0x8152
#define PCI_DEVICE_ID_ITE_8872 0x8872
#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886
@@ -1994,6 +1995,8 @@
#define PCI_VENDOR_ID_TOPIC 0x151f
#define PCI_DEVICE_ID_TOPIC_TP560 0x0000
+#define PCI_VENDOR_ID_MAINPINE 0x1522
+#define PCI_DEVICE_ID_MAINPINE_PBRIDGE 0x0100
#define PCI_VENDOR_ID_ENE 0x1524
#define PCI_DEVICE_ID_ENE_CB712_SD 0x0550
#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551
@@ -2323,6 +2326,8 @@
#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
+#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b
+#define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff
#define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031
#define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h
index 3d9f70972cd..9007ccdfc11 100644
--- a/include/linux/percpu_counter.h
+++ b/include/linux/percpu_counter.h
@@ -30,10 +30,28 @@ struct percpu_counter {
#define FBC_BATCH (NR_CPUS*4)
#endif
-void percpu_counter_init(struct percpu_counter *fbc, s64 amount);
+int percpu_counter_init(struct percpu_counter *fbc, s64 amount);
+int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount);
void percpu_counter_destroy(struct percpu_counter *fbc);
-void percpu_counter_mod(struct percpu_counter *fbc, s32 amount);
-s64 percpu_counter_sum(struct percpu_counter *fbc);
+void percpu_counter_set(struct percpu_counter *fbc, s64 amount);
+void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch);
+s64 __percpu_counter_sum(struct percpu_counter *fbc);
+
+static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount)
+{
+ __percpu_counter_add(fbc, amount, FBC_BATCH);
+}
+
+static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
+{
+ s64 ret = __percpu_counter_sum(fbc);
+ return ret < 0 ? 0 : ret;
+}
+
+static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
+{
+ return __percpu_counter_sum(fbc);
+}
static inline s64 percpu_counter_read(struct percpu_counter *fbc)
{
@@ -61,17 +79,28 @@ struct percpu_counter {
s64 count;
};
-static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
+static inline int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
{
fbc->count = amount;
+ return 0;
}
+#define percpu_counter_init_irq percpu_counter_init
+
static inline void percpu_counter_destroy(struct percpu_counter *fbc)
{
}
+static inline void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
+{
+ fbc->count = amount;
+}
+
+#define __percpu_counter_add(fbc, amount, batch) \
+ percpu_counter_add(fbc, amount)
+
static inline void
-percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
+percpu_counter_add(struct percpu_counter *fbc, s64 amount)
{
preempt_disable();
fbc->count += amount;
@@ -88,21 +117,31 @@ static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc)
return fbc->count;
}
-static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
+static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc)
{
return percpu_counter_read_positive(fbc);
}
+static inline s64 percpu_counter_sum(struct percpu_counter *fbc)
+{
+ return percpu_counter_read(fbc);
+}
+
#endif /* CONFIG_SMP */
static inline void percpu_counter_inc(struct percpu_counter *fbc)
{
- percpu_counter_mod(fbc, 1);
+ percpu_counter_add(fbc, 1);
}
static inline void percpu_counter_dec(struct percpu_counter *fbc)
{
- percpu_counter_mod(fbc, -1);
+ percpu_counter_add(fbc, -1);
+}
+
+static inline void percpu_counter_sub(struct percpu_counter *fbc, s64 amount)
+{
+ percpu_counter_add(fbc, -amount);
}
#endif /* _LINUX_PERCPU_COUNTER_H */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 48b71badfb4..09a309b7b5d 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -104,104 +104,6 @@ extern void (*pm_idle)(void);
extern void (*pm_power_off)(void);
extern void (*pm_power_off_prepare)(void);
-typedef int __bitwise suspend_state_t;
-
-#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
-#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1)
-#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
-#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
-
-/**
- * struct pm_ops - Callbacks for managing platform dependent system sleep
- * states.
- *
- * @valid: Callback to determine if given system sleep state is supported by
- * the platform.
- * Valid (ie. supported) states are advertised in /sys/power/state. Note
- * that it still may be impossible to enter given system sleep state if the
- * conditions aren't right.
- * There is the %pm_valid_only_mem function available that can be assigned
- * to this if the platform only supports mem sleep.
- *
- * @set_target: Tell the platform which system sleep state is going to be
- * entered.
- * @set_target() is executed right prior to suspending devices. The
- * information conveyed to the platform code by @set_target() should be
- * disregarded by the platform as soon as @finish() is executed and if
- * @prepare() fails. If @set_target() fails (ie. returns nonzero),
- * @prepare(), @enter() and @finish() will not be called by the PM core.
- * This callback is optional. However, if it is implemented, the argument
- * passed to @prepare(), @enter() and @finish() is meaningless and should
- * be ignored.
- *
- * @prepare: Prepare the platform for entering the system sleep state indicated
- * by @set_target() or represented by the argument if @set_target() is not
- * implemented.
- * @prepare() is called right after devices have been suspended (ie. the
- * appropriate .suspend() method has been executed for each device) and
- * before the nonboot CPUs are disabled (it is executed with IRQs enabled).
- * This callback is optional. It returns 0 on success or a negative
- * error code otherwise, in which case the system cannot enter the desired
- * sleep state (@enter() and @finish() will not be called in that case).
- *
- * @enter: Enter the system sleep state indicated by @set_target() or
- * represented by the argument if @set_target() is not implemented.
- * This callback is mandatory. It returns 0 on success or a negative
- * error code otherwise, in which case the system cannot enter the desired
- * sleep state.
- *
- * @finish: Called when the system has just left a sleep state, right after
- * the nonboot CPUs have been enabled and before devices are resumed (it is
- * executed with IRQs enabled). If @set_target() is not implemented, the
- * argument represents the sleep state being left.
- * This callback is optional, but should be implemented by the platforms
- * that implement @prepare(). If implemented, it is always called after
- * @enter() (even if @enter() fails).
- */
-struct pm_ops {
- int (*valid)(suspend_state_t state);
- int (*set_target)(suspend_state_t state);
- int (*prepare)(suspend_state_t state);
- int (*enter)(suspend_state_t state);
- int (*finish)(suspend_state_t state);
-};
-
-#ifdef CONFIG_SUSPEND
-extern struct pm_ops *pm_ops;
-
-/**
- * pm_set_ops - set platform dependent power management ops
- * @pm_ops: The new power management operations to set.
- */
-extern void pm_set_ops(struct pm_ops *pm_ops);
-extern int pm_valid_only_mem(suspend_state_t state);
-
-/**
- * arch_suspend_disable_irqs - disable IRQs for suspend
- *
- * Disables IRQs (in the default case). This is a weak symbol in the common
- * code and thus allows architectures to override it if more needs to be
- * done. Not called for suspend to disk.
- */
-extern void arch_suspend_disable_irqs(void);
-
-/**
- * arch_suspend_enable_irqs - enable IRQs after suspend
- *
- * Enables IRQs (in the default case). This is a weak symbol in the common
- * code and thus allows architectures to override it if more needs to be
- * done. Not called for suspend to disk.
- */
-extern void arch_suspend_enable_irqs(void);
-
-extern int pm_suspend(suspend_state_t state);
-#else /* !CONFIG_SUSPEND */
-#define suspend_valid_only_mem NULL
-
-static inline void pm_set_ops(struct pm_ops *pm_ops) {}
-static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
-#endif /* !CONFIG_SUSPEND */
-
/*
* Device power management
*/
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 16b46aace34..664d68cb1fb 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -243,11 +243,11 @@ struct pnp_fixup {
#define PNP_CONFIGURABLE 0x0008
#define PNP_REMOVABLE 0x0010
-#define pnp_can_read(dev) (((dev)->protocol) && ((dev)->protocol->get) && \
+#define pnp_can_read(dev) (((dev)->protocol->get) && \
((dev)->capabilities & PNP_READ))
-#define pnp_can_write(dev) (((dev)->protocol) && ((dev)->protocol->set) && \
+#define pnp_can_write(dev) (((dev)->protocol->set) && \
((dev)->capabilities & PNP_WRITE))
-#define pnp_can_disable(dev) (((dev)->protocol) && ((dev)->protocol->disable) && \
+#define pnp_can_disable(dev) (((dev)->protocol->disable) && \
((dev)->capabilities & PNP_DISABLE))
#define pnp_can_configure(dev) ((!(dev)->active) && \
((dev)->capabilities & PNP_CONFIGURABLE))
diff --git a/include/linux/poison.h b/include/linux/poison.h
index d93c300a344..a9c31be7052 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -36,7 +36,8 @@
*/
/********** fs/jbd/journal.c **********/
-#define JBD_POISON_FREE 0x5b
+#define JBD_POISON_FREE 0x5b
+#define JBD2_POISON_FREE 0x5c
/********** drivers/base/dmapool.c **********/
#define POOL_POISON_FREED 0xa7 /* !inuse */
diff --git a/include/linux/profile.h b/include/linux/profile.h
index eec48f5f934..ff576d1db67 100644
--- a/include/linux/profile.h
+++ b/include/linux/profile.h
@@ -78,9 +78,6 @@ int profile_event_unregister(enum profile_type, struct notifier_block * n);
int register_timer_hook(int (*hook)(struct pt_regs *));
void unregister_timer_hook(int (*hook)(struct pt_regs *));
-/* Timer based profiling hook */
-extern int (*timer_hook)(struct pt_regs *);
-
struct pt_regs;
#else
diff --git a/include/linux/proportions.h b/include/linux/proportions.h
new file mode 100644
index 00000000000..2c3b3cad92b
--- /dev/null
+++ b/include/linux/proportions.h
@@ -0,0 +1,119 @@
+/*
+ * FLoating proportions
+ *
+ * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ * This file contains the public data structure and API definitions.
+ */
+
+#ifndef _LINUX_PROPORTIONS_H
+#define _LINUX_PROPORTIONS_H
+
+#include <linux/percpu_counter.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
+struct prop_global {
+ /*
+ * The period over which we differentiate
+ *
+ * period = 2^shift
+ */
+ int shift;
+ /*
+ * The total event counter aka 'time'.
+ *
+ * Treated as an unsigned long; the lower 'shift - 1' bits are the
+ * counter bits, the remaining upper bits the period counter.
+ */
+ struct percpu_counter events;
+};
+
+/*
+ * global proportion descriptor
+ *
+ * this is needed to consitently flip prop_global structures.
+ */
+struct prop_descriptor {
+ int index;
+ struct prop_global pg[2];
+ struct mutex mutex; /* serialize the prop_global switch */
+};
+
+int prop_descriptor_init(struct prop_descriptor *pd, int shift);
+void prop_change_shift(struct prop_descriptor *pd, int new_shift);
+
+/*
+ * ----- PERCPU ------
+ */
+
+struct prop_local_percpu {
+ /*
+ * the local events counter
+ */
+ struct percpu_counter events;
+
+ /*
+ * snapshot of the last seen global state
+ */
+ int shift;
+ unsigned long period;
+ spinlock_t lock; /* protect the snapshot state */
+};
+
+int prop_local_init_percpu(struct prop_local_percpu *pl);
+void prop_local_destroy_percpu(struct prop_local_percpu *pl);
+void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl);
+void prop_fraction_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl,
+ long *numerator, long *denominator);
+
+static inline
+void prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __prop_inc_percpu(pd, pl);
+ local_irq_restore(flags);
+}
+
+/*
+ * ----- SINGLE ------
+ */
+
+struct prop_local_single {
+ /*
+ * the local events counter
+ */
+ unsigned long events;
+
+ /*
+ * snapshot of the last seen global state
+ * and a lock protecting this state
+ */
+ int shift;
+ unsigned long period;
+ spinlock_t lock; /* protect the snapshot state */
+};
+
+#define INIT_PROP_LOCAL_SINGLE(name) \
+{ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
+}
+
+int prop_local_init_single(struct prop_local_single *pl);
+void prop_local_destroy_single(struct prop_local_single *pl);
+void __prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl);
+void prop_fraction_single(struct prop_descriptor *pd, struct prop_local_single *pl,
+ long *numerator, long *denominator);
+
+static inline
+void prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __prop_inc_single(pd, pl);
+ local_irq_restore(flags);
+}
+
+#endif /* _LINUX_PROPORTIONS_H */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 62439828395..6e0393a5b2e 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -128,6 +128,37 @@ struct if_dqinfo {
__u32 dqi_valid;
};
+/*
+ * Definitions for quota netlink interface
+ */
+#define QUOTA_NL_NOWARN 0
+#define QUOTA_NL_IHARDWARN 1 /* Inode hardlimit reached */
+#define QUOTA_NL_ISOFTLONGWARN 2 /* Inode grace time expired */
+#define QUOTA_NL_ISOFTWARN 3 /* Inode softlimit reached */
+#define QUOTA_NL_BHARDWARN 4 /* Block hardlimit reached */
+#define QUOTA_NL_BSOFTLONGWARN 5 /* Block grace time expired */
+#define QUOTA_NL_BSOFTWARN 6 /* Block softlimit reached */
+
+enum {
+ QUOTA_NL_C_UNSPEC,
+ QUOTA_NL_C_WARNING,
+ __QUOTA_NL_C_MAX,
+};
+#define QUOTA_NL_C_MAX (__QUOTA_NL_C_MAX - 1)
+
+enum {
+ QUOTA_NL_A_UNSPEC,
+ QUOTA_NL_A_QTYPE,
+ QUOTA_NL_A_EXCESS_ID,
+ QUOTA_NL_A_WARNING,
+ QUOTA_NL_A_DEV_MAJOR,
+ QUOTA_NL_A_DEV_MINOR,
+ QUOTA_NL_A_CAUSED_ID,
+ __QUOTA_NL_A_MAX,
+};
+#define QUOTA_NL_A_MAX (__QUOTA_NL_A_MAX - 1)
+
+
#ifdef __KERNEL__
#include <linux/spinlock.h>
#include <linux/rwsem.h>
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index f9e77d2ee32..b6116b4445c 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -26,28 +26,31 @@
#include <linux/rcupdate.h>
/*
- * A direct pointer (root->rnode pointing directly to a data item,
- * rather than another radix_tree_node) is signalled by the low bit
- * set in the root->rnode pointer.
+ * An indirect pointer (root->rnode pointing to a radix_tree_node, rather
+ * than a data item) is signalled by the low bit set in the root->rnode
+ * pointer.
*
- * In this case root->height is also NULL, but the direct pointer tests are
- * needed for RCU lookups when root->height is unreliable.
+ * In this case root->height is > 0, but the indirect pointer tests are
+ * needed for RCU lookups (because root->height is unreliable). The only
+ * time callers need worry about this is when doing a lookup_slot under
+ * RCU.
*/
-#define RADIX_TREE_DIRECT_PTR 1
+#define RADIX_TREE_INDIRECT_PTR 1
+#define RADIX_TREE_RETRY ((void *)-1UL)
-static inline void *radix_tree_ptr_to_direct(void *ptr)
+static inline void *radix_tree_ptr_to_indirect(void *ptr)
{
- return (void *)((unsigned long)ptr | RADIX_TREE_DIRECT_PTR);
+ return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
}
-static inline void *radix_tree_direct_to_ptr(void *ptr)
+static inline void *radix_tree_indirect_to_ptr(void *ptr)
{
- return (void *)((unsigned long)ptr & ~RADIX_TREE_DIRECT_PTR);
+ return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
}
-static inline int radix_tree_is_direct_ptr(void *ptr)
+static inline int radix_tree_is_indirect_ptr(void *ptr)
{
- return (int)((unsigned long)ptr & RADIX_TREE_DIRECT_PTR);
+ return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR);
}
/*** radix-tree API starts here ***/
@@ -130,7 +133,10 @@ do { \
*/
static inline void *radix_tree_deref_slot(void **pslot)
{
- return radix_tree_direct_to_ptr(*pslot);
+ void *ret = *pslot;
+ if (unlikely(radix_tree_is_indirect_ptr(ret)))
+ ret = RADIX_TREE_RETRY;
+ return ret;
}
/**
* radix_tree_replace_slot - replace item in a slot
@@ -142,10 +148,8 @@ static inline void *radix_tree_deref_slot(void **pslot)
*/
static inline void radix_tree_replace_slot(void **pslot, void *item)
{
- BUG_ON(radix_tree_is_direct_ptr(item));
- rcu_assign_pointer(*pslot,
- (void *)((unsigned long)item |
- ((unsigned long)*pslot & RADIX_TREE_DIRECT_PTR)));
+ BUG_ON(radix_tree_is_indirect_ptr(item));
+ rcu_assign_pointer(*pslot, item);
}
int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
@@ -155,6 +159,8 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long);
unsigned int
radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
unsigned long first_index, unsigned int max_items);
+unsigned long radix_tree_next_hole(struct radix_tree_root *root,
+ unsigned long index, unsigned long max_scan);
int radix_tree_preload(gfp_t gfp_mask);
void radix_tree_init(void);
void *radix_tree_tag_set(struct radix_tree_root *root,
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 75e17a05540..306a1d1a5af 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -138,7 +138,6 @@ typedef __u16 bitmap_counter_t;
/* use these for bitmap->flags and bitmap->sb->state bit-fields */
enum bitmap_state {
- BITMAP_ACTIVE = 0x001, /* the bitmap is in use */
BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */
BITMAP_WRITE_ERROR = 0x004, /* A write error has occurred */
BITMAP_HOSTENDIAN = 0x8000,
@@ -258,7 +257,6 @@ struct bitmap {
int bitmap_create(mddev_t *mddev);
void bitmap_flush(mddev_t *mddev);
void bitmap_destroy(mddev_t *mddev);
-int bitmap_active(struct bitmap *bitmap);
char *file_path(struct file *file, char *buf, int count);
void bitmap_print_sb(struct bitmap *bitmap);
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index fe17d7d750c..cc24a01df94 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -41,6 +41,7 @@
#include <linux/percpu.h>
#include <linux/cpumask.h>
#include <linux/seqlock.h>
+#include <linux/lockdep.h>
/**
* struct rcu_head - callback structure for use with RCU
@@ -133,6 +134,15 @@ static inline void rcu_bh_qsctr_inc(int cpu)
extern int rcu_pending(int cpu);
extern int rcu_needs_cpu(int cpu);
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+extern struct lockdep_map rcu_lock_map;
+# define rcu_read_acquire() lock_acquire(&rcu_lock_map, 0, 0, 2, 1, _THIS_IP_)
+# define rcu_read_release() lock_release(&rcu_lock_map, 1, _THIS_IP_)
+#else
+# define rcu_read_acquire() do { } while (0)
+# define rcu_read_release() do { } while (0)
+#endif
+
/**
* rcu_read_lock - mark the beginning of an RCU read-side critical section.
*
@@ -166,6 +176,7 @@ extern int rcu_needs_cpu(int cpu);
do { \
preempt_disable(); \
__acquire(RCU); \
+ rcu_read_acquire(); \
} while(0)
/**
@@ -175,6 +186,7 @@ extern int rcu_needs_cpu(int cpu);
*/
#define rcu_read_unlock() \
do { \
+ rcu_read_release(); \
__release(RCU); \
preempt_enable(); \
} while(0)
@@ -204,6 +216,7 @@ extern int rcu_needs_cpu(int cpu);
do { \
local_bh_disable(); \
__acquire(RCU_BH); \
+ rcu_read_acquire(); \
} while(0)
/*
@@ -213,10 +226,23 @@ extern int rcu_needs_cpu(int cpu);
*/
#define rcu_read_unlock_bh() \
do { \
+ rcu_read_release(); \
__release(RCU_BH); \
local_bh_enable(); \
} while(0)
+/*
+ * Prevent the compiler from merging or refetching accesses. The compiler
+ * is also forbidden from reordering successive instances of ACCESS_ONCE(),
+ * but only when the compiler is aware of some particular ordering. One way
+ * to make the compiler aware of ordering is to put the two invocations of
+ * ACCESS_ONCE() in different C statements.
+ *
+ * This macro does absolutely -nothing- to prevent the CPU from reordering,
+ * merging, or refetching absolutely anything at any time.
+ */
+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
+
/**
* rcu_dereference - fetch an RCU-protected pointer in an
* RCU read-side critical section. This pointer may later
@@ -228,7 +254,7 @@ extern int rcu_needs_cpu(int cpu);
*/
#define rcu_dereference(p) ({ \
- typeof(p) _________p1 = p; \
+ typeof(p) _________p1 = ACCESS_ONCE(p); \
smp_read_barrier_depends(); \
(_________p1); \
})
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 180a9d832dd..8dcf237d338 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1703,8 +1703,6 @@ static inline int reiserfs_transaction_free_space(struct reiserfs_transaction_ha
return th->t_blocks_allocated - th->t_blocks_logged;
}
-int reiserfs_async_progress_wait(struct super_block *s);
-
struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
super_block
*,
@@ -1859,8 +1857,6 @@ void padd_item(char *item, int total_length, int length);
#define GET_BLOCK_NO_IMUX 8 /* i_mutex is not held, don't preallocate */
#define GET_BLOCK_NO_DANGLE 16 /* don't leave any transactions running */
-int restart_transaction(struct reiserfs_transaction_handle *th,
- struct inode *inode, struct treepath *path);
void reiserfs_read_locked_inode(struct inode *inode,
struct reiserfs_iget_args *args);
int reiserfs_find_actor(struct inode *inode, void *p);
@@ -2137,9 +2133,6 @@ void reiserfs_discard_prealloc(struct reiserfs_transaction_handle *th,
struct inode *inode);
void reiserfs_discard_all_prealloc(struct reiserfs_transaction_handle *th);
#endif
-void reiserfs_claim_blocks_to_be_allocated(struct super_block *sb, int blocks);
-void reiserfs_release_claimed_blocks(struct super_block *sb, int blocks);
-int reiserfs_can_fit_pages(struct super_block *sb);
/* hashes.c */
__u32 keyed_hash(const signed char *msg, int len);
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 4efbd9c445f..2dc7464cce5 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -20,4 +20,88 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
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_chain_ptr(sg) \
+ ((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+
+/**
+ * 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.
+ *
+ */
+static inline struct scatterlist *sg_next(struct scatterlist *sg)
+{
+ sg++;
+
+ if (unlikely(sg_is_chain(sg)))
+ sg = sg_chain_ptr(sg);
+
+ return sg;
+}
+
+/*
+ * Loop over each sg element, following the pointer to a new list if necessary
+ */
+#define for_each_sg(sglist, sg, nr, __i) \
+ for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
+
+/**
+ * sg_last - return the last scatterlist entry in a list
+ * @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.
+ *
+ * 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)
+{
+#ifndef ARCH_HAS_SG_CHAIN
+ struct scatterlist *ret = &sgl[nents - 1];
+#else
+ struct scatterlist *sg, *ret = NULL;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ ret = sg;
+
+#endif
+ return ret;
+}
+
+/**
+ * sg_chain - Chain two sglists together
+ * @prv: First scatterlist
+ * @prv_nents: Number of entries in prv
+ * @sgl: Second scatterlist
+ *
+ * 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);
+}
+
#endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 228e0a8ce24..10a83d8d577 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1,8 +1,6 @@
#ifndef _LINUX_SCHED_H
#define _LINUX_SCHED_H
-#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
-
/*
* cloning flags:
*/
@@ -58,12 +56,12 @@ struct sched_param {
#include <linux/cpumask.h>
#include <linux/errno.h>
#include <linux/nodemask.h>
+#include <linux/mm_types.h>
#include <asm/system.h>
#include <asm/semaphore.h>
#include <asm/page.h>
#include <asm/ptrace.h>
-#include <asm/mmu.h>
#include <asm/cputime.h>
#include <linux/smp.h>
@@ -76,6 +74,7 @@ struct sched_param {
#include <linux/pid.h>
#include <linux/percpu.h>
#include <linux/topology.h>
+#include <linux/proportions.h>
#include <linux/seccomp.h>
#include <linux/rcupdate.h>
#include <linux/futex.h>
@@ -262,6 +261,7 @@ extern void softlockup_tick(void);
extern void spawn_softlockup_task(void);
extern void touch_softlockup_watchdog(void);
extern void touch_all_softlockup_watchdogs(void);
+extern int softlockup_thresh;
#else
static inline void softlockup_tick(void)
{
@@ -319,7 +319,6 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
-typedef atomic_long_t mm_counter_t;
#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
/*
@@ -331,7 +330,6 @@ typedef atomic_long_t mm_counter_t;
#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
#define inc_mm_counter(mm, member) (mm)->_##member++
#define dec_mm_counter(mm, member) (mm)->_##member--
-typedef unsigned long mm_counter_t;
#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
@@ -361,81 +359,14 @@ extern int get_dumpable(struct mm_struct *mm);
#define MMF_DUMP_ANON_SHARED 3
#define MMF_DUMP_MAPPED_PRIVATE 4
#define MMF_DUMP_MAPPED_SHARED 5
+#define MMF_DUMP_ELF_HEADERS 6
#define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS
-#define MMF_DUMP_FILTER_BITS 4
+#define MMF_DUMP_FILTER_BITS 5
#define MMF_DUMP_FILTER_MASK \
(((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT)
#define MMF_DUMP_FILTER_DEFAULT \
((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED))
-struct mm_struct {
- struct vm_area_struct * mmap; /* list of VMAs */
- struct rb_root mm_rb;
- struct vm_area_struct * mmap_cache; /* last find_vma result */
- unsigned long (*get_unmapped_area) (struct file *filp,
- unsigned long addr, unsigned long len,
- unsigned long pgoff, unsigned long flags);
- void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
- unsigned long mmap_base; /* base of mmap area */
- unsigned long task_size; /* size of task vm space */
- unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
- unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
- pgd_t * pgd;
- atomic_t mm_users; /* How many users with user space? */
- atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
- int map_count; /* number of VMAs */
- struct rw_semaphore mmap_sem;
- spinlock_t page_table_lock; /* Protects page tables and some counters */
-
- struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
- * together off init_mm.mmlist, and are protected
- * by mmlist_lock
- */
-
- /* Special counters, in some configurations protected by the
- * page_table_lock, in other configurations by being atomic.
- */
- mm_counter_t _file_rss;
- mm_counter_t _anon_rss;
-
- unsigned long hiwater_rss; /* High-watermark of RSS usage */
- unsigned long hiwater_vm; /* High-water virtual memory usage */
-
- unsigned long total_vm, locked_vm, shared_vm, exec_vm;
- unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
- unsigned long start_code, end_code, start_data, end_data;
- unsigned long start_brk, brk, start_stack;
- unsigned long arg_start, arg_end, env_start, env_end;
-
- unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
-
- cpumask_t cpu_vm_mask;
-
- /* Architecture-specific MM context */
- mm_context_t context;
-
- /* Swap token stuff */
- /*
- * Last value of global fault stamp as seen by this process.
- * In other words, this value gives an indication of how long
- * it has been since this task got the token.
- * Look at mm/thrash.c
- */
- unsigned int faultstamp;
- unsigned int token_priority;
- unsigned int last_interval;
-
- unsigned long flags; /* Must use atomic bitops to access the bits */
-
- /* coredumping support */
- int core_waiters;
- struct completion *core_startup_done, core_done;
-
- /* aio bits */
- rwlock_t ioctx_list_lock;
- struct kioctx *ioctx_list;
-};
-
struct sighand_struct {
atomic_t count;
struct k_sigaction action[_NSIG];
@@ -587,8 +518,10 @@ struct user_struct {
atomic_t inotify_watches; /* How many inotify watches does this user have? */
atomic_t inotify_devs; /* How many inotify devs does this user have opened? */
#endif
+#ifdef CONFIG_POSIX_MQUEUE
/* protected by mq_lock */
unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
+#endif
unsigned long locked_shm; /* How many pages of mlocked shm ? */
#ifdef CONFIG_KEYS
@@ -602,10 +535,12 @@ struct user_struct {
#ifdef CONFIG_FAIR_USER_SCHED
struct task_group *tg;
+#ifdef CONFIG_SYSFS
struct kset kset;
struct subsys_attribute user_attr;
struct work_struct work;
#endif
+#endif
};
#ifdef CONFIG_FAIR_USER_SCHED
@@ -634,7 +569,7 @@ struct sched_info {
last_queued; /* when we were last queued to run */
#ifdef CONFIG_SCHEDSTATS
/* BKL stats */
- unsigned long bkl_count;
+ unsigned int bkl_count;
#endif
};
#endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */
@@ -770,40 +705,37 @@ struct sched_domain {
#ifdef CONFIG_SCHEDSTATS
/* load_balance() stats */
- unsigned long lb_count[CPU_MAX_IDLE_TYPES];
- unsigned long lb_failed[CPU_MAX_IDLE_TYPES];
- unsigned long lb_balanced[CPU_MAX_IDLE_TYPES];
- unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES];
- unsigned long lb_gained[CPU_MAX_IDLE_TYPES];
- unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES];
- unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES];
- unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_count[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_failed[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_balanced[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_gained[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES];
+ unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES];
/* Active load balancing */
- unsigned long alb_count;
- unsigned long alb_failed;
- unsigned long alb_pushed;
+ unsigned int alb_count;
+ unsigned int alb_failed;
+ unsigned int alb_pushed;
/* SD_BALANCE_EXEC stats */
- unsigned long sbe_count;
- unsigned long sbe_balanced;
- unsigned long sbe_pushed;
+ unsigned int sbe_count;
+ unsigned int sbe_balanced;
+ unsigned int sbe_pushed;
/* SD_BALANCE_FORK stats */
- unsigned long sbf_count;
- unsigned long sbf_balanced;
- unsigned long sbf_pushed;
+ unsigned int sbf_count;
+ unsigned int sbf_balanced;
+ unsigned int sbf_pushed;
/* try_to_wake_up() stats */
- unsigned long ttwu_wake_remote;
- unsigned long ttwu_move_affine;
- unsigned long ttwu_move_balance;
+ unsigned int ttwu_wake_remote;
+ unsigned int ttwu_move_affine;
+ unsigned int ttwu_move_balance;
#endif
};
-extern int partition_sched_domains(cpumask_t *partition1,
- cpumask_t *partition2);
-
#endif /* CONFIG_SMP */
/*
@@ -988,6 +920,16 @@ struct task_struct {
#endif
unsigned short ioprio;
+ /*
+ * fpu_counter contains the number of consecutive context switches
+ * that the FPU is used. If this is over a threshold, the lazy fpu
+ * saving becomes unlazy to save the trap. This is an unsigned char
+ * so that after 256 times the counter wraps and the behavior turns
+ * lazy again; this to deal with bursty apps that only use FPU for
+ * a short time
+ */
+ unsigned char fpu_counter;
+ s8 oomkilladj; /* OOM kill score adjustment (bit shift). */
#ifdef CONFIG_BLK_DEV_IO_TRACE
unsigned int btrace_seq;
#endif
@@ -1049,7 +991,7 @@ struct task_struct {
int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
unsigned int rt_priority;
- cputime_t utime, stime;
+ cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
unsigned long nvcsw, nivcsw; /* context switch counts */
struct timespec start_time; /* monotonic time */
@@ -1073,16 +1015,6 @@ struct task_struct {
struct key *thread_keyring; /* keyring private to this thread */
unsigned char jit_keyring; /* default keyring to attach requested keys to */
#endif
- /*
- * fpu_counter contains the number of consecutive context switches
- * that the FPU is used. If this is over a threshold, the lazy fpu
- * saving becomes unlazy to save the trap. This is an unsigned char
- * so that after 256 times the counter wraps and the behavior turns
- * lazy again; this to deal with bursty apps that only use FPU for
- * a short time
- */
- unsigned char fpu_counter;
- int oomkilladj; /* OOM kill score adjustment (bit shift). */
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
@@ -1114,8 +1046,9 @@ struct task_struct {
int (*notifier)(void *priv);
void *notifier_data;
sigset_t *notifier_mask;
-
+#ifdef CONFIG_SECURITY
void *security;
+#endif
struct audit_context *audit_context;
seccomp_t seccomp;
@@ -1177,13 +1110,6 @@ struct task_struct {
unsigned long ptrace_message;
siginfo_t *last_siginfo; /* For ptrace use. */
-/*
- * current io wait handle: wait queue entry to use for io waits
- * If this thread is processing aio, this points at the waitqueue
- * inside the currently handled kiocb. It may be NULL (i.e. default
- * to a stack based synchronous wait) if its doing sync IO.
- */
- wait_queue_t *io_wait;
#ifdef CONFIG_TASK_XACCT
/* i/o counters(bytes read/written, #syscalls */
u64 rchar, wchar, syscr, syscw;
@@ -1204,13 +1130,14 @@ struct task_struct {
int cpuset_mems_generation;
int cpuset_mem_spread_rotor;
#endif
+#ifdef CONFIG_FUTEX
struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
struct compat_robust_list_head __user *compat_robust_list;
#endif
struct list_head pi_state_list;
struct futex_pi_state *pi_state_cache;
-
+#endif
atomic_t fs_excl; /* holding fs exclusive resources */
struct rcu_head rcu;
@@ -1224,6 +1151,7 @@ struct task_struct {
#ifdef CONFIG_FAULT_INJECTION
int make_it_fail;
#endif
+ struct prop_local_single dirties;
};
/*
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index 3ee412bc00e..ba81ffe9958 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -47,15 +47,6 @@ struct screen_info {
extern struct screen_info screen_info;
-#define ORIG_X (screen_info.orig_x)
-#define ORIG_Y (screen_info.orig_y)
-#define ORIG_VIDEO_MODE (screen_info.orig_video_mode)
-#define ORIG_VIDEO_COLS (screen_info.orig_video_cols)
-#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
-#define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
-#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA)
-#define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
-
#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
diff --git a/include/linux/security.h b/include/linux/security.h
index 1a15526e9f6..ff3f857f695 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -34,6 +34,13 @@
#include <linux/xfrm.h>
#include <net/flow.h>
+/*
+ * Bounding set
+ */
+extern kernel_cap_t cap_bset;
+
+extern unsigned securebits;
+
struct ctl_table;
/*
@@ -51,10 +58,16 @@ extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
extern int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags);
extern int cap_inode_removexattr(struct dentry *dentry, char *name);
+extern int cap_inode_need_killpriv(struct dentry *dentry);
+extern int cap_inode_killpriv(struct dentry *dentry);
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
extern void cap_task_reparent_to_init (struct task_struct *p);
+extern int cap_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid);
+extern int cap_task_setscheduler (struct task_struct *p, int policy, struct sched_param *lp);
+extern int cap_task_setioprio (struct task_struct *p, int ioprio);
+extern int cap_task_setnice (struct task_struct *p, int nice);
extern int cap_syslog (int type);
-extern int cap_vm_enough_memory (struct mm_struct *mm, long pages);
+extern int cap_vm_enough_memory(struct mm_struct *mm, long pages);
struct msghdr;
struct sk_buff;
@@ -413,6 +426,18 @@ struct request_sock;
* is specified by @buffer_size. @buffer may be NULL to request
* the size of the buffer required.
* Returns number of bytes used/required on success.
+ * @inode_need_killpriv:
+ * Called when an inode has been changed.
+ * @dentry is the dentry being changed.
+ * Return <0 on error to abort the inode change operation.
+ * Return 0 if inode_killpriv does not need to be called.
+ * Return >0 if inode_killpriv does need to be called.
+ * @inode_killpriv:
+ * The setuid bit is being removed. Remove similar security labels.
+ * Called with the dentry->d_inode->i_mutex held.
+ * @dentry is the dentry being changed.
+ * Return 0 on success. If error is returned, then the operation
+ * causing setuid bit removal is failed.
*
* Security hooks for file operations
*
@@ -504,6 +529,13 @@ struct request_sock;
* @file contains the file structure being received.
* Return 0 if permission is granted.
*
+ * Security hook for dentry
+ *
+ * @dentry_open
+ * Save open-time permission checking state for later use upon
+ * file_permission, and recheck access if anything has changed
+ * since inode_permission.
+ *
* Security hooks for task operations.
*
* @task_create:
@@ -1133,10 +1165,6 @@ struct request_sock;
* allow module stacking.
* @name contains the name of the security module being stacked.
* @ops contains a pointer to the struct security_operations of the module to stack.
- * @unregister_security:
- * remove a stacked module.
- * @name contains the name of the security module being unstacked.
- * @ops contains a pointer to the struct security_operations of the module to unstack.
*
* @secid_to_secctx:
* Convert secid to security context.
@@ -1232,7 +1260,8 @@ struct security_operations {
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
- const char *(*inode_xattr_getsuffix) (void);
+ int (*inode_need_killpriv) (struct dentry *dentry);
+ int (*inode_killpriv) (struct dentry *dentry);
int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);
@@ -1256,6 +1285,7 @@ struct security_operations {
int (*file_send_sigiotask) (struct task_struct * tsk,
struct fown_struct * fown, int sig);
int (*file_receive) (struct file * file);
+ int (*dentry_open) (struct file *file);
int (*task_create) (unsigned long clone_flags);
int (*task_alloc_security) (struct task_struct * p);
@@ -1322,8 +1352,6 @@ struct security_operations {
/* allow module stacking */
int (*register_security) (const char *name,
struct security_operations *ops);
- int (*unregister_security) (const char *name,
- struct security_operations *ops);
void (*d_instantiate) (struct dentry *dentry, struct inode *inode);
@@ -1401,743 +1429,10 @@ struct security_operations {
};
-/* global variables */
-extern struct security_operations *security_ops;
-
-/* inline stuff */
-static inline int security_ptrace (struct task_struct * parent, struct task_struct * child)
-{
- return security_ops->ptrace (parent, child);
-}
-
-static inline int security_capget (struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted)
-{
- return security_ops->capget (target, effective, inheritable, permitted);
-}
-
-static inline int security_capset_check (struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted)
-{
- return security_ops->capset_check (target, effective, inheritable, permitted);
-}
-
-static inline void security_capset_set (struct task_struct *target,
- kernel_cap_t *effective,
- kernel_cap_t *inheritable,
- kernel_cap_t *permitted)
-{
- security_ops->capset_set (target, effective, inheritable, permitted);
-}
-
-static inline int security_capable(struct task_struct *tsk, int cap)
-{
- return security_ops->capable(tsk, cap);
-}
-
-static inline int security_acct (struct file *file)
-{
- return security_ops->acct (file);
-}
-
-static inline int security_sysctl(struct ctl_table *table, int op)
-{
- return security_ops->sysctl(table, op);
-}
-
-static inline int security_quotactl (int cmds, int type, int id,
- struct super_block *sb)
-{
- return security_ops->quotactl (cmds, type, id, sb);
-}
-
-static inline int security_quota_on (struct dentry * dentry)
-{
- return security_ops->quota_on (dentry);
-}
-
-static inline int security_syslog(int type)
-{
- return security_ops->syslog(type);
-}
-
-static inline int security_settime(struct timespec *ts, struct timezone *tz)
-{
- return security_ops->settime(ts, tz);
-}
-
-static inline int security_vm_enough_memory(long pages)
-{
- return security_ops->vm_enough_memory(current->mm, pages);
-}
-
-static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
-{
- return security_ops->vm_enough_memory(mm, pages);
-}
-
-static inline int security_bprm_alloc (struct linux_binprm *bprm)
-{
- return security_ops->bprm_alloc_security (bprm);
-}
-static inline void security_bprm_free (struct linux_binprm *bprm)
-{
- security_ops->bprm_free_security (bprm);
-}
-static inline void security_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
-{
- security_ops->bprm_apply_creds (bprm, unsafe);
-}
-static inline void security_bprm_post_apply_creds (struct linux_binprm *bprm)
-{
- security_ops->bprm_post_apply_creds (bprm);
-}
-static inline int security_bprm_set (struct linux_binprm *bprm)
-{
- return security_ops->bprm_set_security (bprm);
-}
-
-static inline int security_bprm_check (struct linux_binprm *bprm)
-{
- return security_ops->bprm_check_security (bprm);
-}
-
-static inline int security_bprm_secureexec (struct linux_binprm *bprm)
-{
- return security_ops->bprm_secureexec (bprm);
-}
-
-static inline int security_sb_alloc (struct super_block *sb)
-{
- return security_ops->sb_alloc_security (sb);
-}
-
-static inline void security_sb_free (struct super_block *sb)
-{
- security_ops->sb_free_security (sb);
-}
-
-static inline int security_sb_copy_data (struct file_system_type *type,
- void *orig, void *copy)
-{
- return security_ops->sb_copy_data (type, orig, copy);
-}
-
-static inline int security_sb_kern_mount (struct super_block *sb, void *data)
-{
- return security_ops->sb_kern_mount (sb, data);
-}
-
-static inline int security_sb_statfs (struct dentry *dentry)
-{
- return security_ops->sb_statfs (dentry);
-}
-
-static inline int security_sb_mount (char *dev_name, struct nameidata *nd,
- char *type, unsigned long flags,
- void *data)
-{
- return security_ops->sb_mount (dev_name, nd, type, flags, data);
-}
-
-static inline int security_sb_check_sb (struct vfsmount *mnt,
- struct nameidata *nd)
-{
- return security_ops->sb_check_sb (mnt, nd);
-}
-
-static inline int security_sb_umount (struct vfsmount *mnt, int flags)
-{
- return security_ops->sb_umount (mnt, flags);
-}
-
-static inline void security_sb_umount_close (struct vfsmount *mnt)
-{
- security_ops->sb_umount_close (mnt);
-}
-
-static inline void security_sb_umount_busy (struct vfsmount *mnt)
-{
- security_ops->sb_umount_busy (mnt);
-}
-
-static inline void security_sb_post_remount (struct vfsmount *mnt,
- unsigned long flags, void *data)
-{
- security_ops->sb_post_remount (mnt, flags, data);
-}
-
-static inline void security_sb_post_mountroot (void)
-{
- security_ops->sb_post_mountroot ();
-}
-
-static inline void security_sb_post_addmount (struct vfsmount *mnt,
- struct nameidata *mountpoint_nd)
-{
- security_ops->sb_post_addmount (mnt, mountpoint_nd);
-}
-
-static inline int security_sb_pivotroot (struct nameidata *old_nd,
- struct nameidata *new_nd)
-{
- return security_ops->sb_pivotroot (old_nd, new_nd);
-}
-
-static inline void security_sb_post_pivotroot (struct nameidata *old_nd,
- struct nameidata *new_nd)
-{
- security_ops->sb_post_pivotroot (old_nd, new_nd);
-}
-
-static inline int security_inode_alloc (struct inode *inode)
-{
- inode->i_security = NULL;
- return security_ops->inode_alloc_security (inode);
-}
-
-static inline void security_inode_free (struct inode *inode)
-{
- security_ops->inode_free_security (inode);
-}
-
-static inline int security_inode_init_security (struct inode *inode,
- struct inode *dir,
- char **name,
- void **value,
- size_t *len)
-{
- if (unlikely (IS_PRIVATE (inode)))
- return -EOPNOTSUPP;
- return security_ops->inode_init_security (inode, dir, name, value, len);
-}
-
-static inline int security_inode_create (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{
- if (unlikely (IS_PRIVATE (dir)))
- return 0;
- return security_ops->inode_create (dir, dentry, mode);
-}
-
-static inline int security_inode_link (struct dentry *old_dentry,
- struct inode *dir,
- struct dentry *new_dentry)
-{
- if (unlikely (IS_PRIVATE (old_dentry->d_inode)))
- return 0;
- return security_ops->inode_link (old_dentry, dir, new_dentry);
-}
-
-static inline int security_inode_unlink (struct inode *dir,
- struct dentry *dentry)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_unlink (dir, dentry);
-}
-
-static inline int security_inode_symlink (struct inode *dir,
- struct dentry *dentry,
- const char *old_name)
-{
- if (unlikely (IS_PRIVATE (dir)))
- return 0;
- return security_ops->inode_symlink (dir, dentry, old_name);
-}
-
-static inline int security_inode_mkdir (struct inode *dir,
- struct dentry *dentry,
- int mode)
-{
- if (unlikely (IS_PRIVATE (dir)))
- return 0;
- return security_ops->inode_mkdir (dir, dentry, mode);
-}
-
-static inline int security_inode_rmdir (struct inode *dir,
- struct dentry *dentry)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_rmdir (dir, dentry);
-}
-
-static inline int security_inode_mknod (struct inode *dir,
- struct dentry *dentry,
- int mode, dev_t dev)
-{
- if (unlikely (IS_PRIVATE (dir)))
- return 0;
- return security_ops->inode_mknod (dir, dentry, mode, dev);
-}
-
-static inline int security_inode_rename (struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry)
-{
- if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
- (new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
- return 0;
- return security_ops->inode_rename (old_dir, old_dentry,
- new_dir, new_dentry);
-}
-
-static inline int security_inode_readlink (struct dentry *dentry)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_readlink (dentry);
-}
-
-static inline int security_inode_follow_link (struct dentry *dentry,
- struct nameidata *nd)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_follow_link (dentry, nd);
-}
-
-static inline int security_inode_permission (struct inode *inode, int mask,
- struct nameidata *nd)
-{
- if (unlikely (IS_PRIVATE (inode)))
- return 0;
- return security_ops->inode_permission (inode, mask, nd);
-}
-
-static inline int security_inode_setattr (struct dentry *dentry,
- struct iattr *attr)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_setattr (dentry, attr);
-}
-
-static inline int security_inode_getattr (struct vfsmount *mnt,
- struct dentry *dentry)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_getattr (mnt, dentry);
-}
-
-static inline void security_inode_delete (struct inode *inode)
-{
- if (unlikely (IS_PRIVATE (inode)))
- return;
- security_ops->inode_delete (inode);
-}
-
-static inline int security_inode_setxattr (struct dentry *dentry, char *name,
- void *value, size_t size, int flags)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_setxattr (dentry, name, value, size, flags);
-}
-
-static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
- void *value, size_t size, int flags)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return;
- security_ops->inode_post_setxattr (dentry, name, value, size, flags);
-}
-
-static inline int security_inode_getxattr (struct dentry *dentry, char *name)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_getxattr (dentry, name);
-}
-
-static inline int security_inode_listxattr (struct dentry *dentry)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_listxattr (dentry);
-}
-
-static inline int security_inode_removexattr (struct dentry *dentry, char *name)
-{
- if (unlikely (IS_PRIVATE (dentry->d_inode)))
- return 0;
- return security_ops->inode_removexattr (dentry, name);
-}
-
-static inline const char *security_inode_xattr_getsuffix(void)
-{
- return security_ops->inode_xattr_getsuffix();
-}
-
-static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
-{
- if (unlikely (IS_PRIVATE (inode)))
- return 0;
- return security_ops->inode_getsecurity(inode, name, buffer, size, err);
-}
-
-static inline int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
-{
- if (unlikely (IS_PRIVATE (inode)))
- return 0;
- return security_ops->inode_setsecurity(inode, name, value, size, flags);
-}
-
-static inline int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
-{
- if (unlikely (IS_PRIVATE (inode)))
- return 0;
- return security_ops->inode_listsecurity(inode, buffer, buffer_size);
-}
-
-static inline int security_file_permission (struct file *file, int mask)
-{
- return security_ops->file_permission (file, mask);
-}
-
-static inline int security_file_alloc (struct file *file)
-{
- return security_ops->file_alloc_security (file);
-}
-
-static inline void security_file_free (struct file *file)
-{
- security_ops->file_free_security (file);
-}
-
-static inline int security_file_ioctl (struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return security_ops->file_ioctl (file, cmd, arg);
-}
-
-static inline int security_file_mmap (struct file *file, unsigned long reqprot,
- unsigned long prot,
- unsigned long flags,
- unsigned long addr,
- unsigned long addr_only)
-{
- return security_ops->file_mmap (file, reqprot, prot, flags, addr,
- addr_only);
-}
-
-static inline int security_file_mprotect (struct vm_area_struct *vma,
- unsigned long reqprot,
- unsigned long prot)
-{
- return security_ops->file_mprotect (vma, reqprot, prot);
-}
-
-static inline int security_file_lock (struct file *file, unsigned int cmd)
-{
- return security_ops->file_lock (file, cmd);
-}
-
-static inline int security_file_fcntl (struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- return security_ops->file_fcntl (file, cmd, arg);
-}
-
-static inline int security_file_set_fowner (struct file *file)
-{
- return security_ops->file_set_fowner (file);
-}
-
-static inline int security_file_send_sigiotask (struct task_struct *tsk,
- struct fown_struct *fown,
- int sig)
-{
- return security_ops->file_send_sigiotask (tsk, fown, sig);
-}
-
-static inline int security_file_receive (struct file *file)
-{
- return security_ops->file_receive (file);
-}
-
-static inline int security_task_create (unsigned long clone_flags)
-{
- return security_ops->task_create (clone_flags);
-}
-
-static inline int security_task_alloc (struct task_struct *p)
-{
- return security_ops->task_alloc_security (p);
-}
-
-static inline void security_task_free (struct task_struct *p)
-{
- security_ops->task_free_security (p);
-}
-
-static inline int security_task_setuid (uid_t id0, uid_t id1, uid_t id2,
- int flags)
-{
- return security_ops->task_setuid (id0, id1, id2, flags);
-}
-
-static inline int security_task_post_setuid (uid_t old_ruid, uid_t old_euid,
- uid_t old_suid, int flags)
-{
- return security_ops->task_post_setuid (old_ruid, old_euid, old_suid, flags);
-}
-
-static inline int security_task_setgid (gid_t id0, gid_t id1, gid_t id2,
- int flags)
-{
- return security_ops->task_setgid (id0, id1, id2, flags);
-}
-
-static inline int security_task_setpgid (struct task_struct *p, pid_t pgid)
-{
- return security_ops->task_setpgid (p, pgid);
-}
-
-static inline int security_task_getpgid (struct task_struct *p)
-{
- return security_ops->task_getpgid (p);
-}
-
-static inline int security_task_getsid (struct task_struct *p)
-{
- return security_ops->task_getsid (p);
-}
-
-static inline void security_task_getsecid (struct task_struct *p, u32 *secid)
-{
- security_ops->task_getsecid (p, secid);
-}
-
-static inline int security_task_setgroups (struct group_info *group_info)
-{
- return security_ops->task_setgroups (group_info);
-}
-
-static inline int security_task_setnice (struct task_struct *p, int nice)
-{
- return security_ops->task_setnice (p, nice);
-}
-
-static inline int security_task_setioprio (struct task_struct *p, int ioprio)
-{
- return security_ops->task_setioprio (p, ioprio);
-}
-
-static inline int security_task_getioprio (struct task_struct *p)
-{
- return security_ops->task_getioprio (p);
-}
-
-static inline int security_task_setrlimit (unsigned int resource,
- struct rlimit *new_rlim)
-{
- return security_ops->task_setrlimit (resource, new_rlim);
-}
-
-static inline int security_task_setscheduler (struct task_struct *p,
- int policy,
- struct sched_param *lp)
-{
- return security_ops->task_setscheduler (p, policy, lp);
-}
-
-static inline int security_task_getscheduler (struct task_struct *p)
-{
- return security_ops->task_getscheduler (p);
-}
-
-static inline int security_task_movememory (struct task_struct *p)
-{
- return security_ops->task_movememory (p);
-}
-
-static inline int security_task_kill (struct task_struct *p,
- struct siginfo *info, int sig,
- u32 secid)
-{
- return security_ops->task_kill (p, info, sig, secid);
-}
-
-static inline int security_task_wait (struct task_struct *p)
-{
- return security_ops->task_wait (p);
-}
-
-static inline int security_task_prctl (int option, unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4,
- unsigned long arg5)
-{
- return security_ops->task_prctl (option, arg2, arg3, arg4, arg5);
-}
-
-static inline void security_task_reparent_to_init (struct task_struct *p)
-{
- security_ops->task_reparent_to_init (p);
-}
-
-static inline void security_task_to_inode(struct task_struct *p, struct inode *inode)
-{
- security_ops->task_to_inode(p, inode);
-}
-
-static inline int security_ipc_permission (struct kern_ipc_perm *ipcp,
- short flag)
-{
- return security_ops->ipc_permission (ipcp, flag);
-}
-
-static inline int security_msg_msg_alloc (struct msg_msg * msg)
-{
- return security_ops->msg_msg_alloc_security (msg);
-}
-
-static inline void security_msg_msg_free (struct msg_msg * msg)
-{
- security_ops->msg_msg_free_security(msg);
-}
-
-static inline int security_msg_queue_alloc (struct msg_queue *msq)
-{
- return security_ops->msg_queue_alloc_security (msq);
-}
-
-static inline void security_msg_queue_free (struct msg_queue *msq)
-{
- security_ops->msg_queue_free_security (msq);
-}
-
-static inline int security_msg_queue_associate (struct msg_queue * msq,
- int msqflg)
-{
- return security_ops->msg_queue_associate (msq, msqflg);
-}
-
-static inline int security_msg_queue_msgctl (struct msg_queue * msq, int cmd)
-{
- return security_ops->msg_queue_msgctl (msq, cmd);
-}
-
-static inline int security_msg_queue_msgsnd (struct msg_queue * msq,
- struct msg_msg * msg, int msqflg)
-{
- return security_ops->msg_queue_msgsnd (msq, msg, msqflg);
-}
-
-static inline int security_msg_queue_msgrcv (struct msg_queue * msq,
- struct msg_msg * msg,
- struct task_struct * target,
- long type, int mode)
-{
- return security_ops->msg_queue_msgrcv (msq, msg, target, type, mode);
-}
-
-static inline int security_shm_alloc (struct shmid_kernel *shp)
-{
- return security_ops->shm_alloc_security (shp);
-}
-
-static inline void security_shm_free (struct shmid_kernel *shp)
-{
- security_ops->shm_free_security (shp);
-}
-
-static inline int security_shm_associate (struct shmid_kernel * shp,
- int shmflg)
-{
- return security_ops->shm_associate(shp, shmflg);
-}
-
-static inline int security_shm_shmctl (struct shmid_kernel * shp, int cmd)
-{
- return security_ops->shm_shmctl (shp, cmd);
-}
-
-static inline int security_shm_shmat (struct shmid_kernel * shp,
- char __user *shmaddr, int shmflg)
-{
- return security_ops->shm_shmat(shp, shmaddr, shmflg);
-}
-
-static inline int security_sem_alloc (struct sem_array *sma)
-{
- return security_ops->sem_alloc_security (sma);
-}
-
-static inline void security_sem_free (struct sem_array *sma)
-{
- security_ops->sem_free_security (sma);
-}
-
-static inline int security_sem_associate (struct sem_array * sma, int semflg)
-{
- return security_ops->sem_associate (sma, semflg);
-}
-
-static inline int security_sem_semctl (struct sem_array * sma, int cmd)
-{
- return security_ops->sem_semctl(sma, cmd);
-}
-
-static inline int security_sem_semop (struct sem_array * sma,
- struct sembuf * sops, unsigned nsops,
- int alter)
-{
- return security_ops->sem_semop(sma, sops, nsops, alter);
-}
-
-static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode)
-{
- if (unlikely (inode && IS_PRIVATE (inode)))
- return;
- security_ops->d_instantiate (dentry, inode);
-}
-
-static inline int security_getprocattr(struct task_struct *p, char *name, char **value)
-{
- return security_ops->getprocattr(p, name, value);
-}
-
-static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
-{
- return security_ops->setprocattr(p, name, value, size);
-}
-
-static inline int security_netlink_send(struct sock *sk, struct sk_buff * skb)
-{
- return security_ops->netlink_send(sk, skb);
-}
-
-static inline int security_netlink_recv(struct sk_buff * skb, int cap)
-{
- return security_ops->netlink_recv(skb, cap);
-}
-
-static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
-{
- return security_ops->secid_to_secctx(secid, secdata, seclen);
-}
-
-static inline void security_release_secctx(char *secdata, u32 seclen)
-{
- return security_ops->release_secctx(secdata, seclen);
-}
-
/* prototypes */
extern int security_init (void);
extern int register_security (struct security_operations *ops);
-extern int unregister_security (struct security_operations *ops);
extern int mod_reg_security (const char *name, struct security_operations *ops);
-extern int mod_unreg_security (const char *name, struct security_operations *ops);
extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
struct dentry *parent, void *data,
const struct file_operations *fops);
@@ -2145,6 +1440,158 @@ extern struct dentry *securityfs_create_dir(const char *name, struct dentry *par
extern void securityfs_remove(struct dentry *dentry);
+/* Security operations */
+int security_ptrace(struct task_struct *parent, struct task_struct *child);
+int security_capget(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted);
+int security_capset_check(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted);
+void security_capset_set(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted);
+int security_capable(struct task_struct *tsk, int cap);
+int security_acct(struct file *file);
+int security_sysctl(struct ctl_table *table, int op);
+int security_quotactl(int cmds, int type, int id, struct super_block *sb);
+int security_quota_on(struct dentry *dentry);
+int security_syslog(int type);
+int security_settime(struct timespec *ts, struct timezone *tz);
+int security_vm_enough_memory(long pages);
+int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
+int security_bprm_alloc(struct linux_binprm *bprm);
+void security_bprm_free(struct linux_binprm *bprm);
+void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe);
+void security_bprm_post_apply_creds(struct linux_binprm *bprm);
+int security_bprm_set(struct linux_binprm *bprm);
+int security_bprm_check(struct linux_binprm *bprm);
+int security_bprm_secureexec(struct linux_binprm *bprm);
+int security_sb_alloc(struct super_block *sb);
+void security_sb_free(struct super_block *sb);
+int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy);
+int security_sb_kern_mount(struct super_block *sb, void *data);
+int security_sb_statfs(struct dentry *dentry);
+int security_sb_mount(char *dev_name, struct nameidata *nd,
+ char *type, unsigned long flags, void *data);
+int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd);
+int security_sb_umount(struct vfsmount *mnt, int flags);
+void security_sb_umount_close(struct vfsmount *mnt);
+void security_sb_umount_busy(struct vfsmount *mnt);
+void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data);
+void security_sb_post_mountroot(void);
+void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd);
+int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
+void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
+int security_inode_alloc(struct inode *inode);
+void security_inode_free(struct inode *inode);
+int security_inode_init_security(struct inode *inode, struct inode *dir,
+ char **name, void **value, size_t *len);
+int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
+int security_inode_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *new_dentry);
+int security_inode_unlink(struct inode *dir, struct dentry *dentry);
+int security_inode_symlink(struct inode *dir, struct dentry *dentry,
+ const char *old_name);
+int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
+int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev);
+int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry);
+int security_inode_readlink(struct dentry *dentry);
+int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
+int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd);
+int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
+int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
+void security_inode_delete(struct inode *inode);
+int security_inode_setxattr(struct dentry *dentry, char *name,
+ void *value, size_t size, int flags);
+void security_inode_post_setxattr(struct dentry *dentry, char *name,
+ void *value, size_t size, int flags);
+int security_inode_getxattr(struct dentry *dentry, char *name);
+int security_inode_listxattr(struct dentry *dentry);
+int security_inode_removexattr(struct dentry *dentry, char *name);
+int security_inode_need_killpriv(struct dentry *dentry);
+int security_inode_killpriv(struct dentry *dentry);
+int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
+int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags);
+int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size);
+int security_file_permission(struct file *file, int mask);
+int security_file_alloc(struct file *file);
+void security_file_free(struct file *file);
+int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+int security_file_mmap(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags,
+ unsigned long addr, unsigned long addr_only);
+int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
+ unsigned long prot);
+int security_file_lock(struct file *file, unsigned int cmd);
+int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg);
+int security_file_set_fowner(struct file *file);
+int security_file_send_sigiotask(struct task_struct *tsk,
+ struct fown_struct *fown, int sig);
+int security_file_receive(struct file *file);
+int security_dentry_open(struct file *file);
+int security_task_create(unsigned long clone_flags);
+int security_task_alloc(struct task_struct *p);
+void security_task_free(struct task_struct *p);
+int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
+int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
+ uid_t old_suid, int flags);
+int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags);
+int security_task_setpgid(struct task_struct *p, pid_t pgid);
+int security_task_getpgid(struct task_struct *p);
+int security_task_getsid(struct task_struct *p);
+void security_task_getsecid(struct task_struct *p, u32 *secid);
+int security_task_setgroups(struct group_info *group_info);
+int security_task_setnice(struct task_struct *p, int nice);
+int security_task_setioprio(struct task_struct *p, int ioprio);
+int security_task_getioprio(struct task_struct *p);
+int security_task_setrlimit(unsigned int resource, struct rlimit *new_rlim);
+int security_task_setscheduler(struct task_struct *p,
+ int policy, struct sched_param *lp);
+int security_task_getscheduler(struct task_struct *p);
+int security_task_movememory(struct task_struct *p);
+int security_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid);
+int security_task_wait(struct task_struct *p);
+int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5);
+void security_task_reparent_to_init(struct task_struct *p);
+void security_task_to_inode(struct task_struct *p, struct inode *inode);
+int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
+int security_msg_msg_alloc(struct msg_msg *msg);
+void security_msg_msg_free(struct msg_msg *msg);
+int security_msg_queue_alloc(struct msg_queue *msq);
+void security_msg_queue_free(struct msg_queue *msq);
+int security_msg_queue_associate(struct msg_queue *msq, int msqflg);
+int security_msg_queue_msgctl(struct msg_queue *msq, int cmd);
+int security_msg_queue_msgsnd(struct msg_queue *msq,
+ struct msg_msg *msg, int msqflg);
+int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
+ struct task_struct *target, long type, int mode);
+int security_shm_alloc(struct shmid_kernel *shp);
+void security_shm_free(struct shmid_kernel *shp);
+int security_shm_associate(struct shmid_kernel *shp, int shmflg);
+int security_shm_shmctl(struct shmid_kernel *shp, int cmd);
+int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg);
+int security_sem_alloc(struct sem_array *sma);
+void security_sem_free(struct sem_array *sma);
+int security_sem_associate(struct sem_array *sma, int semflg);
+int security_sem_semctl(struct sem_array *sma, int cmd);
+int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
+ unsigned nsops, int alter);
+void security_d_instantiate (struct dentry *dentry, struct inode *inode);
+int security_getprocattr(struct task_struct *p, char *name, char **value);
+int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);
+int security_netlink_send(struct sock *sk, struct sk_buff *skb);
+int security_netlink_recv(struct sk_buff *skb, int cap);
+int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+void security_release_secctx(char *secdata, u32 seclen);
+
#else /* CONFIG_SECURITY */
/*
@@ -2463,9 +1910,14 @@ static inline int security_inode_removexattr (struct dentry *dentry, char *name)
return cap_inode_removexattr(dentry, name);
}
-static inline const char *security_inode_xattr_getsuffix (void)
+static inline int security_inode_need_killpriv(struct dentry *dentry)
+{
+ return cap_inode_need_killpriv(dentry);
+}
+
+static inline int security_inode_killpriv(struct dentry *dentry)
{
- return NULL ;
+ return cap_inode_killpriv(dentry);
}
static inline int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
@@ -2546,6 +1998,11 @@ static inline int security_file_receive (struct file *file)
return 0;
}
+static inline int security_dentry_open (struct file *file)
+{
+ return 0;
+}
+
static inline int security_task_create (unsigned long clone_flags)
{
return 0;
@@ -2602,12 +2059,12 @@ static inline int security_task_setgroups (struct group_info *group_info)
static inline int security_task_setnice (struct task_struct *p, int nice)
{
- return 0;
+ return cap_task_setnice(p, nice);
}
static inline int security_task_setioprio (struct task_struct *p, int ioprio)
{
- return 0;
+ return cap_task_setioprio(p, ioprio);
}
static inline int security_task_getioprio (struct task_struct *p)
@@ -2625,7 +2082,7 @@ static inline int security_task_setscheduler (struct task_struct *p,
int policy,
struct sched_param *lp)
{
- return 0;
+ return cap_task_setscheduler(p, policy, lp);
}
static inline int security_task_getscheduler (struct task_struct *p)
@@ -2642,7 +2099,7 @@ static inline int security_task_kill (struct task_struct *p,
struct siginfo *info, int sig,
u32 secid)
{
- return 0;
+ return cap_task_kill(p, info, sig, secid);
}
static inline int security_task_wait (struct task_struct *p)
@@ -2816,170 +2273,43 @@ static inline void security_release_secctx(char *secdata, u32 seclen)
#endif /* CONFIG_SECURITY */
#ifdef CONFIG_SECURITY_NETWORK
-static inline int security_unix_stream_connect(struct socket * sock,
- struct socket * other,
- struct sock * newsk)
-{
- return security_ops->unix_stream_connect(sock, other, newsk);
-}
+int security_unix_stream_connect(struct socket *sock, struct socket *other,
+ struct sock *newsk);
+int security_unix_may_send(struct socket *sock, struct socket *other);
+int security_socket_create(int family, int type, int protocol, int kern);
+int security_socket_post_create(struct socket *sock, int family,
+ int type, int protocol, int kern);
+int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen);
+int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen);
+int security_socket_listen(struct socket *sock, int backlog);
+int security_socket_accept(struct socket *sock, struct socket *newsock);
+void security_socket_post_accept(struct socket *sock, struct socket *newsock);
+int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size);
+int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,
+ int size, int flags);
+int security_socket_getsockname(struct socket *sock);
+int security_socket_getpeername(struct socket *sock);
+int security_socket_getsockopt(struct socket *sock, int level, int optname);
+int security_socket_setsockopt(struct socket *sock, int level, int optname);
+int security_socket_shutdown(struct socket *sock, int how);
+int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb);
+int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
+ int __user *optlen, unsigned len);
+int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid);
+int security_sk_alloc(struct sock *sk, int family, gfp_t priority);
+void security_sk_free(struct sock *sk);
+void security_sk_clone(const struct sock *sk, struct sock *newsk);
+void security_sk_classify_flow(struct sock *sk, struct flowi *fl);
+void security_req_classify_flow(const struct request_sock *req, struct flowi *fl);
+void security_sock_graft(struct sock*sk, struct socket *parent);
+int security_inet_conn_request(struct sock *sk,
+ struct sk_buff *skb, struct request_sock *req);
+void security_inet_csk_clone(struct sock *newsk,
+ const struct request_sock *req);
+void security_inet_conn_established(struct sock *sk,
+ struct sk_buff *skb);
-static inline int security_unix_may_send(struct socket * sock,
- struct socket * other)
-{
- return security_ops->unix_may_send(sock, other);
-}
-
-static inline int security_socket_create (int family, int type,
- int protocol, int kern)
-{
- return security_ops->socket_create(family, type, protocol, kern);
-}
-
-static inline int security_socket_post_create(struct socket * sock,
- int family,
- int type,
- int protocol, int kern)
-{
- return security_ops->socket_post_create(sock, family, type,
- protocol, kern);
-}
-
-static inline int security_socket_bind(struct socket * sock,
- struct sockaddr * address,
- int addrlen)
-{
- return security_ops->socket_bind(sock, address, addrlen);
-}
-
-static inline int security_socket_connect(struct socket * sock,
- struct sockaddr * address,
- int addrlen)
-{
- return security_ops->socket_connect(sock, address, addrlen);
-}
-
-static inline int security_socket_listen(struct socket * sock, int backlog)
-{
- return security_ops->socket_listen(sock, backlog);
-}
-
-static inline int security_socket_accept(struct socket * sock,
- struct socket * newsock)
-{
- return security_ops->socket_accept(sock, newsock);
-}
-
-static inline void security_socket_post_accept(struct socket * sock,
- struct socket * newsock)
-{
- security_ops->socket_post_accept(sock, newsock);
-}
-
-static inline int security_socket_sendmsg(struct socket * sock,
- struct msghdr * msg, int size)
-{
- return security_ops->socket_sendmsg(sock, msg, size);
-}
-
-static inline int security_socket_recvmsg(struct socket * sock,
- struct msghdr * msg, int size,
- int flags)
-{
- return security_ops->socket_recvmsg(sock, msg, size, flags);
-}
-
-static inline int security_socket_getsockname(struct socket * sock)
-{
- return security_ops->socket_getsockname(sock);
-}
-
-static inline int security_socket_getpeername(struct socket * sock)
-{
- return security_ops->socket_getpeername(sock);
-}
-
-static inline int security_socket_getsockopt(struct socket * sock,
- int level, int optname)
-{
- return security_ops->socket_getsockopt(sock, level, optname);
-}
-
-static inline int security_socket_setsockopt(struct socket * sock,
- int level, int optname)
-{
- return security_ops->socket_setsockopt(sock, level, optname);
-}
-
-static inline int security_socket_shutdown(struct socket * sock, int how)
-{
- return security_ops->socket_shutdown(sock, how);
-}
-
-static inline int security_sock_rcv_skb (struct sock * sk,
- struct sk_buff * skb)
-{
- return security_ops->socket_sock_rcv_skb (sk, skb);
-}
-
-static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
- int __user *optlen, unsigned len)
-{
- return security_ops->socket_getpeersec_stream(sock, optval, optlen, len);
-}
-
-static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
-{
- return security_ops->socket_getpeersec_dgram(sock, skb, secid);
-}
-
-static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
-{
- return security_ops->sk_alloc_security(sk, family, priority);
-}
-
-static inline void security_sk_free(struct sock *sk)
-{
- return security_ops->sk_free_security(sk);
-}
-
-static inline void security_sk_clone(const struct sock *sk, struct sock *newsk)
-{
- return security_ops->sk_clone_security(sk, newsk);
-}
-
-static inline void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
-{
- security_ops->sk_getsecid(sk, &fl->secid);
-}
-
-static inline void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
-{
- security_ops->req_classify_flow(req, fl);
-}
-
-static inline void security_sock_graft(struct sock* sk, struct socket *parent)
-{
- security_ops->sock_graft(sk, parent);
-}
-
-static inline int security_inet_conn_request(struct sock *sk,
- struct sk_buff *skb, struct request_sock *req)
-{
- return security_ops->inet_conn_request(sk, skb, req);
-}
-
-static inline void security_inet_csk_clone(struct sock *newsk,
- const struct request_sock *req)
-{
- security_ops->inet_csk_clone(newsk, req);
-}
-
-static inline void security_inet_conn_established(struct sock *sk,
- struct sk_buff *skb)
-{
- security_ops->inet_conn_established(sk, skb);
-}
#else /* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct socket * sock,
struct socket * other,
@@ -3137,77 +2467,24 @@ static inline void security_inet_conn_established(struct sock *sk,
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM
-static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
-{
- return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
-}
-static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
-{
- return security_ops->xfrm_policy_clone_security(old, new);
-}
-
-static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
-{
- security_ops->xfrm_policy_free_security(xp);
-}
-
-static inline int security_xfrm_policy_delete(struct xfrm_policy *xp)
-{
- return security_ops->xfrm_policy_delete_security(xp);
-}
+int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
+void security_xfrm_policy_free(struct xfrm_policy *xp);
+int security_xfrm_policy_delete(struct xfrm_policy *xp);
+int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
+ struct xfrm_sec_ctx *polsec, u32 secid);
+int security_xfrm_state_delete(struct xfrm_state *x);
+void security_xfrm_state_free(struct xfrm_state *x);
+int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
+int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
+ struct xfrm_policy *xp, struct flowi *fl);
+int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid);
+void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl);
-static inline int security_xfrm_state_alloc(struct xfrm_state *x,
- struct xfrm_user_sec_ctx *sec_ctx)
-{
- return security_ops->xfrm_state_alloc_security(x, sec_ctx, 0);
-}
-
-static inline int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
- struct xfrm_sec_ctx *polsec, u32 secid)
-{
- if (!polsec)
- return 0;
- /*
- * We want the context to be taken from secid which is usually
- * from the sock.
- */
- return security_ops->xfrm_state_alloc_security(x, NULL, secid);
-}
-
-static inline int security_xfrm_state_delete(struct xfrm_state *x)
-{
- return security_ops->xfrm_state_delete_security(x);
-}
-
-static inline void security_xfrm_state_free(struct xfrm_state *x)
-{
- security_ops->xfrm_state_free_security(x);
-}
-
-static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
-{
- return security_ops->xfrm_policy_lookup(xp, fl_secid, dir);
-}
-
-static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
- struct xfrm_policy *xp, struct flowi *fl)
-{
- return security_ops->xfrm_state_pol_flow_match(x, xp, fl);
-}
-
-static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
-{
- return security_ops->xfrm_decode_session(skb, secid, 1);
-}
-
-static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
-{
- int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0);
-
- BUG_ON(rc);
-}
#else /* CONFIG_SECURITY_NETWORK_XFRM */
+
static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
{
return 0;
@@ -3272,24 +2549,11 @@ static inline void security_skb_classify_flow(struct sk_buff *skb, struct flowi
#ifdef CONFIG_KEYS
#ifdef CONFIG_SECURITY
-static inline int security_key_alloc(struct key *key,
- struct task_struct *tsk,
- unsigned long flags)
-{
- return security_ops->key_alloc(key, tsk, flags);
-}
-
-static inline void security_key_free(struct key *key)
-{
- security_ops->key_free(key);
-}
-static inline int security_key_permission(key_ref_t key_ref,
- struct task_struct *context,
- key_perm_t perm)
-{
- return security_ops->key_permission(key_ref, context, perm);
-}
+int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags);
+void security_key_free(struct key *key);
+int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context, key_perm_t perm);
#else
diff --git a/include/linux/selection.h b/include/linux/selection.h
index f9457861937..8cdaa1151d2 100644
--- a/include/linux/selection.h
+++ b/include/linux/selection.h
@@ -13,6 +13,7 @@
struct tty_struct;
extern struct vc_data *sel_cons;
+struct tty_struct;
extern void clear_selection(void);
extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty);
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 8bf1e05115b..ebbc02b325f 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -18,7 +18,7 @@ struct seq_file {
size_t from;
size_t count;
loff_t index;
- loff_t version;
+ u64 version;
struct mutex lock;
const struct seq_operations *op;
void *private;
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 09d17b06bf0..4db77249281 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -291,7 +291,8 @@ struct uart_port {
resource_size_t mapbase; /* for ioremap */
struct device *dev; /* parent device */
unsigned char hub6; /* this should be in the 8250 driver */
- unsigned char unused[3];
+ unsigned char suspended;
+ unsigned char unused[2];
void *private_data; /* generic platform data pointer */
};
diff --git a/include/linux/shm.h b/include/linux/shm.h
index ad2e3af6599..bea65d9c93e 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -16,7 +16,9 @@
#define SHMALL (SHMMAX/PAGE_SIZE*(SHMMNI/16)) /* max shm system wide (pages) */
#define SHMSEG SHMMNI /* max shared segs per process */
+#ifdef __KERNEL__
#include <asm/shmparam.h>
+#endif
/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct shmid_ds {
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
index 4c9ff0910ae..86f9b1ef0e0 100644
--- a/include/linux/signalfd.h
+++ b/include/linux/signalfd.h
@@ -10,22 +10,22 @@
struct signalfd_siginfo {
- __u32 signo;
- __s32 err;
- __s32 code;
- __u32 pid;
- __u32 uid;
- __s32 fd;
- __u32 tid;
- __u32 band;
- __u32 overrun;
- __u32 trapno;
- __s32 status;
- __s32 svint;
- __u64 svptr;
- __u64 utime;
- __u64 stime;
- __u64 addr;
+ __u32 ssi_signo;
+ __s32 ssi_errno;
+ __s32 ssi_code;
+ __u32 ssi_pid;
+ __u32 ssi_uid;
+ __s32 ssi_fd;
+ __u32 ssi_tid;
+ __u32 ssi_band;
+ __u32 ssi_overrun;
+ __u32 ssi_trapno;
+ __s32 ssi_status;
+ __s32 ssi_int;
+ __u64 ssi_ptr;
+ __u64 ssi_utime;
+ __u64 ssi_stime;
+ __u64 ssi_addr;
/*
* Pad strcture to 128 bytes. Remember to update the
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a656cecd373..f93f22b3d2f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -357,6 +357,7 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
}
extern void kfree_skbmem(struct sk_buff *skb);
+extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
extern struct sk_buff *skb_clone(struct sk_buff *skb,
gfp_t priority);
extern struct sk_buff *skb_copy(const struct sk_buff *skb,
@@ -1781,6 +1782,11 @@ static inline int skb_is_gso(const struct sk_buff *skb)
return skb_shinfo(skb)->gso_size;
}
+static inline int skb_is_gso_v6(const struct sk_buff *skb)
+{
+ return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
+}
+
static inline void skb_forward_csum(struct sk_buff *skb)
{
/* Unfortunately we don't support this one. Any brave souls? */
diff --git a/include/linux/slab.h b/include/linux/slab.h
index d859354b9e5..f3a8eecd99f 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -24,12 +24,14 @@
#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
-#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */
#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */
+/* The following flags affect the page allocator grouping pages by mobility */
+#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
+#define SLAB_TEMPORARY SLAB_RECLAIM_ACCOUNT /* Objects are short-lived */
/*
* ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
*
@@ -51,7 +53,7 @@ int slab_is_available(void);
struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
unsigned long,
- void (*)(void *, struct kmem_cache *, unsigned long));
+ void (*)(struct kmem_cache *, void *));
void kmem_cache_destroy(struct kmem_cache *);
int kmem_cache_shrink(struct kmem_cache *);
void kmem_cache_free(struct kmem_cache *, void *);
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 74962077f63..40801e754af 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -11,6 +11,14 @@
#include <linux/workqueue.h>
#include <linux/kobject.h>
+struct kmem_cache_cpu {
+ void **freelist;
+ struct page *page;
+ int node;
+ unsigned int offset;
+ unsigned int objsize;
+};
+
struct kmem_cache_node {
spinlock_t list_lock; /* Protect partial list and nr_partial */
unsigned long nr_partial;
@@ -41,7 +49,7 @@ struct kmem_cache {
/* Allocation and freeing of slabs */
int objects; /* Number of objects in slab */
int refcount; /* Refcount for slab cache destroy */
- void (*ctor)(void *, struct kmem_cache *, unsigned long);
+ void (*ctor)(struct kmem_cache *, void *);
int inuse; /* Offset to metadata */
int align; /* Alignment */
const char *name; /* Name (only for display!) */
@@ -54,7 +62,11 @@ struct kmem_cache {
int defrag_ratio;
struct kmem_cache_node *node[MAX_NUMNODES];
#endif
- struct page *cpu_slab[NR_CPUS];
+#ifdef CONFIG_SMP
+ struct kmem_cache_cpu *cpu_slab[NR_CPUS];
+#else
+ struct kmem_cache_cpu cpu_slab;
+#endif
};
/*
@@ -72,7 +84,7 @@ struct kmem_cache {
* We keep the general caches in an array of slab caches that are used for
* 2^x bytes of allocations.
*/
-extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1];
+extern struct kmem_cache kmalloc_caches[PAGE_SHIFT];
/*
* Sorry that the following has to be that ugly but some versions of GCC
@@ -83,9 +95,6 @@ static __always_inline int kmalloc_index(size_t size)
if (!size)
return 0;
- if (size > KMALLOC_MAX_SIZE)
- return -1;
-
if (size <= KMALLOC_MIN_SIZE)
return KMALLOC_SHIFT_LOW;
@@ -102,6 +111,10 @@ static __always_inline int kmalloc_index(size_t size)
if (size <= 512) return 9;
if (size <= 1024) return 10;
if (size <= 2 * 1024) return 11;
+/*
+ * The following is only needed to support architectures with a larger page
+ * size than 4k.
+ */
if (size <= 4 * 1024) return 12;
if (size <= 8 * 1024) return 13;
if (size <= 16 * 1024) return 14;
@@ -109,13 +122,9 @@ static __always_inline int kmalloc_index(size_t size)
if (size <= 64 * 1024) return 16;
if (size <= 128 * 1024) return 17;
if (size <= 256 * 1024) return 18;
- if (size <= 512 * 1024) return 19;
+ if (size <= 512 * 1024) return 19;
if (size <= 1024 * 1024) return 20;
if (size <= 2 * 1024 * 1024) return 21;
- if (size <= 4 * 1024 * 1024) return 22;
- if (size <= 8 * 1024 * 1024) return 23;
- if (size <= 16 * 1024 * 1024) return 24;
- if (size <= 32 * 1024 * 1024) return 25;
return -1;
/*
@@ -140,19 +149,6 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size)
if (index == 0)
return NULL;
- /*
- * This function only gets expanded if __builtin_constant_p(size), so
- * testing it here shouldn't be needed. But some versions of gcc need
- * help.
- */
- if (__builtin_constant_p(size) && index < 0) {
- /*
- * Generate a link failure. Would be great if we could
- * do something to stop the compile here.
- */
- extern void __kmalloc_size_too_large(void);
- __kmalloc_size_too_large();
- }
return &kmalloc_caches[index];
}
@@ -168,15 +164,21 @@ void *__kmalloc(size_t size, gfp_t flags);
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
- if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
- struct kmem_cache *s = kmalloc_slab(size);
+ if (__builtin_constant_p(size)) {
+ if (size > PAGE_SIZE / 2)
+ return (void *)__get_free_pages(flags | __GFP_COMP,
+ get_order(size));
- if (!s)
- return ZERO_SIZE_PTR;
+ if (!(flags & SLUB_DMA)) {
+ struct kmem_cache *s = kmalloc_slab(size);
- return kmem_cache_alloc(s, flags);
- } else
- return __kmalloc(size, flags);
+ if (!s)
+ return ZERO_SIZE_PTR;
+
+ return kmem_cache_alloc(s, flags);
+ }
+ }
+ return __kmalloc(size, flags);
}
#ifdef CONFIG_NUMA
@@ -185,15 +187,16 @@ void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
- if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
- struct kmem_cache *s = kmalloc_slab(size);
+ if (__builtin_constant_p(size) &&
+ size <= PAGE_SIZE / 2 && !(flags & SLUB_DMA)) {
+ struct kmem_cache *s = kmalloc_slab(size);
if (!s)
return ZERO_SIZE_PTR;
return kmem_cache_alloc_node(s, flags, node);
- } else
- return __kmalloc_node(size, flags, node);
+ }
+ return __kmalloc_node(size, flags, node);
}
#endif
diff --git a/include/linux/sm501-regs.h b/include/linux/sm501-regs.h
index 014e73b31fc..df7620dd8f3 100644
--- a/include/linux/sm501-regs.h
+++ b/include/linux/sm501-regs.h
@@ -15,6 +15,24 @@
/* config 1 */
#define SM501_SYSTEM_CONTROL (0x000000)
+
+#define SM501_SYSCTRL_PANEL_TRISTATE (1<<0)
+#define SM501_SYSCTRL_MEM_TRISTATE (1<<1)
+#define SM501_SYSCTRL_CRT_TRISTATE (1<<2)
+
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_1 (0<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_2 (1<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_4 (2<<4)
+#define SM501_SYSCTRL_PCI_SLAVE_BURST_8 (3<<4)
+
+#define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6)
+#define SM501_SYSCTRL_PCI_RETRY_DISABLE (1<<7)
+#define SM501_SYSCTRL_PCI_SUBSYS_LOCK (1<<11)
+#define SM501_SYSCTRL_PCI_BURST_READ_EN (1<<15)
+
+/* miscellaneous control */
+
#define SM501_MISC_CONTROL (0x000004)
#define SM501_MISC_BUS_SH (0x0)
diff --git a/include/linux/spi/at73c213.h b/include/linux/spi/at73c213.h
new file mode 100644
index 00000000000..0f20a70e5eb
--- /dev/null
+++ b/include/linux/spi/at73c213.h
@@ -0,0 +1,25 @@
+/*
+ * Board-specific data used to set up AT73c213 audio DAC driver.
+ */
+
+#ifndef __LINUX_SPI_AT73C213_H
+#define __LINUX_SPI_AT73C213_H
+
+/**
+ * at73c213_board_info - how the external DAC is wired to the device.
+ *
+ * @ssc_id: SSC platform_driver id the DAC shall use to stream the audio.
+ * @dac_clk: the external clock used to provide master clock to the DAC.
+ * @shortname: a short discription for the DAC, seen by userspace tools.
+ *
+ * This struct contains the configuration of the hardware connection to the
+ * external DAC. The DAC needs a master clock and a I2S audio stream. It also
+ * provides a name which is used to identify it in userspace tools.
+ */
+struct at73c213_board_info {
+ int ssc_id;
+ struct clk *dac_clk;
+ char shortname[32];
+};
+
+#endif /* __LINUX_SPI_AT73C213_H */
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 002a3cddbdd..387e428f1cd 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -195,7 +195,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
/**
* struct spi_master - interface to SPI master controller
- * @cdev: class interface to this driver
+ * @dev: device interface to this driver
* @bus_num: board-specific (and often SOC-specific) identifier for a
* given SPI controller.
* @num_chipselect: chipselects are used to distinguish individual
@@ -222,7 +222,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* message's completion function when the transaction completes.
*/
struct spi_master {
- struct class_device cdev;
+ struct device dev;
/* other than negative (== assign one dynamically), bus_num is fully
* board-specific. usually that simplifies to being SOC-specific.
@@ -268,17 +268,17 @@ struct spi_master {
static inline void *spi_master_get_devdata(struct spi_master *master)
{
- return class_get_devdata(&master->cdev);
+ return dev_get_drvdata(&master->dev);
}
static inline void spi_master_set_devdata(struct spi_master *master, void *data)
{
- class_set_devdata(&master->cdev, data);
+ dev_set_drvdata(&master->dev, data);
}
static inline struct spi_master *spi_master_get(struct spi_master *master)
{
- if (!master || !class_device_get(&master->cdev))
+ if (!master || !get_device(&master->dev))
return NULL;
return master;
}
@@ -286,7 +286,7 @@ static inline struct spi_master *spi_master_get(struct spi_master *master)
static inline void spi_master_put(struct spi_master *master)
{
if (master)
- class_device_put(&master->cdev);
+ put_device(&master->dev);
}
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index c0d9d14983b..d9d5c5ad826 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -117,7 +117,7 @@ struct rpc_create_args {
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
- struct rpc_program *, int);
+ struct rpc_program *, u32);
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
void rpc_shutdown_client(struct rpc_clnt *);
void rpc_release_client(struct rpc_clnt *);
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index 3912cf16361..3347c72b848 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -88,6 +88,11 @@ enum {
CTL_SLOTTABLE_TCP,
CTL_MIN_RESVPORT,
CTL_MAX_RESVPORT,
+ CTL_SLOTTABLE_RDMA,
+ CTL_RDMA_MAXINLINEREAD,
+ CTL_RDMA_MAXINLINEWRITE,
+ CTL_RDMA_WRITEPADDING,
+ CTL_RDMA_MEMREG,
};
#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 784d4c3ef65..c4beb577511 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -138,6 +138,19 @@ typedef __be32 rpc_fraghdr;
#define RPC_MAX_HEADER_WITH_AUTH \
(RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
+/*
+ * RFC1833/RFC3530 rpcbind (v3+) well-known netid's.
+ */
+#define RPCBIND_NETID_UDP "udp"
+#define RPCBIND_NETID_TCP "tcp"
+#define RPCBIND_NETID_UDP6 "udp6"
+#define RPCBIND_NETID_TCP6 "tcp6"
+
+/*
+ * Note that RFC 1833 does not put any size restrictions on the
+ * netid string, but all currently defined netid's fit in 4 bytes.
+ */
+#define RPCBIND_MAXNETIDLEN (4u)
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/rpc_rdma.h b/include/linux/sunrpc/rpc_rdma.h
new file mode 100644
index 00000000000..0013a0d8dc6
--- /dev/null
+++ b/include/linux/sunrpc/rpc_rdma.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the BSD-type
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Network Appliance, Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SUNRPC_RPC_RDMA_H
+#define _LINUX_SUNRPC_RPC_RDMA_H
+
+struct rpcrdma_segment {
+ uint32_t rs_handle; /* Registered memory handle */
+ uint32_t rs_length; /* Length of the chunk in bytes */
+ uint64_t rs_offset; /* Chunk virtual address or offset */
+};
+
+/*
+ * read chunk(s), encoded as a linked list.
+ */
+struct rpcrdma_read_chunk {
+ uint32_t rc_discrim; /* 1 indicates presence */
+ uint32_t rc_position; /* Position in XDR stream */
+ struct rpcrdma_segment rc_target;
+};
+
+/*
+ * write chunk, and reply chunk.
+ */
+struct rpcrdma_write_chunk {
+ struct rpcrdma_segment wc_target;
+};
+
+/*
+ * write chunk(s), encoded as a counted array.
+ */
+struct rpcrdma_write_array {
+ uint32_t wc_discrim; /* 1 indicates presence */
+ uint32_t wc_nchunks; /* Array count */
+ struct rpcrdma_write_chunk wc_array[0];
+};
+
+struct rpcrdma_msg {
+ uint32_t rm_xid; /* Mirrors the RPC header xid */
+ uint32_t rm_vers; /* Version of this protocol */
+ uint32_t rm_credit; /* Buffers requested/granted */
+ uint32_t rm_type; /* Type of message (enum rpcrdma_proc) */
+ union {
+
+ struct { /* no chunks */
+ uint32_t rm_empty[3]; /* 3 empty chunk lists */
+ } rm_nochunks;
+
+ struct { /* no chunks and padded */
+ uint32_t rm_align; /* Padding alignment */
+ uint32_t rm_thresh; /* Padding threshold */
+ uint32_t rm_pempty[3]; /* 3 empty chunk lists */
+ } rm_padded;
+
+ uint32_t rm_chunks[0]; /* read, write and reply chunks */
+
+ } rm_body;
+};
+
+#define RPCRDMA_HDRLEN_MIN 28
+
+enum rpcrdma_errcode {
+ ERR_VERS = 1,
+ ERR_CHUNK = 2
+};
+
+struct rpcrdma_err_vers {
+ uint32_t rdma_vers_low; /* Version range supported by peer */
+ uint32_t rdma_vers_high;
+};
+
+enum rpcrdma_proc {
+ RDMA_MSG = 0, /* An RPC call or reply msg */
+ RDMA_NOMSG = 1, /* An RPC call or reply msg - separate body */
+ RDMA_MSGP = 2, /* An RPC call or reply msg with padding */
+ RDMA_DONE = 3, /* Client signals reply completion */
+ RDMA_ERROR = 4 /* An RPC RDMA encoding error */
+};
+
+#endif /* _LINUX_SUNRPC_RPC_RDMA_H */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index c6b53d181bf..0751c9464d0 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -70,7 +70,10 @@ struct xdr_buf {
struct page ** pages; /* Array of contiguous pages */
unsigned int page_base, /* Start of page data */
- page_len; /* Length of page data */
+ page_len, /* Length of page data */
+ flags; /* Flags for data disposition */
+#define XDRBUF_READ 0x01 /* target of file read */
+#define XDRBUF_WRITE 0x02 /* source of file write */
unsigned int buflen, /* Total length of storage buffer */
len; /* Length of XDR encoded message */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index d11cedd14f0..30b17b3bc1a 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -19,25 +19,11 @@
#ifdef __KERNEL__
-extern unsigned int xprt_udp_slot_table_entries;
-extern unsigned int xprt_tcp_slot_table_entries;
-
#define RPC_MIN_SLOT_TABLE (2U)
#define RPC_DEF_SLOT_TABLE (16U)
#define RPC_MAX_SLOT_TABLE (128U)
/*
- * Parameters for choosing a free port
- */
-extern unsigned int xprt_min_resvport;
-extern unsigned int xprt_max_resvport;
-
-#define RPC_MIN_RESVPORT (1U)
-#define RPC_MAX_RESVPORT (65535U)
-#define RPC_DEF_MIN_RESVPORT (665U)
-#define RPC_DEF_MAX_RESVPORT (1023U)
-
-/*
* This describes a timeout strategy
*/
struct rpc_timeout {
@@ -53,6 +39,10 @@ enum rpc_display_format_t {
RPC_DISPLAY_PORT,
RPC_DISPLAY_PROTO,
RPC_DISPLAY_ALL,
+ RPC_DISPLAY_HEX_ADDR,
+ RPC_DISPLAY_HEX_PORT,
+ RPC_DISPLAY_UNIVERSAL_ADDR,
+ RPC_DISPLAY_NETID,
RPC_DISPLAY_MAX,
};
@@ -196,14 +186,22 @@ struct rpc_xprt {
char * address_strings[RPC_DISPLAY_MAX];
};
-struct rpc_xprtsock_create {
- int proto; /* IPPROTO_UDP or IPPROTO_TCP */
+struct xprt_create {
+ int ident; /* XPRT_TRANSPORT identifier */
struct sockaddr * srcaddr; /* optional local address */
struct sockaddr * dstaddr; /* remote peer address */
size_t addrlen;
struct rpc_timeout * timeout; /* optional timeout parameters */
};
+struct xprt_class {
+ struct list_head list;
+ int ident; /* XPRT_TRANSPORT identifier */
+ struct rpc_xprt * (*setup)(struct xprt_create *);
+ struct module *owner;
+ char name[32];
+};
+
/*
* Transport operations used by ULPs
*/
@@ -212,7 +210,7 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long
/*
* Generic internal transport functions
*/
-struct rpc_xprt * xprt_create_transport(struct rpc_xprtsock_create *args);
+struct rpc_xprt *xprt_create_transport(struct xprt_create *args);
void xprt_connect(struct rpc_task *task);
void xprt_reserve(struct rpc_task *task);
int xprt_reserve_xprt(struct rpc_task *task);
@@ -235,6 +233,8 @@ static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *
/*
* Transport switch helper functions
*/
+int xprt_register_transport(struct xprt_class *type);
+int xprt_unregister_transport(struct xprt_class *type);
void xprt_set_retrans_timeout_def(struct rpc_task *task);
void xprt_set_retrans_timeout_rtt(struct rpc_task *task);
void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
@@ -248,14 +248,6 @@ void xprt_release_rqst_cong(struct rpc_task *task);
void xprt_disconnect(struct rpc_xprt *xprt);
/*
- * Socket transport setup operations
- */
-struct rpc_xprt * xs_setup_udp(struct rpc_xprtsock_create *args);
-struct rpc_xprt * xs_setup_tcp(struct rpc_xprtsock_create *args);
-int init_socket_xprt(void);
-void cleanup_socket_xprt(void);
-
-/*
* Reserved bit positions in xprt->state
*/
#define XPRT_LOCKED (0)
diff --git a/include/linux/sunrpc/xprtrdma.h b/include/linux/sunrpc/xprtrdma.h
new file mode 100644
index 00000000000..4de56b1d372
--- /dev/null
+++ b/include/linux/sunrpc/xprtrdma.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the BSD-type
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Network Appliance, Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SUNRPC_XPRTRDMA_H
+#define _LINUX_SUNRPC_XPRTRDMA_H
+
+/*
+ * RPC transport identifier for RDMA
+ */
+#define XPRT_TRANSPORT_RDMA 256
+
+/*
+ * rpcbind (v3+) RDMA netid.
+ */
+#define RPCBIND_NETID_RDMA "rdma"
+
+/*
+ * Constants. Max RPC/NFS header is big enough to account for
+ * additional marshaling buffers passed down by Linux client.
+ *
+ * RDMA header is currently fixed max size, and is big enough for a
+ * fully-chunked NFS message (read chunks are the largest). Note only
+ * a single chunk type per message is supported currently.
+ */
+#define RPCRDMA_MIN_SLOT_TABLE (2U)
+#define RPCRDMA_DEF_SLOT_TABLE (32U)
+#define RPCRDMA_MAX_SLOT_TABLE (256U)
+
+#define RPCRDMA_DEF_INLINE (1024) /* default inline max */
+
+#define RPCRDMA_INLINE_PAD_THRESH (512)/* payload threshold to pad (bytes) */
+
+#define RDMA_RESOLVE_TIMEOUT (5*HZ) /* TBD 5 seconds */
+#define RDMA_CONNECT_RETRY_MAX (2) /* retries if no listener backlog */
+
+/* memory registration strategies */
+#define RPCRDMA_PERSISTENT_REGISTRATION (1)
+
+enum rpcrdma_memreg {
+ RPCRDMA_BOUNCEBUFFERS = 0,
+ RPCRDMA_REGISTER,
+ RPCRDMA_MEMWINDOWS,
+ RPCRDMA_MEMWINDOWS_ASYNC,
+ RPCRDMA_MTHCAFMR,
+ RPCRDMA_ALLPHYSICAL,
+ RPCRDMA_LAST
+};
+
+#endif /* _LINUX_SUNRPC_XPRTRDMA_H */
diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h
new file mode 100644
index 00000000000..2c6c2c2783d
--- /dev/null
+++ b/include/linux/sunrpc/xprtsock.h
@@ -0,0 +1,51 @@
+/*
+ * linux/include/linux/sunrpc/xprtsock.h
+ *
+ * Declarations for the RPC transport socket provider.
+ */
+
+#ifndef _LINUX_SUNRPC_XPRTSOCK_H
+#define _LINUX_SUNRPC_XPRTSOCK_H
+
+#ifdef __KERNEL__
+
+/*
+ * Socket transport setup operations
+ */
+struct rpc_xprt *xs_setup_udp(struct xprt_create *args);
+struct rpc_xprt *xs_setup_tcp(struct xprt_create *args);
+
+int init_socket_xprt(void);
+void cleanup_socket_xprt(void);
+
+/*
+ * RPC transport identifiers for UDP, TCP
+ *
+ * To preserve compatibility with the historical use of raw IP protocol
+ * id's for transport selection, these are specified with the previous
+ * values. No such restriction exists for new transports, except that
+ * they may not collide with these values (17 and 6, respectively).
+ */
+#define XPRT_TRANSPORT_UDP IPPROTO_UDP
+#define XPRT_TRANSPORT_TCP IPPROTO_TCP
+
+/*
+ * RPC slot table sizes for UDP, TCP transports
+ */
+extern unsigned int xprt_udp_slot_table_entries;
+extern unsigned int xprt_tcp_slot_table_entries;
+
+/*
+ * Parameters for choosing a free port
+ */
+extern unsigned int xprt_min_resvport;
+extern unsigned int xprt_max_resvport;
+
+#define RPC_MIN_RESVPORT (1U)
+#define RPC_MAX_RESVPORT (65535U)
+#define RPC_DEF_MIN_RESVPORT (665U)
+#define RPC_DEF_MAX_RESVPORT (1023U)
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_SUNRPC_XPRTSOCK_H */
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 388cace9751..4360e081695 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_SWSUSP_H
-#define _LINUX_SWSUSP_H
+#ifndef _LINUX_SUSPEND_H
+#define _LINUX_SUSPEND_H
#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
#include <asm/suspend.h>
@@ -9,6 +9,108 @@
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/mm.h>
+#include <asm/errno.h>
+
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+#else
+static inline int pm_prepare_console(void) { return 0; }
+static inline void pm_restore_console(void) {}
+#endif
+
+typedef int __bitwise suspend_state_t;
+
+#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
+#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1)
+#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
+#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
+
+/**
+ * struct platform_suspend_ops - Callbacks for managing platform dependent
+ * system sleep states.
+ *
+ * @valid: Callback to determine if given system sleep state is supported by
+ * the platform.
+ * Valid (ie. supported) states are advertised in /sys/power/state. Note
+ * that it still may be impossible to enter given system sleep state if the
+ * conditions aren't right.
+ * There is the %suspend_valid_only_mem function available that can be
+ * assigned to this if the platform only supports mem sleep.
+ *
+ * @set_target: Tell the platform which system sleep state is going to be
+ * entered.
+ * @set_target() is executed right prior to suspending devices. The
+ * information conveyed to the platform code by @set_target() should be
+ * disregarded by the platform as soon as @finish() is executed and if
+ * @prepare() fails. If @set_target() fails (ie. returns nonzero),
+ * @prepare(), @enter() and @finish() will not be called by the PM core.
+ * This callback is optional. However, if it is implemented, the argument
+ * passed to @enter() is meaningless and should be ignored.
+ *
+ * @prepare: Prepare the platform for entering the system sleep state indicated
+ * by @set_target().
+ * @prepare() is called right after devices have been suspended (ie. the
+ * appropriate .suspend() method has been executed for each device) and
+ * before the nonboot CPUs are disabled (it is executed with IRQs enabled).
+ * This callback is optional. It returns 0 on success or a negative
+ * error code otherwise, in which case the system cannot enter the desired
+ * sleep state (@enter() and @finish() will not be called in that case).
+ *
+ * @enter: Enter the system sleep state indicated by @set_target() or
+ * represented by the argument if @set_target() is not implemented.
+ * This callback is mandatory. It returns 0 on success or a negative
+ * error code otherwise, in which case the system cannot enter the desired
+ * sleep state.
+ *
+ * @finish: Called when the system has just left a sleep state, right after
+ * the nonboot CPUs have been enabled and before devices are resumed (it is
+ * executed with IRQs enabled).
+ * This callback is optional, but should be implemented by the platforms
+ * that implement @prepare(). If implemented, it is always called after
+ * @enter() (even if @enter() fails).
+ */
+struct platform_suspend_ops {
+ int (*valid)(suspend_state_t state);
+ int (*set_target)(suspend_state_t state);
+ int (*prepare)(void);
+ int (*enter)(suspend_state_t state);
+ void (*finish)(void);
+};
+
+#ifdef CONFIG_SUSPEND
+/**
+ * suspend_set_ops - set platform dependent suspend operations
+ * @ops: The new suspend operations to set.
+ */
+extern void suspend_set_ops(struct platform_suspend_ops *ops);
+extern int suspend_valid_only_mem(suspend_state_t state);
+
+/**
+ * arch_suspend_disable_irqs - disable IRQs for suspend
+ *
+ * Disables IRQs (in the default case). This is a weak symbol in the common
+ * code and thus allows architectures to override it if more needs to be
+ * done. Not called for suspend to disk.
+ */
+extern void arch_suspend_disable_irqs(void);
+
+/**
+ * arch_suspend_enable_irqs - enable IRQs after suspend
+ *
+ * Enables IRQs (in the default case). This is a weak symbol in the common
+ * code and thus allows architectures to override it if more needs to be
+ * done. Not called for suspend to disk.
+ */
+extern void arch_suspend_enable_irqs(void);
+
+extern int pm_suspend(suspend_state_t state);
+#else /* !CONFIG_SUSPEND */
+#define suspend_valid_only_mem NULL
+
+static inline void suspend_set_ops(struct platform_suspend_ops *ops) {}
+static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
+#endif /* !CONFIG_SUSPEND */
/* struct pbe is used for creating lists of pages that should be restored
* atomically during the resume from disk, because the page frames they have
@@ -24,32 +126,57 @@ struct pbe {
extern void drain_local_pages(void);
extern void mark_free_pages(struct zone *zone);
-#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-#else
-static inline int pm_prepare_console(void) { return 0; }
-static inline void pm_restore_console(void) {}
-#endif
-
/**
- * struct hibernation_ops - hibernation platform support
+ * struct platform_hibernation_ops - hibernation platform support
*
* The methods in this structure allow a platform to override the default
* mechanism of shutting down the machine during a hibernation transition.
*
* All three methods must be assigned.
*
- * @prepare: prepare system for hibernation
- * @enter: shut down system after state has been saved to disk
- * @finish: finish/clean up after state has been reloaded
- * @pre_restore: prepare system for the restoration from a hibernation image
- * @restore_cleanup: clean up after a failing image restoration
+ * @start: Tell the platform driver that we're starting hibernation.
+ * Called right after shrinking memory and before freezing devices.
+ *
+ * @pre_snapshot: Prepare the platform for creating the hibernation image.
+ * Called right after devices have been frozen and before the nonboot
+ * CPUs are disabled (runs with IRQs on).
+ *
+ * @finish: Restore the previous state of the platform after the hibernation
+ * image has been created *or* put the platform into the normal operation
+ * mode after the hibernation (the same method is executed in both cases).
+ * Called right after the nonboot CPUs have been enabled and before
+ * thawing devices (runs with IRQs on).
+ *
+ * @prepare: Prepare the platform for entering the low power state.
+ * Called right after the hibernation image has been saved and before
+ * devices are prepared for entering the low power state.
+ *
+ * @enter: Put the system into the low power state after the hibernation image
+ * has been saved to disk.
+ * Called after the nonboot CPUs have been disabled and all of the low
+ * level devices have been shut down (runs with IRQs off).
+ *
+ * @leave: Perform the first stage of the cleanup after the system sleep state
+ * indicated by @set_target() has been left.
+ * Called right after the control has been passed from the boot kernel to
+ * the image kernel, before the nonboot CPUs are enabled and before devices
+ * are resumed. Executed with interrupts disabled.
+ *
+ * @pre_restore: Prepare system for the restoration from a hibernation image.
+ * Called right after devices have been frozen and before the nonboot
+ * CPUs are disabled (runs with IRQs on).
+ *
+ * @restore_cleanup: Clean up after a failing image restoration.
+ * Called right after the nonboot CPUs have been enabled and before
+ * thawing devices (runs with IRQs on).
*/
-struct hibernation_ops {
+struct platform_hibernation_ops {
+ int (*start)(void);
+ int (*pre_snapshot)(void);
+ void (*finish)(void);
int (*prepare)(void);
int (*enter)(void);
- void (*finish)(void);
+ void (*leave)(void);
int (*pre_restore)(void);
void (*restore_cleanup)(void);
};
@@ -70,14 +197,14 @@ extern void swsusp_set_page_free(struct page *);
extern void swsusp_unset_page_free(struct page *);
extern unsigned long get_safe_page(gfp_t gfp_mask);
-extern void hibernation_set_ops(struct hibernation_ops *ops);
+extern void hibernation_set_ops(struct platform_hibernation_ops *ops);
extern int hibernate(void);
#else /* CONFIG_HIBERNATION */
static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
static inline void swsusp_set_page_free(struct page *p) {}
static inline void swsusp_unset_page_free(struct page *p) {}
-static inline void hibernation_set_ops(struct hibernation_ops *ops) {}
+static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {}
static inline int hibernate(void) { return -ENOSYS; }
#endif /* CONFIG_HIBERNATION */
@@ -130,4 +257,4 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e)
}
#endif
-#endif /* _LINUX_SWSUSP_H */
+#endif /* _LINUX_SUSPEND_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index edf681a7fd8..4f3838adbb3 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -158,11 +158,6 @@ struct swap_list_t {
/* Swap 50% full? Release swapcache more aggressively.. */
#define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
-/* linux/mm/oom_kill.c */
-extern void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order);
-extern int register_oom_notifier(struct notifier_block *nb);
-extern int unregister_oom_notifier(struct notifier_block *nb);
-
/* linux/mm/memory.c */
extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct *);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 483050c924c..e99171f01b4 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -238,6 +238,7 @@ enum
NET_LLC=18,
NET_NETFILTER=19,
NET_DCCP=20,
+ NET_IRDA=412,
};
/* /proc/sys/kernel/random */
@@ -795,6 +796,25 @@ enum {
NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
};
+/* proc/sys/net/irda */
+enum {
+ NET_IRDA_DISCOVERY=1,
+ NET_IRDA_DEVNAME=2,
+ NET_IRDA_DEBUG=3,
+ NET_IRDA_FAST_POLL=4,
+ NET_IRDA_DISCOVERY_SLOTS=5,
+ NET_IRDA_DISCOVERY_TIMEOUT=6,
+ NET_IRDA_SLOT_TIMEOUT=7,
+ NET_IRDA_MAX_BAUD_RATE=8,
+ NET_IRDA_MIN_TX_TURN_TIME=9,
+ NET_IRDA_MAX_TX_DATA_SIZE=10,
+ NET_IRDA_MAX_TX_WINDOW=11,
+ NET_IRDA_MAX_NOREPLY_TIME=12,
+ NET_IRDA_WARN_NOREPLY_TIME=13,
+ NET_IRDA_LAP_KEEPALIVE_TIME=14,
+};
+
+
/* CTL_FS names: */
enum
{
@@ -937,41 +957,42 @@ extern int sysctl_perm(struct ctl_table *table, int op);
typedef struct ctl_table ctl_table;
-typedef int ctl_handler (ctl_table *table, int __user *name, int nlen,
+typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
-typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
+typedef int proc_handler (struct ctl_table *ctl, int write, struct file * filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
-extern int proc_dostring(ctl_table *, int, struct file *,
+extern int proc_dostring(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_dointvec(ctl_table *, int, struct file *,
+extern int proc_dointvec(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_dointvec_bset(ctl_table *, int, struct file *,
+extern int proc_dointvec_bset(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
+extern int proc_dointvec_minmax(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_dointvec_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_jiffies(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *,
+extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_doulongvec_minmax(ctl_table *, int, struct file *,
+extern int proc_doulongvec_minmax(struct ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int,
+extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int,
struct file *, void __user *, size_t *, loff_t *);
extern int do_sysctl (int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
-extern int do_sysctl_strategy (ctl_table *table,
+extern int do_sysctl_strategy (struct ctl_table *table,
int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
+extern ctl_handler sysctl_data;
extern ctl_handler sysctl_string;
extern ctl_handler sysctl_intvec;
extern ctl_handler sysctl_jiffies;
@@ -980,7 +1001,7 @@ extern ctl_handler sysctl_ms_jiffies;
/*
* Register a set of sysctl names by calling register_sysctl_table
- * with an initialised array of ctl_table's. An entry with zero
+ * with an initialised array of struct ctl_table's. An entry with zero
* ctl_name and NULL procname terminates the table. table->de will be
* set up by the registration and need not be initialised in advance.
*
@@ -1026,8 +1047,8 @@ struct ctl_table
void *data;
int maxlen;
mode_t mode;
- ctl_table *child;
- ctl_table *parent; /* Automatically set */
+ struct ctl_table *child;
+ struct ctl_table *parent; /* Automatically set */
proc_handler *proc_handler; /* Callback for text formatting */
ctl_handler *strategy; /* Callback function for all r/w */
void *extra1;
@@ -1035,18 +1056,19 @@ struct ctl_table
};
/* struct ctl_table_header is used to maintain dynamic lists of
- ctl_table trees. */
+ struct ctl_table trees. */
struct ctl_table_header
{
- ctl_table *ctl_table;
+ struct ctl_table *ctl_table;
struct list_head ctl_entry;
int used;
struct completion *unregistering;
};
-struct ctl_table_header * register_sysctl_table(ctl_table * table);
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
void unregister_sysctl_table(struct ctl_table_header * table);
+int sysctl_check_table(struct ctl_table *table);
#else /* __KERNEL__ */
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h
index dce1ed20497..5d69c0744ff 100644
--- a/include/linux/taskstats.h
+++ b/include/linux/taskstats.h
@@ -31,7 +31,7 @@
*/
-#define TASKSTATS_VERSION 5
+#define TASKSTATS_VERSION 6
#define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN
* in linux/sched.h */
@@ -152,6 +152,11 @@ struct taskstats {
__u64 nvcsw; /* voluntary_ctxt_switches */
__u64 nivcsw; /* nonvoluntary_ctxt_switches */
+
+ /* time accounting for SMT machines */
+ __u64 ac_utimescaled; /* utime scaled on frequency etc */
+ __u64 ac_stimescaled; /* stime scaled on frequency etc */
+ __u64 cpu_scaled_run_real_total; /* scaled cpu_run_real_total */
};
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index c5b94c1a5ee..bac17c59b24 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -315,7 +315,7 @@ struct tcp_sock {
*/
u32 snd_ssthresh; /* Slow start size threshold */
u32 snd_cwnd; /* Sending congestion window */
- u16 snd_cwnd_cnt; /* Linear increase counter */
+ u32 snd_cwnd_cnt; /* Linear increase counter */
u32 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */
u32 snd_cwnd_used;
u32 snd_cwnd_stamp;
diff --git a/include/linux/time.h b/include/linux/time.h
index 6a5f503b4f1..b04136d60a2 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -92,7 +92,7 @@ static inline struct timespec timespec_sub(struct timespec lhs,
extern struct timespec xtime;
extern struct timespec wall_to_monotonic;
-extern seqlock_t xtime_lock __attribute__((weak));
+extern seqlock_t xtime_lock;
extern unsigned long read_persistent_clock(void);
extern int update_persistent_clock(struct timespec now);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 60478f6e5dc..56164d7ba0a 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -81,11 +81,6 @@ struct tty_bufhead {
int memory_used; /* Buffer space used excluding free queue */
};
/*
- * The pty uses char_buf and flag_buf as a contiguous buffer
- */
-#define PTY_BUF_SIZE 4*TTY_FLIPBUF_SIZE
-
-/*
* When a break, frame error, or parity error happens, these codes are
* stuffed into the flags buffer.
*/
@@ -321,6 +316,9 @@ extern void tty_flip_buffer_push(struct tty_struct *tty);
extern speed_t tty_get_baud_rate(struct tty_struct *tty);
extern speed_t tty_termios_baud_rate(struct ktermios *termios);
extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
+extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud);
+extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud);
+extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old);
extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
extern void tty_ldisc_deref(struct tty_ldisc *);
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index daeba22b765..10b854d3561 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -46,11 +46,6 @@ typedef __u32 __bitwise __fs32;
typedef __u16 __bitwise __fs16;
#endif
-#ifdef __KERNEL__
-#include <linux/ufs_fs_i.h>
-#include <linux/ufs_fs_sb.h>
-#endif
-
#define UFS_BBLOCK 0
#define UFS_BBSIZE 8192
#define UFS_SBLOCK 8192
@@ -170,8 +165,9 @@ typedef __u16 __bitwise __fs16;
#define UFS_ST_MASK 0x00000700 /* mask for the following */
#define UFS_ST_OLD 0x00000000
#define UFS_ST_44BSD 0x00000100
-#define UFS_ST_SUN 0x00000200
-#define UFS_ST_SUNx86 0x00000400
+#define UFS_ST_SUN 0x00000200 /* Solaris */
+#define UFS_ST_SUNOS 0x00000300
+#define UFS_ST_SUNx86 0x00000400 /* Solaris x86 */
/*cylinder group encoding */
#define UFS_CG_MASK 0x00003000 /* mask for the following */
#define UFS_CG_OLD 0x00000000
@@ -187,28 +183,6 @@ typedef __u16 __bitwise __fs16;
#define UFS_42INODEFMT -1
#define UFS_44INODEFMT 2
-/* mount options */
-#define UFS_MOUNT_ONERROR 0x0000000F
-#define UFS_MOUNT_ONERROR_PANIC 0x00000001
-#define UFS_MOUNT_ONERROR_LOCK 0x00000002
-#define UFS_MOUNT_ONERROR_UMOUNT 0x00000004
-#define UFS_MOUNT_ONERROR_REPAIR 0x00000008
-
-#define UFS_MOUNT_UFSTYPE 0x0000FFF0
-#define UFS_MOUNT_UFSTYPE_OLD 0x00000010
-#define UFS_MOUNT_UFSTYPE_44BSD 0x00000020
-#define UFS_MOUNT_UFSTYPE_SUN 0x00000040
-#define UFS_MOUNT_UFSTYPE_NEXTSTEP 0x00000080
-#define UFS_MOUNT_UFSTYPE_NEXTSTEP_CD 0x00000100
-#define UFS_MOUNT_UFSTYPE_OPENSTEP 0x00000200
-#define UFS_MOUNT_UFSTYPE_SUNx86 0x00000400
-#define UFS_MOUNT_UFSTYPE_HP 0x00000800
-#define UFS_MOUNT_UFSTYPE_UFS2 0x00001000
-
-#define ufs_clear_opt(o,opt) o &= ~UFS_MOUNT_##opt
-#define ufs_set_opt(o,opt) o |= UFS_MOUNT_##opt
-#define ufs_test_opt(o,opt) ((o) & UFS_MOUNT_##opt)
-
/*
* MINFREE gives the minimum acceptable percentage of file system
* blocks which may be free. If the freelist drops below this level
@@ -223,19 +197,6 @@ typedef __u16 __bitwise __fs16;
*/
#define UFS_MINFREE 5
#define UFS_DEFAULTOPT UFS_OPTTIME
-
-/*
- * Debug code
- */
-#ifdef CONFIG_UFS_DEBUG
-# define UFSD(f, a...) { \
- printk ("UFSD (%s, %d): %s:", \
- __FILE__, __LINE__, __FUNCTION__); \
- printk (f, ## a); \
- }
-#else
-# define UFSD(f, a...) /**/
-#endif
/*
* Turn file system block numbers into disk block addresses.
@@ -374,7 +335,14 @@ struct ufs_csum_core {
* struct ufs_super_block_(first,second,third) instead.
*/
struct ufs_super_block {
- __fs32 fs_link; /* UNUSED */
+ union {
+ struct {
+ __fs32 fs_link; /* UNUSED */
+ } fs_42;
+ struct {
+ __fs32 fs_state; /* file system state flag */
+ } fs_sun;
+ } fs_u0;
__fs32 fs_rlink; /* UNUSED */
__fs32 fs_sblkno; /* addr of super-block in filesys */
__fs32 fs_cblkno; /* offset of cyl-block in filesys */
@@ -545,6 +513,15 @@ struct ufs_super_block {
#define CG_MAGIC 0x090255
#define ufs_cg_chkmagic(sb, ucg) \
(fs32_to_cpu((sb), (ucg)->cg_magic) == CG_MAGIC)
+/*
+ * Macros for access to old cylinder group array structures
+ */
+#define ufs_ocg_blktot(sb, ucg) fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_btot)
+#define ufs_ocg_blks(sb, ucg, cylno) fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_b[cylno])
+#define ufs_ocg_inosused(sb, ucg) fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_iused)
+#define ufs_ocg_blksfree(sb, ucg) fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_free)
+#define ufs_ocg_chkmagic(sb, ucg) \
+ (fs32_to_cpu((sb), ((struct ufs_old_cylinder_group *)(ucg))->cg_magic) == CG_MAGIC)
/*
* size of this structure is 172 B
@@ -590,6 +567,28 @@ struct ufs_cylinder_group {
/* actually longer */
};
+/* Historic Cylinder group info */
+struct ufs_old_cylinder_group {
+ __fs32 cg_link; /* linked list of cyl groups */
+ __fs32 cg_rlink; /* for incore cyl groups */
+ __fs32 cg_time; /* time last written */
+ __fs32 cg_cgx; /* we are the cgx'th cylinder group */
+ __fs16 cg_ncyl; /* number of cyl's this cg */
+ __fs16 cg_niblk; /* number of inode blocks this cg */
+ __fs32 cg_ndblk; /* number of data blocks this cg */
+ struct ufs_csum cg_cs; /* cylinder summary information */
+ __fs32 cg_rotor; /* position of last used block */
+ __fs32 cg_frotor; /* position of last used frag */
+ __fs32 cg_irotor; /* position of last used inode */
+ __fs32 cg_frsum[8]; /* counts of available frags */
+ __fs32 cg_btot[32]; /* block totals per cylinder */
+ __fs16 cg_b[32][8]; /* positions of free blocks */
+ __u8 cg_iused[256]; /* used inode map */
+ __fs32 cg_magic; /* magic number */
+ __u8 cg_free[1]; /* free block map */
+/* actually longer */
+};
+
/*
* structure of an on-disk inode
*/
@@ -796,7 +795,14 @@ struct ufs_sb_private_info {
* ufs_super_block_third 356
*/
struct ufs_super_block_first {
- __fs32 fs_link;
+ union {
+ struct {
+ __fs32 fs_link; /* UNUSED */
+ } fs_42;
+ struct {
+ __fs32 fs_state; /* file system state flag */
+ } fs_sun;
+ } fs_u0;
__fs32 fs_rlink;
__fs32 fs_sblkno;
__fs32 fs_cblkno;
@@ -944,89 +950,4 @@ struct ufs_super_block_third {
__u8 fs_space[1];
};
-#ifdef __KERNEL__
-
-/* balloc.c */
-extern void ufs_free_fragments (struct inode *, u64, unsigned);
-extern void ufs_free_blocks (struct inode *, u64, unsigned);
-extern u64 ufs_new_fragments(struct inode *, void *, u64, u64,
- unsigned, int *, struct page *);
-
-/* cylinder.c */
-extern struct ufs_cg_private_info * ufs_load_cylinder (struct super_block *, unsigned);
-extern void ufs_put_cylinder (struct super_block *, unsigned);
-
-/* dir.c */
-extern const struct inode_operations ufs_dir_inode_operations;
-extern int ufs_add_link (struct dentry *, struct inode *);
-extern ino_t ufs_inode_by_name(struct inode *, struct dentry *);
-extern int ufs_make_empty(struct inode *, struct inode *);
-extern struct ufs_dir_entry *ufs_find_entry(struct inode *, struct dentry *, struct page **);
-extern int ufs_delete_entry(struct inode *, struct ufs_dir_entry *, struct page *);
-extern int ufs_empty_dir (struct inode *);
-extern struct ufs_dir_entry *ufs_dotdot(struct inode *, struct page **);
-extern void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
- struct page *page, struct inode *inode);
-
-/* file.c */
-extern const struct inode_operations ufs_file_inode_operations;
-extern const struct file_operations ufs_file_operations;
-
-extern const struct address_space_operations ufs_aops;
-
-/* ialloc.c */
-extern void ufs_free_inode (struct inode *inode);
-extern struct inode * ufs_new_inode (struct inode *, int);
-
-/* inode.c */
-extern void ufs_read_inode (struct inode *);
-extern void ufs_put_inode (struct inode *);
-extern int ufs_write_inode (struct inode *, int);
-extern int ufs_sync_inode (struct inode *);
-extern void ufs_delete_inode (struct inode *);
-extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
-extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create);
-
-/* namei.c */
-extern const struct file_operations ufs_dir_operations;
-
-/* super.c */
-extern void ufs_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
-extern void ufs_error (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
-extern void ufs_panic (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4)));
-
-/* symlink.c */
-extern const struct inode_operations ufs_fast_symlink_inode_operations;
-
-/* truncate.c */
-extern int ufs_truncate (struct inode *, loff_t);
-
-static inline struct ufs_sb_info *UFS_SB(struct super_block *sb)
-{
- return sb->s_fs_info;
-}
-
-static inline struct ufs_inode_info *UFS_I(struct inode *inode)
-{
- return container_of(inode, struct ufs_inode_info, vfs_inode);
-}
-
-/*
- * Give cylinder group number for a file system block.
- * Give cylinder group block number for a file system block.
- */
-/* #define ufs_dtog(d) ((d) / uspi->s_fpg) */
-static inline u64 ufs_dtog(struct ufs_sb_private_info * uspi, u64 b)
-{
- do_div(b, uspi->s_fpg);
- return b;
-}
-/* #define ufs_dtogd(d) ((d) % uspi->s_fpg) */
-static inline u32 ufs_dtogd(struct ufs_sb_private_info * uspi, u64 b)
-{
- return do_div(b, uspi->s_fpg);
-}
-
-#endif /* __KERNEL__ */
-
#endif /* __LINUX_UFS_FS_H */
diff --git a/include/linux/ufs_fs_i.h b/include/linux/ufs_fs_i.h
deleted file mode 100644
index 6496caa82f9..00000000000
--- a/include/linux/ufs_fs_i.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * linux/include/linux/ufs_fs_i.h
- *
- * Copyright (C) 1996
- * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
- * Laboratory for Computer Science Research Computing Facility
- * Rutgers, The State University of New Jersey
- *
- * NeXTstep support added on February 5th 1998 by
- * Niels Kristian Bech Jensen <nkbj@image.dk>.
- */
-
-#ifndef _LINUX_UFS_FS_I_H
-#define _LINUX_UFS_FS_I_H
-
-struct ufs_inode_info {
- union {
- __fs32 i_data[15];
- __u8 i_symlink[4*15];
- __fs64 u2_i_data[15];
- } i_u1;
- __u32 i_flags;
- __u32 i_shadow;
- __u32 i_unused1;
- __u32 i_unused2;
- __u32 i_oeftflag;
- __u16 i_osync;
- __u64 i_lastfrag;
- __u32 i_dir_start_lookup;
- struct inode vfs_inode;
-};
-
-#endif /* _LINUX_UFS_FS_I_H */
diff --git a/include/linux/ufs_fs_sb.h b/include/linux/ufs_fs_sb.h
deleted file mode 100644
index e114c93fc57..00000000000
--- a/include/linux/ufs_fs_sb.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/include/linux/ufs_fs_sb.h
- *
- * Copyright (C) 1996
- * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
- * Laboratory for Computer Science Research Computing Facility
- * Rutgers, The State University of New Jersey
- *
- * $Id: ufs_fs_sb.h,v 1.8 1998/05/06 12:04:40 jj Exp $
- *
- * Write support by Daniel Pirkl <daniel.pirkl@email.cz>
- */
-
-#ifndef __LINUX_UFS_FS_SB_H
-#define __LINUX_UFS_FS_SB_H
-
-
-#define UFS_MAX_GROUP_LOADED 8
-#define UFS_CGNO_EMPTY ((unsigned)-1)
-
-struct ufs_sb_private_info;
-struct ufs_cg_private_info;
-struct ufs_csum;
-
-struct ufs_sb_info {
- struct ufs_sb_private_info * s_uspi;
- struct ufs_csum * s_csp;
- unsigned s_bytesex;
- unsigned s_flags;
- struct buffer_head ** s_ucg;
- struct ufs_cg_private_info * s_ucpi[UFS_MAX_GROUP_LOADED];
- unsigned s_cgno[UFS_MAX_GROUP_LOADED];
- unsigned short s_cg_loaded;
- unsigned s_mount_opt;
-};
-
-#endif
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 46705e91573..c1527c2ef3c 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -481,7 +481,7 @@ static inline void *get_gadget_data (struct usb_gadget *gadget)
/**
* gadget_is_dualspeed - return true iff the hardware handles high speed
- * @gadget: controller that might support both high and full speeds
+ * @g: controller that might support both high and full speeds
*/
static inline int gadget_is_dualspeed(struct usb_gadget *g)
{
@@ -497,7 +497,7 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g)
/**
* gadget_is_otg - return true iff the hardware is OTG-ready
- * @gadget: controller that might have a Mini-AB connector
+ * @g: controller that might have a Mini-AB connector
*
* This is a runtime test, since kernels with a USB-OTG stack sometimes
* run on boards which only have a Mini-B (or Mini-A) connector.
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 699b7e9864f..feb5e99a107 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -87,6 +87,7 @@ extern int unbind_con_driver(const struct consw *csw, int first, int last,
extern char con_buf[CON_BUF_SIZE];
extern struct mutex con_buf_mtx;
extern char vt_dont_switch;
+extern int default_utf8;
struct vt_spawn_console {
spinlock_t lock;
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index c7c3337c3a8..bef7d66601c 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -62,15 +62,13 @@ struct writeback_control {
unsigned for_reclaim:1; /* Invoked from the page allocator */
unsigned for_writepages:1; /* This is a writepages() call */
unsigned range_cyclic:1; /* range_start is cyclic */
-
- void *fs_private; /* For use by ->writepages() */
+ unsigned more_io:1; /* more io to be dispatched */
};
/*
* fs/fs-writeback.c
*/
void writeback_inodes(struct writeback_control *wbc);
-void wake_up_inode(struct inode *inode);
int inode_wait(void *);
void sync_inodes_sb(struct super_block *, int wait);
void sync_inodes(int wait);
@@ -82,6 +80,13 @@ static inline void wait_on_inode(struct inode *inode)
wait_on_bit(&inode->i_state, __I_LOCK, inode_wait,
TASK_UNINTERRUPTIBLE);
}
+static inline void inode_sync_wait(struct inode *inode)
+{
+ might_sleep();
+ wait_on_bit(&inode->i_state, __I_SYNC, inode_wait,
+ TASK_UNINTERRUPTIBLE);
+}
+
/*
* mm/page-writeback.c
@@ -99,6 +104,10 @@ extern int dirty_expire_interval;
extern int block_dump;
extern int laptop_mode;
+extern int dirty_ratio_handler(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer, size_t *lenp,
+ loff_t *ppos);
+
struct ctl_table;
struct file;
int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 7726ff41c3e..686425a97b0 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -216,6 +216,7 @@ struct p9_tauth {
u32 afid;
struct p9_str uname;
struct p9_str aname;
+ u32 n_uname; /* 9P2000.u extensions */
};
struct p9_rauth {
@@ -239,6 +240,7 @@ struct p9_tattach {
u32 afid;
struct p9_str uname;
struct p9_str aname;
+ u32 n_uname; /* 9P2000.u extensions */
};
struct p9_rattach {
@@ -382,8 +384,9 @@ int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu);
void p9_set_tag(struct p9_fcall *fc, u16 tag);
struct p9_fcall *p9_create_tversion(u32 msize, char *version);
struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname,
- char *aname);
-struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname);
+ char *aname, u32 n_uname, int dotu);
+struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
+ u32 n_uname, int dotu);
struct p9_fcall *p9_create_tflush(u16 oldtag);
struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
char **wnames);
@@ -412,18 +415,4 @@ int p9_idpool_check(int id, struct p9_idpool *p);
int p9_error_init(void);
int p9_errstr2errno(char *, int);
-
-#ifdef CONFIG_SYSCTL
-int __init p9_sysctl_register(void);
-void __exit p9_sysctl_unregister(void);
-#else
-static inline int p9_sysctl_register(void)
-{
- return 0;
-}
-static inline void p9_sysctl_unregister(void)
-{
-}
-#endif
-
#endif /* NET_9P_H */
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index d65ed7c6906..9b9221a2139 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -29,7 +29,7 @@ struct p9_client {
spinlock_t lock; /* protect client structure */
int msize;
unsigned char dotu;
- struct p9_transport *trans;
+ struct p9_trans *trans;
struct p9_conn *conn;
struct p9_idpool *fidpool;
@@ -52,13 +52,14 @@ struct p9_fid {
struct list_head dlist; /* list of all fids attached to a dentry */
};
-struct p9_client *p9_client_create(struct p9_transport *trans, int msize,
+struct p9_client *p9_client_create(struct p9_trans *trans, int msize,
int dotu);
void p9_client_destroy(struct p9_client *clnt);
void p9_client_disconnect(struct p9_client *clnt);
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
- char *uname, char *aname);
-struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname);
+ char *uname, u32 n_uname, char *aname);
+struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
+ u32 n_uname, char *aname);
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
int clone);
int p9_client_open(struct p9_fid *fid, int mode);
diff --git a/include/net/9p/conn.h b/include/net/9p/conn.h
index 583b6a2cb3d..756d8784f95 100644
--- a/include/net/9p/conn.h
+++ b/include/net/9p/conn.h
@@ -42,8 +42,8 @@ struct p9_req;
*/
typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
-struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize,
- unsigned char *dotu);
+struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize,
+ unsigned char *dotu);
void p9_conn_destroy(struct p9_conn *);
int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc);
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
index 462d42279fb..9dd4a05619a 100644
--- a/include/net/9p/transport.h
+++ b/include/net/9p/transport.h
@@ -26,24 +26,31 @@
#ifndef NET_9P_TRANSPORT_H
#define NET_9P_TRANSPORT_H
-enum p9_transport_status {
+enum p9_trans_status {
Connected,
Disconnected,
Hung,
};
-struct p9_transport {
- enum p9_transport_status status;
+struct p9_trans {
+ enum p9_trans_status status;
void *priv;
+ int (*write) (struct p9_trans *, void *, int);
+ int (*read) (struct p9_trans *, void *, int);
+ void (*close) (struct p9_trans *);
+ unsigned int (*poll)(struct p9_trans *, struct poll_table_struct *);
+};
- int (*write) (struct p9_transport *, void *, int);
- int (*read) (struct p9_transport *, void *, int);
- void (*close) (struct p9_transport *);
- unsigned int (*poll)(struct p9_transport *, struct poll_table_struct *);
+struct p9_trans_module {
+ struct list_head list;
+ char *name; /* name of transport */
+ int maxsize; /* max message size of transport */
+ int def; /* this transport should be default */
+ struct p9_trans * (*create)(const char *devname, char *options);
};
-struct p9_transport *p9_trans_create_tcp(const char *addr, int port);
-struct p9_transport *p9_trans_create_unix(const char *addr);
-struct p9_transport *p9_trans_create_fd(int rfd, int wfd);
+void v9fs_register_trans(struct p9_trans_module *m);
+struct p9_trans_module *v9fs_match_trans(const substring_t *name);
+struct p9_trans_module *v9fs_default_trans(void);
#endif /* NET_9P_TRANSPORT_H */
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
new file mode 100644
index 00000000000..954def40897
--- /dev/null
+++ b/include/net/inet_frag.h
@@ -0,0 +1,67 @@
+#ifndef __NET_FRAG_H__
+#define __NET_FRAG_H__
+
+struct inet_frag_queue {
+ struct hlist_node list;
+ struct list_head lru_list; /* lru list member */
+ spinlock_t lock;
+ atomic_t refcnt;
+ struct timer_list timer; /* when will this queue expire? */
+ struct sk_buff *fragments; /* list of received fragments */
+ ktime_t stamp;
+ int len; /* total length of orig datagram */
+ int meat;
+ __u8 last_in; /* first/last segment arrived? */
+
+#define COMPLETE 4
+#define FIRST_IN 2
+#define LAST_IN 1
+};
+
+#define INETFRAGS_HASHSZ 64
+
+struct inet_frags_ctl {
+ int high_thresh;
+ int low_thresh;
+ int timeout;
+ int secret_interval;
+};
+
+struct inet_frags {
+ struct list_head lru_list;
+ struct hlist_head hash[INETFRAGS_HASHSZ];
+ rwlock_t lock;
+ u32 rnd;
+ int nqueues;
+ int qsize;
+ atomic_t mem;
+ struct timer_list secret_timer;
+ struct inet_frags_ctl *ctl;
+
+ unsigned int (*hashfn)(struct inet_frag_queue *);
+ void (*constructor)(struct inet_frag_queue *q,
+ void *arg);
+ void (*destructor)(struct inet_frag_queue *);
+ void (*skb_free)(struct sk_buff *);
+ int (*match)(struct inet_frag_queue *q,
+ void *arg);
+ void (*frag_expire)(unsigned long data);
+};
+
+void inet_frags_init(struct inet_frags *);
+void inet_frags_fini(struct inet_frags *);
+
+void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
+void inet_frag_destroy(struct inet_frag_queue *q,
+ struct inet_frags *f, int *work);
+int inet_frag_evictor(struct inet_frags *f);
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+ unsigned int hash);
+
+static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
+{
+ if (atomic_dec_and_test(&q->refcnt))
+ inet_frag_destroy(q, f, NULL);
+}
+
+#endif
diff --git a/include/net/ip.h b/include/net/ip.h
index 3af3ed9d320..840dd91b513 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -160,6 +160,7 @@ DECLARE_SNMP_STAT(struct ipstats_mib, ip_statistics);
#define IP_INC_STATS(field) SNMP_INC_STATS(ip_statistics, field)
#define IP_INC_STATS_BH(field) SNMP_INC_STATS_BH(ip_statistics, field)
#define IP_INC_STATS_USER(field) SNMP_INC_STATS_USER(ip_statistics, field)
+#define IP_ADD_STATS_BH(field, val) SNMP_ADD_STATS_BH(ip_statistics, field, val)
DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
#define NET_INC_STATS(field) SNMP_INC_STATS(net_statistics, field)
#define NET_INC_STATS_BH(field) SNMP_INC_STATS_BH(net_statistics, field)
@@ -177,10 +178,8 @@ extern int sysctl_ip_default_ttl;
extern int sysctl_ip_nonlocal_bind;
/* From ip_fragment.c */
-extern int sysctl_ipfrag_high_thresh;
-extern int sysctl_ipfrag_low_thresh;
-extern int sysctl_ipfrag_time;
-extern int sysctl_ipfrag_secret_interval;
+struct inet_frags_ctl;
+extern struct inet_frags_ctl ip4_frags_ctl;
extern int sysctl_ipfrag_max_dist;
/* From inetpeer.c */
@@ -332,9 +331,9 @@ enum ip_defrag_users
IP_DEFRAG_VS_FWD
};
-struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user);
-extern int ip_frag_nqueues;
-extern atomic_t ip_frag_mem;
+int ip_defrag(struct sk_buff *skb, u32 user);
+int ip_frag_mem(void);
+int ip_frag_nqueues(void);
/*
* Functions provided by ip_forward.c
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 672564e5a81..41870564df8 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -464,10 +464,10 @@ struct ip_vs_protocol {
unsigned int proto_off,
int inverse);
- int (*snat_handler)(struct sk_buff **pskb,
+ int (*snat_handler)(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp);
- int (*dnat_handler)(struct sk_buff **pskb,
+ int (*dnat_handler)(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp);
int (*csum_check)(struct sk_buff *skb, struct ip_vs_protocol *pp);
@@ -654,11 +654,11 @@ struct ip_vs_app
/* output hook: return false if can't linearize. diff set for TCP. */
int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
- struct sk_buff **, int *diff);
+ struct sk_buff *, int *diff);
/* input hook: return false if can't linearize. diff set for TCP. */
int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,
- struct sk_buff **, int *diff);
+ struct sk_buff *, int *diff);
/* ip_vs_app initializer */
int (*init_conn)(struct ip_vs_app *, struct ip_vs_conn *);
@@ -832,8 +832,8 @@ register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port);
extern int ip_vs_app_inc_get(struct ip_vs_app *inc);
extern void ip_vs_app_inc_put(struct ip_vs_app *inc);
-extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff **pskb);
-extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff **pskb);
+extern int ip_vs_app_pkt_out(struct ip_vs_conn *, struct sk_buff *skb);
+extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb);
extern int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri,
char *o_buf, int o_len, char *n_buf, int n_len);
extern int ip_vs_app_init(void);
@@ -984,7 +984,6 @@ static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
return fwd;
}
-extern int ip_vs_make_skb_writable(struct sk_buff **pskb, int len);
extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_conn *cp, int dir);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 31b3f1b45a2..ae328b680ff 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -120,12 +120,21 @@ extern int sysctl_mld_max_msf;
SNMP_INC_STATS##modifier(statname##_statistics, (field)); \
})
+#define _DEVADD(statname, modifier, idev, field, val) \
+({ \
+ struct inet6_dev *_idev = (idev); \
+ if (likely(_idev != NULL)) \
+ SNMP_ADD_STATS##modifier((_idev)->stats.statname, (field), (val)); \
+ SNMP_ADD_STATS##modifier(statname##_statistics, (field), (val));\
+})
+
/* MIBs */
DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);
#define IP6_INC_STATS(idev,field) _DEVINC(ipv6, , idev, field)
#define IP6_INC_STATS_BH(idev,field) _DEVINC(ipv6, _BH, idev, field)
#define IP6_INC_STATS_USER(idev,field) _DEVINC(ipv6, _USER, idev, field)
+#define IP6_ADD_STATS_BH(idev,field,val) _DEVADD(ipv6, _BH, idev, field, val)
DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
@@ -240,7 +249,7 @@ extern int ip6_ra_control(struct sock *sk, int sel,
void (*destructor)(struct sock *));
-extern int ipv6_parse_hopopts(struct sk_buff **skbp);
+extern int ipv6_parse_hopopts(struct sk_buff *skb);
extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
@@ -252,8 +261,8 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
-extern int ip6_frag_nqueues;
-extern atomic_t ip6_frag_mem;
+int ip6_frag_nqueues(void);
+int ip6_frag_mem(void);
#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
@@ -368,6 +377,17 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
prefixlen);
}
+struct inet_frag_queue;
+
+struct ip6_create_arg {
+ __be32 id;
+ struct in6_addr *src;
+ struct in6_addr *dst;
+};
+
+void ip6_frag_init(struct inet_frag_queue *q, void *a);
+int ip6_frag_match(struct inet_frag_queue *q, void *a);
+
static inline int ipv6_addr_any(const struct in6_addr *a)
{
return ((a->s6_addr32[0] | a->s6_addr32[1] |
@@ -565,10 +585,8 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
/*
* reassembly.c
*/
-extern int sysctl_ip6frag_high_thresh;
-extern int sysctl_ip6frag_low_thresh;
-extern int sysctl_ip6frag_time;
-extern int sysctl_ip6frag_secret_interval;
+struct inet_frags_ctl;
+extern struct inet_frags_ctl ip6_frags_ctl;
extern const struct proto_ops inet6_stream_ops;
extern const struct proto_ops inet6_dgram_ops;
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index 070d12cb463..f703533fb4d 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -15,8 +15,7 @@ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
struct net_device *out,
int (*okfn)(struct sk_buff *));
-extern unsigned int nf_ct_frag6_timeout;
-extern unsigned int nf_ct_frag6_low_thresh;
-extern unsigned int nf_ct_frag6_high_thresh;
+struct inet_frags_ctl;
+extern struct inet_frags_ctl nf_frags_ctl;
#endif /* _NF_CONNTRACK_IPV6_H*/
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 4056f5f08da..a532e7b5ed6 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -22,7 +22,7 @@
of connection tracking. */
extern unsigned int nf_conntrack_in(int pf,
unsigned int hooknum,
- struct sk_buff **pskb);
+ struct sk_buff *skb);
extern int nf_conntrack_init(void);
extern void nf_conntrack_cleanup(void);
@@ -60,17 +60,17 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
extern struct nf_conntrack_tuple_hash *
nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple);
-extern int __nf_conntrack_confirm(struct sk_buff **pskb);
+extern int __nf_conntrack_confirm(struct sk_buff *skb);
/* Confirm a connection: returns NF_DROP if packet must be dropped. */
-static inline int nf_conntrack_confirm(struct sk_buff **pskb)
+static inline int nf_conntrack_confirm(struct sk_buff *skb)
{
- struct nf_conn *ct = (struct nf_conn *)(*pskb)->nfct;
+ struct nf_conn *ct = (struct nf_conn *)skb->nfct;
int ret = NF_ACCEPT;
if (ct) {
if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
- ret = __nf_conntrack_confirm(pskb);
+ ret = __nf_conntrack_confirm(skb);
nf_ct_deliver_cached_events(ct);
}
return ret;
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 0dcc4c828ce..d7b2d5483a7 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -29,7 +29,7 @@ struct nf_conntrack_helper
/* Function to call when data passes; return verdict, or -1 to
invalidate. */
- int (*help)(struct sk_buff **pskb,
+ int (*help)(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info conntrackinfo);
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h
index c3cd127ba4b..f29eeb9777e 100644
--- a/include/net/netfilter/nf_nat_core.h
+++ b/include/net/netfilter/nf_nat_core.h
@@ -10,12 +10,12 @@
extern unsigned int nf_nat_packet(struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum,
- struct sk_buff **pskb);
+ struct sk_buff *skb);
extern int nf_nat_icmp_reply_translation(struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum,
- struct sk_buff **pskb);
+ struct sk_buff *skb);
static inline int nf_nat_initialized(struct nf_conn *ct,
enum nf_nat_manip_type manip)
diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h
index ec98ecf95fc..58dd2268794 100644
--- a/include/net/netfilter/nf_nat_helper.h
+++ b/include/net/netfilter/nf_nat_helper.h
@@ -7,21 +7,21 @@
struct sk_buff;
/* These return true or false. */
-extern int nf_nat_mangle_tcp_packet(struct sk_buff **skb,
+extern int nf_nat_mangle_tcp_packet(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
const char *rep_buffer,
unsigned int rep_len);
-extern int nf_nat_mangle_udp_packet(struct sk_buff **skb,
+extern int nf_nat_mangle_udp_packet(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
const char *rep_buffer,
unsigned int rep_len);
-extern int nf_nat_seq_adjust(struct sk_buff **pskb,
+extern int nf_nat_seq_adjust(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo);
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h
index 14c7b2d7263..04578bfe23e 100644
--- a/include/net/netfilter/nf_nat_protocol.h
+++ b/include/net/netfilter/nf_nat_protocol.h
@@ -18,7 +18,7 @@ struct nf_nat_protocol
/* Translate a packet to the target according to manip type.
Return true if succeeded. */
- int (*manip_pkt)(struct sk_buff **pskb,
+ int (*manip_pkt)(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype);
diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h
index f9743187d57..75d1825031d 100644
--- a/include/net/netfilter/nf_nat_rule.h
+++ b/include/net/netfilter/nf_nat_rule.h
@@ -6,7 +6,7 @@
extern int nf_nat_rule_init(void) __init;
extern void nf_nat_rule_cleanup(void);
-extern int nf_nat_rule_find(struct sk_buff **pskb,
+extern int nf_nat_rule_find(struct sk_buff *skb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 105bf12b0c7..1166ffb4b3e 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -45,7 +45,7 @@ struct net_protocol {
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct inet6_protocol
{
- int (*handler)(struct sk_buff **skb);
+ int (*handler)(struct sk_buff *skb);
void (*err_handler)(struct sk_buff *skb,
struct inet6_skb_parm *opt,
diff --git a/include/net/sock.h b/include/net/sock.h
index 453c79d0915..43fc3fa50d6 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -905,16 +905,6 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
}
/**
- * sk_filter_rcu_free: Free a socket filter
- * @rcu: rcu_head that contains the sk_filter to free
- */
-static inline void sk_filter_rcu_free(struct rcu_head *rcu)
-{
- struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
- kfree(fp);
-}
-
-/**
* sk_filter_release: Release a socket filter
* @sk: socket
* @fp: filter to remove
@@ -922,14 +912,18 @@ static inline void sk_filter_rcu_free(struct rcu_head *rcu)
* Remove a filter from a socket and release its resources.
*/
-static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp)
+static inline void sk_filter_release(struct sk_filter *fp)
+{
+ if (atomic_dec_and_test(&fp->refcnt))
+ kfree(fp);
+}
+
+static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
{
unsigned int size = sk_filter_len(fp);
atomic_sub(size, &sk->sk_omem_alloc);
-
- if (atomic_dec_and_test(&fp->refcnt))
- call_rcu_bh(&fp->rcu, sk_filter_rcu_free);
+ sk_filter_release(fp);
}
static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 77be396ca63..688f6f5d328 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -186,7 +186,8 @@ struct xfrm_state
/* Reference to data common to all the instances of this
* transformer. */
struct xfrm_type *type;
- struct xfrm_mode *mode;
+ struct xfrm_mode *inner_mode;
+ struct xfrm_mode *outer_mode;
/* Security context */
struct xfrm_sec_ctx *security;
@@ -228,8 +229,6 @@ struct xfrm_type;
struct xfrm_dst;
struct xfrm_policy_afinfo {
unsigned short family;
- struct xfrm_type *type_map[IPPROTO_MAX];
- struct xfrm_mode *mode_map[XFRM_MODE_MAX];
struct dst_ops *dst_ops;
void (*garbage_collect)(void);
int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
@@ -255,7 +254,10 @@ extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
extern int __xfrm_state_delete(struct xfrm_state *x);
struct xfrm_state_afinfo {
- unsigned short family;
+ unsigned int family;
+ struct module *owner;
+ struct xfrm_type *type_map[IPPROTO_MAX];
+ struct xfrm_mode *mode_map[XFRM_MODE_MAX];
int (*init_flags)(struct xfrm_state *x);
void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
struct xfrm_tmpl *tmpl,
@@ -267,8 +269,6 @@ struct xfrm_state_afinfo {
extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
-extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
-extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
@@ -295,8 +295,6 @@ struct xfrm_type
extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
-extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family);
-extern void xfrm_put_type(struct xfrm_type *type);
struct xfrm_mode {
int (*input)(struct xfrm_state *x, struct sk_buff *skb);
@@ -314,14 +312,19 @@ struct xfrm_mode {
*/
int (*output)(struct xfrm_state *x,struct sk_buff *skb);
+ struct xfrm_state_afinfo *afinfo;
struct module *owner;
unsigned int encap;
+ int flags;
+};
+
+/* Flags for xfrm_mode. */
+enum {
+ XFRM_MODE_FLAG_TUNNEL = 1,
};
extern int xfrm_register_mode(struct xfrm_mode *mode, int family);
extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family);
-extern struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family);
-extern void xfrm_put_mode(struct xfrm_mode *mode);
struct xfrm_tmpl
{
@@ -1046,12 +1049,20 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
extern int xfrm_init_state(struct xfrm_state *x);
extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
+ int encap_type);
extern int xfrm4_rcv(struct sk_buff *skb);
+
+static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+{
+ return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
+}
+
extern int xfrm4_output(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
-extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi);
-extern int xfrm6_rcv(struct sk_buff **pskb);
+extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+extern int xfrm6_rcv(struct sk_buff *skb);
extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
xfrm_address_t *saddr, u8 proto);
extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family);
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 90ef552c42d..f047a1fd64f 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -184,6 +184,7 @@ struct pcmcia_device {
char * prod_id[4];
+ u64 dma_mask;
struct device dev;
#ifdef CONFIG_PCMCIA_IOCTL
diff --git a/include/scsi/Kbuild b/include/scsi/Kbuild
deleted file mode 100644
index 744f85011f1..00000000000
--- a/include/scsi/Kbuild
+++ /dev/null
@@ -1,4 +0,0 @@
-header-y += scsi.h
-
-unifdef-y += scsi_ioctl.h
-unifdef-y += sg.h
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 9f8f80ab0c8..702fcfeb37f 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -11,13 +11,6 @@
#include <linux/types.h>
/*
- * The maximum sg list length SCSI can cope with
- * (currently must be a power of 2 between 32 and 256)
- */
-#define SCSI_MAX_PHYS_SEGMENTS MAX_PHYS_SEGMENTS
-
-
-/*
* SCSI command lengths
*/
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 65ab5145a09..3f47e522a1e 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -5,6 +5,7 @@
#include <linux/list.h>
#include <linux/types.h>
#include <linux/timer.h>
+#include <linux/scatterlist.h>
struct request;
struct scatterlist;
@@ -68,7 +69,7 @@ struct scsi_cmnd {
/* These elements define the operation we ultimately want to perform */
unsigned short use_sg; /* Number of pieces of scatter-gather */
- unsigned short sglist_len; /* size of malloc'd scatter-gather list */
+ unsigned short __use_sg;
unsigned underflow; /* Return error if less than
this amount is transferred */
@@ -128,7 +129,7 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
extern void scsi_kunmap_atomic_sg(void *virt);
extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
-extern void scsi_free_sgtable(struct scatterlist *, int);
+extern void scsi_free_sgtable(struct scsi_cmnd *);
extern int scsi_dma_map(struct scsi_cmnd *cmd);
extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
@@ -148,6 +149,6 @@ static inline int scsi_get_resid(struct scsi_cmnd *cmd)
}
#define scsi_for_each_sg(cmd, sg, nseg, __i) \
- for (__i = 0, sg = scsi_sglist(cmd); __i < (nseg); __i++, (sg)++)
+ for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
#endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 7d210cd6c38..0fd4746ee39 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -39,6 +39,9 @@ struct blk_queue_tags;
#define DISABLE_CLUSTERING 0
#define ENABLE_CLUSTERING 1
+#define DISABLE_SG_CHAINING 0
+#define ENABLE_SG_CHAINING 1
+
enum scsi_eh_timer_return {
EH_NOT_HANDLED,
EH_HANDLED,
@@ -443,6 +446,15 @@ struct scsi_host_template {
unsigned ordered_tag:1;
/*
+ * true if the low-level driver can support sg chaining. this
+ * will be removed eventually when all the drivers are
+ * converted to support sg chaining.
+ *
+ * Status: OBSOLETE
+ */
+ unsigned use_sg_chaining:1;
+
+ /*
* Countdown for host blocking with no commands outstanding
*/
unsigned int max_host_blocked;
@@ -586,6 +598,7 @@ struct Scsi_Host {
unsigned unchecked_isa_dma:1;
unsigned use_clustering:1;
unsigned use_blk_tcq:1;
+ unsigned use_sg_chaining:1;
/*
* Host has requested that no further requests come through for the
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 246ac23534b..01480581f82 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -2,7 +2,7 @@
#define __SOUND_AC97_CODEC_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.1
@@ -345,9 +345,9 @@
#define AC97_ALC650_GPIO_STATUS 0x78
#define AC97_ALC650_CLOCK 0x7a
-/* specific - Yamaha YMF753 */
-#define AC97_YMF753_DIT_CTRL2 0x66 /* DIT Control 2 */
-#define AC97_YMF753_3D_MODE_SEL 0x68 /* 3D Mode Select */
+/* specific - Yamaha YMF7x3 */
+#define AC97_YMF7X3_DIT_CTRL 0x66 /* DIT Control (YMF743) / 2 (YMF753) */
+#define AC97_YMF7X3_3D_MODE_SEL 0x68 /* 3D Mode Select */
/* specific - C-Media */
#define AC97_CM9738_VENDOR_CTRL 0x5a
diff --git a/include/sound/ad1848.h b/include/sound/ad1848.h
index b2c3f00a9b3..d04f9e78c7c 100644
--- a/include/sound/ad1848.h
+++ b/include/sound/ad1848.h
@@ -2,7 +2,7 @@
#define __SOUND_AD1848_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Definitions for AD1847/AD1848/CS4248 chips
*
*
@@ -27,7 +27,7 @@
/* IO ports */
-#define AD1848P( codec, x ) ( (chip) -> port + c_d_c_AD1848##x )
+#define AD1848P( chip, x ) ( (chip) -> port + c_d_c_AD1848##x )
#define c_d_c_AD1848REGSEL 0
#define c_d_c_AD1848REG 1
@@ -154,7 +154,6 @@ struct snd_ad1848 {
#endif
spinlock_t reg_lock;
- struct mutex open_mutex;
};
/* exported functions */
diff --git a/include/sound/ainstr_gf1.h b/include/sound/ainstr_gf1.h
index 47726fe0f46..b62b665c69c 100644
--- a/include/sound/ainstr_gf1.h
+++ b/include/sound/ainstr_gf1.h
@@ -2,7 +2,7 @@
* Advanced Linux Sound Architecture
*
* GF1 (GUS) Patch Instrument Format
- * Copyright (c) 1994-99 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1994-99 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/ainstr_iw.h b/include/sound/ainstr_iw.h
index 251feaf1b38..11bd2508260 100644
--- a/include/sound/ainstr_iw.h
+++ b/include/sound/ainstr_iw.h
@@ -2,7 +2,7 @@
* Advanced Linux Sound Architecture
*
* InterWave FFFF Instrument Format
- * Copyright (c) 1994-99 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1994-99 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/ainstr_simple.h b/include/sound/ainstr_simple.h
index 5eead12e58a..da08e728755 100644
--- a/include/sound/ainstr_simple.h
+++ b/include/sound/ainstr_simple.h
@@ -2,7 +2,7 @@
* Advanced Linux Sound Architecture
*
* Simple (MOD player) Instrument Format
- * Copyright (c) 1994-99 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1994-99 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
index d647dae912b..4e80d3fe738 100644
--- a/include/sound/ak4114.h
+++ b/include/sound/ak4114.h
@@ -3,7 +3,7 @@
/*
* Routines for Asahi Kasei AK4114
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/ak4117.h b/include/sound/ak4117.h
index d650d52e3d2..1e8178171ba 100644
--- a/include/sound/ak4117.h
+++ b/include/sound/ak4117.h
@@ -3,7 +3,7 @@
/*
* Routines for Asahi Kasei AK4117
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h
index fb30faab43a..575296cf798 100644
--- a/include/sound/ak4531_codec.h
+++ b/include/sound/ak4531_codec.h
@@ -2,7 +2,7 @@
#define __SOUND_AK4531_CODEC_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.1
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h
index fd0a6c46f49..891cf1aea8b 100644
--- a/include/sound/ak4xxx-adda.h
+++ b/include/sound/ak4xxx-adda.h
@@ -5,7 +5,7 @@
* ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4381
* AD and DA converters
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/include/sound/asequencer.h b/include/sound/asequencer.h
index 3f2f4042a20..64daccbe8b2 100644
--- a/include/sound/asequencer.h
+++ b/include/sound/asequencer.h
@@ -1,7 +1,7 @@
/*
* Main header file for the ALSA sequencer
* Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- * (c) 1998-1999 by Jaroslav Kysela <perex@suse.cz>
+ * (c) 1998-1999 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/asound.h b/include/sound/asound.h
index c1621c650a9..af9d11d315e 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -1,6 +1,6 @@
/*
* Advanced Linux Sound Architecture - ALSA - Driver
- * Copyright (c) 1994-2003 by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) 1994-2003 by Jaroslav Kysela <perex@perex.cz>,
* Abramo Bagnara <abramo@alsa-project.org>
*
*
@@ -92,6 +92,7 @@ enum {
SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */
SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
+ SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
/* Don't forget to change the following: */
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC
diff --git a/include/sound/asound_fm.h b/include/sound/asound_fm.h
index 956fdc23c59..8fbcab7cc73 100644
--- a/include/sound/asound_fm.h
+++ b/include/sound/asound_fm.h
@@ -5,7 +5,7 @@
* Advanced Linux Sound Architecture - ALSA
*
* Interface file between ALSA driver & user space
- * Copyright (c) 1994-98 by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) 1994-98 by Jaroslav Kysela <perex@perex.cz>,
* 4Front Technologies
*
* Direct FM control
diff --git a/include/sound/asoundef.h b/include/sound/asoundef.h
index 58c9ef3d182..024ce62f7d1 100644
--- a/include/sound/asoundef.h
+++ b/include/sound/asoundef.h
@@ -3,7 +3,7 @@
/*
* Advanced Linux Sound Architecture - ALSA - Driver
- * Copyright (c) 1994-2000 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1994-2000 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/control.h b/include/sound/control.h
index 72e759f619b..e79baa63912 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -3,7 +3,7 @@
/*
* Header file for control interface
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -161,4 +161,12 @@ static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id
return dst_id;
}
+/*
+ * Frequently used control callbacks
+ */
+int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+
#endif /* __SOUND_CONTROL_H */
diff --git a/include/sound/core.h b/include/sound/core.h
index 4b9e609975a..6954836487e 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -3,7 +3,7 @@
/*
* Main header file for the ALSA driver
- * Copyright (c) 1994-2001 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1994-2001 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/cs4231-regs.h b/include/sound/cs4231-regs.h
new file mode 100644
index 00000000000..f1490265c9b
--- /dev/null
+++ b/include/sound/cs4231-regs.h
@@ -0,0 +1,180 @@
+#ifndef __SOUND_CS4231_REGS_H
+#define __SOUND_CS4231_REGS_H
+
+/*
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
+ * Definitions for CS4231 & InterWave chips & compatible chips registers
+ *
+ *
+ * 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
+ *
+ */
+
+/* IO ports */
+
+#define CS4231P(x) (c_d_c_CS4231##x)
+
+#define c_d_c_CS4231REGSEL 0
+#define c_d_c_CS4231REG 1
+#define c_d_c_CS4231STATUS 2
+#define c_d_c_CS4231PIO 3
+
+/* codec registers */
+
+#define CS4231_LEFT_INPUT 0x00 /* left input control */
+#define CS4231_RIGHT_INPUT 0x01 /* right input control */
+#define CS4231_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */
+#define CS4231_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */
+#define CS4231_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */
+#define CS4231_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */
+#define CS4231_LEFT_OUTPUT 0x06 /* left output control register */
+#define CS4231_RIGHT_OUTPUT 0x07 /* right output control register */
+#define CS4231_PLAYBK_FORMAT 0x08 /* clock and data format - playback - bits 7-0 MCE */
+#define CS4231_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */
+#define CS4231_PIN_CTRL 0x0a /* pin control */
+#define CS4231_TEST_INIT 0x0b /* test and initialization */
+#define CS4231_MISC_INFO 0x0c /* miscellaneaous information */
+#define CS4231_LOOPBACK 0x0d /* loopback control */
+#define CS4231_PLY_UPR_CNT 0x0e /* playback upper base count */
+#define CS4231_PLY_LWR_CNT 0x0f /* playback lower base count */
+#define CS4231_ALT_FEATURE_1 0x10 /* alternate #1 feature enable */
+#define AD1845_AF1_MIC_LEFT 0x10 /* alternate #1 feature + MIC left */
+#define CS4231_ALT_FEATURE_2 0x11 /* alternate #2 feature enable */
+#define AD1845_AF2_MIC_RIGHT 0x11 /* alternate #2 feature + MIC right */
+#define CS4231_LEFT_LINE_IN 0x12 /* left line input control */
+#define CS4231_RIGHT_LINE_IN 0x13 /* right line input control */
+#define CS4231_TIMER_LOW 0x14 /* timer low byte */
+#define CS4231_TIMER_HIGH 0x15 /* timer high byte */
+#define CS4231_LEFT_MIC_INPUT 0x16 /* left MIC input control register (InterWave only) */
+#define AD1845_UPR_FREQ_SEL 0x16 /* upper byte of frequency select */
+#define CS4231_RIGHT_MIC_INPUT 0x17 /* right MIC input control register (InterWave only) */
+#define AD1845_LWR_FREQ_SEL 0x17 /* lower byte of frequency select */
+#define CS4236_EXT_REG 0x17 /* extended register access */
+#define CS4231_IRQ_STATUS 0x18 /* irq status register */
+#define CS4231_LINE_LEFT_OUTPUT 0x19 /* left line output control register (InterWave only) */
+#define CS4231_VERSION 0x19 /* CS4231(A) - version values */
+#define CS4231_MONO_CTRL 0x1a /* mono input/output control */
+#define CS4231_LINE_RIGHT_OUTPUT 0x1b /* right line output control register (InterWave only) */
+#define AD1845_PWR_DOWN 0x1b /* power down control */
+#define CS4235_LEFT_MASTER 0x1b /* left master output control */
+#define CS4231_REC_FORMAT 0x1c /* clock and data format - record - bits 7-0 MCE */
+#define CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */
+#define AD1845_CLOCK 0x1d /* crystal clock select and total power down */
+#define CS4235_RIGHT_MASTER 0x1d /* right master output control */
+#define CS4231_REC_UPR_CNT 0x1e /* record upper count */
+#define CS4231_REC_LWR_CNT 0x1f /* record lower count */
+
+/* definitions for codec register select port - CODECP( REGSEL ) */
+
+#define CS4231_INIT 0x80 /* CODEC is initializing */
+#define CS4231_MCE 0x40 /* mode change enable */
+#define CS4231_TRD 0x20 /* transfer request disable */
+
+/* definitions for codec status register - CODECP( STATUS ) */
+
+#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
+
+/* definitions for codec irq status */
+
+#define CS4231_PLAYBACK_IRQ 0x10
+#define CS4231_RECORD_IRQ 0x20
+#define CS4231_TIMER_IRQ 0x40
+#define CS4231_ALL_IRQS 0x70
+#define CS4231_REC_UNDERRUN 0x08
+#define CS4231_REC_OVERRUN 0x04
+#define CS4231_PLY_OVERRUN 0x02
+#define CS4231_PLY_UNDERRUN 0x01
+
+/* definitions for CS4231_LEFT_INPUT and CS4231_RIGHT_INPUT registers */
+
+#define CS4231_ENABLE_MIC_GAIN 0x20
+
+#define CS4231_MIXS_LINE 0x00
+#define CS4231_MIXS_AUX1 0x40
+#define CS4231_MIXS_MIC 0x80
+#define CS4231_MIXS_ALL 0xc0
+
+/* definitions for clock and data format register - CS4231_PLAYBK_FORMAT */
+
+#define CS4231_LINEAR_8 0x00 /* 8-bit unsigned data */
+#define CS4231_ALAW_8 0x60 /* 8-bit A-law companded */
+#define CS4231_ULAW_8 0x20 /* 8-bit U-law companded */
+#define CS4231_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */
+#define CS4231_LINEAR_16_BIG 0xc0 /* 16-bit twos complement data - big endian */
+#define CS4231_ADPCM_16 0xa0 /* 16-bit ADPCM */
+#define CS4231_STEREO 0x10 /* stereo mode */
+/* bits 3-1 define frequency divisor */
+#define CS4231_XTAL1 0x00 /* 24.576 crystal */
+#define CS4231_XTAL2 0x01 /* 16.9344 crystal */
+
+/* definitions for interface control register - CS4231_IFACE_CTRL */
+
+#define CS4231_RECORD_PIO 0x80 /* record PIO enable */
+#define CS4231_PLAYBACK_PIO 0x40 /* playback PIO enable */
+#define CS4231_CALIB_MODE 0x18 /* calibration mode bits */
+#define CS4231_AUTOCALIB 0x08 /* auto calibrate */
+#define CS4231_SINGLE_DMA 0x04 /* use single DMA channel */
+#define CS4231_RECORD_ENABLE 0x02 /* record enable */
+#define CS4231_PLAYBACK_ENABLE 0x01 /* playback enable */
+
+/* definitions for pin control register - CS4231_PIN_CTRL */
+
+#define CS4231_IRQ_ENABLE 0x02 /* enable IRQ */
+#define CS4231_XCTL1 0x40 /* external control #1 */
+#define CS4231_XCTL0 0x80 /* external control #0 */
+
+/* definitions for test and init register - CS4231_TEST_INIT */
+
+#define CS4231_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */
+#define CS4231_DMA_REQUEST 0x10 /* DMA request in progress */
+
+/* definitions for misc control register - CS4231_MISC_INFO */
+
+#define CS4231_MODE2 0x40 /* MODE 2 */
+#define CS4231_IW_MODE3 0x6c /* MODE 3 - InterWave enhanced mode */
+#define CS4231_4236_MODE3 0xe0 /* MODE 3 - CS4236+ enhanced mode */
+
+/* definitions for alternate feature 1 register - CS4231_ALT_FEATURE_1 */
+
+#define CS4231_DACZ 0x01 /* zero DAC when underrun */
+#define CS4231_TIMER_ENABLE 0x40 /* codec timer enable */
+#define CS4231_OLB 0x80 /* output level bit */
+
+/* definitions for Extended Registers - CS4236+ */
+
+#define CS4236_REG(i23val) (((i23val << 2) & 0x10) | ((i23val >> 4) & 0x0f))
+#define CS4236_I23VAL(reg) ((((reg)&0xf) << 4) | (((reg)&0x10) >> 2) | 0x8)
+
+#define CS4236_LEFT_LINE 0x08 /* left LINE alternate volume */
+#define CS4236_RIGHT_LINE 0x18 /* right LINE alternate volume */
+#define CS4236_LEFT_MIC 0x28 /* left MIC volume */
+#define CS4236_RIGHT_MIC 0x38 /* right MIC volume */
+#define CS4236_LEFT_MIX_CTRL 0x48 /* synthesis and left input mixer control */
+#define CS4236_RIGHT_MIX_CTRL 0x58 /* right input mixer control */
+#define CS4236_LEFT_FM 0x68 /* left FM volume */
+#define CS4236_RIGHT_FM 0x78 /* right FM volume */
+#define CS4236_LEFT_DSP 0x88 /* left DSP serial port volume */
+#define CS4236_RIGHT_DSP 0x98 /* right DSP serial port volume */
+#define CS4236_RIGHT_LOOPBACK 0xa8 /* right loopback monitor volume */
+#define CS4236_DAC_MUTE 0xb8 /* DAC mute and IFSE enable */
+#define CS4236_ADC_RATE 0xc8 /* indenpendent ADC sample frequency */
+#define CS4236_DAC_RATE 0xd8 /* indenpendent DAC sample frequency */
+#define CS4236_LEFT_MASTER 0xe8 /* left master digital audio volume */
+#define CS4236_RIGHT_MASTER 0xf8 /* right master digital audio volume */
+#define CS4236_LEFT_WAVE 0x0c /* left wavetable serial port volume */
+#define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */
+#define CS4236_VERSION 0x9c /* chip version and ID */
+
+#endif /* __SOUND_CS4231_REGS_H */
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h
index ab51ce1ba9a..66055d702aa 100644
--- a/include/sound/cs4231.h
+++ b/include/sound/cs4231.h
@@ -2,7 +2,7 @@
#define __SOUND_CS4231_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Definitions for CS4231 & InterWave chips & compatible chips
*
*
@@ -26,160 +26,7 @@
#include "pcm.h"
#include "timer.h"
-/* IO ports */
-
-#define CS4231P(x) (c_d_c_CS4231##x)
-
-#define c_d_c_CS4231REGSEL 0
-#define c_d_c_CS4231REG 1
-#define c_d_c_CS4231STATUS 2
-#define c_d_c_CS4231PIO 3
-
-/* codec registers */
-
-#define CS4231_LEFT_INPUT 0x00 /* left input control */
-#define CS4231_RIGHT_INPUT 0x01 /* right input control */
-#define CS4231_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */
-#define CS4231_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */
-#define CS4231_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */
-#define CS4231_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */
-#define CS4231_LEFT_OUTPUT 0x06 /* left output control register */
-#define CS4231_RIGHT_OUTPUT 0x07 /* right output control register */
-#define CS4231_PLAYBK_FORMAT 0x08 /* clock and data format - playback - bits 7-0 MCE */
-#define CS4231_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */
-#define CS4231_PIN_CTRL 0x0a /* pin control */
-#define CS4231_TEST_INIT 0x0b /* test and initialization */
-#define CS4231_MISC_INFO 0x0c /* miscellaneaous information */
-#define CS4231_LOOPBACK 0x0d /* loopback control */
-#define CS4231_PLY_UPR_CNT 0x0e /* playback upper base count */
-#define CS4231_PLY_LWR_CNT 0x0f /* playback lower base count */
-#define CS4231_ALT_FEATURE_1 0x10 /* alternate #1 feature enable */
-#define AD1845_AF1_MIC_LEFT 0x10 /* alternate #1 feature + MIC left */
-#define CS4231_ALT_FEATURE_2 0x11 /* alternate #2 feature enable */
-#define AD1845_AF2_MIC_RIGHT 0x11 /* alternate #2 feature + MIC right */
-#define CS4231_LEFT_LINE_IN 0x12 /* left line input control */
-#define CS4231_RIGHT_LINE_IN 0x13 /* right line input control */
-#define CS4231_TIMER_LOW 0x14 /* timer low byte */
-#define CS4231_TIMER_HIGH 0x15 /* timer high byte */
-#define CS4231_LEFT_MIC_INPUT 0x16 /* left MIC input control register (InterWave only) */
-#define AD1845_UPR_FREQ_SEL 0x16 /* upper byte of frequency select */
-#define CS4231_RIGHT_MIC_INPUT 0x17 /* right MIC input control register (InterWave only) */
-#define AD1845_LWR_FREQ_SEL 0x17 /* lower byte of frequency select */
-#define CS4236_EXT_REG 0x17 /* extended register access */
-#define CS4231_IRQ_STATUS 0x18 /* irq status register */
-#define CS4231_LINE_LEFT_OUTPUT 0x19 /* left line output control register (InterWave only) */
-#define CS4231_VERSION 0x19 /* CS4231(A) - version values */
-#define CS4231_MONO_CTRL 0x1a /* mono input/output control */
-#define CS4231_LINE_RIGHT_OUTPUT 0x1b /* right line output control register (InterWave only) */
-#define AD1845_PWR_DOWN 0x1b /* power down control */
-#define CS4235_LEFT_MASTER 0x1b /* left master output control */
-#define CS4231_REC_FORMAT 0x1c /* clock and data format - record - bits 7-0 MCE */
-#define CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */
-#define AD1845_CLOCK 0x1d /* crystal clock select and total power down */
-#define CS4235_RIGHT_MASTER 0x1d /* right master output control */
-#define CS4231_REC_UPR_CNT 0x1e /* record upper count */
-#define CS4231_REC_LWR_CNT 0x1f /* record lower count */
-
-/* definitions for codec register select port - CODECP( REGSEL ) */
-
-#define CS4231_INIT 0x80 /* CODEC is initializing */
-#define CS4231_MCE 0x40 /* mode change enable */
-#define CS4231_TRD 0x20 /* transfer request disable */
-
-/* definitions for codec status register - CODECP( STATUS ) */
-
-#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
-
-/* definitions for codec irq status */
-
-#define CS4231_PLAYBACK_IRQ 0x10
-#define CS4231_RECORD_IRQ 0x20
-#define CS4231_TIMER_IRQ 0x40
-#define CS4231_ALL_IRQS 0x70
-#define CS4231_REC_UNDERRUN 0x08
-#define CS4231_REC_OVERRUN 0x04
-#define CS4231_PLY_OVERRUN 0x02
-#define CS4231_PLY_UNDERRUN 0x01
-
-/* definitions for CS4231_LEFT_INPUT and CS4231_RIGHT_INPUT registers */
-
-#define CS4231_ENABLE_MIC_GAIN 0x20
-
-#define CS4231_MIXS_LINE 0x00
-#define CS4231_MIXS_AUX1 0x40
-#define CS4231_MIXS_MIC 0x80
-#define CS4231_MIXS_ALL 0xc0
-
-/* definitions for clock and data format register - CS4231_PLAYBK_FORMAT */
-
-#define CS4231_LINEAR_8 0x00 /* 8-bit unsigned data */
-#define CS4231_ALAW_8 0x60 /* 8-bit A-law companded */
-#define CS4231_ULAW_8 0x20 /* 8-bit U-law companded */
-#define CS4231_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */
-#define CS4231_LINEAR_16_BIG 0xc0 /* 16-bit twos complement data - big endian */
-#define CS4231_ADPCM_16 0xa0 /* 16-bit ADPCM */
-#define CS4231_STEREO 0x10 /* stereo mode */
-/* bits 3-1 define frequency divisor */
-#define CS4231_XTAL1 0x00 /* 24.576 crystal */
-#define CS4231_XTAL2 0x01 /* 16.9344 crystal */
-
-/* definitions for interface control register - CS4231_IFACE_CTRL */
-
-#define CS4231_RECORD_PIO 0x80 /* record PIO enable */
-#define CS4231_PLAYBACK_PIO 0x40 /* playback PIO enable */
-#define CS4231_CALIB_MODE 0x18 /* calibration mode bits */
-#define CS4231_AUTOCALIB 0x08 /* auto calibrate */
-#define CS4231_SINGLE_DMA 0x04 /* use single DMA channel */
-#define CS4231_RECORD_ENABLE 0x02 /* record enable */
-#define CS4231_PLAYBACK_ENABLE 0x01 /* playback enable */
-
-/* definitions for pin control register - CS4231_PIN_CTRL */
-
-#define CS4231_IRQ_ENABLE 0x02 /* enable IRQ */
-#define CS4231_XCTL1 0x40 /* external control #1 */
-#define CS4231_XCTL0 0x80 /* external control #0 */
-
-/* definitions for test and init register - CS4231_TEST_INIT */
-
-#define CS4231_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */
-#define CS4231_DMA_REQUEST 0x10 /* DMA request in progress */
-
-/* definitions for misc control register - CS4231_MISC_INFO */
-
-#define CS4231_MODE2 0x40 /* MODE 2 */
-#define CS4231_IW_MODE3 0x6c /* MODE 3 - InterWave enhanced mode */
-#define CS4231_4236_MODE3 0xe0 /* MODE 3 - CS4236+ enhanced mode */
-
-/* definitions for alternate feature 1 register - CS4231_ALT_FEATURE_1 */
-
-#define CS4231_DACZ 0x01 /* zero DAC when underrun */
-#define CS4231_TIMER_ENABLE 0x40 /* codec timer enable */
-#define CS4231_OLB 0x80 /* output level bit */
-
-/* definitions for Extended Registers - CS4236+ */
-
-#define CS4236_REG(i23val) (((i23val << 2) & 0x10) | ((i23val >> 4) & 0x0f))
-#define CS4236_I23VAL(reg) ((((reg)&0xf) << 4) | (((reg)&0x10) >> 2) | 0x8)
-
-#define CS4236_LEFT_LINE 0x08 /* left LINE alternate volume */
-#define CS4236_RIGHT_LINE 0x18 /* right LINE alternate volume */
-#define CS4236_LEFT_MIC 0x28 /* left MIC volume */
-#define CS4236_RIGHT_MIC 0x38 /* right MIC volume */
-#define CS4236_LEFT_MIX_CTRL 0x48 /* synthesis and left input mixer control */
-#define CS4236_RIGHT_MIX_CTRL 0x58 /* right input mixer control */
-#define CS4236_LEFT_FM 0x68 /* left FM volume */
-#define CS4236_RIGHT_FM 0x78 /* right FM volume */
-#define CS4236_LEFT_DSP 0x88 /* left DSP serial port volume */
-#define CS4236_RIGHT_DSP 0x98 /* right DSP serial port volume */
-#define CS4236_RIGHT_LOOPBACK 0xa8 /* right loopback monitor volume */
-#define CS4236_DAC_MUTE 0xb8 /* DAC mute and IFSE enable */
-#define CS4236_ADC_RATE 0xc8 /* indenpendent ADC sample frequency */
-#define CS4236_DAC_RATE 0xd8 /* indenpendent DAC sample frequency */
-#define CS4236_LEFT_MASTER 0xe8 /* left master digital audio volume */
-#define CS4236_RIGHT_MASTER 0xf8 /* right master digital audio volume */
-#define CS4236_LEFT_WAVE 0x0c /* left wavetable serial port volume */
-#define CS4236_RIGHT_WAVE 0x1c /* right wavetable serial port volume */
-#define CS4236_VERSION 0x9c /* chip version and ID */
+#include "cs4231-regs.h"
/* defines for codec.mode */
@@ -210,7 +57,7 @@
#define CS4231_HW_CS4239 0x0404 /* CS4239 - Crystal Clear (tm) stereo enhancement */
/* compatible, but clones */
#define CS4231_HW_INTERWAVE 0x1000 /* InterWave chip */
-#define CS4231_HW_OPL3SA2 0x1001 /* OPL3-SA2 chip */
+#define CS4231_HW_OPL3SA2 0x1101 /* OPL3-SA2 chip, similar to cs4231 */
/* defines for codec.hwshare */
#define CS4231_HWSHARE_IRQ (1<<0)
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h
index 353910ce975..6b40ee60f4c 100644
--- a/include/sound/cs46xx.h
+++ b/include/sound/cs46xx.h
@@ -2,7 +2,7 @@
#define __SOUND_CS46XX_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Cirrus Logic, Inc.
* Definitions for Cirrus Logic CS46xx chips
*
diff --git a/include/sound/cs46xx_dsp_scb_types.h b/include/sound/cs46xx_dsp_scb_types.h
index 9cb6c7d0956..080857ad0ca 100644
--- a/include/sound/cs46xx_dsp_scb_types.h
+++ b/include/sound/cs46xx_dsp_scb_types.h
@@ -1,6 +1,6 @@
/*
* The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h
index d9da9e59cf3..7c44667e79a 100644
--- a/include/sound/cs46xx_dsp_spos.h
+++ b/include/sound/cs46xx_dsp_spos.h
@@ -1,6 +1,6 @@
/*
* The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/cs46xx_dsp_task_types.h b/include/sound/cs46xx_dsp_task_types.h
index b3076c487de..5cf920bfda2 100644
--- a/include/sound/cs46xx_dsp_task_types.h
+++ b/include/sound/cs46xx_dsp_task_types.h
@@ -1,6 +1,6 @@
/*
* The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/cs8403.h b/include/sound/cs8403.h
index c6c3f9f0da7..3a8c174a420 100644
--- a/include/sound/cs8403.h
+++ b/include/sound/cs8403.h
@@ -3,7 +3,7 @@
/*
* Routines for Cirrus Logic CS8403/CS8404A IEC958 (S/PDIF) Transmitter
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Takashi Iwai <tiwai@suse.de>
*
*
diff --git a/include/sound/cs8427.h b/include/sound/cs8427.h
index 97fd9acf802..f862cfff5f6 100644
--- a/include/sound/cs8427.h
+++ b/include/sound/cs8427.h
@@ -3,7 +3,7 @@
/*
* Routines for Cirrus Logic CS8427
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 3c522e59a33..5ccb6c5feec 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -3,7 +3,7 @@
/*
* Main header file for the ALSA driver
- * Copyright (c) 1994-2000 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1994-2000 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 529d0a56436..441aa06dcd6 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -2,7 +2,7 @@
#define __SOUND_EMU10K1_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Creative Labs, Inc.
* Definitions for EMU10K1 (SB Live!) chips
*
@@ -1408,8 +1408,6 @@ struct snd_emu10k1_fx8010 {
struct snd_emu10k1_fx8010_irq *irq_handlers;
};
-#define emu10k1_gpr_ctl(n) list_entry(n, struct snd_emu10k1_fx8010_ctl, list)
-
struct snd_emu10k1_midi {
struct snd_emu10k1 *emu;
struct snd_rawmidi *rmidi;
@@ -1456,6 +1454,9 @@ struct snd_emu1010 {
unsigned int adc_pads; /* bit mask */
unsigned int dac_pads; /* bit mask */
unsigned int internal_clock; /* 44100 or 48000 */
+ unsigned int optical_in; /* 0:SPDIF, 1:ADAT */
+ unsigned int optical_out; /* 0:SPDIF, 1:ADAT */
+ struct task_struct *firmware_thread;
};
struct snd_emu10k1 {
@@ -1599,9 +1600,9 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg,
void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
-int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value);
-int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value);
-int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src);
+int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value);
+int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value);
+int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src);
unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
@@ -1746,6 +1747,8 @@ int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
#define A_FXBUS2(x) (0x80 + (x)) /* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
#define A_EMU32OUTH(x) (0xa0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" - ??? */
#define A_EMU32OUTL(x) (0xb0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_1 - _F" - ??? */
+#define A3_EMU32IN(x) (0x160 + (x)) /* x = 0x00 - 0x3f "EMU32_IN_00 - _3F" - Only when .device = 0x0008 */
+#define A3_EMU32OUT(x) (0x1E0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_00 - _3F" - Only when .device = 0x0008 */
#define A_GPR(x) (A_FXGPREGBASE + (x))
/* cc_reg constants */
diff --git a/include/sound/es1688.h b/include/sound/es1688.h
index fc1c47dae3d..10fcf146581 100644
--- a/include/sound/es1688.h
+++ b/include/sound/es1688.h
@@ -3,7 +3,7 @@
/*
* Header file for ES488/ES1688
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/gus.h b/include/sound/gus.h
index c49ea57db8c..e5433d8b78b 100644
--- a/include/sound/gus.h
+++ b/include/sound/gus.h
@@ -3,7 +3,7 @@
/*
* Global structures used for GUS part of ALSA driver
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/hda_hwdep.h b/include/sound/hda_hwdep.h
new file mode 100644
index 00000000000..1c0034e87f2
--- /dev/null
+++ b/include/sound/hda_hwdep.h
@@ -0,0 +1,44 @@
+/*
+ * HWDEP Interface for HD-audio codec
+ *
+ * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
+ *
+ * This driver 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 driver 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
+ */
+
+#ifndef __SOUND_HDA_HWDEP_H
+#define __SOUND_HDA_HWDEP_H
+
+#define HDA_HWDEP_VERSION ((1 << 16) | (0 << 8) | (0 << 0)) /* 1.0.0 */
+
+/* verb */
+#define HDA_REG_NID_SHIFT 24
+#define HDA_REG_VERB_SHIFT 8
+#define HDA_REG_VAL_SHIFT 0
+#define HDA_VERB(nid,verb,param) ((nid)<<24 | (verb)<<8 | (param))
+
+struct hda_verb_ioctl {
+ u32 verb; /* HDA_VERB() */
+ u32 res; /* response */
+};
+
+/*
+ * ioctls
+ */
+#define HDA_IOCTL_PVERSION _IOR('H', 0x10, int)
+#define HDA_IOCTL_VERB_WRITE _IOWR('H', 0x11, struct hda_verb_ioctl)
+#define HDA_IOCTL_GET_WCAP _IOWR('H', 0x12, struct hda_verb_ioctl)
+
+#endif
diff --git a/include/sound/hdspm.h b/include/sound/hdspm.h
index c3c854d99c2..81990b2bcc9 100644
--- a/include/sound/hdspm.h
+++ b/include/sound/hdspm.h
@@ -1,4 +1,4 @@
-#ifndef __SOUND_HDSPM_H /* -*- linux-c -*- */
+#ifndef __SOUND_HDSPM_H
#define __SOUND_HDSPM_H
/*
* Copyright (C) 2003 Winfried Ritsch (IEM)
@@ -61,7 +61,8 @@ struct hdspm_peak_rms_ioctl {
};
/* use indirect access due to the limit of ioctl bit size */
-#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct hdspm_peak_rms_ioctl)
+#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS \
+ _IOR('H', 0x40, struct hdspm_peak_rms_ioctl)
/* ------------ CONFIG block IOCTL ---------------------- */
@@ -79,7 +80,8 @@ struct hdspm_config_info {
unsigned int analog_out;
};
-#define SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, struct hdspm_config_info)
+#define SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO \
+ _IOR('H', 0x41, struct hdspm_config_info)
/* get Soundcard Version */
@@ -93,10 +95,14 @@ struct hdspm_version {
/* ------------- get Matrix Mixer IOCTL --------------- */
-/* MADI mixer: 64inputs+64playback in 64outputs = 8192 => *4Byte = 32768 Bytes */
+/* MADI mixer: 64inputs+64playback in 64outputs = 8192 => *4Byte =
+ * 32768 Bytes
+ */
/* organisation is 64 channelfader in a continous memory block */
-/* equivalent to hardware definition, maybe for future feature of mmap of them */
+/* equivalent to hardware definition, maybe for future feature of mmap of
+ * them
+ */
/* each of 64 outputs has 64 infader and 64 outfader:
Ins to Outs mixer[out].in[in], Outstreams to Outs mixer[out].pb[pb] */
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
index 94c387b5d72..d9eea013c75 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -3,7 +3,7 @@
/*
* Hardware dependent layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/info.h b/include/sound/info.h
index 97ffc4fb996..fecbb1ffd54 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -3,7 +3,7 @@
/*
* Header file for info interface
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/initval.h b/include/sound/initval.h
index e85b90750a5..1daa6dff829 100644
--- a/include/sound/initval.h
+++ b/include/sound/initval.h
@@ -3,7 +3,7 @@
/*
* Init values for soundcard modules
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* 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/include/sound/memalloc.h b/include/sound/memalloc.h
index 83489c3abba..ae2921d9ddc 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Takashi Iwai <tiwai@suse.de>
*
* Generic memory allocators
diff --git a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h
index 197b9e3d612..51fbcb4a277 100644
--- a/include/sound/mixer_oss.h
+++ b/include/sound/mixer_oss.h
@@ -3,7 +3,7 @@
/*
* OSS MIXER API
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index d5c1396c4c9..d45218b44df 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -3,7 +3,7 @@
/*
* Header file for MPU-401 and compatible cards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -50,7 +50,6 @@
#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
-#define MPU401_INFO_UART_ONLY (1 << 5) /* No ENTER_UART cmd needed */
#define MPU401_MODE_BIT_INPUT 0
#define MPU401_MODE_BIT_OUTPUT 1
diff --git a/include/sound/opl3.h b/include/sound/opl3.h
index 82fdb093072..1d14b3f8239 100644
--- a/include/sound/opl3.h
+++ b/include/sound/opl3.h
@@ -4,7 +4,7 @@
/*
* Definitions of the OPL-3 registers.
*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Hannu Savolainen 1993-1996
*
*
diff --git a/include/sound/pcm-indirect.h b/include/sound/pcm-indirect.h
index 7003d7702e2..1df7acaaa53 100644
--- a/include/sound/pcm-indirect.h
+++ b/include/sound/pcm-indirect.h
@@ -2,7 +2,7 @@
* Helper functions for indirect PCM data transfer
*
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
* 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/include/sound/pcm.h b/include/sound/pcm.h
index 73334e0f823..5e9cc460075 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -3,7 +3,7 @@
/*
* Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Abramo Bagnara <abramo@alsa-project.org>
*
*
@@ -301,8 +301,8 @@ struct snd_pcm_runtime {
union snd_pcm_sync_id sync; /* hardware synchronization ID */
/* -- mmap -- */
- volatile struct snd_pcm_mmap_status *status;
- volatile struct snd_pcm_mmap_control *control;
+ struct snd_pcm_mmap_status *status;
+ struct snd_pcm_mmap_control *control;
/* -- locking / scheduling -- */
wait_queue_head_t sleep;
@@ -791,13 +791,13 @@ static inline struct snd_interval *hw_param_interval(struct snd_pcm_hw_params *p
static inline const struct snd_mask *hw_param_mask_c(const struct snd_pcm_hw_params *params,
snd_pcm_hw_param_t var)
{
- return (const struct snd_mask *)hw_param_mask((struct snd_pcm_hw_params*) params, var);
+ return &params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
}
static inline const struct snd_interval *hw_param_interval_c(const struct snd_pcm_hw_params *params,
snd_pcm_hw_param_t var)
{
- return (const struct snd_interval *)hw_param_interval((struct snd_pcm_hw_params*) params, var);
+ return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
}
#define params_access(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_ACCESS))
@@ -922,7 +922,10 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
void __user **bufs, snd_pcm_uframes_t frames);
+extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates;
+
int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime);
+unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate);
static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
struct snd_dma_buffer *bufp)
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 1cd4f64cdf3..cc4e226f35f 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -3,7 +3,7 @@
/*
* Digital Audio (PCM) - OSS compatibility abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 7dbcd10fa21..b550a416d07 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -3,7 +3,7 @@
/*
* Abstract layer for MIDI v1.0 stream
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/sb.h b/include/sound/sb.h
index 3ad854b397d..d0c9ed3546c 100644
--- a/include/sound/sb.h
+++ b/include/sound/sb.h
@@ -3,7 +3,7 @@
/*
* Header file for SoundBlaster cards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/seq_instr.h b/include/sound/seq_instr.h
index f2db03bfd74..93b0c51df5b 100644
--- a/include/sound/seq_instr.h
+++ b/include/sound/seq_instr.h
@@ -3,7 +3,7 @@
/*
* Main kernel header file for the ALSA sequencer
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/seq_midi_event.h b/include/sound/seq_midi_event.h
index dd789e7cdb2..5efab8b29c5 100644
--- a/include/sound/seq_midi_event.h
+++ b/include/sound/seq_midi_event.h
@@ -5,7 +5,7 @@
* MIDI byte <-> sequencer event coder
*
* Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>,
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
* 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/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
index 8d5aea76d7c..d888433a309 100644
--- a/include/sound/seq_virmidi.h
+++ b/include/sound/seq_virmidi.h
@@ -4,7 +4,7 @@
/*
* Virtual Raw MIDI client on Sequencer
* Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>,
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
* 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/include/sound/soc.h b/include/sound/soc.h
index db6edba8ef0..f47ef1f75f1 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -201,8 +201,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
-int snd_soc_info_bool_ext(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
+#define snd_soc_info_bool_ext snd_ctl_boolean_mono
int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
index b5067d3c238..e8eeb3a1ed2 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -4,7 +4,7 @@
/*
* ALSA driver for TEA5757/5759 Philips AM/FM tuner chips
*
- * Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
*
* 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/include/sound/timer.h b/include/sound/timer.h
index d42c083db1d..7990469a44c 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -3,7 +3,7 @@
/*
* Timer abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Abramo Bagnara <abramo@alsa-project.org>
*
*
diff --git a/include/sound/tlv.h b/include/sound/tlv.h
index d93a96b9187..d136ea2181e 100644
--- a/include/sound/tlv.h
+++ b/include/sound/tlv.h
@@ -3,7 +3,7 @@
/*
* Advanced Linux Sound Architecture - ALSA - Driver
- * Copyright (c) 2006 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2006 by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/include/sound/version.h b/include/sound/version.h
index 6bbcfefd2c3..8d4a8dd8923 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
/* include/version.h. Generated by alsa/ksync script. */
-#define CONFIG_SND_VERSION "1.0.14"
-#define CONFIG_SND_DATE " (Fri Jul 20 09:12:58 2007 UTC)"
+#define CONFIG_SND_VERSION "1.0.15"
+#define CONFIG_SND_DATE " (Tue Oct 16 14:57:44 2007 UTC)"
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
index 203d2b45b78..05ead669843 100644
--- a/include/sound/ymfpci.h
+++ b/include/sound/ymfpci.h
@@ -2,7 +2,7 @@
#define __SOUND_YMFPCI_H
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Definitions for Yahama YMF724/740/744/754 chips
*
*
diff --git a/include/video/Kbuild b/include/video/Kbuild
index a14f9c045b8..53a6c7310e6 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1 +1 @@
-unifdef-y += sisfb.h
+unifdef-y += sisfb.h uvesafb.h
diff --git a/include/video/mbxfb.h b/include/video/mbxfb.h
index 20b9002712e..ea18961fc5e 100644
--- a/include/video/mbxfb.h
+++ b/include/video/mbxfb.h
@@ -29,18 +29,18 @@ struct mbxfb_platform_data {
};
/* planar */
-#define MBXFB_FMT_YUV12 0
+#define MBXFB_FMT_YUV16 0
+#define MBXFB_FMT_YUV12 1
/* packed */
-#define MBXFB_FMT_UY0VY1 1
-#define MBXFB_FMT_VY0UY1 2
-#define MBXFB_FMT_Y0UY1V 3
-#define MBXFB_FMT_Y0VY1U 4
+#define MBXFB_FMT_UY0VY1 2
+#define MBXFB_FMT_VY0UY1 3
+#define MBXFB_FMT_Y0UY1V 4
+#define MBXFB_FMT_Y0VY1U 5
struct mbxfb_overlaySetup {
__u32 enable;
__u32 x, y;
__u32 width, height;
- __u32 alpha;
__u32 fmt;
__u32 mem_offset;
__u32 scaled_width;
@@ -54,6 +54,45 @@ struct mbxfb_overlaySetup {
__u16 UV_stride;
};
-#define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup)
+#define MBXFB_ALPHABLEND_NONE 0
+#define MBXFB_ALPHABLEND_GLOBAL 1
+#define MBXFB_ALPHABLEND_PIXEL 2
+
+#define MBXFB_COLORKEY_DISABLED 0
+#define MBXFB_COLORKEY_PREVIOUS 1
+#define MBXFB_COLORKEY_CURRENT 2
+struct mbxfb_alphaCtl {
+ __u8 overlay_blend_mode;
+ __u8 overlay_colorkey_mode;
+ __u8 overlay_global_alpha;
+ __u32 overlay_colorkey;
+ __u32 overlay_colorkey_mask;
+
+ __u8 graphics_blend_mode;
+ __u8 graphics_colorkey_mode;
+ __u8 graphics_global_alpha;
+ __u32 graphics_colorkey;
+ __u32 graphics_colorkey_mask;
+};
+
+#define MBXFB_PLANE_GRAPHICS 0
+#define MBXFB_PLANE_VIDEO 1
+struct mbxfb_planeorder {
+ __u8 bottom;
+ __u8 top;
+};
+
+struct mbxfb_reg {
+ __u32 addr; /* offset from 0x03fe 0000 */
+ __u32 val; /* value */
+ __u32 mask; /* which bits to touch (for write) */
+};
+
+#define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup)
+#define MBXFB_IOCG_ALPHA _IOR(0xF4, 0x01,struct mbxfb_alphaCtl)
+#define MBXFB_IOCS_ALPHA _IOW(0xF4, 0x02,struct mbxfb_alphaCtl)
+#define MBXFB_IOCS_PLANEORDER _IOR(0xF4, 0x03,struct mbxfb_planeorder)
+#define MBXFB_IOCS_REG _IOW(0xF4, 0x04,struct mbxfb_reg)
+#define MBXFB_IOCX_REG _IOWR(0xF4, 0x05,struct mbxfb_reg)
#endif /* __MBX_FB_H */
diff --git a/include/video/permedia2.h b/include/video/permedia2.h
index 9e49c9571ec..9ce9adbfda2 100644
--- a/include/video/permedia2.h
+++ b/include/video/permedia2.h
@@ -58,7 +58,14 @@
#define PM2R_RD_PALETTE_DATA 0x4008
#define PM2R_RD_PIXEL_MASK 0x4010
#define PM2R_RD_PALETTE_READ_ADDRESS 0x4018
+#define PM2R_RD_CURSOR_COLOR_ADDRESS 0x4020
+#define PM2R_RD_CURSOR_COLOR_DATA 0x4028
#define PM2R_RD_INDEXED_DATA 0x4050
+#define PM2R_RD_CURSOR_DATA 0x4058
+#define PM2R_RD_CURSOR_X_LSB 0x4060
+#define PM2R_RD_CURSOR_X_MSB 0x4068
+#define PM2R_RD_CURSOR_Y_LSB 0x4070
+#define PM2R_RD_CURSOR_Y_MSB 0x4078
#define PM2R_START_X_DOM 0x8000
#define PM2R_D_X_DOM 0x8008
@@ -68,11 +75,14 @@
#define PM2R_D_Y 0x8028
#define PM2R_COUNT 0x8030
#define PM2R_RENDER 0x8038
+#define PM2R_BIT_MASK_PATTERN 0x8068
#define PM2R_RASTERIZER_MODE 0x80a0
#define PM2R_RECTANGLE_ORIGIN 0x80d0
#define PM2R_RECTANGLE_SIZE 0x80d8
#define PM2R_PACKED_DATA_LIMITS 0x8150
#define PM2R_SCISSOR_MODE 0x8180
+#define PM2R_SCISSOR_MIN_XY 0x8188
+#define PM2R_SCISSOR_MAX_XY 0x8190
#define PM2R_SCREEN_SIZE 0x8198
#define PM2R_AREA_STIPPLE_MODE 0x81a0
#define PM2R_WINDOW_ORIGIN 0x81c8
@@ -83,7 +93,9 @@
#define PM2R_TEXEL_LUT_MODE 0x8678
#define PM2R_TEXTURE_COLOR_MODE 0x8680
#define PM2R_FOG_MODE 0x8690
+#define PM2R_TEXEL0 0x8760
#define PM2R_COLOR_DDA_MODE 0x87e0
+#define PM2R_CONSTANT_COLOR 0x87e8
#define PM2R_ALPHA_BLEND_MODE 0x8810
#define PM2R_DITHER_MODE 0x8818
#define PM2R_FB_SOFT_WRITE_MASK 0x8820
@@ -148,6 +160,7 @@
#define PM2VI_RD_CURSOR_Y_HIGH 0x00A
#define PM2VI_RD_CURSOR_X_HOT 0x00B
#define PM2VI_RD_CURSOR_Y_HOT 0x00C
+#define PM2VI_RD_OVERLAY_KEY 0x00D
#define PM2VI_RD_CLK0_PRESCALE 0x201
#define PM2VI_RD_CLK0_FEEDBACK 0x202
#define PM2VI_RD_CLK0_POSTSCALE 0x203
@@ -169,6 +182,8 @@
#define PM2F_RENDER_TRAPEZOID (1L<<6)
#define PM2F_RENDER_POINT (2L<<6)
#define PM2F_RENDER_RECTANGLE (3L<<6)
+#define PM2F_RENDER_SYNC_ON_BIT_MASK (1L<<11)
+#define PM2F_RENDER_TEXTURE_ENABLE (1L<<13)
#define PM2F_SYNCHRONIZATION (1L<<10)
#define PM2F_PLL_LOCKED 0x10
#define PM2F_BEING_RESET (1L<<31)
@@ -224,6 +239,8 @@
#define PM2F_APERTURE_STANDARD 0
#define PM2F_APERTURE_BYTESWAP 1
#define PM2F_APERTURE_HALFWORDSWAP 2
+#define PM2F_CURSORMODE_CURSOR_ENABLE (1 << 0)
+#define PM2F_CURSORMODE_TYPE_X (1 << 4)
typedef enum {
PM2_TYPE_PERMEDIA2,
diff --git a/include/video/pm3fb.h b/include/video/pm3fb.h
index d52e45a1e9b..2b85134fe96 100644
--- a/include/video/pm3fb.h
+++ b/include/video/pm3fb.h
@@ -1,6 +1,6 @@
/*
* linux/drivers/video/pm3fb.h -- 3DLabs Permedia3 frame buffer device
- *
+ *
* Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
* Copyright (C) 2001 Sven Luther, <luther@dpt-info.u-strasbg.fr>
*
@@ -51,37 +51,36 @@
* GLINT Permedia3 Region 0 Bypass Controls *
***********************************************/
#define PM3ByAperture1Mode 0x0300
- #define PM3ByApertureMode_BYTESWAP_ABCD (0<<0)
- #define PM3ByApertureMode_BYTESWAP_BADC (1<<0)
- #define PM3ByApertureMode_BYTESWAP_CDAB (2<<0)
- #define PM3ByApertureMode_BYTESWAP_DCBA (3<<0)
- #define PM3ByApertureMode_PATCH_DISABLE (0<<2)
- #define PM3ByApertureMode_PATCH_ENABLE (1<<2)
- #define PM3ByApertureMode_FORMAT_RAW (0<<3)
- #define PM3ByApertureMode_FORMAT_YUYV (1<<3)
- #define PM3ByApertureMode_FORMAT_UYVY (2<<3)
- #define PM3ByApertureMode_PIXELSIZE_8BIT (0<<5)
- #define PM3ByApertureMode_PIXELSIZE_16BIT (1<<5)
- #define PM3ByApertureMode_PIXELSIZE_32BIT (2<<5)
- #define PM3ByApertureMode_PIXELSIZE_MASK (3<<5)
- #define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0<<7)
- #define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1<<7)
- #define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2<<7)
- #define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3<<7)
- #define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off)&7f)<<9)
- #define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off)&7f)<<16)
- #define PM3ByApertureMode_FRAMEBUFFER (0<<21)
- #define PM3ByApertureMode_LOCALBUFFER (1<<21)
- #define PM3ByApertureMode_DOUBLE_WRITE_OFF (0<<22)
- #define PM3ByApertureMode_DOUBLE_WRITE_1MB (1<<22)
- #define PM3ByApertureMode_DOUBLE_WRITE_2MB (2<<22)
- #define PM3ByApertureMode_DOUBLE_WRITE_4MB (3<<22)
- #define PM3ByApertureMode_DOUBLE_WRITE_8MB (4<<22)
- #define PM3ByApertureMode_DOUBLE_WRITE_16MB (5<<22)
- #define PM3ByApertureMode_DOUBLE_WRITE_32MB (6<<22)
+ #define PM3ByApertureMode_BYTESWAP_ABCD (0 << 0)
+ #define PM3ByApertureMode_BYTESWAP_BADC (1 << 0)
+ #define PM3ByApertureMode_BYTESWAP_CDAB (2 << 0)
+ #define PM3ByApertureMode_BYTESWAP_DCBA (3 << 0)
+ #define PM3ByApertureMode_PATCH_ENABLE (1 << 2)
+ #define PM3ByApertureMode_FORMAT_RAW (0 << 3)
+ #define PM3ByApertureMode_FORMAT_YUYV (1 << 3)
+ #define PM3ByApertureMode_FORMAT_UYVY (2 << 3)
+ #define PM3ByApertureMode_PIXELSIZE_8BIT (0 << 5)
+ #define PM3ByApertureMode_PIXELSIZE_16BIT (1 << 5)
+ #define PM3ByApertureMode_PIXELSIZE_32BIT (2 << 5)
+ #define PM3ByApertureMode_PIXELSIZE_MASK (3 << 5)
+ #define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0 << 7)
+ #define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1 << 7)
+ #define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2 << 7)
+ #define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3 << 7)
+ #define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off) & 0x7f) << 9)
+ #define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off) & 0x7f) << 16)
+ #define PM3ByApertureMode_FRAMEBUFFER (0 << 21)
+ #define PM3ByApertureMode_LOCALBUFFER (1 << 21)
+ #define PM3ByApertureMode_DOUBLE_WRITE_OFF (0 << 22)
+ #define PM3ByApertureMode_DOUBLE_WRITE_1MB (1 << 22)
+ #define PM3ByApertureMode_DOUBLE_WRITE_2MB (2 << 22)
+ #define PM3ByApertureMode_DOUBLE_WRITE_4MB (3 << 22)
+ #define PM3ByApertureMode_DOUBLE_WRITE_8MB (4 << 22)
+ #define PM3ByApertureMode_DOUBLE_WRITE_16MB (5 << 22)
+ #define PM3ByApertureMode_DOUBLE_WRITE_32MB (6 << 22)
#define PM3ByAperture2Mode 0x0328
-
+
/**********************************************
* GLINT Permedia3 Memory Control (0x1000) *
***********************************************/
@@ -89,7 +88,7 @@
#define PM3MemBypassWriteMask 0x1008
#define PM3MemScratch 0x1010
#define PM3LocalMemCaps 0x1018
- #define PM3LocalMemCaps_NoWriteMask (1 << 28)
+ #define PM3LocalMemCaps_NoWriteMask (1 << 28)
#define PM3LocalMemTimings 0x1020
#define PM3LocalMemControl 0x1028
#define PM3LocalMemRefresh 0x1030
@@ -112,45 +111,41 @@
#define PM3VsStart 0x3048
#define PM3VsEnd 0x3050
#define PM3VideoControl 0x3058
- #define PM3VideoControl_DISABLE (0<<0)
- #define PM3VideoControl_ENABLE (1<<0)
- #define PM3VideoControl_BLANK_ACTIVE_HIGH (0<<1)
- #define PM3VideoControl_BLANK_ACTIVE_LOW (1<<1)
- #define PM3VideoControl_LINE_DOUBLE_OFF (0<<2)
- #define PM3VideoControl_LINE_DOUBLE_ON (1<<2)
- #define PM3VideoControl_HSYNC_FORCE_HIGH (0<<3)
- #define PM3VideoControl_HSYNC_ACTIVE_HIGH (1<<3)
- #define PM3VideoControl_HSYNC_FORCE_LOW (2<<3)
- #define PM3VideoControl_HSYNC_ACTIVE_LOW (3<<3)
- #define PM3VideoControl_HSYNC_MASK (3<<3)
- #define PM3VideoControl_VSYNC_FORCE_HIGH (0<<5)
- #define PM3VideoControl_VSYNC_ACTIVE_HIGH (1<<5)
- #define PM3VideoControl_VSYNC_FORCE_LOW (2<<5)
- #define PM3VideoControl_VSYNC_ACTIVE_LOW (3<<5)
- #define PM3VideoControl_VSYNC_MASK (3<<5)
- #define PM3VideoControl_BYTE_DOUBLE_OFF (0<<7)
- #define PM3VideoControl_BYTE_DOUBLE_ON (1<<7)
- #define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0<<9)
- #define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1<<9)
- #define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2<<9)
- #define PM3VideoControl_STEREO_DISABLE (0<<11)
- #define PM3VideoControl_STEREO_ENABLE (1<<11)
- #define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0<<12)
- #define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1<<12)
- #define PM3VideoControl_VIDEO_EXT_LOW (0<<14)
- #define PM3VideoControl_VIDEO_EXT_HIGH (1<<14)
- #define PM3VideoControl_SYNC_MODE_INDEPENDENT (0<<16)
- #define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1<<16)
- #define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2<<16)
- #define PM3VideoControl_PATCH_DISABLE (0<<18)
- #define PM3VideoControl_PATCH_ENABLE (1<<18)
- #define PM3VideoControl_PIXELSIZE_8BIT (0<<19)
- #define PM3VideoControl_PIXELSIZE_16BIT (1<<19)
- #define PM3VideoControl_PIXELSIZE_32BIT (2<<19)
- #define PM3VideoControl_DISPLAY_DISABLE (0<<21)
- #define PM3VideoControl_DISPLAY_ENABLE (1<<21)
- #define PM3VideoControl_PATCH_OFFSET_X(off) (((off)&0x3f)<<22)
- #define PM3VideoControl_PATCH_OFFSET_Y(off) (((off)&0x3f)<<28)
+ #define PM3VideoControl_ENABLE (1 << 0)
+ #define PM3VideoControl_BLANK_ACTIVE_HIGH (0 << 1)
+ #define PM3VideoControl_BLANK_ACTIVE_LOW (1 << 1)
+ #define PM3VideoControl_LINE_DOUBLE_OFF (0 << 2)
+ #define PM3VideoControl_LINE_DOUBLE_ON (1 << 2)
+ #define PM3VideoControl_HSYNC_FORCE_HIGH (0 << 3)
+ #define PM3VideoControl_HSYNC_ACTIVE_HIGH (1 << 3)
+ #define PM3VideoControl_HSYNC_FORCE_LOW (2 << 3)
+ #define PM3VideoControl_HSYNC_ACTIVE_LOW (3 << 3)
+ #define PM3VideoControl_HSYNC_MASK (3 << 3)
+ #define PM3VideoControl_VSYNC_FORCE_HIGH (0 << 5)
+ #define PM3VideoControl_VSYNC_ACTIVE_HIGH (1 << 5)
+ #define PM3VideoControl_VSYNC_FORCE_LOW (2 << 5)
+ #define PM3VideoControl_VSYNC_ACTIVE_LOW (3 << 5)
+ #define PM3VideoControl_VSYNC_MASK (3 << 5)
+ #define PM3VideoControl_BYTE_DOUBLE_OFF (0 << 7)
+ #define PM3VideoControl_BYTE_DOUBLE_ON (1 << 7)
+ #define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0 << 9)
+ #define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1 << 9)
+ #define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2 << 9)
+ #define PM3VideoControl_STEREO_ENABLE (1 << 11)
+ #define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0 << 12)
+ #define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1 << 12)
+ #define PM3VideoControl_VIDEO_EXT_LOW (0 << 14)
+ #define PM3VideoControl_VIDEO_EXT_HIGH (1 << 14)
+ #define PM3VideoControl_SYNC_MODE_INDEPENDENT (0 << 16)
+ #define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1 << 16)
+ #define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2 << 16)
+ #define PM3VideoControl_PATCH_ENABLE (1 << 18)
+ #define PM3VideoControl_PIXELSIZE_8BIT (0 << 19)
+ #define PM3VideoControl_PIXELSIZE_16BIT (1 << 19)
+ #define PM3VideoControl_PIXELSIZE_32BIT (2 << 19)
+ #define PM3VideoControl_DISPLAY_ENABLE (1 << 21)
+ #define PM3VideoControl_PATCH_OFFSET_X(off) (((off) & 0x3f) << 22)
+ #define PM3VideoControl_PATCH_OFFSET_Y(off) (((off) & 0x3f) << 28)
#define PM3InterruptLine 0x3060
#define PM3DisplayData 0x3068
#define PM3VerticalLineCount 0x3070
@@ -159,80 +154,93 @@
#define PM3MiscControl 0x3088
#define PM3VideoOverlayUpdate 0x3100
- #define PM3VideoOverlayUpdate_DISABLE (0<<0)
- #define PM3VideoOverlayUpdate_ENABLE (1<<0)
+ #define PM3VideoOverlayUpdate_ENABLE (1 << 0)
#define PM3VideoOverlayMode 0x3108
- #define PM3VideoOverlayMode_DISABLE (0<<0)
- #define PM3VideoOverlayMode_ENABLE (1<<0)
- #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0<<1)
- #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1<<1)
- #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2<<1)
- #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0<<4)
- #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1<<4)
- #define PM3VideoOverlayMode_PIXELSIZE_8BIT (0<<5)
- #define PM3VideoOverlayMode_PIXELSIZE_16BIT (1<<5)
- #define PM3VideoOverlayMode_PIXELSIZE_32BIT (2<<5)
- #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_RGB565 ((3<<7)|(1<<12)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_RGB332 ((4<<7)|(1<<12)|(0<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_BGR565 ((3<<7)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_BGR332 ((4<<7)|(0<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_CI8 ((5<<7)|(1<<12)|(0<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_VUY444 ((2<<10)|(1<<12)|(2<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_YUV444 ((2<<10)|(2<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_VUY422 ((1<<10)|(1<<12)|(1<<5))
- #define PM3VideoOverlayMode_COLORFORMAT_YUV422 ((1<<10)|(1<<5))
- #define PM3VideoOverlayMode_COLORORDER_BGR (0<<12)
- #define PM3VideoOverlayMode_COLORORDER_RGB (1<<12)
- #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0<<13)
- #define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1<<13)
- #define PM3VideoOverlayMode_FILTER_MASK (3<<14)
- #define PM3VideoOverlayMode_FILTER_OFF (0<<14)
- #define PM3VideoOverlayMode_FILTER_FULL (1<<14)
- #define PM3VideoOverlayMode_FILTER_PARTIAL (2<<14)
- #define PM3VideoOverlayMode_DEINTERLACE_OFF (0<<16)
- #define PM3VideoOverlayMode_DEINTERLACE_BOB (1<<16)
- #define PM3VideoOverlayMode_PATCHMODE_OFF (0<<18)
- #define PM3VideoOverlayMode_PATCHMODE_ON (1<<18)
- #define PM3VideoOverlayMode_FLIP_VIDEO (0<<20)
- #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1<<20)
- #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2<<20)
- #define PM3VideoOverlayMode_MIRROR_MASK (3<<23)
- #define PM3VideoOverlayMode_MIRRORX_OFF (0<<23)
- #define PM3VideoOverlayMode_MIRRORX_ON (1<<23)
- #define PM3VideoOverlayMode_MIRRORY_OFF (0<<24)
- #define PM3VideoOverlayMode_MIRRORY_ON (1<<24)
+ #define PM3VideoOverlayMode_ENABLE (1 << 0)
+ #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0 << 1)
+ #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1 << 1)
+ #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2 << 1)
+ #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0 << 4)
+ #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1 << 4)
+ #define PM3VideoOverlayMode_PIXELSIZE_8BIT (0 << 5)
+ #define PM3VideoOverlayMode_PIXELSIZE_16BIT (1 << 5)
+ #define PM3VideoOverlayMode_PIXELSIZE_32BIT (2 << 5)
+ #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 \
+ ((0 << 7)|(1 << 12)|(2 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 \
+ ((1 << 7)|(1 << 12)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 \
+ ((2 << 7)|(1 << 12)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_RGB565 \
+ ((3 << 7)|(1 << 12)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_RGB332 \
+ ((4 << 7)|(1 << 12)|(0 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 \
+ ((0 << 7)|(2 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 \
+ ((1 << 7)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 \
+ ((2 << 7)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_BGR565 \
+ ((3 << 7)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_BGR332 \
+ ((4 << 7)|(0 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_CI8 \
+ ((5 << 7)|(1 << 12)|(0 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_VUY444 \
+ ((2 << 10)|(1 << 12)|(2 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_YUV444 \
+ ((2 << 10)|(2 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_VUY422 \
+ ((1 << 10)|(1 << 12)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORFORMAT_YUV422 \
+ ((1 << 10)|(1 << 5))
+ #define PM3VideoOverlayMode_COLORORDER_BGR (0 << 12)
+ #define PM3VideoOverlayMode_COLORORDER_RGB (1 << 12)
+ #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0 << 13)
+ #define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1 << 13)
+ #define PM3VideoOverlayMode_FILTER_MASK (3 << 14)
+ #define PM3VideoOverlayMode_FILTER_OFF (0 << 14)
+ #define PM3VideoOverlayMode_FILTER_FULL (1 << 14)
+ #define PM3VideoOverlayMode_FILTER_PARTIAL (2 << 14)
+ #define PM3VideoOverlayMode_DEINTERLACE_OFF (0 << 16)
+ #define PM3VideoOverlayMode_DEINTERLACE_BOB (1 << 16)
+ #define PM3VideoOverlayMode_PATCHMODE_OFF (0 << 18)
+ #define PM3VideoOverlayMode_PATCHMODE_ON (1 << 18)
+ #define PM3VideoOverlayMode_FLIP_VIDEO (0 << 20)
+ #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1 << 20)
+ #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2 << 20)
+ #define PM3VideoOverlayMode_MIRROR_MASK (3 << 23)
+ #define PM3VideoOverlayMode_MIRRORX_OFF (0 << 23)
+ #define PM3VideoOverlayMode_MIRRORX_ON (1 << 23)
+ #define PM3VideoOverlayMode_MIRRORY_OFF (0 << 24)
+ #define PM3VideoOverlayMode_MIRRORY_ON (1 << 24)
#define PM3VideoOverlayFifoControl 0x3110
#define PM3VideoOverlayIndex 0x3118
#define PM3VideoOverlayBase0 0x3120
#define PM3VideoOverlayBase1 0x3128
#define PM3VideoOverlayBase2 0x3130
#define PM3VideoOverlayStride 0x3138
- #define PM3VideoOverlayStride_STRIDE(s) (((s)&0xfff)<<0)
-#define PM3VideoOverlayWidth 0x3140
- #define PM3VideoOverlayWidth_WIDTH(w) (((w)&0xfff)<<0)
-#define PM3VideoOverlayHeight 0x3148
- #define PM3VideoOverlayHeight_HEIGHT(h) (((h)&0xfff)<<0)
-#define PM3VideoOverlayOrigin 0x3150
- #define PM3VideoOverlayOrigin_XORIGIN(x) (((x)&0xfff)<<0)
- #define PM3VideoOverlayOrigin_YORIGIN(y) (((y)&0xfff)<<16)
-#define PM3VideoOverlayShrinkXDelta 0x3158
- #define PM3VideoOverlayShrinkXDelta_NONE (1<<16)
- #define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \
- ((((s)<<16)/(d))&0x0ffffff0)
-#define PM3VideoOverlayZoomXDelta 0x3160
- #define PM3VideoOverlayZoomXDelta_NONE (1<<16)
- #define PM3VideoOverlayZoomXDelta_DELTA(s,d) \
- ((((s)<<16)/(d))&0x0001fff0)
-#define PM3VideoOverlayYDelta 0x3168
- #define PM3VideoOverlayYDelta_NONE (1<<16)
- #define PM3VideoOverlayYDelta_DELTA(s,d) \
- ((((s)<<16)/(d))&0x0ffffff0)
+ #define PM3VideoOverlayStride_STRIDE(s) (((s) & 0xfff) << 0)
+#define PM3VideoOverlayWidth 0x3140
+ #define PM3VideoOverlayWidth_WIDTH(w) (((w) & 0xfff) << 0)
+#define PM3VideoOverlayHeight 0x3148
+ #define PM3VideoOverlayHeight_HEIGHT(h) (((h) & 0xfff) << 0)
+#define PM3VideoOverlayOrigin 0x3150
+ #define PM3VideoOverlayOrigin_XORIGIN(x) (((x) & 0xfff) << 0)
+ #define PM3VideoOverlayOrigin_YORIGIN(y) (((y) & 0xfff) << 16)
+#define PM3VideoOverlayShrinkXDelta 0x3158
+ #define PM3VideoOverlayShrinkXDelta_NONE (1 << 16)
+ #define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \
+ ((((s) << 16)/(d)) & 0x0ffffff0)
+#define PM3VideoOverlayZoomXDelta 0x3160
+ #define PM3VideoOverlayZoomXDelta_NONE (1 << 16)
+ #define PM3VideoOverlayZoomXDelta_DELTA(s,d) \
+ ((((s) << 16)/(d)) & 0x0001fff0)
+#define PM3VideoOverlayYDelta 0x3168
+ #define PM3VideoOverlayYDelta_NONE (1 << 16)
+ #define PM3VideoOverlayYDelta_DELTA(s,d) \
+ ((((s) << 16)/(d)) & 0x0ffffff0)
#define PM3VideoOverlayFieldOffset 0x3170
#define PM3VideoOverlayStatus 0x3178
@@ -249,102 +257,82 @@
#define PM3RD_IndexHigh 0x4028
#define PM3RD_IndexedData 0x4030
#define PM3RD_IndexControl 0x4038
- #define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1<<0)
- #define PM3RD_IndexControl_AUTOINCREMENT_DISABLE (0<<0)
+ #define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1 << 0)
/* Indirect Registers */
#define PM3RD_MiscControl 0x000
- #define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE (0<<0)
- #define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1<<0)
- #define PM3RD_MiscControl_PIXELDOUBLE_DISABLE (0<<1)
- #define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1<<1)
- #define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE (0<<2)
- #define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1<<2)
- #define PM3RD_MiscControl_DIRECTCOLOR_DISABLE (0<<3)
- #define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1<<3)
- #define PM3RD_MiscControl_OVERLAY_DISABLE (0<<4)
- #define PM3RD_MiscControl_OVERLAY_ENABLE (1<<4)
- #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE (0<<5)
- #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1<<5)
- #define PM3RD_MiscControl_VSB_OUTPUT_DISABLE (0<<6)
- #define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1<<6)
- #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE (0<<7)
- #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1<<7)
+ #define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1 << 0)
+ #define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1 << 1)
+ #define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1 << 2)
+ #define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1 << 3)
+ #define PM3RD_MiscControl_OVERLAY_ENABLE (1 << 4)
+ #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1 << 5)
+ #define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1 << 6)
+ #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1 << 7)
#define PM3RD_SyncControl 0x001
- #define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0<<0)
- #define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1<<0)
- #define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3<<0)
- #define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4<<0)
- #define PM3RD_SyncControl_HSYNC_TRI_STATE (2<<0)
- #define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0<<3)
- #define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1<<3)
- #define PM3RD_SyncControl_VSYNC_TRI_STATE (2<<3)
- #define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3<<3)
- #define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4<<3)
- #define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0<<6)
- #define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1<<6)
- #define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0<<7)
- #define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1<<7)
+ #define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0 << 0)
+ #define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1 << 0)
+ #define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3 << 0)
+ #define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4 << 0)
+ #define PM3RD_SyncControl_HSYNC_TRI_STATE (2 << 0)
+ #define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0 << 3)
+ #define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1 << 3)
+ #define PM3RD_SyncControl_VSYNC_TRI_STATE (2 << 3)
+ #define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3 << 3)
+ #define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4 << 3)
+ #define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0 << 6)
+ #define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1 << 6)
+ #define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0 << 7)
+ #define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1 << 7)
#define PM3RD_DACControl 0x002
- #define PM3RD_DACControl_DAC_POWER_ON (0<<0)
- #define PM3RD_DACControl_DAC_POWER_OFF (1<<0)
- #define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE (0<<3)
- #define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1<<3)
- #define PM3RD_DACControl_BLANK_RED_DAC_DISABLE (0<<4)
- #define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1<<4)
- #define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE (0<<5)
- #define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1<<5)
- #define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE (0<<6)
- #define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1<<6)
- #define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE (0<<7)
- #define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1<<7)
+ #define PM3RD_DACControl_DAC_POWER_ON (0 << 0)
+ #define PM3RD_DACControl_DAC_POWER_OFF (1 << 0)
+ #define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1 << 3)
+ #define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1 << 4)
+ #define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1 << 5)
+ #define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1 << 6)
+ #define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1 << 7)
#define PM3RD_PixelSize 0x003
- #define PM3RD_PixelSize_24_BIT_PIXELS (4<<0)
- #define PM3RD_PixelSize_32_BIT_PIXELS (2<<0)
- #define PM3RD_PixelSize_16_BIT_PIXELS (1<<0)
- #define PM3RD_PixelSize_8_BIT_PIXELS (0<<0)
+ #define PM3RD_PixelSize_24_BIT_PIXELS (4 << 0)
+ #define PM3RD_PixelSize_32_BIT_PIXELS (2 << 0)
+ #define PM3RD_PixelSize_16_BIT_PIXELS (1 << 0)
+ #define PM3RD_PixelSize_8_BIT_PIXELS (0 << 0)
#define PM3RD_ColorFormat 0x004
- #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1<<6)
- #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE (0<<6)
- #define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1<<5)
- #define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0<<5)
- #define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f<<0)
- #define PM3RD_ColorFormat_8888_COLOR (0<<0)
- #define PM3RD_ColorFormat_5551_FRONT_COLOR (1<<0)
- #define PM3RD_ColorFormat_4444_COLOR (2<<0)
- #define PM3RD_ColorFormat_332_FRONT_COLOR (5<<0)
- #define PM3RD_ColorFormat_332_BACK_COLOR (6<<0)
- #define PM3RD_ColorFormat_2321_FRONT_COLOR (9<<0)
- #define PM3RD_ColorFormat_2321_BACK_COLOR (10<<0)
- #define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11<<0)
- #define PM3RD_ColorFormat_232_BACKOFF_COLOR (12<<0)
- #define PM3RD_ColorFormat_5551_BACK_COLOR (13<<0)
- #define PM3RD_ColorFormat_CI8_COLOR (14<<0)
- #define PM3RD_ColorFormat_565_FRONT_COLOR (16<<0)
- #define PM3RD_ColorFormat_565_BACK_COLOR (17<<0)
+ #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1 << 6)
+ #define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1 << 5)
+ #define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0 << 5)
+ #define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f << 0)
+ #define PM3RD_ColorFormat_8888_COLOR (0 << 0)
+ #define PM3RD_ColorFormat_5551_FRONT_COLOR (1 << 0)
+ #define PM3RD_ColorFormat_4444_COLOR (2 << 0)
+ #define PM3RD_ColorFormat_332_FRONT_COLOR (5 << 0)
+ #define PM3RD_ColorFormat_332_BACK_COLOR (6 << 0)
+ #define PM3RD_ColorFormat_2321_FRONT_COLOR (9 << 0)
+ #define PM3RD_ColorFormat_2321_BACK_COLOR (10 << 0)
+ #define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11 << 0)
+ #define PM3RD_ColorFormat_232_BACKOFF_COLOR (12 << 0)
+ #define PM3RD_ColorFormat_5551_BACK_COLOR (13 << 0)
+ #define PM3RD_ColorFormat_CI8_COLOR (14 << 0)
+ #define PM3RD_ColorFormat_565_FRONT_COLOR (16 << 0)
+ #define PM3RD_ColorFormat_565_BACK_COLOR (17 << 0)
#define PM3RD_CursorMode 0x005
- #define PM3RD_CursorMode_CURSOR_DISABLE (0<<0)
- #define PM3RD_CursorMode_CURSOR_ENABLE (1<<0)
- #define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0<<2)
- #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1<<2)
- #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2<<2)
- #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3<<2)
- #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4<<2)
- #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5<<2)
- #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6<<2)
- #define PM3RD_CursorMode_TYPE_MS (0<<4)
- #define PM3RD_CursorMode_TYPE_X (1<<4)
- #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE (0<<6)
- #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1<<6)
- #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2<<6)
- #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3<<6)
+ #define PM3RD_CursorMode_CURSOR_ENABLE (1 << 0)
+ #define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0 << 2)
+ #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1 << 2)
+ #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2 << 2)
+ #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3 << 2)
+ #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4 << 2)
+ #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5 << 2)
+ #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6 << 2)
+ #define PM3RD_CursorMode_TYPE_MS (0 << 4)
+ #define PM3RD_CursorMode_TYPE_X (1 << 4)
+ #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1 << 6)
+ #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2 << 6)
+ #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3 << 6)
#define PM3RD_CursorControl 0x006
- #define PM3RD_CursorControl_DOUBLE_X_DISABLED (0<<0)
- #define PM3RD_CursorControl_DOUBLE_X_ENABLED (1<<0)
- #define PM3RD_CursorControl_DOUBLE_Y_DISABLED (0<<1)
- #define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1<<1)
- #define PM3RD_CursorControl_READBACK_POS_DISABLED (0<<2)
- #define PM3RD_CursorControl_READBACK_POS_ENABLED (1<<2)
+ #define PM3RD_CursorControl_DOUBLE_X_ENABLED (1 << 0)
+ #define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1 << 1)
+ #define PM3RD_CursorControl_READBACK_POS_ENABLED (1 << 2)
#define PM3RD_CursorXLow 0x007
#define PM3RD_CursorXHigh 0x008
@@ -354,17 +342,13 @@
#define PM3RD_CursorHotSpotY 0x00c
#define PM3RD_OverlayKey 0x00d
#define PM3RD_Pan 0x00e
- #define PM3RD_Pan_DISABLE (0<<0)
- #define PM3RD_Pan_ENABLE (1<<0)
- #define PM3RD_Pan_GATE_DISABLE (0<<1)
- #define PM3RD_Pan_GATE_ENABLE (1<<1)
+ #define PM3RD_Pan_ENABLE (1 << 0)
+ #define PM3RD_Pan_GATE_ENABLE (1 << 1)
#define PM3RD_Sense 0x00f
#define PM3RD_CheckControl 0x018
- #define PM3RD_CheckControl_PIXEL_DISABLED (0<<0)
- #define PM3RD_CheckControl_PIXEL_ENABLED (1<<0)
- #define PM3RD_CheckControl_LUT_DISABLED (0<<1)
- #define PM3RD_CheckControl_LUT_ENABLED (1<<1)
+ #define PM3RD_CheckControl_PIXEL_ENABLED (1 << 0)
+ #define PM3RD_CheckControl_LUT_ENABLED (1 << 1)
#define PM3RD_CheckPixelRed 0x019
#define PM3RD_CheckPixelGreen 0x01a
#define PM3RD_CheckPixelBlue 0x01b
@@ -374,19 +358,17 @@
#define PM3RD_Scratch 0x01f
#define PM3RD_VideoOverlayControl 0x020
- #define PM3RD_VideoOverlayControl_DISABLE (0<<0)
- #define PM3RD_VideoOverlayControl_ENABLE (1<<0)
- #define PM3RD_VideoOverlayControl_MODE_MASK (3<<1)
- #define PM3RD_VideoOverlayControl_MODE_MAINKEY (0<<1)
- #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1<<1)
- #define PM3RD_VideoOverlayControl_MODE_ALWAYS (2<<1)
- #define PM3RD_VideoOverlayControl_MODE_BLEND (3<<1)
- #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED (0<<3)
- #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1<<3)
- #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0<<4)
- #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1<<4)
- #define PM3RD_VideoOverlayControl_KEY_COLOR (0<<5)
- #define PM3RD_VideoOverlayControl_KEY_ALPHA (1<<5)
+ #define PM3RD_VideoOverlayControl_ENABLE (1 << 0)
+ #define PM3RD_VideoOverlayControl_MODE_MASK (3 << 1)
+ #define PM3RD_VideoOverlayControl_MODE_MAINKEY (0 << 1)
+ #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1 << 1)
+ #define PM3RD_VideoOverlayControl_MODE_ALWAYS (2 << 1)
+ #define PM3RD_VideoOverlayControl_MODE_BLEND (3 << 1)
+ #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1 << 3)
+ #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0 << 4)
+ #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1 << 4)
+ #define PM3RD_VideoOverlayControl_KEY_COLOR (0 << 5)
+ #define PM3RD_VideoOverlayControl_KEY_ALPHA (1 << 5)
#define PM3RD_VideoOverlayXStartLow 0x021
#define PM3RD_VideoOverlayXStartHigh 0x022
#define PM3RD_VideoOverlayYStartLow 0x023
@@ -399,10 +381,10 @@
#define PM3RD_VideoOverlayKeyG 0x02a
#define PM3RD_VideoOverlayKeyB 0x02b
#define PM3RD_VideoOverlayBlend 0x02c
- #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0<<6)
- #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1<<6)
- #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2<<6)
- #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3<<6)
+ #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0 << 6)
+ #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1 << 6)
+ #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2 << 6)
+ #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3 << 6)
#define PM3RD_DClkSetup1 0x1f0
#define PM3RD_DClkSetup2 0x1f1
@@ -410,21 +392,20 @@
#define PM3RD_KClkSetup2 0x1f3
#define PM3RD_DClkControl 0x200
- #define PM3RD_DClkControl_SOURCE_PLL (0<<4)
- #define PM3RD_DClkControl_SOURCE_VSA (1<<4)
- #define PM3RD_DClkControl_SOURCE_VSB (2<<4)
- #define PM3RD_DClkControl_SOURCE_EXT (3<<4)
- #define PM3RD_DClkControl_STATE_RUN (2<<2)
- #define PM3RD_DClkControl_STATE_HIGH (1<<2)
- #define PM3RD_DClkControl_STATE_LOW (0<<2)
- #define PM3RD_DClkControl_LOCKED (1<<1)
- #define PM3RD_DClkControl_NOT_LOCKED (0<<1)
- #define PM3RD_DClkControl_ENABLE (1<<0)
- #define PM3RD_DClkControl_DISABLE (0<<0)
+ #define PM3RD_DClkControl_SOURCE_PLL (0 << 4)
+ #define PM3RD_DClkControl_SOURCE_VSA (1 << 4)
+ #define PM3RD_DClkControl_SOURCE_VSB (2 << 4)
+ #define PM3RD_DClkControl_SOURCE_EXT (3 << 4)
+ #define PM3RD_DClkControl_STATE_RUN (2 << 2)
+ #define PM3RD_DClkControl_STATE_HIGH (1 << 2)
+ #define PM3RD_DClkControl_STATE_LOW (0 << 2)
+ #define PM3RD_DClkControl_LOCKED (1 << 1)
+ #define PM3RD_DClkControl_NOT_LOCKED (0 << 1)
+ #define PM3RD_DClkControl_ENABLE (1 << 0)
#define PM3RD_DClk0PreScale 0x201
#define PM3RD_DClk0FeedbackScale 0x202
#define PM3RD_DClk0PostScale 0x203
- #define PM3_REF_CLOCK 14318
+ #define PM3_REF_CLOCK 14318
#define PM3RD_DClk1PreScale 0x204
#define PM3RD_DClk1FeedbackScale 0x205
#define PM3RD_DClk1PostScale 0x206
@@ -435,59 +416,56 @@
#define PM3RD_DClk3FeedbackScale 0x20b
#define PM3RD_DClk3PostScale 0x20c
#define PM3RD_KClkControl 0x20d
- #define PM3RD_KClkControl_DISABLE (0<<0)
- #define PM3RD_KClkControl_ENABLE (1<<0)
- #define PM3RD_KClkControl_NOT_LOCKED (0<<1)
- #define PM3RD_KClkControl_LOCKED (1<<1)
- #define PM3RD_KClkControl_STATE_LOW (0<<2)
- #define PM3RD_KClkControl_STATE_HIGH (1<<2)
- #define PM3RD_KClkControl_STATE_RUN (2<<2)
- #define PM3RD_KClkControl_STATE_LOW_POWER (3<<2)
- #define PM3RD_KClkControl_SOURCE_PCLK (0<<4)
- #define PM3RD_KClkControl_SOURCE_HALF_PCLK (1<<4)
- #define PM3RD_KClkControl_SOURCE_PLL (2<<4)
+ #define PM3RD_KClkControl_ENABLE (1 << 0)
+ #define PM3RD_KClkControl_NOT_LOCKED (0 << 1)
+ #define PM3RD_KClkControl_LOCKED (1 << 1)
+ #define PM3RD_KClkControl_STATE_LOW (0 << 2)
+ #define PM3RD_KClkControl_STATE_HIGH (1 << 2)
+ #define PM3RD_KClkControl_STATE_RUN (2 << 2)
+ #define PM3RD_KClkControl_STATE_LOW_POWER (3 << 2)
+ #define PM3RD_KClkControl_SOURCE_PCLK (0 << 4)
+ #define PM3RD_KClkControl_SOURCE_HALF_PCLK (1 << 4)
+ #define PM3RD_KClkControl_SOURCE_PLL (2 << 4)
#define PM3RD_KClkPreScale 0x20e
#define PM3RD_KClkFeedbackScale 0x20f
#define PM3RD_KClkPostScale 0x210
#define PM3RD_MClkControl 0x211
- #define PM3RD_MClkControl_DISABLE (0<<0)
- #define PM3RD_MClkControl_ENABLE (1<<0)
- #define PM3RD_MClkControl_NOT_LOCKED (0<<1)
- #define PM3RD_MClkControl_LOCKED (1<<1)
- #define PM3RD_MClkControl_STATE_LOW (0<<2)
- #define PM3RD_MClkControl_STATE_HIGH (1<<2)
- #define PM3RD_MClkControl_STATE_RUN (2<<2)
- #define PM3RD_MClkControl_STATE_LOW_POWER (3<<2)
- #define PM3RD_MClkControl_SOURCE_PCLK (0<<4)
- #define PM3RD_MClkControl_SOURCE_HALF_PCLK (1<<4)
- #define PM3RD_MClkControl_SOURCE_HALF_EXT (3<<4)
- #define PM3RD_MClkControl_SOURCE_EXT (4<<4)
- #define PM3RD_MClkControl_SOURCE_HALF_KCLK (5<<4)
- #define PM3RD_MClkControl_SOURCE_KCLK (6<<4)
+ #define PM3RD_MClkControl_ENABLE (1 << 0)
+ #define PM3RD_MClkControl_NOT_LOCKED (0 << 1)
+ #define PM3RD_MClkControl_LOCKED (1 << 1)
+ #define PM3RD_MClkControl_STATE_LOW (0 << 2)
+ #define PM3RD_MClkControl_STATE_HIGH (1 << 2)
+ #define PM3RD_MClkControl_STATE_RUN (2 << 2)
+ #define PM3RD_MClkControl_STATE_LOW_POWER (3 << 2)
+ #define PM3RD_MClkControl_SOURCE_PCLK (0 << 4)
+ #define PM3RD_MClkControl_SOURCE_HALF_PCLK (1 << 4)
+ #define PM3RD_MClkControl_SOURCE_HALF_EXT (3 << 4)
+ #define PM3RD_MClkControl_SOURCE_EXT (4 << 4)
+ #define PM3RD_MClkControl_SOURCE_HALF_KCLK (5 << 4)
+ #define PM3RD_MClkControl_SOURCE_KCLK (6 << 4)
#define PM3RD_MClkPreScale 0x212
#define PM3RD_MClkFeedbackScale 0x213
#define PM3RD_MClkPostScale 0x214
#define PM3RD_SClkControl 0x215
- #define PM3RD_SClkControl_DISABLE (0<<0)
- #define PM3RD_SClkControl_ENABLE (1<<0)
- #define PM3RD_SClkControl_NOT_LOCKED (0<<1)
- #define PM3RD_SClkControl_LOCKED (1<<1)
- #define PM3RD_SClkControl_STATE_LOW (0<<2)
- #define PM3RD_SClkControl_STATE_HIGH (1<<2)
- #define PM3RD_SClkControl_STATE_RUN (2<<2)
- #define PM3RD_SClkControl_STATE_LOW_POWER (3<<2)
- #define PM3RD_SClkControl_SOURCE_PCLK (0<<4)
- #define PM3RD_SClkControl_SOURCE_HALF_PCLK (1<<4)
- #define PM3RD_SClkControl_SOURCE_HALF_EXT (3<<4)
- #define PM3RD_SClkControl_SOURCE_EXT (4<<4)
- #define PM3RD_SClkControl_SOURCE_HALF_KCLK (5<<4)
- #define PM3RD_SClkControl_SOURCE_KCLK (6<<4)
+ #define PM3RD_SClkControl_ENABLE (1 << 0)
+ #define PM3RD_SClkControl_NOT_LOCKED (0 << 1)
+ #define PM3RD_SClkControl_LOCKED (1 << 1)
+ #define PM3RD_SClkControl_STATE_LOW (0 << 2)
+ #define PM3RD_SClkControl_STATE_HIGH (1 << 2)
+ #define PM3RD_SClkControl_STATE_RUN (2 << 2)
+ #define PM3RD_SClkControl_STATE_LOW_POWER (3 << 2)
+ #define PM3RD_SClkControl_SOURCE_PCLK (0 << 4)
+ #define PM3RD_SClkControl_SOURCE_HALF_PCLK (1 << 4)
+ #define PM3RD_SClkControl_SOURCE_HALF_EXT (3 << 4)
+ #define PM3RD_SClkControl_SOURCE_EXT (4 << 4)
+ #define PM3RD_SClkControl_SOURCE_HALF_KCLK (5 << 4)
+ #define PM3RD_SClkControl_SOURCE_KCLK (6 << 4)
#define PM3RD_SClkPreScale 0x216
#define PM3RD_SClkFeedbackScale 0x217
#define PM3RD_SClkPostScale 0x218
-#define PM3RD_CursorPalette(p) (0x303+(p))
-#define PM3RD_CursorPattern(p) (0x400+(p))
+#define PM3RD_CursorPalette(p) (0x303 + (p))
+#define PM3RD_CursorPattern(p) (0x400 + (p))
/******************************************************
* GLINT Permedia3 Video Streaming Registers (0x5000) *
*******************************************************/
@@ -521,10 +499,10 @@
#define PM3ColorDDAModeOr 0xabe8
#define PM3CommandInterrupt 0xa990
#define PM3ConstantColorDDA 0xafb0
- #define PM3ConstantColorDDA_R(r) ((r)&0xff)
- #define PM3ConstantColorDDA_G(g) (((g)&0xff)<<8)
- #define PM3ConstantColorDDA_B(b) (((b)&0xff)<<16)
- #define PM3ConstantColorDDA_A(a) (((a)&0xff)<<24)
+ #define PM3ConstantColorDDA_R(r) ((r) & 0xff)
+ #define PM3ConstantColorDDA_G(g) (((g) & 0xff) << 8)
+ #define PM3ConstantColorDDA_B(b) (((b) & 0xff) << 16)
+ #define PM3ConstantColorDDA_A(a) (((a) & 0xff) << 24)
#define PM3ContextData 0x8dd0
#define PM3ContextDump 0x8dc0
#define PM3ContextRestore 0x8dc8
@@ -568,59 +546,59 @@
#define PM3FBDestReadBufferOffset1 0xaea8
#define PM3FBDestReadBufferOffset2 0xaeb0
#define PM3FBDestReadBufferOffset3 0xaeb8
- #define PM3FBDestReadBufferOffset_XOffset(x) ((x)&0xffff)
- #define PM3FBDestReadBufferOffset_YOffset(y) (((y)&0xffff)<<16)
+ #define PM3FBDestReadBufferOffset_XOffset(x) ((x) & 0xffff)
+ #define PM3FBDestReadBufferOffset_YOffset(y) (((y) & 0xffff) << 16)
#define PM3FBDestReadBufferWidth0 0xaec0
#define PM3FBDestReadBufferWidth1 0xaec8
#define PM3FBDestReadBufferWidth2 0xaed0
#define PM3FBDestReadBufferWidth3 0xaed8
- #define PM3FBDestReadBufferWidth_Width(w) ((w)&0x0fff)
+ #define PM3FBDestReadBufferWidth_Width(w) ((w) & 0x0fff)
#define PM3FBDestReadEnables 0xaee8
#define PM3FBDestReadEnablesAnd 0xad20
#define PM3FBDestReadEnablesOr 0xad28
- #define PM3FBDestReadEnables_E(e) ((e)&0xff)
- #define PM3FBDestReadEnables_E0 1<<0
- #define PM3FBDestReadEnables_E1 1<<1
- #define PM3FBDestReadEnables_E2 1<<2
- #define PM3FBDestReadEnables_E3 1<<3
- #define PM3FBDestReadEnables_E4 1<<4
- #define PM3FBDestReadEnables_E5 1<<5
- #define PM3FBDestReadEnables_E6 1<<6
- #define PM3FBDestReadEnables_E7 1<<7
- #define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8)
- #define PM3FBDestReadEnables_R0 1<<8
- #define PM3FBDestReadEnables_R1 1<<9
- #define PM3FBDestReadEnables_R2 1<<10
- #define PM3FBDestReadEnables_R3 1<<11
- #define PM3FBDestReadEnables_R4 1<<12
- #define PM3FBDestReadEnables_R5 1<<13
- #define PM3FBDestReadEnables_R6 1<<14
- #define PM3FBDestReadEnables_R7 1<<15
- #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24)
+ #define PM3FBDestReadEnables_E(e) ((e) & 0xff)
+ #define PM3FBDestReadEnables_E0 (1 << 0)
+ #define PM3FBDestReadEnables_E1 (1 << 1)
+ #define PM3FBDestReadEnables_E2 (1 << 2)
+ #define PM3FBDestReadEnables_E3 (1 << 3)
+ #define PM3FBDestReadEnables_E4 (1 << 4)
+ #define PM3FBDestReadEnables_E5 (1 << 5)
+ #define PM3FBDestReadEnables_E6 (1 << 6)
+ #define PM3FBDestReadEnables_E7 (1 << 7)
+ #define PM3FBDestReadEnables_R(r) (((r) & 0xff) << 8)
+ #define PM3FBDestReadEnables_R0 (1 << 8)
+ #define PM3FBDestReadEnables_R1 (1 << 9)
+ #define PM3FBDestReadEnables_R2 (1 << 10)
+ #define PM3FBDestReadEnables_R3 (1 << 11)
+ #define PM3FBDestReadEnables_R4 (1 << 12)
+ #define PM3FBDestReadEnables_R5 (1 << 13)
+ #define PM3FBDestReadEnables_R6 (1 << 14)
+ #define PM3FBDestReadEnables_R7 (1 << 15)
+ #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a) & 0xff) << 24)
#define PM3FBDestReadMode 0xaee0
#define PM3FBDestReadModeAnd 0xac90
#define PM3FBDestReadModeOr 0xac98
- #define PM3FBDestReadMode_ReadDisable 0<<0
- #define PM3FBDestReadMode_ReadEnable 1<<0
- #define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2)
- #define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7)
- #define PM3FBDestReadMode_Enable0 1<<8
- #define PM3FBDestReadMode_Enable1 1<<9
- #define PM3FBDestReadMode_Enable2 1<<10
- #define PM3FBDestReadMode_Enable3 1<<11
- #define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12)
- #define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14)
- #define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16)
- #define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18)
- #define PM3FBDestReadMode_Origin0 1<<20
- #define PM3FBDestReadMode_Origin1 1<<21
- #define PM3FBDestReadMode_Origin2 1<<22
- #define PM3FBDestReadMode_Origin3 1<<23
- #define PM3FBDestReadMode_Blocking 1<<24
- #define PM3FBDestReadMode_UseReadEnabled 1<<26
- #define PM3FBDestReadMode_AlphaFiltering 1<<27
+ #define PM3FBDestReadMode_ReadDisable (0 << 0)
+ #define PM3FBDestReadMode_ReadEnable (1 << 0)
+ #define PM3FBDestReadMode_StripePitch(sp) (((sp) & 0x7) << 2)
+ #define PM3FBDestReadMode_StripeHeight(sh) (((sh) & 0x7) << 7)
+ #define PM3FBDestReadMode_Enable0 (1 << 8)
+ #define PM3FBDestReadMode_Enable1 (1 << 9)
+ #define PM3FBDestReadMode_Enable2 (1 << 10)
+ #define PM3FBDestReadMode_Enable3 (1 << 11)
+ #define PM3FBDestReadMode_Layout0(l) (((l) & 0x3) << 12)
+ #define PM3FBDestReadMode_Layout1(l) (((l) & 0x3) << 14)
+ #define PM3FBDestReadMode_Layout2(l) (((l) & 0x3) << 16)
+ #define PM3FBDestReadMode_Layout3(l) (((l) & 0x3) << 18)
+ #define PM3FBDestReadMode_Origin0 (1 << 20)
+ #define PM3FBDestReadMode_Origin1 (1 << 21)
+ #define PM3FBDestReadMode_Origin2 (1 << 22)
+ #define PM3FBDestReadMode_Origin3 (1 << 23)
+ #define PM3FBDestReadMode_Blocking (1 << 24)
+ #define PM3FBDestReadMode_UseReadEnabled (1 << 26)
+ #define PM3FBDestReadMode_AlphaFiltering (1 << 27)
#define PM3FBHardwareWriteMask 0x8ac0
#define PM3FBSoftwareWriteMask 0x8820
@@ -628,65 +606,65 @@
#define PM3FBSourceData 0x8aa8
#define PM3FBSourceReadBufferAddr 0xaf08
#define PM3FBSourceReadBufferOffset 0xaf10
- #define PM3FBSourceReadBufferOffset_XOffset(x) ((x)&0xffff)
- #define PM3FBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16)
+ #define PM3FBSourceReadBufferOffset_XOffset(x) ((x) & 0xffff)
+ #define PM3FBSourceReadBufferOffset_YOffset(y) (((y) & 0xffff) << 16)
#define PM3FBSourceReadBufferWidth 0xaf18
- #define PM3FBSourceReadBufferWidth_Width(w) ((w)&0x0fff)
+ #define PM3FBSourceReadBufferWidth_Width(w) ((w) & 0x0fff)
#define PM3FBSourceReadMode 0xaf00
#define PM3FBSourceReadModeAnd 0xaca0
#define PM3FBSourceReadModeOr 0xaca8
- #define PM3FBSourceReadMode_ReadDisable (0<<0)
- #define PM3FBSourceReadMode_ReadEnable (1<<0)
- #define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2)
- #define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7)
- #define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8)
- #define PM3FBSourceReadMode_Origin 1<<10
- #define PM3FBSourceReadMode_Blocking 1<<11
- #define PM3FBSourceReadMode_UserTexelCoord 1<<13
- #define PM3FBSourceReadMode_WrapXEnable 1<<14
- #define PM3FBSourceReadMode_WrapYEnable 1<<15
- #define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16)
- #define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20)
- #define PM3FBSourceReadMode_ExternalSourceData 1<<24
-#define PM3FBWriteBufferAddr0 0xb000
-#define PM3FBWriteBufferAddr1 0xb008
-#define PM3FBWriteBufferAddr2 0xb010
-#define PM3FBWriteBufferAddr3 0xb018
+ #define PM3FBSourceReadMode_ReadDisable (0 << 0)
+ #define PM3FBSourceReadMode_ReadEnable (1 << 0)
+ #define PM3FBSourceReadMode_StripePitch(sp) (((sp) & 0x7) << 2)
+ #define PM3FBSourceReadMode_StripeHeight(sh) (((sh) & 0x7) << 7)
+ #define PM3FBSourceReadMode_Layout(l) (((l) & 0x3) << 8)
+ #define PM3FBSourceReadMode_Origin (1 << 10)
+ #define PM3FBSourceReadMode_Blocking (1 << 11)
+ #define PM3FBSourceReadMode_UserTexelCoord (1 << 13)
+ #define PM3FBSourceReadMode_WrapXEnable (1 << 14)
+ #define PM3FBSourceReadMode_WrapYEnable (1 << 15)
+ #define PM3FBSourceReadMode_WrapX(w) (((w) & 0xf) << 16)
+ #define PM3FBSourceReadMode_WrapY(w) (((w) & 0xf) << 20)
+ #define PM3FBSourceReadMode_ExternalSourceData (1 << 24)
+#define PM3FBWriteBufferAddr0 0xb000
+#define PM3FBWriteBufferAddr1 0xb008
+#define PM3FBWriteBufferAddr2 0xb010
+#define PM3FBWriteBufferAddr3 0xb018
-#define PM3FBWriteBufferOffset0 0xb020
-#define PM3FBWriteBufferOffset1 0xb028
-#define PM3FBWriteBufferOffset2 0xb030
-#define PM3FBWriteBufferOffset3 0xb038
- #define PM3FBWriteBufferOffset_XOffset(x) ((x)&0xffff)
- #define PM3FBWriteBufferOffset_YOffset(y) (((y)&0xffff)<<16)
+#define PM3FBWriteBufferOffset0 0xb020
+#define PM3FBWriteBufferOffset1 0xb028
+#define PM3FBWriteBufferOffset2 0xb030
+#define PM3FBWriteBufferOffset3 0xb038
+ #define PM3FBWriteBufferOffset_XOffset(x) ((x) & 0xffff)
+ #define PM3FBWriteBufferOffset_YOffset(y) (((y) & 0xffff) << 16)
-#define PM3FBWriteBufferWidth0 0xb040
-#define PM3FBWriteBufferWidth1 0xb048
-#define PM3FBWriteBufferWidth2 0xb050
-#define PM3FBWriteBufferWidth3 0xb058
- #define PM3FBWriteBufferWidth_Width(w) ((w)&0x0fff)
+#define PM3FBWriteBufferWidth0 0xb040
+#define PM3FBWriteBufferWidth1 0xb048
+#define PM3FBWriteBufferWidth2 0xb050
+#define PM3FBWriteBufferWidth3 0xb058
+ #define PM3FBWriteBufferWidth_Width(w) ((w) & 0x0fff)
-#define PM3FBWriteMode 0x8ab8
-#define PM3FBWriteModeAnd 0xacf0
-#define PM3FBWriteModeOr 0xacf8
- #define PM3FBWriteMode_WriteDisable 0<<0
- #define PM3FBWriteMode_WriteEnable 1<<0
- #define PM3FBWriteMode_Replicate 1<<4
- #define PM3FBWriteMode_OpaqueSpan 1<<5
- #define PM3FBWriteMode_StripePitch(p) (((p)&0x7)<<6)
- #define PM3FBWriteMode_StripeHeight(h) (((h)&0x7)<<9)
- #define PM3FBWriteMode_Enable0 1<<12
- #define PM3FBWriteMode_Enable1 1<<13
- #define PM3FBWriteMode_Enable2 1<<14
- #define PM3FBWriteMode_Enable3 1<<15
- #define PM3FBWriteMode_Layout0(l) (((l)&0x3)<<16)
- #define PM3FBWriteMode_Layout1(l) (((l)&0x3)<<18)
- #define PM3FBWriteMode_Layout2(l) (((l)&0x3)<<20)
- #define PM3FBWriteMode_Layout3(l) (((l)&0x3)<<22)
- #define PM3FBWriteMode_Origin0 1<<24
- #define PM3FBWriteMode_Origin1 1<<25
- #define PM3FBWriteMode_Origin2 1<<26
- #define PM3FBWriteMode_Origin3 1<<27
+#define PM3FBWriteMode 0x8ab8
+#define PM3FBWriteModeAnd 0xacf0
+#define PM3FBWriteModeOr 0xacf8
+ #define PM3FBWriteMode_WriteDisable (0 << 0)
+ #define PM3FBWriteMode_WriteEnable (1 << 0)
+ #define PM3FBWriteMode_Replicate (1 << 4)
+ #define PM3FBWriteMode_OpaqueSpan (1 << 5)
+ #define PM3FBWriteMode_StripePitch(p) (((p) & 0x7) << 6)
+ #define PM3FBWriteMode_StripeHeight(h) (((h) & 0x7) << 9)
+ #define PM3FBWriteMode_Enable0 (1 << 12)
+ #define PM3FBWriteMode_Enable1 (1 << 13)
+ #define PM3FBWriteMode_Enable2 (1 << 14)
+ #define PM3FBWriteMode_Enable3 (1 << 15)
+ #define PM3FBWriteMode_Layout0(l) (((l) & 0x3) << 16)
+ #define PM3FBWriteMode_Layout1(l) (((l) & 0x3) << 18)
+ #define PM3FBWriteMode_Layout2(l) (((l) & 0x3) << 20)
+ #define PM3FBWriteMode_Layout3(l) (((l) & 0x3) << 22)
+ #define PM3FBWriteMode_Origin0 (1 << 24)
+ #define PM3FBWriteMode_Origin1 (1 << 25)
+ #define PM3FBWriteMode_Origin2 (1 << 26)
+ #define PM3FBWriteMode_Origin3 (1 << 27)
#define PM3ForegroundColor 0xb0c0
/* ... */
#define PM3GIDMode 0xb538
@@ -701,55 +679,55 @@
#define PM3LBDestReadMode 0xb500
#define PM3LBDestReadModeAnd 0xb580
#define PM3LBDestReadModeOr 0xb588
- #define PM3LBDestReadMode_Disable 0<<0
- #define PM3LBDestReadMode_Enable 1<<0
- #define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2)
- #define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5)
- #define PM3LBDestReadMode_Layout 1<<8
- #define PM3LBDestReadMode_Origin 1<<9
- #define PM3LBDestReadMode_UserReadEnables 1<<10
- #define PM3LBDestReadMode_Packed16 1<<11
- #define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12)
+ #define PM3LBDestReadMode_Disable (0 << 0)
+ #define PM3LBDestReadMode_Enable (1 << 0)
+ #define PM3LBDestReadMode_StripePitch(p) (((p) & 0x7) << 2)
+ #define PM3LBDestReadMode_StripeHeight(h) (((h) & 0x7) << 5)
+ #define PM3LBDestReadMode_Layout (1 << 8)
+ #define PM3LBDestReadMode_Origin (1 << 9)
+ #define PM3LBDestReadMode_UserReadEnables (1 << 10)
+ #define PM3LBDestReadMode_Packed16 (1 << 11)
+ #define PM3LBDestReadMode_Width(w) (((w) & 0xfff) << 12)
#define PM3LBReadFormat 0x8888
- #define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0)
- #define PM3LBReadFormat_StencilWidth(w) (((w)&0xf)<<2)
- #define PM3LBReadFormat_StencilPosition(p) (((p)&0x1f)<<6)
- #define PM3LBReadFormat_FCPWidth(w) (((w)&0xf)<<11)
- #define PM3LBReadFormat_FCPPosition(p) (((p)&0x1f)<<15)
- #define PM3LBReadFormat_GIDWidth(w) (((w)&0x7)<<20)
- #define PM3LBReadFormat_GIDPosition(p) (((p)&0x1f)<<23)
+ #define PM3LBReadFormat_DepthWidth(w) (((w) & 0x3) << 0)
+ #define PM3LBReadFormat_StencilWidth(w) (((w) & 0xf) << 2)
+ #define PM3LBReadFormat_StencilPosition(p) (((p) & 0x1f) << 6)
+ #define PM3LBReadFormat_FCPWidth(w) (((w) & 0xf) << 11)
+ #define PM3LBReadFormat_FCPPosition(p) (((p) & 0x1f) << 15)
+ #define PM3LBReadFormat_GIDWidth(w) (((w) & 0x7) << 20)
+ #define PM3LBReadFormat_GIDPosition(p) (((p) & 0x1f) << 23)
#define PM3LBSourceReadBufferAddr 0xb528
#define PM3LBSourceReadBufferOffset 0xb530
#define PM3LBSourceReadMode 0xb520
#define PM3LBSourceReadModeAnd 0xb5a0
#define PM3LBSourceReadModeOr 0xb5a8
- #define PM3LBSourceReadMode_Enable 1<<0
- #define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2)
- #define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5)
- #define PM3LBSourceReadMode_Layout 1<<8
- #define PM3LBSourceReadMode_Origin 1<<9
- #define PM3LBSourceReadMode_Packed16 1<<10
- #define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11)
+ #define PM3LBSourceReadMode_Enable (1 << 0)
+ #define PM3LBSourceReadMode_StripePitch(p) (((p) & 0x7) << 2)
+ #define PM3LBSourceReadMode_StripeHeight(h) (((h) & 0x7) << 5)
+ #define PM3LBSourceReadMode_Layout (1 << 8)
+ #define PM3LBSourceReadMode_Origin (1 << 9)
+ #define PM3LBSourceReadMode_Packed16 (1 << 10)
+ #define PM3LBSourceReadMode_Width(w) (((w) & 0xfff) << 11)
#define PM3LBStencil 0x88a8
#define PM3LBWriteBufferAddr 0xb540
#define PM3LBWriteBufferOffset 0xb548
#define PM3LBWriteFormat 0x88c8
- #define PM3LBWriteFormat_DepthWidth(w) (((w)&0x3)<<0)
- #define PM3LBWriteFormat_StencilWidth(w) (((w)&0xf)<<2)
- #define PM3LBWriteFormat_StencilPosition(p) (((p)&0x1f)<<6)
- #define PM3LBWriteFormat_GIDWidth(w) (((w)&0x7)<<20)
- #define PM3LBWriteFormat_GIDPosition(p) (((p)&0x1f)<<23)
+ #define PM3LBWriteFormat_DepthWidth(w) (((w) & 0x3) << 0)
+ #define PM3LBWriteFormat_StencilWidth(w) (((w) & 0xf) << 2)
+ #define PM3LBWriteFormat_StencilPosition(p) (((p) & 0x1f) << 6)
+ #define PM3LBWriteFormat_GIDWidth(w) (((w) & 0x7) << 20)
+ #define PM3LBWriteFormat_GIDPosition(p) (((p) & 0x1f) << 23)
#define PM3LBWriteMode 0x88c0
#define PM3LBWriteModeAnd 0xac80
#define PM3LBWriteModeOr 0xac88
- #define PM3LBWriteMode_WriteDisable 0<<0
- #define PM3LBWriteMode_WriteEnable 1<<0
- #define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3)
- #define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6)
- #define PM3LBWriteMode_Layout 1<<9
- #define PM3LBWriteMode_Origin 1<<10
- #define PM3LBWriteMode_Packed16 1<<11
- #define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12)
+ #define PM3LBWriteMode_WriteDisable (0 << 0)
+ #define PM3LBWriteMode_WriteEnable (1 << 0)
+ #define PM3LBWriteMode_StripePitch(p) (((p) & 0x7) << 3)
+ #define PM3LBWriteMode_StripeHeight(h) (((h) & 0x7) << 6)
+ #define PM3LBWriteMode_Layout (1 << 9)
+ #define PM3LBWriteMode_Origin (1 << 10)
+ #define PM3LBWriteMode_Packed16 (1 << 11)
+ #define PM3LBWriteMode_Width(w) (((w) & 0xfff) << 12)
/* ... */
#define PM3LineStippleMode 0x81a8
#define PM3LineStippleModeAnd 0xabc0
@@ -759,19 +737,16 @@
#define PM3LogicalOpMode 0x8828
#define PM3LogicalOpModeAnd 0xace0
#define PM3LogicalOpModeOr 0xace8
- #define PM3LogicalOpMode_Disable (0<<0)
- #define PM3LogicalOpMode_Enable (1<<0)
- #define PM3LogicalOpMode_LogicOp(op) (((op)&0xf)<<1)
- #define PM3LogicalOpMode_UseConstantWriteData_Disable (0<<5)
- #define PM3LogicalOpMode_UseConstantWriteData_Enable (1<<5)
- #define PM3LogicalOpMode_Background_Disable (0<<6)
- #define PM3LogicalOpMode_Background_Enable (1<<6)
- #define PM3LogicalOpMode_Background_LogicOp(op) (((op)&0xf)<<7)
- #define PM3LogicalOpMode_UseConstantSource_Disable (0<<11)
- #define PM3LogicalOpMode_UseConstantSource_Enable (1<<11)
-
-/* ... */
-#define PM3LUT 0x8e80
+ #define PM3LogicalOpMode_Disable (0 << 0)
+ #define PM3LogicalOpMode_Enable (1 << 0)
+ #define PM3LogicalOpMode_LogicOp(op) (((op) & 0xf) << 1)
+ #define PM3LogicalOpMode_UseConstantWriteData_Disable (0 << 5)
+ #define PM3LogicalOpMode_UseConstantWriteData_Enable (1 << 5)
+ #define PM3LogicalOpMode_Background_Disable (0 << 6)
+ #define PM3LogicalOpMode_Background_Enable (1 << 6)
+ #define PM3LogicalOpMode_Background_LogicOp(op) (((op) & 0xf) << 7)
+ #define PM3LogicalOpMode_UseConstantSource_Disable (0 << 11)
+ #define PM3LogicalOpMode_UseConstantSource_Enable (1 << 11)
/* ... */
#define PM3LUT 0x8e80
#define PM3LUTAddress 0x84d0
@@ -783,75 +758,74 @@
#define PM3LUTTransfer 0x84d8
/* ... */
#define PM3PixelSize 0x80c0
- #define PM3PixelSize_GLOBAL_32BIT (0<<0)
- #define PM3PixelSize_GLOBAL_16BIT (1<<0)
- #define PM3PixelSize_GLOBAL_8BIT (2<<0)
- #define PM3PixelSize_RASTERIZER_32BIT (0<<2)
- #define PM3PixelSize_RASTERIZER_16BIT (1<<2)
- #define PM3PixelSize_RASTERIZER_8BIT (2<<2)
- #define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0<<4)
- #define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1<<4)
- #define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2<<4)
- #define PM3PixelSize_TEXTURE_32BIT (0<<6)
- #define PM3PixelSize_TEXTURE_16BIT (1<<6)
- #define PM3PixelSize_TEXTURE_8BIT (2<<6)
- #define PM3PixelSize_LUT_32BIT (0<<8)
- #define PM3PixelSize_LUT_16BIT (1<<8)
- #define PM3PixelSize_LUT_8BIT (2<<8)
- #define PM3PixelSize_FRAMEBUFFER_32BIT (0<<10)
- #define PM3PixelSize_FRAMEBUFFER_16BIT (1<<10)
- #define PM3PixelSize_FRAMEBUFFER_8BIT (2<<10)
- #define PM3PixelSize_LOGICAL_OP_32BIT (0<<12)
- #define PM3PixelSize_LOGICAL_OP_16BIT (1<<12)
- #define PM3PixelSize_LOGICAL_OP_8BIT (2<<12)
- #define PM3PixelSize_LOCALBUFFER_32BIT (0<<14)
- #define PM3PixelSize_LOCALBUFFER_16BIT (1<<14)
- #define PM3PixelSize_LOCALBUFFER_8BIT (2<<14)
- #define PM3PixelSize_SETUP_32BIT (0<<16)
- #define PM3PixelSize_SETUP_16BIT (1<<16)
- #define PM3PixelSize_SETUP_8BIT (2<<16)
- #define PM3PixelSize_GLOBAL (0<<31)
- #define PM3PixelSize_INDIVIDUAL (1<<31)
+ #define PM3PixelSize_GLOBAL_32BIT (0 << 0)
+ #define PM3PixelSize_GLOBAL_16BIT (1 << 0)
+ #define PM3PixelSize_GLOBAL_8BIT (2 << 0)
+ #define PM3PixelSize_RASTERIZER_32BIT (0 << 2)
+ #define PM3PixelSize_RASTERIZER_16BIT (1 << 2)
+ #define PM3PixelSize_RASTERIZER_8BIT (2 << 2)
+ #define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0 << 4)
+ #define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1 << 4)
+ #define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2 << 4)
+ #define PM3PixelSize_TEXTURE_32BIT (0 << 6)
+ #define PM3PixelSize_TEXTURE_16BIT (1 << 6)
+ #define PM3PixelSize_TEXTURE_8BIT (2 << 6)
+ #define PM3PixelSize_LUT_32BIT (0 << 8)
+ #define PM3PixelSize_LUT_16BIT (1 << 8)
+ #define PM3PixelSize_LUT_8BIT (2 << 8)
+ #define PM3PixelSize_FRAMEBUFFER_32BIT (0 << 10)
+ #define PM3PixelSize_FRAMEBUFFER_16BIT (1 << 10)
+ #define PM3PixelSize_FRAMEBUFFER_8BIT (2 << 10)
+ #define PM3PixelSize_LOGICAL_OP_32BIT (0 << 12)
+ #define PM3PixelSize_LOGICAL_OP_16BIT (1 << 12)
+ #define PM3PixelSize_LOGICAL_OP_8BIT (2 << 12)
+ #define PM3PixelSize_LOCALBUFFER_32BIT (0 << 14)
+ #define PM3PixelSize_LOCALBUFFER_16BIT (1 << 14)
+ #define PM3PixelSize_LOCALBUFFER_8BIT (2 << 14)
+ #define PM3PixelSize_SETUP_32BIT (0 << 16)
+ #define PM3PixelSize_SETUP_16BIT (1 << 16)
+ #define PM3PixelSize_SETUP_8BIT (2 << 16)
+ #define PM3PixelSize_GLOBAL (0 << 31)
+ #define PM3PixelSize_INDIVIDUAL (1 << 31)
/* ... */
#define PM3Render 0x8038
- #define PM3Render_AreaStipple_Disable (0<<0)
- #define PM3Render_AreaStipple_Enable (1<<0)
- #define PM3Render_LineStipple_Disable (0<<1)
- #define PM3Render_LineStipple_Enable (1<<1)
- #define PM3Render_ResetLine_Disable (0<<2)
- #define PM3Render_ResetLine_Enable (1<<2)
- #define PM3Render_FastFill_Disable (0<<3)
- #define PM3Render_FastFill_Enable (1<<3)
- #define PM3Render_Primitive_Line (0<<6)
- #define PM3Render_Primitive_Trapezoid (1<<6)
- #define PM3Render_Primitive_Point (2<<6)
- #define PM3Render_Antialias_Disable (0<<8)
- #define PM3Render_Antialias_Enable (1<<8)
- #define PM3Render_Antialias_SubPixelRes_4x4 (0<<9)
- #define PM3Render_Antialias_SubPixelRes_8x8 (1<<9)
- #define PM3Render_UsePointTable_Disable (0<<10)
- #define PM3Render_UsePointTable_Enable (1<<10)
- #define PM3Render_SyncOnbitMask_Disable (0<<11)
- #define PM3Render_SyncOnBitMask_Enable (1<<11)
- #define PM3Render_SyncOnHostData_Disable (0<<12)
- #define PM3Render_SyncOnHostData_Enable (1<<12)
- #define PM3Render_Texture_Disable (0<<13)
- #define PM3Render_Texture_Enable (1<<13)
- #define PM3Render_Fog_Disable (0<<14)
- #define PM3Render_Fog_Enable (1<<14)
- #define PM3Render_Coverage_Disable (0<<15)
- #define PM3Render_Coverage_Enable (1<<15)
- #define PM3Render_SubPixelCorrection_Disable (0<<16)
- #define PM3Render_SubPixelCorrection_Enable (1<<16)
- #define PM3Render_SpanOperation_Disable (0<<18)
- #define PM3Render_SpanOperation_Enable (1<<18)
- #define PM3Render_FBSourceRead_Disable (0<<27)
- #define PM3Render_FBSourceRead_Enable (1<<27)
+ #define PM3Render_AreaStipple_Disable (0 << 0)
+ #define PM3Render_AreaStipple_Enable (1 << 0)
+ #define PM3Render_LineStipple_Disable (0 << 1)
+ #define PM3Render_LineStipple_Enable (1 << 1)
+ #define PM3Render_ResetLine_Disable (0 << 2)
+ #define PM3Render_ResetLine_Enable (1 << 2)
+ #define PM3Render_FastFill_Disable (0 << 3)
+ #define PM3Render_FastFill_Enable (1 << 3)
+ #define PM3Render_Primitive_Line (0 << 6)
+ #define PM3Render_Primitive_Trapezoid (1 << 6)
+ #define PM3Render_Primitive_Point (2 << 6)
+ #define PM3Render_Antialias_Disable (0 << 8)
+ #define PM3Render_Antialias_Enable (1 << 8)
+ #define PM3Render_Antialias_SubPixelRes_4x4 (0 << 9)
+ #define PM3Render_Antialias_SubPixelRes_8x8 (1 << 9)
+ #define PM3Render_UsePointTable_Disable (0 << 10)
+ #define PM3Render_UsePointTable_Enable (1 << 10)
+ #define PM3Render_SyncOnbitMask_Disable (0 << 11)
+ #define PM3Render_SyncOnBitMask_Enable (1 << 11)
+ #define PM3Render_SyncOnHostData_Disable (0 << 12)
+ #define PM3Render_SyncOnHostData_Enable (1 << 12)
+ #define PM3Render_Texture_Disable (0 << 13)
+ #define PM3Render_Texture_Enable (1 << 13)
+ #define PM3Render_Fog_Disable (0 << 14)
+ #define PM3Render_Fog_Enable (1 << 14)
+ #define PM3Render_Coverage_Disable (0 << 15)
+ #define PM3Render_Coverage_Enable (1 << 15)
+ #define PM3Render_SubPixelCorrection_Disable (0 << 16)
+ #define PM3Render_SubPixelCorrection_Enable (1 << 16)
+ #define PM3Render_SpanOperation_Disable (0 << 18)
+ #define PM3Render_SpanOperation_Enable (1 << 18)
+ #define PM3Render_FBSourceRead_Disable (0 << 27)
+ #define PM3Render_FBSourceRead_Enable (1 << 27)
#define PM3RasterizerMode 0x80a0
#define PM3RasterizerModeAnd 0xaba0
-#define PM3RasterizerModeOr 0xabb8
+#define PM3RasterizerModeOr 0xaba8
#define PM3RectangleHeight 0x94e0
-#define PM3Render 0x8038
#define PM3RepeatLine 0x9328
#define PM3ResetPickResult 0x8c20
#define PM3RLEMask 0x8c48
@@ -918,31 +892,31 @@
#define PM3TextureIndexMode1And 0xb3d0
#define PM3TextureIndexMode1Or 0xb3d8
/* ... */
-#define PM3TextureMapSize 0xb428
-#define PM3TextureMapWidth0 0x8580
-#define PM3TextureMapWidth1 0x8588
- #define PM3TextureMapWidth_Width(w) ((w&0xfff)<<0)
- #define PM3TextureMapWidth_BorderLayout (1<<12)
- #define PM3TextureMapWidth_Layout_Linear (0<<13)
- #define PM3TextureMapWidth_Layout_Patch64 (1<<13)
- #define PM3TextureMapWidth_Layout_Patch32_2 (2<<13)
- #define PM3TextureMapWidth_Layout_Patch2 (3<<13)
- #define PM3TextureMapWidth_HostTexture (1<<15)
-#define PM3TextureReadMode0 0xb400
-#define PM3TextureReadMode0And 0xac30
-#define PM3TextureReadMode0Or 0xac38
-#define PM3TextureReadMode1 0xb408
-#define PM3TextureReadMode1And 0xad40
-#define PM3TextureReadMode1Or 0xad48
+#define PM3TextureMapSize 0xb428
+#define PM3TextureMapWidth0 0x8580
+#define PM3TextureMapWidth1 0x8588
+ #define PM3TextureMapWidth_Width(w) (((w) & 0xfff) << 0)
+ #define PM3TextureMapWidth_BorderLayout (1 << 12)
+ #define PM3TextureMapWidth_Layout_Linear (0 << 13)
+ #define PM3TextureMapWidth_Layout_Patch64 (1 << 13)
+ #define PM3TextureMapWidth_Layout_Patch32_2 (2 << 13)
+ #define PM3TextureMapWidth_Layout_Patch2 (3 << 13)
+ #define PM3TextureMapWidth_HostTexture (1 << 15)
+#define PM3TextureReadMode0 0xb400
+#define PM3TextureReadMode0And 0xac30
+#define PM3TextureReadMode0Or 0xac38
+#define PM3TextureReadMode1 0xb408
+#define PM3TextureReadMode1And 0xad40
+#define PM3TextureReadMode1Or 0xad48
/* ... */
#define PM3WaitForCompletion 0x80b8
#define PM3Window 0x8980
- #define PM3Window_ForceLBUpdate 1<<3
- #define PM3Window_LBUpdateSource 1<<4
- #define PM3Window_FrameCount(c) (((c)&0xff)<<9)
- #define PM3Window_StencilFCP 1<<17
- #define PM3Window_DepthFCP 1<<18
- #define PM3Window_OverrideWriteFiltering 1<<19
+ #define PM3Window_ForceLBUpdate (1 << 3)
+ #define PM3Window_LBUpdateSource (1 << 4)
+ #define PM3Window_FrameCount(c) (((c) & 0xff) << 9)
+ #define PM3Window_StencilFCP (1 << 17)
+ #define PM3Window_DepthFCP (1 << 18)
+ #define PM3Window_OverrideWriteFiltering (1 << 19)
#define PM3WindowAnd 0xab80
#define PM3WindowOr 0xab88
#define PM3WindowOrigin 0x81c8
@@ -957,169 +931,131 @@
/**********************************************
-* GLINT Permedia3 2D setup Unit *
+* GLINT Permedia3 2D setup Unit *
***********************************************/
#define PM3Config2D 0xb618
- #define PM3Config2D_OpaqueSpan 1<<0
- #define PM3Config2D_MultiRXBlit 1<<1
- #define PM3Config2D_UserScissorEnable 1<<2
- #define PM3Config2D_FBDestReadEnable 1<<3
- #define PM3Config2D_AlphaBlendEnable 1<<4
- #define PM3Config2D_DitherEnable 1<<5
- #define PM3Config2D_ForegroundROPEnable 1<<6
- #define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7)
- #define PM3Config2D_BackgroundROPEnable 1<<11
- #define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12)
- #define PM3Config2D_UseConstantSource 1<<16
- #define PM3Config2D_FBWriteEnable 1<<17
- #define PM3Config2D_Blocking 1<<18
- #define PM3Config2D_ExternalSourceData 1<<19
- #define PM3Config2D_LUTModeEnable 1<<20
+ #define PM3Config2D_OpaqueSpan (1 << 0)
+ #define PM3Config2D_MultiRXBlit (1 << 1)
+ #define PM3Config2D_UserScissorEnable (1 << 2)
+ #define PM3Config2D_FBDestReadEnable (1 << 3)
+ #define PM3Config2D_AlphaBlendEnable (1 << 4)
+ #define PM3Config2D_DitherEnable (1 << 5)
+ #define PM3Config2D_ForegroundROPEnable (1 << 6)
+ #define PM3Config2D_ForegroundROP(rop) (((rop) & 0xf) << 7)
+ #define PM3Config2D_BackgroundROPEnable (1 << 11)
+ #define PM3Config2D_BackgroundROP(rop) (((rop) & 0xf) << 12)
+ #define PM3Config2D_UseConstantSource (1 << 16)
+ #define PM3Config2D_FBWriteEnable (1 << 17)
+ #define PM3Config2D_Blocking (1 << 18)
+ #define PM3Config2D_ExternalSourceData (1 << 19)
+ #define PM3Config2D_LUTModeEnable (1 << 20)
#define PM3DownloadGlyphwidth 0xb658
- #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff)
+ #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw) & 0xffff)
#define PM3DownloadTarget 0xb650
- #define PM3DownloadTarget_TagName(tag) ((tag)&0x1fff)
+ #define PM3DownloadTarget_TagName(tag) ((tag) & 0x1fff)
#define PM3GlyphData 0xb660
#define PM3GlyphPosition 0xb608
- #define PM3GlyphPosition_XOffset(x) ((x)&0xffff)
- #define PM3GlyphPosition_YOffset(y) (((y)&0xffff)<<16)
+ #define PM3GlyphPosition_XOffset(x) ((x) & 0xffff)
+ #define PM3GlyphPosition_YOffset(y) (((y) & 0xffff) << 16)
#define PM3Packed4Pixels 0xb668
#define PM3Packed8Pixels 0xb630
#define PM3Packed16Pixels 0xb638
#define PM3RectanglePosition 0xb600
- #define PM3RectanglePosition_XOffset(x) ((x)&0xffff)
- #define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16)
+ #define PM3RectanglePosition_XOffset(x) ((x) & 0xffff)
+ #define PM3RectanglePosition_YOffset(y) (((y) & 0xffff) << 16)
#define PM3Render2D 0xb640
- #define PM3Render2D_Width(w) ((w)&0x0fff)
- #define PM3Render2D_Operation_Normal 0<<12
- #define PM3Render2D_Operation_SyncOnHostData 1<<12
- #define PM3Render2D_Operation_SyncOnBitMask 2<<12
- #define PM3Render2D_Operation_PatchOrderRendering 3<<12
- #define PM3Render2D_FBSourceReadEnable 1<<14
- #define PM3Render2D_SpanOperation 1<<15
- #define PM3Render2D_Height(h) (((h)&0x0fff)<<16)
- #define PM3Render2D_XPositive 1<<28
- #define PM3Render2D_YPositive 1<<29
- #define PM3Render2D_AreaStippleEnable 1<<30
- #define PM3Render2D_TextureEnable 1<<31
+ #define PM3Render2D_Width(w) ((w) & 0x0fff)
+ #define PM3Render2D_Operation_Normal (0 << 12)
+ #define PM3Render2D_Operation_SyncOnHostData (1 << 12)
+ #define PM3Render2D_Operation_SyncOnBitMask (2 << 12)
+ #define PM3Render2D_Operation_PatchOrderRendering (3 << 12)
+ #define PM3Render2D_FBSourceReadEnable (1 << 14)
+ #define PM3Render2D_SpanOperation (1 << 15)
+ #define PM3Render2D_Height(h) (((h) & 0x0fff) << 16)
+ #define PM3Render2D_XPositive (1 << 28)
+ #define PM3Render2D_YPositive (1 << 29)
+ #define PM3Render2D_AreaStippleEnable (1 << 30)
+ #define PM3Render2D_TextureEnable (1 << 31)
#define PM3Render2DGlyph 0xb648
- #define PM3Render2DGlyph_Width(w) ((w)&0x7f)
- #define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7)
- #define PM3Render2DGlyph_XOffset(x) (((x)&0x1ff)<<14)
- #define PM3Render2DGlyph_YOffset(y) (((y)&0x1ff)<<23)
+ #define PM3Render2DGlyph_Width(w) ((w) & 0x7f)
+ #define PM3Render2DGlyph_Height(h) (((h) & 0x7f) << 7)
+ #define PM3Render2DGlyph_XOffset(x) (((x) & 0x1ff) << 14)
+ #define PM3Render2DGlyph_YOffset(y) (((y) & 0x1ff) << 23)
#define PM3RenderPatchOffset 0xb610
- #define PM3RenderPatchOffset_XOffset(x) ((x)&0xffff)
- #define PM3RenderPatchOffset_YOffset(y) (((y)&0xffff)<<16)
+ #define PM3RenderPatchOffset_XOffset(x) ((x) & 0xffff)
+ #define PM3RenderPatchOffset_YOffset(y) (((y) & 0xffff) << 16)
#define PM3RLCount 0xb678
- #define PM3RLCount_Count(c) ((c)&0x0fff)
+ #define PM3RLCount_Count(c) ((c) & 0x0fff)
#define PM3RLData 0xb670
/**********************************************
-* GLINT Permedia3 Alias Register *
+* GLINT Permedia3 Alias Register *
***********************************************/
-#define PM3FillBackgroundColor 0x8330
-#define PM3FillConfig2D0 0x8338
-#define PM3FillConfig2D1 0x8360
- #define PM3FillConfig2D_OpaqueSpan 1<<0
- #define PM3FillConfig2D_MultiRXBlit 1<<1
- #define PM3FillConfig2D_UserScissorEnable 1<<2
- #define PM3FillConfig2D_FBDestReadEnable 1<<3
- #define PM3FillConfig2D_AlphaBlendEnable 1<<4
- #define PM3FillConfig2D_DitherEnable 1<<5
- #define PM3FillConfig2D_ForegroundROPEnable 1<<6
- #define PM3FillConfig2D_ForegroundROP(rop) (((rop)&0xf)<<7)
- #define PM3FillConfig2D_BackgroundROPEnable 1<<11
- #define PM3FillConfig2D_BackgroundROP(rop) (((rop)&0xf)<<12)
- #define PM3FillConfig2D_UseConstantSource 1<<16
- #define PM3FillConfig2D_FBWriteEnable 1<<17
- #define PM3FillConfig2D_Blocking 1<<18
- #define PM3FillConfig2D_ExternalSourceData 1<<19
- #define PM3FillConfig2D_LUTModeEnable 1<<20
-#define PM3FillFBDestReadBufferAddr 0x8310
-#define PM3FillFBSourceReadBufferAddr 0x8308
-#define PM3FillFBSourceReadBufferOffset 0x8340
- #define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x)&0xffff)
- #define PM3FillFBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16)
-#define PM3FillFBWriteBufferAddr 0x8300
-#define PM3FillForegroundColor0 0x8328
-#define PM3FillForegroundColor1 0x8358
-#define PM3FillGlyphPosition 0x8368
- #define PM3FillGlyphPosition_XOffset(x) ((x)&0xffff)
- #define PM3FillGlyphPosition_YOffset(y) (((y)&0xffff)<<16)
-#define PM3FillRectanglePosition 0x8348
- #define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff)
- #define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16)
+#define PM3FillBackgroundColor 0x8330
+#define PM3FillConfig2D0 0x8338
+#define PM3FillConfig2D1 0x8360
+ #define PM3FillConfig2D_OpaqueSpan (1 << 0)
+ #define PM3FillConfig2D_MultiRXBlit (1 << 1)
+ #define PM3FillConfig2D_UserScissorEnable (1 << 2)
+ #define PM3FillConfig2D_FBDestReadEnable (1 << 3)
+ #define PM3FillConfig2D_AlphaBlendEnable (1 << 4)
+ #define PM3FillConfig2D_DitherEnable (1 << 5)
+ #define PM3FillConfig2D_ForegroundROPEnable (1 << 6)
+ #define PM3FillConfig2D_ForegroundROP(rop) (((rop) & 0xf) << 7)
+ #define PM3FillConfig2D_BackgroundROPEnable (1 << 11)
+ #define PM3FillConfig2D_BackgroundROP(rop) (((rop) & 0xf) << 12)
+ #define PM3FillConfig2D_UseConstantSource (1 << 16)
+ #define PM3FillConfig2D_FBWriteEnable (1 << 17)
+ #define PM3FillConfig2D_Blocking (1 << 18)
+ #define PM3FillConfig2D_ExternalSourceData (1 << 19)
+ #define PM3FillConfig2D_LUTModeEnable (1 << 20)
+#define PM3FillFBDestReadBufferAddr 0x8310
+#define PM3FillFBSourceReadBufferAddr 0x8308
+#define PM3FillFBSourceReadBufferOffset 0x8340
+ #define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x) & 0xffff)
+ #define PM3FillFBSourceReadBufferOffset_YOffset(y) \
+ (((y) & 0xffff) << 16)
+#define PM3FillFBWriteBufferAddr 0x8300
+#define PM3FillForegroundColor0 0x8328
+#define PM3FillForegroundColor1 0x8358
+#define PM3FillGlyphPosition 0x8368
+ #define PM3FillGlyphPosition_XOffset(x) ((x) & 0xffff)
+ #define PM3FillGlyphPosition_YOffset(y) (((y) & 0xffff) << 16)
+#define PM3FillRectanglePosition 0x8348
+ #define PM3FillRectanglePosition_XOffset(x) ((x) & 0xffff)
+ #define PM3FillRectanglePosition_YOffset(y) (((y) & 0xffff) << 16)
-#define PM3_REGS_SIZE 0x10000
-#define PM3_MAX_PIXCLOCK 300000
/* a few more useful registers & regs value... */
-#define PM3Sync 0x8c40
- #define PM3Sync_Tag 0x188
-#define PM3FilterMode 0x8c00
- #define PM3FilterModeSync 0x400
-#define PM3OutputFifo 0x2000
-#define PM3StatisticMode 0x8c08
-#define PM3AreaStippleMode 0x81a0
- #define AreaStipplePattern0 (0x8200)
- #define AreaStipplePattern1 (0x8208)
- #define AreaStipplePattern2 (0x8210)
- #define AreaStipplePattern3 (0x8218)
- #define AreaStipplePattern4 (0x8220)
- #define AreaStipplePattern5 (0x8228)
- #define AreaStipplePattern6 (0x8230)
- #define AreaStipplePattern7 (0x8238)
- #define AreaStipplePattern8 (0x8240)
- #define AreaStipplePattern9 (0x8248)
- #define AreaStipplePattern10 (0x8250)
- #define AreaStipplePattern11 (0x8258)
- #define AreaStipplePattern12 (0x8260)
- #define AreaStipplePattern13 (0x8268)
- #define AreaStipplePattern14 (0x8270)
- #define AreaStipplePattern15 (0x8278)
- #define AreaStipplePattern16 (0x8280)
- #define AreaStipplePattern17 (0x8288)
- #define AreaStipplePattern18 (0x8290)
- #define AreaStipplePattern19 (0x8298)
- #define AreaStipplePattern20 (0x82a0)
- #define AreaStipplePattern21 (0x82a8)
- #define AreaStipplePattern22 (0x82b0)
- #define AreaStipplePattern23 (0x82b8)
- #define AreaStipplePattern24 (0x82c0)
- #define AreaStipplePattern25 (0x82c8)
- #define AreaStipplePattern26 (0x82d0)
- #define AreaStipplePattern27 (0x82d8)
- #define AreaStipplePattern28 (0x82eo)
- #define AreaStipplePattern29 (0x82e8)
- #define AreaStipplePattern30 (0x82f0)
- #define AreaStipplePattern31 (0x82f8)
- #define AreaStipplePattern_indexed(i) (0x8200 + ((i) * 0x8))
+#define PM3Sync 0x8c40
+ #define PM3Sync_Tag 0x188
+#define PM3FilterMode 0x8c00
+ #define PM3FilterModeSync 0x400
+#define PM3OutputFifo 0x2000
+#define PM3StatisticMode 0x8c08
+#define PM3AreaStippleMode 0x81a0
+#define AreaStipplePattern_indexed(i) (0x8200 + ((i) * 0x8))
-#define PM3DepthMode 0x89a0
-#define PM3StencilMode 0x8988
-#define PM3StencilData 0x8990
-#define PM3TextureReadMode 0x8670
-#define PM3FogMode 0x8690
-#define PM3ChromaTestMode 0x8f18
-#define PM3YUVMode 0x8f00
-#define PM3BitMaskPattern 0x8068
+#define PM3DepthMode 0x89a0
+#define PM3StencilMode 0x8988
+#define PM3StencilData 0x8990
+#define PM3TextureReadMode 0x8670
+#define PM3FogMode 0x8690
+#define PM3ChromaTestMode 0x8f18
+#define PM3YUVMode 0x8f00
+#define PM3BitMaskPattern 0x8068
/* ***************************** */
/* ***** pm3fb IOCTL const ***** */
/* ***************************** */
-/* debug-only IOCTL */
-#define PM3FBIO_CLEARMEMORY 0x504D3300 /* 'PM3\000' */
-#define PM3FBIO_CLEARCMAP 0x504D3301 /* 'PM3\001' */
-/* common use IOCTL */
-#define PM3FBIO_RESETCHIP 0x504D33FF /* 'PM3\377' */
+#define PM3FBIO_RESETCHIP 0x504D33FF /* 'PM3\377' */
/* ***************************************** */
/* ***** pm3fb useful define and macro ***** */
/* ***************************************** */
-/* max size of options */
-#define PM3_OPTIONS_SIZE 256
-
-/* max size of font name */
-#define PM3_FONTNAME_SIZE 40
+/* fifo size in chip */
+#define PM3_FIFO_SIZE 120
+#define PM3_REGS_SIZE 0x10000
+#define PM3_MAX_PIXCLOCK 300000
#endif /* PM3FB_H */
diff --git a/include/video/tdfx.h b/include/video/tdfx.h
index c1cc94ba3fd..05b63c2a5ab 100644
--- a/include/video/tdfx.h
+++ b/include/video/tdfx.h
@@ -2,140 +2,140 @@
#define _TDFX_H
/* membase0 register offsets */
-#define STATUS 0x00
-#define PCIINIT0 0x04
-#define SIPMONITOR 0x08
-#define LFBMEMORYCONFIG 0x0c
-#define MISCINIT0 0x10
-#define MISCINIT1 0x14
-#define DRAMINIT0 0x18
-#define DRAMINIT1 0x1c
-#define AGPINIT 0x20
-#define TMUGBEINIT 0x24
-#define VGAINIT0 0x28
-#define VGAINIT1 0x2c
-#define DRAMCOMMAND 0x30
-#define DRAMDATA 0x34
-/* reserved 0x38 */
-/* reserved 0x3c */
-#define PLLCTRL0 0x40
-#define PLLCTRL1 0x44
-#define PLLCTRL2 0x48
-#define DACMODE 0x4c
-#define DACADDR 0x50
-#define DACDATA 0x54
-#define RGBMAXDELTA 0x58
-#define VIDPROCCFG 0x5c
-#define HWCURPATADDR 0x60
-#define HWCURLOC 0x64
-#define HWCURC0 0x68
-#define HWCURC1 0x6c
-#define VIDINFORMAT 0x70
-#define VIDINSTATUS 0x74
-#define VIDSERPARPORT 0x78
-#define VIDINXDELTA 0x7c
-#define VIDININITERR 0x80
-#define VIDINYDELTA 0x84
-#define VIDPIXBUFTHOLD 0x88
-#define VIDCHRMIN 0x8c
-#define VIDCHRMAX 0x90
-#define VIDCURLIN 0x94
-#define VIDSCREENSIZE 0x98
-#define VIDOVRSTARTCRD 0x9c
-#define VIDOVRENDCRD 0xa0
-#define VIDOVRDUDX 0xa4
-#define VIDOVRDUDXOFF 0xa8
-#define VIDOVRDVDY 0xac
-/* ... */
-#define VIDOVRDVDYOFF 0xe0
-#define VIDDESKSTART 0xe4
-#define VIDDESKSTRIDE 0xe8
-#define VIDINADDR0 0xec
-#define VIDINADDR1 0xf0
-#define VIDINADDR2 0xf4
-#define VIDINSTRIDE 0xf8
-#define VIDCUROVRSTART 0xfc
-
-#define INTCTRL (0x00100000 + 0x04)
-#define CLIP0MIN (0x00100000 + 0x08)
-#define CLIP0MAX (0x00100000 + 0x0c)
-#define DSTBASE (0x00100000 + 0x10)
-#define DSTFORMAT (0x00100000 + 0x14)
-#define SRCBASE (0x00100000 + 0x34)
-#define COMMANDEXTRA_2D (0x00100000 + 0x38)
-#define CLIP1MIN (0x00100000 + 0x4c)
-#define CLIP1MAX (0x00100000 + 0x50)
-#define SRCFORMAT (0x00100000 + 0x54)
-#define SRCSIZE (0x00100000 + 0x58)
-#define SRCXY (0x00100000 + 0x5c)
-#define COLORBACK (0x00100000 + 0x60)
-#define COLORFORE (0x00100000 + 0x64)
-#define DSTSIZE (0x00100000 + 0x68)
-#define DSTXY (0x00100000 + 0x6c)
-#define COMMAND_2D (0x00100000 + 0x70)
-#define LAUNCH_2D (0x00100000 + 0x80)
-
-#define COMMAND_3D (0x00200000 + 0x120)
+#define STATUS 0x00
+#define PCIINIT0 0x04
+#define SIPMONITOR 0x08
+#define LFBMEMORYCONFIG 0x0c
+#define MISCINIT0 0x10
+#define MISCINIT1 0x14
+#define DRAMINIT0 0x18
+#define DRAMINIT1 0x1c
+#define AGPINIT 0x20
+#define TMUGBEINIT 0x24
+#define VGAINIT0 0x28
+#define VGAINIT1 0x2c
+#define DRAMCOMMAND 0x30
+#define DRAMDATA 0x34
+/* reserved 0x38 */
+/* reserved 0x3c */
+#define PLLCTRL0 0x40
+#define PLLCTRL1 0x44
+#define PLLCTRL2 0x48
+#define DACMODE 0x4c
+#define DACADDR 0x50
+#define DACDATA 0x54
+#define RGBMAXDELTA 0x58
+#define VIDPROCCFG 0x5c
+#define HWCURPATADDR 0x60
+#define HWCURLOC 0x64
+#define HWCURC0 0x68
+#define HWCURC1 0x6c
+#define VIDINFORMAT 0x70
+#define VIDINSTATUS 0x74
+#define VIDSERPARPORT 0x78
+#define VIDINXDELTA 0x7c
+#define VIDININITERR 0x80
+#define VIDINYDELTA 0x84
+#define VIDPIXBUFTHOLD 0x88
+#define VIDCHRMIN 0x8c
+#define VIDCHRMAX 0x90
+#define VIDCURLIN 0x94
+#define VIDSCREENSIZE 0x98
+#define VIDOVRSTARTCRD 0x9c
+#define VIDOVRENDCRD 0xa0
+#define VIDOVRDUDX 0xa4
+#define VIDOVRDUDXOFF 0xa8
+#define VIDOVRDVDY 0xac
+/* ... */
+#define VIDOVRDVDYOFF 0xe0
+#define VIDDESKSTART 0xe4
+#define VIDDESKSTRIDE 0xe8
+#define VIDINADDR0 0xec
+#define VIDINADDR1 0xf0
+#define VIDINADDR2 0xf4
+#define VIDINSTRIDE 0xf8
+#define VIDCUROVRSTART 0xfc
+
+#define INTCTRL (0x00100000 + 0x04)
+#define CLIP0MIN (0x00100000 + 0x08)
+#define CLIP0MAX (0x00100000 + 0x0c)
+#define DSTBASE (0x00100000 + 0x10)
+#define DSTFORMAT (0x00100000 + 0x14)
+#define SRCBASE (0x00100000 + 0x34)
+#define COMMANDEXTRA_2D (0x00100000 + 0x38)
+#define CLIP1MIN (0x00100000 + 0x4c)
+#define CLIP1MAX (0x00100000 + 0x50)
+#define SRCFORMAT (0x00100000 + 0x54)
+#define SRCSIZE (0x00100000 + 0x58)
+#define SRCXY (0x00100000 + 0x5c)
+#define COLORBACK (0x00100000 + 0x60)
+#define COLORFORE (0x00100000 + 0x64)
+#define DSTSIZE (0x00100000 + 0x68)
+#define DSTXY (0x00100000 + 0x6c)
+#define COMMAND_2D (0x00100000 + 0x70)
+#define LAUNCH_2D (0x00100000 + 0x80)
+
+#define COMMAND_3D (0x00200000 + 0x120)
/* register bitfields (not all, only as needed) */
-#define BIT(x) (1UL << (x))
+#define BIT(x) (1UL << (x))
/* COMMAND_2D reg. values */
-#define TDFX_ROP_COPY 0xcc // src
-#define TDFX_ROP_INVERT 0x55 // NOT dst
-#define TDFX_ROP_XOR 0x66 // src XOR dst
-
-#define AUTOINC_DSTX BIT(10)
-#define AUTOINC_DSTY BIT(11)
-#define COMMAND_2D_FILLRECT 0x05
-#define COMMAND_2D_S2S_BITBLT 0x01 // screen to screen
-#define COMMAND_2D_H2S_BITBLT 0x03 // host to screen
-
-#define COMMAND_3D_NOP 0x00
-#define STATUS_RETRACE BIT(6)
-#define STATUS_BUSY BIT(9)
-#define MISCINIT1_CLUT_INV BIT(0)
-#define MISCINIT1_2DBLOCK_DIS BIT(15)
-#define DRAMINIT0_SGRAM_NUM BIT(26)
-#define DRAMINIT0_SGRAM_TYPE BIT(27)
-#define DRAMINIT0_SGRAM_TYPE_MASK (BIT(27)|BIT(28)|BIT(29))
+#define TDFX_ROP_COPY 0xcc /* src */
+#define TDFX_ROP_INVERT 0x55 /* NOT dst */
+#define TDFX_ROP_XOR 0x66 /* src XOR dst */
+
+#define AUTOINC_DSTX BIT(10)
+#define AUTOINC_DSTY BIT(11)
+#define COMMAND_2D_FILLRECT 0x05
+#define COMMAND_2D_S2S_BITBLT 0x01 /* screen to screen */
+#define COMMAND_2D_H2S_BITBLT 0x03 /* host to screen */
+
+#define COMMAND_3D_NOP 0x00
+#define STATUS_RETRACE BIT(6)
+#define STATUS_BUSY BIT(9)
+#define MISCINIT1_CLUT_INV BIT(0)
+#define MISCINIT1_2DBLOCK_DIS BIT(15)
+#define DRAMINIT0_SGRAM_NUM BIT(26)
+#define DRAMINIT0_SGRAM_TYPE BIT(27)
+#define DRAMINIT0_SGRAM_TYPE_MASK (BIT(27) | BIT(28) | BIT(29))
#define DRAMINIT0_SGRAM_TYPE_SHIFT 27
-#define DRAMINIT1_MEM_SDRAM BIT(30)
-#define VGAINIT0_VGA_DISABLE BIT(0)
-#define VGAINIT0_EXT_TIMING BIT(1)
-#define VGAINIT0_8BIT_DAC BIT(2)
-#define VGAINIT0_EXT_ENABLE BIT(6)
-#define VGAINIT0_WAKEUP_3C3 BIT(8)
-#define VGAINIT0_LEGACY_DISABLE BIT(9)
-#define VGAINIT0_ALT_READBACK BIT(10)
-#define VGAINIT0_FAST_BLINK BIT(11)
-#define VGAINIT0_EXTSHIFTOUT BIT(12)
-#define VGAINIT0_DECODE_3C6 BIT(13)
-#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
-#define VGAINIT1_MASK 0x1fffff
-#define VIDCFG_VIDPROC_ENABLE BIT(0)
-#define VIDCFG_CURS_X11 BIT(1)
-#define VIDCFG_INTERLACE BIT(3)
-#define VIDCFG_HALF_MODE BIT(4)
-#define VIDCFG_DESK_ENABLE BIT(7)
-#define VIDCFG_CLUT_BYPASS BIT(10)
-#define VIDCFG_2X BIT(26)
-#define VIDCFG_HWCURSOR_ENABLE BIT(27)
+#define DRAMINIT1_MEM_SDRAM BIT(30)
+#define VGAINIT0_VGA_DISABLE BIT(0)
+#define VGAINIT0_EXT_TIMING BIT(1)
+#define VGAINIT0_8BIT_DAC BIT(2)
+#define VGAINIT0_EXT_ENABLE BIT(6)
+#define VGAINIT0_WAKEUP_3C3 BIT(8)
+#define VGAINIT0_LEGACY_DISABLE BIT(9)
+#define VGAINIT0_ALT_READBACK BIT(10)
+#define VGAINIT0_FAST_BLINK BIT(11)
+#define VGAINIT0_EXTSHIFTOUT BIT(12)
+#define VGAINIT0_DECODE_3C6 BIT(13)
+#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
+#define VGAINIT1_MASK 0x1fffff
+#define VIDCFG_VIDPROC_ENABLE BIT(0)
+#define VIDCFG_CURS_X11 BIT(1)
+#define VIDCFG_INTERLACE BIT(3)
+#define VIDCFG_HALF_MODE BIT(4)
+#define VIDCFG_DESK_ENABLE BIT(7)
+#define VIDCFG_CLUT_BYPASS BIT(10)
+#define VIDCFG_2X BIT(26)
+#define VIDCFG_HWCURSOR_ENABLE BIT(27)
#define VIDCFG_PIXFMT_SHIFT 18
-#define DACMODE_2X BIT(0)
+#define DACMODE_2X BIT(0)
/* VGA rubbish, need to change this for multihead support */
-#define MISC_W 0x3c2
-#define MISC_R 0x3cc
-#define SEQ_I 0x3c4
-#define SEQ_D 0x3c5
-#define CRT_I 0x3d4
-#define CRT_D 0x3d5
-#define ATT_IW 0x3c0
-#define IS1_R 0x3da
-#define GRA_I 0x3ce
-#define GRA_D 0x3cf
+#define MISC_W 0x3c2
+#define MISC_R 0x3cc
+#define SEQ_I 0x3c4
+#define SEQ_D 0x3c5
+#define CRT_I 0x3d4
+#define CRT_D 0x3d5
+#define ATT_IW 0x3c0
+#define IS1_R 0x3da
+#define GRA_I 0x3ce
+#define GRA_D 0x3cf
#ifdef __KERNEL__
@@ -143,9 +143,9 @@ struct banshee_reg {
/* VGA rubbish */
unsigned char att[21];
unsigned char crt[25];
- unsigned char gra[ 9];
+ unsigned char gra[9];
unsigned char misc[1];
- unsigned char seq[ 5];
+ unsigned char seq[5];
/* Banshee extensions */
unsigned char ext[2];
@@ -167,8 +167,6 @@ struct banshee_reg {
unsigned long clip0max;
unsigned long clip1min;
unsigned long clip1max;
- unsigned long srcbase;
- unsigned long dstbase;
unsigned long miscinit0;
};
@@ -177,18 +175,10 @@ struct tdfx_par {
u32 palette[16];
void __iomem *regbase_virt;
unsigned long iobase;
- u32 baseline;
-
- struct {
- int w,u,d;
- unsigned long enable,disable;
- struct timer_list timer;
- } hwcursor;
-
- spinlock_t DAClock;
+ int mtrr_handle;
};
-#endif /* __KERNEL__ */
+#endif /* __KERNEL__ */
-#endif /* _TDFX_H */
+#endif /* _TDFX_H */
diff --git a/include/video/uvesafb.h b/include/video/uvesafb.h
new file mode 100644
index 00000000000..95bcef19395
--- /dev/null
+++ b/include/video/uvesafb.h
@@ -0,0 +1,193 @@
+#ifndef _UVESAFB_H
+#define _UVESAFB_H
+
+struct v86_regs {
+ __u32 ebx;
+ __u32 ecx;
+ __u32 edx;
+ __u32 esi;
+ __u32 edi;
+ __u32 ebp;
+ __u32 eax;
+ __u32 eip;
+ __u32 eflags;
+ __u32 esp;
+ __u16 cs;
+ __u16 ss;
+ __u16 es;
+ __u16 ds;
+ __u16 fs;
+ __u16 gs;
+};
+
+/* Task flags */
+#define TF_VBEIB 0x01
+#define TF_BUF_ESDI 0x02
+#define TF_BUF_ESBX 0x04
+#define TF_BUF_RET 0x08
+#define TF_EXIT 0x10
+
+struct uvesafb_task {
+ __u8 flags;
+ int buf_len;
+ struct v86_regs regs;
+};
+
+/* Constants for the capabilities field
+ * in vbe_ib */
+#define VBE_CAP_CAN_SWITCH_DAC 0x01
+#define VBE_CAP_VGACOMPAT 0x02
+
+/* The VBE Info Block */
+struct vbe_ib {
+ char vbe_signature[4];
+ __u16 vbe_version;
+ __u32 oem_string_ptr;
+ __u32 capabilities;
+ __u32 mode_list_ptr;
+ __u16 total_memory;
+ __u16 oem_software_rev;
+ __u32 oem_vendor_name_ptr;
+ __u32 oem_product_name_ptr;
+ __u32 oem_product_rev_ptr;
+ __u8 reserved[222];
+ char oem_data[256];
+ char misc_data[512];
+} __attribute__ ((packed));
+
+#ifdef __KERNEL__
+
+/* VBE CRTC Info Block */
+struct vbe_crtc_ib {
+ u16 horiz_total;
+ u16 horiz_start;
+ u16 horiz_end;
+ u16 vert_total;
+ u16 vert_start;
+ u16 vert_end;
+ u8 flags;
+ u32 pixel_clock;
+ u16 refresh_rate;
+ u8 reserved[40];
+} __attribute__ ((packed));
+
+#define VBE_MODE_VGACOMPAT 0x20
+#define VBE_MODE_COLOR 0x08
+#define VBE_MODE_SUPPORTEDHW 0x01
+#define VBE_MODE_GRAPHICS 0x10
+#define VBE_MODE_LFB 0x80
+
+#define VBE_MODE_MASK (VBE_MODE_COLOR | VBE_MODE_SUPPORTEDHW | \
+ VBE_MODE_GRAPHICS | VBE_MODE_LFB)
+
+/* VBE Mode Info Block */
+struct vbe_mode_ib {
+ /* for all VBE revisions */
+ u16 mode_attr;
+ u8 winA_attr;
+ u8 winB_attr;
+ u16 win_granularity;
+ u16 win_size;
+ u16 winA_seg;
+ u16 winB_seg;
+ u32 win_func_ptr;
+ u16 bytes_per_scan_line;
+
+ /* for VBE 1.2+ */
+ u16 x_res;
+ u16 y_res;
+ u8 x_char_size;
+ u8 y_char_size;
+ u8 planes;
+ u8 bits_per_pixel;
+ u8 banks;
+ u8 memory_model;
+ u8 bank_size;
+ u8 image_pages;
+ u8 reserved1;
+
+ /* Direct color fields for direct/6 and YUV/7 memory models. */
+ /* Offsets are bit positions of lsb in the mask. */
+ u8 red_len;
+ u8 red_off;
+ u8 green_len;
+ u8 green_off;
+ u8 blue_len;
+ u8 blue_off;
+ u8 rsvd_len;
+ u8 rsvd_off;
+ u8 direct_color_info; /* direct color mode attributes */
+
+ /* for VBE 2.0+ */
+ u32 phys_base_ptr;
+ u8 reserved2[6];
+
+ /* for VBE 3.0+ */
+ u16 lin_bytes_per_scan_line;
+ u8 bnk_image_pages;
+ u8 lin_image_pages;
+ u8 lin_red_len;
+ u8 lin_red_off;
+ u8 lin_green_len;
+ u8 lin_green_off;
+ u8 lin_blue_len;
+ u8 lin_blue_off;
+ u8 lin_rsvd_len;
+ u8 lin_rsvd_off;
+ u32 max_pixel_clock;
+ u16 mode_id;
+ u8 depth;
+} __attribute__ ((packed));
+
+#define UVESAFB_DEFAULT_MODE "640x480-16"
+
+/* How long to wait for a reply from userspace [ms] */
+#define UVESAFB_TIMEOUT 5000
+
+/* Max number of concurrent tasks */
+#define UVESAFB_TASKS_MAX 16
+
+#define dac_reg (0x3c8)
+#define dac_val (0x3c9)
+
+struct uvesafb_pal_entry {
+ u_char blue, green, red, pad;
+} __attribute__ ((packed));
+
+struct uvesafb_ktask {
+ struct uvesafb_task t;
+ void *buf;
+ struct completion *done;
+ u32 ack;
+};
+
+static int uvesafb_exec(struct uvesafb_ktask *tsk);
+
+#define UVESAFB_EXACT_RES 1
+#define UVESAFB_EXACT_DEPTH 2
+
+struct uvesafb_par {
+ struct vbe_ib vbe_ib; /* VBE Info Block */
+ struct vbe_mode_ib *vbe_modes; /* list of supported VBE modes */
+ int vbe_modes_cnt;
+
+ u8 nocrtc;
+ u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
+ u8 pmi_setpal; /* PMI for palette changes */
+ u16 *pmi_base; /* protected mode interface location */
+ void *pmi_start;
+ void *pmi_pal;
+ u8 *vbe_state_orig; /*
+ * original hardware state, before the
+ * driver was loaded
+ */
+ u8 *vbe_state_saved; /* state saved by fb_save_state */
+ int vbe_state_size;
+ atomic_t ref_count;
+
+ int mode_idx;
+ struct vbe_crtc_ib crtc;
+};
+
+#endif /* __KERNEL__ */
+#endif /* _UVESAFB_H */
diff --git a/include/xen/interface/vcpu.h b/include/xen/interface/vcpu.h
index ff61ea36599..b05d8a6d914 100644
--- a/include/xen/interface/vcpu.h
+++ b/include/xen/interface/vcpu.h
@@ -160,8 +160,9 @@ struct vcpu_set_singleshot_timer {
*/
#define VCPUOP_register_vcpu_info 10 /* arg == struct vcpu_info */
struct vcpu_register_vcpu_info {
- uint32_t mfn; /* mfn of page to place vcpu_info */
- uint32_t offset; /* offset within page */
+ uint64_t mfn; /* mfn of page to place vcpu_info */
+ uint32_t offset; /* offset within page */
+ uint32_t rsvd; /* unused */
};
#endif /* __XEN_PUBLIC_VCPU_H__ */
diff --git a/init/Kconfig b/init/Kconfig
index 54f31a191b8..a29a688c47d 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -689,3 +689,6 @@ config STOP_MACHINE
Need stop_machine() primitive.
source "block/Kconfig"
+
+config PREEMPT_NOTIFIERS
+ bool
diff --git a/init/Makefile b/init/Makefile
index 0154aea1e52..633392f5cde 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -30,4 +30,4 @@ $(obj)/version.o: include/linux/compile.h
include/linux/compile.h: FORCE
@echo ' CHK $@'
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \
- "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)"
+ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)"
diff --git a/init/calibrate.c b/init/calibrate.c
index 40ff3b40489..2d3d73bd4ce 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -10,7 +10,7 @@
#include <asm/timex.h>
-static unsigned long preset_lpj;
+unsigned long preset_lpj;
static int __init lpj_setup(char *str)
{
preset_lpj = simple_strtoul(str,NULL,0);
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index ed652f40f07..3ac5904d1b1 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -57,7 +57,7 @@ identify_ramdisk_image(int fd, int start_block)
unsigned char *buf;
buf = kmalloc(size, GFP_KERNEL);
- if (buf == 0)
+ if (!buf)
return -1;
minixsb = (struct minix_super_block *) buf;
@@ -407,12 +407,12 @@ static int __init crd_load(int in_fd, int out_fd)
crd_infd = in_fd;
crd_outfd = out_fd;
inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
- if (inbuf == 0) {
+ if (!inbuf) {
printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
return -1;
}
window = kmalloc(WSIZE, GFP_KERNEL);
- if (window == 0) {
+ if (!window) {
printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
kfree(inbuf);
return -1;
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index a88934a1b76..79e24e878c1 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -15,7 +15,6 @@
#include <linux/sysctl.h>
#include <linux/uaccess.h>
-#ifdef CONFIG_IPC_NS
static void *get_ipc(ctl_table *table)
{
char *which = table->data;
@@ -23,9 +22,6 @@ static void *get_ipc(ctl_table *table)
which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
return which;
}
-#else
-#define get_ipc(T) ((T)->data)
-#endif
#ifdef CONFIG_PROC_FS
static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 24df3347ad4..20f1fed8fa4 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -44,12 +44,6 @@
#define STATE_PENDING 1
#define STATE_READY 2
-/* used by sysctl */
-#define FS_MQUEUE 1
-#define CTL_QUEUESMAX 2
-#define CTL_MSGMAX 3
-#define CTL_MSGSIZEMAX 4
-
/* default values */
#define DFLT_QUEUESMAX 256 /* max number of message queues */
#define DFLT_MSGMAX 10 /* max number of messages in each queue */
@@ -211,7 +205,7 @@ static int mqueue_get_sb(struct file_system_type *fs_type,
return get_sb_single(fs_type, flags, data, mqueue_fill_super, mnt);
}
-static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo;
@@ -1196,7 +1190,6 @@ static int msg_maxsize_limit_max = INT_MAX;
static ctl_table mq_sysctls[] = {
{
- .ctl_name = CTL_QUEUESMAX,
.procname = "queues_max",
.data = &queues_max,
.maxlen = sizeof(int),
@@ -1204,7 +1197,6 @@ static ctl_table mq_sysctls[] = {
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = CTL_MSGMAX,
.procname = "msg_max",
.data = &msg_max,
.maxlen = sizeof(int),
@@ -1214,7 +1206,6 @@ static ctl_table mq_sysctls[] = {
.extra2 = &msg_max_limit_max,
},
{
- .ctl_name = CTL_MSGSIZEMAX,
.procname = "msgsize_max",
.data = &msgsize_max,
.maxlen = sizeof(int),
@@ -1228,7 +1219,6 @@ static ctl_table mq_sysctls[] = {
static ctl_table mq_sysctl_dir[] = {
{
- .ctl_name = FS_MQUEUE,
.procname = "mqueue",
.mode = 0555,
.child = mq_sysctls,
diff --git a/ipc/shm.c b/ipc/shm.c
index a86a3a5c8a1..5fc5cf50cf1 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -233,7 +233,7 @@ static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
#ifdef CONFIG_NUMA
-int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
+static int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
{
struct file *file = vma->vm_file;
struct shm_file_data *sfd = shm_file_data(file);
@@ -243,7 +243,8 @@ int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
return err;
}
-struct mempolicy *shm_get_policy(struct vm_area_struct *vma, unsigned long addr)
+static struct mempolicy *shm_get_policy(struct vm_area_struct *vma,
+ unsigned long addr)
{
struct file *file = vma->vm_file;
struct shm_file_data *sfd = shm_file_data(file);
@@ -906,7 +907,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
goto out_unlock;
path.dentry = dget(shp->shm_file->f_path.dentry);
- path.mnt = mntget(shp->shm_file->f_path.mnt);
+ path.mnt = shp->shm_file->f_path.mnt;
shp->shm_nattch++;
size = i_size_read(path.dentry->d_inode);
shm_unlock(shp);
@@ -914,18 +915,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
if (!sfd)
- goto out_put_path;
+ goto out_put_dentry;
err = -ENOMEM;
- file = get_empty_filp();
+
+ file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
if (!file)
goto out_free;
- file->f_op = &shm_file_operations;
file->private_data = sfd;
- file->f_path = path;
file->f_mapping = shp->shm_file->f_mapping;
- file->f_mode = f_mode;
sfd->id = shp->id;
sfd->ns = get_ipc_ns(ns);
sfd->file = shp->shm_file;
@@ -976,9 +975,8 @@ out_unlock:
out_free:
kfree(sfd);
-out_put_path:
+out_put_dentry:
dput(path.dentry);
- mntput(path.mnt);
goto out_nattch;
}
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index 6b066632e40..c64ce9c1420 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -63,6 +63,3 @@ config PREEMPT_BKL
Say Y here if you are building a kernel for a desktop system.
Say N if you are unsure.
-config PREEMPT_NOTIFIERS
- bool
-
diff --git a/kernel/Makefile b/kernel/Makefile
index 2a999836ca1..d63fbb18798 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.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
+ utsname.o sysctl_check.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
diff --git a/kernel/acct.c b/kernel/acct.c
index 24f0f8b2ba7..fce53d8df8a 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -329,16 +329,16 @@ static comp_t encode_comp_t(unsigned long value)
}
/*
- * If we need to round up, do it (and handle overflow correctly).
- */
+ * If we need to round up, do it (and handle overflow correctly).
+ */
if (rnd && (++value > MAXFRACT)) {
value >>= EXPSIZE;
exp++;
}
/*
- * Clean it up and polish it off.
- */
+ * Clean it up and polish it off.
+ */
exp <<= MANTSIZE; /* Shift the exponent into place */
exp += value; /* and add on the mantissa. */
return exp;
@@ -361,30 +361,30 @@ static comp_t encode_comp_t(unsigned long value)
static comp2_t encode_comp2_t(u64 value)
{
- int exp, rnd;
-
- exp = (value > (MAXFRACT2>>1));
- rnd = 0;
- while (value > MAXFRACT2) {
- rnd = value & 1;
- value >>= 1;
- exp++;
- }
-
- /*
- * If we need to round up, do it (and handle overflow correctly).
- */
- if (rnd && (++value > MAXFRACT2)) {
- value >>= 1;
- exp++;
- }
-
- if (exp > MAXEXP2) {
- /* Overflow. Return largest representable number instead. */
- return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
- } else {
- return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
- }
+ int exp, rnd;
+
+ exp = (value > (MAXFRACT2>>1));
+ rnd = 0;
+ while (value > MAXFRACT2) {
+ rnd = value & 1;
+ value >>= 1;
+ exp++;
+ }
+
+ /*
+ * If we need to round up, do it (and handle overflow correctly).
+ */
+ if (rnd && (++value > MAXFRACT2)) {
+ value >>= 1;
+ exp++;
+ }
+
+ if (exp > MAXEXP2) {
+ /* Overflow. Return largest representable number instead. */
+ return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
+ } else {
+ return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
+ }
}
#endif
@@ -501,14 +501,14 @@ static void do_acct_process(struct file *file)
ac.ac_swaps = encode_comp_t(0);
/*
- * Kernel segment override to datasegment and write it
- * to the accounting file.
- */
+ * Kernel segment override to datasegment and write it
+ * to the accounting file.
+ */
fs = get_fs();
set_fs(KERNEL_DS);
/*
- * Accounting records are not subject to resource limits.
- */
+ * Accounting records are not subject to resource limits.
+ */
flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
file->f_op->write(file, (char *)&ac,
diff --git a/kernel/audit.c b/kernel/audit.c
index 2924251a654..6977ea57a7e 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -664,11 +664,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (sid) {
if (selinux_sid_to_string(
sid, &ctx, &len)) {
- audit_log_format(ab,
+ audit_log_format(ab,
" ssid=%u", sid);
/* Maybe call audit_panic? */
} else
- audit_log_format(ab,
+ audit_log_format(ab,
" subj=%s", ctx);
kfree(ctx);
}
@@ -769,7 +769,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
sig_data->pid = audit_sig_pid;
memcpy(sig_data->ctx, ctx, len);
kfree(ctx);
- audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
+ audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO,
0, 0, sig_data, sizeof(*sig_data) + len);
kfree(sig_data);
break;
@@ -1005,7 +1005,7 @@ unsigned int audit_serial(void)
return ret;
}
-static inline void audit_get_stamp(struct audit_context *ctx,
+static inline void audit_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial)
{
if (ctx)
@@ -1056,7 +1056,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
if (gfp_mask & __GFP_WAIT)
reserve = 0;
else
- reserve = 5; /* Allow atomic callers to go up to five
+ reserve = 5; /* Allow atomic callers to go up to five
entries over the normal backlog limit */
while (audit_backlog_limit
@@ -1319,7 +1319,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
/* FIXME: can we save some information here? */
audit_log_format(ab, "<too long>");
- } else
+ } else
audit_log_untrustedstring(ab, p);
kfree(path);
}
@@ -1365,7 +1365,7 @@ void audit_log_end(struct audit_buffer *ab)
* audit_log_vformat, and audit_log_end. It may be called
* in any context.
*/
-void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
+void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{
struct audit_buffer *ab;
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 359645cff5b..df66a21fb36 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1498,7 +1498,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
* auditctl to read from it... which isn't ever going to
* happen if we're actually running in the context of auditctl
* trying to _send_ the stuff */
-
+
dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL);
if (!dest)
return -ENOMEM;
@@ -1678,7 +1678,7 @@ int audit_filter_type(int type)
{
struct audit_entry *e;
int result = 0;
-
+
rcu_read_lock();
if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
goto unlock_and_return;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 04f3ffb8d9d..e19b5a33aed 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -45,7 +45,6 @@
#include <linux/init.h>
#include <asm/types.h>
#include <asm/atomic.h>
-#include <asm/types.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/mm.h>
@@ -321,7 +320,7 @@ static int audit_filter_rules(struct task_struct *tsk,
result = audit_comparator(tsk->personality, f->op, f->val);
break;
case AUDIT_ARCH:
- if (ctx)
+ if (ctx)
result = audit_comparator(ctx->arch, f->op, f->val);
break;
@@ -899,7 +898,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
if (context->personality != PER_LINUX)
audit_log_format(ab, " per=%lx", context->personality);
if (context->return_valid)
- audit_log_format(ab, " success=%s exit=%ld",
+ audit_log_format(ab, " success=%s exit=%ld",
(context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
context->return_code);
@@ -1136,8 +1135,8 @@ void audit_free(struct task_struct *tsk)
return;
/* Check for system calls that do not go through the exit
- * function (e.g., exit_group), then free context block.
- * We use GFP_ATOMIC here because we might be doing this
+ * function (e.g., exit_group), then free context block.
+ * We use GFP_ATOMIC here because we might be doing this
* in the context of the idle thread */
/* that can happen only if we are called from do_exit() */
if (context->in_syscall && context->auditable)
@@ -1317,7 +1316,7 @@ void __audit_getname(const char *name)
context->pwdmnt = mntget(current->fs->pwdmnt);
read_unlock(&current->fs->lock);
}
-
+
}
/* audit_putname - intercept a putname request
@@ -1525,6 +1524,7 @@ add_names:
context->names[idx].ino = (unsigned long)-1;
}
}
+EXPORT_SYMBOL_GPL(__audit_inode_child);
/**
* auditsc_get_stamp - get local copies of audit_context values
diff --git a/kernel/capability.c b/kernel/capability.c
index c8d3c776203..cbc5fd60c0f 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -3,9 +3,9 @@
*
* Copyright (C) 1997 Andrew Main <zefram@fysh.org>
*
- * Integrated into 2.1.97+, Andrew G. Morgan <morgan@transmeta.com>
+ * Integrated into 2.1.97+, Andrew G. Morgan <morgan@kernel.org>
* 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net>
- */
+ */
#include <linux/capability.h>
#include <linux/mm.h>
@@ -14,12 +14,6 @@
#include <linux/syscalls.h>
#include <asm/uaccess.h>
-unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
-
-EXPORT_SYMBOL(securebits);
-EXPORT_SYMBOL(cap_bset);
-
/*
* This lock protects task->cap_* for all tasks including current.
* Locking rule: acquire this prior to tasklist_lock.
@@ -43,49 +37,49 @@ static DEFINE_SPINLOCK(task_capability_lock);
*/
asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
{
- int ret = 0;
- pid_t pid;
- __u32 version;
- struct task_struct *target;
- struct __user_cap_data_struct data;
-
- if (get_user(version, &header->version))
- return -EFAULT;
-
- if (version != _LINUX_CAPABILITY_VERSION) {
- if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
- return -EFAULT;
- return -EINVAL;
- }
+ int ret = 0;
+ pid_t pid;
+ __u32 version;
+ struct task_struct *target;
+ struct __user_cap_data_struct data;
+
+ if (get_user(version, &header->version))
+ return -EFAULT;
+
+ if (version != _LINUX_CAPABILITY_VERSION) {
+ if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
+ return -EFAULT;
+ return -EINVAL;
+ }
- if (get_user(pid, &header->pid))
- return -EFAULT;
+ if (get_user(pid, &header->pid))
+ return -EFAULT;
- if (pid < 0)
- return -EINVAL;
+ if (pid < 0)
+ return -EINVAL;
- spin_lock(&task_capability_lock);
- read_lock(&tasklist_lock);
+ spin_lock(&task_capability_lock);
+ read_lock(&tasklist_lock);
- if (pid && pid != current->pid) {
- target = find_task_by_pid(pid);
- if (!target) {
- ret = -ESRCH;
- goto out;
- }
- } else
- target = current;
+ if (pid && pid != current->pid) {
+ target = find_task_by_pid(pid);
+ if (!target) {
+ ret = -ESRCH;
+ goto out;
+ }
+ } else
+ target = current;
- ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
+ ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);
out:
- read_unlock(&tasklist_lock);
- spin_unlock(&task_capability_lock);
+ read_unlock(&tasklist_lock);
+ spin_unlock(&task_capability_lock);
- if (!ret && copy_to_user(dataptr, &data, sizeof data))
- return -EFAULT;
+ if (!ret && copy_to_user(dataptr, &data, sizeof data))
+ return -EFAULT;
- return ret;
+ return ret;
}
/*
@@ -118,7 +112,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective,
} while_each_pid_task(pgrp, PIDTYPE_PGID, g);
if (!found)
- ret = 0;
+ ret = 0;
return ret;
}
@@ -172,68 +166,68 @@ static inline int cap_set_all(kernel_cap_t *effective,
*/
asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
{
- kernel_cap_t inheritable, permitted, effective;
- __u32 version;
- struct task_struct *target;
- int ret;
- pid_t pid;
-
- if (get_user(version, &header->version))
- return -EFAULT;
-
- if (version != _LINUX_CAPABILITY_VERSION) {
- if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
- return -EFAULT;
- return -EINVAL;
- }
-
- if (get_user(pid, &header->pid))
- return -EFAULT;
-
- if (pid && pid != current->pid && !capable(CAP_SETPCAP))
- return -EPERM;
-
- if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
- copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
- copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
- return -EFAULT;
-
- spin_lock(&task_capability_lock);
- read_lock(&tasklist_lock);
-
- if (pid > 0 && pid != current->pid) {
- target = find_task_by_pid(pid);
- if (!target) {
- ret = -ESRCH;
- goto out;
- }
- } else
- target = current;
-
- ret = 0;
-
- /* having verified that the proposed changes are legal,
- we now put them into effect. */
- if (pid < 0) {
- if (pid == -1) /* all procs other than current and init */
- ret = cap_set_all(&effective, &inheritable, &permitted);
-
- else /* all procs in process group */
- ret = cap_set_pg(-pid, &effective, &inheritable,
- &permitted);
- } else {
- ret = security_capset_check(target, &effective, &inheritable,
- &permitted);
- if (!ret)
- security_capset_set(target, &effective, &inheritable,
- &permitted);
- }
+ kernel_cap_t inheritable, permitted, effective;
+ __u32 version;
+ struct task_struct *target;
+ int ret;
+ pid_t pid;
+
+ if (get_user(version, &header->version))
+ return -EFAULT;
+
+ if (version != _LINUX_CAPABILITY_VERSION) {
+ if (put_user(_LINUX_CAPABILITY_VERSION, &header->version))
+ return -EFAULT;
+ return -EINVAL;
+ }
+
+ if (get_user(pid, &header->pid))
+ return -EFAULT;
+
+ if (pid && pid != current->pid && !capable(CAP_SETPCAP))
+ return -EPERM;
+
+ if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
+ copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
+ copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
+ return -EFAULT;
+
+ spin_lock(&task_capability_lock);
+ read_lock(&tasklist_lock);
+
+ if (pid > 0 && pid != current->pid) {
+ target = find_task_by_pid(pid);
+ if (!target) {
+ ret = -ESRCH;
+ goto out;
+ }
+ } else
+ target = current;
+
+ ret = 0;
+
+ /* having verified that the proposed changes are legal,
+ we now put them into effect. */
+ if (pid < 0) {
+ if (pid == -1) /* all procs other than current and init */
+ ret = cap_set_all(&effective, &inheritable, &permitted);
+
+ else /* all procs in process group */
+ ret = cap_set_pg(-pid, &effective, &inheritable,
+ &permitted);
+ } else {
+ ret = security_capset_check(target, &effective, &inheritable,
+ &permitted);
+ if (!ret)
+ security_capset_set(target, &effective, &inheritable,
+ &permitted);
+ }
out:
- read_unlock(&tasklist_lock);
- spin_unlock(&task_capability_lock);
+ read_unlock(&tasklist_lock);
+ spin_unlock(&task_capability_lock);
- return ret;
+ return ret;
}
int __capable(struct task_struct *t, int cap)
@@ -244,7 +238,6 @@ int __capable(struct task_struct *t, int cap)
}
return 0;
}
-EXPORT_SYMBOL(__capable);
int capable(int cap)
{
diff --git a/kernel/compat.c b/kernel/compat.c
index 3bae3742c2a..42a1ed4b61b 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -40,62 +40,27 @@ int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user
__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
}
-static long compat_nanosleep_restart(struct restart_block *restart)
-{
- unsigned long expire = restart->arg0, now = jiffies;
- struct compat_timespec __user *rmtp;
-
- /* Did it expire while we handled signals? */
- if (!time_after(expire, now))
- return 0;
-
- expire = schedule_timeout_interruptible(expire - now);
- if (expire == 0)
- return 0;
-
- rmtp = (struct compat_timespec __user *)restart->arg1;
- if (rmtp) {
- struct compat_timespec ct;
- struct timespec t;
-
- jiffies_to_timespec(expire, &t);
- ct.tv_sec = t.tv_sec;
- ct.tv_nsec = t.tv_nsec;
- if (copy_to_user(rmtp, &ct, sizeof(ct)))
- return -EFAULT;
- }
- /* The 'restart' block is already filled in */
- return -ERESTART_RESTARTBLOCK;
-}
-
asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp,
- struct compat_timespec __user *rmtp)
+ struct compat_timespec __user *rmtp)
{
- struct timespec t;
- struct restart_block *restart;
- unsigned long expire;
+ struct timespec tu, rmt;
+ long ret;
- if (get_compat_timespec(&t, rqtp))
+ if (get_compat_timespec(&tu, rqtp))
return -EFAULT;
- if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0))
+ if (!timespec_valid(&tu))
return -EINVAL;
- expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
- expire = schedule_timeout_interruptible(expire);
- if (expire == 0)
- return 0;
+ ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+ CLOCK_MONOTONIC);
- if (rmtp) {
- jiffies_to_timespec(expire, &t);
- if (put_compat_timespec(&t, rmtp))
+ if (ret && rmtp) {
+ if (put_compat_timespec(&rmt, rmtp))
return -EFAULT;
}
- restart = &current_thread_info()->restart_block;
- restart->fn = compat_nanosleep_restart;
- restart->arg0 = jiffies + expire;
- restart->arg1 = (unsigned long) rmtp;
- return -ERESTART_RESTARTBLOCK;
+
+ return ret;
}
static inline long get_compat_itimerval(struct itimerval *o,
@@ -247,8 +212,8 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource,
int ret;
mm_segment_t old_fs = get_fs ();
- if (resource >= RLIM_NLIMITS)
- return -EINVAL;
+ if (resource >= RLIM_NLIMITS)
+ return -EINVAL;
if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
__get_user(r.rlim_cur, &rlim->rlim_cur) ||
@@ -477,21 +442,21 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
int get_compat_itimerspec(struct itimerspec *dst,
const struct compat_itimerspec __user *src)
-{
+{
if (get_compat_timespec(&dst->it_interval, &src->it_interval) ||
get_compat_timespec(&dst->it_value, &src->it_value))
return -EFAULT;
return 0;
-}
+}
int put_compat_itimerspec(struct compat_itimerspec __user *dst,
const struct itimerspec *src)
-{
+{
if (put_compat_timespec(&src->it_interval, &dst->it_interval) ||
put_compat_timespec(&src->it_value, &dst->it_value))
return -EFAULT;
return 0;
-}
+}
long compat_sys_timer_create(clockid_t which_clock,
struct compat_sigevent __user *timer_event_spec,
@@ -512,9 +477,9 @@ long compat_sys_timer_create(clockid_t which_clock,
}
long compat_sys_timer_settime(timer_t timer_id, int flags,
- struct compat_itimerspec __user *new,
+ struct compat_itimerspec __user *new,
struct compat_itimerspec __user *old)
-{
+{
long err;
mm_segment_t oldfs;
struct itimerspec newts, oldts;
@@ -522,58 +487,58 @@ long compat_sys_timer_settime(timer_t timer_id, int flags,
if (!new)
return -EINVAL;
if (get_compat_itimerspec(&newts, new))
- return -EFAULT;
+ return -EFAULT;
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_timer_settime(timer_id, flags,
(struct itimerspec __user *) &newts,
(struct itimerspec __user *) &oldts);
- set_fs(oldfs);
+ set_fs(oldfs);
if (!err && old && put_compat_itimerspec(old, &oldts))
return -EFAULT;
return err;
-}
+}
long compat_sys_timer_gettime(timer_t timer_id,
struct compat_itimerspec __user *setting)
-{
+{
long err;
mm_segment_t oldfs;
- struct itimerspec ts;
+ struct itimerspec ts;
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_timer_gettime(timer_id,
- (struct itimerspec __user *) &ts);
- set_fs(oldfs);
+ (struct itimerspec __user *) &ts);
+ set_fs(oldfs);
if (!err && put_compat_itimerspec(setting, &ts))
return -EFAULT;
return err;
-}
+}
long compat_sys_clock_settime(clockid_t which_clock,
struct compat_timespec __user *tp)
{
long err;
mm_segment_t oldfs;
- struct timespec ts;
+ struct timespec ts;
if (get_compat_timespec(&ts, tp))
- return -EFAULT;
+ return -EFAULT;
oldfs = get_fs();
- set_fs(KERNEL_DS);
+ set_fs(KERNEL_DS);
err = sys_clock_settime(which_clock,
(struct timespec __user *) &ts);
set_fs(oldfs);
return err;
-}
+}
long compat_sys_clock_gettime(clockid_t which_clock,
struct compat_timespec __user *tp)
{
long err;
mm_segment_t oldfs;
- struct timespec ts;
+ struct timespec ts;
oldfs = get_fs();
set_fs(KERNEL_DS);
@@ -581,16 +546,16 @@ long compat_sys_clock_gettime(clockid_t which_clock,
(struct timespec __user *) &ts);
set_fs(oldfs);
if (!err && put_compat_timespec(&ts, tp))
- return -EFAULT;
+ return -EFAULT;
return err;
-}
+}
long compat_sys_clock_getres(clockid_t which_clock,
struct compat_timespec __user *tp)
{
long err;
mm_segment_t oldfs;
- struct timespec ts;
+ struct timespec ts;
oldfs = get_fs();
set_fs(KERNEL_DS);
@@ -598,9 +563,9 @@ long compat_sys_clock_getres(clockid_t which_clock,
(struct timespec __user *) &ts);
set_fs(oldfs);
if (!err && tp && put_compat_timespec(&ts, tp))
- return -EFAULT;
+ return -EFAULT;
return err;
-}
+}
static long compat_clock_nanosleep_restart(struct restart_block *restart)
{
@@ -632,10 +597,10 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
{
long err;
mm_segment_t oldfs;
- struct timespec in, out;
+ struct timespec in, out;
struct restart_block *restart;
- if (get_compat_timespec(&in, rqtp))
+ if (get_compat_timespec(&in, rqtp))
return -EFAULT;
oldfs = get_fs();
@@ -654,8 +619,8 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags,
restart->fn = compat_clock_nanosleep_restart;
restart->arg1 = (unsigned long) rmtp;
}
- return err;
-}
+ return err;
+}
/*
* We currently only need the following fields from the sigevent
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 38033db8d8e..a21f71af9d8 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -150,6 +150,7 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen)
err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
hcpu, -1, &nr_calls);
if (err == NOTIFY_BAD) {
+ nr_calls--;
__raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
hcpu, nr_calls, NULL);
printk("%s: attempt to take down CPU %u failed\n",
@@ -233,6 +234,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,
-1, &nr_calls);
if (ret == NOTIFY_BAD) {
+ nr_calls--;
printk("%s: attempt to bring up CPU %u failed\n",
__FUNCTION__, cpu);
ret = -EINVAL;
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 57e6448b171..64950fa5d32 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -581,26 +581,28 @@ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
/*
* Return in *pmask the portion of a cpusets's mems_allowed that
- * are online. If none are online, walk up the cpuset hierarchy
- * until we find one that does have some online mems. If we get
- * all the way to the top and still haven't found any online mems,
- * return node_online_map.
+ * are online, with memory. If none are online with memory, walk
+ * up the cpuset hierarchy until we find one that does have some
+ * online mems. If we get all the way to the top and still haven't
+ * found any online mems, return node_states[N_HIGH_MEMORY].
*
* One way or another, we guarantee to return some non-empty subset
- * of node_online_map.
+ * of node_states[N_HIGH_MEMORY].
*
* Call with callback_mutex held.
*/
static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
{
- while (cs && !nodes_intersects(cs->mems_allowed, node_online_map))
+ while (cs && !nodes_intersects(cs->mems_allowed,
+ node_states[N_HIGH_MEMORY]))
cs = cs->parent;
if (cs)
- nodes_and(*pmask, cs->mems_allowed, node_online_map);
+ nodes_and(*pmask, cs->mems_allowed,
+ node_states[N_HIGH_MEMORY]);
else
- *pmask = node_online_map;
- BUG_ON(!nodes_intersects(*pmask, node_online_map));
+ *pmask = node_states[N_HIGH_MEMORY];
+ BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY]));
}
/**
@@ -753,68 +755,13 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
}
/*
- * For a given cpuset cur, partition the system as follows
- * a. All cpus in the parent cpuset's cpus_allowed that are not part of any
- * exclusive child cpusets
- * b. All cpus in the current cpuset's cpus_allowed that are not part of any
- * exclusive child cpusets
- * Build these two partitions by calling partition_sched_domains
- *
- * Call with manage_mutex held. 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.
- */
-
-static void update_cpu_domains(struct cpuset *cur)
-{
- struct cpuset *c, *par = cur->parent;
- cpumask_t pspan, cspan;
-
- if (par == NULL || cpus_empty(cur->cpus_allowed))
- return;
-
- /*
- * Get all cpus from parent's cpus_allowed not part of exclusive
- * children
- */
- pspan = par->cpus_allowed;
- list_for_each_entry(c, &par->children, sibling) {
- if (is_cpu_exclusive(c))
- cpus_andnot(pspan, pspan, c->cpus_allowed);
- }
- if (!is_cpu_exclusive(cur)) {
- cpus_or(pspan, pspan, cur->cpus_allowed);
- if (cpus_equal(pspan, cur->cpus_allowed))
- return;
- cspan = CPU_MASK_NONE;
- } else {
- if (cpus_empty(pspan))
- return;
- cspan = cur->cpus_allowed;
- /*
- * Get all cpus from current cpuset's cpus_allowed not part
- * of exclusive children
- */
- list_for_each_entry(c, &cur->children, sibling) {
- if (is_cpu_exclusive(c))
- cpus_andnot(cspan, cspan, c->cpus_allowed);
- }
- }
-
- lock_cpu_hotplug();
- partition_sched_domains(&pspan, &cspan);
- unlock_cpu_hotplug();
-}
-
-/*
* 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, cpus_unchanged;
+ int retval;
/* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
if (cs == &top_cpuset)
@@ -841,12 +788,9 @@ static int update_cpumask(struct cpuset *cs, char *buf)
retval = validate_change(cs, &trialcs);
if (retval < 0)
return retval;
- cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
mutex_lock(&callback_mutex);
cs->cpus_allowed = trialcs.cpus_allowed;
mutex_unlock(&callback_mutex);
- if (is_cpu_exclusive(cs) && !cpus_unchanged)
- update_cpu_domains(cs);
return 0;
}
@@ -924,7 +868,10 @@ static int update_nodemask(struct cpuset *cs, char *buf)
int fudge;
int retval;
- /* top_cpuset.mems_allowed tracks node_online_map; it's read-only */
+ /*
+ * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
+ * it's read-only
+ */
if (cs == &top_cpuset)
return -EACCES;
@@ -941,8 +888,21 @@ static int update_nodemask(struct cpuset *cs, char *buf)
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;
+ }
}
- nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map);
+ /*
+ * 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;
if (nodes_equal(oldmem, trialcs.mems_allowed)) {
retval = 0; /* Too easy - nothing to do */
@@ -1067,7 +1027,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
{
int turning_on;
struct cpuset trialcs;
- int err, cpu_exclusive_changed;
+ int err;
turning_on = (simple_strtoul(buf, NULL, 10) != 0);
@@ -1080,14 +1040,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
err = validate_change(cs, &trialcs);
if (err < 0)
return err;
- cpu_exclusive_changed =
- (is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
mutex_lock(&callback_mutex);
cs->flags = trialcs.flags;
mutex_unlock(&callback_mutex);
- if (cpu_exclusive_changed)
- update_cpu_domains(cs);
return 0;
}
@@ -1445,7 +1401,7 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
ssize_t retval = 0;
char *s;
- if (!(page = (char *)__get_free_page(GFP_KERNEL)))
+ if (!(page = (char *)__get_free_page(GFP_TEMPORARY)))
return -ENOMEM;
s = page;
@@ -1947,17 +1903,6 @@ static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode)
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 is marked cpu_exclusive, then simulate
- * turning cpu_exclusive off, which will call update_cpu_domains().
- * The lock_cpu_hotplug() call in update_cpu_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)
{
struct cpuset *cs = dentry->d_fsdata;
@@ -1977,13 +1922,6 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
mutex_unlock(&manage_mutex);
return -EBUSY;
}
- if (is_cpu_exclusive(cs)) {
- int retval = update_flag(CS_CPU_EXCLUSIVE, cs, "0");
- if (retval < 0) {
- mutex_unlock(&manage_mutex);
- return retval;
- }
- }
parent = cs->parent;
mutex_lock(&callback_mutex);
set_bit(CS_REMOVED, &cs->flags);
@@ -2098,8 +2036,9 @@ static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
/*
* The cpus_allowed and mems_allowed nodemasks in the top_cpuset track
- * cpu_online_map and node_online_map. Force the top cpuset to track
- * whats online after any CPU or memory node hotplug or unplug event.
+ * cpu_online_map and node_states[N_HIGH_MEMORY]. Force the top cpuset to
+ * track what's online after any CPU or memory node hotplug or unplug
+ * event.
*
* To ensure that we don't remove a CPU or node from the top cpuset
* that is currently in use by a child cpuset (which would violate
@@ -2119,7 +2058,7 @@ static void common_cpu_mem_hotplug_unplug(void)
guarantee_online_cpus_mems_in_subtree(&top_cpuset);
top_cpuset.cpus_allowed = cpu_online_map;
- top_cpuset.mems_allowed = node_online_map;
+ top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
mutex_unlock(&callback_mutex);
mutex_unlock(&manage_mutex);
@@ -2147,8 +2086,9 @@ static int cpuset_handle_cpuhp(struct notifier_block *nb,
#ifdef CONFIG_MEMORY_HOTPLUG
/*
- * Keep top_cpuset.mems_allowed tracking node_online_map.
- * Call this routine anytime after you change node_online_map.
+ * Keep top_cpuset.mems_allowed tracking node_states[N_HIGH_MEMORY].
+ * Call this routine anytime after you change
+ * node_states[N_HIGH_MEMORY].
* See also the previous routine cpuset_handle_cpuhp().
*/
@@ -2167,7 +2107,7 @@ void cpuset_track_online_nodes(void)
void __init cpuset_init_smp(void)
{
top_cpuset.cpus_allowed = cpu_online_map;
- top_cpuset.mems_allowed = node_online_map;
+ top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
hotcpu_notifier(cpuset_handle_cpuhp, 0);
}
@@ -2309,7 +2249,7 @@ void cpuset_init_current_mems_allowed(void)
*
* Description: Returns the nodemask_t mems_allowed of the cpuset
* attached to the specified @tsk. Guaranteed to return some non-empty
- * subset of node_online_map, even if this means going outside the
+ * subset of node_states[N_HIGH_MEMORY], even if this means going outside the
* tasks cpuset.
**/
@@ -2491,12 +2431,12 @@ int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
node = zone_to_nid(z);
if (node_isset(node, current->mems_allowed))
return 1;
- /*
- * Allow tasks that have access to memory reserves because they have
- * been OOM killed to get memory anywhere.
- */
- if (unlikely(test_thread_flag(TIF_MEMDIE)))
- return 1;
+ /*
+ * Allow tasks that have access to memory reserves because they have
+ * been OOM killed to get memory anywhere.
+ */
+ if (unlikely(test_thread_flag(TIF_MEMDIE)))
+ return 1;
return 0;
}
@@ -2566,41 +2506,20 @@ int cpuset_mem_spread_node(void)
EXPORT_SYMBOL_GPL(cpuset_mem_spread_node);
/**
- * cpuset_excl_nodes_overlap - Do we overlap @p's mem_exclusive ancestors?
- * @p: pointer to task_struct of some other task.
- *
- * Description: Return true if the nearest mem_exclusive ancestor
- * cpusets of tasks @p and current overlap. Used by oom killer to
- * determine if task @p's memory usage might impact the memory
- * available to the current task.
- *
- * Call while holding callback_mutex.
+ * cpuset_mems_allowed_intersects - Does @tsk1's mems_allowed intersect @tsk2's?
+ * @tsk1: pointer to task_struct of some task.
+ * @tsk2: pointer to task_struct of some other task.
+ *
+ * Description: Return true if @tsk1's mems_allowed intersects the
+ * mems_allowed of @tsk2. Used by the OOM killer to determine if
+ * one of the task's memory usage might impact the memory available
+ * to the other.
**/
-int cpuset_excl_nodes_overlap(const struct task_struct *p)
+int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
+ const struct task_struct *tsk2)
{
- const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */
- int overlap = 1; /* do cpusets overlap? */
-
- task_lock(current);
- if (current->flags & PF_EXITING) {
- task_unlock(current);
- goto done;
- }
- cs1 = nearest_exclusive_ancestor(current->cpuset);
- task_unlock(current);
-
- task_lock((struct task_struct *)p);
- if (p->flags & PF_EXITING) {
- task_unlock((struct task_struct *)p);
- goto done;
- }
- cs2 = nearest_exclusive_ancestor(p->cpuset);
- task_unlock((struct task_struct *)p);
-
- overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed);
-done:
- return overlap;
+ return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed);
}
/*
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 09e9574eeb2..10e43fd8b72 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -115,6 +115,12 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
tmp += timespec_to_ns(&ts);
d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp;
+ tmp = (s64)d->cpu_scaled_run_real_total;
+ cputime_to_timespec(tsk->utimescaled + tsk->stimescaled, &ts);
+ tmp += timespec_to_ns(&ts);
+ d->cpu_scaled_run_real_total =
+ (tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp;
+
/*
* No locking available for sched_info (and too expensive to add one)
* Mitigate by taking snapshot of values
diff --git a/kernel/dma.c b/kernel/dma.c
index 937b13ca33b..6a82bb716da 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -20,7 +20,7 @@
#include <asm/dma.h>
#include <asm/system.h>
-
+
/* A note on resource allocation:
*
@@ -95,7 +95,7 @@ void free_dma(unsigned int dmanr)
if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) {
printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
return;
- }
+ }
} /* free_dma */
@@ -121,8 +121,8 @@ static int proc_dma_show(struct seq_file *m, void *v)
for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
if (dma_chan_busy[i].lock) {
- seq_printf(m, "%2d: %s\n", i,
- dma_chan_busy[i].device_id);
+ seq_printf(m, "%2d: %s\n", i,
+ dma_chan_busy[i].device_id);
}
}
return 0;
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 3c2eaea66b1..a9e6bad9f70 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -57,7 +57,7 @@ lookup_exec_domain(u_long personality)
{
struct exec_domain * ep;
u_long pers = personality(personality);
-
+
read_lock(&exec_domains_lock);
for (ep = exec_domains; ep; ep = ep->next) {
if (pers >= ep->pers_low && pers <= ep->pers_high)
diff --git a/kernel/exit.c b/kernel/exit.c
index 7f7959de4a8..2c704c86edb 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -44,7 +44,6 @@
#include <linux/resource.h>
#include <linux/blkdev.h>
#include <linux/task_io_accounting_ops.h>
-#include <linux/freezer.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -93,10 +92,9 @@ static void __exit_signal(struct task_struct *tsk)
* If there is any task waiting for the group exit
* then notify it:
*/
- if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) {
+ if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count)
wake_up_process(sig->group_exit_task);
- sig->group_exit_task = NULL;
- }
+
if (tsk == sig->curr_target)
sig->curr_target = next_thread(tsk);
/*
@@ -593,17 +591,6 @@ static void exit_mm(struct task_struct * tsk)
mmput(mm);
}
-static inline void
-choose_new_parent(struct task_struct *p, struct task_struct *reaper)
-{
- /*
- * Make sure we're not reparenting to ourselves and that
- * the parent is not a zombie.
- */
- BUG_ON(p == reaper || reaper->exit_state);
- p->real_parent = reaper;
-}
-
static void
reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
{
@@ -711,7 +698,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
if (father == p->real_parent) {
/* reparent with a reaper, real father it's us */
- choose_new_parent(p, reaper);
+ p->real_parent = reaper;
reparent_thread(p, father, 0);
} else {
/* reparent ptraced task to its real parent */
@@ -732,7 +719,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
}
list_for_each_safe(_p, _n, &father->ptrace_children) {
p = list_entry(_p, struct task_struct, ptrace_list);
- choose_new_parent(p, reaper);
+ p->real_parent = reaper;
reparent_thread(p, father, 1);
}
}
@@ -759,13 +746,11 @@ static void exit_notify(struct task_struct *tsk)
* Now we'll wake all the threads in the group just to make
* sure someone gets all the pending signals.
*/
- read_lock(&tasklist_lock);
spin_lock_irq(&tsk->sighand->siglock);
for (t = next_thread(tsk); t != tsk; t = next_thread(t))
if (!signal_pending(t) && !(t->flags & PF_EXITING))
recalc_sigpending_and_wake(t);
spin_unlock_irq(&tsk->sighand->siglock);
- read_unlock(&tasklist_lock);
}
write_lock_irq(&tasklist_lock);
@@ -793,9 +778,8 @@ static void exit_notify(struct task_struct *tsk)
* and we were the only connection outside, so our pgrp
* is about to become orphaned.
*/
-
t = tsk->real_parent;
-
+
pgrp = task_pgrp(tsk);
if ((task_pgrp(t) != pgrp) &&
(task_session(t) == task_session(tsk)) &&
@@ -842,6 +826,11 @@ static void exit_notify(struct task_struct *tsk)
state = EXIT_DEAD;
tsk->exit_state = state;
+ if (thread_group_leader(tsk) &&
+ tsk->signal->notify_count < 0 &&
+ tsk->signal->group_exit_task)
+ wake_up_process(tsk->signal->group_exit_task);
+
write_unlock_irq(&tasklist_lock);
list_for_each_safe(_p, _n, &ptrace_dead) {
@@ -883,6 +872,14 @@ static void check_stack_usage(void)
static inline void check_stack_usage(void) {}
#endif
+static inline void exit_child_reaper(struct task_struct *tsk)
+{
+ if (likely(tsk->group_leader != child_reaper(tsk)))
+ return;
+
+ panic("Attempted to kill init!");
+}
+
fastcall NORET_TYPE void do_exit(long code)
{
struct task_struct *tsk = current;
@@ -896,13 +893,6 @@ fastcall NORET_TYPE void do_exit(long code)
panic("Aiee, killing interrupt handler!");
if (unlikely(!tsk->pid))
panic("Attempted to kill the idle task!");
- if (unlikely(tsk == child_reaper(tsk))) {
- if (tsk->nsproxy->pid_ns != &init_pid_ns)
- tsk->nsproxy->pid_ns->child_reaper = init_pid_ns.child_reaper;
- else
- panic("Attempted to kill init!");
- }
-
if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
current->ptrace_message = code;
@@ -932,13 +922,13 @@ fastcall NORET_TYPE void do_exit(long code)
schedule();
}
+ tsk->flags |= PF_EXITING;
/*
* tsk->flags are checked in the futex code to protect against
* an exiting task cleaning up the robust pi futexes.
*/
- spin_lock_irq(&tsk->pi_lock);
- tsk->flags |= PF_EXITING;
- spin_unlock_irq(&tsk->pi_lock);
+ smp_mb();
+ spin_unlock_wait(&tsk->pi_lock);
if (unlikely(in_atomic()))
printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
@@ -952,16 +942,19 @@ fastcall NORET_TYPE void do_exit(long code)
}
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
+ exit_child_reaper(tsk);
hrtimer_cancel(&tsk->signal->real_timer);
exit_itimers(tsk->signal);
}
acct_collect(code, group_dead);
+#ifdef CONFIG_FUTEX
if (unlikely(tsk->robust_list))
exit_robust_list(tsk);
-#if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
+#ifdef CONFIG_COMPAT
if (unlikely(tsk->compat_robust_list))
compat_exit_robust_list(tsk);
#endif
+#endif
if (group_dead)
tty_audit_exit();
if (unlikely(tsk->audit_context))
@@ -996,6 +989,7 @@ fastcall NORET_TYPE void do_exit(long code)
mpol_free(tsk->mempolicy);
tsk->mempolicy = NULL;
#endif
+#ifdef CONFIG_FUTEX
/*
* This must happen late, after the PID is not
* hashed anymore:
@@ -1004,6 +998,7 @@ fastcall NORET_TYPE void do_exit(long code)
exit_pi_state_list(tsk);
if (unlikely(current->pi_state_cache))
kfree(current->pi_state_cache);
+#endif
/*
* Make sure we are holding no locks:
*/
@@ -1168,8 +1163,7 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
int __user *stat_addr, struct rusage __user *ru)
{
unsigned long state;
- int retval;
- int status;
+ int retval, status, traced;
if (unlikely(noreap)) {
pid_t pid = p->pid;
@@ -1203,15 +1197,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
BUG_ON(state != EXIT_DEAD);
return 0;
}
- if (unlikely(p->exit_signal == -1 && p->ptrace == 0)) {
- /*
- * This can only happen in a race with a ptraced thread
- * dying on another processor.
- */
- return 0;
- }
- if (likely(p->real_parent == p->parent) && likely(p->signal)) {
+ /* traced means p->ptrace, but not vice versa */
+ traced = (p->real_parent != p->parent);
+
+ if (likely(!traced)) {
struct signal_struct *psig;
struct signal_struct *sig;
@@ -1298,35 +1288,30 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
retval = put_user(p->pid, &infop->si_pid);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
- if (retval) {
- // TODO: is this safe?
- p->exit_state = EXIT_ZOMBIE;
- return retval;
- }
- retval = p->pid;
- if (p->real_parent != p->parent) {
+ if (!retval)
+ retval = p->pid;
+
+ if (traced) {
write_lock_irq(&tasklist_lock);
- /* Double-check with lock held. */
- if (p->real_parent != p->parent) {
- __ptrace_unlink(p);
- // TODO: is this safe?
- p->exit_state = EXIT_ZOMBIE;
- /*
- * If this is not a detached task, notify the parent.
- * If it's still not detached after that, don't release
- * it now.
- */
+ /* We dropped tasklist, ptracer could die and untrace */
+ ptrace_unlink(p);
+ /*
+ * If this is not a detached task, notify the parent.
+ * If it's still not detached after that, don't release
+ * it now.
+ */
+ if (p->exit_signal != -1) {
+ do_notify_parent(p, p->exit_signal);
if (p->exit_signal != -1) {
- do_notify_parent(p, p->exit_signal);
- if (p->exit_signal != -1)
- p = NULL;
+ p->exit_state = EXIT_ZOMBIE;
+ p = NULL;
}
}
write_unlock_irq(&tasklist_lock);
}
if (p != NULL)
release_task(p);
- BUG_ON(!retval);
+
return retval;
}
@@ -1345,7 +1330,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
if (!p->exit_code)
return 0;
if (delayed_group_leader && !(p->ptrace & PT_PTRACED) &&
- p->signal && p->signal->group_stop_count > 0)
+ p->signal->group_stop_count > 0)
/*
* A group stop is in progress and this is the group leader.
* We won't report until all threads have stopped.
@@ -1459,9 +1444,6 @@ static int wait_task_continued(struct task_struct *p, int noreap,
pid_t pid;
uid_t uid;
- if (unlikely(!p->signal))
- return 0;
-
if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
return 0;
diff --git a/kernel/fork.c b/kernel/fork.c
index 3fc3c138391..2ce28f165e3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -107,6 +107,7 @@ static struct kmem_cache *mm_cachep;
void free_task(struct task_struct *tsk)
{
+ prop_local_destroy_single(&tsk->dirties);
free_thread_info(tsk->stack);
rt_mutex_debug_task_free(tsk);
free_task_struct(tsk);
@@ -163,6 +164,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct task_struct *tsk;
struct thread_info *ti;
+ int err;
prepare_to_copy(orig);
@@ -178,6 +180,14 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
*tsk = *orig;
tsk->stack = ti;
+
+ err = prop_local_init_single(&tsk->dirties);
+ if (err) {
+ free_thread_info(ti);
+ free_task_struct(tsk);
+ return NULL;
+ }
+
setup_thread_stack(tsk, orig);
#ifdef CONFIG_CC_STACKPROTECTOR
@@ -258,7 +268,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
get_file(file);
if (tmp->vm_flags & VM_DENYWRITE)
atomic_dec(&inode->i_writecount);
-
+
/* insert tmp into the share list, just after mpnt */
spin_lock(&file->f_mapping->i_mmap_lock);
tmp->vm_truncate_count = mpnt->vm_truncate_count;
@@ -321,7 +331,7 @@ static inline void mm_free_pgd(struct mm_struct * mm)
#define mm_free_pgd(mm)
#endif /* CONFIG_MMU */
- __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
+__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
#define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL))
#define free_mm(mm) (kmem_cache_free(mm_cachep, (mm)))
@@ -728,8 +738,8 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
/* compute the remainder to be cleared */
size = (new_fdt->max_fds - open_files) * sizeof(struct file *);
- /* This is long word aligned thus could use a optimized version */
- memset(new_fds, 0, size);
+ /* This is long word aligned thus could use a optimized version */
+ memset(new_fds, 0, size);
if (new_fdt->max_fds > open_files) {
int left = (new_fdt->max_fds-open_files)/8;
@@ -932,6 +942,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
if (!(clone_flags & CLONE_PTRACE))
p->ptrace = 0;
p->flags = new_flags;
+ clear_freeze_flag(p);
}
asmlinkage long sys_set_tid_address(int __user *tidptr)
@@ -1048,6 +1059,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->utime = cputime_zero;
p->stime = cputime_zero;
p->gtime = cputime_zero;
+ p->utimescaled = cputime_zero;
+ p->stimescaled = cputime_zero;
#ifdef CONFIG_TASK_XACCT
p->rchar = 0; /* I/O counter: bytes read */
@@ -1058,20 +1071,21 @@ static struct task_struct *copy_process(unsigned long clone_flags,
task_io_accounting_init(p);
acct_clear_integrals(p);
- p->it_virt_expires = cputime_zero;
+ p->it_virt_expires = cputime_zero;
p->it_prof_expires = cputime_zero;
- p->it_sched_expires = 0;
- INIT_LIST_HEAD(&p->cpu_timers[0]);
- INIT_LIST_HEAD(&p->cpu_timers[1]);
- INIT_LIST_HEAD(&p->cpu_timers[2]);
+ p->it_sched_expires = 0;
+ INIT_LIST_HEAD(&p->cpu_timers[0]);
+ INIT_LIST_HEAD(&p->cpu_timers[1]);
+ INIT_LIST_HEAD(&p->cpu_timers[2]);
p->lock_depth = -1; /* -1 = no lock */
do_posix_clock_monotonic_gettime(&p->start_time);
p->real_start_time = p->start_time;
monotonic_to_bootbased(&p->real_start_time);
+#ifdef CONFIG_SECURITY
p->security = NULL;
+#endif
p->io_context = NULL;
- p->io_wait = NULL;
p->audit_context = NULL;
cpuset_fork(p);
#ifdef CONFIG_NUMA
@@ -1146,13 +1160,14 @@ static struct task_struct *copy_process(unsigned long clone_flags,
* Clear TID on mm_release()?
*/
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;
+#ifdef CONFIG_FUTEX
p->robust_list = NULL;
#ifdef CONFIG_COMPAT
p->compat_robust_list = NULL;
#endif
INIT_LIST_HEAD(&p->pi_state_list);
p->pi_state_cache = NULL;
-
+#endif
/*
* sigaltstack should be cleared when sharing the same VM
*/
@@ -1226,7 +1241,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
* A fatal signal pending means that current will exit, so the new
* thread can't slip out of an OOM kill (or normal SIGKILL).
*/
- recalc_sigpending();
+ recalc_sigpending();
if (signal_pending(current)) {
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
@@ -1435,8 +1450,7 @@ long do_fork(unsigned long clone_flags,
#define ARCH_MIN_MMSTRUCT_ALIGN 0
#endif
-static void sighand_ctor(void *data, struct kmem_cache *cachep,
- unsigned long flags)
+static void sighand_ctor(struct kmem_cache *cachep, void *data)
{
struct sighand_struct *sighand = data;
diff --git a/kernel/futex.c b/kernel/futex.c
index fcc94e7b408..e45a65e4168 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -52,6 +52,7 @@
#include <linux/syscalls.h>
#include <linux/signal.h>
#include <linux/module.h>
+#include <linux/magic.h>
#include <asm/futex.h>
#include "rtmutex_common.h"
@@ -292,7 +293,7 @@ EXPORT_SYMBOL_GPL(get_futex_key_refs);
*/
void drop_futex_key_refs(union futex_key *key)
{
- if (key->both.ptr == 0)
+ if (!key->both.ptr)
return;
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
case FUT_OFF_INODE:
@@ -1045,7 +1046,7 @@ static int unqueue_me(struct futex_q *q)
retry:
lock_ptr = q->lock_ptr;
barrier();
- if (lock_ptr != 0) {
+ if (lock_ptr != NULL) {
spin_lock(lock_ptr);
/*
* q->lock_ptr can change between reading it and
@@ -2080,7 +2081,7 @@ static int futexfs_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
struct vfsmount *mnt)
{
- return get_sb_pseudo(fs_type, "futex", NULL, 0xBAD1DEA, mnt);
+ return get_sb_pseudo(fs_type, "futex", NULL, FUTEXFS_SUPER_MAGIC, mnt);
}
static struct file_system_type futex_fs_type = {
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index dc8a4451d79..b2b2c2b0a49 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1286,8 +1286,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
{
struct hrtimer_sleeper t;
- struct timespec __user *rmtp;
- struct timespec tu;
+ struct timespec *rmtp;
ktime_t time;
restart->fn = do_no_restart_syscall;
@@ -1298,14 +1297,12 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
if (do_nanosleep(&t, HRTIMER_MODE_ABS))
return 0;
- rmtp = (struct timespec __user *) restart->arg1;
+ rmtp = (struct timespec *)restart->arg1;
if (rmtp) {
time = ktime_sub(t.timer.expires, t.timer.base->get_time());
if (time.tv64 <= 0)
return 0;
- tu = ktime_to_timespec(time);
- if (copy_to_user(rmtp, &tu, sizeof(tu)))
- return -EFAULT;
+ *rmtp = ktime_to_timespec(time);
}
restart->fn = hrtimer_nanosleep_restart;
@@ -1314,12 +1311,11 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)
return -ERESTART_RESTARTBLOCK;
}
-long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp,
const enum hrtimer_mode mode, const clockid_t clockid)
{
struct restart_block *restart;
struct hrtimer_sleeper t;
- struct timespec tu;
ktime_t rem;
hrtimer_init(&t.timer, clockid, mode);
@@ -1335,9 +1331,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
rem = ktime_sub(t.timer.expires, t.timer.base->get_time());
if (rem.tv64 <= 0)
return 0;
- tu = ktime_to_timespec(rem);
- if (copy_to_user(rmtp, &tu, sizeof(tu)))
- return -EFAULT;
+ *rmtp = ktime_to_timespec(rem);
}
restart = &current_thread_info()->restart_block;
@@ -1353,7 +1347,8 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
asmlinkage long
sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
{
- struct timespec tu;
+ struct timespec tu, rmt;
+ int ret;
if (copy_from_user(&tu, rqtp, sizeof(tu)))
return -EFAULT;
@@ -1361,7 +1356,15 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
if (!timespec_valid(&tu))
return -EINVAL;
- return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
+ ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL,
+ CLOCK_MONOTONIC);
+
+ if (ret && rmtp) {
+ if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+ return -EFAULT;
+ }
+
+ return ret;
}
/*
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index f1a73f0b54e..9b5dff6b3f6 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -503,7 +503,6 @@ out_unlock:
spin_unlock(&desc->lock);
}
-#ifdef CONFIG_SMP
/**
* handle_percpu_IRQ - Per CPU local irq handler
* @irq: the interrupt number
@@ -529,8 +528,6 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
desc->chip->eoi(irq);
}
-#endif /* CONFIG_SMP */
-
void
__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7230d914eaa..80eab7a0420 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -405,7 +405,6 @@ void free_irq(unsigned int irq, void *dev_id)
struct irq_desc *desc;
struct irqaction **p;
unsigned long flags;
- irqreturn_t (*handler)(int, void *) = NULL;
WARN_ON(in_interrupt());
if (irq >= NR_IRQS)
@@ -445,8 +444,21 @@ void free_irq(unsigned int irq, void *dev_id)
/* Make sure it's not being used on another CPU */
synchronize_irq(irq);
- if (action->flags & IRQF_SHARED)
- handler = action->handler;
+#ifdef CONFIG_DEBUG_SHIRQ
+ /*
+ * It's a shared IRQ -- the driver ought to be
+ * prepared for it to happen even now it's
+ * being freed, so let's make sure.... We do
+ * this after actually deregistering it, to
+ * make sure that a 'real' IRQ doesn't run in
+ * parallel with our fake
+ */
+ if (action->flags & IRQF_SHARED) {
+ local_irq_save(flags);
+ action->handler(irq, dev_id);
+ local_irq_restore(flags);
+ }
+#endif
kfree(action);
return;
}
@@ -454,19 +466,6 @@ void free_irq(unsigned int irq, void *dev_id)
spin_unlock_irqrestore(&desc->lock, flags);
return;
}
-#ifdef CONFIG_DEBUG_SHIRQ
- if (handler) {
- /*
- * It's a shared IRQ -- the driver ought to be prepared for it
- * to happen even now it's being freed, so let's make sure....
- * We do this after actually deregistering it, to make sure that
- * a 'real' IRQ doesn't run in parallel with our fake
- */
- local_irq_save(flags);
- handler(irq, dev_id);
- local_irq_restore(flags);
- }
-#endif
}
EXPORT_SYMBOL(free_irq);
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 3205e8e114f..2fab344dbf5 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -130,7 +130,7 @@ asmlinkage long sys_getitimer(int which, struct itimerval __user *value)
enum hrtimer_restart it_real_fn(struct hrtimer *timer)
{
struct signal_struct *sig =
- container_of(timer, struct signal_struct, real_timer);
+ container_of(timer, struct signal_struct, real_timer);
send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk);
@@ -291,6 +291,6 @@ asmlinkage long sys_setitimer(int which,
return error;
if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer)))
- return -EFAULT;
+ return -EFAULT;
return 0;
}
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 25db14b89e8..e9f1b4ea504 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -17,21 +17,30 @@
#include <linux/highmem.h>
#include <linux/syscalls.h>
#include <linux/reboot.h>
-#include <linux/syscalls.h>
#include <linux/ioport.h>
#include <linux/hardirq.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
+#include <linux/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/numa.h>
#include <asm/page.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/semaphore.h>
+#include <asm/sections.h>
/* Per cpu memory for storing cpu states in case of system crash. */
note_buf_t* crash_notes;
+/* vmcoreinfo stuff */
+unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
+u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
+size_t vmcoreinfo_size;
+size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
+
/* Location of the reserved area for the crash kernel */
struct resource crashk_res = {
.name = "Crash kernel",
@@ -776,7 +785,7 @@ static int kimage_load_normal_segment(struct kimage *image,
size_t uchunk, mchunk;
page = kimage_alloc_page(image, GFP_HIGHUSER, maddr);
- if (page == 0) {
+ if (!page) {
result = -ENOMEM;
goto out;
}
@@ -835,7 +844,7 @@ static int kimage_load_crash_segment(struct kimage *image,
size_t uchunk, mchunk;
page = pfn_to_page(maddr >> PAGE_SHIFT);
- if (page == 0) {
+ if (!page) {
result = -ENOMEM;
goto out;
}
@@ -1061,6 +1070,7 @@ void crash_kexec(struct pt_regs *regs)
if (kexec_crash_image) {
struct pt_regs fixed_regs;
crash_setup_regs(&fixed_regs, regs);
+ crash_save_vmcoreinfo();
machine_crash_shutdown(&fixed_regs);
machine_kexec(kexec_crash_image);
}
@@ -1135,3 +1145,104 @@ static int __init crash_notes_memory_init(void)
return 0;
}
module_init(crash_notes_memory_init)
+
+void crash_save_vmcoreinfo(void)
+{
+ u32 *buf;
+
+ if (!vmcoreinfo_size)
+ return;
+
+ vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds());
+
+ buf = (u32 *)vmcoreinfo_note;
+
+ buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
+ vmcoreinfo_size);
+
+ final_note(buf);
+}
+
+void vmcoreinfo_append_str(const char *fmt, ...)
+{
+ va_list args;
+ char buf[0x50];
+ int r;
+
+ va_start(args, fmt);
+ r = vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ if (r + vmcoreinfo_size > vmcoreinfo_max_size)
+ r = vmcoreinfo_max_size - vmcoreinfo_size;
+
+ memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
+
+ vmcoreinfo_size += r;
+}
+
+/*
+ * provide an empty default implementation here -- architecture
+ * code may override this
+ */
+void __attribute__ ((weak)) arch_crash_save_vmcoreinfo(void)
+{}
+
+unsigned long __attribute__ ((weak)) paddr_vmcoreinfo_note(void)
+{
+ return __pa((unsigned long)(char *)&vmcoreinfo_note);
+}
+
+static int __init crash_save_vmcoreinfo_init(void)
+{
+ vmcoreinfo_append_str("OSRELEASE=%s\n", init_uts_ns.name.release);
+ vmcoreinfo_append_str("PAGESIZE=%ld\n", PAGE_SIZE);
+
+ VMCOREINFO_SYMBOL(init_uts_ns);
+ VMCOREINFO_SYMBOL(node_online_map);
+ VMCOREINFO_SYMBOL(swapper_pg_dir);
+ VMCOREINFO_SYMBOL(_stext);
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+ VMCOREINFO_SYMBOL(mem_map);
+ VMCOREINFO_SYMBOL(contig_page_data);
+#endif
+#ifdef CONFIG_SPARSEMEM
+ VMCOREINFO_SYMBOL(mem_section);
+ VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
+ VMCOREINFO_SIZE(mem_section);
+ VMCOREINFO_OFFSET(mem_section, section_mem_map);
+#endif
+ VMCOREINFO_SIZE(page);
+ VMCOREINFO_SIZE(pglist_data);
+ VMCOREINFO_SIZE(zone);
+ VMCOREINFO_SIZE(free_area);
+ VMCOREINFO_SIZE(list_head);
+ VMCOREINFO_TYPEDEF_SIZE(nodemask_t);
+ VMCOREINFO_OFFSET(page, flags);
+ VMCOREINFO_OFFSET(page, _count);
+ VMCOREINFO_OFFSET(page, mapping);
+ VMCOREINFO_OFFSET(page, lru);
+ VMCOREINFO_OFFSET(pglist_data, node_zones);
+ VMCOREINFO_OFFSET(pglist_data, nr_zones);
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
+ VMCOREINFO_OFFSET(pglist_data, node_mem_map);
+#endif
+ VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
+ VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
+ VMCOREINFO_OFFSET(pglist_data, node_id);
+ VMCOREINFO_OFFSET(zone, free_area);
+ VMCOREINFO_OFFSET(zone, vm_stat);
+ VMCOREINFO_OFFSET(zone, spanned_pages);
+ VMCOREINFO_OFFSET(free_area, free_list);
+ VMCOREINFO_OFFSET(list_head, next);
+ VMCOREINFO_OFFSET(list_head, prev);
+ VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER);
+ VMCOREINFO_NUMBER(NR_FREE_PAGES);
+
+ arch_crash_save_vmcoreinfo();
+
+ return 0;
+}
+
+module_init(crash_save_vmcoreinfo_init)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 4b8a4493c54..e3a5d817ac9 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -64,7 +64,6 @@
static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
-static atomic_t kprobe_count;
/* NOTE: change this value only with kprobe_mutex held */
static bool kprobe_enabled;
@@ -73,11 +72,6 @@ DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
-static struct notifier_block kprobe_page_fault_nb = {
- .notifier_call = kprobe_exceptions_notify,
- .priority = 0x7fffffff /* we need to notified first */
-};
-
#ifdef __ARCH_WANT_KPROBES_INSN_SLOT
/*
* kprobe->ainsn.insn points to the copy of the instruction to be
@@ -556,8 +550,6 @@ static int __kprobes __register_kprobe(struct kprobe *p,
old_p = get_kprobe(p->addr);
if (old_p) {
ret = register_aggr_kprobe(old_p, p);
- if (!ret)
- atomic_inc(&kprobe_count);
goto out;
}
@@ -569,13 +561,9 @@ static int __kprobes __register_kprobe(struct kprobe *p,
hlist_add_head_rcu(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
- if (kprobe_enabled) {
- if (atomic_add_return(1, &kprobe_count) == \
- (ARCH_INACTIVE_KPROBE_COUNT + 1))
- register_page_fault_notifier(&kprobe_page_fault_nb);
-
+ if (kprobe_enabled)
arch_arm_kprobe(p);
- }
+
out:
mutex_unlock(&kprobe_mutex);
@@ -658,16 +646,6 @@ valid_p:
}
mutex_unlock(&kprobe_mutex);
}
-
- /* Call unregister_page_fault_notifier()
- * if no probes are active
- */
- mutex_lock(&kprobe_mutex);
- if (atomic_add_return(-1, &kprobe_count) == \
- ARCH_INACTIVE_KPROBE_COUNT)
- unregister_page_fault_notifier(&kprobe_page_fault_nb);
- mutex_unlock(&kprobe_mutex);
- return;
}
static struct notifier_block kprobe_exceptions_nb = {
@@ -738,6 +716,18 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
int ret = 0;
struct kretprobe_instance *inst;
int i;
+ void *addr = rp->kp.addr;
+
+ if (kretprobe_blacklist_size) {
+ if (addr == NULL)
+ kprobe_lookup_name(rp->kp.symbol_name, addr);
+ addr += rp->kp.offset;
+
+ for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+ if (kretprobe_blacklist[i].addr == addr)
+ return -EINVAL;
+ }
+ }
rp->kp.pre_handler = pre_handler_kretprobe;
rp->kp.post_handler = NULL;
@@ -815,7 +805,17 @@ static int __init init_kprobes(void)
INIT_HLIST_HEAD(&kprobe_table[i]);
INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
}
- atomic_set(&kprobe_count, 0);
+
+ if (kretprobe_blacklist_size) {
+ /* lookup the function address from its name */
+ for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+ kprobe_lookup_name(kretprobe_blacklist[i].name,
+ kretprobe_blacklist[i].addr);
+ if (!kretprobe_blacklist[i].addr)
+ printk("kretprobe: lookup failed: %s\n",
+ kretprobe_blacklist[i].name);
+ }
+ }
/* By default, kprobes are enabled */
kprobe_enabled = true;
@@ -921,13 +921,6 @@ static void __kprobes enable_all_kprobes(void)
if (kprobe_enabled)
goto already_enabled;
- /*
- * Re-register the page fault notifier only if there are any
- * active probes at the time of enabling kprobes globally
- */
- if (atomic_read(&kprobe_count) > ARCH_INACTIVE_KPROBE_COUNT)
- register_page_fault_notifier(&kprobe_page_fault_nb);
-
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = &kprobe_table[i];
hlist_for_each_entry_rcu(p, node, head, hlist)
@@ -968,10 +961,7 @@ static void __kprobes disable_all_kprobes(void)
mutex_unlock(&kprobe_mutex);
/* Allow all currently running kprobes to complete */
synchronize_sched();
-
- mutex_lock(&kprobe_mutex);
- /* Unconditionally unregister the page_fault notifier */
- unregister_page_fault_notifier(&kprobe_page_fault_nb);
+ return;
already_disabled:
mutex_unlock(&kprobe_mutex);
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 6046939d080..65daa5373ca 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -61,6 +61,15 @@ static ssize_t kexec_crash_loaded_show(struct kset *kset, char *page)
return sprintf(page, "%d\n", !!kexec_crash_image);
}
KERNEL_ATTR_RO(kexec_crash_loaded);
+
+static ssize_t vmcoreinfo_show(struct kset *kset, char *page)
+{
+ return sprintf(page, "%lx %x\n",
+ paddr_vmcoreinfo_note(),
+ (unsigned int)vmcoreinfo_max_size);
+}
+KERNEL_ATTR_RO(vmcoreinfo);
+
#endif /* CONFIG_KEXEC */
/*
@@ -96,6 +105,7 @@ static struct attribute * kernel_attrs[] = {
#ifdef CONFIG_KEXEC
&kexec_loaded_attr.attr,
&kexec_crash_loaded_attr.attr,
+ &vmcoreinfo_attr.attr,
#endif
NULL
};
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 734da579ad1..a6f1ee9c92d 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -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)
+ struct held_lock *hlock, int chain_head, u64 chain_key)
{
/*
* Trylock needs to maintain the stack of held locks, but it
@@ -1534,7 +1534,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
* graph_lock for us)
*/
if (!hlock->trylock && (hlock->check == 2) &&
- lookup_chain_cache(curr->curr_chain_key, hlock->class)) {
+ lookup_chain_cache(chain_key, hlock->class)) {
/*
* Check whether last held lock:
*
@@ -1576,7 +1576,7 @@ static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
#else
static inline int validate_chain(struct task_struct *curr,
struct lockdep_map *lock, struct held_lock *hlock,
- int chain_head)
+ int chain_head, u64 chain_key)
{
return 1;
}
@@ -2450,11 +2450,11 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
chain_head = 1;
}
chain_key = iterate_chain_key(chain_key, id);
- curr->curr_chain_key = chain_key;
- if (!validate_chain(curr, lock, hlock, chain_head))
+ if (!validate_chain(curr, lock, hlock, chain_head, chain_key))
return 0;
+ curr->curr_chain_key = chain_key;
curr->lockdep_depth++;
check_chain_key(curr);
#ifdef CONFIG_DEBUG_LOCKDEP
@@ -3199,3 +3199,19 @@ void debug_show_held_locks(struct task_struct *task)
}
EXPORT_SYMBOL_GPL(debug_show_held_locks);
+
+void lockdep_sys_exit(void)
+{
+ struct task_struct *curr = current;
+
+ if (unlikely(curr->lockdep_depth)) {
+ if (!debug_locks_off())
+ return;
+ printk("\n================================================\n");
+ printk( "[ BUG: lock held when returning to user space! ]\n");
+ printk( "------------------------------------------------\n");
+ printk("%s/%d is leaving the kernel with locks still held!\n",
+ curr->comm, curr->pid);
+ lockdep_print_held_locks(curr);
+ }
+}
diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c
index c851b2dcc68..8a135bd163c 100644
--- a/kernel/lockdep_proc.c
+++ b/kernel/lockdep_proc.c
@@ -25,28 +25,38 @@
static void *l_next(struct seq_file *m, void *v, loff_t *pos)
{
- struct lock_class *class = v;
+ struct lock_class *class;
(*pos)++;
- if (class->lock_entry.next != &all_lock_classes)
- class = list_entry(class->lock_entry.next, struct lock_class,
- lock_entry);
- else
- class = NULL;
- m->private = class;
+ if (v == SEQ_START_TOKEN)
+ class = m->private;
+ else {
+ class = v;
+
+ if (class->lock_entry.next != &all_lock_classes)
+ class = list_entry(class->lock_entry.next,
+ struct lock_class, lock_entry);
+ else
+ class = NULL;
+ }
return class;
}
static void *l_start(struct seq_file *m, loff_t *pos)
{
- struct lock_class *class = m->private;
+ struct lock_class *class;
+ loff_t i = 0;
- if (&class->lock_entry == all_lock_classes.next)
- seq_printf(m, "all lock classes:\n");
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
- return class;
+ list_for_each_entry(class, &all_lock_classes, lock_entry) {
+ if (++i == *pos)
+ return class;
+ }
+ return NULL;
}
static void l_stop(struct seq_file *m, void *v)
@@ -101,10 +111,15 @@ static void print_name(struct seq_file *m, struct lock_class *class)
static int l_show(struct seq_file *m, void *v)
{
unsigned long nr_forward_deps, nr_backward_deps;
- struct lock_class *class = m->private;
+ struct lock_class *class = v;
struct lock_list *entry;
char c1, c2, c3, c4;
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(m, "all lock classes:\n");
+ return 0;
+ }
+
seq_printf(m, "%p", class->key);
#ifdef CONFIG_DEBUG_LOCKDEP
seq_printf(m, " OPS:%8ld", class->ops);
@@ -523,10 +538,11 @@ static void *ls_start(struct seq_file *m, loff_t *pos)
{
struct lock_stat_seq *data = m->private;
- if (data->iter == data->stats)
- seq_header(m);
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
- if (data->iter == data->iter_end)
+ data->iter = data->stats + *pos;
+ if (data->iter >= data->iter_end)
data->iter = NULL;
return data->iter;
@@ -538,8 +554,13 @@ static void *ls_next(struct seq_file *m, void *v, loff_t *pos)
(*pos)++;
- data->iter = v;
- data->iter++;
+ if (v == SEQ_START_TOKEN)
+ data->iter = data->stats;
+ else {
+ data->iter = v;
+ data->iter++;
+ }
+
if (data->iter == data->iter_end)
data->iter = NULL;
@@ -552,9 +573,11 @@ static void ls_stop(struct seq_file *m, void *v)
static int ls_show(struct seq_file *m, void *v)
{
- struct lock_stat_seq *data = m->private;
+ if (v == SEQ_START_TOKEN)
+ seq_header(m);
+ else
+ seq_stats(m, v);
- seq_stats(m, data->iter);
return 0;
}
diff --git a/kernel/module.c b/kernel/module.c
index db0ead0363e..7734595bd32 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -20,6 +20,7 @@
#include <linux/moduleloader.h>
#include <linux/init.h>
#include <linux/kallsyms.h>
+#include <linux/sysfs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -104,7 +105,7 @@ void __module_put_and_exit(struct module *mod, long code)
do_exit(code);
}
EXPORT_SYMBOL(__module_put_and_exit);
-
+
/* Find a module section: 0 means not found. */
static unsigned int find_sec(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
@@ -178,7 +179,7 @@ static unsigned long __find_symbol(const char *name,
struct module *mod;
const struct kernel_symbol *ks;
- /* Core kernel first. */
+ /* Core kernel first. */
*owner = NULL;
ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
if (ks) {
@@ -230,7 +231,7 @@ static unsigned long __find_symbol(const char *name,
return ks->value;
}
- /* Now try modules. */
+ /* Now try modules. */
list_for_each_entry(mod, &modules, list) {
*owner = mod;
ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
@@ -284,7 +285,7 @@ static unsigned long __find_symbol(const char *name,
}
}
DEBUGP("Failed to find symbol %s\n", name);
- return 0;
+ return 0;
}
/* Search for module by name: must hold module_mutex. */
@@ -440,7 +441,7 @@ static int percpu_modinit(void)
}
return 0;
-}
+}
__initcall(percpu_modinit);
#else /* ... !CONFIG_SMP */
static inline void *percpu_modalloc(unsigned long size, unsigned long align,
@@ -482,8 +483,8 @@ static int modinfo_##field##_exists(struct module *mod) \
} \
static void free_modinfo_##field(struct module *mod) \
{ \
- kfree(mod->field); \
- mod->field = NULL; \
+ kfree(mod->field); \
+ mod->field = NULL; \
} \
static struct module_attribute modinfo_##field = { \
.attr = { .name = __stringify(field), .mode = 0444 }, \
@@ -692,8 +693,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
}
/* If it has an init func, it must have an exit func to unload */
- if ((mod->init != NULL && mod->exit == NULL)
- || mod->unsafe) {
+ if (mod->init && !mod->exit) {
forced = try_force_unload(flags);
if (!forced) {
/* This module can't be removed */
@@ -741,11 +741,6 @@ static void print_unload_info(struct seq_file *m, struct module *mod)
seq_printf(m, "%s,", use->module_which_uses->name);
}
- if (mod->unsafe) {
- printed_something = 1;
- seq_printf(m, "[unsafe],");
- }
-
if (mod->init != NULL && mod->exit == NULL) {
printed_something = 1;
seq_printf(m, "[permanent],");
@@ -995,7 +990,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
struct module_sect_attrs *sect_attrs;
struct module_sect_attr *sattr;
struct attribute **gattr;
-
+
/* Count loaded sections and allocate structures */
for (i = 0; i < nsect; i++)
if (sechdrs[i].sh_flags & SHF_ALLOC)
@@ -1053,6 +1048,100 @@ static void remove_sect_attrs(struct module *mod)
}
}
+/*
+ * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections.
+ */
+
+struct module_notes_attrs {
+ struct kobject *dir;
+ unsigned int notes;
+ struct bin_attribute attrs[0];
+};
+
+static ssize_t module_notes_read(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t count)
+{
+ /*
+ * The caller checked the pos and count against our size.
+ */
+ memcpy(buf, bin_attr->private + pos, count);
+ return count;
+}
+
+static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
+ unsigned int i)
+{
+ if (notes_attrs->dir) {
+ while (i-- > 0)
+ sysfs_remove_bin_file(notes_attrs->dir,
+ &notes_attrs->attrs[i]);
+ kobject_del(notes_attrs->dir);
+ }
+ kfree(notes_attrs);
+}
+
+static void add_notes_attrs(struct module *mod, unsigned int nsect,
+ char *secstrings, Elf_Shdr *sechdrs)
+{
+ unsigned int notes, loaded, i;
+ struct module_notes_attrs *notes_attrs;
+ struct bin_attribute *nattr;
+
+ /* Count notes sections and allocate structures. */
+ notes = 0;
+ for (i = 0; i < nsect; i++)
+ if ((sechdrs[i].sh_flags & SHF_ALLOC) &&
+ (sechdrs[i].sh_type == SHT_NOTE))
+ ++notes;
+
+ if (notes == 0)
+ return;
+
+ notes_attrs = kzalloc(sizeof(*notes_attrs)
+ + notes * sizeof(notes_attrs->attrs[0]),
+ GFP_KERNEL);
+ if (notes_attrs == NULL)
+ return;
+
+ notes_attrs->notes = notes;
+ nattr = &notes_attrs->attrs[0];
+ for (loaded = i = 0; i < nsect; ++i) {
+ if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+ if (sechdrs[i].sh_type == SHT_NOTE) {
+ nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
+ nattr->attr.mode = S_IRUGO;
+ nattr->size = sechdrs[i].sh_size;
+ nattr->private = (void *) sechdrs[i].sh_addr;
+ nattr->read = module_notes_read;
+ ++nattr;
+ }
+ ++loaded;
+ }
+
+ notes_attrs->dir = kobject_add_dir(&mod->mkobj.kobj, "notes");
+ if (!notes_attrs->dir)
+ goto out;
+
+ for (i = 0; i < notes; ++i)
+ if (sysfs_create_bin_file(notes_attrs->dir,
+ &notes_attrs->attrs[i]))
+ goto out;
+
+ mod->notes_attrs = notes_attrs;
+ return;
+
+ out:
+ free_notes_attrs(notes_attrs, i);
+}
+
+static void remove_notes_attrs(struct module *mod)
+{
+ if (mod->notes_attrs)
+ free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
+}
+
#else
static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
@@ -1063,6 +1152,15 @@ static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
static inline void remove_sect_attrs(struct module *mod)
{
}
+
+static inline void add_notes_attrs(struct module *mod, unsigned int nsect,
+ char *sectstrings, Elf_Shdr *sechdrs)
+{
+}
+
+static inline void remove_notes_attrs(struct module *mod)
+{
+}
#endif /* CONFIG_KALLSYMS */
#ifdef CONFIG_SYSFS
@@ -1197,6 +1295,7 @@ static void free_module(struct module *mod)
{
/* Delete from various lists */
stop_machine_run(__unlink_module, mod, NR_CPUS);
+ remove_notes_attrs(mod);
remove_sect_attrs(mod);
mod_kobject_remove(mod);
@@ -1249,14 +1348,14 @@ static int verify_export_symbols(struct module *mod)
const unsigned long *crc;
for (i = 0; i < mod->num_syms; i++)
- if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
+ if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
name = mod->syms[i].name;
ret = -ENOEXEC;
goto dup;
}
for (i = 0; i < mod->num_gpl_syms; i++)
- if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
+ if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
name = mod->gpl_syms[i].name;
ret = -ENOEXEC;
goto dup;
@@ -1782,7 +1881,8 @@ static struct module *load_module(void __user *umod,
module_unload_init(mod);
/* Initialize kobject, so we can reference it. */
- if (mod_sysfs_init(mod) != 0)
+ err = mod_sysfs_init(mod);
+ if (err)
goto cleanup;
/* Set up license info based on the info section */
@@ -1829,7 +1929,7 @@ static struct module *load_module(void __user *umod,
mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr;
#ifdef CONFIG_MODVERSIONS
- if ((mod->num_syms && !crcindex) ||
+ if ((mod->num_syms && !crcindex) ||
(mod->num_gpl_syms && !gplcrcindex) ||
(mod->num_gpl_future_syms && !gplfuturecrcindex) ||
(mod->num_unused_syms && !unusedcrcindex) ||
@@ -1916,7 +2016,7 @@ static struct module *load_module(void __user *umod,
if (err < 0)
goto arch_cleanup;
- err = mod_sysfs_setup(mod,
+ err = mod_sysfs_setup(mod,
(struct kernel_param *)
sechdrs[setupindex].sh_addr,
sechdrs[setupindex].sh_size
@@ -1924,11 +2024,12 @@ static struct module *load_module(void __user *umod,
if (err < 0)
goto arch_cleanup;
add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
+ add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
/* Size of section 0 is 0, so this works well if no unwind info. */
mod->unwind_info = unwind_add_table(mod,
- (void *)sechdrs[unwindex].sh_addr,
- sechdrs[unwindex].sh_size);
+ (void *)sechdrs[unwindex].sh_addr,
+ sechdrs[unwindex].sh_size);
/* Get rid of temporary copy */
vfree(hdr);
@@ -2011,15 +2112,10 @@ sys_init_module(void __user *umod,
buggy refcounters. */
mod->state = MODULE_STATE_GOING;
synchronize_sched();
- if (mod->unsafe)
- printk(KERN_ERR "%s: module is now stuck!\n",
- mod->name);
- else {
- module_put(mod);
- mutex_lock(&module_mutex);
- free_module(mod);
- mutex_unlock(&module_mutex);
- }
+ module_put(mod);
+ mutex_lock(&module_mutex);
+ free_module(mod);
+ mutex_unlock(&module_mutex);
return ret;
}
@@ -2050,7 +2146,7 @@ static inline int within(unsigned long addr, void *start, unsigned long size)
*/
static inline int is_arm_mapping_symbol(const char *str)
{
- return str[0] == '$' && strchr("atd", str[1])
+ return str[0] == '$' && strchr("atd", str[1])
&& (str[2] == '\0' || str[2] == '.');
}
@@ -2065,11 +2161,11 @@ static const char *get_ksymbol(struct module *mod,
/* At worse, next value is at end of module */
if (within(addr, mod->module_init, mod->init_size))
nextval = (unsigned long)mod->module_init+mod->init_text_size;
- else
+ else
nextval = (unsigned long)mod->module_core+mod->core_text_size;
/* Scan for closest preceeding symbol, and next symbol. (ELF
- starts real symbols at 1). */
+ starts real symbols at 1). */
for (i = 1; i < mod->num_symtab; i++) {
if (mod->symtab[i].st_shndx == SHN_UNDEF)
continue;
@@ -2311,7 +2407,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
list_for_each_entry(mod, &modules, list) {
if (mod->num_exentries == 0)
continue;
-
+
e = search_extable(mod->extable,
mod->extable + mod->num_exentries - 1,
addr);
@@ -2321,7 +2417,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr)
preempt_enable();
/* Now, if we found one, we are running inside it now, hence
- we cannot unload the module, hence no refcnt needed. */
+ we cannot unload the module, hence no refcnt needed. */
return e;
}
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 691b86564dd..d7fe50cc556 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -51,6 +51,7 @@ __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
EXPORT_SYMBOL(__mutex_init);
+#ifndef CONFIG_DEBUG_LOCK_ALLOC
/*
* We split the mutex lock/unlock logic into separate fastpath and
* slowpath functions, to reduce the register pressure on the fastpath.
@@ -92,6 +93,7 @@ void inline fastcall __sched mutex_lock(struct mutex *lock)
}
EXPORT_SYMBOL(mutex_lock);
+#endif
static void fastcall noinline __sched
__mutex_unlock_slowpath(atomic_t *lock_count);
@@ -122,7 +124,8 @@ EXPORT_SYMBOL(mutex_unlock);
* Lock a mutex (possibly interruptible), slowpath:
*/
static inline int __sched
-__mutex_lock_common(struct mutex *lock, long state, unsigned int subclass)
+__mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
+ unsigned long ip)
{
struct task_struct *task = current;
struct mutex_waiter waiter;
@@ -132,7 +135,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass)
spin_lock_mutex(&lock->wait_lock, flags);
debug_mutex_lock_common(lock, &waiter);
- mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_);
+ mutex_acquire(&lock->dep_map, subclass, 0, ip);
debug_mutex_add_waiter(lock, &waiter, task_thread_info(task));
/* add waiting tasks to the end of the waitqueue (FIFO): */
@@ -143,7 +146,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass)
if (old_val == 1)
goto done;
- lock_contended(&lock->dep_map, _RET_IP_);
+ lock_contended(&lock->dep_map, ip);
for (;;) {
/*
@@ -166,7 +169,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass)
if (unlikely(state == TASK_INTERRUPTIBLE &&
signal_pending(task))) {
mutex_remove_waiter(lock, &waiter, task_thread_info(task));
- mutex_release(&lock->dep_map, 1, _RET_IP_);
+ mutex_release(&lock->dep_map, 1, ip);
spin_unlock_mutex(&lock->wait_lock, flags);
debug_mutex_free_waiter(&waiter);
@@ -197,20 +200,12 @@ done:
return 0;
}
-static void fastcall noinline __sched
-__mutex_lock_slowpath(atomic_t *lock_count)
-{
- struct mutex *lock = container_of(lock_count, struct mutex, count);
-
- __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0);
-}
-
#ifdef CONFIG_DEBUG_LOCK_ALLOC
void __sched
mutex_lock_nested(struct mutex *lock, unsigned int subclass)
{
might_sleep();
- __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass);
+ __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, subclass, _RET_IP_);
}
EXPORT_SYMBOL_GPL(mutex_lock_nested);
@@ -219,7 +214,7 @@ int __sched
mutex_lock_interruptible_nested(struct mutex *lock, unsigned int subclass)
{
might_sleep();
- return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, subclass);
+ return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, subclass, _RET_IP_);
}
EXPORT_SYMBOL_GPL(mutex_lock_interruptible_nested);
@@ -271,6 +266,7 @@ __mutex_unlock_slowpath(atomic_t *lock_count)
__mutex_unlock_common_slowpath(lock_count, 1);
}
+#ifndef CONFIG_DEBUG_LOCK_ALLOC
/*
* Here come the less common (and hence less performance-critical) APIs:
* mutex_lock_interruptible() and mutex_trylock().
@@ -298,13 +294,22 @@ int fastcall __sched mutex_lock_interruptible(struct mutex *lock)
EXPORT_SYMBOL(mutex_lock_interruptible);
+static void fastcall noinline __sched
+__mutex_lock_slowpath(atomic_t *lock_count)
+{
+ struct mutex *lock = container_of(lock_count, struct mutex, count);
+
+ __mutex_lock_common(lock, TASK_UNINTERRUPTIBLE, 0, _RET_IP_);
+}
+
static int fastcall noinline __sched
__mutex_lock_interruptible_slowpath(atomic_t *lock_count)
{
struct mutex *lock = container_of(lock_count, struct mutex, count);
- return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0);
+ return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, _RET_IP_);
}
+#endif
/*
* Spinlock based trylock, we take the spinlock and check whether we
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index f1decd21a53..049e7c0ac56 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -203,8 +203,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
static int __init nsproxy_cache_init(void)
{
- nsproxy_cachep = kmem_cache_create("nsproxy", sizeof(struct nsproxy),
- 0, SLAB_PANIC, NULL);
+ nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
return 0;
}
diff --git a/kernel/panic.c b/kernel/panic.c
index f64f4c1ac11..3886bd8230f 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -56,14 +56,14 @@ EXPORT_SYMBOL(panic_blink);
*
* This function never returns.
*/
-
+
NORET_TYPE void panic(const char * fmt, ...)
{
long i;
static char buf[1024];
va_list args;
#if defined(CONFIG_S390)
- unsigned long caller = (unsigned long) __builtin_return_address(0);
+ unsigned long caller = (unsigned long) __builtin_return_address(0);
#endif
/*
@@ -128,7 +128,7 @@ NORET_TYPE void panic(const char * fmt, ...)
}
#endif
#if defined(CONFIG_S390)
- disabled_wait(caller);
+ disabled_wait(caller);
#endif
local_irq_enable();
for (i = 0;;) {
@@ -154,7 +154,7 @@ EXPORT_SYMBOL(panic);
*
* The string is overwritten by the next call to print_taint().
*/
-
+
const char *print_tainted(void)
{
static char buf[20];
@@ -164,7 +164,7 @@ const char *print_tainted(void)
tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
- tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
+ tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
tainted & TAINT_BAD_PAGE ? 'B' : ' ',
tainted & TAINT_USER ? 'U' : ' ',
tainted & TAINT_DIE ? 'D' : ' ');
diff --git a/kernel/params.c b/kernel/params.c
index 4e57732fcfb..16f269e9ddc 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -252,8 +252,9 @@ int param_get_bool(char *buffer, struct kernel_param *kp)
int param_set_invbool(const char *val, struct kernel_param *kp)
{
int boolval, ret;
- struct kernel_param dummy = { .arg = &boolval };
+ struct kernel_param dummy;
+ dummy.arg = &boolval;
ret = param_set_bool(val, &dummy);
if (ret == 0)
*(int *)kp->arg = !boolval;
@@ -262,11 +263,7 @@ int param_set_invbool(const char *val, struct kernel_param *kp)
int param_get_invbool(char *buffer, struct kernel_param *kp)
{
- int val;
- struct kernel_param dummy = { .arg = &val };
-
- val = !*(int *)kp->arg;
- return param_get_bool(buffer, &dummy);
+ return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y');
}
/* We break the rule and mangle the string. */
@@ -325,7 +322,7 @@ static int param_array(const char *name,
int param_array_set(const char *val, struct kernel_param *kp)
{
- struct kparam_array *arr = kp->arg;
+ const struct kparam_array *arr = kp->arr;
unsigned int temp_num;
return param_array(kp->name, val, 1, arr->max, arr->elem,
@@ -335,7 +332,7 @@ int param_array_set(const char *val, struct kernel_param *kp)
int param_array_get(char *buffer, struct kernel_param *kp)
{
int i, off, ret;
- struct kparam_array *arr = kp->arg;
+ const struct kparam_array *arr = kp->arr;
struct kernel_param p;
p = *kp;
@@ -354,7 +351,7 @@ int param_array_get(char *buffer, struct kernel_param *kp)
int param_set_copystring(const char *val, struct kernel_param *kp)
{
- struct kparam_string *kps = kp->arg;
+ const struct kparam_string *kps = kp->str;
if (!val) {
printk(KERN_ERR "%s: missing param set value\n", kp->name);
@@ -371,7 +368,7 @@ int param_set_copystring(const char *val, struct kernel_param *kp)
int param_get_string(char *buffer, struct kernel_param *kp)
{
- struct kparam_string *kps = kp->arg;
+ const struct kparam_string *kps = kp->str;
return strlcpy(buffer, kps->string, kps->maxlen);
}
@@ -595,11 +592,17 @@ static void __init param_sysfs_builtin(void)
for (i=0; i < __stop___param - __start___param; i++) {
char *dot;
+ size_t kplen;
kp = &__start___param[i];
+ kplen = strlen(kp->name);
/* We do not handle args without periods. */
- dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME);
+ if (kplen > MAX_KBUILD_MODNAME) {
+ DEBUGP("kernel parameter name is too long: %s\n", kp->name);
+ continue;
+ }
+ dot = memchr(kp->name, '.', kplen);
if (!dot) {
DEBUGP("couldn't find period in %s\n", kp->name);
continue;
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 57efe0400bc..d11f579d189 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -241,7 +241,8 @@ static __init int init_posix_timers(void)
register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
posix_timers_cache = kmem_cache_create("posix_timers_cache",
- sizeof (struct k_itimer), 0, 0, NULL);
+ sizeof (struct k_itimer), 0, SLAB_PANIC,
+ NULL);
idr_init(&posix_timers_id);
return 0;
}
@@ -980,9 +981,20 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp)
static int common_nsleep(const clockid_t which_clock, int flags,
struct timespec *tsave, struct timespec __user *rmtp)
{
- return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ?
- HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
- which_clock);
+ struct timespec rmt;
+ int ret;
+
+ ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL,
+ flags & TIMER_ABSTIME ?
+ HRTIMER_MODE_ABS : HRTIMER_MODE_REL,
+ which_clock);
+
+ if (ret && rmtp) {
+ if (copy_to_user(rmtp, &rmt, sizeof(*rmtp)))
+ return -EFAULT;
+ }
+
+ return ret;
}
asmlinkage long
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 14b0e10dc95..8e186c67814 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -44,17 +44,6 @@ config PM_VERBOSE
---help---
This option enables verbose messages from the Power Management code.
-config DISABLE_CONSOLE_SUSPEND
- bool "Keep console(s) enabled during suspend/resume (DANGEROUS)"
- depends on PM_DEBUG && PM_SLEEP
- default n
- ---help---
- This option turns off the console suspend mechanism that prevents
- debug messages from reaching the console during the suspend/resume
- operations. This may be helpful when debugging device drivers'
- suspend/resume routines, but may itself lead to problems, for example
- if netconsole is used.
-
config PM_TRACE
bool "Suspend/resume event tracing"
depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index eb72255b5c8..8b15f777010 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -45,17 +45,18 @@ enum {
static int hibernation_mode = HIBERNATION_SHUTDOWN;
-static struct hibernation_ops *hibernation_ops;
+static struct platform_hibernation_ops *hibernation_ops;
/**
* hibernation_set_ops - set the global hibernate operations
* @ops: the hibernation operations to use in subsequent hibernation transitions
*/
-void hibernation_set_ops(struct hibernation_ops *ops)
+void hibernation_set_ops(struct platform_hibernation_ops *ops)
{
- if (ops && !(ops->prepare && ops->enter && ops->finish
- && ops->pre_restore && ops->restore_cleanup)) {
+ if (ops && !(ops->start && ops->pre_snapshot && ops->finish
+ && ops->prepare && ops->enter && ops->pre_restore
+ && ops->restore_cleanup)) {
WARN_ON(1);
return;
}
@@ -69,16 +70,37 @@ void hibernation_set_ops(struct hibernation_ops *ops)
mutex_unlock(&pm_mutex);
}
+/**
+ * platform_start - tell the platform driver that we're starting
+ * hibernation
+ */
+
+static int platform_start(int platform_mode)
+{
+ return (platform_mode && hibernation_ops) ?
+ hibernation_ops->start() : 0;
+}
/**
- * platform_prepare - prepare the machine for hibernation using the
+ * platform_pre_snapshot - prepare the machine for hibernation using the
* platform driver if so configured and return an error code if it fails
*/
-static int platform_prepare(int platform_mode)
+static int platform_pre_snapshot(int platform_mode)
{
return (platform_mode && hibernation_ops) ?
- hibernation_ops->prepare() : 0;
+ hibernation_ops->pre_snapshot() : 0;
+}
+
+/**
+ * platform_leave - prepare the machine for switching to the normal mode
+ * of operation using the platform driver (called with interrupts disabled)
+ */
+
+static void platform_leave(int platform_mode)
+{
+ if (platform_mode && hibernation_ops)
+ hibernation_ops->leave();
}
/**
@@ -118,6 +140,51 @@ static void platform_restore_cleanup(int platform_mode)
}
/**
+ * create_image - freeze devices that need to be frozen with interrupts
+ * off, create the hibernation image and thaw those devices. Control
+ * reappears in this routine after a restore.
+ */
+
+int create_image(int platform_mode)
+{
+ int error;
+
+ error = arch_prepare_suspend();
+ if (error)
+ return error;
+
+ local_irq_disable();
+ /* At this point, device_suspend() has been called, but *not*
+ * device_power_down(). We *must* call device_power_down() now.
+ * Otherwise, drivers for some devices (e.g. interrupt controllers)
+ * become desynchronized with the actual state of the hardware
+ * at resume time, and evil weirdness ensues.
+ */
+ error = device_power_down(PMSG_FREEZE);
+ if (error) {
+ printk(KERN_ERR "Some devices failed to power down, "
+ KERN_ERR "aborting suspend\n");
+ goto Enable_irqs;
+ }
+
+ save_processor_state();
+ error = swsusp_arch_suspend();
+ if (error)
+ printk(KERN_ERR "Error %d while creating the image\n", error);
+ /* Restore control flow magically appears here */
+ restore_processor_state();
+ if (!in_suspend)
+ platform_leave(platform_mode);
+ /* NOTE: device_power_up() is just a resume() for devices
+ * that suspended with irqs off ... no overall powerup.
+ */
+ device_power_up();
+ Enable_irqs:
+ local_irq_enable();
+ return error;
+}
+
+/**
* hibernation_snapshot - quiesce devices and create the hibernation
* snapshot image.
* @platform_mode - if set, use the platform driver, if available, to
@@ -135,12 +202,16 @@ int hibernation_snapshot(int platform_mode)
if (error)
return error;
+ error = platform_start(platform_mode);
+ if (error)
+ return error;
+
suspend_console();
error = device_suspend(PMSG_FREEZE);
if (error)
goto Resume_console;
- error = platform_prepare(platform_mode);
+ error = platform_pre_snapshot(platform_mode);
if (error)
goto Resume_devices;
@@ -148,7 +219,7 @@ int hibernation_snapshot(int platform_mode)
if (!error) {
if (hibernation_mode != HIBERNATION_TEST) {
in_suspend = 1;
- error = swsusp_suspend();
+ error = create_image(platform_mode);
/* Control returns here after successful restore */
} else {
printk("swsusp debug: Waiting for 5 seconds.\n");
@@ -207,21 +278,50 @@ int hibernation_platform_enter(void)
{
int error;
- if (hibernation_ops) {
- kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
- /*
- * We have cancelled the power transition by running
- * hibernation_ops->finish() before saving the image, so we
- * should let the firmware know that we're going to enter the
- * sleep state after all
- */
- error = hibernation_ops->prepare();
- sysdev_shutdown();
- if (!error)
- error = hibernation_ops->enter();
- } else {
- error = -ENOSYS;
+ if (!hibernation_ops)
+ return -ENOSYS;
+
+ /*
+ * We have cancelled the power transition by running
+ * hibernation_ops->finish() before saving the image, so we should let
+ * the firmware know that we're going to enter the sleep state after all
+ */
+ error = hibernation_ops->start();
+ if (error)
+ return error;
+
+ suspend_console();
+ error = device_suspend(PMSG_SUSPEND);
+ if (error)
+ goto Resume_console;
+
+ error = hibernation_ops->prepare();
+ if (error)
+ goto Resume_devices;
+
+ error = disable_nonboot_cpus();
+ if (error)
+ goto Finish;
+
+ local_irq_disable();
+ error = device_power_down(PMSG_SUSPEND);
+ if (!error) {
+ hibernation_ops->enter();
+ /* We should never get here */
+ while (1);
}
+ local_irq_enable();
+
+ /*
+ * We don't need to reenable the nonboot CPUs or resume consoles, since
+ * the system is going to be halted anyway.
+ */
+ Finish:
+ hibernation_ops->finish();
+ Resume_devices:
+ device_resume();
+ Resume_console:
+ resume_console();
return error;
}
@@ -238,14 +338,14 @@ static void power_down(void)
case HIBERNATION_TEST:
case HIBERNATION_TESTPROC:
break;
- case HIBERNATION_SHUTDOWN:
- kernel_power_off();
- break;
case HIBERNATION_REBOOT:
kernel_restart(NULL);
break;
case HIBERNATION_PLATFORM:
hibernation_platform_enter();
+ case HIBERNATION_SHUTDOWN:
+ kernel_power_off();
+ break;
}
kernel_halt();
/*
@@ -298,6 +398,10 @@ int hibernate(void)
if (error)
goto Exit;
+ printk("Syncing filesystems ... ");
+ sys_sync();
+ printk("done.\n");
+
error = prepare_processes();
if (error)
goto Finish;
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 350b485b3b6..3cdf95b1dc9 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -20,6 +20,7 @@
#include <linux/resume-trace.h>
#include <linux/freezer.h>
#include <linux/vmstat.h>
+#include <linux/syscalls.h>
#include "power.h"
@@ -32,39 +33,32 @@ DEFINE_MUTEX(pm_mutex);
/* This is just an arbitrary number */
#define FREE_PAGE_NUMBER (100)
-struct pm_ops *pm_ops;
+static struct platform_suspend_ops *suspend_ops;
/**
- * pm_set_ops - Set the global power method table.
+ * suspend_set_ops - Set the global suspend method table.
* @ops: Pointer to ops structure.
*/
-void pm_set_ops(struct pm_ops * ops)
+void suspend_set_ops(struct platform_suspend_ops *ops)
{
mutex_lock(&pm_mutex);
- pm_ops = ops;
+ suspend_ops = ops;
mutex_unlock(&pm_mutex);
}
/**
- * pm_valid_only_mem - generic memory-only valid callback
+ * suspend_valid_only_mem - generic memory-only valid callback
*
- * pm_ops drivers that implement mem suspend only and only need
+ * Platform drivers that implement mem suspend only and only need
* to check for that in their .valid callback can use this instead
* of rolling their own .valid callback.
*/
-int pm_valid_only_mem(suspend_state_t state)
+int suspend_valid_only_mem(suspend_state_t state)
{
return state == PM_SUSPEND_MEM;
}
-
-static inline void pm_finish(suspend_state_t state)
-{
- if (pm_ops->finish)
- pm_ops->finish(state);
-}
-
/**
* suspend_prepare - Do prep work before entering low-power state.
*
@@ -76,7 +70,7 @@ static int suspend_prepare(void)
int error;
unsigned int free_pages;
- if (!pm_ops || !pm_ops->enter)
+ if (!suspend_ops || !suspend_ops->enter)
return -EPERM;
error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
@@ -128,7 +122,7 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void)
*
* This function should be called after devices have been suspended.
*/
-int suspend_enter(suspend_state_t state)
+static int suspend_enter(suspend_state_t state)
{
int error = 0;
@@ -139,7 +133,7 @@ int suspend_enter(suspend_state_t state)
printk(KERN_ERR "Some devices failed to power down\n");
goto Done;
}
- error = pm_ops->enter(state);
+ error = suspend_ops->enter(state);
device_power_up();
Done:
arch_suspend_enable_irqs();
@@ -156,11 +150,11 @@ int suspend_devices_and_enter(suspend_state_t state)
{
int error;
- if (!pm_ops)
+ if (!suspend_ops)
return -ENOSYS;
- if (pm_ops->set_target) {
- error = pm_ops->set_target(state);
+ if (suspend_ops->set_target) {
+ error = suspend_ops->set_target(state);
if (error)
return error;
}
@@ -170,8 +164,8 @@ int suspend_devices_and_enter(suspend_state_t state)
printk(KERN_ERR "Some devices failed to suspend\n");
goto Resume_console;
}
- if (pm_ops->prepare) {
- error = pm_ops->prepare(state);
+ if (suspend_ops->prepare) {
+ error = suspend_ops->prepare();
if (error)
goto Resume_devices;
}
@@ -180,7 +174,8 @@ int suspend_devices_and_enter(suspend_state_t state)
suspend_enter(state);
enable_nonboot_cpus();
- pm_finish(state);
+ if (suspend_ops->finish)
+ suspend_ops->finish();
Resume_devices:
device_resume();
Resume_console:
@@ -214,7 +209,7 @@ static inline int valid_state(suspend_state_t state)
/* All states need lowlevel support and need to be valid
* to the lowlevel implementation, no valid callback
* implies that none are valid. */
- if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state))
+ if (!suspend_ops || !suspend_ops->valid || !suspend_ops->valid(state))
return 0;
return 1;
}
@@ -236,9 +231,14 @@ static int enter_state(suspend_state_t state)
if (!valid_state(state))
return -ENODEV;
+
if (!mutex_trylock(&pm_mutex))
return -EBUSY;
+ printk("Syncing filesystems ... ");
+ sys_sync();
+ printk("done.\n");
+
pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
if ((error = suspend_prepare()))
goto Unlock;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 95fbf2dd3fe..195dc461176 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -11,14 +11,32 @@ struct swsusp_info {
unsigned long size;
} __attribute__((aligned(PAGE_SIZE)));
+#ifdef CONFIG_HIBERNATION
+#ifdef CONFIG_ARCH_HIBERNATION_HEADER
+/* Maximum size of architecture specific data in a hibernation header */
+#define MAX_ARCH_HEADER_SIZE (sizeof(struct new_utsname) + 4)
+extern int arch_hibernation_header_save(void *addr, unsigned int max_size);
+extern int arch_hibernation_header_restore(void *addr);
+
+static inline int init_header_complete(struct swsusp_info *info)
+{
+ return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE);
+}
+
+static inline char *check_image_kernel(struct swsusp_info *info)
+{
+ return arch_hibernation_header_restore(info) ?
+ "architecture specific data" : NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
-#ifdef CONFIG_HIBERNATION
/*
* Keep some memory free so that I/O operations can succeed without paging
* [Might this be more than 4 MB?]
*/
#define PAGES_FOR_IO ((4096 * 1024) >> PAGE_SHIFT)
+
/*
* Keep 1 MB of memory free so that device drivers can allocate some pages in
* their .suspend() routines without breaking the suspend to disk.
@@ -165,7 +183,6 @@ extern int swsusp_swap_in_use(void);
extern int swsusp_check(void);
extern int swsusp_shrink_memory(void);
extern void swsusp_free(void);
-extern int swsusp_suspend(void);
extern int swsusp_resume(void);
extern int swsusp_read(unsigned int *flags_p);
extern int swsusp_write(unsigned int flags);
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 3434940a3df..6533923e711 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -75,21 +75,79 @@ void refrigerator(void)
__set_current_state(save);
}
-static void freeze_task(struct task_struct *p)
+static void fake_signal_wake_up(struct task_struct *p, int resume)
{
unsigned long flags;
- if (!freezing(p)) {
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ signal_wake_up(p, resume);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+}
+
+static void send_fake_signal(struct task_struct *p)
+{
+ if (p->state == TASK_STOPPED)
+ force_sig_specific(SIGSTOP, p);
+ fake_signal_wake_up(p, p->state == TASK_STOPPED);
+}
+
+static int has_mm(struct task_struct *p)
+{
+ return (p->mm && !(p->flags & PF_BORROWED_MM));
+}
+
+/**
+ * freeze_task - send a freeze request to given task
+ * @p: task to send the request to
+ * @with_mm_only: if set, the request will only be sent if the task has its
+ * own mm
+ * Return value: 0, if @with_mm_only is set and the task has no mm of its
+ * own or the task is frozen, 1, otherwise
+ *
+ * The freeze request is sent by seting the tasks's TIF_FREEZE flag and
+ * either sending a fake signal to it or waking it up, depending on whether
+ * or not it has its own mm (ie. it is a user land task). If @with_mm_only
+ * is set and the task has no mm of its own (ie. it is a kernel thread),
+ * its TIF_FREEZE flag should not be set.
+ *
+ * The task_lock() is necessary to prevent races with exit_mm() or
+ * use_mm()/unuse_mm() from occuring.
+ */
+static int freeze_task(struct task_struct *p, int with_mm_only)
+{
+ int ret = 1;
+
+ task_lock(p);
+ if (freezing(p)) {
+ if (has_mm(p)) {
+ if (!signal_pending(p))
+ fake_signal_wake_up(p, 0);
+ } else {
+ if (with_mm_only)
+ ret = 0;
+ else
+ wake_up_state(p, TASK_INTERRUPTIBLE);
+ }
+ } else {
rmb();
- if (!frozen(p)) {
- set_freeze_flag(p);
- if (p->state == TASK_STOPPED)
- force_sig_specific(SIGSTOP, p);
- spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, p->state == TASK_STOPPED);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ if (frozen(p)) {
+ ret = 0;
+ } else {
+ if (has_mm(p)) {
+ set_freeze_flag(p);
+ send_fake_signal(p);
+ } else {
+ if (with_mm_only) {
+ ret = 0;
+ } else {
+ set_freeze_flag(p);
+ wake_up_state(p, TASK_INTERRUPTIBLE);
+ }
+ }
}
}
+ task_unlock(p);
+ return ret;
}
static void cancel_freezing(struct task_struct *p)
@@ -110,6 +168,11 @@ static int try_to_freeze_tasks(int freeze_user_space)
struct task_struct *g, *p;
unsigned long end_time;
unsigned int todo;
+ struct timeval start, end;
+ s64 elapsed_csecs64;
+ unsigned int elapsed_csecs;
+
+ do_gettimeofday(&start);
end_time = jiffies + TIMEOUT;
do {
@@ -119,31 +182,14 @@ static int try_to_freeze_tasks(int freeze_user_space)
if (frozen(p) || !freezeable(p))
continue;
- if (freeze_user_space) {
- if (p->state == TASK_TRACED &&
- frozen(p->parent)) {
- cancel_freezing(p);
- continue;
- }
- /*
- * Kernel threads should not have TIF_FREEZE set
- * at this point, so we must ensure that either
- * p->mm is not NULL *and* PF_BORROWED_MM is
- * unset, or TIF_FRREZE is left unset.
- * The task_lock() is necessary to prevent races
- * with exit_mm() or use_mm()/unuse_mm() from
- * occuring.
- */
- task_lock(p);
- if (!p->mm || (p->flags & PF_BORROWED_MM)) {
- task_unlock(p);
- continue;
- }
- freeze_task(p);
- task_unlock(p);
- } else {
- freeze_task(p);
+ if (p->state == TASK_TRACED && frozen(p->parent)) {
+ cancel_freezing(p);
+ continue;
}
+
+ if (!freeze_task(p, freeze_user_space))
+ continue;
+
if (!freezer_should_skip(p))
todo++;
} while_each_thread(g, p);
@@ -153,6 +199,11 @@ static int try_to_freeze_tasks(int freeze_user_space)
break;
} while (todo);
+ do_gettimeofday(&end);
+ elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
+ do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
+ elapsed_csecs = elapsed_csecs64;
+
if (todo) {
/* This does not unfreeze processes that are already frozen
* (we have slightly ugly calling convention in that respect,
@@ -160,10 +211,9 @@ static int try_to_freeze_tasks(int freeze_user_space)
* but it cleans up leftover PF_FREEZE requests.
*/
printk("\n");
- printk(KERN_ERR "Freezing of %s timed out after %d seconds "
+ printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
"(%d tasks refusing to freeze):\n",
- freeze_user_space ? "user space " : "tasks ",
- TIMEOUT / HZ, todo);
+ elapsed_csecs / 100, elapsed_csecs % 100, todo);
show_state();
read_lock(&tasklist_lock);
do_each_thread(g, p) {
@@ -174,6 +224,9 @@ static int try_to_freeze_tasks(int freeze_user_space)
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
+ } else {
+ printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
+ elapsed_csecs % 100);
}
return todo ? -EBUSY : 0;
@@ -186,19 +239,21 @@ int freeze_processes(void)
{
int error;
- printk("Stopping tasks ... ");
+ printk("Freezing user space processes ... ");
error = try_to_freeze_tasks(FREEZER_USER_SPACE);
if (error)
- return error;
+ goto Exit;
+ printk("done.\n");
- sys_sync();
+ printk("Freezing remaining freezable tasks ... ");
error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS);
if (error)
- return error;
-
- printk("done.\n");
+ goto Exit;
+ printk("done.");
+ Exit:
BUG_ON(in_atomic());
- return 0;
+ printk("\n");
+ return error;
}
static void thaw_tasks(int thaw_user_space)
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index a686590d88c..ccc95ac07be 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1239,17 +1239,39 @@ asmlinkage int swsusp_save(void)
return 0;
}
-static void init_header(struct swsusp_info *info)
+#ifndef CONFIG_ARCH_HIBERNATION_HEADER
+static int init_header_complete(struct swsusp_info *info)
{
- memset(info, 0, sizeof(struct swsusp_info));
+ memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
info->version_code = LINUX_VERSION_CODE;
+ return 0;
+}
+
+static char *check_image_kernel(struct swsusp_info *info)
+{
+ if (info->version_code != LINUX_VERSION_CODE)
+ return "kernel version";
+ if (strcmp(info->uts.sysname,init_utsname()->sysname))
+ return "system type";
+ if (strcmp(info->uts.release,init_utsname()->release))
+ return "kernel release";
+ if (strcmp(info->uts.version,init_utsname()->version))
+ return "version";
+ if (strcmp(info->uts.machine,init_utsname()->machine))
+ return "machine";
+ return NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
+static int init_header(struct swsusp_info *info)
+{
+ memset(info, 0, sizeof(struct swsusp_info));
info->num_physpages = num_physpages;
- memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
- info->cpus = num_online_cpus();
info->image_pages = nr_copy_pages;
info->pages = nr_copy_pages + nr_meta_pages + 1;
info->size = info->pages;
info->size <<= PAGE_SHIFT;
+ return init_header_complete(info);
}
/**
@@ -1303,7 +1325,11 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count)
return -ENOMEM;
}
if (!handle->offset) {
- init_header((struct swsusp_info *)buffer);
+ int error;
+
+ error = init_header((struct swsusp_info *)buffer);
+ if (error)
+ return error;
handle->buffer = buffer;
memory_bm_position_reset(&orig_bm);
memory_bm_position_reset(&copy_bm);
@@ -1394,22 +1420,13 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src)
}
}
-static inline int check_header(struct swsusp_info *info)
+static int check_header(struct swsusp_info *info)
{
- char *reason = NULL;
+ char *reason;
- if (info->version_code != LINUX_VERSION_CODE)
- reason = "kernel version";
- if (info->num_physpages != num_physpages)
+ reason = check_image_kernel(info);
+ if (!reason && info->num_physpages != num_physpages)
reason = "memory size";
- if (strcmp(info->uts.sysname,init_utsname()->sysname))
- reason = "system type";
- if (strcmp(info->uts.release,init_utsname()->release))
- reason = "kernel release";
- if (strcmp(info->uts.version,init_utsname()->version))
- reason = "version";
- if (strcmp(info->uts.machine,init_utsname()->machine))
- reason = "machine";
if (reason) {
printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
return -EPERM;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 5da304c8f1f..e1722d3155f 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -270,39 +270,6 @@ int swsusp_shrink_memory(void)
return 0;
}
-int swsusp_suspend(void)
-{
- int error;
-
- if ((error = arch_prepare_suspend()))
- return error;
-
- local_irq_disable();
- /* At this point, device_suspend() has been called, but *not*
- * device_power_down(). We *must* device_power_down() now.
- * Otherwise, drivers for some devices (e.g. interrupt controllers)
- * become desynchronized with the actual state of the hardware
- * at resume time, and evil weirdness ensues.
- */
- if ((error = device_power_down(PMSG_FREEZE))) {
- printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
- goto Enable_irqs;
- }
-
- save_processor_state();
- if ((error = swsusp_arch_suspend()))
- printk(KERN_ERR "Error %d suspending\n", error);
- /* Restore control flow magically appears here */
- restore_processor_state();
- /* NOTE: device_power_up() is just a resume() for devices
- * that suspended with irqs off ... no overall powerup.
- */
- device_power_up();
- Enable_irqs:
- local_irq_enable();
- return error;
-}
-
int swsusp_resume(void)
{
int error;
diff --git a/kernel/power/user.c b/kernel/power/user.c
index bd0723a7df3..5bd321bcbb7 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -153,6 +153,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
mutex_lock(&pm_mutex);
error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
if (!error) {
+ printk("Syncing filesystems ... ");
+ sys_sync();
+ printk("done.\n");
+
error = freeze_processes();
if (error)
thaw_processes();
diff --git a/kernel/printk.c b/kernel/printk.c
index 8451dfc31d2..a30fe33de39 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -22,6 +22,8 @@
#include <linux/tty_driver.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/nmi.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h> /* For in_interrupt() */
@@ -162,6 +164,113 @@ out:
__setup("log_buf_len=", log_buf_len_setup);
+#ifdef CONFIG_BOOT_PRINTK_DELAY
+
+static unsigned int boot_delay; /* msecs delay after each printk during bootup */
+static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */
+
+static int __init boot_delay_setup(char *str)
+{
+ unsigned long lpj;
+ unsigned long long loops_per_msec;
+
+ lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */
+ loops_per_msec = (unsigned long long)lpj / 1000 * HZ;
+
+ get_option(&str, &boot_delay);
+ if (boot_delay > 10 * 1000)
+ boot_delay = 0;
+
+ printk_delay_msec = loops_per_msec;
+ printk(KERN_DEBUG "boot_delay: %u, preset_lpj: %ld, lpj: %lu, "
+ "HZ: %d, printk_delay_msec: %llu\n",
+ boot_delay, preset_lpj, lpj, HZ, printk_delay_msec);
+ return 1;
+}
+__setup("boot_delay=", boot_delay_setup);
+
+static void boot_delay_msec(void)
+{
+ unsigned long long k;
+ unsigned long timeout;
+
+ if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
+ return;
+
+ k = (unsigned long long)printk_delay_msec * boot_delay;
+
+ timeout = jiffies + msecs_to_jiffies(boot_delay);
+ while (k) {
+ k--;
+ cpu_relax();
+ /*
+ * use (volatile) jiffies to prevent
+ * compiler reduction; loop termination via jiffies
+ * is secondary and may or may not happen.
+ */
+ if (time_after(jiffies, timeout))
+ break;
+ touch_nmi_watchdog();
+ }
+}
+#else
+static inline void boot_delay_msec(void)
+{
+}
+#endif
+
+/*
+ * Return the number of unread characters in the log buffer.
+ */
+int log_buf_get_len(void)
+{
+ return logged_chars;
+}
+
+/*
+ * Copy a range of characters from the log buffer.
+ */
+int log_buf_copy(char *dest, int idx, int len)
+{
+ int ret, max;
+ bool took_lock = false;
+
+ if (!oops_in_progress) {
+ spin_lock_irq(&logbuf_lock);
+ took_lock = true;
+ }
+
+ max = log_buf_get_len();
+ if (idx < 0 || idx >= max) {
+ ret = -1;
+ } else {
+ if (len > max)
+ len = max;
+ ret = len;
+ idx += (log_end - max);
+ while (len-- > 0)
+ dest[len] = LOG_BUF(idx + len);
+ }
+
+ if (took_lock)
+ spin_unlock_irq(&logbuf_lock);
+
+ return ret;
+}
+
+/*
+ * Extract a single character from the log buffer.
+ */
+int log_buf_read(int idx)
+{
+ char ret;
+
+ if (log_buf_copy(&ret, idx, 1) == 1)
+ return ret;
+ else
+ return -1;
+}
+
/*
* Commands to do_syslog:
*
@@ -527,6 +636,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
static char printk_buf[1024];
static int log_level_unknown = 1;
+ boot_delay_msec();
+
preempt_disable();
if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
/* If a crash is occurring during printk() on this CPU,
@@ -751,7 +862,16 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
return -1;
}
-#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
+int console_suspend_enabled = 1;
+EXPORT_SYMBOL(console_suspend_enabled);
+
+static int __init console_suspend_disable(char *str)
+{
+ console_suspend_enabled = 0;
+ return 1;
+}
+__setup("no_console_suspend", console_suspend_disable);
+
/**
* suspend_console - suspend the console subsystem
*
@@ -759,6 +879,8 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
*/
void suspend_console(void)
{
+ if (!console_suspend_enabled)
+ return;
printk("Suspending console(s)\n");
acquire_console_sem();
console_suspended = 1;
@@ -766,10 +888,11 @@ void suspend_console(void)
void resume_console(void)
{
+ if (!console_suspend_enabled)
+ return;
console_suspended = 0;
release_console_sem();
}
-#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */
/**
* acquire_console_sem - lock the console system for exclusive use.
diff --git a/kernel/profile.c b/kernel/profile.c
index cb1e37d2dac..631b75c25d7 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -37,7 +37,7 @@ struct profile_hit {
#define NR_PROFILE_GRP (NR_PROFILE_HIT/PROFILE_GRPSZ)
/* Oprofile timer tick hook */
-int (*timer_hook)(struct pt_regs *) __read_mostly;
+static int (*timer_hook)(struct pt_regs *) __read_mostly;
static atomic_t *prof_buffer;
static unsigned long prof_len, prof_shift;
@@ -346,7 +346,7 @@ static int __devinit profile_cpu_callback(struct notifier_block *info,
per_cpu(cpu_profile_flip, cpu) = 0;
if (!per_cpu(cpu_profile_hits, cpu)[1]) {
page = alloc_pages_node(node,
- GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+ GFP_KERNEL | __GFP_ZERO,
0);
if (!page)
return NOTIFY_BAD;
@@ -354,7 +354,7 @@ static int __devinit profile_cpu_callback(struct notifier_block *info,
}
if (!per_cpu(cpu_profile_hits, cpu)[0]) {
page = alloc_pages_node(node,
- GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
+ GFP_KERNEL | __GFP_ZERO,
0);
if (!page)
goto out_free;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 3eca7a55f2e..a73ebd3b9d4 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -386,6 +386,9 @@ int ptrace_request(struct task_struct *child, long request,
case PTRACE_SETSIGINFO:
ret = ptrace_setsiginfo(child, (siginfo_t __user *) data);
break;
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
+ break;
default:
break;
}
@@ -450,6 +453,10 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
return child;
}
+#ifndef arch_ptrace_attach
+#define arch_ptrace_attach(child) do { } while (0)
+#endif
+
#ifndef __ARCH_SYS_PTRACE
asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
{
@@ -473,6 +480,12 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
if (request == PTRACE_ATTACH) {
ret = ptrace_attach(child);
+ /*
+ * Some architectures need to do book-keeping after
+ * a ptrace attach.
+ */
+ if (!ret)
+ arch_ptrace_attach(child);
goto out_put_task_struct;
}
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 2c2dd8410dc..a66d4d1615f 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -45,10 +45,17 @@
#include <linux/moduleparam.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
-#include <linux/rcupdate.h>
#include <linux/cpu.h>
#include <linux/mutex.h>
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static struct lock_class_key rcu_lock_key;
+struct lockdep_map rcu_lock_map =
+ STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
+
+EXPORT_SYMBOL_GPL(rcu_lock_map);
+#endif
+
/* Definition for rcupdate control block. */
static struct rcu_ctrlblk rcu_ctrlblk = {
.cur = -300,
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index ddff3324778..c3e165c2318 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -35,14 +35,12 @@
#include <linux/sched.h>
#include <asm/atomic.h>
#include <linux/bitops.h>
-#include <linux/module.h>
#include <linux/completion.h>
#include <linux/moduleparam.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
#include <linux/freezer.h>
#include <linux/cpu.h>
-#include <linux/random.h>
#include <linux/delay.h>
#include <linux/byteorder/swabb.h>
#include <linux/stat.h>
@@ -166,16 +164,14 @@ struct rcu_random_state {
/*
* Crude but fast random-number generator. Uses a linear congruential
- * generator, with occasional help from get_random_bytes().
+ * generator, with occasional help from cpu_clock().
*/
static unsigned long
rcu_random(struct rcu_random_state *rrsp)
{
- long refresh;
-
if (--rrsp->rrs_count < 0) {
- get_random_bytes(&refresh, sizeof(refresh));
- rrsp->rrs_state += refresh;
+ rrsp->rrs_state +=
+ (unsigned long)cpu_clock(raw_smp_processor_id());
rrsp->rrs_count = RCU_RANDOM_REFRESH;
}
rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD;
diff --git a/kernel/relay.c b/kernel/relay.c
index ad855017bc5..61134eb7a0c 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -370,7 +370,7 @@ void relay_reset(struct rchan *chan)
if (!chan)
return;
- if (chan->is_global && chan->buf[0]) {
+ if (chan->is_global && chan->buf[0]) {
__relay_reset(chan->buf[0], 0);
return;
}
@@ -850,13 +850,13 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
buf->subbufs_consumed = consumed;
buf->bytes_consumed = 0;
}
-
+
produced = (produced % n_subbufs) * subbuf_size + buf->offset;
consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed;
if (consumed > produced)
produced += n_subbufs * subbuf_size;
-
+
if (consumed == produced)
return 0;
diff --git a/kernel/resource.c b/kernel/resource.c
index 9bd14fd3e6d..a358142ff48 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -234,7 +234,7 @@ EXPORT_SYMBOL(release_resource);
* the caller must specify res->start, res->end, res->flags.
* If found, returns 0, res is overwritten, if not found, returns -1.
*/
-int find_next_system_ram(struct resource *res)
+static int find_next_system_ram(struct resource *res)
{
resource_size_t start, end;
struct resource *p;
@@ -267,6 +267,30 @@ int find_next_system_ram(struct resource *res)
res->end = p->end;
return 0;
}
+int
+walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
+ int (*func)(unsigned long, unsigned long, void *))
+{
+ struct resource res;
+ unsigned long pfn, len;
+ u64 orig_end;
+ int ret = -1;
+ res.start = (u64) start_pfn << PAGE_SHIFT;
+ res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
+ res.flags = IORESOURCE_MEM;
+ orig_end = res.end;
+ while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
+ pfn = (unsigned long)(res.start >> PAGE_SHIFT);
+ len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT);
+ ret = (*func)(pfn, len, arg);
+ if (ret)
+ break;
+ res.start = res.end + 1;
+ res.end = orig_end;
+ }
+ return ret;
+}
+
#endif
/*
diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c
index 5aedbee014d..6b0703db152 100644
--- a/kernel/rtmutex-debug.c
+++ b/kernel/rtmutex-debug.c
@@ -82,12 +82,7 @@ do { \
* into the tracing code when doing error printk or
* executing a BUG():
*/
-int rt_trace_on = 1;
-
-void deadlock_trace_off(void)
-{
- rt_trace_on = 0;
-}
+static int rt_trace_on = 1;
static void printk_task(struct task_struct *p)
{
diff --git a/kernel/sched.c b/kernel/sched.c
index bba57adb950..ed90be46fb3 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -266,7 +266,8 @@ struct rt_rq {
* acquire operations must be ordered by ascending &runqueue.
*/
struct rq {
- spinlock_t lock; /* runqueue lock */
+ /* runqueue lock: */
+ spinlock_t lock;
/*
* nr_running and cpu_load should be in the same cacheline because
@@ -279,13 +280,15 @@ struct rq {
#ifdef CONFIG_NO_HZ
unsigned char in_nohz_recently;
#endif
- struct load_weight load; /* capture load from *all* tasks on this cpu */
+ /* capture load from *all* tasks on this cpu: */
+ struct load_weight load;
unsigned long nr_load_updates;
u64 nr_switches;
struct cfs_rq cfs;
#ifdef CONFIG_FAIR_GROUP_SCHED
- struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */
+ /* list of leaf cfs_rq on this cpu: */
+ struct list_head leaf_cfs_rq_list;
#endif
struct rt_rq rt;
@@ -317,7 +320,8 @@ struct rq {
/* For active balancing */
int active_balance;
int push_cpu;
- int cpu; /* cpu of this runqueue */
+ /* cpu of this runqueue: */
+ int cpu;
struct task_struct *migration_thread;
struct list_head migration_queue;
@@ -328,22 +332,22 @@ struct rq {
struct sched_info rq_sched_info;
/* sys_sched_yield() stats */
- unsigned long yld_exp_empty;
- unsigned long yld_act_empty;
- unsigned long yld_both_empty;
- unsigned long yld_count;
+ unsigned int yld_exp_empty;
+ unsigned int yld_act_empty;
+ unsigned int yld_both_empty;
+ unsigned int yld_count;
/* schedule() stats */
- unsigned long sched_switch;
- unsigned long sched_count;
- unsigned long sched_goidle;
+ unsigned int sched_switch;
+ unsigned int sched_count;
+ unsigned int sched_goidle;
/* try_to_wake_up() stats */
- unsigned long ttwu_count;
- unsigned long ttwu_local;
+ unsigned int ttwu_count;
+ unsigned int ttwu_local;
/* BKL stats */
- unsigned long bkl_count;
+ unsigned int bkl_count;
#endif
struct lock_class_key rq_lock_key;
};
@@ -449,12 +453,12 @@ enum {
};
const_debug unsigned int sysctl_sched_features =
- SCHED_FEAT_NEW_FAIR_SLEEPERS *1 |
- SCHED_FEAT_START_DEBIT *1 |
- SCHED_FEAT_TREE_AVG *0 |
- SCHED_FEAT_APPROX_AVG *0 |
- SCHED_FEAT_WAKEUP_PREEMPT *1 |
- SCHED_FEAT_PREEMPT_RESTRICT *1;
+ SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 |
+ SCHED_FEAT_START_DEBIT * 1 |
+ SCHED_FEAT_TREE_AVG * 0 |
+ SCHED_FEAT_APPROX_AVG * 0 |
+ SCHED_FEAT_WAKEUP_PREEMPT * 1 |
+ SCHED_FEAT_PREEMPT_RESTRICT * 1;
#define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
@@ -1712,7 +1716,7 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
p->prio = effective_prio(p);
- if (!p->sched_class->task_new || !current->se.on_rq || !rq->cfs.curr) {
+ if (!p->sched_class->task_new || !current->se.on_rq) {
activate_task(rq, p, 0);
} else {
/*
@@ -2336,7 +2340,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
unsigned long max_pull;
unsigned long busiest_load_per_task, busiest_nr_running;
unsigned long this_load_per_task, this_nr_running;
- int load_idx;
+ int load_idx, group_imb = 0;
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
int power_savings_balance = 1;
unsigned long leader_nr_running = 0, min_load_per_task = 0;
@@ -2355,9 +2359,10 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
load_idx = sd->idle_idx;
do {
- unsigned long load, group_capacity;
+ unsigned long load, group_capacity, max_cpu_load, min_cpu_load;
int local_group;
int i;
+ int __group_imb = 0;
unsigned int balance_cpu = -1, first_idle_cpu = 0;
unsigned long sum_nr_running, sum_weighted_load;
@@ -2368,6 +2373,8 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
/* Tally up the load of all CPUs in the group */
sum_weighted_load = sum_nr_running = avg_load = 0;
+ max_cpu_load = 0;
+ min_cpu_load = ~0UL;
for_each_cpu_mask(i, group->cpumask) {
struct rq *rq;
@@ -2388,8 +2395,13 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
}
load = target_load(i, load_idx);
- } else
+ } else {
load = source_load(i, load_idx);
+ if (load > max_cpu_load)
+ max_cpu_load = load;
+ if (min_cpu_load > load)
+ min_cpu_load = load;
+ }
avg_load += load;
sum_nr_running += rq->nr_running;
@@ -2415,6 +2427,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
avg_load = sg_div_cpu_power(group,
avg_load * SCHED_LOAD_SCALE);
+ if ((max_cpu_load - min_cpu_load) > SCHED_LOAD_SCALE)
+ __group_imb = 1;
+
group_capacity = group->__cpu_power / SCHED_LOAD_SCALE;
if (local_group) {
@@ -2423,11 +2438,12 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
this_nr_running = sum_nr_running;
this_load_per_task = sum_weighted_load;
} else if (avg_load > max_load &&
- sum_nr_running > group_capacity) {
+ (sum_nr_running > group_capacity || __group_imb)) {
max_load = avg_load;
busiest = group;
busiest_nr_running = sum_nr_running;
busiest_load_per_task = sum_weighted_load;
+ group_imb = __group_imb;
}
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
@@ -2499,6 +2515,9 @@ group_next:
goto out_balanced;
busiest_load_per_task /= busiest_nr_running;
+ if (group_imb)
+ busiest_load_per_task = min(busiest_load_per_task, avg_load);
+
/*
* We're trying to get all the cpus to the average_load, so we don't
* want to push ourselves above the average load, nor do we wish to
@@ -3319,6 +3338,16 @@ void account_guest_time(struct task_struct *p, cputime_t cputime)
}
/*
+ * Account scaled user cpu time to a process.
+ * @p: the process that the cpu time gets accounted to
+ * @cputime: the cpu time spent in user space since the last update
+ */
+void account_user_time_scaled(struct task_struct *p, cputime_t cputime)
+{
+ p->utimescaled = cputime_add(p->utimescaled, cputime);
+}
+
+/*
* Account system cpu time to a process.
* @p: the process that the cpu time gets accounted to
* @hardirq_offset: the offset to subtract from hardirq_count()
@@ -3356,6 +3385,17 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
}
/*
+ * Account scaled system 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 kernel space since the last update
+ */
+void account_system_time_scaled(struct task_struct *p, cputime_t cputime)
+{
+ p->stimescaled = cputime_add(p->stimescaled, cputime);
+}
+
+/*
* Account for involuntary wait time.
* @p: the process from which the cpu time has been stolen
* @steal: the cpu time spent in involuntary wait
@@ -3844,7 +3884,10 @@ EXPORT_SYMBOL(wait_for_completion_timeout);
int __sched wait_for_completion_interruptible(struct completion *x)
{
- return wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
+ long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
+ if (t == -ERESTARTSYS)
+ return t;
+ return 0;
}
EXPORT_SYMBOL(wait_for_completion_interruptible);
@@ -4779,18 +4822,18 @@ static void show_task(struct task_struct *p)
unsigned state;
state = p->state ? __ffs(p->state) + 1 : 0;
- printk("%-13.13s %c", p->comm,
+ printk(KERN_INFO "%-13.13s %c", p->comm,
state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?');
#if BITS_PER_LONG == 32
if (state == TASK_RUNNING)
- printk(" running ");
+ printk(KERN_CONT " running ");
else
- printk(" %08lx ", thread_saved_pc(p));
+ printk(KERN_CONT " %08lx ", thread_saved_pc(p));
#else
if (state == TASK_RUNNING)
- printk(" running task ");
+ printk(KERN_CONT " running task ");
else
- printk(" %016lx ", thread_saved_pc(p));
+ printk(KERN_CONT " %016lx ", thread_saved_pc(p));
#endif
#ifdef CONFIG_DEBUG_STACK_USAGE
{
@@ -4800,7 +4843,7 @@ static void show_task(struct task_struct *p)
free = (unsigned long)n - (unsigned long)end_of_stack(p);
}
#endif
- printk("%5lu %5d %6d\n", free, p->pid, p->parent->pid);
+ printk(KERN_CONT "%5lu %5d %6d\n", free, p->pid, p->parent->pid);
if (state != TASK_RUNNING)
show_stack(p, NULL);
@@ -5060,6 +5103,17 @@ wait_to_die:
}
#ifdef CONFIG_HOTPLUG_CPU
+
+static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu)
+{
+ int ret;
+
+ local_irq_disable();
+ ret = __migrate_task(p, src_cpu, dest_cpu);
+ local_irq_enable();
+ return ret;
+}
+
/*
* Figure out where task on dead CPU should go, use force if neccessary.
* NOTE: interrupts should be disabled by the caller
@@ -5098,7 +5152,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
"longer affine to cpu%d\n",
p->pid, p->comm, dead_cpu);
}
- } while (!__migrate_task(p, dead_cpu, dest_cpu));
+ } while (!__migrate_task_irq(p, dead_cpu, dest_cpu));
}
/*
@@ -5126,7 +5180,7 @@ static void migrate_live_tasks(int src_cpu)
{
struct task_struct *p, *t;
- write_lock_irq(&tasklist_lock);
+ read_lock(&tasklist_lock);
do_each_thread(t, p) {
if (p == current)
@@ -5136,7 +5190,7 @@ static void migrate_live_tasks(int src_cpu)
move_task_off_dead_cpu(src_cpu, p);
} while_each_thread(t, p);
- write_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
}
/*
@@ -5214,11 +5268,10 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
* Drop lock around migration; if someone else moves it,
* that's OK. No task can be added to this CPU, so iteration is
* fine.
- * NOTE: interrupts should be left disabled --dev@
*/
- spin_unlock(&rq->lock);
+ spin_unlock_irq(&rq->lock);
move_task_off_dead_cpu(dead_cpu, p);
- spin_lock(&rq->lock);
+ spin_lock_irq(&rq->lock);
put_task_struct(p);
}
@@ -5272,11 +5325,20 @@ static struct ctl_table *sd_alloc_ctl_entry(int n)
static void sd_free_ctl_entry(struct ctl_table **tablep)
{
- struct ctl_table *entry = *tablep;
+ struct ctl_table *entry;
- for (entry = *tablep; entry->procname; entry++)
+ /*
+ * In the intermediate directories, both the child directory and
+ * procname are dynamically allocated and could fail but the mode
+ * will always be set. In the lowest directory the names are
+ * static strings and all have proc handlers.
+ */
+ for (entry = *tablep; entry->mode; entry++) {
if (entry->child)
sd_free_ctl_entry(&entry->child);
+ if (entry->proc_handler == NULL)
+ kfree(entry->procname);
+ }
kfree(*tablep);
*tablep = NULL;
@@ -5330,7 +5392,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
return table;
}
-static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
+static ctl_table * sd_alloc_ctl_cpu_table(int cpu)
{
struct ctl_table *entry, *table;
struct sched_domain *sd;
@@ -5447,14 +5509,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
kthread_stop(rq->migration_thread);
rq->migration_thread = NULL;
/* Idle task back to normal (off runqueue, low prio) */
- rq = task_rq_lock(rq->idle, &flags);
+ spin_lock_irq(&rq->lock);
update_rq_clock(rq);
deactivate_task(rq, rq->idle, 0);
rq->idle->static_prio = MAX_PRIO;
__setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
rq->idle->sched_class = &idle_sched_class;
migrate_dead_tasks(cpu);
- task_rq_unlock(rq, &flags);
+ spin_unlock_irq(&rq->lock);
migrate_nr_uninterruptible(rq);
BUG_ON(rq->nr_running != 0);
@@ -5564,20 +5626,20 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
}
if (!group->__cpu_power) {
- printk("\n");
+ printk(KERN_CONT "\n");
printk(KERN_ERR "ERROR: domain->cpu_power not "
"set\n");
break;
}
if (!cpus_weight(group->cpumask)) {
- printk("\n");
+ printk(KERN_CONT "\n");
printk(KERN_ERR "ERROR: empty group\n");
break;
}
if (cpus_intersects(groupmask, group->cpumask)) {
- printk("\n");
+ printk(KERN_CONT "\n");
printk(KERN_ERR "ERROR: repeated CPUs\n");
break;
}
@@ -5585,11 +5647,11 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
cpus_or(groupmask, groupmask, group->cpumask);
cpumask_scnprintf(str, NR_CPUS, group->cpumask);
- printk(" %s", str);
+ printk(KERN_CONT " %s", str);
group = group->next;
} while (group != sd->groups);
- printk("\n");
+ printk(KERN_CONT "\n");
if (!cpus_equal(sd->span, groupmask))
printk(KERN_ERR "ERROR: groups don't span "
@@ -5869,7 +5931,7 @@ static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map,
struct sched_group **sg)
{
int group;
- cpumask_t mask = cpu_sibling_map[cpu];
+ cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
cpus_and(mask, mask, *cpu_map);
group = first_cpu(mask);
if (sg)
@@ -5898,7 +5960,7 @@ static int cpu_to_phys_group(int cpu, const cpumask_t *cpu_map,
cpus_and(mask, mask, *cpu_map);
group = first_cpu(mask);
#elif defined(CONFIG_SCHED_SMT)
- cpumask_t mask = cpu_sibling_map[cpu];
+ cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
cpus_and(mask, mask, *cpu_map);
group = first_cpu(mask);
#else
@@ -6132,7 +6194,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
p = sd;
sd = &per_cpu(cpu_domains, i);
*sd = SD_SIBLING_INIT;
- sd->span = cpu_sibling_map[i];
+ sd->span = per_cpu(cpu_sibling_map, i);
cpus_and(sd->span, sd->span, *cpu_map);
sd->parent = p;
p->child = sd;
@@ -6143,7 +6205,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
#ifdef CONFIG_SCHED_SMT
/* Set up CPU (sibling) groups */
for_each_cpu_mask(i, *cpu_map) {
- cpumask_t this_sibling_map = cpu_sibling_map[i];
+ cpumask_t this_sibling_map = per_cpu(cpu_sibling_map, i);
cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
if (i != first_cpu(this_sibling_map))
continue;
@@ -6348,35 +6410,6 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
arch_destroy_sched_domains(cpu_map);
}
-/*
- * Partition sched domains as specified by the cpumasks below.
- * This attaches all cpus from the cpumasks to the NULL domain,
- * waits for a RCU quiescent period, recalculates sched
- * domain information and then attaches them back to the
- * correct sched domains
- * Call with hotplug lock held
- */
-int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
-{
- cpumask_t change_map;
- int err = 0;
-
- cpus_and(*partition1, *partition1, cpu_online_map);
- cpus_and(*partition2, *partition2, cpu_online_map);
- cpus_or(change_map, *partition1, *partition2);
-
- /* Detach sched domains from all of the affected cpus */
- detach_destroy_domains(&change_map);
- if (!cpus_empty(*partition1))
- err = build_sched_domains(partition1);
- if (!err && !cpus_empty(*partition2))
- err = build_sched_domains(partition2);
-
- register_sched_domain_sysctl();
-
- return err;
-}
-
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
static int arch_reinit_sched_domains(void)
{
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index a5e517ec07c..e6fb392e516 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -137,7 +137,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
SEQ_printf(m, " .%-30s: %ld\n", "nr_running", cfs_rq->nr_running);
SEQ_printf(m, " .%-30s: %ld\n", "load", cfs_rq->load.weight);
#ifdef CONFIG_SCHEDSTATS
- SEQ_printf(m, " .%-30s: %ld\n", "bkl_count",
+ SEQ_printf(m, " .%-30s: %d\n", "bkl_count",
rq->bkl_count);
#endif
SEQ_printf(m, " .%-30s: %ld\n", "nr_spread_over",
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index a17b785d700..166ed6db600 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -1031,12 +1031,8 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
swap(curr->vruntime, se->vruntime);
}
- update_stats_enqueue(cfs_rq, se);
- check_spread(cfs_rq, se);
- check_spread(cfs_rq, curr);
- __enqueue_entity(cfs_rq, se);
- account_entity_enqueue(cfs_rq, se);
se->peer_preempt = 0;
+ enqueue_task_fair(rq, p, 0);
resched_task(rq->curr);
}
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
index 1c084842c3e..ef1a7df80ea 100644
--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -21,7 +21,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
/* runqueue-specific stats */
seq_printf(seq,
- "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu",
+ "cpu%d %u %u %u %u %u %u %u %u %u %llu %llu %lu",
cpu, rq->yld_both_empty,
rq->yld_act_empty, rq->yld_exp_empty, rq->yld_count,
rq->sched_switch, rq->sched_count, rq->sched_goidle,
@@ -42,8 +42,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
seq_printf(seq, "domain%d %s", dcount++, mask_str);
for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES;
itype++) {
- seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu "
- "%lu",
+ seq_printf(seq, " %u %u %u %u %u %u %u %u",
sd->lb_count[itype],
sd->lb_balanced[itype],
sd->lb_failed[itype],
@@ -53,8 +52,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
sd->lb_nobusyq[itype],
sd->lb_nobusyg[itype]);
}
- seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu"
- " %lu %lu %lu\n",
+ seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n",
sd->alb_count, sd->alb_failed, sd->alb_pushed,
sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed,
sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed,
diff --git a/kernel/signal.c b/kernel/signal.c
index 79295238109..e4f059cd986 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -99,7 +99,6 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
static int recalc_sigpending_tsk(struct task_struct *t)
{
if (t->signal->group_stop_count > 0 ||
- (freezing(t)) ||
PENDING(&t->pending, &t->blocked) ||
PENDING(&t->signal->shared_pending, &t->blocked)) {
set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -909,8 +908,7 @@ __group_complete_signal(int sig, struct task_struct *p)
do {
sigaddset(&t->pending.signal, SIGKILL);
signal_wake_up(t, 1);
- t = next_thread(t);
- } while (t != p);
+ } while_each_thread(p, t);
return;
}
@@ -928,13 +926,11 @@ __group_complete_signal(int sig, struct task_struct *p)
rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending);
p->signal->group_stop_count = 0;
p->signal->group_exit_task = t;
- t = p;
+ p = t;
do {
p->signal->group_stop_count++;
- signal_wake_up(t, 0);
- t = next_thread(t);
- } while (t != p);
- wake_up_process(p->signal->group_exit_task);
+ signal_wake_up(t, t == p);
+ } while_each_thread(p, t);
return;
}
@@ -985,9 +981,6 @@ void zap_other_threads(struct task_struct *p)
p->signal->flags = SIGNAL_GROUP_EXIT;
p->signal->group_stop_count = 0;
- if (thread_group_empty(p))
- return;
-
for (t = next_thread(p); t != p; t = next_thread(t)) {
/*
* Don't bother with already dead threads
@@ -2300,15 +2293,6 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
k = &current->sighand->action[sig-1];
spin_lock_irq(&current->sighand->siglock);
- if (signal_pending(current)) {
- /*
- * If there might be a fatal signal pending on multiple
- * threads, make sure we take it before changing the action.
- */
- spin_unlock_irq(&current->sighand->siglock);
- return -ERESTARTNOINTR;
- }
-
if (oact)
*oact = *k;
@@ -2335,7 +2319,6 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
rm_from_queue_full(&mask, &t->signal->shared_pending);
do {
rm_from_queue_full(&mask, &t->pending);
- recalc_sigpending_and_wake(t);
t = next_thread(t);
} while (t != current);
}
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 708d4882c0c..edeeef3a6a3 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -15,13 +15,16 @@
#include <linux/notifier.h>
#include <linux/module.h>
+#include <asm/irq_regs.h>
+
static DEFINE_SPINLOCK(print_lock);
static DEFINE_PER_CPU(unsigned long, touch_timestamp);
static DEFINE_PER_CPU(unsigned long, print_timestamp);
static DEFINE_PER_CPU(struct task_struct *, watchdog_task);
-static int did_panic = 0;
+static int did_panic;
+int softlockup_thresh = 10;
static int
softlock_panic(struct notifier_block *this, unsigned long event, void *ptr)
@@ -40,14 +43,16 @@ static struct notifier_block panic_block = {
* resolution, and we don't need to waste time with a big divide when
* 2^30ns == 1.074s.
*/
-static unsigned long get_timestamp(void)
+static unsigned long get_timestamp(int this_cpu)
{
- return sched_clock() >> 30; /* 2^30 ~= 10^9 */
+ return cpu_clock(this_cpu) >> 30; /* 2^30 ~= 10^9 */
}
void touch_softlockup_watchdog(void)
{
- __raw_get_cpu_var(touch_timestamp) = get_timestamp();
+ int this_cpu = raw_smp_processor_id();
+
+ __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu);
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
@@ -70,6 +75,7 @@ void softlockup_tick(void)
int this_cpu = smp_processor_id();
unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
unsigned long print_timestamp;
+ struct pt_regs *regs = get_irq_regs();
unsigned long now;
if (touch_timestamp == 0) {
@@ -80,10 +86,11 @@ void softlockup_tick(void)
print_timestamp = per_cpu(print_timestamp, this_cpu);
/* report at most once a second */
- if (print_timestamp < (touch_timestamp + 1) ||
- did_panic ||
- !per_cpu(watchdog_task, this_cpu))
+ if ((print_timestamp >= touch_timestamp &&
+ print_timestamp < (touch_timestamp + 1)) ||
+ did_panic || !per_cpu(watchdog_task, this_cpu)) {
return;
+ }
/* do not print during early bootup: */
if (unlikely(system_state != SYSTEM_RUNNING)) {
@@ -91,28 +98,33 @@ void softlockup_tick(void)
return;
}
- now = get_timestamp();
+ now = get_timestamp(this_cpu);
/* Wake up the high-prio watchdog task every second: */
if (now > (touch_timestamp + 1))
wake_up_process(per_cpu(watchdog_task, this_cpu));
/* Warn about unreasonable 10+ seconds delays: */
- if (now > (touch_timestamp + 10)) {
- per_cpu(print_timestamp, this_cpu) = touch_timestamp;
+ if (now <= (touch_timestamp + softlockup_thresh))
+ return;
- spin_lock(&print_lock);
- printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n",
- this_cpu);
+ per_cpu(print_timestamp, this_cpu) = touch_timestamp;
+
+ 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);
+ if (regs)
+ show_regs(regs);
+ else
dump_stack();
- spin_unlock(&print_lock);
- }
+ spin_unlock(&print_lock);
}
/*
* The watchdog thread - runs every second and touches the timestamp.
*/
-static int watchdog(void * __bind_cpu)
+static int watchdog(void *__bind_cpu)
{
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
@@ -150,13 +162,13 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
BUG_ON(per_cpu(watchdog_task, hotcpu));
p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu);
if (IS_ERR(p)) {
- printk("watchdog for %i failed\n", hotcpu);
+ printk(KERN_ERR "watchdog for %i failed\n", hotcpu);
return NOTIFY_BAD;
}
- per_cpu(touch_timestamp, hotcpu) = 0;
- per_cpu(watchdog_task, hotcpu) = p;
+ per_cpu(touch_timestamp, hotcpu) = 0;
+ per_cpu(watchdog_task, hotcpu) = p;
kthread_bind(p, hotcpu);
- break;
+ break;
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
wake_up_process(per_cpu(watchdog_task, hotcpu));
@@ -176,7 +188,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
kthread_stop(p);
break;
#endif /* CONFIG_HOTPLUG_CPU */
- }
+ }
return NOTIFY_OK;
}
diff --git a/kernel/sys.c b/kernel/sys.c
index 8ae2e636eb1..bc8879c822a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -105,7 +105,6 @@ EXPORT_SYMBOL(cad_pid);
*/
void (*pm_power_off_prepare)(void);
-EXPORT_SYMBOL(pm_power_off_prepare);
/*
* Notifier list for kernel code which wants to be called
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index b0ec498a18d..52c7a151e29 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -4,6 +4,10 @@
#include <asm/unistd.h>
+/* we can't #include <linux/syscalls.h> here,
+ but tell gcc to not warn with -Wmissing-prototypes */
+asmlinkage long sys_ni_syscall(void);
+
/*
* Non-implemented system calls get redirected here.
*/
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ec14aa8ac51..067554bda8b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
-#include <linux/capability.h>
+#include <linux/security.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
#include <linux/smp_lock.h>
@@ -55,6 +55,8 @@
#include <asm/stacktrace.h>
#endif
+static int deprecated_sysctl_warning(struct __sysctl_args *args);
+
#if defined(CONFIG_SYSCTL)
/* External variables not in a header file. */
@@ -63,6 +65,7 @@ extern int print_fatal_signals;
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
extern int sysctl_panic_on_oom;
+extern int sysctl_oom_kill_allocating_task;
extern int max_threads;
extern int core_uses_pid;
extern int suid_dumpable;
@@ -79,6 +82,19 @@ extern int maps_protect;
extern int sysctl_stat_interval;
extern int audit_argv_kb;
+/* Constants used for minimum and maximum */
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+static int one = 1;
+static int sixty = 60;
+#endif
+
+#ifdef CONFIG_MMU
+static int two = 2;
+#endif
+
+static int zero;
+static int one_hundred = 100;
+
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
static int minolduid;
@@ -128,32 +144,29 @@ extern int max_lock_depth;
#ifdef CONFIG_SYSCTL_SYSCALL
static int parse_table(int __user *, int, void __user *, size_t __user *,
- void __user *, size_t, ctl_table *);
+ void __user *, size_t, struct ctl_table *);
#endif
#ifdef CONFIG_PROC_SYSCTL
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
-static ctl_table root_table[];
+static struct ctl_table root_table[];
static struct ctl_table_header root_table_header =
{ root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
-static ctl_table kern_table[];
-static ctl_table vm_table[];
-static ctl_table fs_table[];
-static ctl_table debug_table[];
-static ctl_table dev_table[];
-extern ctl_table random_table[];
-#ifdef CONFIG_UNIX98_PTYS
-extern ctl_table pty_table[];
-#endif
+static struct ctl_table kern_table[];
+static struct ctl_table vm_table[];
+static struct ctl_table fs_table[];
+static struct ctl_table debug_table[];
+static struct ctl_table dev_table[];
+extern struct ctl_table random_table[];
#ifdef CONFIG_INOTIFY_USER
-extern ctl_table inotify_table[];
+extern struct ctl_table inotify_table[];
#endif
#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
@@ -165,7 +178,7 @@ extern int lock_stat;
/* The default sysctl tables: */
-static ctl_table root_table[] = {
+static struct ctl_table root_table[] = {
{
.ctl_name = CTL_KERN,
.procname = "kernel",
@@ -218,7 +231,7 @@ static unsigned long min_wakeup_granularity_ns; /* 0 usecs */
static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */
#endif
-static ctl_table kern_table[] = {
+static struct ctl_table kern_table[] = {
#ifdef CONFIG_SCHED_DEBUG
{
.ctl_name = CTL_UNNUMBERED,
@@ -351,7 +364,6 @@ static ctl_table kern_table[] = {
},
#ifdef CONFIG_PROC_SYSCTL
{
- .ctl_name = KERN_TAINTED,
.procname = "tainted",
.data = &tainted,
.maxlen = sizeof(int),
@@ -359,14 +371,15 @@ static ctl_table kern_table[] = {
.proc_handler = &proc_dointvec_taint,
},
#endif
+#ifdef CONFIG_SECURITY_CAPABILITIES
{
- .ctl_name = KERN_CAP_BSET,
.procname = "cap-bound",
.data = &cap_bset,
.maxlen = sizeof(kernel_cap_t),
.mode = 0600,
.proc_handler = &proc_dointvec_bset,
},
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
#ifdef CONFIG_BLK_DEV_INITRD
{
.ctl_name = KERN_REALROOTDEV,
@@ -500,7 +513,6 @@ static ctl_table kern_table[] = {
#endif
#ifdef CONFIG_PROC_SYSCTL
{
- .ctl_name = KERN_CADPID,
.procname = "cad_pid",
.data = NULL,
.maxlen = sizeof (int),
@@ -522,14 +534,6 @@ static ctl_table kern_table[] = {
.mode = 0555,
.child = random_table,
},
-#ifdef CONFIG_UNIX98_PTYS
- {
- .ctl_name = KERN_PTY,
- .procname = "pty",
- .mode = 0555,
- .child = pty_table,
- },
-#endif
{
.ctl_name = KERN_OVERFLOWUID,
.procname = "overflowuid",
@@ -636,7 +640,6 @@ static ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = KERN_NMI_WATCHDOG,
.procname = "nmi_watchdog",
.data = &nmi_watchdog_enabled,
.maxlen = sizeof (int),
@@ -692,7 +695,6 @@ static ctl_table kern_table[] = {
#endif
#if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
{
- .ctl_name = KERN_ACPI_VIDEO_FLAGS,
.procname = "acpi_video_flags",
.data = &acpi_realmode_flags,
.maxlen = sizeof (unsigned long),
@@ -710,6 +712,19 @@ static ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
+#ifdef CONFIG_DETECT_SOFTLOCKUP
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "softlockup_thresh",
+ .data = &softlockup_thresh,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &one,
+ .extra2 = &sixty,
+ },
+#endif
#ifdef CONFIG_COMPAT
{
.ctl_name = KERN_COMPAT_LOG,
@@ -756,14 +771,7 @@ static ctl_table kern_table[] = {
{ .ctl_name = 0 }
};
-/* Constants for minimum and maximum testing in vm_table.
- We use these as one-element integer vectors. */
-static int zero;
-static int two = 2;
-static int one_hundred = 100;
-
-
-static ctl_table vm_table[] = {
+static struct ctl_table vm_table[] = {
{
.ctl_name = VM_OVERCOMMIT_MEMORY,
.procname = "overcommit_memory",
@@ -781,6 +789,14 @@ static ctl_table vm_table[] = {
.proc_handler = &proc_dointvec,
},
{
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "oom_kill_allocating_task",
+ .data = &sysctl_oom_kill_allocating_task,
+ .maxlen = sizeof(sysctl_oom_kill_allocating_task),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
.ctl_name = VM_OVERCOMMIT_RATIO,
.procname = "overcommit_ratio",
.data = &sysctl_overcommit_ratio,
@@ -813,13 +829,12 @@ static ctl_table vm_table[] = {
.data = &vm_dirty_ratio,
.maxlen = sizeof(vm_dirty_ratio),
.mode = 0644,
- .proc_handler = &proc_dointvec_minmax,
+ .proc_handler = &dirty_ratio_handler,
.strategy = &sysctl_intvec,
.extra1 = &zero,
.extra2 = &one_hundred,
},
{
- .ctl_name = VM_DIRTY_WB_CS,
.procname = "dirty_writeback_centisecs",
.data = &dirty_writeback_interval,
.maxlen = sizeof(dirty_writeback_interval),
@@ -827,7 +842,6 @@ static ctl_table vm_table[] = {
.proc_handler = &dirty_writeback_centisecs_handler,
},
{
- .ctl_name = VM_DIRTY_EXPIRE_CS,
.procname = "dirty_expire_centisecs",
.data = &dirty_expire_interval,
.maxlen = sizeof(dirty_expire_interval),
@@ -855,7 +869,6 @@ static ctl_table vm_table[] = {
},
#ifdef CONFIG_HUGETLB_PAGE
{
- .ctl_name = VM_HUGETLB_PAGES,
.procname = "nr_hugepages",
.data = &max_huge_pages,
.maxlen = sizeof(unsigned long),
@@ -880,6 +893,14 @@ static ctl_table vm_table[] = {
.mode = 0644,
.proc_handler = &hugetlb_treat_movable_handler,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "hugetlb_dynamic_pool",
+ .data = &hugetlb_dynamic_pool,
+ .maxlen = sizeof(hugetlb_dynamic_pool),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
#endif
{
.ctl_name = VM_LOWMEM_RESERVE_RATIO,
@@ -1057,12 +1078,12 @@ static ctl_table vm_table[] = {
};
#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
-static ctl_table binfmt_misc_table[] = {
+static struct ctl_table binfmt_misc_table[] = {
{ .ctl_name = 0 }
};
#endif
-static ctl_table fs_table[] = {
+static struct ctl_table fs_table[] = {
{
.ctl_name = FS_NRINODE,
.procname = "inode-nr",
@@ -1080,7 +1101,6 @@ static ctl_table fs_table[] = {
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = FS_NRFILE,
.procname = "file-nr",
.data = &files_stat,
.maxlen = 3*sizeof(int),
@@ -1156,7 +1176,6 @@ static ctl_table fs_table[] = {
.extra2 = &two,
},
{
- .ctl_name = FS_AIO_NR,
.procname = "aio-nr",
.data = &aio_nr,
.maxlen = sizeof(aio_nr),
@@ -1164,7 +1183,6 @@ static ctl_table fs_table[] = {
.proc_handler = &proc_doulongvec_minmax,
},
{
- .ctl_name = FS_AIO_MAX_NR,
.procname = "aio-max-nr",
.data = &aio_max_nr,
.maxlen = sizeof(aio_max_nr),
@@ -1203,7 +1221,7 @@ static ctl_table fs_table[] = {
{ .ctl_name = 0 }
};
-static ctl_table debug_table[] = {
+static struct ctl_table debug_table[] = {
#if defined(CONFIG_X86) || defined(CONFIG_PPC)
{
.ctl_name = CTL_UNNUMBERED,
@@ -1217,7 +1235,7 @@ static ctl_table debug_table[] = {
{ .ctl_name = 0 }
};
-static ctl_table dev_table[] = {
+static struct ctl_table dev_table[] = {
{ .ctl_name = 0 }
};
@@ -1333,10 +1351,15 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
+ error = deprecated_sysctl_warning(&tmp);
+ if (error)
+ goto out;
+
lock_kernel();
error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
tmp.newval, tmp.newlen);
unlock_kernel();
+out:
return error;
}
#endif /* CONFIG_SYSCTL_SYSCALL */
@@ -1357,7 +1380,7 @@ static int test_perm(int mode, int op)
return -EACCES;
}
-int sysctl_perm(ctl_table *table, int op)
+int sysctl_perm(struct ctl_table *table, int op)
{
int error;
error = security_sysctl(table, op);
@@ -1370,7 +1393,7 @@ int sysctl_perm(ctl_table *table, int op)
static int parse_table(int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen,
- ctl_table *table)
+ struct ctl_table *table)
{
int n;
repeat:
@@ -1401,13 +1424,12 @@ repeat:
}
/* Perform the actual read/write of a sysctl table entry. */
-int do_sysctl_strategy (ctl_table *table,
+int do_sysctl_strategy (struct ctl_table *table,
int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
int op = 0, rc;
- size_t len;
if (oldval)
op |= 004;
@@ -1428,25 +1450,10 @@ int do_sysctl_strategy (ctl_table *table,
/* If there is no strategy routine, or if the strategy returns
* zero, proceed with automatic r/w */
if (table->data && table->maxlen) {
- if (oldval && oldlenp) {
- if (get_user(len, oldlenp))
- return -EFAULT;
- if (len) {
- if (len > table->maxlen)
- len = table->maxlen;
- if(copy_to_user(oldval, table->data, len))
- return -EFAULT;
- if(put_user(len, oldlenp))
- return -EFAULT;
- }
- }
- if (newval && newlen) {
- len = newlen;
- if (len > table->maxlen)
- len = table->maxlen;
- if(copy_from_user(table->data, newval, len))
- return -EFAULT;
- }
+ rc = sysctl_data(table, name, nlen, oldval, oldlenp,
+ newval, newlen);
+ if (rc < 0)
+ return rc;
}
return 0;
}
@@ -1463,7 +1470,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
static __init int sysctl_init(void)
{
+ int err;
sysctl_set_parent(NULL, root_table);
+ err = sysctl_check_table(root_table);
return 0;
}
@@ -1476,7 +1485,7 @@ core_initcall(sysctl_init);
* Register a sysctl table hierarchy. @table should be a filled in ctl_table
* array. An entry with a ctl_name of 0 terminates the table.
*
- * The members of the &ctl_table structure are used as follows:
+ * The members of the &struct ctl_table structure are used as follows:
*
* ctl_name - This is the numeric sysctl value used by sysctl(2). The number
* must be unique within that level of sysctl
@@ -1537,7 +1546,7 @@ core_initcall(sysctl_init);
* This routine returns %NULL on a failure to register, and a pointer
* to the table header on success.
*/
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
{
struct ctl_table_header *tmp;
tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
@@ -1548,6 +1557,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table)
tmp->used = 0;
tmp->unregistering = NULL;
sysctl_set_parent(NULL, table);
+ if (sysctl_check_table(tmp->ctl_table)) {
+ kfree(tmp);
+ return NULL;
+ }
spin_lock(&sysctl_lock);
list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
spin_unlock(&sysctl_lock);
@@ -1571,7 +1584,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
}
#else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(ctl_table * table)
+struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
{
return NULL;
}
@@ -1664,7 +1677,7 @@ static int _proc_do_string(void* data, int maxlen, int write,
*
* Returns 0 on success.
*/
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return _proc_do_string(table->data, table->maxlen, write, filp,
@@ -1691,7 +1704,7 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
return 0;
}
-static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
+static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
int write, struct file *filp, void __user *buffer,
size_t *lenp, loff_t *ppos,
int (*conv)(int *negp, unsigned long *lvalp, int *valp,
@@ -1801,7 +1814,7 @@ static int __do_proc_dointvec(void *tbl_data, ctl_table *table,
#undef TMPBUFLEN
}
-static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
+static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos,
int (*conv)(int *negp, unsigned long *lvalp, int *valp,
int write, void *data),
@@ -1825,7 +1838,7 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp,
*
* Returns 0 on success.
*/
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -1861,11 +1874,12 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
return 0;
}
+#ifdef CONFIG_SECURITY_CAPABILITIES
/*
* init may raise the set.
*/
-
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int op;
@@ -1878,11 +1892,12 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
do_proc_dointvec_bset_conv,&op);
}
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
/*
* Taint values can only be increased
*/
-static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp,
+static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int op;
@@ -1941,7 +1956,7 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
*
* Returns 0 on success.
*/
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
struct do_proc_dointvec_minmax_conv_param param = {
@@ -1952,7 +1967,7 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
do_proc_dointvec_minmax_conv, &param);
}
-static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
+static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
struct file *filp,
void __user *buffer,
size_t *lenp, loff_t *ppos,
@@ -2057,7 +2072,7 @@ static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write,
#undef TMPBUFLEN
}
-static int do_proc_doulongvec_minmax(ctl_table *table, int write,
+static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
struct file *filp,
void __user *buffer,
size_t *lenp, loff_t *ppos,
@@ -2085,7 +2100,7 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write,
*
* Returns 0 on success.
*/
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
@@ -2109,7 +2124,7 @@ int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
*
* Returns 0 on success.
*/
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
struct file *filp,
void __user *buffer,
size_t *lenp, loff_t *ppos)
@@ -2202,7 +2217,7 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
*
* Returns 0 on success.
*/
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2225,7 +2240,7 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
*
* Returns 0 on success.
*/
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
@@ -2249,14 +2264,14 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
*
* Returns 0 on success.
*/
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
do_proc_dointvec_ms_jiffies_conv, NULL);
}
-static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
+static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
struct pid *new_pid;
@@ -2280,55 +2295,55 @@ static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp,
#else /* CONFIG_PROC_FS */
-int proc_dostring(ctl_table *table, int write, struct file *filp,
+int proc_dostring(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_dointvec(ctl_table *table, int write, struct file *filp,
+int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp,
+int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp,
+int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
return -ENOSYS;
}
-int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
+int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
struct file *filp,
void __user *buffer,
size_t *lenp, loff_t *ppos)
@@ -2345,8 +2360,42 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write,
* General sysctl support routines
*/
+/* The generic sysctl data routine (used if no strategy routine supplied) */
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen)
+{
+ size_t len;
+
+ /* Get out of I don't have a variable */
+ if (!table->data || !table->maxlen)
+ return -ENOTDIR;
+
+ if (oldval && oldlenp) {
+ if (get_user(len, oldlenp))
+ return -EFAULT;
+ if (len) {
+ if (len > table->maxlen)
+ len = table->maxlen;
+ if (copy_to_user(oldval, table->data, len))
+ return -EFAULT;
+ if (put_user(len, oldlenp))
+ return -EFAULT;
+ }
+ }
+
+ if (newval && newlen) {
+ if (newlen > table->maxlen)
+ newlen = table->maxlen;
+
+ if (copy_from_user(table->data, newval, newlen))
+ return -EFAULT;
+ }
+ return 1;
+}
+
/* The generic string strategy routine: */
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2392,7 +2441,7 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen,
* are between the minimum and maximum values given in the arrays
* table->extra1 and table->extra2, respectively.
*/
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2428,7 +2477,7 @@ int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
}
/* Strategy function to convert jiffies to seconds */
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2462,7 +2511,7 @@ int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
}
/* Strategy function to convert jiffies to seconds */
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2502,59 +2551,50 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
{
- static int msg_count;
struct __sysctl_args tmp;
- int name[CTL_MAXNAME];
- int i;
+ int error;
- /* Read in the sysctl name for better debug message logging */
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
- if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME)
- return -ENOTDIR;
- for (i = 0; i < tmp.nlen; i++)
- if (get_user(name[i], tmp.name + i))
- return -EFAULT;
- /* Ignore accesses to kernel.version */
- if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
- goto out;
+ error = deprecated_sysctl_warning(&tmp);
- if (msg_count < 5) {
- msg_count++;
- printk(KERN_INFO
- "warning: process `%s' used the removed sysctl "
- "system call with ", current->comm);
- for (i = 0; i < tmp.nlen; i++)
- printk("%d.", name[i]);
- printk("\n");
- }
-out:
+ /* If no error reading the parameters then just -ENOSYS ... */
+ if (!error)
+ error = -ENOSYS;
+
+ return error;
+}
+
+int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen)
+{
return -ENOSYS;
}
-int sysctl_string(ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_intvec(ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2563,6 +2603,33 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen,
#endif /* CONFIG_SYSCTL_SYSCALL */
+static int deprecated_sysctl_warning(struct __sysctl_args *args)
+{
+ static int msg_count;
+ int name[CTL_MAXNAME];
+ int i;
+
+ /* Read in the sysctl name for better debug message logging */
+ for (i = 0; i < args->nlen; i++)
+ if (get_user(name[i], args->name + i))
+ return -EFAULT;
+
+ /* Ignore accesses to kernel.version */
+ if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
+ return 0;
+
+ if (msg_count < 5) {
+ msg_count++;
+ printk(KERN_INFO
+ "warning: process `%s' used the deprecated sysctl "
+ "system call with ", current->comm);
+ for (i = 0; i < args->nlen; i++)
+ printk("%d.", name[i]);
+ printk("\n");
+ }
+ return 0;
+}
+
/*
* No sense putting this after each symbol definition, twice,
* exception granted :-)
@@ -2580,4 +2647,5 @@ EXPORT_SYMBOL(sysctl_intvec);
EXPORT_SYMBOL(sysctl_jiffies);
EXPORT_SYMBOL(sysctl_ms_jiffies);
EXPORT_SYMBOL(sysctl_string);
+EXPORT_SYMBOL(sysctl_data);
EXPORT_SYMBOL(unregister_sysctl_table);
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
new file mode 100644
index 00000000000..3c9ef5a7d57
--- /dev/null
+++ b/kernel/sysctl_check.c
@@ -0,0 +1,1588 @@
+#include <linux/stat.h>
+#include <linux/sysctl.h>
+#include "../arch/s390/appldata/appldata.h"
+#include "../fs/xfs/linux-2.6/xfs_sysctl.h"
+#include <linux/sunrpc/debug.h>
+#include <linux/string.h>
+#include <net/ip_vs.h>
+
+struct trans_ctl_table {
+ int ctl_name;
+ const char *procname;
+ struct trans_ctl_table *child;
+};
+
+static struct trans_ctl_table trans_random_table[] = {
+ { RANDOM_POOLSIZE, "poolsize" },
+ { RANDOM_ENTROPY_COUNT, "entropy_avail" },
+ { RANDOM_READ_THRESH, "read_wakeup_threshold" },
+ { RANDOM_WRITE_THRESH, "write_wakeup_threshold" },
+ { RANDOM_BOOT_ID, "boot_id" },
+ { RANDOM_UUID, "uuid" },
+ {}
+};
+
+static struct trans_ctl_table trans_pty_table[] = {
+ { PTY_MAX, "max" },
+ { PTY_NR, "nr" },
+ {}
+};
+
+static struct trans_ctl_table trans_kern_table[] = {
+ { KERN_OSTYPE, "ostype" },
+ { KERN_OSRELEASE, "osrelease" },
+ /* KERN_OSREV not used */
+ { KERN_VERSION, "version" },
+ /* KERN_SECUREMASK not used */
+ /* KERN_PROF not used */
+ { KERN_NODENAME, "hostname" },
+ { KERN_DOMAINNAME, "domainname" },
+
+#ifdef CONFIG_SECURITY_CAPABILITIES
+ { KERN_CAP_BSET, "cap-bound" },
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
+
+ { KERN_PANIC, "panic" },
+ { KERN_REALROOTDEV, "real-root-dev" },
+
+ { KERN_SPARC_REBOOT, "reboot-cmd" },
+ { KERN_CTLALTDEL, "ctrl-alt-del" },
+ { KERN_PRINTK, "printk" },
+
+ /* KERN_NAMETRANS not used */
+ /* KERN_PPC_HTABRECLAIM not used */
+ /* KERN_PPC_ZEROPAGED not used */
+ { KERN_PPC_POWERSAVE_NAP, "powersave-nap" },
+
+ { KERN_MODPROBE, "modprobe" },
+ { KERN_SG_BIG_BUFF, "sg-big-buff" },
+ { KERN_ACCT, "acct" },
+ { KERN_PPC_L2CR, "l2cr" },
+
+ /* KERN_RTSIGNR not used */
+ /* KERN_RTSIGMAX not used */
+
+ { KERN_SHMMAX, "shmmax" },
+ { KERN_MSGMAX, "msgmax" },
+ { KERN_MSGMNB, "msgmnb" },
+ /* KERN_MSGPOOL not used*/
+ { KERN_SYSRQ, "sysrq" },
+ { KERN_MAX_THREADS, "threads-max" },
+ { KERN_RANDOM, "random", trans_random_table },
+ { KERN_SHMALL, "shmall" },
+ { KERN_MSGMNI, "msgmni" },
+ { KERN_SEM, "sem" },
+ { KERN_SPARC_STOP_A, "stop-a" },
+ { KERN_SHMMNI, "shmmni" },
+
+ { KERN_OVERFLOWUID, "overflowuid" },
+ { KERN_OVERFLOWGID, "overflowgid" },
+
+ { KERN_HOTPLUG, "hotplug", },
+ { KERN_IEEE_EMULATION_WARNINGS, "ieee_emulation_warnings" },
+
+ { KERN_S390_USER_DEBUG_LOGGING, "userprocess_debug" },
+ { KERN_CORE_USES_PID, "core_uses_pid" },
+ { KERN_TAINTED, "tainted" },
+ { KERN_CADPID, "cad_pid" },
+ { KERN_PIDMAX, "pid_max" },
+ { KERN_CORE_PATTERN, "core_pattern" },
+ { KERN_PANIC_ON_OOPS, "panic_on_oops" },
+ { KERN_HPPA_PWRSW, "soft-power" },
+ { KERN_HPPA_UNALIGNED, "unaligned-trap" },
+
+ { KERN_PRINTK_RATELIMIT, "printk_ratelimit" },
+ { KERN_PRINTK_RATELIMIT_BURST, "printk_ratelimit_burst" },
+
+ { KERN_PTY, "pty", trans_pty_table },
+ { KERN_NGROUPS_MAX, "ngroups_max" },
+ { KERN_SPARC_SCONS_PWROFF, "scons_poweroff" },
+ { KERN_HZ_TIMER, "hz_timer" },
+ { KERN_UNKNOWN_NMI_PANIC, "unknown_nmi_panic" },
+ { KERN_BOOTLOADER_TYPE, "bootloader_type" },
+ { KERN_RANDOMIZE, "randomize_va_space" },
+
+ { KERN_SPIN_RETRY, "spin_retry" },
+ { KERN_ACPI_VIDEO_FLAGS, "acpi_video_flags" },
+ { KERN_IA64_UNALIGNED, "ignore-unaligned-usertrap" },
+ { KERN_COMPAT_LOG, "compat-log" },
+ { KERN_MAX_LOCK_DEPTH, "max_lock_depth" },
+ { KERN_NMI_WATCHDOG, "nmi_watchdog" },
+ { KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" },
+ {}
+};
+
+static struct trans_ctl_table trans_vm_table[] = {
+ { VM_OVERCOMMIT_MEMORY, "overcommit_memory" },
+ { VM_PAGE_CLUSTER, "page-cluster" },
+ { VM_DIRTY_BACKGROUND, "dirty_background_ratio" },
+ { VM_DIRTY_RATIO, "dirty_ratio" },
+ { VM_DIRTY_WB_CS, "dirty_writeback_centisecs" },
+ { VM_DIRTY_EXPIRE_CS, "dirty_expire_centisecs" },
+ { VM_NR_PDFLUSH_THREADS, "nr_pdflush_threads" },
+ { VM_OVERCOMMIT_RATIO, "overcommit_ratio" },
+ /* VM_PAGEBUF unused */
+ { VM_HUGETLB_PAGES, "nr_hugepages" },
+ { VM_SWAPPINESS, "swappiness" },
+ { VM_LOWMEM_RESERVE_RATIO, "lowmem_reserve_ratio" },
+ { VM_MIN_FREE_KBYTES, "min_free_kbytes" },
+ { VM_MAX_MAP_COUNT, "max_map_count" },
+ { VM_LAPTOP_MODE, "laptop_mode" },
+ { VM_BLOCK_DUMP, "block_dump" },
+ { VM_HUGETLB_GROUP, "hugetlb_shm_group" },
+ { VM_VFS_CACHE_PRESSURE, "vfs_cache_pressure" },
+ { VM_LEGACY_VA_LAYOUT, "legacy_va_layout" },
+ /* VM_SWAP_TOKEN_TIMEOUT unused */
+ { VM_DROP_PAGECACHE, "drop_caches" },
+ { VM_PERCPU_PAGELIST_FRACTION, "percpu_pagelist_fraction" },
+ { VM_ZONE_RECLAIM_MODE, "zone_reclaim_mode" },
+ { VM_MIN_UNMAPPED, "min_unmapped_ratio" },
+ { VM_PANIC_ON_OOM, "panic_on_oom" },
+ { VM_VDSO_ENABLED, "vdso_enabled" },
+ { VM_MIN_SLAB, "min_slab_ratio" },
+ { VM_CMM_PAGES, "cmm_pages" },
+ { VM_CMM_TIMED_PAGES, "cmm_timed_pages" },
+ { VM_CMM_TIMEOUT, "cmm_timeout" },
+
+ {}
+};
+
+static struct trans_ctl_table trans_net_core_table[] = {
+ { NET_CORE_WMEM_MAX, "wmem_max" },
+ { NET_CORE_RMEM_MAX, "rmem_max" },
+ { NET_CORE_WMEM_DEFAULT, "wmem_default" },
+ { NET_CORE_RMEM_DEFAULT, "rmem_default" },
+ /* NET_CORE_DESTROY_DELAY unused */
+ { NET_CORE_MAX_BACKLOG, "netdev_max_backlog" },
+ /* NET_CORE_FASTROUTE unused */
+ { NET_CORE_MSG_COST, "message_cost" },
+ { NET_CORE_MSG_BURST, "message_burst" },
+ { NET_CORE_OPTMEM_MAX, "optmem_max" },
+ /* NET_CORE_HOT_LIST_LENGTH unused */
+ /* NET_CORE_DIVERT_VERSION unused */
+ /* NET_CORE_NO_CONG_THRESH unused */
+ /* NET_CORE_NO_CONG unused */
+ /* NET_CORE_LO_CONG unused */
+ /* NET_CORE_MOD_CONG unused */
+ { NET_CORE_DEV_WEIGHT, "dev_weight" },
+ { NET_CORE_SOMAXCONN, "somaxconn" },
+ { NET_CORE_BUDGET, "netdev_budget" },
+ { NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" },
+ { NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" },
+ { NET_CORE_WARNINGS, "warnings" },
+ {},
+};
+
+static struct trans_ctl_table trans_net_unix_table[] = {
+ /* NET_UNIX_DESTROY_DELAY unused */
+ /* NET_UNIX_DELETE_DELAY unused */
+ { NET_UNIX_MAX_DGRAM_QLEN, "max_dgram_qlen" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_route_table[] = {
+ { NET_IPV4_ROUTE_FLUSH, "flush" },
+ { NET_IPV4_ROUTE_MIN_DELAY, "min_delay" },
+ { NET_IPV4_ROUTE_MAX_DELAY, "max_delay" },
+ { NET_IPV4_ROUTE_GC_THRESH, "gc_thresh" },
+ { NET_IPV4_ROUTE_MAX_SIZE, "max_size" },
+ { NET_IPV4_ROUTE_GC_MIN_INTERVAL, "gc_min_interval" },
+ { NET_IPV4_ROUTE_GC_TIMEOUT, "gc_timeout" },
+ { NET_IPV4_ROUTE_GC_INTERVAL, "gc_interval" },
+ { NET_IPV4_ROUTE_REDIRECT_LOAD, "redirect_load" },
+ { NET_IPV4_ROUTE_REDIRECT_NUMBER, "redirect_number" },
+ { NET_IPV4_ROUTE_REDIRECT_SILENCE, "redirect_silence" },
+ { NET_IPV4_ROUTE_ERROR_COST, "error_cost" },
+ { NET_IPV4_ROUTE_ERROR_BURST, "error_burst" },
+ { NET_IPV4_ROUTE_GC_ELASTICITY, "gc_elasticity" },
+ { NET_IPV4_ROUTE_MTU_EXPIRES, "mtu_expires" },
+ { NET_IPV4_ROUTE_MIN_PMTU, "min_pmtu" },
+ { NET_IPV4_ROUTE_MIN_ADVMSS, "min_adv_mss" },
+ { NET_IPV4_ROUTE_SECRET_INTERVAL, "secret_interval" },
+ { NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS, "gc_min_interval_ms" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = {
+ { NET_IPV4_CONF_FORWARDING, "forwarding" },
+ { NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding" },
+
+ { NET_IPV4_CONF_PROXY_ARP, "proxy_arp" },
+ { NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects" },
+ { NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects" },
+ { NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects" },
+ { NET_IPV4_CONF_SHARED_MEDIA, "shared_media" },
+ { NET_IPV4_CONF_RP_FILTER, "rp_filter" },
+ { NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route" },
+ { NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay" },
+ { NET_IPV4_CONF_LOG_MARTIANS, "log_martians" },
+ { NET_IPV4_CONF_TAG, "tag" },
+ { NET_IPV4_CONF_ARPFILTER, "arp_filter" },
+ { NET_IPV4_CONF_MEDIUM_ID, "medium_id" },
+ { NET_IPV4_CONF_NOXFRM, "disable_xfrm" },
+ { NET_IPV4_CONF_NOPOLICY, "disable_policy" },
+ { NET_IPV4_CONF_FORCE_IGMP_VERSION, "force_igmp_version" },
+
+ { NET_IPV4_CONF_ARP_ANNOUNCE, "arp_announce" },
+ { NET_IPV4_CONF_ARP_IGNORE, "arp_ignore" },
+ { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" },
+ { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_conf_table[] = {
+ { NET_PROTO_CONF_ALL, "all", trans_net_ipv4_conf_vars_table },
+ { NET_PROTO_CONF_DEFAULT, "default", trans_net_ipv4_conf_vars_table },
+ { 0, NULL, trans_net_ipv4_conf_vars_table },
+ {}
+};
+
+
+static struct trans_ctl_table trans_net_ipv4_vs_table[] = {
+ { NET_IPV4_VS_AMEMTHRESH, "amemthresh" },
+ { NET_IPV4_VS_DEBUG_LEVEL, "debug_level" },
+ { NET_IPV4_VS_AMDROPRATE, "am_droprate" },
+ { NET_IPV4_VS_DROP_ENTRY, "drop_entry" },
+ { NET_IPV4_VS_DROP_PACKET, "drop_packet" },
+ { NET_IPV4_VS_SECURE_TCP, "secure_tcp" },
+ { NET_IPV4_VS_TO_ES, "timeout_established" },
+ { NET_IPV4_VS_TO_SS, "timeout_synsent" },
+ { NET_IPV4_VS_TO_SR, "timeout_synrecv" },
+ { NET_IPV4_VS_TO_FW, "timeout_finwait" },
+ { NET_IPV4_VS_TO_TW, "timeout_timewait" },
+ { NET_IPV4_VS_TO_CL, "timeout_close" },
+ { NET_IPV4_VS_TO_CW, "timeout_closewait" },
+ { NET_IPV4_VS_TO_LA, "timeout_lastack" },
+ { NET_IPV4_VS_TO_LI, "timeout_listen" },
+ { NET_IPV4_VS_TO_SA, "timeout_synack" },
+ { NET_IPV4_VS_TO_UDP, "timeout_udp" },
+ { NET_IPV4_VS_TO_ICMP, "timeout_icmp" },
+ { NET_IPV4_VS_CACHE_BYPASS, "cache_bypass" },
+ { NET_IPV4_VS_EXPIRE_NODEST_CONN, "expire_nodest_conn" },
+ { NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE, "expire_quiescent_template" },
+ { NET_IPV4_VS_SYNC_THRESHOLD, "sync_threshold" },
+ { NET_IPV4_VS_NAT_ICMP_SEND, "nat_icmp_send" },
+ { NET_IPV4_VS_LBLC_EXPIRE, "lblc_expiration" },
+ { NET_IPV4_VS_LBLCR_EXPIRE, "lblcr_expiration" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_neigh_vars_table[] = {
+ { NET_NEIGH_MCAST_SOLICIT, "mcast_solicit" },
+ { NET_NEIGH_UCAST_SOLICIT, "ucast_solicit" },
+ { NET_NEIGH_APP_SOLICIT, "app_solicit" },
+ { NET_NEIGH_RETRANS_TIME, "retrans_time" },
+ { NET_NEIGH_REACHABLE_TIME, "base_reachable_time" },
+ { NET_NEIGH_DELAY_PROBE_TIME, "delay_first_probe_time" },
+ { NET_NEIGH_GC_STALE_TIME, "gc_stale_time" },
+ { NET_NEIGH_UNRES_QLEN, "unres_qlen" },
+ { NET_NEIGH_PROXY_QLEN, "proxy_qlen" },
+ { NET_NEIGH_ANYCAST_DELAY, "anycast_delay" },
+ { NET_NEIGH_PROXY_DELAY, "proxy_delay" },
+ { NET_NEIGH_LOCKTIME, "locktime" },
+ { NET_NEIGH_GC_INTERVAL, "gc_interval" },
+ { NET_NEIGH_GC_THRESH1, "gc_thresh1" },
+ { NET_NEIGH_GC_THRESH2, "gc_thresh2" },
+ { NET_NEIGH_GC_THRESH3, "gc_thresh3" },
+ { NET_NEIGH_RETRANS_TIME_MS, "retrans_time_ms" },
+ { NET_NEIGH_REACHABLE_TIME_MS, "base_reachable_time_ms" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_neigh_table[] = {
+ { NET_PROTO_CONF_DEFAULT, "default", trans_net_neigh_vars_table },
+ { 0, NULL, trans_net_neigh_vars_table },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_netfilter_table[] = {
+ { NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max" },
+
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "ip_conntrack_tcp_timeout_syn_recv" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "ip_conntrack_tcp_timeout_established" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "ip_conntrack_tcp_timeout_fin_wait" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "ip_conntrack_tcp_timeout_close_wait" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "ip_conntrack_tcp_timeout_last_ack" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "ip_conntrack_tcp_timeout_time_wait" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "ip_conntrack_tcp_timeout_close" },
+
+ { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, "ip_conntrack_udp_timeout" },
+ { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "ip_conntrack_udp_timeout_stream" },
+ { NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, "ip_conntrack_icmp_timeout" },
+ { NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, "ip_conntrack_generic_timeout" },
+
+ { NET_IPV4_NF_CONNTRACK_BUCKETS, "ip_conntrack_buckets" },
+ { NET_IPV4_NF_CONNTRACK_LOG_INVALID, "ip_conntrack_log_invalid" },
+ { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, "ip_conntrack_tcp_timeout_max_retrans" },
+ { NET_IPV4_NF_CONNTRACK_TCP_LOOSE, "ip_conntrack_tcp_loose" },
+ { NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL, "ip_conntrack_tcp_be_liberal" },
+ { NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS, "ip_conntrack_tcp_max_retrans" },
+
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, "ip_conntrack_sctp_timeout_closed" },
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, "ip_conntrack_sctp_timeout_cookie_wait" },
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, "ip_conntrack_sctp_timeout_cookie_echoed" },
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, "ip_conntrack_sctp_timeout_established" },
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, "ip_conntrack_sctp_timeout_shutdown_sent" },
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, "ip_conntrack_sctp_timeout_shutdown_recd" },
+ { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "ip_conntrack_sctp_timeout_shutdown_ack_sent" },
+
+ { NET_IPV4_NF_CONNTRACK_COUNT, "ip_conntrack_count" },
+ { NET_IPV4_NF_CONNTRACK_CHECKSUM, "ip_conntrack_checksum" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv4_table[] = {
+ { NET_IPV4_FORWARD, "ip_forward" },
+ { NET_IPV4_DYNADDR, "ip_dynaddr" },
+
+ { NET_IPV4_CONF, "conf", trans_net_ipv4_conf_table },
+ { NET_IPV4_NEIGH, "neigh", trans_net_neigh_table },
+ { NET_IPV4_ROUTE, "route", trans_net_ipv4_route_table },
+ /* NET_IPV4_FIB_HASH unused */
+ { NET_IPV4_NETFILTER, "netfilter", trans_net_ipv4_netfilter_table },
+ { NET_IPV4_VS, "vs", trans_net_ipv4_vs_table },
+
+ { NET_IPV4_TCP_TIMESTAMPS, "tcp_timestamps" },
+ { NET_IPV4_TCP_WINDOW_SCALING, "tcp_window_scaling" },
+ { NET_IPV4_TCP_SACK, "tcp_sack" },
+ { NET_IPV4_TCP_RETRANS_COLLAPSE, "tcp_retrans_collapse" },
+ { NET_IPV4_DEFAULT_TTL, "ip_default_ttl" },
+ /* NET_IPV4_AUTOCONFIG unused */
+ { NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc" },
+ { NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries" },
+ { NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh" },
+ { NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh" },
+ { NET_IPV4_IPFRAG_TIME, "ipfrag_time" },
+ /* NET_IPV4_TCP_MAX_KA_PROBES unused */
+ { NET_IPV4_TCP_KEEPALIVE_TIME, "tcp_keepalive_time" },
+ { NET_IPV4_TCP_KEEPALIVE_PROBES, "tcp_keepalive_probes" },
+ { NET_IPV4_TCP_RETRIES1, "tcp_retries1" },
+ { NET_IPV4_TCP_RETRIES2, "tcp_retries2" },
+ { NET_IPV4_TCP_FIN_TIMEOUT, "tcp_fin_timeout" },
+ /* NET_IPV4_IP_MASQ_DEBUG unused */
+ { NET_TCP_SYNCOOKIES, "tcp_syncookies" },
+ { NET_TCP_STDURG, "tcp_stdurg" },
+ { NET_TCP_RFC1337, "tcp_rfc1337" },
+ /* NET_TCP_SYN_TAILDROP unused */
+ { NET_TCP_MAX_SYN_BACKLOG, "tcp_max_syn_backlog" },
+ { NET_IPV4_LOCAL_PORT_RANGE, "ip_local_port_range" },
+ { NET_IPV4_ICMP_ECHO_IGNORE_ALL, "icmp_echo_ignore_all" },
+ { NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "icmp_echo_ignore_broadcasts" },
+ /* NET_IPV4_ICMP_SOURCEQUENCH_RATE unused */
+ /* NET_IPV4_ICMP_DESTUNREACH_RATE unused */
+ /* NET_IPV4_ICMP_TIMEEXCEED_RATE unused */
+ /* NET_IPV4_ICMP_PARAMPROB_RATE unused */
+ /* NET_IPV4_ICMP_ECHOREPLY_RATE unused */
+ { NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses" },
+ { NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships" },
+ { NET_TCP_TW_RECYCLE, "tcp_tw_recycle" },
+ /* NET_IPV4_ALWAYS_DEFRAG unused */
+ { NET_IPV4_TCP_KEEPALIVE_INTVL, "tcp_keepalive_intvl" },
+ { NET_IPV4_INET_PEER_THRESHOLD, "inet_peer_threshold" },
+ { NET_IPV4_INET_PEER_MINTTL, "inet_peer_minttl" },
+ { NET_IPV4_INET_PEER_MAXTTL, "inet_peer_maxttl" },
+ { NET_IPV4_INET_PEER_GC_MINTIME, "inet_peer_gc_mintime" },
+ { NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime" },
+ { NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries" },
+ { NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow" },
+ { NET_TCP_SYNACK_RETRIES, "tcp_synack_retries" },
+ { NET_TCP_MAX_ORPHANS, "tcp_max_orphans" },
+ { NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets" },
+ { NET_TCP_FACK, "tcp_fack" },
+ { NET_TCP_REORDERING, "tcp_reordering" },
+ { NET_TCP_ECN, "tcp_ecn" },
+ { NET_TCP_DSACK, "tcp_dsack" },
+ { NET_TCP_MEM, "tcp_mem" },
+ { NET_TCP_WMEM, "tcp_wmem" },
+ { NET_TCP_RMEM, "tcp_rmem" },
+ { NET_TCP_APP_WIN, "tcp_app_win" },
+ { NET_TCP_ADV_WIN_SCALE, "tcp_adv_win_scale" },
+ { NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind" },
+ { NET_IPV4_ICMP_RATELIMIT, "icmp_ratelimit" },
+ { NET_IPV4_ICMP_RATEMASK, "icmp_ratemask" },
+ { NET_TCP_TW_REUSE, "tcp_tw_reuse" },
+ { NET_TCP_FRTO, "tcp_frto" },
+ { NET_TCP_LOW_LATENCY, "tcp_low_latency" },
+ { NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" },
+ { NET_IPV4_IGMP_MAX_MSF, "igmp_max_msf" },
+ { NET_TCP_NO_METRICS_SAVE, "tcp_no_metrics_save" },
+ /* NET_TCP_DEFAULT_WIN_SCALE unused */
+ { NET_TCP_MODERATE_RCVBUF, "tcp_moderate_rcvbuf" },
+ { NET_TCP_TSO_WIN_DIVISOR, "tcp_tso_win_divisor" },
+ /* NET_TCP_BIC_BETA unused */
+ { NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR, "icmp_errors_use_inbound_ifaddr" },
+ { NET_TCP_CONG_CONTROL, "tcp_congestion_control" },
+ { NET_TCP_ABC, "tcp_abc" },
+ { NET_IPV4_IPFRAG_MAX_DIST, "ipfrag_max_dist" },
+ { NET_TCP_MTU_PROBING, "tcp_mtu_probing" },
+ { NET_TCP_BASE_MSS, "tcp_base_mss" },
+ { NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS, "tcp_workaround_signed_windows" },
+ { NET_TCP_DMA_COPYBREAK, "tcp_dma_copybreak" },
+ { NET_TCP_SLOW_START_AFTER_IDLE, "tcp_slow_start_after_idle" },
+ { NET_CIPSOV4_CACHE_ENABLE, "cipso_cache_enable" },
+ { NET_CIPSOV4_CACHE_BUCKET_SIZE, "cipso_cache_bucket_size" },
+ { NET_CIPSOV4_RBM_OPTFMT, "cipso_rbm_optfmt" },
+ { NET_CIPSOV4_RBM_STRICTVALID, "cipso_rbm_strictvalid" },
+ { NET_TCP_AVAIL_CONG_CONTROL, "tcp_available_congestion_control" },
+ { NET_TCP_ALLOWED_CONG_CONTROL, "tcp_allowed_congestion_control" },
+ { NET_TCP_MAX_SSTHRESH, "tcp_max_ssthresh" },
+ { NET_TCP_FRTO_RESPONSE, "tcp_frto_response" },
+ { 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipx_table[] = {
+ { NET_IPX_PPROP_BROADCASTING, "ipx_pprop_broadcasting" },
+ /* NET_IPX_FORWARDING unused */
+ {}
+};
+
+static struct trans_ctl_table trans_net_atalk_table[] = {
+ { NET_ATALK_AARP_EXPIRY_TIME, "aarp-expiry-time" },
+ { NET_ATALK_AARP_TICK_TIME, "aarp-tick-time" },
+ { NET_ATALK_AARP_RETRANSMIT_LIMIT, "aarp-retransmit-limit" },
+ { NET_ATALK_AARP_RESOLVE_TIME, "aarp-resolve-time" },
+ {},
+};
+
+static struct trans_ctl_table trans_net_netrom_table[] = {
+ { NET_NETROM_DEFAULT_PATH_QUALITY, "default_path_quality" },
+ { NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER, "obsolescence_count_initialiser" },
+ { NET_NETROM_NETWORK_TTL_INITIALISER, "network_ttl_initialiser" },
+ { NET_NETROM_TRANSPORT_TIMEOUT, "transport_timeout" },
+ { NET_NETROM_TRANSPORT_MAXIMUM_TRIES, "transport_maximum_tries" },
+ { NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY, "transport_acknowledge_delay" },
+ { NET_NETROM_TRANSPORT_BUSY_DELAY, "transport_busy_delay" },
+ { NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE, "transport_requested_window_size" },
+ { NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT, "transport_no_activity_timeout" },
+ { NET_NETROM_ROUTING_CONTROL, "routing_control" },
+ { NET_NETROM_LINK_FAILS_COUNT, "link_fails_count" },
+ { NET_NETROM_RESET, "reset" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ax25_table[] = {
+ { NET_AX25_IP_DEFAULT_MODE, "ip_default_mode" },
+ { NET_AX25_DEFAULT_MODE, "ax25_default_mode" },
+ { NET_AX25_BACKOFF_TYPE, "backoff_type" },
+ { NET_AX25_CONNECT_MODE, "connect_mode" },
+ { NET_AX25_STANDARD_WINDOW, "standard_window_size" },
+ { NET_AX25_EXTENDED_WINDOW, "extended_window_size" },
+ { NET_AX25_T1_TIMEOUT, "t1_timeout" },
+ { NET_AX25_T2_TIMEOUT, "t2_timeout" },
+ { NET_AX25_T3_TIMEOUT, "t3_timeout" },
+ { NET_AX25_IDLE_TIMEOUT, "idle_timeout" },
+ { NET_AX25_N2, "maximum_retry_count" },
+ { NET_AX25_PACLEN, "maximum_packet_length" },
+ { NET_AX25_PROTOCOL, "protocol" },
+ { NET_AX25_DAMA_SLAVE_TIMEOUT, "dama_slave_timeout" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_bridge_table[] = {
+ { NET_BRIDGE_NF_CALL_ARPTABLES, "bridge-nf-call-arptables" },
+ { NET_BRIDGE_NF_CALL_IPTABLES, "bridge-nf-call-iptables" },
+ { NET_BRIDGE_NF_CALL_IP6TABLES, "bridge-nf-call-ip6tables" },
+ { NET_BRIDGE_NF_FILTER_VLAN_TAGGED, "bridge-nf-filter-vlan-tagged" },
+ { NET_BRIDGE_NF_FILTER_PPPOE_TAGGED, "bridge-nf-filter-pppoe-tagged" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_rose_table[] = {
+ { NET_ROSE_RESTART_REQUEST_TIMEOUT, "restart_request_timeout" },
+ { NET_ROSE_CALL_REQUEST_TIMEOUT, "call_request_timeout" },
+ { NET_ROSE_RESET_REQUEST_TIMEOUT, "reset_request_timeout" },
+ { NET_ROSE_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout" },
+ { NET_ROSE_ACK_HOLD_BACK_TIMEOUT, "acknowledge_hold_back_timeout" },
+ { NET_ROSE_ROUTING_CONTROL, "routing_control" },
+ { NET_ROSE_LINK_FAIL_TIMEOUT, "link_fail_timeout" },
+ { NET_ROSE_MAX_VCS, "maximum_virtual_circuits" },
+ { NET_ROSE_WINDOW_SIZE, "window_size" },
+ { NET_ROSE_NO_ACTIVITY_TIMEOUT, "no_activity_timeout" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_conf_var_table[] = {
+ { NET_IPV6_FORWARDING, "forwarding" },
+ { NET_IPV6_HOP_LIMIT, "hop_limit" },
+ { NET_IPV6_MTU, "mtu" },
+ { NET_IPV6_ACCEPT_RA, "accept_ra" },
+ { NET_IPV6_ACCEPT_REDIRECTS, "accept_redirects" },
+ { NET_IPV6_AUTOCONF, "autoconf" },
+ { NET_IPV6_DAD_TRANSMITS, "dad_transmits" },
+ { NET_IPV6_RTR_SOLICITS, "router_solicitations" },
+ { NET_IPV6_RTR_SOLICIT_INTERVAL, "router_solicitation_interval" },
+ { NET_IPV6_RTR_SOLICIT_DELAY, "router_solicitation_delay" },
+ { NET_IPV6_USE_TEMPADDR, "use_tempaddr" },
+ { NET_IPV6_TEMP_VALID_LFT, "temp_valid_lft" },
+ { NET_IPV6_TEMP_PREFERED_LFT, "temp_prefered_lft" },
+ { NET_IPV6_REGEN_MAX_RETRY, "regen_max_retry" },
+ { NET_IPV6_MAX_DESYNC_FACTOR, "max_desync_factor" },
+ { NET_IPV6_MAX_ADDRESSES, "max_addresses" },
+ { NET_IPV6_FORCE_MLD_VERSION, "force_mld_version" },
+ { NET_IPV6_ACCEPT_RA_DEFRTR, "accept_ra_defrtr" },
+ { NET_IPV6_ACCEPT_RA_PINFO, "accept_ra_pinfo" },
+ { NET_IPV6_ACCEPT_RA_RTR_PREF, "accept_ra_rtr_pref" },
+ { NET_IPV6_RTR_PROBE_INTERVAL, "router_probe_interval" },
+ { NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN, "accept_ra_rt_info_max_plen" },
+ { NET_IPV6_PROXY_NDP, "proxy_ndp" },
+ { NET_IPV6_ACCEPT_SOURCE_ROUTE, "accept_source_route" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_conf_table[] = {
+ { NET_PROTO_CONF_ALL, "all", trans_net_ipv6_conf_var_table },
+ { NET_PROTO_CONF_DEFAULT, "default", trans_net_ipv6_conf_var_table },
+ { 0, NULL, trans_net_ipv6_conf_var_table },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_route_table[] = {
+ { NET_IPV6_ROUTE_FLUSH, "flush" },
+ { NET_IPV6_ROUTE_GC_THRESH, "gc_thresh" },
+ { NET_IPV6_ROUTE_MAX_SIZE, "max_size" },
+ { NET_IPV6_ROUTE_GC_MIN_INTERVAL, "gc_min_interval" },
+ { NET_IPV6_ROUTE_GC_TIMEOUT, "gc_timeout" },
+ { NET_IPV6_ROUTE_GC_INTERVAL, "gc_interval" },
+ { NET_IPV6_ROUTE_GC_ELASTICITY, "gc_elasticity" },
+ { NET_IPV6_ROUTE_MTU_EXPIRES, "mtu_expires" },
+ { NET_IPV6_ROUTE_MIN_ADVMSS, "min_adv_mss" },
+ { NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, "gc_min_interval_ms" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_icmp_table[] = {
+ { NET_IPV6_ICMP_RATELIMIT, "ratelimit" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_ipv6_table[] = {
+ { NET_IPV6_CONF, "conf", trans_net_ipv6_conf_table },
+ { NET_IPV6_NEIGH, "neigh", trans_net_neigh_table },
+ { NET_IPV6_ROUTE, "route", trans_net_ipv6_route_table },
+ { NET_IPV6_ICMP, "icmp", trans_net_ipv6_icmp_table },
+ { NET_IPV6_BINDV6ONLY, "bindv6only" },
+ { NET_IPV6_IP6FRAG_HIGH_THRESH, "ip6frag_high_thresh" },
+ { NET_IPV6_IP6FRAG_LOW_THRESH, "ip6frag_low_thresh" },
+ { NET_IPV6_IP6FRAG_TIME, "ip6frag_time" },
+ { NET_IPV6_IP6FRAG_SECRET_INTERVAL, "ip6frag_secret_interval" },
+ { NET_IPV6_MLD_MAX_MSF, "mld_max_msf" },
+ { 2088 /* IPQ_QMAX */, "ip6_queue_maxlen" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_x25_table[] = {
+ { NET_X25_RESTART_REQUEST_TIMEOUT, "restart_request_timeout" },
+ { NET_X25_CALL_REQUEST_TIMEOUT, "call_request_timeout" },
+ { NET_X25_RESET_REQUEST_TIMEOUT, "reset_request_timeout" },
+ { NET_X25_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout" },
+ { NET_X25_ACK_HOLD_BACK_TIMEOUT, "acknowledgement_hold_back_timeout" },
+ { NET_X25_FORWARD, "x25_forward" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_tr_table[] = {
+ { NET_TR_RIF_TIMEOUT, "rif_timeout" },
+ {}
+};
+
+
+static struct trans_ctl_table trans_net_decnet_conf_vars[] = {
+ { NET_DECNET_CONF_DEV_FORWARDING, "forwarding" },
+ { NET_DECNET_CONF_DEV_PRIORITY, "priority" },
+ { NET_DECNET_CONF_DEV_T2, "t2" },
+ { NET_DECNET_CONF_DEV_T3, "t3" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_decnet_conf[] = {
+ { 0, NULL, trans_net_decnet_conf_vars },
+ {}
+};
+
+static struct trans_ctl_table trans_net_decnet_table[] = {
+ { NET_DECNET_CONF, "conf", trans_net_decnet_conf },
+ { NET_DECNET_NODE_ADDRESS, "node_address" },
+ { NET_DECNET_NODE_NAME, "node_name" },
+ { NET_DECNET_DEFAULT_DEVICE, "default_device" },
+ { NET_DECNET_TIME_WAIT, "time_wait" },
+ { NET_DECNET_DN_COUNT, "dn_count" },
+ { NET_DECNET_DI_COUNT, "di_count" },
+ { NET_DECNET_DR_COUNT, "dr_count" },
+ { NET_DECNET_DST_GC_INTERVAL, "dst_gc_interval" },
+ { NET_DECNET_NO_FC_MAX_CWND, "no_fc_max_cwnd" },
+ { NET_DECNET_MEM, "decnet_mem" },
+ { NET_DECNET_RMEM, "decnet_rmem" },
+ { NET_DECNET_WMEM, "decnet_wmem" },
+ { NET_DECNET_DEBUG_LEVEL, "debug" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_sctp_table[] = {
+ { NET_SCTP_RTO_INITIAL, "rto_initial" },
+ { NET_SCTP_RTO_MIN, "rto_min" },
+ { NET_SCTP_RTO_MAX, "rto_max" },
+ { NET_SCTP_RTO_ALPHA, "rto_alpha_exp_divisor" },
+ { NET_SCTP_RTO_BETA, "rto_beta_exp_divisor" },
+ { NET_SCTP_VALID_COOKIE_LIFE, "valid_cookie_life" },
+ { NET_SCTP_ASSOCIATION_MAX_RETRANS, "association_max_retrans" },
+ { NET_SCTP_PATH_MAX_RETRANS, "path_max_retrans" },
+ { NET_SCTP_MAX_INIT_RETRANSMITS, "max_init_retransmits" },
+ { NET_SCTP_HB_INTERVAL, "hb_interval" },
+ { NET_SCTP_PRESERVE_ENABLE, "cookie_preserve_enable" },
+ { NET_SCTP_MAX_BURST, "max_burst" },
+ { NET_SCTP_ADDIP_ENABLE, "addip_enable" },
+ { NET_SCTP_PRSCTP_ENABLE, "prsctp_enable" },
+ { NET_SCTP_SNDBUF_POLICY, "sndbuf_policy" },
+ { NET_SCTP_SACK_TIMEOUT, "sack_timeout" },
+ { NET_SCTP_RCVBUF_POLICY, "rcvbuf_policy" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_llc_llc2_timeout_table[] = {
+ { NET_LLC2_ACK_TIMEOUT, "ack" },
+ { NET_LLC2_P_TIMEOUT, "p" },
+ { NET_LLC2_REJ_TIMEOUT, "rej" },
+ { NET_LLC2_BUSY_TIMEOUT, "busy" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_llc_station_table[] = {
+ { NET_LLC_STATION_ACK_TIMEOUT, "ack_timeout" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_llc_llc2_table[] = {
+ { NET_LLC2, "timeout", trans_net_llc_llc2_timeout_table },
+ {}
+};
+
+static struct trans_ctl_table trans_net_llc_table[] = {
+ { NET_LLC2, "llc2", trans_net_llc_llc2_table },
+ { NET_LLC_STATION, "station", trans_net_llc_station_table },
+ {}
+};
+
+static struct trans_ctl_table trans_net_netfilter_table[] = {
+ { NET_NF_CONNTRACK_MAX, "nf_conntrack_max" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "nf_conntrack_tcp_timeout_syn_sent" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "nf_conntrack_tcp_timeout_syn_recv" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "nf_conntrack_tcp_timeout_established" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "nf_conntrack_tcp_timeout_fin_wait" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "nf_conntrack_tcp_timeout_close_wait" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "nf_conntrack_tcp_timeout_last_ack" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "nf_conntrack_tcp_timeout_time_wait" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "nf_conntrack_tcp_timeout_close" },
+ { NET_NF_CONNTRACK_UDP_TIMEOUT, "nf_conntrack_udp_timeout" },
+ { NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "nf_conntrack_udp_timeout_stream" },
+ { NET_NF_CONNTRACK_ICMP_TIMEOUT, "nf_conntrack_icmp_timeout" },
+ { NET_NF_CONNTRACK_GENERIC_TIMEOUT, "nf_conntrack_generic_timeout" },
+ { NET_NF_CONNTRACK_BUCKETS, "nf_conntrack_buckets" },
+ { NET_NF_CONNTRACK_LOG_INVALID, "nf_conntrack_log_invalid" },
+ { NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, "nf_conntrack_tcp_timeout_max_retrans" },
+ { NET_NF_CONNTRACK_TCP_LOOSE, "nf_conntrack_tcp_loose" },
+ { NET_NF_CONNTRACK_TCP_BE_LIBERAL, "nf_conntrack_tcp_be_liberal" },
+ { NET_NF_CONNTRACK_TCP_MAX_RETRANS, "nf_conntrack_tcp_max_retrans" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, "nf_conntrack_sctp_timeout_closed" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, "nf_conntrack_sctp_timeout_cookie_wait" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, "nf_conntrack_sctp_timeout_cookie_echoed" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, "nf_conntrack_sctp_timeout_established" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, "nf_conntrack_sctp_timeout_shutdown_sent" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, "nf_conntrack_sctp_timeout_shutdown_recd" },
+ { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "nf_conntrack_sctp_timeout_shutdown_ack_sent" },
+ { NET_NF_CONNTRACK_COUNT, "nf_conntrack_count" },
+ { NET_NF_CONNTRACK_ICMPV6_TIMEOUT, "nf_conntrack_icmpv6_timeout" },
+ { NET_NF_CONNTRACK_FRAG6_TIMEOUT, "nf_conntrack_frag6_timeout" },
+ { NET_NF_CONNTRACK_FRAG6_LOW_THRESH, "nf_conntrack_frag6_low_thresh" },
+ { NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, "nf_conntrack_frag6_high_thresh" },
+ { NET_NF_CONNTRACK_CHECKSUM, "nf_conntrack_checksum" },
+
+ {}
+};
+
+static struct trans_ctl_table trans_net_dccp_table[] = {
+ { NET_DCCP_DEFAULT, "default" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_irda_table[] = {
+ { NET_IRDA_DISCOVERY, "discovery" },
+ { NET_IRDA_DEVNAME, "devname" },
+ { NET_IRDA_DEBUG, "debug" },
+ { NET_IRDA_FAST_POLL, "fast_poll_increase" },
+ { NET_IRDA_DISCOVERY_SLOTS, "discovery_slots" },
+ { NET_IRDA_DISCOVERY_TIMEOUT, "discovery_timeout" },
+ { NET_IRDA_SLOT_TIMEOUT, "slot_timeout" },
+ { NET_IRDA_MAX_BAUD_RATE, "max_baud_rate" },
+ { NET_IRDA_MIN_TX_TURN_TIME, "min_tx_turn_time" },
+ { NET_IRDA_MAX_TX_DATA_SIZE, "max_tx_data_size" },
+ { NET_IRDA_MAX_TX_WINDOW, "max_tx_window" },
+ { NET_IRDA_MAX_NOREPLY_TIME, "max_noreply_time" },
+ { NET_IRDA_WARN_NOREPLY_TIME, "warn_noreply_time" },
+ { NET_IRDA_LAP_KEEPALIVE_TIME, "lap_keepalive_time" },
+ {}
+};
+
+static struct trans_ctl_table trans_net_table[] = {
+ { NET_CORE, "core", trans_net_core_table },
+ /* NET_ETHER not used */
+ /* NET_802 not used */
+ { 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_NETROM, "netrom", trans_net_netrom_table },
+ { NET_AX25, "ax25", trans_net_ax25_table },
+ { NET_BRIDGE, "bridge", trans_net_bridge_table },
+ { NET_ROSE, "rose", trans_net_rose_table },
+ { NET_IPV6, "ipv6", trans_net_ipv6_table },
+ { NET_X25, "x25", trans_net_x25_table },
+ { NET_TR, "tr", trans_net_tr_table },
+ { NET_DECNET, "decnet", trans_net_decnet_table },
+ /* NET_ECONET not used */
+ { NET_SCTP, "sctp", trans_net_sctp_table },
+ { NET_LLC, "llc", trans_net_llc_table },
+ { NET_NETFILTER, "netfilter", trans_net_netfilter_table },
+ { NET_DCCP, "dccp", trans_net_dccp_table },
+ { NET_IRDA, "irda", trans_net_irda_table },
+ { 2089, "nf_conntrack_max" },
+ {}
+};
+
+static struct trans_ctl_table trans_fs_quota_table[] = {
+ { FS_DQ_LOOKUPS, "lookups" },
+ { FS_DQ_DROPS, "drops" },
+ { FS_DQ_READS, "reads" },
+ { FS_DQ_WRITES, "writes" },
+ { FS_DQ_CACHE_HITS, "cache_hits" },
+ { FS_DQ_ALLOCATED, "allocated_dquots" },
+ { FS_DQ_FREE, "free_dquots" },
+ { FS_DQ_SYNCS, "syncs" },
+ { FS_DQ_WARNINGS, "warnings" },
+ {}
+};
+
+static struct trans_ctl_table trans_fs_xfs_table[] = {
+ { XFS_RESTRICT_CHOWN, "restrict_chown" },
+ { XFS_SGID_INHERIT, "irix_sgid_inherit" },
+ { XFS_SYMLINK_MODE, "irix_symlink_mode" },
+ { XFS_PANIC_MASK, "panic_mask" },
+
+ { XFS_ERRLEVEL, "error_level" },
+ { XFS_SYNCD_TIMER, "xfssyncd_centisecs" },
+ { XFS_INHERIT_SYNC, "inherit_sync" },
+ { XFS_INHERIT_NODUMP, "inherit_nodump" },
+ { XFS_INHERIT_NOATIME, "inherit_noatime" },
+ { XFS_BUF_TIMER, "xfsbufd_centisecs" },
+ { XFS_BUF_AGE, "age_buffer_centisecs" },
+ { XFS_INHERIT_NOSYM, "inherit_nosymlinks" },
+ { XFS_ROTORSTEP, "rotorstep" },
+ { XFS_INHERIT_NODFRG, "inherit_nodefrag" },
+ { XFS_FILESTREAM_TIMER, "filestream_centisecs" },
+ { XFS_STATS_CLEAR, "stats_clear" },
+ {}
+};
+
+static struct trans_ctl_table trans_fs_ocfs2_nm_table[] = {
+ { 1, "hb_ctl_path" },
+ {}
+};
+
+static struct trans_ctl_table trans_fs_ocfs2_table[] = {
+ { 1, "nm", trans_fs_ocfs2_nm_table },
+ {}
+};
+
+static struct trans_ctl_table trans_inotify_table[] = {
+ { INOTIFY_MAX_USER_INSTANCES, "max_user_instances" },
+ { INOTIFY_MAX_USER_WATCHES, "max_user_watches" },
+ { INOTIFY_MAX_QUEUED_EVENTS, "max_queued_events" },
+ {}
+};
+
+static struct trans_ctl_table trans_fs_table[] = {
+ { FS_NRINODE, "inode-nr" },
+ { FS_STATINODE, "inode-state" },
+ /* FS_MAXINODE unused */
+ /* FS_NRDQUOT unused */
+ /* FS_MAXDQUOT unused */
+ { FS_NRFILE, "file-nr" },
+ { FS_MAXFILE, "file-max" },
+ { FS_DENTRY, "dentry-state" },
+ /* FS_NRSUPER unused */
+ /* FS_MAXUPSER unused */
+ { FS_OVERFLOWUID, "overflowuid" },
+ { FS_OVERFLOWGID, "overflowgid" },
+ { FS_LEASES, "leases-enable" },
+ { FS_DIR_NOTIFY, "dir-notify-enable" },
+ { FS_LEASE_TIME, "lease-break-time" },
+ { FS_DQSTATS, "quota", trans_fs_quota_table },
+ { FS_XFS, "xfs", trans_fs_xfs_table },
+ { FS_AIO_NR, "aio-nr" },
+ { FS_AIO_MAX_NR, "aio-max-nr" },
+ { FS_INOTIFY, "inotify", trans_inotify_table },
+ { FS_OCFS2, "ocfs2", trans_fs_ocfs2_table },
+ { KERN_SETUID_DUMPABLE, "suid_dumpable" },
+ {}
+};
+
+static struct trans_ctl_table trans_debug_table[] = {
+ {}
+};
+
+static struct trans_ctl_table trans_cdrom_table[] = {
+ { DEV_CDROM_INFO, "info" },
+ { DEV_CDROM_AUTOCLOSE, "autoclose" },
+ { DEV_CDROM_AUTOEJECT, "autoeject" },
+ { DEV_CDROM_DEBUG, "debug" },
+ { DEV_CDROM_LOCK, "lock" },
+ { DEV_CDROM_CHECK_MEDIA, "check_media" },
+ {}
+};
+
+static struct trans_ctl_table trans_ipmi_table[] = {
+ { DEV_IPMI_POWEROFF_POWERCYCLE, "poweroff_powercycle" },
+ {}
+};
+
+static struct trans_ctl_table trans_mac_hid_files[] = {
+ /* DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES unused */
+ /* DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES unused */
+ { DEV_MAC_HID_MOUSE_BUTTON_EMULATION, "mouse_button_emulation" },
+ { DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE, "mouse_button2_keycode" },
+ { DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE, "mouse_button3_keycode" },
+ /* DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES unused */
+ {}
+};
+
+static struct trans_ctl_table trans_raid_table[] = {
+ { DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min" },
+ { DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max" },
+ {}
+};
+
+static struct trans_ctl_table trans_scsi_table[] = {
+ { DEV_SCSI_LOGGING_LEVEL, "logging_level" },
+ {}
+};
+
+static struct trans_ctl_table trans_parport_default_table[] = {
+ { DEV_PARPORT_DEFAULT_TIMESLICE, "timeslice" },
+ { DEV_PARPORT_DEFAULT_SPINTIME, "spintime" },
+ {}
+};
+
+static struct trans_ctl_table trans_parport_device_table[] = {
+ { DEV_PARPORT_DEVICE_TIMESLICE, "timeslice" },
+ {}
+};
+
+static struct trans_ctl_table trans_parport_devices_table[] = {
+ { DEV_PARPORT_DEVICES_ACTIVE, "active" },
+ { 0, NULL, trans_parport_device_table },
+ {}
+};
+
+static struct trans_ctl_table trans_parport_parport_table[] = {
+ { DEV_PARPORT_SPINTIME, "spintime" },
+ { DEV_PARPORT_BASE_ADDR, "base-addr" },
+ { DEV_PARPORT_IRQ, "irq" },
+ { DEV_PARPORT_DMA, "dma" },
+ { DEV_PARPORT_MODES, "modes" },
+ { DEV_PARPORT_DEVICES, "devices", trans_parport_devices_table },
+ { DEV_PARPORT_AUTOPROBE, "autoprobe" },
+ { DEV_PARPORT_AUTOPROBE + 1, "autoprobe0" },
+ { DEV_PARPORT_AUTOPROBE + 2, "autoprobe1" },
+ { DEV_PARPORT_AUTOPROBE + 3, "autoprobe2" },
+ { DEV_PARPORT_AUTOPROBE + 4, "autoprobe3" },
+ {}
+};
+static struct trans_ctl_table trans_parport_table[] = {
+ { DEV_PARPORT_DEFAULT, "default", trans_parport_default_table },
+ { 0, NULL, trans_parport_parport_table },
+ {}
+};
+
+static struct trans_ctl_table trans_dev_table[] = {
+ { DEV_CDROM, "cdrom", trans_cdrom_table },
+ /* DEV_HWMON unused */
+ { DEV_PARPORT, "parport", trans_parport_table },
+ { DEV_RAID, "raid", trans_raid_table },
+ { DEV_MAC_HID, "mac_hid", trans_mac_hid_files },
+ { DEV_SCSI, "scsi", trans_scsi_table },
+ { DEV_IPMI, "ipmi", trans_ipmi_table },
+ {}
+};
+
+static struct trans_ctl_table trans_bus_isa_table[] = {
+ { BUS_ISA_MEM_BASE, "membase" },
+ { BUS_ISA_PORT_BASE, "portbase" },
+ { BUS_ISA_PORT_SHIFT, "portshift" },
+ {}
+};
+
+static struct trans_ctl_table trans_bus_table[] = {
+ { CTL_BUS_ISA, "isa", trans_bus_isa_table },
+ {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table0[] = {
+ { 1, "spreadingCode" },
+ { 2, "channelNumber" },
+ { 3, "scramblingDisable" },
+ { 4, "txAttenuation" },
+ { 5, "systemId" },
+ { 6, "maxDatagramSize" },
+ { 7, "maxFrameSize" },
+ { 8, "maxRetries" },
+ { 9, "receiveMode" },
+ { 10, "priority" },
+ { 11, "rootOrRepeater" },
+ { 12, "SID" },
+ { 13, "registrationMode" },
+ { 14, "registrationFill" },
+ { 15, "localTalkAddress" },
+ { 16, "codeFormat" },
+ { 17, "numChannels" },
+ { 18, "channel1" },
+ { 19, "channel2" },
+ { 20, "channel3" },
+ { 21, "channel4" },
+ { 22, "txClear" },
+ { 23, "txRetries" },
+ { 24, "txRouting" },
+ { 25, "txScrambled" },
+ { 26, "rxParameter" },
+ { 27, "txTimeoutMs" },
+ { 28, "waitCardTimeout" },
+ { 29, "channelSet" },
+ { 30, "name" },
+ { 31, "waitTime" },
+ { 32, "lParameter" },
+ { 33, "_15" },
+ { 34, "headerSize" },
+ { 36, "tx_delay_ms" },
+ { 37, "retries" },
+ { 38, "ReTransmitPacketMaxSize" },
+ { 39, "waitReTransmitPacketMaxSize" },
+ { 40, "fastReTransCount" },
+ { 41, "driverRetransmissions" },
+ { 42, "txAckTimeoutMs" },
+ { 43, "registrationInterrupts" },
+ { 44, "hardwareType" },
+ { 45, "radioType" },
+ { 46, "writeEEPROM" },
+ { 47, "writeRadioType" },
+ { 48, "entry_exit_debug" },
+ { 49, "debug" },
+ { 50, "in_speed" },
+ { 51, "out_speed" },
+ { 52, "in_speed10" },
+ { 53, "out_speed10" },
+ { 54, "in_speed_max" },
+ { 55, "out_speed_max" },
+ { 56, "measure_rate" },
+ { 57, "pre_Command_Wait" },
+ { 58, "rx_tweak1" },
+ { 59, "rx_tweak2" },
+ { 60, "tx_queue_len" },
+
+ { 150, "arlan0-txRing" },
+ { 151, "arlan0-rxRing" },
+ { 152, "arlan0-18" },
+ { 153, "arlan0-ring" },
+ { 154, "arlan0-shm-cpy" },
+ { 155, "config0" },
+ { 156, "reset0" },
+ {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table1[] = {
+ { 1, "spreadingCode" },
+ { 2, "channelNumber" },
+ { 3, "scramblingDisable" },
+ { 4, "txAttenuation" },
+ { 5, "systemId" },
+ { 6, "maxDatagramSize" },
+ { 7, "maxFrameSize" },
+ { 8, "maxRetries" },
+ { 9, "receiveMode" },
+ { 10, "priority" },
+ { 11, "rootOrRepeater" },
+ { 12, "SID" },
+ { 13, "registrationMode" },
+ { 14, "registrationFill" },
+ { 15, "localTalkAddress" },
+ { 16, "codeFormat" },
+ { 17, "numChannels" },
+ { 18, "channel1" },
+ { 19, "channel2" },
+ { 20, "channel3" },
+ { 21, "channel4" },
+ { 22, "txClear" },
+ { 23, "txRetries" },
+ { 24, "txRouting" },
+ { 25, "txScrambled" },
+ { 26, "rxParameter" },
+ { 27, "txTimeoutMs" },
+ { 28, "waitCardTimeout" },
+ { 29, "channelSet" },
+ { 30, "name" },
+ { 31, "waitTime" },
+ { 32, "lParameter" },
+ { 33, "_15" },
+ { 34, "headerSize" },
+ { 36, "tx_delay_ms" },
+ { 37, "retries" },
+ { 38, "ReTransmitPacketMaxSize" },
+ { 39, "waitReTransmitPacketMaxSize" },
+ { 40, "fastReTransCount" },
+ { 41, "driverRetransmissions" },
+ { 42, "txAckTimeoutMs" },
+ { 43, "registrationInterrupts" },
+ { 44, "hardwareType" },
+ { 45, "radioType" },
+ { 46, "writeEEPROM" },
+ { 47, "writeRadioType" },
+ { 48, "entry_exit_debug" },
+ { 49, "debug" },
+ { 50, "in_speed" },
+ { 51, "out_speed" },
+ { 52, "in_speed10" },
+ { 53, "out_speed10" },
+ { 54, "in_speed_max" },
+ { 55, "out_speed_max" },
+ { 56, "measure_rate" },
+ { 57, "pre_Command_Wait" },
+ { 58, "rx_tweak1" },
+ { 59, "rx_tweak2" },
+ { 60, "tx_queue_len" },
+
+ { 150, "arlan1-txRing" },
+ { 151, "arlan1-rxRing" },
+ { 152, "arlan1-18" },
+ { 153, "arlan1-ring" },
+ { 154, "arlan1-shm-cpy" },
+ { 155, "config1" },
+ { 156, "reset1" },
+ {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table2[] = {
+ { 1, "spreadingCode" },
+ { 2, "channelNumber" },
+ { 3, "scramblingDisable" },
+ { 4, "txAttenuation" },
+ { 5, "systemId" },
+ { 6, "maxDatagramSize" },
+ { 7, "maxFrameSize" },
+ { 8, "maxRetries" },
+ { 9, "receiveMode" },
+ { 10, "priority" },
+ { 11, "rootOrRepeater" },
+ { 12, "SID" },
+ { 13, "registrationMode" },
+ { 14, "registrationFill" },
+ { 15, "localTalkAddress" },
+ { 16, "codeFormat" },
+ { 17, "numChannels" },
+ { 18, "channel1" },
+ { 19, "channel2" },
+ { 20, "channel3" },
+ { 21, "channel4" },
+ { 22, "txClear" },
+ { 23, "txRetries" },
+ { 24, "txRouting" },
+ { 25, "txScrambled" },
+ { 26, "rxParameter" },
+ { 27, "txTimeoutMs" },
+ { 28, "waitCardTimeout" },
+ { 29, "channelSet" },
+ { 30, "name" },
+ { 31, "waitTime" },
+ { 32, "lParameter" },
+ { 33, "_15" },
+ { 34, "headerSize" },
+ { 36, "tx_delay_ms" },
+ { 37, "retries" },
+ { 38, "ReTransmitPacketMaxSize" },
+ { 39, "waitReTransmitPacketMaxSize" },
+ { 40, "fastReTransCount" },
+ { 41, "driverRetransmissions" },
+ { 42, "txAckTimeoutMs" },
+ { 43, "registrationInterrupts" },
+ { 44, "hardwareType" },
+ { 45, "radioType" },
+ { 46, "writeEEPROM" },
+ { 47, "writeRadioType" },
+ { 48, "entry_exit_debug" },
+ { 49, "debug" },
+ { 50, "in_speed" },
+ { 51, "out_speed" },
+ { 52, "in_speed10" },
+ { 53, "out_speed10" },
+ { 54, "in_speed_max" },
+ { 55, "out_speed_max" },
+ { 56, "measure_rate" },
+ { 57, "pre_Command_Wait" },
+ { 58, "rx_tweak1" },
+ { 59, "rx_tweak2" },
+ { 60, "tx_queue_len" },
+
+ { 150, "arlan2-txRing" },
+ { 151, "arlan2-rxRing" },
+ { 152, "arlan2-18" },
+ { 153, "arlan2-ring" },
+ { 154, "arlan2-shm-cpy" },
+ { 155, "config2" },
+ { 156, "reset2" },
+ {}
+};
+
+static struct trans_ctl_table trans_arlan_conf_table3[] = {
+ { 1, "spreadingCode" },
+ { 2, "channelNumber" },
+ { 3, "scramblingDisable" },
+ { 4, "txAttenuation" },
+ { 5, "systemId" },
+ { 6, "maxDatagramSize" },
+ { 7, "maxFrameSize" },
+ { 8, "maxRetries" },
+ { 9, "receiveMode" },
+ { 10, "priority" },
+ { 11, "rootOrRepeater" },
+ { 12, "SID" },
+ { 13, "registrationMode" },
+ { 14, "registrationFill" },
+ { 15, "localTalkAddress" },
+ { 16, "codeFormat" },
+ { 17, "numChannels" },
+ { 18, "channel1" },
+ { 19, "channel2" },
+ { 20, "channel3" },
+ { 21, "channel4" },
+ { 22, "txClear" },
+ { 23, "txRetries" },
+ { 24, "txRouting" },
+ { 25, "txScrambled" },
+ { 26, "rxParameter" },
+ { 27, "txTimeoutMs" },
+ { 28, "waitCardTimeout" },
+ { 29, "channelSet" },
+ { 30, "name" },
+ { 31, "waitTime" },
+ { 32, "lParameter" },
+ { 33, "_15" },
+ { 34, "headerSize" },
+ { 36, "tx_delay_ms" },
+ { 37, "retries" },
+ { 38, "ReTransmitPacketMaxSize" },
+ { 39, "waitReTransmitPacketMaxSize" },
+ { 40, "fastReTransCount" },
+ { 41, "driverRetransmissions" },
+ { 42, "txAckTimeoutMs" },
+ { 43, "registrationInterrupts" },
+ { 44, "hardwareType" },
+ { 45, "radioType" },
+ { 46, "writeEEPROM" },
+ { 47, "writeRadioType" },
+ { 48, "entry_exit_debug" },
+ { 49, "debug" },
+ { 50, "in_speed" },
+ { 51, "out_speed" },
+ { 52, "in_speed10" },
+ { 53, "out_speed10" },
+ { 54, "in_speed_max" },
+ { 55, "out_speed_max" },
+ { 56, "measure_rate" },
+ { 57, "pre_Command_Wait" },
+ { 58, "rx_tweak1" },
+ { 59, "rx_tweak2" },
+ { 60, "tx_queue_len" },
+
+ { 150, "arlan3-txRing" },
+ { 151, "arlan3-rxRing" },
+ { 152, "arlan3-18" },
+ { 153, "arlan3-ring" },
+ { 154, "arlan3-shm-cpy" },
+ { 155, "config3" },
+ { 156, "reset3" },
+ {}
+};
+
+static struct trans_ctl_table trans_arlan_table[] = {
+ { 1, "arlan0", trans_arlan_conf_table0 },
+ { 2, "arlan1", trans_arlan_conf_table1 },
+ { 3, "arlan2", trans_arlan_conf_table2 },
+ { 4, "arlan3", trans_arlan_conf_table3 },
+ {}
+};
+
+static struct trans_ctl_table trans_appldata_table[] = {
+ { CTL_APPLDATA_TIMER, "timer" },
+ { CTL_APPLDATA_INTERVAL, "interval" },
+ { CTL_APPLDATA_OS, "os" },
+ { CTL_APPLDATA_NET_SUM, "net_sum" },
+ { CTL_APPLDATA_MEM, "mem" },
+ {}
+
+};
+
+static struct trans_ctl_table trans_s390dbf_table[] = {
+ { 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" },
+ { 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" },
+ {}
+};
+
+static struct trans_ctl_table trans_sunrpc_table[] = {
+ { CTL_RPCDEBUG, "rpc_debug" },
+ { CTL_NFSDEBUG, "nfs_debug" },
+ { CTL_NFSDDEBUG, "nfsd_debug" },
+ { CTL_NLMDEBUG, "nlm_debug" },
+ { CTL_SLOTTABLE_UDP, "udp_slot_table_entries" },
+ { CTL_SLOTTABLE_TCP, "tcp_slot_table_entries" },
+ { CTL_MIN_RESVPORT, "min_resvport" },
+ { CTL_MAX_RESVPORT, "max_resvport" },
+ {}
+};
+
+static struct trans_ctl_table trans_pm_table[] = {
+ { 1 /* CTL_PM_SUSPEND */, "suspend" },
+ { 2 /* CTL_PM_CMODE */, "cmode" },
+ { 3 /* CTL_PM_P0 */, "p0" },
+ { 4 /* CTL_PM_CM */, "cm" },
+ {}
+};
+
+static struct trans_ctl_table trans_frv_table[] = {
+ { 1, "cache-mode" },
+ { 2, "pin-cxnr" },
+ {}
+};
+
+static struct trans_ctl_table trans_root_table[] = {
+ { CTL_KERN, "kernel", trans_kern_table },
+ { CTL_VM, "vm", trans_vm_table },
+ { CTL_NET, "net", trans_net_table },
+ /* CTL_PROC not used */
+ { CTL_FS, "fs", trans_fs_table },
+ { CTL_DEBUG, "debug", trans_debug_table },
+ { CTL_DEV, "dev", trans_dev_table },
+ { CTL_BUS, "bus", trans_bus_table },
+ { CTL_ABI, "abi" },
+ /* CTL_CPU not used */
+ { CTL_ARLAN, "arlan", trans_arlan_table },
+ { CTL_APPLDATA, "appldata", trans_appldata_table },
+ { CTL_S390DBF, "s390dbf", trans_s390dbf_table },
+ { CTL_SUNRPC, "sunrpc", trans_sunrpc_table },
+ { CTL_PM, "pm", trans_pm_table },
+ { CTL_FRV, "frv", trans_frv_table },
+ {}
+};
+
+
+
+
+static int sysctl_depth(struct ctl_table *table)
+{
+ struct ctl_table *tmp;
+ int depth;
+
+ depth = 0;
+ for (tmp = table; tmp->parent; tmp = tmp->parent)
+ depth++;
+
+ return depth;
+}
+
+static struct ctl_table *sysctl_parent(struct ctl_table *table, int n)
+{
+ int i;
+
+ for (i = 0; table && i < n; i++)
+ table = table->parent;
+
+ return table;
+}
+
+static struct trans_ctl_table *sysctl_binary_lookup(struct ctl_table *table)
+{
+ struct ctl_table *test;
+ struct trans_ctl_table *ref;
+ int depth, cur_depth;
+
+ depth = sysctl_depth(table);
+
+ cur_depth = depth;
+ ref = trans_root_table;
+repeat:
+ test = sysctl_parent(table, cur_depth);
+ for (; ref->ctl_name || ref->procname || ref->child; ref++) {
+ int match = 0;
+
+ if (cur_depth && !ref->child)
+ continue;
+
+ if (test->procname && ref->procname &&
+ (strcmp(test->procname, ref->procname) == 0))
+ match++;
+
+ if (test->ctl_name && ref->ctl_name &&
+ (test->ctl_name == ref->ctl_name))
+ match++;
+
+ if (!ref->ctl_name && !ref->procname)
+ match++;
+
+ if (match) {
+ if (cur_depth != 0) {
+ cur_depth--;
+ ref = ref->child;
+ goto repeat;
+ }
+ goto out;
+ }
+ }
+ ref = NULL;
+out:
+ return ref;
+}
+
+static void sysctl_print_path(struct ctl_table *table)
+{
+ struct ctl_table *tmp;
+ int depth, i;
+ depth = sysctl_depth(table);
+ if (table->procname) {
+ for (i = depth; i >= 0; i--) {
+ tmp = sysctl_parent(table, i);
+ printk("/%s", tmp->procname?tmp->procname:"");
+ }
+ }
+ printk(" ");
+ if (table->ctl_name) {
+ for (i = depth; i >= 0; i--) {
+ tmp = sysctl_parent(table, i);
+ printk(".%d", tmp->ctl_name);
+ }
+ }
+}
+
+static void sysctl_repair_table(struct ctl_table *table)
+{
+ /* Don't complain about the classic default
+ * sysctl strategy routine. Maybe later we
+ * can get the tables fixed and complain about
+ * this.
+ */
+ if (table->ctl_name && table->procname &&
+ (table->proc_handler == proc_dointvec) &&
+ (!table->strategy)) {
+ table->strategy = sysctl_data;
+ }
+}
+
+static struct ctl_table *sysctl_check_lookup(struct ctl_table *table)
+{
+ struct ctl_table_header *head;
+ struct ctl_table *ref, *test;
+ int depth, cur_depth;
+
+ depth = sysctl_depth(table);
+
+ for (head = sysctl_head_next(NULL); head;
+ head = sysctl_head_next(head)) {
+ cur_depth = depth;
+ ref = head->ctl_table;
+repeat:
+ test = sysctl_parent(table, cur_depth);
+ for (; ref->ctl_name || ref->procname; ref++) {
+ int match = 0;
+ if (cur_depth && !ref->child)
+ continue;
+
+ if (test->procname && ref->procname &&
+ (strcmp(test->procname, ref->procname) == 0))
+ match++;
+
+ if (test->ctl_name && ref->ctl_name &&
+ (test->ctl_name == ref->ctl_name))
+ match++;
+
+ if (match) {
+ if (cur_depth != 0) {
+ cur_depth--;
+ ref = ref->child;
+ goto repeat;
+ }
+ goto out;
+ }
+ }
+ }
+ ref = NULL;
+out:
+ sysctl_head_finish(head);
+ return ref;
+}
+
+static void set_fail(const char **fail, struct ctl_table *table, const char *str)
+{
+ if (*fail) {
+ printk(KERN_ERR "sysctl table check failed: ");
+ sysctl_print_path(table);
+ printk(" %s\n", *fail);
+ }
+ *fail = str;
+}
+
+static int sysctl_check_dir(struct ctl_table *table)
+{
+ struct ctl_table *ref;
+ int error;
+
+ error = 0;
+ ref = sysctl_check_lookup(table);
+ if (ref) {
+ int match = 0;
+ if ((!table->procname && !ref->procname) ||
+ (table->procname && ref->procname &&
+ (strcmp(table->procname, ref->procname) == 0)))
+ match++;
+
+ if ((!table->ctl_name && !ref->ctl_name) ||
+ (table->ctl_name && ref->ctl_name &&
+ (table->ctl_name == ref->ctl_name)))
+ match++;
+
+ if (match != 2) {
+ printk(KERN_ERR "%s: failed: ", __func__);
+ sysctl_print_path(table);
+ printk(" ref: ");
+ sysctl_print_path(ref);
+ printk("\n");
+ error = -EINVAL;
+ }
+ }
+ return error;
+}
+
+static void sysctl_check_leaf(struct ctl_table *table, const char **fail)
+{
+ struct ctl_table *ref;
+
+ ref = sysctl_check_lookup(table);
+ if (ref && (ref != table))
+ set_fail(fail, table, "Sysctl already exists");
+}
+
+static void sysctl_check_bin_path(struct ctl_table *table, const char **fail)
+{
+ struct trans_ctl_table *ref;
+
+ ref = sysctl_binary_lookup(table);
+ if (table->ctl_name && !ref)
+ set_fail(fail, table, "Unknown sysctl binary path");
+ if (ref) {
+ if (ref->procname &&
+ (!table->procname ||
+ (strcmp(table->procname, ref->procname) != 0)))
+ set_fail(fail, table, "procname does not match binary path procname");
+
+ if (ref->ctl_name && table->ctl_name &&
+ (table->ctl_name != ref->ctl_name))
+ set_fail(fail, table, "ctl_name does not match binary path ctl_name");
+ }
+}
+
+int sysctl_check_table(struct ctl_table *table)
+{
+ int error = 0;
+ for (; table->ctl_name || table->procname; table++) {
+ const char *fail = NULL;
+
+ sysctl_repair_table(table);
+ if (table->parent) {
+ if (table->procname && !table->parent->procname)
+ set_fail(&fail, table, "Parent without procname");
+ if (table->ctl_name && !table->parent->ctl_name)
+ set_fail(&fail, table, "Parent without ctl_name");
+ }
+ if (!table->procname)
+ set_fail(&fail, table, "No procname");
+ if (table->child) {
+ if (table->data)
+ set_fail(&fail, table, "Directory with data?");
+ if (table->maxlen)
+ set_fail(&fail, table, "Directory with maxlen?");
+ if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode)
+ set_fail(&fail, table, "Writable sysctl directory");
+ if (table->proc_handler)
+ set_fail(&fail, table, "Directory with proc_handler");
+ if (table->strategy)
+ set_fail(&fail, table, "Directory with strategy");
+ if (table->extra1)
+ set_fail(&fail, table, "Directory with extra1");
+ if (table->extra2)
+ set_fail(&fail, table, "Directory with extra2");
+ if (sysctl_check_dir(table))
+ set_fail(&fail, table, "Inconsistent directory names");
+ } else {
+ if ((table->strategy == sysctl_data) ||
+ (table->strategy == sysctl_string) ||
+ (table->strategy == sysctl_intvec) ||
+ (table->strategy == sysctl_jiffies) ||
+ (table->strategy == sysctl_ms_jiffies) ||
+ (table->proc_handler == proc_dostring) ||
+ (table->proc_handler == proc_dointvec) ||
+#ifdef CONFIG_SECURITY_CAPABILITIES
+ (table->proc_handler == proc_dointvec_bset) ||
+#endif /* def CONFIG_SECURITY_CAPABILITIES */
+ (table->proc_handler == proc_dointvec_minmax) ||
+ (table->proc_handler == proc_dointvec_jiffies) ||
+ (table->proc_handler == proc_dointvec_userhz_jiffies) ||
+ (table->proc_handler == proc_dointvec_ms_jiffies) ||
+ (table->proc_handler == proc_doulongvec_minmax) ||
+ (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+ if (!table->data)
+ set_fail(&fail, table, "No data");
+ if (!table->maxlen)
+ set_fail(&fail, table, "No maxlen");
+ }
+ if ((table->proc_handler == proc_doulongvec_minmax) ||
+ (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+ if (table->maxlen > sizeof (unsigned long)) {
+ if (!table->extra1)
+ set_fail(&fail, table, "No min");
+ if (!table->extra2)
+ set_fail(&fail, table, "No max");
+ }
+ }
+#ifdef CONFIG_SYSCTL_SYSCALL
+ if (table->ctl_name && !table->strategy)
+ set_fail(&fail, table, "Missing strategy");
+#endif
+#if 0
+ if (!table->ctl_name && table->strategy)
+ set_fail(&fail, table, "Strategy without ctl_name");
+#endif
+#ifdef CONFIG_PROC_FS
+ if (table->procname && !table->proc_handler)
+ set_fail(&fail, table, "No proc_handler");
+#endif
+#if 0
+ if (!table->procname && table->proc_handler)
+ set_fail(&fail, table, "proc_handler without procname");
+#endif
+ sysctl_check_leaf(table, &fail);
+ }
+ sysctl_check_bin_path(table, &fail);
+ if (fail) {
+ set_fail(&fail, table, NULL);
+ error = -EINVAL;
+ }
+ if (table->child)
+ error |= sysctl_check_table(table->child);
+ }
+ return error;
+}
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 059431ed67d..7d4d7f9c1bb 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -20,7 +20,6 @@
#include <linux/taskstats_kern.h>
#include <linux/tsacct_kern.h>
#include <linux/delayacct.h>
-#include <linux/tsacct_kern.h>
#include <linux/cpumask.h>
#include <linux/percpu.h>
#include <net/genetlink.h>
diff --git a/kernel/time.c b/kernel/time.c
index 2289a8d6831..09d3c45c4da 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -9,9 +9,9 @@
*/
/*
* Modification history kernel/time.c
- *
+ *
* 1993-09-02 Philip Gladstone
- * Created file with time related functions from sched.c and adjtimex()
+ * Created file with time related functions from sched.c and adjtimex()
* 1993-10-08 Torsten Duwe
* adjtime interface update and CMOS clock write code
* 1995-08-13 Torsten Duwe
@@ -30,16 +30,16 @@
#include <linux/module.h>
#include <linux/timex.h>
#include <linux/capability.h>
+#include <linux/clocksource.h>
#include <linux/errno.h>
#include <linux/syscalls.h>
#include <linux/security.h>
#include <linux/fs.h>
-#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
-/*
+/*
* The timezone where the local system is located. Used as a default by some
* programs who obtain this value by using gettimeofday.
*/
@@ -57,11 +57,7 @@ EXPORT_SYMBOL(sys_tz);
*/
asmlinkage long sys_time(time_t __user * tloc)
{
- time_t i;
- struct timespec tv;
-
- getnstimeofday(&tv);
- i = tv.tv_sec;
+ time_t i = get_seconds();
if (tloc) {
if (put_user(i,tloc))
@@ -76,7 +72,7 @@ asmlinkage long sys_time(time_t __user * tloc)
* why not move it into the appropriate arch directory (for those
* architectures that need it).
*/
-
+
asmlinkage long sys_stime(time_t __user *tptr)
{
struct timespec tv;
@@ -115,10 +111,10 @@ asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __us
/*
* Adjust the time obtained from the CMOS to be UTC time instead of
* local time.
- *
+ *
* This is ugly, but preferable to the alternatives. Otherwise we
* would either need to write a program to do it in /etc/rc (and risk
- * confusion if the program gets run more than once; it would also be
+ * confusion if the program gets run more than once; it would also be
* hard to make the program warp the clock precisely n hours) or
* compile in the timezone information into the kernel. Bad, bad....
*
@@ -163,6 +159,7 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
if (tz) {
/* SMP safe, global irq locking makes it work. */
sys_tz = *tz;
+ update_vsyscall_tz();
if (firsttime) {
firsttime = 0;
if (!tv)
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index fc3fc79b3d5..8cfb8b2ce77 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -222,20 +222,8 @@ static void tick_do_broadcast_on_off(void *why)
if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
goto out;
- /*
- * Defect device ?
- */
- if (!tick_device_is_functional(dev)) {
- /*
- * AMD C1E wreckage fixup:
- *
- * Device was registered functional in the first
- * place. Now the secondary CPU detected the C1E
- * misfeature and notifies us to fix it up
- */
- if (*reason != CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
- goto out;
- }
+ if (!tick_device_is_functional(dev))
+ goto out;
switch (*reason) {
case CLOCK_EVT_NOTIFY_BROADCAST_ON:
@@ -246,6 +234,8 @@ static void tick_do_broadcast_on_off(void *why)
clockevents_set_mode(dev,
CLOCK_EVT_MODE_SHUTDOWN);
}
+ if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
+ dev->features |= CLOCK_EVT_FEAT_DUMMY;
break;
case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
if (cpu_isset(cpu, tick_broadcast_mask)) {
@@ -274,21 +264,12 @@ out:
*/
void tick_broadcast_on_off(unsigned long reason, int *oncpu)
{
- int cpu = get_cpu();
-
- if (!cpu_isset(*oncpu, cpu_online_map)) {
+ if (!cpu_isset(*oncpu, cpu_online_map))
printk(KERN_ERR "tick-braodcast: ignoring broadcast for "
"offline CPU #%d\n", *oncpu);
- } else {
-
- if (cpu == *oncpu)
- tick_do_broadcast_on_off(&reason);
- else
- smp_call_function_single(*oncpu,
- tick_do_broadcast_on_off,
- &reason, 1, 1);
- }
- put_cpu();
+ else
+ smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
+ &reason, 1, 1);
}
/*
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 8c3fef1db09..ce89ffb474d 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -570,7 +570,7 @@ void tick_setup_sched_timer(void)
/* Get the next period (per cpu) */
ts->sched_timer.expires = tick_init_jiffy_update();
offset = ktime_to_ns(tick_period) >> 1;
- do_div(offset, NR_CPUS);
+ do_div(offset, num_possible_cpus());
offset *= smp_processor_id();
ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 4ad79f6bdec..e5e466b2759 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -24,9 +24,7 @@
* This read-write spinlock protects us from races in SMP while
* playing with xtime and avenrun.
*/
-__attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
-
-EXPORT_SYMBOL(xtime_lock);
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
/*
@@ -47,21 +45,13 @@ EXPORT_SYMBOL(xtime_lock);
struct timespec xtime __attribute__ ((aligned (16)));
struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
static unsigned long total_sleep_time; /* seconds */
-EXPORT_SYMBOL(xtime);
-
-#ifdef CONFIG_NO_HZ
static struct timespec xtime_cache __attribute__ ((aligned (16)));
static inline void update_xtime_cache(u64 nsec)
{
xtime_cache = xtime;
timespec_add_ns(&xtime_cache, nsec);
}
-#else
-#define xtime_cache xtime
-/* We do *not* want to evaluate the argument for this case */
-#define update_xtime_cache(n) do { } while (0)
-#endif
static struct clocksource *clock; /* pointer to current clocksource */
diff --git a/kernel/timer.c b/kernel/timer.c
index 6ce1952eea7..8521d10fbb2 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -817,7 +817,7 @@ unsigned long next_timer_interrupt(void)
#endif
/*
- * Called from the timer interrupt handler to charge one tick to the current
+ * Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
*/
void update_process_times(int user_tick)
@@ -826,10 +826,13 @@ void update_process_times(int user_tick)
int cpu = smp_processor_id();
/* Note: this timer irq context must be accounted for as well. */
- if (user_tick)
+ if (user_tick) {
account_user_time(p, jiffies_to_cputime(1));
- else
+ account_user_time_scaled(p, jiffies_to_cputime(1));
+ } else {
account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1));
+ account_system_time_scaled(p, jiffies_to_cputime(1));
+ }
run_local_timers();
if (rcu_pending(cpu))
rcu_check_callbacks(cpu, user_tick);
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index c122131a122..4ab1b584961 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -62,6 +62,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
rcu_read_unlock();
stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
+ stats->ac_utimescaled =
+ cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC;
+ stats->ac_stimescaled =
+ cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC;
stats->ac_minflt = tsk->min_flt;
stats->ac_majflt = tsk->maj_flt;
diff --git a/kernel/user.c b/kernel/user.c
index f0e561e6d08..e91331c457e 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -44,7 +44,6 @@ struct user_struct root_user = {
.processes = ATOMIC_INIT(1),
.files = ATOMIC_INIT(0),
.sigpending = ATOMIC_INIT(0),
- .mq_bytes = 0,
.locked_shm = 0,
#ifdef CONFIG_KEYS
.uid_keyring = &root_user_keyring,
@@ -58,19 +57,17 @@ struct user_struct root_user = {
/*
* These routines must be called with the uidhash spinlock held!
*/
-static inline void uid_hash_insert(struct user_struct *up,
- struct hlist_head *hashent)
+static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent)
{
hlist_add_head(&up->uidhash_node, hashent);
}
-static inline void uid_hash_remove(struct user_struct *up)
+static void uid_hash_remove(struct user_struct *up)
{
hlist_del_init(&up->uidhash_node);
}
-static inline struct user_struct *uid_hash_find(uid_t uid,
- struct hlist_head *hashent)
+static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent)
{
struct user_struct *user;
struct hlist_node *h;
@@ -87,9 +84,6 @@ static inline struct user_struct *uid_hash_find(uid_t uid,
#ifdef CONFIG_FAIR_USER_SCHED
-static struct kobject uids_kobject; /* represents /sys/kernel/uids directory */
-static DEFINE_MUTEX(uids_mutex);
-
static void sched_destroy_user(struct user_struct *up)
{
sched_destroy_group(up->tg);
@@ -111,6 +105,19 @@ static void sched_switch_user(struct task_struct *p)
sched_move_task(p);
}
+#else /* CONFIG_FAIR_USER_SCHED */
+
+static void sched_destroy_user(struct user_struct *up) { }
+static int sched_create_user(struct user_struct *up) { return 0; }
+static void sched_switch_user(struct task_struct *p) { }
+
+#endif /* CONFIG_FAIR_USER_SCHED */
+
+#if defined(CONFIG_FAIR_USER_SCHED) && defined(CONFIG_SYSFS)
+
+static struct kobject uids_kobject; /* represents /sys/kernel/uids directory */
+static DEFINE_MUTEX(uids_mutex);
+
static inline void uids_mutex_lock(void)
{
mutex_lock(&uids_mutex);
@@ -257,11 +264,8 @@ static inline void free_user(struct user_struct *up, unsigned long flags)
schedule_work(&up->work);
}
-#else /* CONFIG_FAIR_USER_SCHED */
+#else /* CONFIG_FAIR_USER_SCHED && CONFIG_SYSFS */
-static void sched_destroy_user(struct user_struct *up) { }
-static int sched_create_user(struct user_struct *up) { return 0; }
-static void sched_switch_user(struct task_struct *p) { }
static inline int user_kobject_create(struct user_struct *up) { return 0; }
static inline void uids_mutex_lock(void) { }
static inline void uids_mutex_unlock(void) { }
@@ -280,7 +284,7 @@ static inline void free_user(struct user_struct *up, unsigned long flags)
kmem_cache_free(uid_cachep, up);
}
-#endif /* CONFIG_FAIR_USER_SCHED */
+#endif
/*
* Locate the user_struct for the passed UID. If found, take a ref on it. The
@@ -343,8 +347,9 @@ struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid)
atomic_set(&new->inotify_watches, 0);
atomic_set(&new->inotify_devs, 0);
#endif
-
+#ifdef CONFIG_POSIX_MQUEUE
new->mq_bytes = 0;
+#endif
new->locked_shm = 0;
if (alloc_uid_keyring(new, current) < 0) {
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 396c38b3cb6..7d16e643330 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -413,6 +413,24 @@ config FORCED_INLINING
become the default in the future, until then this option is there to
test gcc for this.
+config BOOT_PRINTK_DELAY
+ bool "Delay each boot printk message by N milliseconds"
+ depends on DEBUG_KERNEL && PRINTK && GENERIC_CALIBRATE_DELAY
+ help
+ This build option allows you to read kernel boot messages
+ by inserting a short delay after each one. The delay is
+ specified in milliseconds on the kernel command line,
+ using "boot_delay=N".
+
+ It is likely that you would also need to use "lpj=M" to preset
+ the "loops per jiffie" value.
+ See a previous boot log for the "lpj" value to use for your
+ system, and then set "lpj=M" before setting "boot_delay=N".
+ NOTE: Using this option may adversely affect SMP systems.
+ I.e., processors other than the first one may not boot up.
+ BOOT_PRINTK_DELAY also may cause DETECT_SOFTLOCKUP to detect
+ what it believes to be lockup conditions.
+
config RCU_TORTURE_TEST
tristate "torture tests for RCU"
depends on DEBUG_KERNEL
diff --git a/lib/Makefile b/lib/Makefile
index 6c4ea33bb2c..c5f215d509d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -5,7 +5,8 @@
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
+ sha1.o irq_regs.o reciprocal_div.o argv_split.o \
+ proportions.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
diff --git a/lib/argv_split.c b/lib/argv_split.c
index 4096ed42f49..fad6ce4f7b5 100644
--- a/lib/argv_split.c
+++ b/lib/argv_split.c
@@ -75,7 +75,9 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp)
if (argv == NULL)
goto out;
- *argcp = argc;
+ if (argcp)
+ *argcp = argc;
+
argvp = argv;
while (*str) {
diff --git a/lib/bust_spinlocks.c b/lib/bust_spinlocks.c
index accb3565816..486da62b2b0 100644
--- a/lib/bust_spinlocks.c
+++ b/lib/bust_spinlocks.c
@@ -17,13 +17,13 @@
void __attribute__((weak)) bust_spinlocks(int yes)
{
if (yes) {
- oops_in_progress = 1;
+ ++oops_in_progress;
} else {
#ifdef CONFIG_VT
unblank_screen();
#endif
- oops_in_progress = 0;
- wake_up_klogd();
+ if (--oops_in_progress == 0)
+ wake_up_klogd();
}
}
diff --git a/lib/crc32.c b/lib/crc32.c
index bfc33314c72..d2c2f257bed 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -49,7 +49,7 @@ MODULE_LICENSE("GPL");
* @p: pointer to buffer over which CRC is run
* @len: length of buffer @p
*/
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
#if CRC_LE_BITS == 1
/*
@@ -57,7 +57,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len);
* simplified by inlining the table in ?: form.
*/
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
{
int i;
while (len--) {
@@ -69,7 +69,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
}
#else /* Table-based approach */
-u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
{
# if CRC_LE_BITS == 8
const u32 *b =(u32 *)p;
@@ -145,7 +145,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len)
* @p: pointer to buffer over which CRC is run
* @len: length of buffer @p
*/
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len);
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
#if CRC_BE_BITS == 1
/*
@@ -153,7 +153,7 @@ u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len);
* simplified by inlining the table in ?: form.
*/
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
{
int i;
while (len--) {
@@ -167,7 +167,7 @@ u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
}
#else /* Table-based approach */
-u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
{
# if CRC_BE_BITS == 8
const u32 *b =(u32 *)p;
diff --git a/lib/idr.c b/lib/idr.c
index 09cbe2b69ed..afbb0b1023d 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -580,8 +580,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
}
EXPORT_SYMBOL(idr_replace);
-static void idr_cache_ctor(void * idr_layer, struct kmem_cache *idr_layer_cache,
- unsigned long flags)
+static void idr_cache_ctor(struct kmem_cache *idr_layer_cache, void *idr_layer)
{
memset(idr_layer, 0, sizeof(struct idr_layer));
}
diff --git a/lib/iomap.c b/lib/iomap.c
index 864f2ec1966..72c42687ba1 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -40,7 +40,7 @@ static void bad_io_access(unsigned long port, const char *access)
static int count = 10;
if (count) {
count--;
- printk(KERN_ERR "Bad IO access at port %lx (%s)\n", port, access);
+ printk(KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access);
WARN_ON(1);
}
}
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 760521417b6..14c6078f17a 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -8,6 +8,7 @@
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/io.h>
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c
index 60f46803af3..802f11f0bf5 100644
--- a/lib/libcrc32c.c
+++ b/lib/libcrc32c.c
@@ -66,7 +66,7 @@ EXPORT_SYMBOL(crc32c_le);
* loop below with crc32 and vary the POLY if we don't find value in terms
* of space and maintainability in keeping the two modules separate.
*/
-u32 __attribute_pure__
+u32 __pure
crc32c_le(u32 crc, unsigned char const *p, size_t len)
{
int i;
@@ -160,7 +160,7 @@ static const u32 crc32c_table[256] = {
* crc using table.
*/
-u32 __attribute_pure__
+u32 __pure
crc32c_le(u32 seed, unsigned char const *data, size_t length)
{
u32 crc = __cpu_to_le32(seed);
@@ -177,7 +177,7 @@ crc32c_le(u32 seed, unsigned char const *data, size_t length)
EXPORT_SYMBOL(crc32c_be);
#if CRC_BE_BITS == 1
-u32 __attribute_pure__
+u32 __pure
crc32c_be(u32 crc, unsigned char const *p, size_t len)
{
int i;
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c
index cf22c617baa..9659eabffc3 100644
--- a/lib/percpu_counter.c
+++ b/lib/percpu_counter.c
@@ -14,15 +14,29 @@ static LIST_HEAD(percpu_counters);
static DEFINE_MUTEX(percpu_counters_lock);
#endif
-void percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
+void percpu_counter_set(struct percpu_counter *fbc, s64 amount)
{
- long count;
+ int cpu;
+
+ spin_lock(&fbc->lock);
+ for_each_possible_cpu(cpu) {
+ s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
+ *pcount = 0;
+ }
+ fbc->count = amount;
+ spin_unlock(&fbc->lock);
+}
+EXPORT_SYMBOL(percpu_counter_set);
+
+void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch)
+{
+ s64 count;
s32 *pcount;
int cpu = get_cpu();
pcount = per_cpu_ptr(fbc->counters, cpu);
count = *pcount + amount;
- if (count >= FBC_BATCH || count <= -FBC_BATCH) {
+ if (count >= batch || count <= -batch) {
spin_lock(&fbc->lock);
fbc->count += count;
*pcount = 0;
@@ -32,13 +46,13 @@ void percpu_counter_mod(struct percpu_counter *fbc, s32 amount)
}
put_cpu();
}
-EXPORT_SYMBOL(percpu_counter_mod);
+EXPORT_SYMBOL(__percpu_counter_add);
/*
* Add up all the per-cpu counts, return the result. This is a more accurate
* but much slower version of percpu_counter_read_positive()
*/
-s64 percpu_counter_sum(struct percpu_counter *fbc)
+s64 __percpu_counter_sum(struct percpu_counter *fbc)
{
s64 ret;
int cpu;
@@ -50,25 +64,43 @@ s64 percpu_counter_sum(struct percpu_counter *fbc)
ret += *pcount;
}
spin_unlock(&fbc->lock);
- return ret < 0 ? 0 : ret;
+ return ret;
}
-EXPORT_SYMBOL(percpu_counter_sum);
+EXPORT_SYMBOL(__percpu_counter_sum);
+
+static struct lock_class_key percpu_counter_irqsafe;
-void percpu_counter_init(struct percpu_counter *fbc, s64 amount)
+int percpu_counter_init(struct percpu_counter *fbc, s64 amount)
{
spin_lock_init(&fbc->lock);
fbc->count = amount;
fbc->counters = alloc_percpu(s32);
+ if (!fbc->counters)
+ return -ENOMEM;
#ifdef CONFIG_HOTPLUG_CPU
mutex_lock(&percpu_counters_lock);
list_add(&fbc->list, &percpu_counters);
mutex_unlock(&percpu_counters_lock);
#endif
+ return 0;
}
EXPORT_SYMBOL(percpu_counter_init);
+int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount)
+{
+ int err;
+
+ err = percpu_counter_init(fbc, amount);
+ if (!err)
+ lockdep_set_class(&fbc->lock, &percpu_counter_irqsafe);
+ return err;
+}
+
void percpu_counter_destroy(struct percpu_counter *fbc)
{
+ if (!fbc->counters)
+ return;
+
free_percpu(fbc->counters);
#ifdef CONFIG_HOTPLUG_CPU
mutex_lock(&percpu_counters_lock);
diff --git a/lib/proportions.c b/lib/proportions.c
new file mode 100644
index 00000000000..332d8c58184
--- /dev/null
+++ b/lib/proportions.c
@@ -0,0 +1,384 @@
+/*
+ * Floating proportions
+ *
+ * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ * Description:
+ *
+ * The floating proportion is a time derivative with an exponentially decaying
+ * history:
+ *
+ * p_{j} = \Sum_{i=0} (dx_{j}/dt_{-i}) / 2^(1+i)
+ *
+ * Where j is an element from {prop_local}, x_{j} is j's number of events,
+ * and i the time period over which the differential is taken. So d/dt_{-i} is
+ * the differential over the i-th last period.
+ *
+ * The decaying history gives smooth transitions. The time differential carries
+ * the notion of speed.
+ *
+ * The denominator is 2^(1+i) because we want the series to be normalised, ie.
+ *
+ * \Sum_{i=0} 1/2^(1+i) = 1
+ *
+ * Further more, if we measure time (t) in the same events as x; so that:
+ *
+ * t = \Sum_{j} x_{j}
+ *
+ * we get that:
+ *
+ * \Sum_{j} p_{j} = 1
+ *
+ * Writing this in an iterative fashion we get (dropping the 'd's):
+ *
+ * if (++x_{j}, ++t > period)
+ * t /= 2;
+ * for_each (j)
+ * x_{j} /= 2;
+ *
+ * so that:
+ *
+ * p_{j} = x_{j} / t;
+ *
+ * We optimize away the '/= 2' for the global time delta by noting that:
+ *
+ * if (++t > period) t /= 2:
+ *
+ * Can be approximated by:
+ *
+ * period/2 + (++t % period/2)
+ *
+ * [ Furthermore, when we choose period to be 2^n it can be written in terms of
+ * binary operations and wraparound artefacts disappear. ]
+ *
+ * Also note that this yields a natural counter of the elapsed periods:
+ *
+ * c = t / (period/2)
+ *
+ * [ Its monotonic increasing property can be applied to mitigate the wrap-
+ * around issue. ]
+ *
+ * This allows us to do away with the loop over all prop_locals on each period
+ * expiration. By remembering the period count under which it was last accessed
+ * as c_{j}, we can obtain the number of 'missed' cycles from:
+ *
+ * c - c_{j}
+ *
+ * We can then lazily catch up to the global period count every time we are
+ * going to use x_{j}, by doing:
+ *
+ * x_{j} /= 2^(c - c_{j}), c_{j} = c
+ */
+
+#include <linux/proportions.h>
+#include <linux/rcupdate.h>
+
+/*
+ * Limit the time part in order to ensure there are some bits left for the
+ * cycle counter.
+ */
+#define PROP_MAX_SHIFT (3*BITS_PER_LONG/4)
+
+int prop_descriptor_init(struct prop_descriptor *pd, int shift)
+{
+ int err;
+
+ if (shift > PROP_MAX_SHIFT)
+ shift = PROP_MAX_SHIFT;
+
+ pd->index = 0;
+ pd->pg[0].shift = shift;
+ mutex_init(&pd->mutex);
+ err = percpu_counter_init_irq(&pd->pg[0].events, 0);
+ if (err)
+ goto out;
+
+ err = percpu_counter_init_irq(&pd->pg[1].events, 0);
+ if (err)
+ percpu_counter_destroy(&pd->pg[0].events);
+
+out:
+ return err;
+}
+
+/*
+ * We have two copies, and flip between them to make it seem like an atomic
+ * update. The update is not really atomic wrt the events counter, but
+ * it is internally consistent with the bit layout depending on shift.
+ *
+ * We copy the events count, move the bits around and flip the index.
+ */
+void prop_change_shift(struct prop_descriptor *pd, int shift)
+{
+ int index;
+ int offset;
+ u64 events;
+ unsigned long flags;
+
+ if (shift > PROP_MAX_SHIFT)
+ shift = PROP_MAX_SHIFT;
+
+ mutex_lock(&pd->mutex);
+
+ index = pd->index ^ 1;
+ offset = pd->pg[pd->index].shift - shift;
+ if (!offset)
+ goto out;
+
+ pd->pg[index].shift = shift;
+
+ local_irq_save(flags);
+ events = percpu_counter_sum(&pd->pg[pd->index].events);
+ if (offset < 0)
+ events <<= -offset;
+ else
+ events >>= offset;
+ percpu_counter_set(&pd->pg[index].events, events);
+
+ /*
+ * ensure the new pg is fully written before the switch
+ */
+ smp_wmb();
+ pd->index = index;
+ local_irq_restore(flags);
+
+ synchronize_rcu();
+
+out:
+ mutex_unlock(&pd->mutex);
+}
+
+/*
+ * wrap the access to the data in an rcu_read_lock() section;
+ * this is used to track the active references.
+ */
+static struct prop_global *prop_get_global(struct prop_descriptor *pd)
+{
+ int index;
+
+ rcu_read_lock();
+ index = pd->index;
+ /*
+ * match the wmb from vcd_flip()
+ */
+ smp_rmb();
+ return &pd->pg[index];
+}
+
+static void prop_put_global(struct prop_descriptor *pd, struct prop_global *pg)
+{
+ rcu_read_unlock();
+}
+
+static void
+prop_adjust_shift(int *pl_shift, unsigned long *pl_period, int new_shift)
+{
+ int offset = *pl_shift - new_shift;
+
+ if (!offset)
+ return;
+
+ if (offset < 0)
+ *pl_period <<= -offset;
+ else
+ *pl_period >>= offset;
+
+ *pl_shift = new_shift;
+}
+
+/*
+ * PERCPU
+ */
+
+int prop_local_init_percpu(struct prop_local_percpu *pl)
+{
+ spin_lock_init(&pl->lock);
+ pl->shift = 0;
+ pl->period = 0;
+ return percpu_counter_init_irq(&pl->events, 0);
+}
+
+void prop_local_destroy_percpu(struct prop_local_percpu *pl)
+{
+ percpu_counter_destroy(&pl->events);
+}
+
+/*
+ * Catch up with missed period expirations.
+ *
+ * until (c_{j} == c)
+ * x_{j} -= x_{j}/2;
+ * c_{j}++;
+ */
+static
+void prop_norm_percpu(struct prop_global *pg, struct prop_local_percpu *pl)
+{
+ unsigned long period = 1UL << (pg->shift - 1);
+ unsigned long period_mask = ~(period - 1);
+ unsigned long global_period;
+ unsigned long flags;
+
+ global_period = percpu_counter_read(&pg->events);
+ global_period &= period_mask;
+
+ /*
+ * Fast path - check if the local and global period count still match
+ * outside of the lock.
+ */
+ if (pl->period == global_period)
+ return;
+
+ spin_lock_irqsave(&pl->lock, flags);
+ prop_adjust_shift(&pl->shift, &pl->period, pg->shift);
+ /*
+ * For each missed period, we half the local counter.
+ * basically:
+ * pl->events >> (global_period - pl->period);
+ *
+ * but since the distributed nature of percpu counters make division
+ * rather hard, use a regular subtraction loop. This is safe, because
+ * the events will only every be incremented, hence the subtraction
+ * can never result in a negative number.
+ */
+ while (pl->period != global_period) {
+ unsigned long val = percpu_counter_read(&pl->events);
+ unsigned long half = (val + 1) >> 1;
+
+ /*
+ * Half of zero won't be much less, break out.
+ * This limits the loop to shift iterations, even
+ * if we missed a million.
+ */
+ if (!val)
+ break;
+
+ percpu_counter_add(&pl->events, -half);
+ pl->period += period;
+ }
+ pl->period = global_period;
+ spin_unlock_irqrestore(&pl->lock, flags);
+}
+
+/*
+ * ++x_{j}, ++t
+ */
+void __prop_inc_percpu(struct prop_descriptor *pd, struct prop_local_percpu *pl)
+{
+ struct prop_global *pg = prop_get_global(pd);
+
+ prop_norm_percpu(pg, pl);
+ percpu_counter_add(&pl->events, 1);
+ percpu_counter_add(&pg->events, 1);
+ prop_put_global(pd, pg);
+}
+
+/*
+ * Obtain a fraction of this proportion
+ *
+ * p_{j} = x_{j} / (period/2 + t % period/2)
+ */
+void prop_fraction_percpu(struct prop_descriptor *pd,
+ struct prop_local_percpu *pl,
+ long *numerator, long *denominator)
+{
+ struct prop_global *pg = prop_get_global(pd);
+ unsigned long period_2 = 1UL << (pg->shift - 1);
+ unsigned long counter_mask = period_2 - 1;
+ unsigned long global_count;
+
+ prop_norm_percpu(pg, pl);
+ *numerator = percpu_counter_read_positive(&pl->events);
+
+ global_count = percpu_counter_read(&pg->events);
+ *denominator = period_2 + (global_count & counter_mask);
+
+ prop_put_global(pd, pg);
+}
+
+/*
+ * SINGLE
+ */
+
+int prop_local_init_single(struct prop_local_single *pl)
+{
+ spin_lock_init(&pl->lock);
+ pl->shift = 0;
+ pl->period = 0;
+ pl->events = 0;
+ return 0;
+}
+
+void prop_local_destroy_single(struct prop_local_single *pl)
+{
+}
+
+/*
+ * Catch up with missed period expirations.
+ */
+static
+void prop_norm_single(struct prop_global *pg, struct prop_local_single *pl)
+{
+ unsigned long period = 1UL << (pg->shift - 1);
+ unsigned long period_mask = ~(period - 1);
+ unsigned long global_period;
+ unsigned long flags;
+
+ global_period = percpu_counter_read(&pg->events);
+ global_period &= period_mask;
+
+ /*
+ * Fast path - check if the local and global period count still match
+ * outside of the lock.
+ */
+ if (pl->period == global_period)
+ return;
+
+ spin_lock_irqsave(&pl->lock, flags);
+ prop_adjust_shift(&pl->shift, &pl->period, pg->shift);
+ /*
+ * For each missed period, we half the local counter.
+ */
+ period = (global_period - pl->period) >> (pg->shift - 1);
+ if (likely(period < BITS_PER_LONG))
+ pl->events >>= period;
+ else
+ pl->events = 0;
+ pl->period = global_period;
+ spin_unlock_irqrestore(&pl->lock, flags);
+}
+
+/*
+ * ++x_{j}, ++t
+ */
+void __prop_inc_single(struct prop_descriptor *pd, struct prop_local_single *pl)
+{
+ struct prop_global *pg = prop_get_global(pd);
+
+ prop_norm_single(pg, pl);
+ pl->events++;
+ percpu_counter_add(&pg->events, 1);
+ prop_put_global(pd, pg);
+}
+
+/*
+ * Obtain a fraction of this proportion
+ *
+ * p_{j} = x_{j} / (period/2 + t % period/2)
+ */
+void prop_fraction_single(struct prop_descriptor *pd,
+ struct prop_local_single *pl,
+ long *numerator, long *denominator)
+{
+ struct prop_global *pg = prop_get_global(pd);
+ unsigned long period_2 = 1UL << (pg->shift - 1);
+ unsigned long counter_mask = period_2 - 1;
+ unsigned long global_count;
+
+ prop_norm_single(pg, pl);
+ *numerator = pl->events;
+
+ global_count = percpu_counter_read(&pg->events);
+ *denominator = period_2 + (global_count & counter_mask);
+
+ prop_put_global(pd, pg);
+}
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 514efb200be..48c250fe223 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -60,9 +60,14 @@ struct radix_tree_path {
};
#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
-#define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2)
+#define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \
+ RADIX_TREE_MAP_SHIFT))
-static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH] __read_mostly;
+/*
+ * The height_to_maxindex array needs to be one deeper than the maximum
+ * path as height 0 holds only 1 entry.
+ */
+static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly;
/*
* Radix tree node cache.
@@ -93,7 +98,8 @@ radix_tree_node_alloc(struct radix_tree_root *root)
struct radix_tree_node *ret;
gfp_t gfp_mask = root_gfp_mask(root);
- ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
+ ret = kmem_cache_alloc(radix_tree_node_cachep,
+ set_migrateflags(gfp_mask, __GFP_RECLAIMABLE));
if (ret == NULL && !(gfp_mask & __GFP_WAIT)) {
struct radix_tree_preload *rtp;
@@ -104,7 +110,7 @@ radix_tree_node_alloc(struct radix_tree_root *root)
rtp->nr--;
}
}
- BUG_ON(radix_tree_is_direct_ptr(ret));
+ BUG_ON(radix_tree_is_indirect_ptr(ret));
return ret;
}
@@ -137,7 +143,8 @@ int radix_tree_preload(gfp_t gfp_mask)
rtp = &__get_cpu_var(radix_tree_preloads);
while (rtp->nr < ARRAY_SIZE(rtp->nodes)) {
preempt_enable();
- node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
+ node = kmem_cache_alloc(radix_tree_node_cachep,
+ set_migrateflags(gfp_mask, __GFP_RECLAIMABLE));
if (node == NULL)
goto out;
preempt_disable();
@@ -240,7 +247,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
return -ENOMEM;
/* Increase the height. */
- node->slots[0] = radix_tree_direct_to_ptr(root->rnode);
+ node->slots[0] = radix_tree_indirect_to_ptr(root->rnode);
/* Propagate the aggregated tag info into the new root */
for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
@@ -251,6 +258,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
newheight = root->height+1;
node->height = newheight;
node->count = 1;
+ node = radix_tree_ptr_to_indirect(node);
rcu_assign_pointer(root->rnode, node);
root->height = newheight;
} while (height > root->height);
@@ -274,7 +282,7 @@ int radix_tree_insert(struct radix_tree_root *root,
int offset;
int error;
- BUG_ON(radix_tree_is_direct_ptr(item));
+ BUG_ON(radix_tree_is_indirect_ptr(item));
/* Make sure the tree is high enough. */
if (index > radix_tree_maxindex(root->height)) {
@@ -283,7 +291,8 @@ int radix_tree_insert(struct radix_tree_root *root,
return error;
}
- slot = root->rnode;
+ slot = radix_tree_indirect_to_ptr(root->rnode);
+
height = root->height;
shift = (height-1) * RADIX_TREE_MAP_SHIFT;
@@ -298,7 +307,8 @@ int radix_tree_insert(struct radix_tree_root *root,
rcu_assign_pointer(node->slots[offset], slot);
node->count++;
} else
- rcu_assign_pointer(root->rnode, slot);
+ rcu_assign_pointer(root->rnode,
+ radix_tree_ptr_to_indirect(slot));
}
/* Go a level down */
@@ -318,7 +328,7 @@ int radix_tree_insert(struct radix_tree_root *root,
BUG_ON(tag_get(node, 0, offset));
BUG_ON(tag_get(node, 1, offset));
} else {
- rcu_assign_pointer(root->rnode, radix_tree_ptr_to_direct(item));
+ rcu_assign_pointer(root->rnode, item);
BUG_ON(root_tag_get(root, 0));
BUG_ON(root_tag_get(root, 1));
}
@@ -350,11 +360,12 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
if (node == NULL)
return NULL;
- if (radix_tree_is_direct_ptr(node)) {
+ if (!radix_tree_is_indirect_ptr(node)) {
if (index > 0)
return NULL;
return (void **)&root->rnode;
}
+ node = radix_tree_indirect_to_ptr(node);
height = node->height;
if (index > radix_tree_maxindex(height))
@@ -398,11 +409,12 @@ void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
if (node == NULL)
return NULL;
- if (radix_tree_is_direct_ptr(node)) {
+ if (!radix_tree_is_indirect_ptr(node)) {
if (index > 0)
return NULL;
- return radix_tree_direct_to_ptr(node);
+ return node;
}
+ node = radix_tree_indirect_to_ptr(node);
height = node->height;
if (index > radix_tree_maxindex(height))
@@ -447,7 +459,7 @@ void *radix_tree_tag_set(struct radix_tree_root *root,
height = root->height;
BUG_ON(index > radix_tree_maxindex(height));
- slot = root->rnode;
+ slot = radix_tree_indirect_to_ptr(root->rnode);
shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
while (height > 0) {
@@ -487,7 +499,11 @@ EXPORT_SYMBOL(radix_tree_tag_set);
void *radix_tree_tag_clear(struct radix_tree_root *root,
unsigned long index, unsigned int tag)
{
- struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path;
+ /*
+ * The radix tree path needs to be one longer than the maximum path
+ * since the "list" is null terminated.
+ */
+ struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path;
struct radix_tree_node *slot = NULL;
unsigned int height, shift;
@@ -497,7 +513,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root,
shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
pathp->node = NULL;
- slot = root->rnode;
+ slot = radix_tree_indirect_to_ptr(root->rnode);
while (height > 0) {
int offset;
@@ -562,8 +578,9 @@ int radix_tree_tag_get(struct radix_tree_root *root,
if (node == NULL)
return 0;
- if (radix_tree_is_direct_ptr(node))
+ if (!radix_tree_is_indirect_ptr(node))
return (index == 0);
+ node = radix_tree_indirect_to_ptr(node);
height = node->height;
if (index > radix_tree_maxindex(height))
@@ -599,6 +616,42 @@ int radix_tree_tag_get(struct radix_tree_root *root,
EXPORT_SYMBOL(radix_tree_tag_get);
#endif
+/**
+ * radix_tree_next_hole - find the next hole (not-present entry)
+ * @root: tree root
+ * @index: index key
+ * @max_scan: maximum range to search
+ *
+ * Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the lowest
+ * indexed hole.
+ *
+ * Returns: the index of the hole if found, otherwise returns an index
+ * outside of the set specified (in which case 'return - index >= max_scan'
+ * will be true).
+ *
+ * radix_tree_next_hole may be called under rcu_read_lock. However, like
+ * radix_tree_gang_lookup, this will not atomically search a snapshot of the
+ * tree at a single point in time. For example, if a hole is created at index
+ * 5, then subsequently a hole is created at index 10, radix_tree_next_hole
+ * covering both indexes may return 10 if called under rcu_read_lock.
+ */
+unsigned long radix_tree_next_hole(struct radix_tree_root *root,
+ unsigned long index, unsigned long max_scan)
+{
+ unsigned long i;
+
+ for (i = 0; i < max_scan; i++) {
+ if (!radix_tree_lookup(root, index))
+ break;
+ index++;
+ if (index == 0)
+ break;
+ }
+
+ return index;
+}
+EXPORT_SYMBOL(radix_tree_next_hole);
+
static unsigned int
__lookup(struct radix_tree_node *slot, void **results, unsigned long index,
unsigned int max_items, unsigned long *next_index)
@@ -680,13 +733,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
if (!node)
return 0;
- if (radix_tree_is_direct_ptr(node)) {
+ if (!radix_tree_is_indirect_ptr(node)) {
if (first_index > 0)
return 0;
- node = radix_tree_direct_to_ptr(node);
- results[0] = rcu_dereference(node);
+ results[0] = node;
return 1;
}
+ node = radix_tree_indirect_to_ptr(node);
max_index = radix_tree_maxindex(node->height);
@@ -808,13 +861,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
if (!node)
return 0;
- if (radix_tree_is_direct_ptr(node)) {
+ if (!radix_tree_is_indirect_ptr(node)) {
if (first_index > 0)
return 0;
- node = radix_tree_direct_to_ptr(node);
- results[0] = rcu_dereference(node);
+ results[0] = node;
return 1;
}
+ node = radix_tree_indirect_to_ptr(node);
max_index = radix_tree_maxindex(node->height);
@@ -844,12 +897,22 @@ EXPORT_SYMBOL(radix_tree_gang_lookup_tag);
static inline void radix_tree_shrink(struct radix_tree_root *root)
{
/* try to shrink tree height */
- while (root->height > 0 &&
- root->rnode->count == 1 &&
- root->rnode->slots[0]) {
+ while (root->height > 0) {
struct radix_tree_node *to_free = root->rnode;
void *newptr;
+ BUG_ON(!radix_tree_is_indirect_ptr(to_free));
+ to_free = radix_tree_indirect_to_ptr(to_free);
+
+ /*
+ * The candidate node has more than one child, or its child
+ * is not at the leftmost slot, we cannot shrink.
+ */
+ if (to_free->count != 1)
+ break;
+ if (!to_free->slots[0])
+ break;
+
/*
* We don't need rcu_assign_pointer(), since we are simply
* moving the node from one part of the tree to another. If
@@ -858,8 +921,8 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
* one (root->rnode).
*/
newptr = to_free->slots[0];
- if (root->height == 1)
- newptr = radix_tree_ptr_to_direct(newptr);
+ if (root->height > 1)
+ newptr = radix_tree_ptr_to_indirect(newptr);
root->rnode = newptr;
root->height--;
/* must only free zeroed nodes into the slab */
@@ -882,7 +945,11 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
*/
void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
{
- struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path;
+ /*
+ * The radix tree path needs to be one longer than the maximum path
+ * since the "list" is null terminated.
+ */
+ struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path;
struct radix_tree_node *slot = NULL;
struct radix_tree_node *to_free;
unsigned int height, shift;
@@ -894,12 +961,12 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
goto out;
slot = root->rnode;
- if (height == 0 && root->rnode) {
- slot = radix_tree_direct_to_ptr(slot);
+ if (height == 0) {
root_tag_clear_all(root);
root->rnode = NULL;
goto out;
}
+ slot = radix_tree_indirect_to_ptr(slot);
shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
pathp->node = NULL;
@@ -941,7 +1008,8 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
radix_tree_node_free(to_free);
if (pathp->node->count) {
- if (pathp->node == root->rnode)
+ if (pathp->node ==
+ radix_tree_indirect_to_ptr(root->rnode))
radix_tree_shrink(root);
goto out;
}
@@ -974,19 +1042,21 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag)
EXPORT_SYMBOL(radix_tree_tagged);
static void
-radix_tree_node_ctor(void *node, struct kmem_cache *cachep, unsigned long flags)
+radix_tree_node_ctor(struct kmem_cache *cachep, void *node)
{
memset(node, 0, sizeof(struct radix_tree_node));
}
static __init unsigned long __maxindex(unsigned int height)
{
- unsigned int tmp = height * RADIX_TREE_MAP_SHIFT;
- unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1;
-
- if (tmp >= RADIX_TREE_INDEX_BITS)
- index = ~0UL;
- return index;
+ unsigned int width = height * RADIX_TREE_MAP_SHIFT;
+ int shift = RADIX_TREE_INDEX_BITS - width;
+
+ if (shift < 0)
+ return ~0UL;
+ if (shift >= BITS_PER_LONG)
+ return 0UL;
+ return ~0UL >> shift;
}
static __init void radix_tree_init_maxindex(void)
diff --git a/lib/sort.c b/lib/sort.c
index 961567894d1..6abbaf3d585 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -67,7 +67,7 @@ void sort(void *base, size_t num, size_t size,
}
/* sort */
- for (i = n - size; i >= 0; i -= size) {
+ for (i = n - size; i > 0; i -= size) {
swap(base, base + i, size);
for (r = 0; r * 2 + size < i; r = c) {
c = r * 2 + size;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 30c1400e749..752fd95323f 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -677,16 +677,17 @@ swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
* same here.
*/
int
-swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
+swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
int dir)
{
+ struct scatterlist *sg;
void *addr;
dma_addr_t dev_addr;
int i;
BUG_ON(dir == DMA_NONE);
- for (i = 0; i < nelems; i++, sg++) {
+ for_each_sg(sgl, sg, nelems, i) {
addr = SG_ENT_VIRT_ADDRESS(sg);
dev_addr = virt_to_bus(addr);
if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
@@ -695,8 +696,8 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
/* Don't panic here, we expect map_sg users
to do proper error handling. */
swiotlb_full(hwdev, sg->length, dir, 0);
- swiotlb_unmap_sg(hwdev, sg - i, i, dir);
- sg[0].dma_length = 0;
+ swiotlb_unmap_sg(hwdev, sgl, i, dir);
+ sgl[0].dma_length = 0;
return 0;
}
sg->dma_address = virt_to_bus(map);
@@ -712,19 +713,21 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
* concerning calls here are the same as for swiotlb_unmap_single() above.
*/
void
-swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
+swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
int dir)
{
+ struct scatterlist *sg;
int i;
BUG_ON(dir == DMA_NONE);
- for (i = 0; i < nelems; i++, sg++)
+ for_each_sg(sgl, sg, nelems, i) {
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
unmap_single(hwdev, bus_to_virt(sg->dma_address),
sg->dma_length, dir);
else if (dir == DMA_FROM_DEVICE)
dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
+ }
}
/*
@@ -735,19 +738,21 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
* and usage.
*/
static void
-swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,
+swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl,
int nelems, int dir, int target)
{
+ struct scatterlist *sg;
int i;
BUG_ON(dir == DMA_NONE);
- for (i = 0; i < nelems; i++, sg++)
+ for_each_sg(sgl, sg, nelems, i) {
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, bus_to_virt(sg->dma_address),
sg->dma_length, dir, target);
else if (dir == DMA_FROM_DEVICE)
dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
+ }
}
void
diff --git a/mm/Kconfig b/mm/Kconfig
index a7609cbcb00..b1f03b0eb7f 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -112,6 +112,19 @@ config SPARSEMEM_EXTREME
def_bool y
depends on SPARSEMEM && !SPARSEMEM_STATIC
+#
+# SPARSEMEM_VMEMMAP uses a virtually mapped mem_map to optimise pfn_to_page
+# and page_to_pfn. The most efficient option where kernel virtual space is
+# not under pressure.
+#
+config SPARSEMEM_VMEMMAP_ENABLE
+ def_bool n
+
+config SPARSEMEM_VMEMMAP
+ bool
+ depends on SPARSEMEM
+ default y if (SPARSEMEM_VMEMMAP_ENABLE)
+
# eventually, we can have this option just 'select SPARSEMEM'
config MEMORY_HOTPLUG
bool "Allow for memory hot-add"
@@ -126,6 +139,11 @@ config MEMORY_HOTPLUG_SPARSE
def_bool y
depends on SPARSEMEM && MEMORY_HOTPLUG
+config MEMORY_HOTREMOVE
+ bool "Allow for memory hot remove"
+ depends on MEMORY_HOTPLUG && ARCH_ENABLE_MEMORY_HOTREMOVE
+ depends on MIGRATION
+
# Heavily threaded applications may benefit from splitting the mm-wide
# page_table_lock, so that faults on different parts of the user address
# space can be handled with less contention: split it at this NR_CPUS.
@@ -137,7 +155,6 @@ config SPLIT_PTLOCK_CPUS
int
default "4096" if ARM && !CPU_CACHE_VIPT
default "4096" if PARISC && !PA20
- default "4096" if XEN
default "4"
#
diff --git a/mm/Makefile b/mm/Makefile
index 245e33ab00c..5c0b0ea7572 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -11,13 +11,14 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
page_alloc.o page-writeback.o pdflush.o \
readahead.o swap.o truncate.o vmscan.o \
prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
- $(mmu-y)
+ page_isolation.o $(mmu-y)
obj-$(CONFIG_BOUNCE) += bounce.o
obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
obj-$(CONFIG_HUGETLBFS) += hugetlb.o
obj-$(CONFIG_NUMA) += mempolicy.o
obj-$(CONFIG_SPARSEMEM) += sparse.o
+obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o
obj-$(CONFIG_SHMEM) += shmem.o
obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index f50a2811f9d..b0ceb29da4c 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -5,6 +5,41 @@
#include <linux/sched.h>
#include <linux/module.h>
+int bdi_init(struct backing_dev_info *bdi)
+{
+ int i, j;
+ int err;
+
+ for (i = 0; i < NR_BDI_STAT_ITEMS; i++) {
+ err = percpu_counter_init_irq(&bdi->bdi_stat[i], 0);
+ if (err)
+ goto err;
+ }
+
+ bdi->dirty_exceeded = 0;
+ err = prop_local_init_percpu(&bdi->completions);
+
+ if (err) {
+err:
+ for (j = 0; j < i; j++)
+ percpu_counter_destroy(&bdi->bdi_stat[i]);
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(bdi_init);
+
+void bdi_destroy(struct backing_dev_info *bdi)
+{
+ int i;
+
+ for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
+ percpu_counter_destroy(&bdi->bdi_stat[i]);
+
+ prop_local_destroy_percpu(&bdi->completions);
+}
+EXPORT_SYMBOL(bdi_destroy);
+
static wait_queue_head_t congestion_wqh[2] = {
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
@@ -55,15 +90,3 @@ long congestion_wait(int rw, long timeout)
}
EXPORT_SYMBOL(congestion_wait);
-/**
- * congestion_end - wake up sleepers on a congested backing_dev_info
- * @rw: READ or WRITE
- */
-void congestion_end(int rw)
-{
- wait_queue_head_t *wqh = &congestion_wqh[rw];
-
- if (waitqueue_active(wqh))
- wake_up(wqh);
-}
-EXPORT_SYMBOL(congestion_end);
diff --git a/mm/bounce.c b/mm/bounce.c
index 3b549bf31f7..b6d2d0f1019 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -265,6 +265,12 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
mempool_t *pool;
/*
+ * Data-less bio, nothing to bounce
+ */
+ if (bio_empty_barrier(*bio_orig))
+ return;
+
+ /*
* for non-isa bounce case, just check if the bounce pfn is equal
* to or bigger than the highest pfn in the system -- in that case,
* don't waste time iterating over bio segments
diff --git a/mm/filemap.c b/mm/filemap.c
index 15c8413ee92..920366399ee 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -25,12 +25,13 @@
#include <linux/uio.h>
#include <linux/hash.h>
#include <linux/writeback.h>
+#include <linux/backing-dev.h>
#include <linux/pagevec.h>
#include <linux/blkdev.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/cpuset.h>
-#include "filemap.h"
+#include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
#include "internal.h"
/*
@@ -63,6 +64,7 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
* ->private_lock (__free_pte->__set_page_dirty_buffers)
* ->swap_lock (exclusive_swap_page, others)
* ->mapping->tree_lock
+ * ->zone.lock
*
* ->i_mutex
* ->i_mmap_lock (truncate->unmap_mapping_range)
@@ -593,7 +595,7 @@ void fastcall __lock_page_nosync(struct page *page)
* Is there a pagecache struct page at the given (mapping, offset) tuple?
* If yes, increment its refcount and return it; if no, return NULL.
*/
-struct page * find_get_page(struct address_space *mapping, unsigned long offset)
+struct page * find_get_page(struct address_space *mapping, pgoff_t offset)
{
struct page *page;
@@ -617,30 +619,31 @@ EXPORT_SYMBOL(find_get_page);
* Returns zero if the page was not present. find_lock_page() may sleep.
*/
struct page *find_lock_page(struct address_space *mapping,
- unsigned long offset)
+ pgoff_t offset)
{
struct page *page;
- read_lock_irq(&mapping->tree_lock);
repeat:
+ read_lock_irq(&mapping->tree_lock);
page = radix_tree_lookup(&mapping->page_tree, offset);
if (page) {
page_cache_get(page);
if (TestSetPageLocked(page)) {
read_unlock_irq(&mapping->tree_lock);
__lock_page(page);
- read_lock_irq(&mapping->tree_lock);
/* Has the page been truncated while we slept? */
- if (unlikely(page->mapping != mapping ||
- page->index != offset)) {
+ if (unlikely(page->mapping != mapping)) {
unlock_page(page);
page_cache_release(page);
goto repeat;
}
+ VM_BUG_ON(page->index != offset);
+ goto out;
}
}
read_unlock_irq(&mapping->tree_lock);
+out:
return page;
}
EXPORT_SYMBOL(find_lock_page);
@@ -663,29 +666,24 @@ EXPORT_SYMBOL(find_lock_page);
* memory exhaustion.
*/
struct page *find_or_create_page(struct address_space *mapping,
- unsigned long index, gfp_t gfp_mask)
+ pgoff_t index, gfp_t gfp_mask)
{
- struct page *page, *cached_page = NULL;
+ struct page *page;
int err;
repeat:
page = find_lock_page(mapping, index);
if (!page) {
- if (!cached_page) {
- cached_page =
- __page_cache_alloc(gfp_mask);
- if (!cached_page)
- return NULL;
+ page = __page_cache_alloc(gfp_mask);
+ if (!page)
+ return NULL;
+ err = add_to_page_cache_lru(page, mapping, index, gfp_mask);
+ if (unlikely(err)) {
+ page_cache_release(page);
+ page = NULL;
+ if (err == -EEXIST)
+ goto repeat;
}
- err = add_to_page_cache_lru(cached_page, mapping,
- index, gfp_mask);
- if (!err) {
- page = cached_page;
- cached_page = NULL;
- } else if (err == -EEXIST)
- goto repeat;
}
- if (cached_page)
- page_cache_release(cached_page);
return page;
}
EXPORT_SYMBOL(find_or_create_page);
@@ -797,7 +795,7 @@ EXPORT_SYMBOL(find_get_pages_tag);
* and deadlock against the caller's locked page.
*/
struct page *
-grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
+grab_cache_page_nowait(struct address_space *mapping, pgoff_t index)
{
struct page *page = find_get_page(mapping, index);
@@ -859,34 +857,29 @@ static void shrink_readahead_size_eio(struct file *filp,
* It may be NULL.
*/
void do_generic_mapping_read(struct address_space *mapping,
- struct file_ra_state *_ra,
+ struct file_ra_state *ra,
struct file *filp,
loff_t *ppos,
read_descriptor_t *desc,
read_actor_t actor)
{
struct inode *inode = mapping->host;
- unsigned long index;
- unsigned long offset;
- unsigned long last_index;
- unsigned long next_index;
- unsigned long prev_index;
+ pgoff_t index;
+ pgoff_t last_index;
+ pgoff_t prev_index;
+ unsigned long offset; /* offset into pagecache page */
unsigned int prev_offset;
- struct page *cached_page;
int error;
- struct file_ra_state ra = *_ra;
- cached_page = NULL;
index = *ppos >> PAGE_CACHE_SHIFT;
- next_index = index;
- prev_index = ra.prev_index;
- prev_offset = ra.prev_offset;
+ prev_index = ra->prev_pos >> PAGE_CACHE_SHIFT;
+ prev_offset = ra->prev_pos & (PAGE_CACHE_SIZE-1);
last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
offset = *ppos & ~PAGE_CACHE_MASK;
for (;;) {
struct page *page;
- unsigned long end_index;
+ pgoff_t end_index;
loff_t isize;
unsigned long nr, ret;
@@ -895,7 +888,7 @@ find_page:
page = find_get_page(mapping, index);
if (!page) {
page_cache_sync_readahead(mapping,
- &ra, filp,
+ ra, filp,
index, last_index - index);
page = find_get_page(mapping, index);
if (unlikely(page == NULL))
@@ -903,7 +896,7 @@ find_page:
}
if (PageReadahead(page)) {
page_cache_async_readahead(mapping,
- &ra, filp, page,
+ ra, filp, page,
index, last_index - index);
}
if (!PageUptodate(page))
@@ -966,7 +959,6 @@ page_ok:
index += offset >> PAGE_CACHE_SHIFT;
offset &= ~PAGE_CACHE_MASK;
prev_offset = offset;
- ra.prev_offset = offset;
page_cache_release(page);
if (ret == nr && desc->count)
@@ -1015,7 +1007,7 @@ readpage:
}
unlock_page(page);
error = -EIO;
- shrink_readahead_size_eio(filp, &ra);
+ shrink_readahead_size_eio(filp, ra);
goto readpage_error;
}
unlock_page(page);
@@ -1034,33 +1026,29 @@ no_cached_page:
* Ok, it wasn't cached, so we need to create a new
* page..
*/
- if (!cached_page) {
- cached_page = page_cache_alloc_cold(mapping);
- if (!cached_page) {
- desc->error = -ENOMEM;
- goto out;
- }
+ page = page_cache_alloc_cold(mapping);
+ if (!page) {
+ desc->error = -ENOMEM;
+ goto out;
}
- error = add_to_page_cache_lru(cached_page, mapping,
+ error = add_to_page_cache_lru(page, mapping,
index, GFP_KERNEL);
if (error) {
+ page_cache_release(page);
if (error == -EEXIST)
goto find_page;
desc->error = error;
goto out;
}
- page = cached_page;
- cached_page = NULL;
goto readpage;
}
out:
- *_ra = ra;
- _ra->prev_index = prev_index;
+ ra->prev_pos = prev_index;
+ ra->prev_pos <<= PAGE_CACHE_SHIFT;
+ ra->prev_pos |= prev_offset;
- *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
- if (cached_page)
- page_cache_release(cached_page);
+ *ppos = ((loff_t)index << PAGE_CACHE_SHIFT) + offset;
if (filp)
file_accessed(filp);
}
@@ -1220,7 +1208,7 @@ EXPORT_SYMBOL(generic_file_aio_read);
static ssize_t
do_readahead(struct address_space *mapping, struct file *filp,
- unsigned long index, unsigned long nr)
+ pgoff_t index, unsigned long nr)
{
if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage)
return -EINVAL;
@@ -1240,8 +1228,8 @@ asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
if (file) {
if (file->f_mode & FMODE_READ) {
struct address_space *mapping = file->f_mapping;
- unsigned long start = offset >> PAGE_CACHE_SHIFT;
- unsigned long end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
+ pgoff_t start = offset >> PAGE_CACHE_SHIFT;
+ pgoff_t end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
unsigned long len = end - start + 1;
ret = do_readahead(mapping, file, start, len);
}
@@ -1251,7 +1239,6 @@ asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
}
#ifdef CONFIG_MMU
-static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
/**
* page_cache_read - adds requested page to the page cache if not already there
* @file: file to read
@@ -1260,7 +1247,7 @@ static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
* This adds the requested page to the page cache if it isn't already there,
* and schedules an I/O to read in its contents from disk.
*/
-static int fastcall page_cache_read(struct file * file, unsigned long offset)
+static int fastcall page_cache_read(struct file * file, pgoff_t offset)
{
struct address_space *mapping = file->f_mapping;
struct page *page;
@@ -1349,7 +1336,7 @@ retry_find:
* Do we miss much more than hit in this file? If so,
* stop bothering with read-ahead. It will only hurt.
*/
- if (ra->mmap_miss > ra->mmap_hit + MMAP_LOTSAMISS)
+ if (ra->mmap_miss > MMAP_LOTSAMISS)
goto no_cached_page;
/*
@@ -1375,7 +1362,7 @@ retry_find:
}
if (!did_readaround)
- ra->mmap_hit++;
+ ra->mmap_miss--;
/*
* We have a locked page in the page cache, now we need to check
@@ -1396,7 +1383,7 @@ retry_find:
* Found the page and have a reference on it.
*/
mark_page_accessed(page);
- ra->prev_index = page->index;
+ ra->prev_pos = (loff_t)page->index << PAGE_CACHE_SHIFT;
vmf->page = page;
return ret | VM_FAULT_LOCKED;
@@ -1501,39 +1488,32 @@ EXPORT_SYMBOL(generic_file_mmap);
EXPORT_SYMBOL(generic_file_readonly_mmap);
static struct page *__read_cache_page(struct address_space *mapping,
- unsigned long index,
+ pgoff_t index,
int (*filler)(void *,struct page*),
void *data)
{
- struct page *page, *cached_page = NULL;
+ struct page *page;
int err;
repeat:
page = find_get_page(mapping, index);
if (!page) {
- if (!cached_page) {
- cached_page = page_cache_alloc_cold(mapping);
- if (!cached_page)
- return ERR_PTR(-ENOMEM);
- }
- err = add_to_page_cache_lru(cached_page, mapping,
- index, GFP_KERNEL);
- if (err == -EEXIST)
- goto repeat;
- if (err < 0) {
+ page = page_cache_alloc_cold(mapping);
+ if (!page)
+ return ERR_PTR(-ENOMEM);
+ err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
+ if (unlikely(err)) {
+ page_cache_release(page);
+ if (err == -EEXIST)
+ goto repeat;
/* Presumably ENOMEM for radix tree node */
- page_cache_release(cached_page);
return ERR_PTR(err);
}
- page = cached_page;
- cached_page = NULL;
err = filler(data, page);
if (err < 0) {
page_cache_release(page);
page = ERR_PTR(err);
}
}
- if (cached_page)
- page_cache_release(cached_page);
return page;
}
@@ -1542,7 +1522,7 @@ repeat:
* after submitting it to the filler.
*/
struct page *read_cache_page_async(struct address_space *mapping,
- unsigned long index,
+ pgoff_t index,
int (*filler)(void *,struct page*),
void *data)
{
@@ -1590,7 +1570,7 @@ EXPORT_SYMBOL(read_cache_page_async);
* If the page does not get brought uptodate, return -EIO.
*/
struct page *read_cache_page(struct address_space *mapping,
- unsigned long index,
+ pgoff_t index,
int (*filler)(void *,struct page*),
void *data)
{
@@ -1610,40 +1590,6 @@ struct page *read_cache_page(struct address_space *mapping,
EXPORT_SYMBOL(read_cache_page);
/*
- * If the page was newly created, increment its refcount and add it to the
- * caller's lru-buffering pagevec. This function is specifically for
- * generic_file_write().
- */
-static inline struct page *
-__grab_cache_page(struct address_space *mapping, unsigned long index,
- struct page **cached_page, struct pagevec *lru_pvec)
-{
- int err;
- struct page *page;
-repeat:
- page = find_lock_page(mapping, index);
- if (!page) {
- if (!*cached_page) {
- *cached_page = page_cache_alloc(mapping);
- if (!*cached_page)
- return NULL;
- }
- err = add_to_page_cache(*cached_page, mapping,
- index, GFP_KERNEL);
- if (err == -EEXIST)
- goto repeat;
- if (err == 0) {
- page = *cached_page;
- page_cache_get(page);
- if (!pagevec_add(lru_pvec, page))
- __pagevec_lru_add(lru_pvec);
- *cached_page = NULL;
- }
- }
- return page;
-}
-
-/*
* The logic we want is
*
* if suid or (sgid and xgrp)
@@ -1682,17 +1628,22 @@ int __remove_suid(struct dentry *dentry, int kill)
int remove_suid(struct dentry *dentry)
{
- int kill = should_remove_suid(dentry);
+ int killsuid = should_remove_suid(dentry);
+ int killpriv = security_inode_need_killpriv(dentry);
+ int error = 0;
- if (unlikely(kill))
- return __remove_suid(dentry, kill);
+ if (killpriv < 0)
+ return killpriv;
+ if (killpriv)
+ error = security_inode_killpriv(dentry);
+ if (!error && killsuid)
+ error = __remove_suid(dentry, killsuid);
- return 0;
+ return error;
}
EXPORT_SYMBOL(remove_suid);
-size_t
-__filemap_copy_from_user_iovec_inatomic(char *vaddr,
+static size_t __iovec_copy_from_user_inatomic(char *vaddr,
const struct iovec *iov, size_t base, size_t bytes)
{
size_t copied = 0, left = 0;
@@ -1715,6 +1666,124 @@ __filemap_copy_from_user_iovec_inatomic(char *vaddr,
}
/*
+ * Copy as much as we can into the page and return the number of bytes which
+ * were sucessfully copied. If a fault is encountered then return the number of
+ * bytes which were copied.
+ */
+size_t iov_iter_copy_from_user_atomic(struct page *page,
+ struct iov_iter *i, unsigned long offset, size_t bytes)
+{
+ char *kaddr;
+ size_t copied;
+
+ BUG_ON(!in_atomic());
+ kaddr = kmap_atomic(page, KM_USER0);
+ if (likely(i->nr_segs == 1)) {
+ int left;
+ char __user *buf = i->iov->iov_base + i->iov_offset;
+ left = __copy_from_user_inatomic_nocache(kaddr + offset,
+ buf, bytes);
+ copied = bytes - left;
+ } else {
+ copied = __iovec_copy_from_user_inatomic(kaddr + offset,
+ i->iov, i->iov_offset, bytes);
+ }
+ kunmap_atomic(kaddr, KM_USER0);
+
+ return copied;
+}
+EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
+
+/*
+ * This has the same sideeffects and return value as
+ * iov_iter_copy_from_user_atomic().
+ * The difference is that it attempts to resolve faults.
+ * Page must not be locked.
+ */
+size_t iov_iter_copy_from_user(struct page *page,
+ struct iov_iter *i, unsigned long offset, size_t bytes)
+{
+ char *kaddr;
+ size_t copied;
+
+ kaddr = kmap(page);
+ if (likely(i->nr_segs == 1)) {
+ int left;
+ char __user *buf = i->iov->iov_base + i->iov_offset;
+ left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
+ copied = bytes - left;
+ } else {
+ copied = __iovec_copy_from_user_inatomic(kaddr + offset,
+ i->iov, i->iov_offset, bytes);
+ }
+ kunmap(page);
+ return copied;
+}
+EXPORT_SYMBOL(iov_iter_copy_from_user);
+
+static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
+{
+ if (likely(i->nr_segs == 1)) {
+ i->iov_offset += bytes;
+ } else {
+ const struct iovec *iov = i->iov;
+ size_t base = i->iov_offset;
+
+ while (bytes) {
+ int copy = min(bytes, iov->iov_len - base);
+
+ bytes -= copy;
+ base += copy;
+ if (iov->iov_len == base) {
+ iov++;
+ base = 0;
+ }
+ }
+ i->iov = iov;
+ i->iov_offset = base;
+ }
+}
+
+void iov_iter_advance(struct iov_iter *i, size_t bytes)
+{
+ BUG_ON(i->count < bytes);
+
+ __iov_iter_advance_iov(i, bytes);
+ i->count -= bytes;
+}
+EXPORT_SYMBOL(iov_iter_advance);
+
+/*
+ * Fault in the first iovec of the given iov_iter, to a maximum length
+ * of bytes. Returns 0 on success, or non-zero if the memory could not be
+ * accessed (ie. because it is an invalid address).
+ *
+ * writev-intensive code may want this to prefault several iovecs -- that
+ * would be possible (callers must not rely on the fact that _only_ the
+ * first iovec will be faulted with the current implementation).
+ */
+int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
+{
+ char __user *buf = i->iov->iov_base + i->iov_offset;
+ bytes = min(bytes, i->iov->iov_len - i->iov_offset);
+ return fault_in_pages_readable(buf, bytes);
+}
+EXPORT_SYMBOL(iov_iter_fault_in_readable);
+
+/*
+ * Return the count of just the current iov_iter segment.
+ */
+size_t iov_iter_single_seg_count(struct iov_iter *i)
+{
+ const struct iovec *iov = i->iov;
+ if (i->nr_segs == 1)
+ return i->count;
+ else
+ return min(i->count, iov->iov_len - i->iov_offset);
+}
+EXPORT_SYMBOL(iov_iter_single_seg_count);
+
+/*
* Performs necessary checks before doing a write
*
* Can adjust writing position or amount of bytes to write.
@@ -1796,6 +1865,91 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
}
EXPORT_SYMBOL(generic_write_checks);
+int pagecache_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ const struct address_space_operations *aops = mapping->a_ops;
+
+ if (aops->write_begin) {
+ return aops->write_begin(file, mapping, pos, len, flags,
+ pagep, fsdata);
+ } else {
+ int ret;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+ struct inode *inode = mapping->host;
+ struct page *page;
+again:
+ page = __grab_cache_page(mapping, index);
+ *pagep = page;
+ if (!page)
+ return -ENOMEM;
+
+ if (flags & AOP_FLAG_UNINTERRUPTIBLE && !PageUptodate(page)) {
+ /*
+ * There is no way to resolve a short write situation
+ * for a !Uptodate page (except by double copying in
+ * the caller done by generic_perform_write_2copy).
+ *
+ * Instead, we have to bring it uptodate here.
+ */
+ ret = aops->readpage(file, page);
+ page_cache_release(page);
+ if (ret) {
+ if (ret == AOP_TRUNCATED_PAGE)
+ goto again;
+ return ret;
+ }
+ goto again;
+ }
+
+ ret = aops->prepare_write(file, page, offset, offset+len);
+ if (ret) {
+ unlock_page(page);
+ page_cache_release(page);
+ if (pos + len > inode->i_size)
+ vmtruncate(inode, inode->i_size);
+ }
+ return ret;
+ }
+}
+EXPORT_SYMBOL(pagecache_write_begin);
+
+int pagecache_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ const struct address_space_operations *aops = mapping->a_ops;
+ int ret;
+
+ if (aops->write_end) {
+ mark_page_accessed(page);
+ ret = aops->write_end(file, mapping, pos, len, copied,
+ page, fsdata);
+ } else {
+ unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+ struct inode *inode = mapping->host;
+
+ flush_dcache_page(page);
+ ret = aops->commit_write(file, page, offset, offset+len);
+ unlock_page(page);
+ mark_page_accessed(page);
+ page_cache_release(page);
+
+ if (ret < 0) {
+ if (pos + len > inode->i_size)
+ vmtruncate(inode, inode->i_size);
+ } else if (ret > 0)
+ ret = min_t(size_t, copied, ret);
+ else
+ ret = copied;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pagecache_write_end);
+
ssize_t
generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long *nr_segs, loff_t pos, loff_t *ppos,
@@ -1835,151 +1989,314 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
}
EXPORT_SYMBOL(generic_file_direct_write);
-ssize_t
-generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos, loff_t *ppos,
- size_t count, ssize_t written)
+/*
+ * Find or create a page at the given pagecache position. Return the locked
+ * page. This function is specifically for buffered writes.
+ */
+struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index)
{
- struct file *file = iocb->ki_filp;
- struct address_space * mapping = file->f_mapping;
- const struct address_space_operations *a_ops = mapping->a_ops;
- struct inode *inode = mapping->host;
- long status = 0;
- struct page *page;
- struct page *cached_page = NULL;
- size_t bytes;
- struct pagevec lru_pvec;
- const struct iovec *cur_iov = iov; /* current iovec */
- size_t iov_base = 0; /* offset in the current iovec */
- char __user *buf;
-
- pagevec_init(&lru_pvec, 0);
+ int status;
+ struct page *page;
+repeat:
+ page = find_lock_page(mapping, index);
+ if (likely(page))
+ return page;
- /*
- * handle partial DIO write. Adjust cur_iov if needed.
- */
- if (likely(nr_segs == 1))
- buf = iov->iov_base + written;
- else {
- filemap_set_next_iovec(&cur_iov, &iov_base, written);
- buf = cur_iov->iov_base + iov_base;
+ page = page_cache_alloc(mapping);
+ if (!page)
+ return NULL;
+ status = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
+ if (unlikely(status)) {
+ page_cache_release(page);
+ if (status == -EEXIST)
+ goto repeat;
+ return NULL;
}
+ return page;
+}
+EXPORT_SYMBOL(__grab_cache_page);
+
+static ssize_t generic_perform_write_2copy(struct file *file,
+ struct iov_iter *i, loff_t pos)
+{
+ struct address_space *mapping = file->f_mapping;
+ const struct address_space_operations *a_ops = mapping->a_ops;
+ struct inode *inode = mapping->host;
+ long status = 0;
+ ssize_t written = 0;
do {
- unsigned long index;
- unsigned long offset;
- size_t copied;
+ struct page *src_page;
+ struct page *page;
+ pgoff_t index; /* Pagecache index for current page */
+ unsigned long offset; /* Offset into pagecache page */
+ unsigned long bytes; /* Bytes to write to page */
+ size_t copied; /* Bytes copied from user */
- offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
+ offset = (pos & (PAGE_CACHE_SIZE - 1));
index = pos >> PAGE_CACHE_SHIFT;
- bytes = PAGE_CACHE_SIZE - offset;
+ bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
+ iov_iter_count(i));
- /* Limit the size of the copy to the caller's write size */
- bytes = min(bytes, count);
-
- /* We only need to worry about prefaulting when writes are from
- * user-space. NFSd uses vfs_writev with several non-aligned
- * segments in the vector, and limiting to one segment a time is
- * a noticeable performance for re-write
+ /*
+ * a non-NULL src_page indicates that we're doing the
+ * copy via get_user_pages and kmap.
*/
- if (!segment_eq(get_fs(), KERNEL_DS)) {
- /*
- * Limit the size of the copy to that of the current
- * segment, because fault_in_pages_readable() doesn't
- * know how to walk segments.
- */
- bytes = min(bytes, cur_iov->iov_len - iov_base);
+ src_page = NULL;
- /*
- * Bring in the user page that we will copy from
- * _first_. Otherwise there's a nasty deadlock on
- * copying from the same page as we're writing to,
- * without it being marked up-to-date.
- */
- fault_in_pages_readable(buf, bytes);
+ /*
+ * Bring in the user page that we will copy from _first_.
+ * Otherwise there's a nasty deadlock on copying from the
+ * same page as we're writing to, without it being marked
+ * up-to-date.
+ *
+ * Not only is this an optimisation, but it is also required
+ * to check that the address is actually valid, when atomic
+ * usercopies are used, below.
+ */
+ if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
+ status = -EFAULT;
+ break;
}
- page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
+
+ page = __grab_cache_page(mapping, index);
if (!page) {
status = -ENOMEM;
break;
}
- if (unlikely(bytes == 0)) {
- status = 0;
- copied = 0;
- goto zero_length_segment;
- }
+ /*
+ * non-uptodate pages cannot cope with short copies, and we
+ * cannot take a pagefault with the destination page locked.
+ * So pin the source page to copy it.
+ */
+ if (!PageUptodate(page) && !segment_eq(get_fs(), KERNEL_DS)) {
+ unlock_page(page);
- status = a_ops->prepare_write(file, page, offset, offset+bytes);
- if (unlikely(status)) {
- loff_t isize = i_size_read(inode);
+ src_page = alloc_page(GFP_KERNEL);
+ if (!src_page) {
+ page_cache_release(page);
+ status = -ENOMEM;
+ break;
+ }
- if (status != AOP_TRUNCATED_PAGE)
+ /*
+ * Cannot get_user_pages with a page locked for the
+ * same reason as we can't take a page fault with a
+ * page locked (as explained below).
+ */
+ copied = iov_iter_copy_from_user(src_page, i,
+ offset, bytes);
+ if (unlikely(copied == 0)) {
+ status = -EFAULT;
+ page_cache_release(page);
+ page_cache_release(src_page);
+ break;
+ }
+ bytes = copied;
+
+ lock_page(page);
+ /*
+ * Can't handle the page going uptodate here, because
+ * that means we would use non-atomic usercopies, which
+ * zero out the tail of the page, which can cause
+ * zeroes to become transiently visible. We could just
+ * use a non-zeroing copy, but the APIs aren't too
+ * consistent.
+ */
+ if (unlikely(!page->mapping || PageUptodate(page))) {
unlock_page(page);
- page_cache_release(page);
- if (status == AOP_TRUNCATED_PAGE)
+ page_cache_release(page);
+ page_cache_release(src_page);
continue;
+ }
+ }
+
+ status = a_ops->prepare_write(file, page, offset, offset+bytes);
+ if (unlikely(status))
+ goto fs_write_aop_error;
+
+ if (!src_page) {
/*
- * prepare_write() may have instantiated a few blocks
- * outside i_size. Trim these off again.
+ * Must not enter the pagefault handler here, because
+ * we hold the page lock, so we might recursively
+ * deadlock on the same lock, or get an ABBA deadlock
+ * against a different lock, or against the mmap_sem
+ * (which nests outside the page lock). So increment
+ * preempt count, and use _atomic usercopies.
+ *
+ * The page is uptodate so we are OK to encounter a
+ * short copy: if unmodified parts of the page are
+ * marked dirty and written out to disk, it doesn't
+ * really matter.
*/
- if (pos + bytes > isize)
- vmtruncate(inode, isize);
- break;
+ pagefault_disable();
+ copied = iov_iter_copy_from_user_atomic(page, i,
+ offset, bytes);
+ pagefault_enable();
+ } else {
+ void *src, *dst;
+ src = kmap_atomic(src_page, KM_USER0);
+ dst = kmap_atomic(page, KM_USER1);
+ memcpy(dst + offset, src + offset, bytes);
+ kunmap_atomic(dst, KM_USER1);
+ kunmap_atomic(src, KM_USER0);
+ copied = bytes;
}
- if (likely(nr_segs == 1))
- copied = filemap_copy_from_user(page, offset,
- buf, bytes);
- else
- copied = filemap_copy_from_user_iovec(page, offset,
- cur_iov, iov_base, bytes);
flush_dcache_page(page);
+
status = a_ops->commit_write(file, page, offset, offset+bytes);
- if (status == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- continue;
- }
-zero_length_segment:
- if (likely(copied >= 0)) {
- if (!status)
- status = copied;
-
- if (status >= 0) {
- written += status;
- count -= status;
- pos += status;
- buf += status;
- if (unlikely(nr_segs > 1)) {
- filemap_set_next_iovec(&cur_iov,
- &iov_base, status);
- if (count)
- buf = cur_iov->iov_base +
- iov_base;
- } else {
- iov_base += status;
- }
- }
- }
- if (unlikely(copied != bytes))
- if (status >= 0)
- status = -EFAULT;
+ if (unlikely(status < 0))
+ goto fs_write_aop_error;
+ if (unlikely(status > 0)) /* filesystem did partial write */
+ copied = min_t(size_t, copied, status);
+
unlock_page(page);
mark_page_accessed(page);
page_cache_release(page);
- if (status < 0)
- break;
+ if (src_page)
+ page_cache_release(src_page);
+
+ iov_iter_advance(i, copied);
+ pos += copied;
+ written += copied;
+
balance_dirty_pages_ratelimited(mapping);
cond_resched();
- } while (count);
- *ppos = pos;
+ continue;
- if (cached_page)
- page_cache_release(cached_page);
+fs_write_aop_error:
+ unlock_page(page);
+ page_cache_release(page);
+ if (src_page)
+ page_cache_release(src_page);
+
+ /*
+ * prepare_write() may have instantiated a few blocks
+ * outside i_size. Trim these off again. Don't need
+ * i_size_read because we hold i_mutex.
+ */
+ if (pos + bytes > inode->i_size)
+ vmtruncate(inode, inode->i_size);
+ break;
+ } while (iov_iter_count(i));
+
+ return written ? written : status;
+}
+
+static ssize_t generic_perform_write(struct file *file,
+ struct iov_iter *i, loff_t pos)
+{
+ struct address_space *mapping = file->f_mapping;
+ const struct address_space_operations *a_ops = mapping->a_ops;
+ long status = 0;
+ ssize_t written = 0;
+ unsigned int flags = 0;
/*
- * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
+ * Copies from kernel address space cannot fail (NFSD is a big user).
*/
+ if (segment_eq(get_fs(), KERNEL_DS))
+ flags |= AOP_FLAG_UNINTERRUPTIBLE;
+
+ do {
+ struct page *page;
+ pgoff_t index; /* Pagecache index for current page */
+ unsigned long offset; /* Offset into pagecache page */
+ unsigned long bytes; /* Bytes to write to page */
+ size_t copied; /* Bytes copied from user */
+ void *fsdata;
+
+ offset = (pos & (PAGE_CACHE_SIZE - 1));
+ index = pos >> PAGE_CACHE_SHIFT;
+ bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
+ iov_iter_count(i));
+
+again:
+
+ /*
+ * Bring in the user page that we will copy from _first_.
+ * Otherwise there's a nasty deadlock on copying from the
+ * same page as we're writing to, without it being marked
+ * up-to-date.
+ *
+ * Not only is this an optimisation, but it is also required
+ * to check that the address is actually valid, when atomic
+ * usercopies are used, below.
+ */
+ if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
+ status = -EFAULT;
+ break;
+ }
+
+ status = a_ops->write_begin(file, mapping, pos, bytes, flags,
+ &page, &fsdata);
+ if (unlikely(status))
+ break;
+
+ pagefault_disable();
+ copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
+ pagefault_enable();
+ flush_dcache_page(page);
+
+ status = a_ops->write_end(file, mapping, pos, bytes, copied,
+ page, fsdata);
+ if (unlikely(status < 0))
+ break;
+ copied = status;
+
+ cond_resched();
+
+ if (unlikely(copied == 0)) {
+ /*
+ * If we were unable to copy any data at all, we must
+ * fall back to a single segment length write.
+ *
+ * If we didn't fallback here, we could livelock
+ * because not all segments in the iov can be copied at
+ * once without a pagefault.
+ */
+ bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
+ iov_iter_single_seg_count(i));
+ goto again;
+ }
+ iov_iter_advance(i, copied);
+ pos += copied;
+ written += copied;
+
+ balance_dirty_pages_ratelimited(mapping);
+
+ } while (iov_iter_count(i));
+
+ return written ? written : status;
+}
+
+ssize_t
+generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos, loff_t *ppos,
+ size_t count, ssize_t written)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ const struct address_space_operations *a_ops = mapping->a_ops;
+ struct inode *inode = mapping->host;
+ ssize_t status;
+ struct iov_iter i;
+
+ iov_iter_init(&i, iov, nr_segs, count, written);
+ if (a_ops->write_begin)
+ status = generic_perform_write(file, &i, pos);
+ else
+ status = generic_perform_write_2copy(file, &i, pos);
+
if (likely(status >= 0)) {
+ written += status;
+ *ppos = pos + status;
+
+ /*
+ * For now, when the user asks for O_SYNC, we'll actually give
+ * O_DSYNC
+ */
if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
if (!a_ops->writepage || !is_sync_kiocb(iocb))
status = generic_osync_inode(inode, mapping,
@@ -1995,7 +2312,6 @@ zero_length_segment:
if (unlikely(file->f_flags & O_DIRECT) && written)
status = filemap_write_and_wait(mapping);
- pagevec_lru_add(&lru_pvec);
return written ? written : status;
}
EXPORT_SYMBOL(generic_file_buffered_write);
diff --git a/mm/filemap.h b/mm/filemap.h
deleted file mode 100644
index c2bff04c84e..00000000000
--- a/mm/filemap.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * linux/mm/filemap.h
- *
- * Copyright (C) 1994-1999 Linus Torvalds
- */
-
-#ifndef __FILEMAP_H
-#define __FILEMAP_H
-
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/uio.h>
-#include <linux/uaccess.h>
-
-size_t
-__filemap_copy_from_user_iovec_inatomic(char *vaddr,
- const struct iovec *iov,
- size_t base,
- size_t bytes);
-
-/*
- * Copy as much as we can into the page and return the number of bytes which
- * were sucessfully copied. If a fault is encountered then clear the page
- * out to (offset+bytes) and return the number of bytes which were copied.
- *
- * NOTE: For this to work reliably we really want copy_from_user_inatomic_nocache
- * to *NOT* zero any tail of the buffer that it failed to copy. If it does,
- * and if the following non-atomic copy succeeds, then there is a small window
- * where the target page contains neither the data before the write, nor the
- * data after the write (it contains zero). A read at this time will see
- * data that is inconsistent with any ordering of the read and the write.
- * (This has been detected in practice).
- */
-static inline size_t
-filemap_copy_from_user(struct page *page, unsigned long offset,
- const char __user *buf, unsigned bytes)
-{
- char *kaddr;
- int left;
-
- kaddr = kmap_atomic(page, KM_USER0);
- left = __copy_from_user_inatomic_nocache(kaddr + offset, buf, bytes);
- kunmap_atomic(kaddr, KM_USER0);
-
- if (left != 0) {
- /* Do it the slow way */
- kaddr = kmap(page);
- left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
- kunmap(page);
- }
- return bytes - left;
-}
-
-/*
- * This has the same sideeffects and return value as filemap_copy_from_user().
- * The difference is that on a fault we need to memset the remainder of the
- * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
- * single-segment behaviour.
- */
-static inline size_t
-filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
- const struct iovec *iov, size_t base, size_t bytes)
-{
- char *kaddr;
- size_t copied;
-
- kaddr = kmap_atomic(page, KM_USER0);
- copied = __filemap_copy_from_user_iovec_inatomic(kaddr + offset, iov,
- base, bytes);
- kunmap_atomic(kaddr, KM_USER0);
- if (copied != bytes) {
- kaddr = kmap(page);
- copied = __filemap_copy_from_user_iovec_inatomic(kaddr + offset, iov,
- base, bytes);
- if (bytes - copied)
- memset(kaddr + offset + copied, 0, bytes - copied);
- kunmap(page);
- }
- return copied;
-}
-
-static inline void
-filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
-{
- const struct iovec *iov = *iovp;
- size_t base = *basep;
-
- do {
- int copy = min(bytes, iov->iov_len - base);
-
- bytes -= copy;
- base += copy;
- if (iov->iov_len == base) {
- iov++;
- base = 0;
- }
- } while (bytes);
- *iovp = iov;
- *basep = base;
-}
-#endif
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 53ee6a29963..32132f3cd64 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -15,7 +15,6 @@
#include <linux/rmap.h>
#include <linux/sched.h>
#include <asm/tlbflush.h>
-#include "filemap.h"
/*
* We do use our own empty page to avoid interference with other users
@@ -288,6 +287,7 @@ __xip_file_write(struct file *filp, const char __user *buf,
unsigned long index;
unsigned long offset;
size_t copied;
+ char *kaddr;
offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
index = pos >> PAGE_CACHE_SHIFT;
@@ -295,14 +295,6 @@ __xip_file_write(struct file *filp, const char __user *buf,
if (bytes > count)
bytes = count;
- /*
- * Bring in the user page that we will copy from _first_.
- * Otherwise there's a nasty deadlock on copying from the
- * same page as we're writing to, without it being marked
- * up-to-date.
- */
- fault_in_pages_readable(buf, bytes);
-
page = a_ops->get_xip_page(mapping,
index*(PAGE_SIZE/512), 0);
if (IS_ERR(page) && (PTR_ERR(page) == -ENODATA)) {
@@ -319,8 +311,13 @@ __xip_file_write(struct file *filp, const char __user *buf,
break;
}
- copied = filemap_copy_from_user(page, offset, buf, bytes);
+ fault_in_pages_readable(buf, bytes);
+ kaddr = kmap_atomic(page, KM_USER0);
+ copied = bytes -
+ __copy_from_user_inatomic_nocache(kaddr, buf, bytes);
+ kunmap_atomic(kaddr, KM_USER0);
flush_dcache_page(page);
+
if (likely(copied > 0)) {
status = copied;
diff --git a/mm/fremap.c b/mm/fremap.c
index 95bcb5641c7..14bd3bf7826 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -5,7 +5,7 @@
*
* started by Ingo Molnar, Copyright (C) 2002, 2003
*/
-
+#include <linux/backing-dev.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/file.h>
@@ -97,26 +97,28 @@ static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
}
-/***
- * sys_remap_file_pages - remap arbitrary pages of a shared backing store
- * file within an existing vma.
+/**
+ * sys_remap_file_pages - remap arbitrary pages of an existing VM_SHARED vma
* @start: start of the remapped virtual memory range
* @size: size of the remapped virtual memory range
- * @prot: new protection bits of the range
- * @pgoff: to be mapped page of the backing store file
+ * @prot: new protection bits of the range (see NOTE)
+ * @pgoff: to-be-mapped page of the backing store file
* @flags: 0 or MAP_NONBLOCKED - the later will cause no IO.
*
- * this syscall works purely via pagetables, so it's the most efficient
+ * sys_remap_file_pages remaps arbitrary pages of an existing VM_SHARED vma
+ * (shared backing store file).
+ *
+ * This syscall works purely via pagetables, so it's the most efficient
* way to map the same (large) file into a given virtual window. Unlike
* mmap()/mremap() it does not create any new vmas. The new mappings are
* also safe across swapout.
*
- * NOTE: the 'prot' parameter right now is ignored, and the vma's default
- * protection is used. Arbitrary protections might be implemented in the
- * future.
+ * NOTE: the 'prot' parameter right now is ignored (but must be zero),
+ * and the vma's default protection is used. Arbitrary protections
+ * might be implemented in the future.
*/
asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
- unsigned long __prot, unsigned long pgoff, unsigned long flags)
+ unsigned long prot, unsigned long pgoff, unsigned long flags)
{
struct mm_struct *mm = current->mm;
struct address_space *mapping;
@@ -125,7 +127,7 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
int err = -EINVAL;
int has_write_lock = 0;
- if (__prot)
+ if (prot)
return err;
/*
* Sanitize the syscall parameters:
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index eab8c428cc9..034617f8cdb 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -23,12 +23,16 @@
const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
static unsigned long nr_huge_pages, free_huge_pages, resv_huge_pages;
+static unsigned long surplus_huge_pages;
unsigned long max_huge_pages;
static struct list_head hugepage_freelists[MAX_NUMNODES];
static unsigned int nr_huge_pages_node[MAX_NUMNODES];
static unsigned int free_huge_pages_node[MAX_NUMNODES];
+static unsigned int surplus_huge_pages_node[MAX_NUMNODES];
static gfp_t htlb_alloc_mask = GFP_HIGHUSER;
unsigned long hugepages_treat_as_movable;
+int hugetlb_dynamic_pool;
+static int hugetlb_next_nid;
/*
* Protects updates to hugepage_freelists, nr_huge_pages, and free_huge_pages
@@ -85,6 +89,8 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
list_del(&page->lru);
free_huge_pages--;
free_huge_pages_node[nid]--;
+ if (vma && vma->vm_flags & VM_MAYSHARE)
+ resv_huge_pages--;
break;
}
}
@@ -92,58 +98,269 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
return page;
}
+static void update_and_free_page(struct page *page)
+{
+ int i;
+ nr_huge_pages--;
+ nr_huge_pages_node[page_to_nid(page)]--;
+ for (i = 0; i < (HPAGE_SIZE / PAGE_SIZE); i++) {
+ page[i].flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
+ 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
+ 1 << PG_private | 1<< PG_writeback);
+ }
+ set_compound_page_dtor(page, NULL);
+ set_page_refcounted(page);
+ __free_pages(page, HUGETLB_PAGE_ORDER);
+}
+
static void free_huge_page(struct page *page)
{
- BUG_ON(page_count(page));
+ int nid = page_to_nid(page);
+ BUG_ON(page_count(page));
INIT_LIST_HEAD(&page->lru);
spin_lock(&hugetlb_lock);
- enqueue_huge_page(page);
+ if (surplus_huge_pages_node[nid]) {
+ update_and_free_page(page);
+ surplus_huge_pages--;
+ surplus_huge_pages_node[nid]--;
+ } else {
+ enqueue_huge_page(page);
+ }
spin_unlock(&hugetlb_lock);
}
-static int alloc_fresh_huge_page(void)
+/*
+ * Increment or decrement surplus_huge_pages. Keep node-specific counters
+ * balanced by operating on them in a round-robin fashion.
+ * Returns 1 if an adjustment was made.
+ */
+static int adjust_pool_surplus(int delta)
{
static int prev_nid;
- struct page *page;
- int nid;
+ int nid = prev_nid;
+ int ret = 0;
+
+ VM_BUG_ON(delta != -1 && delta != 1);
+ do {
+ nid = next_node(nid, node_online_map);
+ if (nid == MAX_NUMNODES)
+ nid = first_node(node_online_map);
+
+ /* To shrink on this node, there must be a surplus page */
+ if (delta < 0 && !surplus_huge_pages_node[nid])
+ continue;
+ /* Surplus cannot exceed the total number of pages */
+ if (delta > 0 && surplus_huge_pages_node[nid] >=
+ nr_huge_pages_node[nid])
+ continue;
+
+ surplus_huge_pages += delta;
+ surplus_huge_pages_node[nid] += delta;
+ ret = 1;
+ break;
+ } while (nid != prev_nid);
- /*
- * Copy static prev_nid to local nid, work on that, then copy it
- * back to prev_nid afterwards: otherwise there's a window in which
- * a racer might pass invalid nid MAX_NUMNODES to alloc_pages_node.
- * But we don't need to use a spin_lock here: it really doesn't
- * matter if occasionally a racer chooses the same nid as we do.
- */
- nid = next_node(prev_nid, node_online_map);
- if (nid == MAX_NUMNODES)
- nid = first_node(node_online_map);
prev_nid = nid;
+ return ret;
+}
+
+static struct page *alloc_fresh_huge_page_node(int nid)
+{
+ struct page *page;
- page = alloc_pages_node(nid, htlb_alloc_mask|__GFP_COMP|__GFP_NOWARN,
+ page = alloc_pages_node(nid,
+ htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE|__GFP_NOWARN,
+ HUGETLB_PAGE_ORDER);
+ if (page) {
+ set_compound_page_dtor(page, free_huge_page);
+ spin_lock(&hugetlb_lock);
+ nr_huge_pages++;
+ nr_huge_pages_node[nid]++;
+ spin_unlock(&hugetlb_lock);
+ put_page(page); /* free it into the hugepage allocator */
+ }
+
+ return page;
+}
+
+static int alloc_fresh_huge_page(void)
+{
+ struct page *page;
+ int start_nid;
+ int next_nid;
+ int ret = 0;
+
+ start_nid = hugetlb_next_nid;
+
+ do {
+ page = alloc_fresh_huge_page_node(hugetlb_next_nid);
+ if (page)
+ ret = 1;
+ /*
+ * Use a helper variable to find the next node and then
+ * copy it back to hugetlb_next_nid afterwards:
+ * otherwise there's a window in which a racer might
+ * pass invalid nid MAX_NUMNODES to alloc_pages_node.
+ * But we don't need to use a spin_lock here: it really
+ * doesn't matter if occasionally a racer chooses the
+ * same nid as we do. Move nid forward in the mask even
+ * if we just successfully allocated a hugepage so that
+ * the next caller gets hugepages on the next node.
+ */
+ next_nid = next_node(hugetlb_next_nid, node_online_map);
+ if (next_nid == MAX_NUMNODES)
+ next_nid = first_node(node_online_map);
+ hugetlb_next_nid = next_nid;
+ } while (!page && hugetlb_next_nid != start_nid);
+
+ return ret;
+}
+
+static struct page *alloc_buddy_huge_page(struct vm_area_struct *vma,
+ unsigned long address)
+{
+ struct page *page;
+
+ /* Check if the dynamic pool is enabled */
+ if (!hugetlb_dynamic_pool)
+ return NULL;
+
+ page = alloc_pages(htlb_alloc_mask|__GFP_COMP|__GFP_NOWARN,
HUGETLB_PAGE_ORDER);
if (page) {
set_compound_page_dtor(page, free_huge_page);
spin_lock(&hugetlb_lock);
nr_huge_pages++;
nr_huge_pages_node[page_to_nid(page)]++;
+ surplus_huge_pages++;
+ surplus_huge_pages_node[page_to_nid(page)]++;
spin_unlock(&hugetlb_lock);
- put_page(page); /* free it into the hugepage allocator */
- return 1;
}
- return 0;
+
+ return page;
+}
+
+/*
+ * Increase the hugetlb pool such that it can accomodate a reservation
+ * of size 'delta'.
+ */
+static int gather_surplus_pages(int delta)
+{
+ struct list_head surplus_list;
+ struct page *page, *tmp;
+ int ret, i;
+ int needed, allocated;
+
+ needed = (resv_huge_pages + delta) - free_huge_pages;
+ if (needed <= 0)
+ return 0;
+
+ allocated = 0;
+ INIT_LIST_HEAD(&surplus_list);
+
+ ret = -ENOMEM;
+retry:
+ spin_unlock(&hugetlb_lock);
+ for (i = 0; i < needed; i++) {
+ page = alloc_buddy_huge_page(NULL, 0);
+ if (!page) {
+ /*
+ * We were not able to allocate enough pages to
+ * satisfy the entire reservation so we free what
+ * we've allocated so far.
+ */
+ spin_lock(&hugetlb_lock);
+ needed = 0;
+ goto free;
+ }
+
+ list_add(&page->lru, &surplus_list);
+ }
+ allocated += needed;
+
+ /*
+ * After retaking hugetlb_lock, we need to recalculate 'needed'
+ * because either resv_huge_pages or free_huge_pages may have changed.
+ */
+ spin_lock(&hugetlb_lock);
+ needed = (resv_huge_pages + delta) - (free_huge_pages + allocated);
+ if (needed > 0)
+ goto retry;
+
+ /*
+ * The surplus_list now contains _at_least_ the number of extra pages
+ * needed to accomodate the reservation. Add the appropriate number
+ * of pages to the hugetlb pool and free the extras back to the buddy
+ * allocator.
+ */
+ needed += allocated;
+ ret = 0;
+free:
+ list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
+ list_del(&page->lru);
+ if ((--needed) >= 0)
+ enqueue_huge_page(page);
+ else {
+ /*
+ * Decrement the refcount and free the page using its
+ * destructor. This must be done with hugetlb_lock
+ * unlocked which is safe because free_huge_page takes
+ * hugetlb_lock before deciding how to free the page.
+ */
+ spin_unlock(&hugetlb_lock);
+ put_page(page);
+ spin_lock(&hugetlb_lock);
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * When releasing a hugetlb pool reservation, any surplus pages that were
+ * allocated to satisfy the reservation must be explicitly freed if they were
+ * never used.
+ */
+void return_unused_surplus_pages(unsigned long unused_resv_pages)
+{
+ static int nid = -1;
+ struct page *page;
+ unsigned long nr_pages;
+
+ nr_pages = min(unused_resv_pages, surplus_huge_pages);
+
+ while (nr_pages) {
+ nid = next_node(nid, node_online_map);
+ if (nid == MAX_NUMNODES)
+ nid = first_node(node_online_map);
+
+ if (!surplus_huge_pages_node[nid])
+ continue;
+
+ if (!list_empty(&hugepage_freelists[nid])) {
+ page = list_entry(hugepage_freelists[nid].next,
+ struct page, lru);
+ list_del(&page->lru);
+ update_and_free_page(page);
+ free_huge_pages--;
+ free_huge_pages_node[nid]--;
+ surplus_huge_pages--;
+ surplus_huge_pages_node[nid]--;
+ nr_pages--;
+ }
+ }
}
static struct page *alloc_huge_page(struct vm_area_struct *vma,
unsigned long addr)
{
- struct page *page;
+ struct page *page = NULL;
+ int use_reserved_page = vma->vm_flags & VM_MAYSHARE;
spin_lock(&hugetlb_lock);
- if (vma->vm_flags & VM_MAYSHARE)
- resv_huge_pages--;
- else if (free_huge_pages <= resv_huge_pages)
+ if (!use_reserved_page && (free_huge_pages <= resv_huge_pages))
goto fail;
page = dequeue_huge_page(vma, addr);
@@ -155,10 +372,17 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma,
return page;
fail:
- if (vma->vm_flags & VM_MAYSHARE)
- resv_huge_pages++;
spin_unlock(&hugetlb_lock);
- return NULL;
+
+ /*
+ * Private mappings do not use reserved huge pages so the allocation
+ * may have failed due to an undersized hugetlb pool. Try to grab a
+ * surplus huge page from the buddy allocator.
+ */
+ if (!use_reserved_page)
+ page = alloc_buddy_huge_page(vma, addr);
+
+ return page;
}
static int __init hugetlb_init(void)
@@ -171,6 +395,8 @@ static int __init hugetlb_init(void)
for (i = 0; i < MAX_NUMNODES; ++i)
INIT_LIST_HEAD(&hugepage_freelists[i]);
+ hugetlb_next_nid = first_node(node_online_map);
+
for (i = 0; i < max_huge_pages; ++i) {
if (!alloc_fresh_huge_page())
break;
@@ -201,21 +427,6 @@ static unsigned int cpuset_mems_nr(unsigned int *array)
}
#ifdef CONFIG_SYSCTL
-static void update_and_free_page(struct page *page)
-{
- int i;
- nr_huge_pages--;
- nr_huge_pages_node[page_to_nid(page)]--;
- for (i = 0; i < (HPAGE_SIZE / PAGE_SIZE); i++) {
- page[i].flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
- 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
- 1 << PG_private | 1<< PG_writeback);
- }
- set_compound_page_dtor(page, NULL);
- set_page_refcounted(page);
- __free_pages(page, HUGETLB_PAGE_ORDER);
-}
-
#ifdef CONFIG_HIGHMEM
static void try_to_free_low(unsigned long count)
{
@@ -224,14 +435,14 @@ static void try_to_free_low(unsigned long count)
for (i = 0; i < MAX_NUMNODES; ++i) {
struct page *page, *next;
list_for_each_entry_safe(page, next, &hugepage_freelists[i], lru) {
+ if (count >= nr_huge_pages)
+ return;
if (PageHighMem(page))
continue;
list_del(&page->lru);
update_and_free_page(page);
free_huge_pages--;
free_huge_pages_node[page_to_nid(page)]--;
- if (count >= nr_huge_pages)
- return;
}
}
}
@@ -241,26 +452,61 @@ static inline void try_to_free_low(unsigned long count)
}
#endif
+#define persistent_huge_pages (nr_huge_pages - surplus_huge_pages)
static unsigned long set_max_huge_pages(unsigned long count)
{
- while (count > nr_huge_pages) {
- if (!alloc_fresh_huge_page())
- return nr_huge_pages;
- }
- if (count >= nr_huge_pages)
- return nr_huge_pages;
+ unsigned long min_count, ret;
+ /*
+ * Increase the pool size
+ * First take pages out of surplus state. Then make up the
+ * remaining difference by allocating fresh huge pages.
+ */
spin_lock(&hugetlb_lock);
- count = max(count, resv_huge_pages);
- try_to_free_low(count);
- while (count < nr_huge_pages) {
+ while (surplus_huge_pages && count > persistent_huge_pages) {
+ if (!adjust_pool_surplus(-1))
+ break;
+ }
+
+ while (count > persistent_huge_pages) {
+ int ret;
+ /*
+ * If this allocation races such that we no longer need the
+ * page, free_huge_page will handle it by freeing the page
+ * and reducing the surplus.
+ */
+ spin_unlock(&hugetlb_lock);
+ ret = alloc_fresh_huge_page();
+ spin_lock(&hugetlb_lock);
+ if (!ret)
+ goto out;
+
+ }
+
+ /*
+ * Decrease the pool size
+ * First return free pages to the buddy allocator (being careful
+ * to keep enough around to satisfy reservations). Then place
+ * pages into surplus state as needed so the pool will shrink
+ * to the desired size as pages become free.
+ */
+ min_count = resv_huge_pages + nr_huge_pages - free_huge_pages;
+ min_count = max(count, min_count);
+ try_to_free_low(min_count);
+ while (min_count < persistent_huge_pages) {
struct page *page = dequeue_huge_page(NULL, 0);
if (!page)
break;
update_and_free_page(page);
}
+ while (count < persistent_huge_pages) {
+ if (!adjust_pool_surplus(1))
+ break;
+ }
+out:
+ ret = persistent_huge_pages;
spin_unlock(&hugetlb_lock);
- return nr_huge_pages;
+ return ret;
}
int hugetlb_sysctl_handler(struct ctl_table *table, int write,
@@ -292,10 +538,12 @@ int hugetlb_report_meminfo(char *buf)
"HugePages_Total: %5lu\n"
"HugePages_Free: %5lu\n"
"HugePages_Rsvd: %5lu\n"
+ "HugePages_Surp: %5lu\n"
"Hugepagesize: %5lu kB\n",
nr_huge_pages,
free_huge_pages,
resv_huge_pages,
+ surplus_huge_pages,
HPAGE_SIZE/1024);
}
@@ -355,7 +603,6 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma,
entry = pte_mkwrite(pte_mkdirty(*ptep));
if (ptep_set_access_flags(vma, address, ptep, entry, 1)) {
update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
}
}
@@ -708,7 +955,6 @@ void hugetlb_change_protection(struct vm_area_struct *vma,
pte = huge_ptep_get_and_clear(mm, address, ptep);
pte = pte_mkhuge(pte_modify(pte, newprot));
set_huge_pte_at(mm, address, ptep, pte);
- lazy_mmu_prot_update(pte);
}
}
spin_unlock(&mm->page_table_lock);
@@ -774,7 +1020,7 @@ static long region_chg(struct list_head *head, long f, long t)
* size such that we can guarentee to record the reservation. */
if (&rg->link == head || t < rg->from) {
nrg = kmalloc(sizeof(*nrg), GFP_KERNEL);
- if (nrg == 0)
+ if (!nrg)
return -ENOMEM;
nrg->from = f;
nrg->to = f;
@@ -843,21 +1089,6 @@ static int hugetlb_acct_memory(long delta)
int ret = -ENOMEM;
spin_lock(&hugetlb_lock);
- if ((delta + resv_huge_pages) <= free_huge_pages) {
- resv_huge_pages += delta;
- ret = 0;
- }
- spin_unlock(&hugetlb_lock);
- return ret;
-}
-
-int hugetlb_reserve_pages(struct inode *inode, long from, long to)
-{
- long ret, chg;
-
- chg = region_chg(&inode->i_mapping->private_list, from, to);
- if (chg < 0)
- return chg;
/*
* When cpuset is configured, it breaks the strict hugetlb page
* reservation as the accounting is done on a global variable. Such
@@ -875,8 +1106,31 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
* a best attempt and hopefully to minimize the impact of changing
* semantics that cpuset has.
*/
- if (chg > cpuset_mems_nr(free_huge_pages_node))
- return -ENOMEM;
+ if (delta > 0) {
+ if (gather_surplus_pages(delta) < 0)
+ goto out;
+
+ if (delta > cpuset_mems_nr(free_huge_pages_node))
+ goto out;
+ }
+
+ ret = 0;
+ resv_huge_pages += delta;
+ if (delta < 0)
+ return_unused_surplus_pages((unsigned long) -delta);
+
+out:
+ spin_unlock(&hugetlb_lock);
+ return ret;
+}
+
+int hugetlb_reserve_pages(struct inode *inode, long from, long to)
+{
+ long ret, chg;
+
+ chg = region_chg(&inode->i_mapping->private_list, from, to);
+ if (chg < 0)
+ return chg;
ret = hugetlb_acct_memory(chg);
if (ret < 0)
diff --git a/mm/internal.h b/mm/internal.h
index a3110c02aea..953f941ea86 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -37,4 +37,14 @@ static inline void __put_page(struct page *page)
extern void fastcall __init __free_pages_bootmem(struct page *page,
unsigned int order);
+/*
+ * function for dealing with page's order in buddy system.
+ * zone->lock is already acquired when we use these.
+ * So, we don't need atomic page->flags operations here.
+ */
+static inline unsigned long page_order(struct page *page)
+{
+ VM_BUG_ON(!PageBuddy(page));
+ return page_private(page);
+}
#endif
diff --git a/mm/memory.c b/mm/memory.c
index f82b359b274..bd16dcaeefb 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -966,7 +966,7 @@ no_page_table:
* has touched so far, we don't want to allocate page tables.
*/
if (flags & FOLL_ANON) {
- page = ZERO_PAGE(address);
+ page = ZERO_PAGE(0);
if (flags & FOLL_GET)
get_page(page);
BUG_ON(flags & FOLL_WRITE);
@@ -1111,95 +1111,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
}
EXPORT_SYMBOL(get_user_pages);
-static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr, unsigned long end, pgprot_t prot)
-{
- pte_t *pte;
- spinlock_t *ptl;
- int err = 0;
-
- pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
- if (!pte)
- return -EAGAIN;
- arch_enter_lazy_mmu_mode();
- do {
- struct page *page = ZERO_PAGE(addr);
- pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
-
- if (unlikely(!pte_none(*pte))) {
- err = -EEXIST;
- pte++;
- break;
- }
- page_cache_get(page);
- page_add_file_rmap(page);
- inc_mm_counter(mm, file_rss);
- set_pte_at(mm, addr, pte, zero_pte);
- } while (pte++, addr += PAGE_SIZE, addr != end);
- arch_leave_lazy_mmu_mode();
- pte_unmap_unlock(pte - 1, ptl);
- return err;
-}
-
-static inline int zeromap_pmd_range(struct mm_struct *mm, pud_t *pud,
- unsigned long addr, unsigned long end, pgprot_t prot)
-{
- pmd_t *pmd;
- unsigned long next;
- int err;
-
- pmd = pmd_alloc(mm, pud, addr);
- if (!pmd)
- return -EAGAIN;
- do {
- next = pmd_addr_end(addr, end);
- err = zeromap_pte_range(mm, pmd, addr, next, prot);
- if (err)
- break;
- } while (pmd++, addr = next, addr != end);
- return err;
-}
-
-static inline int zeromap_pud_range(struct mm_struct *mm, pgd_t *pgd,
- unsigned long addr, unsigned long end, pgprot_t prot)
-{
- pud_t *pud;
- unsigned long next;
- int err;
-
- pud = pud_alloc(mm, pgd, addr);
- if (!pud)
- return -EAGAIN;
- do {
- next = pud_addr_end(addr, end);
- err = zeromap_pmd_range(mm, pud, addr, next, prot);
- if (err)
- break;
- } while (pud++, addr = next, addr != end);
- return err;
-}
-
-int zeromap_page_range(struct vm_area_struct *vma,
- unsigned long addr, unsigned long size, pgprot_t prot)
-{
- pgd_t *pgd;
- unsigned long next;
- unsigned long end = addr + size;
- struct mm_struct *mm = vma->vm_mm;
- int err;
-
- BUG_ON(addr >= end);
- pgd = pgd_offset(mm, addr);
- flush_cache_range(vma, addr, end);
- do {
- next = pgd_addr_end(addr, end);
- err = zeromap_pud_range(mm, pgd, addr, next, prot);
- if (err)
- break;
- } while (pgd++, addr = next, addr != end);
- return err;
-}
-
pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)
{
pgd_t * pgd = pgd_offset(mm, addr);
@@ -1700,10 +1611,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
flush_cache_page(vma, address, pte_pfn(orig_pte));
entry = pte_mkyoung(orig_pte);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
- if (ptep_set_access_flags(vma, address, page_table, entry,1)) {
+ if (ptep_set_access_flags(vma, address, page_table, entry,1))
update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
- }
ret |= VM_FAULT_WRITE;
goto unlock;
}
@@ -1717,16 +1626,11 @@ gotten:
if (unlikely(anon_vma_prepare(vma)))
goto oom;
- if (old_page == ZERO_PAGE(address)) {
- new_page = alloc_zeroed_user_highpage_movable(vma, address);
- if (!new_page)
- goto oom;
- } else {
- new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
- if (!new_page)
- goto oom;
- cow_user_page(new_page, old_page, address, vma);
- }
+ VM_BUG_ON(old_page == ZERO_PAGE(0));
+ new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
+ if (!new_page)
+ goto oom;
+ cow_user_page(new_page, old_page, address, vma);
/*
* Re-check the pte - we dropped the lock
@@ -1744,7 +1648,6 @@ gotten:
flush_cache_page(vma, address, pte_pfn(orig_pte));
entry = mk_pte(new_page, vma->vm_page_prot);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
- lazy_mmu_prot_update(entry);
/*
* Clear the pte entry and flush it first, before updating the
* pte with the new entry. This will avoid a race condition
@@ -2252,44 +2155,28 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
spinlock_t *ptl;
pte_t entry;
- if (write_access) {
- /* Allocate our own private page. */
- pte_unmap(page_table);
-
- if (unlikely(anon_vma_prepare(vma)))
- goto oom;
- page = alloc_zeroed_user_highpage_movable(vma, address);
- if (!page)
- goto oom;
-
- entry = mk_pte(page, vma->vm_page_prot);
- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ /* Allocate our own private page. */
+ pte_unmap(page_table);
- page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
- if (!pte_none(*page_table))
- goto release;
- inc_mm_counter(mm, anon_rss);
- lru_cache_add_active(page);
- page_add_new_anon_rmap(page, vma, address);
- } else {
- /* Map the ZERO_PAGE - vm_page_prot is readonly */
- page = ZERO_PAGE(address);
- page_cache_get(page);
- entry = mk_pte(page, vma->vm_page_prot);
+ if (unlikely(anon_vma_prepare(vma)))
+ goto oom;
+ page = alloc_zeroed_user_highpage_movable(vma, address);
+ if (!page)
+ goto oom;
- ptl = pte_lockptr(mm, pmd);
- spin_lock(ptl);
- if (!pte_none(*page_table))
- goto release;
- inc_mm_counter(mm, file_rss);
- page_add_file_rmap(page);
- }
+ entry = mk_pte(page, vma->vm_page_prot);
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
+ if (!pte_none(*page_table))
+ goto release;
+ inc_mm_counter(mm, anon_rss);
+ lru_cache_add_active(page);
+ page_add_new_anon_rmap(page, vma, address);
set_pte_at(mm, address, page_table, entry);
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
unlock:
pte_unmap_unlock(page_table, ptl);
return 0;
@@ -2442,7 +2329,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
/* no need to invalidate: a not-present page won't be cached */
update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
} else {
if (anon)
page_cache_release(page);
@@ -2470,7 +2356,7 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
int write_access, pte_t orig_pte)
{
pgoff_t pgoff = (((address & PAGE_MASK)
- - vma->vm_start) >> PAGE_CACHE_SHIFT) + vma->vm_pgoff;
+ - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
unsigned int flags = (write_access ? FAULT_FLAG_WRITE : 0);
pte_unmap(page_table);
@@ -2614,7 +2500,6 @@ static inline int handle_pte_fault(struct mm_struct *mm,
entry = pte_mkyoung(entry);
if (ptep_set_access_flags(vma, address, pte, entry, write_access)) {
update_mmu_cache(vma, address, entry);
- lazy_mmu_prot_update(entry);
} else {
/*
* This is needed only for protection faults but the arch code
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index df9d554bea3..091b9c6c252 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -23,6 +23,9 @@
#include <linux/vmalloc.h>
#include <linux/ioport.h>
#include <linux/cpuset.h>
+#include <linux/delay.h>
+#include <linux/migrate.h>
+#include <linux/page-isolation.h>
#include <asm/tlbflush.h>
@@ -161,14 +164,27 @@ static void grow_pgdat_span(struct pglist_data *pgdat,
pgdat->node_start_pfn;
}
-int online_pages(unsigned long pfn, unsigned long nr_pages)
+static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages,
+ void *arg)
{
unsigned long i;
+ unsigned long onlined_pages = *(unsigned long *)arg;
+ struct page *page;
+ if (PageReserved(pfn_to_page(start_pfn)))
+ for (i = 0; i < nr_pages; i++) {
+ page = pfn_to_page(start_pfn + i);
+ online_page(page);
+ onlined_pages++;
+ }
+ *(unsigned long *)arg = onlined_pages;
+ return 0;
+}
+
+
+int online_pages(unsigned long pfn, unsigned long nr_pages)
+{
unsigned long flags;
unsigned long onlined_pages = 0;
- struct resource res;
- u64 section_end;
- unsigned long start_pfn;
struct zone *zone;
int need_zonelists_rebuild = 0;
@@ -191,32 +207,16 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
if (!populated_zone(zone))
need_zonelists_rebuild = 1;
- res.start = (u64)pfn << PAGE_SHIFT;
- res.end = res.start + ((u64)nr_pages << PAGE_SHIFT) - 1;
- res.flags = IORESOURCE_MEM; /* we just need system ram */
- section_end = res.end;
-
- while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
- start_pfn = (unsigned long)(res.start >> PAGE_SHIFT);
- nr_pages = (unsigned long)
- ((res.end + 1 - res.start) >> PAGE_SHIFT);
-
- if (PageReserved(pfn_to_page(start_pfn))) {
- /* this region's page is not onlined now */
- for (i = 0; i < nr_pages; i++) {
- struct page *page = pfn_to_page(start_pfn + i);
- online_page(page);
- onlined_pages++;
- }
- }
-
- res.start = res.end + 1;
- res.end = section_end;
- }
+ walk_memory_resource(pfn, nr_pages, &onlined_pages,
+ online_pages_range);
zone->present_pages += onlined_pages;
zone->zone_pgdat->node_present_pages += onlined_pages;
setup_per_zone_pages_min();
+ if (onlined_pages) {
+ kswapd_run(zone_to_nid(zone));
+ node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
+ }
if (need_zonelists_rebuild)
build_all_zonelists();
@@ -271,9 +271,6 @@ int add_memory(int nid, u64 start, u64 size)
if (!pgdat)
return -ENOMEM;
new_pgdat = 1;
- ret = kswapd_run(nid);
- if (ret)
- goto error;
}
/* call arch's memory hotadd */
@@ -308,3 +305,260 @@ error:
return ret;
}
EXPORT_SYMBOL_GPL(add_memory);
+
+#ifdef CONFIG_MEMORY_HOTREMOVE
+/*
+ * Confirm all pages in a range [start, end) is belongs to the same zone.
+ */
+static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long pfn;
+ struct zone *zone = NULL;
+ struct page *page;
+ int i;
+ for (pfn = start_pfn;
+ pfn < end_pfn;
+ pfn += MAX_ORDER_NR_PAGES) {
+ i = 0;
+ /* This is just a CONFIG_HOLES_IN_ZONE check.*/
+ while ((i < MAX_ORDER_NR_PAGES) && !pfn_valid_within(pfn + i))
+ i++;
+ if (i == MAX_ORDER_NR_PAGES)
+ continue;
+ page = pfn_to_page(pfn + i);
+ if (zone && page_zone(page) != zone)
+ return 0;
+ zone = page_zone(page);
+ }
+ return 1;
+}
+
+/*
+ * Scanning pfn is much easier than scanning lru list.
+ * Scan pfn from start to end and Find LRU page.
+ */
+int scan_lru_pages(unsigned long start, unsigned long end)
+{
+ unsigned long pfn;
+ struct page *page;
+ for (pfn = start; pfn < end; pfn++) {
+ if (pfn_valid(pfn)) {
+ page = pfn_to_page(pfn);
+ if (PageLRU(page))
+ return pfn;
+ }
+ }
+ return 0;
+}
+
+static struct page *
+hotremove_migrate_alloc(struct page *page,
+ unsigned long private,
+ int **x)
+{
+ /* This should be improoooooved!! */
+ return alloc_page(GFP_HIGHUSER_PAGECACHE);
+}
+
+
+#define NR_OFFLINE_AT_ONCE_PAGES (256)
+static int
+do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long pfn;
+ struct page *page;
+ int move_pages = NR_OFFLINE_AT_ONCE_PAGES;
+ int not_managed = 0;
+ int ret = 0;
+ LIST_HEAD(source);
+
+ for (pfn = start_pfn; pfn < end_pfn && move_pages > 0; pfn++) {
+ if (!pfn_valid(pfn))
+ continue;
+ page = pfn_to_page(pfn);
+ if (!page_count(page))
+ continue;
+ /*
+ * We can skip free pages. And we can only deal with pages on
+ * LRU.
+ */
+ ret = isolate_lru_page(page, &source);
+ if (!ret) { /* Success */
+ move_pages--;
+ } else {
+ /* Becasue we don't have big zone->lock. we should
+ check this again here. */
+ if (page_count(page))
+ not_managed++;
+#ifdef CONFIG_DEBUG_VM
+ printk(KERN_INFO "removing from LRU failed"
+ " %lx/%d/%lx\n",
+ pfn, page_count(page), page->flags);
+#endif
+ }
+ }
+ ret = -EBUSY;
+ if (not_managed) {
+ if (!list_empty(&source))
+ putback_lru_pages(&source);
+ goto out;
+ }
+ ret = 0;
+ if (list_empty(&source))
+ goto out;
+ /* this function returns # of failed pages */
+ ret = migrate_pages(&source, hotremove_migrate_alloc, 0);
+
+out:
+ return ret;
+}
+
+/*
+ * remove from free_area[] and mark all as Reserved.
+ */
+static int
+offline_isolated_pages_cb(unsigned long start, unsigned long nr_pages,
+ void *data)
+{
+ __offline_isolated_pages(start, start + nr_pages);
+ return 0;
+}
+
+static void
+offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
+{
+ walk_memory_resource(start_pfn, end_pfn - start_pfn, NULL,
+ offline_isolated_pages_cb);
+}
+
+/*
+ * Check all pages in range, recoreded as memory resource, are isolated.
+ */
+static int
+check_pages_isolated_cb(unsigned long start_pfn, unsigned long nr_pages,
+ void *data)
+{
+ int ret;
+ long offlined = *(long *)data;
+ ret = test_pages_isolated(start_pfn, start_pfn + nr_pages);
+ offlined = nr_pages;
+ if (!ret)
+ *(long *)data += offlined;
+ return ret;
+}
+
+static long
+check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
+{
+ long offlined = 0;
+ int ret;
+
+ ret = walk_memory_resource(start_pfn, end_pfn - start_pfn, &offlined,
+ check_pages_isolated_cb);
+ if (ret < 0)
+ offlined = (long)ret;
+ return offlined;
+}
+
+extern void drain_all_local_pages(void);
+
+int offline_pages(unsigned long start_pfn,
+ unsigned long end_pfn, unsigned long timeout)
+{
+ unsigned long pfn, nr_pages, expire;
+ long offlined_pages;
+ int ret, drain, retry_max;
+ struct zone *zone;
+
+ BUG_ON(start_pfn >= end_pfn);
+ /* at least, alignment against pageblock is necessary */
+ if (!IS_ALIGNED(start_pfn, pageblock_nr_pages))
+ return -EINVAL;
+ if (!IS_ALIGNED(end_pfn, pageblock_nr_pages))
+ return -EINVAL;
+ /* This makes hotplug much easier...and readable.
+ we assume this for now. .*/
+ if (!test_pages_in_a_zone(start_pfn, end_pfn))
+ return -EINVAL;
+ /* set above range as isolated */
+ ret = start_isolate_page_range(start_pfn, end_pfn);
+ if (ret)
+ return ret;
+ nr_pages = end_pfn - start_pfn;
+ pfn = start_pfn;
+ expire = jiffies + timeout;
+ drain = 0;
+ retry_max = 5;
+repeat:
+ /* start memory hot removal */
+ ret = -EAGAIN;
+ if (time_after(jiffies, expire))
+ goto failed_removal;
+ ret = -EINTR;
+ if (signal_pending(current))
+ goto failed_removal;
+ ret = 0;
+ if (drain) {
+ lru_add_drain_all();
+ flush_scheduled_work();
+ cond_resched();
+ drain_all_local_pages();
+ }
+
+ pfn = scan_lru_pages(start_pfn, end_pfn);
+ if (pfn) { /* We have page on LRU */
+ ret = do_migrate_range(pfn, end_pfn);
+ if (!ret) {
+ drain = 1;
+ goto repeat;
+ } else {
+ if (ret < 0)
+ if (--retry_max == 0)
+ goto failed_removal;
+ yield();
+ drain = 1;
+ goto repeat;
+ }
+ }
+ /* drain all zone's lru pagevec, this is asyncronous... */
+ lru_add_drain_all();
+ flush_scheduled_work();
+ yield();
+ /* drain pcp pages , this is synchrouns. */
+ drain_all_local_pages();
+ /* check again */
+ offlined_pages = check_pages_isolated(start_pfn, end_pfn);
+ if (offlined_pages < 0) {
+ ret = -EBUSY;
+ goto failed_removal;
+ }
+ printk(KERN_INFO "Offlined Pages %ld\n", offlined_pages);
+ /* Ok, all of our target is islaoted.
+ We cannot do rollback at this point. */
+ offline_isolated_pages(start_pfn, end_pfn);
+ /* 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();
+ return 0;
+
+failed_removal:
+ printk(KERN_INFO "memory offlining %lx to %lx failed\n",
+ start_pfn, end_pfn);
+ /* pushback to free area */
+ undo_isolate_page_range(start_pfn, end_pfn);
+ return ret;
+}
+#else
+int remove_memory(u64 start, u64 size)
+{
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(remove_memory);
+#endif /* CONFIG_MEMORY_HOTREMOVE */
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 3d6ac9505d0..568152ae6ca 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -72,7 +72,6 @@
#include <linux/hugetlb.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/mm.h>
#include <linux/nodemask.h>
#include <linux/cpuset.h>
#include <linux/gfp.h>
@@ -82,13 +81,13 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/compat.h>
-#include <linux/mempolicy.h>
#include <linux/swap.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/migrate.h>
#include <linux/rmap.h>
#include <linux/security.h>
+#include <linux/syscalls.h>
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
@@ -110,6 +109,9 @@ struct mempolicy default_policy = {
.policy = MPOL_DEFAULT,
};
+static void mpol_rebind_policy(struct mempolicy *pol,
+ const nodemask_t *newmask);
+
/* Do sanity checking on a policy */
static int mpol_check_policy(int mode, nodemask_t *nodes)
{
@@ -128,7 +130,7 @@ static int mpol_check_policy(int mode, nodemask_t *nodes)
return -EINVAL;
break;
}
- return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL;
+ return nodes_subset(*nodes, node_states[N_HIGH_MEMORY]) ? 0 : -EINVAL;
}
/* Generate a custom zonelist for the BIND policy. */
@@ -185,7 +187,9 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
switch (mode) {
case MPOL_INTERLEAVE:
policy->v.nodes = *nodes;
- if (nodes_weight(*nodes) == 0) {
+ nodes_and(policy->v.nodes, policy->v.nodes,
+ node_states[N_HIGH_MEMORY]);
+ if (nodes_weight(policy->v.nodes) == 0) {
kmem_cache_free(policy_cache, policy);
return ERR_PTR(-EINVAL);
}
@@ -459,7 +463,7 @@ static void mpol_set_task_struct_flag(void)
}
/* Set the process memory policy */
-long do_set_mempolicy(int mode, nodemask_t *nodes)
+static long do_set_mempolicy(int mode, nodemask_t *nodes)
{
struct mempolicy *new;
@@ -494,9 +498,9 @@ static void get_zonemask(struct mempolicy *p, nodemask_t *nodes)
*nodes = p->v.nodes;
break;
case MPOL_PREFERRED:
- /* or use current node instead of online map? */
+ /* or use current node instead of memory_map? */
if (p->v.preferred_node < 0)
- *nodes = node_online_map;
+ *nodes = node_states[N_HIGH_MEMORY];
else
node_set(p->v.preferred_node, *nodes);
break;
@@ -519,8 +523,8 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr)
}
/* Retrieve NUMA policy */
-long do_get_mempolicy(int *policy, nodemask_t *nmask,
- unsigned long addr, unsigned long flags)
+static long do_get_mempolicy(int *policy, nodemask_t *nmask,
+ unsigned long addr, unsigned long flags)
{
int err;
struct mm_struct *mm = current->mm;
@@ -528,8 +532,18 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask,
struct mempolicy *pol = current->mempolicy;
cpuset_update_task_memory_state();
- if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
+ if (flags &
+ ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR|MPOL_F_MEMS_ALLOWED))
return -EINVAL;
+
+ if (flags & MPOL_F_MEMS_ALLOWED) {
+ if (flags & (MPOL_F_NODE|MPOL_F_ADDR))
+ return -EINVAL;
+ *policy = 0; /* just so it's initialized */
+ *nmask = cpuset_current_mems_allowed;
+ return 0;
+ }
+
if (flags & MPOL_F_ADDR) {
down_read(&mm->mmap_sem);
vma = find_vma_intersection(mm, addr, addr+1);
@@ -601,7 +615,8 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x
* Migrate pages from one node to a target node.
* Returns error or the number of pages not migrated.
*/
-int migrate_to_node(struct mm_struct *mm, int source, int dest, int flags)
+static int migrate_to_node(struct mm_struct *mm, int source, int dest,
+ int flags)
{
nodemask_t nmask;
LIST_HEAD(pagelist);
@@ -732,8 +747,9 @@ static struct page *new_vma_page(struct page *page, unsigned long private, int *
}
#endif
-long do_mbind(unsigned long start, unsigned long len,
- unsigned long mode, nodemask_t *nmask, unsigned long flags)
+static long do_mbind(unsigned long start, unsigned long len,
+ unsigned long mode, nodemask_t *nmask,
+ unsigned long flags)
{
struct vm_area_struct *vma;
struct mm_struct *mm = current->mm;
@@ -955,7 +971,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
goto out;
}
- if (!nodes_subset(new, node_online_map)) {
+ if (!nodes_subset(new, node_states[N_HIGH_MEMORY])) {
err = -EINVAL;
goto out;
}
@@ -978,7 +994,8 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
unsigned long maxnode,
unsigned long addr, unsigned long flags)
{
- int err, pval;
+ int err;
+ int uninitialized_var(pval);
nodemask_t nodes;
if (nmask != NULL && maxnode < MAX_NUMNODES)
@@ -1527,8 +1544,8 @@ static void sp_delete(struct shared_policy *sp, struct sp_node *n)
kmem_cache_free(sn_cache, n);
}
-struct sp_node *
-sp_alloc(unsigned long start, unsigned long end, struct mempolicy *pol)
+static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
+ struct mempolicy *pol)
{
struct sp_node *n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
@@ -1677,7 +1694,7 @@ void __init numa_policy_init(void)
* fall back to the largest node if they're all smaller.
*/
nodes_clear(interleave_nodes);
- for_each_online_node(nid) {
+ for_each_node_state(nid, N_HIGH_MEMORY) {
unsigned long total_pages = node_present_pages(nid);
/* Preserve the largest node */
@@ -1706,7 +1723,8 @@ void numa_default_policy(void)
}
/* Migrate a policy to a different set of nodes */
-void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
+static void mpol_rebind_policy(struct mempolicy *pol,
+ const nodemask_t *newmask)
{
nodemask_t *mpolmask;
nodemask_t tmp;
@@ -1963,7 +1981,7 @@ int show_numa_map(struct seq_file *m, void *v)
seq_printf(m, " huge");
} else {
check_pgd_range(vma, vma->vm_start, vma->vm_end,
- &node_online_map, MPOL_MF_STATS, md);
+ &node_states[N_HIGH_MEMORY], MPOL_MF_STATS, md);
}
if (!md->pages)
@@ -1990,7 +2008,7 @@ int show_numa_map(struct seq_file *m, void *v)
if (md->writeback)
seq_printf(m," writeback=%lu", md->writeback);
- for_each_online_node(n)
+ for_each_node_state(n, N_HIGH_MEMORY)
if (md->node[n])
seq_printf(m, " N%d=%lu", n, md->node[n]);
out:
diff --git a/mm/migrate.c b/mm/migrate.c
index 07f22d4a431..06d0877a66e 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -171,6 +171,7 @@ static void remove_migration_pte(struct vm_area_struct *vma,
pte = pte_mkold(mk_pte(new, vma->vm_page_prot));
if (is_write_migration_entry(entry))
pte = pte_mkwrite(pte);
+ flush_cache_page(vma, addr, pte_pfn(pte));
set_pte_at(mm, addr, ptep, pte);
if (PageAnon(new))
@@ -180,7 +181,6 @@ static void remove_migration_pte(struct vm_area_struct *vma,
/* No need to invalidate - it was non-present before */
update_mmu_cache(vma, addr, pte);
- lazy_mmu_prot_update(pte);
out:
pte_unmap_unlock(ptep, ptl);
@@ -986,7 +986,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
goto out;
err = -ENODEV;
- if (!node_online(node))
+ if (!node_state(node, N_HIGH_MEMORY))
goto out;
err = -EACCES;
diff --git a/mm/mmap.c b/mm/mmap.c
index 0d40e66c841..4275e81e25b 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -7,6 +7,7 @@
*/
#include <linux/slab.h>
+#include <linux/backing-dev.h>
#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/mman.h>
@@ -180,8 +181,6 @@ error:
return -ENOMEM;
}
-EXPORT_SYMBOL(__vm_enough_memory);
-
/*
* Requires inode->i_mapping->i_mmap_lock
*/
diff --git a/mm/mprotect.c b/mm/mprotect.c
index e8346c30abe..1d4d69790e5 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -53,7 +53,6 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
if (dirty_accountable && pte_dirty(ptent))
ptent = pte_mkwrite(ptent);
set_pte_at(mm, addr, pte, ptent);
- lazy_mmu_prot_update(ptent);
#ifdef CONFIG_MIGRATION
} else if (!pte_file(oldpte)) {
swp_entry_t entry = pte_to_swp_entry(oldpte);
diff --git a/mm/mremap.c b/mm/mremap.c
index 8ea5c2412c6..08e3c7f2bd1 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -291,7 +291,7 @@ unsigned long do_mremap(unsigned long addr,
if ((addr <= new_addr) && (addr+old_len) > new_addr)
goto out;
- ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
if (ret)
goto out;
@@ -399,7 +399,7 @@ unsigned long do_mremap(unsigned long addr,
goto out;
}
- ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
+ ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
if (ret)
goto out;
}
diff --git a/mm/nommu.c b/mm/nommu.c
index 8ed0cb43118..42fb84e9e81 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -44,7 +44,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
int heap_stack_gap = 0;
EXPORT_SYMBOL(mem_map);
-EXPORT_SYMBOL(__vm_enough_memory);
EXPORT_SYMBOL(num_physpages);
/* list of shareable VMAs */
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f9b82ad5047..a64decb5b13 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -27,6 +27,8 @@
#include <linux/notifier.h>
int sysctl_panic_on_oom;
+int sysctl_oom_kill_allocating_task;
+static DEFINE_SPINLOCK(zone_scan_mutex);
/* #define DEBUG */
/**
@@ -141,7 +143,7 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
* because p may have allocated or otherwise mapped memory on
* this node before. However it will be less likely.
*/
- if (!cpuset_excl_nodes_overlap(p))
+ if (!cpuset_mems_allowed_intersects(current, p))
points /= 8;
/*
@@ -164,27 +166,14 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
}
/*
- * Types of limitations to the nodes from which allocations may occur
- */
-#define CONSTRAINT_NONE 1
-#define CONSTRAINT_MEMORY_POLICY 2
-#define CONSTRAINT_CPUSET 3
-
-/*
* Determine the type of allocation constraint.
*/
-static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask)
+static inline enum oom_constraint constrained_alloc(struct zonelist *zonelist,
+ gfp_t gfp_mask)
{
#ifdef CONFIG_NUMA
struct zone **z;
- nodemask_t nodes;
- int node;
-
- nodes_clear(nodes);
- /* node has memory ? */
- for_each_online_node(node)
- if (NODE_DATA(node)->node_present_pages)
- node_set(node, nodes);
+ nodemask_t nodes = node_states[N_HIGH_MEMORY];
for (z = zonelist->zones; *z; z++)
if (cpuset_zone_allowed_softwall(*z, gfp_mask))
@@ -344,12 +333,20 @@ static int oom_kill_task(struct task_struct *p)
return 0;
}
-static int oom_kill_process(struct task_struct *p, unsigned long points,
- const char *message)
+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: "
+ "gfp_mask=0x%x, order=%d, oomkilladj=%d\n",
+ current->comm, gfp_mask, order, current->oomkilladj);
+ dump_stack();
+ show_mem();
+ }
+
/*
* If the task is already exiting, don't alarm the sysadmin or kill
* its children or threads, just set TIF_MEMDIE so it can die quickly
@@ -387,6 +384,57 @@ int unregister_oom_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(unregister_oom_notifier);
+/*
+ * Try to acquire the OOM killer lock for the zones in zonelist. Returns zero
+ * if a parallel OOM killing is already taking place that includes a zone in
+ * the zonelist. Otherwise, locks all zones in the zonelist and returns 1.
+ */
+int try_set_zone_oom(struct zonelist *zonelist)
+{
+ struct zone **z;
+ int ret = 1;
+
+ z = zonelist->zones;
+
+ spin_lock(&zone_scan_mutex);
+ do {
+ if (zone_is_oom_locked(*z)) {
+ ret = 0;
+ goto out;
+ }
+ } while (*(++z) != NULL);
+
+ /*
+ * Lock each zone in the zonelist under zone_scan_mutex so a parallel
+ * invocation of try_set_zone_oom() doesn't succeed when it shouldn't.
+ */
+ z = zonelist->zones;
+ do {
+ zone_set_flag(*z, ZONE_OOM_LOCKED);
+ } while (*(++z) != NULL);
+out:
+ spin_unlock(&zone_scan_mutex);
+ return ret;
+}
+
+/*
+ * Clears the ZONE_OOM_LOCKED flag for all zones in the zonelist so that failed
+ * allocation attempts with zonelists containing them may now recall the OOM
+ * killer, if necessary.
+ */
+void clear_zonelist_oom(struct zonelist *zonelist)
+{
+ struct zone **z;
+
+ z = zonelist->zones;
+
+ spin_lock(&zone_scan_mutex);
+ do {
+ zone_clear_flag(*z, ZONE_OOM_LOCKED);
+ } while (*(++z) != NULL);
+ spin_unlock(&zone_scan_mutex);
+}
+
/**
* out_of_memory - kill the "best" process when we run out of memory
*
@@ -400,21 +448,13 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
struct task_struct *p;
unsigned long points = 0;
unsigned long freed = 0;
- int constraint;
+ enum oom_constraint constraint;
blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
if (freed > 0)
/* Got some memory back in the last second. */
return;
- if (printk_ratelimit()) {
- printk(KERN_WARNING "%s invoked oom-killer: "
- "gfp_mask=0x%x, order=%d, oomkilladj=%d\n",
- current->comm, gfp_mask, order, current->oomkilladj);
- dump_stack();
- show_mem();
- }
-
if (sysctl_panic_on_oom == 2)
panic("out of memory. Compulsory panic_on_oom is selected.\n");
@@ -423,23 +463,24 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
* NUMA) that may require different handling.
*/
constraint = constrained_alloc(zonelist, gfp_mask);
- cpuset_lock();
read_lock(&tasklist_lock);
switch (constraint) {
case CONSTRAINT_MEMORY_POLICY:
- oom_kill_process(current, points,
+ oom_kill_process(current, gfp_mask, order, points,
"No available memory (MPOL_BIND)");
break;
- case CONSTRAINT_CPUSET:
- oom_kill_process(current, points,
- "No available memory in cpuset");
- break;
-
case CONSTRAINT_NONE:
if (sysctl_panic_on_oom)
panic("out of memory. panic_on_oom is selected\n");
+ /* Fall-through */
+ case CONSTRAINT_CPUSET:
+ if (sysctl_oom_kill_allocating_task) {
+ oom_kill_process(current, gfp_mask, order, points,
+ "Out of memory (oom_kill_allocating_task)");
+ break;
+ }
retry:
/*
* Rambo mode: Shoot down a process and hope it solves whatever
@@ -453,11 +494,11 @@ retry:
/* Found nothing?!?! Either we hang forever, or we panic. */
if (!p) {
read_unlock(&tasklist_lock);
- cpuset_unlock();
panic("Out of memory and no killable processes...\n");
}
- if (oom_kill_process(p, points, "Out of memory"))
+ if (oom_kill_process(p, points, gfp_mask, order,
+ "Out of memory"))
goto retry;
break;
@@ -465,7 +506,6 @@ retry:
out:
read_unlock(&tasklist_lock);
- cpuset_unlock();
/*
* Give "p" a good chance of killing itself before we
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 44720363374..7845462064f 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2,6 +2,7 @@
* mm/page-writeback.c
*
* Copyright (C) 2002, Linus Torvalds.
+ * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
*
* Contains functions related to writing back dirty pages at the
* address_space level.
@@ -36,7 +37,7 @@
/*
* The maximum number of pages to writeout in a single bdflush/kupdate
- * operation. We do this so we don't hold I_LOCK against an inode for
+ * operation. We do this so we don't hold I_SYNC against an inode for
* enormous amounts of time, which would block a userspace task which has
* been forced to throttle against that inode. Also, the code reevaluates
* the dirty each time it has written this many pages.
@@ -49,8 +50,6 @@
*/
static long ratelimit_pages = 32;
-static int dirty_exceeded __cacheline_aligned_in_smp; /* Dirty mem may be over limit */
-
/*
* When balance_dirty_pages decides that the caller needs to perform some
* non-background writeback, this is how many pages it will attempt to write.
@@ -103,6 +102,141 @@ EXPORT_SYMBOL(laptop_mode);
static void background_writeout(unsigned long _min_pages);
/*
+ * Scale the writeback cache size proportional to the relative writeout speeds.
+ *
+ * We do this by keeping a floating proportion between BDIs, based on page
+ * writeback completions [end_page_writeback()]. Those devices that write out
+ * pages fastest will get the larger share, while the slower will get a smaller
+ * share.
+ *
+ * We use page writeout completions because we are interested in getting rid of
+ * dirty pages. Having them written out is the primary goal.
+ *
+ * We introduce a concept of time, a period over which we measure these events,
+ * because demand can/will vary over time. The length of this period itself is
+ * measured in page writeback completions.
+ *
+ */
+static struct prop_descriptor vm_completions;
+static struct prop_descriptor vm_dirties;
+
+static unsigned long determine_dirtyable_memory(void);
+
+/*
+ * couple the period to the dirty_ratio:
+ *
+ * period/2 ~ roundup_pow_of_two(dirty limit)
+ */
+static int calc_period_shift(void)
+{
+ unsigned long dirty_total;
+
+ dirty_total = (vm_dirty_ratio * determine_dirtyable_memory()) / 100;
+ return 2 + ilog2(dirty_total - 1);
+}
+
+/*
+ * update the period when the dirty ratio changes.
+ */
+int dirty_ratio_handler(struct ctl_table *table, int write,
+ struct file *filp, void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ int old_ratio = vm_dirty_ratio;
+ int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+ if (ret == 0 && write && vm_dirty_ratio != old_ratio) {
+ int shift = calc_period_shift();
+ prop_change_shift(&vm_completions, shift);
+ prop_change_shift(&vm_dirties, shift);
+ }
+ return ret;
+}
+
+/*
+ * Increment the BDI's writeout completion count and the global writeout
+ * completion count. Called from test_clear_page_writeback().
+ */
+static inline void __bdi_writeout_inc(struct backing_dev_info *bdi)
+{
+ __prop_inc_percpu(&vm_completions, &bdi->completions);
+}
+
+static inline void task_dirty_inc(struct task_struct *tsk)
+{
+ prop_inc_single(&vm_dirties, &tsk->dirties);
+}
+
+/*
+ * Obtain an accurate fraction of the BDI's portion.
+ */
+static void bdi_writeout_fraction(struct backing_dev_info *bdi,
+ long *numerator, long *denominator)
+{
+ if (bdi_cap_writeback_dirty(bdi)) {
+ prop_fraction_percpu(&vm_completions, &bdi->completions,
+ numerator, denominator);
+ } else {
+ *numerator = 0;
+ *denominator = 1;
+ }
+}
+
+/*
+ * Clip the earned share of dirty pages to that which is actually available.
+ * This avoids exceeding the total dirty_limit when the floating averages
+ * fluctuate too quickly.
+ */
+static void
+clip_bdi_dirty_limit(struct backing_dev_info *bdi, long dirty, long *pbdi_dirty)
+{
+ long avail_dirty;
+
+ avail_dirty = dirty -
+ (global_page_state(NR_FILE_DIRTY) +
+ global_page_state(NR_WRITEBACK) +
+ global_page_state(NR_UNSTABLE_NFS));
+
+ if (avail_dirty < 0)
+ avail_dirty = 0;
+
+ avail_dirty += bdi_stat(bdi, BDI_RECLAIMABLE) +
+ bdi_stat(bdi, BDI_WRITEBACK);
+
+ *pbdi_dirty = min(*pbdi_dirty, avail_dirty);
+}
+
+static inline void task_dirties_fraction(struct task_struct *tsk,
+ long *numerator, long *denominator)
+{
+ prop_fraction_single(&vm_dirties, &tsk->dirties,
+ numerator, denominator);
+}
+
+/*
+ * scale the dirty limit
+ *
+ * task specific dirty limit:
+ *
+ * dirty -= (dirty/8) * p_{t}
+ */
+void task_dirty_limit(struct task_struct *tsk, long *pdirty)
+{
+ long numerator, denominator;
+ long dirty = *pdirty;
+ u64 inv = dirty >> 3;
+
+ task_dirties_fraction(tsk, &numerator, &denominator);
+ inv *= numerator;
+ do_div(inv, denominator);
+
+ dirty -= inv;
+ if (dirty < *pdirty/2)
+ dirty = *pdirty/2;
+
+ *pdirty = dirty;
+}
+
+/*
* Work out the current dirty-memory clamping and background writeout
* thresholds.
*
@@ -126,7 +260,7 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)
int node;
unsigned long x = 0;
- for_each_online_node(node) {
+ for_each_node_state(node, N_HIGH_MEMORY) {
struct zone *z =
&NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
@@ -158,8 +292,8 @@ static unsigned long determine_dirtyable_memory(void)
}
static void
-get_dirty_limits(long *pbackground, long *pdirty,
- struct address_space *mapping)
+get_dirty_limits(long *pbackground, long *pdirty, long *pbdi_dirty,
+ struct backing_dev_info *bdi)
{
int background_ratio; /* Percentages */
int dirty_ratio;
@@ -193,6 +327,23 @@ get_dirty_limits(long *pbackground, long *pdirty,
}
*pbackground = background;
*pdirty = dirty;
+
+ if (bdi) {
+ u64 bdi_dirty = dirty;
+ long numerator, denominator;
+
+ /*
+ * Calculate this BDI's share of the dirty ratio.
+ */
+ bdi_writeout_fraction(bdi, &numerator, &denominator);
+
+ bdi_dirty *= numerator;
+ do_div(bdi_dirty, denominator);
+
+ *pbdi_dirty = bdi_dirty;
+ clip_bdi_dirty_limit(bdi, dirty, pbdi_dirty);
+ task_dirty_limit(current, pbdi_dirty);
+ }
}
/*
@@ -204,9 +355,11 @@ get_dirty_limits(long *pbackground, long *pdirty,
*/
static void balance_dirty_pages(struct address_space *mapping)
{
- long nr_reclaimable;
+ long bdi_nr_reclaimable;
+ long bdi_nr_writeback;
long background_thresh;
long dirty_thresh;
+ long bdi_thresh;
unsigned long pages_written = 0;
unsigned long write_chunk = sync_writeback_pages();
@@ -221,15 +374,15 @@ static void balance_dirty_pages(struct address_space *mapping)
.range_cyclic = 1,
};
- get_dirty_limits(&background_thresh, &dirty_thresh, mapping);
- nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
- global_page_state(NR_UNSTABLE_NFS);
- if (nr_reclaimable + global_page_state(NR_WRITEBACK) <=
- dirty_thresh)
- break;
+ get_dirty_limits(&background_thresh, &dirty_thresh,
+ &bdi_thresh, bdi);
+ bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
+ bdi_nr_writeback = bdi_stat(bdi, BDI_WRITEBACK);
+ if (bdi_nr_reclaimable + bdi_nr_writeback <= bdi_thresh)
+ break;
- if (!dirty_exceeded)
- dirty_exceeded = 1;
+ if (!bdi->dirty_exceeded)
+ bdi->dirty_exceeded = 1;
/* Note: nr_reclaimable denotes nr_dirty + nr_unstable.
* Unstable writes are a feature of certain networked
@@ -237,26 +390,42 @@ static void balance_dirty_pages(struct address_space *mapping)
* written to the server's write cache, but has not yet
* been flushed to permanent storage.
*/
- if (nr_reclaimable) {
+ if (bdi_nr_reclaimable) {
writeback_inodes(&wbc);
- get_dirty_limits(&background_thresh,
- &dirty_thresh, mapping);
- nr_reclaimable = global_page_state(NR_FILE_DIRTY) +
- global_page_state(NR_UNSTABLE_NFS);
- if (nr_reclaimable +
- global_page_state(NR_WRITEBACK)
- <= dirty_thresh)
- break;
pages_written += write_chunk - wbc.nr_to_write;
- if (pages_written >= write_chunk)
- break; /* We've done our duty */
+ get_dirty_limits(&background_thresh, &dirty_thresh,
+ &bdi_thresh, bdi);
}
+
+ /*
+ * In order to avoid the stacked BDI deadlock we need
+ * to ensure we accurately count the 'dirty' pages when
+ * the threshold is low.
+ *
+ * Otherwise it would be possible to get thresh+n pages
+ * reported dirty, even though there are thresh-m pages
+ * actually dirty; with m+n sitting in the percpu
+ * deltas.
+ */
+ if (bdi_thresh < 2*bdi_stat_error(bdi)) {
+ bdi_nr_reclaimable = bdi_stat_sum(bdi, BDI_RECLAIMABLE);
+ bdi_nr_writeback = bdi_stat_sum(bdi, BDI_WRITEBACK);
+ } else if (bdi_nr_reclaimable) {
+ bdi_nr_reclaimable = bdi_stat(bdi, BDI_RECLAIMABLE);
+ bdi_nr_writeback = bdi_stat(bdi, BDI_WRITEBACK);
+ }
+
+ if (bdi_nr_reclaimable + bdi_nr_writeback <= bdi_thresh)
+ break;
+ if (pages_written >= write_chunk)
+ break; /* We've done our duty */
+
congestion_wait(WRITE, HZ/10);
}
- if (nr_reclaimable + global_page_state(NR_WRITEBACK)
- <= dirty_thresh && dirty_exceeded)
- dirty_exceeded = 0;
+ if (bdi_nr_reclaimable + bdi_nr_writeback < bdi_thresh &&
+ bdi->dirty_exceeded)
+ bdi->dirty_exceeded = 0;
if (writeback_in_progress(bdi))
return; /* pdflush is already working this queue */
@@ -270,7 +439,9 @@ static void balance_dirty_pages(struct address_space *mapping)
* background_thresh, to keep the amount of dirty memory low.
*/
if ((laptop_mode && pages_written) ||
- (!laptop_mode && (nr_reclaimable > background_thresh)))
+ (!laptop_mode && (global_page_state(NR_FILE_DIRTY)
+ + global_page_state(NR_UNSTABLE_NFS)
+ > background_thresh)))
pdflush_operation(background_writeout, 0);
}
@@ -306,7 +477,7 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
unsigned long *p;
ratelimit = ratelimit_pages;
- if (dirty_exceeded)
+ if (mapping->backing_dev_info->dirty_exceeded)
ratelimit = 8;
/*
@@ -331,18 +502,8 @@ void throttle_vm_writeout(gfp_t gfp_mask)
long background_thresh;
long dirty_thresh;
- if ((gfp_mask & (__GFP_FS|__GFP_IO)) != (__GFP_FS|__GFP_IO)) {
- /*
- * The caller might hold locks which can prevent IO completion
- * or progress in the filesystem. So we cannot just sit here
- * waiting for IO to complete.
- */
- congestion_wait(WRITE, HZ/10);
- return;
- }
-
for ( ; ; ) {
- get_dirty_limits(&background_thresh, &dirty_thresh, NULL);
+ get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL);
/*
* Boost the allowable dirty threshold a bit for page
@@ -354,6 +515,14 @@ void throttle_vm_writeout(gfp_t gfp_mask)
global_page_state(NR_WRITEBACK) <= dirty_thresh)
break;
congestion_wait(WRITE, HZ/10);
+
+ /*
+ * The caller might hold locks which can prevent IO completion
+ * or progress in the filesystem. So we cannot just sit here
+ * waiting for IO to complete.
+ */
+ if ((gfp_mask & (__GFP_FS|__GFP_IO)) != (__GFP_FS|__GFP_IO))
+ break;
}
}
@@ -377,11 +546,12 @@ static void background_writeout(unsigned long _min_pages)
long background_thresh;
long dirty_thresh;
- get_dirty_limits(&background_thresh, &dirty_thresh, NULL);
+ get_dirty_limits(&background_thresh, &dirty_thresh, NULL, NULL);
if (global_page_state(NR_FILE_DIRTY) +
global_page_state(NR_UNSTABLE_NFS) < background_thresh
&& min_pages <= 0)
break;
+ wbc.more_io = 0;
wbc.encountered_congestion = 0;
wbc.nr_to_write = MAX_WRITEBACK_PAGES;
wbc.pages_skipped = 0;
@@ -389,8 +559,9 @@ static void background_writeout(unsigned long _min_pages)
min_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) {
/* Wrote less than expected */
- congestion_wait(WRITE, HZ/10);
- if (!wbc.encountered_congestion)
+ if (wbc.encountered_congestion || wbc.more_io)
+ congestion_wait(WRITE, HZ/10);
+ else
break;
}
}
@@ -455,11 +626,12 @@ static void wb_kupdate(unsigned long arg)
global_page_state(NR_UNSTABLE_NFS) +
(inodes_stat.nr_inodes - inodes_stat.nr_unused);
while (nr_to_write > 0) {
+ wbc.more_io = 0;
wbc.encountered_congestion = 0;
wbc.nr_to_write = MAX_WRITEBACK_PAGES;
writeback_inodes(&wbc);
if (wbc.nr_to_write > 0) {
- if (wbc.encountered_congestion)
+ if (wbc.encountered_congestion || wbc.more_io)
congestion_wait(WRITE, HZ/10);
else
break; /* All the old data is written */
@@ -580,9 +752,15 @@ static struct notifier_block __cpuinitdata ratelimit_nb = {
*/
void __init page_writeback_init(void)
{
+ int shift;
+
mod_timer(&wb_timer, jiffies + dirty_writeback_interval);
writeback_set_ratelimit();
register_cpu_notifier(&ratelimit_nb);
+
+ shift = calc_period_shift();
+ prop_descriptor_init(&vm_completions, shift);
+ prop_descriptor_init(&vm_dirties, shift);
}
/**
@@ -672,8 +850,10 @@ retry:
ret = (*writepage)(page, wbc, data);
- if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
+ if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
unlock_page(page);
+ ret = 0;
+ }
if (ret || (--(wbc->nr_to_write) <= 0))
done = 1;
if (wbc->nonblocking && bdi_write_congested(bdi)) {
@@ -827,6 +1007,8 @@ int __set_page_dirty_nobuffers(struct page *page)
WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page));
if (mapping_cap_account_dirty(mapping)) {
__inc_zone_page_state(page, NR_FILE_DIRTY);
+ __inc_bdi_stat(mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
task_io_account_write(PAGE_CACHE_SIZE);
}
radix_tree_tag_set(&mapping->page_tree,
@@ -859,7 +1041,7 @@ EXPORT_SYMBOL(redirty_page_for_writepage);
* If the mapping doesn't provide a set_page_dirty a_op, then
* just fall through and assume that it wants buffer_heads.
*/
-int fastcall set_page_dirty(struct page *page)
+static int __set_page_dirty(struct page *page)
{
struct address_space *mapping = page_mapping(page);
@@ -877,6 +1059,14 @@ int fastcall set_page_dirty(struct page *page)
}
return 0;
}
+
+int fastcall set_page_dirty(struct page *page)
+{
+ int ret = __set_page_dirty(page);
+ if (ret)
+ task_dirty_inc(current);
+ return ret;
+}
EXPORT_SYMBOL(set_page_dirty);
/*
@@ -961,6 +1151,8 @@ int clear_page_dirty_for_io(struct page *page)
*/
if (TestClearPageDirty(page)) {
dec_zone_page_state(page, NR_FILE_DIRTY);
+ dec_bdi_stat(mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
return 1;
}
return 0;
@@ -975,14 +1167,20 @@ int test_clear_page_writeback(struct page *page)
int ret;
if (mapping) {
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
unsigned long flags;
write_lock_irqsave(&mapping->tree_lock, flags);
ret = TestClearPageWriteback(page);
- if (ret)
+ if (ret) {
radix_tree_tag_clear(&mapping->page_tree,
page_index(page),
PAGECACHE_TAG_WRITEBACK);
+ if (bdi_cap_writeback_dirty(bdi)) {
+ __dec_bdi_stat(bdi, BDI_WRITEBACK);
+ __bdi_writeout_inc(bdi);
+ }
+ }
write_unlock_irqrestore(&mapping->tree_lock, flags);
} else {
ret = TestClearPageWriteback(page);
@@ -998,14 +1196,18 @@ int test_set_page_writeback(struct page *page)
int ret;
if (mapping) {
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
unsigned long flags;
write_lock_irqsave(&mapping->tree_lock, flags);
ret = TestSetPageWriteback(page);
- if (!ret)
+ if (!ret) {
radix_tree_tag_set(&mapping->page_tree,
page_index(page),
PAGECACHE_TAG_WRITEBACK);
+ if (bdi_cap_writeback_dirty(bdi))
+ __inc_bdi_stat(bdi, BDI_WRITEBACK);
+ }
if (!PageDirty(page))
radix_tree_tag_clear(&mapping->page_tree,
page_index(page),
@@ -1022,17 +1224,15 @@ int test_set_page_writeback(struct page *page)
EXPORT_SYMBOL(test_set_page_writeback);
/*
- * Return true if any of the pages in the mapping are marged with the
+ * Return true if any of the pages in the mapping are marked with the
* passed tag.
*/
int mapping_tagged(struct address_space *mapping, int tag)
{
- unsigned long flags;
int ret;
-
- read_lock_irqsave(&mapping->tree_lock, flags);
+ rcu_read_lock();
ret = radix_tree_tagged(&mapping->page_tree, tag);
- read_unlock_irqrestore(&mapping->tree_lock, flags);
+ rcu_read_unlock();
return ret;
}
EXPORT_SYMBOL(mapping_tagged);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1a8c59571cb..43f757fcf30 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -27,6 +27,7 @@
#include <linux/pagevec.h>
#include <linux/blkdev.h>
#include <linux/slab.h>
+#include <linux/oom.h>
#include <linux/notifier.h>
#include <linux/topology.h>
#include <linux/sysctl.h>
@@ -41,24 +42,37 @@
#include <linux/pfn.h>
#include <linux/backing-dev.h>
#include <linux/fault-inject.h>
+#include <linux/page-isolation.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
#include "internal.h"
/*
- * MCD - HACK: Find somewhere to initialize this EARLY, or make this
- * initializer cleaner
+ * Array of node states.
*/
-nodemask_t node_online_map __read_mostly = { { [0] = 1UL } };
-EXPORT_SYMBOL(node_online_map);
-nodemask_t node_possible_map __read_mostly = NODE_MASK_ALL;
-EXPORT_SYMBOL(node_possible_map);
+nodemask_t node_states[NR_NODE_STATES] __read_mostly = {
+ [N_POSSIBLE] = NODE_MASK_ALL,
+ [N_ONLINE] = { { [0] = 1UL } },
+#ifndef CONFIG_NUMA
+ [N_NORMAL_MEMORY] = { { [0] = 1UL } },
+#ifdef CONFIG_HIGHMEM
+ [N_HIGH_MEMORY] = { { [0] = 1UL } },
+#endif
+ [N_CPU] = { { [0] = 1UL } },
+#endif /* NUMA */
+};
+EXPORT_SYMBOL(node_states);
+
unsigned long totalram_pages __read_mostly;
unsigned long totalreserve_pages __read_mostly;
long nr_swap_pages;
int percpu_pagelist_fraction;
+#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
+int pageblock_order __read_mostly;
+#endif
+
static void __free_pages_ok(struct page *page, unsigned int order);
/*
@@ -137,7 +151,7 @@ static unsigned long __meminitdata dma_reserve;
static unsigned long __meminitdata node_boundary_end_pfn[MAX_NUMNODES];
#endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */
unsigned long __initdata required_kernelcore;
- unsigned long __initdata required_movablecore;
+ static unsigned long __initdata required_movablecore;
unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES];
/* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */
@@ -150,6 +164,14 @@ int nr_node_ids __read_mostly = MAX_NUMNODES;
EXPORT_SYMBOL(nr_node_ids);
#endif
+int page_group_by_mobility_disabled __read_mostly;
+
+static void set_pageblock_migratetype(struct page *page, int migratetype)
+{
+ set_pageblock_flags_group(page, (unsigned long)migratetype,
+ PB_migrate, PB_migrate_end);
+}
+
#ifdef CONFIG_DEBUG_VM
static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{
@@ -293,16 +315,6 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
clear_highpage(page + i);
}
-/*
- * function for dealing with page's order in buddy system.
- * zone->lock is already acquired when we use these.
- * So, we don't need atomic page->flags operations here.
- */
-static inline unsigned long page_order(struct page *page)
-{
- return page_private(page);
-}
-
static inline void set_page_order(struct page *page, int order)
{
set_page_private(page, order);
@@ -404,6 +416,7 @@ static inline void __free_one_page(struct page *page,
{
unsigned long page_idx;
int order_size = 1 << order;
+ int migratetype = get_pageblock_migratetype(page);
if (unlikely(PageCompound(page)))
destroy_compound_page(page, order);
@@ -416,7 +429,6 @@ static inline void __free_one_page(struct page *page,
__mod_zone_page_state(zone, NR_FREE_PAGES, order_size);
while (order < MAX_ORDER-1) {
unsigned long combined_idx;
- struct free_area *area;
struct page *buddy;
buddy = __page_find_buddy(page, page_idx, order);
@@ -424,8 +436,7 @@ static inline void __free_one_page(struct page *page,
break; /* Move the buddy up one level. */
list_del(&buddy->lru);
- area = zone->free_area + order;
- area->nr_free--;
+ zone->free_area[order].nr_free--;
rmv_page_order(buddy);
combined_idx = __find_combined_index(page_idx, order);
page = page + (combined_idx - page_idx);
@@ -433,7 +444,8 @@ static inline void __free_one_page(struct page *page,
order++;
}
set_page_order(page, order);
- list_add(&page->lru, &zone->free_area[order].free_list);
+ list_add(&page->lru,
+ &zone->free_area[order].free_list[migratetype]);
zone->free_area[order].nr_free++;
}
@@ -478,7 +490,7 @@ static void free_pages_bulk(struct zone *zone, int count,
struct list_head *list, int order)
{
spin_lock(&zone->lock);
- zone->all_unreclaimable = 0;
+ zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
zone->pages_scanned = 0;
while (count--) {
struct page *page;
@@ -495,7 +507,7 @@ static void free_pages_bulk(struct zone *zone, int count,
static void free_one_page(struct zone *zone, struct page *page, int order)
{
spin_lock(&zone->lock);
- zone->all_unreclaimable = 0;
+ zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
zone->pages_scanned = 0;
__free_one_page(page, zone, order);
spin_unlock(&zone->lock);
@@ -567,7 +579,8 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
* -- wli
*/
static inline void expand(struct zone *zone, struct page *page,
- int low, int high, struct free_area *area)
+ int low, int high, struct free_area *area,
+ int migratetype)
{
unsigned long size = 1 << high;
@@ -576,7 +589,7 @@ static inline void expand(struct zone *zone, struct page *page,
high--;
size >>= 1;
VM_BUG_ON(bad_range(zone, &page[size]));
- list_add(&page[size].lru, &area->free_list);
+ list_add(&page[size].lru, &area->free_list[migratetype]);
area->nr_free++;
set_page_order(&page[size], high);
}
@@ -628,49 +641,235 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
return 0;
}
-/*
- * Do the hard work of removing an element from the buddy allocator.
- * Call me with the zone->lock already held.
+/*
+ * Go through the free lists for the given migratetype and remove
+ * the smallest available page from the freelists
*/
-static struct page *__rmqueue(struct zone *zone, unsigned int order)
+static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
+ int migratetype)
{
- struct free_area * area;
unsigned int current_order;
+ struct free_area * area;
struct page *page;
+ /* Find a page of the appropriate size in the preferred list */
for (current_order = order; current_order < MAX_ORDER; ++current_order) {
- area = zone->free_area + current_order;
- if (list_empty(&area->free_list))
+ area = &(zone->free_area[current_order]);
+ if (list_empty(&area->free_list[migratetype]))
continue;
- page = list_entry(area->free_list.next, struct page, lru);
+ page = list_entry(area->free_list[migratetype].next,
+ struct page, lru);
list_del(&page->lru);
rmv_page_order(page);
area->nr_free--;
__mod_zone_page_state(zone, NR_FREE_PAGES, - (1UL << order));
- expand(zone, page, order, current_order, area);
+ expand(zone, page, order, current_order, area, migratetype);
return page;
}
return NULL;
}
+
+/*
+ * This array describes the order lists are fallen back to when
+ * the free lists for the desirable migrate type are depleted
+ */
+static int fallbacks[MIGRATE_TYPES][MIGRATE_TYPES-1] = {
+ [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
+ [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
+ [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
+ [MIGRATE_RESERVE] = { MIGRATE_RESERVE, MIGRATE_RESERVE, MIGRATE_RESERVE }, /* Never used */
+};
+
+/*
+ * Move the free pages in a range to the free lists of the requested type.
+ * Note that start_page and end_pages are not aligned on a pageblock
+ * boundary. If alignment is required, use move_freepages_block()
+ */
+int move_freepages(struct zone *zone,
+ struct page *start_page, struct page *end_page,
+ int migratetype)
+{
+ struct page *page;
+ unsigned long order;
+ int pages_moved = 0;
+
+#ifndef CONFIG_HOLES_IN_ZONE
+ /*
+ * page_zone is not safe to call in this context when
+ * CONFIG_HOLES_IN_ZONE is set. This bug check is probably redundant
+ * anyway as we check zone boundaries in move_freepages_block().
+ * Remove at a later date when no bug reports exist related to
+ * grouping pages by mobility
+ */
+ BUG_ON(page_zone(start_page) != page_zone(end_page));
+#endif
+
+ for (page = start_page; page <= end_page;) {
+ if (!pfn_valid_within(page_to_pfn(page))) {
+ page++;
+ continue;
+ }
+
+ if (!PageBuddy(page)) {
+ page++;
+ continue;
+ }
+
+ order = page_order(page);
+ list_del(&page->lru);
+ list_add(&page->lru,
+ &zone->free_area[order].free_list[migratetype]);
+ page += 1 << order;
+ pages_moved += 1 << order;
+ }
+
+ return pages_moved;
+}
+
+int move_freepages_block(struct zone *zone, struct page *page, int migratetype)
+{
+ unsigned long start_pfn, end_pfn;
+ struct page *start_page, *end_page;
+
+ start_pfn = page_to_pfn(page);
+ start_pfn = start_pfn & ~(pageblock_nr_pages-1);
+ start_page = pfn_to_page(start_pfn);
+ end_page = start_page + pageblock_nr_pages - 1;
+ end_pfn = start_pfn + pageblock_nr_pages - 1;
+
+ /* Do not cross zone boundaries */
+ if (start_pfn < zone->zone_start_pfn)
+ start_page = page;
+ if (end_pfn >= zone->zone_start_pfn + zone->spanned_pages)
+ return 0;
+
+ return move_freepages(zone, start_page, end_page, migratetype);
+}
+
+/* Return the page with the lowest PFN in the list */
+static struct page *min_page(struct list_head *list)
+{
+ unsigned long min_pfn = -1UL;
+ struct page *min_page = NULL, *page;;
+
+ list_for_each_entry(page, list, lru) {
+ unsigned long pfn = page_to_pfn(page);
+ if (pfn < min_pfn) {
+ min_pfn = pfn;
+ min_page = page;
+ }
+ }
+
+ return min_page;
+}
+
+/* Remove an element from the buddy allocator from the fallback list */
+static struct page *__rmqueue_fallback(struct zone *zone, int order,
+ int start_migratetype)
+{
+ struct free_area * area;
+ int current_order;
+ struct page *page;
+ int migratetype, i;
+
+ /* Find the largest possible block of pages in the other list */
+ for (current_order = MAX_ORDER-1; current_order >= order;
+ --current_order) {
+ for (i = 0; i < MIGRATE_TYPES - 1; i++) {
+ migratetype = fallbacks[start_migratetype][i];
+
+ /* MIGRATE_RESERVE handled later if necessary */
+ if (migratetype == MIGRATE_RESERVE)
+ continue;
+
+ area = &(zone->free_area[current_order]);
+ if (list_empty(&area->free_list[migratetype]))
+ continue;
+
+ /* Bias kernel allocations towards low pfns */
+ page = list_entry(area->free_list[migratetype].next,
+ struct page, lru);
+ if (unlikely(start_migratetype != MIGRATE_MOVABLE))
+ page = min_page(&area->free_list[migratetype]);
+ area->nr_free--;
+
+ /*
+ * If breaking a large block of pages, move all free
+ * pages to the preferred allocation list. If falling
+ * back for a reclaimable kernel allocation, be more
+ * agressive about taking ownership of free pages
+ */
+ if (unlikely(current_order >= (pageblock_order >> 1)) ||
+ start_migratetype == MIGRATE_RECLAIMABLE) {
+ unsigned long pages;
+ pages = move_freepages_block(zone, page,
+ start_migratetype);
+
+ /* Claim the whole block if over half of it is free */
+ if (pages >= (1 << (pageblock_order-1)))
+ set_pageblock_migratetype(page,
+ start_migratetype);
+
+ migratetype = start_migratetype;
+ }
+
+ /* Remove the page from the freelists */
+ list_del(&page->lru);
+ rmv_page_order(page);
+ __mod_zone_page_state(zone, NR_FREE_PAGES,
+ -(1UL << order));
+
+ if (current_order == pageblock_order)
+ set_pageblock_migratetype(page,
+ start_migratetype);
+
+ expand(zone, page, order, current_order, area, migratetype);
+ return page;
+ }
+ }
+
+ /* Use MIGRATE_RESERVE rather than fail an allocation */
+ return __rmqueue_smallest(zone, order, MIGRATE_RESERVE);
+}
+
+/*
+ * Do the hard work of removing an element from the buddy allocator.
+ * Call me with the zone->lock already held.
+ */
+static struct page *__rmqueue(struct zone *zone, unsigned int order,
+ int migratetype)
+{
+ struct page *page;
+
+ page = __rmqueue_smallest(zone, order, migratetype);
+
+ if (unlikely(!page))
+ page = __rmqueue_fallback(zone, order, migratetype);
+
+ return page;
+}
+
/*
* Obtain a specified number of elements from the buddy allocator, all under
* a single hold of the lock, for efficiency. Add them to the supplied list.
* Returns the number of new pages which were placed at *list.
*/
static int rmqueue_bulk(struct zone *zone, unsigned int order,
- unsigned long count, struct list_head *list)
+ unsigned long count, struct list_head *list,
+ int migratetype)
{
int i;
spin_lock(&zone->lock);
for (i = 0; i < count; ++i) {
- struct page *page = __rmqueue(zone, order);
+ struct page *page = __rmqueue(zone, order, migratetype);
if (unlikely(page == NULL))
break;
- list_add_tail(&page->lru, list);
+ list_add(&page->lru, list);
+ set_page_private(page, migratetype);
}
spin_unlock(&zone->lock);
return i;
@@ -732,7 +931,7 @@ void mark_free_pages(struct zone *zone)
{
unsigned long pfn, max_zone_pfn;
unsigned long flags;
- int order;
+ int order, t;
struct list_head *curr;
if (!zone->spanned_pages)
@@ -749,17 +948,18 @@ void mark_free_pages(struct zone *zone)
swsusp_unset_page_free(page);
}
- for (order = MAX_ORDER - 1; order >= 0; --order)
- list_for_each(curr, &zone->free_area[order].free_list) {
+ for_each_migratetype_order(order, t) {
+ list_for_each(curr, &zone->free_area[order].free_list[t]) {
unsigned long i;
pfn = page_to_pfn(list_entry(curr, struct page, lru));
for (i = 0; i < (1UL << order); i++)
swsusp_set_page_free(pfn_to_page(pfn + i));
}
-
+ }
spin_unlock_irqrestore(&zone->lock, flags);
}
+#endif /* CONFIG_PM */
/*
* Spill all of this CPU's per-cpu pages back into the buddy allocator.
@@ -772,7 +972,25 @@ void drain_local_pages(void)
__drain_pages(smp_processor_id());
local_irq_restore(flags);
}
-#endif /* CONFIG_HIBERNATION */
+
+void smp_drain_local_pages(void *arg)
+{
+ drain_local_pages();
+}
+
+/*
+ * Spill all the per-cpu pages from all CPUs back into the buddy allocator
+ */
+void drain_all_local_pages(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __drain_pages(smp_processor_id());
+ local_irq_restore(flags);
+
+ smp_call_function(smp_drain_local_pages, NULL, 0, 1);
+}
/*
* Free a 0-order page
@@ -797,6 +1015,7 @@ static void fastcall free_hot_cold_page(struct page *page, int cold)
local_irq_save(flags);
__count_vm_event(PGFREE);
list_add(&page->lru, &pcp->list);
+ set_page_private(page, get_pageblock_migratetype(page));
pcp->count++;
if (pcp->count >= pcp->high) {
free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
@@ -846,6 +1065,7 @@ static struct page *buffered_rmqueue(struct zonelist *zonelist,
struct page *page;
int cold = !!(gfp_flags & __GFP_COLD);
int cpu;
+ int migratetype = allocflags_to_migratetype(gfp_flags);
again:
cpu = get_cpu();
@@ -856,16 +1076,28 @@ again:
local_irq_save(flags);
if (!pcp->count) {
pcp->count = rmqueue_bulk(zone, 0,
- pcp->batch, &pcp->list);
+ pcp->batch, &pcp->list, migratetype);
if (unlikely(!pcp->count))
goto failed;
}
- page = list_entry(pcp->list.next, struct page, lru);
+
+ /* Find a page of the appropriate migrate type */
+ list_for_each_entry(page, &pcp->list, lru)
+ if (page_private(page) == migratetype)
+ break;
+
+ /* Allocate more to the pcp list if necessary */
+ if (unlikely(&page->lru == &pcp->list)) {
+ pcp->count += rmqueue_bulk(zone, 0,
+ pcp->batch, &pcp->list, migratetype);
+ page = list_entry(pcp->list.next, struct page, lru);
+ }
+
list_del(&page->lru);
pcp->count--;
} else {
spin_lock_irqsave(&zone->lock, flags);
- page = __rmqueue(zone, order);
+ page = __rmqueue(zone, order, migratetype);
spin_unlock(&zone->lock);
if (!page)
goto failed;
@@ -1032,7 +1264,7 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
*
* If the zonelist cache is present in the passed in zonelist, then
* returns a pointer to the allowed node mask (either the current
- * tasks mems_allowed, or node_online_map.)
+ * tasks mems_allowed, or node_states[N_HIGH_MEMORY].)
*
* If the zonelist cache is not available for this zonelist, does
* nothing and returns NULL.
@@ -1061,7 +1293,7 @@ static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags)
allowednodes = !in_interrupt() && (alloc_flags & ALLOC_CPUSET) ?
&cpuset_current_mems_allowed :
- &node_online_map;
+ &node_states[N_HIGH_MEMORY];
return allowednodes;
}
@@ -1183,9 +1415,6 @@ zonelist_scan:
!zlc_zone_worth_trying(zonelist, z, allowednodes))
continue;
zone = *z;
- if (unlikely(NUMA_BUILD && (gfp_mask & __GFP_THISNODE) &&
- zone->zone_pgdat != zonelist->zones[0]->zone_pgdat))
- break;
if ((alloc_flags & ALLOC_CPUSET) &&
!cpuset_zone_allowed_softwall(zone, gfp_mask))
goto try_next_zone;
@@ -1254,7 +1483,10 @@ restart:
z = zonelist->zones; /* the list of zones suitable for gfp_mask */
if (unlikely(*z == NULL)) {
- /* Should this ever happen?? */
+ /*
+ * Happens if we have an empty zonelist as a result of
+ * GFP_THISNODE being used on a memoryless node
+ */
return NULL;
}
@@ -1346,12 +1578,20 @@ nofail_alloc:
cond_resched();
+ if (order != 0)
+ drain_all_local_pages();
+
if (likely(did_some_progress)) {
page = get_page_from_freelist(gfp_mask, order,
zonelist, alloc_flags);
if (page)
goto got_pg;
} else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) {
+ if (!try_set_zone_oom(zonelist)) {
+ schedule_timeout_uninterruptible(1);
+ goto restart;
+ }
+
/*
* Go through the zonelist yet one more time, keep
* very high watermark here, this is only to catch
@@ -1360,14 +1600,19 @@ nofail_alloc:
*/
page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET);
- if (page)
+ if (page) {
+ clear_zonelist_oom(zonelist);
goto got_pg;
+ }
/* The OOM killer will not help higher order allocs so fail */
- if (order > PAGE_ALLOC_COSTLY_ORDER)
+ if (order > PAGE_ALLOC_COSTLY_ORDER) {
+ clear_zonelist_oom(zonelist);
goto nopage;
+ }
out_of_memory(zonelist, gfp_mask, order);
+ clear_zonelist_oom(zonelist);
goto restart;
}
@@ -1616,7 +1861,7 @@ void show_free_areas(void)
K(zone_page_state(zone, NR_INACTIVE)),
K(zone->present_pages),
zone->pages_scanned,
- (zone->all_unreclaimable ? "yes" : "no")
+ (zone_is_all_unreclaimable(zone) ? "yes" : "no")
);
printk("lowmem_reserve[]:");
for (i = 0; i < MAX_NR_ZONES; i++)
@@ -1794,7 +2039,7 @@ static int find_next_best_node(int node, nodemask_t *used_node_mask)
return node;
}
- for_each_online_node(n) {
+ for_each_node_state(n, N_HIGH_MEMORY) {
cpumask_t tmp;
/* Don't want a node to appear more than once */
@@ -1850,6 +2095,22 @@ static void build_zonelists_in_node_order(pg_data_t *pgdat, int node)
}
/*
+ * Build gfp_thisnode zonelists
+ */
+static void build_thisnode_zonelists(pg_data_t *pgdat)
+{
+ enum zone_type i;
+ int j;
+ struct zonelist *zonelist;
+
+ for (i = 0; i < MAX_NR_ZONES; i++) {
+ zonelist = pgdat->node_zonelists + MAX_NR_ZONES + i;
+ j = build_zonelists_node(pgdat, zonelist, 0, i);
+ zonelist->zones[j] = NULL;
+ }
+}
+
+/*
* Build zonelists ordered by zone and nodes within zones.
* This results in conserving DMA zone[s] until all Normal memory is
* exhausted, but results in overflowing to remote node while memory
@@ -1915,7 +2176,8 @@ static int default_zonelist_order(void)
* If there is a node whose DMA/DMA32 memory is very big area on
* local memory, NODE_ORDER may be suitable.
*/
- average_size = total_size / (num_online_nodes() + 1);
+ average_size = total_size /
+ (nodes_weight(node_states[N_HIGH_MEMORY]) + 1);
for_each_online_node(nid) {
low_kmem_size = 0;
total_size = 0;
@@ -1953,7 +2215,7 @@ static void build_zonelists(pg_data_t *pgdat)
int order = current_zonelist_order;
/* initialize zonelists */
- for (i = 0; i < MAX_NR_ZONES; i++) {
+ for (i = 0; i < MAX_ZONELISTS; i++) {
zonelist = pgdat->node_zonelists + i;
zonelist->zones[0] = NULL;
}
@@ -1998,6 +2260,8 @@ static void build_zonelists(pg_data_t *pgdat)
/* calculate node order -- i.e., DMA last! */
build_zonelists_in_zone_order(pgdat, j);
}
+
+ build_thisnode_zonelists(pgdat);
}
/* Construct the zonelist performance cache - see further mmzone.h */
@@ -2078,8 +2342,10 @@ static int __build_all_zonelists(void *dummy)
int nid;
for_each_online_node(nid) {
- build_zonelists(NODE_DATA(nid));
- build_zonelist_cache(NODE_DATA(nid));
+ pg_data_t *pgdat = NODE_DATA(nid);
+
+ build_zonelists(pgdat);
+ build_zonelist_cache(pgdat);
}
return 0;
}
@@ -2098,9 +2364,23 @@ void build_all_zonelists(void)
/* cpuset refresh routine should be here */
}
vm_total_pages = nr_free_pagecache_pages();
- printk("Built %i zonelists in %s order. Total pages: %ld\n",
+ /*
+ * Disable grouping by mobility if the number of pages in the
+ * system is too low to allow the mechanism to work. It would be
+ * more accurate, but expensive to check per-zone. This check is
+ * made on memory-hotadd so a system can start with mobility
+ * disabled and enable it later
+ */
+ if (vm_total_pages < (pageblock_nr_pages * MIGRATE_TYPES))
+ page_group_by_mobility_disabled = 1;
+ else
+ page_group_by_mobility_disabled = 0;
+
+ printk("Built %i zonelists in %s order, mobility grouping %s. "
+ "Total pages: %ld\n",
num_online_nodes(),
zonelist_order_name[current_zonelist_order],
+ page_group_by_mobility_disabled ? "off" : "on",
vm_total_pages);
#ifdef CONFIG_NUMA
printk("Policy zone: %s\n", zone_names[policy_zone]);
@@ -2176,6 +2456,61 @@ static inline unsigned long wait_table_bits(unsigned long size)
#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
/*
+ * Mark a number of pageblocks as MIGRATE_RESERVE. The number
+ * of blocks reserved is based on zone->pages_min. The memory within the
+ * reserve will tend to store contiguous free pages. Setting min_free_kbytes
+ * higher will lead to a bigger reserve which will get freed as contiguous
+ * blocks as reclaim kicks in
+ */
+static void setup_zone_migrate_reserve(struct zone *zone)
+{
+ unsigned long start_pfn, pfn, end_pfn;
+ struct page *page;
+ unsigned long reserve, block_migratetype;
+
+ /* Get the start pfn, end pfn and the number of blocks to reserve */
+ start_pfn = zone->zone_start_pfn;
+ end_pfn = start_pfn + zone->spanned_pages;
+ reserve = roundup(zone->pages_min, pageblock_nr_pages) >>
+ pageblock_order;
+
+ for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
+ if (!pfn_valid(pfn))
+ continue;
+ page = pfn_to_page(pfn);
+
+ /* Blocks with reserved pages will never free, skip them. */
+ if (PageReserved(page))
+ continue;
+
+ block_migratetype = get_pageblock_migratetype(page);
+
+ /* If this block is reserved, account for it */
+ if (reserve > 0 && block_migratetype == MIGRATE_RESERVE) {
+ reserve--;
+ continue;
+ }
+
+ /* Suitable for reserving if this block is movable */
+ if (reserve > 0 && block_migratetype == MIGRATE_MOVABLE) {
+ set_pageblock_migratetype(page, MIGRATE_RESERVE);
+ move_freepages_block(zone, page, MIGRATE_RESERVE);
+ reserve--;
+ continue;
+ }
+
+ /*
+ * If the reserve is met and this is a previous reserved block,
+ * take it back
+ */
+ if (block_migratetype == MIGRATE_RESERVE) {
+ set_pageblock_migratetype(page, MIGRATE_MOVABLE);
+ move_freepages_block(zone, page, MIGRATE_MOVABLE);
+ }
+ }
+}
+
+/*
* Initially all pages are reserved - free ones are freed
* up by free_all_bootmem() once the early boot process is
* done. Non-atomic initialization, single-pass.
@@ -2204,6 +2539,19 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
init_page_count(page);
reset_page_mapcount(page);
SetPageReserved(page);
+
+ /*
+ * Mark the block movable so that blocks are reserved for
+ * movable at startup. This will force kernel allocations
+ * to reserve their blocks rather than leaking throughout
+ * the address space during boot when many long-lived
+ * kernel allocations are made. Later some blocks near
+ * the start are marked MIGRATE_RESERVE by
+ * setup_zone_migrate_reserve()
+ */
+ if ((pfn & (pageblock_nr_pages-1)))
+ set_pageblock_migratetype(page, MIGRATE_MOVABLE);
+
INIT_LIST_HEAD(&page->lru);
#ifdef WANT_PAGE_VIRTUAL
/* The shift won't overflow because ZONE_NORMAL is below 4G. */
@@ -2216,9 +2564,9 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
static void __meminit zone_init_free_lists(struct pglist_data *pgdat,
struct zone *zone, unsigned long size)
{
- int order;
- for (order = 0; order < MAX_ORDER ; order++) {
- INIT_LIST_HEAD(&zone->free_area[order].free_list);
+ int order, t;
+ for_each_migratetype_order(order, t) {
+ INIT_LIST_HEAD(&zone->free_area[order].free_list[t]);
zone->free_area[order].nr_free = 0;
}
}
@@ -2324,6 +2672,9 @@ static struct per_cpu_pageset boot_pageset[NR_CPUS];
static int __cpuinit process_zones(int cpu)
{
struct zone *zone, *dzone;
+ int node = cpu_to_node(cpu);
+
+ node_set_state(node, N_CPU); /* this node has a cpu */
for_each_zone(zone) {
@@ -2331,7 +2682,7 @@ static int __cpuinit process_zones(int cpu)
continue;
zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset),
- GFP_KERNEL, cpu_to_node(cpu));
+ GFP_KERNEL, node);
if (!zone_pcp(zone, cpu))
goto bad;
@@ -2444,7 +2795,7 @@ int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
* To use this new node's memory, further consideration will be
* necessary.
*/
- zone->wait_table = (wait_queue_head_t *)vmalloc(alloc_size);
+ zone->wait_table = vmalloc(alloc_size);
}
if (!zone->wait_table)
return -ENOMEM;
@@ -2680,10 +3031,8 @@ void __meminit get_pfn_range_for_nid(unsigned int nid,
*end_pfn = max(*end_pfn, early_node_map[i].end_pfn);
}
- if (*start_pfn == -1UL) {
- printk(KERN_WARNING "Node %u active with no memory\n", nid);
+ if (*start_pfn == -1UL)
*start_pfn = 0;
- }
/* Push the node boundaries out if requested */
account_node_boundary(nid, start_pfn, end_pfn);
@@ -2901,6 +3250,62 @@ static void __meminit calculate_node_totalpages(struct pglist_data *pgdat,
realtotalpages);
}
+#ifndef CONFIG_SPARSEMEM
+/*
+ * Calculate the size of the zone->blockflags rounded to an unsigned long
+ * Start by making sure zonesize is a multiple of pageblock_order by rounding
+ * up. Then use 1 NR_PAGEBLOCK_BITS worth of bits per pageblock, finally
+ * round what is now in bits to nearest long in bits, then return it in
+ * bytes.
+ */
+static unsigned long __init usemap_size(unsigned long zonesize)
+{
+ unsigned long usemapsize;
+
+ usemapsize = roundup(zonesize, pageblock_nr_pages);
+ usemapsize = usemapsize >> pageblock_order;
+ usemapsize *= NR_PAGEBLOCK_BITS;
+ usemapsize = roundup(usemapsize, 8 * sizeof(unsigned long));
+
+ return usemapsize / 8;
+}
+
+static void __init setup_usemap(struct pglist_data *pgdat,
+ struct zone *zone, unsigned long zonesize)
+{
+ unsigned long usemapsize = usemap_size(zonesize);
+ zone->pageblock_flags = NULL;
+ if (usemapsize) {
+ zone->pageblock_flags = alloc_bootmem_node(pgdat, usemapsize);
+ memset(zone->pageblock_flags, 0, usemapsize);
+ }
+}
+#else
+static void inline setup_usemap(struct pglist_data *pgdat,
+ struct zone *zone, unsigned long zonesize) {}
+#endif /* CONFIG_SPARSEMEM */
+
+#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
+/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
+static inline void __init set_pageblock_order(unsigned int order)
+{
+ /* Check that pageblock_nr_pages has not already been setup */
+ if (pageblock_order)
+ return;
+
+ /*
+ * Assume the largest contiguous order of interest is a huge page.
+ * This value may be variable depending on boot parameters on IA64
+ */
+ pageblock_order = order;
+}
+#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
+
+/* Defined this way to avoid accidently referencing HUGETLB_PAGE_ORDER */
+#define set_pageblock_order(x) do {} while (0)
+
+#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
+
/*
* Set up the zone data structures:
* - mark all pages reserved
@@ -2977,10 +3382,12 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
zone->nr_scan_active = 0;
zone->nr_scan_inactive = 0;
zap_zone_vm_stats(zone);
- atomic_set(&zone->reclaim_in_progress, 0);
+ zone->flags = 0;
if (!size)
continue;
+ set_pageblock_order(HUGETLB_PAGE_ORDER);
+ setup_usemap(pgdat, zone, size);
ret = init_currently_empty_zone(zone, zone_start_pfn,
size, MEMMAP_EARLY);
BUG_ON(ret);
@@ -3234,16 +3641,24 @@ unsigned long __init find_max_pfn_with_active_regions(void)
return max_pfn;
}
-unsigned long __init early_calculate_totalpages(void)
+/*
+ * early_calculate_totalpages()
+ * Sum pages in active regions for movable zone.
+ * Populate N_HIGH_MEMORY for calculating usable_nodes.
+ */
+static unsigned long __init early_calculate_totalpages(void)
{
int i;
unsigned long totalpages = 0;
- for (i = 0; i < nr_nodemap_entries; i++)
- totalpages += early_node_map[i].end_pfn -
+ for (i = 0; i < nr_nodemap_entries; i++) {
+ unsigned long pages = early_node_map[i].end_pfn -
early_node_map[i].start_pfn;
-
- return totalpages;
+ totalpages += pages;
+ if (pages)
+ node_set_state(early_node_map[i].nid, N_HIGH_MEMORY);
+ }
+ return totalpages;
}
/*
@@ -3257,7 +3672,8 @@ void __init find_zone_movable_pfns_for_nodes(unsigned long *movable_pfn)
int i, nid;
unsigned long usable_startpfn;
unsigned long kernelcore_node, kernelcore_remaining;
- int usable_nodes = num_online_nodes();
+ unsigned long totalpages = early_calculate_totalpages();
+ int usable_nodes = nodes_weight(node_states[N_HIGH_MEMORY]);
/*
* If movablecore was specified, calculate what size of
@@ -3268,7 +3684,6 @@ void __init find_zone_movable_pfns_for_nodes(unsigned long *movable_pfn)
* what movablecore would have allowed.
*/
if (required_movablecore) {
- unsigned long totalpages = early_calculate_totalpages();
unsigned long corepages;
/*
@@ -3293,7 +3708,7 @@ void __init find_zone_movable_pfns_for_nodes(unsigned long *movable_pfn)
restart:
/* Spread kernelcore memory as evenly as possible throughout nodes */
kernelcore_node = required_kernelcore / usable_nodes;
- for_each_online_node(nid) {
+ for_each_node_state(nid, N_HIGH_MEMORY) {
/*
* Recalculate kernelcore_node if the division per node
* now exceeds what is necessary to satisfy the requested
@@ -3385,6 +3800,20 @@ restart:
roundup(zone_movable_pfn[nid], MAX_ORDER_NR_PAGES);
}
+/* Any regular memory on that node ? */
+static void check_for_regular_memory(pg_data_t *pgdat)
+{
+#ifdef CONFIG_HIGHMEM
+ enum zone_type zone_type;
+
+ for (zone_type = 0; zone_type <= ZONE_NORMAL; zone_type++) {
+ struct zone *zone = &pgdat->node_zones[zone_type];
+ if (zone->present_pages)
+ node_set_state(zone_to_nid(zone), N_NORMAL_MEMORY);
+ }
+#endif
+}
+
/**
* free_area_init_nodes - Initialise all pg_data_t and zone data
* @max_zone_pfn: an array of max PFNs for each zone
@@ -3459,6 +3888,11 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
pg_data_t *pgdat = NODE_DATA(nid);
free_area_init_node(nid, pgdat, NULL,
find_min_pfn_for_node(nid), NULL);
+
+ /* Any memory on that node */
+ if (pgdat->node_present_pages)
+ node_set_state(nid, N_HIGH_MEMORY);
+ check_for_regular_memory(pgdat);
}
}
@@ -3673,6 +4107,7 @@ void setup_per_zone_pages_min(void)
zone->pages_low = zone->pages_min + (tmp >> 2);
zone->pages_high = zone->pages_min + (tmp >> 1);
+ setup_zone_migrate_reserve(zone);
spin_unlock_irqrestore(&zone->lru_lock, flags);
}
@@ -3934,4 +4369,169 @@ EXPORT_SYMBOL(pfn_to_page);
EXPORT_SYMBOL(page_to_pfn);
#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */
+/* Return a pointer to the bitmap storing bits affecting a block of pages */
+static inline unsigned long *get_pageblock_bitmap(struct zone *zone,
+ unsigned long pfn)
+{
+#ifdef CONFIG_SPARSEMEM
+ return __pfn_to_section(pfn)->pageblock_flags;
+#else
+ return zone->pageblock_flags;
+#endif /* CONFIG_SPARSEMEM */
+}
+
+static inline int pfn_to_bitidx(struct zone *zone, unsigned long pfn)
+{
+#ifdef CONFIG_SPARSEMEM
+ pfn &= (PAGES_PER_SECTION-1);
+ return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
+#else
+ pfn = pfn - zone->zone_start_pfn;
+ return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
+#endif /* CONFIG_SPARSEMEM */
+}
+
+/**
+ * get_pageblock_flags_group - Return the requested group of flags for the pageblock_nr_pages block of pages
+ * @page: The page within the block of interest
+ * @start_bitidx: The first bit of interest to retrieve
+ * @end_bitidx: The last bit of interest
+ * returns pageblock_bits flags
+ */
+unsigned long get_pageblock_flags_group(struct page *page,
+ int start_bitidx, int end_bitidx)
+{
+ struct zone *zone;
+ unsigned long *bitmap;
+ unsigned long pfn, bitidx;
+ unsigned long flags = 0;
+ unsigned long value = 1;
+
+ zone = page_zone(page);
+ pfn = page_to_pfn(page);
+ bitmap = get_pageblock_bitmap(zone, pfn);
+ bitidx = pfn_to_bitidx(zone, pfn);
+
+ for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
+ if (test_bit(bitidx + start_bitidx, bitmap))
+ flags |= value;
+
+ return flags;
+}
+
+/**
+ * set_pageblock_flags_group - Set the requested group of flags for a pageblock_nr_pages block of pages
+ * @page: The page within the block of interest
+ * @start_bitidx: The first bit of interest
+ * @end_bitidx: The last bit of interest
+ * @flags: The flags to set
+ */
+void set_pageblock_flags_group(struct page *page, unsigned long flags,
+ int start_bitidx, int end_bitidx)
+{
+ struct zone *zone;
+ unsigned long *bitmap;
+ unsigned long pfn, bitidx;
+ unsigned long value = 1;
+
+ zone = page_zone(page);
+ pfn = page_to_pfn(page);
+ bitmap = get_pageblock_bitmap(zone, pfn);
+ bitidx = pfn_to_bitidx(zone, pfn);
+
+ for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
+ if (flags & value)
+ __set_bit(bitidx + start_bitidx, bitmap);
+ else
+ __clear_bit(bitidx + start_bitidx, bitmap);
+}
+
+/*
+ * This is designed as sub function...plz see page_isolation.c also.
+ * set/clear page block's type to be ISOLATE.
+ * page allocater never alloc memory from ISOLATE block.
+ */
+
+int set_migratetype_isolate(struct page *page)
+{
+ struct zone *zone;
+ unsigned long flags;
+ int ret = -EBUSY;
+
+ zone = page_zone(page);
+ spin_lock_irqsave(&zone->lock, flags);
+ /*
+ * In future, more migrate types will be able to be isolation target.
+ */
+ if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE)
+ goto out;
+ set_pageblock_migratetype(page, MIGRATE_ISOLATE);
+ move_freepages_block(zone, page, MIGRATE_ISOLATE);
+ ret = 0;
+out:
+ spin_unlock_irqrestore(&zone->lock, flags);
+ if (!ret)
+ drain_all_local_pages();
+ return ret;
+}
+void unset_migratetype_isolate(struct page *page)
+{
+ struct zone *zone;
+ unsigned long flags;
+ zone = page_zone(page);
+ spin_lock_irqsave(&zone->lock, flags);
+ if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
+ goto out;
+ set_pageblock_migratetype(page, MIGRATE_MOVABLE);
+ move_freepages_block(zone, page, MIGRATE_MOVABLE);
+out:
+ spin_unlock_irqrestore(&zone->lock, flags);
+}
+
+#ifdef CONFIG_MEMORY_HOTREMOVE
+/*
+ * All pages in the range must be isolated before calling this.
+ */
+void
+__offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
+{
+ struct page *page;
+ struct zone *zone;
+ int order, i;
+ unsigned long pfn;
+ unsigned long flags;
+ /* find the first valid pfn */
+ for (pfn = start_pfn; pfn < end_pfn; pfn++)
+ if (pfn_valid(pfn))
+ break;
+ if (pfn == end_pfn)
+ return;
+ zone = page_zone(pfn_to_page(pfn));
+ spin_lock_irqsave(&zone->lock, flags);
+ pfn = start_pfn;
+ while (pfn < end_pfn) {
+ if (!pfn_valid(pfn)) {
+ pfn++;
+ continue;
+ }
+ page = pfn_to_page(pfn);
+ BUG_ON(page_count(page));
+ BUG_ON(!PageBuddy(page));
+ order = page_order(page);
+#ifdef CONFIG_DEBUG_VM
+ printk(KERN_INFO "remove from free list %lx %d %lx\n",
+ pfn, 1 << order, end_pfn);
+#endif
+ list_del(&page->lru);
+ rmv_page_order(page);
+ zone->free_area[order].nr_free--;
+ __mod_zone_page_state(zone, NR_FREE_PAGES,
+ - (1UL << order));
+ for (i = 0; i < (1 << order); i++)
+ SetPageReserved((page+i));
+ pfn += (1 << order);
+ }
+ spin_unlock_irqrestore(&zone->lock, flags);
+}
+#endif
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
new file mode 100644
index 00000000000..8f92a29695c
--- /dev/null
+++ b/mm/page_isolation.c
@@ -0,0 +1,138 @@
+/*
+ * linux/mm/page_isolation.c
+ */
+
+#include <stddef.h>
+#include <linux/mm.h>
+#include <linux/page-isolation.h>
+#include <linux/pageblock-flags.h>
+#include "internal.h"
+
+static inline struct page *
+__first_valid_page(unsigned long pfn, unsigned long nr_pages)
+{
+ int i;
+ for (i = 0; i < nr_pages; i++)
+ if (pfn_valid_within(pfn + i))
+ break;
+ if (unlikely(i == nr_pages))
+ return NULL;
+ return pfn_to_page(pfn + i);
+}
+
+/*
+ * start_isolate_page_range() -- make page-allocation-type of range of pages
+ * to be MIGRATE_ISOLATE.
+ * @start_pfn: The lower PFN of the range to be isolated.
+ * @end_pfn: The upper PFN of the range to be isolated.
+ *
+ * Making page-allocation-type to be MIGRATE_ISOLATE means free pages in
+ * the range will never be allocated. Any free pages and pages freed in the
+ * future will not be allocated again.
+ *
+ * start_pfn/end_pfn must be aligned to pageblock_order.
+ * Returns 0 on success and -EBUSY if any part of range cannot be isolated.
+ */
+int
+start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long pfn;
+ unsigned long undo_pfn;
+ struct page *page;
+
+ BUG_ON((start_pfn) & (pageblock_nr_pages - 1));
+ BUG_ON((end_pfn) & (pageblock_nr_pages - 1));
+
+ for (pfn = start_pfn;
+ pfn < end_pfn;
+ pfn += pageblock_nr_pages) {
+ page = __first_valid_page(pfn, pageblock_nr_pages);
+ if (page && set_migratetype_isolate(page)) {
+ undo_pfn = pfn;
+ goto undo;
+ }
+ }
+ return 0;
+undo:
+ for (pfn = start_pfn;
+ pfn <= undo_pfn;
+ pfn += pageblock_nr_pages)
+ unset_migratetype_isolate(pfn_to_page(pfn));
+
+ return -EBUSY;
+}
+
+/*
+ * Make isolated pages available again.
+ */
+int
+undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long pfn;
+ struct page *page;
+ BUG_ON((start_pfn) & (pageblock_nr_pages - 1));
+ BUG_ON((end_pfn) & (pageblock_nr_pages - 1));
+ for (pfn = start_pfn;
+ pfn < end_pfn;
+ pfn += pageblock_nr_pages) {
+ page = __first_valid_page(pfn, pageblock_nr_pages);
+ if (!page || get_pageblock_flags(page) != MIGRATE_ISOLATE)
+ continue;
+ unset_migratetype_isolate(page);
+ }
+ return 0;
+}
+/*
+ * Test all pages in the range is free(means isolated) or not.
+ * all pages in [start_pfn...end_pfn) must be in the same zone.
+ * zone->lock must be held before call this.
+ *
+ * Returns 0 if all pages in the range is isolated.
+ */
+static int
+__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
+{
+ struct page *page;
+
+ while (pfn < end_pfn) {
+ if (!pfn_valid_within(pfn)) {
+ pfn++;
+ continue;
+ }
+ page = pfn_to_page(pfn);
+ if (PageBuddy(page))
+ pfn += 1 << page_order(page);
+ else if (page_count(page) == 0 &&
+ page_private(page) == MIGRATE_ISOLATE)
+ pfn += 1;
+ else
+ break;
+ }
+ if (pfn < end_pfn)
+ return 0;
+ return 1;
+}
+
+int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
+{
+ unsigned long pfn;
+ struct page *page;
+
+ pfn = start_pfn;
+ /*
+ * Note: pageblock_nr_page != MAX_ORDER. Then, chunks of free page
+ * is not aligned to pageblock_nr_pages.
+ * Then we just check pagetype fist.
+ */
+ for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
+ page = __first_valid_page(pfn, pageblock_nr_pages);
+ if (page && get_pageblock_flags(page) != MIGRATE_ISOLATE)
+ break;
+ }
+ if (pfn < end_pfn)
+ return -EBUSY;
+ /* Check all pages are free or Marked as ISOLATED */
+ if (__test_page_isolated_in_pageblock(start_pfn, end_pfn))
+ return 0;
+ return -EBUSY;
+}
diff --git a/mm/readahead.c b/mm/readahead.c
index be20c9d699d..c9c50ca1ec3 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -22,16 +22,8 @@ void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
}
EXPORT_SYMBOL(default_unplug_io_fn);
-/*
- * Convienent macros for min/max read-ahead pages.
- * Note that MAX_RA_PAGES is rounded down, while MIN_RA_PAGES is rounded up.
- * The latter is necessary for systems with large page size(i.e. 64k).
- */
-#define MAX_RA_PAGES (VM_MAX_READAHEAD*1024 / PAGE_CACHE_SIZE)
-#define MIN_RA_PAGES DIV_ROUND_UP(VM_MIN_READAHEAD*1024, PAGE_CACHE_SIZE)
-
struct backing_dev_info default_backing_dev_info = {
- .ra_pages = MAX_RA_PAGES,
+ .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE,
.state = 0,
.capabilities = BDI_CAP_MAP_COPY,
.unplug_io_fn = default_unplug_io_fn,
@@ -46,7 +38,7 @@ void
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping)
{
ra->ra_pages = mapping->backing_dev_info->ra_pages;
- ra->prev_index = -1;
+ ra->prev_pos = -1;
}
EXPORT_SYMBOL_GPL(file_ra_state_init);
@@ -66,28 +58,25 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
int (*filler)(void *, struct page *), void *data)
{
struct page *page;
- struct pagevec lru_pvec;
int ret = 0;
- pagevec_init(&lru_pvec, 0);
-
while (!list_empty(pages)) {
page = list_to_page(pages);
list_del(&page->lru);
- if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
+ if (add_to_page_cache_lru(page, mapping,
+ page->index, GFP_KERNEL)) {
page_cache_release(page);
continue;
}
+ page_cache_release(page);
+
ret = filler(data, page);
- if (!pagevec_add(&lru_pvec, page))
- __pagevec_lru_add(&lru_pvec);
- if (ret) {
+ if (unlikely(ret)) {
put_pages_list(pages);
break;
}
task_io_account_read(PAGE_CACHE_SIZE);
}
- pagevec_lru_add(&lru_pvec);
return ret;
}
@@ -97,7 +86,6 @@ static int read_pages(struct address_space *mapping, struct file *filp,
struct list_head *pages, unsigned nr_pages)
{
unsigned page_idx;
- struct pagevec lru_pvec;
int ret;
if (mapping->a_ops->readpages) {
@@ -107,19 +95,15 @@ static int read_pages(struct address_space *mapping, struct file *filp,
goto out;
}
- pagevec_init(&lru_pvec, 0);
for (page_idx = 0; page_idx < nr_pages; page_idx++) {
struct page *page = list_to_page(pages);
list_del(&page->lru);
- if (!add_to_page_cache(page, mapping,
+ if (!add_to_page_cache_lru(page, mapping,
page->index, GFP_KERNEL)) {
mapping->a_ops->readpage(filp, page);
- if (!pagevec_add(&lru_pvec, page))
- __pagevec_lru_add(&lru_pvec);
- } else
- page_cache_release(page);
+ }
+ page_cache_release(page);
}
- pagevec_lru_add(&lru_pvec);
ret = 0;
out:
return ret;
@@ -157,20 +141,19 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
/*
* Preallocate as many pages as we will need.
*/
- read_lock_irq(&mapping->tree_lock);
for (page_idx = 0; page_idx < nr_to_read; page_idx++) {
pgoff_t page_offset = offset + page_idx;
if (page_offset > end_index)
break;
+ rcu_read_lock();
page = radix_tree_lookup(&mapping->page_tree, page_offset);
+ rcu_read_unlock();
if (page)
continue;
- read_unlock_irq(&mapping->tree_lock);
page = page_cache_alloc_cold(mapping);
- read_lock_irq(&mapping->tree_lock);
if (!page)
break;
page->index = page_offset;
@@ -179,7 +162,6 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
SetPageReadahead(page);
ret++;
}
- read_unlock_irq(&mapping->tree_lock);
/*
* Now start the IO. We ignore I/O errors - if the page is not
@@ -251,6 +233,12 @@ unsigned long max_sane_readahead(unsigned long nr)
+ node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2);
}
+static int __init readahead_init(void)
+{
+ return bdi_init(&default_backing_dev_info);
+}
+subsys_initcall(readahead_init);
+
/*
* Submit IO for the read-ahead request in file_ra_state.
*/
@@ -327,7 +315,7 @@ static unsigned long get_next_ra_size(struct file_ra_state *ra,
* indicator. The flag won't be set on already cached pages, to avoid the
* readahead-for-nothing fuss, saving pointless page cache lookups.
*
- * prev_index tracks the last visited page in the _previous_ read request.
+ * prev_pos tracks the last visited byte in the _previous_ read request.
* It should be maintained by the caller, and will be used for detecting
* small random reads. Note that the readahead algorithm checks loosely
* for sequential patterns. Hence interleaved reads might be served as
@@ -351,11 +339,9 @@ ondemand_readahead(struct address_space *mapping,
bool hit_readahead_marker, pgoff_t offset,
unsigned long req_size)
{
- unsigned long max; /* max readahead pages */
- int sequential;
-
- max = ra->ra_pages;
- sequential = (offset - ra->prev_index <= 1UL) || (req_size > max);
+ int max = ra->ra_pages; /* max readahead pages */
+ pgoff_t prev_offset;
+ int sequential;
/*
* It's the expected callback offset, assume sequential access.
@@ -369,6 +355,9 @@ ondemand_readahead(struct address_space *mapping,
goto readit;
}
+ prev_offset = ra->prev_pos >> PAGE_CACHE_SHIFT;
+ sequential = offset - prev_offset <= 1UL || req_size > max;
+
/*
* Standalone, small read.
* Read as is, and do not pollute the readahead state.
@@ -379,6 +368,29 @@ ondemand_readahead(struct address_space *mapping,
}
/*
+ * Hit a marked page without valid readahead state.
+ * E.g. interleaved reads.
+ * Query the pagecache for async_size, which normally equals to
+ * readahead size. Ramp it up and use it as the new readahead size.
+ */
+ if (hit_readahead_marker) {
+ pgoff_t start;
+
+ read_lock_irq(&mapping->tree_lock);
+ start = radix_tree_next_hole(&mapping->page_tree, offset, max+1);
+ read_unlock_irq(&mapping->tree_lock);
+
+ if (!start || start - offset > max)
+ return 0;
+
+ ra->start = start;
+ ra->size = start - offset; /* old async_size */
+ ra->size = get_next_ra_size(ra, max);
+ ra->async_size = ra->size;
+ goto readit;
+ }
+
+ /*
* It may be one of
* - first read on start of file
* - sequential cache miss
@@ -389,16 +401,6 @@ ondemand_readahead(struct address_space *mapping,
ra->size = get_init_ra_size(req_size, max);
ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;
- /*
- * Hit on a marked page without valid readahead state.
- * E.g. interleaved reads.
- * Not knowing its readahead pos/size, bet on the minimal possible one.
- */
- if (hit_readahead_marker) {
- ra->start++;
- ra->size = get_next_ra_size(ra, max);
- }
-
readit:
return ra_submit(ra, mapping, filp);
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 41ac39749ef..8990f909492 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -36,6 +36,7 @@
* mapping->tree_lock (widely used, in set_page_dirty,
* in arch-dependent flush_dcache_mmap_lock,
* within inode_lock in __sync_single_inode)
+ * zone->lock (within radix tree node alloc)
*/
#include <linux/mm.h>
@@ -137,8 +138,7 @@ void anon_vma_unlink(struct vm_area_struct *vma)
anon_vma_free(anon_vma);
}
-static void anon_vma_ctor(void *data, struct kmem_cache *cachep,
- unsigned long flags)
+static void anon_vma_ctor(struct kmem_cache *cachep, void *data)
{
struct anon_vma *anon_vma = data;
@@ -436,7 +436,6 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma)
entry = pte_wrprotect(entry);
entry = pte_mkclean(entry);
set_pte_at(mm, address, pte, entry);
- lazy_mmu_prot_update(entry);
ret = 1;
}
diff --git a/mm/shmem.c b/mm/shmem.c
index fcd19d323f9..289dbb0a6fd 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -49,7 +49,6 @@
#include <linux/ctype.h>
#include <linux/migrate.h>
#include <linux/highmem.h>
-#include <linux/backing-dev.h>
#include <asm/uaccess.h>
#include <asm/div64.h>
@@ -96,9 +95,9 @@ static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
* BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE:
* might be reconsidered if it ever diverges from PAGE_SIZE.
*
- * __GFP_MOVABLE is masked out as swap vectors cannot move
+ * Mobility flags are masked out as swap vectors cannot move
*/
- return alloc_pages((gfp_mask & ~__GFP_MOVABLE) | __GFP_ZERO,
+ return alloc_pages((gfp_mask & ~GFP_MOVABLE_MASK) | __GFP_ZERO,
PAGE_CACHE_SHIFT-PAGE_SHIFT);
}
@@ -972,7 +971,7 @@ static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_
*nodelist++ = '\0';
if (nodelist_parse(nodelist, *policy_nodes))
goto out;
- if (!nodes_subset(*policy_nodes, node_online_map))
+ if (!nodes_subset(*policy_nodes, node_states[N_HIGH_MEMORY]))
goto out;
}
if (!strcmp(value, "default")) {
@@ -997,9 +996,11 @@ static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_
err = 0;
} else if (!strcmp(value, "interleave")) {
*policy = MPOL_INTERLEAVE;
- /* Default to nodes online if no nodelist */
+ /*
+ * Default to online nodes with memory if no nodelist
+ */
if (!nodelist)
- *policy_nodes = node_online_map;
+ *policy_nodes = node_states[N_HIGH_MEMORY];
err = 0;
}
out:
@@ -1025,8 +1026,8 @@ static struct page *shmem_swapin_async(struct shared_policy *p,
return page;
}
-struct page *shmem_swapin(struct shmem_inode_info *info, swp_entry_t entry,
- unsigned long idx)
+static struct page *shmem_swapin(struct shmem_inode_info *info,
+ swp_entry_t entry, unsigned long idx)
{
struct shared_policy *p = &info->policy;
int i, num;
@@ -1061,7 +1062,8 @@ shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
return page;
}
#else
-static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes)
+static inline int shmem_parse_mpol(char *value, int *policy,
+ nodemask_t *policy_nodes)
{
return 1;
}
@@ -1109,7 +1111,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
* Normally, filepage is NULL on entry, and either found
* uptodate immediately, or allocated and zeroed, or read
* in under swappage, which is then assigned to filepage.
- * But shmem_readpage and shmem_prepare_write pass in a locked
+ * But shmem_readpage and shmem_write_begin pass in a locked
* filepage, which may be found not uptodate by other callers
* too, and may need to be copied from the swappage read in.
*/
@@ -1327,14 +1329,14 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
#ifdef CONFIG_NUMA
-int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
+static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
{
struct inode *i = vma->vm_file->f_path.dentry->d_inode;
return mpol_set_shared_policy(&SHMEM_I(i)->policy, vma, new);
}
-struct mempolicy *
-shmem_get_policy(struct vm_area_struct *vma, unsigned long addr)
+static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
+ unsigned long addr)
{
struct inode *i = vma->vm_file->f_path.dentry->d_inode;
unsigned long idx;
@@ -1446,7 +1448,7 @@ static const struct inode_operations shmem_symlink_inode_operations;
static const struct inode_operations shmem_symlink_inline_operations;
/*
- * Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write;
+ * Normally tmpfs avoids the use of shmem_readpage and shmem_write_begin;
* but providing them allows a tmpfs file to be used for splice, sendfile, and
* below the loop driver, in the generic fashion that many filesystems support.
*/
@@ -1459,10 +1461,30 @@ static int shmem_readpage(struct file *file, struct page *page)
}
static int
-shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+shmem_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
- struct inode *inode = page->mapping->host;
- return shmem_getpage(inode, page->index, &page, SGP_WRITE, NULL);
+ struct inode *inode = mapping->host;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ *pagep = NULL;
+ return shmem_getpage(inode, index, pagep, SGP_WRITE, NULL);
+}
+
+static int
+shmem_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+
+ set_page_dirty(page);
+ page_cache_release(page);
+
+ if (pos+copied > inode->i_size)
+ i_size_write(inode, pos+copied);
+
+ return copied;
}
static ssize_t
@@ -2219,7 +2241,7 @@ static int shmem_fill_super(struct super_block *sb,
unsigned long blocks = 0;
unsigned long inodes = 0;
int policy = MPOL_DEFAULT;
- nodemask_t policy_nodes = node_online_map;
+ nodemask_t policy_nodes = node_states[N_HIGH_MEMORY];
#ifdef CONFIG_TMPFS
/*
@@ -2306,8 +2328,7 @@ static void shmem_destroy_inode(struct inode *inode)
kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode));
}
-static void init_once(void *foo, struct kmem_cache *cachep,
- unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct shmem_inode_info *p = (struct shmem_inode_info *) foo;
@@ -2322,9 +2343,7 @@ static int init_inodecache(void)
{
shmem_inode_cachep = kmem_cache_create("shmem_inode_cache",
sizeof(struct shmem_inode_info),
- 0, 0, init_once);
- if (shmem_inode_cachep == NULL)
- return -ENOMEM;
+ 0, SLAB_PANIC, init_once);
return 0;
}
@@ -2338,8 +2357,8 @@ static const struct address_space_operations shmem_aops = {
.set_page_dirty = __set_page_dirty_no_writeback,
#ifdef CONFIG_TMPFS
.readpage = shmem_readpage,
- .prepare_write = shmem_prepare_write,
- .commit_write = simple_commit_write,
+ .write_begin = shmem_write_begin,
+ .write_end = shmem_write_end,
#endif
.migratepage = migrate_page,
};
@@ -2442,6 +2461,10 @@ static int __init init_tmpfs(void)
{
int error;
+ error = bdi_init(&shmem_backing_dev_info);
+ if (error)
+ goto out4;
+
error = init_inodecache();
if (error)
goto out3;
@@ -2466,6 +2489,8 @@ out1:
out2:
destroy_inodecache();
out3:
+ bdi_destroy(&shmem_backing_dev_info);
+out4:
shm_mnt = ERR_PTR(error);
return error;
}
@@ -2518,11 +2543,8 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
d_instantiate(dentry, inode);
inode->i_size = size;
inode->i_nlink = 0; /* It is unlinked */
- file->f_path.mnt = mntget(shm_mnt);
- file->f_path.dentry = dentry;
- file->f_mapping = inode->i_mapping;
- file->f_op = &shmem_file_operations;
- file->f_mode = FMODE_WRITE | FMODE_READ;
+ init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
+ &shmem_file_operations);
return file;
close_file:
diff --git a/mm/slab.c b/mm/slab.c
index 6f6abef83a1..54eb555c4ef 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -267,11 +267,10 @@ struct array_cache {
unsigned int batchcount;
unsigned int touched;
spinlock_t lock;
- void *entry[0]; /*
+ void *entry[]; /*
* Must have this definition in here for the proper
* alignment of array_cache. Also simplifies accessing
* the entries.
- * [0] is for gcc 2.95. It should really be [].
*/
};
@@ -408,7 +407,7 @@ struct kmem_cache {
unsigned int dflags; /* dynamic flags */
/* constructor func */
- void (*ctor) (void *, struct kmem_cache *, unsigned long);
+ void (*ctor)(struct kmem_cache *, void *);
/* 5) cache creation/removal */
const char *name;
@@ -1157,105 +1156,187 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
}
#endif
-static int __cpuinit cpuup_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
+static void __cpuinit cpuup_canceled(long cpu)
+{
+ struct kmem_cache *cachep;
+ struct kmem_list3 *l3 = NULL;
+ int node = cpu_to_node(cpu);
+
+ list_for_each_entry(cachep, &cache_chain, next) {
+ struct array_cache *nc;
+ struct array_cache *shared;
+ struct array_cache **alien;
+ cpumask_t mask;
+
+ mask = node_to_cpumask(node);
+ /* cpu is dead; no one can alloc from it. */
+ nc = cachep->array[cpu];
+ cachep->array[cpu] = NULL;
+ l3 = cachep->nodelists[node];
+
+ if (!l3)
+ goto free_array_cache;
+
+ spin_lock_irq(&l3->list_lock);
+
+ /* Free limit for this kmem_list3 */
+ l3->free_limit -= cachep->batchcount;
+ if (nc)
+ free_block(cachep, nc->entry, nc->avail, node);
+
+ if (!cpus_empty(mask)) {
+ spin_unlock_irq(&l3->list_lock);
+ goto free_array_cache;
+ }
+
+ shared = l3->shared;
+ if (shared) {
+ free_block(cachep, shared->entry,
+ shared->avail, node);
+ l3->shared = NULL;
+ }
+
+ alien = l3->alien;
+ l3->alien = NULL;
+
+ spin_unlock_irq(&l3->list_lock);
+
+ kfree(shared);
+ if (alien) {
+ drain_alien_cache(cachep, alien);
+ free_alien_cache(alien);
+ }
+free_array_cache:
+ kfree(nc);
+ }
+ /*
+ * In the previous loop, all the objects were freed to
+ * the respective cache's slabs, now we can go ahead and
+ * shrink each nodelist to its limit.
+ */
+ list_for_each_entry(cachep, &cache_chain, next) {
+ l3 = cachep->nodelists[node];
+ if (!l3)
+ continue;
+ drain_freelist(cachep, l3, l3->free_objects);
+ }
+}
+
+static int __cpuinit cpuup_prepare(long cpu)
{
- long cpu = (long)hcpu;
struct kmem_cache *cachep;
struct kmem_list3 *l3 = NULL;
int node = cpu_to_node(cpu);
const int memsize = sizeof(struct kmem_list3);
- switch (action) {
- case CPU_LOCK_ACQUIRE:
- mutex_lock(&cache_chain_mutex);
- break;
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
+ /*
+ * We need to do this right in the beginning since
+ * alloc_arraycache's are going to use this list.
+ * kmalloc_node allows us to add the slab to the right
+ * kmem_list3 and not this cpu's kmem_list3
+ */
+
+ list_for_each_entry(cachep, &cache_chain, next) {
/*
- * We need to do this right in the beginning since
- * alloc_arraycache's are going to use this list.
- * kmalloc_node allows us to add the slab to the right
- * kmem_list3 and not this cpu's kmem_list3
+ * Set up the size64 kmemlist for cpu before we can
+ * begin anything. Make sure some other cpu on this
+ * node has not already allocated this
*/
+ if (!cachep->nodelists[node]) {
+ l3 = kmalloc_node(memsize, GFP_KERNEL, node);
+ if (!l3)
+ goto bad;
+ kmem_list3_init(l3);
+ l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
+ ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
- list_for_each_entry(cachep, &cache_chain, next) {
/*
- * Set up the size64 kmemlist for cpu before we can
- * begin anything. Make sure some other cpu on this
- * node has not already allocated this
+ * The l3s don't come and go as CPUs come and
+ * go. cache_chain_mutex is sufficient
+ * protection here.
*/
- if (!cachep->nodelists[node]) {
- l3 = kmalloc_node(memsize, GFP_KERNEL, node);
- if (!l3)
- goto bad;
- kmem_list3_init(l3);
- l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
- ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
-
- /*
- * The l3s don't come and go as CPUs come and
- * go. cache_chain_mutex is sufficient
- * protection here.
- */
- cachep->nodelists[node] = l3;
- }
-
- spin_lock_irq(&cachep->nodelists[node]->list_lock);
- cachep->nodelists[node]->free_limit =
- (1 + nr_cpus_node(node)) *
- cachep->batchcount + cachep->num;
- spin_unlock_irq(&cachep->nodelists[node]->list_lock);
+ cachep->nodelists[node] = l3;
}
- /*
- * Now we can go ahead with allocating the shared arrays and
- * array caches
- */
- list_for_each_entry(cachep, &cache_chain, next) {
- struct array_cache *nc;
- struct array_cache *shared = NULL;
- struct array_cache **alien = NULL;
-
- nc = alloc_arraycache(node, cachep->limit,
- cachep->batchcount);
- if (!nc)
+ spin_lock_irq(&cachep->nodelists[node]->list_lock);
+ cachep->nodelists[node]->free_limit =
+ (1 + nr_cpus_node(node)) *
+ cachep->batchcount + cachep->num;
+ spin_unlock_irq(&cachep->nodelists[node]->list_lock);
+ }
+
+ /*
+ * Now we can go ahead with allocating the shared arrays and
+ * array caches
+ */
+ list_for_each_entry(cachep, &cache_chain, next) {
+ struct array_cache *nc;
+ struct array_cache *shared = NULL;
+ struct array_cache **alien = NULL;
+
+ nc = alloc_arraycache(node, cachep->limit,
+ cachep->batchcount);
+ if (!nc)
+ goto bad;
+ if (cachep->shared) {
+ shared = alloc_arraycache(node,
+ cachep->shared * cachep->batchcount,
+ 0xbaadf00d);
+ if (!shared) {
+ kfree(nc);
goto bad;
- if (cachep->shared) {
- shared = alloc_arraycache(node,
- cachep->shared * cachep->batchcount,
- 0xbaadf00d);
- if (!shared)
- goto bad;
}
- if (use_alien_caches) {
- alien = alloc_alien_cache(node, cachep->limit);
- if (!alien)
- goto bad;
- }
- cachep->array[cpu] = nc;
- l3 = cachep->nodelists[node];
- BUG_ON(!l3);
-
- spin_lock_irq(&l3->list_lock);
- if (!l3->shared) {
- /*
- * We are serialised from CPU_DEAD or
- * CPU_UP_CANCELLED by the cpucontrol lock
- */
- l3->shared = shared;
- shared = NULL;
+ }
+ if (use_alien_caches) {
+ alien = alloc_alien_cache(node, cachep->limit);
+ if (!alien) {
+ kfree(shared);
+ kfree(nc);
+ goto bad;
}
+ }
+ cachep->array[cpu] = nc;
+ l3 = cachep->nodelists[node];
+ BUG_ON(!l3);
+
+ spin_lock_irq(&l3->list_lock);
+ if (!l3->shared) {
+ /*
+ * We are serialised from CPU_DEAD or
+ * CPU_UP_CANCELLED by the cpucontrol lock
+ */
+ l3->shared = shared;
+ shared = NULL;
+ }
#ifdef CONFIG_NUMA
- if (!l3->alien) {
- l3->alien = alien;
- alien = NULL;
- }
-#endif
- spin_unlock_irq(&l3->list_lock);
- kfree(shared);
- free_alien_cache(alien);
+ if (!l3->alien) {
+ l3->alien = alien;
+ alien = NULL;
}
+#endif
+ spin_unlock_irq(&l3->list_lock);
+ kfree(shared);
+ free_alien_cache(alien);
+ }
+ return 0;
+bad:
+ cpuup_canceled(cpu);
+ return -ENOMEM;
+}
+
+static int __cpuinit cpuup_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ long cpu = (long)hcpu;
+ int err = 0;
+
+ switch (action) {
+ case CPU_LOCK_ACQUIRE:
+ mutex_lock(&cache_chain_mutex);
+ break;
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ err = cpuup_prepare(cpu);
break;
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
@@ -1292,72 +1373,13 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
#endif
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
- list_for_each_entry(cachep, &cache_chain, next) {
- struct array_cache *nc;
- struct array_cache *shared;
- struct array_cache **alien;
- cpumask_t mask;
-
- mask = node_to_cpumask(node);
- /* cpu is dead; no one can alloc from it. */
- nc = cachep->array[cpu];
- cachep->array[cpu] = NULL;
- l3 = cachep->nodelists[node];
-
- if (!l3)
- goto free_array_cache;
-
- spin_lock_irq(&l3->list_lock);
-
- /* Free limit for this kmem_list3 */
- l3->free_limit -= cachep->batchcount;
- if (nc)
- free_block(cachep, nc->entry, nc->avail, node);
-
- if (!cpus_empty(mask)) {
- spin_unlock_irq(&l3->list_lock);
- goto free_array_cache;
- }
-
- shared = l3->shared;
- if (shared) {
- free_block(cachep, shared->entry,
- shared->avail, node);
- l3->shared = NULL;
- }
-
- alien = l3->alien;
- l3->alien = NULL;
-
- spin_unlock_irq(&l3->list_lock);
-
- kfree(shared);
- if (alien) {
- drain_alien_cache(cachep, alien);
- free_alien_cache(alien);
- }
-free_array_cache:
- kfree(nc);
- }
- /*
- * In the previous loop, all the objects were freed to
- * the respective cache's slabs, now we can go ahead and
- * shrink each nodelist to its limit.
- */
- list_for_each_entry(cachep, &cache_chain, next) {
- l3 = cachep->nodelists[node];
- if (!l3)
- continue;
- drain_freelist(cachep, l3, l3->free_objects);
- }
+ cpuup_canceled(cpu);
break;
case CPU_LOCK_RELEASE:
mutex_unlock(&cache_chain_mutex);
break;
}
- return NOTIFY_OK;
-bad:
- return NOTIFY_BAD;
+ return err ? NOTIFY_BAD : NOTIFY_OK;
}
static struct notifier_block __cpuinitdata cpucache_notifier = {
@@ -1568,7 +1590,7 @@ void __init kmem_cache_init(void)
/* Replace the static kmem_list3 structures for the boot cpu */
init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node);
- for_each_online_node(nid) {
+ for_each_node_state(nid, N_NORMAL_MEMORY) {
init_list(malloc_sizes[INDEX_AC].cs_cachep,
&initkmem_list3[SIZE_AC + nid], nid);
@@ -1643,6 +1665,8 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
#endif
flags |= cachep->gfpflags;
+ if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
+ flags |= __GFP_RECLAIMABLE;
page = alloc_pages_node(nodeid, flags, cachep->gfporder);
if (!page)
@@ -1944,7 +1968,7 @@ static void __init set_up_list3s(struct kmem_cache *cachep, int index)
{
int node;
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
cachep->nodelists[node] = &initkmem_list3[index + node];
cachep->nodelists[node]->next_reap = jiffies +
REAPTIMEOUT_LIST3 +
@@ -2075,7 +2099,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep)
g_cpucache_up = PARTIAL_L3;
} else {
int node;
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
cachep->nodelists[node] =
kmalloc_node(sizeof(struct kmem_list3),
GFP_KERNEL, node);
@@ -2127,7 +2151,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep)
struct kmem_cache *
kmem_cache_create (const char *name, size_t size, size_t align,
unsigned long flags,
- void (*ctor)(void*, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
size_t left_over, slab_size, ralign;
struct kmem_cache *cachep = NULL, *pc;
@@ -2634,8 +2658,7 @@ static void cache_init_objs(struct kmem_cache *cachep,
* They must also be threaded.
*/
if (cachep->ctor && !(cachep->flags & SLAB_POISON))
- cachep->ctor(objp + obj_offset(cachep), cachep,
- 0);
+ cachep->ctor(cachep, objp + obj_offset(cachep));
if (cachep->flags & SLAB_RED_ZONE) {
if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
@@ -2651,7 +2674,7 @@ static void cache_init_objs(struct kmem_cache *cachep,
cachep->buffer_size / PAGE_SIZE, 0);
#else
if (cachep->ctor)
- cachep->ctor(objp, cachep, 0);
+ cachep->ctor(cachep, objp);
#endif
slab_bufctl(slabp)[i] = i + 1;
}
@@ -2746,9 +2769,9 @@ static int cache_grow(struct kmem_cache *cachep,
* Be lazy and only check for valid flags here, keeping it out of the
* critical path in kmem_cache_alloc().
*/
- BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK));
+ BUG_ON(flags & GFP_SLAB_BUG_MASK);
+ local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);
- local_flags = (flags & GFP_LEVEL_MASK);
/* Take the l3 list lock to change the colour_next on this node */
check_irq_off();
l3 = cachep->nodelists[nodeid];
@@ -2785,7 +2808,7 @@ static int cache_grow(struct kmem_cache *cachep,
/* Get slab management. */
slabp = alloc_slabmgmt(cachep, objp, offset,
- local_flags & ~GFP_THISNODE, nodeid);
+ local_flags & ~GFP_CONSTRAINT_MASK, nodeid);
if (!slabp)
goto opps1;
@@ -3076,7 +3099,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
#endif
objp += obj_offset(cachep);
if (cachep->ctor && cachep->flags & SLAB_POISON)
- cachep->ctor(objp, cachep, 0);
+ cachep->ctor(cachep, objp);
#if ARCH_SLAB_MINALIGN
if ((u32)objp & (ARCH_SLAB_MINALIGN-1)) {
printk(KERN_ERR "0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n",
@@ -3225,7 +3248,7 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
zonelist = &NODE_DATA(slab_node(current->mempolicy))
->node_zonelists[gfp_zone(flags)];
- local_flags = (flags & GFP_LEVEL_MASK);
+ local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);
retry:
/*
@@ -3792,7 +3815,7 @@ static int alloc_kmemlist(struct kmem_cache *cachep)
struct array_cache *new_shared;
struct array_cache **new_alien = NULL;
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
if (use_alien_caches) {
new_alien = alloc_alien_cache(node, cachep->limit);
@@ -4446,7 +4469,8 @@ const struct seq_operations slabstats_op = {
*/
size_t ksize(const void *objp)
{
- if (unlikely(ZERO_OR_NULL_PTR(objp)))
+ BUG_ON(!objp);
+ if (unlikely(objp == ZERO_SIZE_PTR))
return 0;
return obj_size(virt_to_cache(objp));
diff --git a/mm/slob.c b/mm/slob.c
index ec33fcdc852..5bc2ceb692e 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -360,7 +360,7 @@ static void slob_free(void *block, int size)
slobidx_t units;
unsigned long flags;
- if (ZERO_OR_NULL_PTR(block))
+ if (unlikely(ZERO_OR_NULL_PTR(block)))
return;
BUG_ON(!size);
@@ -466,7 +466,7 @@ void kfree(const void *block)
{
struct slob_page *sp;
- if (ZERO_OR_NULL_PTR(block))
+ if (unlikely(ZERO_OR_NULL_PTR(block)))
return;
sp = (struct slob_page *)virt_to_page(block);
@@ -484,7 +484,8 @@ size_t ksize(const void *block)
{
struct slob_page *sp;
- if (ZERO_OR_NULL_PTR(block))
+ BUG_ON(!block);
+ if (unlikely(block == ZERO_SIZE_PTR))
return 0;
sp = (struct slob_page *)virt_to_page(block);
@@ -498,12 +499,12 @@ struct kmem_cache {
unsigned int size, align;
unsigned long flags;
const char *name;
- void (*ctor)(void *, struct kmem_cache *, unsigned long);
+ void (*ctor)(struct kmem_cache *, void *);
};
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
size_t align, unsigned long flags,
- void (*ctor)(void*, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
struct kmem_cache *c;
@@ -547,7 +548,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
b = slob_new_page(flags, get_order(c->size), node);
if (c->ctor)
- c->ctor(b, c, 0);
+ c->ctor(c, b);
return b;
}
diff --git a/mm/slub.c b/mm/slub.c
index addb20a6d67..e29a42988c7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -90,7 +90,7 @@
* One use of this flag is to mark slabs that are
* used for allocations. Then such a slab becomes a cpu
* slab. The cpu slab may be equipped with an additional
- * lockless_freelist that allows lockless access to
+ * freelist that allows lockless access to
* free objects in addition to the regular freelist
* that requires the slab lock.
*
@@ -140,11 +140,6 @@ static inline void ClearSlabDebug(struct page *page)
/*
* Issues still to be resolved:
*
- * - The per cpu array is updated for each new slab and and is a remote
- * cacheline for most nodes. This could become a bouncing cacheline given
- * enough frequent updates. There are 16 pointers in a cacheline, so at
- * max 16 cpus could compete for the cacheline which may be okay.
- *
* - Support PAGE_ALLOC_DEBUG. Should be easy to do.
*
* - Variable sizing of the per node arrays
@@ -205,11 +200,6 @@ static inline void ClearSlabDebug(struct page *page)
#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
#endif
-/*
- * The page->inuse field is 16 bit thus we have this limitation
- */
-#define MAX_OBJECTS_PER_SLAB 65535
-
/* Internal SLUB flags */
#define __OBJECT_POISON 0x80000000 /* Poison object */
#define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */
@@ -277,6 +267,15 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
#endif
}
+static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
+{
+#ifdef CONFIG_SMP
+ return s->cpu_slab[cpu];
+#else
+ return &s->cpu_slab;
+#endif
+}
+
static inline int check_valid_pointer(struct kmem_cache *s,
struct page *page, const void *object)
{
@@ -729,11 +728,6 @@ static int check_slab(struct kmem_cache *s, struct page *page)
slab_err(s, page, "Not a valid slab page");
return 0;
}
- if (page->offset * sizeof(void *) != s->offset) {
- slab_err(s, page, "Corrupted offset %lu",
- (unsigned long)(page->offset * sizeof(void *)));
- return 0;
- }
if (page->inuse > s->objects) {
slab_err(s, page, "inuse %u > max %u",
s->name, page->inuse, s->objects);
@@ -872,8 +866,6 @@ bad:
slab_fix(s, "Marking all objects used");
page->inuse = s->objects;
page->freelist = NULL;
- /* Fix up fields that may be corrupted */
- page->offset = s->offset / sizeof(void *);
}
return 0;
}
@@ -988,7 +980,7 @@ __setup("slub_debug", setup_slub_debug);
static unsigned long kmem_cache_flags(unsigned long objsize,
unsigned long flags, const char *name,
- void (*ctor)(void *, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
/*
* The page->offset field is only 16 bit wide. This is an offset
@@ -1035,7 +1027,7 @@ static inline int check_object(struct kmem_cache *s, struct page *page,
static inline void add_full(struct kmem_cache_node *n, struct page *page) {}
static inline unsigned long kmem_cache_flags(unsigned long objsize,
unsigned long flags, const char *name,
- void (*ctor)(void *, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
return flags;
}
@@ -1055,6 +1047,9 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
if (s->flags & SLAB_CACHE_DMA)
flags |= SLUB_DMA;
+ if (s->flags & SLAB_RECLAIM_ACCOUNT)
+ flags |= __GFP_RECLAIMABLE;
+
if (node == -1)
page = alloc_pages(flags, s->order);
else
@@ -1076,7 +1071,7 @@ static void setup_object(struct kmem_cache *s, struct page *page,
{
setup_object_debug(s, page, object);
if (unlikely(s->ctor))
- s->ctor(object, s, 0);
+ s->ctor(s, object);
}
static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
@@ -1088,19 +1083,16 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
void *last;
void *p;
- BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK));
-
- if (flags & __GFP_WAIT)
- local_irq_enable();
+ BUG_ON(flags & GFP_SLAB_BUG_MASK);
- page = allocate_slab(s, flags & GFP_LEVEL_MASK, node);
+ page = allocate_slab(s,
+ flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node);
if (!page)
goto out;
n = get_node(s, page_to_nid(page));
if (n)
atomic_long_inc(&n->nr_slabs);
- page->offset = s->offset / sizeof(void *);
page->slab = s;
page->flags |= 1 << PG_slab;
if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
@@ -1123,11 +1115,8 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
set_freepointer(s, last, NULL);
page->freelist = start;
- page->lockless_freelist = NULL;
page->inuse = 0;
out:
- if (flags & __GFP_WAIT)
- local_irq_disable();
return page;
}
@@ -1149,7 +1138,6 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
- pages);
- page->mapping = NULL;
__free_pages(page, s->order);
}
@@ -1383,33 +1371,34 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page)
/*
* Remove the cpu slab
*/
-static void deactivate_slab(struct kmem_cache *s, struct page *page, int cpu)
+static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
{
+ struct page *page = c->page;
/*
* Merge cpu freelist into freelist. Typically we get here
* because both freelists are empty. So this is unlikely
* to occur.
*/
- while (unlikely(page->lockless_freelist)) {
+ while (unlikely(c->freelist)) {
void **object;
/* Retrieve object from cpu_freelist */
- object = page->lockless_freelist;
- page->lockless_freelist = page->lockless_freelist[page->offset];
+ object = c->freelist;
+ c->freelist = c->freelist[c->offset];
/* And put onto the regular freelist */
- object[page->offset] = page->freelist;
+ object[c->offset] = page->freelist;
page->freelist = object;
page->inuse--;
}
- s->cpu_slab[cpu] = NULL;
+ c->page = NULL;
unfreeze_slab(s, page);
}
-static inline void flush_slab(struct kmem_cache *s, struct page *page, int cpu)
+static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
{
- slab_lock(page);
- deactivate_slab(s, page, cpu);
+ slab_lock(c->page);
+ deactivate_slab(s, c);
}
/*
@@ -1418,18 +1407,17 @@ static inline void flush_slab(struct kmem_cache *s, struct page *page, int cpu)
*/
static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
{
- struct page *page = s->cpu_slab[cpu];
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
- if (likely(page))
- flush_slab(s, page, cpu);
+ if (likely(c && c->page))
+ flush_slab(s, c);
}
static void flush_cpu_slab(void *d)
{
struct kmem_cache *s = d;
- int cpu = smp_processor_id();
- __flush_cpu_slab(s, cpu);
+ __flush_cpu_slab(s, smp_processor_id());
}
static void flush_all(struct kmem_cache *s)
@@ -1446,6 +1434,19 @@ static void flush_all(struct kmem_cache *s)
}
/*
+ * Check if the objects in a per cpu structure fit numa
+ * locality expectations.
+ */
+static inline int node_match(struct kmem_cache_cpu *c, int node)
+{
+#ifdef CONFIG_NUMA
+ if (node != -1 && c->node != node)
+ return 0;
+#endif
+ return 1;
+}
+
+/*
* Slow path. The lockless freelist is empty or we need to perform
* debugging duties.
*
@@ -1463,45 +1464,53 @@ static void flush_all(struct kmem_cache *s)
* we need to allocate a new slab. This is slowest path since we may sleep.
*/
static void *__slab_alloc(struct kmem_cache *s,
- gfp_t gfpflags, int node, void *addr, struct page *page)
+ gfp_t gfpflags, int node, void *addr, struct kmem_cache_cpu *c)
{
void **object;
- int cpu = smp_processor_id();
+ struct page *new;
- if (!page)
+ if (!c->page)
goto new_slab;
- slab_lock(page);
- if (unlikely(node != -1 && page_to_nid(page) != node))
+ slab_lock(c->page);
+ if (unlikely(!node_match(c, node)))
goto another_slab;
load_freelist:
- object = page->freelist;
+ object = c->page->freelist;
if (unlikely(!object))
goto another_slab;
- if (unlikely(SlabDebug(page)))
+ if (unlikely(SlabDebug(c->page)))
goto debug;
- object = page->freelist;
- page->lockless_freelist = object[page->offset];
- page->inuse = s->objects;
- page->freelist = NULL;
- slab_unlock(page);
+ object = c->page->freelist;
+ c->freelist = object[c->offset];
+ c->page->inuse = s->objects;
+ c->page->freelist = NULL;
+ c->node = page_to_nid(c->page);
+ slab_unlock(c->page);
return object;
another_slab:
- deactivate_slab(s, page, cpu);
+ deactivate_slab(s, c);
new_slab:
- page = get_partial(s, gfpflags, node);
- if (page) {
- s->cpu_slab[cpu] = page;
+ new = get_partial(s, gfpflags, node);
+ if (new) {
+ c->page = new;
goto load_freelist;
}
- page = new_slab(s, gfpflags, node);
- if (page) {
- cpu = smp_processor_id();
- if (s->cpu_slab[cpu]) {
+ if (gfpflags & __GFP_WAIT)
+ local_irq_enable();
+
+ new = new_slab(s, gfpflags, node);
+
+ if (gfpflags & __GFP_WAIT)
+ local_irq_disable();
+
+ if (new) {
+ c = get_cpu_slab(s, smp_processor_id());
+ if (c->page) {
/*
* Someone else populated the cpu_slab while we
* enabled interrupts, or we have gotten scheduled
@@ -1509,34 +1518,33 @@ new_slab:
* requested node even if __GFP_THISNODE was
* specified. So we need to recheck.
*/
- if (node == -1 ||
- page_to_nid(s->cpu_slab[cpu]) == node) {
+ if (node_match(c, node)) {
/*
* Current cpuslab is acceptable and we
* want the current one since its cache hot
*/
- discard_slab(s, page);
- page = s->cpu_slab[cpu];
- slab_lock(page);
+ discard_slab(s, new);
+ slab_lock(c->page);
goto load_freelist;
}
/* New slab does not fit our expectations */
- flush_slab(s, s->cpu_slab[cpu], cpu);
+ flush_slab(s, c);
}
- slab_lock(page);
- SetSlabFrozen(page);
- s->cpu_slab[cpu] = page;
+ slab_lock(new);
+ SetSlabFrozen(new);
+ c->page = new;
goto load_freelist;
}
return NULL;
debug:
- object = page->freelist;
- if (!alloc_debug_processing(s, page, object, addr))
+ object = c->page->freelist;
+ if (!alloc_debug_processing(s, c->page, object, addr))
goto another_slab;
- page->inuse++;
- page->freelist = object[page->offset];
- slab_unlock(page);
+ c->page->inuse++;
+ c->page->freelist = object[c->offset];
+ c->node = -1;
+ slab_unlock(c->page);
return object;
}
@@ -1553,25 +1561,24 @@ debug:
static void __always_inline *slab_alloc(struct kmem_cache *s,
gfp_t gfpflags, int node, void *addr)
{
- struct page *page;
void **object;
unsigned long flags;
+ struct kmem_cache_cpu *c;
local_irq_save(flags);
- page = s->cpu_slab[smp_processor_id()];
- if (unlikely(!page || !page->lockless_freelist ||
- (node != -1 && page_to_nid(page) != node)))
+ c = get_cpu_slab(s, smp_processor_id());
+ if (unlikely(!c->freelist || !node_match(c, node)))
- object = __slab_alloc(s, gfpflags, node, addr, page);
+ object = __slab_alloc(s, gfpflags, node, addr, c);
else {
- object = page->lockless_freelist;
- page->lockless_freelist = object[page->offset];
+ object = c->freelist;
+ c->freelist = object[c->offset];
}
local_irq_restore(flags);
if (unlikely((gfpflags & __GFP_ZERO) && object))
- memset(object, 0, s->objsize);
+ memset(object, 0, c->objsize);
return object;
}
@@ -1599,7 +1606,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
* handling required then we can return immediately.
*/
static void __slab_free(struct kmem_cache *s, struct page *page,
- void *x, void *addr)
+ void *x, void *addr, unsigned int offset)
{
void *prior;
void **object = (void *)x;
@@ -1609,7 +1616,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
if (unlikely(SlabDebug(page)))
goto debug;
checks_ok:
- prior = object[page->offset] = page->freelist;
+ prior = object[offset] = page->freelist;
page->freelist = object;
page->inuse--;
@@ -1664,15 +1671,16 @@ static void __always_inline slab_free(struct kmem_cache *s,
{
void **object = (void *)x;
unsigned long flags;
+ struct kmem_cache_cpu *c;
local_irq_save(flags);
debug_check_no_locks_freed(object, s->objsize);
- if (likely(page == s->cpu_slab[smp_processor_id()] &&
- !SlabDebug(page))) {
- object[page->offset] = page->lockless_freelist;
- page->lockless_freelist = object;
+ c = get_cpu_slab(s, smp_processor_id());
+ if (likely(page == c->page && c->node >= 0)) {
+ object[c->offset] = c->freelist;
+ c->freelist = object;
} else
- __slab_free(s, page, x, addr);
+ __slab_free(s, page, x, addr, c->offset);
local_irq_restore(flags);
}
@@ -1759,14 +1767,6 @@ static inline int slab_order(int size, int min_objects,
int rem;
int min_order = slub_min_order;
- /*
- * If we would create too many object per slab then reduce
- * the slab order even if it goes below slub_min_order.
- */
- while (min_order > 0 &&
- (PAGE_SIZE << min_order) >= MAX_OBJECTS_PER_SLAB * size)
- min_order--;
-
for (order = max(min_order,
fls(min_objects * size - 1) - PAGE_SHIFT);
order <= max_order; order++) {
@@ -1781,9 +1781,6 @@ static inline int slab_order(int size, int min_objects,
if (rem <= slab_size / fract_leftover)
break;
- /* If the next size is too high then exit now */
- if (slab_size * 2 >= MAX_OBJECTS_PER_SLAB * size)
- break;
}
return order;
@@ -1858,6 +1855,16 @@ static unsigned long calculate_alignment(unsigned long flags,
return ALIGN(align, sizeof(void *));
}
+static void init_kmem_cache_cpu(struct kmem_cache *s,
+ struct kmem_cache_cpu *c)
+{
+ c->page = NULL;
+ c->freelist = NULL;
+ c->node = 0;
+ c->offset = s->offset / sizeof(void *);
+ c->objsize = s->objsize;
+}
+
static void init_kmem_cache_node(struct kmem_cache_node *n)
{
n->nr_partial = 0;
@@ -1869,6 +1876,131 @@ static void init_kmem_cache_node(struct kmem_cache_node *n)
#endif
}
+#ifdef CONFIG_SMP
+/*
+ * Per cpu array for per cpu structures.
+ *
+ * The per cpu array places all kmem_cache_cpu structures from one processor
+ * close together meaning that it becomes possible that multiple per cpu
+ * structures are contained in one cacheline. This may be particularly
+ * beneficial for the kmalloc caches.
+ *
+ * A desktop system typically has around 60-80 slabs. With 100 here we are
+ * likely able to get per cpu structures for all caches from the array defined
+ * here. We must be able to cover all kmalloc caches during bootstrap.
+ *
+ * If the per cpu array is exhausted then fall back to kmalloc
+ * of individual cachelines. No sharing is possible then.
+ */
+#define NR_KMEM_CACHE_CPU 100
+
+static DEFINE_PER_CPU(struct kmem_cache_cpu,
+ kmem_cache_cpu)[NR_KMEM_CACHE_CPU];
+
+static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
+static cpumask_t kmem_cach_cpu_free_init_once = CPU_MASK_NONE;
+
+static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
+ int cpu, gfp_t flags)
+{
+ struct kmem_cache_cpu *c = per_cpu(kmem_cache_cpu_free, cpu);
+
+ if (c)
+ per_cpu(kmem_cache_cpu_free, cpu) =
+ (void *)c->freelist;
+ else {
+ /* Table overflow: So allocate ourselves */
+ c = kmalloc_node(
+ ALIGN(sizeof(struct kmem_cache_cpu), cache_line_size()),
+ flags, cpu_to_node(cpu));
+ if (!c)
+ return NULL;
+ }
+
+ init_kmem_cache_cpu(s, c);
+ return c;
+}
+
+static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu)
+{
+ if (c < per_cpu(kmem_cache_cpu, cpu) ||
+ c > per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) {
+ kfree(c);
+ return;
+ }
+ c->freelist = (void *)per_cpu(kmem_cache_cpu_free, cpu);
+ per_cpu(kmem_cache_cpu_free, cpu) = c;
+}
+
+static void free_kmem_cache_cpus(struct kmem_cache *s)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+
+ if (c) {
+ s->cpu_slab[cpu] = NULL;
+ free_kmem_cache_cpu(c, cpu);
+ }
+ }
+}
+
+static int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+
+ if (c)
+ continue;
+
+ c = alloc_kmem_cache_cpu(s, cpu, flags);
+ if (!c) {
+ free_kmem_cache_cpus(s);
+ return 0;
+ }
+ s->cpu_slab[cpu] = c;
+ }
+ return 1;
+}
+
+/*
+ * Initialize the per cpu array.
+ */
+static void init_alloc_cpu_cpu(int cpu)
+{
+ int i;
+
+ if (cpu_isset(cpu, kmem_cach_cpu_free_init_once))
+ return;
+
+ for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--)
+ free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu);
+
+ cpu_set(cpu, kmem_cach_cpu_free_init_once);
+}
+
+static void __init init_alloc_cpu(void)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu)
+ init_alloc_cpu_cpu(cpu);
+ }
+
+#else
+static inline void free_kmem_cache_cpus(struct kmem_cache *s) {}
+static inline void init_alloc_cpu(void) {}
+
+static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
+{
+ init_kmem_cache_cpu(s, &s->cpu_slab);
+ return 1;
+}
+#endif
+
#ifdef CONFIG_NUMA
/*
* No kmalloc_node yet so do it by hand. We know that this is the first
@@ -1876,10 +2008,11 @@ static void init_kmem_cache_node(struct kmem_cache_node *n)
* possible.
*
* Note that this function only works on the kmalloc_node_cache
- * when allocating for the kmalloc_node_cache.
+ * when allocating for the kmalloc_node_cache. This is used for bootstrapping
+ * memory on a fresh node that has no slab structures yet.
*/
-static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflags,
- int node)
+static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags,
+ int node)
{
struct page *page;
struct kmem_cache_node *n;
@@ -1908,12 +2041,6 @@ static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflag
init_kmem_cache_node(n);
atomic_long_inc(&n->nr_slabs);
add_partial(n, page);
-
- /*
- * new_slab() disables interupts. If we do not reenable interrupts here
- * then bootup would continue with interrupts disabled.
- */
- local_irq_enable();
return n;
}
@@ -1921,7 +2048,7 @@ static void free_kmem_cache_nodes(struct kmem_cache *s)
{
int node;
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = s->node[node];
if (n && n != &s->local_node)
kmem_cache_free(kmalloc_caches, n);
@@ -1939,7 +2066,7 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
else
local_node = 0;
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n;
if (local_node == node)
@@ -2077,21 +2204,14 @@ static int calculate_sizes(struct kmem_cache *s)
*/
s->objects = (PAGE_SIZE << s->order) / size;
- /*
- * Verify that the number of objects is within permitted limits.
- * The page->inuse field is only 16 bit wide! So we cannot have
- * more than 64k objects per slab.
- */
- if (!s->objects || s->objects > MAX_OBJECTS_PER_SLAB)
- return 0;
- return 1;
+ return !!s->objects;
}
static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
const char *name, size_t size,
size_t align, unsigned long flags,
- void (*ctor)(void *, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
memset(s, 0, kmem_size);
s->name = name;
@@ -2107,9 +2227,12 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
#ifdef CONFIG_NUMA
s->defrag_ratio = 100;
#endif
+ if (!init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA))
+ goto error;
- if (init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA))
+ if (alloc_kmem_cache_cpus(s, gfpflags & ~SLUB_DMA))
return 1;
+ free_kmem_cache_nodes(s);
error:
if (flags & SLAB_PANIC)
panic("Cannot create slab %s size=%lu realsize=%u "
@@ -2192,7 +2315,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
flush_all(s);
/* Attempt to free all objects */
- for_each_online_node(node) {
+ free_kmem_cache_cpus(s);
+ for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
n->nr_partial -= free_list(s, n, &n->partial);
@@ -2227,11 +2351,11 @@ EXPORT_SYMBOL(kmem_cache_destroy);
* Kmalloc subsystem
*******************************************************************/
-struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1] __cacheline_aligned;
+struct kmem_cache kmalloc_caches[PAGE_SHIFT] __cacheline_aligned;
EXPORT_SYMBOL(kmalloc_caches);
#ifdef CONFIG_ZONE_DMA
-static struct kmem_cache *kmalloc_caches_dma[KMALLOC_SHIFT_HIGH + 1];
+static struct kmem_cache *kmalloc_caches_dma[PAGE_SHIFT];
#endif
static int __init setup_slub_min_order(char *str)
@@ -2397,12 +2521,8 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
return ZERO_SIZE_PTR;
index = size_index[(size - 1) / 8];
- } else {
- if (size > KMALLOC_MAX_SIZE)
- return NULL;
-
+ } else
index = fls(size - 1);
- }
#ifdef CONFIG_ZONE_DMA
if (unlikely((flags & SLUB_DMA)))
@@ -2414,9 +2534,15 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
void *__kmalloc(size_t size, gfp_t flags)
{
- struct kmem_cache *s = get_slab(size, flags);
+ struct kmem_cache *s;
- if (ZERO_OR_NULL_PTR(s))
+ if (unlikely(size > PAGE_SIZE / 2))
+ return (void *)__get_free_pages(flags | __GFP_COMP,
+ get_order(size));
+
+ s = get_slab(size, flags);
+
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
return slab_alloc(s, flags, -1, __builtin_return_address(0));
@@ -2426,9 +2552,15 @@ EXPORT_SYMBOL(__kmalloc);
#ifdef CONFIG_NUMA
void *__kmalloc_node(size_t size, gfp_t flags, int node)
{
- struct kmem_cache *s = get_slab(size, flags);
+ struct kmem_cache *s;
- if (ZERO_OR_NULL_PTR(s))
+ if (unlikely(size > PAGE_SIZE / 2))
+ return (void *)__get_free_pages(flags | __GFP_COMP,
+ get_order(size));
+
+ s = get_slab(size, flags);
+
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
return slab_alloc(s, flags, node, __builtin_return_address(0));
@@ -2441,7 +2573,8 @@ size_t ksize(const void *object)
struct page *page;
struct kmem_cache *s;
- if (ZERO_OR_NULL_PTR(object))
+ BUG_ON(!object);
+ if (unlikely(object == ZERO_SIZE_PTR))
return 0;
page = get_object_page(object);
@@ -2473,22 +2606,17 @@ EXPORT_SYMBOL(ksize);
void kfree(const void *x)
{
- struct kmem_cache *s;
struct page *page;
- /*
- * This has to be an unsigned comparison. According to Linus
- * some gcc version treat a pointer as a signed entity. Then
- * this comparison would be true for all "negative" pointers
- * (which would cover the whole upper half of the address space).
- */
- if (ZERO_OR_NULL_PTR(x))
+ if (unlikely(ZERO_OR_NULL_PTR(x)))
return;
page = virt_to_head_page(x);
- s = page->slab;
-
- slab_free(s, page, (void *)x, __builtin_return_address(0));
+ if (unlikely(!PageSlab(page))) {
+ put_page(page);
+ return;
+ }
+ slab_free(page->slab, page, (void *)x, __builtin_return_address(0));
}
EXPORT_SYMBOL(kfree);
@@ -2517,7 +2645,7 @@ int kmem_cache_shrink(struct kmem_cache *s)
return -ENOMEM;
flush_all(s);
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
n = get_node(s, node);
if (!n->nr_partial)
@@ -2575,6 +2703,8 @@ void __init kmem_cache_init(void)
int i;
int caches = 0;
+ init_alloc_cpu();
+
#ifdef CONFIG_NUMA
/*
* Must first have the slab cache available for the allocations of the
@@ -2602,7 +2732,7 @@ void __init kmem_cache_init(void)
caches++;
}
- for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) {
+ for (i = KMALLOC_SHIFT_LOW; i < PAGE_SHIFT; i++) {
create_kmalloc_cache(&kmalloc_caches[i],
"kmalloc", 1 << i, GFP_KERNEL);
caches++;
@@ -2629,16 +2759,18 @@ void __init kmem_cache_init(void)
slab_state = UP;
/* Provide the correct kmalloc names now that the caches are up */
- for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++)
+ for (i = KMALLOC_SHIFT_LOW; i < PAGE_SHIFT; i++)
kmalloc_caches[i]. name =
kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i);
#ifdef CONFIG_SMP
register_cpu_notifier(&slab_notifier);
+ kmem_size = offsetof(struct kmem_cache, cpu_slab) +
+ nr_cpu_ids * sizeof(struct kmem_cache_cpu *);
+#else
+ kmem_size = sizeof(struct kmem_cache);
#endif
- kmem_size = offsetof(struct kmem_cache, cpu_slab) +
- nr_cpu_ids * sizeof(struct page *);
printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
" CPUs=%d, Nodes=%d\n",
@@ -2669,7 +2801,7 @@ static int slab_unmergeable(struct kmem_cache *s)
static struct kmem_cache *find_mergeable(size_t size,
size_t align, unsigned long flags, const char *name,
- void (*ctor)(void *, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
struct kmem_cache *s;
@@ -2710,19 +2842,28 @@ static struct kmem_cache *find_mergeable(size_t size,
struct kmem_cache *kmem_cache_create(const char *name, size_t size,
size_t align, unsigned long flags,
- void (*ctor)(void *, struct kmem_cache *, unsigned long))
+ void (*ctor)(struct kmem_cache *, void *))
{
struct kmem_cache *s;
down_write(&slub_lock);
s = find_mergeable(size, align, flags, name, ctor);
if (s) {
+ int cpu;
+
s->refcount++;
/*
* Adjust the object sizes so that we clear
* the complete object on kzalloc.
*/
s->objsize = max(s->objsize, (int)size);
+
+ /*
+ * And then we need to update the object size in the
+ * per cpu structures
+ */
+ for_each_online_cpu(cpu)
+ get_cpu_slab(s, cpu)->objsize = s->objsize;
s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
up_write(&slub_lock);
if (sysfs_slab_alias(s, name))
@@ -2765,15 +2906,29 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
unsigned long flags;
switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ init_alloc_cpu_cpu(cpu);
+ down_read(&slub_lock);
+ list_for_each_entry(s, &slab_caches, list)
+ s->cpu_slab[cpu] = alloc_kmem_cache_cpu(s, cpu,
+ GFP_KERNEL);
+ up_read(&slub_lock);
+ break;
+
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
down_read(&slub_lock);
list_for_each_entry(s, &slab_caches, list) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+
local_irq_save(flags);
__flush_cpu_slab(s, cpu);
local_irq_restore(flags);
+ free_kmem_cache_cpu(c, cpu);
+ s->cpu_slab[cpu] = NULL;
}
up_read(&slub_lock);
break;
@@ -2790,9 +2945,14 @@ static struct notifier_block __cpuinitdata slab_notifier =
void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
{
- struct kmem_cache *s = get_slab(size, gfpflags);
+ struct kmem_cache *s;
+
+ if (unlikely(size > PAGE_SIZE / 2))
+ return (void *)__get_free_pages(gfpflags | __GFP_COMP,
+ get_order(size));
+ s = get_slab(size, gfpflags);
- if (ZERO_OR_NULL_PTR(s))
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
return slab_alloc(s, gfpflags, -1, caller);
@@ -2801,9 +2961,14 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
int node, void *caller)
{
- struct kmem_cache *s = get_slab(size, gfpflags);
+ struct kmem_cache *s;
+
+ if (unlikely(size > PAGE_SIZE / 2))
+ return (void *)__get_free_pages(gfpflags | __GFP_COMP,
+ get_order(size));
+ s = get_slab(size, gfpflags);
- if (ZERO_OR_NULL_PTR(s))
+ if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
return slab_alloc(s, gfpflags, node, caller);
@@ -2902,7 +3067,7 @@ static long validate_slab_cache(struct kmem_cache *s)
return -ENOMEM;
flush_all(s);
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
count += validate_slab_node(s, n, map);
@@ -3116,13 +3281,13 @@ static int list_locations(struct kmem_cache *s, char *buf,
int node;
if (!alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location),
- GFP_KERNEL))
+ GFP_TEMPORARY))
return sprintf(buf, "Out of memory\n");
/* Push back cpu slabs */
flush_all(s);
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
unsigned long flags;
struct page *page;
@@ -3230,11 +3395,18 @@ static unsigned long slab_objects(struct kmem_cache *s,
per_cpu = nodes + nr_node_ids;
for_each_possible_cpu(cpu) {
- struct page *page = s->cpu_slab[cpu];
+ struct page *page;
int node;
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+ if (!c)
+ continue;
+
+ page = c->page;
+ node = c->node;
+ if (node < 0)
+ continue;
if (page) {
- node = page_to_nid(page);
if (flags & SO_CPU) {
int x = 0;
@@ -3249,7 +3421,7 @@ static unsigned long slab_objects(struct kmem_cache *s,
}
}
- for_each_online_node(node) {
+ for_each_node_state(node, N_NORMAL_MEMORY) {
struct kmem_cache_node *n = get_node(s, node);
if (flags & SO_PARTIAL) {
@@ -3277,7 +3449,7 @@ static unsigned long slab_objects(struct kmem_cache *s,
x = sprintf(buf, "%lu", total);
#ifdef CONFIG_NUMA
- for_each_online_node(node)
+ for_each_node_state(node, N_NORMAL_MEMORY)
if (nodes[node])
x += sprintf(buf + x, " N%d=%lu",
node, nodes[node]);
@@ -3291,13 +3463,19 @@ static int any_slab_objects(struct kmem_cache *s)
int node;
int cpu;
- for_each_possible_cpu(cpu)
- if (s->cpu_slab[cpu])
+ for_each_possible_cpu(cpu) {
+ struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+
+ if (c && c->page)
return 1;
+ }
- for_each_node(node) {
+ for_each_online_node(node) {
struct kmem_cache_node *n = get_node(s, node);
+ if (!n)
+ continue;
+
if (n->nr_partial || atomic_long_read(&n->nr_slabs))
return 1;
}
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
new file mode 100644
index 00000000000..d3b718b0c20
--- /dev/null
+++ b/mm/sparse-vmemmap.c
@@ -0,0 +1,148 @@
+/*
+ * Virtual Memory Map support
+ *
+ * (C) 2007 sgi. Christoph Lameter <clameter@sgi.com>.
+ *
+ * Virtual memory maps allow VM primitives pfn_to_page, page_to_pfn,
+ * virt_to_page, page_address() to be implemented as a base offset
+ * calculation without memory access.
+ *
+ * However, virtual mappings need a page table and TLBs. Many Linux
+ * architectures already map their physical space using 1-1 mappings
+ * via TLBs. For those arches the virtual memmory map is essentially
+ * for free if we use the same page size as the 1-1 mappings. In that
+ * case the overhead consists of a few additional pages that are
+ * allocated to create a view of memory for vmemmap.
+ *
+ * The architecture is expected to provide a vmemmap_populate() function
+ * to instantiate the mapping.
+ */
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
+#include <asm/dma.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+/*
+ * Allocate a block of memory to be used to back the virtual memory map
+ * or to back the page tables that are used to create the mapping.
+ * Uses the main allocators if they are available, else bootmem.
+ */
+void * __meminit vmemmap_alloc_block(unsigned long size, int node)
+{
+ /* If the main allocator is up use that, fallback to bootmem. */
+ if (slab_is_available()) {
+ struct page *page = alloc_pages_node(node,
+ GFP_KERNEL | __GFP_ZERO, get_order(size));
+ if (page)
+ return page_address(page);
+ return NULL;
+ } else
+ return __alloc_bootmem_node(NODE_DATA(node), size, size,
+ __pa(MAX_DMA_ADDRESS));
+}
+
+void __meminit vmemmap_verify(pte_t *pte, int node,
+ unsigned long start, unsigned long end)
+{
+ unsigned long pfn = pte_pfn(*pte);
+ int actual_node = early_pfn_to_nid(pfn);
+
+ if (actual_node != node)
+ printk(KERN_WARNING "[%lx-%lx] potential offnode "
+ "page_structs\n", start, end - 1);
+}
+
+pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
+{
+ pte_t *pte = pte_offset_kernel(pmd, addr);
+ if (pte_none(*pte)) {
+ pte_t entry;
+ void *p = vmemmap_alloc_block(PAGE_SIZE, node);
+ if (!p)
+ return 0;
+ entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
+ set_pte_at(&init_mm, addr, pte, entry);
+ }
+ return pte;
+}
+
+pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
+{
+ pmd_t *pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd)) {
+ void *p = vmemmap_alloc_block(PAGE_SIZE, node);
+ if (!p)
+ return 0;
+ pmd_populate_kernel(&init_mm, pmd, p);
+ }
+ return pmd;
+}
+
+pud_t * __meminit vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ if (pud_none(*pud)) {
+ void *p = vmemmap_alloc_block(PAGE_SIZE, node);
+ if (!p)
+ return 0;
+ pud_populate(&init_mm, pud, p);
+ }
+ return pud;
+}
+
+pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
+{
+ pgd_t *pgd = pgd_offset_k(addr);
+ if (pgd_none(*pgd)) {
+ void *p = vmemmap_alloc_block(PAGE_SIZE, node);
+ if (!p)
+ return 0;
+ pgd_populate(&init_mm, pgd, p);
+ }
+ return pgd;
+}
+
+int __meminit vmemmap_populate_basepages(struct page *start_page,
+ unsigned long size, int node)
+{
+ unsigned long addr = (unsigned long)start_page;
+ unsigned long end = (unsigned long)(start_page + size);
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ for (; addr < end; addr += PAGE_SIZE) {
+ pgd = vmemmap_pgd_populate(addr, node);
+ if (!pgd)
+ return -ENOMEM;
+ pud = vmemmap_pud_populate(pgd, addr, node);
+ if (!pud)
+ return -ENOMEM;
+ pmd = vmemmap_pmd_populate(pud, addr, node);
+ if (!pmd)
+ return -ENOMEM;
+ pte = vmemmap_pte_populate(pmd, addr, node);
+ if (!pte)
+ return -ENOMEM;
+ vmemmap_verify(pte, node, addr, addr + PAGE_SIZE);
+ }
+
+ return 0;
+}
+
+struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid)
+{
+ struct page *map = pfn_to_page(pnum * PAGES_PER_SECTION);
+ int error = vmemmap_populate(map, PAGES_PER_SECTION, nid);
+ if (error)
+ return NULL;
+
+ return map;
+}
diff --git a/mm/sparse.c b/mm/sparse.c
index 239f5a720d3..08fb14f5eea 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -9,6 +9,8 @@
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include <asm/dma.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
/*
* Permanent SPARSEMEM data:
@@ -106,7 +108,7 @@ static inline int sparse_index_init(unsigned long section_nr, int nid)
/*
* Although written for the SPARSEMEM_EXTREME case, this happens
- * to also work for the flat array case becase
+ * to also work for the flat array case because
* NR_SECTION_ROOTS==NR_MEM_SECTIONS.
*/
int __section_nr(struct mem_section* ms)
@@ -176,7 +178,7 @@ unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn,
if (nid != early_pfn_to_nid(pfn))
continue;
- if (pfn_valid(pfn))
+ if (pfn_present(pfn))
nr_pages += PAGES_PER_SECTION;
}
@@ -204,13 +206,16 @@ struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pn
}
static int __meminit sparse_init_one_section(struct mem_section *ms,
- unsigned long pnum, struct page *mem_map)
+ unsigned long pnum, struct page *mem_map,
+ unsigned long *pageblock_bitmap)
{
- if (!valid_section(ms))
+ if (!present_section(ms))
return -EINVAL;
ms->section_mem_map &= ~SECTION_MAP_MASK;
- ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum);
+ ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum) |
+ SECTION_HAS_MEM_MAP;
+ ms->pageblock_flags = pageblock_bitmap;
return 1;
}
@@ -221,12 +226,43 @@ void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
return NULL;
}
-static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
+static unsigned long usemap_size(void)
{
- struct page *map;
+ unsigned long size_bytes;
+ size_bytes = roundup(SECTION_BLOCKFLAGS_BITS, 8) / 8;
+ size_bytes = roundup(size_bytes, sizeof(unsigned long));
+ return size_bytes;
+}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+static unsigned long *__kmalloc_section_usemap(void)
+{
+ return kmalloc(usemap_size(), GFP_KERNEL);
+}
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
+static unsigned long *sparse_early_usemap_alloc(unsigned long pnum)
+{
+ unsigned long *usemap;
struct mem_section *ms = __nr_to_section(pnum);
int nid = sparse_early_nid(ms);
+ usemap = alloc_bootmem_node(NODE_DATA(nid), usemap_size());
+ if (usemap)
+ return usemap;
+
+ /* Stupid: suppress gcc warning for SPARSEMEM && !NUMA */
+ nid = 0;
+
+ printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__);
+ return NULL;
+}
+
+#ifndef CONFIG_SPARSEMEM_VMEMMAP
+struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid)
+{
+ struct page *map;
+
map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION);
if (map)
return map;
@@ -238,10 +274,22 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
map = alloc_bootmem_node(NODE_DATA(nid),
sizeof(struct page) * PAGES_PER_SECTION);
+ return map;
+}
+#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
+
+struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
+{
+ struct page *map;
+ struct mem_section *ms = __nr_to_section(pnum);
+ int nid = sparse_early_nid(ms);
+
+ map = sparse_mem_map_populate(pnum, nid);
if (map)
return map;
- printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__);
+ printk(KERN_ERR "%s: sparsemem memory map backing failed "
+ "some memory will not be available.\n", __FUNCTION__);
ms->section_mem_map = 0;
return NULL;
}
@@ -254,19 +302,38 @@ void __init sparse_init(void)
{
unsigned long pnum;
struct page *map;
+ unsigned long *usemap;
for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
- if (!valid_section_nr(pnum))
+ if (!present_section_nr(pnum))
continue;
map = sparse_early_mem_map_alloc(pnum);
if (!map)
continue;
- sparse_init_one_section(__nr_to_section(pnum), pnum, map);
+
+ usemap = sparse_early_usemap_alloc(pnum);
+ if (!usemap)
+ continue;
+
+ sparse_init_one_section(__nr_to_section(pnum), pnum, map,
+ usemap);
}
}
#ifdef CONFIG_MEMORY_HOTPLUG
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+ unsigned long nr_pages)
+{
+ /* This will make the necessary allocations eventually. */
+ return sparse_mem_map_populate(pnum, nid);
+}
+static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
+{
+ return; /* XXX: Not implemented yet */
+}
+#else
static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
{
struct page *page, *ret;
@@ -289,6 +356,12 @@ got_map_ptr:
return ret;
}
+static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+ unsigned long nr_pages)
+{
+ return __kmalloc_section_memmap(nr_pages);
+}
+
static int vaddr_in_vmalloc_area(void *addr)
{
if (addr >= (void *)VMALLOC_START &&
@@ -305,6 +378,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
free_pages((unsigned long)memmap,
get_order(sizeof(struct page) * nr_pages));
}
+#endif /* CONFIG_SPARSEMEM_VMEMMAP */
/*
* returns the number of sections whose mem_maps were properly
@@ -318,6 +392,7 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
struct pglist_data *pgdat = zone->zone_pgdat;
struct mem_section *ms;
struct page *memmap;
+ unsigned long *usemap;
unsigned long flags;
int ret;
@@ -326,7 +401,8 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
* plus, it does a kmalloc
*/
sparse_index_init(section_nr, pgdat->node_id);
- memmap = __kmalloc_section_memmap(nr_pages);
+ memmap = kmalloc_section_memmap(section_nr, pgdat->node_id, nr_pages);
+ usemap = __kmalloc_section_usemap();
pgdat_resize_lock(pgdat, &flags);
@@ -335,9 +411,14 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
ret = -EEXIST;
goto out;
}
+
+ if (!usemap) {
+ ret = -ENOMEM;
+ goto out;
+ }
ms->section_mem_map |= SECTION_MARKED_PRESENT;
- ret = sparse_init_one_section(ms, section_nr, memmap);
+ ret = sparse_init_one_section(ms, section_nr, memmap, usemap);
out:
pgdat_resize_unlock(pgdat, &flags);
diff --git a/mm/swap.c b/mm/swap.c
index d3cb966fe99..a65eff8a517 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -24,16 +24,19 @@
#include <linux/module.h>
#include <linux/mm_inline.h>
#include <linux/buffer_head.h> /* for try_to_release_page() */
-#include <linux/module.h>
#include <linux/percpu_counter.h>
#include <linux/percpu.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
-#include <linux/init.h>
+#include <linux/backing-dev.h>
/* How many pages do we try to swap or page in/out together? */
int page_cluster;
+static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
+static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
+static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
+
/*
* This path almost never happens for VM activity - pages are normally
* freed via pagevecs. But it gets used by networking.
@@ -94,23 +97,47 @@ void put_pages_list(struct list_head *pages)
EXPORT_SYMBOL(put_pages_list);
/*
+ * pagevec_move_tail() must be called with IRQ disabled.
+ * Otherwise this may cause nasty races.
+ */
+static void pagevec_move_tail(struct pagevec *pvec)
+{
+ int i;
+ int pgmoved = 0;
+ struct zone *zone = NULL;
+
+ for (i = 0; i < pagevec_count(pvec); i++) {
+ struct page *page = pvec->pages[i];
+ struct zone *pagezone = page_zone(page);
+
+ if (pagezone != zone) {
+ if (zone)
+ spin_unlock(&zone->lru_lock);
+ zone = pagezone;
+ spin_lock(&zone->lru_lock);
+ }
+ if (PageLRU(page) && !PageActive(page)) {
+ list_move_tail(&page->lru, &zone->inactive_list);
+ pgmoved++;
+ }
+ }
+ if (zone)
+ spin_unlock(&zone->lru_lock);
+ __count_vm_events(PGROTATED, pgmoved);
+ release_pages(pvec->pages, pvec->nr, pvec->cold);
+ pagevec_reinit(pvec);
+}
+
+/*
* Writeback is about to end against a page which has been marked for immediate
* reclaim. If it still appears to be reclaimable, move it to the tail of the
- * inactive list. The page still has PageWriteback set, which will pin it.
- *
- * We don't expect many pages to come through here, so don't bother batching
- * things up.
- *
- * To avoid placing the page at the tail of the LRU while PG_writeback is still
- * set, this function will clear PG_writeback before performing the page
- * motion. Do that inside the lru lock because once PG_writeback is cleared
- * we may not touch the page.
+ * inactive list.
*
* Returns zero if it cleared PG_writeback.
*/
int rotate_reclaimable_page(struct page *page)
{
- struct zone *zone;
+ struct pagevec *pvec;
unsigned long flags;
if (PageLocked(page))
@@ -122,15 +149,16 @@ int rotate_reclaimable_page(struct page *page)
if (!PageLRU(page))
return 1;
- zone = page_zone(page);
- spin_lock_irqsave(&zone->lru_lock, flags);
- if (PageLRU(page) && !PageActive(page)) {
- list_move_tail(&page->lru, &zone->inactive_list);
- __count_vm_event(PGROTATED);
- }
+ page_cache_get(page);
+ local_irq_save(flags);
+ pvec = &__get_cpu_var(lru_rotate_pvecs);
+ if (!pagevec_add(pvec, page))
+ pagevec_move_tail(pvec);
+ local_irq_restore(flags);
+
if (!test_clear_page_writeback(page))
BUG();
- spin_unlock_irqrestore(&zone->lru_lock, flags);
+
return 0;
}
@@ -174,9 +202,6 @@ EXPORT_SYMBOL(mark_page_accessed);
* lru_cache_add: add a page to the page lists
* @page: the page to add
*/
-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
-
void fastcall lru_cache_add(struct page *page)
{
struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
@@ -197,21 +222,37 @@ void fastcall lru_cache_add_active(struct page *page)
put_cpu_var(lru_add_active_pvecs);
}
-static void __lru_add_drain(int cpu)
+/*
+ * Drain pages out of the cpu's pagevecs.
+ * Either "cpu" is the current CPU, and preemption has already been
+ * disabled; or "cpu" is being hot-unplugged, and is already dead.
+ */
+static void drain_cpu_pagevecs(int cpu)
{
- struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu);
+ struct pagevec *pvec;
- /* CPU is dead, so no locking needed. */
+ pvec = &per_cpu(lru_add_pvecs, cpu);
if (pagevec_count(pvec))
__pagevec_lru_add(pvec);
+
pvec = &per_cpu(lru_add_active_pvecs, cpu);
if (pagevec_count(pvec))
__pagevec_lru_add_active(pvec);
+
+ pvec = &per_cpu(lru_rotate_pvecs, cpu);
+ if (pagevec_count(pvec)) {
+ unsigned long flags;
+
+ /* No harm done if a racing interrupt already did this */
+ local_irq_save(flags);
+ pagevec_move_tail(pvec);
+ local_irq_restore(flags);
+ }
}
void lru_add_drain(void)
{
- __lru_add_drain(get_cpu());
+ drain_cpu_pagevecs(get_cpu());
put_cpu();
}
@@ -258,6 +299,7 @@ void release_pages(struct page **pages, int nr, int cold)
int i;
struct pagevec pages_to_free;
struct zone *zone = NULL;
+ unsigned long uninitialized_var(flags);
pagevec_init(&pages_to_free, cold);
for (i = 0; i < nr; i++) {
@@ -265,7 +307,7 @@ void release_pages(struct page **pages, int nr, int cold)
if (unlikely(PageCompound(page))) {
if (zone) {
- spin_unlock_irq(&zone->lru_lock);
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
zone = NULL;
}
put_compound_page(page);
@@ -279,9 +321,10 @@ void release_pages(struct page **pages, int nr, int cold)
struct zone *pagezone = page_zone(page);
if (pagezone != zone) {
if (zone)
- spin_unlock_irq(&zone->lru_lock);
+ spin_unlock_irqrestore(&zone->lru_lock,
+ flags);
zone = pagezone;
- spin_lock_irq(&zone->lru_lock);
+ spin_lock_irqsave(&zone->lru_lock, flags);
}
VM_BUG_ON(!PageLRU(page));
__ClearPageLRU(page);
@@ -290,7 +333,7 @@ void release_pages(struct page **pages, int nr, int cold)
if (!pagevec_add(&pages_to_free, page)) {
if (zone) {
- spin_unlock_irq(&zone->lru_lock);
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
zone = NULL;
}
__pagevec_free(&pages_to_free);
@@ -298,7 +341,7 @@ void release_pages(struct page **pages, int nr, int cold)
}
}
if (zone)
- spin_unlock_irq(&zone->lru_lock);
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
pagevec_free(&pages_to_free);
}
@@ -491,7 +534,7 @@ static int cpu_swap_callback(struct notifier_block *nfb,
if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
atomic_add(*committed, &vm_committed_space);
*committed = 0;
- __lru_add_drain((long)hcpu);
+ drain_cpu_pagevecs((long)hcpu);
}
return NOTIFY_OK;
}
@@ -505,6 +548,10 @@ void __init swap_setup(void)
{
unsigned long megs = num_physpages >> (20 - PAGE_SHIFT);
+#ifdef CONFIG_SWAP
+ bdi_init(swapper_space.backing_dev_info);
+#endif
+
/* Use a smaller cluster for small-memory machines */
if (megs < 16)
page_cluster = 2;
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 67daecb6031..b52635601df 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -74,6 +74,7 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
{
int error;
+ BUG_ON(!PageLocked(page));
BUG_ON(PageSwapCache(page));
BUG_ON(PagePrivate(page));
error = radix_tree_preload(gfp_mask);
@@ -83,7 +84,6 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
entry.val, page);
if (!error) {
page_cache_get(page);
- SetPageLocked(page);
SetPageSwapCache(page);
set_page_private(page, entry.val);
total_swapcache_pages++;
@@ -99,15 +99,18 @@ static int add_to_swap_cache(struct page *page, swp_entry_t entry)
{
int error;
+ BUG_ON(PageLocked(page));
if (!swap_duplicate(entry)) {
INC_CACHE_INFO(noent_race);
return -ENOENT;
}
+ SetPageLocked(page);
error = __add_to_swap_cache(page, entry, GFP_KERNEL);
/*
* Anon pages are already on the LRU, we don't run lru_cache_add here.
*/
if (error) {
+ ClearPageLocked(page);
swap_free(entry);
if (error == -EEXIST)
INC_CACHE_INFO(exist_race);
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index 8803471593f..d436a9c82db 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -66,24 +66,19 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
if (!dentry)
goto put_memory;
- error = -ENFILE;
- file = get_empty_filp();
- if (!file)
- goto put_dentry;
-
error = -ENOSPC;
inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
if (!inode)
- goto close_file;
+ goto put_dentry;
d_instantiate(dentry, inode);
- inode->i_nlink = 0; /* It is unlinked */
+ error = -ENFILE;
+ file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
+ &ramfs_file_operations);
+ if (!file)
+ goto put_dentry;
- file->f_path.mnt = mntget(shm_mnt);
- file->f_path.dentry = dentry;
- file->f_mapping = inode->i_mapping;
- file->f_op = &ramfs_file_operations;
- file->f_mode = FMODE_WRITE | FMODE_READ;
+ inode->i_nlink = 0; /* It is unlinked */
/* notify everyone as to the change of file size */
error = do_truncate(dentry, size, 0, file);
diff --git a/mm/truncate.c b/mm/truncate.c
index 5cdfbc1a59f..cadc15653dd 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -8,6 +8,7 @@
*/
#include <linux/kernel.h>
+#include <linux/backing-dev.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/module.h>
@@ -72,6 +73,8 @@ void cancel_dirty_page(struct page *page, unsigned int account_size)
struct address_space *mapping = page->mapping;
if (mapping && mapping_cap_account_dirty(mapping)) {
dec_zone_page_state(page, NR_FILE_DIRTY);
+ dec_bdi_stat(mapping->backing_dev_info,
+ BDI_RECLAIMABLE);
if (account_size)
task_io_account_cancelled_write(account_size);
}
diff --git a/mm/util.c b/mm/util.c
index bf340d80686..5f64026cbb4 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -81,14 +81,16 @@ EXPORT_SYMBOL(kmemdup);
void *krealloc(const void *p, size_t new_size, gfp_t flags)
{
void *ret;
- size_t ks;
+ size_t ks = 0;
if (unlikely(!new_size)) {
kfree(p);
return ZERO_SIZE_PTR;
}
- ks = ksize(p);
+ if (p)
+ ks = ksize(p);
+
if (ks >= new_size)
return (void *)p;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 3cee76a8c9f..2e01af36584 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -190,7 +190,8 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long fl
if (unlikely(!size))
return NULL;
- area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node);
+ area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);
+
if (unlikely(!area))
return NULL;
@@ -439,7 +440,7 @@ void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
area->flags |= VM_VPAGES;
} else {
pages = kmalloc_node(array_size,
- (gfp_mask & GFP_LEVEL_MASK) | __GFP_ZERO,
+ (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO,
node);
}
area->pages = pages;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index a6e65d02499..cb474cc9964 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -932,6 +932,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
long mapped_ratio;
long distress;
long swap_tendency;
+ long imbalance;
if (zone_is_near_oom(zone))
goto force_reclaim_mapped;
@@ -967,6 +968,46 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;
/*
+ * If there's huge imbalance between active and inactive
+ * (think active 100 times larger than inactive) we should
+ * become more permissive, or the system will take too much
+ * cpu before it start swapping during memory pressure.
+ * Distress is about avoiding early-oom, this is about
+ * making swappiness graceful despite setting it to low
+ * values.
+ *
+ * Avoid div by zero with nr_inactive+1, and max resulting
+ * value is vm_total_pages.
+ */
+ imbalance = zone_page_state(zone, NR_ACTIVE);
+ imbalance /= zone_page_state(zone, NR_INACTIVE) + 1;
+
+ /*
+ * Reduce the effect of imbalance if swappiness is low,
+ * this means for a swappiness very low, the imbalance
+ * must be much higher than 100 for this logic to make
+ * the difference.
+ *
+ * Max temporary value is vm_total_pages*100.
+ */
+ imbalance *= (vm_swappiness + 1);
+ imbalance /= 100;
+
+ /*
+ * If not much of the ram is mapped, makes the imbalance
+ * less relevant, it's high priority we refill the inactive
+ * list with mapped pages only in presence of high ratio of
+ * mapped pages.
+ *
+ * Max temporary value is vm_total_pages*100.
+ */
+ imbalance *= mapped_ratio;
+ imbalance /= 100;
+
+ /* apply imbalance feedback to swap_tendency */
+ swap_tendency += imbalance;
+
+ /*
* Now use this metric to decide whether to start moving mapped
* memory onto the inactive list.
*/
@@ -1067,8 +1108,6 @@ static unsigned long shrink_zone(int priority, struct zone *zone,
unsigned long nr_to_scan;
unsigned long nr_reclaimed = 0;
- atomic_inc(&zone->reclaim_in_progress);
-
/*
* Add one to `nr_to_scan' just to make sure that the kernel will
* slowly sift through the active list.
@@ -1107,8 +1146,6 @@ static unsigned long shrink_zone(int priority, struct zone *zone,
}
throttle_vm_writeout(sc->gfp_mask);
-
- atomic_dec(&zone->reclaim_in_progress);
return nr_reclaimed;
}
@@ -1146,7 +1183,7 @@ static unsigned long shrink_zones(int priority, struct zone **zones,
note_zone_scanning_priority(zone, priority);
- if (zone->all_unreclaimable && priority != DEF_PRIORITY)
+ if (zone_is_all_unreclaimable(zone) && priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */
sc->all_unreclaimable = 0;
@@ -1245,7 +1282,7 @@ out:
*/
if (priority < 0)
priority = 0;
- for (i = 0; zones[i] != 0; i++) {
+ for (i = 0; zones[i] != NULL; i++) {
struct zone *zone = zones[i];
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
@@ -1327,7 +1364,8 @@ loop_again:
if (!populated_zone(zone))
continue;
- if (zone->all_unreclaimable && priority != DEF_PRIORITY)
+ if (zone_is_all_unreclaimable(zone) &&
+ priority != DEF_PRIORITY)
continue;
if (!zone_watermark_ok(zone, order, zone->pages_high,
@@ -1362,7 +1400,8 @@ loop_again:
if (!populated_zone(zone))
continue;
- if (zone->all_unreclaimable && priority != DEF_PRIORITY)
+ if (zone_is_all_unreclaimable(zone) &&
+ priority != DEF_PRIORITY)
continue;
if (!zone_watermark_ok(zone, order, zone->pages_high,
@@ -1371,18 +1410,25 @@ loop_again:
temp_priority[i] = priority;
sc.nr_scanned = 0;
note_zone_scanning_priority(zone, priority);
- nr_reclaimed += shrink_zone(priority, zone, &sc);
+ /*
+ * We put equal pressure on every zone, unless one
+ * zone has way too many pages free already.
+ */
+ if (!zone_watermark_ok(zone, order, 8*zone->pages_high,
+ end_zone, 0))
+ nr_reclaimed += shrink_zone(priority, zone, &sc);
reclaim_state->reclaimed_slab = 0;
nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
lru_pages);
nr_reclaimed += reclaim_state->reclaimed_slab;
total_scanned += sc.nr_scanned;
- if (zone->all_unreclaimable)
+ if (zone_is_all_unreclaimable(zone))
continue;
if (nr_slab == 0 && zone->pages_scanned >=
(zone_page_state(zone, NR_ACTIVE)
+ zone_page_state(zone, NR_INACTIVE)) * 6)
- zone->all_unreclaimable = 1;
+ zone_set_flag(zone,
+ ZONE_ALL_UNRECLAIMABLE);
/*
* If we've done a decent amount of scanning and
* the reclaim ratio is low, start doing writepage
@@ -1548,7 +1594,7 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio,
if (!populated_zone(zone))
continue;
- if (zone->all_unreclaimable && prio != DEF_PRIORITY)
+ if (zone_is_all_unreclaimable(zone) && prio != DEF_PRIORITY)
continue;
/* For pass = 0 we don't shrink the active list */
@@ -1688,9 +1734,11 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
{
pg_data_t *pgdat;
cpumask_t mask;
+ int nid;
if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) {
- for_each_online_pgdat(pgdat) {
+ for_each_node_state(nid, N_HIGH_MEMORY) {
+ pgdat = NODE_DATA(nid);
mask = node_to_cpumask(pgdat->node_id);
if (any_online_cpu(mask) != NR_CPUS)
/* One of our CPUs online: restore mask */
@@ -1727,7 +1775,7 @@ static int __init kswapd_init(void)
int nid;
swap_setup();
- for_each_online_node(nid)
+ for_each_node_state(nid, N_HIGH_MEMORY)
kswapd_run(nid);
hotcpu_notifier(cpu_callback, 0);
return 0;
@@ -1847,8 +1895,8 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
{
- cpumask_t mask;
int node_id;
+ int ret;
/*
* Zone reclaim reclaims unmapped file backed pages and
@@ -1866,15 +1914,13 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
<= zone->min_slab_pages)
return 0;
+ if (zone_is_all_unreclaimable(zone))
+ return 0;
+
/*
- * Avoid concurrent zone reclaims, do not reclaim in a zone that does
- * not have reclaimable pages and if we should not delay the allocation
- * then do not scan.
+ * Do not scan if the allocation should not be delayed.
*/
- if (!(gfp_mask & __GFP_WAIT) ||
- zone->all_unreclaimable ||
- atomic_read(&zone->reclaim_in_progress) > 0 ||
- (current->flags & PF_MEMALLOC))
+ if (!(gfp_mask & __GFP_WAIT) || (current->flags & PF_MEMALLOC))
return 0;
/*
@@ -1884,9 +1930,14 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
* as wide as possible.
*/
node_id = zone_to_nid(zone);
- mask = node_to_cpumask(node_id);
- if (!cpus_empty(mask) && node_id != numa_node_id())
+ if (node_state(node_id, N_CPU) && node_id != numa_node_id())
+ return 0;
+
+ if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
return 0;
- return __zone_reclaim(zone, gfp_mask, order);
+ ret = __zone_reclaim(zone, gfp_mask, order);
+ zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);
+
+ return ret;
}
#endif
diff --git a/mm/vmstat.c b/mm/vmstat.c
index c64d169537b..4651bf153f3 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -353,23 +353,6 @@ void refresh_cpu_vm_stats(int cpu)
}
}
-static void __refresh_cpu_vm_stats(void *dummy)
-{
- refresh_cpu_vm_stats(smp_processor_id());
-}
-
-/*
- * Consolidate all counters.
- *
- * Note that the result is less inaccurate but still inaccurate
- * if concurrent processes are allowed to run.
- */
-void refresh_vm_stats(void)
-{
- on_each_cpu(__refresh_cpu_vm_stats, NULL, 0, 1);
-}
-EXPORT_SYMBOL(refresh_vm_stats);
-
#endif
#ifdef CONFIG_NUMA
@@ -398,6 +381,13 @@ void zone_statistics(struct zonelist *zonelist, struct zone *z)
#include <linux/seq_file.h>
+static char * const migratetype_names[MIGRATE_TYPES] = {
+ "Unmovable",
+ "Reclaimable",
+ "Movable",
+ "Reserve",
+};
+
static void *frag_start(struct seq_file *m, loff_t *pos)
{
pg_data_t *pgdat;
@@ -422,28 +412,144 @@ static void frag_stop(struct seq_file *m, void *arg)
{
}
-/*
- * This walks the free areas for each zone.
- */
-static int frag_show(struct seq_file *m, void *arg)
+/* Walk all the zones in a node and print using a callback */
+static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
+ void (*print)(struct seq_file *m, pg_data_t *, struct zone *))
{
- pg_data_t *pgdat = (pg_data_t *)arg;
struct zone *zone;
struct zone *node_zones = pgdat->node_zones;
unsigned long flags;
- int order;
for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
if (!populated_zone(zone))
continue;
spin_lock_irqsave(&zone->lock, flags);
- seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
- for (order = 0; order < MAX_ORDER; ++order)
- seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
+ print(m, pgdat, zone);
spin_unlock_irqrestore(&zone->lock, flags);
+ }
+}
+
+static void frag_show_print(struct seq_file *m, pg_data_t *pgdat,
+ struct zone *zone)
+{
+ int order;
+
+ seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
+ for (order = 0; order < MAX_ORDER; ++order)
+ seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
+ seq_putc(m, '\n');
+}
+
+/*
+ * This walks the free areas for each zone.
+ */
+static int frag_show(struct seq_file *m, void *arg)
+{
+ pg_data_t *pgdat = (pg_data_t *)arg;
+ walk_zones_in_node(m, pgdat, frag_show_print);
+ return 0;
+}
+
+static void pagetypeinfo_showfree_print(struct seq_file *m,
+ pg_data_t *pgdat, struct zone *zone)
+{
+ int order, mtype;
+
+ for (mtype = 0; mtype < MIGRATE_TYPES; mtype++) {
+ seq_printf(m, "Node %4d, zone %8s, type %12s ",
+ pgdat->node_id,
+ zone->name,
+ migratetype_names[mtype]);
+ for (order = 0; order < MAX_ORDER; ++order) {
+ unsigned long freecount = 0;
+ struct free_area *area;
+ struct list_head *curr;
+
+ area = &(zone->free_area[order]);
+
+ list_for_each(curr, &area->free_list[mtype])
+ freecount++;
+ seq_printf(m, "%6lu ", freecount);
+ }
seq_putc(m, '\n');
}
+}
+
+/* Print out the free pages at each order for each migatetype */
+static int pagetypeinfo_showfree(struct seq_file *m, void *arg)
+{
+ int order;
+ pg_data_t *pgdat = (pg_data_t *)arg;
+
+ /* Print header */
+ seq_printf(m, "%-43s ", "Free pages count per migrate type at order");
+ for (order = 0; order < MAX_ORDER; ++order)
+ seq_printf(m, "%6d ", order);
+ seq_putc(m, '\n');
+
+ walk_zones_in_node(m, pgdat, pagetypeinfo_showfree_print);
+
+ return 0;
+}
+
+static void pagetypeinfo_showblockcount_print(struct seq_file *m,
+ pg_data_t *pgdat, struct zone *zone)
+{
+ int mtype;
+ unsigned long pfn;
+ unsigned long start_pfn = zone->zone_start_pfn;
+ unsigned long end_pfn = start_pfn + zone->spanned_pages;
+ unsigned long count[MIGRATE_TYPES] = { 0, };
+
+ for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
+ struct page *page;
+
+ if (!pfn_valid(pfn))
+ continue;
+
+ page = pfn_to_page(pfn);
+ mtype = get_pageblock_migratetype(page);
+
+ count[mtype]++;
+ }
+
+ /* Print counts */
+ seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
+ for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
+ seq_printf(m, "%12lu ", count[mtype]);
+ seq_putc(m, '\n');
+}
+
+/* Print out the free pages at each order for each migratetype */
+static int pagetypeinfo_showblockcount(struct seq_file *m, void *arg)
+{
+ int mtype;
+ pg_data_t *pgdat = (pg_data_t *)arg;
+
+ seq_printf(m, "\n%-23s", "Number of blocks type ");
+ for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
+ seq_printf(m, "%12s ", migratetype_names[mtype]);
+ seq_putc(m, '\n');
+ walk_zones_in_node(m, pgdat, pagetypeinfo_showblockcount_print);
+
+ return 0;
+}
+
+/*
+ * This prints out statistics in relation to grouping pages by mobility.
+ * It is expensive to collect so do not constantly read the file.
+ */
+static int pagetypeinfo_show(struct seq_file *m, void *arg)
+{
+ pg_data_t *pgdat = (pg_data_t *)arg;
+
+ seq_printf(m, "Page block order: %d\n", pageblock_order);
+ seq_printf(m, "Pages per block: %lu\n", pageblock_nr_pages);
+ seq_putc(m, '\n');
+ pagetypeinfo_showfree(m, pgdat);
+ pagetypeinfo_showblockcount(m, pgdat);
+
return 0;
}
@@ -454,6 +560,13 @@ const struct seq_operations fragmentation_op = {
.show = frag_show,
};
+const struct seq_operations pagetypeinfo_op = {
+ .start = frag_start,
+ .next = frag_next,
+ .stop = frag_stop,
+ .show = pagetypeinfo_show,
+};
+
#ifdef CONFIG_ZONE_DMA
#define TEXT_FOR_DMA(xx) xx "_dma",
#else
@@ -532,84 +645,78 @@ static const char * const vmstat_text[] = {
#endif
};
-/*
- * Output information about zones in @pgdat.
- */
-static int zoneinfo_show(struct seq_file *m, void *arg)
+static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
+ struct zone *zone)
{
- pg_data_t *pgdat = arg;
- struct zone *zone;
- struct zone *node_zones = pgdat->node_zones;
- unsigned long flags;
-
- for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) {
- int i;
-
- if (!populated_zone(zone))
- continue;
-
- spin_lock_irqsave(&zone->lock, flags);
- seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
- seq_printf(m,
- "\n pages free %lu"
- "\n min %lu"
- "\n low %lu"
- "\n high %lu"
- "\n scanned %lu (a: %lu i: %lu)"
- "\n spanned %lu"
- "\n present %lu",
- zone_page_state(zone, NR_FREE_PAGES),
- zone->pages_min,
- zone->pages_low,
- zone->pages_high,
- zone->pages_scanned,
- zone->nr_scan_active, zone->nr_scan_inactive,
- zone->spanned_pages,
- zone->present_pages);
+ int i;
+ seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
+ seq_printf(m,
+ "\n pages free %lu"
+ "\n min %lu"
+ "\n low %lu"
+ "\n high %lu"
+ "\n scanned %lu (a: %lu i: %lu)"
+ "\n spanned %lu"
+ "\n present %lu",
+ zone_page_state(zone, NR_FREE_PAGES),
+ zone->pages_min,
+ zone->pages_low,
+ zone->pages_high,
+ zone->pages_scanned,
+ zone->nr_scan_active, zone->nr_scan_inactive,
+ zone->spanned_pages,
+ zone->present_pages);
- for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
- seq_printf(m, "\n %-12s %lu", vmstat_text[i],
- zone_page_state(zone, i));
-
- seq_printf(m,
- "\n protection: (%lu",
- zone->lowmem_reserve[0]);
- for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
- seq_printf(m, ", %lu", zone->lowmem_reserve[i]);
- seq_printf(m,
- ")"
- "\n pagesets");
- for_each_online_cpu(i) {
- struct per_cpu_pageset *pageset;
- int j;
-
- pageset = zone_pcp(zone, i);
- for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
- seq_printf(m,
- "\n cpu: %i pcp: %i"
- "\n count: %i"
- "\n high: %i"
- "\n batch: %i",
- i, j,
- pageset->pcp[j].count,
- pageset->pcp[j].high,
- pageset->pcp[j].batch);
+ for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+ seq_printf(m, "\n %-12s %lu", vmstat_text[i],
+ zone_page_state(zone, i));
+
+ seq_printf(m,
+ "\n protection: (%lu",
+ zone->lowmem_reserve[0]);
+ for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
+ seq_printf(m, ", %lu", zone->lowmem_reserve[i]);
+ seq_printf(m,
+ ")"
+ "\n pagesets");
+ for_each_online_cpu(i) {
+ struct per_cpu_pageset *pageset;
+ int j;
+
+ pageset = zone_pcp(zone, i);
+ for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
+ seq_printf(m,
+ "\n cpu: %i pcp: %i"
+ "\n count: %i"
+ "\n high: %i"
+ "\n batch: %i",
+ i, j,
+ pageset->pcp[j].count,
+ pageset->pcp[j].high,
+ pageset->pcp[j].batch);
}
#ifdef CONFIG_SMP
- seq_printf(m, "\n vm stats threshold: %d",
- pageset->stat_threshold);
+ seq_printf(m, "\n vm stats threshold: %d",
+ pageset->stat_threshold);
#endif
- }
- seq_printf(m,
- "\n all_unreclaimable: %u"
- "\n prev_priority: %i"
- "\n start_pfn: %lu",
- zone->all_unreclaimable,
- zone->prev_priority,
- zone->zone_start_pfn);
- spin_unlock_irqrestore(&zone->lock, flags);
- seq_putc(m, '\n');
}
+ seq_printf(m,
+ "\n all_unreclaimable: %u"
+ "\n prev_priority: %i"
+ "\n start_pfn: %lu",
+ zone_is_all_unreclaimable(zone),
+ zone->prev_priority,
+ zone->zone_start_pfn);
+ seq_putc(m, '\n');
+}
+
+/*
+ * Output information about zones in @pgdat.
+ */
+static int zoneinfo_show(struct seq_file *m, void *arg)
+{
+ pg_data_t *pgdat = (pg_data_t *)arg;
+ walk_zones_in_node(m, pgdat, zoneinfo_show_print);
return 0;
}
@@ -741,7 +848,7 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb,
static struct notifier_block __cpuinitdata vmstat_notifier =
{ &vmstat_cpuup_callback, NULL, 0 };
-int __init setup_vmstat(void)
+static int __init setup_vmstat(void)
{
int cpu;
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
index 66821cd64a7..eecbf12f639 100644
--- a/net/9p/Kconfig
+++ b/net/9p/Kconfig
@@ -13,6 +13,16 @@ menuconfig NET_9P
If unsure, say N.
+config NET_9P_FD
+ depends on NET_9P
+ default y if NET_9P
+ tristate "9P File Descriptor Transports (Experimental)"
+ help
+ This builds support for file descriptor transports for 9p
+ which includes support for TCP/IP, named pipes, or passed
+ file descriptors. TCP/IP is the default transport for 9p,
+ so if you are going to use 9p, you'll likely want this.
+
config NET_9P_DEBUG
bool "Debug information"
depends on NET_9P
diff --git a/net/9p/Makefile b/net/9p/Makefile
index 85b3a7838ac..5059bc06f8f 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -1,8 +1,8 @@
obj-$(CONFIG_NET_9P) := 9pnet.o
+obj-$(CONFIG_NET_9P_FD) += 9pnet_fd.o
9pnet-objs := \
mod.o \
- trans_fd.o \
mux.o \
client.o \
conv.o \
@@ -10,4 +10,5 @@ obj-$(CONFIG_NET_9P) := 9pnet.o
fcprint.o \
util.o \
-9pnet-$(CONFIG_SYSCTL) += sysctl.o
+9pnet_fd-objs := \
+ trans_fd.o \
diff --git a/net/9p/client.c b/net/9p/client.c
index cb170750337..af919936404 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -30,6 +30,7 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <net/9p/9p.h>
+#include <linux/parser.h>
#include <net/9p/transport.h>
#include <net/9p/conn.h>
#include <net/9p/client.h>
@@ -38,7 +39,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt);
static void p9_fid_destroy(struct p9_fid *fid);
static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu);
-struct p9_client *p9_client_create(struct p9_transport *trans, int msize,
+struct p9_client *p9_client_create(struct p9_trans *trans, int msize,
int dotu)
{
int err, n;
@@ -146,7 +147,7 @@ void p9_client_disconnect(struct p9_client *clnt)
EXPORT_SYMBOL(p9_client_disconnect);
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
- char *uname, char *aname)
+ char *uname, u32 n_uname, char *aname)
{
int err;
struct p9_fcall *tc, *rc;
@@ -165,7 +166,8 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
goto error;
}
- tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname);
+ tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname,
+ n_uname, clnt->dotu);
if (IS_ERR(tc)) {
err = PTR_ERR(tc);
tc = NULL;
@@ -190,7 +192,8 @@ error:
}
EXPORT_SYMBOL(p9_client_attach);
-struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname)
+struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
+ u32 n_uname, char *aname)
{
int err;
struct p9_fcall *tc, *rc;
@@ -209,7 +212,7 @@ struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname)
goto error;
}
- tc = p9_create_tauth(fid->fid, uname, aname);
+ tc = p9_create_tauth(fid->fid, uname, aname, n_uname, clnt->dotu);
if (IS_ERR(tc)) {
err = PTR_ERR(tc);
tc = NULL;
diff --git a/net/9p/conv.c b/net/9p/conv.c
index d979d958ea1..aa2aa9884f9 100644
--- a/net/9p/conv.c
+++ b/net/9p/conv.c
@@ -547,7 +547,8 @@ error:
}
EXPORT_SYMBOL(p9_create_tversion);
-struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname)
+struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
+ u32 n_uname, int dotu)
{
int size;
struct p9_fcall *fc;
@@ -555,7 +556,16 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname)
struct cbuf *bufp = &buffer;
/* afid[4] uname[s] aname[s] */
- size = 4 + 2 + strlen(uname) + 2 + strlen(aname);
+ size = 4 + 2 + 2;
+ if (uname)
+ size += strlen(uname);
+
+ if (aname)
+ size += strlen(aname);
+
+ if (dotu)
+ size += 4; /* n_uname */
+
fc = p9_create_common(bufp, size, P9_TAUTH);
if (IS_ERR(fc))
goto error;
@@ -563,6 +573,8 @@ struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname)
p9_put_int32(bufp, afid, &fc->params.tauth.afid);
p9_put_str(bufp, uname, &fc->params.tauth.uname);
p9_put_str(bufp, aname, &fc->params.tauth.aname);
+ if (dotu)
+ p9_put_int32(bufp, n_uname, &fc->params.tauth.n_uname);
if (buf_check_overflow(bufp)) {
kfree(fc);
@@ -574,7 +586,8 @@ error:
EXPORT_SYMBOL(p9_create_tauth);
struct p9_fcall *
-p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname)
+p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
+ u32 n_uname, int dotu)
{
int size;
struct p9_fcall *fc;
@@ -582,7 +595,16 @@ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname)
struct cbuf *bufp = &buffer;
/* fid[4] afid[4] uname[s] aname[s] */
- size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname);
+ size = 4 + 4 + 2 + 2;
+ if (uname)
+ size += strlen(uname);
+
+ if (aname)
+ size += strlen(aname);
+
+ if (dotu)
+ size += 4; /* n_uname */
+
fc = p9_create_common(bufp, size, P9_TATTACH);
if (IS_ERR(fc))
goto error;
@@ -591,6 +613,8 @@ p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname)
p9_put_int32(bufp, afid, &fc->params.tattach.afid);
p9_put_str(bufp, uname, &fc->params.tattach.uname);
p9_put_str(bufp, aname, &fc->params.tattach.aname);
+ if (dotu)
+ p9_put_int32(bufp, n_uname, &fc->params.tattach.n_uname);
error:
return fc;
diff --git a/net/9p/mod.c b/net/9p/mod.c
index 4f9e1d2ac25..41d70f47375 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -27,6 +27,10 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <net/9p/9p.h>
+#include <linux/fs.h>
+#include <linux/parser.h>
+#include <net/9p/transport.h>
+#include <linux/list.h>
#ifdef CONFIG_NET_9P_DEBUG
unsigned int p9_debug_level = 0; /* feature-rific global debug level */
@@ -37,8 +41,64 @@ MODULE_PARM_DESC(debug, "9P debugging level");
extern int p9_mux_global_init(void);
extern void p9_mux_global_exit(void);
-extern int p9_sysctl_register(void);
-extern void p9_sysctl_unregister(void);
+
+/*
+ * Dynamic Transport Registration Routines
+ *
+ */
+
+static LIST_HEAD(v9fs_trans_list);
+static struct p9_trans_module *v9fs_default_transport;
+
+/**
+ * v9fs_register_trans - register a new transport with 9p
+ * @m - structure describing the transport module and entry points
+ *
+ */
+void v9fs_register_trans(struct p9_trans_module *m)
+{
+ list_add_tail(&m->list, &v9fs_trans_list);
+ if (m->def)
+ v9fs_default_transport = m;
+}
+EXPORT_SYMBOL(v9fs_register_trans);
+
+/**
+ * v9fs_match_trans - match transport versus registered transports
+ * @arg: string identifying transport
+ *
+ */
+struct p9_trans_module *v9fs_match_trans(const substring_t *name)
+{
+ struct list_head *p;
+ struct p9_trans_module *t = NULL;
+
+ list_for_each(p, &v9fs_trans_list) {
+ t = list_entry(p, struct p9_trans_module, list);
+ if (strncmp(t->name, name->from, name->to-name->from) == 0)
+ break;
+ }
+ return t;
+}
+EXPORT_SYMBOL(v9fs_match_trans);
+
+/**
+ * v9fs_default_trans - returns pointer to default transport
+ *
+ */
+
+struct p9_trans_module *v9fs_default_trans(void)
+{
+ if (v9fs_default_transport)
+ return v9fs_default_transport;
+ else if (!list_empty(&v9fs_trans_list))
+ return list_first_entry(&v9fs_trans_list,
+ struct p9_trans_module, list);
+ else
+ return NULL;
+}
+EXPORT_SYMBOL(v9fs_default_trans);
+
/**
* v9fs_init - Initialize module
@@ -56,12 +116,6 @@ static int __init init_p9(void)
return ret;
}
- ret = p9_sysctl_register();
- if (ret) {
- printk(KERN_WARNING "9p: registering sysctl failed\n");
- return ret;
- }
-
return ret;
}
@@ -72,7 +126,6 @@ static int __init init_p9(void)
static void __exit exit_p9(void)
{
- p9_sysctl_unregister();
p9_mux_global_exit();
}
diff --git a/net/9p/mux.c b/net/9p/mux.c
index 5d70558c4c6..f14014793be 100644
--- a/net/9p/mux.c
+++ b/net/9p/mux.c
@@ -31,6 +31,7 @@
#include <linux/idr.h>
#include <linux/mutex.h>
#include <net/9p/9p.h>
+#include <linux/parser.h>
#include <net/9p/transport.h>
#include <net/9p/conn.h>
@@ -71,7 +72,7 @@ struct p9_conn {
struct p9_mux_poll_task *poll_task;
int msize;
unsigned char *extended;
- struct p9_transport *trans;
+ struct p9_trans *trans;
struct p9_idpool *tagpool;
int err;
wait_queue_head_t equeue;
@@ -271,7 +272,7 @@ static void p9_mux_poll_stop(struct p9_conn *m)
* @msize - maximum message size
* @extended - pointer to the extended flag
*/
-struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize,
+struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize,
unsigned char *extended)
{
int i, n;
diff --git a/net/9p/sysctl.c b/net/9p/sysctl.c
deleted file mode 100644
index 8b61027a24e..00000000000
--- a/net/9p/sysctl.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * net/9p/sysctl.c
- *
- * 9P sysctl interface
- *
- * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
- *
- * 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:
- * Free Software Foundation
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02111-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <linux/init.h>
-#include <net/9p/9p.h>
-
-static struct ctl_table p9_table[] = {
-#ifdef CONFIG_NET_9P_DEBUG
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "debug",
- .data = &p9_debug_level,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec
- },
-#endif
- {},
-};
-
-static struct ctl_table p9_net_table[] = {
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "9p",
- .maxlen = 0,
- .mode = 0555,
- .child = p9_table,
- },
- {},
-};
-
-static struct ctl_table p9_ctl_table[] = {
- {
- .ctl_name = CTL_NET,
- .procname = "net",
- .maxlen = 0,
- .mode = 0555,
- .child = p9_net_table,
- },
- {},
-};
-
-static struct ctl_table_header *p9_table_header;
-
-int __init p9_sysctl_register(void)
-{
- p9_table_header = register_sysctl_table(p9_ctl_table);
- if (!p9_table_header)
- return -ENOMEM;
-
- return 0;
-}
-
-void __exit p9_sysctl_unregister(void)
-{
- unregister_sysctl_table(p9_table_header);
-}
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index fd636e94358..30269a4ff22 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
* Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
- * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com>
+ * Copyright (C) 2004-2007 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -36,160 +36,114 @@
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
+#include <linux/parser.h>
#include <net/9p/9p.h>
#include <net/9p/transport.h>
#define P9_PORT 564
+#define MAX_SOCK_BUF (64*1024)
+
+
+struct p9_fd_opts {
+ int rfd;
+ int wfd;
+ u16 port;
+};
struct p9_trans_fd {
struct file *rd;
struct file *wr;
};
-static int p9_socket_open(struct p9_transport *trans, struct socket *csocket);
-static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd);
-static int p9_fd_read(struct p9_transport *trans, void *v, int len);
-static int p9_fd_write(struct p9_transport *trans, void *v, int len);
-static unsigned int p9_fd_poll(struct p9_transport *trans,
- struct poll_table_struct *pt);
-static void p9_fd_close(struct p9_transport *trans);
-
-struct p9_transport *p9_trans_create_tcp(const char *addr, int port)
-{
- int err;
- struct p9_transport *trans;
- struct socket *csocket;
- struct sockaddr_in sin_server;
-
- csocket = NULL;
- trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
-
- trans->write = p9_fd_write;
- trans->read = p9_fd_read;
- trans->close = p9_fd_close;
- trans->poll = p9_fd_poll;
-
- sin_server.sin_family = AF_INET;
- sin_server.sin_addr.s_addr = in_aton(addr);
- sin_server.sin_port = htons(port);
- sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
-
- if (!csocket) {
- P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n");
- err = -EIO;
- goto error;
- }
-
- err = csocket->ops->connect(csocket,
- (struct sockaddr *)&sin_server,
- sizeof(struct sockaddr_in), 0);
- if (err < 0) {
- P9_EPRINTK(KERN_ERR,
- "p9_trans_tcp: problem connecting socket to %s\n",
- addr);
- goto error;
- }
-
- err = p9_socket_open(trans, csocket);
- if (err < 0)
- goto error;
+/*
+ * Option Parsing (code inspired by NFS code)
+ * - a little lazy - parse all fd-transport options
+ */
- return trans;
+enum {
+ /* Options that take integer arguments */
+ Opt_port, Opt_rfdno, Opt_wfdno,
+};
-error:
- if (csocket)
- sock_release(csocket);
+static match_table_t tokens = {
+ {Opt_port, "port=%u"},
+ {Opt_rfdno, "rfdno=%u"},
+ {Opt_wfdno, "wfdno=%u"},
+};
- kfree(trans);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_trans_create_tcp);
+/**
+ * v9fs_parse_options - parse mount options into session structure
+ * @options: options string passed from mount
+ * @v9ses: existing v9fs session information
+ *
+ */
-struct p9_transport *p9_trans_create_unix(const char *addr)
+static void parse_opts(char *options, struct p9_fd_opts *opts)
{
- int err;
- struct socket *csocket;
- struct sockaddr_un sun_server;
- struct p9_transport *trans;
-
- csocket = NULL;
- trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option;
+ int ret;
- trans->write = p9_fd_write;
- trans->read = p9_fd_read;
- trans->close = p9_fd_close;
- trans->poll = p9_fd_poll;
+ opts->port = P9_PORT;
+ opts->rfd = ~0;
+ opts->wfd = ~0;
- if (strlen(addr) > UNIX_PATH_MAX) {
- P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
- addr);
- err = -ENAMETOOLONG;
- goto error;
- }
+ if (!options)
+ return;
- sun_server.sun_family = PF_UNIX;
- strcpy(sun_server.sun_path, addr);
- sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
- err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
- sizeof(struct sockaddr_un) - 1, 0);
- if (err < 0) {
- P9_EPRINTK(KERN_ERR,
- "p9_trans_unix: problem connecting socket: %s: %d\n",
- addr, err);
- goto error;
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
+ continue;
+ token = match_token(p, tokens, args);
+ ret = match_int(&args[0], &option);
+ if (ret < 0) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "integer field, but no integer?\n");
+ continue;
+ }
+ switch (token) {
+ case Opt_port:
+ opts->port = option;
+ break;
+ case Opt_rfdno:
+ opts->rfd = option;
+ break;
+ case Opt_wfdno:
+ opts->wfd = option;
+ break;
+ default:
+ continue;
+ }
}
-
- err = p9_socket_open(trans, csocket);
- if (err < 0)
- goto error;
-
- return trans;
-
-error:
- if (csocket)
- sock_release(csocket);
-
- kfree(trans);
- return ERR_PTR(err);
}
-EXPORT_SYMBOL(p9_trans_create_unix);
-struct p9_transport *p9_trans_create_fd(int rfd, int wfd)
+static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
{
- int err;
- struct p9_transport *trans;
+ struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
+ GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
- if (rfd == ~0 || wfd == ~0) {
- printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
- return ERR_PTR(-ENOPROTOOPT);
+ ts->rd = fget(rfd);
+ ts->wr = fget(wfd);
+ if (!ts->rd || !ts->wr) {
+ if (ts->rd)
+ fput(ts->rd);
+ if (ts->wr)
+ fput(ts->wr);
+ kfree(ts);
+ return -EIO;
}
- trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
-
- trans->write = p9_fd_write;
- trans->read = p9_fd_read;
- trans->close = p9_fd_close;
- trans->poll = p9_fd_poll;
-
- err = p9_fd_open(trans, rfd, wfd);
- if (err < 0)
- goto error;
-
- return trans;
+ trans->priv = ts;
+ trans->status = Connected;
-error:
- kfree(trans);
- return ERR_PTR(err);
+ return 0;
}
-EXPORT_SYMBOL(p9_trans_create_fd);
-static int p9_socket_open(struct p9_transport *trans, struct socket *csocket)
+static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
{
int fd, ret;
@@ -212,30 +166,6 @@ static int p9_socket_open(struct p9_transport *trans, struct socket *csocket)
return 0;
}
-static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd)
-{
- struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
- GFP_KERNEL);
- if (!ts)
- return -ENOMEM;
-
- ts->rd = fget(rfd);
- ts->wr = fget(wfd);
- if (!ts->rd || !ts->wr) {
- if (ts->rd)
- fput(ts->rd);
- if (ts->wr)
- fput(ts->wr);
- kfree(ts);
- return -EIO;
- }
-
- trans->priv = ts;
- trans->status = Connected;
-
- return 0;
-}
-
/**
* p9_fd_read- read from a fd
* @v9ses: session information
@@ -243,7 +173,7 @@ static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd)
* @len: size of receive buffer
*
*/
-static int p9_fd_read(struct p9_transport *trans, void *v, int len)
+static int p9_fd_read(struct p9_trans *trans, void *v, int len)
{
int ret;
struct p9_trans_fd *ts = NULL;
@@ -270,7 +200,7 @@ static int p9_fd_read(struct p9_transport *trans, void *v, int len)
* @len: size of send buffer
*
*/
-static int p9_fd_write(struct p9_transport *trans, void *v, int len)
+static int p9_fd_write(struct p9_trans *trans, void *v, int len)
{
int ret;
mm_segment_t oldfs;
@@ -297,7 +227,7 @@ static int p9_fd_write(struct p9_transport *trans, void *v, int len)
}
static unsigned int
-p9_fd_poll(struct p9_transport *trans, struct poll_table_struct *pt)
+p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
{
int ret, n;
struct p9_trans_fd *ts = NULL;
@@ -341,7 +271,7 @@ end:
* @trans: private socket structure
*
*/
-static void p9_fd_close(struct p9_transport *trans)
+static void p9_fd_close(struct p9_trans *trans)
{
struct p9_trans_fd *ts;
@@ -361,3 +291,182 @@ static void p9_fd_close(struct p9_transport *trans)
kfree(ts);
}
+static struct p9_trans *p9_trans_create_tcp(const char *addr, char *args)
+{
+ int err;
+ struct p9_trans *trans;
+ struct socket *csocket;
+ struct sockaddr_in sin_server;
+ struct p9_fd_opts opts;
+
+ parse_opts(args, &opts);
+
+ csocket = NULL;
+ trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+ if (!trans)
+ return ERR_PTR(-ENOMEM);
+
+ trans->write = p9_fd_write;
+ trans->read = p9_fd_read;
+ trans->close = p9_fd_close;
+ trans->poll = p9_fd_poll;
+
+ sin_server.sin_family = AF_INET;
+ sin_server.sin_addr.s_addr = in_aton(addr);
+ sin_server.sin_port = htons(opts.port);
+ sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
+
+ if (!csocket) {
+ P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n");
+ err = -EIO;
+ goto error;
+ }
+
+ err = csocket->ops->connect(csocket,
+ (struct sockaddr *)&sin_server,
+ sizeof(struct sockaddr_in), 0);
+ if (err < 0) {
+ P9_EPRINTK(KERN_ERR,
+ "p9_trans_tcp: problem connecting socket to %s\n",
+ addr);
+ goto error;
+ }
+
+ err = p9_socket_open(trans, csocket);
+ if (err < 0)
+ goto error;
+
+ return trans;
+
+error:
+ if (csocket)
+ sock_release(csocket);
+
+ kfree(trans);
+ return ERR_PTR(err);
+}
+
+static struct p9_trans *p9_trans_create_unix(const char *addr, char *args)
+{
+ int err;
+ struct socket *csocket;
+ struct sockaddr_un sun_server;
+ struct p9_trans *trans;
+
+ csocket = NULL;
+ trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+ if (!trans)
+ return ERR_PTR(-ENOMEM);
+
+ trans->write = p9_fd_write;
+ trans->read = p9_fd_read;
+ trans->close = p9_fd_close;
+ trans->poll = p9_fd_poll;
+
+ if (strlen(addr) > UNIX_PATH_MAX) {
+ P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
+ addr);
+ err = -ENAMETOOLONG;
+ goto error;
+ }
+
+ sun_server.sun_family = PF_UNIX;
+ strcpy(sun_server.sun_path, addr);
+ sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
+ err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
+ sizeof(struct sockaddr_un) - 1, 0);
+ if (err < 0) {
+ P9_EPRINTK(KERN_ERR,
+ "p9_trans_unix: problem connecting socket: %s: %d\n",
+ addr, err);
+ goto error;
+ }
+
+ err = p9_socket_open(trans, csocket);
+ if (err < 0)
+ goto error;
+
+ return trans;
+
+error:
+ if (csocket)
+ sock_release(csocket);
+
+ kfree(trans);
+ return ERR_PTR(err);
+}
+
+static struct p9_trans *p9_trans_create_fd(const char *name, char *args)
+{
+ int err;
+ struct p9_trans *trans;
+ struct p9_fd_opts opts;
+
+ parse_opts(args, &opts);
+
+ if (opts.rfd == ~0 || opts.wfd == ~0) {
+ printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
+ return ERR_PTR(-ENOPROTOOPT);
+ }
+
+ trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
+ if (!trans)
+ return ERR_PTR(-ENOMEM);
+
+ trans->write = p9_fd_write;
+ trans->read = p9_fd_read;
+ trans->close = p9_fd_close;
+ trans->poll = p9_fd_poll;
+
+ err = p9_fd_open(trans, opts.rfd, opts.wfd);
+ if (err < 0)
+ goto error;
+
+ return trans;
+
+error:
+ kfree(trans);
+ return ERR_PTR(err);
+}
+
+static struct p9_trans_module p9_tcp_trans = {
+ .name = "tcp",
+ .maxsize = MAX_SOCK_BUF,
+ .def = 1,
+ .create = p9_trans_create_tcp,
+};
+
+static struct p9_trans_module p9_unix_trans = {
+ .name = "unix",
+ .maxsize = MAX_SOCK_BUF,
+ .def = 0,
+ .create = p9_trans_create_unix,
+};
+
+static struct p9_trans_module p9_fd_trans = {
+ .name = "fd",
+ .maxsize = MAX_SOCK_BUF,
+ .def = 0,
+ .create = p9_trans_create_fd,
+};
+
+static int __init p9_trans_fd_init(void)
+{
+ v9fs_register_trans(&p9_tcp_trans);
+ v9fs_register_trans(&p9_unix_trans);
+ v9fs_register_trans(&p9_fd_trans);
+
+ return 1;
+}
+
+static void __exit p9_trans_fd_exit(void) {
+ printk(KERN_ERR "Removal of 9p transports not implemented\n");
+ BUG();
+}
+
+module_init(p9_trans_fd_init);
+module_exit(p9_trans_fd_exit);
+
+MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
+MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index c742d37bfb9..ba6428f204f 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -24,16 +24,6 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
#include "common.h"
-/*
- * Define this to use a version of the code which interacts with the higher
- * layers in a more intellegent way, by always reserving enough space for
- * our header at the begining of the packet. However, there may still be
- * some problems with programs like tcpdump. In 2.5 we'll sort out what
- * we need to do to get this perfect. For now we just will copy the packet
- * if we need space for the header
- */
-/* #define FASTER_VERSION */
-
#ifdef SKB_DEBUG
static void skb_debug(const struct sk_buff *skb)
{
@@ -69,9 +59,7 @@ struct br2684_vcc {
#ifdef CONFIG_ATM_BR2684_IPFILTER
struct br2684_filter filter;
#endif /* CONFIG_ATM_BR2684_IPFILTER */
-#ifndef FASTER_VERSION
unsigned copies_needed, copies_failed;
-#endif /* FASTER_VERSION */
};
struct br2684_dev {
@@ -147,13 +135,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
struct br2684_vcc *brvcc)
{
struct atm_vcc *atmvcc;
-#ifdef FASTER_VERSION
- if (brvcc->encaps == e_llc)
- memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8);
- /* last 2 bytes of llc_oui_pid_pad are managed by header routines;
- yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad)
- */
-#else
int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
if (skb_headroom(skb) < minheadroom) {
struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
@@ -170,7 +151,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10);
else
memset(skb->data, 0, 2);
-#endif /* FASTER_VERSION */
skb_debug(skb);
ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
@@ -237,87 +217,6 @@ static struct net_device_stats *br2684_get_stats(struct net_device *dev)
return &BRPRIV(dev)->stats;
}
-#ifdef FASTER_VERSION
-/*
- * These mirror eth_header and eth_header_cache. They are not usually
- * exported for use in modules, so we grab them from net_device
- * after ether_setup() is done with it. Bit of a hack.
- */
-static int (*my_eth_header)(struct sk_buff *, struct net_device *,
- unsigned short, void *, void *, unsigned);
-static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *);
-
-static int
-br2684_header(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, void *daddr, void *saddr, unsigned len)
-{
- u16 *pad_before_eth;
- int t = my_eth_header(skb, dev, type, daddr, saddr, len);
- if (t > 0) {
- pad_before_eth = (u16 *) skb_push(skb, 2);
- *pad_before_eth = 0;
- return dev->hard_header_len; /* or return 16; ? */
- } else
- return t;
-}
-
-static int
-br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh)
-{
-/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so
-xmit will add the additional header part in that case */
- u16 *pad_before_eth = (u16 *)(hh->hh_data);
- int t = my_eth_header_cache(neigh, hh);
- DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh);
- if (t < 0)
- return t;
- else {
- *pad_before_eth = 0;
- hh->hh_len = PADLEN + ETH_HLEN;
- }
- return 0;
-}
-
-/*
- * This is similar to eth_type_trans, which cannot be used because of
- * our dev->hard_header_len
- */
-static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev)
-{
- struct ethhdr *eth;
- unsigned char *rawp;
- eth = eth_hdr(skb);
-
- if (is_multicast_ether_addr(eth->h_dest)) {
- if (!compare_ether_addr(eth->h_dest, dev->broadcast))
- skb->pkt_type = PACKET_BROADCAST;
- else
- skb->pkt_type = PACKET_MULTICAST;
- }
-
- else if (compare_ether_addr(eth->h_dest, dev->dev_addr))
- skb->pkt_type = PACKET_OTHERHOST;
-
- if (ntohs(eth->h_proto) >= 1536)
- return eth->h_proto;
-
- rawp = skb->data;
-
- /*
- * This is a magic hack to spot IPX packets. Older Novell breaks
- * the protocol design and runs IPX over 802.3 without an 802.2 LLC
- * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
- * won't work for fault tolerant netware but does for the rest.
- */
- if (*(unsigned short *) rawp == 0xFFFF)
- return htons(ETH_P_802_3);
-
- /*
- * Real 802.2 LLC
- */
- return htons(ETH_P_802_2);
-}
-#endif /* FASTER_VERSION */
/*
* We remember when the MAC gets set, so we don't override it later with
@@ -448,17 +347,8 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
return;
}
-#ifdef FASTER_VERSION
- /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier,
- than should be. What else should I set? */
- skb_pull(skb, plen);
- skb_set_mac_header(skb, -ETH_HLEN);
- skb->pkt_type = PACKET_HOST;
- skb->protocol = br_type_trans(skb, net_dev);
-#else
skb_pull(skb, plen - ETH_HLEN);
skb->protocol = eth_type_trans(skb, net_dev);
-#endif /* FASTER_VERSION */
#ifdef CONFIG_ATM_BR2684_IPFILTER
if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
brdev->stats.rx_dropped++;
@@ -584,13 +474,6 @@ static void br2684_setup(struct net_device *netdev)
ether_setup(netdev);
brdev->net_dev = netdev;
-#ifdef FASTER_VERSION
- my_eth_header = netdev->hard_header;
- netdev->hard_header = br2684_header;
- my_eth_header_cache = netdev->hard_header_cache;
- netdev->hard_header_cache = br2684_header_cache;
- netdev->hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN; /* 10 + 14 */
-#endif
my_eth_mac_addr = netdev->set_mac_address;
netdev->set_mac_address = br2684_mac_addr;
netdev->hard_start_xmit = br2684_start_xmit;
@@ -719,16 +602,12 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
seq_printf(seq, " vcc %d.%d.%d: encaps=%s"
-#ifndef FASTER_VERSION
", failed copies %u/%u"
-#endif /* FASTER_VERSION */
"\n", brvcc->atmvcc->dev->number,
brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
(brvcc->encaps == e_llc) ? "LLC" : "VC"
-#ifndef FASTER_VERSION
, brvcc->copies_failed
, brvcc->copies_needed
-#endif /* FASTER_VERSION */
);
#ifdef CONFIG_ATM_BR2684_IPFILTER
#define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte]
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 848b8fa8bed..93867bb6cc9 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -23,7 +23,7 @@
#include "br_private.h"
-int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
+int (*br_should_route_hook)(struct sk_buff *skb);
static struct llc_sap *br_stp_sap;
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 3a8a015c92e..3cedd4eeeed 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -126,6 +126,10 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
goto drop;
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb)
+ return NULL;
+
if (unlikely(is_link_local(dest))) {
/* Pause frames shouldn't be passed up by driver anyway */
if (skb->protocol == htons(ETH_P_PAUSE))
@@ -145,7 +149,7 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
case BR_STATE_FORWARDING:
if (br_should_route_hook) {
- if (br_should_route_hook(&skb))
+ if (br_should_route_hook(skb))
return skb;
dest = eth_hdr(skb)->h_dest;
}
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 8245f051ccb..da22f900e89 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -503,18 +503,14 @@ inhdr_error:
* receiving device) to make netfilter happy, the REDIRECT
* target in particular. Save the original destination IP
* address to be able to detect DNAT afterwards. */
-static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
- struct sk_buff *skb = *pskb;
__u32 len = nf_bridge_encap_header_len(skb);
- if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
- return NF_STOLEN;
-
if (unlikely(!pskb_may_pull(skb, len)))
goto out;
@@ -584,13 +580,11 @@ out:
* took place when the packet entered the bridge), but we
* register an IPv4 PRE_ROUTING 'sabotage' hook that will
* prevent this from happening. */
-static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *skb = *pskb;
-
if (skb->dst == (struct dst_entry *)&__fake_rtable) {
dst_release(skb->dst);
skb->dst = NULL;
@@ -625,12 +619,11 @@ static int br_nf_forward_finish(struct sk_buff *skb)
* but we are still able to filter on the 'real' indev/outdev
* because of the physdev module. For ARP, indev and outdev are the
* bridge ports. */
-static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
struct net_device *parent;
int pf;
@@ -648,7 +641,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
else
pf = PF_INET6;
- nf_bridge_pull_encap_header(*pskb);
+ nf_bridge_pull_encap_header(skb);
nf_bridge = skb->nf_bridge;
if (skb->pkt_type == PACKET_OTHERHOST) {
@@ -666,12 +659,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
return NF_STOLEN;
}
-static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *skb = *pskb;
struct net_device **d = (struct net_device **)(skb->cb);
#ifdef CONFIG_SYSCTL
@@ -682,12 +674,12 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
if (skb->protocol != htons(ETH_P_ARP)) {
if (!IS_VLAN_ARP(skb))
return NF_ACCEPT;
- nf_bridge_pull_encap_header(*pskb);
+ nf_bridge_pull_encap_header(skb);
}
if (arp_hdr(skb)->ar_pln != 4) {
if (IS_VLAN_ARP(skb))
- nf_bridge_push_encap_header(*pskb);
+ nf_bridge_push_encap_header(skb);
return NF_ACCEPT;
}
*d = (struct net_device *)in;
@@ -709,13 +701,12 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
* NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
* will be executed.
*/
-static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct net_device *realindev;
- struct sk_buff *skb = *pskb;
struct nf_bridge_info *nf_bridge;
if (!skb->nf_bridge)
@@ -752,13 +743,12 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb)
}
/* PF_BRIDGE/POST_ROUTING ********************************************/
-static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
+static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *skb = *pskb;
- struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge;
+ struct nf_bridge_info *nf_bridge = skb->nf_bridge;
struct net_device *realoutdev = bridge_parent(skb->dev);
int pf;
@@ -828,13 +818,13 @@ print_error:
/* IP/SABOTAGE *****************************************************/
/* Don't hand locally destined packets to PF_INET(6)/PRE_ROUTING
* for the second time. */
-static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
+static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- if ((*pskb)->nf_bridge &&
- !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
+ if (skb->nf_bridge &&
+ !(skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
return NF_STOP;
}
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c
index ffe468a632e..48a80e42328 100644
--- a/net/bridge/netfilter/ebt_arpreply.c
+++ b/net/bridge/netfilter/ebt_arpreply.c
@@ -15,7 +15,7 @@
#include <net/arp.h>
#include <linux/module.h>
-static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
+static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
@@ -23,7 +23,6 @@ static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
__be32 _sip, *siptr, _dip, *diptr;
struct arphdr _ah, *ap;
unsigned char _sha[ETH_ALEN], *shp;
- struct sk_buff *skb = *pskb;
ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL)
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index 4582659dff0..74262e9a566 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -8,29 +8,22 @@
*
*/
+#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
#include <net/sock.h>
-static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr,
+static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_nat_info *info = (struct ebt_nat_info *)data;
- if (skb_shared(*pskb) || skb_cloned(*pskb)) {
- struct sk_buff *nskb;
+ if (skb_make_writable(skb, 0))
+ return NF_DROP;
- nskb = skb_copy(*pskb, GFP_ATOMIC);
- if (!nskb)
- return NF_DROP;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
- memcpy(eth_hdr(*pskb)->h_dest, info->mac, ETH_ALEN);
+ memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN);
return info->target;
}
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 62d23c7b25e..6cba54309c0 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -17,7 +17,7 @@
#include <linux/netfilter_bridge/ebt_mark_t.h>
#include <linux/module.h>
-static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
+static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
@@ -25,13 +25,13 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
int action = info->target & -16;
if (action == MARK_SET_VALUE)
- (*pskb)->mark = info->mark;
+ skb->mark = info->mark;
else if (action == MARK_OR_VALUE)
- (*pskb)->mark |= info->mark;
+ skb->mark |= info->mark;
else if (action == MARK_AND_VALUE)
- (*pskb)->mark &= info->mark;
+ skb->mark &= info->mark;
else
- (*pskb)->mark ^= info->mark;
+ skb->mark ^= info->mark;
return info->target | ~EBT_VERDICT_BITS;
}
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index 9f378eab72d..422cb834cff 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -8,35 +8,28 @@
*
*/
+#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_redirect.h>
#include <linux/module.h>
#include <net/sock.h>
#include "../br_private.h"
-static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr,
+static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
- if (skb_shared(*pskb) || skb_cloned(*pskb)) {
- struct sk_buff *nskb;
+ if (skb_make_writable(skb, 0))
+ return NF_DROP;
- nskb = skb_copy(*pskb, GFP_ATOMIC);
- if (!nskb)
- return NF_DROP;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
if (hooknr != NF_BR_BROUTING)
- memcpy(eth_hdr(*pskb)->h_dest,
+ memcpy(eth_hdr(skb)->h_dest,
in->br_port->br->dev->dev_addr, ETH_ALEN);
else
- memcpy(eth_hdr(*pskb)->h_dest, in->dev_addr, ETH_ALEN);
- (*pskb)->pkt_type = PACKET_HOST;
+ memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN);
+ skb->pkt_type = PACKET_HOST;
return info->target;
}
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index a50722182bf..425ac920904 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
@@ -15,34 +16,26 @@
#include <linux/if_arp.h>
#include <net/arp.h>
-static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
+static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_nat_info *info = (struct ebt_nat_info *) data;
- if (skb_shared(*pskb) || skb_cloned(*pskb)) {
- struct sk_buff *nskb;
+ if (skb_make_writable(skb, 0))
+ return NF_DROP;
- nskb = skb_copy(*pskb, GFP_ATOMIC);
- if (!nskb)
- return NF_DROP;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
- memcpy(eth_hdr(*pskb)->h_source, info->mac, ETH_ALEN);
+ memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
if (!(info->target & NAT_ARP_BIT) &&
- eth_hdr(*pskb)->h_proto == htons(ETH_P_ARP)) {
+ eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
struct arphdr _ah, *ap;
- ap = skb_header_pointer(*pskb, 0, sizeof(_ah), &_ah);
+ ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL)
return EBT_DROP;
if (ap->ar_hln != ETH_ALEN)
goto out;
- if (skb_store_bits(*pskb, sizeof(_ah), info->mac,ETH_ALEN))
+ if (skb_store_bits(skb, sizeof(_ah), info->mac,ETH_ALEN))
return EBT_DROP;
}
out:
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index d37ce047893..e44519ebf1d 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -51,11 +51,11 @@ static struct ebt_table broute_table =
.me = THIS_MODULE,
};
-static int ebt_broute(struct sk_buff **pskb)
+static int ebt_broute(struct sk_buff *skb)
{
int ret;
- ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL,
+ ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL,
&broute_table);
if (ret == NF_DROP)
return 1; /* route it */
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index 81d84145c41..210493f99bc 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -61,10 +61,10 @@ static struct ebt_table frame_filter =
};
static unsigned int
-ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in,
+ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, int (*okfn)(struct sk_buff *))
{
- return ebt_do_table(hook, pskb, in, out, &frame_filter);
+ return ebt_do_table(hook, skb, in, out, &frame_filter);
}
static struct nf_hook_ops ebt_ops_filter[] = {
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 9c50488b62e..3e58c2e5ee2 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -61,17 +61,17 @@ static struct ebt_table frame_nat =
};
static unsigned int
-ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
+ebt_nat_dst(unsigned int hook, struct sk_buff *skb, const struct net_device *in
, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
- return ebt_do_table(hook, pskb, in, out, &frame_nat);
+ return ebt_do_table(hook, skb, in, out, &frame_nat);
}
static unsigned int
-ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in
+ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in
, const struct net_device *out, int (*okfn)(struct sk_buff *))
{
- return ebt_do_table(hook, pskb, in, out, &frame_nat);
+ return ebt_do_table(hook, skb, in, out, &frame_nat);
}
static struct nf_hook_ops ebt_ops_nat[] = {
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 6018d0e5193..d5a09eaef91 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -142,7 +142,7 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
}
/* Do some firewalling */
-unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
+unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
struct ebt_table *table)
{
@@ -172,19 +172,19 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
base = private->entries;
i = 0;
while (i < nentries) {
- if (ebt_basic_match(point, eth_hdr(*pskb), in, out))
+ if (ebt_basic_match(point, eth_hdr(skb), in, out))
goto letscontinue;
- if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0)
+ if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0)
goto letscontinue;
/* increase counter */
(*(counter_base + i)).pcnt++;
- (*(counter_base + i)).bcnt+=(**pskb).len;
+ (*(counter_base + i)).bcnt += skb->len;
/* these should only watch: not modify, nor tell us
what to do with the packet */
- EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, hook, in,
+ EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in,
out);
t = (struct ebt_entry_target *)
@@ -193,7 +193,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
if (!t->u.target->target)
verdict = ((struct ebt_standard_target *)t)->verdict;
else
- verdict = t->u.target->target(pskb, hook,
+ verdict = t->u.target->target(skb, hook,
in, out, t->data, t->target_size);
if (verdict == EBT_ACCEPT) {
read_unlock_bh(&table->lock);
diff --git a/net/core/dev.c b/net/core/dev.c
index 99b7bda37d1..38b03da5c1c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1362,22 +1362,21 @@ int skb_checksum_help(struct sk_buff *skb)
goto out_set_summed;
}
- if (skb_cloned(skb)) {
+ offset = skb->csum_start - skb_headroom(skb);
+ BUG_ON(offset >= skb_headlen(skb));
+ csum = skb_checksum(skb, offset, skb->len - offset, 0);
+
+ offset += skb->csum_offset;
+ BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));
+
+ if (skb_cloned(skb) &&
+ !skb_clone_writable(skb, offset + sizeof(__sum16))) {
ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (ret)
goto out;
}
- offset = skb->csum_start - skb_headroom(skb);
- BUG_ON(offset > (int)skb->len);
- csum = skb_checksum(skb, offset, skb->len-offset, 0);
-
- offset = skb_headlen(skb) - offset;
- BUG_ON(offset <= 0);
- BUG_ON(skb->csum_offset + 2 > offset);
-
- *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) =
- csum_fold(csum);
+ *(__sum16 *)(skb->data + offset) = csum_fold(csum);
out_set_summed:
skb->ip_summed = CHECKSUM_NONE;
out:
@@ -1949,27 +1948,51 @@ static int ing_filter(struct sk_buff *skb)
struct Qdisc *q;
struct net_device *dev = skb->dev;
int result = TC_ACT_OK;
+ u32 ttl = G_TC_RTTL(skb->tc_verd);
- if (dev->qdisc_ingress) {
- __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
- if (MAX_RED_LOOP < ttl++) {
- printk(KERN_WARNING "Redir loop detected Dropping packet (%d->%d)\n",
- skb->iif, skb->dev->ifindex);
- return TC_ACT_SHOT;
- }
+ if (MAX_RED_LOOP < ttl++) {
+ printk(KERN_WARNING
+ "Redir loop detected Dropping packet (%d->%d)\n",
+ skb->iif, dev->ifindex);
+ return TC_ACT_SHOT;
+ }
+
+ skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl);
+ skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS);
- skb->tc_verd = SET_TC_RTTL(skb->tc_verd,ttl);
+ spin_lock(&dev->ingress_lock);
+ if ((q = dev->qdisc_ingress) != NULL)
+ result = q->enqueue(skb, q);
+ spin_unlock(&dev->ingress_lock);
- skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
+ return result;
+}
+
+static inline struct sk_buff *handle_ing(struct sk_buff *skb,
+ struct packet_type **pt_prev,
+ int *ret, struct net_device *orig_dev)
+{
+ if (!skb->dev->qdisc_ingress)
+ goto out;
- spin_lock(&dev->ingress_lock);
- if ((q = dev->qdisc_ingress) != NULL)
- result = q->enqueue(skb, q);
- spin_unlock(&dev->ingress_lock);
+ if (*pt_prev) {
+ *ret = deliver_skb(skb, *pt_prev, orig_dev);
+ *pt_prev = NULL;
+ } else {
+ /* Huh? Why does turning on AF_PACKET affect this? */
+ skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
+ }
+ switch (ing_filter(skb)) {
+ case TC_ACT_SHOT:
+ case TC_ACT_STOLEN:
+ kfree_skb(skb);
+ return NULL;
}
- return result;
+out:
+ skb->tc_verd = 0;
+ return skb;
}
#endif
@@ -2021,21 +2044,9 @@ int netif_receive_skb(struct sk_buff *skb)
}
#ifdef CONFIG_NET_CLS_ACT
- if (pt_prev) {
- ret = deliver_skb(skb, pt_prev, orig_dev);
- pt_prev = NULL; /* noone else should process this after*/
- } else {
- skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
- }
-
- ret = ing_filter(skb);
-
- if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) {
- kfree_skb(skb);
+ skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
+ if (!skb)
goto out;
- }
-
- skb->tc_verd = 0;
ncls:
#endif
diff --git a/net/core/filter.c b/net/core/filter.c
index bd903aaf7aa..1f0068eae50 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -387,6 +387,25 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
}
/**
+ * sk_filter_rcu_release: Release a socket filter by rcu_head
+ * @rcu: rcu_head that contains the sk_filter to free
+ */
+static void sk_filter_rcu_release(struct rcu_head *rcu)
+{
+ struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
+
+ sk_filter_release(fp);
+}
+
+static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
+{
+ unsigned int size = sk_filter_len(fp);
+
+ atomic_sub(size, &sk->sk_omem_alloc);
+ call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+}
+
+/**
* sk_attach_filter - attach a socket filter
* @fprog: the filter program
* @sk: the socket to use
@@ -398,7 +417,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
*/
int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
{
- struct sk_filter *fp;
+ struct sk_filter *fp, *old_fp;
unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
int err;
@@ -418,19 +437,34 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
fp->len = fprog->len;
err = sk_chk_filter(fp->insns, fp->len);
- if (!err) {
- struct sk_filter *old_fp;
-
- rcu_read_lock_bh();
- old_fp = rcu_dereference(sk->sk_filter);
- rcu_assign_pointer(sk->sk_filter, fp);
- rcu_read_unlock_bh();
- fp = old_fp;
+ if (err) {
+ sk_filter_uncharge(sk, fp);
+ return err;
}
- if (fp)
- sk_filter_release(sk, fp);
- return err;
+ rcu_read_lock_bh();
+ old_fp = rcu_dereference(sk->sk_filter);
+ rcu_assign_pointer(sk->sk_filter, fp);
+ rcu_read_unlock_bh();
+
+ sk_filter_delayed_uncharge(sk, old_fp);
+ return 0;
+}
+
+int sk_detach_filter(struct sock *sk)
+{
+ int ret = -ENOENT;
+ struct sk_filter *filter;
+
+ rcu_read_lock_bh();
+ filter = rcu_dereference(sk->sk_filter);
+ if (filter) {
+ rcu_assign_pointer(sk->sk_filter, NULL);
+ sk_filter_delayed_uncharge(sk, filter);
+ ret = 0;
+ }
+ rcu_read_unlock_bh();
+ return ret;
}
EXPORT_SYMBOL(sk_chk_filter);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index c52df858d0b..67ba9914e52 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -481,6 +481,8 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
if (!creat)
goto out;
+ ASSERT_RTNL();
+
n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL);
if (!n)
goto out;
@@ -2494,7 +2496,6 @@ static struct neigh_sysctl_table {
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = NET_NEIGH_RETRANS_TIME,
.procname = "retrans_time",
.maxlen = sizeof(int),
.mode = 0644,
@@ -2539,27 +2540,40 @@ static struct neigh_sysctl_table {
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = NET_NEIGH_ANYCAST_DELAY,
.procname = "anycast_delay",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_userhz_jiffies,
},
{
- .ctl_name = NET_NEIGH_PROXY_DELAY,
.procname = "proxy_delay",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_userhz_jiffies,
},
{
- .ctl_name = NET_NEIGH_LOCKTIME,
.procname = "locktime",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_userhz_jiffies,
},
{
+ .ctl_name = NET_NEIGH_RETRANS_TIME_MS,
+ .procname = "retrans_time_ms",
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_ms_jiffies,
+ .strategy = &sysctl_ms_jiffies,
+ },
+ {
+ .ctl_name = NET_NEIGH_REACHABLE_TIME_MS,
+ .procname = "base_reachable_time_ms",
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_ms_jiffies,
+ .strategy = &sysctl_ms_jiffies,
+ },
+ {
.ctl_name = NET_NEIGH_GC_INTERVAL,
.procname = "gc_interval",
.maxlen = sizeof(int),
@@ -2588,22 +2602,7 @@ static struct neigh_sysctl_table {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
- {
- .ctl_name = NET_NEIGH_RETRANS_TIME_MS,
- .procname = "retrans_time_ms",
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_ms_jiffies,
- .strategy = &sysctl_ms_jiffies,
- },
- {
- .ctl_name = NET_NEIGH_REACHABLE_TIME_MS,
- .procname = "base_reachable_time_ms",
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec_ms_jiffies,
- .strategy = &sysctl_ms_jiffies,
- },
+ {}
},
.neigh_dev = {
{
@@ -2656,42 +2655,48 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
t->neigh_vars[9].data = &p->anycast_delay;
t->neigh_vars[10].data = &p->proxy_delay;
t->neigh_vars[11].data = &p->locktime;
+ t->neigh_vars[12].data = &p->retrans_time;
+ t->neigh_vars[13].data = &p->base_reachable_time;
if (dev) {
dev_name_source = dev->name;
t->neigh_dev[0].ctl_name = dev->ifindex;
- t->neigh_vars[12].procname = NULL;
- t->neigh_vars[13].procname = NULL;
- t->neigh_vars[14].procname = NULL;
- t->neigh_vars[15].procname = NULL;
+ /* Terminate the table early */
+ memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14]));
} else {
dev_name_source = t->neigh_dev[0].procname;
- t->neigh_vars[12].data = (int *)(p + 1);
- t->neigh_vars[13].data = (int *)(p + 1) + 1;
- t->neigh_vars[14].data = (int *)(p + 1) + 2;
- t->neigh_vars[15].data = (int *)(p + 1) + 3;
+ t->neigh_vars[14].data = (int *)(p + 1);
+ t->neigh_vars[15].data = (int *)(p + 1) + 1;
+ t->neigh_vars[16].data = (int *)(p + 1) + 2;
+ t->neigh_vars[17].data = (int *)(p + 1) + 3;
}
- t->neigh_vars[16].data = &p->retrans_time;
- t->neigh_vars[17].data = &p->base_reachable_time;
if (handler || strategy) {
/* RetransTime */
t->neigh_vars[3].proc_handler = handler;
t->neigh_vars[3].strategy = strategy;
t->neigh_vars[3].extra1 = dev;
+ if (!strategy)
+ t->neigh_vars[3].ctl_name = CTL_UNNUMBERED;
/* ReachableTime */
t->neigh_vars[4].proc_handler = handler;
t->neigh_vars[4].strategy = strategy;
t->neigh_vars[4].extra1 = dev;
+ if (!strategy)
+ t->neigh_vars[4].ctl_name = CTL_UNNUMBERED;
/* RetransTime (in milliseconds)*/
- t->neigh_vars[16].proc_handler = handler;
- t->neigh_vars[16].strategy = strategy;
- t->neigh_vars[16].extra1 = dev;
+ t->neigh_vars[12].proc_handler = handler;
+ t->neigh_vars[12].strategy = strategy;
+ t->neigh_vars[12].extra1 = dev;
+ if (!strategy)
+ t->neigh_vars[12].ctl_name = CTL_UNNUMBERED;
/* ReachableTime (in milliseconds) */
- t->neigh_vars[17].proc_handler = handler;
- t->neigh_vars[17].strategy = strategy;
- t->neigh_vars[17].extra1 = dev;
+ t->neigh_vars[13].proc_handler = handler;
+ t->neigh_vars[13].strategy = strategy;
+ t->neigh_vars[13].extra1 = dev;
+ if (!strategy)
+ t->neigh_vars[13].ctl_name = CTL_UNNUMBERED;
}
dev_name = kstrdup(dev_name_source, GFP_KERNEL);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 2100c734b10..8cae60c5338 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2454,7 +2454,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
spin_lock(&x->lock);
iph = ip_hdr(skb);
- err = x->mode->output(x, skb);
+ err = x->outer_mode->output(x, skb);
if (err)
goto error;
err = x->type->output(x, skb);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 944189d9632..70d9b5da96a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -362,6 +362,97 @@ void kfree_skb(struct sk_buff *skb)
__kfree_skb(skb);
}
+static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
+{
+ new->tstamp = old->tstamp;
+ new->dev = old->dev;
+ new->transport_header = old->transport_header;
+ new->network_header = old->network_header;
+ new->mac_header = old->mac_header;
+ new->dst = dst_clone(old->dst);
+#ifdef CONFIG_INET
+ new->sp = secpath_get(old->sp);
+#endif
+ memcpy(new->cb, old->cb, sizeof(old->cb));
+ new->csum_start = old->csum_start;
+ new->csum_offset = old->csum_offset;
+ new->local_df = old->local_df;
+ new->pkt_type = old->pkt_type;
+ new->ip_summed = old->ip_summed;
+ skb_copy_queue_mapping(new, old);
+ new->priority = old->priority;
+#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
+ new->ipvs_property = old->ipvs_property;
+#endif
+ new->protocol = old->protocol;
+ new->mark = old->mark;
+ __nf_copy(new, old);
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+ defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+ new->nf_trace = old->nf_trace;
+#endif
+#ifdef CONFIG_NET_SCHED
+ new->tc_index = old->tc_index;
+#ifdef CONFIG_NET_CLS_ACT
+ new->tc_verd = old->tc_verd;
+#endif
+#endif
+ skb_copy_secmark(new, old);
+}
+
+static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
+{
+#define C(x) n->x = skb->x
+
+ n->next = n->prev = NULL;
+ n->sk = NULL;
+ __copy_skb_header(n, skb);
+
+ C(len);
+ C(data_len);
+ C(mac_len);
+ n->cloned = 1;
+ n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
+ n->nohdr = 0;
+ n->destructor = NULL;
+#ifdef CONFIG_NET_CLS_ACT
+ /* FIXME What is this and why don't we do it in copy_skb_header? */
+ n->tc_verd = SET_TC_VERD(n->tc_verd,0);
+ n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
+ n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
+ C(iif);
+#endif
+ C(truesize);
+ atomic_set(&n->users, 1);
+ C(head);
+ C(data);
+ C(tail);
+ C(end);
+
+ atomic_inc(&(skb_shinfo(skb)->dataref));
+ skb->cloned = 1;
+
+ return n;
+#undef C
+}
+
+/**
+ * skb_morph - morph one skb into another
+ * @dst: the skb to receive the contents
+ * @src: the skb to supply the contents
+ *
+ * This is identical to skb_clone except that the target skb is
+ * supplied by the user.
+ *
+ * The target skb is returned upon exit.
+ */
+struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)
+{
+ skb_release_data(dst);
+ return __skb_clone(dst, src);
+}
+EXPORT_SYMBOL_GPL(skb_morph);
+
/**
* skb_clone - duplicate an sk_buff
* @skb: buffer to clone
@@ -393,66 +484,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
n->fclone = SKB_FCLONE_UNAVAILABLE;
}
-#define C(x) n->x = skb->x
-
- n->next = n->prev = NULL;
- n->sk = NULL;
- C(tstamp);
- C(dev);
- C(transport_header);
- C(network_header);
- C(mac_header);
- C(dst);
- dst_clone(skb->dst);
- C(sp);
-#ifdef CONFIG_INET
- secpath_get(skb->sp);
-#endif
- memcpy(n->cb, skb->cb, sizeof(skb->cb));
- C(len);
- C(data_len);
- C(mac_len);
- C(csum);
- C(local_df);
- n->cloned = 1;
- n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
- n->nohdr = 0;
- C(pkt_type);
- C(ip_summed);
- skb_copy_queue_mapping(n, skb);
- C(priority);
-#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
- C(ipvs_property);
-#endif
- C(protocol);
- n->destructor = NULL;
- C(mark);
- __nf_copy(n, skb);
-#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
- defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
- C(nf_trace);
-#endif
-#ifdef CONFIG_NET_SCHED
- C(tc_index);
-#ifdef CONFIG_NET_CLS_ACT
- n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
- n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
- n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
- C(iif);
-#endif
-#endif
- skb_copy_secmark(n, skb);
- C(truesize);
- atomic_set(&n->users, 1);
- C(head);
- C(data);
- C(tail);
- C(end);
-
- atomic_inc(&(skb_shinfo(skb)->dataref));
- skb->cloned = 1;
-
- return n;
+ return __skb_clone(n, skb);
}
static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
@@ -463,50 +495,15 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
*/
unsigned long offset = new->data - old->data;
#endif
- new->sk = NULL;
- new->dev = old->dev;
- skb_copy_queue_mapping(new, old);
- new->priority = old->priority;
- new->protocol = old->protocol;
- new->dst = dst_clone(old->dst);
-#ifdef CONFIG_INET
- new->sp = secpath_get(old->sp);
-#endif
- new->csum_start = old->csum_start;
- new->csum_offset = old->csum_offset;
- new->ip_summed = old->ip_summed;
- new->transport_header = old->transport_header;
- new->network_header = old->network_header;
- new->mac_header = old->mac_header;
+
+ __copy_skb_header(new, old);
+
#ifndef NET_SKBUFF_DATA_USES_OFFSET
/* {transport,network,mac}_header are relative to skb->head */
new->transport_header += offset;
new->network_header += offset;
new->mac_header += offset;
#endif
- memcpy(new->cb, old->cb, sizeof(old->cb));
- new->local_df = old->local_df;
- new->fclone = SKB_FCLONE_UNAVAILABLE;
- new->pkt_type = old->pkt_type;
- new->tstamp = old->tstamp;
- new->destructor = NULL;
- new->mark = old->mark;
- __nf_copy(new, old);
-#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
- defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
- new->nf_trace = old->nf_trace;
-#endif
-#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
- new->ipvs_property = old->ipvs_property;
-#endif
-#ifdef CONFIG_NET_SCHED
-#ifdef CONFIG_NET_CLS_ACT
- new->tc_verd = old->tc_verd;
-#endif
- new->tc_index = old->tc_index;
-#endif
- skb_copy_secmark(new, old);
- atomic_set(&new->users, 1);
skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
@@ -685,7 +682,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
skb->transport_header += off;
skb->network_header += off;
skb->mac_header += off;
- skb->csum_start += off;
+ skb->csum_start += nhead;
skb->cloned = 0;
skb->hdr_len = 0;
skb->nohdr = 0;
diff --git a/net/core/sock.c b/net/core/sock.c
index d45ecdccc6a..d292b4113d6 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -428,7 +428,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
{
struct sock *sk=sock->sk;
- struct sk_filter *filter;
int val;
int valbool;
struct linger ling;
@@ -652,16 +651,7 @@ set_rcvbuf:
break;
case SO_DETACH_FILTER:
- rcu_read_lock_bh();
- filter = rcu_dereference(sk->sk_filter);
- if (filter) {
- rcu_assign_pointer(sk->sk_filter, NULL);
- sk_filter_release(sk, filter);
- rcu_read_unlock_bh();
- break;
- }
- rcu_read_unlock_bh();
- ret = -ENONET;
+ ret = sk_detach_filter(sk);
break;
case SO_PASSSEC:
@@ -925,7 +915,7 @@ void sk_free(struct sock *sk)
filter = rcu_dereference(sk->sk_filter);
if (filter) {
- sk_filter_release(sk, filter);
+ sk_filter_uncharge(sk, filter);
rcu_assign_pointer(sk->sk_filter, NULL);
}
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 19d7e1dbd87..3560a2a875a 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -19,6 +19,9 @@
#include "ccid.h"
#include "dccp.h"
+/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
+int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
+
static void dccp_fin(struct sock *sk, struct sk_buff *skb)
{
sk->sk_shutdown |= RCV_SHUTDOWN;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 006a3834fbc..cac53548c2d 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -767,10 +767,9 @@ discard:
return 0;
}
-static int dccp_v6_rcv(struct sk_buff **pskb)
+static int dccp_v6_rcv(struct sk_buff *skb)
{
const struct dccp_hdr *dh;
- struct sk_buff *skb = *pskb;
struct sock *sk;
int min_cov;
diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c
index 9364b2fb4db..c62c05039f6 100644
--- a/net/dccp/sysctl.c
+++ b/net/dccp/sysctl.c
@@ -18,9 +18,6 @@
#error This file should not be compiled without CONFIG_SYSCTL defined
#endif
-/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
-int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
-
static struct ctl_table dccp_default_table[] = {
{
.procname = "seq_window",
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index f7fba7721e6..43fcd29046d 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -88,12 +88,12 @@ static void dnrmg_send_peer(struct sk_buff *skb)
static unsigned int dnrmg_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- dnrmg_send_peer(*pskb);
+ dnrmg_send_peer(skb);
return NF_ACCEPT;
}
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 6cc54eeca3e..72e6ab66834 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -586,7 +586,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
if (stype & IEEE80211_STYPE_QOS_DATA) {
const struct ieee80211_hdr_3addrqos *qoshdr =
(struct ieee80211_hdr_3addrqos *)skb->data;
- hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
+ hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
} else
hdr[12] = 0; /* priority */
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index a02c36d0a13..93fe3966805 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -10,7 +10,8 @@ obj-y := route.o inetpeer.o protocol.o \
tcp_minisocks.o tcp_cong.o \
datagram.o raw.o udp.o udplite.o \
arp.o icmp.o devinet.o af_inet.o igmp.o \
- sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
+ sysctl_net_ipv4.o fib_frontend.o fib_semantics.o \
+ inet_fragment.o
obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
new file mode 100644
index 00000000000..e15e04fc666
--- /dev/null
+++ b/net/ipv4/inet_fragment.c
@@ -0,0 +1,261 @@
+/*
+ * inet fragments management
+ *
+ * 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.
+ *
+ * Authors: Pavel Emelyanov <xemul@openvz.org>
+ * Started as consolidation of ipv4/ip_fragment.c,
+ * ipv6/reassembly. and ipv6 nf conntrack reassembly
+ */
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+
+#include <net/inet_frag.h>
+
+static void inet_frag_secret_rebuild(unsigned long dummy)
+{
+ struct inet_frags *f = (struct inet_frags *)dummy;
+ unsigned long now = jiffies;
+ int i;
+
+ write_lock(&f->lock);
+ get_random_bytes(&f->rnd, sizeof(u32));
+ for (i = 0; i < INETFRAGS_HASHSZ; i++) {
+ struct inet_frag_queue *q;
+ struct hlist_node *p, *n;
+
+ hlist_for_each_entry_safe(q, p, n, &f->hash[i], list) {
+ unsigned int hval = f->hashfn(q);
+
+ if (hval != i) {
+ hlist_del(&q->list);
+
+ /* Relink to new hash chain. */
+ hlist_add_head(&q->list, &f->hash[hval]);
+ }
+ }
+ }
+ write_unlock(&f->lock);
+
+ mod_timer(&f->secret_timer, now + f->ctl->secret_interval);
+}
+
+void inet_frags_init(struct inet_frags *f)
+{
+ int i;
+
+ for (i = 0; i < INETFRAGS_HASHSZ; i++)
+ INIT_HLIST_HEAD(&f->hash[i]);
+
+ INIT_LIST_HEAD(&f->lru_list);
+ rwlock_init(&f->lock);
+
+ f->rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
+ (jiffies ^ (jiffies >> 6)));
+
+ f->nqueues = 0;
+ atomic_set(&f->mem, 0);
+
+ init_timer(&f->secret_timer);
+ f->secret_timer.function = inet_frag_secret_rebuild;
+ f->secret_timer.data = (unsigned long)f;
+ f->secret_timer.expires = jiffies + f->ctl->secret_interval;
+ add_timer(&f->secret_timer);
+}
+EXPORT_SYMBOL(inet_frags_init);
+
+void inet_frags_fini(struct inet_frags *f)
+{
+ del_timer(&f->secret_timer);
+}
+EXPORT_SYMBOL(inet_frags_fini);
+
+static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
+{
+ write_lock(&f->lock);
+ hlist_del(&fq->list);
+ list_del(&fq->lru_list);
+ f->nqueues--;
+ write_unlock(&f->lock);
+}
+
+void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
+{
+ if (del_timer(&fq->timer))
+ atomic_dec(&fq->refcnt);
+
+ if (!(fq->last_in & COMPLETE)) {
+ fq_unlink(fq, f);
+ atomic_dec(&fq->refcnt);
+ fq->last_in |= COMPLETE;
+ }
+}
+
+EXPORT_SYMBOL(inet_frag_kill);
+
+static inline void frag_kfree_skb(struct inet_frags *f, struct sk_buff *skb,
+ int *work)
+{
+ if (work)
+ *work -= skb->truesize;
+
+ atomic_sub(skb->truesize, &f->mem);
+ if (f->skb_free)
+ f->skb_free(skb);
+ kfree_skb(skb);
+}
+
+void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
+ int *work)
+{
+ struct sk_buff *fp;
+
+ BUG_TRAP(q->last_in & COMPLETE);
+ BUG_TRAP(del_timer(&q->timer) == 0);
+
+ /* Release all fragment data. */
+ fp = q->fragments;
+ while (fp) {
+ struct sk_buff *xp = fp->next;
+
+ frag_kfree_skb(f, fp, work);
+ fp = xp;
+ }
+
+ if (work)
+ *work -= f->qsize;
+ atomic_sub(f->qsize, &f->mem);
+
+ if (f->destructor)
+ f->destructor(q);
+ kfree(q);
+
+}
+EXPORT_SYMBOL(inet_frag_destroy);
+
+int inet_frag_evictor(struct inet_frags *f)
+{
+ struct inet_frag_queue *q;
+ int work, evicted = 0;
+
+ work = atomic_read(&f->mem) - f->ctl->low_thresh;
+ while (work > 0) {
+ read_lock(&f->lock);
+ if (list_empty(&f->lru_list)) {
+ read_unlock(&f->lock);
+ break;
+ }
+
+ q = list_first_entry(&f->lru_list,
+ struct inet_frag_queue, lru_list);
+ atomic_inc(&q->refcnt);
+ read_unlock(&f->lock);
+
+ spin_lock(&q->lock);
+ if (!(q->last_in & COMPLETE))
+ inet_frag_kill(q, f);
+ spin_unlock(&q->lock);
+
+ if (atomic_dec_and_test(&q->refcnt))
+ inet_frag_destroy(q, f, &work);
+ evicted++;
+ }
+
+ return evicted;
+}
+EXPORT_SYMBOL(inet_frag_evictor);
+
+static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
+ struct inet_frags *f, unsigned int hash, void *arg)
+{
+ struct inet_frag_queue *qp;
+#ifdef CONFIG_SMP
+ struct hlist_node *n;
+#endif
+
+ write_lock(&f->lock);
+#ifdef CONFIG_SMP
+ /* With SMP race we have to recheck hash table, because
+ * such entry could be created on other cpu, while we
+ * promoted read lock to write lock.
+ */
+ hlist_for_each_entry(qp, n, &f->hash[hash], list) {
+ if (f->match(qp, arg)) {
+ atomic_inc(&qp->refcnt);
+ write_unlock(&f->lock);
+ qp_in->last_in |= COMPLETE;
+ inet_frag_put(qp_in, f);
+ return qp;
+ }
+ }
+#endif
+ qp = qp_in;
+ if (!mod_timer(&qp->timer, jiffies + f->ctl->timeout))
+ atomic_inc(&qp->refcnt);
+
+ atomic_inc(&qp->refcnt);
+ hlist_add_head(&qp->list, &f->hash[hash]);
+ list_add_tail(&qp->lru_list, &f->lru_list);
+ f->nqueues++;
+ write_unlock(&f->lock);
+ return qp;
+}
+
+static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
+{
+ struct inet_frag_queue *q;
+
+ q = kzalloc(f->qsize, GFP_ATOMIC);
+ if (q == NULL)
+ return NULL;
+
+ f->constructor(q, arg);
+ atomic_add(f->qsize, &f->mem);
+ setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
+ spin_lock_init(&q->lock);
+ atomic_set(&q->refcnt, 1);
+
+ return q;
+}
+
+static struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
+ void *arg, unsigned int hash)
+{
+ struct inet_frag_queue *q;
+
+ q = inet_frag_alloc(f, arg);
+ if (q == NULL)
+ return NULL;
+
+ return inet_frag_intern(q, f, hash, arg);
+}
+
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+ unsigned int hash)
+{
+ struct inet_frag_queue *q;
+ struct hlist_node *n;
+
+ read_lock(&f->lock);
+ hlist_for_each_entry(q, n, &f->hash[hash], list) {
+ if (f->match(q, key)) {
+ atomic_inc(&q->refcnt);
+ read_unlock(&f->lock);
+ return q;
+ }
+ }
+ read_unlock(&f->lock);
+
+ return inet_frag_create(f, key, hash);
+}
+EXPORT_SYMBOL(inet_frag_find);
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index afbf938836f..877da3ed52e 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -40,7 +40,7 @@
#include <net/route.h>
#include <net/xfrm.h>
-static inline int ip_forward_finish(struct sk_buff *skb)
+static int ip_forward_finish(struct sk_buff *skb)
{
struct ip_options * opt = &(IPCB(skb)->opt);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index fabb86db763..2143bf30597 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -39,6 +39,7 @@
#include <net/icmp.h>
#include <net/checksum.h>
#include <net/inetpeer.h>
+#include <net/inet_frag.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/inet.h>
@@ -49,21 +50,8 @@
* as well. Or notify me, at least. --ANK
*/
-/* Fragment cache limits. We will commit 256K at one time. Should we
- * cross that limit we will prune down to 192K. This should cope with
- * even the most extreme cases without allowing an attacker to measurably
- * harm machine performance.
- */
-int sysctl_ipfrag_high_thresh __read_mostly = 256*1024;
-int sysctl_ipfrag_low_thresh __read_mostly = 192*1024;
-
int sysctl_ipfrag_max_dist __read_mostly = 64;
-/* Important NOTE! Fragment queue must be destroyed before MSL expires.
- * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
- */
-int sysctl_ipfrag_time __read_mostly = IP_FRAG_TIME;
-
struct ipfrag_skb_cb
{
struct inet_skb_parm h;
@@ -74,153 +62,123 @@ struct ipfrag_skb_cb
/* Describe an entry in the "incomplete datagrams" queue. */
struct ipq {
- struct hlist_node list;
- struct list_head lru_list; /* lru list member */
+ struct inet_frag_queue q;
+
u32 user;
__be32 saddr;
__be32 daddr;
__be16 id;
u8 protocol;
- u8 last_in;
-#define COMPLETE 4
-#define FIRST_IN 2
-#define LAST_IN 1
-
- struct sk_buff *fragments; /* linked list of received fragments */
- int len; /* total length of original datagram */
- int meat;
- spinlock_t lock;
- atomic_t refcnt;
- struct timer_list timer; /* when will this queue expire? */
- ktime_t stamp;
int iif;
unsigned int rid;
struct inet_peer *peer;
};
-/* Hash table. */
+struct inet_frags_ctl ip4_frags_ctl __read_mostly = {
+ /*
+ * Fragment cache limits. We will commit 256K at one time. Should we
+ * cross that limit we will prune down to 192K. This should cope with
+ * even the most extreme cases without allowing an attacker to
+ * measurably harm machine performance.
+ */
+ .high_thresh = 256 * 1024,
+ .low_thresh = 192 * 1024,
-#define IPQ_HASHSZ 64
+ /*
+ * Important NOTE! Fragment queue must be destroyed before MSL expires.
+ * RFC791 is wrong proposing to prolongate timer each fragment arrival
+ * by TTL.
+ */
+ .timeout = IP_FRAG_TIME,
+ .secret_interval = 10 * 60 * HZ,
+};
-/* Per-bucket lock is easy to add now. */
-static struct hlist_head ipq_hash[IPQ_HASHSZ];
-static DEFINE_RWLOCK(ipfrag_lock);
-static u32 ipfrag_hash_rnd;
-static LIST_HEAD(ipq_lru_list);
-int ip_frag_nqueues = 0;
+static struct inet_frags ip4_frags;
-static __inline__ void __ipq_unlink(struct ipq *qp)
+int ip_frag_nqueues(void)
{
- hlist_del(&qp->list);
- list_del(&qp->lru_list);
- ip_frag_nqueues--;
+ return ip4_frags.nqueues;
}
-static __inline__ void ipq_unlink(struct ipq *ipq)
+int ip_frag_mem(void)
{
- write_lock(&ipfrag_lock);
- __ipq_unlink(ipq);
- write_unlock(&ipfrag_lock);
+ return atomic_read(&ip4_frags.mem);
}
+static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
+ struct net_device *dev);
+
+struct ip4_create_arg {
+ struct iphdr *iph;
+ u32 user;
+};
+
static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
{
return jhash_3words((__force u32)id << 16 | prot,
(__force u32)saddr, (__force u32)daddr,
- ipfrag_hash_rnd) & (IPQ_HASHSZ - 1);
+ ip4_frags.rnd) & (INETFRAGS_HASHSZ - 1);
}
-static struct timer_list ipfrag_secret_timer;
-int sysctl_ipfrag_secret_interval __read_mostly = 10 * 60 * HZ;
-
-static void ipfrag_secret_rebuild(unsigned long dummy)
+static unsigned int ip4_hashfn(struct inet_frag_queue *q)
{
- unsigned long now = jiffies;
- int i;
+ struct ipq *ipq;
- write_lock(&ipfrag_lock);
- get_random_bytes(&ipfrag_hash_rnd, sizeof(u32));
- for (i = 0; i < IPQ_HASHSZ; i++) {
- struct ipq *q;
- struct hlist_node *p, *n;
-
- hlist_for_each_entry_safe(q, p, n, &ipq_hash[i], list) {
- unsigned int hval = ipqhashfn(q->id, q->saddr,
- q->daddr, q->protocol);
-
- if (hval != i) {
- hlist_del(&q->list);
-
- /* Relink to new hash chain. */
- hlist_add_head(&q->list, &ipq_hash[hval]);
- }
- }
- }
- write_unlock(&ipfrag_lock);
-
- mod_timer(&ipfrag_secret_timer, now + sysctl_ipfrag_secret_interval);
+ ipq = container_of(q, struct ipq, q);
+ return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
}
-atomic_t ip_frag_mem = ATOMIC_INIT(0); /* Memory used for fragments */
+static int ip4_frag_match(struct inet_frag_queue *q, void *a)
+{
+ struct ipq *qp;
+ struct ip4_create_arg *arg = a;
+
+ qp = container_of(q, struct ipq, q);
+ return (qp->id == arg->iph->id &&
+ qp->saddr == arg->iph->saddr &&
+ qp->daddr == arg->iph->daddr &&
+ qp->protocol == arg->iph->protocol &&
+ qp->user == arg->user);
+}
/* Memory Tracking Functions. */
static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
{
if (work)
*work -= skb->truesize;
- atomic_sub(skb->truesize, &ip_frag_mem);
+ atomic_sub(skb->truesize, &ip4_frags.mem);
kfree_skb(skb);
}
-static __inline__ void frag_free_queue(struct ipq *qp, int *work)
+static void ip4_frag_init(struct inet_frag_queue *q, void *a)
{
- if (work)
- *work -= sizeof(struct ipq);
- atomic_sub(sizeof(struct ipq), &ip_frag_mem);
- kfree(qp);
+ struct ipq *qp = container_of(q, struct ipq, q);
+ struct ip4_create_arg *arg = a;
+
+ qp->protocol = arg->iph->protocol;
+ qp->id = arg->iph->id;
+ qp->saddr = arg->iph->saddr;
+ qp->daddr = arg->iph->daddr;
+ qp->user = arg->user;
+ qp->peer = sysctl_ipfrag_max_dist ?
+ inet_getpeer(arg->iph->saddr, 1) : NULL;
}
-static __inline__ struct ipq *frag_alloc_queue(void)
+static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
{
- struct ipq *qp = kmalloc(sizeof(struct ipq), GFP_ATOMIC);
-
- if (!qp)
- return NULL;
- atomic_add(sizeof(struct ipq), &ip_frag_mem);
- return qp;
-}
-
-
-/* Destruction primitives. */
-
-/* Complete destruction of ipq. */
-static void ip_frag_destroy(struct ipq *qp, int *work)
-{
- struct sk_buff *fp;
-
- BUG_TRAP(qp->last_in&COMPLETE);
- BUG_TRAP(del_timer(&qp->timer) == 0);
+ struct ipq *qp;
+ qp = container_of(q, struct ipq, q);
if (qp->peer)
inet_putpeer(qp->peer);
+}
- /* Release all fragment data. */
- fp = qp->fragments;
- while (fp) {
- struct sk_buff *xp = fp->next;
-
- frag_kfree_skb(fp, work);
- fp = xp;
- }
- /* Finally, release the queue descriptor itself. */
- frag_free_queue(qp, work);
-}
+/* Destruction primitives. */
-static __inline__ void ipq_put(struct ipq *ipq, int *work)
+static __inline__ void ipq_put(struct ipq *ipq)
{
- if (atomic_dec_and_test(&ipq->refcnt))
- ip_frag_destroy(ipq, work);
+ inet_frag_put(&ipq->q, &ip4_frags);
}
/* Kill ipq entry. It is not destroyed immediately,
@@ -228,14 +186,7 @@ static __inline__ void ipq_put(struct ipq *ipq, int *work)
*/
static void ipq_kill(struct ipq *ipq)
{
- if (del_timer(&ipq->timer))
- atomic_dec(&ipq->refcnt);
-
- if (!(ipq->last_in & COMPLETE)) {
- ipq_unlink(ipq);
- atomic_dec(&ipq->refcnt);
- ipq->last_in |= COMPLETE;
- }
+ inet_frag_kill(&ipq->q, &ip4_frags);
}
/* Memory limiting on fragments. Evictor trashes the oldest
@@ -243,33 +194,11 @@ static void ipq_kill(struct ipq *ipq)
*/
static void ip_evictor(void)
{
- struct ipq *qp;
- struct list_head *tmp;
- int work;
-
- work = atomic_read(&ip_frag_mem) - sysctl_ipfrag_low_thresh;
- if (work <= 0)
- return;
-
- while (work > 0) {
- read_lock(&ipfrag_lock);
- if (list_empty(&ipq_lru_list)) {
- read_unlock(&ipfrag_lock);
- return;
- }
- tmp = ipq_lru_list.next;
- qp = list_entry(tmp, struct ipq, lru_list);
- atomic_inc(&qp->refcnt);
- read_unlock(&ipfrag_lock);
-
- spin_lock(&qp->lock);
- if (!(qp->last_in&COMPLETE))
- ipq_kill(qp);
- spin_unlock(&qp->lock);
+ int evicted;
- ipq_put(qp, &work);
- IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
- }
+ evicted = inet_frag_evictor(&ip4_frags);
+ if (evicted)
+ IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted);
}
/*
@@ -277,11 +206,13 @@ static void ip_evictor(void)
*/
static void ip_expire(unsigned long arg)
{
- struct ipq *qp = (struct ipq *) arg;
+ struct ipq *qp;
+
+ qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
- spin_lock(&qp->lock);
+ spin_lock(&qp->q.lock);
- if (qp->last_in & COMPLETE)
+ if (qp->q.last_in & COMPLETE)
goto out;
ipq_kill(qp);
@@ -289,8 +220,8 @@ static void ip_expire(unsigned long arg)
IP_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT);
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
- if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
- struct sk_buff *head = qp->fragments;
+ if ((qp->q.last_in&FIRST_IN) && qp->q.fragments != NULL) {
+ struct sk_buff *head = qp->q.fragments;
/* Send an ICMP "Fragment Reassembly Timeout" message. */
if ((head->dev = dev_get_by_index(&init_net, qp->iif)) != NULL) {
icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
@@ -298,121 +229,34 @@ static void ip_expire(unsigned long arg)
}
}
out:
- spin_unlock(&qp->lock);
- ipq_put(qp, NULL);
+ spin_unlock(&qp->q.lock);
+ ipq_put(qp);
}
-/* Creation primitives. */
-
-static struct ipq *ip_frag_intern(struct ipq *qp_in)
+/* Find the correct entry in the "incomplete datagrams" queue for
+ * this IP datagram, and create new one, if nothing is found.
+ */
+static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
{
- struct ipq *qp;
-#ifdef CONFIG_SMP
- struct hlist_node *n;
-#endif
+ struct inet_frag_queue *q;
+ struct ip4_create_arg arg;
unsigned int hash;
- write_lock(&ipfrag_lock);
- hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr,
- qp_in->protocol);
-#ifdef CONFIG_SMP
- /* With SMP race we have to recheck hash table, because
- * such entry could be created on other cpu, while we
- * promoted read lock to write lock.
- */
- hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
- if (qp->id == qp_in->id &&
- qp->saddr == qp_in->saddr &&
- qp->daddr == qp_in->daddr &&
- qp->protocol == qp_in->protocol &&
- qp->user == qp_in->user) {
- atomic_inc(&qp->refcnt);
- write_unlock(&ipfrag_lock);
- qp_in->last_in |= COMPLETE;
- ipq_put(qp_in, NULL);
- return qp;
- }
- }
-#endif
- qp = qp_in;
-
- if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time))
- atomic_inc(&qp->refcnt);
-
- atomic_inc(&qp->refcnt);
- hlist_add_head(&qp->list, &ipq_hash[hash]);
- INIT_LIST_HEAD(&qp->lru_list);
- list_add_tail(&qp->lru_list, &ipq_lru_list);
- ip_frag_nqueues++;
- write_unlock(&ipfrag_lock);
- return qp;
-}
-
-/* Add an entry to the 'ipq' queue for a newly received IP datagram. */
-static struct ipq *ip_frag_create(struct iphdr *iph, u32 user)
-{
- struct ipq *qp;
+ arg.iph = iph;
+ arg.user = user;
+ hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
- if ((qp = frag_alloc_queue()) == NULL)
+ q = inet_frag_find(&ip4_frags, &arg, hash);
+ if (q == NULL)
goto out_nomem;
- qp->protocol = iph->protocol;
- qp->last_in = 0;
- qp->id = iph->id;
- qp->saddr = iph->saddr;
- qp->daddr = iph->daddr;
- qp->user = user;
- qp->len = 0;
- qp->meat = 0;
- qp->fragments = NULL;
- qp->iif = 0;
- qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
-
- /* Initialize a timer for this entry. */
- init_timer(&qp->timer);
- qp->timer.data = (unsigned long) qp; /* pointer to queue */
- qp->timer.function = ip_expire; /* expire function */
- spin_lock_init(&qp->lock);
- atomic_set(&qp->refcnt, 1);
-
- return ip_frag_intern(qp);
+ return container_of(q, struct ipq, q);
out_nomem:
LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
return NULL;
}
-/* Find the correct entry in the "incomplete datagrams" queue for
- * this IP datagram, and create new one, if nothing is found.
- */
-static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
-{
- __be16 id = iph->id;
- __be32 saddr = iph->saddr;
- __be32 daddr = iph->daddr;
- __u8 protocol = iph->protocol;
- unsigned int hash;
- struct ipq *qp;
- struct hlist_node *n;
-
- read_lock(&ipfrag_lock);
- hash = ipqhashfn(id, saddr, daddr, protocol);
- hlist_for_each_entry(qp, n, &ipq_hash[hash], list) {
- if (qp->id == id &&
- qp->saddr == saddr &&
- qp->daddr == daddr &&
- qp->protocol == protocol &&
- qp->user == user) {
- atomic_inc(&qp->refcnt);
- read_unlock(&ipfrag_lock);
- return qp;
- }
- }
- read_unlock(&ipfrag_lock);
-
- return ip_frag_create(iph, user);
-}
-
/* Is the fragment too far ahead to be part of ipq? */
static inline int ip_frag_too_far(struct ipq *qp)
{
@@ -429,7 +273,7 @@ static inline int ip_frag_too_far(struct ipq *qp)
end = atomic_inc_return(&peer->rid);
qp->rid = end;
- rc = qp->fragments && (end - start) > max;
+ rc = qp->q.fragments && (end - start) > max;
if (rc) {
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
@@ -442,39 +286,42 @@ static int ip_frag_reinit(struct ipq *qp)
{
struct sk_buff *fp;
- if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
- atomic_inc(&qp->refcnt);
+ if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout)) {
+ atomic_inc(&qp->q.refcnt);
return -ETIMEDOUT;
}
- fp = qp->fragments;
+ fp = qp->q.fragments;
do {
struct sk_buff *xp = fp->next;
frag_kfree_skb(fp, NULL);
fp = xp;
} while (fp);
- qp->last_in = 0;
- qp->len = 0;
- qp->meat = 0;
- qp->fragments = NULL;
+ qp->q.last_in = 0;
+ qp->q.len = 0;
+ qp->q.meat = 0;
+ qp->q.fragments = NULL;
qp->iif = 0;
return 0;
}
/* Add new segment to existing queue. */
-static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
+static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
{
struct sk_buff *prev, *next;
+ struct net_device *dev;
int flags, offset;
int ihl, end;
+ int err = -ENOENT;
- if (qp->last_in & COMPLETE)
+ if (qp->q.last_in & COMPLETE)
goto err;
if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
- unlikely(ip_frag_too_far(qp)) && unlikely(ip_frag_reinit(qp))) {
+ unlikely(ip_frag_too_far(qp)) &&
+ unlikely(err = ip_frag_reinit(qp))) {
ipq_kill(qp);
goto err;
}
@@ -487,36 +334,40 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
/* Determine the position of this fragment. */
end = offset + skb->len - ihl;
+ err = -EINVAL;
/* Is this the final fragment? */
if ((flags & IP_MF) == 0) {
/* If we already have some bits beyond end
* or have different end, the segment is corrrupted.
*/
- if (end < qp->len ||
- ((qp->last_in & LAST_IN) && end != qp->len))
+ if (end < qp->q.len ||
+ ((qp->q.last_in & LAST_IN) && end != qp->q.len))
goto err;
- qp->last_in |= LAST_IN;
- qp->len = end;
+ qp->q.last_in |= LAST_IN;
+ qp->q.len = end;
} else {
if (end&7) {
end &= ~7;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
- if (end > qp->len) {
+ if (end > qp->q.len) {
/* Some bits beyond end -> corruption. */
- if (qp->last_in & LAST_IN)
+ if (qp->q.last_in & LAST_IN)
goto err;
- qp->len = end;
+ qp->q.len = end;
}
}
if (end == offset)
goto err;
+ err = -ENOMEM;
if (pskb_pull(skb, ihl) == NULL)
goto err;
- if (pskb_trim_rcsum(skb, end-offset))
+
+ err = pskb_trim_rcsum(skb, end - offset);
+ if (err)
goto err;
/* Find out which fragments are in front and at the back of us
@@ -524,7 +375,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
* this fragment, right?
*/
prev = NULL;
- for (next = qp->fragments; next != NULL; next = next->next) {
+ for (next = qp->q.fragments; next != NULL; next = next->next) {
if (FRAG_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
@@ -539,8 +390,10 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
if (i > 0) {
offset += i;
+ err = -EINVAL;
if (end <= offset)
goto err;
+ err = -ENOMEM;
if (!pskb_pull(skb, i))
goto err;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
@@ -548,6 +401,8 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
}
}
+ err = -ENOMEM;
+
while (next && FRAG_CB(next)->offset < end) {
int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */
@@ -558,7 +413,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
if (!pskb_pull(next, i))
goto err;
FRAG_CB(next)->offset += i;
- qp->meat -= i;
+ qp->q.meat -= i;
if (next->ip_summed != CHECKSUM_UNNECESSARY)
next->ip_summed = CHECKSUM_NONE;
break;
@@ -573,9 +428,9 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
if (prev)
prev->next = next;
else
- qp->fragments = next;
+ qp->q.fragments = next;
- qp->meat -= free_it->len;
+ qp->q.meat -= free_it->len;
frag_kfree_skb(free_it, NULL);
}
}
@@ -587,46 +442,71 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
if (prev)
prev->next = skb;
else
- qp->fragments = skb;
-
- if (skb->dev)
- qp->iif = skb->dev->ifindex;
- skb->dev = NULL;
- qp->stamp = skb->tstamp;
- qp->meat += skb->len;
- atomic_add(skb->truesize, &ip_frag_mem);
+ qp->q.fragments = skb;
+
+ dev = skb->dev;
+ if (dev) {
+ qp->iif = dev->ifindex;
+ skb->dev = NULL;
+ }
+ qp->q.stamp = skb->tstamp;
+ qp->q.meat += skb->len;
+ atomic_add(skb->truesize, &ip4_frags.mem);
if (offset == 0)
- qp->last_in |= FIRST_IN;
+ qp->q.last_in |= FIRST_IN;
- write_lock(&ipfrag_lock);
- list_move_tail(&qp->lru_list, &ipq_lru_list);
- write_unlock(&ipfrag_lock);
+ if (qp->q.last_in == (FIRST_IN | LAST_IN) && qp->q.meat == qp->q.len)
+ return ip_frag_reasm(qp, prev, dev);
- return;
+ write_lock(&ip4_frags.lock);
+ list_move_tail(&qp->q.lru_list, &ip4_frags.lru_list);
+ write_unlock(&ip4_frags.lock);
+ return -EINPROGRESS;
err:
kfree_skb(skb);
+ return err;
}
/* Build a new IP datagram from all its fragments. */
-static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
+static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
+ struct net_device *dev)
{
struct iphdr *iph;
- struct sk_buff *fp, *head = qp->fragments;
+ struct sk_buff *fp, *head = qp->q.fragments;
int len;
int ihlen;
+ int err;
ipq_kill(qp);
+ /* Make the one we just received the head. */
+ if (prev) {
+ head = prev->next;
+ fp = skb_clone(head, GFP_ATOMIC);
+ if (!fp)
+ goto out_nomem;
+
+ fp->next = head->next;
+ prev->next = fp;
+
+ skb_morph(head, qp->q.fragments);
+ head->next = qp->q.fragments->next;
+
+ kfree_skb(qp->q.fragments);
+ qp->q.fragments = head;
+ }
+
BUG_TRAP(head != NULL);
BUG_TRAP(FRAG_CB(head)->offset == 0);
/* Allocate a new buffer for the datagram. */
ihlen = ip_hdrlen(head);
- len = ihlen + qp->len;
+ len = ihlen + qp->q.len;
+ err = -E2BIG;
if (len > 65535)
goto out_oversize;
@@ -654,12 +534,12 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
head->len -= clone->len;
clone->csum = 0;
clone->ip_summed = head->ip_summed;
- atomic_add(clone->truesize, &ip_frag_mem);
+ atomic_add(clone->truesize, &ip4_frags.mem);
}
skb_shinfo(head)->frag_list = head->next;
skb_push(head, head->data - skb_network_header(head));
- atomic_sub(head->truesize, &ip_frag_mem);
+ atomic_sub(head->truesize, &ip4_frags.mem);
for (fp=head->next; fp; fp = fp->next) {
head->data_len += fp->len;
@@ -669,23 +549,24 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
else if (head->ip_summed == CHECKSUM_COMPLETE)
head->csum = csum_add(head->csum, fp->csum);
head->truesize += fp->truesize;
- atomic_sub(fp->truesize, &ip_frag_mem);
+ atomic_sub(fp->truesize, &ip4_frags.mem);
}
head->next = NULL;
head->dev = dev;
- head->tstamp = qp->stamp;
+ head->tstamp = qp->q.stamp;
iph = ip_hdr(head);
iph->frag_off = 0;
iph->tot_len = htons(len);
IP_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
- qp->fragments = NULL;
- return head;
+ qp->q.fragments = NULL;
+ return 0;
out_nomem:
LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing "
"queue %p\n", qp);
+ err = -ENOMEM;
goto out_fail;
out_oversize:
if (net_ratelimit())
@@ -694,54 +575,49 @@ out_oversize:
NIPQUAD(qp->saddr));
out_fail:
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
- return NULL;
+ return err;
}
/* Process an incoming IP datagram fragment. */
-struct sk_buff *ip_defrag(struct sk_buff *skb, u32 user)
+int ip_defrag(struct sk_buff *skb, u32 user)
{
struct ipq *qp;
- struct net_device *dev;
IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);
/* Start by cleaning up the memory. */
- if (atomic_read(&ip_frag_mem) > sysctl_ipfrag_high_thresh)
+ if (atomic_read(&ip4_frags.mem) > ip4_frags_ctl.high_thresh)
ip_evictor();
- dev = skb->dev;
-
/* Lookup (or create) queue header */
if ((qp = ip_find(ip_hdr(skb), user)) != NULL) {
- struct sk_buff *ret = NULL;
+ int ret;
- spin_lock(&qp->lock);
+ spin_lock(&qp->q.lock);
- ip_frag_queue(qp, skb);
+ ret = ip_frag_queue(qp, skb);
- if (qp->last_in == (FIRST_IN|LAST_IN) &&
- qp->meat == qp->len)
- ret = ip_frag_reasm(qp, dev);
-
- spin_unlock(&qp->lock);
- ipq_put(qp, NULL);
+ spin_unlock(&qp->q.lock);
+ ipq_put(qp);
return ret;
}
IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
kfree_skb(skb);
- return NULL;
+ return -ENOMEM;
}
void __init ipfrag_init(void)
{
- ipfrag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
- (jiffies ^ (jiffies >> 6)));
-
- init_timer(&ipfrag_secret_timer);
- ipfrag_secret_timer.function = ipfrag_secret_rebuild;
- ipfrag_secret_timer.expires = jiffies + sysctl_ipfrag_secret_interval;
- add_timer(&ipfrag_secret_timer);
+ ip4_frags.ctl = &ip4_frags_ctl;
+ ip4_frags.hashfn = ip4_hashfn;
+ ip4_frags.constructor = ip4_frag_init;
+ ip4_frags.destructor = ip4_frag_free;
+ ip4_frags.skb_free = NULL;
+ ip4_frags.qsize = sizeof(struct ipq);
+ ip4_frags.match = ip4_frag_match;
+ ip4_frags.frag_expire = ip_expire;
+ inet_frags_init(&ip4_frags);
}
EXPORT_SYMBOL(ip_defrag);
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 41d8964591e..168c871fcd7 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -172,8 +172,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
(!sk->sk_bound_dev_if ||
sk->sk_bound_dev_if == skb->dev->ifindex)) {
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- skb = ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN);
- if (skb == NULL) {
+ if (ip_defrag(skb, IP_DEFRAG_CALL_RA_CHAIN)) {
read_unlock(&ip_ra_lock);
return 1;
}
@@ -196,7 +195,7 @@ int ip_call_ra_chain(struct sk_buff *skb)
return 0;
}
-static inline int ip_local_deliver_finish(struct sk_buff *skb)
+static int ip_local_deliver_finish(struct sk_buff *skb)
{
__skb_pull(skb, ip_hdrlen(skb));
@@ -265,8 +264,7 @@ int ip_local_deliver(struct sk_buff *skb)
*/
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
- if (!skb)
+ if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER))
return 0;
}
@@ -326,7 +324,7 @@ drop:
return -1;
}
-static inline int ip_rcv_finish(struct sk_buff *skb)
+static int ip_rcv_finish(struct sk_buff *skb)
{
const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 699f06781fd..f508835ba71 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -202,7 +202,7 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb)
skb->dst->dev->mtu : dst_mtu(skb->dst);
}
-static inline int ip_finish_output(struct sk_buff *skb)
+static int ip_finish_output(struct sk_buff *skb)
{
#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
/* Policy lookup after SNAT yielded a new policy */
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 341474eefa5..664cb8e97c1 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -25,6 +25,7 @@
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/netfilter.h>
#include <net/net_namespace.h>
#include <net/protocol.h>
#include <net/tcp.h>
@@ -328,18 +329,18 @@ static inline void vs_seq_update(struct ip_vs_conn *cp, struct ip_vs_seq *vseq,
spin_unlock(&cp->lock);
}
-static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb,
+static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb,
struct ip_vs_app *app)
{
int diff;
- const unsigned int tcp_offset = ip_hdrlen(*pskb);
+ const unsigned int tcp_offset = ip_hdrlen(skb);
struct tcphdr *th;
__u32 seq;
- if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
+ if (!skb_make_writable(skb, tcp_offset + sizeof(*th)))
return 0;
- th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
+ th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
/*
* Remember seq number in case this pkt gets resized
@@ -360,7 +361,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb,
if (app->pkt_out == NULL)
return 1;
- if (!app->pkt_out(app, cp, pskb, &diff))
+ if (!app->pkt_out(app, cp, skb, &diff))
return 0;
/*
@@ -378,7 +379,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb,
* called by ipvs packet handler, assumes previously checked cp!=NULL
* returns false if it can't handle packet (oom)
*/
-int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb)
+int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff *skb)
{
struct ip_vs_app *app;
@@ -391,7 +392,7 @@ int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb)
/* TCP is complicated */
if (cp->protocol == IPPROTO_TCP)
- return app_tcp_pkt_out(cp, pskb, app);
+ return app_tcp_pkt_out(cp, skb, app);
/*
* Call private output hook function
@@ -399,22 +400,22 @@ int ip_vs_app_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb)
if (app->pkt_out == NULL)
return 1;
- return app->pkt_out(app, cp, pskb, NULL);
+ return app->pkt_out(app, cp, skb, NULL);
}
-static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb,
+static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb,
struct ip_vs_app *app)
{
int diff;
- const unsigned int tcp_offset = ip_hdrlen(*pskb);
+ const unsigned int tcp_offset = ip_hdrlen(skb);
struct tcphdr *th;
__u32 seq;
- if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th)))
+ if (!skb_make_writable(skb, tcp_offset + sizeof(*th)))
return 0;
- th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset);
+ th = (struct tcphdr *)(skb_network_header(skb) + tcp_offset);
/*
* Remember seq number in case this pkt gets resized
@@ -435,7 +436,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb,
if (app->pkt_in == NULL)
return 1;
- if (!app->pkt_in(app, cp, pskb, &diff))
+ if (!app->pkt_in(app, cp, skb, &diff))
return 0;
/*
@@ -453,7 +454,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb,
* called by ipvs packet handler, assumes previously checked cp!=NULL.
* returns false if can't handle packet (oom).
*/
-int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb)
+int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb)
{
struct ip_vs_app *app;
@@ -466,7 +467,7 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb)
/* TCP is complicated */
if (cp->protocol == IPPROTO_TCP)
- return app_tcp_pkt_in(cp, pskb, app);
+ return app_tcp_pkt_in(cp, skb, app);
/*
* Call private input hook function
@@ -474,7 +475,7 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb)
if (app->pkt_in == NULL)
return 1;
- return app->pkt_in(app, cp, pskb, NULL);
+ return app->pkt_in(app, cp, skb, NULL);
}
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index fbca2a2ff29..c6ed7654e83 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -58,7 +58,6 @@ EXPORT_SYMBOL(ip_vs_conn_put);
#ifdef CONFIG_IP_VS_DEBUG
EXPORT_SYMBOL(ip_vs_get_debug_level);
#endif
-EXPORT_SYMBOL(ip_vs_make_skb_writable);
/* ID used in ICMP lookups */
@@ -163,42 +162,6 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction,
}
-int ip_vs_make_skb_writable(struct sk_buff **pskb, int writable_len)
-{
- struct sk_buff *skb = *pskb;
-
- /* skb is already used, better copy skb and its payload */
- if (unlikely(skb_shared(skb) || skb->sk))
- goto copy_skb;
-
- /* skb data is already used, copy it */
- if (unlikely(skb_cloned(skb)))
- goto copy_data;
-
- return pskb_may_pull(skb, writable_len);
-
- copy_data:
- if (unlikely(writable_len > skb->len))
- return 0;
- return !pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-
- copy_skb:
- if (unlikely(writable_len > skb->len))
- return 0;
- skb = skb_copy(skb, GFP_ATOMIC);
- if (!skb)
- return 0;
- BUG_ON(skb_is_nonlinear(skb));
-
- /* Rest of kernel will get very unhappy if we pass it a
- suddenly-orphaned skbuff */
- if ((*pskb)->sk)
- skb_set_owner_w(skb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = skb;
- return 1;
-}
-
/*
* IPVS persistent scheduling function
* It creates a connection entry according to its template if exists,
@@ -525,12 +488,12 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
* for VS/NAT.
*/
static unsigned int ip_vs_post_routing(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- if (!((*pskb)->ipvs_property))
+ if (!skb->ipvs_property)
return NF_ACCEPT;
/* The packet was sent from IPVS, exit this chain */
return NF_STOP;
@@ -541,13 +504,14 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
}
-static inline struct sk_buff *
-ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
+static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
{
- skb = ip_defrag(skb, user);
- if (skb)
+ int err = ip_defrag(skb, user);
+
+ if (!err)
ip_send_check(ip_hdr(skb));
- return skb;
+
+ return err;
}
/*
@@ -605,9 +569,8 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
* Currently handles error types - unreachable, quench, ttl exceeded.
* (Only used in VS/NAT)
*/
-static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
+static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
{
- struct sk_buff *skb = *pskb;
struct iphdr *iph;
struct icmphdr _icmph, *ic;
struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
@@ -619,10 +582,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
/* reassemble IP fragments */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
- if (!skb)
+ if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
return NF_STOLEN;
- *pskb = skb;
}
iph = ip_hdr(skb);
@@ -690,9 +651,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related)
if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
offset += 2 * sizeof(__u16);
- if (!ip_vs_make_skb_writable(pskb, offset))
+ if (!skb_make_writable(skb, offset))
goto out;
- skb = *pskb;
ip_vs_nat_icmp(skb, pp, cp, 1);
@@ -724,11 +684,10 @@ static inline int is_tcp_reset(const struct sk_buff *skb)
* rewrite addresses of the packet and send it on its way...
*/
static unsigned int
-ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
+ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *skb = *pskb;
struct iphdr *iph;
struct ip_vs_protocol *pp;
struct ip_vs_conn *cp;
@@ -741,11 +700,10 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
iph = ip_hdr(skb);
if (unlikely(iph->protocol == IPPROTO_ICMP)) {
- int related, verdict = ip_vs_out_icmp(pskb, &related);
+ int related, verdict = ip_vs_out_icmp(skb, &related);
if (related)
return verdict;
- skb = *pskb;
iph = ip_hdr(skb);
}
@@ -756,11 +714,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
/* reassemble IP fragments */
if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) &&
!pp->dont_defrag)) {
- skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT);
- if (!skb)
+ if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
return NF_STOLEN;
iph = ip_hdr(skb);
- *pskb = skb;
}
ihl = iph->ihl << 2;
@@ -802,13 +758,12 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet");
- if (!ip_vs_make_skb_writable(pskb, ihl))
+ if (!skb_make_writable(skb, ihl))
goto drop;
/* mangle the packet */
- if (pp->snat_handler && !pp->snat_handler(pskb, pp, cp))
+ if (pp->snat_handler && !pp->snat_handler(skb, pp, cp))
goto drop;
- skb = *pskb;
ip_hdr(skb)->saddr = cp->vaddr;
ip_send_check(ip_hdr(skb));
@@ -818,9 +773,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
* if it came from this machine itself. So re-compute
* the routing information.
*/
- if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
+ if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
goto drop;
- skb = *pskb;
IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
@@ -835,7 +789,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
drop:
ip_vs_conn_put(cp);
- kfree_skb(*pskb);
+ kfree_skb(skb);
return NF_STOLEN;
}
@@ -847,9 +801,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
* Currently handles error types - unreachable, quench, ttl exceeded.
*/
static int
-ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
+ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
{
- struct sk_buff *skb = *pskb;
struct iphdr *iph;
struct icmphdr _icmph, *ic;
struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
@@ -861,12 +814,9 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
/* reassemble IP fragments */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- skb = ip_vs_gather_frags(skb,
- hooknum == NF_IP_LOCAL_IN ?
- IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD);
- if (!skb)
+ if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ?
+ IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
return NF_STOLEN;
- *pskb = skb;
}
iph = ip_hdr(skb);
@@ -945,11 +895,10 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum)
* and send it on its way...
*/
static unsigned int
-ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
+ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *skb = *pskb;
struct iphdr *iph;
struct ip_vs_protocol *pp;
struct ip_vs_conn *cp;
@@ -971,11 +920,10 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
iph = ip_hdr(skb);
if (unlikely(iph->protocol == IPPROTO_ICMP)) {
- int related, verdict = ip_vs_in_icmp(pskb, &related, hooknum);
+ int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
if (related)
return verdict;
- skb = *pskb;
iph = ip_hdr(skb);
}
@@ -1056,16 +1004,16 @@ ip_vs_in(unsigned int hooknum, struct sk_buff **pskb,
* and send them to ip_vs_in_icmp.
*/
static unsigned int
-ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff **pskb,
+ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
int r;
- if (ip_hdr(*pskb)->protocol != IPPROTO_ICMP)
+ if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
return NF_ACCEPT;
- return ip_vs_in_icmp(pskb, &r, hooknum);
+ return ip_vs_in_icmp(skb, &r, hooknum);
}
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c
index 344ddbbdc75..59aa166b767 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/ipv4/ipvs/ip_vs_ftp.c
@@ -30,6 +30,7 @@
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
+#include <linux/netfilter.h>
#include <net/protocol.h>
#include <net/tcp.h>
#include <asm/unaligned.h>
@@ -135,7 +136,7 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit,
* xxx,xxx,xxx,xxx is the server address, ppp,ppp is the server port number.
*/
static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
- struct sk_buff **pskb, int *diff)
+ struct sk_buff *skb, int *diff)
{
struct iphdr *iph;
struct tcphdr *th;
@@ -155,14 +156,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
return 1;
/* Linear packets are much easier to deal with. */
- if (!ip_vs_make_skb_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return 0;
if (cp->app_data == &ip_vs_ftp_pasv) {
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
data = (char *)th + (th->doff << 2);
- data_limit = skb_tail_pointer(*pskb);
+ data_limit = skb_tail_pointer(skb);
if (ip_vs_ftp_get_addrport(data, data_limit,
SERVER_STRING,
@@ -213,7 +214,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
memcpy(start, buf, buf_len);
ret = 1;
} else {
- ret = !ip_vs_skb_replace(*pskb, GFP_ATOMIC, start,
+ ret = !ip_vs_skb_replace(skb, GFP_ATOMIC, start,
end-start, buf, buf_len);
}
@@ -238,7 +239,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
* the client.
*/
static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
- struct sk_buff **pskb, int *diff)
+ struct sk_buff *skb, int *diff)
{
struct iphdr *iph;
struct tcphdr *th;
@@ -256,20 +257,20 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
return 1;
/* Linear packets are much easier to deal with. */
- if (!ip_vs_make_skb_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return 0;
/*
* Detecting whether it is passive
*/
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
th = (struct tcphdr *)&(((char *)iph)[iph->ihl*4]);
/* Since there may be OPTIONS in the TCP packet and the HLEN is
the length of the header in 32-bit multiples, it is accurate
to calculate data address by th+HLEN*4 */
data = data_start = (char *)th + (th->doff << 2);
- data_limit = skb_tail_pointer(*pskb);
+ data_limit = skb_tail_pointer(skb);
while (data <= data_limit - 6) {
if (strnicmp(data, "PASV\r\n", 6) == 0) {
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index e65577a7700..12dc0d640b6 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -20,6 +20,7 @@
#include <linux/tcp.h> /* for tcphdr */
#include <net/ip.h>
#include <net/tcp.h> /* for csum_tcpudp_magic */
+#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <net/ip_vs.h>
@@ -122,27 +123,27 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip,
static int
-tcp_snat_handler(struct sk_buff **pskb,
+tcp_snat_handler(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
{
struct tcphdr *tcph;
- const unsigned int tcphoff = ip_hdrlen(*pskb);
+ const unsigned int tcphoff = ip_hdrlen(skb);
/* csum_check requires unshared skb */
- if (!ip_vs_make_skb_writable(pskb, tcphoff+sizeof(*tcph)))
+ if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
return 0;
if (unlikely(cp->app != NULL)) {
/* Some checks before mangling */
- if (pp->csum_check && !pp->csum_check(*pskb, pp))
+ if (pp->csum_check && !pp->csum_check(skb, pp))
return 0;
/* Call application helper if needed */
- if (!ip_vs_app_pkt_out(cp, pskb))
+ if (!ip_vs_app_pkt_out(cp, skb))
return 0;
}
- tcph = (void *)ip_hdr(*pskb) + tcphoff;
+ tcph = (void *)ip_hdr(skb) + tcphoff;
tcph->source = cp->vport;
/* Adjust TCP checksums */
@@ -150,17 +151,15 @@ tcp_snat_handler(struct sk_buff **pskb,
/* Only port and addr are changed, do fast csum update */
tcp_fast_csum_update(tcph, cp->daddr, cp->vaddr,
cp->dport, cp->vport);
- if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->ip_summed = CHECKSUM_NONE;
} else {
/* full checksum calculation */
tcph->check = 0;
- (*pskb)->csum = skb_checksum(*pskb, tcphoff,
- (*pskb)->len - tcphoff, 0);
+ skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
tcph->check = csum_tcpudp_magic(cp->vaddr, cp->caddr,
- (*pskb)->len - tcphoff,
- cp->protocol,
- (*pskb)->csum);
+ skb->len - tcphoff,
+ cp->protocol, skb->csum);
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
pp->name, tcph->check,
(char*)&(tcph->check) - (char*)tcph);
@@ -170,30 +169,30 @@ tcp_snat_handler(struct sk_buff **pskb,
static int
-tcp_dnat_handler(struct sk_buff **pskb,
+tcp_dnat_handler(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
{
struct tcphdr *tcph;
- const unsigned int tcphoff = ip_hdrlen(*pskb);
+ const unsigned int tcphoff = ip_hdrlen(skb);
/* csum_check requires unshared skb */
- if (!ip_vs_make_skb_writable(pskb, tcphoff+sizeof(*tcph)))
+ if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
return 0;
if (unlikely(cp->app != NULL)) {
/* Some checks before mangling */
- if (pp->csum_check && !pp->csum_check(*pskb, pp))
+ if (pp->csum_check && !pp->csum_check(skb, pp))
return 0;
/*
* Attempt ip_vs_app call.
* It will fix ip_vs_conn and iph ack_seq stuff
*/
- if (!ip_vs_app_pkt_in(cp, pskb))
+ if (!ip_vs_app_pkt_in(cp, skb))
return 0;
}
- tcph = (void *)ip_hdr(*pskb) + tcphoff;
+ tcph = (void *)ip_hdr(skb) + tcphoff;
tcph->dest = cp->dport;
/*
@@ -203,18 +202,16 @@ tcp_dnat_handler(struct sk_buff **pskb,
/* Only port and addr are changed, do fast csum update */
tcp_fast_csum_update(tcph, cp->vaddr, cp->daddr,
cp->vport, cp->dport);
- if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->ip_summed = CHECKSUM_NONE;
} else {
/* full checksum calculation */
tcph->check = 0;
- (*pskb)->csum = skb_checksum(*pskb, tcphoff,
- (*pskb)->len - tcphoff, 0);
+ skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
tcph->check = csum_tcpudp_magic(cp->caddr, cp->daddr,
- (*pskb)->len - tcphoff,
- cp->protocol,
- (*pskb)->csum);
- (*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->len - tcphoff,
+ cp->protocol, skb->csum);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
}
return 1;
}
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 8ee5fe6a101..1fa7b330b9a 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -18,6 +18,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/kernel.h>
+#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/udp.h>
@@ -129,29 +130,29 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip,
}
static int
-udp_snat_handler(struct sk_buff **pskb,
+udp_snat_handler(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
{
struct udphdr *udph;
- const unsigned int udphoff = ip_hdrlen(*pskb);
+ const unsigned int udphoff = ip_hdrlen(skb);
/* csum_check requires unshared skb */
- if (!ip_vs_make_skb_writable(pskb, udphoff+sizeof(*udph)))
+ if (!skb_make_writable(skb, udphoff+sizeof(*udph)))
return 0;
if (unlikely(cp->app != NULL)) {
/* Some checks before mangling */
- if (pp->csum_check && !pp->csum_check(*pskb, pp))
+ if (pp->csum_check && !pp->csum_check(skb, pp))
return 0;
/*
* Call application helper if needed
*/
- if (!ip_vs_app_pkt_out(cp, pskb))
+ if (!ip_vs_app_pkt_out(cp, skb))
return 0;
}
- udph = (void *)ip_hdr(*pskb) + udphoff;
+ udph = (void *)ip_hdr(skb) + udphoff;
udph->source = cp->vport;
/*
@@ -161,17 +162,15 @@ udp_snat_handler(struct sk_buff **pskb,
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update(udph, cp->daddr, cp->vaddr,
cp->dport, cp->vport);
- if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->ip_summed = CHECKSUM_NONE;
} else {
/* full checksum calculation */
udph->check = 0;
- (*pskb)->csum = skb_checksum(*pskb, udphoff,
- (*pskb)->len - udphoff, 0);
+ skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0);
udph->check = csum_tcpudp_magic(cp->vaddr, cp->caddr,
- (*pskb)->len - udphoff,
- cp->protocol,
- (*pskb)->csum);
+ skb->len - udphoff,
+ cp->protocol, skb->csum);
if (udph->check == 0)
udph->check = CSUM_MANGLED_0;
IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
@@ -183,30 +182,30 @@ udp_snat_handler(struct sk_buff **pskb,
static int
-udp_dnat_handler(struct sk_buff **pskb,
+udp_dnat_handler(struct sk_buff *skb,
struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
{
struct udphdr *udph;
- unsigned int udphoff = ip_hdrlen(*pskb);
+ unsigned int udphoff = ip_hdrlen(skb);
/* csum_check requires unshared skb */
- if (!ip_vs_make_skb_writable(pskb, udphoff+sizeof(*udph)))
+ if (!skb_make_writable(skb, udphoff+sizeof(*udph)))
return 0;
if (unlikely(cp->app != NULL)) {
/* Some checks before mangling */
- if (pp->csum_check && !pp->csum_check(*pskb, pp))
+ if (pp->csum_check && !pp->csum_check(skb, pp))
return 0;
/*
* Attempt ip_vs_app call.
* It will fix ip_vs_conn
*/
- if (!ip_vs_app_pkt_in(cp, pskb))
+ if (!ip_vs_app_pkt_in(cp, skb))
return 0;
}
- udph = (void *)ip_hdr(*pskb) + udphoff;
+ udph = (void *)ip_hdr(skb) + udphoff;
udph->dest = cp->dport;
/*
@@ -216,20 +215,18 @@ udp_dnat_handler(struct sk_buff **pskb,
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update(udph, cp->vaddr, cp->daddr,
cp->vport, cp->dport);
- if ((*pskb)->ip_summed == CHECKSUM_COMPLETE)
- (*pskb)->ip_summed = CHECKSUM_NONE;
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
+ skb->ip_summed = CHECKSUM_NONE;
} else {
/* full checksum calculation */
udph->check = 0;
- (*pskb)->csum = skb_checksum(*pskb, udphoff,
- (*pskb)->len - udphoff, 0);
+ skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0);
udph->check = csum_tcpudp_magic(cp->caddr, cp->daddr,
- (*pskb)->len - udphoff,
- cp->protocol,
- (*pskb)->csum);
+ skb->len - udphoff,
+ cp->protocol, skb->csum);
if (udph->check == 0)
udph->check = CSUM_MANGLED_0;
- (*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
}
return 1;
}
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index 666e080a74a..d0a92dec105 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -253,7 +253,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
}
/* copy-on-write the packet before mangling it */
- if (!ip_vs_make_skb_writable(&skb, sizeof(struct iphdr)))
+ if (!skb_make_writable(skb, sizeof(struct iphdr)))
goto tx_error_put;
if (skb_cow(skb, rt->u.dst.dev->hard_header_len))
@@ -264,7 +264,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
skb->dst = &rt->u.dst;
/* mangle the packet */
- if (pp->dnat_handler && !pp->dnat_handler(&skb, pp, cp))
+ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
goto tx_error;
ip_hdr(skb)->daddr = cp->daddr;
ip_send_check(ip_hdr(skb));
@@ -529,7 +529,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
}
/* copy-on-write the packet before mangling it */
- if (!ip_vs_make_skb_writable(&skb, offset))
+ if (!skb_make_writable(skb, offset))
goto tx_error_put;
if (skb_cow(skb, rt->u.dst.dev->hard_header_len))
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index b44192924f9..5539debf497 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -3,14 +3,15 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
+#include <linux/skbuff.h>
#include <net/route.h>
#include <net/xfrm.h>
#include <net/ip.h>
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
-int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
+int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
{
- const struct iphdr *iph = ip_hdr(*pskb);
+ const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt;
struct flowi fl = {};
struct dst_entry *odst;
@@ -29,14 +30,14 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
if (type == RTN_LOCAL)
fl.nl_u.ip4_u.saddr = iph->saddr;
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
- fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0;
- fl.mark = (*pskb)->mark;
+ fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
+ fl.mark = skb->mark;
if (ip_route_output_key(&rt, &fl) != 0)
return -1;
/* Drop old route. */
- dst_release((*pskb)->dst);
- (*pskb)->dst = &rt->u.dst;
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
} else {
/* non-local src, find valid iif to satisfy
* rp-filter when calling ip_route_input. */
@@ -44,8 +45,8 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
if (ip_route_output_key(&rt, &fl) != 0)
return -1;
- odst = (*pskb)->dst;
- if (ip_route_input(*pskb, iph->daddr, iph->saddr,
+ odst = skb->dst;
+ if (ip_route_input(skb, iph->daddr, iph->saddr,
RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
dst_release(&rt->u.dst);
return -1;
@@ -54,70 +55,54 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
dst_release(odst);
}
- if ((*pskb)->dst->error)
+ if (skb->dst->error)
return -1;
#ifdef CONFIG_XFRM
- if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
- xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
- if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
+ if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
+ xfrm_decode_session(skb, &fl, AF_INET) == 0)
+ if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
return -1;
#endif
/* Change in oif may mean change in hh_len. */
- hh_len = (*pskb)->dst->dev->hard_header_len;
- if (skb_headroom(*pskb) < hh_len) {
- struct sk_buff *nskb;
-
- nskb = skb_realloc_headroom(*pskb, hh_len);
- if (!nskb)
- return -1;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
+ hh_len = skb->dst->dev->hard_header_len;
+ if (skb_headroom(skb) < hh_len &&
+ pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
+ return -1;
return 0;
}
EXPORT_SYMBOL(ip_route_me_harder);
#ifdef CONFIG_XFRM
-int ip_xfrm_me_harder(struct sk_buff **pskb)
+int ip_xfrm_me_harder(struct sk_buff *skb)
{
struct flowi fl;
unsigned int hh_len;
struct dst_entry *dst;
- if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED)
+ if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
return 0;
- if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0)
+ if (xfrm_decode_session(skb, &fl, AF_INET) < 0)
return -1;
- dst = (*pskb)->dst;
+ dst = skb->dst;
if (dst->xfrm)
dst = ((struct xfrm_dst *)dst)->route;
dst_hold(dst);
- if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0)
+ if (xfrm_lookup(&dst, &fl, skb->sk, 0) < 0)
return -1;
- dst_release((*pskb)->dst);
- (*pskb)->dst = dst;
+ dst_release(skb->dst);
+ skb->dst = dst;
/* Change in oif may mean change in hh_len. */
- hh_len = (*pskb)->dst->dev->hard_header_len;
- if (skb_headroom(*pskb) < hh_len) {
- struct sk_buff *nskb;
-
- nskb = skb_realloc_headroom(*pskb, hh_len);
- if (!nskb)
- return -1;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
+ hh_len = skb->dst->dev->hard_header_len;
+ if (skb_headroom(skb) < hh_len &&
+ pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
+ return -1;
return 0;
}
EXPORT_SYMBOL(ip_xfrm_me_harder);
@@ -150,17 +135,17 @@ static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info)
}
}
-static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info)
+static int nf_ip_reroute(struct sk_buff *skb, const struct nf_info *info)
{
const struct ip_rt_info *rt_info = nf_info_reroute(info);
if (info->hook == NF_IP_LOCAL_OUT) {
- const struct iphdr *iph = ip_hdr(*pskb);
+ const struct iphdr *iph = ip_hdr(skb);
if (!(iph->tos == rt_info->tos
&& iph->daddr == rt_info->daddr
&& iph->saddr == rt_info->saddr))
- return ip_route_me_harder(pskb, RTN_UNSPEC);
+ return ip_route_me_harder(skb, RTN_UNSPEC);
}
return 0;
}
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 29114a9ccd1..2909c92ecd9 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -197,7 +197,7 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
return 1;
}
-static unsigned int arpt_error(struct sk_buff **pskb,
+static unsigned int arpt_error(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -215,7 +215,7 @@ static inline struct arpt_entry *get_entry(void *base, unsigned int offset)
return (struct arpt_entry *)(base + offset);
}
-unsigned int arpt_do_table(struct sk_buff **pskb,
+unsigned int arpt_do_table(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
@@ -231,9 +231,9 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
struct xt_table_info *private;
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
- if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
- (2 * (*pskb)->dev->addr_len) +
- (2 * sizeof(u32)))))
+ if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
+ (2 * skb->dev->addr_len) +
+ (2 * sizeof(u32)))))
return NF_DROP;
indev = in ? in->name : nulldevname;
@@ -245,14 +245,14 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
e = get_entry(table_base, private->hook_entry[hook]);
back = get_entry(table_base, private->underflow[hook]);
- arp = arp_hdr(*pskb);
+ arp = arp_hdr(skb);
do {
- if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) {
+ if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
struct arpt_entry_target *t;
int hdr_len;
hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) +
- (2 * (*pskb)->dev->addr_len);
+ (2 * skb->dev->addr_len);
ADD_COUNTER(e->counters, hdr_len, 1);
t = arpt_get_target(e);
@@ -290,14 +290,14 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
/* Targets which reenter must return
* abs. verdicts
*/
- verdict = t->u.kernel.target->target(pskb,
+ verdict = t->u.kernel.target->target(skb,
in, out,
hook,
t->u.kernel.target,
t->data);
/* Target might have changed stuff. */
- arp = arp_hdr(*pskb);
+ arp = arp_hdr(skb);
if (verdict == ARPT_CONTINUE)
e = (void *)e + e->next_offset;
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index c4bdab47597..45fa4e20094 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -1,5 +1,6 @@
/* module that allows mangling of the arp payload */
#include <linux/module.h>
+#include <linux/netfilter.h>
#include <linux/netfilter_arp/arpt_mangle.h>
#include <net/sock.h>
@@ -8,7 +9,7 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
MODULE_DESCRIPTION("arptables arp payload mangle target");
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target,
const void *targinfo)
@@ -18,47 +19,38 @@ target(struct sk_buff **pskb,
unsigned char *arpptr;
int pln, hln;
- if (skb_shared(*pskb) || skb_cloned(*pskb)) {
- struct sk_buff *nskb;
+ if (skb_make_writable(skb, skb->len))
+ return NF_DROP;
- nskb = skb_copy(*pskb, GFP_ATOMIC);
- if (!nskb)
- return NF_DROP;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
-
- arp = arp_hdr(*pskb);
- arpptr = skb_network_header(*pskb) + sizeof(*arp);
+ arp = arp_hdr(skb);
+ arpptr = skb_network_header(skb) + sizeof(*arp);
pln = arp->ar_pln;
hln = arp->ar_hln;
/* We assume that pln and hln were checked in the match */
if (mangle->flags & ARPT_MANGLE_SDEV) {
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
- (arpptr + hln > skb_tail_pointer(*pskb)))
+ (arpptr + hln > skb_tail_pointer(skb)))
return NF_DROP;
memcpy(arpptr, mangle->src_devaddr, hln);
}
arpptr += hln;
if (mangle->flags & ARPT_MANGLE_SIP) {
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
- (arpptr + pln > skb_tail_pointer(*pskb)))
+ (arpptr + pln > skb_tail_pointer(skb)))
return NF_DROP;
memcpy(arpptr, &mangle->u_s.src_ip, pln);
}
arpptr += pln;
if (mangle->flags & ARPT_MANGLE_TDEV) {
if (ARPT_DEV_ADDR_LEN_MAX < hln ||
- (arpptr + hln > skb_tail_pointer(*pskb)))
+ (arpptr + hln > skb_tail_pointer(skb)))
return NF_DROP;
memcpy(arpptr, mangle->tgt_devaddr, hln);
}
arpptr += hln;
if (mangle->flags & ARPT_MANGLE_TIP) {
if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
- (arpptr + pln > skb_tail_pointer(*pskb)))
+ (arpptr + pln > skb_tail_pointer(skb)))
return NF_DROP;
memcpy(arpptr, &mangle->u_t.tgt_ip, pln);
}
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 75c02306253..302d3da5f69 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -56,12 +56,12 @@ static struct arpt_table packet_filter = {
/* The work comes in here from netfilter.c */
static unsigned int arpt_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return arpt_do_table(pskb, hook, in, out, &packet_filter);
+ return arpt_do_table(skb, hook, in, out, &packet_filter);
}
static struct nf_hook_ops arpt_ops[] = {
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 23cbfc7c80f..10a2ce09fd8 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -335,6 +335,7 @@ static int
ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
{
int diff;
+ int err;
struct iphdr *user_iph = (struct iphdr *)v->payload;
if (v->data_len < sizeof(*user_iph))
@@ -347,25 +348,18 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- struct sk_buff *newskb;
-
- newskb = skb_copy_expand(e->skb,
- skb_headroom(e->skb),
- diff,
- GFP_ATOMIC);
- if (newskb == NULL) {
- printk(KERN_WARNING "ip_queue: OOM "
- "in mangle, dropping packet\n");
- return -ENOMEM;
+ err = pskb_expand_head(e->skb, 0,
+ diff - skb_tailroom(e->skb),
+ GFP_ATOMIC);
+ if (err) {
+ printk(KERN_WARNING "ip_queue: error "
+ "in mangle, dropping packet: %d\n", -err);
+ return err;
}
- if (e->skb->sk)
- skb_set_owner_w(newskb, e->skb->sk);
- kfree_skb(e->skb);
- e->skb = newskb;
}
skb_put(e->skb, diff);
}
- if (!skb_make_writable(&e->skb, v->data_len))
+ if (!skb_make_writable(e->skb, v->data_len))
return -ENOMEM;
skb_copy_to_linear_data(e->skb, v->payload, v->data_len);
e->skb->ip_summed = CHECKSUM_NONE;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 6486894f450..4b10b98640a 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -169,7 +169,7 @@ ip_checkentry(const struct ipt_ip *ip)
}
static unsigned int
-ipt_error(struct sk_buff **pskb,
+ipt_error(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -312,7 +312,7 @@ static void trace_packet(struct sk_buff *skb,
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned int
-ipt_do_table(struct sk_buff **pskb,
+ipt_do_table(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
@@ -331,8 +331,8 @@ ipt_do_table(struct sk_buff **pskb,
struct xt_table_info *private;
/* Initialization */
- ip = ip_hdr(*pskb);
- datalen = (*pskb)->len - ip->ihl * 4;
+ ip = ip_hdr(skb);
+ datalen = skb->len - ip->ihl * 4;
indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname;
/* We handle fragments by dealing with the first fragment as
@@ -359,7 +359,7 @@ ipt_do_table(struct sk_buff **pskb,
struct ipt_entry_target *t;
if (IPT_MATCH_ITERATE(e, do_match,
- *pskb, in, out,
+ skb, in, out,
offset, &hotdrop) != 0)
goto no_match;
@@ -371,8 +371,8 @@ ipt_do_table(struct sk_buff **pskb,
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* The packet is traced: log it */
- if (unlikely((*pskb)->nf_trace))
- trace_packet(*pskb, hook, in, out,
+ if (unlikely(skb->nf_trace))
+ trace_packet(skb, hook, in, out,
table->name, private, e);
#endif
/* Standard target? */
@@ -410,7 +410,7 @@ ipt_do_table(struct sk_buff **pskb,
((struct ipt_entry *)table_base)->comefrom
= 0xeeeeeeec;
#endif
- verdict = t->u.kernel.target->target(pskb,
+ verdict = t->u.kernel.target->target(skb,
in, out,
hook,
t->u.kernel.target,
@@ -428,8 +428,8 @@ ipt_do_table(struct sk_buff **pskb,
= 0x57acc001;
#endif
/* Target might have changed stuff. */
- ip = ip_hdr(*pskb);
- datalen = (*pskb)->len - ip->ihl * 4;
+ ip = ip_hdr(skb);
+ datalen = skb->len - ip->ihl * 4;
if (verdict == IPT_CONTINUE)
e = (void *)e + e->next_offset;
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 27f14e1ebd8..2f544dac72d 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -289,7 +289,7 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
***********************************************************************/
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -305,7 +305,7 @@ target(struct sk_buff **pskb,
* is only decremented by destroy() - and ip_tables guarantees
* that the ->target() function isn't called after ->destroy() */
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
if (ct == NULL) {
printk(KERN_ERR "CLUSTERIP: no conntrack!\n");
/* FIXME: need to drop invalid ones, since replies
@@ -316,7 +316,7 @@ target(struct sk_buff **pskb,
/* special case: ICMP error handling. conntrack distinguishes between
* error messages (RELATED) and information requests (see below) */
- if (ip_hdr(*pskb)->protocol == IPPROTO_ICMP
+ if (ip_hdr(skb)->protocol == IPPROTO_ICMP
&& (ctinfo == IP_CT_RELATED
|| ctinfo == IP_CT_RELATED+IP_CT_IS_REPLY))
return XT_CONTINUE;
@@ -325,7 +325,7 @@ target(struct sk_buff **pskb,
* TIMESTAMP, INFO_REQUEST or ADDRESS type icmp packets from here
* on, which all have an ID field [relevant for hashing]. */
- hash = clusterip_hashfn(*pskb, cipinfo->config);
+ hash = clusterip_hashfn(skb, cipinfo->config);
switch (ctinfo) {
case IP_CT_NEW:
@@ -355,7 +355,7 @@ target(struct sk_buff **pskb,
/* despite being received via linklayer multicast, this is
* actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */
- (*pskb)->pkt_type = PACKET_HOST;
+ skb->pkt_type = PACKET_HOST;
return XT_CONTINUE;
}
@@ -505,12 +505,12 @@ static void arp_print(struct arp_payload *payload)
static unsigned int
arp_mangle(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct arphdr *arp = arp_hdr(*pskb);
+ struct arphdr *arp = arp_hdr(skb);
struct arp_payload *payload;
struct clusterip_config *c;
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index f1253bd3837..add110060a2 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -26,15 +26,15 @@ MODULE_DESCRIPTION("iptables ECN modification module");
/* set ECT codepoint from IP header.
* return false if there was an error. */
static inline bool
-set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
+set_ect_ip(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
{
- struct iphdr *iph = ip_hdr(*pskb);
+ struct iphdr *iph = ip_hdr(skb);
if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
__u8 oldtos;
- if (!skb_make_writable(pskb, sizeof(struct iphdr)))
+ if (!skb_make_writable(skb, sizeof(struct iphdr)))
return false;
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
oldtos = iph->tos;
iph->tos &= ~IPT_ECN_IP_MASK;
iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
@@ -45,14 +45,13 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
/* Return false if there was an error. */
static inline bool
-set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
+set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
{
struct tcphdr _tcph, *tcph;
__be16 oldval;
/* Not enought header? */
- tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
- sizeof(_tcph), &_tcph);
+ tcph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
if (!tcph)
return false;
@@ -62,9 +61,9 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
tcph->cwr == einfo->proto.tcp.cwr))
return true;
- if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
+ if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
return false;
- tcph = (void *)ip_hdr(*pskb) + ip_hdrlen(*pskb);
+ tcph = (void *)ip_hdr(skb) + ip_hdrlen(skb);
oldval = ((__be16 *)tcph)[6];
if (einfo->operation & IPT_ECN_OP_SET_ECE)
@@ -72,13 +71,13 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
if (einfo->operation & IPT_ECN_OP_SET_CWR)
tcph->cwr = einfo->proto.tcp.cwr;
- nf_proto_csum_replace2(&tcph->check, *pskb,
+ nf_proto_csum_replace2(&tcph->check, skb,
oldval, ((__be16 *)tcph)[6], 0);
return true;
}
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -88,12 +87,12 @@ target(struct sk_buff **pskb,
const struct ipt_ECN_info *einfo = targinfo;
if (einfo->operation & IPT_ECN_OP_SET_IP)
- if (!set_ect_ip(pskb, einfo))
+ if (!set_ect_ip(skb, einfo))
return NF_DROP;
if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
- && ip_hdr(*pskb)->protocol == IPPROTO_TCP)
- if (!set_ect_tcp(pskb, einfo))
+ && ip_hdr(skb)->protocol == IPPROTO_TCP)
+ if (!set_ect_tcp(skb, einfo))
return NF_DROP;
return XT_CONTINUE;
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 127a5e89bf1..4b5e8216a4e 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -418,7 +418,7 @@ ipt_log_packet(unsigned int pf,
}
static unsigned int
-ipt_log_target(struct sk_buff **pskb,
+ipt_log_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -432,7 +432,7 @@ ipt_log_target(struct sk_buff **pskb,
li.u.log.level = loginfo->level;
li.u.log.logflags = loginfo->logflags;
- ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
+ ipt_log_packet(PF_INET, hooknum, skb, in, out, &li,
loginfo->prefix);
return XT_CONTINUE;
}
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 3e0b562b2db..44b516e7cb7 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -52,7 +52,7 @@ masquerade_check(const char *tablename,
}
static unsigned int
-masquerade_target(struct sk_buff **pskb,
+masquerade_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -69,7 +69,7 @@ masquerade_target(struct sk_buff **pskb,
NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
nat = nfct_nat(ct);
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
@@ -82,7 +82,7 @@ masquerade_target(struct sk_buff **pskb,
return NF_ACCEPT;
mr = targinfo;
- rt = (struct rtable *)(*pskb)->dst;
+ rt = (struct rtable *)skb->dst;
newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
if (!newsrc) {
printk("MASQUERADE: %s ate my IP address\n", out->name);
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index 41a011d5a06..f8699291e33 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -43,7 +43,7 @@ check(const char *tablename,
}
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -59,14 +59,14 @@ target(struct sk_buff **pskb,
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_POST_ROUTING
|| hooknum == NF_IP_LOCAL_OUT);
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
if (hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT)
- new_ip = ip_hdr(*pskb)->daddr & ~netmask;
+ new_ip = ip_hdr(skb)->daddr & ~netmask;
else
- new_ip = ip_hdr(*pskb)->saddr & ~netmask;
+ new_ip = ip_hdr(skb)->saddr & ~netmask;
new_ip |= mr->range[0].min_ip & netmask;
newrange = ((struct nf_nat_range)
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index 6ac7a237331..f7cf7d61a2d 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -47,7 +47,7 @@ redirect_check(const char *tablename,
}
static unsigned int
-redirect_target(struct sk_buff **pskb,
+redirect_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -63,7 +63,7 @@ redirect_target(struct sk_buff **pskb,
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_LOCAL_OUT);
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
/* Local packets: make them go to loopback */
@@ -76,7 +76,7 @@ redirect_target(struct sk_buff **pskb,
newdst = 0;
rcu_read_lock();
- indev = __in_dev_get_rcu((*pskb)->dev);
+ indev = __in_dev_get_rcu(skb->dev);
if (indev && (ifa = indev->ifa_list))
newdst = ifa->ifa_local;
rcu_read_unlock();
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index cb038c8fbc9..dcf4d21d511 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -131,7 +131,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
)
addr_type = RTN_LOCAL;
- if (ip_route_me_harder(&nskb, addr_type))
+ if (ip_route_me_harder(nskb, addr_type))
goto free_nskb;
nskb->ip_summed = CHECKSUM_NONE;
@@ -162,7 +162,7 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
}
-static unsigned int reject(struct sk_buff **pskb,
+static unsigned int reject(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -173,7 +173,7 @@ static unsigned int reject(struct sk_buff **pskb,
/* Our naive response construction doesn't deal with IP
options, and probably shouldn't try. */
- if (ip_hdrlen(*pskb) != sizeof(struct iphdr))
+ if (ip_hdrlen(skb) != sizeof(struct iphdr))
return NF_DROP;
/* WARNING: This code causes reentry within iptables.
@@ -181,28 +181,28 @@ static unsigned int reject(struct sk_buff **pskb,
must return an absolute verdict. --RR */
switch (reject->with) {
case IPT_ICMP_NET_UNREACHABLE:
- send_unreach(*pskb, ICMP_NET_UNREACH);
+ send_unreach(skb, ICMP_NET_UNREACH);
break;
case IPT_ICMP_HOST_UNREACHABLE:
- send_unreach(*pskb, ICMP_HOST_UNREACH);
+ send_unreach(skb, ICMP_HOST_UNREACH);
break;
case IPT_ICMP_PROT_UNREACHABLE:
- send_unreach(*pskb, ICMP_PROT_UNREACH);
+ send_unreach(skb, ICMP_PROT_UNREACH);
break;
case IPT_ICMP_PORT_UNREACHABLE:
- send_unreach(*pskb, ICMP_PORT_UNREACH);
+ send_unreach(skb, ICMP_PORT_UNREACH);
break;
case IPT_ICMP_NET_PROHIBITED:
- send_unreach(*pskb, ICMP_NET_ANO);
+ send_unreach(skb, ICMP_NET_ANO);
break;
case IPT_ICMP_HOST_PROHIBITED:
- send_unreach(*pskb, ICMP_HOST_ANO);
+ send_unreach(skb, ICMP_HOST_ANO);
break;
case IPT_ICMP_ADMIN_PROHIBITED:
- send_unreach(*pskb, ICMP_PKT_FILTERED);
+ send_unreach(skb, ICMP_PKT_FILTERED);
break;
case IPT_TCP_RESET:
- send_reset(*pskb, hooknum);
+ send_reset(skb, hooknum);
case IPT_ICMP_ECHOREPLY:
/* Doesn't happen. */
break;
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index 97641f1a97f..8988571436b 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -104,7 +104,7 @@ same_destroy(const struct xt_target *target, void *targinfo)
}
static unsigned int
-same_target(struct sk_buff **pskb,
+same_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -121,7 +121,7 @@ same_target(struct sk_buff **pskb,
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
hooknum == NF_IP_POST_ROUTING);
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 25f5d0b3906..d4573baa7f2 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -21,7 +21,7 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
MODULE_DESCRIPTION("iptables TOS mangling module");
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -29,13 +29,13 @@ target(struct sk_buff **pskb,
const void *targinfo)
{
const struct ipt_tos_target_info *tosinfo = targinfo;
- struct iphdr *iph = ip_hdr(*pskb);
+ struct iphdr *iph = ip_hdr(skb);
if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
__u8 oldtos;
- if (!skb_make_writable(pskb, sizeof(struct iphdr)))
+ if (!skb_make_writable(skb, sizeof(struct iphdr)))
return NF_DROP;
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
oldtos = iph->tos;
iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index 2b54e7b0cfe..c620a052766 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -20,7 +20,7 @@ MODULE_DESCRIPTION("IP tables TTL modification module");
MODULE_LICENSE("GPL");
static unsigned int
-ipt_ttl_target(struct sk_buff **pskb,
+ipt_ttl_target(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target,
const void *targinfo)
@@ -29,10 +29,10 @@ ipt_ttl_target(struct sk_buff **pskb,
const struct ipt_TTL_info *info = targinfo;
int new_ttl;
- if (!skb_make_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return NF_DROP;
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
switch (info->mode) {
case IPT_TTL_SET:
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index c636d6d6357..212b830765a 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -279,7 +279,7 @@ alloc_failure:
spin_unlock_bh(&ulog_lock);
}
-static unsigned int ipt_ulog_target(struct sk_buff **pskb,
+static unsigned int ipt_ulog_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -288,7 +288,7 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
{
struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
- ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL);
+ ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL);
return XT_CONTINUE;
}
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 4f51c1d7d2d..ba3262c6043 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -62,31 +62,31 @@ static struct xt_table packet_filter = {
/* The work comes in here from netfilter.c. */
static unsigned int
ipt_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ipt_do_table(pskb, hook, in, out, &packet_filter);
+ return ipt_do_table(skb, hook, in, out, &packet_filter);
}
static unsigned int
ipt_local_out_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr)
- || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (skb->len < sizeof(struct iphdr) ||
+ ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("iptable_filter: ignoring short SOCK_RAW "
"packet.\n");
return NF_ACCEPT;
}
- return ipt_do_table(pskb, hook, in, out, &packet_filter);
+ return ipt_do_table(skb, hook, in, out, &packet_filter);
}
static struct nf_hook_ops ipt_ops[] = {
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 902446f7cbc..b4360a69d5c 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -75,17 +75,17 @@ static struct xt_table packet_mangler = {
/* The work comes in here from netfilter.c. */
static unsigned int
ipt_route_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ipt_do_table(pskb, hook, in, out, &packet_mangler);
+ return ipt_do_table(skb, hook, in, out, &packet_mangler);
}
static unsigned int
ipt_local_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -97,8 +97,8 @@ ipt_local_hook(unsigned int hook,
u_int32_t mark;
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr)
- || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (skb->len < sizeof(struct iphdr)
+ || ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("iptable_mangle: ignoring short SOCK_RAW "
"packet.\n");
@@ -106,22 +106,22 @@ ipt_local_hook(unsigned int hook,
}
/* Save things which could affect route */
- mark = (*pskb)->mark;
- iph = ip_hdr(*pskb);
+ mark = skb->mark;
+ iph = ip_hdr(skb);
saddr = iph->saddr;
daddr = iph->daddr;
tos = iph->tos;
- ret = ipt_do_table(pskb, hook, in, out, &packet_mangler);
+ ret = ipt_do_table(skb, hook, in, out, &packet_mangler);
/* Reroute for ANY change. */
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
if (iph->saddr != saddr ||
iph->daddr != daddr ||
- (*pskb)->mark != mark ||
+ skb->mark != mark ||
iph->tos != tos)
- if (ip_route_me_harder(pskb, RTN_UNSPEC))
+ if (ip_route_me_harder(skb, RTN_UNSPEC))
ret = NF_DROP;
}
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index d6e50339568..5de6e57ac55 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -47,30 +47,30 @@ static struct xt_table packet_raw = {
/* The work comes in here from netfilter.c. */
static unsigned int
ipt_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ipt_do_table(pskb, hook, in, out, &packet_raw);
+ return ipt_do_table(skb, hook, in, out, &packet_raw);
}
static unsigned int
ipt_local_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr) ||
- ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (skb->len < sizeof(struct iphdr) ||
+ ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("iptable_raw: ignoring short SOCK_RAW"
"packet.\n");
return NF_ACCEPT;
}
- return ipt_do_table(pskb, hook, in, out, &packet_raw);
+ return ipt_do_table(skb, hook, in, out, &packet_raw);
}
/* 'raw' is the very first table. */
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 2fcb9249a8d..831e9b29806 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -63,19 +63,20 @@ static int ipv4_print_conntrack(struct seq_file *s,
}
/* Returns new sk_buff, or NULL */
-static struct sk_buff *
-nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
+static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
{
+ int err;
+
skb_orphan(skb);
local_bh_disable();
- skb = ip_defrag(skb, user);
+ err = ip_defrag(skb, user);
local_bh_enable();
- if (skb)
+ if (!err)
ip_send_check(ip_hdr(skb));
- return skb;
+ return err;
}
static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
@@ -99,17 +100,17 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
}
static unsigned int ipv4_confirm(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* We've seen it coming out the other side: confirm it */
- return nf_conntrack_confirm(pskb);
+ return nf_conntrack_confirm(skb);
}
static unsigned int ipv4_conntrack_help(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -120,7 +121,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
struct nf_conntrack_helper *helper;
/* This is where we call the helper: as the packet goes out. */
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
return NF_ACCEPT;
@@ -131,56 +132,55 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum,
helper = rcu_dereference(help->helper);
if (!helper)
return NF_ACCEPT;
- return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb),
+ return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
ct, ctinfo);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
- if ((*pskb)->nfct)
+ if (skb->nfct)
return NF_ACCEPT;
/* Gather fragments. */
- if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
- *pskb = nf_ct_ipv4_gather_frags(*pskb,
- hooknum == NF_IP_PRE_ROUTING ?
- IP_DEFRAG_CONNTRACK_IN :
- IP_DEFRAG_CONNTRACK_OUT);
- if (!*pskb)
+ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
+ if (nf_ct_ipv4_gather_frags(skb,
+ hooknum == NF_IP_PRE_ROUTING ?
+ IP_DEFRAG_CONNTRACK_IN :
+ IP_DEFRAG_CONNTRACK_OUT))
return NF_STOLEN;
}
return NF_ACCEPT;
}
static unsigned int ipv4_conntrack_in(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return nf_conntrack_in(PF_INET, hooknum, pskb);
+ return nf_conntrack_in(PF_INET, hooknum, skb);
}
static unsigned int ipv4_conntrack_local(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr)
- || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (skb->len < sizeof(struct iphdr) ||
+ ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("ipt_hook: happy cracking.\n");
return NF_ACCEPT;
}
- return nf_conntrack_in(PF_INET, hooknum, pskb);
+ return nf_conntrack_in(PF_INET, hooknum, skb);
}
/* Connection tracking may drop packets, but never alters them, so
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 11fedc73049..adcbaf6d429 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -281,7 +281,6 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[],
static struct ctl_table_header *icmp_sysctl_header;
static struct ctl_table icmp_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT,
.procname = "nf_conntrack_icmp_timeout",
.data = &nf_ct_icmp_timeout,
.maxlen = sizeof(unsigned int),
@@ -295,7 +294,6 @@ static struct ctl_table icmp_sysctl_table[] = {
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
static struct ctl_table icmp_compat_sysctl_table[] = {
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,
.procname = "ip_conntrack_icmp_timeout",
.data = &nf_ct_icmp_timeout,
.maxlen = sizeof(unsigned int),
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
index bd93a1d7105..35a5aa69cd9 100644
--- a/net/ipv4/netfilter/nf_nat_amanda.c
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -24,7 +24,7 @@ MODULE_DESCRIPTION("Amanda NAT helper");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_nat_amanda");
-static unsigned int help(struct sk_buff **pskb,
+static unsigned int help(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
@@ -53,7 +53,7 @@ static unsigned int help(struct sk_buff **pskb,
return NF_DROP;
sprintf(buffer, "%u", port);
- ret = nf_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
+ ret = nf_nat_mangle_udp_packet(skb, exp->master, ctinfo,
matchoff, matchlen,
buffer, strlen(buffer));
if (ret != NF_ACCEPT)
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 7221aa20e6f..56e93f692e8 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -349,7 +349,7 @@ EXPORT_SYMBOL(nf_nat_setup_info);
/* Returns true if succeeded. */
static int
manip_pkt(u_int16_t proto,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_conntrack_tuple *target,
enum nf_nat_manip_type maniptype)
@@ -357,19 +357,19 @@ manip_pkt(u_int16_t proto,
struct iphdr *iph;
struct nf_nat_protocol *p;
- if (!skb_make_writable(pskb, iphdroff + sizeof(*iph)))
+ if (!skb_make_writable(skb, iphdroff + sizeof(*iph)))
return 0;
- iph = (void *)(*pskb)->data + iphdroff;
+ iph = (void *)skb->data + iphdroff;
/* Manipulate protcol part. */
/* rcu_read_lock()ed by nf_hook_slow */
p = __nf_nat_proto_find(proto);
- if (!p->manip_pkt(pskb, iphdroff, target, maniptype))
+ if (!p->manip_pkt(skb, iphdroff, target, maniptype))
return 0;
- iph = (void *)(*pskb)->data + iphdroff;
+ iph = (void *)skb->data + iphdroff;
if (maniptype == IP_NAT_MANIP_SRC) {
nf_csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
@@ -385,7 +385,7 @@ manip_pkt(u_int16_t proto,
unsigned int nf_nat_packet(struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum,
- struct sk_buff **pskb)
+ struct sk_buff *skb)
{
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned long statusbit;
@@ -407,7 +407,7 @@ unsigned int nf_nat_packet(struct nf_conn *ct,
/* We are aiming to look like inverse of other direction. */
nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
- if (!manip_pkt(target.dst.protonum, pskb, 0, &target, mtype))
+ if (!manip_pkt(target.dst.protonum, skb, 0, &target, mtype))
return NF_DROP;
}
return NF_ACCEPT;
@@ -418,7 +418,7 @@ EXPORT_SYMBOL_GPL(nf_nat_packet);
int nf_nat_icmp_reply_translation(struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int hooknum,
- struct sk_buff **pskb)
+ struct sk_buff *skb)
{
struct {
struct icmphdr icmp;
@@ -426,24 +426,24 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
} *inside;
struct nf_conntrack_l4proto *l4proto;
struct nf_conntrack_tuple inner, target;
- int hdrlen = ip_hdrlen(*pskb);
+ int hdrlen = ip_hdrlen(skb);
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
unsigned long statusbit;
enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
- if (!skb_make_writable(pskb, hdrlen + sizeof(*inside)))
+ if (!skb_make_writable(skb, hdrlen + sizeof(*inside)))
return 0;
- inside = (void *)(*pskb)->data + ip_hdrlen(*pskb);
+ inside = (void *)skb->data + ip_hdrlen(skb);
/* We're actually going to mangle it beyond trivial checksum
adjustment, so make sure the current checksum is correct. */
- if (nf_ip_checksum(*pskb, hooknum, hdrlen, 0))
+ if (nf_ip_checksum(skb, hooknum, hdrlen, 0))
return 0;
/* Must be RELATED */
- NF_CT_ASSERT((*pskb)->nfctinfo == IP_CT_RELATED ||
- (*pskb)->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
+ NF_CT_ASSERT(skb->nfctinfo == IP_CT_RELATED ||
+ skb->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
/* Redirects on non-null nats must be dropped, else they'll
start talking to each other without our translation, and be
@@ -458,15 +458,15 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
}
pr_debug("icmp_reply_translation: translating error %p manip %u "
- "dir %s\n", *pskb, manip,
+ "dir %s\n", skb, manip,
dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
/* rcu_read_lock()ed by nf_hook_slow */
l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
- if (!nf_ct_get_tuple(*pskb,
- ip_hdrlen(*pskb) + sizeof(struct icmphdr),
- (ip_hdrlen(*pskb) +
+ if (!nf_ct_get_tuple(skb,
+ ip_hdrlen(skb) + sizeof(struct icmphdr),
+ (ip_hdrlen(skb) +
sizeof(struct icmphdr) + inside->ip.ihl * 4),
(u_int16_t)AF_INET,
inside->ip.protocol,
@@ -478,19 +478,19 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
pass all hooks (locally-generated ICMP). Consider incoming
packet: PREROUTING (DST manip), routing produces ICMP, goes
through POSTROUTING (which must correct the DST manip). */
- if (!manip_pkt(inside->ip.protocol, pskb,
- ip_hdrlen(*pskb) + sizeof(inside->icmp),
+ if (!manip_pkt(inside->ip.protocol, skb,
+ ip_hdrlen(skb) + sizeof(inside->icmp),
&ct->tuplehash[!dir].tuple,
!manip))
return 0;
- if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
/* Reloading "inside" here since manip_pkt inner. */
- inside = (void *)(*pskb)->data + ip_hdrlen(*pskb);
+ inside = (void *)skb->data + ip_hdrlen(skb);
inside->icmp.checksum = 0;
inside->icmp.checksum =
- csum_fold(skb_checksum(*pskb, hdrlen,
- (*pskb)->len - hdrlen, 0));
+ csum_fold(skb_checksum(skb, hdrlen,
+ skb->len - hdrlen, 0));
}
/* Change outer to look the reply to an incoming packet
@@ -506,7 +506,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
if (ct->status & statusbit) {
nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
- if (!manip_pkt(0, pskb, 0, &target, manip))
+ if (!manip_pkt(0, skb, 0, &target, manip))
return 0;
}
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index 3663bd879c3..e1a16d3ea4c 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -28,7 +28,7 @@ MODULE_ALIAS("ip_nat_ftp");
/* FIXME: Time out? --RR */
static int
-mangle_rfc959_packet(struct sk_buff **pskb,
+mangle_rfc959_packet(struct sk_buff *skb,
__be32 newip,
u_int16_t port,
unsigned int matchoff,
@@ -43,13 +43,13 @@ mangle_rfc959_packet(struct sk_buff **pskb,
pr_debug("calling nf_nat_mangle_tcp_packet\n");
- return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
+ return nf_nat_mangle_tcp_packet(skb, ct, ctinfo, matchoff,
matchlen, buffer, strlen(buffer));
}
/* |1|132.235.1.2|6275| */
static int
-mangle_eprt_packet(struct sk_buff **pskb,
+mangle_eprt_packet(struct sk_buff *skb,
__be32 newip,
u_int16_t port,
unsigned int matchoff,
@@ -63,13 +63,13 @@ mangle_eprt_packet(struct sk_buff **pskb,
pr_debug("calling nf_nat_mangle_tcp_packet\n");
- return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
+ return nf_nat_mangle_tcp_packet(skb, ct, ctinfo, matchoff,
matchlen, buffer, strlen(buffer));
}
/* |1|132.235.1.2|6275| */
static int
-mangle_epsv_packet(struct sk_buff **pskb,
+mangle_epsv_packet(struct sk_buff *skb,
__be32 newip,
u_int16_t port,
unsigned int matchoff,
@@ -83,11 +83,11 @@ mangle_epsv_packet(struct sk_buff **pskb,
pr_debug("calling nf_nat_mangle_tcp_packet\n");
- return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
+ return nf_nat_mangle_tcp_packet(skb, ct, ctinfo, matchoff,
matchlen, buffer, strlen(buffer));
}
-static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
+static int (*mangle[])(struct sk_buff *, __be32, u_int16_t,
unsigned int, unsigned int, struct nf_conn *,
enum ip_conntrack_info)
= {
@@ -99,7 +99,7 @@ static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
/* So, this packet has hit the connection tracking matching code.
Mangle it, and change the expectation to match the new version. */
-static unsigned int nf_nat_ftp(struct sk_buff **pskb,
+static unsigned int nf_nat_ftp(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
enum nf_ct_ftp_type type,
unsigned int matchoff,
@@ -132,7 +132,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
if (port == 0)
return NF_DROP;
- if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
+ if (!mangle[type](skb, newip, port, matchoff, matchlen, ct, ctinfo)) {
nf_ct_unexpect_related(exp);
return NF_DROP;
}
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index c1b059a7370..a868c8c4132 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -22,12 +22,12 @@
#include <linux/netfilter/nf_conntrack_h323.h>
/****************************************************************************/
-static int set_addr(struct sk_buff **pskb,
+static int set_addr(struct sk_buff *skb,
unsigned char **data, int dataoff,
unsigned int addroff, __be32 ip, __be16 port)
{
enum ip_conntrack_info ctinfo;
- struct nf_conn *ct = nf_ct_get(*pskb, &ctinfo);
+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
struct {
__be32 ip;
__be16 port;
@@ -38,8 +38,8 @@ static int set_addr(struct sk_buff **pskb,
buf.port = port;
addroff += dataoff;
- if (ip_hdr(*pskb)->protocol == IPPROTO_TCP) {
- if (!nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP) {
+ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
addroff, sizeof(buf),
(char *) &buf, sizeof(buf))) {
if (net_ratelimit())
@@ -49,14 +49,13 @@ static int set_addr(struct sk_buff **pskb,
}
/* Relocate data pointer */
- th = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
+ th = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(_tcph), &_tcph);
if (th == NULL)
return -1;
- *data = (*pskb)->data + ip_hdrlen(*pskb) +
- th->doff * 4 + dataoff;
+ *data = skb->data + ip_hdrlen(skb) + th->doff * 4 + dataoff;
} else {
- if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
+ if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
addroff, sizeof(buf),
(char *) &buf, sizeof(buf))) {
if (net_ratelimit())
@@ -67,36 +66,35 @@ static int set_addr(struct sk_buff **pskb,
/* nf_nat_mangle_udp_packet uses skb_make_writable() to copy
* or pull everything in a linear buffer, so we can safely
* use the skb pointers now */
- *data = ((*pskb)->data + ip_hdrlen(*pskb) +
- sizeof(struct udphdr));
+ *data = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
}
return 0;
}
/****************************************************************************/
-static int set_h225_addr(struct sk_buff **pskb,
+static int set_h225_addr(struct sk_buff *skb,
unsigned char **data, int dataoff,
TransportAddress *taddr,
union nf_conntrack_address *addr, __be16 port)
{
- return set_addr(pskb, data, dataoff, taddr->ipAddress.ip,
+ return set_addr(skb, data, dataoff, taddr->ipAddress.ip,
addr->ip, port);
}
/****************************************************************************/
-static int set_h245_addr(struct sk_buff **pskb,
+static int set_h245_addr(struct sk_buff *skb,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr,
union nf_conntrack_address *addr, __be16 port)
{
- return set_addr(pskb, data, dataoff,
+ return set_addr(skb, data, dataoff,
taddr->unicastAddress.iPAddress.network,
addr->ip, port);
}
/****************************************************************************/
-static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
+static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count)
@@ -125,7 +123,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
NIPQUAD(addr.ip), port,
NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
info->sig_port[!dir]);
- return set_h225_addr(pskb, data, 0, &taddr[i],
+ return set_h225_addr(skb, data, 0, &taddr[i],
&ct->tuplehash[!dir].
tuple.dst.u3,
info->sig_port[!dir]);
@@ -137,7 +135,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
NIPQUAD(addr.ip), port,
NIPQUAD(ct->tuplehash[!dir].tuple.src.u3.ip),
info->sig_port[!dir]);
- return set_h225_addr(pskb, data, 0, &taddr[i],
+ return set_h225_addr(skb, data, 0, &taddr[i],
&ct->tuplehash[!dir].
tuple.src.u3,
info->sig_port[!dir]);
@@ -149,7 +147,7 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
+static int set_ras_addr(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count)
@@ -168,7 +166,7 @@ static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
NIPQUAD(addr.ip), ntohs(port),
NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
- return set_h225_addr(pskb, data, 0, &taddr[i],
+ return set_h225_addr(skb, data, 0, &taddr[i],
&ct->tuplehash[!dir].tuple.dst.u3,
ct->tuplehash[!dir].tuple.
dst.u.udp.port);
@@ -179,7 +177,7 @@ static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
+static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr,
@@ -244,7 +242,7 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
}
/* Modify signal */
- if (set_h245_addr(pskb, data, dataoff, taddr,
+ if (set_h245_addr(skb, data, dataoff, taddr,
&ct->tuplehash[!dir].tuple.dst.u3,
htons((port & htons(1)) ? nated_port + 1 :
nated_port)) == 0) {
@@ -273,7 +271,7 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
+static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr, __be16 port,
@@ -301,7 +299,7 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
}
/* Modify signal */
- if (set_h245_addr(pskb, data, dataoff, taddr,
+ if (set_h245_addr(skb, data, dataoff, taddr,
&ct->tuplehash[!dir].tuple.dst.u3,
htons(nated_port)) < 0) {
nf_ct_unexpect_related(exp);
@@ -318,7 +316,7 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
+static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr, __be16 port,
@@ -351,7 +349,7 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
}
/* Modify signal */
- if (set_h225_addr(pskb, data, dataoff, taddr,
+ if (set_h225_addr(skb, data, dataoff, taddr,
&ct->tuplehash[!dir].tuple.dst.u3,
htons(nated_port)) == 0) {
/* Save ports */
@@ -406,7 +404,7 @@ static void ip_nat_q931_expect(struct nf_conn *new,
}
/****************************************************************************/
-static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
+static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, TransportAddress *taddr, int idx,
__be16 port, struct nf_conntrack_expect *exp)
@@ -439,7 +437,7 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
}
/* Modify signal */
- if (set_h225_addr(pskb, data, 0, &taddr[idx],
+ if (set_h225_addr(skb, data, 0, &taddr[idx],
&ct->tuplehash[!dir].tuple.dst.u3,
htons(nated_port)) == 0) {
/* Save ports */
@@ -450,7 +448,7 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
if (idx > 0 &&
get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
(ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
- set_h225_addr(pskb, data, 0, &taddr[0],
+ set_h225_addr(skb, data, 0, &taddr[0],
&ct->tuplehash[!dir].tuple.dst.u3,
info->sig_port[!dir]);
}
@@ -495,7 +493,7 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new,
}
/****************************************************************************/
-static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
+static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr, __be16 port,
@@ -525,7 +523,7 @@ static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
}
/* Modify signal */
- if (!set_h225_addr(pskb, data, dataoff, taddr,
+ if (!set_h225_addr(skb, data, dataoff, taddr,
&ct->tuplehash[!dir].tuple.dst.u3,
htons(nated_port)) == 0) {
nf_ct_unexpect_related(exp);
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 93d8a0a8f03..8718da00ef2 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -111,22 +111,14 @@ static void mangle_contents(struct sk_buff *skb,
}
/* Unusual, but possible case. */
-static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
+static int enlarge_skb(struct sk_buff *skb, unsigned int extra)
{
- struct sk_buff *nskb;
-
- if ((*pskb)->len + extra > 65535)
+ if (skb->len + extra > 65535)
return 0;
- nskb = skb_copy_expand(*pskb, skb_headroom(*pskb), extra, GFP_ATOMIC);
- if (!nskb)
+ if (pskb_expand_head(skb, 0, extra - skb_tailroom(skb), GFP_ATOMIC))
return 0;
- /* Transfer socket to new skb. */
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
return 1;
}
@@ -139,7 +131,7 @@ static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
*
* */
int
-nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
+nf_nat_mangle_tcp_packet(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
@@ -147,37 +139,37 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
const char *rep_buffer,
unsigned int rep_len)
{
- struct rtable *rt = (struct rtable *)(*pskb)->dst;
+ struct rtable *rt = (struct rtable *)skb->dst;
struct iphdr *iph;
struct tcphdr *tcph;
int oldlen, datalen;
- if (!skb_make_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return 0;
if (rep_len > match_len &&
- rep_len - match_len > skb_tailroom(*pskb) &&
- !enlarge_skb(pskb, rep_len - match_len))
+ rep_len - match_len > skb_tailroom(skb) &&
+ !enlarge_skb(skb, rep_len - match_len))
return 0;
- SKB_LINEAR_ASSERT(*pskb);
+ SKB_LINEAR_ASSERT(skb);
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
tcph = (void *)iph + iph->ihl*4;
- oldlen = (*pskb)->len - iph->ihl*4;
- mangle_contents(*pskb, iph->ihl*4 + tcph->doff*4,
+ oldlen = skb->len - iph->ihl*4;
+ mangle_contents(skb, iph->ihl*4 + tcph->doff*4,
match_offset, match_len, rep_buffer, rep_len);
- datalen = (*pskb)->len - iph->ihl*4;
- if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
+ datalen = skb->len - iph->ihl*4;
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
if (!(rt->rt_flags & RTCF_LOCAL) &&
- (*pskb)->dev->features & NETIF_F_V4_CSUM) {
- (*pskb)->ip_summed = CHECKSUM_PARTIAL;
- (*pskb)->csum_start = skb_headroom(*pskb) +
- skb_network_offset(*pskb) +
- iph->ihl * 4;
- (*pskb)->csum_offset = offsetof(struct tcphdr, check);
+ skb->dev->features & NETIF_F_V4_CSUM) {
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = skb_headroom(skb) +
+ skb_network_offset(skb) +
+ iph->ihl * 4;
+ skb->csum_offset = offsetof(struct tcphdr, check);
tcph->check = ~tcp_v4_check(datalen,
iph->saddr, iph->daddr, 0);
} else {
@@ -188,7 +180,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
datalen, 0));
}
} else
- nf_proto_csum_replace2(&tcph->check, *pskb,
+ nf_proto_csum_replace2(&tcph->check, skb,
htons(oldlen), htons(datalen), 1);
if (rep_len != match_len) {
@@ -197,7 +189,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
(int)rep_len - (int)match_len,
ct, ctinfo);
/* Tell TCP window tracking about seq change */
- nf_conntrack_tcp_update(*pskb, ip_hdrlen(*pskb),
+ nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
ct, CTINFO2DIR(ctinfo));
}
return 1;
@@ -215,7 +207,7 @@ EXPORT_SYMBOL(nf_nat_mangle_tcp_packet);
* should be fairly easy to do.
*/
int
-nf_nat_mangle_udp_packet(struct sk_buff **pskb,
+nf_nat_mangle_udp_packet(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
@@ -223,48 +215,48 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
const char *rep_buffer,
unsigned int rep_len)
{
- struct rtable *rt = (struct rtable *)(*pskb)->dst;
+ struct rtable *rt = (struct rtable *)skb->dst;
struct iphdr *iph;
struct udphdr *udph;
int datalen, oldlen;
/* UDP helpers might accidentally mangle the wrong packet */
- iph = ip_hdr(*pskb);
- if ((*pskb)->len < iph->ihl*4 + sizeof(*udph) +
+ iph = ip_hdr(skb);
+ if (skb->len < iph->ihl*4 + sizeof(*udph) +
match_offset + match_len)
return 0;
- if (!skb_make_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return 0;
if (rep_len > match_len &&
- rep_len - match_len > skb_tailroom(*pskb) &&
- !enlarge_skb(pskb, rep_len - match_len))
+ rep_len - match_len > skb_tailroom(skb) &&
+ !enlarge_skb(skb, rep_len - match_len))
return 0;
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
udph = (void *)iph + iph->ihl*4;
- oldlen = (*pskb)->len - iph->ihl*4;
- mangle_contents(*pskb, iph->ihl*4 + sizeof(*udph),
+ oldlen = skb->len - iph->ihl*4;
+ mangle_contents(skb, iph->ihl*4 + sizeof(*udph),
match_offset, match_len, rep_buffer, rep_len);
/* update the length of the UDP packet */
- datalen = (*pskb)->len - iph->ihl*4;
+ datalen = skb->len - iph->ihl*4;
udph->len = htons(datalen);
/* fix udp checksum if udp checksum was previously calculated */
- if (!udph->check && (*pskb)->ip_summed != CHECKSUM_PARTIAL)
+ if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL)
return 1;
- if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
if (!(rt->rt_flags & RTCF_LOCAL) &&
- (*pskb)->dev->features & NETIF_F_V4_CSUM) {
- (*pskb)->ip_summed = CHECKSUM_PARTIAL;
- (*pskb)->csum_start = skb_headroom(*pskb) +
- skb_network_offset(*pskb) +
- iph->ihl * 4;
- (*pskb)->csum_offset = offsetof(struct udphdr, check);
+ skb->dev->features & NETIF_F_V4_CSUM) {
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = skb_headroom(skb) +
+ skb_network_offset(skb) +
+ iph->ihl * 4;
+ skb->csum_offset = offsetof(struct udphdr, check);
udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
datalen, IPPROTO_UDP,
0);
@@ -278,7 +270,7 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
udph->check = CSUM_MANGLED_0;
}
} else
- nf_proto_csum_replace2(&udph->check, *pskb,
+ nf_proto_csum_replace2(&udph->check, skb,
htons(oldlen), htons(datalen), 1);
return 1;
@@ -330,7 +322,7 @@ sack_adjust(struct sk_buff *skb,
/* TCP SACK sequence number adjustment */
static inline unsigned int
-nf_nat_sack_adjust(struct sk_buff **pskb,
+nf_nat_sack_adjust(struct sk_buff *skb,
struct tcphdr *tcph,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
@@ -338,17 +330,17 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
unsigned int dir, optoff, optend;
struct nf_conn_nat *nat = nfct_nat(ct);
- optoff = ip_hdrlen(*pskb) + sizeof(struct tcphdr);
- optend = ip_hdrlen(*pskb) + tcph->doff * 4;
+ optoff = ip_hdrlen(skb) + sizeof(struct tcphdr);
+ optend = ip_hdrlen(skb) + tcph->doff * 4;
- if (!skb_make_writable(pskb, optend))
+ if (!skb_make_writable(skb, optend))
return 0;
dir = CTINFO2DIR(ctinfo);
while (optoff < optend) {
/* Usually: option, length. */
- unsigned char *op = (*pskb)->data + optoff;
+ unsigned char *op = skb->data + optoff;
switch (op[0]) {
case TCPOPT_EOL:
@@ -365,7 +357,7 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
if (op[0] == TCPOPT_SACK &&
op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
- sack_adjust(*pskb, tcph, optoff+2,
+ sack_adjust(skb, tcph, optoff+2,
optoff+op[1], &nat->seq[!dir]);
optoff += op[1];
}
@@ -375,7 +367,7 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
/* TCP sequence number adjustment. Returns 1 on success, 0 on failure */
int
-nf_nat_seq_adjust(struct sk_buff **pskb,
+nf_nat_seq_adjust(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
@@ -390,10 +382,10 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
this_way = &nat->seq[dir];
other_way = &nat->seq[!dir];
- if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
+ if (!skb_make_writable(skb, ip_hdrlen(skb) + sizeof(*tcph)))
return 0;
- tcph = (void *)(*pskb)->data + ip_hdrlen(*pskb);
+ tcph = (void *)skb->data + ip_hdrlen(skb);
if (after(ntohl(tcph->seq), this_way->correction_pos))
newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
else
@@ -405,8 +397,8 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
else
newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
- nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
- nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
+ nf_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
+ nf_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);
pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",
ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
@@ -415,10 +407,10 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
tcph->seq = newseq;
tcph->ack_seq = newack;
- if (!nf_nat_sack_adjust(pskb, tcph, ct, ctinfo))
+ if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo))
return 0;
- nf_conntrack_tcp_update(*pskb, ip_hdrlen(*pskb), ct, dir);
+ nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir);
return 1;
}
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
index bcf274bba60..766e2c16c6b 100644
--- a/net/ipv4/netfilter/nf_nat_irc.c
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("IRC (DCC) NAT helper");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_nat_irc");
-static unsigned int help(struct sk_buff **pskb,
+static unsigned int help(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
@@ -58,7 +58,7 @@ static unsigned int help(struct sk_buff **pskb,
pr_debug("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
buffer, NIPQUAD(ip), port);
- ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo,
+ ret = nf_nat_mangle_tcp_packet(skb, exp->master, ctinfo,
matchoff, matchlen, buffer,
strlen(buffer));
if (ret != NF_ACCEPT)
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index 984ec8308b2..e1385a09907 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -110,7 +110,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
/* outbound packets == from PNS to PAC */
static int
-pptp_outbound_pkt(struct sk_buff **pskb,
+pptp_outbound_pkt(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
@@ -175,7 +175,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
/* mangle packet */
- if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
cid_off + sizeof(struct pptp_pkt_hdr) +
sizeof(struct PptpControlHeader),
sizeof(new_callid), (char *)&new_callid,
@@ -213,7 +213,7 @@ pptp_exp_gre(struct nf_conntrack_expect *expect_orig,
/* inbound packets == from PAC to PNS */
static int
-pptp_inbound_pkt(struct sk_buff **pskb,
+pptp_inbound_pkt(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
@@ -268,7 +268,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
pr_debug("altering peer call id from 0x%04x to 0x%04x\n",
ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
- if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
+ if (nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
pcid_off + sizeof(struct pptp_pkt_hdr) +
sizeof(struct PptpControlHeader),
sizeof(new_pcid), (char *)&new_pcid,
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index d562290b182..b820f996035 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -98,21 +98,21 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
/* manipulate a GRE packet according to maniptype */
static int
-gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
+gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
struct gre_hdr *greh;
struct gre_hdr_pptp *pgreh;
- struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
+ struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
unsigned int hdroff = iphdroff + iph->ihl * 4;
/* pgreh includes two optional 32bit fields which are not required
* to be there. That's where the magic '8' comes from */
- if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh) - 8))
+ if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8))
return 0;
- greh = (void *)(*pskb)->data + hdroff;
+ greh = (void *)skb->data + hdroff;
pgreh = (struct gre_hdr_pptp *)greh;
/* we only have destination manip of a packet, since 'source key'
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c
index 898d7377115..b9fc724388f 100644
--- a/net/ipv4/netfilter/nf_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
@@ -52,20 +52,20 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
}
static int
-icmp_manip_pkt(struct sk_buff **pskb,
+icmp_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
- struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
+ struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
struct icmphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
- if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
+ if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
return 0;
- hdr = (struct icmphdr *)((*pskb)->data + hdroff);
- nf_proto_csum_replace2(&hdr->checksum, *pskb,
+ hdr = (struct icmphdr *)(skb->data + hdroff);
+ nf_proto_csum_replace2(&hdr->checksum, skb,
hdr->un.echo.id, tuple->src.u.icmp.id, 0);
hdr->un.echo.id = tuple->src.u.icmp.id;
return 1;
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index 5bbbb2acdc7..6bab2e18445 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -88,12 +88,12 @@ tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
}
static int
-tcp_manip_pkt(struct sk_buff **pskb,
+tcp_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
- struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
+ struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
struct tcphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
__be32 oldip, newip;
@@ -103,14 +103,14 @@ tcp_manip_pkt(struct sk_buff **pskb,
/* this could be a inner header returned in icmp packet; in such
cases we cannot update the checksum field since it is outside of
the 8 bytes of transport layer headers we are guaranteed */
- if ((*pskb)->len >= hdroff + sizeof(struct tcphdr))
+ if (skb->len >= hdroff + sizeof(struct tcphdr))
hdrsize = sizeof(struct tcphdr);
- if (!skb_make_writable(pskb, hdroff + hdrsize))
+ if (!skb_make_writable(skb, hdroff + hdrsize))
return 0;
- iph = (struct iphdr *)((*pskb)->data + iphdroff);
- hdr = (struct tcphdr *)((*pskb)->data + hdroff);
+ iph = (struct iphdr *)(skb->data + iphdroff);
+ hdr = (struct tcphdr *)(skb->data + hdroff);
if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */
@@ -132,8 +132,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
if (hdrsize < sizeof(*hdr))
return 1;
- nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
- nf_proto_csum_replace2(&hdr->check, *pskb, oldport, newport, 0);
+ nf_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
+ nf_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0);
return 1;
}
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
index a0af4fd9558..cbf1a61e290 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -86,22 +86,22 @@ udp_unique_tuple(struct nf_conntrack_tuple *tuple,
}
static int
-udp_manip_pkt(struct sk_buff **pskb,
+udp_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
{
- struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
+ struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
struct udphdr *hdr;
unsigned int hdroff = iphdroff + iph->ihl*4;
__be32 oldip, newip;
__be16 *portptr, newport;
- if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
+ if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
return 0;
- iph = (struct iphdr *)((*pskb)->data + iphdroff);
- hdr = (struct udphdr *)((*pskb)->data + hdroff);
+ iph = (struct iphdr *)(skb->data + iphdroff);
+ hdr = (struct udphdr *)(skb->data + hdroff);
if (maniptype == IP_NAT_MANIP_SRC) {
/* Get rid of src ip and src pt */
@@ -116,9 +116,9 @@ udp_manip_pkt(struct sk_buff **pskb,
newport = tuple->dst.u.udp.port;
portptr = &hdr->dest;
}
- if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) {
- nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
- nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport,
+ if (hdr->check || skb->ip_summed == CHECKSUM_PARTIAL) {
+ nf_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
+ nf_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
0);
if (!hdr->check)
hdr->check = CSUM_MANGLED_0;
diff --git a/net/ipv4/netfilter/nf_nat_proto_unknown.c b/net/ipv4/netfilter/nf_nat_proto_unknown.c
index f50d0203f9c..cfd2742e970 100644
--- a/net/ipv4/netfilter/nf_nat_proto_unknown.c
+++ b/net/ipv4/netfilter/nf_nat_proto_unknown.c
@@ -37,7 +37,7 @@ static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple,
}
static int
-unknown_manip_pkt(struct sk_buff **pskb,
+unknown_manip_pkt(struct sk_buff *skb,
unsigned int iphdroff,
const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype)
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 76ec59ae524..46b25ab5f78 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -65,7 +65,7 @@ static struct xt_table nat_table = {
};
/* Source NAT */
-static unsigned int ipt_snat_target(struct sk_buff **pskb,
+static unsigned int ipt_snat_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -78,7 +78,7 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb,
NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
/* Connection must be valid and new. */
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
@@ -107,7 +107,7 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
ip_rt_put(rt);
}
-static unsigned int ipt_dnat_target(struct sk_buff **pskb,
+static unsigned int ipt_dnat_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -121,14 +121,14 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
hooknum == NF_IP_LOCAL_OUT);
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
/* Connection must be valid and new. */
NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
if (hooknum == NF_IP_LOCAL_OUT &&
mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
- warn_if_extra_mangle(ip_hdr(*pskb)->daddr,
+ warn_if_extra_mangle(ip_hdr(skb)->daddr,
mr->range[0].min_ip);
return nf_nat_setup_info(ct, &mr->range[0], hooknum);
@@ -204,7 +204,7 @@ alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
return nf_nat_setup_info(ct, &range, hooknum);
}
-int nf_nat_rule_find(struct sk_buff **pskb,
+int nf_nat_rule_find(struct sk_buff *skb,
unsigned int hooknum,
const struct net_device *in,
const struct net_device *out,
@@ -212,7 +212,7 @@ int nf_nat_rule_find(struct sk_buff **pskb,
{
int ret;
- ret = ipt_do_table(pskb, hooknum, in, out, &nat_table);
+ ret = ipt_do_table(skb, hooknum, in, out, &nat_table);
if (ret == NF_ACCEPT) {
if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index e14d41976c2..ce9edbcc01e 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -60,7 +60,7 @@ static void addr_map_init(struct nf_conn *ct, struct addr_map *map)
}
}
-static int map_sip_addr(struct sk_buff **pskb, enum ip_conntrack_info ctinfo,
+static int map_sip_addr(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
struct nf_conn *ct, const char **dptr, size_t dlen,
enum sip_header_pos pos, struct addr_map *map)
{
@@ -84,15 +84,15 @@ static int map_sip_addr(struct sk_buff **pskb, enum ip_conntrack_info ctinfo,
} else
return 1;
- if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
+ if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
matchoff, matchlen, addr, addrlen))
return 0;
- *dptr = (*pskb)->data + ip_hdrlen(*pskb) + sizeof(struct udphdr);
+ *dptr = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
return 1;
}
-static unsigned int ip_nat_sip(struct sk_buff **pskb,
+static unsigned int ip_nat_sip(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr)
@@ -101,8 +101,8 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
struct addr_map map;
int dataoff, datalen;
- dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
- datalen = (*pskb)->len - dataoff;
+ dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);
+ datalen = skb->len - dataoff;
if (datalen < sizeof("SIP/2.0") - 1)
return NF_ACCEPT;
@@ -121,19 +121,19 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
else
pos = POS_REQ_URI;
- if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, pos, &map))
+ if (!map_sip_addr(skb, ctinfo, ct, dptr, datalen, pos, &map))
return NF_DROP;
}
- if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_FROM, &map) ||
- !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_TO, &map) ||
- !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_VIA, &map) ||
- !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_CONTACT, &map))
+ if (!map_sip_addr(skb, ctinfo, ct, dptr, datalen, POS_FROM, &map) ||
+ !map_sip_addr(skb, ctinfo, ct, dptr, datalen, POS_TO, &map) ||
+ !map_sip_addr(skb, ctinfo, ct, dptr, datalen, POS_VIA, &map) ||
+ !map_sip_addr(skb, ctinfo, ct, dptr, datalen, POS_CONTACT, &map))
return NF_DROP;
return NF_ACCEPT;
}
-static unsigned int mangle_sip_packet(struct sk_buff **pskb,
+static unsigned int mangle_sip_packet(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr, size_t dlen,
@@ -145,16 +145,16 @@ static unsigned int mangle_sip_packet(struct sk_buff **pskb,
if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0)
return 0;
- if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
+ if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo,
matchoff, matchlen, buffer, bufflen))
return 0;
/* We need to reload this. Thanks Patrick. */
- *dptr = (*pskb)->data + ip_hdrlen(*pskb) + sizeof(struct udphdr);
+ *dptr = skb->data + ip_hdrlen(skb) + sizeof(struct udphdr);
return 1;
}
-static int mangle_content_len(struct sk_buff **pskb,
+static int mangle_content_len(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char *dptr)
@@ -163,22 +163,22 @@ static int mangle_content_len(struct sk_buff **pskb,
char buffer[sizeof("65536")];
int bufflen;
- dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
+ dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);
/* Get actual SDP lenght */
- if (ct_sip_get_info(ct, dptr, (*pskb)->len - dataoff, &matchoff,
+ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff,
&matchlen, POS_SDP_HEADER) > 0) {
/* since ct_sip_get_info() give us a pointer passing 'v='
we need to add 2 bytes in this count. */
- int c_len = (*pskb)->len - dataoff - matchoff + 2;
+ int c_len = skb->len - dataoff - matchoff + 2;
/* Now, update SDP length */
- if (ct_sip_get_info(ct, dptr, (*pskb)->len - dataoff, &matchoff,
+ if (ct_sip_get_info(ct, dptr, skb->len - dataoff, &matchoff,
&matchlen, POS_CONTENT) > 0) {
bufflen = sprintf(buffer, "%u", c_len);
- return nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
+ return nf_nat_mangle_udp_packet(skb, ct, ctinfo,
matchoff, matchlen,
buffer, bufflen);
}
@@ -186,7 +186,7 @@ static int mangle_content_len(struct sk_buff **pskb,
return 0;
}
-static unsigned int mangle_sdp(struct sk_buff **pskb,
+static unsigned int mangle_sdp(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
__be32 newip, u_int16_t port,
@@ -195,25 +195,25 @@ static unsigned int mangle_sdp(struct sk_buff **pskb,
char buffer[sizeof("nnn.nnn.nnn.nnn")];
unsigned int dataoff, bufflen;
- dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
+ dataoff = ip_hdrlen(skb) + sizeof(struct udphdr);
/* Mangle owner and contact info. */
bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
- if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
+ if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
buffer, bufflen, POS_OWNER_IP4))
return 0;
- if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
+ if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
buffer, bufflen, POS_CONNECTION_IP4))
return 0;
/* Mangle media port. */
bufflen = sprintf(buffer, "%u", port);
- if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
+ if (!mangle_sip_packet(skb, ctinfo, ct, &dptr, skb->len - dataoff,
buffer, bufflen, POS_MEDIA))
return 0;
- return mangle_content_len(pskb, ctinfo, ct, dptr);
+ return mangle_content_len(skb, ctinfo, ct, dptr);
}
static void ip_nat_sdp_expect(struct nf_conn *ct,
@@ -241,7 +241,7 @@ static void ip_nat_sdp_expect(struct nf_conn *ct,
/* So, this packet has hit the connection tracking matching code.
Mangle it, and change the expectation to match the new version. */
-static unsigned int ip_nat_sdp(struct sk_buff **pskb,
+static unsigned int ip_nat_sdp(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp,
const char *dptr)
@@ -277,7 +277,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
if (port == 0)
return NF_DROP;
- if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
+ if (!mangle_sdp(skb, ctinfo, ct, newip, port, dptr)) {
nf_ct_unexpect_related(exp);
return NF_DROP;
}
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 6bfcd3a90f0..03709d6b4b0 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1188,9 +1188,9 @@ static int snmp_parse_mangle(unsigned char *msg,
*/
static int snmp_translate(struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
- struct sk_buff **pskb)
+ struct sk_buff *skb)
{
- struct iphdr *iph = ip_hdr(*pskb);
+ struct iphdr *iph = ip_hdr(skb);
struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
u_int16_t udplen = ntohs(udph->len);
u_int16_t paylen = udplen - sizeof(struct udphdr);
@@ -1225,13 +1225,13 @@ static int snmp_translate(struct nf_conn *ct,
/* We don't actually set up expectations, just adjust internal IP
* addresses if this is being NATted */
-static int help(struct sk_buff **pskb, unsigned int protoff,
+static int help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
int dir = CTINFO2DIR(ctinfo);
unsigned int ret;
- struct iphdr *iph = ip_hdr(*pskb);
+ struct iphdr *iph = ip_hdr(skb);
struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
/* SNMP replies and originating SNMP traps get mangled */
@@ -1250,7 +1250,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
* enough room for a UDP header. Just verify the UDP length field so we
* can mess around with the payload.
*/
- if (ntohs(udph->len) != (*pskb)->len - (iph->ihl << 2)) {
+ if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) {
if (net_ratelimit())
printk(KERN_WARNING "SNMP: dropping malformed packet "
"src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
@@ -1258,11 +1258,11 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
return NF_DROP;
}
- if (!skb_make_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return NF_DROP;
spin_lock_bh(&snmp_lock);
- ret = snmp_translate(ct, ctinfo, pskb);
+ ret = snmp_translate(ct, ctinfo, skb);
spin_unlock_bh(&snmp_lock);
return ret;
}
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 46cc99def16..7db76ea9af9 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -67,7 +67,7 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
static unsigned int
nf_nat_fn(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -80,9 +80,9 @@ nf_nat_fn(unsigned int hooknum,
/* We never see fragments: conntrack defrags on pre-routing
and local-out, and nf_nat_out protects post-routing. */
- NF_CT_ASSERT(!(ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)));
+ NF_CT_ASSERT(!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)));
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
/* Can't track? It's not due to stress, or conntrack would
have dropped it. Hence it's the user's responsibilty to
packet filter it out, or implement conntrack/NAT for that
@@ -91,10 +91,10 @@ nf_nat_fn(unsigned int hooknum,
/* Exception: ICMP redirect to new connection (not in
hash table yet). We must not let this through, in
case we're doing NAT to the same network. */
- if (ip_hdr(*pskb)->protocol == IPPROTO_ICMP) {
+ if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
struct icmphdr _hdr, *hp;
- hp = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
+ hp = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(_hdr), &_hdr);
if (hp != NULL &&
hp->type == ICMP_REDIRECT)
@@ -119,9 +119,9 @@ nf_nat_fn(unsigned int hooknum,
switch (ctinfo) {
case IP_CT_RELATED:
case IP_CT_RELATED+IP_CT_IS_REPLY:
- if (ip_hdr(*pskb)->protocol == IPPROTO_ICMP) {
+ if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
if (!nf_nat_icmp_reply_translation(ct, ctinfo,
- hooknum, pskb))
+ hooknum, skb))
return NF_DROP;
else
return NF_ACCEPT;
@@ -141,7 +141,7 @@ nf_nat_fn(unsigned int hooknum,
/* LOCAL_IN hook doesn't have a chain! */
ret = alloc_null_binding(ct, hooknum);
else
- ret = nf_nat_rule_find(pskb, hooknum, in, out,
+ ret = nf_nat_rule_find(skb, hooknum, in, out,
ct);
if (ret != NF_ACCEPT) {
@@ -159,31 +159,31 @@ nf_nat_fn(unsigned int hooknum,
ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
}
- return nf_nat_packet(ct, ctinfo, hooknum, pskb);
+ return nf_nat_packet(ct, ctinfo, hooknum, skb);
}
static unsigned int
nf_nat_in(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
unsigned int ret;
- __be32 daddr = ip_hdr(*pskb)->daddr;
+ __be32 daddr = ip_hdr(skb)->daddr;
- ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
+ ret = nf_nat_fn(hooknum, skb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN &&
- daddr != ip_hdr(*pskb)->daddr) {
- dst_release((*pskb)->dst);
- (*pskb)->dst = NULL;
+ daddr != ip_hdr(skb)->daddr) {
+ dst_release(skb->dst);
+ skb->dst = NULL;
}
return ret;
}
static unsigned int
nf_nat_out(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -195,14 +195,14 @@ nf_nat_out(unsigned int hooknum,
unsigned int ret;
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr) ||
- ip_hdrlen(*pskb) < sizeof(struct iphdr))
+ if (skb->len < sizeof(struct iphdr) ||
+ ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT;
- ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
+ ret = nf_nat_fn(hooknum, skb, in, out, okfn);
#ifdef CONFIG_XFRM
if (ret != NF_DROP && ret != NF_STOLEN &&
- (ct = nf_ct_get(*pskb, &ctinfo)) != NULL) {
+ (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.src.u3.ip !=
@@ -210,7 +210,7 @@ nf_nat_out(unsigned int hooknum,
|| ct->tuplehash[dir].tuple.src.u.all !=
ct->tuplehash[!dir].tuple.dst.u.all
)
- return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP;
+ return ip_xfrm_me_harder(skb) == 0 ? ret : NF_DROP;
}
#endif
return ret;
@@ -218,7 +218,7 @@ nf_nat_out(unsigned int hooknum,
static unsigned int
nf_nat_local_fn(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -228,24 +228,24 @@ nf_nat_local_fn(unsigned int hooknum,
unsigned int ret;
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr) ||
- ip_hdrlen(*pskb) < sizeof(struct iphdr))
+ if (skb->len < sizeof(struct iphdr) ||
+ ip_hdrlen(skb) < sizeof(struct iphdr))
return NF_ACCEPT;
- ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
+ ret = nf_nat_fn(hooknum, skb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN &&
- (ct = nf_ct_get(*pskb, &ctinfo)) != NULL) {
+ (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.dst.u3.ip !=
ct->tuplehash[!dir].tuple.src.u3.ip) {
- if (ip_route_me_harder(pskb, RTN_UNSPEC))
+ if (ip_route_me_harder(skb, RTN_UNSPEC))
ret = NF_DROP;
}
#ifdef CONFIG_XFRM
else if (ct->tuplehash[dir].tuple.dst.u.all !=
ct->tuplehash[!dir].tuple.src.u.all)
- if (ip_xfrm_me_harder(pskb))
+ if (ip_xfrm_me_harder(skb))
ret = NF_DROP;
#endif
}
@@ -254,7 +254,7 @@ nf_nat_local_fn(unsigned int hooknum,
static unsigned int
nf_nat_adjust(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -262,10 +262,10 @@ nf_nat_adjust(unsigned int hooknum,
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
pr_debug("nf_nat_standalone: adjusting sequence number\n");
- if (!nf_nat_seq_adjust(pskb, ct, ctinfo))
+ if (!nf_nat_seq_adjust(skb, ct, ctinfo))
return NF_DROP;
}
return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c
index 04dfeaefec0..0ecec701cb4 100644
--- a/net/ipv4/netfilter/nf_nat_tftp.c
+++ b/net/ipv4/netfilter/nf_nat_tftp.c
@@ -20,7 +20,7 @@ MODULE_DESCRIPTION("TFTP NAT helper");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_nat_tftp");
-static unsigned int help(struct sk_buff **pskb,
+static unsigned int help(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp)
{
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index e5b05b03910..fd16cb8f8ab 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -70,8 +70,8 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot));
seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
- seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
- atomic_read(&ip_frag_mem));
+ seq_printf(seq, "FRAG: inuse %d memory %d\n",
+ ip_frag_nqueues(), ip_frag_mem());
return 0;
}
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index eb286abcf5d..c78acc1a7f1 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -19,6 +19,7 @@
#include <net/route.h>
#include <net/tcp.h>
#include <net/cipso_ipv4.h>
+#include <net/inet_frag.h>
/* From af_inet.c */
extern int sysctl_ip_nonlocal_bind;
@@ -357,7 +358,7 @@ ctl_table ipv4_table[] = {
{
.ctl_name = NET_IPV4_IPFRAG_HIGH_THRESH,
.procname = "ipfrag_high_thresh",
- .data = &sysctl_ipfrag_high_thresh,
+ .data = &ip4_frags_ctl.high_thresh,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec
@@ -365,7 +366,7 @@ ctl_table ipv4_table[] = {
{
.ctl_name = NET_IPV4_IPFRAG_LOW_THRESH,
.procname = "ipfrag_low_thresh",
- .data = &sysctl_ipfrag_low_thresh,
+ .data = &ip4_frags_ctl.low_thresh,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec
@@ -381,7 +382,7 @@ ctl_table ipv4_table[] = {
{
.ctl_name = NET_IPV4_IPFRAG_TIME,
.procname = "ipfrag_time",
- .data = &sysctl_ipfrag_time,
+ .data = &ip4_frags_ctl.timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
@@ -732,14 +733,13 @@ ctl_table ipv4_table[] = {
{
.ctl_name = NET_IPV4_IPFRAG_SECRET_INTERVAL,
.procname = "ipfrag_secret_interval",
- .data = &sysctl_ipfrag_secret_interval,
+ .data = &ip4_frags_ctl.secret_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
.strategy = &sysctl_jiffies
},
{
- .ctl_name = NET_IPV4_IPFRAG_MAX_DIST,
.procname = "ipfrag_max_dist",
.data = &sysctl_ipfrag_max_dist,
.maxlen = sizeof(int),
@@ -864,7 +864,6 @@ ctl_table ipv4_table[] = {
},
#endif /* CONFIG_NETLABEL */
{
- .ctl_name = NET_TCP_AVAIL_CONG_CONTROL,
.procname = "tcp_available_congestion_control",
.maxlen = TCP_CA_BUF_MAX,
.mode = 0444,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0a42e934034..9288220b73a 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
struct sk_buff *skb;
int flag = 0;
int cnt = 0;
- u32 new_low_seq = 0;
+ u32 new_low_seq = tp->snd_nxt;
tcp_for_write_queue(skb, sk) {
u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
@@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
}
} else {
- if (!new_low_seq || before(ack_seq, new_low_seq))
+ if (before(ack_seq, new_low_seq))
new_low_seq = ack_seq;
cnt += tcp_skb_pcount(skb);
}
@@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
int reord = tp->packets_out;
int prior_fackets;
- u32 highest_sack_end_seq = 0;
+ u32 highest_sack_end_seq = tp->lost_retrans_low;
int flag = 0;
int found_dup_sack = 0;
int cached_fack_count;
@@ -1995,8 +1995,7 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp,
}
/* Mark head of queue up as lost. */
-static void tcp_mark_head_lost(struct sock *sk,
- int packets, u32 high_seq)
+static void tcp_mark_head_lost(struct sock *sk, int packets)
{
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb;
@@ -2019,7 +2018,7 @@ static void tcp_mark_head_lost(struct sock *sk,
tp->lost_skb_hint = skb;
tp->lost_cnt_hint = cnt;
cnt += tcp_skb_pcount(skb);
- if (cnt > packets || after(TCP_SKB_CB(skb)->end_seq, high_seq))
+ if (cnt > packets || after(TCP_SKB_CB(skb)->end_seq, tp->high_seq))
break;
if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_SACKED_ACKED|TCPCB_LOST))) {
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -2040,9 +2039,9 @@ static void tcp_update_scoreboard(struct sock *sk)
int lost = tp->fackets_out - tp->reordering;
if (lost <= 0)
lost = 1;
- tcp_mark_head_lost(sk, lost, tp->high_seq);
+ tcp_mark_head_lost(sk, lost);
} else {
- tcp_mark_head_lost(sk, 1, tp->high_seq);
+ tcp_mark_head_lost(sk, 1);
}
/* New heuristics: it is possible only after we switched
@@ -2381,7 +2380,7 @@ tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
before(tp->snd_una, tp->high_seq) &&
icsk->icsk_ca_state != TCP_CA_Open &&
tp->fackets_out > tp->reordering) {
- tcp_mark_head_lost(sk, tp->fackets_out-tp->reordering, tp->high_seq);
+ tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering);
NET_INC_STATS_BH(LINUX_MIB_TCPLOSS);
}
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index e9bbfde19ac..5e95c8a07ef 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,19 +16,6 @@
#include <net/ip.h>
#include <net/xfrm.h>
-static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
-{
- switch (nexthdr) {
- case IPPROTO_IPIP:
- case IPPROTO_IPV6:
- *spi = ip_hdr(skb)->saddr;
- *seq = 0;
- return 0;
- }
-
- return xfrm_parse_spi(skb, nexthdr, spi, seq);
-}
-
#ifdef CONFIG_NETFILTER
static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
{
@@ -46,28 +33,29 @@ drop:
}
#endif
-static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
+int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
+ int encap_type)
{
- __be32 spi, seq;
+ int err;
+ __be32 seq;
struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
struct xfrm_state *x;
int xfrm_nr = 0;
int decaps = 0;
- int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
unsigned int nhoff = offsetof(struct iphdr, protocol);
- if (err != 0)
+ seq = 0;
+ if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
goto drop;
do {
const struct iphdr *iph = ip_hdr(skb);
- int nexthdr;
if (xfrm_nr == XFRM_MAX_DEPTH)
goto drop;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
- iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET);
+ nexthdr, AF_INET);
if (x == NULL)
goto drop;
@@ -103,15 +91,15 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
xfrm_vec[xfrm_nr++] = x;
- if (x->mode->input(x, skb))
+ if (x->outer_mode->input(x, skb))
goto drop;
- if (x->props.mode == XFRM_MODE_TUNNEL) {
+ if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
decaps = 1;
break;
}
- err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
+ err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
if (err < 0)
goto drop;
} while (!err);
@@ -165,6 +153,7 @@ drop:
kfree_skb(skb);
return 0;
}
+EXPORT_SYMBOL(xfrm4_rcv_encap);
/* If it's a keepalive packet, then just eat it.
* If it's an encapsulated packet, then pass it to the
@@ -252,11 +241,8 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
__skb_pull(skb, len);
skb_reset_transport_header(skb);
- /* modify the protocol (it's ESP!) */
- iph->protocol = IPPROTO_ESP;
-
/* process ESP */
- ret = xfrm4_rcv_encap(skb, encap_type);
+ ret = xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
return ret;
drop:
@@ -266,7 +252,7 @@ drop:
int xfrm4_rcv(struct sk_buff *skb)
{
- return xfrm4_rcv_encap(skb, 0);
+ return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0);
}
EXPORT_SYMBOL(xfrm4_rcv);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 73d2338bec5..e42e122414b 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -114,6 +114,7 @@ static struct xfrm_mode xfrm4_beet_mode = {
.output = xfrm4_beet_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_BEET,
+ .flags = XFRM_MODE_FLAG_TUNNEL,
};
static int __init xfrm4_beet_init(void)
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 1ae9d32276f..e4deecba6dd 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -139,6 +139,7 @@ static struct xfrm_mode xfrm4_tunnel_mode = {
.output = xfrm4_tunnel_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_TUNNEL,
+ .flags = XFRM_MODE_FLAG_TUNNEL,
};
static int __init xfrm4_tunnel_init(void)
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 434ef302ba8..c4a7156962b 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -47,7 +47,7 @@ static inline int xfrm4_output_one(struct sk_buff *skb)
struct iphdr *iph;
int err;
- if (x->props.mode == XFRM_MODE_TUNNEL) {
+ if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
err = xfrm4_tunnel_check_size(skb);
if (err)
goto error_nolock;
@@ -78,7 +78,7 @@ static int xfrm4_output_finish2(struct sk_buff *skb)
while (likely((err = xfrm4_output_one(skb)) == 0)) {
nf_reset(skb);
- err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, &skb, NULL,
+ err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
skb->dst->dev, dst_output);
if (unlikely(err != 1))
break;
@@ -86,7 +86,7 @@ static int xfrm4_output_finish2(struct sk_buff *skb)
if (!skb->dst->xfrm)
return dst_output(skb);
- err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
+ err = nf_hook(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
skb->dst->dev, xfrm4_output_finish2);
if (unlikely(err != 1))
break;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 329825ca68f..cc86fb110dd 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -117,7 +117,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
header_len += xfrm[i]->props.header_len;
trailer_len += xfrm[i]->props.trailer_len;
- if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {
+ if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
unsigned short encap_family = xfrm[i]->props.family;
switch (encap_family) {
case AF_INET:
@@ -151,7 +151,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
i = 0;
for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
- struct xfrm_state_afinfo *afinfo;
x->u.rt.fl = *fl;
dst_prev->xfrm = xfrm[i++];
@@ -169,27 +168,17 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
/* Copy neighbout for reachability confirmation */
dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
dst_prev->input = rt->u.dst.input;
- /* XXX: When IPv6 module can be unloaded, we should manage reference
- * to xfrm6_output in afinfo->output. Miyazawa
- * */
- afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
- if (!afinfo) {
- dst = *dst_p;
- err = -EAFNOSUPPORT;
- goto error;
- }
- dst_prev->output = afinfo->output;
- xfrm_state_put_afinfo(afinfo);
- if (dst_prev->xfrm->props.family == AF_INET && rt->peer)
- atomic_inc(&rt->peer->refcnt);
- x->u.rt.peer = rt->peer;
+ dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
+ if (rt0->peer)
+ atomic_inc(&rt0->peer->refcnt);
+ x->u.rt.peer = rt0->peer;
/* Sheit... I remember I did this right. Apparently,
* it was magically lost, so this code needs audit */
x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
- x->u.rt.rt_type = rt->rt_type;
+ x->u.rt.rt_type = rt0->rt_type;
x->u.rt.rt_src = rt0->rt_src;
x->u.rt.rt_dst = rt0->rt_dst;
- x->u.rt.rt_gateway = rt->rt_gateway;
+ x->u.rt.rt_gateway = rt0->rt_gateway;
x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
x->u.rt.idev = rt0->idev;
in_dev_hold(rt0->idev);
@@ -291,7 +280,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
if (likely(xdst->u.rt.idev))
in_dev_put(xdst->u.rt.idev);
- if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer))
+ if (likely(xdst->u.rt.peer))
inet_putpeer(xdst->u.rt.peer);
xfrm_dst_destroy(xdst);
}
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 93e2c061cdd..13d54a1c333 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -49,6 +49,7 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
static struct xfrm_state_afinfo xfrm4_state_afinfo = {
.family = AF_INET,
+ .owner = THIS_MODULE,
.init_flags = xfrm4_init_flags,
.init_tempsel = __xfrm4_init_tempsel,
.output = xfrm4_output,
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 1312417608e..32684519562 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
{
- return IPPROTO_IP;
+ return ip_hdr(skb)->protocol;
}
static int ipip_init_state(struct xfrm_state *x)
@@ -48,20 +48,25 @@ static struct xfrm_type ipip_type = {
.output = ipip_output
};
+static int xfrm_tunnel_rcv(struct sk_buff *skb)
+{
+ return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr);
+}
+
static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
{
return -ENOENT;
}
static struct xfrm_tunnel xfrm_tunnel_handler = {
- .handler = xfrm4_rcv,
+ .handler = xfrm_tunnel_rcv,
.err_handler = xfrm_tunnel_err,
.priority = 2,
};
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static struct xfrm_tunnel xfrm64_tunnel_handler = {
- .handler = xfrm4_rcv,
+ .handler = xfrm_tunnel_rcv,
.err_handler = xfrm_tunnel_err,
.priority = 2,
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 52d10d21321..348bd8d0611 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -255,11 +255,6 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
static int snmp6_alloc_dev(struct inet6_dev *idev)
{
- int err = -ENOMEM;
-
- if (!idev || !idev->dev)
- return -EINVAL;
-
if (snmp_mib_init((void **)idev->stats.ipv6,
sizeof(struct ipstats_mib),
__alignof__(struct ipstats_mib)) < 0)
@@ -280,15 +275,14 @@ err_icmpmsg:
err_icmp:
snmp_mib_free((void **)idev->stats.ipv6);
err_ip:
- return err;
+ return -ENOMEM;
}
-static int snmp6_free_dev(struct inet6_dev *idev)
+static void snmp6_free_dev(struct inet6_dev *idev)
{
snmp_mib_free((void **)idev->stats.icmpv6msg);
snmp_mib_free((void **)idev->stats.icmpv6);
snmp_mib_free((void **)idev->stats.ipv6);
- return 0;
}
/* Nobody refers to this device, we may destroy it. */
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index bc929381fa4..1b1caf3aa1c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -747,6 +747,7 @@ static void cleanup_ipv6_mibs(void)
{
snmp_mib_free((void **)ipv6_statistics);
snmp_mib_free((void **)icmpv6_statistics);
+ snmp_mib_free((void **)icmpv6msg_statistics);
snmp_mib_free((void **)udp_stats_in6);
snmp_mib_free((void **)udplite_stats_in6);
}
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index f9f68916269..67cd06613a2 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -344,6 +344,8 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out;
+ skb->ip_summed = CHECKSUM_NONE;
+
hdr_len = skb->data - skb_network_header(skb);
ah = (struct ip_auth_hdr *)skb->data;
ahp = x->data;
@@ -475,8 +477,15 @@ static int ah6_init_state(struct xfrm_state *x)
x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) +
ahp->icv_trunc_len);
- if (x->props.mode == XFRM_MODE_TUNNEL)
+ switch (x->props.mode) {
+ case XFRM_MODE_BEET:
+ case XFRM_MODE_TRANSPORT:
+ break;
+ case XFRM_MODE_TUNNEL:
x->props.header_len += sizeof(struct ipv6hdr);
+ default:
+ goto error;
+ }
x->data = ahp;
return 0;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 9eb92859835..b0715432e45 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -354,8 +354,15 @@ static int esp6_init_state(struct xfrm_state *x)
(x->ealg->alg_key_len + 7) / 8))
goto error;
x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
- if (x->props.mode == XFRM_MODE_TUNNEL)
+ switch (x->props.mode) {
+ case XFRM_MODE_BEET:
+ case XFRM_MODE_TRANSPORT:
+ break;
+ case XFRM_MODE_TUNNEL:
x->props.header_len += sizeof(struct ipv6hdr);
+ default:
+ goto error;
+ }
x->data = esp;
return 0;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index c82d4d49f71..1e89efd38a0 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(ipv6_find_tlv);
struct tlvtype_proc {
int type;
- int (*func)(struct sk_buff **skbp, int offset);
+ int (*func)(struct sk_buff *skb, int offset);
};
/*********************
@@ -111,10 +111,8 @@ struct tlvtype_proc {
/* An unknown option is detected, decide what to do */
-static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
+static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff)
{
- struct sk_buff *skb = *skbp;
-
switch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {
case 0: /* ignore */
return 1;
@@ -139,9 +137,8 @@ static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff)
/* Parse tlv encoded option header (hop-by-hop or destination) */
-static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
+static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb)
{
- struct sk_buff *skb = *skbp;
struct tlvtype_proc *curr;
const unsigned char *nh = skb_network_header(skb);
int off = skb_network_header_len(skb);
@@ -172,13 +169,13 @@ static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp)
/* type specific length/alignment
checks will be performed in the
func(). */
- if (curr->func(skbp, off) == 0)
+ if (curr->func(skb, off) == 0)
return 0;
break;
}
}
if (curr->type < 0) {
- if (ip6_tlvopt_unknown(skbp, off) == 0)
+ if (ip6_tlvopt_unknown(skb, off) == 0)
return 0;
}
break;
@@ -198,9 +195,8 @@ bad:
*****************************/
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
-static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
+static int ipv6_dest_hao(struct sk_buff *skb, int optoff)
{
- struct sk_buff *skb = *skbp;
struct ipv6_destopt_hao *hao;
struct inet6_skb_parm *opt = IP6CB(skb);
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
@@ -234,22 +230,13 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
goto discard;
if (skb_cloned(skb)) {
- struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
- struct inet6_skb_parm *opt2;
-
- if (skb2 == NULL)
+ if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto discard;
- opt2 = IP6CB(skb2);
- memcpy(opt2, opt, sizeof(*opt2));
-
- kfree_skb(skb);
-
/* update all variable using below by copied skbuff */
- *skbp = skb = skb2;
- hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
+ hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) +
optoff);
- ipv6h = ipv6_hdr(skb2);
+ ipv6h = ipv6_hdr(skb);
}
if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -280,9 +267,8 @@ static struct tlvtype_proc tlvprocdestopt_lst[] = {
{-1, NULL}
};
-static int ipv6_destopt_rcv(struct sk_buff **skbp)
+static int ipv6_destopt_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *skbp;
struct inet6_skb_parm *opt = IP6CB(skb);
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
__u16 dstbuf;
@@ -304,9 +290,8 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
#endif
dst = dst_clone(skb->dst);
- if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
+ if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
dst_release(dst);
- skb = *skbp;
skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
opt = IP6CB(skb);
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
@@ -337,10 +322,8 @@ void __init ipv6_destopt_init(void)
NONE header. No data in packet.
********************************/
-static int ipv6_nodata_rcv(struct sk_buff **skbp)
+static int ipv6_nodata_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *skbp;
-
kfree_skb(skb);
return 0;
}
@@ -360,9 +343,8 @@ void __init ipv6_nodata_init(void)
Routing header.
********************************/
-static int ipv6_rthdr_rcv(struct sk_buff **skbp)
+static int ipv6_rthdr_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *skbp;
struct inet6_skb_parm *opt = IP6CB(skb);
struct in6_addr *addr = NULL;
struct in6_addr daddr;
@@ -464,18 +446,14 @@ looped_back:
Do not damage packets queued somewhere.
*/
if (skb_cloned(skb)) {
- struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
/* the copy is a forwarded packet */
- if (skb2 == NULL) {
+ if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
IPSTATS_MIB_OUTDISCARDS);
kfree_skb(skb);
return -1;
}
- kfree_skb(skb);
- *skbp = skb = skb2;
- opt = IP6CB(skb2);
- hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb2);
+ hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
}
if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -578,9 +556,8 @@ static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
/* Router Alert as of RFC 2711 */
-static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
+static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
{
- struct sk_buff *skb = *skbp;
const unsigned char *nh = skb_network_header(skb);
if (nh[optoff + 1] == 2) {
@@ -595,9 +572,8 @@ static int ipv6_hop_ra(struct sk_buff **skbp, int optoff)
/* Jumbo payload */
-static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
+static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
{
- struct sk_buff *skb = *skbp;
const unsigned char *nh = skb_network_header(skb);
u32 pkt_len;
@@ -648,9 +624,8 @@ static struct tlvtype_proc tlvprochopopt_lst[] = {
{ -1, }
};
-int ipv6_parse_hopopts(struct sk_buff **skbp)
+int ipv6_parse_hopopts(struct sk_buff *skb)
{
- struct sk_buff *skb = *skbp;
struct inet6_skb_parm *opt = IP6CB(skb);
/*
@@ -667,8 +642,7 @@ int ipv6_parse_hopopts(struct sk_buff **skbp)
}
opt->hop = sizeof(struct ipv6hdr);
- if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) {
- skb = *skbp;
+ if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
opt = IP6CB(skb);
opt->nhoff = sizeof(struct ipv6hdr);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 47b8ce232e8..9bb031fa1c2 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -82,7 +82,7 @@ EXPORT_SYMBOL(icmpv6msg_statistics);
static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL;
#define icmpv6_socket __get_cpu_var(__icmpv6_socket)
-static int icmpv6_rcv(struct sk_buff **pskb);
+static int icmpv6_rcv(struct sk_buff *skb);
static struct inet6_protocol icmpv6_protocol = {
.handler = icmpv6_rcv,
@@ -614,9 +614,8 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
* Handle icmp messages
*/
-static int icmpv6_rcv(struct sk_buff **pskb)
+static int icmpv6_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *pskb;
struct net_device *dev = skb->dev;
struct inet6_dev *idev = __in6_dev_get(dev);
struct in6_addr *saddr, *daddr;
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 25b93170974..78de42ada84 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -146,7 +146,7 @@ void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
__ip6_dst_store(sk, dst, daddr, saddr);
#ifdef CONFIG_XFRM
- if (dst) {
+ {
struct rt6_info *rt = (struct rt6_info *)dst;
rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
}
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 217d60f9fc8..b12cc22e774 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -154,8 +154,10 @@ static void ip6_fl_gc(unsigned long dummy)
write_unlock(&ip6_fl_lock);
}
-static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
+static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label)
{
+ struct ip6_flowlabel *lfl;
+
fl->label = label & IPV6_FLOWLABEL_MASK;
write_lock_bh(&ip6_fl_lock);
@@ -163,12 +165,26 @@ static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
for (;;) {
fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK;
if (fl->label) {
- struct ip6_flowlabel *lfl;
lfl = __fl_lookup(fl->label);
if (lfl == NULL)
break;
}
}
+ } else {
+ /*
+ * we dropper the ip6_fl_lock, so this entry could reappear
+ * and we need to recheck with it.
+ *
+ * OTOH no need to search the active socket first, like it is
+ * done in ipv6_flowlabel_opt - sock is locked, so new entry
+ * with the same label can only appear on another sock
+ */
+ lfl = __fl_lookup(fl->label);
+ if (lfl != NULL) {
+ atomic_inc(&lfl->users);
+ write_unlock_bh(&ip6_fl_lock);
+ return lfl;
+ }
}
fl->lastuse = jiffies;
@@ -176,7 +192,7 @@ static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
fl_ht[FL_HASH(fl->label)] = fl;
atomic_inc(&fl_size);
write_unlock_bh(&ip6_fl_lock);
- return 0;
+ return NULL;
}
@@ -190,14 +206,17 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label)
label &= IPV6_FLOWLABEL_MASK;
+ read_lock_bh(&ip6_sk_fl_lock);
for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) {
struct ip6_flowlabel *fl = sfl->fl;
if (fl->label == label) {
fl->lastuse = jiffies;
atomic_inc(&fl->users);
+ read_unlock_bh(&ip6_sk_fl_lock);
return fl;
}
}
+ read_unlock_bh(&ip6_sk_fl_lock);
return NULL;
}
@@ -409,6 +428,16 @@ static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2)
return 0;
}
+static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
+ struct ip6_flowlabel *fl)
+{
+ write_lock_bh(&ip6_sk_fl_lock);
+ sfl->fl = fl;
+ sfl->next = np->ipv6_fl_list;
+ np->ipv6_fl_list = sfl;
+ write_unlock_bh(&ip6_sk_fl_lock);
+}
+
int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
{
int err;
@@ -416,7 +445,8 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
struct in6_flowlabel_req freq;
struct ipv6_fl_socklist *sfl1=NULL;
struct ipv6_fl_socklist *sfl, **sflp;
- struct ip6_flowlabel *fl;
+ struct ip6_flowlabel *fl, *fl1 = NULL;
+
if (optlen < sizeof(freq))
return -EINVAL;
@@ -472,8 +502,6 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
if (freq.flr_label) {
- struct ip6_flowlabel *fl1 = NULL;
-
err = -EEXIST;
read_lock_bh(&ip6_sk_fl_lock);
for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) {
@@ -492,6 +520,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
if (fl1 == NULL)
fl1 = fl_lookup(freq.flr_label);
if (fl1) {
+recheck:
err = -EEXIST;
if (freq.flr_flags&IPV6_FL_F_EXCL)
goto release;
@@ -513,11 +542,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
fl1->linger = fl->linger;
if ((long)(fl->expires - fl1->expires) > 0)
fl1->expires = fl->expires;
- write_lock_bh(&ip6_sk_fl_lock);
- sfl1->fl = fl1;
- sfl1->next = np->ipv6_fl_list;
- np->ipv6_fl_list = sfl1;
- write_unlock_bh(&ip6_sk_fl_lock);
+ fl_link(np, sfl1, fl1);
fl_free(fl);
return 0;
@@ -534,9 +559,9 @@ release:
if (sfl1 == NULL || (err = mem_check(sk)) != 0)
goto done;
- err = fl_intern(fl, freq.flr_label);
- if (err)
- goto done;
+ fl1 = fl_intern(fl, freq.flr_label);
+ if (fl1 != NULL)
+ goto recheck;
if (!freq.flr_label) {
if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
@@ -545,9 +570,7 @@ release:
}
}
- sfl1->fl = fl;
- sfl1->next = np->ipv6_fl_list;
- np->ipv6_fl_list = sfl1;
+ fl_link(np, sfl1, fl);
return 0;
default:
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 9149fc23975..fac6f7f9dd7 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -125,7 +125,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
}
if (hdr->nexthdr == NEXTHDR_HOP) {
- if (ipv6_parse_hopopts(&skb) < 0) {
+ if (ipv6_parse_hopopts(skb) < 0) {
IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
rcu_read_unlock();
return 0;
@@ -149,7 +149,7 @@ out:
*/
-static inline int ip6_input_finish(struct sk_buff *skb)
+static int ip6_input_finish(struct sk_buff *skb)
{
struct inet6_protocol *ipprot;
struct sock *raw_sk;
@@ -199,7 +199,7 @@ resubmit:
!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
goto discard;
- ret = ipprot->handler(&skb);
+ ret = ipprot->handler(skb);
if (ret > 0)
goto resubmit;
else if (ret == 0)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 011082ed921..13565dfb1b4 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -70,7 +70,7 @@ static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *f
spin_unlock_bh(&ip6_id_lock);
}
-static inline int ip6_output_finish(struct sk_buff *skb)
+static int ip6_output_finish(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 28fc8edfdc3..80ef2a1d39f 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -411,8 +411,15 @@ static int ipcomp6_init_state(struct xfrm_state *x)
goto out;
x->props.header_len = 0;
- if (x->props.mode == XFRM_MODE_TUNNEL)
+ switch (x->props.mode) {
+ case XFRM_MODE_BEET:
+ case XFRM_MODE_TRANSPORT:
+ break;
+ case XFRM_MODE_TUNNEL:
x->props.header_len += sizeof(struct ipv6hdr);
+ default:
+ goto error;
+ }
mutex_lock(&ipcomp6_resource_mutex);
if (!ipcomp6_alloc_scratches())
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 6cc33dc83d1..20cfc90d559 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1658,30 +1658,26 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f
struct inet6_dev *idev;
int ret;
- if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME ||
- ctl->ctl_name == NET_NEIGH_REACHABLE_TIME)
+ if ((strcmp(ctl->procname, "retrans_time") == 0) ||
+ (strcmp(ctl->procname, "base_reachable_time") == 0))
ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default");
- switch (ctl->ctl_name) {
- case NET_NEIGH_RETRANS_TIME:
+ if (strcmp(ctl->procname, "retrans_time") == 0)
ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
- break;
- case NET_NEIGH_REACHABLE_TIME:
+
+ else if (strcmp(ctl->procname, "base_reachable_time") == 0)
ret = proc_dointvec_jiffies(ctl, write,
filp, buffer, lenp, ppos);
- break;
- case NET_NEIGH_RETRANS_TIME_MS:
- case NET_NEIGH_REACHABLE_TIME_MS:
+
+ else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) ||
+ (strcmp(ctl->procname, "base_reacable_time_ms") == 0))
ret = proc_dointvec_ms_jiffies(ctl, write,
filp, buffer, lenp, ppos);
- break;
- default:
+ else
ret = -1;
- }
if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) {
- if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME ||
- ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS)
+ if (ctl->data == &idev->nd_parms->base_reachable_time)
idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time);
idev->tstamp = jiffies;
inet6_ifinfo_notify(RTM_NEWLINK, idev);
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 38b14961391..b1326c2bf8a 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -68,15 +68,15 @@ static void nf_ip6_saveroute(const struct sk_buff *skb, struct nf_info *info)
}
}
-static int nf_ip6_reroute(struct sk_buff **pskb, const struct nf_info *info)
+static int nf_ip6_reroute(struct sk_buff *skb, const struct nf_info *info)
{
struct ip6_rt_info *rt_info = nf_info_reroute(info);
if (info->hook == NF_IP6_LOCAL_OUT) {
- struct ipv6hdr *iph = ipv6_hdr(*pskb);
+ struct ipv6hdr *iph = ipv6_hdr(skb);
if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
!ipv6_addr_equal(&iph->saddr, &rt_info->saddr))
- return ip6_route_me_harder(*pskb);
+ return ip6_route_me_harder(skb);
}
return 0;
}
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 0473145ac53..6413a30d9f6 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -332,6 +332,7 @@ static int
ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
{
int diff;
+ int err;
struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload;
if (v->data_len < sizeof(*user_iph))
@@ -344,25 +345,18 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- struct sk_buff *newskb;
-
- newskb = skb_copy_expand(e->skb,
- skb_headroom(e->skb),
- diff,
- GFP_ATOMIC);
- if (newskb == NULL) {
+ err = pskb_expand_head(e->skb, 0,
+ diff - skb_tailroom(e->skb),
+ GFP_ATOMIC);
+ if (err) {
printk(KERN_WARNING "ip6_queue: OOM "
"in mangle, dropping packet\n");
- return -ENOMEM;
+ return err;
}
- if (e->skb->sk)
- skb_set_owner_w(newskb, e->skb->sk);
- kfree_skb(e->skb);
- e->skb = newskb;
}
skb_put(e->skb, diff);
}
- if (!skb_make_writable(&e->skb, v->data_len))
+ if (!skb_make_writable(e->skb, v->data_len))
return -ENOMEM;
skb_copy_to_linear_data(e->skb, v->payload, v->data_len);
e->skb->ip_summed = CHECKSUM_NONE;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index cd9df02bb85..acaba153793 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -205,7 +205,7 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
}
static unsigned int
-ip6t_error(struct sk_buff **pskb,
+ip6t_error(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -350,7 +350,7 @@ static void trace_packet(struct sk_buff *skb,
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned int
-ip6t_do_table(struct sk_buff **pskb,
+ip6t_do_table(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
@@ -389,17 +389,17 @@ ip6t_do_table(struct sk_buff **pskb,
do {
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
- if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6,
+ if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
&protoff, &offset, &hotdrop)) {
struct ip6t_entry_target *t;
if (IP6T_MATCH_ITERATE(e, do_match,
- *pskb, in, out,
+ skb, in, out,
offset, protoff, &hotdrop) != 0)
goto no_match;
ADD_COUNTER(e->counters,
- ntohs(ipv6_hdr(*pskb)->payload_len)
+ ntohs(ipv6_hdr(skb)->payload_len)
+ IPV6_HDR_LEN,
1);
@@ -409,8 +409,8 @@ ip6t_do_table(struct sk_buff **pskb,
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* The packet is traced: log it */
- if (unlikely((*pskb)->nf_trace))
- trace_packet(*pskb, hook, in, out,
+ if (unlikely(skb->nf_trace))
+ trace_packet(skb, hook, in, out,
table->name, private, e);
#endif
/* Standard target? */
@@ -448,7 +448,7 @@ ip6t_do_table(struct sk_buff **pskb,
((struct ip6t_entry *)table_base)->comefrom
= 0xeeeeeeec;
#endif
- verdict = t->u.kernel.target->target(pskb,
+ verdict = t->u.kernel.target->target(skb,
in, out,
hook,
t->u.kernel.target,
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index ad4d94310b8..9afc836fd45 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -18,7 +18,7 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
MODULE_DESCRIPTION("IP6 tables Hop Limit modification module");
MODULE_LICENSE("GPL");
-static unsigned int ip6t_hl_target(struct sk_buff **pskb,
+static unsigned int ip6t_hl_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -29,10 +29,10 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
const struct ip6t_HL_info *info = targinfo;
int new_hl;
- if (!skb_make_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return NF_DROP;
- ip6h = ipv6_hdr(*pskb);
+ ip6h = ipv6_hdr(skb);
switch (info->mode) {
case IP6T_HL_SET:
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 6ab99001dcc..7a48c342df4 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -431,7 +431,7 @@ ip6t_log_packet(unsigned int pf,
}
static unsigned int
-ip6t_log_target(struct sk_buff **pskb,
+ip6t_log_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -445,8 +445,7 @@ ip6t_log_target(struct sk_buff **pskb,
li.u.log.level = loginfo->level;
li.u.log.logflags = loginfo->logflags;
- ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
- loginfo->prefix);
+ ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix);
return XT_CONTINUE;
}
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 3fd08d5567a..1a7d2917545 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -172,7 +172,7 @@ send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
}
-static unsigned int reject6_target(struct sk_buff **pskb,
+static unsigned int reject6_target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -187,25 +187,25 @@ static unsigned int reject6_target(struct sk_buff **pskb,
must return an absolute verdict. --RR */
switch (reject->with) {
case IP6T_ICMP6_NO_ROUTE:
- send_unreach(*pskb, ICMPV6_NOROUTE, hooknum);
+ send_unreach(skb, ICMPV6_NOROUTE, hooknum);
break;
case IP6T_ICMP6_ADM_PROHIBITED:
- send_unreach(*pskb, ICMPV6_ADM_PROHIBITED, hooknum);
+ send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum);
break;
case IP6T_ICMP6_NOT_NEIGHBOUR:
- send_unreach(*pskb, ICMPV6_NOT_NEIGHBOUR, hooknum);
+ send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum);
break;
case IP6T_ICMP6_ADDR_UNREACH:
- send_unreach(*pskb, ICMPV6_ADDR_UNREACH, hooknum);
+ send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum);
break;
case IP6T_ICMP6_PORT_UNREACH:
- send_unreach(*pskb, ICMPV6_PORT_UNREACH, hooknum);
+ send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum);
break;
case IP6T_ICMP6_ECHOREPLY:
/* Do nothing */
break;
case IP6T_TCP_RESET:
- send_reset(*pskb);
+ send_reset(skb);
break;
default:
if (net_ratelimit())
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 7e32e2aaf7f..1d26b202bf3 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -60,32 +60,32 @@ static struct xt_table packet_filter = {
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ip6t_do_table(pskb, hook, in, out, &packet_filter);
+ return ip6t_do_table(skb, hook, in, out, &packet_filter);
}
static unsigned int
ip6t_local_out_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
#if 0
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr)
- || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (skb->len < sizeof(struct iphdr)
+ || ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("ip6t_hook: happy cracking.\n");
return NF_ACCEPT;
}
#endif
- return ip6t_do_table(pskb, hook, in, out, &packet_filter);
+ return ip6t_do_table(skb, hook, in, out, &packet_filter);
}
static struct nf_hook_ops ip6t_ops[] = {
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index f0a9efa67fb..a0b6381f1e8 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -68,17 +68,17 @@ static struct xt_table packet_mangler = {
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_route_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ip6t_do_table(pskb, hook, in, out, &packet_mangler);
+ return ip6t_do_table(skb, hook, in, out, &packet_mangler);
}
static unsigned int
ip6t_local_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -91,8 +91,8 @@ ip6t_local_hook(unsigned int hook,
#if 0
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct iphdr)
- || ip_hdrlen(*pskb) < sizeof(struct iphdr)) {
+ if (skb->len < sizeof(struct iphdr)
+ || ip_hdrlen(skb) < sizeof(struct iphdr)) {
if (net_ratelimit())
printk("ip6t_hook: happy cracking.\n");
return NF_ACCEPT;
@@ -100,22 +100,22 @@ ip6t_local_hook(unsigned int hook,
#endif
/* save source/dest address, mark, hoplimit, flowlabel, priority, */
- memcpy(&saddr, &ipv6_hdr(*pskb)->saddr, sizeof(saddr));
- memcpy(&daddr, &ipv6_hdr(*pskb)->daddr, sizeof(daddr));
- mark = (*pskb)->mark;
- hop_limit = ipv6_hdr(*pskb)->hop_limit;
+ memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr));
+ memcpy(&daddr, &ipv6_hdr(skb)->daddr, sizeof(daddr));
+ mark = skb->mark;
+ hop_limit = ipv6_hdr(skb)->hop_limit;
/* flowlabel and prio (includes version, which shouldn't change either */
- flowlabel = *((u_int32_t *)ipv6_hdr(*pskb));
+ flowlabel = *((u_int32_t *)ipv6_hdr(skb));
- ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler);
+ ret = ip6t_do_table(skb, hook, in, out, &packet_mangler);
if (ret != NF_DROP && ret != NF_STOLEN
- && (memcmp(&ipv6_hdr(*pskb)->saddr, &saddr, sizeof(saddr))
- || memcmp(&ipv6_hdr(*pskb)->daddr, &daddr, sizeof(daddr))
- || (*pskb)->mark != mark
- || ipv6_hdr(*pskb)->hop_limit != hop_limit))
- return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP;
+ && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
+ || memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr))
+ || skb->mark != mark
+ || ipv6_hdr(skb)->hop_limit != hop_limit))
+ return ip6_route_me_harder(skb) == 0 ? ret : NF_DROP;
return ret;
}
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index ec290e4ebdd..8f7109f991e 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -46,12 +46,12 @@ static struct xt_table packet_raw = {
/* The work comes in here from netfilter.c. */
static unsigned int
ip6t_hook(unsigned int hook,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return ip6t_do_table(pskb, hook, in, out, &packet_raw);
+ return ip6t_do_table(skb, hook, in, out, &packet_raw);
}
static struct nf_hook_ops ip6t_ops[] = {
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 37a3db92695..ad74bab0504 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -18,6 +18,7 @@
#include <linux/icmp.h>
#include <linux/sysctl.h>
#include <net/ipv6.h>
+#include <net/inet_frag.h>
#include <linux/netfilter_ipv6.h>
#include <net/netfilter/nf_conntrack.h>
@@ -145,7 +146,7 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
}
static unsigned int ipv6_confirm(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -155,12 +156,12 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
struct nf_conntrack_helper *helper;
enum ip_conntrack_info ctinfo;
unsigned int ret, protoff;
- unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
- unsigned char pnum = ipv6_hdr(*pskb)->nexthdr;
+ unsigned int extoff = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
+ unsigned char pnum = ipv6_hdr(skb)->nexthdr;
/* This is where we call the helper: as the packet goes out. */
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
goto out;
@@ -172,23 +173,23 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
if (!helper)
goto out;
- protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
- (*pskb)->len - extoff);
- if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) {
+ protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum,
+ skb->len - extoff);
+ if (protoff > skb->len || pnum == NEXTHDR_FRAGMENT) {
pr_debug("proto header not found\n");
return NF_ACCEPT;
}
- ret = helper->help(pskb, protoff, ct, ctinfo);
+ ret = helper->help(skb, protoff, ct, ctinfo);
if (ret != NF_ACCEPT)
return ret;
out:
/* We've seen it coming out the other side: confirm it */
- return nf_conntrack_confirm(pskb);
+ return nf_conntrack_confirm(skb);
}
static unsigned int ipv6_defrag(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
@@ -196,17 +197,17 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
struct sk_buff *reasm;
/* Previously seen (loopback)? */
- if ((*pskb)->nfct)
+ if (skb->nfct)
return NF_ACCEPT;
- reasm = nf_ct_frag6_gather(*pskb);
+ reasm = nf_ct_frag6_gather(skb);
/* queued */
if (reasm == NULL)
return NF_STOLEN;
/* error occured or not fragmented */
- if (reasm == *pskb)
+ if (reasm == skb)
return NF_ACCEPT;
nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
@@ -216,12 +217,12 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
}
static unsigned int ipv6_conntrack_in(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- struct sk_buff *reasm = (*pskb)->nfct_reasm;
+ struct sk_buff *reasm = skb->nfct_reasm;
/* This packet is fragmented and has reassembled packet. */
if (reasm) {
@@ -229,32 +230,32 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
if (!reasm->nfct) {
unsigned int ret;
- ret = nf_conntrack_in(PF_INET6, hooknum, &reasm);
+ ret = nf_conntrack_in(PF_INET6, hooknum, reasm);
if (ret != NF_ACCEPT)
return ret;
}
nf_conntrack_get(reasm->nfct);
- (*pskb)->nfct = reasm->nfct;
- (*pskb)->nfctinfo = reasm->nfctinfo;
+ skb->nfct = reasm->nfct;
+ skb->nfctinfo = reasm->nfctinfo;
return NF_ACCEPT;
}
- return nf_conntrack_in(PF_INET6, hooknum, pskb);
+ return nf_conntrack_in(PF_INET6, hooknum, skb);
}
static unsigned int ipv6_conntrack_local(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
/* root is playing with raw sockets. */
- if ((*pskb)->len < sizeof(struct ipv6hdr)) {
+ if (skb->len < sizeof(struct ipv6hdr)) {
if (net_ratelimit())
printk("ipv6_conntrack_local: packet too short\n");
return NF_ACCEPT;
}
- return ipv6_conntrack_in(hooknum, pskb, in, out, okfn);
+ return ipv6_conntrack_in(hooknum, skb, in, out, okfn);
}
static struct nf_hook_ops ipv6_conntrack_ops[] = {
@@ -305,9 +306,8 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = {
#ifdef CONFIG_SYSCTL
static ctl_table nf_ct_ipv6_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
.procname = "nf_conntrack_frag6_timeout",
- .data = &nf_ct_frag6_timeout,
+ .data = &nf_frags_ctl.timeout,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
@@ -315,7 +315,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = {
{
.ctl_name = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
.procname = "nf_conntrack_frag6_low_thresh",
- .data = &nf_ct_frag6_low_thresh,
+ .data = &nf_frags_ctl.low_thresh,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = &proc_dointvec,
@@ -323,7 +323,7 @@ static ctl_table nf_ct_ipv6_sysctl_table[] = {
{
.ctl_name = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
.procname = "nf_conntrack_frag6_high_thresh",
- .data = &nf_ct_frag6_high_thresh,
+ .data = &nf_frags_ctl.high_thresh,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = &proc_dointvec,
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index fbdc66920de..fd9123f3dc0 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -260,7 +260,6 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
static struct ctl_table_header *icmpv6_sysctl_header;
static struct ctl_table icmpv6_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
.procname = "nf_conntrack_icmpv6_timeout",
.data = &nf_ct_icmpv6_timeout,
.maxlen = sizeof(unsigned int),
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 25442a8c1ba..e170c67c47a 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -31,6 +31,7 @@
#include <net/sock.h>
#include <net/snmp.h>
+#include <net/inet_frag.h>
#include <net/ipv6.h>
#include <net/protocol.h>
@@ -48,10 +49,6 @@
#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
-unsigned int nf_ct_frag6_high_thresh __read_mostly = 256*1024;
-unsigned int nf_ct_frag6_low_thresh __read_mostly = 192*1024;
-unsigned long nf_ct_frag6_timeout __read_mostly = IPV6_FRAG_TIMEOUT;
-
struct nf_ct_frag6_skb_cb
{
struct inet6_skb_parm h;
@@ -63,51 +60,24 @@ struct nf_ct_frag6_skb_cb
struct nf_ct_frag6_queue
{
- struct hlist_node list;
- struct list_head lru_list; /* lru list member */
+ struct inet_frag_queue q;
__be32 id; /* fragment id */
struct in6_addr saddr;
struct in6_addr daddr;
- spinlock_t lock;
- atomic_t refcnt;
- struct timer_list timer; /* expire timer */
- struct sk_buff *fragments;
- int len;
- int meat;
- ktime_t stamp;
unsigned int csum;
- __u8 last_in; /* has first/last segment arrived? */
-#define COMPLETE 4
-#define FIRST_IN 2
-#define LAST_IN 1
__u16 nhoffset;
};
-/* Hash table. */
-
-#define FRAG6Q_HASHSZ 64
-
-static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ];
-static DEFINE_RWLOCK(nf_ct_frag6_lock);
-static u32 nf_ct_frag6_hash_rnd;
-static LIST_HEAD(nf_ct_frag6_lru_list);
-int nf_ct_frag6_nqueues = 0;
-
-static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq)
-{
- hlist_del(&fq->list);
- list_del(&fq->lru_list);
- nf_ct_frag6_nqueues--;
-}
+struct inet_frags_ctl nf_frags_ctl __read_mostly = {
+ .high_thresh = 256 * 1024,
+ .low_thresh = 192 * 1024,
+ .timeout = IPV6_FRAG_TIMEOUT,
+ .secret_interval = 10 * 60 * HZ,
+};
-static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
-{
- write_lock(&nf_ct_frag6_lock);
- __fq_unlink(fq);
- write_unlock(&nf_ct_frag6_lock);
-}
+static struct inet_frags nf_frags;
static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
struct in6_addr *daddr)
@@ -120,7 +90,7 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
a += JHASH_GOLDEN_RATIO;
b += JHASH_GOLDEN_RATIO;
- c += nf_ct_frag6_hash_rnd;
+ c += nf_frags.rnd;
__jhash_mix(a, b, c);
a += (__force u32)saddr->s6_addr32[3];
@@ -133,100 +103,38 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
c += (__force u32)id;
__jhash_mix(a, b, c);
- return c & (FRAG6Q_HASHSZ - 1);
+ return c & (INETFRAGS_HASHSZ - 1);
}
-static struct timer_list nf_ct_frag6_secret_timer;
-int nf_ct_frag6_secret_interval = 10 * 60 * HZ;
-
-static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
+static unsigned int nf_hashfn(struct inet_frag_queue *q)
{
- unsigned long now = jiffies;
- int i;
-
- write_lock(&nf_ct_frag6_lock);
- get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
- for (i = 0; i < FRAG6Q_HASHSZ; i++) {
- struct nf_ct_frag6_queue *q;
- struct hlist_node *p, *n;
-
- hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) {
- unsigned int hval = ip6qhashfn(q->id,
- &q->saddr,
- &q->daddr);
- if (hval != i) {
- hlist_del(&q->list);
- /* Relink to new hash chain. */
- hlist_add_head(&q->list,
- &nf_ct_frag6_hash[hval]);
- }
- }
- }
- write_unlock(&nf_ct_frag6_lock);
+ struct nf_ct_frag6_queue *nq;
- mod_timer(&nf_ct_frag6_secret_timer, now + nf_ct_frag6_secret_interval);
+ nq = container_of(q, struct nf_ct_frag6_queue, q);
+ return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr);
}
-atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0);
-
-/* Memory Tracking Functions. */
-static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
+static void nf_skb_free(struct sk_buff *skb)
{
- if (work)
- *work -= skb->truesize;
- atomic_sub(skb->truesize, &nf_ct_frag6_mem);
if (NFCT_FRAG6_CB(skb)->orig)
kfree_skb(NFCT_FRAG6_CB(skb)->orig);
-
- kfree_skb(skb);
}
-static inline void frag_free_queue(struct nf_ct_frag6_queue *fq,
- unsigned int *work)
+/* Memory Tracking Functions. */
+static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
{
if (work)
- *work -= sizeof(struct nf_ct_frag6_queue);
- atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
- kfree(fq);
-}
-
-static inline struct nf_ct_frag6_queue *frag_alloc_queue(void)
-{
- struct nf_ct_frag6_queue *fq = kmalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC);
-
- if (!fq)
- return NULL;
- atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
- return fq;
+ *work -= skb->truesize;
+ atomic_sub(skb->truesize, &nf_frags.mem);
+ nf_skb_free(skb);
+ kfree_skb(skb);
}
/* Destruction primitives. */
-/* Complete destruction of fq. */
-static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq,
- unsigned int *work)
+static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
{
- struct sk_buff *fp;
-
- BUG_TRAP(fq->last_in&COMPLETE);
- BUG_TRAP(del_timer(&fq->timer) == 0);
-
- /* Release all fragment data. */
- fp = fq->fragments;
- while (fp) {
- struct sk_buff *xp = fp->next;
-
- frag_kfree_skb(fp, work);
- fp = xp;
- }
-
- frag_free_queue(fq, work);
-}
-
-static __inline__ void fq_put(struct nf_ct_frag6_queue *fq, unsigned int *work)
-{
- if (atomic_dec_and_test(&fq->refcnt))
- nf_ct_frag6_destroy(fq, work);
+ inet_frag_put(&fq->q, &nf_frags);
}
/* Kill fq entry. It is not destroyed immediately,
@@ -234,151 +142,58 @@ static __inline__ void fq_put(struct nf_ct_frag6_queue *fq, unsigned int *work)
*/
static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
{
- if (del_timer(&fq->timer))
- atomic_dec(&fq->refcnt);
-
- if (!(fq->last_in & COMPLETE)) {
- fq_unlink(fq);
- atomic_dec(&fq->refcnt);
- fq->last_in |= COMPLETE;
- }
+ inet_frag_kill(&fq->q, &nf_frags);
}
static void nf_ct_frag6_evictor(void)
{
- struct nf_ct_frag6_queue *fq;
- struct list_head *tmp;
- unsigned int work;
-
- work = atomic_read(&nf_ct_frag6_mem);
- if (work <= nf_ct_frag6_low_thresh)
- return;
-
- work -= nf_ct_frag6_low_thresh;
- while (work > 0) {
- read_lock(&nf_ct_frag6_lock);
- if (list_empty(&nf_ct_frag6_lru_list)) {
- read_unlock(&nf_ct_frag6_lock);
- return;
- }
- tmp = nf_ct_frag6_lru_list.next;
- BUG_ON(tmp == NULL);
- fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list);
- atomic_inc(&fq->refcnt);
- read_unlock(&nf_ct_frag6_lock);
-
- spin_lock(&fq->lock);
- if (!(fq->last_in&COMPLETE))
- fq_kill(fq);
- spin_unlock(&fq->lock);
-
- fq_put(fq, &work);
- }
+ inet_frag_evictor(&nf_frags);
}
static void nf_ct_frag6_expire(unsigned long data)
{
- struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data;
+ struct nf_ct_frag6_queue *fq;
+
+ fq = container_of((struct inet_frag_queue *)data,
+ struct nf_ct_frag6_queue, q);
- spin_lock(&fq->lock);
+ spin_lock(&fq->q.lock);
- if (fq->last_in & COMPLETE)
+ if (fq->q.last_in & COMPLETE)
goto out;
fq_kill(fq);
out:
- spin_unlock(&fq->lock);
- fq_put(fq, NULL);
+ spin_unlock(&fq->q.lock);
+ fq_put(fq);
}
/* Creation primitives. */
-static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
- struct nf_ct_frag6_queue *fq_in)
+static __inline__ struct nf_ct_frag6_queue *
+fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
{
- struct nf_ct_frag6_queue *fq;
-#ifdef CONFIG_SMP
- struct hlist_node *n;
-#endif
-
- write_lock(&nf_ct_frag6_lock);
-#ifdef CONFIG_SMP
- hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) {
- if (fq->id == fq_in->id &&
- ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
- ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
- atomic_inc(&fq->refcnt);
- write_unlock(&nf_ct_frag6_lock);
- fq_in->last_in |= COMPLETE;
- fq_put(fq_in, NULL);
- return fq;
- }
- }
-#endif
- fq = fq_in;
-
- if (!mod_timer(&fq->timer, jiffies + nf_ct_frag6_timeout))
- atomic_inc(&fq->refcnt);
-
- atomic_inc(&fq->refcnt);
- hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]);
- INIT_LIST_HEAD(&fq->lru_list);
- list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
- nf_ct_frag6_nqueues++;
- write_unlock(&nf_ct_frag6_lock);
- return fq;
-}
+ struct inet_frag_queue *q;
+ struct ip6_create_arg arg;
+ unsigned int hash;
+ arg.id = id;
+ arg.src = src;
+ arg.dst = dst;
+ hash = ip6qhashfn(id, src, dst);
-static struct nf_ct_frag6_queue *
-nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, struct in6_addr *dst)
-{
- struct nf_ct_frag6_queue *fq;
-
- if ((fq = frag_alloc_queue()) == NULL) {
- pr_debug("Can't alloc new queue\n");
+ q = inet_frag_find(&nf_frags, &arg, hash);
+ if (q == NULL)
goto oom;
- }
-
- memset(fq, 0, sizeof(struct nf_ct_frag6_queue));
-
- fq->id = id;
- ipv6_addr_copy(&fq->saddr, src);
- ipv6_addr_copy(&fq->daddr, dst);
- setup_timer(&fq->timer, nf_ct_frag6_expire, (unsigned long)fq);
- spin_lock_init(&fq->lock);
- atomic_set(&fq->refcnt, 1);
-
- return nf_ct_frag6_intern(hash, fq);
+ return container_of(q, struct nf_ct_frag6_queue, q);
oom:
+ pr_debug("Can't alloc new queue\n");
return NULL;
}
-static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
-{
- struct nf_ct_frag6_queue *fq;
- struct hlist_node *n;
- unsigned int hash = ip6qhashfn(id, src, dst);
-
- read_lock(&nf_ct_frag6_lock);
- hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) {
- if (fq->id == id &&
- ipv6_addr_equal(src, &fq->saddr) &&
- ipv6_addr_equal(dst, &fq->daddr)) {
- atomic_inc(&fq->refcnt);
- read_unlock(&nf_ct_frag6_lock);
- return fq;
- }
- }
- read_unlock(&nf_ct_frag6_lock);
-
- return nf_ct_frag6_create(hash, id, src, dst);
-}
-
static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
struct frag_hdr *fhdr, int nhoff)
@@ -386,7 +201,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
struct sk_buff *prev, *next;
int offset, end;
- if (fq->last_in & COMPLETE) {
+ if (fq->q.last_in & COMPLETE) {
pr_debug("Allready completed\n");
goto err;
}
@@ -412,13 +227,13 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
/* If we already have some bits beyond end
* or have different end, the segment is corrupted.
*/
- if (end < fq->len ||
- ((fq->last_in & LAST_IN) && end != fq->len)) {
+ if (end < fq->q.len ||
+ ((fq->q.last_in & LAST_IN) && end != fq->q.len)) {
pr_debug("already received last fragment\n");
goto err;
}
- fq->last_in |= LAST_IN;
- fq->len = end;
+ fq->q.last_in |= LAST_IN;
+ fq->q.len = end;
} else {
/* Check if the fragment is rounded to 8 bytes.
* Required by the RFC.
@@ -430,13 +245,13 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
pr_debug("end of fragment not rounded to 8 bytes.\n");
return -1;
}
- if (end > fq->len) {
+ if (end > fq->q.len) {
/* Some bits beyond end -> corruption. */
- if (fq->last_in & LAST_IN) {
+ if (fq->q.last_in & LAST_IN) {
pr_debug("last packet already reached.\n");
goto err;
}
- fq->len = end;
+ fq->q.len = end;
}
}
@@ -458,7 +273,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
* this fragment, right?
*/
prev = NULL;
- for (next = fq->fragments; next != NULL; next = next->next) {
+ for (next = fq->q.fragments; next != NULL; next = next->next) {
if (NFCT_FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
@@ -503,7 +318,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
/* next fragment */
NFCT_FRAG6_CB(next)->offset += i;
- fq->meat -= i;
+ fq->q.meat -= i;
if (next->ip_summed != CHECKSUM_UNNECESSARY)
next->ip_summed = CHECKSUM_NONE;
break;
@@ -518,9 +333,9 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
if (prev)
prev->next = next;
else
- fq->fragments = next;
+ fq->q.fragments = next;
- fq->meat -= free_it->len;
+ fq->q.meat -= free_it->len;
frag_kfree_skb(free_it, NULL);
}
}
@@ -532,23 +347,23 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
if (prev)
prev->next = skb;
else
- fq->fragments = skb;
+ fq->q.fragments = skb;
skb->dev = NULL;
- fq->stamp = skb->tstamp;
- fq->meat += skb->len;
- atomic_add(skb->truesize, &nf_ct_frag6_mem);
+ fq->q.stamp = skb->tstamp;
+ fq->q.meat += skb->len;
+ atomic_add(skb->truesize, &nf_frags.mem);
/* The first fragment.
* nhoffset is obtained from the first fragment, of course.
*/
if (offset == 0) {
fq->nhoffset = nhoff;
- fq->last_in |= FIRST_IN;
+ fq->q.last_in |= FIRST_IN;
}
- write_lock(&nf_ct_frag6_lock);
- list_move_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
- write_unlock(&nf_ct_frag6_lock);
+ write_lock(&nf_frags.lock);
+ list_move_tail(&fq->q.lru_list, &nf_frags.lru_list);
+ write_unlock(&nf_frags.lock);
return 0;
err:
@@ -567,7 +382,7 @@ err:
static struct sk_buff *
nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
{
- struct sk_buff *fp, *op, *head = fq->fragments;
+ struct sk_buff *fp, *op, *head = fq->q.fragments;
int payload_len;
fq_kill(fq);
@@ -577,7 +392,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
/* Unfragmented part is taken from the first segment. */
payload_len = ((head->data - skb_network_header(head)) -
- sizeof(struct ipv6hdr) + fq->len -
+ sizeof(struct ipv6hdr) + fq->q.len -
sizeof(struct frag_hdr));
if (payload_len > IPV6_MAXPLEN) {
pr_debug("payload len is too large.\n");
@@ -614,7 +429,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
clone->ip_summed = head->ip_summed;
NFCT_FRAG6_CB(clone)->orig = NULL;
- atomic_add(clone->truesize, &nf_ct_frag6_mem);
+ atomic_add(clone->truesize, &nf_frags.mem);
}
/* We have to remove fragment header from datagram and to relocate
@@ -628,7 +443,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
skb_shinfo(head)->frag_list = head->next;
skb_reset_transport_header(head);
skb_push(head, head->data - skb_network_header(head));
- atomic_sub(head->truesize, &nf_ct_frag6_mem);
+ atomic_sub(head->truesize, &nf_frags.mem);
for (fp=head->next; fp; fp = fp->next) {
head->data_len += fp->len;
@@ -638,12 +453,12 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
else if (head->ip_summed == CHECKSUM_COMPLETE)
head->csum = csum_add(head->csum, fp->csum);
head->truesize += fp->truesize;
- atomic_sub(fp->truesize, &nf_ct_frag6_mem);
+ atomic_sub(fp->truesize, &nf_frags.mem);
}
head->next = NULL;
head->dev = dev;
- head->tstamp = fq->stamp;
+ head->tstamp = fq->q.stamp;
ipv6_hdr(head)->payload_len = htons(payload_len);
/* Yes, and fold redundant checksum back. 8) */
@@ -652,7 +467,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
skb_network_header_len(head),
head->csum);
- fq->fragments = NULL;
+ fq->q.fragments = NULL;
/* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
fp = skb_shinfo(head)->frag_list;
@@ -788,7 +603,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
goto ret_orig;
}
- if (atomic_read(&nf_ct_frag6_mem) > nf_ct_frag6_high_thresh)
+ if (atomic_read(&nf_frags.mem) > nf_frags_ctl.high_thresh)
nf_ct_frag6_evictor();
fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
@@ -797,23 +612,23 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
goto ret_orig;
}
- spin_lock(&fq->lock);
+ spin_lock(&fq->q.lock);
if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
- spin_unlock(&fq->lock);
+ spin_unlock(&fq->q.lock);
pr_debug("Can't insert skb to queue\n");
- fq_put(fq, NULL);
+ fq_put(fq);
goto ret_orig;
}
- if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
+ if (fq->q.last_in == (FIRST_IN|LAST_IN) && fq->q.meat == fq->q.len) {
ret_skb = nf_ct_frag6_reasm(fq, dev);
if (ret_skb == NULL)
pr_debug("Can't reassemble fragmented packets\n");
}
- spin_unlock(&fq->lock);
+ spin_unlock(&fq->q.lock);
- fq_put(fq, NULL);
+ fq_put(fq);
return ret_skb;
ret_orig:
@@ -859,20 +674,23 @@ int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
int nf_ct_frag6_init(void)
{
- nf_ct_frag6_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
- (jiffies ^ (jiffies >> 6)));
-
- setup_timer(&nf_ct_frag6_secret_timer, nf_ct_frag6_secret_rebuild, 0);
- nf_ct_frag6_secret_timer.expires = jiffies
- + nf_ct_frag6_secret_interval;
- add_timer(&nf_ct_frag6_secret_timer);
+ nf_frags.ctl = &nf_frags_ctl;
+ nf_frags.hashfn = nf_hashfn;
+ nf_frags.constructor = ip6_frag_init;
+ nf_frags.destructor = NULL;
+ nf_frags.skb_free = nf_skb_free;
+ nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
+ nf_frags.match = ip6_frag_match;
+ nf_frags.frag_expire = nf_ct_frag6_expire;
+ inet_frags_init(&nf_frags);
return 0;
}
void nf_ct_frag6_cleanup(void)
{
- del_timer(&nf_ct_frag6_secret_timer);
- nf_ct_frag6_low_thresh = 0;
+ inet_frags_fini(&nf_frags);
+
+ nf_frags_ctl.low_thresh = 0;
nf_ct_frag6_evictor();
}
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index db945018579..be526ad9254 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -54,7 +54,7 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "RAW6: inuse %d\n",
fold_prot_inuse(&rawv6_prot));
seq_printf(seq, "FRAG6: inuse %d memory %d\n",
- ip6_frag_nqueues, atomic_read(&ip6_frag_mem));
+ ip6_frag_nqueues(), ip6_frag_mem());
return 0;
}
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 31601c99354..76c88a93b9b 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -42,6 +42,7 @@
#include <linux/icmpv6.h>
#include <linux/random.h>
#include <linux/jhash.h>
+#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/snmp.h>
@@ -53,11 +54,7 @@
#include <net/rawv6.h>
#include <net/ndisc.h>
#include <net/addrconf.h>
-
-int sysctl_ip6frag_high_thresh __read_mostly = 256*1024;
-int sysctl_ip6frag_low_thresh __read_mostly = 192*1024;
-
-int sysctl_ip6frag_time __read_mostly = IPV6_FRAG_TIMEOUT;
+#include <net/inet_frag.h>
struct ip6frag_skb_cb
{
@@ -74,53 +71,39 @@ struct ip6frag_skb_cb
struct frag_queue
{
- struct hlist_node list;
- struct list_head lru_list; /* lru list member */
+ struct inet_frag_queue q;
__be32 id; /* fragment id */
struct in6_addr saddr;
struct in6_addr daddr;
- spinlock_t lock;
- atomic_t refcnt;
- struct timer_list timer; /* expire timer */
- struct sk_buff *fragments;
- int len;
- int meat;
int iif;
- ktime_t stamp;
unsigned int csum;
- __u8 last_in; /* has first/last segment arrived? */
-#define COMPLETE 4
-#define FIRST_IN 2
-#define LAST_IN 1
__u16 nhoffset;
};
-/* Hash table. */
-
-#define IP6Q_HASHSZ 64
+struct inet_frags_ctl ip6_frags_ctl __read_mostly = {
+ .high_thresh = 256 * 1024,
+ .low_thresh = 192 * 1024,
+ .timeout = IPV6_FRAG_TIMEOUT,
+ .secret_interval = 10 * 60 * HZ,
+};
-static struct hlist_head ip6_frag_hash[IP6Q_HASHSZ];
-static DEFINE_RWLOCK(ip6_frag_lock);
-static u32 ip6_frag_hash_rnd;
-static LIST_HEAD(ip6_frag_lru_list);
-int ip6_frag_nqueues = 0;
+static struct inet_frags ip6_frags;
-static __inline__ void __fq_unlink(struct frag_queue *fq)
+int ip6_frag_nqueues(void)
{
- hlist_del(&fq->list);
- list_del(&fq->lru_list);
- ip6_frag_nqueues--;
+ return ip6_frags.nqueues;
}
-static __inline__ void fq_unlink(struct frag_queue *fq)
+int ip6_frag_mem(void)
{
- write_lock(&ip6_frag_lock);
- __fq_unlink(fq);
- write_unlock(&ip6_frag_lock);
+ return atomic_read(&ip6_frags.mem);
}
+static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
+ struct net_device *dev);
+
/*
* callers should be careful not to use the hash value outside the ipfrag_lock
* as doing so could race with ipfrag_hash_rnd being recalculated.
@@ -136,7 +119,7 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
a += JHASH_GOLDEN_RATIO;
b += JHASH_GOLDEN_RATIO;
- c += ip6_frag_hash_rnd;
+ c += ip6_frags.rnd;
__jhash_mix(a, b, c);
a += (__force u32)saddr->s6_addr32[3];
@@ -149,98 +132,54 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
c += (__force u32)id;
__jhash_mix(a, b, c);
- return c & (IP6Q_HASHSZ - 1);
+ return c & (INETFRAGS_HASHSZ - 1);
}
-static struct timer_list ip6_frag_secret_timer;
-int sysctl_ip6frag_secret_interval __read_mostly = 10 * 60 * HZ;
-
-static void ip6_frag_secret_rebuild(unsigned long dummy)
+static unsigned int ip6_hashfn(struct inet_frag_queue *q)
{
- unsigned long now = jiffies;
- int i;
-
- write_lock(&ip6_frag_lock);
- get_random_bytes(&ip6_frag_hash_rnd, sizeof(u32));
- for (i = 0; i < IP6Q_HASHSZ; i++) {
- struct frag_queue *q;
- struct hlist_node *p, *n;
-
- hlist_for_each_entry_safe(q, p, n, &ip6_frag_hash[i], list) {
- unsigned int hval = ip6qhashfn(q->id,
- &q->saddr,
- &q->daddr);
-
- if (hval != i) {
- hlist_del(&q->list);
+ struct frag_queue *fq;
- /* Relink to new hash chain. */
- hlist_add_head(&q->list,
- &ip6_frag_hash[hval]);
+ fq = container_of(q, struct frag_queue, q);
+ return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
+}
- }
- }
- }
- write_unlock(&ip6_frag_lock);
+int ip6_frag_match(struct inet_frag_queue *q, void *a)
+{
+ struct frag_queue *fq;
+ struct ip6_create_arg *arg = a;
- mod_timer(&ip6_frag_secret_timer, now + sysctl_ip6frag_secret_interval);
+ fq = container_of(q, struct frag_queue, q);
+ return (fq->id == arg->id &&
+ ipv6_addr_equal(&fq->saddr, arg->src) &&
+ ipv6_addr_equal(&fq->daddr, arg->dst));
}
-
-atomic_t ip6_frag_mem = ATOMIC_INIT(0);
+EXPORT_SYMBOL(ip6_frag_match);
/* Memory Tracking Functions. */
static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
{
if (work)
*work -= skb->truesize;
- atomic_sub(skb->truesize, &ip6_frag_mem);
+ atomic_sub(skb->truesize, &ip6_frags.mem);
kfree_skb(skb);
}
-static inline void frag_free_queue(struct frag_queue *fq, int *work)
+void ip6_frag_init(struct inet_frag_queue *q, void *a)
{
- if (work)
- *work -= sizeof(struct frag_queue);
- atomic_sub(sizeof(struct frag_queue), &ip6_frag_mem);
- kfree(fq);
-}
+ struct frag_queue *fq = container_of(q, struct frag_queue, q);
+ struct ip6_create_arg *arg = a;
-static inline struct frag_queue *frag_alloc_queue(void)
-{
- struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC);
-
- if(!fq)
- return NULL;
- atomic_add(sizeof(struct frag_queue), &ip6_frag_mem);
- return fq;
+ fq->id = arg->id;
+ ipv6_addr_copy(&fq->saddr, arg->src);
+ ipv6_addr_copy(&fq->daddr, arg->dst);
}
+EXPORT_SYMBOL(ip6_frag_init);
/* Destruction primitives. */
-/* Complete destruction of fq. */
-static void ip6_frag_destroy(struct frag_queue *fq, int *work)
+static __inline__ void fq_put(struct frag_queue *fq)
{
- struct sk_buff *fp;
-
- BUG_TRAP(fq->last_in&COMPLETE);
- BUG_TRAP(del_timer(&fq->timer) == 0);
-
- /* Release all fragment data. */
- fp = fq->fragments;
- while (fp) {
- struct sk_buff *xp = fp->next;
-
- frag_kfree_skb(fp, work);
- fp = xp;
- }
-
- frag_free_queue(fq, work);
-}
-
-static __inline__ void fq_put(struct frag_queue *fq, int *work)
-{
- if (atomic_dec_and_test(&fq->refcnt))
- ip6_frag_destroy(fq, work);
+ inet_frag_put(&fq->q, &ip6_frags);
}
/* Kill fq entry. It is not destroyed immediately,
@@ -248,55 +187,28 @@ static __inline__ void fq_put(struct frag_queue *fq, int *work)
*/
static __inline__ void fq_kill(struct frag_queue *fq)
{
- if (del_timer(&fq->timer))
- atomic_dec(&fq->refcnt);
-
- if (!(fq->last_in & COMPLETE)) {
- fq_unlink(fq);
- atomic_dec(&fq->refcnt);
- fq->last_in |= COMPLETE;
- }
+ inet_frag_kill(&fq->q, &ip6_frags);
}
static void ip6_evictor(struct inet6_dev *idev)
{
- struct frag_queue *fq;
- struct list_head *tmp;
- int work;
-
- work = atomic_read(&ip6_frag_mem) - sysctl_ip6frag_low_thresh;
- if (work <= 0)
- return;
-
- while(work > 0) {
- read_lock(&ip6_frag_lock);
- if (list_empty(&ip6_frag_lru_list)) {
- read_unlock(&ip6_frag_lock);
- return;
- }
- tmp = ip6_frag_lru_list.next;
- fq = list_entry(tmp, struct frag_queue, lru_list);
- atomic_inc(&fq->refcnt);
- read_unlock(&ip6_frag_lock);
-
- spin_lock(&fq->lock);
- if (!(fq->last_in&COMPLETE))
- fq_kill(fq);
- spin_unlock(&fq->lock);
-
- fq_put(fq, &work);
- IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
- }
+ int evicted;
+
+ evicted = inet_frag_evictor(&ip6_frags);
+ if (evicted)
+ IP6_ADD_STATS_BH(idev, IPSTATS_MIB_REASMFAILS, evicted);
}
static void ip6_frag_expire(unsigned long data)
{
- struct frag_queue *fq = (struct frag_queue *) data;
+ struct frag_queue *fq;
struct net_device *dev = NULL;
- spin_lock(&fq->lock);
+ fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
+
+ spin_lock(&fq->q.lock);
- if (fq->last_in & COMPLETE)
+ if (fq->q.last_in & COMPLETE)
goto out;
fq_kill(fq);
@@ -311,7 +223,7 @@ static void ip6_frag_expire(unsigned long data)
rcu_read_unlock();
/* Don't send error if the first segment did not arrive. */
- if (!(fq->last_in&FIRST_IN) || !fq->fragments)
+ if (!(fq->q.last_in&FIRST_IN) || !fq->q.fragments)
goto out;
/*
@@ -319,114 +231,47 @@ static void ip6_frag_expire(unsigned long data)
segment was received. And do not use fq->dev
pointer directly, device might already disappeared.
*/
- fq->fragments->dev = dev;
- icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev);
+ fq->q.fragments->dev = dev;
+ icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev);
out:
if (dev)
dev_put(dev);
- spin_unlock(&fq->lock);
- fq_put(fq, NULL);
+ spin_unlock(&fq->q.lock);
+ fq_put(fq);
}
-/* Creation primitives. */
-
-
-static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
+static __inline__ struct frag_queue *
+fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
+ struct inet6_dev *idev)
{
- struct frag_queue *fq;
+ struct inet_frag_queue *q;
+ struct ip6_create_arg arg;
unsigned int hash;
-#ifdef CONFIG_SMP
- struct hlist_node *n;
-#endif
-
- write_lock(&ip6_frag_lock);
- hash = ip6qhashfn(fq_in->id, &fq_in->saddr, &fq_in->daddr);
-#ifdef CONFIG_SMP
- hlist_for_each_entry(fq, n, &ip6_frag_hash[hash], list) {
- if (fq->id == fq_in->id &&
- ipv6_addr_equal(&fq_in->saddr, &fq->saddr) &&
- ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) {
- atomic_inc(&fq->refcnt);
- write_unlock(&ip6_frag_lock);
- fq_in->last_in |= COMPLETE;
- fq_put(fq_in, NULL);
- return fq;
- }
- }
-#endif
- fq = fq_in;
-
- if (!mod_timer(&fq->timer, jiffies + sysctl_ip6frag_time))
- atomic_inc(&fq->refcnt);
-
- atomic_inc(&fq->refcnt);
- hlist_add_head(&fq->list, &ip6_frag_hash[hash]);
- INIT_LIST_HEAD(&fq->lru_list);
- list_add_tail(&fq->lru_list, &ip6_frag_lru_list);
- ip6_frag_nqueues++;
- write_unlock(&ip6_frag_lock);
- return fq;
-}
-
-static struct frag_queue *
-ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
- struct inet6_dev *idev)
-{
- struct frag_queue *fq;
+ arg.id = id;
+ arg.src = src;
+ arg.dst = dst;
+ hash = ip6qhashfn(id, src, dst);
- if ((fq = frag_alloc_queue()) == NULL)
+ q = inet_frag_find(&ip6_frags, &arg, hash);
+ if (q == NULL)
goto oom;
- fq->id = id;
- ipv6_addr_copy(&fq->saddr, src);
- ipv6_addr_copy(&fq->daddr, dst);
-
- init_timer(&fq->timer);
- fq->timer.function = ip6_frag_expire;
- fq->timer.data = (long) fq;
- spin_lock_init(&fq->lock);
- atomic_set(&fq->refcnt, 1);
-
- return ip6_frag_intern(fq);
+ return container_of(q, struct frag_queue, q);
oom:
IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
return NULL;
}
-static __inline__ struct frag_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
- struct inet6_dev *idev)
-{
- struct frag_queue *fq;
- struct hlist_node *n;
- unsigned int hash;
-
- read_lock(&ip6_frag_lock);
- hash = ip6qhashfn(id, src, dst);
- hlist_for_each_entry(fq, n, &ip6_frag_hash[hash], list) {
- if (fq->id == id &&
- ipv6_addr_equal(src, &fq->saddr) &&
- ipv6_addr_equal(dst, &fq->daddr)) {
- atomic_inc(&fq->refcnt);
- read_unlock(&ip6_frag_lock);
- return fq;
- }
- }
- read_unlock(&ip6_frag_lock);
-
- return ip6_frag_create(id, src, dst, idev);
-}
-
-
-static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
+static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
+ struct net_device *dev;
int offset, end;
- if (fq->last_in & COMPLETE)
+ if (fq->q.last_in & COMPLETE)
goto err;
offset = ntohs(fhdr->frag_off) & ~0x7;
@@ -439,7 +284,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
((u8 *)&fhdr->frag_off -
skb_network_header(skb)));
- return;
+ return -1;
}
if (skb->ip_summed == CHECKSUM_COMPLETE) {
@@ -454,11 +299,11 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
/* If we already have some bits beyond end
* or have different end, the segment is corrupted.
*/
- if (end < fq->len ||
- ((fq->last_in & LAST_IN) && end != fq->len))
+ if (end < fq->q.len ||
+ ((fq->q.last_in & LAST_IN) && end != fq->q.len))
goto err;
- fq->last_in |= LAST_IN;
- fq->len = end;
+ fq->q.last_in |= LAST_IN;
+ fq->q.len = end;
} else {
/* Check if the fragment is rounded to 8 bytes.
* Required by the RFC.
@@ -471,13 +316,13 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
IPSTATS_MIB_INHDRERRORS);
icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
offsetof(struct ipv6hdr, payload_len));
- return;
+ return -1;
}
- if (end > fq->len) {
+ if (end > fq->q.len) {
/* Some bits beyond end -> corruption. */
- if (fq->last_in & LAST_IN)
+ if (fq->q.last_in & LAST_IN)
goto err;
- fq->len = end;
+ fq->q.len = end;
}
}
@@ -496,7 +341,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
* this fragment, right?
*/
prev = NULL;
- for(next = fq->fragments; next != NULL; next = next->next) {
+ for(next = fq->q.fragments; next != NULL; next = next->next) {
if (FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
@@ -533,7 +378,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
if (!pskb_pull(next, i))
goto err;
FRAG6_CB(next)->offset += i; /* next fragment */
- fq->meat -= i;
+ fq->q.meat -= i;
if (next->ip_summed != CHECKSUM_UNNECESSARY)
next->ip_summed = CHECKSUM_NONE;
break;
@@ -548,9 +393,9 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
if (prev)
prev->next = next;
else
- fq->fragments = next;
+ fq->q.fragments = next;
- fq->meat -= free_it->len;
+ fq->q.meat -= free_it->len;
frag_kfree_skb(free_it, NULL);
}
}
@@ -562,30 +407,37 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
if (prev)
prev->next = skb;
else
- fq->fragments = skb;
+ fq->q.fragments = skb;
- if (skb->dev)
- fq->iif = skb->dev->ifindex;
- skb->dev = NULL;
- fq->stamp = skb->tstamp;
- fq->meat += skb->len;
- atomic_add(skb->truesize, &ip6_frag_mem);
+ dev = skb->dev;
+ if (dev) {
+ fq->iif = dev->ifindex;
+ skb->dev = NULL;
+ }
+ fq->q.stamp = skb->tstamp;
+ fq->q.meat += skb->len;
+ atomic_add(skb->truesize, &ip6_frags.mem);
/* The first fragment.
* nhoffset is obtained from the first fragment, of course.
*/
if (offset == 0) {
fq->nhoffset = nhoff;
- fq->last_in |= FIRST_IN;
+ fq->q.last_in |= FIRST_IN;
}
- write_lock(&ip6_frag_lock);
- list_move_tail(&fq->lru_list, &ip6_frag_lru_list);
- write_unlock(&ip6_frag_lock);
- return;
+
+ if (fq->q.last_in == (FIRST_IN | LAST_IN) && fq->q.meat == fq->q.len)
+ return ip6_frag_reasm(fq, prev, dev);
+
+ write_lock(&ip6_frags.lock);
+ list_move_tail(&fq->q.lru_list, &ip6_frags.lru_list);
+ write_unlock(&ip6_frags.lock);
+ return -1;
err:
IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
kfree_skb(skb);
+ return -1;
}
/*
@@ -597,21 +449,39 @@ err:
* queue is eligible for reassembly i.e. it is not COMPLETE,
* the last and the first frames arrived and all the bits are here.
*/
-static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
+static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
struct net_device *dev)
{
- struct sk_buff *fp, *head = fq->fragments;
+ struct sk_buff *fp, *head = fq->q.fragments;
int payload_len;
unsigned int nhoff;
fq_kill(fq);
+ /* Make the one we just received the head. */
+ if (prev) {
+ head = prev->next;
+ fp = skb_clone(head, GFP_ATOMIC);
+
+ if (!fp)
+ goto out_oom;
+
+ fp->next = head->next;
+ prev->next = fp;
+
+ skb_morph(head, fq->q.fragments);
+ head->next = fq->q.fragments->next;
+
+ kfree_skb(fq->q.fragments);
+ fq->q.fragments = head;
+ }
+
BUG_TRAP(head != NULL);
BUG_TRAP(FRAG6_CB(head)->offset == 0);
/* Unfragmented part is taken from the first segment. */
payload_len = ((head->data - skb_network_header(head)) -
- sizeof(struct ipv6hdr) + fq->len -
+ sizeof(struct ipv6hdr) + fq->q.len -
sizeof(struct frag_hdr));
if (payload_len > IPV6_MAXPLEN)
goto out_oversize;
@@ -640,7 +510,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
head->len -= clone->len;
clone->csum = 0;
clone->ip_summed = head->ip_summed;
- atomic_add(clone->truesize, &ip6_frag_mem);
+ atomic_add(clone->truesize, &ip6_frags.mem);
}
/* We have to remove fragment header from datagram and to relocate
@@ -655,7 +525,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
skb_shinfo(head)->frag_list = head->next;
skb_reset_transport_header(head);
skb_push(head, head->data - skb_network_header(head));
- atomic_sub(head->truesize, &ip6_frag_mem);
+ atomic_sub(head->truesize, &ip6_frags.mem);
for (fp=head->next; fp; fp = fp->next) {
head->data_len += fp->len;
@@ -665,17 +535,15 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
else if (head->ip_summed == CHECKSUM_COMPLETE)
head->csum = csum_add(head->csum, fp->csum);
head->truesize += fp->truesize;
- atomic_sub(fp->truesize, &ip6_frag_mem);
+ atomic_sub(fp->truesize, &ip6_frags.mem);
}
head->next = NULL;
head->dev = dev;
- head->tstamp = fq->stamp;
+ head->tstamp = fq->q.stamp;
ipv6_hdr(head)->payload_len = htons(payload_len);
IP6CB(head)->nhoff = nhoff;
- *skb_in = head;
-
/* Yes, and fold redundant checksum back. 8) */
if (head->ip_summed == CHECKSUM_COMPLETE)
head->csum = csum_partial(skb_network_header(head),
@@ -685,7 +553,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
rcu_read_lock();
IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
rcu_read_unlock();
- fq->fragments = NULL;
+ fq->q.fragments = NULL;
return 1;
out_oversize:
@@ -702,10 +570,8 @@ out_fail:
return -1;
}
-static int ipv6_frag_rcv(struct sk_buff **skbp)
+static int ipv6_frag_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *skbp;
- struct net_device *dev = skb->dev;
struct frag_hdr *fhdr;
struct frag_queue *fq;
struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -739,23 +605,19 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
return 1;
}
- if (atomic_read(&ip6_frag_mem) > sysctl_ip6frag_high_thresh)
+ if (atomic_read(&ip6_frags.mem) > ip6_frags_ctl.high_thresh)
ip6_evictor(ip6_dst_idev(skb->dst));
if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr,
ip6_dst_idev(skb->dst))) != NULL) {
- int ret = -1;
+ int ret;
- spin_lock(&fq->lock);
+ spin_lock(&fq->q.lock);
- ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
+ ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
- if (fq->last_in == (FIRST_IN|LAST_IN) &&
- fq->meat == fq->len)
- ret = ip6_frag_reasm(fq, skbp, dev);
-
- spin_unlock(&fq->lock);
- fq_put(fq, NULL);
+ spin_unlock(&fq->q.lock);
+ fq_put(fq);
return ret;
}
@@ -775,11 +637,13 @@ void __init ipv6_frag_init(void)
if (inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT) < 0)
printk(KERN_ERR "ipv6_frag_init: Could not register protocol\n");
- ip6_frag_hash_rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
- (jiffies ^ (jiffies >> 6)));
-
- init_timer(&ip6_frag_secret_timer);
- ip6_frag_secret_timer.function = ip6_frag_secret_rebuild;
- ip6_frag_secret_timer.expires = jiffies + sysctl_ip6frag_secret_interval;
- add_timer(&ip6_frag_secret_timer);
+ ip6_frags.ctl = &ip6_frags_ctl;
+ ip6_frags.hashfn = ip6_hashfn;
+ ip6_frags.constructor = ip6_frag_init;
+ ip6_frags.destructor = NULL;
+ ip6_frags.skb_free = NULL;
+ ip6_frags.qsize = sizeof(struct frag_queue);
+ ip6_frags.match = ip6_frag_match;
+ ip6_frags.frag_expire = ip6_frag_expire;
+ inet_frags_init(&ip6_frags);
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 6ff19f9eb9e..95f8e4a62f6 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -663,7 +663,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
return rt;
}
-static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
+static struct rt6_info *ip6_pol_route(struct fib6_table *table, int oif,
struct flowi *fl, int flags)
{
struct fib6_node *fn;
@@ -682,7 +682,7 @@ restart_2:
fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
restart:
- rt = rt6_select(fn, fl->iif, strict | reachable);
+ rt = rt6_select(fn, oif, strict | reachable);
BACKTRACK(&fl->fl6_src);
if (rt == &ip6_null_entry ||
rt->rt6i_flags & RTF_CACHE)
@@ -735,6 +735,12 @@ out2:
return rt;
}
+static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
+ struct flowi *fl, int flags)
+{
+ return ip6_pol_route(table, fl->iif, fl, flags);
+}
+
void ip6_route_input(struct sk_buff *skb)
{
struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -761,72 +767,7 @@ void ip6_route_input(struct sk_buff *skb)
static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
struct flowi *fl, int flags)
{
- struct fib6_node *fn;
- struct rt6_info *rt, *nrt;
- int strict = 0;
- int attempts = 3;
- int err;
- int reachable = ipv6_devconf.forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
-
- strict |= flags & RT6_LOOKUP_F_IFACE;
-
-relookup:
- read_lock_bh(&table->tb6_lock);
-
-restart_2:
- fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
-
-restart:
- rt = rt6_select(fn, fl->oif, strict | reachable);
- BACKTRACK(&fl->fl6_src);
- if (rt == &ip6_null_entry ||
- rt->rt6i_flags & RTF_CACHE)
- goto out;
-
- dst_hold(&rt->u.dst);
- read_unlock_bh(&table->tb6_lock);
-
- if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
- nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
- else {
-#if CLONE_OFFLINK_ROUTE
- nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
-#else
- goto out2;
-#endif
- }
-
- dst_release(&rt->u.dst);
- rt = nrt ? : &ip6_null_entry;
-
- dst_hold(&rt->u.dst);
- if (nrt) {
- err = ip6_ins_rt(nrt);
- if (!err)
- goto out2;
- }
-
- if (--attempts <= 0)
- goto out2;
-
- /*
- * Race condition! In the gap, when table->tb6_lock was
- * released someone could insert this route. Relookup.
- */
- dst_release(&rt->u.dst);
- goto relookup;
-
-out:
- if (reachable) {
- reachable = 0;
- goto restart_2;
- }
- dst_hold(&rt->u.dst);
- read_unlock_bh(&table->tb6_lock);
-out2:
- rt->u.dst.lastuse = jiffies;
- rt->u.dst.__use++;
- return rt;
+ return ip6_pol_route(table, fl->oif, fl, flags);
}
struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
@@ -2456,7 +2397,6 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
ctl_table ipv6_route_table[] = {
{
- .ctl_name = NET_IPV6_ROUTE_FLUSH,
.procname = "flush",
.data = &flush_delay,
.maxlen = sizeof(int),
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 3fb44277207..68bb2548e46 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -12,6 +12,7 @@
#include <net/ndisc.h>
#include <net/ipv6.h>
#include <net/addrconf.h>
+#include <net/inet_frag.h>
#ifdef CONFIG_SYSCTL
@@ -41,7 +42,7 @@ static ctl_table ipv6_table[] = {
{
.ctl_name = NET_IPV6_IP6FRAG_HIGH_THRESH,
.procname = "ip6frag_high_thresh",
- .data = &sysctl_ip6frag_high_thresh,
+ .data = &ip6_frags_ctl.high_thresh,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec
@@ -49,7 +50,7 @@ static ctl_table ipv6_table[] = {
{
.ctl_name = NET_IPV6_IP6FRAG_LOW_THRESH,
.procname = "ip6frag_low_thresh",
- .data = &sysctl_ip6frag_low_thresh,
+ .data = &ip6_frags_ctl.low_thresh,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec
@@ -57,7 +58,7 @@ static ctl_table ipv6_table[] = {
{
.ctl_name = NET_IPV6_IP6FRAG_TIME,
.procname = "ip6frag_time",
- .data = &sysctl_ip6frag_time,
+ .data = &ip6_frags_ctl.timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
@@ -66,7 +67,7 @@ static ctl_table ipv6_table[] = {
{
.ctl_name = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
.procname = "ip6frag_secret_interval",
- .data = &sysctl_ip6frag_secret_interval,
+ .data = &ip6_frags_ctl.secret_interval,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_jiffies,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a07b59c528f..737b755342b 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1668,9 +1668,8 @@ ipv6_pktoptions:
return 0;
}
-static int tcp_v6_rcv(struct sk_buff **pskb)
+static int tcp_v6_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *pskb;
struct tcphdr *th;
struct sock *sk;
int ret;
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 23e2809878a..6323921b40b 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -87,9 +87,8 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family)
EXPORT_SYMBOL(xfrm6_tunnel_deregister);
-static int tunnel6_rcv(struct sk_buff **pskb)
+static int tunnel6_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *pskb;
struct xfrm6_tunnel *handler;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
@@ -106,9 +105,8 @@ drop:
return 0;
}
-static int tunnel46_rcv(struct sk_buff **pskb)
+static int tunnel46_rcv(struct sk_buff *skb)
{
- struct sk_buff *skb = *pskb;
struct xfrm6_tunnel *handler;
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 82ff26dd447..caebad6ee51 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -405,10 +405,9 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
return 0;
}
-int __udp6_lib_rcv(struct sk_buff **pskb, struct hlist_head udptable[],
+int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
int proto)
{
- struct sk_buff *skb = *pskb;
struct sock *sk;
struct udphdr *uh;
struct net_device *dev = skb->dev;
@@ -494,9 +493,9 @@ discard:
return 0;
}
-static __inline__ int udpv6_rcv(struct sk_buff **pskb)
+static __inline__ int udpv6_rcv(struct sk_buff *skb)
{
- return __udp6_lib_rcv(pskb, udp_hash, IPPROTO_UDP);
+ return __udp6_lib_rcv(skb, udp_hash, IPPROTO_UDP);
}
/*
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 6e252f318f7..2d3fda60123 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -6,7 +6,7 @@
#include <net/addrconf.h>
#include <net/inet_common.h>
-extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
+extern int __udp6_lib_rcv(struct sk_buff *, struct hlist_head [], int );
extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
int , int , int , __be32 , struct hlist_head []);
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index f54016a5500..766566f7de4 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -17,9 +17,9 @@
DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6) __read_mostly;
-static int udplitev6_rcv(struct sk_buff **pskb)
+static int udplitev6_rcv(struct sk_buff *skb)
{
- return __udp6_lib_rcv(pskb, udplite_hash, IPPROTO_UDPLITE);
+ return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
}
static void udplitev6_err(struct sk_buff *skb,
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index c858537cec4..515783707e8 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,7 +16,7 @@
#include <net/ipv6.h>
#include <net/xfrm.h>
-int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
{
int err;
__be32 seq;
@@ -24,11 +24,9 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
struct xfrm_state *x;
int xfrm_nr = 0;
int decaps = 0;
- int nexthdr;
unsigned int nhoff;
nhoff = IP6CB(skb)->nhoff;
- nexthdr = skb_network_header(skb)[nhoff];
seq = 0;
if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
@@ -41,7 +39,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
goto drop;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
- nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6);
+ nexthdr, AF_INET6);
if (x == NULL)
goto drop;
spin_lock(&x->lock);
@@ -70,10 +68,10 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
xfrm_vec[xfrm_nr++] = x;
- if (x->mode->input(x, skb))
+ if (x->outer_mode->input(x, skb))
goto drop;
- if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
+ if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
decaps = 1;
break;
}
@@ -99,7 +97,6 @@ int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi)
memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
xfrm_nr * sizeof(xfrm_vec[0]));
skb->sp->len += xfrm_nr;
- skb->ip_summed = CHECKSUM_NONE;
nf_reset(skb);
@@ -133,9 +130,10 @@ drop:
EXPORT_SYMBOL(xfrm6_rcv_spi);
-int xfrm6_rcv(struct sk_buff **pskb)
+int xfrm6_rcv(struct sk_buff *skb)
{
- return xfrm6_rcv_spi(*pskb, 0);
+ return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
+ 0);
}
EXPORT_SYMBOL(xfrm6_rcv);
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 13bb1e85676..2bfb4f05c14 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -79,6 +79,7 @@ static struct xfrm_mode xfrm6_beet_mode = {
.output = xfrm6_beet_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_BEET,
+ .flags = XFRM_MODE_FLAG_TUNNEL,
};
static int __init xfrm6_beet_init(void)
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index 957ae36b669..a7bc8c62317 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -58,16 +58,7 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
return 0;
}
-/*
- * Do nothing about routing optimization header unlike IPsec.
- */
-static int xfrm6_ro_input(struct xfrm_state *x, struct sk_buff *skb)
-{
- return 0;
-}
-
static struct xfrm_mode xfrm6_ro_mode = {
- .input = xfrm6_ro_input,
.output = xfrm6_ro_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_ROUTEOPTIMIZATION,
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index ea228387911..fd84e221727 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -118,6 +118,7 @@ static struct xfrm_mode xfrm6_tunnel_mode = {
.output = xfrm6_tunnel_output,
.owner = THIS_MODULE,
.encap = XFRM_MODE_TUNNEL,
+ .flags = XFRM_MODE_FLAG_TUNNEL,
};
static int __init xfrm6_tunnel_init(void)
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 4618c18e611..656976760ad 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -50,7 +50,7 @@ static inline int xfrm6_output_one(struct sk_buff *skb)
struct ipv6hdr *iph;
int err;
- if (x->props.mode == XFRM_MODE_TUNNEL) {
+ if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
err = xfrm6_tunnel_check_size(skb);
if (err)
goto error_nolock;
@@ -80,7 +80,7 @@ static int xfrm6_output_finish2(struct sk_buff *skb)
while (likely((err = xfrm6_output_one(skb)) == 0)) {
nf_reset(skb);
- err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, &skb, NULL,
+ err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
skb->dst->dev, dst_output);
if (unlikely(err != 1))
break;
@@ -88,7 +88,7 @@ static int xfrm6_output_finish2(struct sk_buff *skb)
if (!skb->dst->xfrm)
return dst_output(skb);
- err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
+ err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL,
skb->dst->dev, xfrm6_output_finish2);
if (unlikely(err != 1))
break;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 15aa4c58c31..82e27b80d07 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -178,8 +178,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
__xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
trailer_len += xfrm[i]->props.trailer_len;
- if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL ||
- xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {
+ if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
unsigned short encap_family = xfrm[i]->props.family;
switch(encap_family) {
case AF_INET:
@@ -215,7 +214,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
i = 0;
for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
- struct xfrm_state_afinfo *afinfo;
dst_prev->xfrm = xfrm[i++];
dst_prev->dev = rt->u.dst.dev;
@@ -232,18 +230,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
/* Copy neighbour for reachability confirmation */
dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour);
dst_prev->input = rt->u.dst.input;
- /* XXX: When IPv4 is implemented as module and can be unloaded,
- * we should manage reference to xfrm4_output in afinfo->output.
- * Miyazawa
- */
- afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family);
- if (!afinfo) {
- dst = *dst_p;
- goto error;
- }
-
- dst_prev->output = afinfo->output;
- xfrm_state_put_afinfo(afinfo);
+ dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
/* Sheit... I remember I did this right. Apparently,
* it was magically lost, so this code needs audit */
x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index cdadb484746..b392bee396f 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -93,7 +93,8 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
/* Rule 4: select IPsec tunnel */
for (i = 0; i < n; i++) {
if (src[i] &&
- src[i]->props.mode == XFRM_MODE_TUNNEL) {
+ (src[i]->props.mode == XFRM_MODE_TUNNEL ||
+ src[i]->props.mode == XFRM_MODE_BEET)) {
dst[j++] = src[i];
src[i] = NULL;
}
@@ -146,7 +147,8 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
/* Rule 3: select IPsec tunnel */
for (i = 0; i < n; i++) {
if (src[i] &&
- src[i]->mode == XFRM_MODE_TUNNEL) {
+ (src[i]->mode == XFRM_MODE_TUNNEL ||
+ src[i]->mode == XFRM_MODE_BEET)) {
dst[j++] = src[i];
src[i] = NULL;
}
@@ -168,6 +170,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
static struct xfrm_state_afinfo xfrm6_state_afinfo = {
.family = AF_INET6,
+ .owner = THIS_MODULE,
.init_tempsel = __xfrm6_init_tempsel,
.tmpl_sort = __xfrm6_tmpl_sort,
.state_sort = __xfrm6_state_sort,
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 3f8a3abde67..fae90ff3108 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -248,7 +248,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
{
- return 0;
+ return skb_network_header(skb)[IP6CB(skb)->nhoff];
}
static int xfrm6_tunnel_rcv(struct sk_buff *skb)
@@ -257,7 +257,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
__be32 spi;
spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
- return xfrm6_rcv_spi(skb, spi) > 0 ? : 0;
+ return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0;
}
static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index 824309dabfe..b5a13882c92 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -381,18 +381,9 @@ static void ircomm_tty_discovery_indication(discinfo_t *discovery,
info.daddr = discovery->daddr;
info.saddr = discovery->saddr;
- /* FIXME. We have a locking problem on the hashbin here.
- * We probably need to use hashbin_find_next(), but we first
- * need to ensure that "line" is unique. - Jean II */
- self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
- while (self != NULL) {
- IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
-
- ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
- NULL, &info);
-
- self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
- }
+ self = (struct ircomm_tty_cb *) priv;
+ ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION,
+ NULL, &info);
}
/*
diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c
index 957e04feb0f..525343a1c52 100644
--- a/net/irda/irsysctl.c
+++ b/net/irda/irsysctl.c
@@ -31,12 +31,6 @@
#include <net/irda/irda.h> /* irda_debug */
#include <net/irda/irias_object.h>
-#define NET_IRDA 412 /* Random number */
-enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS,
- DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME,
- MAX_TX_DATA_SIZE, MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME,
- LAP_KEEPALIVE_TIME };
-
extern int sysctl_discovery;
extern int sysctl_discovery_slots;
extern int sysctl_discovery_timeout;
@@ -94,7 +88,7 @@ static int do_devname(ctl_table *table, int write, struct file *filp,
/* One file */
static ctl_table irda_table[] = {
{
- .ctl_name = DISCOVERY,
+ .ctl_name = NET_IRDA_DISCOVERY,
.procname = "discovery",
.data = &sysctl_discovery,
.maxlen = sizeof(int),
@@ -102,7 +96,7 @@ static ctl_table irda_table[] = {
.proc_handler = &proc_dointvec
},
{
- .ctl_name = DEVNAME,
+ .ctl_name = NET_IRDA_DEVNAME,
.procname = "devname",
.data = sysctl_devname,
.maxlen = 65,
@@ -112,7 +106,7 @@ static ctl_table irda_table[] = {
},
#ifdef CONFIG_IRDA_DEBUG
{
- .ctl_name = DEBUG,
+ .ctl_name = NET_IRDA_DEBUG,
.procname = "debug",
.data = &irda_debug,
.maxlen = sizeof(int),
@@ -122,7 +116,7 @@ static ctl_table irda_table[] = {
#endif
#ifdef CONFIG_IRDA_FAST_RR
{
- .ctl_name = FAST_POLL,
+ .ctl_name = NET_IRDA_FAST_POLL,
.procname = "fast_poll_increase",
.data = &sysctl_fast_poll_increase,
.maxlen = sizeof(int),
@@ -131,7 +125,7 @@ static ctl_table irda_table[] = {
},
#endif
{
- .ctl_name = DISCOVERY_SLOTS,
+ .ctl_name = NET_IRDA_DISCOVERY_SLOTS,
.procname = "discovery_slots",
.data = &sysctl_discovery_slots,
.maxlen = sizeof(int),
@@ -142,7 +136,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_discovery_slots
},
{
- .ctl_name = DISCOVERY_TIMEOUT,
+ .ctl_name = NET_IRDA_DISCOVERY_TIMEOUT,
.procname = "discovery_timeout",
.data = &sysctl_discovery_timeout,
.maxlen = sizeof(int),
@@ -150,7 +144,7 @@ static ctl_table irda_table[] = {
.proc_handler = &proc_dointvec
},
{
- .ctl_name = SLOT_TIMEOUT,
+ .ctl_name = NET_IRDA_SLOT_TIMEOUT,
.procname = "slot_timeout",
.data = &sysctl_slot_timeout,
.maxlen = sizeof(int),
@@ -161,7 +155,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_slot_timeout
},
{
- .ctl_name = MAX_BAUD_RATE,
+ .ctl_name = NET_IRDA_MAX_BAUD_RATE,
.procname = "max_baud_rate",
.data = &sysctl_max_baud_rate,
.maxlen = sizeof(int),
@@ -172,7 +166,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_max_baud_rate
},
{
- .ctl_name = MIN_TX_TURN_TIME,
+ .ctl_name = NET_IRDA_MIN_TX_TURN_TIME,
.procname = "min_tx_turn_time",
.data = &sysctl_min_tx_turn_time,
.maxlen = sizeof(int),
@@ -183,7 +177,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_min_tx_turn_time
},
{
- .ctl_name = MAX_TX_DATA_SIZE,
+ .ctl_name = NET_IRDA_MAX_TX_DATA_SIZE,
.procname = "max_tx_data_size",
.data = &sysctl_max_tx_data_size,
.maxlen = sizeof(int),
@@ -194,7 +188,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_max_tx_data_size
},
{
- .ctl_name = MAX_TX_WINDOW,
+ .ctl_name = NET_IRDA_MAX_TX_WINDOW,
.procname = "max_tx_window",
.data = &sysctl_max_tx_window,
.maxlen = sizeof(int),
@@ -205,7 +199,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_max_tx_window
},
{
- .ctl_name = MAX_NOREPLY_TIME,
+ .ctl_name = NET_IRDA_MAX_NOREPLY_TIME,
.procname = "max_noreply_time",
.data = &sysctl_max_noreply_time,
.maxlen = sizeof(int),
@@ -216,7 +210,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_max_noreply_time
},
{
- .ctl_name = WARN_NOREPLY_TIME,
+ .ctl_name = NET_IRDA_WARN_NOREPLY_TIME,
.procname = "warn_noreply_time",
.data = &sysctl_warn_noreply_time,
.maxlen = sizeof(int),
@@ -227,7 +221,7 @@ static ctl_table irda_table[] = {
.extra2 = &max_warn_noreply_time
},
{
- .ctl_name = LAP_KEEPALIVE_TIME,
+ .ctl_name = NET_IRDA_LAP_KEEPALIVE_TIME,
.procname = "lap_keepalive_time",
.data = &sysctl_lap_keepalive_time,
.maxlen = sizeof(int),
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index f0224c2311d..6caa3ec2cff 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -306,9 +306,12 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
((chan->chan == channel) || (chan->freq == freq))) {
local->oper_channel = chan;
local->oper_hw_mode = mode;
- set++;
+ set = 1;
+ break;
}
}
+ if (set)
+ break;
}
if (set) {
@@ -508,10 +511,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
static int ieee80211_ioctl_siwscan(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct iw_scan_req *req = NULL;
u8 *ssid = NULL;
size_t ssid_len = 0;
@@ -536,6 +540,14 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
return -EOPNOTSUPP;
}
+ /* if SSID was specified explicitly then use that */
+ if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+ wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ req = (struct iw_scan_req *)extra;
+ ssid = req->essid;
+ ssid_len = req->essid_len;
+ }
+
return ieee80211_sta_req_scan(dev, ssid, ssid_len);
}
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 1641e8fe44b..db81aef6177 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -12,7 +12,6 @@
*/
/* TODO:
- * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
* order BSS list by RSSI(?) ("quality of AP")
* scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
* SSID)
@@ -61,7 +60,8 @@
static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
u8 *ssid, size_t ssid_len);
static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid);
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+ u8 *ssid, u8 ssid_len);
static void ieee80211_rx_bss_put(struct net_device *dev,
struct ieee80211_sta_bss *bss);
static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -427,7 +427,9 @@ static void ieee80211_set_associated(struct net_device *dev,
if (sdata->type != IEEE80211_IF_TYPE_STA)
return;
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+ local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
if (bss->has_erp_value)
ieee80211_handle_erp_ie(dev, bss->erp_value);
@@ -574,7 +576,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
WLAN_CAPABILITY_SHORT_PREAMBLE;
}
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
if (bss->capability & WLAN_CAPABILITY_PRIVACY)
capab |= WLAN_CAPABILITY_PRIVACY;
@@ -722,6 +725,7 @@ static void ieee80211_send_disassoc(struct net_device *dev,
static int ieee80211_privacy_mismatch(struct net_device *dev,
struct ieee80211_if_sta *ifsta)
{
+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
int res = 0;
@@ -729,7 +733,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev,
ifsta->key_management_enabled)
return 0;
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (!bss)
return 0;
@@ -1203,15 +1208,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
- if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
- printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
- "set\n", dev->name, aid);
- aid &= ~(BIT(15) | BIT(14));
printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
"status=%d aid=%d)\n",
dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
- capab_info, status_code, aid);
+ capab_info, status_code, aid & ~(BIT(15) | BIT(14)));
if (status_code != WLAN_STATUS_SUCCESS) {
printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -1223,6 +1224,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
return;
}
+ if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
+ printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
+ "set\n", dev->name, aid);
+ aid &= ~(BIT(15) | BIT(14));
+
pos = mgmt->u.assoc_resp.variable;
if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
== ParseFailed) {
@@ -1241,7 +1247,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
* update our stored copy */
if (elems.erp_info && elems.erp_info_len >= 1) {
struct ieee80211_sta_bss *bss
- = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ = ieee80211_rx_bss_get(dev, ifsta->bssid,
+ local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
bss->erp_value = elems.erp_info[0];
bss->has_erp_value = 1;
@@ -1271,7 +1279,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
" AP\n", dev->name);
return;
}
- bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
+ bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
+ local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len);
if (bss) {
sta->last_rssi = bss->rssi;
sta->last_signal = bss->signal;
@@ -1347,7 +1357,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev,
static struct ieee80211_sta_bss *
-ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
+ u8 *ssid, u8 ssid_len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
@@ -1358,6 +1369,11 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
atomic_inc(&bss->users);
atomic_inc(&bss->users);
memcpy(bss->bssid, bssid, ETH_ALEN);
+ bss->channel = channel;
+ if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
+ memcpy(bss->ssid, ssid, ssid_len);
+ bss->ssid_len = ssid_len;
+ }
spin_lock_bh(&local->sta_bss_lock);
/* TODO: order by RSSI? */
@@ -1369,7 +1385,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
static struct ieee80211_sta_bss *
-ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
+ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
+ u8 *ssid, u8 ssid_len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
@@ -1377,7 +1394,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
spin_lock_bh(&local->sta_bss_lock);
bss = local->sta_bss_hash[STA_HASH(bssid)];
while (bss) {
- if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
+ if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
+ bss->channel == channel &&
+ bss->ssid_len == ssid_len &&
+ (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
atomic_inc(&bss->users);
break;
}
@@ -1545,9 +1565,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
else
channel = rx_status->channel;
- bss = ieee80211_rx_bss_get(dev, mgmt->bssid);
+ bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
+ elems.ssid, elems.ssid_len);
if (!bss) {
- bss = ieee80211_rx_bss_add(dev, mgmt->bssid);
+ bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
+ elems.ssid, elems.ssid_len);
if (!bss)
return;
} else {
@@ -1573,10 +1595,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
- if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
- memcpy(bss->ssid, elems.ssid, elems.ssid_len);
- bss->ssid_len = elems.ssid_len;
- }
bss->supp_rates_len = 0;
if (elems.supp_rates) {
@@ -1647,7 +1665,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->hw_mode = rx_status->phymode;
- bss->channel = channel;
bss->freq = rx_status->freq;
if (channel != rx_status->channel &&
(bss->hw_mode == MODE_IEEE80211G ||
@@ -2375,7 +2392,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sta_bss *bss;
- struct ieee80211_sub_if_data *sdata;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_hw_mode *mode;
u8 bssid[ETH_ALEN], *pos;
int i;
@@ -2398,18 +2415,17 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
dev->name, print_mac(mac, bssid));
- bss = ieee80211_rx_bss_add(dev, bssid);
+ bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
+ sdata->u.sta.ssid, sdata->u.sta.ssid_len);
if (!bss)
return -ENOMEM;
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
mode = local->oper_hw_mode;
if (local->hw.conf.beacon_int == 0)
local->hw.conf.beacon_int = 100;
bss->beacon_int = local->hw.conf.beacon_int;
bss->hw_mode = local->hw.conf.phymode;
- bss->channel = local->hw.conf.channel;
bss->freq = local->hw.conf.freq;
bss->last_update = jiffies;
bss->capability = WLAN_CAPABILITY_IBSS;
@@ -2469,7 +2485,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
"%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid));
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
- (bss = ieee80211_rx_bss_get(dev, bssid))) {
+ (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
+ ifsta->ssid, ifsta->ssid_len))) {
printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
" based on configured SSID\n",
dev->name, print_mac(mac, bssid));
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index a523fa4136e..bed9ba01e8e 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -117,7 +117,7 @@ void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
EXPORT_SYMBOL(nf_unregister_hooks);
unsigned int nf_iterate(struct list_head *head,
- struct sk_buff **skb,
+ struct sk_buff *skb,
int hook,
const struct net_device *indev,
const struct net_device *outdev,
@@ -160,7 +160,7 @@ unsigned int nf_iterate(struct list_head *head,
/* Returns 1 if okfn() needs to be executed by the caller,
* -EPERM for NF_DROP, 0 otherwise. */
-int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
+int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *),
@@ -175,17 +175,17 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
elem = &nf_hooks[pf][hook];
next_hook:
- verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
+ verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev,
outdev, &elem, okfn, hook_thresh);
if (verdict == NF_ACCEPT || verdict == NF_STOP) {
ret = 1;
goto unlock;
} else if (verdict == NF_DROP) {
- kfree_skb(*pskb);
+ kfree_skb(skb);
ret = -EPERM;
} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
NFDEBUG("nf_hook: Verdict = QUEUE.\n");
- if (!nf_queue(*pskb, elem, pf, hook, indev, outdev, okfn,
+ if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
verdict >> NF_VERDICT_BITS))
goto next_hook;
}
@@ -196,34 +196,24 @@ unlock:
EXPORT_SYMBOL(nf_hook_slow);
-int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len)
+int skb_make_writable(struct sk_buff *skb, unsigned int writable_len)
{
- struct sk_buff *nskb;
-
- if (writable_len > (*pskb)->len)
+ if (writable_len > skb->len)
return 0;
/* Not exclusive use of packet? Must copy. */
- if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len))
- goto copy_skb;
- if (skb_shared(*pskb))
- goto copy_skb;
-
- return pskb_may_pull(*pskb, writable_len);
-
-copy_skb:
- nskb = skb_copy(*pskb, GFP_ATOMIC);
- if (!nskb)
- return 0;
- BUG_ON(skb_is_nonlinear(nskb));
-
- /* Rest of kernel will get very unhappy if we pass it a
- suddenly-orphaned skbuff */
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- return 1;
+ if (!skb_cloned(skb)) {
+ if (writable_len <= skb_headlen(skb))
+ return 1;
+ } else if (skb_clone_writable(skb, writable_len))
+ return 1;
+
+ if (writable_len <= skb_headlen(skb))
+ writable_len = 0;
+ else
+ writable_len -= skb_headlen(skb);
+
+ return !!__pskb_pull_tail(skb, writable_len);
}
EXPORT_SYMBOL(skb_make_writable);
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index e42ab230ad8..7b8239c0cd5 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
module_param(ts_algo, charp, 0400);
MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");
-unsigned int (*nf_nat_amanda_hook)(struct sk_buff **pskb,
+unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
@@ -79,7 +79,7 @@ static struct {
},
};
-static int amanda_help(struct sk_buff **pskb,
+static int amanda_help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
@@ -101,25 +101,25 @@ static int amanda_help(struct sk_buff **pskb,
/* increase the UDP timeout of the master connection as replies from
* Amanda clients to the server can be quite delayed */
- nf_ct_refresh(ct, *pskb, master_timeout * HZ);
+ nf_ct_refresh(ct, skb, master_timeout * HZ);
/* No data? */
dataoff = protoff + sizeof(struct udphdr);
- if (dataoff >= (*pskb)->len) {
+ if (dataoff >= skb->len) {
if (net_ratelimit())
- printk("amanda_help: skblen = %u\n", (*pskb)->len);
+ printk("amanda_help: skblen = %u\n", skb->len);
return NF_ACCEPT;
}
memset(&ts, 0, sizeof(ts));
- start = skb_find_text(*pskb, dataoff, (*pskb)->len,
+ start = skb_find_text(skb, dataoff, skb->len,
search[SEARCH_CONNECT].ts, &ts);
if (start == UINT_MAX)
goto out;
start += dataoff + search[SEARCH_CONNECT].len;
memset(&ts, 0, sizeof(ts));
- stop = skb_find_text(*pskb, start, (*pskb)->len,
+ stop = skb_find_text(skb, start, skb->len,
search[SEARCH_NEWLINE].ts, &ts);
if (stop == UINT_MAX)
goto out;
@@ -127,13 +127,13 @@ static int amanda_help(struct sk_buff **pskb,
for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) {
memset(&ts, 0, sizeof(ts));
- off = skb_find_text(*pskb, start, stop, search[i].ts, &ts);
+ off = skb_find_text(skb, start, stop, search[i].ts, &ts);
if (off == UINT_MAX)
continue;
off += start + search[i].len;
len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off);
- if (skb_copy_bits(*pskb, off, pbuf, len))
+ if (skb_copy_bits(skb, off, pbuf, len))
break;
pbuf[len] = '\0';
@@ -153,7 +153,7 @@ static int amanda_help(struct sk_buff **pskb,
nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
- ret = nf_nat_amanda(pskb, ctinfo, off - dataoff,
+ ret = nf_nat_amanda(skb, ctinfo, off - dataoff,
len, exp);
else if (nf_ct_expect_related(exp) != 0)
ret = NF_DROP;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 83c30b45d17..4d6171bc082 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -307,7 +307,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
/* Confirm a connection given skb; places it in hash table */
int
-__nf_conntrack_confirm(struct sk_buff **pskb)
+__nf_conntrack_confirm(struct sk_buff *skb)
{
unsigned int hash, repl_hash;
struct nf_conntrack_tuple_hash *h;
@@ -316,7 +316,7 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
struct hlist_node *n;
enum ip_conntrack_info ctinfo;
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
/* ipt_REJECT uses nf_conntrack_attach to attach related
ICMP/TCP RST packets in other direction. Actual packet
@@ -367,14 +367,14 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
write_unlock_bh(&nf_conntrack_lock);
help = nfct_help(ct);
if (help && help->helper)
- nf_conntrack_event_cache(IPCT_HELPER, *pskb);
+ nf_conntrack_event_cache(IPCT_HELPER, skb);
#ifdef CONFIG_NF_NAT_NEEDED
if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
- nf_conntrack_event_cache(IPCT_NATINFO, *pskb);
+ nf_conntrack_event_cache(IPCT_NATINFO, skb);
#endif
nf_conntrack_event_cache(master_ct(ct) ?
- IPCT_RELATED : IPCT_NEW, *pskb);
+ IPCT_RELATED : IPCT_NEW, skb);
return NF_ACCEPT;
out:
@@ -632,7 +632,7 @@ resolve_normal_ct(struct sk_buff *skb,
}
unsigned int
-nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
+nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
@@ -644,14 +644,14 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
int ret;
/* Previously seen (loopback or untracked)? Ignore. */
- if ((*pskb)->nfct) {
+ if (skb->nfct) {
NF_CT_STAT_INC_ATOMIC(ignore);
return NF_ACCEPT;
}
/* rcu_read_lock()ed by nf_hook_slow */
l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
- ret = l3proto->get_l4proto(*pskb, skb_network_offset(*pskb),
+ ret = l3proto->get_l4proto(skb, skb_network_offset(skb),
&dataoff, &protonum);
if (ret <= 0) {
pr_debug("not prepared to track yet or error occured\n");
@@ -666,13 +666,13 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
* inverse of the return code tells to the netfilter
* core what to do with the packet. */
if (l4proto->error != NULL &&
- (ret = l4proto->error(*pskb, dataoff, &ctinfo, pf, hooknum)) <= 0) {
+ (ret = l4proto->error(skb, dataoff, &ctinfo, pf, hooknum)) <= 0) {
NF_CT_STAT_INC_ATOMIC(error);
NF_CT_STAT_INC_ATOMIC(invalid);
return -ret;
}
- ct = resolve_normal_ct(*pskb, dataoff, pf, protonum, l3proto, l4proto,
+ ct = resolve_normal_ct(skb, dataoff, pf, protonum, l3proto, l4proto,
&set_reply, &ctinfo);
if (!ct) {
/* Not valid part of a connection */
@@ -686,21 +686,21 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
return NF_DROP;
}
- NF_CT_ASSERT((*pskb)->nfct);
+ NF_CT_ASSERT(skb->nfct);
- ret = l4proto->packet(ct, *pskb, dataoff, ctinfo, pf, hooknum);
+ ret = l4proto->packet(ct, skb, dataoff, ctinfo, pf, hooknum);
if (ret < 0) {
/* Invalid: inverse of the return code tells
* the netfilter core what to do */
pr_debug("nf_conntrack_in: Can't track with proto module\n");
- nf_conntrack_put((*pskb)->nfct);
- (*pskb)->nfct = NULL;
+ nf_conntrack_put(skb->nfct);
+ skb->nfct = NULL;
NF_CT_STAT_INC_ATOMIC(invalid);
return -ret;
}
if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
- nf_conntrack_event_cache(IPCT_STATUS, *pskb);
+ nf_conntrack_event_cache(IPCT_STATUS, skb);
return ret;
}
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index c763ee74ea0..6df259067f7 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -43,7 +43,7 @@ module_param_array(ports, ushort, &ports_c, 0400);
static int loose;
module_param(loose, bool, 0600);
-unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
+unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
enum nf_ct_ftp_type type,
unsigned int matchoff,
@@ -344,7 +344,7 @@ static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir,
}
}
-static int help(struct sk_buff **pskb,
+static int help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
@@ -371,21 +371,21 @@ static int help(struct sk_buff **pskb,
return NF_ACCEPT;
}
- th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
+ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
dataoff = protoff + th->doff * 4;
/* No data? */
- if (dataoff >= (*pskb)->len) {
+ if (dataoff >= skb->len) {
pr_debug("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
- (*pskb)->len);
+ skb->len);
return NF_ACCEPT;
}
- datalen = (*pskb)->len - dataoff;
+ datalen = skb->len - dataoff;
spin_lock_bh(&nf_ftp_lock);
- fb_ptr = skb_header_pointer(*pskb, dataoff, datalen, ftp_buffer);
+ fb_ptr = skb_header_pointer(skb, dataoff, datalen, ftp_buffer);
BUG_ON(fb_ptr == NULL);
ends_in_nl = (fb_ptr[datalen - 1] == '\n');
@@ -491,7 +491,7 @@ static int help(struct sk_buff **pskb,
* (possibly changed) expectation itself. */
nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook);
if (nf_nat_ftp && ct->status & IPS_NAT_MASK)
- ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
+ ret = nf_nat_ftp(skb, ctinfo, search[dir][i].ftptype,
matchoff, matchlen, exp);
else {
/* Can't expect this? Best to drop packet now. */
@@ -508,7 +508,7 @@ out_update_nl:
/* Now if this ends in \n, update ftp info. Seq may have been
* adjusted by NAT code. */
if (ends_in_nl)
- update_nl_seq(seq, ct_ftp_info, dir, *pskb);
+ update_nl_seq(seq, ct_ftp_info, dir, skb);
out:
spin_unlock_bh(&nf_ftp_lock);
return ret;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index a8a9dfbe7a6..f23fd9598e1 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -47,27 +47,27 @@ MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
"(determined by routing information)");
/* Hooks for NAT */
-int (*set_h245_addr_hook) (struct sk_buff **pskb,
+int (*set_h245_addr_hook) (struct sk_buff *skb,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr,
union nf_conntrack_address *addr, __be16 port)
__read_mostly;
-int (*set_h225_addr_hook) (struct sk_buff **pskb,
+int (*set_h225_addr_hook) (struct sk_buff *skb,
unsigned char **data, int dataoff,
TransportAddress *taddr,
union nf_conntrack_address *addr, __be16 port)
__read_mostly;
-int (*set_sig_addr_hook) (struct sk_buff **pskb,
+int (*set_sig_addr_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count) __read_mostly;
-int (*set_ras_addr_hook) (struct sk_buff **pskb,
+int (*set_ras_addr_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count) __read_mostly;
-int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
+int (*nat_rtp_rtcp_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -75,25 +75,25 @@ int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
__be16 port, __be16 rtp_port,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp) __read_mostly;
-int (*nat_t120_hook) (struct sk_buff **pskb,
+int (*nat_t120_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr, __be16 port,
struct nf_conntrack_expect *exp) __read_mostly;
-int (*nat_h245_hook) (struct sk_buff **pskb,
+int (*nat_h245_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr, __be16 port,
struct nf_conntrack_expect *exp) __read_mostly;
-int (*nat_callforwarding_hook) (struct sk_buff **pskb,
+int (*nat_callforwarding_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr, __be16 port,
struct nf_conntrack_expect *exp) __read_mostly;
-int (*nat_q931_hook) (struct sk_buff **pskb,
+int (*nat_q931_hook) (struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, TransportAddress *taddr, int idx,
@@ -108,7 +108,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[];
static struct nf_conntrack_helper nf_conntrack_helper_ras[];
/****************************************************************************/
-static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
+static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
unsigned char **data, int *datalen, int *dataoff)
{
@@ -122,7 +122,7 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
int tpktoff;
/* Get TCP header */
- th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
+ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return 0;
@@ -130,13 +130,13 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
tcpdataoff = protoff + th->doff * 4;
/* Get TCP data length */
- tcpdatalen = (*pskb)->len - tcpdataoff;
+ tcpdatalen = skb->len - tcpdataoff;
if (tcpdatalen <= 0) /* No TCP data */
goto clear_out;
if (*data == NULL) { /* first TPKT */
/* Get first TPKT pointer */
- tpkt = skb_header_pointer(*pskb, tcpdataoff, tcpdatalen,
+ tpkt = skb_header_pointer(skb, tcpdataoff, tcpdatalen,
h323_buffer);
BUG_ON(tpkt == NULL);
@@ -248,7 +248,7 @@ static int get_h245_addr(struct nf_conn *ct, unsigned char *data,
}
/****************************************************************************/
-static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
+static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
H245_TransportAddress *taddr)
@@ -297,7 +297,7 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
(nat_rtp_rtcp = rcu_dereference(nat_rtp_rtcp_hook)) &&
ct->status & IPS_NAT_MASK) {
/* NAT needed */
- ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
+ ret = nat_rtp_rtcp(skb, ct, ctinfo, data, dataoff,
taddr, port, rtp_port, rtp_exp, rtcp_exp);
} else { /* Conntrack only */
if (nf_ct_expect_related(rtp_exp) == 0) {
@@ -321,7 +321,7 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int expect_t120(struct sk_buff **pskb,
+static int expect_t120(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -355,7 +355,7 @@ static int expect_t120(struct sk_buff **pskb,
(nat_t120 = rcu_dereference(nat_t120_hook)) &&
ct->status & IPS_NAT_MASK) {
/* NAT needed */
- ret = nat_t120(pskb, ct, ctinfo, data, dataoff, taddr,
+ ret = nat_t120(skb, ct, ctinfo, data, dataoff, taddr,
port, exp);
} else { /* Conntrack only */
if (nf_ct_expect_related(exp) == 0) {
@@ -371,7 +371,7 @@ static int expect_t120(struct sk_buff **pskb,
}
/****************************************************************************/
-static int process_h245_channel(struct sk_buff **pskb,
+static int process_h245_channel(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -381,7 +381,7 @@ static int process_h245_channel(struct sk_buff **pskb,
if (channel->options & eH2250LogicalChannelParameters_mediaChannel) {
/* RTP */
- ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff,
&channel->mediaChannel);
if (ret < 0)
return -1;
@@ -390,7 +390,7 @@ static int process_h245_channel(struct sk_buff **pskb,
if (channel->
options & eH2250LogicalChannelParameters_mediaControlChannel) {
/* RTCP */
- ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff,
&channel->mediaControlChannel);
if (ret < 0)
return -1;
@@ -400,7 +400,7 @@ static int process_h245_channel(struct sk_buff **pskb,
}
/****************************************************************************/
-static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_olc(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
OpenLogicalChannel *olc)
@@ -412,7 +412,7 @@ static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
{
- ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
+ ret = process_h245_channel(skb, ct, ctinfo, data, dataoff,
&olc->
forwardLogicalChannelParameters.
multiplexParameters.
@@ -430,7 +430,7 @@ static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
{
ret =
- process_h245_channel(pskb, ct, ctinfo, data, dataoff,
+ process_h245_channel(skb, ct, ctinfo, data, dataoff,
&olc->
reverseLogicalChannelParameters.
multiplexParameters.
@@ -448,7 +448,7 @@ static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
t120.choice == eDataProtocolCapability_separateLANStack &&
olc->separateStack.networkAddress.choice ==
eNetworkAccessParameters_networkAddress_localAreaAddress) {
- ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_t120(skb, ct, ctinfo, data, dataoff,
&olc->separateStack.networkAddress.
localAreaAddress);
if (ret < 0)
@@ -459,7 +459,7 @@ static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_olca(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
OpenLogicalChannelAck *olca)
@@ -477,7 +477,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
choice ==
eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
{
- ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
+ ret = process_h245_channel(skb, ct, ctinfo, data, dataoff,
&olca->
reverseLogicalChannelParameters.
multiplexParameters.
@@ -496,7 +496,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
if (ack->options &
eH2250LogicalChannelAckParameters_mediaChannel) {
/* RTP */
- ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff,
&ack->mediaChannel);
if (ret < 0)
return -1;
@@ -505,7 +505,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
if (ack->options &
eH2250LogicalChannelAckParameters_mediaControlChannel) {
/* RTCP */
- ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_rtp_rtcp(skb, ct, ctinfo, data, dataoff,
&ack->mediaControlChannel);
if (ret < 0)
return -1;
@@ -515,7 +515,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
if ((olca->options & eOpenLogicalChannelAck_separateStack) &&
olca->separateStack.networkAddress.choice ==
eNetworkAccessParameters_networkAddress_localAreaAddress) {
- ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_t120(skb, ct, ctinfo, data, dataoff,
&olca->separateStack.networkAddress.
localAreaAddress);
if (ret < 0)
@@ -526,7 +526,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_h245(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
MultimediaSystemControlMessage *mscm)
@@ -535,7 +535,7 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
case eMultimediaSystemControlMessage_request:
if (mscm->request.choice ==
eRequestMessage_openLogicalChannel) {
- return process_olc(pskb, ct, ctinfo, data, dataoff,
+ return process_olc(skb, ct, ctinfo, data, dataoff,
&mscm->request.openLogicalChannel);
}
pr_debug("nf_ct_h323: H.245 Request %d\n",
@@ -544,7 +544,7 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
case eMultimediaSystemControlMessage_response:
if (mscm->response.choice ==
eResponseMessage_openLogicalChannelAck) {
- return process_olca(pskb, ct, ctinfo, data, dataoff,
+ return process_olca(skb, ct, ctinfo, data, dataoff,
&mscm->response.
openLogicalChannelAck);
}
@@ -560,7 +560,7 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int h245_help(struct sk_buff **pskb, unsigned int protoff,
+static int h245_help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
static MultimediaSystemControlMessage mscm;
@@ -574,12 +574,12 @@ static int h245_help(struct sk_buff **pskb, unsigned int protoff,
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
return NF_ACCEPT;
}
- pr_debug("nf_ct_h245: skblen = %u\n", (*pskb)->len);
+ pr_debug("nf_ct_h245: skblen = %u\n", skb->len);
spin_lock_bh(&nf_h323_lock);
/* Process each TPKT */
- while (get_tpkt_data(pskb, protoff, ct, ctinfo,
+ while (get_tpkt_data(skb, protoff, ct, ctinfo,
&data, &datalen, &dataoff)) {
pr_debug("nf_ct_h245: TPKT len=%d ", datalen);
NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
@@ -596,7 +596,7 @@ static int h245_help(struct sk_buff **pskb, unsigned int protoff,
}
/* Process H.245 signal */
- if (process_h245(pskb, ct, ctinfo, &data, dataoff, &mscm) < 0)
+ if (process_h245(skb, ct, ctinfo, &data, dataoff, &mscm) < 0)
goto drop;
}
@@ -654,7 +654,7 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data,
}
/****************************************************************************/
-static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
+static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
TransportAddress *taddr)
@@ -687,7 +687,7 @@ static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
(nat_h245 = rcu_dereference(nat_h245_hook)) &&
ct->status & IPS_NAT_MASK) {
/* NAT needed */
- ret = nat_h245(pskb, ct, ctinfo, data, dataoff, taddr,
+ ret = nat_h245(skb, ct, ctinfo, data, dataoff, taddr,
port, exp);
} else { /* Conntrack only */
if (nf_ct_expect_related(exp) == 0) {
@@ -758,7 +758,7 @@ static int callforward_do_filter(union nf_conntrack_address *src,
}
/****************************************************************************/
-static int expect_callforwarding(struct sk_buff **pskb,
+static int expect_callforwarding(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -798,7 +798,7 @@ static int expect_callforwarding(struct sk_buff **pskb,
(nat_callforwarding = rcu_dereference(nat_callforwarding_hook)) &&
ct->status & IPS_NAT_MASK) {
/* Need NAT */
- ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff,
+ ret = nat_callforwarding(skb, ct, ctinfo, data, dataoff,
taddr, port, exp);
} else { /* Conntrack only */
if (nf_ct_expect_related(exp) == 0) {
@@ -814,7 +814,7 @@ static int expect_callforwarding(struct sk_buff **pskb,
}
/****************************************************************************/
-static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_setup(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
Setup_UUIE *setup)
@@ -829,7 +829,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
pr_debug("nf_ct_q931: Setup\n");
if (setup->options & eSetup_UUIE_h245Address) {
- ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_h245(skb, ct, ctinfo, data, dataoff,
&setup->h245Address);
if (ret < 0)
return -1;
@@ -846,7 +846,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
NIP6(*(struct in6_addr *)&addr), ntohs(port),
NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
- ret = set_h225_addr(pskb, data, dataoff,
+ ret = set_h225_addr(skb, data, dataoff,
&setup->destCallSignalAddress,
&ct->tuplehash[!dir].tuple.src.u3,
ct->tuplehash[!dir].tuple.src.u.tcp.port);
@@ -864,7 +864,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
NIP6(*(struct in6_addr *)&addr), ntohs(port),
NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
- ret = set_h225_addr(pskb, data, dataoff,
+ ret = set_h225_addr(skb, data, dataoff,
&setup->sourceCallSignalAddress,
&ct->tuplehash[!dir].tuple.dst.u3,
ct->tuplehash[!dir].tuple.dst.u.tcp.port);
@@ -874,7 +874,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
if (setup->options & eSetup_UUIE_fastStart) {
for (i = 0; i < setup->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
+ ret = process_olc(skb, ct, ctinfo, data, dataoff,
&setup->fastStart.item[i]);
if (ret < 0)
return -1;
@@ -885,7 +885,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_callproceeding(struct sk_buff **pskb,
+static int process_callproceeding(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -897,7 +897,7 @@ static int process_callproceeding(struct sk_buff **pskb,
pr_debug("nf_ct_q931: CallProceeding\n");
if (callproc->options & eCallProceeding_UUIE_h245Address) {
- ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_h245(skb, ct, ctinfo, data, dataoff,
&callproc->h245Address);
if (ret < 0)
return -1;
@@ -905,7 +905,7 @@ static int process_callproceeding(struct sk_buff **pskb,
if (callproc->options & eCallProceeding_UUIE_fastStart) {
for (i = 0; i < callproc->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
+ ret = process_olc(skb, ct, ctinfo, data, dataoff,
&callproc->fastStart.item[i]);
if (ret < 0)
return -1;
@@ -916,7 +916,7 @@ static int process_callproceeding(struct sk_buff **pskb,
}
/****************************************************************************/
-static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_connect(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
Connect_UUIE *connect)
@@ -927,7 +927,7 @@ static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
pr_debug("nf_ct_q931: Connect\n");
if (connect->options & eConnect_UUIE_h245Address) {
- ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_h245(skb, ct, ctinfo, data, dataoff,
&connect->h245Address);
if (ret < 0)
return -1;
@@ -935,7 +935,7 @@ static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
if (connect->options & eConnect_UUIE_fastStart) {
for (i = 0; i < connect->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
+ ret = process_olc(skb, ct, ctinfo, data, dataoff,
&connect->fastStart.item[i]);
if (ret < 0)
return -1;
@@ -946,7 +946,7 @@ static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_alerting(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
Alerting_UUIE *alert)
@@ -957,7 +957,7 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
pr_debug("nf_ct_q931: Alerting\n");
if (alert->options & eAlerting_UUIE_h245Address) {
- ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_h245(skb, ct, ctinfo, data, dataoff,
&alert->h245Address);
if (ret < 0)
return -1;
@@ -965,7 +965,7 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
if (alert->options & eAlerting_UUIE_fastStart) {
for (i = 0; i < alert->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
+ ret = process_olc(skb, ct, ctinfo, data, dataoff,
&alert->fastStart.item[i]);
if (ret < 0)
return -1;
@@ -976,7 +976,7 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_facility(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
Facility_UUIE *facility)
@@ -988,7 +988,7 @@ static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
if (facility->reason.choice == eFacilityReason_callForwarded) {
if (facility->options & eFacility_UUIE_alternativeAddress)
- return expect_callforwarding(pskb, ct, ctinfo, data,
+ return expect_callforwarding(skb, ct, ctinfo, data,
dataoff,
&facility->
alternativeAddress);
@@ -996,7 +996,7 @@ static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
}
if (facility->options & eFacility_UUIE_h245Address) {
- ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_h245(skb, ct, ctinfo, data, dataoff,
&facility->h245Address);
if (ret < 0)
return -1;
@@ -1004,7 +1004,7 @@ static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
if (facility->options & eFacility_UUIE_fastStart) {
for (i = 0; i < facility->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
+ ret = process_olc(skb, ct, ctinfo, data, dataoff,
&facility->fastStart.item[i]);
if (ret < 0)
return -1;
@@ -1015,7 +1015,7 @@ static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_progress(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
Progress_UUIE *progress)
@@ -1026,7 +1026,7 @@ static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
pr_debug("nf_ct_q931: Progress\n");
if (progress->options & eProgress_UUIE_h245Address) {
- ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = expect_h245(skb, ct, ctinfo, data, dataoff,
&progress->h245Address);
if (ret < 0)
return -1;
@@ -1034,7 +1034,7 @@ static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
if (progress->options & eProgress_UUIE_fastStart) {
for (i = 0; i < progress->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
+ ret = process_olc(skb, ct, ctinfo, data, dataoff,
&progress->fastStart.item[i]);
if (ret < 0)
return -1;
@@ -1045,7 +1045,7 @@ static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_q931(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff, Q931 *q931)
{
@@ -1055,28 +1055,28 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
switch (pdu->h323_message_body.choice) {
case eH323_UU_PDU_h323_message_body_setup:
- ret = process_setup(pskb, ct, ctinfo, data, dataoff,
+ ret = process_setup(skb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.setup);
break;
case eH323_UU_PDU_h323_message_body_callProceeding:
- ret = process_callproceeding(pskb, ct, ctinfo, data, dataoff,
+ ret = process_callproceeding(skb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.
callProceeding);
break;
case eH323_UU_PDU_h323_message_body_connect:
- ret = process_connect(pskb, ct, ctinfo, data, dataoff,
+ ret = process_connect(skb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.connect);
break;
case eH323_UU_PDU_h323_message_body_alerting:
- ret = process_alerting(pskb, ct, ctinfo, data, dataoff,
+ ret = process_alerting(skb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.alerting);
break;
case eH323_UU_PDU_h323_message_body_facility:
- ret = process_facility(pskb, ct, ctinfo, data, dataoff,
+ ret = process_facility(skb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.facility);
break;
case eH323_UU_PDU_h323_message_body_progress:
- ret = process_progress(pskb, ct, ctinfo, data, dataoff,
+ ret = process_progress(skb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.progress);
break;
default:
@@ -1090,7 +1090,7 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
if (pdu->options & eH323_UU_PDU_h245Control) {
for (i = 0; i < pdu->h245Control.count; i++) {
- ret = process_h245(pskb, ct, ctinfo, data, dataoff,
+ ret = process_h245(skb, ct, ctinfo, data, dataoff,
&pdu->h245Control.item[i]);
if (ret < 0)
return -1;
@@ -1101,7 +1101,7 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int q931_help(struct sk_buff **pskb, unsigned int protoff,
+static int q931_help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
static Q931 q931;
@@ -1115,12 +1115,12 @@ static int q931_help(struct sk_buff **pskb, unsigned int protoff,
ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
return NF_ACCEPT;
}
- pr_debug("nf_ct_q931: skblen = %u\n", (*pskb)->len);
+ pr_debug("nf_ct_q931: skblen = %u\n", skb->len);
spin_lock_bh(&nf_h323_lock);
/* Process each TPKT */
- while (get_tpkt_data(pskb, protoff, ct, ctinfo,
+ while (get_tpkt_data(skb, protoff, ct, ctinfo,
&data, &datalen, &dataoff)) {
pr_debug("nf_ct_q931: TPKT len=%d ", datalen);
NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
@@ -1136,7 +1136,7 @@ static int q931_help(struct sk_buff **pskb, unsigned int protoff,
}
/* Process Q.931 signal */
- if (process_q931(pskb, ct, ctinfo, &data, dataoff, &q931) < 0)
+ if (process_q931(skb, ct, ctinfo, &data, dataoff, &q931) < 0)
goto drop;
}
@@ -1177,20 +1177,20 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
};
/****************************************************************************/
-static unsigned char *get_udp_data(struct sk_buff **pskb, unsigned int protoff,
+static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,
int *datalen)
{
struct udphdr _uh, *uh;
int dataoff;
- uh = skb_header_pointer(*pskb, protoff, sizeof(_uh), &_uh);
+ uh = skb_header_pointer(skb, protoff, sizeof(_uh), &_uh);
if (uh == NULL)
return NULL;
dataoff = protoff + sizeof(_uh);
- if (dataoff >= (*pskb)->len)
+ if (dataoff >= skb->len)
return NULL;
- *datalen = (*pskb)->len - dataoff;
- return skb_header_pointer(*pskb, dataoff, *datalen, h323_buffer);
+ *datalen = skb->len - dataoff;
+ return skb_header_pointer(skb, dataoff, *datalen, h323_buffer);
}
/****************************************************************************/
@@ -1227,7 +1227,7 @@ static int set_expect_timeout(struct nf_conntrack_expect *exp,
}
/****************************************************************************/
-static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
+static int expect_q931(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data,
TransportAddress *taddr, int count)
@@ -1265,7 +1265,7 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
nat_q931 = rcu_dereference(nat_q931_hook);
if (nat_q931 && ct->status & IPS_NAT_MASK) { /* Need NAT */
- ret = nat_q931(pskb, ct, ctinfo, data, taddr, i, port, exp);
+ ret = nat_q931(skb, ct, ctinfo, data, taddr, i, port, exp);
} else { /* Conntrack only */
if (nf_ct_expect_related(exp) == 0) {
pr_debug("nf_ct_ras: expect Q.931 ");
@@ -1283,7 +1283,7 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_grq(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_grq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, GatekeeperRequest *grq)
{
@@ -1293,13 +1293,13 @@ static int process_grq(struct sk_buff **pskb, struct nf_conn *ct,
set_ras_addr = rcu_dereference(set_ras_addr_hook);
if (set_ras_addr && ct->status & IPS_NAT_MASK) /* NATed */
- return set_ras_addr(pskb, ct, ctinfo, data,
+ return set_ras_addr(skb, ct, ctinfo, data,
&grq->rasAddress, 1);
return 0;
}
/****************************************************************************/
-static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_gcf(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, GatekeeperConfirm *gcf)
{
@@ -1343,7 +1343,7 @@ static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_rrq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, RegistrationRequest *rrq)
{
@@ -1353,7 +1353,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
pr_debug("nf_ct_ras: RRQ\n");
- ret = expect_q931(pskb, ct, ctinfo, data,
+ ret = expect_q931(skb, ct, ctinfo, data,
rrq->callSignalAddress.item,
rrq->callSignalAddress.count);
if (ret < 0)
@@ -1361,7 +1361,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
set_ras_addr = rcu_dereference(set_ras_addr_hook);
if (set_ras_addr && ct->status & IPS_NAT_MASK) {
- ret = set_ras_addr(pskb, ct, ctinfo, data,
+ ret = set_ras_addr(skb, ct, ctinfo, data,
rrq->rasAddress.item,
rrq->rasAddress.count);
if (ret < 0)
@@ -1378,7 +1378,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, RegistrationConfirm *rcf)
{
@@ -1392,7 +1392,7 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
set_sig_addr = rcu_dereference(set_sig_addr_hook);
if (set_sig_addr && ct->status & IPS_NAT_MASK) {
- ret = set_sig_addr(pskb, ct, ctinfo, data,
+ ret = set_sig_addr(skb, ct, ctinfo, data,
rcf->callSignalAddress.item,
rcf->callSignalAddress.count);
if (ret < 0)
@@ -1407,7 +1407,7 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
if (info->timeout > 0) {
pr_debug("nf_ct_ras: set RAS connection timeout to "
"%u seconds\n", info->timeout);
- nf_ct_refresh(ct, *pskb, info->timeout * HZ);
+ nf_ct_refresh(ct, skb, info->timeout * HZ);
/* Set expect timeout */
read_lock_bh(&nf_conntrack_lock);
@@ -1427,7 +1427,7 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_urq(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_urq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, UnregistrationRequest *urq)
{
@@ -1440,7 +1440,7 @@ static int process_urq(struct sk_buff **pskb, struct nf_conn *ct,
set_sig_addr = rcu_dereference(set_sig_addr_hook);
if (set_sig_addr && ct->status & IPS_NAT_MASK) {
- ret = set_sig_addr(pskb, ct, ctinfo, data,
+ ret = set_sig_addr(skb, ct, ctinfo, data,
urq->callSignalAddress.item,
urq->callSignalAddress.count);
if (ret < 0)
@@ -1453,13 +1453,13 @@ static int process_urq(struct sk_buff **pskb, struct nf_conn *ct,
info->sig_port[!dir] = 0;
/* Give it 30 seconds for UCF or URJ */
- nf_ct_refresh(ct, *pskb, 30 * HZ);
+ nf_ct_refresh(ct, skb, 30 * HZ);
return 0;
}
/****************************************************************************/
-static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_arq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, AdmissionRequest *arq)
{
@@ -1479,7 +1479,7 @@ static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
port == info->sig_port[dir] &&
set_h225_addr && ct->status & IPS_NAT_MASK) {
/* Answering ARQ */
- return set_h225_addr(pskb, data, 0,
+ return set_h225_addr(skb, data, 0,
&arq->destCallSignalAddress,
&ct->tuplehash[!dir].tuple.dst.u3,
info->sig_port[!dir]);
@@ -1491,7 +1491,7 @@ static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
!memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&
set_h225_addr && ct->status & IPS_NAT_MASK) {
/* Calling ARQ */
- return set_h225_addr(pskb, data, 0,
+ return set_h225_addr(skb, data, 0,
&arq->srcCallSignalAddress,
&ct->tuplehash[!dir].tuple.dst.u3,
port);
@@ -1501,7 +1501,7 @@ static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_acf(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, AdmissionConfirm *acf)
{
@@ -1522,7 +1522,7 @@ static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
/* Answering ACF */
set_sig_addr = rcu_dereference(set_sig_addr_hook);
if (set_sig_addr && ct->status & IPS_NAT_MASK)
- return set_sig_addr(pskb, ct, ctinfo, data,
+ return set_sig_addr(skb, ct, ctinfo, data,
&acf->destCallSignalAddress, 1);
return 0;
}
@@ -1548,7 +1548,7 @@ static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_lrq(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_lrq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, LocationRequest *lrq)
{
@@ -1558,13 +1558,13 @@ static int process_lrq(struct sk_buff **pskb, struct nf_conn *ct,
set_ras_addr = rcu_dereference(set_ras_addr_hook);
if (set_ras_addr && ct->status & IPS_NAT_MASK)
- return set_ras_addr(pskb, ct, ctinfo, data,
+ return set_ras_addr(skb, ct, ctinfo, data,
&lrq->replyAddress, 1);
return 0;
}
/****************************************************************************/
-static int process_lcf(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_lcf(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, LocationConfirm *lcf)
{
@@ -1603,7 +1603,7 @@ static int process_lcf(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_irr(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, InfoRequestResponse *irr)
{
@@ -1615,7 +1615,7 @@ static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
set_ras_addr = rcu_dereference(set_ras_addr_hook);
if (set_ras_addr && ct->status & IPS_NAT_MASK) {
- ret = set_ras_addr(pskb, ct, ctinfo, data,
+ ret = set_ras_addr(skb, ct, ctinfo, data,
&irr->rasAddress, 1);
if (ret < 0)
return -1;
@@ -1623,7 +1623,7 @@ static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
set_sig_addr = rcu_dereference(set_sig_addr_hook);
if (set_sig_addr && ct->status & IPS_NAT_MASK) {
- ret = set_sig_addr(pskb, ct, ctinfo, data,
+ ret = set_sig_addr(skb, ct, ctinfo, data,
irr->callSignalAddress.item,
irr->callSignalAddress.count);
if (ret < 0)
@@ -1634,40 +1634,40 @@ static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int process_ras(struct sk_buff **pskb, struct nf_conn *ct,
+static int process_ras(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, RasMessage *ras)
{
switch (ras->choice) {
case eRasMessage_gatekeeperRequest:
- return process_grq(pskb, ct, ctinfo, data,
+ return process_grq(skb, ct, ctinfo, data,
&ras->gatekeeperRequest);
case eRasMessage_gatekeeperConfirm:
- return process_gcf(pskb, ct, ctinfo, data,
+ return process_gcf(skb, ct, ctinfo, data,
&ras->gatekeeperConfirm);
case eRasMessage_registrationRequest:
- return process_rrq(pskb, ct, ctinfo, data,
+ return process_rrq(skb, ct, ctinfo, data,
&ras->registrationRequest);
case eRasMessage_registrationConfirm:
- return process_rcf(pskb, ct, ctinfo, data,
+ return process_rcf(skb, ct, ctinfo, data,
&ras->registrationConfirm);
case eRasMessage_unregistrationRequest:
- return process_urq(pskb, ct, ctinfo, data,
+ return process_urq(skb, ct, ctinfo, data,
&ras->unregistrationRequest);
case eRasMessage_admissionRequest:
- return process_arq(pskb, ct, ctinfo, data,
+ return process_arq(skb, ct, ctinfo, data,
&ras->admissionRequest);
case eRasMessage_admissionConfirm:
- return process_acf(pskb, ct, ctinfo, data,
+ return process_acf(skb, ct, ctinfo, data,
&ras->admissionConfirm);
case eRasMessage_locationRequest:
- return process_lrq(pskb, ct, ctinfo, data,
+ return process_lrq(skb, ct, ctinfo, data,
&ras->locationRequest);
case eRasMessage_locationConfirm:
- return process_lcf(pskb, ct, ctinfo, data,
+ return process_lcf(skb, ct, ctinfo, data,
&ras->locationConfirm);
case eRasMessage_infoRequestResponse:
- return process_irr(pskb, ct, ctinfo, data,
+ return process_irr(skb, ct, ctinfo, data,
&ras->infoRequestResponse);
default:
pr_debug("nf_ct_ras: RAS message %d\n", ras->choice);
@@ -1678,7 +1678,7 @@ static int process_ras(struct sk_buff **pskb, struct nf_conn *ct,
}
/****************************************************************************/
-static int ras_help(struct sk_buff **pskb, unsigned int protoff,
+static int ras_help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
static RasMessage ras;
@@ -1686,12 +1686,12 @@ static int ras_help(struct sk_buff **pskb, unsigned int protoff,
int datalen = 0;
int ret;
- pr_debug("nf_ct_ras: skblen = %u\n", (*pskb)->len);
+ pr_debug("nf_ct_ras: skblen = %u\n", skb->len);
spin_lock_bh(&nf_h323_lock);
/* Get UDP data */
- data = get_udp_data(pskb, protoff, &datalen);
+ data = get_udp_data(skb, protoff, &datalen);
if (data == NULL)
goto accept;
pr_debug("nf_ct_ras: RAS message len=%d ", datalen);
@@ -1707,7 +1707,7 @@ static int ras_help(struct sk_buff **pskb, unsigned int protoff,
}
/* Process RAS message */
- if (process_ras(pskb, ct, ctinfo, &data, &ras) < 0)
+ if (process_ras(skb, ct, ctinfo, &data, &ras) < 0)
goto drop;
accept:
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 1562ca97a34..dfaed4ba83c 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -30,7 +30,7 @@ static unsigned int dcc_timeout __read_mostly = 300;
static char *irc_buffer;
static DEFINE_SPINLOCK(irc_buffer_lock);
-unsigned int (*nf_nat_irc_hook)(struct sk_buff **pskb,
+unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
unsigned int matchoff,
unsigned int matchlen,
@@ -89,7 +89,7 @@ static int parse_dcc(char *data, char *data_end, u_int32_t *ip,
return 0;
}
-static int help(struct sk_buff **pskb, unsigned int protoff,
+static int help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
unsigned int dataoff;
@@ -116,22 +116,22 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
return NF_ACCEPT;
/* Not a full tcp header? */
- th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
+ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
/* No data? */
dataoff = protoff + th->doff*4;
- if (dataoff >= (*pskb)->len)
+ if (dataoff >= skb->len)
return NF_ACCEPT;
spin_lock_bh(&irc_buffer_lock);
- ib_ptr = skb_header_pointer(*pskb, dataoff, (*pskb)->len - dataoff,
+ ib_ptr = skb_header_pointer(skb, dataoff, skb->len - dataoff,
irc_buffer);
BUG_ON(ib_ptr == NULL);
data = ib_ptr;
- data_limit = ib_ptr + (*pskb)->len - dataoff;
+ data_limit = ib_ptr + skb->len - dataoff;
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
@@ -143,7 +143,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
data += 5;
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
pr_debug("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u\n",
NIPQUAD(iph->saddr), ntohs(th->source),
NIPQUAD(iph->daddr), ntohs(th->dest));
@@ -193,7 +193,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
nf_nat_irc = rcu_dereference(nf_nat_irc_hook);
if (nf_nat_irc && ct->status & IPS_NAT_MASK)
- ret = nf_nat_irc(pskb, ctinfo,
+ ret = nf_nat_irc(skb, ctinfo,
addr_beg_p - ib_ptr,
addr_end_p - addr_beg_p,
exp);
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 1d59fabeb5f..9810d81e2a0 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -42,17 +42,17 @@ static unsigned int timeout __read_mostly = 3;
module_param(timeout, uint, 0400);
MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
-static int help(struct sk_buff **pskb, unsigned int protoff,
+static int help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
struct nf_conntrack_expect *exp;
- struct iphdr *iph = ip_hdr(*pskb);
- struct rtable *rt = (struct rtable *)(*pskb)->dst;
+ struct iphdr *iph = ip_hdr(skb);
+ struct rtable *rt = (struct rtable *)skb->dst;
struct in_device *in_dev;
__be32 mask = 0;
/* we're only interested in locally generated packets */
- if ((*pskb)->sk == NULL)
+ if (skb->sk == NULL)
goto out;
if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
goto out;
@@ -91,7 +91,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
nf_ct_expect_related(exp);
nf_ct_expect_put(exp);
- nf_ct_refresh(ct, *pskb, timeout * HZ);
+ nf_ct_refresh(ct, skb, timeout * HZ);
out:
return NF_ACCEPT;
}
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index b0804199ab5..099b6df3e2b 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -41,14 +41,14 @@ MODULE_ALIAS("ip_conntrack_pptp");
static DEFINE_SPINLOCK(nf_pptp_lock);
int
-(*nf_nat_pptp_hook_outbound)(struct sk_buff **pskb,
+(*nf_nat_pptp_hook_outbound)(struct sk_buff *skb,
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_outbound);
int
-(*nf_nat_pptp_hook_inbound)(struct sk_buff **pskb,
+(*nf_nat_pptp_hook_inbound)(struct sk_buff *skb,
struct nf_conn *ct, enum ip_conntrack_info ctinfo,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq) __read_mostly;
@@ -254,7 +254,7 @@ out_unexpect_orig:
}
static inline int
-pptp_inbound_pkt(struct sk_buff **pskb,
+pptp_inbound_pkt(struct sk_buff *skb,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq,
unsigned int reqlen,
@@ -367,7 +367,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
nf_nat_pptp_inbound = rcu_dereference(nf_nat_pptp_hook_inbound);
if (nf_nat_pptp_inbound && ct->status & IPS_NAT_MASK)
- return nf_nat_pptp_inbound(pskb, ct, ctinfo, ctlh, pptpReq);
+ return nf_nat_pptp_inbound(skb, ct, ctinfo, ctlh, pptpReq);
return NF_ACCEPT;
invalid:
@@ -380,7 +380,7 @@ invalid:
}
static inline int
-pptp_outbound_pkt(struct sk_buff **pskb,
+pptp_outbound_pkt(struct sk_buff *skb,
struct PptpControlHeader *ctlh,
union pptp_ctrl_union *pptpReq,
unsigned int reqlen,
@@ -462,7 +462,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
nf_nat_pptp_outbound = rcu_dereference(nf_nat_pptp_hook_outbound);
if (nf_nat_pptp_outbound && ct->status & IPS_NAT_MASK)
- return nf_nat_pptp_outbound(pskb, ct, ctinfo, ctlh, pptpReq);
+ return nf_nat_pptp_outbound(skb, ct, ctinfo, ctlh, pptpReq);
return NF_ACCEPT;
invalid:
@@ -492,7 +492,7 @@ static const unsigned int pptp_msg_size[] = {
/* track caller id inside control connection, call expect_related */
static int
-conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
+conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
@@ -502,7 +502,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
struct pptp_pkt_hdr _pptph, *pptph;
struct PptpControlHeader _ctlh, *ctlh;
union pptp_ctrl_union _pptpReq, *pptpReq;
- unsigned int tcplen = (*pskb)->len - protoff;
+ unsigned int tcplen = skb->len - protoff;
unsigned int datalen, reqlen, nexthdr_off;
int oldsstate, oldcstate;
int ret;
@@ -514,12 +514,12 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
return NF_ACCEPT;
nexthdr_off = protoff;
- tcph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_tcph), &_tcph);
+ tcph = skb_header_pointer(skb, nexthdr_off, sizeof(_tcph), &_tcph);
BUG_ON(!tcph);
nexthdr_off += tcph->doff * 4;
datalen = tcplen - tcph->doff * 4;
- pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
+ pptph = skb_header_pointer(skb, nexthdr_off, sizeof(_pptph), &_pptph);
if (!pptph) {
pr_debug("no full PPTP header, can't track\n");
return NF_ACCEPT;
@@ -534,7 +534,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
return NF_ACCEPT;
}
- ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh);
+ ctlh = skb_header_pointer(skb, nexthdr_off, sizeof(_ctlh), &_ctlh);
if (!ctlh)
return NF_ACCEPT;
nexthdr_off += sizeof(_ctlh);
@@ -547,7 +547,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
if (reqlen > sizeof(*pptpReq))
reqlen = sizeof(*pptpReq);
- pptpReq = skb_header_pointer(*pskb, nexthdr_off, reqlen, &_pptpReq);
+ pptpReq = skb_header_pointer(skb, nexthdr_off, reqlen, &_pptpReq);
if (!pptpReq)
return NF_ACCEPT;
@@ -560,11 +560,11 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
* established from PNS->PAC. However, RFC makes no guarantee */
if (dir == IP_CT_DIR_ORIGINAL)
/* client -> server (PNS -> PAC) */
- ret = pptp_outbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
+ ret = pptp_outbound_pkt(skb, ctlh, pptpReq, reqlen, ct,
ctinfo);
else
/* server -> client (PAC -> PNS) */
- ret = pptp_inbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
+ ret = pptp_inbound_pkt(skb, ctlh, pptpReq, reqlen, ct,
ctinfo);
pr_debug("sstate: %d->%d, cstate: %d->%d\n",
oldsstate, info->sstate, oldcstate, info->cstate);
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index d8b501878d9..13f81917964 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -70,7 +70,6 @@ static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
static struct ctl_table_header *generic_sysctl_header;
static struct ctl_table generic_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
.procname = "nf_conntrack_generic_timeout",
.data = &nf_ct_generic_timeout,
.maxlen = sizeof(unsigned int),
@@ -84,7 +83,6 @@ static struct ctl_table generic_sysctl_table[] = {
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
static struct ctl_table generic_compat_sysctl_table[] = {
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,
.procname = "ip_conntrack_generic_timeout",
.data = &nf_ct_generic_timeout,
.maxlen = sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 04192acc7c4..cb046751059 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -476,7 +476,6 @@ static unsigned int sctp_sysctl_table_users;
static struct ctl_table_header *sctp_sysctl_header;
static struct ctl_table sctp_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
.procname = "nf_conntrack_sctp_timeout_closed",
.data = &nf_ct_sctp_timeout_closed,
.maxlen = sizeof(unsigned int),
@@ -484,7 +483,6 @@ static struct ctl_table sctp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
.procname = "nf_conntrack_sctp_timeout_cookie_wait",
.data = &nf_ct_sctp_timeout_cookie_wait,
.maxlen = sizeof(unsigned int),
@@ -492,7 +490,6 @@ static struct ctl_table sctp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
.procname = "nf_conntrack_sctp_timeout_cookie_echoed",
.data = &nf_ct_sctp_timeout_cookie_echoed,
.maxlen = sizeof(unsigned int),
@@ -500,7 +497,6 @@ static struct ctl_table sctp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
.procname = "nf_conntrack_sctp_timeout_established",
.data = &nf_ct_sctp_timeout_established,
.maxlen = sizeof(unsigned int),
@@ -508,7 +504,6 @@ static struct ctl_table sctp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
.procname = "nf_conntrack_sctp_timeout_shutdown_sent",
.data = &nf_ct_sctp_timeout_shutdown_sent,
.maxlen = sizeof(unsigned int),
@@ -516,7 +511,6 @@ static struct ctl_table sctp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
.procname = "nf_conntrack_sctp_timeout_shutdown_recd",
.data = &nf_ct_sctp_timeout_shutdown_recd,
.maxlen = sizeof(unsigned int),
@@ -524,7 +518,6 @@ static struct ctl_table sctp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
.procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
.data = &nf_ct_sctp_timeout_shutdown_ack_sent,
.maxlen = sizeof(unsigned int),
@@ -539,7 +532,6 @@ static struct ctl_table sctp_sysctl_table[] = {
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
static struct ctl_table sctp_compat_sysctl_table[] = {
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
.procname = "ip_conntrack_sctp_timeout_closed",
.data = &nf_ct_sctp_timeout_closed,
.maxlen = sizeof(unsigned int),
@@ -547,7 +539,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
.procname = "ip_conntrack_sctp_timeout_cookie_wait",
.data = &nf_ct_sctp_timeout_cookie_wait,
.maxlen = sizeof(unsigned int),
@@ -555,7 +546,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
.procname = "ip_conntrack_sctp_timeout_cookie_echoed",
.data = &nf_ct_sctp_timeout_cookie_echoed,
.maxlen = sizeof(unsigned int),
@@ -563,7 +553,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
.procname = "ip_conntrack_sctp_timeout_established",
.data = &nf_ct_sctp_timeout_established,
.maxlen = sizeof(unsigned int),
@@ -571,7 +560,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
.procname = "ip_conntrack_sctp_timeout_shutdown_sent",
.data = &nf_ct_sctp_timeout_shutdown_sent,
.maxlen = sizeof(unsigned int),
@@ -579,7 +567,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
.procname = "ip_conntrack_sctp_timeout_shutdown_recd",
.data = &nf_ct_sctp_timeout_shutdown_recd,
.maxlen = sizeof(unsigned int),
@@ -587,7 +574,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
.procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
.data = &nf_ct_sctp_timeout_shutdown_ack_sent,
.maxlen = sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index c7075345971..7a3f64c1aca 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -834,10 +834,12 @@ static int tcp_packet(struct nf_conn *conntrack,
case TCP_CONNTRACK_SYN_SENT:
if (old_state < TCP_CONNTRACK_TIME_WAIT)
break;
- if (conntrack->proto.tcp.seen[!dir].flags &
- IP_CT_TCP_FLAG_CLOSE_INIT) {
- /* Attempt to reopen a closed connection.
- * Delete this connection and look up again. */
+ if ((conntrack->proto.tcp.seen[!dir].flags &
+ IP_CT_TCP_FLAG_CLOSE_INIT)
+ || (conntrack->proto.tcp.last_dir == dir
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+ /* Attempt to reopen a closed/aborted connection.
+ * Delete this connection and look up again. */
write_unlock_bh(&tcp_lock);
if (del_timer(&conntrack->timeout))
conntrack->timeout.function((unsigned long)
@@ -925,6 +927,7 @@ static int tcp_packet(struct nf_conn *conntrack,
in_window:
/* From now on we have got in-window packets */
conntrack->proto.tcp.last_index = index;
+ conntrack->proto.tcp.last_dir = dir;
pr_debug("tcp_conntracks: ");
NF_CT_DUMP_TUPLE(tuple);
@@ -1162,7 +1165,6 @@ static unsigned int tcp_sysctl_table_users;
static struct ctl_table_header *tcp_sysctl_header;
static struct ctl_table tcp_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
.procname = "nf_conntrack_tcp_timeout_syn_sent",
.data = &nf_ct_tcp_timeout_syn_sent,
.maxlen = sizeof(unsigned int),
@@ -1170,7 +1172,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
.procname = "nf_conntrack_tcp_timeout_syn_recv",
.data = &nf_ct_tcp_timeout_syn_recv,
.maxlen = sizeof(unsigned int),
@@ -1178,7 +1179,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
.procname = "nf_conntrack_tcp_timeout_established",
.data = &nf_ct_tcp_timeout_established,
.maxlen = sizeof(unsigned int),
@@ -1186,7 +1186,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
.procname = "nf_conntrack_tcp_timeout_fin_wait",
.data = &nf_ct_tcp_timeout_fin_wait,
.maxlen = sizeof(unsigned int),
@@ -1194,7 +1193,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
.procname = "nf_conntrack_tcp_timeout_close_wait",
.data = &nf_ct_tcp_timeout_close_wait,
.maxlen = sizeof(unsigned int),
@@ -1202,7 +1200,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
.procname = "nf_conntrack_tcp_timeout_last_ack",
.data = &nf_ct_tcp_timeout_last_ack,
.maxlen = sizeof(unsigned int),
@@ -1210,7 +1207,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
.procname = "nf_conntrack_tcp_timeout_time_wait",
.data = &nf_ct_tcp_timeout_time_wait,
.maxlen = sizeof(unsigned int),
@@ -1218,7 +1214,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
.procname = "nf_conntrack_tcp_timeout_close",
.data = &nf_ct_tcp_timeout_close,
.maxlen = sizeof(unsigned int),
@@ -1226,7 +1221,6 @@ static struct ctl_table tcp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
.procname = "nf_conntrack_tcp_timeout_max_retrans",
.data = &nf_ct_tcp_timeout_max_retrans,
.maxlen = sizeof(unsigned int),
@@ -1265,7 +1259,6 @@ static struct ctl_table tcp_sysctl_table[] = {
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
static struct ctl_table tcp_compat_sysctl_table[] = {
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
.procname = "ip_conntrack_tcp_timeout_syn_sent",
.data = &nf_ct_tcp_timeout_syn_sent,
.maxlen = sizeof(unsigned int),
@@ -1273,7 +1266,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
.procname = "ip_conntrack_tcp_timeout_syn_recv",
.data = &nf_ct_tcp_timeout_syn_recv,
.maxlen = sizeof(unsigned int),
@@ -1281,7 +1273,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
.procname = "ip_conntrack_tcp_timeout_established",
.data = &nf_ct_tcp_timeout_established,
.maxlen = sizeof(unsigned int),
@@ -1289,7 +1280,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
.procname = "ip_conntrack_tcp_timeout_fin_wait",
.data = &nf_ct_tcp_timeout_fin_wait,
.maxlen = sizeof(unsigned int),
@@ -1297,7 +1287,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
.procname = "ip_conntrack_tcp_timeout_close_wait",
.data = &nf_ct_tcp_timeout_close_wait,
.maxlen = sizeof(unsigned int),
@@ -1305,7 +1294,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
.procname = "ip_conntrack_tcp_timeout_last_ack",
.data = &nf_ct_tcp_timeout_last_ack,
.maxlen = sizeof(unsigned int),
@@ -1313,7 +1301,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
.procname = "ip_conntrack_tcp_timeout_time_wait",
.data = &nf_ct_tcp_timeout_time_wait,
.maxlen = sizeof(unsigned int),
@@ -1321,7 +1308,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
.procname = "ip_conntrack_tcp_timeout_close",
.data = &nf_ct_tcp_timeout_close,
.maxlen = sizeof(unsigned int),
@@ -1329,7 +1315,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
.procname = "ip_conntrack_tcp_timeout_max_retrans",
.data = &nf_ct_tcp_timeout_max_retrans,
.maxlen = sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index ba80e1a1ea1..b3e7ecb080e 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -146,7 +146,6 @@ static unsigned int udp_sysctl_table_users;
static struct ctl_table_header *udp_sysctl_header;
static struct ctl_table udp_sysctl_table[] = {
{
- .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
.procname = "nf_conntrack_udp_timeout",
.data = &nf_ct_udp_timeout,
.maxlen = sizeof(unsigned int),
@@ -154,7 +153,6 @@ static struct ctl_table udp_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
.procname = "nf_conntrack_udp_timeout_stream",
.data = &nf_ct_udp_timeout_stream,
.maxlen = sizeof(unsigned int),
@@ -168,7 +166,6 @@ static struct ctl_table udp_sysctl_table[] = {
#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
static struct ctl_table udp_compat_sysctl_table[] = {
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,
.procname = "ip_conntrack_udp_timeout",
.data = &nf_ct_udp_timeout,
.maxlen = sizeof(unsigned int),
@@ -176,7 +173,6 @@ static struct ctl_table udp_compat_sysctl_table[] = {
.proc_handler = &proc_dointvec_jiffies,
},
{
- .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
.procname = "ip_conntrack_udp_timeout_stream",
.data = &nf_ct_udp_timeout_stream,
.maxlen = sizeof(unsigned int),
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 355d371bac9..b5a16c6e21c 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -56,7 +56,7 @@ struct sane_reply_net_start {
/* other fields aren't interesting for conntrack */
};
-static int help(struct sk_buff **pskb,
+static int help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
@@ -80,19 +80,19 @@ static int help(struct sk_buff **pskb,
return NF_ACCEPT;
/* Not a full tcp header? */
- th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
+ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
if (th == NULL)
return NF_ACCEPT;
/* No data? */
dataoff = protoff + th->doff * 4;
- if (dataoff >= (*pskb)->len)
+ if (dataoff >= skb->len)
return NF_ACCEPT;
- datalen = (*pskb)->len - dataoff;
+ datalen = skb->len - dataoff;
spin_lock_bh(&nf_sane_lock);
- sb_ptr = skb_header_pointer(*pskb, dataoff, datalen, sane_buffer);
+ sb_ptr = skb_header_pointer(skb, dataoff, datalen, sane_buffer);
BUG_ON(sb_ptr == NULL);
if (dir == IP_CT_DIR_ORIGINAL) {
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index d449fa47491..8f8b5a48df3 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -36,13 +36,13 @@ static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
module_param(sip_timeout, uint, 0600);
MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
-unsigned int (*nf_nat_sip_hook)(struct sk_buff **pskb,
+unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conn *ct,
const char **dptr) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
-unsigned int (*nf_nat_sdp_hook)(struct sk_buff **pskb,
+unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp,
const char *dptr) __read_mostly;
@@ -363,7 +363,7 @@ int ct_sip_get_info(struct nf_conn *ct,
}
EXPORT_SYMBOL_GPL(ct_sip_get_info);
-static int set_expected_rtp(struct sk_buff **pskb,
+static int set_expected_rtp(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
union nf_conntrack_address *addr,
@@ -385,7 +385,7 @@ static int set_expected_rtp(struct sk_buff **pskb,
nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);
if (nf_nat_sdp && ct->status & IPS_NAT_MASK)
- ret = nf_nat_sdp(pskb, ctinfo, exp, dptr);
+ ret = nf_nat_sdp(skb, ctinfo, exp, dptr);
else {
if (nf_ct_expect_related(exp) != 0)
ret = NF_DROP;
@@ -397,7 +397,7 @@ static int set_expected_rtp(struct sk_buff **pskb,
return ret;
}
-static int sip_help(struct sk_buff **pskb,
+static int sip_help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
@@ -414,13 +414,13 @@ static int sip_help(struct sk_buff **pskb,
/* No Data ? */
dataoff = protoff + sizeof(struct udphdr);
- if (dataoff >= (*pskb)->len)
+ if (dataoff >= skb->len)
return NF_ACCEPT;
- nf_ct_refresh(ct, *pskb, sip_timeout * HZ);
+ nf_ct_refresh(ct, skb, sip_timeout * HZ);
- if (!skb_is_nonlinear(*pskb))
- dptr = (*pskb)->data + dataoff;
+ if (!skb_is_nonlinear(skb))
+ dptr = skb->data + dataoff;
else {
pr_debug("Copy of skbuff not supported yet.\n");
goto out;
@@ -428,13 +428,13 @@ static int sip_help(struct sk_buff **pskb,
nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
if (nf_nat_sip && ct->status & IPS_NAT_MASK) {
- if (!nf_nat_sip(pskb, ctinfo, ct, &dptr)) {
+ if (!nf_nat_sip(skb, ctinfo, ct, &dptr)) {
ret = NF_DROP;
goto out;
}
}
- datalen = (*pskb)->len - dataoff;
+ datalen = skb->len - dataoff;
if (datalen < sizeof("SIP/2.0 200") - 1)
goto out;
@@ -464,7 +464,7 @@ static int sip_help(struct sk_buff **pskb,
ret = NF_DROP;
goto out;
}
- ret = set_expected_rtp(pskb, ct, ctinfo, &addr,
+ ret = set_expected_rtp(skb, ct, ctinfo, &addr,
htons(port), dptr);
}
}
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index cc19506cf2f..e894aa1ff3a 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -29,12 +29,12 @@ static int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
-unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
+unsigned int (*nf_nat_tftp_hook)(struct sk_buff *skb,
enum ip_conntrack_info ctinfo,
struct nf_conntrack_expect *exp) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);
-static int tftp_help(struct sk_buff **pskb,
+static int tftp_help(struct sk_buff *skb,
unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
@@ -46,7 +46,7 @@ static int tftp_help(struct sk_buff **pskb,
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
typeof(nf_nat_tftp_hook) nf_nat_tftp;
- tfh = skb_header_pointer(*pskb, protoff + sizeof(struct udphdr),
+ tfh = skb_header_pointer(skb, protoff + sizeof(struct udphdr),
sizeof(_tftph), &_tftph);
if (tfh == NULL)
return NF_ACCEPT;
@@ -70,7 +70,7 @@ static int tftp_help(struct sk_buff **pskb,
nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
- ret = nf_nat_tftp(pskb, ctinfo, exp);
+ ret = nf_nat_tftp(skb, ctinfo, exp);
else if (nf_ct_expect_related(exp) != 0)
ret = NF_DROP;
nf_ct_expect_put(exp);
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
index 0df7fff196a..196269c1e58 100644
--- a/net/netfilter/nf_internals.h
+++ b/net/netfilter/nf_internals.h
@@ -14,7 +14,7 @@
/* core.c */
extern unsigned int nf_iterate(struct list_head *head,
- struct sk_buff **skb,
+ struct sk_buff *skb,
int hook,
const struct net_device *indev,
const struct net_device *outdev,
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index a481a349f7b..0cef1433d66 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -256,14 +256,14 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
if (verdict == NF_ACCEPT) {
afinfo = nf_get_afinfo(info->pf);
- if (!afinfo || afinfo->reroute(&skb, info) < 0)
+ if (!afinfo || afinfo->reroute(skb, info) < 0)
verdict = NF_DROP;
}
if (verdict == NF_ACCEPT) {
next_hook:
verdict = nf_iterate(&nf_hooks[info->pf][info->hook],
- &skb, info->hook,
+ skb, info->hook,
info->indev, info->outdev, &elem,
info->okfn, INT_MIN);
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 49f0480afe0..3ceeffcf6f9 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -617,6 +617,7 @@ static int
nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
{
int diff;
+ int err;
diff = data_len - e->skb->len;
if (diff < 0) {
@@ -626,25 +627,18 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
if (data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
- struct sk_buff *newskb;
-
- newskb = skb_copy_expand(e->skb,
- skb_headroom(e->skb),
- diff,
- GFP_ATOMIC);
- if (newskb == NULL) {
+ err = pskb_expand_head(e->skb, 0,
+ diff - skb_tailroom(e->skb),
+ GFP_ATOMIC);
+ if (err) {
printk(KERN_WARNING "nf_queue: OOM "
"in mangle, dropping packet\n");
- return -ENOMEM;
+ return err;
}
- if (e->skb->sk)
- skb_set_owner_w(newskb, e->skb->sk);
- kfree_skb(e->skb);
- e->skb = newskb;
}
skb_put(e->skb, diff);
}
- if (!skb_make_writable(&e->skb, data_len))
+ if (!skb_make_writable(e->skb, data_len))
return -ENOMEM;
skb_copy_to_linear_data(e->skb, data, data_len);
e->skb->ip_summed = CHECKSUM_NONE;
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 07a1b966500..77eeae658d4 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -27,7 +27,7 @@ MODULE_ALIAS("ipt_CLASSIFY");
MODULE_ALIAS("ip6t_CLASSIFY");
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -36,7 +36,7 @@ target(struct sk_buff **pskb,
{
const struct xt_classify_target_info *clinfo = targinfo;
- (*pskb)->priority = clinfo->priority;
+ skb->priority = clinfo->priority;
return XT_CONTINUE;
}
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 7043c2757e0..8cc324b159e 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -34,7 +34,7 @@ MODULE_ALIAS("ip6t_CONNMARK");
#include <net/netfilter/nf_conntrack_ecache.h>
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -48,28 +48,28 @@ target(struct sk_buff **pskb,
u_int32_t mark;
u_int32_t newmark;
- ct = nf_ct_get(*pskb, &ctinfo);
+ ct = nf_ct_get(skb, &ctinfo);
if (ct) {
switch(markinfo->mode) {
case XT_CONNMARK_SET:
newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
if (newmark != ct->mark) {
ct->mark = newmark;
- nf_conntrack_event_cache(IPCT_MARK, *pskb);
+ nf_conntrack_event_cache(IPCT_MARK, skb);
}
break;
case XT_CONNMARK_SAVE:
newmark = (ct->mark & ~markinfo->mask) |
- ((*pskb)->mark & markinfo->mask);
+ (skb->mark & markinfo->mask);
if (ct->mark != newmark) {
ct->mark = newmark;
- nf_conntrack_event_cache(IPCT_MARK, *pskb);
+ nf_conntrack_event_cache(IPCT_MARK, skb);
}
break;
case XT_CONNMARK_RESTORE:
- mark = (*pskb)->mark;
+ mark = skb->mark;
diff = (ct->mark ^ mark) & markinfo->mask;
- (*pskb)->mark = mark ^ diff;
+ skb->mark = mark ^ diff;
break;
}
}
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 63d73138c1b..021b5c8d20e 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -61,12 +61,11 @@ static void secmark_restore(struct sk_buff *skb)
}
}
-static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
+static unsigned int target(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{
- struct sk_buff *skb = *pskb;
const struct xt_connsecmark_target_info *info = targinfo;
switch (info->mode) {
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 798ab731009..6322a933ab7 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -25,7 +25,7 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_DSCP");
MODULE_ALIAS("ip6t_DSCP");
-static unsigned int target(struct sk_buff **pskb,
+static unsigned int target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -33,20 +33,20 @@ static unsigned int target(struct sk_buff **pskb,
const void *targinfo)
{
const struct xt_DSCP_info *dinfo = targinfo;
- u_int8_t dscp = ipv4_get_dsfield(ip_hdr(*pskb)) >> XT_DSCP_SHIFT;
+ u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
if (dscp != dinfo->dscp) {
- if (!skb_make_writable(pskb, sizeof(struct iphdr)))
+ if (!skb_make_writable(skb, sizeof(struct iphdr)))
return NF_DROP;
- ipv4_change_dsfield(ip_hdr(*pskb), (__u8)(~XT_DSCP_MASK),
+ ipv4_change_dsfield(ip_hdr(skb), (__u8)(~XT_DSCP_MASK),
dinfo->dscp << XT_DSCP_SHIFT);
}
return XT_CONTINUE;
}
-static unsigned int target6(struct sk_buff **pskb,
+static unsigned int target6(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -54,13 +54,13 @@ static unsigned int target6(struct sk_buff **pskb,
const void *targinfo)
{
const struct xt_DSCP_info *dinfo = targinfo;
- u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(*pskb)) >> XT_DSCP_SHIFT;
+ u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
if (dscp != dinfo->dscp) {
- if (!skb_make_writable(pskb, sizeof(struct ipv6hdr)))
+ if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
return NF_DROP;
- ipv6_change_dsfield(ipv6_hdr(*pskb), (__u8)(~XT_DSCP_MASK),
+ ipv6_change_dsfield(ipv6_hdr(skb), (__u8)(~XT_DSCP_MASK),
dinfo->dscp << XT_DSCP_SHIFT);
}
return XT_CONTINUE;
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index f30fe0baf7d..bc6503d77d7 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -22,7 +22,7 @@ MODULE_ALIAS("ipt_MARK");
MODULE_ALIAS("ip6t_MARK");
static unsigned int
-target_v0(struct sk_buff **pskb,
+target_v0(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -31,12 +31,12 @@ target_v0(struct sk_buff **pskb,
{
const struct xt_mark_target_info *markinfo = targinfo;
- (*pskb)->mark = markinfo->mark;
+ skb->mark = markinfo->mark;
return XT_CONTINUE;
}
static unsigned int
-target_v1(struct sk_buff **pskb,
+target_v1(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -52,15 +52,15 @@ target_v1(struct sk_buff **pskb,
break;
case XT_MARK_AND:
- mark = (*pskb)->mark & markinfo->mark;
+ mark = skb->mark & markinfo->mark;
break;
case XT_MARK_OR:
- mark = (*pskb)->mark | markinfo->mark;
+ mark = skb->mark | markinfo->mark;
break;
}
- (*pskb)->mark = mark;
+ skb->mark = mark;
return XT_CONTINUE;
}
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index d3594c7ccb2..9fb449ffbf8 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -20,7 +20,7 @@ MODULE_ALIAS("ipt_NFLOG");
MODULE_ALIAS("ip6t_NFLOG");
static unsigned int
-nflog_target(struct sk_buff **pskb,
+nflog_target(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target,
const void *targinfo)
@@ -33,7 +33,7 @@ nflog_target(struct sk_buff **pskb,
li.u.ulog.group = info->group;
li.u.ulog.qthreshold = info->threshold;
- nf_log_packet(target->family, hooknum, *pskb, in, out, &li,
+ nf_log_packet(target->family, hooknum, skb, in, out, &li,
"%s", info->prefix);
return XT_CONTINUE;
}
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 13f59f3e8c3..c3984e9f766 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -24,7 +24,7 @@ MODULE_ALIAS("ip6t_NFQUEUE");
MODULE_ALIAS("arpt_NFQUEUE");
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index fec1aefb1c3..4976ce18661 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -12,7 +12,7 @@ MODULE_ALIAS("ipt_NOTRACK");
MODULE_ALIAS("ip6t_NOTRACK");
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
@@ -20,16 +20,16 @@ target(struct sk_buff **pskb,
const void *targinfo)
{
/* Previously seen (loopback)? Ignore. */
- if ((*pskb)->nfct != NULL)
+ if (skb->nfct != NULL)
return XT_CONTINUE;
/* Attach fake conntrack entry.
If there is a real ct entry correspondig to this packet,
it'll hang aroun till timing out. We don't deal with it
for performance reasons. JK */
- (*pskb)->nfct = &nf_conntrack_untracked.ct_general;
- (*pskb)->nfctinfo = IP_CT_NEW;
- nf_conntrack_get((*pskb)->nfct);
+ skb->nfct = &nf_conntrack_untracked.ct_general;
+ skb->nfctinfo = IP_CT_NEW;
+ nf_conntrack_get(skb->nfct);
return XT_CONTINUE;
}
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index c83779a941a..235806eb6ec 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -28,7 +28,7 @@ MODULE_ALIAS("ip6t_SECMARK");
static u8 mode;
-static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
+static unsigned int target(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
@@ -47,7 +47,7 @@ static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
BUG();
}
- (*pskb)->secmark = secmark;
+ skb->secmark = secmark;
return XT_CONTINUE;
}
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index d40f7e4b128..07435a602b1 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -39,7 +39,7 @@ optlen(const u_int8_t *opt, unsigned int offset)
}
static int
-tcpmss_mangle_packet(struct sk_buff **pskb,
+tcpmss_mangle_packet(struct sk_buff *skb,
const struct xt_tcpmss_info *info,
unsigned int tcphoff,
unsigned int minlen)
@@ -50,11 +50,11 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
u16 newmss;
u8 *opt;
- if (!skb_make_writable(pskb, (*pskb)->len))
+ if (!skb_make_writable(skb, skb->len))
return -1;
- tcplen = (*pskb)->len - tcphoff;
- tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
+ tcplen = skb->len - tcphoff;
+ tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
/* Since it passed flags test in tcp match, we know it is is
not a fragment, and has data >= tcp header length. SYN
@@ -64,19 +64,19 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
if (tcplen != tcph->doff*4) {
if (net_ratelimit())
printk(KERN_ERR "xt_TCPMSS: bad length (%u bytes)\n",
- (*pskb)->len);
+ skb->len);
return -1;
}
if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
- if (dst_mtu((*pskb)->dst) <= minlen) {
+ if (dst_mtu(skb->dst) <= minlen) {
if (net_ratelimit())
printk(KERN_ERR "xt_TCPMSS: "
"unknown or invalid path-MTU (%u)\n",
- dst_mtu((*pskb)->dst));
+ dst_mtu(skb->dst));
return -1;
}
- newmss = dst_mtu((*pskb)->dst) - minlen;
+ newmss = dst_mtu(skb->dst) - minlen;
} else
newmss = info->mss;
@@ -95,7 +95,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
opt[i+2] = (newmss & 0xff00) >> 8;
opt[i+3] = newmss & 0x00ff;
- nf_proto_csum_replace2(&tcph->check, *pskb,
+ nf_proto_csum_replace2(&tcph->check, skb,
htons(oldmss), htons(newmss), 0);
return 0;
}
@@ -104,57 +104,53 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
/*
* MSS Option not found ?! add it..
*/
- if (skb_tailroom((*pskb)) < TCPOLEN_MSS) {
- struct sk_buff *newskb;
-
- newskb = skb_copy_expand(*pskb, skb_headroom(*pskb),
- TCPOLEN_MSS, GFP_ATOMIC);
- if (!newskb)
+ if (skb_tailroom(skb) < TCPOLEN_MSS) {
+ if (pskb_expand_head(skb, 0,
+ TCPOLEN_MSS - skb_tailroom(skb),
+ GFP_ATOMIC))
return -1;
- kfree_skb(*pskb);
- *pskb = newskb;
- tcph = (struct tcphdr *)(skb_network_header(*pskb) + tcphoff);
+ tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
}
- skb_put((*pskb), TCPOLEN_MSS);
+ skb_put(skb, TCPOLEN_MSS);
opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
- nf_proto_csum_replace2(&tcph->check, *pskb,
+ nf_proto_csum_replace2(&tcph->check, skb,
htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
opt[0] = TCPOPT_MSS;
opt[1] = TCPOLEN_MSS;
opt[2] = (newmss & 0xff00) >> 8;
opt[3] = newmss & 0x00ff;
- nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0);
+ nf_proto_csum_replace4(&tcph->check, skb, 0, *((__be32 *)opt), 0);
oldval = ((__be16 *)tcph)[6];
tcph->doff += TCPOLEN_MSS/4;
- nf_proto_csum_replace2(&tcph->check, *pskb,
+ nf_proto_csum_replace2(&tcph->check, skb,
oldval, ((__be16 *)tcph)[6], 0);
return TCPOLEN_MSS;
}
static unsigned int
-xt_tcpmss_target4(struct sk_buff **pskb,
+xt_tcpmss_target4(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{
- struct iphdr *iph = ip_hdr(*pskb);
+ struct iphdr *iph = ip_hdr(skb);
__be16 newlen;
int ret;
- ret = tcpmss_mangle_packet(pskb, targinfo, iph->ihl * 4,
+ ret = tcpmss_mangle_packet(skb, targinfo, iph->ihl * 4,
sizeof(*iph) + sizeof(struct tcphdr));
if (ret < 0)
return NF_DROP;
if (ret > 0) {
- iph = ip_hdr(*pskb);
+ iph = ip_hdr(skb);
newlen = htons(ntohs(iph->tot_len) + ret);
nf_csum_replace2(&iph->check, iph->tot_len, newlen);
iph->tot_len = newlen;
@@ -164,30 +160,30 @@ xt_tcpmss_target4(struct sk_buff **pskb,
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
static unsigned int
-xt_tcpmss_target6(struct sk_buff **pskb,
+xt_tcpmss_target6(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{
- struct ipv6hdr *ipv6h = ipv6_hdr(*pskb);
+ struct ipv6hdr *ipv6h = ipv6_hdr(skb);
u8 nexthdr;
int tcphoff;
int ret;
nexthdr = ipv6h->nexthdr;
- tcphoff = ipv6_skip_exthdr(*pskb, sizeof(*ipv6h), &nexthdr);
+ tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
if (tcphoff < 0) {
WARN_ON(1);
return NF_DROP;
}
- ret = tcpmss_mangle_packet(pskb, targinfo, tcphoff,
+ ret = tcpmss_mangle_packet(skb, targinfo, tcphoff,
sizeof(*ipv6h) + sizeof(struct tcphdr));
if (ret < 0)
return NF_DROP;
if (ret > 0) {
- ipv6h = ipv6_hdr(*pskb);
+ ipv6h = ipv6_hdr(skb);
ipv6h->payload_len = htons(ntohs(ipv6h->payload_len) + ret);
}
return XT_CONTINUE;
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
index 4df2dedcc0b..26c5d08ab2c 100644
--- a/net/netfilter/xt_TRACE.c
+++ b/net/netfilter/xt_TRACE.c
@@ -10,14 +10,14 @@ MODULE_ALIAS("ipt_TRACE");
MODULE_ALIAS("ip6t_TRACE");
static unsigned int
-target(struct sk_buff **pskb,
+target(struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
unsigned int hooknum,
const struct xt_target *target,
const void *targinfo)
{
- (*pskb)->nf_trace = 1;
+ skb->nf_trace = 1;
return XT_CONTINUE;
}
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index f907770fd4e..3358273a47b 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -42,21 +42,21 @@ match_flags(const struct xt_sctp_flag_info *flag_info,
static inline bool
match_packet(const struct sk_buff *skb,
unsigned int offset,
- const u_int32_t *chunkmap,
- int chunk_match_type,
- const struct xt_sctp_flag_info *flag_info,
- const int flag_count,
+ const struct xt_sctp_info *info,
bool *hotdrop)
{
u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
sctp_chunkhdr_t _sch, *sch;
+ int chunk_match_type = info->chunk_match_type;
+ const struct xt_sctp_flag_info *flag_info = info->flag_info;
+ int flag_count = info->flag_count;
#ifdef DEBUG_SCTP
int i = 0;
#endif
if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
- SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
+ SCTP_CHUNKMAP_COPY(chunkmapcopy, info->chunkmap);
do {
sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
@@ -73,7 +73,7 @@ match_packet(const struct sk_buff *skb,
duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
- if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) {
+ if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) {
switch (chunk_match_type) {
case SCTP_CHUNK_MATCH_ANY:
if (match_flags(flag_info, flag_count,
@@ -104,7 +104,7 @@ match_packet(const struct sk_buff *skb,
switch (chunk_match_type) {
case SCTP_CHUNK_MATCH_ALL:
- return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
+ return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap);
case SCTP_CHUNK_MATCH_ANY:
return false;
case SCTP_CHUNK_MATCH_ONLY:
@@ -148,9 +148,7 @@ match(const struct sk_buff *skb,
&& ntohs(sh->dest) <= info->dpts[1],
XT_SCTP_DEST_PORTS, info->flags, info->invflags)
&& SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
- info->chunkmap, info->chunk_match_type,
- info->flag_info, info->flag_count,
- hotdrop),
+ info, hotdrop),
XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index c776bcd9f82..98e313e5e59 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1378,6 +1378,8 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
nl_table[unit].cb_mutex = cb_mutex;
nl_table[unit].module = module;
nl_table[unit].registered = 1;
+ } else {
+ kfree(listeners);
}
netlink_table_ungrab();
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 0803f305ed0..c680017f5c8 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
+#include <linux/key-type.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 7e049ff6ae6..9a8ff684da7 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -15,7 +15,7 @@
#include <linux/module.h>
#include <linux/net.h>
#include <linux/skbuff.h>
-#include <linux/key.h>
+#include <linux/key-type.h>
#include <linux/crypto.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
@@ -40,7 +40,6 @@ struct key_type key_type_rxrpc = {
.destroy = rxrpc_destroy,
.describe = rxrpc_describe,
};
-
EXPORT_SYMBOL(key_type_rxrpc);
/*
@@ -330,5 +329,32 @@ error:
_leave(" = -ENOMEM [ins %d]", ret);
return -ENOMEM;
}
-
EXPORT_SYMBOL(rxrpc_get_server_data_key);
+
+/**
+ * rxrpc_get_null_key - Generate a null RxRPC key
+ * @keyname: The name to give the key.
+ *
+ * Generate a null RxRPC key that can be used to indicate anonymous security is
+ * required for a particular domain.
+ */
+struct key *rxrpc_get_null_key(const char *keyname)
+{
+ struct key *key;
+ int ret;
+
+ key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current,
+ KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
+ if (IS_ERR(key))
+ return key;
+
+ ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
+ if (ret < 0) {
+ key_revoke(key);
+ key_put(key);
+ return ERR_PTR(ret);
+ }
+
+ return key;
+}
+EXPORT_SYMBOL(rxrpc_get_null_key);
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 6b407ece953..fa006e06ce3 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -202,11 +202,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
/* yes, we have to worry about both in and out dev
worry later - danger - this API seems to have changed
from earlier kernels */
-
- /* iptables targets take a double skb pointer in case the skb
- * needs to be replaced. We don't own the skb, so this must not
- * happen. The pskb_expand_head above should make sure of this */
- ret = ipt->tcfi_t->u.kernel.target->target(&skb, skb->dev, NULL,
+ ret = ipt->tcfi_t->u.kernel.target->target(skb, skb->dev, NULL,
ipt->tcfi_hook,
ipt->tcfi_t->u.kernel.target,
ipt->tcfi_t->data);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 95ae11956f3..e01d57692c9 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -249,10 +249,11 @@ static void dev_watchdog_down(struct net_device *dev)
*/
void netif_carrier_on(struct net_device *dev)
{
- if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state))
+ if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
linkwatch_fire_event(dev);
- if (netif_running(dev))
- __netdev_watchdog_up(dev);
+ if (netif_running(dev))
+ __netdev_watchdog_up(dev);
+ }
}
/**
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 2d32fd27496..3f8335e6ea2 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -205,20 +205,19 @@ static unsigned int ingress_drop(struct Qdisc *sch)
#ifndef CONFIG_NET_CLS_ACT
#ifdef CONFIG_NETFILTER
static unsigned int
-ing_hook(unsigned int hook, struct sk_buff **pskb,
+ing_hook(unsigned int hook, struct sk_buff *skb,
const struct net_device *indev,
const struct net_device *outdev,
int (*okfn)(struct sk_buff *))
{
struct Qdisc *q;
- struct sk_buff *skb = *pskb;
struct net_device *dev = skb->dev;
int fwres=NF_ACCEPT;
DPRINTK("ing_hook: skb %s dev=%s len=%u\n",
skb->sk ? "(owned)" : "(unowned)",
- skb->dev ? (*pskb)->dev->name : "(no dev)",
+ skb->dev ? skb->dev->name : "(no dev)",
skb->len);
if (dev->qdisc_ingress) {
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 9de3ddaa276..eb4deaf5891 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -954,9 +954,9 @@ static struct inet_protosw sctpv6_stream_protosw = {
.flags = SCTP_PROTOSW_FLAG,
};
-static int sctp6_rcv(struct sk_buff **pskb)
+static int sctp6_rcv(struct sk_buff *skb)
{
- return sctp_rcv(*pskb) ? -1 : 0;
+ return sctp_rcv(skb) ? -1 : 0;
}
static struct inet6_protocol sctpv6_protocol = {
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 81b26c5ffd4..f5cd96f5fe7 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1228,7 +1228,6 @@ SCTP_STATIC __init int sctp_init(void)
if (status)
goto err_v6_add_protocol;
- __unsafe(THIS_MODULE);
status = 0;
out:
return status;
diff --git a/net/socket.c b/net/socket.c
index 379b3a39075..540013ea862 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -258,7 +258,7 @@ static void sock_destroy_inode(struct inode *inode)
container_of(inode, struct socket_alloc, vfs_inode));
}
-static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
+static void init_once(struct kmem_cache *cachep, void *foo)
{
struct socket_alloc *ei = (struct socket_alloc *)foo;
@@ -364,26 +364,26 @@ static int sock_alloc_fd(struct file **filep)
static int sock_attach_fd(struct socket *sock, struct file *file)
{
+ struct dentry *dentry;
struct qstr name = { .name = "" };
- file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
- if (unlikely(!file->f_path.dentry))
+ dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
+ if (unlikely(!dentry))
return -ENOMEM;
- file->f_path.dentry->d_op = &sockfs_dentry_operations;
+ dentry->d_op = &sockfs_dentry_operations;
/*
* We dont want to push this dentry into global dentry hash table.
* We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
* This permits a working /proc/$pid/fd/XXX on sockets
*/
- file->f_path.dentry->d_flags &= ~DCACHE_UNHASHED;
- d_instantiate(file->f_path.dentry, SOCK_INODE(sock));
- file->f_path.mnt = mntget(sock_mnt);
- file->f_mapping = file->f_path.dentry->d_inode->i_mapping;
+ dentry->d_flags &= ~DCACHE_UNHASHED;
+ d_instantiate(dentry, SOCK_INODE(sock));
sock->file = file;
- file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
- file->f_mode = FMODE_READ | FMODE_WRITE;
+ init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
+ &socket_file_ops);
+ SOCK_INODE(sock)->i_fop = &socket_file_ops;
file->f_flags = O_RDWR;
file->f_pos = 0;
file->private_data = sock;
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
index 8ebfc4db7f5..5c69a725e53 100644
--- a/net/sunrpc/Makefile
+++ b/net/sunrpc/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_SUNRPC) += sunrpc.o
obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
+obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma/
sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \
auth.o auth_null.o auth_unix.o \
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 42b3220bed3..8bd074df27d 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -42,7 +42,7 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
{
u8 *ptr;
u8 pad;
- int len = buf->len;
+ size_t len = buf->len;
if (len <= buf->head[0].iov_len) {
pad = *(u8 *)(buf->head[0].iov_base + len - 1);
@@ -53,9 +53,9 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
} else
len -= buf->head[0].iov_len;
if (len <= buf->page_len) {
- int last = (buf->page_base + len - 1)
+ unsigned int last = (buf->page_base + len - 1)
>>PAGE_CACHE_SHIFT;
- int offset = (buf->page_base + len - 1)
+ unsigned int offset = (buf->page_base + len - 1)
& (PAGE_CACHE_SIZE - 1);
ptr = kmap_atomic(buf->pages[last], KM_USER0);
pad = *(ptr + offset);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 52429b1ffcc..76be83ee4b0 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -127,7 +127,14 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
struct rpc_clnt *clnt = NULL;
struct rpc_auth *auth;
int err;
- int len;
+ size_t len;
+
+ /* sanity check the name before trying to print it */
+ err = -EINVAL;
+ len = strlen(servname);
+ if (len > RPC_MAXNETNAMELEN)
+ goto out_no_rpciod;
+ len++;
dprintk("RPC: creating %s client for %s (xprt %p)\n",
program->name, servname, xprt);
@@ -148,7 +155,6 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
clnt->cl_parent = clnt;
clnt->cl_server = clnt->cl_inline_name;
- len = strlen(servname) + 1;
if (len > sizeof(clnt->cl_inline_name)) {
char *buf = kmalloc(len, GFP_KERNEL);
if (buf != 0)
@@ -234,8 +240,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
{
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
- struct rpc_xprtsock_create xprtargs = {
- .proto = args->protocol,
+ struct xprt_create xprtargs = {
+ .ident = args->protocol,
.srcaddr = args->saddress,
.dstaddr = args->address,
.addrlen = args->addrsize,
@@ -253,7 +259,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
*/
if (args->servername == NULL) {
struct sockaddr_in *addr =
- (struct sockaddr_in *) &args->address;
+ (struct sockaddr_in *) args->address;
snprintf(servername, sizeof(servername), NIPQUAD_FMT,
NIPQUAD(addr->sin_addr.s_addr));
args->servername = servername;
@@ -269,9 +275,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
xprt->resvport = 0;
- dprintk("RPC: creating %s client for %s (xprt %p)\n",
- args->program->name, args->servername, xprt);
-
clnt = rpc_new_client(xprt, args->servername, args->program,
args->version, args->authflavor);
if (IS_ERR(clnt))
@@ -439,7 +442,7 @@ rpc_release_client(struct rpc_clnt *clnt)
*/
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
struct rpc_program *program,
- int vers)
+ u32 vers)
{
struct rpc_clnt *clnt;
struct rpc_version *version;
@@ -843,8 +846,7 @@ call_allocate(struct rpc_task *task)
dprintk("RPC: %5u rpc_buffer allocation failed\n", task->tk_pid);
if (RPC_IS_ASYNC(task) || !signalled()) {
- xprt_release(task);
- task->tk_action = call_reserve;
+ task->tk_action = call_allocate;
rpc_delay(task, HZ>>4);
return;
}
@@ -871,6 +873,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
buf->head[0].iov_len = len;
buf->tail[0].iov_len = 0;
buf->page_len = 0;
+ buf->flags = 0;
buf->len = 0;
buf->buflen = len;
}
@@ -937,7 +940,7 @@ call_bind(struct rpc_task *task)
static void
call_bind_status(struct rpc_task *task)
{
- int status = -EACCES;
+ int status = -EIO;
if (task->tk_status >= 0) {
dprint_status(task);
@@ -947,9 +950,20 @@ call_bind_status(struct rpc_task *task)
}
switch (task->tk_status) {
+ case -EAGAIN:
+ dprintk("RPC: %5u rpcbind waiting for another request "
+ "to finish\n", task->tk_pid);
+ /* avoid busy-waiting here -- could be a network outage. */
+ rpc_delay(task, 5*HZ);
+ goto retry_timeout;
case -EACCES:
dprintk("RPC: %5u remote rpcbind: RPC program/version "
"unavailable\n", task->tk_pid);
+ /* fail immediately if this is an RPC ping */
+ if (task->tk_msg.rpc_proc->p_proc == 0) {
+ status = -EOPNOTSUPP;
+ break;
+ }
rpc_delay(task, 3*HZ);
goto retry_timeout;
case -ETIMEDOUT:
@@ -957,6 +971,7 @@ call_bind_status(struct rpc_task *task)
task->tk_pid);
goto retry_timeout;
case -EPFNOSUPPORT:
+ /* server doesn't support any rpcbind version we know of */
dprintk("RPC: %5u remote rpcbind service unavailable\n",
task->tk_pid);
break;
@@ -969,7 +984,6 @@ call_bind_status(struct rpc_task *task)
default:
dprintk("RPC: %5u unrecognized rpcbind error (%d)\n",
task->tk_pid, -task->tk_status);
- status = -EIO;
}
rpc_exit(task, status);
@@ -1257,7 +1271,6 @@ call_refresh(struct rpc_task *task)
{
dprint_status(task);
- xprt_release(task); /* Must do to obtain new XID */
task->tk_action = call_refreshresult;
task->tk_status = 0;
task->tk_client->cl_stats->rpcauthrefresh++;
@@ -1375,6 +1388,8 @@ call_verify(struct rpc_task *task)
dprintk("RPC: %5u %s: retry stale creds\n",
task->tk_pid, __FUNCTION__);
rpcauth_invalcred(task);
+ /* Ensure we obtain a new XID! */
+ xprt_release(task);
task->tk_action = call_refresh;
goto out_retry;
case RPC_AUTH_BADCRED:
@@ -1523,13 +1538,18 @@ void rpc_show_tasks(void)
spin_lock(&clnt->cl_lock);
list_for_each_entry(t, &clnt->cl_tasks, tk_task) {
const char *rpc_waitq = "none";
+ int proc;
+
+ if (t->tk_msg.rpc_proc)
+ proc = t->tk_msg.rpc_proc->p_proc;
+ else
+ proc = -1;
if (RPC_IS_QUEUED(t))
rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
- t->tk_pid,
- (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
+ t->tk_pid, proc,
t->tk_flags, t->tk_status,
t->tk_client,
(t->tk_client ? t->tk_client->cl_prog : 0),
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 669e12a4ed1..18f0a8dcc09 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -14,7 +14,7 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/namei.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
#include <linux/kernel.h>
#include <asm/ioctls.h>
@@ -329,6 +329,7 @@ rpc_show_info(struct seq_file *m, void *v)
clnt->cl_prog, clnt->cl_vers);
seq_printf(m, "address: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR));
seq_printf(m, "protocol: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PROTO));
+ seq_printf(m, "port: %s\n", rpc_peeraddr2str(clnt, RPC_DISPLAY_PORT));
return 0;
}
@@ -585,6 +586,7 @@ rpc_populate(struct dentry *parent,
if (S_ISDIR(mode))
inc_nlink(dir);
d_add(dentry, inode);
+ fsnotify_create(dir, dentry);
}
mutex_unlock(&dir->i_mutex);
return 0;
@@ -606,7 +608,7 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry)
inode->i_ino = iunique(dir->i_sb, 100);
d_instantiate(dentry, inode);
inc_nlink(dir);
- inode_dir_notify(dir, DN_CREATE);
+ fsnotify_mkdir(dir, dentry);
return 0;
out_err:
printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
@@ -748,7 +750,7 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
rpci->flags = flags;
rpci->ops = ops;
rpci->nkern_readwriters = 1;
- inode_dir_notify(dir, DN_CREATE);
+ fsnotify_create(dir, dentry);
dget(dentry);
out:
mutex_unlock(&dir->i_mutex);
@@ -840,7 +842,7 @@ static struct file_system_type rpc_pipe_fs_type = {
};
static void
-init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
+init_once(struct kmem_cache * cachep, void *foo)
{
struct rpc_inode *rpci = (struct rpc_inode *) foo;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index d1740dbab99..a05493aedb6 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -16,11 +16,14 @@
#include <linux/types.h>
#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/xprtsock.h>
#ifdef RPC_DEBUG
# define RPCDBG_FACILITY RPCDBG_BIND
@@ -91,26 +94,6 @@ enum {
#define RPCB_MAXADDRLEN (128u)
/*
- * r_netid
- *
- * Quoting RFC 3530, section 2.2:
- *
- * For TCP over IPv4 the value of r_netid is the string "tcp". For UDP
- * over IPv4 the value of r_netid is the string "udp".
- *
- * ...
- *
- * For TCP over IPv6 the value of r_netid is the string "tcp6". For UDP
- * over IPv6 the value of r_netid is the string "udp6".
- */
-#define RPCB_NETID_UDP "\165\144\160" /* "udp" */
-#define RPCB_NETID_TCP "\164\143\160" /* "tcp" */
-#define RPCB_NETID_UDP6 "\165\144\160\066" /* "udp6" */
-#define RPCB_NETID_TCP6 "\164\143\160\066" /* "tcp6" */
-
-#define RPCB_MAXNETIDLEN (4u)
-
-/*
* r_owner
*
* The "owner" is allowed to unset a service in the rpcbind database.
@@ -120,7 +103,7 @@ enum {
#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
static void rpcb_getport_done(struct rpc_task *, void *);
-extern struct rpc_program rpcb_program;
+static struct rpc_program rpcb_program;
struct rpcbind_args {
struct rpc_xprt * r_xprt;
@@ -137,10 +120,13 @@ struct rpcbind_args {
static struct rpc_procinfo rpcb_procedures2[];
static struct rpc_procinfo rpcb_procedures3[];
-static struct rpcb_info {
+struct rpcb_info {
int rpc_vers;
struct rpc_procinfo * rpc_proc;
-} rpcb_next_version[];
+};
+
+static struct rpcb_info rpcb_next_version[];
+static struct rpcb_info rpcb_next_version6[];
static void rpcb_getport_prepare(struct rpc_task *task, void *calldata)
{
@@ -190,7 +176,17 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
RPC_CLNT_CREATE_INTR),
};
- ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
+ switch (srvaddr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
+ break;
+ default:
+ return NULL;
+ }
+
if (!privileged)
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
return rpc_create(&args);
@@ -234,7 +230,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
prog, vers, prot, port);
rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin,
- IPPROTO_UDP, 2, 1);
+ XPRT_TRANSPORT_UDP, 2, 1);
if (IS_ERR(rpcb_clnt))
return PTR_ERR(rpcb_clnt);
@@ -316,6 +312,7 @@ void rpcb_getport_async(struct rpc_task *task)
struct rpc_task *child;
struct sockaddr addr;
int status;
+ struct rpcb_info *info;
dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
task->tk_pid, __FUNCTION__,
@@ -325,7 +322,7 @@ void rpcb_getport_async(struct rpc_task *task)
BUG_ON(clnt->cl_parent != clnt);
if (xprt_test_and_set_binding(xprt)) {
- status = -EACCES; /* tell caller to check again */
+ status = -EAGAIN; /* tell caller to check again */
dprintk("RPC: %5u %s: waiting for another binder\n",
task->tk_pid, __FUNCTION__);
goto bailout_nowake;
@@ -343,18 +340,43 @@ void rpcb_getport_async(struct rpc_task *task)
goto bailout_nofree;
}
- if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) {
+ rpc_peeraddr(clnt, (void *)&addr, sizeof(addr));
+
+ /* Don't ever use rpcbind v2 for AF_INET6 requests */
+ switch (addr.sa_family) {
+ case AF_INET:
+ info = rpcb_next_version;
+ break;
+ case AF_INET6:
+ info = rpcb_next_version6;
+ break;
+ default:
+ status = -EAFNOSUPPORT;
+ dprintk("RPC: %5u %s: bad address family\n",
+ task->tk_pid, __FUNCTION__);
+ goto bailout_nofree;
+ }
+ if (info[xprt->bind_index].rpc_proc == NULL) {
xprt->bind_index = 0;
- status = -EACCES; /* tell caller to try again later */
+ status = -EPFNOSUPPORT;
dprintk("RPC: %5u %s: no more getport versions available\n",
task->tk_pid, __FUNCTION__);
goto bailout_nofree;
}
- bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
+ bind_version = info[xprt->bind_index].rpc_vers;
dprintk("RPC: %5u %s: trying rpcbind version %u\n",
task->tk_pid, __FUNCTION__, bind_version);
+ rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot,
+ bind_version, 0);
+ if (IS_ERR(rpcb_clnt)) {
+ status = PTR_ERR(rpcb_clnt);
+ dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
+ task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt));
+ goto bailout_nofree;
+ }
+
map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
if (!map) {
status = -ENOMEM;
@@ -367,28 +389,19 @@ void rpcb_getport_async(struct rpc_task *task)
map->r_prot = xprt->prot;
map->r_port = 0;
map->r_xprt = xprt_get(xprt);
- map->r_netid = (xprt->prot == IPPROTO_TCP) ? RPCB_NETID_TCP :
- RPCB_NETID_UDP;
- memcpy(&map->r_addr, rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR),
- sizeof(map->r_addr));
+ map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
+ memcpy(map->r_addr,
+ rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR),
+ sizeof(map->r_addr));
map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */
- rpc_peeraddr(clnt, (void *)&addr, sizeof(addr));
- rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0);
- if (IS_ERR(rpcb_clnt)) {
- status = PTR_ERR(rpcb_clnt);
- dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
- task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt));
- goto bailout;
- }
-
child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map);
rpc_release_client(rpcb_clnt);
if (IS_ERR(child)) {
status = -EIO;
dprintk("RPC: %5u %s: rpc_run_task failed\n",
task->tk_pid, __FUNCTION__);
- goto bailout_nofree;
+ goto bailout;
}
rpc_put_task(child);
@@ -403,6 +416,7 @@ bailout_nofree:
bailout_nowake:
task->tk_status = status;
}
+EXPORT_SYMBOL_GPL(rpcb_getport_async);
/*
* Rpcbind child task calls this callback via tk_exit.
@@ -413,6 +427,10 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
struct rpc_xprt *xprt = map->r_xprt;
int status = child->tk_status;
+ /* Garbage reply: retry with a lesser rpcbind version */
+ if (status == -EIO)
+ status = -EPROTONOSUPPORT;
+
/* rpcbind server doesn't support this rpcbind protocol version */
if (status == -EPROTONOSUPPORT)
xprt->bind_index++;
@@ -490,16 +508,24 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
unsigned short *portp)
{
char *addr;
- int addr_len, c, i, f, first, val;
+ u32 addr_len;
+ int c, i, f, first, val;
*portp = 0;
- addr_len = (unsigned int) ntohl(*p++);
- if (addr_len > RPCB_MAXADDRLEN) /* sanity */
- return -EINVAL;
-
- dprintk("RPC: rpcb_decode_getaddr returned string: '%s'\n",
- (char *) p);
-
+ addr_len = ntohl(*p++);
+
+ /*
+ * Simple sanity check. The smallest possible universal
+ * address is an IPv4 address string containing 11 bytes.
+ */
+ if (addr_len < 11 || addr_len > RPCB_MAXADDRLEN)
+ goto out_err;
+
+ /*
+ * Start at the end and walk backwards until the first dot
+ * is encountered. When the second dot is found, we have
+ * both parts of the port number.
+ */
addr = (char *)p;
val = 0;
first = 1;
@@ -521,8 +547,19 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
}
}
+ /*
+ * Simple sanity check. If we never saw a dot in the reply,
+ * then this was probably just garbage.
+ */
+ if (first)
+ goto out_err;
+
dprintk("RPC: rpcb_decode_getaddr port=%u\n", *portp);
return 0;
+
+out_err:
+ dprintk("RPC: rpcbind server returned malformed reply\n");
+ return -EIO;
}
#define RPCB_program_sz (1u)
@@ -531,7 +568,7 @@ static int rpcb_decode_getaddr(struct rpc_rqst *req, __be32 *p,
#define RPCB_port_sz (1u)
#define RPCB_boolean_sz (1u)
-#define RPCB_netid_sz (1+XDR_QUADLEN(RPCB_MAXNETIDLEN))
+#define RPCB_netid_sz (1+XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
#define RPCB_addr_sz (1+XDR_QUADLEN(RPCB_MAXADDRLEN))
#define RPCB_ownerstring_sz (1+XDR_QUADLEN(RPCB_MAXOWNERLEN))
@@ -593,6 +630,14 @@ static struct rpcb_info rpcb_next_version[] = {
{ 0, NULL },
};
+static struct rpcb_info rpcb_next_version6[] = {
+#ifdef CONFIG_SUNRPC_BIND34
+ { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] },
+ { 3, &rpcb_procedures3[RPCBPROC_GETADDR] },
+#endif
+ { 0, NULL },
+};
+
static struct rpc_version rpcb_version2 = {
.number = 2,
.nrprocs = RPCB_HIGHPROC_2,
@@ -621,7 +666,7 @@ static struct rpc_version *rpcb_version[] = {
static struct rpc_stat rpcb_stats;
-struct rpc_program rpcb_program = {
+static struct rpc_program rpcb_program = {
.name = "rpcbind",
.number = RPCBIND_PROGRAM,
.nrvers = ARRAY_SIZE(rpcb_version),
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 954d7ec86c7..3c773c53e12 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -777,6 +777,7 @@ void *rpc_malloc(struct rpc_task *task, size_t size)
task->tk_pid, size, buf);
return &buf->data;
}
+EXPORT_SYMBOL_GPL(rpc_malloc);
/**
* rpc_free - free buffer allocated via rpc_malloc
@@ -802,6 +803,7 @@ void rpc_free(void *buffer)
else
kfree(buf);
}
+EXPORT_SYMBOL_GPL(rpc_free);
/*
* Creation and deletion of RPC task structures
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index 1d377d1ab7f..97ac45f034d 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -34,6 +34,7 @@ size_t xdr_skb_read_bits(struct xdr_skb_reader *desc, void *to, size_t len)
desc->offset += len;
return len;
}
+EXPORT_SYMBOL_GPL(xdr_skb_read_bits);
/**
* xdr_skb_read_and_csum_bits - copy and checksum from skb to buffer
@@ -137,6 +138,7 @@ copy_tail:
out:
return copied;
}
+EXPORT_SYMBOL_GPL(xdr_partial_copy_from_skb);
/**
* csum_partial_copy_to_xdr - checksum and copy data
@@ -179,3 +181,4 @@ no_checksum:
return -1;
return 0;
}
+EXPORT_SYMBOL_GPL(csum_partial_copy_to_xdr);
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 384c4ad5ab8..33d89e842c8 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -20,7 +20,7 @@
#include <linux/sunrpc/auth.h>
#include <linux/workqueue.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
-
+#include <linux/sunrpc/xprtsock.h>
/* RPC scheduler */
EXPORT_SYMBOL(rpc_execute);
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index 738db32a287..864b541bbf5 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -114,7 +114,6 @@ done:
static ctl_table debug_table[] = {
{
- .ctl_name = CTL_RPCDEBUG,
.procname = "rpc_debug",
.data = &rpc_debug,
.maxlen = sizeof(int),
@@ -122,7 +121,6 @@ static ctl_table debug_table[] = {
.proc_handler = &proc_dodebug
},
{
- .ctl_name = CTL_NFSDEBUG,
.procname = "nfs_debug",
.data = &nfs_debug,
.maxlen = sizeof(int),
@@ -130,7 +128,6 @@ static ctl_table debug_table[] = {
.proc_handler = &proc_dodebug
},
{
- .ctl_name = CTL_NFSDDEBUG,
.procname = "nfsd_debug",
.data = &nfsd_debug,
.maxlen = sizeof(int),
@@ -138,7 +135,6 @@ static ctl_table debug_table[] = {
.proc_handler = &proc_dodebug
},
{
- .ctl_name = CTL_NLMDEBUG,
.procname = "nlm_debug",
.data = &nlm_debug,
.maxlen = sizeof(int),
diff --git a/net/sunrpc/timer.c b/net/sunrpc/timer.c
index 8142fdb8a93..31becbf0926 100644
--- a/net/sunrpc/timer.c
+++ b/net/sunrpc/timer.c
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/unistd.h>
+#include <linux/module.h>
#include <linux/sunrpc/clnt.h>
@@ -40,6 +41,7 @@ rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
rt->ntimeouts[i] = 0;
}
}
+EXPORT_SYMBOL_GPL(rpc_init_rtt);
/*
* NB: When computing the smoothed RTT and standard deviation,
@@ -75,6 +77,7 @@ rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m)
if (*sdrtt < RPC_RTO_MIN)
*sdrtt = RPC_RTO_MIN;
}
+EXPORT_SYMBOL_GPL(rpc_update_rtt);
/*
* Estimate rto for an nfs rpc sent via. an unreliable datagram.
@@ -103,3 +106,4 @@ rpc_calc_rto(struct rpc_rtt *rt, unsigned timer)
return res;
}
+EXPORT_SYMBOL_GPL(rpc_calc_rto);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c8c2edccad7..282a9a2ec90 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -62,6 +62,9 @@ static inline void do_xprt_reserve(struct rpc_task *);
static void xprt_connect_status(struct rpc_task *task);
static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
+static spinlock_t xprt_list_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(xprt_list);
+
/*
* The transport code maintains an estimate on the maximum number of out-
* standing RPC requests, using a smoothed version of the congestion
@@ -81,6 +84,78 @@ static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
/**
+ * xprt_register_transport - register a transport implementation
+ * @transport: transport to register
+ *
+ * If a transport implementation is loaded as a kernel module, it can
+ * call this interface to make itself known to the RPC client.
+ *
+ * Returns:
+ * 0: transport successfully registered
+ * -EEXIST: transport already registered
+ * -EINVAL: transport module being unloaded
+ */
+int xprt_register_transport(struct xprt_class *transport)
+{
+ struct xprt_class *t;
+ int result;
+
+ result = -EEXIST;
+ spin_lock(&xprt_list_lock);
+ list_for_each_entry(t, &xprt_list, list) {
+ /* don't register the same transport class twice */
+ if (t->ident == transport->ident)
+ goto out;
+ }
+
+ result = -EINVAL;
+ if (try_module_get(THIS_MODULE)) {
+ list_add_tail(&transport->list, &xprt_list);
+ printk(KERN_INFO "RPC: Registered %s transport module.\n",
+ transport->name);
+ result = 0;
+ }
+
+out:
+ spin_unlock(&xprt_list_lock);
+ return result;
+}
+EXPORT_SYMBOL_GPL(xprt_register_transport);
+
+/**
+ * xprt_unregister_transport - unregister a transport implementation
+ * transport: transport to unregister
+ *
+ * Returns:
+ * 0: transport successfully unregistered
+ * -ENOENT: transport never registered
+ */
+int xprt_unregister_transport(struct xprt_class *transport)
+{
+ struct xprt_class *t;
+ int result;
+
+ result = 0;
+ spin_lock(&xprt_list_lock);
+ list_for_each_entry(t, &xprt_list, list) {
+ if (t == transport) {
+ printk(KERN_INFO
+ "RPC: Unregistered %s transport module.\n",
+ transport->name);
+ list_del_init(&transport->list);
+ module_put(THIS_MODULE);
+ goto out;
+ }
+ }
+ result = -ENOENT;
+
+out:
+ spin_unlock(&xprt_list_lock);
+ return result;
+}
+EXPORT_SYMBOL_GPL(xprt_unregister_transport);
+
+/**
* xprt_reserve_xprt - serialize write access to transports
* @task: task that is requesting access to the transport
*
@@ -118,6 +193,7 @@ out_sleep:
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
return 0;
}
+EXPORT_SYMBOL_GPL(xprt_reserve_xprt);
static void xprt_clear_locked(struct rpc_xprt *xprt)
{
@@ -167,6 +243,7 @@ out_sleep:
rpc_sleep_on(&xprt->sending, task, NULL, NULL);
return 0;
}
+EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong);
static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
@@ -246,6 +323,7 @@ void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
__xprt_lock_write_next(xprt);
}
}
+EXPORT_SYMBOL_GPL(xprt_release_xprt);
/**
* xprt_release_xprt_cong - allow other requests to use a transport
@@ -262,6 +340,7 @@ void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
__xprt_lock_write_next_cong(xprt);
}
}
+EXPORT_SYMBOL_GPL(xprt_release_xprt_cong);
static inline void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task *task)
{
@@ -314,6 +393,7 @@ void xprt_release_rqst_cong(struct rpc_task *task)
{
__xprt_put_cong(task->tk_xprt, task->tk_rqstp);
}
+EXPORT_SYMBOL_GPL(xprt_release_rqst_cong);
/**
* xprt_adjust_cwnd - adjust transport congestion window
@@ -345,6 +425,7 @@ void xprt_adjust_cwnd(struct rpc_task *task, int result)
xprt->cwnd = cwnd;
__xprt_put_cong(xprt, req);
}
+EXPORT_SYMBOL_GPL(xprt_adjust_cwnd);
/**
* xprt_wake_pending_tasks - wake all tasks on a transport's pending queue
@@ -359,6 +440,7 @@ void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status)
else
rpc_wake_up(&xprt->pending);
}
+EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);
/**
* xprt_wait_for_buffer_space - wait for transport output buffer to clear
@@ -373,6 +455,7 @@ void xprt_wait_for_buffer_space(struct rpc_task *task)
task->tk_timeout = req->rq_timeout;
rpc_sleep_on(&xprt->pending, task, NULL, NULL);
}
+EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
/**
* xprt_write_space - wake the task waiting for transport output buffer space
@@ -393,6 +476,7 @@ void xprt_write_space(struct rpc_xprt *xprt)
}
spin_unlock_bh(&xprt->transport_lock);
}
+EXPORT_SYMBOL_GPL(xprt_write_space);
/**
* xprt_set_retrans_timeout_def - set a request's retransmit timeout
@@ -406,6 +490,7 @@ void xprt_set_retrans_timeout_def(struct rpc_task *task)
{
task->tk_timeout = task->tk_rqstp->rq_timeout;
}
+EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_def);
/*
* xprt_set_retrans_timeout_rtt - set a request's retransmit timeout
@@ -425,6 +510,7 @@ void xprt_set_retrans_timeout_rtt(struct rpc_task *task)
if (task->tk_timeout > max_timeout || task->tk_timeout == 0)
task->tk_timeout = max_timeout;
}
+EXPORT_SYMBOL_GPL(xprt_set_retrans_timeout_rtt);
static void xprt_reset_majortimeo(struct rpc_rqst *req)
{
@@ -500,6 +586,7 @@ void xprt_disconnect(struct rpc_xprt *xprt)
xprt_wake_pending_tasks(xprt, -ENOTCONN);
spin_unlock_bh(&xprt->transport_lock);
}
+EXPORT_SYMBOL_GPL(xprt_disconnect);
static void
xprt_init_autodisconnect(unsigned long data)
@@ -610,6 +697,7 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
xprt->stat.bad_xids++;
return NULL;
}
+EXPORT_SYMBOL_GPL(xprt_lookup_rqst);
/**
* xprt_update_rtt - update an RPC client's RTT state after receiving a reply
@@ -629,6 +717,7 @@ void xprt_update_rtt(struct rpc_task *task)
rpc_set_timeo(rtt, timer, req->rq_ntrans - 1);
}
}
+EXPORT_SYMBOL_GPL(xprt_update_rtt);
/**
* xprt_complete_rqst - called when reply processing is complete
@@ -653,6 +742,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
req->rq_received = req->rq_private_buf.len = copied;
rpc_wake_up_task(task);
}
+EXPORT_SYMBOL_GPL(xprt_complete_rqst);
static void xprt_timer(struct rpc_task *task)
{
@@ -889,23 +979,25 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
* @args: rpc transport creation arguments
*
*/
-struct rpc_xprt *xprt_create_transport(struct rpc_xprtsock_create *args)
+struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
{
struct rpc_xprt *xprt;
struct rpc_rqst *req;
+ struct xprt_class *t;
- switch (args->proto) {
- case IPPROTO_UDP:
- xprt = xs_setup_udp(args);
- break;
- case IPPROTO_TCP:
- xprt = xs_setup_tcp(args);
- break;
- default:
- printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
- args->proto);
- return ERR_PTR(-EIO);
+ spin_lock(&xprt_list_lock);
+ list_for_each_entry(t, &xprt_list, list) {
+ if (t->ident == args->ident) {
+ spin_unlock(&xprt_list_lock);
+ goto found;
+ }
}
+ spin_unlock(&xprt_list_lock);
+ printk(KERN_ERR "RPC: transport (%d) not supported\n", args->ident);
+ return ERR_PTR(-EIO);
+
+found:
+ xprt = t->setup(args);
if (IS_ERR(xprt)) {
dprintk("RPC: xprt_create_transport: failed, %ld\n",
-PTR_ERR(xprt));
diff --git a/net/sunrpc/xprtrdma/Makefile b/net/sunrpc/xprtrdma/Makefile
new file mode 100644
index 00000000000..264f0feeb51
--- /dev/null
+++ b/net/sunrpc/xprtrdma/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SUNRPC_XPRT_RDMA) += xprtrdma.o
+
+xprtrdma-y := transport.o rpc_rdma.o verbs.o
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
new file mode 100644
index 00000000000..12db6358042
--- /dev/null
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the BSD-type
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Network Appliance, Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_rdma.c
+ *
+ * This file contains the guts of the RPC RDMA protocol, and
+ * does marshaling/unmarshaling, etc. It is also where interfacing
+ * to the Linux RPC framework lives.
+ */
+
+#include "xprt_rdma.h"
+
+#include <linux/highmem.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_TRANS
+#endif
+
+enum rpcrdma_chunktype {
+ rpcrdma_noch = 0,
+ rpcrdma_readch,
+ rpcrdma_areadch,
+ rpcrdma_writech,
+ rpcrdma_replych
+};
+
+#ifdef RPC_DEBUG
+static const char transfertypes[][12] = {
+ "pure inline", /* no chunks */
+ " read chunk", /* some argument via rdma read */
+ "*read chunk", /* entire request via rdma read */
+ "write chunk", /* some result via rdma write */
+ "reply chunk" /* entire reply via rdma write */
+};
+#endif
+
+/*
+ * Chunk assembly from upper layer xdr_buf.
+ *
+ * Prepare the passed-in xdr_buf into representation as RPC/RDMA chunk
+ * elements. Segments are then coalesced when registered, if possible
+ * within the selected memreg mode.
+ *
+ * Note, this routine is never called if the connection's memory
+ * registration strategy is 0 (bounce buffers).
+ */
+
+static int
+rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, int pos,
+ enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg, int nsegs)
+{
+ int len, n = 0, p;
+
+ if (pos == 0 && xdrbuf->head[0].iov_len) {
+ seg[n].mr_page = NULL;
+ seg[n].mr_offset = xdrbuf->head[0].iov_base;
+ seg[n].mr_len = xdrbuf->head[0].iov_len;
+ pos += xdrbuf->head[0].iov_len;
+ ++n;
+ }
+
+ if (xdrbuf->page_len && (xdrbuf->pages[0] != NULL)) {
+ if (n == nsegs)
+ return 0;
+ seg[n].mr_page = xdrbuf->pages[0];
+ seg[n].mr_offset = (void *)(unsigned long) xdrbuf->page_base;
+ seg[n].mr_len = min_t(u32,
+ PAGE_SIZE - xdrbuf->page_base, xdrbuf->page_len);
+ len = xdrbuf->page_len - seg[n].mr_len;
+ pos += len;
+ ++n;
+ p = 1;
+ while (len > 0) {
+ if (n == nsegs)
+ return 0;
+ seg[n].mr_page = xdrbuf->pages[p];
+ seg[n].mr_offset = NULL;
+ seg[n].mr_len = min_t(u32, PAGE_SIZE, len);
+ len -= seg[n].mr_len;
+ ++n;
+ ++p;
+ }
+ }
+
+ if (pos < xdrbuf->len && xdrbuf->tail[0].iov_len) {
+ if (n == nsegs)
+ return 0;
+ seg[n].mr_page = NULL;
+ seg[n].mr_offset = xdrbuf->tail[0].iov_base;
+ seg[n].mr_len = xdrbuf->tail[0].iov_len;
+ pos += xdrbuf->tail[0].iov_len;
+ ++n;
+ }
+
+ if (pos < xdrbuf->len)
+ dprintk("RPC: %s: marshaled only %d of %d\n",
+ __func__, pos, xdrbuf->len);
+
+ return n;
+}
+
+/*
+ * Create read/write chunk lists, and reply chunks, for RDMA
+ *
+ * Assume check against THRESHOLD has been done, and chunks are required.
+ * Assume only encoding one list entry for read|write chunks. The NFSv3
+ * protocol is simple enough to allow this as it only has a single "bulk
+ * result" in each procedure - complicated NFSv4 COMPOUNDs are not. (The
+ * RDMA/Sessions NFSv4 proposal addresses this for future v4 revs.)
+ *
+ * When used for a single reply chunk (which is a special write
+ * chunk used for the entire reply, rather than just the data), it
+ * is used primarily for READDIR and READLINK which would otherwise
+ * be severely size-limited by a small rdma inline read max. The server
+ * response will come back as an RDMA Write, followed by a message
+ * of type RDMA_NOMSG carrying the xid and length. As a result, reply
+ * chunks do not provide data alignment, however they do not require
+ * "fixup" (moving the response to the upper layer buffer) either.
+ *
+ * Encoding key for single-list chunks (HLOO = Handle32 Length32 Offset64):
+ *
+ * Read chunklist (a linked list):
+ * N elements, position P (same P for all chunks of same arg!):
+ * 1 - PHLOO - 1 - PHLOO - ... - 1 - PHLOO - 0
+ *
+ * Write chunklist (a list of (one) counted array):
+ * N elements:
+ * 1 - N - HLOO - HLOO - ... - HLOO - 0
+ *
+ * Reply chunk (a counted array):
+ * N elements:
+ * 1 - N - HLOO - HLOO - ... - HLOO
+ */
+
+static unsigned int
+rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
+ struct rpcrdma_msg *headerp, enum rpcrdma_chunktype type)
+{
+ struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_task->tk_xprt);
+ int nsegs, nchunks = 0;
+ int pos;
+ struct rpcrdma_mr_seg *seg = req->rl_segments;
+ struct rpcrdma_read_chunk *cur_rchunk = NULL;
+ struct rpcrdma_write_array *warray = NULL;
+ struct rpcrdma_write_chunk *cur_wchunk = NULL;
+ u32 *iptr = headerp->rm_body.rm_chunks;
+
+ if (type == rpcrdma_readch || type == rpcrdma_areadch) {
+ /* a read chunk - server will RDMA Read our memory */
+ cur_rchunk = (struct rpcrdma_read_chunk *) iptr;
+ } else {
+ /* a write or reply chunk - server will RDMA Write our memory */
+ *iptr++ = xdr_zero; /* encode a NULL read chunk list */
+ if (type == rpcrdma_replych)
+ *iptr++ = xdr_zero; /* a NULL write chunk list */
+ warray = (struct rpcrdma_write_array *) iptr;
+ cur_wchunk = (struct rpcrdma_write_chunk *) (warray + 1);
+ }
+
+ if (type == rpcrdma_replych || type == rpcrdma_areadch)
+ pos = 0;
+ else
+ pos = target->head[0].iov_len;
+
+ nsegs = rpcrdma_convert_iovs(target, pos, type, seg, RPCRDMA_MAX_SEGS);
+ if (nsegs == 0)
+ return 0;
+
+ do {
+ /* bind/register the memory, then build chunk from result. */
+ int n = rpcrdma_register_external(seg, nsegs,
+ cur_wchunk != NULL, r_xprt);
+ if (n <= 0)
+ goto out;
+ if (cur_rchunk) { /* read */
+ cur_rchunk->rc_discrim = xdr_one;
+ /* all read chunks have the same "position" */
+ cur_rchunk->rc_position = htonl(pos);
+ cur_rchunk->rc_target.rs_handle = htonl(seg->mr_rkey);
+ cur_rchunk->rc_target.rs_length = htonl(seg->mr_len);
+ xdr_encode_hyper(
+ (u32 *)&cur_rchunk->rc_target.rs_offset,
+ seg->mr_base);
+ dprintk("RPC: %s: read chunk "
+ "elem %d@0x%llx:0x%x pos %d (%s)\n", __func__,
+ seg->mr_len, seg->mr_base, seg->mr_rkey, pos,
+ n < nsegs ? "more" : "last");
+ cur_rchunk++;
+ r_xprt->rx_stats.read_chunk_count++;
+ } else { /* write/reply */
+ cur_wchunk->wc_target.rs_handle = htonl(seg->mr_rkey);
+ cur_wchunk->wc_target.rs_length = htonl(seg->mr_len);
+ xdr_encode_hyper(
+ (u32 *)&cur_wchunk->wc_target.rs_offset,
+ seg->mr_base);
+ dprintk("RPC: %s: %s chunk "
+ "elem %d@0x%llx:0x%x (%s)\n", __func__,
+ (type == rpcrdma_replych) ? "reply" : "write",
+ seg->mr_len, seg->mr_base, seg->mr_rkey,
+ n < nsegs ? "more" : "last");
+ cur_wchunk++;
+ if (type == rpcrdma_replych)
+ r_xprt->rx_stats.reply_chunk_count++;
+ else
+ r_xprt->rx_stats.write_chunk_count++;
+ r_xprt->rx_stats.total_rdma_request += seg->mr_len;
+ }
+ nchunks++;
+ seg += n;
+ nsegs -= n;
+ } while (nsegs);
+
+ /* success. all failures return above */
+ req->rl_nchunks = nchunks;
+
+ BUG_ON(nchunks == 0);
+
+ /*
+ * finish off header. If write, marshal discrim and nchunks.
+ */
+ if (cur_rchunk) {
+ iptr = (u32 *) cur_rchunk;
+ *iptr++ = xdr_zero; /* finish the read chunk list */
+ *iptr++ = xdr_zero; /* encode a NULL write chunk list */
+ *iptr++ = xdr_zero; /* encode a NULL reply chunk */
+ } else {
+ warray->wc_discrim = xdr_one;
+ warray->wc_nchunks = htonl(nchunks);
+ iptr = (u32 *) cur_wchunk;
+ if (type == rpcrdma_writech) {
+ *iptr++ = xdr_zero; /* finish the write chunk list */
+ *iptr++ = xdr_zero; /* encode a NULL reply chunk */
+ }
+ }
+
+ /*
+ * Return header size.
+ */
+ return (unsigned char *)iptr - (unsigned char *)headerp;
+
+out:
+ for (pos = 0; nchunks--;)
+ pos += rpcrdma_deregister_external(
+ &req->rl_segments[pos], r_xprt, NULL);
+ return 0;
+}
+
+/*
+ * Copy write data inline.
+ * This function is used for "small" requests. Data which is passed
+ * to RPC via iovecs (or page list) is copied directly into the
+ * pre-registered memory buffer for this request. For small amounts
+ * of data, this is efficient. The cutoff value is tunable.
+ */
+static int
+rpcrdma_inline_pullup(struct rpc_rqst *rqst, int pad)
+{
+ int i, npages, curlen;
+ int copy_len;
+ unsigned char *srcp, *destp;
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
+
+ destp = rqst->rq_svec[0].iov_base;
+ curlen = rqst->rq_svec[0].iov_len;
+ destp += curlen;
+ /*
+ * Do optional padding where it makes sense. Alignment of write
+ * payload can help the server, if our setting is accurate.
+ */
+ pad -= (curlen + 36/*sizeof(struct rpcrdma_msg_padded)*/);
+ if (pad < 0 || rqst->rq_slen - curlen < RPCRDMA_INLINE_PAD_THRESH)
+ pad = 0; /* don't pad this request */
+
+ dprintk("RPC: %s: pad %d destp 0x%p len %d hdrlen %d\n",
+ __func__, pad, destp, rqst->rq_slen, curlen);
+
+ copy_len = rqst->rq_snd_buf.page_len;
+ r_xprt->rx_stats.pullup_copy_count += copy_len;
+ npages = PAGE_ALIGN(rqst->rq_snd_buf.page_base+copy_len) >> PAGE_SHIFT;
+ for (i = 0; copy_len && i < npages; i++) {
+ if (i == 0)
+ curlen = PAGE_SIZE - rqst->rq_snd_buf.page_base;
+ else
+ curlen = PAGE_SIZE;
+ if (curlen > copy_len)
+ curlen = copy_len;
+ dprintk("RPC: %s: page %d destp 0x%p len %d curlen %d\n",
+ __func__, i, destp, copy_len, curlen);
+ srcp = kmap_atomic(rqst->rq_snd_buf.pages[i],
+ KM_SKB_SUNRPC_DATA);
+ if (i == 0)
+ memcpy(destp, srcp+rqst->rq_snd_buf.page_base, curlen);
+ else
+ memcpy(destp, srcp, curlen);
+ kunmap_atomic(srcp, KM_SKB_SUNRPC_DATA);
+ rqst->rq_svec[0].iov_len += curlen;
+ destp += curlen;
+ copy_len -= curlen;
+ }
+ if (rqst->rq_snd_buf.tail[0].iov_len) {
+ curlen = rqst->rq_snd_buf.tail[0].iov_len;
+ if (destp != rqst->rq_snd_buf.tail[0].iov_base) {
+ memcpy(destp,
+ rqst->rq_snd_buf.tail[0].iov_base, curlen);
+ r_xprt->rx_stats.pullup_copy_count += curlen;
+ }
+ dprintk("RPC: %s: tail destp 0x%p len %d curlen %d\n",
+ __func__, destp, copy_len, curlen);
+ rqst->rq_svec[0].iov_len += curlen;
+ }
+ /* header now contains entire send message */
+ return pad;
+}
+
+/*
+ * Marshal a request: the primary job of this routine is to choose
+ * the transfer modes. See comments below.
+ *
+ * Uses multiple RDMA IOVs for a request:
+ * [0] -- RPC RDMA header, which uses memory from the *start* of the
+ * preregistered buffer that already holds the RPC data in
+ * its middle.
+ * [1] -- the RPC header/data, marshaled by RPC and the NFS protocol.
+ * [2] -- optional padding.
+ * [3] -- if padded, header only in [1] and data here.
+ */
+
+int
+rpcrdma_marshal_req(struct rpc_rqst *rqst)
+{
+ struct rpc_xprt *xprt = rqst->rq_task->tk_xprt;
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+ struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
+ char *base;
+ size_t hdrlen, rpclen, padlen;
+ enum rpcrdma_chunktype rtype, wtype;
+ struct rpcrdma_msg *headerp;
+
+ /*
+ * rpclen gets amount of data in first buffer, which is the
+ * pre-registered buffer.
+ */
+ base = rqst->rq_svec[0].iov_base;
+ rpclen = rqst->rq_svec[0].iov_len;
+
+ /* build RDMA header in private area at front */
+ headerp = (struct rpcrdma_msg *) req->rl_base;
+ /* don't htonl XID, it's already done in request */
+ headerp->rm_xid = rqst->rq_xid;
+ headerp->rm_vers = xdr_one;
+ headerp->rm_credit = htonl(r_xprt->rx_buf.rb_max_requests);
+ headerp->rm_type = __constant_htonl(RDMA_MSG);
+
+ /*
+ * Chunks needed for results?
+ *
+ * o If the expected result is under the inline threshold, all ops
+ * return as inline (but see later).
+ * o Large non-read ops return as a single reply chunk.
+ * o Large read ops return data as write chunk(s), header as inline.
+ *
+ * Note: the NFS code sending down multiple result segments implies
+ * the op is one of read, readdir[plus], readlink or NFSv4 getacl.
+ */
+
+ /*
+ * This code can handle read chunks, write chunks OR reply
+ * chunks -- only one type. If the request is too big to fit
+ * inline, then we will choose read chunks. If the request is
+ * a READ, then use write chunks to separate the file data
+ * into pages; otherwise use reply chunks.
+ */
+ if (rqst->rq_rcv_buf.buflen <= RPCRDMA_INLINE_READ_THRESHOLD(rqst))
+ wtype = rpcrdma_noch;
+ else if (rqst->rq_rcv_buf.page_len == 0)
+ wtype = rpcrdma_replych;
+ else if (rqst->rq_rcv_buf.flags & XDRBUF_READ)
+ wtype = rpcrdma_writech;
+ else
+ wtype = rpcrdma_replych;
+
+ /*
+ * Chunks needed for arguments?
+ *
+ * o If the total request is under the inline threshold, all ops
+ * are sent as inline.
+ * o Large non-write ops are sent with the entire message as a
+ * single read chunk (protocol 0-position special case).
+ * o Large write ops transmit data as read chunk(s), header as
+ * inline.
+ *
+ * Note: the NFS code sending down multiple argument segments
+ * implies the op is a write.
+ * TBD check NFSv4 setacl
+ */
+ if (rqst->rq_snd_buf.len <= RPCRDMA_INLINE_WRITE_THRESHOLD(rqst))
+ rtype = rpcrdma_noch;
+ else if (rqst->rq_snd_buf.page_len == 0)
+ rtype = rpcrdma_areadch;
+ else
+ rtype = rpcrdma_readch;
+
+ /* The following simplification is not true forever */
+ if (rtype != rpcrdma_noch && wtype == rpcrdma_replych)
+ wtype = rpcrdma_noch;
+ BUG_ON(rtype != rpcrdma_noch && wtype != rpcrdma_noch);
+
+ if (r_xprt->rx_ia.ri_memreg_strategy == RPCRDMA_BOUNCEBUFFERS &&
+ (rtype != rpcrdma_noch || wtype != rpcrdma_noch)) {
+ /* forced to "pure inline"? */
+ dprintk("RPC: %s: too much data (%d/%d) for inline\n",
+ __func__, rqst->rq_rcv_buf.len, rqst->rq_snd_buf.len);
+ return -1;
+ }
+
+ hdrlen = 28; /*sizeof *headerp;*/
+ padlen = 0;
+
+ /*
+ * Pull up any extra send data into the preregistered buffer.
+ * When padding is in use and applies to the transfer, insert
+ * it and change the message type.
+ */
+ if (rtype == rpcrdma_noch) {
+
+ padlen = rpcrdma_inline_pullup(rqst,
+ RPCRDMA_INLINE_PAD_VALUE(rqst));
+
+ if (padlen) {
+ headerp->rm_type = __constant_htonl(RDMA_MSGP);
+ headerp->rm_body.rm_padded.rm_align =
+ htonl(RPCRDMA_INLINE_PAD_VALUE(rqst));
+ headerp->rm_body.rm_padded.rm_thresh =
+ __constant_htonl(RPCRDMA_INLINE_PAD_THRESH);
+ headerp->rm_body.rm_padded.rm_pempty[0] = xdr_zero;
+ headerp->rm_body.rm_padded.rm_pempty[1] = xdr_zero;
+ headerp->rm_body.rm_padded.rm_pempty[2] = xdr_zero;
+ hdrlen += 2 * sizeof(u32); /* extra words in padhdr */
+ BUG_ON(wtype != rpcrdma_noch);
+
+ } else {
+ headerp->rm_body.rm_nochunks.rm_empty[0] = xdr_zero;
+ headerp->rm_body.rm_nochunks.rm_empty[1] = xdr_zero;
+ headerp->rm_body.rm_nochunks.rm_empty[2] = xdr_zero;
+ /* new length after pullup */
+ rpclen = rqst->rq_svec[0].iov_len;
+ /*
+ * Currently we try to not actually use read inline.
+ * Reply chunks have the desirable property that
+ * they land, packed, directly in the target buffers
+ * without headers, so they require no fixup. The
+ * additional RDMA Write op sends the same amount
+ * of data, streams on-the-wire and adds no overhead
+ * on receive. Therefore, we request a reply chunk
+ * for non-writes wherever feasible and efficient.
+ */
+ if (wtype == rpcrdma_noch &&
+ r_xprt->rx_ia.ri_memreg_strategy > RPCRDMA_REGISTER)
+ wtype = rpcrdma_replych;
+ }
+ }
+
+ /*
+ * Marshal chunks. This routine will return the header length
+ * consumed by marshaling.
+ */
+ if (rtype != rpcrdma_noch) {
+ hdrlen = rpcrdma_create_chunks(rqst,
+ &rqst->rq_snd_buf, headerp, rtype);
+ wtype = rtype; /* simplify dprintk */
+
+ } else if (wtype != rpcrdma_noch) {
+ hdrlen = rpcrdma_create_chunks(rqst,
+ &rqst->rq_rcv_buf, headerp, wtype);
+ }
+
+ if (hdrlen == 0)
+ return -1;
+
+ dprintk("RPC: %s: %s: hdrlen %zd rpclen %zd padlen %zd\n"
+ " headerp 0x%p base 0x%p lkey 0x%x\n",
+ __func__, transfertypes[wtype], hdrlen, rpclen, padlen,
+ headerp, base, req->rl_iov.lkey);
+
+ /*
+ * initialize send_iov's - normally only two: rdma chunk header and
+ * single preregistered RPC header buffer, but if padding is present,
+ * then use a preregistered (and zeroed) pad buffer between the RPC
+ * header and any write data. In all non-rdma cases, any following
+ * data has been copied into the RPC header buffer.
+ */
+ req->rl_send_iov[0].addr = req->rl_iov.addr;
+ req->rl_send_iov[0].length = hdrlen;
+ req->rl_send_iov[0].lkey = req->rl_iov.lkey;
+
+ req->rl_send_iov[1].addr = req->rl_iov.addr + (base - req->rl_base);
+ req->rl_send_iov[1].length = rpclen;
+ req->rl_send_iov[1].lkey = req->rl_iov.lkey;
+
+ req->rl_niovs = 2;
+
+ if (padlen) {
+ struct rpcrdma_ep *ep = &r_xprt->rx_ep;
+
+ req->rl_send_iov[2].addr = ep->rep_pad.addr;
+ req->rl_send_iov[2].length = padlen;
+ req->rl_send_iov[2].lkey = ep->rep_pad.lkey;
+
+ req->rl_send_iov[3].addr = req->rl_send_iov[1].addr + rpclen;
+ req->rl_send_iov[3].length = rqst->rq_slen - rpclen;
+ req->rl_send_iov[3].lkey = req->rl_iov.lkey;
+
+ req->rl_niovs = 4;
+ }
+
+ return 0;
+}
+
+/*
+ * Chase down a received write or reply chunklist to get length
+ * RDMA'd by server. See map at rpcrdma_create_chunks()! :-)
+ */
+static int
+rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, u32 **iptrp)
+{
+ unsigned int i, total_len;
+ struct rpcrdma_write_chunk *cur_wchunk;
+
+ i = ntohl(**iptrp); /* get array count */
+ if (i > max)
+ return -1;
+ cur_wchunk = (struct rpcrdma_write_chunk *) (*iptrp + 1);
+ total_len = 0;
+ while (i--) {
+ struct rpcrdma_segment *seg = &cur_wchunk->wc_target;
+ ifdebug(FACILITY) {
+ u64 off;
+ xdr_decode_hyper((u32 *)&seg->rs_offset, &off);
+ dprintk("RPC: %s: chunk %d@0x%llx:0x%x\n",
+ __func__,
+ ntohl(seg->rs_length),
+ off,
+ ntohl(seg->rs_handle));
+ }
+ total_len += ntohl(seg->rs_length);
+ ++cur_wchunk;
+ }
+ /* check and adjust for properly terminated write chunk */
+ if (wrchunk) {
+ u32 *w = (u32 *) cur_wchunk;
+ if (*w++ != xdr_zero)
+ return -1;
+ cur_wchunk = (struct rpcrdma_write_chunk *) w;
+ }
+ if ((char *) cur_wchunk > rep->rr_base + rep->rr_len)
+ return -1;
+
+ *iptrp = (u32 *) cur_wchunk;
+ return total_len;
+}
+
+/*
+ * Scatter inline received data back into provided iov's.
+ */
+static void
+rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len)
+{
+ int i, npages, curlen, olen;
+ char *destp;
+
+ curlen = rqst->rq_rcv_buf.head[0].iov_len;
+ if (curlen > copy_len) { /* write chunk header fixup */
+ curlen = copy_len;
+ rqst->rq_rcv_buf.head[0].iov_len = curlen;
+ }
+
+ dprintk("RPC: %s: srcp 0x%p len %d hdrlen %d\n",
+ __func__, srcp, copy_len, curlen);
+
+ /* Shift pointer for first receive segment only */
+ rqst->rq_rcv_buf.head[0].iov_base = srcp;
+ srcp += curlen;
+ copy_len -= curlen;
+
+ olen = copy_len;
+ i = 0;
+ rpcx_to_rdmax(rqst->rq_xprt)->rx_stats.fixup_copy_count += olen;
+ if (copy_len && rqst->rq_rcv_buf.page_len) {
+ npages = PAGE_ALIGN(rqst->rq_rcv_buf.page_base +
+ rqst->rq_rcv_buf.page_len) >> PAGE_SHIFT;
+ for (; i < npages; i++) {
+ if (i == 0)
+ curlen = PAGE_SIZE - rqst->rq_rcv_buf.page_base;
+ else
+ curlen = PAGE_SIZE;
+ if (curlen > copy_len)
+ curlen = copy_len;
+ dprintk("RPC: %s: page %d"
+ " srcp 0x%p len %d curlen %d\n",
+ __func__, i, srcp, copy_len, curlen);
+ destp = kmap_atomic(rqst->rq_rcv_buf.pages[i],
+ KM_SKB_SUNRPC_DATA);
+ if (i == 0)
+ memcpy(destp + rqst->rq_rcv_buf.page_base,
+ srcp, curlen);
+ else
+ memcpy(destp, srcp, curlen);
+ flush_dcache_page(rqst->rq_rcv_buf.pages[i]);
+ kunmap_atomic(destp, KM_SKB_SUNRPC_DATA);
+ srcp += curlen;
+ copy_len -= curlen;
+ if (copy_len == 0)
+ break;
+ }
+ rqst->rq_rcv_buf.page_len = olen - copy_len;
+ } else
+ rqst->rq_rcv_buf.page_len = 0;
+
+ if (copy_len && rqst->rq_rcv_buf.tail[0].iov_len) {
+ curlen = copy_len;
+ if (curlen > rqst->rq_rcv_buf.tail[0].iov_len)
+ curlen = rqst->rq_rcv_buf.tail[0].iov_len;
+ if (rqst->rq_rcv_buf.tail[0].iov_base != srcp)
+ memcpy(rqst->rq_rcv_buf.tail[0].iov_base, srcp, curlen);
+ dprintk("RPC: %s: tail srcp 0x%p len %d curlen %d\n",
+ __func__, srcp, copy_len, curlen);
+ rqst->rq_rcv_buf.tail[0].iov_len = curlen;
+ copy_len -= curlen; ++i;
+ } else
+ rqst->rq_rcv_buf.tail[0].iov_len = 0;
+
+ if (copy_len)
+ dprintk("RPC: %s: %d bytes in"
+ " %d extra segments (%d lost)\n",
+ __func__, olen, i, copy_len);
+
+ /* TBD avoid a warning from call_decode() */
+ rqst->rq_private_buf = rqst->rq_rcv_buf;
+}
+
+/*
+ * This function is called when an async event is posted to
+ * the connection which changes the connection state. All it
+ * does at this point is mark the connection up/down, the rpc
+ * timers do the rest.
+ */
+void
+rpcrdma_conn_func(struct rpcrdma_ep *ep)
+{
+ struct rpc_xprt *xprt = ep->rep_xprt;
+
+ spin_lock_bh(&xprt->transport_lock);
+ if (ep->rep_connected > 0) {
+ if (!xprt_test_and_set_connected(xprt))
+ xprt_wake_pending_tasks(xprt, 0);
+ } else {
+ if (xprt_test_and_clear_connected(xprt))
+ xprt_wake_pending_tasks(xprt, ep->rep_connected);
+ }
+ spin_unlock_bh(&xprt->transport_lock);
+}
+
+/*
+ * This function is called when memory window unbind which we are waiting
+ * for completes. Just use rr_func (zeroed by upcall) to signal completion.
+ */
+static void
+rpcrdma_unbind_func(struct rpcrdma_rep *rep)
+{
+ wake_up(&rep->rr_unbind);
+}
+
+/*
+ * Called as a tasklet to do req/reply match and complete a request
+ * Errors must result in the RPC task either being awakened, or
+ * allowed to timeout, to discover the errors at that time.
+ */
+void
+rpcrdma_reply_handler(struct rpcrdma_rep *rep)
+{
+ struct rpcrdma_msg *headerp;
+ struct rpcrdma_req *req;
+ struct rpc_rqst *rqst;
+ struct rpc_xprt *xprt = rep->rr_xprt;
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+ u32 *iptr;
+ int i, rdmalen, status;
+
+ /* Check status. If bad, signal disconnect and return rep to pool */
+ if (rep->rr_len == ~0U) {
+ rpcrdma_recv_buffer_put(rep);
+ if (r_xprt->rx_ep.rep_connected == 1) {
+ r_xprt->rx_ep.rep_connected = -EIO;
+ rpcrdma_conn_func(&r_xprt->rx_ep);
+ }
+ return;
+ }
+ if (rep->rr_len < 28) {
+ dprintk("RPC: %s: short/invalid reply\n", __func__);
+ goto repost;
+ }
+ headerp = (struct rpcrdma_msg *) rep->rr_base;
+ if (headerp->rm_vers != xdr_one) {
+ dprintk("RPC: %s: invalid version %d\n",
+ __func__, ntohl(headerp->rm_vers));
+ goto repost;
+ }
+
+ /* Get XID and try for a match. */
+ spin_lock(&xprt->transport_lock);
+ rqst = xprt_lookup_rqst(xprt, headerp->rm_xid);
+ if (rqst == NULL) {
+ spin_unlock(&xprt->transport_lock);
+ dprintk("RPC: %s: reply 0x%p failed "
+ "to match any request xid 0x%08x len %d\n",
+ __func__, rep, headerp->rm_xid, rep->rr_len);
+repost:
+ r_xprt->rx_stats.bad_reply_count++;
+ rep->rr_func = rpcrdma_reply_handler;
+ if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, &r_xprt->rx_ep, rep))
+ rpcrdma_recv_buffer_put(rep);
+
+ return;
+ }
+
+ /* get request object */
+ req = rpcr_to_rdmar(rqst);
+
+ dprintk("RPC: %s: reply 0x%p completes request 0x%p\n"
+ " RPC request 0x%p xid 0x%08x\n",
+ __func__, rep, req, rqst, headerp->rm_xid);
+
+ BUG_ON(!req || req->rl_reply);
+
+ /* from here on, the reply is no longer an orphan */
+ req->rl_reply = rep;
+
+ /* check for expected message types */
+ /* The order of some of these tests is important. */
+ switch (headerp->rm_type) {
+ case __constant_htonl(RDMA_MSG):
+ /* never expect read chunks */
+ /* never expect reply chunks (two ways to check) */
+ /* never expect write chunks without having offered RDMA */
+ if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
+ (headerp->rm_body.rm_chunks[1] == xdr_zero &&
+ headerp->rm_body.rm_chunks[2] != xdr_zero) ||
+ (headerp->rm_body.rm_chunks[1] != xdr_zero &&
+ req->rl_nchunks == 0))
+ goto badheader;
+ if (headerp->rm_body.rm_chunks[1] != xdr_zero) {
+ /* count any expected write chunks in read reply */
+ /* start at write chunk array count */
+ iptr = &headerp->rm_body.rm_chunks[2];
+ rdmalen = rpcrdma_count_chunks(rep,
+ req->rl_nchunks, 1, &iptr);
+ /* check for validity, and no reply chunk after */
+ if (rdmalen < 0 || *iptr++ != xdr_zero)
+ goto badheader;
+ rep->rr_len -=
+ ((unsigned char *)iptr - (unsigned char *)headerp);
+ status = rep->rr_len + rdmalen;
+ r_xprt->rx_stats.total_rdma_reply += rdmalen;
+ } else {
+ /* else ordinary inline */
+ iptr = (u32 *)((unsigned char *)headerp + 28);
+ rep->rr_len -= 28; /*sizeof *headerp;*/
+ status = rep->rr_len;
+ }
+ /* Fix up the rpc results for upper layer */
+ rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len);
+ break;
+
+ case __constant_htonl(RDMA_NOMSG):
+ /* never expect read or write chunks, always reply chunks */
+ if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
+ headerp->rm_body.rm_chunks[1] != xdr_zero ||
+ headerp->rm_body.rm_chunks[2] != xdr_one ||
+ req->rl_nchunks == 0)
+ goto badheader;
+ iptr = (u32 *)((unsigned char *)headerp + 28);
+ rdmalen = rpcrdma_count_chunks(rep, req->rl_nchunks, 0, &iptr);
+ if (rdmalen < 0)
+ goto badheader;
+ r_xprt->rx_stats.total_rdma_reply += rdmalen;
+ /* Reply chunk buffer already is the reply vector - no fixup. */
+ status = rdmalen;
+ break;
+
+badheader:
+ default:
+ dprintk("%s: invalid rpcrdma reply header (type %d):"
+ " chunks[012] == %d %d %d"
+ " expected chunks <= %d\n",
+ __func__, ntohl(headerp->rm_type),
+ headerp->rm_body.rm_chunks[0],
+ headerp->rm_body.rm_chunks[1],
+ headerp->rm_body.rm_chunks[2],
+ req->rl_nchunks);
+ status = -EIO;
+ r_xprt->rx_stats.bad_reply_count++;
+ break;
+ }
+
+ /* If using mw bind, start the deregister process now. */
+ /* (Note: if mr_free(), cannot perform it here, in tasklet context) */
+ if (req->rl_nchunks) switch (r_xprt->rx_ia.ri_memreg_strategy) {
+ case RPCRDMA_MEMWINDOWS:
+ for (i = 0; req->rl_nchunks-- > 1;)
+ i += rpcrdma_deregister_external(
+ &req->rl_segments[i], r_xprt, NULL);
+ /* Optionally wait (not here) for unbinds to complete */
+ rep->rr_func = rpcrdma_unbind_func;
+ (void) rpcrdma_deregister_external(&req->rl_segments[i],
+ r_xprt, rep);
+ break;
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ for (i = 0; req->rl_nchunks--;)
+ i += rpcrdma_deregister_external(&req->rl_segments[i],
+ r_xprt, NULL);
+ break;
+ default:
+ break;
+ }
+
+ dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",
+ __func__, xprt, rqst, status);
+ xprt_complete_rqst(rqst->rq_task, status);
+ spin_unlock(&xprt->transport_lock);
+}
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
new file mode 100644
index 00000000000..dc55cc974c9
--- /dev/null
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the BSD-type
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Network Appliance, Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * transport.c
+ *
+ * This file contains the top-level implementation of an RPC RDMA
+ * transport.
+ *
+ * Naming convention: functions beginning with xprt_ are part of the
+ * transport switch. All others are RPC RDMA internal.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+
+#include "xprt_rdma.h"
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_TRANS
+#endif
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+MODULE_DESCRIPTION("RPC/RDMA Transport for Linux kernel NFS");
+MODULE_AUTHOR("Network Appliance, Inc.");
+
+/*
+ * tunables
+ */
+
+static unsigned int xprt_rdma_slot_table_entries = RPCRDMA_DEF_SLOT_TABLE;
+static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
+static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
+static unsigned int xprt_rdma_inline_write_padding;
+#if !RPCRDMA_PERSISTENT_REGISTRATION
+static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_REGISTER; /* FMR? */
+#else
+static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_ALLPHYSICAL;
+#endif
+
+#ifdef RPC_DEBUG
+
+static unsigned int min_slot_table_size = RPCRDMA_MIN_SLOT_TABLE;
+static unsigned int max_slot_table_size = RPCRDMA_MAX_SLOT_TABLE;
+static unsigned int zero;
+static unsigned int max_padding = PAGE_SIZE;
+static unsigned int min_memreg = RPCRDMA_BOUNCEBUFFERS;
+static unsigned int max_memreg = RPCRDMA_LAST - 1;
+
+static struct ctl_table_header *sunrpc_table_header;
+
+static ctl_table xr_tunables_table[] = {
+ {
+ .ctl_name = CTL_SLOTTABLE_RDMA,
+ .procname = "rdma_slot_table_entries",
+ .data = &xprt_rdma_slot_table_entries,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &min_slot_table_size,
+ .extra2 = &max_slot_table_size
+ },
+ {
+ .ctl_name = CTL_RDMA_MAXINLINEREAD,
+ .procname = "rdma_max_inline_read",
+ .data = &xprt_rdma_max_inline_read,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
+ .ctl_name = CTL_RDMA_MAXINLINEWRITE,
+ .procname = "rdma_max_inline_write",
+ .data = &xprt_rdma_max_inline_write,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ .strategy = &sysctl_intvec,
+ },
+ {
+ .ctl_name = CTL_RDMA_WRITEPADDING,
+ .procname = "rdma_inline_write_padding",
+ .data = &xprt_rdma_inline_write_padding,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &zero,
+ .extra2 = &max_padding,
+ },
+ {
+ .ctl_name = CTL_RDMA_MEMREG,
+ .procname = "rdma_memreg_strategy",
+ .data = &xprt_rdma_memreg_strategy,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec_minmax,
+ .strategy = &sysctl_intvec,
+ .extra1 = &min_memreg,
+ .extra2 = &max_memreg,
+ },
+ {
+ .ctl_name = 0,
+ },
+};
+
+static ctl_table sunrpc_table[] = {
+ {
+ .ctl_name = CTL_SUNRPC,
+ .procname = "sunrpc",
+ .mode = 0555,
+ .child = xr_tunables_table
+ },
+ {
+ .ctl_name = 0,
+ },
+};
+
+#endif
+
+static struct rpc_xprt_ops xprt_rdma_procs; /* forward reference */
+
+static void
+xprt_rdma_format_addresses(struct rpc_xprt *xprt)
+{
+ struct sockaddr_in *addr = (struct sockaddr_in *)
+ &rpcx_to_rdmad(xprt).addr;
+ char *buf;
+
+ buf = kzalloc(20, GFP_KERNEL);
+ if (buf)
+ snprintf(buf, 20, NIPQUAD_FMT, NIPQUAD(addr->sin_addr.s_addr));
+ xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
+
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf)
+ snprintf(buf, 8, "%u", ntohs(addr->sin_port));
+ xprt->address_strings[RPC_DISPLAY_PORT] = buf;
+
+ xprt->address_strings[RPC_DISPLAY_PROTO] = "rdma";
+
+ buf = kzalloc(48, GFP_KERNEL);
+ if (buf)
+ snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s",
+ NIPQUAD(addr->sin_addr.s_addr),
+ ntohs(addr->sin_port), "rdma");
+ xprt->address_strings[RPC_DISPLAY_ALL] = buf;
+
+ buf = kzalloc(10, GFP_KERNEL);
+ if (buf)
+ snprintf(buf, 10, "%02x%02x%02x%02x",
+ NIPQUAD(addr->sin_addr.s_addr));
+ xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
+
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf)
+ snprintf(buf, 8, "%4hx", ntohs(addr->sin_port));
+ xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
+
+ buf = kzalloc(30, GFP_KERNEL);
+ if (buf)
+ snprintf(buf, 30, NIPQUAD_FMT".%u.%u",
+ NIPQUAD(addr->sin_addr.s_addr),
+ ntohs(addr->sin_port) >> 8,
+ ntohs(addr->sin_port) & 0xff);
+ xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
+
+ /* netid */
+ xprt->address_strings[RPC_DISPLAY_NETID] = "rdma";
+}
+
+static void
+xprt_rdma_free_addresses(struct rpc_xprt *xprt)
+{
+ kfree(xprt->address_strings[RPC_DISPLAY_ADDR]);
+ kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
+ kfree(xprt->address_strings[RPC_DISPLAY_ALL]);
+ kfree(xprt->address_strings[RPC_DISPLAY_HEX_ADDR]);
+ kfree(xprt->address_strings[RPC_DISPLAY_HEX_PORT]);
+ kfree(xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR]);
+}
+
+static void
+xprt_rdma_connect_worker(struct work_struct *work)
+{
+ struct rpcrdma_xprt *r_xprt =
+ container_of(work, struct rpcrdma_xprt, rdma_connect.work);
+ struct rpc_xprt *xprt = &r_xprt->xprt;
+ int rc = 0;
+
+ if (!xprt->shutdown) {
+ xprt_clear_connected(xprt);
+
+ dprintk("RPC: %s: %sconnect\n", __func__,
+ r_xprt->rx_ep.rep_connected != 0 ? "re" : "");
+ rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
+ if (rc)
+ goto out;
+ }
+ goto out_clear;
+
+out:
+ xprt_wake_pending_tasks(xprt, rc);
+
+out_clear:
+ dprintk("RPC: %s: exit\n", __func__);
+ xprt_clear_connecting(xprt);
+}
+
+/*
+ * xprt_rdma_destroy
+ *
+ * Destroy the xprt.
+ * Free all memory associated with the object, including its own.
+ * NOTE: none of the *destroy methods free memory for their top-level
+ * objects, even though they may have allocated it (they do free
+ * private memory). It's up to the caller to handle it. In this
+ * case (RDMA transport), all structure memory is inlined with the
+ * struct rpcrdma_xprt.
+ */
+static void
+xprt_rdma_destroy(struct rpc_xprt *xprt)
+{
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+ int rc;
+
+ dprintk("RPC: %s: called\n", __func__);
+
+ cancel_delayed_work(&r_xprt->rdma_connect);
+ flush_scheduled_work();
+
+ xprt_clear_connected(xprt);
+
+ rpcrdma_buffer_destroy(&r_xprt->rx_buf);
+ rc = rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
+ if (rc)
+ dprintk("RPC: %s: rpcrdma_ep_destroy returned %i\n",
+ __func__, rc);
+ rpcrdma_ia_close(&r_xprt->rx_ia);
+
+ xprt_rdma_free_addresses(xprt);
+
+ kfree(xprt->slot);
+ xprt->slot = NULL;
+ kfree(xprt);
+
+ dprintk("RPC: %s: returning\n", __func__);
+
+ module_put(THIS_MODULE);
+}
+
+/**
+ * xprt_setup_rdma - Set up transport to use RDMA
+ *
+ * @args: rpc transport arguments
+ */
+static struct rpc_xprt *
+xprt_setup_rdma(struct xprt_create *args)
+{
+ struct rpcrdma_create_data_internal cdata;
+ struct rpc_xprt *xprt;
+ struct rpcrdma_xprt *new_xprt;
+ struct rpcrdma_ep *new_ep;
+ struct sockaddr_in *sin;
+ int rc;
+
+ if (args->addrlen > sizeof(xprt->addr)) {
+ dprintk("RPC: %s: address too large\n", __func__);
+ return ERR_PTR(-EBADF);
+ }
+
+ xprt = kzalloc(sizeof(struct rpcrdma_xprt), GFP_KERNEL);
+ if (xprt == NULL) {
+ dprintk("RPC: %s: couldn't allocate rpcrdma_xprt\n",
+ __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ xprt->max_reqs = xprt_rdma_slot_table_entries;
+ xprt->slot = kcalloc(xprt->max_reqs,
+ sizeof(struct rpc_rqst), GFP_KERNEL);
+ if (xprt->slot == NULL) {
+ kfree(xprt);
+ dprintk("RPC: %s: couldn't allocate %d slots\n",
+ __func__, xprt->max_reqs);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* 60 second timeout, no retries */
+ xprt_set_timeout(&xprt->timeout, 0, 60UL * HZ);
+ xprt->bind_timeout = (60U * HZ);
+ xprt->connect_timeout = (60U * HZ);
+ xprt->reestablish_timeout = (5U * HZ);
+ xprt->idle_timeout = (5U * 60 * HZ);
+
+ xprt->resvport = 0; /* privileged port not needed */
+ xprt->tsh_size = 0; /* RPC-RDMA handles framing */
+ xprt->max_payload = RPCRDMA_MAX_DATA_SEGS * PAGE_SIZE;
+ xprt->ops = &xprt_rdma_procs;
+
+ /*
+ * Set up RDMA-specific connect data.
+ */
+
+ /* Put server RDMA address in local cdata */
+ memcpy(&cdata.addr, args->dstaddr, args->addrlen);
+
+ /* Ensure xprt->addr holds valid server TCP (not RDMA)
+ * address, for any side protocols which peek at it */
+ xprt->prot = IPPROTO_TCP;
+ xprt->addrlen = args->addrlen;
+ memcpy(&xprt->addr, &cdata.addr, xprt->addrlen);
+
+ sin = (struct sockaddr_in *)&cdata.addr;
+ if (ntohs(sin->sin_port) != 0)
+ xprt_set_bound(xprt);
+
+ dprintk("RPC: %s: %u.%u.%u.%u:%u\n", __func__,
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+
+ /* Set max requests */
+ cdata.max_requests = xprt->max_reqs;
+
+ /* Set some length limits */
+ cdata.rsize = RPCRDMA_MAX_SEGS * PAGE_SIZE; /* RDMA write max */
+ cdata.wsize = RPCRDMA_MAX_SEGS * PAGE_SIZE; /* RDMA read max */
+
+ cdata.inline_wsize = xprt_rdma_max_inline_write;
+ if (cdata.inline_wsize > cdata.wsize)
+ cdata.inline_wsize = cdata.wsize;
+
+ cdata.inline_rsize = xprt_rdma_max_inline_read;
+ if (cdata.inline_rsize > cdata.rsize)
+ cdata.inline_rsize = cdata.rsize;
+
+ cdata.padding = xprt_rdma_inline_write_padding;
+
+ /*
+ * Create new transport instance, which includes initialized
+ * o ia
+ * o endpoint
+ * o buffers
+ */
+
+ new_xprt = rpcx_to_rdmax(xprt);
+
+ rc = rpcrdma_ia_open(new_xprt, (struct sockaddr *) &cdata.addr,
+ xprt_rdma_memreg_strategy);
+ if (rc)
+ goto out1;
+
+ /*
+ * initialize and create ep
+ */
+ new_xprt->rx_data = cdata;
+ new_ep = &new_xprt->rx_ep;
+ new_ep->rep_remote_addr = cdata.addr;
+
+ rc = rpcrdma_ep_create(&new_xprt->rx_ep,
+ &new_xprt->rx_ia, &new_xprt->rx_data);
+ if (rc)
+ goto out2;
+
+ /*
+ * Allocate pre-registered send and receive buffers for headers and
+ * any inline data. Also specify any padding which will be provided
+ * from a preregistered zero buffer.
+ */
+ rc = rpcrdma_buffer_create(&new_xprt->rx_buf, new_ep, &new_xprt->rx_ia,
+ &new_xprt->rx_data);
+ if (rc)
+ goto out3;
+
+ /*
+ * Register a callback for connection events. This is necessary because
+ * connection loss notification is async. We also catch connection loss
+ * when reaping receives.
+ */
+ INIT_DELAYED_WORK(&new_xprt->rdma_connect, xprt_rdma_connect_worker);
+ new_ep->rep_func = rpcrdma_conn_func;
+ new_ep->rep_xprt = xprt;
+
+ xprt_rdma_format_addresses(xprt);
+
+ if (!try_module_get(THIS_MODULE))
+ goto out4;
+
+ return xprt;
+
+out4:
+ xprt_rdma_free_addresses(xprt);
+ rc = -EINVAL;
+out3:
+ (void) rpcrdma_ep_destroy(new_ep, &new_xprt->rx_ia);
+out2:
+ rpcrdma_ia_close(&new_xprt->rx_ia);
+out1:
+ kfree(xprt->slot);
+ kfree(xprt);
+ return ERR_PTR(rc);
+}
+
+/*
+ * Close a connection, during shutdown or timeout/reconnect
+ */
+static void
+xprt_rdma_close(struct rpc_xprt *xprt)
+{
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+
+ dprintk("RPC: %s: closing\n", __func__);
+ xprt_disconnect(xprt);
+ (void) rpcrdma_ep_disconnect(&r_xprt->rx_ep, &r_xprt->rx_ia);
+}
+
+static void
+xprt_rdma_set_port(struct rpc_xprt *xprt, u16 port)
+{
+ struct sockaddr_in *sap;
+
+ sap = (struct sockaddr_in *)&xprt->addr;
+ sap->sin_port = htons(port);
+ sap = (struct sockaddr_in *)&rpcx_to_rdmad(xprt).addr;
+ sap->sin_port = htons(port);
+ dprintk("RPC: %s: %u\n", __func__, port);
+}
+
+static void
+xprt_rdma_connect(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = (struct rpc_xprt *)task->tk_xprt;
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+
+ if (!xprt_test_and_set_connecting(xprt)) {
+ if (r_xprt->rx_ep.rep_connected != 0) {
+ /* Reconnect */
+ schedule_delayed_work(&r_xprt->rdma_connect,
+ xprt->reestablish_timeout);
+ } else {
+ schedule_delayed_work(&r_xprt->rdma_connect, 0);
+ if (!RPC_IS_ASYNC(task))
+ flush_scheduled_work();
+ }
+ }
+}
+
+static int
+xprt_rdma_reserve_xprt(struct rpc_task *task)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+ int credits = atomic_read(&r_xprt->rx_buf.rb_credits);
+
+ /* == RPC_CWNDSCALE @ init, but *after* setup */
+ if (r_xprt->rx_buf.rb_cwndscale == 0UL) {
+ r_xprt->rx_buf.rb_cwndscale = xprt->cwnd;
+ dprintk("RPC: %s: cwndscale %lu\n", __func__,
+ r_xprt->rx_buf.rb_cwndscale);
+ BUG_ON(r_xprt->rx_buf.rb_cwndscale <= 0);
+ }
+ xprt->cwnd = credits * r_xprt->rx_buf.rb_cwndscale;
+ return xprt_reserve_xprt_cong(task);
+}
+
+/*
+ * The RDMA allocate/free functions need the task structure as a place
+ * to hide the struct rpcrdma_req, which is necessary for the actual send/recv
+ * sequence. For this reason, the recv buffers are attached to send
+ * buffers for portions of the RPC. Note that the RPC layer allocates
+ * both send and receive buffers in the same call. We may register
+ * the receive buffer portion when using reply chunks.
+ */
+static void *
+xprt_rdma_allocate(struct rpc_task *task, size_t size)
+{
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpcrdma_req *req, *nreq;
+
+ req = rpcrdma_buffer_get(&rpcx_to_rdmax(xprt)->rx_buf);
+ BUG_ON(NULL == req);
+
+ if (size > req->rl_size) {
+ dprintk("RPC: %s: size %zd too large for buffer[%zd]: "
+ "prog %d vers %d proc %d\n",
+ __func__, size, req->rl_size,
+ task->tk_client->cl_prog, task->tk_client->cl_vers,
+ task->tk_msg.rpc_proc->p_proc);
+ /*
+ * Outgoing length shortage. Our inline write max must have
+ * been configured to perform direct i/o.
+ *
+ * This is therefore a large metadata operation, and the
+ * allocate call was made on the maximum possible message,
+ * e.g. containing long filename(s) or symlink data. In
+ * fact, while these metadata operations *might* carry
+ * large outgoing payloads, they rarely *do*. However, we
+ * have to commit to the request here, so reallocate and
+ * register it now. The data path will never require this
+ * reallocation.
+ *
+ * If the allocation or registration fails, the RPC framework
+ * will (doggedly) retry.
+ */
+ if (rpcx_to_rdmax(xprt)->rx_ia.ri_memreg_strategy ==
+ RPCRDMA_BOUNCEBUFFERS) {
+ /* forced to "pure inline" */
+ dprintk("RPC: %s: too much data (%zd) for inline "
+ "(r/w max %d/%d)\n", __func__, size,
+ rpcx_to_rdmad(xprt).inline_rsize,
+ rpcx_to_rdmad(xprt).inline_wsize);
+ size = req->rl_size;
+ rpc_exit(task, -EIO); /* fail the operation */
+ rpcx_to_rdmax(xprt)->rx_stats.failed_marshal_count++;
+ goto out;
+ }
+ if (task->tk_flags & RPC_TASK_SWAPPER)
+ nreq = kmalloc(sizeof *req + size, GFP_ATOMIC);
+ else
+ nreq = kmalloc(sizeof *req + size, GFP_NOFS);
+ if (nreq == NULL)
+ goto outfail;
+
+ if (rpcrdma_register_internal(&rpcx_to_rdmax(xprt)->rx_ia,
+ nreq->rl_base, size + sizeof(struct rpcrdma_req)
+ - offsetof(struct rpcrdma_req, rl_base),
+ &nreq->rl_handle, &nreq->rl_iov)) {
+ kfree(nreq);
+ goto outfail;
+ }
+ rpcx_to_rdmax(xprt)->rx_stats.hardway_register_count += size;
+ nreq->rl_size = size;
+ nreq->rl_niovs = 0;
+ nreq->rl_nchunks = 0;
+ nreq->rl_buffer = (struct rpcrdma_buffer *)req;
+ nreq->rl_reply = req->rl_reply;
+ memcpy(nreq->rl_segments,
+ req->rl_segments, sizeof nreq->rl_segments);
+ /* flag the swap with an unused field */
+ nreq->rl_iov.length = 0;
+ req->rl_reply = NULL;
+ req = nreq;
+ }
+ dprintk("RPC: %s: size %zd, request 0x%p\n", __func__, size, req);
+out:
+ return req->rl_xdr_buf;
+
+outfail:
+ rpcrdma_buffer_put(req);
+ rpcx_to_rdmax(xprt)->rx_stats.failed_marshal_count++;
+ return NULL;
+}
+
+/*
+ * This function returns all RDMA resources to the pool.
+ */
+static void
+xprt_rdma_free(void *buffer)
+{
+ struct rpcrdma_req *req;
+ struct rpcrdma_xprt *r_xprt;
+ struct rpcrdma_rep *rep;
+ int i;
+
+ if (buffer == NULL)
+ return;
+
+ req = container_of(buffer, struct rpcrdma_req, rl_xdr_buf[0]);
+ r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf);
+ rep = req->rl_reply;
+
+ dprintk("RPC: %s: called on 0x%p%s\n",
+ __func__, rep, (rep && rep->rr_func) ? " (with waiter)" : "");
+
+ /*
+ * Finish the deregistration. When using mw bind, this was
+ * begun in rpcrdma_reply_handler(). In all other modes, we
+ * do it here, in thread context. The process is considered
+ * complete when the rr_func vector becomes NULL - this
+ * was put in place during rpcrdma_reply_handler() - the wait
+ * call below will not block if the dereg is "done". If
+ * interrupted, our framework will clean up.
+ */
+ for (i = 0; req->rl_nchunks;) {
+ --req->rl_nchunks;
+ i += rpcrdma_deregister_external(
+ &req->rl_segments[i], r_xprt, NULL);
+ }
+
+ if (rep && wait_event_interruptible(rep->rr_unbind, !rep->rr_func)) {
+ rep->rr_func = NULL; /* abandon the callback */
+ req->rl_reply = NULL;
+ }
+
+ if (req->rl_iov.length == 0) { /* see allocate above */
+ struct rpcrdma_req *oreq = (struct rpcrdma_req *)req->rl_buffer;
+ oreq->rl_reply = req->rl_reply;
+ (void) rpcrdma_deregister_internal(&r_xprt->rx_ia,
+ req->rl_handle,
+ &req->rl_iov);
+ kfree(req);
+ req = oreq;
+ }
+
+ /* Put back request+reply buffers */
+ rpcrdma_buffer_put(req);
+}
+
+/*
+ * send_request invokes the meat of RPC RDMA. It must do the following:
+ * 1. Marshal the RPC request into an RPC RDMA request, which means
+ * putting a header in front of data, and creating IOVs for RDMA
+ * from those in the request.
+ * 2. In marshaling, detect opportunities for RDMA, and use them.
+ * 3. Post a recv message to set up asynch completion, then send
+ * the request (rpcrdma_ep_post).
+ * 4. No partial sends are possible in the RPC-RDMA protocol (as in UDP).
+ */
+
+static int
+xprt_rdma_send_request(struct rpc_task *task)
+{
+ struct rpc_rqst *rqst = task->tk_rqstp;
+ struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpcrdma_req *req = rpcr_to_rdmar(rqst);
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+
+ /* marshal the send itself */
+ if (req->rl_niovs == 0 && rpcrdma_marshal_req(rqst) != 0) {
+ r_xprt->rx_stats.failed_marshal_count++;
+ dprintk("RPC: %s: rpcrdma_marshal_req failed\n",
+ __func__);
+ return -EIO;
+ }
+
+ if (req->rl_reply == NULL) /* e.g. reconnection */
+ rpcrdma_recv_buffer_get(req);
+
+ if (req->rl_reply) {
+ req->rl_reply->rr_func = rpcrdma_reply_handler;
+ /* this need only be done once, but... */
+ req->rl_reply->rr_xprt = xprt;
+ }
+
+ if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) {
+ xprt_disconnect(xprt);
+ return -ENOTCONN; /* implies disconnect */
+ }
+
+ rqst->rq_bytes_sent = 0;
+ return 0;
+}
+
+static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
+{
+ struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
+ long idle_time = 0;
+
+ if (xprt_connected(xprt))
+ idle_time = (long)(jiffies - xprt->last_used) / HZ;
+
+ seq_printf(seq,
+ "\txprt:\trdma %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu "
+ "%lu %lu %lu %Lu %Lu %Lu %Lu %lu %lu %lu\n",
+
+ 0, /* need a local port? */
+ xprt->stat.bind_count,
+ xprt->stat.connect_count,
+ xprt->stat.connect_time,
+ idle_time,
+ xprt->stat.sends,
+ xprt->stat.recvs,
+ xprt->stat.bad_xids,
+ xprt->stat.req_u,
+ xprt->stat.bklog_u,
+
+ r_xprt->rx_stats.read_chunk_count,
+ r_xprt->rx_stats.write_chunk_count,
+ r_xprt->rx_stats.reply_chunk_count,
+ r_xprt->rx_stats.total_rdma_request,
+ r_xprt->rx_stats.total_rdma_reply,
+ r_xprt->rx_stats.pullup_copy_count,
+ r_xprt->rx_stats.fixup_copy_count,
+ r_xprt->rx_stats.hardway_register_count,
+ r_xprt->rx_stats.failed_marshal_count,
+ r_xprt->rx_stats.bad_reply_count);
+}
+
+/*
+ * Plumbing for rpc transport switch and kernel module
+ */
+
+static struct rpc_xprt_ops xprt_rdma_procs = {
+ .reserve_xprt = xprt_rdma_reserve_xprt,
+ .release_xprt = xprt_release_xprt_cong, /* sunrpc/xprt.c */
+ .release_request = xprt_release_rqst_cong, /* ditto */
+ .set_retrans_timeout = xprt_set_retrans_timeout_def, /* ditto */
+ .rpcbind = rpcb_getport_async, /* sunrpc/rpcb_clnt.c */
+ .set_port = xprt_rdma_set_port,
+ .connect = xprt_rdma_connect,
+ .buf_alloc = xprt_rdma_allocate,
+ .buf_free = xprt_rdma_free,
+ .send_request = xprt_rdma_send_request,
+ .close = xprt_rdma_close,
+ .destroy = xprt_rdma_destroy,
+ .print_stats = xprt_rdma_print_stats
+};
+
+static struct xprt_class xprt_rdma = {
+ .list = LIST_HEAD_INIT(xprt_rdma.list),
+ .name = "rdma",
+ .owner = THIS_MODULE,
+ .ident = XPRT_TRANSPORT_RDMA,
+ .setup = xprt_setup_rdma,
+};
+
+static void __exit xprt_rdma_cleanup(void)
+{
+ int rc;
+
+ dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
+#ifdef RPC_DEBUG
+ if (sunrpc_table_header) {
+ unregister_sysctl_table(sunrpc_table_header);
+ sunrpc_table_header = NULL;
+ }
+#endif
+ rc = xprt_unregister_transport(&xprt_rdma);
+ if (rc)
+ dprintk("RPC: %s: xprt_unregister returned %i\n",
+ __func__, rc);
+}
+
+static int __init xprt_rdma_init(void)
+{
+ int rc;
+
+ rc = xprt_register_transport(&xprt_rdma);
+
+ if (rc)
+ return rc;
+
+ dprintk(KERN_INFO "RPCRDMA Module Init, register RPC RDMA transport\n");
+
+ dprintk(KERN_INFO "Defaults:\n");
+ dprintk(KERN_INFO "\tSlots %d\n"
+ "\tMaxInlineRead %d\n\tMaxInlineWrite %d\n",
+ xprt_rdma_slot_table_entries,
+ xprt_rdma_max_inline_read, xprt_rdma_max_inline_write);
+ dprintk(KERN_INFO "\tPadding %d\n\tMemreg %d\n",
+ xprt_rdma_inline_write_padding, xprt_rdma_memreg_strategy);
+
+#ifdef RPC_DEBUG
+ if (!sunrpc_table_header)
+ sunrpc_table_header = register_sysctl_table(sunrpc_table);
+#endif
+ return 0;
+}
+
+module_init(xprt_rdma_init);
+module_exit(xprt_rdma_cleanup);
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
new file mode 100644
index 00000000000..44b0fb942e8
--- /dev/null
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -0,0 +1,1627 @@
+/*
+ * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the BSD-type
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Network Appliance, Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * verbs.c
+ *
+ * Encapsulates the major functions managing:
+ * o adapters
+ * o endpoints
+ * o connections
+ * o buffer memory
+ */
+
+#include <linux/pci.h> /* for Tavor hack below */
+
+#include "xprt_rdma.h"
+
+/*
+ * Globals/Macros
+ */
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY RPCDBG_TRANS
+#endif
+
+/*
+ * internal functions
+ */
+
+/*
+ * handle replies in tasklet context, using a single, global list
+ * rdma tasklet function -- just turn around and call the func
+ * for all replies on the list
+ */
+
+static DEFINE_SPINLOCK(rpcrdma_tk_lock_g);
+static LIST_HEAD(rpcrdma_tasklets_g);
+
+static void
+rpcrdma_run_tasklet(unsigned long data)
+{
+ struct rpcrdma_rep *rep;
+ void (*func)(struct rpcrdma_rep *);
+ unsigned long flags;
+
+ data = data;
+ spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
+ while (!list_empty(&rpcrdma_tasklets_g)) {
+ rep = list_entry(rpcrdma_tasklets_g.next,
+ struct rpcrdma_rep, rr_list);
+ list_del(&rep->rr_list);
+ func = rep->rr_func;
+ rep->rr_func = NULL;
+ spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
+
+ if (func)
+ func(rep);
+ else
+ rpcrdma_recv_buffer_put(rep);
+
+ spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
+ }
+ spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
+}
+
+static DECLARE_TASKLET(rpcrdma_tasklet_g, rpcrdma_run_tasklet, 0UL);
+
+static inline void
+rpcrdma_schedule_tasklet(struct rpcrdma_rep *rep)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rpcrdma_tk_lock_g, flags);
+ list_add_tail(&rep->rr_list, &rpcrdma_tasklets_g);
+ spin_unlock_irqrestore(&rpcrdma_tk_lock_g, flags);
+ tasklet_schedule(&rpcrdma_tasklet_g);
+}
+
+static void
+rpcrdma_qp_async_error_upcall(struct ib_event *event, void *context)
+{
+ struct rpcrdma_ep *ep = context;
+
+ dprintk("RPC: %s: QP error %X on device %s ep %p\n",
+ __func__, event->event, event->device->name, context);
+ if (ep->rep_connected == 1) {
+ ep->rep_connected = -EIO;
+ ep->rep_func(ep);
+ wake_up_all(&ep->rep_connect_wait);
+ }
+}
+
+static void
+rpcrdma_cq_async_error_upcall(struct ib_event *event, void *context)
+{
+ struct rpcrdma_ep *ep = context;
+
+ dprintk("RPC: %s: CQ error %X on device %s ep %p\n",
+ __func__, event->event, event->device->name, context);
+ if (ep->rep_connected == 1) {
+ ep->rep_connected = -EIO;
+ ep->rep_func(ep);
+ wake_up_all(&ep->rep_connect_wait);
+ }
+}
+
+static inline
+void rpcrdma_event_process(struct ib_wc *wc)
+{
+ struct rpcrdma_rep *rep =
+ (struct rpcrdma_rep *)(unsigned long) wc->wr_id;
+
+ dprintk("RPC: %s: event rep %p status %X opcode %X length %u\n",
+ __func__, rep, wc->status, wc->opcode, wc->byte_len);
+
+ if (!rep) /* send or bind completion that we don't care about */
+ return;
+
+ if (IB_WC_SUCCESS != wc->status) {
+ dprintk("RPC: %s: %s WC status %X, connection lost\n",
+ __func__, (wc->opcode & IB_WC_RECV) ? "recv" : "send",
+ wc->status);
+ rep->rr_len = ~0U;
+ rpcrdma_schedule_tasklet(rep);
+ return;
+ }
+
+ switch (wc->opcode) {
+ case IB_WC_RECV:
+ rep->rr_len = wc->byte_len;
+ ib_dma_sync_single_for_cpu(
+ rdmab_to_ia(rep->rr_buffer)->ri_id->device,
+ rep->rr_iov.addr, rep->rr_len, DMA_FROM_DEVICE);
+ /* Keep (only) the most recent credits, after check validity */
+ if (rep->rr_len >= 16) {
+ struct rpcrdma_msg *p =
+ (struct rpcrdma_msg *) rep->rr_base;
+ unsigned int credits = ntohl(p->rm_credit);
+ if (credits == 0) {
+ dprintk("RPC: %s: server"
+ " dropped credits to 0!\n", __func__);
+ /* don't deadlock */
+ credits = 1;
+ } else if (credits > rep->rr_buffer->rb_max_requests) {
+ dprintk("RPC: %s: server"
+ " over-crediting: %d (%d)\n",
+ __func__, credits,
+ rep->rr_buffer->rb_max_requests);
+ credits = rep->rr_buffer->rb_max_requests;
+ }
+ atomic_set(&rep->rr_buffer->rb_credits, credits);
+ }
+ /* fall through */
+ case IB_WC_BIND_MW:
+ rpcrdma_schedule_tasklet(rep);
+ break;
+ default:
+ dprintk("RPC: %s: unexpected WC event %X\n",
+ __func__, wc->opcode);
+ break;
+ }
+}
+
+static inline int
+rpcrdma_cq_poll(struct ib_cq *cq)
+{
+ struct ib_wc wc;
+ int rc;
+
+ for (;;) {
+ rc = ib_poll_cq(cq, 1, &wc);
+ if (rc < 0) {
+ dprintk("RPC: %s: ib_poll_cq failed %i\n",
+ __func__, rc);
+ return rc;
+ }
+ if (rc == 0)
+ break;
+
+ rpcrdma_event_process(&wc);
+ }
+
+ return 0;
+}
+
+/*
+ * rpcrdma_cq_event_upcall
+ *
+ * This upcall handles recv, send, bind and unbind events.
+ * It is reentrant but processes single events in order to maintain
+ * ordering of receives to keep server credits.
+ *
+ * It is the responsibility of the scheduled tasklet to return
+ * recv buffers to the pool. NOTE: this affects synchronization of
+ * connection shutdown. That is, the structures required for
+ * the completion of the reply handler must remain intact until
+ * all memory has been reclaimed.
+ *
+ * Note that send events are suppressed and do not result in an upcall.
+ */
+static void
+rpcrdma_cq_event_upcall(struct ib_cq *cq, void *context)
+{
+ int rc;
+
+ rc = rpcrdma_cq_poll(cq);
+ if (rc)
+ return;
+
+ rc = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+ if (rc) {
+ dprintk("RPC: %s: ib_req_notify_cq failed %i\n",
+ __func__, rc);
+ return;
+ }
+
+ rpcrdma_cq_poll(cq);
+}
+
+#ifdef RPC_DEBUG
+static const char * const conn[] = {
+ "address resolved",
+ "address error",
+ "route resolved",
+ "route error",
+ "connect request",
+ "connect response",
+ "connect error",
+ "unreachable",
+ "rejected",
+ "established",
+ "disconnected",
+ "device removal"
+};
+#endif
+
+static int
+rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
+{
+ struct rpcrdma_xprt *xprt = id->context;
+ struct rpcrdma_ia *ia = &xprt->rx_ia;
+ struct rpcrdma_ep *ep = &xprt->rx_ep;
+ struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
+ struct ib_qp_attr attr;
+ struct ib_qp_init_attr iattr;
+ int connstate = 0;
+
+ switch (event->event) {
+ case RDMA_CM_EVENT_ADDR_RESOLVED:
+ case RDMA_CM_EVENT_ROUTE_RESOLVED:
+ complete(&ia->ri_done);
+ break;
+ case RDMA_CM_EVENT_ADDR_ERROR:
+ ia->ri_async_rc = -EHOSTUNREACH;
+ dprintk("RPC: %s: CM address resolution error, ep 0x%p\n",
+ __func__, ep);
+ complete(&ia->ri_done);
+ break;
+ case RDMA_CM_EVENT_ROUTE_ERROR:
+ ia->ri_async_rc = -ENETUNREACH;
+ dprintk("RPC: %s: CM route resolution error, ep 0x%p\n",
+ __func__, ep);
+ complete(&ia->ri_done);
+ break;
+ case RDMA_CM_EVENT_ESTABLISHED:
+ connstate = 1;
+ ib_query_qp(ia->ri_id->qp, &attr,
+ IB_QP_MAX_QP_RD_ATOMIC | IB_QP_MAX_DEST_RD_ATOMIC,
+ &iattr);
+ dprintk("RPC: %s: %d responder resources"
+ " (%d initiator)\n",
+ __func__, attr.max_dest_rd_atomic, attr.max_rd_atomic);
+ goto connected;
+ case RDMA_CM_EVENT_CONNECT_ERROR:
+ connstate = -ENOTCONN;
+ goto connected;
+ case RDMA_CM_EVENT_UNREACHABLE:
+ connstate = -ENETDOWN;
+ goto connected;
+ case RDMA_CM_EVENT_REJECTED:
+ connstate = -ECONNREFUSED;
+ goto connected;
+ case RDMA_CM_EVENT_DISCONNECTED:
+ connstate = -ECONNABORTED;
+ goto connected;
+ case RDMA_CM_EVENT_DEVICE_REMOVAL:
+ connstate = -ENODEV;
+connected:
+ dprintk("RPC: %s: %s: %u.%u.%u.%u:%u"
+ " (ep 0x%p event 0x%x)\n",
+ __func__,
+ (event->event <= 11) ? conn[event->event] :
+ "unknown connection error",
+ NIPQUAD(addr->sin_addr.s_addr),
+ ntohs(addr->sin_port),
+ ep, event->event);
+ atomic_set(&rpcx_to_rdmax(ep->rep_xprt)->rx_buf.rb_credits, 1);
+ dprintk("RPC: %s: %sconnected\n",
+ __func__, connstate > 0 ? "" : "dis");
+ ep->rep_connected = connstate;
+ ep->rep_func(ep);
+ wake_up_all(&ep->rep_connect_wait);
+ break;
+ default:
+ ia->ri_async_rc = -EINVAL;
+ dprintk("RPC: %s: unexpected CM event %X\n",
+ __func__, event->event);
+ complete(&ia->ri_done);
+ break;
+ }
+
+ return 0;
+}
+
+static struct rdma_cm_id *
+rpcrdma_create_id(struct rpcrdma_xprt *xprt,
+ struct rpcrdma_ia *ia, struct sockaddr *addr)
+{
+ struct rdma_cm_id *id;
+ int rc;
+
+ id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP);
+ if (IS_ERR(id)) {
+ rc = PTR_ERR(id);
+ dprintk("RPC: %s: rdma_create_id() failed %i\n",
+ __func__, rc);
+ return id;
+ }
+
+ ia->ri_async_rc = 0;
+ rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT);
+ if (rc) {
+ dprintk("RPC: %s: rdma_resolve_addr() failed %i\n",
+ __func__, rc);
+ goto out;
+ }
+ wait_for_completion(&ia->ri_done);
+ rc = ia->ri_async_rc;
+ if (rc)
+ goto out;
+
+ ia->ri_async_rc = 0;
+ rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
+ if (rc) {
+ dprintk("RPC: %s: rdma_resolve_route() failed %i\n",
+ __func__, rc);
+ goto out;
+ }
+ wait_for_completion(&ia->ri_done);
+ rc = ia->ri_async_rc;
+ if (rc)
+ goto out;
+
+ return id;
+
+out:
+ rdma_destroy_id(id);
+ return ERR_PTR(rc);
+}
+
+/*
+ * Drain any cq, prior to teardown.
+ */
+static void
+rpcrdma_clean_cq(struct ib_cq *cq)
+{
+ struct ib_wc wc;
+ int count = 0;
+
+ while (1 == ib_poll_cq(cq, 1, &wc))
+ ++count;
+
+ if (count)
+ dprintk("RPC: %s: flushed %d events (last 0x%x)\n",
+ __func__, count, wc.opcode);
+}
+
+/*
+ * Exported functions.
+ */
+
+/*
+ * Open and initialize an Interface Adapter.
+ * o initializes fields of struct rpcrdma_ia, including
+ * interface and provider attributes and protection zone.
+ */
+int
+rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
+{
+ int rc;
+ struct rpcrdma_ia *ia = &xprt->rx_ia;
+
+ init_completion(&ia->ri_done);
+
+ ia->ri_id = rpcrdma_create_id(xprt, ia, addr);
+ if (IS_ERR(ia->ri_id)) {
+ rc = PTR_ERR(ia->ri_id);
+ goto out1;
+ }
+
+ ia->ri_pd = ib_alloc_pd(ia->ri_id->device);
+ if (IS_ERR(ia->ri_pd)) {
+ rc = PTR_ERR(ia->ri_pd);
+ dprintk("RPC: %s: ib_alloc_pd() failed %i\n",
+ __func__, rc);
+ goto out2;
+ }
+
+ /*
+ * Optionally obtain an underlying physical identity mapping in
+ * order to do a memory window-based bind. This base registration
+ * is protected from remote access - that is enabled only by binding
+ * for the specific bytes targeted during each RPC operation, and
+ * revoked after the corresponding completion similar to a storage
+ * adapter.
+ */
+ if (memreg > RPCRDMA_REGISTER) {
+ int mem_priv = IB_ACCESS_LOCAL_WRITE;
+ switch (memreg) {
+#if RPCRDMA_PERSISTENT_REGISTRATION
+ case RPCRDMA_ALLPHYSICAL:
+ mem_priv |= IB_ACCESS_REMOTE_WRITE;
+ mem_priv |= IB_ACCESS_REMOTE_READ;
+ break;
+#endif
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ mem_priv |= IB_ACCESS_MW_BIND;
+ break;
+ default:
+ break;
+ }
+ ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv);
+ if (IS_ERR(ia->ri_bind_mem)) {
+ printk(KERN_ALERT "%s: ib_get_dma_mr for "
+ "phys register failed with %lX\n\t"
+ "Will continue with degraded performance\n",
+ __func__, PTR_ERR(ia->ri_bind_mem));
+ memreg = RPCRDMA_REGISTER;
+ ia->ri_bind_mem = NULL;
+ }
+ }
+
+ /* Else will do memory reg/dereg for each chunk */
+ ia->ri_memreg_strategy = memreg;
+
+ return 0;
+out2:
+ rdma_destroy_id(ia->ri_id);
+out1:
+ return rc;
+}
+
+/*
+ * Clean up/close an IA.
+ * o if event handles and PD have been initialized, free them.
+ * o close the IA
+ */
+void
+rpcrdma_ia_close(struct rpcrdma_ia *ia)
+{
+ int rc;
+
+ dprintk("RPC: %s: entering\n", __func__);
+ if (ia->ri_bind_mem != NULL) {
+ rc = ib_dereg_mr(ia->ri_bind_mem);
+ dprintk("RPC: %s: ib_dereg_mr returned %i\n",
+ __func__, rc);
+ }
+ if (ia->ri_id != NULL && !IS_ERR(ia->ri_id) && ia->ri_id->qp)
+ rdma_destroy_qp(ia->ri_id);
+ if (ia->ri_pd != NULL && !IS_ERR(ia->ri_pd)) {
+ rc = ib_dealloc_pd(ia->ri_pd);
+ dprintk("RPC: %s: ib_dealloc_pd returned %i\n",
+ __func__, rc);
+ }
+ if (ia->ri_id != NULL && !IS_ERR(ia->ri_id))
+ rdma_destroy_id(ia->ri_id);
+}
+
+/*
+ * Create unconnected endpoint.
+ */
+int
+rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
+ struct rpcrdma_create_data_internal *cdata)
+{
+ struct ib_device_attr devattr;
+ int rc;
+
+ rc = ib_query_device(ia->ri_id->device, &devattr);
+ if (rc) {
+ dprintk("RPC: %s: ib_query_device failed %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ /* check provider's send/recv wr limits */
+ if (cdata->max_requests > devattr.max_qp_wr)
+ cdata->max_requests = devattr.max_qp_wr;
+
+ ep->rep_attr.event_handler = rpcrdma_qp_async_error_upcall;
+ ep->rep_attr.qp_context = ep;
+ /* send_cq and recv_cq initialized below */
+ ep->rep_attr.srq = NULL;
+ ep->rep_attr.cap.max_send_wr = cdata->max_requests;
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ /* Add room for mw_binds+unbinds - overkill! */
+ ep->rep_attr.cap.max_send_wr++;
+ ep->rep_attr.cap.max_send_wr *= (2 * RPCRDMA_MAX_SEGS);
+ if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
+ return -EINVAL;
+ break;
+ default:
+ break;
+ }
+ ep->rep_attr.cap.max_recv_wr = cdata->max_requests;
+ ep->rep_attr.cap.max_send_sge = (cdata->padding ? 4 : 2);
+ ep->rep_attr.cap.max_recv_sge = 1;
+ ep->rep_attr.cap.max_inline_data = 0;
+ ep->rep_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
+ ep->rep_attr.qp_type = IB_QPT_RC;
+ ep->rep_attr.port_num = ~0;
+
+ dprintk("RPC: %s: requested max: dtos: send %d recv %d; "
+ "iovs: send %d recv %d\n",
+ __func__,
+ ep->rep_attr.cap.max_send_wr,
+ ep->rep_attr.cap.max_recv_wr,
+ ep->rep_attr.cap.max_send_sge,
+ ep->rep_attr.cap.max_recv_sge);
+
+ /* set trigger for requesting send completion */
+ ep->rep_cqinit = ep->rep_attr.cap.max_send_wr/2 /* - 1*/;
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ ep->rep_cqinit -= RPCRDMA_MAX_SEGS;
+ break;
+ default:
+ break;
+ }
+ if (ep->rep_cqinit <= 2)
+ ep->rep_cqinit = 0;
+ INIT_CQCOUNT(ep);
+ ep->rep_ia = ia;
+ init_waitqueue_head(&ep->rep_connect_wait);
+
+ /*
+ * Create a single cq for receive dto and mw_bind (only ever
+ * care about unbind, really). Send completions are suppressed.
+ * Use single threaded tasklet upcalls to maintain ordering.
+ */
+ ep->rep_cq = ib_create_cq(ia->ri_id->device, rpcrdma_cq_event_upcall,
+ rpcrdma_cq_async_error_upcall, NULL,
+ ep->rep_attr.cap.max_recv_wr +
+ ep->rep_attr.cap.max_send_wr + 1, 0);
+ if (IS_ERR(ep->rep_cq)) {
+ rc = PTR_ERR(ep->rep_cq);
+ dprintk("RPC: %s: ib_create_cq failed: %i\n",
+ __func__, rc);
+ goto out1;
+ }
+
+ rc = ib_req_notify_cq(ep->rep_cq, IB_CQ_NEXT_COMP);
+ if (rc) {
+ dprintk("RPC: %s: ib_req_notify_cq failed: %i\n",
+ __func__, rc);
+ goto out2;
+ }
+
+ ep->rep_attr.send_cq = ep->rep_cq;
+ ep->rep_attr.recv_cq = ep->rep_cq;
+
+ /* Initialize cma parameters */
+
+ /* RPC/RDMA does not use private data */
+ ep->rep_remote_cma.private_data = NULL;
+ ep->rep_remote_cma.private_data_len = 0;
+
+ /* Client offers RDMA Read but does not initiate */
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_BOUNCEBUFFERS:
+ ep->rep_remote_cma.responder_resources = 0;
+ break;
+ case RPCRDMA_MTHCAFMR:
+ case RPCRDMA_REGISTER:
+ ep->rep_remote_cma.responder_resources = cdata->max_requests *
+ (RPCRDMA_MAX_DATA_SEGS / 8);
+ break;
+ case RPCRDMA_MEMWINDOWS:
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+#if RPCRDMA_PERSISTENT_REGISTRATION
+ case RPCRDMA_ALLPHYSICAL:
+#endif
+ ep->rep_remote_cma.responder_resources = cdata->max_requests *
+ (RPCRDMA_MAX_DATA_SEGS / 2);
+ break;
+ default:
+ break;
+ }
+ if (ep->rep_remote_cma.responder_resources > devattr.max_qp_rd_atom)
+ ep->rep_remote_cma.responder_resources = devattr.max_qp_rd_atom;
+ ep->rep_remote_cma.initiator_depth = 0;
+
+ ep->rep_remote_cma.retry_count = 7;
+ ep->rep_remote_cma.flow_control = 0;
+ ep->rep_remote_cma.rnr_retry_count = 0;
+
+ return 0;
+
+out2:
+ if (ib_destroy_cq(ep->rep_cq))
+ ;
+out1:
+ return rc;
+}
+
+/*
+ * rpcrdma_ep_destroy
+ *
+ * Disconnect and destroy endpoint. After this, the only
+ * valid operations on the ep are to free it (if dynamically
+ * allocated) or re-create it.
+ *
+ * The caller's error handling must be sure to not leak the endpoint
+ * if this function fails.
+ */
+int
+rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
+{
+ int rc;
+
+ dprintk("RPC: %s: entering, connected is %d\n",
+ __func__, ep->rep_connected);
+
+ if (ia->ri_id->qp) {
+ rc = rpcrdma_ep_disconnect(ep, ia);
+ if (rc)
+ dprintk("RPC: %s: rpcrdma_ep_disconnect"
+ " returned %i\n", __func__, rc);
+ }
+
+ ep->rep_func = NULL;
+
+ /* padding - could be done in rpcrdma_buffer_destroy... */
+ if (ep->rep_pad_mr) {
+ rpcrdma_deregister_internal(ia, ep->rep_pad_mr, &ep->rep_pad);
+ ep->rep_pad_mr = NULL;
+ }
+
+ if (ia->ri_id->qp) {
+ rdma_destroy_qp(ia->ri_id);
+ ia->ri_id->qp = NULL;
+ }
+
+ rpcrdma_clean_cq(ep->rep_cq);
+ rc = ib_destroy_cq(ep->rep_cq);
+ if (rc)
+ dprintk("RPC: %s: ib_destroy_cq returned %i\n",
+ __func__, rc);
+
+ return rc;
+}
+
+/*
+ * Connect unconnected endpoint.
+ */
+int
+rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
+{
+ struct rdma_cm_id *id;
+ int rc = 0;
+ int retry_count = 0;
+ int reconnect = (ep->rep_connected != 0);
+
+ if (reconnect) {
+ struct rpcrdma_xprt *xprt;
+retry:
+ rc = rpcrdma_ep_disconnect(ep, ia);
+ if (rc && rc != -ENOTCONN)
+ dprintk("RPC: %s: rpcrdma_ep_disconnect"
+ " status %i\n", __func__, rc);
+ rpcrdma_clean_cq(ep->rep_cq);
+
+ xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
+ id = rpcrdma_create_id(xprt, ia,
+ (struct sockaddr *)&xprt->rx_data.addr);
+ if (IS_ERR(id)) {
+ rc = PTR_ERR(id);
+ goto out;
+ }
+ /* TEMP TEMP TEMP - fail if new device:
+ * Deregister/remarshal *all* requests!
+ * Close and recreate adapter, pd, etc!
+ * Re-determine all attributes still sane!
+ * More stuff I haven't thought of!
+ * Rrrgh!
+ */
+ if (ia->ri_id->device != id->device) {
+ printk("RPC: %s: can't reconnect on "
+ "different device!\n", __func__);
+ rdma_destroy_id(id);
+ rc = -ENETDOWN;
+ goto out;
+ }
+ /* END TEMP */
+ rdma_destroy_id(ia->ri_id);
+ ia->ri_id = id;
+ }
+
+ rc = rdma_create_qp(ia->ri_id, ia->ri_pd, &ep->rep_attr);
+ if (rc) {
+ dprintk("RPC: %s: rdma_create_qp failed %i\n",
+ __func__, rc);
+ goto out;
+ }
+
+/* XXX Tavor device performs badly with 2K MTU! */
+if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
+ struct pci_dev *pcid = to_pci_dev(ia->ri_id->device->dma_device);
+ if (pcid->device == PCI_DEVICE_ID_MELLANOX_TAVOR &&
+ (pcid->vendor == PCI_VENDOR_ID_MELLANOX ||
+ pcid->vendor == PCI_VENDOR_ID_TOPSPIN)) {
+ struct ib_qp_attr attr = {
+ .path_mtu = IB_MTU_1024
+ };
+ rc = ib_modify_qp(ia->ri_id->qp, &attr, IB_QP_PATH_MTU);
+ }
+}
+
+ /* Theoretically a client initiator_depth > 0 is not needed,
+ * but many peers fail to complete the connection unless they
+ * == responder_resources! */
+ if (ep->rep_remote_cma.initiator_depth !=
+ ep->rep_remote_cma.responder_resources)
+ ep->rep_remote_cma.initiator_depth =
+ ep->rep_remote_cma.responder_resources;
+
+ ep->rep_connected = 0;
+
+ rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
+ if (rc) {
+ dprintk("RPC: %s: rdma_connect() failed with %i\n",
+ __func__, rc);
+ goto out;
+ }
+
+ if (reconnect)
+ return 0;
+
+ wait_event_interruptible(ep->rep_connect_wait, ep->rep_connected != 0);
+
+ /*
+ * Check state. A non-peer reject indicates no listener
+ * (ECONNREFUSED), which may be a transient state. All
+ * others indicate a transport condition which has already
+ * undergone a best-effort.
+ */
+ if (ep->rep_connected == -ECONNREFUSED
+ && ++retry_count <= RDMA_CONNECT_RETRY_MAX) {
+ dprintk("RPC: %s: non-peer_reject, retry\n", __func__);
+ goto retry;
+ }
+ if (ep->rep_connected <= 0) {
+ /* Sometimes, the only way to reliably connect to remote
+ * CMs is to use same nonzero values for ORD and IRD. */
+ ep->rep_remote_cma.initiator_depth =
+ ep->rep_remote_cma.responder_resources;
+ if (ep->rep_remote_cma.initiator_depth == 0)
+ ++ep->rep_remote_cma.initiator_depth;
+ if (ep->rep_remote_cma.responder_resources == 0)
+ ++ep->rep_remote_cma.responder_resources;
+ if (retry_count++ == 0)
+ goto retry;
+ rc = ep->rep_connected;
+ } else {
+ dprintk("RPC: %s: connected\n", __func__);
+ }
+
+out:
+ if (rc)
+ ep->rep_connected = rc;
+ return rc;
+}
+
+/*
+ * rpcrdma_ep_disconnect
+ *
+ * This is separate from destroy to facilitate the ability
+ * to reconnect without recreating the endpoint.
+ *
+ * This call is not reentrant, and must not be made in parallel
+ * on the same endpoint.
+ */
+int
+rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
+{
+ int rc;
+
+ rpcrdma_clean_cq(ep->rep_cq);
+ rc = rdma_disconnect(ia->ri_id);
+ if (!rc) {
+ /* returns without wait if not connected */
+ wait_event_interruptible(ep->rep_connect_wait,
+ ep->rep_connected != 1);
+ dprintk("RPC: %s: after wait, %sconnected\n", __func__,
+ (ep->rep_connected == 1) ? "still " : "dis");
+ } else {
+ dprintk("RPC: %s: rdma_disconnect %i\n", __func__, rc);
+ ep->rep_connected = rc;
+ }
+ return rc;
+}
+
+/*
+ * Initialize buffer memory
+ */
+int
+rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
+ struct rpcrdma_ia *ia, struct rpcrdma_create_data_internal *cdata)
+{
+ char *p;
+ size_t len;
+ int i, rc;
+
+ buf->rb_max_requests = cdata->max_requests;
+ spin_lock_init(&buf->rb_lock);
+ atomic_set(&buf->rb_credits, 1);
+
+ /* Need to allocate:
+ * 1. arrays for send and recv pointers
+ * 2. arrays of struct rpcrdma_req to fill in pointers
+ * 3. array of struct rpcrdma_rep for replies
+ * 4. padding, if any
+ * 5. mw's, if any
+ * Send/recv buffers in req/rep need to be registered
+ */
+
+ len = buf->rb_max_requests *
+ (sizeof(struct rpcrdma_req *) + sizeof(struct rpcrdma_rep *));
+ len += cdata->padding;
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_MTHCAFMR:
+ /* TBD we are perhaps overallocating here */
+ len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS *
+ sizeof(struct rpcrdma_mw);
+ break;
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS *
+ sizeof(struct rpcrdma_mw);
+ break;
+ default:
+ break;
+ }
+
+ /* allocate 1, 4 and 5 in one shot */
+ p = kzalloc(len, GFP_KERNEL);
+ if (p == NULL) {
+ dprintk("RPC: %s: req_t/rep_t/pad kzalloc(%zd) failed\n",
+ __func__, len);
+ rc = -ENOMEM;
+ goto out;
+ }
+ buf->rb_pool = p; /* for freeing it later */
+
+ buf->rb_send_bufs = (struct rpcrdma_req **) p;
+ p = (char *) &buf->rb_send_bufs[buf->rb_max_requests];
+ buf->rb_recv_bufs = (struct rpcrdma_rep **) p;
+ p = (char *) &buf->rb_recv_bufs[buf->rb_max_requests];
+
+ /*
+ * Register the zeroed pad buffer, if any.
+ */
+ if (cdata->padding) {
+ rc = rpcrdma_register_internal(ia, p, cdata->padding,
+ &ep->rep_pad_mr, &ep->rep_pad);
+ if (rc)
+ goto out;
+ }
+ p += cdata->padding;
+
+ /*
+ * Allocate the fmr's, or mw's for mw_bind chunk registration.
+ * We "cycle" the mw's in order to minimize rkey reuse,
+ * and also reduce unbind-to-bind collision.
+ */
+ INIT_LIST_HEAD(&buf->rb_mws);
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_MTHCAFMR:
+ {
+ struct rpcrdma_mw *r = (struct rpcrdma_mw *)p;
+ struct ib_fmr_attr fa = {
+ RPCRDMA_MAX_DATA_SEGS, 1, PAGE_SHIFT
+ };
+ /* TBD we are perhaps overallocating here */
+ for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
+ r->r.fmr = ib_alloc_fmr(ia->ri_pd,
+ IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ,
+ &fa);
+ if (IS_ERR(r->r.fmr)) {
+ rc = PTR_ERR(r->r.fmr);
+ dprintk("RPC: %s: ib_alloc_fmr"
+ " failed %i\n", __func__, rc);
+ goto out;
+ }
+ list_add(&r->mw_list, &buf->rb_mws);
+ ++r;
+ }
+ }
+ break;
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ {
+ struct rpcrdma_mw *r = (struct rpcrdma_mw *)p;
+ /* Allocate one extra request's worth, for full cycling */
+ for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
+ r->r.mw = ib_alloc_mw(ia->ri_pd);
+ if (IS_ERR(r->r.mw)) {
+ rc = PTR_ERR(r->r.mw);
+ dprintk("RPC: %s: ib_alloc_mw"
+ " failed %i\n", __func__, rc);
+ goto out;
+ }
+ list_add(&r->mw_list, &buf->rb_mws);
+ ++r;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Allocate/init the request/reply buffers. Doing this
+ * using kmalloc for now -- one for each buf.
+ */
+ for (i = 0; i < buf->rb_max_requests; i++) {
+ struct rpcrdma_req *req;
+ struct rpcrdma_rep *rep;
+
+ len = cdata->inline_wsize + sizeof(struct rpcrdma_req);
+ /* RPC layer requests *double* size + 1K RPC_SLACK_SPACE! */
+ /* Typical ~2400b, so rounding up saves work later */
+ if (len < 4096)
+ len = 4096;
+ req = kmalloc(len, GFP_KERNEL);
+ if (req == NULL) {
+ dprintk("RPC: %s: request buffer %d alloc"
+ " failed\n", __func__, i);
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(req, 0, sizeof(struct rpcrdma_req));
+ buf->rb_send_bufs[i] = req;
+ buf->rb_send_bufs[i]->rl_buffer = buf;
+
+ rc = rpcrdma_register_internal(ia, req->rl_base,
+ len - offsetof(struct rpcrdma_req, rl_base),
+ &buf->rb_send_bufs[i]->rl_handle,
+ &buf->rb_send_bufs[i]->rl_iov);
+ if (rc)
+ goto out;
+
+ buf->rb_send_bufs[i]->rl_size = len-sizeof(struct rpcrdma_req);
+
+ len = cdata->inline_rsize + sizeof(struct rpcrdma_rep);
+ rep = kmalloc(len, GFP_KERNEL);
+ if (rep == NULL) {
+ dprintk("RPC: %s: reply buffer %d alloc failed\n",
+ __func__, i);
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(rep, 0, sizeof(struct rpcrdma_rep));
+ buf->rb_recv_bufs[i] = rep;
+ buf->rb_recv_bufs[i]->rr_buffer = buf;
+ init_waitqueue_head(&rep->rr_unbind);
+
+ rc = rpcrdma_register_internal(ia, rep->rr_base,
+ len - offsetof(struct rpcrdma_rep, rr_base),
+ &buf->rb_recv_bufs[i]->rr_handle,
+ &buf->rb_recv_bufs[i]->rr_iov);
+ if (rc)
+ goto out;
+
+ }
+ dprintk("RPC: %s: max_requests %d\n",
+ __func__, buf->rb_max_requests);
+ /* done */
+ return 0;
+out:
+ rpcrdma_buffer_destroy(buf);
+ return rc;
+}
+
+/*
+ * Unregister and destroy buffer memory. Need to deal with
+ * partial initialization, so it's callable from failed create.
+ * Must be called before destroying endpoint, as registrations
+ * reference it.
+ */
+void
+rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
+{
+ int rc, i;
+ struct rpcrdma_ia *ia = rdmab_to_ia(buf);
+
+ /* clean up in reverse order from create
+ * 1. recv mr memory (mr free, then kfree)
+ * 1a. bind mw memory
+ * 2. send mr memory (mr free, then kfree)
+ * 3. padding (if any) [moved to rpcrdma_ep_destroy]
+ * 4. arrays
+ */
+ dprintk("RPC: %s: entering\n", __func__);
+
+ for (i = 0; i < buf->rb_max_requests; i++) {
+ if (buf->rb_recv_bufs && buf->rb_recv_bufs[i]) {
+ rpcrdma_deregister_internal(ia,
+ buf->rb_recv_bufs[i]->rr_handle,
+ &buf->rb_recv_bufs[i]->rr_iov);
+ kfree(buf->rb_recv_bufs[i]);
+ }
+ if (buf->rb_send_bufs && buf->rb_send_bufs[i]) {
+ while (!list_empty(&buf->rb_mws)) {
+ struct rpcrdma_mw *r;
+ r = list_entry(buf->rb_mws.next,
+ struct rpcrdma_mw, mw_list);
+ list_del(&r->mw_list);
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_MTHCAFMR:
+ rc = ib_dealloc_fmr(r->r.fmr);
+ if (rc)
+ dprintk("RPC: %s:"
+ " ib_dealloc_fmr"
+ " failed %i\n",
+ __func__, rc);
+ break;
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ rc = ib_dealloc_mw(r->r.mw);
+ if (rc)
+ dprintk("RPC: %s:"
+ " ib_dealloc_mw"
+ " failed %i\n",
+ __func__, rc);
+ break;
+ default:
+ break;
+ }
+ }
+ rpcrdma_deregister_internal(ia,
+ buf->rb_send_bufs[i]->rl_handle,
+ &buf->rb_send_bufs[i]->rl_iov);
+ kfree(buf->rb_send_bufs[i]);
+ }
+ }
+
+ kfree(buf->rb_pool);
+}
+
+/*
+ * Get a set of request/reply buffers.
+ *
+ * Reply buffer (if needed) is attached to send buffer upon return.
+ * Rule:
+ * rb_send_index and rb_recv_index MUST always be pointing to the
+ * *next* available buffer (non-NULL). They are incremented after
+ * removing buffers, and decremented *before* returning them.
+ */
+struct rpcrdma_req *
+rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
+{
+ struct rpcrdma_req *req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&buffers->rb_lock, flags);
+ if (buffers->rb_send_index == buffers->rb_max_requests) {
+ spin_unlock_irqrestore(&buffers->rb_lock, flags);
+ dprintk("RPC: %s: out of request buffers\n", __func__);
+ return ((struct rpcrdma_req *)NULL);
+ }
+
+ req = buffers->rb_send_bufs[buffers->rb_send_index];
+ if (buffers->rb_send_index < buffers->rb_recv_index) {
+ dprintk("RPC: %s: %d extra receives outstanding (ok)\n",
+ __func__,
+ buffers->rb_recv_index - buffers->rb_send_index);
+ req->rl_reply = NULL;
+ } else {
+ req->rl_reply = buffers->rb_recv_bufs[buffers->rb_recv_index];
+ buffers->rb_recv_bufs[buffers->rb_recv_index++] = NULL;
+ }
+ buffers->rb_send_bufs[buffers->rb_send_index++] = NULL;
+ if (!list_empty(&buffers->rb_mws)) {
+ int i = RPCRDMA_MAX_SEGS - 1;
+ do {
+ struct rpcrdma_mw *r;
+ r = list_entry(buffers->rb_mws.next,
+ struct rpcrdma_mw, mw_list);
+ list_del(&r->mw_list);
+ req->rl_segments[i].mr_chunk.rl_mw = r;
+ } while (--i >= 0);
+ }
+ spin_unlock_irqrestore(&buffers->rb_lock, flags);
+ return req;
+}
+
+/*
+ * Put request/reply buffers back into pool.
+ * Pre-decrement counter/array index.
+ */
+void
+rpcrdma_buffer_put(struct rpcrdma_req *req)
+{
+ struct rpcrdma_buffer *buffers = req->rl_buffer;
+ struct rpcrdma_ia *ia = rdmab_to_ia(buffers);
+ int i;
+ unsigned long flags;
+
+ BUG_ON(req->rl_nchunks != 0);
+ spin_lock_irqsave(&buffers->rb_lock, flags);
+ buffers->rb_send_bufs[--buffers->rb_send_index] = req;
+ req->rl_niovs = 0;
+ if (req->rl_reply) {
+ buffers->rb_recv_bufs[--buffers->rb_recv_index] = req->rl_reply;
+ init_waitqueue_head(&req->rl_reply->rr_unbind);
+ req->rl_reply->rr_func = NULL;
+ req->rl_reply = NULL;
+ }
+ switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_MTHCAFMR:
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ /*
+ * Cycle mw's back in reverse order, and "spin" them.
+ * This delays and scrambles reuse as much as possible.
+ */
+ i = 1;
+ do {
+ struct rpcrdma_mw **mw;
+ mw = &req->rl_segments[i].mr_chunk.rl_mw;
+ list_add_tail(&(*mw)->mw_list, &buffers->rb_mws);
+ *mw = NULL;
+ } while (++i < RPCRDMA_MAX_SEGS);
+ list_add_tail(&req->rl_segments[0].mr_chunk.rl_mw->mw_list,
+ &buffers->rb_mws);
+ req->rl_segments[0].mr_chunk.rl_mw = NULL;
+ break;
+ default:
+ break;
+ }
+ spin_unlock_irqrestore(&buffers->rb_lock, flags);
+}
+
+/*
+ * Recover reply buffers from pool.
+ * This happens when recovering from error conditions.
+ * Post-increment counter/array index.
+ */
+void
+rpcrdma_recv_buffer_get(struct rpcrdma_req *req)
+{
+ struct rpcrdma_buffer *buffers = req->rl_buffer;
+ unsigned long flags;
+
+ if (req->rl_iov.length == 0) /* special case xprt_rdma_allocate() */
+ buffers = ((struct rpcrdma_req *) buffers)->rl_buffer;
+ spin_lock_irqsave(&buffers->rb_lock, flags);
+ if (buffers->rb_recv_index < buffers->rb_max_requests) {
+ req->rl_reply = buffers->rb_recv_bufs[buffers->rb_recv_index];
+ buffers->rb_recv_bufs[buffers->rb_recv_index++] = NULL;
+ }
+ spin_unlock_irqrestore(&buffers->rb_lock, flags);
+}
+
+/*
+ * Put reply buffers back into pool when not attached to
+ * request. This happens in error conditions, and when
+ * aborting unbinds. Pre-decrement counter/array index.
+ */
+void
+rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep)
+{
+ struct rpcrdma_buffer *buffers = rep->rr_buffer;
+ unsigned long flags;
+
+ rep->rr_func = NULL;
+ spin_lock_irqsave(&buffers->rb_lock, flags);
+ buffers->rb_recv_bufs[--buffers->rb_recv_index] = rep;
+ spin_unlock_irqrestore(&buffers->rb_lock, flags);
+}
+
+/*
+ * Wrappers for internal-use kmalloc memory registration, used by buffer code.
+ */
+
+int
+rpcrdma_register_internal(struct rpcrdma_ia *ia, void *va, int len,
+ struct ib_mr **mrp, struct ib_sge *iov)
+{
+ struct ib_phys_buf ipb;
+ struct ib_mr *mr;
+ int rc;
+
+ /*
+ * All memory passed here was kmalloc'ed, therefore phys-contiguous.
+ */
+ iov->addr = ib_dma_map_single(ia->ri_id->device,
+ va, len, DMA_BIDIRECTIONAL);
+ iov->length = len;
+
+ if (ia->ri_bind_mem != NULL) {
+ *mrp = NULL;
+ iov->lkey = ia->ri_bind_mem->lkey;
+ return 0;
+ }
+
+ ipb.addr = iov->addr;
+ ipb.size = iov->length;
+ mr = ib_reg_phys_mr(ia->ri_pd, &ipb, 1,
+ IB_ACCESS_LOCAL_WRITE, &iov->addr);
+
+ dprintk("RPC: %s: phys convert: 0x%llx "
+ "registered 0x%llx length %d\n",
+ __func__, (unsigned long long)ipb.addr,
+ (unsigned long long)iov->addr, len);
+
+ if (IS_ERR(mr)) {
+ *mrp = NULL;
+ rc = PTR_ERR(mr);
+ dprintk("RPC: %s: failed with %i\n", __func__, rc);
+ } else {
+ *mrp = mr;
+ iov->lkey = mr->lkey;
+ rc = 0;
+ }
+
+ return rc;
+}
+
+int
+rpcrdma_deregister_internal(struct rpcrdma_ia *ia,
+ struct ib_mr *mr, struct ib_sge *iov)
+{
+ int rc;
+
+ ib_dma_unmap_single(ia->ri_id->device,
+ iov->addr, iov->length, DMA_BIDIRECTIONAL);
+
+ if (NULL == mr)
+ return 0;
+
+ rc = ib_dereg_mr(mr);
+ if (rc)
+ dprintk("RPC: %s: ib_dereg_mr failed %i\n", __func__, rc);
+ return rc;
+}
+
+/*
+ * Wrappers for chunk registration, shared by read/write chunk code.
+ */
+
+static void
+rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, int writing)
+{
+ seg->mr_dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ seg->mr_dmalen = seg->mr_len;
+ if (seg->mr_page)
+ seg->mr_dma = ib_dma_map_page(ia->ri_id->device,
+ seg->mr_page, offset_in_page(seg->mr_offset),
+ seg->mr_dmalen, seg->mr_dir);
+ else
+ seg->mr_dma = ib_dma_map_single(ia->ri_id->device,
+ seg->mr_offset,
+ seg->mr_dmalen, seg->mr_dir);
+}
+
+static void
+rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
+{
+ if (seg->mr_page)
+ ib_dma_unmap_page(ia->ri_id->device,
+ seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
+ else
+ ib_dma_unmap_single(ia->ri_id->device,
+ seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
+}
+
+int
+rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
+ int nsegs, int writing, struct rpcrdma_xprt *r_xprt)
+{
+ struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+ int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
+ IB_ACCESS_REMOTE_READ);
+ struct rpcrdma_mr_seg *seg1 = seg;
+ int i;
+ int rc = 0;
+
+ switch (ia->ri_memreg_strategy) {
+
+#if RPCRDMA_PERSISTENT_REGISTRATION
+ case RPCRDMA_ALLPHYSICAL:
+ rpcrdma_map_one(ia, seg, writing);
+ seg->mr_rkey = ia->ri_bind_mem->rkey;
+ seg->mr_base = seg->mr_dma;
+ seg->mr_nsegs = 1;
+ nsegs = 1;
+ break;
+#endif
+
+ /* Registration using fast memory registration */
+ case RPCRDMA_MTHCAFMR:
+ {
+ u64 physaddrs[RPCRDMA_MAX_DATA_SEGS];
+ int len, pageoff = offset_in_page(seg->mr_offset);
+ seg1->mr_offset -= pageoff; /* start of page */
+ seg1->mr_len += pageoff;
+ len = -pageoff;
+ if (nsegs > RPCRDMA_MAX_DATA_SEGS)
+ nsegs = RPCRDMA_MAX_DATA_SEGS;
+ for (i = 0; i < nsegs;) {
+ rpcrdma_map_one(ia, seg, writing);
+ physaddrs[i] = seg->mr_dma;
+ len += seg->mr_len;
+ ++seg;
+ ++i;
+ /* Check for holes */
+ if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
+ offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
+ break;
+ }
+ nsegs = i;
+ rc = ib_map_phys_fmr(seg1->mr_chunk.rl_mw->r.fmr,
+ physaddrs, nsegs, seg1->mr_dma);
+ if (rc) {
+ dprintk("RPC: %s: failed ib_map_phys_fmr "
+ "%u@0x%llx+%i (%d)... status %i\n", __func__,
+ len, (unsigned long long)seg1->mr_dma,
+ pageoff, nsegs, rc);
+ while (nsegs--)
+ rpcrdma_unmap_one(ia, --seg);
+ } else {
+ seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.fmr->rkey;
+ seg1->mr_base = seg1->mr_dma + pageoff;
+ seg1->mr_nsegs = nsegs;
+ seg1->mr_len = len;
+ }
+ }
+ break;
+
+ /* Registration using memory windows */
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ {
+ struct ib_mw_bind param;
+ rpcrdma_map_one(ia, seg, writing);
+ param.mr = ia->ri_bind_mem;
+ param.wr_id = 0ULL; /* no send cookie */
+ param.addr = seg->mr_dma;
+ param.length = seg->mr_len;
+ param.send_flags = 0;
+ param.mw_access_flags = mem_priv;
+
+ DECR_CQCOUNT(&r_xprt->rx_ep);
+ rc = ib_bind_mw(ia->ri_id->qp,
+ seg->mr_chunk.rl_mw->r.mw, &param);
+ if (rc) {
+ dprintk("RPC: %s: failed ib_bind_mw "
+ "%u@0x%llx status %i\n",
+ __func__, seg->mr_len,
+ (unsigned long long)seg->mr_dma, rc);
+ rpcrdma_unmap_one(ia, seg);
+ } else {
+ seg->mr_rkey = seg->mr_chunk.rl_mw->r.mw->rkey;
+ seg->mr_base = param.addr;
+ seg->mr_nsegs = 1;
+ nsegs = 1;
+ }
+ }
+ break;
+
+ /* Default registration each time */
+ default:
+ {
+ struct ib_phys_buf ipb[RPCRDMA_MAX_DATA_SEGS];
+ int len = 0;
+ if (nsegs > RPCRDMA_MAX_DATA_SEGS)
+ nsegs = RPCRDMA_MAX_DATA_SEGS;
+ for (i = 0; i < nsegs;) {
+ rpcrdma_map_one(ia, seg, writing);
+ ipb[i].addr = seg->mr_dma;
+ ipb[i].size = seg->mr_len;
+ len += seg->mr_len;
+ ++seg;
+ ++i;
+ /* Check for holes */
+ if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
+ offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
+ break;
+ }
+ nsegs = i;
+ seg1->mr_base = seg1->mr_dma;
+ seg1->mr_chunk.rl_mr = ib_reg_phys_mr(ia->ri_pd,
+ ipb, nsegs, mem_priv, &seg1->mr_base);
+ if (IS_ERR(seg1->mr_chunk.rl_mr)) {
+ rc = PTR_ERR(seg1->mr_chunk.rl_mr);
+ dprintk("RPC: %s: failed ib_reg_phys_mr "
+ "%u@0x%llx (%d)... status %i\n",
+ __func__, len,
+ (unsigned long long)seg1->mr_dma, nsegs, rc);
+ while (nsegs--)
+ rpcrdma_unmap_one(ia, --seg);
+ } else {
+ seg1->mr_rkey = seg1->mr_chunk.rl_mr->rkey;
+ seg1->mr_nsegs = nsegs;
+ seg1->mr_len = len;
+ }
+ }
+ break;
+ }
+ if (rc)
+ return -1;
+
+ return nsegs;
+}
+
+int
+rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
+ struct rpcrdma_xprt *r_xprt, void *r)
+{
+ struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+ struct rpcrdma_mr_seg *seg1 = seg;
+ int nsegs = seg->mr_nsegs, rc;
+
+ switch (ia->ri_memreg_strategy) {
+
+#if RPCRDMA_PERSISTENT_REGISTRATION
+ case RPCRDMA_ALLPHYSICAL:
+ BUG_ON(nsegs != 1);
+ rpcrdma_unmap_one(ia, seg);
+ rc = 0;
+ break;
+#endif
+
+ case RPCRDMA_MTHCAFMR:
+ {
+ LIST_HEAD(l);
+ list_add(&seg->mr_chunk.rl_mw->r.fmr->list, &l);
+ rc = ib_unmap_fmr(&l);
+ while (seg1->mr_nsegs--)
+ rpcrdma_unmap_one(ia, seg++);
+ }
+ if (rc)
+ dprintk("RPC: %s: failed ib_unmap_fmr,"
+ " status %i\n", __func__, rc);
+ break;
+
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ {
+ struct ib_mw_bind param;
+ BUG_ON(nsegs != 1);
+ param.mr = ia->ri_bind_mem;
+ param.addr = 0ULL; /* unbind */
+ param.length = 0;
+ param.mw_access_flags = 0;
+ if (r) {
+ param.wr_id = (u64) (unsigned long) r;
+ param.send_flags = IB_SEND_SIGNALED;
+ INIT_CQCOUNT(&r_xprt->rx_ep);
+ } else {
+ param.wr_id = 0ULL;
+ param.send_flags = 0;
+ DECR_CQCOUNT(&r_xprt->rx_ep);
+ }
+ rc = ib_bind_mw(ia->ri_id->qp,
+ seg->mr_chunk.rl_mw->r.mw, &param);
+ rpcrdma_unmap_one(ia, seg);
+ }
+ if (rc)
+ dprintk("RPC: %s: failed ib_(un)bind_mw,"
+ " status %i\n", __func__, rc);
+ else
+ r = NULL; /* will upcall on completion */
+ break;
+
+ default:
+ rc = ib_dereg_mr(seg1->mr_chunk.rl_mr);
+ seg1->mr_chunk.rl_mr = NULL;
+ while (seg1->mr_nsegs--)
+ rpcrdma_unmap_one(ia, seg++);
+ if (rc)
+ dprintk("RPC: %s: failed ib_dereg_mr,"
+ " status %i\n", __func__, rc);
+ break;
+ }
+ if (r) {
+ struct rpcrdma_rep *rep = r;
+ void (*func)(struct rpcrdma_rep *) = rep->rr_func;
+ rep->rr_func = NULL;
+ func(rep); /* dereg done, callback now */
+ }
+ return nsegs;
+}
+
+/*
+ * Prepost any receive buffer, then post send.
+ *
+ * Receive buffer is donated to hardware, reclaimed upon recv completion.
+ */
+int
+rpcrdma_ep_post(struct rpcrdma_ia *ia,
+ struct rpcrdma_ep *ep,
+ struct rpcrdma_req *req)
+{
+ struct ib_send_wr send_wr, *send_wr_fail;
+ struct rpcrdma_rep *rep = req->rl_reply;
+ int rc;
+
+ if (rep) {
+ rc = rpcrdma_ep_post_recv(ia, ep, rep);
+ if (rc)
+ goto out;
+ req->rl_reply = NULL;
+ }
+
+ send_wr.next = NULL;
+ send_wr.wr_id = 0ULL; /* no send cookie */
+ send_wr.sg_list = req->rl_send_iov;
+ send_wr.num_sge = req->rl_niovs;
+ send_wr.opcode = IB_WR_SEND;
+ send_wr.imm_data = 0;
+ if (send_wr.num_sge == 4) /* no need to sync any pad (constant) */
+ ib_dma_sync_single_for_device(ia->ri_id->device,
+ req->rl_send_iov[3].addr, req->rl_send_iov[3].length,
+ DMA_TO_DEVICE);
+ ib_dma_sync_single_for_device(ia->ri_id->device,
+ req->rl_send_iov[1].addr, req->rl_send_iov[1].length,
+ DMA_TO_DEVICE);
+ ib_dma_sync_single_for_device(ia->ri_id->device,
+ req->rl_send_iov[0].addr, req->rl_send_iov[0].length,
+ DMA_TO_DEVICE);
+
+ if (DECR_CQCOUNT(ep) > 0)
+ send_wr.send_flags = 0;
+ else { /* Provider must take a send completion every now and then */
+ INIT_CQCOUNT(ep);
+ send_wr.send_flags = IB_SEND_SIGNALED;
+ }
+
+ rc = ib_post_send(ia->ri_id->qp, &send_wr, &send_wr_fail);
+ if (rc)
+ dprintk("RPC: %s: ib_post_send returned %i\n", __func__,
+ rc);
+out:
+ return rc;
+}
+
+/*
+ * (Re)post a receive buffer.
+ */
+int
+rpcrdma_ep_post_recv(struct rpcrdma_ia *ia,
+ struct rpcrdma_ep *ep,
+ struct rpcrdma_rep *rep)
+{
+ struct ib_recv_wr recv_wr, *recv_wr_fail;
+ int rc;
+
+ recv_wr.next = NULL;
+ recv_wr.wr_id = (u64) (unsigned long) rep;
+ recv_wr.sg_list = &rep->rr_iov;
+ recv_wr.num_sge = 1;
+
+ ib_dma_sync_single_for_cpu(ia->ri_id->device,
+ rep->rr_iov.addr, rep->rr_iov.length, DMA_BIDIRECTIONAL);
+
+ DECR_CQCOUNT(ep);
+ rc = ib_post_recv(ia->ri_id->qp, &recv_wr, &recv_wr_fail);
+
+ if (rc)
+ dprintk("RPC: %s: ib_post_recv returned %i\n", __func__,
+ rc);
+ return rc;
+}
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
new file mode 100644
index 00000000000..2427822f8bd
--- /dev/null
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the BSD-type
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Neither the name of the Network Appliance, Inc. nor the names of
+ * its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SUNRPC_XPRT_RDMA_H
+#define _LINUX_SUNRPC_XPRT_RDMA_H
+
+#include <linux/wait.h> /* wait_queue_head_t, etc */
+#include <linux/spinlock.h> /* spinlock_t, etc */
+#include <asm/atomic.h> /* atomic_t, etc */
+
+#include <rdma/rdma_cm.h> /* RDMA connection api */
+#include <rdma/ib_verbs.h> /* RDMA verbs api */
+
+#include <linux/sunrpc/clnt.h> /* rpc_xprt */
+#include <linux/sunrpc/rpc_rdma.h> /* RPC/RDMA protocol */
+#include <linux/sunrpc/xprtrdma.h> /* xprt parameters */
+
+/*
+ * Interface Adapter -- one per transport instance
+ */
+struct rpcrdma_ia {
+ struct rdma_cm_id *ri_id;
+ struct ib_pd *ri_pd;
+ struct ib_mr *ri_bind_mem;
+ struct completion ri_done;
+ int ri_async_rc;
+ enum rpcrdma_memreg ri_memreg_strategy;
+};
+
+/*
+ * RDMA Endpoint -- one per transport instance
+ */
+
+struct rpcrdma_ep {
+ atomic_t rep_cqcount;
+ int rep_cqinit;
+ int rep_connected;
+ struct rpcrdma_ia *rep_ia;
+ struct ib_cq *rep_cq;
+ struct ib_qp_init_attr rep_attr;
+ wait_queue_head_t rep_connect_wait;
+ struct ib_sge rep_pad; /* holds zeroed pad */
+ struct ib_mr *rep_pad_mr; /* holds zeroed pad */
+ void (*rep_func)(struct rpcrdma_ep *);
+ struct rpc_xprt *rep_xprt; /* for rep_func */
+ struct rdma_conn_param rep_remote_cma;
+ struct sockaddr_storage rep_remote_addr;
+};
+
+#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
+#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
+
+/*
+ * struct rpcrdma_rep -- this structure encapsulates state required to recv
+ * and complete a reply, asychronously. It needs several pieces of
+ * state:
+ * o recv buffer (posted to provider)
+ * o ib_sge (also donated to provider)
+ * o status of reply (length, success or not)
+ * o bookkeeping state to get run by tasklet (list, etc)
+ *
+ * These are allocated during initialization, per-transport instance;
+ * however, the tasklet execution list itself is global, as it should
+ * always be pretty short.
+ *
+ * N of these are associated with a transport instance, and stored in
+ * struct rpcrdma_buffer. N is the max number of outstanding requests.
+ */
+
+/* temporary static scatter/gather max */
+#define RPCRDMA_MAX_DATA_SEGS (8) /* max scatter/gather */
+#define RPCRDMA_MAX_SEGS (RPCRDMA_MAX_DATA_SEGS + 2) /* head+tail = 2 */
+#define MAX_RPCRDMAHDR (\
+ /* max supported RPC/RDMA header */ \
+ sizeof(struct rpcrdma_msg) + (2 * sizeof(u32)) + \
+ (sizeof(struct rpcrdma_read_chunk) * RPCRDMA_MAX_SEGS) + sizeof(u32))
+
+struct rpcrdma_buffer;
+
+struct rpcrdma_rep {
+ unsigned int rr_len; /* actual received reply length */
+ struct rpcrdma_buffer *rr_buffer; /* home base for this structure */
+ struct rpc_xprt *rr_xprt; /* needed for request/reply matching */
+ void (*rr_func)(struct rpcrdma_rep *);/* called by tasklet in softint */
+ struct list_head rr_list; /* tasklet list */
+ wait_queue_head_t rr_unbind; /* optional unbind wait */
+ struct ib_sge rr_iov; /* for posting */
+ struct ib_mr *rr_handle; /* handle for mem in rr_iov */
+ char rr_base[MAX_RPCRDMAHDR]; /* minimal inline receive buffer */
+};
+
+/*
+ * struct rpcrdma_req -- structure central to the request/reply sequence.
+ *
+ * N of these are associated with a transport instance, and stored in
+ * struct rpcrdma_buffer. N is the max number of outstanding requests.
+ *
+ * It includes pre-registered buffer memory for send AND recv.
+ * The recv buffer, however, is not owned by this structure, and
+ * is "donated" to the hardware when a recv is posted. When a
+ * reply is handled, the recv buffer used is given back to the
+ * struct rpcrdma_req associated with the request.
+ *
+ * In addition to the basic memory, this structure includes an array
+ * of iovs for send operations. The reason is that the iovs passed to
+ * ib_post_{send,recv} must not be modified until the work request
+ * completes.
+ *
+ * NOTES:
+ * o RPCRDMA_MAX_SEGS is the max number of addressible chunk elements we
+ * marshal. The number needed varies depending on the iov lists that
+ * are passed to us, the memory registration mode we are in, and if
+ * physical addressing is used, the layout.
+ */
+
+struct rpcrdma_mr_seg { /* chunk descriptors */
+ union { /* chunk memory handles */
+ struct ib_mr *rl_mr; /* if registered directly */
+ struct rpcrdma_mw { /* if registered from region */
+ union {
+ struct ib_mw *mw;
+ struct ib_fmr *fmr;
+ } r;
+ struct list_head mw_list;
+ } *rl_mw;
+ } mr_chunk;
+ u64 mr_base; /* registration result */
+ u32 mr_rkey; /* registration result */
+ u32 mr_len; /* length of chunk or segment */
+ int mr_nsegs; /* number of segments in chunk or 0 */
+ enum dma_data_direction mr_dir; /* segment mapping direction */
+ dma_addr_t mr_dma; /* segment mapping address */
+ size_t mr_dmalen; /* segment mapping length */
+ struct page *mr_page; /* owning page, if any */
+ char *mr_offset; /* kva if no page, else offset */
+};
+
+struct rpcrdma_req {
+ size_t rl_size; /* actual length of buffer */
+ unsigned int rl_niovs; /* 0, 2 or 4 */
+ unsigned int rl_nchunks; /* non-zero if chunks */
+ struct rpcrdma_buffer *rl_buffer; /* home base for this structure */
+ struct rpcrdma_rep *rl_reply;/* holder for reply buffer */
+ struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */
+ struct ib_sge rl_send_iov[4]; /* for active requests */
+ struct ib_sge rl_iov; /* for posting */
+ struct ib_mr *rl_handle; /* handle for mem in rl_iov */
+ char rl_base[MAX_RPCRDMAHDR]; /* start of actual buffer */
+ __u32 rl_xdr_buf[0]; /* start of returned rpc rq_buffer */
+};
+#define rpcr_to_rdmar(r) \
+ container_of((r)->rq_buffer, struct rpcrdma_req, rl_xdr_buf[0])
+
+/*
+ * struct rpcrdma_buffer -- holds list/queue of pre-registered memory for
+ * inline requests/replies, and client/server credits.
+ *
+ * One of these is associated with a transport instance
+ */
+struct rpcrdma_buffer {
+ spinlock_t rb_lock; /* protects indexes */
+ atomic_t rb_credits; /* most recent server credits */
+ unsigned long rb_cwndscale; /* cached framework rpc_cwndscale */
+ int rb_max_requests;/* client max requests */
+ struct list_head rb_mws; /* optional memory windows/fmrs */
+ int rb_send_index;
+ struct rpcrdma_req **rb_send_bufs;
+ int rb_recv_index;
+ struct rpcrdma_rep **rb_recv_bufs;
+ char *rb_pool;
+};
+#define rdmab_to_ia(b) (&container_of((b), struct rpcrdma_xprt, rx_buf)->rx_ia)
+
+/*
+ * Internal structure for transport instance creation. This
+ * exists primarily for modularity.
+ *
+ * This data should be set with mount options
+ */
+struct rpcrdma_create_data_internal {
+ struct sockaddr_storage addr; /* RDMA server address */
+ unsigned int max_requests; /* max requests (slots) in flight */
+ unsigned int rsize; /* mount rsize - max read hdr+data */
+ unsigned int wsize; /* mount wsize - max write hdr+data */
+ unsigned int inline_rsize; /* max non-rdma read data payload */
+ unsigned int inline_wsize; /* max non-rdma write data payload */
+ unsigned int padding; /* non-rdma write header padding */
+};
+
+#define RPCRDMA_INLINE_READ_THRESHOLD(rq) \
+ (rpcx_to_rdmad(rq->rq_task->tk_xprt).inline_rsize)
+
+#define RPCRDMA_INLINE_WRITE_THRESHOLD(rq)\
+ (rpcx_to_rdmad(rq->rq_task->tk_xprt).inline_wsize)
+
+#define RPCRDMA_INLINE_PAD_VALUE(rq)\
+ rpcx_to_rdmad(rq->rq_task->tk_xprt).padding
+
+/*
+ * Statistics for RPCRDMA
+ */
+struct rpcrdma_stats {
+ unsigned long read_chunk_count;
+ unsigned long write_chunk_count;
+ unsigned long reply_chunk_count;
+
+ unsigned long long total_rdma_request;
+ unsigned long long total_rdma_reply;
+
+ unsigned long long pullup_copy_count;
+ unsigned long long fixup_copy_count;
+ unsigned long hardway_register_count;
+ unsigned long failed_marshal_count;
+ unsigned long bad_reply_count;
+};
+
+/*
+ * RPCRDMA transport -- encapsulates the structures above for
+ * integration with RPC.
+ *
+ * The contained structures are embedded, not pointers,
+ * for convenience. This structure need not be visible externally.
+ *
+ * It is allocated and initialized during mount, and released
+ * during unmount.
+ */
+struct rpcrdma_xprt {
+ struct rpc_xprt xprt;
+ struct rpcrdma_ia rx_ia;
+ struct rpcrdma_ep rx_ep;
+ struct rpcrdma_buffer rx_buf;
+ struct rpcrdma_create_data_internal rx_data;
+ struct delayed_work rdma_connect;
+ struct rpcrdma_stats rx_stats;
+};
+
+#define rpcx_to_rdmax(x) container_of(x, struct rpcrdma_xprt, xprt)
+#define rpcx_to_rdmad(x) (rpcx_to_rdmax(x)->rx_data)
+
+/*
+ * Interface Adapter calls - xprtrdma/verbs.c
+ */
+int rpcrdma_ia_open(struct rpcrdma_xprt *, struct sockaddr *, int);
+void rpcrdma_ia_close(struct rpcrdma_ia *);
+
+/*
+ * Endpoint calls - xprtrdma/verbs.c
+ */
+int rpcrdma_ep_create(struct rpcrdma_ep *, struct rpcrdma_ia *,
+ struct rpcrdma_create_data_internal *);
+int rpcrdma_ep_destroy(struct rpcrdma_ep *, struct rpcrdma_ia *);
+int rpcrdma_ep_connect(struct rpcrdma_ep *, struct rpcrdma_ia *);
+int rpcrdma_ep_disconnect(struct rpcrdma_ep *, struct rpcrdma_ia *);
+
+int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *,
+ struct rpcrdma_req *);
+int rpcrdma_ep_post_recv(struct rpcrdma_ia *, struct rpcrdma_ep *,
+ struct rpcrdma_rep *);
+
+/*
+ * Buffer calls - xprtrdma/verbs.c
+ */
+int rpcrdma_buffer_create(struct rpcrdma_buffer *, struct rpcrdma_ep *,
+ struct rpcrdma_ia *,
+ struct rpcrdma_create_data_internal *);
+void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
+
+struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);
+void rpcrdma_buffer_put(struct rpcrdma_req *);
+void rpcrdma_recv_buffer_get(struct rpcrdma_req *);
+void rpcrdma_recv_buffer_put(struct rpcrdma_rep *);
+
+int rpcrdma_register_internal(struct rpcrdma_ia *, void *, int,
+ struct ib_mr **, struct ib_sge *);
+int rpcrdma_deregister_internal(struct rpcrdma_ia *,
+ struct ib_mr *, struct ib_sge *);
+
+int rpcrdma_register_external(struct rpcrdma_mr_seg *,
+ int, int, struct rpcrdma_xprt *);
+int rpcrdma_deregister_external(struct rpcrdma_mr_seg *,
+ struct rpcrdma_xprt *, void *);
+
+/*
+ * RPC/RDMA connection management calls - xprtrdma/rpc_rdma.c
+ */
+void rpcrdma_conn_func(struct rpcrdma_ep *);
+void rpcrdma_reply_handler(struct rpcrdma_rep *);
+
+/*
+ * RPC/RDMA protocol calls - xprtrdma/rpc_rdma.c
+ */
+int rpcrdma_marshal_req(struct rpc_rqst *);
+
+#endif /* _LINUX_SUNRPC_XPRT_RDMA_H */
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 282efd447a6..02298f529da 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -13,10 +13,14 @@
* (C) 1999 Trond Myklebust <trond.myklebust@fys.uio.no>
*
* IP socket transport implementation, (C) 2005 Chuck Lever <cel@netapp.com>
+ *
+ * IPv6 support contributed by Gilles Quillard, Bull Open Source, 2005.
+ * <gilles.quillard@bull.net>
*/
#include <linux/types.h>
#include <linux/slab.h>
+#include <linux/module.h>
#include <linux/capability.h>
#include <linux/pagemap.h>
#include <linux/errno.h>
@@ -28,6 +32,7 @@
#include <linux/tcp.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/xprtsock.h>
#include <linux/file.h>
#include <net/sock.h>
@@ -260,14 +265,29 @@ struct sock_xprt {
#define TCP_RCV_COPY_XID (1UL << 2)
#define TCP_RCV_COPY_DATA (1UL << 3)
-static void xs_format_peer_addresses(struct rpc_xprt *xprt)
+static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt)
+{
+ return (struct sockaddr *) &xprt->addr;
+}
+
+static inline struct sockaddr_in *xs_addr_in(struct rpc_xprt *xprt)
{
- struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
+ return (struct sockaddr_in *) &xprt->addr;
+}
+
+static inline struct sockaddr_in6 *xs_addr_in6(struct rpc_xprt *xprt)
+{
+ return (struct sockaddr_in6 *) &xprt->addr;
+}
+
+static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt)
+{
+ struct sockaddr_in *addr = xs_addr_in(xprt);
char *buf;
buf = kzalloc(20, GFP_KERNEL);
if (buf) {
- snprintf(buf, 20, "%u.%u.%u.%u",
+ snprintf(buf, 20, NIPQUAD_FMT,
NIPQUAD(addr->sin_addr.s_addr));
}
xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
@@ -279,26 +299,123 @@ static void xs_format_peer_addresses(struct rpc_xprt *xprt)
}
xprt->address_strings[RPC_DISPLAY_PORT] = buf;
- if (xprt->prot == IPPROTO_UDP)
- xprt->address_strings[RPC_DISPLAY_PROTO] = "udp";
- else
- xprt->address_strings[RPC_DISPLAY_PROTO] = "tcp";
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf) {
+ if (xprt->prot == IPPROTO_UDP)
+ snprintf(buf, 8, "udp");
+ else
+ snprintf(buf, 8, "tcp");
+ }
+ xprt->address_strings[RPC_DISPLAY_PROTO] = buf;
buf = kzalloc(48, GFP_KERNEL);
if (buf) {
- snprintf(buf, 48, "addr=%u.%u.%u.%u port=%u proto=%s",
+ snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s",
NIPQUAD(addr->sin_addr.s_addr),
ntohs(addr->sin_port),
xprt->prot == IPPROTO_UDP ? "udp" : "tcp");
}
xprt->address_strings[RPC_DISPLAY_ALL] = buf;
+
+ buf = kzalloc(10, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 10, "%02x%02x%02x%02x",
+ NIPQUAD(addr->sin_addr.s_addr));
+ }
+ xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
+
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 8, "%4hx",
+ ntohs(addr->sin_port));
+ }
+ xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
+
+ buf = kzalloc(30, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 30, NIPQUAD_FMT".%u.%u",
+ NIPQUAD(addr->sin_addr.s_addr),
+ ntohs(addr->sin_port) >> 8,
+ ntohs(addr->sin_port) & 0xff);
+ }
+ xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
+
+ xprt->address_strings[RPC_DISPLAY_NETID] =
+ kstrdup(xprt->prot == IPPROTO_UDP ?
+ RPCBIND_NETID_UDP : RPCBIND_NETID_TCP, GFP_KERNEL);
+}
+
+static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt)
+{
+ struct sockaddr_in6 *addr = xs_addr_in6(xprt);
+ char *buf;
+
+ buf = kzalloc(40, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 40, NIP6_FMT,
+ NIP6(addr->sin6_addr));
+ }
+ xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
+
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 8, "%u",
+ ntohs(addr->sin6_port));
+ }
+ xprt->address_strings[RPC_DISPLAY_PORT] = buf;
+
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf) {
+ if (xprt->prot == IPPROTO_UDP)
+ snprintf(buf, 8, "udp");
+ else
+ snprintf(buf, 8, "tcp");
+ }
+ xprt->address_strings[RPC_DISPLAY_PROTO] = buf;
+
+ buf = kzalloc(64, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s",
+ NIP6(addr->sin6_addr),
+ ntohs(addr->sin6_port),
+ xprt->prot == IPPROTO_UDP ? "udp" : "tcp");
+ }
+ xprt->address_strings[RPC_DISPLAY_ALL] = buf;
+
+ buf = kzalloc(36, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 36, NIP6_SEQFMT,
+ NIP6(addr->sin6_addr));
+ }
+ xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
+
+ buf = kzalloc(8, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 8, "%4hx",
+ ntohs(addr->sin6_port));
+ }
+ xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
+
+ buf = kzalloc(50, GFP_KERNEL);
+ if (buf) {
+ snprintf(buf, 50, NIP6_FMT".%u.%u",
+ NIP6(addr->sin6_addr),
+ ntohs(addr->sin6_port) >> 8,
+ ntohs(addr->sin6_port) & 0xff);
+ }
+ xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
+
+ xprt->address_strings[RPC_DISPLAY_NETID] =
+ kstrdup(xprt->prot == IPPROTO_UDP ?
+ RPCBIND_NETID_UDP6 : RPCBIND_NETID_TCP6, GFP_KERNEL);
}
static void xs_free_peer_addresses(struct rpc_xprt *xprt)
{
- kfree(xprt->address_strings[RPC_DISPLAY_ADDR]);
- kfree(xprt->address_strings[RPC_DISPLAY_PORT]);
- kfree(xprt->address_strings[RPC_DISPLAY_ALL]);
+ int i;
+
+ for (i = 0; i < RPC_DISPLAY_MAX; i++)
+ kfree(xprt->address_strings[i]);
}
#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)
@@ -463,19 +580,20 @@ static int xs_udp_send_request(struct rpc_task *task)
req->rq_xtime = jiffies;
status = xs_sendpages(transport->sock,
- (struct sockaddr *) &xprt->addr,
+ xs_addr(xprt),
xprt->addrlen, xdr,
req->rq_bytes_sent);
dprintk("RPC: xs_udp_send_request(%u) = %d\n",
xdr->len - req->rq_bytes_sent, status);
- if (likely(status >= (int) req->rq_slen))
- return 0;
-
- /* Still some bytes left; set up for a retry later. */
- if (status > 0)
+ if (status >= 0) {
+ task->tk_bytes_sent += status;
+ if (status >= req->rq_slen)
+ return 0;
+ /* Still some bytes left; set up for a retry later. */
status = -EAGAIN;
+ }
switch (status) {
case -ENETUNREACH:
@@ -523,7 +641,8 @@ static int xs_tcp_send_request(struct rpc_task *task)
struct rpc_xprt *xprt = req->rq_xprt;
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
struct xdr_buf *xdr = &req->rq_snd_buf;
- int status, retry = 0;
+ int status;
+ unsigned int retry = 0;
xs_encode_tcp_record_marker(&req->rq_snd_buf);
@@ -661,6 +780,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
xs_free_peer_addresses(xprt);
kfree(xprt->slot);
kfree(xprt);
+ module_put(THIS_MODULE);
}
static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -1139,14 +1259,23 @@ static unsigned short xs_get_random_port(void)
*/
static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
{
- struct sockaddr_in *sap = (struct sockaddr_in *) &xprt->addr;
+ struct sockaddr *addr = xs_addr(xprt);
dprintk("RPC: setting port for xprt %p to %u\n", xprt, port);
- sap->sin_port = htons(port);
+ switch (addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)addr)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+ break;
+ default:
+ BUG();
+ }
}
-static int xs_bind(struct sock_xprt *transport, struct socket *sock)
+static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
{
struct sockaddr_in myaddr = {
.sin_family = AF_INET,
@@ -1174,8 +1303,42 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock)
else
port--;
} while (err == -EADDRINUSE && port != transport->port);
- dprintk("RPC: xs_bind "NIPQUAD_FMT":%u: %s (%d)\n",
- NIPQUAD(myaddr.sin_addr), port, err ? "failed" : "ok", err);
+ dprintk("RPC: %s "NIPQUAD_FMT":%u: %s (%d)\n",
+ __FUNCTION__, NIPQUAD(myaddr.sin_addr),
+ port, err ? "failed" : "ok", err);
+ return err;
+}
+
+static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
+{
+ struct sockaddr_in6 myaddr = {
+ .sin6_family = AF_INET6,
+ };
+ struct sockaddr_in6 *sa;
+ int err;
+ unsigned short port = transport->port;
+
+ if (!transport->xprt.resvport)
+ port = 0;
+ sa = (struct sockaddr_in6 *)&transport->addr;
+ myaddr.sin6_addr = sa->sin6_addr;
+ do {
+ myaddr.sin6_port = htons(port);
+ err = kernel_bind(sock, (struct sockaddr *) &myaddr,
+ sizeof(myaddr));
+ if (!transport->xprt.resvport)
+ break;
+ if (err == 0) {
+ transport->port = port;
+ break;
+ }
+ if (port <= xprt_min_resvport)
+ port = xprt_max_resvport;
+ else
+ port--;
+ } while (err == -EADDRINUSE && port != transport->port);
+ dprintk("RPC: xs_bind6 "NIP6_FMT":%u: %s (%d)\n",
+ NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err);
return err;
}
@@ -1183,38 +1346,69 @@ static int xs_bind(struct sock_xprt *transport, struct socket *sock)
static struct lock_class_key xs_key[2];
static struct lock_class_key xs_slock_key[2];
-static inline void xs_reclassify_socket(struct socket *sock)
+static inline void xs_reclassify_socket4(struct socket *sock)
{
struct sock *sk = sock->sk;
+
BUG_ON(sock_owned_by_user(sk));
- switch (sk->sk_family) {
- case AF_INET:
- sock_lock_init_class_and_name(sk, "slock-AF_INET-NFS",
- &xs_slock_key[0], "sk_lock-AF_INET-NFS", &xs_key[0]);
- break;
+ sock_lock_init_class_and_name(sk, "slock-AF_INET-RPC",
+ &xs_slock_key[0], "sk_lock-AF_INET-RPC", &xs_key[0]);
+}
- case AF_INET6:
- sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFS",
- &xs_slock_key[1], "sk_lock-AF_INET6-NFS", &xs_key[1]);
- break;
+static inline void xs_reclassify_socket6(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
- default:
- BUG();
- }
+ BUG_ON(sock_owned_by_user(sk));
+ sock_lock_init_class_and_name(sk, "slock-AF_INET6-RPC",
+ &xs_slock_key[1], "sk_lock-AF_INET6-RPC", &xs_key[1]);
}
#else
-static inline void xs_reclassify_socket(struct socket *sock)
+static inline void xs_reclassify_socket4(struct socket *sock)
+{
+}
+
+static inline void xs_reclassify_socket6(struct socket *sock)
{
}
#endif
+static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
+{
+ struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+
+ if (!transport->inet) {
+ struct sock *sk = sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ sk->sk_user_data = xprt;
+ transport->old_data_ready = sk->sk_data_ready;
+ transport->old_state_change = sk->sk_state_change;
+ transport->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = xs_udp_data_ready;
+ sk->sk_write_space = xs_udp_write_space;
+ sk->sk_no_check = UDP_CSUM_NORCV;
+ sk->sk_allocation = GFP_ATOMIC;
+
+ xprt_set_connected(xprt);
+
+ /* Reset to new socket */
+ transport->sock = sock;
+ transport->inet = sk;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+ xs_udp_do_set_buffer_size(xprt);
+}
+
/**
- * xs_udp_connect_worker - set up a UDP socket
+ * xs_udp_connect_worker4 - set up a UDP socket
* @work: RPC transport to connect
*
* Invoked by a work queue tasklet.
*/
-static void xs_udp_connect_worker(struct work_struct *work)
+static void xs_udp_connect_worker4(struct work_struct *work)
{
struct sock_xprt *transport =
container_of(work, struct sock_xprt, connect_worker.work);
@@ -1232,9 +1426,9 @@ static void xs_udp_connect_worker(struct work_struct *work)
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
goto out;
}
- xs_reclassify_socket(sock);
+ xs_reclassify_socket4(sock);
- if (xs_bind(transport, sock)) {
+ if (xs_bind4(transport, sock)) {
sock_release(sock);
goto out;
}
@@ -1242,29 +1436,48 @@ static void xs_udp_connect_worker(struct work_struct *work)
dprintk("RPC: worker connecting xprt %p to address: %s\n",
xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
- if (!transport->inet) {
- struct sock *sk = sock->sk;
+ xs_udp_finish_connecting(xprt, sock);
+ status = 0;
+out:
+ xprt_wake_pending_tasks(xprt, status);
+ xprt_clear_connecting(xprt);
+}
- write_lock_bh(&sk->sk_callback_lock);
+/**
+ * xs_udp_connect_worker6 - set up a UDP socket
+ * @work: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_udp_connect_worker6(struct work_struct *work)
+{
+ struct sock_xprt *transport =
+ container_of(work, struct sock_xprt, connect_worker.work);
+ struct rpc_xprt *xprt = &transport->xprt;
+ struct socket *sock = transport->sock;
+ int err, status = -EIO;
- sk->sk_user_data = xprt;
- transport->old_data_ready = sk->sk_data_ready;
- transport->old_state_change = sk->sk_state_change;
- transport->old_write_space = sk->sk_write_space;
- sk->sk_data_ready = xs_udp_data_ready;
- sk->sk_write_space = xs_udp_write_space;
- sk->sk_no_check = UDP_CSUM_NORCV;
- sk->sk_allocation = GFP_ATOMIC;
+ if (xprt->shutdown || !xprt_bound(xprt))
+ goto out;
- xprt_set_connected(xprt);
+ /* Start by resetting any existing state */
+ xs_close(xprt);
- /* Reset to new socket */
- transport->sock = sock;
- transport->inet = sk;
+ if ((err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
+ dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
+ goto out;
+ }
+ xs_reclassify_socket6(sock);
- write_unlock_bh(&sk->sk_callback_lock);
+ if (xs_bind6(transport, sock) < 0) {
+ sock_release(sock);
+ goto out;
}
- xs_udp_do_set_buffer_size(xprt);
+
+ dprintk("RPC: worker connecting xprt %p to address: %s\n",
+ xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
+
+ xs_udp_finish_connecting(xprt, sock);
status = 0;
out:
xprt_wake_pending_tasks(xprt, status);
@@ -1295,13 +1508,52 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
result);
}
+static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
+{
+ struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+
+ if (!transport->inet) {
+ struct sock *sk = sock->sk;
+
+ write_lock_bh(&sk->sk_callback_lock);
+
+ sk->sk_user_data = xprt;
+ transport->old_data_ready = sk->sk_data_ready;
+ transport->old_state_change = sk->sk_state_change;
+ transport->old_write_space = sk->sk_write_space;
+ sk->sk_data_ready = xs_tcp_data_ready;
+ sk->sk_state_change = xs_tcp_state_change;
+ sk->sk_write_space = xs_tcp_write_space;
+ sk->sk_allocation = GFP_ATOMIC;
+
+ /* socket options */
+ sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
+ sock_reset_flag(sk, SOCK_LINGER);
+ tcp_sk(sk)->linger2 = 0;
+ tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
+
+ xprt_clear_connected(xprt);
+
+ /* Reset to new socket */
+ transport->sock = sock;
+ transport->inet = sk;
+
+ write_unlock_bh(&sk->sk_callback_lock);
+ }
+
+ /* Tell the socket layer to start connecting... */
+ xprt->stat.connect_count++;
+ xprt->stat.connect_start = jiffies;
+ return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK);
+}
+
/**
- * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
+ * xs_tcp_connect_worker4 - connect a TCP socket to a remote endpoint
* @work: RPC transport to connect
*
* Invoked by a work queue tasklet.
*/
-static void xs_tcp_connect_worker(struct work_struct *work)
+static void xs_tcp_connect_worker4(struct work_struct *work)
{
struct sock_xprt *transport =
container_of(work, struct sock_xprt, connect_worker.work);
@@ -1315,13 +1567,12 @@ static void xs_tcp_connect_worker(struct work_struct *work)
if (!sock) {
/* start from scratch */
if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
- dprintk("RPC: can't create TCP transport "
- "socket (%d).\n", -err);
+ dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
goto out;
}
- xs_reclassify_socket(sock);
+ xs_reclassify_socket4(sock);
- if (xs_bind(transport, sock)) {
+ if (xs_bind4(transport, sock) < 0) {
sock_release(sock);
goto out;
}
@@ -1332,43 +1583,70 @@ static void xs_tcp_connect_worker(struct work_struct *work)
dprintk("RPC: worker connecting xprt %p to address: %s\n",
xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
- if (!transport->inet) {
- struct sock *sk = sock->sk;
-
- write_lock_bh(&sk->sk_callback_lock);
+ status = xs_tcp_finish_connecting(xprt, sock);
+ dprintk("RPC: %p connect status %d connected %d sock state %d\n",
+ xprt, -status, xprt_connected(xprt),
+ sock->sk->sk_state);
+ if (status < 0) {
+ switch (status) {
+ case -EINPROGRESS:
+ case -EALREADY:
+ goto out_clear;
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ /* retry with existing socket, after a delay */
+ break;
+ default:
+ /* get rid of existing socket, and retry */
+ xs_close(xprt);
+ break;
+ }
+ }
+out:
+ xprt_wake_pending_tasks(xprt, status);
+out_clear:
+ xprt_clear_connecting(xprt);
+}
- sk->sk_user_data = xprt;
- transport->old_data_ready = sk->sk_data_ready;
- transport->old_state_change = sk->sk_state_change;
- transport->old_write_space = sk->sk_write_space;
- sk->sk_data_ready = xs_tcp_data_ready;
- sk->sk_state_change = xs_tcp_state_change;
- sk->sk_write_space = xs_tcp_write_space;
- sk->sk_allocation = GFP_ATOMIC;
+/**
+ * xs_tcp_connect_worker6 - connect a TCP socket to a remote endpoint
+ * @work: RPC transport to connect
+ *
+ * Invoked by a work queue tasklet.
+ */
+static void xs_tcp_connect_worker6(struct work_struct *work)
+{
+ struct sock_xprt *transport =
+ container_of(work, struct sock_xprt, connect_worker.work);
+ struct rpc_xprt *xprt = &transport->xprt;
+ struct socket *sock = transport->sock;
+ int err, status = -EIO;
- /* socket options */
- sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
- sock_reset_flag(sk, SOCK_LINGER);
- tcp_sk(sk)->linger2 = 0;
- tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
+ if (xprt->shutdown || !xprt_bound(xprt))
+ goto out;
- xprt_clear_connected(xprt);
+ if (!sock) {
+ /* start from scratch */
+ if ((err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
+ dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
+ goto out;
+ }
+ xs_reclassify_socket6(sock);
- /* Reset to new socket */
- transport->sock = sock;
- transport->inet = sk;
+ if (xs_bind6(transport, sock) < 0) {
+ sock_release(sock);
+ goto out;
+ }
+ } else
+ /* "close" the socket, preserving the local port */
+ xs_tcp_reuse_connection(xprt);
- write_unlock_bh(&sk->sk_callback_lock);
- }
+ dprintk("RPC: worker connecting xprt %p to address: %s\n",
+ xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
- /* Tell the socket layer to start connecting... */
- xprt->stat.connect_count++;
- xprt->stat.connect_start = jiffies;
- status = kernel_connect(sock, (struct sockaddr *) &xprt->addr,
- xprt->addrlen, O_NONBLOCK);
+ status = xs_tcp_finish_connecting(xprt, sock);
dprintk("RPC: %p connect status %d connected %d sock state %d\n",
- xprt, -status, xprt_connected(xprt),
- sock->sk->sk_state);
+ xprt, -status, xprt_connected(xprt), sock->sk->sk_state);
if (status < 0) {
switch (status) {
case -EINPROGRESS:
@@ -1508,7 +1786,8 @@ static struct rpc_xprt_ops xs_tcp_ops = {
.print_stats = xs_tcp_print_stats,
};
-static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned int slot_table_size)
+static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
+ unsigned int slot_table_size)
{
struct rpc_xprt *xprt;
struct sock_xprt *new;
@@ -1549,8 +1828,9 @@ static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned
* @args: rpc transport creation arguments
*
*/
-struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
+struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
{
+ struct sockaddr *addr = args->dstaddr;
struct rpc_xprt *xprt;
struct sock_xprt *transport;
@@ -1559,15 +1839,11 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
return xprt;
transport = container_of(xprt, struct sock_xprt, xprt);
- if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0)
- xprt_set_bound(xprt);
-
xprt->prot = IPPROTO_UDP;
xprt->tsh_size = 0;
/* XXX: header size can vary due to auth type, IPv6, etc. */
xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
- INIT_DELAYED_WORK(&transport->connect_worker, xs_udp_connect_worker);
xprt->bind_timeout = XS_BIND_TO;
xprt->connect_timeout = XS_UDP_CONN_TO;
xprt->reestablish_timeout = XS_UDP_REEST_TO;
@@ -1580,11 +1856,37 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
else
xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
- xs_format_peer_addresses(xprt);
+ switch (addr->sa_family) {
+ case AF_INET:
+ if (((struct sockaddr_in *)addr)->sin_port != htons(0))
+ xprt_set_bound(xprt);
+
+ INIT_DELAYED_WORK(&transport->connect_worker,
+ xs_udp_connect_worker4);
+ xs_format_ipv4_peer_addresses(xprt);
+ break;
+ case AF_INET6:
+ if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
+ xprt_set_bound(xprt);
+
+ INIT_DELAYED_WORK(&transport->connect_worker,
+ xs_udp_connect_worker6);
+ xs_format_ipv6_peer_addresses(xprt);
+ break;
+ default:
+ kfree(xprt);
+ return ERR_PTR(-EAFNOSUPPORT);
+ }
+
dprintk("RPC: set up transport to address %s\n",
xprt->address_strings[RPC_DISPLAY_ALL]);
- return xprt;
+ if (try_module_get(THIS_MODULE))
+ return xprt;
+
+ kfree(xprt->slot);
+ kfree(xprt);
+ return ERR_PTR(-EINVAL);
}
/**
@@ -1592,8 +1894,9 @@ struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
* @args: rpc transport creation arguments
*
*/
-struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args)
+struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
{
+ struct sockaddr *addr = args->dstaddr;
struct rpc_xprt *xprt;
struct sock_xprt *transport;
@@ -1602,14 +1905,10 @@ struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args)
return xprt;
transport = container_of(xprt, struct sock_xprt, xprt);
- if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0)
- xprt_set_bound(xprt);
-
xprt->prot = IPPROTO_TCP;
xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
- INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker);
xprt->bind_timeout = XS_BIND_TO;
xprt->connect_timeout = XS_TCP_CONN_TO;
xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
@@ -1622,15 +1921,55 @@ struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args)
else
xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);
- xs_format_peer_addresses(xprt);
+ switch (addr->sa_family) {
+ case AF_INET:
+ if (((struct sockaddr_in *)addr)->sin_port != htons(0))
+ xprt_set_bound(xprt);
+
+ INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4);
+ xs_format_ipv4_peer_addresses(xprt);
+ break;
+ case AF_INET6:
+ if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
+ xprt_set_bound(xprt);
+
+ INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6);
+ xs_format_ipv6_peer_addresses(xprt);
+ break;
+ default:
+ kfree(xprt);
+ return ERR_PTR(-EAFNOSUPPORT);
+ }
+
dprintk("RPC: set up transport to address %s\n",
xprt->address_strings[RPC_DISPLAY_ALL]);
- return xprt;
+ if (try_module_get(THIS_MODULE))
+ return xprt;
+
+ kfree(xprt->slot);
+ kfree(xprt);
+ return ERR_PTR(-EINVAL);
}
+static struct xprt_class xs_udp_transport = {
+ .list = LIST_HEAD_INIT(xs_udp_transport.list),
+ .name = "udp",
+ .owner = THIS_MODULE,
+ .ident = IPPROTO_UDP,
+ .setup = xs_setup_udp,
+};
+
+static struct xprt_class xs_tcp_transport = {
+ .list = LIST_HEAD_INIT(xs_tcp_transport.list),
+ .name = "tcp",
+ .owner = THIS_MODULE,
+ .ident = IPPROTO_TCP,
+ .setup = xs_setup_tcp,
+};
+
/**
- * init_socket_xprt - set up xprtsock's sysctls
+ * init_socket_xprt - set up xprtsock's sysctls, register with RPC client
*
*/
int init_socket_xprt(void)
@@ -1640,11 +1979,14 @@ int init_socket_xprt(void)
sunrpc_table_header = register_sysctl_table(sunrpc_table);
#endif
+ xprt_register_transport(&xs_udp_transport);
+ xprt_register_transport(&xs_tcp_transport);
+
return 0;
}
/**
- * cleanup_socket_xprt - remove xprtsock's sysctls
+ * cleanup_socket_xprt - remove xprtsock's sysctls, unregister
*
*/
void cleanup_socket_xprt(void)
@@ -1655,4 +1997,7 @@ void cleanup_socket_xprt(void)
sunrpc_table_header = NULL;
}
#endif
+
+ xprt_unregister_transport(&xs_udp_transport);
+ xprt_unregister_transport(&xs_tcp_transport);
}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 113f4442998..cb97fda1b6d 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -49,13 +49,16 @@ EXPORT_SYMBOL(secpath_dup);
int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
{
int offset, offset_seq;
+ int hlen;
switch (nexthdr) {
case IPPROTO_AH:
+ hlen = sizeof(struct ip_auth_hdr);
offset = offsetof(struct ip_auth_hdr, spi);
offset_seq = offsetof(struct ip_auth_hdr, seq_no);
break;
case IPPROTO_ESP:
+ hlen = sizeof(struct ip_esp_hdr);
offset = offsetof(struct ip_esp_hdr, spi);
offset_seq = offsetof(struct ip_esp_hdr, seq_no);
break;
@@ -69,7 +72,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
return 1;
}
- if (!pskb_may_pull(skb, 16))
+ if (!pskb_may_pull(skb, hlen))
return -EINVAL;
*spi = *(__be32*)(skb_transport_header(skb) + offset);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 0eb3377602e..f4bfd6c4565 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -63,7 +63,7 @@ int xfrm_output(struct sk_buff *skb)
xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
}
- err = x->mode->output(x, skb);
+ err = x->outer_mode->output(x, skb);
if (err)
goto error;
@@ -82,7 +82,7 @@ int xfrm_output(struct sk_buff *skb)
}
dst = skb->dst;
x = dst->xfrm;
- } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
+ } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
err = 0;
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index af27c193697..b702bd8a389 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -49,8 +49,6 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
-static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family);
-static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo);
static inline int
__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -86,72 +84,6 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
return 0;
}
-int xfrm_register_type(struct xfrm_type *type, unsigned short family)
-{
- struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
- struct xfrm_type **typemap;
- int err = 0;
-
- if (unlikely(afinfo == NULL))
- return -EAFNOSUPPORT;
- typemap = afinfo->type_map;
-
- if (likely(typemap[type->proto] == NULL))
- typemap[type->proto] = type;
- else
- err = -EEXIST;
- xfrm_policy_unlock_afinfo(afinfo);
- return err;
-}
-EXPORT_SYMBOL(xfrm_register_type);
-
-int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
-{
- struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
- struct xfrm_type **typemap;
- int err = 0;
-
- if (unlikely(afinfo == NULL))
- return -EAFNOSUPPORT;
- typemap = afinfo->type_map;
-
- if (unlikely(typemap[type->proto] != type))
- err = -ENOENT;
- else
- typemap[type->proto] = NULL;
- xfrm_policy_unlock_afinfo(afinfo);
- return err;
-}
-EXPORT_SYMBOL(xfrm_unregister_type);
-
-struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
-{
- struct xfrm_policy_afinfo *afinfo;
- struct xfrm_type **typemap;
- struct xfrm_type *type;
- int modload_attempted = 0;
-
-retry:
- afinfo = xfrm_policy_get_afinfo(family);
- if (unlikely(afinfo == NULL))
- return NULL;
- typemap = afinfo->type_map;
-
- type = typemap[proto];
- if (unlikely(type && !try_module_get(type->owner)))
- type = NULL;
- if (!type && !modload_attempted) {
- xfrm_policy_put_afinfo(afinfo);
- request_module("xfrm-type-%d-%d",
- (int) family, (int) proto);
- modload_attempted = 1;
- goto retry;
- }
-
- xfrm_policy_put_afinfo(afinfo);
- return type;
-}
-
int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
unsigned short family)
{
@@ -170,94 +102,6 @@ int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
}
EXPORT_SYMBOL(xfrm_dst_lookup);
-void xfrm_put_type(struct xfrm_type *type)
-{
- module_put(type->owner);
-}
-
-int xfrm_register_mode(struct xfrm_mode *mode, int family)
-{
- struct xfrm_policy_afinfo *afinfo;
- struct xfrm_mode **modemap;
- int err;
-
- if (unlikely(mode->encap >= XFRM_MODE_MAX))
- return -EINVAL;
-
- afinfo = xfrm_policy_lock_afinfo(family);
- if (unlikely(afinfo == NULL))
- return -EAFNOSUPPORT;
-
- err = -EEXIST;
- modemap = afinfo->mode_map;
- if (likely(modemap[mode->encap] == NULL)) {
- modemap[mode->encap] = mode;
- err = 0;
- }
-
- xfrm_policy_unlock_afinfo(afinfo);
- return err;
-}
-EXPORT_SYMBOL(xfrm_register_mode);
-
-int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
-{
- struct xfrm_policy_afinfo *afinfo;
- struct xfrm_mode **modemap;
- int err;
-
- if (unlikely(mode->encap >= XFRM_MODE_MAX))
- return -EINVAL;
-
- afinfo = xfrm_policy_lock_afinfo(family);
- if (unlikely(afinfo == NULL))
- return -EAFNOSUPPORT;
-
- err = -ENOENT;
- modemap = afinfo->mode_map;
- if (likely(modemap[mode->encap] == mode)) {
- modemap[mode->encap] = NULL;
- err = 0;
- }
-
- xfrm_policy_unlock_afinfo(afinfo);
- return err;
-}
-EXPORT_SYMBOL(xfrm_unregister_mode);
-
-struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
-{
- struct xfrm_policy_afinfo *afinfo;
- struct xfrm_mode *mode;
- int modload_attempted = 0;
-
- if (unlikely(encap >= XFRM_MODE_MAX))
- return NULL;
-
-retry:
- afinfo = xfrm_policy_get_afinfo(family);
- if (unlikely(afinfo == NULL))
- return NULL;
-
- mode = afinfo->mode_map[encap];
- if (unlikely(mode && !try_module_get(mode->owner)))
- mode = NULL;
- if (!mode && !modload_attempted) {
- xfrm_policy_put_afinfo(afinfo);
- request_module("xfrm-mode-%d-%d", family, encap);
- modload_attempted = 1;
- goto retry;
- }
-
- xfrm_policy_put_afinfo(afinfo);
- return mode;
-}
-
-void xfrm_put_mode(struct xfrm_mode *mode)
-{
- module_put(mode->owner);
-}
-
static inline unsigned long make_jiffies(long secs)
{
if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
@@ -2096,7 +1940,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
if (xdst->genid != dst->xfrm->genid)
return 0;
- if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL &&
+ if (strict && fl &&
+ !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
!xfrm_state_addr_flow_check(dst->xfrm, fl, family))
return 0;
@@ -2213,23 +2058,6 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
read_unlock(&xfrm_policy_afinfo_lock);
}
-static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family)
-{
- struct xfrm_policy_afinfo *afinfo;
- if (unlikely(family >= NPROTO))
- return NULL;
- write_lock_bh(&xfrm_policy_afinfo_lock);
- afinfo = xfrm_policy_afinfo[family];
- if (unlikely(!afinfo))
- write_unlock_bh(&xfrm_policy_afinfo_lock);
- return afinfo;
-}
-
-static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo)
-{
- write_unlock_bh(&xfrm_policy_afinfo_lock);
-}
-
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
@@ -2464,7 +2292,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i]))
continue;
n++;
- if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL)
+ if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
+ pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
continue;
/* update endpoints */
memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 344f0a6abec..224b44e31a0 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -57,6 +57,9 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
static unsigned int xfrm_state_num;
static unsigned int xfrm_state_genid;
+static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
+static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
+
static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
xfrm_address_t *saddr,
u32 reqid,
@@ -187,6 +190,184 @@ int __xfrm_state_delete(struct xfrm_state *x);
int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
+static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
+{
+ struct xfrm_state_afinfo *afinfo;
+ if (unlikely(family >= NPROTO))
+ return NULL;
+ write_lock_bh(&xfrm_state_afinfo_lock);
+ afinfo = xfrm_state_afinfo[family];
+ if (unlikely(!afinfo))
+ write_unlock_bh(&xfrm_state_afinfo_lock);
+ return afinfo;
+}
+
+static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
+{
+ write_unlock_bh(&xfrm_state_afinfo_lock);
+}
+
+int xfrm_register_type(struct xfrm_type *type, unsigned short family)
+{
+ struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+ struct xfrm_type **typemap;
+ int err = 0;
+
+ if (unlikely(afinfo == NULL))
+ return -EAFNOSUPPORT;
+ typemap = afinfo->type_map;
+
+ if (likely(typemap[type->proto] == NULL))
+ typemap[type->proto] = type;
+ else
+ err = -EEXIST;
+ xfrm_state_unlock_afinfo(afinfo);
+ return err;
+}
+EXPORT_SYMBOL(xfrm_register_type);
+
+int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
+{
+ struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family);
+ struct xfrm_type **typemap;
+ int err = 0;
+
+ if (unlikely(afinfo == NULL))
+ return -EAFNOSUPPORT;
+ typemap = afinfo->type_map;
+
+ if (unlikely(typemap[type->proto] != type))
+ err = -ENOENT;
+ else
+ typemap[type->proto] = NULL;
+ xfrm_state_unlock_afinfo(afinfo);
+ return err;
+}
+EXPORT_SYMBOL(xfrm_unregister_type);
+
+static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
+{
+ struct xfrm_state_afinfo *afinfo;
+ struct xfrm_type **typemap;
+ struct xfrm_type *type;
+ int modload_attempted = 0;
+
+retry:
+ afinfo = xfrm_state_get_afinfo(family);
+ if (unlikely(afinfo == NULL))
+ return NULL;
+ typemap = afinfo->type_map;
+
+ type = typemap[proto];
+ if (unlikely(type && !try_module_get(type->owner)))
+ type = NULL;
+ if (!type && !modload_attempted) {
+ xfrm_state_put_afinfo(afinfo);
+ request_module("xfrm-type-%d-%d", family, proto);
+ modload_attempted = 1;
+ goto retry;
+ }
+
+ xfrm_state_put_afinfo(afinfo);
+ return type;
+}
+
+static void xfrm_put_type(struct xfrm_type *type)
+{
+ module_put(type->owner);
+}
+
+int xfrm_register_mode(struct xfrm_mode *mode, int family)
+{
+ struct xfrm_state_afinfo *afinfo;
+ struct xfrm_mode **modemap;
+ int err;
+
+ if (unlikely(mode->encap >= XFRM_MODE_MAX))
+ return -EINVAL;
+
+ afinfo = xfrm_state_lock_afinfo(family);
+ if (unlikely(afinfo == NULL))
+ return -EAFNOSUPPORT;
+
+ err = -EEXIST;
+ modemap = afinfo->mode_map;
+ if (modemap[mode->encap])
+ goto out;
+
+ err = -ENOENT;
+ if (!try_module_get(afinfo->owner))
+ goto out;
+
+ mode->afinfo = afinfo;
+ modemap[mode->encap] = mode;
+ err = 0;
+
+out:
+ xfrm_state_unlock_afinfo(afinfo);
+ return err;
+}
+EXPORT_SYMBOL(xfrm_register_mode);
+
+int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
+{
+ struct xfrm_state_afinfo *afinfo;
+ struct xfrm_mode **modemap;
+ int err;
+
+ if (unlikely(mode->encap >= XFRM_MODE_MAX))
+ return -EINVAL;
+
+ afinfo = xfrm_state_lock_afinfo(family);
+ if (unlikely(afinfo == NULL))
+ return -EAFNOSUPPORT;
+
+ err = -ENOENT;
+ modemap = afinfo->mode_map;
+ if (likely(modemap[mode->encap] == mode)) {
+ modemap[mode->encap] = NULL;
+ module_put(mode->afinfo->owner);
+ err = 0;
+ }
+
+ xfrm_state_unlock_afinfo(afinfo);
+ return err;
+}
+EXPORT_SYMBOL(xfrm_unregister_mode);
+
+static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
+{
+ struct xfrm_state_afinfo *afinfo;
+ struct xfrm_mode *mode;
+ int modload_attempted = 0;
+
+ if (unlikely(encap >= XFRM_MODE_MAX))
+ return NULL;
+
+retry:
+ afinfo = xfrm_state_get_afinfo(family);
+ if (unlikely(afinfo == NULL))
+ return NULL;
+
+ mode = afinfo->mode_map[encap];
+ if (unlikely(mode && !try_module_get(mode->owner)))
+ mode = NULL;
+ if (!mode && !modload_attempted) {
+ xfrm_state_put_afinfo(afinfo);
+ request_module("xfrm-mode-%d-%d", family, encap);
+ modload_attempted = 1;
+ goto retry;
+ }
+
+ xfrm_state_put_afinfo(afinfo);
+ return mode;
+}
+
+static void xfrm_put_mode(struct xfrm_mode *mode)
+{
+ module_put(mode->owner);
+}
+
static void xfrm_state_gc_destroy(struct xfrm_state *x)
{
del_timer_sync(&x->timer);
@@ -196,8 +377,10 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
kfree(x->calg);
kfree(x->encap);
kfree(x->coaddr);
- if (x->mode)
- xfrm_put_mode(x->mode);
+ if (x->inner_mode)
+ xfrm_put_mode(x->inner_mode);
+ if (x->outer_mode)
+ xfrm_put_mode(x->outer_mode);
if (x->type) {
x->type->destructor(x);
xfrm_put_type(x->type);
@@ -1699,7 +1882,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
}
EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
-struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
+static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
{
struct xfrm_state_afinfo *afinfo;
if (unlikely(family >= NPROTO))
@@ -1711,14 +1894,11 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family)
return afinfo;
}
-void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
+static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
{
read_unlock(&xfrm_state_afinfo_lock);
}
-EXPORT_SYMBOL(xfrm_state_get_afinfo);
-EXPORT_SYMBOL(xfrm_state_put_afinfo);
-
/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
void xfrm_state_delete_tunnel(struct xfrm_state *x)
{
@@ -1769,6 +1949,14 @@ int xfrm_init_state(struct xfrm_state *x)
goto error;
err = -EPROTONOSUPPORT;
+ x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
+ if (x->inner_mode == NULL)
+ goto error;
+
+ if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
+ family != x->sel.family)
+ goto error;
+
x->type = xfrm_get_type(x->id.proto, family);
if (x->type == NULL)
goto error;
@@ -1777,8 +1965,8 @@ int xfrm_init_state(struct xfrm_state *x)
if (err)
goto error;
- x->mode = xfrm_get_mode(x->props.mode, family);
- if (x->mode == NULL)
+ x->outer_mode = xfrm_get_mode(x->props.mode, family);
+ if (x->outer_mode == NULL)
goto error;
x->km.state = XFRM_STATE_VALID;
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 677bc6c175c..de7bb284c61 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -75,24 +75,24 @@ try-run = $(shell set -e; \
# Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
as-option = $(call try-run,\
- $(CC) $(CFLAGS) $(1) -c -xassembler /dev/null -o "$$TMP",$(1),$(2))
+ $(CC) $(KBUILD_CFLAGS) $(1) -c -xassembler /dev/null -o "$$TMP",$(1),$(2))
# as-instr
# Usage: cflags-y += $(call as-instr,instr,option1,option2)
as-instr = $(call try-run,\
- echo -e "$(1)" | $(CC) $(AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
+ echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
# cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
cc-option = $(call try-run,\
- $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2))
+ $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",$(1),$(2))
# cc-option-yn
# Usage: flag := $(call cc-option-yn,-march=winchip-c6)
cc-option-yn = $(call try-run,\
- $(CC) $(CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",y,n)
+ $(CC) $(KBUILD_CFLAGS) $(1) -S -xc /dev/null -o "$$TMP",y,n)
# cc-option-align
# Prefix align with either -falign or -malign
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 7fd6055bedf..de9836eee8b 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -22,16 +22,30 @@ EXTRA_AFLAGS :=
EXTRA_CFLAGS :=
EXTRA_CPPFLAGS :=
EXTRA_LDFLAGS :=
+asflags-y :=
+ccflags-y :=
+cppflags-y :=
+ldflags-y :=
# Read .config if it exist, otherwise ignore
-include include/config/auto.conf
include scripts/Kbuild.include
+# For backward compatibility check that these variables does not change
+save-cflags := $(CFLAGS)
+
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
-include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
-
+kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
+include $(kbuild-file)
+
+# If the save-* variables changed error out
+ifeq ($(KBUILD_NOPEDANTIC),)
+ ifneq ("$(save-cflags)","$(CFLAGS)")
+ $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use EXTRA_CFLAGS)
+ endif
+endif
include scripts/Makefile.lib
ifdef host-progs
@@ -55,31 +69,6 @@ _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
endif
-
-ifdef EXTRA_TARGETS
-$(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.6. Please fix!)
-endif
-
-ifdef build-targets
-$(warning kbuild: $(obj)/Makefile - Usage of build-targets is obsolete in 2.6. Please fix!)
-endif
-
-ifdef export-objs
-$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.6. Please fix!)
-endif
-
-ifdef O_TARGET
-$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.6. Please fix!)
-endif
-
-ifdef L_TARGET
-$(error kbuild: $(obj)/Makefile - Use of L_TARGET is replaced by lib-y in 2.6. Please fix!)
-endif
-
-ifdef list-multi
-$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.6. Please fix!)
-endif
-
ifndef obj
$(warning kbuild: Makefile.build is included improperly)
endif
@@ -291,7 +280,7 @@ endif # builtin-target
#
ifdef lib-target
quiet_cmd_link_l_target = AR $@
-cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y)
+cmd_link_l_target = rm -f $@; $(AR) rcs $@ $(lib-y)
$(lib-target): $(lib-y) FORCE
$(call if_changed,link_l_target)
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index cff33498fa1..2c647107c9c 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -40,7 +40,7 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
# build a list of files to remove, usually releative to the current
# directory
-__clean-files := $(extra-y) $(EXTRA_TARGETS) $(always) \
+__clean-files := $(extra-y) $(always) \
$(targets) $(clean-files) \
$(host-progs) \
$(hostprogs-y) $(hostprogs-m) $(hostprogs-)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index fc498fee68e..3c5e88bfecf 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -1,5 +1,9 @@
-# Backward compatibility - to be removed...
-extra-y += $(EXTRA_TARGETS)
+# Backward compatibility
+asflags-y += $(EXTRA_AFLAGS)
+ccflags-y += $(EXTRA_CFLAGS)
+cppflags-y += $(EXTRA_CPPFLAGS)
+ldflags-y += $(EXTRA_LDFLAGS)
+
# Figure out what we need to build from the various variables
# ===========================================================================
@@ -44,9 +48,9 @@ multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
multi-objs := $(multi-objs-y) $(multi-objs-m)
-# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live
-# in the local directory
-subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)))
+# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
+# tell kbuild to descend
+subdir-obj-y := $(filter %/built-in.o, $(obj-y))
# $(obj-dirs) is a list of directories that contain object files
obj-dirs := $(dir $(multi-objs) $(subdir-obj-y))
@@ -86,9 +90,9 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
-_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(basetarget).o)
-_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
-_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
+_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
+_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
+_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
# If building the kernel in a separate objtree expand all occurrences
# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
@@ -108,16 +112,16 @@ __a_flags = $(call flags,_a_flags)
__cpp_flags = $(call flags,_cpp_flags)
endif
-c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(__c_flags) $(modkern_cflags) \
-D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
-a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(__a_flags) $(modkern_aflags)
cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
-ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS)
+ld_flags = $(LDFLAGS) $(ldflags-y)
# Finds the multi-part object the current object will be linked into
modname-multi = $(sort $(foreach m,$(multi-used),\
@@ -140,14 +144,14 @@ $(obj)/%:: $(src)/%_shipped
# target: source(s) FORCE
# $(if_changed,ld/objcopy/gzip)
#
-# and add target to EXTRA_TARGETS so that we know we have to
+# and add target to extra-y so that we know we have to
# read in the saved command line
# Linking
# ---------------------------------------------------------------------------
quiet_cmd_ld = LD $@
-cmd_ld = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) \
+cmd_ld = $(LD) $(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \
$(filter-out FORCE,$^) -o $@
# Objcopy
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 2f60070f973..4c324a1f1e0 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -1,13 +1,13 @@
###
-# Makefile.basic list the most basic programs used during the build process.
-# The programs listed herein is what is needed to do the basic stuff,
-# such as fix dependency file.
+# Makefile.basic lists the most basic programs used during the build process.
+# The programs listed herein are what are needed to do the basic stuff,
+# such as fix file dependencies.
# This initial step is needed to avoid files to be recompiled
# when kernel configuration changes (which is what happens when
# .config is included by main Makefile.
# ---------------------------------------------------------------------------
# fixdep: Used to generate dependency information during build process
-# docproc: Used in Documentation/docbook
+# docproc: Used in Documentation/DocBook
hostprogs-y := fixdep docproc
always := $(hostprogs-y)
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index f4d2f68452b..e5c6ac7bde9 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -10,8 +10,10 @@
* documentation-frontend
* Scans the template file and call kernel-doc for
* all occurrences of ![EIF]file
- * Beforehand each referenced file are scanned for
- * any exported sympols "EXPORT_SYMBOL()" statements.
+ * Beforehand each referenced file is scanned for
+ * any symbols that are exported via these macros:
+ * EXPORT_SYMBOL(), EXPORT_SYMBOL_GPL(), &
+ * EXPORT_SYMBOL_GPL_FUTURE()
* This is used to create proper -function and
* -nofunction arguments in calls to kernel-doc.
* Usage: docproc doc file.tmpl
@@ -73,7 +75,7 @@ void usage (void)
}
/*
- * Execute kernel-doc with parameters givin in svec
+ * Execute kernel-doc with parameters given in svec
*/
void exec_kernel_doc(char **svec)
{
@@ -82,7 +84,7 @@ void exec_kernel_doc(char **svec)
char real_filename[PATH_MAX + 1];
/* Make sure output generated so far are flushed */
fflush(stdout);
- switch(pid=fork()) {
+ switch (pid=fork()) {
case -1:
perror("fork");
exit(1);
@@ -133,6 +135,7 @@ struct symfile * add_new_file(char * filename)
symfilelist[symfilecnt++].filename = strdup(filename);
return &symfilelist[symfilecnt - 1];
}
+
/* Check if file already are present in the list */
struct symfile * filename_exist(char * filename)
{
@@ -156,8 +159,8 @@ void noaction2(char * file, char * line) { file = file; line = line; }
void printline(char * line) { printf("%s", line); }
/*
- * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL
- * in filename.
+ * Find all symbols in filename that are exported with EXPORT_SYMBOL &
+ * EXPORT_SYMBOL_GPL (& EXPORT_SYMBOL_GPL_FUTURE implicitly).
* All symbols located are stored in symfilelist.
*/
void find_export_symbols(char * filename)
@@ -179,15 +182,15 @@ void find_export_symbols(char * filename)
perror(real_filename);
exit(1);
}
- while(fgets(line, MAXLINESZ, fp)) {
+ while (fgets(line, MAXLINESZ, fp)) {
char *p;
char *e;
- if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
- ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
+ if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != NULL) ||
+ ((p = strstr(line, "EXPORT_SYMBOL")) != NULL)) {
/* Skip EXPORT_SYMBOL{_GPL} */
while (isalnum(*p) || *p == '_')
p++;
- /* Remove paranteses and additional ws */
+ /* Remove parentheses & additional whitespace */
while (isspace(*p))
p++;
if (*p != '(')
@@ -211,7 +214,7 @@ void find_export_symbols(char * filename)
* Document all external or internal functions in a file.
* Call kernel-doc with following parameters:
* kernel-doc -docbook -nofunction function_name1 filename
- * function names are obtained from all the src files
+ * Function names are obtained from all the src files
* by find_export_symbols.
* intfunc uses -nofunction
* extfunc uses -function
@@ -262,7 +265,7 @@ void singfunc(char * filename, char * line)
vec[idx++] = KERNELDOC;
vec[idx++] = DOCBOOK;
- /* Split line up in individual parameters preceeded by FUNCTION */
+ /* Split line up in individual parameters preceded by FUNCTION */
for (i=0; line[i]; i++) {
if (isspace(line[i])) {
line[i] = '\0';
@@ -292,7 +295,7 @@ void parse_file(FILE *infile)
{
char line[MAXLINESZ];
char * s;
- while(fgets(line, MAXLINESZ, infile)) {
+ while (fgets(line, MAXLINESZ, infile)) {
if (line[0] == '!') {
s = line + 2;
switch (line[1]) {
@@ -351,9 +354,9 @@ int main(int argc, char *argv[])
{
/* Need to do this in two passes.
* First pass is used to collect all symbols exported
- * in the various files.
+ * in the various files;
* Second pass generate the documentation.
- * This is required because function are declared
+ * This is required because some functions are declared
* and exported in different files :-((
*/
/* Collect symbols */
@@ -396,4 +399,3 @@ int main(int argc, char *argv[])
fflush(stdout);
return exitstatus;
}
-
diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh
new file mode 100755
index 00000000000..39677c82747
--- /dev/null
+++ b/scripts/checkkconfigsymbols.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+# Find Kconfig variables used in source code but never defined in Kconfig
+# Copyright (C) 2007, Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+
+# Tested with dash.
+paths="$@"
+[ -z "$paths" ] && paths=.
+
+# Doing this once at the beginning saves a lot of time, on a cache-hot tree.
+Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`"
+
+echo -e "File list \tundefined symbol used"
+find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i
+do
+ # Output the bare Kconfig variable and the filename; the _MODULE part at
+ # the end is not removed here (would need perl an not-hungry regexp for that).
+ sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Z_]\+\).*!\2 '$i'!p' < $i
+done | \
+# Smart "sort|uniq" implemented in awk and tuned to collect the names of all
+# files which use a given symbol
+awk '{map[$1, count[$1]++] = $2; }
+END {
+ for (combIdx in map) {
+ split(combIdx, separate, SUBSEP);
+ # The value may have been removed.
+ if (! ( (separate[1], separate[2]) in map ) )
+ continue;
+ symb=separate[1];
+ printf "%s ", symb;
+ #Use gawk extension to delete the names vector
+ delete names;
+ #Portably delete the names vector
+ #split("", names);
+ for (i=0; i < count[symb]; i++) {
+ names[map[symb, i]] = 1;
+ # Unfortunately, we may still encounter symb, i in the
+ # outside iteration.
+ delete map[symb, i];
+ }
+ i=0;
+ for (name in names) {
+ if (i > 0)
+ printf ", %s", name;
+ else
+ printf "%s", name;
+ i++;
+ }
+ printf "\n";
+ }
+}' |
+while read symb files; do
+ # Remove the _MODULE suffix when checking the variable name. This should
+ # be done only on tristate symbols, actually, but Kconfig parsing is
+ # beyond the purpose of this script.
+ symb_bare=`echo $symb | sed -e 's/_MODULE//'`
+ if ! grep -q "\<$symb_bare\>" $Kconfigs; then
+ echo -e "$files: \t$symb"
+ fi
+done|sort
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index dae7d30dca0..cbb42580a81 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.09';
+my $V = '0.11';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -18,12 +18,21 @@ my $tree = 1;
my $chk_signoff = 1;
my $chk_patch = 1;
my $tst_type = 0;
+my $emacs = 0;
+my $file = 0;
+my $check = 0;
+my $root;
GetOptions(
- 'q|quiet' => \$quiet,
+ 'q|quiet+' => \$quiet,
'tree!' => \$tree,
'signoff!' => \$chk_signoff,
'patch!' => \$chk_patch,
'test-type!' => \$tst_type,
+ 'emacs!' => \$emacs,
+ 'file!' => \$file,
+ 'subjective!' => \$check,
+ 'strict!' => \$check,
+ 'root=s' => \$root,
) or exit;
my $exit = 0;
@@ -33,19 +42,110 @@ if ($#ARGV < 0) {
print "version: $V\n";
print "options: -q => quiet\n";
print " --no-tree => run without a kernel tree\n";
+ print " --emacs => emacs compile window format\n";
+ print " --file => check a source file\n";
+ print " --strict => enable more subjective tests\n";
+ print " --root => path to the kernel tree root\n";
exit(1);
}
-if ($tree && !top_of_kernel_tree()) {
- print "Must be run from the top-level dir. of a kernel tree\n";
- exit(2);
+if ($tree) {
+ if (defined $root) {
+ if (!top_of_kernel_tree($root)) {
+ die "$P: $root: --root does not point at a valid tree\n";
+ }
+ } else {
+ if (top_of_kernel_tree('.')) {
+ $root = '.';
+ } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
+ top_of_kernel_tree($1)) {
+ $root = $1;
+ }
+ }
+
+ if (!defined $root) {
+ print "Must be run from the top-level dir. of a kernel tree\n";
+ exit(2);
+ }
}
+my $emitted_corrupt = 0;
+
+our $Ident = qr{[A-Za-z_][A-Za-z\d_]*};
+our $Storage = qr{extern|static|asmlinkage};
+our $Sparse = qr{
+ __user|
+ __kernel|
+ __force|
+ __iomem|
+ __must_check|
+ __init_refok|
+ __kprobes|
+ fastcall
+ }x;
+our $Attribute = qr{
+ const|
+ __read_mostly|
+ __kprobes|
+ __(?:mem|cpu|dev|)(?:initdata|init)
+ }x;
+our $Inline = qr{inline|__always_inline|noinline};
+our $NonptrType = qr{
+ \b
+ (?:const\s+)?
+ (?:unsigned\s+)?
+ (?:
+ void|
+ char|
+ short|
+ int|
+ long|
+ unsigned|
+ float|
+ double|
+ bool|
+ long\s+int|
+ long\s+long|
+ long\s+long\s+int|
+ (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
+ struct\s+$Ident|
+ union\s+$Ident|
+ enum\s+$Ident|
+ ${Ident}_t|
+ ${Ident}_handler|
+ ${Ident}_handler_fn
+ )
+ (?:\s+$Sparse)*
+ \b
+ }x;
+
+our $Type = qr{
+ \b$NonptrType\b
+ (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+ (?:\s+$Sparse|\s+$Attribute)*
+ }x;
+our $Declare = qr{(?:$Storage\s+)?$Type};
+our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
+our $Lval = qr{$Ident(?:$Member)*};
+
+our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
+our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
+our $Operators = qr{
+ <=|>=|==|!=|
+ =>|->|<<|>>|<|>|!|~|
+ &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
+ }x;
+
+our $Bare = '';
+
+$chk_signoff = 0 if ($file);
+
my @dep_includes = ();
my @dep_functions = ();
-my $removal = 'Documentation/feature-removal-schedule.txt';
-if ($tree && -f $removal) {
- open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n";
+my $removal = "Documentation/feature-removal-schedule.txt";
+if ($tree && -f "$root/$removal") {
+ open(REMOVE, "<$root/$removal") ||
+ die "$P: $removal: open failed - $!\n";
while (<REMOVE>) {
if (/^Check:\s+(.*\S)/) {
for my $entry (split(/[, ]+/, $1)) {
@@ -61,28 +161,42 @@ if ($tree && -f $removal) {
}
my @rawlines = ();
-while (<>) {
- chomp;
- push(@rawlines, $_);
- if (eof(ARGV)) {
- if (!process($ARGV, @rawlines)) {
- $exit = 1;
- }
- @rawlines = ();
+for my $filename (@ARGV) {
+ if ($file) {
+ open(FILE, "diff -u /dev/null $filename|") ||
+ die "$P: $filename: diff failed - $!\n";
+ } else {
+ open(FILE, "<$filename") ||
+ die "$P: $filename: open failed - $!\n";
}
+ while (<FILE>) {
+ chomp;
+ push(@rawlines, $_);
+ }
+ close(FILE);
+ if (!process($filename, @rawlines)) {
+ $exit = 1;
+ }
+ @rawlines = ();
}
exit($exit);
sub top_of_kernel_tree {
- if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") &&
- (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") &&
- (-d "Documentation") && (-d "arch") && (-d "include") &&
- (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") &&
- (-d "kernel") && (-d "lib") && (-d "scripts")) {
- return 1;
+ my ($root) = @_;
+
+ my @tree_check = (
+ "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
+ "README", "Documentation", "arch", "include", "drivers",
+ "fs", "init", "ipc", "kernel", "lib", "scripts",
+ );
+
+ foreach my $check (@tree_check) {
+ if (! -e $root . '/' . $check) {
+ return 0;
+ }
}
- return 0;
+ return 1;
}
sub expand_tabs {
@@ -105,6 +219,20 @@ sub expand_tabs {
return $res;
}
+sub copy_spacing {
+ my ($str) = @_;
+
+ my $res = '';
+ for my $c (split(//, $str)) {
+ if ($c eq "\t") {
+ $res .= $c;
+ } else {
+ $res .= ' ';
+ }
+ }
+
+ return $res;
+}
sub line_stats {
my ($line) = @_;
@@ -212,6 +340,11 @@ sub ctx_block_level {
return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
}
+sub ctx_statement_level {
+ my ($linenr, $remain, $off) = @_;
+
+ return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
+}
sub ctx_locate_comment {
my ($first_line, $end_line) = @_;
@@ -257,16 +390,136 @@ sub ctx_has_comment {
sub cat_vet {
my ($vet) = @_;
+ my ($res, $coded);
- $vet =~ s/\t/^I/;
- $vet =~ s/$/\$/;
+ $res = '';
+ while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
+ $res .= $1;
+ if ($2 ne '') {
+ $coded = sprintf("^%c", unpack('C', $2) + 64);
+ $res .= $coded;
+ }
+ }
+ $res =~ s/$/\$/;
- return $vet;
+ return $res;
}
+sub annotate_values {
+ my ($stream, $type) = @_;
+
+ my $res;
+ my $cur = $stream;
+
+ my $debug = 0;
+
+ print "$stream\n" if ($debug);
+
+ ##my $type = 'N';
+ my $pos = 0;
+ my $preprocessor = 0;
+ my $paren = 0;
+ my @paren_type;
+
+ # Include any user defined types we may have found as we went.
+ my $type_match = "(?:$Type$Bare)";
+
+ while (length($cur)) {
+ print " <$type> " if ($debug);
+ if ($cur =~ /^(\s+)/o) {
+ print "WS($1)\n" if ($debug);
+ if ($1 =~ /\n/ && $preprocessor) {
+ $preprocessor = 0;
+ $type = 'N';
+ }
+
+ } elsif ($cur =~ /^($type_match)/) {
+ print "DECLARE($1)\n" if ($debug);
+ $type = 'T';
+
+ } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) {
+ print "DEFINE($1)\n" if ($debug);
+ $preprocessor = 1;
+ $paren_type[$paren] = 'N';
+
+ } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) {
+ print "PRE($1)\n" if ($debug);
+ $preprocessor = 1;
+ $type = 'N';
+
+ } elsif ($cur =~ /^(\\\n)/o) {
+ print "PRECONT($1)\n" if ($debug);
+
+ } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
+ print "SIZEOF($1)\n" if ($debug);
+ if (defined $2) {
+ $paren_type[$paren] = 'V';
+ }
+ $type = 'N';
+
+ } elsif ($cur =~ /^(if|while|typeof)\b/o) {
+ print "COND($1)\n" if ($debug);
+ $paren_type[$paren] = 'N';
+ $type = 'N';
+
+ } elsif ($cur =~/^(return|case|else)/o) {
+ print "KEYWORD($1)\n" if ($debug);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(\()/o) {
+ print "PAREN('$1')\n" if ($debug);
+ $paren++;
+ $type = 'N';
+
+ } elsif ($cur =~ /^(\))/o) {
+ $paren-- if ($paren > 0);
+ if (defined $paren_type[$paren]) {
+ $type = $paren_type[$paren];
+ undef $paren_type[$paren];
+ print "PAREN('$1') -> $type\n" if ($debug);
+ } else {
+ print "PAREN('$1')\n" if ($debug);
+ }
+
+ } elsif ($cur =~ /^($Ident)\(/o) {
+ print "FUNC($1)\n" if ($debug);
+ $paren_type[$paren] = 'V';
+
+ } elsif ($cur =~ /^($Ident|$Constant)/o) {
+ print "IDENT($1)\n" if ($debug);
+ $type = 'V';
+
+ } elsif ($cur =~ /^($Assignment)/o) {
+ print "ASSIGN($1)\n" if ($debug);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) {
+ print "END($1)\n" if ($debug);
+ $type = 'N';
+
+ } elsif ($cur =~ /^($Operators)/o) {
+ print "OP($1)\n" if ($debug);
+ if ($1 ne '++' && $1 ne '--') {
+ $type = 'N';
+ }
+
+ } elsif ($cur =~ /(^.)/o) {
+ print "C($1)\n" if ($debug);
+ }
+ if (defined $1) {
+ $cur = substr($cur, length($1));
+ $res .= $type x length($1);
+ }
+ }
+
+ return $res;
+}
+
+my $prefix = '';
+
my @report = ();
sub report {
- push(@report, $_[0]);
+ push(@report, $prefix . $_[0]);
}
sub report_dump {
@report;
@@ -274,14 +527,19 @@ sub report_dump {
sub ERROR {
report("ERROR: $_[0]\n");
our $clean = 0;
+ our $cnt_error++;
}
sub WARN {
report("WARNING: $_[0]\n");
our $clean = 0;
+ our $cnt_warn++;
}
sub CHK {
- report("CHECK: $_[0]\n");
- our $clean = 0;
+ if ($check) {
+ report("CHECK: $_[0]\n");
+ our $clean = 0;
+ our $cnt_chk++;
+ }
}
sub process {
@@ -301,6 +559,11 @@ sub process {
my $signoff = 0;
my $is_patch = 0;
+ our $cnt_lines = 0;
+ our $cnt_error = 0;
+ our $cnt_warn = 0;
+ our $cnt_chk = 0;
+
# Trace the real file/line as we go.
my $realfile = '';
my $realline = 0;
@@ -309,46 +572,10 @@ sub process {
my $in_comment = 0;
my $first_line = 0;
- my $Ident = qr{[A-Za-z\d_]+};
- my $Storage = qr{extern|static};
- my $Sparse = qr{__user|__kernel|__force|__iomem|__must_check|__init_refok};
- my $NonptrType = qr{
- \b
- (?:const\s+)?
- (?:unsigned\s+)?
- (?:
- void|
- char|
- short|
- int|
- long|
- unsigned|
- float|
- double|
- bool|
- long\s+int|
- long\s+long|
- long\s+long\s+int|
- u8|u16|u32|u64|
- s8|s16|s32|s64|
- struct\s+$Ident|
- union\s+$Ident|
- enum\s+$Ident|
- ${Ident}_t
- )
- (?:\s+$Sparse)*
- \b
- }x;
- my $Type = qr{
- \b$NonptrType\b
- (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
- (?:\s+$Sparse)*
- }x;
- my $Declare = qr{(?:$Storage\s+)?$Type};
- my $Attribute = qr{const|__read_mostly|__init|__initdata|__meminit};
-
- my $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
- my $Lval = qr{$Ident(?:$Member)*};
+ my $prev_values = 'N';
+
+ # Possible bare types.
+ my @bare = ();
# Pre-scan the patch looking for any __setup documentation.
my @setup_docs = ();
@@ -367,11 +594,14 @@ sub process {
}
}
+ $prefix = '';
+
foreach my $line (@lines) {
$linenr++;
my $rawline = $line;
+
#extract the filename as it passes
if ($line=~/^\+\+\+\s+(\S+)/) {
$realfile=$1;
@@ -380,7 +610,7 @@ sub process {
next;
}
#extract the line range in the file after the patch is applied
- if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) {
+ if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
$is_patch = 1;
$first_line = $linenr + 1;
$in_comment = 0;
@@ -390,6 +620,7 @@ sub process {
} else {
$realcnt=1+1;
}
+ $prev_values = 'N';
next;
}
@@ -423,18 +654,24 @@ sub process {
# Track the previous line.
($prevline, $stashline) = ($stashline, $line);
($previndent, $stashindent) = ($stashindent, $indent);
+
} elsif ($realcnt == 1) {
$realcnt--;
}
#make up the handle for any error we report on this line
- $here = "#$linenr: ";
+ $here = "#$linenr: " if (!$file);
+ $here = "#$realline: " if ($file);
$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
my $hereline = "$here\n$line\n";
my $herecurr = "$here\n$line\n";
my $hereprev = "$here\n$prevline\n$line\n";
+ $prefix = "$filename:$realline: " if ($emacs && $file);
+ $prefix = "$filename:$linenr: " if ($emacs && !$file);
+ $cnt_lines++ if ($realcnt != 0);
+
#check the patch for a signoff:
if ($line =~ /^\s*signed-off-by:/i) {
# This is a signoff, if ugly, so do not double report.
@@ -452,7 +689,7 @@ sub process {
# Check for wrappage within a valid hunk of the file
if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) {
ERROR("patch seems to be corrupt (line wrapped?)\n" .
- $herecurr);
+ $herecurr) if (!$emitted_corrupt++);
}
# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
@@ -477,7 +714,11 @@ sub process {
next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
#trailing whitespace
- if ($line =~ /^\+.*\S\s+$/ || $line =~ /^\+\s+$/) {
+ if ($line =~ /^\+.*\015/) {
+ my $herevet = "$here\n" . cat_vet($line) . "\n";
+ ERROR("DOS line endings\n" . $herevet);
+
+ } elsif ($line =~ /^\+.*\S\s+$/ || $line =~ /^\+\s+$/) {
my $herevet = "$here\n" . cat_vet($line) . "\n";
ERROR("trailing whitespace\n" . $herevet);
}
@@ -509,6 +750,34 @@ sub process {
# Standardise the strings and chars within the input to simplify matching.
$line = sanitise_line($line);
+# Check for potential 'bare' types
+ if ($realcnt &&
+ $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ &&
+ $line !~ /$Ident:\s*$/ &&
+ $line !~ /^.\s*$Ident\s*\(/ &&
+ # definitions in global scope can only start with types
+ ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ ||
+ # declarations always start with types
+ $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) ||
+ # any (foo ... *) is a pointer cast, and foo is a type
+ $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) {
+ my $possible = $1;
+ if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ &&
+ $possible ne 'goto' && $possible ne 'return' &&
+ $possible ne 'struct' && $possible ne 'enum' &&
+ $possible ne 'case' && $possible ne 'else' &&
+ $possible ne 'typedef') {
+ #print "POSSIBLE<$possible>\n";
+ push(@bare, $possible);
+ my $bare = join("|", @bare);
+ $Bare = '|' . qr{
+ \b(?:$bare)\b
+ (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+ (?:\s+$Sparse)*
+ }x;
+ }
+ }
+
#
# Checks which may be anchored in the context.
#
@@ -531,18 +800,19 @@ sub process {
}
}
if ($err ne '') {
- ERROR("switch and case should be at the same indent\n$hereline\n$err\n");
+ ERROR("switch and case should be at the same indent\n$hereline$err");
}
}
# if/while/etc brace do not go on next line, unless defining a do while loop,
# or if that brace on the next line is for something else
if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) {
- my @ctx = ctx_statement($linenr, $realcnt, 0);
+ my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
my $ctx_ln = $linenr + $#ctx + 1;
my $ctx_cnt = $realcnt - $#ctx - 1;
my $ctx = join("\n", @ctx);
+ # Skip over any removed lines in the context following statement.
while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) {
$ctx_ln++;
$ctx_cnt--;
@@ -553,8 +823,23 @@ sub process {
ERROR("That open brace { should be on the previous line\n" .
"$here\n$ctx\n$lines[$ctx_ln - 1]");
}
+ if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) {
+ my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
+ if ($nindent > $indent) {
+ WARN("Trailing semicolon indicates no statements, indent implies otherwise\n" .
+ "$here\n$ctx\n$lines[$ctx_ln - 1]");
+ }
+ }
}
+ # Track the 'values' across context and added lines.
+ my $opline = $line; $opline =~ s/^./ /;
+ my $curr_values = annotate_values($opline . "\n", $prev_values);
+ $curr_values = $prev_values . $curr_values;
+ #warn "--> $opline\n";
+ #warn "--> $curr_values ($prev_values)\n";
+ $prev_values = substr($curr_values, -1);
+
#ignore lines not being added
if ($line=~/^[^\+]/) {next;}
@@ -592,6 +877,7 @@ sub process {
}
# Remove C99 comments.
$line =~ s@//.*@@;
+ $opline =~ s@//.*@@;
#EXPORT_SYMBOL should immediately follow its function closing }.
if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
@@ -619,7 +905,7 @@ sub process {
# check for new typedefs, only function parameters and sparse annotations
# make sense.
if ($line =~ /\btypedef\s/ &&
- $line !~ /\btypedef\s+$Type\s+\(\s*\*$Ident\s*\)\s*\(/ &&
+ $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
$line !~ /\b__bitwise(?:__|)\b/) {
WARN("do not add new typedefs\n" . $herecurr);
}
@@ -633,11 +919,11 @@ sub process {
ERROR("\"(foo $1 )\" should be \"(foo $1)\"\n" .
$herecurr);
- } elsif ($line =~ m{$NonptrType(\*+)(?:\s+$Attribute)?\s+[A-Za-z\d_]+}) {
+ } elsif ($line =~ m{$NonptrType(\*+)(?:\s+(?:$Attribute|$Sparse))?\s+[A-Za-z\d_]+}) {
ERROR("\"foo$1 bar\" should be \"foo $1bar\"\n" .
$herecurr);
- } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+$Attribute)\s+[A-Za-z\d_]+}) {
+ } elsif ($line =~ m{$NonptrType\s+(\*+)(?!\s+(?:$Attribute|$Sparse))\s+[A-Za-z\d_]+}) {
ERROR("\"foo $1 bar\" should be \"foo $1bar\"\n" .
$herecurr);
}
@@ -680,21 +966,25 @@ sub process {
}
# check for spaces between functions and their parentheses.
- if ($line =~ /($Ident)\s+\(/ &&
- $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ &&
- $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
- WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+ while ($line =~ /($Ident)\s+\(/g) {
+ if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ &&
+ $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
+ WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+ }
}
# Check operator spacing.
- # Note we expand the line with the leading + as the real
- # line will be displayed with the leading + and the tabs
- # will therefore also expand that way.
- my $opline = $line;
- $opline = expand_tabs($opline);
- $opline =~ s/^./ /;
if (!($line=~/\#\s*include/)) {
- my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|=>|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline);
+ my $ops = qr{
+ <<=|>>=|<=|>=|==|!=|
+ \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
+ =>|->|<<|>>|<|>|=|!|~|
+ &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/
+ }x;
+ my @elements = split(/($ops|;)/, $opline);
my $off = 0;
+
+ my $blank = copy_spacing($opline);
+
for (my $n = 0; $n < $#elements; $n += 2) {
$off += length($elements[$n]);
@@ -730,10 +1020,25 @@ sub process {
my $at = "(ctx:$ctx)";
- my $ptr = (" " x $off) . "^";
+ my $ptr = substr($blank, 0, $off) . "^";
my $hereptr = "$hereline$ptr\n";
- ##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n";
+ # Classify operators into binary, unary, or
+ # definitions (* only) where they have more
+ # than one mode.
+ my $op_type = substr($curr_values, $off + 1, 1);
+ my $op_left = substr($curr_values, $off, 1);
+ my $is_unary;
+ if ($op_type eq 'T') {
+ $is_unary = 2;
+ } elsif ($op_left eq 'V') {
+ $is_unary = 0;
+ } else {
+ $is_unary = 1;
+ }
+ #if ($op eq '-' || $op eq '&' || $op eq '*') {
+ # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n";
+ #}
# ; should have either the end of line or a space or \ after it
if ($op eq ';') {
@@ -757,9 +1062,16 @@ sub process {
ERROR("need space after that '$op' $at\n" . $hereptr);
}
- # unary ! and unary ~ are allowed no space on the right
- } elsif ($op eq '!' or $op eq '~') {
- if ($ctx !~ /[WOEB]x./) {
+ # '*' as part of a type definition -- reported already.
+ } elsif ($op eq '*' && $is_unary == 2) {
+ #warn "'*' is part of type\n";
+
+ # unary operators should have a space before and
+ # none after. May be left adjacent to another
+ # unary operator, or a cast
+ } elsif ($op eq '!' || $op eq '~' ||
+ ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) {
+ if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
ERROR("need space before that '$op' $at\n" . $hereptr);
}
if ($ctx =~ /.xW/) {
@@ -775,39 +1087,13 @@ sub process {
ERROR("no space before that '$op' $at\n" . $hereptr);
}
- # & is both unary and binary
- # unary:
- # a &b
- # binary (consistent spacing):
- # a&b OK
- # a & b OK
- #
- # boiling down to: if there is a space on the right then there
- # should be one on the left.
- #
- # - is the same
- #
- } elsif ($op eq '&' or $op eq '-') {
- if ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]/) {
- ERROR("need space before that '$op' $at\n" . $hereptr);
- }
-
- # * is the same as & only adding:
- # type:
- # (foo *)
- # (foo **)
- #
- } elsif ($op eq '*') {
- if ($ca !~ /$Type$/ && $cb !~ /(\*$;|$;\*)/ &&
- $ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]|OxV|WxB|BxB/) {
- ERROR("need space before that '$op' $at\n" . $hereptr);
- }
-
# << and >> may either have or not have spaces both sides
- } elsif ($op eq '<<' or $op eq '>>' or $op eq '+' or $op eq '/' or
- $op eq '^' or $op eq '|')
+ } elsif ($op eq '<<' or $op eq '>>' or
+ $op eq '&' or $op eq '^' or $op eq '|' or
+ $op eq '+' or $op eq '-' or
+ $op eq '*' or $op eq '/')
{
- if ($ctx !~ /VxV|WxW|VxE|WxE/) {
+ if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) {
ERROR("need consistent spacing around '$op' $at\n" .
$hereptr);
}
@@ -826,7 +1112,7 @@ sub process {
# check for multiple assignments
if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
- WARN("multiple assignments should be avoided\n" . $herecurr);
+ CHK("multiple assignments should be avoided\n" . $herecurr);
}
## # check for multiple declarations, allowing for a function declaration
@@ -865,10 +1151,12 @@ sub process {
}
# check spacing on paretheses
- if ($line =~ /\(\s/ && $line !~ /\(\s*$/) {
+ if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
+ $line !~ /for\s*\(\s+;/) {
ERROR("no space after that open parenthesis '('\n" . $herecurr);
}
- if ($line =~ /\s\)/) {
+ if ($line =~ /\s\)/ && $line !~ /^.\s*\)/ &&
+ $line !~ /for\s*\(.*;\s+\)/) {
ERROR("no space before that close parenthesis ')'\n" . $herecurr);
}
@@ -884,7 +1172,7 @@ sub process {
}
# Check for illegal assignment in if conditional.
- if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) {
+ if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) {
#next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/);
ERROR("do not use assignment in if condition\n" . $herecurr);
}
@@ -910,8 +1198,8 @@ sub process {
#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) {
- my $checkfile = "include/linux/$1.h";
- if (-f $checkfile) {
+ my $checkfile = "$root/include/linux/$1.h";
+ if (-f $checkfile && $1 ne 'irq.h') {
CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
$herecurr);
}
@@ -926,10 +1214,10 @@ sub process {
# multi-statement macros should be enclosed in a do while loop, grab the
# first statement and ensure its the whole macro if its not enclosed
# in a known goot container
- if (($prevline=~/\#define.*\\/) and
- !($prevline=~/do\s+{/) and !($prevline=~/\(\{/) and
- !($line=~/do.*{/) and !($line=~/\(\{/) and
- !($line=~/^.\s*$Declare\s/)) {
+ if ($prevline =~ /\#define.*\\/ &&
+ $prevline !~/(?:do\s+{|\(\{|\{)/ &&
+ $line !~ /(?:do\s+{|\(\{|\{)/ &&
+ $line !~ /^.\s*$Declare\s/) {
# Grab the first statement, if that is the entire macro
# its ok. This may start either on the #define line
# or the one below.
@@ -1023,10 +1311,16 @@ sub process {
}
# no volatiles please
- if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) {
+ my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
+ if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
}
+# SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated
+ if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) {
+ ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr);
+ }
+
# warn about #if 0
if ($line =~ /^.#\s*if\s+0\b/) {
CHK("if this code is redundant consider removing it\n" .
@@ -1073,8 +1367,8 @@ sub process {
# check the location of the inline attribute, that it is between
# storage class and type.
- if ($line =~ /$Type\s+(?:inline|__always_inline|noinline)\b/ ||
- $line =~ /\b(?:inline|__always_inline|noinline)\s+$Storage/) {
+ if ($line =~ /\b$Type\s+$Inline\b/ ||
+ $line =~ /\b$Inline\s+$Storage\b/) {
ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
}
@@ -1091,6 +1385,11 @@ sub process {
CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
}
}
+
+# check for pointless casting of kmalloc return
+ if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) {
+ WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
+ }
}
if ($chk_patch && !$is_patch) {
@@ -1102,6 +1401,11 @@ sub process {
if ($clean == 0 && ($chk_patch || $is_patch)) {
print report_dump();
+ if ($quiet < 2) {
+ print "total: $cnt_error errors, $cnt_warn warnings, " .
+ (($check)? "$cnt_chk checks, " : "") .
+ "$cnt_lines lines checked\n";
+ }
}
if ($clean == 1 && $quiet == 0) {
print "Your patch has no obvious style problems and is ready for submission.\n"
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 66315862715..b458e2acb4a 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -78,6 +78,9 @@ my (@stack, $re, $x, $xs);
# pair for larger users. -- PFM.
#a00048e0: d4fc40f0 addi.l r15,-240,r15
$re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
+ } elsif ($arch =~ /^blackfin$/) {
+ # 0: 00 e8 38 01 LINK 0x4e0;
+ $re = qr/.*[[:space:]]LINK[[:space:]]*(0x$x{1,8})/o;
} else {
print("wrong or unknown architecture\n");
exit
diff --git a/scripts/export_report.pl b/scripts/export_report.pl
index 9ed00d9bb0a..705b5ba7c15 100644
--- a/scripts/export_report.pl
+++ b/scripts/export_report.pl
@@ -103,16 +103,16 @@ foreach my $thismod (@allcfiles) {
my $state=0;
while ( <MODULE_MODULE> ) {
chomp;
- if ($state eq 0) {
+ if ($state == 0) {
$state = 1 if ($_ =~ /static const struct modversion_info/);
next;
}
- if ($state eq 1) {
+ if ($state == 1) {
$state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/);
next;
}
- if ($state eq 2) {
- if ( $_ !~ /0x[0-9a-f]{7,8},/ ) {
+ if ($state == 2) {
+ if ( $_ !~ /0x[0-9a-f]+,/ ) {
next;
}
my $sym = (split /([,"])/,)[4];
@@ -121,7 +121,7 @@ foreach my $thismod (@allcfiles) {
push(@{$MODULE{$thismod}} , $sym);
}
}
- if ($state ne 2) {
+ if ($state != 2) {
print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
}
close(MODULE_MODULE);
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
index 8a1d1879c7a..a5121a6d894 100644
--- a/scripts/gcc-version.sh
+++ b/scripts/gcc-version.sh
@@ -9,10 +9,16 @@
# gcc-2.95.3, `030301' for gcc-3.3.1, etc.
#
-if [ $1 = "-p" ] ; then with_patchlevel=1; shift; fi
+if [[ $1 = "-p" ]] ; then with_patchlevel=1; shift; fi
compiler="$*"
+if [ ${#compiler} -eq 0 ]; then
+ echo "Error: No compiler specified."
+ echo -e "Usage:\n\t$0 <gcc-command>"
+ exit 1
+fi
+
MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
if [ "x$with_patchlevel" != "x" ] ; then
diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile
index 5875f29a860..e420fe44001 100644
--- a/scripts/genksyms/Makefile
+++ b/scripts/genksyms/Makefile
@@ -23,14 +23,16 @@ quiet_cmd_keywords.c = GPERF $@
$(obj)/keywords.c: $(obj)/keywords.gperf FORCE
$(call if_changed,keywords.c)
+ cp $@ $@_shipped
# flex
quiet_cmd_lex.c = FLEX $@
- cmd_lex.c = flex -o$@ -d $(filter-out FORCE,$^)
+ cmd_lex.c = flex -o$@ -d $< $(obj)/parse.h
-$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h FORCE
+$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h $(obj)/keywords.c FORCE
$(call if_changed,lex.c)
+ cp $@ $@_shipped
# bison
@@ -39,6 +41,8 @@ quiet_cmd_parse.c = BISON $@
$(obj)/parse.c: $(obj)/parse.y FORCE
$(call if_changed,parse.c)
+ cp $@ $@_shipped
+ cp $(@:.c=.h) $(@:.c=.h)_shipped
$(obj)/parse.h: $(obj)/parse.c ;
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index d8153f572e4..971e0113ae7 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.1 */
+/* ANSI-C code produced by gperf version 3.0.2 */
/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -32,7 +32,7 @@
#line 3 "scripts/genksyms/keywords.gperf"
struct resword { const char *name; int token; };
-/* maximum key range = 68, duplicates = 0 */
+/* maximum key range = 62, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -46,32 +46,32 @@ is_reserved_hash (register const char *str, register unsigned int len)
{
static const unsigned char asso_values[] =
{
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 0,
- 71, 71, 71, 71, 71, 71, 35, 71, 71, 71,
- 5, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 0, 71, 0, 71, 5,
- 5, 0, 10, 20, 71, 25, 71, 71, 20, 0,
- 20, 30, 25, 71, 10, 5, 0, 20, 15, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 5,
+ 65, 65, 65, 65, 65, 65, 35, 65, 65, 65,
+ 0, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 0, 65, 0, 65, 5,
+ 20, 15, 10, 30, 65, 15, 65, 65, 20, 0,
+ 10, 35, 20, 65, 10, 5, 0, 10, 5, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 65, 65
};
return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
}
@@ -84,17 +84,17 @@ is_reserved_word (register const char *str, register unsigned int len)
{
enum
{
- TOTAL_KEYWORDS = 42,
+ TOTAL_KEYWORDS = 43,
MIN_WORD_LENGTH = 3,
MAX_WORD_LENGTH = 24,
MIN_HASH_VALUE = 3,
- MAX_HASH_VALUE = 70
+ MAX_HASH_VALUE = 64
};
static const struct resword wordlist[] =
{
{""}, {""}, {""},
-#line 25 "scripts/genksyms/keywords.gperf"
+#line 26 "scripts/genksyms/keywords.gperf"
{"asm", ASM_KEYW},
{""},
#line 8 "scripts/genksyms/keywords.gperf"
@@ -102,98 +102,98 @@ is_reserved_word (register const char *str, register unsigned int len)
{""},
#line 9 "scripts/genksyms/keywords.gperf"
{"__asm__", ASM_KEYW},
- {""},
-#line 22 "scripts/genksyms/keywords.gperf"
- {"_restrict", RESTRICT_KEYW},
-#line 51 "scripts/genksyms/keywords.gperf"
+ {""}, {""},
+#line 52 "scripts/genksyms/keywords.gperf"
{"__typeof__", TYPEOF_KEYW},
-#line 10 "scripts/genksyms/keywords.gperf"
- {"__attribute", ATTRIBUTE_KEYW},
+ {""},
#line 12 "scripts/genksyms/keywords.gperf"
{"__const", CONST_KEYW},
#line 11 "scripts/genksyms/keywords.gperf"
{"__attribute__", ATTRIBUTE_KEYW},
#line 13 "scripts/genksyms/keywords.gperf"
{"__const__", CONST_KEYW},
-#line 17 "scripts/genksyms/keywords.gperf"
+#line 18 "scripts/genksyms/keywords.gperf"
{"__signed__", SIGNED_KEYW},
-#line 43 "scripts/genksyms/keywords.gperf"
+#line 44 "scripts/genksyms/keywords.gperf"
{"static", STATIC_KEYW},
- {""},
-#line 16 "scripts/genksyms/keywords.gperf"
- {"__signed", SIGNED_KEYW},
-#line 31 "scripts/genksyms/keywords.gperf"
+#line 20 "scripts/genksyms/keywords.gperf"
+ {"__volatile__", VOLATILE_KEYW},
+#line 39 "scripts/genksyms/keywords.gperf"
+ {"int", INT_KEYW},
+#line 32 "scripts/genksyms/keywords.gperf"
{"char", CHAR_KEYW},
- {""},
-#line 44 "scripts/genksyms/keywords.gperf"
+#line 33 "scripts/genksyms/keywords.gperf"
+ {"const", CONST_KEYW},
+#line 45 "scripts/genksyms/keywords.gperf"
{"struct", STRUCT_KEYW},
-#line 23 "scripts/genksyms/keywords.gperf"
- {"__restrict__", RESTRICT_KEYW},
#line 24 "scripts/genksyms/keywords.gperf"
+ {"__restrict__", RESTRICT_KEYW},
+#line 25 "scripts/genksyms/keywords.gperf"
{"restrict", RESTRICT_KEYW},
-#line 34 "scripts/genksyms/keywords.gperf"
+#line 23 "scripts/genksyms/keywords.gperf"
+ {"_restrict", RESTRICT_KEYW},
+#line 16 "scripts/genksyms/keywords.gperf"
+ {"__inline__", INLINE_KEYW},
+#line 10 "scripts/genksyms/keywords.gperf"
+ {"__attribute", ATTRIBUTE_KEYW},
+ {""},
+#line 14 "scripts/genksyms/keywords.gperf"
+ {"__extension__", EXTENSION_KEYW},
+#line 35 "scripts/genksyms/keywords.gperf"
{"enum", ENUM_KEYW},
-#line 18 "scripts/genksyms/keywords.gperf"
+#line 19 "scripts/genksyms/keywords.gperf"
{"__volatile", VOLATILE_KEYW},
-#line 35 "scripts/genksyms/keywords.gperf"
+#line 36 "scripts/genksyms/keywords.gperf"
{"extern", EXTERN_KEYW},
-#line 19 "scripts/genksyms/keywords.gperf"
- {"__volatile__", VOLATILE_KEYW},
-#line 38 "scripts/genksyms/keywords.gperf"
- {"int", INT_KEYW},
+ {""},
+#line 17 "scripts/genksyms/keywords.gperf"
+ {"__signed", SIGNED_KEYW},
#line 7 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
-#line 32 "scripts/genksyms/keywords.gperf"
- {"const", CONST_KEYW},
-#line 33 "scripts/genksyms/keywords.gperf"
- {"double", DOUBLE_KEYW},
{""},
-#line 14 "scripts/genksyms/keywords.gperf"
+#line 51 "scripts/genksyms/keywords.gperf"
+ {"typeof", TYPEOF_KEYW},
+#line 46 "scripts/genksyms/keywords.gperf"
+ {"typedef", TYPEDEF_KEYW},
+#line 15 "scripts/genksyms/keywords.gperf"
{"__inline", INLINE_KEYW},
-#line 30 "scripts/genksyms/keywords.gperf"
+#line 31 "scripts/genksyms/keywords.gperf"
{"auto", AUTO_KEYW},
-#line 15 "scripts/genksyms/keywords.gperf"
- {"__inline__", INLINE_KEYW},
-#line 42 "scripts/genksyms/keywords.gperf"
- {"signed", SIGNED_KEYW},
- {""},
#line 47 "scripts/genksyms/keywords.gperf"
+ {"union", UNION_KEYW},
+ {""}, {""},
+#line 48 "scripts/genksyms/keywords.gperf"
{"unsigned", UNSIGNED_KEYW},
- {""},
-#line 41 "scripts/genksyms/keywords.gperf"
+#line 49 "scripts/genksyms/keywords.gperf"
+ {"void", VOID_KEYW},
+#line 42 "scripts/genksyms/keywords.gperf"
{"short", SHORT_KEYW},
+ {""}, {""},
#line 50 "scripts/genksyms/keywords.gperf"
- {"typeof", TYPEOF_KEYW},
-#line 45 "scripts/genksyms/keywords.gperf"
- {"typedef", TYPEDEF_KEYW},
-#line 49 "scripts/genksyms/keywords.gperf"
{"volatile", VOLATILE_KEYW},
{""},
-#line 36 "scripts/genksyms/keywords.gperf"
- {"float", FLOAT_KEYW},
- {""}, {""},
-#line 40 "scripts/genksyms/keywords.gperf"
- {"register", REGISTER_KEYW},
-#line 48 "scripts/genksyms/keywords.gperf"
- {"void", VOID_KEYW},
- {""},
#line 37 "scripts/genksyms/keywords.gperf"
- {"inline", INLINE_KEYW},
+ {"float", FLOAT_KEYW},
+#line 34 "scripts/genksyms/keywords.gperf"
+ {"double", DOUBLE_KEYW},
{""},
#line 5 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
- {""},
-#line 21 "scripts/genksyms/keywords.gperf"
- {"_Bool", BOOL_KEYW},
- {""},
+ {""}, {""},
+#line 38 "scripts/genksyms/keywords.gperf"
+ {"inline", INLINE_KEYW},
#line 6 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
- {""}, {""}, {""}, {""}, {""}, {""},
-#line 39 "scripts/genksyms/keywords.gperf"
- {"long", LONG_KEYW},
- {""}, {""}, {""}, {""}, {""},
-#line 46 "scripts/genksyms/keywords.gperf"
- {"union", UNION_KEYW}
+#line 41 "scripts/genksyms/keywords.gperf"
+ {"register", REGISTER_KEYW},
+ {""},
+#line 22 "scripts/genksyms/keywords.gperf"
+ {"_Bool", BOOL_KEYW},
+#line 43 "scripts/genksyms/keywords.gperf"
+ {"signed", SIGNED_KEYW},
+ {""}, {""},
+#line 40 "scripts/genksyms/keywords.gperf"
+ {"long", LONG_KEYW}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
index c75e0c8d8f0..5ef3733225f 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -11,6 +11,7 @@ __attribute, ATTRIBUTE_KEYW
__attribute__, ATTRIBUTE_KEYW
__const, CONST_KEYW
__const__, CONST_KEYW
+__extension__, EXTENSION_KEYW
__inline, INLINE_KEYW
__inline__, INLINE_KEYW
__signed, SIGNED_KEYW
diff --git a/scripts/genksyms/lex.c_shipped b/scripts/genksyms/lex.c_shipped
index 37ba98241b9..2a176988d46 100644
--- a/scripts/genksyms/lex.c_shipped
+++ b/scripts/genksyms/lex.c_shipped
@@ -1,32 +1,114 @@
#line 2 "scripts/genksyms/lex.c"
-/* A lexical scanner generated by flex */
-/* Scanner skeleton version:
- * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
- */
+#line 4 "scripts/genksyms/lex.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* %if-c++-only */
+/* %endif */
+/* %if-c-only */
+
+/* %endif */
+
+/* %if-c-only */
+
+/* %endif */
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+/* %if-c-only */
#include <stdio.h>
-#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+/* %endif */
+/* %if-tables-serialization */
+/* %endif */
+/* end standard C headers. */
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
+/* %if-c-or-c++ */
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
+/* %endif */
-#include <stdlib.h>
+/* %if-c++-only */
+/* %endif */
-/* Use prototypes in function declarations. */
-#define YY_USE_PROTOS
+#ifdef __cplusplus
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
@@ -35,36 +117,24 @@
#if __STDC__
-#define YY_USE_PROTOS
#define YY_USE_CONST
#endif /* __STDC__ */
#endif /* ! __cplusplus */
-#ifdef __TURBOC__
- #pragma warn -rch
- #pragma warn -use
-#include <io.h>
-#include <stdlib.h>
-#define YY_USE_CONST
-#define YY_USE_PROTOS
-#endif
-
#ifdef YY_USE_CONST
#define yyconst const
#else
#define yyconst
#endif
-
-#ifdef YY_USE_PROTOS
-#define YY_PROTO(proto) proto
-#else
-#define YY_PROTO(proto) ()
-#endif
+/* %not-for-header */
/* Returned upon end-of-file. */
#define YY_NULL 0
+/* %ok-for-header */
+
+/* %not-for-header */
/* Promotes a possibly negative, possibly signed char to an unsigned
* integer for use as an array index. If the signed char is negative,
@@ -72,79 +142,102 @@
* double cast.
*/
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+/* %ok-for-header */
+
+/* %if-reentrant */
+/* %endif */
+
+/* %if-not-reentrant */
+
+/* %endif */
/* Enter a start condition. This macro really ought to take a parameter,
* but we do it the disgusting crufty way forced on us by the ()-less
* definition of BEGIN.
*/
-#define BEGIN yy_start = 1 + 2 *
+#define BEGIN (yy_start) = 1 + 2 *
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
-#define YY_START ((yy_start - 1) / 2)
+#define YY_START (((yy_start) - 1) / 2)
#define YYSTATE YY_START
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin )
+#define YY_NEW_FILE yyrestart(yyin )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
#define YY_BUF_SIZE 16384
+#endif
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+/* %if-not-reentrant */
extern int yyleng;
+/* %endif */
+
+/* %if-c-only */
+/* %if-not-reentrant */
extern FILE *yyin, *yyout;
+/* %endif */
+/* %endif */
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-/* The funky do-while in the following #define is used to turn the definition
- * int a single C statement (which needs a semi-colon terminator). This
- * avoids problems with code like:
- *
- * if ( condition_holds )
- * yyless( 5 );
- * else
- * do_something_else();
- *
- * Prior to using the do-while the compiler would get upset at the
- * "else" because it interpreted the "if" statement as being all
- * done when it reached the ';' after the yyless() call.
- */
-
-/* Return all but the first 'n' matched characters back to the input stream. */
-
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
do \
{ \
/* Undo effects of setting up yytext. */ \
- *yy_cp = yy_hold_char; \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
YY_RESTORE_YY_MORE_OFFSET \
- yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-#define unput(c) yyunput( c, yytext_ptr )
+#define unput(c) yyunput( c, (yytext_ptr) )
/* The following is because we cannot portably get our hands on size_t
* (without autoconf's help, which isn't available because we want
* flex-generated scanners to compile on their own).
*/
-typedef unsigned int yy_size_t;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
+/* %if-c-only */
FILE *yy_input_file;
+/* %endif */
+
+/* %if-c++-only */
+/* %endif */
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
@@ -178,12 +271,16 @@ struct yy_buffer_state
*/
int yy_at_bol;
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
+
#define YY_BUFFER_NEW 0
#define YY_BUFFER_NORMAL 1
/* When an EOF's been seen but there's still some text to process
@@ -197,102 +294,163 @@ struct yy_buffer_state
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
+
};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
-static YY_BUFFER_STATE yy_current_buffer = 0;
+/* %if-not-reentrant */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+/* %endif */
+/* %ok-for-header */
+
+/* %endif */
/* We provide macros for accessing buffer states in case in the
* future we want to put the buffer states in a more general
* "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
*/
-#define YY_CURRENT_BUFFER yy_current_buffer
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* %if-c-only Standard (non-C++) definition */
+
+/* %if-not-reentrant */
+/* %not-for-header */
/* yy_hold_char holds the character lost when yytext is formed. */
static char yy_hold_char;
-
static int yy_n_chars; /* number of characters read into yy_ch_buf */
-
-
int yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
+static int yy_init = 0; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
/* Flag which is used to allow yywrap()'s to do buffer switches
* instead of setting up a fresh yyin. A bit of a hack ...
*/
static int yy_did_buffer_switch_on_eof;
+/* %ok-for-header */
+
+/* %endif */
-void yyrestart YY_PROTO(( FILE *input_file ));
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
-void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
-void yy_load_buffer_state YY_PROTO(( void ));
-YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
-void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
-void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
-YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
-YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
-YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
-static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
-static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
-static void yy_flex_free YY_PROTO(( void * ));
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+/* %endif */
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
#define yy_new_buffer yy_create_buffer
#define yy_set_interactive(is_interactive) \
{ \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_is_interactive = is_interactive; \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
#define yy_set_bol(at_bol) \
{ \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_at_bol = at_bol; \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */
+/* Begin user sect3 */
#define yywrap() 1
#define YY_SKIP_YYWRAP
#define FLEX_DEBUG
+
typedef unsigned char YY_CHAR;
+
FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
typedef int yy_state_type;
-#define FLEX_DEBUG
+extern int yylineno;
+
+int yylineno = 1;
+
extern char *yytext;
#define yytext_ptr yytext
-static yy_state_type yy_get_previous_state YY_PROTO(( void ));
-static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
-static int yy_get_next_buffer YY_PROTO(( void ));
-static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+/* %if-c-only Standard (non-C++) definition */
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* %endif */
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
- yytext_ptr = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
- yy_hold_char = *yy_cp; \
+ (yytext_ptr) = yy_bp; \
+/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
- yy_c_buf_p = yy_cp;
+/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
+ (yy_c_buf_p) = yy_cp;
+/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
#define YY_NUM_RULES 13
#define YY_END_OF_BUFFER 14
-static yyconst short int yy_accept[76] =
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[76] =
{ 0,
0, 0, 0, 0, 14, 12, 4, 3, 12, 7,
12, 12, 7, 12, 12, 12, 12, 12, 9, 9,
@@ -304,7 +462,7 @@ static yyconst short int yy_accept[76] =
0, 0, 0, 1, 0
} ;
-static yyconst int yy_ec[256] =
+static yyconst flex_int32_t yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
@@ -336,14 +494,14 @@ static yyconst int yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst int yy_meta[29] =
+static yyconst flex_int32_t yy_meta[29] =
{ 0,
1, 1, 2, 1, 1, 1, 3, 1, 1, 1,
4, 4, 5, 6, 6, 6, 1, 1, 1, 7,
8, 7, 3, 3, 3, 1, 3, 1
} ;
-static yyconst short int yy_base[88] =
+static yyconst flex_int16_t yy_base[88] =
{ 0,
0, 147, 21, 140, 145, 284, 39, 284, 26, 0,
32, 126, 40, 44, 115, 35, 36, 46, 50, 53,
@@ -356,7 +514,7 @@ static yyconst short int yy_base[88] =
246, 250, 255, 256, 261, 267, 275
} ;
-static yyconst short int yy_def[88] =
+static yyconst flex_int16_t yy_def[88] =
{ 0,
75, 1, 1, 3, 75, 75, 75, 75, 76, 77,
78, 75, 77, 79, 75, 75, 75, 75, 75, 19,
@@ -369,7 +527,7 @@ static yyconst short int yy_def[88] =
75, 75, 75, 75, 75, 75, 75
} ;
-static yyconst short int yy_nxt[313] =
+static yyconst flex_int16_t yy_nxt[313] =
{ 0,
6, 7, 8, 7, 9, 6, 10, 6, 6, 11,
6, 6, 12, 6, 6, 6, 6, 6, 6, 10,
@@ -408,7 +566,7 @@ static yyconst short int yy_nxt[313] =
75, 75
} ;
-static yyconst short int yy_chk[313] =
+static yyconst flex_int16_t yy_chk[313] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -453,7 +611,7 @@ static char *yy_last_accepting_cpos;
extern int yy_flex_debug;
int yy_flex_debug = 1;
-static yyconst short int yy_rule_linenum[13] =
+static yyconst flex_int16_t yy_rule_linenum[13] =
{ 0,
69, 70, 71, 74, 77, 78, 79, 85, 86, 87,
89, 92
@@ -468,7 +626,6 @@ static yyconst short int yy_rule_linenum[13] =
#define YY_RESTORE_YY_MORE_OFFSET
char *yytext;
#line 1 "scripts/genksyms/lex.l"
-#define INITIAL 0
/* Lexical analysis for genksyms.
Copyright 1996, 1997 Linux International.
@@ -506,10 +663,41 @@ char *yytext;
/* Version 2 checksumming does proper tokenization; version 1 wasn't
quite so pedantic. */
-#define V2_TOKENS 1
/* We don't do multiple input files. */
-#line 513 "scripts/genksyms/lex.c"
+#line 669 "scripts/genksyms/lex.c"
+
+#define INITIAL 0
+#define V2_TOKENS 1
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+/* %if-c-only */
+#include <unistd.h>
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* %if-c-only Reentrant structure and macros (non-C++). */
+/* %if-reentrant */
+/* %if-c-only */
+
+static int yy_init_globals (void );
+
+/* %endif */
+/* %if-reentrant */
+/* %endif */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif End reentrant structures and macros. */
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -517,66 +705,45 @@ char *yytext;
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int yywrap YY_PROTO(( void ));
+extern "C" int yywrap (void );
#else
-extern int yywrap YY_PROTO(( void ));
+extern int yywrap (void );
#endif
#endif
-#ifndef YY_NO_UNPUT
-static void yyunput YY_PROTO(( int c, char *buf_ptr ));
-#endif
+/* %not-for-header */
+
+ static void yyunput (int c,char *buf_ptr );
+
+/* %ok-for-header */
+
+/* %endif */
#ifndef yytext_ptr
-static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+static void yy_flex_strncpy (char *,yyconst char *,int );
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+static int yy_flex_strlen (yyconst char * );
#endif
#ifndef YY_NO_INPUT
+/* %if-c-only Standard (non-C++) definition */
+/* %not-for-header */
+
#ifdef __cplusplus
-static int yyinput YY_PROTO(( void ));
+static int yyinput (void );
#else
-static int input YY_PROTO(( void ));
-#endif
+static int input (void );
#endif
+/* %ok-for-header */
-#if YY_STACK_USED
-static int yy_start_stack_ptr = 0;
-static int yy_start_stack_depth = 0;
-static int *yy_start_stack = 0;
-#ifndef YY_NO_PUSH_STATE
-static void yy_push_state YY_PROTO(( int new_state ));
-#endif
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state YY_PROTO(( void ));
-#endif
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state YY_PROTO(( void ));
+/* %endif */
#endif
-#else
-#define YY_NO_PUSH_STATE 1
-#define YY_NO_POP_STATE 1
-#define YY_NO_TOP_STATE 1
-#endif
+/* %if-c-only */
-#ifdef YY_MALLOC_DECL
-YY_MALLOC_DECL
-#else
-#if __STDC__
-#ifndef __cplusplus
-#include <stdlib.h>
-#endif
-#else
-/* Just try to get by without declaring the routines. This will fail
- * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
- * or sizeof(void*) != sizeof(int).
- */
-#endif
-#endif
+/* %endif */
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
@@ -584,12 +751,15 @@ YY_MALLOC_DECL
#endif
/* Copy whatever the last rule matched to the standard output. */
-
#ifndef ECHO
+/* %if-c-only Standard (non-C++) definition */
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -597,9 +767,11 @@ YY_MALLOC_DECL
*/
#ifndef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
- if ( yy_current_buffer->yy_is_interactive ) \
+/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
- int c = '*', n; \
+ int c = '*'; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -609,9 +781,24 @@ YY_MALLOC_DECL
YY_FATAL_ERROR( "input in flex scanner failed" ); \
result = n; \
} \
- else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
- && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" );
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+/* %if-c++-only C++ definition \ */\
+/* %endif */
+
#endif
/* No semi-colon after return; correct usage is to write "yyterminate();" -
@@ -629,15 +816,40 @@ YY_MALLOC_DECL
/* Report a fatal error. */
#ifndef YY_FATAL_ERROR
+/* %if-c-only */
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
#endif
+/* %if-tables-serialization structures and prototypes */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %not-for-header */
+
+/* %tables-yydmap generated elements */
+/* %endif */
+/* end tables serialization structures and prototypes */
+
+/* %ok-for-header */
+
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
-#define YY_DECL int yylex YY_PROTO(( void ))
-#endif
+#define YY_DECL_IS_OURS 1
+/* %if-c-only Standard (non-C++) definition */
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+/* %endif */
+/* %if-c++-only C++ definition */
+/* %endif */
+#endif /* !YY_DECL */
/* Code executed at the beginning of each rule, after yytext and yyleng
* have been set up.
@@ -651,62 +863,80 @@ YY_MALLOC_DECL
#define YY_BREAK break;
#endif
+/* %% [6.0] YY_RULE_SETUP definition goes here */
#define YY_RULE_SETUP \
if ( yyleng > 0 ) \
- yy_current_buffer->yy_at_bol = \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
(yytext[yyleng - 1] == '\n'); \
YY_USER_ACTION
+/* %not-for-header */
+
+/** The main scanner function which does all the work.
+ */
YY_DECL
- {
+{
register yy_state_type yy_current_state;
- register char *yy_cp = NULL, *yy_bp = NULL;
+ register char *yy_cp, *yy_bp;
register int yy_act;
-
+
+/* %% [7.0] user's declarations go here */
#line 65 "scripts/genksyms/lex.l"
/* Keep track of our location in the original source files. */
-#line 672 "scripts/genksyms/lex.c"
+#line 890 "scripts/genksyms/lex.c"
- if ( yy_init )
+ if ( !(yy_init) )
{
- yy_init = 0;
+ (yy_init) = 1;
#ifdef YY_USER_INIT
YY_USER_INIT;
#endif
- if ( ! yy_start )
- yy_start = 1; /* first start state */
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
if ( ! yyin )
+/* %if-c-only */
yyin = stdin;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
if ( ! yyout )
+/* %if-c-only */
yyout = stdout;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
- if ( ! yy_current_buffer )
- yy_current_buffer =
- yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_load_buffer_state();
+ yy_load_buffer_state( );
}
while ( 1 ) /* loops until end-of-file is reached */
{
- yy_cp = yy_c_buf_p;
+/* %% [8.0] yymore()-related code goes here */
+ yy_cp = (yy_c_buf_p);
/* Support of yytext. */
- *yy_cp = yy_hold_char;
+ *yy_cp = (yy_hold_char);
/* yy_bp points to the position in yy_ch_buf of the start of
* the current run.
*/
yy_bp = yy_cp;
- yy_current_state = yy_start;
+/* %% [9.0] code to set up and find next match goes here */
+ yy_current_state = (yy_start);
yy_current_state += YY_AT_BOL();
yy_match:
do
@@ -714,8 +944,8 @@ yy_match:
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
if ( yy_accept[yy_current_state] )
{
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
@@ -729,26 +959,29 @@ yy_match:
while ( yy_base[yy_current_state] != 284 );
yy_find_action:
+/* %% [10.0] code to find the action number goes here */
yy_act = yy_accept[yy_current_state];
if ( yy_act == 0 )
{ /* have to back up */
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
yy_act = yy_accept[yy_current_state];
}
YY_DO_BEFORE_ACTION;
+/* %% [11.0] code for yylineno update goes here */
do_action: /* This label is used only to access EOF actions. */
+/* %% [12.0] debug code goes here */
if ( yy_flex_debug )
{
if ( yy_act == 0 )
fprintf( stderr, "--scanner backing up\n" );
else if ( yy_act < 13 )
- fprintf( stderr, "--accepting rule at line %d (\"%s\")\n",
- yy_rule_linenum[yy_act], yytext );
+ fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
+ (long)yy_rule_linenum[yy_act], yytext );
else if ( yy_act == 13 )
fprintf( stderr, "--accepting default rule (\"%s\")\n",
yytext );
@@ -760,24 +993,28 @@ do_action: /* This label is used only to access EOF actions. */
switch ( yy_act )
{ /* beginning of action switch */
+/* %% [13.0] actions go here */
case 0: /* must back up */
/* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yy_hold_char;
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
goto yy_find_action;
case 1:
+/* rule 1 can match eol */
YY_RULE_SETUP
#line 69 "scripts/genksyms/lex.l"
return FILENAME;
YY_BREAK
case 2:
+/* rule 2 can match eol */
YY_RULE_SETUP
#line 70 "scripts/genksyms/lex.l"
cur_line++;
YY_BREAK
case 3:
+/* rule 3 can match eol */
YY_RULE_SETUP
#line 71 "scripts/genksyms/lex.l"
cur_line++;
@@ -789,11 +1026,13 @@ YY_RULE_SETUP
;
YY_BREAK
case 5:
+/* rule 5 can match eol */
YY_RULE_SETUP
#line 77 "scripts/genksyms/lex.l"
return STRING;
YY_BREAK
case 6:
+/* rule 6 can match eol */
YY_RULE_SETUP
#line 78 "scripts/genksyms/lex.l"
return CHAR;
@@ -838,7 +1077,7 @@ YY_RULE_SETUP
#line 95 "scripts/genksyms/lex.l"
ECHO;
YY_BREAK
-#line 842 "scripts/genksyms/lex.c"
+#line 1081 "scripts/genksyms/lex.c"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(V2_TOKENS):
yyterminate();
@@ -846,26 +1085,26 @@ case YY_STATE_EOF(V2_TOKENS):
case YY_END_OF_BUFFER:
{
/* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
/* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yy_hold_char;
+ *yy_cp = (yy_hold_char);
YY_RESTORE_YY_MORE_OFFSET
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
{
/* We're scanning a new file or input source. It's
* possible that this happened because the user
* just pointed yyin at a new source and called
* yylex(). If so, then we have to assure
- * consistency between yy_current_buffer and our
+ * consistency between YY_CURRENT_BUFFER and our
* globals. Here is the right place to do so, because
* this is the first action (other than possibly a
* back-up) that will match for the new input source.
*/
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yy_current_buffer->yy_input_file = yyin;
- yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
}
/* Note that here we test for yy_c_buf_p "<=" to the position
@@ -875,13 +1114,13 @@ case YY_STATE_EOF(V2_TOKENS):
* end-of-buffer state). Contrast this with the test
* in input().
*/
- if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
{ /* This was really a NUL. */
yy_state_type yy_next_state;
- yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
- yy_current_state = yy_get_previous_state();
+ yy_current_state = yy_get_previous_state( );
/* Okay, we're now positioned to make the NUL
* transition. We couldn't have
@@ -894,30 +1133,31 @@ case YY_STATE_EOF(V2_TOKENS):
yy_next_state = yy_try_NUL_trans( yy_current_state );
- yy_bp = yytext_ptr + YY_MORE_ADJ;
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
if ( yy_next_state )
{
/* Consume the NUL. */
- yy_cp = ++yy_c_buf_p;
+ yy_cp = ++(yy_c_buf_p);
yy_current_state = yy_next_state;
goto yy_match;
}
else
{
- yy_cp = yy_c_buf_p;
+/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */
+ yy_cp = (yy_c_buf_p);
goto yy_find_action;
}
}
- else switch ( yy_get_next_buffer() )
+ else switch ( yy_get_next_buffer( ) )
{
case EOB_ACT_END_OF_FILE:
{
- yy_did_buffer_switch_on_eof = 0;
+ (yy_did_buffer_switch_on_eof) = 0;
- if ( yywrap() )
+ if ( yywrap( ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -928,7 +1168,7 @@ case YY_STATE_EOF(V2_TOKENS):
* YY_NULL, it'll still work - another
* YY_NULL will get returned.
*/
- yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
yy_act = YY_STATE_EOF(YY_START);
goto do_action;
@@ -936,30 +1176,30 @@ case YY_STATE_EOF(V2_TOKENS):
else
{
- if ( ! yy_did_buffer_switch_on_eof )
+ if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE;
}
break;
}
case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p =
- yytext_ptr + yy_amount_of_matched_text;
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
- yy_current_state = yy_get_previous_state();
+ yy_current_state = yy_get_previous_state( );
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
goto yy_match;
case EOB_ACT_LAST_MATCH:
- yy_c_buf_p =
- &yy_current_buffer->yy_ch_buf[yy_n_chars];
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
- yy_current_state = yy_get_previous_state();
+ yy_current_state = yy_get_previous_state( );
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
goto yy_find_action;
}
break;
@@ -970,8 +1210,15 @@ case YY_STATE_EOF(V2_TOKENS):
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
- } /* end of yylex */
+} /* end of yylex */
+/* %ok-for-header */
+/* %if-c++-only */
+/* %not-for-header */
+
+/* %ok-for-header */
+
+/* %endif */
/* yy_get_next_buffer - try to read in a new buffer
*
@@ -980,21 +1227,24 @@ case YY_STATE_EOF(V2_TOKENS):
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position
* EOB_ACT_END_OF_FILE - end of file
*/
-
-static int yy_get_next_buffer()
- {
- register char *dest = yy_current_buffer->yy_ch_buf;
- register char *source = yytext_ptr;
+/* %if-c-only */
+static int yy_get_next_buffer (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
register int number_to_move, i;
int ret_val;
- if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
YY_FATAL_ERROR(
"fatal flex scanner internal error--end of buffer missed" );
- if ( yy_current_buffer->yy_fill_buffer == 0 )
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
{ /* Don't try to fill the buffer, so this is an EOF. */
- if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
{
/* We matched a single character, the EOB, so
* treat this as a final EOF.
@@ -1014,34 +1264,30 @@ static int yy_get_next_buffer()
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
/* don't do the read, it's not guaranteed to return an EOF,
* just force an EOF
*/
- yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
else
{
- int num_to_read =
- yy_current_buffer->yy_buf_size - number_to_move - 1;
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
{ /* Not enough room in the buffer - grow it. */
-#ifdef YY_USES_REJECT
- YY_FATAL_ERROR(
-"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-#else
/* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = yy_current_buffer;
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
int yy_c_buf_p_offset =
- (int) (yy_c_buf_p - b->yy_ch_buf);
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
if ( b->yy_is_our_buffer )
{
@@ -1054,8 +1300,7 @@ static int yy_get_next_buffer()
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- yy_flex_realloc( (void *) b->yy_ch_buf,
- b->yy_buf_size + 2 );
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
}
else
/* Can't grow it, we don't own it. */
@@ -1065,35 +1310,35 @@ static int yy_get_next_buffer()
YY_FATAL_ERROR(
"fatal error - scanner input buffer overflow" );
- yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
- num_to_read = yy_current_buffer->yy_buf_size -
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
number_to_move - 1;
-#endif
+
}
if ( num_to_read > YY_READ_BUF_SIZE )
num_to_read = YY_READ_BUF_SIZE;
/* Read in more data. */
- YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
- yy_n_chars, num_to_read );
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
- yy_current_buffer->yy_n_chars = yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
- if ( yy_n_chars == 0 )
+ if ( (yy_n_chars) == 0 )
{
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- yyrestart( yyin );
+ yyrestart(yyin );
}
else
{
ret_val = EOB_ACT_LAST_MATCH;
- yy_current_buffer->yy_buffer_status =
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
YY_BUFFER_EOF_PENDING;
}
}
@@ -1101,33 +1346,40 @@ static int yy_get_next_buffer()
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- yy_n_chars += number_to_move;
- yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
- yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
return ret_val;
- }
-
+}
/* yy_get_previous_state - get the state just before the EOB char was reached */
-static yy_state_type yy_get_previous_state()
- {
+/* %if-c-only */
+/* %not-for-header */
+
+ static yy_state_type yy_get_previous_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
register yy_state_type yy_current_state;
register char *yy_cp;
-
- yy_current_state = yy_start;
+
+/* %% [15.0] code to get the start state into yy_current_state goes here */
+ yy_current_state = (yy_start);
yy_current_state += YY_AT_BOL();
- for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
{
+/* %% [16.0] code to find the next state goes here */
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
@@ -1139,30 +1391,28 @@ static yy_state_type yy_get_previous_state()
}
return yy_current_state;
- }
-
+}
/* yy_try_NUL_trans - try to make a transition on the NUL character
*
* synopsis
* next_state = yy_try_NUL_trans( current_state );
*/
-
-#ifdef YY_USE_PROTOS
-static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
-#else
-static yy_state_type yy_try_NUL_trans( yy_current_state )
-yy_state_type yy_current_state;
-#endif
- {
+/* %if-c-only */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
register int yy_is_jam;
- register char *yy_cp = yy_c_buf_p;
+ /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */
+ register char *yy_cp = (yy_c_buf_p);
register YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
}
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
@@ -1174,80 +1424,87 @@ yy_state_type yy_current_state;
yy_is_jam = (yy_current_state == 75);
return yy_is_jam ? 0 : yy_current_state;
- }
+}
+/* %if-c-only */
-#ifndef YY_NO_UNPUT
-#ifdef YY_USE_PROTOS
-static void yyunput( int c, register char *yy_bp )
-#else
-static void yyunput( c, yy_bp )
-int c;
-register char *yy_bp;
-#endif
- {
- register char *yy_cp = yy_c_buf_p;
+ static void yyunput (int c, register char * yy_bp )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
/* undo effects of setting up yytext */
- *yy_cp = yy_hold_char;
+ *yy_cp = (yy_hold_char);
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- register int number_to_move = yy_n_chars + 2;
- register char *dest = &yy_current_buffer->yy_ch_buf[
- yy_current_buffer->yy_buf_size + 2];
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
register char *source =
- &yy_current_buffer->yy_ch_buf[number_to_move];
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
- while ( source > yy_current_buffer->yy_ch_buf )
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
*--dest = *--source;
yy_cp += (int) (dest - source);
yy_bp += (int) (dest - source);
- yy_current_buffer->yy_n_chars =
- yy_n_chars = yy_current_buffer->yy_buf_size;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
YY_FATAL_ERROR( "flex scanner push-back overflow" );
}
*--yy_cp = (char) c;
+/* %% [18.0] update yylineno here */
- yytext_ptr = yy_bp;
- yy_hold_char = *yy_cp;
- yy_c_buf_p = yy_cp;
- }
-#endif /* ifndef YY_NO_UNPUT */
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+/* %if-c-only */
+/* %endif */
+/* %if-c-only */
+#ifndef YY_NO_INPUT
#ifdef __cplusplus
-static int yyinput()
+ static int yyinput (void)
#else
-static int input()
+ static int input (void)
#endif
- {
- int c;
- *yy_c_buf_p = yy_hold_char;
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
- if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
{
/* yy_c_buf_p now points to the character we want to return.
* If this occurs *before* the EOB characters, then it's a
* valid NUL; if not, then we've hit the end of the buffer.
*/
- if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
/* This was really a NUL. */
- *yy_c_buf_p = '\0';
+ *(yy_c_buf_p) = '\0';
else
{ /* need more input */
- int offset = yy_c_buf_p - yytext_ptr;
- ++yy_c_buf_p;
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
- switch ( yy_get_next_buffer() )
+ switch ( yy_get_next_buffer( ) )
{
case EOB_ACT_LAST_MATCH:
/* This happens because yy_g_n_b()
@@ -1261,16 +1518,16 @@ static int input()
*/
/* Reset buffer status. */
- yyrestart( yyin );
+ yyrestart(yyin );
- /* fall through */
+ /*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( yywrap() )
+ if ( yywrap( ) )
return EOF;
- if ( ! yy_did_buffer_switch_on_eof )
+ if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE;
#ifdef __cplusplus
return yyinput();
@@ -1280,91 +1537,113 @@ static int input()
}
case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p = yytext_ptr + offset;
+ (yy_c_buf_p) = (yytext_ptr) + offset;
break;
}
}
}
- c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
- *yy_c_buf_p = '\0'; /* preserve yytext */
- yy_hold_char = *++yy_c_buf_p;
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
- yy_current_buffer->yy_at_bol = (c == '\n');
+/* %% [19.0] update BOL and yylineno */
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
return c;
+}
+/* %if-c-only */
+#endif /* ifndef YY_NO_INPUT */
+/* %endif */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+/* %if-c-only */
+ void yyrestart (FILE * input_file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
}
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
-#ifdef YY_USE_PROTOS
-void yyrestart( FILE *input_file )
-#else
-void yyrestart( input_file )
-FILE *input_file;
-#endif
- {
- if ( ! yy_current_buffer )
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_init_buffer( yy_current_buffer, input_file );
- yy_load_buffer_state();
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
-#else
-void yy_switch_to_buffer( new_buffer )
-YY_BUFFER_STATE new_buffer;
-#endif
- {
- if ( yy_current_buffer == new_buffer )
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+/* %if-c-only */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
return;
- if ( yy_current_buffer )
+ if ( YY_CURRENT_BUFFER )
{
/* Flush out information for old buffer. */
- *yy_c_buf_p = yy_hold_char;
- yy_current_buffer->yy_buf_pos = yy_c_buf_p;
- yy_current_buffer->yy_n_chars = yy_n_chars;
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
- yy_current_buffer = new_buffer;
- yy_load_buffer_state();
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
/* We don't actually know whether we did this switch during
* EOF (yywrap()) processing, but the only time this flag
* is looked at is after yywrap() is called, so it's safe
* to go ahead and always set it.
*/
- yy_did_buffer_switch_on_eof = 1;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_load_buffer_state( void )
-#else
-void yy_load_buffer_state()
-#endif
- {
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
- yyin = yy_current_buffer->yy_input_file;
- yy_hold_char = *yy_c_buf_p;
- }
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+/* %if-c-only */
+static void yy_load_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
-#else
-YY_BUFFER_STATE yy_create_buffer( file, size )
-FILE *file;
-int size;
-#endif
- {
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+/* %if-c-only */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
@@ -1373,75 +1652,99 @@ int size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- yy_init_buffer( b, file );
+ yy_init_buffer(b,file );
return b;
- }
-
+}
-#ifdef YY_USE_PROTOS
-void yy_delete_buffer( YY_BUFFER_STATE b )
-#else
-void yy_delete_buffer( b )
-YY_BUFFER_STATE b;
-#endif
- {
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+/* %if-c-only */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
if ( ! b )
return;
- if ( b == yy_current_buffer )
- yy_current_buffer = (YY_BUFFER_STATE) 0;
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- yy_flex_free( (void *) b->yy_ch_buf );
+ yyfree((void *) b->yy_ch_buf );
- yy_flex_free( (void *) b );
- }
+ yyfree((void *) b );
+}
+/* %if-c-only */
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* %endif */
-#ifdef YY_USE_PROTOS
-void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
-#else
-void yy_init_buffer( b, file )
-YY_BUFFER_STATE b;
-FILE *file;
-#endif
+/* %if-c++-only */
+/* %endif */
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+/* %if-c-only */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
- {
- yy_flush_buffer( b );
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
b->yy_input_file = file;
b->yy_fill_buffer = 1;
-#if YY_ALWAYS_INTERACTIVE
- b->yy_is_interactive = 1;
-#else
-#if YY_NEVER_INTERACTIVE
- b->yy_is_interactive = 0;
-#else
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-#endif
-#endif
- }
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+/* %if-c-only */
-#ifdef YY_USE_PROTOS
-void yy_flush_buffer( YY_BUFFER_STATE b )
-#else
-void yy_flush_buffer( b )
-YY_BUFFER_STATE b;
-#endif
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+ errno = oerrno;
+}
- {
- if ( ! b )
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+/* %if-c-only */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if ( ! b )
return;
b->yy_n_chars = 0;
@@ -1458,29 +1761,140 @@ YY_BUFFER_STATE b;
b->yy_at_bol = 1;
b->yy_buffer_status = YY_BUFFER_NEW;
- if ( b == yy_current_buffer )
- yy_load_buffer_state();
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/* %if-c-or-c++ */
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+/* %if-c-only */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+/* %if-c-only */
+void yypop_buffer_state (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
}
+}
+/* %endif */
+/* %if-c-or-c++ */
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+/* %if-c-only */
+static void yyensure_buffer_stack (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
-#ifndef YY_NO_SCAN_BUFFER
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
-#else
-YY_BUFFER_STATE yy_scan_buffer( base, size )
-char *base;
-yy_size_t size;
-#endif
- {
- YY_BUFFER_STATE b;
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
if ( size < 2 ||
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
return 0;
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
@@ -1494,56 +1908,55 @@ yy_size_t size;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- yy_switch_to_buffer( b );
+ yy_switch_to_buffer(b );
return b;
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_STRING
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
-#else
-YY_BUFFER_STATE yy_scan_string( yy_str )
-yyconst char *yy_str;
-#endif
- {
- int len;
- for ( len = 0; yy_str[len]; ++len )
- ;
-
- return yy_scan_bytes( yy_str, len );
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_BYTES
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
-#else
-YY_BUFFER_STATE yy_scan_bytes( bytes, len )
-yyconst char *bytes;
-int len;
-#endif
- {
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+/* %endif */
+
+/* %if-c-only */
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
int i;
-
+
/* Get memory for full buffer, including space for trailing EOB's. */
- n = len + 2;
- buf = (char *) yy_flex_alloc( n );
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
- for ( i = 0; i < len; ++i )
- buf[i] = bytes[i];
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = yy_scan_buffer( buf, n );
+ b = yy_scan_buffer(buf,n );
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
@@ -1553,148 +1966,231 @@ int len;
b->yy_is_our_buffer = 1;
return b;
- }
+}
+/* %endif */
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
#endif
+/* %if-c-only */
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+/* %endif */
+/* %if-c++-only */
+/* %endif */
-#ifndef YY_NO_PUSH_STATE
-#ifdef YY_USE_PROTOS
-static void yy_push_state( int new_state )
-#else
-static void yy_push_state( new_state )
-int new_state;
-#endif
- {
- if ( yy_start_stack_ptr >= yy_start_stack_depth )
- {
- yy_size_t new_size;
+/* Redefine yyless() so it works in section 3 code. */
- yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yy_start_stack_depth * sizeof( int );
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
- if ( ! yy_start_stack )
- yy_start_stack = (int *) yy_flex_alloc( new_size );
+/* Accessor methods (get/set functions) to struct members. */
- else
- yy_start_stack = (int *) yy_flex_realloc(
- (void *) yy_start_stack, new_size );
+/* %if-c-only */
+/* %if-reentrant */
+/* %endif */
- if ( ! yy_start_stack )
- YY_FATAL_ERROR(
- "out of memory expanding start-condition stack" );
- }
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
- yy_start_stack[yy_start_stack_ptr++] = YY_START;
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
- BEGIN(new_state);
- }
-#endif
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state()
- {
- if ( --yy_start_stack_ptr < 0 )
- YY_FATAL_ERROR( "start-condition stack underflow" );
+/** Get the current token.
+ *
+ */
- BEGIN(yy_start_stack[yy_start_stack_ptr]);
- }
-#endif
+char *yyget_text (void)
+{
+ return yytext;
+}
+/* %if-reentrant */
+/* %endif */
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state()
- {
- return yy_start_stack[yy_start_stack_ptr - 1];
- }
-#endif
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
-#ifdef YY_USE_PROTOS
-static void yy_fatal_error( yyconst char msg[] )
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+/* %endif */
+
+/* %if-reentrant */
+/* %if-bison-bridge */
+/* %endif */
+/* %endif */
+
+/* %if-c-only */
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
#else
-static void yy_fatal_error( msg )
-char msg[];
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
#endif
- {
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+/* %endif */
+
+/* %if-c-or-c++ */
+/* %if-c-only */
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+/* %endif */
+/* %if-c++-only */
+/* %endif */
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
}
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+/* %if-c++-only */
+/* %endif */
-/* Redefine yyless() so it works in section 3 code. */
+/* %if-c-only */
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- yytext[yyleng] = yy_hold_char; \
- yy_c_buf_p = yytext + n; \
- yy_hold_char = *yy_c_buf_p; \
- *yy_c_buf_p = '\0'; \
- yyleng = n; \
- } \
- while ( 0 )
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+/* %if-reentrant */
+/* %endif */
+ return 0;
+/* %endif */
+}
+/* %endif */
-/* Internal utility routines. */
+/*
+ * Internal utility routines.
+ */
#ifndef yytext_ptr
-#ifdef YY_USE_PROTOS
-static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
-#else
-static void yy_flex_strncpy( s1, s2, n )
-char *s1;
-yyconst char *s2;
-int n;
-#endif
- {
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
register int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
- }
+}
#endif
#ifdef YY_NEED_STRLEN
-#ifdef YY_USE_PROTOS
-static int yy_flex_strlen( yyconst char *s )
-#else
-static int yy_flex_strlen( s )
-yyconst char *s;
-#endif
- {
+static int yy_flex_strlen (yyconst char * s )
+{
register int n;
for ( n = 0; s[n]; ++n )
;
return n;
- }
+}
#endif
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_alloc( yy_size_t size )
-#else
-static void *yy_flex_alloc( size )
-yy_size_t size;
-#endif
- {
+void *yyalloc (yy_size_t size )
+{
return (void *) malloc( size );
- }
+}
-#ifdef YY_USE_PROTOS
-static void *yy_flex_realloc( void *ptr, yy_size_t size )
-#else
-static void *yy_flex_realloc( ptr, size )
-void *ptr;
-yy_size_t size;
-#endif
- {
+void *yyrealloc (void * ptr, yy_size_t size )
+{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
@@ -1703,28 +2199,24 @@ yy_size_t size;
* as though doing an assignment.
*/
return (void *) realloc( (char *) ptr, size );
- }
+}
-#ifdef YY_USE_PROTOS
-static void yy_flex_free( void *ptr )
-#else
-static void yy_flex_free( ptr )
-void *ptr;
-#endif
- {
- free( ptr );
- }
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+/* %if-tables-serialization definitions */
+/* %define-yytables The name for this specific scanner's tables. */
+#define YYTABLES_NAME "yytables"
+/* %endif */
+
+/* %ok-for-header */
-#if YY_MAIN
-int main()
- {
- yylex();
- return 0;
- }
-#endif
#line 95 "scripts/genksyms/lex.l"
+
/* Bring in the keyword recognizer. */
#include "keywords.c"
@@ -2036,10 +2528,12 @@ fini:
return token;
}
-/* A Bison parser, made by GNU Bison 2.0. */
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, 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
@@ -2053,13 +2547,21 @@ fini:
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. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -2076,39 +2578,41 @@ fini:
DOUBLE_KEYW = 264,
ENUM_KEYW = 265,
EXTERN_KEYW = 266,
- FLOAT_KEYW = 267,
- INLINE_KEYW = 268,
- INT_KEYW = 269,
- LONG_KEYW = 270,
- REGISTER_KEYW = 271,
- RESTRICT_KEYW = 272,
- SHORT_KEYW = 273,
- SIGNED_KEYW = 274,
- STATIC_KEYW = 275,
- STRUCT_KEYW = 276,
- TYPEDEF_KEYW = 277,
- UNION_KEYW = 278,
- UNSIGNED_KEYW = 279,
- VOID_KEYW = 280,
- VOLATILE_KEYW = 281,
- TYPEOF_KEYW = 282,
- EXPORT_SYMBOL_KEYW = 283,
- ASM_PHRASE = 284,
- ATTRIBUTE_PHRASE = 285,
- BRACE_PHRASE = 286,
- BRACKET_PHRASE = 287,
- EXPRESSION_PHRASE = 288,
- CHAR = 289,
- DOTS = 290,
- IDENT = 291,
- INT = 292,
- REAL = 293,
- STRING = 294,
- TYPE = 295,
- OTHER = 296,
- FILENAME = 297
+ EXTENSION_KEYW = 267,
+ FLOAT_KEYW = 268,
+ INLINE_KEYW = 269,
+ INT_KEYW = 270,
+ LONG_KEYW = 271,
+ REGISTER_KEYW = 272,
+ RESTRICT_KEYW = 273,
+ SHORT_KEYW = 274,
+ SIGNED_KEYW = 275,
+ STATIC_KEYW = 276,
+ STRUCT_KEYW = 277,
+ TYPEDEF_KEYW = 278,
+ UNION_KEYW = 279,
+ UNSIGNED_KEYW = 280,
+ VOID_KEYW = 281,
+ VOLATILE_KEYW = 282,
+ TYPEOF_KEYW = 283,
+ EXPORT_SYMBOL_KEYW = 284,
+ ASM_PHRASE = 285,
+ ATTRIBUTE_PHRASE = 286,
+ BRACE_PHRASE = 287,
+ BRACKET_PHRASE = 288,
+ EXPRESSION_PHRASE = 289,
+ CHAR = 290,
+ DOTS = 291,
+ IDENT = 292,
+ INT = 293,
+ REAL = 294,
+ STRING = 295,
+ TYPE = 296,
+ OTHER = 297,
+ FILENAME = 298
};
#endif
+/* Tokens. */
#define ASM_KEYW 258
#define ATTRIBUTE_KEYW 259
#define AUTO_KEYW 260
@@ -2118,42 +2622,43 @@ fini:
#define DOUBLE_KEYW 264
#define ENUM_KEYW 265
#define EXTERN_KEYW 266
-#define FLOAT_KEYW 267
-#define INLINE_KEYW 268
-#define INT_KEYW 269
-#define LONG_KEYW 270
-#define REGISTER_KEYW 271
-#define RESTRICT_KEYW 272
-#define SHORT_KEYW 273
-#define SIGNED_KEYW 274
-#define STATIC_KEYW 275
-#define STRUCT_KEYW 276
-#define TYPEDEF_KEYW 277
-#define UNION_KEYW 278
-#define UNSIGNED_KEYW 279
-#define VOID_KEYW 280
-#define VOLATILE_KEYW 281
-#define TYPEOF_KEYW 282
-#define EXPORT_SYMBOL_KEYW 283
-#define ASM_PHRASE 284
-#define ATTRIBUTE_PHRASE 285
-#define BRACE_PHRASE 286
-#define BRACKET_PHRASE 287
-#define EXPRESSION_PHRASE 288
-#define CHAR 289
-#define DOTS 290
-#define IDENT 291
-#define INT 292
-#define REAL 293
-#define STRING 294
-#define TYPE 295
-#define OTHER 296
-#define FILENAME 297
-
-
-
-
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#define EXTENSION_KEYW 267
+#define FLOAT_KEYW 268
+#define INLINE_KEYW 269
+#define INT_KEYW 270
+#define LONG_KEYW 271
+#define REGISTER_KEYW 272
+#define RESTRICT_KEYW 273
+#define SHORT_KEYW 274
+#define SIGNED_KEYW 275
+#define STATIC_KEYW 276
+#define STRUCT_KEYW 277
+#define TYPEDEF_KEYW 278
+#define UNION_KEYW 279
+#define UNSIGNED_KEYW 280
+#define VOID_KEYW 281
+#define VOLATILE_KEYW 282
+#define TYPEOF_KEYW 283
+#define EXPORT_SYMBOL_KEYW 284
+#define ASM_PHRASE 285
+#define ATTRIBUTE_PHRASE 286
+#define BRACE_PHRASE 287
+#define BRACKET_PHRASE 288
+#define EXPRESSION_PHRASE 289
+#define CHAR 290
+#define DOTS 291
+#define IDENT 292
+#define INT 293
+#define REAL 294
+#define STRING 295
+#define TYPE 296
+#define OTHER 297
+#define FILENAME 298
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -2163,4 +2668,3 @@ typedef int YYSTYPE;
extern YYSTYPE yylval;
-
diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped
index 99d7c258696..3e6079f36b9 100644
--- a/scripts/genksyms/parse.c_shipped
+++ b/scripts/genksyms/parse.c_shipped
@@ -1,7 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.0. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, 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
@@ -15,16 +17,24 @@
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. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
-/* Written by Richard Stallman by simplifying the original so called
- ``semantic'' parser. */
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
@@ -36,6 +46,9 @@
/* Identify Bison output. */
#define YYBISON 1
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -62,39 +75,41 @@
DOUBLE_KEYW = 264,
ENUM_KEYW = 265,
EXTERN_KEYW = 266,
- FLOAT_KEYW = 267,
- INLINE_KEYW = 268,
- INT_KEYW = 269,
- LONG_KEYW = 270,
- REGISTER_KEYW = 271,
- RESTRICT_KEYW = 272,
- SHORT_KEYW = 273,
- SIGNED_KEYW = 274,
- STATIC_KEYW = 275,
- STRUCT_KEYW = 276,
- TYPEDEF_KEYW = 277,
- UNION_KEYW = 278,
- UNSIGNED_KEYW = 279,
- VOID_KEYW = 280,
- VOLATILE_KEYW = 281,
- TYPEOF_KEYW = 282,
- EXPORT_SYMBOL_KEYW = 283,
- ASM_PHRASE = 284,
- ATTRIBUTE_PHRASE = 285,
- BRACE_PHRASE = 286,
- BRACKET_PHRASE = 287,
- EXPRESSION_PHRASE = 288,
- CHAR = 289,
- DOTS = 290,
- IDENT = 291,
- INT = 292,
- REAL = 293,
- STRING = 294,
- TYPE = 295,
- OTHER = 296,
- FILENAME = 297
+ EXTENSION_KEYW = 267,
+ FLOAT_KEYW = 268,
+ INLINE_KEYW = 269,
+ INT_KEYW = 270,
+ LONG_KEYW = 271,
+ REGISTER_KEYW = 272,
+ RESTRICT_KEYW = 273,
+ SHORT_KEYW = 274,
+ SIGNED_KEYW = 275,
+ STATIC_KEYW = 276,
+ STRUCT_KEYW = 277,
+ TYPEDEF_KEYW = 278,
+ UNION_KEYW = 279,
+ UNSIGNED_KEYW = 280,
+ VOID_KEYW = 281,
+ VOLATILE_KEYW = 282,
+ TYPEOF_KEYW = 283,
+ EXPORT_SYMBOL_KEYW = 284,
+ ASM_PHRASE = 285,
+ ATTRIBUTE_PHRASE = 286,
+ BRACE_PHRASE = 287,
+ BRACKET_PHRASE = 288,
+ EXPRESSION_PHRASE = 289,
+ CHAR = 290,
+ DOTS = 291,
+ IDENT = 292,
+ INT = 293,
+ REAL = 294,
+ STRING = 295,
+ TYPE = 296,
+ OTHER = 297,
+ FILENAME = 298
};
#endif
+/* Tokens. */
#define ASM_KEYW 258
#define ATTRIBUTE_KEYW 259
#define AUTO_KEYW 260
@@ -104,37 +119,38 @@
#define DOUBLE_KEYW 264
#define ENUM_KEYW 265
#define EXTERN_KEYW 266
-#define FLOAT_KEYW 267
-#define INLINE_KEYW 268
-#define INT_KEYW 269
-#define LONG_KEYW 270
-#define REGISTER_KEYW 271
-#define RESTRICT_KEYW 272
-#define SHORT_KEYW 273
-#define SIGNED_KEYW 274
-#define STATIC_KEYW 275
-#define STRUCT_KEYW 276
-#define TYPEDEF_KEYW 277
-#define UNION_KEYW 278
-#define UNSIGNED_KEYW 279
-#define VOID_KEYW 280
-#define VOLATILE_KEYW 281
-#define TYPEOF_KEYW 282
-#define EXPORT_SYMBOL_KEYW 283
-#define ASM_PHRASE 284
-#define ATTRIBUTE_PHRASE 285
-#define BRACE_PHRASE 286
-#define BRACKET_PHRASE 287
-#define EXPRESSION_PHRASE 288
-#define CHAR 289
-#define DOTS 290
-#define IDENT 291
-#define INT 292
-#define REAL 293
-#define STRING 294
-#define TYPE 295
-#define OTHER 296
-#define FILENAME 297
+#define EXTENSION_KEYW 267
+#define FLOAT_KEYW 268
+#define INLINE_KEYW 269
+#define INT_KEYW 270
+#define LONG_KEYW 271
+#define REGISTER_KEYW 272
+#define RESTRICT_KEYW 273
+#define SHORT_KEYW 274
+#define SIGNED_KEYW 275
+#define STATIC_KEYW 276
+#define STRUCT_KEYW 277
+#define TYPEDEF_KEYW 278
+#define UNION_KEYW 279
+#define UNSIGNED_KEYW 280
+#define VOID_KEYW 281
+#define VOLATILE_KEYW 282
+#define TYPEOF_KEYW 283
+#define EXPORT_SYMBOL_KEYW 284
+#define ASM_PHRASE 285
+#define ATTRIBUTE_PHRASE 286
+#define BRACE_PHRASE 287
+#define BRACKET_PHRASE 288
+#define EXPRESSION_PHRASE 289
+#define CHAR 290
+#define DOTS 291
+#define IDENT 292
+#define INT 293
+#define REAL 294
+#define STRING 295
+#define TYPE 296
+#define OTHER 297
+#define FILENAME 298
@@ -185,7 +201,12 @@ remove_list(struct string_list **pb, struct string_list **pe)
# define YYERROR_VERBOSE 0
#endif
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -197,17 +218,94 @@ typedef int YYSTYPE;
/* Copy the second part of user declarations. */
-/* Line 213 of yacc.c. */
-#line 202 "scripts/genksyms/parse.c"
+/* Line 216 of yacc.c. */
+#line 223 "scripts/genksyms/parse.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-# ifndef YYFREE
-# define YYFREE free
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
+# ifndef YY_
+# define YY_(msgid) msgid
# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -215,34 +313,76 @@ typedef int YYSTYPE;
# if YYSTACK_USE_ALLOCA
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
# endif
+# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-#if (! defined (yyoverflow) \
- && (! defined (__cplusplus) \
- || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short int yyss;
+ yytype_int16 yyss;
YYSTYPE yyvs;
};
@@ -252,24 +392,24 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if defined (__GNUC__) && 1 < __GNUC__
+# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
- register YYSIZE_T yyi; \
+ YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
- while (0)
+ while (YYID (0))
# endif
# endif
@@ -287,53 +427,47 @@ union yyalloc
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
- while (0)
+ while (YYID (0))
#endif
-#if defined (__STDC__) || defined (__cplusplus)
- typedef signed char yysigned_char;
-#else
- typedef short int yysigned_char;
-#endif
-
-/* YYFINAL -- State number of the termination state. */
+/* YYFINAL -- State number of the termination state. */
#define YYFINAL 4
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 535
+#define YYLAST 523
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 52
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 45
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 124
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 174
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 53
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 46
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 126
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 178
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 297
+#define YYMAXUTOK 298
-#define YYTRANSLATE(YYX) \
+#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
+static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 46, 48, 47, 2, 45, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 51, 43,
- 2, 49, 2, 2, 2, 2, 2, 2, 2, 2,
+ 47, 49, 48, 2, 46, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 52, 44,
+ 2, 50, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 50, 2, 44, 2, 2, 2, 2,
+ 2, 2, 2, 51, 2, 45, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -350,114 +484,116 @@ static const unsigned char yytranslate[] =
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42
+ 35, 36, 37, 38, 39, 40, 41, 42, 43
};
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned short int yyprhs[] =
+static const yytype_uint16 yyprhs[] =
{
- 0, 0, 3, 5, 8, 9, 12, 13, 17, 19,
- 21, 23, 25, 28, 31, 35, 36, 38, 40, 44,
- 49, 50, 52, 54, 57, 59, 61, 63, 65, 67,
- 69, 71, 73, 75, 81, 86, 89, 92, 95, 99,
- 103, 107, 110, 113, 116, 118, 120, 122, 124, 126,
- 128, 130, 132, 134, 136, 138, 141, 142, 144, 146,
- 149, 151, 153, 155, 157, 160, 162, 164, 169, 174,
- 177, 181, 185, 188, 190, 192, 194, 199, 204, 207,
- 211, 215, 218, 220, 224, 225, 227, 229, 233, 236,
- 239, 241, 242, 244, 246, 251, 256, 259, 263, 267,
- 271, 272, 274, 277, 281, 285, 286, 288, 290, 293,
- 297, 300, 301, 303, 305, 309, 312, 315, 317, 320,
- 321, 323, 326, 327, 329
+ 0, 0, 3, 5, 8, 9, 12, 13, 18, 19,
+ 23, 25, 27, 29, 31, 34, 37, 41, 42, 44,
+ 46, 50, 55, 56, 58, 60, 63, 65, 67, 69,
+ 71, 73, 75, 77, 79, 81, 87, 92, 95, 98,
+ 101, 105, 109, 113, 116, 119, 122, 124, 126, 128,
+ 130, 132, 134, 136, 138, 140, 142, 144, 147, 148,
+ 150, 152, 155, 157, 159, 161, 163, 166, 168, 170,
+ 175, 180, 183, 187, 191, 194, 196, 198, 200, 205,
+ 210, 213, 217, 221, 224, 226, 230, 231, 233, 235,
+ 239, 242, 245, 247, 248, 250, 252, 257, 262, 265,
+ 269, 273, 277, 278, 280, 283, 287, 291, 292, 294,
+ 296, 299, 303, 306, 307, 309, 311, 315, 318, 321,
+ 323, 326, 327, 329, 332, 333, 335
};
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
{
- 53, 0, -1, 54, -1, 53, 54, -1, -1, 55,
- 56, -1, -1, 22, 57, 58, -1, 58, -1, 82,
- -1, 94, -1, 96, -1, 1, 43, -1, 1, 44,
- -1, 62, 59, 43, -1, -1, 60, -1, 61, -1,
- 60, 45, 61, -1, 72, 95, 93, 83, -1, -1,
- 63, -1, 64, -1, 63, 64, -1, 65, -1, 66,
- -1, 5, -1, 16, -1, 20, -1, 11, -1, 13,
- -1, 67, -1, 71, -1, 27, 46, 63, 47, 48,
- -1, 27, 46, 63, 48, -1, 21, 36, -1, 23,
- 36, -1, 10, 36, -1, 21, 36, 85, -1, 23,
- 36, 85, -1, 10, 36, 31, -1, 10, 31, -1,
- 21, 85, -1, 23, 85, -1, 7, -1, 18, -1,
- 14, -1, 15, -1, 19, -1, 24, -1, 12, -1,
- 9, -1, 25, -1, 6, -1, 40, -1, 47, 69,
- -1, -1, 70, -1, 71, -1, 70, 71, -1, 8,
- -1, 26, -1, 30, -1, 17, -1, 68, 72, -1,
- 73, -1, 36, -1, 73, 46, 76, 48, -1, 73,
- 46, 1, 48, -1, 73, 32, -1, 46, 72, 48,
- -1, 46, 1, 48, -1, 68, 74, -1, 75, -1,
- 36, -1, 40, -1, 75, 46, 76, 48, -1, 75,
- 46, 1, 48, -1, 75, 32, -1, 46, 74, 48,
- -1, 46, 1, 48, -1, 77, 35, -1, 77, -1,
- 78, 45, 35, -1, -1, 78, -1, 79, -1, 78,
- 45, 79, -1, 63, 80, -1, 68, 80, -1, 81,
- -1, -1, 36, -1, 40, -1, 81, 46, 76, 48,
- -1, 81, 46, 1, 48, -1, 81, 32, -1, 46,
- 80, 48, -1, 46, 1, 48, -1, 62, 72, 31,
- -1, -1, 84, -1, 49, 33, -1, 50, 86, 44,
- -1, 50, 1, 44, -1, -1, 87, -1, 88, -1,
- 87, 88, -1, 62, 89, 43, -1, 1, 43, -1,
- -1, 90, -1, 91, -1, 90, 45, 91, -1, 74,
- 93, -1, 36, 92, -1, 92, -1, 51, 33, -1,
- -1, 30, -1, 29, 43, -1, -1, 29, -1, 28,
- 46, 36, 48, 43, -1
+ 54, 0, -1, 55, -1, 54, 55, -1, -1, 56,
+ 57, -1, -1, 12, 23, 58, 60, -1, -1, 23,
+ 59, 60, -1, 60, -1, 84, -1, 96, -1, 98,
+ -1, 1, 44, -1, 1, 45, -1, 64, 61, 44,
+ -1, -1, 62, -1, 63, -1, 62, 46, 63, -1,
+ 74, 97, 95, 85, -1, -1, 65, -1, 66, -1,
+ 65, 66, -1, 67, -1, 68, -1, 5, -1, 17,
+ -1, 21, -1, 11, -1, 14, -1, 69, -1, 73,
+ -1, 28, 47, 65, 48, 49, -1, 28, 47, 65,
+ 49, -1, 22, 37, -1, 24, 37, -1, 10, 37,
+ -1, 22, 37, 87, -1, 24, 37, 87, -1, 10,
+ 37, 32, -1, 10, 32, -1, 22, 87, -1, 24,
+ 87, -1, 7, -1, 19, -1, 15, -1, 16, -1,
+ 20, -1, 25, -1, 13, -1, 9, -1, 26, -1,
+ 6, -1, 41, -1, 48, 71, -1, -1, 72, -1,
+ 73, -1, 72, 73, -1, 8, -1, 27, -1, 31,
+ -1, 18, -1, 70, 74, -1, 75, -1, 37, -1,
+ 75, 47, 78, 49, -1, 75, 47, 1, 49, -1,
+ 75, 33, -1, 47, 74, 49, -1, 47, 1, 49,
+ -1, 70, 76, -1, 77, -1, 37, -1, 41, -1,
+ 77, 47, 78, 49, -1, 77, 47, 1, 49, -1,
+ 77, 33, -1, 47, 76, 49, -1, 47, 1, 49,
+ -1, 79, 36, -1, 79, -1, 80, 46, 36, -1,
+ -1, 80, -1, 81, -1, 80, 46, 81, -1, 65,
+ 82, -1, 70, 82, -1, 83, -1, -1, 37, -1,
+ 41, -1, 83, 47, 78, 49, -1, 83, 47, 1,
+ 49, -1, 83, 33, -1, 47, 82, 49, -1, 47,
+ 1, 49, -1, 64, 74, 32, -1, -1, 86, -1,
+ 50, 34, -1, 51, 88, 45, -1, 51, 1, 45,
+ -1, -1, 89, -1, 90, -1, 89, 90, -1, 64,
+ 91, 44, -1, 1, 44, -1, -1, 92, -1, 93,
+ -1, 92, 46, 93, -1, 76, 95, -1, 37, 94,
+ -1, 94, -1, 52, 34, -1, -1, 31, -1, 30,
+ 44, -1, -1, 30, -1, 29, 47, 37, 49, 44,
+ -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short int yyrline[] =
+static const yytype_uint16 yyrline[] =
{
- 0, 102, 102, 103, 107, 107, 113, 113, 115, 116,
- 117, 118, 119, 120, 124, 138, 139, 143, 151, 164,
- 170, 171, 175, 176, 180, 186, 190, 191, 192, 193,
- 194, 198, 199, 200, 201, 205, 207, 209, 213, 220,
- 227, 236, 237, 238, 242, 243, 244, 245, 246, 247,
- 248, 249, 250, 251, 252, 256, 261, 262, 266, 267,
- 271, 271, 271, 272, 280, 281, 285, 294, 296, 298,
- 300, 302, 309, 310, 314, 315, 316, 318, 320, 322,
- 324, 329, 330, 331, 335, 336, 340, 341, 346, 351,
- 353, 357, 358, 366, 370, 372, 374, 376, 378, 383,
- 392, 393, 398, 403, 404, 408, 409, 413, 414, 418,
- 420, 425, 426, 430, 431, 435, 436, 437, 441, 445,
- 446, 450, 454, 455, 459
+ 0, 103, 103, 104, 108, 108, 114, 114, 116, 116,
+ 118, 119, 120, 121, 122, 123, 127, 141, 142, 146,
+ 154, 167, 173, 174, 178, 179, 183, 189, 193, 194,
+ 195, 196, 197, 201, 202, 203, 204, 208, 210, 212,
+ 216, 223, 230, 239, 240, 241, 245, 246, 247, 248,
+ 249, 250, 251, 252, 253, 254, 255, 259, 264, 265,
+ 269, 270, 274, 274, 274, 275, 283, 284, 288, 297,
+ 299, 301, 303, 305, 312, 313, 317, 318, 319, 321,
+ 323, 325, 327, 332, 333, 334, 338, 339, 343, 344,
+ 349, 354, 356, 360, 361, 369, 373, 375, 377, 379,
+ 381, 386, 395, 396, 401, 406, 407, 411, 412, 416,
+ 417, 421, 423, 428, 429, 433, 434, 438, 439, 440,
+ 444, 448, 449, 453, 457, 458, 462
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "ASM_KEYW", "ATTRIBUTE_KEYW",
"AUTO_KEYW", "BOOL_KEYW", "CHAR_KEYW", "CONST_KEYW", "DOUBLE_KEYW",
- "ENUM_KEYW", "EXTERN_KEYW", "FLOAT_KEYW", "INLINE_KEYW", "INT_KEYW",
- "LONG_KEYW", "REGISTER_KEYW", "RESTRICT_KEYW", "SHORT_KEYW",
- "SIGNED_KEYW", "STATIC_KEYW", "STRUCT_KEYW", "TYPEDEF_KEYW",
- "UNION_KEYW", "UNSIGNED_KEYW", "VOID_KEYW", "VOLATILE_KEYW",
- "TYPEOF_KEYW", "EXPORT_SYMBOL_KEYW", "ASM_PHRASE", "ATTRIBUTE_PHRASE",
- "BRACE_PHRASE", "BRACKET_PHRASE", "EXPRESSION_PHRASE", "CHAR", "DOTS",
- "IDENT", "INT", "REAL", "STRING", "TYPE", "OTHER", "FILENAME", "';'",
- "'}'", "','", "'('", "'*'", "')'", "'='", "'{'", "':'", "$accept",
- "declaration_seq", "declaration", "@1", "declaration1", "@2",
- "simple_declaration", "init_declarator_list_opt", "init_declarator_list",
- "init_declarator", "decl_specifier_seq_opt", "decl_specifier_seq",
- "decl_specifier", "storage_class_specifier", "type_specifier",
- "simple_type_specifier", "ptr_operator", "cvar_qualifier_seq_opt",
- "cvar_qualifier_seq", "cvar_qualifier", "declarator",
- "direct_declarator", "nested_declarator", "direct_nested_declarator",
- "parameter_declaration_clause", "parameter_declaration_list_opt",
- "parameter_declaration_list", "parameter_declaration",
- "m_abstract_declarator", "direct_m_abstract_declarator",
- "function_definition", "initializer_opt", "initializer", "class_body",
- "member_specification_opt", "member_specification", "member_declaration",
+ "ENUM_KEYW", "EXTERN_KEYW", "EXTENSION_KEYW", "FLOAT_KEYW",
+ "INLINE_KEYW", "INT_KEYW", "LONG_KEYW", "REGISTER_KEYW", "RESTRICT_KEYW",
+ "SHORT_KEYW", "SIGNED_KEYW", "STATIC_KEYW", "STRUCT_KEYW",
+ "TYPEDEF_KEYW", "UNION_KEYW", "UNSIGNED_KEYW", "VOID_KEYW",
+ "VOLATILE_KEYW", "TYPEOF_KEYW", "EXPORT_SYMBOL_KEYW", "ASM_PHRASE",
+ "ATTRIBUTE_PHRASE", "BRACE_PHRASE", "BRACKET_PHRASE",
+ "EXPRESSION_PHRASE", "CHAR", "DOTS", "IDENT", "INT", "REAL", "STRING",
+ "TYPE", "OTHER", "FILENAME", "';'", "'}'", "','", "'('", "'*'", "')'",
+ "'='", "'{'", "':'", "$accept", "declaration_seq", "declaration", "@1",
+ "declaration1", "@2", "@3", "simple_declaration",
+ "init_declarator_list_opt", "init_declarator_list", "init_declarator",
+ "decl_specifier_seq_opt", "decl_specifier_seq", "decl_specifier",
+ "storage_class_specifier", "type_specifier", "simple_type_specifier",
+ "ptr_operator", "cvar_qualifier_seq_opt", "cvar_qualifier_seq",
+ "cvar_qualifier", "declarator", "direct_declarator", "nested_declarator",
+ "direct_nested_declarator", "parameter_declaration_clause",
+ "parameter_declaration_list_opt", "parameter_declaration_list",
+ "parameter_declaration", "m_abstract_declarator",
+ "direct_m_abstract_declarator", "function_definition", "initializer_opt",
+ "initializer", "class_body", "member_specification_opt",
+ "member_specification", "member_declaration",
"member_declarator_list_opt", "member_declarator_list",
"member_declarator", "member_bitfield_declarator", "attribute_opt",
"asm_definition", "asm_phrase_opt", "export_definition", 0
@@ -467,284 +603,266 @@ static const char *const yytname[] =
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short int yytoknum[] =
+static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
- 295, 296, 297, 59, 125, 44, 40, 42, 41, 61,
- 123, 58
+ 295, 296, 297, 298, 59, 125, 44, 40, 42, 41,
+ 61, 123, 58
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const unsigned char yyr1[] =
+static const yytype_uint8 yyr1[] =
{
- 0, 52, 53, 53, 55, 54, 57, 56, 56, 56,
- 56, 56, 56, 56, 58, 59, 59, 60, 60, 61,
- 62, 62, 63, 63, 64, 64, 65, 65, 65, 65,
- 65, 66, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 66, 66, 67, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, 67, 68, 69, 69, 70, 70,
- 71, 71, 71, 71, 72, 72, 73, 73, 73, 73,
- 73, 73, 74, 74, 75, 75, 75, 75, 75, 75,
- 75, 76, 76, 76, 77, 77, 78, 78, 79, 80,
- 80, 81, 81, 81, 81, 81, 81, 81, 81, 82,
- 83, 83, 84, 85, 85, 86, 86, 87, 87, 88,
- 88, 89, 89, 90, 90, 91, 91, 91, 92, 93,
- 93, 94, 95, 95, 96
+ 0, 53, 54, 54, 56, 55, 58, 57, 59, 57,
+ 57, 57, 57, 57, 57, 57, 60, 61, 61, 62,
+ 62, 63, 64, 64, 65, 65, 66, 66, 67, 67,
+ 67, 67, 67, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 70, 71, 71,
+ 72, 72, 73, 73, 73, 73, 74, 74, 75, 75,
+ 75, 75, 75, 75, 76, 76, 77, 77, 77, 77,
+ 77, 77, 77, 78, 78, 78, 79, 79, 80, 80,
+ 81, 82, 82, 83, 83, 83, 83, 83, 83, 83,
+ 83, 84, 85, 85, 86, 87, 87, 88, 88, 89,
+ 89, 90, 90, 91, 91, 92, 92, 93, 93, 93,
+ 94, 95, 95, 96, 97, 97, 98
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const unsigned char yyr2[] =
+static const yytype_uint8 yyr2[] =
{
- 0, 2, 1, 2, 0, 2, 0, 3, 1, 1,
- 1, 1, 2, 2, 3, 0, 1, 1, 3, 4,
- 0, 1, 1, 2, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 5, 4, 2, 2, 2, 3, 3,
- 3, 2, 2, 2, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 2, 0, 1, 1, 2,
- 1, 1, 1, 1, 2, 1, 1, 4, 4, 2,
- 3, 3, 2, 1, 1, 1, 4, 4, 2, 3,
- 3, 2, 1, 3, 0, 1, 1, 3, 2, 2,
- 1, 0, 1, 1, 4, 4, 2, 3, 3, 3,
- 0, 1, 2, 3, 3, 0, 1, 1, 2, 3,
- 2, 0, 1, 1, 3, 2, 2, 1, 2, 0,
- 1, 2, 0, 1, 5
+ 0, 2, 1, 2, 0, 2, 0, 4, 0, 3,
+ 1, 1, 1, 1, 2, 2, 3, 0, 1, 1,
+ 3, 4, 0, 1, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 5, 4, 2, 2, 2,
+ 3, 3, 3, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 0, 1,
+ 1, 2, 1, 1, 1, 1, 2, 1, 1, 4,
+ 4, 2, 3, 3, 2, 1, 1, 1, 4, 4,
+ 2, 3, 3, 2, 1, 3, 0, 1, 1, 3,
+ 2, 2, 1, 0, 1, 1, 4, 4, 2, 3,
+ 3, 3, 0, 1, 2, 3, 3, 0, 1, 1,
+ 2, 3, 2, 0, 1, 1, 3, 2, 2, 1,
+ 2, 0, 1, 2, 0, 1, 5
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
-static const unsigned char yydefact[] =
+static const yytype_uint8 yydefact[] =
{
- 4, 4, 2, 0, 1, 3, 0, 26, 53, 44,
- 60, 51, 0, 29, 50, 30, 46, 47, 27, 63,
- 45, 48, 28, 0, 6, 0, 49, 52, 61, 0,
- 0, 0, 62, 54, 5, 8, 15, 21, 22, 24,
- 25, 31, 32, 9, 10, 11, 12, 13, 41, 37,
- 35, 0, 42, 20, 36, 43, 0, 0, 121, 66,
- 0, 56, 0, 16, 17, 0, 122, 65, 23, 40,
- 38, 0, 111, 0, 0, 107, 7, 15, 39, 0,
- 0, 0, 0, 55, 57, 58, 14, 0, 64, 123,
- 99, 119, 69, 0, 110, 104, 74, 75, 0, 0,
- 0, 119, 73, 0, 112, 113, 117, 103, 0, 108,
- 122, 0, 34, 0, 71, 70, 59, 18, 120, 100,
- 0, 91, 0, 82, 85, 86, 116, 0, 74, 0,
- 118, 72, 115, 78, 0, 109, 0, 33, 124, 0,
- 19, 101, 68, 92, 54, 0, 91, 88, 90, 67,
- 81, 0, 80, 79, 0, 0, 114, 102, 0, 93,
- 0, 89, 96, 0, 83, 87, 77, 76, 98, 97,
- 0, 0, 95, 94
+ 4, 4, 2, 0, 1, 3, 0, 28, 55, 46,
+ 62, 53, 0, 31, 0, 52, 32, 48, 49, 29,
+ 65, 47, 50, 30, 0, 8, 0, 51, 54, 63,
+ 0, 0, 0, 64, 56, 5, 10, 17, 23, 24,
+ 26, 27, 33, 34, 11, 12, 13, 14, 15, 43,
+ 39, 6, 37, 0, 44, 22, 38, 45, 0, 0,
+ 123, 68, 0, 58, 0, 18, 19, 0, 124, 67,
+ 25, 42, 22, 40, 0, 113, 0, 0, 109, 9,
+ 17, 41, 0, 0, 0, 0, 57, 59, 60, 16,
+ 0, 66, 125, 101, 121, 71, 0, 7, 112, 106,
+ 76, 77, 0, 0, 0, 121, 75, 0, 114, 115,
+ 119, 105, 0, 110, 124, 0, 36, 0, 73, 72,
+ 61, 20, 122, 102, 0, 93, 0, 84, 87, 88,
+ 118, 0, 76, 0, 120, 74, 117, 80, 0, 111,
+ 0, 35, 126, 0, 21, 103, 70, 94, 56, 0,
+ 93, 90, 92, 69, 83, 0, 82, 81, 0, 0,
+ 116, 104, 0, 95, 0, 91, 98, 0, 85, 89,
+ 79, 78, 100, 99, 0, 0, 97, 96
};
-/* YYDEFGOTO[NTERM-NUM]. */
-static const short int yydefgoto[] =
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
{
- -1, 1, 2, 3, 34, 53, 35, 62, 63, 64,
- 72, 37, 38, 39, 40, 41, 65, 83, 84, 42,
- 110, 67, 101, 102, 122, 123, 124, 125, 147, 148,
- 43, 140, 141, 52, 73, 74, 75, 103, 104, 105,
- 106, 119, 44, 91, 45
+ -1, 1, 2, 3, 35, 72, 55, 36, 64, 65,
+ 66, 75, 38, 39, 40, 41, 42, 67, 86, 87,
+ 43, 114, 69, 105, 106, 126, 127, 128, 129, 151,
+ 152, 44, 144, 145, 54, 76, 77, 78, 107, 108,
+ 109, 110, 123, 45, 94, 46
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -128
-static const short int yypact[] =
+#define YYPACT_NINF -135
+static const yytype_int16 yypact[] =
{
- -128, 13, -128, 329, -128, -128, 36, -128, -128, -128,
- -128, -128, -16, -128, -128, -128, -128, -128, -128, -128,
- -128, -128, -128, -25, -128, -24, -128, -128, -128, -29,
- -4, -22, -128, -128, -128, -128, -28, 495, -128, -128,
- -128, -128, -128, -128, -128, -128, -128, -128, -128, 16,
- -23, 103, -128, 495, -23, -128, 495, 35, -128, -128,
- 3, 15, 9, 17, -128, -28, -15, -8, -128, -128,
- -128, 47, 23, 44, 150, -128, -128, -28, -128, 372,
- 33, 48, 49, -128, 15, -128, -128, -28, -128, -128,
- -128, 64, -128, 197, -128, -128, 50, -128, 21, 65,
- 37, 64, 14, 56, 55, -128, -128, -128, 59, -128,
- 74, 57, -128, 63, -128, -128, -128, -128, -128, 76,
- 83, 416, 84, 99, 90, -128, -128, 88, -128, 89,
- -128, -128, -128, -128, 241, -128, 23, -128, -128, 105,
- -128, -128, -128, -128, -128, 8, 46, -128, 26, -128,
- -128, 459, -128, -128, 92, 93, -128, -128, 94, -128,
- 96, -128, -128, 285, -128, -128, -128, -128, -128, -128,
- 97, 100, -128, -128
+ -135, 11, -135, 312, -135, -135, 24, -135, -135, -135,
+ -135, -135, -23, -135, -2, -135, -135, -135, -135, -135,
+ -135, -135, -135, -135, -17, -135, -11, -135, -135, -135,
+ -3, 16, 26, -135, -135, -135, -135, 34, 482, -135,
+ -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
+ -8, -135, 22, 97, -135, 482, 22, -135, 482, 56,
+ -135, -135, 12, 10, 50, 49, -135, 34, -13, 15,
+ -135, -135, 482, -135, 47, -25, 51, 145, -135, -135,
+ 34, -135, 356, 52, 71, 77, -135, 10, -135, -135,
+ 34, -135, -135, -135, 68, -135, 193, -135, -135, -135,
+ 48, -135, 6, 93, 37, 68, 18, 85, 84, -135,
+ -135, -135, 87, -135, 102, 86, -135, 89, -135, -135,
+ -135, -135, -135, 90, 88, 401, 94, 100, 101, -135,
+ -135, 99, -135, 108, -135, -135, -135, -135, 230, -135,
+ -25, -135, -135, 105, -135, -135, -135, -135, -135, 9,
+ 42, -135, 28, -135, -135, 445, -135, -135, 119, 125,
+ -135, -135, 126, -135, 128, -135, -135, 267, -135, -135,
+ -135, -135, -135, -135, 129, 130, -135, -135
};
/* YYPGOTO[NTERM-NUM]. */
-static const short int yypgoto[] =
+static const yytype_int16 yypgoto[] =
{
- -128, -128, 151, -128, -128, -128, 119, -128, -128, 66,
- 0, -56, -36, -128, -128, -128, -70, -128, -128, -51,
- -31, -128, -11, -128, -127, -128, -128, 27, -81, -128,
- -128, -128, -128, -19, -128, -128, 107, -128, -128, 43,
- 86, 82, -128, -128, -128
+ -135, -135, 179, -135, -135, -135, -135, -47, -135, -135,
+ 91, 0, -58, -37, -135, -135, -135, -73, -135, -135,
+ -48, -32, -135, -38, -135, -134, -135, -135, 29, -63,
+ -135, -135, -135, -135, -20, -135, -135, 106, -135, -135,
+ 45, 95, 82, -135, -135, -135
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -107
-static const short int yytable[] =
+#define YYTABLE_NINF -109
+static const yytype_int16 yytable[] =
{
- 79, 68, 100, 36, 81, 66, 55, 155, 59, 158,
- 85, 50, 54, 4, 89, 48, 90, 56, 60, 61,
- 49, 58, 127, 10, 92, 51, 51, 51, 100, 82,
- 100, 70, 19, 116, 88, 78, 171, 121, 93, 59,
- -91, 28, 57, 68, 143, 32, 133, 69, 159, 60,
- 61, 146, 86, 77, 145, 61, -91, 128, 162, 96,
- 134, 97, 87, 97, 160, 161, 100, 98, 61, 98,
- 61, 80, 163, 128, 99, 146, 146, 97, 121, 46,
- 47, 113, 143, 98, 61, 68, 159, 129, 107, 131,
- 94, 95, 145, 61, 118, 121, 114, 115, 130, 135,
- 136, 99, 94, 89, 71, 137, 138, 121, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 139, 25, 26, 27, 28,
- 29, 142, 149, 32, 150, 151, 152, 153, 157, -20,
- 166, 167, 168, 33, 169, 172, -20, -105, 173, -20,
- -20, 108, 5, 117, -20, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 76, 25, 26, 27, 28, 29, 165, 156,
- 32, 109, 126, 132, 0, 0, -20, 0, 0, 0,
- 33, 0, 0, -20, -106, 0, -20, -20, 120, 0,
- 0, -20, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 0,
- 25, 26, 27, 28, 29, 0, 0, 32, 0, 0,
- 0, 0, -84, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 154, 0, 0, -84, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 0, 25, 26, 27, 28, 29, 0,
- 0, 32, 0, 0, 0, 0, -84, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 170, 0, 0, -84,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 0, 25, 26,
- 27, 28, 29, 0, 0, 32, 0, 0, 0, 0,
- -84, 0, 0, 0, 0, 33, 0, 0, 0, 0,
- 6, 0, 0, -84, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 0, 0, 0, 0, 0, -20, 0, 0, 0, 33,
- 0, 0, -20, 0, 0, -20, -20, 7, 8, 9,
+ 82, 70, 104, 37, 159, 68, 57, 131, 79, 49,
+ 162, 4, 100, 84, 50, 88, 101, 92, 10, 93,
+ 52, 51, 102, 63, 71, 97, 56, 103, 20, 104,
+ 85, 104, 73, 175, 53, 91, 81, 29, 125, 120,
+ 53, 33, -93, 132, 58, 70, 147, 101, 95, 61,
+ 163, 137, 150, 102, 63, 80, 149, 63, -93, 62,
+ 63, 166, 96, 59, 133, 138, 135, 104, 47, 48,
+ 60, 61, 80, 53, 132, 167, 150, 150, 101, 147,
+ 125, 62, 63, 163, 102, 63, 164, 165, 70, 149,
+ 63, 98, 99, 83, 89, 90, 111, 125, 74, 122,
+ 103, 117, 7, 8, 9, 10, 11, 12, 13, 125,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 118, 26, 27, 28, 29, 30, 119, 134, 33, 139,
+ 140, 98, 92, 142, -22, 141, 154, 146, 34, 161,
+ 143, -22, -107, 153, -22, -22, 112, 155, 156, -22,
+ 7, 8, 9, 10, 11, 12, 13, 157, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 170, 26,
+ 27, 28, 29, 30, 171, 172, 33, 173, 176, 177,
+ 5, 121, -22, 113, 169, 160, 34, 136, 0, -22,
+ -108, 0, -22, -22, 124, 130, 0, -22, 7, 8,
+ 9, 10, 11, 12, 13, 0, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 0, 26, 27, 28,
+ 29, 30, 0, 0, 33, 0, 0, 0, 0, -86,
+ 0, 158, 0, 0, 34, 7, 8, 9, 10, 11,
+ 12, 13, -86, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 0, 26, 27, 28, 29, 30, 0,
+ 0, 33, 0, 0, 0, 0, -86, 0, 174, 0,
+ 0, 34, 7, 8, 9, 10, 11, 12, 13, -86,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 0, 26, 27, 28, 29, 30, 0, 0, 33, 0,
+ 0, 0, 0, -86, 0, 0, 0, 0, 34, 0,
+ 0, 0, 0, 6, 0, 0, -86, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 0, 25, 26, 27, 28, 29,
- 0, 0, 32, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 33, 0, 0, 0, 0, 0, 0, 111,
- 112, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 0, 25,
- 26, 27, 28, 29, 0, 0, 32, 0, 0, 0,
- 0, 0, 143, 0, 0, 0, 144, 0, 0, 0,
- 0, 0, 145, 61, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 0, 25, 26, 27, 28, 29, 0, 0, 32,
- 0, 0, 0, 0, 164, 0, 0, 0, 0, 33,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 0, 25, 26,
- 27, 28, 29, 0, 0, 32, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 33
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 0, 0, 0, 0, 0, -22,
+ 0, 0, 0, 34, 0, 0, -22, 0, 0, -22,
+ -22, 7, 8, 9, 10, 11, 12, 13, 0, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 0,
+ 26, 27, 28, 29, 30, 0, 0, 33, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 34, 0, 0,
+ 0, 0, 0, 0, 115, 116, 7, 8, 9, 10,
+ 11, 12, 13, 0, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 0, 26, 27, 28, 29, 30,
+ 0, 0, 33, 0, 0, 0, 0, 0, 147, 0,
+ 0, 0, 148, 0, 0, 0, 0, 0, 149, 63,
+ 7, 8, 9, 10, 11, 12, 13, 0, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 0, 26,
+ 27, 28, 29, 30, 0, 0, 33, 0, 0, 0,
+ 0, 168, 0, 0, 0, 0, 34, 7, 8, 9,
+ 10, 11, 12, 13, 0, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 0, 26, 27, 28, 29,
+ 30, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 34
};
-static const short int yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 56, 37, 72, 3, 1, 36, 25, 134, 36, 1,
- 61, 36, 36, 0, 29, 31, 31, 46, 46, 47,
- 36, 43, 1, 8, 32, 50, 50, 50, 98, 60,
- 100, 50, 17, 84, 65, 54, 163, 93, 46, 36,
- 32, 26, 46, 79, 36, 30, 32, 31, 40, 46,
- 47, 121, 43, 53, 46, 47, 48, 36, 32, 36,
- 46, 40, 45, 40, 145, 146, 136, 46, 47, 46,
- 47, 36, 46, 36, 51, 145, 146, 40, 134, 43,
- 44, 48, 36, 46, 47, 121, 40, 98, 44, 100,
- 43, 44, 46, 47, 30, 151, 48, 48, 33, 43,
- 45, 51, 43, 29, 1, 48, 43, 163, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 49, 23, 24, 25, 26,
- 27, 48, 48, 30, 35, 45, 48, 48, 33, 36,
- 48, 48, 48, 40, 48, 48, 43, 44, 48, 46,
- 47, 1, 1, 87, 51, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 53, 23, 24, 25, 26, 27, 151, 136,
- 30, 74, 96, 101, -1, -1, 36, -1, -1, -1,
- 40, -1, -1, 43, 44, -1, 46, 47, 1, -1,
- -1, 51, 5, 6, 7, 8, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, -1,
- 23, 24, 25, 26, 27, -1, -1, 30, -1, -1,
- -1, -1, 35, -1, -1, -1, -1, 40, -1, -1,
- -1, -1, 1, -1, -1, 48, 5, 6, 7, 8,
- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, -1, 23, 24, 25, 26, 27, -1,
- -1, 30, -1, -1, -1, -1, 35, -1, -1, -1,
- -1, 40, -1, -1, -1, -1, 1, -1, -1, 48,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, -1, 23, 24,
- 25, 26, 27, -1, -1, 30, -1, -1, -1, -1,
- 35, -1, -1, -1, -1, 40, -1, -1, -1, -1,
- 1, -1, -1, 48, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- -1, -1, -1, -1, -1, 36, -1, -1, -1, 40,
- -1, -1, 43, -1, -1, 46, 47, 5, 6, 7,
+ 58, 38, 75, 3, 138, 37, 26, 1, 55, 32,
+ 1, 0, 37, 1, 37, 63, 41, 30, 8, 32,
+ 37, 23, 47, 48, 32, 72, 37, 52, 18, 102,
+ 62, 104, 52, 167, 51, 67, 56, 27, 96, 87,
+ 51, 31, 33, 37, 47, 82, 37, 41, 33, 37,
+ 41, 33, 125, 47, 48, 55, 47, 48, 49, 47,
+ 48, 33, 47, 47, 102, 47, 104, 140, 44, 45,
+ 44, 37, 72, 51, 37, 47, 149, 150, 41, 37,
+ 138, 47, 48, 41, 47, 48, 149, 150, 125, 47,
+ 48, 44, 45, 37, 44, 46, 45, 155, 1, 31,
+ 52, 49, 5, 6, 7, 8, 9, 10, 11, 167,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 49, 24, 25, 26, 27, 28, 49, 34, 31, 44,
+ 46, 44, 30, 44, 37, 49, 36, 49, 41, 34,
+ 50, 44, 45, 49, 47, 48, 1, 46, 49, 52,
+ 5, 6, 7, 8, 9, 10, 11, 49, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 49, 24,
+ 25, 26, 27, 28, 49, 49, 31, 49, 49, 49,
+ 1, 90, 37, 77, 155, 140, 41, 105, -1, 44,
+ 45, -1, 47, 48, 1, 100, -1, 52, 5, 6,
+ 7, 8, 9, 10, 11, -1, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, -1, 24, 25, 26,
+ 27, 28, -1, -1, 31, -1, -1, -1, -1, 36,
+ -1, 1, -1, -1, 41, 5, 6, 7, 8, 9,
+ 10, 11, 49, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, -1, 24, 25, 26, 27, 28, -1,
+ -1, 31, -1, -1, -1, -1, 36, -1, 1, -1,
+ -1, 41, 5, 6, 7, 8, 9, 10, 11, 49,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ -1, 24, 25, 26, 27, 28, -1, -1, 31, -1,
+ -1, -1, -1, 36, -1, -1, -1, -1, 41, -1,
+ -1, -1, -1, 1, -1, -1, 49, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, -1, 23, 24, 25, 26, 27,
- -1, -1, 30, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 40, -1, -1, -1, -1, -1, -1, 47,
- 48, 5, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, -1, 23,
- 24, 25, 26, 27, -1, -1, 30, -1, -1, -1,
- -1, -1, 36, -1, -1, -1, 40, -1, -1, -1,
- -1, -1, 46, 47, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, -1, 23, 24, 25, 26, 27, -1, -1, 30,
- -1, -1, -1, -1, 35, -1, -1, -1, -1, 40,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, -1, 23, 24,
- 25, 26, 27, -1, -1, 30, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 40
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, -1, -1, -1, -1, -1, 37,
+ -1, -1, -1, 41, -1, -1, 44, -1, -1, 47,
+ 48, 5, 6, 7, 8, 9, 10, 11, -1, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, -1,
+ 24, 25, 26, 27, 28, -1, -1, 31, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 41, -1, -1,
+ -1, -1, -1, -1, 48, 49, 5, 6, 7, 8,
+ 9, 10, 11, -1, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, -1, 24, 25, 26, 27, 28,
+ -1, -1, 31, -1, -1, -1, -1, -1, 37, -1,
+ -1, -1, 41, -1, -1, -1, -1, -1, 47, 48,
+ 5, 6, 7, 8, 9, 10, 11, -1, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, -1, 24,
+ 25, 26, 27, 28, -1, -1, 31, -1, -1, -1,
+ -1, 36, -1, -1, -1, -1, 41, 5, 6, 7,
+ 8, 9, 10, 11, -1, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, -1, 24, 25, 26, 27,
+ 28, -1, -1, 31, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 41
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
-static const unsigned char yystos[] =
+static const yytype_uint8 yystos[] =
{
- 0, 53, 54, 55, 0, 54, 1, 5, 6, 7,
+ 0, 54, 55, 56, 0, 55, 1, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 40, 56, 58, 62, 63, 64, 65,
- 66, 67, 71, 82, 94, 96, 43, 44, 31, 36,
- 36, 50, 85, 57, 36, 85, 46, 46, 43, 36,
- 46, 47, 59, 60, 61, 68, 72, 73, 64, 31,
- 85, 1, 62, 86, 87, 88, 58, 62, 85, 63,
- 36, 1, 72, 69, 70, 71, 43, 45, 72, 29,
- 31, 95, 32, 46, 43, 44, 36, 40, 46, 51,
- 68, 74, 75, 89, 90, 91, 92, 44, 1, 88,
- 72, 47, 48, 48, 48, 48, 71, 61, 30, 93,
- 1, 63, 76, 77, 78, 79, 92, 1, 36, 74,
- 33, 74, 93, 32, 46, 43, 45, 48, 43, 49,
- 83, 84, 48, 36, 40, 46, 68, 80, 81, 48,
- 35, 45, 48, 48, 1, 76, 91, 33, 1, 40,
- 80, 80, 32, 46, 35, 79, 48, 48, 48, 48,
- 1, 76, 48, 48
+ 28, 29, 30, 31, 41, 57, 60, 64, 65, 66,
+ 67, 68, 69, 73, 84, 96, 98, 44, 45, 32,
+ 37, 23, 37, 51, 87, 59, 37, 87, 47, 47,
+ 44, 37, 47, 48, 61, 62, 63, 70, 74, 75,
+ 66, 32, 58, 87, 1, 64, 88, 89, 90, 60,
+ 64, 87, 65, 37, 1, 74, 71, 72, 73, 44,
+ 46, 74, 30, 32, 97, 33, 47, 60, 44, 45,
+ 37, 41, 47, 52, 70, 76, 77, 91, 92, 93,
+ 94, 45, 1, 90, 74, 48, 49, 49, 49, 49,
+ 73, 63, 31, 95, 1, 65, 78, 79, 80, 81,
+ 94, 1, 37, 76, 34, 76, 95, 33, 47, 44,
+ 46, 49, 44, 50, 85, 86, 49, 37, 41, 47,
+ 70, 82, 83, 49, 36, 46, 49, 49, 1, 78,
+ 93, 34, 1, 41, 82, 82, 33, 47, 36, 81,
+ 49, 49, 49, 49, 1, 78, 49, 49
};
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
-#endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
-#endif
-
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
@@ -770,15 +888,15 @@ do \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
+ YYPOPSTACK (1); \
goto yybackup; \
} \
else \
- { \
- yyerror ("syntax error: cannot back up");\
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
-while (0)
+while (YYID (0))
#define YYTERROR 1
@@ -793,7 +911,7 @@ while (0)
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
- if (N) \
+ if (YYID (N)) \
{ \
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
@@ -807,7 +925,7 @@ while (0)
(Current).first_column = (Current).last_column = \
YYRHSLOC (Rhs, 0).last_column; \
} \
- while (0)
+ while (YYID (0))
#endif
@@ -819,8 +937,8 @@ while (0)
# if YYLTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
@@ -847,36 +965,96 @@ while (0)
do { \
if (yydebug) \
YYFPRINTF Args; \
-} while (0)
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included). |
`------------------------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
yy_stack_print (bottom, top)
- short int *bottom;
- short int *top;
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (/* Nothing. */; bottom <= top; ++bottom)
+ for (; bottom <= top; ++bottom)
YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -885,37 +1063,45 @@ yy_stack_print (bottom, top)
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
-} while (0)
+} while (YYID (0))
/*------------------------------------------------.
| Report that the YYRULE is going to be reduced. |
`------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
#else
static void
-yy_reduce_print (yyrule)
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
int yyrule;
#endif
{
+ int yynrhs = yyr2[yyrule];
int yyi;
- unsigned int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
- yyrule - 1, yylno);
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (Rule); \
-} while (0)
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -937,7 +1123,7 @@ int yydebug;
if the built-in stack extension method is used).
Do not make this value too large; the results are undefined if
- SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
#ifndef YYMAXDEPTH
@@ -949,45 +1135,47 @@ int yydebug;
#if YYERROR_VERBOSE
# ifndef yystrlen
-# if defined (__GLIBC__) && defined (_STRING_H)
+# if defined __GLIBC__ && defined _STRING_H
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
-# if defined (__STDC__) || defined (__cplusplus)
yystrlen (const char *yystr)
-# else
+#else
+static YYSIZE_T
yystrlen (yystr)
- const char *yystr;
-# endif
+ const char *yystr;
+#endif
{
- register const char *yys = yystr;
-
- while (*yys++ != '\0')
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
continue;
-
- return yys - yystr - 1;
+ return yylen;
}
# endif
# endif
# ifndef yystpcpy
-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
# define yystpcpy stpcpy
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static char *
-# if defined (__STDC__) || defined (__cplusplus)
yystpcpy (char *yydest, const char *yysrc)
-# else
+#else
+static char *
yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-# endif
+ char *yydest;
+ const char *yysrc;
+#endif
{
- register char *yyd = yydest;
- register const char *yys = yysrc;
+ char *yyd = yydest;
+ const char *yys = yysrc;
while ((*yyd++ = *yys++) != '\0')
continue;
@@ -997,53 +1185,171 @@ yystpcpy (yydest, yysrc)
# endif
# endif
-#endif /* !YYERROR_VERBOSE */
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
-
+ if (! yyres)
+ return yystrlen (yystr);
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ int yyn = yypact[yystate];
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
-
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- switch (yytype)
{
- default:
- break;
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
}
- YYFPRINTF (yyoutput, ")");
}
+#endif /* YYERROR_VERBOSE */
+
-#endif /* ! YYDEBUG */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
@@ -1054,8 +1360,7 @@ yydestruct (yymsg, yytype, yyvaluep)
YYSTYPE *yyvaluep;
#endif
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ YYUSE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
@@ -1065,7 +1370,7 @@ yydestruct (yymsg, yytype, yyvaluep)
{
default:
- break;
+ break;
}
}
@@ -1073,13 +1378,13 @@ yydestruct (yymsg, yytype, yyvaluep)
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
-# else
+#else
int yyparse ();
-# endif
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
@@ -1104,14 +1409,18 @@ int yynerrs;
`----------*/
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-# endif
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
#else
@@ -1122,13 +1431,19 @@ yyparse ()
#endif
{
- register int yystate;
- register int yyn;
+ int yystate;
+ int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
/* Three stacks and their tools:
`yyss': related to states,
@@ -1139,18 +1454,18 @@ yyparse ()
to reallocate them elsewhere. */
/* The state stack. */
- short int yyssa[YYINITDEPTH];
- short int *yyss = yyssa;
- register short int *yyssp;
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
- register YYSTYPE *yyvsp;
+ YYSTYPE *yyvsp;
-#define YYPOPSTACK (yyvsp--, yyssp--)
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
YYSIZE_T yystacksize = YYINITDEPTH;
@@ -1159,9 +1474,9 @@ yyparse ()
YYSTYPE yyval;
- /* When reducing, the number of symbols on the RHS of the reduced
- rule. */
- int yylen;
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1178,9 +1493,6 @@ yyparse ()
yyssp = yyss;
yyvsp = yyvs;
-
- yyvsp[0] = yylval;
-
goto yysetstate;
/*------------------------------------------------------------.
@@ -1188,8 +1500,7 @@ yyparse ()
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks.
- */
+ have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
yysetstate:
@@ -1202,18 +1513,18 @@ yyparse ()
#ifdef yyoverflow
{
- /* Give user a chance to reallocate the stack. Use copies of
+ /* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
+ yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
@@ -1224,21 +1535,21 @@ yyparse ()
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
- goto yyoverflowlab;
+ goto yyexhaustedlab;
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyoverflowlab;
+ goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
- goto yyoverflowlab;
+ goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
@@ -1269,12 +1580,10 @@ yyparse ()
`-----------*/
yybackup:
-/* Do appropriate processing given the current state. */
-/* Read a look-ahead token if we need one and don't already have one. */
-/* yyresume: */
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
-
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
@@ -1316,22 +1625,21 @@ yybackup:
if (yyn == YYFINAL)
YYACCEPT;
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
/* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the token being shifted unless it is eof. */
+ /* Discard the shifted token unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
+ yystate = yyn;
*++yyvsp = yylval;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- yystate = yyn;
goto yynewstate;
@@ -1367,457 +1675,466 @@ yyreduce:
switch (yyn)
{
case 4:
-#line 107 "scripts/genksyms/parse.y"
+#line 108 "scripts/genksyms/parse.y"
{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;}
break;
case 5:
-#line 109 "scripts/genksyms/parse.y"
- { free_list(*(yyvsp[0]), NULL); *(yyvsp[0]) = NULL; ;}
+#line 110 "scripts/genksyms/parse.y"
+ { free_list(*(yyvsp[(2) - (2)]), NULL); *(yyvsp[(2) - (2)]) = NULL; ;}
break;
case 6:
-#line 113 "scripts/genksyms/parse.y"
+#line 114 "scripts/genksyms/parse.y"
{ is_typedef = 1; ;}
break;
case 7:
-#line 114 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 115 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
- case 12:
-#line 119 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 8:
+#line 116 "scripts/genksyms/parse.y"
+ { is_typedef = 1; ;}
break;
- case 13:
-#line 120 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 9:
+#line 117 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
case 14:
-#line 125 "scripts/genksyms/parse.y"
+#line 122 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
+ break;
+
+ case 15:
+#line 123 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
+ break;
+
+ case 16:
+#line 128 "scripts/genksyms/parse.y"
{ if (current_name) {
- struct string_list *decl = (*(yyvsp[0]))->next;
- (*(yyvsp[0]))->next = NULL;
+ struct string_list *decl = (*(yyvsp[(3) - (3)]))->next;
+ (*(yyvsp[(3) - (3)]))->next = NULL;
add_symbol(current_name,
is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
decl, is_extern);
current_name = NULL;
}
- (yyval) = (yyvsp[0]);
+ (yyval) = (yyvsp[(3) - (3)]);
;}
break;
- case 15:
-#line 138 "scripts/genksyms/parse.y"
+ case 17:
+#line 141 "scripts/genksyms/parse.y"
{ (yyval) = NULL; ;}
break;
- case 17:
-#line 144 "scripts/genksyms/parse.y"
- { struct string_list *decl = *(yyvsp[0]);
- *(yyvsp[0]) = NULL;
+ case 19:
+#line 147 "scripts/genksyms/parse.y"
+ { struct string_list *decl = *(yyvsp[(1) - (1)]);
+ *(yyvsp[(1) - (1)]) = NULL;
add_symbol(current_name,
is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
current_name = NULL;
- (yyval) = (yyvsp[0]);
+ (yyval) = (yyvsp[(1) - (1)]);
;}
break;
- case 18:
-#line 152 "scripts/genksyms/parse.y"
- { struct string_list *decl = *(yyvsp[0]);
- *(yyvsp[0]) = NULL;
- free_list(*(yyvsp[-1]), NULL);
- *(yyvsp[-1]) = decl_spec;
+ case 20:
+#line 155 "scripts/genksyms/parse.y"
+ { struct string_list *decl = *(yyvsp[(3) - (3)]);
+ *(yyvsp[(3) - (3)]) = NULL;
+ free_list(*(yyvsp[(2) - (3)]), NULL);
+ *(yyvsp[(2) - (3)]) = decl_spec;
add_symbol(current_name,
is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
current_name = NULL;
- (yyval) = (yyvsp[0]);
+ (yyval) = (yyvsp[(3) - (3)]);
;}
break;
- case 19:
-#line 165 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]) ? (yyvsp[-1]) : (yyvsp[-2]) ? (yyvsp[-2]) : (yyvsp[-3]); ;}
+ case 21:
+#line 168 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]) ? (yyvsp[(4) - (4)]) : (yyvsp[(3) - (4)]) ? (yyvsp[(3) - (4)]) : (yyvsp[(2) - (4)]) ? (yyvsp[(2) - (4)]) : (yyvsp[(1) - (4)]); ;}
break;
- case 20:
-#line 170 "scripts/genksyms/parse.y"
+ case 22:
+#line 173 "scripts/genksyms/parse.y"
{ decl_spec = NULL; ;}
break;
- case 22:
-#line 175 "scripts/genksyms/parse.y"
- { decl_spec = *(yyvsp[0]); ;}
+ case 24:
+#line 178 "scripts/genksyms/parse.y"
+ { decl_spec = *(yyvsp[(1) - (1)]); ;}
break;
- case 23:
-#line 176 "scripts/genksyms/parse.y"
- { decl_spec = *(yyvsp[0]); ;}
+ case 25:
+#line 179 "scripts/genksyms/parse.y"
+ { decl_spec = *(yyvsp[(2) - (2)]); ;}
break;
- case 24:
-#line 181 "scripts/genksyms/parse.y"
+ case 26:
+#line 184 "scripts/genksyms/parse.y"
{ /* Version 2 checksumming ignores storage class, as that
is really irrelevant to the linkage. */
- remove_node((yyvsp[0]));
- (yyval) = (yyvsp[0]);
+ remove_node((yyvsp[(1) - (1)]));
+ (yyval) = (yyvsp[(1) - (1)]);
;}
break;
- case 29:
-#line 193 "scripts/genksyms/parse.y"
- { is_extern = 1; (yyval) = (yyvsp[0]); ;}
+ case 31:
+#line 196 "scripts/genksyms/parse.y"
+ { is_extern = 1; (yyval) = (yyvsp[(1) - (1)]); ;}
break;
- case 30:
-#line 194 "scripts/genksyms/parse.y"
- { is_extern = 0; (yyval) = (yyvsp[0]); ;}
+ case 32:
+#line 197 "scripts/genksyms/parse.y"
+ { is_extern = 0; (yyval) = (yyvsp[(1) - (1)]); ;}
break;
- case 35:
-#line 206 "scripts/genksyms/parse.y"
- { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_STRUCT; (yyval) = (yyvsp[0]); ;}
+ case 37:
+#line 209 "scripts/genksyms/parse.y"
+ { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_STRUCT; (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 36:
-#line 208 "scripts/genksyms/parse.y"
- { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_UNION; (yyval) = (yyvsp[0]); ;}
+ case 38:
+#line 211 "scripts/genksyms/parse.y"
+ { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_UNION; (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 37:
-#line 210 "scripts/genksyms/parse.y"
- { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_ENUM; (yyval) = (yyvsp[0]); ;}
+ case 39:
+#line 213 "scripts/genksyms/parse.y"
+ { remove_node((yyvsp[(1) - (2)])); (*(yyvsp[(2) - (2)]))->tag = SYM_ENUM; (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 38:
-#line 214 "scripts/genksyms/parse.y"
- { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
+ case 40:
+#line 217 "scripts/genksyms/parse.y"
+ { struct string_list *s = *(yyvsp[(3) - (3)]), *i = *(yyvsp[(2) - (3)]), *r;
r = copy_node(i); r->tag = SYM_STRUCT;
- r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
+ r->next = (*(yyvsp[(1) - (3)]))->next; *(yyvsp[(3) - (3)]) = r; (*(yyvsp[(1) - (3)]))->next = NULL;
add_symbol(i->string, SYM_STRUCT, s, is_extern);
- (yyval) = (yyvsp[0]);
+ (yyval) = (yyvsp[(3) - (3)]);
;}
break;
- case 39:
-#line 221 "scripts/genksyms/parse.y"
- { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
+ case 41:
+#line 224 "scripts/genksyms/parse.y"
+ { struct string_list *s = *(yyvsp[(3) - (3)]), *i = *(yyvsp[(2) - (3)]), *r;
r = copy_node(i); r->tag = SYM_UNION;
- r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
+ r->next = (*(yyvsp[(1) - (3)]))->next; *(yyvsp[(3) - (3)]) = r; (*(yyvsp[(1) - (3)]))->next = NULL;
add_symbol(i->string, SYM_UNION, s, is_extern);
- (yyval) = (yyvsp[0]);
+ (yyval) = (yyvsp[(3) - (3)]);
;}
break;
- case 40:
-#line 228 "scripts/genksyms/parse.y"
- { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
+ case 42:
+#line 231 "scripts/genksyms/parse.y"
+ { struct string_list *s = *(yyvsp[(3) - (3)]), *i = *(yyvsp[(2) - (3)]), *r;
r = copy_node(i); r->tag = SYM_ENUM;
- r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
+ r->next = (*(yyvsp[(1) - (3)]))->next; *(yyvsp[(3) - (3)]) = r; (*(yyvsp[(1) - (3)]))->next = NULL;
add_symbol(i->string, SYM_ENUM, s, is_extern);
- (yyval) = (yyvsp[0]);
+ (yyval) = (yyvsp[(3) - (3)]);
;}
break;
- case 41:
-#line 236 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 43:
+#line 239 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 42:
-#line 237 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 44:
+#line 240 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 43:
-#line 238 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 45:
+#line 241 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 54:
-#line 252 "scripts/genksyms/parse.y"
- { (*(yyvsp[0]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[0]); ;}
+ case 56:
+#line 255 "scripts/genksyms/parse.y"
+ { (*(yyvsp[(1) - (1)]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[(1) - (1)]); ;}
break;
- case 55:
-#line 257 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+ case 57:
+#line 260 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
break;
- case 56:
-#line 261 "scripts/genksyms/parse.y"
+ case 58:
+#line 264 "scripts/genksyms/parse.y"
{ (yyval) = NULL; ;}
break;
- case 59:
-#line 267 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 61:
+#line 270 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 63:
-#line 273 "scripts/genksyms/parse.y"
+ case 65:
+#line 276 "scripts/genksyms/parse.y"
{ /* restrict has no effect in prototypes so ignore it */
- remove_node((yyvsp[0]));
- (yyval) = (yyvsp[0]);
+ remove_node((yyvsp[(1) - (1)]));
+ (yyval) = (yyvsp[(1) - (1)]);
;}
break;
- case 64:
-#line 280 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 66:
+#line 283 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 66:
-#line 286 "scripts/genksyms/parse.y"
+ case 68:
+#line 289 "scripts/genksyms/parse.y"
{ if (current_name != NULL) {
error_with_pos("unexpected second declaration name");
YYERROR;
} else {
- current_name = (*(yyvsp[0]))->string;
- (yyval) = (yyvsp[0]);
+ current_name = (*(yyvsp[(1) - (1)]))->string;
+ (yyval) = (yyvsp[(1) - (1)]);
}
;}
break;
- case 67:
-#line 295 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
- break;
-
- case 68:
-#line 297 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
- break;
-
case 69:
-#line 299 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 298 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
case 70:
-#line 301 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 300 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
case 71:
-#line 303 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 302 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 72:
-#line 309 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 304 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 76:
-#line 317 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 73:
+#line 306 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 77:
-#line 319 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 74:
+#line 312 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 78:
-#line 321 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 320 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
case 79:
-#line 323 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 322 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
case 80:
-#line 325 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 324 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 81:
-#line 329 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 326 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 83:
-#line 331 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 82:
+#line 328 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 84:
-#line 335 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+ case 83:
+#line 332 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 87:
-#line 342 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 85:
+#line 334 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 88:
-#line 347 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+ case 86:
+#line 338 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
case 89:
-#line 352 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+#line 345 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 91:
-#line 357 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+ case 90:
+#line 350 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
break;
- case 92:
-#line 359 "scripts/genksyms/parse.y"
- { /* For version 2 checksums, we don't want to remember
- private parameter names. */
- remove_node((yyvsp[0]));
- (yyval) = (yyvsp[0]);
- ;}
+ case 91:
+#line 355 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
break;
case 93:
-#line 367 "scripts/genksyms/parse.y"
- { remove_node((yyvsp[0]));
- (yyval) = (yyvsp[0]);
- ;}
+#line 360 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
case 94:
-#line 371 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 362 "scripts/genksyms/parse.y"
+ { /* For version 2 checksums, we don't want to remember
+ private parameter names. */
+ remove_node((yyvsp[(1) - (1)]));
+ (yyval) = (yyvsp[(1) - (1)]);
+ ;}
break;
case 95:
-#line 373 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 370 "scripts/genksyms/parse.y"
+ { remove_node((yyvsp[(1) - (1)]));
+ (yyval) = (yyvsp[(1) - (1)]);
+ ;}
break;
case 96:
-#line 375 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 374 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
case 97:
-#line 377 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 376 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(4) - (4)]); ;}
break;
case 98:
-#line 379 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 378 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 99:
-#line 384 "scripts/genksyms/parse.y"
- { struct string_list *decl = *(yyvsp[-1]);
- *(yyvsp[-1]) = NULL;
- add_symbol(current_name, SYM_NORMAL, decl, is_extern);
- (yyval) = (yyvsp[0]);
- ;}
+#line 380 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
case 100:
-#line 392 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+#line 382 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 102:
-#line 399 "scripts/genksyms/parse.y"
- { remove_list((yyvsp[0]), &(*(yyvsp[-1]))->next); (yyval) = (yyvsp[0]); ;}
+ case 101:
+#line 387 "scripts/genksyms/parse.y"
+ { struct string_list *decl = *(yyvsp[(2) - (3)]);
+ *(yyvsp[(2) - (3)]) = NULL;
+ add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+ (yyval) = (yyvsp[(3) - (3)]);
+ ;}
break;
- case 103:
-#line 403 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 102:
+#line 395 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
case 104:
-#line 404 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 402 "scripts/genksyms/parse.y"
+ { remove_list((yyvsp[(2) - (2)]), &(*(yyvsp[(1) - (2)]))->next); (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 105:
-#line 408 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+#line 406 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 108:
-#line 414 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 106:
+#line 407 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 109:
-#line 419 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 107:
+#line 411 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
case 110:
-#line 421 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 417 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 111:
-#line 425 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+#line 422 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
break;
- case 114:
-#line 431 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+ case 112:
+#line 424 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 115:
-#line 435 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+ case 113:
+#line 428 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
case 116:
-#line 436 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 434 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(3) - (3)]); ;}
+ break;
+
+ case 117:
+#line 438 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]) ? (yyvsp[(2) - (2)]) : (yyvsp[(1) - (2)]); ;}
break;
case 118:
-#line 441 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 439 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
- case 119:
-#line 445 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+ case 120:
+#line 444 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 121:
-#line 450 "scripts/genksyms/parse.y"
- { (yyval) = (yyvsp[0]); ;}
+#line 448 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
- case 122:
-#line 454 "scripts/genksyms/parse.y"
- { (yyval) = NULL; ;}
+ case 123:
+#line 453 "scripts/genksyms/parse.y"
+ { (yyval) = (yyvsp[(2) - (2)]); ;}
break;
case 124:
-#line 460 "scripts/genksyms/parse.y"
- { export_symbol((*(yyvsp[-2]))->string); (yyval) = (yyvsp[0]); ;}
+#line 457 "scripts/genksyms/parse.y"
+ { (yyval) = NULL; ;}
break;
+ case 126:
+#line 463 "scripts/genksyms/parse.y"
+ { export_symbol((*(yyvsp[(3) - (5)]))->string); (yyval) = (yyvsp[(5) - (5)]); ;}
+ break;
- }
-
-/* Line 1037 of yacc.c. */
-#line 1816 "scripts/genksyms/parse.c"
-
- yyvsp -= yylen;
- yyssp -= yylen;
+/* Line 1267 of yacc.c. */
+#line 2132 "scripts/genksyms/parse.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+ YYPOPSTACK (yylen);
+ yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
@@ -1846,66 +2163,41 @@ yyerrlab:
if (!yyerrstatus)
{
++yynerrs;
-#if YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (YYPACT_NINF < yyn && yyn < YYLAST)
- {
- YYSIZE_T yysize = 0;
- int yytype = YYTRANSLATE (yychar);
- const char* yyprefix;
- char *yymsg;
- int yyx;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 0;
-
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
{
- yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
- yycount += 1;
- if (yycount == 5)
- {
- yysize = 0;
- break;
- }
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
}
- yysize += (sizeof ("syntax error, unexpected ")
- + yystrlen (yytname[yytype]));
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg != 0)
- {
- char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
- yyp = yystpcpy (yyp, yytname[yytype]);
-
- if (yycount < 5)
- {
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- yyp = yystpcpy (yyp, yyprefix);
- yyp = yystpcpy (yyp, yytname[yyx]);
- yyprefix = " or ";
- }
- }
- yyerror (yymsg);
- YYSTACK_FREE (yymsg);
- }
- else
- yyerror ("syntax error; also virtual memory exhausted");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror ("syntax error");
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
}
@@ -1916,23 +2208,15 @@ yyerrlab:
error, discard it. */
if (yychar <= YYEOF)
- {
- /* If at end of input, pop the error token,
- then the rest of the stack, then return failure. */
+ {
+ /* Return failure if at end of input. */
if (yychar == YYEOF)
- for (;;)
- {
-
- YYPOPSTACK;
- if (yyssp == yyss)
- YYABORT;
- yydestruct ("Error: popping",
- yystos[*yyssp], yyvsp);
- }
- }
+ YYABORT;
+ }
else
{
- yydestruct ("Error: discarding", yytoken, &yylval);
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
yychar = YYEMPTY;
}
}
@@ -1947,15 +2231,17 @@ yyerrlab:
`---------------------------------------------------*/
yyerrorlab:
-#ifdef __GNUC__
- /* Pacify GCC when the user code never invokes YYERROR and the label
- yyerrorlab therefore never appears in user code. */
- if (0)
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
goto yyerrorlab;
-#endif
-yyvsp -= yylen;
- yyssp -= yylen;
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
@@ -1985,8 +2271,9 @@ yyerrlab1:
YYABORT;
- yydestruct ("Error: popping", yystos[yystate], yyvsp);
- YYPOPSTACK;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
@@ -1997,7 +2284,7 @@ yyerrlab1:
*++yyvsp = yylval;
- /* Shift the error token. */
+ /* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
yystate = yyn;
@@ -2015,32 +2302,47 @@ yyacceptlab:
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
- yydestruct ("Error: discarding lookahead",
- yytoken, &yylval);
- yychar = YYEMPTY;
yyresult = 1;
goto yyreturn;
#ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here. |
-`----------------------------------------------*/
-yyoverflowlab:
- yyerror ("parser stack overflow");
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
- return yyresult;
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
}
-#line 464 "scripts/genksyms/parse.y"
+#line 467 "scripts/genksyms/parse.y"
static void
diff --git a/scripts/genksyms/parse.h_shipped b/scripts/genksyms/parse.h_shipped
index f3fb2bb058e..c4eeec652b7 100644
--- a/scripts/genksyms/parse.h_shipped
+++ b/scripts/genksyms/parse.h_shipped
@@ -1,7 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.0. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, 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
@@ -15,13 +17,21 @@
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. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -38,39 +48,41 @@
DOUBLE_KEYW = 264,
ENUM_KEYW = 265,
EXTERN_KEYW = 266,
- FLOAT_KEYW = 267,
- INLINE_KEYW = 268,
- INT_KEYW = 269,
- LONG_KEYW = 270,
- REGISTER_KEYW = 271,
- RESTRICT_KEYW = 272,
- SHORT_KEYW = 273,
- SIGNED_KEYW = 274,
- STATIC_KEYW = 275,
- STRUCT_KEYW = 276,
- TYPEDEF_KEYW = 277,
- UNION_KEYW = 278,
- UNSIGNED_KEYW = 279,
- VOID_KEYW = 280,
- VOLATILE_KEYW = 281,
- TYPEOF_KEYW = 282,
- EXPORT_SYMBOL_KEYW = 283,
- ASM_PHRASE = 284,
- ATTRIBUTE_PHRASE = 285,
- BRACE_PHRASE = 286,
- BRACKET_PHRASE = 287,
- EXPRESSION_PHRASE = 288,
- CHAR = 289,
- DOTS = 290,
- IDENT = 291,
- INT = 292,
- REAL = 293,
- STRING = 294,
- TYPE = 295,
- OTHER = 296,
- FILENAME = 297
+ EXTENSION_KEYW = 267,
+ FLOAT_KEYW = 268,
+ INLINE_KEYW = 269,
+ INT_KEYW = 270,
+ LONG_KEYW = 271,
+ REGISTER_KEYW = 272,
+ RESTRICT_KEYW = 273,
+ SHORT_KEYW = 274,
+ SIGNED_KEYW = 275,
+ STATIC_KEYW = 276,
+ STRUCT_KEYW = 277,
+ TYPEDEF_KEYW = 278,
+ UNION_KEYW = 279,
+ UNSIGNED_KEYW = 280,
+ VOID_KEYW = 281,
+ VOLATILE_KEYW = 282,
+ TYPEOF_KEYW = 283,
+ EXPORT_SYMBOL_KEYW = 284,
+ ASM_PHRASE = 285,
+ ATTRIBUTE_PHRASE = 286,
+ BRACE_PHRASE = 287,
+ BRACKET_PHRASE = 288,
+ EXPRESSION_PHRASE = 289,
+ CHAR = 290,
+ DOTS = 291,
+ IDENT = 292,
+ INT = 293,
+ REAL = 294,
+ STRING = 295,
+ TYPE = 296,
+ OTHER = 297,
+ FILENAME = 298
};
#endif
+/* Tokens. */
#define ASM_KEYW 258
#define ATTRIBUTE_KEYW 259
#define AUTO_KEYW 260
@@ -80,42 +92,43 @@
#define DOUBLE_KEYW 264
#define ENUM_KEYW 265
#define EXTERN_KEYW 266
-#define FLOAT_KEYW 267
-#define INLINE_KEYW 268
-#define INT_KEYW 269
-#define LONG_KEYW 270
-#define REGISTER_KEYW 271
-#define RESTRICT_KEYW 272
-#define SHORT_KEYW 273
-#define SIGNED_KEYW 274
-#define STATIC_KEYW 275
-#define STRUCT_KEYW 276
-#define TYPEDEF_KEYW 277
-#define UNION_KEYW 278
-#define UNSIGNED_KEYW 279
-#define VOID_KEYW 280
-#define VOLATILE_KEYW 281
-#define TYPEOF_KEYW 282
-#define EXPORT_SYMBOL_KEYW 283
-#define ASM_PHRASE 284
-#define ATTRIBUTE_PHRASE 285
-#define BRACE_PHRASE 286
-#define BRACKET_PHRASE 287
-#define EXPRESSION_PHRASE 288
-#define CHAR 289
-#define DOTS 290
-#define IDENT 291
-#define INT 292
-#define REAL 293
-#define STRING 294
-#define TYPE 295
-#define OTHER 296
-#define FILENAME 297
+#define EXTENSION_KEYW 267
+#define FLOAT_KEYW 268
+#define INLINE_KEYW 269
+#define INT_KEYW 270
+#define LONG_KEYW 271
+#define REGISTER_KEYW 272
+#define RESTRICT_KEYW 273
+#define SHORT_KEYW 274
+#define SIGNED_KEYW 275
+#define STATIC_KEYW 276
+#define STRUCT_KEYW 277
+#define TYPEDEF_KEYW 278
+#define UNION_KEYW 279
+#define UNSIGNED_KEYW 280
+#define VOID_KEYW 281
+#define VOLATILE_KEYW 282
+#define TYPEOF_KEYW 283
+#define EXPORT_SYMBOL_KEYW 284
+#define ASM_PHRASE 285
+#define ATTRIBUTE_PHRASE 286
+#define BRACE_PHRASE 287
+#define BRACKET_PHRASE 288
+#define EXPRESSION_PHRASE 289
+#define CHAR 290
+#define DOTS 291
+#define IDENT 292
+#define INT 293
+#define REAL 294
+#define STRING 295
+#define TYPE 296
+#define OTHER 297
+#define FILENAME 298
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -124,5 +137,3 @@ typedef int YYSTYPE;
extern YYSTYPE yylval;
-
-
diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y
index ca04c944b7c..408cdf82b27 100644
--- a/scripts/genksyms/parse.y
+++ b/scripts/genksyms/parse.y
@@ -61,6 +61,7 @@ remove_list(struct string_list **pb, struct string_list **pe)
%token DOUBLE_KEYW
%token ENUM_KEYW
%token EXTERN_KEYW
+%token EXTENSION_KEYW
%token FLOAT_KEYW
%token INLINE_KEYW
%token INT_KEYW
@@ -110,7 +111,9 @@ declaration:
;
declaration1:
- TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
+ EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
+ { $$ = $4; }
+ | TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
{ $$ = $3; }
| simple_declaration
| function_definition
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 8986a48c8c4..bb08069b04a 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -143,14 +143,8 @@ clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
.tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
clean-files += mconf qconf gconf
-# Needed for systems without gettext
-KBUILD_HAVE_NLS := $(shell \
- if echo "\#include <libintl.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
- then echo yes ; \
- else echo no ; fi)
-ifeq ($(KBUILD_HAVE_NLS),no)
-HOSTCFLAGS += -DKBUILD_NO_NLS
-endif
+# Add environment specific flags
+HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(srctree)/$(src)/check.sh $(HOSTCC) $(HOSTCFLAGS))
# generated files seem to need this to find local include files
HOSTCFLAGS_lex.zconf.o := -I$(src)
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
new file mode 100755
index 00000000000..fa59cbf9d62
--- /dev/null
+++ b/scripts/kconfig/check.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Needed for systems without gettext
+$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+#include <libintl.h>
+int main()
+{
+ gettext("");
+ return 0;
+}
+EOF
+if [ ! "$?" -eq "0" ]; then
+ echo -DKBUILD_NO_NLS;
+fi
+
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 0fdc9049296..a065d5a57c0 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -5,6 +5,25 @@
/* A lexical scanner generated by flex */
+#define yy_create_buffer zconf_create_buffer
+#define yy_delete_buffer zconf_delete_buffer
+#define yy_flex_debug zconf_flex_debug
+#define yy_init_buffer zconf_init_buffer
+#define yy_flush_buffer zconf_flush_buffer
+#define yy_load_buffer_state zconf_load_buffer_state
+#define yy_switch_to_buffer zconf_switch_to_buffer
+#define yyin zconfin
+#define yyleng zconfleng
+#define yylex zconflex
+#define yylineno zconflineno
+#define yyout zconfout
+#define yyrestart zconfrestart
+#define yytext zconftext
+#define yywrap zconfwrap
+#define yyalloc zconfalloc
+#define yyrealloc zconfrealloc
+#define yyfree zconffree
+
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
@@ -33,7 +52,7 @@
#if __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
+ * if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
@@ -335,7 +354,7 @@ void zconffree (void * );
/* Begin user sect3 */
-#define zconfwrap() 1
+#define zconfwrap(n) 1
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
@@ -1983,7 +2002,7 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to zconflex() will
* scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
+ * @param str a NUL-terminated string to scan
*
* @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index bc5854ed605..47e226fdedd 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -35,9 +35,13 @@ static const char mconf_readme[] = N_(
"kernel parameters which are not really features, but must be\n"
"entered in as decimal or hexadecimal numbers or possibly text.\n"
"\n"
-"Menu items beginning with [*], <M> or [ ] represent features\n"
-"configured to be built in, modularized or removed respectively.\n"
-"Pointed brackets <> represent module capable features.\n"
+"Menu items beginning with following braces represent features that\n"
+" [ ] can be built in or removed\n"
+" < > can be built in, modularized or removed\n"
+" { } can be built in or modularized (selected by other feature)\n"
+" - - are selected by other feature,\n"
+"while *, M or whitespace inside braces means to build in, build as\n"
+"a module or to exclude the feature respectively.\n"
"\n"
"To change any of these features, highlight it with the cursor\n"
"keys and press <Y> to build it in, <M> to make it a module or\n"
@@ -357,8 +361,9 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym)
bool hit;
struct property *prop;
- str_printf(r, "Symbol: %s [=%s]\n", sym->name,
- sym_get_string_value(sym));
+ if (sym && sym->name)
+ str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+ sym_get_string_value(sym));
for_all_prompts(sym, prop)
get_prompt_str(r, prop);
hit = false;
@@ -481,6 +486,14 @@ static void build_conf(struct menu *menu)
if (single_menu_mode && menu->data)
goto conf_childs;
return;
+ case P_COMMENT:
+ if (prompt) {
+ child_count++;
+ item_make(" %*c*** %s ***", indent + 1, ' ', prompt);
+ item_set_tag(':');
+ item_set_data(menu);
+ }
+ break;
default:
if (prompt) {
child_count++;
@@ -560,7 +573,7 @@ static void build_conf(struct menu *menu)
if (sym_is_changable(sym))
item_make("[%c]", val == no ? ' ' : '*');
else
- item_make("---");
+ item_make("-%c-", val == no ? ' ' : '*');
item_set_tag('t');
item_set_data(menu);
break;
@@ -570,10 +583,13 @@ static void build_conf(struct menu *menu)
case mod: ch = 'M'; break;
default: ch = ' '; break;
}
- if (sym_is_changable(sym))
- item_make("<%c>", ch);
- else
- item_make("---");
+ if (sym_is_changable(sym)) {
+ if (sym->rev_dep.tri == mod)
+ item_make("{%c}", ch);
+ else
+ item_make("<%c>", ch);
+ } else
+ item_make("-%c-", ch);
item_set_tag('t');
item_set_data(menu);
break;
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index f9d0d91a3fe..7bfa181d6ed 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -235,16 +235,23 @@ void menu_finalize(struct menu *parent)
sym = parent->sym;
if (parent->list) {
if (sym && sym_is_choice(sym)) {
- /* find the first choice value and find out choice type */
+ /* find out choice type */
+ enum symbol_type type = S_UNKNOWN;
+
for (menu = parent->list; menu; menu = menu->next) {
- if (menu->sym) {
- current_entry = parent;
- menu_set_type(menu->sym->type);
- current_entry = menu;
- menu_set_type(sym->type);
- break;
+ 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;
+ }
}
}
+ current_entry = parent;
+ menu_set_type(type);
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
parentdep = parent->prompt->visible.expr;
@@ -253,7 +260,16 @@ void menu_finalize(struct menu *parent)
for (menu = parent->list; menu; menu = menu->next) {
basedep = expr_transform(menu->dep);
- basedep = expr_alloc_and(expr_copy(parentdep), basedep);
+ 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_eliminate_dups(basedep);
menu->dep = basedep;
if (menu->sym)
@@ -326,7 +342,8 @@ void menu_finalize(struct menu *parent)
"values not supported");
}
current_entry = menu;
- menu_set_type(sym->type);
+ if (menu->sym->type == S_UNKNOWN)
+ 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/util.c b/scripts/kconfig/util.c
index e3f28b9d59f..e1cad924c0a 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -84,12 +84,15 @@ void str_free(struct gstr *gs)
/* Append to growable string */
void str_append(struct gstr *gs, const char *s)
{
- size_t l = strlen(gs->s) + strlen(s) + 1;
- if (l > gs->len) {
- gs->s = realloc(gs->s, l);
- gs->len = l;
+ size_t l;
+ if (s) {
+ l = strlen(gs->s) + strlen(s) + 1;
+ if (l > gs->len) {
+ gs->s = realloc(gs->s, l);
+ gs->len = l;
+ }
+ strcat(gs->s, s);
}
- strcat(gs->s, s);
}
/* Append printf formatted string to growable string */
diff --git a/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf
index 9b44c80dd89..93538e567bd 100644
--- a/scripts/kconfig/zconf.gperf
+++ b/scripts/kconfig/zconf.gperf
@@ -23,7 +23,6 @@ help, T_HELP, TF_COMMAND
if, T_IF, TF_COMMAND|TF_PARAM
endif, T_ENDIF, TF_COMMAND
depends, T_DEPENDS, TF_COMMAND
-requires, T_REQUIRES, TF_COMMAND
optional, T_OPTIONAL, TF_COMMAND
default, T_DEFAULT, TF_COMMAND, S_UNKNOWN
prompt, T_PROMPT, TF_COMMAND
@@ -32,7 +31,6 @@ def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE
bool, T_TYPE, TF_COMMAND, S_BOOLEAN
boolean, T_TYPE, TF_COMMAND, S_BOOLEAN
def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN
-def_boolean, T_DEFAULT, TF_COMMAND, S_BOOLEAN
int, T_TYPE, TF_COMMAND, S_INT
hex, T_TYPE, TF_COMMAND, S_HEX
string, T_TYPE, TF_COMMAND, S_STRING
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index 47c8b5babf3..ab28b18153a 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.1 */
+/* ANSI-C code produced by gperf version 3.0.2 */
/* Command-line: gperf */
/* Computed positions: -k'1,3' */
@@ -30,7 +30,7 @@
#endif
struct kconf_id;
-/* maximum key range = 45, duplicates = 0 */
+/* maximum key range = 47, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -44,32 +44,32 @@ kconf_id_hash (register const char *str, register unsigned int len)
{
static unsigned char asso_values[] =
{
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 25, 30, 15,
- 0, 15, 0, 47, 5, 15, 47, 47, 30, 20,
- 5, 0, 25, 15, 0, 0, 10, 35, 47, 47,
- 5, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 47, 47, 47, 47, 47
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 18, 11, 5,
+ 0, 0, 5, 49, 5, 20, 49, 49, 5, 20,
+ 5, 0, 30, 49, 0, 15, 0, 10, 49, 49,
+ 25, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49
};
register int hval = len;
@@ -89,74 +89,70 @@ kconf_id_hash (register const char *str, register unsigned int len)
struct kconf_id_strings_t
{
char kconf_id_strings_str2[sizeof("on")];
- char kconf_id_strings_str6[sizeof("string")];
- char kconf_id_strings_str7[sizeof("default")];
- char kconf_id_strings_str8[sizeof("def_bool")];
+ char kconf_id_strings_str5[sizeof("endif")];
+ char kconf_id_strings_str6[sizeof("option")];
+ char kconf_id_strings_str7[sizeof("endmenu")];
+ char kconf_id_strings_str8[sizeof("optional")];
+ char kconf_id_strings_str9[sizeof("endchoice")];
char kconf_id_strings_str10[sizeof("range")];
- char kconf_id_strings_str11[sizeof("def_boolean")];
- char kconf_id_strings_str12[sizeof("def_tristate")];
- char kconf_id_strings_str13[sizeof("hex")];
- char kconf_id_strings_str14[sizeof("defconfig_list")];
- char kconf_id_strings_str16[sizeof("option")];
- char kconf_id_strings_str17[sizeof("if")];
- char kconf_id_strings_str18[sizeof("optional")];
- char kconf_id_strings_str20[sizeof("endif")];
- char kconf_id_strings_str21[sizeof("choice")];
- char kconf_id_strings_str22[sizeof("endmenu")];
- char kconf_id_strings_str23[sizeof("requires")];
- char kconf_id_strings_str24[sizeof("endchoice")];
- char kconf_id_strings_str26[sizeof("config")];
+ char kconf_id_strings_str11[sizeof("choice")];
+ char kconf_id_strings_str12[sizeof("default")];
+ char kconf_id_strings_str13[sizeof("def_bool")];
+ char kconf_id_strings_str14[sizeof("help")];
+ char kconf_id_strings_str15[sizeof("bool")];
+ char kconf_id_strings_str16[sizeof("config")];
+ char kconf_id_strings_str17[sizeof("def_tristate")];
+ char kconf_id_strings_str18[sizeof("boolean")];
+ char kconf_id_strings_str19[sizeof("defconfig_list")];
+ char kconf_id_strings_str21[sizeof("string")];
+ char kconf_id_strings_str22[sizeof("if")];
+ char kconf_id_strings_str23[sizeof("int")];
+ char kconf_id_strings_str24[sizeof("enable")];
+ char kconf_id_strings_str26[sizeof("select")];
char kconf_id_strings_str27[sizeof("modules")];
- char kconf_id_strings_str28[sizeof("int")];
+ char kconf_id_strings_str28[sizeof("tristate")];
char kconf_id_strings_str29[sizeof("menu")];
- char kconf_id_strings_str31[sizeof("prompt")];
- char kconf_id_strings_str32[sizeof("depends")];
- char kconf_id_strings_str33[sizeof("tristate")];
- char kconf_id_strings_str34[sizeof("bool")];
+ char kconf_id_strings_str31[sizeof("source")];
+ char kconf_id_strings_str32[sizeof("comment")];
+ char kconf_id_strings_str33[sizeof("hex")];
char kconf_id_strings_str35[sizeof("menuconfig")];
- char kconf_id_strings_str36[sizeof("select")];
- char kconf_id_strings_str37[sizeof("boolean")];
- char kconf_id_strings_str39[sizeof("help")];
- char kconf_id_strings_str41[sizeof("source")];
- char kconf_id_strings_str42[sizeof("comment")];
- char kconf_id_strings_str43[sizeof("mainmenu")];
- char kconf_id_strings_str46[sizeof("enable")];
+ char kconf_id_strings_str36[sizeof("prompt")];
+ char kconf_id_strings_str37[sizeof("depends")];
+ char kconf_id_strings_str48[sizeof("mainmenu")];
};
static struct kconf_id_strings_t kconf_id_strings_contents =
{
"on",
- "string",
+ "endif",
+ "option",
+ "endmenu",
+ "optional",
+ "endchoice",
+ "range",
+ "choice",
"default",
"def_bool",
- "range",
- "def_boolean",
+ "help",
+ "bool",
+ "config",
"def_tristate",
- "hex",
+ "boolean",
"defconfig_list",
- "option",
+ "string",
"if",
- "optional",
- "endif",
- "choice",
- "endmenu",
- "requires",
- "endchoice",
- "config",
- "modules",
"int",
- "menu",
- "prompt",
- "depends",
- "tristate",
- "bool",
- "menuconfig",
+ "enable",
"select",
- "boolean",
- "help",
+ "modules",
+ "tristate",
+ "menu",
"source",
"comment",
- "mainmenu",
- "enable"
+ "hex",
+ "menuconfig",
+ "prompt",
+ "depends",
+ "mainmenu"
};
#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
#ifdef __GNUC__
@@ -167,58 +163,54 @@ kconf_id_lookup (register const char *str, register unsigned int len)
{
enum
{
- TOTAL_KEYWORDS = 33,
+ TOTAL_KEYWORDS = 31,
MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 14,
MIN_HASH_VALUE = 2,
- MAX_HASH_VALUE = 46
+ MAX_HASH_VALUE = 48
};
static struct kconf_id wordlist[] =
{
{-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
- {-1}, {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_TYPE, TF_COMMAND, S_STRING},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
- {-1},
+ {-1}, {-1},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_OPTION, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_OPTIONAL, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_TYPE, TF_COMMAND, S_HEX},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION},
- {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_OPTION, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_IF, TF_COMMAND|TF_PARAM},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_CHOICE, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_HELP, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str15, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_CONFIG, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str19, T_OPT_DEFCONFIG_LIST,TF_OPTION},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_ENDIF, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CHOICE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_REQUIRES, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24, T_ENDCHOICE, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_TYPE, TF_COMMAND, S_STRING},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_IF, TF_COMMAND|TF_PARAM},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_INT},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24, T_SELECT, TF_COMMAND},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_CONFIG, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SELECT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_INT},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_TRISTATE},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_PROMPT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_DEPENDS, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_TRISTATE},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_SELECT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SOURCE, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_HEX},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_HELP, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_PROMPT, TF_COMMAND},
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_DEPENDS, TF_COMMAND},
+ {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_COMMENT, TF_COMMAND},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_MAINMENU, TF_COMMAND},
- {-1}, {-1},
- {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND}
+ {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str48, T_MAINMENU, TF_COMMAND}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index ec21db77f78..d22d92496f2 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -1,7 +1,9 @@
-/* A Bison parser, made by GNU Bison 2.1. */
+/* A Bison parser, made by GNU Bison 2.3. */
-/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, 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
@@ -18,13 +20,21 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
-/* Written by Richard Stallman by simplifying the original so called
- ``semantic'' parser. */
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
@@ -37,7 +47,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.1"
+#define YYBISON_VERSION "2.3"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -78,25 +88,24 @@
T_IF = 269,
T_ENDIF = 270,
T_DEPENDS = 271,
- T_REQUIRES = 272,
- T_OPTIONAL = 273,
- T_PROMPT = 274,
- T_TYPE = 275,
- T_DEFAULT = 276,
- T_SELECT = 277,
- T_RANGE = 278,
- T_OPTION = 279,
- T_ON = 280,
- T_WORD = 281,
- T_WORD_QUOTE = 282,
- T_UNEQUAL = 283,
- T_CLOSE_PAREN = 284,
- T_OPEN_PAREN = 285,
- T_EOL = 286,
- T_OR = 287,
- T_AND = 288,
- T_EQUAL = 289,
- T_NOT = 290
+ T_OPTIONAL = 272,
+ T_PROMPT = 273,
+ T_TYPE = 274,
+ T_DEFAULT = 275,
+ T_SELECT = 276,
+ T_RANGE = 277,
+ T_OPTION = 278,
+ T_ON = 279,
+ T_WORD = 280,
+ T_WORD_QUOTE = 281,
+ T_UNEQUAL = 282,
+ T_CLOSE_PAREN = 283,
+ T_OPEN_PAREN = 284,
+ T_EOL = 285,
+ T_OR = 286,
+ T_AND = 287,
+ T_EQUAL = 288,
+ T_NOT = 289
};
#endif
/* Tokens. */
@@ -114,25 +123,24 @@
#define T_IF 269
#define T_ENDIF 270
#define T_DEPENDS 271
-#define T_REQUIRES 272
-#define T_OPTIONAL 273
-#define T_PROMPT 274
-#define T_TYPE 275
-#define T_DEFAULT 276
-#define T_SELECT 277
-#define T_RANGE 278
-#define T_OPTION 279
-#define T_ON 280
-#define T_WORD 281
-#define T_WORD_QUOTE 282
-#define T_UNEQUAL 283
-#define T_CLOSE_PAREN 284
-#define T_OPEN_PAREN 285
-#define T_EOL 286
-#define T_OR 287
-#define T_AND 288
-#define T_EQUAL 289
-#define T_NOT 290
+#define T_OPTIONAL 272
+#define T_PROMPT 273
+#define T_TYPE 274
+#define T_DEFAULT 275
+#define T_SELECT 276
+#define T_RANGE 277
+#define T_OPTION 278
+#define T_ON 279
+#define T_WORD 280
+#define T_WORD_QUOTE 281
+#define T_UNEQUAL 282
+#define T_CLOSE_PAREN 283
+#define T_OPEN_PAREN 284
+#define T_EOL 285
+#define T_OR 286
+#define T_AND 287
+#define T_EQUAL 288
+#define T_NOT 289
@@ -198,18 +206,20 @@ static struct menu *current_menu, *current_entry;
# define YYTOKEN_TABLE 0
#endif
-#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
-typedef union YYSTYPE {
+{
char *string;
struct file *file;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
struct kconf_id *id;
-} YYSTYPE;
-/* Line 196 of yacc.c. */
+}
+/* Line 187 of yacc.c. */
+ YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
@@ -220,23 +230,56 @@ typedef union YYSTYPE {
/* Copy the second part of user declarations. */
-/* Line 219 of yacc.c. */
+/* Line 216 of yacc.c. */
+
+
+#ifdef short
+# undef short
+#endif
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
#endif
-#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
#endif
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
#ifndef YY_
# if YYENABLE_NLS
# if ENABLE_NLS
@@ -249,7 +292,32 @@ typedef union YYSTYPE {
# endif
#endif
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -257,64 +325,76 @@ typedef union YYSTYPE {
# if YYSTACK_USE_ALLOCA
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if defined (__STDC__) || defined (__cplusplus)
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYINCLUDED_STDLIB_H
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
- /* Pacify GCC's `empty if-body' warning. */
-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
# ifndef YYSTACK_ALLOC_MAXIMUM
/* The OS might guarantee only one guard page at the bottom of the stack,
and a page size can be as small as 4096 bytes. So we cannot safely
invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
to allow for a few compiler-allocated temporary stack slots. */
-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
# endif
# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
# ifndef YYSTACK_ALLOC_MAXIMUM
-# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# ifdef __cplusplus
-extern "C" {
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
- && (defined (__STDC__) || defined (__cplusplus)))
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
- && (defined (__STDC__) || defined (__cplusplus)))
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
-# ifdef __cplusplus
-}
-# endif
# endif
-#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-#if (! defined (yyoverflow) \
- && (! defined (__cplusplus) \
- || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short int yyss;
+ yytype_int16 yyss;
YYSTYPE yyvs;
};
@@ -324,13 +404,13 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
-# if defined (__GNUC__) && 1 < __GNUC__
+# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
@@ -341,7 +421,7 @@ union yyalloc
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
- while (0)
+ while (YYID (0))
# endif
# endif
@@ -359,39 +439,33 @@ union yyalloc
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
- while (0)
+ while (YYID (0))
#endif
-#if defined (__STDC__) || defined (__cplusplus)
- typedef signed char yysigned_char;
-#else
- typedef short int yysigned_char;
-#endif
-
-/* YYFINAL -- State number of the termination state. */
+/* YYFINAL -- State number of the termination state. */
#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 275
+#define YYLAST 258
-/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 36
-/* YYNNTS -- Number of nonterminals. */
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 35
+/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 45
-/* YYNRULES -- Number of rules. */
-#define YYNRULES 110
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 183
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 108
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 178
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 290
+#define YYMAXUTOK 289
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
+static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -421,14 +495,13 @@ static const unsigned char yytranslate[] =
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
};
#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
YYRHS. */
-static const unsigned short int yyprhs[] =
+static const yytype_uint16 yyprhs[] =
{
0, 0, 3, 5, 6, 9, 12, 15, 20, 23,
28, 33, 37, 39, 41, 43, 45, 47, 49, 51,
@@ -439,80 +512,77 @@ static const unsigned short int yyprhs[] =
178, 181, 186, 187, 190, 194, 196, 200, 201, 204,
207, 210, 214, 217, 219, 223, 224, 227, 230, 233,
237, 241, 244, 247, 250, 251, 254, 257, 260, 265,
- 269, 273, 274, 277, 279, 281, 284, 287, 290, 292,
- 295, 296, 299, 301, 305, 309, 313, 316, 320, 324,
- 326
+ 266, 269, 271, 273, 276, 279, 282, 284, 287, 288,
+ 291, 293, 297, 301, 305, 308, 312, 316, 318
};
-/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
{
- 37, 0, -1, 38, -1, -1, 38, 40, -1, 38,
- 54, -1, 38, 65, -1, 38, 3, 75, 77, -1,
- 38, 76, -1, 38, 26, 1, 31, -1, 38, 39,
- 1, 31, -1, 38, 1, 31, -1, 16, -1, 19,
- -1, 20, -1, 22, -1, 18, -1, 23, -1, 21,
- -1, 31, -1, 60, -1, 69, -1, 43, -1, 45,
- -1, 67, -1, 26, 1, 31, -1, 1, 31, -1,
- 10, 26, 31, -1, 42, 46, -1, 11, 26, 31,
- -1, 44, 46, -1, -1, 46, 47, -1, 46, 48,
- -1, 46, 73, -1, 46, 71, -1, 46, 41, -1,
- 46, 31, -1, 20, 74, 31, -1, 19, 75, 78,
- 31, -1, 21, 79, 78, 31, -1, 22, 26, 78,
- 31, -1, 23, 80, 80, 78, 31, -1, 24, 49,
- 31, -1, -1, 49, 26, 50, -1, -1, 34, 75,
- -1, 7, 31, -1, 51, 55, -1, 76, -1, 52,
- 57, 53, -1, -1, 55, 56, -1, 55, 73, -1,
- 55, 71, -1, 55, 31, -1, 55, 41, -1, 19,
- 75, 78, 31, -1, 20, 74, 31, -1, 18, 31,
- -1, 21, 26, 78, 31, -1, -1, 57, 40, -1,
- 14, 79, 77, -1, 76, -1, 58, 61, 59, -1,
- -1, 61, 40, -1, 61, 65, -1, 61, 54, -1,
- 4, 75, 31, -1, 62, 72, -1, 76, -1, 63,
- 66, 64, -1, -1, 66, 40, -1, 66, 65, -1,
- 66, 54, -1, 6, 75, 31, -1, 9, 75, 31,
- -1, 68, 72, -1, 12, 31, -1, 70, 13, -1,
- -1, 72, 73, -1, 72, 31, -1, 72, 41, -1,
- 16, 25, 79, 31, -1, 16, 79, 31, -1, 17,
- 79, 31, -1, -1, 75, 78, -1, 26, -1, 27,
- -1, 5, 31, -1, 8, 31, -1, 15, 31, -1,
- 31, -1, 77, 31, -1, -1, 14, 79, -1, 80,
- -1, 80, 34, 80, -1, 80, 28, 80, -1, 30,
- 79, 29, -1, 35, 79, -1, 79, 32, 79, -1,
- 79, 33, 79, -1, 26, -1, 27, -1
+ 36, 0, -1, 37, -1, -1, 37, 39, -1, 37,
+ 53, -1, 37, 64, -1, 37, 3, 74, 76, -1,
+ 37, 75, -1, 37, 25, 1, 30, -1, 37, 38,
+ 1, 30, -1, 37, 1, 30, -1, 16, -1, 18,
+ -1, 19, -1, 21, -1, 17, -1, 22, -1, 20,
+ -1, 30, -1, 59, -1, 68, -1, 42, -1, 44,
+ -1, 66, -1, 25, 1, 30, -1, 1, 30, -1,
+ 10, 25, 30, -1, 41, 45, -1, 11, 25, 30,
+ -1, 43, 45, -1, -1, 45, 46, -1, 45, 47,
+ -1, 45, 72, -1, 45, 70, -1, 45, 40, -1,
+ 45, 30, -1, 19, 73, 30, -1, 18, 74, 77,
+ 30, -1, 20, 78, 77, 30, -1, 21, 25, 77,
+ 30, -1, 22, 79, 79, 77, 30, -1, 23, 48,
+ 30, -1, -1, 48, 25, 49, -1, -1, 33, 74,
+ -1, 7, 30, -1, 50, 54, -1, 75, -1, 51,
+ 56, 52, -1, -1, 54, 55, -1, 54, 72, -1,
+ 54, 70, -1, 54, 30, -1, 54, 40, -1, 18,
+ 74, 77, 30, -1, 19, 73, 30, -1, 17, 30,
+ -1, 20, 25, 77, 30, -1, -1, 56, 39, -1,
+ 14, 78, 76, -1, 75, -1, 57, 60, 58, -1,
+ -1, 60, 39, -1, 60, 64, -1, 60, 53, -1,
+ 4, 74, 30, -1, 61, 71, -1, 75, -1, 62,
+ 65, 63, -1, -1, 65, 39, -1, 65, 64, -1,
+ 65, 53, -1, 6, 74, 30, -1, 9, 74, 30,
+ -1, 67, 71, -1, 12, 30, -1, 69, 13, -1,
+ -1, 71, 72, -1, 71, 30, -1, 71, 40, -1,
+ 16, 24, 78, 30, -1, -1, 74, 77, -1, 25,
+ -1, 26, -1, 5, 30, -1, 8, 30, -1, 15,
+ 30, -1, 30, -1, 76, 30, -1, -1, 14, 78,
+ -1, 79, -1, 79, 33, 79, -1, 79, 27, 79,
+ -1, 29, 78, 28, -1, 34, 78, -1, 78, 31,
+ 78, -1, 78, 32, 78, -1, 25, -1, 26, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short int yyrline[] =
+static const yytype_uint16 yyrline[] =
{
- 0, 105, 105, 107, 109, 110, 111, 112, 113, 114,
- 115, 119, 123, 123, 123, 123, 123, 123, 123, 127,
- 128, 129, 130, 131, 132, 136, 137, 143, 151, 157,
- 165, 175, 177, 178, 179, 180, 181, 182, 185, 193,
- 199, 209, 215, 221, 224, 226, 237, 238, 243, 252,
- 257, 265, 268, 270, 271, 272, 273, 274, 277, 283,
- 294, 300, 310, 312, 317, 325, 333, 336, 338, 339,
- 340, 345, 352, 357, 365, 368, 370, 371, 372, 375,
- 383, 390, 397, 403, 410, 412, 413, 414, 417, 422,
- 427, 435, 437, 442, 443, 446, 447, 448, 452, 453,
- 456, 457, 460, 461, 462, 463, 464, 465, 466, 469,
- 470
+ 0, 104, 104, 106, 108, 109, 110, 111, 112, 113,
+ 114, 118, 122, 122, 122, 122, 122, 122, 122, 126,
+ 127, 128, 129, 130, 131, 135, 136, 142, 150, 156,
+ 164, 174, 176, 177, 178, 179, 180, 181, 184, 192,
+ 198, 208, 214, 220, 223, 225, 236, 237, 242, 251,
+ 256, 264, 267, 269, 270, 271, 272, 273, 276, 282,
+ 293, 299, 309, 311, 316, 324, 332, 335, 337, 338,
+ 339, 344, 351, 356, 364, 367, 369, 370, 371, 374,
+ 382, 389, 396, 402, 409, 411, 412, 413, 416, 424,
+ 426, 431, 432, 435, 436, 437, 441, 442, 445, 446,
+ 449, 450, 451, 452, 453, 454, 455, 458, 459
};
#endif
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
"$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
"T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
"T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
- "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
- "T_SELECT", "T_RANGE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE",
- "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND",
- "T_EQUAL", "T_NOT", "$accept", "input", "stmt_list", "option_name",
- "common_stmt", "option_error", "config_entry_start", "config_stmt",
+ "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT", "T_SELECT", "T_RANGE",
+ "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE", "T_UNEQUAL",
+ "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND", "T_EQUAL",
+ "T_NOT", "$accept", "input", "stmt_list", "option_name", "common_stmt",
+ "option_error", "config_entry_start", "config_stmt",
"menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
"config_option", "symbol_option", "symbol_option_list",
"symbol_option_arg", "choice", "choice_entry", "choice_end",
@@ -527,34 +597,33 @@ static const char *const yytname[] =
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short int yytoknum[] =
+static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
- 285, 286, 287, 288, 289, 290
+ 285, 286, 287, 288, 289
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const unsigned char yyr1[] =
+static const yytype_uint8 yyr1[] =
{
- 0, 36, 37, 38, 38, 38, 38, 38, 38, 38,
- 38, 38, 39, 39, 39, 39, 39, 39, 39, 40,
- 40, 40, 40, 40, 40, 41, 41, 42, 43, 44,
- 45, 46, 46, 46, 46, 46, 46, 46, 47, 47,
- 47, 47, 47, 48, 49, 49, 50, 50, 51, 52,
- 53, 54, 55, 55, 55, 55, 55, 55, 56, 56,
- 56, 56, 57, 57, 58, 59, 60, 61, 61, 61,
- 61, 62, 63, 64, 65, 66, 66, 66, 66, 67,
- 68, 69, 70, 71, 72, 72, 72, 72, 73, 73,
- 73, 74, 74, 75, 75, 76, 76, 76, 77, 77,
- 78, 78, 79, 79, 79, 79, 79, 79, 79, 80,
- 80
+ 0, 35, 36, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 38, 38, 38, 38, 38, 38, 38, 39,
+ 39, 39, 39, 39, 39, 40, 40, 41, 42, 43,
+ 44, 45, 45, 45, 45, 45, 45, 45, 46, 46,
+ 46, 46, 46, 47, 48, 48, 49, 49, 50, 51,
+ 52, 53, 54, 54, 54, 54, 54, 54, 55, 55,
+ 55, 55, 56, 56, 57, 58, 59, 60, 60, 60,
+ 60, 61, 62, 63, 64, 65, 65, 65, 65, 66,
+ 67, 68, 69, 70, 71, 71, 71, 71, 72, 73,
+ 73, 74, 74, 75, 75, 75, 76, 76, 77, 77,
+ 78, 78, 78, 78, 78, 78, 78, 79, 79
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
-static const unsigned char yyr2[] =
+static const yytype_uint8 yyr2[] =
{
0, 2, 1, 0, 2, 2, 2, 4, 2, 4,
4, 3, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -564,82 +633,79 @@ static const unsigned char yyr2[] =
1, 3, 0, 2, 2, 2, 2, 2, 4, 3,
2, 4, 0, 2, 3, 1, 3, 0, 2, 2,
2, 3, 2, 1, 3, 0, 2, 2, 2, 3,
- 3, 2, 2, 2, 0, 2, 2, 2, 4, 3,
- 3, 0, 2, 1, 1, 2, 2, 2, 1, 2,
- 0, 2, 1, 3, 3, 3, 2, 3, 3, 1,
- 1
+ 3, 2, 2, 2, 0, 2, 2, 2, 4, 0,
+ 2, 1, 1, 2, 2, 2, 1, 2, 0, 2,
+ 1, 3, 3, 3, 2, 3, 3, 1, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
-static const unsigned char yydefact[] =
+static const yytype_uint8 yydefact[] =
{
3, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 12, 16, 13, 14,
18, 15, 17, 0, 19, 0, 4, 31, 22, 31,
23, 52, 62, 5, 67, 20, 84, 75, 6, 24,
- 84, 21, 8, 11, 93, 94, 0, 0, 95, 0,
- 48, 96, 0, 0, 0, 109, 110, 0, 0, 0,
- 102, 97, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 98, 7, 71, 79, 80, 27, 29, 0,
- 106, 0, 0, 64, 0, 0, 9, 10, 0, 0,
- 0, 0, 0, 91, 0, 0, 0, 44, 0, 37,
- 36, 32, 33, 0, 35, 34, 0, 0, 91, 0,
- 56, 57, 53, 55, 54, 63, 51, 50, 68, 70,
- 66, 69, 65, 86, 87, 85, 76, 78, 74, 77,
- 73, 99, 105, 107, 108, 104, 103, 26, 82, 0,
- 0, 0, 100, 0, 100, 100, 100, 0, 0, 0,
- 83, 60, 100, 0, 100, 0, 89, 90, 0, 0,
- 38, 92, 0, 0, 100, 46, 43, 25, 0, 59,
- 0, 88, 101, 39, 40, 41, 0, 0, 45, 58,
- 61, 42, 47
+ 84, 21, 8, 11, 91, 92, 0, 0, 93, 0,
+ 48, 94, 0, 0, 0, 107, 108, 0, 0, 0,
+ 100, 95, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 96, 7, 71, 79, 80, 27, 29, 0,
+ 104, 0, 0, 64, 0, 0, 9, 10, 0, 0,
+ 0, 0, 89, 0, 0, 0, 44, 0, 37, 36,
+ 32, 33, 0, 35, 34, 0, 0, 89, 0, 56,
+ 57, 53, 55, 54, 63, 51, 50, 68, 70, 66,
+ 69, 65, 86, 87, 85, 76, 78, 74, 77, 73,
+ 97, 103, 105, 106, 102, 101, 26, 82, 0, 98,
+ 0, 98, 98, 98, 0, 0, 0, 83, 60, 98,
+ 0, 98, 0, 0, 0, 38, 90, 0, 0, 98,
+ 46, 43, 25, 0, 59, 0, 88, 99, 39, 40,
+ 41, 0, 0, 45, 58, 61, 42, 47
};
-/* YYDEFGOTO[NTERM-NUM]. */
-static const short int yydefgoto[] =
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
{
- -1, 1, 2, 25, 26, 100, 27, 28, 29, 30,
- 64, 101, 102, 148, 178, 31, 32, 116, 33, 66,
- 112, 67, 34, 120, 35, 68, 36, 37, 128, 38,
- 70, 39, 40, 41, 103, 104, 69, 105, 143, 144,
- 42, 73, 159, 59, 60
+ -1, 1, 2, 25, 26, 99, 27, 28, 29, 30,
+ 64, 100, 101, 145, 173, 31, 32, 115, 33, 66,
+ 111, 67, 34, 119, 35, 68, 36, 37, 127, 38,
+ 70, 39, 40, 41, 102, 103, 69, 104, 140, 141,
+ 42, 73, 154, 59, 60
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -135
-static const short int yypact[] =
+#define YYPACT_NINF -78
+static const yytype_int16 yypact[] =
{
- -135, 2, 170, -135, -14, 56, 56, -8, 56, 24,
- 67, 56, 7, 14, 62, 97, -135, -135, -135, -135,
- -135, -135, -135, 156, -135, 166, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, 138, 151, -135, 152,
- -135, -135, 163, 167, 176, -135, -135, 62, 62, 185,
- -19, -135, 188, 190, 42, 103, 194, 85, 70, 222,
- 70, 132, -135, 191, -135, -135, -135, -135, -135, 127,
- -135, 62, 62, 191, 104, 104, -135, -135, 193, 203,
- 9, 62, 56, 56, 62, 161, 104, -135, 196, -135,
- -135, -135, -135, 233, -135, -135, 204, 56, 56, 221,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, -135,
- -135, -135, -135, 219, -135, -135, -135, -135, -135, 62,
- 209, 212, 240, 224, 240, -1, 240, 104, 41, 225,
- -135, -135, 240, 226, 240, 218, -135, -135, 62, 227,
- -135, -135, 228, 229, 240, 230, -135, -135, 231, -135,
- 232, -135, 112, -135, -135, -135, 234, 56, -135, -135,
- -135, -135, -135
+ -78, 33, 130, -78, -28, 73, 73, 7, 73, 36,
+ 41, 73, 26, 52, -4, 58, -78, -78, -78, -78,
+ -78, -78, -78, 90, -78, 94, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, 74, 85, -78, 96,
+ -78, -78, 131, 134, 147, -78, -78, -4, -4, 193,
+ -10, -78, 162, 164, 38, 102, 64, 148, 5, 192,
+ 5, 165, -78, 174, -78, -78, -78, -78, -78, 65,
+ -78, -4, -4, 174, 103, 103, -78, -78, 175, 185,
+ 197, 73, 73, -4, 194, 103, -78, 231, -78, -78,
+ -78, -78, 220, -78, -78, 204, 73, 73, 210, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -78,
+ -78, -78, 205, -78, -78, -78, -78, -78, -4, 222,
+ 208, 222, 195, 222, 103, 2, 209, -78, -78, 222,
+ 211, 222, 199, -4, 212, -78, -78, 213, 214, 222,
+ 207, -78, -78, 215, -78, 216, -78, 111, -78, -78,
+ -78, 217, 73, -78, -78, -78, -78, -78
};
/* YYPGOTO[NTERM-NUM]. */
-static const short int yypgoto[] =
+static const yytype_int16 yypgoto[] =
{
- -135, -135, -135, -135, 94, -45, -135, -135, -135, -135,
- 237, -135, -135, -135, -135, -135, -135, -135, -54, -135,
- -135, -135, -135, -135, -135, -135, -135, -135, -135, 1,
- -135, -135, -135, -135, -135, 195, 235, -44, 159, -5,
- 98, 210, -134, -53, -77
+ -78, -78, -78, -78, 121, -35, -78, -78, -78, -78,
+ 219, -78, -78, -78, -78, -78, -78, -78, -44, -78,
+ -78, -78, -78, -78, -78, -78, -78, -78, -78, -6,
+ -78, -78, -78, -78, -78, 183, 218, 21, 143, -5,
+ 146, 196, 69, -53, -77
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -647,93 +713,88 @@ static const short int yypgoto[] =
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -82
-static const short int yytable[] =
+static const yytype_int16 yytable[] =
{
- 46, 47, 3, 49, 79, 80, 52, 135, 136, 84,
- 161, 162, 163, 158, 119, 85, 127, 43, 168, 147,
- 170, 111, 114, 48, 124, 125, 124, 125, 133, 134,
- 176, 81, 82, 53, 139, 55, 56, 140, 141, 57,
- 54, 145, -28, 88, 58, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, 89, 50, -28, -28, 90, 91,
- -28, 92, 93, 94, 95, 96, 97, 165, 98, 121,
- 164, 129, 166, 99, 6, 7, 8, 9, 10, 11,
- 12, 13, 44, 45, 14, 15, 155, 142, 55, 56,
- 7, 8, 57, 10, 11, 12, 13, 58, 51, 14,
- 15, 24, 152, -30, 88, 172, -30, -30, -30, -30,
- -30, -30, -30, -30, -30, 89, 24, -30, -30, 90,
- 91, -30, 92, 93, 94, 95, 96, 97, 61, 98,
- 55, 56, -81, 88, 99, -81, -81, -81, -81, -81,
- -81, -81, -81, -81, 81, 82, -81, -81, 90, 91,
- -81, -81, -81, -81, -81, -81, 132, 62, 98, 81,
- 82, 115, 118, 123, 126, 117, 122, 63, 130, 72,
- -2, 4, 182, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 74, 75, 14, 15, 16, 146, 17, 18,
- 19, 20, 21, 22, 76, 88, 23, 149, 77, -49,
- -49, 24, -49, -49, -49, -49, 89, 78, -49, -49,
- 90, 91, 106, 107, 108, 109, 72, 81, 82, 86,
- 98, 87, 131, 88, 137, 110, -72, -72, -72, -72,
- -72, -72, -72, -72, 138, 151, -72, -72, 90, 91,
- 156, 81, 82, 157, 81, 82, 150, 154, 98, 171,
- 81, 82, 82, 123, 158, 160, 167, 169, 173, 174,
- 175, 113, 179, 180, 177, 181, 65, 153, 0, 83,
- 0, 0, 0, 0, 0, 71
+ 46, 47, 43, 49, 79, 80, 52, 134, 135, 6,
+ 7, 8, 9, 10, 11, 12, 13, 84, 144, 14,
+ 15, 55, 56, 85, 118, 57, 126, 160, 132, 133,
+ 58, 110, 161, 3, 123, 24, 123, 48, -28, 88,
+ 142, -28, -28, -28, -28, -28, -28, -28, -28, -28,
+ 89, 53, -28, -28, 90, -28, 91, 92, 93, 94,
+ 95, 96, 120, 97, 128, 88, 50, 159, 98, -49,
+ -49, 51, -49, -49, -49, -49, 89, 54, -49, -49,
+ 90, 105, 106, 107, 108, 152, 139, 113, 61, 97,
+ 124, 62, 124, 131, 109, 63, 81, 82, 44, 45,
+ 167, 149, -30, 88, 72, -30, -30, -30, -30, -30,
+ -30, -30, -30, -30, 89, 74, -30, -30, 90, -30,
+ 91, 92, 93, 94, 95, 96, 75, 97, 55, 56,
+ -2, 4, 98, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 81, 82, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 7, 8, 23, 10, 11, 12, 13,
+ 24, 76, 14, 15, 77, -81, 88, 177, -81, -81,
+ -81, -81, -81, -81, -81, -81, -81, 78, 24, -81,
+ -81, 90, -81, -81, -81, -81, -81, -81, 114, 117,
+ 97, 125, 86, 88, 87, 122, -72, -72, -72, -72,
+ -72, -72, -72, -72, 130, 136, -72, -72, 90, 153,
+ 156, 157, 158, 116, 121, 137, 129, 97, 163, 143,
+ 165, 138, 122, 72, 81, 82, 81, 82, 171, 166,
+ 81, 82, 146, 147, 148, 151, 153, 82, 155, 162,
+ 172, 164, 168, 169, 170, 174, 175, 176, 65, 112,
+ 150, 0, 0, 0, 0, 83, 0, 0, 71
};
-static const short int yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 5, 6, 0, 8, 57, 58, 11, 84, 85, 28,
- 144, 145, 146, 14, 68, 34, 70, 31, 152, 96,
- 154, 66, 66, 31, 69, 69, 71, 71, 81, 82,
- 164, 32, 33, 26, 25, 26, 27, 90, 91, 30,
- 26, 94, 0, 1, 35, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 31, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 26, 26, 68,
- 147, 70, 31, 31, 4, 5, 6, 7, 8, 9,
- 10, 11, 26, 27, 14, 15, 139, 92, 26, 27,
- 5, 6, 30, 8, 9, 10, 11, 35, 31, 14,
- 15, 31, 107, 0, 1, 158, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 31, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 31, 26,
- 26, 27, 0, 1, 31, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 32, 33, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 29, 1, 26, 32,
- 33, 67, 68, 31, 70, 67, 68, 1, 70, 31,
- 0, 1, 177, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 31, 31, 14, 15, 16, 26, 18, 19,
- 20, 21, 22, 23, 31, 1, 26, 1, 31, 5,
- 6, 31, 8, 9, 10, 11, 12, 31, 14, 15,
- 16, 17, 18, 19, 20, 21, 31, 32, 33, 31,
- 26, 31, 31, 1, 31, 31, 4, 5, 6, 7,
- 8, 9, 10, 11, 31, 31, 14, 15, 16, 17,
- 31, 32, 33, 31, 32, 33, 13, 26, 26, 31,
- 32, 33, 33, 31, 14, 31, 31, 31, 31, 31,
- 31, 66, 31, 31, 34, 31, 29, 108, -1, 59,
- -1, -1, -1, -1, -1, 40
+ 5, 6, 30, 8, 57, 58, 11, 84, 85, 4,
+ 5, 6, 7, 8, 9, 10, 11, 27, 95, 14,
+ 15, 25, 26, 33, 68, 29, 70, 25, 81, 82,
+ 34, 66, 30, 0, 69, 30, 71, 30, 0, 1,
+ 93, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 25, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 68, 25, 70, 1, 30, 144, 30, 5,
+ 6, 30, 8, 9, 10, 11, 12, 25, 14, 15,
+ 16, 17, 18, 19, 20, 138, 91, 66, 30, 25,
+ 69, 1, 71, 28, 30, 1, 31, 32, 25, 26,
+ 153, 106, 0, 1, 30, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 30, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 30, 25, 25, 26,
+ 0, 1, 30, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 31, 32, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 5, 6, 25, 8, 9, 10, 11,
+ 30, 30, 14, 15, 30, 0, 1, 172, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 30, 30, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 67, 68,
+ 25, 70, 30, 1, 30, 30, 4, 5, 6, 7,
+ 8, 9, 10, 11, 30, 30, 14, 15, 16, 14,
+ 141, 142, 143, 67, 68, 30, 70, 25, 149, 25,
+ 151, 24, 30, 30, 31, 32, 31, 32, 159, 30,
+ 31, 32, 1, 13, 30, 25, 14, 32, 30, 30,
+ 33, 30, 30, 30, 30, 30, 30, 30, 29, 66,
+ 107, -1, -1, -1, -1, 59, -1, -1, 40
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
-static const unsigned char yystos[] =
+static const yytype_uint8 yystos[] =
{
- 0, 37, 38, 0, 1, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 14, 15, 16, 18, 19, 20,
- 21, 22, 23, 26, 31, 39, 40, 42, 43, 44,
- 45, 51, 52, 54, 58, 60, 62, 63, 65, 67,
- 68, 69, 76, 31, 26, 27, 75, 75, 31, 75,
- 31, 31, 75, 26, 26, 26, 27, 30, 35, 79,
- 80, 31, 1, 1, 46, 46, 55, 57, 61, 72,
- 66, 72, 31, 77, 31, 31, 31, 31, 31, 79,
- 79, 32, 33, 77, 28, 34, 31, 31, 1, 12,
- 16, 17, 19, 20, 21, 22, 23, 24, 26, 31,
- 41, 47, 48, 70, 71, 73, 18, 19, 20, 21,
- 31, 41, 56, 71, 73, 40, 53, 76, 40, 54,
- 59, 65, 76, 31, 41, 73, 40, 54, 64, 65,
- 76, 31, 29, 79, 79, 80, 80, 31, 31, 25,
- 79, 79, 75, 74, 75, 79, 26, 80, 49, 1,
- 13, 31, 75, 74, 26, 79, 31, 31, 14, 78,
- 31, 78, 78, 78, 80, 26, 31, 31, 78, 31,
- 78, 31, 79, 31, 31, 31, 78, 34, 50, 31,
- 31, 31, 75
+ 0, 36, 37, 0, 1, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 25, 30, 38, 39, 41, 42, 43,
+ 44, 50, 51, 53, 57, 59, 61, 62, 64, 66,
+ 67, 68, 75, 30, 25, 26, 74, 74, 30, 74,
+ 30, 30, 74, 25, 25, 25, 26, 29, 34, 78,
+ 79, 30, 1, 1, 45, 45, 54, 56, 60, 71,
+ 65, 71, 30, 76, 30, 30, 30, 30, 30, 78,
+ 78, 31, 32, 76, 27, 33, 30, 30, 1, 12,
+ 16, 18, 19, 20, 21, 22, 23, 25, 30, 40,
+ 46, 47, 69, 70, 72, 17, 18, 19, 20, 30,
+ 40, 55, 70, 72, 39, 52, 75, 39, 53, 58,
+ 64, 75, 30, 40, 72, 39, 53, 63, 64, 75,
+ 30, 28, 78, 78, 79, 79, 30, 30, 24, 74,
+ 73, 74, 78, 25, 79, 48, 1, 13, 30, 74,
+ 73, 25, 78, 14, 77, 30, 77, 77, 77, 79,
+ 25, 30, 30, 77, 30, 77, 30, 78, 30, 30,
+ 30, 77, 33, 49, 30, 30, 30, 74
};
#define yyerrok (yyerrstatus = 0)
@@ -761,7 +822,7 @@ do \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
+ YYPOPSTACK (1); \
goto yybackup; \
} \
else \
@@ -769,7 +830,7 @@ do \
yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
-while (0)
+while (YYID (0))
#define YYTERROR 1
@@ -784,7 +845,7 @@ while (0)
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
- if (N) \
+ if (YYID (N)) \
{ \
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
@@ -798,7 +859,7 @@ while (0)
(Current).first_column = (Current).last_column = \
YYRHSLOC (Rhs, 0).last_column; \
} \
- while (0)
+ while (YYID (0))
#endif
@@ -810,8 +871,8 @@ while (0)
# if YYLTYPE_IS_TRIVIAL
# define YY_LOCATION_PRINT(File, Loc) \
fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
# else
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
# endif
@@ -838,36 +899,96 @@ while (0)
do { \
if (yydebug) \
YYFPRINTF Args; \
-} while (0)
+} while (YYID (0))
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
-do { \
- if (yydebug) \
- { \
- YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Type, Value); \
- YYFPRINTF (stderr, "\n"); \
- } \
-} while (0)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included). |
`------------------------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
#else
static void
yy_stack_print (bottom, top)
- short int *bottom;
- short int *top;
+ yytype_int16 *bottom;
+ yytype_int16 *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
- for (/* Nothing. */; bottom <= top; ++bottom)
+ for (; bottom <= top; ++bottom)
YYFPRINTF (stderr, " %d", *bottom);
YYFPRINTF (stderr, "\n");
}
@@ -876,37 +997,45 @@ yy_stack_print (bottom, top)
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
-} while (0)
+} while (YYID (0))
/*------------------------------------------------.
| Report that the YYRULE is going to be reduced. |
`------------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
#else
static void
-yy_reduce_print (yyrule)
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
int yyrule;
#endif
{
+ int yynrhs = yyr2[yyrule];
int yyi;
unsigned long int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
- yyrule - 1, yylno);
- /* Print the symbols being reduced, and their result. */
- for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (stderr, "\n");
+ }
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (Rule); \
-} while (0)
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
multiple parsers can coexist. */
@@ -940,42 +1069,44 @@ int yydebug;
#if YYERROR_VERBOSE
# ifndef yystrlen
-# if defined (__GLIBC__) && defined (_STRING_H)
+# if defined __GLIBC__ && defined _STRING_H
# define yystrlen strlen
# else
/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static YYSIZE_T
-# if defined (__STDC__) || defined (__cplusplus)
yystrlen (const char *yystr)
-# else
+#else
+static YYSIZE_T
yystrlen (yystr)
- const char *yystr;
-# endif
+ const char *yystr;
+#endif
{
- const char *yys = yystr;
-
- while (*yys++ != '\0')
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
continue;
-
- return yys - yystr - 1;
+ return yylen;
}
# endif
# endif
# ifndef yystpcpy
-# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
# define yystpcpy stpcpy
# else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static char *
-# if defined (__STDC__) || defined (__cplusplus)
yystpcpy (char *yydest, const char *yysrc)
-# else
+#else
+static char *
yystpcpy (yydest, yysrc)
- char *yydest;
- const char *yysrc;
-# endif
+ char *yydest;
+ const char *yysrc;
+#endif
{
char *yyd = yydest;
const char *yys = yysrc;
@@ -1001,7 +1132,7 @@ yytnamerr (char *yyres, const char *yystr)
{
if (*yystr == '"')
{
- size_t yyn = 0;
+ YYSIZE_T yyn = 0;
char const *yyp = yystr;
for (;;)
@@ -1036,53 +1167,123 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
-#endif /* YYERROR_VERBOSE */
-
-
-
-#if YYDEBUG
-/*--------------------------------.
-| Print this symbol on YYOUTPUT. |
-`--------------------------------*/
-
-#if defined (__STDC__) || defined (__cplusplus)
-static void
-yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
-#else
-static void
-yysymprint (yyoutput, yytype, yyvaluep)
- FILE *yyoutput;
- int yytype;
- YYSTYPE *yyvaluep;
-#endif
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ int yyn = yypact[yystate];
- if (yytype < YYNTOKENS)
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
else
- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
-# ifdef YYPRINT
- if (yytype < YYNTOKENS)
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- switch (yytype)
- {
- default:
- break;
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
}
- YYFPRINTF (yyoutput, ")");
}
+#endif /* YYERROR_VERBOSE */
+
-#endif /* ! YYDEBUG */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
`-----------------------------------------------*/
-#if defined (__STDC__) || defined (__cplusplus)
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
@@ -1093,8 +1294,7 @@ yydestruct (yymsg, yytype, yyvaluep)
YYSTYPE *yyvaluep;
#endif
{
- /* Pacify ``unused variable'' warnings. */
- (void) yyvaluep;
+ YYUSE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
@@ -1102,39 +1302,39 @@ yydestruct (yymsg, yytype, yyvaluep)
switch (yytype)
{
- case 52: /* "choice_entry" */
+ case 51: /* "choice_entry" */
- {
+ {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
if (current_menu == (yyvaluep->menu))
menu_end_menu();
};
- break;
- case 58: /* "if_entry" */
+ break;
+ case 57: /* "if_entry" */
- {
+ {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
if (current_menu == (yyvaluep->menu))
menu_end_menu();
};
- break;
- case 63: /* "menu_entry" */
+ break;
+ case 62: /* "menu_entry" */
- {
+ {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
if (current_menu == (yyvaluep->menu))
menu_end_menu();
};
- break;
+ break;
default:
- break;
+ break;
}
}
@@ -1142,13 +1342,13 @@ yydestruct (yymsg, yytype, yyvaluep)
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
-# else
+#else
int yyparse ();
-# endif
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if defined __STDC__ || defined __cplusplus
int yyparse (void);
#else
int yyparse ();
@@ -1173,20 +1373,24 @@ int yynerrs;
`----------*/
#ifdef YYPARSE_PARAM
-# if defined (__STDC__) || defined (__cplusplus)
-int yyparse (void *YYPARSE_PARAM)
-# else
-int yyparse (YYPARSE_PARAM)
- void *YYPARSE_PARAM;
-# endif
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
#else /* ! YYPARSE_PARAM */
-#if defined (__STDC__) || defined (__cplusplus)
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
#else
int
yyparse ()
- ;
+
#endif
#endif
{
@@ -1198,6 +1402,12 @@ yyparse ()
int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
/* Three stacks and their tools:
`yyss': related to states,
@@ -1208,9 +1418,9 @@ yyparse ()
to reallocate them elsewhere. */
/* The state stack. */
- short int yyssa[YYINITDEPTH];
- short int *yyss = yyssa;
- short int *yyssp;
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
@@ -1219,7 +1429,7 @@ yyparse ()
-#define YYPOPSTACK (yyvsp--, yyssp--)
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
YYSIZE_T yystacksize = YYINITDEPTH;
@@ -1228,9 +1438,9 @@ yyparse ()
YYSTYPE yyval;
- /* When reducing, the number of symbols on the RHS of the reduced
- rule. */
- int yylen;
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1254,8 +1464,7 @@ yyparse ()
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks.
- */
+ have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
yysetstate:
@@ -1268,11 +1477,11 @@ yyparse ()
#ifdef yyoverflow
{
- /* Give user a chance to reallocate the stack. Use copies of
+ /* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
@@ -1300,7 +1509,7 @@ yyparse ()
yystacksize = YYMAXDEPTH;
{
- short int *yyss1 = yyss;
+ yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
@@ -1335,12 +1544,10 @@ yyparse ()
`-----------*/
yybackup:
-/* Do appropriate processing given the current state. */
-/* Read a look-ahead token if we need one and don't already have one. */
-/* yyresume: */
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
-
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
@@ -1382,22 +1589,21 @@ yybackup:
if (yyn == YYFINAL)
YYACCEPT;
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
/* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
- /* Discard the token being shifted unless it is eof. */
+ /* Discard the shifted token unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
+ yystate = yyn;
*++yyvsp = yylval;
-
- /* Count tokens shifted since error; after three, turn off error
- status. */
- if (yyerrstatus)
- yyerrstatus--;
-
- yystate = yyn;
goto yynewstate;
@@ -1439,13 +1645,13 @@ yyreduce:
case 9:
- { zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
+ { zconf_error("unknown statement \"%s\"", (yyvsp[(2) - (4)].string)); ;}
break;
case 10:
{
- zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+ zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[(2) - (4)].id)->name);
;}
break;
@@ -1456,7 +1662,7 @@ yyreduce:
case 25:
- { zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
+ { zconf_error("unknown option \"%s\"", (yyvsp[(1) - (3)].string)); ;}
break;
case 26:
@@ -1467,10 +1673,10 @@ yyreduce:
case 27:
{
- struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+ struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+ printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
;}
break;
@@ -1485,10 +1691,10 @@ yyreduce:
case 29:
{
- struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+ struct symbol *sym = sym_lookup((yyvsp[(2) - (3)].string), 0);
sym->flags |= SYMBOL_OPTIONAL;
menu_add_entry(sym);
- printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+ printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
;}
break;
@@ -1507,17 +1713,17 @@ yyreduce:
case 38:
{
- menu_set_type((yyvsp[-2].id)->stype);
+ menu_set_type((yyvsp[(1) - (3)].id)->stype);
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
zconf_curname(), zconf_lineno(),
- (yyvsp[-2].id)->stype);
+ (yyvsp[(1) - (3)].id)->stype);
;}
break;
case 39:
{
- menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+ menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1525,19 +1731,19 @@ yyreduce:
case 40:
{
- menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
- if ((yyvsp[-3].id)->stype != S_UNKNOWN)
- menu_set_type((yyvsp[-3].id)->stype);
+ menu_add_expr(P_DEFAULT, (yyvsp[(2) - (4)].expr), (yyvsp[(3) - (4)].expr));
+ if ((yyvsp[(1) - (4)].id)->stype != S_UNKNOWN)
+ menu_set_type((yyvsp[(1) - (4)].id)->stype);
printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
zconf_curname(), zconf_lineno(),
- (yyvsp[-3].id)->stype);
+ (yyvsp[(1) - (4)].id)->stype);
;}
break;
case 41:
{
- menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+ menu_add_symbol(P_SELECT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1545,7 +1751,7 @@ yyreduce:
case 42:
{
- menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
+ menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[(2) - (5)].symbol), (yyvsp[(3) - (5)].symbol)), (yyvsp[(4) - (5)].expr));
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1553,12 +1759,12 @@ yyreduce:
case 45:
{
- struct kconf_id *id = kconf_id_lookup((yyvsp[-1].string), strlen((yyvsp[-1].string)));
+ struct kconf_id *id = kconf_id_lookup((yyvsp[(2) - (3)].string), strlen((yyvsp[(2) - (3)].string)));
if (id && id->flags & TF_OPTION)
- menu_add_option(id->token, (yyvsp[0].string));
+ menu_add_option(id->token, (yyvsp[(3) - (3)].string));
else
- zconfprint("warning: ignoring unknown option %s", (yyvsp[-1].string));
- free((yyvsp[-1].string));
+ zconfprint("warning: ignoring unknown option %s", (yyvsp[(2) - (3)].string));
+ free((yyvsp[(2) - (3)].string));
;}
break;
@@ -1569,7 +1775,7 @@ yyreduce:
case 47:
- { (yyval.string) = (yyvsp[0].string); ;}
+ { (yyval.string) = (yyvsp[(2) - (2)].string); ;}
break;
case 48:
@@ -1593,7 +1799,7 @@ yyreduce:
case 50:
{
- if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
+ if (zconf_endtoken((yyvsp[(1) - (1)].id), T_CHOICE, T_ENDCHOICE)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
}
@@ -1603,7 +1809,7 @@ yyreduce:
case 58:
{
- menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+ menu_add_prompt(P_PROMPT, (yyvsp[(2) - (4)].string), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1611,11 +1817,11 @@ yyreduce:
case 59:
{
- if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
- menu_set_type((yyvsp[-2].id)->stype);
+ if ((yyvsp[(1) - (3)].id)->stype == S_BOOLEAN || (yyvsp[(1) - (3)].id)->stype == S_TRISTATE) {
+ menu_set_type((yyvsp[(1) - (3)].id)->stype);
printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
zconf_curname(), zconf_lineno(),
- (yyvsp[-2].id)->stype);
+ (yyvsp[(1) - (3)].id)->stype);
} else
YYERROR;
;}
@@ -1632,8 +1838,8 @@ yyreduce:
case 61:
{
- if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
- menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+ if ((yyvsp[(1) - (4)].id)->stype == S_UNKNOWN) {
+ menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[(2) - (4)].string), 0), (yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:default\n",
zconf_curname(), zconf_lineno());
} else
@@ -1646,7 +1852,7 @@ yyreduce:
{
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL);
- menu_add_dep((yyvsp[-1].expr));
+ menu_add_dep((yyvsp[(2) - (3)].expr));
(yyval.menu) = menu_add_menu();
;}
break;
@@ -1654,7 +1860,7 @@ yyreduce:
case 65:
{
- if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
+ if (zconf_endtoken((yyvsp[(1) - (1)].id), T_IF, T_ENDIF)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
}
@@ -1665,7 +1871,7 @@ yyreduce:
{
menu_add_entry(NULL);
- menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
+ menu_add_prompt(P_MENU, (yyvsp[(2) - (3)].string), NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1680,7 +1886,7 @@ yyreduce:
case 73:
{
- if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
+ if (zconf_endtoken((yyvsp[(1) - (1)].id), T_MENU, T_ENDMENU)) {
menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
}
@@ -1690,8 +1896,8 @@ yyreduce:
case 79:
{
- printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
- zconf_nextfile((yyvsp[-1].string));
+ printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[(2) - (3)].string));
+ zconf_nextfile((yyvsp[(2) - (3)].string));
;}
break;
@@ -1699,7 +1905,7 @@ yyreduce:
{
menu_add_entry(NULL);
- menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
+ menu_add_prompt(P_COMMENT, (yyvsp[(2) - (3)].string), NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
;}
break;
@@ -1722,122 +1928,104 @@ yyreduce:
case 83:
{
- current_entry->help = (yyvsp[0].string);
+ current_entry->help = (yyvsp[(2) - (2)].string);
;}
break;
case 88:
{
- menu_add_dep((yyvsp[-1].expr));
+ menu_add_dep((yyvsp[(3) - (4)].expr));
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
;}
break;
- case 89:
+ case 90:
{
- menu_add_dep((yyvsp[-1].expr));
- printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+ menu_add_prompt(P_PROMPT, (yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].expr));
;}
break;
- case 90:
+ case 93:
- {
- menu_add_dep((yyvsp[-1].expr));
- printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
-;}
+ { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 92:
+ case 94:
- {
- menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
-;}
+ { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
case 95:
- { (yyval.id) = (yyvsp[-1].id); ;}
+ { (yyval.id) = (yyvsp[(1) - (2)].id); ;}
break;
- case 96:
+ case 98:
- { (yyval.id) = (yyvsp[-1].id); ;}
+ { (yyval.expr) = NULL; ;}
break;
- case 97:
+ case 99:
- { (yyval.id) = (yyvsp[-1].id); ;}
+ { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;}
break;
case 100:
- { (yyval.expr) = NULL; ;}
+ { (yyval.expr) = expr_alloc_symbol((yyvsp[(1) - (1)].symbol)); ;}
break;
case 101:
- { (yyval.expr) = (yyvsp[0].expr); ;}
+ { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
break;
case 102:
- { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
+ { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[(1) - (3)].symbol), (yyvsp[(3) - (3)].symbol)); ;}
break;
case 103:
- { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
+ { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;}
break;
case 104:
- { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
+ { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[(2) - (2)].expr)); ;}
break;
case 105:
- { (yyval.expr) = (yyvsp[-1].expr); ;}
+ { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
break;
case 106:
- { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
+ { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;}
break;
case 107:
- { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 0); free((yyvsp[(1) - (1)].string)); ;}
break;
case 108:
- { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
- break;
-
- case 109:
-
- { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
+ { (yyval.symbol) = sym_lookup((yyvsp[(1) - (1)].string), 1); free((yyvsp[(1) - (1)].string)); ;}
break;
- case 110:
-
- { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
- break;
+/* Line 1267 of yacc.c. */
default: break;
}
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-/* Line 1126 of yacc.c. */
-
-
- yyvsp -= yylen;
- yyssp -= yylen;
-
-
+ YYPOPSTACK (yylen);
+ yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
@@ -1866,110 +2054,41 @@ yyerrlab:
if (!yyerrstatus)
{
++yynerrs;
-#if YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (YYPACT_NINF < yyn && yyn < YYLAST)
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- char *yymsg = 0;
-# define YYERROR_VERBOSE_ARGS_MAXIMUM 5
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-#if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-#endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
{
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= yysize1 < yysize;
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
}
+ }
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= yysize1 < yysize;
- yysize = yysize1;
-
- if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yymsg;
- int yyi = 0;
- while ((*yyp = *yyf))
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- yyerror (yymsg);
- YYSTACK_FREE (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
goto yyexhaustedlab;
- }
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror (YY_("syntax error"));
+ }
+ }
+#endif
}
@@ -1980,14 +2099,15 @@ yyerrlab:
error, discard it. */
if (yychar <= YYEOF)
- {
+ {
/* Return failure if at end of input. */
if (yychar == YYEOF)
YYABORT;
- }
+ }
else
{
- yydestruct ("Error: discarding", yytoken, &yylval);
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
yychar = YYEMPTY;
}
}
@@ -2005,11 +2125,14 @@ yyerrorlab:
/* Pacify compilers like GCC when the user code never invokes
YYERROR and the label yyerrorlab therefore never appears in user
code. */
- if (0)
+ if (/*CONSTCOND*/ 0)
goto yyerrorlab;
-yyvsp -= yylen;
- yyssp -= yylen;
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
@@ -2039,8 +2162,9 @@ yyerrlab1:
YYABORT;
- yydestruct ("Error: popping", yystos[yystate], yyvsp);
- YYPOPSTACK;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
@@ -2051,7 +2175,7 @@ yyerrlab1:
*++yyvsp = yylval;
- /* Shift the error token. */
+ /* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
yystate = yyn;
@@ -2086,17 +2210,26 @@ yyreturn:
if (yychar != YYEOF && yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
yystos[*yyssp], yyvsp);
- YYPOPSTACK;
+ YYPOPSTACK (1);
}
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
- return yyresult;
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
}
@@ -2344,4 +2477,3 @@ void zconfdump(FILE *out)
#include "symbol.c"
#include "menu.c"
-
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 79db4cf22a5..d9b96ba8e38 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -64,7 +64,6 @@ static struct menu *current_menu, *current_entry;
%token <id>T_IF
%token <id>T_ENDIF
%token <id>T_DEPENDS
-%token <id>T_REQUIRES
%token <id>T_OPTIONAL
%token <id>T_PROMPT
%token <id>T_TYPE
@@ -418,16 +417,6 @@ depends: T_DEPENDS T_ON expr T_EOL
{
menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
-}
- | T_DEPENDS expr T_EOL
-{
- menu_add_dep($2);
- printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
-}
- | T_REQUIRES expr T_EOL
-{
- menu_add_dep($2);
- printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
};
/* prompt statement */
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 1f5835115ca..1d1401807e9 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -5,6 +5,7 @@ use strict;
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ##
## Copyright (C) 2001 Simon Huggins ##
+## Copyright (C) 2005-2007 Randy Dunlap ##
## ##
## #define enhancements by Armin Kuster <akuster@mvista.com> ##
## Copyright (c) 2000 MontaVista Software, Inc. ##
@@ -161,7 +162,7 @@ my $type_constant = '\%([-_\w]+)';
my $type_func = '(\w+)\(\)';
my $type_param = '\@(\w+)';
my $type_struct = '\&((struct\s*)*[_\w]+)';
-my $type_struct_xml = '\\\amp;((struct\s*)*[_\w]+)';
+my $type_struct_xml = '\\&amp;((struct\s*)*[_\w]+)';
my $type_env = '(\$\w+)';
# Output conversion substitutions.
@@ -173,7 +174,9 @@ my %highlights_html = ( $type_constant, "<i>\$1</i>",
$type_struct_xml, "<i>\$1</i>",
$type_env, "<b><i>\$1</i></b>",
$type_param, "<tt><b>\$1</b></tt>" );
-my $blankline_html = "<p>";
+my $local_lt = "\\\\\\\\lt:";
+my $local_gt = "\\\\\\\\gt:";
+my $blankline_html = $local_lt . "p" . $local_gt; # was "<p>"
# XML, docbook format
my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
@@ -391,17 +394,19 @@ sub output_highlight {
# confess "output_highlight got called with no args?\n";
# }
+ if ($output_mode eq "html") {
+ $contents = local_unescape($contents);
+ # convert data read & converted thru xml_escape() into &xyz; format:
+ $contents =~ s/\\\\\\/&/g;
+ }
# print STDERR "contents b4:$contents\n";
eval $dohighlight;
die $@ if $@;
- if ($output_mode eq "html") {
- $contents =~ s/\\\\//;
- }
# print STDERR "contents af:$contents\n";
foreach $line (split "\n", $contents) {
if ($line eq ""){
- print $lineprefix, $blankline;
+ print $lineprefix, local_unescape($blankline);
} else {
$line =~ s/\\\\\\/\&/g;
if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
@@ -1752,7 +1757,13 @@ sub process_state3_type($$) {
}
}
-# replace <, >, and &
+# xml_escape: replace <, >, and & in the text stream;
+#
+# however, formatting controls that are generated internally/locally in the
+# kernel-doc script are not escaped here; instead, they begin life like
+# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings
+# are converted to their mnemonic-expected output, without the 4 * '\' & ':',
+# just before actual output; (this is done by local_unescape())
sub xml_escape($) {
my $text = shift;
if (($output_mode eq "text") || ($output_mode eq "man")) {
@@ -1764,6 +1775,18 @@ sub xml_escape($) {
return $text;
}
+# convert local escape strings to html
+# local escape strings look like: '\\\\menmonic:' (that's 4 backslashes)
+sub local_unescape($) {
+ my $text = shift;
+ if (($output_mode eq "text") || ($output_mode eq "man")) {
+ return $text;
+ }
+ $text =~ s/\\\\\\\\lt:/</g;
+ $text =~ s/\\\\\\\\gt:/>/g;
+ return $text;
+}
+
sub process_file($) {
my $file;
my $identifier;
@@ -1903,7 +1926,7 @@ sub process_file($) {
} elsif ($state == 4) {
# Documentation block
if (/$doc_block/) {
- dump_section($section, $contents);
+ dump_section($section, xml_escape($contents));
output_intro({'sectionlist' => \@sectionlist,
'sections' => \%sections });
$contents = "";
@@ -1923,7 +1946,7 @@ sub process_file($) {
}
elsif (/$doc_end/)
{
- dump_section($section, $contents);
+ dump_section($section, xml_escape($contents));
output_intro({'sectionlist' => \@sectionlist,
'sections' => \%sections });
$contents = "";
diff --git a/scripts/makelst b/scripts/makelst
index 4fc80f2b7e1..e6581496d82 100755
--- a/scripts/makelst
+++ b/scripts/makelst
@@ -3,8 +3,8 @@
# with correct relocations from System.map
# Requires the following lines in makefile:
#%.lst: %.c
-# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
-# $(srctree)/scripts/makelst $*.o $(objtree)/System.map $(OBJDUMP)
+# $(CC) $(c_flags) -g -c -o $*.o $< &&
+# $(srctree)/scripts/makelst $*.o System.map $(OBJDUMP) > $@
#
# Copyright (C) 2000 IBM Corporation
# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
diff --git a/scripts/mkmakefile b/scripts/mkmakefile
index 7f9d544f9b6..ee39facee15 100644
--- a/scripts/mkmakefile
+++ b/scripts/mkmakefile
@@ -26,11 +26,13 @@ MAKEFLAGS += --no-print-directory
.PHONY: all \$(MAKECMDGOALS)
+all := \$(filter-out all Makefile,\$(MAKECMDGOALS))
+
all:
- \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT)
+ \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$(all)
Makefile:;
-\$(filter-out all Makefile,\$(MAKECMDGOALS)) %/:
- \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@
+\$(all) %/: all
+ @:
EOF
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 494435ca88f..91c15da2680 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -55,10 +55,14 @@ do { \
* Check that sizeof(device_id type) are consistent with size of section
* in .o file. If in-consistent then userspace and kernel does not agree
* on actual size which is a bug.
+ * Also verify that the final entry in the table is all zeros.
**/
-static void device_id_size_check(const char *modname, const char *device_id,
- unsigned long size, unsigned long id_size)
+static void device_id_check(const char *modname, const char *device_id,
+ unsigned long size, unsigned long id_size,
+ void *symval)
{
+ int i;
+
if (size % id_size || size < id_size) {
fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
"of the size of section __mod_%s_device_table=%lu.\n"
@@ -66,6 +70,20 @@ static void device_id_size_check(const char *modname, const char *device_id,
"in mod_devicetable.h\n",
modname, device_id, id_size, device_id, size, device_id);
}
+ /* Verify last one is a terminator */
+ for (i = 0; i < id_size; i++ ) {
+ if (*(uint8_t*)(symval+size-id_size+i)) {
+ fprintf(stderr,"%s: struct %s_device_id is %lu bytes. "
+ "The last of %lu is:\n",
+ modname, device_id, id_size, size / id_size);
+ for (i = 0; i < id_size; i++ )
+ fprintf(stderr,"0x%02x ",
+ *(uint8_t*)(symval+size-id_size+i) );
+ fprintf(stderr,"\n");
+ fatal("%s: struct %s_device_id is not terminated "
+ "with a NULL entry!\n", modname, device_id);
+ }
+ }
}
/* USB is special because the bcdDevice can be matched against a numeric range */
@@ -168,7 +186,7 @@ static void do_usb_table(void *symval, unsigned long size,
unsigned int i;
const unsigned long id_size = sizeof(struct usb_device_id);
- device_id_size_check(mod->name, "usb", size, id_size);
+ device_id_check(mod->name, "usb", size, id_size, symval);
/* Leave last one: it's the terminator. */
size -= id_size;
@@ -528,7 +546,7 @@ static void do_table(void *symval, unsigned long size,
char alias[500];
int (*do_entry)(const char *, void *entry, char *alias) = function;
- device_id_size_check(mod->name, device_id, size, id_size);
+ device_id_check(mod->name, device_id, size, id_size, symval);
/* Leave last one: it's the terminator. */
size -= id_size;
@@ -550,14 +568,21 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname)
{
void *symval;
+ char *zeros = NULL;
/* We're looking for a section relative symbol */
if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
return;
- symval = (void *)info->hdr
- + info->sechdrs[sym->st_shndx].sh_offset
- + sym->st_value;
+ /* Handle all-NULL symbols allocated into .bss */
+ if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) {
+ zeros = calloc(1, sym->st_size);
+ symval = zeros;
+ } else {
+ symval = (void *)info->hdr
+ + info->sechdrs[sym->st_shndx].sh_offset
+ + sym->st_value;
+ }
if (sym_is(symname, "__mod_pci_device_table"))
do_table(symval, sym->st_size,
@@ -626,6 +651,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
do_table(symval, sym->st_size,
sizeof(struct ssb_device_id), "ssb",
do_ssb_entry, mod);
+ free(zeros);
}
/* Now add out buffered information to the generated C source */
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 0a4051fbd34..2ef9a193fca 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -381,6 +381,12 @@ static int parse_elf(struct elf_info *info, const char *filename)
sechdrs = (void *)hdr + hdr->e_shoff;
info->sechdrs = sechdrs;
+ /* Check if file offset is correct */
+ if (hdr->e_shoff > info->size) {
+ fatal("section header offset=%u in file '%s' is bigger then filesize=%lu\n", hdr->e_shoff, filename, info->size);
+ return 0;
+ }
+
/* Fix endianness in section headers */
for (i = 0; i < hdr->e_shnum; i++) {
sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 4156dd34c5d..0ffed17ec20 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -17,7 +17,7 @@
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Addr Elf32_Addr
-#define Elf_Section Elf32_Section
+#define Elf_Section Elf32_Half
#define ELF_ST_BIND ELF32_ST_BIND
#define ELF_ST_TYPE ELF32_ST_TYPE
@@ -31,7 +31,7 @@
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Addr Elf64_Addr
-#define Elf_Section Elf64_Section
+#define Elf_Section Elf64_Half
#define ELF_ST_BIND ELF64_ST_BIND
#define ELF_ST_TYPE ELF64_ST_TYPE
diff --git a/scripts/ver_linux b/scripts/ver_linux
index 8f8df93141a..ab69ecefedb 100755
--- a/scripts/ver_linux
+++ b/scripts/ver_linux
@@ -21,9 +21,7 @@ gcc --version 2>&1| grep gcc | awk \
make --version 2>&1 | awk -F, '{print $1}' | awk \
'/GNU Make/{print "Gnu make ",$NF}'
-ld -v | awk -F\) '{print $1}' | awk \
-'/BFD/{print "binutils ",$NF} \
-/^GNU/{print "binutils ",$4}'
+echo "binutils $(ld -v | egrep -o '[0-9]+\.[0-9\.]+')"
echo -n "util-linux "
fdformat --version | awk '{print $NF}' | sed -e s/^util-linux-// -e s/\)$//
@@ -65,9 +63,8 @@ isdnctrl 2>&1 | grep version | awk \
showmount --version 2>&1 | grep nfs-utils | awk \
'NR==1{print "nfs-utils ", $NF}'
-ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \
--e 's/\.so$//' | sed -e 's/>//' | \
-awk -F'[.-]' '{print "Linux C Library "$(NF-1)"."$NF}'
+echo -n "Linux C Library "
+sed -n -e '/^.*\/libc-\([^/]*\)\.so$/{s//\1/;p;q}' < /proc/self/maps
ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -n 1 | awk \
'NR==1{print "Dynamic linker (ldd) ", $NF}'
diff --git a/security/Kconfig b/security/Kconfig
index 460e5c9cf49..8086e61058e 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -74,15 +74,25 @@ config SECURITY_NETWORK_XFRM
If you are unsure how to answer this question, answer N.
config SECURITY_CAPABILITIES
- tristate "Default Linux Capabilities"
+ bool "Default Linux Capabilities"
depends on SECURITY
help
This enables the "default" Linux capabilities functionality.
If you are unsure how to answer this question, answer Y.
+config SECURITY_FILE_CAPABILITIES
+ bool "File POSIX Capabilities (EXPERIMENTAL)"
+ depends on (SECURITY=n || SECURITY_CAPABILITIES!=n) && EXPERIMENTAL
+ default n
+ help
+ This enables filesystem capabilities, allowing you to give
+ binaries a subset of root's powers without using setuid 0.
+
+ If in doubt, answer N.
+
config SECURITY_ROOTPLUG
- tristate "Root Plug Support"
- depends on USB && SECURITY
+ bool "Root Plug Support"
+ depends on USB=y && SECURITY
help
This is a sample LSM module that should only be used as such.
It prevents any programs running with egid == 0 if a specific
diff --git a/security/capability.c b/security/capability.c
index 38296a00546..9e99f36a8b5 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -8,7 +8,6 @@
*
*/
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/security.h>
@@ -38,7 +37,13 @@ static struct security_operations capability_ops = {
.inode_setxattr = cap_inode_setxattr,
.inode_removexattr = cap_inode_removexattr,
+ .inode_need_killpriv = cap_inode_need_killpriv,
+ .inode_killpriv = cap_inode_killpriv,
+ .task_kill = cap_task_kill,
+ .task_setscheduler = cap_task_setscheduler,
+ .task_setioprio = cap_task_setioprio,
+ .task_setnice = cap_task_setnice,
.task_post_setuid = cap_task_post_setuid,
.task_reparent_to_init = cap_task_reparent_to_init,
@@ -52,7 +57,6 @@ static int secondary;
static int capability_disable;
module_param_named(disable, capability_disable, int, 0);
-MODULE_PARM_DESC(disable, "To disable capabilities module set disable = 1");
static int __init capability_init (void)
{
@@ -75,26 +79,4 @@ static int __init capability_init (void)
return 0;
}
-static void __exit capability_exit (void)
-{
- if (capability_disable)
- return;
- /* remove ourselves from the security framework */
- if (secondary) {
- if (mod_unreg_security (KBUILD_MODNAME, &capability_ops))
- printk (KERN_INFO "Failure unregistering capabilities "
- "with primary module.\n");
- return;
- }
-
- if (unregister_security (&capability_ops)) {
- printk (KERN_INFO
- "Failure unregistering capabilities with the kernel\n");
- }
-}
-
security_initcall (capability_init);
-module_exit (capability_exit);
-
-MODULE_DESCRIPTION("Standard Linux Capabilities Security Module");
-MODULE_LICENSE("GPL");
diff --git a/security/commoncap.c b/security/commoncap.c
index 7520361663e..48ca5b09276 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -22,6 +22,26 @@
#include <linux/ptrace.h>
#include <linux/xattr.h>
#include <linux/hugetlb.h>
+#include <linux/mount.h>
+
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+/*
+ * Because of the reduced scope of CAP_SETPCAP when filesystem
+ * capabilities are in effect, it is safe to allow this capability to
+ * be available in the default configuration.
+ */
+# define CAP_INIT_BSET CAP_FULL_SET
+#else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */
+# define CAP_INIT_BSET CAP_INIT_EFF_SET
+#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
+
+kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */
+EXPORT_SYMBOL(cap_bset);
+
+/* Global security state */
+
+unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
+EXPORT_SYMBOL(securebits);
int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
{
@@ -29,8 +49,6 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
return 0;
}
-EXPORT_SYMBOL(cap_netlink_send);
-
int cap_netlink_recv(struct sk_buff *skb, int cap)
{
if (!cap_raised(NETLINK_CB(skb).eff_cap, cap))
@@ -74,14 +92,44 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective,
return 0;
}
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+
+static inline int cap_block_setpcap(struct task_struct *target)
+{
+ /*
+ * No support for remote process capability manipulation with
+ * filesystem capability support.
+ */
+ return (target != current);
+}
+
+static inline int cap_inh_is_capped(void)
+{
+ /*
+ * return 1 if changes to the inheritable set are limited
+ * to the old permitted set.
+ */
+ return !cap_capable(current, CAP_SETPCAP);
+}
+
+#else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */
+
+static inline int cap_block_setpcap(struct task_struct *t) { return 0; }
+static inline int cap_inh_is_capped(void) { return 1; }
+
+#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
+
int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
kernel_cap_t *inheritable, kernel_cap_t *permitted)
{
- /* Derived from kernel/capability.c:sys_capset. */
- /* verify restrictions on target's new Inheritable set */
- if (!cap_issubset (*inheritable,
- cap_combine (target->cap_inheritable,
- current->cap_permitted))) {
+ if (cap_block_setpcap(target)) {
+ return -EPERM;
+ }
+ if (cap_inh_is_capped()
+ && !cap_issubset(*inheritable,
+ cap_combine(target->cap_inheritable,
+ current->cap_permitted))) {
+ /* incapable of using this inheritable set */
return -EPERM;
}
@@ -108,14 +156,130 @@ void cap_capset_set (struct task_struct *target, kernel_cap_t *effective,
target->cap_permitted = *permitted;
}
+static inline void bprm_clear_caps(struct linux_binprm *bprm)
+{
+ cap_clear(bprm->cap_inheritable);
+ cap_clear(bprm->cap_permitted);
+ bprm->cap_effective = false;
+}
+
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+
+int cap_inode_need_killpriv(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ if (!inode->i_op || !inode->i_op->getxattr)
+ return 0;
+
+ error = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, NULL, 0);
+ if (error <= 0)
+ return 0;
+ return 1;
+}
+
+int cap_inode_killpriv(struct dentry *dentry)
+{
+ struct inode *inode = dentry->d_inode;
+
+ if (!inode->i_op || !inode->i_op->removexattr)
+ return 0;
+
+ return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
+}
+
+static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
+ int size)
+{
+ __u32 magic_etc;
+
+ if (size != XATTR_CAPS_SZ)
+ return -EINVAL;
+
+ magic_etc = le32_to_cpu(caps[0]);
+
+ switch ((magic_etc & VFS_CAP_REVISION_MASK)) {
+ case VFS_CAP_REVISION:
+ if (magic_etc & VFS_CAP_FLAGS_EFFECTIVE)
+ 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]) );
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+/* Locate any VFS capabilities: */
+static int get_file_caps(struct linux_binprm *bprm)
+{
+ struct dentry *dentry;
+ int rc = 0;
+ __le32 v1caps[XATTR_CAPS_SZ];
+ struct inode *inode;
+
+ if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
+ bprm_clear_caps(bprm);
+ return 0;
+ }
+
+ dentry = dget(bprm->file->f_dentry);
+ inode = dentry->d_inode;
+ if (!inode->i_op || !inode->i_op->getxattr)
+ goto out;
+
+ rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &v1caps,
+ XATTR_CAPS_SZ);
+ if (rc == -ENODATA || rc == -EOPNOTSUPP) {
+ /* no data, that's ok */
+ rc = 0;
+ goto out;
+ }
+ if (rc < 0)
+ goto out;
+
+ rc = cap_from_disk(v1caps, bprm, rc);
+ if (rc)
+ printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
+ __FUNCTION__, rc, bprm->filename);
+
+out:
+ dput(dentry);
+ if (rc)
+ bprm_clear_caps(bprm);
+
+ return rc;
+}
+
+#else
+int cap_inode_need_killpriv(struct dentry *dentry)
+{
+ return 0;
+}
+
+int cap_inode_killpriv(struct dentry *dentry)
+{
+ return 0;
+}
+
+static inline int get_file_caps(struct linux_binprm *bprm)
+{
+ bprm_clear_caps(bprm);
+ return 0;
+}
+#endif
+
int cap_bprm_set_security (struct linux_binprm *bprm)
{
- /* Copied from fs/exec.c:prepare_binprm. */
+ int ret;
- /* We don't have VFS support for capabilities yet */
- cap_clear (bprm->cap_inheritable);
- cap_clear (bprm->cap_permitted);
- cap_clear (bprm->cap_effective);
+ ret = get_file_caps(bprm);
+ if (ret)
+ printk(KERN_NOTICE "%s: get_file_caps returned %d for %s\n",
+ __FUNCTION__, ret, bprm->filename);
/* To support inheritance of root-permissions and suid-root
* executables under compatibility mode, we raise all three
@@ -131,9 +295,10 @@ int cap_bprm_set_security (struct linux_binprm *bprm)
cap_set_full (bprm->cap_permitted);
}
if (bprm->e_uid == 0)
- cap_set_full (bprm->cap_effective);
+ bprm->cap_effective = true;
}
- return 0;
+
+ return ret;
}
void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
@@ -149,6 +314,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
!cap_issubset (new_permitted, current->cap_permitted)) {
set_dumpable(current->mm, suid_dumpable);
+ current->pdeath_signal = 0;
if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
if (!capable(CAP_SETUID)) {
@@ -170,8 +336,8 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
* capability rules */
if (!is_init(current)) {
current->cap_permitted = new_permitted;
- current->cap_effective =
- cap_intersect (new_permitted, bprm->cap_effective);
+ current->cap_effective = bprm->cap_effective ?
+ new_permitted : 0;
}
/* AUD: Audit candidate if current->cap_effective is set */
@@ -181,11 +347,15 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
int cap_bprm_secureexec (struct linux_binprm *bprm)
{
- /* If/when this module is enhanced to incorporate capability
- bits on files, the test below should be extended to also perform a
- test between the old and new capability sets. For now,
- it simply preserves the legacy decision algorithm used by
- the old userland. */
+ if (current->uid != 0) {
+ if (bprm->cap_effective)
+ return 1;
+ if (!cap_isclear(bprm->cap_permitted))
+ return 1;
+ if (!cap_isclear(bprm->cap_inheritable))
+ return 1;
+ }
+
return (current->euid != current->uid ||
current->egid != current->gid);
}
@@ -193,7 +363,11 @@ int cap_bprm_secureexec (struct linux_binprm *bprm)
int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
size_t size, int flags)
{
- if (!strncmp(name, XATTR_SECURITY_PREFIX,
+ if (!strcmp(name, XATTR_NAME_CAPS)) {
+ if (!capable(CAP_SETFCAP))
+ return -EPERM;
+ return 0;
+ } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -202,7 +376,11 @@ int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
int cap_inode_removexattr(struct dentry *dentry, char *name)
{
- if (!strncmp(name, XATTR_SECURITY_PREFIX,
+ if (!strcmp(name, XATTR_NAME_CAPS)) {
+ if (!capable(CAP_SETFCAP))
+ return -EPERM;
+ return 0;
+ } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -299,6 +477,83 @@ int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
return 0;
}
+#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
+/*
+ * Rationale: code calling task_setscheduler, task_setioprio, and
+ * task_setnice, assumes that
+ * . if capable(cap_sys_nice), then those actions should be allowed
+ * . if not capable(cap_sys_nice), but acting on your own processes,
+ * then those actions should be allowed
+ * This is insufficient now since you can call code without suid, but
+ * yet with increased caps.
+ * So we check for increased caps on the target process.
+ */
+static inline int cap_safe_nice(struct task_struct *p)
+{
+ if (!cap_issubset(p->cap_permitted, current->cap_permitted) &&
+ !__capable(current, CAP_SYS_NICE))
+ return -EPERM;
+ return 0;
+}
+
+int cap_task_setscheduler (struct task_struct *p, int policy,
+ struct sched_param *lp)
+{
+ return cap_safe_nice(p);
+}
+
+int cap_task_setioprio (struct task_struct *p, int ioprio)
+{
+ return cap_safe_nice(p);
+}
+
+int cap_task_setnice (struct task_struct *p, int nice)
+{
+ return cap_safe_nice(p);
+}
+
+int cap_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid)
+{
+ if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info)))
+ return 0;
+
+ if (secid)
+ /*
+ * Signal sent as a particular user.
+ * Capabilities are ignored. May be wrong, but it's the
+ * only thing we can do at the moment.
+ * Used only by usb drivers?
+ */
+ return 0;
+ if (cap_issubset(p->cap_permitted, current->cap_permitted))
+ return 0;
+ if (capable(CAP_KILL))
+ return 0;
+
+ return -EPERM;
+}
+#else
+int cap_task_setscheduler (struct task_struct *p, int policy,
+ struct sched_param *lp)
+{
+ return 0;
+}
+int cap_task_setioprio (struct task_struct *p, int ioprio)
+{
+ return 0;
+}
+int cap_task_setnice (struct task_struct *p, int nice)
+{
+ return 0;
+}
+int cap_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid)
+{
+ return 0;
+}
+#endif
+
void cap_task_reparent_to_init (struct task_struct *p)
{
p->cap_effective = CAP_INIT_EFF_SET;
@@ -324,21 +579,3 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
return __vm_enough_memory(mm, pages, cap_sys_admin);
}
-EXPORT_SYMBOL(cap_capable);
-EXPORT_SYMBOL(cap_settime);
-EXPORT_SYMBOL(cap_ptrace);
-EXPORT_SYMBOL(cap_capget);
-EXPORT_SYMBOL(cap_capset_check);
-EXPORT_SYMBOL(cap_capset_set);
-EXPORT_SYMBOL(cap_bprm_set_security);
-EXPORT_SYMBOL(cap_bprm_apply_creds);
-EXPORT_SYMBOL(cap_bprm_secureexec);
-EXPORT_SYMBOL(cap_inode_setxattr);
-EXPORT_SYMBOL(cap_inode_removexattr);
-EXPORT_SYMBOL(cap_task_post_setuid);
-EXPORT_SYMBOL(cap_task_reparent_to_init);
-EXPORT_SYMBOL(cap_syslog);
-EXPORT_SYMBOL(cap_vm_enough_memory);
-
-MODULE_DESCRIPTION("Standard Linux Common Capabilities Security Module");
-MODULE_LICENSE("GPL");
diff --git a/security/dummy.c b/security/dummy.c
index 853ec229279..6d895ade73d 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -15,7 +15,6 @@
#undef DEBUG
#include <linux/capability.h>
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mman.h>
#include <linux/pagemap.h>
@@ -38,15 +37,13 @@ static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
kernel_cap_t * inheritable, kernel_cap_t * permitted)
{
*effective = *inheritable = *permitted = 0;
- if (!issecure(SECURE_NOROOT)) {
- if (target->euid == 0) {
- *permitted |= (~0 & ~CAP_FS_MASK);
- *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
- }
- if (target->fsuid == 0) {
- *permitted |= CAP_FS_MASK;
- *effective |= CAP_FS_MASK;
- }
+ if (target->euid == 0) {
+ *permitted |= (~0 & ~CAP_FS_MASK);
+ *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
+ }
+ if (target->fsuid == 0) {
+ *permitted |= CAP_FS_MASK;
+ *effective |= CAP_FS_MASK;
}
return 0;
}
@@ -377,6 +374,16 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
return 0;
}
+static int dummy_inode_need_killpriv(struct dentry *dentry)
+{
+ return 0;
+}
+
+static int dummy_inode_killpriv(struct dentry *dentry)
+{
+ return 0;
+}
+
static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
{
return -EOPNOTSUPP;
@@ -392,11 +399,6 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu
return 0;
}
-static const char *dummy_inode_xattr_getsuffix(void)
-{
- return NULL;
-}
-
static int dummy_file_permission (struct file *file, int mask)
{
return 0;
@@ -463,6 +465,11 @@ static int dummy_file_receive (struct file *file)
return 0;
}
+static int dummy_dentry_open (struct file *file)
+{
+ return 0;
+}
+
static int dummy_task_create (unsigned long clone_flags)
{
return 0;
@@ -901,11 +908,6 @@ static int dummy_register_security (const char *name, struct security_operations
return -EINVAL;
}
-static int dummy_unregister_security (const char *name, struct security_operations *ops)
-{
- return -EINVAL;
-}
-
static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode)
{
return;
@@ -1018,7 +1020,8 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, inode_getxattr);
set_to_dummy_if_null(ops, inode_listxattr);
set_to_dummy_if_null(ops, inode_removexattr);
- set_to_dummy_if_null(ops, inode_xattr_getsuffix);
+ set_to_dummy_if_null(ops, inode_need_killpriv);
+ set_to_dummy_if_null(ops, inode_killpriv);
set_to_dummy_if_null(ops, inode_getsecurity);
set_to_dummy_if_null(ops, inode_setsecurity);
set_to_dummy_if_null(ops, inode_listsecurity);
@@ -1033,6 +1036,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, file_set_fowner);
set_to_dummy_if_null(ops, file_send_sigiotask);
set_to_dummy_if_null(ops, file_receive);
+ set_to_dummy_if_null(ops, dentry_open);
set_to_dummy_if_null(ops, task_create);
set_to_dummy_if_null(ops, task_alloc_security);
set_to_dummy_if_null(ops, task_free_security);
@@ -1078,7 +1082,6 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, netlink_send);
set_to_dummy_if_null(ops, netlink_recv);
set_to_dummy_if_null(ops, register_security);
- set_to_dummy_if_null(ops, unregister_security);
set_to_dummy_if_null(ops, d_instantiate);
set_to_dummy_if_null(ops, getprocattr);
set_to_dummy_if_null(ops, setprocattr);
diff --git a/security/inode.c b/security/inode.c
index 307211ac734..b28a8acae34 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -332,14 +332,6 @@ static int __init securityfs_init(void)
return retval;
}
-static void __exit securityfs_exit(void)
-{
- simple_release_fs(&mount, &mount_count);
- unregister_filesystem(&fs_type);
- subsystem_unregister(&security_subsys);
-}
-
core_initcall(securityfs_init);
-module_exit(securityfs_exit);
MODULE_LICENSE("GPL");
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 1bb416f4bbc..d36d6939335 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -1,6 +1,6 @@
/* internal.h: authentication token and access key management internal defs
*
- * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -12,17 +12,28 @@
#ifndef _INTERNAL_H
#define _INTERNAL_H
-#include <linux/key.h>
+#include <linux/key-type.h>
#include <linux/key-ui.h>
-#if 0
-#define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a)
-#define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a)
-#define kdebug(FMT, a...) printk(FMT"\n" , ## a)
+static inline __attribute__((format(printf, 1, 2)))
+void no_printk(const char *fmt, ...)
+{
+}
+
+#ifdef __KDEBUG
+#define kenter(FMT, ...) \
+ printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__)
+#define kleave(FMT, ...) \
+ printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__)
+#define kdebug(FMT, ...) \
+ printk(KERN_DEBUG "xxx" FMT"yyy\n", ##__VA_ARGS__)
#else
-#define kenter(FMT, a...) do {} while(0)
-#define kleave(FMT, a...) do {} while(0)
-#define kdebug(FMT, a...) do {} while(0)
+#define kenter(FMT, ...) \
+ no_printk(KERN_DEBUG "==> %s("FMT")\n", __FUNCTION__, ##__VA_ARGS__)
+#define kleave(FMT, ...) \
+ no_printk(KERN_DEBUG "<== %s()"FMT"\n", __FUNCTION__, ##__VA_ARGS__)
+#define kdebug(FMT, ...) \
+ no_printk(KERN_DEBUG FMT"\n", ##__VA_ARGS__)
#endif
extern struct key_type key_type_user;
@@ -36,7 +47,7 @@ extern struct key_type key_type_user;
*/
struct key_user {
struct rb_node node;
- struct list_head consq; /* construction queue */
+ struct mutex cons_lock; /* construction initiation lock */
spinlock_t lock;
atomic_t usage; /* for accessing qnkeys & qnbytes */
atomic_t nkeys; /* number of keys */
@@ -62,7 +73,7 @@ extern void key_user_put(struct key_user *user);
extern struct rb_root key_serial_tree;
extern spinlock_t key_serial_lock;
extern struct semaphore key_alloc_sem;
-extern struct rw_semaphore key_construction_sem;
+extern struct mutex key_construction_mutex;
extern wait_queue_head_t request_key_conswq;
@@ -109,7 +120,7 @@ extern struct key *request_key_and_link(struct key_type *type,
struct request_key_auth {
struct key *target_key;
struct task_struct *context;
- const char *callout_info;
+ char *callout_info;
pid_t pid;
};
diff --git a/security/keys/key.c b/security/keys/key.c
index 01bbc6d9d19..fdd5ca6d89f 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
-/* key.c: basic authentication token and access key management
+/* Basic authentication token and access key management
*
- * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@ static void key_cleanup(struct work_struct *work);
static DECLARE_WORK(key_cleanup_task, key_cleanup);
/* we serialise key instantiation and link */
-DECLARE_RWSEM(key_construction_sem);
+DEFINE_MUTEX(key_construction_mutex);
/* any key who's type gets unegistered will be re-typed to this */
static struct key_type key_type_dead = {
@@ -104,7 +104,7 @@ struct key_user *key_user_lookup(uid_t uid)
candidate->qnkeys = 0;
candidate->qnbytes = 0;
spin_lock_init(&candidate->lock);
- INIT_LIST_HEAD(&candidate->consq);
+ mutex_init(&candidate->cons_lock);
rb_link_node(&candidate->node, parent, p);
rb_insert_color(&candidate->node, &key_user_tree);
@@ -418,7 +418,7 @@ static int __key_instantiate_and_link(struct key *key,
awaken = 0;
ret = -EBUSY;
- down_write(&key_construction_sem);
+ mutex_lock(&key_construction_mutex);
/* can't instantiate twice */
if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
@@ -443,11 +443,11 @@ static int __key_instantiate_and_link(struct key *key,
}
}
- up_write(&key_construction_sem);
+ mutex_unlock(&key_construction_mutex);
/* wake up anyone waiting for a key to be constructed */
if (awaken)
- wake_up_all(&request_key_conswq);
+ wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
return ret;
@@ -500,7 +500,7 @@ int key_negate_and_link(struct key *key,
if (keyring)
down_write(&keyring->sem);
- down_write(&key_construction_sem);
+ mutex_lock(&key_construction_mutex);
/* can't instantiate twice */
if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
@@ -525,14 +525,14 @@ int key_negate_and_link(struct key *key,
key_revoke(instkey);
}
- up_write(&key_construction_sem);
+ mutex_unlock(&key_construction_mutex);
if (keyring)
up_write(&keyring->sem);
/* wake up anyone waiting for a key to be constructed */
if (awaken)
- wake_up_all(&request_key_conswq);
+ wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
return ret;
@@ -899,12 +899,14 @@ void key_revoke(struct key *key)
{
key_check(key);
- /* make sure no one's trying to change or use the key when we mark
- * it */
- down_write(&key->sem);
- set_bit(KEY_FLAG_REVOKED, &key->flags);
-
- if (key->type->revoke)
+ /* make sure no one's trying to change or use the key when we mark it
+ * - we tell lockdep that we might nest because we might be revoking an
+ * authorisation key whilst holding the sem on a key we've just
+ * instantiated
+ */
+ down_write_nested(&key->sem, 1);
+ if (!test_and_set_bit(KEY_FLAG_REVOKED, &key->flags) &&
+ key->type->revoke)
key->type->revoke(key);
up_write(&key->sem);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index b6f86808475..2a0eb946fc7 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -26,7 +26,7 @@ static DEFINE_MUTEX(key_session_mutex);
/* the root user's tracking struct */
struct key_user root_key_user = {
.usage = ATOMIC_INIT(3),
- .consq = LIST_HEAD_INIT(root_key_user.consq),
+ .cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock),
.lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
.nkeys = ATOMIC_INIT(2),
.nikeys = ATOMIC_INIT(2),
@@ -679,8 +679,18 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
break;
}
- /* check the status */
- if (perm) {
+ if (!partial) {
+ ret = wait_for_key_construction(key, true);
+ switch (ret) {
+ case -ERESTARTSYS:
+ goto invalid_key;
+ default:
+ if (perm)
+ goto invalid_key;
+ case 0:
+ break;
+ }
+ } else if (perm) {
ret = key_validate(key);
if (ret < 0)
goto invalid_key;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 557500110a1..6381e616c47 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -1,6 +1,6 @@
-/* request_key.c: request a key from userspace
+/* Request a key from userspace
*
- * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -18,27 +18,54 @@
#include <linux/keyctl.h>
#include "internal.h"
-struct key_construction {
- struct list_head link; /* link in construction queue */
- struct key *key; /* key being constructed */
-};
+/*
+ * wait_on_bit() sleep function for uninterruptible waiting
+ */
+static int key_wait_bit(void *flags)
+{
+ schedule();
+ return 0;
+}
+
+/*
+ * wait_on_bit() sleep function for interruptible waiting
+ */
+static int key_wait_bit_intr(void *flags)
+{
+ schedule();
+ return signal_pending(current) ? -ERESTARTSYS : 0;
+}
+
+/*
+ * call to complete the construction of a key
+ */
+void complete_request_key(struct key_construction *cons, int error)
+{
+ kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
-/* when waiting for someone else's keys, you get added to this */
-DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
+ if (error < 0)
+ key_negate_and_link(cons->key, key_negative_timeout, NULL,
+ cons->authkey);
+ else
+ key_revoke(cons->authkey);
+
+ key_put(cons->key);
+ key_put(cons->authkey);
+ kfree(cons);
+}
+EXPORT_SYMBOL(complete_request_key);
-/*****************************************************************************/
/*
* request userspace finish the construction of a key
* - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
*/
-static int call_sbin_request_key(struct key *key,
- struct key *authkey,
+static int call_sbin_request_key(struct key_construction *cons,
const char *op,
void *aux)
{
struct task_struct *tsk = current;
key_serial_t prkey, sskey;
- struct key *keyring;
+ struct key *key = cons->key, *authkey = cons->authkey, *keyring;
char *argv[9], *envp[3], uid_str[12], gid_str[12];
char key_str[12], keyring_str[3][12];
char desc[20];
@@ -82,8 +109,7 @@ static int call_sbin_request_key(struct key *key,
rcu_read_lock();
sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
rcu_read_unlock();
- }
- else {
+ } else {
sskey = tsk->user->session_keyring->serial;
}
@@ -110,228 +136,77 @@ static int call_sbin_request_key(struct key *key,
/* do it */
ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
UMH_WAIT_PROC);
+ kdebug("usermode -> 0x%x", ret);
+ if (ret >= 0) {
+ /* ret is the exit/wait code */
+ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
+ key_validate(key) < 0)
+ ret = -ENOKEY;
+ else
+ /* ignore any errors from userspace if the key was
+ * instantiated */
+ ret = 0;
+ }
error_link:
key_put(keyring);
error_alloc:
kleave(" = %d", ret);
+ complete_request_key(cons, ret);
return ret;
+}
-} /* end call_sbin_request_key() */
-
-/*****************************************************************************/
/*
- * call out to userspace for the key
- * - called with the construction sem held, but the sem is dropped here
+ * call out to userspace for key construction
* - we ignore program failure and go on key status instead
*/
-static struct key *__request_key_construction(struct key_type *type,
- const char *description,
- const char *callout_info,
- void *aux,
- unsigned long flags)
+static int construct_key(struct key *key, const char *callout_info, void *aux)
{
+ struct key_construction *cons;
request_key_actor_t actor;
- struct key_construction cons;
- struct timespec now;
- struct key *key, *authkey;
- int ret, negated;
+ struct key *authkey;
+ int ret;
- kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags);
+ kenter("%d,%s,%p", key->serial, callout_info, aux);
- /* create a key and add it to the queue */
- key = key_alloc(type, description,
- current->fsuid, current->fsgid, current, KEY_POS_ALL,
- flags);
- if (IS_ERR(key))
- goto alloc_failed;
-
- set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
-
- cons.key = key;
- list_add_tail(&cons.link, &key->user->consq);
-
- /* we drop the construction sem here on behalf of the caller */
- up_write(&key_construction_sem);
+ cons = kmalloc(sizeof(*cons), GFP_KERNEL);
+ if (!cons)
+ return -ENOMEM;
/* allocate an authorisation key */
authkey = request_key_auth_new(key, callout_info);
if (IS_ERR(authkey)) {
+ kfree(cons);
ret = PTR_ERR(authkey);
authkey = NULL;
- goto alloc_authkey_failed;
- }
-
- /* make the call */
- actor = call_sbin_request_key;
- if (type->request_key)
- actor = type->request_key;
- ret = actor(key, authkey, "create", aux);
- if (ret < 0)
- goto request_failed;
-
- /* if the key wasn't instantiated, then we want to give an error */
- ret = -ENOKEY;
- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
- goto request_failed;
-
- key_revoke(authkey);
- key_put(authkey);
-
- down_write(&key_construction_sem);
- list_del(&cons.link);
- up_write(&key_construction_sem);
-
- /* also give an error if the key was negatively instantiated */
-check_not_negative:
- if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
- key_put(key);
- key = ERR_PTR(-ENOKEY);
- }
-
-out:
- kleave(" = %p", key);
- return key;
-
-request_failed:
- key_revoke(authkey);
- key_put(authkey);
-
-alloc_authkey_failed:
- /* it wasn't instantiated
- * - remove from construction queue
- * - mark the key as dead
- */
- negated = 0;
- down_write(&key_construction_sem);
-
- list_del(&cons.link);
-
- /* check it didn't get instantiated between the check and the down */
- if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
- set_bit(KEY_FLAG_NEGATIVE, &key->flags);
- set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
- negated = 1;
- }
-
- clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
-
- up_write(&key_construction_sem);
-
- if (!negated)
- goto check_not_negative; /* surprisingly, the key got
- * instantiated */
-
- /* set the timeout and store in the session keyring if we can */
- now = current_kernel_time();
- key->expiry = now.tv_sec + key_negative_timeout;
-
- if (current->signal->session_keyring) {
- struct key *keyring;
-
- rcu_read_lock();
- keyring = rcu_dereference(current->signal->session_keyring);
- atomic_inc(&keyring->usage);
- rcu_read_unlock();
-
- key_link(keyring, key);
- key_put(keyring);
- }
-
- key_put(key);
-
- /* notify anyone who was waiting */
- wake_up_all(&request_key_conswq);
-
- key = ERR_PTR(ret);
- goto out;
-
-alloc_failed:
- up_write(&key_construction_sem);
- goto out;
-
-} /* end __request_key_construction() */
-
-/*****************************************************************************/
-/*
- * call out to userspace to request the key
- * - we check the construction queue first to see if an appropriate key is
- * already being constructed by userspace
- */
-static struct key *request_key_construction(struct key_type *type,
- const char *description,
- const char *callout_info,
- void *aux,
- struct key_user *user,
- unsigned long flags)
-{
- struct key_construction *pcons;
- struct key *key, *ckey;
-
- DECLARE_WAITQUEUE(myself, current);
-
- kenter("%s,%s,{%d},%s,%lx",
- type->name, description, user->uid, callout_info, flags);
-
- /* see if there's such a key under construction already */
- down_write(&key_construction_sem);
-
- list_for_each_entry(pcons, &user->consq, link) {
- ckey = pcons->key;
-
- if (ckey->type != type)
- continue;
-
- if (type->match(ckey, description))
- goto found_key_under_construction;
+ } else {
+ cons->authkey = key_get(authkey);
+ cons->key = key_get(key);
+
+ /* make the call */
+ actor = call_sbin_request_key;
+ if (key->type->request_key)
+ actor = key->type->request_key;
+
+ ret = actor(cons, "create", aux);
+
+ /* check that the actor called complete_request_key() prior to
+ * returning an error */
+ WARN_ON(ret < 0 &&
+ !test_bit(KEY_FLAG_REVOKED, &authkey->flags));
+ key_put(authkey);
}
- /* see about getting userspace to construct the key */
- key = __request_key_construction(type, description, callout_info, aux,
- flags);
- error:
- kleave(" = %p", key);
- return key;
-
- /* someone else has the same key under construction
- * - we want to keep an eye on their key
- */
- found_key_under_construction:
- atomic_inc(&ckey->usage);
- up_write(&key_construction_sem);
-
- /* wait for the key to be completed one way or another */
- add_wait_queue(&request_key_conswq, &myself);
-
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
- break;
- if (signal_pending(current))
- break;
- schedule();
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&request_key_conswq, &myself);
-
- /* we'll need to search this process's keyrings to see if the key is
- * now there since we can't automatically assume it's also available
- * there */
- key_put(ckey);
- ckey = NULL;
-
- key = NULL; /* request a retry */
- goto error;
-
-} /* end request_key_construction() */
+ kleave(" = %d", ret);
+ return ret;
+}
-/*****************************************************************************/
/*
- * link a freshly minted key to an appropriate destination keyring
+ * link a key to the appropriate destination keyring
+ * - the caller must hold a write lock on the destination keyring
*/
-static void request_key_link(struct key *key, struct key *dest_keyring)
+static void construct_key_make_link(struct key *key, struct key *dest_keyring)
{
struct task_struct *tsk = current;
struct key *drop = NULL;
@@ -363,11 +238,11 @@ static void request_key_link(struct key *key, struct key *dest_keyring)
break;
case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
- dest_keyring = current->user->session_keyring;
+ dest_keyring = tsk->user->session_keyring;
break;
case KEY_REQKEY_DEFL_USER_KEYRING:
- dest_keyring = current->user->uid_keyring;
+ dest_keyring = tsk->user->uid_keyring;
break;
case KEY_REQKEY_DEFL_GROUP_KEYRING:
@@ -377,15 +252,115 @@ static void request_key_link(struct key *key, struct key *dest_keyring)
}
/* and attach the key to it */
- key_link(dest_keyring, key);
-
+ __key_link(dest_keyring, key);
key_put(drop);
-
kleave("");
+}
-} /* end request_key_link() */
+/*
+ * allocate a new key in under-construction state and attempt to link it in to
+ * the requested place
+ * - may return a key that's already under construction instead
+ */
+static int construct_alloc_key(struct key_type *type,
+ const char *description,
+ struct key *dest_keyring,
+ unsigned long flags,
+ struct key_user *user,
+ struct key **_key)
+{
+ struct key *key;
+ key_ref_t key_ref;
+
+ kenter("%s,%s,,,", type->name, description);
+
+ mutex_lock(&user->cons_lock);
+
+ key = key_alloc(type, description,
+ current->fsuid, current->fsgid, current, KEY_POS_ALL,
+ flags);
+ if (IS_ERR(key))
+ goto alloc_failed;
+
+ set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
+
+ if (dest_keyring)
+ down_write(&dest_keyring->sem);
+
+ /* attach the key to the destination keyring under lock, but we do need
+ * to do another check just in case someone beat us to it whilst we
+ * waited for locks */
+ mutex_lock(&key_construction_mutex);
+
+ key_ref = search_process_keyrings(type, description, type->match,
+ current);
+ if (!IS_ERR(key_ref))
+ goto key_already_present;
+
+ if (dest_keyring)
+ construct_key_make_link(key, dest_keyring);
+
+ mutex_unlock(&key_construction_mutex);
+ if (dest_keyring)
+ up_write(&dest_keyring->sem);
+ mutex_unlock(&user->cons_lock);
+ *_key = key;
+ kleave(" = 0 [%d]", key_serial(key));
+ return 0;
+
+key_already_present:
+ mutex_unlock(&key_construction_mutex);
+ if (dest_keyring)
+ up_write(&dest_keyring->sem);
+ mutex_unlock(&user->cons_lock);
+ key_put(key);
+ *_key = key = key_ref_to_ptr(key_ref);
+ kleave(" = -EINPROGRESS [%d]", key_serial(key));
+ return -EINPROGRESS;
+
+alloc_failed:
+ mutex_unlock(&user->cons_lock);
+ *_key = NULL;
+ kleave(" = %ld", PTR_ERR(key));
+ return PTR_ERR(key);
+}
+
+/*
+ * commence key construction
+ */
+static struct key *construct_key_and_link(struct key_type *type,
+ const char *description,
+ const char *callout_info,
+ void *aux,
+ struct key *dest_keyring,
+ unsigned long flags)
+{
+ struct key_user *user;
+ struct key *key;
+ int ret;
+
+ user = key_user_lookup(current->fsuid);
+ if (!user)
+ return ERR_PTR(-ENOMEM);
+
+ ret = construct_alloc_key(type, description, dest_keyring, flags, user,
+ &key);
+ key_user_put(user);
+
+ if (ret == 0) {
+ ret = construct_key(key, callout_info, aux);
+ if (ret < 0)
+ goto construction_failed;
+ }
+
+ return key;
+
+construction_failed:
+ key_negate_and_link(key, key_negative_timeout, NULL, NULL);
+ key_put(key);
+ return ERR_PTR(ret);
+}
-/*****************************************************************************/
/*
* request a key
* - search the process's keyrings
@@ -400,7 +375,6 @@ struct key *request_key_and_link(struct key_type *type,
struct key *dest_keyring,
unsigned long flags)
{
- struct key_user *user;
struct key *key;
key_ref_t key_ref;
@@ -412,112 +386,124 @@ struct key *request_key_and_link(struct key_type *type,
key_ref = search_process_keyrings(type, description, type->match,
current);
- kdebug("search 1: %p", key_ref);
-
if (!IS_ERR(key_ref)) {
key = key_ref_to_ptr(key_ref);
- }
- else if (PTR_ERR(key_ref) != -EAGAIN) {
+ } else if (PTR_ERR(key_ref) != -EAGAIN) {
key = ERR_PTR(PTR_ERR(key_ref));
- }
- else {
+ } else {
/* the search failed, but the keyrings were searchable, so we
* should consult userspace if we can */
key = ERR_PTR(-ENOKEY);
if (!callout_info)
goto error;
- /* - get hold of the user's construction queue */
- user = key_user_lookup(current->fsuid);
- if (!user)
- goto nomem;
-
- for (;;) {
- if (signal_pending(current))
- goto interrupted;
-
- /* ask userspace (returns NULL if it waited on a key
- * being constructed) */
- key = request_key_construction(type, description,
- callout_info, aux,
- user, flags);
- if (key)
- break;
-
- /* someone else made the key we want, so we need to
- * search again as it might now be available to us */
- key_ref = search_process_keyrings(type, description,
- type->match,
- current);
-
- kdebug("search 2: %p", key_ref);
-
- if (!IS_ERR(key_ref)) {
- key = key_ref_to_ptr(key_ref);
- break;
- }
-
- if (PTR_ERR(key_ref) != -EAGAIN) {
- key = ERR_PTR(PTR_ERR(key_ref));
- break;
- }
- }
-
- key_user_put(user);
-
- /* link the new key into the appropriate keyring */
- if (!IS_ERR(key))
- request_key_link(key, dest_keyring);
+ key = construct_key_and_link(type, description, callout_info,
+ aux, dest_keyring, flags);
}
error:
kleave(" = %p", key);
return key;
+}
-nomem:
- key = ERR_PTR(-ENOMEM);
- goto error;
-
-interrupted:
- key_user_put(user);
- key = ERR_PTR(-EINTR);
- goto error;
+/*
+ * wait for construction of a key to complete
+ */
+int wait_for_key_construction(struct key *key, bool intr)
+{
+ int ret;
-} /* end request_key_and_link() */
+ ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
+ intr ? key_wait_bit_intr : key_wait_bit,
+ intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+ if (ret < 0)
+ return ret;
+ return key_validate(key);
+}
+EXPORT_SYMBOL(wait_for_key_construction);
-/*****************************************************************************/
/*
* request a key
* - search the process's keyrings
* - check the list of keys being created or updated
* - call out to userspace for a key if supplementary info was provided
+ * - waits uninterruptible for creation to complete
*/
struct key *request_key(struct key_type *type,
const char *description,
const char *callout_info)
{
- return request_key_and_link(type, description, callout_info, NULL,
- NULL, KEY_ALLOC_IN_QUOTA);
-
-} /* end request_key() */
-
+ struct key *key;
+ int ret;
+
+ key = request_key_and_link(type, description, callout_info, NULL,
+ NULL, KEY_ALLOC_IN_QUOTA);
+ if (!IS_ERR(key)) {
+ ret = wait_for_key_construction(key, false);
+ if (ret < 0) {
+ key_put(key);
+ return ERR_PTR(ret);
+ }
+ }
+ return key;
+}
EXPORT_SYMBOL(request_key);
-/*****************************************************************************/
/*
* request a key with auxiliary data for the upcaller
* - search the process's keyrings
* - check the list of keys being created or updated
* - call out to userspace for a key if supplementary info was provided
+ * - waits uninterruptible for creation to complete
*/
struct key *request_key_with_auxdata(struct key_type *type,
const char *description,
const char *callout_info,
void *aux)
{
- return request_key_and_link(type, description, callout_info, aux,
- NULL, KEY_ALLOC_IN_QUOTA);
+ struct key *key;
+ int ret;
+
+ key = request_key_and_link(type, description, callout_info, aux,
+ NULL, KEY_ALLOC_IN_QUOTA);
+ if (!IS_ERR(key)) {
+ ret = wait_for_key_construction(key, false);
+ if (ret < 0) {
+ key_put(key);
+ return ERR_PTR(ret);
+ }
+ }
+ return key;
+}
+EXPORT_SYMBOL(request_key_with_auxdata);
-} /* end request_key_with_auxdata() */
+/*
+ * request a key (allow async construction)
+ * - search the process's keyrings
+ * - check the list of keys being created or updated
+ * - call out to userspace for a key if supplementary info was provided
+ */
+struct key *request_key_async(struct key_type *type,
+ const char *description,
+ const char *callout_info)
+{
+ return request_key_and_link(type, description, callout_info, NULL,
+ NULL, KEY_ALLOC_IN_QUOTA);
+}
+EXPORT_SYMBOL(request_key_async);
-EXPORT_SYMBOL(request_key_with_auxdata);
+/*
+ * request a key with auxiliary data for the upcaller (allow async construction)
+ * - search the process's keyrings
+ * - check the list of keys being created or updated
+ * - call out to userspace for a key if supplementary info was provided
+ */
+struct key *request_key_async_with_auxdata(struct key_type *type,
+ const char *description,
+ const char *callout_info,
+ void *aux)
+{
+ return request_key_and_link(type, description, callout_info, aux,
+ NULL, KEY_ALLOC_IN_QUOTA);
+}
+EXPORT_SYMBOL(request_key_async_with_auxdata);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index cbf58a91b00..510f7be73a2 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -127,6 +127,7 @@ static void request_key_auth_destroy(struct key *key)
}
key_put(rka->target_key);
+ kfree(rka->callout_info);
kfree(rka);
} /* end request_key_auth_destroy() */
@@ -151,6 +152,12 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
kleave(" = -ENOMEM");
return ERR_PTR(-ENOMEM);
}
+ rka->callout_info = kmalloc(strlen(callout_info) + 1, GFP_KERNEL);
+ if (!rka->callout_info) {
+ kleave(" = -ENOMEM");
+ kfree(rka);
+ return ERR_PTR(-ENOMEM);
+ }
/* see if the calling process is already servicing the key request of
* another process */
@@ -179,7 +186,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
}
rka->target_key = key_get(target);
- rka->callout_info = callout_info;
+ strcpy(rka->callout_info, callout_info);
/* allocate the auth key */
sprintf(desc, "%x", target->serial);
@@ -203,6 +210,7 @@ struct key *request_key_auth_new(struct key *target, const char *callout_info)
auth_key_revoked:
up_read(&current->request_key_auth->sem);
+ kfree(rka->callout_info);
kfree(rka);
kleave("= -EKEYREVOKED");
return ERR_PTR(-EKEYREVOKED);
@@ -212,6 +220,7 @@ error_inst:
key_put(authkey);
error_alloc:
key_put(rka->target_key);
+ kfree(rka->callout_info);
kfree(rka);
kleave("= %d", ret);
return ERR_PTR(ret);
diff --git a/security/root_plug.c b/security/root_plug.c
index 38dd4f3e641..870f13095bb 100644
--- a/security/root_plug.c
+++ b/security/root_plug.c
@@ -22,11 +22,11 @@
* License.
*/
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/security.h>
#include <linux/usb.h>
+#include <linux/moduleparam.h>
/* flag to keep track of how we were registered */
static int secondary;
@@ -36,22 +36,14 @@ static int vendor_id = 0x0557;
static int product_id = 0x2008;
module_param(vendor_id, uint, 0400);
-MODULE_PARM_DESC(vendor_id, "USB Vendor ID of device to look for");
-
module_param(product_id, uint, 0400);
-MODULE_PARM_DESC(product_id, "USB Product ID of device to look for");
/* should we print out debug messages */
static int debug = 0;
module_param(debug, bool, 0600);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-#if defined(CONFIG_SECURITY_ROOTPLUG_MODULE)
-#define MY_NAME THIS_MODULE->name
-#else
#define MY_NAME "root_plug"
-#endif
#define root_dbg(fmt, arg...) \
do { \
@@ -117,25 +109,4 @@ static int __init rootplug_init (void)
return 0;
}
-static void __exit rootplug_exit (void)
-{
- /* remove ourselves from the security framework */
- if (secondary) {
- if (mod_unreg_security (MY_NAME, &rootplug_security_ops))
- printk (KERN_INFO "Failure unregistering Root Plug "
- " module with primary module.\n");
- } else {
- if (unregister_security (&rootplug_security_ops)) {
- printk (KERN_INFO "Failure unregistering Root Plug "
- "module with the kernel\n");
- }
- }
- printk (KERN_INFO "Root Plug module removed\n");
-}
-
security_initcall (rootplug_init);
-module_exit (rootplug_exit);
-
-MODULE_DESCRIPTION("Root Plug sample LSM module, written for Linux Journal article");
-MODULE_LICENSE("GPL");
-
diff --git a/security/security.c b/security/security.c
index 27e5863d30f..0e1f1f12436 100644
--- a/security/security.c
+++ b/security/security.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/security.h>
-#define SECURITY_FRAMEWORK_VERSION "1.0.0"
/* things that live in dummy.c */
extern struct security_operations dummy_security_ops;
@@ -52,8 +51,7 @@ static void __init do_security_initcalls(void)
*/
int __init security_init(void)
{
- printk(KERN_INFO "Security Framework v" SECURITY_FRAMEWORK_VERSION
- " initialized\n");
+ printk(KERN_INFO "Security Framework initialized\n");
if (verify(&dummy_security_ops)) {
printk(KERN_ERR "%s could not verify "
@@ -73,8 +71,7 @@ int __init security_init(void)
*
* This function is to allow a security module to register itself with the
* kernel security subsystem. Some rudimentary checking is done on the @ops
- * value passed to this function. A call to unregister_security() should be
- * done to remove this security_options structure from the kernel.
+ * value passed to this function.
*
* If there is already a security module registered with the kernel,
* an error will be returned. Otherwise 0 is returned on success.
@@ -96,31 +93,6 @@ int register_security(struct security_operations *ops)
}
/**
- * unregister_security - unregisters a security framework with the kernel
- * @ops: a pointer to the struct security_options that is to be registered
- *
- * This function removes a struct security_operations variable that had
- * previously been registered with a successful call to register_security().
- *
- * If @ops does not match the valued previously passed to register_security()
- * an error is returned. Otherwise the default security options is set to the
- * the dummy_security_ops structure, and 0 is returned.
- */
-int unregister_security(struct security_operations *ops)
-{
- if (ops != security_ops) {
- printk(KERN_INFO "%s: trying to unregister "
- "a security_opts structure that is not "
- "registered, failing.\n", __FUNCTION__);
- return -EINVAL;
- }
-
- security_ops = &dummy_security_ops;
-
- return 0;
-}
-
-/**
* mod_reg_security - allows security modules to be "stacked"
* @name: a pointer to a string with the name of the security_options to be registered
* @ops: a pointer to the struct security_options that is to be registered
@@ -149,32 +121,962 @@ int mod_reg_security(const char *name, struct security_operations *ops)
return security_ops->register_security(name, ops);
}
-/**
- * mod_unreg_security - allows a security module registered with mod_reg_security() to be unloaded
- * @name: a pointer to a string with the name of the security_options to be removed
- * @ops: a pointer to the struct security_options that is to be removed
- *
- * This function allows security modules that have been successfully registered
- * with a call to mod_reg_security() to be unloaded from the system.
- * This calls the currently loaded security module's unregister_security() call
- * with the @name and @ops variables.
- *
- * The return value depends on the currently loaded security module, with 0 as
- * success.
- */
-int mod_unreg_security(const char *name, struct security_operations *ops)
+/* Security operations */
+
+int security_ptrace(struct task_struct *parent, struct task_struct *child)
{
- if (ops == security_ops) {
- printk(KERN_INFO "%s invalid attempt to unregister "
- " primary security ops.\n", __FUNCTION__);
- return -EINVAL;
- }
+ return security_ops->ptrace(parent, child);
+}
+
+int security_capget(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted)
+{
+ return security_ops->capget(target, effective, inheritable, permitted);
+}
+
+int security_capset_check(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted)
+{
+ return security_ops->capset_check(target, effective, inheritable, permitted);
+}
+
+void security_capset_set(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted)
+{
+ security_ops->capset_set(target, effective, inheritable, permitted);
+}
+
+int security_capable(struct task_struct *tsk, int cap)
+{
+ return security_ops->capable(tsk, cap);
+}
+
+int security_acct(struct file *file)
+{
+ return security_ops->acct(file);
+}
+
+int security_sysctl(struct ctl_table *table, int op)
+{
+ return security_ops->sysctl(table, op);
+}
+
+int security_quotactl(int cmds, int type, int id, struct super_block *sb)
+{
+ return security_ops->quotactl(cmds, type, id, sb);
+}
+
+int security_quota_on(struct dentry *dentry)
+{
+ return security_ops->quota_on(dentry);
+}
+
+int security_syslog(int type)
+{
+ return security_ops->syslog(type);
+}
+
+int security_settime(struct timespec *ts, struct timezone *tz)
+{
+ return security_ops->settime(ts, tz);
+}
+
+int security_vm_enough_memory(long pages)
+{
+ return security_ops->vm_enough_memory(current->mm, pages);
+}
+
+int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
+{
+ return security_ops->vm_enough_memory(mm, pages);
+}
+
+int security_bprm_alloc(struct linux_binprm *bprm)
+{
+ return security_ops->bprm_alloc_security(bprm);
+}
+
+void security_bprm_free(struct linux_binprm *bprm)
+{
+ security_ops->bprm_free_security(bprm);
+}
+
+void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
+{
+ security_ops->bprm_apply_creds(bprm, unsafe);
+}
+
+void security_bprm_post_apply_creds(struct linux_binprm *bprm)
+{
+ security_ops->bprm_post_apply_creds(bprm);
+}
+
+int security_bprm_set(struct linux_binprm *bprm)
+{
+ return security_ops->bprm_set_security(bprm);
+}
+
+int security_bprm_check(struct linux_binprm *bprm)
+{
+ return security_ops->bprm_check_security(bprm);
+}
+
+int security_bprm_secureexec(struct linux_binprm *bprm)
+{
+ return security_ops->bprm_secureexec(bprm);
+}
+
+int security_sb_alloc(struct super_block *sb)
+{
+ return security_ops->sb_alloc_security(sb);
+}
+
+void security_sb_free(struct super_block *sb)
+{
+ security_ops->sb_free_security(sb);
+}
+
+int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy)
+{
+ return security_ops->sb_copy_data(type, orig, copy);
+}
+
+int security_sb_kern_mount(struct super_block *sb, void *data)
+{
+ return security_ops->sb_kern_mount(sb, data);
+}
+
+int security_sb_statfs(struct dentry *dentry)
+{
+ return security_ops->sb_statfs(dentry);
+}
+
+int security_sb_mount(char *dev_name, struct nameidata *nd,
+ char *type, unsigned long flags, void *data)
+{
+ return security_ops->sb_mount(dev_name, nd, type, flags, data);
+}
+
+int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd)
+{
+ return security_ops->sb_check_sb(mnt, nd);
+}
+
+int security_sb_umount(struct vfsmount *mnt, int flags)
+{
+ return security_ops->sb_umount(mnt, flags);
+}
+
+void security_sb_umount_close(struct vfsmount *mnt)
+{
+ security_ops->sb_umount_close(mnt);
+}
+
+void security_sb_umount_busy(struct vfsmount *mnt)
+{
+ security_ops->sb_umount_busy(mnt);
+}
+
+void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data)
+{
+ security_ops->sb_post_remount(mnt, flags, data);
+}
+
+void security_sb_post_mountroot(void)
+{
+ security_ops->sb_post_mountroot();
+}
+
+void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd)
+{
+ security_ops->sb_post_addmount(mnt, mountpoint_nd);
+}
+
+int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
+{
+ return security_ops->sb_pivotroot(old_nd, new_nd);
+}
+
+void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
+{
+ security_ops->sb_post_pivotroot(old_nd, new_nd);
+}
+
+int security_inode_alloc(struct inode *inode)
+{
+ inode->i_security = NULL;
+ return security_ops->inode_alloc_security(inode);
+}
+
+void security_inode_free(struct inode *inode)
+{
+ security_ops->inode_free_security(inode);
+}
+
+int security_inode_init_security(struct inode *inode, struct inode *dir,
+ char **name, void **value, size_t *len)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return -EOPNOTSUPP;
+ return security_ops->inode_init_security(inode, dir, name, value, len);
+}
+EXPORT_SYMBOL(security_inode_init_security);
+
+int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+ if (unlikely(IS_PRIVATE(dir)))
+ return 0;
+ return security_ops->inode_create(dir, dentry, mode);
+}
+
+int security_inode_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *new_dentry)
+{
+ if (unlikely(IS_PRIVATE(old_dentry->d_inode)))
+ return 0;
+ return security_ops->inode_link(old_dentry, dir, new_dentry);
+}
+
+int security_inode_unlink(struct inode *dir, struct dentry *dentry)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_unlink(dir, dentry);
+}
+
+int security_inode_symlink(struct inode *dir, struct dentry *dentry,
+ const char *old_name)
+{
+ if (unlikely(IS_PRIVATE(dir)))
+ return 0;
+ return security_ops->inode_symlink(dir, dentry, old_name);
+}
+
+int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ if (unlikely(IS_PRIVATE(dir)))
+ return 0;
+ return security_ops->inode_mkdir(dir, dentry, mode);
+}
+
+int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_rmdir(dir, dentry);
+}
+
+int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+ if (unlikely(IS_PRIVATE(dir)))
+ return 0;
+ return security_ops->inode_mknod(dir, dentry, mode, dev);
+}
+
+int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ if (unlikely(IS_PRIVATE(old_dentry->d_inode) ||
+ (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode))))
+ return 0;
+ return security_ops->inode_rename(old_dir, old_dentry,
+ new_dir, new_dentry);
+}
+
+int security_inode_readlink(struct dentry *dentry)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_readlink(dentry);
+}
+
+int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_follow_link(dentry, nd);
+}
+
+int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return 0;
+ return security_ops->inode_permission(inode, mask, nd);
+}
+
+int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_setattr(dentry, attr);
+}
+
+int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_getattr(mnt, dentry);
+}
+
+void security_inode_delete(struct inode *inode)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return;
+ security_ops->inode_delete(inode);
+}
+
+int security_inode_setxattr(struct dentry *dentry, char *name,
+ void *value, size_t size, int flags)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_setxattr(dentry, name, value, size, flags);
+}
+
+void security_inode_post_setxattr(struct dentry *dentry, char *name,
+ void *value, size_t size, int flags)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return;
+ security_ops->inode_post_setxattr(dentry, name, value, size, flags);
+}
+
+int security_inode_getxattr(struct dentry *dentry, char *name)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_getxattr(dentry, name);
+}
+
+int security_inode_listxattr(struct dentry *dentry)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_listxattr(dentry);
+}
+
+int security_inode_removexattr(struct dentry *dentry, char *name)
+{
+ if (unlikely(IS_PRIVATE(dentry->d_inode)))
+ return 0;
+ return security_ops->inode_removexattr(dentry, name);
+}
+
+int security_inode_need_killpriv(struct dentry *dentry)
+{
+ return security_ops->inode_need_killpriv(dentry);
+}
+
+int security_inode_killpriv(struct dentry *dentry)
+{
+ return security_ops->inode_killpriv(dentry);
+}
+
+int security_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return 0;
+ return security_ops->inode_getsecurity(inode, name, buffer, size, err);
+}
+
+int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return 0;
+ return security_ops->inode_setsecurity(inode, name, value, size, flags);
+}
+
+int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size)
+{
+ if (unlikely(IS_PRIVATE(inode)))
+ return 0;
+ return security_ops->inode_listsecurity(inode, buffer, buffer_size);
+}
+
+int security_file_permission(struct file *file, int mask)
+{
+ return security_ops->file_permission(file, mask);
+}
+
+int security_file_alloc(struct file *file)
+{
+ return security_ops->file_alloc_security(file);
+}
+
+void security_file_free(struct file *file)
+{
+ security_ops->file_free_security(file);
+}
+
+int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return security_ops->file_ioctl(file, cmd, arg);
+}
+
+int security_file_mmap(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags,
+ unsigned long addr, unsigned long addr_only)
+{
+ return security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+}
+
+int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
+ unsigned long prot)
+{
+ return security_ops->file_mprotect(vma, reqprot, prot);
+}
+
+int security_file_lock(struct file *file, unsigned int cmd)
+{
+ return security_ops->file_lock(file, cmd);
+}
+
+int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return security_ops->file_fcntl(file, cmd, arg);
+}
+
+int security_file_set_fowner(struct file *file)
+{
+ return security_ops->file_set_fowner(file);
+}
+
+int security_file_send_sigiotask(struct task_struct *tsk,
+ struct fown_struct *fown, int sig)
+{
+ return security_ops->file_send_sigiotask(tsk, fown, sig);
+}
+
+int security_file_receive(struct file *file)
+{
+ return security_ops->file_receive(file);
+}
+
+int security_dentry_open(struct file *file)
+{
+ return security_ops->dentry_open(file);
+}
+
+int security_task_create(unsigned long clone_flags)
+{
+ return security_ops->task_create(clone_flags);
+}
+
+int security_task_alloc(struct task_struct *p)
+{
+ return security_ops->task_alloc_security(p);
+}
+
+void security_task_free(struct task_struct *p)
+{
+ security_ops->task_free_security(p);
+}
+
+int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
+{
+ return security_ops->task_setuid(id0, id1, id2, flags);
+}
+
+int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
+ uid_t old_suid, int flags)
+{
+ return security_ops->task_post_setuid(old_ruid, old_euid, old_suid, flags);
+}
+
+int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
+{
+ return security_ops->task_setgid(id0, id1, id2, flags);
+}
- return security_ops->unregister_security(name, ops);
+int security_task_setpgid(struct task_struct *p, pid_t pgid)
+{
+ return security_ops->task_setpgid(p, pgid);
+}
+
+int security_task_getpgid(struct task_struct *p)
+{
+ return security_ops->task_getpgid(p);
+}
+
+int security_task_getsid(struct task_struct *p)
+{
+ return security_ops->task_getsid(p);
+}
+
+void security_task_getsecid(struct task_struct *p, u32 *secid)
+{
+ security_ops->task_getsecid(p, secid);
+}
+EXPORT_SYMBOL(security_task_getsecid);
+
+int security_task_setgroups(struct group_info *group_info)
+{
+ return security_ops->task_setgroups(group_info);
+}
+
+int security_task_setnice(struct task_struct *p, int nice)
+{
+ return security_ops->task_setnice(p, nice);
+}
+
+int security_task_setioprio(struct task_struct *p, int ioprio)
+{
+ return security_ops->task_setioprio(p, ioprio);
+}
+
+int security_task_getioprio(struct task_struct *p)
+{
+ return security_ops->task_getioprio(p);
+}
+
+int security_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
+{
+ return security_ops->task_setrlimit(resource, new_rlim);
+}
+
+int security_task_setscheduler(struct task_struct *p,
+ int policy, struct sched_param *lp)
+{
+ return security_ops->task_setscheduler(p, policy, lp);
+}
+
+int security_task_getscheduler(struct task_struct *p)
+{
+ return security_ops->task_getscheduler(p);
+}
+
+int security_task_movememory(struct task_struct *p)
+{
+ return security_ops->task_movememory(p);
+}
+
+int security_task_kill(struct task_struct *p, struct siginfo *info,
+ int sig, u32 secid)
+{
+ return security_ops->task_kill(p, info, sig, secid);
+}
+
+int security_task_wait(struct task_struct *p)
+{
+ return security_ops->task_wait(p);
+}
+
+int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5)
+{
+ return security_ops->task_prctl(option, arg2, arg3, arg4, arg5);
+}
+
+void security_task_reparent_to_init(struct task_struct *p)
+{
+ security_ops->task_reparent_to_init(p);
+}
+
+void security_task_to_inode(struct task_struct *p, struct inode *inode)
+{
+ security_ops->task_to_inode(p, inode);
+}
+
+int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
+{
+ return security_ops->ipc_permission(ipcp, flag);
+}
+
+int security_msg_msg_alloc(struct msg_msg *msg)
+{
+ return security_ops->msg_msg_alloc_security(msg);
+}
+
+void security_msg_msg_free(struct msg_msg *msg)
+{
+ security_ops->msg_msg_free_security(msg);
+}
+
+int security_msg_queue_alloc(struct msg_queue *msq)
+{
+ return security_ops->msg_queue_alloc_security(msq);
+}
+
+void security_msg_queue_free(struct msg_queue *msq)
+{
+ security_ops->msg_queue_free_security(msq);
+}
+
+int security_msg_queue_associate(struct msg_queue *msq, int msqflg)
+{
+ return security_ops->msg_queue_associate(msq, msqflg);
+}
+
+int security_msg_queue_msgctl(struct msg_queue *msq, int cmd)
+{
+ return security_ops->msg_queue_msgctl(msq, cmd);
+}
+
+int security_msg_queue_msgsnd(struct msg_queue *msq,
+ struct msg_msg *msg, int msqflg)
+{
+ return security_ops->msg_queue_msgsnd(msq, msg, msqflg);
+}
+
+int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
+ struct task_struct *target, long type, int mode)
+{
+ return security_ops->msg_queue_msgrcv(msq, msg, target, type, mode);
+}
+
+int security_shm_alloc(struct shmid_kernel *shp)
+{
+ return security_ops->shm_alloc_security(shp);
+}
+
+void security_shm_free(struct shmid_kernel *shp)
+{
+ security_ops->shm_free_security(shp);
+}
+
+int security_shm_associate(struct shmid_kernel *shp, int shmflg)
+{
+ return security_ops->shm_associate(shp, shmflg);
+}
+
+int security_shm_shmctl(struct shmid_kernel *shp, int cmd)
+{
+ return security_ops->shm_shmctl(shp, cmd);
+}
+
+int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg)
+{
+ return security_ops->shm_shmat(shp, shmaddr, shmflg);
+}
+
+int security_sem_alloc(struct sem_array *sma)
+{
+ return security_ops->sem_alloc_security(sma);
+}
+
+void security_sem_free(struct sem_array *sma)
+{
+ security_ops->sem_free_security(sma);
+}
+
+int security_sem_associate(struct sem_array *sma, int semflg)
+{
+ return security_ops->sem_associate(sma, semflg);
+}
+
+int security_sem_semctl(struct sem_array *sma, int cmd)
+{
+ return security_ops->sem_semctl(sma, cmd);
+}
+
+int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
+ unsigned nsops, int alter)
+{
+ return security_ops->sem_semop(sma, sops, nsops, alter);
+}
+
+void security_d_instantiate(struct dentry *dentry, struct inode *inode)
+{
+ if (unlikely(inode && IS_PRIVATE(inode)))
+ return;
+ security_ops->d_instantiate(dentry, inode);
+}
+EXPORT_SYMBOL(security_d_instantiate);
+
+int security_getprocattr(struct task_struct *p, char *name, char **value)
+{
+ return security_ops->getprocattr(p, name, value);
+}
+
+int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
+{
+ return security_ops->setprocattr(p, name, value, size);
+}
+
+int security_netlink_send(struct sock *sk, struct sk_buff *skb)
+{
+ return security_ops->netlink_send(sk, skb);
+}
+
+int security_netlink_recv(struct sk_buff *skb, int cap)
+{
+ return security_ops->netlink_recv(skb, cap);
+}
+EXPORT_SYMBOL(security_netlink_recv);
+
+int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
+{
+ return security_ops->secid_to_secctx(secid, secdata, seclen);
+}
+EXPORT_SYMBOL(security_secid_to_secctx);
+
+void security_release_secctx(char *secdata, u32 seclen)
+{
+ return security_ops->release_secctx(secdata, seclen);
+}
+EXPORT_SYMBOL(security_release_secctx);
+
+#ifdef CONFIG_SECURITY_NETWORK
+
+int security_unix_stream_connect(struct socket *sock, struct socket *other,
+ struct sock *newsk)
+{
+ return security_ops->unix_stream_connect(sock, other, newsk);
+}
+EXPORT_SYMBOL(security_unix_stream_connect);
+
+int security_unix_may_send(struct socket *sock, struct socket *other)
+{
+ return security_ops->unix_may_send(sock, other);
+}
+EXPORT_SYMBOL(security_unix_may_send);
+
+int security_socket_create(int family, int type, int protocol, int kern)
+{
+ return security_ops->socket_create(family, type, protocol, kern);
+}
+
+int security_socket_post_create(struct socket *sock, int family,
+ int type, int protocol, int kern)
+{
+ return security_ops->socket_post_create(sock, family, type,
+ protocol, kern);
+}
+
+int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
+{
+ return security_ops->socket_bind(sock, address, addrlen);
+}
+
+int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
+{
+ return security_ops->socket_connect(sock, address, addrlen);
+}
+
+int security_socket_listen(struct socket *sock, int backlog)
+{
+ return security_ops->socket_listen(sock, backlog);
+}
+
+int security_socket_accept(struct socket *sock, struct socket *newsock)
+{
+ return security_ops->socket_accept(sock, newsock);
+}
+
+void security_socket_post_accept(struct socket *sock, struct socket *newsock)
+{
+ security_ops->socket_post_accept(sock, newsock);
+}
+
+int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size)
+{
+ return security_ops->socket_sendmsg(sock, msg, size);
+}
+
+int security_socket_recvmsg(struct socket *sock, struct msghdr *msg,
+ int size, int flags)
+{
+ return security_ops->socket_recvmsg(sock, msg, size, flags);
+}
+
+int security_socket_getsockname(struct socket *sock)
+{
+ return security_ops->socket_getsockname(sock);
+}
+
+int security_socket_getpeername(struct socket *sock)
+{
+ return security_ops->socket_getpeername(sock);
+}
+
+int security_socket_getsockopt(struct socket *sock, int level, int optname)
+{
+ return security_ops->socket_getsockopt(sock, level, optname);
+}
+
+int security_socket_setsockopt(struct socket *sock, int level, int optname)
+{
+ return security_ops->socket_setsockopt(sock, level, optname);
+}
+
+int security_socket_shutdown(struct socket *sock, int how)
+{
+ return security_ops->socket_shutdown(sock, how);
+}
+
+int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+ return security_ops->socket_sock_rcv_skb(sk, skb);
+}
+EXPORT_SYMBOL(security_sock_rcv_skb);
+
+int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
+ int __user *optlen, unsigned len)
+{
+ return security_ops->socket_getpeersec_stream(sock, optval, optlen, len);
+}
+
+int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid)
+{
+ return security_ops->socket_getpeersec_dgram(sock, skb, secid);
+}
+EXPORT_SYMBOL(security_socket_getpeersec_dgram);
+
+int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
+{
+ return security_ops->sk_alloc_security(sk, family, priority);
+}
+
+void security_sk_free(struct sock *sk)
+{
+ return security_ops->sk_free_security(sk);
+}
+
+void security_sk_clone(const struct sock *sk, struct sock *newsk)
+{
+ return security_ops->sk_clone_security(sk, newsk);
+}
+
+void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
+{
+ security_ops->sk_getsecid(sk, &fl->secid);
+}
+EXPORT_SYMBOL(security_sk_classify_flow);
+
+void security_req_classify_flow(const struct request_sock *req, struct flowi *fl)
+{
+ security_ops->req_classify_flow(req, fl);
+}
+EXPORT_SYMBOL(security_req_classify_flow);
+
+void security_sock_graft(struct sock *sk, struct socket *parent)
+{
+ security_ops->sock_graft(sk, parent);
+}
+EXPORT_SYMBOL(security_sock_graft);
+
+int security_inet_conn_request(struct sock *sk,
+ struct sk_buff *skb, struct request_sock *req)
+{
+ return security_ops->inet_conn_request(sk, skb, req);
+}
+EXPORT_SYMBOL(security_inet_conn_request);
+
+void security_inet_csk_clone(struct sock *newsk,
+ const struct request_sock *req)
+{
+ security_ops->inet_csk_clone(newsk, req);
+}
+
+void security_inet_conn_established(struct sock *sk,
+ struct sk_buff *skb)
+{
+ security_ops->inet_conn_established(sk, skb);
+}
+
+#endif /* CONFIG_SECURITY_NETWORK */
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+
+int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+ return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
+}
+EXPORT_SYMBOL(security_xfrm_policy_alloc);
+
+int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+ return security_ops->xfrm_policy_clone_security(old, new);
+}
+
+void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+ security_ops->xfrm_policy_free_security(xp);
+}
+EXPORT_SYMBOL(security_xfrm_policy_free);
+
+int security_xfrm_policy_delete(struct xfrm_policy *xp)
+{
+ return security_ops->xfrm_policy_delete_security(xp);
+}
+
+int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+ return security_ops->xfrm_state_alloc_security(x, sec_ctx, 0);
+}
+EXPORT_SYMBOL(security_xfrm_state_alloc);
+
+int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
+ struct xfrm_sec_ctx *polsec, u32 secid)
+{
+ if (!polsec)
+ return 0;
+ /*
+ * We want the context to be taken from secid which is usually
+ * from the sock.
+ */
+ return security_ops->xfrm_state_alloc_security(x, NULL, secid);
+}
+
+int security_xfrm_state_delete(struct xfrm_state *x)
+{
+ return security_ops->xfrm_state_delete_security(x);
+}
+EXPORT_SYMBOL(security_xfrm_state_delete);
+
+void security_xfrm_state_free(struct xfrm_state *x)
+{
+ security_ops->xfrm_state_free_security(x);
+}
+
+int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
+{
+ return security_ops->xfrm_policy_lookup(xp, fl_secid, dir);
+}
+
+int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
+ struct xfrm_policy *xp, struct flowi *fl)
+{
+ return security_ops->xfrm_state_pol_flow_match(x, xp, fl);
+}
+
+int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
+{
+ return security_ops->xfrm_decode_session(skb, secid, 1);
+}
+
+void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl)
+{
+ int rc = security_ops->xfrm_decode_session(skb, &fl->secid, 0);
+
+ BUG_ON(rc);
+}
+EXPORT_SYMBOL(security_skb_classify_flow);
+
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
+
+#ifdef CONFIG_KEYS
+
+int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags)
+{
+ return security_ops->key_alloc(key, tsk, flags);
+}
+
+void security_key_free(struct key *key)
+{
+ security_ops->key_free(key);
+}
+
+int security_key_permission(key_ref_t key_ref,
+ struct task_struct *context, key_perm_t perm)
+{
+ return security_ops->key_permission(key_ref, context, perm);
}
-EXPORT_SYMBOL_GPL(register_security);
-EXPORT_SYMBOL_GPL(unregister_security);
-EXPORT_SYMBOL_GPL(mod_reg_security);
-EXPORT_SYMBOL_GPL(mod_unreg_security);
-EXPORT_SYMBOL(security_ops);
+#endif /* CONFIG_KEYS */
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 0e69adf63bd..81b3dff3cbf 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -916,3 +916,8 @@ int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
return rc;
}
+
+u32 avc_policy_seqno(void)
+{
+ return avc_cache.latest_notif;
+}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3c3fff33d1c..24e1b1885de 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -14,13 +14,14 @@
* <dgoeddel@trustedcs.com>
* Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
* Paul Moore, <paul.moore@hp.com>
+ * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
+ * Yuichi Nakamura <ynakam@hitachisoft.jp>
*
* 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.
*/
-#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
@@ -84,6 +85,7 @@
extern unsigned int policydb_loaded_version;
extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
extern int selinux_compat_net;
+extern struct security_operations *security_ops;
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
int selinux_enforcing = 0;
@@ -2295,6 +2297,25 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
}
+static int selinux_inode_setotherxattr(struct dentry *dentry, char *name)
+{
+ if (!strncmp(name, XATTR_SECURITY_PREFIX,
+ sizeof XATTR_SECURITY_PREFIX - 1)) {
+ if (!strcmp(name, XATTR_NAME_CAPS)) {
+ if (!capable(CAP_SETFCAP))
+ return -EPERM;
+ } else if (!capable(CAP_SYS_ADMIN)) {
+ /* A different attribute in the security namespace.
+ Restrict to administrator. */
+ return -EPERM;
+ }
+ }
+
+ /* Not an attribute we recognize, so just check the
+ ordinary setattr permission. */
+ return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
+}
+
static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags)
{
struct task_security_struct *tsec = current->security;
@@ -2305,19 +2326,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value
u32 newsid;
int rc = 0;
- if (strcmp(name, XATTR_NAME_SELINUX)) {
- if (!strncmp(name, XATTR_SECURITY_PREFIX,
- sizeof XATTR_SECURITY_PREFIX - 1) &&
- !capable(CAP_SYS_ADMIN)) {
- /* A different attribute in the security namespace.
- Restrict to administrator. */
- return -EPERM;
- }
-
- /* Not an attribute we recognize, so just check the
- ordinary setattr permission. */
- return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
- }
+ if (strcmp(name, XATTR_NAME_SELINUX))
+ return selinux_inode_setotherxattr(dentry, name);
sbsec = inode->i_sb->s_security;
if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
@@ -2391,31 +2401,14 @@ static int selinux_inode_listxattr (struct dentry *dentry)
static int selinux_inode_removexattr (struct dentry *dentry, char *name)
{
- if (strcmp(name, XATTR_NAME_SELINUX)) {
- if (!strncmp(name, XATTR_SECURITY_PREFIX,
- sizeof XATTR_SECURITY_PREFIX - 1) &&
- !capable(CAP_SYS_ADMIN)) {
- /* A different attribute in the security namespace.
- Restrict to administrator. */
- return -EPERM;
- }
-
- /* Not an attribute we recognize, so just check the
- ordinary setattr permission. Might want a separate
- permission for removexattr. */
- return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
- }
+ if (strcmp(name, XATTR_NAME_SELINUX))
+ return selinux_inode_setotherxattr(dentry, name);
/* No one is allowed to remove a SELinux security label.
You can change the label, but all data must be labeled. */
return -EACCES;
}
-static const char *selinux_inode_xattr_getsuffix(void)
-{
- return XATTR_SELINUX_SUFFIX;
-}
-
/*
* Copy the in-core inode security context value to the user. If the
* getxattr() prior to this succeeded, check to see if we need to
@@ -2462,9 +2455,19 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
return len;
}
+static int selinux_inode_need_killpriv(struct dentry *dentry)
+{
+ return secondary_ops->inode_need_killpriv(dentry);
+}
+
+static int selinux_inode_killpriv(struct dentry *dentry)
+{
+ return secondary_ops->inode_killpriv(dentry);
+}
+
/* file security operations */
-static int selinux_file_permission(struct file *file, int mask)
+static int selinux_revalidate_file_permission(struct file *file, int mask)
{
int rc;
struct inode *inode = file->f_path.dentry->d_inode;
@@ -2486,6 +2489,25 @@ static int selinux_file_permission(struct file *file, int mask)
return selinux_netlbl_inode_permission(inode, mask);
}
+static int selinux_file_permission(struct file *file, int mask)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct task_security_struct *tsec = current->security;
+ struct file_security_struct *fsec = file->f_security;
+ struct inode_security_struct *isec = inode->i_security;
+
+ if (!mask) {
+ /* No permission to check. Existence test. */
+ return 0;
+ }
+
+ if (tsec->sid == fsec->sid && fsec->isid == isec->sid
+ && fsec->pseqno == avc_policy_seqno())
+ return selinux_netlbl_inode_permission(inode, mask);
+
+ return selinux_revalidate_file_permission(file, mask);
+}
+
static int selinux_file_alloc_security(struct file *file)
{
return file_alloc_security(file);
@@ -2725,6 +2747,34 @@ static int selinux_file_receive(struct file *file)
return file_has_perm(current, file, file_to_av(file));
}
+static int selinux_dentry_open(struct file *file)
+{
+ struct file_security_struct *fsec;
+ struct inode *inode;
+ struct inode_security_struct *isec;
+ inode = file->f_path.dentry->d_inode;
+ fsec = file->f_security;
+ isec = inode->i_security;
+ /*
+ * Save inode label and policy sequence number
+ * at open-time so that selinux_file_permission
+ * can determine whether revalidation is necessary.
+ * Task label is already saved in the file security
+ * struct as its SID.
+ */
+ fsec->isid = isec->sid;
+ fsec->pseqno = avc_policy_seqno();
+ /*
+ * Since the inode label or policy seqno may have changed
+ * between the selinux_inode_permission check and the saving
+ * of state above, recheck that access is still permitted.
+ * Otherwise, access might never be revalidated against the
+ * new inode label or new policy.
+ * This check is not redundant - do not remove.
+ */
+ return inode_has_perm(current, inode, file_to_av(file), NULL);
+}
+
/* task security operations */
static int selinux_task_create(unsigned long clone_flags)
@@ -2833,6 +2883,12 @@ static int selinux_task_setnice(struct task_struct *p, int nice)
static int selinux_task_setioprio(struct task_struct *p, int ioprio)
{
+ int rc;
+
+ rc = secondary_ops->task_setioprio(p, ioprio);
+ if (rc)
+ return rc;
+
return task_has_perm(current, p, PROCESS__SETSCHED);
}
@@ -2862,6 +2918,12 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim
static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
{
+ int rc;
+
+ rc = secondary_ops->task_setscheduler(p, policy, lp);
+ if (rc)
+ return rc;
+
return task_has_perm(current, p, PROCESS__SETSCHED);
}
@@ -3932,7 +3994,7 @@ out:
}
static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *),
@@ -3941,7 +4003,6 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
char *addrp;
int len, err = 0;
struct sock *sk;
- struct sk_buff *skb = *pskb;
struct avc_audit_data ad;
struct net_device *dev = (struct net_device *)out;
struct sk_security_struct *sksec;
@@ -3977,23 +4038,23 @@ out:
}
static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET);
+ return selinux_ip_postroute_last(hooknum, skb, in, out, okfn, PF_INET);
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
- struct sk_buff **pskb,
+ struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
- return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET6);
+ return selinux_ip_postroute_last(hooknum, skb, in, out, okfn, PF_INET6);
}
#endif /* IPV6 */
@@ -4488,19 +4549,6 @@ static int selinux_register_security (const char *name, struct security_operatio
return 0;
}
-static int selinux_unregister_security (const char *name, struct security_operations *ops)
-{
- if (ops != secondary_ops) {
- printk(KERN_ERR "%s: trying to unregister a security module "
- "that is not registered.\n", __FUNCTION__);
- return -EINVAL;
- }
-
- secondary_ops = original_ops;
-
- return 0;
-}
-
static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode)
{
if (inode)
@@ -4778,10 +4826,11 @@ static struct security_operations selinux_ops = {
.inode_getxattr = selinux_inode_getxattr,
.inode_listxattr = selinux_inode_listxattr,
.inode_removexattr = selinux_inode_removexattr,
- .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
.inode_getsecurity = selinux_inode_getsecurity,
.inode_setsecurity = selinux_inode_setsecurity,
.inode_listsecurity = selinux_inode_listsecurity,
+ .inode_need_killpriv = selinux_inode_need_killpriv,
+ .inode_killpriv = selinux_inode_killpriv,
.file_permission = selinux_file_permission,
.file_alloc_security = selinux_file_alloc_security,
@@ -4795,6 +4844,8 @@ static struct security_operations selinux_ops = {
.file_send_sigiotask = selinux_file_send_sigiotask,
.file_receive = selinux_file_receive,
+ .dentry_open = selinux_dentry_open,
+
.task_create = selinux_task_create,
.task_alloc_security = selinux_task_alloc_security,
.task_free_security = selinux_task_free_security,
@@ -4844,7 +4895,6 @@ static struct security_operations selinux_ops = {
.sem_semop = selinux_sem_semop,
.register_security = selinux_register_security,
- .unregister_security = selinux_unregister_security,
.d_instantiate = selinux_d_instantiate,
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index e145f6e13b0..553607a19e9 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -112,6 +112,8 @@ int avc_has_perm(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct avc_audit_data *auditdata);
+u32 avc_policy_seqno(void);
+
#define AVC_CALLBACK_GRANT 1
#define AVC_CALLBACK_TRY_REVOKE 2
#define AVC_CALLBACK_REVOKE 4
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 91b88f0ba20..642a9fd319a 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -53,6 +53,8 @@ struct file_security_struct {
struct file *file; /* back pointer to file object */
u32 sid; /* SID of open file description */
u32 fown_sid; /* SID of file owner (for SIGIO) */
+ u32 isid; /* SID of inode at the time of file open */
+ u32 pseqno; /* Policy seqno at the time of file open */
};
struct superblock_security_struct {
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 83bdd4d2a29..39337afffec 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -90,6 +90,8 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
int security_get_classes(char ***classes, int *nclasses);
int security_get_permissions(char *class, char ***perms, int *nperms);
+int security_get_reject_unknown(void);
+int security_get_allow_unknown(void);
#define SECURITY_FS_USE_XATTR 1 /* use xattr */
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index c9e92daedee..f5f3e6da5da 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -103,6 +103,8 @@ enum sel_inos {
SEL_MEMBER, /* compute polyinstantiation membership decision */
SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
SEL_COMPAT_NET, /* whether to use old compat network packet controls */
+ SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
+ SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
SEL_INO_NEXT, /* The next inode number to use */
};
@@ -177,6 +179,23 @@ static const struct file_operations sel_enforce_ops = {
.write = sel_write_enforce,
};
+static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char tmpbuf[TMPBUFLEN];
+ ssize_t length;
+ ino_t ino = filp->f_path.dentry->d_inode->i_ino;
+ int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
+ security_get_reject_unknown() : !security_get_allow_unknown();
+
+ length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
+ return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static const struct file_operations sel_handle_unknown_ops = {
+ .read = sel_read_handle_unknown,
+};
+
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
static ssize_t sel_write_disable(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
@@ -309,6 +328,11 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
length = count;
out1:
+
+ printk(KERN_INFO "SELinux: policy loaded with handle_unknown=%s\n",
+ (security_get_reject_unknown() ? "reject" :
+ (security_get_allow_unknown() ? "allow" : "deny")));
+
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
"policy loaded auid=%u",
audit_get_loginuid(current->audit_context));
@@ -1575,6 +1599,8 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
[SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
[SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
[SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
+ [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
+ [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
/* last one */ {""}
};
ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 85705eb289e..7551af1f789 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -12,24 +12,25 @@
* 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.
+ *
+ * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
+ * Tuned number of hash slots for avtab to reduce memory usage
*/
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <linux/errno.h>
-
#include "avtab.h"
#include "policydb.h"
-#define AVTAB_HASH(keyp) \
-((keyp->target_class + \
- (keyp->target_type << 2) + \
- (keyp->source_type << 9)) & \
- AVTAB_HASH_MASK)
-
static struct kmem_cache *avtab_node_cachep;
+static inline int avtab_hash(struct avtab_key *keyp, u16 mask)
+{
+ return ((keyp->target_class + (keyp->target_type << 2) +
+ (keyp->source_type << 9)) & mask);
+}
+
static struct avtab_node*
avtab_insert_node(struct avtab *h, int hvalue,
struct avtab_node * prev, struct avtab_node * cur,
@@ -59,10 +60,10 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
struct avtab_node *prev, *cur, *newnode;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
- if (!h)
+ if (!h || !h->htable)
return -EINVAL;
- hvalue = AVTAB_HASH(key);
+ hvalue = avtab_hash(key, h->mask);
for (prev = NULL, cur = h->htable[hvalue];
cur;
prev = cur, cur = cur->next) {
@@ -100,9 +101,9 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
struct avtab_node *prev, *cur, *newnode;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
- if (!h)
+ if (!h || !h->htable)
return NULL;
- hvalue = AVTAB_HASH(key);
+ hvalue = avtab_hash(key, h->mask);
for (prev = NULL, cur = h->htable[hvalue];
cur;
prev = cur, cur = cur->next) {
@@ -132,10 +133,10 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
struct avtab_node *cur;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
- if (!h)
+ if (!h || !h->htable)
return NULL;
- hvalue = AVTAB_HASH(key);
+ hvalue = avtab_hash(key, h->mask);
for (cur = h->htable[hvalue]; cur; cur = cur->next) {
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
@@ -167,10 +168,10 @@ avtab_search_node(struct avtab *h, struct avtab_key *key)
struct avtab_node *cur;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
- if (!h)
+ if (!h || !h->htable)
return NULL;
- hvalue = AVTAB_HASH(key);
+ hvalue = avtab_hash(key, h->mask);
for (cur = h->htable[hvalue]; cur; cur = cur->next) {
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
@@ -228,7 +229,7 @@ void avtab_destroy(struct avtab *h)
if (!h || !h->htable)
return;
- for (i = 0; i < AVTAB_SIZE; i++) {
+ for (i = 0; i < h->nslot; i++) {
cur = h->htable[i];
while (cur != NULL) {
temp = cur;
@@ -237,32 +238,63 @@ void avtab_destroy(struct avtab *h)
}
h->htable[i] = NULL;
}
- vfree(h->htable);
+ kfree(h->htable);
h->htable = NULL;
+ h->nslot = 0;
+ h->mask = 0;
}
-
int avtab_init(struct avtab *h)
{
- int i;
+ h->htable = NULL;
+ h->nel = 0;
+ return 0;
+}
+
+int avtab_alloc(struct avtab *h, u32 nrules)
+{
+ u16 mask = 0;
+ u32 shift = 0;
+ u32 work = nrules;
+ u32 nslot = 0;
+
+ if (nrules == 0)
+ goto avtab_alloc_out;
- h->htable = vmalloc(sizeof(*(h->htable)) * AVTAB_SIZE);
+ while (work) {
+ work = work >> 1;
+ shift++;
+ }
+ if (shift > 2)
+ shift = shift - 2;
+ nslot = 1 << shift;
+ if (nslot > MAX_AVTAB_SIZE)
+ nslot = MAX_AVTAB_SIZE;
+ mask = nslot - 1;
+
+ h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL);
if (!h->htable)
return -ENOMEM;
- for (i = 0; i < AVTAB_SIZE; i++)
- h->htable[i] = NULL;
+
+ avtab_alloc_out:
h->nel = 0;
+ h->nslot = nslot;
+ h->mask = mask;
+ printk(KERN_DEBUG "SELinux:%d avtab hash slots allocated."
+ "Num of rules:%d\n", h->nslot, nrules);
return 0;
}
void avtab_hash_eval(struct avtab *h, char *tag)
{
int i, chain_len, slots_used, max_chain_len;
+ unsigned long long chain2_len_sum;
struct avtab_node *cur;
slots_used = 0;
max_chain_len = 0;
- for (i = 0; i < AVTAB_SIZE; i++) {
+ chain2_len_sum = 0;
+ for (i = 0; i < h->nslot; i++) {
cur = h->htable[i];
if (cur) {
slots_used++;
@@ -274,12 +306,14 @@ void avtab_hash_eval(struct avtab *h, char *tag)
if (chain_len > max_chain_len)
max_chain_len = chain_len;
+ chain2_len_sum += chain_len * chain_len;
}
}
printk(KERN_DEBUG "%s: %d entries and %d/%d buckets used, longest "
- "chain length %d\n", tag, h->nel, slots_used, AVTAB_SIZE,
- max_chain_len);
+ "chain length %d sum of chain length^2 %Lu\n",
+ tag, h->nel, slots_used, h->nslot, max_chain_len,
+ chain2_len_sum);
}
static uint16_t spec_order[] = {
@@ -419,6 +453,11 @@ int avtab_read(struct avtab *a, void *fp, u32 vers)
rc = -EINVAL;
goto bad;
}
+
+ rc = avtab_alloc(a, nel);
+ if (rc)
+ goto bad;
+
for (i = 0; i < nel; i++) {
rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
if (rc) {
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 0a90d939af9..d8edf8ca56d 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -16,6 +16,9 @@
* 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.
+ *
+ * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
+ * Tuned number of hash slots for avtab to reduce memory usage
*/
#ifndef _SS_AVTAB_H_
#define _SS_AVTAB_H_
@@ -50,9 +53,13 @@ struct avtab_node {
struct avtab {
struct avtab_node **htable;
u32 nel; /* number of elements */
+ u32 nslot; /* number of hash slots */
+ u16 mask; /* mask to compute hash func */
+
};
int avtab_init(struct avtab *);
+int avtab_alloc(struct avtab *, u32);
struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
void avtab_destroy(struct avtab *h);
void avtab_hash_eval(struct avtab *h, char *tag);
@@ -74,11 +81,10 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
void avtab_cache_init(void);
void avtab_cache_destroy(void);
-#define AVTAB_HASH_BITS 15
-#define AVTAB_HASH_BUCKETS (1 << AVTAB_HASH_BITS)
-#define AVTAB_HASH_MASK (AVTAB_HASH_BUCKETS-1)
-
-#define AVTAB_SIZE AVTAB_HASH_BUCKETS
+#define MAX_AVTAB_HASH_BITS 13
+#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
+#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
+#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
#endif /* _SS_AVTAB_H_ */
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index d2737edba54..45b93a827c8 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -456,6 +456,10 @@ int cond_read_list(struct policydb *p, void *fp)
len = le32_to_cpu(buf[0]);
+ rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel);
+ if (rc)
+ goto err;
+
for (i = 0; i < len; i++) {
node = kzalloc(sizeof(struct cond_node), GFP_KERNEL);
if (!node)
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index ce492a6b38e..c1a6b22d48d 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -10,6 +10,10 @@
*
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
*/
+/*
+ * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com>
+ * Applied standard bit operations to improve bitmap scanning.
+ */
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -29,7 +33,7 @@ int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
n2 = e2->node;
while (n1 && n2 &&
(n1->startbit == n2->startbit) &&
- (n1->map == n2->map)) {
+ !memcmp(n1->maps, n2->maps, EBITMAP_SIZE / 8)) {
n1 = n1->next;
n2 = n2->next;
}
@@ -54,7 +58,7 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
return -ENOMEM;
}
new->startbit = n->startbit;
- new->map = n->map;
+ memcpy(new->maps, n->maps, EBITMAP_SIZE / 8);
new->next = NULL;
if (prev)
prev->next = new;
@@ -84,13 +88,15 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
{
struct ebitmap_node *e_iter = ebmap->node;
struct netlbl_lsm_secattr_catmap *c_iter;
- u32 cmap_idx;
+ u32 cmap_idx, cmap_sft;
+ int i;
- /* This function is a much simpler because SELinux's MAPTYPE happens
- * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is
- * changed from a u64 this function will most likely need to be changed
- * as well. It's not ideal but I think the tradeoff in terms of
- * neatness and speed is worth it. */
+ /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
+ * however, it is not always compatible with an array of unsigned long
+ * in ebitmap_node.
+ * In addition, you should pay attention the following implementation
+ * assumes unsigned long has a width equal with or less than 64-bit.
+ */
if (e_iter == NULL) {
*catmap = NULL;
@@ -104,19 +110,27 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
while (e_iter != NULL) {
- if (e_iter->startbit >=
- (c_iter->startbit + NETLBL_CATMAP_SIZE)) {
- c_iter->next = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
- if (c_iter->next == NULL)
- goto netlbl_export_failure;
- c_iter = c_iter->next;
- c_iter->startbit = e_iter->startbit &
- ~(NETLBL_CATMAP_SIZE - 1);
+ for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
+ unsigned int delta, e_startbit, c_endbit;
+
+ e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE;
+ c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE;
+ if (e_startbit >= c_endbit) {
+ c_iter->next
+ = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
+ if (c_iter->next == NULL)
+ goto netlbl_export_failure;
+ c_iter = c_iter->next;
+ c_iter->startbit
+ = e_startbit & ~(NETLBL_CATMAP_SIZE - 1);
+ }
+ delta = e_startbit - c_iter->startbit;
+ cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
+ cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
+ c_iter->bitmap[cmap_idx]
+ |= e_iter->maps[cmap_idx] << cmap_sft;
+ e_iter = e_iter->next;
}
- cmap_idx = (e_iter->startbit - c_iter->startbit) /
- NETLBL_CATMAP_MAPSIZE;
- c_iter->bitmap[cmap_idx] = e_iter->map;
- e_iter = e_iter->next;
}
return 0;
@@ -128,7 +142,7 @@ netlbl_export_failure:
/**
* ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap
- * @ebmap: the ebitmap to export
+ * @ebmap: the ebitmap to import
* @catmap: the NetLabel category bitmap
*
* Description:
@@ -142,36 +156,50 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
struct ebitmap_node *e_iter = NULL;
struct ebitmap_node *emap_prev = NULL;
struct netlbl_lsm_secattr_catmap *c_iter = catmap;
- u32 c_idx;
+ u32 c_idx, c_pos, e_idx, e_sft;
- /* This function is a much simpler because SELinux's MAPTYPE happens
- * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is
- * changed from a u64 this function will most likely need to be changed
- * as well. It's not ideal but I think the tradeoff in terms of
- * neatness and speed is worth it. */
+ /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
+ * however, it is not always compatible with an array of unsigned long
+ * in ebitmap_node.
+ * In addition, you should pay attention the following implementation
+ * assumes unsigned long has a width equal with or less than 64-bit.
+ */
do {
for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
- if (c_iter->bitmap[c_idx] == 0)
+ unsigned int delta;
+ u64 map = c_iter->bitmap[c_idx];
+
+ if (!map)
continue;
- e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
- if (e_iter == NULL)
- goto netlbl_import_failure;
- if (emap_prev == NULL)
- ebmap->node = e_iter;
- else
- emap_prev->next = e_iter;
- emap_prev = e_iter;
-
- e_iter->startbit = c_iter->startbit +
- NETLBL_CATMAP_MAPSIZE * c_idx;
- e_iter->map = c_iter->bitmap[c_idx];
+ c_pos = c_iter->startbit
+ + c_idx * NETLBL_CATMAP_MAPSIZE;
+ if (!e_iter
+ || c_pos >= e_iter->startbit + EBITMAP_SIZE) {
+ e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
+ if (!e_iter)
+ goto netlbl_import_failure;
+ e_iter->startbit
+ = c_pos - (c_pos % EBITMAP_SIZE);
+ if (emap_prev == NULL)
+ ebmap->node = e_iter;
+ else
+ emap_prev->next = e_iter;
+ emap_prev = e_iter;
+ }
+ delta = c_pos - e_iter->startbit;
+ e_idx = delta / EBITMAP_UNIT_SIZE;
+ e_sft = delta % EBITMAP_UNIT_SIZE;
+ while (map) {
+ e_iter->maps[e_idx++] |= map & (-1UL);
+ map = EBITMAP_SHIFT_UNIT_SIZE(map);
+ }
}
c_iter = c_iter->next;
} while (c_iter != NULL);
if (e_iter != NULL)
- ebmap->highbit = e_iter->startbit + MAPSIZE;
+ ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
else
ebitmap_destroy(ebmap);
@@ -186,6 +214,7 @@ netlbl_import_failure:
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
{
struct ebitmap_node *n1, *n2;
+ int i;
if (e1->highbit < e2->highbit)
return 0;
@@ -197,8 +226,10 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
n1 = n1->next;
continue;
}
- if ((n1->map & n2->map) != n2->map)
- return 0;
+ for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
+ if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
+ return 0;
+ }
n1 = n1->next;
n2 = n2->next;
@@ -219,12 +250,8 @@ int ebitmap_get_bit(struct ebitmap *e, unsigned long bit)
n = e->node;
while (n && (n->startbit <= bit)) {
- if ((n->startbit + MAPSIZE) > bit) {
- if (n->map & (MAPBIT << (bit - n->startbit)))
- return 1;
- else
- return 0;
- }
+ if ((n->startbit + EBITMAP_SIZE) > bit)
+ return ebitmap_node_get_bit(n, bit);
n = n->next;
}
@@ -238,31 +265,35 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
prev = NULL;
n = e->node;
while (n && n->startbit <= bit) {
- if ((n->startbit + MAPSIZE) > bit) {
+ if ((n->startbit + EBITMAP_SIZE) > bit) {
if (value) {
- n->map |= (MAPBIT << (bit - n->startbit));
+ ebitmap_node_set_bit(n, bit);
} else {
- n->map &= ~(MAPBIT << (bit - n->startbit));
- if (!n->map) {
- /* drop this node from the bitmap */
-
- if (!n->next) {
- /*
- * this was the highest map
- * within the bitmap
- */
- if (prev)
- e->highbit = prev->startbit + MAPSIZE;
- else
- e->highbit = 0;
- }
+ unsigned int s;
+
+ ebitmap_node_clr_bit(n, bit);
+
+ s = find_first_bit(n->maps, EBITMAP_SIZE);
+ if (s < EBITMAP_SIZE)
+ return 0;
+
+ /* drop this node from the bitmap */
+ if (!n->next) {
+ /*
+ * this was the highest map
+ * within the bitmap
+ */
if (prev)
- prev->next = n->next;
+ e->highbit = prev->startbit
+ + EBITMAP_SIZE;
else
- e->node = n->next;
-
- kfree(n);
+ e->highbit = 0;
}
+ if (prev)
+ prev->next = n->next;
+ else
+ e->node = n->next;
+ kfree(n);
}
return 0;
}
@@ -277,12 +308,12 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
if (!new)
return -ENOMEM;
- new->startbit = bit & ~(MAPSIZE - 1);
- new->map = (MAPBIT << (bit - new->startbit));
+ new->startbit = bit - (bit % EBITMAP_SIZE);
+ ebitmap_node_set_bit(new, bit);
if (!n)
/* this node will be the highest map within the bitmap */
- e->highbit = new->startbit + MAPSIZE;
+ e->highbit = new->startbit + EBITMAP_SIZE;
if (prev) {
new->next = prev->next;
@@ -316,11 +347,11 @@ void ebitmap_destroy(struct ebitmap *e)
int ebitmap_read(struct ebitmap *e, void *fp)
{
- int rc;
- struct ebitmap_node *n, *l;
+ struct ebitmap_node *n = NULL;
+ u32 mapunit, count, startbit, index;
+ u64 map;
__le32 buf[3];
- u32 mapsize, count, i;
- __le64 map;
+ int rc, i;
ebitmap_init(e);
@@ -328,85 +359,88 @@ int ebitmap_read(struct ebitmap *e, void *fp)
if (rc < 0)
goto out;
- mapsize = le32_to_cpu(buf[0]);
+ mapunit = le32_to_cpu(buf[0]);
e->highbit = le32_to_cpu(buf[1]);
count = le32_to_cpu(buf[2]);
- if (mapsize != MAPSIZE) {
+ if (mapunit != sizeof(u64) * 8) {
printk(KERN_ERR "security: ebitmap: map size %u does not "
- "match my size %Zd (high bit was %d)\n", mapsize,
- MAPSIZE, e->highbit);
+ "match my size %Zd (high bit was %d)\n",
+ mapunit, sizeof(u64) * 8, e->highbit);
goto bad;
}
+
+ /* round up e->highbit */
+ e->highbit += EBITMAP_SIZE - 1;
+ e->highbit -= (e->highbit % EBITMAP_SIZE);
+
if (!e->highbit) {
e->node = NULL;
goto ok;
}
- if (e->highbit & (MAPSIZE - 1)) {
- printk(KERN_ERR "security: ebitmap: high bit (%d) is not a "
- "multiple of the map size (%Zd)\n", e->highbit, MAPSIZE);
- goto bad;
- }
- l = NULL;
+
for (i = 0; i < count; i++) {
- rc = next_entry(buf, fp, sizeof(u32));
+ rc = next_entry(&startbit, fp, sizeof(u32));
if (rc < 0) {
printk(KERN_ERR "security: ebitmap: truncated map\n");
goto bad;
}
- n = kzalloc(sizeof(*n), GFP_KERNEL);
- if (!n) {
- printk(KERN_ERR "security: ebitmap: out of memory\n");
- rc = -ENOMEM;
- goto bad;
- }
-
- n->startbit = le32_to_cpu(buf[0]);
+ startbit = le32_to_cpu(startbit);
- if (n->startbit & (MAPSIZE - 1)) {
+ if (startbit & (mapunit - 1)) {
printk(KERN_ERR "security: ebitmap start bit (%d) is "
- "not a multiple of the map size (%Zd)\n",
- n->startbit, MAPSIZE);
- goto bad_free;
+ "not a multiple of the map unit size (%u)\n",
+ startbit, mapunit);
+ goto bad;
}
- if (n->startbit > (e->highbit - MAPSIZE)) {
+ if (startbit > e->highbit - mapunit) {
printk(KERN_ERR "security: ebitmap start bit (%d) is "
- "beyond the end of the bitmap (%Zd)\n",
- n->startbit, (e->highbit - MAPSIZE));
- goto bad_free;
+ "beyond the end of the bitmap (%u)\n",
+ startbit, (e->highbit - mapunit));
+ goto bad;
+ }
+
+ if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
+ struct ebitmap_node *tmp;
+ tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+ if (!tmp) {
+ printk(KERN_ERR
+ "security: ebitmap: out of memory\n");
+ rc = -ENOMEM;
+ goto bad;
+ }
+ /* round down */
+ tmp->startbit = startbit - (startbit % EBITMAP_SIZE);
+ if (n) {
+ n->next = tmp;
+ } else {
+ e->node = tmp;
+ }
+ n = tmp;
+ } else if (startbit <= n->startbit) {
+ printk(KERN_ERR "security: ebitmap: start bit %d"
+ " comes after start bit %d\n",
+ startbit, n->startbit);
+ goto bad;
}
+
rc = next_entry(&map, fp, sizeof(u64));
if (rc < 0) {
printk(KERN_ERR "security: ebitmap: truncated map\n");
- goto bad_free;
+ goto bad;
}
- n->map = le64_to_cpu(map);
+ map = le64_to_cpu(map);
- if (!n->map) {
- printk(KERN_ERR "security: ebitmap: null map in "
- "ebitmap (startbit %d)\n", n->startbit);
- goto bad_free;
+ index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE;
+ while (map) {
+ n->maps[index++] = map & (-1UL);
+ map = EBITMAP_SHIFT_UNIT_SIZE(map);
}
- if (l) {
- if (n->startbit <= l->startbit) {
- printk(KERN_ERR "security: ebitmap: start "
- "bit %d comes after start bit %d\n",
- n->startbit, l->startbit);
- goto bad_free;
- }
- l->next = n;
- } else
- e->node = n;
-
- l = n;
}
-
ok:
rc = 0;
out:
return rc;
-bad_free:
- kfree(n);
bad:
if (!rc)
rc = -EINVAL;
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 1270e34b61c..f283b4367f5 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -16,14 +16,18 @@
#include <net/netlabel.h>
-#define MAPTYPE u64 /* portion of bitmap in each node */
-#define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */
-#define MAPBIT 1ULL /* a bit in the node bitmap */
+#define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \
+ / sizeof(unsigned long))
+#define EBITMAP_UNIT_SIZE BITS_PER_LONG
+#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
+#define EBITMAP_BIT 1ULL
+#define EBITMAP_SHIFT_UNIT_SIZE(x) \
+ (((x) >> EBITMAP_UNIT_SIZE / 2) >> EBITMAP_UNIT_SIZE / 2)
struct ebitmap_node {
- u32 startbit; /* starting position in the total bitmap */
- MAPTYPE map; /* this node's portion of the bitmap */
struct ebitmap_node *next;
+ unsigned long maps[EBITMAP_UNIT_NUMS];
+ u32 startbit;
};
struct ebitmap {
@@ -34,11 +38,17 @@ struct ebitmap {
#define ebitmap_length(e) ((e)->highbit)
#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
-static inline unsigned int ebitmap_start(struct ebitmap *e,
- struct ebitmap_node **n)
+static inline unsigned int ebitmap_start_positive(struct ebitmap *e,
+ struct ebitmap_node **n)
{
- *n = e->node;
- return ebitmap_startbit(e);
+ unsigned int ofs;
+
+ for (*n = e->node; *n; *n = (*n)->next) {
+ ofs = find_first_bit((*n)->maps, EBITMAP_SIZE);
+ if (ofs < EBITMAP_SIZE)
+ return (*n)->startbit + ofs;
+ }
+ return ebitmap_length(e);
}
static inline void ebitmap_init(struct ebitmap *e)
@@ -46,28 +56,65 @@ static inline void ebitmap_init(struct ebitmap *e)
memset(e, 0, sizeof(*e));
}
-static inline unsigned int ebitmap_next(struct ebitmap_node **n,
- unsigned int bit)
+static inline unsigned int ebitmap_next_positive(struct ebitmap *e,
+ struct ebitmap_node **n,
+ unsigned int bit)
{
- if ((bit == ((*n)->startbit + MAPSIZE - 1)) &&
- (*n)->next) {
- *n = (*n)->next;
- return (*n)->startbit;
- }
+ unsigned int ofs;
+
+ ofs = find_next_bit((*n)->maps, EBITMAP_SIZE, bit - (*n)->startbit + 1);
+ if (ofs < EBITMAP_SIZE)
+ return ofs + (*n)->startbit;
- return (bit+1);
+ for (*n = (*n)->next; *n; *n = (*n)->next) {
+ ofs = find_first_bit((*n)->maps, EBITMAP_SIZE);
+ if (ofs < EBITMAP_SIZE)
+ return ofs + (*n)->startbit;
+ }
+ return ebitmap_length(e);
}
-static inline int ebitmap_node_get_bit(struct ebitmap_node * n,
+#define EBITMAP_NODE_INDEX(node, bit) \
+ (((bit) - (node)->startbit) / EBITMAP_UNIT_SIZE)
+#define EBITMAP_NODE_OFFSET(node, bit) \
+ (((bit) - (node)->startbit) % EBITMAP_UNIT_SIZE)
+
+static inline int ebitmap_node_get_bit(struct ebitmap_node *n,
unsigned int bit)
{
- if (n->map & (MAPBIT << (bit - n->startbit)))
+ unsigned int index = EBITMAP_NODE_INDEX(n, bit);
+ unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
+
+ BUG_ON(index >= EBITMAP_UNIT_NUMS);
+ if ((n->maps[index] & (EBITMAP_BIT << ofs)))
return 1;
return 0;
}
-#define ebitmap_for_each_bit(e, n, bit) \
- for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \
+static inline void ebitmap_node_set_bit(struct ebitmap_node *n,
+ unsigned int bit)
+{
+ unsigned int index = EBITMAP_NODE_INDEX(n, bit);
+ unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
+
+ BUG_ON(index >= EBITMAP_UNIT_NUMS);
+ n->maps[index] |= (EBITMAP_BIT << ofs);
+}
+
+static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
+ unsigned int bit)
+{
+ unsigned int index = EBITMAP_NODE_INDEX(n, bit);
+ unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
+
+ BUG_ON(index >= EBITMAP_UNIT_NUMS);
+ n->maps[index] &= ~(EBITMAP_BIT << ofs);
+}
+
+#define ebitmap_for_each_positive_bit(e, n, bit) \
+ for (bit = ebitmap_start_positive(e, &n); \
+ bit < ebitmap_length(e); \
+ bit = ebitmap_next_positive(e, &n, bit)) \
int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 4a8bab2f3c7..9a11deaaa9e 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -34,7 +34,9 @@
*/
int mls_compute_context_len(struct context * context)
{
- int i, l, len, range;
+ int i, l, len, head, prev;
+ char *nm;
+ struct ebitmap *e;
struct ebitmap_node *node;
if (!selinux_mls_enabled)
@@ -42,31 +44,33 @@ int mls_compute_context_len(struct context * context)
len = 1; /* for the beginning ":" */
for (l = 0; l < 2; l++) {
- range = 0;
- len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
-
- ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
- if (ebitmap_node_get_bit(node, i)) {
- if (range) {
- range++;
- continue;
- }
+ int index_sens = context->range.level[l].sens;
+ len += strlen(policydb.p_sens_val_to_name[index_sens - 1]);
- len += strlen(policydb.p_cat_val_to_name[i]) + 1;
- range++;
- } else {
- if (range > 1)
- len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
- range = 0;
+ /* categories */
+ head = -2;
+ prev = -2;
+ e = &context->range.level[l].cat;
+ ebitmap_for_each_positive_bit(e, node, i) {
+ if (i - prev > 1) {
+ /* one or more negative bits are skipped */
+ if (head != prev) {
+ nm = policydb.p_cat_val_to_name[prev];
+ len += strlen(nm) + 1;
+ }
+ nm = policydb.p_cat_val_to_name[i];
+ len += strlen(nm) + 1;
+ head = i;
}
+ prev = i;
+ }
+ if (prev != head) {
+ nm = policydb.p_cat_val_to_name[prev];
+ len += strlen(nm) + 1;
}
- /* Handle case where last category is the end of range */
- if (range > 1)
- len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1;
-
if (l == 0) {
if (mls_level_eq(&context->range.level[0],
- &context->range.level[1]))
+ &context->range.level[1]))
break;
else
len++;
@@ -84,8 +88,9 @@ int mls_compute_context_len(struct context * context)
void mls_sid_to_context(struct context *context,
char **scontext)
{
- char *scontextp;
- int i, l, range, wrote_sep;
+ char *scontextp, *nm;
+ int i, l, head, prev;
+ struct ebitmap *e;
struct ebitmap_node *node;
if (!selinux_mls_enabled)
@@ -97,61 +102,54 @@ void mls_sid_to_context(struct context *context,
scontextp++;
for (l = 0; l < 2; l++) {
- range = 0;
- wrote_sep = 0;
strcpy(scontextp,
policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
- scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]);
+ scontextp += strlen(scontextp);
/* categories */
- ebitmap_for_each_bit(&context->range.level[l].cat, node, i) {
- if (ebitmap_node_get_bit(node, i)) {
- if (range) {
- range++;
- continue;
- }
-
- if (!wrote_sep) {
- *scontextp++ = ':';
- wrote_sep = 1;
- } else
- *scontextp++ = ',';
- strcpy(scontextp, policydb.p_cat_val_to_name[i]);
- scontextp += strlen(policydb.p_cat_val_to_name[i]);
- range++;
- } else {
- if (range > 1) {
- if (range > 2)
+ head = -2;
+ prev = -2;
+ e = &context->range.level[l].cat;
+ ebitmap_for_each_positive_bit(e, node, i) {
+ if (i - prev > 1) {
+ /* one or more negative bits are skipped */
+ if (prev != head) {
+ if (prev - head > 1)
*scontextp++ = '.';
else
*scontextp++ = ',';
-
- strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
- scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
+ nm = policydb.p_cat_val_to_name[prev];
+ strcpy(scontextp, nm);
+ scontextp += strlen(nm);
}
- range = 0;
+ if (prev < 0)
+ *scontextp++ = ':';
+ else
+ *scontextp++ = ',';
+ nm = policydb.p_cat_val_to_name[i];
+ strcpy(scontextp, nm);
+ scontextp += strlen(nm);
+ head = i;
}
+ prev = i;
}
- /* Handle case where last category is the end of range */
- if (range > 1) {
- if (range > 2)
+ if (prev != head) {
+ if (prev - head > 1)
*scontextp++ = '.';
else
*scontextp++ = ',';
-
- strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]);
- scontextp += strlen(policydb.p_cat_val_to_name[i - 1]);
+ nm = policydb.p_cat_val_to_name[prev];
+ strcpy(scontextp, nm);
+ scontextp += strlen(nm);
}
if (l == 0) {
if (mls_level_eq(&context->range.level[0],
&context->range.level[1]))
break;
- else {
- *scontextp = '-';
- scontextp++;
- }
+ else
+ *scontextp++ = '-';
}
}
@@ -190,17 +188,15 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
if (!levdatum)
return 0;
- ebitmap_for_each_bit(&c->range.level[l].cat, node, i) {
- if (ebitmap_node_get_bit(node, i)) {
- if (i > p->p_cats.nprim)
- return 0;
- if (!ebitmap_get_bit(&levdatum->level->cat, i))
- /*
- * Category may not be associated with
- * sensitivity in low level.
- */
- return 0;
- }
+ ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
+ if (i > p->p_cats.nprim)
+ return 0;
+ if (!ebitmap_get_bit(&levdatum->level->cat, i))
+ /*
+ * Category may not be associated with
+ * sensitivity in low level.
+ */
+ return 0;
}
}
@@ -485,18 +481,16 @@ int mls_convert_context(struct policydb *oldp,
c->range.level[l].sens = levdatum->level->sens;
ebitmap_init(&bitmap);
- ebitmap_for_each_bit(&c->range.level[l].cat, node, i) {
- if (ebitmap_node_get_bit(node, i)) {
- int rc;
-
- catdatum = hashtab_search(newp->p_cats.table,
- oldp->p_cat_val_to_name[i]);
- if (!catdatum)
- return -EINVAL;
- rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
- if (rc)
- return rc;
- }
+ ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) {
+ int rc;
+
+ catdatum = hashtab_search(newp->p_cats.table,
+ oldp->p_cat_val_to_name[i]);
+ if (!catdatum)
+ return -EINVAL;
+ rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
+ if (rc)
+ return rc;
}
ebitmap_destroy(&c->range.level[l].cat);
c->range.level[l].cat = bitmap;
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f05f97a2bc3..539828b229b 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -177,18 +177,15 @@ static int policydb_init(struct policydb *p)
rc = roles_init(p);
if (rc)
- goto out_free_avtab;
+ goto out_free_symtab;
rc = cond_policydb_init(p);
if (rc)
- goto out_free_avtab;
+ goto out_free_symtab;
out:
return rc;
-out_free_avtab:
- avtab_destroy(&p->te_avtab);
-
out_free_symtab:
for (i = 0; i < SYM_NUM; i++)
hashtab_destroy(p->symtab[i].table);
@@ -677,6 +674,8 @@ void policydb_destroy(struct policydb *p)
}
kfree(p->type_attr_map);
+ kfree(p->undefined_perms);
+
return;
}
@@ -1530,6 +1529,8 @@ int policydb_read(struct policydb *p, void *fp)
goto bad;
}
}
+ p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
+ p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
info = policydb_lookup_compat(p->policyvers);
if (!info) {
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 8319d5ff594..844d310f4f1 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -242,6 +242,10 @@ struct policydb {
struct ebitmap *type_attr_map;
unsigned int policyvers;
+
+ unsigned int reject_unknown : 1;
+ unsigned int allow_unknown : 1;
+ u32 *undefined_perms;
};
extern void policydb_destroy(struct policydb *p);
@@ -253,6 +257,10 @@ extern int policydb_read(struct policydb *p, void *fp);
#define POLICYDB_CONFIG_MLS 1
+/* the config flags related to unknown classes/perms are bits 2 and 3 */
+#define REJECT_UNKNOWN 0x00000002
+#define ALLOW_UNKNOWN 0x00000004
+
#define OBJECT_R "object_r"
#define OBJECT_R_VAL 1
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6100fc02305..d572dc908f3 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -292,6 +292,7 @@ static int context_struct_compute_av(struct context *scontext,
struct class_datum *tclass_datum;
struct ebitmap *sattr, *tattr;
struct ebitmap_node *snode, *tnode;
+ const struct selinux_class_perm *kdefs = &selinux_class_perm;
unsigned int i, j;
/*
@@ -305,13 +306,6 @@ static int context_struct_compute_av(struct context *scontext,
tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
tclass = SECCLASS_NETLINK_SOCKET;
- if (!tclass || tclass > policydb.p_classes.nprim) {
- printk(KERN_ERR "security_compute_av: unrecognized class %d\n",
- tclass);
- return -EINVAL;
- }
- tclass_datum = policydb.class_val_to_struct[tclass - 1];
-
/*
* Initialize the access vectors to the default values.
*/
@@ -322,6 +316,36 @@ static int context_struct_compute_av(struct context *scontext,
avd->seqno = latest_granting;
/*
+ * Check for all the invalid cases.
+ * - tclass 0
+ * - tclass > policy and > kernel
+ * - tclass > policy but is a userspace class
+ * - tclass > policy but we do not allow unknowns
+ */
+ if (unlikely(!tclass))
+ goto inval_class;
+ if (unlikely(tclass > policydb.p_classes.nprim))
+ if (tclass > kdefs->cts_len ||
+ !kdefs->class_to_string[tclass - 1] ||
+ !policydb.allow_unknown)
+ goto inval_class;
+
+ /*
+ * Kernel class and we allow unknown so pad the allow decision
+ * the pad will be all 1 for unknown classes.
+ */
+ if (tclass <= kdefs->cts_len && policydb.allow_unknown)
+ avd->allowed = policydb.undefined_perms[tclass - 1];
+
+ /*
+ * Not in policy. Since decision is completed (all 1 or all 0) return.
+ */
+ if (unlikely(tclass > policydb.p_classes.nprim))
+ return 0;
+
+ tclass_datum = policydb.class_val_to_struct[tclass - 1];
+
+ /*
* If a specific type enforcement rule was defined for
* this permission check, then use it.
*/
@@ -329,12 +353,8 @@ static int context_struct_compute_av(struct context *scontext,
avkey.specified = AVTAB_AV;
sattr = &policydb.type_attr_map[scontext->type - 1];
tattr = &policydb.type_attr_map[tcontext->type - 1];
- ebitmap_for_each_bit(sattr, snode, i) {
- if (!ebitmap_node_get_bit(snode, i))
- continue;
- ebitmap_for_each_bit(tattr, tnode, j) {
- if (!ebitmap_node_get_bit(tnode, j))
- continue;
+ ebitmap_for_each_positive_bit(sattr, snode, i) {
+ ebitmap_for_each_positive_bit(tattr, tnode, j) {
avkey.source_type = i + 1;
avkey.target_type = j + 1;
for (node = avtab_search_node(&policydb.te_avtab, &avkey);
@@ -387,6 +407,10 @@ static int context_struct_compute_av(struct context *scontext,
}
return 0;
+
+inval_class:
+ printk(KERN_ERR "%s: unrecognized class %d\n", __FUNCTION__, tclass);
+ return -EINVAL;
}
static int security_validtrans_handle_fail(struct context *ocontext,
@@ -1054,6 +1078,13 @@ static int validate_classes(struct policydb *p)
const char *def_class, *def_perm, *pol_class;
struct symtab *perms;
+ if (p->allow_unknown) {
+ u32 num_classes = kdefs->cts_len;
+ p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
+ if (!p->undefined_perms)
+ return -ENOMEM;
+ }
+
for (i = 1; i < kdefs->cts_len; i++) {
def_class = kdefs->class_to_string[i];
if (!def_class)
@@ -1062,6 +1093,10 @@ static int validate_classes(struct policydb *p)
printk(KERN_INFO
"security: class %s not defined in policy\n",
def_class);
+ if (p->reject_unknown)
+ return -EINVAL;
+ if (p->allow_unknown)
+ p->undefined_perms[i-1] = ~0U;
continue;
}
pol_class = p->p_class_val_to_name[i-1];
@@ -1087,12 +1122,16 @@ static int validate_classes(struct policydb *p)
printk(KERN_INFO
"security: permission %s in class %s not defined in policy\n",
def_perm, pol_class);
+ if (p->reject_unknown)
+ return -EINVAL;
+ if (p->allow_unknown)
+ p->undefined_perms[class_val-1] |= perm_val;
continue;
}
perdatum = hashtab_search(perms->table, def_perm);
if (perdatum == NULL) {
printk(KERN_ERR
- "security: permission %s in class %s not found in policy\n",
+ "security: permission %s in class %s not found in policy, bad policy\n",
def_perm, pol_class);
return -EINVAL;
}
@@ -1130,12 +1169,16 @@ static int validate_classes(struct policydb *p)
printk(KERN_INFO
"security: permission %s in class %s not defined in policy\n",
def_perm, pol_class);
+ if (p->reject_unknown)
+ return -EINVAL;
+ if (p->allow_unknown)
+ p->undefined_perms[class_val-1] |= (1 << j);
continue;
}
perdatum = hashtab_search(perms->table, def_perm);
if (perdatum == NULL) {
printk(KERN_ERR
- "security: permission %s in class %s not found in policy\n",
+ "security: permission %s in class %s not found in policy, bad policy\n",
def_perm, pol_class);
return -EINVAL;
}
@@ -1621,14 +1664,10 @@ int security_get_user_sids(u32 fromsid,
goto out_unlock;
}
- ebitmap_for_each_bit(&user->roles, rnode, i) {
- if (!ebitmap_node_get_bit(rnode, i))
- continue;
+ ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
role = policydb.role_val_to_struct[i];
usercon.role = i+1;
- ebitmap_for_each_bit(&role->types, tnode, j) {
- if (!ebitmap_node_get_bit(tnode, j))
- continue;
+ ebitmap_for_each_positive_bit(&role->types, tnode, j) {
usercon.type = j+1;
if (mls_setup_user_range(fromcon, user, &usercon))
@@ -2102,6 +2141,16 @@ err:
return rc;
}
+int security_get_reject_unknown(void)
+{
+ return policydb.reject_unknown;
+}
+
+int security_get_allow_unknown(void)
+{
+ return policydb.allow_unknown;
+}
+
struct selinux_audit_rule {
u32 au_seqno;
struct context au_ctxt;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index ba715f40b65..36a191e7004 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -31,7 +31,6 @@
* 2. Emulating a reasonable SO_PEERSEC across machines
* 3. Testing addition of sk_policy's with security context via setsockopt
*/
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/security.h>
@@ -449,7 +448,7 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
if (dst) {
struct dst_entry *dst_test;
- for (dst_test = dst; dst_test != 0;
+ for (dst_test = dst; dst_test != NULL;
dst_test = dst_test->child) {
struct xfrm_state *x = dst_test->xfrm;
diff --git a/sound/Kconfig b/sound/Kconfig
index e48b9b37d22..b2a2db47aff 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -63,6 +63,10 @@ source "sound/aoa/Kconfig"
source "sound/arm/Kconfig"
+if SPI
+source "sound/spi/Kconfig"
+endif
+
source "sound/mips/Kconfig"
source "sound/sh/Kconfig"
diff --git a/sound/Makefile b/sound/Makefile
index 3ead922bd9c..c76d70716fa 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -5,7 +5,8 @@ obj-$(CONFIG_SOUND) += soundcore.o
obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
obj-$(CONFIG_SOUND_PRIME) += oss/
obj-$(CONFIG_DMASOUND) += oss/
-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/
+obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
+ sparc/ spi/ parisc/ pcmcia/ mips/ soc/
obj-$(CONFIG_SND_AOA) += aoa/
# This one must be compilable even if sound is configured out
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
index 028852374f2..71e3f936065 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -297,15 +297,7 @@ static struct snd_kcontrol_new capture_source_control = {
.put = onyx_snd_capture_source_put,
};
-static int onyx_snd_mute_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define onyx_snd_mute_info snd_ctl_boolean_stereo_info
static int onyx_snd_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -359,15 +351,7 @@ static struct snd_kcontrol_new mute_control = {
};
-static int onyx_snd_single_bit_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define onyx_snd_single_bit_info snd_ctl_boolean_mono_info
#define FLAG_POLARITY_INVERT 1
#define FLAG_SPDIFLOCK 2
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index 2f771f57c76..70c34168479 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -272,15 +272,7 @@ static struct snd_kcontrol_new volume_control = {
.put = tas_snd_vol_put,
};
-static int tas_snd_mute_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define tas_snd_mute_info snd_ctl_boolean_stereo_info
static int tas_snd_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -431,15 +423,7 @@ static struct snd_kcontrol_new drc_range_control = {
.put = tas_snd_drc_range_put,
};
-static int tas_snd_drc_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define tas_snd_drc_switch_info snd_ctl_boolean_mono_info
static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -743,6 +727,7 @@ static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock
return 0;
}
+#ifdef CONFIG_PM
/* we are controlled via i2c and assume that is always up
* If that wasn't the case, we'd have to suspend once
* our i2c device is suspended, and then take note of that! */
@@ -768,7 +753,6 @@ static int tas_resume(struct tas *tas)
return 0;
}
-#ifdef CONFIG_PM
static int _tas_suspend(struct codec_info_item *cii, pm_message_t state)
{
return tas_suspend(cii->codec_data);
@@ -778,7 +762,10 @@ static int _tas_resume(struct codec_info_item *cii)
{
return tas_resume(cii->codec_data);
}
-#endif
+#else /* CONFIG_PM */
+#define _tas_suspend NULL
+#define _tas_resume NULL
+#endif /* CONFIG_PM */
static struct codec_info tas_codec_info = {
.transfers = tas_transfers,
@@ -791,10 +778,8 @@ static struct codec_info tas_codec_info = {
.owner = THIS_MODULE,
.usable = tas_usable,
.switch_clock = tas_switch_clock,
-#ifdef CONFIG_PM
.suspend = _tas_suspend,
.resume = _tas_resume,
-#endif
};
static int tas_init_codec(struct aoa_codec *codec)
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
index 98806283d1b..8b2ba99d7f8 100644
--- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c
+++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c
@@ -582,15 +582,7 @@ static int layouts_list_items;
* make the fabric handle all the card stuff, etc... */
static struct layout_dev *layout_device;
-static int control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define control_info snd_ctl_boolean_mono_info
#define AMP_CONTROL(n, description) \
static int n##_control_get(struct snd_kcontrol *kcontrol, \
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index b9eca9f3dd2..3b73ba7d03e 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -209,7 +209,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
void *ptr;
if (!aacirun->substream || !aacirun->start) {
- dev_warn(&aaci->dev->dev, "RX interrupt???");
+ dev_warn(&aaci->dev->dev, "RX interrupt???\n");
writel(0, aacirun->base + AACI_IE);
return;
}
@@ -263,7 +263,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
void *ptr;
if (!aacirun->substream || !aacirun->start) {
- dev_warn(&aaci->dev->dev, "TX interrupt???");
+ dev_warn(&aaci->dev->dev, "TX interrupt???\n");
writel(0, aacirun->base + AACI_IE);
return;
}
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index e7ed868fa7c..81c64b09d35 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -79,12 +79,6 @@
#include <asm/mach-types.h>
#include <asm/dma.h>
-#ifdef CONFIG_H3600_HAL
-#include <asm/semaphore.h>
-#include <asm/uaccess.h>
-#include <asm/arch/h3600_hal.h>
-#endif
-
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
@@ -100,9 +94,6 @@
* We use DMA stuff from 2.4.18-rmk3-hh24 here to be able to compile this
* module for Familiar 0.6.1
*/
-#ifdef CONFIG_H3600_HAL
-#define HH_VERSION 1
-#endif
/* {{{ Type definitions */
@@ -238,11 +229,8 @@ static void sa11xx_uda1341_set_samplerate(struct sa11xx_uda1341 *sa11xx_uda1341,
rate = 8000;
/* Set the external clock generator */
-#ifdef CONFIG_H3600_HAL
- h3600_audio_clock(rate);
-#else
+
sa11xx_uda1341_set_audio_clock(rate);
-#endif
/* Select the clock divisor */
switch (rate) {
@@ -307,13 +295,10 @@ static void sa11xx_uda1341_audio_init(struct sa11xx_uda1341 *sa11xx_uda1341)
local_irq_restore(flags);
/* Enable the audio power */
-#ifdef CONFIG_H3600_HAL
- h3600_audio_power(AUDIO_RATE_DEFAULT);
-#else
+
clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_CODEC_NRESET);
set_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
-#endif
/* Wait for the UDA1341 to wake up */
mdelay(1); //FIXME - was removed by Perex - Why?
@@ -331,21 +316,13 @@ static void sa11xx_uda1341_audio_init(struct sa11xx_uda1341 *sa11xx_uda1341)
/* make the left and right channels unswapped (flip the WS latch) */
Ser4SSDR = 0;
-#ifdef CONFIG_H3600_HAL
- h3600_audio_mute(0);
-#else
- clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
-#endif
+ clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
}
static void sa11xx_uda1341_audio_shutdown(struct sa11xx_uda1341 *sa11xx_uda1341)
{
/* mute on */
-#ifdef CONFIG_H3600_HAL
- h3600_audio_mute(1);
-#else
set_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
-#endif
/* disable the audio power and all signals leading to the audio chip */
l3_close(sa11xx_uda1341->uda1341);
@@ -354,13 +331,9 @@ static void sa11xx_uda1341_audio_shutdown(struct sa11xx_uda1341 *sa11xx_uda1341)
/* power off and mute off */
/* FIXME - is muting off necesary??? */
-#ifdef CONFIG_H3600_HAL
- h3600_audio_power(0);
- h3600_audio_mute(0);
-#else
+
clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_AUDIO_ON);
clr_sa11xx_uda1341_egpio(IPAQ_EGPIO_QMUTE);
-#endif
}
/* }}} */
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 5a01c76d02e..267039a97bd 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -1,20 +1,17 @@
#
# Makefile for ALSA
-# Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 1999,2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-objs := sound.o init.o memory.o info.o control.o misc.o device.o
-ifeq ($(CONFIG_ISA_DMA_API),y)
-snd-objs += isadma.o
-endif
-ifeq ($(CONFIG_SND_OSSEMUL),y)
-snd-objs += sound_oss.o info_oss.o
-endif
+snd-y := sound.o init.o memory.o info.o control.o misc.o device.o
+snd-$(CONFIG_ISA_DMA_API) += isadma.o
+snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
pcm_memory.o
-snd-page-alloc-objs := memalloc.o sgbuf.o
+snd-page-alloc-y := memalloc.o
+snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o
snd-rawmidi-objs := rawmidi.o
snd-timer-objs := timer.o
diff --git a/sound/core/control.c b/sound/core/control.c
index 1f1ab9c1b66..4c3aa8e1037 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1,6 +1,6 @@
/*
* Routines for driver control interface
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -716,8 +716,6 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
return result;
}
-EXPORT_SYMBOL(snd_ctl_elem_read);
-
static int snd_ctl_elem_read_user(struct snd_card *card,
struct snd_ctl_elem_value __user *_control)
{
@@ -781,8 +779,6 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
return result;
}
-EXPORT_SYMBOL(snd_ctl_elem_write);
-
static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
struct snd_ctl_elem_value __user *_control)
{
@@ -1486,3 +1482,30 @@ int snd_ctl_create(struct snd_card *card)
snd_assert(card != NULL, return -ENXIO);
return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
}
+
+/*
+ * Frequently used control callbacks
+ */
+int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+EXPORT_SYMBOL(snd_ctl_boolean_mono_info);
+
+int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);
diff --git a/sound/core/device.c b/sound/core/device.c
index 5858b02b0b1..ea1a0621eef 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -1,6 +1,6 @@
/*
* Device management routines
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 51ad95b7c89..bfd9d182b8a 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -1,6 +1,6 @@
/*
* Hardware dependent layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
#include <sound/hwdep.h>
#include <sound/info.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Hardware dependent layer");
MODULE_LICENSE("GPL");
diff --git a/sound/core/info.c b/sound/core/info.c
index bf6dbf99528..1ffd29bb4cd 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -1,6 +1,6 @@
/*
* Information interface for ALSA driver
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index a444bfe2cf7..435c9399f7a 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -1,6 +1,6 @@
/*
* Information interface for ALSA driver
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/init.c b/sound/core/init.c
index f2fe3573718..2cb7099eb1e 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -1,6 +1,6 @@
/*
* Initialization routines
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index d52398727f0..eb173cef4f0 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -1,6 +1,6 @@
/*
* ISA DMA support functions
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 9b5656d8bcc..9b4992eab47 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Takashi Iwai <tiwai@suse.de>
*
* Generic memory allocators
@@ -38,7 +38,7 @@
#endif
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Memory allocator for ALSA system.");
MODULE_LICENSE("GPL");
@@ -206,6 +206,7 @@ void snd_free_pages(void *ptr, size_t size)
*
*/
+#ifdef CONFIG_HAS_DMA
/* allocate the coherent DMA pages */
static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *dma)
{
@@ -239,6 +240,7 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
dec_snd_pages(pg);
dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
}
+#endif /* CONFIG_HAS_DMA */
#ifdef CONFIG_SBUS
@@ -312,12 +314,14 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
dmab->area = snd_malloc_sbus_pages(device, size, &dmab->addr);
break;
#endif
+#ifdef CONFIG_HAS_DMA
case SNDRV_DMA_TYPE_DEV:
dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
break;
case SNDRV_DMA_TYPE_DEV_SG:
snd_malloc_sgbuf_pages(device, size, dmab, NULL);
break;
+#endif
default:
printk(KERN_ERR "snd-malloc: invalid device type %d\n", type);
dmab->area = NULL;
@@ -383,12 +387,14 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
snd_free_sbus_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
break;
#endif
+#ifdef CONFIG_HAS_DMA
case SNDRV_DMA_TYPE_DEV:
snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
break;
case SNDRV_DMA_TYPE_DEV_SG:
snd_free_sgbuf_pages(dmab);
break;
+#endif
default:
printk(KERN_ERR "snd-malloc: invalid device type %d\n", dmab->dev.type);
}
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 93537ab7c2a..25b0f056563 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* Misc memory accessors
*
diff --git a/sound/core/misc.c b/sound/core/misc.c
index f78cd000e88..6cabab8cc53 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -1,6 +1,6 @@
/*
* Misc and compatibility things
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/oss/Makefile b/sound/core/oss/Makefile
index e6d5a045ba2..10a79453245 100644
--- a/sound/core/oss/Makefile
+++ b/sound/core/oss/Makefile
@@ -1,12 +1,13 @@
#
# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
snd-mixer-oss-objs := mixer_oss.o
-snd-pcm-oss-objs := pcm_oss.o pcm_plugin.o \
- io.o copy.o linear.o mulaw.o route.o rate.o
+snd-pcm-oss-y := pcm_oss.o
+snd-pcm-oss-$(CONFIG_SND_PCM_OSS_PLUGINS) += pcm_plugin.o \
+ io.o copy.o linear.o mulaw.o route.o rate.o
obj-$(CONFIG_SND_MIXER_OSS) += snd-mixer-oss.o
obj-$(CONFIG_SND_PCM_OSS) += snd-pcm-oss.o
diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c
index 6658facc5cd..d6a04c2d5a7 100644
--- a/sound/core/oss/copy.c
+++ b/sound/core/oss/copy.c
@@ -20,9 +20,6 @@
*/
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -88,5 +85,3 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
-
-#endif
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c
index b6e7ce30e5a..3ece39fc48d 100644
--- a/sound/core/oss/io.c
+++ b/sound/core/oss/io.c
@@ -1,6 +1,6 @@
/*
* PCM I/O Plug-In Interface
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
*
* This library is free software; you can redistribute it and/or modify
@@ -20,9 +20,6 @@
*/
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -135,5 +132,3 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
-
-#endif
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index 5b1bcdc6477..06f96a3e86f 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -1,6 +1,6 @@
/*
* Linear conversion Plug-In
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>,
* Abramo Bagnara <abramo@alsa-project.org>
*
*
@@ -21,9 +21,6 @@
*/
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -34,19 +31,34 @@
*/
struct linear_priv {
- int conv;
+ int cvt_endian; /* need endian conversion? */
+ unsigned int src_ofs; /* byte offset in source format */
+ unsigned int dst_ofs; /* byte soffset in destination format */
+ unsigned int copy_ofs; /* byte offset in temporary u32 data */
+ unsigned int dst_bytes; /* byte size of destination format */
+ unsigned int copy_bytes; /* bytes to copy per conversion */
+ unsigned int flip; /* MSB flip for signeness, done after endian conv */
};
+static inline void do_convert(struct linear_priv *data,
+ unsigned char *dst, unsigned char *src)
+{
+ unsigned int tmp = 0;
+ unsigned char *p = (unsigned char *)&tmp;
+
+ memcpy(p + data->copy_ofs, src + data->src_ofs, data->copy_bytes);
+ if (data->cvt_endian)
+ tmp = swab32(tmp);
+ tmp ^= data->flip;
+ memcpy(dst, p + data->dst_ofs, data->dst_bytes);
+}
+
static void convert(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channels,
snd_pcm_uframes_t frames)
{
-#define CONV_LABELS
-#include "plugin_ops.h"
-#undef CONV_LABELS
struct linear_priv *data = (struct linear_priv *)plugin->extra_data;
- void *conv = conv_labels[data->conv];
int channel;
int nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; ++channel) {
@@ -67,11 +79,7 @@ static void convert(struct snd_pcm_plugin *plugin,
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
- goto *conv;
-#define CONV_END after
-#include "plugin_ops.h"
-#undef CONV_END
- after:
+ do_convert(data, dst, src);
src += src_step;
dst += dst_step;
}
@@ -106,29 +114,36 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
return frames;
}
-static int conv_index(int src_format, int dst_format)
+static void init_data(struct linear_priv *data, int src_format, int dst_format)
{
- int src_endian, dst_endian, sign, src_width, dst_width;
-
- sign = (snd_pcm_format_signed(src_format) !=
- snd_pcm_format_signed(dst_format));
-#ifdef SNDRV_LITTLE_ENDIAN
- src_endian = snd_pcm_format_big_endian(src_format);
- dst_endian = snd_pcm_format_big_endian(dst_format);
-#else
- src_endian = snd_pcm_format_little_endian(src_format);
- dst_endian = snd_pcm_format_little_endian(dst_format);
-#endif
-
- if (src_endian < 0)
- src_endian = 0;
- if (dst_endian < 0)
- dst_endian = 0;
-
- src_width = snd_pcm_format_width(src_format) / 8 - 1;
- dst_width = snd_pcm_format_width(dst_format) / 8 - 1;
-
- return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian;
+ int src_le, dst_le, src_bytes, dst_bytes;
+
+ src_bytes = snd_pcm_format_width(src_format) / 8;
+ dst_bytes = snd_pcm_format_width(dst_format) / 8;
+ src_le = snd_pcm_format_little_endian(src_format) > 0;
+ dst_le = snd_pcm_format_little_endian(dst_format) > 0;
+
+ data->dst_bytes = dst_bytes;
+ data->cvt_endian = src_le != dst_le;
+ data->copy_bytes = src_bytes < dst_bytes ? src_bytes : dst_bytes;
+ if (src_le) {
+ data->copy_ofs = 4 - data->copy_bytes;
+ data->src_ofs = src_bytes - data->copy_bytes;
+ } else
+ data->src_ofs = snd_pcm_format_physical_width(src_format) / 8 -
+ src_bytes;
+ if (dst_le)
+ data->dst_ofs = 4 - data->dst_bytes;
+ else
+ data->dst_ofs = snd_pcm_format_physical_width(dst_format) / 8 -
+ dst_bytes;
+ if (snd_pcm_format_signed(src_format) !=
+ snd_pcm_format_signed(dst_format)) {
+ if (dst_le)
+ data->flip = cpu_to_le32(0x80000000);
+ else
+ data->flip = cpu_to_be32(0x80000000);
+ }
}
int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
@@ -154,10 +169,8 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
if (err < 0)
return err;
data = (struct linear_priv *)plugin->extra_data;
- data->conv = conv_index(src_format->format, dst_format->format);
+ init_data(data, src_format->format, dst_format->format);
plugin->transfer = linear_transfer;
*r_plugin = plugin;
return 0;
}
-
-#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index fccad8f0a6b..3ace4a5680b 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1,6 +1,6 @@
/*
* OSS emulation layer for the mixer interface
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -33,7 +33,7 @@
#define OSS_ALSAEMULVER _SIOR ('M', 249, int)
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Mixer OSS emulation for ALSA.");
MODULE_LICENSE("GPL");
MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MIXER);
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
index 2eb18807e6d..848db82529e 100644
--- a/sound/core/oss/mulaw.c
+++ b/sound/core/oss/mulaw.c
@@ -1,6 +1,6 @@
/*
* Mu-Law conversion Plug-In Interface
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
* Uros Bizjak <uros@kss-loka.si>
*
* Based on reference implementation by Sun Microsystems, Inc.
@@ -22,9 +22,6 @@
*/
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -149,19 +146,32 @@ typedef void (*mulaw_f)(struct snd_pcm_plugin *plugin,
struct mulaw_priv {
mulaw_f func;
- int conv;
+ int cvt_endian; /* need endian conversion? */
+ unsigned int native_ofs; /* byte offset in native format */
+ unsigned int copy_ofs; /* byte offset in s16 format */
+ unsigned int native_bytes; /* byte size of the native format */
+ unsigned int copy_bytes; /* bytes to copy per conversion */
+ u16 flip; /* MSB flip for signedness, done after endian conversion */
};
+static inline void cvt_s16_to_native(struct mulaw_priv *data,
+ unsigned char *dst, u16 sample)
+{
+ sample ^= data->flip;
+ if (data->cvt_endian)
+ sample = swab16(sample);
+ if (data->native_bytes > data->copy_bytes)
+ memset(dst, 0, data->native_bytes);
+ memcpy(dst + data->native_ofs, (char *)&sample + data->copy_ofs,
+ data->copy_bytes);
+}
+
static void mulaw_decode(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channels,
snd_pcm_uframes_t frames)
{
-#define PUT_S16_LABELS
-#include "plugin_ops.h"
-#undef PUT_S16_LABELS
struct mulaw_priv *data = (struct mulaw_priv *)plugin->extra_data;
- void *put = put_s16_labels[data->conv];
int channel;
int nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; ++channel) {
@@ -183,30 +193,33 @@ static void mulaw_decode(struct snd_pcm_plugin *plugin,
frames1 = frames;
while (frames1-- > 0) {
signed short sample = ulaw2linear(*src);
- goto *put;
-#define PUT_S16_END after
-#include "plugin_ops.h"
-#undef PUT_S16_END
- after:
+ cvt_s16_to_native(data, dst, sample);
src += src_step;
dst += dst_step;
}
}
}
+static inline signed short cvt_native_to_s16(struct mulaw_priv *data,
+ unsigned char *src)
+{
+ u16 sample = 0;
+ memcpy((char *)&sample + data->copy_ofs, src + data->native_ofs,
+ data->copy_bytes);
+ if (data->cvt_endian)
+ sample = swab16(sample);
+ sample ^= data->flip;
+ return (signed short)sample;
+}
+
static void mulaw_encode(struct snd_pcm_plugin *plugin,
const struct snd_pcm_plugin_channel *src_channels,
struct snd_pcm_plugin_channel *dst_channels,
snd_pcm_uframes_t frames)
{
-#define GET_S16_LABELS
-#include "plugin_ops.h"
-#undef GET_S16_LABELS
struct mulaw_priv *data = (struct mulaw_priv *)plugin->extra_data;
- void *get = get_s16_labels[data->conv];
int channel;
int nchannels = plugin->src_format.channels;
- signed short sample = 0;
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
@@ -225,11 +238,7 @@ static void mulaw_encode(struct snd_pcm_plugin *plugin,
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
- goto *get;
-#define GET_S16_END after
-#include "plugin_ops.h"
-#undef GET_S16_END
- after:
+ signed short sample = cvt_native_to_s16(data, src);
*dst = linear2ulaw(sample);
src += src_step;
dst += dst_step;
@@ -265,23 +274,25 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
return frames;
}
-static int getput_index(int format)
+static void init_data(struct mulaw_priv *data, int format)
{
- int sign, width, endian;
- sign = !snd_pcm_format_signed(format);
- width = snd_pcm_format_width(format) / 8 - 1;
- if (width < 0 || width > 3) {
- snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
- width = 0;
- }
#ifdef SNDRV_LITTLE_ENDIAN
- endian = snd_pcm_format_big_endian(format);
+ data->cvt_endian = snd_pcm_format_big_endian(format) > 0;
#else
- endian = snd_pcm_format_little_endian(format);
+ data->cvt_endian = snd_pcm_format_little_endian(format) > 0;
#endif
- if (endian < 0)
- endian = 0;
- return width * 4 + endian * 2 + sign;
+ if (!snd_pcm_format_signed(format))
+ data->flip = 0x8000;
+ data->native_bytes = snd_pcm_format_physical_width(format) / 8;
+ data->copy_bytes = data->native_bytes < 2 ? 1 : 2;
+ if (snd_pcm_format_little_endian(format)) {
+ data->native_ofs = data->native_bytes - data->copy_bytes;
+ data->copy_ofs = 2 - data->copy_bytes;
+ } else {
+ /* S24 in 4bytes need an 1 byte offset */
+ data->native_ofs = data->native_bytes -
+ snd_pcm_format_width(format) / 8;
+ }
}
int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
@@ -322,11 +333,8 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
return err;
data = (struct mulaw_priv *)plugin->extra_data;
data->func = func;
- data->conv = getput_index(format->format);
- snd_assert(data->conv >= 0 && data->conv < 4*2*2, return -EINVAL);
+ init_data(data, format->format);
plugin->transfer = mulaw_transfer;
*r_plugin = plugin;
return 0;
}
-
-#endif
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index fc11572c48c..d0c4ceb9f0b 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1,6 +1,6 @@
/*
* Digital Audio (PCM) abstract layer / OSS compatible
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -48,7 +48,7 @@ static int dsp_map[SNDRV_CARDS];
static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
static int nonblock_open = 1;
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
MODULE_LICENSE("GPL");
module_param_array(dsp_map, int, NULL, 0444);
@@ -633,6 +633,22 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
}
+/* define extended formats in the recent OSS versions (if any) */
+/* linear formats */
+#define AFMT_S32_LE 0x00001000
+#define AFMT_S32_BE 0x00002000
+#define AFMT_S24_LE 0x00008000
+#define AFMT_S24_BE 0x00010000
+#define AFMT_S24_PACKED 0x00040000
+
+/* other supported formats */
+#define AFMT_FLOAT 0x00004000
+#define AFMT_SPDIF_RAW 0x00020000
+
+/* unsupported formats */
+#define AFMT_AC3 0x00000400
+#define AFMT_VORBIS 0x00000800
+
static int snd_pcm_oss_format_from(int format)
{
switch (format) {
@@ -646,6 +662,13 @@ static int snd_pcm_oss_format_from(int format)
case AFMT_U16_LE: return SNDRV_PCM_FORMAT_U16_LE;
case AFMT_U16_BE: return SNDRV_PCM_FORMAT_U16_BE;
case AFMT_MPEG: return SNDRV_PCM_FORMAT_MPEG;
+ case AFMT_S32_LE: return SNDRV_PCM_FORMAT_S32_LE;
+ case AFMT_S32_BE: return SNDRV_PCM_FORMAT_S32_BE;
+ case AFMT_S24_LE: return SNDRV_PCM_FORMAT_S24_LE;
+ case AFMT_S24_BE: return SNDRV_PCM_FORMAT_S24_BE;
+ case AFMT_S24_PACKED: return SNDRV_PCM_FORMAT_S24_3LE;
+ case AFMT_FLOAT: return SNDRV_PCM_FORMAT_FLOAT;
+ case AFMT_SPDIF_RAW: return SNDRV_PCM_FORMAT_IEC958_SUBFRAME;
default: return SNDRV_PCM_FORMAT_U8;
}
}
@@ -663,6 +686,13 @@ static int snd_pcm_oss_format_to(int format)
case SNDRV_PCM_FORMAT_U16_LE: return AFMT_U16_LE;
case SNDRV_PCM_FORMAT_U16_BE: return AFMT_U16_BE;
case SNDRV_PCM_FORMAT_MPEG: return AFMT_MPEG;
+ case SNDRV_PCM_FORMAT_S32_LE: return AFMT_S32_LE;
+ case SNDRV_PCM_FORMAT_S32_BE: return AFMT_S32_BE;
+ case SNDRV_PCM_FORMAT_S24_LE: return AFMT_S24_LE;
+ case SNDRV_PCM_FORMAT_S24_BE: return AFMT_S24_BE;
+ case SNDRV_PCM_FORMAT_S24_3LE: return AFMT_S24_PACKED;
+ case SNDRV_PCM_FORMAT_FLOAT: return AFMT_FLOAT;
+ case SNDRV_PCM_FORMAT_IEC958_SUBFRAME: return AFMT_SPDIF_RAW;
default: return -EINVAL;
}
}
@@ -1725,7 +1755,10 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
return AFMT_MU_LAW | AFMT_U8 |
AFMT_S16_LE | AFMT_S16_BE |
AFMT_S8 | AFMT_U16_LE |
- AFMT_U16_BE;
+ AFMT_U16_BE |
+ AFMT_S32_LE | AFMT_S32_BE |
+ AFMT_S24_LE | AFMT_S24_LE |
+ AFMT_S24_PACKED;
params = kmalloc(sizeof(*params), GFP_KERNEL);
if (!params)
return -ENOMEM;
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 0e67dd280a5..14095a927a1 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -1,6 +1,6 @@
/*
* PCM Plug-In shared (kernel/library) code
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
*
@@ -25,9 +25,6 @@
#endif
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
@@ -267,6 +264,8 @@ static int snd_pcm_plug_formats(struct snd_mask *mask, int format)
SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE |
+ SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE |
SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW);
@@ -283,6 +282,10 @@ static int preferred_formats[] = {
SNDRV_PCM_FORMAT_S16_BE,
SNDRV_PCM_FORMAT_U16_LE,
SNDRV_PCM_FORMAT_U16_BE,
+ SNDRV_PCM_FORMAT_S24_3LE,
+ SNDRV_PCM_FORMAT_S24_3BE,
+ SNDRV_PCM_FORMAT_U24_3LE,
+ SNDRV_PCM_FORMAT_U24_3BE,
SNDRV_PCM_FORMAT_S24_LE,
SNDRV_PCM_FORMAT_S24_BE,
SNDRV_PCM_FORMAT_U24_LE,
@@ -297,41 +300,37 @@ static int preferred_formats[] = {
int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask)
{
+ int i;
+
if (snd_mask_test(format_mask, format))
return format;
if (! snd_pcm_plug_formats(format_mask, format))
return -EINVAL;
if (snd_pcm_format_linear(format)) {
- int width = snd_pcm_format_width(format);
- int unsignd = snd_pcm_format_unsigned(format);
- int big = snd_pcm_format_big_endian(format);
- int format1;
- int wid, width1=width;
- int dwidth1 = 8;
- for (wid = 0; wid < 4; ++wid) {
- int end, big1 = big;
- for (end = 0; end < 2; ++end) {
- int sgn, unsignd1 = unsignd;
- for (sgn = 0; sgn < 2; ++sgn) {
- format1 = snd_pcm_build_linear_format(width1, unsignd1, big1);
- if (format1 >= 0 &&
- snd_mask_test(format_mask, format1))
- goto _found;
- unsignd1 = !unsignd1;
- }
- big1 = !big1;
- }
- if (width1 == 32) {
- dwidth1 = -dwidth1;
- width1 = width;
+ unsigned int width = snd_pcm_format_width(format);
+ int unsignd = snd_pcm_format_unsigned(format) > 0;
+ int big = snd_pcm_format_big_endian(format) > 0;
+ unsigned int badness, best = -1;
+ int best_format = -1;
+ for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
+ int f = preferred_formats[i];
+ unsigned int w;
+ if (!snd_mask_test(format_mask, f))
+ continue;
+ w = snd_pcm_format_width(f);
+ if (w >= width)
+ badness = w - width;
+ else
+ badness = width - w + 32;
+ badness += snd_pcm_format_unsigned(f) != unsignd;
+ badness += snd_pcm_format_big_endian(f) != big;
+ if (badness < best) {
+ best_format = f;
+ best = badness;
}
- width1 += dwidth1;
}
- return -EINVAL;
- _found:
- return format1;
+ return best_format >= 0 ? best_format : -EINVAL;
} else {
- unsigned int i;
switch (format) {
case SNDRV_PCM_FORMAT_MU_LAW:
for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
@@ -740,5 +739,3 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of
}
return 0;
}
-
-#endif
diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
index 3be91b3d537..ca2f4c39be4 100644
--- a/sound/core/oss/pcm_plugin.h
+++ b/sound/core/oss/pcm_plugin.h
@@ -3,7 +3,7 @@
/*
* Digital Audio (Plugin interface) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/oss/plugin_ops.h b/sound/core/oss/plugin_ops.h
deleted file mode 100644
index 1f5bde4631f..00000000000
--- a/sound/core/oss/plugin_ops.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Plugin sample operators with fast switch
- * Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
- *
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library 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 Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library 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
- *
- */
-
-
-#define as_u8(ptr) (*(u_int8_t*)(ptr))
-#define as_u16(ptr) (*(u_int16_t*)(ptr))
-#define as_u32(ptr) (*(u_int32_t*)(ptr))
-#define as_u64(ptr) (*(u_int64_t*)(ptr))
-#define as_s8(ptr) (*(int8_t*)(ptr))
-#define as_s16(ptr) (*(int16_t*)(ptr))
-#define as_s32(ptr) (*(int32_t*)(ptr))
-#define as_s64(ptr) (*(int64_t*)(ptr))
-
-#ifdef COPY_LABELS
-static void *copy_labels[4] = {
- &&copy_8,
- &&copy_16,
- &&copy_32,
- &&copy_64
-};
-#endif
-
-#ifdef COPY_END
-while(0) {
-copy_8: as_s8(dst) = as_s8(src); goto COPY_END;
-copy_16: as_s16(dst) = as_s16(src); goto COPY_END;
-copy_32: as_s32(dst) = as_s32(src); goto COPY_END;
-copy_64: as_s64(dst) = as_s64(src); goto COPY_END;
-}
-#endif
-
-#ifdef CONV_LABELS
-/* src_wid src_endswap sign_toggle dst_wid dst_endswap */
-static void *conv_labels[4 * 2 * 2 * 4 * 2] = {
- &&conv_xxx1_xxx1, /* 8h -> 8h */
- &&conv_xxx1_xxx1, /* 8h -> 8s */
- &&conv_xxx1_xx10, /* 8h -> 16h */
- &&conv_xxx1_xx01, /* 8h -> 16s */
- &&conv_xxx1_x100, /* 8h -> 24h */
- &&conv_xxx1_001x, /* 8h -> 24s */
- &&conv_xxx1_1000, /* 8h -> 32h */
- &&conv_xxx1_0001, /* 8h -> 32s */
- &&conv_xxx1_xxx9, /* 8h ^> 8h */
- &&conv_xxx1_xxx9, /* 8h ^> 8s */
- &&conv_xxx1_xx90, /* 8h ^> 16h */
- &&conv_xxx1_xx09, /* 8h ^> 16s */
- &&conv_xxx1_x900, /* 8h ^> 24h */
- &&conv_xxx1_009x, /* 8h ^> 24s */
- &&conv_xxx1_9000, /* 8h ^> 32h */
- &&conv_xxx1_0009, /* 8h ^> 32s */
- &&conv_xxx1_xxx1, /* 8s -> 8h */
- &&conv_xxx1_xxx1, /* 8s -> 8s */
- &&conv_xxx1_xx10, /* 8s -> 16h */
- &&conv_xxx1_xx01, /* 8s -> 16s */
- &&conv_xxx1_x100, /* 8s -> 24h */
- &&conv_xxx1_001x, /* 8s -> 24s */
- &&conv_xxx1_1000, /* 8s -> 32h */
- &&conv_xxx1_0001, /* 8s -> 32s */
- &&conv_xxx1_xxx9, /* 8s ^> 8h */
- &&conv_xxx1_xxx9, /* 8s ^> 8s */
- &&conv_xxx1_xx90, /* 8s ^> 16h */
- &&conv_xxx1_xx09, /* 8s ^> 16s */
- &&conv_xxx1_x900, /* 8s ^> 24h */
- &&conv_xxx1_009x, /* 8s ^> 24s */
- &&conv_xxx1_9000, /* 8s ^> 32h */
- &&conv_xxx1_0009, /* 8s ^> 32s */
- &&conv_xx12_xxx1, /* 16h -> 8h */
- &&conv_xx12_xxx1, /* 16h -> 8s */
- &&conv_xx12_xx12, /* 16h -> 16h */
- &&conv_xx12_xx21, /* 16h -> 16s */
- &&conv_xx12_x120, /* 16h -> 24h */
- &&conv_xx12_021x, /* 16h -> 24s */
- &&conv_xx12_1200, /* 16h -> 32h */
- &&conv_xx12_0021, /* 16h -> 32s */
- &&conv_xx12_xxx9, /* 16h ^> 8h */
- &&conv_xx12_xxx9, /* 16h ^> 8s */
- &&conv_xx12_xx92, /* 16h ^> 16h */
- &&conv_xx12_xx29, /* 16h ^> 16s */
- &&conv_xx12_x920, /* 16h ^> 24h */
- &&conv_xx12_029x, /* 16h ^> 24s */
- &&conv_xx12_9200, /* 16h ^> 32h */
- &&conv_xx12_0029, /* 16h ^> 32s */
- &&conv_xx12_xxx2, /* 16s -> 8h */
- &&conv_xx12_xxx2, /* 16s -> 8s */
- &&conv_xx12_xx21, /* 16s -> 16h */
- &&conv_xx12_xx12, /* 16s -> 16s */
- &&conv_xx12_x210, /* 16s -> 24h */
- &&conv_xx12_012x, /* 16s -> 24s */
- &&conv_xx12_2100, /* 16s -> 32h */
- &&conv_xx12_0012, /* 16s -> 32s */
- &&conv_xx12_xxxA, /* 16s ^> 8h */
- &&conv_xx12_xxxA, /* 16s ^> 8s */
- &&conv_xx12_xxA1, /* 16s ^> 16h */
- &&conv_xx12_xx1A, /* 16s ^> 16s */
- &&conv_xx12_xA10, /* 16s ^> 24h */
- &&conv_xx12_01Ax, /* 16s ^> 24s */
- &&conv_xx12_A100, /* 16s ^> 32h */
- &&conv_xx12_001A, /* 16s ^> 32s */
- &&conv_x123_xxx1, /* 24h -> 8h */
- &&conv_x123_xxx1, /* 24h -> 8s */
- &&conv_x123_xx12, /* 24h -> 16h */
- &&conv_x123_xx21, /* 24h -> 16s */
- &&conv_x123_x123, /* 24h -> 24h */
- &&conv_x123_321x, /* 24h -> 24s */
- &&conv_x123_1230, /* 24h -> 32h */
- &&conv_x123_0321, /* 24h -> 32s */
- &&conv_x123_xxx9, /* 24h ^> 8h */
- &&conv_x123_xxx9, /* 24h ^> 8s */
- &&conv_x123_xx92, /* 24h ^> 16h */
- &&conv_x123_xx29, /* 24h ^> 16s */
- &&conv_x123_x923, /* 24h ^> 24h */
- &&conv_x123_329x, /* 24h ^> 24s */
- &&conv_x123_9230, /* 24h ^> 32h */
- &&conv_x123_0329, /* 24h ^> 32s */
- &&conv_123x_xxx3, /* 24s -> 8h */
- &&conv_123x_xxx3, /* 24s -> 8s */
- &&conv_123x_xx32, /* 24s -> 16h */
- &&conv_123x_xx23, /* 24s -> 16s */
- &&conv_123x_x321, /* 24s -> 24h */
- &&conv_123x_123x, /* 24s -> 24s */
- &&conv_123x_3210, /* 24s -> 32h */
- &&conv_123x_0123, /* 24s -> 32s */
- &&conv_123x_xxxB, /* 24s ^> 8h */
- &&conv_123x_xxxB, /* 24s ^> 8s */
- &&conv_123x_xxB2, /* 24s ^> 16h */
- &&conv_123x_xx2B, /* 24s ^> 16s */
- &&conv_123x_xB21, /* 24s ^> 24h */
- &&conv_123x_12Bx, /* 24s ^> 24s */
- &&conv_123x_B210, /* 24s ^> 32h */
- &&conv_123x_012B, /* 24s ^> 32s */
- &&conv_1234_xxx1, /* 32h -> 8h */
- &&conv_1234_xxx1, /* 32h -> 8s */
- &&conv_1234_xx12, /* 32h -> 16h */
- &&conv_1234_xx21, /* 32h -> 16s */
- &&conv_1234_x123, /* 32h -> 24h */
- &&conv_1234_321x, /* 32h -> 24s */
- &&conv_1234_1234, /* 32h -> 32h */
- &&conv_1234_4321, /* 32h -> 32s */
- &&conv_1234_xxx9, /* 32h ^> 8h */
- &&conv_1234_xxx9, /* 32h ^> 8s */
- &&conv_1234_xx92, /* 32h ^> 16h */
- &&conv_1234_xx29, /* 32h ^> 16s */
- &&conv_1234_x923, /* 32h ^> 24h */
- &&conv_1234_329x, /* 32h ^> 24s */
- &&conv_1234_9234, /* 32h ^> 32h */
- &&conv_1234_4329, /* 32h ^> 32s */
- &&conv_1234_xxx4, /* 32s -> 8h */
- &&conv_1234_xxx4, /* 32s -> 8s */
- &&conv_1234_xx43, /* 32s -> 16h */
- &&conv_1234_xx34, /* 32s -> 16s */
- &&conv_1234_x432, /* 32s -> 24h */
- &&conv_1234_234x, /* 32s -> 24s */
- &&conv_1234_4321, /* 32s -> 32h */
- &&conv_1234_1234, /* 32s -> 32s */
- &&conv_1234_xxxC, /* 32s ^> 8h */
- &&conv_1234_xxxC, /* 32s ^> 8s */
- &&conv_1234_xxC3, /* 32s ^> 16h */
- &&conv_1234_xx3C, /* 32s ^> 16s */
- &&conv_1234_xC32, /* 32s ^> 24h */
- &&conv_1234_23Cx, /* 32s ^> 24s */
- &&conv_1234_C321, /* 32s ^> 32h */
- &&conv_1234_123C, /* 32s ^> 32s */
-};
-#endif
-
-#ifdef CONV_END
-while(0) {
-conv_xxx1_xxx1: as_u8(dst) = as_u8(src); goto CONV_END;
-conv_xxx1_xx10: as_u16(dst) = (u_int16_t)as_u8(src) << 8; goto CONV_END;
-conv_xxx1_xx01: as_u16(dst) = (u_int16_t)as_u8(src); goto CONV_END;
-conv_xxx1_x100: as_u32(dst) = (u_int32_t)as_u8(src) << 16; goto CONV_END;
-conv_xxx1_001x: as_u32(dst) = (u_int32_t)as_u8(src) << 8; goto CONV_END;
-conv_xxx1_1000: as_u32(dst) = (u_int32_t)as_u8(src) << 24; goto CONV_END;
-conv_xxx1_0001: as_u32(dst) = (u_int32_t)as_u8(src); goto CONV_END;
-conv_xxx1_xxx9: as_u8(dst) = as_u8(src) ^ 0x80; goto CONV_END;
-conv_xxx1_xx90: as_u16(dst) = (u_int16_t)(as_u8(src) ^ 0x80) << 8; goto CONV_END;
-conv_xxx1_xx09: as_u16(dst) = (u_int16_t)(as_u8(src) ^ 0x80); goto CONV_END;
-conv_xxx1_x900: as_u32(dst) = (u_int32_t)(as_u8(src) ^ 0x80) << 16; goto CONV_END;
-conv_xxx1_009x: as_u32(dst) = (u_int32_t)(as_u8(src) ^ 0x80) << 8; goto CONV_END;
-conv_xxx1_9000: as_u32(dst) = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto CONV_END;
-conv_xxx1_0009: as_u32(dst) = (u_int32_t)(as_u8(src) ^ 0x80); goto CONV_END;
-conv_xx12_xxx1: as_u8(dst) = as_u16(src) >> 8; goto CONV_END;
-conv_xx12_xx12: as_u16(dst) = as_u16(src); goto CONV_END;
-conv_xx12_xx21: as_u16(dst) = swab16(as_u16(src)); goto CONV_END;
-conv_xx12_x120: as_u32(dst) = (u_int32_t)as_u16(src) << 8; goto CONV_END;
-conv_xx12_021x: as_u32(dst) = (u_int32_t)swab16(as_u16(src)) << 8; goto CONV_END;
-conv_xx12_1200: as_u32(dst) = (u_int32_t)as_u16(src) << 16; goto CONV_END;
-conv_xx12_0021: as_u32(dst) = (u_int32_t)swab16(as_u16(src)); goto CONV_END;
-conv_xx12_xxx9: as_u8(dst) = (as_u16(src) >> 8) ^ 0x80; goto CONV_END;
-conv_xx12_xx92: as_u16(dst) = as_u16(src) ^ 0x8000; goto CONV_END;
-conv_xx12_xx29: as_u16(dst) = swab16(as_u16(src)) ^ 0x80; goto CONV_END;
-conv_xx12_x920: as_u32(dst) = (u_int32_t)(as_u16(src) ^ 0x8000) << 8; goto CONV_END;
-conv_xx12_029x: as_u32(dst) = (u_int32_t)(swab16(as_u16(src)) ^ 0x80) << 8; goto CONV_END;
-conv_xx12_9200: as_u32(dst) = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto CONV_END;
-conv_xx12_0029: as_u32(dst) = (u_int32_t)(swab16(as_u16(src)) ^ 0x80); goto CONV_END;
-conv_xx12_xxx2: as_u8(dst) = as_u16(src) & 0xff; goto CONV_END;
-conv_xx12_x210: as_u32(dst) = (u_int32_t)swab16(as_u16(src)) << 8; goto CONV_END;
-conv_xx12_012x: as_u32(dst) = (u_int32_t)as_u16(src) << 8; goto CONV_END;
-conv_xx12_2100: as_u32(dst) = (u_int32_t)swab16(as_u16(src)) << 16; goto CONV_END;
-conv_xx12_0012: as_u32(dst) = (u_int32_t)as_u16(src); goto CONV_END;
-conv_xx12_xxxA: as_u8(dst) = (as_u16(src) ^ 0x80) & 0xff; goto CONV_END;
-conv_xx12_xxA1: as_u16(dst) = swab16(as_u16(src) ^ 0x80); goto CONV_END;
-conv_xx12_xx1A: as_u16(dst) = as_u16(src) ^ 0x80; goto CONV_END;
-conv_xx12_xA10: as_u32(dst) = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 8; goto CONV_END;
-conv_xx12_01Ax: as_u32(dst) = (u_int32_t)(as_u16(src) ^ 0x80) << 8; goto CONV_END;
-conv_xx12_A100: as_u32(dst) = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto CONV_END;
-conv_xx12_001A: as_u32(dst) = (u_int32_t)(as_u16(src) ^ 0x80); goto CONV_END;
-conv_x123_xxx1: as_u8(dst) = as_u32(src) >> 16; goto CONV_END;
-conv_x123_xx12: as_u16(dst) = as_u32(src) >> 8; goto CONV_END;
-conv_x123_xx21: as_u16(dst) = swab16(as_u32(src) >> 8); goto CONV_END;
-conv_x123_x123: as_u32(dst) = as_u32(src); goto CONV_END;
-conv_x123_321x: as_u32(dst) = swab32(as_u32(src)); goto CONV_END;
-conv_x123_1230: as_u32(dst) = as_u32(src) << 8; goto CONV_END;
-conv_x123_0321: as_u32(dst) = swab32(as_u32(src)) >> 8; goto CONV_END;
-conv_x123_xxx9: as_u8(dst) = (as_u32(src) >> 16) ^ 0x80; goto CONV_END;
-conv_x123_xx92: as_u16(dst) = (as_u32(src) >> 8) ^ 0x8000; goto CONV_END;
-conv_x123_xx29: as_u16(dst) = swab16(as_u32(src) >> 8) ^ 0x80; goto CONV_END;
-conv_x123_x923: as_u32(dst) = as_u32(src) ^ 0x800000; goto CONV_END;
-conv_x123_329x: as_u32(dst) = swab32(as_u32(src)) ^ 0x8000; goto CONV_END;
-conv_x123_9230: as_u32(dst) = (as_u32(src) ^ 0x800000) << 8; goto CONV_END;
-conv_x123_0329: as_u32(dst) = (swab32(as_u32(src)) >> 8) ^ 0x80; goto CONV_END;
-conv_123x_xxx3: as_u8(dst) = (as_u32(src) >> 8) & 0xff; goto CONV_END;
-conv_123x_xx32: as_u16(dst) = swab16(as_u32(src) >> 8); goto CONV_END;
-conv_123x_xx23: as_u16(dst) = (as_u32(src) >> 8) & 0xffff; goto CONV_END;
-conv_123x_x321: as_u32(dst) = swab32(as_u32(src)); goto CONV_END;
-conv_123x_123x: as_u32(dst) = as_u32(src); goto CONV_END;
-conv_123x_3210: as_u32(dst) = swab32(as_u32(src)) << 8; goto CONV_END;
-conv_123x_0123: as_u32(dst) = as_u32(src) >> 8; goto CONV_END;
-conv_123x_xxxB: as_u8(dst) = ((as_u32(src) >> 8) & 0xff) ^ 0x80; goto CONV_END;
-conv_123x_xxB2: as_u16(dst) = swab16((as_u32(src) >> 8) ^ 0x80); goto CONV_END;
-conv_123x_xx2B: as_u16(dst) = ((as_u32(src) >> 8) & 0xffff) ^ 0x80; goto CONV_END;
-conv_123x_xB21: as_u32(dst) = swab32(as_u32(src)) ^ 0x800000; goto CONV_END;
-conv_123x_12Bx: as_u32(dst) = as_u32(src) ^ 0x8000; goto CONV_END;
-conv_123x_B210: as_u32(dst) = swab32(as_u32(src) ^ 0x8000) << 8; goto CONV_END;
-conv_123x_012B: as_u32(dst) = (as_u32(src) >> 8) ^ 0x80; goto CONV_END;
-conv_1234_xxx1: as_u8(dst) = as_u32(src) >> 24; goto CONV_END;
-conv_1234_xx12: as_u16(dst) = as_u32(src) >> 16; goto CONV_END;
-conv_1234_xx21: as_u16(dst) = swab16(as_u32(src) >> 16); goto CONV_END;
-conv_1234_x123: as_u32(dst) = as_u32(src) >> 8; goto CONV_END;
-conv_1234_321x: as_u32(dst) = swab32(as_u32(src)) << 8; goto CONV_END;
-conv_1234_1234: as_u32(dst) = as_u32(src); goto CONV_END;
-conv_1234_4321: as_u32(dst) = swab32(as_u32(src)); goto CONV_END;
-conv_1234_xxx9: as_u8(dst) = (as_u32(src) >> 24) ^ 0x80; goto CONV_END;
-conv_1234_xx92: as_u16(dst) = (as_u32(src) >> 16) ^ 0x8000; goto CONV_END;
-conv_1234_xx29: as_u16(dst) = swab16(as_u32(src) >> 16) ^ 0x80; goto CONV_END;
-conv_1234_x923: as_u32(dst) = (as_u32(src) >> 8) ^ 0x800000; goto CONV_END;
-conv_1234_329x: as_u32(dst) = (swab32(as_u32(src)) ^ 0x80) << 8; goto CONV_END;
-conv_1234_9234: as_u32(dst) = as_u32(src) ^ 0x80000000; goto CONV_END;
-conv_1234_4329: as_u32(dst) = swab32(as_u32(src)) ^ 0x80; goto CONV_END;
-conv_1234_xxx4: as_u8(dst) = as_u32(src) & 0xff; goto CONV_END;
-conv_1234_xx43: as_u16(dst) = swab16(as_u32(src)); goto CONV_END;
-conv_1234_xx34: as_u16(dst) = as_u32(src) & 0xffff; goto CONV_END;
-conv_1234_x432: as_u32(dst) = swab32(as_u32(src)) >> 8; goto CONV_END;
-conv_1234_234x: as_u32(dst) = as_u32(src) << 8; goto CONV_END;
-conv_1234_xxxC: as_u8(dst) = (as_u32(src) & 0xff) ^ 0x80; goto CONV_END;
-conv_1234_xxC3: as_u16(dst) = swab16(as_u32(src) ^ 0x80); goto CONV_END;
-conv_1234_xx3C: as_u16(dst) = (as_u32(src) & 0xffff) ^ 0x80; goto CONV_END;
-conv_1234_xC32: as_u32(dst) = (swab32(as_u32(src)) >> 8) ^ 0x800000; goto CONV_END;
-conv_1234_23Cx: as_u32(dst) = (as_u32(src) ^ 0x80) << 8; goto CONV_END;
-conv_1234_C321: as_u32(dst) = swab32(as_u32(src) ^ 0x80); goto CONV_END;
-conv_1234_123C: as_u32(dst) = as_u32(src) ^ 0x80; goto CONV_END;
-}
-#endif
-
-#ifdef GET_S16_LABELS
-/* src_wid src_endswap unsigned */
-static void *get_s16_labels[4 * 2 * 2] = {
- &&get_s16_xxx1_xx10, /* 8h -> 16h */
- &&get_s16_xxx1_xx90, /* 8h ^> 16h */
- &&get_s16_xxx1_xx10, /* 8s -> 16h */
- &&get_s16_xxx1_xx90, /* 8s ^> 16h */
- &&get_s16_xx12_xx12, /* 16h -> 16h */
- &&get_s16_xx12_xx92, /* 16h ^> 16h */
- &&get_s16_xx12_xx21, /* 16s -> 16h */
- &&get_s16_xx12_xxA1, /* 16s ^> 16h */
- &&get_s16_x123_xx12, /* 24h -> 16h */
- &&get_s16_x123_xx92, /* 24h ^> 16h */
- &&get_s16_123x_xx32, /* 24s -> 16h */
- &&get_s16_123x_xxB2, /* 24s ^> 16h */
- &&get_s16_1234_xx12, /* 32h -> 16h */
- &&get_s16_1234_xx92, /* 32h ^> 16h */
- &&get_s16_1234_xx43, /* 32s -> 16h */
- &&get_s16_1234_xxC3, /* 32s ^> 16h */
-};
-#endif
-
-#ifdef GET_S16_END
-while(0) {
-get_s16_xxx1_xx10: sample = (u_int16_t)as_u8(src) << 8; goto GET_S16_END;
-get_s16_xxx1_xx90: sample = (u_int16_t)(as_u8(src) ^ 0x80) << 8; goto GET_S16_END;
-get_s16_xx12_xx12: sample = as_u16(src); goto GET_S16_END;
-get_s16_xx12_xx92: sample = as_u16(src) ^ 0x8000; goto GET_S16_END;
-get_s16_xx12_xx21: sample = swab16(as_u16(src)); goto GET_S16_END;
-get_s16_xx12_xxA1: sample = swab16(as_u16(src) ^ 0x80); goto GET_S16_END;
-get_s16_x123_xx12: sample = as_u32(src) >> 8; goto GET_S16_END;
-get_s16_x123_xx92: sample = (as_u32(src) >> 8) ^ 0x8000; goto GET_S16_END;
-get_s16_123x_xx32: sample = swab16(as_u32(src) >> 8); goto GET_S16_END;
-get_s16_123x_xxB2: sample = swab16((as_u32(src) >> 8) ^ 0x8000); goto GET_S16_END;
-get_s16_1234_xx12: sample = as_u32(src) >> 16; goto GET_S16_END;
-get_s16_1234_xx92: sample = (as_u32(src) >> 16) ^ 0x8000; goto GET_S16_END;
-get_s16_1234_xx43: sample = swab16(as_u32(src)); goto GET_S16_END;
-get_s16_1234_xxC3: sample = swab16(as_u32(src) ^ 0x80); goto GET_S16_END;
-}
-#endif
-
-#ifdef PUT_S16_LABELS
-/* dst_wid dst_endswap unsigned */
-static void *put_s16_labels[4 * 2 * 2] = {
- &&put_s16_xx12_xxx1, /* 16h -> 8h */
- &&put_s16_xx12_xxx9, /* 16h ^> 8h */
- &&put_s16_xx12_xxx1, /* 16h -> 8s */
- &&put_s16_xx12_xxx9, /* 16h ^> 8s */
- &&put_s16_xx12_xx12, /* 16h -> 16h */
- &&put_s16_xx12_xx92, /* 16h ^> 16h */
- &&put_s16_xx12_xx21, /* 16h -> 16s */
- &&put_s16_xx12_xx29, /* 16h ^> 16s */
- &&put_s16_xx12_x120, /* 16h -> 24h */
- &&put_s16_xx12_x920, /* 16h ^> 24h */
- &&put_s16_xx12_021x, /* 16h -> 24s */
- &&put_s16_xx12_029x, /* 16h ^> 24s */
- &&put_s16_xx12_1200, /* 16h -> 32h */
- &&put_s16_xx12_9200, /* 16h ^> 32h */
- &&put_s16_xx12_0021, /* 16h -> 32s */
- &&put_s16_xx12_0029, /* 16h ^> 32s */
-};
-#endif
-
-#ifdef PUT_S16_END
-while (0) {
-put_s16_xx12_xxx1: as_u8(dst) = sample >> 8; goto PUT_S16_END;
-put_s16_xx12_xxx9: as_u8(dst) = (sample >> 8) ^ 0x80; goto PUT_S16_END;
-put_s16_xx12_xx12: as_u16(dst) = sample; goto PUT_S16_END;
-put_s16_xx12_xx92: as_u16(dst) = sample ^ 0x8000; goto PUT_S16_END;
-put_s16_xx12_xx21: as_u16(dst) = swab16(sample); goto PUT_S16_END;
-put_s16_xx12_xx29: as_u16(dst) = swab16(sample) ^ 0x80; goto PUT_S16_END;
-put_s16_xx12_x120: as_u32(dst) = (u_int32_t)sample << 8; goto PUT_S16_END;
-put_s16_xx12_x920: as_u32(dst) = (u_int32_t)(sample ^ 0x8000) << 8; goto PUT_S16_END;
-put_s16_xx12_021x: as_u32(dst) = (u_int32_t)swab16(sample) << 8; goto PUT_S16_END;
-put_s16_xx12_029x: as_u32(dst) = (u_int32_t)(swab16(sample) ^ 0x80) << 8; goto PUT_S16_END;
-put_s16_xx12_1200: as_u32(dst) = (u_int32_t)sample << 16; goto PUT_S16_END;
-put_s16_xx12_9200: as_u32(dst) = (u_int32_t)(sample ^ 0x8000) << 16; goto PUT_S16_END;
-put_s16_xx12_0021: as_u32(dst) = (u_int32_t)swab16(sample); goto PUT_S16_END;
-put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_END;
-}
-#endif
-
-#undef as_u8
-#undef as_u16
-#undef as_u32
-#undef as_s8
-#undef as_s16
-#undef as_s32
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c
index 18d8a0f4e81..9eb267913c3 100644
--- a/sound/core/oss/rate.c
+++ b/sound/core/oss/rate.c
@@ -1,6 +1,6 @@
/*
* Rate conversion Plug-In
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
*
* This library is free software; you can redistribute it and/or modify
@@ -20,9 +20,6 @@
*/
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -340,5 +337,3 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
-
-#endif
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index 46917dc0196..de3ffdeaf7e 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -20,9 +20,6 @@
*/
#include <sound/driver.h>
-
-#ifdef CONFIG_SND_PCM_OSS_PLUGINS
-
#include <linux/slab.h>
#include <linux/time.h>
#include <sound/core.h>
@@ -108,5 +105,3 @@ int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
*r_plugin = plugin;
return 0;
}
-
-#endif
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 2743414fc8f..cf9b9493d41 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1,6 +1,6 @@
/*
* Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -30,7 +30,7 @@
#include <sound/control.h>
#include <sound/info.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-project.org>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
MODULE_LICENSE("GPL");
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 9fefcaa2c32..806f1fba544 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1,6 +1,6 @@
/*
* Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Abramo Bagnara <abramo@alsa-project.org>
*
*
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 95b1b2f0b1e..a13e38cfd2c 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -1,6 +1,6 @@
/*
* Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 0019c59a779..dd9aa51d8c8 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -1,6 +1,6 @@
/*
* PCM Interface - misc routines
- * Copyright (c) 1998 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz>
*
*
* This library is free software; you can redistribute it and/or modify
@@ -422,38 +422,6 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
EXPORT_SYMBOL(snd_pcm_format_set_silence);
-/* [width][unsigned][bigendian] */
-static int linear_formats[4][2][2] = {
- {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8},
- { SNDRV_PCM_FORMAT_U8, SNDRV_PCM_FORMAT_U8}},
- {{SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_FORMAT_S16_BE},
- {SNDRV_PCM_FORMAT_U16_LE, SNDRV_PCM_FORMAT_U16_BE}},
- {{SNDRV_PCM_FORMAT_S24_LE, SNDRV_PCM_FORMAT_S24_BE},
- {SNDRV_PCM_FORMAT_U24_LE, SNDRV_PCM_FORMAT_U24_BE}},
- {{SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_S32_BE},
- {SNDRV_PCM_FORMAT_U32_LE, SNDRV_PCM_FORMAT_U32_BE}}
-};
-
-/**
- * snd_pcm_build_linear_format - return the suitable linear format for the given condition
- * @width: the bit-width
- * @unsignd: 1 if unsigned, 0 if signed.
- * @big_endian: 1 if big-endian, 0 if little-endian
- *
- * Returns the suitable linear format for the given condition.
- */
-snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
-{
- if (width & 7)
- return SND_PCM_FORMAT_UNKNOWN;
- width = (width / 8) - 1;
- if (width < 0 || width >= 4)
- return SND_PCM_FORMAT_UNKNOWN;
- return linear_formats[width][!!unsignd][!!big_endian];
-}
-
-EXPORT_SYMBOL(snd_pcm_build_linear_format);
-
/**
* snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
* @runtime: the runtime instance
@@ -465,21 +433,16 @@ EXPORT_SYMBOL(snd_pcm_build_linear_format);
*/
int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
{
- static unsigned rates[] = {
- /* ATTENTION: these values depend on the definition in pcm.h! */
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
- 64000, 88200, 96000, 176400, 192000
- };
int i;
- for (i = 0; i < (int)ARRAY_SIZE(rates); i++) {
+ for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
if (runtime->hw.rates & (1 << i)) {
- runtime->hw.rate_min = rates[i];
+ runtime->hw.rate_min = snd_pcm_known_rates.list[i];
break;
}
}
- for (i = (int)ARRAY_SIZE(rates) - 1; i >= 0; i--) {
+ for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) {
if (runtime->hw.rates & (1 << i)) {
- runtime->hw.rate_max = rates[i];
+ runtime->hw.rate_max = snd_pcm_known_rates.list[i];
break;
}
}
@@ -487,3 +450,21 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
}
EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
+
+/**
+ * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
+ * @rate: the sample rate to convert
+ *
+ * Returns the SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or
+ * SNDRV_PCM_RATE_KNOT for an unknown rate.
+ */
+unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
+{
+ unsigned int i;
+
+ for (i = 0; i < snd_pcm_known_rates.count; i++)
+ if (snd_pcm_known_rates.list[i] == rate)
+ return 1u << i;
+ return SNDRV_PCM_RATE_KNOT;
+}
+EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 59b29cd482a..fb3dde4db04 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1,6 +1,6 @@
/*
* Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -1787,12 +1787,18 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
48000, 64000, 88200, 96000, 176400, 192000 };
+const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+};
+
static int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_pcm_hardware *hw = rule->private;
return snd_interval_list(hw_param_interval(params, rule->var),
- ARRAY_SIZE(rates), rates, hw->rates);
+ snd_pcm_known_rates.count,
+ snd_pcm_known_rates.list, hw->rates);
}
static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index d94ed16d21e..23aa9a27e21 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -1,6 +1,6 @@
/*
* Digital Audio (PCM) abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index e470c3c7d61..b8e700b94e5 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1,6 +1,6 @@
/*
* Abstract layer for MIDI v1.0 stream
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -30,14 +30,13 @@
#include <linux/mutex.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
-#include <linux/wait.h>
#include <sound/rawmidi.h>
#include <sound/info.h>
#include <sound/control.h>
#include <sound/minors.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Midlevel RawMidi code for ALSA.");
MODULE_LICENSE("GPL");
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile
index 402e2b4a34c..ceef14afee3 100644
--- a/sound/core/seq/Makefile
+++ b/sound/core/seq/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
obj-$(CONFIG_SND) += instr/
diff --git a/sound/core/seq/instr/Makefile b/sound/core/seq/instr/Makefile
index 69138f30a29..60896036481 100644
--- a/sound/core/seq/instr/Makefile
+++ b/sound/core/seq/instr/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
snd-ainstr-fm-objs := ainstr_fm.o
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
index c640e1cf854..49400262b1e 100644
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -1,6 +1,6 @@
/*
* GF1 (GUS) Patch - Instrument routines
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -26,7 +26,7 @@
#include <sound/initval.h>
#include <asm/uaccess.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture GF1 (GUS) Patch support.");
MODULE_LICENSE("GPL");
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
index 5367baee2d0..6c40eb73fa9 100644
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -1,6 +1,6 @@
/*
* IWFFFF - AMD InterWave (tm) - Instrument routines
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -26,7 +26,7 @@
#include <sound/initval.h>
#include <asm/uaccess.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture IWFFFF support.");
MODULE_LICENSE("GPL");
diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
index ac717bef9d7..78f68bee24f 100644
--- a/sound/core/seq/instr/ainstr_simple.c
+++ b/sound/core/seq/instr/ainstr_simple.c
@@ -1,6 +1,6 @@
/*
* Simple (MOD player) - Instrument routines
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -26,7 +26,7 @@
#include <sound/initval.h>
#include <asm/uaccess.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture Simple Instrument support.");
MODULE_LICENSE("GPL");
diff --git a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile
index a37ddedf710..b38406b8463 100644
--- a/sound/core/seq/oss/Makefile
+++ b/sound/core/seq/oss/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
#
snd-seq-oss-objs := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index ca5a2ed4d7c..d0d721c22ea 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -176,29 +176,29 @@ snd_seq_oss_open(struct file *file, int level)
int i, rc;
struct seq_oss_devinfo *dp;
- if ((dp = kzalloc(sizeof(*dp), GFP_KERNEL)) == NULL) {
+ dp = kzalloc(sizeof(*dp), GFP_KERNEL);
+ if (!dp) {
snd_printk(KERN_ERR "can't malloc device info\n");
return -ENOMEM;
}
debug_printk(("oss_open: dp = %p\n", dp));
+ dp->cseq = system_client;
+ dp->port = -1;
+ dp->queue = -1;
+
for (i = 0; i < SNDRV_SEQ_OSS_MAX_CLIENTS; i++) {
if (client_table[i] == NULL)
break;
}
+
+ dp->index = i;
if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) {
snd_printk(KERN_ERR "too many applications\n");
- kfree(dp);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto _error;
}
- dp->index = i;
- dp->cseq = system_client;
- dp->port = -1;
- dp->queue = -1;
- dp->readq = NULL;
- dp->writeq = NULL;
-
/* look up synth and midi devices */
snd_seq_oss_synth_setup(dp);
snd_seq_oss_midi_setup(dp);
@@ -211,14 +211,16 @@ snd_seq_oss_open(struct file *file, int level)
/* create port */
debug_printk(("create new port\n"));
- if ((rc = create_port(dp)) < 0) {
+ rc = create_port(dp);
+ if (rc < 0) {
snd_printk(KERN_ERR "can't create port\n");
goto _error;
}
/* allocate queue */
debug_printk(("allocate queue\n"));
- if ((rc = alloc_seq_queue(dp)) < 0)
+ rc = alloc_seq_queue(dp);
+ if (rc < 0)
goto _error;
/* set address */
@@ -235,7 +237,8 @@ snd_seq_oss_open(struct file *file, int level)
/* initialize read queue */
debug_printk(("initialize read queue\n"));
if (is_read_mode(dp->file_mode)) {
- if ((dp->readq = snd_seq_oss_readq_new(dp, maxqlen)) == NULL) {
+ dp->readq = snd_seq_oss_readq_new(dp, maxqlen);
+ if (!dp->readq) {
rc = -ENOMEM;
goto _error;
}
@@ -245,7 +248,7 @@ snd_seq_oss_open(struct file *file, int level)
debug_printk(("initialize write queue\n"));
if (is_write_mode(dp->file_mode)) {
dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen);
- if (dp->writeq == NULL) {
+ if (!dp->writeq) {
rc = -ENOMEM;
goto _error;
}
@@ -253,7 +256,8 @@ snd_seq_oss_open(struct file *file, int level)
/* initialize timer */
debug_printk(("initialize timer\n"));
- if ((dp->timer = snd_seq_oss_timer_new(dp)) == NULL) {
+ dp->timer = snd_seq_oss_timer_new(dp);
+ if (!dp->timer) {
snd_printk(KERN_ERR "can't alloc timer\n");
rc = -ENOMEM;
goto _error;
@@ -276,11 +280,13 @@ snd_seq_oss_open(struct file *file, int level)
return 0;
_error:
+ snd_seq_oss_writeq_delete(dp->writeq);
+ snd_seq_oss_readq_delete(dp->readq);
snd_seq_oss_synth_cleanup(dp);
snd_seq_oss_midi_cleanup(dp);
- i = dp->queue;
delete_port(dp);
- delete_seq_queue(i);
+ delete_seq_queue(dp->queue);
+ kfree(dp);
return rc;
}
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 5c8495601a3..21742485819 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -63,8 +63,10 @@ snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen)
void
snd_seq_oss_writeq_delete(struct seq_oss_writeq *q)
{
- snd_seq_oss_writeq_clear(q); /* to be sure */
- kfree(q);
+ if (q) {
+ snd_seq_oss_writeq_clear(q); /* to be sure */
+ kfree(q);
+ }
}
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 2f0d8773ac6..1878208a802 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -53,7 +53,7 @@ int seq_default_timer_device =
int seq_default_timer_subdevice = 0;
int seq_default_timer_resolution = 0; /* Hz */
-MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer.");
MODULE_LICENSE("GPL");
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index b31b5282a2c..2e3fa25ab19 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1,7 +1,7 @@
/*
* ALSA sequencer Client Manager
* Copyright (c) 1998-2001 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
* Takashi Iwai <tiwai@suse.de>
*
*
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 5efe6523a58..9a6fd56c910 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -1,6 +1,6 @@
/*
* Generic Instrument routines for ALSA sequencer
- * Copyright (c) 1999 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -26,7 +26,7 @@
#include <sound/seq_instr.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer instrument library.");
MODULE_LICENSE("GPL");
@@ -109,7 +109,7 @@ void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr)
spin_lock_irqsave(&list->lock, flags);
while (instr->use) {
spin_unlock_irqrestore(&list->lock, flags);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&list->lock, flags);
}
spin_unlock_irqrestore(&list->lock, flags);
@@ -198,8 +198,10 @@ int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list,
while (flist) {
instr = flist;
flist = instr->next;
- while (instr->use)
- schedule_timeout(1);
+ while (instr->use) {
+ schedule_timeout_uninterruptible(1);
+ barrier();
+ }
if (snd_seq_instr_free(instr, atomic)<0)
snd_printk(KERN_WARNING "instrument free problem\n");
instr = next;
@@ -555,7 +557,7 @@ static int instr_free(struct snd_seq_kinstr_ops *ops,
SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
while (instr->use) {
spin_unlock_irqrestore(&list->lock, flags);
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&list->lock, flags);
}
spin_unlock_irqrestore(&list->lock, flags);
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index a3dc5e01e9f..a72a1945bf8 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -1,7 +1,7 @@
/*
* ALSA sequencer Memory Manager
* Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
* 2000 by Takashi Iwai <tiwai@suse.de>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 1daa5b069c7..5929aaf1df9 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -1,7 +1,7 @@
/*
* Generic MIDI synth driver for ALSA sequencer
* Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -40,7 +40,7 @@ Possible options for midisynth module:
#include <sound/seq_midi_event.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Frank van de Pol <fvdpol@coil.demon.nl>, Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture sequencer MIDI synth.");
MODULE_LICENSE("GPL");
static int output_buffer_size = PAGE_SIZE;
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
index 5ff80b77690..b6820a5a73f 100644
--- a/sound/core/seq/seq_midi_event.c
+++ b/sound/core/seq/seq_midi_event.c
@@ -2,7 +2,7 @@
* MIDI byte <-> sequencer event coder
*
* Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>,
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -28,14 +28,13 @@
#include <sound/seq_midi_event.h>
#include <sound/asoundef.h>
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("MIDI byte <-> sequencer event coder");
MODULE_LICENSE("GPL");
-/* queue type */
-/* from 0 to 7 are normal commands (note off, on, etc.) */
-#define ST_NOTEOFF 0
-#define ST_NOTEON 1
+/* event type, index into status_event[] */
+/* from 0 to 6 are normal commands (note off, on, etc.) for 0x9?-0xe? */
+#define ST_INVALID 7
#define ST_SPECIAL 8
#define ST_SYSEX ST_SPECIAL
/* from 8 to 15 are events for 0xf0-0xf7 */
@@ -65,32 +64,33 @@ static struct status_event_list {
void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev);
void (*decode)(struct snd_seq_event *ev, unsigned char *buf);
} status_event[] = {
- /* 0x80 - 0xf0 */
- {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
- {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
- {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
- {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
- {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
- {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
- {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
- {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */
+ /* 0x80 - 0xef */
+ {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
+ {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
+ {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
+ {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
+ {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
+ {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
+ {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
+ /* invalid */
+ {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL},
/* 0xf0 - 0xff */
- {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
- {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
- {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
- {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
- {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */
- {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */
- {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
- {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */
- {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
- {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */
- {SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
- {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
- {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
- {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */
- {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
- {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
+ {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
+ {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
+ {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
+ {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
+ {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf4 */
+ {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf5 */
+ {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
+ {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf7 */
+ {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
+ {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf9 */
+ {SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
+ {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
+ {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
+ {SNDRV_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xfd */
+ {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
+ {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
};
static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf, int len,
@@ -129,6 +129,7 @@ int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev)
}
dev->bufsize = bufsize;
dev->lastcmd = 0xff;
+ dev->type = ST_INVALID;
spin_lock_init(&dev->lock);
*rdev = dev;
return 0;
@@ -149,7 +150,7 @@ static inline void reset_encode(struct snd_midi_event *dev)
{
dev->read = 0;
dev->qlen = 0;
- dev->type = 0;
+ dev->type = ST_INVALID;
}
void snd_midi_event_reset_encode(struct snd_midi_event *dev)
@@ -251,29 +252,31 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
- return 1;
+ return ev->type != SNDRV_SEQ_EVENT_NONE;
}
spin_lock_irqsave(&dev->lock, flags);
- if (dev->qlen > 0) {
- /* rest of command */
- dev->buf[dev->read++] = c;
- if (dev->type != ST_SYSEX)
- dev->qlen--;
- } else {
+ if ((c & 0x80) &&
+ (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
/* new command */
+ dev->buf[0] = c;
+ if ((c & 0xf0) == 0xf0) /* system messages */
+ dev->type = (c & 0x0f) + ST_SPECIAL;
+ else
+ dev->type = (c >> 4) & 0x07;
dev->read = 1;
- if (c & 0x80) {
- dev->buf[0] = c;
- if ((c & 0xf0) == 0xf0) /* special events */
- dev->type = (c & 0x0f) + ST_SPECIAL;
- else
- dev->type = (c >> 4) & 0x07;
- dev->qlen = status_event[dev->type].qlen;
- } else {
- /* process this byte as argument */
+ dev->qlen = status_event[dev->type].qlen;
+ } else {
+ if (dev->qlen > 0) {
+ /* rest of command */
dev->buf[dev->read++] = c;
+ if (dev->type != ST_SYSEX)
+ dev->qlen--;
+ } else {
+ /* running status */
+ dev->buf[1] = c;
dev->qlen = status_event[dev->type].qlen - 1;
+ dev->read = 2;
}
}
if (dev->qlen == 0) {
@@ -282,6 +285,8 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
if (status_event[dev->type].encode) /* set data values */
status_event[dev->type].encode(dev, ev);
+ if (dev->type >= ST_SPECIAL)
+ dev->type = ST_INVALID;
rc = 1;
} else if (dev->type == ST_SYSEX) {
if (c == MIDI_CMD_COMMON_SYSEX_END ||
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index eefd1cf872b..b6e23ad12ab 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -1,7 +1,7 @@
/*
* ALSA sequencer Ports
* Copyright (c) 1998 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index b4b9a132cb1..8716352afc8 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -1,7 +1,7 @@
/*
* ALSA sequencer Timer
* Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 8dc7a3b32b9..7b486c4d70d 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -1,6 +1,6 @@
/*
* Advanced Linux Sound Architecture
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -42,7 +42,7 @@ EXPORT_SYMBOL(snd_major);
static int cards_limit = 1;
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards.");
MODULE_LICENSE("GPL");
module_param(major, int, 0444);
@@ -266,6 +266,14 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
snd_minors[minor] = preg;
preg->dev = device_create(sound_class, device, MKDEV(major, minor),
"%s", name);
+ if (IS_ERR(preg->dev)) {
+ snd_minors[minor] = NULL;
+ mutex_unlock(&sound_mutex);
+ minor = PTR_ERR(preg->dev);
+ kfree(preg);
+ return minor;
+ }
+
if (preg->dev)
dev_set_drvdata(preg->dev, private_data);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 4566df41912..dc73313b733 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -1,6 +1,6 @@
/*
* Advanced Linux Sound Architecture
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/core/timer.c b/sound/core/timer.c
index f2bbacedd56..e7dc56ca4b9 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1,6 +1,6 @@
/*
* Timers abstract layer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -44,7 +44,7 @@
#endif
static int timer_limit = DEFAULT_TIMER_LIMIT;
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ALSA timer interface");
MODULE_LICENSE("GPL");
module_param(timer_limit, int, 0444);
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index 04112642611..80aeff5ccde 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-dummy-objs := dummy.o
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 4360ae9de19..e008f3c58ea 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1,6 +1,6 @@
/*
* Dummy soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -34,7 +34,7 @@
#include <sound/rawmidi.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Dummy soundcard (/dev/null)");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
@@ -510,15 +510,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_dummy, -4500, 30, 0);
.get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \
.private_value = addr }
-static int snd_dummy_capsrc_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_dummy_capsrc_info snd_ctl_boolean_stereo_info
static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/drivers/mpu401/Makefile b/sound/drivers/mpu401/Makefile
index 3fe185d19ae..918f83f34c1 100644
--- a/sound/drivers/mpu401/Makefile
+++ b/sound/drivers/mpu401/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-mpu401-objs := mpu401.o
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 67c6e974541..1fc95dadde1 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -1,6 +1,6 @@
/*
* Driver for generic MPU-401 boards (UART mode only)
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Copyright (c) 2004 by Castet Matthieu <castet.matthieu@free.fr>
*
*
@@ -30,7 +30,7 @@
#include <sound/mpu401.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("MPU-401 UART");
MODULE_LICENSE("GPL");
@@ -70,6 +70,9 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
struct snd_card *card;
int err;
+ if (!uart_enter[dev])
+ snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n");
+
*rcard = NULL;
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
@@ -83,8 +86,7 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
strcat(card->longname, "polled");
}
- err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev],
- uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY,
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0,
irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0,
NULL);
if (err < 0) {
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 85aedc348e2..3306ecd4924 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of MPU-401 in UART mode
*
* MPU-401 supports UART mode which is not capable generate transmit
@@ -39,7 +39,7 @@
#include <sound/core.h>
#include <sound/mpu401.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of MPU-401 in UART mode");
MODULE_LICENSE("GPL");
@@ -270,8 +270,7 @@ static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
{
if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
return -EIO;
- if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) &&
- snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+ if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 0))
return -EIO;
return 0;
}
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 2025db5947a..911c159bb3d 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -440,15 +440,7 @@ static void mts64_write_midi(struct mts64 *mts, u8 c,
*********************************************************************/
/* SMPTE Switch */
-static int snd_mts64_ctl_smpte_switch_info(struct snd_kcontrol *kctl,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_mts64_ctl_smpte_switch_info snd_ctl_boolean_mono_info
static int snd_mts64_ctl_smpte_switch_get(struct snd_kcontrol* kctl,
struct snd_ctl_elem_value *uctl)
diff --git a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile
index 12059785b5c..19767a6a5c5 100644
--- a/sound/drivers/opl3/Makefile
+++ b/sound/drivers/opl3/Makefile
@@ -1,13 +1,11 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-opl3-lib-objs := opl3_lib.o opl3_synth.o
-snd-opl3-synth-objs := opl3_seq.o opl3_midi.o opl3_drums.o
-ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
-snd-opl3-synth-objs += opl3_oss.o
-endif
+snd-opl3-synth-y := opl3_seq.o opl3_midi.o opl3_drums.o
+snd-opl3-synth-$(CONFIG_SND_SEQUENCER_OSS) += opl3_oss.o
#
# this function returns:
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 87fe376f38f..a2b9ce06029 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Hannu Savolainen 1993-1996,
* Rob Hooft
*
@@ -31,7 +31,7 @@
#include <linux/ioport.h>
#include <sound/minors.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
MODULE_LICENSE("GPL");
diff --git a/sound/drivers/opl4/Makefile b/sound/drivers/opl4/Makefile
index 141aacbaf31..d178b39ffa6 100644
--- a/sound/drivers/opl4/Makefile
+++ b/sound/drivers/opl4/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-opl4-lib-objs := opl4_lib.o opl4_mixer.o opl4_proc.o
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index d3e6a20edd3..65de3a755dd 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -1,6 +1,6 @@
/*
* serial.c
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Isaku Yamahata <yamahata@private.email.ne.jp>,
* George Hansper <ghansper@apana.org.au>,
* Hannu Savolainen
diff --git a/sound/drivers/vx/Makefile b/sound/drivers/vx/Makefile
index 269bd8544a5..9a168a3c156 100644
--- a/sound/drivers/vx/Makefile
+++ b/sound/drivers/vx/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-vx-lib-objs := vx_core.o vx_hwdep.o vx_pcm.o vx_mixer.o vx_cmd.o vx_uer.o
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
index f63152a6a22..b8fcd79a7e1 100644
--- a/sound/drivers/vx/vx_mixer.c
+++ b/sound/drivers/vx/vx_mixer.c
@@ -647,14 +647,7 @@ static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
return 0;
}
-static int vx_audio_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define vx_audio_sw_info snd_ctl_boolean_stereo_info
static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -865,14 +858,7 @@ static int vx_peak_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
return 0;
}
-static int vx_saturation_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define vx_saturation_info snd_ctl_boolean_stereo_info
static int vx_saturation_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/i2c/Makefile b/sound/i2c/Makefile
index 45902d48c89..37970666a45 100644
--- a/sound/i2c/Makefile
+++ b/sound/i2c/Makefile
@@ -1,15 +1,13 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-i2c-objs := i2c.o
snd-cs8427-objs := cs8427.o
snd-tea6330t-objs := tea6330t.o
-ifeq ($(subst m,y,$(CONFIG_L3)),y)
- obj-$(CONFIG_L3) += l3/
-endif
+obj-$(CONFIG_L3) += l3/
obj-$(CONFIG_SND) += other/
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index 64388cb8d6e..744366b7234 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -1,7 +1,7 @@
/*
* Routines for control of the CS8427 via i2c bus
* IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@
static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
MODULE_LICENSE("GPL");
@@ -229,6 +229,12 @@ int snd_cs8427_create(struct snd_i2c_bus *bus,
snd_i2c_lock(bus);
err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
if (err != CS8427_VER8427A) {
+ /* give second chance */
+ snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
+ "let me try again...\n", err);
+ err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
+ }
+ if (err != CS8427_VER8427A) {
snd_i2c_unlock(bus);
snd_printk(KERN_ERR "unable to find CS8427 signature "
"(expected 0x%x, read 0x%x),\n",
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index b60fb189282..1e58a963b2a 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -2,7 +2,7 @@
* Generic i2c interface for ALSA
*
* (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
- * Modified for the ALSA driver by Jaroslav Kysela <perex@suse.cz>
+ * Modified for the ALSA driver by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -28,7 +28,7 @@
#include <sound/core.h>
#include <sound/i2c.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Generic i2c interface for ALSA");
MODULE_LICENSE("GPL");
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 77a8a7c75dd..703d954238f 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
#
snd-ak4114-objs := ak4114.o
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 1efb973137a..facde46f957 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -1,7 +1,7 @@
/*
* Routines for control of the AK4114 via I2C and 4-wire serial interface
* IEC958 (S/PDIF) receiver by Asahi Kasei
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,7 @@
#include <sound/ak4114.h>
#include <sound/asoundef.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("AK4114 IEC958 (S/PDIF) receiver by Asahi Kasei");
MODULE_LICENSE("GPL");
@@ -200,15 +200,7 @@ static int snd_ak4114_in_error_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static int snd_ak4114_in_bit_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ak4114_in_bit_info snd_ctl_boolean_mono_info
static int snd_ak4114_in_bit_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index c022f29da2f..ee1585aec99 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -1,7 +1,7 @@
/*
* Routines for control of the AK4117 via 4-wire serial interface
* IEC958 (S/PDIF) receiver by Asahi Kasei
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,7 @@
#include <sound/ak4117.h>
#include <sound/asoundef.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("AK4117 IEC958 (S/PDIF) receiver by Asahi Kasei");
MODULE_LICENSE("GPL");
@@ -181,15 +181,7 @@ static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static int snd_ak4117_in_bit_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ak4117_in_bit_info snd_ctl_boolean_mono_info
static int snd_ak4117_in_bit_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index fd335159f84..de03f689fa2 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -2,7 +2,7 @@
* ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4358 / AK4381
* AD and DA converters
*
- * Copyright (c) 2000-2004 Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) 2000-2004 Jaroslav Kysela <perex@perex.cz>,
* Takashi Iwai <tiwai@suse.de>
*
* This program is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
#include <sound/tlv.h>
#include <sound/ak4xxx-adda.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx AD/DA converters");
MODULE_LICENSE("GPL");
@@ -463,15 +463,7 @@ static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
return change;
}
-static int ak4xxx_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define ak4xxx_switch_info snd_ctl_boolean_mono_info
static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/i2c/other/pt2258.c b/sound/i2c/other/pt2258.c
index e91cc3b44de..00c83d8b32b 100644
--- a/sound/i2c/other/pt2258.c
+++ b/sound/i2c/other/pt2258.c
@@ -140,15 +140,7 @@ static int pt2258_stereo_volume_put(struct snd_kcontrol *kcontrol,
return -EIO;
}
-static int pt2258_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define pt2258_switch_info snd_ctl_boolean_mono_info
static int pt2258_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 4c2fd14c105..fe31bb5cffb 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -1,7 +1,7 @@
/*
* ALSA driver for TEA5757/5759 Philips AM/FM radio tuner chips
*
- * Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -28,7 +28,7 @@
#include <sound/core.h>
#include <sound/tea575x-tuner.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
MODULE_LICENSE("GPL");
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index ae5b1e3a68c..9bab744af0e 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -1,7 +1,7 @@
/*
* Routines for control of the TEA6330T circuit via i2c bus
* Sound fader control circuit for car radios by Philips Semiconductors
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -27,7 +27,7 @@
#include <sound/control.h>
#include <sound/tea6330t.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of the TEA6330T circuit via i2c bus");
MODULE_LICENSE("GPL");
@@ -142,15 +142,7 @@ static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol,
.info = snd_tea6330t_info_master_switch, \
.get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
-static int snd_tea6330t_info_master_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_tea6330t_info_master_switch snd_ctl_boolean_stereo_info
static int snd_tea6330t_get_master_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index ea5084abe60..2639a6ab8f2 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -191,6 +191,19 @@ config SND_ES18XX
To compile this driver as a module, choose M here: the module
will be called snd-es18xx.
+config SND_SC6000
+ tristate "Gallant SC-6000, Audio Excel DSP 16"
+ depends on SND && HAS_IOPORT
+ select SND_AD1848_LIB
+ select SND_OPL3_LIB
+ select SND_MPU401_UART
+ help
+ Say Y here to include support for Gallant SC-6000 card and clones:
+ Audio Excel DSP 16 and Zoltrix AV302.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-sc6000.
+
config SND_GUS_SYNTH
tristate
@@ -414,7 +427,7 @@ config SND_SSCAPE
config SND_WAVEFRONT
tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
depends on SND
- select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+ select FW_LOADER
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_CS4231_LIB
@@ -430,8 +443,9 @@ config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
depends on SND_WAVEFRONT
default y
help
- Say Y here to include the static firmware built in the kernel
- for the Wavefront driver. If you choose N here, you need to
- install the firmware files from the alsa-firmware package.
+ Say Y here to include the static firmware for FX DSP built in
+ the kernel for the Wavefront driver. If you choose N here,
+ you need to install the firmware files from the
+ alsa-firmware package.
endmenu
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index bb317ccc170..c0ce7db2a1b 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-adlib-objs := adlib.o
@@ -10,6 +10,7 @@ snd-cmi8330-objs := cmi8330.o
snd-dt019x-objs := dt019x.o
snd-es18xx-objs := es18xx.o
snd-opl3sa2-objs := opl3sa2.o
+snd-sc6000-objs := sc6000.o
snd-sgalaxy-objs := sgalaxy.o
snd-sscape-objs := sscape.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
obj-$(CONFIG_SND_DT019X) += snd-dt019x.o
obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
+obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o
obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o
diff --git a/sound/isa/ad1816a/Makefile b/sound/isa/ad1816a/Makefile
index 90e00e842e4..487ab23860e 100644
--- a/sound/isa/ad1816a/Makefile
+++ b/sound/isa/ad1816a/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ad1816a-objs := ad1816a.o ad1816a_lib.o
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index ec9209cd517..cf18fe4617a 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -453,7 +453,6 @@ static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream)
if ((error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK)) < 0)
return error;
- snd_pcm_set_sync(substream);
runtime->hw = snd_ad1816a_playback;
snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
@@ -469,7 +468,6 @@ static int snd_ad1816a_capture_open(struct snd_pcm_substream *substream)
if ((error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE)) < 0)
return error;
- snd_pcm_set_sync(substream);
runtime->hw = snd_ad1816a_capture;
snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
diff --git a/sound/isa/ad1848/Makefile b/sound/isa/ad1848/Makefile
index 45d59998aa6..ae23331e920 100644
--- a/sound/isa/ad1848/Makefile
+++ b/sound/isa/ad1848/Makefile
@@ -1,15 +1,12 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ad1848-lib-objs := ad1848_lib.o
snd-ad1848-objs := ad1848.o
# Toplevel Module Dependency
-obj-$(CONFIG_SND_CMI8330) += snd-ad1848-lib.o
-obj-$(CONFIG_SND_SGALAXY) += snd-ad1848-lib.o
-obj-$(CONFIG_SND_AD1848) += snd-ad1848.o snd-ad1848-lib.o
-obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-ad1848-lib.o
+obj-$(CONFIG_SND_AD1848) += snd-ad1848.o
+obj-$(CONFIG_SND_AD1848_LIB) += snd-ad1848-lib.o
-obj-m := $(sort $(obj-m))
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index d09a7fa8654..a4710b5e214 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -1,8 +1,8 @@
/*
* Generic driver for AD1848/AD1847/CS4248 chips (0.1 Alpha)
* Copyright (c) by Tugrul Galatali <galatalt@stuy.edu>,
- * Jaroslav Kysela <perex@suse.cz>
- * Based on card-4232.c by Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
+ * Based on card-4232.c by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -36,7 +36,7 @@
#define DEV_NAME "ad1848"
MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
"{Analog Devices,AD1847},"
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 1bc2e3fd572..a901cd1ee69 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of AD1848/AD1847/CS4248
*
*
@@ -35,7 +35,7 @@
#include <asm/io.h>
#include <asm/dma.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of AD1848/AD1847/CS4248");
MODULE_LICENSE("GPL");
@@ -70,7 +70,7 @@ static unsigned int rates[14] = {
};
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = 14,
+ .count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
@@ -99,24 +99,32 @@ static unsigned char snd_ad1848_original_image[16] =
* Basic I/O functions
*/
-void snd_ad1848_out(struct snd_ad1848 *chip,
- unsigned char reg,
- unsigned char value)
+static void snd_ad1848_wait(struct snd_ad1848 *chip)
{
int timeout;
- for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
+ for (timeout = 250; timeout > 0; timeout--) {
+ if ((inb(AD1848P(chip, REGSEL)) & AD1848_INIT) == 0)
+ break;
udelay(100);
+ }
+}
+
+void snd_ad1848_out(struct snd_ad1848 *chip,
+ unsigned char reg,
+ unsigned char value)
+{
+ snd_ad1848_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
- snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ snd_printk(KERN_WARNING "auto calibration time out - "
+ "reg = 0x%x, value = 0x%x\n", reg, value);
#endif
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
outb(chip->image[reg] = value, AD1848P(chip, REG));
mb();
-#if 0
- printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
-#endif
+ snd_printdd("codec out - reg 0x%x = 0x%x\n",
+ chip->mce_bit | reg, value);
}
EXPORT_SYMBOL(snd_ad1848_out);
@@ -124,10 +132,7 @@ EXPORT_SYMBOL(snd_ad1848_out);
static void snd_ad1848_dout(struct snd_ad1848 *chip,
unsigned char reg, unsigned char value)
{
- int timeout;
-
- for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
- udelay(100);
+ snd_ad1848_wait(chip);
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
outb(value, AD1848P(chip, REG));
mb();
@@ -135,13 +140,11 @@ static void snd_ad1848_dout(struct snd_ad1848 *chip,
static unsigned char snd_ad1848_in(struct snd_ad1848 *chip, unsigned char reg)
{
- int timeout;
-
- for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
- udelay(100);
+ snd_ad1848_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
- snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x\n", reg);
+ snd_printk(KERN_WARNING "auto calibration time out - "
+ "reg = 0x%x\n", reg);
#endif
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
mb();
@@ -183,8 +186,7 @@ static void snd_ad1848_mce_up(struct snd_ad1848 *chip)
unsigned long flags;
int timeout;
- for (timeout = 250; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
- udelay(100);
+ snd_ad1848_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
@@ -201,9 +203,8 @@ static void snd_ad1848_mce_up(struct snd_ad1848 *chip)
static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
{
- unsigned long flags;
- int timeout;
- signed long time;
+ unsigned long flags, timeout;
+ int reg;
spin_lock_irqsave(&chip->reg_lock, flags);
for (timeout = 5; timeout > 0; timeout--)
@@ -211,61 +212,48 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
/* end of cleanup sequence */
for (timeout = 12000; timeout > 0 && (inb(AD1848P(chip, REGSEL)) & AD1848_INIT); timeout--)
udelay(100);
-#if 0
- printk("(1) timeout = %i\n", timeout);
-#endif
+
+ snd_printdd("(1) timeout = %d\n", timeout);
+
#ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
#endif
+
chip->mce_bit &= ~AD1848_MCE;
- timeout = inb(AD1848P(chip, REGSEL));
- outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
- if (timeout == 0x80)
+ reg = inb(AD1848P(chip, REGSEL));
+ outb(chip->mce_bit | (reg & 0x1f), AD1848P(chip, REGSEL));
+ if (reg == 0x80)
snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
- if ((timeout & AD1848_MCE) == 0) {
+ if ((reg & AD1848_MCE) == 0) {
spin_unlock_irqrestore(&chip->reg_lock, flags);
return;
}
- /* calibration process */
- for (timeout = 500; timeout > 0 && (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) == 0; timeout--);
- if ((snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) == 0) {
- snd_printd("mce_down - auto calibration time out (1)\n");
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- return;
- }
-#if 0
- printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
-#endif
- time = HZ / 4;
- while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
+ /*
+ * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low.
+ * It may take up to 5 sample periods (at most 907 us @ 5.5125 kHz) for
+ * the process to _start_, so it is important to wait at least that long
+ * before checking. Otherwise we might think AC has finished when it
+ * has in fact not begun. It could take 128 (no AC) or 384 (AC) cycles
+ * for ACI to drop. This gives a wait of at most 70 ms with a more
+ * typical value of 3-9 ms.
+ */
+ timeout = jiffies + msecs_to_jiffies(250);
+ do {
spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (time <= 0) {
- snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
- return;
- }
- time = schedule_timeout(time);
+ msleep(1);
spin_lock_irqsave(&chip->reg_lock, flags);
- }
-#if 0
- printk("(3) jiffies = %li\n", jiffies);
-#endif
- time = HZ / 10;
- while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) {
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- if (time <= 0) {
- snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
- return;
- }
- time = schedule_timeout(time);
- spin_lock_irqsave(&chip->reg_lock, flags);
- }
+ reg = snd_ad1848_in(chip, AD1848_TEST_INIT) &
+ AD1848_CALIB_IN_PROGRESS;
+ } while (reg && time_before(jiffies, timeout));
spin_unlock_irqrestore(&chip->reg_lock, flags);
-#if 0
- printk("(4) jiffies = %li\n", jiffies);
- snd_printk("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL)));
-#endif
+ if (reg)
+ snd_printk(KERN_ERR
+ "mce_down - auto calibration time out (2)\n");
+
+ snd_printdd("(4) jiffies = %lu\n", jiffies);
+ snd_printd("mce_down - exit = 0x%x\n", inb(AD1848P(chip, REGSEL)));
}
static unsigned int snd_ad1848_get_count(unsigned char format,
@@ -319,11 +307,11 @@ static unsigned char snd_ad1848_get_rate(unsigned int rate)
{
int i;
- for (i = 0; i < 14; i++)
+ for (i = 0; i < ARRAY_SIZE(rates); i++)
if (rate == rates[i])
return freq_bits[i];
snd_BUG();
- return freq_bits[13];
+ return freq_bits[ARRAY_SIZE(rates) - 1];
}
static int snd_ad1848_ioctl(struct snd_pcm_substream *substream,
@@ -390,11 +378,9 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
{
unsigned long flags;
- mutex_lock(&chip->open_mutex);
- if (chip->mode & AD1848_MODE_OPEN) {
- mutex_unlock(&chip->open_mutex);
+ if (chip->mode & AD1848_MODE_OPEN)
return -EAGAIN;
- }
+
snd_ad1848_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
@@ -435,7 +421,6 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = mode;
- mutex_unlock(&chip->open_mutex);
return 0;
}
@@ -444,11 +429,8 @@ static void snd_ad1848_close(struct snd_ad1848 *chip)
{
unsigned long flags;
- mutex_lock(&chip->open_mutex);
- if (!chip->mode) {
- mutex_unlock(&chip->open_mutex);
+ if (!chip->mode)
return;
- }
/* disable IRQ */
spin_lock_irqsave(&chip->reg_lock, flags);
outb(0, AD1848P(chip, STATUS)); /* clear IRQ */
@@ -474,7 +456,6 @@ static void snd_ad1848_close(struct snd_ad1848 *chip)
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = 0;
- mutex_unlock(&chip->open_mutex);
}
/*
@@ -892,7 +873,6 @@ int snd_ad1848_create(struct snd_card *card,
if (chip == NULL)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
- mutex_init(&chip->open_mutex);
chip->card = card;
chip->port = port;
chip->irq = -1;
diff --git a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile
index 2fb4f7409d7..5067ee00193 100644
--- a/sound/isa/cs423x/Makefile
+++ b/sound/isa/cs423x/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-cs4231-lib-objs := cs4231_lib.o
@@ -10,17 +10,8 @@ snd-cs4232-objs := cs4232.o
snd-cs4236-objs := cs4236.o
# Toplevel Module Dependency
-obj-$(CONFIG_SND_AZT2320) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_MIRO) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_OPL3SA2) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_CS4231) += snd-cs4231.o snd-cs4231-lib.o
-obj-$(CONFIG_SND_CS4232) += snd-cs4232.o snd-cs4231-lib.o
-obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o snd-cs4231-lib.o
-obj-$(CONFIG_SND_GUSMAX) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_INTERWAVE) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_INTERWAVE_STB) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_WAVEFRONT) += snd-cs4231-lib.o
-obj-$(CONFIG_SND_SSCAPE) += snd-cs4231-lib.o
+obj-$(CONFIG_SND_CS4231_LIB) += snd-cs4231-lib.o
+obj-$(CONFIG_SND_CS4231) += snd-cs4231.o
+obj-$(CONFIG_SND_CS4232) += snd-cs4232.o
+obj-$(CONFIG_SND_CS4236) += snd-cs4236.o snd-cs4236-lib.o
-obj-m := $(sort $(obj-m))
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index ac404113415..13db6842eaa 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -1,6 +1,6 @@
/*
* Generic driver for CS4231 chips
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Originally the CS4232/CS4232A driver, modified for use on CS4231 by
* Tugrul Galatali <galatalt@stuy.edu>
*
@@ -36,7 +36,7 @@
#define DEV_NAME "cs4231"
MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 914d77b61b0..a5eb9659b51 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of CS4231(A)/CS4232/InterWave & compatible chips
*
* Bugs:
@@ -39,7 +39,7 @@
#include <asm/dma.h>
#include <asm/irq.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
MODULE_LICENSE("GPL");
@@ -74,7 +74,7 @@ static unsigned int rates[14] = {
};
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = 14,
+ .count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
@@ -134,29 +134,31 @@ static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset)
return inb(chip->port + offset);
}
-static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
- unsigned char mask, unsigned char value)
+static void snd_cs4231_wait(struct snd_cs4231 *chip)
{
int timeout;
- unsigned char tmp;
for (timeout = 250;
timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
timeout--)
udelay(100);
+}
+
+static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
+ unsigned char mask, unsigned char value)
+{
+ unsigned char tmp = (chip->image[reg] & mask) | value;
+
+ snd_cs4231_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif
- if (chip->calibrate_mute) {
- chip->image[reg] &= mask;
- chip->image[reg] |= value;
- } else {
+ chip->image[reg] = tmp;
+ if (!chip->calibrate_mute) {
cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
- mb();
- tmp = (chip->image[reg] & mask) | value;
+ wmb();
cs4231_outb(chip, CS4231P(REG), tmp);
- chip->image[reg] = tmp;
mb();
}
}
@@ -176,12 +178,7 @@ static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned
void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
{
- int timeout;
-
- for (timeout = 250;
- timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
+ snd_cs4231_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
@@ -190,19 +187,13 @@ void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char va
cs4231_outb(chip, CS4231P(REG), value);
chip->image[reg] = value;
mb();
-#if 0
- printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
-#endif
+ snd_printdd("codec out - reg 0x%x = 0x%x\n",
+ chip->mce_bit | reg, value);
}
unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
{
- int timeout;
-
- for (timeout = 250;
- timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
+ snd_cs4231_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
@@ -304,8 +295,7 @@ void snd_cs4231_mce_up(struct snd_cs4231 *chip)
unsigned long flags;
int timeout;
- for (timeout = 250; timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--)
- udelay(100);
+ snd_cs4231_wait(chip);
#ifdef CONFIG_SND_DEBUG
if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
snd_printk("mce_up - auto calibration time out (0)\n");
@@ -323,12 +313,11 @@ void snd_cs4231_mce_up(struct snd_cs4231 *chip)
void snd_cs4231_mce_down(struct snd_cs4231 *chip)
{
unsigned long flags;
+ unsigned long end_time;
int timeout;
snd_cs4231_busy_wait(chip);
-#if 0
- printk("(1) timeout = %i\n", timeout);
-#endif
+
#ifdef CONFIG_SND_DEBUG
if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
@@ -346,42 +335,42 @@ void snd_cs4231_mce_down(struct snd_cs4231 *chip)
}
snd_cs4231_busy_wait(chip);
- /* calibration process */
+ /*
+ * Wait for (possible -- during init auto-calibration may not be set)
+ * calibration process to start. Needs upto 5 sample periods on AD1848
+ * which at the slowest possible rate of 5.5125 kHz means 907 us.
+ */
+ msleep(1);
- for (timeout = 500; timeout > 0 && (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0; timeout--)
- udelay(10);
- if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) {
- snd_printd("cs4231_mce_down - auto calibration time out (1)\n");
- return;
- }
-#if 0
- printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
-#endif
- /* in 10 ms increments, check condition, up to 250 ms */
- timeout = 25;
- while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
- if (--timeout < 0) {
- snd_printk("mce_down - auto calibration time out (2)\n");
+ snd_printdd("(1) jiffies = %lu\n", jiffies);
+
+ /* check condition up to 250 ms */
+ end_time = jiffies + msecs_to_jiffies(250);
+ while (snd_cs4231_in(chip, CS4231_TEST_INIT) &
+ CS4231_CALIB_IN_PROGRESS) {
+
+ if (time_after(jiffies, end_time)) {
+ snd_printk(KERN_ERR "mce_down - "
+ "auto calibration time out (2)\n");
return;
}
- msleep(10);
+ msleep(1);
}
-#if 0
- printk("(3) jiffies = %li\n", jiffies);
-#endif
- /* in 10 ms increments, check condition, up to 100 ms */
- timeout = 10;
+
+ snd_printdd("(2) jiffies = %lu\n", jiffies);
+
+ /* check condition up to 100 ms */
+ end_time = jiffies + msecs_to_jiffies(100);
while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
- if (--timeout < 0) {
+ if (time_after(jiffies, end_time)) {
snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
return;
}
- msleep(10);
+ msleep(1);
}
-#if 0
- printk("(4) jiffies = %li\n", jiffies);
- snd_printk("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL)));
-#endif
+
+ snd_printdd("(3) jiffies = %lu\n", jiffies);
+ snd_printd("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL)));
}
static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size)
@@ -459,11 +448,11 @@ static unsigned char snd_cs4231_get_rate(unsigned int rate)
{
int i;
- for (i = 0; i < 14; i++)
+ for (i = 0; i < ARRAY_SIZE(rates); i++)
if (rate == rates[i])
return freq_bits[i];
// snd_BUG();
- return freq_bits[13];
+ return freq_bits[ARRAY_SIZE(rates) - 1];
}
static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip,
@@ -555,6 +544,8 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT] = pdfr);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
+ if (chip->hardware == CS4231_HW_OPL3SA2)
+ udelay(100); /* this seems to help */
snd_cs4231_mce_down(chip);
}
snd_cs4231_calibrate_mute(chip, 0);
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 1a14f33b6ab..5784b43f412 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -1,6 +1,6 @@
/*
* Driver for generic CS4232/CS4235/CS4236/CS4236B/CS4237B/CS4238B/CS4239 chips
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@
#include <sound/opl3.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
#ifdef CS4232
MODULE_DESCRIPTION("Cirrus Logic CS4232");
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 7a5a6c71f5e..6bd064470d4 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of CS4235/4236B/4237B/4238B/4239 chips
*
* Note:
@@ -89,7 +89,7 @@
#include <sound/cs4231.h>
#include <sound/asoundef.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of CS4235/4236B/4237B/4238B/4239 chips");
MODULE_LICENSE("GPL");
diff --git a/sound/isa/es1688/Makefile b/sound/isa/es1688/Makefile
index 501c8bf903a..aee1e4ddb22 100644
--- a/sound/isa/es1688/Makefile
+++ b/sound/isa/es1688/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-es1688-lib-objs := es1688_lib.o
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index edc398712e8..74bbc92f2e7 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -1,6 +1,6 @@
/*
* Driver for generic ESS AudioDrive ESx688 soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,7 @@
#define DEV_NAME "es1688"
MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
"{ESS,ES1688 PnP AudioDrive,pnp:ESS0102},"
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index a2ab99f2ac3..5c26d495daa 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of ESS ES1688/688/488 chip
*
*
@@ -32,7 +32,7 @@
#include <asm/io.h>
#include <asm/dma.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("ESS ESx688 lowlevel module");
MODULE_LICENSE("GPL");
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index f7732bf90be..4a7367a8ff9 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1071,14 +1071,7 @@ static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal;
}
-static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es18xx_info_spatializer_enable snd_ctl_boolean_mono_info
static int snd_es18xx_get_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1120,14 +1113,7 @@ static int snd_es18xx_get_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ct
return 0;
}
-static int snd_es18xx_info_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es18xx_info_hw_switch snd_ctl_boolean_stereo_info
static int snd_es18xx_get_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2042,6 +2028,7 @@ static int pnpc_registered;
static struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
{ .id = "ESS1869" },
+ { .id = "ESS1879" },
{ .id = "" } /* end */
};
diff --git a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile
index bae5dbd6c8e..df3d59f25f5 100644
--- a/sound/isa/gus/Makefile
+++ b/sound/isa/gus/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-gus-lib-objs := gus_main.o \
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index 44ee5d3674a..fc905141e8a 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -1,6 +1,6 @@
/*
* Routines for GF1 DMA control
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gus_dram.c b/sound/isa/gus/gus_dram.c
index f22fe7967fc..9eaa932f6ef 100644
--- a/sound/isa/gus/gus_dram.c
+++ b/sound/isa/gus/gus_dram.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* DRAM access routines
*
*
diff --git a/sound/isa/gus/gus_instr.c b/sound/isa/gus/gus_instr.c
index d0c38e1856e..bf137ea7232 100644
--- a/sound/isa/gus/gus_instr.c
+++ b/sound/isa/gus/gus_instr.c
@@ -1,6 +1,6 @@
/*
* Routines for Gravis UltraSound soundcards - Synthesizer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
index 9b1fe292de4..3d4f899285e 100644
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* I/O routines for GF1/InterWave synthesizer chips
*
*
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
index 537d3cfe41f..cd9a6f1c99e 100644
--- a/sound/isa/gus/gus_irq.c
+++ b/sound/isa/gus/gus_irq.c
@@ -1,6 +1,6 @@
/*
* Routine for IRQ handling from GF1/InterWave chip
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -45,11 +45,13 @@ __again:
// snd_printk("IRQ: status = 0x%x\n", status);
if (status & 0x02) {
STAT_ADD(gus->gf1.interrupt_stat_midi_in);
- gus->gf1.interrupt_handler_midi_in(gus);
+ if (gus->gf1.interrupt_handler_midi_in)
+ gus->gf1.interrupt_handler_midi_in(gus);
}
if (status & 0x01) {
STAT_ADD(gus->gf1.interrupt_stat_midi_out);
- gus->gf1.interrupt_handler_midi_out(gus);
+ if (gus->gf1.interrupt_handler_midi_out)
+ gus->gf1.interrupt_handler_midi_out(gus);
}
if (status & (0x20 | 0x40)) {
unsigned int already, _current_;
@@ -85,20 +87,24 @@ __again:
}
if (status & 0x04) {
STAT_ADD(gus->gf1.interrupt_stat_timer1);
- gus->gf1.interrupt_handler_timer1(gus);
+ if (gus->gf1.interrupt_handler_timer1)
+ gus->gf1.interrupt_handler_timer1(gus);
}
if (status & 0x08) {
STAT_ADD(gus->gf1.interrupt_stat_timer2);
- gus->gf1.interrupt_handler_timer2(gus);
+ if (gus->gf1.interrupt_handler_timer2)
+ gus->gf1.interrupt_handler_timer2(gus);
}
if (status & 0x80) {
if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL) & 0x40) {
STAT_ADD(gus->gf1.interrupt_stat_dma_write);
- gus->gf1.interrupt_handler_dma_write(gus);
+ if (gus->gf1.interrupt_handler_dma_write)
+ gus->gf1.interrupt_handler_dma_write(gus);
}
if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL) & 0x40) {
STAT_ADD(gus->gf1.interrupt_stat_dma_read);
- gus->gf1.interrupt_handler_dma_read(gus);
+ if (gus->gf1.interrupt_handler_dma_read)
+ gus->gf1.interrupt_handler_dma_read(gus);
}
}
if (--loop > 0)
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 8ced5e81b9a..b14d5d6d9a3 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -1,6 +1,6 @@
/*
* Routines for Gravis UltraSound soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
#include <asm/dma.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards");
MODULE_LICENSE("GPL");
@@ -154,6 +154,14 @@ int snd_gus_create(struct snd_card *card,
gus = kzalloc(sizeof(*gus), GFP_KERNEL);
if (gus == NULL)
return -ENOMEM;
+ spin_lock_init(&gus->reg_lock);
+ spin_lock_init(&gus->voice_alloc);
+ spin_lock_init(&gus->active_voice_lock);
+ spin_lock_init(&gus->event_lock);
+ spin_lock_init(&gus->dma_lock);
+ spin_lock_init(&gus->pcm_volume_level_lock);
+ spin_lock_init(&gus->uart_cmd_lock);
+ mutex_init(&gus->dma_mutex);
gus->gf1.irq = -1;
gus->gf1.dma1 = -1;
gus->gf1.dma2 = -1;
@@ -218,14 +226,6 @@ int snd_gus_create(struct snd_card *card,
gus->gf1.pcm_channels = pcm_channels;
gus->gf1.volume_ramp = 25;
gus->gf1.smooth_pan = 1;
- spin_lock_init(&gus->reg_lock);
- spin_lock_init(&gus->voice_alloc);
- spin_lock_init(&gus->active_voice_lock);
- spin_lock_init(&gus->event_lock);
- spin_lock_init(&gus->dma_lock);
- spin_lock_init(&gus->pcm_volume_level_lock);
- spin_lock_init(&gus->uart_cmd_lock);
- mutex_init(&gus->dma_mutex);
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
snd_gus_free(gus);
return err;
@@ -398,7 +398,7 @@ static int snd_gus_check_version(struct snd_gus_card * gus)
gus->ess_flag = 1;
} else {
snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
- snd_printk(KERN_ERR " please - report to <perex@suse.cz>\n");
+ snd_printk(KERN_ERR " please - report to <perex@perex.cz>\n");
}
}
}
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 7107753b85b..bcf4656853c 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* GUS's memory allocation routines / bottom layer
*
*
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 80f0a83818b..f69a44728eb 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* GUS's memory access via proc filesystem
*
*
diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c
index acc25a29720..a96253e1665 100644
--- a/sound/isa/gus/gus_mixer.c
+++ b/sound/isa/gus/gus_mixer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of ICS 2101 chip and "mixer" in GF1 chip
*
*
@@ -36,14 +36,7 @@
.get = snd_gf1_get_single, .put = snd_gf1_put_single, \
.private_value = shift | (invert << 8) }
-static int snd_gf1_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_gf1_info_single snd_ctl_boolean_mono_info
static int snd_gf1_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index c7f95e7aa01..a7971f5ffe6 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of GF1 chip (PCM things)
*
* InterWave chips supports interleaved DMA, but this feature isn't used in
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
index b263655c411..20cfdb87f84 100644
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gus_sample.c b/sound/isa/gus/gus_sample.c
index 9e0c55ab25b..cba0829a710 100644
--- a/sound/isa/gus/gus_sample.c
+++ b/sound/isa/gus/gus_sample.c
@@ -1,6 +1,6 @@
/*
* Routines for Gravis UltraSound soundcards - Sample support
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gus_simple.c b/sound/isa/gus/gus_simple.c
index dcad6ed0198..39d121e2c8c 100644
--- a/sound/isa/gus/gus_simple.c
+++ b/sound/isa/gus/gus_simple.c
@@ -1,6 +1,6 @@
/*
* Routines for Gravis UltraSound soundcards - Simple instrument handlers
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
index 3e4d4d6edd8..2c2051782aa 100644
--- a/sound/isa/gus/gus_synth.c
+++ b/sound/isa/gus/gus_synth.c
@@ -1,6 +1,6 @@
/*
* Routines for Gravis UltraSound soundcards - Synthesizer
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,7 @@
#include <sound/gus.h>
#include <sound/seq_device.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards - Synthesizer");
MODULE_LICENSE("GPL");
diff --git a/sound/isa/gus/gus_tables.h b/sound/isa/gus/gus_tables.h
index 4adf098d326..42a4ca0d622 100644
--- a/sound/isa/gus/gus_tables.h
+++ b/sound/isa/gus/gus_tables.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gus_timer.c b/sound/isa/gus/gus_timer.c
index a43b662f17c..99eac573c41 100644
--- a/sound/isa/gus/gus_timer.c
+++ b/sound/isa/gus/gus_timer.c
@@ -1,6 +1,6 @@
/*
* Routines for Gravis UltraSound soundcards - Timers
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* GUS have similar timers as AdLib (OPL2/OPL3 chips).
*
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index 654290a8b21..e6fd9b01c49 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for the GF1 MIDI interface - like UART 6850
*
*
diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c
index dbbc0a6d765..71a67744a14 100644
--- a/sound/isa/gus/gus_volume.c
+++ b/sound/isa/gus/gus_volume.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 8f23f433d49..29e422b00b5 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -1,6 +1,6 @@
/*
* Driver for Gravis UltraSound Classic soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
#define DEV_NAME "gusclassic"
MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 0aeaa6cf6cf..fc59536c918 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -1,6 +1,6 @@
/*
* Driver for Gravis UltraSound Extreme soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@
#define DEV_NAME "gusextreme"
MODULE_DESCRIPTION(CRD_NAME);
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 708783d4351..4922f5da08f 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -1,6 +1,6 @@
/*
* Driver for Gravis UltraSound MAX soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Gravis UltraSound MAX");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound MAX}}");
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 0220cdbe1a2..2091c50b2e3 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -1,6 +1,6 @@
/*
* Driver for AMD InterWave soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
#ifndef SNDRV_STB
MODULE_DESCRIPTION("AMD InterWave");
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index e70db32991d..59af9ab7191 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -1,6 +1,6 @@
/*
* Driver for Yamaha OPL3-SA[2,3] soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -37,7 +37,7 @@
#include <asm/io.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Yamaha OPL3SA2+");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF719E-S},"
@@ -253,6 +253,7 @@ static int __devinit snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
/* 0x03 - YM715B */
/* 0x04 - YM719 - OPL-SA4? */
/* 0x05 - OPL3-SA3 - Libretto 100 */
+ /* 0x07 - unknown - Neomagic MagicWave 3D */
break;
}
str[0] = chip->version + '0';
diff --git a/sound/isa/opti9xx/Makefile b/sound/isa/opti9xx/Makefile
index 0e41bfd5a40..b4d894db257 100644
--- a/sound/isa/opti9xx/Makefile
+++ b/sound/isa/opti9xx/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-opti92x-ad1848-objs := opti92x-ad1848.o
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index cd29b30b362..d295936611f 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -242,14 +242,7 @@ static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value)
* MIXER part
*/
-static int snd_miro_info_capture(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
-
- return 0;
-}
+#define snd_miro_info_capture snd_ctl_boolean_mono_info
static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -344,14 +337,7 @@ static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
return change;
}
-static int snd_miro_info_amp(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
-
- return 0;
-}
+#define snd_miro_info_amp snd_ctl_boolean_mono_info
static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 049d479ce2b..ee1a824d8fc 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -501,6 +501,16 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
(chip->hardware == OPTi9XX_HW_82C930 ? 0x00 : 0x04),
0x34);
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x20, 0xbf);
+ /*
+ * The BTC 1817DW has QS1000 wavetable which is connected
+ * to the serial digital input of the OPTI931.
+ */
+ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(21), 0x82, 0xff);
+ /*
+ * This bit sets OPTI931 to automaticaly select FM
+ * or digital input signal.
+ */
+ snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(26), 0x01, 0x01);
break;
#endif /* OPTi93X */
@@ -1732,11 +1742,11 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
#ifdef OPTi93X
port = pnp_port_start(pdev, 0) - 4;
- fm_port = pnp_port_start(pdev, 1);
+ fm_port = pnp_port_start(pdev, 1) + 8;
#else
if (pid->driver_data != 0x0924)
port = pnp_port_start(pdev, 1);
- fm_port = pnp_port_start(pdev, 2);
+ fm_port = pnp_port_start(pdev, 2) + 8;
#endif /* OPTi93X */
irq = pnp_irq(pdev, 0);
dma1 = pnp_dma(pdev, 0);
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index 556e6692802..c9d1c986d70 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-sb-common-objs := sb_common.o sb_mixer.o
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 658179e8614..4eea84cfd4f 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk>
* Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
*
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c
index 3d72742b342..0c7905c85b7 100644
--- a/sound/isa/sb/emu8000_synth.c
+++ b/sound/isa/sb/emu8000_synth.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk>
* Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
*
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index c4ba24bfd27..e7f9edd9262 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -1,6 +1,6 @@
/*
* Driver for SoundBlaster 16/AWE32/AWE64 soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -44,7 +44,7 @@
#define PFX "sb16: "
#endif
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_LICENSE("GPL");
#ifndef SNDRV_SBAWE
MODULE_DESCRIPTION("Sound Blaster 16");
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index b279f2308ae..3682059787a 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -979,14 +979,7 @@ static int snd_sb_csp_restart(struct snd_sb_csp * p)
* QSound mixer control for PCM
*/
-static int snd_sb_qsound_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_sb_qsound_switch_info snd_ctl_boolean_mono_info
static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index 5d4d3aafe2d..c06754f7ee5 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of 16-bit SoundBlaster cards and clones
* Note: This is very ugly hardware which uses one 8-bit DMA channel and
* second 16-bit DMA channel. Unfortunately 8-bit DMA channel can't
@@ -45,7 +45,7 @@
#include <sound/control.h>
#include <sound/info.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of 16-bit SoundBlaster cards and clones");
MODULE_LICENSE("GPL");
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index a1b3786b391..f933aef7d8a 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -1,6 +1,6 @@
/*
* Driver for SoundBlaster 1.0/2.0/Pro soundcards and compatible
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -31,7 +31,7 @@
#include <sound/opl3.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Sound Blaster 1.0/2.0/Pro");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB 1.0/SB 2.0/SB Pro}}");
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index aea9e5ec7b3..bee894b3f5c 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Uros Bizjak <uros@kss-loka.si>
*
* Routines for control of 8-bit SoundBlaster cards and clones
@@ -38,7 +38,7 @@
#include <sound/core.h>
#include <sound/sb.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Uros Bizjak <uros@kss-loka.si>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Uros Bizjak <uros@kss-loka.si>");
MODULE_DESCRIPTION("Routines for control of 8-bit SoundBlaster cards and clones");
MODULE_LICENSE("GPL");
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index 0b67edd7ac6..e56e5633411 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of SoundBlaster cards - MIDI interface
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index efa9d5c2558..176193c0510 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Uros Bizjak <uros@kss-loka.si>
*
* Lowlevel routines for control of Sound Blaster cards
@@ -33,7 +33,7 @@
#include <asm/io.h>
#include <asm/dma.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("ALSA lowlevel driver for Sound Blaster cards");
MODULE_LICENSE("GPL");
@@ -234,7 +234,9 @@ int snd_sbdsp_create(struct snd_card *card,
chip->dma16 = -1;
chip->port = port;
- if (request_irq(irq, irq_handler, hardware == SB_HW_ALS4000 ?
+ if (request_irq(irq, irq_handler,
+ (hardware == SB_HW_ALS4000 ||
+ hardware == SB_HW_CS5530) ?
IRQF_SHARED : IRQF_DISABLED,
"SoundBlaster", (void *) chip)) {
snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 3d4befcff28..03241cd5aae 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for Sound Blaster mixer control
*
*
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
new file mode 100644
index 00000000000..94daf839999
--- /dev/null
+++ b/sound/isa/sc6000.c
@@ -0,0 +1,656 @@
+/*
+ * Driver for Gallant SC-6000 soundcard. This card is also known as
+ * Audio Excel DSP 16 or Zoltrix AV302.
+ * These cards use CompuMedia ASC-9308 chip + AD1848 codec.
+ *
+ * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
+ *
+ * I don't have documentation for this card. I used the driver
+ * for OSS/Free included in the kernel source as reference.
+ *
+ * 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 <sound/driver.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/isa.h>
+#include <linux/io.h>
+#include <asm/dma.h>
+#include <sound/core.h>
+#include <sound/ad1848.h>
+#include <sound/opl3.h>
+#include <sound/mpu401.h>
+#include <sound/control.h>
+#define SNDRV_LEGACY_FIND_FREE_IRQ
+#define SNDRV_LEGACY_FIND_FREE_DMA
+#include <sound/initval.h>
+
+MODULE_AUTHOR("Krzysztof Helt");
+MODULE_DESCRIPTION("Gallant SC-6000");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Gallant, SC-6000},"
+ "{AudioExcel, Audio Excel DSP 16},"
+ "{Zoltrix, AV302}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220, 0x240 */
+static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 11 */
+static long mss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530, 0xe80 */
+static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
+ /* 0x300, 0x310, 0x320, 0x330 */
+static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 0 */
+static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0, 1, 3 */
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for sc-6000 based soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for sc-6000 based soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable sc-6000 based soundcard.");
+module_param_array(port, long, NULL, 0444);
+MODULE_PARM_DESC(port, "Port # for sc-6000 driver.");
+module_param_array(mss_port, long, NULL, 0444);
+MODULE_PARM_DESC(mss_port, "MSS Port # for sc-6000 driver.");
+module_param_array(mpu_port, long, NULL, 0444);
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for sc-6000 driver.");
+module_param_array(irq, int, NULL, 0444);
+MODULE_PARM_DESC(irq, "IRQ # for sc-6000 driver.");
+module_param_array(mpu_irq, int, NULL, 0444);
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver.");
+module_param_array(dma, int, NULL, 0444);
+MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver.");
+
+/*
+ * Commands of SC6000's DSP (SBPRO+special).
+ * Some of them are COMMAND_xx, in the future they may change.
+ */
+#define WRITE_MDIRQ_CFG 0x50 /* Set M&I&DRQ mask (the real config) */
+#define COMMAND_52 0x52 /* */
+#define READ_HARD_CFG 0x58 /* Read Hardware Config (I/O base etc) */
+#define COMMAND_5C 0x5c /* */
+#define COMMAND_60 0x60 /* */
+#define COMMAND_66 0x66 /* */
+#define COMMAND_6C 0x6c /* */
+#define COMMAND_6E 0x6e /* */
+#define COMMAND_88 0x88 /* Unknown command */
+#define DSP_INIT_MSS 0x8c /* Enable Microsoft Sound System mode */
+#define COMMAND_C5 0xc5 /* */
+#define GET_DSP_VERSION 0xe1 /* Get DSP Version */
+#define GET_DSP_COPYRIGHT 0xe3 /* Get DSP Copyright */
+
+/*
+ * Offsets of SC6000 DSP I/O ports. The offset is added to base I/O port
+ * to have the actual I/O port.
+ * Register permissions are:
+ * (wo) == Write Only
+ * (ro) == Read Only
+ * (w-) == Write
+ * (r-) == Read
+ */
+#define DSP_RESET 0x06 /* offset of DSP RESET (wo) */
+#define DSP_READ 0x0a /* offset of DSP READ (ro) */
+#define DSP_WRITE 0x0c /* offset of DSP WRITE (w-) */
+#define DSP_COMMAND 0x0c /* offset of DSP COMMAND (w-) */
+#define DSP_STATUS 0x0c /* offset of DSP STATUS (r-) */
+#define DSP_DATAVAIL 0x0e /* offset of DSP DATA AVAILABLE (ro) */
+
+#define PFX "sc6000: "
+#define DRV_NAME "SC-6000"
+
+/* hardware dependent functions */
+
+/*
+ * sc6000_irq_to_softcfg - Decode irq number into cfg code.
+ */
+static __devinit unsigned char sc6000_irq_to_softcfg(int irq)
+{
+ unsigned char val = 0;
+
+ switch (irq) {
+ case 5:
+ val = 0x28;
+ break;
+ case 7:
+ val = 0x8;
+ break;
+ case 9:
+ val = 0x10;
+ break;
+ case 10:
+ val = 0x18;
+ break;
+ case 11:
+ val = 0x20;
+ break;
+ default:
+ break;
+ }
+ return val;
+}
+
+/*
+ * sc6000_dma_to_softcfg - Decode dma number into cfg code.
+ */
+static __devinit unsigned char sc6000_dma_to_softcfg(int dma)
+{
+ unsigned char val = 0;
+
+ switch (dma) {
+ case 0:
+ val = 1;
+ break;
+ case 1:
+ val = 2;
+ break;
+ case 3:
+ val = 3;
+ break;
+ default:
+ break;
+ }
+ return val;
+}
+
+/*
+ * sc6000_mpu_irq_to_softcfg - Decode MPU-401 irq number into cfg code.
+ */
+static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq)
+{
+ unsigned char val = 0;
+
+ switch (mpu_irq) {
+ case 5:
+ val = 4;
+ break;
+ case 7:
+ val = 0x44;
+ break;
+ case 9:
+ val = 0x84;
+ break;
+ case 10:
+ val = 0xc4;
+ break;
+ default:
+ break;
+ }
+ return val;
+}
+
+static __devinit int sc6000_wait_data(char __iomem *vport)
+{
+ int loop = 1000;
+ unsigned char val = 0;
+
+ do {
+ val = ioread8(vport + DSP_DATAVAIL);
+ if (val & 0x80)
+ return 0;
+ cpu_relax();
+ } while (loop--);
+
+ return -EAGAIN;
+}
+
+static __devinit int sc6000_read(char __iomem *vport)
+{
+ if (sc6000_wait_data(vport))
+ return -EBUSY;
+
+ return ioread8(vport + DSP_READ);
+
+}
+
+static __devinit int sc6000_write(char __iomem *vport, int cmd)
+{
+ unsigned char val;
+ int loop = 500000;
+
+ do {
+ val = ioread8(vport + DSP_STATUS);
+ /*
+ * DSP ready to receive data if bit 7 of val == 0
+ */
+ if (!(val & 0x80)) {
+ iowrite8(cmd, vport + DSP_COMMAND);
+ return 0;
+ }
+ cpu_relax();
+ } while (loop--);
+
+ snd_printk(KERN_ERR "DSP Command (0x%x) timeout.\n", cmd);
+
+ return -EIO;
+}
+
+static int __devinit sc6000_dsp_get_answer(char __iomem *vport, int command,
+ char *data, int data_len)
+{
+ int len = 0;
+
+ if (sc6000_write(vport, command)) {
+ snd_printk(KERN_ERR "CMD 0x%x: failed!\n", command);
+ return -EIO;
+ }
+
+ do {
+ int val = sc6000_read(vport);
+
+ if (val < 0)
+ break;
+
+ data[len++] = val;
+
+ } while (len < data_len);
+
+ /*
+ * If no more data available, return to the caller, no error if len>0.
+ * We have no other way to know when the string is finished.
+ */
+ return len ? len : -EIO;
+}
+
+static int __devinit sc6000_dsp_reset(char __iomem *vport)
+{
+ iowrite8(1, vport + DSP_RESET);
+ udelay(10);
+ iowrite8(0, vport + DSP_RESET);
+ udelay(20);
+ if (sc6000_read(vport) == 0xaa)
+ return 0;
+ return -ENODEV;
+}
+
+/* detection and initialization */
+static int __devinit sc6000_cfg_write(char __iomem *vport,
+ unsigned char softcfg)
+{
+
+ if (sc6000_write(vport, WRITE_MDIRQ_CFG)) {
+ snd_printk(KERN_ERR "CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
+ return -EIO;
+ }
+ if (sc6000_write(vport, softcfg)) {
+ snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int __devinit sc6000_setup_board(char __iomem *vport, int config)
+{
+ int loop = 10;
+
+ do {
+ if (sc6000_write(vport, COMMAND_88)) {
+ snd_printk(KERN_ERR "CMD 0x%x: failed!\n",
+ COMMAND_88);
+ return -EIO;
+ }
+ } while ((sc6000_wait_data(vport) < 0) && loop--);
+
+ if (sc6000_read(vport) < 0) {
+ snd_printk(KERN_ERR "sc6000_read after CMD 0x%x: failed\n",
+ COMMAND_88);
+ return -EIO;
+ }
+
+ if (sc6000_cfg_write(vport, config))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int __devinit sc6000_init_mss(char __iomem *vport, int config,
+ char __iomem *vmss_port, int mss_config)
+{
+ if (sc6000_write(vport, DSP_INIT_MSS)) {
+ snd_printk(KERN_ERR "sc6000_init_mss [0x%x]: failed!\n",
+ DSP_INIT_MSS);
+ return -EIO;
+ }
+
+ msleep(10);
+
+ if (sc6000_cfg_write(vport, config))
+ return -EIO;
+
+ iowrite8(mss_config, vmss_port);
+
+ return 0;
+}
+
+static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma,
+ char __iomem *vmss_port, int mpu_irq)
+{
+ char answer[15];
+ char version[2];
+ int mss_config = sc6000_irq_to_softcfg(irq) |
+ sc6000_dma_to_softcfg(dma);
+ int config = mss_config |
+ sc6000_mpu_irq_to_softcfg(mpu_irq);
+ int err;
+
+ err = sc6000_dsp_reset(vport);
+ if (err < 0) {
+ snd_printk(KERN_ERR "sc6000_dsp_reset: failed!\n");
+ return err;
+ }
+
+ memset(answer, 0, sizeof(answer));
+ err = sc6000_dsp_get_answer(vport, GET_DSP_COPYRIGHT, answer, 15);
+ if (err <= 0) {
+ snd_printk(KERN_ERR "sc6000_dsp_copyright: failed!\n");
+ return -ENODEV;
+ }
+ /*
+ * My SC-6000 card return "SC-6000" in DSPCopyright, so
+ * if we have something different, we have to be warned.
+ * Mine returns "SC-6000A " - KH
+ */
+ if (strncmp("SC-6000", answer, 7))
+ snd_printk(KERN_WARNING "Warning: non SC-6000 audio card!\n");
+
+ if (sc6000_dsp_get_answer(vport, GET_DSP_VERSION, version, 2) < 2) {
+ snd_printk(KERN_ERR "sc6000_dsp_version: failed!\n");
+ return -ENODEV;
+ }
+ printk(KERN_INFO PFX "Detected model: %s, DSP version %d.%d\n",
+ answer, version[0], version[1]);
+
+ /*
+ * 0x0A == (IRQ 7, DMA 1, MIRQ 0)
+ */
+ err = sc6000_cfg_write(vport, 0x0a);
+ if (err < 0) {
+ snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n");
+ return -EFAULT;
+ }
+
+ err = sc6000_setup_board(vport, config);
+ if (err < 0) {
+ snd_printk(KERN_ERR "sc6000_setup_board: failed!\n");
+ return -ENODEV;
+ }
+
+ err = sc6000_init_mss(vport, config, vmss_port, mss_config);
+ if (err < 0) {
+ snd_printk(KERN_ERR "Can not initialize"
+ "Microsoft Sound System mode.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int __devinit snd_sc6000_mixer(struct snd_ad1848 *chip)
+{
+ struct snd_card *card = chip->card;
+ struct snd_ctl_elem_id id1, id2;
+ int err;
+
+ memset(&id1, 0, sizeof(id1));
+ memset(&id2, 0, sizeof(id2));
+ id1.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ /* reassign AUX0 to FM */
+ strcpy(id1.name, "Aux Playback Switch");
+ strcpy(id2.name, "FM Playback Switch");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
+ return err;
+ strcpy(id1.name, "Aux Playback Volume");
+ strcpy(id2.name, "FM Playback Volume");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
+ return err;
+ /* reassign AUX1 to CD */
+ strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
+ strcpy(id2.name, "CD Playback Switch");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
+ return err;
+ strcpy(id1.name, "Aux Playback Volume");
+ strcpy(id2.name, "CD Playback Volume");
+ err = snd_ctl_rename_id(card, &id1, &id2);
+ if (err < 0)
+ return err;
+ return 0;
+}
+
+static int __devinit snd_sc6000_match(struct device *devptr, unsigned int dev)
+{
+ if (!enable[dev])
+ return 0;
+ if (port[dev] == SNDRV_AUTO_PORT) {
+ printk(KERN_ERR PFX "specify IO port\n");
+ return 0;
+ }
+ if (mss_port[dev] == SNDRV_AUTO_PORT) {
+ printk(KERN_ERR PFX "specify MSS port\n");
+ return 0;
+ }
+ if (port[dev] != 0x220 && port[dev] != 0x240) {
+ printk(KERN_ERR PFX "Port must be 0x220 or 0x240\n");
+ return 0;
+ }
+ if (mss_port[dev] != 0x530 && mss_port[dev] != 0xe80) {
+ printk(KERN_ERR PFX "MSS port must be 0x530 or 0xe80\n");
+ return 0;
+ }
+ if (irq[dev] != SNDRV_AUTO_IRQ && !sc6000_irq_to_softcfg(irq[dev])) {
+ printk(KERN_ERR PFX "invalid IRQ %d\n", irq[dev]);
+ return 0;
+ }
+ if (dma[dev] != SNDRV_AUTO_DMA && !sc6000_dma_to_softcfg(dma[dev])) {
+ printk(KERN_ERR PFX "invalid DMA %d\n", dma[dev]);
+ return 0;
+ }
+ if (mpu_port[dev] != SNDRV_AUTO_PORT &&
+ (mpu_port[dev] & ~0x30L) != 0x300) {
+ printk(KERN_ERR PFX "invalid MPU-401 port %lx\n",
+ mpu_port[dev]);
+ return 0;
+ }
+ if (mpu_port[dev] != SNDRV_AUTO_PORT &&
+ mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] != 0 &&
+ !sc6000_mpu_irq_to_softcfg(mpu_irq[dev])) {
+ printk(KERN_ERR PFX "invalid MPU-401 IRQ %d\n", mpu_irq[dev]);
+ return 0;
+ }
+ return 1;
+}
+
+static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
+{
+ static int possible_irqs[] = { 5, 7, 9, 10, 11, -1 };
+ static int possible_dmas[] = { 1, 3, 0, -1 };
+ int err;
+ int xirq = irq[dev];
+ int xdma = dma[dev];
+ struct snd_card *card;
+ struct snd_ad1848 *chip;
+ struct snd_opl3 *opl3;
+ char __iomem *vport;
+ char __iomem *vmss_port;
+
+
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ if (!card)
+ return -ENOMEM;
+
+ if (xirq == SNDRV_AUTO_IRQ) {
+ xirq = snd_legacy_find_free_irq(possible_irqs);
+ if (xirq < 0) {
+ snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+ err = -EBUSY;
+ goto err_exit;
+ }
+ }
+
+ if (xdma == SNDRV_AUTO_DMA) {
+ xdma = snd_legacy_find_free_dma(possible_dmas);
+ if (xdma < 0) {
+ snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
+ err = -EBUSY;
+ goto err_exit;
+ }
+ }
+
+ if (!request_region(port[dev], 0x10, DRV_NAME)) {
+ snd_printk(KERN_ERR PFX
+ "I/O port region is already in use.\n");
+ err = -EBUSY;
+ goto err_exit;
+ }
+ vport = devm_ioport_map(devptr, port[dev], 0x10);
+ if (!vport) {
+ snd_printk(KERN_ERR PFX
+ "I/O port cannot be iomaped.\n");
+ err = -EBUSY;
+ goto err_unmap1;
+ }
+
+ /* to make it marked as used */
+ if (!request_region(mss_port[dev], 4, DRV_NAME)) {
+ snd_printk(KERN_ERR PFX
+ "SC-6000 port I/O port region is already in use.\n");
+ err = -EBUSY;
+ goto err_unmap1;
+ }
+ vmss_port = devm_ioport_map(devptr, mss_port[dev], 4);
+ if (!vport) {
+ snd_printk(KERN_ERR PFX
+ "MSS port I/O cannot be iomaped.\n");
+ err = -EBUSY;
+ goto err_unmap2;
+ }
+
+ snd_printd("Initializing BASE[0x%lx] IRQ[%d] DMA[%d] MIRQ[%d]\n",
+ port[dev], xirq, xdma,
+ mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]);
+
+ err = sc6000_init_board(vport, xirq, xdma, vmss_port, mpu_irq[dev]);
+ if (err < 0)
+ goto err_unmap2;
+
+ err = snd_ad1848_create(card, mss_port[dev] + 4, xirq, xdma,
+ AD1848_HW_DETECT, &chip);
+ if (err < 0)
+ goto err_unmap2;
+ card->private_data = chip;
+
+ err = snd_ad1848_pcm(chip, 0, NULL);
+ if (err < 0) {
+ snd_printk(KERN_ERR PFX
+ "error creating new ad1848 PCM device\n");
+ goto err_unmap2;
+ }
+ err = snd_ad1848_mixer(chip);
+ if (err < 0) {
+ snd_printk(KERN_ERR PFX "error creating new ad1848 mixer\n");
+ goto err_unmap2;
+ }
+ err = snd_sc6000_mixer(chip);
+ if (err < 0) {
+ snd_printk(KERN_ERR PFX "the mixer rewrite failed\n");
+ goto err_unmap2;
+ }
+ if (snd_opl3_create(card,
+ 0x388, 0x388 + 2,
+ OPL3_HW_AUTO, 0, &opl3) < 0) {
+ snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n",
+ 0x388, 0x388 + 2);
+ } else {
+ err = snd_opl3_timer_new(opl3, 0, 1);
+ if (err < 0)
+ goto err_unmap2;
+
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0)
+ goto err_unmap2;
+ }
+
+ if (mpu_port[dev] != SNDRV_AUTO_PORT) {
+ if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
+ mpu_irq[dev] = -1;
+ if (snd_mpu401_uart_new(card, 0,
+ MPU401_HW_MPU401,
+ mpu_port[dev], 0,
+ mpu_irq[dev], IRQF_DISABLED,
+ NULL) < 0)
+ snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n",
+ mpu_port[dev]);
+ }
+
+ strcpy(card->driver, DRV_NAME);
+ strcpy(card->shortname, "SC-6000");
+ sprintf(card->longname, "Gallant SC-6000 at 0x%lx, irq %d, dma %d",
+ mss_port[dev], xirq, xdma);
+
+ snd_card_set_dev(card, devptr);
+
+ err = snd_card_register(card);
+ if (err < 0)
+ goto err_unmap2;
+
+ dev_set_drvdata(devptr, card);
+ return 0;
+
+err_unmap2:
+ release_region(mss_port[dev], 4);
+err_unmap1:
+ release_region(port[dev], 0x10);
+err_exit:
+ snd_card_free(card);
+ return err;
+}
+
+static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev)
+{
+ release_region(port[dev], 0x10);
+ release_region(mss_port[dev], 4);
+
+ snd_card_free(dev_get_drvdata(devptr));
+ dev_set_drvdata(devptr, NULL);
+ return 0;
+}
+
+static struct isa_driver snd_sc6000_driver = {
+ .match = snd_sc6000_match,
+ .probe = snd_sc6000_probe,
+ .remove = __devexit_p(snd_sc6000_remove),
+ /* FIXME: suspend/resume */
+ .driver = {
+ .name = DRV_NAME,
+ },
+};
+
+
+static int __init alsa_card_sc6000_init(void)
+{
+ return isa_register_driver(&snd_sc6000_driver, SNDRV_CARDS);
+}
+
+static void __exit alsa_card_sc6000_exit(void)
+{
+ isa_unregister_driver(&snd_sc6000_driver);
+}
+
+module_init(alsa_card_sc6000_init)
+module_exit(alsa_card_sc6000_exit)
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index cbad2a51cba..1cb921d6137 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -45,10 +45,12 @@ MODULE_LICENSE("GPL");
static int index[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IDX;
static char* id[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_STR;
-static long port[SNDRV_CARDS] __devinitdata = { [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_PORT };
+static long port[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PORT;
+static long wss_port[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_PORT;
static int irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ;
static int mpu_irq[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_IRQ;
static int dma[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA;
+static int dma2[SNDRV_CARDS] __devinitdata = SNDRV_DEFAULT_DMA;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");
@@ -59,6 +61,9 @@ MODULE_PARM_DESC(id, "Description for SoundScape card");
module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for SoundScape driver.");
+module_param_array(wss_port, long, NULL, 0444);
+MODULE_PARM_DESC(wss_port, "WSS Port # for SoundScape driver.");
+
module_param_array(irq, int, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver.");
@@ -68,12 +73,16 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
module_param_array(dma, int, NULL, 0444);
MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
+module_param_array(dma2, int, NULL, 0444);
+MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver.");
+
#ifdef CONFIG_PNP
static int isa_registered;
static int pnp_registered;
static struct pnp_card_device_id sscape_pnpids[] = {
- { .id = "ENS3081", .devs = { { "ENS0000" } } },
+ { .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */
+ { .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */
{ .id = "" } /* end */
};
@@ -124,12 +133,21 @@ enum GA_REG {
#define AD1845_FREQ_SEL_MSB 0x16
#define AD1845_FREQ_SEL_LSB 0x17
+enum card_type {
+ SSCAPE,
+ SSCAPE_PNP,
+ SSCAPE_VIVO,
+};
+
struct soundscape {
spinlock_t lock;
unsigned io_base;
+ unsigned wss_base;
int codec_type;
int ic_type;
+ enum card_type type;
struct resource *io_res;
+ struct resource *wss_res;
struct snd_cs4231 *chip;
struct snd_mpu401 *mpu;
struct snd_hwdep *hw;
@@ -340,8 +358,9 @@ static inline void activate_ad1845_unsafe(unsigned io_base)
*/
static void soundscape_free(struct snd_card *c)
{
- register struct soundscape *sscape = get_card_soundscape(c);
+ struct soundscape *sscape = get_card_soundscape(c);
release_and_free_resource(sscape->io_res);
+ release_and_free_resource(sscape->wss_res);
free_dma(sscape->chip->dma1);
}
@@ -382,7 +401,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long flags;
unsigned char x;
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&s->lock, flags);
x = inb(HOST_DATA_IO(s->io_base));
@@ -409,7 +428,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long flags;
unsigned char x;
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
spin_lock_irqsave(&s->lock, flags);
x = inb(HOST_DATA_IO(s->io_base));
@@ -522,7 +541,7 @@ static int upload_dma_data(struct soundscape *s,
ret = -EAGAIN;
}
- _release_dma:
+_release_dma:
/*
* NOTE!!! We are NOT holding any spinlocks at this point !!!
*/
@@ -802,6 +821,7 @@ static int __devinit detect_sscape(struct soundscape *s)
unsigned long flags;
unsigned d;
int retval = 0;
+ int codec = s->wss_base;
spin_lock_irqsave(&s->lock, flags);
@@ -833,9 +853,27 @@ static int __devinit detect_sscape(struct soundscape *s)
outb(0xfe, ODIE_ADDR_IO(s->io_base));
if ((inb(ODIE_ADDR_IO(s->io_base)) & 0x9f) != 0x0e)
goto _done;
- if ((inb(ODIE_DATA_IO(s->io_base)) & 0x9f) != 0x0e)
+
+ outb(0xfe, ODIE_ADDR_IO(s->io_base));
+ d = inb(ODIE_DATA_IO(s->io_base));
+ if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e)
goto _done;
+ d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f;
+ sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0);
+
+ if (s->type == SSCAPE_VIVO)
+ codec += 4;
+ /* wait for WSS codec */
+ for (d = 0; d < 500; d++) {
+ if ((inb(codec) & 0x80) == 0)
+ break;
+ spin_unlock_irqrestore(&s->lock, flags);
+ msleep(1);
+ spin_lock_irqsave(&s->lock, flags);
+ }
+ snd_printd(KERN_INFO "init delay = %d ms\n", d);
+
/*
* SoundScape successfully detected!
*/
@@ -995,21 +1033,23 @@ static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_pa
* try to support at least some of the extra bits by overriding
* some of the CS4231 callback.
*/
-static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq, int dma1)
+static int __devinit create_ad1845(struct snd_card *card, unsigned port,
+ int irq, int dma1, int dma2)
{
register struct soundscape *sscape = get_card_soundscape(card);
struct snd_cs4231 *chip;
int err;
-#define CS4231_SHARE_HARDWARE (CS4231_HWSHARE_DMA1 | CS4231_HWSHARE_DMA2)
- /*
- * The AD1845 PCM device is only half-duplex, and so
- * we only give it one DMA channel ...
- */
- if ((err = snd_cs4231_create(card,
- port, -1, irq, dma1, dma1,
- CS4231_HW_DETECT,
- CS4231_HWSHARE_DMA1, &chip)) == 0) {
+ if (sscape->type == SSCAPE_VIVO)
+ port += 4;
+
+ if (dma1 == dma2)
+ dma2 = -1;
+
+ err = snd_cs4231_create(card,
+ port, -1, irq, dma1, dma2,
+ CS4231_HW_DETECT, CS4231_HWSHARE_DMA1, &chip);
+ if (!err) {
unsigned long flags;
struct snd_pcm *pcm;
@@ -1031,49 +1071,72 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq
snd_cs4231_mce_down(chip);
*/
- /*
- * The input clock frequency on the SoundScape must
- * be 14.31818 MHz, because we must set this register
- * to get the playback to sound correct ...
- */
- snd_cs4231_mce_up(chip);
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
- snd_cs4231_mce_down(chip);
+ if (sscape->type != SSCAPE_VIVO) {
+ int val;
+ /*
+ * The input clock frequency on the SoundScape must
+ * be 14.31818 MHz, because we must set this register
+ * to get the playback to sound correct ...
+ */
+ snd_cs4231_mce_up(chip);
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ snd_cs4231_out(chip, AD1845_CRYS_CLOCK_SEL, 0x20);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+ snd_cs4231_mce_down(chip);
- /*
- * More custom configuration:
- * a) select "mode 2", and provide a current drive of 8 mA
- * b) enable frequency selection (for capture/playback)
- */
- spin_lock_irqsave(&chip->reg_lock, flags);
- snd_cs4231_out(chip, CS4231_MISC_INFO, (CS4231_MODE2 | 0x10));
- snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL, snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL) | AD1845_FREQ_SEL_ENABLE);
- spin_unlock_irqrestore(&chip->reg_lock, flags);
+ /*
+ * More custom configuration:
+ * a) select "mode 2" and provide a current drive of 8mA
+ * b) enable frequency selection (for capture/playback)
+ */
+ spin_lock_irqsave(&chip->reg_lock, flags);
+ snd_cs4231_out(chip, CS4231_MISC_INFO,
+ CS4231_MODE2 | 0x10);
+ val = snd_cs4231_in(chip, AD1845_PWR_DOWN_CTRL);
+ snd_cs4231_out(chip, AD1845_PWR_DOWN_CTRL,
+ val | AD1845_FREQ_SEL_ENABLE);
+ spin_unlock_irqrestore(&chip->reg_lock, flags);
+ }
- if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
- snd_printk(KERN_ERR "sscape: No PCM device for AD1845 chip\n");
+ err = snd_cs4231_pcm(chip, 0, &pcm);
+ if (err < 0) {
+ snd_printk(KERN_ERR "sscape: No PCM device "
+ "for AD1845 chip\n");
goto _error;
}
- if ((err = snd_cs4231_mixer(chip)) < 0) {
- snd_printk(KERN_ERR "sscape: No mixer device for AD1845 chip\n");
+ err = snd_cs4231_mixer(chip);
+ if (err < 0) {
+ snd_printk(KERN_ERR "sscape: No mixer device "
+ "for AD1845 chip\n");
goto _error;
}
-
- if ((err = snd_ctl_add(card, snd_ctl_new1(&midi_mixer_ctl, chip))) < 0) {
- snd_printk(KERN_ERR "sscape: Could not create MIDI mixer control\n");
+ err = snd_cs4231_timer(chip, 0, NULL);
+ if (err < 0) {
+ snd_printk(KERN_ERR "sscape: No timer device "
+ "for AD1845 chip\n");
goto _error;
}
+ if (sscape->type != SSCAPE_VIVO) {
+ err = snd_ctl_add(card,
+ snd_ctl_new1(&midi_mixer_ctl, chip));
+ if (err < 0) {
+ snd_printk(KERN_ERR "sscape: Could not create "
+ "MIDI mixer control\n");
+ goto _error;
+ }
+ chip->set_playback_format = ad1845_playback_format;
+ chip->set_capture_format = ad1845_capture_format;
+ }
+
strcpy(card->driver, "SoundScape");
strcpy(card->shortname, pcm->name);
snprintf(card->longname, sizeof(card->longname),
- "%s at 0x%lx, IRQ %d, DMA %d\n",
- pcm->name, chip->port, chip->irq, chip->dma1);
- chip->set_playback_format = ad1845_playback_format;
- chip->set_capture_format = ad1845_capture_format;
+ "%s at 0x%lx, IRQ %d, DMA1 %d, DMA2 %d\n",
+ pcm->name, chip->port, chip->irq,
+ chip->dma1, chip->dma2);
+
sscape->chip = chip;
}
@@ -1086,15 +1149,15 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq
* Create an ALSA soundcard entry for the SoundScape, using
* the given list of port, IRQ and DMA resources.
*/
-static int __devinit create_sscape(int dev, struct snd_card **rcardp)
+static int __devinit create_sscape(int dev, struct snd_card *card)
{
- struct snd_card *card;
- register struct soundscape *sscape;
- register unsigned dma_cfg;
+ struct soundscape *sscape = get_card_soundscape(card);
+ unsigned dma_cfg;
unsigned irq_cfg;
unsigned mpu_irq_cfg;
unsigned xport;
struct resource *io_res;
+ struct resource *wss_res;
unsigned long flags;
int err;
@@ -1118,61 +1181,69 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
* Grab IO ports that we will need to probe so that we
* can detect and control this hardware ...
*/
- if ((io_res = request_region(xport, 8, "SoundScape")) == NULL) {
+ io_res = request_region(xport, 8, "SoundScape");
+ if (!io_res) {
snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport);
return -EBUSY;
}
+ wss_res = NULL;
+ if (sscape->type == SSCAPE_VIVO) {
+ wss_res = request_region(wss_port[dev], 4, "SoundScape");
+ if (!wss_res) {
+ snd_printk(KERN_ERR "sscape: can't grab port 0x%lx\n",
+ wss_port[dev]);
+ err = -EBUSY;
+ goto _release_region;
+ }
+ }
/*
- * Grab both DMA channels (OK, only one for now) ...
+ * Grab one DMA channel ...
*/
- if ((err = request_dma(dma[dev], "SoundScape")) < 0) {
+ err = request_dma(dma[dev], "SoundScape");
+ if (err < 0) {
snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]);
goto _release_region;
}
- /*
- * Create a new ALSA sound card entry, in anticipation
- * of detecting our hardware ...
- */
- if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
- sizeof(struct soundscape))) == NULL) {
- err = -ENOMEM;
- goto _release_dma;
- }
-
- sscape = get_card_soundscape(card);
spin_lock_init(&sscape->lock);
spin_lock_init(&sscape->fwlock);
sscape->io_res = io_res;
+ sscape->wss_res = wss_res;
sscape->io_base = xport;
+ sscape->wss_base = wss_port[dev];
if (!detect_sscape(sscape)) {
printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base);
err = -ENODEV;
- goto _release_card;
+ goto _release_dma;
}
printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n",
- sscape->io_base, irq[dev], dma[dev]);
+ sscape->io_base, irq[dev], dma[dev]);
- /*
- * Now create the hardware-specific device so that we can
- * load the microcode into the on-board processor.
- * We cannot use the MPU-401 MIDI system until this firmware
- * has been loaded into the card.
- */
- if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) {
- printk(KERN_ERR "sscape: Failed to create firmware device\n");
- goto _release_card;
+ if (sscape->type != SSCAPE_VIVO) {
+ /*
+ * Now create the hardware-specific device so that we can
+ * load the microcode into the on-board processor.
+ * We cannot use the MPU-401 MIDI system until this firmware
+ * has been loaded into the card.
+ */
+ err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw));
+ if (err < 0) {
+ printk(KERN_ERR "sscape: Failed to create "
+ "firmware device\n");
+ goto _release_dma;
+ }
+ strlcpy(sscape->hw->name, "SoundScape M68K",
+ sizeof(sscape->hw->name));
+ sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0';
+ sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE;
+ sscape->hw->ops.open = sscape_hw_open;
+ sscape->hw->ops.release = sscape_hw_release;
+ sscape->hw->ops.ioctl = sscape_hw_ioctl;
+ sscape->hw->private_data = sscape;
}
- strlcpy(sscape->hw->name, "SoundScape M68K", sizeof(sscape->hw->name));
- sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0';
- sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE;
- sscape->hw->ops.open = sscape_hw_open;
- sscape->hw->ops.release = sscape_hw_release;
- sscape->hw->ops.ioctl = sscape_hw_ioctl;
- sscape->hw->private_data = sscape;
/*
* Tell the on-board devices where their resources are (I think -
@@ -1197,7 +1268,8 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
sscape_write_unsafe(sscape->io_base,
GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg);
sscape_write_unsafe(sscape->io_base,
- GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1));
+ GA_CDCFG_REG, 0x09 | DMA_8BIT
+ | (dma[dev] << 4) | (irq_cfg << 1));
spin_unlock_irqrestore(&sscape->lock, flags);
@@ -1205,30 +1277,37 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
* We have now enabled the codec chip, and so we should
* detect the AD1845 device ...
*/
- if ((err = create_ad1845(card, CODEC_IO(xport), irq[dev], dma[dev])) < 0) {
- printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n",
- CODEC_IO(xport), irq[dev]);
- goto _release_card;
+ err = create_ad1845(card, wss_port[dev], irq[dev],
+ dma[dev], dma2[dev]);
+ if (err < 0) {
+ printk(KERN_ERR "sscape: No AD1845 device at 0x%lx, IRQ %d\n",
+ wss_port[dev], irq[dev]);
+ goto _release_dma;
}
#define MIDI_DEVNUM 0
- if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(xport), mpu_irq[dev])) < 0) {
- printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n",
- MPU401_IO(xport));
- goto _release_card;
- }
+ if (sscape->type != SSCAPE_VIVO) {
+ err = create_mpu401(card, MIDI_DEVNUM,
+ MPU401_IO(xport), mpu_irq[dev]);
+ if (err < 0) {
+ printk(KERN_ERR "sscape: Failed to create "
+ "MPU-401 device at 0x%x\n",
+ MPU401_IO(xport));
+ goto _release_dma;
+ }
- /*
- * Enable the master IRQ ...
- */
- sscape_write(sscape, GA_INTENA_REG, 0x80);
+ /*
+ * Enable the master IRQ ...
+ */
+ sscape_write(sscape, GA_INTENA_REG, 0x80);
- /*
- * Initialize mixer
- */
- sscape->midi_vol = 0;
- host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100);
- host_write_ctrl_unsafe(sscape->io_base, 0, 100);
- host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100);
+ /*
+ * Initialize mixer
+ */
+ sscape->midi_vol = 0;
+ host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100);
+ host_write_ctrl_unsafe(sscape->io_base, 0, 100);
+ host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100);
+ }
/*
* Now that we have successfully created this sound card,
@@ -1237,17 +1316,14 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
* function now that our "constructor" has completed.
*/
card->private_free = soundscape_free;
- *rcardp = card;
return 0;
- _release_card:
- snd_card_free(card);
-
- _release_dma:
+_release_dma:
free_dma(dma[dev]);
- _release_region:
+_release_region:
+ release_and_free_resource(wss_res);
release_and_free_resource(io_res);
return err;
@@ -1276,19 +1352,33 @@ static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
{
struct snd_card *card;
+ struct soundscape *sscape;
int ret;
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+ sizeof(struct soundscape));
+ if (!card)
+ return -ENOMEM;
+
+ sscape = get_card_soundscape(card);
+ sscape->type = SSCAPE;
+
dma[dev] &= 0x03;
- ret = create_sscape(dev, &card);
+ ret = create_sscape(dev, card);
if (ret < 0)
- return ret;
+ goto _release_card;
+
snd_card_set_dev(card, pdev);
if ((ret = snd_card_register(card)) < 0) {
printk(KERN_ERR "sscape: Failed to register sound card\n");
- return ret;
+ goto _release_card;
}
dev_set_drvdata(pdev, card);
return 0;
+
+_release_card:
+ snd_card_free(card);
+ return ret;
}
static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
@@ -1325,6 +1415,7 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
static int idx = 0;
struct pnp_dev *dev;
struct snd_card *card;
+ struct soundscape *sscape;
int ret;
/*
@@ -1366,26 +1457,55 @@ static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
}
/*
+ * Create a new ALSA sound card entry, in anticipation
+ * of detecting our hardware ...
+ */
+ card = snd_card_new(index[idx], id[idx], THIS_MODULE,
+ sizeof(struct soundscape));
+ if (!card)
+ return -ENOMEM;
+
+ sscape = get_card_soundscape(card);
+
+ /*
+ * Identify card model ...
+ */
+ if (!strncmp("ENS4081", pid->id, 7))
+ sscape->type = SSCAPE_VIVO;
+ else
+ sscape->type = SSCAPE_PNP;
+
+ /*
* Read the correct parameters off the ISA PnP bus ...
*/
port[idx] = pnp_port_start(dev, 0);
irq[idx] = pnp_irq(dev, 0);
mpu_irq[idx] = pnp_irq(dev, 1);
dma[idx] = pnp_dma(dev, 0) & 0x03;
+ if (sscape->type == SSCAPE_PNP) {
+ dma2[idx] = dma[idx];
+ wss_port[idx] = CODEC_IO(port[idx]);
+ } else {
+ wss_port[idx] = pnp_port_start(dev, 1);
+ dma2[idx] = pnp_dma(dev, 1);
+ }
- ret = create_sscape(idx, &card);
+ ret = create_sscape(idx, card);
if (ret < 0)
- return ret;
+ goto _release_card;
+
snd_card_set_dev(card, &pcard->card->dev);
if ((ret = snd_card_register(card)) < 0) {
printk(KERN_ERR "sscape: Failed to register sound card\n");
- snd_card_free(card);
- return ret;
+ goto _release_card;
}
pnp_set_card_drvdata(pcard, card);
++idx;
+ return 0;
+_release_card:
+ snd_card_free(card);
return ret;
}
diff --git a/sound/isa/wavefront/Makefile b/sound/isa/wavefront/Makefile
index b4cb28422db..601bdddd44d 100644
--- a/sound/isa/wavefront/Makefile
+++ b/sound/isa/wavefront/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-wavefront-objs := wavefront.o wavefront_fx.o wavefront_synth.o wavefront_midi.o
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index bacc51c8658..a1ebb7c5c68 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -27,6 +27,7 @@
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/wait.h>
+#include <linux/firmware.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/snd_wavefront.h>
@@ -53,9 +54,8 @@ static int debug_default = 0; /* you can set this to control debugging
/* XXX this needs to be made firmware and hardware version dependent */
-static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
- version of the WaveFront OS
- */
+#define DEFAULT_OSPATH "wavefront.os"
+static char *ospath = DEFAULT_OSPATH; /* the firmware file name */
static int wait_usecs = 150; /* This magic number seems to give pretty optimal
throughput based on my limited experimentation.
@@ -97,7 +97,7 @@ MODULE_PARM_DESC(sleep_interval, "how long to sleep when waiting for reply");
module_param(sleep_tries, int, 0444);
MODULE_PARM_DESC(sleep_tries, "how many times to try sleeping during a wait");
module_param(ospath, charp, 0444);
-MODULE_PARM_DESC(ospath, "full pathname to processed ICS2115 OS firmware");
+MODULE_PARM_DESC(ospath, "pathname to processed ICS2115 OS firmware");
module_param(reset_time, int, 0444);
MODULE_PARM_DESC(reset_time, "how long to wait for a reset to take effect");
module_param(ramcheck_time, int, 0444);
@@ -1768,7 +1768,7 @@ snd_wavefront_interrupt_bits (int irq)
static void __devinit
wavefront_should_cause_interrupt (snd_wavefront_t *dev,
- int val, int port, int timeout)
+ int val, int port, unsigned long timeout)
{
wait_queue_t wait;
@@ -1779,11 +1779,9 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev,
dev->irq_ok = 0;
outb (val,port);
spin_unlock_irq(&dev->irq_lock);
- while (1) {
- if ((timeout = schedule_timeout(timeout)) == 0)
- return;
- if (dev->irq_ok)
- return;
+ while (!dev->irq_ok && time_before(jiffies, timeout)) {
+ schedule_timeout_uninterruptible(1);
+ barrier();
}
}
@@ -1938,111 +1936,75 @@ wavefront_reset_to_cleanliness (snd_wavefront_t *dev)
return (1);
}
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/unistd.h>
-#include <linux/syscalls.h>
-#include <asm/uaccess.h>
-
-
static int __devinit
wavefront_download_firmware (snd_wavefront_t *dev, char *path)
{
- unsigned char section[WF_SECTION_MAX];
- signed char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
+ unsigned char *buf;
+ int len, err;
int section_cnt_downloaded = 0;
- int fd;
- int c;
- int i;
- mm_segment_t fs;
-
- /* This tries to be a bit cleverer than the stuff Alan Cox did for
- the generic sound firmware, in that it actually knows
- something about the structure of the Motorola firmware. In
- particular, it uses a version that has been stripped of the
- 20K of useless header information, and had section lengths
- added, making it possible to load the entire OS without any
- [kv]malloc() activity, since the longest entity we ever read is
- 42 bytes (well, WF_SECTION_MAX) long.
- */
-
- fs = get_fs();
- set_fs (get_ds());
+ const struct firmware *firmware;
- if ((fd = sys_open ((char __user *) path, 0, 0)) < 0) {
- snd_printk ("Unable to load \"%s\".\n",
- path);
+ err = request_firmware(&firmware, path, dev->card->dev);
+ if (err < 0) {
+ snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path);
return 1;
}
- while (1) {
- int x;
-
- if ((x = sys_read (fd, (char __user *) &section_length, sizeof (section_length))) !=
- sizeof (section_length)) {
- snd_printk ("firmware read error.\n");
- goto failure;
- }
-
- if (section_length == 0) {
+ len = 0;
+ buf = firmware->data;
+ for (;;) {
+ int section_length = *(signed char *)buf;
+ if (section_length == 0)
break;
- }
-
if (section_length < 0 || section_length > WF_SECTION_MAX) {
- snd_printk ("invalid firmware section length %d\n",
- section_length);
+ snd_printk(KERN_ERR
+ "invalid firmware section length %d\n",
+ section_length);
goto failure;
}
+ buf++;
+ len++;
- if (sys_read (fd, (char __user *) section, section_length) != section_length) {
- snd_printk ("firmware section "
- "read error.\n");
+ if (firmware->size < len + section_length) {
+ snd_printk(KERN_ERR "firmware section read error.\n");
goto failure;
}
/* Send command */
-
- if (wavefront_write (dev, WFC_DOWNLOAD_OS)) {
+ if (wavefront_write(dev, WFC_DOWNLOAD_OS))
goto failure;
- }
- for (i = 0; i < section_length; i++) {
- if (wavefront_write (dev, section[i])) {
+ for (; section_length; section_length--) {
+ if (wavefront_write(dev, *buf))
goto failure;
- }
+ buf++;
+ len++;
}
/* get ACK */
-
- if (wavefront_wait (dev, STAT_CAN_READ)) {
-
- if ((c = inb (dev->data_port)) != WF_ACK) {
-
- snd_printk ("download "
- "of section #%d not "
- "acknowledged, ack = 0x%x\n",
- section_cnt_downloaded + 1, c);
- goto failure;
-
- }
-
- } else {
- snd_printk ("time out for firmware ACK.\n");
+ if (!wavefront_wait(dev, STAT_CAN_READ)) {
+ snd_printk(KERN_ERR "time out for firmware ACK.\n");
+ goto failure;
+ }
+ err = inb(dev->data_port);
+ if (err != WF_ACK) {
+ snd_printk(KERN_ERR
+ "download of section #%d not "
+ "acknowledged, ack = 0x%x\n",
+ section_cnt_downloaded + 1, err);
goto failure;
}
+ section_cnt_downloaded++;
}
- sys_close (fd);
- set_fs (fs);
+ release_firmware(firmware);
return 0;
failure:
- sys_close (fd);
- set_fs (fs);
- snd_printk ("firmware download failed!!!\n");
+ release_firmware(firmware);
+ snd_printk(KERN_ERR "firmware download failed!!!\n");
return 1;
}
@@ -2232,3 +2194,5 @@ snd_wavefront_detect (snd_wavefront_card_t *card)
return 0;
}
+
+MODULE_FIRMWARE(DEFAULT_OSPATH);
diff --git a/sound/last.c b/sound/last.c
index 964314efff5..282b0cdb058 100644
--- a/sound/last.c
+++ b/sound/last.c
@@ -1,6 +1,6 @@
/*
* Advanced Linux Sound Architecture
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 1200670017b..f883c4b676a 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -36,7 +36,6 @@ obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o
obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o
obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o
obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
diff --git a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile
index 4611636b1a8..3c1531652d1 100644
--- a/sound/oss/dmasound/Makefile
+++ b/sound/oss/dmasound/Makefile
@@ -2,12 +2,6 @@
# Makefile for the DMA sound driver
#
-dmasound_pmac-y += dmasound_awacs.o \
- trans_16.o dac3550a.o tas_common.o \
- tas3001c.o tas3001c_tables.o \
- tas3004.o tas3004_tables.o
-
obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o
-obj-$(CONFIG_DMASOUND_PMAC) += dmasound_core.o dmasound_pmac.o
obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o
obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o
diff --git a/sound/oss/dmasound/awacs_defs.h b/sound/oss/dmasound/awacs_defs.h
deleted file mode 100644
index 2194f46b046..00000000000
--- a/sound/oss/dmasound/awacs_defs.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*********************************************************/
-/* This file was written by someone, somewhere, sometime */
-/* And is released into the Public Domain */
-/*********************************************************/
-
-#ifndef _AWACS_DEFS_H_
-#define _AWACS_DEFS_H_
-
-/*******************************/
-/* AWACs Audio Register Layout */
-/*******************************/
-
-struct awacs_regs {
- unsigned control; /* Audio control register */
- unsigned pad0[3];
- unsigned codec_ctrl; /* Codec control register */
- unsigned pad1[3];
- unsigned codec_stat; /* Codec status register */
- unsigned pad2[3];
- unsigned clip_count; /* Clipping count register */
- unsigned pad3[3];
- unsigned byteswap; /* Data is little-endian if 1 */
-};
-
-/*******************/
-/* Audio Bit Masks */
-/*******************/
-
-/* Audio Control Reg Bit Masks */
-/* ----- ------- --- --- ----- */
-#define MASK_ISFSEL (0xf) /* Input SubFrame Select */
-#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */
-#define MASK_RATE (0x7 << 8) /* Sound Rate */
-#define MASK_CNTLERR (0x1 << 11) /* Error */
-#define MASK_PORTCHG (0x1 << 12) /* Port Change */
-#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */
-#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */
-#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */
-
-/* Audio Codec Control Reg Bit Masks */
-/* ----- ----- ------- --- --- ----- */
-#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */
-#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */
-#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */
-#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */
-
-/* Audio Codec Control Address Values / Masks */
-/* ----- ----- ------- ------- ------ - ----- */
-#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */
-#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */
-#define MASK_ADDR_GAIN MASK_ADDR0
-
-#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */
-#define MASK_ADDR_MUTE MASK_ADDR1
-#define MASK_ADDR_RATE MASK_ADDR1
-
-#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */
-#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */
-#define MASK_ADDR_VOLHD MASK_ADDR2
-
-#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */
-#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
-#define MASK_ADDR_VOLSPK MASK_ADDR4
-
-/* additional registers of screamer */
-#define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */
-#define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */
-#define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */
-
-/* Address 0 Bit Masks & Macros */
-/* ------- - --- ----- - ------ */
-#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
-#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */
-#define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */
-#define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */
-
-#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */
-#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */
-#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */
-#define MASK_MUX_LINE MASK_MUX_AUDIN
-
-#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT)
-#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT)
-
-#define DEF_CD_GAIN 0x00bb
-#define DEF_MIC_GAIN 0x00cc
-
-/* Address 1 Bit Masks */
-/* ------- - --- ----- */
-#define MASK_ADDR1RES1 (0x3) /* Reserved */
-#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */
-#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */
-#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */
-#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */
-#define MASK_SPKMUTE MASK_CMUTE
-#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */
-#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */
-#define MASK_HDMUTE MASK_AMUTE
-#define MASK_PAROUT0 (0x1 << 10) /* Parallel Output 0 */
-#define MASK_PAROUT1 (0x2 << 10) /* Parallel Output 1 */
-
-#define MASK_MIC_BOOST (0x4) /* screamer mic boost */
-
-#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */
-#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */
-#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */
-#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */
-#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */
-#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */
-#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */
-#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */
-
-/* Address 2 & 4 Bit Masks & Macros */
-/* ------- - - - --- ----- - ------ */
-#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */
-#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */
-#define MASK_ADDR4RES1 MASK_ADDR2RES1
-#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */
-#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */
-#define MASK_ADDR4RES2 MASK_ADDR2RES2
-
-#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT))
-#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT)
-
-/* Audio Codec Status Reg Bit Masks */
-/* ----- ----- ------ --- --- ----- */
-#define MASK_EXTEND (0x1 << 23) /* Extend */
-#define MASK_VALID (0x1 << 22) /* Valid Data? */
-#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */
-#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */
-#define MASK_ERRCODE (0xf << 16) /* Error Code */
-#define MASK_REVISION (0xf << 12) /* Revision Number */
-#define MASK_MFGID (0xf << 8) /* Mfg. ID */
-#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */
-#define MASK_INPPORT (0xf) /* Input Port */
-#define MASK_HDPCONN 8 /* headphone plugged in */
-
-/* Clipping Count Reg Bit Masks */
-/* -------- ----- --- --- ----- */
-#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */
-#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */
-
-/* DBDMA ChannelStatus Bit Masks */
-/* ----- ------------- --- ----- */
-#define MASK_CSERR (0x1 << 7) /* Error */
-#define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */
-#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */
-#define MASK_WAIT (0x1) /* Wait */
-
-/* Various Rates */
-/* ------- ----- */
-#define RATE_48000 (0x0 << 8) /* 48 kHz */
-#define RATE_44100 (0x0 << 8) /* 44.1 kHz */
-#define RATE_32000 (0x1 << 8) /* 32 kHz */
-#define RATE_29400 (0x1 << 8) /* 29.4 kHz */
-#define RATE_24000 (0x2 << 8) /* 24 kHz */
-#define RATE_22050 (0x2 << 8) /* 22.05 kHz */
-#define RATE_19200 (0x3 << 8) /* 19.2 kHz */
-#define RATE_17640 (0x3 << 8) /* 17.64 kHz */
-#define RATE_16000 (0x4 << 8) /* 16 kHz */
-#define RATE_14700 (0x4 << 8) /* 14.7 kHz */
-#define RATE_12000 (0x5 << 8) /* 12 kHz */
-#define RATE_11025 (0x5 << 8) /* 11.025 kHz */
-#define RATE_9600 (0x6 << 8) /* 9.6 kHz */
-#define RATE_8820 (0x6 << 8) /* 8.82 kHz */
-#define RATE_8000 (0x7 << 8) /* 8 kHz */
-#define RATE_7350 (0x7 << 8) /* 7.35 kHz */
-
-#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
-
-/*******************/
-/* Burgundy values */
-/*******************/
-
-#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
-#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
-
-#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12)
-#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12)
-#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12)
-
-#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12)
-#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12)
-
-#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12)
-
-#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12)
-
-#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12)
-#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12)
-
-#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1)
-#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2)
-#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3)
-#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1)
-#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2)
-#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3)
-#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4)
-
-
-/* These are all default values for the burgundy */
-#define DEF_BURGUNDY_INPSEL21 (0xAA)
-#define DEF_BURGUNDY_INPSEL3 (0x0A)
-
-#define DEF_BURGUNDY_GAINCD (0x33)
-#define DEF_BURGUNDY_GAINLINE (0x44)
-#define DEF_BURGUNDY_GAINMIC (0x44)
-#define DEF_BURGUNDY_GAINMODEM (0x06)
-
-/* Remember: lowest volume here is 0x9b */
-#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC)
-#define DEF_BURGUNDY_VOLLINE (0x00000000)
-#define DEF_BURGUNDY_VOLMIC (0x00000000)
-#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC)
-
-#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f)
-#define DEF_BURGUNDY_OUTPUTENABLES (0x0A)
-
-#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF)
-
-#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E)
-
-#define DEF_BURGUNDY_ATTENSPEAKER (0x44)
-#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
-#define DEF_BURGUNDY_ATTENHP (0xCC)
-
-/*********************/
-/* i2s layout values */
-/*********************/
-
-#define I2S_REG_INT_CTL 0x00
-#define I2S_REG_SERIAL_FORMAT 0x10
-#define I2S_REG_CODEC_MSG_OUT 0x20
-#define I2S_REG_CODEC_MSG_IN 0x30
-#define I2S_REG_FRAME_COUNT 0x40
-#define I2S_REG_FRAME_MATCH 0x50
-#define I2S_REG_DATAWORD_SIZES 0x60
-#define I2S_REG_PEAKLEVEL_SEL 0x70
-#define I2S_REG_PEAKLEVEL_IN0 0x80
-#define I2S_REG_PEAKLEVEL_IN1 0x90
-
-#endif /* _AWACS_DEFS_H_ */
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c
deleted file mode 100644
index 0f0d03a55da..00000000000
--- a/sound/oss/dmasound/dac3550a.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Driver for the i2c/i2s based DAC3550a sound chip used
- * on some Apple iBooks. Also known as "DACA".
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-
-#include "dmasound.h"
-
-/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer
- * control code, as well as info derived from the AppleDACAAudio driver
- * from Darwin CVS (main thing I derived being register numbers and
- * values, as well as when to make the calls). */
-
-#define I2C_DRIVERID_DACA (0xFDCB)
-
-#define DACA_VERSION "0.1"
-#define DACA_DATE "20010930"
-
-static int cur_left_vol;
-static int cur_right_vol;
-static struct i2c_client *daca_client;
-
-static int daca_attach_adapter(struct i2c_adapter *adapter);
-static int daca_detect_client(struct i2c_adapter *adapter, int address);
-static int daca_detach_client(struct i2c_client *client);
-
-struct i2c_driver daca_driver = {
- .driver = {
- .name = "DAC3550A driver V " DACA_VERSION,
- },
- .id = I2C_DRIVERID_DACA,
- .attach_adapter = daca_attach_adapter,
- .detach_client = daca_detach_client,
-};
-
-#define VOL_MAX ((1<<20) - 1)
-
-void daca_get_volume(uint * left_vol, uint *right_vol)
-{
- *left_vol = cur_left_vol >> 5;
- *right_vol = cur_right_vol >> 5;
-}
-
-int daca_set_volume(uint left_vol, uint right_vol)
-{
- unsigned short voldata;
-
- if (!daca_client)
- return -1;
-
- /* Derived from experience, not from any specific values */
- left_vol <<= 5;
- right_vol <<= 5;
-
- if (left_vol > VOL_MAX)
- left_vol = VOL_MAX;
- if (right_vol > VOL_MAX)
- right_vol = VOL_MAX;
-
- voldata = ((left_vol >> 14) & 0x3f) << 8;
- voldata |= (right_vol >> 14) & 0x3f;
-
- if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) {
- printk("daca: failed to set volume \n");
- return -1;
- }
-
- cur_left_vol = left_vol;
- cur_right_vol = right_vol;
-
- return 0;
-}
-
-int daca_leave_sleep(void)
-{
- if (!daca_client)
- return -1;
-
- /* Do a short sleep, just to make sure I2C bus is awake and paying
- * attention to us
- */
- msleep(20);
- /* Write the sample rate reg the value it needs */
- i2c_smbus_write_byte_data(daca_client, 1, 8);
- daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
- /* Another short delay, just to make sure the other I2C bus writes
- * have taken...
- */
- msleep(20);
- /* Write the global config reg - invert right power amp,
- * DAC on, use 5-volt mode */
- i2c_smbus_write_byte_data(daca_client, 3, 0x45);
-
- return 0;
-}
-
-int daca_enter_sleep(void)
-{
- if (!daca_client)
- return -1;
-
- i2c_smbus_write_byte_data(daca_client, 1, 8);
- daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5);
-
- /* Write the global config reg - invert right power amp,
- * DAC on, enter low-power mode, use 5-volt mode
- */
- i2c_smbus_write_byte_data(daca_client, 3, 0x65);
-
- return 0;
-}
-
-static int daca_attach_adapter(struct i2c_adapter *adapter)
-{
- if (!strncmp(adapter->name, "mac-io", 6))
- daca_detect_client(adapter, 0x4d);
- return 0;
-}
-
-static int daca_init_client(struct i2c_client * new_client)
-{
- /*
- * Probe is not working with the current i2c-keywest
- * driver. We try to use addr 0x4d on each adapters
- * instead, by setting the format register.
- *
- * FIXME: I'm sure that can be obtained from the
- * device-tree. --BenH.
- */
-
- /* Write the global config reg - invert right power amp,
- * DAC on, use 5-volt mode
- */
- if (i2c_smbus_write_byte_data(new_client, 3, 0x45))
- return -1;
-
- i2c_smbus_write_byte_data(new_client, 1, 8);
- daca_client = new_client;
- daca_set_volume(15000, 15000);
-
- return 0;
-}
-
-static int daca_detect_client(struct i2c_adapter *adapter, int address)
-{
- const char *client_name = "DAC 3550A Digital Equalizer";
- struct i2c_client *new_client;
- int rc = -ENODEV;
-
- new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
- if (!new_client)
- return -ENOMEM;
-
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &daca_driver;
- new_client->flags = 0;
- strcpy(new_client->name, client_name);
-
- if (daca_init_client(new_client))
- goto bail;
-
- /* Tell the i2c layer a new client has arrived */
- if (i2c_attach_client(new_client))
- goto bail;
-
- return 0;
- bail:
- kfree(new_client);
- return rc;
-}
-
-
-static int daca_detach_client(struct i2c_client *client)
-{
- if (client == daca_client)
- daca_client = NULL;
-
- i2c_detach_client(client);
- kfree(client);
- return 0;
-}
-
-void daca_cleanup(void)
-{
- i2c_del_driver(&daca_driver);
-}
-
-int daca_init(void)
-{
- printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE);
- return i2c_add_driver(&daca_driver);
-}
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 25dd5a318eb..d978b009656 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -59,7 +59,6 @@ static inline int ioctl_return(int __user *addr, int value)
*/
#undef HAS_8BIT_TABLES
-#undef HAS_RECORD
#if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\
defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\
@@ -83,10 +82,6 @@ static inline int ioctl_return(int __user *addr, int value)
#define DEFAULT_N_BUFFERS 4
#define DEFAULT_BUFF_SIZE (1<<15)
-#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE)
-#define HAS_RECORD
-#endif
-
/*
* Initialization
*/
@@ -168,9 +163,6 @@ struct sound_settings {
SETTINGS soft; /* software settings */
SETTINGS dsp; /* /dev/dsp default settings */
TRANS *trans_write; /* supported translations */
-#ifdef HAS_RECORD
- TRANS *trans_read; /* supported translations */
-#endif
int volume_left; /* volume (range is machine dependent) */
int volume_right;
int bass; /* tone (range is machine dependent) */
@@ -253,11 +245,6 @@ struct sound_queue {
extern struct sound_queue dmasound_write_sq;
#define write_sq dmasound_write_sq
-#ifdef HAS_RECORD
-extern struct sound_queue dmasound_read_sq;
-#define read_sq dmasound_read_sq
-#endif
-
extern int dmasound_catchRadius;
#define catchRadius dmasound_catchRadius
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
deleted file mode 100644
index 8f6388004f4..00000000000
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ /dev/null
@@ -1,3215 +0,0 @@
-/*
- * linux/sound/oss/dmasound/dmasound_awacs.c
- *
- * PowerMac `AWACS' and `Burgundy' DMA Sound Driver
- * with some limited support for DACA & Tumbler
- *
- * See linux/sound/oss/dmasound/dmasound_core.c for copyright and
- * history prior to 2001/01/26.
- *
- * 26/01/2001 ed 0.1 Iain Sandoe
- * - added version info.
- * - moved dbdma command buffer allocation to PMacXXXSqSetup()
- * - fixed up beep dbdma cmd buffers
- *
- * 08/02/2001 [0.2]
- * - make SNDCTL_DSP_GETFMTS return the correct info for the h/w
- * - move soft format translations to a separate file
- * - [0.3] make SNDCTL_DSP_GETCAPS return correct info.
- * - [0.4] more informative machine name strings.
- * - [0.5]
- * - record changes.
- * - made the default_hard/soft entries.
- * 04/04/2001 [0.6]
- * - minor correction to bit assignments in awacs_defs.h
- * - incorporate mixer changes from 2.2.x back-port.
- * - take out passthru as a rec input (it isn't).
- * - make Input Gain slider work the 'right way up'.
- * - try to make the mixer sliders more logical - so now the
- * input selectors are just two-state (>50% == ON) and the
- * Input Gain slider handles the rest of the gain issues.
- * - try to pick slider representations that most closely match
- * the actual use - e.g. IGain for input gain...
- * - first stab at over/under-run detection.
- * - minor cosmetic changes to IRQ identification.
- * - fix bug where rates > max would be reported as supported.
- * - first stab at over/under-run detection.
- * - make use of i2c for mixer settings conditional on perch
- * rather than cuda (some machines without perch have cuda).
- * - fix bug where TX stops when dbdma status comes up "DEAD"
- * so far only reported on PowerComputing clones ... but.
- * - put in AWACS/Screamer register write timeouts.
- * - part way to partitioning the init() stuff
- * - first pass at 'tumbler' stuff (not support - just an attempt
- * to allow the driver to load on new G4s).
- * 01/02/2002 [0.7] - BenH
- * - all sort of minor bits went in since the latest update, I
- * bumped the version number for that reason
- *
- * 07/26/2002 [0.8] - BenH
- * - More minor bits since last changelog (I should be more careful
- * with those)
- * - Support for snapper & better tumbler integration by Toby Sargeant
- * - Headphone detect for scremer by Julien Blache
- * - More tumbler fixed by Andreas Schwab
- * 11/29/2003 [0.8.1] - Renzo Davoli (King Enzo)
- * - Support for Snapper line in
- * - snapper input resampling (for rates < 44100)
- * - software line gain control
- */
-
-/* GENERAL FIXME/TODO: check that the assumptions about what is written to
- mac-io is valid for DACA & Tumbler.
-
- This driver is in bad need of a rewrite. The dbdma code has to be split,
- some proper device-tree parsing code has to be written, etc...
-*/
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/soundcard.h>
-#include <linux/adb.h>
-#include <linux/nvram.h>
-#include <linux/tty.h>
-#include <linux/vt_kern.h>
-#include <linux/spinlock.h>
-#include <linux/kmod.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/mutex.h>
-#ifdef CONFIG_ADB_CUDA
-#include <linux/cuda.h>
-#endif
-#ifdef CONFIG_ADB_PMU
-#include <linux/pmu.h>
-#endif
-
-#include <asm/uaccess.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/dbdma.h>
-#include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/nvram.h>
-
-#include "awacs_defs.h"
-#include "dmasound.h"
-#include "tas3001c.h"
-#include "tas3004.h"
-#include "tas_common.h"
-
-#define DMASOUND_AWACS_REVISION 0
-#define DMASOUND_AWACS_EDITION 7
-
-#define AWACS_SNAPPER 110 /* fake revision # for snapper */
-#define AWACS_BURGUNDY 100 /* fake revision # for burgundy */
-#define AWACS_TUMBLER 90 /* fake revision # for tumbler */
-#define AWACS_DACA 80 /* fake revision # for daca (ibook) */
-#define AWACS_AWACS 2 /* holding revision for AWACS */
-#define AWACS_SCREAMER 3 /* holding revision for Screamer */
-/*
- * Interrupt numbers and addresses, & info obtained from the device tree.
- */
-static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
-static volatile struct awacs_regs __iomem *awacs;
-static volatile u32 __iomem *i2s;
-static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma;
-static int awacs_rate_index;
-static int awacs_subframe;
-static struct device_node* awacs_node;
-static struct device_node* i2s_node;
-static struct resource awacs_rsrc[3];
-
-static char awacs_name[64];
-static int awacs_revision;
-static int awacs_sleeping;
-static DEFINE_MUTEX(dmasound_mutex);
-
-static int sound_device_id; /* exists after iMac revA */
-static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */
-
-/* model info */
-/* To be replaced with better interaction with pmac_feature.c */
-static int is_pbook_3X00;
-static int is_pbook_g3;
-
-/* expansion info */
-static int has_perch;
-static int has_ziva;
-
-/* for earlier powerbooks which need fiddling with mac-io to enable
- * cd etc.
-*/
-static unsigned char __iomem *latch_base;
-static unsigned char __iomem *macio_base;
-
-/*
- * Space for the DBDMA command blocks.
- */
-static void *awacs_tx_cmd_space;
-static volatile struct dbdma_cmd *awacs_tx_cmds;
-static int number_of_tx_cmd_buffers;
-
-static void *awacs_rx_cmd_space;
-static volatile struct dbdma_cmd *awacs_rx_cmds;
-static int number_of_rx_cmd_buffers;
-
-/*
- * Cached values of AWACS registers (we can't read them).
- * Except on the burgundy (and screamer). XXX
- */
-
-int awacs_reg[8];
-int awacs_reg1_save;
-
-/* tracking values for the mixer contents
-*/
-
-static int spk_vol;
-static int line_vol;
-static int passthru_vol;
-
-static int ip_gain; /* mic preamp settings */
-static int rec_lev = 0x4545 ; /* default CD gain 69 % */
-static int mic_lev;
-static int cd_lev = 0x6363 ; /* 99 % */
-static int line_lev;
-
-static int hdp_connected;
-
-/*
- * Stuff for outputting a beep. The values range from -327 to +327
- * so we can multiply by an amplitude in the range 0..100 to get a
- * signed short value to put in the output buffer.
- */
-static short beep_wform[256] = {
- 0, 40, 79, 117, 153, 187, 218, 245,
- 269, 288, 304, 316, 323, 327, 327, 324,
- 318, 310, 299, 288, 275, 262, 249, 236,
- 224, 213, 204, 196, 190, 186, 183, 182,
- 182, 183, 186, 189, 192, 196, 200, 203,
- 206, 208, 209, 209, 209, 207, 204, 201,
- 197, 193, 188, 183, 179, 174, 170, 166,
- 163, 161, 160, 159, 159, 160, 161, 162,
- 164, 166, 168, 169, 171, 171, 171, 170,
- 169, 167, 163, 159, 155, 150, 144, 139,
- 133, 128, 122, 117, 113, 110, 107, 105,
- 103, 103, 103, 103, 104, 104, 105, 105,
- 105, 103, 101, 97, 92, 86, 78, 68,
- 58, 45, 32, 18, 3, -11, -26, -41,
- -55, -68, -79, -88, -95, -100, -102, -102,
- -99, -93, -85, -75, -62, -48, -33, -16,
- 0, 16, 33, 48, 62, 75, 85, 93,
- 99, 102, 102, 100, 95, 88, 79, 68,
- 55, 41, 26, 11, -3, -18, -32, -45,
- -58, -68, -78, -86, -92, -97, -101, -103,
- -105, -105, -105, -104, -104, -103, -103, -103,
- -103, -105, -107, -110, -113, -117, -122, -128,
- -133, -139, -144, -150, -155, -159, -163, -167,
- -169, -170, -171, -171, -171, -169, -168, -166,
- -164, -162, -161, -160, -159, -159, -160, -161,
- -163, -166, -170, -174, -179, -183, -188, -193,
- -197, -201, -204, -207, -209, -209, -209, -208,
- -206, -203, -200, -196, -192, -189, -186, -183,
- -182, -182, -183, -186, -190, -196, -204, -213,
- -224, -236, -249, -262, -275, -288, -299, -310,
- -318, -324, -327, -327, -323, -316, -304, -288,
- -269, -245, -218, -187, -153, -117, -79, -40,
-};
-
-/* beep support */
-#define BEEP_SRATE 22050 /* 22050 Hz sample rate */
-#define BEEP_BUFLEN 512
-#define BEEP_VOLUME 15 /* 0 - 100 */
-
-static int beep_vol = BEEP_VOLUME;
-static int beep_playing;
-static int awacs_beep_state;
-static short *beep_buf;
-static void *beep_dbdma_cmd_space;
-static volatile struct dbdma_cmd *beep_dbdma_cmd;
-
-/* Burgundy functions */
-static void awacs_burgundy_wcw(unsigned addr,unsigned newval);
-static unsigned awacs_burgundy_rcw(unsigned addr);
-static void awacs_burgundy_write_volume(unsigned address, int volume);
-static int awacs_burgundy_read_volume(unsigned address);
-static void awacs_burgundy_write_mvolume(unsigned address, int volume);
-static int awacs_burgundy_read_mvolume(unsigned address);
-
-/* we will allocate a single 'emergency' dbdma cmd block to use if the
- tx status comes up "DEAD". This happens on some PowerComputing Pmac
- clones, either owing to a bug in dbdma or some interaction between
- IDE and sound. However, this measure would deal with DEAD status if
- if appeared elsewhere.
-
- for the sake of memory efficiency we'll allocate this cmd as part of
- the beep cmd stuff.
-*/
-
-static volatile struct dbdma_cmd *emergency_dbdma_cmd;
-
-#ifdef CONFIG_PM
-/*
- * Stuff for restoring after a sleep.
- */
-static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when);
-struct pmu_sleep_notifier awacs_sleep_notifier = {
- awacs_sleep_notify, SLEEP_LEVEL_SOUND,
-};
-#endif /* CONFIG_PM */
-
-/* for (soft) sample rate translations */
-int expand_bal; /* Balance factor for expanding (not volume!) */
-int expand_read_bal; /* Balance factor for expanding reads (not volume!) */
-
-/*** Low level stuff *********************************************************/
-
-static void *PMacAlloc(unsigned int size, gfp_t flags);
-static void PMacFree(void *ptr, unsigned int size);
-static int PMacIrqInit(void);
-#ifdef MODULE
-static void PMacIrqCleanup(void);
-#endif
-static void PMacSilence(void);
-static void PMacInit(void);
-static int PMacSetFormat(int format);
-static int PMacSetVolume(int volume);
-static void PMacPlay(void);
-static void PMacRecord(void);
-static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid);
-static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid);
-static irqreturn_t pmac_awacs_intr(int irq, void *devid);
-static void awacs_write(int val);
-static int awacs_get_volume(int reg, int lshift);
-static int awacs_volume_setter(int volume, int n, int mute, int lshift);
-
-
-/*** Mid level stuff **********************************************************/
-
-static int PMacMixerIoctl(u_int cmd, u_long arg);
-static int PMacWriteSqSetup(void);
-static int PMacReadSqSetup(void);
-static void PMacAbortRead(void);
-
-extern TRANS transAwacsNormal ;
-extern TRANS transAwacsExpand ;
-extern TRANS transAwacsNormalRead ;
-extern TRANS transAwacsExpandRead ;
-
-extern int daca_init(void);
-extern void daca_cleanup(void);
-extern int daca_set_volume(uint left_vol, uint right_vol);
-extern void daca_get_volume(uint * left_vol, uint *right_vol);
-extern int daca_enter_sleep(void);
-extern int daca_leave_sleep(void);
-
-#define TRY_LOCK() \
- if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \
- return rc;
-#define LOCK() mutex_lock(&dmasound_mutex);
-
-#define UNLOCK() mutex_unlock(&dmasound_mutex);
-
-/* We use different versions that the ones provided in dmasound.h
- *
- * FIXME: Use different names ;)
- */
-#undef IOCTL_IN
-#undef IOCTL_OUT
-
-#define IOCTL_IN(arg, ret) \
- rc = get_user(ret, (int __user *)(arg)); \
- if (rc) break;
-#define IOCTL_OUT(arg, ret) \
- ioctl_return2((int __user *)(arg), ret)
-
-static inline int ioctl_return2(int __user *addr, int value)
-{
- return value < 0 ? value : put_user(value, addr);
-}
-
-
-/*** AE - TUMBLER / SNAPPER START ************************************************/
-
-
-int gpio_audio_reset, gpio_audio_reset_pol;
-int gpio_amp_mute, gpio_amp_mute_pol;
-int gpio_headphone_mute, gpio_headphone_mute_pol;
-int gpio_headphone_detect, gpio_headphone_detect_pol;
-int gpio_headphone_irq;
-
-int
-setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol)
-{
- struct device_node *gpiop;
- struct device_node *np;
- const u32* pp;
- int ret = -ENODEV;
-
- gpiop = of_find_node_by_name(NULL, "gpio");
- if (!gpiop)
- goto done;
-
- np = of_get_next_child(gpiop, NULL);
- while(np != 0) {
- if (name) {
- const char *property =
- of_get_property(np,"audio-gpio",NULL);
- if (property != 0 && strcmp(property,name) == 0)
- break;
- } else if (compatible && of_device_is_compatible(np, compatible))
- break;
- np = of_get_next_child(gpiop, np);
- }
- if (!np)
- goto done;
- pp = of_get_property(np, "AAPL,address", NULL);
- if (!pp)
- goto done;
- *gpio_addr = (*pp) & 0x0000ffff;
- pp = of_get_property(np, "audio-gpio-active-state", NULL);
- if (pp)
- *gpio_pol = *pp;
- else
- *gpio_pol = 1;
- ret = irq_of_parse_and_map(np, 0);
-done:
- of_node_put(np);
- of_node_put(gpiop);
- return ret;
-}
-
-static inline void
-write_audio_gpio(int gpio_addr, int data)
-{
- if (!gpio_addr)
- return;
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04);
-}
-
-static inline int
-read_audio_gpio(int gpio_addr)
-{
- if (!gpio_addr)
- return 0;
- return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
-}
-
-/*
- * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
- */
-static irqreturn_t
-headphone_intr(int irq, void *devid)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&dmasound.lock, flags);
- if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
- printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
- write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
- write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
- tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
- } else {
- printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
- write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
- write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
- tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
- }
- spin_unlock_irqrestore(&dmasound.lock, flags);
- return IRQ_HANDLED;
-}
-
-
-/* Initialize tumbler */
-
-static int
-tas_dmasound_init(void)
-{
- setup_audio_gpio(
- "audio-hw-reset",
- NULL,
- &gpio_audio_reset,
- &gpio_audio_reset_pol);
- setup_audio_gpio(
- "amp-mute",
- NULL,
- &gpio_amp_mute,
- &gpio_amp_mute_pol);
- setup_audio_gpio("headphone-mute",
- NULL,
- &gpio_headphone_mute,
- &gpio_headphone_mute_pol);
- gpio_headphone_irq = setup_audio_gpio(
- "headphone-detect",
- NULL,
- &gpio_headphone_detect,
- &gpio_headphone_detect_pol);
- /* Fix some broken OF entries in desktop machines */
- if (!gpio_headphone_irq)
- gpio_headphone_irq = setup_audio_gpio(
- NULL,
- "keywest-gpio15",
- &gpio_headphone_detect,
- &gpio_headphone_detect_pol);
-
- write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
- msleep(100);
- write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
- msleep(100);
- if (gpio_headphone_irq) {
- if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) {
- printk(KERN_ERR "tumbler: Can't request headphone interrupt\n");
- gpio_headphone_irq = 0;
- } else {
- u8 val;
- /* Activate headphone status interrupts */
- val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0);
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80);
- /* Trigger it */
- headphone_intr(0, NULL);
- }
- }
- if (!gpio_headphone_irq) {
- /* Some machine enter this case ? */
- printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n");
- write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
- write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
- }
- return 0;
-}
-
-
-static int
-tas_dmasound_cleanup(void)
-{
- if (gpio_headphone_irq)
- free_irq(gpio_headphone_irq, NULL);
- return 0;
-}
-
-/* We don't support 48k yet */
-static int tas_freqs[1] = { 44100 } ;
-static int tas_freqs_ok[1] = { 1 } ;
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int
-tas_set_frame_rate(void)
-{
- if (i2s) {
- out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
- out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
- }
- dmasound.hard.speed = 44100 ;
- awacs_rate_index = 0 ;
- return 44100 ;
-}
-
-static int
-tas_mixer_ioctl(u_int cmd, u_long arg)
-{
- int __user *argp = (int __user *)arg;
- int data;
- int rc;
-
- rc=tas_device_ioctl(cmd, arg);
- if (rc != -EINVAL) {
- return rc;
- }
-
- if ((cmd & ~0xff) == MIXER_WRITE(0) &&
- tas_supported_mixers() & (1<<(cmd & 0xff))) {
- rc = get_user(data, argp);
- if (rc<0) return rc;
- tas_set_mixer_level(cmd & 0xff, data);
- tas_get_mixer_level(cmd & 0xff, &data);
- return ioctl_return2(argp, data);
- }
- if ((cmd & ~0xff) == MIXER_READ(0) &&
- tas_supported_mixers() & (1<<(cmd & 0xff))) {
- tas_get_mixer_level(cmd & 0xff, &data);
- return ioctl_return2(argp, data);
- }
-
- switch(cmd) {
- case SOUND_MIXER_READ_DEVMASK:
- data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_STEREODEVS:
- data = tas_stereo_mixers();
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_CAPS:
- rc = IOCTL_OUT(arg, 0);
- break;
- case SOUND_MIXER_READ_RECMASK:
- // XXX FIXME: find a way to check what is really available */
- data = SOUND_MASK_LINE | SOUND_MASK_MIC;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECSRC:
- if (awacs_reg[0] & MASK_MUX_AUDIN)
- data |= SOUND_MASK_LINE;
- if (awacs_reg[0] & MASK_MUX_MIC)
- data |= SOUND_MASK_MIC;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_RECSRC:
- IOCTL_IN(arg, data);
- data =0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */
- IOCTL_IN(arg, data);
- beep_vol = data & 0xff;
- /* fall through */
- case SOUND_MIXER_READ_SPEAKER:
- rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
- break;
- case SOUND_MIXER_OUTMASK:
- case SOUND_MIXER_OUTSRC:
- default:
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-static void __init
-tas_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
- int i ;
- if (prop) {
- for (i=0; i<1; i++)
- tas_freqs_ok[i] = 0;
- for (l /= sizeof(int); l > 0; --l) {
- unsigned int r = *prop++;
- /* Apple 'Fixed' format */
- if (r >= 0x10000)
- r >>= 16;
- for (i = 0; i < 1; ++i) {
- if (r == tas_freqs[i]) {
- tas_freqs_ok[i] = 1;
- break;
- }
- }
- }
- }
- /* else we assume that all the rates are available */
-}
-
-
-/*** AE - TUMBLER / SNAPPER END ************************************************/
-
-
-
-/*** Low level stuff *********************************************************/
-
-/*
- * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA.
- */
-static void *PMacAlloc(unsigned int size, gfp_t flags)
-{
- return kmalloc(size, flags);
-}
-
-static void PMacFree(void *ptr, unsigned int size)
-{
- kfree(ptr);
-}
-
-static int __init PMacIrqInit(void)
-{
- if (awacs)
- if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL))
- return 0;
- if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL)
- || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL))
- return 0;
- return 1;
-}
-
-#ifdef MODULE
-static void PMacIrqCleanup(void)
-{
- /* turn off input & output dma */
- DBDMA_DO_STOP(awacs_txdma);
- DBDMA_DO_STOP(awacs_rxdma);
-
- if (awacs)
- /* disable interrupts from awacs interface */
- out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
-
- /* Switch off the sound clock */
- pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
- /* Make sure proper bits are set on pismo & tipb */
- if ((machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook3,2")) && awacs) {
- awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- msleep(200);
- }
- if (awacs)
- free_irq(awacs_irq, NULL);
- free_irq(awacs_tx_irq, NULL);
- free_irq(awacs_rx_irq, NULL);
-
- if (awacs)
- iounmap(awacs);
- if (i2s)
- iounmap(i2s);
- iounmap(awacs_txdma);
- iounmap(awacs_rxdma);
-
- release_mem_region(awacs_rsrc[0].start,
- awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
- release_mem_region(awacs_rsrc[1].start,
- awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
- release_mem_region(awacs_rsrc[2].start,
- awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
-
- kfree(awacs_tx_cmd_space);
- kfree(awacs_rx_cmd_space);
- kfree(beep_dbdma_cmd_space);
- kfree(beep_buf);
-#ifdef CONFIG_PM
- pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
-#endif
-}
-#endif /* MODULE */
-
-static void PMacSilence(void)
-{
- /* turn off output dma */
- DBDMA_DO_STOP(awacs_txdma);
-}
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int daca_set_frame_rate(void)
-{
- if (i2s) {
- out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
- out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
- }
- dmasound.hard.speed = 44100 ;
- awacs_rate_index = 0 ;
- return 44100 ;
-}
-
-static int awacs_freqs[8] = {
- 44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
-};
-static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
-
-static int
-awacs_set_frame_rate(int desired, int catch_r)
-{
- int tolerance, i = 8 ;
- /*
- * If we have a sample rate which is within catchRadius percent
- * of the requested value, we don't have to expand the samples.
- * Otherwise choose the next higher rate.
- * N.B.: burgundy awacs only works at 44100 Hz.
- */
- do {
- tolerance = catch_r * awacs_freqs[--i] / 100;
- if (awacs_freqs_ok[i]
- && dmasound.soft.speed <= awacs_freqs[i] + tolerance)
- break;
- } while (i > 0);
- dmasound.hard.speed = awacs_freqs[i];
- awacs_rate_index = i;
-
- out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 );
- awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3);
- awacs_write(awacs_reg[1] | MASK_ADDR1);
- return dmasound.hard.speed;
-}
-
-static int
-burgundy_set_frame_rate(void)
-{
- awacs_rate_index = 0 ;
- awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
- /* XXX disable error interrupt on burgundy for now */
- out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE);
- return 44100 ;
-}
-
-static int
-set_frame_rate(int desired, int catch_r)
-{
- switch (awacs_revision) {
- case AWACS_BURGUNDY:
- dmasound.hard.speed = burgundy_set_frame_rate();
- break ;
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- dmasound.hard.speed = tas_set_frame_rate();
- break ;
- case AWACS_DACA:
- dmasound.hard.speed =
- daca_set_frame_rate();
- break ;
- default:
- dmasound.hard.speed = awacs_set_frame_rate(desired,
- catch_r);
- break ;
- }
- return dmasound.hard.speed ;
-}
-
-static void
-awacs_recalibrate(void)
-{
- /* Sorry for the horrible delays... I hope to get that improved
- * by making the whole PM process asynchronous in a future version
- */
- msleep(750);
- awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE;
- awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1);
- msleep(1000);
- awacs_write(awacs_reg[1] | MASK_ADDR1);
-}
-
-static void PMacInit(void)
-{
- int tolerance;
-
- switch (dmasound.soft.format) {
- case AFMT_S16_LE:
- case AFMT_U16_LE:
- if (hw_can_byteswap)
- dmasound.hard.format = AFMT_S16_LE;
- else
- dmasound.hard.format = AFMT_S16_BE;
- break;
- default:
- dmasound.hard.format = AFMT_S16_BE;
- break;
- }
- dmasound.hard.stereo = 1;
- dmasound.hard.size = 16;
-
- /* set dmasound.hard.speed - on the basis of what we want (soft)
- * and the tolerance we'll allow.
- */
- set_frame_rate(dmasound.soft.speed, catchRadius) ;
-
- tolerance = (catchRadius * dmasound.hard.speed) / 100;
- if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) {
- dmasound.trans_write = &transAwacsNormal;
- dmasound.trans_read = &transAwacsNormalRead;
- } else {
- dmasound.trans_write = &transAwacsExpand;
- dmasound.trans_read = &transAwacsExpandRead;
- }
-
- if (awacs) {
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
- }
-
- expand_bal = -dmasound.soft.speed;
- expand_read_bal = -dmasound.soft.speed;
-}
-
-static int PMacSetFormat(int format)
-{
- int size;
- int req_format = format;
-
- switch (format) {
- case AFMT_QUERY:
- return dmasound.soft.format;
- case AFMT_MU_LAW:
- case AFMT_A_LAW:
- case AFMT_U8:
- case AFMT_S8:
- size = 8;
- break;
- case AFMT_S16_LE:
- if(!hw_can_byteswap)
- format = AFMT_S16_BE;
- case AFMT_S16_BE:
- size = 16;
- break;
- case AFMT_U16_LE:
- if(!hw_can_byteswap)
- format = AFMT_U16_BE;
- case AFMT_U16_BE:
- size = 16;
- break;
- default: /* :-) */
- printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
- format);
- size = 8;
- format = AFMT_U8;
- }
-
- if (req_format == format) {
- dmasound.soft.format = format;
- dmasound.soft.size = size;
- if (dmasound.minDev == SND_DEV_DSP) {
- dmasound.dsp.format = format;
- dmasound.dsp.size = size;
- }
- }
-
- return format;
-}
-
-#define AWACS_VOLUME_TO_MASK(x) (15 - ((((x) - 1) * 15) / 99))
-#define AWACS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 15))
-
-static int awacs_get_volume(int reg, int lshift)
-{
- int volume;
-
- volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf);
- volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8;
- return volume;
-}
-
-static int awacs_volume_setter(int volume, int n, int mute, int lshift)
-{
- int r1, rn;
-
- if (mute && volume == 0) {
- r1 = awacs_reg[1] | mute;
- } else {
- r1 = awacs_reg[1] & ~mute;
- rn = awacs_reg[n] & ~(0xf | (0xf << lshift));
- rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift);
- rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf;
- awacs_reg[n] = rn;
- awacs_write((n << 12) | rn);
- volume = awacs_get_volume(rn, lshift);
- }
- if (r1 != awacs_reg[1]) {
- awacs_reg[1] = r1;
- awacs_write(r1 | MASK_ADDR1);
- }
- return volume;
-}
-
-static int PMacSetVolume(int volume)
-{
- printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
- return 0;
-}
-
-static void awacs_setup_for_beep(int speed)
-{
- out_le32(&awacs->control,
- (in_le32(&awacs->control) & ~0x1f00)
- | ((speed > 0 ? speed : awacs_rate_index) << 8));
-
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
-}
-
-/* CHECK: how much of this *really* needs IRQs masked? */
-static void __PMacPlay(void)
-{
- volatile struct dbdma_cmd *cp;
- int next_frg, count;
-
- count = 300 ; /* > two cycles at the lowest sample rate */
-
- /* what we want to send next */
- next_frg = (write_sq.front + write_sq.active) % write_sq.max_count;
-
- if (awacs_beep_state) {
- /* sound takes precedence over beeps */
- /* stop the dma channel */
- out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
- while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
- udelay(1);
- if (awacs)
- awacs_setup_for_beep(-1);
- out_le32(&awacs_txdma->cmdptr,
- virt_to_bus(&(awacs_tx_cmds[next_frg])));
-
- beep_playing = 0;
- awacs_beep_state = 0;
- }
- /* this won't allow more than two frags to be in the output queue at
- once. (or one, if the max frags is 2 - because count can't exceed
- 2 in that case)
- */
- while (write_sq.active < 2 && write_sq.active < write_sq.count) {
- count = (write_sq.count == write_sq.active + 1) ?
- write_sq.rear_size:write_sq.block_size ;
- if (count < write_sq.block_size) {
- if (!write_sq.syncing) /* last block not yet filled,*/
- break; /* and we're not syncing or POST-ed */
- else {
- /* pretend the block is full to force a new
- block to be started on the next write */
- write_sq.rear_size = write_sq.block_size ;
- write_sq.syncing &= ~2 ; /* clear POST */
- }
- }
- cp = &awacs_tx_cmds[next_frg];
- st_le16(&cp->req_count, count);
- st_le16(&cp->xfer_status, 0);
- st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS);
- /* put a STOP at the end of the queue - but only if we have
- space for it. This means that, if we under-run and we only
- have two fragments, we might re-play sound from an existing
- queued frag. I guess the solution to that is not to set two
- frags if you are likely to under-run...
- */
- if (write_sq.count < write_sq.max_count) {
- if (++next_frg >= write_sq.max_count)
- next_frg = 0 ; /* wrap */
- /* if we get here then we've underrun so we will stop*/
- st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP);
- }
- /* set the dbdma controller going, if it is not already */
- if (write_sq.active == 0)
- out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
- (void)in_le32(&awacs_txdma->status);
- out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
- ++write_sq.active;
- }
-}
-
-static void PMacPlay(void)
-{
- LOCK();
- if (!awacs_sleeping) {
- unsigned long flags;
-
- spin_lock_irqsave(&dmasound.lock, flags);
- __PMacPlay();
- spin_unlock_irqrestore(&dmasound.lock, flags);
- }
- UNLOCK();
-}
-
-static void PMacRecord(void)
-{
- unsigned long flags;
-
- if (read_sq.active)
- return;
-
- spin_lock_irqsave(&dmasound.lock, flags);
-
- /* This is all we have to do......Just start it up.
- */
- out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE));
- read_sq.active = 1;
-
- spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-/* if the TX status comes up "DEAD" - reported on some Power Computing machines
- we need to re-start the dbdma - but from a different physical start address
- and with a different transfer length. It would get very messy to do this
- with the normal dbdma_cmd blocks - we would have to re-write the buffer start
- addresses each time. So, we will keep a single dbdma_cmd block which can be
- fiddled with.
- When DEAD status is first reported the content of the faulted dbdma block is
- copied into the emergency buffer and we note that the buffer is in use.
- we then bump the start physical address by the amount that was successfully
- output before it died.
- On any subsequent DEAD result we just do the bump-ups (we know that we are
- already using the emergency dbdma_cmd).
- CHECK: this just tries to "do it". It is possible that we should abandon
- xfers when the number of residual bytes gets below a certain value - I can
- see that this might cause a loop-forever if too small a transfer causes
- DEAD status. However this is a TODO for now - we'll see what gets reported.
- When we get a successful transfer result with the emergency buffer we just
- pretend that it completed using the original dmdma_cmd and carry on. The
- 'next_cmd' field will already point back to the original loop of blocks.
-*/
-
-static irqreturn_t
-pmac_awacs_tx_intr(int irq, void *devid)
-{
- int i = write_sq.front;
- int stat;
- int i_nowrap = write_sq.front;
- volatile struct dbdma_cmd *cp;
- /* != 0 when we are dealing with a DEAD xfer */
- static int emergency_in_use;
-
- spin_lock(&dmasound.lock);
- while (write_sq.active > 0) { /* we expect to have done something*/
- if (emergency_in_use) /* we are dealing with DEAD xfer */
- cp = emergency_dbdma_cmd ;
- else
- cp = &awacs_tx_cmds[i];
- stat = ld_le16(&cp->xfer_status);
- if (stat & DEAD) {
- unsigned short req, res ;
- unsigned int phy ;
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ;
-#endif
- /* to clear DEAD status we must first clear RUN
- set it to quiescent to be on the safe side */
- (void)in_le32(&awacs_txdma->status);
- out_le32(&awacs_txdma->control,
- (RUN|PAUSE|FLUSH|WAKE) << 16);
- write_sq.died++ ;
- if (!emergency_in_use) { /* new problem */
- memcpy((void *)emergency_dbdma_cmd, (void *)cp,
- sizeof(struct dbdma_cmd));
- emergency_in_use = 1;
- cp = emergency_dbdma_cmd;
- }
- /* now bump the values to reflect the amount
- we haven't yet shifted */
- req = ld_le16(&cp->req_count);
- res = ld_le16(&cp->res_count);
- phy = ld_le32(&cp->phy_addr);
- phy += (req - res);
- st_le16(&cp->req_count, res);
- st_le16(&cp->res_count, 0);
- st_le16(&cp->xfer_status, 0);
- st_le32(&cp->phy_addr, phy);
- st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count]));
- st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS);
-
- /* point at our patched up command block */
- out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp));
- /* we must re-start the controller */
- (void)in_le32(&awacs_txdma->status);
- /* should complete clearing the DEAD status */
- out_le32(&awacs_txdma->control,
- ((RUN|WAKE) << 16) + (RUN|WAKE));
- break; /* this block is still going */
- }
- if ((stat & ACTIVE) == 0)
- break; /* this frame is still going */
- if (emergency_in_use)
- emergency_in_use = 0 ; /* done that */
- --write_sq.count;
- --write_sq.active;
- i_nowrap++;
- if (++i >= write_sq.max_count)
- i = 0;
- }
-
- /* if we stopped and we were not sync-ing - then we under-ran */
- if( write_sq.syncing == 0 ){
- stat = in_le32(&awacs_txdma->status) ;
- /* we hit the dbdma_stop */
- if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ;
- }
-
- /* if we used some data up then wake the writer to supply some more*/
- if (i_nowrap != write_sq.front)
- WAKE_UP(write_sq.action_queue);
- write_sq.front = i;
-
- /* but make sure we funnel what we've already got */\
- if (!awacs_sleeping)
- __PMacPlay();
-
- /* make the wake-on-empty conditional on syncing */
- if (!write_sq.active && (write_sq.syncing & 1))
- WAKE_UP(write_sq.sync_queue); /* any time we're empty */
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-pmac_awacs_rx_intr(int irq, void *devid)
-{
- int stat ;
- /* For some reason on my PowerBook G3, I get one interrupt
- * when the interrupt vector is installed (like something is
- * pending). This happens before the dbdma is initialized by
- * us, so I just check the command pointer and if it is zero,
- * just blow it off.
- */
- if (in_le32(&awacs_rxdma->cmdptr) == 0)
- return IRQ_HANDLED;
-
- /* We also want to blow 'em off when shutting down.
- */
- if (read_sq.active == 0)
- return IRQ_HANDLED;
-
- spin_lock(&dmasound.lock);
- /* Check multiple buffers in case we were held off from
- * interrupt processing for a long time. Geeze, I really hope
- * this doesn't happen.
- */
- while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) {
-
- /* if we got a "DEAD" status then just log it for now.
- and try to restart dma.
- TODO: figure out how best to fix it up
- */
- if (stat & DEAD){
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n");
-#endif
- /* to clear DEAD status we must first clear RUN
- set it to quiescent to be on the safe side */
- (void)in_le32(&awacs_txdma->status);
- out_le32(&awacs_txdma->control,
- (RUN|PAUSE|FLUSH|WAKE) << 16);
- awacs_rx_cmds[read_sq.rear].xfer_status = 0;
- awacs_rx_cmds[read_sq.rear].res_count = 0;
- read_sq.died++ ;
- (void)in_le32(&awacs_txdma->status);
- /* re-start the same block */
- out_le32(&awacs_rxdma->cmdptr,
- virt_to_bus(&awacs_rx_cmds[read_sq.rear]));
- /* we must re-start the controller */
- (void)in_le32(&awacs_rxdma->status);
- /* should complete clearing the DEAD status */
- out_le32(&awacs_rxdma->control,
- ((RUN|WAKE) << 16) + (RUN|WAKE));
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED; /* try this block again */
- }
- /* Clear status and move on to next buffer.
- */
- awacs_rx_cmds[read_sq.rear].xfer_status = 0;
- read_sq.rear++;
-
- /* Wrap the buffer ring.
- */
- if (read_sq.rear >= read_sq.max_active)
- read_sq.rear = 0;
-
- /* If we have caught up to the front buffer, bump it.
- * This will cause weird (but not fatal) results if the
- * read loop is currently using this buffer. The user is
- * behind in this case anyway, so weird things are going
- * to happen.
- */
- if (read_sq.rear == read_sq.front) {
- read_sq.front++;
- read_sq.xruns++ ; /* we overan */
- if (read_sq.front >= read_sq.max_active)
- read_sq.front = 0;
- }
- }
-
- WAKE_UP(read_sq.action_queue);
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED;
-}
-
-
-static irqreturn_t
-pmac_awacs_intr(int irq, void *devid)
-{
- int ctrl;
- int status;
- int r1;
-
- spin_lock(&dmasound.lock);
- ctrl = in_le32(&awacs->control);
- status = in_le32(&awacs->codec_stat);
-
- if (ctrl & MASK_PORTCHG) {
- /* tested on Screamer, should work on others too */
- if (awacs_revision == AWACS_SCREAMER) {
- if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
- hdp_connected = 1;
-
- r1 = awacs_reg[1] | MASK_SPKMUTE;
- awacs_reg[1] = r1;
- awacs_write(r1 | MASK_ADDR_MUTE);
- } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
- hdp_connected = 0;
-
- r1 = awacs_reg[1] & ~MASK_SPKMUTE;
- awacs_reg[1] = r1;
- awacs_write(r1 | MASK_ADDR_MUTE);
- }
- }
- }
- if (ctrl & MASK_CNTLERR) {
- int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
- /* CHECK: we just swallow burgundy errors at the moment..*/
- if (err != 0 && awacs_revision != AWACS_BURGUNDY)
- printk(KERN_ERR "dmasound_pmac: error %x\n", err);
- }
- /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */
- out_le32(&awacs->control, ctrl);
- spin_unlock(&dmasound.lock);
- return IRQ_HANDLED;
-}
-
-static void
-awacs_write(int val)
-{
- int count = 300 ;
- if (awacs_revision >= AWACS_DACA || !awacs)
- return ;
-
- while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
- udelay(1) ; /* timeout is > 2 samples at lowest rate */
- out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22));
- (void)in_le32(&awacs->byteswap);
-}
-
-/* this is called when the beep timer expires... it will be called even
- if the beep has been overidden by other sound output.
-*/
-static void awacs_nosound(unsigned long xx)
-{
- unsigned long flags;
- int count = 600 ; /* > four samples at lowest rate */
-
- spin_lock_irqsave(&dmasound.lock, flags);
- if (beep_playing) {
- st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
- out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
- while ((in_le32(&awacs_txdma->status) & RUN) && count--)
- udelay(1);
- if (awacs)
- awacs_setup_for_beep(-1);
- beep_playing = 0;
- }
- spin_unlock_irqrestore(&dmasound.lock, flags);
-}
-
-/*
- * We generate the beep with a single dbdma command that loops a buffer
- * forever - without generating interrupts.
- *
- * So, to stop it you have to stop dma output as per awacs_nosound.
- */
-static int awacs_beep_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int hz)
-{
- unsigned long flags;
- int beep_speed = 0;
- int srate;
- int period, ncycles, nsamples;
- int i, j, f;
- short *p;
- static int beep_hz_cache;
- static int beep_nsamples_cache;
- static int beep_volume_cache;
-
- if (type != EV_SND)
- return -1;
- switch (code) {
- case SND_BELL:
- if (hz)
- hz = 1000;
- break;
- case SND_TONE:
- break;
- default:
- return -1;
- }
-
- if (beep_buf == NULL)
- return -1;
-
- /* quick-hack fix for DACA, Burgundy & Tumbler */
-
- if (awacs_revision >= AWACS_DACA){
- srate = 44100 ;
- } else {
- for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i)
- if (awacs_freqs_ok[i])
- beep_speed = i;
- srate = awacs_freqs[beep_speed];
- }
-
- if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
- /* cancel beep currently playing */
- awacs_nosound(0);
- return 0;
- }
-
- spin_lock_irqsave(&dmasound.lock, flags);
- if (beep_playing || write_sq.active || beep_buf == NULL) {
- spin_unlock_irqrestore(&dmasound.lock, flags);
- return -1; /* too hard, sorry :-( */
- }
- beep_playing = 1;
- st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
- spin_unlock_irqrestore(&dmasound.lock, flags);
-
- if (hz == beep_hz_cache && beep_vol == beep_volume_cache) {
- nsamples = beep_nsamples_cache;
- } else {
- period = srate * 256 / hz; /* fixed point */
- ncycles = BEEP_BUFLEN * 256 / period;
- nsamples = (period * ncycles) >> 8;
- f = ncycles * 65536 / nsamples;
- j = 0;
- p = beep_buf;
- for (i = 0; i < nsamples; ++i, p += 2) {
- p[0] = p[1] = beep_wform[j >> 8] * beep_vol;
- j = (j + f) & 0xffff;
- }
- beep_hz_cache = hz;
- beep_volume_cache = beep_vol;
- beep_nsamples_cache = nsamples;
- }
-
- st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
- st_le16(&beep_dbdma_cmd->xfer_status, 0);
- st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
- st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
- awacs_beep_state = 1;
-
- spin_lock_irqsave(&dmasound.lock, flags);
- if (beep_playing) { /* i.e. haven't been terminated already */
- int count = 300 ;
- out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
- while ((in_le32(&awacs_txdma->status) & RUN) && count--)
- udelay(1); /* timeout > 2 samples at lowest rate*/
- if (awacs)
- awacs_setup_for_beep(beep_speed);
- out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
- (void)in_le32(&awacs_txdma->status);
- out_le32(&awacs_txdma->control, RUN | (RUN << 16));
- }
- spin_unlock_irqrestore(&dmasound.lock, flags);
-
- return 0;
-}
-
-/* used in init and for wake-up */
-
-static void
-load_awacs(void)
-{
- awacs_write(awacs_reg[0] + MASK_ADDR0);
- awacs_write(awacs_reg[1] + MASK_ADDR1);
- awacs_write(awacs_reg[2] + MASK_ADDR2);
- awacs_write(awacs_reg[4] + MASK_ADDR4);
-
- if (awacs_revision == AWACS_SCREAMER) {
- awacs_write(awacs_reg[5] + MASK_ADDR5);
- msleep(100);
- awacs_write(awacs_reg[6] + MASK_ADDR6);
- msleep(2);
- awacs_write(awacs_reg[1] + MASK_ADDR1);
- awacs_write(awacs_reg[7] + MASK_ADDR7);
- }
- if (awacs) {
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
- }
-}
-
-#ifdef CONFIG_PM
-/*
- * Save state when going to sleep, restore it afterwards.
- */
-/* FIXME: sort out disabling/re-enabling of read stuff as well */
-static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
- unsigned long flags;
-
- switch (when) {
- case PBOOK_SLEEP_NOW:
- LOCK();
- awacs_sleeping = 1;
- /* Tell the rest of the driver we are now going to sleep */
- mb();
- if (awacs_revision == AWACS_SCREAMER ||
- awacs_revision == AWACS_AWACS) {
- awacs_reg1_save = awacs_reg[1];
- awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE;
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- }
-
- PMacSilence();
- /* stop rx - if going - a bit of a daft user... but */
- out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
- /* deny interrupts */
- if (awacs)
- disable_irq(awacs_irq);
- disable_irq(awacs_tx_irq);
- disable_irq(awacs_rx_irq);
- /* Chip specific sleep code */
- switch (awacs_revision) {
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
- write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
- tas_enter_sleep();
- write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
- break ;
- case AWACS_DACA:
- daca_enter_sleep();
- break ;
- case AWACS_BURGUNDY:
- break ;
- case AWACS_SCREAMER:
- case AWACS_AWACS:
- default:
- out_le32(&awacs->control, 0x11) ;
- break ;
- }
- /* Disable sound clock */
- pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
- /* According to Darwin, we do that after turning off the sound
- * chip clock. All this will have to be cleaned up once we properly
- * parse the OF sound-objects
- */
- if ((machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook3,2")) && awacs) {
- awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- msleep(200);
- }
- break;
- case PBOOK_WAKE:
- /* Enable sound clock */
- pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
- if ((machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook3,2")) && awacs) {
- msleep(100);
- awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- msleep(300);
- } else
- msleep(1000);
- /* restore settings */
- switch (awacs_revision) {
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
- write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
- write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
- msleep(100);
- write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
- msleep(150);
- tas_leave_sleep(); /* Stub for now */
- headphone_intr(0, NULL);
- break;
- case AWACS_DACA:
- msleep(10); /* Check this !!! */
- daca_leave_sleep();
- break ; /* dont know how yet */
- case AWACS_BURGUNDY:
- break ;
- case AWACS_SCREAMER:
- case AWACS_AWACS:
- default:
- load_awacs() ;
- break ;
- }
- /* Recalibrate chip */
- if (awacs_revision == AWACS_SCREAMER && awacs)
- awacs_recalibrate();
- /* Make sure dma is stopped */
- PMacSilence();
- if (awacs)
- enable_irq(awacs_irq);
- enable_irq(awacs_tx_irq);
- enable_irq(awacs_rx_irq);
- if (awacs) {
- /* OK, allow ints back again */
- out_le32(&awacs->control, MASK_IEPC
- | (awacs_rate_index << 8) | 0x11
- | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
- }
- if (macio_base && is_pbook_g3) {
- /* FIXME: should restore the setup we had...*/
- out_8(macio_base + 0x37, 3);
- } else if (is_pbook_3X00) {
- in_8(latch_base + 0x190);
- }
- /* Remove mute */
- if (awacs_revision == AWACS_SCREAMER ||
- awacs_revision == AWACS_AWACS) {
- awacs_reg[1] = awacs_reg1_save;
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- }
- awacs_sleeping = 0;
- /* Resume pending sounds. */
- /* we don't try to restart input... */
- spin_lock_irqsave(&dmasound.lock, flags);
- __PMacPlay();
- spin_unlock_irqrestore(&dmasound.lock, flags);
- UNLOCK();
- }
-}
-#endif /* CONFIG_PM */
-
-
-/* All the burgundy functions: */
-
-/* Waits for busy flag to clear */
-static inline void
-awacs_burgundy_busy_wait(void)
-{
- int count = 50; /* > 2 samples at 44k1 */
- while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
- udelay(1) ;
-}
-
-static inline void
-awacs_burgundy_extend_wait(void)
-{
- int count = 50 ; /* > 2 samples at 44k1 */
- while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--)
- udelay(1) ;
- count = 50;
- while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--)
- udelay(1);
-}
-
-static void
-awacs_burgundy_wcw(unsigned addr, unsigned val)
-{
- out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
- awacs_burgundy_busy_wait();
- out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff));
- awacs_burgundy_busy_wait();
- out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff));
- awacs_burgundy_busy_wait();
- out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff));
- awacs_burgundy_busy_wait();
-}
-
-static unsigned
-awacs_burgundy_rcw(unsigned addr)
-{
- unsigned val = 0;
- unsigned long flags;
-
- /* should have timeouts here */
- spin_lock_irqsave(&dmasound.lock, flags);
-
- out_le32(&awacs->codec_ctrl, addr + 0x100000);
- awacs_burgundy_busy_wait();
- awacs_burgundy_extend_wait();
- val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
-
- out_le32(&awacs->codec_ctrl, addr + 0x100100);
- awacs_burgundy_busy_wait();
- awacs_burgundy_extend_wait();
- val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8;
-
- out_le32(&awacs->codec_ctrl, addr + 0x100200);
- awacs_burgundy_busy_wait();
- awacs_burgundy_extend_wait();
- val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16;
-
- out_le32(&awacs->codec_ctrl, addr + 0x100300);
- awacs_burgundy_busy_wait();
- awacs_burgundy_extend_wait();
- val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24;
-
- spin_unlock_irqrestore(&dmasound.lock, flags);
-
- return val;
-}
-
-
-static void
-awacs_burgundy_wcb(unsigned addr, unsigned val)
-{
- out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
- awacs_burgundy_busy_wait();
-}
-
-static unsigned
-awacs_burgundy_rcb(unsigned addr)
-{
- unsigned val = 0;
- unsigned long flags;
-
- /* should have timeouts here */
- spin_lock_irqsave(&dmasound.lock, flags);
-
- out_le32(&awacs->codec_ctrl, addr + 0x100000);
- awacs_burgundy_busy_wait();
- awacs_burgundy_extend_wait();
- val += (in_le32(&awacs->codec_stat) >> 4) & 0xff;
-
- spin_unlock_irqrestore(&dmasound.lock, flags);
-
- return val;
-}
-
-static int
-awacs_burgundy_check(void)
-{
- /* Checks to see the chip is alive and kicking */
- int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE;
-
- return error == 0xf0000;
-}
-
-static int
-awacs_burgundy_init(void)
-{
- if (awacs_burgundy_check()) {
- printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n");
- return 1;
- }
-
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES,
- DEF_BURGUNDY_OUTPUTENABLES);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- DEF_BURGUNDY_MORE_OUTPUTENABLES);
- awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS,
- DEF_BURGUNDY_OUTPUTSELECTS);
-
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21,
- DEF_BURGUNDY_INPSEL21);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3,
- DEF_BURGUNDY_INPSEL3);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD,
- DEF_BURGUNDY_GAINCD);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE,
- DEF_BURGUNDY_GAINLINE);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC,
- DEF_BURGUNDY_GAINMIC);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM,
- DEF_BURGUNDY_GAINMODEM);
-
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER,
- DEF_BURGUNDY_ATTENSPEAKER);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT,
- DEF_BURGUNDY_ATTENLINEOUT);
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP,
- DEF_BURGUNDY_ATTENHP);
-
- awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME,
- DEF_BURGUNDY_MASTER_VOLUME);
- awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD,
- DEF_BURGUNDY_VOLCD);
- awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE,
- DEF_BURGUNDY_VOLLINE);
- awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC,
- DEF_BURGUNDY_VOLMIC);
- return 0;
-}
-
-static void
-awacs_burgundy_write_volume(unsigned address, int volume)
-{
- int hardvolume,lvolume,rvolume;
-
- lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0;
- rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0;
-
- hardvolume = lvolume + (rvolume << 16);
-
- awacs_burgundy_wcw(address, hardvolume);
-}
-
-static int
-awacs_burgundy_read_volume(unsigned address)
-{
- int softvolume,wvolume;
-
- wvolume = awacs_burgundy_rcw(address);
-
- softvolume = (wvolume & 0xff) - 155;
- softvolume += (((wvolume >> 16) & 0xff) - 155)<<8;
-
- return softvolume > 0 ? softvolume : 0;
-}
-
-static int
-awacs_burgundy_read_mvolume(unsigned address)
-{
- int lvolume,rvolume,wvolume;
-
- wvolume = awacs_burgundy_rcw(address);
-
- wvolume &= 0xffff;
-
- rvolume = (wvolume & 0xff) - 155;
- lvolume = ((wvolume & 0xff00)>>8) - 155;
-
- return lvolume + (rvolume << 8);
-}
-
-static void
-awacs_burgundy_write_mvolume(unsigned address, int volume)
-{
- int lvolume,rvolume,hardvolume;
-
- lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0;
- rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0;
-
- hardvolume = lvolume + (rvolume << 8);
- hardvolume += (hardvolume << 16);
-
- awacs_burgundy_wcw(address, hardvolume);
-}
-
-/* End burgundy functions */
-
-/* Set up output volumes on machines with the 'perch/whisper' extension card.
- * this has an SGS i2c chip (7433) which is accessed using the cuda.
- *
- * TODO: split this out and make use of the other parts of the SGS chip to
- * do Bass, Treble etc.
- */
-
-static void
-awacs_enable_amp(int spkr_vol)
-{
-#ifdef CONFIG_ADB_CUDA
- struct adb_request req;
-
- if (sys_ctrler != SYS_CTRLER_CUDA)
- return;
-
- /* turn on headphones */
- cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
- 0x8a, 4, 0);
- while (!req.complete) cuda_poll();
- cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
- 0x8a, 6, 0);
- while (!req.complete) cuda_poll();
-
- /* turn on speaker */
- cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
- 0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100);
- while (!req.complete) cuda_poll();
- cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
- 0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100);
- while (!req.complete) cuda_poll();
-
- cuda_request(&req, NULL, 5, CUDA_PACKET,
- CUDA_GET_SET_IIC, 0x8a, 1, 0x29);
- while (!req.complete) cuda_poll();
-#endif /* CONFIG_ADB_CUDA */
-}
-
-
-/*** Mid level stuff *********************************************************/
-
-
-/*
- * /dev/mixer abstraction
- */
-
-static void do_line_lev(int data)
-{
- line_lev = data ;
- awacs_reg[0] &= ~MASK_MUX_AUDIN;
- if ((data & 0xff) >= 50)
- awacs_reg[0] |= MASK_MUX_AUDIN;
- awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_ip_gain(int data)
-{
- ip_gain = data ;
- data &= 0xff;
- awacs_reg[0] &= ~MASK_GAINLINE;
- if (awacs_revision == AWACS_SCREAMER) {
- awacs_reg[6] &= ~MASK_MIC_BOOST ;
- if (data >= 33) {
- awacs_reg[0] |= MASK_GAINLINE;
- if( data >= 66)
- awacs_reg[6] |= MASK_MIC_BOOST ;
- }
- awacs_write(MASK_ADDR6 | awacs_reg[6]) ;
- } else {
- if (data >= 50)
- awacs_reg[0] |= MASK_GAINLINE;
- }
- awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_mic_lev(int data)
-{
- mic_lev = data ;
- data &= 0xff;
- awacs_reg[0] &= ~MASK_MUX_MIC;
- if (data >= 50)
- awacs_reg[0] |= MASK_MUX_MIC;
- awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_cd_lev(int data)
-{
- cd_lev = data ;
- awacs_reg[0] &= ~MASK_MUX_CD;
- if ((data & 0xff) >= 50)
- awacs_reg[0] |= MASK_MUX_CD;
- awacs_write(MASK_ADDR0 | awacs_reg[0]);
-}
-
-static void do_rec_lev(int data)
-{
- int left, right ;
- rec_lev = data ;
- /* need to fudge this to use the volume setter routine */
- left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ;
- right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ;
- left |= (right << 8 );
- left = awacs_volume_setter(left, 0, 0, 4);
-}
-
-static void do_passthru_vol(int data)
-{
- passthru_vol = data ;
- awacs_reg[1] &= ~MASK_LOOPTHRU;
- if (awacs_revision == AWACS_SCREAMER) {
- if( data ) { /* switch it on for non-zero */
- awacs_reg[1] |= MASK_LOOPTHRU;
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- }
- data = awacs_volume_setter(data, 5, 0, 6) ;
- } else {
- if ((data & 0xff) >= 50)
- awacs_reg[1] |= MASK_LOOPTHRU;
- awacs_write(MASK_ADDR1 | awacs_reg[1]);
- data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;
- }
-}
-
-static int awacs_mixer_ioctl(u_int cmd, u_long arg)
-{
- int data;
- int rc;
-
- switch (cmd) {
- case SOUND_MIXER_READ_CAPS:
- /* say we will allow multiple inputs? prob. wrong
- so I'm switching it to single */
- return IOCTL_OUT(arg, 1);
- case SOUND_MIXER_READ_DEVMASK:
- data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
- | SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD
- | SOUND_MASK_IGAIN | SOUND_MASK_RECLEV
- | SOUND_MASK_ALTPCM
- | SOUND_MASK_MONITOR;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECMASK:
- data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECSRC:
- data = 0;
- if (awacs_reg[0] & MASK_MUX_AUDIN)
- data |= SOUND_MASK_LINE;
- if (awacs_reg[0] & MASK_MUX_MIC)
- data |= SOUND_MASK_MIC;
- if (awacs_reg[0] & MASK_MUX_CD)
- data |= SOUND_MASK_CD;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_RECSRC:
- IOCTL_IN(arg, data);
- data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD);
- awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
- | MASK_MUX_AUDIN);
- if (data & SOUND_MASK_LINE)
- awacs_reg[0] |= MASK_MUX_AUDIN;
- if (data & SOUND_MASK_MIC)
- awacs_reg[0] |= MASK_MUX_MIC;
- if (data & SOUND_MASK_CD)
- awacs_reg[0] |= MASK_MUX_CD;
- awacs_write(awacs_reg[0] | MASK_ADDR0);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_STEREODEVS:
- data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV ;
- if (awacs_revision == AWACS_SCREAMER)
- data |= SOUND_MASK_MONITOR ;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- line_vol = data ;
- awacs_volume_setter(data, 2, 0, 6);
- /* fall through */
- case SOUND_MIXER_READ_VOLUME:
- rc = IOCTL_OUT(arg, line_vol);
- break;
- case SOUND_MIXER_WRITE_SPEAKER:
- IOCTL_IN(arg, data);
- spk_vol = data ;
- if (has_perch)
- awacs_enable_amp(data);
- else
- (void)awacs_volume_setter(data, 4, MASK_CMUTE, 6);
- /* fall though */
- case SOUND_MIXER_READ_SPEAKER:
- rc = IOCTL_OUT(arg, spk_vol);
- break;
- case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
- IOCTL_IN(arg, data);
- beep_vol = data & 0xff;
- /* fall through */
- case SOUND_MIXER_READ_ALTPCM:
- rc = IOCTL_OUT(arg, beep_vol);
- break;
- case SOUND_MIXER_WRITE_LINE:
- IOCTL_IN(arg, data);
- do_line_lev(data) ;
- /* fall through */
- case SOUND_MIXER_READ_LINE:
- rc = IOCTL_OUT(arg, line_lev);
- break;
- case SOUND_MIXER_WRITE_IGAIN:
- IOCTL_IN(arg, data);
- do_ip_gain(data) ;
- /* fall through */
- case SOUND_MIXER_READ_IGAIN:
- rc = IOCTL_OUT(arg, ip_gain);
- break;
- case SOUND_MIXER_WRITE_MIC:
- IOCTL_IN(arg, data);
- do_mic_lev(data);
- /* fall through */
- case SOUND_MIXER_READ_MIC:
- rc = IOCTL_OUT(arg, mic_lev);
- break;
- case SOUND_MIXER_WRITE_CD:
- IOCTL_IN(arg, data);
- do_cd_lev(data);
- /* fall through */
- case SOUND_MIXER_READ_CD:
- rc = IOCTL_OUT(arg, cd_lev);
- break;
- case SOUND_MIXER_WRITE_RECLEV:
- IOCTL_IN(arg, data);
- do_rec_lev(data) ;
- /* fall through */
- case SOUND_MIXER_READ_RECLEV:
- rc = IOCTL_OUT(arg, rec_lev);
- break;
- case MIXER_WRITE(SOUND_MIXER_MONITOR):
- IOCTL_IN(arg, data);
- do_passthru_vol(data) ;
- /* fall through */
- case MIXER_READ(SOUND_MIXER_MONITOR):
- rc = IOCTL_OUT(arg, passthru_vol);
- break;
- default:
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-static void awacs_mixer_init(void)
-{
- awacs_volume_setter(line_vol, 2, 0, 6);
- if (has_perch)
- awacs_enable_amp(spk_vol);
- else
- (void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6);
- do_line_lev(line_lev) ;
- do_ip_gain(ip_gain) ;
- do_mic_lev(mic_lev) ;
- do_cd_lev(cd_lev) ;
- do_rec_lev(rec_lev) ;
- do_passthru_vol(passthru_vol) ;
-}
-
-static int burgundy_mixer_ioctl(u_int cmd, u_long arg)
-{
- int data;
- int rc;
-
- /* We are, we are, we are... Burgundy or better */
- switch(cmd) {
- case SOUND_MIXER_READ_DEVMASK:
- data = SOUND_MASK_VOLUME | SOUND_MASK_CD |
- SOUND_MASK_LINE | SOUND_MASK_MIC |
- SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECMASK:
- data = SOUND_MASK_LINE | SOUND_MASK_MIC
- | SOUND_MASK_CD;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECSRC:
- data = 0;
- if (awacs_reg[0] & MASK_MUX_AUDIN)
- data |= SOUND_MASK_LINE;
- if (awacs_reg[0] & MASK_MUX_MIC)
- data |= SOUND_MASK_MIC;
- if (awacs_reg[0] & MASK_MUX_CD)
- data |= SOUND_MASK_CD;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_RECSRC:
- IOCTL_IN(arg, data);
- data &= (SOUND_MASK_LINE
- | SOUND_MASK_MIC | SOUND_MASK_CD);
- awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC
- | MASK_MUX_AUDIN);
- if (data & SOUND_MASK_LINE)
- awacs_reg[0] |= MASK_MUX_AUDIN;
- if (data & SOUND_MASK_MIC)
- awacs_reg[0] |= MASK_MUX_MIC;
- if (data & SOUND_MASK_CD)
- awacs_reg[0] |= MASK_MUX_CD;
- awacs_write(awacs_reg[0] | MASK_ADDR0);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_STEREODEVS:
- data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
- | SOUND_MASK_RECLEV | SOUND_MASK_CD
- | SOUND_MASK_LINE;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_CAPS:
- rc = IOCTL_OUT(arg, 0);
- break;
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data);
- /* Fall through */
- case SOUND_MIXER_READ_VOLUME:
- rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME));
- break;
- case SOUND_MIXER_WRITE_SPEAKER:
- IOCTL_IN(arg, data);
- if (!(data & 0xff)) {
- /* Mute the left speaker */
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2);
- } else {
- /* Unmute the left speaker */
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2);
- }
- if (!(data & 0xff00)) {
- /* Mute the right speaker */
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4);
- } else {
- /* Unmute the right speaker */
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
- awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4);
- }
-
- data = (((data&0xff)*16)/100 > 0xf ? 0xf :
- (((data&0xff)*16)/100)) +
- ((((data>>8)*16)/100 > 0xf ? 0xf :
- ((((data>>8)*16)/100)))<<4);
-
- awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data);
- /* Fall through */
- case SOUND_MIXER_READ_SPEAKER:
- data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
- data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
- rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
- break;
- case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
- IOCTL_IN(arg, data);
- beep_vol = data & 0xff;
- /* fall through */
- case SOUND_MIXER_READ_ALTPCM:
- rc = IOCTL_OUT(arg, beep_vol);
- break;
- case SOUND_MIXER_WRITE_LINE:
- IOCTL_IN(arg, data);
- awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data);
-
- /* fall through */
- case SOUND_MIXER_READ_LINE:
- data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_MIC:
- IOCTL_IN(arg, data);
- /* Mic is mono device */
- data = (data << 8) + (data << 24);
- awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data);
- /* fall through */
- case SOUND_MIXER_READ_MIC:
- data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC);
- data <<= 24;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_CD:
- IOCTL_IN(arg, data);
- awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data);
- /* fall through */
- case SOUND_MIXER_READ_CD:
- data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_RECLEV:
- IOCTL_IN(arg, data);
- data = awacs_volume_setter(data, 0, 0, 4);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECLEV:
- data = awacs_get_volume(awacs_reg[0], 4);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_OUTMASK:
- case SOUND_MIXER_OUTSRC:
- default:
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-static int daca_mixer_ioctl(u_int cmd, u_long arg)
-{
- int data;
- int rc;
-
- /* And the DACA's no genius either! */
-
- switch(cmd) {
- case SOUND_MIXER_READ_DEVMASK:
- data = SOUND_MASK_VOLUME;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECMASK:
- data = 0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECSRC:
- data = 0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_RECSRC:
- IOCTL_IN(arg, data);
- data =0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_STEREODEVS:
- data = SOUND_MASK_VOLUME;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_CAPS:
- rc = IOCTL_OUT(arg, 0);
- break;
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- daca_set_volume(data, data);
- /* Fall through */
- case SOUND_MIXER_READ_VOLUME:
- daca_get_volume(& data, &data);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_OUTMASK:
- case SOUND_MIXER_OUTSRC:
- default:
- rc = -EINVAL;
- }
- return rc;
-}
-
-static int PMacMixerIoctl(u_int cmd, u_long arg)
-{
- int rc;
-
- /* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */
-
- TRY_LOCK();
-
- switch (awacs_revision){
- case AWACS_BURGUNDY:
- rc = burgundy_mixer_ioctl(cmd, arg);
- break ;
- case AWACS_DACA:
- rc = daca_mixer_ioctl(cmd, arg);
- break;
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- rc = tas_mixer_ioctl(cmd, arg);
- break ;
- default: /* ;-)) */
- rc = awacs_mixer_ioctl(cmd, arg);
- }
-
- UNLOCK();
-
- return rc;
-}
-
-static void PMacMixerInit(void)
-{
- switch (awacs_revision) {
- case AWACS_TUMBLER:
- printk("AE-Init tumbler mixer\n");
- break ;
- case AWACS_SNAPPER:
- printk("AE-Init snapper mixer\n");
- break ;
- case AWACS_DACA:
- case AWACS_BURGUNDY:
- break ; /* don't know yet */
- case AWACS_AWACS:
- case AWACS_SCREAMER:
- default:
- awacs_mixer_init() ;
- break ;
- }
-}
-
-/* Write/Read sq setup functions:
- Check to see if we have enough (or any) dbdma cmd buffers for the
- user's fragment settings. If not, allocate some. If this fails we will
- point at the beep buffer - as an emergency provision - to stop dma tromping
- on some random bit of memory (if someone lets it go anyway).
- The command buffers are then set up to point to the fragment buffers
- (allocated elsewhere). We need n+1 commands the last of which holds
- a NOP + loop to start.
-*/
-
-static int PMacWriteSqSetup(void)
-{
- int i, count = 600 ;
- volatile struct dbdma_cmd *cp;
-
- LOCK();
-
- /* stop the controller from doing any output - if it isn't already.
- it _should_ be before this is called anyway */
-
- out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
- while ((in_le32(&awacs_txdma->status) & RUN) && count--)
- udelay(1);
-#ifdef DEBUG_DMASOUND
-if (count <= 0)
- printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n");
-#endif
-
- if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
- kfree(awacs_tx_cmd_space);
- number_of_tx_cmd_buffers = 0;
-
- /* we need nbufs + 1 (for the loop) and we should request + 1
- again because the DBDMA_ALIGN might pull the start up by up
- to sizeof(struct dbdma_cmd) - 4.
- */
-
- awacs_tx_cmd_space = kmalloc
- ((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
- GFP_KERNEL);
- if (awacs_tx_cmd_space == NULL) {
- /* don't leave it dangling - nasty but better than a
- random address */
- out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
- printk(KERN_ERR
- "dmasound_pmac: can't allocate dbdma cmd buffers"
- ", driver disabled\n");
- UNLOCK();
- return -ENOMEM;
- }
- awacs_tx_cmds = (volatile struct dbdma_cmd *)
- DBDMA_ALIGN(awacs_tx_cmd_space);
- number_of_tx_cmd_buffers = write_sq.max_count + 1;
- }
-
- cp = awacs_tx_cmds;
- memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd));
- for (i = 0; i < write_sq.max_count; ++i, ++cp) {
- st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i]));
- }
- st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
- st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds));
- /* point the controller at the command stack - ready to go */
- out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds));
- UNLOCK();
- return 0;
-}
-
-static int PMacReadSqSetup(void)
-{
- int i, count = 600;
- volatile struct dbdma_cmd *cp;
-
- LOCK();
-
- /* stop the controller from doing any input - if it isn't already.
- it _should_ be before this is called anyway */
-
- out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
- while ((in_le32(&awacs_rxdma->status) & RUN) && count--)
- udelay(1);
-#ifdef DEBUG_DMASOUND
-if (count <= 0)
- printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n");
-#endif
-
- if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
- kfree(awacs_rx_cmd_space);
- number_of_rx_cmd_buffers = 0;
-
- /* we need nbufs + 1 (for the loop) and we should request + 1 again
- because the DBDMA_ALIGN might pull the start up by up to
- sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits).
- */
-
- awacs_rx_cmd_space = kmalloc
- ((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd),
- GFP_KERNEL);
- if (awacs_rx_cmd_space == NULL) {
- /* don't leave it dangling - nasty but better than a
- random address */
- out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
- printk(KERN_ERR
- "dmasound_pmac: can't allocate dbdma cmd buffers"
- ", driver disabled\n");
- UNLOCK();
- return -ENOMEM;
- }
- awacs_rx_cmds = (volatile struct dbdma_cmd *)
- DBDMA_ALIGN(awacs_rx_cmd_space);
- number_of_rx_cmd_buffers = read_sq.max_count + 1 ;
- }
- cp = awacs_rx_cmds;
- memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd));
-
- /* Set dma buffers up in a loop */
- for (i = 0; i < read_sq.max_count; i++,cp++) {
- st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i]));
- st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS);
- st_le16(&cp->req_count, read_sq.block_size);
- st_le16(&cp->xfer_status, 0);
- }
-
- /* The next two lines make the thing loop around.
- */
- st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS);
- st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds));
- /* point the controller at the command stack - ready to go */
- out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds));
-
- UNLOCK();
- return 0;
-}
-
-/* TODO: this needs work to guarantee that when it returns DMA has stopped
- but in a more elegant way than is done here....
-*/
-
-static void PMacAbortRead(void)
-{
- int i;
- volatile struct dbdma_cmd *cp;
-
- LOCK();
- /* give it a chance to update the output and provide the IRQ
- that is expected.
- */
-
- out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH );
-
- cp = awacs_rx_cmds;
- for (i = 0; i < read_sq.max_count; i++,cp++)
- st_le16(&cp->command, DBDMA_STOP);
- /*
- * We should probably wait for the thing to stop before we
- * release the memory.
- */
-
- msleep(100) ; /* give it a (small) chance to act */
-
- /* apply the sledgehammer approach - just stop it now */
-
- out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
- UNLOCK();
-}
-
-extern char *get_afmt_string(int);
-static int PMacStateInfo(char *b, size_t sp)
-{
- int i, len = 0;
- len = sprintf(b,"HW rates: ");
- switch (awacs_revision){
- case AWACS_DACA:
- case AWACS_BURGUNDY:
- len += sprintf(b,"44100 ") ;
- break ;
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- for (i=0; i<1; i++){
- if (tas_freqs_ok[i])
- len += sprintf(b+len,"%d ", tas_freqs[i]) ;
- }
- break ;
- case AWACS_AWACS:
- case AWACS_SCREAMER:
- default:
- for (i=0; i<8; i++){
- if (awacs_freqs_ok[i])
- len += sprintf(b+len,"%d ", awacs_freqs[i]) ;
- }
- break ;
- }
- len += sprintf(b+len,"s/sec\n") ;
- if (len < sp) {
- len += sprintf(b+len,"HW AFMTS: ");
- i = AFMT_U16_BE ;
- while (i) {
- if (i & dmasound.mach.hardware_afmts)
- len += sprintf(b+len,"%s ",
- get_afmt_string(i & dmasound.mach.hardware_afmts));
- i >>= 1 ;
- }
- len += sprintf(b+len,"\n") ;
- }
- return len ;
-}
-
-/*** Machine definitions *****************************************************/
-
-static SETTINGS def_hard = {
- .format = AFMT_S16_BE,
- .stereo = 1,
- .size = 16,
- .speed = 44100
-} ;
-
-static SETTINGS def_soft = {
- .format = AFMT_S16_BE,
- .stereo = 1,
- .size = 16,
- .speed = 44100
-} ;
-
-static MACHINE machPMac = {
- .name = awacs_name,
- .name2 = "PowerMac Built-in Sound",
- .owner = THIS_MODULE,
- .dma_alloc = PMacAlloc,
- .dma_free = PMacFree,
- .irqinit = PMacIrqInit,
-#ifdef MODULE
- .irqcleanup = PMacIrqCleanup,
-#endif /* MODULE */
- .init = PMacInit,
- .silence = PMacSilence,
- .setFormat = PMacSetFormat,
- .setVolume = PMacSetVolume,
- .play = PMacPlay,
- .record = NULL, /* default to no record */
- .mixer_init = PMacMixerInit,
- .mixer_ioctl = PMacMixerIoctl,
- .write_sq_setup = PMacWriteSqSetup,
- .read_sq_setup = PMacReadSqSetup,
- .state_info = PMacStateInfo,
- .abort_read = PMacAbortRead,
- .min_dsp_speed = 7350,
- .max_dsp_speed = 44100,
- .version = ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION)
-};
-
-
-/*** Config & Setup **********************************************************/
-
-/* Check for pmac models that we care about in terms of special actions.
-*/
-
-void __init
-set_model(void)
-{
- /* portables/lap-tops */
-
- if (machine_is_compatible("AAPL,3400/2400") ||
- machine_is_compatible("AAPL,3500")) {
- is_pbook_3X00 = 1 ;
- }
- if (machine_is_compatible("PowerBook1,1") || /* lombard */
- machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */
- is_pbook_g3 = 1 ;
- return ;
- }
-}
-
-/* Get the OF node that tells us about the registers, interrupts etc. to use
- for sound IO.
-
- On most machines the sound IO OF node is the 'davbus' node. On newer pmacs
- with DACA (& Tumbler) the node to use is i2s-a. On much older machines i.e.
- before 9500 there is no davbus node and we have to use the 'awacs' property.
-
- In the latter case we signal this by setting the codec value - so that the
- code that looks for chip properties knows how to go about it.
-*/
-
-static struct device_node* __init
-get_snd_io_node(void)
-{
- struct device_node *np;
-
- /* set up awacs_node for early OF which doesn't have a full set of
- * properties on davbus
- */
- awacs_node = of_find_node_by_name(NULL, "awacs");
- if (awacs_node)
- awacs_revision = AWACS_AWACS;
-
- /* powermac models after 9500 (other than those which use DACA or
- * Tumbler) have a node called "davbus".
- */
- np = of_find_node_by_name(NULL, "davbus");
- /*
- * if we didn't find a davbus device, try 'i2s-a' since
- * this seems to be what iBooks (& Tumbler) have.
- */
- if (np == NULL) {
- i2s_node = of_find_node_by_name(NULL, "i2s-a");
- np = of_node_get(i2s_node);
- }
-
- /* if we didn't find this - perhaps we are on an early model
- * which _only_ has an 'awacs' node
- */
- if (np == NULL && awacs_node)
- np = of_node_get(awacs_node);
-
- /* if we failed all these return null - this will cause the
- * driver to give up...
- */
- return np ;
-}
-
-/* Get the OF node that contains the info about the sound chip, inputs s-rates
- etc.
- This node does not exist (or contains much reduced info) on earlier machines
- we have to deduce the info other ways for these.
-*/
-
-static struct device_node* __init
-get_snd_info_node(struct device_node *io)
-{
- struct device_node *info;
-
- for_each_node_by_name(info, "sound")
- if (info->parent == io)
- break;
- return info;
-}
-
-/* Find out what type of codec we have.
-*/
-
-static int __init
-get_codec_type(struct device_node *info)
-{
- /* already set if pre-davbus model and info will be NULL */
- int codec = awacs_revision ;
-
- if (info) {
- /* must do awacs first to allow screamer to overide it */
- if (of_device_is_compatible(info, "awacs"))
- codec = AWACS_AWACS ;
- if (of_device_is_compatible(info, "screamer"))
- codec = AWACS_SCREAMER;
- if (of_device_is_compatible(info, "burgundy"))
- codec = AWACS_BURGUNDY ;
- if (of_device_is_compatible(info, "daca"))
- codec = AWACS_DACA;
- if (of_device_is_compatible(info, "tumbler"))
- codec = AWACS_TUMBLER;
- if (of_device_is_compatible(info, "snapper"))
- codec = AWACS_SNAPPER;
- }
- return codec ;
-}
-
-/* find out what type, if any, of expansion card we have
-*/
-static void __init
-get_expansion_type(void)
-{
- struct device_node *dn;
-
- dn = of_find_node_by_name(NULL, "perch");
- if (dn != NULL)
- has_perch = 1;
- of_node_put(dn);
-
- dn = of_find_node_by_name(NULL, "pb-ziva-pc");
- if (dn != NULL)
- has_ziva = 1;
- of_node_put(dn);
- /* need to work out how we deal with iMac SRS module */
-}
-
-/* set up frame rates.
- * I suspect that these routines don't quite go about it the right way:
- * - where there is more than one rate - I think that the first property
- * value is the number of rates.
- * TODO: check some more device trees and modify accordingly
- * Set dmasound.mach.max_dsp_rate on the basis of these routines.
-*/
-
-static void __init
-awacs_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
- int i ;
- if (prop) {
- for (i=0; i<8; i++)
- awacs_freqs_ok[i] = 0 ;
- for (l /= sizeof(int); l > 0; --l) {
- unsigned int r = *prop++;
- /* Apple 'Fixed' format */
- if (r >= 0x10000)
- r >>= 16;
- for (i = 0; i < 8; ++i) {
- if (r == awacs_freqs[i]) {
- awacs_freqs_ok[i] = 1;
- break;
- }
- }
- }
- }
- /* else we assume that all the rates are available */
-}
-
-static void __init
-burgundy_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
- int temp[9] ;
- int i = 0 ;
- if (prop) {
- for (l /= sizeof(int); l > 0; --l) {
- unsigned int r = *prop++;
- /* Apple 'Fixed' format */
- if (r >= 0x10000)
- r >>= 16;
- temp[i] = r ;
- i++ ; if(i>=9) i=8;
- }
- }
-#ifdef DEBUG_DMASOUND
-if (i > 1){
- int j;
- printk("dmasound_pmac: burgundy with multiple frame rates\n");
- for(j=0; j<i; j++)
- printk("%d ", temp[j]) ;
- printk("\n") ;
-}
-#endif
-}
-
-static void __init
-daca_init_frame_rates(const unsigned int *prop, unsigned int l)
-{
- int temp[9] ;
- int i = 0 ;
- if (prop) {
- for (l /= sizeof(int); l > 0; --l) {
- unsigned int r = *prop++;
- /* Apple 'Fixed' format */
- if (r >= 0x10000)
- r >>= 16;
- temp[i] = r ;
- i++ ; if(i>=9) i=8;
-
- }
- }
-#ifdef DEBUG_DMASOUND
-if (i > 1){
- int j;
- printk("dmasound_pmac: DACA with multiple frame rates\n");
- for(j=0; j<i; j++)
- printk("%d ", temp[j]) ;
- printk("\n") ;
-}
-#endif
-}
-
-static void __init
-init_frame_rates(const unsigned int *prop, unsigned int l)
-{
- switch (awacs_revision) {
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- tas_init_frame_rates(prop, l);
- break ;
- case AWACS_DACA:
- daca_init_frame_rates(prop, l);
- break ;
- case AWACS_BURGUNDY:
- burgundy_init_frame_rates(prop, l);
- break ;
- default:
- awacs_init_frame_rates(prop, l);
- break ;
- }
-}
-
-/* find things/machines that can't do mac-io byteswap
-*/
-
-static void __init
-set_hw_byteswap(struct device_node *io)
-{
- struct device_node *mio ;
- unsigned int kl = 0 ;
-
- /* if seems that Keylargo can't byte-swap */
-
- for (mio = io->parent; mio ; mio = mio->parent) {
- if (strcmp(mio->name, "mac-io") == 0) {
- if (of_device_is_compatible(mio, "Keylargo"))
- kl = 1;
- break;
- }
- }
- hw_can_byteswap = !kl;
-}
-
-/* Allocate the resources necessary for beep generation. This cannot be (quite)
- done statically (yet) because we cannot do virt_to_bus() on static vars when
- the code is loaded as a module.
-
- for the sake of saving the possibility that two allocations will incur the
- overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma
- command here as well... even tho' it is not part of the beep process.
-*/
-
-int32_t
-__init setup_beep(void)
-{
- /* Initialize beep stuff */
- /* want one cmd buffer for beeps, and a second one for emergencies
- - i.e. dbdma error conditions.
- ask for three to allow for pull up in DBDMA_ALIGN().
- */
- beep_dbdma_cmd_space =
- kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL);
- if(beep_dbdma_cmd_space == NULL) {
- printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ;
- return -ENOMEM ;
- }
- beep_dbdma_cmd = (volatile struct dbdma_cmd *)
- DBDMA_ALIGN(beep_dbdma_cmd_space);
- /* set up emergency dbdma cmd */
- emergency_dbdma_cmd = beep_dbdma_cmd+1 ;
- beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
- if (beep_buf == NULL) {
- printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
- kfree(beep_dbdma_cmd_space) ;
- return -ENOMEM ;
- }
- return 0 ;
-}
-
-static struct input_dev *awacs_beep_dev;
-
-int __init dmasound_awacs_init(void)
-{
- struct device_node *io = NULL, *info = NULL;
- int vol, res;
-
- if (!machine_is(powermac))
- return -ENODEV;
-
- awacs_subframe = 0;
- awacs_revision = 0;
- hw_can_byteswap = 1 ; /* most can */
-
- /* look for models we need to handle specially */
- set_model() ;
-
- /* find the OF node that tells us about the dbdma stuff
- */
- io = get_snd_io_node();
- if (io == NULL) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find sound io OF node\n");
-#endif
- goto no_device;
- }
-
- /* find the OF node that tells us about the sound sub-system
- * this doesn't exist on pre-davbus machines (earlier than 9500)
- */
- if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */
- info = get_snd_info_node(io) ;
- if (info == NULL){
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find 'sound' OF node\n");
-#endif
- goto no_device;
- }
- }
-
- awacs_revision = get_codec_type(info) ;
- if (awacs_revision == 0) {
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: couldn't find a Codec we can handle\n");
-#endif
- goto no_device; /* we don't know this type of h/w */
- }
-
- /* set up perch, ziva, SRS or whatever else we have as sound
- * expansion.
- */
- get_expansion_type();
-
- /* we've now got enough information to make up the audio topology.
- * we will map the sound part of mac-io now so that we can probe for
- * other info if necessary (early AWACS we want to read chip ids)
- */
-
- if (of_get_address(io, 2, NULL, NULL) == NULL) {
- /* OK - maybe we need to use the 'awacs' node (on earlier
- * machines).
- */
- if (awacs_node) {
- of_node_put(io);
- io = of_node_get(awacs_node);
- if (of_get_address(io, 2, NULL, NULL) == NULL) {
- printk("dmasound_pmac: can't use %s\n",
- io->full_name);
- goto no_device;
- }
- } else
- printk("dmasound_pmac: can't use %s\n", io->full_name);
- }
-
- if (of_address_to_resource(io, 0, &awacs_rsrc[0]) ||
- request_mem_region(awacs_rsrc[0].start,
- awacs_rsrc[0].end - awacs_rsrc[0].start + 1,
- " (IO)") == NULL) {
- printk(KERN_ERR "dmasound: can't request IO resource !\n");
- goto no_device;
- }
- if (of_address_to_resource(io, 1, &awacs_rsrc[1]) ||
- request_mem_region(awacs_rsrc[1].start,
- awacs_rsrc[1].end - awacs_rsrc[1].start + 1,
- " (tx dma)") == NULL) {
- release_mem_region(awacs_rsrc[0].start,
- awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
- printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n");
- goto no_device;
- }
- if (of_address_to_resource(io, 2, &awacs_rsrc[2]) ||
- request_mem_region(awacs_rsrc[2].start,
- awacs_rsrc[2].end - awacs_rsrc[2].start + 1,
- " (rx dma)") == NULL) {
- release_mem_region(awacs_rsrc[0].start,
- awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
- release_mem_region(awacs_rsrc[1].start,
- awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
- printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n");
- goto no_device;
- }
-
- awacs_beep_dev = input_allocate_device();
- if (!awacs_beep_dev) {
- release_mem_region(awacs_rsrc[0].start,
- awacs_rsrc[0].end - awacs_rsrc[0].start + 1);
- release_mem_region(awacs_rsrc[1].start,
- awacs_rsrc[1].end - awacs_rsrc[1].start + 1);
- release_mem_region(awacs_rsrc[2].start,
- awacs_rsrc[2].end - awacs_rsrc[2].start + 1);
- printk(KERN_ERR "dmasound: can't allocate input device !\n");
- goto no_device;
- }
-
- awacs_beep_dev->name = "dmasound beeper";
- awacs_beep_dev->phys = "macio/input0";
- awacs_beep_dev->id.bustype = BUS_HOST;
- awacs_beep_dev->event = awacs_beep_event;
- awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
- awacs_beep_dev->evbit[0] = BIT(EV_SND);
-
- /* all OF versions I've seen use this value */
- if (i2s_node)
- i2s = ioremap(awacs_rsrc[0].start, 0x1000);
- else
- awacs = ioremap(awacs_rsrc[0].start, 0x1000);
- awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100);
- awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100);
-
- /* first of all make sure that the chip is powered up....*/
- pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
- if (awacs_revision == AWACS_SCREAMER && awacs)
- awacs_recalibrate();
-
- awacs_irq = irq_of_parse_and_map(io, 0);
- awacs_tx_irq = irq_of_parse_and_map(io, 1);
- awacs_rx_irq = irq_of_parse_and_map(io, 2);
-
- /* Hack for legacy crap that will be killed someday */
- of_node_put(awacs_node);
- awacs_node = of_node_get(io);
-
- /* if we have an awacs or screamer - probe the chip to make
- * sure we have the right revision.
- */
-
- if (awacs_revision <= AWACS_SCREAMER){
- uint32_t temp, rev, mfg ;
- /* find out the awacs revision from the chip */
- temp = in_le32(&awacs->codec_stat);
- rev = (temp >> 12) & 0xf;
- mfg = (temp >> 8) & 0xf;
-#ifdef DEBUG_DMASOUND
-printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev);
-#endif
- if (rev >= AWACS_SCREAMER)
- awacs_revision = AWACS_SCREAMER ;
- else
- awacs_revision = rev ;
- }
-
- dmasound.mach = machPMac;
-
- /* find out other bits & pieces from OF, these may be present
- only on some models ... so be careful.
- */
-
- /* in the absence of a frame rates property we will use the defaults
- */
-
- if (info) {
- const unsigned int *prop;
- unsigned int l;
-
- sound_device_id = 0;
- /* device ID appears post g3 b&w */
- prop = of_get_property(info, "device-id", NULL);
- if (prop != 0)
- sound_device_id = *prop;
-
- /* look for a property saying what sample rates
- are available */
-
- prop = of_get_property(info, "sample-rates", &l);
- if (prop == 0)
- prop = of_get_property(info, "output-frame-rates", &l);
-
- /* if it's there use it to set up frame rates */
- init_frame_rates(prop, l) ;
- of_node_put(info);
- info = NULL;
- }
-
- if (awacs)
- out_le32(&awacs->control, 0x11); /* set everything quiesent */
-
- set_hw_byteswap(io) ; /* figure out if the h/w can do it */
-
-#ifdef CONFIG_NVRAM
- /* get default volume from nvram */
- vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 );
-#else
- vol = 0;
-#endif
-
- /* set up tracking values */
- spk_vol = vol * 100 ;
- spk_vol /= 7 ; /* get set value to a percentage */
- spk_vol |= (spk_vol << 8) ; /* equal left & right */
- line_vol = passthru_vol = spk_vol ;
-
- /* fill regs that are shared between AWACS & Burgundy */
-
- awacs_reg[2] = vol + (vol << 6);
- awacs_reg[4] = vol + (vol << 6);
- awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */
- awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */
- awacs_reg[7] = 0;
-
- awacs_reg[0] = MASK_MUX_CD;
- awacs_reg[1] = MASK_LOOPTHRU;
-
- /* FIXME: Only machines with external SRS module need MASK_PAROUT */
- if (has_perch || sound_device_id == 0x5
- || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb)
- awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
-
- switch (awacs_revision) {
- case AWACS_TUMBLER:
- tas_register_driver(&tas3001c_hooks);
- tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
- tas_dmasound_init();
- tas_post_init();
- break ;
- case AWACS_SNAPPER:
- tas_register_driver(&tas3004_hooks);
- tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
- tas_dmasound_init();
- tas_post_init();
- break;
- case AWACS_DACA:
- daca_init();
- break;
- case AWACS_BURGUNDY:
- awacs_burgundy_init();
- break ;
- case AWACS_SCREAMER:
- case AWACS_AWACS:
- default:
- load_awacs();
- break ;
- }
-
- /* enable/set-up external modules - when we know how */
-
- if (has_perch)
- awacs_enable_amp(100 * 0x101);
-
- /* Reset dbdma channels */
- out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
- while (in_le32(&awacs_txdma->status) & RUN)
- udelay(1);
- out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
- while (in_le32(&awacs_rxdma->status) & RUN)
- udelay(1);
-
- /* Initialize beep stuff */
- if ((res=setup_beep()))
- return res ;
-
-#ifdef CONFIG_PM
- pmu_register_sleep_notifier(&awacs_sleep_notifier);
-#endif /* CONFIG_PM */
-
- /* Powerbooks have odd ways of enabling inputs such as
- an expansion-bay CD or sound from an internal modem
- or a PC-card modem. */
- if (is_pbook_3X00) {
- /*
- * Enable CD and PC-card sound inputs.
- * This is done by reading from address
- * f301a000, + 0x10 to enable the expansion-bay
- * CD sound input, + 0x80 to enable the PC-card
- * sound input. The 0x100 enables the SCSI bus
- * terminator power.
- */
- latch_base = ioremap (0xf301a000, 0x1000);
- in_8(latch_base + 0x190);
-
- } else if (is_pbook_g3) {
- struct device_node* mio;
- macio_base = NULL;
- for (mio = io->parent; mio; mio = mio->parent) {
- if (strcmp(mio->name, "mac-io") == 0) {
- struct resource r;
- if (of_address_to_resource(mio, 0, &r) == 0)
- macio_base = ioremap(r.start, 0x40);
- break;
- }
- }
- /*
- * Enable CD sound input.
- * The relevant bits for writing to this byte are 0x8f.
- * I haven't found out what the 0x80 bit does.
- * For the 0xf bits, writing 3 or 7 enables the CD
- * input, any other value disables it. Values
- * 1, 3, 5, 7 enable the microphone. Values 0, 2,
- * 4, 6, 8 - f enable the input from the modem.
- * -- paulus.
- */
- if (macio_base)
- out_8(macio_base + 0x37, 3);
- }
-
- if (hw_can_byteswap)
- dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ;
- else
- dmasound.mach.hardware_afmts = AFMT_S16_BE ;
-
- /* shut out chips that do output only.
- * may need to extend this to machines which have no inputs - even tho'
- * they use screamer - IIRC one of the powerbooks is like this.
- */
-
- if (awacs_revision != AWACS_DACA) {
- dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
- dmasound.mach.record = PMacRecord ;
- }
-
- dmasound.mach.default_hard = def_hard ;
- dmasound.mach.default_soft = def_soft ;
-
- switch (awacs_revision) {
- case AWACS_BURGUNDY:
- sprintf(awacs_name, "PowerMac Burgundy ") ;
- break ;
- case AWACS_DACA:
- sprintf(awacs_name, "PowerMac DACA ") ;
- break ;
- case AWACS_TUMBLER:
- sprintf(awacs_name, "PowerMac Tumbler ") ;
- break ;
- case AWACS_SNAPPER:
- sprintf(awacs_name, "PowerMac Snapper ") ;
- break ;
- case AWACS_SCREAMER:
- sprintf(awacs_name, "PowerMac Screamer ") ;
- break ;
- case AWACS_AWACS:
- default:
- sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ;
- break ;
- }
-
- /*
- * XXX: we should handle errors here, but that would mean
- * rewriting the whole init code. later..
- */
- input_register_device(awacs_beep_dev);
-
- of_node_put(io);
-
- return dmasound_init();
-
-no_device:
- of_node_put(info);
- of_node_put(awacs_node);
- of_node_put(i2s_node);
- of_node_put(io);
- return -ENODEV ;
-}
-
-static void __exit dmasound_awacs_cleanup(void)
-{
- input_unregister_device(awacs_beep_dev);
-
- switch (awacs_revision) {
- case AWACS_TUMBLER:
- case AWACS_SNAPPER:
- tas_dmasound_cleanup();
- tas_cleanup();
- break ;
- case AWACS_DACA:
- daca_cleanup();
- break;
- }
- dmasound_deinit();
-
- of_node_put(awacs_node);
- of_node_put(i2s_node);
-}
-
-MODULE_DESCRIPTION("PowerMac built-in audio driver.");
-MODULE_LICENSE("GPL");
-
-module_init(dmasound_awacs_init);
-module_exit(dmasound_awacs_cleanup);
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index f4056a9c371..a003c0ea930 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -202,13 +202,6 @@ module_param(numWriteBufs, int, 0);
static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */
module_param(writeBufSize, int, 0);
-#ifdef HAS_RECORD
-static unsigned int numReadBufs = DEFAULT_N_BUFFERS;
-module_param(numReadBufs, int, 0);
-static unsigned int readBufSize = DEFAULT_BUFF_SIZE; /* in bytes */
-module_param(readBufSize, int, 0);
-#endif
-
MODULE_LICENSE("GPL");
#ifdef MODULE
@@ -403,10 +396,6 @@ static void mixer_init(void)
struct sound_queue dmasound_write_sq;
static void sq_reset_output(void) ;
-#ifdef HAS_RECORD
-struct sound_queue dmasound_read_sq;
-static void sq_reset_input(void) ;
-#endif
static int sq_allocate_buffers(struct sound_queue *sq, int num, int size)
{
@@ -530,12 +519,6 @@ printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ;
sq->rear = -1;
setup_func = dmasound.mach.write_sq_setup;
}
-#ifdef HAS_RECORD
- else {
- sq->rear = 0;
- setup_func = dmasound.mach.read_sq_setup;
- }
-#endif
if (setup_func)
return setup_func();
return 0 ;
@@ -672,13 +655,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
}
if (file->f_mode & FMODE_WRITE )
poll_wait(file, &write_sq.action_queue, wait);
-#ifdef HAS_RECORD
- if (file->f_mode & FMODE_READ)
- poll_wait(file, &read_sq.action_queue, wait);
- if (file->f_mode & FMODE_READ)
- if (read_sq.block_size - read_sq.rear_size > 0)
- mask |= POLLIN | POLLRDNORM;
-#endif
if (file->f_mode & FMODE_WRITE)
if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0)
mask |= POLLOUT | POLLWRNORM;
@@ -686,101 +662,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait)
}
-#ifdef HAS_RECORD
- /*
- * Here is how the values are used for reading.
- * The value 'active' simply indicates the DMA is running. This is done
- * so the driver semantics are DMA starts when the first read is posted.
- * The value 'front' indicates the buffer we should next send to the user.
- * The value 'rear' indicates the buffer the DMA is currently filling.
- * When 'front' == 'rear' the buffer "ring" is empty (we always have an
- * empty available). The 'rear_size' is used to track partial offsets
- * into the buffer we are currently returning to the user.
-
- * This level (> [1.5]) doesn't care what strategy the LL driver uses with
- * DMA on over-run. It can leave it running (and keep active == 1) or it
- * can kill it and set active == 0 in which case this routine will spot
- * it and restart the DMA.
- */
-
-static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft,
- loff_t *ppos)
-{
-
- ssize_t uRead, bLeft, bUsed, uUsed;
-
- if (uLeft == 0)
- return 0;
-
- /* cater for the compatibility mode - record compiled in but no LL */
- if (dmasound.mach.record == NULL)
- return -EINVAL ;
-
- /* see comment in sq_write()
- */
-
- if( shared_resources_initialised == 0) {
- dmasound.mach.init() ;
- shared_resources_initialised = 1 ;
- }
-
- /* set up the sq if it is not already done. see comments in sq_write().
- */
-
- if (read_sq.locked == 0) {
- if ((uRead = sq_setup(&read_sq)) < 0)
- return uRead ;
- }
-
- uRead = 0;
-
- /* Move what the user requests, depending upon other options.
- */
- while (uLeft > 0) {
-
- /* we happened to get behind and the LL driver killed DMA
- then we should set it going again. This also sets it
- going the first time through.
- */
- if ( !read_sq.active )
- dmasound.mach.record();
-
- /* When front == rear, the DMA is not done yet.
- */
- while (read_sq.front == read_sq.rear) {
- if (read_sq.open_mode & O_NONBLOCK) {
- return uRead > 0 ? uRead : -EAGAIN;
- }
- SLEEP(read_sq.action_queue);
- if (signal_pending(current))
- return uRead > 0 ? uRead : -EINTR;
- }
-
- /* The amount we move is either what is left in the
- * current buffer or what the user wants.
- */
- bLeft = read_sq.block_size - read_sq.rear_size;
- bUsed = read_sq.rear_size;
- uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft,
- read_sq.buffers[read_sq.front],
- &bUsed, bLeft);
- if (uUsed <= 0)
- return uUsed;
- dst += uUsed;
- uRead += uUsed;
- uLeft -= uUsed;
- read_sq.rear_size += bUsed;
- if (read_sq.rear_size >= read_sq.block_size) {
- read_sq.rear_size = 0;
- read_sq.front++;
- if (read_sq.front >= read_sq.max_active)
- read_sq.front = 0;
- }
- }
- return uRead;
-}
-#endif /* HAS_RECORD */
-
static inline void sq_init_waitqueue(struct sound_queue *sq)
{
init_waitqueue_head(&sq->action_queue);
@@ -854,23 +735,6 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
#define write_sq_open(file) \
sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize )
-#ifdef HAS_RECORD
-#define read_sq_init_waitqueue() sq_init_waitqueue(&read_sq)
-#if 0 /* blocking open() */
-#define read_sq_wake_up(file) sq_wake_up(&read_sq, file, FMODE_READ)
-#endif
-#define read_sq_release_buffers() sq_release_buffers(&read_sq)
-#define read_sq_open(file) \
- sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize )
-#else
-#define read_sq_init_waitqueue() do {} while (0)
-#if 0 /* blocking open() */
-#define read_sq_wake_up(file) do {} while (0)
-#endif
-#define read_sq_release_buffers() do {} while (0)
-#define sq_reset_input() do {} while (0)
-#endif
-
static int sq_open(struct inode *inode, struct file *file)
{
int rc;
@@ -881,25 +745,11 @@ static int sq_open(struct inode *inode, struct file *file)
rc = write_sq_open(file); /* checks the f_mode */
if (rc)
goto out;
-#ifdef HAS_RECORD
- if (dmasound.mach.record) {
- rc = read_sq_open(file); /* checks the f_mode */
- if (rc)
- goto out;
- } else { /* no record function installed; in compat mode */
- if (file->f_mode & FMODE_READ) {
- /* TODO: if O_RDWR, release any resources grabbed by write part */
- rc = -ENXIO;
- goto out;
- }
- }
-#else /* !HAS_RECORD */
if (file->f_mode & FMODE_READ) {
/* TODO: if O_RDWR, release any resources grabbed by write part */
rc = -ENXIO ; /* I think this is what is required by open(2) */
goto out;
}
-#endif /* HAS_RECORD */
if (dmasound.mach.sq_open)
dmasound.mach.sq_open(file->f_mode);
@@ -956,43 +806,9 @@ static void sq_reset_output(void)
write_sq.user_frag_size = 0 ;
}
-#ifdef HAS_RECORD
-
-static void sq_reset_input(void)
-{
- if (dmasound.mach.record && read_sq.active) {
- if (dmasound.mach.abort_read) { /* this routine must really be present */
- read_sq.syncing = 1 ;
- /* this can use the read_sq.sync_queue to sleep if
- necessary - it should not return until DMA
- is really stopped - because we might deallocate
- the buffers as the next action...
- */
- dmasound.mach.abort_read() ;
- } else {
- printk(KERN_ERR
- "dmasound_core: %s has no abort_read()!! all bets are off\n",
- dmasound.mach.name) ;
- }
- }
- read_sq.syncing =
- read_sq.active =
- read_sq.front =
- read_sq.count =
- read_sq.rear = 0 ;
-
- /* OK - we can unlock the parameters and fragment settings */
- read_sq.locked = 0 ;
- read_sq.user_frags = 0 ;
- read_sq.user_frag_size = 0 ;
-}
-
-#endif
-
static void sq_reset(void)
{
sq_reset_output() ;
- sq_reset_input() ;
/* we could consider resetting the shared_resources_owner here... but I
think it is probably still rather non-obvious to application writer
*/
@@ -1038,17 +854,6 @@ static int sq_release(struct inode *inode, struct file *file)
lock_kernel();
-#ifdef HAS_RECORD
- /* probably best to do the read side first - so that time taken to do it
- overlaps with playing any remaining output samples.
- */
- if (file->f_mode & FMODE_READ) {
- sq_reset_input() ; /* make sure dma is stopped and all is quiet */
- read_sq_release_buffers();
- read_sq.busy = 0;
- }
-#endif
-
if (file->f_mode & FMODE_WRITE) {
if (write_sq.busy)
rc = sq_fsync(file, file->f_path.dentry);
@@ -1105,11 +910,6 @@ static int shared_resources_are_mine(mode_t md)
static int queues_are_quiescent(void)
{
-#ifdef HAS_RECORD
- if (dmasound.mach.record)
- if (read_sq.locked)
- return 0 ;
-#endif
if (write_sq.locked)
return 0 ;
return 1 ;
@@ -1185,13 +985,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
the read_sq ones.
*/
size = 0 ;
-#ifdef HAS_RECORD
- if (dmasound.mach.record && (file->f_mode & FMODE_READ)) {
- if ( !read_sq.locked )
- sq_setup(&read_sq) ; /* set params */
- size = read_sq.user_frag_size ;
- }
-#endif
if (file->f_mode & FMODE_WRITE) {
if ( !write_sq.locked )
sq_setup(&write_sq) ;
@@ -1214,8 +1007,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
everything - read, however, is killed imediately.
*/
result = 0 ;
- if ((file->f_mode & FMODE_READ) && dmasound.mach.record)
- sq_reset_input() ;
if (file->f_mode & FMODE_WRITE) {
result = sq_fsync(file, file->f_path.dentry);
sq_reset_output() ;
@@ -1294,13 +1085,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
result = 0 ;
nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */
size = data & 0xffff;
-#ifdef HAS_RECORD
- if ((file->f_mode & FMODE_READ) && dmasound.mach.record) {
- result = set_queue_frags(&read_sq, nbufs, size) ;
- if (result)
- return result ;
- }
-#endif
if (file->f_mode & FMODE_WRITE) {
result = set_queue_frags(&write_sq, nbufs, size) ;
if (result)
@@ -1348,20 +1132,6 @@ static const struct file_operations sq_fops =
.release = sq_release,
};
-#ifdef HAS_RECORD
-static const struct file_operations sq_fops_record =
-{
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = sq_write,
- .poll = sq_poll,
- .ioctl = sq_ioctl,
- .open = sq_open,
- .release = sq_release,
- .read = sq_read,
-};
-#endif
-
static int sq_init(void)
{
const struct file_operations *fops = &sq_fops;
@@ -1369,10 +1139,6 @@ static int sq_init(void)
int sq_unit;
#endif
-#ifdef HAS_RECORD
- if (dmasound.mach.record)
- fops = &sq_fops_record;
-#endif
sq_unit = register_sound_dsp(fops, -1);
if (sq_unit < 0) {
printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
@@ -1380,7 +1146,6 @@ static int sq_init(void)
}
write_sq_init_waitqueue();
- read_sq_init_waitqueue();
/* These parameters will be restored for every clean open()
* in the case of multiple open()s (e.g. dsp0 & dsp1) they
@@ -1406,11 +1171,7 @@ static int sq_init(void)
driver.
*/
-#ifdef HAS_RECORD
-#define STAT_BUFF_LEN 1024
-#else
#define STAT_BUFF_LEN 768
-#endif
/* this is how much space we will allow the low-level driver to use
in the stat buffer. Currently, 2 * (80 character line + <NL>).
@@ -1518,11 +1279,6 @@ static int state_open(struct inode *inode, struct file *file)
len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ;
len += sprintf(buffer+len,"%9s:%8d%6d\n",
"write", write_sq.numBufs, write_sq.bufSize) ;
-#ifdef HAS_RECORD
- if (dmasound.mach.record)
- len += sprintf(buffer+len,"%9s:%8d%6d\n",
- "read", read_sq.numBufs, read_sq.bufSize) ;
-#endif
len += sprintf(buffer+len,
"Current : MaxFrg FragSiz MaxAct Frnt Rear "
"Cnt RrSize A B S L xruns\n") ;
@@ -1531,14 +1287,6 @@ static int state_open(struct inode *inode, struct file *file)
write_sq.max_active, write_sq.front, write_sq.rear,
write_sq.count, write_sq.rear_size, write_sq.active,
write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ;
-#ifdef HAS_RECORD
- if (dmasound.mach.record)
- len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n",
- "read", read_sq.max_count, read_sq.block_size,
- read_sq.max_active, read_sq.front, read_sq.rear,
- read_sq.count, read_sq.rear_size, read_sq.active,
- read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ;
-#endif
#ifdef DEBUG_DMASOUND
printk("dmasound: stat buffer used %d bytes\n", len) ;
#endif
@@ -1638,13 +1386,6 @@ int dmasound_init(void)
(dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ;
printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n",
numWriteBufs, writeBufSize) ;
-#ifdef HAS_RECORD
- if (dmasound.mach.record)
- printk(KERN_INFO
- "Read will use %4d fragments of %7d bytes as default\n",
- numReadBufs, readBufSize) ;
-#endif
-
return 0;
}
@@ -1659,7 +1400,6 @@ void dmasound_deinit(void)
}
write_sq_release_buffers();
- read_sq_release_buffers();
if (mixer_unit >= 0)
unregister_sound_mixer(mixer_unit);
@@ -1684,36 +1424,12 @@ static int dmasound_setup(char *str)
*/
switch (ints[0]) {
-#ifdef HAS_RECORD
- case 5:
- if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS))
- printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
- else
- catchRadius = ints[5];
- /* fall through */
- case 4:
- if (ints[4] < MIN_BUFFERS)
- printk("dmasound_setup: invalid number of read buffers, using default = %d\n",
- numReadBufs);
- else
- numReadBufs = ints[4];
- /* fall through */
- case 3:
- if ((size = ints[3]) < 256) /* check for small buffer specs */
- size <<= 10 ;
- if (size < MIN_BUFSIZE || size > MAX_BUFSIZE)
- printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize);
- else
- readBufSize = size;
- /* fall through */
-#else
case 3:
if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
else
catchRadius = ints[3];
/* fall through */
-#endif
case 2:
if (ints[1] < MIN_BUFFERS)
printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs);
@@ -1830,9 +1546,6 @@ EXPORT_SYMBOL(dmasound_init);
EXPORT_SYMBOL(dmasound_deinit);
#endif
EXPORT_SYMBOL(dmasound_write_sq);
-#ifdef HAS_RECORD
-EXPORT_SYMBOL(dmasound_read_sq);
-#endif
EXPORT_SYMBOL(dmasound_catchRadius);
#ifdef HAS_8BIT_TABLES
EXPORT_SYMBOL(dmasound_ulaw2dma8);
diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c
deleted file mode 100644
index 4b7dbdd2a43..00000000000
--- a/sound/oss/dmasound/tas3001c.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Driver for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "snapper".
- *
- * Tobias Sargeant <tobias.sargeant@bigpond.com>
- * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
- *
- * TODO:
- * -----
- * * Enable control over input line 2 (is this connected?)
- * * Implement sleep support (at least mute everything and
- * * set gains to minimum during sleep)
- * * Look into some of Darwin's tweaks regarding the mute
- * * lines (delays & different behaviour on some HW)
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/workqueue.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "dmasound.h"
-#include "tas_common.h"
-#include "tas3001c.h"
-
-#include "tas_ioctl.h"
-
-#define TAS3001C_BIQUAD_FILTER_COUNT 6
-#define TAS3001C_BIQUAD_CHANNEL_COUNT 2
-
-#define VOL_DEFAULT (100 * 4 / 5)
-#define INPUT_DEFAULT (100 * 4 / 5)
-#define BASS_DEFAULT (100 / 2)
-#define TREBLE_DEFAULT (100 / 2)
-
-struct tas3001c_data_t {
- struct tas_data_t super;
- int device_id;
- int output_id;
- int speaker_id;
- struct tas_drce_t drce_state;
- struct work_struct change;
-};
-
-
-static const union tas_biquad_t
-tas3001c_eq_unity={
- .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }
-};
-
-
-static inline unsigned char db_to_regval(short db) {
- int r=0;
-
- r=(db+0x59a0) / 0x60;
-
- if (r < 0x91) return 0x91;
- if (r > 0xef) return 0xef;
- return r;
-}
-
-static inline short quantize_db(short db) {
- return db_to_regval(db) * 0x60 - 0x59a0;
-}
-
-
-static inline int
-register_width(enum tas3001c_reg_t r)
-{
- switch(r) {
- case TAS3001C_REG_MCR:
- case TAS3001C_REG_TREBLE:
- case TAS3001C_REG_BASS:
- return 1;
-
- case TAS3001C_REG_DRC:
- return 2;
-
- case TAS3001C_REG_MIXER1:
- case TAS3001C_REG_MIXER2:
- return 3;
-
- case TAS3001C_REG_VOLUME:
- return 6;
-
- case TAS3001C_REG_LEFT_BIQUAD0:
- case TAS3001C_REG_LEFT_BIQUAD1:
- case TAS3001C_REG_LEFT_BIQUAD2:
- case TAS3001C_REG_LEFT_BIQUAD3:
- case TAS3001C_REG_LEFT_BIQUAD4:
- case TAS3001C_REG_LEFT_BIQUAD5:
- case TAS3001C_REG_LEFT_BIQUAD6:
-
- case TAS3001C_REG_RIGHT_BIQUAD0:
- case TAS3001C_REG_RIGHT_BIQUAD1:
- case TAS3001C_REG_RIGHT_BIQUAD2:
- case TAS3001C_REG_RIGHT_BIQUAD3:
- case TAS3001C_REG_RIGHT_BIQUAD4:
- case TAS3001C_REG_RIGHT_BIQUAD5:
- case TAS3001C_REG_RIGHT_BIQUAD6:
- return 15;
-
- default:
- return 0;
- }
-}
-
-static int
-tas3001c_write_register( struct tas3001c_data_t *self,
- enum tas3001c_reg_t reg_num,
- char *data,
- uint write_mode)
-{
- if (reg_num==TAS3001C_REG_MCR ||
- reg_num==TAS3001C_REG_BASS ||
- reg_num==TAS3001C_REG_TREBLE) {
- return tas_write_byte_register(&self->super,
- (uint)reg_num,
- *data,
- write_mode);
- } else {
- return tas_write_register(&self->super,
- (uint)reg_num,
- register_width(reg_num),
- data,
- write_mode);
- }
-}
-
-static int
-tas3001c_sync_register( struct tas3001c_data_t *self,
- enum tas3001c_reg_t reg_num)
-{
- if (reg_num==TAS3001C_REG_MCR ||
- reg_num==TAS3001C_REG_BASS ||
- reg_num==TAS3001C_REG_TREBLE) {
- return tas_sync_byte_register(&self->super,
- (uint)reg_num,
- register_width(reg_num));
- } else {
- return tas_sync_register(&self->super,
- (uint)reg_num,
- register_width(reg_num));
- }
-}
-
-static int
-tas3001c_read_register( struct tas3001c_data_t *self,
- enum tas3001c_reg_t reg_num,
- char *data,
- uint write_mode)
-{
- return tas_read_register(&self->super,
- (uint)reg_num,
- register_width(reg_num),
- data);
-}
-
-static inline int
-tas3001c_fast_load(struct tas3001c_data_t *self, int fast)
-{
- if (fast)
- self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80;
- else
- self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f;
- return tas3001c_sync_register(self,TAS3001C_REG_MCR);
-}
-
-static uint
-tas3001c_supported_mixers(struct tas3001c_data_t *self)
-{
- return SOUND_MASK_VOLUME |
- SOUND_MASK_PCM |
- SOUND_MASK_ALTPCM |
- SOUND_MASK_TREBLE |
- SOUND_MASK_BASS;
-}
-
-static int
-tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer)
-{
- switch(mixer) {
- case SOUND_MIXER_VOLUME:
- return 1;
- default:
- return 0;
- }
-}
-
-static uint
-tas3001c_stereo_mixers(struct tas3001c_data_t *self)
-{
- uint r=tas3001c_supported_mixers(self);
- uint i;
-
- for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
- if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i))
- r &= ~(1<<i);
- return r;
-}
-
-static int
-tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level)
-{
- if (!self)
- return -1;
-
- *level=self->super.mixer[mixer];
-
- return 0;
-}
-
-static int
-tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level)
-{
- int rc;
- tas_shadow_t *shadow;
-
- uint temp;
- uint offset=0;
-
- if (!self)
- return -1;
-
- shadow=self->super.shadow;
-
- if (!tas3001c_mixer_is_stereo(self,mixer))
- level = tas_mono_to_stereo(level);
-
- switch(mixer) {
- case SOUND_MIXER_VOLUME:
- temp = tas3001c_gain.master[level&0xff];
- shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff;
- shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff;
- shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff;
- temp = tas3001c_gain.master[(level>>8)&0xff];
- shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff;
- shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff;
- shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff;
- rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
- break;
- case SOUND_MIXER_ALTPCM:
- /* tas3001c_fast_load(self, 1); */
- level = tas_mono_to_stereo(level);
- temp = tas3001c_gain.mixer[level&0xff];
- shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff;
- shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff;
- shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff;
- rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
- /* tas3001c_fast_load(self, 0); */
- break;
- case SOUND_MIXER_PCM:
- /* tas3001c_fast_load(self, 1); */
- level = tas_mono_to_stereo(level);
- temp = tas3001c_gain.mixer[level&0xff];
- shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff;
- shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff;
- shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff;
- rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
- /* tas3001c_fast_load(self, 0); */
- break;
- case SOUND_MIXER_TREBLE:
- temp = tas3001c_gain.treble[level&0xff];
- shadow[TAS3001C_REG_TREBLE][0]=temp&0xff;
- rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
- break;
- case SOUND_MIXER_BASS:
- temp = tas3001c_gain.bass[level&0xff];
- shadow[TAS3001C_REG_BASS][0]=temp&0xff;
- rc = tas3001c_sync_register(self,TAS3001C_REG_BASS);
- break;
- default:
- rc = -1;
- break;
- }
- if (rc < 0)
- return rc;
- self->super.mixer[mixer]=level;
- return 0;
-}
-
-static int
-tas3001c_leave_sleep(struct tas3001c_data_t *self)
-{
- unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
- if (!self)
- return -1;
-
- /* Make sure something answers on the i2c bus */
- if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
- WRITE_NORMAL|FORCE_WRITE) < 0)
- return -1;
-
- tas3001c_fast_load(self, 1);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
-
- tas3001c_fast_load(self, 0);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
- (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-
- return 0;
-}
-
-static int
-tas3001c_enter_sleep(struct tas3001c_data_t *self)
-{
- /* Stub for now, but I have the details on low-power mode */
- if (!self)
- return -1;
- return 0;
-}
-
-static int
-tas3001c_sync_biquad( struct tas3001c_data_t *self,
- u_int channel,
- u_int filter)
-{
- enum tas3001c_reg_t reg;
-
- if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
- filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
- reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
- return tas3001c_sync_register(self,reg);
-}
-
-static int
-tas3001c_write_biquad_shadow( struct tas3001c_data_t *self,
- u_int channel,
- u_int filter,
- const union tas_biquad_t *biquad)
-{
- tas_shadow_t *shadow=self->super.shadow;
- enum tas3001c_reg_t reg;
-
- if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
- filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
- reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
- SET_4_20(shadow[reg], 0,biquad->coeff.b0);
- SET_4_20(shadow[reg], 3,biquad->coeff.b1);
- SET_4_20(shadow[reg], 6,biquad->coeff.b2);
- SET_4_20(shadow[reg], 9,biquad->coeff.a1);
- SET_4_20(shadow[reg],12,biquad->coeff.a2);
-
- return 0;
-}
-
-static int
-tas3001c_write_biquad( struct tas3001c_data_t *self,
- u_int channel,
- u_int filter,
- const union tas_biquad_t *biquad)
-{
- int rc;
-
- rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad);
- if (rc < 0) return rc;
-
- return tas3001c_sync_biquad(self, channel, filter);
-}
-
-static int
-tas3001c_write_biquad_list( struct tas3001c_data_t *self,
- u_int filter_count,
- u_int flags,
- struct tas_biquad_ctrl_t *biquads)
-{
- int i;
- int rc;
-
- if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
-
- for (i=0; i<filter_count; i++) {
- rc=tas3001c_write_biquad(self,
- biquads[i].channel,
- biquads[i].filter,
- &biquads[i].data);
- if (rc < 0) break;
- }
-
- if (flags & TAS_BIQUAD_FAST_LOAD) {
- tas3001c_fast_load(self,0);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
- (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
- }
-
- return rc;
-}
-
-static int
-tas3001c_read_biquad( struct tas3001c_data_t *self,
- u_int channel,
- u_int filter,
- union tas_biquad_t *biquad)
-{
- tas_shadow_t *shadow=self->super.shadow;
- enum tas3001c_reg_t reg;
-
- if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT ||
- filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL;
-
- reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter;
-
- biquad->coeff.b0=GET_4_20(shadow[reg], 0);
- biquad->coeff.b1=GET_4_20(shadow[reg], 3);
- biquad->coeff.b2=GET_4_20(shadow[reg], 6);
- biquad->coeff.a1=GET_4_20(shadow[reg], 9);
- biquad->coeff.a2=GET_4_20(shadow[reg],12);
-
- return 0;
-}
-
-static int
-tas3001c_eq_rw( struct tas3001c_data_t *self,
- u_int cmd,
- u_long arg)
-{
- int rc;
- struct tas_biquad_ctrl_t biquad;
- void __user *argp = (void __user *)arg;
-
- if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
-
- if (cmd & SIOC_IN) {
- rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
- }
-
- if (cmd & SIOC_OUT) {
- rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
-
- if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
-
- }
- return 0;
-}
-
-static int
-tas3001c_eq_list_rw( struct tas3001c_data_t *self,
- u_int cmd,
- u_long arg)
-{
- int rc;
- int filter_count;
- int flags;
- int i,j;
- char sync_required[2][6];
- struct tas_biquad_ctrl_t biquad;
- struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
-
- memset(sync_required,0,sizeof(sync_required));
-
- if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
- return -EFAULT;
-
- if (copy_from_user(&flags, &argp->flags, sizeof(int)))
- return -EFAULT;
-
- if (cmd & SIOC_IN) {
- }
-
- for (i=0; i < filter_count; i++) {
- if (copy_from_user(&biquad, &argp->biquads[i],
- sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
-
- if (cmd & SIOC_IN) {
- sync_required[biquad.channel][biquad.filter]=1;
- rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
- }
-
- if (cmd & SIOC_OUT) {
- rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
-
- if (copy_to_user(&argp->biquads[i], &biquad,
- sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
- }
- }
-
- if (cmd & SIOC_IN) {
- if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1);
- for (i=0; i<2; i++) {
- for (j=0; j<6; j++) {
- if (sync_required[i][j]) {
- rc=tas3001c_sync_biquad(self, i, j);
- if (rc < 0) return rc;
- }
- }
- }
- if (flags & TAS_BIQUAD_FAST_LOAD) {
- tas3001c_fast_load(self,0);
- /* now we need to set up the mixers again,
- because leaving fast mode resets them. */
- (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
- (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
- }
- }
-
- return 0;
-}
-
-static int
-tas3001c_update_drce( struct tas3001c_data_t *self,
- int flags,
- struct tas_drce_t *drce)
-{
- tas_shadow_t *shadow;
- shadow=self->super.shadow;
-
- shadow[TAS3001C_REG_DRC][1] = 0xc1;
-
- if (flags & TAS_DRCE_THRESHOLD) {
- self->drce_state.threshold=quantize_db(drce->threshold);
- shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
- }
-
- if (flags & TAS_DRCE_ENABLE) {
- self->drce_state.enable = drce->enable;
- }
-
- if (!self->drce_state.enable) {
- shadow[TAS3001C_REG_DRC][0] = 0xf0;
- }
-
-#ifdef DEBUG_DRCE
- printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n",
- self->drce_state.enable,
- self->drce_state.threshold);
-
- printk("DRCE IOCTL: reg [ %02x %02x ]\n",
- (unsigned char)shadow[TAS3001C_REG_DRC][0],
- (unsigned char)shadow[TAS3001C_REG_DRC][1]);
-#endif
-
- return tas3001c_sync_register(self, TAS3001C_REG_DRC);
-}
-
-static int
-tas3001c_drce_rw( struct tas3001c_data_t *self,
- u_int cmd,
- u_long arg)
-{
- int rc;
- struct tas_drce_ctrl_t drce_ctrl;
- void __user *argp = (void __user *)arg;
-
- if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
- return -EFAULT;
-
-#ifdef DEBUG_DRCE
- printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n",
- drce_ctrl.flags,
- drce_ctrl.data.enable,
- drce_ctrl.data.threshold);
-#endif
-
- if (cmd & SIOC_IN) {
- rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
- if (rc < 0)
- return rc;
- }
-
- if (cmd & SIOC_OUT) {
- if (drce_ctrl.flags & TAS_DRCE_ENABLE)
- drce_ctrl.data.enable = self->drce_state.enable;
-
- if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
- drce_ctrl.data.threshold = self->drce_state.threshold;
-
- if (copy_to_user(argp, &drce_ctrl,
- sizeof(struct tas_drce_ctrl_t))) {
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-static void
-tas3001c_update_device_parameters(struct tas3001c_data_t *self)
-{
- int i,j;
-
- if (!self) return;
-
- if (self->output_id == TAS_OUTPUT_HEADPHONES) {
- tas3001c_fast_load(self, 1);
-
- for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) {
- for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) {
- tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity);
- }
- }
-
- tas3001c_fast_load(self, 0);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_BASS);
- (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME);
-
- return;
- }
-
- for (i=0; tas3001c_eq_prefs[i]; i++) {
- struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i];
-
- if (eq->device_id == self->device_id &&
- (eq->output_id == 0 || eq->output_id == self->output_id) &&
- (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
-
- tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce);
- tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
-
- break;
- }
- }
-}
-
-static void
-tas3001c_device_change_handler(struct work_struct *work)
-{
- struct tas3001c_data_t *self;
- self = container_of(work, struct tas3001c_data_t, change);
- tas3001c_update_device_parameters(self);
-}
-
-static int
-tas3001c_output_device_change( struct tas3001c_data_t *self,
- int device_id,
- int output_id,
- int speaker_id)
-{
- self->device_id=device_id;
- self->output_id=output_id;
- self->speaker_id=speaker_id;
-
- schedule_work(&self->change);
- return 0;
-}
-
-static int
-tas3001c_device_ioctl( struct tas3001c_data_t *self,
- u_int cmd,
- u_long arg)
-{
- uint __user *argp = (void __user *)arg;
- switch (cmd) {
- case TAS_READ_EQ:
- case TAS_WRITE_EQ:
- return tas3001c_eq_rw(self, cmd, arg);
-
- case TAS_READ_EQ_LIST:
- case TAS_WRITE_EQ_LIST:
- return tas3001c_eq_list_rw(self, cmd, arg);
-
- case TAS_READ_EQ_FILTER_COUNT:
- put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp);
- return 0;
-
- case TAS_READ_EQ_CHANNEL_COUNT:
- put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp);
- return 0;
-
- case TAS_READ_DRCE:
- case TAS_WRITE_DRCE:
- return tas3001c_drce_rw(self, cmd, arg);
-
- case TAS_READ_DRCE_CAPS:
- put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp);
- return 0;
-
- case TAS_READ_DRCE_MIN:
- case TAS_READ_DRCE_MAX: {
- struct tas_drce_ctrl_t drce_ctrl;
-
- if (copy_from_user(&drce_ctrl, argp,
- sizeof(struct tas_drce_ctrl_t))) {
- return -EFAULT;
- }
-
- if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
- if (cmd == TAS_READ_DRCE_MIN) {
- drce_ctrl.data.threshold=-36<<8;
- } else {
- drce_ctrl.data.threshold=-6<<8;
- }
- }
-
- if (copy_to_user(argp, &drce_ctrl,
- sizeof(struct tas_drce_ctrl_t))) {
- return -EFAULT;
- }
- }
- }
-
- return -EINVAL;
-}
-
-static int
-tas3001c_init_mixer(struct tas3001c_data_t *self)
-{
- unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
- /* Make sure something answers on the i2c bus */
- if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr,
- WRITE_NORMAL|FORCE_WRITE) < 0)
- return -1;
-
- tas3001c_fast_load(self, 1);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5);
- (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6);
-
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5);
- (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6);
-
- tas3001c_fast_load(self, 0);
-
- tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
- tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
- tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-
- tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
- tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
-
- return 0;
-}
-
-static int
-tas3001c_uninit_mixer(struct tas3001c_data_t *self)
-{
- tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
- tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0);
- tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
-
- tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0);
- tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
-
- return 0;
-}
-
-static int
-tas3001c_init(struct i2c_client *client)
-{
- struct tas3001c_data_t *self;
- size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t));
- int i, j;
-
- self = kzalloc(sz, GFP_KERNEL);
- if (!self)
- return -ENOMEM;
-
- self->super.client = client;
- self->super.shadow = (tas_shadow_t *)(self+1);
- self->output_id = TAS_OUTPUT_HEADPHONES;
-
- dev_set_drvdata(&client->dev, self);
-
- for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++)
- for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++)
- tas3001c_write_biquad_shadow(self, i, j,
- &tas3001c_eq_unity);
-
- INIT_WORK(&self->change, tas3001c_device_change_handler);
- return 0;
-}
-
-static void
-tas3001c_uninit(struct tas3001c_data_t *self)
-{
- tas3001c_uninit_mixer(self);
- kfree(self);
-}
-
-struct tas_driver_hooks_t tas3001c_hooks = {
- .init = (tas_hook_init_t)tas3001c_init,
- .post_init = (tas_hook_post_init_t)tas3001c_init_mixer,
- .uninit = (tas_hook_uninit_t)tas3001c_uninit,
- .get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level,
- .set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level,
- .enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep,
- .leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep,
- .supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers,
- .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo,
- .stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers,
- .output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change,
- .device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl
-};
diff --git a/sound/oss/dmasound/tas3001c.h b/sound/oss/dmasound/tas3001c.h
deleted file mode 100644
index 3660da33a2d..00000000000
--- a/sound/oss/dmasound/tas3001c.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Header file for the i2c/i2s based TA3001c sound chip used
- * on some Apple hardware. Also known as "tumbler".
- *
- * 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.
- *
- * Written by Christopher C. Chimelis <chris@debian.org>
- */
-
-#ifndef _TAS3001C_H_
-#define _TAS3001C_H_
-
-#include <linux/types.h>
-
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-/*
- * Macros that correspond to the registers that we write to
- * when setting the various values.
- */
-
-#define TAS3001C_VERSION "0.3"
-#define TAS3001C_DATE "20011214"
-
-#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION
-#define I2C_DRIVERID_TAS3001C (I2C_DRIVERID_TAS_BASE+0)
-
-extern struct tas_driver_hooks_t tas3001c_hooks;
-extern struct tas_gain_t tas3001c_gain;
-extern struct tas_eq_pref_t *tas3001c_eq_prefs[];
-
-enum tas3001c_reg_t {
- TAS3001C_REG_MCR = 0x01,
- TAS3001C_REG_DRC = 0x02,
-
- TAS3001C_REG_VOLUME = 0x04,
- TAS3001C_REG_TREBLE = 0x05,
- TAS3001C_REG_BASS = 0x06,
- TAS3001C_REG_MIXER1 = 0x07,
- TAS3001C_REG_MIXER2 = 0x08,
-
- TAS3001C_REG_LEFT_BIQUAD0 = 0x0a,
- TAS3001C_REG_LEFT_BIQUAD1 = 0x0b,
- TAS3001C_REG_LEFT_BIQUAD2 = 0x0c,
- TAS3001C_REG_LEFT_BIQUAD3 = 0x0d,
- TAS3001C_REG_LEFT_BIQUAD4 = 0x0e,
- TAS3001C_REG_LEFT_BIQUAD5 = 0x0f,
- TAS3001C_REG_LEFT_BIQUAD6 = 0x10,
-
- TAS3001C_REG_RIGHT_BIQUAD0 = 0x13,
- TAS3001C_REG_RIGHT_BIQUAD1 = 0x14,
- TAS3001C_REG_RIGHT_BIQUAD2 = 0x15,
- TAS3001C_REG_RIGHT_BIQUAD3 = 0x16,
- TAS3001C_REG_RIGHT_BIQUAD4 = 0x17,
- TAS3001C_REG_RIGHT_BIQUAD5 = 0x18,
- TAS3001C_REG_RIGHT_BIQUAD6 = 0x19,
-
- TAS3001C_REG_MAX = 0x20
-};
-
-#endif /* _TAS3001C_H_ */
diff --git a/sound/oss/dmasound/tas3001c_tables.c b/sound/oss/dmasound/tas3001c_tables.c
deleted file mode 100644
index 1768fa95f25..00000000000
--- a/sound/oss/dmasound/tas3001c_tables.c
+++ /dev/null
@@ -1,375 +0,0 @@
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-static struct tas_drce_t eqp_0e_2_1_drce = {
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -15.33 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-};
-
-static struct tas_eq_pref_t eqp_0e_2_1 = {
- .sample_rate = 44100,
- .device_id = 0x0e,
- .output_id = TAS_OUTPUT_EXTERNAL_SPKR,
- .speaker_id = 0x01,
-
- .drce = &eqp_0e_2_1_drce,
-
- .filter_count = 12,
- .biquads = eqp_0e_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_10_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -12.46 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-};
-
-static struct tas_eq_pref_t eqp_10_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x10,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_10_1_0_drce,
-
- .filter_count = 12,
- .biquads = eqp_10_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_15_2_1_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -15.33 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-};
-
-static struct tas_eq_pref_t eqp_15_2_1 = {
- .sample_rate = 44100,
- .device_id = 0x15,
- .output_id = TAS_OUTPUT_EXTERNAL_SPKR,
- .speaker_id = 0x01,
-
- .drce = &eqp_15_2_1_drce,
-
- .filter_count = 12,
- .biquads = eqp_15_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_15_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = 0.0 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } },
-};
-
-static struct tas_eq_pref_t eqp_15_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x15,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_15_1_0_drce,
-
- .filter_count = 12,
- .biquads = eqp_15_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_0f_2_1_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -15.33 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } },
-};
-
-static struct tas_eq_pref_t eqp_0f_2_1 = {
- .sample_rate = 44100,
- .device_id = 0x0f,
- .output_id = TAS_OUTPUT_EXTERNAL_SPKR,
- .speaker_id = 0x01,
-
- .drce = &eqp_0f_2_1_drce,
-
- .filter_count = 12,
- .biquads = eqp_0f_2_1_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_0f_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -15.33 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } },
-};
-
-static struct tas_eq_pref_t eqp_0f_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x0f,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_0f_1_0_drce,
-
- .filter_count = 12,
- .biquads = eqp_0f_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static uint tas3001c_master_tab[]={
- 0x0, 0x75, 0x9c, 0xbb,
- 0xdb, 0xfb, 0x11e, 0x143,
- 0x16b, 0x196, 0x1c3, 0x1f5,
- 0x229, 0x263, 0x29f, 0x2e1,
- 0x328, 0x373, 0x3c5, 0x41b,
- 0x478, 0x4dc, 0x547, 0x5b8,
- 0x633, 0x6b5, 0x740, 0x7d5,
- 0x873, 0x91c, 0x9d2, 0xa92,
- 0xb5e, 0xc39, 0xd22, 0xe19,
- 0xf20, 0x1037, 0x1161, 0x129e,
- 0x13ed, 0x1551, 0x16ca, 0x185d,
- 0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
- 0x21c1, 0x23fa, 0x2655, 0x28d6,
- 0x2b7c, 0x2e4a, 0x3141, 0x3464,
- 0x37b4, 0x3b35, 0x3ee9, 0x42d3,
- 0x46f6, 0x4b53, 0x4ff0, 0x54ce,
- 0x59f2, 0x5f5f, 0x6519, 0x6b24,
- 0x7183, 0x783c, 0x7f53, 0x86cc,
- 0x8ead, 0x96fa, 0x9fba, 0xa8f2,
- 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
- 0xdee8, 0xeb75, 0xf8aa, 0x1068e,
- 0x1152a, 0x12487, 0x134ad, 0x145a5,
- 0x1577b, 0x16a37, 0x17df5, 0x192bd,
- 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
- 0x20b55, 0x22727, 0x24456, 0x262f2,
- 0x2830b
-};
-
-static uint tas3001c_mixer_tab[]={
- 0x0, 0x748, 0x9be, 0xbaf,
- 0xda4, 0xfb1, 0x11de, 0x1431,
- 0x16ad, 0x1959, 0x1c37, 0x1f4b,
- 0x2298, 0x2628, 0x29fb, 0x2e12,
- 0x327d, 0x3734, 0x3c47, 0x41b4,
- 0x4787, 0x4dbe, 0x546d, 0x5b86,
- 0x632e, 0x6b52, 0x7400, 0x7d54,
- 0x873b, 0x91c6, 0x9d1a, 0xa920,
- 0xb5e5, 0xc38c, 0xd21b, 0xe18f,
- 0xf1f5, 0x1036a, 0x1160f, 0x129d6,
- 0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
- 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
- 0x21c0f, 0x23fa3, 0x26552, 0x28d64,
- 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
- 0x37b44, 0x3b353, 0x3ee94, 0x42d30,
- 0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
- 0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
- 0x71835, 0x783c3, 0x7f52c, 0x86cc0,
- 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
- 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
- 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
- 0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
- 0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
- 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
- 0x20b542, 0x227268, 0x244564, 0x262f26,
- 0x2830af
-};
-
-static uint tas3001c_treble_tab[]={
- 0x96, 0x95, 0x95, 0x94,
- 0x93, 0x92, 0x92, 0x91,
- 0x90, 0x90, 0x8f, 0x8e,
- 0x8d, 0x8d, 0x8c, 0x8b,
- 0x8a, 0x8a, 0x89, 0x88,
- 0x88, 0x87, 0x86, 0x85,
- 0x85, 0x84, 0x83, 0x83,
- 0x82, 0x81, 0x80, 0x80,
- 0x7f, 0x7e, 0x7e, 0x7d,
- 0x7c, 0x7b, 0x7b, 0x7a,
- 0x79, 0x78, 0x78, 0x77,
- 0x76, 0x76, 0x75, 0x74,
- 0x73, 0x73, 0x72, 0x71,
- 0x71, 0x70, 0x6e, 0x6d,
- 0x6d, 0x6c, 0x6b, 0x6a,
- 0x69, 0x68, 0x67, 0x66,
- 0x65, 0x63, 0x62, 0x62,
- 0x60, 0x5f, 0x5d, 0x5c,
- 0x5a, 0x58, 0x56, 0x55,
- 0x53, 0x51, 0x4f, 0x4c,
- 0x4a, 0x48, 0x45, 0x43,
- 0x40, 0x3d, 0x3a, 0x37,
- 0x35, 0x32, 0x2e, 0x2a,
- 0x27, 0x22, 0x1e, 0x1a,
- 0x15, 0x11, 0xc, 0x7,
- 0x1
-};
-
-static uint tas3001c_bass_tab[]={
- 0x86, 0x83, 0x81, 0x7f,
- 0x7d, 0x7b, 0x79, 0x78,
- 0x76, 0x75, 0x74, 0x72,
- 0x71, 0x6f, 0x6e, 0x6d,
- 0x6c, 0x6b, 0x69, 0x67,
- 0x65, 0x64, 0x61, 0x60,
- 0x5e, 0x5d, 0x5c, 0x5b,
- 0x5a, 0x59, 0x58, 0x57,
- 0x56, 0x55, 0x55, 0x54,
- 0x53, 0x52, 0x50, 0x4f,
- 0x4d, 0x4c, 0x4b, 0x49,
- 0x47, 0x45, 0x44, 0x42,
- 0x41, 0x3f, 0x3e, 0x3d,
- 0x3c, 0x3b, 0x39, 0x38,
- 0x37, 0x36, 0x35, 0x34,
- 0x33, 0x31, 0x30, 0x2f,
- 0x2e, 0x2c, 0x2b, 0x2b,
- 0x29, 0x28, 0x27, 0x26,
- 0x25, 0x24, 0x22, 0x21,
- 0x20, 0x1e, 0x1c, 0x19,
- 0x18, 0x18, 0x17, 0x16,
- 0x15, 0x14, 0x13, 0x12,
- 0x11, 0x10, 0xf, 0xe,
- 0xd, 0xb, 0xa, 0x9,
- 0x8, 0x6, 0x4, 0x2,
- 0x1
-};
-
-struct tas_gain_t tas3001c_gain = {
- .master = tas3001c_master_tab,
- .treble = tas3001c_treble_tab,
- .bass = tas3001c_bass_tab,
- .mixer = tas3001c_mixer_tab
-};
-
-struct tas_eq_pref_t *tas3001c_eq_prefs[]={
- &eqp_0e_2_1,
- &eqp_10_1_0,
- &eqp_15_2_1,
- &eqp_15_1_0,
- &eqp_0f_2_1,
- &eqp_0f_1_0,
- NULL
-};
diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c
deleted file mode 100644
index 678bf0ff6da..00000000000
--- a/sound/oss/dmasound/tas3004.c
+++ /dev/null
@@ -1,1138 +0,0 @@
-/*
- * Driver for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "snapper".
- *
- * Tobias Sargeant <tobias.sargeant@bigpond.com>
- * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
- *
- * Input support by Renzo Davoli <renzo@cs.unibo.it>
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "dmasound.h"
-#include "tas_common.h"
-#include "tas3004.h"
-
-#include "tas_ioctl.h"
-
-/* #define DEBUG_DRCE */
-
-#define TAS3004_BIQUAD_FILTER_COUNT 7
-#define TAS3004_BIQUAD_CHANNEL_COUNT 2
-
-#define VOL_DEFAULT (100 * 4 / 5)
-#define INPUT_DEFAULT (100 * 4 / 5)
-#define BASS_DEFAULT (100 / 2)
-#define TREBLE_DEFAULT (100 / 2)
-
-struct tas3004_data_t {
- struct tas_data_t super;
- int device_id;
- int output_id;
- int speaker_id;
- struct tas_drce_t drce_state;
- struct work_struct change;
-};
-
-#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
-
-#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
-
-
-static const union tas_biquad_t tas3004_eq_unity = {
- .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
-};
-
-
-static const struct tas_drce_t tas3004_drce_min = {
- .enable = 1,
- .above = { .val = MAKE_RATIO(16,0), .expand = 0 },
- .below = { .val = MAKE_RATIO(2,0), .expand = 0 },
- .threshold = -0x59a0,
- .energy = MAKE_TIME(0, 1700),
- .attack = MAKE_TIME(0, 1700),
- .decay = MAKE_TIME(0, 1700),
-};
-
-
-static const struct tas_drce_t tas3004_drce_max = {
- .enable = 1,
- .above = { .val = MAKE_RATIO(1,500), .expand = 1 },
- .below = { .val = MAKE_RATIO(2,0), .expand = 1 },
- .threshold = -0x0,
- .energy = MAKE_TIME(2,400000),
- .attack = MAKE_TIME(2,400000),
- .decay = MAKE_TIME(2,400000),
-};
-
-
-static const unsigned short time_constants[]={
- MAKE_TIME(0, 1700),
- MAKE_TIME(0, 3500),
- MAKE_TIME(0, 6700),
- MAKE_TIME(0, 13000),
- MAKE_TIME(0, 26000),
- MAKE_TIME(0, 53000),
- MAKE_TIME(0,106000),
- MAKE_TIME(0,212000),
- MAKE_TIME(0,425000),
- MAKE_TIME(0,850000),
- MAKE_TIME(1,700000),
- MAKE_TIME(2,400000),
-};
-
-static const unsigned short above_threshold_compression_ratio[]={
- MAKE_RATIO( 1, 70),
- MAKE_RATIO( 1,140),
- MAKE_RATIO( 1,230),
- MAKE_RATIO( 1,330),
- MAKE_RATIO( 1,450),
- MAKE_RATIO( 1,600),
- MAKE_RATIO( 1,780),
- MAKE_RATIO( 2, 0),
- MAKE_RATIO( 2,290),
- MAKE_RATIO( 2,670),
- MAKE_RATIO( 3,200),
- MAKE_RATIO( 4, 0),
- MAKE_RATIO( 5,330),
- MAKE_RATIO( 8, 0),
- MAKE_RATIO(16, 0),
-};
-
-static const unsigned short above_threshold_expansion_ratio[]={
- MAKE_RATIO(1, 60),
- MAKE_RATIO(1,130),
- MAKE_RATIO(1,190),
- MAKE_RATIO(1,250),
- MAKE_RATIO(1,310),
- MAKE_RATIO(1,380),
- MAKE_RATIO(1,440),
- MAKE_RATIO(1,500)
-};
-
-static const unsigned short below_threshold_compression_ratio[]={
- MAKE_RATIO(1, 70),
- MAKE_RATIO(1,140),
- MAKE_RATIO(1,230),
- MAKE_RATIO(1,330),
- MAKE_RATIO(1,450),
- MAKE_RATIO(1,600),
- MAKE_RATIO(1,780),
- MAKE_RATIO(2, 0)
-};
-
-static const unsigned short below_threshold_expansion_ratio[]={
- MAKE_RATIO(1, 60),
- MAKE_RATIO(1,130),
- MAKE_RATIO(1,190),
- MAKE_RATIO(1,250),
- MAKE_RATIO(1,310),
- MAKE_RATIO(1,380),
- MAKE_RATIO(1,440),
- MAKE_RATIO(1,500),
- MAKE_RATIO(1,560),
- MAKE_RATIO(1,630),
- MAKE_RATIO(1,690),
- MAKE_RATIO(1,750),
- MAKE_RATIO(1,810),
- MAKE_RATIO(1,880),
- MAKE_RATIO(1,940),
- MAKE_RATIO(2, 0)
-};
-
-static inline int
-search( unsigned short val,
- const unsigned short *arr,
- const int arrsize) {
- /*
- * This could be a binary search, but for small tables,
- * a linear search is likely to be faster
- */
-
- int i;
-
- for (i=0; i < arrsize; i++)
- if (arr[i] >= val)
- goto _1;
- return arrsize-1;
- _1:
- if (i == 0)
- return 0;
- return (arr[i]-val < val-arr[i-1]) ? i : i-1;
-}
-
-#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
-
-static inline int
-time_index(unsigned short time)
-{
- return SEARCH(time, time_constants);
-}
-
-
-static inline int
-above_threshold_compression_index(unsigned short ratio)
-{
- return SEARCH(ratio, above_threshold_compression_ratio);
-}
-
-
-static inline int
-above_threshold_expansion_index(unsigned short ratio)
-{
- return SEARCH(ratio, above_threshold_expansion_ratio);
-}
-
-
-static inline int
-below_threshold_compression_index(unsigned short ratio)
-{
- return SEARCH(ratio, below_threshold_compression_ratio);
-}
-
-
-static inline int
-below_threshold_expansion_index(unsigned short ratio)
-{
- return SEARCH(ratio, below_threshold_expansion_ratio);
-}
-
-static inline unsigned char db_to_regval(short db) {
- int r=0;
-
- r=(db+0x59a0) / 0x60;
-
- if (r < 0x91) return 0x91;
- if (r > 0xef) return 0xef;
- return r;
-}
-
-static inline short quantize_db(short db)
-{
- return db_to_regval(db) * 0x60 - 0x59a0;
-}
-
-static inline int
-register_width(enum tas3004_reg_t r)
-{
- switch(r) {
- case TAS3004_REG_MCR:
- case TAS3004_REG_TREBLE:
- case TAS3004_REG_BASS:
- case TAS3004_REG_ANALOG_CTRL:
- case TAS3004_REG_TEST1:
- case TAS3004_REG_TEST2:
- case TAS3004_REG_MCR2:
- return 1;
-
- case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
- case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
- return 3;
-
- case TAS3004_REG_DRC:
- case TAS3004_REG_VOLUME:
- return 6;
-
- case TAS3004_REG_LEFT_MIXER:
- case TAS3004_REG_RIGHT_MIXER:
- return 9;
-
- case TAS3004_REG_TEST:
- return 10;
-
- case TAS3004_REG_LEFT_BIQUAD0:
- case TAS3004_REG_LEFT_BIQUAD1:
- case TAS3004_REG_LEFT_BIQUAD2:
- case TAS3004_REG_LEFT_BIQUAD3:
- case TAS3004_REG_LEFT_BIQUAD4:
- case TAS3004_REG_LEFT_BIQUAD5:
- case TAS3004_REG_LEFT_BIQUAD6:
-
- case TAS3004_REG_RIGHT_BIQUAD0:
- case TAS3004_REG_RIGHT_BIQUAD1:
- case TAS3004_REG_RIGHT_BIQUAD2:
- case TAS3004_REG_RIGHT_BIQUAD3:
- case TAS3004_REG_RIGHT_BIQUAD4:
- case TAS3004_REG_RIGHT_BIQUAD5:
- case TAS3004_REG_RIGHT_BIQUAD6:
-
- case TAS3004_REG_LEFT_LOUD_BIQUAD:
- case TAS3004_REG_RIGHT_LOUD_BIQUAD:
- return 15;
-
- default:
- return 0;
- }
-}
-
-static int
-tas3004_write_register( struct tas3004_data_t *self,
- enum tas3004_reg_t reg_num,
- char *data,
- uint write_mode)
-{
- if (reg_num==TAS3004_REG_MCR ||
- reg_num==TAS3004_REG_BASS ||
- reg_num==TAS3004_REG_TREBLE ||
- reg_num==TAS3004_REG_ANALOG_CTRL) {
- return tas_write_byte_register(&self->super,
- (uint)reg_num,
- *data,
- write_mode);
- } else {
- return tas_write_register(&self->super,
- (uint)reg_num,
- register_width(reg_num),
- data,
- write_mode);
- }
-}
-
-static int
-tas3004_sync_register( struct tas3004_data_t *self,
- enum tas3004_reg_t reg_num)
-{
- if (reg_num==TAS3004_REG_MCR ||
- reg_num==TAS3004_REG_BASS ||
- reg_num==TAS3004_REG_TREBLE ||
- reg_num==TAS3004_REG_ANALOG_CTRL) {
- return tas_sync_byte_register(&self->super,
- (uint)reg_num,
- register_width(reg_num));
- } else {
- return tas_sync_register(&self->super,
- (uint)reg_num,
- register_width(reg_num));
- }
-}
-
-static int
-tas3004_read_register( struct tas3004_data_t *self,
- enum tas3004_reg_t reg_num,
- char *data,
- uint write_mode)
-{
- return tas_read_register(&self->super,
- (uint)reg_num,
- register_width(reg_num),
- data);
-}
-
-static inline int
-tas3004_fast_load(struct tas3004_data_t *self, int fast)
-{
- if (fast)
- self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
- else
- self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
- return tas3004_sync_register(self,TAS3004_REG_MCR);
-}
-
-static uint
-tas3004_supported_mixers(struct tas3004_data_t *self)
-{
- return SOUND_MASK_VOLUME |
- SOUND_MASK_PCM |
- SOUND_MASK_ALTPCM |
- SOUND_MASK_IMIX |
- SOUND_MASK_TREBLE |
- SOUND_MASK_BASS |
- SOUND_MASK_MIC |
- SOUND_MASK_LINE;
-}
-
-static int
-tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
-{
- switch(mixer) {
- case SOUND_MIXER_VOLUME:
- case SOUND_MIXER_PCM:
- case SOUND_MIXER_ALTPCM:
- case SOUND_MIXER_IMIX:
- return 1;
- default:
- return 0;
- }
-}
-
-static uint
-tas3004_stereo_mixers(struct tas3004_data_t *self)
-{
- uint r = tas3004_supported_mixers(self);
- uint i;
-
- for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
- if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
- r &= ~(1<<i);
- return r;
-}
-
-static int
-tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
-{
- if (!self)
- return -1;
-
- *level = self->super.mixer[mixer];
-
- return 0;
-}
-
-static int
-tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
-{
- int rc;
- tas_shadow_t *shadow;
- uint temp;
- uint offset=0;
-
- if (!self)
- return -1;
-
- shadow = self->super.shadow;
-
- if (!tas3004_mixer_is_stereo(self,mixer))
- level = tas_mono_to_stereo(level);
- switch(mixer) {
- case SOUND_MIXER_VOLUME:
- temp = tas3004_gain.master[level&0xff];
- SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
- temp = tas3004_gain.master[(level>>8)&0xff];
- SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
- rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
- break;
- case SOUND_MIXER_IMIX:
- offset += 3;
- case SOUND_MIXER_ALTPCM:
- offset += 3;
- case SOUND_MIXER_PCM:
- /*
- * Don't load these in fast mode. The documentation
- * says it can be done in either mode, but testing it
- * shows that fast mode produces ugly clicking.
- */
- /* tas3004_fast_load(self,1); */
- temp = tas3004_gain.mixer[level&0xff];
- SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
- temp = tas3004_gain.mixer[(level>>8)&0xff];
- SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
- rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
- if (rc == 0)
- rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
- /* tas3004_fast_load(self,0); */
- break;
- case SOUND_MIXER_TREBLE:
- temp = tas3004_gain.treble[level&0xff];
- shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
- rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
- break;
- case SOUND_MIXER_BASS:
- temp = tas3004_gain.bass[level&0xff];
- shadow[TAS3004_REG_BASS][0]=temp&0xff;
- rc = tas3004_sync_register(self,TAS3004_REG_BASS);
- break;
- case SOUND_MIXER_MIC:
- if ((level&0xff)>0) {
- software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
- if (self->super.mixer[mixer] == 0) {
- self->super.mixer[SOUND_MIXER_LINE] = 0;
- shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
- rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
- } else rc=0;
- } else {
- self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
- software_input_volume = SW_INPUT_VOLUME_SCALE *
- (self->super.mixer[SOUND_MIXER_LINE]&0xff);
- shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
- rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
- }
- break;
- case SOUND_MIXER_LINE:
- if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
- software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
- rc=0;
- }
- break;
- default:
- rc = -1;
- break;
- }
- if (rc < 0)
- return rc;
- self->super.mixer[mixer] = level;
-
- return 0;
-}
-
-static int
-tas3004_leave_sleep(struct tas3004_data_t *self)
-{
- unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
- if (!self)
- return -1;
-
- /* Make sure something answers on the i2c bus */
- if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
- WRITE_NORMAL | FORCE_WRITE) < 0)
- return -1;
-
- tas3004_fast_load(self, 1);
-
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
-
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
-
- tas3004_fast_load(self, 0);
-
- (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
- (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
- (void)tas3004_sync_register(self,TAS3004_REG_BASS);
- (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
-
- return 0;
-}
-
-static int
-tas3004_enter_sleep(struct tas3004_data_t *self)
-{
- if (!self)
- return -1;
- return 0;
-}
-
-static int
-tas3004_sync_biquad( struct tas3004_data_t *self,
- u_int channel,
- u_int filter)
-{
- enum tas3004_reg_t reg;
-
- if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
- filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
- reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
- return tas3004_sync_register(self,reg);
-}
-
-static int
-tas3004_write_biquad_shadow( struct tas3004_data_t *self,
- u_int channel,
- u_int filter,
- const union tas_biquad_t *biquad)
-{
- tas_shadow_t *shadow=self->super.shadow;
- enum tas3004_reg_t reg;
-
- if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
- filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
- reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
- SET_4_20(shadow[reg], 0,biquad->coeff.b0);
- SET_4_20(shadow[reg], 3,biquad->coeff.b1);
- SET_4_20(shadow[reg], 6,biquad->coeff.b2);
- SET_4_20(shadow[reg], 9,biquad->coeff.a1);
- SET_4_20(shadow[reg],12,biquad->coeff.a2);
-
- return 0;
-}
-
-static int
-tas3004_write_biquad( struct tas3004_data_t *self,
- u_int channel,
- u_int filter,
- const union tas_biquad_t *biquad)
-{
- int rc;
-
- rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
- if (rc < 0) return rc;
-
- return tas3004_sync_biquad(self, channel, filter);
-}
-
-static int
-tas3004_write_biquad_list( struct tas3004_data_t *self,
- u_int filter_count,
- u_int flags,
- struct tas_biquad_ctrl_t *biquads)
-{
- int i;
- int rc;
-
- if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
-
- for (i=0; i<filter_count; i++) {
- rc=tas3004_write_biquad(self,
- biquads[i].channel,
- biquads[i].filter,
- &biquads[i].data);
- if (rc < 0) break;
- }
-
- if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
-
- return rc;
-}
-
-static int
-tas3004_read_biquad( struct tas3004_data_t *self,
- u_int channel,
- u_int filter,
- union tas_biquad_t *biquad)
-{
- tas_shadow_t *shadow=self->super.shadow;
- enum tas3004_reg_t reg;
-
- if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
- filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
-
- reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
-
- biquad->coeff.b0=GET_4_20(shadow[reg], 0);
- biquad->coeff.b1=GET_4_20(shadow[reg], 3);
- biquad->coeff.b2=GET_4_20(shadow[reg], 6);
- biquad->coeff.a1=GET_4_20(shadow[reg], 9);
- biquad->coeff.a2=GET_4_20(shadow[reg],12);
-
- return 0;
-}
-
-static int
-tas3004_eq_rw( struct tas3004_data_t *self,
- u_int cmd,
- u_long arg)
-{
- void __user *argp = (void __user *)arg;
- int rc;
- struct tas_biquad_ctrl_t biquad;
-
- if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
-
- if (cmd & SIOC_IN) {
- rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
- }
-
- if (cmd & SIOC_OUT) {
- rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
-
- if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
-
- }
- return 0;
-}
-
-static int
-tas3004_eq_list_rw( struct tas3004_data_t *self,
- u_int cmd,
- u_long arg)
-{
- int rc = 0;
- int filter_count;
- int flags;
- int i,j;
- char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
- struct tas_biquad_ctrl_t biquad;
- struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
-
- memset(sync_required,0,sizeof(sync_required));
-
- if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
- return -EFAULT;
-
- if (copy_from_user(&flags, &argp->flags, sizeof(int)))
- return -EFAULT;
-
- if (cmd & SIOC_IN) {
- }
-
- for (i=0; i < filter_count; i++) {
- if (copy_from_user(&biquad, &argp->biquads[i],
- sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
-
- if (cmd & SIOC_IN) {
- sync_required[biquad.channel][biquad.filter]=1;
- rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
- }
-
- if (cmd & SIOC_OUT) {
- rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
- if (rc != 0) return rc;
-
- if (copy_to_user(&argp->biquads[i], &biquad,
- sizeof(struct tas_biquad_ctrl_t))) {
- return -EFAULT;
- }
- }
- }
-
- if (cmd & SIOC_IN) {
- /*
- * This is OK for the tas3004. For the
- * tas3001c, going into fast load mode causes
- * the treble and bass to be reset to 0dB, and
- * volume controls to be muted.
- */
- if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
- for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
- for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
- if (sync_required[i][j]) {
- rc=tas3004_sync_biquad(self, i, j);
- if (rc < 0) goto out;
- }
- }
- }
- out:
- if (flags & TAS_BIQUAD_FAST_LOAD)
- tas3004_fast_load(self,0);
- }
-
- return rc;
-}
-
-static int
-tas3004_update_drce( struct tas3004_data_t *self,
- int flags,
- struct tas_drce_t *drce)
-{
- tas_shadow_t *shadow;
- int i;
- shadow=self->super.shadow;
-
- if (flags & TAS_DRCE_ABOVE_RATIO) {
- self->drce_state.above.expand = drce->above.expand;
- if (drce->above.val == (1<<8)) {
- self->drce_state.above.val = 1<<8;
- shadow[TAS3004_REG_DRC][0] = 0x02;
-
- } else if (drce->above.expand) {
- i=above_threshold_expansion_index(drce->above.val);
- self->drce_state.above.val=above_threshold_expansion_ratio[i];
- shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
- } else {
- i=above_threshold_compression_index(drce->above.val);
- self->drce_state.above.val=above_threshold_compression_ratio[i];
- shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
- }
- }
-
- if (flags & TAS_DRCE_BELOW_RATIO) {
- self->drce_state.below.expand = drce->below.expand;
- if (drce->below.val == (1<<8)) {
- self->drce_state.below.val = 1<<8;
- shadow[TAS3004_REG_DRC][1] = 0x02;
-
- } else if (drce->below.expand) {
- i=below_threshold_expansion_index(drce->below.val);
- self->drce_state.below.val=below_threshold_expansion_ratio[i];
- shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
- } else {
- i=below_threshold_compression_index(drce->below.val);
- self->drce_state.below.val=below_threshold_compression_ratio[i];
- shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
- }
- }
-
- if (flags & TAS_DRCE_THRESHOLD) {
- self->drce_state.threshold=quantize_db(drce->threshold);
- shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
- }
-
- if (flags & TAS_DRCE_ENERGY) {
- i=time_index(drce->energy);
- self->drce_state.energy=time_constants[i];
- shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
- }
-
- if (flags & TAS_DRCE_ATTACK) {
- i=time_index(drce->attack);
- self->drce_state.attack=time_constants[i];
- shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
- }
-
- if (flags & TAS_DRCE_DECAY) {
- i=time_index(drce->decay);
- self->drce_state.decay=time_constants[i];
- shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
- }
-
- if (flags & TAS_DRCE_ENABLE) {
- self->drce_state.enable = drce->enable;
- }
-
- if (!self->drce_state.enable) {
- shadow[TAS3004_REG_DRC][0] |= 0x01;
- }
-
-#ifdef DEBUG_DRCE
- printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
- self->drce_state.enable,
- self->drce_state.above.expand,self->drce_state.above.val,
- self->drce_state.below.expand,self->drce_state.below.val,
- self->drce_state.threshold,
- self->drce_state.energy,
- self->drce_state.attack,
- self->drce_state.decay);
-
- printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
- (unsigned char)shadow[TAS3004_REG_DRC][0],
- (unsigned char)shadow[TAS3004_REG_DRC][1],
- (unsigned char)shadow[TAS3004_REG_DRC][2],
- (unsigned char)shadow[TAS3004_REG_DRC][3],
- (unsigned char)shadow[TAS3004_REG_DRC][4],
- (unsigned char)shadow[TAS3004_REG_DRC][5]);
-#endif
-
- return tas3004_sync_register(self, TAS3004_REG_DRC);
-}
-
-static int
-tas3004_drce_rw( struct tas3004_data_t *self,
- u_int cmd,
- u_long arg)
-{
- int rc;
- struct tas_drce_ctrl_t drce_ctrl;
- void __user *argp = (void __user *)arg;
-
- if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
- return -EFAULT;
-
-#ifdef DEBUG_DRCE
- printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
- drce_ctrl.flags,
- drce_ctrl.data.enable,
- drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
- drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
- drce_ctrl.data.threshold,
- drce_ctrl.data.energy,
- drce_ctrl.data.attack,
- drce_ctrl.data.decay);
-#endif
-
- if (cmd & SIOC_IN) {
- rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
- if (rc < 0) return rc;
- }
-
- if (cmd & SIOC_OUT) {
- if (drce_ctrl.flags & TAS_DRCE_ENABLE)
- drce_ctrl.data.enable = self->drce_state.enable;
- if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
- drce_ctrl.data.above = self->drce_state.above;
- if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
- drce_ctrl.data.below = self->drce_state.below;
- if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
- drce_ctrl.data.threshold = self->drce_state.threshold;
- if (drce_ctrl.flags & TAS_DRCE_ENERGY)
- drce_ctrl.data.energy = self->drce_state.energy;
- if (drce_ctrl.flags & TAS_DRCE_ATTACK)
- drce_ctrl.data.attack = self->drce_state.attack;
- if (drce_ctrl.flags & TAS_DRCE_DECAY)
- drce_ctrl.data.decay = self->drce_state.decay;
-
- if (copy_to_user(argp, &drce_ctrl,
- sizeof(struct tas_drce_ctrl_t))) {
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-static void
-tas3004_update_device_parameters(struct tas3004_data_t *self)
-{
- char data;
- int i;
-
- if (!self) return;
-
- if (self->output_id == TAS_OUTPUT_HEADPHONES) {
- /* turn on allPass when headphones are plugged in */
- data = 0x02;
- } else {
- data = 0x00;
- }
-
- tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
-
- for (i=0; tas3004_eq_prefs[i]; i++) {
- struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
-
- if (eq->device_id == self->device_id &&
- (eq->output_id == 0 || eq->output_id == self->output_id) &&
- (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
-
- tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
- tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
-
- break;
- }
- }
-}
-
-static void
-tas3004_device_change_handler(struct work_struct *work)
-{
- struct tas3004_data_t *self;
- self = container_of(work, struct tas3004_data_t, change);
- tas3004_update_device_parameters(self);
-}
-
-static int
-tas3004_output_device_change( struct tas3004_data_t *self,
- int device_id,
- int output_id,
- int speaker_id)
-{
- self->device_id=device_id;
- self->output_id=output_id;
- self->speaker_id=speaker_id;
-
- schedule_work(&self->change);
-
- return 0;
-}
-
-static int
-tas3004_device_ioctl( struct tas3004_data_t *self,
- u_int cmd,
- u_long arg)
-{
- uint __user *argp = (void __user *)arg;
- switch (cmd) {
- case TAS_READ_EQ:
- case TAS_WRITE_EQ:
- return tas3004_eq_rw(self, cmd, arg);
-
- case TAS_READ_EQ_LIST:
- case TAS_WRITE_EQ_LIST:
- return tas3004_eq_list_rw(self, cmd, arg);
-
- case TAS_READ_EQ_FILTER_COUNT:
- put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
- return 0;
-
- case TAS_READ_EQ_CHANNEL_COUNT:
- put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
- return 0;
-
- case TAS_READ_DRCE:
- case TAS_WRITE_DRCE:
- return tas3004_drce_rw(self, cmd, arg);
-
- case TAS_READ_DRCE_CAPS:
- put_user(TAS_DRCE_ENABLE |
- TAS_DRCE_ABOVE_RATIO |
- TAS_DRCE_BELOW_RATIO |
- TAS_DRCE_THRESHOLD |
- TAS_DRCE_ENERGY |
- TAS_DRCE_ATTACK |
- TAS_DRCE_DECAY,
- argp);
- return 0;
-
- case TAS_READ_DRCE_MIN:
- case TAS_READ_DRCE_MAX: {
- struct tas_drce_ctrl_t drce_ctrl;
- const struct tas_drce_t *drce_copy;
-
- if (copy_from_user(&drce_ctrl, argp,
- sizeof(struct tas_drce_ctrl_t))) {
- return -EFAULT;
- }
-
- if (cmd == TAS_READ_DRCE_MIN) {
- drce_copy=&tas3004_drce_min;
- } else {
- drce_copy=&tas3004_drce_max;
- }
-
- if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
- drce_ctrl.data.above=drce_copy->above;
- }
- if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
- drce_ctrl.data.below=drce_copy->below;
- }
- if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
- drce_ctrl.data.threshold=drce_copy->threshold;
- }
- if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
- drce_ctrl.data.energy=drce_copy->energy;
- }
- if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
- drce_ctrl.data.attack=drce_copy->attack;
- }
- if (drce_ctrl.flags & TAS_DRCE_DECAY) {
- drce_ctrl.data.decay=drce_copy->decay;
- }
-
- if (copy_to_user(argp, &drce_ctrl,
- sizeof(struct tas_drce_ctrl_t))) {
- return -EFAULT;
- }
- }
- }
-
- return -EINVAL;
-}
-
-static int
-tas3004_init_mixer(struct tas3004_data_t *self)
-{
- unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
-
- /* Make sure something answers on the i2c bus */
- if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
- WRITE_NORMAL | FORCE_WRITE) < 0)
- return -1;
-
- tas3004_fast_load(self, 1);
-
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
- (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
-
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
- (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
-
- tas3004_sync_register(self, TAS3004_REG_DRC);
-
- tas3004_sync_register(self, TAS3004_REG_MCR2);
-
- tas3004_fast_load(self, 0);
-
- tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
- tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
- tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
- tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
-
- tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
- tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
-
- tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
-
- return 0;
-}
-
-static int
-tas3004_uninit_mixer(struct tas3004_data_t *self)
-{
- tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
- tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
- tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
- tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
-
- tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
- tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
-
- tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
-
- return 0;
-}
-
-static int
-tas3004_init(struct i2c_client *client)
-{
- struct tas3004_data_t *self;
- size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
- char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
- char mcr2 = 0;
- int i, j;
-
- self = kzalloc(sz, GFP_KERNEL);
- if (!self)
- return -ENOMEM;
-
- self->super.client = client;
- self->super.shadow = (tas_shadow_t *)(self+1);
- self->output_id = TAS_OUTPUT_HEADPHONES;
-
- dev_set_drvdata(&client->dev, self);
-
- for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
- for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
- tas3004_write_biquad_shadow(self, i, j,
- &tas3004_eq_unity);
-
- tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
- tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
-
- INIT_WORK(&self->change, tas3004_device_change_handler);
- return 0;
-}
-
-static void
-tas3004_uninit(struct tas3004_data_t *self)
-{
- tas3004_uninit_mixer(self);
- kfree(self);
-}
-
-
-struct tas_driver_hooks_t tas3004_hooks = {
- .init = (tas_hook_init_t)tas3004_init,
- .post_init = (tas_hook_post_init_t)tas3004_init_mixer,
- .uninit = (tas_hook_uninit_t)tas3004_uninit,
- .get_mixer_level = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
- .set_mixer_level = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
- .enter_sleep = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
- .leave_sleep = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
- .supported_mixers = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
- .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
- .stereo_mixers = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
- .output_device_change = (tas_hook_output_device_change_t)tas3004_output_device_change,
- .device_ioctl = (tas_hook_device_ioctl_t)tas3004_device_ioctl
-};
diff --git a/sound/oss/dmasound/tas3004.h b/sound/oss/dmasound/tas3004.h
deleted file mode 100644
index c6d584bf2ca..00000000000
--- a/sound/oss/dmasound/tas3004.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Header file for the i2c/i2s based TA3004 sound chip used
- * on some Apple hardware. Also known as "tumbler".
- *
- * 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.
- *
- * Written by Christopher C. Chimelis <chris@debian.org>
- */
-
-#ifndef _TAS3004_H_
-#define _TAS3004_H_
-
-#include <linux/types.h>
-
-#include "tas_common.h"
-#include "tas_eq_prefs.h"
-
-/*
- * Macros that correspond to the registers that we write to
- * when setting the various values.
- */
-
-#define TAS3004_VERSION "0.3"
-#define TAS3004_DATE "20011214"
-
-#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION
-#define I2C_DRIVERID_TAS3004 (I2C_DRIVERID_TAS_BASE+1)
-
-extern struct tas_driver_hooks_t tas3004_hooks;
-extern struct tas_gain_t tas3004_gain;
-extern struct tas_eq_pref_t *tas3004_eq_prefs[];
-
-enum tas3004_reg_t {
- TAS3004_REG_MCR = 0x01,
- TAS3004_REG_DRC = 0x02,
-
- TAS3004_REG_VOLUME = 0x04,
- TAS3004_REG_TREBLE = 0x05,
- TAS3004_REG_BASS = 0x06,
- TAS3004_REG_LEFT_MIXER = 0x07,
- TAS3004_REG_RIGHT_MIXER = 0x08,
-
- TAS3004_REG_LEFT_BIQUAD0 = 0x0a,
- TAS3004_REG_LEFT_BIQUAD1 = 0x0b,
- TAS3004_REG_LEFT_BIQUAD2 = 0x0c,
- TAS3004_REG_LEFT_BIQUAD3 = 0x0d,
- TAS3004_REG_LEFT_BIQUAD4 = 0x0e,
- TAS3004_REG_LEFT_BIQUAD5 = 0x0f,
- TAS3004_REG_LEFT_BIQUAD6 = 0x10,
-
- TAS3004_REG_RIGHT_BIQUAD0 = 0x13,
- TAS3004_REG_RIGHT_BIQUAD1 = 0x14,
- TAS3004_REG_RIGHT_BIQUAD2 = 0x15,
- TAS3004_REG_RIGHT_BIQUAD3 = 0x16,
- TAS3004_REG_RIGHT_BIQUAD4 = 0x17,
- TAS3004_REG_RIGHT_BIQUAD5 = 0x18,
- TAS3004_REG_RIGHT_BIQUAD6 = 0x19,
-
- TAS3004_REG_LEFT_LOUD_BIQUAD = 0x21,
- TAS3004_REG_RIGHT_LOUD_BIQUAD = 0x22,
-
- TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN = 0x23,
- TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24,
-
- TAS3004_REG_TEST = 0x29,
-
- TAS3004_REG_ANALOG_CTRL = 0x40,
- TAS3004_REG_TEST1 = 0x41,
- TAS3004_REG_TEST2 = 0x42,
- TAS3004_REG_MCR2 = 0x43,
-
- TAS3004_REG_MAX = 0x44
-};
-
-#endif /* _TAS3004_H_ */
diff --git a/sound/oss/dmasound/tas3004_tables.c b/sound/oss/dmasound/tas3004_tables.c
deleted file mode 100644
index b910e0a6677..00000000000
--- a/sound/oss/dmasound/tas3004_tables.c
+++ /dev/null
@@ -1,301 +0,0 @@
-#include "tas3004.h"
-#include "tas_eq_prefs.h"
-
-static struct tas_drce_t eqp_17_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -19.12 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
- { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } },
- { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }
-};
-
-static struct tas_eq_pref_t eqp_17_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x17,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_17_1_0_drce,
-
- .filter_count = 14,
- .biquads = eqp_17_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_18_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -13.14 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
- { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } },
- { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }
-};
-
-static struct tas_eq_pref_t eqp_18_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x18,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_18_1_0_drce,
-
- .filter_count = 14,
- .biquads = eqp_18_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_1a_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -10.75 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
- { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } },
- { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }
-};
-
-static struct tas_eq_pref_t eqp_1a_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x1a,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_1a_1_0_drce,
-
- .filter_count = 14,
- .biquads = eqp_1a_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static struct tas_drce_t eqp_1c_1_0_drce={
- .enable = 1,
- .above = { .val = 3.0 * (1<<8), .expand = 0 },
- .below = { .val = 1.0 * (1<<8), .expand = 0 },
- .threshold = -14.34 * (1<<8),
- .energy = 2.4 * (1<<12),
- .attack = 0.013 * (1<<12),
- .decay = 0.212 * (1<<12),
-};
-
-static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={
- { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
- { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
- { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
- { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
- { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
- { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
- { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } },
-
- { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } },
- { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } },
- { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } },
- { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } },
- { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } },
- { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } },
- { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }
-};
-
-static struct tas_eq_pref_t eqp_1c_1_0 = {
- .sample_rate = 44100,
- .device_id = 0x1c,
- .output_id = TAS_OUTPUT_INTERNAL_SPKR,
- .speaker_id = 0x00,
-
- .drce = &eqp_1c_1_0_drce,
-
- .filter_count = 14,
- .biquads = eqp_1c_1_0_biquads
-};
-
-/* ======================================================================== */
-
-static uint tas3004_master_tab[]={
- 0x0, 0x75, 0x9c, 0xbb,
- 0xdb, 0xfb, 0x11e, 0x143,
- 0x16b, 0x196, 0x1c3, 0x1f5,
- 0x229, 0x263, 0x29f, 0x2e1,
- 0x328, 0x373, 0x3c5, 0x41b,
- 0x478, 0x4dc, 0x547, 0x5b8,
- 0x633, 0x6b5, 0x740, 0x7d5,
- 0x873, 0x91c, 0x9d2, 0xa92,
- 0xb5e, 0xc39, 0xd22, 0xe19,
- 0xf20, 0x1037, 0x1161, 0x129e,
- 0x13ed, 0x1551, 0x16ca, 0x185d,
- 0x1a08, 0x1bcc, 0x1dac, 0x1fa7,
- 0x21c1, 0x23fa, 0x2655, 0x28d6,
- 0x2b7c, 0x2e4a, 0x3141, 0x3464,
- 0x37b4, 0x3b35, 0x3ee9, 0x42d3,
- 0x46f6, 0x4b53, 0x4ff0, 0x54ce,
- 0x59f2, 0x5f5f, 0x6519, 0x6b24,
- 0x7183, 0x783c, 0x7f53, 0x86cc,
- 0x8ead, 0x96fa, 0x9fba, 0xa8f2,
- 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa,
- 0xdee8, 0xeb75, 0xf8aa, 0x1068e,
- 0x1152a, 0x12487, 0x134ad, 0x145a5,
- 0x1577b, 0x16a37, 0x17df5, 0x192bd,
- 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1,
- 0x20b55, 0x22727, 0x24456, 0x262f2,
- 0x2830b
-};
-
-static uint tas3004_mixer_tab[]={
- 0x0, 0x748, 0x9be, 0xbaf,
- 0xda4, 0xfb1, 0x11de, 0x1431,
- 0x16ad, 0x1959, 0x1c37, 0x1f4b,
- 0x2298, 0x2628, 0x29fb, 0x2e12,
- 0x327d, 0x3734, 0x3c47, 0x41b4,
- 0x4787, 0x4dbe, 0x546d, 0x5b86,
- 0x632e, 0x6b52, 0x7400, 0x7d54,
- 0x873b, 0x91c6, 0x9d1a, 0xa920,
- 0xb5e5, 0xc38c, 0xd21b, 0xe18f,
- 0xf1f5, 0x1036a, 0x1160f, 0x129d6,
- 0x13ed0, 0x1550c, 0x16ca0, 0x185c9,
- 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75,
- 0x21c0f, 0x23fa3, 0x26552, 0x28d64,
- 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b,
- 0x37b44, 0x3b353, 0x3ee94, 0x42d30,
- 0x46f55, 0x4b533, 0x4fefc, 0x54ce5,
- 0x59f25, 0x5f5f6, 0x65193, 0x6b23c,
- 0x71835, 0x783c3, 0x7f52c, 0x86cc0,
- 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a,
- 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0,
- 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4,
- 0x1152a3, 0x12486a, 0x134ac8, 0x145a55,
- 0x1577ac, 0x16a370, 0x17df51, 0x192bc2,
- 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04,
- 0x20b542, 0x227268, 0x244564, 0x262f26,
- 0x2830af
-};
-
-static uint tas3004_treble_tab[]={
- 0x96, 0x95, 0x95, 0x94,
- 0x93, 0x92, 0x92, 0x91,
- 0x90, 0x90, 0x8f, 0x8e,
- 0x8d, 0x8d, 0x8c, 0x8b,
- 0x8a, 0x8a, 0x89, 0x88,
- 0x88, 0x87, 0x86, 0x85,
- 0x85, 0x84, 0x83, 0x83,
- 0x82, 0x81, 0x80, 0x80,
- 0x7f, 0x7e, 0x7e, 0x7d,
- 0x7c, 0x7b, 0x7b, 0x7a,
- 0x79, 0x78, 0x78, 0x77,
- 0x76, 0x76, 0x75, 0x74,
- 0x73, 0x73, 0x72, 0x71,
- 0x71, 0x68, 0x45, 0x5b,
- 0x6d, 0x6c, 0x6b, 0x6a,
- 0x69, 0x68, 0x67, 0x66,
- 0x65, 0x63, 0x62, 0x62,
- 0x60, 0x5e, 0x5c, 0x5b,
- 0x59, 0x57, 0x55, 0x53,
- 0x52, 0x4f, 0x4d, 0x4a,
- 0x48, 0x46, 0x43, 0x40,
- 0x3d, 0x3a, 0x36, 0x33,
- 0x2f, 0x2c, 0x27, 0x23,
- 0x1f, 0x1a, 0x15, 0xf,
- 0x8, 0x5, 0x2, 0x1,
- 0x1
-};
-
-static uint tas3004_bass_tab[]={
- 0x96, 0x95, 0x95, 0x94,
- 0x93, 0x92, 0x92, 0x91,
- 0x90, 0x90, 0x8f, 0x8e,
- 0x8d, 0x8d, 0x8c, 0x8b,
- 0x8a, 0x8a, 0x89, 0x88,
- 0x88, 0x87, 0x86, 0x85,
- 0x85, 0x84, 0x83, 0x83,
- 0x82, 0x81, 0x80, 0x80,
- 0x7f, 0x7e, 0x7e, 0x7d,
- 0x7c, 0x7b, 0x7b, 0x7a,
- 0x79, 0x78, 0x78, 0x77,
- 0x76, 0x76, 0x75, 0x74,
- 0x73, 0x73, 0x72, 0x71,
- 0x70, 0x6f, 0x6e, 0x6d,
- 0x6c, 0x6b, 0x6a, 0x6a,
- 0x69, 0x67, 0x66, 0x66,
- 0x65, 0x63, 0x62, 0x62,
- 0x61, 0x60, 0x5e, 0x5d,
- 0x5b, 0x59, 0x57, 0x55,
- 0x53, 0x51, 0x4f, 0x4c,
- 0x4a, 0x48, 0x46, 0x44,
- 0x41, 0x3e, 0x3b, 0x38,
- 0x36, 0x33, 0x2f, 0x2b,
- 0x28, 0x24, 0x20, 0x1c,
- 0x17, 0x12, 0xd, 0x7,
- 0x1
-};
-
-struct tas_gain_t tas3004_gain={
- .master = tas3004_master_tab,
- .treble = tas3004_treble_tab,
- .bass = tas3004_bass_tab,
- .mixer = tas3004_mixer_tab
-};
-
-struct tas_eq_pref_t *tas3004_eq_prefs[]={
- &eqp_17_1_0,
- &eqp_18_1_0,
- &eqp_1a_1_0,
- &eqp_1c_1_0,
- NULL
-};
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
deleted file mode 100644
index b295ef68219..00000000000
--- a/sound/oss/dmasound/tas_common.c
+++ /dev/null
@@ -1,214 +0,0 @@
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-
-#include "tas_common.h"
-
-#define CALL0(proc) \
- do { \
- struct tas_data_t *self; \
- if (!tas_client || driver_hooks == NULL) \
- return -1; \
- self = dev_get_drvdata(&tas_client->dev); \
- if (driver_hooks->proc) \
- return driver_hooks->proc(self); \
- else \
- return -EINVAL; \
- } while (0)
-
-#define CALL(proc,arg...) \
- do { \
- struct tas_data_t *self; \
- if (!tas_client || driver_hooks == NULL) \
- return -1; \
- self = dev_get_drvdata(&tas_client->dev); \
- if (driver_hooks->proc) \
- return driver_hooks->proc(self, ## arg); \
- else \
- return -EINVAL; \
- } while (0)
-
-
-static u8 tas_i2c_address = 0x34;
-static struct i2c_client *tas_client;
-
-static int tas_attach_adapter(struct i2c_adapter *);
-static int tas_detach_client(struct i2c_client *);
-
-struct i2c_driver tas_driver = {
- .driver = {
- .name = "tas",
- },
- .attach_adapter = tas_attach_adapter,
- .detach_client = tas_detach_client,
-};
-
-struct tas_driver_hooks_t *driver_hooks;
-
-int
-tas_register_driver(struct tas_driver_hooks_t *hooks)
-{
- driver_hooks = hooks;
- return 0;
-}
-
-int
-tas_get_mixer_level(int mixer, uint *level)
-{
- CALL(get_mixer_level,mixer,level);
-}
-
-int
-tas_set_mixer_level(int mixer,uint level)
-{
- CALL(set_mixer_level,mixer,level);
-}
-
-int
-tas_enter_sleep(void)
-{
- CALL0(enter_sleep);
-}
-
-int
-tas_leave_sleep(void)
-{
- CALL0(leave_sleep);
-}
-
-int
-tas_supported_mixers(void)
-{
- CALL0(supported_mixers);
-}
-
-int
-tas_mixer_is_stereo(int mixer)
-{
- CALL(mixer_is_stereo,mixer);
-}
-
-int
-tas_stereo_mixers(void)
-{
- CALL0(stereo_mixers);
-}
-
-int
-tas_output_device_change(int device_id,int layout_id,int speaker_id)
-{
- CALL(output_device_change,device_id,layout_id,speaker_id);
-}
-
-int
-tas_device_ioctl(u_int cmd, u_long arg)
-{
- CALL(device_ioctl,cmd,arg);
-}
-
-int
-tas_post_init(void)
-{
- CALL0(post_init);
-}
-
-static int
-tas_detect_client(struct i2c_adapter *adapter, int address)
-{
- static const char *client_name = "tas Digital Equalizer";
- struct i2c_client *new_client;
- int rc = -ENODEV;
-
- if (!driver_hooks) {
- printk(KERN_ERR "tas_detect_client called with no hooks !\n");
- return -ENODEV;
- }
-
- new_client = kzalloc(sizeof(*new_client), GFP_KERNEL);
- if (!new_client)
- return -ENOMEM;
-
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &tas_driver;
- strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
-
- if (driver_hooks->init(new_client))
- goto bail;
-
- /* Tell the i2c layer a new client has arrived */
- if (i2c_attach_client(new_client)) {
- driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
- goto bail;
- }
-
- tas_client = new_client;
- return 0;
- bail:
- tas_client = NULL;
- kfree(new_client);
- return rc;
-}
-
-static int
-tas_attach_adapter(struct i2c_adapter *adapter)
-{
- if (!strncmp(adapter->name, "mac-io", 6))
- return tas_detect_client(adapter, tas_i2c_address);
- return 0;
-}
-
-static int
-tas_detach_client(struct i2c_client *client)
-{
- if (client == tas_client) {
- driver_hooks->uninit(dev_get_drvdata(&client->dev));
-
- i2c_detach_client(client);
- kfree(client);
- }
- return 0;
-}
-
-void
-tas_cleanup(void)
-{
- i2c_del_driver(&tas_driver);
-}
-
-int __init
-tas_init(int driver_id, const char *driver_name)
-{
- const u32* paddr;
- struct device_node *tas_node;
-
- printk(KERN_INFO "tas driver [%s])\n", driver_name);
-
-#ifndef CONFIG_I2C_POWERMAC
- request_module("i2c-powermac");
-#endif
- tas_node = of_find_node_by_name("deq");
- if (tas_node == NULL)
- return -ENODEV;
- paddr = of_get_property(tas_node, "i2c-address", NULL);
- if (paddr) {
- tas_i2c_address = (*paddr) >> 1;
- printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
- tas_i2c_address);
- } else
- printk(KERN_INFO "using i2c address: 0x%x (default)\n",
- tas_i2c_address);
- of_node_put(tas_node);
-
- return i2c_add_driver(&tas_driver);
-}
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h
deleted file mode 100644
index 0741c28e56c..00000000000
--- a/sound/oss/dmasound/tas_common.h
+++ /dev/null
@@ -1,284 +0,0 @@
-#ifndef _TAS_COMMON_H_
-#define _TAS_COMMON_H_
-
-#include <linux/i2c.h>
-#include <linux/soundcard.h>
-#include <asm/string.h>
-
-#define I2C_DRIVERID_TAS_BASE (0xFEBA)
-
-#define SET_4_20(shadow, offset, val) \
- do { \
- (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
- (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \
- (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \
- } while (0)
-
-#define GET_4_20(shadow, offset) \
- (((u_int)((shadow)[(offset)+0]) << 16) | \
- ((u_int)((shadow)[(offset)+1]) << 8) | \
- ((u_int)((shadow)[(offset)+2]) << 0))
-
-
-#define TAS_BIQUAD_FAST_LOAD 0x01
-
-#define TAS_DRCE_ENABLE 0x01
-#define TAS_DRCE_ABOVE_RATIO 0x02
-#define TAS_DRCE_BELOW_RATIO 0x04
-#define TAS_DRCE_THRESHOLD 0x08
-#define TAS_DRCE_ENERGY 0x10
-#define TAS_DRCE_ATTACK 0x20
-#define TAS_DRCE_DECAY 0x40
-
-#define TAS_DRCE_ALL 0x7f
-
-
-#define TAS_OUTPUT_HEADPHONES 0x00
-#define TAS_OUTPUT_INTERNAL_SPKR 0x01
-#define TAS_OUTPUT_EXTERNAL_SPKR 0x02
-
-
-union tas_biquad_t {
- struct {
- int b0,b1,b2,a1,a2;
- } coeff;
- int buf[5];
-};
-
-struct tas_biquad_ctrl_t {
- u_int channel:4;
- u_int filter:4;
-
- union tas_biquad_t data;
-};
-
-struct tas_biquad_ctrl_list_t {
- int flags;
- int filter_count;
- struct tas_biquad_ctrl_t biquads[0];
-};
-
-struct tas_ratio_t {
- unsigned short val; /* 8.8 */
- unsigned short expand; /* 0 = compress, !0 = expand. */
-};
-
-struct tas_drce_t {
- unsigned short enable;
- struct tas_ratio_t above;
- struct tas_ratio_t below;
- short threshold; /* dB, 8.8 signed */
- unsigned short energy; /* seconds, 4.12 unsigned */
- unsigned short attack; /* seconds, 4.12 unsigned */
- unsigned short decay; /* seconds, 4.12 unsigned */
-};
-
-struct tas_drce_ctrl_t {
- uint flags;
-
- struct tas_drce_t data;
-};
-
-struct tas_gain_t
-{
- unsigned int *master;
- unsigned int *treble;
- unsigned int *bass;
- unsigned int *mixer;
-};
-
-typedef char tas_shadow_t[0x45];
-
-struct tas_data_t
-{
- struct i2c_client *client;
- tas_shadow_t *shadow;
- uint mixer[SOUND_MIXER_NRDEVICES];
-};
-
-typedef int (*tas_hook_init_t)(struct i2c_client *);
-typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
-typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
-typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
-
-typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
-typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
-typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
-typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
-
-typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
-typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
-
-struct tas_driver_hooks_t {
- /*
- * All hardware initialisation must be performed in
- * post_init(), as tas_dmasound_init() does a hardware reset.
- *
- * init() is called before tas_dmasound_init() so that
- * ouput_device_change() is always called after i2c driver
- * initialisation. The implication is that
- * output_device_change() must cope with the fact that it
- * may be called before post_init().
- */
-
- tas_hook_init_t init;
- tas_hook_post_init_t post_init;
- tas_hook_uninit_t uninit;
-
- tas_hook_get_mixer_level_t get_mixer_level;
- tas_hook_set_mixer_level_t set_mixer_level;
-
- tas_hook_enter_sleep_t enter_sleep;
- tas_hook_leave_sleep_t leave_sleep;
-
- tas_hook_supported_mixers_t supported_mixers;
- tas_hook_mixer_is_stereo_t mixer_is_stereo;
- tas_hook_stereo_mixers_t stereo_mixers;
-
- tas_hook_output_device_change_t output_device_change;
- tas_hook_device_ioctl_t device_ioctl;
-};
-
-enum tas_write_mode_t {
- WRITE_HW = 0x01,
- WRITE_SHADOW = 0x02,
- WRITE_NORMAL = 0x03,
- FORCE_WRITE = 0x04
-};
-
-static inline uint
-tas_mono_to_stereo(uint mono)
-{
- mono &=0xff;
- return mono | (mono<<8);
-}
-
-/*
- * Todo: make these functions a bit more efficient !
- */
-static inline int
-tas_write_register( struct tas_data_t *self,
- uint reg_num,
- uint reg_width,
- char *data,
- uint write_mode)
-{
- int rc;
-
- if (reg_width==0 || data==NULL || self==NULL)
- return -EINVAL;
- if (!(write_mode & FORCE_WRITE) &&
- !memcmp(data,self->shadow[reg_num],reg_width))
- return 0;
-
- if (write_mode & WRITE_SHADOW)
- memcpy(self->shadow[reg_num],data,reg_width);
- if (write_mode & WRITE_HW) {
- rc=i2c_smbus_write_i2c_block_data(self->client,
- reg_num,
- reg_width,
- data);
- if (rc < 0) {
- printk("tas: I2C block write failed \n");
- return rc;
- }
- }
- return 0;
-}
-
-static inline int
-tas_sync_register( struct tas_data_t *self,
- uint reg_num,
- uint reg_width)
-{
- int rc;
-
- if (reg_width==0 || self==NULL)
- return -EINVAL;
- rc=i2c_smbus_write_i2c_block_data(self->client,
- reg_num,
- reg_width,
- self->shadow[reg_num]);
- if (rc < 0) {
- printk("tas: I2C block write failed \n");
- return rc;
- }
- return 0;
-}
-
-static inline int
-tas_write_byte_register( struct tas_data_t *self,
- uint reg_num,
- char data,
- uint write_mode)
-{
- if (self==NULL)
- return -1;
- if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
- return 0;
- if (write_mode & WRITE_SHADOW)
- self->shadow[reg_num][0]=data;
- if (write_mode & WRITE_HW) {
- if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
- printk("tas: I2C byte write failed \n");
- return -1;
- }
- }
- return 0;
-}
-
-static inline int
-tas_sync_byte_register( struct tas_data_t *self,
- uint reg_num,
- uint reg_width)
-{
- if (reg_width==0 || self==NULL)
- return -1;
- if (i2c_smbus_write_byte_data(
- self->client, reg_num, self->shadow[reg_num][0]) < 0) {
- printk("tas: I2C byte write failed \n");
- return -1;
- }
- return 0;
-}
-
-static inline int
-tas_read_register( struct tas_data_t *self,
- uint reg_num,
- uint reg_width,
- char *data)
-{
- if (reg_width==0 || data==NULL || self==NULL)
- return -1;
- memcpy(data,self->shadow[reg_num],reg_width);
- return 0;
-}
-
-extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
-
-extern int tas_get_mixer_level(int mixer,uint *level);
-extern int tas_set_mixer_level(int mixer,uint level);
-extern int tas_enter_sleep(void);
-extern int tas_leave_sleep(void);
-extern int tas_supported_mixers(void);
-extern int tas_mixer_is_stereo(int mixer);
-extern int tas_stereo_mixers(void);
-extern int tas_output_device_change(int,int,int);
-extern int tas_device_ioctl(u_int, u_long);
-
-extern void tas_cleanup(void);
-extern int tas_init(int driver_id,const char *driver_name);
-extern int tas_post_init(void);
-
-#endif /* _TAS_COMMON_H_ */
-/*
- * Local Variables:
- * tab-width: 8
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
diff --git a/sound/oss/dmasound/tas_eq_prefs.h b/sound/oss/dmasound/tas_eq_prefs.h
deleted file mode 100644
index 3a994eda6ab..00000000000
--- a/sound/oss/dmasound/tas_eq_prefs.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _TAS_EQ_PREFS_H_
-#define _TAS_EQ_PREFS_H_
-
-struct tas_eq_pref_t {
- u_int sample_rate;
- u_int device_id;
- u_int output_id;
- u_int speaker_id;
-
- struct tas_drce_t *drce;
-
- u_int filter_count;
- struct tas_biquad_ctrl_t *biquads;
-};
-
-#endif /* _TAS_EQ_PREFS_H_ */
-
-/*
- * Local Variables:
- * tab-width: 8
- * indent-tabs-mode: t
- * c-basic-offset: 8
- * End:
- */
diff --git a/sound/oss/dmasound/tas_ioctl.h b/sound/oss/dmasound/tas_ioctl.h
deleted file mode 100644
index 9d12b373b4a..00000000000
--- a/sound/oss/dmasound/tas_ioctl.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _TAS_IOCTL_H_
-#define _TAS_IOCTL_H_
-
-#include <linux/soundcard.h>
-
-
-#define TAS_READ_EQ _SIOR('t',0,struct tas_biquad_ctrl_t)
-#define TAS_WRITE_EQ _SIOW('t',0,struct tas_biquad_ctrl_t)
-
-#define TAS_READ_EQ_LIST _SIOR('t',1,struct tas_biquad_ctrl_t)
-#define TAS_WRITE_EQ_LIST _SIOW('t',1,struct tas_biquad_ctrl_t)
-
-#define TAS_READ_EQ_FILTER_COUNT _SIOR('t',2,int)
-#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int)
-
-#define TAS_READ_DRCE _SIOR('t',4,struct tas_drce_ctrl_t)
-#define TAS_WRITE_DRCE _SIOW('t',4,struct tas_drce_ctrl_t)
-
-#define TAS_READ_DRCE_CAPS _SIOR('t',5,int)
-#define TAS_READ_DRCE_MIN _SIOR('t',6,int)
-#define TAS_READ_DRCE_MAX _SIOR('t',7,int)
-
-#endif
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c
deleted file mode 100644
index ca973ac2a30..00000000000
--- a/sound/oss/dmasound/trans_16.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- * linux/sound/oss/dmasound/trans_16.c
- *
- * 16 bit translation routines. Only used by Power mac at present.
- *
- * See linux/sound/oss/dmasound/dmasound_core.c for copyright and
- * history prior to 08/02/2001.
- *
- * 08/02/2001 Iain Sandoe
- * split from dmasound_awacs.c
- * 11/29/2003 Renzo Davoli (King Enzo)
- * - input resampling (for soft rate < hard rate)
- * - software line in gain control
- */
-
-#include <linux/soundcard.h>
-#include <asm/uaccess.h>
-#include "dmasound.h"
-
-extern int expand_bal; /* Balance factor for expanding (not volume!) */
-static short dmasound_alaw2dma16[] ;
-static short dmasound_ulaw2dma16[] ;
-
-static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-
-static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-
-static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
-
-/*** Translations ************************************************************/
-
-static int expand_data; /* Data for expanding */
-
-static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- short *table = dmasound.soft.format == AFMT_MU_LAW
- ? dmasound_ulaw2dma16 : dmasound_alaw2dma16;
- ssize_t count, used;
- short *p = (short *) &frame[*frameUsed];
- int val, stereo = dmasound.soft.stereo;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = table[data];
- *p++ = val;
- if (stereo) {
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = table[data];
- }
- *p++ = val;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- short *p = (short *) &frame[*frameUsed];
- int val, stereo = dmasound.soft.stereo;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = data << 8;
- *p++ = val;
- if (stereo) {
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = data << 8;
- }
- *p++ = val;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- short *p = (short *) &frame[*frameUsed];
- int val, stereo = dmasound.soft.stereo;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- u_char data;
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = (data ^ 0x80) << 8;
- *p++ = val;
- if (stereo) {
- if (get_user(data, userPtr++))
- return -EFAULT;
- val = (data ^ 0x80) << 8;
- }
- *p++ = val;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- int stereo = dmasound.soft.stereo;
- short *fp = (short *) &frame[*frameUsed];
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- used = count = min_t(unsigned long, userCount, frameLeft);
- if (!stereo) {
- short __user *up = (short __user *) userPtr;
- while (count > 0) {
- short data;
- if (get_user(data, up++))
- return -EFAULT;
- *fp++ = data;
- *fp++ = data;
- count--;
- }
- } else {
- if (copy_from_user(fp, userPtr, count * 4))
- return -EFAULT;
- }
- *frameUsed += used * 4;
- return stereo? used * 4: used * 2;
-}
-
-static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
- int stereo = dmasound.soft.stereo;
- short *fp = (short *) &frame[*frameUsed];
- short __user *up = (short __user *) userPtr;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- short data;
- if (get_user(data, up++))
- return -EFAULT;
- data ^= mask;
- *fp++ = data;
- if (stereo) {
- if (get_user(data, up++))
- return -EFAULT;
- data ^= mask;
- }
- *fp++ = data;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 4: used * 2;
-}
-
-
-static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- unsigned short *table = (unsigned short *)
- (dmasound.soft.format == AFMT_MU_LAW
- ? dmasound_ulaw2dma16 : dmasound_alaw2dma16);
- unsigned int data = expand_data;
- unsigned int *p = (unsigned int *) &frame[*frameUsed];
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
- int stereo = dmasound.soft.stereo;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = table[c];
- if (stereo) {
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = (data << 16) + table[c];
- } else
- data = (data << 16) + data;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 2: utotal;
-}
-
-static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- unsigned int *p = (unsigned int *) &frame[*frameUsed];
- unsigned int data = expand_data;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int stereo = dmasound.soft.stereo;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = c << 8;
- if (stereo) {
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = (data << 16) + (c << 8);
- } else
- data = (data << 16) + data;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- unsigned int *p = (unsigned int *) &frame[*frameUsed];
- unsigned int data = expand_data;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int stereo = dmasound.soft.stereo;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = (c ^ 0x80) << 8;
- if (stereo) {
- if (get_user(c, userPtr++))
- return -EFAULT;
- data = (data << 16) + ((c ^ 0x80) << 8);
- } else
- data = (data << 16) + data;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- unsigned int *p = (unsigned int *) &frame[*frameUsed];
- unsigned int data = expand_data;
- unsigned short __user *up = (unsigned short __user *) userPtr;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int stereo = dmasound.soft.stereo;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- unsigned short c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(data, up++))
- return -EFAULT;
- if (stereo) {
- if (get_user(c, up++))
- return -EFAULT;
- data = (data << 16) + c;
- } else
- data = (data << 16) + data;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 4: utotal * 2;
-}
-
-
-static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
- unsigned int *p = (unsigned int *) &frame[*frameUsed];
- unsigned int data = expand_data;
- unsigned short __user *up = (unsigned short __user *) userPtr;
- int bal = expand_bal;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int stereo = dmasound.soft.stereo;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- unsigned short c;
- if (bal < 0) {
- if (userCount == 0)
- break;
- if (get_user(data, up++))
- return -EFAULT;
- data ^= mask;
- if (stereo) {
- if (get_user(c, up++))
- return -EFAULT;
- data = (data << 16) + (c ^ mask);
- } else
- data = (data << 16) + data;
- userCount--;
- bal += hSpeed;
- }
- *p++ = data;
- frameLeft--;
- bal -= sSpeed;
- }
- expand_bal = bal;
- expand_data = data;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 4: utotal * 2;
-}
-
-/* data in routines... */
-
-static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- short *p = (short *) &frame[*frameUsed];
- int val, stereo = dmasound.soft.stereo;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- u_char data;
-
- val = *p++;
- val = (val * software_input_volume) >> 7;
- data = val >> 8;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- if (stereo) {
- val = *p;
- val = (val * software_input_volume) >> 7;
- data = val >> 8;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- }
- p++;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 2: used;
-}
-
-
-static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- short *p = (short *) &frame[*frameUsed];
- int val, stereo = dmasound.soft.stereo;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- u_char data;
-
- val = *p++;
- val = (val * software_input_volume) >> 7;
- data = (val >> 8) ^ 0x80;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- if (stereo) {
- val = *p;
- val = (val * software_input_volume) >> 7;
- data = (val >> 8) ^ 0x80;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- }
- p++;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 2: used;
-}
-
-static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- int stereo = dmasound.soft.stereo;
- short *fp = (short *) &frame[*frameUsed];
- short __user *up = (short __user *) userPtr;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- short data;
-
- data = *fp++;
- data = (data * software_input_volume) >> 7;
- if (put_user(data, up++))
- return -EFAULT;
- if (stereo) {
- data = *fp;
- data = (data * software_input_volume) >> 7;
- if (put_user(data, up++))
- return -EFAULT;
- }
- fp++;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 4: used * 2;
-}
-
-static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- ssize_t count, used;
- int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
- int stereo = dmasound.soft.stereo;
- short *fp = (short *) &frame[*frameUsed];
- short __user *up = (short __user *) userPtr;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- used = count = min_t(unsigned long, userCount, frameLeft);
- while (count > 0) {
- int data;
-
- data = *fp++;
- data = (data * software_input_volume) >> 7;
- data ^= mask;
- if (put_user(data, up++))
- return -EFAULT;
- if (stereo) {
- data = *fp;
- data = (data * software_input_volume) >> 7;
- data ^= mask;
- if (put_user(data, up++))
- return -EFAULT;
- }
- fp++;
- count--;
- }
- *frameUsed += used * 4;
- return stereo? used * 4: used * 2;
-}
-
-/* data in routines (reducing speed)... */
-
-static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- short *p = (short *) &frame[*frameUsed];
- int bal = expand_read_bal;
- int vall,valr, stereo = dmasound.soft.stereo;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char data;
-
- if (bal<0 && userCount == 0)
- break;
- vall = *p++;
- vall = (vall * software_input_volume) >> 7;
- if (stereo) {
- valr = *p;
- valr = (valr * software_input_volume) >> 7;
- }
- p++;
- if (bal < 0) {
- data = vall >> 8;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- if (stereo) {
- data = valr >> 8;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- }
- userCount--;
- bal += hSpeed;
- }
- frameLeft--;
- bal -= sSpeed;
- }
- expand_read_bal=bal;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- short *p = (short *) &frame[*frameUsed];
- int bal = expand_read_bal;
- int vall,valr, stereo = dmasound.soft.stereo;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- if (stereo)
- userCount >>= 1;
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- u_char data;
-
- if (bal<0 && userCount == 0)
- break;
-
- vall = *p++;
- vall = (vall * software_input_volume) >> 7;
- if (stereo) {
- valr = *p;
- valr = (valr * software_input_volume) >> 7;
- }
- p++;
- if (bal < 0) {
- data = (vall >> 8) ^ 0x80;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- if (stereo) {
- data = (valr >> 8) ^ 0x80;
- if (put_user(data, (u_char __user *)userPtr++))
- return -EFAULT;
- }
- userCount--;
- bal += hSpeed;
- }
- frameLeft--;
- bal -= sSpeed;
- }
- expand_read_bal=bal;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 2: utotal;
-}
-
-static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- int bal = expand_read_bal;
- short *fp = (short *) &frame[*frameUsed];
- short __user *up = (short __user *) userPtr;
- int stereo = dmasound.soft.stereo;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- int datal,datar;
-
- if (bal<0 && userCount == 0)
- break;
-
- datal = *fp++;
- datal = (datal * software_input_volume) >> 7;
- if (stereo) {
- datar = *fp;
- datar = (datar * software_input_volume) >> 7;
- }
- fp++;
- if (bal < 0) {
- if (put_user(datal, up++))
- return -EFAULT;
- if (stereo) {
- if (put_user(datar, up++))
- return -EFAULT;
- }
- userCount--;
- bal += hSpeed;
- }
- frameLeft--;
- bal -= sSpeed;
- }
- expand_read_bal=bal;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 4: utotal * 2;
-}
-
-static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
-{
- int bal = expand_read_bal;
- int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
- short *fp = (short *) &frame[*frameUsed];
- short __user *up = (short __user *) userPtr;
- int stereo = dmasound.soft.stereo;
- int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
- int utotal, ftotal;
-
- frameLeft >>= 2;
- userCount >>= (stereo? 2: 1);
- ftotal = frameLeft;
- utotal = userCount;
- while (frameLeft) {
- int datal,datar;
-
- if (bal<0 && userCount == 0)
- break;
-
- datal = *fp++;
- datal = (datal * software_input_volume) >> 7;
- datal ^= mask;
- if (stereo) {
- datar = *fp;
- datar = (datar * software_input_volume) >> 7;
- datar ^= mask;
- }
- fp++;
- if (bal < 0) {
- if (put_user(datal, up++))
- return -EFAULT;
- if (stereo) {
- if (put_user(datar, up++))
- return -EFAULT;
- }
- userCount--;
- bal += hSpeed;
- }
- frameLeft--;
- bal -= sSpeed;
- }
- expand_read_bal=bal;
- *frameUsed += (ftotal - frameLeft) * 4;
- utotal -= userCount;
- return stereo? utotal * 4: utotal * 2;
-}
-
-
-TRANS transAwacsNormal = {
- .ct_ulaw= pmac_ct_law,
- .ct_alaw= pmac_ct_law,
- .ct_s8= pmac_ct_s8,
- .ct_u8= pmac_ct_u8,
- .ct_s16be= pmac_ct_s16,
- .ct_u16be= pmac_ct_u16,
- .ct_s16le= pmac_ct_s16,
- .ct_u16le= pmac_ct_u16,
-};
-
-TRANS transAwacsExpand = {
- .ct_ulaw= pmac_ctx_law,
- .ct_alaw= pmac_ctx_law,
- .ct_s8= pmac_ctx_s8,
- .ct_u8= pmac_ctx_u8,
- .ct_s16be= pmac_ctx_s16,
- .ct_u16be= pmac_ctx_u16,
- .ct_s16le= pmac_ctx_s16,
- .ct_u16le= pmac_ctx_u16,
-};
-
-TRANS transAwacsNormalRead = {
- .ct_s8= pmac_ct_s8_read,
- .ct_u8= pmac_ct_u8_read,
- .ct_s16be= pmac_ct_s16_read,
- .ct_u16be= pmac_ct_u16_read,
- .ct_s16le= pmac_ct_s16_read,
- .ct_u16le= pmac_ct_u16_read,
-};
-
-TRANS transAwacsExpandRead = {
- .ct_s8= pmac_ctx_s8_read,
- .ct_u8= pmac_ctx_u8_read,
- .ct_s16be= pmac_ctx_s16_read,
- .ct_u16be= pmac_ctx_u16_read,
- .ct_s16le= pmac_ctx_s16_read,
- .ct_u16le= pmac_ctx_u16_read,
-};
-
-/* translation tables */
-/* 16 bit mu-law */
-
-static short dmasound_ulaw2dma16[] = {
- -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
- -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
- -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
- -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
- -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
- -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
- -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
- -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
- -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
- -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
- -876, -844, -812, -780, -748, -716, -684, -652,
- -620, -588, -556, -524, -492, -460, -428, -396,
- -372, -356, -340, -324, -308, -292, -276, -260,
- -244, -228, -212, -196, -180, -164, -148, -132,
- -120, -112, -104, -96, -88, -80, -72, -64,
- -56, -48, -40, -32, -24, -16, -8, 0,
- 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
- 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
- 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
- 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
- 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
- 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
- 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
- 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
- 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
- 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
- 876, 844, 812, 780, 748, 716, 684, 652,
- 620, 588, 556, 524, 492, 460, 428, 396,
- 372, 356, 340, 324, 308, 292, 276, 260,
- 244, 228, 212, 196, 180, 164, 148, 132,
- 120, 112, 104, 96, 88, 80, 72, 64,
- 56, 48, 40, 32, 24, 16, 8, 0,
-};
-
-/* 16 bit A-law */
-
-static short dmasound_alaw2dma16[] = {
- -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
- -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
- -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
- -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
- -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
- -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
- -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
- -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
- -344, -328, -376, -360, -280, -264, -312, -296,
- -472, -456, -504, -488, -408, -392, -440, -424,
- -88, -72, -120, -104, -24, -8, -56, -40,
- -216, -200, -248, -232, -152, -136, -184, -168,
- -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
- -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
- -688, -656, -752, -720, -560, -528, -624, -592,
- -944, -912, -1008, -976, -816, -784, -880, -848,
- 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
- 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
- 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
- 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
- 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
- 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
- 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
- 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
- 344, 328, 376, 360, 280, 264, 312, 296,
- 472, 456, 504, 488, 408, 392, 440, 424,
- 88, 72, 120, 104, 24, 8, 56, 40,
- 216, 200, 248, 232, 152, 136, 184, 168,
- 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
- 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
- 688, 656, 752, 720, 560, 528, 624, 592,
- 944, 912, 1008, 976, 816, 784, 880, 848,
-};
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
deleted file mode 100644
index 52648573f60..00000000000
--- a/sound/oss/es1371.c
+++ /dev/null
@@ -1,3131 +0,0 @@
-/*****************************************************************************/
-
-/*
- * es1371.c -- Creative Ensoniq ES1371.
- *
- * Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to Ensoniq
- *
- * Supported devices:
- * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible
- * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
- * /dev/dsp1 additional DAC, like /dev/dsp, but outputs to mixer "SYNTH" setting
- * /dev/midi simple MIDI UART interface, no ioctl
- *
- * NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed
- * to be done in software. That is what /dev/dac is for. By now (Q2 1998)
- * there are several MIDI to PCM (WAV) packages, one of them is timidity.
- *
- * Revision history
- * 04.06.1998 0.1 Initial release
- * Mixer stuff should be overhauled; especially optional AC97 mixer bits
- * should be detected. This results in strange behaviour of some mixer
- * settings, like master volume and mic.
- * 08.06.1998 0.2 First release using Alan Cox' soundcore instead of miscdevice
- * 03.08.1998 0.3 Do not include modversions.h
- * Now mixer behaviour can basically be selected between
- * "OSS documented" and "OSS actual" behaviour
- * 31.08.1998 0.4 Fix realplayer problems - dac.count issues
- * 27.10.1998 0.5 Fix joystick support
- * -- Oliver Neukum (c188@org.chemie.uni-muenchen.de)
- * 10.12.1998 0.6 Fix drain_dac trying to wait on not yet initialized DMA
- * 23.12.1998 0.7 Fix a few f_file & FMODE_ bugs
- * Don't wake up app until there are fragsize bytes to read/write
- * 06.01.1999 0.8 remove the silly SA_INTERRUPT flag.
- * hopefully killed the egcs section type conflict
- * 12.03.1999 0.9 cinfo.blocks should be reset after GETxPTR ioctl.
- * reported by Johan Maes <joma@telindus.be>
- * 22.03.1999 0.10 return EAGAIN instead of EBUSY when O_NONBLOCK
- * read/write cannot be executed
- * 07.04.1999 0.11 implemented the following ioctl's: SOUND_PCM_READ_RATE,
- * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS;
- * Alpha fixes reported by Peter Jones <pjones@redhat.com>
- * Another Alpha fix (wait_src_ready in init routine)
- * reported by "Ivan N. Kokshaysky" <ink@jurassic.park.msu.ru>
- * Note: joystick address handling might still be wrong on archs
- * other than i386
- * 15.06.1999 0.12 Fix bad allocation bug.
- * Thanks to Deti Fliegl <fliegl@in.tum.de>
- * 28.06.1999 0.13 Add pci_set_master
- * 03.08.1999 0.14 adapt to Linus' new __setup/__initcall
- * added kernel command line option "es1371=joystickaddr"
- * removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge
- * 10.08.1999 0.15 (Re)added S/PDIF module option for cards revision >= 4.
- * Initial version by Dave Platt <dplatt@snulbug.mtview.ca.us>.
- * module_init/__setup fixes
- * 08.16.1999 0.16 Joe Cotellese <joec@ensoniq.com>
- * Added detection for ES1371 revision ID so that we can
- * detect the ES1373 and later parts.
- * added AC97 #defines for readability
- * added a /proc file system for dumping hardware state
- * updated SRC and CODEC w/r functions to accommodate bugs
- * in some versions of the ES137x chips.
- * 31.08.1999 0.17 add spin_lock_init
- * replaced current->state = x with set_current_state(x)
- * 03.09.1999 0.18 change read semantics for MIDI to match
- * OSS more closely; remove possible wakeup race
- * 21.10.1999 0.19 Round sampling rates, requested by
- * Kasamatsu Kenichi <t29w0267@ip.media.kyoto-u.ac.jp>
- * 27.10.1999 0.20 Added SigmaTel 3D enhancement string
- * Codec ID printing changes
- * 28.10.1999 0.21 More waitqueue races fixed
- * Joe Cotellese <joec@ensoniq.com>
- * Changed PCI detection routine so we can more easily
- * detect ES137x chip and derivatives.
- * 05.01.2000 0.22 Should now work with rev7 boards; patch by
- * Eric Lemar, elemar@cs.washington.edu
- * 08.01.2000 0.23 Prevent some ioctl's from returning bad count values on underrun/overrun;
- * Tim Janik's BSE (Bedevilled Sound Engine) found this
- * 07.02.2000 0.24 Use pci_alloc_consistent and pci_register_driver
- * 07.02.2000 0.25 Use ac97_codec
- * 01.03.2000 0.26 SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com>
- * Use pci_module_init
- * 21.11.2000 0.27 Initialize dma buffers in poll, otherwise poll may return a bogus mask
- * 12.12.2000 0.28 More dma buffer initializations, patch from
- * Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- * 05.01.2001 0.29 Hopefully updates will not be required anymore when Creative bumps
- * the CT5880 revision.
- * suggested by Stephan Müller <smueller@chronox.de>
- * 31.01.2001 0.30 Register/Unregister gameport
- * Fix SETTRIGGER non OSS API conformity
- * 14.07.2001 0.31 Add list of laptops needing amplifier control
- * 03.01.2003 0.32 open_mode fixes from Georg Acher <acher@in.tum.de>
- */
-
-/*****************************************************************************/
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define ES1371_DEBUG
-#define DBG(x) {}
-/*#define DBG(x) {x}*/
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ENSONIQ
-#define PCI_VENDOR_ID_ENSONIQ 0x1274
-#endif
-
-#ifndef PCI_VENDOR_ID_ECTIVA
-#define PCI_VENDOR_ID_ECTIVA 0x1102
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371
-#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
-#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
-#endif
-
-#ifndef PCI_DEVICE_ID_ECTIVA_EV1938
-#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
-#endif
-
-/* ES1371 chip ID */
-/* This is a little confusing because all ES1371 compatible chips have the
- same DEVICE_ID, the only thing differentiating them is the REV_ID field.
- This is only significant if you want to enable features on the later parts.
- Yes, I know it's stupid and why didn't we use the sub IDs?
-*/
-#define ES1371REV_ES1373_A 0x04
-#define ES1371REV_ES1373_B 0x06
-#define ES1371REV_CT5880_A 0x07
-#define CT5880REV_CT5880_C 0x02
-#define CT5880REV_CT5880_D 0x03
-#define ES1371REV_ES1371_B 0x09
-#define EV1938REV_EV1938_A 0x00
-#define ES1371REV_ES1373_8 0x08
-
-#define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371)
-
-#define ES1371_EXTENT 0x40
-#define JOY_EXTENT 8
-
-#define ES1371_REG_CONTROL 0x00
-#define ES1371_REG_STATUS 0x04 /* on the 5880 it is control/status */
-#define ES1371_REG_UART_DATA 0x08
-#define ES1371_REG_UART_STATUS 0x09
-#define ES1371_REG_UART_CONTROL 0x09
-#define ES1371_REG_UART_TEST 0x0a
-#define ES1371_REG_MEMPAGE 0x0c
-#define ES1371_REG_SRCONV 0x10
-#define ES1371_REG_CODEC 0x14
-#define ES1371_REG_LEGACY 0x18
-#define ES1371_REG_SERIAL_CONTROL 0x20
-#define ES1371_REG_DAC1_SCOUNT 0x24
-#define ES1371_REG_DAC2_SCOUNT 0x28
-#define ES1371_REG_ADC_SCOUNT 0x2c
-
-#define ES1371_REG_DAC1_FRAMEADR 0xc30
-#define ES1371_REG_DAC1_FRAMECNT 0xc34
-#define ES1371_REG_DAC2_FRAMEADR 0xc38
-#define ES1371_REG_DAC2_FRAMECNT 0xc3c
-#define ES1371_REG_ADC_FRAMEADR 0xd30
-#define ES1371_REG_ADC_FRAMECNT 0xd34
-
-#define ES1371_FMT_U8_MONO 0
-#define ES1371_FMT_U8_STEREO 1
-#define ES1371_FMT_S16_MONO 2
-#define ES1371_FMT_S16_STEREO 3
-#define ES1371_FMT_STEREO 1
-#define ES1371_FMT_S16 2
-#define ES1371_FMT_MASK 3
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-#define CTRL_RECEN_B 0x08000000 /* 1 = don't mix analog in to digital out */
-#define CTRL_SPDIFEN_B 0x04000000
-#define CTRL_JOY_SHIFT 24
-#define CTRL_JOY_MASK 3
-#define CTRL_JOY_200 0x00000000 /* joystick base address */
-#define CTRL_JOY_208 0x01000000
-#define CTRL_JOY_210 0x02000000
-#define CTRL_JOY_218 0x03000000
-#define CTRL_GPIO_IN0 0x00100000 /* general purpose inputs/outputs */
-#define CTRL_GPIO_IN1 0x00200000
-#define CTRL_GPIO_IN2 0x00400000
-#define CTRL_GPIO_IN3 0x00800000
-#define CTRL_GPIO_OUT0 0x00010000
-#define CTRL_GPIO_OUT1 0x00020000
-#define CTRL_GPIO_OUT2 0x00040000
-#define CTRL_GPIO_OUT3 0x00080000
-#define CTRL_MSFMTSEL 0x00008000 /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_SYNCRES 0x00004000 /* AC97 warm reset */
-#define CTRL_ADCSTOP 0x00002000 /* stop ADC transfers */
-#define CTRL_PWR_INTRM 0x00001000 /* 1 = power level ints enabled */
-#define CTRL_M_CB 0x00000800 /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_CCB_INTRM 0x00000400 /* 1 = CCB "voice" ints enabled */
-#define CTRL_PDLEV0 0x00000000 /* power down level */
-#define CTRL_PDLEV1 0x00000100
-#define CTRL_PDLEV2 0x00000200
-#define CTRL_PDLEV3 0x00000300
-#define CTRL_BREQ 0x00000080 /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN 0x00000040 /* enable DAC1 */
-#define CTRL_DAC2_EN 0x00000020 /* enable DAC2 */
-#define CTRL_ADC_EN 0x00000010 /* enable ADC */
-#define CTRL_UART_EN 0x00000008 /* enable MIDI uart */
-#define CTRL_JYSTK_EN 0x00000004 /* enable Joystick port */
-#define CTRL_XTALCLKDIS 0x00000002 /* 1 = disable crystal clock input */
-#define CTRL_PCICLKDIS 0x00000001 /* 1 = disable PCI clock distribution */
-
-
-#define STAT_INTR 0x80000000 /* wired or of all interrupt bits */
-#define CSTAT_5880_AC97_RST 0x20000000 /* CT5880 Reset bit */
-#define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */
-#define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */
-#define STAT_TESTMODE 0x00010000 /* test ASIC */
-#define STAT_SYNC_ERR 0x00000100 /* 1 = codec sync error */
-#define STAT_VC 0x000000c0 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC 6
-#define STAT_MPWR 0x00000020 /* power level interrupt */
-#define STAT_MCCB 0x00000010 /* CCB int pending */
-#define STAT_UART 0x00000008 /* UART int pending */
-#define STAT_DAC1 0x00000004 /* DAC1 int pending */
-#define STAT_DAC2 0x00000002 /* DAC2 int pending */
-#define STAT_ADC 0x00000001 /* ADC int pending */
-
-#define USTAT_RXINT 0x80 /* UART rx int pending */
-#define USTAT_TXINT 0x04 /* UART tx int pending */
-#define USTAT_TXRDY 0x02 /* UART tx ready */
-#define USTAT_RXRDY 0x01 /* UART rx ready */
-
-#define UCTRL_RXINTEN 0x80 /* 1 = enable RX ints */
-#define UCTRL_TXINTEN 0x60 /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20 /* enable TX int */
-#define UCTRL_CNTRL 0x03 /* control field */
-#define UCTRL_CNTRL_SWR 0x03 /* software reset command */
-
-/* sample rate converter */
-#define SRC_OKSTATE 1
-
-#define SRC_RAMADDR_MASK 0xfe000000
-#define SRC_RAMADDR_SHIFT 25
-#define SRC_DAC1FREEZE (1UL << 21)
-#define SRC_DAC2FREEZE (1UL << 20)
-#define SRC_ADCFREEZE (1UL << 19)
-
-
-#define SRC_WE 0x01000000 /* read/write control for SRC RAM */
-#define SRC_BUSY 0x00800000 /* SRC busy */
-#define SRC_DIS 0x00400000 /* 1 = disable SRC */
-#define SRC_DDAC1 0x00200000 /* 1 = disable accum update for DAC1 */
-#define SRC_DDAC2 0x00100000 /* 1 = disable accum update for DAC2 */
-#define SRC_DADC 0x00080000 /* 1 = disable accum update for ADC2 */
-#define SRC_CTLMASK 0x00780000
-#define SRC_RAMDATA_MASK 0x0000ffff
-#define SRC_RAMDATA_SHIFT 0
-
-#define SRCREG_ADC 0x78
-#define SRCREG_DAC1 0x70
-#define SRCREG_DAC2 0x74
-#define SRCREG_VOL_ADC 0x6c
-#define SRCREG_VOL_DAC1 0x7c
-#define SRCREG_VOL_DAC2 0x7e
-
-#define SRCREG_TRUNC_N 0x00
-#define SRCREG_INT_REGS 0x01
-#define SRCREG_ACCUM_FRAC 0x02
-#define SRCREG_VFREQ_FRAC 0x03
-
-#define CODEC_PIRD 0x00800000 /* 0 = write AC97 register */
-#define CODEC_PIADD_MASK 0x007f0000
-#define CODEC_PIADD_SHIFT 16
-#define CODEC_PIDAT_MASK 0x0000ffff
-#define CODEC_PIDAT_SHIFT 0
-
-#define CODEC_RDY 0x80000000 /* AC97 read data valid */
-#define CODEC_WIP 0x40000000 /* AC97 write in progress */
-#define CODEC_PORD 0x00800000 /* 0 = write AC97 register */
-#define CODEC_POADD_MASK 0x007f0000
-#define CODEC_POADD_SHIFT 16
-#define CODEC_PODAT_MASK 0x0000ffff
-#define CODEC_PODAT_SHIFT 0
-
-
-#define LEGACY_JFAST 0x80000000 /* fast joystick timing */
-#define LEGACY_FIRQ 0x01000000 /* force IRQ */
-
-#define SCTRL_DACTEST 0x00400000 /* 1 = DAC test, test vector generation purposes */
-#define SCTRL_P2ENDINC 0x00380000 /* */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC 0x00070000 /* */
-#define SCTRL_SH_P2STINC 16
-#define SCTRL_R1LOOPSEL 0x00008000 /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL 0x00004000 /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL 0x00002000 /* 0 = loop mode */
-#define SCTRL_P2PAUSE 0x00001000 /* 1 = pause mode */
-#define SCTRL_P1PAUSE 0x00000800 /* 1 = pause mode */
-#define SCTRL_R1INTEN 0x00000400 /* enable interrupt */
-#define SCTRL_P2INTEN 0x00000200 /* enable interrupt */
-#define SCTRL_P1INTEN 0x00000100 /* enable interrupt */
-#define SCTRL_P1SCTRLD 0x00000080 /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN 0x00000040 /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB 0x00000020 /* 1 = 16bit */
-#define SCTRL_R1SMB 0x00000010 /* 1 = stereo */
-#define SCTRL_R1FMT 0x00000030 /* format mask */
-#define SCTRL_SH_R1FMT 4
-#define SCTRL_P2SEB 0x00000008 /* 1 = 16bit */
-#define SCTRL_P2SMB 0x00000004 /* 1 = stereo */
-#define SCTRL_P2FMT 0x0000000c /* format mask */
-#define SCTRL_SH_P2FMT 2
-#define SCTRL_P1SEB 0x00000002 /* 1 = 16bit */
-#define SCTRL_P1SMB 0x00000001 /* 1 = stereo */
-#define SCTRL_P1FMT 0x00000003 /* format mask */
-#define SCTRL_SH_P1FMT 0
-
-
-/* misc stuff */
-#define POLL_COUNT 0x1000
-#define FMODE_DAC 4 /* slight misuse of mode_t */
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF 256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define ES1371_MODULE_NAME "es1371"
-#define PFX ES1371_MODULE_NAME ": "
-
-/* --------------------------------------------------------------------- */
-
-struct es1371_state {
- /* magic */
- unsigned int magic;
-
- /* list of es1371 devices */
- struct list_head devs;
-
- /* the corresponding pci_dev structure */
- struct pci_dev *dev;
-
- /* soundcore stuff */
- int dev_audio;
- int dev_dac;
- int dev_midi;
-
- /* hardware resources */
- unsigned long io; /* long for SPARC */
- unsigned int irq;
-
- /* PCI ID's */
- u16 vendor;
- u16 device;
- u8 rev; /* the chip revision */
-
- /* options */
- int spdif_volume; /* S/PDIF output is enabled if != -1 */
-
-#ifdef ES1371_DEBUG
- /* debug /proc entry */
- struct proc_dir_entry *ps;
-#endif /* ES1371_DEBUG */
-
- struct ac97_codec *codec;
-
- /* wave stuff */
- unsigned ctrl;
- unsigned sctrl;
- unsigned dac1rate, dac2rate, adcrate;
-
- spinlock_t lock;
- struct mutex open_mutex;
- mode_t open_mode;
- wait_queue_head_t open_wait;
-
- struct dmabuf {
- void *rawbuf;
- dma_addr_t dmaaddr;
- unsigned buforder;
- unsigned numfrag;
- unsigned fragshift;
- unsigned hwptr, swptr;
- unsigned total_bytes;
- int count;
- unsigned error; /* over/underrun */
- wait_queue_head_t wait;
- /* redundant, but makes calculations easier */
- unsigned fragsize;
- unsigned dmasize;
- unsigned fragsamples;
- /* OSS stuff */
- unsigned mapped:1;
- unsigned ready:1;
- unsigned endcleared:1;
- unsigned enabled:1;
- unsigned ossfragshift;
- int ossmaxfrags;
- unsigned subdivision;
- } dma_dac1, dma_dac2, dma_adc;
-
- /* midi stuff */
- struct {
- unsigned ird, iwr, icnt;
- unsigned ord, owr, ocnt;
- wait_queue_head_t iwait;
- wait_queue_head_t owait;
- unsigned char ibuf[MIDIINBUF];
- unsigned char obuf[MIDIOUTBUF];
- } midi;
-
-#ifdef SUPPORT_JOYSTICK
- struct gameport *gameport;
-#endif
-
- struct mutex sem;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
- unsigned r = 0;
-
- if (x >= 0x10000) {
- x >>= 16;
- r += 16;
- }
- if (x >= 0x100) {
- x >>= 8;
- r += 8;
- }
- if (x >= 0x10) {
- x >>= 4;
- r += 4;
- }
- if (x >= 4) {
- x >>= 2;
- r += 2;
- }
- if (x >= 2)
- r++;
- return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static unsigned wait_src_ready(struct es1371_state *s)
-{
- unsigned int t, r;
-
- for (t = 0; t < POLL_COUNT; t++) {
- if (!((r = inl(s->io + ES1371_REG_SRCONV)) & SRC_BUSY))
- return r;
- udelay(1);
- }
- printk(KERN_DEBUG PFX "sample rate converter timeout r = 0x%08x\n", r);
- return r;
-}
-
-static unsigned src_read(struct es1371_state *s, unsigned reg)
-{
- unsigned int temp,i,orig;
-
- /* wait for ready */
- temp = wait_src_ready (s);
-
- /* we can only access the SRC at certain times, make sure
- we're allowed to before we read */
-
- orig = temp;
- /* expose the SRC state bits */
- outl ( (temp & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT) | 0x10000UL,
- s->io + ES1371_REG_SRCONV);
-
- /* now, wait for busy and the correct time to read */
- temp = wait_src_ready (s);
-
- if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){
- /* wait for the right state */
- for (i=0; i<POLL_COUNT; i++){
- temp = inl (s->io + ES1371_REG_SRCONV);
- if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 ))
- break;
- }
- }
-
- /* hide the state bits */
- outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV);
- return temp;
-
-
-}
-
-static void src_write(struct es1371_state *s, unsigned reg, unsigned data)
-{
-
- unsigned int r;
-
- r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC);
- r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK;
- r |= (data << SRC_RAMDATA_SHIFT) & SRC_RAMDATA_MASK;
- outl(r | SRC_WE, s->io + ES1371_REG_SRCONV);
-
-}
-
-/* --------------------------------------------------------------------- */
-
-/* most of the following here is black magic */
-static void set_adc_rate(struct es1371_state *s, unsigned rate)
-{
- unsigned long flags;
- unsigned int n, truncm, freq;
-
- if (rate > 48000)
- rate = 48000;
- if (rate < 4000)
- rate = 4000;
- n = rate / 3000;
- if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
- n--;
- truncm = (21 * n - 1) | 1;
- freq = ((48000UL << 15) / rate) * n;
- s->adcrate = (48000UL << 15) / (freq / n);
- spin_lock_irqsave(&s->lock, flags);
- if (rate >= 24000) {
- if (truncm > 239)
- truncm = 239;
- src_write(s, SRCREG_ADC+SRCREG_TRUNC_N,
- (((239 - truncm) >> 1) << 9) | (n << 4));
- } else {
- if (truncm > 119)
- truncm = 119;
- src_write(s, SRCREG_ADC+SRCREG_TRUNC_N,
- 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
- }
- src_write(s, SRCREG_ADC+SRCREG_INT_REGS,
- (src_read(s, SRCREG_ADC+SRCREG_INT_REGS) & 0x00ff) |
- ((freq >> 5) & 0xfc00));
- src_write(s, SRCREG_ADC+SRCREG_VFREQ_FRAC, freq & 0x7fff);
- src_write(s, SRCREG_VOL_ADC, n << 8);
- src_write(s, SRCREG_VOL_ADC+1, n << 8);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void set_dac1_rate(struct es1371_state *s, unsigned rate)
-{
- unsigned long flags;
- unsigned int freq, r;
-
- if (rate > 48000)
- rate = 48000;
- if (rate < 4000)
- rate = 4000;
- freq = ((rate << 15) + 1500) / 3000;
- s->dac1rate = (freq * 3000 + 16384) >> 15;
- spin_lock_irqsave(&s->lock, flags);
- r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)) | SRC_DDAC1;
- outl(r, s->io + ES1371_REG_SRCONV);
- src_write(s, SRCREG_DAC1+SRCREG_INT_REGS,
- (src_read(s, SRCREG_DAC1+SRCREG_INT_REGS) & 0x00ff) |
- ((freq >> 5) & 0xfc00));
- src_write(s, SRCREG_DAC1+SRCREG_VFREQ_FRAC, freq & 0x7fff);
- r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC));
- outl(r, s->io + ES1371_REG_SRCONV);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_dac2_rate(struct es1371_state *s, unsigned rate)
-{
- unsigned long flags;
- unsigned int freq, r;
-
- if (rate > 48000)
- rate = 48000;
- if (rate < 4000)
- rate = 4000;
- freq = ((rate << 15) + 1500) / 3000;
- s->dac2rate = (freq * 3000 + 16384) >> 15;
- spin_lock_irqsave(&s->lock, flags);
- r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2;
- outl(r, s->io + ES1371_REG_SRCONV);
- src_write(s, SRCREG_DAC2+SRCREG_INT_REGS,
- (src_read(s, SRCREG_DAC2+SRCREG_INT_REGS) & 0x00ff) |
- ((freq >> 5) & 0xfc00));
- src_write(s, SRCREG_DAC2+SRCREG_VFREQ_FRAC, freq & 0x7fff);
- r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC));
- outl(r, s->io + ES1371_REG_SRCONV);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void __devinit src_init(struct es1371_state *s)
-{
- unsigned int i;
-
- /* before we enable or disable the SRC we need
- to wait for it to become ready */
- wait_src_ready(s);
-
- outl(SRC_DIS, s->io + ES1371_REG_SRCONV);
-
- for (i = 0; i < 0x80; i++)
- src_write(s, i, 0);
-
- src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4);
- src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10);
- src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4);
- src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10);
- src_write(s, SRCREG_VOL_ADC, 1 << 12);
- src_write(s, SRCREG_VOL_ADC+1, 1 << 12);
- src_write(s, SRCREG_VOL_DAC1, 1 << 12);
- src_write(s, SRCREG_VOL_DAC1+1, 1 << 12);
- src_write(s, SRCREG_VOL_DAC2, 1 << 12);
- src_write(s, SRCREG_VOL_DAC2+1, 1 << 12);
- set_adc_rate(s, 22050);
- set_dac1_rate(s, 22050);
- set_dac2_rate(s, 22050);
-
- /* WARNING:
- * enabling the sample rate converter without properly programming
- * its parameters causes the chip to lock up (the SRC busy bit will
- * be stuck high, and I've found no way to rectify this other than
- * power cycle)
- */
- wait_src_ready(s);
- outl(0, s->io+ES1371_REG_SRCONV);
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
- struct es1371_state *s = (struct es1371_state *)codec->private_data;
- unsigned long flags;
- unsigned t, x;
-
- spin_lock_irqsave(&s->lock, flags);
- for (t = 0; t < POLL_COUNT; t++)
- if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
- break;
-
- /* save the current state for later */
- x = wait_src_ready(s);
-
- /* enable SRC state data in SRC mux */
- outl((x & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000,
- s->io+ES1371_REG_SRCONV);
-
- /* wait for not busy (state 0) first to avoid
- transition states */
- for (t=0; t<POLL_COUNT; t++){
- if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 )
- break;
- udelay(1);
- }
-
- /* wait for a SAFE time to write addr/data and then do it, dammit */
- for (t=0; t<POLL_COUNT; t++){
- if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000)
- break;
- udelay(1);
- }
-
- outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
- ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK), s->io+ES1371_REG_CODEC);
-
- /* restore SRC reg */
- wait_src_ready(s);
- outl(x, s->io+ES1371_REG_SRCONV);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
- struct es1371_state *s = (struct es1371_state *)codec->private_data;
- unsigned long flags;
- unsigned t, x;
-
- spin_lock_irqsave(&s->lock, flags);
-
- /* wait for WIP to go away */
- for (t = 0; t < 0x1000; t++)
- if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
- break;
-
- /* save the current state for later */
- x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC));
-
- /* enable SRC state data in SRC mux */
- outl( x | 0x00010000,
- s->io+ES1371_REG_SRCONV);
-
- /* wait for not busy (state 0) first to avoid
- transition states */
- for (t=0; t<POLL_COUNT; t++){
- if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 )
- break;
- udelay(1);
- }
-
- /* wait for a SAFE time to write addr/data and then do it, dammit */
- for (t=0; t<POLL_COUNT; t++){
- if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000)
- break;
- udelay(1);
- }
-
- outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD, s->io+ES1371_REG_CODEC);
- /* restore SRC reg */
- wait_src_ready(s);
- outl(x, s->io+ES1371_REG_SRCONV);
-
- /* wait for WIP again */
- for (t = 0; t < 0x1000; t++)
- if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
- break;
-
- /* now wait for the stinkin' data (RDY) */
- for (t = 0; t < POLL_COUNT; t++)
- if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY)
- break;
-
- spin_unlock_irqrestore(&s->lock, flags);
- return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct es1371_state *s)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&s->lock, flags);
- s->ctrl &= ~CTRL_ADC_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static inline void stop_dac1(struct es1371_state *s)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&s->lock, flags);
- s->ctrl &= ~CTRL_DAC1_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static inline void stop_dac2(struct es1371_state *s)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&s->lock, flags);
- s->ctrl &= ~CTRL_DAC2_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac1(struct es1371_state *s)
-{
- unsigned long flags;
- unsigned fragremain, fshift;
-
- spin_lock_irqsave(&s->lock, flags);
- if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0)
- && s->dma_dac1.ready) {
- s->ctrl |= CTRL_DAC1_EN;
- s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1));
- fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
- if (fragremain < 2*fshift)
- fragremain = s->dma_dac1.fragsize;
- outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT);
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT);
- }
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac2(struct es1371_state *s)
-{
- unsigned long flags;
- unsigned fragremain, fshift;
-
- spin_lock_irqsave(&s->lock, flags);
- if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0)
- && s->dma_dac2.ready) {
- s->ctrl |= CTRL_DAC2_EN;
- s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN |
- SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN |
- (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) |
- (0 << SCTRL_SH_P2STINC);
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1));
- fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
- if (fragremain < 2*fshift)
- fragremain = s->dma_dac2.fragsize;
- outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT);
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT);
- }
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct es1371_state *s)
-{
- unsigned long flags;
- unsigned fragremain, fshift;
-
- spin_lock_irqsave(&s->lock, flags);
- if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
- && s->dma_adc.ready) {
- s->ctrl |= CTRL_ADC_EN;
- s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1));
- fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT];
- if (fragremain < 2*fshift)
- fragremain = s->dma_adc.fragsize;
- outl((fragremain >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT);
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT);
- }
- spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-
-static inline void dealloc_dmabuf(struct es1371_state *s, struct dmabuf *db)
-{
- struct page *page, *pend;
-
- if (db->rawbuf) {
- /* undo marking the pages as reserved */
- pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
- for (page = virt_to_page(db->rawbuf); page <= pend; page++)
- ClearPageReserved(page);
- pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
- }
- db->rawbuf = NULL;
- db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct es1371_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg)
-{
- int order;
- unsigned bytepersec;
- unsigned bufs;
- struct page *page, *pend;
-
- db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
- if (!db->rawbuf) {
- db->ready = db->mapped = 0;
- for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
- if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
- break;
- if (!db->rawbuf)
- return -ENOMEM;
- db->buforder = order;
- /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
- pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
- for (page = virt_to_page(db->rawbuf); page <= pend; page++)
- SetPageReserved(page);
- }
- fmt &= ES1371_FMT_MASK;
- bytepersec = rate << sample_shift[fmt];
- bufs = PAGE_SIZE << db->buforder;
- if (db->ossfragshift) {
- if ((1000 << db->ossfragshift) < bytepersec)
- db->fragshift = ld2(bytepersec/1000);
- else
- db->fragshift = db->ossfragshift;
- } else {
- db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
- if (db->fragshift < 3)
- db->fragshift = 3;
- }
- db->numfrag = bufs >> db->fragshift;
- while (db->numfrag < 4 && db->fragshift > 3) {
- db->fragshift--;
- db->numfrag = bufs >> db->fragshift;
- }
- db->fragsize = 1 << db->fragshift;
- if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
- db->numfrag = db->ossmaxfrags;
- db->fragsamples = db->fragsize >> sample_shift[fmt];
- db->dmasize = db->numfrag << db->fragshift;
- memset(db->rawbuf, (fmt & ES1371_FMT_S16) ? 0 : 0x80, db->dmasize);
- outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
- outl(db->dmaaddr, s->io+(reg & 0xff));
- outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
- db->enabled = 1;
- db->ready = 1;
- return 0;
-}
-
-static inline int prog_dmabuf_adc(struct es1371_state *s)
-{
- stop_adc(s);
- return prog_dmabuf(s, &s->dma_adc, s->adcrate, (s->sctrl >> SCTRL_SH_R1FMT) & ES1371_FMT_MASK,
- ES1371_REG_ADC_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac2(struct es1371_state *s)
-{
- stop_dac2(s);
- return prog_dmabuf(s, &s->dma_dac2, s->dac2rate, (s->sctrl >> SCTRL_SH_P2FMT) & ES1371_FMT_MASK,
- ES1371_REG_DAC2_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac1(struct es1371_state *s)
-{
- stop_dac1(s);
- return prog_dmabuf(s, &s->dma_dac1, s->dac1rate, (s->sctrl >> SCTRL_SH_P1FMT) & ES1371_FMT_MASK,
- ES1371_REG_DAC1_FRAMEADR);
-}
-
-static inline unsigned get_hwptr(struct es1371_state *s, struct dmabuf *db, unsigned reg)
-{
- unsigned hwptr, diff;
-
- outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE);
- hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc;
- diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize;
- db->hwptr = hwptr;
- return diff;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
- if (bptr + len > bsize) {
- unsigned x = bsize - bptr;
- memset(((char *)buf) + bptr, c, x);
- bptr = 0;
- len -= x;
- }
- memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void es1371_update_ptr(struct es1371_state *s)
-{
- int diff;
-
- /* update ADC pointer */
- if (s->ctrl & CTRL_ADC_EN) {
- diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT);
- s->dma_adc.total_bytes += diff;
- s->dma_adc.count += diff;
- if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
- wake_up(&s->dma_adc.wait);
- if (!s->dma_adc.mapped) {
- if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
- s->ctrl &= ~CTRL_ADC_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- s->dma_adc.error++;
- }
- }
- }
- /* update DAC1 pointer */
- if (s->ctrl & CTRL_DAC1_EN) {
- diff = get_hwptr(s, &s->dma_dac1, ES1371_REG_DAC1_FRAMECNT);
- s->dma_dac1.total_bytes += diff;
- if (s->dma_dac1.mapped) {
- s->dma_dac1.count += diff;
- if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
- wake_up(&s->dma_dac1.wait);
- } else {
- s->dma_dac1.count -= diff;
- if (s->dma_dac1.count <= 0) {
- s->ctrl &= ~CTRL_DAC1_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- s->dma_dac1.error++;
- } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) {
- clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr,
- s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
- s->dma_dac1.endcleared = 1;
- }
- if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
- wake_up(&s->dma_dac1.wait);
- }
- }
- /* update DAC2 pointer */
- if (s->ctrl & CTRL_DAC2_EN) {
- diff = get_hwptr(s, &s->dma_dac2, ES1371_REG_DAC2_FRAMECNT);
- s->dma_dac2.total_bytes += diff;
- if (s->dma_dac2.mapped) {
- s->dma_dac2.count += diff;
- if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
- wake_up(&s->dma_dac2.wait);
- } else {
- s->dma_dac2.count -= diff;
- if (s->dma_dac2.count <= 0) {
- s->ctrl &= ~CTRL_DAC2_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- s->dma_dac2.error++;
- } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) {
- clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr,
- s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
- s->dma_dac2.endcleared = 1;
- }
- if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
- wake_up(&s->dma_dac2.wait);
- }
- }
-}
-
-/* hold spinlock for the following! */
-static void es1371_handle_midi(struct es1371_state *s)
-{
- unsigned char ch;
- int wake;
-
- if (!(s->ctrl & CTRL_UART_EN))
- return;
- wake = 0;
- while (inb(s->io+ES1371_REG_UART_STATUS) & USTAT_RXRDY) {
- ch = inb(s->io+ES1371_REG_UART_DATA);
- if (s->midi.icnt < MIDIINBUF) {
- s->midi.ibuf[s->midi.iwr] = ch;
- s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
- s->midi.icnt++;
- }
- wake = 1;
- }
- if (wake)
- wake_up(&s->midi.iwait);
- wake = 0;
- while ((inb(s->io+ES1371_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) {
- outb(s->midi.obuf[s->midi.ord], s->io+ES1371_REG_UART_DATA);
- s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
- s->midi.ocnt--;
- if (s->midi.ocnt < MIDIOUTBUF-16)
- wake = 1;
- }
- if (wake)
- wake_up(&s->midi.owait);
- outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL);
-}
-
-static irqreturn_t es1371_interrupt(int irq, void *dev_id)
-{
- struct es1371_state *s = dev_id;
- unsigned int intsrc, sctl;
-
- /* fastpath out, to ease interrupt sharing */
- intsrc = inl(s->io+ES1371_REG_STATUS);
- if (!(intsrc & 0x80000000))
- return IRQ_NONE;
- spin_lock(&s->lock);
- /* clear audio interrupts first */
- sctl = s->sctrl;
- if (intsrc & STAT_ADC)
- sctl &= ~SCTRL_R1INTEN;
- if (intsrc & STAT_DAC1)
- sctl &= ~SCTRL_P1INTEN;
- if (intsrc & STAT_DAC2)
- sctl &= ~SCTRL_P2INTEN;
- outl(sctl, s->io+ES1371_REG_SERIAL_CONTROL);
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- es1371_update_ptr(s);
- es1371_handle_midi(s);
- spin_unlock(&s->lock);
- return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value\n";
-
-#define VALIDATE_STATE(s) \
-({ \
- if (!(s) || (s)->magic != ES1371_MAGIC) { \
- printk(invalid_magic); \
- return -ENXIO; \
- } \
-})
-
-/* --------------------------------------------------------------------- */
-
-/* Conversion table for S/PDIF PCM volume emulation through the SRC */
-/* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */
-static const unsigned short DACVolTable[101] =
-{
- 0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff,
- 0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a,
- 0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab,
- 0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b,
- 0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb,
- 0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b,
- 0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7,
- 0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c,
- 0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b,
- 0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c,
- 0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027,
- 0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019,
- 0x0018, 0x0017, 0x0016, 0x0014, 0x0000
-};
-
-/*
- * when we are in S/PDIF mode, we want to disable any analog output so
- * we filter the mixer ioctls
- */
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
-{
- struct es1371_state *s = (struct es1371_state *)codec->private_data;
- int val;
- unsigned long flags;
- unsigned int left, right;
-
- VALIDATE_STATE(s);
- /* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */
- if (s->spdif_volume == -1)
- return codec->mixer_ioctl(codec, cmd, arg);
- switch (cmd) {
- case SOUND_MIXER_WRITE_VOLUME:
- return 0;
-
- case SOUND_MIXER_WRITE_PCM: /* use SRC for PCM volume */
- if (get_user(val, (int __user *)arg))
- return -EFAULT;
- right = ((val >> 8) & 0xff);
- left = (val & 0xff);
- if (right > 100)
- right = 100;
- if (left > 100)
- left = 100;
- s->spdif_volume = (right << 8) | left;
- spin_lock_irqsave(&s->lock, flags);
- src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]);
- src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]);
- spin_unlock_irqrestore(&s->lock, flags);
- return 0;
-
- case SOUND_MIXER_READ_PCM:
- return put_user(s->spdif_volume, (int __user *)arg);
- }
- return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * AC97 Mixer Register to Connections mapping of the Concert 97 board
- *
- * AC97_MASTER_VOL_STEREO Line Out
- * AC97_MASTER_VOL_MONO TAD Output
- * AC97_PCBEEP_VOL none
- * AC97_PHONE_VOL TAD Input (mono)
- * AC97_MIC_VOL MIC Input (mono)
- * AC97_LINEIN_VOL Line Input (stereo)
- * AC97_CD_VOL CD Input (stereo)
- * AC97_VIDEO_VOL none
- * AC97_AUX_VOL Aux Input (stereo)
- * AC97_PCMOUT_VOL Wave Output (stereo)
- */
-
-static int es1371_open_mixdev(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- struct list_head *list;
- struct es1371_state *s;
-
- for (list = devs.next; ; list = list->next) {
- if (list == &devs)
- return -ENODEV;
- s = list_entry(list, struct es1371_state, devs);
- if (s->codec->dev_mixer == minor)
- break;
- }
- VALIDATE_STATE(s);
- file->private_data = s;
- return nonseekable_open(inode, file);
-}
-
-static int es1371_release_mixdev(struct inode *inode, struct file *file)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
-
- VALIDATE_STATE(s);
- return 0;
-}
-
-static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- struct ac97_codec *codec = s->codec;
-
- return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const*/ struct file_operations es1371_mixer_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .ioctl = es1371_ioctl_mixdev,
- .open = es1371_open_mixdev,
- .release = es1371_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac1(struct es1371_state *s, int nonblock)
-{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- int count, tmo;
-
- if (s->dma_dac1.mapped || !s->dma_dac1.ready)
- return 0;
- add_wait_queue(&s->dma_dac1.wait, &wait);
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irqsave(&s->lock, flags);
- count = s->dma_dac1.count;
- spin_unlock_irqrestore(&s->lock, flags);
- if (count <= 0)
- break;
- if (signal_pending(current))
- break;
- if (nonblock) {
- remove_wait_queue(&s->dma_dac1.wait, &wait);
- set_current_state(TASK_RUNNING);
- return -EBUSY;
- }
- tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate;
- tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
- if (!schedule_timeout(tmo + 1))
- DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");)
- }
- remove_wait_queue(&s->dma_dac1.wait, &wait);
- set_current_state(TASK_RUNNING);
- if (signal_pending(current))
- return -ERESTARTSYS;
- return 0;
-}
-
-static int drain_dac2(struct es1371_state *s, int nonblock)
-{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- int count, tmo;
-
- if (s->dma_dac2.mapped || !s->dma_dac2.ready)
- return 0;
- add_wait_queue(&s->dma_dac2.wait, &wait);
- for (;;) {
- __set_current_state(TASK_UNINTERRUPTIBLE);
- spin_lock_irqsave(&s->lock, flags);
- count = s->dma_dac2.count;
- spin_unlock_irqrestore(&s->lock, flags);
- if (count <= 0)
- break;
- if (signal_pending(current))
- break;
- if (nonblock) {
- remove_wait_queue(&s->dma_dac2.wait, &wait);
- set_current_state(TASK_RUNNING);
- return -EBUSY;
- }
- tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate;
- tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
- if (!schedule_timeout(tmo + 1))
- DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");)
- }
- remove_wait_queue(&s->dma_dac2.wait, &wait);
- set_current_state(TASK_RUNNING);
- if (signal_pending(current))
- return -ERESTARTSYS;
- return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret = 0;
- unsigned long flags;
- unsigned swptr;
- int cnt;
-
- VALIDATE_STATE(s);
- if (s->dma_adc.mapped)
- return -ENXIO;
- if (!access_ok(VERIFY_WRITE, buffer, count))
- return -EFAULT;
- mutex_lock(&s->sem);
- if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
- goto out2;
-
- add_wait_queue(&s->dma_adc.wait, &wait);
- while (count > 0) {
- spin_lock_irqsave(&s->lock, flags);
- swptr = s->dma_adc.swptr;
- cnt = s->dma_adc.dmasize-swptr;
- if (s->dma_adc.count < cnt)
- cnt = s->dma_adc.count;
- if (cnt <= 0)
- __set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irqrestore(&s->lock, flags);
- if (cnt > count)
- cnt = count;
- if (cnt <= 0) {
- if (s->dma_adc.enabled)
- start_adc(s);
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- goto out;
- }
- mutex_unlock(&s->sem);
- schedule();
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- goto out2;
- }
- mutex_lock(&s->sem);
- if (s->dma_adc.mapped)
- {
- ret = -ENXIO;
- goto out;
- }
- continue;
- }
- if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
- if (!ret)
- ret = -EFAULT;
- goto out;
- }
- swptr = (swptr + cnt) % s->dma_adc.dmasize;
- spin_lock_irqsave(&s->lock, flags);
- s->dma_adc.swptr = swptr;
- s->dma_adc.count -= cnt;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= cnt;
- buffer += cnt;
- ret += cnt;
- if (s->dma_adc.enabled)
- start_adc(s);
- }
-out:
- mutex_unlock(&s->sem);
-out2:
- remove_wait_queue(&s->dma_adc.wait, &wait);
- set_current_state(TASK_RUNNING);
- return ret;
-}
-
-static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret;
- unsigned long flags;
- unsigned swptr;
- int cnt;
-
- VALIDATE_STATE(s);
- if (s->dma_dac2.mapped)
- return -ENXIO;
- if (!access_ok(VERIFY_READ, buffer, count))
- return -EFAULT;
- mutex_lock(&s->sem);
- if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
- goto out3;
- ret = 0;
- add_wait_queue(&s->dma_dac2.wait, &wait);
- while (count > 0) {
- spin_lock_irqsave(&s->lock, flags);
- if (s->dma_dac2.count < 0) {
- s->dma_dac2.count = 0;
- s->dma_dac2.swptr = s->dma_dac2.hwptr;
- }
- swptr = s->dma_dac2.swptr;
- cnt = s->dma_dac2.dmasize-swptr;
- if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)
- cnt = s->dma_dac2.dmasize - s->dma_dac2.count;
- if (cnt <= 0)
- __set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irqrestore(&s->lock, flags);
- if (cnt > count)
- cnt = count;
- if (cnt <= 0) {
- if (s->dma_dac2.enabled)
- start_dac2(s);
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- goto out;
- }
- mutex_unlock(&s->sem);
- schedule();
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- goto out2;
- }
- mutex_lock(&s->sem);
- if (s->dma_dac2.mapped)
- {
- ret = -ENXIO;
- goto out;
- }
- continue;
- }
- if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {
- if (!ret)
- ret = -EFAULT;
- goto out;
- }
- swptr = (swptr + cnt) % s->dma_dac2.dmasize;
- spin_lock_irqsave(&s->lock, flags);
- s->dma_dac2.swptr = swptr;
- s->dma_dac2.count += cnt;
- s->dma_dac2.endcleared = 0;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= cnt;
- buffer += cnt;
- ret += cnt;
- if (s->dma_dac2.enabled)
- start_dac2(s);
- }
-out:
- mutex_unlock(&s->sem);
-out2:
- remove_wait_queue(&s->dma_dac2.wait, &wait);
-out3:
- set_current_state(TASK_RUNNING);
- return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- unsigned long flags;
- unsigned int mask = 0;
-
- VALIDATE_STATE(s);
- if (file->f_mode & FMODE_WRITE) {
- if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
- return 0;
- poll_wait(file, &s->dma_dac2.wait, wait);
- }
- if (file->f_mode & FMODE_READ) {
- if (!s->dma_adc.ready && prog_dmabuf_adc(s))
- return 0;
- poll_wait(file, &s->dma_adc.wait, wait);
- }
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- if (file->f_mode & FMODE_READ) {
- if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
- mask |= POLLIN | POLLRDNORM;
- }
- if (file->f_mode & FMODE_WRITE) {
- if (s->dma_dac2.mapped) {
- if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
- mask |= POLLOUT | POLLWRNORM;
- } else {
- if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
- mask |= POLLOUT | POLLWRNORM;
- }
- }
- spin_unlock_irqrestore(&s->lock, flags);
- return mask;
-}
-
-static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- struct dmabuf *db;
- int ret = 0;
- unsigned long size;
-
- VALIDATE_STATE(s);
- lock_kernel();
- mutex_lock(&s->sem);
-
- if (vma->vm_flags & VM_WRITE) {
- if ((ret = prog_dmabuf_dac2(s)) != 0) {
- goto out;
- }
- db = &s->dma_dac2;
- } else if (vma->vm_flags & VM_READ) {
- if ((ret = prog_dmabuf_adc(s)) != 0) {
- goto out;
- }
- db = &s->dma_adc;
- } else {
- ret = -EINVAL;
- goto out;
- }
- if (vma->vm_pgoff != 0) {
- ret = -EINVAL;
- goto out;
- }
- size = vma->vm_end - vma->vm_start;
- if (size > (PAGE_SIZE << db->buforder)) {
- ret = -EINVAL;
- goto out;
- }
- if (remap_pfn_range(vma, vma->vm_start,
- virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
- size, vma->vm_page_prot)) {
- ret = -EAGAIN;
- goto out;
- }
- db->mapped = 1;
-out:
- mutex_unlock(&s->sem);
- unlock_kernel();
- return ret;
-}
-
-static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- unsigned long flags;
- audio_buf_info abinfo;
- count_info cinfo;
- int count;
- int val, mapped, ret;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
-
- VALIDATE_STATE(s);
- mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
- ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
- switch (cmd) {
- case OSS_GETVERSION:
- return put_user(SOUND_VERSION, p);
-
- case SNDCTL_DSP_SYNC:
- if (file->f_mode & FMODE_WRITE)
- return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
- return 0;
-
- case SNDCTL_DSP_SETDUPLEX:
- return 0;
-
- case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-
- case SNDCTL_DSP_RESET:
- if (file->f_mode & FMODE_WRITE) {
- stop_dac2(s);
- synchronize_irq(s->irq);
- s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;
- }
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- synchronize_irq(s->irq);
- s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
- }
- return 0;
-
- case SNDCTL_DSP_SPEED:
- if (get_user(val, p))
- return -EFAULT;
- if (val >= 0) {
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- set_adc_rate(s, val);
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac2(s);
- s->dma_dac2.ready = 0;
- set_dac2_rate(s, val);
- }
- }
- return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
-
- case SNDCTL_DSP_STEREO:
- if (get_user(val, p))
- return -EFAULT;
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val)
- s->sctrl |= SCTRL_R1SMB;
- else
- s->sctrl &= ~SCTRL_R1SMB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac2(s);
- s->dma_dac2.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val)
- s->sctrl |= SCTRL_P2SMB;
- else
- s->sctrl &= ~SCTRL_P2SMB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- return 0;
-
- case SNDCTL_DSP_CHANNELS:
- if (get_user(val, p))
- return -EFAULT;
- if (val != 0) {
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val >= 2)
- s->sctrl |= SCTRL_R1SMB;
- else
- s->sctrl &= ~SCTRL_R1SMB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac2(s);
- s->dma_dac2.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val >= 2)
- s->sctrl |= SCTRL_P2SMB;
- else
- s->sctrl &= ~SCTRL_P2SMB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- }
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-
- case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, p);
-
- case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, p))
- return -EFAULT;
- if (val != AFMT_QUERY) {
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- s->dma_adc.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val == AFMT_S16_LE)
- s->sctrl |= SCTRL_R1SEB;
- else
- s->sctrl &= ~SCTRL_R1SEB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- if (file->f_mode & FMODE_WRITE) {
- stop_dac2(s);
- s->dma_dac2.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val == AFMT_S16_LE)
- s->sctrl |= SCTRL_P2SEB;
- else
- s->sctrl &= ~SCTRL_P2SEB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- }
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ?
- AFMT_S16_LE : AFMT_U8, p);
-
- case SNDCTL_DSP_POST:
- return 0;
-
- case SNDCTL_DSP_GETTRIGGER:
- val = 0;
- if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN)
- val |= PCM_ENABLE_INPUT;
- if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN)
- val |= PCM_ENABLE_OUTPUT;
- return put_user(val, p);
-
- case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, p))
- return -EFAULT;
- if (file->f_mode & FMODE_READ) {
- if (val & PCM_ENABLE_INPUT) {
- if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
- return ret;
- s->dma_adc.enabled = 1;
- start_adc(s);
- } else {
- s->dma_adc.enabled = 0;
- stop_adc(s);
- }
- }
- if (file->f_mode & FMODE_WRITE) {
- if (val & PCM_ENABLE_OUTPUT) {
- if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
- return ret;
- s->dma_dac2.enabled = 1;
- start_dac2(s);
- } else {
- s->dma_dac2.enabled = 0;
- stop_dac2(s);
- }
- }
- return 0;
-
- case SNDCTL_DSP_GETOSPACE:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- abinfo.fragsize = s->dma_dac2.fragsize;
- count = s->dma_dac2.count;
- if (count < 0)
- count = 0;
- abinfo.bytes = s->dma_dac2.dmasize - count;
- abinfo.fragstotal = s->dma_dac2.numfrag;
- abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_GETISPACE:
- if (!(file->f_mode & FMODE_READ))
- return -EINVAL;
- if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- abinfo.fragsize = s->dma_adc.fragsize;
- count = s->dma_adc.count;
- if (count < 0)
- count = 0;
- abinfo.bytes = count;
- abinfo.fragstotal = s->dma_adc.numfrag;
- abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_NONBLOCK:
- file->f_flags |= O_NONBLOCK;
- return 0;
-
- case SNDCTL_DSP_GETODELAY:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- count = s->dma_dac2.count;
- spin_unlock_irqrestore(&s->lock, flags);
- if (count < 0)
- count = 0;
- return put_user(count, p);
-
- case SNDCTL_DSP_GETIPTR:
- if (!(file->f_mode & FMODE_READ))
- return -EINVAL;
- if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- cinfo.bytes = s->dma_adc.total_bytes;
- count = s->dma_adc.count;
- if (count < 0)
- count = 0;
- cinfo.blocks = count >> s->dma_adc.fragshift;
- cinfo.ptr = s->dma_adc.hwptr;
- if (s->dma_adc.mapped)
- s->dma_adc.count &= s->dma_adc.fragsize-1;
- spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETOPTR:
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- cinfo.bytes = s->dma_dac2.total_bytes;
- count = s->dma_dac2.count;
- if (count < 0)
- count = 0;
- cinfo.blocks = count >> s->dma_dac2.fragshift;
- cinfo.ptr = s->dma_dac2.hwptr;
- if (s->dma_dac2.mapped)
- s->dma_dac2.count &= s->dma_dac2.fragsize-1;
- spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETBLKSIZE:
- if (file->f_mode & FMODE_WRITE) {
- if ((val = prog_dmabuf_dac2(s)))
- return val;
- return put_user(s->dma_dac2.fragsize, p);
- }
- if ((val = prog_dmabuf_adc(s)))
- return val;
- return put_user(s->dma_adc.fragsize, p);
-
- case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, p))
- return -EFAULT;
- if (file->f_mode & FMODE_READ) {
- s->dma_adc.ossfragshift = val & 0xffff;
- s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
- if (s->dma_adc.ossfragshift < 4)
- s->dma_adc.ossfragshift = 4;
- if (s->dma_adc.ossfragshift > 15)
- s->dma_adc.ossfragshift = 15;
- if (s->dma_adc.ossmaxfrags < 4)
- s->dma_adc.ossmaxfrags = 4;
- }
- if (file->f_mode & FMODE_WRITE) {
- s->dma_dac2.ossfragshift = val & 0xffff;
- s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;
- if (s->dma_dac2.ossfragshift < 4)
- s->dma_dac2.ossfragshift = 4;
- if (s->dma_dac2.ossfragshift > 15)
- s->dma_dac2.ossfragshift = 15;
- if (s->dma_dac2.ossmaxfrags < 4)
- s->dma_dac2.ossmaxfrags = 4;
- }
- return 0;
-
- case SNDCTL_DSP_SUBDIVIDE:
- if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
- (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
- return -EINVAL;
- if (get_user(val, p))
- return -EFAULT;
- if (val != 1 && val != 2 && val != 4)
- return -EINVAL;
- if (file->f_mode & FMODE_READ)
- s->dma_adc.subdivision = val;
- if (file->f_mode & FMODE_WRITE)
- s->dma_dac2.subdivision = val;
- return 0;
-
- case SOUND_PCM_READ_RATE:
- return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p);
-
- case SOUND_PCM_READ_CHANNELS:
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-
- case SOUND_PCM_READ_BITS:
- return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, p);
-
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
- case SOUND_PCM_READ_FILTER:
- return -EINVAL;
-
- }
- return mixdev_ioctl(s->codec, cmd, arg);
-}
-
-static int es1371_open(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- struct list_head *list;
- struct es1371_state *s;
-
- for (list = devs.next; ; list = list->next) {
- if (list == &devs)
- return -ENODEV;
- s = list_entry(list, struct es1371_state, devs);
- if (!((s->dev_audio ^ minor) & ~0xf))
- break;
- }
- VALIDATE_STATE(s);
- file->private_data = s;
- /* wait for device to become free */
- mutex_lock(&s->open_mutex);
- while (s->open_mode & file->f_mode) {
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&s->open_mutex);
- return -EBUSY;
- }
- add_wait_queue(&s->open_wait, &wait);
- __set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&s->open_mutex);
- schedule();
- remove_wait_queue(&s->open_wait, &wait);
- set_current_state(TASK_RUNNING);
- if (signal_pending(current))
- return -ERESTARTSYS;
- mutex_lock(&s->open_mutex);
- }
- if (file->f_mode & FMODE_READ) {
- s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
- s->dma_adc.enabled = 1;
- set_adc_rate(s, 8000);
- }
- if (file->f_mode & FMODE_WRITE) {
- s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
- s->dma_dac2.enabled = 1;
- set_dac2_rate(s, 8000);
- }
- spin_lock_irqsave(&s->lock, flags);
- if (file->f_mode & FMODE_READ) {
- s->sctrl &= ~SCTRL_R1FMT;
- if ((minor & 0xf) == SND_DEV_DSP16)
- s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_R1FMT;
- else
- s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_R1FMT;
- }
- if (file->f_mode & FMODE_WRITE) {
- s->sctrl &= ~SCTRL_P2FMT;
- if ((minor & 0xf) == SND_DEV_DSP16)
- s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P2FMT;
- else
- s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P2FMT;
- }
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- mutex_unlock(&s->open_mutex);
- mutex_init(&s->sem);
- return nonseekable_open(inode, file);
-}
-
-static int es1371_release(struct inode *inode, struct file *file)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
-
- VALIDATE_STATE(s);
- lock_kernel();
- if (file->f_mode & FMODE_WRITE)
- drain_dac2(s, file->f_flags & O_NONBLOCK);
- mutex_lock(&s->open_mutex);
- if (file->f_mode & FMODE_WRITE) {
- stop_dac2(s);
- dealloc_dmabuf(s, &s->dma_dac2);
- }
- if (file->f_mode & FMODE_READ) {
- stop_adc(s);
- dealloc_dmabuf(s, &s->dma_adc);
- }
- s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
- mutex_unlock(&s->open_mutex);
- wake_up(&s->open_wait);
- unlock_kernel();
- return 0;
-}
-
-static /*const*/ struct file_operations es1371_audio_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = es1371_read,
- .write = es1371_write,
- .poll = es1371_poll,
- .ioctl = es1371_ioctl,
- .mmap = es1371_mmap,
- .open = es1371_open,
- .release = es1371_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret = 0;
- unsigned long flags;
- unsigned swptr;
- int cnt;
-
- VALIDATE_STATE(s);
- if (s->dma_dac1.mapped)
- return -ENXIO;
- if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
- return ret;
- if (!access_ok(VERIFY_READ, buffer, count))
- return -EFAULT;
- add_wait_queue(&s->dma_dac1.wait, &wait);
- while (count > 0) {
- spin_lock_irqsave(&s->lock, flags);
- if (s->dma_dac1.count < 0) {
- s->dma_dac1.count = 0;
- s->dma_dac1.swptr = s->dma_dac1.hwptr;
- }
- swptr = s->dma_dac1.swptr;
- cnt = s->dma_dac1.dmasize-swptr;
- if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)
- cnt = s->dma_dac1.dmasize - s->dma_dac1.count;
- if (cnt <= 0)
- __set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irqrestore(&s->lock, flags);
- if (cnt > count)
- cnt = count;
- if (cnt <= 0) {
- if (s->dma_dac1.enabled)
- start_dac1(s);
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- schedule();
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
- continue;
- }
- if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
- swptr = (swptr + cnt) % s->dma_dac1.dmasize;
- spin_lock_irqsave(&s->lock, flags);
- s->dma_dac1.swptr = swptr;
- s->dma_dac1.count += cnt;
- s->dma_dac1.endcleared = 0;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= cnt;
- buffer += cnt;
- ret += cnt;
- if (s->dma_dac1.enabled)
- start_dac1(s);
- }
- remove_wait_queue(&s->dma_dac1.wait, &wait);
- set_current_state(TASK_RUNNING);
- return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_poll_dac(struct file *file, struct poll_table_struct *wait)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- unsigned long flags;
- unsigned int mask = 0;
-
- VALIDATE_STATE(s);
- if (!s->dma_dac1.ready && prog_dmabuf_dac1(s))
- return 0;
- poll_wait(file, &s->dma_dac1.wait, wait);
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- if (s->dma_dac1.mapped) {
- if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
- mask |= POLLOUT | POLLWRNORM;
- } else {
- if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
- mask |= POLLOUT | POLLWRNORM;
- }
- spin_unlock_irqrestore(&s->lock, flags);
- return mask;
-}
-
-static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- int ret;
- unsigned long size;
-
- VALIDATE_STATE(s);
- if (!(vma->vm_flags & VM_WRITE))
- return -EINVAL;
- lock_kernel();
- if ((ret = prog_dmabuf_dac1(s)) != 0)
- goto out;
- ret = -EINVAL;
- if (vma->vm_pgoff != 0)
- goto out;
- size = vma->vm_end - vma->vm_start;
- if (size > (PAGE_SIZE << s->dma_dac1.buforder))
- goto out;
- ret = -EAGAIN;
- if (remap_pfn_range(vma, vma->vm_start,
- virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT,
- size, vma->vm_page_prot))
- goto out;
- s->dma_dac1.mapped = 1;
- ret = 0;
-out:
- unlock_kernel();
- return ret;
-}
-
-static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- unsigned long flags;
- audio_buf_info abinfo;
- count_info cinfo;
- int count;
- int val, ret;
- int __user *p = (int __user *)arg;
-
- VALIDATE_STATE(s);
- switch (cmd) {
- case OSS_GETVERSION:
- return put_user(SOUND_VERSION, p);
-
- case SNDCTL_DSP_SYNC:
- return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
-
- case SNDCTL_DSP_SETDUPLEX:
- return -EINVAL;
-
- case SNDCTL_DSP_GETCAPS:
- return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-
- case SNDCTL_DSP_RESET:
- stop_dac1(s);
- synchronize_irq(s->irq);
- s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;
- return 0;
-
- case SNDCTL_DSP_SPEED:
- if (get_user(val, p))
- return -EFAULT;
- if (val >= 0) {
- stop_dac1(s);
- s->dma_dac1.ready = 0;
- set_dac1_rate(s, val);
- }
- return put_user(s->dac1rate, p);
-
- case SNDCTL_DSP_STEREO:
- if (get_user(val, p))
- return -EFAULT;
- stop_dac1(s);
- s->dma_dac1.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val)
- s->sctrl |= SCTRL_P1SMB;
- else
- s->sctrl &= ~SCTRL_P1SMB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- return 0;
-
- case SNDCTL_DSP_CHANNELS:
- if (get_user(val, p))
- return -EFAULT;
- if (val != 0) {
- stop_dac1(s);
- s->dma_dac1.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val >= 2)
- s->sctrl |= SCTRL_P1SMB;
- else
- s->sctrl &= ~SCTRL_P1SMB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
- case SNDCTL_DSP_GETFMTS: /* Returns a mask */
- return put_user(AFMT_S16_LE|AFMT_U8, p);
-
- case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
- if (get_user(val, p))
- return -EFAULT;
- if (val != AFMT_QUERY) {
- stop_dac1(s);
- s->dma_dac1.ready = 0;
- spin_lock_irqsave(&s->lock, flags);
- if (val == AFMT_S16_LE)
- s->sctrl |= SCTRL_P1SEB;
- else
- s->sctrl &= ~SCTRL_P1SEB;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
-
- case SNDCTL_DSP_POST:
- return 0;
-
- case SNDCTL_DSP_GETTRIGGER:
- return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
-
- case SNDCTL_DSP_SETTRIGGER:
- if (get_user(val, p))
- return -EFAULT;
- if (val & PCM_ENABLE_OUTPUT) {
- if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
- return ret;
- s->dma_dac1.enabled = 1;
- start_dac1(s);
- } else {
- s->dma_dac1.enabled = 0;
- stop_dac1(s);
- }
- return 0;
-
- case SNDCTL_DSP_GETOSPACE:
- if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- abinfo.fragsize = s->dma_dac1.fragsize;
- count = s->dma_dac1.count;
- if (count < 0)
- count = 0;
- abinfo.bytes = s->dma_dac1.dmasize - count;
- abinfo.fragstotal = s->dma_dac1.numfrag;
- abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;
- spin_unlock_irqrestore(&s->lock, flags);
- return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
- case SNDCTL_DSP_NONBLOCK:
- file->f_flags |= O_NONBLOCK;
- return 0;
-
- case SNDCTL_DSP_GETODELAY:
- if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- count = s->dma_dac1.count;
- spin_unlock_irqrestore(&s->lock, flags);
- if (count < 0)
- count = 0;
- return put_user(count, p);
-
- case SNDCTL_DSP_GETOPTR:
- if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
- return val;
- spin_lock_irqsave(&s->lock, flags);
- es1371_update_ptr(s);
- cinfo.bytes = s->dma_dac1.total_bytes;
- count = s->dma_dac1.count;
- if (count < 0)
- count = 0;
- cinfo.blocks = count >> s->dma_dac1.fragshift;
- cinfo.ptr = s->dma_dac1.hwptr;
- if (s->dma_dac1.mapped)
- s->dma_dac1.count &= s->dma_dac1.fragsize-1;
- spin_unlock_irqrestore(&s->lock, flags);
- if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_DSP_GETBLKSIZE:
- if ((val = prog_dmabuf_dac1(s)))
- return val;
- return put_user(s->dma_dac1.fragsize, p);
-
- case SNDCTL_DSP_SETFRAGMENT:
- if (get_user(val, p))
- return -EFAULT;
- s->dma_dac1.ossfragshift = val & 0xffff;
- s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
- if (s->dma_dac1.ossfragshift < 4)
- s->dma_dac1.ossfragshift = 4;
- if (s->dma_dac1.ossfragshift > 15)
- s->dma_dac1.ossfragshift = 15;
- if (s->dma_dac1.ossmaxfrags < 4)
- s->dma_dac1.ossmaxfrags = 4;
- return 0;
-
- case SNDCTL_DSP_SUBDIVIDE:
- if (s->dma_dac1.subdivision)
- return -EINVAL;
- if (get_user(val, p))
- return -EFAULT;
- if (val != 1 && val != 2 && val != 4)
- return -EINVAL;
- s->dma_dac1.subdivision = val;
- return 0;
-
- case SOUND_PCM_READ_RATE:
- return put_user(s->dac1rate, p);
-
- case SOUND_PCM_READ_CHANNELS:
- return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
- case SOUND_PCM_READ_BITS:
- return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
-
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
- case SOUND_PCM_READ_FILTER:
- return -EINVAL;
-
- }
- return mixdev_ioctl(s->codec, cmd, arg);
-}
-
-static int es1371_open_dac(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- struct list_head *list;
- struct es1371_state *s;
-
- for (list = devs.next; ; list = list->next) {
- if (list == &devs)
- return -ENODEV;
- s = list_entry(list, struct es1371_state, devs);
- if (!((s->dev_dac ^ minor) & ~0xf))
- break;
- }
- VALIDATE_STATE(s);
- /* we allow opening with O_RDWR, most programs do it although they will only write */
-#if 0
- if (file->f_mode & FMODE_READ)
- return -EPERM;
-#endif
- if (!(file->f_mode & FMODE_WRITE))
- return -EINVAL;
- file->private_data = s;
- /* wait for device to become free */
- mutex_lock(&s->open_mutex);
- while (s->open_mode & FMODE_DAC) {
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&s->open_mutex);
- return -EBUSY;
- }
- add_wait_queue(&s->open_wait, &wait);
- __set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&s->open_mutex);
- schedule();
- remove_wait_queue(&s->open_wait, &wait);
- set_current_state(TASK_RUNNING);
- if (signal_pending(current))
- return -ERESTARTSYS;
- mutex_lock(&s->open_mutex);
- }
- s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
- s->dma_dac1.enabled = 1;
- set_dac1_rate(s, 8000);
- spin_lock_irqsave(&s->lock, flags);
- s->sctrl &= ~SCTRL_P1FMT;
- if ((minor & 0xf) == SND_DEV_DSP16)
- s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P1FMT;
- else
- s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P1FMT;
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- spin_unlock_irqrestore(&s->lock, flags);
- s->open_mode |= FMODE_DAC;
- mutex_unlock(&s->open_mutex);
- return nonseekable_open(inode, file);
-}
-
-static int es1371_release_dac(struct inode *inode, struct file *file)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
-
- VALIDATE_STATE(s);
- lock_kernel();
- drain_dac1(s, file->f_flags & O_NONBLOCK);
- mutex_lock(&s->open_mutex);
- stop_dac1(s);
- dealloc_dmabuf(s, &s->dma_dac1);
- s->open_mode &= ~FMODE_DAC;
- mutex_unlock(&s->open_mutex);
- wake_up(&s->open_wait);
- unlock_kernel();
- return 0;
-}
-
-static /*const*/ struct file_operations es1371_dac_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = es1371_write_dac,
- .poll = es1371_poll_dac,
- .ioctl = es1371_ioctl_dac,
- .mmap = es1371_mmap_dac,
- .open = es1371_open_dac,
- .release = es1371_release_dac,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret;
- unsigned long flags;
- unsigned ptr;
- int cnt;
-
- VALIDATE_STATE(s);
- if (!access_ok(VERIFY_WRITE, buffer, count))
- return -EFAULT;
- if (count == 0)
- return 0;
- ret = 0;
- add_wait_queue(&s->midi.iwait, &wait);
- while (count > 0) {
- spin_lock_irqsave(&s->lock, flags);
- ptr = s->midi.ird;
- cnt = MIDIINBUF - ptr;
- if (s->midi.icnt < cnt)
- cnt = s->midi.icnt;
- if (cnt <= 0)
- __set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irqrestore(&s->lock, flags);
- if (cnt > count)
- cnt = count;
- if (cnt <= 0) {
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- schedule();
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
- continue;
- }
- if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
- ptr = (ptr + cnt) % MIDIINBUF;
- spin_lock_irqsave(&s->lock, flags);
- s->midi.ird = ptr;
- s->midi.icnt -= cnt;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= cnt;
- buffer += cnt;
- ret += cnt;
- break;
- }
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&s->midi.iwait, &wait);
- return ret;
-}
-
-static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- ssize_t ret;
- unsigned long flags;
- unsigned ptr;
- int cnt;
-
- VALIDATE_STATE(s);
- if (!access_ok(VERIFY_READ, buffer, count))
- return -EFAULT;
- if (count == 0)
- return 0;
- ret = 0;
- add_wait_queue(&s->midi.owait, &wait);
- while (count > 0) {
- spin_lock_irqsave(&s->lock, flags);
- ptr = s->midi.owr;
- cnt = MIDIOUTBUF - ptr;
- if (s->midi.ocnt + cnt > MIDIOUTBUF)
- cnt = MIDIOUTBUF - s->midi.ocnt;
- if (cnt <= 0) {
- __set_current_state(TASK_INTERRUPTIBLE);
- es1371_handle_midi(s);
- }
- spin_unlock_irqrestore(&s->lock, flags);
- if (cnt > count)
- cnt = count;
- if (cnt <= 0) {
- if (file->f_flags & O_NONBLOCK) {
- if (!ret)
- ret = -EAGAIN;
- break;
- }
- schedule();
- if (signal_pending(current)) {
- if (!ret)
- ret = -ERESTARTSYS;
- break;
- }
- continue;
- }
- if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
- ptr = (ptr + cnt) % MIDIOUTBUF;
- spin_lock_irqsave(&s->lock, flags);
- s->midi.owr = ptr;
- s->midi.ocnt += cnt;
- spin_unlock_irqrestore(&s->lock, flags);
- count -= cnt;
- buffer += cnt;
- ret += cnt;
- spin_lock_irqsave(&s->lock, flags);
- es1371_handle_midi(s);
- spin_unlock_irqrestore(&s->lock, flags);
- }
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&s->midi.owait, &wait);
- return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1371_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- unsigned long flags;
- unsigned int mask = 0;
-
- VALIDATE_STATE(s);
- if (file->f_mode & FMODE_WRITE)
- poll_wait(file, &s->midi.owait, wait);
- if (file->f_mode & FMODE_READ)
- poll_wait(file, &s->midi.iwait, wait);
- spin_lock_irqsave(&s->lock, flags);
- if (file->f_mode & FMODE_READ) {
- if (s->midi.icnt > 0)
- mask |= POLLIN | POLLRDNORM;
- }
- if (file->f_mode & FMODE_WRITE) {
- if (s->midi.ocnt < MIDIOUTBUF)
- mask |= POLLOUT | POLLWRNORM;
- }
- spin_unlock_irqrestore(&s->lock, flags);
- return mask;
-}
-
-static int es1371_midi_open(struct inode *inode, struct file *file)
-{
- int minor = iminor(inode);
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- struct list_head *list;
- struct es1371_state *s;
-
- for (list = devs.next; ; list = list->next) {
- if (list == &devs)
- return -ENODEV;
- s = list_entry(list, struct es1371_state, devs);
- if (s->dev_midi == minor)
- break;
- }
- VALIDATE_STATE(s);
- file->private_data = s;
- /* wait for device to become free */
- mutex_lock(&s->open_mutex);
- while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
- if (file->f_flags & O_NONBLOCK) {
- mutex_unlock(&s->open_mutex);
- return -EBUSY;
- }
- add_wait_queue(&s->open_wait, &wait);
- __set_current_state(TASK_INTERRUPTIBLE);
- mutex_unlock(&s->open_mutex);
- schedule();
- remove_wait_queue(&s->open_wait, &wait);
- set_current_state(TASK_RUNNING);
- if (signal_pending(current))
- return -ERESTARTSYS;
- mutex_lock(&s->open_mutex);
- }
- spin_lock_irqsave(&s->lock, flags);
- if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
- s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
- s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
- outb(UCTRL_CNTRL_SWR, s->io+ES1371_REG_UART_CONTROL);
- outb(0, s->io+ES1371_REG_UART_CONTROL);
- outb(0, s->io+ES1371_REG_UART_TEST);
- }
- if (file->f_mode & FMODE_READ) {
- s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
- }
- if (file->f_mode & FMODE_WRITE) {
- s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
- }
- s->ctrl |= CTRL_UART_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- es1371_handle_midi(s);
- spin_unlock_irqrestore(&s->lock, flags);
- s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
- mutex_unlock(&s->open_mutex);
- return nonseekable_open(inode, file);
-}
-
-static int es1371_midi_release(struct inode *inode, struct file *file)
-{
- struct es1371_state *s = (struct es1371_state *)file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- unsigned count, tmo;
-
- VALIDATE_STATE(s);
- lock_kernel();
- if (file->f_mode & FMODE_WRITE) {
- add_wait_queue(&s->midi.owait, &wait);
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irqsave(&s->lock, flags);
- count = s->midi.ocnt;
- spin_unlock_irqrestore(&s->lock, flags);
- if (count <= 0)
- break;
- if (signal_pending(current))
- break;
- if (file->f_flags & O_NONBLOCK)
- break;
- tmo = (count * HZ) / 3100;
- if (!schedule_timeout(tmo ? : 1) && tmo)
- printk(KERN_DEBUG PFX "midi timed out??\n");
- }
- remove_wait_queue(&s->midi.owait, &wait);
- set_current_state(TASK_RUNNING);
- }
- mutex_lock(&s->open_mutex);
- s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
- spin_lock_irqsave(&s->lock, flags);
- if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
- s->ctrl &= ~CTRL_UART_EN;
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- }
- spin_unlock_irqrestore(&s->lock, flags);
- mutex_unlock(&s->open_mutex);
- wake_up(&s->open_wait);
- unlock_kernel();
- return 0;
-}
-
-static /*const*/ struct file_operations es1371_midi_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = es1371_midi_read,
- .write = es1371_midi_write,
- .poll = es1371_midi_poll,
- .open = es1371_midi_open,
- .release = es1371_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef ES1371_DEBUG
-static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, int *eof, void *data)
-{
- struct es1371_state *s;
- int cnt, len = 0;
-
- if (list_empty(&devs))
- return 0;
- s = list_entry(devs.next, struct es1371_state, devs);
- /* print out header */
- len += sprintf(buf + len, "\t\tCreative ES137x Debug Dump-o-matic\n");
-
- /* print out CODEC state */
- len += sprintf (buf + len, "AC97 CODEC state\n");
- for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
- len+= sprintf (buf + len, "reg:0x%02x val:0x%04x\n", cnt, rdcodec(s->codec, cnt));
-
- if (fpos >=len){
- *start = buf;
- *eof =1;
- return 0;
- }
- *start = buf + fpos;
- if ((len -= fpos) > length)
- return length;
- *eof =1;
- return len;
-
-}
-#endif /* ES1371_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int spdif[NR_DEVICE];
-static int nomix[NR_DEVICE];
-static int amplifier[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(spdif, bool, NULL, 0);
-MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
-module_param_array(nomix, bool, NULL, 0);
-MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output");
-module_param_array(amplifier, bool, NULL, 0);
-MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabling (many laptops)");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
- int mixch;
- int vol;
-} initvol[] __devinitdata = {
- { SOUND_MIXER_WRITE_LINE, 0x4040 },
- { SOUND_MIXER_WRITE_CD, 0x4040 },
- { MIXER_WRITE(SOUND_MIXER_VIDEO), 0x4040 },
- { SOUND_MIXER_WRITE_LINE1, 0x4040 },
- { SOUND_MIXER_WRITE_PCM, 0x4040 },
- { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
- { MIXER_WRITE(SOUND_MIXER_PHONEOUT), 0x4040 },
- { SOUND_MIXER_WRITE_OGAIN, 0x4040 },
- { MIXER_WRITE(SOUND_MIXER_PHONEIN), 0x4040 },
- { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
- { SOUND_MIXER_WRITE_MIC, 0x4040 },
- { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
- { SOUND_MIXER_WRITE_IGAIN, 0x4040 }
-};
-
-static struct
-{
- short svid, sdid;
-} amplifier_needed[] =
-{
- { 0x107B, 0x2150 }, /* Gateway Solo 2150 */
- { 0x13BD, 0x100C }, /* Mebius PC-MJ100V */
- { 0x1102, 0x5938 }, /* Targa Xtender 300 */
- { 0x1102, 0x8938 }, /* IPC notebook */
- { PCI_ANY_ID, PCI_ANY_ID }
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit es1371_register_gameport(struct es1371_state *s)
-{
- struct gameport *gp;
- int gpio;
-
- for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
- if (request_region(gpio, JOY_EXTENT, "es1371"))
- break;
-
- if (gpio < 0x200) {
- printk(KERN_ERR PFX "no free joystick address found\n");
- return -EBUSY;
- }
-
- s->gameport = gp = gameport_allocate_port();
- if (!gp) {
- printk(KERN_ERR PFX "can not allocate memory for gameport\n");
- release_region(gpio, JOY_EXTENT);
- return -ENOMEM;
- }
-
- gameport_set_name(gp, "ESS1371 Gameport");
- gameport_set_phys(gp, "isa%04x/gameport0", gpio);
- gp->dev.parent = &s->dev->dev;
- gp->io = gpio;
-
- s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
- outl(s->ctrl, s->io + ES1371_REG_CONTROL);
-
- gameport_register_port(gp);
-
- return 0;
-}
-
-static inline void es1371_unregister_gameport(struct es1371_state *s)
-{
- if (s->gameport) {
- int gpio = s->gameport->io;
- gameport_unregister_port(s->gameport);
- release_region(gpio, JOY_EXTENT);
-
- }
-}
-
-#else
-static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; }
-static inline void es1371_unregister_gameport(struct es1371_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-
-static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
- struct es1371_state *s;
- mm_segment_t fs;
- int i, val, res = -1;
- int idx;
- unsigned long tmo;
- signed long tmo2;
- unsigned int cssr;
-
- if ((res=pci_enable_device(pcidev)))
- return res;
-
- if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO))
- return -ENODEV;
- if (pcidev->irq == 0)
- return -ENODEV;
- i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
- if (i) {
- printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n");
- return i;
- }
- if (!(s = kzalloc(sizeof(struct es1371_state), GFP_KERNEL))) {
- printk(KERN_WARNING PFX "out of memory\n");
- return -ENOMEM;
- }
-
- s->codec = ac97_alloc_codec();
- if(s->codec == NULL)
- goto err_codec;
-
- init_waitqueue_head(&s->dma_adc.wait);
- init_waitqueue_head(&s->dma_dac1.wait);
- init_waitqueue_head(&s->dma_dac2.wait);
- init_waitqueue_head(&s->open_wait);
- init_waitqueue_head(&s->midi.iwait);
- init_waitqueue_head(&s->midi.owait);
- mutex_init(&s->open_mutex);
- spin_lock_init(&s->lock);
- s->magic = ES1371_MAGIC;
- s->dev = pcidev;
- s->io = pci_resource_start(pcidev, 0);
- s->irq = pcidev->irq;
- s->vendor = pcidev->vendor;
- s->device = pcidev->device;
- s->rev = pcidev->revision;
- s->codec->private_data = s;
- s->codec->id = 0;
- s->codec->codec_read = rdcodec;
- s->codec->codec_write = wrcodec;
- printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
- s->vendor, s->device, s->rev);
- if (!request_region(s->io, ES1371_EXTENT, "es1371")) {
- printk(KERN_ERR PFX "io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1);
- res = -EBUSY;
- goto err_region;
- }
- if ((res=request_irq(s->irq, es1371_interrupt, IRQF_SHARED, "es1371",s))) {
- printk(KERN_ERR PFX "irq %u in use\n", s->irq);
- goto err_irq;
- }
- printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n",
- s->rev, s->io, s->irq);
- /* register devices */
- if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0)
- goto err_dev1;
- if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1))) < 0)
- goto err_dev2;
- if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0)
- goto err_dev3;
- if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)))<0 )
- goto err_dev4;
-#ifdef ES1371_DEBUG
- /* initialize the debug proc device */
- s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL);
-#endif /* ES1371_DEBUG */
-
- /* initialize codec registers */
- s->ctrl = 0;
-
- /* Check amplifier requirements */
-
- if (amplifier[devindex])
- s->ctrl |= CTRL_GPIO_OUT0;
- else for(idx = 0; amplifier_needed[idx].svid != PCI_ANY_ID; idx++)
- {
- if(pcidev->subsystem_vendor == amplifier_needed[idx].svid &&
- pcidev->subsystem_device == amplifier_needed[idx].sdid)
- {
- s->ctrl |= CTRL_GPIO_OUT0; /* turn internal amplifier on */
- printk(KERN_INFO PFX "Enabling internal amplifier.\n");
- }
- }
-
- s->sctrl = 0;
- cssr = 0;
- s->spdif_volume = -1;
- /* check to see if s/pdif mode is being requested */
- if (spdif[devindex]) {
- if (s->rev >= 4) {
- printk(KERN_INFO PFX "enabling S/PDIF output\n");
- s->spdif_volume = 0;
- cssr |= STAT_EN_SPDIF;
- s->ctrl |= CTRL_SPDIFEN_B;
- if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */
- s->ctrl |= CTRL_RECEN_B;
- } else {
- printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev);
- }
- }
- /* initialize the chips */
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
- outl(LEGACY_JFAST, s->io+ES1371_REG_LEGACY);
- pci_set_master(pcidev); /* enable bus mastering */
- /* if we are a 5880 turn on the AC97 */
- if (s->vendor == PCI_VENDOR_ID_ENSONIQ &&
- ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev >= CT5880REV_CT5880_C) ||
- (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) ||
- (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) {
- cssr |= CSTAT_5880_AC97_RST;
- outl(cssr, s->io+ES1371_REG_STATUS);
- /* need to delay around 20ms(bleech) to give
- some CODECs enough time to wakeup */
- tmo = jiffies + (HZ / 50) + 1;
- for (;;) {
- tmo2 = tmo - jiffies;
- if (tmo2 <= 0)
- break;
- schedule_timeout(tmo2);
- }
- }
- /* AC97 warm reset to start the bitclk */
- outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL);
- udelay(2);
- outl(s->ctrl, s->io+ES1371_REG_CONTROL);
- /* init the sample rate converter */
- src_init(s);
- /* codec init */
- if (!ac97_probe_codec(s->codec)) {
- res = -ENODEV;
- goto err_gp;
- }
- /* set default values */
-
- fs = get_fs();
- set_fs(KERNEL_DS);
- val = SOUND_MASK_LINE;
- mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
- for (i = 0; i < ARRAY_SIZE(initvol); i++) {
- val = initvol[i].vol;
- mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val);
- }
- /* mute master and PCM when in S/PDIF mode */
- if (s->spdif_volume != -1) {
- val = 0x0000;
- s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
- s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
- }
- set_fs(fs);
- /* turn on S/PDIF output driver if requested */
- outl(cssr, s->io+ES1371_REG_STATUS);
-
- es1371_register_gameport(s);
-
- /* store it in the driver field */
- pci_set_drvdata(pcidev, s);
- /* put it into driver list */
- list_add_tail(&s->devs, &devs);
- /* increment devindex */
- if (devindex < NR_DEVICE-1)
- devindex++;
- return 0;
-
- err_gp:
-#ifdef ES1371_DEBUG
- if (s->ps)
- remove_proc_entry("es1371", NULL);
-#endif
- unregister_sound_midi(s->dev_midi);
- err_dev4:
- unregister_sound_dsp(s->dev_dac);
- err_dev3:
- unregister_sound_mixer(s->codec->dev_mixer);
- err_dev2:
- unregister_sound_dsp(s->dev_audio);
- err_dev1:
- printk(KERN_ERR PFX "cannot register misc device\n");
- free_irq(s->irq, s);
- err_irq:
- release_region(s->io, ES1371_EXTENT);
- err_region:
- err_codec:
- ac97_release_codec(s->codec);
- kfree(s);
- return res;
-}
-
-static void __devexit es1371_remove(struct pci_dev *dev)
-{
- struct es1371_state *s = pci_get_drvdata(dev);
-
- if (!s)
- return;
- list_del(&s->devs);
-#ifdef ES1371_DEBUG
- if (s->ps)
- remove_proc_entry("es1371", NULL);
-#endif /* ES1371_DEBUG */
- outl(0, s->io+ES1371_REG_CONTROL); /* switch everything off */
- outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
- synchronize_irq(s->irq);
- free_irq(s->irq, s);
- es1371_unregister_gameport(s);
- release_region(s->io, ES1371_EXTENT);
- unregister_sound_dsp(s->dev_audio);
- unregister_sound_mixer(s->codec->dev_mixer);
- unregister_sound_dsp(s->dev_dac);
- unregister_sound_midi(s->dev_midi);
- ac97_release_codec(s->codec);
- kfree(s);
- pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
- { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_CT5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { PCI_VENDOR_ID_ECTIVA, PCI_DEVICE_ID_ECTIVA_EV1938, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver es1371_driver = {
- .name = "es1371",
- .id_table = id_table,
- .probe = es1371_probe,
- .remove = __devexit_p(es1371_remove),
-};
-
-static int __init init_es1371(void)
-{
- printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n");
- return pci_register_driver(&es1371_driver);
-}
-
-static void __exit cleanup_es1371(void)
-{
- printk(KERN_INFO PFX "unloading\n");
- pci_unregister_driver(&es1371_driver);
-}
-
-module_init(init_es1371);
-module_exit(cleanup_es1371);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: es1371=[spdif,[nomix,[amplifier]]] */
-
-static int __init es1371_setup(char *str)
-{
- static unsigned __initdata nr_dev = 0;
-
- if (nr_dev >= NR_DEVICE)
- return 0;
-
- (void)
- ((get_option(&str, &spdif[nr_dev]) == 2)
- && (get_option(&str, &nomix[nr_dev]) == 2)
- && (get_option(&str, &amplifier[nr_dev])));
-
- nr_dev++;
- return 1;
-}
-
-__setup("es1371=", es1371_setup);
-
-#endif /* MODULE */
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index c6b44102aa5..356bf21a150 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -170,14 +170,14 @@ config SND_CA0106
will be called snd-ca0106.
config SND_CMIPCI
- tristate "C-Media 8738, 8338"
+ tristate "C-Media 8338, 8738, 8768, 8770"
depends on SND
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
help
- If you want to use soundcards based on C-Media CMI8338 or CMI8738
- chips, say Y here and read
+ If you want to use soundcards based on C-Media CMI8338, CMI8738,
+ CMI8768 or CMI8770 chips, say Y here and read
<file:Documentation/sound/alsa/CMIPCI.txt>.
To compile this driver as a module, choose M here: the module
@@ -500,6 +500,103 @@ config SND_HDA_INTEL
To compile this driver as a module, choose M here: the module
will be called snd-hda-intel.
+config SND_HDA_HWDEP
+ bool "Build hwdep interface for HD-audio driver"
+ depends on SND_HDA_INTEL
+ select SND_HWDEP
+ help
+ Say Y here to build a hwdep interface for HD-audio driver.
+ This interface can be used for out-of-band communication
+ with codecs for debugging purposes.
+
+config SND_HDA_CODEC_REALTEK
+ bool "Build Realtek HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include Realtek HD-audio codec support in
+ snd-hda-intel driver, such as ALC880.
+
+config SND_HDA_CODEC_ANALOG
+ bool "Build Analog Device HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include Analog Device HD-audio codec support in
+ snd-hda-intel driver, such as AD1986A.
+
+config SND_HDA_CODEC_SIGMATEL
+ bool "Build IDT/Sigmatel HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include IDT (Sigmatel) HD-audio codec support in
+ snd-hda-intel driver, such as STAC9200.
+
+config SND_HDA_CODEC_VIA
+ bool "Build VIA HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include VIA HD-audio codec support in
+ snd-hda-intel driver, such as VT1708.
+
+config SND_HDA_CODEC_ATIHDMI
+ bool "Build ATI HDMI HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include ATI HDMI HD-audio codec support in
+ snd-hda-intel driver, such as ATI RS600 HDMI.
+
+config SND_HDA_CODEC_CONEXANT
+ bool "Build Conexant HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include Conexant HD-audio codec support in
+ snd-hda-intel driver, such as CX20549.
+
+config SND_HDA_CODEC_CMEDIA
+ bool "Build C-Media HD-audio codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include C-Media HD-audio codec support in
+ snd-hda-intel driver, such as CMI9880.
+
+config SND_HDA_CODEC_SI3054
+ bool "Build Silicon Labs 3054 HD-modem codec support"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to include Silicon Labs 3054 HD-modem codec
+ (and compatibles) support in snd-hda-intel driver.
+
+config SND_HDA_GENERIC
+ bool "Enable generic HD-audio codec parser"
+ depends on SND_HDA_INTEL
+ default y
+ help
+ Say Y here to enable the generic HD-audio codec parser
+ in snd-hda-intel driver.
+
+config SND_HDA_POWER_SAVE
+ bool "Aggressive power-saving on HD-audio"
+ depends on SND_HDA_INTEL && EXPERIMENTAL
+ help
+ Say Y here to enable more aggressive power-saving mode on
+ HD-audio driver. The power-saving timeout can be configured
+ via power_save option or over sysfs on-the-fly.
+
+config SND_HDA_POWER_SAVE_DEFAULT
+ int "Default time-out for HD-audio power-save mode"
+ depends on SND_HDA_POWER_SAVE
+ default 0
+ help
+ The default time-out value in seconds for HD-audio automatic
+ power-save mode. 0 means to disable the power-save mode.
+
config SND_HDSP
tristate "RME Hammerfall DSP Audio"
depends on SND
@@ -799,4 +896,12 @@ config SND_AC97_POWER_SAVE
snd-ac97-codec driver. You can toggle it dynamically over
sysfs, too.
+config SND_AC97_POWER_SAVE_DEFAULT
+ int "Default time-out for AC97 power-save mode"
+ depends on SND_AC97_POWER_SAVE
+ default 0
+ help
+ The default time-out value in seconds for AC97 automatic
+ power-save mode. 0 means to disable the power-save mode.
+
endmenu
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index cd76e0293d0..09ddc82eeca 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ad1889-objs := ad1889.o
diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile
index f5d471896b9..0be48b1a22d 100644
--- a/sound/pci/ac97/Makefile
+++ b/sound/pci/ac97/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index bbed644bf9c..6a9966df0cc 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
@@ -39,7 +39,7 @@
#include "ac97_patch.c"
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
MODULE_LICENSE("GPL");
@@ -49,7 +49,7 @@ module_param(enable_loopback, bool, 0444);
MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control");
#ifdef CONFIG_SND_AC97_POWER_SAVE
-static int power_save;
+static int power_save = CONFIG_SND_AC97_POWER_SAVE_DEFAULT;
module_param(power_save, bool, 0644);
MODULE_PARM_DESC(power_save, "Enable AC97 power-saving control");
#endif
@@ -176,7 +176,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL},
{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
-{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL },
+{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL },
{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL },
{ 0x83847600, 0xffffffff, "STAC9700,83,84", patch_sigmatel_stac9700, NULL },
@@ -779,6 +779,12 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_
change |= snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC,
AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
v);
+ } else if (ac97->id == AC97_ID_YMF743) {
+ change |= snd_ac97_update_bits_nolock(ac97,
+ AC97_YMF7X3_DIT_CTRL,
+ 0xff38,
+ ((val << 4) & 0xff00) |
+ ((val << 2) & 0x0038));
} else {
unsigned short extst = snd_ac97_read_cache(ac97, AC97_EXTENDED_STATUS);
snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */
@@ -1375,7 +1381,8 @@ static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
for (idx = 0; idx < 2; idx++) {
if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_tone[idx], ac97))) < 0)
return err;
- if (ac97->id == AC97_ID_YMF753) {
+ if (ac97->id == AC97_ID_YMF743 ||
+ ac97->id == AC97_ID_YMF753) {
kctl->private_value &= ~(0xff << 16);
kctl->private_value |= 7 << 16;
}
@@ -2036,11 +2043,12 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
else {
udelay(50);
if (ac97->scaps & AC97_SCAP_SKIP_AUDIO)
- err = ac97_reset_wait(ac97, HZ/2, 1);
+ err = ac97_reset_wait(ac97, msecs_to_jiffies(500), 1);
else {
- err = ac97_reset_wait(ac97, HZ/2, 0);
+ err = ac97_reset_wait(ac97, msecs_to_jiffies(500), 0);
if (err < 0)
- err = ac97_reset_wait(ac97, HZ/2, 1);
+ err = ac97_reset_wait(ac97,
+ msecs_to_jiffies(500), 1);
}
if (err < 0) {
snd_printk(KERN_WARNING "AC'97 %d does not respond - RESET\n", ac97->num);
@@ -2104,7 +2112,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
}
/* nothing should be in powerdown mode */
snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
- end_time = jiffies + (HZ / 10);
+ end_time = jiffies + msecs_to_jiffies(100);
do {
if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
goto __ready_ok;
@@ -2136,7 +2144,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
udelay(100);
/* nothing should be in powerdown mode */
snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
- end_time = jiffies + (HZ / 10);
+ end_time = jiffies + msecs_to_jiffies(100);
do {
if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
goto __ready_ok;
@@ -2354,7 +2362,8 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
* (for avoiding loud click noises for many (OSS) apps
* that open/close frequently)
*/
- schedule_delayed_work(&ac97->power_work, HZ*2);
+ schedule_delayed_work(&ac97->power_work,
+ msecs_to_jiffies(2000));
else {
cancel_delayed_work(&ac97->power_work);
update_power_regs(ac97);
@@ -2436,7 +2445,7 @@ EXPORT_SYMBOL(snd_ac97_suspend);
/*
* restore ac97 status
*/
-void snd_ac97_restore_status(struct snd_ac97 *ac97)
+static void snd_ac97_restore_status(struct snd_ac97 *ac97)
{
int i;
@@ -2457,7 +2466,7 @@ void snd_ac97_restore_status(struct snd_ac97 *ac97)
/*
* restore IEC958 status
*/
-void snd_ac97_restore_iec958(struct snd_ac97 *ac97)
+static void snd_ac97_restore_iec958(struct snd_ac97 *ac97)
{
if (ac97->ext_id & AC97_EI_SPDIF) {
if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
@@ -2494,7 +2503,10 @@ void snd_ac97_resume(struct snd_ac97 *ac97)
snd_ac97_write(ac97, AC97_POWERDOWN, 0);
if (! (ac97->flags & AC97_DEFAULT_POWER_OFF)) {
- snd_ac97_write(ac97, AC97_RESET, 0);
+ if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO))
+ snd_ac97_write(ac97, AC97_RESET, 0);
+ else if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM))
+ snd_ac97_write(ac97, AC97_EXTENDED_MID, 0);
udelay(100);
snd_ac97_write(ac97, AC97_POWERDOWN, 0);
}
diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
index 6d73514dc49..c129492c82b 100644
--- a/sound/pci/ac97/ac97_id.h
+++ b/sound/pci/ac97/ac97_id.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
@@ -54,6 +54,7 @@
#define AC97_ID_ALC658 0x414c4780
#define AC97_ID_ALC658D 0x414c4781
#define AC97_ID_ALC850 0x414c4790
+#define AC97_ID_YMF743 0x594d4800
#define AC97_ID_YMF753 0x594d4803
#define AC97_ID_VT1616 0x49434551
#define AC97_ID_CM9738 0x434d4941
diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
index 78745c5c6df..c276a5e3f7a 100644
--- a/sound/pci/ac97/ac97_local.h
+++ b/sound/pci/ac97/ac97_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 581ebba4d1a..98c8b727b62 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
@@ -204,9 +204,13 @@ static inline int is_shared_micin(struct snd_ac97 *ac97)
/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
+/* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
-/* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */
-static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+/* It is possible to indicate to the Yamaha YMF7x3 the type of
+ speakers being used. */
+
+static int snd_ac97_ymf7x3_info_speaker(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
static char *texts[3] = {
"Standard", "Small", "Smaller"
@@ -221,12 +225,13 @@ static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct sn
return 0;
}
-static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_ymf7x3_get_speaker(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
unsigned short val;
- val = ac97->regs[AC97_YMF753_3D_MODE_SEL];
+ val = ac97->regs[AC97_YMF7X3_3D_MODE_SEL];
val = (val >> 10) & 3;
if (val > 0) /* 0 = invalid */
val--;
@@ -234,7 +239,8 @@ static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd
return 0;
}
-static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_ymf7x3_put_speaker(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
unsigned short val;
@@ -242,20 +248,22 @@ static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd
if (ucontrol->value.enumerated.item[0] > 2)
return -EINVAL;
val = (ucontrol->value.enumerated.item[0] + 1) << 10;
- return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val);
+ return snd_ac97_update(ac97, AC97_YMF7X3_3D_MODE_SEL, val);
}
-static const struct snd_kcontrol_new snd_ac97_ymf753_controls_speaker =
+static const struct snd_kcontrol_new snd_ac97_ymf7x3_controls_speaker =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "3D Control - Speaker",
- .info = snd_ac97_ymf753_info_speaker,
- .get = snd_ac97_ymf753_get_speaker,
- .put = snd_ac97_ymf753_put_speaker,
+ .info = snd_ac97_ymf7x3_info_speaker,
+ .get = snd_ac97_ymf7x3_get_speaker,
+ .put = snd_ac97_ymf7x3_put_speaker,
};
-/* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */
-static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+/* It is possible to indicate to the Yamaha YMF7x3 the source to
+ direct to the S/PDIF output. */
+static int snd_ac97_ymf7x3_spdif_source_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
{
static char *texts[2] = { "AC-Link", "A/D Converter" };
@@ -268,17 +276,19 @@ static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, stru
return 0;
}
-static int snd_ac97_ymf753_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_ymf7x3_spdif_source_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
unsigned short val;
- val = ac97->regs[AC97_YMF753_DIT_CTRL2];
+ val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
ucontrol->value.enumerated.item[0] = (val >> 1) & 1;
return 0;
}
-static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_ymf7x3_spdif_source_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
unsigned short val;
@@ -286,7 +296,75 @@ static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struc
if (ucontrol->value.enumerated.item[0] > 1)
return -EINVAL;
val = ucontrol->value.enumerated.item[0] << 1;
- return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0002, val);
+ return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0002, val);
+}
+
+static int patch_yamaha_ymf7x3_3d(struct snd_ac97 *ac97)
+{
+ struct snd_kcontrol *kctl;
+ int err;
+
+ kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97);
+ err = snd_ctl_add(ac97->bus->card, kctl);
+ if (err < 0)
+ return err;
+ strcpy(kctl->id.name, "3D Control - Wide");
+ kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
+ snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
+ err = snd_ctl_add(ac97->bus->card,
+ snd_ac97_cnew(&snd_ac97_ymf7x3_controls_speaker,
+ ac97));
+ if (err < 0)
+ return err;
+ snd_ac97_write_cache(ac97, AC97_YMF7X3_3D_MODE_SEL, 0x0c00);
+ return 0;
+}
+
+static const struct snd_kcontrol_new snd_ac97_yamaha_ymf743_controls_spdif[3] =
+{
+ AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
+ AC97_YMF7X3_DIT_CTRL, 0, 1, 0),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Source",
+ .info = snd_ac97_ymf7x3_spdif_source_info,
+ .get = snd_ac97_ymf7x3_spdif_source_get,
+ .put = snd_ac97_ymf7x3_spdif_source_put,
+ },
+ AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
+ AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
+};
+
+static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
+{
+ int err;
+
+ err = patch_build_controls(ac97, &snd_ac97_controls_spdif[0], 3);
+ if (err < 0)
+ return err;
+ err = patch_build_controls(ac97,
+ snd_ac97_yamaha_ymf743_controls_spdif, 3);
+ if (err < 0)
+ return err;
+ /* set default PCM S/PDIF params */
+ /* PCM audio,no copyright,no preemphasis,PCM coder,original */
+ snd_ac97_write_cache(ac97, AC97_YMF7X3_DIT_CTRL, 0xa201);
+ return 0;
+}
+
+static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
+ .build_spdif = patch_yamaha_ymf743_build_spdif,
+ .build_3d = patch_yamaha_ymf7x3_3d,
+};
+
+static int patch_yamaha_ymf743(struct snd_ac97 *ac97)
+{
+ ac97->build_ops = &patch_yamaha_ymf743_ops;
+ ac97->caps |= AC97_BC_BASS_TREBLE;
+ ac97->caps |= 0x04 << 10; /* Yamaha 3D enhancement */
+ ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
+ ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
+ return 0;
}
/* The AC'97 spec states that the S/PDIF signal is to be output at pin 48.
@@ -311,7 +389,7 @@ static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, s
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
unsigned short val;
- val = ac97->regs[AC97_YMF753_DIT_CTRL2];
+ val = ac97->regs[AC97_YMF7X3_DIT_CTRL];
ucontrol->value.enumerated.item[0] = (val & 0x0008) ? 2 : (val & 0x0020) ? 1 : 0;
return 0;
}
@@ -325,7 +403,7 @@ static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, s
return -EINVAL;
val = (ucontrol->value.enumerated.item[0] == 2) ? 0x0008 :
(ucontrol->value.enumerated.item[0] == 1) ? 0x0020 : 0;
- return snd_ac97_update_bits(ac97, AC97_YMF753_DIT_CTRL2, 0x0028, val);
+ return snd_ac97_update_bits(ac97, AC97_YMF7X3_DIT_CTRL, 0x0028, val);
/* The following can be used to direct S/PDIF output to pin 47 (EAPD).
snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
}
@@ -334,9 +412,9 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
- .info = snd_ac97_ymf753_spdif_source_info,
- .get = snd_ac97_ymf753_spdif_source_get,
- .put = snd_ac97_ymf753_spdif_source_put,
+ .info = snd_ac97_ymf7x3_spdif_source_info,
+ .get = snd_ac97_ymf7x3_spdif_source_get,
+ .put = snd_ac97_ymf7x3_spdif_source_put,
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -345,25 +423,10 @@ static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
.get = snd_ac97_ymf753_spdif_output_pin_get,
.put = snd_ac97_ymf753_spdif_output_pin_put,
},
- AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1)
+ AC97_SINGLE(SNDRV_CTL_NAME_IEC958("", NONE, NONE) "Mute",
+ AC97_YMF7X3_DIT_CTRL, 2, 1, 1)
};
-static int patch_yamaha_ymf753_3d(struct snd_ac97 * ac97)
-{
- struct snd_kcontrol *kctl;
- int err;
-
- if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
- return err;
- strcpy(kctl->id.name, "3D Control - Wide");
- kctl->private_value = AC97_SINGLE_VALUE(AC97_3D_CONTROL, 9, 7, 0);
- snd_ac97_write_cache(ac97, AC97_3D_CONTROL, 0x0000);
- if ((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_ymf753_controls_speaker, ac97))) < 0)
- return err;
- snd_ac97_write_cache(ac97, AC97_YMF753_3D_MODE_SEL, 0x0c00);
- return 0;
-}
-
static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
{
int err;
@@ -374,7 +437,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
}
static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
- .build_3d = patch_yamaha_ymf753_3d,
+ .build_3d = patch_yamaha_ymf7x3_3d,
.build_post_spdif = patch_yamaha_ymf753_post_spdif
};
@@ -1880,14 +1943,7 @@ static int patch_ad1981b(struct snd_ac97 *ac97)
return 0;
}
-static int snd_ac97_ad1888_lohpsel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ac97_ad1888_lohpsel_info snd_ctl_boolean_mono_info
static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2186,15 +2242,7 @@ static int patch_ad1985(struct snd_ac97 * ac97)
return 0;
}
-static int snd_ac97_ad1986_bool_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ac97_ad1986_bool_info snd_ctl_boolean_mono_info
static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
index fd341ce6376..9cccc27ea1b 100644
--- a/sound/pci/ac97/ac97_patch.h
+++ b/sound/pci/ac97/ac97_patch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index 4281e6d0c5b..8cbc03332b0 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index a3fdd7da911..fed4a2c3d8a 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal interface for Audio Codec '97
*
* For more details look to AC '97 component specification revision 2.2
@@ -236,10 +236,14 @@ static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffe
val = snd_ac97_read(ac97, AC97_PCM_MIC_ADC_RATE);
snd_iprintf(buffer, "PCM MIC ADC : %iHz\n", val);
}
- if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF)) {
+ if ((ext & AC97_EI_SPDIF) || (ac97->flags & AC97_CS_SPDIF) ||
+ (ac97->id == AC97_ID_YMF743)) {
if (ac97->flags & AC97_CS_SPDIF)
val = snd_ac97_read(ac97, AC97_CSR_SPDIF);
- else
+ else if (ac97->id == AC97_ID_YMF743) {
+ val = snd_ac97_read(ac97, AC97_YMF7X3_DIT_CTRL);
+ val = 0x2000 | (val & 0xff00) >> 4 | (val & 0x38) >> 2;
+ } else
val = snd_ac97_read(ac97, AC97_SPDIF);
snd_iprintf(buffer, "SPDIF Control :%s%s%s%s Category=0x%x Generation=%i%s%s%s\n",
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index dc26820a03a..722de451d15 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Universal routines for AK4531 codec
*
*
@@ -29,7 +29,7 @@
#include <sound/ak4531_codec.h>
#include <sound/tlv.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Universal routines for AK4531 codec");
MODULE_LICENSE("GPL");
diff --git a/sound/pci/ali5451/Makefile b/sound/pci/ali5451/Makefile
index 2e183159747..713459c12d2 100644
--- a/sound/pci/ali5451/Makefile
+++ b/sound/pci/ali5451/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ali5451-objs := ali5451.o
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 05b4c869694..4c2bd7adf67 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1804,15 +1804,7 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
.info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
.put = snd_ali5451_spdif_put, .private_value = value}
-static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ali5451_spdif_info snd_ctl_boolean_mono_info
static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 8fb55d3b454..1190ef366a4 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -1,7 +1,7 @@
/*
* card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
* Copyright (C) 2000 by Bart Hartgers <bart@etpmod.phys.tue.nl>,
- * Jaroslav Kysela <perex@suse.cz>
+ * Jaroslav Kysela <perex@perex.cz>
* Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
*
* Framework borrowed from Massimo Piccioni's card-als100.c.
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 5ec1b6fcd54..f70286a7364 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -232,6 +232,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
pci_disable_device(chip->pci_dev);
//FIXME: this not the right place to unregister the gameport
vortex_gameport_unregister(chip);
+ kfree(chip);
return err;
}
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 0c86a31c433..38602b85874 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -728,15 +728,7 @@ static void vortex_Eqlzr_shutdown(vortex_t * vortex)
/* ALSA interface */
/* Control interface */
-static int
-snd_vortex_eqtoggle_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_vortex_eqtoggle_info snd_ctl_boolean_mono_info
static int
snd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index c75d368ea08..8db3d3e6f7b 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of MPU-401 in UART mode
*
* Modified for the Aureal Vortex based Soundcards
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
index d3e662a1285..978b856f562 100644
--- a/sound/pci/au88x0/au88x0_synth.c
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -370,8 +370,8 @@ static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr)
while ((edx & 0x80000000) == 0) {
edx <<= 1;
eax--;
- if (eax == 0) ;
- break;
+ if (eax == 0)
+ break;
}
if (eax)
edx <<= 1;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 131952f5585..91f9e6a112f 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -147,15 +147,56 @@ MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
/* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
#define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8)
+/* Cards with configuration information */
+enum snd_bt87x_boardid {
+ SND_BT87X_BOARD_UNKNOWN,
+ SND_BT87X_BOARD_GENERIC, /* both an & dig interfaces, 32kHz */
+ SND_BT87X_BOARD_ANALOG, /* board with no external A/D */
+ SND_BT87X_BOARD_OSPREY2x0,
+ SND_BT87X_BOARD_OSPREY440,
+ SND_BT87X_BOARD_AVPHONE98,
+};
+
+/* Card configuration */
+struct snd_bt87x_board {
+ int dig_rate; /* Digital input sampling rate */
+ u32 digital_fmt; /* Register settings for digital input */
+ unsigned no_analog:1; /* No analog input */
+ unsigned no_digital:1; /* No digital input */
+};
+
+static const __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
+ [SND_BT87X_BOARD_UNKNOWN] = {
+ .dig_rate = 32000, /* just a guess */
+ },
+ [SND_BT87X_BOARD_GENERIC] = {
+ .dig_rate = 32000,
+ },
+ [SND_BT87X_BOARD_ANALOG] = {
+ .no_digital = 1,
+ },
+ [SND_BT87X_BOARD_OSPREY2x0] = {
+ .dig_rate = 44100,
+ .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT),
+ },
+ [SND_BT87X_BOARD_OSPREY440] = {
+ .dig_rate = 32000,
+ .digital_fmt = CTL_DA_LRI | (1 << CTL_DA_LRD_SHIFT),
+ .no_analog = 1,
+ },
+ [SND_BT87X_BOARD_AVPHONE98] = {
+ .dig_rate = 48000,
+ },
+};
+
struct snd_bt87x {
struct snd_card *card;
struct pci_dev *pci;
+ struct snd_bt87x_board board;
void __iomem *mmio;
int irq;
- int dig_rate;
-
spinlock_t reg_lock;
unsigned long opened;
struct snd_pcm_substream *substream;
@@ -340,30 +381,11 @@ static struct snd_pcm_hardware snd_bt87x_analog_hw = {
static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime)
{
- static struct {
- int rate;
- unsigned int bit;
- } ratebits[] = {
- {8000, SNDRV_PCM_RATE_8000},
- {11025, SNDRV_PCM_RATE_11025},
- {16000, SNDRV_PCM_RATE_16000},
- {22050, SNDRV_PCM_RATE_22050},
- {32000, SNDRV_PCM_RATE_32000},
- {44100, SNDRV_PCM_RATE_44100},
- {48000, SNDRV_PCM_RATE_48000}
- };
- int i;
-
- chip->reg_control |= CTL_DA_IOM_DA;
+ chip->reg_control |= CTL_DA_IOM_DA | CTL_A_PWRDN;
runtime->hw = snd_bt87x_digital_hw;
- runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
- for (i = 0; i < ARRAY_SIZE(ratebits); ++i)
- if (chip->dig_rate == ratebits[i].rate) {
- runtime->hw.rates = ratebits[i].bit;
- break;
- }
- runtime->hw.rate_min = chip->dig_rate;
- runtime->hw.rate_max = chip->dig_rate;
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->board.dig_rate);
+ runtime->hw.rate_min = chip->board.dig_rate;
+ runtime->hw.rate_max = chip->board.dig_rate;
return 0;
}
@@ -380,7 +402,7 @@ static int snd_bt87x_set_analog_hw(struct snd_bt87x *chip, struct snd_pcm_runtim
.rats = &analog_clock
};
- chip->reg_control &= ~CTL_DA_IOM_DA;
+ chip->reg_control &= ~(CTL_DA_IOM_DA | CTL_A_PWRDN);
runtime->hw = snd_bt87x_analog_hw;
return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&constraint_rates);
@@ -419,6 +441,11 @@ static int snd_bt87x_close(struct snd_pcm_substream *substream)
{
struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
+ spin_lock_irq(&chip->reg_lock);
+ chip->reg_control |= CTL_A_PWRDN;
+ snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
+ spin_unlock_irq(&chip->reg_lock);
+
chip->substream = NULL;
clear_bit(0, &chip->opened);
smp_mb__after_clear_bit();
@@ -569,15 +596,7 @@ static struct snd_kcontrol_new snd_bt87x_capture_volume = {
.put = snd_bt87x_capture_volume_put,
};
-static int snd_bt87x_capture_boost_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- info->count = 1;
- info->value.integer.min = 0;
- info->value.integer.max = 1;
- return 0;
-}
+#define snd_bt87x_capture_boost_info snd_ctl_boolean_mono_info
static int snd_bt87x_capture_boost_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *value)
@@ -736,61 +755,69 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
pci_resource_len(pci, 0));
if (!chip->mmio) {
- snd_bt87x_free(chip);
snd_printk(KERN_ERR "cannot remap io memory\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ goto fail;
}
- chip->reg_control = CTL_DA_ES2 | CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
+ chip->reg_control = CTL_A_PWRDN | CTL_DA_ES2 |
+ CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
chip->interrupt_mask = MY_INTERRUPTS;
snd_bt87x_writel(chip, REG_GPIO_DMA_CTL, chip->reg_control);
snd_bt87x_writel(chip, REG_INT_MASK, 0);
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
- if (request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
- "Bt87x audio", chip)) {
- snd_bt87x_free(chip);
- snd_printk(KERN_ERR "cannot grab irq\n");
- return -EBUSY;
+ err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
+ "Bt87x audio", chip);
+ if (err < 0) {
+ snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
+ goto fail;
}
chip->irq = pci->irq;
pci_set_master(pci);
synchronize_irq(chip->irq);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
- if (err < 0) {
- snd_bt87x_free(chip);
- return err;
- }
+ if (err < 0)
+ goto fail;
+
snd_card_set_dev(card, &pci->dev);
*rchip = chip;
return 0;
+
+fail:
+ snd_bt87x_free(chip);
+ return err;
}
-#define BT_DEVICE(chip, subvend, subdev, rate) \
+#define BT_DEVICE(chip, subvend, subdev, id) \
{ .vendor = PCI_VENDOR_ID_BROOKTREE, \
.device = chip, \
.subvendor = subvend, .subdevice = subdev, \
- .driver_data = rate }
+ .driver_data = SND_BT87X_BOARD_ ## id }
+/* driver_data is the card id for that device */
-/* driver_data is the default digital_rate value for that device */
static struct pci_device_id snd_bt87x_ids[] = {
/* Hauppauge WinTV series */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC),
/* Hauppauge WinTV series */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, GENERIC),
/* Viewcast Osprey 200 */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, OSPREY2x0),
/* Viewcast Osprey 440 (rate is configurable via gpio) */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, 32000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff07, OSPREY440),
/* ATI TV-Wonder */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC),
/* Leadtek Winfast tv 2000xp delux */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
/* Voodoo TV 200 */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, 32000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
/* AVerMedia Studio No. 103, 203, ...? */
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, AVPHONE98),
+ /* Prolink PixelView PV-M4900 */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1554, 0x4011, GENERIC),
+ /* Pinnacle Studio PCTV rave */
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0xbd11, 0x1200, GENERIC),
{ }
};
MODULE_DEVICE_TABLE(pci, snd_bt87x_ids);
@@ -815,7 +842,7 @@ static struct {
static struct pci_driver driver;
-/* return the rate of the card, or a negative value if it's blacklisted */
+/* return the id of the card, or a negative value if it's blacklisted */
static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
{
int i;
@@ -833,12 +860,12 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
return -EBUSY;
}
- snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default rate 32000\n",
- pci->device, pci->subsystem_vendor, pci->subsystem_device);
+ snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x\n",
+ pci->device, pci->subsystem_vendor, pci->subsystem_device);
snd_printk(KERN_DEBUG "please mail id, board name, and, "
"if it works, the correct digital_rate option to "
"<alsa-devel@alsa-project.org>\n");
- return 32000; /* default rate */
+ return SND_BT87X_BOARD_UNKNOWN;
}
static int __devinit snd_bt87x_probe(struct pci_dev *pci,
@@ -847,12 +874,16 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci,
static int dev;
struct snd_card *card;
struct snd_bt87x *chip;
- int err, rate;
+ int err;
+ enum snd_bt87x_boardid boardid;
- rate = pci_id->driver_data;
- if (! rate)
- if ((rate = snd_bt87x_detect_card(pci)) <= 0)
+ if (!pci_id->driver_data) {
+ err = snd_bt87x_detect_card(pci);
+ if (err < 0)
return -ENODEV;
+ boardid = err;
+ } else
+ boardid = pci_id->driver_data;
if (dev >= SNDRV_CARDS)
return -ENODEV;
@@ -869,27 +900,39 @@ static int __devinit snd_bt87x_probe(struct pci_dev *pci,
if (err < 0)
goto _error;
- if (digital_rate[dev] > 0)
- chip->dig_rate = digital_rate[dev];
- else
- chip->dig_rate = rate;
+ memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board));
- err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
- if (err < 0)
- goto _error;
- err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
- if (err < 0)
- goto _error;
+ if (!chip->board.no_digital) {
+ if (digital_rate[dev] > 0)
+ chip->board.dig_rate = digital_rate[dev];
- err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_volume, chip));
- if (err < 0)
- goto _error;
- err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_boost, chip));
- if (err < 0)
- goto _error;
- err = snd_ctl_add(card, snd_ctl_new1(&snd_bt87x_capture_source, chip));
- if (err < 0)
- goto _error;
+ chip->reg_control |= chip->board.digital_fmt;
+
+ err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
+ if (err < 0)
+ goto _error;
+ }
+ if (!chip->board.no_analog) {
+ err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
+ if (err < 0)
+ goto _error;
+ err = snd_ctl_add(card, snd_ctl_new1(
+ &snd_bt87x_capture_volume, chip));
+ if (err < 0)
+ goto _error;
+ err = snd_ctl_add(card, snd_ctl_new1(
+ &snd_bt87x_capture_boost, chip));
+ if (err < 0)
+ goto _error;
+ err = snd_ctl_add(card, snd_ctl_new1(
+ &snd_bt87x_capture_source, chip));
+ if (err < 0)
+ goto _error;
+ }
+ snd_printk(KERN_INFO "bt87x%d: Using board %d, %sanalog, %sdigital "
+ "(rate %d Hz)\n", dev, boardid,
+ chip->board.no_analog ? "no " : "",
+ chip->board.no_digital ? "no " : "", chip->board.dig_rate);
strcpy(card->driver, "Bt87x");
sprintf(card->shortname, "Brooktree Bt%x", pci->device);
@@ -920,8 +963,8 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
/* default entries for all Bt87x cards - it's not exported */
/* driver_data is set to 0 to call detection */
static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = {
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0),
- BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
+ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
{ }
};
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index a0420bc63f0..75da1746e75 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
* Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.21
+ * Version: 0.0.22
*
* FEATURES currently supported:
* See ca0106_main.c for features.
@@ -47,6 +47,8 @@
* Added GPIO info for SB Live 24bit.
* 0.0.21
* Implement support for Line-in capture on SB Live 24bit.
+ * 0.0.22
+ * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
*
*
* This code was initally based on code from ALSA's emu10k1x.c which is:
@@ -552,6 +554,95 @@
#define CONTROL_CENTER_LFE_CHANNEL 1
#define CONTROL_UNKNOWN_CHANNEL 2
+
+/* Based on WM8768 Datasheet Rev 4.2 page 32 */
+#define SPI_REG_MASK 0x1ff /* 16-bit SPI writes have a 7-bit address */
+#define SPI_REG_SHIFT 9 /* followed by 9 bits of data */
+
+#define SPI_LDA1_REG 0 /* digital attenuation */
+#define SPI_RDA1_REG 1
+#define SPI_LDA2_REG 4
+#define SPI_RDA2_REG 5
+#define SPI_LDA3_REG 6
+#define SPI_RDA3_REG 7
+#define SPI_LDA4_REG 13
+#define SPI_RDA4_REG 14
+#define SPI_MASTDA_REG 8
+
+#define SPI_DA_BIT_UPDATE (1<<8) /* update attenuation values */
+#define SPI_DA_BIT_0dB 0xff /* 0 dB */
+#define SPI_DA_BIT_infdB 0x00 /* inf dB attenuation (mute) */
+
+#define SPI_PL_REG 2
+#define SPI_PL_BIT_L_M (0<<5) /* left channel = mute */
+#define SPI_PL_BIT_L_L (1<<5) /* left channel = left */
+#define SPI_PL_BIT_L_R (2<<5) /* left channel = right */
+#define SPI_PL_BIT_L_C (3<<5) /* left channel = (L+R)/2 */
+#define SPI_PL_BIT_R_M (0<<7) /* right channel = mute */
+#define SPI_PL_BIT_R_L (1<<7) /* right channel = left */
+#define SPI_PL_BIT_R_R (2<<7) /* right channel = right */
+#define SPI_PL_BIT_R_C (3<<7) /* right channel = (L+R)/2 */
+#define SPI_IZD_REG 2
+#define SPI_IZD_BIT (1<<4) /* infinite zero detect */
+
+#define SPI_FMT_REG 3
+#define SPI_FMT_BIT_RJ (0<<0) /* right justified mode */
+#define SPI_FMT_BIT_LJ (1<<0) /* left justified mode */
+#define SPI_FMT_BIT_I2S (2<<0) /* I2S mode */
+#define SPI_FMT_BIT_DSP (3<<0) /* DSP Modes A or B */
+#define SPI_LRP_REG 3
+#define SPI_LRP_BIT (1<<2) /* invert LRCLK polarity */
+#define SPI_BCP_REG 3
+#define SPI_BCP_BIT (1<<3) /* invert BCLK polarity */
+#define SPI_IWL_REG 3
+#define SPI_IWL_BIT_16 (0<<4) /* 16-bit world length */
+#define SPI_IWL_BIT_20 (1<<4) /* 20-bit world length */
+#define SPI_IWL_BIT_24 (2<<4) /* 24-bit world length */
+#define SPI_IWL_BIT_32 (3<<4) /* 32-bit world length */
+
+#define SPI_MS_REG 10
+#define SPI_MS_BIT (1<<5) /* master mode */
+#define SPI_RATE_REG 10 /* only applies in master mode */
+#define SPI_RATE_BIT_128 (0<<6) /* MCLK = LRCLK * 128 */
+#define SPI_RATE_BIT_192 (1<<6)
+#define SPI_RATE_BIT_256 (2<<6)
+#define SPI_RATE_BIT_384 (3<<6)
+#define SPI_RATE_BIT_512 (4<<6)
+#define SPI_RATE_BIT_768 (5<<6)
+
+/* They really do label the bit for the 4th channel "4" and not "3" */
+#define SPI_DMUTE0_REG 9
+#define SPI_DMUTE1_REG 9
+#define SPI_DMUTE2_REG 9
+#define SPI_DMUTE4_REG 15
+#define SPI_DMUTE0_BIT (1<<3)
+#define SPI_DMUTE1_BIT (1<<4)
+#define SPI_DMUTE2_BIT (1<<5)
+#define SPI_DMUTE4_BIT (1<<2)
+
+#define SPI_PHASE0_REG 3
+#define SPI_PHASE1_REG 3
+#define SPI_PHASE2_REG 3
+#define SPI_PHASE4_REG 15
+#define SPI_PHASE0_BIT (1<<6)
+#define SPI_PHASE1_BIT (1<<7)
+#define SPI_PHASE2_BIT (1<<8)
+#define SPI_PHASE4_BIT (1<<3)
+
+#define SPI_PDWN_REG 2 /* power down all DACs */
+#define SPI_PDWN_BIT (1<<2)
+#define SPI_DACD0_REG 10 /* power down individual DACs */
+#define SPI_DACD1_REG 10
+#define SPI_DACD2_REG 10
+#define SPI_DACD4_REG 15
+#define SPI_DACD0_BIT (1<<1)
+#define SPI_DACD1_BIT (1<<2)
+#define SPI_DACD2_BIT (1<<3)
+#define SPI_DACD4_BIT (1<<0) /* datasheet error says it's 1 */
+
+#define SPI_PWRDNALL_REG 10 /* power down everything */
+#define SPI_PWRDNALL_BIT (1<<4)
+
#include "ca_midi.h"
struct snd_ca0106;
@@ -611,6 +702,8 @@ struct snd_ca0106 {
struct snd_ca_midi midi;
struct snd_ca_midi midi2;
+
+ u16 spi_dac_reg[16];
};
int snd_ca0106_mixer(struct snd_ca0106 *emu);
@@ -627,4 +720,5 @@ void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
-
+int snd_ca0106_spi_write(struct snd_ca0106 * emu,
+ unsigned int data);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index fcab8fb97e3..31d8db9f7a4 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
* Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.23
+ * Version: 0.0.25
*
* FEATURES currently supported:
* Front, Rear and Center/LFE.
@@ -79,6 +79,10 @@
* Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901
* 0.0.23
* Implement support for Line-in capture on SB Live 24bit.
+ * 0.0.24
+ * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
+ * 0.0.25
+ * Powerdown SPI DAC channels when not in use
*
* BUGS:
* Some stability problems when unloading the snd-ca0106 kernel module.
@@ -170,6 +174,15 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
static struct snd_ca0106_details ca0106_chip_details[] = {
/* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */
/* It is really just a normal SB Live 24bit. */
+ /* Tested:
+ * See ALSA bug#3251
+ */
+ { .serial = 0x10131102,
+ .name = "X-Fi Extreme Audio [SBxxxx]",
+ .gpio_type = 1,
+ .i2c_adc = 1 } ,
+ /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */
+ /* It is really just a normal SB Live 24bit. */
/*
* CTRL:CA0111-WTLF
* ADC: WM8775SEDS
@@ -261,10 +274,11 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
/* hardware definition */
static struct snd_pcm_hardware snd_ca0106_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.rates = (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_192000),
@@ -447,6 +461,19 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
kfree(runtime->private_data);
}
+static const int spi_dacd_reg[] = {
+ [PCM_FRONT_CHANNEL] = SPI_DACD4_REG,
+ [PCM_REAR_CHANNEL] = SPI_DACD0_REG,
+ [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG,
+ [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG,
+};
+static const int spi_dacd_bit[] = {
+ [PCM_FRONT_CHANNEL] = SPI_DACD4_BIT,
+ [PCM_REAR_CHANNEL] = SPI_DACD0_BIT,
+ [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_BIT,
+ [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT,
+};
+
/* open_playback callback */
static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
int channel_id)
@@ -481,6 +508,17 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
return err;
if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
return err;
+ snd_pcm_set_sync(substream);
+
+ if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) {
+ const int reg = spi_dacd_reg[channel_id];
+
+ /* Power up dac */
+ chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id];
+ err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
+ if (err < 0)
+ return err;
+ }
return 0;
}
@@ -491,6 +529,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ca0106_pcm *epcm = runtime->private_data;
chip->playback_channels[epcm->channel_id].use = 0;
+
+ if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) {
+ const int reg = spi_dacd_reg[epcm->channel_id];
+
+ /* Power down DAC */
+ chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id];
+ snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
+ }
/* FIXME: maybe zero others */
return 0;
}
@@ -809,6 +855,9 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
break;
}
snd_pcm_group_for_each_entry(s, substream) {
+ if (snd_pcm_substream_chip(s) != emu ||
+ s->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ continue;
runtime = s->runtime;
epcm = runtime->private_data;
channel = epcm->channel_id;
@@ -1214,28 +1263,23 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
return 0;
}
+#define SPI_REG(reg, value) (((reg) << SPI_REG_SHIFT) | (value))
static unsigned int spi_dac_init[] = {
- 0x00ff,
- 0x02ff,
- 0x0400,
- 0x0520,
- 0x0620, /* Set 24 bit. Was 0x0600 */
- 0x08ff,
- 0x0aff,
- 0x0cff,
- 0x0eff,
- 0x10ff,
- 0x1200,
- 0x1400,
- 0x1480,
- 0x1800,
- 0x1aff,
- 0x1cff,
- 0x1e00,
- 0x0530,
- 0x0602,
- 0x0622,
- 0x1400,
+ SPI_REG(SPI_LDA1_REG, SPI_DA_BIT_0dB), /* 0dB dig. attenuation */
+ SPI_REG(SPI_RDA1_REG, SPI_DA_BIT_0dB),
+ SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R | SPI_IZD_BIT),
+ SPI_REG(SPI_FMT_REG, SPI_FMT_BIT_I2S | SPI_IWL_BIT_24),
+ SPI_REG(SPI_LDA2_REG, SPI_DA_BIT_0dB),
+ SPI_REG(SPI_RDA2_REG, SPI_DA_BIT_0dB),
+ SPI_REG(SPI_LDA3_REG, SPI_DA_BIT_0dB),
+ SPI_REG(SPI_RDA3_REG, SPI_DA_BIT_0dB),
+ SPI_REG(SPI_MASTDA_REG, SPI_DA_BIT_0dB),
+ SPI_REG(9, 0x00),
+ SPI_REG(SPI_MS_REG, SPI_DACD0_BIT | SPI_DACD1_BIT | SPI_DACD2_BIT),
+ SPI_REG(12, 0x00),
+ SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB),
+ SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE),
+ SPI_REG(SPI_DACD4_REG, 0x00),
};
static unsigned int i2c_adc_init[][2] = {
@@ -1475,8 +1519,13 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
int size, n;
size = ARRAY_SIZE(spi_dac_init);
- for (n=0; n < size; n++)
+ for (n = 0; n < size; n++) {
+ int reg = spi_dac_init[n] >> SPI_REG_SHIFT;
+
snd_ca0106_spi_write(chip, spi_dac_init[n]);
+ if (reg < ARRAY_SIZE(chip->spi_dac_reg))
+ chip->spi_dac_reg[reg] = spi_dac_init[n];
+ }
}
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 9c3a9c8d1dc..be519a17dfa 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
* Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- * Version: 0.0.17
+ * Version: 0.0.18
*
* FEATURES currently supported:
* See ca0106_main.c for features.
@@ -39,6 +39,8 @@
* Modified Copyright message.
* 0.0.17
* Implement Mic and Line in Capture.
+ * 0.0.18
+ * Add support for mute control on SB Live 24bit (cards w/ SPI DAC)
*
* This code was initally based on code from ALSA's emu10k1x.c which is:
* Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
@@ -77,15 +79,7 @@
static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
-static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ca0106_shared_spdif_info snd_ctl_boolean_mono_info
static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -470,6 +464,42 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
return change;
}
+#define spi_mute_info snd_ctl_boolean_mono_info
+
+static int spi_mute_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
+ unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
+ unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
+
+ ucontrol->value.integer.value[0] = !(emu->spi_dac_reg[reg] & bit);
+ return 0;
+}
+
+static int spi_mute_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
+ unsigned int reg = kcontrol->private_value >> SPI_REG_SHIFT;
+ unsigned int bit = kcontrol->private_value & SPI_REG_MASK;
+ int ret;
+
+ ret = emu->spi_dac_reg[reg] & bit;
+ if (ucontrol->value.integer.value[0]) {
+ if (!ret) /* bit already cleared, do nothing */
+ return 0;
+ emu->spi_dac_reg[reg] &= ~bit;
+ } else {
+ if (ret) /* bit already set, do nothing */
+ return 0;
+ emu->spi_dac_reg[reg] |= bit;
+ }
+
+ ret = snd_ca0106_spi_write(emu, emu->spi_dac_reg[reg]);
+ return ret ? -1 : 1;
+}
+
#define CA_VOLUME(xname,chid,reg) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -562,6 +592,28 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata =
I2C_VOLUME("Aux Capture Volume", 3),
};
+#define SPI_SWITCH(xname,reg,bit) \
+{ \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+ .info = spi_mute_info, \
+ .get = spi_mute_get, \
+ .put = spi_mute_put, \
+ .private_value = (reg<<SPI_REG_SHIFT) | (bit) \
+}
+
+static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[]
+__devinitdata = {
+ SPI_SWITCH("Analog Front Playback Switch",
+ SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
+ SPI_SWITCH("Analog Rear Playback Switch",
+ SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
+ SPI_SWITCH("Analog Center/LFE Playback Switch",
+ SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
+ SPI_SWITCH("Analog Side Playback Switch",
+ SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
+};
+
static int __devinit remove_ctl(struct snd_card *card, const char *name)
{
struct snd_ctl_elem_id id;
@@ -591,9 +643,19 @@ static int __devinit rename_ctl(struct snd_card *card, const char *src, const ch
return -ENOENT;
}
+#define ADD_CTLS(emu, ctls) \
+ do { \
+ int i, err; \
+ for (i = 0; i < ARRAY_SIZE(ctls); i++) { \
+ err = snd_ctl_add(card, snd_ctl_new1(&ctls[i], emu)); \
+ if (err < 0) \
+ return err; \
+ } \
+ } while (0)
+
int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
{
- int i, err;
+ int err;
struct snd_card *card = emu->card;
char **c;
static char *ca0106_remove_ctls[] = {
@@ -640,17 +702,9 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
rename_ctl(card, c[0], c[1]);
#endif
- for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_ctls); i++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_ctls[i], emu));
- if (err < 0)
- return err;
- }
+ ADD_CTLS(emu, snd_ca0106_volume_ctls);
if (emu->details->i2c_adc == 1) {
- for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_i2c_adc_ctls); i++) {
- err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_i2c_adc_ctls[i], emu));
- if (err < 0)
- return err;
- }
+ ADD_CTLS(emu, snd_ca0106_volume_i2c_adc_ctls);
if (emu->details->gpio_type == 1)
err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
else /* gpio_type == 2 */
@@ -658,6 +712,8 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
if (err < 0)
return err;
}
+ if (emu->details->spi_dac == 1)
+ ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls);
return 0;
}
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index 2e6eab1f118..ad32eff2713 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -6,7 +6,7 @@
* Changelog:
* Implementation is based on mpu401 and emu10k1x and
* tested with ca0106.
- * mpu401: Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * mpu401: Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* emu10k1x: Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h
index b72c0933bd2..922ed3e3731 100644
--- a/sound/pci/ca0106/ca_midi.h
+++ b/sound/pci/ca0106/ca_midi.h
@@ -22,9 +22,9 @@
*
*/
-#include<linux/spinlock.h>
-#include<sound/rawmidi.h>
-#include<sound/mpu401.h>
+#include <linux/spinlock.h>
+#include <sound/rawmidi.h>
+#include <sound/mpu401.h>
#define CA_MIDI_MODE_INPUT MPU401_MODE_INPUT
#define CA_MIDI_MODE_OUTPUT MPU401_MODE_OUTPUT
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 7d3c5ee0005..6832649879c 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -95,30 +95,34 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_CHADC0 0x00000001 /* ch0, 0:playback, 1:record */
#define CM_REG_FUNCTRL1 0x04
-#define CM_ASFC_MASK 0x0000E000 /* ADC sampling frequency */
-#define CM_ASFC_SHIFT 13
-#define CM_DSFC_MASK 0x00001C00 /* DAC sampling frequency */
-#define CM_DSFC_SHIFT 10
+#define CM_DSFC_MASK 0x0000E000 /* channel 1 (DAC?) sampling frequency */
+#define CM_DSFC_SHIFT 13
+#define CM_ASFC_MASK 0x00001C00 /* channel 0 (ADC?) sampling frequency */
+#define CM_ASFC_SHIFT 10
#define CM_SPDF_1 0x00000200 /* SPDIF IN/OUT at channel B */
#define CM_SPDF_0 0x00000100 /* SPDIF OUT only channel A */
-#define CM_SPDFLOOP 0x00000080 /* ext. SPDIIF/OUT -> IN loopback */
+#define CM_SPDFLOOP 0x00000080 /* ext. SPDIIF/IN -> OUT loopback */
#define CM_SPDO2DAC 0x00000040 /* SPDIF/OUT can be heard from internal DAC */
#define CM_INTRM 0x00000020 /* master control block (MCB) interrupt enabled */
#define CM_BREQ 0x00000010 /* bus master enabled */
#define CM_VOICE_EN 0x00000008 /* legacy voice (SB16,FM) */
-#define CM_UART_EN 0x00000004 /* UART */
-#define CM_JYSTK_EN 0x00000002 /* joy stick */
+#define CM_UART_EN 0x00000004 /* legacy UART */
+#define CM_JYSTK_EN 0x00000002 /* legacy joystick */
+#define CM_ZVPORT 0x00000001 /* ZVPORT */
#define CM_REG_CHFORMAT 0x08
#define CM_CHB3D5C 0x80000000 /* 5,6 channels */
+#define CM_FMOFFSET2 0x40000000 /* initial FM PCM offset 2 when Fmute=1 */
#define CM_CHB3D 0x20000000 /* 4 channels */
#define CM_CHIP_MASK1 0x1f000000
#define CM_CHIP_037 0x01000000
-
-#define CM_SPDIF_SELECT1 0x00080000 /* for model <= 037 ? */
+#define CM_SETLAT48 0x00800000 /* set latency timer 48h */
+#define CM_EDGEIRQ 0x00400000 /* emulated edge trigger legacy IRQ */
+#define CM_SPD24SEL39 0x00200000 /* 24-bit spdif: model 039 */
#define CM_AC3EN1 0x00100000 /* enable AC3: model 037 */
+#define CM_SPDIF_SELECT1 0x00080000 /* for model <= 037 ? */
#define CM_SPD24SEL 0x00020000 /* 24bit spdif: model 037 */
/* #define CM_SPDIF_INVERSE 0x00010000 */ /* ??? */
@@ -128,35 +132,45 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_ADCBITLEN_14 0x00008000
#define CM_ADCBITLEN_13 0x0000C000
-#define CM_ADCDACLEN_MASK 0x00003000
+#define CM_ADCDACLEN_MASK 0x00003000 /* model 037 */
#define CM_ADCDACLEN_060 0x00000000
#define CM_ADCDACLEN_066 0x00001000
#define CM_ADCDACLEN_130 0x00002000
#define CM_ADCDACLEN_280 0x00003000
+#define CM_ADCDLEN_MASK 0x00003000 /* model 039 */
+#define CM_ADCDLEN_ORIGINAL 0x00000000
+#define CM_ADCDLEN_EXTRA 0x00001000
+#define CM_ADCDLEN_24K 0x00002000
+#define CM_ADCDLEN_WEIGHT 0x00003000
+
#define CM_CH1_SRATE_176K 0x00000800
+#define CM_CH1_SRATE_96K 0x00000800 /* model 055? */
#define CM_CH1_SRATE_88K 0x00000400
#define CM_CH0_SRATE_176K 0x00000200
+#define CM_CH0_SRATE_96K 0x00000200 /* model 055? */
#define CM_CH0_SRATE_88K 0x00000100
#define CM_SPDIF_INVERSE2 0x00000080 /* model 055? */
+#define CM_DBLSPDS 0x00000040 /* double SPDIF sample rate 88.2/96 */
+#define CM_POLVALID 0x00000020 /* inverse SPDIF/IN valid bit */
+#define CM_SPDLOCKED 0x00000010
-#define CM_CH1FMT_MASK 0x0000000C
+#define CM_CH1FMT_MASK 0x0000000C /* bit 3: 16 bits, bit 2: stereo */
#define CM_CH1FMT_SHIFT 2
-#define CM_CH0FMT_MASK 0x00000003
+#define CM_CH0FMT_MASK 0x00000003 /* bit 1: 16 bits, bit 0: stereo */
#define CM_CH0FMT_SHIFT 0
#define CM_REG_INT_HLDCLR 0x0C
#define CM_CHIP_MASK2 0xff000000
+#define CM_CHIP_8768 0x20000000
+#define CM_CHIP_055 0x08000000
#define CM_CHIP_039 0x04000000
#define CM_CHIP_039_6CH 0x01000000
-#define CM_CHIP_055 0x08000000
-#define CM_CHIP_8768 0x20000000
+#define CM_UNKNOWN_INT_EN 0x00080000 /* ? */
#define CM_TDMA_INT_EN 0x00040000
#define CM_CH1_INT_EN 0x00020000
#define CM_CH0_INT_EN 0x00010000
-#define CM_INT_HOLD 0x00000002
-#define CM_INT_CLEAR 0x00000001
#define CM_REG_INT_STATUS 0x10
#define CM_INTR 0x80000000
@@ -175,12 +189,13 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_CHINT0 0x00000001
#define CM_REG_LEGACY_CTRL 0x14
-#define CM_NXCHG 0x80000000 /* h/w multi channels? */
+#define CM_NXCHG 0x80000000 /* don't map base reg dword->sample */
#define CM_VMPU_MASK 0x60000000 /* MPU401 i/o port address */
#define CM_VMPU_330 0x00000000
#define CM_VMPU_320 0x20000000
#define CM_VMPU_310 0x40000000
#define CM_VMPU_300 0x60000000
+#define CM_ENWR8237 0x10000000 /* enable bus master to write 8237 base reg */
#define CM_VSBSEL_MASK 0x0C000000 /* SB16 base address */
#define CM_VSBSEL_220 0x00000000
#define CM_VSBSEL_240 0x04000000
@@ -191,44 +206,74 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_FMSEL_3C8 0x01000000
#define CM_FMSEL_3E0 0x02000000
#define CM_FMSEL_3E8 0x03000000
-#define CM_ENSPDOUT 0x00800000 /* enable XPDIF/OUT to I/O interface */
-#define CM_SPDCOPYRHT 0x00400000 /* set copyright spdif in/out */
+#define CM_ENSPDOUT 0x00800000 /* enable XSPDIF/OUT to I/O interface */
+#define CM_SPDCOPYRHT 0x00400000 /* spdif in/out copyright bit */
#define CM_DAC2SPDO 0x00200000 /* enable wave+fm_midi -> SPDIF/OUT */
-#define CM_SETRETRY 0x00010000 /* 0: legacy i/o wait (default), 1: legacy i/o bus retry */
+#define CM_INVIDWEN 0x00100000 /* internal vendor ID write enable, model 039? */
+#define CM_SETRETRY 0x00100000 /* 0: legacy i/o wait (default), 1: legacy i/o bus retry */
+#define CM_C_EEACCESS 0x00080000 /* direct programming eeprom regs */
+#define CM_C_EECS 0x00040000
+#define CM_C_EEDI46 0x00020000
+#define CM_C_EECK46 0x00010000
#define CM_CHB3D6C 0x00008000 /* 5.1 channels support */
-#define CM_LINE_AS_BASS 0x00006000 /* use line-in as bass */
+#define CM_CENTR2LIN 0x00004000 /* line-in as center out */
+#define CM_BASE2LIN 0x00002000 /* line-in as bass out */
+#define CM_EXBASEN 0x00001000 /* external bass input enable */
#define CM_REG_MISC_CTRL 0x18
-#define CM_PWD 0x80000000
+#define CM_PWD 0x80000000 /* power down */
#define CM_RESET 0x40000000
-#define CM_SFIL_MASK 0x30000000
-#define CM_TXVX 0x08000000
-#define CM_N4SPK3D 0x04000000 /* 4ch output */
+#define CM_SFIL_MASK 0x30000000 /* filter control at front end DAC, model 037? */
+#define CM_VMGAIN 0x10000000 /* analog master amp +6dB, model 039? */
+#define CM_TXVX 0x08000000 /* model 037? */
+#define CM_N4SPK3D 0x04000000 /* copy front to rear */
#define CM_SPDO5V 0x02000000 /* 5V spdif output (1 = 0.5v (coax)) */
#define CM_SPDIF48K 0x01000000 /* write */
#define CM_SPATUS48K 0x01000000 /* read */
-#define CM_ENDBDAC 0x00800000 /* enable dual dac */
+#define CM_ENDBDAC 0x00800000 /* enable double dac */
#define CM_XCHGDAC 0x00400000 /* 0: front=ch0, 1: front=ch1 */
#define CM_SPD32SEL 0x00200000 /* 0: 16bit SPDIF, 1: 32bit */
-#define CM_SPDFLOOPI 0x00100000 /* int. SPDIF-IN -> int. OUT */
-#define CM_FM_EN 0x00080000 /* enalbe FM */
+#define CM_SPDFLOOPI 0x00100000 /* int. SPDIF-OUT -> int. IN */
+#define CM_FM_EN 0x00080000 /* enable legacy FM */
#define CM_AC3EN2 0x00040000 /* enable AC3: model 039 */
-#define CM_VIDWPDSB 0x00010000
+#define CM_ENWRASID 0x00010000 /* choose writable internal SUBID (audio) */
+#define CM_VIDWPDSB 0x00010000 /* model 037? */
#define CM_SPDF_AC97 0x00008000 /* 0: SPDIF/OUT 44.1K, 1: 48K */
-#define CM_MASK_EN 0x00004000
-#define CM_VIDWPPRT 0x00002000
-#define CM_SFILENB 0x00001000
-#define CM_MMODE_MASK 0x00000E00
+#define CM_MASK_EN 0x00004000 /* activate channel mask on legacy DMA */
+#define CM_ENWRMSID 0x00002000 /* choose writable internal SUBID (modem) */
+#define CM_VIDWPPRT 0x00002000 /* model 037? */
+#define CM_SFILENB 0x00001000 /* filter stepping at front end DAC, model 037? */
+#define CM_MMODE_MASK 0x00000E00 /* model DAA interface mode */
#define CM_SPDIF_SELECT2 0x00000100 /* for model > 039 ? */
#define CM_ENCENTER 0x00000080
-#define CM_FLINKON 0x00000040
-#define CM_FLINKOFF 0x00000020
-#define CM_MIDSMP 0x00000010
-#define CM_UPDDMA_MASK 0x0000000C
-#define CM_TWAIT_MASK 0x00000003
+#define CM_FLINKON 0x00000080 /* force modem link detection on, model 037 */
+#define CM_MUTECH1 0x00000040 /* mute PCI ch1 to DAC */
+#define CM_FLINKOFF 0x00000040 /* force modem link detection off, model 037 */
+#define CM_UNKNOWN_18_5 0x00000020 /* ? */
+#define CM_MIDSMP 0x00000010 /* 1/2 interpolation at front end DAC */
+#define CM_UPDDMA_MASK 0x0000000C /* TDMA position update notification */
+#define CM_UPDDMA_2048 0x00000000
+#define CM_UPDDMA_1024 0x00000004
+#define CM_UPDDMA_512 0x00000008
+#define CM_UPDDMA_256 0x0000000C
+#define CM_TWAIT_MASK 0x00000003 /* model 037 */
+#define CM_TWAIT1 0x00000002 /* FM i/o cycle, 0: 48, 1: 64 PCICLKs */
+#define CM_TWAIT0 0x00000001 /* i/o cycle, 0: 4, 1: 6 PCICLKs */
+
+#define CM_REG_TDMA_POSITION 0x1C
+#define CM_TDMA_CNT_MASK 0xFFFF0000 /* current byte/word count */
+#define CM_TDMA_ADR_MASK 0x0000FFFF /* current address */
/* byte */
#define CM_REG_MIXER0 0x20
+#define CM_REG_SBVR 0x20 /* write: sb16 version */
+#define CM_REG_DEV 0x20 /* read: hardware device version */
+
+#define CM_REG_MIXER21 0x21
+#define CM_UNKNOWN_21_MASK 0x78 /* ? */
+#define CM_X_ADPCM 0x04 /* SB16 ADPCM enable */
+#define CM_PROINV 0x02 /* SBPro left/right channel switching */
+#define CM_X_SB16 0x01 /* SB16 compatible */
#define CM_REG_SB16_DATA 0x22
#define CM_REG_SB16_ADDR 0x23
@@ -243,8 +288,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_FMMUTE_SHIFT 7
#define CM_WSMUTE 0x40 /* mute PCM */
#define CM_WSMUTE_SHIFT 6
-#define CM_SPK4 0x20 /* lin-in -> rear line out */
-#define CM_SPK4_SHIFT 5
+#define CM_REAR2LIN 0x20 /* lin-in -> rear line out */
+#define CM_REAR2LIN_SHIFT 5
#define CM_REAR2FRONT 0x10 /* exchange rear/front */
#define CM_REAR2FRONT_SHIFT 4
#define CM_WAVEINL 0x08 /* digital wave rec. left chan */
@@ -276,12 +321,13 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_VAUXR_MASK 0x0f
#define CM_REG_MISC 0x27
+#define CM_UNKNOWN_27_MASK 0xd8 /* ? */
#define CM_XGPO1 0x20
// #define CM_XGPBIO 0x04
#define CM_MIC_CENTER_LFE 0x04 /* mic as center/lfe out? (model 039 or later?) */
#define CM_SPDIF_INVERSE 0x04 /* spdif input phase inverse (model 037) */
#define CM_SPDVALID 0x02 /* spdif input valid check */
-#define CM_DMAUTO 0x01
+#define CM_DMAUTO 0x01 /* SB16 DMA auto detect */
#define CM_REG_AC97 0x28 /* hmmm.. do we have ac97 link? */
/*
@@ -322,18 +368,20 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
/*
* extended registers
*/
-#define CM_REG_CH0_FRAME1 0x80 /* base address */
-#define CM_REG_CH0_FRAME2 0x84
+#define CM_REG_CH0_FRAME1 0x80 /* write: base address */
+#define CM_REG_CH0_FRAME2 0x84 /* read: current address */
#define CM_REG_CH1_FRAME1 0x88 /* 0-15: count of samples at bus master; buffer size */
#define CM_REG_CH1_FRAME2 0x8C /* 16-31: count of samples at codec; fragment size */
+
#define CM_REG_EXT_MISC 0x90
-#define CM_REG_MISC_CTRL_8768 0x92 /* reg. name the same as 0x18 */
-#define CM_CHB3D8C 0x20 /* 7.1 channels support */
-#define CM_SPD32FMT 0x10 /* SPDIF/IN 32k */
-#define CM_ADC2SPDIF 0x08 /* ADC output to SPDIF/OUT */
-#define CM_SHAREADC 0x04 /* DAC in ADC as Center/LFE */
-#define CM_REALTCMP 0x02 /* monitor the CMPL/CMPR of ADC */
-#define CM_INVLRCK 0x01 /* invert ZVPORT's LRCK */
+#define CM_ADC48K44K 0x10000000 /* ADC parameters group, 0: 44k, 1: 48k */
+#define CM_CHB3D8C 0x00200000 /* 7.1 channels support */
+#define CM_SPD32FMT 0x00100000 /* SPDIF/IN 32k sample rate */
+#define CM_ADC2SPDIF 0x00080000 /* ADC output to SPDIF/OUT */
+#define CM_SHAREADC 0x00040000 /* DAC in ADC as Center/LFE */
+#define CM_REALTCMP 0x00020000 /* monitor the CMPL/CMPR of ADC */
+#define CM_INVLRCK 0x00010000 /* invert ZVPORT's LRCK */
+#define CM_UNKNOWN_90_MASK 0x0000FFFF /* ? */
/*
* size of i/o region
@@ -383,15 +431,14 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
struct cmipci_pcm {
struct snd_pcm_substream *substream;
- int running; /* dac/adc running? */
+ u8 running; /* dac/adc running? */
+ u8 fmt; /* format bits */
+ u8 is_dac;
+ u8 needs_silencing;
unsigned int dma_size; /* in frames */
- unsigned int period_size; /* in frames */
+ unsigned int shift;
+ unsigned int ch; /* channel (0/1) */
unsigned int offset; /* physical address of the buffer */
- unsigned int fmt; /* format bits */
- int ch; /* channel (0/1) */
- unsigned int is_dac; /* is dac? */
- int bytes_per_frame;
- int shift;
};
/* mixer elements toggled/resumed during ac3 playback */
@@ -424,7 +471,6 @@ struct cmipci {
int chip_version;
int max_channels;
- unsigned int has_dual_dac: 1;
unsigned int can_ac3_sw: 1;
unsigned int can_ac3_hw: 1;
unsigned int can_multi_ch: 1;
@@ -557,6 +603,9 @@ static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 4
static unsigned int snd_cmipci_rate_freq(unsigned int rate)
{
unsigned int i;
+
+ if (rate > 48000)
+ rate /= 2;
for (i = 0; i < ARRAY_SIZE(rates); i++) {
if (rates[i] == rate)
return i;
@@ -671,19 +720,19 @@ static int snd_cmipci_hw_free(struct snd_pcm_substream *substream)
/*
*/
-static unsigned int hw_channels[] = {1, 2, 4, 5, 6, 8};
+static unsigned int hw_channels[] = {1, 2, 4, 6, 8};
static struct snd_pcm_hw_constraint_list hw_constraints_channels_4 = {
.count = 3,
.list = hw_channels,
.mask = 0,
};
static struct snd_pcm_hw_constraint_list hw_constraints_channels_6 = {
- .count = 5,
+ .count = 4,
.list = hw_channels,
.mask = 0,
};
static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = {
- .count = 6,
+ .count = 5,
.list = hw_channels,
.mask = 0,
};
@@ -691,48 +740,37 @@ static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = {
static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels)
{
if (channels > 2) {
- if (! cm->can_multi_ch)
+ if (!cm->can_multi_ch || !rec->ch)
return -EINVAL;
if (rec->fmt != 0x03) /* stereo 16bit only */
return -EINVAL;
+ }
+ if (cm->can_multi_ch) {
spin_lock_irq(&cm->reg_lock);
- snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
- if (channels > 4) {
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
+ if (channels > 2) {
+ snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
+ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
} else {
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
+ snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
}
- if (channels >= 6) {
+ if (channels == 8)
+ snd_cmipci_set_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
+ else
+ snd_cmipci_clear_bit(cm, CM_REG_EXT_MISC, CM_CHB3D8C);
+ if (channels == 6) {
+ snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
} else {
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
- }
- if (cm->chip_version == 68) {
- if (channels == 8) {
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL_8768, CM_CHB3D8C);
- } else {
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL_8768, CM_CHB3D8C);
- }
- }
- spin_unlock_irq(&cm->reg_lock);
-
- } else {
- if (cm->can_multi_ch) {
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D5C);
snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CHB3D6C);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENCENTER);
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
- spin_unlock_irq(&cm->reg_lock);
}
+ if (channels == 4)
+ snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
+ else
+ snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
+ spin_unlock_irq(&cm->reg_lock);
}
return 0;
}
@@ -746,6 +784,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
struct snd_pcm_substream *substream)
{
unsigned int reg, freq, val;
+ unsigned int period_size;
struct snd_pcm_runtime *runtime = substream->runtime;
rec->fmt = 0;
@@ -765,11 +804,11 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
rec->offset = runtime->dma_addr;
/* buffer and period sizes in frame */
rec->dma_size = runtime->buffer_size << rec->shift;
- rec->period_size = runtime->period_size << rec->shift;
+ period_size = runtime->period_size << rec->shift;
if (runtime->channels > 2) {
/* multi-channels */
rec->dma_size = (rec->dma_size * runtime->channels) / 2;
- rec->period_size = (rec->period_size * runtime->channels) / 2;
+ period_size = (period_size * runtime->channels) / 2;
}
spin_lock_irq(&cm->reg_lock);
@@ -780,7 +819,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
/* program sample counts */
reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
snd_cmipci_write_w(cm, reg, rec->dma_size - 1);
- snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1);
+ snd_cmipci_write_w(cm, reg + 2, period_size - 1);
/* set adc/dac flag */
val = rec->ch ? CM_CHADC1 : CM_CHADC0;
@@ -795,11 +834,11 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
freq = snd_cmipci_rate_freq(runtime->rate);
val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
if (rec->ch) {
- val &= ~CM_ASFC_MASK;
- val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK;
- } else {
val &= ~CM_DSFC_MASK;
val |= (freq << CM_DSFC_SHIFT) & CM_DSFC_MASK;
+ } else {
+ val &= ~CM_ASFC_MASK;
+ val |= (freq << CM_ASFC_SHIFT) & CM_ASFC_MASK;
}
snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
//snd_printd("cmipci: functrl1 = %08x\n", val);
@@ -813,6 +852,16 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
val &= ~CM_CH0FMT_MASK;
val |= rec->fmt << CM_CH0FMT_SHIFT;
}
+ if (cm->chip_version == 68) {
+ if (runtime->rate == 88200)
+ val |= CM_CH0_SRATE_88K << (rec->ch * 2);
+ else
+ val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2));
+ if (runtime->rate == 96000)
+ val |= CM_CH0_SRATE_96K << (rec->ch * 2);
+ else
+ val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2));
+ }
snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
//snd_printd("cmipci: chformat = %08x\n", val);
@@ -826,7 +875,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
* PCM trigger/stop
*/
static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
- struct snd_pcm_substream *substream, int cmd)
+ int cmd)
{
unsigned int inthld, chen, reset, pause;
int result = 0;
@@ -855,6 +904,7 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
cm->ctrl &= ~chen;
snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset);
snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset);
+ rec->needs_silencing = rec->is_dac;
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -906,7 +956,7 @@ static int snd_cmipci_playback_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], substream, cmd);
+ return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], cmd);
}
static snd_pcm_uframes_t snd_cmipci_playback_pointer(struct snd_pcm_substream *substream)
@@ -925,7 +975,7 @@ static int snd_cmipci_capture_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
- return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], substream, cmd);
+ return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], cmd);
}
static snd_pcm_uframes_t snd_cmipci_capture_pointer(struct snd_pcm_substream *substream)
@@ -1199,15 +1249,19 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub
snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
setup_ac3(cm, subs, do_ac3, rate);
- if (rate == 48000)
+ if (rate == 48000 || rate == 96000)
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
else
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
-
+ if (rate > 48000)
+ snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ else
+ snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
} else {
/* they are controlled via "IEC958 Output Switch" */
/* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */
/* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
+ snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
setup_ac3(cm, subs, 0, 0);
}
@@ -1227,7 +1281,7 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream)
int rate = substream->runtime->rate;
int err, do_spdif, do_ac3 = 0;
- do_spdif = ((rate == 44100 || rate == 48000) &&
+ do_spdif = (rate >= 44100 &&
substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE &&
substream->runtime->channels == 2);
if (do_spdif && cm->can_ac3_hw)
@@ -1252,11 +1306,75 @@ static int snd_cmipci_playback_spdif_prepare(struct snd_pcm_substream *substream
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
}
+/*
+ * Apparently, the samples last played on channel A stay in some buffer, even
+ * after the channel is reset, and get added to the data for the rear DACs when
+ * playing a multichannel stream on channel B. This is likely to generate
+ * wraparounds and thus distortions.
+ * To avoid this, we play at least one zero sample after the actual stream has
+ * stopped.
+ */
+static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec)
+{
+ struct snd_pcm_runtime *runtime = rec->substream->runtime;
+ unsigned int reg, val;
+
+ if (rec->needs_silencing && runtime && runtime->dma_area) {
+ /* set up a small silence buffer */
+ memset(runtime->dma_area, 0, PAGE_SIZE);
+ reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
+ val = ((PAGE_SIZE / 4) - 1) | (((PAGE_SIZE / 4) / 2 - 1) << 16);
+ snd_cmipci_write(cm, reg, val);
+
+ /* configure for 16 bits, 2 channels, 8 kHz */
+ if (runtime->channels > 2)
+ set_dac_channels(cm, rec, 2);
+ spin_lock_irq(&cm->reg_lock);
+ val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
+ val &= ~(CM_ASFC_MASK << (rec->ch * 3));
+ val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
+ val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
+ val &= ~(CM_CH0FMT_MASK << (rec->ch * 2));
+ val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2);
+ if (cm->chip_version == 68) {
+ val &= ~(CM_CH0_SRATE_88K << (rec->ch * 2));
+ val &= ~(CM_CH0_SRATE_96K << (rec->ch * 2));
+ }
+ snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
+
+ /* start stream (we don't need interrupts) */
+ cm->ctrl |= CM_CHEN0 << rec->ch;
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
+ spin_unlock_irq(&cm->reg_lock);
+
+ msleep(1);
+
+ /* stop and reset stream */
+ spin_lock_irq(&cm->reg_lock);
+ cm->ctrl &= ~(CM_CHEN0 << rec->ch);
+ val = CM_RST_CH0 << rec->ch;
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val);
+ spin_unlock_irq(&cm->reg_lock);
+
+ rec->needs_silencing = 0;
+ }
+}
+
static int snd_cmipci_playback_hw_free(struct snd_pcm_substream *substream)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
setup_spdif_playback(cm, substream, 0, 0);
restore_mixer_state(cm);
+ snd_cmipci_silence_hack(cm, &cm->channel[0]);
+ return snd_cmipci_hw_free(substream);
+}
+
+static int snd_cmipci_playback2_hw_free(struct snd_pcm_substream *substream)
+{
+ struct cmipci *cm = snd_pcm_substream_chip(substream);
+ snd_cmipci_silence_hack(cm, &cm->channel[1]);
return snd_cmipci_hw_free(substream);
}
@@ -1515,7 +1633,11 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream)
if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
return err;
runtime->hw = snd_cmipci_playback;
- runtime->hw.channels_max = cm->max_channels;
+ if (cm->chip_version == 68) {
+ runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000;
+ runtime->hw.rate_max = 96000;
+ }
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
cm->dig_pcm_status = cm->dig_status;
return 0;
@@ -1558,9 +1680,14 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
else if (cm->max_channels == 8)
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8);
}
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
}
mutex_unlock(&cm->open_mutex);
+ if (cm->chip_version == 68) {
+ runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000;
+ runtime->hw.rate_max = 96000;
+ }
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
return 0;
}
@@ -1574,8 +1701,15 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream)
return err;
if (cm->can_ac3_hw) {
runtime->hw = snd_cmipci_playback_spdif;
- if (cm->chip_version >= 37)
+ if (cm->chip_version >= 37) {
runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
+ snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+ }
+ if (cm->chip_version == 68) {
+ runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000;
+ runtime->hw.rate_max = 96000;
+ }
} else {
runtime->hw = snd_cmipci_playback_iec958_subframe;
}
@@ -1668,7 +1802,7 @@ static struct snd_pcm_ops snd_cmipci_playback2_ops = {
.close = snd_cmipci_playback2_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cmipci_playback2_hw_params,
- .hw_free = snd_cmipci_hw_free,
+ .hw_free = snd_cmipci_playback2_hw_free,
.prepare = snd_cmipci_capture_prepare, /* channel B */
.trigger = snd_cmipci_capture_trigger, /* channel B */
.pointer = snd_cmipci_capture_pointer, /* channel B */
@@ -2139,15 +2273,7 @@ struct cmipci_switch_args {
*/
};
-static int snd_cmipci_uswitch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_cmipci_uswitch_info snd_ctl_boolean_mono_info
static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol,
@@ -2260,8 +2386,8 @@ DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, 0, 0, 0); /* rever
DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0);
#endif
DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0);
-// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0);
-// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0);
+// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_REAR2LIN, 1, 0);
+// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_CENTR2LIN|CM_BASE2LIN, 0, 0);
// DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */
DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0);
@@ -2331,11 +2457,11 @@ static inline unsigned int get_line_in_mode(struct cmipci *cm)
unsigned int val;
if (cm->chip_version >= 39) {
val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL);
- if (val & CM_LINE_AS_BASS)
+ if (val & (CM_CENTR2LIN | CM_BASE2LIN))
return 2;
}
val = snd_cmipci_read_b(cm, CM_REG_MIXER1);
- if (val & CM_SPK4)
+ if (val & CM_REAR2LIN)
return 1;
return 0;
}
@@ -2359,13 +2485,13 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
spin_lock_irq(&cm->reg_lock);
if (ucontrol->value.enumerated.item[0] == 2)
- change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS);
+ change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN);
else
- change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS);
+ change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN);
if (ucontrol->value.enumerated.item[0] == 1)
- change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_SPK4);
+ change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
else
- change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_SPK4);
+ change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2583,19 +2709,18 @@ static void snd_cmipci_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct cmipci *cm = entry->private_data;
- int i;
+ int i, v;
- snd_iprintf(buffer, "%s\n\n", cm->card->longname);
- for (i = 0; i < 0x40; i++) {
- int v = inb(cm->iobase + i);
+ snd_iprintf(buffer, "%s\n", cm->card->longname);
+ for (i = 0; i < 0x94; i++) {
+ if (i == 0x28)
+ i = 0x90;
+ v = inb(cm->iobase + i);
if (i % 4 == 0)
- snd_iprintf(buffer, "%02x: ", i);
- snd_iprintf(buffer, "%02x", v);
- if (i % 4 == 3)
- snd_iprintf(buffer, "\n");
- else
- snd_iprintf(buffer, " ");
+ snd_iprintf(buffer, "\n%02x:", i);
+ snd_iprintf(buffer, " %02x", v);
}
+ snd_iprintf(buffer, "\n");
}
static void __devinit snd_cmipci_proc_init(struct cmipci *cm)
@@ -2633,46 +2758,40 @@ static void __devinit query_chip(struct cmipci *cm)
if (! detect) {
/* check reg 08h, bit 24-28 */
detect = snd_cmipci_read(cm, CM_REG_CHFORMAT) & CM_CHIP_MASK1;
- if (! detect) {
+ switch (detect) {
+ case 0:
cm->chip_version = 33;
- cm->max_channels = 2;
if (cm->do_soft_ac3)
cm->can_ac3_sw = 1;
else
cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- } else {
+ break;
+ case CM_CHIP_037:
cm->chip_version = 37;
- cm->max_channels = 2;
cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
+ break;
+ default:
+ cm->chip_version = 39;
+ cm->can_ac3_hw = 1;
+ break;
}
+ cm->max_channels = 2;
} else {
- /* check reg 0Ch, bit 26 */
- if (detect & CM_CHIP_8768) {
- cm->chip_version = 68;
- cm->max_channels = 8;
- cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- cm->can_multi_ch = 1;
- } else if (detect & CM_CHIP_055) {
- cm->chip_version = 55;
- cm->max_channels = 6;
- cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- cm->can_multi_ch = 1;
- } else if (detect & CM_CHIP_039) {
+ if (detect & CM_CHIP_039) {
cm->chip_version = 39;
if (detect & CM_CHIP_039_6CH) /* 4 or 6 channels */
cm->max_channels = 6;
else
cm->max_channels = 4;
- cm->can_ac3_hw = 1;
- cm->has_dual_dac = 1;
- cm->can_multi_ch = 1;
+ } else if (detect & CM_CHIP_8768) {
+ cm->chip_version = 68;
+ cm->max_channels = 8;
} else {
- printk(KERN_ERR "chip %x version not supported\n", detect);
+ cm->chip_version = 55;
+ cm->max_channels = 6;
}
+ cm->can_ac3_hw = 1;
+ cm->can_multi_ch = 1;
}
}
@@ -2782,10 +2901,14 @@ static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
if (!fm_port)
goto disable_fm;
- /* first try FM regs in PCI port range */
- iosynth = cm->iobase + CM_REG_FM_PCI;
- err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
- OPL3_HW_OPL3, 1, &opl3);
+ if (cm->chip_version >= 39) {
+ /* first try FM regs in PCI port range */
+ iosynth = cm->iobase + CM_REG_FM_PCI;
+ err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
+ OPL3_HW_OPL3, 1, &opl3);
+ } else {
+ err = -EIO;
+ }
if (err < 0) {
/* then try legacy ports */
val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
@@ -2829,9 +2952,10 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
static struct snd_device_ops ops = {
.dev_free = snd_cmipci_dev_free,
};
- unsigned int val = 0;
+ unsigned int val;
long iomidi;
- int integrated_midi;
+ int integrated_midi = 0;
+ char modelstr[16];
int pcm_index, pcm_spdif_index;
static struct pci_device_id intel_82437vx[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
@@ -2904,6 +3028,8 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
#endif
/* initialize codec registers */
+ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_RESET);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_RESET);
snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
snd_cmipci_ch_reset(cm, CM_CH_PLAY);
snd_cmipci_ch_reset(cm, CM_CH_CAPT);
@@ -2917,6 +3043,10 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
#else
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
#endif
+ if (cm->chip_version) {
+ snd_cmipci_write_b(cm, CM_REG_EXT_MISC, 0x20); /* magic */
+ snd_cmipci_write_b(cm, CM_REG_EXT_MISC + 1, 0x09); /* more magic */
+ }
/* Set Bus Master Request */
snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_BREQ);
@@ -2931,15 +3061,55 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
break;
}
+ if (cm->chip_version < 68) {
+ val = pci->device < 0x110 ? 8338 : 8738;
+ } else {
+ switch (snd_cmipci_read_b(cm, CM_REG_INT_HLDCLR + 3) & 0x03) {
+ case 0:
+ val = 8769;
+ break;
+ case 2:
+ val = 8762;
+ break;
+ default:
+ switch ((pci->subsystem_vendor << 16) |
+ pci->subsystem_device) {
+ case 0x13f69761:
+ case 0x584d3741:
+ case 0x584d3751:
+ case 0x584d3761:
+ case 0x584d3771:
+ case 0x72848384:
+ val = 8770;
+ break;
+ default:
+ val = 8768;
+ break;
+ }
+ }
+ }
+ sprintf(card->shortname, "C-Media CMI%d", val);
+ if (cm->chip_version < 68)
+ sprintf(modelstr, " (model %d)", cm->chip_version);
+ else
+ modelstr[0] = '\0';
+ sprintf(card->longname, "%s%s at %#lx, irq %i",
+ card->shortname, modelstr, cm->iobase, cm->irq);
+
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
snd_cmipci_free(cm);
return err;
}
- integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
- if (integrated_midi && mpu_port[dev] == 1)
- iomidi = cm->iobase + CM_REG_MPU_PCI;
- else {
+ if (cm->chip_version >= 39) {
+ val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1);
+ if (val != 0x00 && val != 0xff) {
+ iomidi = cm->iobase + CM_REG_MPU_PCI;
+ integrated_midi = 1;
+ }
+ }
+ if (!integrated_midi) {
+ val = 0;
iomidi = mpu_port[dev];
switch (iomidi) {
case 0x320: val = CM_VMPU_320; break;
@@ -2953,11 +3123,21 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
/* enable UART */
snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
+ if (inb(iomidi + 1) == 0xff) {
+ snd_printk(KERN_ERR "cannot enable MPU-401 port"
+ " at %#lx\n", iomidi);
+ snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1,
+ CM_UART_EN);
+ iomidi = 0;
+ }
}
}
- if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0)
- return err;
+ if (cm->chip_version < 68) {
+ err = snd_cmipci_create_fm(cm, fm_port[dev]);
+ if (err < 0)
+ return err;
+ }
/* reset mixer */
snd_cmipci_mixer_write(cm, 0, 0);
@@ -2969,11 +3149,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
return err;
pcm_index++;
- if (cm->has_dual_dac) {
- if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
- return err;
- pcm_index++;
- }
+ if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
+ return err;
+ pcm_index++;
if (cm->can_ac3_hw || cm->can_ac3_sw) {
pcm_spdif_index = pcm_index;
if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
@@ -3057,15 +3235,6 @@ static int __devinit snd_cmipci_probe(struct pci_dev *pci,
}
card->private_data = cm;
- sprintf(card->shortname, "C-Media PCI %s", card->driver);
- sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i",
- card->shortname,
- cm->chip_version,
- cm->iobase,
- cm->irq);
-
- //snd_printd("%s is detected\n", card->longname);
-
if ((err = snd_card_register(card)) < 0) {
snd_card_free(card);
return err;
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 44cf5460764..9a55f4a9739 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1,6 +1,6 @@
/*
* Driver for Cirrus Logic CS4281 based PCI soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
*
*
* This program is free software; you can redistribute it and/or modify
@@ -38,7 +38,7 @@
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Cirrus Logic CS4281");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,CS4281}}");
@@ -842,12 +842,11 @@ static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream)
static struct snd_pcm_hardware snd_cs4281_playback =
{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
@@ -868,12 +867,11 @@ static struct snd_pcm_hardware snd_cs4281_playback =
static struct snd_pcm_hardware snd_cs4281_capture =
{
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_SYNC_START),
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
@@ -904,7 +902,6 @@ static int snd_cs4281_playback_open(struct snd_pcm_substream *substream)
dma->right_slot = 1;
runtime->private_data = dma;
runtime->hw = snd_cs4281_playback;
- snd_pcm_set_sync(substream);
/* should be detected from the AC'97 layer, but it seems
that although CS4297A rev B reports 18-bit ADC resolution,
samples are 20-bit */
@@ -924,7 +921,6 @@ static int snd_cs4281_capture_open(struct snd_pcm_substream *substream)
dma->right_slot = 11;
runtime->private_data = dma;
runtime->hw = snd_cs4281_capture;
- snd_pcm_set_sync(substream);
/* should be detected from the AC'97 layer, but it seems
that although CS4297A rev B reports 18-bit ADC resolution,
samples are 20-bit */
diff --git a/sound/pci/cs46xx/Makefile b/sound/pci/cs46xx/Makefile
index d8b77b89aec..67e811ec853 100644
--- a/sound/pci/cs46xx/Makefile
+++ b/sound/pci/cs46xx/Makefile
@@ -1,12 +1,10 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
-snd-cs46xx-objs := cs46xx.o cs46xx_lib.o
-ifeq ($(CONFIG_SND_CS46XX_NEW_DSP),y)
- snd-cs46xx-objs += dsp_spos.o dsp_spos_scb_lib.o
-endif
+snd-cs46xx-y := cs46xx.o cs46xx_lib.o
+snd-cs46xx-$(CONFIG_SND_CS46XX_NEW_DSP) += dsp_spos.o dsp_spos_scb_lib.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_CS46XX) += snd-cs46xx.o
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 8b6cd144d10..2699cb6c2cd 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -1,6 +1,6 @@
/*
* The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@
#include <sound/cs46xx.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Cirrus Logic Sound Fusion CS46XX");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)},"
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 71d7aab9d86..2c7bfc9fef6 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Abramo Bagnara <abramo@alsa-project.org>
* Cirrus Logic, Inc.
* Routines for control of Cirrus Logic CS461x chips
@@ -1818,15 +1818,7 @@ static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_c
}
#endif
-static int snd_mixer_boolean_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_mixer_boolean_info snd_ctl_boolean_mono_info
static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index 20dcd72f06c..018a7de5601 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -1,6 +1,6 @@
/*
* The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h
index 0d246bca418..f9e169d33c0 100644
--- a/sound/pci/cs46xx/dsp_spos.h
+++ b/sound/pci/cs46xx/dsp_spos.h
@@ -1,6 +1,6 @@
/*
* The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 57e357de150..eded4dfeba1 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -1480,7 +1480,7 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
if (!pcm_channel->src_scb->ref_count) {
cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb);
- snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot <= DSP_MAX_SRC_NR,
+ snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot < DSP_MAX_SRC_NR,
return );
ins->src_scb_slots[pcm_channel->src_slot] = 0;
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index ad947b4c04c..bb3d57e6a3c 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -2,11 +2,8 @@
# Makefile for cs5535audio
#
-snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o
-
-ifeq ($(CONFIG_PM),y)
-snd-cs5535audio-objs += cs5535audio_pm.o
-endif
+snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
+snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index b8e75ef9c1e..2b35889787b 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -206,7 +206,6 @@ static void process_bm1_irq(struct cs5535audio *cs5535au)
static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
{
u16 acc_irq_stat;
- u8 bm_stat;
unsigned char count;
struct cs5535audio *cs5535au = dev_id;
@@ -217,7 +216,7 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
if (!acc_irq_stat)
return IRQ_NONE;
- for (count = 0; count < 10; count++) {
+ for (count = 0; count < 4; count++) {
if (acc_irq_stat & (1 << count)) {
switch (count) {
case IRQ_STS:
@@ -232,26 +231,9 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
case BM1_IRQ_STS:
process_bm1_irq(cs5535au);
break;
- case BM2_IRQ_STS:
- bm_stat = cs_readb(cs5535au, ACC_BM2_STATUS);
- break;
- case BM3_IRQ_STS:
- bm_stat = cs_readb(cs5535au, ACC_BM3_STATUS);
- break;
- case BM4_IRQ_STS:
- bm_stat = cs_readb(cs5535au, ACC_BM4_STATUS);
- break;
- case BM5_IRQ_STS:
- bm_stat = cs_readb(cs5535au, ACC_BM5_STATUS);
- break;
- case BM6_IRQ_STS:
- bm_stat = cs_readb(cs5535au, ACC_BM6_STATUS);
- break;
- case BM7_IRQ_STS:
- bm_stat = cs_readb(cs5535au, ACC_BM7_STATUS);
- break;
default:
- snd_printk(KERN_ERR "Unexpected irq src\n");
+ snd_printk(KERN_ERR "Unexpected irq src: "
+ "0x%x\n", acc_irq_stat);
break;
}
}
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 4fd1f31a6cf..66bae766419 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -16,57 +16,28 @@
#define ACC_IRQ_STATUS 0x12
#define ACC_BM0_CMD 0x20
#define ACC_BM1_CMD 0x28
-#define ACC_BM2_CMD 0x30
-#define ACC_BM3_CMD 0x38
-#define ACC_BM4_CMD 0x40
-#define ACC_BM5_CMD 0x48
-#define ACC_BM6_CMD 0x50
-#define ACC_BM7_CMD 0x58
#define ACC_BM0_PRD 0x24
#define ACC_BM1_PRD 0x2C
-#define ACC_BM2_PRD 0x34
-#define ACC_BM3_PRD 0x3C
-#define ACC_BM4_PRD 0x44
-#define ACC_BM5_PRD 0x4C
-#define ACC_BM6_PRD 0x54
-#define ACC_BM7_PRD 0x5C
#define ACC_BM0_STATUS 0x21
#define ACC_BM1_STATUS 0x29
-#define ACC_BM2_STATUS 0x31
-#define ACC_BM3_STATUS 0x39
-#define ACC_BM4_STATUS 0x41
-#define ACC_BM5_STATUS 0x49
-#define ACC_BM6_STATUS 0x51
-#define ACC_BM7_STATUS 0x59
#define ACC_BM0_PNTR 0x60
#define ACC_BM1_PNTR 0x64
-#define ACC_BM2_PNTR 0x68
-#define ACC_BM3_PNTR 0x6C
-#define ACC_BM4_PNTR 0x70
-#define ACC_BM5_PNTR 0x74
-#define ACC_BM6_PNTR 0x78
-#define ACC_BM7_PNTR 0x7C
+
/* acc_codec bar0 reg bits */
/* ACC_IRQ_STATUS */
#define IRQ_STS 0
#define WU_IRQ_STS 1
#define BM0_IRQ_STS 2
#define BM1_IRQ_STS 3
-#define BM2_IRQ_STS 4
-#define BM3_IRQ_STS 5
-#define BM4_IRQ_STS 6
-#define BM5_IRQ_STS 7
-#define BM6_IRQ_STS 8
-#define BM7_IRQ_STS 9
/* ACC_BMX_STATUS */
#define EOP (1<<0)
#define BM_EOP_ERR (1<<1)
/* ACC_BMX_CTL */
-#define BM_CTL_EN 0x00000001
-#define BM_CTL_PAUSE 0x00000011
-#define BM_CTL_DIS 0x00000000
-#define BM_CTL_BYTE_ORD_LE 0x00000000
-#define BM_CTL_BYTE_ORD_BE 0x00000100
+#define BM_CTL_EN 0x01
+#define BM_CTL_PAUSE 0x03
+#define BM_CTL_DIS 0x00
+#define BM_CTL_BYTE_ORD_LE 0x00
+#define BM_CTL_BYTE_ORD_BE 0x04
/* cs5535 specific ac97 codec register defines */
#define CMD_MASK 0xFF00FFFF
#define CMD_NEW 0x00010000
@@ -106,7 +77,6 @@ struct cs5535audio_dma {
struct snd_pcm_substream *substream;
unsigned int buf_addr, buf_bytes;
unsigned int period_bytes, periods;
- int suspended;
u32 saved_prd;
};
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 5450a9e8f13..21df0634af3 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -43,7 +43,6 @@ static struct snd_pcm_hardware snd_cs5535audio_playback =
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE |
- SNDRV_PCM_INFO_SYNC_START |
SNDRV_PCM_INFO_RESUME
),
.formats = (
@@ -71,8 +70,7 @@ static struct snd_pcm_hardware snd_cs5535audio_capture =
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_SYNC_START
+ SNDRV_PCM_INFO_MMAP_VALID
),
.formats = (
SNDRV_PCM_FMTBIT_S16_LE
@@ -102,7 +100,6 @@ static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream)
runtime->hw = snd_cs5535audio_playback;
cs5535au->playback_substream = substream;
runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]);
- snd_pcm_set_sync(substream);
if ((err = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err;
@@ -164,6 +161,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
jmpprd_addr = cpu_to_le32(lastdesc->addr +
(sizeof(struct cs5535audio_dma_desc)*periods));
+ dma->substream = substream;
dma->period_bytes = period_bytes;
dma->periods = periods;
spin_lock_irq(&cs5535au->reg_lock);
@@ -241,6 +239,7 @@ static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au,
{
snd_dma_free_pages(&dma->desc_buf);
dma->desc_buf.area = NULL;
+ dma->substream = NULL;
}
static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
@@ -298,14 +297,12 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
break;
case SNDRV_PCM_TRIGGER_RESUME:
dma->ops->enable_dma(cs5535au);
- dma->suspended = 0;
break;
case SNDRV_PCM_TRIGGER_STOP:
dma->ops->disable_dma(cs5535au);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
dma->ops->disable_dma(cs5535au);
- dma->suspended = 1;
break;
default:
snd_printk(KERN_ERR "unhandled trigger\n");
@@ -348,7 +345,6 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
runtime->hw = snd_cs5535audio_capture;
cs5535au->capture_substream = substream;
runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]);
- snd_pcm_set_sync(substream);
if ((err = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err;
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index 3e4d198a450..838708f6d45 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -64,18 +64,21 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
int i;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ snd_pcm_suspend_all(cs5535au->pcm);
+ snd_ac97_suspend(cs5535au->ac97);
for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
struct cs5535audio_dma *dma = &cs5535au->dmas[i];
- if (dma && dma->substream && !dma->suspended)
+ if (dma && dma->substream)
dma->saved_prd = dma->ops->read_prd(cs5535au);
}
- snd_pcm_suspend_all(cs5535au->pcm);
- snd_ac97_suspend(cs5535au->ac97);
/* save important regs, then disable aclink in hw */
snd_cs5535audio_stop_hardware(cs5535au);
+ if (pci_save_state(pci)) {
+ printk(KERN_ERR "cs5535audio: pci_save_state failed!\n");
+ return -EIO;
+ }
pci_disable_device(pci);
- pci_save_state(pci);
pci_set_power_state(pci, pci_choose_state(pci, state));
return 0;
}
@@ -89,7 +92,12 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
int i;
pci_set_power_state(pci, PCI_D0);
- pci_restore_state(pci);
+ if (pci_restore_state(pci) < 0) {
+ printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
+ "disabling device\n");
+ snd_card_disconnect(card);
+ return -EIO;
+ }
if (pci_enable_device(pci) < 0) {
printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
"disabling device\n");
@@ -112,17 +120,17 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
if (!timeout)
snd_printk(KERN_ERR "Failure getting AC Link ready\n");
- /* we depend on ac97 to perform the codec power up */
- snd_ac97_resume(cs5535au->ac97);
/* set up rate regs, dma. actual initiation is done in trig */
for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) {
struct cs5535audio_dma *dma = &cs5535au->dmas[i];
- if (dma && dma->substream && dma->suspended) {
+ if (dma && dma->substream) {
dma->substream->ops->prepare(dma->substream);
dma->ops->setup_prd(cs5535au, dma->saved_prd);
}
}
-
+
+ /* we depend on ac97 to perform the codec power up */
+ snd_ac97_resume(cs5535au->ac97);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index f27b6a733b9..499ee1a5319 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1595,15 +1595,7 @@ static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = {
#ifdef ECHOCARD_HAS_PHANTOM_POWER
/******************* Phantom power switch *******************/
-static int snd_echo_phantom_power_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_echo_phantom_power_info snd_ctl_boolean_mono_info
static int snd_echo_phantom_power_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1646,15 +1638,7 @@ static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = {
#ifdef ECHOCARD_HAS_DIGITAL_IN_AUTOMUTE
/******************* Digital input automute switch *******************/
-static int snd_echo_automute_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_echo_automute_info snd_ctl_boolean_mono_info
static int snd_echo_automute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1695,18 +1679,7 @@ static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = {
/******************* VU-meters switch *******************/
-static int snd_echo_vumeters_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct echoaudio *chip;
-
- chip = snd_kcontrol_chip(kcontrol);
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_echo_vumeters_switch_info snd_ctl_boolean_mono_info
static int snd_echo_vumeters_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c
index 42afa837d9b..e6c10077039 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.c
+++ b/sound/pci/echoaudio/echoaudio_dsp.c
@@ -43,11 +43,11 @@ static int wait_handshake(struct echoaudio *chip)
{
int i;
- /* Wait up to 10ms for the handshake from the DSP */
+ /* Wait up to 20ms for the handshake from the DSP */
for (i = 0; i < HANDSHAKE_TIMEOUT; i++) {
/* Look for the handshake value */
+ barrier();
if (chip->comm_page->handshake) {
- /*if (i) DE_ACT(("Handshake time: %d\n", i));*/
return 0;
}
udelay(1);
diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h
index e55ee00991a..e352f3ae292 100644
--- a/sound/pci/echoaudio/echoaudio_dsp.h
+++ b/sound/pci/echoaudio/echoaudio_dsp.h
@@ -642,18 +642,18 @@ struct comm_page { /* Base Length*/
u32 flags; /* See Appendix A below 0x004 4 */
u32 unused; /* Unused entry 0x008 4 */
u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */
- volatile u32 handshake; /* DSP command handshake 0x010 4 */
+ u32 handshake; /* DSP command handshake 0x010 4 */
u32 cmd_start; /* Chs. to start mask 0x014 4 */
u32 cmd_stop; /* Chs. to stop mask 0x018 4 */
u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */
u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */
struct sg_entry sglist_addr[DSP_MAXPIPES];
/* Chs. Physical sglist addrs 0x060 32*8 */
- volatile u32 position[DSP_MAXPIPES];
+ u32 position[DSP_MAXPIPES];
/* Positions for ea. ch. 0x160 32*4 */
- volatile s8 vu_meter[DSP_MAXPIPES];
+ s8 vu_meter[DSP_MAXPIPES];
/* VU meters 0x1e0 32*1 */
- volatile s8 peak_meter[DSP_MAXPIPES];
+ s8 peak_meter[DSP_MAXPIPES];
/* Peak meters 0x200 32*1 */
s8 line_out_level[DSP_MAXAUDIOOUTPUTS];
/* Output gain 0x220 16*1 */
@@ -665,7 +665,7 @@ struct comm_page { /* Base Length*/
/* Gina/Darla play filters - obsolete 0x3c0 168*4 */
u32 rec_coeff[MAX_REC_TAPS];
/* Gina/Darla record filters - obsolete 0x660 192*4 */
- volatile u16 midi_input[MIDI_IN_BUFFER_SIZE];
+ u16 midi_input[MIDI_IN_BUFFER_SIZE];
/* MIDI input data transfer buffer 0x960 256*2 */
u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */
u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */
@@ -674,11 +674,10 @@ struct comm_page { /* Base Length*/
u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */
u16 input_clock; /* Chg. Input clock state 0xb68 2 */
u16 output_clock; /* Chg. Output clock state 0xb6a 2 */
- volatile u32 status_clocks;
- /* Current Input clock state 0xb6c 4 */
+ u32 status_clocks; /* Current Input clock state 0xb6c 4 */
u32 ext_box_status; /* External box status 0xb70 4 */
u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */
- volatile u32 midi_out_free_count;
+ u32 midi_out_free_count;
/* # of bytes free in MIDI output FIFO 0xb78 4 */
u32 unused2; /* Cyclic pipes 0xb7c 4 */
u32 control_register;
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
index e521c38cef4..cf2d5636d8b 100644
--- a/sound/pci/emu10k1/Makefile
+++ b/sound/pci/emu10k1/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 55caf341933..9680caff90c 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -1,6 +1,6 @@
/*
* The driver for the EMU10K1 (SB Live!) based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
* Added support for Audigy 2 Value.
@@ -32,7 +32,7 @@
#include <sound/emu10k1.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("EMU10K1");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS},"
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 404ae1be0a4..97c41d72a25 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips
*
@@ -31,6 +31,8 @@
*
*/
+#include <linux/sched.h>
+#include <linux/kthread.h>
#include <sound/driver.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -702,6 +704,65 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
return 0;
}
+int emu1010_firmware_thread(void *data) {
+ struct snd_emu10k1 * emu = data;
+ int tmp,tmp2;
+ int reg;
+ int err;
+
+ for (;;) {
+ /* Delay to allow Audio Dock to settle */
+ msleep(1000);
+ if (kthread_should_stop())
+ break;
+ snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
+ snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */
+ if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
+ /* Audio Dock attached */
+ /* Return to Audio Dock programming mode */
+ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
+ snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
+ if (emu->card_capabilities->emu1010 == 1) {
+ if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
+ return err;
+ }
+ } else if (emu->card_capabilities->emu1010 == 2) {
+ if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
+ return err;
+ }
+ } else if (emu->card_capabilities->emu1010 == 3) {
+ if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
+ return err;
+ }
+ }
+
+ snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
+ snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
+ snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
+ /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
+ snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
+ snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
+ if ((reg & 0x1f) != 0x15) {
+ /* FPGA failed to be programmed */
+ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
+ return 0;
+ return -ENODEV;
+ }
+ snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
+ snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
+ snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
+ snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
+ /* Sync clocking between 1010 and Dock */
+ /* Allow DLL to settle */
+ msleep(10);
+ /* Unmute all. Default is muted after a firmware load */
+ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
+ break;
+ }
+ }
+ return 0;
+}
+
/*
* EMU-1010 - details found out from this driver, official MS Win drivers,
* testing the card:
@@ -817,8 +878,16 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg );
snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg);
snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp );
- /* ADAT input. */
- snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 );
+ /* Optical -> ADAT I/O */
+ /* 0 : SPDIF
+ * 1 : ADAT
+ */
+ emu->emu1010.optical_in = 1; /* IN_ADAT */
+ emu->emu1010.optical_out = 1; /* IN_ADAT */
+ tmp = 0;
+ tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
+ (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
+ snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp );
snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp );
/* Set no attenuation on Audio Dock pads. */
snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 );
@@ -1004,49 +1073,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp );
snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
- /* Delay to allow Audio Dock to settle */
- msleep(100);
- snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
- snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */
- /* FIXME: The loading of this should be able to happen any time,
- * as the user can plug/unplug it at any time
- */
- if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) {
- /* Audio Dock attached */
- /* Return to Audio Dock programming mode */
- snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
- if (emu->card_capabilities->emu1010 == 1) {
- if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
- return err;
- }
- } else if (emu->card_capabilities->emu1010 == 2) {
- if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
- return err;
- }
- } else if (emu->card_capabilities->emu1010 == 3) {
- if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) {
- return err;
- }
- }
+ /* Start Micro/Audio Dock firmware loader thread */
+ emu->emu1010.firmware_thread = kthread_create(&emu1010_firmware_thread,
+ emu,
+ "emu1010_firmware");
+ wake_up_process(emu->emu1010.firmware_thread);
- snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
- snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
- snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
- /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
- snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
- snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
- if ((reg & 0x3f) != 0x15) {
- /* FPGA failed to be programmed */
- snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
- return 0;
- return -ENODEV;
- }
- snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
- snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
- snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
- snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
- }
#if 0
snd_emu1010_fpga_link_dst_src_write(emu,
EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */
@@ -1132,7 +1164,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
emu->emu1010.output_source[23] = 28;
/* TEMP: Select SPDIF in/out */
- snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */
+ //snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */
/* TEMP: Select 48kHz SPDIF out */
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
@@ -1173,6 +1205,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
if (emu->card_capabilities->emu1010) {
/* Disable 48Volt power to Audio Dock */
snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 );
+ kthread_stop(emu->emu1010.firmware_thread);
}
if (emu->memhdr)
snd_util_memhdr_free(emu->memhdr);
@@ -1722,8 +1755,9 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
goto error;
}
- emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
- emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
+ emu->page_ptr_table = vmalloc(emu->max_cache_pages * sizeof(void *));
+ emu->page_addr_table = vmalloc(emu->max_cache_pages *
+ sizeof(unsigned long));
if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
err = -ENOMEM;
goto error;
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index e4af7a9b808..1ec7ebaff9e 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1062,14 +1062,7 @@ static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu)
return 0;
}
-static int snd_emu10k1x_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_emu10k1x_shared_spdif_info snd_ctl_boolean_mono_info
static int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 7206c0fa06f..9bf1cd59219 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for effect processor FX8010
*
@@ -642,10 +642,8 @@ snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
{
struct snd_emu10k1_fx8010_ctl *ctl;
struct snd_kcontrol *kcontrol;
- struct list_head *list;
-
- list_for_each(list, &emu->fx8010.gpr_ctl) {
- ctl = emu10k1_gpr_ctl(list);
+
+ list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
kcontrol = ctl->kcontrol;
if (kcontrol->id.iface == id->iface &&
!strcmp(kcontrol->id.name, id->name) &&
@@ -895,14 +893,12 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_control_gpr *gctl;
struct snd_emu10k1_fx8010_ctl *ctl;
struct snd_ctl_elem_id *id;
- struct list_head *list;
gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
if (! gctl)
return -ENOMEM;
- list_for_each(list, &emu->fx8010.gpr_ctl) {
- ctl = emu10k1_gpr_ctl(list);
+ list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
total++;
if (icode->gpr_list_controls &&
i < icode->gpr_list_control_count) {
@@ -1207,7 +1203,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
gpr += 2;
-
+
/* PCM Surround Playback (independent from stereo mix) */
A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
@@ -1267,8 +1263,16 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
/* emu1212 DSP 0 and DSP 1 Capture */
if (emu->card_capabilities->emu1010) {
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
- A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
+ if (emu->card_capabilities->ca0108_chip) {
+ /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
+ A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
+ A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_GPR(tmp));
+ A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x1), A_C_00000001);
+ A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr), A_GPR(tmp));
+ } else {
+ A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
+ A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
+ }
snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
gpr += 2;
}
@@ -1516,7 +1520,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
/* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
snd_printk("EMU outputs on\n");
for (z = 0; z < 8; z++) {
- A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
+ if (emu->card_capabilities->ca0108_chip) {
+ A_OP(icode, &ptr, iACC3, A3_EMU32OUT(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
+ } else {
+ A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
+ }
}
}
@@ -1557,106 +1565,116 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
#endif
if (emu->card_capabilities->emu1010) {
- snd_printk("EMU inputs on\n");
- /* Capture 16 (originally 8) channels of S32_LE sound */
-
- /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
- /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
- /* A_P16VIN(0) is delayed by one sample,
- * so all other A_P16VIN channels will need to also be delayed
- */
- /* Left ADC in. 1 of 2 */
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
- /* Right ADC in 1 of 2 */
- gpr_map[gpr++] = 0x00000000;
- /* Delaying by one sample: instead of copying the input
- * value A_P16VIN to output A_FXBUS2 as in the first channel,
- * we use an auxiliary register, delaying the value by one
- * sample
- */
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
- /* For 96kHz mode */
- /* Left ADC in. 2 of 2 */
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
- /* Right ADC in 2 of 2 */
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
- /* Pavel Hofman - we still have voices, A_FXBUS2s, and
- * A_P16VINs available -
- * let's add 8 more capture channels - total of 16
- */
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x10));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x12));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x14));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x16));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x18));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x1a));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x1c));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
- A_C_00000000, A_C_00000000);
- gpr_map[gpr++] = 0x00000000;
- snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
- bit_shifter16,
- A_GPR(gpr - 1),
- A_FXBUS2(0x1e));
- A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
- A_C_00000000, A_C_00000000);
+ if (emu->card_capabilities->ca0108_chip) {
+ snd_printk("EMU2 inputs on\n");
+ for (z = 0; z < 0x10; z++) {
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
+ bit_shifter16,
+ A3_EMU32IN(z),
+ A_FXBUS2(z*2) );
+ }
+ } else {
+ snd_printk("EMU inputs on\n");
+ /* Capture 16 (originally 8) channels of S32_LE sound */
+
+ /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
+ /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
+ /* A_P16VIN(0) is delayed by one sample,
+ * so all other A_P16VIN channels will need to also be delayed
+ */
+ /* Left ADC in. 1 of 2 */
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
+ /* Right ADC in 1 of 2 */
+ gpr_map[gpr++] = 0x00000000;
+ /* Delaying by one sample: instead of copying the input
+ * value A_P16VIN to output A_FXBUS2 as in the first channel,
+ * we use an auxiliary register, delaying the value by one
+ * sample
+ */
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
+ /* For 96kHz mode */
+ /* Left ADC in. 2 of 2 */
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
+ /* Right ADC in 2 of 2 */
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
+ /* Pavel Hofman - we still have voices, A_FXBUS2s, and
+ * A_P16VINs available -
+ * let's add 8 more capture channels - total of 16
+ */
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x10));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x12));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x14));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x16));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x18));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x1a));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x1c));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe),
+ A_C_00000000, A_C_00000000);
+ gpr_map[gpr++] = 0x00000000;
+ snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp,
+ bit_shifter16,
+ A_GPR(gpr - 1),
+ A_FXBUS2(0x1e));
+ A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf),
+ A_C_00000000, A_C_00000000);
+ }
#if 0
for (z = 4; z < 8; z++) {
@@ -2418,14 +2436,13 @@ static void copy_string(char *dst, char *src, char *null, int idx)
strcpy(dst, src);
}
-static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
+static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
struct snd_emu10k1_fx8010_info *info)
{
char **fxbus, **extin, **extout;
unsigned short fxbus_mask, extin_mask, extout_mask;
int res;
- memset(info, 0, sizeof(info));
info->internal_tram_size = emu->fx8010.itram_size;
info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
fxbus = fxbuses;
@@ -2442,7 +2459,6 @@ static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
for (res = 16; res < 32; res++, extout++)
copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
info->gpr_controls = emu->fx8010.gpr_count;
- return 0;
}
static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
@@ -2463,10 +2479,7 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
- if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
- kfree(info);
- return res;
- }
+ snd_emu10k1_fx8010_info(emu, info);
if (copy_to_user(argp, info, sizeof(*info))) {
kfree(info);
return -EFAULT;
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 7b2c1dcc533..54a2034d8ed 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Takashi Iwai <tiwai@suse.de>
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips / mixer routines
@@ -400,15 +400,7 @@ static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = {
-
-static int snd_emu1010_adc_pads_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_emu1010_adc_pads_info snd_ctl_boolean_mono_info
static int snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -456,14 +448,7 @@ static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = {
EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1),
};
-static int snd_emu1010_dac_pads_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_emu1010_dac_pads_info snd_ctl_boolean_mono_info
static int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -516,17 +501,19 @@ static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = {
static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
- static char *texts[2] = {
- "44100", "48000"
+ static char *texts[4] = {
+ "44100", "48000", "SPDIF", "ADAT"
};
-
+
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
+ uinfo->value.enumerated.items = 4;
+ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
return 0;
+
+
}
static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol,
@@ -584,6 +571,44 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
/* Unmute all */
snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
break;
+
+ case 2: /* Take clock from S/PDIF IN */
+ /* Mute all */
+ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
+ /* Default fallback clock 48kHz */
+ snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
+ /* Word Clock source, sync to S/PDIF input */
+ snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
+ EMU_HANA_WCLOCK_HANA_SPDIF_IN | EMU_HANA_WCLOCK_1X );
+ /* Set LEDs on Audio Dock */
+ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
+ EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
+ /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
+ /* Allow DLL to settle */
+ msleep(10);
+ /* Unmute all */
+ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
+ break;
+
+ case 3:
+ /* Take clock from ADAT IN */
+ /* Mute all */
+ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
+ /* Default fallback clock 48kHz */
+ snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
+ /* Word Clock source, sync to ADAT input */
+ snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
+ EMU_HANA_WCLOCK_HANA_ADAT_IN | EMU_HANA_WCLOCK_1X );
+ /* Set LEDs on Audio Dock */
+ snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_LOCK );
+ /* FIXME: We should set EMU_HANA_DOCK_LEDS_2_LOCK only when clock signal is present and valid */
+ /* Allow DLL to settle */
+ msleep(10);
+ /* Unmute all */
+ snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
+
+
+ break;
}
}
return change;
@@ -871,7 +896,7 @@ static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
- .count = 4,
+ .count = 3,
.info = snd_emu10k1_spdif_info,
.get = snd_emu10k1_spdif_get_mask
};
@@ -880,7 +905,7 @@ static struct snd_kcontrol_new snd_emu10k1_spdif_control =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
- .count = 4,
+ .count = 3,
.info = snd_emu10k1_spdif_info,
.get = snd_emu10k1_spdif_get,
.put = snd_emu10k1_spdif_put
@@ -1326,14 +1351,7 @@ static struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
.put = snd_emu10k1_efx_attn_put
};
-static int snd_emu10k1_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_emu10k1_shared_spdif_info snd_ctl_boolean_mono_info
static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index 950c6bcd6b7..04c7cf70353 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of EMU10K1 MPU-401 in UART mode
*
*
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index eda5cb373de..5ce5befc701 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips / PCM routines
* Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 2c1585991bc..c3fb10e81c9 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips / proc interface routines
*
@@ -240,8 +240,42 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_emu10k1 *emu = entry->private_data;
- snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
- snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
+ u32 value;
+ u32 value2;
+ unsigned long flags;
+ u32 rate;
+
+ if (emu->card_capabilities->emu1010) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x38, &value);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ if ((value & 0x1) == 0) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x2a, &value);
+ snd_emu1010_fpga_read(emu, 0x2b, &value2);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ rate = 0x1770000 / (((value << 5) | value2)+1);
+ snd_iprintf(buffer, "ADAT Locked : %u\n", rate);
+ } else {
+ snd_iprintf(buffer, "ADAT Unlocked\n");
+ }
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x20, &value);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ if ((value & 0x4) == 0) {
+ spin_lock_irqsave(&emu->emu_lock, flags);
+ snd_emu1010_fpga_read(emu, 0x28, &value);
+ snd_emu1010_fpga_read(emu, 0x29, &value2);
+ spin_unlock_irqrestore(&emu->emu_lock, flags);
+ rate = 0x1770000 / (((value << 5) | value2)+1);
+ snd_iprintf(buffer, "SPDIF Locked : %d\n", rate);
+ } else {
+ snd_iprintf(buffer, "SPDIF Unlocked\n");
+ }
+ } else {
+ snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
+ snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
+ }
#if 0
val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0);
snd_iprintf(buffer, "\nZoomed Video\n");
@@ -379,20 +413,16 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_emu10k1 *emu = entry->private_data;
- unsigned long value;
+ int value;
unsigned long flags;
- unsigned long regs;
int i;
snd_iprintf(buffer, "EMU1010 Registers:\n\n");
- for(i = 0; i < 0x30; i+=1) {
+ for(i = 0; i < 0x40; i+=1) {
spin_lock_irqsave(&emu->emu_lock, flags);
- regs=i+0x40; /* 0x40 upwards are registers. */
- outl(regs, emu->port + A_IOCFG);
- outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
- value = inl(emu->port + A_IOCFG);
+ snd_emu1010_fpga_read(emu, i, &value);
spin_unlock_irqrestore(&emu->emu_lock, flags);
- snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f);
+ snd_iprintf(buffer, "%02X: %08X, %02X\n", i, value, (value >> 8) & 0x7f);
}
}
@@ -555,9 +585,9 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
{
struct snd_info_entry *entry;
#ifdef CONFIG_SND_DEBUG
- if ((emu->card_capabilities->emu1010) &&
- snd_card_proc_new(emu->card, "emu1010_regs", &entry)) {
- snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
+ if (emu->card_capabilities->emu1010) {
+ if (! snd_card_proc_new(emu->card, "emu1010_regs", &entry))
+ snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
}
if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 116e1c8d936..6702c15fefa 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for control of EMU10K1 chips
*
@@ -226,9 +226,9 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
return 0;
}
-int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
+int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
{
- if (reg < 0 || reg > 0x3f)
+ if (reg > 0x3f)
return 1;
reg += 0x40; /* 0x40 upwards are registers. */
if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */
@@ -244,9 +244,9 @@ int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
return 0;
}
-int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
+int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value)
{
- if (reg < 0 || reg > 0x3f)
+ if (reg > 0x3f)
return 1;
reg += 0x40; /* 0x40 upwards are registers. */
outl(reg, emu->port + A_IOCFG);
@@ -261,7 +261,7 @@ int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
/* Each Destination has one and only one Source,
* but one Source can feed any number of Destinations simultaneously.
*/
-int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src)
+int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src)
{
snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index 4f18f7e8bcf..3c114b45e0b 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Routines for IRQ control of EMU10K1 chips
*
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 4fcaefe5a3c..48097c6bb15 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
*
* EMU10K1 memory page allocation (PTB area)
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 7ee19c63c2c..d619a3842cd 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -124,11 +124,12 @@
/* hardware definition */
static struct snd_pcm_hardware snd_p16v_playback_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_RESUME |
- SNDRV_PCM_INFO_MMAP_VALID),
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_RESUME |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START,
.formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
.rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100,
.rate_min = 44100,
@@ -207,6 +208,11 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea
if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
return err;
+ runtime->sync.id32[0] = substream->pcm->card->number;
+ runtime->sync.id32[1] = 'P';
+ runtime->sync.id32[2] = 16;
+ runtime->sync.id32[3] = 'V';
+
return 0;
}
/* open_capture callback */
@@ -448,6 +454,9 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
break;
}
snd_pcm_group_for_each_entry(s, substream) {
+ if (snd_pcm_substream_chip(s) != emu ||
+ s->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ continue;
runtime = s->runtime;
epcm = runtime->private_data;
channel = substream->pcm->device-emu->p16v_device_offset;
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 1db50fe6147..04fa8492abb 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Creative Labs, Inc.
* Lee Revell <rlrevell@joe-job.com>
* Routines for control of EMU10K1 chips - voice manager
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 21cb4268a59..b958f869cb1 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1,6 +1,6 @@
/*
* Driver for Ensoniq ES1370/ES1371 AudioPCI soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
* Thomas Sailer <sailer@ife.ee.ethz.ch>
*
* This program is free software; you can redistribute it and/or modify
@@ -61,7 +61,7 @@
#endif
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Thomas Sailer <sailer@ife.ee.ethz.ch>");
MODULE_LICENSE("GPL");
#ifdef CHIP1370
MODULE_DESCRIPTION("Ensoniq AudioPCI ES1370");
@@ -1419,15 +1419,7 @@ static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol,
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \
.get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put }
-static int snd_es1371_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es1371_spdif_info snd_ctl_boolean_mono_info
static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1489,15 +1481,7 @@ static struct snd_kcontrol_new snd_es1371_mixer_spdif[] __devinitdata = {
};
-static int snd_es1373_rear_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es1373_rear_info snd_ctl_boolean_mono_info
static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1542,15 +1526,7 @@ static struct snd_kcontrol_new snd_ens1373_rear __devinitdata =
.put = snd_es1373_rear_put,
};
-static int snd_es1373_line_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es1373_line_info snd_ctl_boolean_mono_info
static int snd_es1373_line_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1707,15 +1683,7 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
.get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
.private_value = mask }
-static int snd_ensoniq_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ensoniq_control_info snd_ctl_boolean_mono_info
static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index fec29a10894..fb25abe68a0 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1,7 +1,7 @@
/*
* Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard
* Copyright (c) by Jaromir Koutek <miri@punknet.cz>,
- * Jaroslav Kysela <perex@suse.cz>,
+ * Jaroslav Kysela <perex@perex.cz>,
* Thomas Sailer <sailer@ife.ee.ethz.ch>,
* Abramo Bagnara <abramo@alsa-project.org>,
* Markus Gruber <gruber@eikon.tum.de>
@@ -1066,15 +1066,7 @@ static int snd_es1938_put_mux(struct snd_kcontrol *kcontrol,
return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;
}
-static int snd_es1938_info_spatializer_enable(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es1938_info_spatializer_enable snd_ctl_boolean_mono_info
static int snd_es1938_get_spatializer_enable(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1120,15 +1112,7 @@ static int snd_es1938_get_hw_volume(struct snd_kcontrol *kcontrol,
return 0;
}
-static int snd_es1938_info_hw_switch(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_es1938_info_hw_switch snd_ctl_boolean_stereo_info
static int snd_es1938_get_hw_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 2faf009076b..d69b11d1f99 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -843,10 +843,9 @@ static void snd_es1968_bob_dec(struct es1968 *chip)
snd_es1968_bob_stop(chip);
else if (chip->bob_freq > ESM_BOB_FREQ) {
/* check reduction of timer frequency */
- struct list_head *p;
int max_freq = ESM_BOB_FREQ;
- list_for_each(p, &chip->substream_list) {
- struct esschan *es = list_entry(p, struct esschan, list);
+ struct esschan *es;
+ list_for_each_entry(es, &chip->substream_list, list) {
if (max_freq < es->bob_freq)
max_freq = es->bob_freq;
}
@@ -1316,12 +1315,11 @@ static struct snd_pcm_hardware snd_es1968_capture = {
static int calc_available_memory_size(struct es1968 *chip)
{
- struct list_head *p;
int max_size = 0;
-
+ struct esm_memory *buf;
+
mutex_lock(&chip->memory_mutex);
- list_for_each(p, &chip->buf_list) {
- struct esm_memory *buf = list_entry(p, struct esm_memory, list);
+ list_for_each_entry(buf, &chip->buf_list, list) {
if (buf->empty && buf->buf.bytes > max_size)
max_size = buf->buf.bytes;
}
@@ -1335,12 +1333,10 @@ static int calc_available_memory_size(struct es1968 *chip)
static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
{
struct esm_memory *buf;
- struct list_head *p;
-
+
size = ALIGN(size, ESM_MEM_ALIGN);
mutex_lock(&chip->memory_mutex);
- list_for_each(p, &chip->buf_list) {
- buf = list_entry(p, struct esm_memory, list);
+ list_for_each_entry(buf, &chip->buf_list, list) {
if (buf->empty && buf->buf.bytes >= size)
goto __found;
}
@@ -1938,10 +1934,9 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
}
if (event & ESM_SOUND_IRQ) {
- struct list_head *p;
+ struct esschan *es;
spin_lock(&chip->substream_lock);
- list_for_each(p, &chip->substream_list) {
- struct esschan *es = list_entry(p, struct esschan, list);
+ list_for_each_entry(es, &chip->substream_list, list) {
if (es->running)
snd_es1968_update_pcm(chip, es);
}
@@ -2345,7 +2340,7 @@ static int es1968_resume(struct pci_dev *pci)
{
struct snd_card *card = pci_get_drvdata(pci);
struct es1968 *chip = card->private_data;
- struct list_head *p;
+ struct esschan *es;
if (! chip->do_pm)
return 0;
@@ -2374,8 +2369,7 @@ static int es1968_resume(struct pci_dev *pci)
/* restore ac97 state */
snd_ac97_resume(chip->ac97);
- list_for_each(p, &chip->substream_list) {
- struct esschan *es = list_entry(p, struct esschan, list);
+ list_for_each_entry(es, &chip->substream_list, list) {
switch (es->mode) {
case ESM_MODE_PLAY:
snd_es1968_playback_setup(chip, es, es->substream->runtime);
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 11015178e20..9939109f05a 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1,6 +1,6 @@
/*
* The driver for the ForteMedia FM801 based soundcards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* Support FM only card by Andy Shevchenko <andy@smile.org.ua>
*
@@ -42,7 +42,7 @@
#define TEA575X_RADIO 1
#endif
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("ForteMedia FM801");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801},"
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index b2484bbdcc1..ab0c726d648 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,19 +1,18 @@
-snd-hda-intel-objs := hda_intel.o
+snd-hda-intel-y := hda_intel.o
# since snd-hda-intel is the only driver using hda-codec,
# merge it into a single module although it was originally
# designed to be individual modules
-snd-hda-intel-objs += hda_codec.o \
- hda_generic.o \
- patch_realtek.o \
- patch_cmedia.o \
- patch_analog.o \
- patch_sigmatel.o \
- patch_si3054.o \
- patch_atihdmi.o \
- patch_conexant.o \
- patch_via.o
-ifdef CONFIG_PROC_FS
-snd-hda-intel-objs += hda_proc.o
-endif
+snd-hda-intel-y += hda_codec.o
+snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
+snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
+snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ANALOG) += patch_analog.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += patch_sigmatel.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o
+snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index f87f8f08895..187533e477c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -31,7 +31,15 @@
#include <sound/tlv.h>
#include <sound/initval.h>
#include "hda_local.h"
-
+#include <sound/hda_hwdep.h>
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+/* define this option here to hide as static */
+static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
+module_param(power_save, int, 0644);
+MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
+ "(in second, 0 = disable).");
+#endif
/*
* vendor / preset table
@@ -59,6 +67,13 @@ static struct hda_vendor_id hda_vendor_ids[] = {
#include "hda_patch.h"
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static void hda_power_work(struct work_struct *work);
+static void hda_keep_power_on(struct hda_codec *codec);
+#else
+static inline void hda_keep_power_on(struct hda_codec *codec) {}
+#endif
+
/**
* snd_hda_codec_read - send a command and get the response
* @codec: the HDA codec
@@ -76,12 +91,14 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
unsigned int verb, unsigned int parm)
{
unsigned int res;
+ snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex);
if (!codec->bus->ops.command(codec, nid, direct, verb, parm))
res = codec->bus->ops.get_response(codec);
else
res = (unsigned int)-1;
mutex_unlock(&codec->bus->cmd_mutex);
+ snd_hda_power_down(codec);
return res;
}
@@ -101,9 +118,11 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned int verb, unsigned int parm)
{
int err;
+ snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex);
err = codec->bus->ops.command(codec, nid, direct, verb, parm);
mutex_unlock(&codec->bus->cmd_mutex);
+ snd_hda_power_down(codec);
return err;
}
@@ -136,6 +155,8 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
unsigned int parm;
parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT);
+ if (parm == -1)
+ return 0;
*start_id = (parm >> 16) & 0x7fff;
return (int)(parm & 0x7fff);
}
@@ -387,6 +408,13 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
return 0;
}
+#ifdef CONFIG_SND_HDA_GENERIC
+#define is_generic_config(codec) \
+ (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic"))
+#else
+#define is_generic_config(codec) 0
+#endif
+
/*
* find a matching codec preset
*/
@@ -395,7 +423,7 @@ find_codec_preset(struct hda_codec *codec)
{
const struct hda_codec_preset **tbl, *preset;
- if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic"))
+ if (is_generic_config(codec))
return NULL; /* use the generic parser */
for (tbl = hda_preset_tables; *tbl; tbl++) {
@@ -486,6 +514,10 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
}
+static void init_hda_cache(struct hda_cache_rec *cache,
+ unsigned int record_size);
+static void free_hda_cache(struct hda_cache_rec *cache);
+
/*
* codec destructor
*/
@@ -493,17 +525,20 @@ static void snd_hda_codec_free(struct hda_codec *codec)
{
if (!codec)
return;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ cancel_delayed_work(&codec->power_work);
+ flush_scheduled_work();
+#endif
list_del(&codec->list);
codec->bus->caddr_tbl[codec->addr] = NULL;
if (codec->patch_ops.free)
codec->patch_ops.free(codec);
- kfree(codec->amp_info);
+ free_hda_cache(&codec->amp_cache);
+ free_hda_cache(&codec->cmd_cache);
kfree(codec->wcaps);
kfree(codec);
}
-static void init_amp_hash(struct hda_codec *codec);
-
/**
* snd_hda_codec_new - create a HDA codec
* @bus: the bus to assign
@@ -537,7 +572,17 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
codec->bus = bus;
codec->addr = codec_addr;
mutex_init(&codec->spdif_mutex);
- init_amp_hash(codec);
+ init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
+ init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
+ /* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
+ * the caller has to power down appropriatley after initialization
+ * phase.
+ */
+ hda_keep_power_on(codec);
+#endif
list_add_tail(&codec->list, &bus->codec_list);
bus->caddr_tbl[codec_addr] = codec;
@@ -581,10 +626,26 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
snd_hda_get_codec_name(codec, bus->card->mixername,
sizeof(bus->card->mixername));
- if (codec->preset && codec->preset->patch)
- err = codec->preset->patch(codec);
- else
+#ifdef CONFIG_SND_HDA_GENERIC
+ if (is_generic_config(codec)) {
err = snd_hda_parse_generic_codec(codec);
+ goto patched;
+ }
+#endif
+ if (codec->preset && codec->preset->patch) {
+ err = codec->preset->patch(codec);
+ goto patched;
+ }
+
+ /* call the default parser */
+#ifdef CONFIG_SND_HDA_GENERIC
+ err = snd_hda_parse_generic_codec(codec);
+#else
+ printk(KERN_ERR "hda-codec: No codec parser is available\n");
+ err = -ENODEV;
+#endif
+
+ patched:
if (err < 0) {
snd_hda_codec_free(codec);
return err;
@@ -594,6 +655,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
init_unsol_queue(bus);
snd_hda_codec_proc_new(codec);
+#ifdef CONFIG_SND_HDA_HWDEP
+ snd_hda_create_hwdep(codec);
+#endif
sprintf(component, "HDA:%08x", codec->vendor_id);
snd_component_add(codec->bus->card, component);
@@ -637,59 +701,72 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
/* initialize the hash table */
-static void __devinit init_amp_hash(struct hda_codec *codec)
+static void __devinit init_hda_cache(struct hda_cache_rec *cache,
+ unsigned int record_size)
+{
+ memset(cache, 0, sizeof(*cache));
+ memset(cache->hash, 0xff, sizeof(cache->hash));
+ cache->record_size = record_size;
+}
+
+static void free_hda_cache(struct hda_cache_rec *cache)
{
- memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
- codec->num_amp_entries = 0;
- codec->amp_info_size = 0;
- codec->amp_info = NULL;
+ kfree(cache->buffer);
}
/* query the hash. allocate an entry if not found. */
-static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
+static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
+ u32 key)
{
- u16 idx = key % (u16)ARRAY_SIZE(codec->amp_hash);
- u16 cur = codec->amp_hash[idx];
- struct hda_amp_info *info;
+ u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
+ u16 cur = cache->hash[idx];
+ struct hda_cache_head *info;
while (cur != 0xffff) {
- info = &codec->amp_info[cur];
+ info = (struct hda_cache_head *)(cache->buffer +
+ cur * cache->record_size);
if (info->key == key)
return info;
cur = info->next;
}
/* add a new hash entry */
- if (codec->num_amp_entries >= codec->amp_info_size) {
+ if (cache->num_entries >= cache->size) {
/* reallocate the array */
- int new_size = codec->amp_info_size + 64;
- struct hda_amp_info *new_info;
- new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
- GFP_KERNEL);
- if (!new_info) {
+ unsigned int new_size = cache->size + 64;
+ void *new_buffer;
+ new_buffer = kcalloc(new_size, cache->record_size, GFP_KERNEL);
+ if (!new_buffer) {
snd_printk(KERN_ERR "hda_codec: "
"can't malloc amp_info\n");
return NULL;
}
- if (codec->amp_info) {
- memcpy(new_info, codec->amp_info,
- codec->amp_info_size *
- sizeof(struct hda_amp_info));
- kfree(codec->amp_info);
+ if (cache->buffer) {
+ memcpy(new_buffer, cache->buffer,
+ cache->size * cache->record_size);
+ kfree(cache->buffer);
}
- codec->amp_info_size = new_size;
- codec->amp_info = new_info;
+ cache->size = new_size;
+ cache->buffer = new_buffer;
}
- cur = codec->num_amp_entries++;
- info = &codec->amp_info[cur];
+ cur = cache->num_entries++;
+ info = (struct hda_cache_head *)(cache->buffer +
+ cur * cache->record_size);
info->key = key;
- info->status = 0; /* not initialized yet */
- info->next = codec->amp_hash[idx];
- codec->amp_hash[idx] = cur;
+ info->val = 0;
+ info->next = cache->hash[idx];
+ cache->hash[idx] = cur;
return info;
}
+/* query and allocate an amp hash entry */
+static inline struct hda_amp_info *
+get_alloc_amp_hash(struct hda_codec *codec, u32 key)
+{
+ return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key);
+}
+
/*
* query AMP capabilities for the given widget and direction
*/
@@ -700,7 +777,7 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
if (!info)
return 0;
- if (!(info->status & INFO_AMP_CAPS)) {
+ if (!(info->head.val & INFO_AMP_CAPS)) {
if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
nid = codec->afg;
info->amp_caps = snd_hda_param_read(codec, nid,
@@ -708,7 +785,7 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
AC_PAR_AMP_OUT_CAP :
AC_PAR_AMP_IN_CAP);
if (info->amp_caps)
- info->status |= INFO_AMP_CAPS;
+ info->head.val |= INFO_AMP_CAPS;
}
return info->amp_caps;
}
@@ -722,7 +799,7 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
if (!info)
return -EINVAL;
info->amp_caps = caps;
- info->status |= INFO_AMP_CAPS;
+ info->head.val |= INFO_AMP_CAPS;
return 0;
}
@@ -736,7 +813,7 @@ static unsigned int get_vol_mute(struct hda_codec *codec,
{
u32 val, parm;
- if (info->status & INFO_AMP_VOL(ch))
+ if (info->head.val & INFO_AMP_VOL(ch))
return info->vol[ch];
parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
@@ -745,7 +822,7 @@ static unsigned int get_vol_mute(struct hda_codec *codec,
val = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_AMP_GAIN_MUTE, parm);
info->vol[ch] = val & 0xff;
- info->status |= INFO_AMP_VOL(ch);
+ info->head.val |= INFO_AMP_VOL(ch);
return info->vol[ch];
}
@@ -792,12 +869,50 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
return 0;
val &= mask;
val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
- if (info->vol[ch] == val && !codec->in_resume)
+ if (info->vol[ch] == val)
return 0;
put_vol_mute(codec, info, nid, ch, direction, idx, val);
return 1;
}
+/*
+ * update the AMP stereo with the same mask and value
+ */
+int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
+ int direction, int idx, int mask, int val)
+{
+ int ch, ret = 0;
+ for (ch = 0; ch < 2; ch++)
+ ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
+ idx, mask, val);
+ return ret;
+}
+
+#ifdef SND_HDA_NEEDS_RESUME
+/* resume the all amp commands from the cache */
+void snd_hda_codec_resume_amp(struct hda_codec *codec)
+{
+ struct hda_amp_info *buffer = codec->amp_cache.buffer;
+ int i;
+
+ for (i = 0; i < codec->amp_cache.size; i++, buffer++) {
+ u32 key = buffer->head.key;
+ hda_nid_t nid;
+ unsigned int idx, dir, ch;
+ if (!key)
+ continue;
+ nid = key & 0xff;
+ idx = (key >> 16) & 0xff;
+ dir = (key >> 24) & 0xff;
+ for (ch = 0; ch < 2; ch++) {
+ if (!(buffer->head.val & INFO_AMP_VOL(ch)))
+ continue;
+ put_vol_mute(codec, buffer, nid, ch, dir, idx,
+ buffer->vol[ch]);
+ }
+ }
+}
+#endif /* SND_HDA_NEEDS_RESUME */
/*
* AMP control callbacks
@@ -844,9 +959,11 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
if (chs & 1)
- *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f;
+ *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx)
+ & HDA_AMP_VOLMASK;
if (chs & 2)
- *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f;
+ *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx)
+ & HDA_AMP_VOLMASK;
return 0;
}
@@ -861,6 +978,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
int change = 0;
+ snd_hda_power_up(codec);
if (chs & 1) {
change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
0x7f, *valp);
@@ -869,6 +987,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
if (chs & 2)
change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
0x7f, *valp);
+ snd_hda_power_down(codec);
return change;
}
@@ -923,10 +1042,10 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
if (chs & 1)
*valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
- 0x80) ? 0 : 1;
+ HDA_AMP_MUTE) ? 0 : 1;
if (chs & 2)
*valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
- 0x80) ? 0 : 1;
+ HDA_AMP_MUTE) ? 0 : 1;
return 0;
}
@@ -941,15 +1060,22 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
int change = 0;
+ snd_hda_power_up(codec);
if (chs & 1) {
change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
- 0x80, *valp ? 0 : 0x80);
+ HDA_AMP_MUTE,
+ *valp ? 0 : HDA_AMP_MUTE);
valp++;
}
if (chs & 2)
change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
- 0x80, *valp ? 0 : 0x80);
-
+ HDA_AMP_MUTE,
+ *valp ? 0 : HDA_AMP_MUTE);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (codec->patch_ops.check_power_status)
+ codec->patch_ops.check_power_status(codec, nid);
+#endif
+ snd_hda_power_down(codec);
return change;
}
@@ -1002,6 +1128,93 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
}
/*
+ * generic bound volume/swtich controls
+ */
+int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct hda_bind_ctls *c;
+ int err;
+
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
+ mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ kcontrol->private_value = *c->values;
+ err = c->ops->info(kcontrol, uinfo);
+ kcontrol->private_value = (long)c;
+ mutex_unlock(&codec->spdif_mutex);
+ return err;
+}
+
+int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct hda_bind_ctls *c;
+ int err;
+
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
+ mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ kcontrol->private_value = *c->values;
+ err = c->ops->get(kcontrol, ucontrol);
+ kcontrol->private_value = (long)c;
+ mutex_unlock(&codec->spdif_mutex);
+ return err;
+}
+
+int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct hda_bind_ctls *c;
+ unsigned long *vals;
+ int err = 0, change = 0;
+
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
+ mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ for (vals = c->values; *vals; vals++) {
+ kcontrol->private_value = *vals;
+ err = c->ops->put(kcontrol, ucontrol);
+ if (err < 0)
+ break;
+ change |= err;
+ }
+ kcontrol->private_value = (long)c;
+ mutex_unlock(&codec->spdif_mutex);
+ return err < 0 ? err : change;
+}
+
+int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+ unsigned int size, unsigned int __user *tlv)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct hda_bind_ctls *c;
+ int err;
+
+ c = (struct hda_bind_ctls *)kcontrol->private_value;
+ mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ kcontrol->private_value = *c->values;
+ err = c->ops->tlv(kcontrol, op_flag, size, tlv);
+ kcontrol->private_value = (long)c;
+ mutex_unlock(&codec->spdif_mutex);
+ return err;
+}
+
+struct hda_ctl_ops snd_hda_bind_vol = {
+ .info = snd_hda_mixer_amp_volume_info,
+ .get = snd_hda_mixer_amp_volume_get,
+ .put = snd_hda_mixer_amp_volume_put,
+ .tlv = snd_hda_mixer_amp_tlv
+};
+
+struct hda_ctl_ops snd_hda_bind_sw = {
+ .info = snd_hda_mixer_amp_switch_info,
+ .get = snd_hda_mixer_amp_switch_get,
+ .put = snd_hda_mixer_amp_switch_put,
+ .tlv = snd_hda_mixer_amp_tlv
+};
+
+/*
* SPDIF out controls
*/
@@ -1118,26 +1331,20 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
change = codec->spdif_ctls != val;
codec->spdif_ctls = val;
- if (change || codec->in_resume) {
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- val & 0xff);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2,
- val >> 8);
+ if (change) {
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ val & 0xff);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_2,
+ val >> 8);
}
mutex_unlock(&codec->spdif_mutex);
return change;
}
-static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hda_spdif_out_switch_info snd_ctl_boolean_mono_info
static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1161,17 +1368,16 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.integer.value[0])
val |= AC_DIG1_ENABLE;
change = codec->spdif_ctls != val;
- if (change || codec->in_resume) {
+ if (change) {
codec->spdif_ctls = val;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- val & 0xff);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_1,
+ val & 0xff);
/* unmute amp switch (if any) */
if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
(val & AC_DIG1_ENABLE))
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
- AC_AMP_SET_OUTPUT);
+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, 0);
}
mutex_unlock(&codec->spdif_mutex);
return change;
@@ -1219,8 +1425,7 @@ static struct snd_kcontrol_new dig_mixes[] = {
*
* Returns 0 if successful, or a negative error code.
*/
-int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
- hda_nid_t nid)
+int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
{
int err;
struct snd_kcontrol *kctl;
@@ -1264,10 +1469,10 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
mutex_lock(&codec->spdif_mutex);
change = codec->spdif_in_enable != val;
- if (change || codec->in_resume) {
+ if (change) {
codec->spdif_in_enable = val;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- val);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_1, val);
}
mutex_unlock(&codec->spdif_mutex);
return change;
@@ -1318,8 +1523,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
*
* Returns 0 if successful, or a negative error code.
*/
-int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec,
- hda_nid_t nid)
+int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
{
int err;
struct snd_kcontrol *kctl;
@@ -1338,6 +1542,79 @@ int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec,
return 0;
}
+#ifdef SND_HDA_NEEDS_RESUME
+/*
+ * command cache
+ */
+
+/* build a 32bit cache key with the widget id and the command parameter */
+#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
+#define get_cmd_cache_nid(key) ((key) & 0xff)
+#define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff)
+
+/**
+ * snd_hda_codec_write_cache - send a single command with caching
+ * @codec: the HDA codec
+ * @nid: NID to send the command
+ * @direct: direct flag
+ * @verb: the verb to send
+ * @parm: the parameter for the verb
+ *
+ * Send a single command without waiting for response.
+ *
+ * Returns 0 if successful, or a negative error code.
+ */
+int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
+ int direct, unsigned int verb, unsigned int parm)
+{
+ int err;
+ snd_hda_power_up(codec);
+ mutex_lock(&codec->bus->cmd_mutex);
+ err = codec->bus->ops.command(codec, nid, direct, verb, parm);
+ if (!err) {
+ struct hda_cache_head *c;
+ u32 key = build_cmd_cache_key(nid, verb);
+ c = get_alloc_hash(&codec->cmd_cache, key);
+ if (c)
+ c->val = parm;
+ }
+ mutex_unlock(&codec->bus->cmd_mutex);
+ snd_hda_power_down(codec);
+ return err;
+}
+
+/* resume the all commands from the cache */
+void snd_hda_codec_resume_cache(struct hda_codec *codec)
+{
+ struct hda_cache_head *buffer = codec->cmd_cache.buffer;
+ int i;
+
+ for (i = 0; i < codec->cmd_cache.size; i++, buffer++) {
+ u32 key = buffer->key;
+ if (!key)
+ continue;
+ snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0,
+ get_cmd_cache_cmd(key), buffer->val);
+ }
+}
+
+/**
+ * snd_hda_sequence_write_cache - sequence writes with caching
+ * @codec: the HDA codec
+ * @seq: VERB array to send
+ *
+ * Send the commands sequentially from the given array.
+ * Thte commands are recorded on cache for power-save and resume.
+ * The array must be terminated with NID=0.
+ */
+void snd_hda_sequence_write_cache(struct hda_codec *codec,
+ const struct hda_verb *seq)
+{
+ for (; seq->nid; seq++)
+ snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
+ seq->param);
+}
+#endif /* SND_HDA_NEEDS_RESUME */
/*
* set power state of the codec
@@ -1345,23 +1622,86 @@ int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec,
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
unsigned int power_state)
{
- hda_nid_t nid, nid_start;
- int nodes;
+ hda_nid_t nid;
+ int i;
snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE,
power_state);
- nodes = snd_hda_get_sub_nodes(codec, fg, &nid_start);
- for (nid = nid_start; nid < nodes + nid_start; nid++) {
- if (get_wcaps(codec, nid) & AC_WCAP_POWER)
+ nid = codec->start_nid;
+ for (i = 0; i < codec->num_nodes; i++, nid++) {
+ if (get_wcaps(codec, nid) & AC_WCAP_POWER) {
+ unsigned int pincap;
+ /*
+ * don't power down the widget if it controls eapd
+ * and EAPD_BTLENABLE is set.
+ */
+ pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
+ if (pincap & AC_PINCAP_EAPD) {
+ int eapd = snd_hda_codec_read(codec, nid,
+ 0, AC_VERB_GET_EAPD_BTLENABLE, 0);
+ eapd &= 0x02;
+ if (power_state == AC_PWRST_D3 && eapd)
+ continue;
+ }
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_POWER_STATE,
power_state);
+ }
}
- if (power_state == AC_PWRST_D0)
+ if (power_state == AC_PWRST_D0) {
+ unsigned long end_time;
+ int state;
msleep(10);
+ /* wait until the codec reachs to D0 */
+ end_time = jiffies + msecs_to_jiffies(500);
+ do {
+ state = snd_hda_codec_read(codec, fg, 0,
+ AC_VERB_GET_POWER_STATE, 0);
+ if (state == power_state)
+ break;
+ msleep(1);
+ } while (time_after_eq(end_time, jiffies));
+ }
+}
+
+#ifdef SND_HDA_NEEDS_RESUME
+/*
+ * call suspend and power-down; used both from PM and power-save
+ */
+static void hda_call_codec_suspend(struct hda_codec *codec)
+{
+ if (codec->patch_ops.suspend)
+ codec->patch_ops.suspend(codec, PMSG_SUSPEND);
+ hda_set_power_state(codec,
+ codec->afg ? codec->afg : codec->mfg,
+ AC_PWRST_D3);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ cancel_delayed_work(&codec->power_work);
+ codec->power_on = 0;
+ codec->power_transition = 0;
+#endif
+}
+
+/*
+ * kick up codec; used both from PM and power-save
+ */
+static void hda_call_codec_resume(struct hda_codec *codec)
+{
+ hda_set_power_state(codec,
+ codec->afg ? codec->afg : codec->mfg,
+ AC_PWRST_D0);
+ if (codec->patch_ops.resume)
+ codec->patch_ops.resume(codec);
+ else {
+ if (codec->patch_ops.init)
+ codec->patch_ops.init(codec);
+ snd_hda_codec_resume_amp(codec);
+ snd_hda_codec_resume_cache(codec);
+ }
}
+#endif /* SND_HDA_NEEDS_RESUME */
/**
@@ -1376,28 +1716,24 @@ int __devinit snd_hda_build_controls(struct hda_bus *bus)
{
struct hda_codec *codec;
- /* build controls */
list_for_each_entry(codec, &bus->codec_list, list) {
- int err;
- if (!codec->patch_ops.build_controls)
- continue;
- err = codec->patch_ops.build_controls(codec);
- if (err < 0)
- return err;
- }
-
- /* initialize */
- list_for_each_entry(codec, &bus->codec_list, list) {
- int err;
+ int err = 0;
+ /* fake as if already powered-on */
+ hda_keep_power_on(codec);
+ /* then fire up */
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0);
- if (!codec->patch_ops.init)
- continue;
- err = codec->patch_ops.init(codec);
+ /* continue to initialize... */
+ if (codec->patch_ops.init)
+ err = codec->patch_ops.init(codec);
+ if (!err && codec->patch_ops.build_controls)
+ err = codec->patch_ops.build_controls(codec);
+ snd_hda_power_down(codec);
if (err < 0)
return err;
}
+
return 0;
}
@@ -1789,9 +2125,9 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
*
* If no entries are matching, the function returns a negative value.
*/
-int __devinit snd_hda_check_board_config(struct hda_codec *codec,
- int num_configs, const char **models,
- const struct snd_pci_quirk *tbl)
+int snd_hda_check_board_config(struct hda_codec *codec,
+ int num_configs, const char **models,
+ const struct snd_pci_quirk *tbl)
{
if (codec->bus->modelname && models) {
int i;
@@ -1841,10 +2177,9 @@ int __devinit snd_hda_check_board_config(struct hda_codec *codec,
*
* Returns 0 if successful, or a negative error code.
*/
-int __devinit snd_hda_add_new_ctls(struct hda_codec *codec,
- struct snd_kcontrol_new *knew)
+int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
{
- int err;
+ int err;
for (; knew->name; knew++) {
struct snd_kcontrol *kctl;
@@ -1867,6 +2202,93 @@ int __devinit snd_hda_add_new_ctls(struct hda_codec *codec,
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state);
+
+static void hda_power_work(struct work_struct *work)
+{
+ struct hda_codec *codec =
+ container_of(work, struct hda_codec, power_work.work);
+
+ if (!codec->power_on || codec->power_count) {
+ codec->power_transition = 0;
+ return;
+ }
+
+ hda_call_codec_suspend(codec);
+ if (codec->bus->ops.pm_notify)
+ codec->bus->ops.pm_notify(codec);
+}
+
+static void hda_keep_power_on(struct hda_codec *codec)
+{
+ codec->power_count++;
+ codec->power_on = 1;
+}
+
+void snd_hda_power_up(struct hda_codec *codec)
+{
+ codec->power_count++;
+ if (codec->power_on || codec->power_transition)
+ return;
+
+ codec->power_on = 1;
+ if (codec->bus->ops.pm_notify)
+ codec->bus->ops.pm_notify(codec);
+ hda_call_codec_resume(codec);
+ cancel_delayed_work(&codec->power_work);
+ codec->power_transition = 0;
+}
+
+void snd_hda_power_down(struct hda_codec *codec)
+{
+ --codec->power_count;
+ if (!codec->power_on || codec->power_count || codec->power_transition)
+ return;
+ if (power_save) {
+ codec->power_transition = 1; /* avoid reentrance */
+ schedule_delayed_work(&codec->power_work,
+ msecs_to_jiffies(power_save * 1000));
+ }
+}
+
+int snd_hda_check_amp_list_power(struct hda_codec *codec,
+ struct hda_loopback_check *check,
+ hda_nid_t nid)
+{
+ struct hda_amp_list *p;
+ int ch, v;
+
+ if (!check->amplist)
+ return 0;
+ for (p = check->amplist; p->nid; p++) {
+ if (p->nid == nid)
+ break;
+ }
+ if (!p->nid)
+ return 0; /* nothing changed */
+
+ for (p = check->amplist; p->nid; p++) {
+ for (ch = 0; ch < 2; ch++) {
+ v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
+ p->idx);
+ if (!(v & HDA_AMP_MUTE) && v > 0) {
+ if (!check->power_on) {
+ check->power_on = 1;
+ snd_hda_power_up(codec);
+ }
+ return 1;
+ }
+ }
+ }
+ if (check->power_on) {
+ check->power_on = 0;
+ snd_hda_power_down(codec);
+ }
+ return 0;
+}
+#endif
/*
* Channel mode helper
@@ -1913,12 +2335,12 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
mode = ucontrol->value.enumerated.item[0];
snd_assert(mode < num_chmodes, return -EINVAL);
- if (*max_channelsp == chmode[mode].channels && !codec->in_resume)
+ if (*max_channelsp == chmode[mode].channels)
return 0;
/* change the current channel setting */
*max_channelsp = chmode[mode].channels;
if (chmode[mode].sequence)
- snd_hda_sequence_write(codec, chmode[mode].sequence);
+ snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
return 1;
}
@@ -1933,6 +2355,8 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux,
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = imux->num_items;
+ if (!imux->num_items)
+ return 0;
index = uinfo->value.enumerated.item;
if (index >= imux->num_items)
index = imux->num_items - 1;
@@ -1948,13 +2372,15 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
{
unsigned int idx;
+ if (!imux->num_items)
+ return 0;
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && !codec->in_resume)
+ if (*cur_val == idx)
return 0;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
- imux->items[idx].index);
+ snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
+ imux->items[idx].index);
*cur_val = idx;
return 1;
}
@@ -2118,7 +2544,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
* Helper for automatic ping configuration
*/
-static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
+static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
{
for (; *list; list++)
if (*list == nid)
@@ -2169,9 +2595,9 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
* The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
* respectively.
*/
-int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec,
- struct auto_pin_cfg *cfg,
- hda_nid_t *ignore_nids)
+int snd_hda_parse_pin_def_config(struct hda_codec *codec,
+ struct auto_pin_cfg *cfg,
+ hda_nid_t *ignore_nids)
{
hda_nid_t nid, nid_start;
int nodes;
@@ -2371,13 +2797,12 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
{
struct hda_codec *codec;
- /* FIXME: should handle power widget capabilities */
list_for_each_entry(codec, &bus->codec_list, list) {
- if (codec->patch_ops.suspend)
- codec->patch_ops.suspend(codec, state);
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D3);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!codec->power_on)
+ continue;
+#endif
+ hda_call_codec_suspend(codec);
}
return 0;
}
@@ -2388,76 +2813,30 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
* @state: resume state
*
* Returns 0 if successful.
+ *
+ * This fucntion is defined only when POWER_SAVE isn't set.
+ * In the power-save mode, the codec is resumed dynamically.
*/
int snd_hda_resume(struct hda_bus *bus)
{
struct hda_codec *codec;
list_for_each_entry(codec, &bus->codec_list, list) {
- hda_set_power_state(codec,
- codec->afg ? codec->afg : codec->mfg,
- AC_PWRST_D0);
- if (codec->patch_ops.resume)
- codec->patch_ops.resume(codec);
+ if (snd_hda_codec_needs_resume(codec))
+ hda_call_codec_resume(codec);
}
return 0;
}
-
-/**
- * snd_hda_resume_ctls - resume controls in the new control list
- * @codec: the HDA codec
- * @knew: the array of struct snd_kcontrol_new
- *
- * This function resumes the mixer controls in the struct snd_kcontrol_new array,
- * originally for snd_hda_add_new_ctls().
- * The array must be terminated with an empty entry as terminator.
- */
-int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+int snd_hda_codecs_inuse(struct hda_bus *bus)
{
- struct snd_ctl_elem_value *val;
+ struct hda_codec *codec;
- val = kmalloc(sizeof(*val), GFP_KERNEL);
- if (!val)
- return -ENOMEM;
- codec->in_resume = 1;
- for (; knew->name; knew++) {
- int i, count;
- count = knew->count ? knew->count : 1;
- for (i = 0; i < count; i++) {
- memset(val, 0, sizeof(*val));
- val->id.iface = knew->iface;
- val->id.device = knew->device;
- val->id.subdevice = knew->subdevice;
- strcpy(val->id.name, knew->name);
- val->id.index = knew->index ? knew->index : i;
- /* Assume that get callback reads only from cache,
- * not accessing to the real hardware
- */
- if (snd_ctl_elem_read(codec->bus->card, val) < 0)
- continue;
- snd_ctl_elem_write(codec->bus->card, NULL, val);
- }
+ list_for_each_entry(codec, &bus->codec_list, list) {
+ if (snd_hda_codec_needs_resume(codec))
+ return 1;
}
- codec->in_resume = 0;
- kfree(val);
return 0;
}
-
-/**
- * snd_hda_resume_spdif_out - resume the digital out
- * @codec: the HDA codec
- */
-int snd_hda_resume_spdif_out(struct hda_codec *codec)
-{
- return snd_hda_resume_ctls(codec, dig_mixes);
-}
-
-/**
- * snd_hda_resume_spdif_in - resume the digital in
- * @codec: the HDA codec
- */
-int snd_hda_resume_spdif_in(struct hda_codec *codec)
-{
- return snd_hda_resume_ctls(codec, dig_in_ctls);
-}
+#endif
#endif
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 56c26e7ccdf..2bce925d84e 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -24,6 +24,11 @@
#include <sound/info.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/hwdep.h>
+
+#if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE)
+#define SND_HDA_NEEDS_RESUME /* resume control code is required */
+#endif
/*
* nodes
@@ -199,7 +204,9 @@ enum {
#define AC_AMPCAP_OFFSET_SHIFT 0
#define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */
#define AC_AMPCAP_NUM_STEPS_SHIFT 8
-#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB in 0.25dB */
+#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB
+ * in 0.25dB
+ */
#define AC_AMPCAP_STEP_SIZE_SHIFT 16
#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
#define AC_AMPCAP_MUTE_SHIFT 31
@@ -409,6 +416,10 @@ struct hda_bus_ops {
unsigned int (*get_response)(struct hda_codec *codec);
/* free the private data */
void (*private_free)(struct hda_bus *);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ /* notify power-up/down from codec to contoller */
+ void (*pm_notify)(struct hda_codec *codec);
+#endif
};
/* template to pass to the bus constructor */
@@ -436,7 +447,8 @@ struct hda_bus {
/* codec linked list */
struct list_head codec_list;
- struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */
+ /* link caddr -> codec */
+ struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
struct mutex cmd_mutex;
@@ -469,19 +481,34 @@ struct hda_codec_ops {
int (*init)(struct hda_codec *codec);
void (*free)(struct hda_codec *codec);
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
-#ifdef CONFIG_PM
+#ifdef SND_HDA_NEEDS_RESUME
int (*suspend)(struct hda_codec *codec, pm_message_t state);
int (*resume)(struct hda_codec *codec);
#endif
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
+#endif
};
/* record for amp information cache */
-struct hda_amp_info {
+struct hda_cache_head {
u32 key; /* hash key */
+ u16 val; /* assigned value */
+ u16 next; /* next link; -1 = terminal */
+};
+
+struct hda_amp_info {
+ struct hda_cache_head head;
u32 amp_caps; /* amp capabilities */
u16 vol[2]; /* current volume & mute */
- u16 status; /* update flag */
- u16 next; /* next link */
+};
+
+struct hda_cache_rec {
+ u16 hash[64]; /* hash table for index */
+ unsigned int num_entries; /* number of assigned entries */
+ unsigned int size; /* allocated size */
+ unsigned int record_size; /* record size (including header) */
+ void *buffer; /* hash table entries */
};
/* PCM callbacks */
@@ -499,7 +526,7 @@ struct hda_pcm_ops {
/* PCM information for each substream */
struct hda_pcm_stream {
- unsigned int substreams; /* number of substreams, 0 = not exist */
+ unsigned int substreams; /* number of substreams, 0 = not exist*/
unsigned int channels_min; /* min. number of channels */
unsigned int channels_max; /* max. number of channels */
hda_nid_t nid; /* default NID to query rates/formats/bps, or set up */
@@ -536,11 +563,6 @@ struct hda_codec {
/* set by patch */
struct hda_codec_ops patch_ops;
- /* resume phase - all controls should update even if
- * the values are not changed
- */
- unsigned int in_resume;
-
/* PCM to create, set by patch_ops.build_pcms callback */
unsigned int num_pcms;
struct hda_pcm *pcm_info;
@@ -553,16 +575,22 @@ struct hda_codec {
hda_nid_t start_nid;
u32 *wcaps;
- /* hash for amp access */
- u16 amp_hash[32];
- int num_amp_entries;
- int amp_info_size;
- struct hda_amp_info *amp_info;
+ struct hda_cache_rec amp_cache; /* cache for amp access */
+ struct hda_cache_rec cmd_cache; /* cache for other commands */
struct mutex spdif_mutex;
unsigned int spdif_status; /* IEC958 status bits */
unsigned short spdif_ctls; /* SPDIF control bits */
unsigned int spdif_in_enable; /* SPDIF input enable? */
+
+ struct snd_hwdep *hwdep; /* assigned hwdep device */
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ unsigned int power_on :1; /* current (global) power-state */
+ unsigned int power_transition :1; /* power-state in transition */
+ int power_count; /* current (global) power refcount */
+ struct delayed_work power_work; /* delayed task for powerdown */
+#endif
};
/* direction */
@@ -582,13 +610,17 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
/*
* low level functions
*/
-unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct,
+unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
+ int direct,
unsigned int verb, unsigned int parm);
int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned int verb, unsigned int parm);
-#define snd_hda_param_read(codec, nid, param) snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param)
-int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id);
-int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *conn_list, int max_conns);
+#define snd_hda_param_read(codec, nid, param) \
+ snd_hda_codec_read(codec, nid, 0, AC_VERB_PARAMETERS, param)
+int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
+ hda_nid_t *start_id);
+int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
+ hda_nid_t *conn_list, int max_conns);
struct hda_verb {
hda_nid_t nid;
@@ -596,11 +628,24 @@ struct hda_verb {
u32 param;
};
-void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq);
+void snd_hda_sequence_write(struct hda_codec *codec,
+ const struct hda_verb *seq);
/* unsolicited event */
int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
+/* cached write */
+#ifdef SND_HDA_NEEDS_RESUME
+int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
+ int direct, unsigned int verb, unsigned int parm);
+void snd_hda_sequence_write_cache(struct hda_codec *codec,
+ const struct hda_verb *seq);
+void snd_hda_codec_resume_cache(struct hda_codec *codec);
+#else
+#define snd_hda_codec_write_cache snd_hda_codec_write
+#define snd_hda_sequence_write_cache snd_hda_sequence_write
+#endif
+
/*
* Mixer
*/
@@ -610,10 +655,13 @@ int snd_hda_build_controls(struct hda_bus *bus);
* PCM
*/
int snd_hda_build_pcms(struct hda_bus *bus);
-void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
+void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
+ u32 stream_tag,
int channel_id, int format);
-unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels,
- unsigned int format, unsigned int maxbps);
+unsigned int snd_hda_calc_stream_format(unsigned int rate,
+ unsigned int channels,
+ unsigned int format,
+ unsigned int maxbps);
int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
@@ -632,4 +680,19 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state);
int snd_hda_resume(struct hda_bus *bus);
#endif
+/*
+ * power saving
+ */
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+void snd_hda_power_up(struct hda_codec *codec);
+void snd_hda_power_down(struct hda_codec *codec);
+#define snd_hda_codec_needs_resume(codec) codec->power_count
+int snd_hda_codecs_inuse(struct hda_bus *bus);
+#else
+static inline void snd_hda_power_up(struct hda_codec *codec) {}
+static inline void snd_hda_power_down(struct hda_codec *codec) {}
+#define snd_hda_codec_needs_resume(codec) 1
+#define snd_hda_codecs_inuse(bus) 1
+#endif
+
#endif /* __SOUND_HDA_CODEC_H */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 000287f7da4..c957eb58de5 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -70,6 +70,13 @@ struct hda_gspec {
struct hda_pcm pcm_rec; /* PCM information */
struct list_head nid_list; /* list of widgets */
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+#define MAX_LOOPBACK_AMPS 7
+ struct hda_loopback_check loopback;
+ int num_loopbacks;
+ struct hda_amp_list loopback_list[MAX_LOOPBACK_AMPS + 1];
+#endif
};
/*
@@ -88,13 +95,12 @@ struct hda_gspec {
static void snd_hda_generic_free(struct hda_codec *codec)
{
struct hda_gspec *spec = codec->spec;
- struct list_head *p, *n;
+ struct hda_gnode *node, *n;
if (! spec)
return;
/* free all widgets */
- list_for_each_safe(p, n, &spec->nid_list) {
- struct hda_gnode *node = list_entry(p, struct hda_gnode, list);
+ list_for_each_entry_safe(node, n, &spec->nid_list, list) {
if (node->conn_list != node->slist)
kfree(node->conn_list);
kfree(node);
@@ -196,11 +202,9 @@ static int build_afg_tree(struct hda_codec *codec)
/* FIXME: should avoid the braindead linear search */
static struct hda_gnode *hda_get_node(struct hda_gspec *spec, hda_nid_t nid)
{
- struct list_head *p;
struct hda_gnode *node;
- list_for_each(p, &spec->nid_list) {
- node = list_entry(p, struct hda_gnode, list);
+ list_for_each_entry(node, &spec->nid_list, list) {
if (node->nid == nid)
return node;
}
@@ -218,9 +222,8 @@ static int unmute_output(struct hda_codec *codec, struct hda_gnode *node)
ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
if (val >= ofs)
val -= ofs;
- val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
- val |= AC_AMP_SET_OUTPUT;
- return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
+ snd_hda_codec_amp_stereo(codec, node->nid, HDA_OUTPUT, 0, 0xff, val);
+ return 0;
}
/*
@@ -234,11 +237,8 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne
ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
if (val >= ofs)
val -= ofs;
- val |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
- val |= AC_AMP_SET_INPUT;
- // awk added - fixed to allow unmuting of indexed amps
- val |= index << AC_AMP_SET_INDEX_SHIFT;
- return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val);
+ snd_hda_codec_amp_stereo(codec, node->nid, HDA_INPUT, index, 0xff, val);
+ return 0;
}
/*
@@ -248,7 +248,8 @@ static int select_input_connection(struct hda_codec *codec, struct hda_gnode *no
unsigned int index)
{
snd_printdd("CONNECT: NID=0x%x IDX=0x%x\n", node->nid, index);
- return snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_CONNECT_SEL, index);
+ return snd_hda_codec_write_cache(codec, node->nid, 0,
+ AC_VERB_SET_CONNECT_SEL, index);
}
/*
@@ -256,11 +257,9 @@ static int select_input_connection(struct hda_codec *codec, struct hda_gnode *no
*/
static void clear_check_flags(struct hda_gspec *spec)
{
- struct list_head *p;
struct hda_gnode *node;
- list_for_each(p, &spec->nid_list) {
- node = list_entry(p, struct hda_gnode, list);
+ list_for_each_entry(node, &spec->nid_list, list) {
node->checked = 0;
}
}
@@ -343,12 +342,10 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
struct hda_gspec *spec,
int jack_type)
{
- struct list_head *p;
struct hda_gnode *node;
int err;
- list_for_each(p, &spec->nid_list) {
- node = list_entry(p, struct hda_gnode, list);
+ list_for_each_entry(node, &spec->nid_list, list) {
if (node->type != AC_WID_PIN)
continue;
/* output capable? */
@@ -379,7 +376,7 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec,
/* unmute the PIN output */
unmute_output(codec, node);
/* set PIN-Out enable */
- snd_hda_codec_write(codec, node->nid, 0,
+ snd_hda_codec_write_cache(codec, node->nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
AC_PINCTL_OUT_EN |
((node->pin_caps & AC_PINCAP_HP_DRV) ?
@@ -570,7 +567,8 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec,
/* unmute the PIN external input */
unmute_input(codec, node, 0); /* index = 0? */
/* set PIN-In enable */
- snd_hda_codec_write(codec, node->nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
+ snd_hda_codec_write_cache(codec, node->nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
return 1; /* found */
}
@@ -659,7 +657,6 @@ static int parse_input_path(struct hda_codec *codec, struct hda_gnode *adc_node)
static int parse_input(struct hda_codec *codec)
{
struct hda_gspec *spec = codec->spec;
- struct list_head *p;
struct hda_gnode *node;
int err;
@@ -668,8 +665,7 @@ static int parse_input(struct hda_codec *codec)
* If it reaches to certain input PINs, we take it as the
* input path.
*/
- list_for_each(p, &spec->nid_list) {
- node = list_entry(p, struct hda_gnode, list);
+ list_for_each_entry(node, &spec->nid_list, list) {
if (node->wid_caps & AC_WCAP_DIGITAL)
continue; /* skip SPDIF */
if (node->type == AC_WID_AUD_IN) {
@@ -684,11 +680,33 @@ static int parse_input(struct hda_codec *codec)
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static void add_input_loopback(struct hda_codec *codec, hda_nid_t nid,
+ int dir, int idx)
+{
+ struct hda_gspec *spec = codec->spec;
+ struct hda_amp_list *p;
+
+ if (spec->num_loopbacks >= MAX_LOOPBACK_AMPS) {
+ snd_printk(KERN_ERR "hda_generic: Too many loopback ctls\n");
+ return;
+ }
+ p = &spec->loopback_list[spec->num_loopbacks++];
+ p->nid = nid;
+ p->dir = dir;
+ p->idx = idx;
+ spec->loopback.amplist = spec->loopback_list;
+}
+#else
+#define add_input_loopback(codec,nid,dir,idx)
+#endif
+
/*
* create mixer controls if possible
*/
static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
- unsigned int index, const char *type, const char *dir_sfx)
+ unsigned int index, const char *type,
+ const char *dir_sfx, int is_loopback)
{
char name[32];
int err;
@@ -702,6 +720,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
if ((node->wid_caps & AC_WCAP_IN_AMP) &&
(node->amp_in_caps & AC_AMPCAP_MUTE)) {
knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
+ if (is_loopback)
+ add_input_loopback(codec, node->nid, HDA_INPUT, index);
snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
return err;
@@ -709,6 +729,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
} else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
(node->amp_out_caps & AC_AMPCAP_MUTE)) {
knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
+ if (is_loopback)
+ add_input_loopback(codec, node->nid, HDA_OUTPUT, 0);
snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
return err;
@@ -767,7 +789,7 @@ static int create_output_mixers(struct hda_codec *codec, const char **names)
for (i = 0; i < spec->pcm_vol_nodes; i++) {
err = create_mixer(codec, spec->pcm_vol[i].node,
spec->pcm_vol[i].index,
- names[i], "Playback");
+ names[i], "Playback", 0);
if (err < 0)
return err;
}
@@ -784,7 +806,7 @@ static int build_output_controls(struct hda_codec *codec)
case 1:
return create_mixer(codec, spec->pcm_vol[0].node,
spec->pcm_vol[0].index,
- "Master", "Playback");
+ "Master", "Playback", 0);
case 2:
if (defcfg_type(spec->out_pin_node[0]) == AC_JACK_SPEAKER)
return create_output_mixers(codec, types_speaker);
@@ -820,7 +842,7 @@ static int build_input_controls(struct hda_codec *codec)
if (spec->input_mux.num_items == 1) {
err = create_mixer(codec, adc_node,
spec->input_mux.items[0].index,
- NULL, "Capture");
+ NULL, "Capture", 0);
if (err < 0)
return err;
return 0;
@@ -886,7 +908,8 @@ static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec,
return err;
else if (err >= 1) {
if (err == 1) {
- err = create_mixer(codec, node, i, type, "Playback");
+ err = create_mixer(codec, node, i, type,
+ "Playback", 1);
if (err < 0)
return err;
if (err > 0)
@@ -911,7 +934,6 @@ static int parse_loopback_path(struct hda_codec *codec, struct hda_gspec *spec,
static int build_loopback_controls(struct hda_codec *codec)
{
struct hda_gspec *spec = codec->spec;
- struct list_head *p;
struct hda_gnode *node;
int err;
const char *type;
@@ -919,8 +941,7 @@ static int build_loopback_controls(struct hda_codec *codec)
if (! spec->out_pin_node[0])
return 0;
- list_for_each(p, &spec->nid_list) {
- node = list_entry(p, struct hda_gnode, list);
+ list_for_each_entry(node, &spec->nid_list, list) {
if (node->type != AC_WID_PIN)
continue;
/* input capable? */
@@ -1022,6 +1043,14 @@ static int build_generic_pcms(struct hda_codec *codec)
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int generic_check_power_status(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hda_gspec *spec = codec->spec;
+ return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
+}
+#endif
+
/*
*/
@@ -1029,6 +1058,9 @@ static struct hda_codec_ops generic_patch_ops = {
.build_controls = build_generic_controls,
.build_pcms = build_generic_pcms,
.free = snd_hda_generic_free,
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ .check_power_status = generic_check_power_status,
+#endif
};
/*
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
new file mode 100644
index 00000000000..bafb7b01f5a
--- /dev/null
+++ b/sound/pci/hda/hda_hwdep.c
@@ -0,0 +1,122 @@
+/*
+ * HWDEP Interface for HD-audio codec
+ *
+ * Copyright (c) 2007 Takashi Iwai <tiwai@suse.de>
+ *
+ * This driver 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 driver 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 <sound/driver.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/compat.h>
+#include <linux/mutex.h>
+#include <sound/core.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+#include <sound/hda_hwdep.h>
+
+/*
+ * write/read an out-of-bound verb
+ */
+static int verb_write_ioctl(struct hda_codec *codec,
+ struct hda_verb_ioctl __user *arg)
+{
+ u32 verb, res;
+
+ if (get_user(verb, &arg->verb))
+ return -EFAULT;
+ res = snd_hda_codec_read(codec, verb >> 24, 0,
+ (verb >> 8) & 0xffff, verb & 0xff);
+ if (put_user(res, &arg->res))
+ return -EFAULT;
+ return 0;
+}
+
+static int get_wcap_ioctl(struct hda_codec *codec,
+ struct hda_verb_ioctl __user *arg)
+{
+ u32 verb, res;
+
+ if (get_user(verb, &arg->verb))
+ return -EFAULT;
+ res = get_wcaps(codec, verb >> 24);
+ if (put_user(res, &arg->res))
+ return -EFAULT;
+ return 0;
+}
+
+
+/*
+ */
+static int hda_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct hda_codec *codec = hw->private_data;
+ void __user *argp = (void __user *)arg;
+
+ switch (cmd) {
+ case HDA_IOCTL_PVERSION:
+ return put_user(HDA_HWDEP_VERSION, (int __user *)argp);
+ case HDA_IOCTL_VERB_WRITE:
+ return verb_write_ioctl(codec, argp);
+ case HDA_IOCTL_GET_WCAP:
+ return get_wcap_ioctl(codec, argp);
+ }
+ return -ENOIOCTLCMD;
+}
+
+#ifdef CONFIG_COMPAT
+static int hda_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ return hda_hwdep_ioctl(hw, file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
+static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
+{
+#ifndef CONFIG_SND_DEBUG_DETECT
+ if (!capable(CAP_SYS_RAWIO))
+ return -EACCES;
+#endif
+ return 0;
+}
+
+int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
+{
+ char hwname[16];
+ struct snd_hwdep *hwdep;
+ int err;
+
+ sprintf(hwname, "HDA Codec %d", codec->addr);
+ err = snd_hwdep_new(codec->bus->card, hwname, codec->addr, &hwdep);
+ if (err < 0)
+ return err;
+ codec->hwdep = hwdep;
+ sprintf(hwdep->name, "HDA Codec %d", codec->addr);
+ hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
+ hwdep->private_data = codec;
+ hwdep->exclusive = 1;
+
+ hwdep->ops.open = hda_hwdep_open;
+ hwdep->ops.ioctl = hda_hwdep_ioctl;
+#ifdef CONFIG_COMPAT
+ hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
+#endif
+
+ return 0;
+}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 92bc8b3fa2a..3fa0f970490 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1,6 +1,7 @@
/*
*
- * hda_intel.c - Implementation of primary alsa driver code base for Intel HD Audio.
+ * hda_intel.c - Implementation of primary alsa driver code base
+ * for Intel HD Audio.
*
* Copyright(c) 2004 Intel Corporation. All rights reserved.
*
@@ -64,14 +65,27 @@ MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
module_param(model, charp, 0444);
MODULE_PARM_DESC(model, "Use the given board model.");
module_param(position_fix, int, 0444);
-MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
+MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
+ "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
module_param(probe_mask, int, 0444);
MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
module_param(single_cmd, bool, 0444);
-MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only).");
+MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
+ "(for debugging only).");
module_param(enable_msi, int, 0);
MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+/* power_save option is defined in hda_codec.c */
+
+/* reset the HD-audio controller in power save mode.
+ * this may give more power-saving, but will take longer time to
+ * wake up.
+ */
+static int power_save_controller = 1;
+module_param(power_save_controller, bool, 0644);
+MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
+#endif
/* just for backward compatibility */
static int enable;
@@ -98,6 +112,7 @@ MODULE_DESCRIPTION("Intel HDA driver");
#define SFX "hda-intel: "
+
/*
* registers
*/
@@ -213,15 +228,16 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define SD_INT_DESC_ERR 0x10 /* descriptor error interrupt */
#define SD_INT_FIFO_ERR 0x08 /* FIFO error interrupt */
#define SD_INT_COMPLETE 0x04 /* completion interrupt */
-#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|SD_INT_COMPLETE)
+#define SD_INT_MASK (SD_INT_DESC_ERR|SD_INT_FIFO_ERR|\
+ SD_INT_COMPLETE)
/* SD_STS */
#define SD_STS_FIFO_READY 0x20 /* FIFO ready */
/* INTCTL and INTSTS */
-#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */
-#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
-#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
+#define ICH6_INT_ALL_STREAM 0xff /* all stream interrupts */
+#define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */
+#define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */
/* GCTL unsolicited response enable bit */
#define ICH6_GCTL_UREN (1<<8)
@@ -257,22 +273,26 @@ enum {
*/
struct azx_dev {
- u32 *bdl; /* virtual address of the BDL */
- dma_addr_t bdl_addr; /* physical address of the BDL */
- u32 *posbuf; /* position buffer pointer */
+ u32 *bdl; /* virtual address of the BDL */
+ dma_addr_t bdl_addr; /* physical address of the BDL */
+ u32 *posbuf; /* position buffer pointer */
- unsigned int bufsize; /* size of the play buffer in bytes */
- unsigned int fragsize; /* size of each period in bytes */
- unsigned int frags; /* number for period in the play buffer */
- unsigned int fifo_size; /* FIFO size */
+ unsigned int bufsize; /* size of the play buffer in bytes */
+ unsigned int fragsize; /* size of each period in bytes */
+ unsigned int frags; /* number for period in the play buffer */
+ unsigned int fifo_size; /* FIFO size */
- void __iomem *sd_addr; /* stream descriptor pointer */
+ void __iomem *sd_addr; /* stream descriptor pointer */
- u32 sd_int_sta_mask; /* stream int status mask */
+ u32 sd_int_sta_mask; /* stream int status mask */
/* pcm support */
- struct snd_pcm_substream *substream; /* assigned substream, set in PCM open */
- unsigned int format_val; /* format value to be set in the controller and the codec */
+ struct snd_pcm_substream *substream; /* assigned substream,
+ * set in PCM open
+ */
+ unsigned int format_val; /* format value to be set in the
+ * controller and the codec
+ */
unsigned char stream_tag; /* assigned stream */
unsigned char index; /* stream index */
/* for sanity check of position buffer */
@@ -337,6 +357,7 @@ struct azx {
/* flags */
int position_fix;
+ unsigned int running :1;
unsigned int initialized :1;
unsigned int single_cmd :1;
unsigned int polling_mode :1;
@@ -418,7 +439,8 @@ static int azx_alloc_cmd_io(struct azx *chip)
int err;
/* single page (at least 4096 bytes) must suffice for both ringbuffes */
- err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->pci),
PAGE_SIZE, &chip->rb);
if (err < 0) {
snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
@@ -531,9 +553,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
azx_update_rirb(chip);
spin_unlock_irq(&chip->reg_lock);
}
- if (! chip->rirb.cmds)
+ if (!chip->rirb.cmds)
return chip->rirb.res; /* the last value */
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_after_eq(timeout, jiffies));
if (chip->msi) {
@@ -585,16 +607,19 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
while (timeout--) {
/* check ICB busy bit */
- if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) {
+ if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
/* Clear IRV valid bit */
- azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_VALID);
+ azx_writew(chip, IRS, azx_readw(chip, IRS) |
+ ICH6_IRS_VALID);
azx_writel(chip, IC, val);
- azx_writew(chip, IRS, azx_readw(chip, IRS) | ICH6_IRS_BUSY);
+ azx_writew(chip, IRS, azx_readw(chip, IRS) |
+ ICH6_IRS_BUSY);
return 0;
}
udelay(1);
}
- snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n", azx_readw(chip, IRS), val);
+ snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
+ azx_readw(chip, IRS), val);
return -EIO;
}
@@ -610,7 +635,8 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
return azx_readl(chip, IR);
udelay(1);
}
- snd_printd(SFX "get_response timeout: IRS=0x%x\n", azx_readw(chip, IRS));
+ snd_printd(SFX "get_response timeout: IRS=0x%x\n",
+ azx_readw(chip, IRS));
return (unsigned int)-1;
}
@@ -652,12 +678,18 @@ static unsigned int azx_get_response(struct hda_codec *codec)
return azx_rirb_get_response(codec);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static void azx_power_notify(struct hda_codec *codec);
+#endif
/* reset codec link */
static int azx_reset(struct azx *chip)
{
int count;
+ /* clear STATESTS */
+ azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
+
/* reset controller */
azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
@@ -777,18 +809,12 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
/*
- * initialize the chip
+ * reset and start the controller registers
*/
static void azx_init_chip(struct azx *chip)
{
- unsigned char reg;
-
- /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
- * TCSEL == Traffic Class Select Register, which sets PCI express QOS
- * Ensuring these bits are 0 clears playback static on some HD Audio codecs
- */
- pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
- pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
+ if (chip->initialized)
+ return;
/* reset controller */
azx_reset(chip);
@@ -805,19 +831,45 @@ static void azx_init_chip(struct azx *chip)
azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
+ chip->initialized = 1;
+}
+
+/*
+ * initialize the PCI registers
+ */
+/* update bits in a PCI register byte */
+static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
+ unsigned char mask, unsigned char val)
+{
+ unsigned char data;
+
+ pci_read_config_byte(pci, reg, &data);
+ data &= ~mask;
+ data |= (val & mask);
+ pci_write_config_byte(pci, reg, data);
+}
+
+static void azx_init_pci(struct azx *chip)
+{
+ /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
+ * TCSEL == Traffic Class Select Register, which sets PCI express QOS
+ * Ensuring these bits are 0 clears playback static on some HD Audio
+ * codecs
+ */
+ update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
+
switch (chip->driver_type) {
case AZX_DRIVER_ATI:
/* For ATI SB450 azalia HD audio, we need to enable snoop */
- pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- &reg);
- pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
- (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+ update_pci_byte(chip->pci,
+ ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR,
+ 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP);
break;
case AZX_DRIVER_NVIDIA:
/* For NVIDIA HDA, enable snoop */
- pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg);
- pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR,
- (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS);
+ update_pci_byte(chip->pci,
+ NVIDIA_HDA_TRANSREG_ADDR,
+ 0x0f, NVIDIA_HDA_ENABLE_COHBITS);
break;
}
}
@@ -857,7 +909,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
/* clear rirb int */
status = azx_readb(chip, RIRBSTS);
if (status & RIRB_INT_MASK) {
- if (! chip->single_cmd && (status & RIRB_INT_RESPONSE))
+ if (!chip->single_cmd && (status & RIRB_INT_RESPONSE))
azx_update_rirb(chip);
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
}
@@ -911,9 +963,11 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
int timeout;
/* make sure the run bit is zero for SD */
- azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & ~SD_CTL_DMA_START);
+ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
+ ~SD_CTL_DMA_START);
/* reset stream */
- azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | SD_CTL_STREAM_RESET);
+ azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
+ SD_CTL_STREAM_RESET);
udelay(3);
timeout = 300;
while (!((val = azx_sd_readb(azx_dev, SD_CTL)) & SD_CTL_STREAM_RESET) &&
@@ -931,7 +985,7 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
/* program the stream_tag */
azx_sd_writel(azx_dev, SD_CTL,
- (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK) |
+ (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)|
(azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT));
/* program the length of samples in cyclic buffer */
@@ -951,11 +1005,13 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr));
/* enable the position buffer */
- if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
- azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
+ if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
+ azx_writel(chip, DPLBASE,
+ (u32)chip->posbuf.addr |ICH6_DPLBASE_ENABLE);
/* set the interrupt enable bits in the descriptor control register */
- azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
+ azx_sd_writel(azx_dev, SD_CTL,
+ azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
return 0;
}
@@ -986,8 +1042,12 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
bus_temp.pci = chip->pci;
bus_temp.ops.command = azx_send_cmd;
bus_temp.ops.get_response = azx_get_response;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ bus_temp.ops.pm_notify = azx_power_notify;
+#endif
- if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
+ err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
+ if (err < 0)
return err;
codecs = audio_codecs = 0;
@@ -1038,7 +1098,7 @@ static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
nums = chip->capture_streams;
}
for (i = 0; i < nums; i++, dev++)
- if (! chip->azx_dev[dev].opened) {
+ if (!chip->azx_dev[dev].opened) {
chip->azx_dev[dev].opened = 1;
return &chip->azx_dev[dev];
}
@@ -1052,7 +1112,8 @@ static inline void azx_release_device(struct azx_dev *azx_dev)
}
static struct snd_pcm_hardware azx_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
/* No full-resume yet implemented */
@@ -1105,8 +1166,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
128);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
128);
- if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) {
+ snd_hda_power_up(apcm->codec);
+ err = hinfo->ops.open(hinfo, apcm->codec, substream);
+ if (err < 0) {
azx_release_device(azx_dev);
+ snd_hda_power_down(apcm->codec);
mutex_unlock(&chip->open_mutex);
return err;
}
@@ -1135,13 +1199,16 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
spin_unlock_irqrestore(&chip->reg_lock, flags);
azx_release_device(azx_dev);
hinfo->ops.close(hinfo, apcm->codec, substream);
+ snd_hda_power_down(apcm->codec);
mutex_unlock(&chip->open_mutex);
return 0;
}
-static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
+static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
}
static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
@@ -1175,13 +1242,15 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
runtime->channels,
runtime->format,
hinfo->maxbps);
- if (! azx_dev->format_val) {
- snd_printk(KERN_ERR SFX "invalid format_val, rate=%d, ch=%d, format=%d\n",
+ if (!azx_dev->format_val) {
+ snd_printk(KERN_ERR SFX
+ "invalid format_val, rate=%d, ch=%d, format=%d\n",
runtime->rate, runtime->channels, runtime->format);
return -EINVAL;
}
- snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, format=0x%x\n",
+ snd_printdd("azx_pcm_prepare: bufsize=0x%x, fragsize=0x%x, "
+ "format=0x%x\n",
azx_dev->bufsize, azx_dev->fragsize, azx_dev->format_val);
azx_setup_periods(azx_dev);
azx_setup_controller(chip, azx_dev);
@@ -1223,7 +1292,8 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
cmd == SNDRV_PCM_TRIGGER_SUSPEND ||
cmd == SNDRV_PCM_TRIGGER_STOP) {
int timeout = 5000;
- while (azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START && --timeout)
+ while ((azx_sd_readb(azx_dev, SD_CTL) & SD_CTL_DMA_START) &&
+ --timeout)
;
}
return err;
@@ -1241,7 +1311,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
/* use the position buffer */
pos = le32_to_cpu(*azx_dev->posbuf);
if (chip->position_fix == POS_FIX_AUTO &&
- azx_dev->period_intr == 1 && ! pos) {
+ azx_dev->period_intr == 1 && !pos) {
printk(KERN_WARNING
"hda-intel: Invalid position buffer, "
"using LPIB read method instead.\n");
@@ -1292,7 +1362,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
snd_assert(cpcm->name, return -EINVAL);
err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
- cpcm->stream[0].substreams, cpcm->stream[1].substreams,
+ cpcm->stream[0].substreams,
+ cpcm->stream[1].substreams,
&pcm);
if (err < 0)
return err;
@@ -1322,26 +1393,27 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
static int __devinit azx_pcm_create(struct azx *chip)
{
- struct list_head *p;
struct hda_codec *codec;
int c, err;
int pcm_dev;
- if ((err = snd_hda_build_pcms(chip->bus)) < 0)
+ err = snd_hda_build_pcms(chip->bus);
+ if (err < 0)
return err;
/* create audio PCMs */
pcm_dev = 0;
- list_for_each(p, &chip->bus->codec_list) {
- codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &chip->bus->codec_list, list) {
for (c = 0; c < codec->num_pcms; c++) {
if (codec->pcm_info[c].is_modem)
continue; /* create later */
if (pcm_dev >= AZX_MAX_AUDIO_PCMS) {
- snd_printk(KERN_ERR SFX "Too many audio PCMs\n");
+ snd_printk(KERN_ERR SFX
+ "Too many audio PCMs\n");
return -EINVAL;
}
- err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
+ err = create_codec_pcm(chip, codec,
+ &codec->pcm_info[c], pcm_dev);
if (err < 0)
return err;
pcm_dev++;
@@ -1350,16 +1422,17 @@ static int __devinit azx_pcm_create(struct azx *chip)
/* create modem PCMs */
pcm_dev = AZX_MAX_AUDIO_PCMS;
- list_for_each(p, &chip->bus->codec_list) {
- codec = list_entry(p, struct hda_codec, list);
+ list_for_each_entry(codec, &chip->bus->codec_list, list) {
for (c = 0; c < codec->num_pcms; c++) {
- if (! codec->pcm_info[c].is_modem)
+ if (!codec->pcm_info[c].is_modem)
continue; /* already created */
if (pcm_dev >= AZX_MAX_PCMS) {
- snd_printk(KERN_ERR SFX "Too many modem PCMs\n");
+ snd_printk(KERN_ERR SFX
+ "Too many modem PCMs\n");
return -EINVAL;
}
- err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
+ err = create_codec_pcm(chip, codec,
+ &codec->pcm_info[c], pcm_dev);
if (err < 0)
return err;
chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
@@ -1386,7 +1459,8 @@ static int __devinit azx_init_stream(struct azx *chip)
int i;
/* initialize each stream (aka device)
- * assign the starting bdl address to each stream (device) and initialize
+ * assign the starting bdl address to each stream (device)
+ * and initialize
*/
for (i = 0; i < chip->num_streams; i++) {
unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4);
@@ -1423,6 +1497,46 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
}
+static void azx_stop_chip(struct azx *chip)
+{
+ if (!chip->initialized)
+ return;
+
+ /* disable interrupts */
+ azx_int_disable(chip);
+ azx_int_clear(chip);
+
+ /* disable CORB/RIRB */
+ azx_free_cmd_io(chip);
+
+ /* disable position buffer */
+ azx_writel(chip, DPLBASE, 0);
+ azx_writel(chip, DPUBASE, 0);
+
+ chip->initialized = 0;
+}
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+/* power-up/down the controller */
+static void azx_power_notify(struct hda_codec *codec)
+{
+ struct azx *chip = codec->bus->private_data;
+ struct hda_codec *c;
+ int power_on = 0;
+
+ list_for_each_entry(c, &codec->bus->codec_list, list) {
+ if (c->power_on) {
+ power_on = 1;
+ break;
+ }
+ }
+ if (power_on)
+ azx_init_chip(chip);
+ else if (chip->running && power_save_controller)
+ azx_stop_chip(chip);
+}
+#endif /* CONFIG_SND_HDA_POWER_SAVE */
+
#ifdef CONFIG_PM
/*
* power management
@@ -1436,8 +1550,9 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
for (i = 0; i < chip->pcm_devs; i++)
snd_pcm_suspend_all(chip->pcm[i]);
- snd_hda_suspend(chip->bus, state);
- azx_free_cmd_io(chip);
+ if (chip->initialized)
+ snd_hda_suspend(chip->bus, state);
+ azx_stop_chip(chip);
if (chip->irq >= 0) {
synchronize_irq(chip->irq);
free_irq(chip->irq, chip);
@@ -1470,7 +1585,11 @@ static int azx_resume(struct pci_dev *pci)
chip->msi = 0;
if (azx_acquire_irq(chip, 1) < 0)
return -EIO;
- azx_init_chip(chip);
+ azx_init_pci(chip);
+
+ if (snd_hda_codecs_inuse(chip->bus))
+ azx_init_chip(chip);
+
snd_hda_resume(chip->bus);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
@@ -1485,20 +1604,9 @@ static int azx_free(struct azx *chip)
{
if (chip->initialized) {
int i;
-
for (i = 0; i < chip->num_streams; i++)
azx_stream_stop(chip, &chip->azx_dev[i]);
-
- /* disable interrupts */
- azx_int_disable(chip);
- azx_int_clear(chip);
-
- /* disable CORB/RIRB */
- azx_free_cmd_io(chip);
-
- /* disable position buffer */
- azx_writel(chip, DPLBASE, 0);
- azx_writel(chip, DPUBASE, 0);
+ azx_stop_chip(chip);
}
if (chip->irq >= 0) {
@@ -1534,6 +1642,7 @@ static int azx_dev_free(struct snd_device *device)
*/
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
+ SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_NONE),
{}
};
@@ -1544,7 +1653,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
if (fix == POS_FIX_AUTO) {
q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
if (q) {
- snd_printdd(KERN_INFO
+ printk(KERN_INFO
"hda_intel: position_fix set to %d "
"for device %04x:%04x\n",
q->value, q->subvendor, q->subdevice);
@@ -1555,6 +1664,36 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
}
/*
+ * black-lists for probe_mask
+ */
+static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
+ /* Thinkpad often breaks the controller communication when accessing
+ * to the non-working (or non-existing) modem codec slot.
+ */
+ SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
+ SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
+ SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
+ {}
+};
+
+static void __devinit check_probe_mask(struct azx *chip)
+{
+ const struct snd_pci_quirk *q;
+
+ if (probe_mask == -1) {
+ q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
+ if (q) {
+ printk(KERN_INFO
+ "hda_intel: probe_mask set to 0x%x "
+ "for device %04x:%04x\n",
+ q->value, q->subvendor, q->subdevice);
+ probe_mask = q->value;
+ }
+ }
+}
+
+
+/*
* constructor
*/
static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
@@ -1589,6 +1728,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
chip->msi = enable_msi;
chip->position_fix = check_position_fix(chip, position_fix);
+ check_probe_mask(chip);
chip->single_cmd = single_cmd;
@@ -1650,37 +1790,43 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
break;
}
chip->num_streams = chip->playback_streams + chip->capture_streams;
- chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev), GFP_KERNEL);
+ chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
+ GFP_KERNEL);
if (!chip->azx_dev) {
snd_printk(KERN_ERR "cannot malloc azx_dev\n");
goto errout;
}
/* allocate memory for the BDL for each stream */
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- BDL_SIZE, &chip->bdl)) < 0) {
+ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->pci),
+ BDL_SIZE, &chip->bdl);
+ if (err < 0) {
snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
goto errout;
}
/* allocate memory for the position buffer */
- if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
- chip->num_streams * 8, &chip->posbuf)) < 0) {
+ err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(chip->pci),
+ chip->num_streams * 8, &chip->posbuf);
+ if (err < 0) {
snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
goto errout;
}
/* allocate CORB/RIRB */
- if (! chip->single_cmd)
- if ((err = azx_alloc_cmd_io(chip)) < 0)
+ if (!chip->single_cmd) {
+ err = azx_alloc_cmd_io(chip);
+ if (err < 0)
goto errout;
+ }
/* initialize streams */
azx_init_stream(chip);
/* initialize chip */
+ azx_init_pci(chip);
azx_init_chip(chip);
- chip->initialized = 1;
-
/* codec detection */
if (!chip->codec_mask) {
snd_printk(KERN_ERR SFX "no codecs found!\n");
@@ -1688,14 +1834,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
goto errout;
}
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) <0) {
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err <0) {
snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
goto errout;
}
strcpy(card->driver, "HDA-Intel");
strcpy(card->shortname, driver_short_names[chip->driver_type]);
- sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->addr, chip->irq);
+ sprintf(card->longname, "%s at 0x%lx irq %i",
+ card->shortname, chip->addr, chip->irq);
*rchip = chip;
return 0;
@@ -1705,7 +1853,21 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
return err;
}
-static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+static void power_down_all_codecs(struct azx *chip)
+{
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ /* The codecs were powered up in snd_hda_codec_new().
+ * Now all initialization done, so turn them down if possible
+ */
+ struct hda_codec *codec;
+ list_for_each_entry(codec, &chip->bus->codec_list, list) {
+ snd_hda_power_down(codec);
+ }
+#endif
+}
+
+static int __devinit azx_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
{
struct snd_card *card;
struct azx *chip;
@@ -1725,31 +1887,37 @@ static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *
card->private_data = chip;
/* create codec instances */
- if ((err = azx_codec_create(chip, model)) < 0) {
+ err = azx_codec_create(chip, model);
+ if (err < 0) {
snd_card_free(card);
return err;
}
/* create PCM streams */
- if ((err = azx_pcm_create(chip)) < 0) {
+ err = azx_pcm_create(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
/* create mixer controls */
- if ((err = azx_mixer_create(chip)) < 0) {
+ err = azx_mixer_create(chip);
+ if (err < 0) {
snd_card_free(card);
return err;
}
snd_card_set_dev(card, &pci->dev);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
pci_set_drvdata(pci, card);
+ chip->running = 1;
+ power_down_all_codecs(chip);
return err;
}
@@ -1791,6 +1959,10 @@ static struct pci_device_id azx_ids[] = {
{ 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
{ 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
{ 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */
+ { 0x10de, 0x0ac0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
+ { 0x10de, 0x0ac1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
+ { 0x10de, 0x0ac2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
+ { 0x10de, 0x0ac3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP79 */
{ 0, }
};
MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index f91ea5ec9f6..a79d0ed5469 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -26,7 +26,8 @@
/*
* for mixer controls
*/
-#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
+#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
+ ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
/* mono volume with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
@@ -64,18 +65,35 @@
#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
-int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv);
-int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+ unsigned int size, unsigned int __user *tlv);
+int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
/* lowlevel accessor with caching; use carefully */
int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int index);
int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int idx, int mask, int val);
+int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
+ int dir, int idx, int mask, int val);
+#ifdef SND_HDA_NEEDS_RESUME
+void snd_hda_codec_resume_amp(struct hda_codec *codec);
+#endif
+
+/* amp value bits */
+#define HDA_AMP_MUTE 0x80
+#define HDA_AMP_UNMUTE 0x00
+#define HDA_AMP_VOLMASK 0x7f
/* mono switch binding multiple inputs */
#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
@@ -86,11 +104,61 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
/* stereo switch binding multiple inputs */
-#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+#define HDA_BIND_MUTE(xname,nid,indices,dir) \
+ HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+
+int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+
+/* more generic bound controls */
+struct hda_ctl_ops {
+ snd_kcontrol_info_t *info;
+ snd_kcontrol_get_t *get;
+ snd_kcontrol_put_t *put;
+ snd_kcontrol_tlv_rw_t *tlv;
+};
-int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+extern struct hda_ctl_ops snd_hda_bind_vol; /* for bind-volume with TLV */
+extern struct hda_ctl_ops snd_hda_bind_sw; /* for bind-switch */
+struct hda_bind_ctls {
+ struct hda_ctl_ops *ops;
+ long values[];
+};
+
+int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo);
+int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+ unsigned int size, unsigned int __user *tlv);
+
+#define HDA_BIND_VOL(xname, bindrec) \
+ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+ SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\
+ .info = snd_hda_mixer_bind_ctls_info,\
+ .get = snd_hda_mixer_bind_ctls_get,\
+ .put = snd_hda_mixer_bind_ctls_put,\
+ .tlv = { .c = snd_hda_mixer_bind_tlv },\
+ .private_value = (long) (bindrec) }
+#define HDA_BIND_SW(xname, bindrec) \
+ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
+ .name = xname, \
+ .info = snd_hda_mixer_bind_ctls_info,\
+ .get = snd_hda_mixer_bind_ctls_get,\
+ .put = snd_hda_mixer_bind_ctls_put,\
+ .private_value = (long) (bindrec) }
+
+/*
+ * SPDIF I/O
+ */
int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
@@ -107,8 +175,10 @@ struct hda_input_mux {
struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
};
-int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo);
-int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
+int snd_hda_input_mux_info(const struct hda_input_mux *imux,
+ struct snd_ctl_elem_info *uinfo);
+int snd_hda_input_mux_put(struct hda_codec *codec,
+ const struct hda_input_mux *imux,
struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
unsigned int *cur_val);
@@ -120,13 +190,19 @@ struct hda_channel_mode {
const struct hda_verb *sequence;
};
-int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
- const struct hda_channel_mode *chmode, int num_chmodes);
-int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_info(struct hda_codec *codec,
+ struct snd_ctl_elem_info *uinfo,
+ const struct hda_channel_mode *chmode,
+ int num_chmodes);
+int snd_hda_ch_mode_get(struct hda_codec *codec,
+ struct snd_ctl_elem_value *ucontrol,
+ const struct hda_channel_mode *chmode,
+ int num_chmodes,
int max_channels);
-int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
- const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_put(struct hda_codec *codec,
+ struct snd_ctl_elem_value *ucontrol,
+ const struct hda_channel_mode *chmode,
+ int num_chmodes,
int *max_channelsp);
/*
@@ -146,20 +222,25 @@ struct hda_multi_out {
int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
};
-int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
-int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
+int snd_hda_multi_out_dig_open(struct hda_codec *codec,
+ struct hda_multi_out *mout);
+int snd_hda_multi_out_dig_close(struct hda_codec *codec,
+ struct hda_multi_out *mout);
int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
struct hda_multi_out *mout,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream);
-int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+ struct hda_multi_out *mout,
struct snd_pcm_substream *substream);
-int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
+ struct hda_multi_out *mout,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream);
-int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout);
+int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
+ struct hda_multi_out *mout);
/*
* generic codec parser
@@ -181,16 +262,8 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
const char **modelnames,
const struct snd_pci_quirk *pci_list);
-int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
-
-/*
- * power management
- */
-#ifdef CONFIG_PM
-int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
-int snd_hda_resume_spdif_out(struct hda_codec *codec);
-int snd_hda_resume_spdif_in(struct hda_codec *codec);
-#endif
+int snd_hda_add_new_ctls(struct hda_codec *codec,
+ struct snd_kcontrol_new *knew);
/*
* unsolicited event handler
@@ -232,7 +305,9 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
struct auto_pin_cfg {
int line_outs;
- hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */
+ hda_nid_t line_out_pins[5]; /* sorted in the order of
+ * Front/Surr/CLFE/Side
+ */
int speaker_outs;
hda_nid_t speaker_pins[5];
int hp_outs;
@@ -243,13 +318,19 @@ struct auto_pin_cfg {
hda_nid_t dig_in_pin;
};
-#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
-#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
-#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
-#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE)
-#define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
-
-int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
+#define get_defcfg_connect(cfg) \
+ ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
+#define get_defcfg_association(cfg) \
+ ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
+#define get_defcfg_location(cfg) \
+ ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
+#define get_defcfg_sequence(cfg) \
+ (cfg & AC_DEFCFG_SEQUENCE)
+#define get_defcfg_device(cfg) \
+ ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
+
+int snd_hda_parse_pin_def_config(struct hda_codec *codec,
+ struct auto_pin_cfg *cfg,
hda_nid_t *ignore_nids);
/* amp values */
@@ -280,4 +361,32 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
unsigned int caps);
+/*
+ * hwdep interface
+ */
+int snd_hda_create_hwdep(struct hda_codec *codec);
+
+/*
+ * power-management
+ */
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+void snd_hda_schedule_power_save(struct hda_codec *codec);
+
+struct hda_amp_list {
+ hda_nid_t nid;
+ unsigned char dir;
+ unsigned char idx;
+};
+
+struct hda_loopback_check {
+ struct hda_amp_list *amplist;
+ int power_on;
+};
+
+int snd_hda_check_amp_list_power(struct hda_codec *codec,
+ struct hda_loopback_check *check,
+ hda_nid_t nid);
+#endif /* CONFIG_SND_HDA_POWER_SAVE */
+
#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
index 9f9e9ae44a9..f5c23bb16d7 100644
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -20,13 +20,29 @@ extern struct hda_codec_preset snd_hda_preset_conexant[];
extern struct hda_codec_preset snd_hda_preset_via[];
static const struct hda_codec_preset *hda_preset_tables[] = {
+#ifdef CONFIG_SND_HDA_CODEC_REALTEK
snd_hda_preset_realtek,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_CMEDIA
snd_hda_preset_cmedia,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_ANALOG
snd_hda_preset_analog,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_SIGMATEL
snd_hda_preset_sigmatel,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_SI3054
snd_hda_preset_si3054,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
snd_hda_preset_atihdmi,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_CONEXANT
snd_hda_preset_conexant,
+#endif
+#ifdef CONFIG_SND_HDA_CODEC_VIA
snd_hda_preset_via,
+#endif
NULL
};
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index ac15066fd30..e94944f34ff 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -58,7 +58,8 @@ static void print_amp_caps(struct snd_info_buffer *buffer,
snd_iprintf(buffer, "N/A\n");
return;
}
- snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, mute=%x\n",
+ snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
+ "mute=%x\n",
caps & AC_AMPCAP_OFFSET,
(caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT,
(caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT,
@@ -76,11 +77,13 @@ static void print_amp_vals(struct snd_info_buffer *buffer,
for (i = 0; i < indices; i++) {
snd_iprintf(buffer, " [");
if (stereo) {
- val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
+ val = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_AMP_GAIN_MUTE,
AC_AMP_GET_LEFT | dir | i);
snd_iprintf(buffer, "0x%02x ", val);
}
- val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
+ val = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_AMP_GAIN_MUTE,
AC_AMP_GET_RIGHT | dir | i);
snd_iprintf(buffer, "0x%02x]", val);
}
@@ -237,7 +240,8 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
}
-static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+static void print_codec_info(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
struct hda_codec *codec = entry->private_data;
char buf[32];
@@ -258,6 +262,7 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
if (! codec->afg)
return;
+ snd_hda_power_up(codec);
snd_iprintf(buffer, "Default PCM:\n");
print_pcm_caps(buffer, codec, codec->afg);
snd_iprintf(buffer, "Default Amp-In caps: ");
@@ -268,12 +273,15 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
if (! nid || nodes < 0) {
snd_iprintf(buffer, "Invalid AFG subtree\n");
+ snd_hda_power_down(codec);
return;
}
for (i = 0; i < nodes; i++, nid++) {
- unsigned int wid_caps = snd_hda_param_read(codec, nid,
- AC_PAR_AUDIO_WIDGET_CAP);
- unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+ unsigned int wid_caps =
+ snd_hda_param_read(codec, nid,
+ AC_PAR_AUDIO_WIDGET_CAP);
+ unsigned int wid_type =
+ (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
int conn_len = 0;
hda_nid_t conn[HDA_MAX_CONNECTIONS];
@@ -313,7 +321,9 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
if (wid_type == AC_WID_PIN) {
unsigned int pinctls;
print_pin_caps(buffer, codec, nid);
- pinctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+ pinctls = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_PIN_WIDGET_CONTROL,
+ 0);
snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
if (pinctls & AC_PINCTL_IN_EN)
snd_iprintf(buffer, " IN");
@@ -333,7 +343,8 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
if (wid_caps & AC_WCAP_POWER)
snd_iprintf(buffer, " Power: 0x%x\n",
snd_hda_codec_read(codec, nid, 0,
- AC_VERB_GET_POWER_STATE, 0));
+ AC_VERB_GET_POWER_STATE,
+ 0));
if (wid_caps & AC_WCAP_CONN_LIST) {
int c, curr = -1;
@@ -350,6 +361,7 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe
snd_iprintf(buffer, "\n");
}
}
+ snd_hda_power_down(codec);
}
/*
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 4d7f8d11ad7..54cfd4526d2 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -73,6 +73,12 @@ struct ad198x_spec {
struct snd_kcontrol_new *kctl_alloc;
struct hda_input_mux private_imux;
hda_nid_t private_dac_nids[4];
+
+ unsigned int jack_present :1;
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ struct hda_loopback_check loopback;
+#endif
};
/*
@@ -144,6 +150,14 @@ static int ad198x_build_controls(struct hda_codec *codec)
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct ad198x_spec *spec = codec->spec;
+ return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
+}
+#endif
+
/*
* Analog playback callbacks
*/
@@ -318,30 +332,13 @@ static void ad198x_free(struct hda_codec *codec)
kfree(codec->spec);
}
-#ifdef CONFIG_PM
-static int ad198x_resume(struct hda_codec *codec)
-{
- struct ad198x_spec *spec = codec->spec;
- int i;
-
- codec->patch_ops.init(codec);
- for (i = 0; i < spec->num_mixers; i++)
- snd_hda_resume_ctls(codec, spec->mixers[i]);
- if (spec->multiout.dig_out_nid)
- snd_hda_resume_spdif_out(codec);
- if (spec->dig_in_nid)
- snd_hda_resume_spdif_in(codec);
- return 0;
-}
-#endif
-
static struct hda_codec_ops ad198x_patch_ops = {
.build_controls = ad198x_build_controls,
.build_pcms = ad198x_build_pcms,
.init = ad198x_init,
.free = ad198x_free,
-#ifdef CONFIG_PM
- .resume = ad198x_resume,
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ .check_power_status = ad198x_check_power_status,
#endif
};
@@ -350,15 +347,7 @@ static struct hda_codec_ops ad198x_patch_ops = {
* EAPD control
* the private value = nid | (invert << 8)
*/
-static int ad198x_eapd_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define ad198x_eapd_info snd_ctl_boolean_mono_info
static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -384,12 +373,12 @@ static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
eapd = ucontrol->value.integer.value[0];
if (invert)
eapd = !eapd;
- if (eapd == spec->cur_eapd && ! codec->in_resume)
+ if (eapd == spec->cur_eapd)
return 0;
spec->cur_eapd = eapd;
- snd_hda_codec_write(codec, nid,
- 0, AC_VERB_SET_EAPD_BTLENABLE,
- eapd ? 0x02 : 0x00);
+ snd_hda_codec_write_cache(codec, nid,
+ 0, AC_VERB_SET_EAPD_BTLENABLE,
+ eapd ? 0x02 : 0x00);
return 1;
}
@@ -430,94 +419,36 @@ static struct hda_input_mux ad1986a_capture_source = {
},
};
-/*
- * PCM control
- *
- * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
- */
-
-#define ad1986a_pcm_amp_vol_info snd_hda_mixer_amp_volume_info
-
-static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *ad = codec->spec;
-
- mutex_lock(&ad->amp_mutex);
- snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
- mutex_unlock(&ad->amp_mutex);
- return 0;
-}
-
-static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *ad = codec->spec;
- int i, change = 0;
-
- mutex_lock(&ad->amp_mutex);
- for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
- change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
- }
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
- mutex_unlock(&ad->amp_mutex);
- return change;
-}
-
-#define ad1986a_pcm_amp_sw_info snd_hda_mixer_amp_switch_info
-static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *ad = codec->spec;
-
- mutex_lock(&ad->amp_mutex);
- snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
- mutex_unlock(&ad->amp_mutex);
- return 0;
-}
-
-static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- struct ad198x_spec *ad = codec->spec;
- int i, change = 0;
+static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
- mutex_lock(&ad->amp_mutex);
- for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) {
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT);
- change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
- }
- kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT);
- mutex_unlock(&ad->amp_mutex);
- return change;
-}
+static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
/*
* mixers
*/
static struct snd_kcontrol_new ad1986a_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Volume",
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
- .info = ad1986a_pcm_amp_vol_info,
- .get = ad1986a_pcm_amp_vol_get,
- .put = ad1986a_pcm_amp_vol_put,
- .tlv = { .c = snd_hda_mixer_amp_tlv },
- .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "PCM Playback Switch",
- .info = ad1986a_pcm_amp_sw_info,
- .get = ad1986a_pcm_amp_sw_get,
- .put = ad1986a_pcm_amp_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT)
- },
+ /*
+ * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
+ */
+ HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
+ HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
@@ -569,13 +500,30 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
/* laptop model - 2ch only */
static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
+/* master controls both pins 0x1a and 0x1b */
+static struct hda_bind_ctls ad1986a_laptop_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
+ 0,
+ },
+};
+
+static struct hda_bind_ctls ad1986a_laptop_master_sw = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
+ 0,
+ },
+};
+
static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
- /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */
+ HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
@@ -603,68 +551,114 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
/* laptop-eapd model - 2ch only */
-/* master controls both pins 0x1a and 0x1b */
-static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
+ .num_items = 3,
+ .items = {
+ { "Mic", 0x0 },
+ { "Internal Mic", 0x4 },
+ { "Mix", 0x5 },
+ },
+};
+
+static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
+ HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
+ HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = ad198x_mux_enum_info,
+ .get = ad198x_mux_enum_get,
+ .put = ad198x_mux_enum_put,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "External Amplifier",
+ .info = ad198x_eapd_info,
+ .get = ad198x_eapd_get,
+ .put = ad198x_eapd_put,
+ .private_value = 0x1b | (1 << 8), /* port-D, inversed */
+ },
+ { } /* end */
+};
+
+/* laptop-automute - 2ch only */
+
+static void ad1986a_update_hp(struct hda_codec *codec)
{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
+ struct ad198x_spec *spec = codec->spec;
+ unsigned int mute;
- change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- return change;
+ if (spec->jack_present)
+ mute = HDA_AMP_MUTE; /* mute internal speaker */
+ else
+ /* unmute internal speaker if necessary */
+ mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
+ snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
}
-static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+static void ad1986a_hp_automute(struct hda_codec *codec)
+{
+ struct ad198x_spec *spec = codec->spec;
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0);
+ spec->jack_present = (present & 0x80000000) != 0;
+ ad1986a_update_hp(codec);
+}
+
+#define AD1986A_HP_EVENT 0x37
+
+static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ if ((res >> 26) != AD1986A_HP_EVENT)
+ return;
+ ad1986a_hp_automute(codec);
+}
+
+static int ad1986a_hp_init(struct hda_codec *codec)
+{
+ ad198x_init(codec);
+ ad1986a_hp_automute(codec);
+ return 0;
+}
+
+/* bind hp and internal speaker mute (with plug check) */
+static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
long *valp = ucontrol->value.integer.value;
int change;
change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
- 0x80, valp[0] ? 0 : 0x80);
+ HDA_AMP_MUTE,
+ valp[0] ? 0 : HDA_AMP_MUTE);
change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
- 0x80, valp[1] ? 0 : 0x80);
- snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
- 0x80, valp[0] ? 0 : 0x80);
- snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
- 0x80, valp[1] ? 0 : 0x80);
+ HDA_AMP_MUTE,
+ valp[1] ? 0 : HDA_AMP_MUTE);
+ if (change)
+ ad1986a_update_hp(codec);
return change;
}
-static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
- .num_items = 3,
- .items = {
- { "Mic", 0x0 },
- { "Internal Mic", 0x4 },
- { "Mix", 0x5 },
- },
-};
-
-static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = ad1986a_laptop_master_vol_put,
- .tlv = { .c = snd_hda_mixer_amp_tlv },
- .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
- },
+static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = {
+ HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
.info = snd_hda_mixer_amp_switch_info,
.get = snd_hda_mixer_amp_switch_get,
- .put = ad1986a_laptop_master_sw_put,
+ .put = ad1986a_hp_master_sw_put,
.private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
},
HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
@@ -674,6 +668,8 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
{
@@ -807,12 +803,20 @@ static struct hda_verb ad1986a_ultra_init[] = {
{ } /* end */
};
+/* pin sensing on HP jack */
+static struct hda_verb ad1986a_hp_init_verbs[] = {
+ {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
+ {}
+};
+
+
/* models */
enum {
AD1986A_6STACK,
AD1986A_3STACK,
AD1986A_LAPTOP,
AD1986A_LAPTOP_EAPD,
+ AD1986A_LAPTOP_AUTOMUTE,
AD1986A_ULTRA,
AD1986A_MODELS
};
@@ -822,6 +826,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = {
[AD1986A_3STACK] = "3stack",
[AD1986A_LAPTOP] = "laptop",
[AD1986A_LAPTOP_EAPD] = "laptop-eapd",
+ [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
[AD1986A_ULTRA] = "ultra",
};
@@ -850,11 +855,22 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
- SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD),
+ SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
{}
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list ad1986a_loopbacks[] = {
+ { 0x13, HDA_OUTPUT, 0 }, /* Mic */
+ { 0x14, HDA_OUTPUT, 0 }, /* Phone */
+ { 0x15, HDA_OUTPUT, 0 }, /* CD */
+ { 0x16, HDA_OUTPUT, 0 }, /* Aux */
+ { 0x17, HDA_OUTPUT, 0 }, /* Line */
+ { } /* end */
+};
+#endif
+
static int patch_ad1986a(struct hda_codec *codec)
{
struct ad198x_spec *spec;
@@ -864,7 +880,6 @@ static int patch_ad1986a(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 6;
@@ -879,6 +894,9 @@ static int patch_ad1986a(struct hda_codec *codec)
spec->mixers[0] = ad1986a_mixers;
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1986a_init_verbs;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = ad1986a_loopbacks;
+#endif
codec->patch_ops = ad198x_patch_ops;
@@ -914,6 +932,19 @@ static int patch_ad1986a(struct hda_codec *codec)
spec->multiout.dig_out_nid = 0;
spec->input_mux = &ad1986a_laptop_eapd_capture_source;
break;
+ case AD1986A_LAPTOP_AUTOMUTE:
+ spec->mixers[0] = ad1986a_laptop_automute_mixers;
+ spec->num_init_verbs = 3;
+ spec->init_verbs[1] = ad1986a_eapd_init_verbs;
+ spec->init_verbs[2] = ad1986a_hp_init_verbs;
+ spec->multiout.max_channels = 2;
+ spec->multiout.num_dacs = 1;
+ spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
+ spec->multiout.dig_out_nid = 0;
+ spec->input_mux = &ad1986a_laptop_eapd_capture_source;
+ codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
+ codec->patch_ops.init = ad1986a_hp_init;
+ break;
case AD1986A_ULTRA:
spec->mixers[0] = ad1986a_laptop_eapd_mixers;
spec->num_init_verbs = 2;
@@ -982,8 +1013,9 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
spec->spdif_route = ucontrol->value.enumerated.item[0];
- snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
- AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
+ snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ spec->spdif_route);
return 1;
}
return 0;
@@ -1063,6 +1095,13 @@ static struct hda_verb ad1983_init_verbs[] = {
{ } /* end */
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list ad1983_loopbacks[] = {
+ { 0x12, HDA_OUTPUT, 0 }, /* Mic */
+ { 0x13, HDA_OUTPUT, 0 }, /* Line */
+ { } /* end */
+};
+#endif
static int patch_ad1983(struct hda_codec *codec)
{
@@ -1072,7 +1111,6 @@ static int patch_ad1983(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 2;
@@ -1088,6 +1126,9 @@ static int patch_ad1983(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1983_init_verbs;
spec->spdif_route = 0;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = ad1983_loopbacks;
+#endif
codec->patch_ops = ad198x_patch_ops;
@@ -1211,6 +1252,17 @@ static struct hda_verb ad1981_init_verbs[] = {
{ } /* end */
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list ad1981_loopbacks[] = {
+ { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
+ { 0x13, HDA_OUTPUT, 0 }, /* Line */
+ { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
+ { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
+ { 0x1d, HDA_OUTPUT, 0 }, /* CD */
+ { } /* end */
+};
+#endif
+
/*
* Patch for HP nx6320
*
@@ -1240,31 +1292,21 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
return 0;
/* toggle HP mute appropriately */
- snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
- 0x80, spec->cur_eapd ? 0 : 0x80);
- snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
- 0x80, spec->cur_eapd ? 0 : 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ spec->cur_eapd ? 0 : HDA_AMP_MUTE);
return 1;
}
/* bind volumes of both NID 0x05 and 0x06 */
-static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- return change;
-}
+static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
/* mute internal speaker if HP is plugged */
static void ad1981_hp_automute(struct hda_codec *codec)
@@ -1273,10 +1315,8 @@ static void ad1981_hp_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x06, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
/* toggle input of built-in and mic jack appropriately */
@@ -1327,14 +1367,7 @@ static struct hda_input_mux ad1981_hp_capture_source = {
};
static struct snd_kcontrol_new ad1981_hp_mixers[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = ad1981_hp_master_vol_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
- },
+ HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
@@ -1474,7 +1507,6 @@ static int patch_ad1981(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
spec->multiout.max_channels = 2;
@@ -1490,6 +1522,9 @@ static int patch_ad1981(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1981_init_verbs;
spec->spdif_route = 0;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = ad1981_loopbacks;
+#endif
codec->patch_ops = ad198x_patch_ops;
@@ -1897,16 +1932,19 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int sel;
- sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
- if (sel > 0) {
+ sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
+ AC_AMP_GET_INPUT);
+ if (!(sel & 0x80))
+ ucontrol->value.enumerated.item[0] = 0;
+ else {
sel = snd_hda_codec_read(codec, 0x0b, 0,
AC_VERB_GET_CONNECT_SEL, 0);
if (sel < 3)
sel++;
else
sel = 0;
+ ucontrol->value.enumerated.item[0] = sel;
}
- ucontrol->value.enumerated.item[0] = sel;
return 0;
}
@@ -1918,23 +1956,39 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
int change;
val = ucontrol->value.enumerated.item[0];
- sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
if (!val) {
- change = sel != 0;
- if (change || codec->in_resume)
- snd_hda_codec_write(codec, 0x02, 0,
- AC_VERB_SET_CONNECT_SEL, 0);
+ sel = snd_hda_codec_read(codec, 0x1d, 0,
+ AC_VERB_GET_AMP_GAIN_MUTE,
+ AC_AMP_GET_INPUT);
+ change = sel & 0x80;
+ if (change) {
+ snd_hda_codec_write_cache(codec, 0x1d, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_IN_UNMUTE(0));
+ snd_hda_codec_write_cache(codec, 0x1d, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_IN_MUTE(1));
+ }
} else {
- change = sel == 0;
- if (change || codec->in_resume)
- snd_hda_codec_write(codec, 0x02, 0,
- AC_VERB_SET_CONNECT_SEL, 1);
+ sel = snd_hda_codec_read(codec, 0x1d, 0,
+ AC_VERB_GET_AMP_GAIN_MUTE,
+ AC_AMP_GET_INPUT | 0x01);
+ change = sel & 0x80;
+ if (change) {
+ snd_hda_codec_write_cache(codec, 0x1d, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_IN_MUTE(0));
+ snd_hda_codec_write_cache(codec, 0x1d, 0,
+ AC_VERB_SET_AMP_GAIN_MUTE,
+ AMP_IN_UNMUTE(1));
+ }
sel = snd_hda_codec_read(codec, 0x0b, 0,
AC_VERB_GET_CONNECT_SEL, 0) + 1;
change |= sel != val;
- if (change || codec->in_resume)
- snd_hda_codec_write(codec, 0x0b, 0,
- AC_VERB_SET_CONNECT_SEL, val - 1);
+ if (change)
+ snd_hda_codec_write_cache(codec, 0x0b, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ val - 1);
}
return change;
}
@@ -2047,10 +2101,9 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
/* SPDIF out pin */
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
- {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */
{ }
};
@@ -2225,6 +2278,15 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list ad1988_loopbacks[] = {
+ { 0x20, HDA_INPUT, 0 }, /* Front Mic */
+ { 0x20, HDA_INPUT, 1 }, /* Line */
+ { 0x20, HDA_INPUT, 4 }, /* Mic */
+ { 0x20, HDA_INPUT, 6 }, /* CD */
+ { } /* end */
+};
+#endif
/*
* Automatic parse of I/O pins from the BIOS configuration
@@ -2663,7 +2725,6 @@ static int patch_ad1988(struct hda_codec *codec)
if (spec == NULL)
return -ENOMEM;
- mutex_init(&spec->amp_mutex);
codec->spec = spec;
if (is_rev2(codec))
@@ -2770,6 +2831,9 @@ static int patch_ad1988(struct hda_codec *codec)
codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
break;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = ad1988_loopbacks;
+#endif
return 0;
}
@@ -2926,6 +2990,16 @@ static struct hda_verb ad1884_init_verbs[] = {
{ } /* end */
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list ad1884_loopbacks[] = {
+ { 0x20, HDA_INPUT, 0 }, /* Front Mic */
+ { 0x20, HDA_INPUT, 1 }, /* Mic */
+ { 0x20, HDA_INPUT, 2 }, /* CD */
+ { 0x20, HDA_INPUT, 4 }, /* Docking */
+ { } /* end */
+};
+#endif
+
static int patch_ad1884(struct hda_codec *codec)
{
struct ad198x_spec *spec;
@@ -2950,6 +3024,9 @@ static int patch_ad1884(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1884_init_verbs;
spec->spdif_route = 0;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = ad1884_loopbacks;
+#endif
codec->patch_ops = ad198x_patch_ops;
@@ -3331,6 +3408,16 @@ static struct hda_verb ad1882_init_verbs[] = {
{ } /* end */
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list ad1882_loopbacks[] = {
+ { 0x20, HDA_INPUT, 0 }, /* Front Mic */
+ { 0x20, HDA_INPUT, 1 }, /* Mic */
+ { 0x20, HDA_INPUT, 4 }, /* Line */
+ { 0x20, HDA_INPUT, 6 }, /* CD */
+ { } /* end */
+};
+#endif
+
/* models */
enum {
AD1882_3STACK,
@@ -3369,6 +3456,9 @@ static int patch_ad1882(struct hda_codec *codec)
spec->num_init_verbs = 1;
spec->init_verbs[0] = ad1882_init_verbs;
spec->spdif_route = 0;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = ad1882_loopbacks;
+#endif
codec->patch_ops = ad198x_patch_ops;
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 72d3ab9751a..fbb8969dc55 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -62,19 +62,6 @@ static int atihdmi_init(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int atihdmi_resume(struct hda_codec *codec)
-{
- atihdmi_init(codec);
- snd_hda_resume_spdif_out(codec);
-
- return 0;
-}
-#endif
-
/*
* Digital out
*/
@@ -141,9 +128,6 @@ static struct hda_codec_ops atihdmi_patch_ops = {
.build_pcms = atihdmi_build_pcms,
.init = atihdmi_init,
.free = atihdmi_free,
-#ifdef CONFIG_PM
- .resume = atihdmi_resume,
-#endif
};
static int patch_atihdmi(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 3c722e667bc..2468f317122 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -427,27 +427,6 @@ static int cmi9880_init(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int cmi9880_resume(struct hda_codec *codec)
-{
- struct cmi_spec *spec = codec->spec;
-
- cmi9880_init(codec);
- snd_hda_resume_ctls(codec, cmi9880_basic_mixer);
- if (spec->channel_modes)
- snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer);
- if (spec->multiout.dig_out_nid)
- snd_hda_resume_spdif_out(codec);
- if (spec->dig_in_nid)
- snd_hda_resume_spdif_in(codec);
-
- return 0;
-}
-#endif
-
/*
* Analog playback callbacks
*/
@@ -635,9 +614,6 @@ static struct hda_codec_ops cmi9880_patch_ops = {
.build_pcms = cmi9880_build_pcms,
.init = cmi9880_init,
.free = cmi9880_free,
-#ifdef CONFIG_PM
- .resume = cmi9880_resume,
-#endif
};
static int patch_cmi9880(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 4d8e8af5c81..080e3001d9c 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -311,23 +311,6 @@ static void conexant_free(struct hda_codec *codec)
kfree(codec->spec);
}
-#ifdef CONFIG_PM
-static int conexant_resume(struct hda_codec *codec)
-{
- struct conexant_spec *spec = codec->spec;
- int i;
-
- codec->patch_ops.init(codec);
- for (i = 0; i < spec->num_mixers; i++)
- snd_hda_resume_ctls(codec, spec->mixers[i]);
- if (spec->multiout.dig_out_nid)
- snd_hda_resume_spdif_out(codec);
- if (spec->dig_in_nid)
- snd_hda_resume_spdif_in(codec);
- return 0;
-}
-#endif
-
static int conexant_build_controls(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
@@ -358,9 +341,6 @@ static struct hda_codec_ops conexant_patch_ops = {
.build_pcms = conexant_build_pcms,
.init = conexant_init,
.free = conexant_free,
-#ifdef CONFIG_PM
- .resume = conexant_resume,
-#endif
};
/*
@@ -368,15 +348,7 @@ static struct hda_codec_ops conexant_patch_ops = {
* the private value = nid | (invert << 8)
*/
-static int cxt_eapd_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define cxt_eapd_info snd_ctl_boolean_mono_info
static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -404,13 +376,13 @@ static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
eapd = ucontrol->value.integer.value[0];
if (invert)
eapd = !eapd;
- if (eapd == spec->cur_eapd && !codec->in_resume)
+ if (eapd == spec->cur_eapd)
return 0;
spec->cur_eapd = eapd;
- snd_hda_codec_write(codec, nid,
- 0, AC_VERB_SET_EAPD_BTLENABLE,
- eapd ? 0x02 : 0x00);
+ snd_hda_codec_write_cache(codec, nid,
+ 0, AC_VERB_SET_EAPD_BTLENABLE,
+ eapd ? 0x02 : 0x00);
return 1;
}
@@ -500,34 +472,25 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
/* toggle internal speakers mute depending of presence of
* the headphone jack
*/
- bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
- snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
+ bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
- bits = spec->cur_eapd ? 0 : 0x80;
- snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits);
+ bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
return 1;
}
/* bind volumes of both NID 0x10 and 0x11 */
-static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- change |= snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- return change;
-}
+static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
/* toggle input of built-in and mic jack appropriately */
static void cxt5045_hp_automic(struct hda_codec *codec)
@@ -562,9 +525,9 @@ static void cxt5045_hp_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
+ bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
/* unsolicited event for HP jack sensing */
@@ -595,14 +558,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = cxt5045_hp_master_vol_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
- },
+ HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
@@ -915,33 +871,24 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
/* toggle internal speakers mute depending of presence of
* the headphone jack
*/
- bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
- snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
- bits = spec->cur_eapd ? 0 : 0x80;
- snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, 0x80, bits);
+ bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
+ bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
return 1;
}
/* bind volumes of both NID 0x13 (Headphones) and 0x1d (Speakers) */
-static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- change |= snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- return change;
-}
+static struct hda_bind_ctls cxt5047_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
/* mute internal speaker if HP is plugged */
static void cxt5047_hp_automute(struct hda_codec *codec)
@@ -952,12 +899,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
+ bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
/* Mute/Unmute PCM 2 for good measure - some systems need this */
- snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
+ snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
/* mute internal speaker if HP is plugged */
@@ -969,12 +916,12 @@ static void cxt5047_hp2_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = spec->hp_present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
+ bits = spec->hp_present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
/* Mute/Unmute PCM 2 for good measure - some systems need this */
- snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
+ snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
/* toggle input of built-in and mic jack appropriately */
@@ -1063,14 +1010,7 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = {
HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = cxt5047_hp_master_vol_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
- },
+ HDA_BIND_VOL("Master Playback Volume", &cxt5047_bind_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9a47eec5a27..53b0428abfc 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -102,6 +102,8 @@ enum {
/* ALC268 models */
enum {
ALC268_3ST,
+ ALC268_TOSHIBA,
+ ALC268_ACER,
ALC268_AUTO,
ALC268_MODEL_LAST /* last tag */
};
@@ -129,6 +131,7 @@ enum {
ALC861VD_6ST_DIG,
ALC861VD_LENOVO,
ALC861VD_DALLAS,
+ ALC861VD_HP,
ALC861VD_AUTO,
ALC861VD_MODEL_LAST,
};
@@ -140,6 +143,7 @@ enum {
ALC662_3ST_6ch,
ALC662_5ST_DIG,
ALC662_LENOVO_101E,
+ ALC662_ASUS_EEEPC_P701,
ALC662_AUTO,
ALC662_MODEL_LAST,
};
@@ -152,7 +156,9 @@ enum {
ALC882_W2JC,
ALC882_TARGA,
ALC882_ASUS_A7J,
+ ALC882_ASUS_A7M,
ALC885_MACPRO,
+ ALC885_MBP3,
ALC885_IMAC24,
ALC882_AUTO,
ALC882_MODEL_LAST,
@@ -167,12 +173,14 @@ enum {
ALC883_TARGA_DIG,
ALC883_TARGA_2ch_DIG,
ALC883_ACER,
+ ALC883_ACER_ASPIRE,
ALC883_MEDION,
ALC883_MEDION_MD2,
ALC883_LAPTOP_EAPD,
ALC883_LENOVO_101E_2ch,
ALC883_LENOVO_NB0763,
- ALC888_LENOVO_MS7195_DIG,
+ ALC888_LENOVO_MS7195_DIG,
+ ALC883_HAIER_W66,
ALC888_6ST_HP,
ALC888_3ST_HP,
ALC883_AUTO,
@@ -239,6 +247,10 @@ struct alc_spec {
/* for pin sensing */
unsigned int sense_updated: 1;
unsigned int jack_present: 1;
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ struct hda_loopback_check loopback;
+#endif
};
/*
@@ -263,6 +275,9 @@ struct alc_config_preset {
const struct hda_input_mux *input_mux;
void (*unsol_event)(struct hda_codec *, unsigned int);
void (*init_hook)(struct hda_codec *);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ struct hda_amp_list *loopbacks;
+#endif
};
@@ -441,8 +456,9 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
change = pinctl != alc_pin_mode_values[val];
if (change) {
/* Set pin mode to that requested */
- snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
- alc_pin_mode_values[val]);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ alc_pin_mode_values[val]);
/* Also enable the retasking pin's input/output as required
* for the requested pin mode. Enum values of 2 or less are
@@ -455,19 +471,15 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
* this turns out to be necessary in the future.
*/
if (val <= 2) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_MUTE);
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_UNMUTE(0));
+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
+ HDA_AMP_MUTE, 0);
} else {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_IN_MUTE(0));
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_AMP_GAIN_MUTE,
- AMP_OUT_UNMUTE);
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, 0);
}
}
return change;
@@ -486,15 +498,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
* needed for any "production" models.
*/
#ifdef CONFIG_SND_DEBUG
-static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define alc_gpio_data_info snd_ctl_boolean_mono_info
static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -527,7 +531,8 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
gpio_data &= ~mask;
else
gpio_data |= mask;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_GPIO_DATA, gpio_data);
return change;
}
@@ -547,15 +552,7 @@ static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
* necessary.
*/
#ifdef CONFIG_SND_DEBUG
-static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -588,8 +585,8 @@ static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
ctrl_data &= ~mask;
else
ctrl_data |= mask;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
- ctrl_data);
+ snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+ ctrl_data);
return change;
}
@@ -638,6 +635,9 @@ static void setup_preset(struct alc_spec *spec,
spec->unsol_event = preset->unsol_event;
spec->init_hook = preset->init_hook;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = preset->loopbacks;
+#endif
}
/* Enable GPIO mask and set output */
@@ -662,6 +662,44 @@ static struct hda_verb alc_gpio3_init_verbs[] = {
{ }
};
+static void alc_sku_automute(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ unsigned int mute;
+ unsigned int present;
+ unsigned int hp_nid = spec->autocfg.hp_pins[0];
+ unsigned int sp_nid = spec->autocfg.speaker_pins[0];
+
+ /* need to execute and sync at first */
+ snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
+ present = snd_hda_codec_read(codec, hp_nid, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+ spec->jack_present = (present & 0x80000000) != 0;
+ if (spec->jack_present) {
+ /* mute internal speaker */
+ snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
+ } else {
+ /* unmute internal speaker if necessary */
+ mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
+ snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ }
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ if (codec->vendor_id == 0x10ec0880)
+ res >>= 28;
+ else
+ res >>= 26;
+ if (res != ALC880_HP_EVENT)
+ return;
+
+ alc_sku_automute(codec);
+}
+
/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
* 31 ~ 16 : Manufacture ID
* 15 ~ 8 : SKU ID
@@ -672,13 +710,48 @@ static void alc_subsystem_id(struct hda_codec *codec,
unsigned int porta, unsigned int porte,
unsigned int portd)
{
- unsigned int ass, tmp;
+ unsigned int ass, tmp, i;
+ unsigned nid;
+ struct alc_spec *spec = codec->spec;
- ass = codec->subsystem_id;
- if (!(ass & 1))
+ ass = codec->subsystem_id & 0xffff;
+ if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
+ goto do_sku;
+
+ /*
+ * 31~30 : port conetcivity
+ * 29~21 : reserve
+ * 20 : PCBEEP input
+ * 19~16 : Check sum (15:1)
+ * 15~1 : Custom
+ * 0 : override
+ */
+ nid = 0x1d;
+ if (codec->vendor_id == 0x10ec0260)
+ nid = 0x17;
+ ass = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONFIG_DEFAULT, 0);
+ if (!(ass & 1) && !(ass & 0x100000))
+ return;
+ if ((ass >> 30) != 1) /* no physical connection */
return;
- /* Override */
+ /* check sum */
+ tmp = 0;
+ for (i = 1; i < 16; i++) {
+ if ((ass >> i) && 1)
+ tmp++;
+ }
+ if (((ass >> 16) & 0xf) != tmp)
+ return;
+do_sku:
+ /*
+ * 0 : override
+ * 1 : Swap Jack
+ * 2 : 0 --> Desktop, 1 --> Laptop
+ * 3~5 : External Amplifier control
+ * 7~6 : Reserved
+ */
tmp = (ass & 0x38) >> 3; /* external Amp control */
switch (tmp) {
case 1:
@@ -690,38 +763,108 @@ static void alc_subsystem_id(struct hda_codec *codec,
case 7:
snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
break;
- case 5:
+ case 5: /* set EAPD output high */
switch (codec->vendor_id) {
- case 0x10ec0862:
- case 0x10ec0660:
- case 0x10ec0662:
+ case 0x10ec0260:
+ snd_hda_codec_write(codec, 0x0f, 0,
+ AC_VERB_SET_EAPD_BTLENABLE, 2);
+ snd_hda_codec_write(codec, 0x10, 0,
+ AC_VERB_SET_EAPD_BTLENABLE, 2);
+ break;
+ case 0x10ec0262:
case 0x10ec0267:
case 0x10ec0268:
+ case 0x10ec0269:
+ case 0x10ec0862:
+ case 0x10ec0662:
snd_hda_codec_write(codec, 0x14, 0,
AC_VERB_SET_EAPD_BTLENABLE, 2);
snd_hda_codec_write(codec, 0x15, 0,
AC_VERB_SET_EAPD_BTLENABLE, 2);
- return;
+ break;
}
- case 6:
- if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */
- hda_nid_t port = 0;
- tmp = (ass & 0x1800) >> 11;
- switch (tmp) {
- case 0: port = porta; break;
- case 1: port = porte; break;
- case 2: port = portd; break;
- }
- if (port)
- snd_hda_codec_write(codec, port, 0,
- AC_VERB_SET_EAPD_BTLENABLE,
- 2);
+ switch (codec->vendor_id) {
+ case 0x10ec0260:
+ snd_hda_codec_write(codec, 0x1a, 0,
+ AC_VERB_SET_COEF_INDEX, 7);
+ tmp = snd_hda_codec_read(codec, 0x1a, 0,
+ AC_VERB_GET_PROC_COEF, 0);
+ snd_hda_codec_write(codec, 0x1a, 0,
+ AC_VERB_SET_COEF_INDEX, 7);
+ snd_hda_codec_write(codec, 0x1a, 0,
+ AC_VERB_SET_PROC_COEF,
+ tmp | 0x2010);
+ break;
+ case 0x10ec0262:
+ case 0x10ec0880:
+ case 0x10ec0882:
+ case 0x10ec0883:
+ case 0x10ec0885:
+ case 0x10ec0888:
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_COEF_INDEX, 7);
+ tmp = snd_hda_codec_read(codec, 0x20, 0,
+ AC_VERB_GET_PROC_COEF, 0);
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_COEF_INDEX, 7);
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_PROC_COEF,
+ tmp | 0x2010);
+ break;
+ case 0x10ec0267:
+ case 0x10ec0268:
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_COEF_INDEX, 7);
+ tmp = snd_hda_codec_read(codec, 0x20, 0,
+ AC_VERB_GET_PROC_COEF, 0);
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_COEF_INDEX, 7);
+ snd_hda_codec_write(codec, 0x20, 0,
+ AC_VERB_SET_PROC_COEF,
+ tmp | 0x3000);
+ break;
}
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
- snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
- (tmp == 5 ? 0x3040 : 0x3050));
+ default:
break;
}
+
+ /* is laptop and enable the function "Mute internal speaker
+ * when the external headphone out jack is plugged"
+ */
+ if (!(ass & 0x4) || !(ass & 0x8000))
+ return;
+ /*
+ * 10~8 : Jack location
+ * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
+ * 14~13: Resvered
+ * 15 : 1 --> enable the function "Mute internal speaker
+ * when the external headphone out jack is plugged"
+ */
+ if (!spec->autocfg.speaker_pins[0]) {
+ if (spec->multiout.dac_nids[0])
+ spec->autocfg.speaker_pins[0] =
+ spec->multiout.dac_nids[0];
+ else
+ return;
+ }
+
+ if (!spec->autocfg.hp_pins[0]) {
+ tmp = (ass >> 11) & 0x3; /* HP to chassis */
+ if (tmp == 0)
+ spec->autocfg.hp_pins[0] = porta;
+ else if (tmp == 1)
+ spec->autocfg.hp_pins[0] = porte;
+ else if (tmp == 2)
+ spec->autocfg.hp_pins[0] = portd;
+ else
+ return;
+ }
+
+ snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | ALC880_HP_EVENT);
+ spec->unsol_event = alc_sku_unsol_event;
+ spec->init_hook = alc_sku_automute;
}
/*
@@ -1304,11 +1447,13 @@ static struct hda_verb alc880_volume_init_verbs[] = {
* panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
/*
* Set up output mixers (0x0c - 0x0f)
@@ -1568,15 +1713,11 @@ static void alc880_uniwill_hp_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
+ snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
/* auto-toggle front mic */
@@ -1587,11 +1728,8 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x18, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
}
static void alc880_uniwill_automute(struct hda_codec *codec)
@@ -1623,11 +1761,8 @@ static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
}
static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -1635,19 +1770,14 @@ static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
unsigned int present;
present = snd_hda_codec_read(codec, 0x21, 0,
- AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
-
- snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
- 0x7f, present);
- snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
- 0x7f, present);
-
- snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
- 0x7f, present);
- snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
- 0x7f, present);
-
+ AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
+ present &= HDA_AMP_VOLMASK;
+ snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
+ HDA_AMP_VOLMASK, present);
+ snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
+ HDA_AMP_VOLMASK, present);
}
+
static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
unsigned int res)
{
@@ -1868,8 +1998,8 @@ static struct hda_verb alc880_lg_init_verbs[] = {
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* mute all amp mixer inputs */
{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
/* line-in to input */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -1900,11 +2030,9 @@ static void alc880_lg_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1973,7 +2101,7 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
/* speaker-out */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -1999,11 +2127,9 @@ static void alc880_lg_lw_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -2015,6 +2141,24 @@ static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
alc880_lg_lw_automute(codec);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list alc880_loopbacks[] = {
+ { 0x0b, HDA_INPUT, 0 },
+ { 0x0b, HDA_INPUT, 1 },
+ { 0x0b, HDA_INPUT, 2 },
+ { 0x0b, HDA_INPUT, 3 },
+ { 0x0b, HDA_INPUT, 4 },
+ { } /* end */
+};
+
+static struct hda_amp_list alc880_lg_loopbacks[] = {
+ { 0x0b, HDA_INPUT, 1 },
+ { 0x0b, HDA_INPUT, 6 },
+ { 0x0b, HDA_INPUT, 7 },
+ { } /* end */
+};
+#endif
+
/*
* Common callbacks
*/
@@ -2041,24 +2185,11 @@ static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
spec->unsol_event(codec, res);
}
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int alc_resume(struct hda_codec *codec)
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct alc_spec *spec = codec->spec;
- int i;
-
- alc_init(codec);
- for (i = 0; i < spec->num_mixers; i++)
- snd_hda_resume_ctls(codec, spec->mixers[i]);
- if (spec->multiout.dig_out_nid)
- snd_hda_resume_spdif_out(codec);
- if (spec->dig_in_nid)
- snd_hda_resume_spdif_in(codec);
-
- return 0;
+ return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
}
#endif
@@ -2293,8 +2424,8 @@ static struct hda_codec_ops alc_patch_ops = {
.init = alc_init,
.free = alc_free,
.unsol_event = alc_unsol_event,
-#ifdef CONFIG_PM
- .resume = alc_resume,
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ .check_power_status = alc_check_power_status,
#endif
};
@@ -2392,11 +2523,14 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
new_ctl = ctls[ucontrol->value.enumerated.item[0]];
if (old_ctl != new_ctl) {
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- (ucontrol->value.enumerated.item[0] >= 3 ?
- 0xb080 : 0xb000));
+ int val;
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ new_ctl);
+ val = ucontrol->value.enumerated.item[0] >= 3 ?
+ HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, val);
return 1;
}
return 0;
@@ -2439,7 +2573,8 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
if (ucontrol->value.enumerated.item[0] != sel) {
sel = ucontrol->value.enumerated.item[0] & 3;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_CONNECT_SEL, sel);
return 1;
}
return 0;
@@ -2885,6 +3020,7 @@ static struct alc_config_preset alc880_presets[] = {
alc880_beep_init_verbs },
.num_dacs = ARRAY_SIZE(alc880_dac_nids),
.dac_nids = alc880_dac_nids,
+ .dig_out_nid = ALC880_DIGOUT_NID,
.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_capture_source,
@@ -2916,6 +3052,9 @@ static struct alc_config_preset alc880_presets[] = {
.input_mux = &alc880_lg_capture_source,
.unsol_event = alc880_lg_unsol_event,
.init_hook = alc880_lg_automute,
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ .loopbacks = alc880_lg_loopbacks,
+#endif
},
[ALC880_LG_LW] = {
.mixers = { alc880_lg_lw_mixer },
@@ -3399,6 +3538,10 @@ static int patch_alc880(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC880_AUTO)
spec->init_hook = alc880_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc880_loopbacks;
+#endif
return 0;
}
@@ -3747,12 +3890,12 @@ static struct hda_verb alc260_init_verbs[] = {
/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
* Line In 2 = 0x03
*/
- /* mute CD */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
- /* mute Line In */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- /* mute Mic */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ /* mute analog inputs */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
/* mute Front out path */
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -3797,12 +3940,12 @@ static struct hda_verb alc260_hp_init_verbs[] = {
/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
* Line In 2 = 0x03
*/
- /* unmute CD */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
- /* unmute Line In */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
- /* unmute Mic */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+ /* mute analog inputs */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
/* Unmute Front out path */
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
@@ -3847,12 +3990,12 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
* Line In 2 = 0x03
*/
- /* unmute CD */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
- /* unmute Line In */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
- /* unmute Mic */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+ /* mute analog inputs */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
/* Unmute Front out path */
{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
@@ -4069,13 +4212,17 @@ static void alc260_replacer_672v_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x0f, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
if (present) {
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
- snd_hda_codec_write(codec, 0x0f, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+ snd_hda_codec_write_cache(codec, 0x01, 0,
+ AC_VERB_SET_GPIO_DATA, 1);
+ snd_hda_codec_write_cache(codec, 0x0f, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ PIN_HP);
} else {
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
- snd_hda_codec_write(codec, 0x0f, 0,
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+ snd_hda_codec_write_cache(codec, 0x01, 0,
+ AC_VERB_SET_GPIO_DATA, 0);
+ snd_hda_codec_write_cache(codec, 0x0f, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL,
+ PIN_OUT);
}
}
@@ -4470,11 +4617,12 @@ static struct hda_verb alc260_volume_init_verbs[] = {
* front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ /* mute analog inputs */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x08 - 0x0a)
@@ -4551,6 +4699,17 @@ static void alc260_auto_init(struct hda_codec *codec)
alc260_auto_init_analog_input(codec);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list alc260_loopbacks[] = {
+ { 0x07, HDA_INPUT, 0 },
+ { 0x07, HDA_INPUT, 1 },
+ { 0x07, HDA_INPUT, 2 },
+ { 0x07, HDA_INPUT, 3 },
+ { 0x07, HDA_INPUT, 4 },
+ { } /* end */
+};
+#endif
+
/*
* ALC260 configurations
*/
@@ -4750,6 +4909,10 @@ static int patch_alc260(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC260_AUTO)
spec->init_hook = alc260_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc260_loopbacks;
+#endif
return 0;
}
@@ -4812,12 +4975,13 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && !codec->in_resume)
+ if (*cur_val == idx)
return 0;
for (i = 0; i < imux->num_items; i++) {
- unsigned int v = (i == idx) ? 0x7000 : 0x7080;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- v | (imux->items[i].index << 8));
+ unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
+ imux->items[i].index,
+ HDA_AMP_MUTE, v);
}
*cur_val = idx;
return 1;
@@ -4879,6 +5043,38 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
{ 8, alc882_sixstack_ch8_init },
};
+/*
+ * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
+ */
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc885_mbp_ch2_init[] = {
+ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+ { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ { } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc885_mbp_ch6_init[] = {
+ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
+ { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ { } /* end */
+};
+
+static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
+ { 2, alc885_mbp_ch2_init },
+ { 6, alc885_mbp_ch6_init },
+};
+
+
/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
* Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
*/
@@ -4909,6 +5105,19 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
+ HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
+ HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
+ HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
+ { } /* end */
+};
static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -4934,8 +5143,10 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = {
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
{ } /* end */
};
@@ -4955,6 +5166,23 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ { } /* end */
+};
+
+static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+ HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+ HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
{ } /* end */
};
@@ -5119,6 +5347,66 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
{ }
};
+/* Macbook Pro rev3 */
+static struct hda_verb alc885_mbp3_init_verbs[] = {
+ /* Front mixer: unmute input/output amp left and right (volume = 0) */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ /* Rear mixer */
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ /* Front Pin: output 0 (0x0c) */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* HP Pin: output 0 (0x0d) */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ /* Mic (rear) pin: input vref at 80% */
+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Front Mic pin: input vref at 80% */
+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+ {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ /* Line In pin: use output 1 when in LineOut mode */
+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
+
+ /* FIXME: use matrix-type input source selection */
+ /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+ /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ /* Input mixer2 */
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ /* Input mixer3 */
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ /* ADC1: mute amp left and right */
+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* ADC2: mute amp left and right */
+ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* ADC3: mute amp left and right */
+ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+ { }
+};
+
/* iMac 24 mixer. */
static struct snd_kcontrol_new alc885_imac24_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
@@ -5154,14 +5442,10 @@ static void alc885_imac24_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
/* Processes unsolicited events. */
@@ -5173,6 +5457,27 @@ static void alc885_imac24_unsol_event(struct hda_codec *codec,
alc885_imac24_automute(codec);
}
+static void alc885_mbp3_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
+
+}
+static void alc885_mbp3_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ /* Headphone insertion or removal. */
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc885_mbp3_automute(codec);
+}
+
+
static struct hda_verb alc882_targa_verbs[] = {
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -5198,11 +5503,10 @@ static void alc882_targa_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+ snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+ present ? 1 : 3);
}
static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -5233,6 +5537,24 @@ static struct hda_verb alc882_asus_a7j_verbs[] = {
{ } /* end */
};
+static struct hda_verb alc882_asus_a7m_verbs[] = {
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+ {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+ {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
+
+ {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
+ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
+ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+ { } /* end */
+};
+
static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
{
unsigned int gpiostate, gpiomask, gpiodir;
@@ -5265,6 +5587,20 @@ static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
AC_VERB_SET_GPIO_DATA, gpiostate);
}
+/* set up GPIO at initialization */
+static void alc885_macpro_init_hook(struct hda_codec *codec)
+{
+ alc882_gpio_mute(codec, 0, 0);
+ alc882_gpio_mute(codec, 1, 0);
+}
+
+/* set up GPIO and update auto-muting at initialization */
+static void alc885_imac24_init_hook(struct hda_codec *codec)
+{
+ alc885_macpro_init_hook(codec);
+ alc885_imac24_automute(codec);
+}
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -5279,17 +5615,17 @@ static struct hda_verb alc882_auto_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
* Note: PASD motherboards uses the Line In 2 as the input for
* front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x0c - 0x0f)
@@ -5378,6 +5714,10 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = {
{ } /* end */
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+#define alc882_loopbacks alc880_loopbacks
+#endif
+
/* pcm configuration: identiacal with ALC880 */
#define alc882_pcm_analog_playback alc880_pcm_analog_playback
#define alc882_pcm_analog_capture alc880_pcm_analog_capture
@@ -5392,7 +5732,11 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
[ALC882_6ST_DIG] = "6stack-dig",
[ALC882_ARIMA] = "arima",
[ALC882_W2JC] = "w2jc",
+ [ALC882_TARGA] = "targa",
+ [ALC882_ASUS_A7J] = "asus-a7j",
+ [ALC882_ASUS_A7M] = "asus-a7m",
[ALC885_MACPRO] = "macpro",
+ [ALC885_MBP3] = "mbp3",
[ALC885_IMAC24] = "imac24",
[ALC882_AUTO] = "auto",
};
@@ -5404,6 +5748,8 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
+ SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
+ SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
@@ -5455,6 +5801,20 @@ static struct alc_config_preset alc882_presets[] = {
.input_mux = &alc882_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
},
+ [ALC885_MBP3] = {
+ .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
+ .init_verbs = { alc885_mbp3_init_verbs,
+ alc880_gpio1_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+ .dac_nids = alc882_dac_nids,
+ .channel_mode = alc885_mbp_6ch_modes,
+ .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
+ .input_mux = &alc882_capture_source,
+ .dig_out_nid = ALC882_DIGOUT_NID,
+ .dig_in_nid = ALC882_DIGIN_NID,
+ .unsol_event = alc885_mbp3_unsol_event,
+ .init_hook = alc885_mbp3_automute,
+ },
[ALC885_MACPRO] = {
.mixers = { alc882_macpro_mixer },
.init_verbs = { alc882_macpro_init_verbs },
@@ -5465,6 +5825,7 @@ static struct alc_config_preset alc882_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
.channel_mode = alc882_ch_modes,
.input_mux = &alc882_capture_source,
+ .init_hook = alc885_macpro_init_hook,
},
[ALC885_IMAC24] = {
.mixers = { alc885_imac24_mixer },
@@ -5477,7 +5838,7 @@ static struct alc_config_preset alc882_presets[] = {
.channel_mode = alc882_ch_modes,
.input_mux = &alc882_capture_source,
.unsol_event = alc885_imac24_unsol_event,
- .init_hook = alc885_imac24_automute,
+ .init_hook = alc885_imac24_init_hook,
},
[ALC882_TARGA] = {
.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
@@ -5509,6 +5870,19 @@ static struct alc_config_preset alc882_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc882_capture_source,
},
+ [ALC882_ASUS_A7M] = {
+ .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
+ .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
+ alc880_gpio1_init_verbs,
+ alc882_asus_a7m_verbs },
+ .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+ .dac_nids = alc882_dac_nids,
+ .dig_out_nid = ALC882_DIGOUT_NID,
+ .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+ .channel_mode = alc880_threestack_modes,
+ .need_dac_fix = 1,
+ .input_mux = &alc882_capture_source,
+ },
};
@@ -5608,6 +5982,32 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
}
}
+/* add mic boosts if needed */
+static int alc_auto_add_mic_boost(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ int err;
+ hda_nid_t nid;
+
+ nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
+ if (nid) {
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Mic Boost",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
+ if (err < 0)
+ return err;
+ }
+ nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
+ if (nid) {
+ err = add_control(spec, ALC_CTL_WIDGET_VOL,
+ "Front Mic Boost",
+ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
/* almost identical with ALC880 parser... */
static int alc882_parse_auto_config(struct hda_codec *codec)
{
@@ -5616,10 +6016,17 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
if (err < 0)
return err;
- else if (err > 0)
- /* hack - override the init verbs */
- spec->init_verbs[0] = alc882_auto_init_verbs;
- return err;
+ else if (!err)
+ return 0; /* no config found */
+
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
+ /* hack - override the init verbs */
+ spec->init_verbs[0] = alc882_auto_init_verbs;
+
+ return 1; /* config found */
}
/* additional initialization for auto-configuration model */
@@ -5654,6 +6061,9 @@ static int patch_alc882(struct hda_codec *codec)
case 0x106b1000: /* iMac 24 */
board_config = ALC885_IMAC24;
break;
+ case 0x106b2c00: /* Macbook Pro rev3 */
+ board_config = ALC885_MBP3;
+ break;
default:
printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
"trying auto-probe from BIOS...\n");
@@ -5680,11 +6090,6 @@ static int patch_alc882(struct hda_codec *codec)
if (board_config != ALC882_AUTO)
setup_preset(spec, &alc882_presets[board_config]);
- if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
- alc882_gpio_mute(codec, 0, 0);
- alc882_gpio_mute(codec, 1, 0);
- }
-
spec->stream_name_analog = "ALC882 Analog";
spec->stream_analog_playback = &alc882_pcm_analog_playback;
spec->stream_analog_capture = &alc882_pcm_analog_capture;
@@ -5715,6 +6120,10 @@ static int patch_alc882(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC882_AUTO)
spec->init_hook = alc882_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc882_loopbacks;
+#endif
return 0;
}
@@ -5792,12 +6201,13 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && !codec->in_resume)
+ if (*cur_val == idx)
return 0;
for (i = 0; i < imux->num_items; i++) {
- unsigned int v = (i == idx) ? 0x7000 : 0x7080;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- v | (imux->items[i].index << 8));
+ unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
+ imux->items[i].index,
+ HDA_AMP_MUTE, v);
}
*cur_val = idx;
return 1;
@@ -5822,6 +6232,18 @@ static struct hda_verb alc883_3ST_ch2_init[] = {
};
/*
+ * 4ch mode
+ */
+static struct hda_verb alc883_3ST_ch4_init[] = {
+ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+ { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+ { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+ { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
+ { } /* end */
+};
+
+/*
* 6ch mode
*/
static struct hda_verb alc883_3ST_ch6_init[] = {
@@ -5834,8 +6256,9 @@ static struct hda_verb alc883_3ST_ch6_init[] = {
{ } /* end */
};
-static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
+static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
{ 2, alc883_3ST_ch2_init },
+ { 4, alc883_3ST_ch4_init },
{ 6, alc883_3ST_ch6_init },
};
@@ -6235,6 +6658,31 @@ static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ /* .name = "Capture Source", */
+ .name = "Input Source",
+ .count = 2,
+ .info = alc883_mux_enum_info,
+ .get = alc883_mux_enum_get,
+ .put = alc883_mux_enum_put,
+ },
+ { } /* end */
+};
+
static struct snd_kcontrol_new alc883_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -6270,11 +6718,12 @@ static struct hda_verb alc883_init_verbs[] = {
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ /* mute analog input loopbacks */
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Front Pin: output 0 (0x0c) */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -6366,6 +6815,19 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
{ } /* end */
};
+static struct hda_verb alc883_haier_w66_verbs[] = {
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ { } /* end */
+};
+
static struct hda_verb alc888_6st_hp_verbs[] = {
{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
{0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
@@ -6409,15 +6871,10 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
-
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
/* toggle RCA according to the front-jack state */
@@ -6427,12 +6884,10 @@ static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
-
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
+
static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
unsigned int res)
{
@@ -6459,10 +6914,8 @@ static void alc883_medion_md2_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
@@ -6480,13 +6933,11 @@ static void alc883_tagra_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
- present ? 1 : 3);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
+ snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+ present ? 1 : 3);
}
static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -6495,6 +6946,25 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
alc883_tagra_automute(codec);
}
+static void alc883_haier_w66_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+ unsigned char bits;
+
+ present = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ bits = present ? 0x80 : 0;
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ 0x80, bits);
+}
+
+static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc883_haier_w66_automute(codec);
+}
+
static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
{
unsigned int present;
@@ -6502,11 +6972,9 @@ static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
@@ -6516,15 +6984,11 @@ static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
@@ -6536,6 +7000,44 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
alc883_lenovo_101e_ispeaker_automute(codec);
}
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_acer_aspire_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x14, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+}
+
+static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc883_acer_aspire_automute(codec);
+}
+
+static struct hda_verb alc883_acer_eapd_verbs[] = {
+ /* HP Pin: output 0 (0x0c) */
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* Front Pin: output 0 (0x0c) */
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
+ /* eanable EAPD on medion laptop */
+ {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
+ {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
+ /* enable unsolicited event */
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ { }
+};
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -6548,17 +7050,17 @@ static struct hda_verb alc883_auto_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
* Note: PASD motherboards uses the Line In 2 as the input for
* front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x0c - 0x0f)
@@ -6621,6 +7123,10 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = {
{ } /* end */
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+#define alc883_loopbacks alc880_loopbacks
+#endif
+
/* pcm configuration: identiacal with ALC880 */
#define alc883_pcm_analog_playback alc880_pcm_analog_playback
#define alc883_pcm_analog_capture alc880_pcm_analog_capture
@@ -6638,12 +7144,14 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
[ALC883_TARGA_DIG] = "targa-dig",
[ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
[ALC883_ACER] = "acer",
+ [ALC883_ACER_ASPIRE] = "acer-aspire",
[ALC883_MEDION] = "medion",
[ALC883_MEDION_MD2] = "medion-md2",
[ALC883_LAPTOP_EAPD] = "laptop-eapd",
[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
[ALC883_LENOVO_NB0763] = "lenovo-nb0763",
[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
+ [ALC883_HAIER_W66] = "haier-w66",
[ALC888_6ST_HP] = "6stack-hp",
[ALC888_3ST_HP] = "3stack-hp",
[ALC883_AUTO] = "auto",
@@ -6669,10 +7177,14 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
+ SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
+ SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
+ SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
+ SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
@@ -6685,6 +7197,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
+ SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
+ SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
+ SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
+ SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
{}
};
@@ -6771,8 +7287,7 @@ static struct alc_config_preset alc883_presets[] = {
.init_hook = alc883_tagra_automute,
},
[ALC883_ACER] = {
- .mixers = { alc883_base_mixer,
- alc883_chmode_mixer },
+ .mixers = { alc883_base_mixer },
/* On TravelMate laptops, GPIO 0 enables the internal speaker
* and the headphone jack. Turn this on and rely on the
* standard mute methods whenever the user wants to turn
@@ -6787,6 +7302,20 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
},
+ [ALC883_ACER_ASPIRE] = {
+ .mixers = { alc883_acer_aspire_mixer },
+ .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .dac_nids = alc883_dac_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+ .adc_nids = alc883_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+ .input_mux = &alc883_capture_source,
+ .unsol_event = alc883_acer_aspire_unsol_event,
+ .init_hook = alc883_acer_aspire_automute,
+ },
[ALC883_MEDION] = {
.mixers = { alc883_fivestack_mixer,
alc883_chmode_mixer },
@@ -6815,8 +7344,7 @@ static struct alc_config_preset alc883_presets[] = {
.init_hook = alc883_medion_md2_automute,
},
[ALC883_LAPTOP_EAPD] = {
- .mixers = { alc883_base_mixer,
- alc883_chmode_mixer },
+ .mixers = { alc883_base_mixer },
.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
.num_dacs = ARRAY_SIZE(alc883_dac_nids),
.dac_nids = alc883_dac_nids,
@@ -6867,6 +7395,20 @@ static struct alc_config_preset alc883_presets[] = {
.input_mux = &alc883_capture_source,
.unsol_event = alc883_lenovo_ms7195_unsol_event,
.init_hook = alc888_lenovo_ms7195_front_automute,
+ },
+ [ALC883_HAIER_W66] = {
+ .mixers = { alc883_tagra_2ch_mixer},
+ .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
+ .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+ .dac_nids = alc883_dac_nids,
+ .dig_out_nid = ALC883_DIGOUT_NID,
+ .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+ .adc_nids = alc883_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+ .channel_mode = alc883_3ST_2ch_modes,
+ .input_mux = &alc883_capture_source,
+ .unsol_event = alc883_haier_w66_unsol_event,
+ .init_hook = alc883_haier_w66_automute,
},
[ALC888_6ST_HP] = {
.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
@@ -6977,12 +7519,19 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
if (err < 0)
return err;
- else if (err > 0)
- /* hack - override the init verbs */
- spec->init_verbs[0] = alc883_auto_init_verbs;
+ else if (!err)
+ return 0; /* no config found */
+
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
+ /* hack - override the init verbs */
+ spec->init_verbs[0] = alc883_auto_init_verbs;
spec->mixers[spec->num_mixers] = alc883_capture_mixer;
spec->num_mixers++;
- return err;
+
+ return 1; /* config found */
}
/* additional initialization for auto-configuration model */
@@ -7046,6 +7595,10 @@ static int patch_alc883(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC883_AUTO)
spec->init_hook = alc883_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc883_loopbacks;
+#endif
return 0;
}
@@ -7156,9 +7709,46 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
{ } /* end */
};
+/* bind hp and internal speaker mute (with plug check) */
+static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ long *valp = ucontrol->value.integer.value;
+ int change;
+
+ /* change hp mute */
+ change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ valp[0] ? 0 : HDA_AMP_MUTE);
+ change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ valp[1] ? 0 : HDA_AMP_MUTE);
+ if (change) {
+ /* change speaker according to HP jack state */
+ struct alc_spec *spec = codec->spec;
+ unsigned int mute;
+ if (spec->jack_present)
+ mute = HDA_AMP_MUTE;
+ else
+ mute = snd_hda_codec_amp_read(codec, 0x15, 0,
+ HDA_OUTPUT, 0);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+ }
+ return change;
+}
+
static struct snd_kcontrol_new alc262_sony_mixer[] = {
- HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Master Playback Switch",
+ .info = snd_hda_mixer_amp_switch_info,
+ .get = snd_hda_mixer_amp_switch_get,
+ .put = alc262_sony_master_sw_put,
+ .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
+ },
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
@@ -7194,17 +7784,17 @@ static struct hda_verb alc262_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
* Note: PASD motherboards uses the Line In 2 as the input for
* front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x0c - 0x0e)
@@ -7285,34 +7875,26 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {
};
/* mute/unmute internal speaker according to the hp jack and mute state */
-static void alc262_hippo_automute(struct hda_codec *codec, int force)
+static void alc262_hippo_automute(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
unsigned int mute;
+ unsigned int present;
- if (force || !spec->sense_updated) {
- unsigned int present;
- /* need to execute and sync at first */
- snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
- present = snd_hda_codec_read(codec, 0x15, 0,
- AC_VERB_GET_PIN_SENSE, 0);
- spec->jack_present = (present & 0x80000000) != 0;
- spec->sense_updated = 1;
- }
+ /* need to execute and sync at first */
+ snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
+ present = snd_hda_codec_read(codec, 0x15, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+ spec->jack_present = (present & 0x80000000) != 0;
if (spec->jack_present) {
/* mute internal speaker */
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, 0x80);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
/* unmute internal speaker if necessary */
mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, mute & 0x80);
- mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, mute & 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
}
}
@@ -7322,37 +7904,27 @@ static void alc262_hippo_unsol_event(struct hda_codec *codec,
{
if ((res >> 26) != ALC880_HP_EVENT)
return;
- alc262_hippo_automute(codec, 1);
+ alc262_hippo_automute(codec);
}
-static void alc262_hippo1_automute(struct hda_codec *codec, int force)
+static void alc262_hippo1_automute(struct hda_codec *codec)
{
- struct alc_spec *spec = codec->spec;
unsigned int mute;
+ unsigned int present;
- if (force || !spec->sense_updated) {
- unsigned int present;
- /* need to execute and sync at first */
- snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
- present = snd_hda_codec_read(codec, 0x1b, 0,
- AC_VERB_GET_PIN_SENSE, 0);
- spec->jack_present = (present & 0x80000000) != 0;
- spec->sense_updated = 1;
- }
- if (spec->jack_present) {
+ snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
+ present = snd_hda_codec_read(codec, 0x1b, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+ present = (present & 0x80000000) != 0;
+ if (present) {
/* mute internal speaker */
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, 0x80);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
/* unmute internal speaker if necessary */
mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, mute & 0x80);
- mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, mute & 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
}
}
@@ -7362,7 +7934,7 @@ static void alc262_hippo1_unsol_event(struct hda_codec *codec,
{
if ((res >> 26) != ALC880_HP_EVENT)
return;
- alc262_hippo1_automute(codec, 1);
+ alc262_hippo1_automute(codec);
}
/*
@@ -7379,9 +7951,10 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
};
static struct hda_input_mux alc262_fujitsu_capture_source = {
- .num_items = 2,
+ .num_items = 3,
.items = {
{ "Mic", 0x0 },
+ { "Int Mic", 0x1 },
{ "CD", 0x4 },
},
};
@@ -7390,13 +7963,23 @@ static struct hda_input_mux alc262_HP_capture_source = {
.num_items = 5,
.items = {
{ "Mic", 0x0 },
- { "Front Mic", 0x3 },
+ { "Front Mic", 0x1 },
{ "Line", 0x2 },
{ "CD", 0x4 },
{ "AUX IN", 0x6 },
},
};
+static struct hda_input_mux alc262_HP_D7000_capture_source = {
+ .num_items = 4,
+ .items = {
+ { "Mic", 0x0 },
+ { "Front Mic", 0x2 },
+ { "Line", 0x1 },
+ { "CD", 0x4 },
+ },
+};
+
/* mute/unmute internal speaker according to the hp jack and mute state */
static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
{
@@ -7414,18 +7997,13 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
}
if (spec->jack_present) {
/* mute internal speaker */
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, 0x80);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
/* unmute internal speaker if necessary */
mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, mute & 0x80);
- mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, mute & 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
}
}
@@ -7439,23 +8017,14 @@ static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
}
/* bind volumes of both NID 0x0c and 0x0d */
-static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- return change;
-}
+static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
/* bind hp and internal speaker mute (with plug check) */
static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
@@ -7466,24 +8035,18 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
int change;
change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, valp[0] ? 0 : 0x80);
+ HDA_AMP_MUTE,
+ valp[0] ? 0 : HDA_AMP_MUTE);
change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, valp[1] ? 0 : 0x80);
- if (change || codec->in_resume)
- alc262_fujitsu_automute(codec, codec->in_resume);
+ HDA_AMP_MUTE,
+ valp[1] ? 0 : HDA_AMP_MUTE);
+ if (change)
+ alc262_fujitsu_automute(codec, 0);
return change;
}
static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = alc262_fujitsu_master_vol_put,
- .tlv = { .c = snd_hda_mixer_amp_tlv },
- .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
- },
+ HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
@@ -7497,6 +8060,9 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
{ } /* end */
};
@@ -7611,17 +8177,17 @@ static struct hda_verb alc262_volume_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
* Note: PASD motherboards uses the Line In 2 as the input for
* front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x0c - 0x0f)
@@ -7672,19 +8238,19 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
* Note: PASD motherboards uses the Line In 2 as the input for
* front panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
/*
* Set up output mixers (0x0c - 0x0e)
@@ -7759,20 +8325,20 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
* Note: PASD motherboards uses the Line In 2 as the input for front
* panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
/*
* Set up output mixers (0x0c - 0x0e)
*/
@@ -7842,6 +8408,10 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
{ }
};
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+#define alc262_loopbacks alc880_loopbacks
+#endif
+
/* pcm configuration: identiacal with ALC880 */
#define alc262_pcm_analog_playback alc880_pcm_analog_playback
#define alc262_pcm_analog_capture alc880_pcm_analog_capture
@@ -7884,6 +8454,10 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux;
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
return 1;
}
@@ -7939,6 +8513,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
+ SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
@@ -7967,6 +8542,7 @@ static struct alc_config_preset alc262_presets[] = {
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
.unsol_event = alc262_hippo_unsol_event,
+ .init_hook = alc262_hippo_automute,
},
[ALC262_HIPPO_1] = {
.mixers = { alc262_hippo1_mixer },
@@ -7979,10 +8555,12 @@ static struct alc_config_preset alc262_presets[] = {
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
.unsol_event = alc262_hippo1_unsol_event,
+ .init_hook = alc262_hippo1_automute,
},
[ALC262_FUJITSU] = {
.mixers = { alc262_fujitsu_mixer },
- .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
+ .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
+ alc262_fujitsu_unsol_verbs },
.num_dacs = ARRAY_SIZE(alc262_dac_nids),
.dac_nids = alc262_dac_nids,
.hp_nid = 0x03,
@@ -8010,7 +8588,7 @@ static struct alc_config_preset alc262_presets[] = {
.hp_nid = 0x03,
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
- .input_mux = &alc262_HP_capture_source,
+ .input_mux = &alc262_HP_D7000_capture_source,
},
[ALC262_HP_BPC_D7000_WL] = {
.mixers = { alc262_HP_BPC_WildWest_mixer,
@@ -8021,7 +8599,7 @@ static struct alc_config_preset alc262_presets[] = {
.hp_nid = 0x03,
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
- .input_mux = &alc262_HP_capture_source,
+ .input_mux = &alc262_HP_D7000_capture_source,
},
[ALC262_BENQ_ED8] = {
.mixers = { alc262_base_mixer },
@@ -8043,6 +8621,7 @@ static struct alc_config_preset alc262_presets[] = {
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
.unsol_event = alc262_hippo_unsol_event,
+ .init_hook = alc262_hippo_automute,
},
[ALC262_BENQ_T31] = {
.mixers = { alc262_benq_t31_mixer },
@@ -8054,6 +8633,7 @@ static struct alc_config_preset alc262_presets[] = {
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
.unsol_event = alc262_hippo_unsol_event,
+ .init_hook = alc262_hippo_automute,
},
};
@@ -8139,6 +8719,10 @@ static int patch_alc262(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC262_AUTO)
spec->init_hook = alc262_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc262_loopbacks;
+#endif
return 0;
}
@@ -8170,9 +8754,125 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
+ { }
+};
+
+static struct hda_verb alc268_eapd_verbs[] = {
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
+ { }
+};
+
+/* Toshiba specific */
+#define alc268_toshiba_automute alc262_hippo_automute
+
+static struct hda_verb alc268_toshiba_verbs[] = {
+ {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ { } /* end */
+};
+
+/* Acer specific */
+/* bind volumes of both NID 0x02 and 0x03 */
+static struct hda_bind_ctls alc268_acer_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
+
+/* mute/unmute internal speaker according to the hp jack and mute state */
+static void alc268_acer_automute(struct hda_codec *codec, int force)
+{
+ struct alc_spec *spec = codec->spec;
+ unsigned int mute;
+
+ if (force || !spec->sense_updated) {
+ unsigned int present;
+ present = snd_hda_codec_read(codec, 0x14, 0,
+ AC_VERB_GET_PIN_SENSE, 0);
+ spec->jack_present = (present & 0x80000000) != 0;
+ spec->sense_updated = 1;
+ }
+ if (spec->jack_present)
+ mute = HDA_AMP_MUTE; /* mute internal speaker */
+ else /* unmute internal speaker if necessary */
+ mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, mute);
+}
+
+
+/* bind hp and internal speaker mute (with plug check) */
+static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ long *valp = ucontrol->value.integer.value;
+ int change;
+
+ change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ valp[0] ? 0 : HDA_AMP_MUTE);
+ change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE,
+ valp[1] ? 0 : HDA_AMP_MUTE);
+ if (change)
+ alc268_acer_automute(codec, 0);
+ return change;
+}
+
+static struct snd_kcontrol_new alc268_acer_mixer[] = {
+ /* output mixer control */
+ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Master Playback Switch",
+ .info = snd_hda_mixer_amp_switch_info,
+ .get = snd_hda_mixer_amp_switch_get,
+ .put = alc268_acer_master_sw_put,
+ .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+ },
+ HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
{ }
};
+static struct hda_verb alc268_acer_verbs[] = {
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+
+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+ { }
+};
+
+/* unsolicited event for HP jack sensing */
+static void alc268_toshiba_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) != ALC880_HP_EVENT)
+ return;
+ alc268_toshiba_automute(codec);
+}
+
+static void alc268_acer_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) != ALC880_HP_EVENT)
+ return;
+ alc268_acer_automute(codec, 1);
+}
+
+static void alc268_acer_init_hook(struct hda_codec *codec)
+{
+ alc268_acer_automute(codec, 1);
+}
+
/*
* generic initialization of ADC, input mixers and output mixers
*/
@@ -8282,14 +8982,16 @@ static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && !codec->in_resume)
+ if (*cur_val == idx)
return 0;
for (i = 0; i < imux->num_items; i++) {
- unsigned int v = (i == idx) ? 0x7000 : 0x7080;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- v | (imux->items[i].index << 8));
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
- idx );
+ unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
+ imux->items[i].index,
+ HDA_AMP_MUTE, v);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_CONNECT_SEL,
+ idx );
}
*cur_val = idx;
return 1;
@@ -8530,6 +9232,10 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux;
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
return 1;
}
@@ -8551,11 +9257,19 @@ static void alc268_auto_init(struct hda_codec *codec)
*/
static const char *alc268_models[ALC268_MODEL_LAST] = {
[ALC268_3ST] = "3stack",
+ [ALC268_TOSHIBA] = "toshiba",
+ [ALC268_ACER] = "acer",
[ALC268_AUTO] = "auto",
};
static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
+ SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
+ SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
+ SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
+ SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
+ SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
+ SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
{}
};
@@ -8573,6 +9287,37 @@ static struct alc_config_preset alc268_presets[] = {
.channel_mode = alc268_modes,
.input_mux = &alc268_capture_source,
},
+ [ALC268_TOSHIBA] = {
+ .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
+ .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+ alc268_toshiba_verbs },
+ .num_dacs = ARRAY_SIZE(alc268_dac_nids),
+ .dac_nids = alc268_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
+ .adc_nids = alc268_adc_nids_alt,
+ .hp_nid = 0x03,
+ .num_channel_mode = ARRAY_SIZE(alc268_modes),
+ .channel_mode = alc268_modes,
+ .input_mux = &alc268_capture_source,
+ .input_mux = &alc268_capture_source,
+ .unsol_event = alc268_toshiba_unsol_event,
+ .init_hook = alc268_toshiba_automute,
+ },
+ [ALC268_ACER] = {
+ .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
+ .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
+ alc268_acer_verbs },
+ .num_dacs = ARRAY_SIZE(alc268_dac_nids),
+ .dac_nids = alc268_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
+ .adc_nids = alc268_adc_nids_alt,
+ .hp_nid = 0x02,
+ .num_channel_mode = ARRAY_SIZE(alc268_modes),
+ .channel_mode = alc268_modes,
+ .input_mux = &alc268_capture_source,
+ .unsol_event = alc268_acer_unsol_event,
+ .init_hook = alc268_acer_init_hook,
+ },
};
static int patch_alc268(struct hda_codec *codec)
@@ -9279,14 +10024,10 @@ static void alc861_toshiba_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x0f, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
- 0x80, present ? 0 : 0x80);
- snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
- 0x80, present ? 0 : 0x80);
+ snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+ snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
+ HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
}
static void alc861_toshiba_unsol_event(struct hda_codec *codec,
@@ -9599,6 +10340,16 @@ static void alc861_auto_init(struct hda_codec *codec)
alc861_auto_init_analog_input(codec);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list alc861_loopbacks[] = {
+ { 0x15, HDA_INPUT, 0 },
+ { 0x15, HDA_INPUT, 1 },
+ { 0x15, HDA_INPUT, 2 },
+ { 0x15, HDA_INPUT, 3 },
+ { } /* end */
+};
+#endif
+
/*
* configuration and preset
@@ -9796,6 +10547,10 @@ static int patch_alc861(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC861_AUTO)
spec->init_hook = alc861_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc861_loopbacks;
+#endif
return 0;
}
@@ -9852,6 +10607,14 @@ static struct hda_input_mux alc861vd_dallas_capture_source = {
},
};
+static struct hda_input_mux alc861vd_hp_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "Front Mic", 0x0 },
+ { "ATAPI Mic", 0x1 },
+ },
+};
+
#define alc861vd_mux_enum_info alc_mux_enum_info
#define alc861vd_mux_enum_get alc_mux_enum_get
@@ -9870,12 +10633,13 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && !codec->in_resume)
+ if (*cur_val == idx)
return 0;
for (i = 0; i < imux->num_items; i++) {
- unsigned int v = (i == idx) ? 0x7000 : 0x7080;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- v | (imux->items[i].index << 8));
+ unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
+ imux->items[i].index,
+ HDA_AMP_MUTE, v);
}
*cur_val = idx;
return 1;
@@ -10049,17 +10813,22 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
- HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- /* .name = "Capture Source", */
- .name = "Input Source",
- .count = 1,
- .info = alc882_mux_enum_info,
- .get = alc882_mux_enum_get,
- .put = alc882_mux_enum_put,
- },
+ { } /* end */
+};
+
+/* Pin assignment: Speaker=0x14, Line-out = 0x15,
+ * Front Mic=0x18, ATAPI Mic = 0x19,
+ */
+static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
+ HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+ HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+ HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+
{ } /* end */
};
@@ -10077,11 +10846,11 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
* the analog-loopback mixer widget
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -10210,11 +10979,9 @@ static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
@@ -10224,11 +10991,9 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x18, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
+ HDA_AMP_MUTE, bits);
}
static void alc861vd_lenovo_automute(struct hda_codec *codec)
@@ -10302,10 +11067,8 @@ static void alc861vd_dallas_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, present ? 0x80 : 0);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -10314,6 +11077,10 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
alc861vd_dallas_automute(codec);
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+#define alc861vd_loopbacks alc880_loopbacks
+#endif
+
/* pcm configuration: identiacal with ALC880 */
#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
@@ -10325,12 +11092,13 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
*/
static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
[ALC660VD_3ST] = "3stack-660",
- [ALC660VD_3ST_DIG]= "3stack-660-digout",
+ [ALC660VD_3ST_DIG] = "3stack-660-digout",
[ALC861VD_3ST] = "3stack",
[ALC861VD_3ST_DIG] = "3stack-digout",
[ALC861VD_6ST_DIG] = "6stack-digout",
[ALC861VD_LENOVO] = "lenovo",
[ALC861VD_DALLAS] = "dallas",
+ [ALC861VD_HP] = "hp",
[ALC861VD_AUTO] = "auto",
};
@@ -10341,11 +11109,15 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
- SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
+ /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
+ SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
+ SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
+ SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
+ SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
{}
};
@@ -10435,7 +11207,21 @@ static struct alc_config_preset alc861vd_presets[] = {
.input_mux = &alc861vd_dallas_capture_source,
.unsol_event = alc861vd_dallas_unsol_event,
.init_hook = alc861vd_dallas_automute,
- },
+ },
+ [ALC861VD_HP] = {
+ .mixers = { alc861vd_hp_mixer },
+ .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
+ .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
+ .dac_nids = alc861vd_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+ .dig_out_nid = ALC861VD_DIGOUT_NID,
+ .adc_nids = alc861vd_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
+ .channel_mode = alc861vd_3stack_2ch_modes,
+ .input_mux = &alc861vd_hp_capture_source,
+ .unsol_event = alc861vd_dallas_unsol_event,
+ .init_hook = alc861vd_dallas_automute,
+ },
};
/*
@@ -10668,6 +11454,10 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux;
+ err = alc_auto_add_mic_boost(codec);
+ if (err < 0)
+ return err;
+
return 1;
}
@@ -10735,6 +11525,10 @@ static int patch_alc861vd(struct hda_codec *codec)
if (board_config == ALC861VD_AUTO)
spec->init_hook = alc861vd_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc861vd_loopbacks;
+#endif
return 0;
}
@@ -10782,6 +11576,15 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = {
{ "Line", 0x2 },
},
};
+
+static struct hda_input_mux alc662_eeepc_capture_source = {
+ .num_items = 2,
+ .items = {
+ { "i-Mic", 0x1 },
+ { "e-Mic", 0x0 },
+ },
+};
+
#define alc662_mux_enum_info alc_mux_enum_info
#define alc662_mux_enum_get alc_mux_enum_get
@@ -10792,7 +11595,7 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
struct alc_spec *spec = codec->spec;
const struct hda_input_mux *imux = spec->input_mux;
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
- static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
+ static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
hda_nid_t nid = capture_mixers[adc_idx];
unsigned int *cur_val = &spec->cur_mux[adc_idx];
unsigned int i, idx;
@@ -10800,12 +11603,13 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
idx = ucontrol->value.enumerated.item[0];
if (idx >= imux->num_items)
idx = imux->num_items - 1;
- if (*cur_val == idx && !codec->in_resume)
+ if (*cur_val == idx)
return 0;
for (i = 0; i < imux->num_items; i++) {
- unsigned int v = (i == idx) ? 0x7000 : 0x7080;
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
- v | (imux->items[i].index << 8));
+ unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
+ snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
+ imux->items[i].index,
+ HDA_AMP_MUTE, v);
}
*cur_val = idx;
return 1;
@@ -10997,6 +11801,22 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
+ HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+
+ HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
+ HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+ HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+ { } /* end */
+};
+
static struct snd_kcontrol_new alc662_chmode_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -11014,18 +11834,18 @@ static struct hda_verb alc662_init_verbs[] = {
{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
/* Front mixer: unmute input/output amp left and right (volume = 0) */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* Front Pin: output 0 (0x0c) */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
@@ -11062,13 +11882,24 @@ static struct hda_verb alc662_init_verbs[] = {
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
{ }
};
static struct hda_verb alc662_sue_init_verbs[] = {
{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
- {}
+ {}
+};
+
+static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {}
};
/*
@@ -11087,11 +11918,11 @@ static struct hda_verb alc662_auto_init_verbs[] = {
* panel mic (mic 2)
*/
/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x0c - 0x0f)
@@ -11103,23 +11934,19 @@ static struct hda_verb alc662_auto_init_verbs[] = {
/* set up input amps for analog loopback */
/* Amp Indices: DAC = 0, mixer = 1 */
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* FIXME: use matrix-type input source selection */
/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
/* Input mixer */
{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
- {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
-
+ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
{ }
};
@@ -11150,11 +11977,9 @@ static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
@@ -11164,15 +11989,11 @@ static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
- bits = present ? 0x80 : 0;
- snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
- 0x80, bits);
- snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
- 0x80, bits);
+ bits = present ? HDA_AMP_MUTE : 0;
+ snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
+ snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
+ HDA_AMP_MUTE, bits);
}
static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
@@ -11184,6 +12005,43 @@ static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
alc662_lenovo_101e_ispeaker_automute(codec);
}
+static void alc662_eeepc_mic_automute(struct hda_codec *codec)
+{
+ unsigned int present;
+
+ present = snd_hda_codec_read(codec, 0x18, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
+ snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
+ snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
+ snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc662_eeepc_unsol_event(struct hda_codec *codec,
+ unsigned int res)
+{
+ if ((res >> 26) == ALC880_HP_EVENT)
+ alc262_hippo1_automute( codec );
+
+ if ((res >> 26) == ALC880_MIC_EVENT)
+ alc662_eeepc_mic_automute(codec);
+}
+
+static void alc662_eeepc_inithook(struct hda_codec *codec)
+{
+ alc262_hippo1_automute( codec );
+ alc662_eeepc_mic_automute(codec);
+}
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+#define alc662_loopbacks alc880_loopbacks
+#endif
+
/* pcm configuration: identiacal with ALC880 */
#define alc662_pcm_analog_playback alc880_pcm_analog_playback
@@ -11205,12 +12063,13 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
+ SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
{}
};
static struct alc_config_preset alc662_presets[] = {
[ALC662_3ST_2ch_DIG] = {
- .mixers = { alc662_3ST_2ch_mixer },
+ .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
.init_verbs = { alc662_init_verbs },
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
.dac_nids = alc662_dac_nids,
@@ -11223,7 +12082,8 @@ static struct alc_config_preset alc662_presets[] = {
.input_mux = &alc662_capture_source,
},
[ALC662_3ST_6ch_DIG] = {
- .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+ .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
+ alc662_capture_mixer },
.init_verbs = { alc662_init_verbs },
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
.dac_nids = alc662_dac_nids,
@@ -11237,7 +12097,8 @@ static struct alc_config_preset alc662_presets[] = {
.input_mux = &alc662_capture_source,
},
[ALC662_3ST_6ch] = {
- .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+ .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
+ alc662_capture_mixer },
.init_verbs = { alc662_init_verbs },
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
.dac_nids = alc662_dac_nids,
@@ -11249,7 +12110,8 @@ static struct alc_config_preset alc662_presets[] = {
.input_mux = &alc662_capture_source,
},
[ALC662_5ST_DIG] = {
- .mixers = { alc662_base_mixer, alc662_chmode_mixer },
+ .mixers = { alc662_base_mixer, alc662_chmode_mixer,
+ alc662_capture_mixer },
.init_verbs = { alc662_init_verbs },
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
.dac_nids = alc662_dac_nids,
@@ -11262,7 +12124,7 @@ static struct alc_config_preset alc662_presets[] = {
.input_mux = &alc662_capture_source,
},
[ALC662_LENOVO_101E] = {
- .mixers = { alc662_lenovo_101e_mixer },
+ .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
.num_dacs = ARRAY_SIZE(alc662_dac_nids),
.dac_nids = alc662_dac_nids,
@@ -11274,6 +12136,20 @@ static struct alc_config_preset alc662_presets[] = {
.unsol_event = alc662_lenovo_101e_unsol_event,
.init_hook = alc662_lenovo_101e_all_automute,
},
+ [ALC662_ASUS_EEEPC_P701] = {
+ .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
+ .init_verbs = { alc662_init_verbs,
+ alc662_eeepc_sue_init_verbs },
+ .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+ .dac_nids = alc662_dac_nids,
+ .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+ .adc_nids = alc662_adc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+ .channel_mode = alc662_3ST_2ch_modes,
+ .input_mux = &alc662_eeepc_capture_source,
+ .unsol_event = alc662_eeepc_unsol_event,
+ .init_hook = alc662_eeepc_inithook,
+ },
};
@@ -11296,7 +12172,7 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
for (i = 0; i < cfg->line_outs; i++) {
if (!spec->multiout.dac_nids[i])
continue;
- nid = alc880_idx_to_mixer(i);
+ nid = alc880_idx_to_dac(i);
if (i == 2) {
/* Center/LFE */
err = add_control(spec, ALC_CTL_WIDGET_VOL,
@@ -11586,6 +12462,10 @@ static int patch_alc662(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC662_AUTO)
spec->init_hook = alc662_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ if (!spec->loopback.amplist)
+ spec->loopback.amplist = alc662_loopbacks;
+#endif
return 0;
}
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 6d2ecc38905..2a4b9609aa5 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -78,6 +78,8 @@
/* si3054 codec registers (nodes) access macros */
#define GET_REG(codec,reg) (snd_hda_codec_read(codec,reg,0,SI3054_VERB_READ_NODE,0))
#define SET_REG(codec,reg,val) (snd_hda_codec_write(codec,reg,0,SI3054_VERB_WRITE_NODE,val))
+#define SET_REG_CACHE(codec,reg,val) \
+ snd_hda_codec_write_cache(codec,reg,0,SI3054_VERB_WRITE_NODE,val)
struct si3054_spec {
@@ -94,15 +96,7 @@ struct si3054_spec {
#define PRIVATE_REG(val) ((val>>16)&0xffff)
#define PRIVATE_MASK(val) (val&0xffff)
-static int si3054_switch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define si3054_switch_info snd_ctl_boolean_mono_info
static int si3054_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *uvalue)
@@ -121,9 +115,9 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol,
u16 reg = PRIVATE_REG(kcontrol->private_value);
u16 mask = PRIVATE_MASK(kcontrol->private_value);
if (uvalue->value.integer.value[0])
- SET_REG(codec, reg, (GET_REG(codec, reg)) | mask);
+ SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) | mask);
else
- SET_REG(codec, reg, (GET_REG(codec, reg)) & ~mask);
+ SET_REG_CACHE(codec, reg, (GET_REG(codec, reg)) & ~mask);
return 0;
}
@@ -275,10 +269,6 @@ static struct hda_codec_ops si3054_patch_ops = {
.build_pcms = si3054_build_pcms,
.init = si3054_init,
.free = si3054_free,
-#ifdef CONFIG_PM
- //.suspend = si3054_suspend,
- .resume = si3054_init,
-#endif
};
static int patch_si3054(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 3f25de72966..bf950195107 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -39,12 +39,25 @@
enum {
STAC_REF,
+ STAC_9200_DELL_D21,
+ STAC_9200_DELL_D22,
+ STAC_9200_DELL_D23,
+ STAC_9200_DELL_M21,
+ STAC_9200_DELL_M22,
+ STAC_9200_DELL_M23,
+ STAC_9200_DELL_M24,
+ STAC_9200_DELL_M25,
+ STAC_9200_DELL_M26,
+ STAC_9200_DELL_M27,
+ STAC_9200_GATEWAY,
STAC_9200_MODELS
};
enum {
STAC_9205_REF,
- STAC_M43xx,
+ STAC_9205_DELL_M42,
+ STAC_9205_DELL_M43,
+ STAC_9205_DELL_M44,
STAC_9205_MODELS
};
@@ -60,19 +73,22 @@ enum {
STAC_D945_REF,
STAC_D945GTP3,
STAC_D945GTP5,
- STAC_922X_DELL,
STAC_INTEL_MAC_V1,
STAC_INTEL_MAC_V2,
STAC_INTEL_MAC_V3,
STAC_INTEL_MAC_V4,
STAC_INTEL_MAC_V5,
- /* for backward compitability */
+ /* for backward compatibility */
STAC_MACMINI,
STAC_MACBOOK,
STAC_MACBOOK_PRO_V1,
STAC_MACBOOK_PRO_V2,
STAC_IMAC_INTEL,
STAC_IMAC_INTEL_20,
+ STAC_922X_DELL_D81,
+ STAC_922X_DELL_D82,
+ STAC_922X_DELL_M81,
+ STAC_922X_DELL_M82,
STAC_922X_MODELS
};
@@ -80,6 +96,7 @@ enum {
STAC_D965_REF,
STAC_D965_3ST,
STAC_D965_5ST,
+ STAC_DELL_3ST,
STAC_927X_MODELS
};
@@ -95,6 +112,8 @@ struct sigmatel_spec {
unsigned int hp_detect: 1;
unsigned int gpio_mute: 1;
+ unsigned int gpio_mask, gpio_data;
+
/* playback */
struct hda_multi_out multiout;
hda_nid_t dac_nids[5];
@@ -127,6 +146,8 @@ struct sigmatel_spec {
/* i/o switches */
unsigned int io_switch[2];
+ unsigned int clfe_swap;
+ unsigned int aloopback;
struct hda_pcm pcm_rec[2]; /* PCM information */
@@ -162,8 +183,9 @@ static hda_nid_t stac925x_dac_nids[1] = {
0x02,
};
-static hda_nid_t stac925x_dmic_nids[1] = {
- 0x15,
+#define STAC925X_NUM_DMICS 1
+static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
+ 0x15, 0
};
static hda_nid_t stac922x_adc_nids[2] = {
@@ -190,8 +212,9 @@ static hda_nid_t stac9205_mux_nids[2] = {
0x19, 0x1a
};
-static hda_nid_t stac9205_dmic_nids[2] = {
- 0x17, 0x18,
+#define STAC9205_NUM_DMICS 2
+static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
+ 0x17, 0x18, 0
};
static hda_nid_t stac9200_pin_nids[8] = {
@@ -276,12 +299,97 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
}
+#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
+
+static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+
+ ucontrol->value.integer.value[0] = spec->aloopback;
+ return 0;
+}
+
+static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+ unsigned int dac_mode;
+
+ if (spec->aloopback == ucontrol->value.integer.value[0])
+ return 0;
+
+ spec->aloopback = ucontrol->value.integer.value[0];
+
+
+ dac_mode = snd_hda_codec_read(codec, codec->afg, 0,
+ kcontrol->private_value & 0xFFFF, 0x0);
+
+ if (spec->aloopback) {
+ snd_hda_power_up(codec);
+ dac_mode |= 0x40;
+ } else {
+ snd_hda_power_down(codec);
+ dac_mode &= ~0x40;
+ }
+
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ kcontrol->private_value >> 16, dac_mode);
+
+ return 1;
+}
+
+static int stac92xx_volknob_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 127;
+ return 0;
+}
+
+static int stac92xx_volknob_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = kcontrol->private_value & 0xff;
+ return 0;
+}
+
+static int stac92xx_volknob_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ unsigned int val = kcontrol->private_value & 0xff;
+
+ if (val == ucontrol->value.integer.value[0])
+ return 0;
+
+ val = ucontrol->value.integer.value[0];
+ kcontrol->private_value &= ~0xff;
+ kcontrol->private_value |= val;
+
+ snd_hda_codec_write_cache(codec, kcontrol->private_value >> 16, 0,
+ AC_VERB_SET_VOLUME_KNOB_CONTROL, val | 0x80);
+ return 1;
+}
+
+
static struct hda_verb stac9200_core_init[] = {
/* set dac0mux for dac converter */
{ 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
{}
};
+static struct hda_verb stac9200_eapd_init[] = {
+ /* set dac0mux for dac converter */
+ {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+ {}
+};
+
static struct hda_verb stac925x_core_init[] = {
/* set dac0mux for dac converter */
{ 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -316,17 +424,43 @@ static struct hda_verb stac9205_core_init[] = {
{}
};
+#define STAC_INPUT_SOURCE(cnt) \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Input Source", \
+ .count = cnt, \
+ .info = stac92xx_mux_enum_info, \
+ .get = stac92xx_mux_enum_get, \
+ .put = stac92xx_mux_enum_put, \
+ }
+
+#define STAC_ANALOG_LOOPBACK(verb_read,verb_write) \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Analog Loopback", \
+ .count = 1, \
+ .info = stac92xx_aloopback_info, \
+ .get = stac92xx_aloopback_get, \
+ .put = stac92xx_aloopback_put, \
+ .private_value = verb_read | (verb_write << 16), \
+ }
+
+#define STAC_VOLKNOB(knob_nid) \
+ { \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = "Master Playback Volume", \
+ .count = 1, \
+ .info = stac92xx_volknob_info, \
+ .get = stac92xx_volknob_get, \
+ .put = stac92xx_volknob_put, \
+ .private_value = 127 | (knob_nid << 16), \
+ }
+
+
static struct snd_kcontrol_new stac9200_mixer[] = {
HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
+ STAC_INPUT_SOURCE(1),
HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
@@ -334,86 +468,68 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
};
static struct snd_kcontrol_new stac925x_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
+ STAC_INPUT_SOURCE(1),
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
{ } /* end */
};
-/* This needs to be generated dynamically based on sequence */
-static struct snd_kcontrol_new stac922x_mixer[] = {
+static struct snd_kcontrol_new stac9205_mixer[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
+ .name = "Digital Input Source",
.count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
+ .info = stac92xx_dmux_enum_info,
+ .get = stac92xx_dmux_enum_get,
+ .put = stac92xx_dmux_enum_put,
},
- HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
- HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
+ STAC_INPUT_SOURCE(2),
+ STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0),
+ STAC_VOLKNOB(0x24),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT),
+
{ } /* end */
};
/* This needs to be generated dynamically based on sequence */
-static struct snd_kcontrol_new stac9227_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
- HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_MUTE("Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
+static struct snd_kcontrol_new stac922x_mixer[] = {
+ STAC_INPUT_SOURCE(2),
+ STAC_VOLKNOB(0x16),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT),
{ } /* end */
};
+
static struct snd_kcontrol_new stac927x_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
- HDA_CODEC_VOLUME("InMux Capture Volume", 0x15, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("InVol Capture Volume", 0x18, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1b, 0x0, HDA_OUTPUT),
- { } /* end */
-};
+ STAC_INPUT_SOURCE(3),
+ STAC_VOLKNOB(0x24),
+ STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB),
-static struct snd_kcontrol_new stac9205_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Input Source",
- .count = 1,
- .info = stac92xx_dmux_enum_info,
- .get = stac92xx_dmux_enum_get,
- .put = stac92xx_dmux_enum_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Input Source",
- .count = 1,
- .info = stac92xx_mux_enum_info,
- .get = stac92xx_mux_enum_get,
- .put = stac92xx_mux_enum_put,
- },
- HDA_CODEC_VOLUME("InMux Capture Volume", 0x19, 0x0, HDA_OUTPUT),
- HDA_CODEC_VOLUME("InVol Capture Volume", 0x1b, 0x0, HDA_INPUT),
- HDA_CODEC_MUTE("ADCMux Capture Switch", 0x1d, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT),
+
+ HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
+ HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
+ HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT),
{ } /* end */
};
@@ -451,12 +567,145 @@ static unsigned int ref9200_pin_configs[8] = {
0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
};
+/*
+ STAC 9200 pin configs for
+ 102801A8
+ 102801DE
+ 102801E8
+*/
+static unsigned int dell9200_d21_pin_configs[8] = {
+ 0x400001f0, 0x400001f1, 0x02214030, 0x01014010,
+ 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
+};
+
+/*
+ STAC 9200 pin configs for
+ 102801C0
+ 102801C1
+*/
+static unsigned int dell9200_d22_pin_configs[8] = {
+ 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
+ 0x01813020, 0x02a19021, 0x90100140, 0x400001f2,
+};
+
+/*
+ STAC 9200 pin configs for
+ 102801C4 (Dell Dimension E310)
+ 102801C5
+ 102801C7
+ 102801D9
+ 102801DA
+ 102801E3
+*/
+static unsigned int dell9200_d23_pin_configs[8] = {
+ 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010,
+ 0x01813020, 0x01a19021, 0x90100140, 0x400001f2,
+};
+
+
+/*
+ STAC 9200-32 pin configs for
+ 102801B5 (Dell Inspiron 630m)
+ 102801D8 (Dell Inspiron 640m)
+*/
+static unsigned int dell9200_m21_pin_configs[8] = {
+ 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310,
+ 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd,
+};
+
+/*
+ STAC 9200-32 pin configs for
+ 102801C2 (Dell Latitude D620)
+ 102801C8
+ 102801CC (Dell Latitude D820)
+ 102801D4
+ 102801D6
+*/
+static unsigned int dell9200_m22_pin_configs[8] = {
+ 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310,
+ 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc,
+};
+
+/*
+ STAC 9200-32 pin configs for
+ 102801CE (Dell XPS M1710)
+ 102801CF (Dell Precision M90)
+*/
+static unsigned int dell9200_m23_pin_configs[8] = {
+ 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310,
+ 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc,
+};
+
+/*
+ STAC 9200-32 pin configs for
+ 102801C9
+ 102801CA
+ 102801CB (Dell Latitude 120L)
+ 102801D3
+*/
+static unsigned int dell9200_m24_pin_configs[8] = {
+ 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310,
+ 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe,
+};
+
+/*
+ STAC 9200-32 pin configs for
+ 102801BD (Dell Inspiron E1505n)
+ 102801EE
+ 102801EF
+*/
+static unsigned int dell9200_m25_pin_configs[8] = {
+ 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
+ 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd,
+};
+
+/*
+ STAC 9200-32 pin configs for
+ 102801F5 (Dell Inspiron 1501)
+ 102801F6
+*/
+static unsigned int dell9200_m26_pin_configs[8] = {
+ 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310,
+ 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe,
+};
+
+/*
+ STAC 9200-32
+ 102801CD (Dell Inspiron E1705/9400)
+*/
+static unsigned int dell9200_m27_pin_configs[8] = {
+ 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310,
+ 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc,
+};
+
+
static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
[STAC_REF] = ref9200_pin_configs,
+ [STAC_9200_DELL_D21] = dell9200_d21_pin_configs,
+ [STAC_9200_DELL_D22] = dell9200_d22_pin_configs,
+ [STAC_9200_DELL_D23] = dell9200_d23_pin_configs,
+ [STAC_9200_DELL_M21] = dell9200_m21_pin_configs,
+ [STAC_9200_DELL_M22] = dell9200_m22_pin_configs,
+ [STAC_9200_DELL_M23] = dell9200_m23_pin_configs,
+ [STAC_9200_DELL_M24] = dell9200_m24_pin_configs,
+ [STAC_9200_DELL_M25] = dell9200_m25_pin_configs,
+ [STAC_9200_DELL_M26] = dell9200_m26_pin_configs,
+ [STAC_9200_DELL_M27] = dell9200_m27_pin_configs,
};
static const char *stac9200_models[STAC_9200_MODELS] = {
[STAC_REF] = "ref",
+ [STAC_9200_DELL_D21] = "dell-d21",
+ [STAC_9200_DELL_D22] = "dell-d22",
+ [STAC_9200_DELL_D23] = "dell-d23",
+ [STAC_9200_DELL_M21] = "dell-m21",
+ [STAC_9200_DELL_M22] = "dell-m22",
+ [STAC_9200_DELL_M23] = "dell-m23",
+ [STAC_9200_DELL_M24] = "dell-m24",
+ [STAC_9200_DELL_M25] = "dell-m25",
+ [STAC_9200_DELL_M26] = "dell-m26",
+ [STAC_9200_DELL_M27] = "dell-m27",
+ [STAC_9200_GATEWAY] = "gateway",
};
static struct snd_pci_quirk stac9200_cfg_tbl[] = {
@@ -464,30 +713,72 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_REF),
/* Dell laptops have BIOS problem */
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8,
+ "unknown Dell", STAC_9200_DELL_D21),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
- "Dell Inspiron 630m", STAC_REF),
+ "Dell Inspiron 630m", STAC_9200_DELL_M21),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd,
+ "Dell Inspiron E1505n", STAC_9200_DELL_M25),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0,
+ "unknown Dell", STAC_9200_DELL_D22),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1,
+ "unknown Dell", STAC_9200_DELL_D22),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
- "Dell Latitude D620", STAC_REF),
+ "Dell Latitude D620", STAC_9200_DELL_M22),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5,
+ "unknown Dell", STAC_9200_DELL_D23),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7,
+ "unknown Dell", STAC_9200_DELL_D23),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8,
+ "unknown Dell", STAC_9200_DELL_M22),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9,
+ "unknown Dell", STAC_9200_DELL_M24),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca,
+ "unknown Dell", STAC_9200_DELL_M24),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
- "Dell Latitude 120L", STAC_REF),
+ "Dell Latitude 120L", STAC_9200_DELL_M24),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
- "Dell Latitude D820", STAC_REF),
+ "Dell Latitude D820", STAC_9200_DELL_M22),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd,
- "Dell Inspiron E1705/9400", STAC_REF),
+ "Dell Inspiron E1705/9400", STAC_9200_DELL_M27),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce,
- "Dell XPS M1710", STAC_REF),
+ "Dell XPS M1710", STAC_9200_DELL_M23),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
- "Dell Precision M90", STAC_REF),
+ "Dell Precision M90", STAC_9200_DELL_M23),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3,
+ "unknown Dell", STAC_9200_DELL_M22),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4,
+ "unknown Dell", STAC_9200_DELL_M22),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
- "unknown Dell", STAC_REF),
+ "unknown Dell", STAC_9200_DELL_M22),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8,
- "Dell Inspiron 640m", STAC_REF),
+ "Dell Inspiron 640m", STAC_9200_DELL_M21),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9,
+ "unknown Dell", STAC_9200_DELL_D23),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da,
+ "unknown Dell", STAC_9200_DELL_D23),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de,
+ "unknown Dell", STAC_9200_DELL_D21),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3,
+ "unknown Dell", STAC_9200_DELL_D23),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8,
+ "unknown Dell", STAC_9200_DELL_D21),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee,
+ "unknown Dell", STAC_9200_DELL_M25),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef,
+ "unknown Dell", STAC_9200_DELL_M25),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5,
- "Dell Inspiron 1501", STAC_REF),
-
+ "Dell Inspiron 1501", STAC_9200_DELL_M26),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
+ "unknown Dell", STAC_9200_DELL_M26),
/* Panasonic */
SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF),
-
+ /* Gateway machines needs EAPD to be set on resume */
+ SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY),
+ SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*",
+ STAC_9200_GATEWAY),
+ SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707",
+ STAC_9200_GATEWAY),
{} /* terminator */
};
@@ -543,6 +834,51 @@ static unsigned int ref922x_pin_configs[10] = {
0x40000100, 0x40000100,
};
+/*
+ STAC 922X pin configs for
+ 102801A7
+ 102801AB
+ 102801A9
+ 102801D1
+ 102801D2
+*/
+static unsigned int dell_922x_d81_pin_configs[10] = {
+ 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
+ 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1,
+ 0x01813122, 0x400001f2,
+};
+
+/*
+ STAC 922X pin configs for
+ 102801AC
+ 102801D0
+*/
+static unsigned int dell_922x_d82_pin_configs[10] = {
+ 0x02214030, 0x01a19021, 0x01111012, 0x01114010,
+ 0x02a19020, 0x01117011, 0x01451140, 0x400001f0,
+ 0x01813122, 0x400001f1,
+};
+
+/*
+ STAC 922X pin configs for
+ 102801BF
+*/
+static unsigned int dell_922x_m81_pin_configs[10] = {
+ 0x0321101f, 0x01112024, 0x01111222, 0x91174220,
+ 0x03a11050, 0x01116221, 0x90a70330, 0x01452340,
+ 0x40C003f1, 0x405003f0,
+};
+
+/*
+ STAC 9221 A1 pin configs for
+ 102801D7 (Dell XPS M1210)
+*/
+static unsigned int dell_922x_m82_pin_configs[10] = {
+ 0x0221121f, 0x408103ff, 0x02111212, 0x90100310,
+ 0x408003f1, 0x02111211, 0x03451340, 0x40c003f2,
+ 0x508003f3, 0x405003f4,
+};
+
static unsigned int d945gtp3_pin_configs[10] = {
0x0221401f, 0x01a19022, 0x01813021, 0x01014010,
0x40000100, 0x40000100, 0x40000100, 0x40000100,
@@ -585,48 +921,49 @@ static unsigned int intel_mac_v5_pin_configs[10] = {
0x400000fc, 0x400000fb,
};
-static unsigned int stac922x_dell_pin_configs[10] = {
- 0x0221121e, 0x408103ff, 0x02a1123e, 0x90100310,
- 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2,
- 0x50a003f3, 0x405003f4
-};
static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
[STAC_D945_REF] = ref922x_pin_configs,
[STAC_D945GTP3] = d945gtp3_pin_configs,
[STAC_D945GTP5] = d945gtp5_pin_configs,
- [STAC_922X_DELL] = stac922x_dell_pin_configs,
[STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs,
[STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs,
[STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
[STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
[STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
- /* for backward compitability */
+ /* for backward compatibility */
[STAC_MACMINI] = intel_mac_v3_pin_configs,
[STAC_MACBOOK] = intel_mac_v5_pin_configs,
[STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs,
[STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs,
[STAC_IMAC_INTEL] = intel_mac_v2_pin_configs,
[STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs,
+ [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs,
+ [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs,
+ [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs,
+ [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
};
static const char *stac922x_models[STAC_922X_MODELS] = {
[STAC_D945_REF] = "ref",
[STAC_D945GTP5] = "5stack",
[STAC_D945GTP3] = "3stack",
- [STAC_922X_DELL] = "dell",
[STAC_INTEL_MAC_V1] = "intel-mac-v1",
[STAC_INTEL_MAC_V2] = "intel-mac-v2",
[STAC_INTEL_MAC_V3] = "intel-mac-v3",
[STAC_INTEL_MAC_V4] = "intel-mac-v4",
[STAC_INTEL_MAC_V5] = "intel-mac-v5",
- /* for backward compitability */
+ /* for backward compatibility */
[STAC_MACMINI] = "macmini",
[STAC_MACBOOK] = "macbook",
[STAC_MACBOOK_PRO_V1] = "macbook-pro-v1",
[STAC_MACBOOK_PRO_V2] = "macbook-pro",
[STAC_IMAC_INTEL] = "imac-intel",
[STAC_IMAC_INTEL_20] = "imac-intel-20",
+ [STAC_922X_DELL_D81] = "dell-d81",
+ [STAC_922X_DELL_D82] = "dell-d82",
+ [STAC_922X_DELL_M81] = "dell-m81",
+ [STAC_922X_DELL_M82] = "dell-m82",
};
static struct snd_pci_quirk stac922x_cfg_tbl[] = {
@@ -690,9 +1027,25 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
/* Apple Mac Mini (early 2006) */
SND_PCI_QUIRK(0x8384, 0x7680,
"Mac Mini", STAC_INTEL_MAC_V3),
- /* Dell */
- SND_PCI_QUIRK(0x1028, 0x01d7, "Dell XPS M1210", STAC_922X_DELL),
-
+ /* Dell systems */
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
+ "unknown Dell", STAC_922X_DELL_D81),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9,
+ "unknown Dell", STAC_922X_DELL_D81),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab,
+ "unknown Dell", STAC_922X_DELL_D81),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac,
+ "unknown Dell", STAC_922X_DELL_D82),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf,
+ "unknown Dell", STAC_922X_DELL_M81),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0,
+ "unknown Dell", STAC_922X_DELL_D82),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1,
+ "unknown Dell", STAC_922X_DELL_D81),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2,
+ "unknown Dell", STAC_922X_DELL_D81),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7,
+ "Dell XPS M1210", STAC_922X_DELL_M82),
{} /* terminator */
};
@@ -717,16 +1070,25 @@ static unsigned int d965_5st_pin_configs[14] = {
0x40000100, 0x40000100
};
+static unsigned int dell_3st_pin_configs[14] = {
+ 0x02211230, 0x02a11220, 0x01a19040, 0x01114210,
+ 0x01111212, 0x01116211, 0x01813050, 0x01112214,
+ 0x403003fa, 0x40000100, 0x40000100, 0x404003fb,
+ 0x40c003fc, 0x40000100
+};
+
static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
[STAC_D965_REF] = ref927x_pin_configs,
[STAC_D965_3ST] = d965_3st_pin_configs,
[STAC_D965_5ST] = d965_5st_pin_configs,
+ [STAC_DELL_3ST] = dell_3st_pin_configs,
};
static const char *stac927x_models[STAC_927X_MODELS] = {
[STAC_D965_REF] = "ref",
[STAC_D965_3ST] = "3stack",
[STAC_D965_5ST] = "5stack",
+ [STAC_DELL_3ST] = "dell-3stack",
};
static struct snd_pci_quirk stac927x_cfg_tbl[] = {
@@ -753,7 +1115,13 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_D965_3ST),
+ /* Dell 3 stack systems */
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
/* 965 based 5 stack systems */
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_D965_5ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
@@ -772,23 +1140,97 @@ static unsigned int ref9205_pin_configs[12] = {
0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
};
+/*
+ STAC 9205 pin configs for
+ 102801F1
+ 102801F2
+ 102801FC
+ 102801FD
+ 10280204
+ 1028021F
+*/
+static unsigned int dell_9205_m42_pin_configs[12] = {
+ 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
+ 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9,
+ 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE,
+};
+
+/*
+ STAC 9205 pin configs for
+ 102801F9
+ 102801FA
+ 102801FE
+ 102801FF (Dell Precision M4300)
+ 10280206
+ 10280200
+ 10280201
+*/
+static unsigned int dell_9205_m43_pin_configs[12] = {
+ 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310,
+ 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9,
+ 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8,
+};
+
+static unsigned int dell_9205_m44_pin_configs[12] = {
+ 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310,
+ 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9,
+ 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe,
+};
+
static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
- [STAC_REF] = ref9205_pin_configs,
- [STAC_M43xx] = NULL,
+ [STAC_9205_REF] = ref9205_pin_configs,
+ [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs,
+ [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs,
+ [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs,
};
static const char *stac9205_models[STAC_9205_MODELS] = {
[STAC_9205_REF] = "ref",
+ [STAC_9205_DELL_M42] = "dell-m42",
+ [STAC_9205_DELL_M43] = "dell-m43",
+ [STAC_9205_DELL_M44] = "dell-m44",
};
static struct snd_pci_quirk stac9205_cfg_tbl[] = {
/* SigmaTel reference board */
SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
"DFI LanParty", STAC_9205_REF),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8,
- "Dell Precision", STAC_M43xx),
- SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff,
- "Dell Precision", STAC_M43xx),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
+ "unknown Dell", STAC_9205_DELL_M42),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
+ "unknown Dell", STAC_9205_DELL_M42),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
+ "unknown Dell", STAC_9205_DELL_M42),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
+ "unknown Dell", STAC_9205_DELL_M42),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff,
+ "Dell Precision M4300", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206,
+ "Dell Precision", STAC_9205_DELL_M43),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1,
+ "Dell Inspiron", STAC_9205_DELL_M44),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2,
+ "Dell Inspiron", STAC_9205_DELL_M44),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc,
+ "Dell Inspiron", STAC_9205_DELL_M44),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd,
+ "Dell Inspiron", STAC_9205_DELL_M44),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204,
+ "unknown Dell", STAC_9205_DELL_M42),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f,
+ "Dell Inspiron", STAC_9205_DELL_M44),
{} /* terminator */
};
@@ -854,20 +1296,20 @@ static void stac92xx_set_config_regs(struct hda_codec *codec)
spec->pin_configs[i]);
}
-static void stac92xx_enable_gpio_mask(struct hda_codec *codec,
- int gpio_mask, int gpio_data)
+static void stac92xx_enable_gpio_mask(struct hda_codec *codec)
{
+ struct sigmatel_spec *spec = codec->spec;
/* Configure GPIOx as output */
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DIRECTION, gpio_mask);
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_DIRECTION, spec->gpio_mask);
/* Configure GPIOx as CMOS */
- snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
+ snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7e7, 0x00000000);
/* Assert GPIOx */
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_DATA, gpio_data);
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_DATA, spec->gpio_data);
/* Enable GPIOx */
- snd_hda_codec_write(codec, codec->afg, 0,
- AC_VERB_SET_GPIO_MASK, gpio_mask);
+ snd_hda_codec_write_cache(codec, codec->afg, 0,
+ AC_VERB_SET_GPIO_MASK, spec->gpio_mask);
}
/*
@@ -1000,10 +1442,9 @@ static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = {
};
static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
- .substreams = 2,
.channels_min = 2,
.channels_max = 2,
- /* NID is set in stac92xx_build_pcms */
+ /* NID + .substreams is set in stac92xx_build_pcms */
.ops = {
.prepare = stac92xx_capture_pcm_prepare,
.cleanup = stac92xx_capture_pcm_cleanup
@@ -1022,6 +1463,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+ info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
if (spec->alt_switch) {
codec->num_pcms++;
@@ -1066,17 +1508,11 @@ static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
{
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
}
-static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define stac92xx_io_switch_info snd_ctl_boolean_mono_info
static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1109,6 +1545,36 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
return 1;
}
+#define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info
+
+static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+
+ ucontrol->value.integer.value[0] = spec->clfe_swap;
+ return 0;
+}
+
+static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct sigmatel_spec *spec = codec->spec;
+ hda_nid_t nid = kcontrol->private_value & 0xff;
+
+ if (spec->clfe_swap == ucontrol->value.integer.value[0])
+ return 0;
+
+ spec->clfe_swap = ucontrol->value.integer.value[0];
+
+ snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
+ spec->clfe_swap ? 0x4 : 0x0);
+
+ return 1;
+}
+
#define STAC_CODEC_IO_SWITCH(xname, xpval) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
.name = xname, \
@@ -1119,17 +1585,28 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
.private_value = xpval, \
}
+#define STAC_CODEC_CLFE_SWITCH(xname, xpval) \
+ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = 0, \
+ .info = stac92xx_clfe_switch_info, \
+ .get = stac92xx_clfe_switch_get, \
+ .put = stac92xx_clfe_switch_put, \
+ .private_value = xpval, \
+ }
enum {
STAC_CTL_WIDGET_VOL,
STAC_CTL_WIDGET_MUTE,
STAC_CTL_WIDGET_IO_SWITCH,
+ STAC_CTL_WIDGET_CLFE_SWITCH
};
static struct snd_kcontrol_new stac92xx_control_templates[] = {
HDA_CODEC_VOLUME(NULL, 0, 0, 0),
HDA_CODEC_MUTE(NULL, 0, 0, 0),
STAC_CODEC_IO_SWITCH(NULL, 0),
+ STAC_CODEC_CLFE_SWITCH(NULL, 0),
};
/* add dynamic controls */
@@ -1182,7 +1659,8 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
case 3:
/* add line-in as side */
if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
- cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
+ cfg->line_out_pins[cfg->line_outs] =
+ cfg->input_pins[AUTO_PIN_LINE];
spec->line_switch = 1;
cfg->line_outs++;
}
@@ -1190,12 +1668,14 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
case 2:
/* add line-in as clfe and mic as side */
if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
- cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
+ cfg->line_out_pins[cfg->line_outs] =
+ cfg->input_pins[AUTO_PIN_LINE];
spec->line_switch = 1;
cfg->line_outs++;
}
if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
- cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
+ cfg->line_out_pins[cfg->line_outs] =
+ cfg->input_pins[AUTO_PIN_MIC];
spec->mic_switch = 1;
cfg->line_outs++;
}
@@ -1203,12 +1683,14 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
case 1:
/* add line-in as surr and mic as clfe */
if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
- cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
+ cfg->line_out_pins[cfg->line_outs] =
+ cfg->input_pins[AUTO_PIN_LINE];
spec->line_switch = 1;
cfg->line_outs++;
}
if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
- cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
+ cfg->line_out_pins[cfg->line_outs] =
+ cfg->input_pins[AUTO_PIN_MIC];
spec->mic_switch = 1;
cfg->line_outs++;
}
@@ -1282,8 +1764,8 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
spec->multiout.num_dacs++;
if (conn_len > 1) {
/* select this DAC in the pin's input mux */
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_CONNECT_SEL, j);
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_CONNECT_SEL, j);
}
}
@@ -1318,7 +1800,7 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_
}
/* add playback controls from the parsed DAC table */
-static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
+static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
static const char *chname[4] = {
@@ -1327,6 +1809,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
hda_nid_t nid;
int i, err;
+ struct sigmatel_spec *spec = codec->spec;
+ unsigned int wid_caps;
+
+
for (i = 0; i < cfg->line_outs; i++) {
if (!spec->multiout.dac_nids[i])
continue;
@@ -1341,6 +1827,18 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
err = create_controls(spec, "LFE", nid, 2);
if (err < 0)
return err;
+
+ wid_caps = get_wcaps(codec, nid);
+
+ if (wid_caps & AC_WCAP_LR_SWAP) {
+ err = stac92xx_add_control(spec,
+ STAC_CTL_WIDGET_CLFE_SWITCH,
+ "Swap Center/LFE Playback Switch", nid);
+
+ if (err < 0)
+ return err;
+ }
+
} else {
err = create_controls(spec, chname[i], nid, 3);
if (err < 0)
@@ -1536,9 +2034,9 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
* NID lists. Hopefully this won't get confused.
*/
for (i = 0; i < spec->num_muxes; i++) {
- snd_hda_codec_write(codec, spec->mux_nids[i], 0,
- AC_VERB_SET_CONNECT_SEL,
- imux->items[0].index);
+ snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0,
+ AC_VERB_SET_CONNECT_SEL,
+ imux->items[0].index);
}
}
@@ -1593,9 +2091,19 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
return err;
- if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
- (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 ||
- (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
+ err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
+
+ if (err < 0)
+ return err;
+
+ err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
+
+ if (err < 0)
+ return err;
+
+ err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
+
+ if (err < 0)
return err;
if (spec->num_dmics > 0)
@@ -1764,9 +2272,9 @@ static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
unsigned int event)
{
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)
- snd_hda_codec_write(codec, nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- (AC_USRSP_EN | event));
+ snd_hda_codec_write_cache(codec, nid, 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ (AC_USRSP_EN | event));
}
static int stac92xx_init(struct hda_codec *codec)
@@ -1870,7 +2378,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
- snd_hda_codec_write(codec, nid, 0,
+ snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pin_ctl | flag);
}
@@ -1880,7 +2388,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
{
unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
- snd_hda_codec_write(codec, nid, 0,
+ snd_hda_codec_write_cache(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pin_ctl & ~flag);
}
@@ -1936,22 +2444,22 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
}
}
-#ifdef CONFIG_PM
+#ifdef SND_HDA_NEEDS_RESUME
static int stac92xx_resume(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
- int i;
- stac92xx_init(codec);
stac92xx_set_config_regs(codec);
- snd_hda_resume_ctls(codec, spec->mixer);
- for (i = 0; i < spec->num_mixers; i++)
- snd_hda_resume_ctls(codec, spec->mixers[i]);
- if (spec->multiout.dig_out_nid)
- snd_hda_resume_spdif_out(codec);
- if (spec->dig_in_nid)
- snd_hda_resume_spdif_in(codec);
-
+ snd_hda_sequence_write(codec, spec->init);
+ if (spec->gpio_mute) {
+ stac922x_gpio_mute(codec, 0, 0);
+ stac922x_gpio_mute(codec, 1, 0);
+ }
+ snd_hda_codec_resume_amp(codec);
+ snd_hda_codec_resume_cache(codec);
+ /* invoke unsolicited event to reset the HP state */
+ if (spec->hp_detect)
+ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
return 0;
}
#endif
@@ -1962,7 +2470,7 @@ static struct hda_codec_ops stac92xx_patch_ops = {
.init = stac92xx_init,
.free = stac92xx_free,
.unsol_event = stac92xx_unsol_event,
-#ifdef CONFIG_PM
+#ifdef SND_HDA_NEEDS_RESUME
.resume = stac92xx_resume,
#endif
};
@@ -2002,8 +2510,12 @@ static int patch_stac9200(struct hda_codec *codec)
spec->mux_nids = stac9200_mux_nids;
spec->num_muxes = 1;
spec->num_dmics = 0;
+ spec->num_adcs = 1;
- spec->init = stac9200_core_init;
+ if (spec->board_config == STAC_9200_GATEWAY)
+ spec->init = stac9200_eapd_init;
+ else
+ spec->init = stac9200_core_init;
spec->mixer = stac9200_mixer;
err = stac9200_parse_auto_config(codec);
@@ -2053,12 +2565,13 @@ static int patch_stac925x(struct hda_codec *codec)
spec->adc_nids = stac925x_adc_nids;
spec->mux_nids = stac925x_mux_nids;
spec->num_muxes = 1;
+ spec->num_adcs = 1;
switch (codec->vendor_id) {
case 0x83847632: /* STAC9202 */
case 0x83847633: /* STAC9202D */
case 0x83847636: /* STAC9251 */
case 0x83847637: /* STAC9251D */
- spec->num_dmics = 1;
+ spec->num_dmics = STAC925X_NUM_DMICS;
spec->dmic_nids = stac925x_dmic_nids;
break;
default:
@@ -2156,6 +2669,7 @@ static int patch_stac922x(struct hda_codec *codec)
spec->adc_nids = stac922x_adc_nids;
spec->mux_nids = stac922x_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
+ spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids);
spec->num_dmics = 0;
spec->init = stac922x_core_init;
@@ -2224,22 +2738,25 @@ static int patch_stac927x(struct hda_codec *codec)
spec->adc_nids = stac927x_adc_nids;
spec->mux_nids = stac927x_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
+ spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
spec->num_dmics = 0;
spec->init = d965_core_init;
- spec->mixer = stac9227_mixer;
+ spec->mixer = stac927x_mixer;
break;
case STAC_D965_5ST:
spec->adc_nids = stac927x_adc_nids;
spec->mux_nids = stac927x_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
+ spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
spec->num_dmics = 0;
spec->init = d965_core_init;
- spec->mixer = stac9227_mixer;
+ spec->mixer = stac927x_mixer;
break;
default:
spec->adc_nids = stac927x_adc_nids;
spec->mux_nids = stac927x_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
+ spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids);
spec->num_dmics = 0;
spec->init = stac927x_core_init;
spec->mixer = stac927x_mixer;
@@ -2247,7 +2764,8 @@ static int patch_stac927x(struct hda_codec *codec)
spec->multiout.dac_nids = spec->dac_nids;
/* GPIO0 High = Enable EAPD */
- stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001);
+ spec->gpio_mask = spec->gpio_data = 0x00000001;
+ stac92xx_enable_gpio_mask(codec);
err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
if (!err) {
@@ -2272,7 +2790,7 @@ static int patch_stac927x(struct hda_codec *codec)
static int patch_stac9205(struct hda_codec *codec)
{
struct sigmatel_spec *spec;
- int err, gpio_mask, gpio_data;
+ int err;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
@@ -2299,10 +2817,11 @@ static int patch_stac9205(struct hda_codec *codec)
}
spec->adc_nids = stac9205_adc_nids;
+ spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids);
spec->mux_nids = stac9205_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
spec->dmic_nids = stac9205_dmic_nids;
- spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
+ spec->num_dmics = STAC9205_NUM_DMICS;
spec->dmux_nid = 0x1d;
spec->init = stac9205_core_init;
@@ -2310,20 +2829,25 @@ static int patch_stac9205(struct hda_codec *codec)
spec->multiout.dac_nids = spec->dac_nids;
- if (spec->board_config == STAC_M43xx) {
+ switch (spec->board_config){
+ case STAC_9205_DELL_M43:
/* Enable SPDIF in/out */
stac92xx_set_config_reg(codec, 0x1f, 0x01441030);
stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
- gpio_mask = 0x00000007; /* GPIO0-2 */
+ spec->gpio_mask = 0x00000007; /* GPIO0-2 */
/* GPIO0 High = EAPD, GPIO1 Low = DRM,
* GPIO2 High = Headphone Mute
*/
- gpio_data = 0x00000005;
- } else
- gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */
+ spec->gpio_data = 0x00000005;
+ break;
+ default:
+ /* GPIO0 High = EAPD */
+ spec->gpio_mask = spec->gpio_data = 0x00000001;
+ break;
+ }
- stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data);
+ stac92xx_enable_gpio_mask(codec);
err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
if (!err) {
if (spec->board_config < 0) {
@@ -2355,7 +2879,7 @@ static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ };
static hda_nid_t vaio_mux_nids[] = { 0x15 };
static struct hda_input_mux vaio_mux = {
- .num_items = 2,
+ .num_items = 3,
.items = {
/* { "HP", 0x0 }, */
{ "Mic Jack", 0x1 },
@@ -2366,6 +2890,7 @@ static struct hda_input_mux vaio_mux = {
static struct hda_verb vaio_init[] = {
{0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */
+ {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT},
{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */
{0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */
{0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */
@@ -2397,61 +2922,28 @@ static struct hda_verb vaio_ar_init[] = {
};
/* bind volumes of both NID 0x02 and 0x05 */
-static int vaio_master_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
- 0x7f, valp[0] & 0x7f);
- snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
- 0x7f, valp[1] & 0x7f);
- return change;
-}
+static struct hda_bind_ctls vaio_bind_master_vol = {
+ .ops = &snd_hda_bind_vol,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
+ 0
+ },
+};
/* bind volumes of both NID 0x02 and 0x05 */
-static int vaio_master_sw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
- long *valp = ucontrol->value.integer.value;
- int change;
-
- change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
- 0x80, (valp[0] ? 0 : 0x80));
- change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
- 0x80, (valp[1] ? 0 : 0x80));
- snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
- 0x80, (valp[0] ? 0 : 0x80));
- snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
- 0x80, (valp[1] ? 0 : 0x80));
- return change;
-}
+static struct hda_bind_ctls vaio_bind_master_sw = {
+ .ops = &snd_hda_bind_sw,
+ .values = {
+ HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
+ HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
+ 0,
+ },
+};
static struct snd_kcontrol_new vaio_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = vaio_master_vol_put,
- .tlv = { .c = snd_hda_mixer_amp_tlv },
- .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = vaio_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
- },
+ HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
/* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
@@ -2467,22 +2959,8 @@ static struct snd_kcontrol_new vaio_mixer[] = {
};
static struct snd_kcontrol_new vaio_ar_mixer[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Volume",
- .info = snd_hda_mixer_amp_volume_info,
- .get = snd_hda_mixer_amp_volume_get,
- .put = vaio_master_vol_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Master Playback Switch",
- .info = snd_hda_mixer_amp_switch_info,
- .get = snd_hda_mixer_amp_switch_get,
- .put = vaio_master_sw_put,
- .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
- },
+ HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol),
+ HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw),
/* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
@@ -2504,6 +2982,49 @@ static struct hda_codec_ops stac9872_patch_ops = {
.build_pcms = stac92xx_build_pcms,
.init = stac92xx_init,
.free = stac92xx_free,
+#ifdef SND_HDA_NEEDS_RESUME
+ .resume = stac92xx_resume,
+#endif
+};
+
+static int stac9872_vaio_init(struct hda_codec *codec)
+{
+ int err;
+
+ err = stac92xx_init(codec);
+ if (err < 0)
+ return err;
+ if (codec->patch_ops.unsol_event)
+ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
+ return 0;
+}
+
+static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
+{
+ if (get_pin_presence(codec, 0x0a)) {
+ stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
+ stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
+ } else {
+ stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
+ stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
+ }
+}
+
+static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+ switch (res >> 26) {
+ case STAC_HP_EVENT:
+ stac9872_vaio_hp_detect(codec, res);
+ break;
+ }
+}
+
+static struct hda_codec_ops stac9872_vaio_patch_ops = {
+ .build_controls = stac92xx_build_controls,
+ .build_pcms = stac92xx_build_pcms,
+ .init = stac9872_vaio_init,
+ .free = stac92xx_free,
+ .unsol_event = stac9872_vaio_unsol_event,
#ifdef CONFIG_PM
.resume = stac92xx_resume,
#endif
@@ -2564,6 +3085,7 @@ static int patch_stac9872(struct hda_codec *codec)
spec->adc_nids = vaio_adcs;
spec->input_mux = &vaio_mux;
spec->mux_nids = vaio_mux_nids;
+ codec->patch_ops = stac9872_vaio_patch_ops;
break;
case CXD9872AKD_VAIO:
@@ -2577,10 +3099,10 @@ static int patch_stac9872(struct hda_codec *codec)
spec->adc_nids = vaio_adcs;
spec->input_mux = &vaio_mux;
spec->mux_nids = vaio_mux_nids;
+ codec->patch_ops = stac9872_patch_ops;
break;
}
- codec->patch_ops = stac9872_patch_ops;
return 0;
}
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index ba32d1e52cb..33b5e1ffa81 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -115,6 +115,10 @@ struct via_spec {
struct snd_kcontrol_new *kctl_alloc;
struct hda_input_mux private_imux;
hda_nid_t private_dac_nids[4];
+
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ struct hda_loopback_check loopback;
+#endif
};
static hda_nid_t vt1708_adc_nids[2] = {
@@ -305,15 +309,15 @@ static struct hda_verb vt1708_volume_init_verbs[] = {
{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
*/
/* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* master */
+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output mixers (0x19 - 0x1b)
@@ -543,24 +547,11 @@ static int via_init(struct hda_codec *codec)
return 0;
}
-#ifdef CONFIG_PM
-/*
- * resume
- */
-static int via_resume(struct hda_codec *codec)
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{
struct via_spec *spec = codec->spec;
- int i;
-
- via_init(codec);
- for (i = 0; i < spec->num_mixers; i++)
- snd_hda_resume_ctls(codec, spec->mixers[i]);
- if (spec->multiout.dig_out_nid)
- snd_hda_resume_spdif_out(codec);
- if (spec->dig_in_nid)
- snd_hda_resume_spdif_in(codec);
-
- return 0;
+ return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
}
#endif
@@ -571,8 +562,8 @@ static struct hda_codec_ops via_patch_ops = {
.build_pcms = via_build_pcms,
.init = via_init,
.free = via_free,
-#ifdef CONFIG_PM
- .resume = via_resume,
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ .check_power_status = via_check_power_status,
#endif
};
@@ -762,6 +753,16 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list vt1708_loopbacks[] = {
+ { 0x17, HDA_INPUT, 1 },
+ { 0x17, HDA_INPUT, 2 },
+ { 0x17, HDA_INPUT, 3 },
+ { 0x17, HDA_INPUT, 4 },
+ { } /* end */
+};
+#endif
+
static int vt1708_parse_auto_config(struct hda_codec *codec)
{
struct via_spec *spec = codec->spec;
@@ -855,6 +856,9 @@ static int patch_vt1708(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = vt1708_loopbacks;
+#endif
return 0;
}
@@ -895,15 +899,15 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+ /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
* mixer widget
*/
/* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
- {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* unmute master */
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
/*
* Set up output selector (0x1a, 0x1b, 0x29)
@@ -1251,6 +1255,16 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
return 1;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static struct hda_amp_list vt1709_loopbacks[] = {
+ { 0x18, HDA_INPUT, 1 },
+ { 0x18, HDA_INPUT, 2 },
+ { 0x18, HDA_INPUT, 3 },
+ { 0x18, HDA_INPUT, 4 },
+ { } /* end */
+};
+#endif
+
static int patch_vt1709_10ch(struct hda_codec *codec)
{
struct via_spec *spec;
@@ -1293,6 +1307,9 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = vt1709_loopbacks;
+#endif
return 0;
}
@@ -1383,6 +1400,9 @@ static int patch_vt1709_6ch(struct hda_codec *codec)
codec->patch_ops = via_patch_ops;
codec->patch_ops.init = via_auto_init;
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+ spec->loopback.amplist = vt1709_loopbacks;
+#endif
return 0;
}
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index 6efdd62f683..65ce66adba5 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ice17xx-ak4xxx-objs := ak4xxx.o
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index ab00cce2c39..a1aba0d7d0e 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -3,7 +3,7 @@
*
* AK4524 / AK4528 / AK4529 / AK4355 / AK4381 interface
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -30,7 +30,7 @@
#include <sound/initval.h>
#include "ice1712.h"
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface");
MODULE_LICENSE("GPL");
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 44bbb630b94..6e13d758bb5 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -3,7 +3,7 @@
*
* Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
index a0fc89b4812..bf81d30d915 100644
--- a/sound/pci/ice1712/amp.h
+++ b/sound/pci/ice1712/amp.h
@@ -6,7 +6,7 @@
*
* Lowlevel functions for Advanced Micro Peripherals Ltd AUDIO2000
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 66bacde1ead..ec0699c8995 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -394,7 +394,7 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
/*
* AC'97 mute controls
*/
-#define aureon_ac97_mute_info aureon_mono_bool_info
+#define aureon_ac97_mute_info snd_ctl_boolean_mono_info
static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -430,7 +430,7 @@ static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
/*
* AC'97 mute controls
*/
-#define aureon_ac97_micboost_info aureon_mono_bool_info
+#define aureon_ac97_micboost_info snd_ctl_boolean_mono_info
static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -621,19 +621,12 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
/*
*/
-static int aureon_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define aureon_mono_bool_info snd_ctl_boolean_mono_info
/*
* AC'97 master playback mute controls (Mute on WM8770 chip)
*/
-#define aureon_ac97_mmute_info aureon_mono_bool_info
+#define aureon_ac97_mmute_info snd_ctl_boolean_mono_info
static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -708,7 +701,7 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
/*
* DAC mute control
*/
-#define wm_pcm_mute_info aureon_mono_bool_info
+#define wm_pcm_mute_info snd_ctl_boolean_mono_info
static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -879,13 +872,7 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
/*
* WM8770 master mute control
*/
-static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define wm_master_mute_info snd_ctl_boolean_stereo_info
static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -969,14 +956,7 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
/*
* ADC mute control
*/
-static int wm_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define wm_adc_mute_info snd_ctl_boolean_stereo_info
static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1210,12 +1190,7 @@ static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl
/*
* CS8415A Mute
*/
-static int aureon_cs8415_mute_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- return 0;
-}
+#define aureon_cs8415_mute_info snd_ctl_boolean_mono_info
static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1316,7 +1291,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
return ( tmp & AUREON_HP_SEL )!= 0;
}
-#define aureon_hpamp_info aureon_mono_bool_info
+#define aureon_hpamp_info snd_ctl_boolean_mono_info
static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1338,7 +1313,7 @@ static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
* Deemphasis
*/
-#define aureon_deemp_info aureon_mono_bool_info
+#define aureon_deemp_info snd_ctl_boolean_mono_info
static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index af659800c9b..371f78461db 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -4,7 +4,7 @@
* Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
* Digigram VX442
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -393,15 +393,8 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
}
-static int snd_ice1712_delta1010lt_wordclock_status_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_delta1010lt_wordclock_status_info \
+ snd_ctl_boolean_mono_info
static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index 2697156607e..26ea05a32f5 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -7,7 +7,7 @@
* Lowlevel functions for M-Audio Delta 1010, 44, 66, Dio2496, Audiophile
* Digigram VX442
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
index b58afcda9ed..43b9e3e858b 100644
--- a/sound/pci/ice1712/envy24ht.h
+++ b/sound/pci/ice1712/envy24ht.h
@@ -4,7 +4,7 @@
/*
* ALSA driver for ICEnsemble VT1724 (Envy24)
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index b135389fec6..75e4e5e0f1e 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -3,7 +3,7 @@
*
* Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
* 2002 Takashi Iwai <tiwai@suse.de>
*
* This program is free software; you can redistribute it and/or modify
@@ -700,14 +700,7 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata =
* EWS88D specific controls
*/
-static int snd_ice1712_ews88d_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_ews88d_control_info snd_ctl_boolean_mono_info
static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -812,14 +805,7 @@ static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char re
return 0;
}
-static int snd_ice1712_6fire_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_6fire_control_info snd_ctl_boolean_mono_info
static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h
index a12a0b05355..e4ed1b475b0 100644
--- a/sound/pci/ice1712/ews.h
+++ b/sound/pci/ice1712/ews.h
@@ -6,7 +6,7 @@
*
* Lowlevel functions for Terratec EWS88MT/D, EWX24/96, DMX 6Fire
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
* 2002 Takashi Iwai <tiwai@suse.de>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index 8203562ef7e..abcfd1da658 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -3,7 +3,7 @@
*
* Lowlevel functions for Hoontech STDSP24
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h
index 1ee538b20fb..cc1da1e69ad 100644
--- a/sound/pci/ice1712/hoontech.h
+++ b/sound/pci/ice1712/hoontech.h
@@ -6,7 +6,7 @@
*
* Lowlevel functions for Hoontech STDSP24
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 6630a0ae952..052fc3cb327 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -1,7 +1,7 @@
/*
* ALSA driver for ICEnsemble ICE1712 (Envy24)
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -73,7 +73,7 @@
#include "ews.h"
#include "hoontech.h"
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{"
@@ -256,14 +256,7 @@ static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97,
/*
* consumer ac97 digital mix
*/
-static int snd_ice1712_digmix_route_ac97_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_digmix_route_ac97_info snd_ctl_boolean_mono_info
static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1300,14 +1293,7 @@ static void snd_ice1712_update_volume(struct snd_ice1712 *ice, int index)
outw(val, ICEMT(ice, MONITOR_VOLUME));
}
-static int snd_ice1712_pro_mixer_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_pro_mixer_switch_info snd_ctl_boolean_stereo_info
static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1759,16 +1745,6 @@ static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
.put = snd_ice1712_spdif_stream_put
};
-int snd_ice1712_gpio_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1968,15 +1944,7 @@ static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitd
.put = snd_ice1712_pro_internal_clock_default_put
};
-static int snd_ice1712_pro_rate_locking_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_pro_rate_locking_info snd_ctl_boolean_mono_info
static int snd_ice1712_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2007,15 +1975,7 @@ static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
.put = snd_ice1712_pro_rate_locking_put
};
-static int snd_ice1712_pro_rate_reset_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ice1712_pro_rate_reset_info snd_ctl_boolean_mono_info
static int snd_ice1712_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 6ac486d9c13..58640afa540 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -4,7 +4,7 @@
/*
* ALSA driver for ICEnsemble ICE1712 (Envy24)
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -451,11 +451,10 @@ static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice)
/* for bit controls */
#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
-{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ice1712_gpio_info, \
+{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ctl_boolean_mono_info, \
.get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
.private_value = mask | (invert << 24) }
-int snd_ice1712_gpio_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index ee620dea7ef..0b0bbb0d96b 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2,7 +2,7 @@
* ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT)
* VIA VT1720 (Envy24PT)
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
* 2002 James Stafford <jstafford@ampltd.com>
* 2003 Takashi Iwai <tiwai@suse.de>
*
@@ -52,7 +52,7 @@
#include "phase.h"
#include "wtm.h"
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{"
@@ -341,10 +341,12 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
what = 0;
snd_pcm_group_for_each_entry(s, substream) {
- const struct vt1724_pcm_reg *reg;
- reg = s->runtime->private_data;
- what |= reg->start;
- snd_pcm_trigger_done(s, substream);
+ if (snd_pcm_substream_chip(s) == ice) {
+ const struct vt1724_pcm_reg *reg;
+ reg = s->runtime->private_data;
+ what |= reg->start;
+ snd_pcm_trigger_done(s, substream);
+ }
}
switch (cmd) {
@@ -1479,15 +1481,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
.get = snd_vt1724_spdif_maskp_get,
};
-static int snd_vt1724_spdif_sw_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_vt1724_spdif_sw_info snd_ctl_boolean_mono_info
static int snd_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1532,15 +1526,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
* GPIO access from extern
*/
-int snd_vt1724_gpio_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_vt1724_gpio_info snd_ctl_boolean_mono_info
int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1706,15 +1692,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
.put = snd_vt1724_pro_internal_clock_put
};
-static int snd_vt1724_pro_rate_locking_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_vt1724_pro_rate_locking_info snd_ctl_boolean_mono_info
static int snd_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1745,15 +1723,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
.put = snd_vt1724_pro_rate_locking_put
};
-static int snd_vt1724_pro_rate_reset_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_vt1724_pro_rate_reset_info snd_ctl_boolean_mono_info
static int snd_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 3d8e74e493d..1fbe3ef8e60 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -3,7 +3,7 @@
*
* Lowlevel functions for ESI Juli@ cards
*
- * Copyright (c) 2004 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2004 Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 40a9098af77..3ac25058bb5 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -270,7 +270,7 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
/*
* DAC mute control
*/
-#define wm_pcm_mute_info phase28_mono_bool_info
+#define wm_pcm_mute_info snd_ctl_boolean_mono_info
static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -527,13 +527,7 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
/*
* WM8770 master mute control
*/
-static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define wm_master_mute_info snd_ctl_boolean_stereo_info
static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -615,20 +609,9 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
}
/*
- */
-static int phase28_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-/*
* Deemphasis
*/
-#define phase28_deemp_info phase28_mono_bool_info
+#define phase28_deemp_info snd_ctl_boolean_mono_info
static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 01c69453dde..faefd52c1b8 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -216,14 +216,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
/*
* ADC input mux mixer control
*/
-static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define wm_adc_mux_info snd_ctl_boolean_mono_info
static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -260,14 +253,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
/*
* Analog bypass (In -> Out)
*/
-static int wm_bypass_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define wm_bypass_info snd_ctl_boolean_mono_info
static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -302,14 +288,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
/*
* Left/Right swap
*/
-static int wm_chswap_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define wm_chswap_info snd_ctl_boolean_mono_info
static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 4bae7305a79..4180f9739ec 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -81,14 +81,7 @@ static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
/*
* DAC mute control
*/
-static int stac9460_dac_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define stac9460_dac_mute_info snd_ctl_boolean_mono_info
static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -177,14 +170,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
/*
* ADC mute control
*/
-static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -292,14 +278,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
return ( tmp & AUREON_HP_SEL )!= 0;
}
-static int aureon_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define aureon_bool_info snd_ctl_boolean_mono_info
static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index 04e535c8542..7fcce0a506d 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -71,14 +71,7 @@ static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
/*
* DAC mute control
*/
-static int stac9460_dac_mute_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- return 0;
-}
+#define stac9460_dac_mute_info snd_ctl_boolean_mono_info
static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -218,15 +211,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
/*
* ADC mute control
*/
-static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define stac9460_adc_mute_info snd_ctl_boolean_stereo_info
static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -357,15 +342,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
* MIC / LINE switch fonction
*/
-static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define stac9460_mic_sw_info snd_ctl_boolean_mono_info
static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index da9734073db..b4a38a3d855 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1,7 +1,7 @@
/*
* ALSA driver for Intel ICH (i8x0) chipsets
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
*
* This code also contains alpha support for SiS 735 chipsets provided
@@ -43,7 +43,7 @@
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index c155e1f3a0e..fad806e60f3 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1,7 +1,7 @@
/*
* ALSA modem driver for Intel ICH (i8x0) chipsets
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
*
* This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
* of ALSA ICH sound driver intel8x0.c .
@@ -37,7 +37,7 @@
#include <sound/info.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; "
"SiS 7013; NVidia MCP/2/2S/3 modems");
MODULE_LICENSE("GPL");
diff --git a/sound/pci/korg1212/Makefile b/sound/pci/korg1212/Makefile
index 78c9dc6eeb2..f11ce1b1b3d 100644
--- a/sound/pci/korg1212/Makefile
+++ b/sound/pci/korg1212/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-korg1212-objs := korg1212.o
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 5338243fb03..c4af57fb5af 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1391,8 +1391,6 @@ static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n",
stateName[korg1212->cardState]);
- snd_pcm_set_sync(substream); // ???
-
snd_korg1212_OpenCard(korg1212);
runtime->hw = snd_korg1212_playback_info;
@@ -1422,8 +1420,6 @@ static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n",
stateName[korg1212->cardState]);
- snd_pcm_set_sync(substream);
-
snd_korg1212_OpenCard(korg1212);
runtime->hw = snd_korg1212_capture_info;
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 8a5ff1cb536..32245770595 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1821,7 +1821,6 @@ snd_m3_playback_open(struct snd_pcm_substream *subs)
return err;
runtime->hw = snd_m3_playback;
- snd_pcm_set_sync(subs);
return 0;
}
@@ -1846,7 +1845,6 @@ snd_m3_capture_open(struct snd_pcm_substream *subs)
return err;
runtime->hw = snd_m3_capture;
- snd_pcm_set_sync(subs);
return 0;
}
diff --git a/sound/pci/mixart/Makefile b/sound/pci/mixart/Makefile
index fe6ba0c4b56..cce159ec562 100644
--- a/sound/pci/mixart/Makefile
+++ b/sound/pci/mixart/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-mixart-objs := mixart.o mixart_core.o mixart_hwdep.o mixart_mixer.o
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index ac007cec087..880b824e24c 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -652,7 +652,7 @@ static int snd_mixart_hw_free(struct snd_pcm_substream *subs)
static struct snd_pcm_hardware snd_mixart_analog_caps =
{
.info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE),
.formats = ( SNDRV_PCM_FMTBIT_U8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
@@ -673,7 +673,7 @@ static struct snd_pcm_hardware snd_mixart_analog_caps =
static struct snd_pcm_hardware snd_mixart_digital_caps =
{
.info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE),
.formats = ( SNDRV_PCM_FMTBIT_U8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
@@ -1317,6 +1317,12 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
mgr->mem[i].phys = pci_resource_start(pci, i);
mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys,
pci_resource_len(pci, i));
+ if (!mgr->mem[i].virt) {
+ printk(KERN_ERR "unable to remap resource 0x%lx\n",
+ mgr->mem[i].phys);
+ snd_mixart_free(mgr);
+ return -EBUSY;
+ }
}
if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index d7d15c036e0..0e16512d25f 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -403,14 +403,7 @@ static struct snd_kcontrol_new mixart_control_analog_level = {
};
/* shared */
-static int mixart_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define mixart_sw_info snd_ctl_boolean_stereo_info
static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/nm256/Makefile b/sound/pci/nm256/Makefile
index d91d8c51921..a1bd44ff850 100644
--- a/sound/pci/nm256/Makefile
+++ b/sound/pci/nm256/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-nm256-objs := nm256.o
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index c7621bd770a..276c5763f0e 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -842,7 +842,6 @@ static void snd_nm256_setup_stream(struct nm256 *chip, struct nm256_stream *s,
runtime->private_data = s;
s->substream = substream;
- snd_pcm_set_sync(substream);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&constraints_rates);
}
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index f7f6a687f03..2d618bd7e62 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -646,6 +646,8 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
if (snd_pcm_stream_linked(subs)) {
struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
snd_pcm_group_for_each_entry(s, subs) {
+ if (snd_pcm_substream_chip(s) != chip)
+ continue;
stream = s->runtime->private_data;
stream->status =
PCXHR_STREAM_STATUS_SCHEDULE_RUN;
@@ -662,6 +664,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
if (pcxhr_update_r_buffer(stream))
return -EINVAL;
+ stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;
if (pcxhr_set_stream_state(stream))
return -EINVAL;
stream->status = PCXHR_STREAM_STATUS_RUNNING;
@@ -902,6 +905,8 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
+ snd_pcm_set_sync(subs);
+
mgr->ref_count_rate++;
mutex_unlock(&mgr->setup_mutex);
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index d9cc8d2beb6..5f8d42633b0 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -44,8 +44,8 @@
#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */
#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
-static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0);
-static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0);
+static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 3150);
+static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel)
{
@@ -144,14 +144,7 @@ static struct snd_kcontrol_new pcxhr_control_analog_level = {
};
/* shared */
-static int pcxhr_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define pcxhr_sw_info snd_ctl_boolean_stereo_info
static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -195,7 +188,7 @@ static struct snd_kcontrol_new pcxhr_control_output_switch = {
#define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */
#define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */
-static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
+static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10975, 25, 1800);
#define MORE_THAN_ONE_STREAM_LEVEL 0x000001
#define VALID_STREAM_PAN_LEVEL_MASK 0x800000
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 618653e2256..1475912588e 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -258,19 +258,6 @@ static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32)
& RME32_RCR_AUDIO_ADDR_MASK);
}
-static int snd_rme32_ratecode(int rate)
-{
- switch (rate) {
- case 32000: return SNDRV_PCM_RATE_32000;
- case 44100: return SNDRV_PCM_RATE_44100;
- case 48000: return SNDRV_PCM_RATE_48000;
- case 64000: return SNDRV_PCM_RATE_64000;
- case 88200: return SNDRV_PCM_RATE_88200;
- case 96000: return SNDRV_PCM_RATE_96000;
- }
- return 0;
-}
-
/* silence callback for halfduplex mode */
static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
@@ -887,7 +874,7 @@ static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream)
if ((rme32->rcreg & RME32_RCR_KMODE) &&
(rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
/* AutoSync */
- runtime->hw.rates = snd_rme32_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -929,7 +916,7 @@ static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream)
if (isadat) {
return -EIO;
}
- runtime->hw.rates = snd_rme32_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -965,7 +952,7 @@ snd_rme32_playback_adat_open(struct snd_pcm_substream *substream)
if ((rme32->rcreg & RME32_RCR_KMODE) &&
(rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
/* AutoSync */
- runtime->hw.rates = snd_rme32_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -989,7 +976,7 @@ snd_rme32_capture_adat_open(struct snd_pcm_substream *substream)
if (!isadat) {
return -EIO;
}
- runtime->hw.rates = snd_rme32_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -1582,16 +1569,8 @@ static void __devinit snd_rme32_proc_init(struct rme32 * rme32)
* control interface
*/
-static int
-snd_rme32_info_loopback_control(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_rme32_info_loopback_control snd_ctl_boolean_mono_info
+
static int
snd_rme32_get_loopback_control(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index e3304b7ccbc..0b3c532c401 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -301,20 +301,6 @@ snd_rme96_capture_ptr(struct rme96 *rme96)
}
static int
-snd_rme96_ratecode(int rate)
-{
- switch (rate) {
- case 32000: return SNDRV_PCM_RATE_32000;
- case 44100: return SNDRV_PCM_RATE_44100;
- case 48000: return SNDRV_PCM_RATE_48000;
- case 64000: return SNDRV_PCM_RATE_64000;
- case 88200: return SNDRV_PCM_RATE_88200;
- case 96000: return SNDRV_PCM_RATE_96000;
- }
- return 0;
-}
-
-static int
snd_rme96_playback_silence(struct snd_pcm_substream *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
@@ -1176,8 +1162,6 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_set_sync(substream);
-
spin_lock_irq(&rme96->lock);
if (rme96->playback_substream != NULL) {
spin_unlock_irq(&rme96->lock);
@@ -1194,7 +1178,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
(rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
{
/* slave clock */
- runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -1214,8 +1198,6 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_set_sync(substream);
-
runtime->hw = snd_rme96_capture_spdif_info;
if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
(rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
@@ -1223,7 +1205,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
if (isadat) {
return -EIO;
}
- runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -1247,8 +1229,6 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_set_sync(substream);
-
spin_lock_irq(&rme96->lock);
if (rme96->playback_substream != NULL) {
spin_unlock_irq(&rme96->lock);
@@ -1265,7 +1245,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
(rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
{
/* slave clock */
- runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -1280,8 +1260,6 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_set_sync(substream);
-
runtime->hw = snd_rme96_capture_adat_info;
if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
/* makes no sense to use analog input. Note that analog
@@ -1292,7 +1270,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
if (!isadat) {
return -EIO;
}
- runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
runtime->hw.rate_min = rate;
runtime->hw.rate_max = rate;
}
@@ -1826,15 +1804,8 @@ snd_rme96_proc_init(struct rme96 *rme96)
* control interface
*/
-static int
-snd_rme96_info_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_rme96_info_loopback_control snd_ctl_boolean_mono_info
+
static int
snd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile
index d2c294e136f..dcba5604020 100644
--- a/sound/pci/rme9652/Makefile
+++ b/sound/pci/rme9652/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-rme9652-objs := rme9652.o
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 3b3ef657f73..ff26a3672d4 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -606,28 +606,28 @@ static void snd_hdsp_9652_enable_mixer (struct hdsp *hdsp);
static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
{
- switch (hdsp->firmware_rev) {
- case 0xa:
+ switch (hdsp->io_type) {
+ case Multiface:
+ case Digiface:
+ default:
return (64 * out) + (32 + (in));
- case 0x96:
- case 0x97:
- case 0x98:
+ case H9632:
return (32 * out) + (16 + (in));
- default:
+ case H9652:
return (52 * out) + (26 + (in));
}
}
static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
{
- switch (hdsp->firmware_rev) {
- case 0xa:
+ switch (hdsp->io_type) {
+ case Multiface:
+ case Digiface:
+ default:
return (64 * out) + in;
- case 0x96:
- case 0x97:
- case 0x98:
+ case H9632:
return (32 * out) + in;
- default:
+ case H9652:
return (52 * out) + in;
}
}
@@ -1623,14 +1623,7 @@ static int hdsp_set_spdif_output(struct hdsp *hdsp, int out)
return 0;
}
-static int snd_hdsp_info_spdif_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_spdif_bits snd_ctl_boolean_mono_info
static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2111,14 +2104,7 @@ static int snd_hdsp_put_clock_source(struct snd_kcontrol *kcontrol, struct snd_c
return change;
}
-static int snd_hdsp_info_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_clock_source_lock snd_ctl_boolean_mono_info
static int snd_hdsp_get_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2420,14 +2406,7 @@ static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode)
return 0;
}
-static int snd_hdsp_info_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info
static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2483,14 +2462,7 @@ static int hdsp_set_aeb(struct hdsp *hdsp, int mode)
return 0;
}
-static int snd_hdsp_info_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_aeb snd_ctl_boolean_mono_info
static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2729,14 +2701,7 @@ static int hdsp_set_line_output(struct hdsp *hdsp, int out)
return 0;
}
-static int snd_hdsp_info_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_line_out snd_ctl_boolean_mono_info
static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2782,14 +2747,7 @@ static int hdsp_set_precise_pointer(struct hdsp *hdsp, int precise)
return 0;
}
-static int snd_hdsp_info_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_precise_pointer snd_ctl_boolean_mono_info
static int snd_hdsp_get_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -2835,14 +2793,7 @@ static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet)
return 0;
}
-static int snd_hdsp_info_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info
static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -3108,6 +3059,9 @@ static int hdsp_dds_offset(struct hdsp *hdsp)
unsigned int dds_value = hdsp->dds_value;
int system_sample_rate = hdsp->system_sample_rate;
+ if (!dds_value)
+ return 0;
+
n = DDS_NUMERATOR;
/*
* dds_value = n / rate
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 143185e7e4d..f1bdda6cbcf 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1,5 +1,4 @@
-/* -*- linux-c -*-
- *
+/*
* ALSA driver for RME Hammerfall DSP MADI audio interface(s)
*
* Copyright (c) 2003 Winfried Ritsch (IEM)
@@ -78,7 +77,8 @@ MODULE_PARM_DESC(enable_monitor,
"Enable Analog Out on Channel 63/64 by default.");
MODULE_AUTHOR
- ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, "
+ ("Winfried Ritsch <ritsch_AT_iem.at>, "
+ "Paul Davis <paul@linuxaudiosystems.com>, "
"Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
"Remy Bruno <remy.bruno@trinnov.com>");
MODULE_DESCRIPTION("RME HDSPM");
@@ -161,7 +161,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
0=off, 1=on */ /* MADI ONLY */
#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
-#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ /* MADI ONLY*/
+#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax
+ * -- MADI ONLY
+ */
#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */
@@ -189,11 +191,13 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
/* --- bit helper defines */
#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
-#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
+#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\
+ HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
#define HDSPM_InputOptical 0
#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
-#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|HDSPM_SyncRef2|HDSPM_SyncRef3)
+#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|\
+ HDSPM_SyncRef2|HDSPM_SyncRef3)
#define HDSPM_SyncRef_Word 0
#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0)
@@ -205,10 +209,12 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_Frequency48KHz (HDSPM_Frequency1|HDSPM_Frequency0)
#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
-#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
+#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|\
+ HDSPM_Frequency0)
#define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0)
#define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1)
-#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
+#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|\
+ HDSPM_Frequency0)
/* --- for internal discrimination */
#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */
@@ -256,10 +262,14 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_RD_MULTIPLE (1<<10)
/* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and
- that do not conflict with specific bits for AES32 seem to be valid also for the AES32 */
+ that do not conflict with specific bits for AES32 seem to be valid also
+ for the AES32
+ */
#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */
-#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */
-#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */
+#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn MODE=0 */
+#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1
+ * (like inp0)
+ */
#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
@@ -274,12 +284,15 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_madiFreq2 (1<<24) /* 4=64, 5=88.2 6=96 */
#define HDSPM_madiFreq3 (1<<25) /* 7=128, 8=176.4 9=192 */
-#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with Interrupt */
+#define HDSPM_BufferID (1<<26) /* (Double)Buffer ID toggles with
+ * Interrupt
+ */
#define HDSPM_midi0IRQPending (1<<30) /* MIDI IRQ is pending */
#define HDSPM_midi1IRQPending (1<<31) /* and aktiv */
/* --- status bit helpers */
-#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2|HDSPM_madiFreq3)
+#define HDSPM_madiFreqMask (HDSPM_madiFreq0|HDSPM_madiFreq1|\
+ HDSPM_madiFreq2|HDSPM_madiFreq3)
#define HDSPM_madiFreq32 (HDSPM_madiFreq0)
#define HDSPM_madiFreq44_1 (HDSPM_madiFreq1)
#define HDSPM_madiFreq48 (HDSPM_madiFreq0|HDSPM_madiFreq1)
@@ -319,10 +332,12 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_wcFreq96 (HDSPM_wc_freq1|HDSPM_wc_freq2)
-#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
+#define HDSPM_SelSyncRefMask (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
+ HDSPM_SelSyncRef2)
#define HDSPM_SelSyncRef_WORD 0
#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
-#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
+#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|\
+ HDSPM_SelSyncRef2)
/*
For AES32, bits for status, status2 and timecode are different
@@ -344,7 +359,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
-#define HDSPM_AES32_AUTOSYNC_FROM_NONE -1
+#define HDSPM_AES32_AUTOSYNC_FROM_NONE 9
/* status2 */
/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
@@ -398,6 +413,13 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
/* revisions >= 230 indicate AES32 card */
#define HDSPM_AESREVISION 230
+/* speed factor modes */
+#define HDSPM_SPEED_SINGLE 0
+#define HDSPM_SPEED_DOUBLE 1
+#define HDSPM_SPEED_QUAD 2
+/* names for speed modes */
+static char *hdspm_speed_names[] = { "single", "double", "quad" };
+
struct hdspm_midi {
struct hdspm *hdspm;
int id;
@@ -412,8 +434,9 @@ struct hdspm_midi {
struct hdspm {
spinlock_t lock;
- struct snd_pcm_substream *capture_substream; /* only one playback */
- struct snd_pcm_substream *playback_substream; /* and/or capture stream */
+ /* only one playback and/or capture stream */
+ struct snd_pcm_substream *capture_substream;
+ struct snd_pcm_substream *playback_substream;
char *card_name; /* for procinfo */
unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
@@ -460,9 +483,12 @@ struct hdspm {
struct pci_dev *pci; /* and an pci info */
/* Mixer vars */
- struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; /* fast alsa mixer */
- struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; /* but input to much, so not used */
- struct hdspm_mixer *mixer; /* full mixer accessable over mixer ioctl or hwdep-device */
+ /* fast alsa mixer */
+ struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];
+ /* but input to much, so not used */
+ struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];
+ /* full mixer accessable over mixer ioctl or hwdep-device */
+ struct hdspm_mixer *mixer;
};
@@ -616,13 +642,15 @@ static inline int hdspm_external_sample_rate(struct hdspm * hdspm)
if (hdspm->is_aes32) {
unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
- unsigned int timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
+ unsigned int timecode =
+ hdspm_read(hdspm, HDSPM_timecodeRegister);
int syncref = hdspm_autosync_ref(hdspm);
if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD &&
status & HDSPM_AES32_wcLock)
- return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF);
+ return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit)
+ & 0xF);
if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 &&
syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 &&
status2 & (HDSPM_LockAES >>
@@ -668,7 +696,9 @@ static inline int hdspm_external_sample_rate(struct hdspm * hdspm)
}
}
- /* if rate detected and Syncref is Word than have it, word has priority to MADI */
+ /* if rate detected and Syncref is Word than have it,
+ * word has priority to MADI
+ */
if (rate != 0 &&
(status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
return rate;
@@ -727,12 +757,12 @@ static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm * hdspm)
position = hdspm_read(hdspm, HDSPM_statusRegister);
- if (!hdspm->precise_ptr) {
- return (position & HDSPM_BufferID) ? (hdspm->period_bytes /
- 4) : 0;
- }
+ if (!hdspm->precise_ptr)
+ return (position & HDSPM_BufferID) ?
+ (hdspm->period_bytes / 4) : 0;
- /* hwpointer comes in bytes and is 64Bytes accurate (by docu since PCI Burst)
+ /* hwpointer comes in bytes and is 64Bytes accurate (by docu since
+ PCI Burst)
i have experimented that it is at most 64 Byte to much for playing
so substraction of 64 byte should be ok for ALSA, but use it only
for application where you know what you do since if you come to
@@ -811,7 +841,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
// return 104857600000000 / rate; // 100 MHz
return 110100480000000 / rate; // 105 MHz
*/
- //n = 104857600000000ULL; /* = 2^20 * 10^8 */
+ /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */
n = 110100480000000ULL; /* Value checked for AES32 and MADI */
div64_32(&n, rate, &r);
/* n should be less than 2^32 for being written to FREQ register */
@@ -822,11 +852,10 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
/* dummy set rate lets see what happens */
static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
{
- int reject_if_open = 0;
int current_rate;
int rate_bits;
int not_set = 0;
- int is_single, is_double, is_quad;
+ int current_speed, target_speed;
/* ASSUMPTION: hdspm->lock is either set, or there is no need for
it (e.g. during module initialization).
@@ -841,8 +870,9 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
just make a warning an remember setting
for future master mode switching */
- snd_printk
- (KERN_WARNING "HDSPM: Warning: device is not running as a clock master.\n");
+ snd_printk(KERN_WARNING "HDSPM: "
+ "Warning: device is not running "
+ "as a clock master.\n");
not_set = 1;
} else {
@@ -850,16 +880,18 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
int external_freq =
hdspm_external_sample_rate(hdspm);
- if ((hdspm_autosync_ref(hdspm) ==
- HDSPM_AUTOSYNC_FROM_NONE)) {
+ if (hdspm_autosync_ref(hdspm) ==
+ HDSPM_AUTOSYNC_FROM_NONE) {
- snd_printk(KERN_WARNING "HDSPM: Detected no Externel Sync \n");
+ snd_printk(KERN_WARNING "HDSPM: "
+ "Detected no Externel Sync \n");
not_set = 1;
} else if (rate != external_freq) {
- snd_printk
- (KERN_WARNING "HDSPM: Warning: No AutoSync source for requested rate\n");
+ snd_printk(KERN_WARNING "HDSPM: "
+ "Warning: No AutoSync source for "
+ "requested rate\n");
not_set = 1;
}
}
@@ -877,64 +909,60 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
changes in the read/write routines.
*/
- is_single = (current_rate <= 48000);
- is_double = (current_rate > 48000 && current_rate <= 96000);
- is_quad = (current_rate > 96000);
+ if (current_rate <= 48000)
+ current_speed = HDSPM_SPEED_SINGLE;
+ else if (current_rate <= 96000)
+ current_speed = HDSPM_SPEED_DOUBLE;
+ else
+ current_speed = HDSPM_SPEED_QUAD;
+
+ if (rate <= 48000)
+ target_speed = HDSPM_SPEED_SINGLE;
+ else if (rate <= 96000)
+ target_speed = HDSPM_SPEED_DOUBLE;
+ else
+ target_speed = HDSPM_SPEED_QUAD;
switch (rate) {
case 32000:
- if (!is_single)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency32KHz;
break;
case 44100:
- if (!is_single)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency44_1KHz;
break;
case 48000:
- if (!is_single)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency48KHz;
break;
case 64000:
- if (!is_double)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency64KHz;
break;
case 88200:
- if (!is_double)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency88_2KHz;
break;
case 96000:
- if (!is_double)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency96KHz;
break;
case 128000:
- if (!is_quad)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency128KHz;
break;
case 176400:
- if (!is_quad)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency176_4KHz;
break;
case 192000:
- if (!is_quad)
- reject_if_open = 1;
rate_bits = HDSPM_Frequency192KHz;
break;
default:
return -EINVAL;
}
- if (reject_if_open
+ if (current_speed != target_speed
&& (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) {
snd_printk
- (KERN_ERR "HDSPM: cannot change between single- and double-speed mode (capture PID = %d, playback PID = %d)\n",
+ (KERN_ERR "HDSPM: "
+ "cannot change from %s speed to %s speed mode "
+ "(capture PID = %d, playback PID = %d)\n",
+ hdspm_speed_names[current_speed],
+ hdspm_speed_names[target_speed],
hdspm->capture_pid, hdspm->playback_pid);
return -EBUSY;
}
@@ -966,8 +994,14 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
static void all_in_all_mixer(struct hdspm * hdspm, int sgain)
{
int i, j;
- unsigned int gain =
- (sgain > UNITY_GAIN) ? UNITY_GAIN : (sgain < 0) ? 0 : sgain;
+ unsigned int gain;
+
+ if (sgain > UNITY_GAIN)
+ gain = UNITY_GAIN;
+ else if (sgain < 0)
+ gain = 0;
+ else
+ gain = sgain;
for (i = 0; i < HDSPM_MIXER_CHANNELS; i++)
for (j = 0; j < HDSPM_MIXER_CHANNELS; j++) {
@@ -980,7 +1014,8 @@ static void all_in_all_mixer(struct hdspm * hdspm, int sgain)
MIDI
----------------------------------------------------------------------------*/
-static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, int id)
+static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm,
+ int id)
{
/* the hardware already does the relevant bit-mask with 0xff */
if (id)
@@ -989,7 +1024,8 @@ static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, int i
return hdspm_read(hdspm, HDSPM_midiDataIn0);
}
-static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, int val)
+static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id,
+ int val)
{
/* the hardware already does the relevant bit-mask with 0xff */
if (id)
@@ -1011,9 +1047,10 @@ static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
int fifo_bytes_used;
if (id)
- fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xff;
+ fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1);
else
- fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xff;
+ fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0);
+ fifo_bytes_used &= 0xff;
if (fifo_bytes_used < 128)
return 128 - fifo_bytes_used;
@@ -1038,16 +1075,21 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
/* Output is not interrupt driven */
spin_lock_irqsave (&hmidi->lock, flags);
- if (hmidi->output) {
- if (!snd_rawmidi_transmit_empty (hmidi->output)) {
- if ((n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm, hmidi->id)) > 0) {
- if (n_pending > (int)sizeof (buf))
- n_pending = sizeof (buf);
-
- if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
- for (i = 0; i < to_write; ++i)
- snd_hdspm_midi_write_byte (hmidi->hdspm, hmidi->id, buf[i]);
- }
+ if (hmidi->output &&
+ !snd_rawmidi_transmit_empty (hmidi->output)) {
+ n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm,
+ hmidi->id);
+ if (n_pending > 0) {
+ if (n_pending > (int)sizeof (buf))
+ n_pending = sizeof (buf);
+
+ to_write = snd_rawmidi_transmit (hmidi->output, buf,
+ n_pending);
+ if (to_write > 0) {
+ for (i = 0; i < to_write; ++i)
+ snd_hdspm_midi_write_byte (hmidi->hdspm,
+ hmidi->id,
+ buf[i]);
}
}
}
@@ -1057,51 +1099,55 @@ static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
{
- unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
+ unsigned char buf[128]; /* this buffer is designed to match the MIDI
+ * input FIFO size
+ */
unsigned long flags;
int n_pending;
int i;
spin_lock_irqsave (&hmidi->lock, flags);
- if ((n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id)) > 0) {
+ n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id);
+ if (n_pending > 0) {
if (hmidi->input) {
- if (n_pending > (int)sizeof (buf)) {
+ if (n_pending > (int)sizeof (buf))
n_pending = sizeof (buf);
- }
- for (i = 0; i < n_pending; ++i) {
- buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id);
- }
- if (n_pending) {
- snd_rawmidi_receive (hmidi->input, buf, n_pending);
- }
+ for (i = 0; i < n_pending; ++i)
+ buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm,
+ hmidi->id);
+ if (n_pending)
+ snd_rawmidi_receive (hmidi->input, buf,
+ n_pending);
} else {
/* flush the MIDI input FIFO */
- while (n_pending--) {
- snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id);
- }
+ while (n_pending--)
+ snd_hdspm_midi_read_byte (hmidi->hdspm,
+ hmidi->id);
}
}
hmidi->pending = 0;
- if (hmidi->id) {
+ if (hmidi->id)
hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable;
- } else {
+ else
hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable;
- }
- hdspm_write(hmidi->hdspm, HDSPM_controlRegister, hmidi->hdspm->control_register);
+ hdspm_write(hmidi->hdspm, HDSPM_controlRegister,
+ hmidi->hdspm->control_register);
spin_unlock_irqrestore (&hmidi->lock, flags);
return snd_hdspm_midi_output_write (hmidi);
}
-static void snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
+static void
+snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct hdspm *hdspm;
struct hdspm_midi *hmidi;
unsigned long flags;
u32 ie;
- hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
+ hmidi = substream->rmidi->private_data;
hdspm = hmidi->hdspm;
- ie = hmidi->id ? HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
+ ie = hmidi->id ?
+ HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
spin_lock_irqsave (&hdspm->lock, flags);
if (up) {
if (!(hdspm->control_register & ie)) {
@@ -1138,12 +1184,13 @@ static void snd_hdspm_midi_output_timer(unsigned long data)
spin_unlock_irqrestore (&hmidi->lock, flags);
}
-static void snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
+static void
+snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct hdspm_midi *hmidi;
unsigned long flags;
- hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
+ hmidi = substream->rmidi->private_data;
spin_lock_irqsave (&hmidi->lock, flags);
if (up) {
if (!hmidi->istimer) {
@@ -1155,9 +1202,8 @@ static void snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substrea
hmidi->istimer++;
}
} else {
- if (hmidi->istimer && --hmidi->istimer <= 0) {
+ if (hmidi->istimer && --hmidi->istimer <= 0)
del_timer (&hmidi->timer);
- }
}
spin_unlock_irqrestore (&hmidi->lock, flags);
if (up)
@@ -1168,7 +1214,7 @@ static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream)
{
struct hdspm_midi *hmidi;
- hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
+ hmidi = substream->rmidi->private_data;
spin_lock_irq (&hmidi->lock);
snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
hmidi->input = substream;
@@ -1181,7 +1227,7 @@ static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream)
{
struct hdspm_midi *hmidi;
- hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
+ hmidi = substream->rmidi->private_data;
spin_lock_irq (&hmidi->lock);
hmidi->output = substream;
spin_unlock_irq (&hmidi->lock);
@@ -1195,7 +1241,7 @@ static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream)
snd_hdspm_midi_input_trigger (substream, 0);
- hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
+ hmidi = substream->rmidi->private_data;
spin_lock_irq (&hmidi->lock);
hmidi->input = NULL;
spin_unlock_irq (&hmidi->lock);
@@ -1209,7 +1255,7 @@ static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
snd_hdspm_midi_output_trigger (substream, 0);
- hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
+ hmidi = substream->rmidi->private_data;
spin_lock_irq (&hmidi->lock);
hmidi->output = NULL;
spin_unlock_irq (&hmidi->lock);
@@ -1231,29 +1277,28 @@ static struct snd_rawmidi_ops snd_hdspm_midi_input =
.trigger = snd_hdspm_midi_input_trigger,
};
-static int __devinit snd_hdspm_create_midi (struct snd_card *card, struct hdspm *hdspm, int id)
+static int __devinit snd_hdspm_create_midi (struct snd_card *card,
+ struct hdspm *hdspm, int id)
{
int err;
char buf[32];
hdspm->midi[id].id = id;
- hdspm->midi[id].rmidi = NULL;
- hdspm->midi[id].input = NULL;
- hdspm->midi[id].output = NULL;
hdspm->midi[id].hdspm = hdspm;
- hdspm->midi[id].istimer = 0;
- hdspm->midi[id].pending = 0;
spin_lock_init (&hdspm->midi[id].lock);
sprintf (buf, "%s MIDI %d", card->shortname, id+1);
- if ((err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi)) < 0)
+ err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi);
+ if (err < 0)
return err;
sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
- snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdspm_midi_output);
- snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdspm_midi_input);
+ snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &snd_hdspm_midi_output);
+ snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &snd_hdspm_midi_input);
hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
SNDRV_RAWMIDI_INFO_INPUT |
@@ -1558,8 +1603,8 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
val = ucontrol->value.enumerated.item[0];
if (val < 0)
val = 0;
- if (val > 6)
- val = 6;
+ if (val > 9)
+ val = 9;
spin_lock_irq(&hdspm->lock);
if (val != hdspm_clock_source(hdspm))
change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
@@ -1637,7 +1682,8 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1;
break;
case 7:
- hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
+ hdspm->control_register |=
+ HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
break;
case 8:
hdspm->control_register |= HDSPM_SyncRef3;
@@ -1675,7 +1721,8 @@ static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
uinfo->value.enumerated.items = 9;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ if (uinfo->value.enumerated.item >=
+ uinfo->value.enumerated.items)
uinfo->value.enumerated.item =
uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name,
@@ -1688,7 +1735,8 @@ static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ if (uinfo->value.enumerated.item >=
+ uinfo->value.enumerated.items)
uinfo->value.enumerated.item =
uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name,
@@ -1740,7 +1788,8 @@ static int hdspm_autosync_ref(struct hdspm * hdspm)
{
if (hdspm->is_aes32) {
unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
- unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF;
+ unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) &
+ 0xF;
if (syncref == 0)
return HDSPM_AES32_AUTOSYNC_FROM_WORD;
if (syncref <= 8)
@@ -1777,20 +1826,20 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 10;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ if (uinfo->value.enumerated.item >=
+ uinfo->value.enumerated.items)
uinfo->value.enumerated.item =
uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name,
texts[uinfo->value.enumerated.item]);
- }
- else
- {
+ } else {
static char *texts[] = { "WordClock", "MADI", "None" };
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 3;
- if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+ if (uinfo->value.enumerated.item >=
+ uinfo->value.enumerated.items)
uinfo->value.enumerated.item =
uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name,
@@ -1804,7 +1853,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
{
struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
+ ucontrol->value.enumerated.item[0] = hdspm_autosync_ref(hdspm);
return 0;
}
@@ -1834,15 +1883,7 @@ static int hdspm_set_line_output(struct hdspm * hdspm, int out)
return 0;
}
-static int snd_hdspm_info_line_out(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_line_out snd_ctl_boolean_mono_info
static int snd_hdspm_get_line_out(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1897,15 +1938,7 @@ static int hdspm_set_tx_64(struct hdspm * hdspm, int out)
return 0;
}
-static int snd_hdspm_info_tx_64(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_tx_64 snd_ctl_boolean_mono_info
static int snd_hdspm_get_tx_64(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1960,15 +1993,7 @@ static int hdspm_set_c_tms(struct hdspm * hdspm, int out)
return 0;
}
-static int snd_hdspm_info_c_tms(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_c_tms snd_ctl_boolean_mono_info
static int snd_hdspm_get_c_tms(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2023,15 +2048,7 @@ static int hdspm_set_safe_mode(struct hdspm * hdspm, int out)
return 0;
}
-static int snd_hdspm_info_safe_mode(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_safe_mode snd_ctl_boolean_mono_info
static int snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2086,15 +2103,7 @@ static int hdspm_set_emphasis(struct hdspm * hdspm, int emp)
return 0;
}
-static int snd_hdspm_info_emphasis(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_emphasis snd_ctl_boolean_mono_info
static int snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2149,15 +2158,7 @@ static int hdspm_set_dolby(struct hdspm * hdspm, int dol)
return 0;
}
-static int snd_hdspm_info_dolby(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_dolby snd_ctl_boolean_mono_info
static int snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2212,15 +2213,7 @@ static int hdspm_set_professional(struct hdspm * hdspm, int dol)
return 0;
}
-static int snd_hdspm_info_professional(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdspm_info_professional snd_ctl_boolean_mono_info
static int snd_hdspm_get_professional(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2472,7 +2465,7 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
if (val > 2)
val = 2;
spin_lock_irq(&hdspm->lock);
- change = (int) val != hdspm_qs_wire(hdspm);
+ change = val != hdspm_qs_wire(hdspm);
hdspm_set_qs_wire(hdspm, val);
spin_unlock_irq(&hdspm->lock);
return change;
@@ -2573,8 +2566,8 @@ static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
source -
HDSPM_MAX_CHANNELS);
else
- change =
- gain != hdspm_read_in_gain(hdspm, destination, source);
+ change = gain != hdspm_read_in_gain(hdspm, destination,
+ source);
if (change) {
if (source >= HDSPM_MAX_CHANNELS)
@@ -2627,7 +2620,8 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
snd_assert(channel >= 0
|| channel < HDSPM_MAX_CHANNELS, return -EINVAL);
- if ((mapped_channel = hdspm->channel_map[channel]) < 0)
+ mapped_channel = hdspm->channel_map[channel];
+ if (mapped_channel < 0)
return -EINVAL;
spin_lock_irq(&hdspm->lock);
@@ -2635,10 +2629,12 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel);
spin_unlock_irq(&hdspm->lock);
- /* snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, value %d\n",
- ucontrol->id.index, channel, mapped_channel, ucontrol->value.integer.value[0]);
- */
-
+ /*
+ snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, "
+ "value %d\n",
+ ucontrol->id.index, channel, mapped_channel,
+ ucontrol->value.integer.value[0]);
+ */
return 0;
}
@@ -2659,7 +2655,8 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
snd_assert(channel >= 0
|| channel < HDSPM_MAX_CHANNELS, return -EINVAL);
- if ((mapped_channel = hdspm->channel_map[channel]) < 0)
+ mapped_channel = hdspm->channel_map[channel];
+ if (mapped_channel < 0)
return -EINVAL;
gain = ucontrol->value.integer.value[0];
@@ -2909,28 +2906,26 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
}
/* Channel playback mixer as default control
-Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer
-they are accesible via special IOCTL on hwdep
-and the mixer 2dimensional mixer control */
+ Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders,
+ thats too * big for any alsamixer they are accesible via special
+ IOCTL on hwdep and the mixer 2dimensional mixer control
+ */
snd_hdspm_playback_mixer.name = "Chn";
limit = HDSPM_MAX_CHANNELS;
- /* The index values are one greater than the channel ID so that alsamixer
- will display them correctly. We want to use the index for fast lookup
- of the relevant channel, but if we use it at all, most ALSA software
- does the wrong thing with it ...
+ /* The index values are one greater than the channel ID so that
+ * alsamixer will display them correctly. We want to use the index
+ * for fast lookup of the relevant channel, but if we use it at all,
+ * most ALSA software does the wrong thing with it ...
*/
for (idx = 0; idx < limit; ++idx) {
snd_hdspm_playback_mixer.index = idx + 1;
- if ((err = snd_ctl_add(card,
- kctl =
- snd_ctl_new1
- (&snd_hdspm_playback_mixer,
- hdspm)))) {
+ kctl = snd_ctl_new1(&snd_hdspm_playback_mixer, hdspm);
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
- }
hdspm->playback_mixer_ctls[idx] = kctl;
}
@@ -2945,7 +2940,7 @@ static void
snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
struct snd_info_buffer *buffer)
{
- struct hdspm *hdspm = (struct hdspm *) entry->private_data;
+ struct hdspm *hdspm = entry->private_data;
unsigned int status;
unsigned int status2;
char *pref_sync_ref;
@@ -2978,14 +2973,14 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
(status & HDSPM_midi1IRQPending) ? 1 : 0,
hdspm->irq_count);
snd_iprintf(buffer,
- "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n",
+ "HW pointer: id = %d, rawptr = %d (%d->%d) "
+ "estimated= %ld (bytes)\n",
((status & HDSPM_BufferID) ? 1 : 0),
(status & HDSPM_BufferPositionMask),
- (status & HDSPM_BufferPositionMask) % (2 *
- (int)hdspm->
- period_bytes),
- ((status & HDSPM_BufferPositionMask) -
- 64) % (2 * (int)hdspm->period_bytes),
+ (status & HDSPM_BufferPositionMask) %
+ (2 * (int)hdspm->period_bytes),
+ ((status & HDSPM_BufferPositionMask) - 64) %
+ (2 * (int)hdspm->period_bytes),
(long) hdspm_hw_pointer(hdspm) * 4);
snd_iprintf(buffer,
@@ -2995,24 +2990,22 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
snd_iprintf(buffer,
- "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x\n",
+ "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
+ "status2=0x%x\n",
hdspm->control_register, hdspm->control2_register,
status, status2);
snd_iprintf(buffer, "--- Settings ---\n");
- x = 1 << (6 +
- hdspm_decode_latency(hdspm->
- control_register &
- HDSPM_LatencyMask));
+ x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
+ HDSPM_LatencyMask));
snd_iprintf(buffer,
"Size (Latency): %d samples (2 periods of %lu bytes)\n",
x, (unsigned long) hdspm->period_bytes);
snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n",
- (hdspm->
- control_register & HDSPM_LineOut) ? "on " : "off",
+ (hdspm->control_register & HDSPM_LineOut) ? "on " : "off",
(hdspm->precise_ptr) ? "on" : "off");
switch (hdspm->control_register & HDSPM_InputMask) {
@@ -3040,7 +3033,8 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
syncref);
snd_iprintf(buffer,
- "ClearTrackMarker = %s, Transmit in %s Channel Mode, Auto Input %s\n",
+ "ClearTrackMarker = %s, Transmit in %s Channel Mode, "
+ "Auto Input %s\n",
(hdspm->
control_register & HDSPM_clr_tms) ? "on" : "off",
(hdspm->
@@ -3141,7 +3135,7 @@ static void
snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
struct snd_info_buffer *buffer)
{
- struct hdspm *hdspm = (struct hdspm *) entry->private_data;
+ struct hdspm *hdspm = entry->private_data;
unsigned int status;
unsigned int status2;
unsigned int timecode;
@@ -3171,14 +3165,14 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
(status & HDSPM_midi1IRQPending) ? 1 : 0,
hdspm->irq_count);
snd_iprintf(buffer,
- "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n",
+ "HW pointer: id = %d, rawptr = %d (%d->%d) "
+ "estimated= %ld (bytes)\n",
((status & HDSPM_BufferID) ? 1 : 0),
(status & HDSPM_BufferPositionMask),
- (status & HDSPM_BufferPositionMask) % (2 *
- (int)hdspm->
- period_bytes),
- ((status & HDSPM_BufferPositionMask) -
- 64) % (2 * (int)hdspm->period_bytes),
+ (status & HDSPM_BufferPositionMask) %
+ (2 * (int)hdspm->period_bytes),
+ ((status & HDSPM_BufferPositionMask) - 64) %
+ (2 * (int)hdspm->period_bytes),
(long) hdspm_hw_pointer(hdspm) * 4);
snd_iprintf(buffer,
@@ -3188,16 +3182,15 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
snd_iprintf(buffer,
- "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
+ "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, "
+ "timecode=0x%x\n",
hdspm->control_register,
status, status2, timecode);
snd_iprintf(buffer, "--- Settings ---\n");
- x = 1 << (6 +
- hdspm_decode_latency(hdspm->
- control_register &
- HDSPM_LatencyMask));
+ x = 1 << (6 + hdspm_decode_latency(hdspm->control_register &
+ HDSPM_LatencyMask));
snd_iprintf(buffer,
"Size (Latency): %d samples (2 periods of %lu bytes)\n",
@@ -3280,14 +3273,15 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
snd_iprintf(buffer, "--- Status:\n");
snd_iprintf(buffer, "Word: %s Frequency: %d\n",
- (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock",
- HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
+ (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock",
+ HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
for (x = 0; x < 8; x++) {
snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
- x+1,
- (status2 & (HDSPM_LockAES >> x))? "Sync ": "No Lock",
- HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
+ x+1,
+ (status2 & (HDSPM_LockAES >> x)) ?
+ "Sync ": "No Lock",
+ HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
}
switch (hdspm_autosync_ref(hdspm)) {
@@ -3313,12 +3307,11 @@ static void
snd_hdspm_proc_read_debug(struct snd_info_entry * entry,
struct snd_info_buffer *buffer)
{
- struct hdspm *hdspm = (struct hdspm *)entry->private_data;
+ struct hdspm *hdspm = entry->private_data;
int j,i;
- for (i = 0; i < 256 /* 1024*64 */; i += j)
- {
+ for (i = 0; i < 256 /* 1024*64 */; i += j) {
snd_iprintf(buffer, "0x%08X: ", i);
for (j = 0; j < 16; j += 4)
snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j));
@@ -3361,14 +3354,20 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
/* set defaults: */
if (hdspm->is_aes32)
- hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
- hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
+ hdspm->control_register =
+ HDSPM_ClockModeMaster | /* Master Cloack Mode on */
+ hdspm_encode_latency(7) | /* latency maximum =
+ * 8192 samples
+ */
HDSPM_SyncRef0 | /* AES1 is syncclock */
HDSPM_LineOut | /* Analog output in */
HDSPM_Professional; /* Professional mode */
else
- hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
- hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
+ hdspm->control_register =
+ HDSPM_ClockModeMaster | /* Master Cloack Mode on */
+ hdspm_encode_latency(7) | /* latency maximum =
+ * 8192 samples
+ */
HDSPM_InputCoaxial | /* Input Coax not Optical */
HDSPM_SyncRef_MADI | /* Madi is syncclock */
HDSPM_LineOut | /* Analog output in */
@@ -3399,7 +3398,8 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
if (line_outs_monitor[hdspm->dev]) {
- snd_printk(KERN_INFO "HDSPM: sending all playback streams to line outs.\n");
+ snd_printk(KERN_INFO "HDSPM: "
+ "sending all playback streams to line outs.\n");
for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) {
if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN))
@@ -3448,20 +3448,16 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
if (audio) {
if (hdspm->capture_substream)
- snd_pcm_period_elapsed(hdspm->pcm->
- streams
- [SNDRV_PCM_STREAM_CAPTURE].
- substream);
+ snd_pcm_period_elapsed(hdspm->capture_substream);
if (hdspm->playback_substream)
- snd_pcm_period_elapsed(hdspm->pcm->
- streams
- [SNDRV_PCM_STREAM_PLAYBACK].
- substream);
+ snd_pcm_period_elapsed(hdspm->playback_substream);
}
if (midi0 && midi0status) {
- /* we disable interrupts for this input until processing is done */
+ /* we disable interrupts for this input until processing
+ * is done
+ */
hdspm->control_register &= ~HDSPM_Midi0InterruptEnable;
hdspm_write(hdspm, HDSPM_controlRegister,
hdspm->control_register);
@@ -3469,7 +3465,9 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
schedule = 1;
}
if (midi1 && midi1status) {
- /* we disable interrupts for this input until processing is done */
+ /* we disable interrupts for this input until processing
+ * is done
+ */
hdspm->control_register &= ~HDSPM_Midi1InterruptEnable;
hdspm_write(hdspm, HDSPM_controlRegister,
hdspm->control_register);
@@ -3501,16 +3499,16 @@ static char *hdspm_channel_buffer_location(struct hdspm * hdspm,
snd_assert(channel >= 0
|| channel < HDSPM_MAX_CHANNELS, return NULL);
- if ((mapped_channel = hdspm->channel_map[channel]) < 0)
+ mapped_channel = hdspm->channel_map[channel];
+ if (mapped_channel < 0)
return NULL;
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (stream == SNDRV_PCM_STREAM_CAPTURE)
return hdspm->capture_buffer +
mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
- } else {
+ else
return hdspm->playback_buffer +
mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
- }
}
@@ -3525,9 +3523,9 @@ static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream,
snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
return -EINVAL);
- channel_buf = hdspm_channel_buffer_location(hdspm,
- substream->pstr->
- stream, channel);
+ channel_buf =
+ hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
+ channel);
snd_assert(channel_buf != NULL, return -EIO);
@@ -3544,9 +3542,9 @@ static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream,
snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
return -EINVAL);
- channel_buf = hdspm_channel_buffer_location(hdspm,
- substream->pstr->
- stream, channel);
+ channel_buf =
+ hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
+ channel);
snd_assert(channel_buf != NULL, return -EIO);
return copy_to_user(dst, channel_buf + pos * 4, count * 4);
}
@@ -3559,8 +3557,8 @@ static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream,
char *channel_buf;
channel_buf =
- hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
- channel);
+ hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
+ channel);
snd_assert(channel_buf != NULL, return -EIO);
memset(channel_buf + pos * 4, 0, count * 4);
return 0;
@@ -3616,7 +3614,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
other_pid = hdspm->playback_pid;
}
- if ((other_pid > 0) && (this_pid != other_pid)) {
+ if (other_pid > 0 && this_pid != other_pid) {
/* The other stream is open, and not by the same
task as this one. Make sure that the parameters
@@ -3633,7 +3631,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
if (params_period_size(params) != hdspm->period_bytes / 4) {
spin_unlock_irq(&hdspm->lock);
_snd_pcm_hw_param_setempty(params,
- SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
return -EBUSY;
}
@@ -3644,7 +3642,8 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
/* how to make sure that the rate matches an externally-set one ? */
spin_lock_irq(&hdspm->lock);
- if ((err = hdspm_set_rate(hdspm, params_rate(params), 0)) < 0) {
+ err = hdspm_set_rate(hdspm, params_rate(params), 0);
+ if (err < 0) {
spin_unlock_irq(&hdspm->lock);
_snd_pcm_hw_param_setempty(params,
SNDRV_PCM_HW_PARAM_RATE);
@@ -3652,16 +3651,17 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
}
spin_unlock_irq(&hdspm->lock);
- if ((err =
- hdspm_set_interrupt_interval(hdspm,
- params_period_size(params))) <
- 0) {
+ err = hdspm_set_interrupt_interval(hdspm,
+ params_period_size(params));
+ if (err < 0) {
_snd_pcm_hw_param_setempty(params,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
return err;
}
- /* Memory allocation, takashi's method, dont know if we should spinlock */
+ /* Memory allocation, takashi's method, dont know if we should
+ * spinlock
+ */
/* malloc all buffer even if not enabled to get sure */
/* Update for MADI rev 204: we need to allocate for all channels,
* otherwise it doesn't work at 96kHz */
@@ -3746,7 +3746,8 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL);
- if ((mapped_channel = hdspm->channel_map[info->channel]) < 0)
+ mapped_channel = hdspm->channel_map[info->channel];
+ if (mapped_channel < 0)
return -EINVAL;
info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
@@ -3760,15 +3761,13 @@ static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
{
switch (cmd) {
case SNDRV_PCM_IOCTL1_RESET:
- {
- return snd_hdspm_reset(substream);
- }
+ return snd_hdspm_reset(substream);
case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
- {
- struct snd_pcm_channel_info *info = arg;
- return snd_hdspm_channel_info(substream, info);
- }
+ {
+ struct snd_pcm_channel_info *info = arg;
+ return snd_hdspm_channel_info(substream, info);
+ }
default:
break;
}
@@ -3979,9 +3978,12 @@ static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params,
}
-static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
+static unsigned int hdspm_aes32_sample_rates[] = {
+ 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000
+};
-static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = {
+static struct snd_pcm_hw_constraint_list
+hdspm_hw_constraints_aes32_sample_rates = {
.count = ARRAY_SIZE(hdspm_aes32_sample_rates),
.list = hdspm_aes32_sample_rates,
.mask = 0
@@ -4107,7 +4109,7 @@ static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep * hw, struct file *file)
static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct hdspm *hdspm = (struct hdspm *) hw->private_data;
+ struct hdspm *hdspm = hw->private_data;
struct hdspm_mixer_ioctl mixer;
struct hdspm_config_info info;
struct hdspm_version hdspm_version;
@@ -4115,11 +4117,12 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
switch (cmd) {
-
case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
if (copy_from_user(&rms, (void __user *)arg, sizeof(rms)))
return -EFAULT;
- /* maybe there is a chance to memorymap in future so dont touch just copy */
+ /* maybe there is a chance to memorymap in future
+ * so dont touch just copy
+ */
if(copy_to_user_fromio((void __user *)rms.peak,
hdspm->iobase+HDSPM_MADI_peakrmsbase,
sizeof(struct hdspm_peak_rms)) != 0 )
@@ -4131,21 +4134,16 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO:
spin_lock_irq(&hdspm->lock);
- info.pref_sync_ref =
- (unsigned char) hdspm_pref_sync_ref(hdspm);
- info.wordclock_sync_check =
- (unsigned char) hdspm_wc_sync_check(hdspm);
+ info.pref_sync_ref = hdspm_pref_sync_ref(hdspm);
+ info.wordclock_sync_check = hdspm_wc_sync_check(hdspm);
info.system_sample_rate = hdspm->system_sample_rate;
info.autosync_sample_rate =
hdspm_external_sample_rate(hdspm);
- info.system_clock_mode =
- (unsigned char) hdspm_system_clock_mode(hdspm);
- info.clock_source =
- (unsigned char) hdspm_clock_source(hdspm);
- info.autosync_ref =
- (unsigned char) hdspm_autosync_ref(hdspm);
- info.line_out = (unsigned char) hdspm_line_out(hdspm);
+ info.system_clock_mode = hdspm_system_clock_mode(hdspm);
+ info.clock_source = hdspm_clock_source(hdspm);
+ info.autosync_ref = hdspm_autosync_ref(hdspm);
+ info.line_out = hdspm_line_out(hdspm);
info.passthru = 0;
spin_unlock_irq(&hdspm->lock);
if (copy_to_user((void __user *) arg, &info, sizeof(info)))
@@ -4162,8 +4160,8 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
case SNDRV_HDSPM_IOCTL_GET_MIXER:
if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
return -EFAULT;
- if (copy_to_user
- ((void __user *)mixer.mixer, hdspm->mixer, sizeof(struct hdspm_mixer)))
+ if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
+ sizeof(struct hdspm_mixer)))
return -EFAULT;
break;
@@ -4206,7 +4204,8 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
struct snd_hwdep *hw;
int err;
- if ((err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw)) < 0)
+ err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw);
+ if (err < 0)
return err;
hdspm->hwdep = hw;
@@ -4232,15 +4231,15 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
pcm = hdspm->pcm;
-/* wanted = HDSPM_DMA_AREA_BYTES + 4096;*/ /* dont know why, but it works */
wanted = HDSPM_DMA_AREA_BYTES;
- if ((err =
+ err =
snd_pcm_lib_preallocate_pages_for_all(pcm,
SNDRV_DMA_TYPE_DEV_SG,
snd_dma_pci_data(hdspm->pci),
wanted,
- wanted)) < 0) {
+ wanted);
+ if (err < 0) {
snd_printdd("Could not preallocate %zd Bytes\n", wanted);
return err;
@@ -4256,8 +4255,7 @@ static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
int i;
for (i = 0; i < (channels * 16); i++)
hdspm_write(hdspm, reg + 4 * i,
- snd_pcm_sgbuf_get_addr(sgbuf,
- (size_t) 4096 * i));
+ snd_pcm_sgbuf_get_addr(sgbuf, (size_t) 4096 * i));
}
/* ------------- ALSA Devices ---------------------------- */
@@ -4267,7 +4265,8 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm);
+ if (err < 0)
return err;
hdspm->pcm = pcm;
@@ -4281,7 +4280,8 @@ static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
- if ((err = snd_hdspm_preallocate_memory(hdspm)) < 0)
+ err = snd_hdspm_preallocate_memory(hdspm);
+ if (err < 0)
return err;
return 0;
@@ -4299,19 +4299,24 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
int err;
snd_printdd("Create card...\n");
- if ((err = snd_hdspm_create_pcm(card, hdspm)) < 0)
+ err = snd_hdspm_create_pcm(card, hdspm);
+ if (err < 0)
return err;
- if ((err = snd_hdspm_create_midi(card, hdspm, 0)) < 0)
+ err = snd_hdspm_create_midi(card, hdspm, 0);
+ if (err < 0)
return err;
- if ((err = snd_hdspm_create_midi(card, hdspm, 1)) < 0)
+ err = snd_hdspm_create_midi(card, hdspm, 1);
+ if (err < 0)
return err;
- if ((err = snd_hdspm_create_controls(card, hdspm)) < 0)
+ err = snd_hdspm_create_controls(card, hdspm);
+ if (err < 0)
return err;
- if ((err = snd_hdspm_create_hwdep(card, hdspm)) < 0)
+ err = snd_hdspm_create_hwdep(card, hdspm);
+ if (err < 0)
return err;
snd_printdd("proc init...\n");
@@ -4326,7 +4331,8 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
hdspm->playback_substream = NULL;
snd_printdd("Set defaults...\n");
- if ((err = snd_hdspm_set_defaults(hdspm)) < 0)
+ err = snd_hdspm_set_defaults(hdspm);
+ if (err < 0)
return err;
snd_printdd("Update mixer controls...\n");
@@ -4334,7 +4340,8 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
snd_printdd("Initializeing complete ???\n");
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_printk(KERN_ERR "HDSPM: error registering card\n");
return err;
}
@@ -4344,36 +4351,18 @@ static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
return 0;
}
-static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdspm,
+static int __devinit snd_hdspm_create(struct snd_card *card,
+ struct hdspm *hdspm,
int precise_ptr, int enable_monitor)
{
struct pci_dev *pci = hdspm->pci;
int err;
- int i;
-
unsigned long io_extent;
hdspm->irq = -1;
- hdspm->irq_count = 0;
-
- hdspm->midi[0].rmidi = NULL;
- hdspm->midi[1].rmidi = NULL;
- hdspm->midi[0].input = NULL;
- hdspm->midi[1].input = NULL;
- hdspm->midi[0].output = NULL;
- hdspm->midi[1].output = NULL;
+
spin_lock_init(&hdspm->midi[0].lock);
spin_lock_init(&hdspm->midi[1].lock);
- hdspm->iobase = NULL;
- hdspm->control_register = 0;
- hdspm->control2_register = 0;
-
- hdspm->playback_buffer = NULL;
- hdspm->capture_buffer = NULL;
-
- for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
- hdspm->playback_mixer_ctls[i] = NULL;
- hdspm->mixer = NULL;
hdspm->card = card;
@@ -4396,12 +4385,14 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
hdspm->card_name = "RME HDSPM MADI";
}
- if ((err = pci_enable_device(pci)) < 0)
+ err = pci_enable_device(pci);
+ if (err < 0)
return err;
pci_set_master(hdspm->pci);
- if ((err = pci_request_regions(pci, "hdspm")) < 0)
+ err = pci_request_regions(pci, "hdspm");
+ if (err < 0)
return err;
hdspm->port = pci_resource_start(pci, 0);
@@ -4411,8 +4402,10 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
hdspm->port, hdspm->port + io_extent - 1);
- if ((hdspm->iobase = ioremap_nocache(hdspm->port, io_extent)) == NULL) {
- snd_printk(KERN_ERR "HDSPM: unable to remap region 0x%lx-0x%lx\n",
+ hdspm->iobase = ioremap_nocache(hdspm->port, io_extent);
+ if (!hdspm->iobase) {
+ snd_printk(KERN_ERR "HDSPM: "
+ "unable to remap region 0x%lx-0x%lx\n",
hdspm->port, hdspm->port + io_extent - 1);
return -EBUSY;
}
@@ -4435,9 +4428,10 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
snd_printdd("kmalloc Mixer memory of %zd Bytes\n",
sizeof(struct hdspm_mixer));
- if ((hdspm->mixer = kmalloc(sizeof(struct hdspm_mixer), GFP_KERNEL))
- == NULL) {
- snd_printk(KERN_ERR "HDSPM: unable to kmalloc Mixer memory of %d Bytes\n",
+ hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL);
+ if (!hdspm->mixer) {
+ snd_printk(KERN_ERR "HDSPM: "
+ "unable to kmalloc Mixer memory of %d Bytes\n",
(int)sizeof(struct hdspm_mixer));
return err;
}
@@ -4447,7 +4441,8 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
hdspm->qs_channels = MADI_QS_CHANNELS;
snd_printdd("create alsa devices.\n");
- if ((err = snd_hdspm_create_alsa_devices(card, hdspm)) < 0)
+ err = snd_hdspm_create_alsa_devices(card, hdspm);
+ if (err < 0)
return err;
snd_hdspm_initialize_midi_flush(hdspm);
@@ -4462,9 +4457,8 @@ static int snd_hdspm_free(struct hdspm * hdspm)
/* stop th audio, and cancel all interrupts */
hdspm->control_register &=
- ~(HDSPM_Start | HDSPM_AudioInterruptEnable
- | HDSPM_Midi0InterruptEnable |
- HDSPM_Midi1InterruptEnable);
+ ~(HDSPM_Start | HDSPM_AudioInterruptEnable |
+ HDSPM_Midi0InterruptEnable | HDSPM_Midi1InterruptEnable);
hdspm_write(hdspm, HDSPM_controlRegister,
hdspm->control_register);
}
@@ -4472,7 +4466,6 @@ static int snd_hdspm_free(struct hdspm * hdspm)
if (hdspm->irq >= 0)
free_irq(hdspm->irq, (void *) hdspm);
-
kfree(hdspm->mixer);
if (hdspm->iobase)
@@ -4487,7 +4480,7 @@ static int snd_hdspm_free(struct hdspm * hdspm)
static void snd_hdspm_card_free(struct snd_card *card)
{
- struct hdspm *hdspm = (struct hdspm *) card->private_data;
+ struct hdspm *hdspm = card->private_data;
if (hdspm)
snd_hdspm_free(hdspm);
@@ -4508,20 +4501,21 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci,
return -ENOENT;
}
- if (!(card = snd_card_new(index[dev], id[dev],
- THIS_MODULE, sizeof(struct hdspm))))
+ card = snd_card_new(index[dev], id[dev],
+ THIS_MODULE, sizeof(struct hdspm));
+ if (!card)
return -ENOMEM;
- hdspm = (struct hdspm *) card->private_data;
+ hdspm = card->private_data;
card->private_free = snd_hdspm_card_free;
hdspm->dev = dev;
hdspm->pci = pci;
snd_card_set_dev(card, &pci->dev);
- if ((err =
- snd_hdspm_create(card, hdspm, precise_ptr[dev],
- enable_monitor[dev])) < 0) {
+ err = snd_hdspm_create(card, hdspm, precise_ptr[dev],
+ enable_monitor[dev]);
+ if (err < 0) {
snd_card_free(card);
return err;
}
@@ -4530,7 +4524,8 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci,
sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name,
hdspm->port, hdspm->irq);
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err < 0) {
snd_card_free(card);
return err;
}
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 2de27405a0b..34f96f12e5b 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -1067,14 +1067,7 @@ static int rme9652_set_spdif_output(struct snd_rme9652 *rme9652, int out)
return 0;
}
-static int snd_rme9652_info_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_rme9652_info_spdif_out snd_ctl_boolean_mono_info
static int snd_rme9652_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1338,14 +1331,7 @@ static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_el
.put = snd_rme9652_put_passthru, \
.get = snd_rme9652_get_passthru }
-static int snd_rme9652_info_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_rme9652_info_passthru snd_ctl_boolean_mono_info
static int snd_rme9652_get_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1445,14 +1431,7 @@ static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_c
.info = snd_rme9652_info_tc_valid, \
.get = snd_rme9652_get_tc_valid }
-static int snd_rme9652_info_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_rme9652_info_tc_valid snd_ctl_boolean_mono_info
static int snd_rme9652_get_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 9f25d93cbec..44a7f5fad57 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1,6 +1,6 @@
/*
* Driver for S3 SonicVibes soundcard
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
* BUGS:
* It looks like 86c617 rev 3 doesn't supports DDMA buffers above 16MB?
@@ -42,7 +42,7 @@
#include <asm/io.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("S3 SonicVibes PCI");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}");
diff --git a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile
index 65bc5b70323..65f2c218324 100644
--- a/sound/pci/trident/Makefile
+++ b/sound/pci/trident/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-trident-objs := trident.o trident_main.o trident_memory.o
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 9145f7c57fb..84884567df6 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -30,7 +30,7 @@
#include <sound/trident.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, <audio@tridentmicro.com>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
MODULE_DESCRIPTION("Trident 4D-WaveDX/NX & SiS SI7018");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX},"
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 7ca60627246..a235e034a69 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1,5 +1,5 @@
/*
- * Maintained by Jaroslav Kysela <perex@suse.cz>
+ * Maintained by Jaroslav Kysela <perex@perex.cz>
* Originated by audio@tridentmicro.com
* Fri Feb 19 15:55:28 MST 1999
* Routines for control of Trident 4DWave (DX and NX) chip
@@ -2317,15 +2317,7 @@ int __devinit snd_trident_spdif_pcm(struct snd_trident * trident,
Description: enable/disable S/PDIF out from ac97 mixer
---------------------------------------------------------------------------*/
-static int snd_trident_spdif_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_trident_spdif_control_info snd_ctl_boolean_mono_info
static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2545,15 +2537,7 @@ static struct snd_kcontrol_new snd_trident_spdif_stream __devinitdata =
Description: enable/disable rear path for ac97
---------------------------------------------------------------------------*/
-static int snd_trident_ac97_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_trident_ac97_control_info snd_ctl_boolean_mono_info
static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index aff3f874131..847b8c6d5c0 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
* Copyright (c) by Scott McNab <sdm@fractalgraphics.com.au>
*
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 6ea09df0c73..cf62d2ab8d7 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -3,7 +3,7 @@
*
* VT82C686A/B/C, VT8233A/C, VT8235
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
* Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
* 2002 Takashi Iwai <tiwai@suse.de>
*
@@ -68,7 +68,7 @@
#define POINTER_DEBUG
#endif
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("VIA VT82xx audio");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}");
@@ -1572,15 +1572,7 @@ static struct snd_kcontrol_new snd_via8233_capture_source __devinitdata = {
.put = snd_via8233_capture_source_put,
};
-static int snd_via8233_dxs3_spdif_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_via8233_dxs3_spdif_info snd_ctl_boolean_mono_info
static int snd_via8233_dxs3_spdif_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -2098,7 +2090,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break;
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
@@ -2117,7 +2109,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */
@@ -2371,6 +2363,7 @@ static struct snd_pci_quirk dxs_whitelist[] __devinitdata = {
SND_PCI_QUIRK(0x1071, 0, "Diverse Notebook", VIA_DXS_NO_VRA),
SND_PCI_QUIRK(0x10cf, 0x118e, "FSC Laptop", VIA_DXS_ENABLE),
SND_PCI_QUIRK(0x1106, 0, "ASRock", VIA_DXS_SRC),
+ SND_PCI_QUIRK(0x1297, 0xa231, "Shuttle AK31v2", VIA_DXS_SRC),
SND_PCI_QUIRK(0x1297, 0xa232, "Shuttle", VIA_DXS_ENABLE),
SND_PCI_QUIRK(0x1297, 0xc160, "Shuttle Sk41G", VIA_DXS_ENABLE),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte GA-7VAXP", VIA_DXS_ENABLE),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 72425e73aba..57fb9ae22f9 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -3,7 +3,7 @@
*
* VT82C686A/B/C, VT8233A/C, VT8235
*
- * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
* Tjeerd.Mulder <Tjeerd.Mulder@fujitsu-siemens.com>
* 2002 Takashi Iwai <tiwai@suse.de>
*
@@ -50,7 +50,7 @@
#define POINTER_DEBUG
#endif
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("VIA VT82xx modem");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
@@ -983,7 +983,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
break;
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
@@ -1001,7 +1001,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
chip->ac97_secondary = 1;
goto __ac97_ok2;
}
- schedule_timeout(1);
+ schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
/* This is ok, the most of motherboards have only one codec */
diff --git a/sound/pci/vx222/Makefile b/sound/pci/vx222/Makefile
index 058c8bff7c1..a4d08d4de35 100644
--- a/sound/pci/vx222/Makefile
+++ b/sound/pci/vx222/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-vx222-objs := vx222.o vx222_ops.o
diff --git a/sound/pci/ymfpci/Makefile b/sound/pci/ymfpci/Makefile
index 8790c5f3ed0..bd3d514ed76 100644
--- a/sound/pci/ymfpci/Makefile
+++ b/sound/pci/ymfpci/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-ymfpci-objs := ymfpci.o ymfpci_main.o
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index fd9b7b83a88..5c4256a4d4b 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -1,6 +1,6 @@
/*
* The driver for the Yamaha's DS1/DS1E cards
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -30,7 +30,7 @@
#include <sound/opl3.h>
#include <sound/initval.h>
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Yamaha DS-1 PCI");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724},"
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index ab7a81c3570..1fe39ed2876 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
* Routines for control of YMF724/740/744/754 chips
*
* This program is free software; you can redistribute it and/or modify
@@ -84,7 +84,6 @@ static int snd_ymfpci_codec_ready(struct snd_ymfpci *chip, int secondary)
do {
if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
return 0;
- set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout_uninterruptible(1);
} while (time_before(jiffies, end_time));
snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
@@ -171,17 +170,6 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate)
return val[0];
}
-static void snd_ymfpci_pcm_441_volume_set(struct snd_ymfpci_pcm *ypcm)
-{
- unsigned int value;
- struct snd_ymfpci_pcm_mixer *mixer;
-
- mixer = &ypcm->chip->pcm_mixer[ypcm->substream->number];
- value = min_t(unsigned int, mixer->left, 0x7fff) >> 1;
- value |= (min_t(unsigned int, mixer->right, 0x7fff) >> 1) << 16;
- snd_ymfpci_writel(ypcm->chip, YDSXGR_BUF441OUTVOL, value);
-}
-
/*
* Hardware start management
*/
@@ -389,6 +377,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
{
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
+ struct snd_kcontrol *kctl = NULL;
int result = 0;
spin_lock(&chip->reg_lock);
@@ -406,6 +395,11 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
ypcm->running = 1;
break;
case SNDRV_PCM_TRIGGER_STOP:
+ if (substream->pcm == chip->pcm && !ypcm->use_441_slot) {
+ kctl = chip->pcm_mixer[substream->number].ctl;
+ kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ }
+ /* fall through */
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
@@ -419,6 +413,8 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
}
__unlock:
spin_unlock(&chip->reg_lock);
+ if (kctl)
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
return result;
}
static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream,
@@ -526,7 +522,6 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
ypcm->chip->src441_used = voice->number;
ypcm->use_441_slot = 1;
format |= 0x10000000;
- snd_ymfpci_pcm_441_volume_set(ypcm);
}
if (ypcm->chip->src441_used == voice->number &&
(format & 0x10000000) == 0) {
@@ -667,6 +662,7 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream)
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ymfpci_pcm *ypcm = runtime->private_data;
+ struct snd_kcontrol *kctl;
unsigned int nvoice;
ypcm->period_size = runtime->period_size;
@@ -676,6 +672,12 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream)
for (nvoice = 0; nvoice < runtime->channels; nvoice++)
snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime,
substream->pcm == chip->pcm);
+
+ if (substream->pcm == chip->pcm && !ypcm->use_441_slot) {
+ kctl = chip->pcm_mixer[substream->number].ctl;
+ kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
+ }
return 0;
}
@@ -926,7 +928,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_ymfpci_pcm *ypcm;
- struct snd_kcontrol *kctl;
int err;
if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
@@ -941,10 +942,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
chip->rear_opened++;
}
spin_unlock_irq(&chip->reg_lock);
-
- kctl = chip->pcm_mixer[substream->number].ctl;
- kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
return 0;
}
@@ -1039,7 +1036,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
{
struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
- struct snd_kcontrol *kctl;
spin_lock_irq(&chip->reg_lock);
if (ypcm->output_rear && chip->rear_opened > 0) {
@@ -1047,9 +1043,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
ymfpci_close_extension(chip);
}
spin_unlock_irq(&chip->reg_lock);
- kctl = chip->pcm_mixer[substream->number].ctl;
- kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
return snd_ymfpci_playback_close_1(substream);
}
@@ -1443,22 +1436,7 @@ static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = {
.get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
.private_value = ((reg) | ((shift) << 16)) }
-static int snd_ymfpci_info_single(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- int reg = kcontrol->private_value & 0xffff;
-
- switch (reg) {
- case YDSXGR_SPDIFOUTCTRL: break;
- case YDSXGR_SPDIFINCTRL: break;
- default: return -EINVAL;
- }
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ymfpci_info_single snd_ctl_boolean_mono_info
static int snd_ymfpci_get_single(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1567,17 +1545,30 @@ static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
return change;
}
+static int snd_ymfpci_put_nativedacvol(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
+ unsigned int reg = YDSXGR_NATIVEDACOUTVOL;
+ unsigned int reg2 = YDSXGR_BUF441OUTVOL;
+ int change;
+ unsigned int value, oval;
+
+ value = ucontrol->value.integer.value[0] & 0x3fff;
+ value |= (ucontrol->value.integer.value[1] & 0x3fff) << 16;
+ spin_lock_irq(&chip->reg_lock);
+ oval = snd_ymfpci_readl(chip, reg);
+ change = value != oval;
+ snd_ymfpci_writel(chip, reg, value);
+ snd_ymfpci_writel(chip, reg2, value);
+ spin_unlock_irq(&chip->reg_lock);
+ return change;
+}
+
/*
* 4ch duplication
*/
-static int snd_ymfpci_info_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ymfpci_info_dup4ch snd_ctl_boolean_mono_info
static int snd_ymfpci_get_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1598,7 +1589,17 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e
static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = {
-YMFPCI_DOUBLE("Wave Playback Volume", 0, YDSXGR_NATIVEDACOUTVOL),
+{
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Wave Playback Volume",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ .info = snd_ymfpci_info_double,
+ .get = snd_ymfpci_get_double,
+ .put = snd_ymfpci_put_nativedacvol,
+ .private_value = YDSXGR_NATIVEDACOUTVOL,
+ .tlv = { .p = db_scale_native },
+},
YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL),
YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL),
YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL),
@@ -1665,14 +1666,7 @@ static int snd_ymfpci_set_gpio_out(struct snd_ymfpci *chip, int pin, int enable)
return 0;
}
-static int snd_ymfpci_gpio_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_ymfpci_gpio_sw_info snd_ctl_boolean_mono_info
static int snd_ymfpci_gpio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
@@ -1748,8 +1742,6 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
if (!ypcm->use_441_slot)
ypcm->update_pcm_vol = 2;
- else
- snd_ymfpci_pcm_441_volume_set(ypcm);
}
spin_unlock_irqrestore(&chip->voice_lock, flags);
return 1;
diff --git a/sound/pcmcia/Makefile b/sound/pcmcia/Makefile
index b6656d48bec..beef2e33b71 100644
--- a/sound/pcmcia/Makefile
+++ b/sound/pcmcia/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
obj-$(CONFIG_SND) += vx/ pdaudiocf/
diff --git a/sound/pcmcia/pdaudiocf/Makefile b/sound/pcmcia/pdaudiocf/Makefile
index 6e194f9b50e..e892d7299ab 100644
--- a/sound/pcmcia/pdaudiocf/Makefile
+++ b/sound/pcmcia/pdaudiocf/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2004 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2004 by Jaroslav Kysela <perex@perex.cz>
#
snd-pdaudiocf-objs := pdaudiocf.o pdaudiocf_core.o pdaudiocf_irq.o pdaudiocf_pcm.o
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 2d40cc72f23..de683b08fe0 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -1,7 +1,7 @@
/*
* Driver for Sound Core PDAudioCF soundcard
*
- * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
*
* 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
@@ -33,7 +33,7 @@
#define CARD_NAME "PDAudio-CF"
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Sound Core " CARD_NAME);
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Sound Core," CARD_NAME "}}");
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index 206e2f5a113..b0601838112 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -1,7 +1,7 @@
/*
* Driver for Sound Cors PDAudioCF soundcard
*
- * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 1dfe29b863d..484c8f9a6f1 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -1,7 +1,7 @@
/*
* Driver for Sound Core PDAudioCF soundcard
*
- * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
index 5bd69206ba6..54543369949 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
@@ -1,7 +1,7 @@
/*
* Driver for Sound Core PDAudioCF soundcard
*
- * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 7f2a4de1d35..10afcb262d5 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -3,7 +3,7 @@
*
* PCM part
*
- * Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
*
* 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/sound/pcmcia/vx/Makefile b/sound/pcmcia/vx/Makefile
index 54971f01e96..2bb42ea12f3 100644
--- a/sound/pcmcia/vx/Makefile
+++ b/sound/pcmcia/vx/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-vxpocket-objs := vxpocket.o vxp_ops.o vxp_mixer.o
diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c
index 2b1f996c898..1eff158b868 100644
--- a/sound/pcmcia/vx/vxp_mixer.c
+++ b/sound/pcmcia/vx/vxp_mixer.c
@@ -80,14 +80,7 @@ static struct snd_kcontrol_new vx_control_mic_level = {
/*
* mic boost level control (for VXP440)
*/
-static int vx_mic_boost_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define vx_mic_boost_info snd_ctl_boolean_mono_info
static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/ppc/Makefile b/sound/ppc/Makefile
index eacee2d0675..679c45a8da2 100644
--- a/sound/ppc/Makefile
+++ b/sound/ppc/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c
index 57202b0f033..c5a1f0be6a4 100644
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -91,15 +91,7 @@ static int daca_set_volume(struct pmac_daca *mix)
/* deemphasis switch */
-static int daca_info_deemphasis(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define daca_info_deemphasis snd_ctl_boolean_mono_info
static int daca_get_deemphasis(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 7a22f0f3784..4f9b19c90a4 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -490,35 +490,14 @@ static int snd_pmac_pcm_open(struct snd_pmac *chip, struct pmac_stream *rec,
struct snd_pcm_substream *subs)
{
struct snd_pcm_runtime *runtime = subs->runtime;
- int i, j, fflags;
- static int typical_freqs[] = {
- 44100,
- 22050,
- 11025,
- 0,
- };
- static int typical_freq_flags[] = {
- SNDRV_PCM_RATE_44100,
- SNDRV_PCM_RATE_22050,
- SNDRV_PCM_RATE_11025,
- 0,
- };
+ int i;
/* look up frequency table and fill bit mask */
runtime->hw.rates = 0;
- fflags = chip->freqs_ok;
- for (i = 0; typical_freqs[i]; i++) {
- for (j = 0; j < chip->num_freqs; j++) {
- if ((chip->freqs_ok & (1 << j)) &&
- chip->freq_table[j] == typical_freqs[i]) {
- runtime->hw.rates |= typical_freq_flags[i];
- fflags &= ~(1 << j);
- break;
- }
- }
- }
- if (fflags) /* rest */
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
+ for (i = 0; i < chip->num_freqs; i++)
+ if (chip->freqs_ok & (1 << i))
+ runtime->hw.rates |=
+ snd_pcm_rate_to_rate_bit(chip->freq_table[i]);
/* check for minimum and maximum rates */
for (i = 0; i < chip->num_freqs; i++) {
@@ -551,9 +530,6 @@ static int snd_pmac_pcm_open(struct snd_pmac *chip, struct pmac_stream *rec,
runtime->hw.periods_max = rec->cmd.size - 1;
- if (chip->can_duplex)
- snd_pcm_set_sync(subs);
-
/* constraints to fix choppy sound */
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
return 0;
@@ -1035,29 +1011,6 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
return 0;
}
-/*
- * exported - boolean info callbacks for ease of programming
- */
-int snd_pmac_boolean_stereo_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
-int snd_pmac_boolean_mono_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-
#ifdef PMAC_SUPPORT_AUTOMUTE
/*
* auto-mute
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index 8394e66ceb0..25c512c2d74 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -202,8 +202,8 @@ int snd_pmac_keywest_init(struct pmac_keywest *i2c);
void snd_pmac_keywest_cleanup(struct pmac_keywest *i2c);
/* misc */
-int snd_pmac_boolean_stereo_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_pmac_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+#define snd_pmac_boolean_stereo_info snd_ctl_boolean_stereo_info
+#define snd_pmac_boolean_mono_info snd_ctl_boolean_mono_info
int snd_pmac_add_automute(struct snd_pmac *chip);
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 1aa0b467599..27b61899fe8 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -33,7 +33,6 @@
#include <linux/dmapool.h>
#include <linux/dma-mapping.h>
#include <asm/firmware.h>
-#include <linux/io.h>
#include <asm/dma.h>
#include <asm/lv1call.h>
#include <asm/ps3.h>
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 739786529ca..131ec481228 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -451,15 +451,7 @@ static int __init snd_aicapcmchip(struct snd_card_aica
}
/* Mixer controls */
-static int aica_pcmswitch_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define aica_pcmswitch_info snd_ctl_boolean_mono_info
static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index e5fb437b86e..78248808a9d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -17,3 +17,23 @@ config SND_SOC_WM8753
config SND_SOC_WM9712
tristate
depends on SND_SOC
+
+# Cirrus Logic CS4270 Codec
+config SND_SOC_CS4270
+ tristate
+ depends on SND_SOC
+
+# Cirrus Logic CS4270 Codec Hardware Mute Support
+# Select if you have external muting circuitry attached to your CS4270.
+config SND_SOC_CS4270_HWMUTE
+ bool
+ depends on SND_SOC_CS4270
+
+# Cirrus Logic CS4270 Codec VD = 3.3V Errata
+# Select if you are affected by the errata where the part will not function
+# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
+# not select any sample rates that require MCLK to be divided by 1.5.
+config SND_SOC_CS4270_VD33_ERRATA
+ bool
+ depends on SND_SOC_CS4270
+
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index e39a747a17c..7ad78e36d50 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,9 +3,11 @@ snd-soc-wm8731-objs := wm8731.o
snd-soc-wm8750-objs := wm8750.o
snd-soc-wm8753-objs := wm8753.o
snd-soc-wm9712-objs := wm9712.o
+snd-soc-cs4270-objs := cs4270.o
obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
+obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
new file mode 100644
index 00000000000..5d601ad6da7
--- /dev/null
+++ b/sound/soc/codecs/cs4270.c
@@ -0,0 +1,805 @@
+/*
+ * CS4270 ALSA SoC (ASoC) codec driver
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * This is an ASoC device driver for the Cirrus Logic CS4270 codec.
+ *
+ * Current features/limitations:
+ *
+ * 1) Software mode is supported. Stand-alone mode is automatically
+ * selected if I2C is disabled or if a CS4270 is not found on the I2C
+ * bus. However, stand-alone mode is only partially implemented because
+ * there is no mechanism yet for this driver and the machine driver to
+ * communicate the values of the M0, M1, MCLK1, and MCLK2 pins.
+ * 2) Only I2C is supported, not SPI
+ * 3) Only Master mode is supported, not Slave.
+ * 4) The machine driver's 'startup' function must call
+ * cs4270_set_dai_sysclk() with the value of MCLK.
+ * 5) Only I2S and left-justified modes are supported
+ * 6) Power management is not supported
+ * 7) The only supported control is volume and hardware mute (if enabled)
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <linux/i2c.h>
+
+#include "cs4270.h"
+
+/* If I2C is defined, then we support software mode. However, if we're
+ not compiled as module but I2C is, then we can't use I2C calls. */
+#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
+#define USE_I2C
+#endif
+
+/* Private data for the CS4270 */
+struct cs4270_private {
+ unsigned int mclk; /* Input frequency of the MCLK pin */
+ unsigned int mode; /* The mode (I2S or left-justified) */
+};
+
+/* The number of MCLK/LRCK ratios supported by the CS4270 */
+#define NUM_MCLK_RATIOS 9
+
+/* The actual MCLK/LRCK ratios, in increasing numerical order */
+static unsigned int mclk_ratios[NUM_MCLK_RATIOS] =
+ {64, 96, 128, 192, 256, 384, 512, 768, 1024};
+
+/*
+ * Determine the CS4270 samples rates.
+ *
+ * 'freq' is the input frequency to MCLK. The other parameters are ignored.
+ *
+ * The value of MCLK is used to determine which sample rates are supported
+ * by the CS4270. The ratio of MCLK / Fs must be equal to one of nine
+ * support values: 64, 96, 128, 192, 256, 384, 512, 768, and 1024.
+ *
+ * This function calculates the nine ratios and determines which ones match
+ * a standard sample rate. If there's a match, then it is added to the list
+ * of support sample rates.
+ *
+ * This function must be called by the machine driver's 'startup' function,
+ * otherwise the list of supported sample rates will not be available in
+ * time for ALSA.
+ *
+ * Note that in stand-alone mode, the sample rate is determined by input
+ * pins M0, M1, MDIV1, and MDIV2. Also in stand-alone mode, divide-by-3
+ * is not a programmable option. However, divide-by-3 is not an available
+ * option in stand-alone mode. This cases two problems: a ratio of 768 is
+ * not available (it requires divide-by-3) and B) ratios 192 and 384 can
+ * only be selected with divide-by-1.5, but there is an errate that make
+ * this selection difficult.
+ *
+ * In addition, there is no mechanism for communicating with the machine
+ * driver what the input settings can be. This would need to be implemented
+ * for stand-alone mode to work.
+ */
+static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs4270_private *cs4270 = codec->private_data;
+ unsigned int rates = 0;
+ unsigned int rate_min = -1;
+ unsigned int rate_max = 0;
+ unsigned int i;
+
+ cs4270->mclk = freq;
+
+ for (i = 0; i < NUM_MCLK_RATIOS; i++) {
+ unsigned int rate = freq / mclk_ratios[i];
+ rates |= snd_pcm_rate_to_rate_bit(rate);
+ if (rate < rate_min)
+ rate_min = rate;
+ if (rate > rate_max)
+ rate_max = rate;
+ }
+ /* FIXME: soc should support a rate list */
+ rates &= ~SNDRV_PCM_RATE_KNOT;
+
+ if (!rates) {
+ printk(KERN_ERR "cs4270: could not find a valid sample rate\n");
+ return -EINVAL;
+ }
+
+ codec_dai->playback.rates = rates;
+ codec_dai->playback.rate_min = rate_min;
+ codec_dai->playback.rate_max = rate_max;
+
+ codec_dai->capture.rates = rates;
+ codec_dai->capture.rate_min = rate_min;
+ codec_dai->capture.rate_max = rate_max;
+
+ return 0;
+}
+
+/*
+ * Configure the codec for the selected audio format
+ *
+ * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the
+ * codec accordingly.
+ *
+ * Currently, this function only supports SND_SOC_DAIFMT_I2S and
+ * SND_SOC_DAIFMT_LEFT_J. The CS4270 codec also supports right-justified
+ * data for playback only, but ASoC currently does not support different
+ * formats for playback vs. record.
+ */
+static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+ unsigned int format)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs4270_private *cs4270 = codec->private_data;
+ int ret = 0;
+
+ switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ case SND_SOC_DAIFMT_LEFT_J:
+ cs4270->mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
+ break;
+ default:
+ printk(KERN_ERR "cs4270: invalid DAI format\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/*
+ * The codec isn't really big-endian or little-endian, since the I2S
+ * interface requires data to be sent serially with the MSbit first.
+ * However, to support BE and LE I2S devices, we specify both here. That
+ * way, ALSA will always match the bit patterns.
+ */
+#define CS4270_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
+ SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
+ SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
+
+#ifdef USE_I2C
+
+/* CS4270 registers addresses */
+#define CS4270_CHIPID 0x01 /* Chip ID */
+#define CS4270_PWRCTL 0x02 /* Power Control */
+#define CS4270_MODE 0x03 /* Mode Control */
+#define CS4270_FORMAT 0x04 /* Serial Format, ADC/DAC Control */
+#define CS4270_TRANS 0x05 /* Transition Control */
+#define CS4270_MUTE 0x06 /* Mute Control */
+#define CS4270_VOLA 0x07 /* DAC Channel A Volume Control */
+#define CS4270_VOLB 0x08 /* DAC Channel B Volume Control */
+
+#define CS4270_FIRSTREG 0x01
+#define CS4270_LASTREG 0x08
+#define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1)
+
+/* Bit masks for the CS4270 registers */
+#define CS4270_CHIPID_ID 0xF0
+#define CS4270_CHIPID_REV 0x0F
+#define CS4270_PWRCTL_FREEZE 0x80
+#define CS4270_PWRCTL_PDN_ADC 0x20
+#define CS4270_PWRCTL_PDN_DAC 0x02
+#define CS4270_PWRCTL_PDN 0x01
+#define CS4270_MODE_SPEED_MASK 0x30
+#define CS4270_MODE_1X 0x00
+#define CS4270_MODE_2X 0x10
+#define CS4270_MODE_4X 0x20
+#define CS4270_MODE_SLAVE 0x30
+#define CS4270_MODE_DIV_MASK 0x0E
+#define CS4270_MODE_DIV1 0x00
+#define CS4270_MODE_DIV15 0x02
+#define CS4270_MODE_DIV2 0x04
+#define CS4270_MODE_DIV3 0x06
+#define CS4270_MODE_DIV4 0x08
+#define CS4270_MODE_POPGUARD 0x01
+#define CS4270_FORMAT_FREEZE_A 0x80
+#define CS4270_FORMAT_FREEZE_B 0x40
+#define CS4270_FORMAT_LOOPBACK 0x20
+#define CS4270_FORMAT_DAC_MASK 0x18
+#define CS4270_FORMAT_DAC_LJ 0x00
+#define CS4270_FORMAT_DAC_I2S 0x08
+#define CS4270_FORMAT_DAC_RJ16 0x18
+#define CS4270_FORMAT_DAC_RJ24 0x10
+#define CS4270_FORMAT_ADC_MASK 0x01
+#define CS4270_FORMAT_ADC_LJ 0x00
+#define CS4270_FORMAT_ADC_I2S 0x01
+#define CS4270_TRANS_ONE_VOL 0x80
+#define CS4270_TRANS_SOFT 0x40
+#define CS4270_TRANS_ZERO 0x20
+#define CS4270_TRANS_INV_ADC_A 0x08
+#define CS4270_TRANS_INV_ADC_B 0x10
+#define CS4270_TRANS_INV_DAC_A 0x02
+#define CS4270_TRANS_INV_DAC_B 0x04
+#define CS4270_TRANS_DEEMPH 0x01
+#define CS4270_MUTE_AUTO 0x20
+#define CS4270_MUTE_ADC_A 0x08
+#define CS4270_MUTE_ADC_B 0x10
+#define CS4270_MUTE_POLARITY 0x04
+#define CS4270_MUTE_DAC_A 0x01
+#define CS4270_MUTE_DAC_B 0x02
+
+/*
+ * A list of addresses on which this CS4270 could use. I2C addresses are
+ * 7 bits. For the CS4270, the upper four bits are always 1001, and the
+ * lower three bits are determined via the AD2, AD1, and AD0 pins
+ * (respectively).
+ */
+static unsigned short normal_i2c[] = {
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END
+};
+I2C_CLIENT_INSMOD;
+
+/*
+ * Pre-fill the CS4270 register cache.
+ *
+ * We use the auto-increment feature of the CS4270 to read all registers in
+ * one shot.
+ */
+static int cs4270_fill_cache(struct snd_soc_codec *codec)
+{
+ u8 *cache = codec->reg_cache;
+ struct i2c_client *i2c_client = codec->control_data;
+ s32 length;
+
+ length = i2c_smbus_read_i2c_block_data(i2c_client,
+ CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache);
+
+ if (length != CS4270_NUMREGS) {
+ printk(KERN_ERR "cs4270: I2C read failure, addr=0x%x\n",
+ i2c_client->addr);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * Read from the CS4270 register cache.
+ *
+ * This CS4270 registers are cached to avoid excessive I2C I/O operations.
+ * After the initial read to pre-fill the cache, the CS4270 never updates
+ * the register values, so we won't have a cache coherncy problem.
+ */
+static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ u8 *cache = codec->reg_cache;
+
+ if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
+ return -EIO;
+
+ return cache[reg - CS4270_FIRSTREG];
+}
+
+/*
+ * Write to a CS4270 register via the I2C bus.
+ *
+ * This function writes the given value to the given CS4270 register, and
+ * also updates the register cache.
+ *
+ * Note that we don't use the hw_write function pointer of snd_soc_codec.
+ * That's because it's too clunky: the hw_write_t prototype does not match
+ * i2c_smbus_write_byte_data(), and it's just another layer of overhead.
+ */
+static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
+ unsigned int value)
+{
+ u8 *cache = codec->reg_cache;
+
+ if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
+ return -EIO;
+
+ /* Only perform an I2C operation if the new value is different */
+ if (cache[reg - CS4270_FIRSTREG] != value) {
+ struct i2c_client *client = codec->control_data;
+ if (i2c_smbus_write_byte_data(client, reg, value)) {
+ printk(KERN_ERR "cs4270: I2C write failed\n");
+ return -EIO;
+ }
+
+ /* We've written to the hardware, so update the cache */
+ cache[reg - CS4270_FIRSTREG] = value;
+ }
+
+ return 0;
+}
+
+/*
+ * Clock Ratio Selection for Master Mode with I2C enabled
+ *
+ * The data for this chart is taken from Table 5 of the CS4270 reference
+ * manual.
+ *
+ * This table is used to determine how to program the Mode Control register.
+ * It is also used by cs4270_set_dai_sysclk() to tell ALSA which sampling
+ * rates the CS4270 currently supports.
+ *
+ * Each element in this array corresponds to the ratios in mclk_ratios[].
+ * These two arrays need to be in sync.
+ *
+ * 'speed_mode' is the corresponding bit pattern to be written to the
+ * MODE bits of the Mode Control Register
+ *
+ * 'mclk' is the corresponding bit pattern to be wirten to the MCLK bits of
+ * the Mode Control Register.
+ *
+ * In situations where a single ratio is represented by multiple speed
+ * modes, we favor the slowest speed. E.g, for a ratio of 128, we pick
+ * double-speed instead of quad-speed. However, the CS4270 errata states
+ * that Divide-By-1.5 can cause failures, so we avoid that mode where
+ * possible.
+ *
+ * ERRATA: There is an errata for the CS4270 where divide-by-1.5 does not
+ * work if VD = 3.3V. If this effects you, select the
+ * CONFIG_SND_SOC_CS4270_VD33_ERRATA Kconfig option, and the driver will
+ * never select any sample rates that require divide-by-1.5.
+ */
+static struct {
+ u8 speed_mode;
+ u8 mclk;
+} cs4270_mode_ratios[NUM_MCLK_RATIOS] = {
+ {CS4270_MODE_4X, CS4270_MODE_DIV1}, /* 64 */
+#ifndef CONFIG_SND_SOC_CS4270_VD33_ERRATA
+ {CS4270_MODE_4X, CS4270_MODE_DIV15}, /* 96 */
+#endif
+ {CS4270_MODE_2X, CS4270_MODE_DIV1}, /* 128 */
+ {CS4270_MODE_4X, CS4270_MODE_DIV3}, /* 192 */
+ {CS4270_MODE_1X, CS4270_MODE_DIV1}, /* 256 */
+ {CS4270_MODE_2X, CS4270_MODE_DIV3}, /* 384 */
+ {CS4270_MODE_1X, CS4270_MODE_DIV2}, /* 512 */
+ {CS4270_MODE_1X, CS4270_MODE_DIV3}, /* 768 */
+ {CS4270_MODE_1X, CS4270_MODE_DIV4} /* 1024 */
+};
+
+/*
+ * Program the CS4270 with the given hardware parameters.
+ *
+ * The .dai_ops functions are used to provide board-specific data, like
+ * input frequencies, to this driver. This function takes that information,
+ * combines it with the hardware parameters provided, and programs the
+ * hardware accordingly.
+ */
+static int cs4270_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_device *socdev = rtd->socdev;
+ struct snd_soc_codec *codec = socdev->codec;
+ struct cs4270_private *cs4270 = codec->private_data;
+ unsigned int ret = 0;
+ unsigned int i;
+ unsigned int rate;
+ unsigned int ratio;
+ int reg;
+
+ /* Figure out which MCLK/LRCK ratio to use */
+
+ rate = params_rate(params); /* Sampling rate, in Hz */
+ ratio = cs4270->mclk / rate; /* MCLK/LRCK ratio */
+
+ for (i = 0; i < NUM_MCLK_RATIOS; i++) {
+ if (mclk_ratios[i] == ratio)
+ break;
+ }
+
+ if (i == NUM_MCLK_RATIOS) {
+ /* We did not find a matching ratio */
+ printk(KERN_ERR "cs4270: could not find matching ratio\n");
+ return -EINVAL;
+ }
+
+ /* Freeze and power-down the codec */
+
+ ret = snd_soc_write(codec, CS4270_PWRCTL, CS4270_PWRCTL_FREEZE |
+ CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC |
+ CS4270_PWRCTL_PDN);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: I2C write failed\n");
+ return ret;
+ }
+
+ /* Program the mode control register */
+
+ reg = snd_soc_read(codec, CS4270_MODE);
+ reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK);
+ reg |= cs4270_mode_ratios[i].speed_mode | cs4270_mode_ratios[i].mclk;
+
+ ret = snd_soc_write(codec, CS4270_MODE, reg);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: I2C write failed\n");
+ return ret;
+ }
+
+ /* Program the format register */
+
+ reg = snd_soc_read(codec, CS4270_FORMAT);
+ reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK);
+
+ switch (cs4270->mode) {
+ case SND_SOC_DAIFMT_I2S:
+ reg |= CS4270_FORMAT_DAC_I2S | CS4270_FORMAT_ADC_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ reg |= CS4270_FORMAT_DAC_LJ | CS4270_FORMAT_ADC_LJ;
+ break;
+ default:
+ printk(KERN_ERR "cs4270: unknown format\n");
+ return -EINVAL;
+ }
+
+ ret = snd_soc_write(codec, CS4270_FORMAT, reg);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: I2C write failed\n");
+ return ret;
+ }
+
+ /* Disable auto-mute. This feature appears to be buggy, because in
+ some situations, auto-mute will not deactivate when it should. */
+
+ reg = snd_soc_read(codec, CS4270_MUTE);
+ reg &= ~CS4270_MUTE_AUTO;
+ ret = snd_soc_write(codec, CS4270_MUTE, reg);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: I2C write failed\n");
+ return ret;
+ }
+
+ /* Thaw and power-up the codec */
+
+ ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: I2C write failed\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
+
+/*
+ * Set the CS4270 external mute
+ *
+ * This function toggles the mute bits in the MUTE register. The CS4270's
+ * mute capability is intended for external muting circuitry, so if the
+ * board does not have the MUTEA or MUTEB pins connected to such circuitry,
+ * then this function will do nothing.
+ */
+static int cs4270_mute(struct snd_soc_codec_dai *dai, int mute)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int reg6;
+
+ reg6 = snd_soc_read(codec, CS4270_MUTE);
+
+ if (mute)
+ reg6 |= CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B |
+ CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B;
+ else
+ reg6 &= ~(CS4270_MUTE_ADC_A | CS4270_MUTE_ADC_B |
+ CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B);
+
+ return snd_soc_write(codec, CS4270_MUTE, reg6);
+}
+
+#endif
+
+static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind);
+
+/*
+ * Notify the driver that a new I2C bus has been found.
+ *
+ * This function is called for each I2C bus in the system. The function
+ * then asks the I2C subsystem to probe that bus at the addresses on which
+ * our device (the CS4270) could exist. If a device is found at one of
+ * those addresses, then our probe function (cs4270_i2c_probe) is called.
+ */
+static int cs4270_i2c_attach(struct i2c_adapter *adapter)
+{
+ return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
+}
+
+static int cs4270_i2c_detach(struct i2c_client *client)
+{
+ struct snd_soc_codec *codec = i2c_get_clientdata(client);
+
+ i2c_detach_client(client);
+ codec->control_data = NULL;
+
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+
+ kfree(client);
+ return 0;
+}
+
+/* A list of non-DAPM controls that the CS4270 supports */
+static const struct snd_kcontrol_new cs4270_snd_controls[] = {
+ SOC_DOUBLE_R("Master Playback Volume",
+ CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
+};
+
+static struct i2c_driver cs4270_i2c_driver = {
+ .driver = {
+ .name = "CS4270 I2C",
+ .owner = THIS_MODULE,
+ },
+ .id = I2C_DRIVERID_CS4270,
+ .attach_adapter = cs4270_i2c_attach,
+ .detach_client = cs4270_i2c_detach,
+};
+
+/*
+ * Global variable to store socdev for i2c probe function.
+ *
+ * If struct i2c_driver had a private_data field, we wouldn't need to use
+ * cs4270_socdec. This is the only way to pass the socdev structure to
+ * cs4270_i2c_probe().
+ *
+ * The real solution to cs4270_socdev is to create a mechanism
+ * that maps I2C addresses to snd_soc_device structures. Perhaps the
+ * creation of the snd_soc_device object should be moved out of
+ * cs4270_probe() and into cs4270_i2c_probe(), but that would make this
+ * driver dependent on I2C. The CS4270 supports "stand-alone" mode, whereby
+ * the chip is *not* connected to the I2C bus, but is instead configured via
+ * input pins.
+ */
+static struct snd_soc_device *cs4270_socdev;
+
+/*
+ * Initialize the I2C interface of the CS4270
+ *
+ * This function is called for whenever the I2C subsystem finds a device
+ * at a particular address.
+ *
+ * Note: snd_soc_new_pcms() must be called before this function can be called,
+ * because of snd_ctl_add().
+ */
+static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct snd_soc_device *socdev = cs4270_socdev;
+ struct snd_soc_codec *codec = socdev->codec;
+ struct i2c_client *i2c_client = NULL;
+ int i;
+ int ret = 0;
+
+ /* Probing all possible addresses has one drawback: if there are
+ multiple CS4270s on the bus, then you cannot specify which
+ socdev is matched with which CS4270. For now, we just reject
+ this I2C device if the socdev already has one attached. */
+ if (codec->control_data)
+ return -ENODEV;
+
+ /* Note: codec_dai->codec is NULL here */
+
+ i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (!i2c_client) {
+ printk(KERN_ERR "cs4270: could not allocate I2C client\n");
+ return -ENOMEM;
+ }
+
+ codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
+ if (!codec->reg_cache) {
+ printk(KERN_ERR "cs4270: could not allocate register cache\n");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ i2c_set_clientdata(i2c_client, codec);
+ strcpy(i2c_client->name, "CS4270");
+
+ i2c_client->driver = &cs4270_i2c_driver;
+ i2c_client->adapter = adapter;
+ i2c_client->addr = addr;
+
+ /* Verify that we have a CS4270 */
+
+ ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: failed to read I2C\n");
+ goto error;
+ }
+ /* The top four bits of the chip ID should be 1100. */
+ if ((ret & 0xF0) != 0xC0) {
+ /* The device at this address is not a CS4270 codec */
+ ret = -ENODEV;
+ goto error;
+ }
+
+ printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr);
+ printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
+
+ /* Tell the I2C layer a new client has arrived */
+
+ ret = i2c_attach_client(i2c_client);
+ if (ret) {
+ printk(KERN_ERR "cs4270: could not attach codec, "
+ "I2C address %x, error code %i\n", addr, ret);
+ goto error;
+ }
+
+ codec->control_data = i2c_client;
+ codec->read = cs4270_read_reg_cache;
+ codec->write = cs4270_i2c_write;
+ codec->reg_cache_size = CS4270_NUMREGS;
+
+ /* The I2C interface is set up, so pre-fill our register cache */
+
+ ret = cs4270_fill_cache(codec);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: failed to fill register cache\n");
+ goto error;
+ }
+
+ /* Add the non-DAPM controls */
+
+ for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) {
+ struct snd_kcontrol *kctrl =
+ snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL);
+
+ ret = snd_ctl_add(codec->card, kctrl);
+ if (ret < 0)
+ goto error;
+ }
+
+ return 0;
+
+error:
+ if (codec->control_data) {
+ i2c_detach_client(i2c_client);
+ codec->control_data = NULL;
+ }
+
+ kfree(codec->reg_cache);
+ codec->reg_cache = NULL;
+ codec->reg_cache_size = 0;
+
+ kfree(i2c_client);
+
+ return ret;
+}
+
+#endif
+
+struct snd_soc_codec_dai cs4270_dai = {
+ .name = "CS4270",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = 0,
+ .formats = CS4270_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = 0,
+ .formats = CS4270_FORMATS,
+ },
+ .dai_ops = {
+ .set_sysclk = cs4270_set_dai_sysclk,
+ .set_fmt = cs4270_set_dai_fmt,
+ }
+};
+EXPORT_SYMBOL_GPL(cs4270_dai);
+
+/*
+ * ASoC probe function
+ *
+ * This function is called when the machine driver calls
+ * platform_device_add().
+ */
+static int cs4270_probe(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec;
+ int ret = 0;
+
+ printk(KERN_INFO "CS4270 ALSA SoC Codec\n");
+
+ /* Allocate enough space for the snd_soc_codec structure
+ and our private data together. */
+ codec = kzalloc(ALIGN(sizeof(struct snd_soc_codec), 4) +
+ sizeof(struct cs4270_private), GFP_KERNEL);
+ if (!codec) {
+ printk(KERN_ERR "cs4270: Could not allocate codec structure\n");
+ return -ENOMEM;
+ }
+
+ mutex_init(&codec->mutex);
+ INIT_LIST_HEAD(&codec->dapm_widgets);
+ INIT_LIST_HEAD(&codec->dapm_paths);
+
+ codec->name = "CS4270";
+ codec->owner = THIS_MODULE;
+ codec->dai = &cs4270_dai;
+ codec->num_dai = 1;
+ codec->private_data = codec + ALIGN(sizeof(struct snd_soc_codec), 4);
+
+ socdev->codec = codec;
+
+ /* Register PCMs */
+
+ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: failed to create PCMs\n");
+ return ret;
+ }
+
+#ifdef USE_I2C
+ cs4270_socdev = socdev;
+
+ ret = i2c_add_driver(&cs4270_i2c_driver);
+ if (ret) {
+ printk(KERN_ERR "cs4270: failed to attach driver");
+ snd_soc_free_pcms(socdev);
+ return ret;
+ }
+
+ /* Did we find a CS4270 on the I2C bus? */
+ if (codec->control_data) {
+ /* Initialize codec ops */
+ cs4270_dai.ops.hw_params = cs4270_hw_params;
+#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
+ cs4270_dai.dai_ops.digital_mute = cs4270_mute;
+#endif
+ } else
+ printk(KERN_INFO "cs4270: no I2C device found, "
+ "using stand-alone mode\n");
+#else
+ printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n");
+#endif
+
+ ret = snd_soc_register_card(socdev);
+ if (ret < 0) {
+ printk(KERN_ERR "cs4270: failed to register card\n");
+ snd_soc_free_pcms(socdev);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int cs4270_remove(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+
+ snd_soc_free_pcms(socdev);
+
+#ifdef USE_I2C
+ if (socdev->codec->control_data)
+ i2c_del_driver(&cs4270_i2c_driver);
+#endif
+
+ kfree(socdev->codec);
+ socdev->codec = NULL;
+
+ return 0;
+}
+
+/*
+ * ASoC codec device structure
+ *
+ * Assign this variable to the codec_dev field of the machine driver's
+ * snd_soc_device structure.
+ */
+struct snd_soc_codec_device soc_codec_device_cs4270 = {
+ .probe = cs4270_probe,
+ .remove = cs4270_remove
+};
+EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
+
+MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
+MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h
new file mode 100644
index 00000000000..0ced49b7804
--- /dev/null
+++ b/sound/soc/codecs/cs4270.h
@@ -0,0 +1,28 @@
+/*
+ * Cirrus Logic CS4270 ALSA SoC Codec Driver
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef _CS4270_H
+#define _CS4270_H
+
+/*
+ * The ASoC codec DAI structure for the CS4270. Assign this structure to
+ * the .codec_dai field of your machine driver's snd_soc_dai_link structure.
+ */
+extern struct snd_soc_codec_dai cs4270_dai;
+
+/*
+ * The ASoC codec device structure for the CS4270. Assign this structure
+ * to the .codec_dev field of your machine driver's snd_soc_device
+ * structure.
+ */
+extern struct snd_soc_codec_device soc_codec_device_cs4270;
+
+#endif
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 80e82109fef..4dd8f35312b 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -34,7 +34,6 @@
#include <asm/arch/hardware.h>
#include <asm/arch/akita.h>
#include <asm/arch/spitz.h>
-#include <asm/mach-types.h>
#include "../codecs/wm8750.h"
#include "pxa2xx-pcm.h"
#include "pxa2xx-i2s.h"
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index e97c68306a9..5632a2e1518 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -18,7 +18,7 @@ config SND_S3C2443_SOC_AC97
config SND_S3C24XX_SOC_NEO1973_WM8753
tristate "SoC I2S Audio support for NEO1973 - WM8753"
- depends on SND_S3C24XX_SOC && MACH_GTA01
+ depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
select SND_S3C24XX_SOC_I2S
select SND_SOC_WM8753
help
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 39f02462e07..cd89c4105fc 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -385,6 +385,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev)
s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis");
if (s3c24xx_i2s.iis_clk == NULL) {
DBG("failed to get iis_clock\n");
+ iounmap(s3c24xx_i2s.regs);
return -ENODEV;
}
clk_enable(s3c24xx_i2s.iis_clk);
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index bfbdc3cbd43..4107a87d4de 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -158,18 +158,22 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
if (!dma)
return 0;
- /* prepare DMA */
- prtd->params = dma;
+ /* this may get called several times by oss emulation
+ * with different params -HW */
+ if (prtd->params == NULL) {
+ /* prepare DMA */
+ prtd->params = dma;
- DBG("params %p, client %p, channel %d\n", prtd->params,
- prtd->params->client, prtd->params->channel);
+ DBG("params %p, client %p, channel %d\n", prtd->params,
+ prtd->params->client, prtd->params->channel);
- ret = s3c2410_dma_request(prtd->params->channel,
- prtd->params->client, NULL);
+ ret = s3c2410_dma_request(prtd->params->channel,
+ prtd->params->client, NULL);
- if (ret) {
- DBG(KERN_ERR "failed to get dma channel\n");
- return ret;
+ if (ret) {
+ DBG(KERN_ERR "failed to get dma channel\n");
+ return ret;
+ }
}
/* channel needs configuring for mem=>device, increment memory addr,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 92d5d917b73..91651bdfa76 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1362,26 +1362,6 @@ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
/**
- * snd_soc_info_bool_ext - external single boolean mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a single boolean external mixer control.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_bool_ext(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_bool_ext);
-
-/**
* snd_soc_info_volsw - single mixer info callback
* @kcontrol: mixer control
* @uinfo: control element information
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 96bce55572a..b3193e687db 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -63,7 +63,7 @@
#define POP_DEBUG 0
#if POP_DEBUG
#define POP_TIME 500 /* 500 msecs - change if pop debug is too fast */
-#define pop_wait(time) schedule_timeout_interruptible(msecs_to_jiffies(time))
+#define pop_wait(time) schedule_timeout_uninterruptible(msecs_to_jiffies(time))
#define pop_dbg(format, arg...) printk(format, ## arg); pop_wait(POP_TIME)
#else
#define pop_dbg(format, arg...)
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index f2950cab74a..9785382a5f3 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -3,9 +3,9 @@
* Copyright (C) 2002 David S. Miller <davem@redhat.com>
*
* Based entirely upon drivers/sbus/audio/cs4231.c which is:
- * Copyright (C) 1996, 1997, 1998, 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
+ * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
* and also sound/isa/cs423x/cs4231_lib.c which is:
- * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*/
#include <linux/module.h>
@@ -15,6 +15,9 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
#include <sound/driver.h>
#include <sound/core.h>
@@ -25,29 +28,21 @@
#include <sound/initval.h>
#include <sound/pcm_params.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
#ifdef CONFIG_SBUS
#define SBUS_SUPPORT
-#endif
-
-#ifdef SBUS_SUPPORT
#include <asm/sbus.h>
#endif
#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
#define EBUS_SUPPORT
-#endif
-
-#ifdef EBUS_SUPPORT
#include <linux/pci.h>
#include <asm/ebus.h>
#endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+/* Enable this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard.");
@@ -62,19 +57,22 @@ MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}");
#ifdef SBUS_SUPPORT
struct sbus_dma_info {
- spinlock_t lock;
- int dir;
- void __iomem *regs;
+ spinlock_t lock; /* DMA access lock */
+ int dir;
+ void __iomem *regs;
};
#endif
struct snd_cs4231;
struct cs4231_dma_control {
- void (*prepare)(struct cs4231_dma_control *dma_cont, int dir);
- void (*enable)(struct cs4231_dma_control *dma_cont, int on);
- int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len);
- unsigned int (*address)(struct cs4231_dma_control *dma_cont);
- void (*preallocate)(struct snd_cs4231 *chip, struct snd_pcm *pcm);
+ void (*prepare)(struct cs4231_dma_control *dma_cont,
+ int dir);
+ void (*enable)(struct cs4231_dma_control *dma_cont, int on);
+ int (*request)(struct cs4231_dma_control *dma_cont,
+ dma_addr_t bus_addr, size_t len);
+ unsigned int (*address)(struct cs4231_dma_control *dma_cont);
+ void (*preallocate)(struct snd_cs4231 *chip,
+ struct snd_pcm *pcm);
#ifdef EBUS_SUPPORT
struct ebus_dma_info ebus_info;
#endif
@@ -84,7 +82,7 @@ struct cs4231_dma_control {
};
struct snd_cs4231 {
- spinlock_t lock;
+ spinlock_t lock; /* registers access lock */
void __iomem *port;
struct cs4231_dma_control p_dma;
@@ -108,13 +106,14 @@ struct snd_cs4231 {
#define CS4231_MODE_PLAY 0x0001
#define CS4231_MODE_RECORD 0x0002
#define CS4231_MODE_TIMER 0x0004
-#define CS4231_MODE_OPEN (CS4231_MODE_PLAY|CS4231_MODE_RECORD|CS4231_MODE_TIMER)
+#define CS4231_MODE_OPEN (CS4231_MODE_PLAY | CS4231_MODE_RECORD | \
+ CS4231_MODE_TIMER)
unsigned char image[32]; /* registers image */
int mce_bit;
int calibrate_mute;
- struct mutex mce_mutex;
- struct mutex open_mutex;
+ struct mutex mce_mutex; /* mutex for mce register */
+ struct mutex open_mutex; /* mutex for ALSA open/close */
union {
#ifdef SBUS_SUPPORT
@@ -136,129 +135,10 @@ static struct snd_cs4231 *cs4231_list;
*/
/* IO ports */
-
-#define CS4231P(chip, x) ((chip)->port + c_d_c_CS4231##x)
+#include <sound/cs4231-regs.h>
/* XXX offsets are different than PC ISA chips... */
-#define c_d_c_CS4231REGSEL 0x0
-#define c_d_c_CS4231REG 0x4
-#define c_d_c_CS4231STATUS 0x8
-#define c_d_c_CS4231PIO 0xc
-
-/* codec registers */
-
-#define CS4231_LEFT_INPUT 0x00 /* left input control */
-#define CS4231_RIGHT_INPUT 0x01 /* right input control */
-#define CS4231_AUX1_LEFT_INPUT 0x02 /* left AUX1 input control */
-#define CS4231_AUX1_RIGHT_INPUT 0x03 /* right AUX1 input control */
-#define CS4231_AUX2_LEFT_INPUT 0x04 /* left AUX2 input control */
-#define CS4231_AUX2_RIGHT_INPUT 0x05 /* right AUX2 input control */
-#define CS4231_LEFT_OUTPUT 0x06 /* left output control register */
-#define CS4231_RIGHT_OUTPUT 0x07 /* right output control register */
-#define CS4231_PLAYBK_FORMAT 0x08 /* clock and data format - playback - bits 7-0 MCE */
-#define CS4231_IFACE_CTRL 0x09 /* interface control - bits 7-2 MCE */
-#define CS4231_PIN_CTRL 0x0a /* pin control */
-#define CS4231_TEST_INIT 0x0b /* test and initialization */
-#define CS4231_MISC_INFO 0x0c /* miscellaneaous information */
-#define CS4231_LOOPBACK 0x0d /* loopback control */
-#define CS4231_PLY_UPR_CNT 0x0e /* playback upper base count */
-#define CS4231_PLY_LWR_CNT 0x0f /* playback lower base count */
-#define CS4231_ALT_FEATURE_1 0x10 /* alternate #1 feature enable */
-#define CS4231_ALT_FEATURE_2 0x11 /* alternate #2 feature enable */
-#define CS4231_LEFT_LINE_IN 0x12 /* left line input control */
-#define CS4231_RIGHT_LINE_IN 0x13 /* right line input control */
-#define CS4231_TIMER_LOW 0x14 /* timer low byte */
-#define CS4231_TIMER_HIGH 0x15 /* timer high byte */
-#define CS4231_LEFT_MIC_INPUT 0x16 /* left MIC input control register (InterWave only) */
-#define CS4231_RIGHT_MIC_INPUT 0x17 /* right MIC input control register (InterWave only) */
-#define CS4236_EXT_REG 0x17 /* extended register access */
-#define CS4231_IRQ_STATUS 0x18 /* irq status register */
-#define CS4231_LINE_LEFT_OUTPUT 0x19 /* left line output control register (InterWave only) */
-#define CS4231_VERSION 0x19 /* CS4231(A) - version values */
-#define CS4231_MONO_CTRL 0x1a /* mono input/output control */
-#define CS4231_LINE_RIGHT_OUTPUT 0x1b /* right line output control register (InterWave only) */
-#define CS4235_LEFT_MASTER 0x1b /* left master output control */
-#define CS4231_REC_FORMAT 0x1c /* clock and data format - record - bits 7-0 MCE */
-#define CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */
-#define CS4235_RIGHT_MASTER 0x1d /* right master output control */
-#define CS4231_REC_UPR_CNT 0x1e /* record upper count */
-#define CS4231_REC_LWR_CNT 0x1f /* record lower count */
-
-/* definitions for codec register select port - CODECP( REGSEL ) */
-
-#define CS4231_INIT 0x80 /* CODEC is initializing */
-#define CS4231_MCE 0x40 /* mode change enable */
-#define CS4231_TRD 0x20 /* transfer request disable */
-
-/* definitions for codec status register - CODECP( STATUS ) */
-
-#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
-
-/* definitions for codec irq status - CS4231_IRQ_STATUS */
-
-#define CS4231_PLAYBACK_IRQ 0x10
-#define CS4231_RECORD_IRQ 0x20
-#define CS4231_TIMER_IRQ 0x40
-#define CS4231_ALL_IRQS 0x70
-#define CS4231_REC_UNDERRUN 0x08
-#define CS4231_REC_OVERRUN 0x04
-#define CS4231_PLY_OVERRUN 0x02
-#define CS4231_PLY_UNDERRUN 0x01
-
-/* definitions for CS4231_LEFT_INPUT and CS4231_RIGHT_INPUT registers */
-
-#define CS4231_ENABLE_MIC_GAIN 0x20
-
-#define CS4231_MIXS_LINE 0x00
-#define CS4231_MIXS_AUX1 0x40
-#define CS4231_MIXS_MIC 0x80
-#define CS4231_MIXS_ALL 0xc0
-
-/* definitions for clock and data format register - CS4231_PLAYBK_FORMAT */
-
-#define CS4231_LINEAR_8 0x00 /* 8-bit unsigned data */
-#define CS4231_ALAW_8 0x60 /* 8-bit A-law companded */
-#define CS4231_ULAW_8 0x20 /* 8-bit U-law companded */
-#define CS4231_LINEAR_16 0x40 /* 16-bit twos complement data - little endian */
-#define CS4231_LINEAR_16_BIG 0xc0 /* 16-bit twos complement data - big endian */
-#define CS4231_ADPCM_16 0xa0 /* 16-bit ADPCM */
-#define CS4231_STEREO 0x10 /* stereo mode */
-/* bits 3-1 define frequency divisor */
-#define CS4231_XTAL1 0x00 /* 24.576 crystal */
-#define CS4231_XTAL2 0x01 /* 16.9344 crystal */
-
-/* definitions for interface control register - CS4231_IFACE_CTRL */
-
-#define CS4231_RECORD_PIO 0x80 /* record PIO enable */
-#define CS4231_PLAYBACK_PIO 0x40 /* playback PIO enable */
-#define CS4231_CALIB_MODE 0x18 /* calibration mode bits */
-#define CS4231_AUTOCALIB 0x08 /* auto calibrate */
-#define CS4231_SINGLE_DMA 0x04 /* use single DMA channel */
-#define CS4231_RECORD_ENABLE 0x02 /* record enable */
-#define CS4231_PLAYBACK_ENABLE 0x01 /* playback enable */
-
-/* definitions for pin control register - CS4231_PIN_CTRL */
-
-#define CS4231_IRQ_ENABLE 0x02 /* enable IRQ */
-#define CS4231_XCTL1 0x40 /* external control #1 */
-#define CS4231_XCTL0 0x80 /* external control #0 */
-
-/* definitions for test and init register - CS4231_TEST_INIT */
-
-#define CS4231_CALIB_IN_PROGRESS 0x20 /* auto calibrate in progress */
-#define CS4231_DMA_REQUEST 0x10 /* DMA request in progress */
-
-/* definitions for misc control register - CS4231_MISC_INFO */
-
-#define CS4231_MODE2 0x40 /* MODE 2 */
-#define CS4231_IW_MODE3 0x6c /* MODE 3 - InterWave enhanced mode */
-#define CS4231_4236_MODE3 0xe0 /* MODE 3 - CS4236+ enhanced mode */
-
-/* definitions for alternate feature 1 register - CS4231_ALT_FEATURE_1 */
-
-#define CS4231_DACZ 0x01 /* zero DAC when underrun */
-#define CS4231_TIMER_ENABLE 0x40 /* codec timer enable */
-#define CS4231_OLB 0x80 /* output level bit */
+#define CS4231U(chip, x) ((chip)->port + ((c_d_c_CS4231##x) << 2))
/* SBUS DMA register defines. */
@@ -339,7 +219,7 @@ static unsigned int rates[14] = {
};
static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = 14,
+ .count = ARRAY_SIZE(rates),
.list = rates,
};
@@ -389,116 +269,89 @@ static unsigned char snd_cs4231_original_image[32] =
static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
{
#ifdef EBUS_SUPPORT
- if (cp->flags & CS4231_FLAG_EBUS) {
+ if (cp->flags & CS4231_FLAG_EBUS)
return readb(reg_addr);
- } else {
+ else
#endif
#ifdef SBUS_SUPPORT
return sbus_readb(reg_addr);
#endif
-#ifdef EBUS_SUPPORT
- }
-#endif
}
-static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, void __iomem *reg_addr)
+static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val,
+ void __iomem *reg_addr)
{
#ifdef EBUS_SUPPORT
- if (cp->flags & CS4231_FLAG_EBUS) {
+ if (cp->flags & CS4231_FLAG_EBUS)
return writeb(val, reg_addr);
- } else {
+ else
#endif
#ifdef SBUS_SUPPORT
return sbus_writeb(val, reg_addr);
#endif
-#ifdef EBUS_SUPPORT
- }
-#endif
}
/*
* Basic I/O functions
*/
-static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
- unsigned char mask, unsigned char value)
+static void snd_cs4231_ready(struct snd_cs4231 *chip)
{
int timeout;
- unsigned char tmp;
- for (timeout = 250;
- timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
-#endif
- if (chip->calibrate_mute) {
- chip->image[reg] &= mask;
- chip->image[reg] |= value;
- } else {
- __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
- mb();
- tmp = (chip->image[reg] & mask) | value;
- __cs4231_writeb(chip, tmp, CS4231P(chip, REG));
- chip->image[reg] = tmp;
- mb();
+ for (timeout = 250; timeout > 0; timeout--) {
+ int val = __cs4231_readb(chip, CS4231U(chip, REGSEL));
+ if ((val & CS4231_INIT) == 0)
+ break;
+ udelay(100);
}
}
-static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
+static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg,
+ unsigned char value)
{
- int timeout;
-
- for (timeout = 250;
- timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
+ snd_cs4231_ready(chip);
#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
+ snd_printdd("out: auto calibration time out - reg = 0x%x, "
+ "value = 0x%x\n",
+ reg, value);
#endif
- __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
- __cs4231_writeb(chip, value, CS4231P(chip, REG));
+ __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL));
+ wmb();
+ __cs4231_writeb(chip, value, CS4231U(chip, REG));
mb();
}
-static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
+static inline void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
+ unsigned char mask, unsigned char value)
{
- int timeout;
+ unsigned char tmp = (chip->image[reg] & mask) | value;
- for (timeout = 250;
- timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
-#endif
- __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
- __cs4231_writeb(chip, value, CS4231P(chip, REG));
+ chip->image[reg] = tmp;
+ if (!chip->calibrate_mute)
+ snd_cs4231_dout(chip, reg, tmp);
+}
+
+static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg,
+ unsigned char value)
+{
+ snd_cs4231_dout(chip, reg, value);
chip->image[reg] = value;
mb();
}
static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
{
- int timeout;
- unsigned char ret;
-
- for (timeout = 250;
- timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(100);
+ snd_cs4231_ready(chip);
#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("in: auto calibration time out - reg = 0x%x\n", reg);
+ if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
+ snd_printdd("in: auto calibration time out - reg = 0x%x\n",
+ reg);
#endif
- __cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
+ __cs4231_writeb(chip, chip->mce_bit | reg, CS4231U(chip, REGSEL));
mb();
- ret = __cs4231_readb(chip, CS4231P(chip, REG));
- return ret;
+ return __cs4231_readb(chip, CS4231U(chip, REG));
}
/*
@@ -509,15 +362,17 @@ static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
{
int timeout;
- /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
+ /* looks like this sequence is proper for CS4231A chip (GUS MAX) */
for (timeout = 5; timeout > 0; timeout--)
- __cs4231_readb(chip, CS4231P(chip, REGSEL));
+ __cs4231_readb(chip, CS4231U(chip, REGSEL));
/* end of cleanup sequence */
- for (timeout = 500;
- timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
- timeout--)
- udelay(1000);
+ for (timeout = 500; timeout > 0; timeout--) {
+ int val = __cs4231_readb(chip, CS4231U(chip, REGSEL));
+ if ((val & CS4231_INIT) == 0)
+ break;
+ msleep(1);
+ }
}
static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
@@ -526,74 +381,81 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
int timeout;
spin_lock_irqsave(&chip->lock, flags);
- for (timeout = 250; timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT); timeout--)
- udelay(100);
+ snd_cs4231_ready(chip);
#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
+ if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
snd_printdd("mce_up - auto calibration time out (0)\n");
#endif
chip->mce_bit |= CS4231_MCE;
- timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
+ timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
if (timeout == 0x80)
- snd_printdd("mce_up [%p]: serious init problem - codec still busy\n", chip->port);
+ snd_printdd("mce_up [%p]: serious init problem - "
+ "codec still busy\n",
+ chip->port);
if (!(timeout & CS4231_MCE))
- __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
+ __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
+ CS4231U(chip, REGSEL));
spin_unlock_irqrestore(&chip->lock, flags);
}
static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
{
unsigned long flags;
+ unsigned long end_time;
int timeout;
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_busy_wait(chip);
#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL));
+ if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
+ snd_printdd("mce_down [%p] - auto calibration time out (0)\n",
+ CS4231U(chip, REGSEL));
#endif
chip->mce_bit &= ~CS4231_MCE;
- timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
- __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
+ timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL));
+ __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f),
+ CS4231U(chip, REGSEL));
if (timeout == 0x80)
- snd_printdd("mce_down [%p]: serious init problem - codec still busy\n", chip->port);
+ snd_printdd("mce_down [%p]: serious init problem - "
+ "codec still busy\n",
+ chip->port);
if ((timeout & CS4231_MCE) == 0) {
spin_unlock_irqrestore(&chip->lock, flags);
return;
}
- snd_cs4231_busy_wait(chip);
- /* calibration process */
+ /*
+ * Wait for (possible -- during init auto-calibration may not be set)
+ * calibration process to start. Needs upto 5 sample periods on AD1848
+ * which at the slowest possible rate of 5.5125 kHz means 907 us.
+ */
+ msleep(1);
- for (timeout = 500; timeout > 0 && (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0; timeout--)
- udelay(100);
- if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) {
- snd_printd("cs4231_mce_down - auto calibration time out (1)\n");
- spin_unlock_irqrestore(&chip->lock, flags);
- return;
- }
+ /* check condition up to 250ms */
+ end_time = jiffies + msecs_to_jiffies(250);
+ while (snd_cs4231_in(chip, CS4231_TEST_INIT) &
+ CS4231_CALIB_IN_PROGRESS) {
- /* in 10ms increments, check condition, up to 250ms */
- timeout = 25;
- while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
spin_unlock_irqrestore(&chip->lock, flags);
- if (--timeout < 0) {
- snd_printk("mce_down - auto calibration time out (2)\n");
+ if (time_after(jiffies, end_time)) {
+ snd_printk("mce_down - "
+ "auto calibration time out (2)\n");
return;
}
- msleep(10);
+ msleep(1);
spin_lock_irqsave(&chip->lock, flags);
}
- /* in 10ms increments, check condition, up to 100ms */
- timeout = 10;
- while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) {
+ /* check condition up to 100ms */
+ end_time = jiffies + msecs_to_jiffies(100);
+ while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) {
spin_unlock_irqrestore(&chip->lock, flags);
- if (--timeout < 0) {
- snd_printk("mce_down - auto calibration time out (3)\n");
+ if (time_after(jiffies, end_time)) {
+ snd_printk("mce_down - "
+ "auto calibration time out (3)\n");
return;
}
- msleep(10);
+ msleep(1);
spin_lock_irqsave(&chip->lock, flags);
}
spin_unlock_irqrestore(&chip->lock, flags);
@@ -611,7 +473,8 @@ static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont,
BUG_ON(period_size >= (1 << 24));
- if (dma_cont->request(dma_cont, runtime->dma_addr + offset, period_size))
+ if (dma_cont->request(dma_cont,
+ runtime->dma_addr + offset, period_size))
return;
(*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
}
@@ -704,21 +567,32 @@ static unsigned char snd_cs4231_get_rate(unsigned int rate)
for (i = 0; i < 14; i++)
if (rate == rates[i])
return freq_bits[i];
- // snd_BUG();
+
return freq_bits[13];
}
-static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format, int channels)
+static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format,
+ int channels)
{
unsigned char rformat;
rformat = CS4231_LINEAR_8;
switch (format) {
- case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break;
- case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break;
- case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break;
- case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break;
- case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break;
+ case SNDRV_PCM_FORMAT_MU_LAW:
+ rformat = CS4231_ULAW_8;
+ break;
+ case SNDRV_PCM_FORMAT_A_LAW:
+ rformat = CS4231_ALAW_8;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ rformat = CS4231_LINEAR_16;
+ break;
+ case SNDRV_PCM_FORMAT_S16_BE:
+ rformat = CS4231_LINEAR_16_BIG;
+ break;
+ case SNDRV_PCM_FORMAT_IMA_ADPCM:
+ rformat = CS4231_ADPCM_16;
+ break;
}
if (channels > 1)
rformat |= CS4231_STEREO;
@@ -765,7 +639,8 @@ static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
spin_unlock_irqrestore(&chip->lock, flags);
}
-static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params,
+static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
+ struct snd_pcm_hw_params *params,
unsigned char pdfr)
{
unsigned long flags;
@@ -788,8 +663,9 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_h
mutex_unlock(&chip->mce_mutex);
}
-static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params,
- unsigned char cdfr)
+static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
+ struct snd_pcm_hw_params *params,
+ unsigned char cdfr)
{
unsigned long flags;
@@ -846,7 +722,8 @@ static int snd_cs4231_timer_start(struct snd_timer *timer)
chip->image[CS4231_TIMER_LOW] =
(unsigned char) ticks);
snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] | CS4231_TIMER_ENABLE);
+ chip->image[CS4231_ALT_FEATURE_1] |
+ CS4231_TIMER_ENABLE);
}
spin_unlock_irqrestore(&chip->lock, flags);
@@ -859,8 +736,9 @@ static int snd_cs4231_timer_stop(struct snd_timer *timer)
struct snd_cs4231 *chip = snd_timer_chip(timer);
spin_lock_irqsave(&chip->lock, flags);
+ chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
- chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE);
+ chip->image[CS4231_ALT_FEATURE_1]);
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -877,8 +755,10 @@ static void __init snd_cs4231_init(struct snd_cs4231 *chip)
#endif
snd_cs4231_mce_up(chip);
spin_lock_irqsave(&chip->lock, flags);
- chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
- CS4231_RECORD_ENABLE | CS4231_RECORD_PIO |
+ chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
+ CS4231_PLAYBACK_PIO |
+ CS4231_RECORD_ENABLE |
+ CS4231_RECORD_PIO |
CS4231_CALIB_MODE);
chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
@@ -891,21 +771,25 @@ static void __init snd_cs4231_init(struct snd_cs4231 *chip)
snd_cs4231_mce_up(chip);
spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
+ snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
+ chip->image[CS4231_ALT_FEATURE_1]);
spin_unlock_irqrestore(&chip->lock, flags);
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
+ snd_printdd("init: (3) - afei = 0x%x\n",
+ chip->image[CS4231_ALT_FEATURE_1]);
#endif
spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_ALT_FEATURE_2, chip->image[CS4231_ALT_FEATURE_2]);
+ snd_cs4231_out(chip, CS4231_ALT_FEATURE_2,
+ chip->image[CS4231_ALT_FEATURE_2]);
spin_unlock_irqrestore(&chip->lock, flags);
snd_cs4231_mce_up(chip);
spin_lock_irqsave(&chip->lock, flags);
- snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT, chip->image[CS4231_PLAYBK_FORMAT]);
+ snd_cs4231_out(chip, CS4231_PLAYBK_FORMAT,
+ chip->image[CS4231_PLAYBK_FORMAT]);
spin_unlock_irqrestore(&chip->lock, flags);
snd_cs4231_mce_down(chip);
@@ -944,8 +828,8 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
CS4231_RECORD_IRQ |
CS4231_TIMER_IRQ);
snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ |
CS4231_RECORD_IRQ |
@@ -974,8 +858,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
/* disable IRQ */
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
/* now disable record & playback */
@@ -988,7 +872,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
chip->image[CS4231_IFACE_CTRL] &=
~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
- snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
+ snd_cs4231_out(chip, CS4231_IFACE_CTRL,
+ chip->image[CS4231_IFACE_CTRL]);
spin_unlock_irqrestore(&chip->lock, flags);
snd_cs4231_mce_down(chip);
spin_lock_irqsave(&chip->lock, flags);
@@ -996,8 +881,8 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
/* clear IRQ again */
snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS)); /* clear IRQ */
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS)); /* clear IRQ */
spin_unlock_irqrestore(&chip->lock, flags);
snd_cs4231_calibrate_mute(chip, 0);
@@ -1017,15 +902,14 @@ static int snd_cs4231_timer_open(struct snd_timer *timer)
return 0;
}
-static int snd_cs4231_timer_close(struct snd_timer * timer)
+static int snd_cs4231_timer_close(struct snd_timer *timer)
{
struct snd_cs4231 *chip = snd_timer_chip(timer);
snd_cs4231_close(chip, CS4231_MODE_TIMER);
return 0;
}
-static struct snd_timer_hardware snd_cs4231_timer_table =
-{
+static struct snd_timer_hardware snd_cs4231_timer_table = {
.flags = SNDRV_TIMER_HW_AUTO,
.resolution = 9945,
.ticks = 65535,
@@ -1047,8 +931,9 @@ static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
unsigned char new_pdfr;
int err;
- if ((err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params))) < 0)
+ err = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (err < 0)
return err;
new_pdfr = snd_cs4231_get_format(chip, params_format(hw_params),
params_channels(hw_params)) |
@@ -1058,11 +943,6 @@ static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
{
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
@@ -1089,8 +969,9 @@ static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
unsigned char new_cdfr;
int err;
- if ((err = snd_pcm_lib_malloc_pages(substream,
- params_buffer_bytes(hw_params))) < 0)
+ err = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (err < 0)
return err;
new_cdfr = snd_cs4231_get_format(chip, params_format(hw_params),
params_channels(hw_params)) |
@@ -1100,11 +981,6 @@ static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
{
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
@@ -1130,7 +1006,8 @@ static void snd_cs4231_overrange(struct snd_cs4231 *chip)
res = snd_cs4231_in(chip, CS4231_TEST_INIT);
spin_unlock_irqrestore(&chip->lock, flags);
- if (res & (0x08 | 0x02)) /* detect overrange only above 0dB; may be user selectable? */
+ /* detect overrange only above 0dB; may be user selectable? */
+ if (res & (0x08 | 0x02))
chip->capture_substream->runtime->overrange++;
}
@@ -1152,51 +1029,50 @@ static void snd_cs4231_capture_callback(struct snd_cs4231 *chip)
}
}
-static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t snd_cs4231_playback_pointer(
+ struct snd_pcm_substream *substream)
{
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
struct cs4231_dma_control *dma_cont = &chip->p_dma;
size_t ptr;
-
+
if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
return 0;
ptr = dma_cont->address(dma_cont);
if (ptr != 0)
ptr -= substream->runtime->dma_addr;
-
+
return bytes_to_frames(substream->runtime, ptr);
}
-static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t snd_cs4231_capture_pointer(
+ struct snd_pcm_substream *substream)
{
struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
struct cs4231_dma_control *dma_cont = &chip->c_dma;
size_t ptr;
-
+
if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
return 0;
ptr = dma_cont->address(dma_cont);
if (ptr != 0)
ptr -= substream->runtime->dma_addr;
-
+
return bytes_to_frames(substream->runtime, ptr);
}
-/*
-
- */
-
static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
{
unsigned long flags;
- int i, id, vers;
+ int i;
+ int id = 0;
+ int vers = 0;
unsigned char *ptr;
- id = vers = 0;
for (i = 0; i < 50; i++) {
mb();
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- udelay(2000);
+ if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT)
+ msleep(2);
else {
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_out(chip, CS4231_MISC_INFO, CS4231_MODE2);
@@ -1213,8 +1089,9 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
spin_lock_irqsave(&chip->lock, flags);
- __cs4231_readb(chip, CS4231P(chip, STATUS)); /* clear any pendings IRQ */
- __cs4231_writeb(chip, 0, CS4231P(chip, STATUS));
+ /* clear any pendings IRQ */
+ __cs4231_readb(chip, CS4231U(chip, STATUS));
+ __cs4231_writeb(chip, 0, CS4231U(chip, STATUS));
mb();
spin_unlock_irqrestore(&chip->lock, flags);
@@ -1247,42 +1124,50 @@ static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
return 0; /* all things are ok.. */
}
-static struct snd_pcm_hardware snd_cs4231_playback =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE),
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
+static struct snd_pcm_hardware snd_cs4231_playback = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START,
+ .formats = SNDRV_PCM_FMTBIT_MU_LAW |
+ SNDRV_PCM_FMTBIT_A_LAW |
+ SNDRV_PCM_FMTBIT_IMA_ADPCM |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE,
+ .rates = SNDRV_PCM_RATE_KNOT |
+ SNDRV_PCM_RATE_8000_48000,
.rate_min = 5510,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = (32*1024),
+ .buffer_bytes_max = 32 * 1024,
.period_bytes_min = 64,
- .period_bytes_max = (32*1024),
+ .period_bytes_max = 32 * 1024,
.periods_min = 1,
.periods_max = 1024,
};
-static struct snd_pcm_hardware snd_cs4231_capture =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
- .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_IMA_ADPCM |
- SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S16_BE),
- .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
+static struct snd_pcm_hardware snd_cs4231_capture = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START,
+ .formats = SNDRV_PCM_FMTBIT_MU_LAW |
+ SNDRV_PCM_FMTBIT_A_LAW |
+ SNDRV_PCM_FMTBIT_IMA_ADPCM |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S16_BE,
+ .rates = SNDRV_PCM_RATE_KNOT |
+ SNDRV_PCM_RATE_8000_48000,
.rate_min = 5510,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = (32*1024),
+ .buffer_bytes_max = 32 * 1024,
.period_bytes_min = 64,
- .period_bytes_max = (32*1024),
+ .period_bytes_max = 32 * 1024,
.periods_min = 1,
.periods_max = 1024,
};
@@ -1295,7 +1180,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
runtime->hw = snd_cs4231_playback;
- if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) {
+ err = snd_cs4231_open(chip, CS4231_MODE_PLAY);
+ if (err < 0) {
snd_free_pages(runtime->dma_area, runtime->dma_bytes);
return err;
}
@@ -1315,7 +1201,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
runtime->hw = snd_cs4231_capture;
- if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) {
+ err = snd_cs4231_open(chip, CS4231_MODE_RECORD);
+ if (err < 0) {
snd_free_pages(runtime->dma_area, runtime->dma_bytes);
return err;
}
@@ -1356,7 +1243,7 @@ static struct snd_pcm_ops snd_cs4231_playback_ops = {
.close = snd_cs4231_playback_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cs4231_playback_hw_params,
- .hw_free = snd_cs4231_playback_hw_free,
+ .hw_free = snd_pcm_lib_free_pages,
.prepare = snd_cs4231_playback_prepare,
.trigger = snd_cs4231_trigger,
.pointer = snd_cs4231_playback_pointer,
@@ -1367,23 +1254,27 @@ static struct snd_pcm_ops snd_cs4231_capture_ops = {
.close = snd_cs4231_capture_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cs4231_capture_hw_params,
- .hw_free = snd_cs4231_capture_hw_free,
+ .hw_free = snd_pcm_lib_free_pages,
.prepare = snd_cs4231_capture_prepare,
.trigger = snd_cs4231_trigger,
.pointer = snd_cs4231_capture_pointer,
};
-static int __init snd_cs4231_pcm(struct snd_cs4231 *chip)
+static int __init snd_cs4231_pcm(struct snd_card *card)
{
+ struct snd_cs4231 *chip = card->private_data;
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(chip->card, "CS4231", 0, 1, 1, &pcm)) < 0)
+ err = snd_pcm_new(card, "CS4231", 0, 1, 1, &pcm);
+ if (err < 0)
return err;
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops);
-
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_cs4231_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &snd_cs4231_capture_ops);
+
/* global setup */
pcm->private_data = chip;
pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
@@ -1396,8 +1287,9 @@ static int __init snd_cs4231_pcm(struct snd_cs4231 *chip)
return 0;
}
-static int __init snd_cs4231_timer(struct snd_cs4231 *chip)
+static int __init snd_cs4231_timer(struct snd_card *card)
{
+ struct snd_cs4231 *chip = card->private_data;
struct snd_timer *timer;
struct snd_timer_id tid;
int err;
@@ -1405,10 +1297,11 @@ static int __init snd_cs4231_timer(struct snd_cs4231 *chip)
/* Timer initialization */
tid.dev_class = SNDRV_TIMER_CLASS_CARD;
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
- tid.card = chip->card->number;
+ tid.card = card->number;
tid.device = 0;
tid.subdevice = 0;
- if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
+ err = snd_timer_new(card, "CS4231", &tid, &timer);
+ if (err < 0)
return err;
strcpy(timer->name, "CS4231");
timer->private_data = chip;
@@ -1417,7 +1310,7 @@ static int __init snd_cs4231_timer(struct snd_cs4231 *chip)
return 0;
}
-
+
/*
* MIXER part
*/
@@ -1428,15 +1321,14 @@ static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol,
static char *texts[4] = {
"Line", "CD", "Mic", "Mix"
};
- struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
- snd_assert(chip->card != NULL, return -EINVAL);
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 2;
uinfo->value.enumerated.items = 4;
if (uinfo->value.enumerated.item > 3)
uinfo->value.enumerated.item = 3;
- strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+ strcpy(uinfo->value.enumerated.name,
+ texts[uinfo->value.enumerated.item]);
return 0;
}
@@ -1446,7 +1338,7 @@ static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol,
{
struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
unsigned long flags;
-
+
spin_lock_irqsave(&chip->lock, flags);
ucontrol->value.enumerated.item[0] =
(chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
@@ -1464,7 +1356,7 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
unsigned long flags;
unsigned short left, right;
int change;
-
+
if (ucontrol->value.enumerated.item[0] > 3 ||
ucontrol->value.enumerated.item[1] > 3)
return -EINVAL;
@@ -1476,7 +1368,7 @@ static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
change = left != chip->image[CS4231_LEFT_INPUT] ||
- right != chip->image[CS4231_RIGHT_INPUT];
+ right != chip->image[CS4231_RIGHT_INPUT];
snd_cs4231_out(chip, CS4231_LEFT_INPUT, left);
snd_cs4231_out(chip, CS4231_RIGHT_INPUT, right);
@@ -1508,7 +1400,7 @@ static int snd_cs4231_get_single(struct snd_kcontrol *kcontrol,
int shift = (kcontrol->private_value >> 8) & 0xff;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0xff;
-
+
spin_lock_irqsave(&chip->lock, flags);
ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
@@ -1533,7 +1425,7 @@ static int snd_cs4231_put_single(struct snd_kcontrol *kcontrol,
int invert = (kcontrol->private_value >> 24) & 0xff;
int change;
unsigned short val;
-
+
val = (ucontrol->value.integer.value[0] & mask);
if (invert)
val = mask - val;
@@ -1575,11 +1467,13 @@ static int snd_cs4231_get_double(struct snd_kcontrol *kcontrol,
int shift_right = (kcontrol->private_value >> 19) & 0x07;
int mask = (kcontrol->private_value >> 24) & 0xff;
int invert = (kcontrol->private_value >> 22) & 1;
-
+
spin_lock_irqsave(&chip->lock, flags);
- ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
- ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
+ ucontrol->value.integer.value[0] =
+ (chip->image[left_reg] >> shift_left) & mask;
+ ucontrol->value.integer.value[1] =
+ (chip->image[right_reg] >> shift_right) & mask;
spin_unlock_irqrestore(&chip->lock, flags);
@@ -1606,7 +1500,7 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
int invert = (kcontrol->private_value >> 22) & 1;
int change;
unsigned short val1, val2;
-
+
val1 = ucontrol->value.integer.value[0] & mask;
val2 = ucontrol->value.integer.value[1] & mask;
if (invert) {
@@ -1620,7 +1514,8 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
- change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
+ change = val1 != chip->image[left_reg];
+ change |= val2 != chip->image[right_reg];
snd_cs4231_out(chip, left_reg, val1);
snd_cs4231_out(chip, right_reg, val2);
@@ -1630,31 +1525,42 @@ static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
}
#define CS4231_SINGLE(xname, xindex, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4231_info_single, \
- .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
- .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
-
-#define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
- .info = snd_cs4231_info_double, \
- .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
- .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .index = (xindex), \
+ .info = snd_cs4231_info_single, \
+ .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
+ .private_value = (reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24) }
+
+#define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, \
+ shift_right, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .index = (xindex), \
+ .info = snd_cs4231_info_double, \
+ .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
+ .private_value = (left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | \
+ ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22) }
static struct snd_kcontrol_new snd_cs4231_controls[] __initdata = {
-CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
-CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
-CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
-CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
-CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
+CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT,
+ CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
+CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT,
+ CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
+CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN,
+ CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
+CS4231_DOUBLE("Line Playback Volume", 0, CS4231_LEFT_LINE_IN,
+ CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
+CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT,
+ CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
+CS4231_DOUBLE("Aux Playback Volume", 0, CS4231_AUX1_LEFT_INPUT,
+ CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
+CS4231_DOUBLE("Aux Playback Switch", 1, CS4231_AUX2_LEFT_INPUT,
+ CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
+CS4231_DOUBLE("Aux Playback Volume", 1, CS4231_AUX2_LEFT_INPUT,
+ CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
CS4231_SINGLE("Mono Playback Switch", 0, CS4231_MONO_CTRL, 7, 1, 1),
CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
CS4231_SINGLE("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 6, 1, 1),
CS4231_SINGLE("Mono Output Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
-CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
+CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0,
+ 15, 0),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Source",
@@ -1662,29 +1568,28 @@ CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0,
.get = snd_cs4231_get_mux,
.put = snd_cs4231_put_mux,
},
-CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
+CS4231_DOUBLE("Mic Boost", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5,
+ 1, 0),
CS4231_SINGLE("Loopback Capture Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1),
/* SPARC specific uses of XCTL{0,1} general purpose outputs. */
CS4231_SINGLE("Line Out Switch", 0, CS4231_PIN_CTRL, 6, 1, 1),
CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1)
};
-
-static int __init snd_cs4231_mixer(struct snd_cs4231 *chip)
+
+static int __init snd_cs4231_mixer(struct snd_card *card)
{
- struct snd_card *card;
+ struct snd_cs4231 *chip = card->private_data;
int err, idx;
snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
- card = chip->card;
-
strcpy(card->mixername, chip->pcm->name);
for (idx = 0; idx < ARRAY_SIZE(snd_cs4231_controls); idx++) {
- if ((err = snd_ctl_add(card,
- snd_ctl_new1(&snd_cs4231_controls[idx],
- chip))) < 0)
+ err = snd_ctl_add(card,
+ snd_ctl_new1(&snd_cs4231_controls[idx], chip));
+ if (err < 0)
return err;
}
return 0;
@@ -1695,6 +1600,7 @@ static int dev;
static int __init cs4231_attach_begin(struct snd_card **rcard)
{
struct snd_card *card;
+ struct snd_cs4231 *chip;
*rcard = NULL;
@@ -1706,31 +1612,40 @@ static int __init cs4231_attach_begin(struct snd_card **rcard)
return -ENOENT;
}
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+ sizeof(struct snd_cs4231));
if (card == NULL)
return -ENOMEM;
strcpy(card->driver, "CS4231");
strcpy(card->shortname, "Sun CS4231");
+ chip = card->private_data;
+ chip->card = card;
+
*rcard = card;
return 0;
}
-static int __init cs4231_attach_finish(struct snd_card *card, struct snd_cs4231 *chip)
+static int __init cs4231_attach_finish(struct snd_card *card)
{
+ struct snd_cs4231 *chip = card->private_data;
int err;
- if ((err = snd_cs4231_pcm(chip)) < 0)
+ err = snd_cs4231_pcm(card);
+ if (err < 0)
goto out_err;
- if ((err = snd_cs4231_mixer(chip)) < 0)
+ err = snd_cs4231_mixer(card);
+ if (err < 0)
goto out_err;
- if ((err = snd_cs4231_timer(chip)) < 0)
+ err = snd_cs4231_timer(card);
+ if (err < 0)
goto out_err;
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto out_err;
chip->next = cs4231_list;
@@ -1754,7 +1669,7 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
struct snd_cs4231 *chip = dev_id;
/*This is IRQ is not raised by the cs4231*/
- if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
+ if (!(__cs4231_readb(chip, CS4231U(chip, STATUS)) & CS4231_GLOBALIRQ))
return IRQ_NONE;
/* ACK the APC interrupt. */
@@ -1762,24 +1677,24 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
sbus_writel(csr, chip->port + APCCSR);
- if ((csr & APC_PDMA_READY) &&
- (csr & APC_PLAY_INT) &&
+ if ((csr & APC_PDMA_READY) &&
+ (csr & APC_PLAY_INT) &&
(csr & APC_XINT_PNVA) &&
!(csr & APC_XINT_EMPT))
snd_cs4231_play_callback(chip);
- if ((csr & APC_CDMA_READY) &&
- (csr & APC_CAPT_INT) &&
+ if ((csr & APC_CDMA_READY) &&
+ (csr & APC_CAPT_INT) &&
(csr & APC_XINT_CNVA) &&
!(csr & APC_XINT_EMPT))
snd_cs4231_capture_callback(chip);
-
+
status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
if (status & CS4231_TIMER_IRQ) {
if (chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
- }
+ }
if ((status & CS4231_RECORD_IRQ) && (csr & APC_CDMA_READY))
snd_cs4231_overrange(chip);
@@ -1796,26 +1711,27 @@ static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id)
* SBUS DMA routines
*/
-static int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
+static int sbus_dma_request(struct cs4231_dma_control *dma_cont,
+ dma_addr_t bus_addr, size_t len)
{
unsigned long flags;
u32 test, csr;
int err;
struct sbus_dma_info *base = &dma_cont->sbus_info;
-
+
if (len >= (1 << 24))
return -EINVAL;
spin_lock_irqsave(&base->lock, flags);
csr = sbus_readl(base->regs + APCCSR);
err = -EINVAL;
test = APC_CDMA_READY;
- if ( base->dir == APC_PLAY )
+ if (base->dir == APC_PLAY)
test = APC_PDMA_READY;
if (!(csr & test))
goto out;
err = -EBUSY;
test = APC_XINT_CNVA;
- if ( base->dir == APC_PLAY )
+ if (base->dir == APC_PLAY)
test = APC_XINT_PNVA;
if (!(csr & test))
goto out;
@@ -1838,7 +1754,7 @@ static void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
test = APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
APC_XINT_PLAY | APC_XINT_PEMP | APC_XINT_GENL |
APC_XINT_PENA;
- if ( base->dir == APC_RECORD )
+ if (base->dir == APC_RECORD)
test = APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL;
csr |= test;
@@ -1856,28 +1772,28 @@ static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
if (!on) {
sbus_writel(0, base->regs + base->dir + APCNC);
sbus_writel(0, base->regs + base->dir + APCNVA);
- if ( base->dir == APC_PLAY ) {
+ if (base->dir == APC_PLAY) {
sbus_writel(0, base->regs + base->dir + APCC);
sbus_writel(0, base->regs + base->dir + APCVA);
}
udelay(1200);
- }
+ }
csr = sbus_readl(base->regs + APCCSR);
shift = 0;
- if ( base->dir == APC_PLAY )
+ if (base->dir == APC_PLAY)
shift = 1;
if (on)
csr &= ~(APC_CPAUSE << shift);
else
- csr |= (APC_CPAUSE << shift);
+ csr |= (APC_CPAUSE << shift);
sbus_writel(csr, base->regs + APCCSR);
if (on)
csr |= (APC_CDMA_READY << shift);
else
csr &= ~(APC_CDMA_READY << shift);
sbus_writel(csr, base->regs + APCCSR);
-
+
spin_unlock_irqrestore(&base->lock, flags);
}
@@ -1885,14 +1801,14 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
{
struct sbus_dma_info *base = &dma_cont->sbus_info;
- return sbus_readl(base->regs + base->dir + APCVA);
+ return sbus_readl(base->regs + base->dir + APCVA);
}
static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
{
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
- snd_dma_sbus_data(chip->dev_u.sdev),
- 64*1024, 128*1024);
+ snd_dma_sbus_data(chip->dev_u.sdev),
+ 64 * 1024, 128 * 1024);
}
/*
@@ -1907,8 +1823,6 @@ static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
if (chip->port)
sbus_iounmap(chip->port, chip->regs_size);
- kfree(chip);
-
return 0;
}
@@ -1925,23 +1839,16 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
static int __init snd_cs4231_sbus_create(struct snd_card *card,
struct sbus_dev *sdev,
- int dev,
- struct snd_cs4231 **rchip)
+ int dev)
{
- struct snd_cs4231 *chip;
+ struct snd_cs4231 *chip = card->private_data;
int err;
- *rchip = NULL;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
spin_lock_init(&chip->lock);
spin_lock_init(&chip->c_dma.sbus_info.lock);
spin_lock_init(&chip->p_dma.sbus_info.lock);
mutex_init(&chip->mce_mutex);
mutex_init(&chip->open_mutex);
- chip->card = card;
chip->dev_u.sdev = sdev;
chip->regs_size = sdev->reg_addrs[0].reg_size;
memcpy(&chip->image, &snd_cs4231_original_image,
@@ -1992,14 +1899,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
return err;
}
- *rchip = chip;
return 0;
}
static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
{
struct resource *rp = &sdev->resource[0];
- struct snd_cs4231 *cp;
struct snd_card *card;
int err;
@@ -2013,25 +1918,28 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
(unsigned long long)rp->start,
sdev->irqs[0]);
- if ((err = snd_cs4231_sbus_create(card, sdev, dev, &cp)) < 0) {
+ err = snd_cs4231_sbus_create(card, sdev, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- return cs4231_attach_finish(card, cp);
+ return cs4231_attach_finish(card);
}
#endif
#ifdef EBUS_SUPPORT
-static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie)
+static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event,
+ void *cookie)
{
struct snd_cs4231 *chip = cookie;
-
+
snd_cs4231_play_callback(chip);
}
-static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie)
+static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p,
+ int event, void *cookie)
{
struct snd_cs4231 *chip = cookie;
@@ -2042,7 +1950,8 @@ static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event,
* EBUS DMA wrappers
*/
-static int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
+static int _ebus_dma_request(struct cs4231_dma_control *dma_cont,
+ dma_addr_t bus_addr, size_t len)
{
return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len);
}
@@ -2087,8 +1996,6 @@ static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
if (chip->port)
iounmap(chip->port);
- kfree(chip);
-
return 0;
}
@@ -2105,24 +2012,17 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
static int __init snd_cs4231_ebus_create(struct snd_card *card,
struct linux_ebus_device *edev,
- int dev,
- struct snd_cs4231 **rchip)
+ int dev)
{
- struct snd_cs4231 *chip;
+ struct snd_cs4231 *chip = card->private_data;
int err;
- *rchip = NULL;
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
spin_lock_init(&chip->lock);
spin_lock_init(&chip->c_dma.ebus_info.lock);
spin_lock_init(&chip->p_dma.ebus_info.lock);
mutex_init(&chip->mce_mutex);
mutex_init(&chip->open_mutex);
chip->flags |= CS4231_FLAG_EBUS;
- chip->card = card;
chip->dev_u.pdev = edev->bus->self;
memcpy(&chip->image, &snd_cs4231_original_image,
sizeof(snd_cs4231_original_image));
@@ -2152,7 +2052,8 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
chip->port = ioremap(edev->resource[0].start, 0x10);
chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10);
chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10);
- if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) {
+ if (!chip->port || !chip->p_dma.ebus_info.regs ||
+ !chip->c_dma.ebus_info.regs) {
snd_cs4231_ebus_free(chip);
snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
return -EIO;
@@ -2160,18 +2061,21 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
if (ebus_dma_register(&chip->c_dma.ebus_info)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
+ snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n",
+ dev);
return -EBUSY;
}
if (ebus_dma_irq_enable(&chip->c_dma.ebus_info, 1)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
+ snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n",
+ dev);
return -EBUSY;
}
if (ebus_dma_register(&chip->p_dma.ebus_info)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev);
+ snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n",
+ dev);
return -EBUSY;
}
if (ebus_dma_irq_enable(&chip->p_dma.ebus_info, 1)) {
@@ -2192,14 +2096,12 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
return err;
}
- *rchip = chip;
return 0;
}
static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
{
struct snd_card *card;
- struct snd_cs4231 *chip;
int err;
err = cs4231_attach_begin(&card);
@@ -2211,12 +2113,13 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
edev->resource[0].start,
edev->irqs[0]);
- if ((err = snd_cs4231_ebus_create(card, edev, dev, &chip)) < 0) {
+ err = snd_cs4231_ebus_create(card, edev, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
- return cs4231_attach_finish(card, chip);
+ return cs4231_attach_finish(card);
}
#endif
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index e07085a7cfc..376b98691c9 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -8,18 +8,18 @@
* Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
* Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org)
*
- * This is the lowlevel driver for the DBRI & MMCODEC duo used for ISDN & AUDIO
- * on Sun SPARCstation 10, 20, LX and Voyager models.
+ * This is the low level driver for the DBRI & MMCODEC duo used for ISDN & AUDIO
+ * on Sun SPARCStation 10, 20, LX and Voyager models.
*
* - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel
* data time multiplexer with ISDN support (aka T7259)
* Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel.
* CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?).
* Documentation:
- * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Tranceiver" from
+ * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Transceiver" from
* Sparc Technology Business (courtesy of Sun Support)
* - Data sheet of the T7903, a newer but very similar ISA bus equivalent
- * available from the Lucent (formarly AT&T microelectronics) home
+ * available from the Lucent (formerly AT&T microelectronics) home
* page.
* - http://www.freesoft.org/Linux/DBRI/
* - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec
@@ -27,21 +27,21 @@
* Documentation: from the Crystal Semiconductor home page.
*
* The DBRI is a 32 pipe machine, each pipe can transfer some bits between
- * memory and a serial device (long pipes, nr 0-15) or between two serial
- * devices (short pipes, nr 16-31), or simply send a fixed data to a serial
+ * memory and a serial device (long pipes, no. 0-15) or between two serial
+ * devices (short pipes, no. 16-31), or simply send a fixed data to a serial
* device (short pipes).
- * A timeslot defines the bit-offset and nr of bits read from a serial device.
+ * A timeslot defines the bit-offset and no. of bits read from a serial device.
* The timeslots are linked to 6 circular lists, one for each direction for
* each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes
* (the second one is a monitor/tee pipe, valid only for serial input).
*
* The mmcodec is connected via the CHI bus and needs the data & some
- * parameters (volume, output selection) timemultiplexed in 8 byte
+ * parameters (volume, output selection) time multiplexed in 8 byte
* chunks. It also has a control mode, which serves for audio format setting.
*
* Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on
- * the same CHI bus, so I thought perhaps it is possible to use the onboard
- * & the speakerbox codec simultanously, giving 2 (not very independent :-)
+ * the same CHI bus, so I thought perhaps it is possible to use the on-board
+ * & the speakerbox codec simultaneously, giving 2 (not very independent :-)
* audio devices. But the SUN HW group decided against it, at least on my
* LX the speakerbox connector has at least 1 pin missing and 1 wrongly
* connected.
@@ -56,6 +56,8 @@
#include <sound/driver.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/io.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -64,8 +66,7 @@
#include <sound/control.h>
#include <sound/initval.h>
-#include <asm/irq.h>
-#include <asm/io.h>
+#include <linux/of.h>
#include <asm/sbus.h>
#include <asm/atomic.h>
@@ -76,7 +77,8 @@ MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+/* Enable this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard.");
@@ -104,7 +106,7 @@ static char *cmds[] = {
"SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV"
};
-#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
+#define dprintk(a, x...) if (dbri_debug & a) printk(KERN_DEBUG x)
#else
#define dprintk(a, x...) do { } while (0)
@@ -131,7 +133,7 @@ struct cs4215 {
};
/*
- * Control mode first
+ * Control mode first
*/
/* Time Slot 1, Status register */
@@ -219,7 +221,7 @@ static struct {
/* Time Slot 7, Input Setting */
#define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */
#define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */
-#define CS4215_OVR (1<<5) /* 1: Overrange condition occurred */
+#define CS4215_OVR (1<<5) /* 1: Over range condition occurred */
#define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */
#define CS4215_PIO1 (1<<7)
@@ -232,12 +234,12 @@ static struct {
****************************************************************************/
/* DBRI main registers */
-#define REG0 0x00UL /* Status and Control */
-#define REG1 0x04UL /* Mode and Interrupt */
-#define REG2 0x08UL /* Parallel IO */
-#define REG3 0x0cUL /* Test */
-#define REG8 0x20UL /* Command Queue Pointer */
-#define REG9 0x24UL /* Interrupt Queue Pointer */
+#define REG0 0x00 /* Status and Control */
+#define REG1 0x04 /* Mode and Interrupt */
+#define REG2 0x08 /* Parallel IO */
+#define REG3 0x0c /* Test */
+#define REG8 0x20 /* Command Queue Pointer */
+#define REG9 0x24 /* Interrupt Queue Pointer */
#define DBRI_NO_CMDS 64
#define DBRI_INT_BLK 64
@@ -285,7 +287,7 @@ struct dbri_pipe {
/* Per stream (playback or record) information */
struct dbri_streaminfo {
struct snd_pcm_substream *substream;
- u32 dvma_buffer; /* Device view of Alsa DMA buffer */
+ u32 dvma_buffer; /* Device view of ALSA DMA buffer */
int size; /* Size of DMA buffer */
size_t offset; /* offset in user buffer */
int pipe; /* Data pipe used */
@@ -295,8 +297,6 @@ struct dbri_streaminfo {
/* This structure holds the information for both chips (DBRI & CS4215) */
struct snd_dbri {
- struct snd_card *card; /* ALSA card */
-
int regs_size, irq; /* Needed for unload */
struct sbus_dev *sdev; /* SBUS device info */
spinlock_t lock;
@@ -317,8 +317,6 @@ struct snd_dbri {
struct cs4215 mm; /* mmcodec special info */
/* per stream (playback/record) info */
struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
-
- struct snd_dbri *next;
};
#define DBRI_MAX_VOLUME 63 /* Output volume */
@@ -341,11 +339,11 @@ struct snd_dbri {
/* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */
#define D_LITTLE_END (1<<8) /* Byte Order */
#define D_BIG_END (0<<8) /* Byte Order */
-#define D_MRR (1<<4) /* Multiple Error Ack on SBus (readonly) */
-#define D_MLE (1<<3) /* Multiple Late Error on SBus (readonly) */
-#define D_LBG (1<<2) /* Lost Bus Grant on SBus (readonly) */
-#define D_MBE (1<<1) /* Burst Error on SBus (readonly) */
-#define D_IR (1<<0) /* Interrupt Indicator (readonly) */
+#define D_MRR (1<<4) /* Multiple Error Ack on SBus (read only) */
+#define D_MLE (1<<3) /* Multiple Late Error on SBus (read only) */
+#define D_LBG (1<<2) /* Lost Bus Grant on SBus (read only) */
+#define D_MBE (1<<1) /* Burst Error on SBus (read only) */
+#define D_IR (1<<0) /* Interrupt Indicator (read only) */
/* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */
#define D_ENPIO3 (1<<7) /* Enable Pin 3 */
@@ -376,11 +374,11 @@ struct snd_dbri {
#define D_CDM 0xe /* CHI Data mode command */
/* Special bits for some commands */
-#define D_PIPE(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */
+#define D_PIPE(v) ((v)<<0) /* Pipe No.: 0-15 long, 16-21 short */
/* Setup Data Pipe */
/* IRM */
-#define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value rcvd */
+#define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value received */
#define D_SDP_CHANGE (2<<18) /* Report any changes */
#define D_SDP_EVERY (3<<18) /* Report any changes */
#define D_SDP_EOL (1<<17) /* EOL interrupt enable */
@@ -419,7 +417,7 @@ struct snd_dbri {
#define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */
#define D_TS_ANCHOR (7<<10) /* Starting short pipes */
#define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */
-#define D_TS_NEXT(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */
+#define D_TS_NEXT(v) ((v)<<0) /* Pipe no.: 0-15 long, 16-21 short */
/* Concentration Highway Interface Modes */
#define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */
@@ -435,7 +433,7 @@ struct snd_dbri {
#define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */
#define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */
#define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */
-#define D_NT_ISNT (1<<13) /* Configfure interface as NT */
+#define D_NT_ISNT (1<<13) /* Configure interface as NT */
#define D_NT_FT (1<<12) /* Fixed Timing */
#define D_NT_EZ (1<<11) /* Echo Channel is Zeros */
#define D_NT_IFA (1<<10) /* Inhibit Final Activation */
@@ -455,7 +453,7 @@ struct snd_dbri {
#define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */
#define D_TEST_SIZE(v) ((v)<<11) /* */
#define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */
-#define D_TEST_PROC 0x6 /* MicroProcessor test */
+#define D_TEST_PROC 0x6 /* Microprocessor test */
#define D_TEST_SER 0x7 /* Serial-Controller test */
#define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */
#define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */
@@ -464,12 +462,12 @@ struct snd_dbri {
#define D_TEST_DUMP 0xe /* ROM Dump */
/* CHI Data Mode */
-#define D_CDM_THI (1<<8) /* Transmit Data on CHIDR Pin */
-#define D_CDM_RHI (1<<7) /* Receive Data on CHIDX Pin */
-#define D_CDM_RCE (1<<6) /* Receive on Rising Edge of CHICK */
-#define D_CDM_XCE (1<<2) /* Transmit Data on Rising Edge of CHICK */
-#define D_CDM_XEN (1<<1) /* Transmit Highway Enable */
-#define D_CDM_REN (1<<0) /* Receive Highway Enable */
+#define D_CDM_THI (1 << 8) /* Transmit Data on CHIDR Pin */
+#define D_CDM_RHI (1 << 7) /* Receive Data on CHIDX Pin */
+#define D_CDM_RCE (1 << 6) /* Receive on Rising Edge of CHICK */
+#define D_CDM_XCE (1 << 2) /* Transmit Data on Rising Edge of CHICK */
+#define D_CDM_XEN (1 << 1) /* Transmit Highway Enable */
+#define D_CDM_REN (1 << 0) /* Receive Highway Enable */
/* The Interrupts */
#define D_INTR_BRDY 1 /* Buffer Ready for processing */
@@ -493,9 +491,9 @@ struct snd_dbri {
#define D_INTR_CHI 36
#define D_INTR_CMD 38
-#define D_INTR_GETCHAN(v) (((v)>>24) & 0x3f)
-#define D_INTR_GETCODE(v) (((v)>>20) & 0xf)
-#define D_INTR_GETCMD(v) (((v)>>16) & 0xf)
+#define D_INTR_GETCHAN(v) (((v) >> 24) & 0x3f)
+#define D_INTR_GETCODE(v) (((v) >> 20) & 0xf)
+#define D_INTR_GETCMD(v) (((v) >> 16) & 0xf)
#define D_INTR_GETVAL(v) ((v) & 0xffff)
#define D_INTR_GETRVAL(v) ((v) & 0xfffff)
@@ -533,43 +531,42 @@ struct snd_dbri {
#define D_P_31 31 /* */
/* Transmit descriptor defines */
-#define DBRI_TD_F (1<<31) /* End of Frame */
-#define DBRI_TD_D (1<<30) /* Do not append CRC */
-#define DBRI_TD_CNT(v) ((v)<<16) /* Number of valid bytes in the buffer */
-#define DBRI_TD_B (1<<15) /* Final interrupt */
-#define DBRI_TD_M (1<<14) /* Marker interrupt */
-#define DBRI_TD_I (1<<13) /* Transmit Idle Characters */
-#define DBRI_TD_FCNT(v) (v) /* Flag Count */
-#define DBRI_TD_UNR (1<<3) /* Underrun: transmitter is out of data */
-#define DBRI_TD_ABT (1<<2) /* Abort: frame aborted */
-#define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */
-#define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */
- /* Maximum buffer size per TD: almost 8Kb */
+#define DBRI_TD_F (1 << 31) /* End of Frame */
+#define DBRI_TD_D (1 << 30) /* Do not append CRC */
+#define DBRI_TD_CNT(v) ((v) << 16) /* Number of valid bytes in the buffer */
+#define DBRI_TD_B (1 << 15) /* Final interrupt */
+#define DBRI_TD_M (1 << 14) /* Marker interrupt */
+#define DBRI_TD_I (1 << 13) /* Transmit Idle Characters */
+#define DBRI_TD_FCNT(v) (v) /* Flag Count */
+#define DBRI_TD_UNR (1 << 3) /* Underrun: transmitter is out of data */
+#define DBRI_TD_ABT (1 << 2) /* Abort: frame aborted */
+#define DBRI_TD_TBC (1 << 0) /* Transmit buffer Complete */
+#define DBRI_TD_STATUS(v) ((v) & 0xff) /* Transmit status */
+ /* Maximum buffer size per TD: almost 8KB */
#define DBRI_TD_MAXCNT ((1 << 13) - 4)
/* Receive descriptor defines */
-#define DBRI_RD_F (1<<31) /* End of Frame */
-#define DBRI_RD_C (1<<30) /* Completed buffer */
-#define DBRI_RD_B (1<<15) /* Final interrupt */
-#define DBRI_RD_M (1<<14) /* Marker interrupt */
-#define DBRI_RD_BCNT(v) (v) /* Buffer size */
-#define DBRI_RD_CRC (1<<7) /* 0: CRC is correct */
-#define DBRI_RD_BBC (1<<6) /* 1: Bad Byte received */
-#define DBRI_RD_ABT (1<<5) /* Abort: frame aborted */
-#define DBRI_RD_OVRN (1<<3) /* Overrun: data lost */
-#define DBRI_RD_STATUS(v) ((v)&0xff) /* Receive status */
-#define DBRI_RD_CNT(v) (((v)>>16)&0x1fff) /* Valid bytes in the buffer */
+#define DBRI_RD_F (1 << 31) /* End of Frame */
+#define DBRI_RD_C (1 << 30) /* Completed buffer */
+#define DBRI_RD_B (1 << 15) /* Final interrupt */
+#define DBRI_RD_M (1 << 14) /* Marker interrupt */
+#define DBRI_RD_BCNT(v) (v) /* Buffer size */
+#define DBRI_RD_CRC (1 << 7) /* 0: CRC is correct */
+#define DBRI_RD_BBC (1 << 6) /* 1: Bad Byte received */
+#define DBRI_RD_ABT (1 << 5) /* Abort: frame aborted */
+#define DBRI_RD_OVRN (1 << 3) /* Overrun: data lost */
+#define DBRI_RD_STATUS(v) ((v) & 0xff) /* Receive status */
+#define DBRI_RD_CNT(v) (((v) >> 16) & 0x1fff) /* Valid bytes in the buffer */
/* stream_info[] access */
/* Translate the ALSA direction into the array index */
#define DBRI_STREAMNO(substream) \
- (substream->stream == \
- SNDRV_PCM_STREAM_PLAYBACK? DBRI_PLAY: DBRI_REC)
+ (substream->stream == \
+ SNDRV_PCM_STREAM_PLAYBACK ? DBRI_PLAY: DBRI_REC)
/* Return a pointer to dbri_streaminfo */
-#define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)]
-
-static struct snd_dbri *dbri_list; /* All DBRI devices */
+#define DBRI_STREAM(dbri, substream) \
+ &dbri->stream_info[DBRI_STREAMNO(substream)]
/*
* Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
@@ -609,21 +606,21 @@ The list is terminated with a WAIT command, which generates a
CPU interrupt to signal completion.
Since the DBRI can run in parallel with the CPU, several means of
-synchronization present themselves. The method implemented here is only
-use of the dbri_cmdwait() to wait for execution of batch of sent commands.
+synchronization present themselves. The method implemented here uses
+the dbri_cmdwait() to wait for execution of batch of sent commands.
-A circular command buffer is used here. A new command is being added
+A circular command buffer is used here. A new command is being added
while another can be executed. The scheme works by adding two WAIT commands
after each sent batch of commands. When the next batch is prepared it is
added after the WAIT commands then the WAITs are replaced with single JUMP
-command to the new batch. The the DBRI is forced to reread the last WAIT
-command (replaced by the JUMP by then). If the DBRI is still executing
+command to the new batch. The the DBRI is forced to reread the last WAIT
+command (replaced by the JUMP by then). If the DBRI is still executing
previous commands the request to reread the WAIT command is ignored.
Every time a routine wants to write commands to the DBRI, it must
-first call dbri_cmdlock() and get pointer to a free space in
-dbri->dma->cmd buffer. After this, the commands can be written to
-the buffer, and dbri_cmdsend() is called with the final pointer value
+first call dbri_cmdlock() and get pointer to a free space in
+dbri->dma->cmd buffer. After this, the commands can be written to
+the buffer, and dbri_cmdsend() is called with the final pointer value
to send them to the DBRI.
*/
@@ -646,18 +643,17 @@ static void dbri_cmdwait(struct snd_dbri *dbri)
}
spin_unlock_irqrestore(&dbri->lock, flags);
- if (maxloops == 0) {
+ if (maxloops == 0)
printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
- } else {
+ else
dprintk(D_CMD, "Chip completed command buffer (%d)\n",
MAXLOOPS - maxloops - 1);
- }
}
/*
- * Lock the command queue and returns pointer to a space for len cmd words
+ * Lock the command queue and return pointer to space for len cmd words
* It locks the cmdlock spinlock.
*/
-static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len)
+static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
{
/* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */
len += 2;
@@ -680,7 +676,7 @@ static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len)
*
* Lock must be held before calling this.
*/
-static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
+static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
{
s32 tmp, addr;
static int wait_id = 0;
@@ -700,16 +696,17 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
s32 *ptr;
for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++)
- dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
+ dprintk(D_CMD, "cmd: %lx:%08x\n",
+ (unsigned long)ptr, *ptr);
} else {
s32 *ptr = dbri->cmdptr;
dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
ptr++;
dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
- for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) {
- dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
- }
+ for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++)
+ dprintk(D_CMD, "cmd: %lx:%08x\n",
+ (unsigned long)ptr, *ptr);
}
#endif
@@ -723,7 +720,7 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
}
/* Lock must be held when calling this */
-static void dbri_reset(struct snd_dbri * dbri)
+static void dbri_reset(struct snd_dbri *dbri)
{
int i;
u32 tmp;
@@ -746,7 +743,7 @@ static void dbri_reset(struct snd_dbri * dbri)
}
/* Lock must not be held before calling this */
-static void dbri_initialize(struct snd_dbri * dbri)
+static void __devinit dbri_initialize(struct snd_dbri *dbri)
{
s32 *cmd;
u32 dma_addr;
@@ -763,7 +760,7 @@ static void dbri_initialize(struct snd_dbri * dbri)
spin_lock_init(&dbri->cmdlock);
/*
- * Initialize the interrupt ringbuffer.
+ * Initialize the interrupt ring buffer.
*/
dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
dbri->dma->intr[0] = dma_addr;
@@ -801,7 +798,7 @@ list ordering, among other things. The transmit and receive functions
here interface closely with the transmit and receive interrupt code.
*/
-static int pipe_active(struct snd_dbri * dbri, int pipe)
+static inline int pipe_active(struct snd_dbri *dbri, int pipe)
{
return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1));
}
@@ -811,20 +808,22 @@ static int pipe_active(struct snd_dbri * dbri, int pipe)
* Called on an in-use pipe to clear anything being transmitted or received
* Lock must be held before calling this.
*/
-static void reset_pipe(struct snd_dbri * dbri, int pipe)
+static void reset_pipe(struct snd_dbri *dbri, int pipe)
{
int sdp;
int desc;
s32 *cmd;
if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n");
+ printk(KERN_ERR "DBRI: reset_pipe called with "
+ "illegal pipe number\n");
return;
}
sdp = dbri->pipes[pipe].sdp;
if (sdp == 0) {
- printk(KERN_ERR "DBRI: reset_pipe called on uninitialized pipe\n");
+ printk(KERN_ERR "DBRI: reset_pipe called "
+ "on uninitialized pipe\n");
return;
}
@@ -835,9 +834,10 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe)
dbri_cmdsend(dbri, cmd, 3);
desc = dbri->pipes[pipe].first_desc;
- if ( desc >= 0)
+ if (desc >= 0)
do {
- dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0;
+ dbri->dma->desc[desc].ba = 0;
+ dbri->dma->desc[desc].nda = 0;
desc = dbri->next_desc[desc];
} while (desc != -1 && desc != dbri->pipes[pipe].first_desc);
@@ -848,15 +848,17 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe)
/*
* Lock must be held before calling this.
*/
-static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp)
+static void setup_pipe(struct snd_dbri *dbri, int pipe, int sdp)
{
if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n");
+ printk(KERN_ERR "DBRI: setup_pipe called "
+ "with illegal pipe number\n");
return;
}
if ((sdp & 0xf800) != sdp) {
- printk(KERN_ERR "DBRI: setup_pipe called with strange SDP value\n");
+ printk(KERN_ERR "DBRI: setup_pipe called "
+ "with strange SDP value\n");
/* sdp &= 0xf800; */
}
@@ -877,25 +879,26 @@ static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp)
/*
* Lock must be held before calling this.
*/
-static void link_time_slot(struct snd_dbri * dbri, int pipe,
+static void link_time_slot(struct snd_dbri *dbri, int pipe,
int prevpipe, int nextpipe,
int length, int cycle)
{
s32 *cmd;
int val;
- if (pipe < 0 || pipe > DBRI_MAX_PIPE
+ if (pipe < 0 || pipe > DBRI_MAX_PIPE
|| prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
|| nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR
+ printk(KERN_ERR
"DBRI: link_time_slot called with illegal pipe number\n");
return;
}
- if (dbri->pipes[pipe].sdp == 0
+ if (dbri->pipes[pipe].sdp == 0
|| dbri->pipes[prevpipe].sdp == 0
|| dbri->pipes[nextpipe].sdp == 0) {
- printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n");
+ printk(KERN_ERR "DBRI: link_time_slot called "
+ "on uninitialized pipe\n");
return;
}
@@ -935,17 +938,17 @@ static void link_time_slot(struct snd_dbri * dbri, int pipe,
/*
* Lock must be held before calling this.
*/
-static void unlink_time_slot(struct snd_dbri * dbri, int pipe,
+static void unlink_time_slot(struct snd_dbri *dbri, int pipe,
enum in_or_out direction, int prevpipe,
int nextpipe)
{
s32 *cmd;
int val;
- if (pipe < 0 || pipe > DBRI_MAX_PIPE
+ if (pipe < 0 || pipe > DBRI_MAX_PIPE
|| prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
|| nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR
+ printk(KERN_ERR
"DBRI: unlink_time_slot called with illegal pipe number\n");
return;
}
@@ -985,7 +988,7 @@ static void unlink_time_slot(struct snd_dbri * dbri, int pipe,
*
* Lock must not be held before calling it.
*/
-static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
+static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data)
{
s32 *cmd;
unsigned long flags;
@@ -996,7 +999,8 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
}
if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
- printk(KERN_ERR "DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: xmit_fixed: "
+ "Uninitialized pipe %d\n", pipe);
return;
}
@@ -1006,7 +1010,8 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
}
if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
- printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n",
+ pipe);
return;
}
@@ -1028,20 +1033,23 @@ static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
}
-static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr)
+static void recv_fixed(struct snd_dbri *dbri, int pipe, volatile __u32 *ptr)
{
if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
- printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n");
+ printk(KERN_ERR "DBRI: recv_fixed called with "
+ "illegal pipe number\n");
return;
}
if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
- printk(KERN_ERR "DBRI: recv_fixed called on non-fixed pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: recv_fixed called on "
+ "non-fixed pipe %d\n", pipe);
return;
}
if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
- printk(KERN_ERR "DBRI: recv_fixed called on transmit pipe %d\n", pipe);
+ printk(KERN_ERR "DBRI: recv_fixed called on "
+ "transmit pipe %d\n", pipe);
return;
}
@@ -1064,7 +1072,7 @@ static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr)
*
* Lock must be held before calling this.
*/
-static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period)
+static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
{
struct dbri_streaminfo *info = &dbri->stream_info[streamno];
__u32 dvma_buffer;
@@ -1089,21 +1097,23 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
if (streamno == DBRI_PLAY) {
if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
- printk(KERN_ERR "DBRI: setup_descs: Called on receive pipe %d\n",
- info->pipe);
+ printk(KERN_ERR "DBRI: setup_descs: "
+ "Called on receive pipe %d\n", info->pipe);
return -2;
}
} else {
if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
- printk(KERN_ERR
+ printk(KERN_ERR
"DBRI: setup_descs: Called on transmit pipe %d\n",
info->pipe);
return -2;
}
- /* Should be able to queue multiple buffers to receive on a pipe */
+ /* Should be able to queue multiple buffers
+ * to receive on a pipe
+ */
if (pipe_active(dbri, info->pipe)) {
- printk(KERN_ERR "DBRI: recv_on_pipe: Called on active pipe %d\n",
- info->pipe);
+ printk(KERN_ERR "DBRI: recv_on_pipe: "
+ "Called on active pipe %d\n", info->pipe);
return -2;
}
@@ -1113,11 +1123,13 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
/* Free descriptors if pipe has any */
desc = dbri->pipes[info->pipe].first_desc;
- if ( desc >= 0)
+ if (desc >= 0)
do {
- dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0;
+ dbri->dma->desc[desc].ba = 0;
+ dbri->dma->desc[desc].nda = 0;
desc = dbri->next_desc[desc];
- } while (desc != -1 && desc != dbri->pipes[info->pipe].first_desc);
+ } while (desc != -1 &&
+ desc != dbri->pipes[info->pipe].first_desc);
dbri->pipes[info->pipe].desc = -1;
dbri->pipes[info->pipe].first_desc = -1;
@@ -1130,6 +1142,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
if (!dbri->dma->desc[desc].ba)
break;
}
+
if (desc == DBRI_NO_DESCS) {
printk(KERN_ERR "DBRI: setup_descs: No descriptors\n");
return -1;
@@ -1150,8 +1163,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
if (streamno == DBRI_PLAY) {
dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen);
dbri->dma->desc[desc].word4 = 0;
- dbri->dma->desc[desc].word1 |=
- DBRI_TD_F | DBRI_TD_B;
+ dbri->dma->desc[desc].word1 |= DBRI_TD_F | DBRI_TD_B;
} else {
dbri->dma->desc[desc].word1 = 0;
dbri->dma->desc[desc].word4 =
@@ -1172,7 +1184,8 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
}
if (first_desc == -1 || last_desc == -1) {
- printk(KERN_ERR "DBRI: setup_descs: Not enough descriptors available\n");
+ printk(KERN_ERR "DBRI: setup_descs: "
+ " Not enough descriptors available\n");
return -1;
}
@@ -1183,14 +1196,14 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period
dbri->pipes[info->pipe].desc = first_desc;
#ifdef DBRI_DEBUG
- for (desc = first_desc; desc != -1; ) {
+ for (desc = first_desc; desc != -1;) {
dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n",
desc,
dbri->dma->desc[desc].word1,
dbri->dma->desc[desc].ba,
dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4);
desc = dbri->next_desc[desc];
- if ( desc == first_desc )
+ if (desc == first_desc)
break;
}
#endif
@@ -1213,7 +1226,8 @@ enum master_or_slave { CHImaster, CHIslave };
/*
* Lock must not be held before calling it.
*/
-static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave,
+static void reset_chi(struct snd_dbri *dbri,
+ enum master_or_slave master_or_slave,
int bits_per_frame)
{
s32 *cmd;
@@ -1222,7 +1236,7 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla
/* Set CHI Anchor: Pipe 16 */
cmd = dbri_cmdlock(dbri, 4);
- val = D_DTS_VO | D_DTS_VI | D_DTS_INS
+ val = D_DTS_VO | D_DTS_VI | D_DTS_INS
| D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16);
*(cmd++) = DBRI_CMD(D_DTS, 0, val);
*(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
@@ -1246,15 +1260,16 @@ static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_sla
} else {
/* Setup DBRI for CHI Master - generate clock, FS
*
- * BPF = bits per 8 kHz frame
- * 12.288 MHz / CHICM_divisor = clock rate
- * FD = 1 - drive CHIFS on rising edge of CHICK
+ * BPF = bits per 8 kHz frame
+ * 12.288 MHz / CHICM_divisor = clock rate
+ * FD = 1 - drive CHIFS on rising edge of CHICK
*/
int clockrate = bits_per_frame * 8;
int divisor = 12288 / clockrate;
if (divisor > 255 || divisor * clockrate != 12288)
- printk(KERN_ERR "DBRI: illegal bits_per_frame in setup_chi\n");
+ printk(KERN_ERR "DBRI: illegal bits_per_frame "
+ "in setup_chi\n");
*(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
| D_CHI_BPF(bits_per_frame));
@@ -1288,7 +1303,7 @@ to the DBRI via the CHI interface and few of the DBRI's PIO pins.
* Lock must not be held before calling it.
*/
-static void cs4215_setup_pipes(struct snd_dbri * dbri)
+static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri)
{
unsigned long flags;
@@ -1303,9 +1318,9 @@ static void cs4215_setup_pipes(struct snd_dbri * dbri)
* not relevant for us (only for doublechecking).
*
* Control mode:
- * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly)
+ * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
* Pipe 18: Receive timeslot 1 (clb).
- * Pipe 19: Receive timeslot 7 (version).
+ * Pipe 19: Receive timeslot 7 (version).
*/
setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
@@ -1321,7 +1336,7 @@ static void cs4215_setup_pipes(struct snd_dbri * dbri)
dbri_cmdwait(dbri);
}
-static int cs4215_init_data(struct cs4215 *mm)
+static __devinit int cs4215_init_data(struct cs4215 *mm)
{
/*
* No action, memory resetting only.
@@ -1355,7 +1370,7 @@ static int cs4215_init_data(struct cs4215 *mm)
return 0;
}
-static void cs4215_setdata(struct snd_dbri * dbri, int muted)
+static void cs4215_setdata(struct snd_dbri *dbri, int muted)
{
if (muted) {
dbri->mm.data[0] |= 63;
@@ -1387,7 +1402,7 @@ static void cs4215_setdata(struct snd_dbri * dbri, int muted)
/*
* Set the CS4215 to data mode.
*/
-static void cs4215_open(struct snd_dbri * dbri)
+static void cs4215_open(struct snd_dbri *dbri)
{
int data_width;
u32 tmp;
@@ -1452,7 +1467,7 @@ static void cs4215_open(struct snd_dbri * dbri)
/*
* Send the control information (i.e. audio format)
*/
-static int cs4215_setctrl(struct snd_dbri * dbri)
+static int cs4215_setctrl(struct snd_dbri *dbri)
{
int i, val;
u32 tmp;
@@ -1502,9 +1517,9 @@ static int cs4215_setctrl(struct snd_dbri * dbri)
/*
* Control mode:
- * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly)
+ * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
* Pipe 18: Receive timeslot 1 (clb).
- * Pipe 19: Receive timeslot 7 (version).
+ * Pipe 19: Receive timeslot 7 (version).
*/
link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset);
@@ -1522,9 +1537,9 @@ static int cs4215_setctrl(struct snd_dbri * dbri)
sbus_writel(tmp, dbri->regs + REG0);
spin_unlock_irqrestore(&dbri->lock, flags);
- for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) {
+ for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i)
msleep_interruptible(1);
- }
+
if (i == 0) {
dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
dbri->mm.status);
@@ -1556,7 +1571,7 @@ static int cs4215_setctrl(struct snd_dbri * dbri)
* As part of the process we resend the settings for the data
* timeslots as well.
*/
-static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate,
+static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate,
snd_pcm_format_t format, unsigned int channels)
{
int freq_idx;
@@ -1613,7 +1628,7 @@ static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate,
/*
*
*/
-static int cs4215_init(struct snd_dbri * dbri)
+static __devinit int cs4215_init(struct snd_dbri *dbri)
{
u32 reg2 = sbus_readl(dbri->regs + REG2);
dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
@@ -1674,7 +1689,7 @@ interrupts are disabled.
/* xmit_descs()
*
- * Starts transmiting the current TD's for recording/playing.
+ * Starts transmitting the current TD's for recording/playing.
* For playback, ALSA has filled the DMA memory with new data (we hope).
*/
static void xmit_descs(struct snd_dbri *dbri)
@@ -1701,7 +1716,8 @@ static void xmit_descs(struct snd_dbri *dbri)
*(cmd++) = DBRI_CMD(D_SDP, 0,
dbri->pipes[info->pipe].sdp
| D_SDP_P | D_SDP_EVERY | D_SDP_C);
- *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
+ *(cmd++) = dbri->dma_dvma +
+ dbri_dma_off(desc, first_td);
dbri_cmdsend(dbri, cmd, 2);
/* Reset our admin of the pipe. */
@@ -1722,7 +1738,8 @@ static void xmit_descs(struct snd_dbri *dbri)
*(cmd++) = DBRI_CMD(D_SDP, 0,
dbri->pipes[info->pipe].sdp
| D_SDP_P | D_SDP_EVERY | D_SDP_C);
- *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
+ *(cmd++) = dbri->dma_dvma +
+ dbri_dma_off(desc, first_td);
dbri_cmdsend(dbri, cmd, 2);
/* Reset our admin of the pipe. */
@@ -1747,15 +1764,12 @@ static void xmit_descs(struct snd_dbri *dbri)
*
*/
-static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
+static void transmission_complete_intr(struct snd_dbri *dbri, int pipe)
{
- struct dbri_streaminfo *info;
- int td;
+ struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
+ int td = dbri->pipes[pipe].desc;
int status;
- info = &dbri->stream_info[DBRI_PLAY];
-
- td = dbri->pipes[pipe].desc;
while (td >= 0) {
if (td >= DBRI_NO_DESCS) {
printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe);
@@ -1763,9 +1777,8 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
}
status = DBRI_TD_STATUS(dbri->dma->desc[td].word4);
- if (!(status & DBRI_TD_TBC)) {
+ if (!(status & DBRI_TD_TBC))
break;
- }
dprintk(D_INT, "TD %d, status 0x%02x\n", td, status);
@@ -1777,15 +1790,12 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
}
/* Notify ALSA */
- if (spin_is_locked(&dbri->lock)) {
- spin_unlock(&dbri->lock);
- snd_pcm_period_elapsed(info->substream);
- spin_lock(&dbri->lock);
- } else
- snd_pcm_period_elapsed(info->substream);
+ spin_unlock(&dbri->lock);
+ snd_pcm_period_elapsed(info->substream);
+ spin_lock(&dbri->lock);
}
-static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
+static void reception_complete_intr(struct snd_dbri *dbri, int pipe)
{
struct dbri_streaminfo *info;
int rd = dbri->pipes[pipe].desc;
@@ -1809,15 +1819,12 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
/* Notify ALSA */
- if (spin_is_locked(&dbri->lock)) {
- spin_unlock(&dbri->lock);
- snd_pcm_period_elapsed(info->substream);
- spin_lock(&dbri->lock);
- } else
- snd_pcm_period_elapsed(info->substream);
+ spin_unlock(&dbri->lock);
+ snd_pcm_period_elapsed(info->substream);
+ spin_lock(&dbri->lock);
}
-static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
+static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x)
{
int val = D_INTR_GETVAL(x);
int channel = D_INTR_GETCHAN(x);
@@ -1889,7 +1896,7 @@ static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
* right now). Non-zero words require processing and are handed off
* to dbri_process_one_interrupt AFTER advancing the pointer.
*/
-static void dbri_process_interrupt_buffer(struct snd_dbri * dbri)
+static void dbri_process_interrupt_buffer(struct snd_dbri *dbri)
{
s32 x;
@@ -1965,20 +1972,20 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
PCM Interface
****************************************************************************/
static struct snd_pcm_hardware snd_dbri_pcm_hw = {
- .info = (SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_MU_LAW |
- SNDRV_PCM_FMTBIT_A_LAW |
- SNDRV_PCM_FMTBIT_U8 |
- SNDRV_PCM_FMTBIT_S16_BE,
- .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512,
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_MU_LAW |
+ SNDRV_PCM_FMTBIT_A_LAW |
+ SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_BE,
+ .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512,
.rate_min = 5512,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = (64 * 1024),
+ .buffer_bytes_max = 64 * 1024,
.period_bytes_min = 1,
.period_bytes_max = DBRI_TD_MAXCNT,
.periods_min = 1,
@@ -2011,7 +2018,8 @@ static int snd_hw_rule_channels(struct snd_pcm_hw_params *params,
snd_interval_any(&ch);
if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) {
- ch.min = ch.max = 1;
+ ch.min = 1;
+ ch.max = 1;
ch.integer = 1;
return snd_interval_refine(c, &ch);
}
@@ -2035,14 +2043,14 @@ static int snd_dbri_open(struct snd_pcm_substream *substream)
info->pipe = -1;
spin_unlock_irqrestore(&dbri->lock, flags);
- snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_CHANNELS,
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT,
-1);
- snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_FORMAT,
- snd_hw_rule_channels, NULL,
+ snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+ snd_hw_rule_channels, NULL,
SNDRV_PCM_HW_PARAM_CHANNELS,
-1);
-
+
cs4215_open(dbri);
return 0;
@@ -2145,7 +2153,7 @@ static int snd_dbri_prepare(struct snd_pcm_substream *substream)
spin_lock_irq(&dbri->lock);
info->offset = 0;
- /* Setup the all the transmit/receive desciptors to cover the
+ /* Setup the all the transmit/receive descriptors to cover the
* whole DMA buffer.
*/
ret = setup_descs(dbri, DBRI_STREAMNO(substream),
@@ -2205,12 +2213,12 @@ static struct snd_pcm_ops snd_dbri_ops = {
.pointer = snd_dbri_pointer,
};
-static int __devinit snd_dbri_pcm(struct snd_dbri * dbri)
+static int __devinit snd_dbri_pcm(struct snd_card *card)
{
struct snd_pcm *pcm;
int err;
- if ((err = snd_pcm_new(dbri->card,
+ if ((err = snd_pcm_new(card,
/* ID */ "sun_dbri",
/* device */ 0,
/* playback count */ 1,
@@ -2221,16 +2229,15 @@ static int __devinit snd_dbri_pcm(struct snd_dbri * dbri)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
- pcm->private_data = dbri;
+ pcm->private_data = card->private_data;
pcm->info_flags = 0;
- strcpy(pcm->name, dbri->card->shortname);
+ strcpy(pcm->name, card->shortname);
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm,
SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL),
- 64 * 1024, 64 * 1024)) < 0) {
+ 64 * 1024, 64 * 1024)) < 0)
return err;
- }
return 0;
}
@@ -2245,11 +2252,10 @@ static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
uinfo->value.integer.min = 0;
- if (kcontrol->private_value == DBRI_PLAY) {
+ if (kcontrol->private_value == DBRI_PLAY)
uinfo->value.integer.max = DBRI_MAX_VOLUME;
- } else {
+ else
uinfo->value.integer.max = DBRI_MAX_GAIN;
- }
return 0;
}
@@ -2271,7 +2277,8 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
- struct dbri_streaminfo *info = &dbri->stream_info[kcontrol->private_value];
+ struct dbri_streaminfo *info =
+ &dbri->stream_info[kcontrol->private_value];
int changed = 0;
if (info->left_gain != ucontrol->value.integer.value[0]) {
@@ -2282,7 +2289,7 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol,
info->right_gain = ucontrol->value.integer.value[1];
changed = 1;
}
- if (changed == 1) {
+ if (changed) {
/* First mute outputs, and wait 1/8000 sec (125 us)
* to make sure this takes. This avoids clicking noises.
*/
@@ -2316,18 +2323,16 @@ static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol,
int invert = (kcontrol->private_value >> 24) & 1;
snd_assert(dbri != NULL, return -EINVAL);
- if (elem < 4) {
+ if (elem < 4)
ucontrol->value.integer.value[0] =
(dbri->mm.data[elem] >> shift) & mask;
- } else {
+ else
ucontrol->value.integer.value[0] =
(dbri->mm.ctrl[elem - 4] >> shift) & mask;
- }
- if (invert == 1) {
+ if (invert == 1)
ucontrol->value.integer.value[0] =
mask - ucontrol->value.integer.value[0];
- }
return 0;
}
@@ -2378,11 +2383,12 @@ static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol,
timeslots. Shift is the bit offset in the timeslot, mask defines the
number of bits. invert is a boolean for use with attenuation.
*/
-#define CS4215_SINGLE(xname, entry, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_cs4215_info_single, \
- .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
- .private_value = entry | (shift << 8) | (mask << 16) | (invert << 24) },
+#define CS4215_SINGLE(xname, entry, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .info = snd_cs4215_info_single, \
+ .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
+ .private_value = (entry) | ((shift) << 8) | ((mask) << 16) | \
+ ((invert) << 24) },
static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
{
@@ -2411,19 +2417,20 @@ static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
};
-static int __init snd_dbri_mixer(struct snd_dbri * dbri)
+static int __devinit snd_dbri_mixer(struct snd_card *card)
{
- struct snd_card *card;
int idx, err;
+ struct snd_dbri *dbri;
- snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL);
+ snd_assert(card != NULL && card->private_data != NULL, return -EINVAL);
+ dbri = card->private_data;
- card = dbri->card;
strcpy(card->mixername, card->shortname);
for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
- if ((err = snd_ctl_add(card,
- snd_ctl_new1(&dbri_controls[idx], dbri))) < 0)
+ err = snd_ctl_add(card,
+ snd_ctl_new1(&dbri_controls[idx], dbri));
+ if (err < 0)
return err;
}
@@ -2438,7 +2445,8 @@ static int __init snd_dbri_mixer(struct snd_dbri * dbri)
/****************************************************************************
/proc interface
****************************************************************************/
-static void dbri_regs_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer)
+static void dbri_regs_read(struct snd_info_entry *entry,
+ struct snd_info_buffer *buffer)
{
struct snd_dbri *dbri = entry->private_data;
@@ -2449,7 +2457,7 @@ static void dbri_regs_read(struct snd_info_entry * entry, struct snd_info_buffer
}
#ifdef DBRI_DEBUG
-static void dbri_debug_read(struct snd_info_entry * entry,
+static void dbri_debug_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_dbri *dbri = entry->private_data;
@@ -2463,7 +2471,8 @@ static void dbri_debug_read(struct snd_info_entry * entry,
"Pipe %d: %s SDP=0x%x desc=%d, "
"len=%d next %d\n",
pipe,
- ((pptr->sdp & D_SDP_TO_SER) ? "output" : "input"),
+ (pptr->sdp & D_SDP_TO_SER) ? "output" :
+ "input",
pptr->sdp, pptr->desc,
pptr->length, pptr->nextpipe);
}
@@ -2471,15 +2480,16 @@ static void dbri_debug_read(struct snd_info_entry * entry,
}
#endif
-void snd_dbri_proc(struct snd_dbri * dbri)
+void __devinit snd_dbri_proc(struct snd_card *card)
{
+ struct snd_dbri *dbri = card->private_data;
struct snd_info_entry *entry;
- if (! snd_card_proc_new(dbri->card, "regs", &entry))
+ if (!snd_card_proc_new(card, "regs", &entry))
snd_info_set_text_ops(entry, dbri, dbri_regs_read);
#ifdef DBRI_DEBUG
- if (! snd_card_proc_new(dbri->card, "debug", &entry)) {
+ if (!snd_card_proc_new(card, "debug", &entry)) {
snd_info_set_text_ops(entry, dbri, dbri_debug_read);
entry->mode = S_IFREG | S_IRUGO; /* Readable only. */
}
@@ -2491,19 +2501,18 @@ void snd_dbri_proc(struct snd_dbri * dbri)
**************************** Initialization ********************************
****************************************************************************
*/
-static void snd_dbri_free(struct snd_dbri * dbri);
+static void snd_dbri_free(struct snd_dbri *dbri);
-static int __init snd_dbri_create(struct snd_card *card,
+static int __devinit snd_dbri_create(struct snd_card *card,
struct sbus_dev *sdev,
- struct linux_prom_irqs *irq, int dev)
+ int irq, int dev)
{
struct snd_dbri *dbri = card->private_data;
int err;
spin_lock_init(&dbri->lock);
- dbri->card = card;
dbri->sdev = sdev;
- dbri->irq = irq->pri;
+ dbri->irq = irq;
dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma),
&dbri->dma_dvma);
@@ -2541,13 +2550,10 @@ static int __init snd_dbri_create(struct snd_card *card,
return err;
}
- dbri->next = dbri_list;
- dbri_list = dbri;
-
return 0;
}
-static void snd_dbri_free(struct snd_dbri * dbri)
+static void snd_dbri_free(struct snd_dbri *dbri)
{
dprintk(D_GEN, "snd_dbri_free\n");
dbri_reset(dbri);
@@ -2563,20 +2569,19 @@ static void snd_dbri_free(struct snd_dbri * dbri)
(void *)dbri->dma, dbri->dma_dvma);
}
-static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
+static int __devinit dbri_probe(struct of_device *of_dev,
+ const struct of_device_id *match)
{
+ struct sbus_dev *sdev = to_sbus_device(&of_dev->dev);
struct snd_dbri *dbri;
- struct linux_prom_irqs irq;
+ int irq;
struct resource *rp;
struct snd_card *card;
static int dev = 0;
int err;
- if (sdev->prom_name[9] < 'e') {
- printk(KERN_ERR "DBRI: unsupported chip version %c found.\n",
- sdev->prom_name[9]);
- return -EIO;
- }
+ dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
+ sdev->prom_name, sdev->slot);
if (dev >= SNDRV_CARDS)
return -ENODEV;
@@ -2585,9 +2590,9 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
return -ENOENT;
}
- err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
- if (err < 0) {
- printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", dev);
+ irq = sdev->irqs[0];
+ if (irq <= 0) {
+ printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
return -ENODEV;
}
@@ -2601,24 +2606,29 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
rp = &sdev->resource[0];
sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
card->shortname,
- rp->flags & 0xffL, (unsigned long long)rp->start, irq.pri);
+ rp->flags & 0xffL, (unsigned long long)rp->start, irq);
- if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) {
+ err = snd_dbri_create(card, sdev, irq, dev);
+ if (err < 0) {
snd_card_free(card);
return err;
}
dbri = card->private_data;
- if ((err = snd_dbri_pcm(dbri)) < 0)
+ err = snd_dbri_pcm(card);
+ if (err < 0)
goto _err;
- if ((err = snd_dbri_mixer(dbri)) < 0)
+ err = snd_dbri_mixer(card);
+ if (err < 0)
goto _err;
/* /proc file handling */
- snd_dbri_proc(dbri);
+ snd_dbri_proc(card);
+ dev_set_drvdata(&of_dev->dev, card);
- if ((err = snd_card_register(card)) < 0)
+ err = snd_card_register(card);
+ if (err < 0)
goto _err;
printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
@@ -2628,49 +2638,52 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
return 0;
- _err:
+_err:
snd_dbri_free(dbri);
snd_card_free(card);
return err;
}
-/* Probe for the dbri chip and then attach the driver. */
-static int __init dbri_init(void)
+static int __devexit dbri_remove(struct of_device *dev)
{
- struct sbus_bus *sbus;
- struct sbus_dev *sdev;
- int found = 0;
-
- /* Probe each SBUS for the DBRI chip(s). */
- for_all_sbusdev(sdev, sbus) {
- /*
- * The version is coded in the last character
- */
- if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) {
- dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
- sdev->prom_name, sdev->slot);
+ struct snd_card *card = dev_get_drvdata(&dev->dev);
- if (dbri_attach(sdev->prom_node, sdev) == 0)
- found++;
- }
- }
+ snd_dbri_free(card->private_data);
+ snd_card_free(card);
+
+ dev_set_drvdata(&dev->dev, NULL);
+
+ return 0;
+}
+
+static struct of_device_id dbri_match[] = {
+ {
+ .name = "SUNW,DBRIe",
+ },
+ {
+ .name = "SUNW,DBRIf",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, dbri_match);
+
+static struct of_platform_driver dbri_sbus_driver = {
+ .name = "dbri",
+ .match_table = dbri_match,
+ .probe = dbri_probe,
+ .remove = __devexit_p(dbri_remove),
+};
- return (found > 0) ? 0 : -EIO;
+/* Probe for the dbri chip and then attach the driver. */
+static int __init dbri_init(void)
+{
+ return of_register_driver(&dbri_sbus_driver, &sbus_bus_type);
}
static void __exit dbri_exit(void)
{
- struct snd_dbri *this = dbri_list;
-
- while (this != NULL) {
- struct snd_dbri *next = this->next;
- struct snd_card *card = this->card;
-
- snd_dbri_free(this);
- snd_card_free(card);
- this = next;
- }
- dbri_list = NULL;
+ of_unregister_driver(&dbri_sbus_driver);
}
module_init(dbri_init);
diff --git a/sound/spi/Kconfig b/sound/spi/Kconfig
new file mode 100644
index 00000000000..0d08c29213c
--- /dev/null
+++ b/sound/spi/Kconfig
@@ -0,0 +1,31 @@
+#SPI drivers
+
+menu "SPI devices"
+ depends on SND != n
+
+config SND_AT73C213
+ tristate "Atmel AT73C213 DAC driver"
+ depends on ATMEL_SSC
+ select SND_PCM
+ help
+ Say Y here if you want to use the Atmel AT73C213 external DAC. This
+ DAC can be found on Atmel development boards.
+
+ This driver requires the Atmel SSC driver for sound sink, a
+ peripheral found on most AT91 and AVR32 microprocessors.
+
+ To compile this driver as a module, choose M here: the module will be
+ called snd-at73c213.
+
+config SND_AT73C213_TARGET_BITRATE
+ int "Target bitrate for AT73C213"
+ depends on SND_AT73C213
+ default "48000"
+ range 8000 50000
+ help
+ Sets the target bitrate for the bitrate calculator in the driver.
+ Limited by hardware to be between 8000 Hz and 50000 Hz.
+
+ Set to 48000 Hz by default.
+
+endmenu
diff --git a/sound/spi/Makefile b/sound/spi/Makefile
new file mode 100644
index 00000000000..026fb73f887
--- /dev/null
+++ b/sound/spi/Makefile
@@ -0,0 +1,5 @@
+# Makefile for SPI drivers
+
+snd-at73c213-objs := at73c213.o
+
+obj-$(CONFIG_SND_AT73C213) += snd-at73c213.o
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
new file mode 100644
index 00000000000..fee869bcc95
--- /dev/null
+++ b/sound/spi/at73c213.c
@@ -0,0 +1,1129 @@
+/*
+ * Driver for AT73C213 16-bit stereo DAC connected to Atmel SSC
+ *
+ * Copyright (C) 2006-2007 Atmel Norway
+ *
+ * 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.
+ */
+
+/*#define DEBUG*/
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <sound/driver.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include <linux/atmel-ssc.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+
+#include "at73c213.h"
+
+#define BITRATE_MIN 8000 /* Hardware limit? */
+#define BITRATE_TARGET CONFIG_SND_AT73C213_TARGET_BITRATE
+#define BITRATE_MAX 50000 /* Hardware limit. */
+
+/* Initial (hardware reset) AT73C213 register values. */
+static u8 snd_at73c213_original_image[18] =
+{
+ 0x00, /* 00 - CTRL */
+ 0x05, /* 01 - LLIG */
+ 0x05, /* 02 - RLIG */
+ 0x08, /* 03 - LPMG */
+ 0x08, /* 04 - RPMG */
+ 0x00, /* 05 - LLOG */
+ 0x00, /* 06 - RLOG */
+ 0x22, /* 07 - OLC */
+ 0x09, /* 08 - MC */
+ 0x00, /* 09 - CSFC */
+ 0x00, /* 0A - MISC */
+ 0x00, /* 0B - */
+ 0x00, /* 0C - PRECH */
+ 0x05, /* 0D - AUXG */
+ 0x00, /* 0E - */
+ 0x00, /* 0F - */
+ 0x00, /* 10 - RST */
+ 0x00, /* 11 - PA_CTRL */
+};
+
+struct snd_at73c213 {
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ struct snd_pcm_substream *substream;
+ struct at73c213_board_info *board;
+ int irq;
+ int period;
+ unsigned long bitrate;
+ struct clk *bitclk;
+ struct ssc_device *ssc;
+ struct spi_device *spi;
+ u8 spi_wbuffer[2];
+ u8 spi_rbuffer[2];
+ /* Image of the SPI registers in AT73C213. */
+ u8 reg_image[18];
+ /* Protect registers against concurrent access. */
+ spinlock_t lock;
+};
+
+#define get_chip(card) ((struct snd_at73c213 *)card->private_data)
+
+static int
+snd_at73c213_write_reg(struct snd_at73c213 *chip, u8 reg, u8 val)
+{
+ struct spi_message msg;
+ struct spi_transfer msg_xfer = {
+ .len = 2,
+ .cs_change = 0,
+ };
+ int retval;
+
+ spi_message_init(&msg);
+
+ chip->spi_wbuffer[0] = reg;
+ chip->spi_wbuffer[1] = val;
+
+ msg_xfer.tx_buf = chip->spi_wbuffer;
+ msg_xfer.rx_buf = chip->spi_rbuffer;
+ spi_message_add_tail(&msg_xfer, &msg);
+
+ retval = spi_sync(chip->spi, &msg);
+
+ if (!retval)
+ chip->reg_image[reg] = val;
+
+ return retval;
+}
+
+static struct snd_pcm_hardware snd_at73c213_playback_hw = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER,
+ .formats = SNDRV_PCM_FMTBIT_S16_BE,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 8000, /* Replaced by chip->bitrate later. */
+ .rate_max = 50000, /* Replaced by chip->bitrate later. */
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 64 * 1024 - 1,
+ .period_bytes_min = 512,
+ .period_bytes_max = 64 * 1024 - 1,
+ .periods_min = 4,
+ .periods_max = 1024,
+};
+
+/*
+ * Calculate and set bitrate and divisions.
+ */
+static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip)
+{
+ unsigned long ssc_rate = clk_get_rate(chip->ssc->clk);
+ unsigned long dac_rate_new, ssc_div, status;
+ unsigned long ssc_div_max, ssc_div_min;
+ int max_tries;
+
+ /*
+ * We connect two clocks here, picking divisors so the I2S clocks
+ * out data at the same rate the DAC clocks it in ... and as close
+ * as practical to the desired target rate.
+ *
+ * The DAC master clock (MCLK) is programmable, and is either 256
+ * or (not here) 384 times the I2S output clock (BCLK).
+ */
+
+ /* SSC clock / (bitrate * stereo * 16-bit). */
+ ssc_div = ssc_rate / (BITRATE_TARGET * 2 * 16);
+ ssc_div_min = ssc_rate / (BITRATE_MAX * 2 * 16);
+ ssc_div_max = ssc_rate / (BITRATE_MIN * 2 * 16);
+ max_tries = (ssc_div_max - ssc_div_min) / 2;
+
+ if (max_tries < 1)
+ max_tries = 1;
+
+ /* ssc_div must be a power of 2. */
+ ssc_div = (ssc_div + 1) & ~1UL;
+
+ if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) {
+ ssc_div -= 2;
+ if ((ssc_rate / (ssc_div * 2 * 16)) > BITRATE_MAX)
+ return -ENXIO;
+ }
+
+ /* Search for a possible bitrate. */
+ do {
+ /* SSC clock / (ssc divider * 16-bit * stereo). */
+ if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN)
+ return -ENXIO;
+
+ /* 256 / (2 * 16) = 8 */
+ dac_rate_new = 8 * (ssc_rate / ssc_div);
+
+ status = clk_round_rate(chip->board->dac_clk, dac_rate_new);
+ if (status < 0)
+ return status;
+
+ /* Ignore difference smaller than 256 Hz. */
+ if ((status/256) == (dac_rate_new/256))
+ goto set_rate;
+
+ ssc_div += 2;
+ } while (--max_tries);
+
+ /* Not able to find a valid bitrate. */
+ return -ENXIO;
+
+set_rate:
+ status = clk_set_rate(chip->board->dac_clk, status);
+ if (status < 0)
+ return status;
+
+ /* Set divider in SSC device. */
+ ssc_writel(chip->ssc->regs, CMR, ssc_div/2);
+
+ /* SSC clock / (ssc divider * 16-bit * stereo). */
+ chip->bitrate = ssc_rate / (ssc_div * 16 * 2);
+
+ dev_info(&chip->spi->dev,
+ "at73c213: supported bitrate is %lu (%lu divider)\n",
+ chip->bitrate, ssc_div);
+
+ return 0;
+}
+
+static int snd_at73c213_pcm_open(struct snd_pcm_substream *substream)
+{
+ struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ snd_at73c213_playback_hw.rate_min = chip->bitrate;
+ snd_at73c213_playback_hw.rate_max = chip->bitrate;
+ runtime->hw = snd_at73c213_playback_hw;
+ chip->substream = substream;
+
+ return 0;
+}
+
+static int snd_at73c213_pcm_close(struct snd_pcm_substream *substream)
+{
+ struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
+ chip->substream = NULL;
+ return 0;
+}
+
+static int snd_at73c213_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+}
+
+static int snd_at73c213_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ return snd_pcm_lib_free_pages(substream);
+}
+
+static int snd_at73c213_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int block_size;
+
+ block_size = frames_to_bytes(runtime, runtime->period_size);
+
+ chip->period = 0;
+
+ ssc_writel(chip->ssc->regs, PDC_TPR,
+ (long)runtime->dma_addr);
+ ssc_writel(chip->ssc->regs, PDC_TCR, runtime->period_size * 2);
+ ssc_writel(chip->ssc->regs, PDC_TNPR,
+ (long)runtime->dma_addr + block_size);
+ ssc_writel(chip->ssc->regs, PDC_TNCR, runtime->period_size * 2);
+
+ return 0;
+}
+
+static int snd_at73c213_pcm_trigger(struct snd_pcm_substream *substream,
+ int cmd)
+{
+ struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
+ int retval = 0;
+
+ spin_lock(&chip->lock);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ ssc_writel(chip->ssc->regs, IER, SSC_BIT(IER_ENDTX));
+ ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTEN));
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ ssc_writel(chip->ssc->regs, PDC_PTCR, SSC_BIT(PDC_PTCR_TXTDIS));
+ ssc_writel(chip->ssc->regs, IDR, SSC_BIT(IDR_ENDTX));
+ break;
+ default:
+ dev_dbg(&chip->spi->dev, "spurious command %x\n", cmd);
+ retval = -EINVAL;
+ break;
+ }
+
+ spin_unlock(&chip->lock);
+
+ return retval;
+}
+
+static snd_pcm_uframes_t
+snd_at73c213_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ snd_pcm_uframes_t pos;
+ unsigned long bytes;
+
+ bytes = ssc_readl(chip->ssc->regs, PDC_TPR)
+ - (unsigned long)runtime->dma_addr;
+
+ pos = bytes_to_frames(runtime, bytes);
+ if (pos >= runtime->buffer_size)
+ pos -= runtime->buffer_size;
+
+ return pos;
+}
+
+static struct snd_pcm_ops at73c213_playback_ops = {
+ .open = snd_at73c213_pcm_open,
+ .close = snd_at73c213_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_at73c213_pcm_hw_params,
+ .hw_free = snd_at73c213_pcm_hw_free,
+ .prepare = snd_at73c213_pcm_prepare,
+ .trigger = snd_at73c213_pcm_trigger,
+ .pointer = snd_at73c213_pcm_pointer,
+};
+
+static void snd_at73c213_pcm_free(struct snd_pcm *pcm)
+{
+ struct snd_at73c213 *chip = snd_pcm_chip(pcm);
+ if (chip->pcm) {
+ snd_pcm_lib_preallocate_free_for_all(chip->pcm);
+ chip->pcm = NULL;
+ }
+}
+
+static int __devinit snd_at73c213_pcm_new(struct snd_at73c213 *chip, int device)
+{
+ struct snd_pcm *pcm;
+ int retval;
+
+ retval = snd_pcm_new(chip->card, chip->card->shortname,
+ device, 1, 0, &pcm);
+ if (retval < 0)
+ goto out;
+
+ pcm->private_data = chip;
+ pcm->private_free = snd_at73c213_pcm_free;
+ pcm->info_flags = SNDRV_PCM_INFO_BLOCK_TRANSFER;
+ strcpy(pcm->name, "at73c213");
+ chip->pcm = pcm;
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &at73c213_playback_ops);
+
+ retval = snd_pcm_lib_preallocate_pages_for_all(chip->pcm,
+ SNDRV_DMA_TYPE_DEV, &chip->ssc->pdev->dev,
+ 64 * 1024, 64 * 1024);
+out:
+ return retval;
+}
+
+static irqreturn_t snd_at73c213_interrupt(int irq, void *dev_id)
+{
+ struct snd_at73c213 *chip = dev_id;
+ struct snd_pcm_runtime *runtime = chip->substream->runtime;
+ u32 status;
+ int offset;
+ int block_size;
+ int next_period;
+ int retval = IRQ_NONE;
+
+ spin_lock(&chip->lock);
+
+ block_size = frames_to_bytes(runtime, runtime->period_size);
+ status = ssc_readl(chip->ssc->regs, IMR);
+
+ if (status & SSC_BIT(IMR_ENDTX)) {
+ chip->period++;
+ if (chip->period == runtime->periods)
+ chip->period = 0;
+ next_period = chip->period + 1;
+ if (next_period == runtime->periods)
+ next_period = 0;
+
+ offset = block_size * next_period;
+
+ ssc_writel(chip->ssc->regs, PDC_TNPR,
+ (long)runtime->dma_addr + offset);
+ ssc_writel(chip->ssc->regs, PDC_TNCR, runtime->period_size * 2);
+ retval = IRQ_HANDLED;
+ }
+
+ ssc_readl(chip->ssc->regs, IMR);
+ spin_unlock(&chip->lock);
+
+ if (status & SSC_BIT(IMR_ENDTX))
+ snd_pcm_period_elapsed(chip->substream);
+
+ return retval;
+}
+
+/*
+ * Mixer functions.
+ */
+static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
+ int reg = kcontrol->private_value & 0xff;
+ int shift = (kcontrol->private_value >> 8) & 0xff;
+ int mask = (kcontrol->private_value >> 16) & 0xff;
+ int invert = (kcontrol->private_value >> 24) & 0xff;
+
+ spin_lock_irq(&chip->lock);
+
+ ucontrol->value.integer.value[0] =
+ (chip->reg_image[reg] >> shift) & mask;
+
+ if (invert)
+ ucontrol->value.integer.value[0] =
+ mask - ucontrol->value.integer.value[0];
+
+ spin_unlock_irq(&chip->lock);
+
+ return 0;
+}
+
+static int snd_at73c213_mono_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
+ int reg = kcontrol->private_value & 0xff;
+ int shift = (kcontrol->private_value >> 8) & 0xff;
+ int mask = (kcontrol->private_value >> 16) & 0xff;
+ int invert = (kcontrol->private_value >> 24) & 0xff;
+ int change, retval;
+ unsigned short val;
+
+ val = (ucontrol->value.integer.value[0] & mask);
+ if (invert)
+ val = mask - val;
+ val <<= shift;
+
+ spin_lock_irq(&chip->lock);
+
+ val = (chip->reg_image[reg] & ~(mask << shift)) | val;
+ change = val != chip->reg_image[reg];
+ retval = snd_at73c213_write_reg(chip, reg, val);
+
+ spin_unlock_irq(&chip->lock);
+
+ if (retval)
+ return retval;
+
+ return change;
+}
+
+static int snd_at73c213_stereo_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ int mask = (kcontrol->private_value >> 24) & 0xff;
+
+ if (mask == 1)
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ else
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mask;
+
+ return 0;
+}
+
+static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
+ int left_reg = kcontrol->private_value & 0xff;
+ int right_reg = (kcontrol->private_value >> 8) & 0xff;
+ int shift_left = (kcontrol->private_value >> 16) & 0x07;
+ int shift_right = (kcontrol->private_value >> 19) & 0x07;
+ int mask = (kcontrol->private_value >> 24) & 0xff;
+ int invert = (kcontrol->private_value >> 22) & 1;
+
+ spin_lock_irq(&chip->lock);
+
+ ucontrol->value.integer.value[0] =
+ (chip->reg_image[left_reg] >> shift_left) & mask;
+ ucontrol->value.integer.value[1] =
+ (chip->reg_image[right_reg] >> shift_right) & mask;
+
+ if (invert) {
+ ucontrol->value.integer.value[0] =
+ mask - ucontrol->value.integer.value[0];
+ ucontrol->value.integer.value[1] =
+ mask - ucontrol->value.integer.value[1];
+ }
+
+ spin_unlock_irq(&chip->lock);
+
+ return 0;
+}
+
+static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
+ int left_reg = kcontrol->private_value & 0xff;
+ int right_reg = (kcontrol->private_value >> 8) & 0xff;
+ int shift_left = (kcontrol->private_value >> 16) & 0x07;
+ int shift_right = (kcontrol->private_value >> 19) & 0x07;
+ int mask = (kcontrol->private_value >> 24) & 0xff;
+ int invert = (kcontrol->private_value >> 22) & 1;
+ int change, retval;
+ unsigned short val1, val2;
+
+ val1 = ucontrol->value.integer.value[0] & mask;
+ val2 = ucontrol->value.integer.value[1] & mask;
+ if (invert) {
+ val1 = mask - val1;
+ val2 = mask - val2;
+ }
+ val1 <<= shift_left;
+ val2 <<= shift_right;
+
+ spin_lock_irq(&chip->lock);
+
+ val1 = (chip->reg_image[left_reg] & ~(mask << shift_left)) | val1;
+ val2 = (chip->reg_image[right_reg] & ~(mask << shift_right)) | val2;
+ change = val1 != chip->reg_image[left_reg]
+ || val2 != chip->reg_image[right_reg];
+ retval = snd_at73c213_write_reg(chip, left_reg, val1);
+ if (retval) {
+ spin_unlock_irq(&chip->lock);
+ goto out;
+ }
+ retval = snd_at73c213_write_reg(chip, right_reg, val2);
+ if (retval) {
+ spin_unlock_irq(&chip->lock);
+ goto out;
+ }
+
+ spin_unlock_irq(&chip->lock);
+
+ return change;
+
+out:
+ return retval;
+}
+
+static int snd_at73c213_mono_switch_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+
+ return 0;
+}
+
+static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
+ int reg = kcontrol->private_value & 0xff;
+ int shift = (kcontrol->private_value >> 8) & 0xff;
+ int invert = (kcontrol->private_value >> 24) & 0xff;
+
+ spin_lock_irq(&chip->lock);
+
+ ucontrol->value.integer.value[0] =
+ (chip->reg_image[reg] >> shift) & 0x01;
+
+ if (invert)
+ ucontrol->value.integer.value[0] =
+ 0x01 - ucontrol->value.integer.value[0];
+
+ spin_unlock_irq(&chip->lock);
+
+ return 0;
+}
+
+static int snd_at73c213_mono_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
+ int reg = kcontrol->private_value & 0xff;
+ int shift = (kcontrol->private_value >> 8) & 0xff;
+ int mask = (kcontrol->private_value >> 16) & 0xff;
+ int invert = (kcontrol->private_value >> 24) & 0xff;
+ int change, retval;
+ unsigned short val;
+
+ if (ucontrol->value.integer.value[0])
+ val = mask;
+ else
+ val = 0;
+
+ if (invert)
+ val = mask - val;
+ val <<= shift;
+
+ spin_lock_irq(&chip->lock);
+
+ val |= (chip->reg_image[reg] & ~(mask << shift));
+ change = val != chip->reg_image[reg];
+
+ retval = snd_at73c213_write_reg(chip, reg, val);
+
+ spin_unlock_irq(&chip->lock);
+
+ if (retval)
+ return retval;
+
+ return change;
+}
+
+static int snd_at73c213_pa_volume_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = ((kcontrol->private_value >> 16) & 0xff) - 1;
+
+ return 0;
+}
+
+static int snd_at73c213_line_capture_volume_info(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ /* When inverted will give values 0x10001 => 0. */
+ uinfo->value.integer.min = 14;
+ uinfo->value.integer.max = 31;
+
+ return 0;
+}
+
+static int snd_at73c213_aux_capture_volume_info(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ /* When inverted will give values 0x10001 => 0. */
+ uinfo->value.integer.min = 14;
+ uinfo->value.integer.max = 31;
+
+ return 0;
+}
+
+#define AT73C213_MONO_SWITCH(xname, xindex, reg, shift, mask, invert) \
+{ \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = xindex, \
+ .info = snd_at73c213_mono_switch_info, \
+ .get = snd_at73c213_mono_switch_get, \
+ .put = snd_at73c213_mono_switch_put, \
+ .private_value = (reg | (shift << 8) | (mask << 16) | (invert << 24)) \
+}
+
+#define AT73C213_STEREO(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
+{ \
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+ .name = xname, \
+ .index = xindex, \
+ .info = snd_at73c213_stereo_info, \
+ .get = snd_at73c213_stereo_get, \
+ .put = snd_at73c213_stereo_put, \
+ .private_value = (left_reg | (right_reg << 8) \
+ | (shift_left << 16) | (shift_right << 19) \
+ | (mask << 24) | (invert << 22)) \
+}
+
+static struct snd_kcontrol_new snd_at73c213_controls[] __devinitdata = {
+AT73C213_STEREO("Master Playback Volume", 0, DAC_LMPG, DAC_RMPG, 0, 0, 0x1f, 1),
+AT73C213_STEREO("Master Playback Switch", 0, DAC_LMPG, DAC_RMPG, 5, 5, 1, 1),
+AT73C213_STEREO("PCM Playback Volume", 0, DAC_LLOG, DAC_RLOG, 0, 0, 0x1f, 1),
+AT73C213_STEREO("PCM Playback Switch", 0, DAC_LLOG, DAC_RLOG, 5, 5, 1, 1),
+AT73C213_MONO_SWITCH("Mono PA Playback Switch", 0, DAC_CTRL, DAC_CTRL_ONPADRV,
+ 0x01, 0),
+{
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PA Playback Volume",
+ .index = 0,
+ .info = snd_at73c213_pa_volume_info,
+ .get = snd_at73c213_mono_get,
+ .put = snd_at73c213_mono_put,
+ .private_value = PA_CTRL | (PA_CTRL_APAGAIN << 8) | \
+ (0x0f << 16) | (1 << 24),
+},
+AT73C213_MONO_SWITCH("PA High Gain Playback Switch", 0, PA_CTRL, PA_CTRL_APALP,
+ 0x01, 1),
+AT73C213_MONO_SWITCH("PA Playback Switch", 0, PA_CTRL, PA_CTRL_APAON, 0x01, 0),
+{
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Aux Capture Volume",
+ .index = 0,
+ .info = snd_at73c213_aux_capture_volume_info,
+ .get = snd_at73c213_mono_get,
+ .put = snd_at73c213_mono_put,
+ .private_value = DAC_AUXG | (0 << 8) | (0x1f << 16) | (1 << 24),
+},
+AT73C213_MONO_SWITCH("Aux Capture Switch", 0, DAC_CTRL, DAC_CTRL_ONAUXIN,
+ 0x01, 0),
+{
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Line Capture Volume",
+ .index = 0,
+ .info = snd_at73c213_line_capture_volume_info,
+ .get = snd_at73c213_stereo_get,
+ .put = snd_at73c213_stereo_put,
+ .private_value = DAC_LLIG | (DAC_RLIG << 8) | (0 << 16) | (0 << 19)
+ | (0x1f << 24) | (1 << 22),
+},
+AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0),
+};
+
+static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip)
+{
+ struct snd_card *card;
+ int errval, idx;
+
+ if (chip == NULL || chip->pcm == NULL)
+ return -EINVAL;
+
+ card = chip->card;
+
+ strcpy(card->mixername, chip->pcm->name);
+
+ for (idx = 0; idx < ARRAY_SIZE(snd_at73c213_controls); idx++) {
+ errval = snd_ctl_add(card,
+ snd_ctl_new1(&snd_at73c213_controls[idx],
+ chip));
+ if (errval < 0)
+ goto cleanup;
+ }
+
+ return 0;
+
+cleanup:
+ for (idx = 1; idx < ARRAY_SIZE(snd_at73c213_controls) + 1; idx++) {
+ struct snd_kcontrol *kctl;
+ kctl = snd_ctl_find_numid(card, idx);
+ if (kctl)
+ snd_ctl_remove(card, kctl);
+ }
+ return errval;
+}
+
+/*
+ * Device functions
+ */
+static int snd_at73c213_ssc_init(struct snd_at73c213 *chip)
+{
+ /*
+ * Continuous clock output.
+ * Starts on falling TF.
+ * Delay 1 cycle (1 bit).
+ * Periode is 16 bit (16 - 1).
+ */
+ ssc_writel(chip->ssc->regs, TCMR,
+ SSC_BF(TCMR_CKO, 1)
+ | SSC_BF(TCMR_START, 4)
+ | SSC_BF(TCMR_STTDLY, 1)
+ | SSC_BF(TCMR_PERIOD, 16 - 1));
+ /*
+ * Data length is 16 bit (16 - 1).
+ * Transmit MSB first.
+ * Transmit 2 words each transfer.
+ * Frame sync length is 16 bit (16 - 1).
+ * Frame starts on negative pulse.
+ */
+ ssc_writel(chip->ssc->regs, TFMR,
+ SSC_BF(TFMR_DATLEN, 16 - 1)
+ | SSC_BIT(TFMR_MSBF)
+ | SSC_BF(TFMR_DATNB, 1)
+ | SSC_BF(TFMR_FSLEN, 16 - 1)
+ | SSC_BF(TFMR_FSOS, 1));
+
+ return 0;
+}
+
+static int snd_at73c213_chip_init(struct snd_at73c213 *chip)
+{
+ int retval;
+ unsigned char dac_ctrl = 0;
+
+ retval = snd_at73c213_set_bitrate(chip);
+ if (retval)
+ goto out;
+
+ /* Enable DAC master clock. */
+ clk_enable(chip->board->dac_clk);
+
+ /* Initialize at73c213 on SPI bus. */
+ retval = snd_at73c213_write_reg(chip, DAC_RST, 0x04);
+ if (retval)
+ goto out_clk;
+ msleep(1);
+ retval = snd_at73c213_write_reg(chip, DAC_RST, 0x03);
+ if (retval)
+ goto out_clk;
+
+ /* Precharge everything. */
+ retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0xff);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, PA_CTRL, (1<<PA_CTRL_APAPRECH));
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_CTRL,
+ (1<<DAC_CTRL_ONLNOL) | (1<<DAC_CTRL_ONLNOR));
+ if (retval)
+ goto out_clk;
+
+ msleep(50);
+
+ /* Stop precharging PA. */
+ retval = snd_at73c213_write_reg(chip, PA_CTRL,
+ (1<<PA_CTRL_APALP) | 0x0f);
+ if (retval)
+ goto out_clk;
+
+ msleep(450);
+
+ /* Stop precharging DAC, turn on master power. */
+ retval = snd_at73c213_write_reg(chip, DAC_PRECH, (1<<DAC_PRECH_ONMSTR));
+ if (retval)
+ goto out_clk;
+
+ msleep(1);
+
+ /* Turn on DAC. */
+ dac_ctrl = (1<<DAC_CTRL_ONDACL) | (1<<DAC_CTRL_ONDACR)
+ | (1<<DAC_CTRL_ONLNOL) | (1<<DAC_CTRL_ONLNOR);
+
+ retval = snd_at73c213_write_reg(chip, DAC_CTRL, dac_ctrl);
+ if (retval)
+ goto out_clk;
+
+ /* Mute sound. */
+ retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_RMPG, 0x3f);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_LLOG, 0x3f);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_RLOG, 0x3f);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_LLIG, 0x11);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11);
+ if (retval)
+ goto out_clk;
+ retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11);
+ if (retval)
+ goto out_clk;
+
+ /* Enable I2S device, i.e. clock output. */
+ ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
+
+ goto out;
+
+out_clk:
+ clk_disable(chip->board->dac_clk);
+out:
+ return retval;
+}
+
+static int snd_at73c213_dev_free(struct snd_device *device)
+{
+ struct snd_at73c213 *chip = device->device_data;
+
+ ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
+ if (chip->irq >= 0) {
+ free_irq(chip->irq, chip);
+ chip->irq = -1;
+ }
+
+ return 0;
+}
+
+static int __devinit snd_at73c213_dev_init(struct snd_card *card,
+ struct spi_device *spi)
+{
+ static struct snd_device_ops ops = {
+ .dev_free = snd_at73c213_dev_free,
+ };
+ struct snd_at73c213 *chip = get_chip(card);
+ int irq, retval;
+
+ irq = chip->ssc->irq;
+ if (irq < 0)
+ return irq;
+
+ spin_lock_init(&chip->lock);
+ chip->card = card;
+ chip->irq = -1;
+
+ retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip);
+ if (retval) {
+ dev_dbg(&chip->spi->dev, "unable to request irq %d\n", irq);
+ goto out;
+ }
+ chip->irq = irq;
+
+ memcpy(&chip->reg_image, &snd_at73c213_original_image,
+ sizeof(snd_at73c213_original_image));
+
+ retval = snd_at73c213_ssc_init(chip);
+ if (retval)
+ goto out_irq;
+
+ retval = snd_at73c213_chip_init(chip);
+ if (retval)
+ goto out_irq;
+
+ retval = snd_at73c213_pcm_new(chip, 0);
+ if (retval)
+ goto out_irq;
+
+ retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (retval)
+ goto out_irq;
+
+ retval = snd_at73c213_mixer(chip);
+ if (retval)
+ goto out_snd_dev;
+
+ snd_card_set_dev(card, &spi->dev);
+
+ goto out;
+
+out_snd_dev:
+ snd_device_free(card, chip);
+out_irq:
+ free_irq(chip->irq, chip);
+ chip->irq = -1;
+out:
+ return retval;
+}
+
+static int snd_at73c213_probe(struct spi_device *spi)
+{
+ struct snd_card *card;
+ struct snd_at73c213 *chip;
+ struct at73c213_board_info *board;
+ int retval;
+ char id[16];
+
+ board = spi->dev.platform_data;
+ if (!board) {
+ dev_dbg(&spi->dev, "no platform_data\n");
+ return -ENXIO;
+ }
+
+ if (!board->dac_clk) {
+ dev_dbg(&spi->dev, "no DAC clk\n");
+ return -ENXIO;
+ }
+
+ if (IS_ERR(board->dac_clk)) {
+ dev_dbg(&spi->dev, "no DAC clk\n");
+ return PTR_ERR(board->dac_clk);
+ }
+
+ retval = -ENOMEM;
+
+ /* Allocate "card" using some unused identifiers. */
+ snprintf(id, sizeof id, "at73c213_%d", board->ssc_id);
+ card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct snd_at73c213));
+ if (!card)
+ goto out;
+
+ chip = card->private_data;
+ chip->spi = spi;
+ chip->board = board;
+
+ chip->ssc = ssc_request(board->ssc_id);
+ if (IS_ERR(chip->ssc)) {
+ dev_dbg(&spi->dev, "could not get ssc%d device\n",
+ board->ssc_id);
+ retval = PTR_ERR(chip->ssc);
+ goto out_card;
+ }
+
+ retval = snd_at73c213_dev_init(card, spi);
+ if (retval)
+ goto out_ssc;
+
+ strcpy(card->driver, "at73c213");
+ strcpy(card->shortname, board->shortname);
+ sprintf(card->longname, "%s on irq %d", card->shortname, chip->irq);
+
+ retval = snd_card_register(card);
+ if (retval)
+ goto out_ssc;
+
+ dev_set_drvdata(&spi->dev, card);
+
+ goto out;
+
+out_ssc:
+ ssc_free(chip->ssc);
+out_card:
+ snd_card_free(card);
+out:
+ return retval;
+}
+
+static int __devexit snd_at73c213_remove(struct spi_device *spi)
+{
+ struct snd_card *card = dev_get_drvdata(&spi->dev);
+ struct snd_at73c213 *chip = card->private_data;
+ int retval;
+
+ /* Stop playback. */
+ ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
+
+ /* Mute sound. */
+ retval = snd_at73c213_write_reg(chip, DAC_LMPG, 0x3f);
+ if (retval)
+ goto out;
+ retval = snd_at73c213_write_reg(chip, DAC_RMPG, 0x3f);
+ if (retval)
+ goto out;
+ retval = snd_at73c213_write_reg(chip, DAC_LLOG, 0x3f);
+ if (retval)
+ goto out;
+ retval = snd_at73c213_write_reg(chip, DAC_RLOG, 0x3f);
+ if (retval)
+ goto out;
+ retval = snd_at73c213_write_reg(chip, DAC_LLIG, 0x11);
+ if (retval)
+ goto out;
+ retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11);
+ if (retval)
+ goto out;
+ retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11);
+ if (retval)
+ goto out;
+
+ /* Turn off PA. */
+ retval = snd_at73c213_write_reg(chip, PA_CTRL,
+ chip->reg_image[PA_CTRL] | 0x0f);
+ if (retval)
+ goto out;
+ msleep(10);
+ retval = snd_at73c213_write_reg(chip, PA_CTRL,
+ (1 << PA_CTRL_APALP) | 0x0f);
+ if (retval)
+ goto out;
+
+ /* Turn off external DAC. */
+ retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x0c);
+ if (retval)
+ goto out;
+ msleep(2);
+ retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x00);
+ if (retval)
+ goto out;
+
+ /* Turn off master power. */
+ retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0x00);
+ if (retval)
+ goto out;
+
+out:
+ /* Stop DAC master clock. */
+ clk_disable(chip->board->dac_clk);
+
+ ssc_free(chip->ssc);
+ snd_card_free(card);
+ dev_set_drvdata(&spi->dev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_at73c213_suspend(struct spi_device *spi, pm_message_t msg)
+{
+ struct snd_card *card = dev_get_drvdata(&spi->dev);
+ struct snd_at73c213 *chip = card->private_data;
+
+ ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXDIS));
+ clk_disable(chip->board->dac_clk);
+
+ return 0;
+}
+
+static int snd_at73c213_resume(struct spi_device *spi)
+{
+ struct snd_card *card = dev_get_drvdata(&spi->dev);
+ struct snd_at73c213 *chip = card->private_data;
+
+ clk_enable(chip->board->dac_clk);
+ ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN));
+
+ return 0;
+}
+#else
+#define snd_at73c213_suspend NULL
+#define snd_at73c213_resume NULL
+#endif
+
+static struct spi_driver at73c213_driver = {
+ .driver = {
+ .name = "at73c213",
+ },
+ .probe = snd_at73c213_probe,
+ .suspend = snd_at73c213_suspend,
+ .resume = snd_at73c213_resume,
+ .remove = __devexit_p(snd_at73c213_remove),
+};
+
+static int __init at73c213_init(void)
+{
+ return spi_register_driver(&at73c213_driver);
+}
+module_init(at73c213_init);
+
+static void __exit at73c213_exit(void)
+{
+ spi_unregister_driver(&at73c213_driver);
+}
+module_exit(at73c213_exit);
+
+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
+MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
+MODULE_LICENSE("GPL");
diff --git a/sound/spi/at73c213.h b/sound/spi/at73c213.h
new file mode 100644
index 00000000000..fd8b372df5d
--- /dev/null
+++ b/sound/spi/at73c213.h
@@ -0,0 +1,119 @@
+/*
+ * Driver for the AT73C213 16-bit stereo DAC on Atmel ATSTK1000
+ *
+ * Copyright (C) 2006 - 2007 Atmel Corporation
+ *
+ * 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.
+ *
+ * The full GNU General Public License is included in this
+ * distribution in the file called COPYING.
+ */
+
+#ifndef _SND_AT73C213_H
+#define _SND_AT73C213_H
+
+/* DAC control register */
+#define DAC_CTRL 0x00
+#define DAC_CTRL_ONPADRV 7
+#define DAC_CTRL_ONAUXIN 6
+#define DAC_CTRL_ONDACR 5
+#define DAC_CTRL_ONDACL 4
+#define DAC_CTRL_ONLNOR 3
+#define DAC_CTRL_ONLNOL 2
+#define DAC_CTRL_ONLNIR 1
+#define DAC_CTRL_ONLNIL 0
+
+/* DAC left line in gain register */
+#define DAC_LLIG 0x01
+#define DAC_LLIG_LLIG 0
+
+/* DAC right line in gain register */
+#define DAC_RLIG 0x02
+#define DAC_RLIG_RLIG 0
+
+/* DAC Left Master Playback Gain Register */
+#define DAC_LMPG 0x03
+#define DAC_LMPG_LMPG 0
+
+/* DAC Right Master Playback Gain Register */
+#define DAC_RMPG 0x04
+#define DAC_RMPG_RMPG 0
+
+/* DAC Left Line Out Gain Register */
+#define DAC_LLOG 0x05
+#define DAC_LLOG_LLOG 0
+
+/* DAC Right Line Out Gain Register */
+#define DAC_RLOG 0x06
+#define DAC_RLOG_RLOG 0
+
+/* DAC Output Level Control Register */
+#define DAC_OLC 0x07
+#define DAC_OLC_RSHORT 7
+#define DAC_OLC_ROLC 4
+#define DAC_OLC_LSHORT 3
+#define DAC_OLC_LOLC 0
+
+/* DAC Mixer Control Register */
+#define DAC_MC 0x08
+#define DAC_MC_INVR 5
+#define DAC_MC_INVL 4
+#define DAC_MC_RMSMIN2 3
+#define DAC_MC_RMSMIN1 2
+#define DAC_MC_LMSMIN2 1
+#define DAC_MC_LMSMIN1 0
+
+/* DAC Clock and Sampling Frequency Control Register */
+#define DAC_CSFC 0x09
+#define DAC_CSFC_OVRSEL 4
+
+/* DAC Miscellaneous Register */
+#define DAC_MISC 0x0A
+#define DAC_MISC_VCMCAPSEL 7
+#define DAC_MISC_DINTSEL 4
+#define DAC_MISC_DITHEN 3
+#define DAC_MISC_DEEMPEN 2
+#define DAC_MISC_NBITS 0
+
+/* DAC Precharge Control Register */
+#define DAC_PRECH 0x0C
+#define DAC_PRECH_PRCHGPDRV 7
+#define DAC_PRECH_PRCHGAUX1 6
+#define DAC_PRECH_PRCHGLNOR 5
+#define DAC_PRECH_PRCHGLNOL 4
+#define DAC_PRECH_PRCHGLNIR 3
+#define DAC_PRECH_PRCHGLNIL 2
+#define DAC_PRECH_PRCHG 1
+#define DAC_PRECH_ONMSTR 0
+
+/* DAC Auxiliary Input Gain Control Register */
+#define DAC_AUXG 0x0D
+#define DAC_AUXG_AUXG 0
+
+/* DAC Reset Register */
+#define DAC_RST 0x10
+#define DAC_RST_RESMASK 2
+#define DAC_RST_RESFILZ 1
+#define DAC_RST_RSTZ 0
+
+/* Power Amplifier Control Register */
+#define PA_CTRL 0x11
+#define PA_CTRL_APAON 6
+#define PA_CTRL_APAPRECH 5
+#define PA_CTRL_APALP 4
+#define PA_CTRL_APAGAIN 0
+
+#endif /* _SND_AT73C213_H */
diff --git a/sound/synth/Makefile b/sound/synth/Makefile
index 986291dcb91..e99fd76caa1 100644
--- a/sound/synth/Makefile
+++ b/sound/synth/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-util-mem-objs := util_mem.o
diff --git a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile
index 32a102d2670..b69035240cf 100644
--- a/sound/synth/emux/Makefile
+++ b/sound/synth/emux/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for ALSA
-# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
+# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
#
snd-emux-synth-objs := emux.o emux_synth.o emux_seq.o emux_nrpn.o \
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c
index 1d9b11f345f..6fc3d2b2519 100644
--- a/sound/synth/util_mem.c
+++ b/sound/synth/util_mem.c
@@ -116,7 +116,7 @@ __snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
if (blk == NULL)
return NULL;
- if (! prev || prev == &hdr->block)
+ if (prev == &hdr->block)
blk->offset = 0;
else {
struct snd_util_memblk *p = get_memblk(prev);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 315360f3127..706143826af 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -40,6 +40,7 @@ config SND_USB_CAIAQ
namely:
* Native Instruments RigKontrol2
+ * Native Instruments RigKontrol3
* Native Instruments Kore Controller
* Native Instruments Audio Kontrol 1
* Native Instruments Audio 8 DJ
@@ -55,6 +56,7 @@ config SND_USB_CAIAQ_INPUT
alpha dials and analog pedals on the following products:
* Native Instruments RigKontrol2
+ * Native Instruments RigKontrol3
* Native Instruments Audio Kontrol 1
endmenu
diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c
index 0414d766ba0..0666908a236 100644
--- a/sound/usb/caiaq/caiaq-audio.c
+++ b/sound/usb/caiaq/caiaq-audio.c
@@ -648,6 +648,7 @@ int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
dev->samplerates = dev->pcm_info.rates;
switch (dev->chip.usb_id) {
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
dev->samplerates |= SNDRV_PCM_RATE_88200;
dev->samplerates |= SNDRV_PCM_RATE_192000;
break;
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index 4709347326f..58af8142c57 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -41,9 +41,10 @@
#endif
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.2.0");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
+ "{Native Instruments, RigKontrol3},"
"{Native Instruments, Kore Controller},"
"{Native Instruments, Audio Kontrol 1}"
"{Native Instruments, Audio 8 DJ}}");
@@ -85,6 +86,11 @@ static struct usb_device_id snd_usb_id_table[] = {
{
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = USB_VID_NATIVEINSTRUMENTS,
+ .idProduct = USB_PID_RIGKONTROL3
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = USB_VID_NATIVEINSTRUMENTS,
.idProduct = USB_PID_KORECONTROLLER
},
{
@@ -226,7 +232,7 @@ int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev,
static void setup_card(struct snd_usb_caiaqdev *dev)
{
int ret;
- char val[3];
+ char val[4];
/* device-specific startup specials */
switch (dev->chip.usb_id) {
@@ -237,6 +243,14 @@ static void setup_card(struct snd_usb_caiaqdev *dev)
val[2] = 0x01;
send_command(dev, EP1_CMD_WRITE_IO, val, 3);
break;
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
+ /* RigKontrol2 - display two centered dashes ('--') */
+ val[0] = 0x00;
+ val[1] = 0x40;
+ val[2] = 0x40;
+ val[3] = 0x00;
+ send_command(dev, EP1_CMD_WRITE_IO, val, 4);
+ break;
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
/* Audio Kontrol 1 - make USB-LED stop blinking */
val[0] = 0x00;
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
index 088d5ec241f..79bc5be2df7 100644
--- a/sound/usb/caiaq/caiaq-device.h
+++ b/sound/usb/caiaq/caiaq-device.h
@@ -6,6 +6,7 @@
#define USB_VID_NATIVEINSTRUMENTS 0x17cc
#define USB_PID_RIGKONTROL2 0x1969
+#define USB_PID_RIGKONTROL3 0x1940
#define USB_PID_KORECONTROLLER 0x4711
#define USB_PID_AK1 0x0815
#define USB_PID_AUDIO8DJ 0x1978
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c
index 3acd12db695..a1de0c60895 100644
--- a/sound/usb/caiaq/caiaq-input.c
+++ b/sound/usb/caiaq/caiaq-input.c
@@ -34,6 +34,8 @@
static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A };
static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
KEY_5, KEY_6, KEY_7 };
+static unsigned char keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4,
+ KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 };
#define DEG90 (range/2)
#define DEG180 (range)
@@ -107,7 +109,8 @@ static unsigned int decode_erp(unsigned char a, unsigned char b)
static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
- const char *buf, unsigned int len)
+ const unsigned char *buf,
+ unsigned int len)
{
switch(dev->input_dev->id.product) {
case USB_PID_RIGKONTROL2:
@@ -116,6 +119,12 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]);
input_sync(dev->input_dev);
break;
+ case USB_PID_RIGKONTROL3:
+ input_report_abs(dev->input_dev, ABS_X, (buf[0] << 8) |buf[1]);
+ input_report_abs(dev->input_dev, ABS_Y, (buf[2] << 8) |buf[3]);
+ input_report_abs(dev->input_dev, ABS_Z, (buf[4] << 8) |buf[5]);
+ input_sync(dev->input_dev);
+ break;
}
}
@@ -128,7 +137,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
case USB_PID_AK1:
i = decode_erp(buf[0], buf[1]);
input_report_abs(dev->input_dev, ABS_X, i);
- input_sync(dev->input_dev);
+ input_sync(dev->input_dev);
break;
}
}
@@ -204,6 +213,20 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
break;
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
+ input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
+ input->keycode = keycode_rk3;
+ input->keycodesize = sizeof(char);
+ input->keycodemax = ARRAY_SIZE(keycode_rk3);
+ for (i=0; i<ARRAY_SIZE(keycode_rk3); i++)
+ set_bit(keycode_rk3[i], input->keybit);
+
+ input_set_abs_params(input, ABS_X, 0, 1024, 0, 10);
+ input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10);
+ input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10);
+ 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);
@@ -238,7 +261,6 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
return;
input_unregister_device(dev->input_dev);
- input_free_device(dev->input_dev);
dev->input_dev = NULL;
}
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index ac5666f4c6d..967b823eace 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -123,7 +123,6 @@ struct audioformat {
unsigned int rate_min, rate_max; /* min/max rates */
unsigned int nr_rates; /* number of rate table entries */
unsigned int *rate_table; /* rate table */
- unsigned int needs_knot; /* any unusual rates? */
};
struct snd_usb_substream;
@@ -1309,7 +1308,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
/* close the old interface */
if (subs->interface >= 0 && subs->interface != fmt->iface) {
- usb_set_interface(subs->dev, subs->interface, 0);
+ if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
+ snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
+ dev->devnum, fmt->iface, fmt->altsetting);
+ return -EIO;
+ }
subs->interface = -1;
subs->format = 0;
}
@@ -1761,7 +1764,7 @@ static int check_hw_params_convention(struct snd_usb_substream *subs)
channels[f->format] |= (1 << f->channels);
rates[f->format] |= f->rates;
/* needs knot? */
- if (f->needs_knot)
+ if (f->rates & SNDRV_PCM_RATE_KNOT)
goto __out;
}
/* check whether channels and rates match for all formats */
@@ -1817,7 +1820,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
return 0;
count += fp->nr_rates;
- if (fp->needs_knot)
+ if (fp->rates & SNDRV_PCM_RATE_KNOT)
needs_knot = 1;
}
if (!needs_knot)
@@ -2453,7 +2456,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
unsigned char *fmt, int offset)
{
int nr_rates = fmt[offset];
- int found;
+
if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
chip->dev->devnum, fp->iface, fp->altsetting);
@@ -2464,20 +2467,15 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
/*
* build the rate table and bitmap flags
*/
- int r, idx, c;
+ int r, idx;
unsigned int nonzero_rates = 0;
- /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */
- static unsigned int conv_rates[] = {
- 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
- 64000, 88200, 96000, 176400, 192000
- };
+
fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
if (fp->rate_table == NULL) {
snd_printk(KERN_ERR "cannot malloc\n");
return -1;
}
- fp->needs_knot = 0;
fp->nr_rates = nr_rates;
fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
@@ -2493,23 +2491,12 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
fp->rate_min = rate;
else if (rate > fp->rate_max)
fp->rate_max = rate;
- found = 0;
- for (c = 0; c < (int)ARRAY_SIZE(conv_rates); c++) {
- if (rate == conv_rates[c]) {
- found = 1;
- fp->rates |= (1 << c);
- break;
- }
- }
- if (!found)
- fp->needs_knot = 1;
+ fp->rates |= snd_pcm_rate_to_rate_bit(rate);
}
if (!nonzero_rates) {
hwc_debug("All rates were zero. Skipping format!\n");
return -1;
}
- if (fp->needs_knot)
- fp->rates |= SNDRV_PCM_RATE_KNOT;
} else {
/* continuous rates */
fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
@@ -2857,6 +2844,10 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
/* skip non-supported classes */
continue;
}
+ if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
+ snd_printk(KERN_ERR "low speed audio streaming not supported\n");
+ continue;
+ }
if (! parse_audio_endpoints(chip, j)) {
usb_set_interface(dev, j, 0); /* reset the current interface */
usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
@@ -3399,7 +3390,8 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
*rchip = NULL;
- if (snd_usb_get_speed(dev) != USB_SPEED_FULL &&
+ if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
+ snd_usb_get_speed(dev) != USB_SPEED_FULL &&
snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
return -ENXIO;
@@ -3473,7 +3465,9 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
strlcat(card->longname,
- snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" : ", high speed",
+ snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
+ snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
+ ", high speed",
sizeof(card->longname));
snd_usb_audio_create_proc(chip);
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 99295f9b769..6330788c1c2 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -407,6 +407,20 @@ static void snd_usbmidi_maudio_broken_running_status_input(
}
/*
+ * CME protocol: like the standard protocol, but SysEx commands are sent as a
+ * single USB packet preceded by a 0x0F byte.
+ */
+static void snd_usbmidi_cme_input(struct snd_usb_midi_in_endpoint *ep,
+ uint8_t *buffer, int buffer_length)
+{
+ if (buffer_length < 2 || (buffer[0] & 0x0f) != 0x0f)
+ snd_usbmidi_standard_input(ep, buffer, buffer_length);
+ else
+ snd_usbmidi_input_data(ep, buffer[0] >> 4,
+ &buffer[1], buffer_length - 1);
+}
+
+/*
* Adds one USB MIDI packet to the output buffer.
*/
static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0,
@@ -572,6 +586,12 @@ static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
.output_packet = snd_usbmidi_output_standard_packet,
};
+static struct usb_protocol_ops snd_usbmidi_cme_ops = {
+ .input = snd_usbmidi_cme_input,
+ .output = snd_usbmidi_standard_output,
+ .output_packet = snd_usbmidi_output_standard_packet,
+};
+
/*
* Novation USB MIDI protocol: number of data bytes is in the first byte
* (when receiving) (+1!) or in the second byte (when sending); data begins
@@ -963,8 +983,10 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
snd_usbmidi_out_endpoint_delete(ep);
return -ENOMEM;
}
- /* we never use interrupt output pipes */
- pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
+ if (ep_info->out_interval)
+ pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep);
+ else
+ pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
/* FIXME: we need more URBs to get reasonable bandwidth here: */
ep->max_transfer = 4;
@@ -976,8 +998,14 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
snd_usbmidi_out_endpoint_delete(ep);
return -ENOMEM;
}
- usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
- ep->max_transfer, snd_usbmidi_out_urb_complete, ep);
+ if (ep_info->out_interval)
+ usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+ ep->max_transfer, snd_usbmidi_out_urb_complete,
+ ep, ep_info->out_interval);
+ else
+ usb_fill_bulk_urb(ep->urb, umidi->chip->dev,
+ pipe, buffer, ep->max_transfer,
+ snd_usbmidi_out_urb_complete, ep);
ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
spin_lock_init(&ep->buffer_lock);
@@ -1323,6 +1351,13 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
endpoints[epidx].out_interval = ep->bInterval;
+ else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW)
+ /*
+ * Low speed bulk transfers don't exist, so
+ * force interrupt transfers for devices like
+ * ESI MIDI Mate that try to use them anyway.
+ */
+ endpoints[epidx].out_interval = 1;
endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
@@ -1336,6 +1371,8 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
endpoints[epidx].in_interval = ep->bInterval;
+ else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW)
+ endpoints[epidx].in_interval = 1;
endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
@@ -1690,6 +1727,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
break;
case QUIRK_MIDI_CME:
+ umidi->usb_protocol_ops = &snd_usbmidi_cme_ops;
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
default:
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 325d4b6b54a..5e329690cfb 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -1483,7 +1483,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
struct snd_kcontrol *kctl;
char **namelist;
- if (! num_ins || desc[0] < 6 + num_ins) {
+ if (! num_ins || desc[0] < 5 + num_ins) {
snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
return -EINVAL;
}
@@ -1888,14 +1888,7 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
return 0;
}
-static int snd_audigy2nx_led_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 5a2f518c662..743568f8990 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -88,7 +88,19 @@
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
},
-
+/* E-Mu devices */
+{
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x041e,
+ .idProduct = 0x3f02,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+},
+{
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x041e,
+ .idProduct = 0x3f04,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+},
/*
* Yamaha devices
*/
@@ -1254,7 +1266,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
/* TODO: add Edirol PC-80 support */
- /* TODO: add Edirol UA-1EX support */
+{
+ USB_DEVICE(0x0582, 0x0096),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "EDIROL",
+ .product_name = "UA-1EX",
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
{
USB_DEVICE(0x0582, 0x009a),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -1567,6 +1600,40 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
+{
+ USB_DEVICE(0x0763, 0x2019),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ /* .vendor_name = "M-Audio", */
+ /* .product_name = "Ozone Academic", */
+ .ifnum = QUIRK_ANY_INTERFACE,
+ .type = QUIRK_COMPOSITE,
+ .data = & (const struct snd_usb_audio_quirk[]) {
+ {
+ .ifnum = 0,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 1,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 2,
+ .type = QUIRK_AUDIO_STANDARD_INTERFACE
+ },
+ {
+ .ifnum = 3,
+ .type = QUIRK_MIDI_MIDIMAN,
+ .data = & (const struct snd_usb_midi_endpoint_info) {
+ .out_cables = 0x0001,
+ .in_cables = 0x0001
+ }
+ },
+ {
+ .ifnum = -1
+ }
+ }
+ }
+},
/* Casio devices */
{
@@ -1709,6 +1776,24 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
+/* Stanton/N2IT Final Scratch v1 device ('Scratchamp') */
+{
+ USB_DEVICE(0x103d, 0x0100),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "Stanton",
+ .product_name = "ScratchAmp",
+ .ifnum = QUIRK_NO_INTERFACE
+ }
+},
+{
+ USB_DEVICE(0x103d, 0x0101),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "Stanton",
+ .product_name = "ScratchAmp",
+ .ifnum = QUIRK_NO_INTERFACE
+ }
+},
+
/* Novation EMS devices */
{
USB_DEVICE_VENDOR_SPEC(0x1235, 0x0001),
@@ -1738,6 +1823,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
+/* */
+{
+ /* aka. Serato Scratch Live DJ Box */
+ USB_DEVICE(0x13e5, 0x0001),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "Rane",
+ .product_name = "SL-1",
+ .ifnum = QUIRK_NO_INTERFACE
+ }
+},
+
/* Miditech devices */
{
USB_DEVICE(0x4752, 0x0011),